diff --git a/ExampleKinSDK.meta b/ExampleKinSDK.meta new file mode 100644 index 0000000..d0f396a --- /dev/null +++ b/ExampleKinSDK.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d88fcb639f316d641a8f232c4d4d4624 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/ExampleKinSDK/Animations.meta b/ExampleKinSDK/Animations.meta new file mode 100644 index 0000000..a4edcc0 --- /dev/null +++ b/ExampleKinSDK/Animations.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a08484aefd7a5483682d0da386104df0 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/ExampleKinSDK/Animations/Loading.anim b/ExampleKinSDK/Animations/Loading.anim new file mode 100644 index 0000000..65d978e --- /dev/null +++ b/ExampleKinSDK/Animations/Loading.anim @@ -0,0 +1,199 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!74 &7400000 +AnimationClip: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Loading + serializedVersion: 6 + m_Legacy: 0 + m_Compressed: 0 + m_UseHighQualityCurve: 1 + m_RotationCurves: [] + m_CompressedRotationCurves: [] + m_EulerCurves: + - curve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 3 + time: 0 + value: {x: 0, y: 0, z: 0} + inSlope: {x: 0, y: 0, z: 0} + outSlope: {x: 0, y: 0, z: 0} + tangentMode: 0 + weightedMode: 0 + inWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334} + outWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334} + - serializedVersion: 3 + time: 1 + value: {x: 0, y: 0, z: 360} + inSlope: {x: 0, y: 0, z: 0} + outSlope: {x: 0, y: 0, z: 0} + tangentMode: 0 + weightedMode: 0 + inWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334} + outWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334} + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + path: + m_PositionCurves: [] + m_ScaleCurves: [] + m_FloatCurves: [] + m_PPtrCurves: [] + m_SampleRate: 60 + m_WrapMode: 0 + m_Bounds: + m_Center: {x: 0, y: 0, z: 0} + m_Extent: {x: 0, y: 0, z: 0} + m_ClipBindingConstant: + genericBindings: + - serializedVersion: 2 + path: 0 + attribute: 4 + script: {fileID: 0} + typeID: 4 + customType: 4 + isPPtrCurve: 0 + pptrCurveMapping: [] + m_AnimationClipSettings: + serializedVersion: 2 + m_AdditiveReferencePoseClip: {fileID: 0} + m_AdditiveReferencePoseTime: 0 + m_StartTime: 0 + m_StopTime: 1 + m_OrientationOffsetY: 0 + m_Level: 0 + m_CycleOffset: 0 + m_HasAdditiveReferencePose: 0 + m_LoopTime: 1 + m_LoopBlend: 0 + m_LoopBlendOrientation: 0 + m_LoopBlendPositionY: 0 + m_LoopBlendPositionXZ: 0 + m_KeepOriginalOrientation: 0 + m_KeepOriginalPositionY: 1 + m_KeepOriginalPositionXZ: 0 + m_HeightFromFeet: 0 + m_Mirror: 0 + m_EditorCurves: + - curve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 3 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 136 + weightedMode: 0 + inWeight: 0.33333334 + outWeight: 0.33333334 + - serializedVersion: 3 + time: 1 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 136 + weightedMode: 0 + inWeight: 0.33333334 + outWeight: 0.33333334 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + attribute: localEulerAnglesRaw.x + path: + classID: 224 + script: {fileID: 0} + - curve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 3 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 136 + weightedMode: 0 + inWeight: 0.33333334 + outWeight: 0.33333334 + - serializedVersion: 3 + time: 1 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 136 + weightedMode: 0 + inWeight: 0.33333334 + outWeight: 0.33333334 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + attribute: localEulerAnglesRaw.y + path: + classID: 224 + script: {fileID: 0} + - curve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 3 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 136 + weightedMode: 0 + inWeight: 0.33333334 + outWeight: 0.33333334 + - serializedVersion: 3 + time: 1 + value: 360 + inSlope: 0 + outSlope: 0 + tangentMode: 136 + weightedMode: 0 + inWeight: 0.33333334 + outWeight: 0.33333334 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + attribute: localEulerAnglesRaw.z + path: + classID: 224 + script: {fileID: 0} + m_EulerEditorCurves: + - curve: + serializedVersion: 2 + m_Curve: [] + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + attribute: m_LocalEulerAngles.x + path: + classID: 224 + script: {fileID: 0} + - curve: + serializedVersion: 2 + m_Curve: [] + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + attribute: m_LocalEulerAngles.y + path: + classID: 224 + script: {fileID: 0} + - curve: + serializedVersion: 2 + m_Curve: [] + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + attribute: m_LocalEulerAngles.z + path: + classID: 224 + script: {fileID: 0} + m_HasGenericRootTransform: 1 + m_HasMotionFloatCurves: 0 + m_Events: [] diff --git a/ExampleKinSDK/Animations/Loading.anim.meta b/ExampleKinSDK/Animations/Loading.anim.meta new file mode 100644 index 0000000..229f800 --- /dev/null +++ b/ExampleKinSDK/Animations/Loading.anim.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c68183e40394f48b0af3014498067b99 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 7400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/ExampleKinSDK/Animations/Loading.controller b/ExampleKinSDK/Animations/Loading.controller new file mode 100644 index 0000000..38b592e --- /dev/null +++ b/ExampleKinSDK/Animations/Loading.controller @@ -0,0 +1,72 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1102 &-3983692369812406522 +AnimatorState: + serializedVersion: 6 + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Loading + m_Speed: 1 + m_CycleOffset: 0 + m_Transitions: [] + m_StateMachineBehaviours: [] + m_Position: {x: 50, y: 50, z: 0} + m_IKOnFeet: 0 + m_WriteDefaultValues: 1 + m_Mirror: 0 + m_SpeedParameterActive: 0 + m_MirrorParameterActive: 0 + m_CycleOffsetParameterActive: 0 + m_TimeParameterActive: 0 + m_Motion: {fileID: 7400000, guid: c68183e40394f48b0af3014498067b99, type: 2} + m_Tag: + m_SpeedParameter: + m_MirrorParameter: + m_CycleOffsetParameter: + m_TimeParameter: +--- !u!91 &9100000 +AnimatorController: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Loading + serializedVersion: 5 + m_AnimatorParameters: [] + m_AnimatorLayers: + - serializedVersion: 5 + m_Name: Base Layer + m_StateMachine: {fileID: 7396751832364323253} + m_Mask: {fileID: 0} + m_Motions: [] + m_Behaviours: [] + m_BlendingMode: 0 + m_SyncedLayerIndex: -1 + m_DefaultWeight: 0 + m_IKPass: 0 + m_SyncedLayerAffectsTiming: 0 + m_Controller: {fileID: 9100000} +--- !u!1107 &7396751832364323253 +AnimatorStateMachine: + serializedVersion: 6 + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Base Layer + m_ChildStates: + - serializedVersion: 1 + m_State: {fileID: -3983692369812406522} + m_Position: {x: 200, y: 0, z: 0} + m_ChildStateMachines: [] + m_AnyStateTransitions: [] + m_EntryTransitions: [] + m_StateMachineTransitions: {} + m_StateMachineBehaviours: [] + m_AnyStatePosition: {x: 50, y: 20, z: 0} + m_EntryPosition: {x: 50, y: 120, z: 0} + m_ExitPosition: {x: 800, y: 120, z: 0} + m_ParentStateMachinePosition: {x: 800, y: 20, z: 0} + m_DefaultState: {fileID: -3983692369812406522} diff --git a/ExampleKinSDK/Animations/Loading.controller.meta b/ExampleKinSDK/Animations/Loading.controller.meta new file mode 100644 index 0000000..b935866 --- /dev/null +++ b/ExampleKinSDK/Animations/Loading.controller.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 6e71013b992a04010ab6ec826060cdf6 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 9100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/ExampleKinSDK/Images.meta b/ExampleKinSDK/Images.meta new file mode 100644 index 0000000..a53063a --- /dev/null +++ b/ExampleKinSDK/Images.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0b430c782e25541b79900c6fd202a002 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/ExampleKinSDK/Images/Loading_2.gif b/ExampleKinSDK/Images/Loading_2.gif new file mode 100644 index 0000000..8df2c15 --- /dev/null +++ b/ExampleKinSDK/Images/Loading_2.gif @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1827e9d30f9e24480d9f61158b1a701def6d07f814858109aedb8f48b9d2fd28 +size 67640 diff --git a/ExampleKinSDK/Images/Loading_2.gif.meta b/ExampleKinSDK/Images/Loading_2.gif.meta new file mode 100644 index 0000000..030554c --- /dev/null +++ b/ExampleKinSDK/Images/Loading_2.gif.meta @@ -0,0 +1,135 @@ +fileFormatVersion: 2 +guid: fd7cd1a200ca84200836cd8800b3020b +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMasterTextureLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 8 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Server + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: WebGL + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 5e97eb03825dee720800000000000000 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/ExampleKinSDK/Images/RoundedRectange.png b/ExampleKinSDK/Images/RoundedRectange.png new file mode 100644 index 0000000..9118d54 --- /dev/null +++ b/ExampleKinSDK/Images/RoundedRectange.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d6b90b681f2aee8dc84b001b5eccc13dd56069045574e81d8014eb3ce51b65e3 +size 1477 diff --git a/ExampleKinSDK/Images/RoundedRectange.png.meta b/ExampleKinSDK/Images/RoundedRectange.png.meta new file mode 100644 index 0000000..2357c00 --- /dev/null +++ b/ExampleKinSDK/Images/RoundedRectange.png.meta @@ -0,0 +1,135 @@ +fileFormatVersion: 2 +guid: d426dc3b537914150b0df30f95e20748 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMasterTextureLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 8 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Server + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: WebGL + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 5e97eb03825dee720800000000000000 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/ExampleKinSDK/Images/bg.png b/ExampleKinSDK/Images/bg.png new file mode 100644 index 0000000..f4f4db7 --- /dev/null +++ b/ExampleKinSDK/Images/bg.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:40a5679417d5a51c279788d35cfedcd0a81eee9e2e549489c0603160594af83d +size 81580 diff --git a/ExampleKinSDK/Images/bg.png.meta b/ExampleKinSDK/Images/bg.png.meta new file mode 100644 index 0000000..24a7dd7 --- /dev/null +++ b/ExampleKinSDK/Images/bg.png.meta @@ -0,0 +1,135 @@ +fileFormatVersion: 2 +guid: 55573cdcc754d4f3ca243abbcf23b2d3 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMasterTextureLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Server + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: WebGL + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/ExampleKinSDK/Scenes.meta b/ExampleKinSDK/Scenes.meta new file mode 100644 index 0000000..7fe8e10 --- /dev/null +++ b/ExampleKinSDK/Scenes.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 131a6b21c8605f84396be9f6751fb6e3 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/ExampleKinSDK/Scenes/KinSampleScene.unity b/ExampleKinSDK/Scenes/KinSampleScene.unity new file mode 100644 index 0000000..d7e4c4e --- /dev/null +++ b/ExampleKinSDK/Scenes/KinSampleScene.unity @@ -0,0 +1,7752 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!29 &1 +OcclusionCullingSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_OcclusionBakeSettings: + smallestOccluder: 5 + smallestHole: 0.25 + backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} +--- !u!104 &2 +RenderSettings: + m_ObjectHideFlags: 0 + serializedVersion: 9 + m_Fog: 0 + m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + m_FogMode: 3 + m_FogDensity: 0.01 + m_LinearFogStart: 0 + m_LinearFogEnd: 300 + m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} + m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} + m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} + m_AmbientIntensity: 1 + m_AmbientMode: 3 + m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} + m_SkyboxMaterial: {fileID: 0} + m_HaloStrength: 0.5 + m_FlareStrength: 1 + m_FlareFadeSpeed: 3 + m_HaloTexture: {fileID: 0} + m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} + m_DefaultReflectionMode: 0 + m_DefaultReflectionResolution: 128 + m_ReflectionBounces: 1 + m_ReflectionIntensity: 1 + m_CustomReflection: {fileID: 0} + m_Sun: {fileID: 0} + m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1} + m_UseRadianceAmbientProbe: 0 +--- !u!157 &3 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 12 + m_GIWorkflowMode: 1 + m_GISettings: + serializedVersion: 2 + m_BounceScale: 1 + m_IndirectOutputScale: 1 + m_AlbedoBoost: 1 + m_EnvironmentLightingMode: 0 + m_EnableBakedLightmaps: 0 + m_EnableRealtimeLightmaps: 0 + m_LightmapEditorSettings: + serializedVersion: 12 + m_Resolution: 2 + m_BakeResolution: 40 + m_AtlasSize: 1024 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 1 + m_CompAOExponentDirect: 0 + m_ExtractAmbientOcclusion: 0 + m_Padding: 2 + m_LightmapParameters: {fileID: 0} + m_LightmapsBakeMode: 1 + m_TextureCompression: 1 + m_FinalGather: 0 + m_FinalGatherFiltering: 1 + m_FinalGatherRayCount: 256 + m_ReflectionCompression: 2 + m_MixedBakeMode: 2 + m_BakeBackend: 0 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 500 + m_PVRBounces: 2 + m_PVREnvironmentSampleCount: 500 + m_PVREnvironmentReferencePointCount: 2048 + m_PVRFilteringMode: 2 + m_PVRDenoiserTypeDirect: 0 + m_PVRDenoiserTypeIndirect: 0 + m_PVRDenoiserTypeAO: 0 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVREnvironmentMIS: 0 + m_PVRCulling: 1 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_ExportTrainingData: 0 + m_TrainingDataDestination: TrainingData + m_LightProbeSampleCountMultiplier: 4 + m_LightingDataAsset: {fileID: 0} + m_LightingSettings: {fileID: 0} +--- !u!196 &4 +NavMeshSettings: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_BuildSettings: + serializedVersion: 2 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.4 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + accuratePlacement: 0 + maxJobWorkers: 0 + preserveTilesOutsideBounds: 0 + debug: + m_Flags: 0 + m_NavMeshData: {fileID: 0} +--- !u!1 &56093881 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 56093882} + m_Layer: 5 + m_Name: Content + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &56093882 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 56093881} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 665457121} + m_Father: {fileID: 2143904337} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 28} + m_Pivot: {x: 0.5, y: 1} +--- !u!1 &58222922 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 58222923} + - component: {fileID: 58222924} + m_Layer: 5 + m_Name: Text Area + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &58222923 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 58222922} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1647829005} + - {fileID: 205485170} + m_Father: {fileID: 1494765189} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: -0.5} + m_SizeDelta: {x: -20, y: -13} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &58222924 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 58222922} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 3312d7739989d2b4e91e6319e9a96d76, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Padding: {x: -8, y: -5, z: -8, w: -5} + m_Softness: {x: 0, y: 0} +--- !u!1 &71217032 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 71217033} + m_Layer: 5 + m_Name: Sliding Area + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &71217033 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 71217032} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1478252376} + m_Father: {fileID: 1505492019} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: -20, y: -20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!1 &168030516 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 168030517} + - component: {fileID: 168030520} + - component: {fileID: 168030519} + - component: {fileID: 168030518} + m_Layer: 5 + m_Name: Scrollbar Vertical + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &168030517 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 168030516} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1728334077} + m_Father: {fileID: 1524290441} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 1, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 20, y: -17} + m_Pivot: {x: 1, y: 1} +--- !u!114 &168030518 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 168030516} + m_Enabled: 0 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2a4db7a114972834c8e4117be1d82ba3, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1681756779} + m_HandleRect: {fileID: 1681756778} + m_Direction: 2 + m_Value: 0.944399 + m_Size: 0.22430307 + m_NumberOfSteps: 0 + m_OnValueChanged: + m_PersistentCalls: + m_Calls: [] +--- !u!114 &168030519 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 168030516} + m_Enabled: 0 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &168030520 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 168030516} + m_CullTransparentMesh: 1 +--- !u!1 &182563498 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 182563499} + - component: {fileID: 182563501} + - component: {fileID: 182563500} + m_Layer: 5 + m_Name: PanelPublicKey + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &182563499 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 182563498} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 2026027259} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.16121823, y: 0.9012636} + m_AnchorMax: {x: 0.8408221, y: 1} + m_AnchoredPosition: {x: 0, y: 20.837097} + m_SizeDelta: {x: 0, y: 41.6742} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &182563500 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 182563498} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.9764706, g: 0.17254902, b: 0.8156863, a: 0.69411767} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: d426dc3b537914150b0df30f95e20748, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &182563501 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 182563498} + m_CullTransparentMesh: 1 +--- !u!1 &190750845 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 190750846} + - component: {fileID: 190750849} + - component: {fileID: 190750848} + - component: {fileID: 190750847} + m_Layer: 5 + m_Name: BtnTransfer + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &190750846 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 190750845} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1698028097} + m_Father: {fileID: 2026027259} + m_RootOrder: 4 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.52827626, y: 0.04308063} + m_AnchorMax: {x: 0.91830975, y: 0.15817142} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: -2, y: -0.79019165} + m_Pivot: {x: 0.5, y: 0} +--- !u!114 &190750847 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 190750845} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 190750848} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 1449580719} + m_TargetAssemblyTypeName: UnityEngine.GameObject, UnityEngine + m_MethodName: SetActive + m_Mode: 6 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 1 + m_CallState: 2 +--- !u!114 &190750848 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 190750845} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.9764706, g: 0.17254902, b: 0.8156863, a: 0.69411767} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: d426dc3b537914150b0df30f95e20748, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &190750849 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 190750845} + m_CullTransparentMesh: 1 +--- !u!1 &205485169 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 205485170} + - component: {fileID: 205485172} + - component: {fileID: 205485171} + m_Layer: 5 + m_Name: TxtKeyOrMnemonics + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &205485170 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 205485169} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 58222923} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.008700598, y: 0} + m_AnchorMax: {x: 0.9912995, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &205485171 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 205485169} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: "\u200B" + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4281479730 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 72 + m_fontSizeBase: 14 + m_fontWeight: 400 + m_enableAutoSizing: 1 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 1 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &205485172 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 205485169} + m_CullTransparentMesh: 1 +--- !u!1 &234428082 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 234428083} + - component: {fileID: 234428085} + - component: {fileID: 234428084} + m_Layer: 5 + m_Name: PanelHistory + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 0 +--- !u!224 &234428083 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 234428082} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1754763207} + - {fileID: 1524290441} + m_Father: {fileID: 2026027259} + m_RootOrder: 9 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.16121823, y: 0.025437322} + m_AnchorMax: {x: 0.8408221, y: 0.9840138} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &234428084 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 234428082} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 0.3726415, b: 0.87196773, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &234428085 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 234428082} + m_CullTransparentMesh: 1 +--- !u!1 &259111920 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 259111923} + - component: {fileID: 259111922} + - component: {fileID: 259111921} + m_Layer: 0 + m_Name: EventSystem + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &259111921 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 259111920} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4f231c4fb786f3946a6b90b886c48677, type: 3} + m_Name: + m_EditorClassIdentifier: + m_SendPointerHoverToParent: 1 + m_HorizontalAxis: Horizontal + m_VerticalAxis: Vertical + m_SubmitButton: Submit + m_CancelButton: Cancel + m_InputActionsPerSecond: 10 + m_RepeatDelay: 0.5 + m_ForceModuleActive: 0 +--- !u!114 &259111922 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 259111920} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 76c392e42b5098c458856cdf6ecaaaa1, type: 3} + m_Name: + m_EditorClassIdentifier: + m_FirstSelected: {fileID: 0} + m_sendNavigationEvents: 1 + m_DragThreshold: 10 +--- !u!4 &259111923 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 259111920} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &275802248 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 275802249} + - component: {fileID: 275802251} + - component: {fileID: 275802250} + m_Layer: 5 + m_Name: TxtClose + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &275802249 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 275802248} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 830987879} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &275802250 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 275802248} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: CLOSE + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4278190335 + m_fontColor: {r: 1, g: 0, b: 0, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: 97690656 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 20 + m_fontSizeBase: 20 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 0 + m_fontSizeMax: 0 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &275802251 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 275802248} + m_CullTransparentMesh: 1 +--- !u!1 &276866467 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 276866468} + - component: {fileID: 276866471} + - component: {fileID: 276866470} + - component: {fileID: 276866469} + m_Layer: 5 + m_Name: DropdownTokenAccounts + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 0 +--- !u!224 &276866468 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 276866467} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 619681933} + - {fileID: 417434894} + - {fileID: 1874048011} + m_Father: {fileID: 2026027259} + m_RootOrder: 8 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.2836518, y: 0.43600005} + m_AnchorMax: {x: 0.7178074, y: 0.52735686} + m_AnchoredPosition: {x: 0.05697632, y: -0.40000153} + m_SizeDelta: {x: -1.0700073, y: 1.658001} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &276866469 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 276866467} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 7b743370ac3e4ec2a1668f5455a8ef8a, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 276866470} + m_Template: {fileID: 1874048011} + m_CaptionText: {fileID: 619681934} + m_CaptionImage: {fileID: 0} + m_Placeholder: {fileID: 0} + m_ItemText: {fileID: 1784266766} + m_ItemImage: {fileID: 0} + m_Value: 0 + m_Options: + m_Options: [] + m_OnValueChanged: + m_PersistentCalls: + m_Calls: [] + m_AlphaFadeSpeed: 0.15 +--- !u!114 &276866470 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 276866467} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.99215686, g: 0.8235294, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &276866471 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 276866467} + m_CullTransparentMesh: 1 +--- !u!1 &306602514 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 306602515} + - component: {fileID: 306602518} + - component: {fileID: 306602517} + - component: {fileID: 306602516} + m_Layer: 5 + m_Name: Placeholder + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &306602515 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 306602514} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1952579026} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &306602516 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 306602514} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreLayout: 1 + m_MinWidth: -1 + m_MinHeight: -1 + m_PreferredWidth: -1 + m_PreferredHeight: -1 + m_FlexibleWidth: -1 + m_FlexibleHeight: -1 + m_LayoutPriority: 1 +--- !u!114 &306602517 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 306602514} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Destination + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 2150773298 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 0.5} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 20 + m_fontSizeBase: 20 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 1 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 1 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &306602518 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 306602514} + m_CullTransparentMesh: 1 +--- !u!1 &340591500 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 340591501} + - component: {fileID: 340591503} + - component: {fileID: 340591502} + m_Layer: 5 + m_Name: TxtBalance + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &340591501 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 340591500} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 738988725} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.03748751, y: 0.16230007} + m_AnchorMax: {x: 0.9850001, y: 0.86700004} + m_AnchoredPosition: {x: -59.83618, y: 0} + m_SizeDelta: {x: -144, y: 2} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &340591502 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 340591500} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4278190080 + m_fontColor: {r: 0, g: 0, b: 0, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 36 + m_fontSizeBase: 36 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: -17.128113, y: 0, z: -130.17368, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &340591503 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 340591500} + m_CullTransparentMesh: 1 +--- !u!1 &341012196 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 341012197} + - component: {fileID: 341012199} + - component: {fileID: 341012198} + m_Layer: 5 + m_Name: TextTokenAccountsDesc + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 0 +--- !u!224 &341012197 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 341012196} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 2026027259} + m_RootOrder: 7 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.2836518, y: 0.52735686} + m_AnchorMax: {x: 0.7178074, y: 0.5805066} + m_AnchoredPosition: {x: -0.000015258789, y: 0} + m_SizeDelta: {x: -0.000030518, y: -0.536} + m_Pivot: {x: 0.5, y: 0} +--- !u!114 &341012198 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 341012196} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Owned token accounts + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 21.55 + m_fontSizeBase: 36 + m_fontWeight: 400 + m_enableAutoSizing: 1 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 1 + m_VerticalAlignment: 256 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 5.8471375, y: 5.656189, z: 0, w: 1.912857} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &341012199 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 341012196} + m_CullTransparentMesh: 1 +--- !u!1 &395266776 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 395266777} + - component: {fileID: 395266780} + - component: {fileID: 395266779} + - component: {fileID: 395266778} + m_Layer: 5 + m_Name: Viewport + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &395266777 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 395266776} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 717344525} + m_Father: {fileID: 1524290441} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: -17, y: -17} + m_Pivot: {x: 0, y: 1} +--- !u!114 &395266778 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 395266776} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 31a19414c41e5ae4aae2af33fee712f6, type: 3} + m_Name: + m_EditorClassIdentifier: + m_ShowMaskGraphic: 0 +--- !u!114 &395266779 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 395266776} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10917, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &395266780 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 395266776} + m_CullTransparentMesh: 1 +--- !u!1 &400344508 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 400344509} + - component: {fileID: 400344512} + - component: {fileID: 400344511} + - component: {fileID: 400344510} + m_Layer: 5 + m_Name: BtnGetHistory + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &400344509 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 400344508} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 2144804968} + m_Father: {fileID: 2026027259} + m_RootOrder: 5 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.28961483, y: 0.23263174} + m_AnchorMax: {x: 0.7118124, y: 0.35701317} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: -2, y: -0.79019165} + m_Pivot: {x: 0.5, y: 0} +--- !u!114 &400344510 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 400344508} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 400344511} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 2026027260} + m_TargetAssemblyTypeName: WalletScreen, Assembly-CSharp + m_MethodName: GetHistory + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 + - m_Target: {fileID: 234428082} + m_TargetAssemblyTypeName: UnityEngine.GameObject, UnityEngine + m_MethodName: SetActive + m_Mode: 6 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 1 + m_CallState: 2 +--- !u!114 &400344511 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 400344508} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.9764706, g: 0.17254902, b: 0.8156863, a: 0.69411767} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: d426dc3b537914150b0df30f95e20748, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &400344512 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 400344508} + m_CullTransparentMesh: 1 +--- !u!1 &417434893 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 417434894} + - component: {fileID: 417434896} + - component: {fileID: 417434895} + m_Layer: 5 + m_Name: Arrow + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &417434894 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 417434893} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 276866468} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 1, y: 0.5} + m_AnchorMax: {x: 1, y: 0.5} + m_AnchoredPosition: {x: -15, y: 0} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &417434895 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 417434893} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10915, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &417434896 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 417434893} + m_CullTransparentMesh: 1 +--- !u!1 &457188605 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 457188606} + - component: {fileID: 457188609} + - component: {fileID: 457188608} + - component: {fileID: 457188607} + m_Layer: 5 + m_Name: BtnTransfer + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &457188606 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 457188605} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1557106042} + m_Father: {fileID: 1257448179} + m_RootOrder: 4 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.13161282, y: 0.42923856} + m_AnchorMax: {x: 0.88321424, y: 0.5517312} + m_AnchoredPosition: {x: -1.211853, y: -5.321686} + m_SizeDelta: {x: 1.4906311, y: 6.1647263} + m_Pivot: {x: 0.5, y: 0} +--- !u!114 &457188607 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 457188605} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 457188608} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 2026027260} + m_TargetAssemblyTypeName: WalletScreen, Assembly-CSharp + m_MethodName: MakeTransfer + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 +--- !u!114 &457188608 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 457188605} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: d426dc3b537914150b0df30f95e20748, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &457188609 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 457188605} + m_CullTransparentMesh: 1 +--- !u!1 &519420028 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 519420032} + - component: {fileID: 519420031} + - component: {fileID: 519420029} + m_Layer: 0 + m_Name: Main Camera + m_TagString: MainCamera + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!81 &519420029 +AudioListener: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 519420028} + m_Enabled: 1 +--- !u!20 &519420031 +Camera: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 519420028} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 1 + m_BackGroundColor: {r: 0.23137257, g: 0.227451, b: 0.5764706, a: 0} + m_projectionMatrixMode: 1 + m_GateFitMode: 2 + m_FOVAxisMode: 0 + m_SensorSize: {x: 36, y: 24} + m_LensShift: {x: 0, y: 0} + m_FocalLength: 50 + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: 0.3 + far clip plane: 1000 + field of view: 60 + orthographic: 1 + orthographic size: 5 + m_Depth: -1 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 0 + m_HDR: 1 + m_AllowMSAA: 0 + m_AllowDynamicResolution: 0 + m_ForceIntoRT: 0 + m_OcclusionCulling: 0 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 +--- !u!4 &519420032 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 519420028} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: -10} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &569779072 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 569779073} + - component: {fileID: 569779075} + - component: {fileID: 569779074} + m_Layer: 5 + m_Name: Item Background + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &569779073 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 569779072} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 665457121} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &569779074 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 569779072} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &569779075 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 569779072} + m_CullTransparentMesh: 1 +--- !u!1 &581214749 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 581214750} + - component: {fileID: 581214752} + - component: {fileID: 581214751} + m_Layer: 5 + m_Name: Handle + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &581214750 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 581214749} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 704828155} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &581214751 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 581214749} + m_Enabled: 0 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &581214752 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 581214749} + m_CullTransparentMesh: 1 +--- !u!1 &619681932 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 619681933} + - component: {fileID: 619681935} + - component: {fileID: 619681934} + m_Layer: 5 + m_Name: Label + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &619681933 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 619681932} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 276866468} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: -7.4999084, y: -0.4999981} + m_SizeDelta: {x: -35, y: -13} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &619681934 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 619681932} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4281479730 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 14 + m_fontSizeBase: 14 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 1 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &619681935 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 619681932} + m_CullTransparentMesh: 1 +--- !u!1 &665457120 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 665457121} + - component: {fileID: 665457122} + m_Layer: 5 + m_Name: Item + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &665457121 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 665457120} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 569779073} + - {fileID: 1355121920} + - {fileID: 1784266765} + m_Father: {fileID: 56093882} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0.5} + m_AnchorMax: {x: 1, y: 0.5} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &665457122 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 665457120} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9085046f02f69544eb97fd06b6048fe2, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 569779074} + toggleTransition: 1 + graphic: {fileID: 1355121921} + m_Group: {fileID: 0} + onValueChanged: + m_PersistentCalls: + m_Calls: [] + m_IsOn: 1 +--- !u!1 &704828154 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 704828155} + m_Layer: 5 + m_Name: Sliding Area + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &704828155 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 704828154} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 581214750} + m_Father: {fileID: 1870937327} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: -20, y: -20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!1 &717344524 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 717344525} + m_Layer: 5 + m_Name: Content + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &717344525 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 717344524} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1646169728} + m_Father: {fileID: 395266777} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 62.21472} + m_SizeDelta: {x: 0, y: 1442.509} + m_Pivot: {x: 0, y: 1} +--- !u!1 &738988724 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 738988725} + - component: {fileID: 738988727} + - component: {fileID: 738988726} + - component: {fileID: 738988728} + m_Layer: 5 + m_Name: Balance + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 0 +--- !u!224 &738988725 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 738988724} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 340591501} + m_Father: {fileID: 2026027259} + m_RootOrder: 6 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.2836518, y: 0.684} + m_AnchorMax: {x: 0.7178074, y: 0.82400006} + m_AnchoredPosition: {x: -0.5, y: 0} + m_SizeDelta: {x: -1.2269897, y: -1.9725037} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &738988726 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 738988724} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.99408376, g: 0.8254717, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &738988727 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 738988724} + m_CullTransparentMesh: 1 +--- !u!114 &738988728 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 738988724} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 738988726} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 2026027260} + m_TargetAssemblyTypeName: WalletScreen, Assembly-CSharp + m_MethodName: UpdateBalance + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 +--- !u!1 &740345442 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 740345443} + - component: {fileID: 740345445} + - component: {fileID: 740345444} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &740345443 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 740345442} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 2044982344} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &740345444 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 740345442} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: "\u200B" + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4281479730 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 72 + m_fontSizeBase: 20 + m_fontWeight: 400 + m_enableAutoSizing: 1 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 1 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 1 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &740345445 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 740345442} + m_CullTransparentMesh: 1 +--- !u!1 &787690794 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 787690795} + m_Layer: 5 + m_Name: GameObject + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &787690795 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 787690794} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1887713060} + m_RootOrder: 3 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 100, y: 100} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!1 &830987878 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 830987879} + - component: {fileID: 830987882} + - component: {fileID: 830987881} + - component: {fileID: 830987880} + m_Layer: 5 + m_Name: BtnClose + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &830987879 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 830987878} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 275802249} + m_Father: {fileID: 1257448179} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.13161282, y: 0.053638067} + m_AnchorMax: {x: 0.90124285, y: 0.16889244} + m_AnchoredPosition: {x: -1.211853, y: -5.321686} + m_SizeDelta: {x: 1.4906311, y: 6.1647263} + m_Pivot: {x: 0.5, y: 0} +--- !u!114 &830987880 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 830987878} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 830987881} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 1449580719} + m_TargetAssemblyTypeName: UnityEngine.GameObject, UnityEngine + m_MethodName: SetActive + m_Mode: 6 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 +--- !u!114 &830987881 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 830987878} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: d426dc3b537914150b0df30f95e20748, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &830987882 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 830987878} + m_CullTransparentMesh: 1 +--- !u!1 &862687848 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 862687849} + - component: {fileID: 862687852} + - component: {fileID: 862687851} + - component: {fileID: 862687850} + m_Layer: 5 + m_Name: BtnLogin + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &862687849 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 862687848} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1931057017} + m_Father: {fileID: 1887713060} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.2594222, y: 0.40893367} + m_AnchorMax: {x: 0.73709637, y: 0.53474504} + m_AnchoredPosition: {x: -0.34960938, y: 0} + m_SizeDelta: {x: -2, y: -0.79019165} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &862687850 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 862687848} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 862687851} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 1732370167} + m_TargetAssemblyTypeName: GameController, Assembly-CSharp + m_MethodName: Login + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 + - m_Target: {fileID: 2026027255} + m_TargetAssemblyTypeName: UnityEngine.GameObject, UnityEngine + m_MethodName: SetActive + m_Mode: 6 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 1 + m_CallState: 2 + - m_Target: {fileID: 1887713056} + m_TargetAssemblyTypeName: UnityEngine.GameObject, UnityEngine + m_MethodName: SetActive + m_Mode: 6 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 +--- !u!114 &862687851 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 862687848} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.9764706, g: 0.17254902, b: 0.8156863, a: 0.69411767} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: d426dc3b537914150b0df30f95e20748, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &862687852 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 862687848} + m_CullTransparentMesh: 1 +--- !u!1 &975210816 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 975210817} + - component: {fileID: 975210819} + - component: {fileID: 975210818} + m_Layer: 5 + m_Name: Panel + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &975210817 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 975210816} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1887713060} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &975210818 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 975210816} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: 55573cdcc754d4f3ca243abbcf23b2d3, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &975210819 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 975210816} + m_CullTransparentMesh: 1 +--- !u!1 &1002089369 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1002089370} + - component: {fileID: 1002089372} + - component: {fileID: 1002089371} + m_Layer: 5 + m_Name: TxtRequestAirdrop + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1002089370 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1002089369} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1513583404} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1002089371 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1002089369} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: REQUEST AIRDROP + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: 97690656 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 20 + m_fontSizeBase: 20 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 0 + m_fontSizeMax: 0 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &1002089372 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1002089369} + m_CullTransparentMesh: 1 +--- !u!1 &1037139893 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1037139894} + - component: {fileID: 1037139897} + - component: {fileID: 1037139896} + - component: {fileID: 1037139895} + m_Layer: 5 + m_Name: InputFieldDestination + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1037139894 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1037139893} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1952579026} + m_Father: {fileID: 1257448179} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.13161282, y: 0.7536054} + m_AnchorMax: {x: 0.90124285, y: 0.8687448} + m_AnchoredPosition: {x: 1, y: 0} + m_SizeDelta: {x: -2, y: -2} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1037139895 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1037139893} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2da0c512f12947e489f739169773d7ca, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1037139896} + m_TextViewport: {fileID: 1952579026} + m_TextComponent: {fileID: 1261229069} + m_Placeholder: {fileID: 306602517} + m_VerticalScrollbar: {fileID: 0} + m_VerticalScrollbarEventHandler: {fileID: 0} + m_LayoutGroup: {fileID: 0} + m_ScrollSensitivity: 1 + m_ContentType: 0 + m_InputType: 0 + m_AsteriskChar: 42 + m_KeyboardType: 0 + m_LineType: 0 + m_HideMobileInput: 0 + m_HideSoftKeyboard: 0 + m_CharacterValidation: 0 + m_RegexValue: + m_GlobalPointSize: 20 + m_CharacterLimit: 0 + m_OnEndEdit: + m_PersistentCalls: + m_Calls: [] + m_OnSubmit: + m_PersistentCalls: + m_Calls: [] + m_OnSelect: + m_PersistentCalls: + m_Calls: [] + m_OnDeselect: + m_PersistentCalls: + m_Calls: [] + m_OnTextSelection: + m_PersistentCalls: + m_Calls: [] + m_OnEndTextSelection: + m_PersistentCalls: + m_Calls: [] + m_OnValueChanged: + m_PersistentCalls: + m_Calls: [] + m_OnTouchScreenKeyboardStatusChanged: + m_PersistentCalls: + m_Calls: [] + m_CaretColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_CustomCaretColor: 0 + m_SelectionColor: {r: 0.65882355, g: 0.80784315, b: 1, a: 0.7529412} + m_Text: + m_CaretBlinkRate: 0.85 + m_CaretWidth: 1 + m_ReadOnly: 0 + m_RichText: 1 + m_GlobalFontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_OnFocusSelectAll: 1 + m_ResetOnDeActivation: 1 + m_RestoreOriginalTextOnEscape: 1 + m_isRichTextEditingAllowed: 0 + m_LineLimit: 0 + m_InputValidator: {fileID: 0} +--- !u!114 &1037139896 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1037139893} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10911, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1037139897 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1037139893} + m_CullTransparentMesh: 1 +--- !u!1 &1257448178 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1257448179} + - component: {fileID: 1257448181} + - component: {fileID: 1257448180} + m_Layer: 5 + m_Name: PanelTransfer + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1257448179 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1257448178} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 830987879} + - {fileID: 1037139894} + - {fileID: 1637158286} + - {fileID: 1687982967} + - {fileID: 457188606} + m_Father: {fileID: 1449580720} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.16121823, y: 0.025437322} + m_AnchorMax: {x: 0.8408221, y: 0.9840138} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1257448180 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1257448178} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 0.3726415, b: 0.87196773, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1257448181 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1257448178} + m_CullTransparentMesh: 1 +--- !u!1 &1261229067 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1261229068} + - component: {fileID: 1261229070} + - component: {fileID: 1261229069} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1261229068 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1261229067} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1952579026} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1261229069 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1261229067} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: "\u200B" + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4281479730 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 72 + m_fontSizeBase: 20 + m_fontWeight: 400 + m_enableAutoSizing: 1 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 1 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 1 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &1261229070 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1261229067} + m_CullTransparentMesh: 1 +--- !u!1 &1355121919 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1355121920} + - component: {fileID: 1355121922} + - component: {fileID: 1355121921} + m_Layer: 5 + m_Name: Item Checkmark + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1355121920 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1355121919} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 665457121} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0.5} + m_AnchorMax: {x: 0, y: 0.5} + m_AnchoredPosition: {x: 10, y: 0} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1355121921 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1355121919} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10901, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1355121922 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1355121919} + m_CullTransparentMesh: 1 +--- !u!1 &1449580719 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1449580720} + - component: {fileID: 1449580722} + - component: {fileID: 1449580721} + m_Layer: 5 + m_Name: PanelTransfer + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 0 +--- !u!224 &1449580720 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1449580719} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1257448179} + m_Father: {fileID: 2026027259} + m_RootOrder: 10 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1449580721 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1449580719} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0, g: 0, b: 0, a: 0.87058824} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1449580722 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1449580719} + m_CullTransparentMesh: 1 +--- !u!1 &1466237471 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1466237472} + - component: {fileID: 1466237474} + - component: {fileID: 1466237473} + m_Layer: 5 + m_Name: TxtClose + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1466237472 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1466237471} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1754763207} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1466237473 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1466237471} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: CLOSE + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4278190335 + m_fontColor: {r: 1, g: 0, b: 0, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: 97690656 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 20 + m_fontSizeBase: 20 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 0 + m_fontSizeMax: 0 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &1466237474 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1466237471} + m_CullTransparentMesh: 1 +--- !u!1 &1478252375 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1478252376} + - component: {fileID: 1478252378} + - component: {fileID: 1478252377} + m_Layer: 5 + m_Name: Handle + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1478252376 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1478252375} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 71217033} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 0.2} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1478252377 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1478252375} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1478252378 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1478252375} + m_CullTransparentMesh: 1 +--- !u!1 &1494765188 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1494765189} + - component: {fileID: 1494765192} + - component: {fileID: 1494765191} + - component: {fileID: 1494765190} + m_Layer: 5 + m_Name: InputLogin + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1494765189 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1494765188} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 58222923} + m_Father: {fileID: 1887713060} + m_RootOrder: 4 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.2594222, y: 0.6186874} + m_AnchorMax: {x: 0.73709637, y: 0.7235877} + m_AnchoredPosition: {x: -1, y: 0} + m_SizeDelta: {x: 0, y: -2} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1494765190 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1494765188} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2da0c512f12947e489f739169773d7ca, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1494765191} + m_TextViewport: {fileID: 58222923} + m_TextComponent: {fileID: 205485171} + m_Placeholder: {fileID: 1647829007} + m_VerticalScrollbar: {fileID: 0} + m_VerticalScrollbarEventHandler: {fileID: 0} + m_LayoutGroup: {fileID: 0} + m_ScrollSensitivity: 1 + m_ContentType: 0 + m_InputType: 0 + m_AsteriskChar: 42 + m_KeyboardType: 0 + m_LineType: 0 + m_HideMobileInput: 0 + m_HideSoftKeyboard: 0 + m_CharacterValidation: 0 + m_RegexValue: + m_GlobalPointSize: 14 + m_CharacterLimit: 0 + m_OnEndEdit: + m_PersistentCalls: + m_Calls: [] + m_OnSubmit: + m_PersistentCalls: + m_Calls: [] + m_OnSelect: + m_PersistentCalls: + m_Calls: [] + m_OnDeselect: + m_PersistentCalls: + m_Calls: [] + m_OnTextSelection: + m_PersistentCalls: + m_Calls: [] + m_OnEndTextSelection: + m_PersistentCalls: + m_Calls: [] + m_OnValueChanged: + m_PersistentCalls: + m_Calls: [] + m_OnTouchScreenKeyboardStatusChanged: + m_PersistentCalls: + m_Calls: [] + m_CaretColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_CustomCaretColor: 0 + m_SelectionColor: {r: 0.65882355, g: 0.80784315, b: 1, a: 0.7529412} + m_Text: + m_CaretBlinkRate: 0.85 + m_CaretWidth: 1 + m_ReadOnly: 0 + m_RichText: 1 + m_GlobalFontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_OnFocusSelectAll: 1 + m_ResetOnDeActivation: 1 + m_RestoreOriginalTextOnEscape: 1 + m_isRichTextEditingAllowed: 0 + m_LineLimit: 0 + m_InputValidator: {fileID: 0} +--- !u!114 &1494765191 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1494765188} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10911, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1494765192 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1494765188} + m_CullTransparentMesh: 1 +--- !u!1 &1505492018 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1505492019} + - component: {fileID: 1505492022} + - component: {fileID: 1505492021} + - component: {fileID: 1505492020} + m_Layer: 5 + m_Name: Scrollbar + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1505492019 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1505492018} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 71217033} + m_Father: {fileID: 1874048011} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 1, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 20, y: 0} + m_Pivot: {x: 1, y: 1} +--- !u!114 &1505492020 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1505492018} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2a4db7a114972834c8e4117be1d82ba3, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1478252377} + m_HandleRect: {fileID: 1478252376} + m_Direction: 2 + m_Value: 0 + m_Size: 0.2 + m_NumberOfSteps: 0 + m_OnValueChanged: + m_PersistentCalls: + m_Calls: [] +--- !u!114 &1505492021 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1505492018} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1505492022 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1505492018} + m_CullTransparentMesh: 1 +--- !u!1 &1513583403 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1513583404} + - component: {fileID: 1513583407} + - component: {fileID: 1513583406} + - component: {fileID: 1513583405} + m_Layer: 5 + m_Name: BtnRequestAirdrop + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1513583404 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1513583403} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1002089370} + m_Father: {fileID: 2026027259} + m_RootOrder: 3 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.08154979, y: 0.04308063} + m_AnchorMax: {x: 0.46716505, y: 0.15817142} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: -2, y: -0.79019165} + m_Pivot: {x: 0.5, y: 0} +--- !u!114 &1513583405 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1513583403} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1513583406} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 2026027260} + m_TargetAssemblyTypeName: WalletScreen, Assembly-CSharp + m_MethodName: RequestAirdrop + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 +--- !u!114 &1513583406 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1513583403} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.9764706, g: 0.17254902, b: 0.8156863, a: 0.69411767} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: d426dc3b537914150b0df30f95e20748, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1513583407 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1513583403} + m_CullTransparentMesh: 1 +--- !u!1 &1524290440 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1524290441} + - component: {fileID: 1524290444} + - component: {fileID: 1524290443} + - component: {fileID: 1524290442} + m_Layer: 5 + m_Name: Scroll View + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1524290441 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1524290440} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 395266777} + - {fileID: 1870937327} + - {fileID: 168030517} + m_Father: {fileID: 234428083} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 4.266, y: 30.279587} + m_SizeDelta: {x: 447.83, y: 340.5592} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1524290442 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1524290440} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 1aa08ab6e0800fa44ae55d278d1423e3, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Content: {fileID: 717344525} + m_Horizontal: 0 + m_Vertical: 1 + m_MovementType: 1 + m_Elasticity: 0.1 + m_Inertia: 1 + m_DecelerationRate: 0.135 + m_ScrollSensitivity: 1 + m_Viewport: {fileID: 395266777} + m_HorizontalScrollbar: {fileID: 1870937328} + m_VerticalScrollbar: {fileID: 168030518} + m_HorizontalScrollbarVisibility: 2 + m_VerticalScrollbarVisibility: 2 + m_HorizontalScrollbarSpacing: -3 + m_VerticalScrollbarSpacing: -3 + m_OnValueChanged: + m_PersistentCalls: + m_Calls: [] +--- !u!114 &1524290443 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1524290440} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: d426dc3b537914150b0df30f95e20748, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1524290444 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1524290440} + m_CullTransparentMesh: 1 +--- !u!1 &1557106041 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1557106042} + - component: {fileID: 1557106044} + - component: {fileID: 1557106043} + m_Layer: 5 + m_Name: TxtClose + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1557106042 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1557106041} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 457188606} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1557106043 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1557106041} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: TRANSFER + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4278321666 + m_fontColor: {r: 0.009433985, g: 0.009433985, b: 0.009433985, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: 97690656 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 20 + m_fontSizeBase: 20 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 0 + m_fontSizeMax: 0 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &1557106044 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1557106041} + m_CullTransparentMesh: 1 +--- !u!1 &1573948528 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1573948529} + - component: {fileID: 1573948532} + - component: {fileID: 1573948531} + - component: {fileID: 1573948530} + m_Layer: 5 + m_Name: Placeholder + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1573948529 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1573948528} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 2044982344} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1573948530 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1573948528} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreLayout: 1 + m_MinWidth: -1 + m_MinHeight: -1 + m_PreferredWidth: -1 + m_PreferredHeight: -1 + m_FlexibleWidth: -1 + m_FlexibleHeight: -1 + m_LayoutPriority: 1 +--- !u!114 &1573948531 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1573948528} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Amount + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 2150773298 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 0.5} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 20 + m_fontSizeBase: 20 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 1 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 1 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &1573948532 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1573948528} + m_CullTransparentMesh: 1 +--- !u!1 &1588423115 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1588423116} + - component: {fileID: 1588423118} + - component: {fileID: 1588423117} + - component: {fileID: 1588423119} + m_Layer: 5 + m_Name: Loading + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 0 +--- !u!224 &1588423116 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1588423115} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1887713060} + m_RootOrder: 5 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.31} + m_AnchorMax: {x: 0.5, y: 0.31} + m_AnchoredPosition: {x: 0, y: 0.30000305} + m_SizeDelta: {x: 101, y: 95} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1588423117 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1588423115} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: fd7cd1a200ca84200836cd8800b3020b, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1588423118 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1588423115} + m_CullTransparentMesh: 1 +--- !u!95 &1588423119 +Animator: + serializedVersion: 4 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1588423115} + m_Enabled: 1 + m_Avatar: {fileID: 0} + m_Controller: {fileID: 9100000, guid: 6e71013b992a04010ab6ec826060cdf6, type: 2} + m_CullingMode: 0 + m_UpdateMode: 0 + m_ApplyRootMotion: 0 + m_LinearVelocityBlending: 0 + m_StabilizeFeet: 0 + m_WarningMessage: + m_HasTransformHierarchy: 1 + m_AllowConstantClipSamplingOptimization: 1 + m_KeepAnimatorControllerStateOnDisable: 0 +--- !u!1 &1598920924 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1598920925} + - component: {fileID: 1598920927} + - component: {fileID: 1598920926} + m_Layer: 5 + m_Name: TxtPublicKey + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1598920925 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1598920924} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 2026027259} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.18271708, y: 0.8843641} + m_AnchorMax: {x: 0.82198864, y: 0.9840138} + m_AnchoredPosition: {x: -12.000061, y: 0} + m_SizeDelta: {x: -316, y: -1} + m_Pivot: {x: 0.5, y: 1} +--- !u!114 &1598920926 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1598920924} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 36 + m_fontSizeBase: 36 + m_fontWeight: 400 + m_enableAutoSizing: 1 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 1 + m_VerticalAlignment: 256 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: -146.61484, y: 0, z: -168.80011, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &1598920927 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1598920924} + m_CullTransparentMesh: 1 +--- !u!1 &1633119660 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1633119661} + - component: {fileID: 1633119663} + - component: {fileID: 1633119662} + m_Layer: 5 + m_Name: Panel + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1633119661 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1633119660} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 2026027259} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1633119662 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1633119660} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: 55573cdcc754d4f3ca243abbcf23b2d3, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1633119663 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1633119660} + m_CullTransparentMesh: 1 +--- !u!1 &1637158285 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1637158286} + - component: {fileID: 1637158289} + - component: {fileID: 1637158288} + - component: {fileID: 1637158287} + m_Layer: 5 + m_Name: InputFieldAmount + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1637158286 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1637158285} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 2044982344} + m_Father: {fileID: 1257448179} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.13161282, y: 0.6171403} + m_AnchorMax: {x: 0.5250409, y: 0.7244367} + m_AnchoredPosition: {x: 1, y: 0} + m_SizeDelta: {x: -2, y: -2} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1637158287 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1637158285} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2da0c512f12947e489f739169773d7ca, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1637158288} + m_TextViewport: {fileID: 2044982344} + m_TextComponent: {fileID: 740345444} + m_Placeholder: {fileID: 1573948531} + m_VerticalScrollbar: {fileID: 0} + m_VerticalScrollbarEventHandler: {fileID: 0} + m_LayoutGroup: {fileID: 0} + m_ScrollSensitivity: 1 + m_ContentType: 3 + m_InputType: 0 + m_AsteriskChar: 42 + m_KeyboardType: 2 + m_LineType: 0 + m_HideMobileInput: 0 + m_HideSoftKeyboard: 0 + m_CharacterValidation: 3 + m_RegexValue: + m_GlobalPointSize: 20 + m_CharacterLimit: 0 + m_OnEndEdit: + m_PersistentCalls: + m_Calls: [] + m_OnSubmit: + m_PersistentCalls: + m_Calls: [] + m_OnSelect: + m_PersistentCalls: + m_Calls: [] + m_OnDeselect: + m_PersistentCalls: + m_Calls: [] + m_OnTextSelection: + m_PersistentCalls: + m_Calls: [] + m_OnEndTextSelection: + m_PersistentCalls: + m_Calls: [] + m_OnValueChanged: + m_PersistentCalls: + m_Calls: [] + m_OnTouchScreenKeyboardStatusChanged: + m_PersistentCalls: + m_Calls: [] + m_CaretColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_CustomCaretColor: 0 + m_SelectionColor: {r: 0.65882355, g: 0.80784315, b: 1, a: 0.7529412} + m_Text: + m_CaretBlinkRate: 0.85 + m_CaretWidth: 1 + m_ReadOnly: 0 + m_RichText: 1 + m_GlobalFontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_OnFocusSelectAll: 1 + m_ResetOnDeActivation: 1 + m_RestoreOriginalTextOnEscape: 1 + m_isRichTextEditingAllowed: 0 + m_LineLimit: 0 + m_InputValidator: {fileID: 0} +--- !u!114 &1637158288 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1637158285} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10911, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1637158289 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1637158285} + m_CullTransparentMesh: 1 +--- !u!1 &1642083670 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1642083671} + - component: {fileID: 1642083673} + - component: {fileID: 1642083672} + m_Layer: 5 + m_Name: TxtCreateAccount + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1642083671 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1642083670} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1977574691} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1642083672 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1642083670} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: CREATE ACCOUNT + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: 97690656 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 20 + m_fontSizeBase: 20 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 0 + m_fontSizeMax: 0 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &1642083673 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1642083670} + m_CullTransparentMesh: 1 +--- !u!1 &1646169727 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1646169728} + - component: {fileID: 1646169730} + - component: {fileID: 1646169729} + m_Layer: 5 + m_Name: TxtHistory + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1646169728 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1646169727} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 717344525} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: -0.89759827, y: 0} + m_SizeDelta: {x: -23.3396, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1646169729 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1646169727} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Loading history ................. + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4278190080 + m_fontColor: {r: 0, g: 0, b: 0, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 30 + m_fontSizeBase: 20 + m_fontWeight: 400 + m_enableAutoSizing: 1 + m_fontSizeMin: 18 + m_fontSizeMax: 30 + m_fontStyle: 0 + m_HorizontalAlignment: 1 + m_VerticalAlignment: 256 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 18.532318, y: 83.61856, z: -9.98053, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &1646169730 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1646169727} + m_CullTransparentMesh: 1 +--- !u!1 &1647829004 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1647829005} + - component: {fileID: 1647829008} + - component: {fileID: 1647829007} + - component: {fileID: 1647829006} + m_Layer: 5 + m_Name: Placeholder + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1647829005 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1647829004} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 58222923} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.03695129, y: 0.1534396} + m_AnchorMax: {x: 0.96764094, y: 0.88993835} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1647829006 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1647829004} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreLayout: 1 + m_MinWidth: -1 + m_MinHeight: -1 + m_PreferredWidth: -1 + m_PreferredHeight: -1 + m_FlexibleWidth: -1 + m_FlexibleHeight: -1 + m_LayoutPriority: 1 +--- !u!114 &1647829007 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1647829004} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Private Key or Mnemonics + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 2150773298 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 0.5} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 63.6 + m_fontSizeBase: 14 + m_fontWeight: 400 + m_enableAutoSizing: 1 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 256 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 1 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &1647829008 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1647829004} + m_CullTransparentMesh: 1 +--- !u!1 &1681756777 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1681756778} + - component: {fileID: 1681756780} + - component: {fileID: 1681756779} + m_Layer: 5 + m_Name: Handle + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1681756778 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1681756777} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1728334077} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1681756779 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1681756777} + m_Enabled: 0 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1681756780 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1681756777} + m_CullTransparentMesh: 1 +--- !u!1 &1687982966 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1687982967} + - component: {fileID: 1687982969} + - component: {fileID: 1687982968} + m_Layer: 5 + m_Name: TexKIN + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1687982967 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1687982966} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1257448179} + m_RootOrder: 3 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.54334205, y: 0.6171403} + m_AnchorMax: {x: 0.894611, y: 0.71468633} + m_AnchoredPosition: {x: 7, y: 0.5} + m_SizeDelta: {x: -12, y: -3} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1687982968 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1687982966} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: KIN + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 36 + m_fontSizeBase: 36 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 1 + m_VerticalAlignment: 256 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: -12.702942, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &1687982969 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1687982966} + m_CullTransparentMesh: 1 +--- !u!1 &1698028096 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1698028097} + - component: {fileID: 1698028099} + - component: {fileID: 1698028098} + m_Layer: 5 + m_Name: TxtRequestAirdrop + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1698028097 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1698028096} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 190750846} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1698028098 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1698028096} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: TRANSFER + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: 97690656 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 20 + m_fontSizeBase: 20 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 0 + m_fontSizeMax: 0 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &1698028099 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1698028096} + m_CullTransparentMesh: 1 +--- !u!1 &1728334076 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1728334077} + m_Layer: 5 + m_Name: Sliding Area + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1728334077 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1728334076} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1681756778} + m_Father: {fileID: 168030517} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: -20, y: -20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!1 &1732370166 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1732370168} + - component: {fileID: 1732370167} + m_Layer: 0 + m_Name: GameController + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1732370167 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1732370166} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d17962196a1414ee49af90f1ae9f87f9, type: 3} + m_Name: + m_EditorClassIdentifier: + endpoint: https://sandbox.kinetic.host/ + environment: devnet + index: 399 + canvasLogin: {fileID: 1887713056} + canvasWallet: {fileID: 2026027255} +--- !u!4 &1732370168 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1732370166} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 3 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1754763206 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1754763207} + - component: {fileID: 1754763210} + - component: {fileID: 1754763209} + - component: {fileID: 1754763208} + m_Layer: 5 + m_Name: BtnClose + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1754763207 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1754763206} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1466237472} + m_Father: {fileID: 234428083} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.13161282, y: 0.053638067} + m_AnchorMax: {x: 0.90124285, y: 0.16889244} + m_AnchoredPosition: {x: -1.211853, y: -5.321686} + m_SizeDelta: {x: 1.4906311, y: 6.1647263} + m_Pivot: {x: 0.5, y: 0} +--- !u!114 &1754763208 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1754763206} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1754763209} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 234428082} + m_TargetAssemblyTypeName: UnityEngine.GameObject, UnityEngine + m_MethodName: SetActive + m_Mode: 6 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 +--- !u!114 &1754763209 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1754763206} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: d426dc3b537914150b0df30f95e20748, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1754763210 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1754763206} + m_CullTransparentMesh: 1 +--- !u!1 &1784266764 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1784266765} + - component: {fileID: 1784266767} + - component: {fileID: 1784266766} + m_Layer: 5 + m_Name: Item Label + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1784266765 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1784266764} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 665457121} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 5, y: -0.5} + m_SizeDelta: {x: -30, y: -3} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1784266766 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1784266764} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Option A + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: 0 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 14 + m_fontSizeBase: 14 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 1 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &1784266767 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1784266764} + m_CullTransparentMesh: 1 +--- !u!1 &1870937326 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1870937327} + - component: {fileID: 1870937330} + - component: {fileID: 1870937329} + - component: {fileID: 1870937328} + m_Layer: 5 + m_Name: Scrollbar Horizontal + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1870937327 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1870937326} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 704828155} + m_Father: {fileID: 1524290441} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: -17, y: 20} + m_Pivot: {x: 0, y: 0} +--- !u!114 &1870937328 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1870937326} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2a4db7a114972834c8e4117be1d82ba3, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 581214751} + m_HandleRect: {fileID: 581214750} + m_Direction: 0 + m_Value: 0 + m_Size: 1 + m_NumberOfSteps: 0 + m_OnValueChanged: + m_PersistentCalls: + m_Calls: [] +--- !u!114 &1870937329 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1870937326} + m_Enabled: 0 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1870937330 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1870937326} + m_CullTransparentMesh: 1 +--- !u!1 &1874048010 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1874048011} + - component: {fileID: 1874048014} + - component: {fileID: 1874048013} + - component: {fileID: 1874048012} + m_Layer: 5 + m_Name: Template + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 0 +--- !u!224 &1874048011 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1874048010} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 2143904337} + - {fileID: 1505492019} + m_Father: {fileID: 276866468} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 0} + m_AnchoredPosition: {x: 0, y: 2} + m_SizeDelta: {x: 0, y: 150} + m_Pivot: {x: 0.5, y: 1} +--- !u!114 &1874048012 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1874048010} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 1aa08ab6e0800fa44ae55d278d1423e3, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Content: {fileID: 56093882} + m_Horizontal: 0 + m_Vertical: 1 + m_MovementType: 2 + m_Elasticity: 0.1 + m_Inertia: 1 + m_DecelerationRate: 0.135 + m_ScrollSensitivity: 1 + m_Viewport: {fileID: 2143904337} + m_HorizontalScrollbar: {fileID: 0} + m_VerticalScrollbar: {fileID: 1505492020} + m_HorizontalScrollbarVisibility: 0 + m_VerticalScrollbarVisibility: 2 + m_HorizontalScrollbarSpacing: 0 + m_VerticalScrollbarSpacing: -3 + m_OnValueChanged: + m_PersistentCalls: + m_Calls: [] +--- !u!114 &1874048013 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1874048010} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1874048014 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1874048010} + m_CullTransparentMesh: 1 +--- !u!1 &1887713056 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1887713060} + - component: {fileID: 1887713059} + - component: {fileID: 1887713058} + - component: {fileID: 1887713057} + - component: {fileID: 1887713061} + m_Layer: 5 + m_Name: CanvasLogin + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1887713057 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1887713056} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreReversedGraphics: 1 + m_BlockingObjects: 0 + m_BlockingMask: + serializedVersion: 2 + m_Bits: 4294967295 +--- !u!114 &1887713058 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1887713056} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3} + m_Name: + m_EditorClassIdentifier: + m_UiScaleMode: 0 + m_ReferencePixelsPerUnit: 100 + m_ScaleFactor: 1 + m_ReferenceResolution: {x: 800, y: 600} + m_ScreenMatchMode: 0 + m_MatchWidthOrHeight: 0 + m_PhysicalUnit: 3 + m_FallbackScreenDPI: 96 + m_DefaultSpriteDPI: 96 + m_DynamicPixelsPerUnit: 1 + m_PresetInfoIsWorld: 0 +--- !u!223 &1887713059 +Canvas: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1887713056} + m_Enabled: 1 + serializedVersion: 3 + m_RenderMode: 0 + m_Camera: {fileID: 0} + m_PlaneDistance: 100 + m_PixelPerfect: 0 + m_ReceivesEvents: 1 + m_OverrideSorting: 0 + m_OverridePixelPerfect: 0 + m_SortingBucketNormalizedSize: 0 + m_AdditionalShaderChannelsFlag: 25 + m_SortingLayerID: 0 + m_SortingOrder: 0 + m_TargetDisplay: 0 +--- !u!224 &1887713060 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1887713056} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 0, y: 0, z: 0} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 975210817} + - {fileID: 1977574691} + - {fileID: 862687849} + - {fileID: 787690795} + - {fileID: 1494765189} + - {fileID: 1588423116} + m_Father: {fileID: 0} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0, y: 0} +--- !u!222 &1887713061 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1887713056} + m_CullTransparentMesh: 1 +--- !u!1 &1931057016 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1931057017} + - component: {fileID: 1931057019} + - component: {fileID: 1931057018} + m_Layer: 5 + m_Name: TxtLogin + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1931057017 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1931057016} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 862687849} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1931057018 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1931057016} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: LOGIN + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: 97690656 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 20 + m_fontSizeBase: 20 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 0 + m_fontSizeMax: 0 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &1931057019 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1931057016} + m_CullTransparentMesh: 1 +--- !u!1 &1952579025 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1952579026} + - component: {fileID: 1952579027} + m_Layer: 5 + m_Name: Text Area + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1952579026 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1952579025} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 306602515} + - {fileID: 1261229068} + m_Father: {fileID: 1037139894} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: -0.5} + m_SizeDelta: {x: -20, y: -13} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1952579027 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1952579025} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 3312d7739989d2b4e91e6319e9a96d76, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Padding: {x: -8, y: -5, z: -8, w: -5} + m_Softness: {x: 0, y: 0} +--- !u!1 &1977574690 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1977574691} + - component: {fileID: 1977574694} + - component: {fileID: 1977574693} + - component: {fileID: 1977574692} + m_Layer: 5 + m_Name: BtnCreateAccount + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1977574691 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1977574690} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1642083671} + m_Father: {fileID: 1887713060} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.2594222, y: 0.062000003} + m_AnchorMax: {x: 0.73709637, y: 0.19234458} + m_AnchoredPosition: {x: -0.34960938, y: 0} + m_SizeDelta: {x: -2, y: -0.79019165} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1977574692 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1977574690} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1977574693} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 1732370167} + m_TargetAssemblyTypeName: GameController, Assembly-CSharp + m_MethodName: CreateNewAccount + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 + - m_Target: {fileID: 1588423115} + m_TargetAssemblyTypeName: UnityEngine.GameObject, UnityEngine + m_MethodName: SetActive + m_Mode: 6 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 1 + m_CallState: 2 +--- !u!114 &1977574693 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1977574690} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.9764706, g: 0.17254902, b: 0.8156863, a: 0.69411767} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: d426dc3b537914150b0df30f95e20748, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1977574694 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1977574690} + m_CullTransparentMesh: 1 +--- !u!1 &2026027255 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2026027259} + - component: {fileID: 2026027258} + - component: {fileID: 2026027257} + - component: {fileID: 2026027256} + - component: {fileID: 2026027260} + m_Layer: 5 + m_Name: CanvasWallet + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 0 +--- !u!114 &2026027256 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2026027255} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreReversedGraphics: 1 + m_BlockingObjects: 0 + m_BlockingMask: + serializedVersion: 2 + m_Bits: 4294967295 +--- !u!114 &2026027257 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2026027255} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3} + m_Name: + m_EditorClassIdentifier: + m_UiScaleMode: 0 + m_ReferencePixelsPerUnit: 100 + m_ScaleFactor: 1 + m_ReferenceResolution: {x: 800, y: 600} + m_ScreenMatchMode: 0 + m_MatchWidthOrHeight: 0 + m_PhysicalUnit: 3 + m_FallbackScreenDPI: 96 + m_DefaultSpriteDPI: 96 + m_DynamicPixelsPerUnit: 1 + m_PresetInfoIsWorld: 0 +--- !u!223 &2026027258 +Canvas: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2026027255} + m_Enabled: 1 + serializedVersion: 3 + m_RenderMode: 0 + m_Camera: {fileID: 0} + m_PlaneDistance: 100 + m_PixelPerfect: 0 + m_ReceivesEvents: 1 + m_OverrideSorting: 0 + m_OverridePixelPerfect: 0 + m_SortingBucketNormalizedSize: 0 + m_AdditionalShaderChannelsFlag: 1 + m_SortingLayerID: 0 + m_SortingOrder: 0 + m_TargetDisplay: 0 +--- !u!224 &2026027259 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2026027255} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 0, y: 0, z: 0} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1633119661} + - {fileID: 182563499} + - {fileID: 1598920925} + - {fileID: 1513583404} + - {fileID: 190750846} + - {fileID: 400344509} + - {fileID: 738988725} + - {fileID: 341012197} + - {fileID: 276866468} + - {fileID: 234428083} + - {fileID: 1449580720} + - {fileID: 2050005201} + m_Father: {fileID: 0} + m_RootOrder: 4 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0, y: 0} +--- !u!114 &2026027260 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2026027255} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d36f6de41716147b1a0e7fc138a6498b, type: 3} + m_Name: + m_EditorClassIdentifier: + txtPublicKey: {fileID: 1598920926} + txtBalance: {fileID: 340591502} + txtHistory: {fileID: 1646169729} + txtTokenAccountDesc: {fileID: 341012198} + txtDestination: {fileID: 1037139895} + txtAmount: {fileID: 1637158287} + tokenAccountsDropDown: {fileID: 276866469} + loading: {fileID: 2050005200} +--- !u!1 &2044982343 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2044982344} + - component: {fileID: 2044982345} + m_Layer: 5 + m_Name: Text Area + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2044982344 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2044982343} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1573948529} + - {fileID: 740345443} + m_Father: {fileID: 1637158286} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: -0.5} + m_SizeDelta: {x: -20, y: -13} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &2044982345 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2044982343} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 3312d7739989d2b4e91e6319e9a96d76, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Padding: {x: -8, y: -5, z: -8, w: -5} + m_Softness: {x: 0, y: 0} +--- !u!1 &2050005200 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2050005201} + - component: {fileID: 2050005204} + - component: {fileID: 2050005203} + - component: {fileID: 2050005202} + m_Layer: 5 + m_Name: Loading + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 0 +--- !u!224 &2050005201 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2050005200} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 2026027259} + m_RootOrder: 11 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 101, y: 95} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!95 &2050005202 +Animator: + serializedVersion: 4 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2050005200} + m_Enabled: 1 + m_Avatar: {fileID: 0} + m_Controller: {fileID: 9100000, guid: 6e71013b992a04010ab6ec826060cdf6, type: 2} + m_CullingMode: 0 + m_UpdateMode: 0 + m_ApplyRootMotion: 0 + m_LinearVelocityBlending: 0 + m_StabilizeFeet: 0 + m_WarningMessage: + m_HasTransformHierarchy: 1 + m_AllowConstantClipSamplingOptimization: 1 + m_KeepAnimatorControllerStateOnDisable: 0 +--- !u!114 &2050005203 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2050005200} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: fd7cd1a200ca84200836cd8800b3020b, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &2050005204 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2050005200} + m_CullTransparentMesh: 1 +--- !u!1 &2143904336 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2143904337} + - component: {fileID: 2143904340} + - component: {fileID: 2143904339} + - component: {fileID: 2143904338} + m_Layer: 5 + m_Name: Viewport + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2143904337 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2143904336} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 56093882} + m_Father: {fileID: 1874048011} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: -18, y: 0} + m_Pivot: {x: 0, y: 1} +--- !u!114 &2143904338 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2143904336} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10917, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &2143904339 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2143904336} + m_CullTransparentMesh: 1 +--- !u!114 &2143904340 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2143904336} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 31a19414c41e5ae4aae2af33fee712f6, type: 3} + m_Name: + m_EditorClassIdentifier: + m_ShowMaskGraphic: 0 +--- !u!1 &2144804967 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2144804968} + - component: {fileID: 2144804970} + - component: {fileID: 2144804969} + m_Layer: 5 + m_Name: TxtGetHistory + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2144804968 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2144804967} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 400344509} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &2144804969 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2144804967} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: HISTORY + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: 97690656 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 20 + m_fontSizeBase: 20 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 0 + m_fontSizeMax: 0 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &2144804970 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2144804967} + m_CullTransparentMesh: 1 diff --git a/Runtime/Kinetic/Generated.csproj.meta b/ExampleKinSDK/Scenes/KinSampleScene.unity.meta similarity index 74% rename from Runtime/Kinetic/Generated.csproj.meta rename to ExampleKinSDK/Scenes/KinSampleScene.unity.meta index ca2afb2..c1e3c88 100644 --- a/Runtime/Kinetic/Generated.csproj.meta +++ b/ExampleKinSDK/Scenes/KinSampleScene.unity.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 3f0bd622052884eac838e59ce305d83b +guid: 2cda990e2423bbf4892e6590ba056729 DefaultImporter: externalObjects: {} userData: diff --git a/ExampleKinSDK/Scripts.meta b/ExampleKinSDK/Scripts.meta new file mode 100644 index 0000000..7fe1480 --- /dev/null +++ b/ExampleKinSDK/Scripts.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 299d3d7f1e36d447d97d3c41f2b647a0 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/ExampleKinSDK/Scripts/GameController.cs b/ExampleKinSDK/Scripts/GameController.cs new file mode 100644 index 0000000..ca3cce7 --- /dev/null +++ b/ExampleKinSDK/Scripts/GameController.cs @@ -0,0 +1,60 @@ +using System; +using Kinetic.Sdk; +using Kinetic.Sdk.Interfaces; +using Solana.Unity.Rpc.Types; +using TMPro; +using UnityEngine; + +public class GameController : MonoBehaviour +{ + public string endpoint = "https://sandbox.kinetic.host/"; + public string environment = "devnet"; + public int index = 1; + public static Keypair Keypair { get; private set; } + public static KineticSdk KineticSdk { get; private set; } + + public GameObject canvasLogin; + public GameObject canvasWallet; + + + + // Start is called before the first frame update + async void Awake() + { + Debug.Log("Start setting up SDK"); + KineticSdk = await KineticSdk.Setup( + new KineticSdkConfig( + index: index, + endpoint: endpoint, + environment: environment, + logger: new Logger(Debug.unityLogger.logHandler) + ) + ); + Debug.Log("Finish setting up SDK"); + } + + + public async void CreateNewAccount() + { + Keypair = Keypair.Random(); + await KineticSdk.CreateAccount(Keypair, commitment: Kinetic.Sdk.Interfaces.Commitment.Finalized); + canvasWallet.SetActive(true); + canvasLogin.SetActive(false); + } + + public void Login() + { + var keyOrMnemonics = GameObject.Find("TxtKeyOrMnemonics").GetComponentInChildren().text; + keyOrMnemonics = keyOrMnemonics.Trim().Replace("\u200B", ""); + try + { + Keypair = Keypair.FromMnemonic(keyOrMnemonics); + } + catch (NotSupportedException) + { + Keypair = Keypair.FromSecretKey(keyOrMnemonics); + Keypair.FromSecretKey(keyOrMnemonics); + } + } + +} \ No newline at end of file diff --git a/ExampleKinSDK/Scripts/GameController.cs.meta b/ExampleKinSDK/Scripts/GameController.cs.meta new file mode 100644 index 0000000..a20b51f --- /dev/null +++ b/ExampleKinSDK/Scripts/GameController.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d17962196a1414ee49af90f1ae9f87f9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/ExampleKinSDK/Scripts/WalletScreen.cs b/ExampleKinSDK/Scripts/WalletScreen.cs new file mode 100644 index 0000000..1e8cf85 --- /dev/null +++ b/ExampleKinSDK/Scripts/WalletScreen.cs @@ -0,0 +1,107 @@ +using System; +using Solana.Unity.Rpc.Types; +using TMPro; +using UnityEngine; + +public class WalletScreen : MonoBehaviour +{ + public TextMeshProUGUI txtPublicKey; + public TextMeshProUGUI txtBalance; + public TextMeshProUGUI txtHistory; + public TextMeshProUGUI txtTokenAccountDesc; + public TMP_InputField txtDestination; + public TMP_InputField txtAmount; + public TMP_Dropdown tokenAccountsDropDown; + public GameObject loading; + + private void OnEnable() + { + if (GameController.Keypair != null) + { + txtPublicKey.text = GameController.Keypair.PublicKey; + } + UpdateBalance(); + GetTokenAccounts(); + } + + public async void UpdateBalance() + { + if(GameController.Keypair == null) return; + var balance = await GameController.KineticSdk.GetBalance( account: GameController.Keypair.PublicKey ); + txtBalance.gameObject.transform.parent.gameObject.SetActive(true); + txtBalance.text = (float.Parse(balance.Balance) / Math.Pow(10, 5)).ToString("0.00") + " KIN"; + } + + public async void GetTokenAccounts() + { + if(GameController.Keypair == null) return; + var accounts = await GameController.KineticSdk.GetTokenAccounts( account: GameController.Keypair.PublicKey ); + if(accounts.Count == 0) return; + tokenAccountsDropDown.gameObject.SetActive(true); + txtTokenAccountDesc.gameObject.SetActive(true); + tokenAccountsDropDown.options.Clear(); + foreach (var acc in accounts) + { + tokenAccountsDropDown.options.Add(new TMP_Dropdown.OptionData(acc)); + } + } + + public async void GetHistory() + { + if(GameController.Keypair == null) return; + var history = await GameController.KineticSdk.GetHistory( account: GameController.Keypair.PublicKey ); + txtHistory.text = ""; + foreach (var h in history) + { + txtHistory.text += h.ToJson(); + } + } + + public async void RequestAirdrop() + { + if(GameController.Keypair == null) return; + loading.SetActive(true); + try + { + await GameController.KineticSdk.RequestAirdrop( + account: GameController.Keypair.PublicKey, + amount: "1000" + ); + UpdateBalance(); + } + catch (Exception e) + { + + Debug.LogException(e); + } + + loading.SetActive(false); + } + + public async void MakeTransfer() + { + if(GameController.Keypair == null) return; + loading.SetActive(true); + try + { + await GameController.KineticSdk.MakeTransfer( + amount: txtAmount.text, + destination: txtDestination.text, + owner: GameController.Keypair, + commitment: Kinetic.Sdk.Interfaces.Commitment.Finalized, + senderCreate: true + ); + txtDestination.transform.parent.parent.gameObject.SetActive(false); + UpdateBalance(); + } + catch (Exception e) + { + + txtDestination.text = " - Invalid destination - "; + Debug.LogException(e); + } + loading.SetActive(false); + + } + +} diff --git a/ExampleKinSDK/Scripts/WalletScreen.cs.meta b/ExampleKinSDK/Scripts/WalletScreen.cs.meta new file mode 100644 index 0000000..db781e7 --- /dev/null +++ b/ExampleKinSDK/Scripts/WalletScreen.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d36f6de41716147b1a0e7fc138a6498b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/BouncyCastle.Crypto.dll b/Packages/BouncyCastle.Crypto.dll deleted file mode 100644 index b811138..0000000 Binary files a/Packages/BouncyCastle.Crypto.dll and /dev/null differ diff --git a/Packages/BouncyCastle.Crypto.dll.meta b/Packages/BouncyCastle.Crypto.dll.meta deleted file mode 100644 index 9f6f912..0000000 --- a/Packages/BouncyCastle.Crypto.dll.meta +++ /dev/null @@ -1,33 +0,0 @@ -fileFormatVersion: 2 -guid: 391ec5898d5e744a39076e31e713f6e6 -PluginImporter: - externalObjects: {} - serializedVersion: 2 - iconMap: {} - executionOrder: {} - defineConstraints: [] - isPreloaded: 0 - isOverridable: 1 - isExplicitlyReferenced: 0 - validateReferences: 1 - platformData: - - first: - Any: - second: - enabled: 1 - settings: {} - - first: - Editor: Editor - second: - enabled: 0 - settings: - DefaultValueInitialized: true - - first: - Windows Store Apps: WindowsStoreApps - second: - enabled: 0 - settings: - CPU: AnyCPU - userData: - assetBundleName: - assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1).meta b/Packages/Chaos.NaCl-master (1).meta new file mode 100644 index 0000000..bbdfcfc --- /dev/null +++ b/Packages/Chaos.NaCl-master (1).meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 76b3133f4d8adab44befd3022e6aa139 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master.meta new file mode 100644 index 0000000..7befb06 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c9f4edabff382d54c8110c90d8809ff2 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl.meta new file mode 100644 index 0000000..70c574b --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 6af744c3721b9d3439a91bcf93897c2c +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Chaos.NaCl-Portable.csproj.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Chaos.NaCl-Portable.csproj.meta new file mode 100644 index 0000000..61d2546 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Chaos.NaCl-Portable.csproj.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 7c936c810c7593947bdcc71beb0485d3 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Chaos.NaCl.csproj.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Chaos.NaCl.csproj.meta new file mode 100644 index 0000000..f7b8f73 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Chaos.NaCl.csproj.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: dcf8a97f8f9c8744e93b79a3326c6d7a +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/CryptoBytes.cs b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/CryptoBytes.cs new file mode 100644 index 0000000..477576d --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/CryptoBytes.cs @@ -0,0 +1,190 @@ +using System; +using System.Runtime.CompilerServices; + +namespace Chaos.NaCl +{ + public static class CryptoBytes + { + public static bool ConstantTimeEquals(byte[] x, byte[] y) + { + if (x == null) + throw new ArgumentNullException("x"); + if (y == null) + throw new ArgumentNullException("y"); + if (x.Length != y.Length) + throw new ArgumentException("x.Length must equal y.Length"); + return InternalConstantTimeEquals(x, 0, y, 0, x.Length) != 0; + } + + public static bool ConstantTimeEquals(ArraySegment x, ArraySegment y) + { + if (x.Array == null) + throw new ArgumentNullException("x.Array"); + if (y.Array == null) + throw new ArgumentNullException("y.Array"); + if (x.Count != y.Count) + throw new ArgumentException("x.Count must equal y.Count"); + + return InternalConstantTimeEquals(x.Array, x.Offset, y.Array, y.Offset, x.Count) != 0; + } + + public static bool ConstantTimeEquals(byte[] x, int xOffset, byte[] y, int yOffset, int length) + { + if (x == null) + throw new ArgumentNullException("x"); + if (xOffset < 0) + throw new ArgumentOutOfRangeException("xOffset", "xOffset < 0"); + if (y == null) + throw new ArgumentNullException("y"); + if (yOffset < 0) + throw new ArgumentOutOfRangeException("yOffset", "yOffset < 0"); + if (length < 0) + throw new ArgumentOutOfRangeException("length", "length < 0"); + if (x.Length - xOffset < length) + throw new ArgumentException("xOffset + length > x.Length"); + if (y.Length - yOffset < length) + throw new ArgumentException("yOffset + length > y.Length"); + + return InternalConstantTimeEquals(x, xOffset, y, yOffset, length) != 0; + } + + private static uint InternalConstantTimeEquals(byte[] x, int xOffset, byte[] y, int yOffset, int length) + { + int differentbits = 0; + for (int i = 0; i < length; i++) + differentbits |= x[xOffset + i] ^ y[yOffset + i]; + return (1 & (unchecked((uint)differentbits - 1) >> 8)); + } + + public static void Wipe(byte[] data) + { + if (data == null) + throw new ArgumentNullException("data"); + InternalWipe(data, 0, data.Length); + } + + public static void Wipe(byte[] data, int offset, int count) + { + if (data == null) + throw new ArgumentNullException("data"); + if (offset < 0) + throw new ArgumentOutOfRangeException("offset"); + if (count < 0) + throw new ArgumentOutOfRangeException("count", "Requires count >= 0"); + if ((uint)offset + (uint)count > (uint)data.Length) + throw new ArgumentException("Requires offset + count <= data.Length"); + InternalWipe(data, offset, count); + } + + public static void Wipe(ArraySegment data) + { + if (data.Array == null) + throw new ArgumentNullException("data.Array"); + InternalWipe(data.Array, data.Offset, data.Count); + } + + // Secure wiping is hard + // * the GC can move around and copy memory + // Perhaps this can be avoided by using unmanaged memory or by fixing the position of the array in memory + // * Swap files and error dumps can contain secret information + // It seems possible to lock memory in RAM, no idea about error dumps + // * Compiler could optimize out the wiping if it knows that data won't be read back + // I hope this is enough, suppressing inlining + // but perhaps `RtlSecureZeroMemory` is needed + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void InternalWipe(byte[] data, int offset, int count) + { + Array.Clear(data, offset, count); + } + + // shallow wipe of structs + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void InternalWipe(ref T data) + where T : struct + { + data = default(T); + } + + // constant time hex conversion + // see http://stackoverflow.com/a/14333437/445517 + // + // An explanation of the weird bit fiddling: + // + // 1. `bytes[i] >> 4` extracts the high nibble of a byte + // `bytes[i] & 0xF` extracts the low nibble of a byte + // 2. `b - 10` + // is `< 0` for values `b < 10`, which will become a decimal digit + // is `>= 0` for values `b > 10`, which will become a letter from `A` to `F`. + // 3. Using `i >> 31` on a signed 32 bit integer extracts the sign, thanks to sign extension. + // It will be `-1` for `i < 0` and `0` for `i >= 0`. + // 4. Combining 2) and 3), shows that `(b-10)>>31` will be `0` for letters and `-1` for digits. + // 5. Looking at the case for letters, the last summand becomes `0`, and `b` is in the range 10 to 15. We want to map it to `A`(65) to `F`(70), which implies adding 55 (`'A'-10`). + // 6. Looking at the case for digits, we want to adapt the last summand so it maps `b` from the range 0 to 9 to the range `0`(48) to `9`(57). This means it needs to become -7 (`'0' - 55`). + // Now we could just multiply with 7. But since -1 is represented by all bits being 1, we can instead use `& -7` since `(0 & -7) == 0` and `(-1 & -7) == -7`. + // + // Some further considerations: + // + // * I didn't use a second loop variable to index into `c`, since measurement shows that calculating it from `i` is cheaper. + // * Using exactly `i < bytes.Length` as upper bound of the loop allows the JITter to eliminate bounds checks on `bytes[i]`, so I chose that variant. + // * Making `b` an int avoids unnecessary conversions from and to byte. + public static string ToHexStringUpper(byte[] data) + { + if (data == null) + return null; + char[] c = new char[data.Length * 2]; + int b; + for (int i = 0; i < data.Length; i++) + { + b = data[i] >> 4; + c[i * 2] = (char)(55 + b + (((b - 10) >> 31) & -7)); + b = data[i] & 0xF; + c[i * 2 + 1] = (char)(55 + b + (((b - 10) >> 31) & -7)); + } + return new string(c); + } + + // Explanation is similar to ToHexStringUpper + // constant 55 -> 87 and -7 -> -39 to compensate for the offset 32 between lowercase and uppercase letters + public static string ToHexStringLower(byte[] data) + { + if (data == null) + return null; + char[] c = new char[data.Length * 2]; + int b; + for (int i = 0; i < data.Length; i++) + { + b = data[i] >> 4; + c[i * 2] = (char)(87 + b + (((b - 10) >> 31) & -39)); + b = data[i] & 0xF; + c[i * 2 + 1] = (char)(87 + b + (((b - 10) >> 31) & -39)); + } + return new string(c); + } + + public static byte[] FromHexString(string hexString) + { + if (hexString == null) + return null; + if (hexString.Length % 2 != 0) + throw new FormatException("The hex string is invalid because it has an odd length"); + var result = new byte[hexString.Length / 2]; + for (int i = 0; i < result.Length; i++) + result[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16); + return result; + } + + public static string ToBase64String(byte[] data) + { + if (data == null) + return null; + return Convert.ToBase64String(data); + } + + public static byte[] FromBase64String(string s) + { + if (s == null) + return null; + return Convert.FromBase64String(s); + } + } +} diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/CryptoBytes.cs.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/CryptoBytes.cs.meta new file mode 100644 index 0000000..643d6de --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/CryptoBytes.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cecc3f6662269904ba853b4ad850682e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Ed25519.cs b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Ed25519.cs new file mode 100644 index 0000000..451be28 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Ed25519.cs @@ -0,0 +1,147 @@ +using System; +using Chaos.NaCl.Internal.Ed25519Ref10; + +namespace Chaos.NaCl +{ + public static class Ed25519 + { + public static readonly int PublicKeySizeInBytes = 32; + public static readonly int SignatureSizeInBytes = 64; + public static readonly int ExpandedPrivateKeySizeInBytes = 32 * 2; + public static readonly int PrivateKeySeedSizeInBytes = 32; + public static readonly int SharedKeySizeInBytes = 32; + + public static bool Verify(ArraySegment signature, ArraySegment message, ArraySegment publicKey) + { + if (signature.Count != SignatureSizeInBytes) + throw new ArgumentException(string.Format("Signature size must be {0}", SignatureSizeInBytes), "signature.Count"); + if (publicKey.Count != PublicKeySizeInBytes) + throw new ArgumentException(string.Format("Public key size must be {0}", PublicKeySizeInBytes), "publicKey.Count"); + return Ed25519Operations.crypto_sign_verify(signature.Array, signature.Offset, message.Array, message.Offset, message.Count, publicKey.Array, publicKey.Offset); + } + + public static bool Verify(byte[] signature, byte[] message, byte[] publicKey) + { + if (signature == null) + throw new ArgumentNullException("signature"); + if (message == null) + throw new ArgumentNullException("message"); + if (publicKey == null) + throw new ArgumentNullException("publicKey"); + if (signature.Length != SignatureSizeInBytes) + throw new ArgumentException(string.Format("Signature size must be {0}", SignatureSizeInBytes), "signature.Length"); + if (publicKey.Length != PublicKeySizeInBytes) + throw new ArgumentException(string.Format("Public key size must be {0}", PublicKeySizeInBytes), "publicKey.Length"); + return Ed25519Operations.crypto_sign_verify(signature, 0, message, 0, message.Length, publicKey, 0); + } + + public static void Sign(ArraySegment signature, ArraySegment message, ArraySegment expandedPrivateKey) + { + if (signature.Array == null) + throw new ArgumentNullException("signature.Array"); + if (signature.Count != SignatureSizeInBytes) + throw new ArgumentException("signature.Count"); + if (expandedPrivateKey.Array == null) + throw new ArgumentNullException("expandedPrivateKey.Array"); + if (expandedPrivateKey.Count != ExpandedPrivateKeySizeInBytes) + throw new ArgumentException("expandedPrivateKey.Count"); + if (message.Array == null) + throw new ArgumentNullException("message.Array"); + Ed25519Operations.crypto_sign2(signature.Array, signature.Offset, message.Array, message.Offset, message.Count, expandedPrivateKey.Array, expandedPrivateKey.Offset); + } + + public static byte[] Sign(byte[] message, byte[] expandedPrivateKey) + { + var signature = new byte[SignatureSizeInBytes]; + Sign(new ArraySegment(signature), new ArraySegment(message), new ArraySegment(expandedPrivateKey)); + return signature; + } + + public static byte[] PublicKeyFromSeed(byte[] privateKeySeed) + { + byte[] privateKey; + byte[] publicKey; + KeyPairFromSeed(out publicKey, out privateKey, privateKeySeed); + CryptoBytes.Wipe(privateKey); + return publicKey; + } + + public static byte[] ExpandedPrivateKeyFromSeed(byte[] privateKeySeed) + { + byte[] privateKey; + byte[] publicKey; + KeyPairFromSeed(out publicKey, out privateKey, privateKeySeed); + CryptoBytes.Wipe(publicKey); + return privateKey; + } + + public static void KeyPairFromSeed(out byte[] publicKey, out byte[] expandedPrivateKey, byte[] privateKeySeed) + { + if (privateKeySeed == null) + throw new ArgumentNullException("privateKeySeed"); + if (privateKeySeed.Length != PrivateKeySeedSizeInBytes) + throw new ArgumentException("privateKeySeed"); + var pk = new byte[PublicKeySizeInBytes]; + var sk = new byte[ExpandedPrivateKeySizeInBytes]; + Ed25519Operations.crypto_sign_keypair(pk, 0, sk, 0, privateKeySeed, 0); + publicKey = pk; + expandedPrivateKey = sk; + } + + public static void KeyPairFromSeed(ArraySegment publicKey, ArraySegment expandedPrivateKey, ArraySegment privateKeySeed) + { + if (publicKey.Array == null) + throw new ArgumentNullException("publicKey.Array"); + if (expandedPrivateKey.Array == null) + throw new ArgumentNullException("expandedPrivateKey.Array"); + if (privateKeySeed.Array == null) + throw new ArgumentNullException("privateKeySeed.Array"); + if (publicKey.Count != PublicKeySizeInBytes) + throw new ArgumentException("publicKey.Count"); + if (expandedPrivateKey.Count != ExpandedPrivateKeySizeInBytes) + throw new ArgumentException("expandedPrivateKey.Count"); + if (privateKeySeed.Count != PrivateKeySeedSizeInBytes) + throw new ArgumentException("privateKeySeed.Count"); + Ed25519Operations.crypto_sign_keypair( + publicKey.Array, publicKey.Offset, + expandedPrivateKey.Array, expandedPrivateKey.Offset, + privateKeySeed.Array, privateKeySeed.Offset); + } + + [Obsolete("Needs more testing")] + public static byte[] KeyExchange(byte[] publicKey, byte[] privateKey) + { + var sharedKey = new byte[SharedKeySizeInBytes]; + KeyExchange(new ArraySegment(sharedKey), new ArraySegment(publicKey), new ArraySegment(privateKey)); + return sharedKey; + } + + [Obsolete("Needs more testing")] + public static void KeyExchange(ArraySegment sharedKey, ArraySegment publicKey, ArraySegment privateKey) + { + if (sharedKey.Array == null) + throw new ArgumentNullException("sharedKey.Array"); + if (publicKey.Array == null) + throw new ArgumentNullException("publicKey.Array"); + if (privateKey.Array == null) + throw new ArgumentNullException("privateKey"); + if (sharedKey.Count != 32) + throw new ArgumentException("sharedKey.Count != 32"); + if (publicKey.Count != 32) + throw new ArgumentException("publicKey.Count != 32"); + if (privateKey.Count != 64) + throw new ArgumentException("privateKey.Count != 64"); + + FieldElement montgomeryX, edwardsY, edwardsZ, sharedMontgomeryX; + FieldOperations.fe_frombytes(out edwardsY, publicKey.Array, publicKey.Offset); + FieldOperations.fe_1(out edwardsZ); + MontgomeryCurve25519.EdwardsToMontgomeryX(out montgomeryX, ref edwardsY, ref edwardsZ); + byte[] h = Sha512.Hash(privateKey.Array, privateKey.Offset, 32);//ToDo: Remove alloc + ScalarOperations.sc_clamp(h, 0); + MontgomeryOperations.scalarmult(out sharedMontgomeryX, h, 0, ref montgomeryX); + CryptoBytes.Wipe(h); + FieldOperations.fe_tobytes(sharedKey.Array, sharedKey.Offset, ref sharedMontgomeryX); + MontgomeryCurve25519.KeyExchangeOutputHashNaCl(sharedKey.Array, sharedKey.Offset); + } + } +} \ No newline at end of file diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Ed25519.cs.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Ed25519.cs.meta new file mode 100644 index 0000000..2806c33 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Ed25519.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b1d517d898ebf0b4b93c3ce19a0d1b36 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal.meta new file mode 100644 index 0000000..681ed8d --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5b05b3201a8488348af2661e80ad06f8 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Array16.cs b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Array16.cs new file mode 100644 index 0000000..082bf06 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Array16.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; + +namespace Chaos.NaCl.Internal +{ + // Array16 Salsa20 state + // Array16 SHA-512 block + internal struct Array16 + { + public T x0; + public T x1; + public T x2; + public T x3; + public T x4; + public T x5; + public T x6; + public T x7; + public T x8; + public T x9; + public T x10; + public T x11; + public T x12; + public T x13; + public T x14; + public T x15; + } +} diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Array16.cs.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Array16.cs.meta new file mode 100644 index 0000000..66a9c90 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Array16.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a4bebb38cbfa2a04b8f3ca0cac0381fe +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Array8.cs b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Array8.cs new file mode 100644 index 0000000..f3bc50d --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Array8.cs @@ -0,0 +1,18 @@ +using System; + +namespace Chaos.NaCl.Internal +{ + // Array8 Poly1305 key + // Array8 SHA-512 state/output + internal struct Array8 + { + public T x0; + public T x1; + public T x2; + public T x3; + public T x4; + public T x5; + public T x6; + public T x7; + } +} \ No newline at end of file diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Array8.cs.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Array8.cs.meta new file mode 100644 index 0000000..0ee9800 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Array8.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c4e40fb077a141f49ad2f2ad71c22b83 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/ByteIntegerConverter.cs b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/ByteIntegerConverter.cs new file mode 100644 index 0000000..c90aa5b --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/ByteIntegerConverter.cs @@ -0,0 +1,416 @@ +using System; +using System.Collections.Generic; + +namespace Chaos.NaCl.Internal +{ + // Loops? Arrays? Never heard of that stuff + // Library avoids unnecessary heap allocations and unsafe code + // so this ugly code becomes necessary :( + internal static class ByteIntegerConverter + { + #region Individual + + public static UInt32 LoadLittleEndian32(byte[] buf, int offset) + { + return + (UInt32)(buf[offset + 0]) + | (((UInt32)(buf[offset + 1])) << 8) + | (((UInt32)(buf[offset + 2])) << 16) + | (((UInt32)(buf[offset + 3])) << 24); + } + + public static void StoreLittleEndian32(byte[] buf, int offset, UInt32 value) + { + buf[offset + 0] = unchecked((byte)value); + buf[offset + 1] = unchecked((byte)(value >> 8)); + buf[offset + 2] = unchecked((byte)(value >> 16)); + buf[offset + 3] = unchecked((byte)(value >> 24)); + } + + public static UInt64 LoadBigEndian64(byte[] buf, int offset) + { + return + (UInt64)(buf[offset + 7]) + | (((UInt64)(buf[offset + 6])) << 8) + | (((UInt64)(buf[offset + 5])) << 16) + | (((UInt64)(buf[offset + 4])) << 24) + | (((UInt64)(buf[offset + 3])) << 32) + | (((UInt64)(buf[offset + 2])) << 40) + | (((UInt64)(buf[offset + 1])) << 48) + | (((UInt64)(buf[offset + 0])) << 56); + } + + public static void StoreBigEndian64(byte[] buf, int offset, UInt64 value) + { + buf[offset + 7] = unchecked((byte)value); + buf[offset + 6] = unchecked((byte)(value >> 8)); + buf[offset + 5] = unchecked((byte)(value >> 16)); + buf[offset + 4] = unchecked((byte)(value >> 24)); + buf[offset + 3] = unchecked((byte)(value >> 32)); + buf[offset + 2] = unchecked((byte)(value >> 40)); + buf[offset + 1] = unchecked((byte)(value >> 48)); + buf[offset + 0] = unchecked((byte)(value >> 56)); + } + + /*public static void XorLittleEndian32(byte[] buf, int offset, UInt32 value) + { + buf[offset + 0] ^= (byte)value; + buf[offset + 1] ^= (byte)(value >> 8); + buf[offset + 2] ^= (byte)(value >> 16); + buf[offset + 3] ^= (byte)(value >> 24); + }*/ + + /*public static void XorLittleEndian32(byte[] output, int outputOffset, byte[] input, int inputOffset, UInt32 value) + { + output[outputOffset + 0] = (byte)(input[inputOffset + 0] ^ value); + output[outputOffset + 1] = (byte)(input[inputOffset + 1] ^ (value >> 8)); + output[outputOffset + 2] = (byte)(input[inputOffset + 2] ^ (value >> 16)); + output[outputOffset + 3] = (byte)(input[inputOffset + 3] ^ (value >> 24)); + }*/ + + #endregion + + #region Array8 + + public static void Array8LoadLittleEndian32(out Array8 output, byte[] input, int inputOffset) + { + output.x0 = LoadLittleEndian32(input, inputOffset + 0); + output.x1 = LoadLittleEndian32(input, inputOffset + 4); + output.x2 = LoadLittleEndian32(input, inputOffset + 8); + output.x3 = LoadLittleEndian32(input, inputOffset + 12); + output.x4 = LoadLittleEndian32(input, inputOffset + 16); + output.x5 = LoadLittleEndian32(input, inputOffset + 20); + output.x6 = LoadLittleEndian32(input, inputOffset + 24); + output.x7 = LoadLittleEndian32(input, inputOffset + 28); + } + + /* public static void Array8LoadLittleEndian32(out Array8 output, byte[] input, int inputOffset, int inputLength) + { + #if DEBUG + if (inputLength <= 0) + throw new ArgumentException(); + #endif + int inputEnd = inputOffset + inputLength; + UInt32 highestInt; + switch (inputLength & 3) + { + case 1: + highestInt = input[inputEnd - 1]; + break; + case 2: + highestInt = (uint)( + (input[inputEnd - 1] << 8) | + (input[inputEnd - 2])); + break; + case 3: + highestInt = (uint)( + (input[inputEnd - 1] << 16) | + (input[inputEnd - 2] << 8) | + (input[inputEnd - 3])); + break; + case 0: + highestInt = (uint)( + (input[inputEnd - 1] << 24) | + (input[inputEnd - 2] << 16) | + (input[inputEnd - 3] << 8) | + (input[inputEnd - 4])); + break; + default: + throw new InvalidOperationException(); + } + switch ((inputLength - 1) >> 2) + { + case 7: + output.x7 = highestInt; + output.x6 = LoadLittleEndian32(input, inputOffset + 6 * 4); + output.x5 = LoadLittleEndian32(input, inputOffset + 5 * 4); + output.x4 = LoadLittleEndian32(input, inputOffset + 4 * 4); + output.x3 = LoadLittleEndian32(input, inputOffset + 3 * 4); + output.x2 = LoadLittleEndian32(input, inputOffset + 2 * 4); + output.x1 = LoadLittleEndian32(input, inputOffset + 1 * 4); + output.x0 = LoadLittleEndian32(input, inputOffset + 0 * 4); + return; + case 6: + output.x7 = 0; + output.x6 = highestInt; + output.x5 = LoadLittleEndian32(input, inputOffset + 5 * 4); + output.x4 = LoadLittleEndian32(input, inputOffset + 4 * 4); + output.x3 = LoadLittleEndian32(input, inputOffset + 3 * 4); + output.x2 = LoadLittleEndian32(input, inputOffset + 2 * 4); + output.x1 = LoadLittleEndian32(input, inputOffset + 1 * 4); + output.x0 = LoadLittleEndian32(input, inputOffset + 0 * 4); + return; + case 5: + output.x7 = 0; + output.x6 = 0; + output.x5 = highestInt; + output.x4 = LoadLittleEndian32(input, inputOffset + 4 * 4); + output.x3 = LoadLittleEndian32(input, inputOffset + 3 * 4); + output.x2 = LoadLittleEndian32(input, inputOffset + 2 * 4); + output.x1 = LoadLittleEndian32(input, inputOffset + 1 * 4); + output.x0 = LoadLittleEndian32(input, inputOffset + 0 * 4); + return; + case 4: + output.x7 = 0; + output.x6 = 0; + output.x5 = 0; + output.x4 = highestInt; + output.x3 = LoadLittleEndian32(input, inputOffset + 3 * 4); + output.x2 = LoadLittleEndian32(input, inputOffset + 2 * 4); + output.x1 = LoadLittleEndian32(input, inputOffset + 1 * 4); + output.x0 = LoadLittleEndian32(input, inputOffset + 0 * 4); + return; + case 3: + output.x7 = 0; + output.x6 = 0; + output.x5 = 0; + output.x4 = 0; + output.x3 = highestInt; + output.x2 = LoadLittleEndian32(input, inputOffset + 2 * 4); + output.x1 = LoadLittleEndian32(input, inputOffset + 1 * 4); + output.x0 = LoadLittleEndian32(input, inputOffset + 0 * 4); + return; + case 2: + output.x7 = 0; + output.x6 = 0; + output.x5 = 0; + output.x4 = 0; + output.x3 = 0; + output.x2 = highestInt; + output.x1 = LoadLittleEndian32(input, inputOffset + 1 * 4); + output.x0 = LoadLittleEndian32(input, inputOffset + 0 * 4); + return; + case 1: + output.x7 = 0; + output.x6 = 0; + output.x5 = 0; + output.x4 = 0; + output.x3 = 0; + output.x2 = 0; + output.x1 = highestInt; + output.x0 = LoadLittleEndian32(input, inputOffset + 0 * 4); + return; + case 0: + output.x7 = 0; + output.x6 = 0; + output.x5 = 0; + output.x4 = 0; + output.x3 = 0; + output.x2 = 0; + output.x1 = 0; + output.x0 = highestInt; + return; + default: + throw new InvalidOperationException(); + } + }*/ + + /*public static void Array8XorLittleEndian(byte[] output, int outputOffset, byte[] input, int inputOffset, ref Array8 keyStream, int length) + { +#if DEBUG + InternalAssert(length > 0); +#endif + int outputEnd = outputOffset + length; + UInt32 highestInt; + switch ((length - 1) >> 2) + { + case 7: + highestInt = keyStream.x7; + XorLittleEndian32(output, outputOffset + 6 * 4, input, inputOffset + 6 * 4, keyStream.x6); + XorLittleEndian32(output, outputOffset + 5 * 4, input, inputOffset + 6 * 4, keyStream.x5); + XorLittleEndian32(output, outputOffset + 4 * 4, input, inputOffset + 6 * 4, keyStream.x4); + XorLittleEndian32(output, outputOffset + 3 * 4, input, inputOffset + 6 * 4, keyStream.x3); + XorLittleEndian32(output, outputOffset + 2 * 4, input, inputOffset + 6 * 4, keyStream.x2); + XorLittleEndian32(output, outputOffset + 1 * 4, input, inputOffset + 6 * 4, keyStream.x1); + XorLittleEndian32(output, outputOffset + 0 * 4, input, inputOffset + 6 * 4, keyStream.x0); + break; + case 6: + highestInt = keyStream.x6; + XorLittleEndian32(output, outputOffset + 5 * 4, input, inputOffset + 6 * 4, keyStream.x5); + XorLittleEndian32(output, outputOffset + 4 * 4, input, inputOffset + 6 * 4, keyStream.x4); + XorLittleEndian32(output, outputOffset + 3 * 4, input, inputOffset + 6 * 4, keyStream.x3); + XorLittleEndian32(output, outputOffset + 2 * 4, input, inputOffset + 6 * 4, keyStream.x2); + XorLittleEndian32(output, outputOffset + 1 * 4, input, inputOffset + 6 * 4, keyStream.x1); + XorLittleEndian32(output, outputOffset + 0 * 4, input, inputOffset + 6 * 4, keyStream.x0); + break; + case 5: + highestInt = keyStream.x5; + XorLittleEndian32(output, outputOffset + 4 * 4, input, inputOffset + 6 * 4, keyStream.x4); + XorLittleEndian32(output, outputOffset + 3 * 4, input, inputOffset + 6 * 4, keyStream.x3); + XorLittleEndian32(output, outputOffset + 2 * 4, input, inputOffset + 6 * 4, keyStream.x2); + XorLittleEndian32(output, outputOffset + 1 * 4, input, inputOffset + 6 * 4, keyStream.x1); + XorLittleEndian32(output, outputOffset + 0 * 4, input, inputOffset + 6 * 4, keyStream.x0); + break; + case 4: + highestInt = keyStream.x4; + XorLittleEndian32(output, outputOffset + 3 * 4, input, inputOffset + 6 * 4, keyStream.x3); + XorLittleEndian32(output, outputOffset + 2 * 4, input, inputOffset + 6 * 4, keyStream.x2); + XorLittleEndian32(output, outputOffset + 1 * 4, input, inputOffset + 6 * 4, keyStream.x1); + XorLittleEndian32(output, outputOffset + 0 * 4, input, inputOffset + 6 * 4, keyStream.x0); + break; + case 3: + highestInt = keyStream.x3; + XorLittleEndian32(output, outputOffset + 2 * 4, input, inputOffset + 6 * 4, keyStream.x2); + XorLittleEndian32(output, outputOffset + 1 * 4, input, inputOffset + 6 * 4, keyStream.x1); + XorLittleEndian32(output, outputOffset + 0 * 4, input, inputOffset + 6 * 4, keyStream.x0); + break; + case 2: + highestInt = keyStream.x2; + XorLittleEndian32(output, outputOffset + 1 * 4, input, inputOffset + 6 * 4, keyStream.x1); + XorLittleEndian32(output, outputOffset + 0 * 4, input, inputOffset + 6 * 4, keyStream.x0); + break; + case 1: + highestInt = keyStream.x1; + XorLittleEndian32(output, outputOffset + 0 * 4, input, inputOffset + 6 * 4, keyStream.x0); + break; + case 0: + highestInt = keyStream.x0; + break; + default: + throw new InvalidOperationException(); + } + switch (length & 3) + { + case 1: + output[outputEnd - 1] ^= (byte)highestInt; + break; + case 2: + output[outputEnd - 1] ^= (byte)(highestInt >> 8); + output[outputEnd - 2] ^= (byte)highestInt; + break; + case 3: + output[outputEnd - 1] ^= (byte)(highestInt >> 16); + output[outputEnd - 2] ^= (byte)(highestInt >> 8); + output[outputEnd - 3] ^= (byte)highestInt; + break; + case 0: + output[outputEnd - 1] ^= (byte)(highestInt >> 24); + output[outputEnd - 2] ^= (byte)(highestInt >> 16); + output[outputEnd - 3] ^= (byte)(highestInt >> 8); + output[outputEnd - 4] ^= (byte)highestInt; + break; + default: + throw new InvalidOperationException(); + } + }*/ + + /*public static void Array8StoreLittleEndian32(byte[] output, int outputOffset, ref Array8 input) + { + StoreLittleEndian32(output, outputOffset + 0, input.x0); + StoreLittleEndian32(output, outputOffset + 4, input.x1); + StoreLittleEndian32(output, outputOffset + 8, input.x2); + StoreLittleEndian32(output, outputOffset + 12, input.x3); + StoreLittleEndian32(output, outputOffset + 16, input.x4); + StoreLittleEndian32(output, outputOffset + 20, input.x5); + StoreLittleEndian32(output, outputOffset + 24, input.x6); + StoreLittleEndian32(output, outputOffset + 28, input.x7); + }*/ + #endregion + + public static void Array16LoadBigEndian64(out Array16 output, byte[] input, int inputOffset) + { + output.x0 = LoadBigEndian64(input, inputOffset + 0); + output.x1 = LoadBigEndian64(input, inputOffset + 8); + output.x2 = LoadBigEndian64(input, inputOffset + 16); + output.x3 = LoadBigEndian64(input, inputOffset + 24); + output.x4 = LoadBigEndian64(input, inputOffset + 32); + output.x5 = LoadBigEndian64(input, inputOffset + 40); + output.x6 = LoadBigEndian64(input, inputOffset + 48); + output.x7 = LoadBigEndian64(input, inputOffset + 56); + output.x8 = LoadBigEndian64(input, inputOffset + 64); + output.x9 = LoadBigEndian64(input, inputOffset + 72); + output.x10 = LoadBigEndian64(input, inputOffset + 80); + output.x11 = LoadBigEndian64(input, inputOffset + 88); + output.x12 = LoadBigEndian64(input, inputOffset + 96); + output.x13 = LoadBigEndian64(input, inputOffset + 104); + output.x14 = LoadBigEndian64(input, inputOffset + 112); + output.x15 = LoadBigEndian64(input, inputOffset + 120); + } + + // ToDo: Only used in tests. Remove? + public static void Array16LoadLittleEndian32(out Array16 output, byte[] input, int inputOffset) + { + output.x0 = LoadLittleEndian32(input, inputOffset + 0); + output.x1 = LoadLittleEndian32(input, inputOffset + 4); + output.x2 = LoadLittleEndian32(input, inputOffset + 8); + output.x3 = LoadLittleEndian32(input, inputOffset + 12); + output.x4 = LoadLittleEndian32(input, inputOffset + 16); + output.x5 = LoadLittleEndian32(input, inputOffset + 20); + output.x6 = LoadLittleEndian32(input, inputOffset + 24); + output.x7 = LoadLittleEndian32(input, inputOffset + 28); + output.x8 = LoadLittleEndian32(input, inputOffset + 32); + output.x9 = LoadLittleEndian32(input, inputOffset + 36); + output.x10 = LoadLittleEndian32(input, inputOffset + 40); + output.x11 = LoadLittleEndian32(input, inputOffset + 44); + output.x12 = LoadLittleEndian32(input, inputOffset + 48); + output.x13 = LoadLittleEndian32(input, inputOffset + 52); + output.x14 = LoadLittleEndian32(input, inputOffset + 56); + output.x15 = LoadLittleEndian32(input, inputOffset + 60); + } + + /*public static void Array16LoadLittleEndian32(out Array16 output, byte[] input, int inputOffset, int inputLength) + { + Array8 temp; + if (inputLength > 32) + { + output.x0 = LoadLittleEndian32(input, inputOffset + 0); + output.x1 = LoadLittleEndian32(input, inputOffset + 4); + output.x2 = LoadLittleEndian32(input, inputOffset + 8); + output.x3 = LoadLittleEndian32(input, inputOffset + 12); + output.x4 = LoadLittleEndian32(input, inputOffset + 16); + output.x5 = LoadLittleEndian32(input, inputOffset + 20); + output.x6 = LoadLittleEndian32(input, inputOffset + 24); + output.x7 = LoadLittleEndian32(input, inputOffset + 28); + Array8LoadLittleEndian32(out temp, input, inputOffset + 32, inputLength - 32); + output.x8 = temp.x0; + output.x9 = temp.x1; + output.x10 = temp.x2; + output.x11 = temp.x3; + output.x12 = temp.x4; + output.x13 = temp.x5; + output.x14 = temp.x6; + output.x15 = temp.x7; + } + else + { + Array8LoadLittleEndian32(out temp, input, inputOffset, inputLength); + output.x0 = temp.x0; + output.x1 = temp.x1; + output.x2 = temp.x2; + output.x3 = temp.x3; + output.x4 = temp.x4; + output.x5 = temp.x5; + output.x6 = temp.x6; + output.x7 = temp.x7; + output.x8 = 0; + output.x9 = 0; + output.x10 = 0; + output.x11 = 0; + output.x12 = 0; + output.x13 = 0; + output.x14 = 0; + output.x15 = 0; + } + }*/ + + public static void Array16StoreLittleEndian32(byte[] output, int outputOffset, ref Array16 input) + { + StoreLittleEndian32(output, outputOffset + 0, input.x0); + StoreLittleEndian32(output, outputOffset + 4, input.x1); + StoreLittleEndian32(output, outputOffset + 8, input.x2); + StoreLittleEndian32(output, outputOffset + 12, input.x3); + StoreLittleEndian32(output, outputOffset + 16, input.x4); + StoreLittleEndian32(output, outputOffset + 20, input.x5); + StoreLittleEndian32(output, outputOffset + 24, input.x6); + StoreLittleEndian32(output, outputOffset + 28, input.x7); + StoreLittleEndian32(output, outputOffset + 32, input.x8); + StoreLittleEndian32(output, outputOffset + 36, input.x9); + StoreLittleEndian32(output, outputOffset + 40, input.x10); + StoreLittleEndian32(output, outputOffset + 44, input.x11); + StoreLittleEndian32(output, outputOffset + 48, input.x12); + StoreLittleEndian32(output, outputOffset + 52, input.x13); + StoreLittleEndian32(output, outputOffset + 56, input.x14); + StoreLittleEndian32(output, outputOffset + 60, input.x15); + } + } +} diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/ByteIntegerConverter.cs.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/ByteIntegerConverter.cs.meta new file mode 100644 index 0000000..eeda4fd --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/ByteIntegerConverter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5e028615afa313e40b42074e88b48b5a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10.meta new file mode 100644 index 0000000..acdf9a1 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a94ccbd13de35874b9d41bb59cbea852 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/FieldElement.cs b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/FieldElement.cs new file mode 100644 index 0000000..5a5c785 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/FieldElement.cs @@ -0,0 +1,36 @@ +using System; + +namespace Chaos.NaCl.Internal.Ed25519Ref10 +{ + internal struct FieldElement + { + internal int x0; + internal int x1; + internal int x2; + internal int x3; + internal int x4; + internal int x5; + internal int x6; + internal int x7; + internal int x8; + internal int x9; + + //public static readonly FieldElement Zero = new FieldElement(); + //public static readonly FieldElement One = new FieldElement() { x0 = 1 }; + + internal FieldElement(params int[] elements) + { + InternalAssert.Assert(elements.Length == 10, "elements.Length != 10"); + x0 = elements[0]; + x1 = elements[1]; + x2 = elements[2]; + x3 = elements[3]; + x4 = elements[4]; + x5 = elements[5]; + x6 = elements[6]; + x7 = elements[7]; + x8 = elements[8]; + x9 = elements[9]; + } + } +} diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/FieldElement.cs.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/FieldElement.cs.meta new file mode 100644 index 0000000..bcdf356 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/FieldElement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 67621a159ea0d494a93d25fb60bed3cc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/GroupElement.cs b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/GroupElement.cs new file mode 100644 index 0000000..abeaca8 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/GroupElement.cs @@ -0,0 +1,63 @@ +using System; + +namespace Chaos.NaCl.Internal.Ed25519Ref10 +{ + /* + ge means group element. + + Here the group is the set of pairs (x,y) of field elements (see fe.h) + satisfying -x^2 + y^2 = 1 + d x^2y^2 + where d = -121665/121666. + + Representations: + ge_p2 (projective): (X:Y:Z) satisfying x=X/Z, y=Y/Z + ge_p3 (extended): (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT + ge_p1p1 (completed): ((X:Z),(Y:T)) satisfying x=X/Z, y=Y/T + ge_precomp (Duif): (y+x,y-x,2dxy) + */ + + internal struct GroupElementP2 + { + public FieldElement X; + public FieldElement Y; + public FieldElement Z; + } ; + + internal struct GroupElementP3 + { + public FieldElement X; + public FieldElement Y; + public FieldElement Z; + public FieldElement T; + } ; + + internal struct GroupElementP1P1 + { + public FieldElement X; + public FieldElement Y; + public FieldElement Z; + public FieldElement T; + } ; + + internal struct GroupElementPreComp + { + public FieldElement yplusx; + public FieldElement yminusx; + public FieldElement xy2d; + + public GroupElementPreComp(FieldElement yplusx, FieldElement yminusx, FieldElement xy2d) + { + this.yplusx = yplusx; + this.yminusx = yminusx; + this.xy2d = xy2d; + } + } ; + + internal struct GroupElementCached + { + public FieldElement YplusX; + public FieldElement YminusX; + public FieldElement Z; + public FieldElement T2d; + } ; +} diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/GroupElement.cs.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/GroupElement.cs.meta new file mode 100644 index 0000000..eeb708a --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/GroupElement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fac570495aa125248a54c9ff0b9afb7a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/base.cs b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/base.cs new file mode 100644 index 0000000..5627e9c --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/base.cs @@ -0,0 +1,1357 @@ +using System; + +namespace Chaos.NaCl.Internal.Ed25519Ref10 +{ + internal static partial class LookupTables + { + /* base[i][j] = (j+1)*256^i*B */ + //32*8 + internal static GroupElementPreComp[][] Base = new GroupElementPreComp[][] + { + new[]{ + new GroupElementPreComp( + new FieldElement( 25967493,-14356035,29566456,3660896,-12694345,4014787,27544626,-11754271,-6079156,2047605 ), + new FieldElement( -12545711,934262,-2722910,3049990,-727428,9406986,12720692,5043384,19500929,-15469378 ), + new FieldElement( -8738181,4489570,9688441,-14785194,10184609,-12363380,29287919,11864899,-24514362,-4438546 ) + ), + new GroupElementPreComp( + new FieldElement( -12815894,-12976347,-21581243,11784320,-25355658,-2750717,-11717903,-3814571,-358445,-10211303 ), + new FieldElement( -21703237,6903825,27185491,6451973,-29577724,-9554005,-15616551,11189268,-26829678,-5319081 ), + new FieldElement( 26966642,11152617,32442495,15396054,14353839,-12752335,-3128826,-9541118,-15472047,-4166697 ) + ), + new GroupElementPreComp( + new FieldElement( 15636291,-9688557,24204773,-7912398,616977,-16685262,27787600,-14772189,28944400,-1550024 ), + new FieldElement( 16568933,4717097,-11556148,-1102322,15682896,-11807043,16354577,-11775962,7689662,11199574 ), + new FieldElement( 30464156,-5976125,-11779434,-15670865,23220365,15915852,7512774,10017326,-17749093,-9920357 ) + ), + new GroupElementPreComp( + new FieldElement( -17036878,13921892,10945806,-6033431,27105052,-16084379,-28926210,15006023,3284568,-6276540 ), + new FieldElement( 23599295,-8306047,-11193664,-7687416,13236774,10506355,7464579,9656445,13059162,10374397 ), + new FieldElement( 7798556,16710257,3033922,2874086,28997861,2835604,32406664,-3839045,-641708,-101325 ) + ), + new GroupElementPreComp( + new FieldElement( 10861363,11473154,27284546,1981175,-30064349,12577861,32867885,14515107,-15438304,10819380 ), + new FieldElement( 4708026,6336745,20377586,9066809,-11272109,6594696,-25653668,12483688,-12668491,5581306 ), + new FieldElement( 19563160,16186464,-29386857,4097519,10237984,-4348115,28542350,13850243,-23678021,-15815942 ) + ), + new GroupElementPreComp( + new FieldElement( -15371964,-12862754,32573250,4720197,-26436522,5875511,-19188627,-15224819,-9818940,-12085777 ), + new FieldElement( -8549212,109983,15149363,2178705,22900618,4543417,3044240,-15689887,1762328,14866737 ), + new FieldElement( -18199695,-15951423,-10473290,1707278,-17185920,3916101,-28236412,3959421,27914454,4383652 ) + ), + new GroupElementPreComp( + new FieldElement( 5153746,9909285,1723747,-2777874,30523605,5516873,19480852,5230134,-23952439,-15175766 ), + new FieldElement( -30269007,-3463509,7665486,10083793,28475525,1649722,20654025,16520125,30598449,7715701 ), + new FieldElement( 28881845,14381568,9657904,3680757,-20181635,7843316,-31400660,1370708,29794553,-1409300 ) + ), + new GroupElementPreComp( + new FieldElement( 14499471,-2729599,-33191113,-4254652,28494862,14271267,30290735,10876454,-33154098,2381726 ), + new FieldElement( -7195431,-2655363,-14730155,462251,-27724326,3941372,-6236617,3696005,-32300832,15351955 ), + new FieldElement( 27431194,8222322,16448760,-3907995,-18707002,11938355,-32961401,-2970515,29551813,10109425 ) + ), + }, + new[]{ + new GroupElementPreComp( + new FieldElement( -13657040,-13155431,-31283750,11777098,21447386,6519384,-2378284,-1627556,10092783,-4764171 ), + new FieldElement( 27939166,14210322,4677035,16277044,-22964462,-12398139,-32508754,12005538,-17810127,12803510 ), + new FieldElement( 17228999,-15661624,-1233527,300140,-1224870,-11714777,30364213,-9038194,18016357,4397660 ) + ), + new GroupElementPreComp( + new FieldElement( -10958843,-7690207,4776341,-14954238,27850028,-15602212,-26619106,14544525,-17477504,982639 ), + new FieldElement( 29253598,15796703,-2863982,-9908884,10057023,3163536,7332899,-4120128,-21047696,9934963 ), + new FieldElement( 5793303,16271923,-24131614,-10116404,29188560,1206517,-14747930,4559895,-30123922,-10897950 ) + ), + new GroupElementPreComp( + new FieldElement( -27643952,-11493006,16282657,-11036493,28414021,-15012264,24191034,4541697,-13338309,5500568 ), + new FieldElement( 12650548,-1497113,9052871,11355358,-17680037,-8400164,-17430592,12264343,10874051,13524335 ), + new FieldElement( 25556948,-3045990,714651,2510400,23394682,-10415330,33119038,5080568,-22528059,5376628 ) + ), + new GroupElementPreComp( + new FieldElement( -26088264,-4011052,-17013699,-3537628,-6726793,1920897,-22321305,-9447443,4535768,1569007 ), + new FieldElement( -2255422,14606630,-21692440,-8039818,28430649,8775819,-30494562,3044290,31848280,12543772 ), + new FieldElement( -22028579,2943893,-31857513,6777306,13784462,-4292203,-27377195,-2062731,7718482,14474653 ) + ), + new GroupElementPreComp( + new FieldElement( 2385315,2454213,-22631320,46603,-4437935,-15680415,656965,-7236665,24316168,-5253567 ), + new FieldElement( 13741529,10911568,-33233417,-8603737,-20177830,-1033297,33040651,-13424532,-20729456,8321686 ), + new FieldElement( 21060490,-2212744,15712757,-4336099,1639040,10656336,23845965,-11874838,-9984458,608372 ) + ), + new GroupElementPreComp( + new FieldElement( -13672732,-15087586,-10889693,-7557059,-6036909,11305547,1123968,-6780577,27229399,23887 ), + new FieldElement( -23244140,-294205,-11744728,14712571,-29465699,-2029617,12797024,-6440308,-1633405,16678954 ), + new FieldElement( -29500620,4770662,-16054387,14001338,7830047,9564805,-1508144,-4795045,-17169265,4904953 ) + ), + new GroupElementPreComp( + new FieldElement( 24059557,14617003,19037157,-15039908,19766093,-14906429,5169211,16191880,2128236,-4326833 ), + new FieldElement( -16981152,4124966,-8540610,-10653797,30336522,-14105247,-29806336,916033,-6882542,-2986532 ), + new FieldElement( -22630907,12419372,-7134229,-7473371,-16478904,16739175,285431,2763829,15736322,4143876 ) + ), + new GroupElementPreComp( + new FieldElement( 2379352,11839345,-4110402,-5988665,11274298,794957,212801,-14594663,23527084,-16458268 ), + new FieldElement( 33431127,-11130478,-17838966,-15626900,8909499,8376530,-32625340,4087881,-15188911,-14416214 ), + new FieldElement( 1767683,7197987,-13205226,-2022635,-13091350,448826,5799055,4357868,-4774191,-16323038 ) + ), + }, + new[]{ + new GroupElementPreComp( + new FieldElement( 6721966,13833823,-23523388,-1551314,26354293,-11863321,23365147,-3949732,7390890,2759800 ), + new FieldElement( 4409041,2052381,23373853,10530217,7676779,-12885954,21302353,-4264057,1244380,-12919645 ), + new FieldElement( -4421239,7169619,4982368,-2957590,30256825,-2777540,14086413,9208236,15886429,16489664 ) + ), + new GroupElementPreComp( + new FieldElement( 1996075,10375649,14346367,13311202,-6874135,-16438411,-13693198,398369,-30606455,-712933 ), + new FieldElement( -25307465,9795880,-2777414,14878809,-33531835,14780363,13348553,12076947,-30836462,5113182 ), + new FieldElement( -17770784,11797796,31950843,13929123,-25888302,12288344,-30341101,-7336386,13847711,5387222 ) + ), + new GroupElementPreComp( + new FieldElement( -18582163,-3416217,17824843,-2340966,22744343,-10442611,8763061,3617786,-19600662,10370991 ), + new FieldElement( 20246567,-14369378,22358229,-543712,18507283,-10413996,14554437,-8746092,32232924,16763880 ), + new FieldElement( 9648505,10094563,26416693,14745928,-30374318,-6472621,11094161,15689506,3140038,-16510092 ) + ), + new GroupElementPreComp( + new FieldElement( -16160072,5472695,31895588,4744994,8823515,10365685,-27224800,9448613,-28774454,366295 ), + new FieldElement( 19153450,11523972,-11096490,-6503142,-24647631,5420647,28344573,8041113,719605,11671788 ), + new FieldElement( 8678025,2694440,-6808014,2517372,4964326,11152271,-15432916,-15266516,27000813,-10195553 ) + ), + new GroupElementPreComp( + new FieldElement( -15157904,7134312,8639287,-2814877,-7235688,10421742,564065,5336097,6750977,-14521026 ), + new FieldElement( 11836410,-3979488,26297894,16080799,23455045,15735944,1695823,-8819122,8169720,16220347 ), + new FieldElement( -18115838,8653647,17578566,-6092619,-8025777,-16012763,-11144307,-2627664,-5990708,-14166033 ) + ), + new GroupElementPreComp( + new FieldElement( -23308498,-10968312,15213228,-10081214,-30853605,-11050004,27884329,2847284,2655861,1738395 ), + new FieldElement( -27537433,-14253021,-25336301,-8002780,-9370762,8129821,21651608,-3239336,-19087449,-11005278 ), + new FieldElement( 1533110,3437855,23735889,459276,29970501,11335377,26030092,5821408,10478196,8544890 ) + ), + new GroupElementPreComp( + new FieldElement( 32173121,-16129311,24896207,3921497,22579056,-3410854,19270449,12217473,17789017,-3395995 ), + new FieldElement( -30552961,-2228401,-15578829,-10147201,13243889,517024,15479401,-3853233,30460520,1052596 ), + new FieldElement( -11614875,13323618,32618793,8175907,-15230173,12596687,27491595,-4612359,3179268,-9478891 ) + ), + new GroupElementPreComp( + new FieldElement( 31947069,-14366651,-4640583,-15339921,-15125977,-6039709,-14756777,-16411740,19072640,-9511060 ), + new FieldElement( 11685058,11822410,3158003,-13952594,33402194,-4165066,5977896,-5215017,473099,5040608 ), + new FieldElement( -20290863,8198642,-27410132,11602123,1290375,-2799760,28326862,1721092,-19558642,-3131606 ) + ), + }, + new[]{ + new GroupElementPreComp( + new FieldElement( 7881532,10687937,7578723,7738378,-18951012,-2553952,21820786,8076149,-27868496,11538389 ), + new FieldElement( -19935666,3899861,18283497,-6801568,-15728660,-11249211,8754525,7446702,-5676054,5797016 ), + new FieldElement( -11295600,-3793569,-15782110,-7964573,12708869,-8456199,2014099,-9050574,-2369172,-5877341 ) + ), + new GroupElementPreComp( + new FieldElement( -22472376,-11568741,-27682020,1146375,18956691,16640559,1192730,-3714199,15123619,10811505 ), + new FieldElement( 14352098,-3419715,-18942044,10822655,32750596,4699007,-70363,15776356,-28886779,-11974553 ), + new FieldElement( -28241164,-8072475,-4978962,-5315317,29416931,1847569,-20654173,-16484855,4714547,-9600655 ) + ), + new GroupElementPreComp( + new FieldElement( 15200332,8368572,19679101,15970074,-31872674,1959451,24611599,-4543832,-11745876,12340220 ), + new FieldElement( 12876937,-10480056,33134381,6590940,-6307776,14872440,9613953,8241152,15370987,9608631 ), + new FieldElement( -4143277,-12014408,8446281,-391603,4407738,13629032,-7724868,15866074,-28210621,-8814099 ) + ), + new GroupElementPreComp( + new FieldElement( 26660628,-15677655,8393734,358047,-7401291,992988,-23904233,858697,20571223,8420556 ), + new FieldElement( 14620715,13067227,-15447274,8264467,14106269,15080814,33531827,12516406,-21574435,-12476749 ), + new FieldElement( 236881,10476226,57258,-14677024,6472998,2466984,17258519,7256740,8791136,15069930 ) + ), + new GroupElementPreComp( + new FieldElement( 1276410,-9371918,22949635,-16322807,-23493039,-5702186,14711875,4874229,-30663140,-2331391 ), + new FieldElement( 5855666,4990204,-13711848,7294284,-7804282,1924647,-1423175,-7912378,-33069337,9234253 ), + new FieldElement( 20590503,-9018988,31529744,-7352666,-2706834,10650548,31559055,-11609587,18979186,13396066 ) + ), + new GroupElementPreComp( + new FieldElement( 24474287,4968103,22267082,4407354,24063882,-8325180,-18816887,13594782,33514650,7021958 ), + new FieldElement( -11566906,-6565505,-21365085,15928892,-26158305,4315421,-25948728,-3916677,-21480480,12868082 ), + new FieldElement( -28635013,13504661,19988037,-2132761,21078225,6443208,-21446107,2244500,-12455797,-8089383 ) + ), + new GroupElementPreComp( + new FieldElement( -30595528,13793479,-5852820,319136,-25723172,-6263899,33086546,8957937,-15233648,5540521 ), + new FieldElement( -11630176,-11503902,-8119500,-7643073,2620056,1022908,-23710744,-1568984,-16128528,-14962807 ), + new FieldElement( 23152971,775386,27395463,14006635,-9701118,4649512,1689819,892185,-11513277,-15205948 ) + ), + new GroupElementPreComp( + new FieldElement( 9770129,9586738,26496094,4324120,1556511,-3550024,27453819,4763127,-19179614,5867134 ), + new FieldElement( -32765025,1927590,31726409,-4753295,23962434,-16019500,27846559,5931263,-29749703,-16108455 ), + new FieldElement( 27461885,-2977536,22380810,1815854,-23033753,-3031938,7283490,-15148073,-19526700,7734629 ) + ), + }, + new[]{ + new GroupElementPreComp( + new FieldElement( -8010264,-9590817,-11120403,6196038,29344158,-13430885,7585295,-3176626,18549497,15302069 ), + new FieldElement( -32658337,-6171222,-7672793,-11051681,6258878,13504381,10458790,-6418461,-8872242,8424746 ), + new FieldElement( 24687205,8613276,-30667046,-3233545,1863892,-1830544,19206234,7134917,-11284482,-828919 ) + ), + new GroupElementPreComp( + new FieldElement( 11334899,-9218022,8025293,12707519,17523892,-10476071,10243738,-14685461,-5066034,16498837 ), + new FieldElement( 8911542,6887158,-9584260,-6958590,11145641,-9543680,17303925,-14124238,6536641,10543906 ), + new FieldElement( -28946384,15479763,-17466835,568876,-1497683,11223454,-2669190,-16625574,-27235709,8876771 ) + ), + new GroupElementPreComp( + new FieldElement( -25742899,-12566864,-15649966,-846607,-33026686,-796288,-33481822,15824474,-604426,-9039817 ), + new FieldElement( 10330056,70051,7957388,-9002667,9764902,15609756,27698697,-4890037,1657394,3084098 ), + new FieldElement( 10477963,-7470260,12119566,-13250805,29016247,-5365589,31280319,14396151,-30233575,15272409 ) + ), + new GroupElementPreComp( + new FieldElement( -12288309,3169463,28813183,16658753,25116432,-5630466,-25173957,-12636138,-25014757,1950504 ), + new FieldElement( -26180358,9489187,11053416,-14746161,-31053720,5825630,-8384306,-8767532,15341279,8373727 ), + new FieldElement( 28685821,7759505,-14378516,-12002860,-31971820,4079242,298136,-10232602,-2878207,15190420 ) + ), + new GroupElementPreComp( + new FieldElement( -32932876,13806336,-14337485,-15794431,-24004620,10940928,8669718,2742393,-26033313,-6875003 ), + new FieldElement( -1580388,-11729417,-25979658,-11445023,-17411874,-10912854,9291594,-16247779,-12154742,6048605 ), + new FieldElement( -30305315,14843444,1539301,11864366,20201677,1900163,13934231,5128323,11213262,9168384 ) + ), + new GroupElementPreComp( + new FieldElement( -26280513,11007847,19408960,-940758,-18592965,-4328580,-5088060,-11105150,20470157,-16398701 ), + new FieldElement( -23136053,9282192,14855179,-15390078,-7362815,-14408560,-22783952,14461608,14042978,5230683 ), + new FieldElement( 29969567,-2741594,-16711867,-8552442,9175486,-2468974,21556951,3506042,-5933891,-12449708 ) + ), + new GroupElementPreComp( + new FieldElement( -3144746,8744661,19704003,4581278,-20430686,6830683,-21284170,8971513,-28539189,15326563 ), + new FieldElement( -19464629,10110288,-17262528,-3503892,-23500387,1355669,-15523050,15300988,-20514118,9168260 ), + new FieldElement( -5353335,4488613,-23803248,16314347,7780487,-15638939,-28948358,9601605,33087103,-9011387 ) + ), + new GroupElementPreComp( + new FieldElement( -19443170,-15512900,-20797467,-12445323,-29824447,10229461,-27444329,-15000531,-5996870,15664672 ), + new FieldElement( 23294591,-16632613,-22650781,-8470978,27844204,11461195,13099750,-2460356,18151676,13417686 ), + new FieldElement( -24722913,-4176517,-31150679,5988919,-26858785,6685065,1661597,-12551441,15271676,-15452665 ) + ), + }, + new[]{ + new GroupElementPreComp( + new FieldElement( 11433042,-13228665,8239631,-5279517,-1985436,-725718,-18698764,2167544,-6921301,-13440182 ), + new FieldElement( -31436171,15575146,30436815,12192228,-22463353,9395379,-9917708,-8638997,12215110,12028277 ), + new FieldElement( 14098400,6555944,23007258,5757252,-15427832,-12950502,30123440,4617780,-16900089,-655628 ) + ), + new GroupElementPreComp( + new FieldElement( -4026201,-15240835,11893168,13718664,-14809462,1847385,-15819999,10154009,23973261,-12684474 ), + new FieldElement( -26531820,-3695990,-1908898,2534301,-31870557,-16550355,18341390,-11419951,32013174,-10103539 ), + new FieldElement( -25479301,10876443,-11771086,-14625140,-12369567,1838104,21911214,6354752,4425632,-837822 ) + ), + new GroupElementPreComp( + new FieldElement( -10433389,-14612966,22229858,-3091047,-13191166,776729,-17415375,-12020462,4725005,14044970 ), + new FieldElement( 19268650,-7304421,1555349,8692754,-21474059,-9910664,6347390,-1411784,-19522291,-16109756 ), + new FieldElement( -24864089,12986008,-10898878,-5558584,-11312371,-148526,19541418,8180106,9282262,10282508 ) + ), + new GroupElementPreComp( + new FieldElement( -26205082,4428547,-8661196,-13194263,4098402,-14165257,15522535,8372215,5542595,-10702683 ), + new FieldElement( -10562541,14895633,26814552,-16673850,-17480754,-2489360,-2781891,6993761,-18093885,10114655 ), + new FieldElement( -20107055,-929418,31422704,10427861,-7110749,6150669,-29091755,-11529146,25953725,-106158 ) + ), + new GroupElementPreComp( + new FieldElement( -4234397,-8039292,-9119125,3046000,2101609,-12607294,19390020,6094296,-3315279,12831125 ), + new FieldElement( -15998678,7578152,5310217,14408357,-33548620,-224739,31575954,6326196,7381791,-2421839 ), + new FieldElement( -20902779,3296811,24736065,-16328389,18374254,7318640,6295303,8082724,-15362489,12339664 ) + ), + new GroupElementPreComp( + new FieldElement( 27724736,2291157,6088201,-14184798,1792727,5857634,13848414,15768922,25091167,14856294 ), + new FieldElement( -18866652,8331043,24373479,8541013,-701998,-9269457,12927300,-12695493,-22182473,-9012899 ), + new FieldElement( -11423429,-5421590,11632845,3405020,30536730,-11674039,-27260765,13866390,30146206,9142070 ) + ), + new GroupElementPreComp( + new FieldElement( 3924129,-15307516,-13817122,-10054960,12291820,-668366,-27702774,9326384,-8237858,4171294 ), + new FieldElement( -15921940,16037937,6713787,16606682,-21612135,2790944,26396185,3731949,345228,-5462949 ), + new FieldElement( -21327538,13448259,25284571,1143661,20614966,-8849387,2031539,-12391231,-16253183,-13582083 ) + ), + new GroupElementPreComp( + new FieldElement( 31016211,-16722429,26371392,-14451233,-5027349,14854137,17477601,3842657,28012650,-16405420 ), + new FieldElement( -5075835,9368966,-8562079,-4600902,-15249953,6970560,-9189873,16292057,-8867157,3507940 ), + new FieldElement( 29439664,3537914,23333589,6997794,-17555561,-11018068,-15209202,-15051267,-9164929,6580396 ) + ), + }, + new[]{ + new GroupElementPreComp( + new FieldElement( -12185861,-7679788,16438269,10826160,-8696817,-6235611,17860444,-9273846,-2095802,9304567 ), + new FieldElement( 20714564,-4336911,29088195,7406487,11426967,-5095705,14792667,-14608617,5289421,-477127 ), + new FieldElement( -16665533,-10650790,-6160345,-13305760,9192020,-1802462,17271490,12349094,26939669,-3752294 ) + ), + new GroupElementPreComp( + new FieldElement( -12889898,9373458,31595848,16374215,21471720,13221525,-27283495,-12348559,-3698806,117887 ), + new FieldElement( 22263325,-6560050,3984570,-11174646,-15114008,-566785,28311253,5358056,-23319780,541964 ), + new FieldElement( 16259219,3261970,2309254,-15534474,-16885711,-4581916,24134070,-16705829,-13337066,-13552195 ) + ), + new GroupElementPreComp( + new FieldElement( 9378160,-13140186,-22845982,-12745264,28198281,-7244098,-2399684,-717351,690426,14876244 ), + new FieldElement( 24977353,-314384,-8223969,-13465086,28432343,-1176353,-13068804,-12297348,-22380984,6618999 ), + new FieldElement( -1538174,11685646,12944378,13682314,-24389511,-14413193,8044829,-13817328,32239829,-5652762 ) + ), + new GroupElementPreComp( + new FieldElement( -18603066,4762990,-926250,8885304,-28412480,-3187315,9781647,-10350059,32779359,5095274 ), + new FieldElement( -33008130,-5214506,-32264887,-3685216,9460461,-9327423,-24601656,14506724,21639561,-2630236 ), + new FieldElement( -16400943,-13112215,25239338,15531969,3987758,-4499318,-1289502,-6863535,17874574,558605 ) + ), + new GroupElementPreComp( + new FieldElement( -13600129,10240081,9171883,16131053,-20869254,9599700,33499487,5080151,2085892,5119761 ), + new FieldElement( -22205145,-2519528,-16381601,414691,-25019550,2170430,30634760,-8363614,-31999993,-5759884 ), + new FieldElement( -6845704,15791202,8550074,-1312654,29928809,-12092256,27534430,-7192145,-22351378,12961482 ) + ), + new GroupElementPreComp( + new FieldElement( -24492060,-9570771,10368194,11582341,-23397293,-2245287,16533930,8206996,-30194652,-5159638 ), + new FieldElement( -11121496,-3382234,2307366,6362031,-135455,8868177,-16835630,7031275,7589640,8945490 ), + new FieldElement( -32152748,8917967,6661220,-11677616,-1192060,-15793393,7251489,-11182180,24099109,-14456170 ) + ), + new GroupElementPreComp( + new FieldElement( 5019558,-7907470,4244127,-14714356,-26933272,6453165,-19118182,-13289025,-6231896,-10280736 ), + new FieldElement( 10853594,10721687,26480089,5861829,-22995819,1972175,-1866647,-10557898,-3363451,-6441124 ), + new FieldElement( -17002408,5906790,221599,-6563147,7828208,-13248918,24362661,-2008168,-13866408,7421392 ) + ), + new GroupElementPreComp( + new FieldElement( 8139927,-6546497,32257646,-5890546,30375719,1886181,-21175108,15441252,28826358,-4123029 ), + new FieldElement( 6267086,9695052,7709135,-16603597,-32869068,-1886135,14795160,-7840124,13746021,-1742048 ), + new FieldElement( 28584902,7787108,-6732942,-15050729,22846041,-7571236,-3181936,-363524,4771362,-8419958 ) + ), + }, + new[]{ + new GroupElementPreComp( + new FieldElement( 24949256,6376279,-27466481,-8174608,-18646154,-9930606,33543569,-12141695,3569627,11342593 ), + new FieldElement( 26514989,4740088,27912651,3697550,19331575,-11472339,6809886,4608608,7325975,-14801071 ), + new FieldElement( -11618399,-14554430,-24321212,7655128,-1369274,5214312,-27400540,10258390,-17646694,-8186692 ) + ), + new GroupElementPreComp( + new FieldElement( 11431204,15823007,26570245,14329124,18029990,4796082,-31446179,15580664,9280358,-3973687 ), + new FieldElement( -160783,-10326257,-22855316,-4304997,-20861367,-13621002,-32810901,-11181622,-15545091,4387441 ), + new FieldElement( -20799378,12194512,3937617,-5805892,-27154820,9340370,-24513992,8548137,20617071,-7482001 ) + ), + new GroupElementPreComp( + new FieldElement( -938825,-3930586,-8714311,16124718,24603125,-6225393,-13775352,-11875822,24345683,10325460 ), + new FieldElement( -19855277,-1568885,-22202708,8714034,14007766,6928528,16318175,-1010689,4766743,3552007 ), + new FieldElement( -21751364,-16730916,1351763,-803421,-4009670,3950935,3217514,14481909,10988822,-3994762 ) + ), + new GroupElementPreComp( + new FieldElement( 15564307,-14311570,3101243,5684148,30446780,-8051356,12677127,-6505343,-8295852,13296005 ), + new FieldElement( -9442290,6624296,-30298964,-11913677,-4670981,-2057379,31521204,9614054,-30000824,12074674 ), + new FieldElement( 4771191,-135239,14290749,-13089852,27992298,14998318,-1413936,-1556716,29832613,-16391035 ) + ), + new GroupElementPreComp( + new FieldElement( 7064884,-7541174,-19161962,-5067537,-18891269,-2912736,25825242,5293297,-27122660,13101590 ), + new FieldElement( -2298563,2439670,-7466610,1719965,-27267541,-16328445,32512469,-5317593,-30356070,-4190957 ), + new FieldElement( -30006540,10162316,-33180176,3981723,-16482138,-13070044,14413974,9515896,19568978,9628812 ) + ), + new GroupElementPreComp( + new FieldElement( 33053803,199357,15894591,1583059,27380243,-4580435,-17838894,-6106839,-6291786,3437740 ), + new FieldElement( -18978877,3884493,19469877,12726490,15913552,13614290,-22961733,70104,7463304,4176122 ), + new FieldElement( -27124001,10659917,11482427,-16070381,12771467,-6635117,-32719404,-5322751,24216882,5944158 ) + ), + new GroupElementPreComp( + new FieldElement( 8894125,7450974,-2664149,-9765752,-28080517,-12389115,19345746,14680796,11632993,5847885 ), + new FieldElement( 26942781,-2315317,9129564,-4906607,26024105,11769399,-11518837,6367194,-9727230,4782140 ), + new FieldElement( 19916461,-4828410,-22910704,-11414391,25606324,-5972441,33253853,8220911,6358847,-1873857 ) + ), + new GroupElementPreComp( + new FieldElement( 801428,-2081702,16569428,11065167,29875704,96627,7908388,-4480480,-13538503,1387155 ), + new FieldElement( 19646058,5720633,-11416706,12814209,11607948,12749789,14147075,15156355,-21866831,11835260 ), + new FieldElement( 19299512,1155910,28703737,14890794,2925026,7269399,26121523,15467869,-26560550,5052483 ) + ), + }, + new[]{ + new GroupElementPreComp( + new FieldElement( -3017432,10058206,1980837,3964243,22160966,12322533,-6431123,-12618185,12228557,-7003677 ), + new FieldElement( 32944382,14922211,-22844894,5188528,21913450,-8719943,4001465,13238564,-6114803,8653815 ), + new FieldElement( 22865569,-4652735,27603668,-12545395,14348958,8234005,24808405,5719875,28483275,2841751 ) + ), + new GroupElementPreComp( + new FieldElement( -16420968,-1113305,-327719,-12107856,21886282,-15552774,-1887966,-315658,19932058,-12739203 ), + new FieldElement( -11656086,10087521,-8864888,-5536143,-19278573,-3055912,3999228,13239134,-4777469,-13910208 ), + new FieldElement( 1382174,-11694719,17266790,9194690,-13324356,9720081,20403944,11284705,-14013818,3093230 ) + ), + new GroupElementPreComp( + new FieldElement( 16650921,-11037932,-1064178,1570629,-8329746,7352753,-302424,16271225,-24049421,-6691850 ), + new FieldElement( -21911077,-5927941,-4611316,-5560156,-31744103,-10785293,24123614,15193618,-21652117,-16739389 ), + new FieldElement( -9935934,-4289447,-25279823,4372842,2087473,10399484,31870908,14690798,17361620,11864968 ) + ), + new GroupElementPreComp( + new FieldElement( -11307610,6210372,13206574,5806320,-29017692,-13967200,-12331205,-7486601,-25578460,-16240689 ), + new FieldElement( 14668462,-12270235,26039039,15305210,25515617,4542480,10453892,6577524,9145645,-6443880 ), + new FieldElement( 5974874,3053895,-9433049,-10385191,-31865124,3225009,-7972642,3936128,-5652273,-3050304 ) + ), + new GroupElementPreComp( + new FieldElement( 30625386,-4729400,-25555961,-12792866,-20484575,7695099,17097188,-16303496,-27999779,1803632 ), + new FieldElement( -3553091,9865099,-5228566,4272701,-5673832,-16689700,14911344,12196514,-21405489,7047412 ), + new FieldElement( 20093277,9920966,-11138194,-5343857,13161587,12044805,-32856851,4124601,-32343828,-10257566 ) + ), + new GroupElementPreComp( + new FieldElement( -20788824,14084654,-13531713,7842147,19119038,-13822605,4752377,-8714640,-21679658,2288038 ), + new FieldElement( -26819236,-3283715,29965059,3039786,-14473765,2540457,29457502,14625692,-24819617,12570232 ), + new FieldElement( -1063558,-11551823,16920318,12494842,1278292,-5869109,-21159943,-3498680,-11974704,4724943 ) + ), + new GroupElementPreComp( + new FieldElement( 17960970,-11775534,-4140968,-9702530,-8876562,-1410617,-12907383,-8659932,-29576300,1903856 ), + new FieldElement( 23134274,-14279132,-10681997,-1611936,20684485,15770816,-12989750,3190296,26955097,14109738 ), + new FieldElement( 15308788,5320727,-30113809,-14318877,22902008,7767164,29425325,-11277562,31960942,11934971 ) + ), + new GroupElementPreComp( + new FieldElement( -27395711,8435796,4109644,12222639,-24627868,14818669,20638173,4875028,10491392,1379718 ), + new FieldElement( -13159415,9197841,3875503,-8936108,-1383712,-5879801,33518459,16176658,21432314,12180697 ), + new FieldElement( -11787308,11500838,13787581,-13832590,-22430679,10140205,1465425,12689540,-10301319,-13872883 ) + ), + }, + new[]{ + new GroupElementPreComp( + new FieldElement( 5414091,-15386041,-21007664,9643570,12834970,1186149,-2622916,-1342231,26128231,6032912 ), + new FieldElement( -26337395,-13766162,32496025,-13653919,17847801,-12669156,3604025,8316894,-25875034,-10437358 ), + new FieldElement( 3296484,6223048,24680646,-12246460,-23052020,5903205,-8862297,-4639164,12376617,3188849 ) + ), + new GroupElementPreComp( + new FieldElement( 29190488,-14659046,27549113,-1183516,3520066,-10697301,32049515,-7309113,-16109234,-9852307 ), + new FieldElement( -14744486,-9309156,735818,-598978,-20407687,-5057904,25246078,-15795669,18640741,-960977 ), + new FieldElement( -6928835,-16430795,10361374,5642961,4910474,12345252,-31638386,-494430,10530747,1053335 ) + ), + new GroupElementPreComp( + new FieldElement( -29265967,-14186805,-13538216,-12117373,-19457059,-10655384,-31462369,-2948985,24018831,15026644 ), + new FieldElement( -22592535,-3145277,-2289276,5953843,-13440189,9425631,25310643,13003497,-2314791,-15145616 ), + new FieldElement( -27419985,-603321,-8043984,-1669117,-26092265,13987819,-27297622,187899,-23166419,-2531735 ) + ), + new GroupElementPreComp( + new FieldElement( -21744398,-13810475,1844840,5021428,-10434399,-15911473,9716667,16266922,-5070217,726099 ), + new FieldElement( 29370922,-6053998,7334071,-15342259,9385287,2247707,-13661962,-4839461,30007388,-15823341 ), + new FieldElement( -936379,16086691,23751945,-543318,-1167538,-5189036,9137109,730663,9835848,4555336 ) + ), + new GroupElementPreComp( + new FieldElement( -23376435,1410446,-22253753,-12899614,30867635,15826977,17693930,544696,-11985298,12422646 ), + new FieldElement( 31117226,-12215734,-13502838,6561947,-9876867,-12757670,-5118685,-4096706,29120153,13924425 ), + new FieldElement( -17400879,-14233209,19675799,-2734756,-11006962,-5858820,-9383939,-11317700,7240931,-237388 ) + ), + new GroupElementPreComp( + new FieldElement( -31361739,-11346780,-15007447,-5856218,-22453340,-12152771,1222336,4389483,3293637,-15551743 ), + new FieldElement( -16684801,-14444245,11038544,11054958,-13801175,-3338533,-24319580,7733547,12796905,-6335822 ), + new FieldElement( -8759414,-10817836,-25418864,10783769,-30615557,-9746811,-28253339,3647836,3222231,-11160462 ) + ), + new GroupElementPreComp( + new FieldElement( 18606113,1693100,-25448386,-15170272,4112353,10045021,23603893,-2048234,-7550776,2484985 ), + new FieldElement( 9255317,-3131197,-12156162,-1004256,13098013,-9214866,16377220,-2102812,-19802075,-3034702 ), + new FieldElement( -22729289,7496160,-5742199,11329249,19991973,-3347502,-31718148,9936966,-30097688,-10618797 ) + ), + new GroupElementPreComp( + new FieldElement( 21878590,-5001297,4338336,13643897,-3036865,13160960,19708896,5415497,-7360503,-4109293 ), + new FieldElement( 27736861,10103576,12500508,8502413,-3413016,-9633558,10436918,-1550276,-23659143,-8132100 ), + new FieldElement( 19492550,-12104365,-29681976,-852630,-3208171,12403437,30066266,8367329,13243957,8709688 ) + ), + }, + new[]{ + new GroupElementPreComp( + new FieldElement( 12015105,2801261,28198131,10151021,24818120,-4743133,-11194191,-5645734,5150968,7274186 ), + new FieldElement( 2831366,-12492146,1478975,6122054,23825128,-12733586,31097299,6083058,31021603,-9793610 ), + new FieldElement( -2529932,-2229646,445613,10720828,-13849527,-11505937,-23507731,16354465,15067285,-14147707 ) + ), + new GroupElementPreComp( + new FieldElement( 7840942,14037873,-33364863,15934016,-728213,-3642706,21403988,1057586,-19379462,-12403220 ), + new FieldElement( 915865,-16469274,15608285,-8789130,-24357026,6060030,-17371319,8410997,-7220461,16527025 ), + new FieldElement( 32922597,-556987,20336074,-16184568,10903705,-5384487,16957574,52992,23834301,6588044 ) + ), + new GroupElementPreComp( + new FieldElement( 32752030,11232950,3381995,-8714866,22652988,-10744103,17159699,16689107,-20314580,-1305992 ), + new FieldElement( -4689649,9166776,-25710296,-10847306,11576752,12733943,7924251,-2752281,1976123,-7249027 ), + new FieldElement( 21251222,16309901,-2983015,-6783122,30810597,12967303,156041,-3371252,12331345,-8237197 ) + ), + new GroupElementPreComp( + new FieldElement( 8651614,-4477032,-16085636,-4996994,13002507,2950805,29054427,-5106970,10008136,-4667901 ), + new FieldElement( 31486080,15114593,-14261250,12951354,14369431,-7387845,16347321,-13662089,8684155,-10532952 ), + new FieldElement( 19443825,11385320,24468943,-9659068,-23919258,2187569,-26263207,-6086921,31316348,14219878 ) + ), + new GroupElementPreComp( + new FieldElement( -28594490,1193785,32245219,11392485,31092169,15722801,27146014,6992409,29126555,9207390 ), + new FieldElement( 32382935,1110093,18477781,11028262,-27411763,-7548111,-4980517,10843782,-7957600,-14435730 ), + new FieldElement( 2814918,7836403,27519878,-7868156,-20894015,-11553689,-21494559,8550130,28346258,1994730 ) + ), + new GroupElementPreComp( + new FieldElement( -19578299,8085545,-14000519,-3948622,2785838,-16231307,-19516951,7174894,22628102,8115180 ), + new FieldElement( -30405132,955511,-11133838,-15078069,-32447087,-13278079,-25651578,3317160,-9943017,930272 ), + new FieldElement( -15303681,-6833769,28856490,1357446,23421993,1057177,24091212,-1388970,-22765376,-10650715 ) + ), + new GroupElementPreComp( + new FieldElement( -22751231,-5303997,-12907607,-12768866,-15811511,-7797053,-14839018,-16554220,-1867018,8398970 ), + new FieldElement( -31969310,2106403,-4736360,1362501,12813763,16200670,22981545,-6291273,18009408,-15772772 ), + new FieldElement( -17220923,-9545221,-27784654,14166835,29815394,7444469,29551787,-3727419,19288549,1325865 ) + ), + new GroupElementPreComp( + new FieldElement( 15100157,-15835752,-23923978,-1005098,-26450192,15509408,12376730,-3479146,33166107,-8042750 ), + new FieldElement( 20909231,13023121,-9209752,16251778,-5778415,-8094914,12412151,10018715,2213263,-13878373 ), + new FieldElement( 32529814,-11074689,30361439,-16689753,-9135940,1513226,22922121,6382134,-5766928,8371348 ) + ), + }, + new[]{ + new GroupElementPreComp( + new FieldElement( 9923462,11271500,12616794,3544722,-29998368,-1721626,12891687,-8193132,-26442943,10486144 ), + new FieldElement( -22597207,-7012665,8587003,-8257861,4084309,-12970062,361726,2610596,-23921530,-11455195 ), + new FieldElement( 5408411,-1136691,-4969122,10561668,24145918,14240566,31319731,-4235541,19985175,-3436086 ) + ), + new GroupElementPreComp( + new FieldElement( -13994457,16616821,14549246,3341099,32155958,13648976,-17577068,8849297,65030,8370684 ), + new FieldElement( -8320926,-12049626,31204563,5839400,-20627288,-1057277,-19442942,6922164,12743482,-9800518 ), + new FieldElement( -2361371,12678785,28815050,4759974,-23893047,4884717,23783145,11038569,18800704,255233 ) + ), + new GroupElementPreComp( + new FieldElement( -5269658,-1773886,13957886,7990715,23132995,728773,13393847,9066957,19258688,-14753793 ), + new FieldElement( -2936654,-10827535,-10432089,14516793,-3640786,4372541,-31934921,2209390,-1524053,2055794 ), + new FieldElement( 580882,16705327,5468415,-2683018,-30926419,-14696000,-7203346,-8994389,-30021019,7394435 ) + ), + new GroupElementPreComp( + new FieldElement( 23838809,1822728,-15738443,15242727,8318092,-3733104,-21672180,-3492205,-4821741,14799921 ), + new FieldElement( 13345610,9759151,3371034,-16137791,16353039,8577942,31129804,13496856,-9056018,7402518 ), + new FieldElement( 2286874,-4435931,-20042458,-2008336,-13696227,5038122,11006906,-15760352,8205061,1607563 ) + ), + new GroupElementPreComp( + new FieldElement( 14414086,-8002132,3331830,-3208217,22249151,-5594188,18364661,-2906958,30019587,-9029278 ), + new FieldElement( -27688051,1585953,-10775053,931069,-29120221,-11002319,-14410829,12029093,9944378,8024 ), + new FieldElement( 4368715,-3709630,29874200,-15022983,-20230386,-11410704,-16114594,-999085,-8142388,5640030 ) + ), + new GroupElementPreComp( + new FieldElement( 10299610,13746483,11661824,16234854,7630238,5998374,9809887,-16694564,15219798,-14327783 ), + new FieldElement( 27425505,-5719081,3055006,10660664,23458024,595578,-15398605,-1173195,-18342183,9742717 ), + new FieldElement( 6744077,2427284,26042789,2720740,-847906,1118974,32324614,7406442,12420155,1994844 ) + ), + new GroupElementPreComp( + new FieldElement( 14012521,-5024720,-18384453,-9578469,-26485342,-3936439,-13033478,-10909803,24319929,-6446333 ), + new FieldElement( 16412690,-4507367,10772641,15929391,-17068788,-4658621,10555945,-10484049,-30102368,-4739048 ), + new FieldElement( 22397382,-7767684,-9293161,-12792868,17166287,-9755136,-27333065,6199366,21880021,-12250760 ) + ), + new GroupElementPreComp( + new FieldElement( -4283307,5368523,-31117018,8163389,-30323063,3209128,16557151,8890729,8840445,4957760 ), + new FieldElement( -15447727,709327,-6919446,-10870178,-29777922,6522332,-21720181,12130072,-14796503,5005757 ), + new FieldElement( -2114751,-14308128,23019042,15765735,-25269683,6002752,10183197,-13239326,-16395286,-2176112 ) + ), + }, + new[]{ + new GroupElementPreComp( + new FieldElement( -19025756,1632005,13466291,-7995100,-23640451,16573537,-32013908,-3057104,22208662,2000468 ), + new FieldElement( 3065073,-1412761,-25598674,-361432,-17683065,-5703415,-8164212,11248527,-3691214,-7414184 ), + new FieldElement( 10379208,-6045554,8877319,1473647,-29291284,-12507580,16690915,2553332,-3132688,16400289 ) + ), + new GroupElementPreComp( + new FieldElement( 15716668,1254266,-18472690,7446274,-8448918,6344164,-22097271,-7285580,26894937,9132066 ), + new FieldElement( 24158887,12938817,11085297,-8177598,-28063478,-4457083,-30576463,64452,-6817084,-2692882 ), + new FieldElement( 13488534,7794716,22236231,5989356,25426474,-12578208,2350710,-3418511,-4688006,2364226 ) + ), + new GroupElementPreComp( + new FieldElement( 16335052,9132434,25640582,6678888,1725628,8517937,-11807024,-11697457,15445875,-7798101 ), + new FieldElement( 29004207,-7867081,28661402,-640412,-12794003,-7943086,31863255,-4135540,-278050,-15759279 ), + new FieldElement( -6122061,-14866665,-28614905,14569919,-10857999,-3591829,10343412,-6976290,-29828287,-10815811 ) + ), + new GroupElementPreComp( + new FieldElement( 27081650,3463984,14099042,-4517604,1616303,-6205604,29542636,15372179,17293797,960709 ), + new FieldElement( 20263915,11434237,-5765435,11236810,13505955,-10857102,-16111345,6493122,-19384511,7639714 ), + new FieldElement( -2830798,-14839232,25403038,-8215196,-8317012,-16173699,18006287,-16043750,29994677,-15808121 ) + ), + new GroupElementPreComp( + new FieldElement( 9769828,5202651,-24157398,-13631392,-28051003,-11561624,-24613141,-13860782,-31184575,709464 ), + new FieldElement( 12286395,13076066,-21775189,-1176622,-25003198,4057652,-32018128,-8890874,16102007,13205847 ), + new FieldElement( 13733362,5599946,10557076,3195751,-5557991,8536970,-25540170,8525972,10151379,10394400 ) + ), + new GroupElementPreComp( + new FieldElement( 4024660,-16137551,22436262,12276534,-9099015,-2686099,19698229,11743039,-33302334,8934414 ), + new FieldElement( -15879800,-4525240,-8580747,-2934061,14634845,-698278,-9449077,3137094,-11536886,11721158 ), + new FieldElement( 17555939,-5013938,8268606,2331751,-22738815,9761013,9319229,8835153,-9205489,-1280045 ) + ), + new GroupElementPreComp( + new FieldElement( -461409,-7830014,20614118,16688288,-7514766,-4807119,22300304,505429,6108462,-6183415 ), + new FieldElement( -5070281,12367917,-30663534,3234473,32617080,-8422642,29880583,-13483331,-26898490,-7867459 ), + new FieldElement( -31975283,5726539,26934134,10237677,-3173717,-605053,24199304,3795095,7592688,-14992079 ) + ), + new GroupElementPreComp( + new FieldElement( 21594432,-14964228,17466408,-4077222,32537084,2739898,6407723,12018833,-28256052,4298412 ), + new FieldElement( -20650503,-11961496,-27236275,570498,3767144,-1717540,13891942,-1569194,13717174,10805743 ), + new FieldElement( -14676630,-15644296,15287174,11927123,24177847,-8175568,-796431,14860609,-26938930,-5863836 ) + ), + }, + new[]{ + new GroupElementPreComp( + new FieldElement( 12962541,5311799,-10060768,11658280,18855286,-7954201,13286263,-12808704,-4381056,9882022 ), + new FieldElement( 18512079,11319350,-20123124,15090309,18818594,5271736,-22727904,3666879,-23967430,-3299429 ), + new FieldElement( -6789020,-3146043,16192429,13241070,15898607,-14206114,-10084880,-6661110,-2403099,5276065 ) + ), + new GroupElementPreComp( + new FieldElement( 30169808,-5317648,26306206,-11750859,27814964,7069267,7152851,3684982,1449224,13082861 ), + new FieldElement( 10342826,3098505,2119311,193222,25702612,12233820,23697382,15056736,-21016438,-8202000 ), + new FieldElement( -33150110,3261608,22745853,7948688,19370557,-15177665,-26171976,6482814,-10300080,-11060101 ) + ), + new GroupElementPreComp( + new FieldElement( 32869458,-5408545,25609743,15678670,-10687769,-15471071,26112421,2521008,-22664288,6904815 ), + new FieldElement( 29506923,4457497,3377935,-9796444,-30510046,12935080,1561737,3841096,-29003639,-6657642 ), + new FieldElement( 10340844,-6630377,-18656632,-2278430,12621151,-13339055,30878497,-11824370,-25584551,5181966 ) + ), + new GroupElementPreComp( + new FieldElement( 25940115,-12658025,17324188,-10307374,-8671468,15029094,24396252,-16450922,-2322852,-12388574 ), + new FieldElement( -21765684,9916823,-1300409,4079498,-1028346,11909559,1782390,12641087,20603771,-6561742 ), + new FieldElement( -18882287,-11673380,24849422,11501709,13161720,-4768874,1925523,11914390,4662781,7820689 ) + ), + new GroupElementPreComp( + new FieldElement( 12241050,-425982,8132691,9393934,32846760,-1599620,29749456,12172924,16136752,15264020 ), + new FieldElement( -10349955,-14680563,-8211979,2330220,-17662549,-14545780,10658213,6671822,19012087,3772772 ), + new FieldElement( 3753511,-3421066,10617074,2028709,14841030,-6721664,28718732,-15762884,20527771,12988982 ) + ), + new GroupElementPreComp( + new FieldElement( -14822485,-5797269,-3707987,12689773,-898983,-10914866,-24183046,-10564943,3299665,-12424953 ), + new FieldElement( -16777703,-15253301,-9642417,4978983,3308785,8755439,6943197,6461331,-25583147,8991218 ), + new FieldElement( -17226263,1816362,-1673288,-6086439,31783888,-8175991,-32948145,7417950,-30242287,1507265 ) + ), + new GroupElementPreComp( + new FieldElement( 29692663,6829891,-10498800,4334896,20945975,-11906496,-28887608,8209391,14606362,-10647073 ), + new FieldElement( -3481570,8707081,32188102,5672294,22096700,1711240,-33020695,9761487,4170404,-2085325 ), + new FieldElement( -11587470,14855945,-4127778,-1531857,-26649089,15084046,22186522,16002000,-14276837,-8400798 ) + ), + new GroupElementPreComp( + new FieldElement( -4811456,13761029,-31703877,-2483919,-3312471,7869047,-7113572,-9620092,13240845,10965870 ), + new FieldElement( -7742563,-8256762,-14768334,-13656260,-23232383,12387166,4498947,14147411,29514390,4302863 ), + new FieldElement( -13413405,-12407859,20757302,-13801832,14785143,8976368,-5061276,-2144373,17846988,-13971927 ) + ), + }, + new[]{ + new GroupElementPreComp( + new FieldElement( -2244452,-754728,-4597030,-1066309,-6247172,1455299,-21647728,-9214789,-5222701,12650267 ), + new FieldElement( -9906797,-16070310,21134160,12198166,-27064575,708126,387813,13770293,-19134326,10958663 ), + new FieldElement( 22470984,12369526,23446014,-5441109,-21520802,-9698723,-11772496,-11574455,-25083830,4271862 ) + ), + new GroupElementPreComp( + new FieldElement( -25169565,-10053642,-19909332,15361595,-5984358,2159192,75375,-4278529,-32526221,8469673 ), + new FieldElement( 15854970,4148314,-8893890,7259002,11666551,13824734,-30531198,2697372,24154791,-9460943 ), + new FieldElement( 15446137,-15806644,29759747,14019369,30811221,-9610191,-31582008,12840104,24913809,9815020 ) + ), + new GroupElementPreComp( + new FieldElement( -4709286,-5614269,-31841498,-12288893,-14443537,10799414,-9103676,13438769,18735128,9466238 ), + new FieldElement( 11933045,9281483,5081055,-5183824,-2628162,-4905629,-7727821,-10896103,-22728655,16199064 ), + new FieldElement( 14576810,379472,-26786533,-8317236,-29426508,-10812974,-102766,1876699,30801119,2164795 ) + ), + new GroupElementPreComp( + new FieldElement( 15995086,3199873,13672555,13712240,-19378835,-4647646,-13081610,-15496269,-13492807,1268052 ), + new FieldElement( -10290614,-3659039,-3286592,10948818,23037027,3794475,-3470338,-12600221,-17055369,3565904 ), + new FieldElement( 29210088,-9419337,-5919792,-4952785,10834811,-13327726,-16512102,-10820713,-27162222,-14030531 ) + ), + new GroupElementPreComp( + new FieldElement( -13161890,15508588,16663704,-8156150,-28349942,9019123,-29183421,-3769423,2244111,-14001979 ), + new FieldElement( -5152875,-3800936,-9306475,-6071583,16243069,14684434,-25673088,-16180800,13491506,4641841 ), + new FieldElement( 10813417,643330,-19188515,-728916,30292062,-16600078,27548447,-7721242,14476989,-12767431 ) + ), + new GroupElementPreComp( + new FieldElement( 10292079,9984945,6481436,8279905,-7251514,7032743,27282937,-1644259,-27912810,12651324 ), + new FieldElement( -31185513,-813383,22271204,11835308,10201545,15351028,17099662,3988035,21721536,-3148940 ), + new FieldElement( 10202177,-6545839,-31373232,-9574638,-32150642,-8119683,-12906320,3852694,13216206,14842320 ) + ), + new GroupElementPreComp( + new FieldElement( -15815640,-10601066,-6538952,-7258995,-6984659,-6581778,-31500847,13765824,-27434397,9900184 ), + new FieldElement( 14465505,-13833331,-32133984,-14738873,-27443187,12990492,33046193,15796406,-7051866,-8040114 ), + new FieldElement( 30924417,-8279620,6359016,-12816335,16508377,9071735,-25488601,15413635,9524356,-7018878 ) + ), + new GroupElementPreComp( + new FieldElement( 12274201,-13175547,32627641,-1785326,6736625,13267305,5237659,-5109483,15663516,4035784 ), + new FieldElement( -2951309,8903985,17349946,601635,-16432815,-4612556,-13732739,-15889334,-22258478,4659091 ), + new FieldElement( -16916263,-4952973,-30393711,-15158821,20774812,15897498,5736189,15026997,-2178256,-13455585 ) + ), + }, + new[]{ + new GroupElementPreComp( + new FieldElement( -8858980,-2219056,28571666,-10155518,-474467,-10105698,-3801496,278095,23440562,-290208 ), + new FieldElement( 10226241,-5928702,15139956,120818,-14867693,5218603,32937275,11551483,-16571960,-7442864 ), + new FieldElement( 17932739,-12437276,-24039557,10749060,11316803,7535897,22503767,5561594,-3646624,3898661 ) + ), + new GroupElementPreComp( + new FieldElement( 7749907,-969567,-16339731,-16464,-25018111,15122143,-1573531,7152530,21831162,1245233 ), + new FieldElement( 26958459,-14658026,4314586,8346991,-5677764,11960072,-32589295,-620035,-30402091,-16716212 ), + new FieldElement( -12165896,9166947,33491384,13673479,29787085,13096535,6280834,14587357,-22338025,13987525 ) + ), + new GroupElementPreComp( + new FieldElement( -24349909,7778775,21116000,15572597,-4833266,-5357778,-4300898,-5124639,-7469781,-2858068 ), + new FieldElement( 9681908,-6737123,-31951644,13591838,-6883821,386950,31622781,6439245,-14581012,4091397 ), + new FieldElement( -8426427,1470727,-28109679,-1596990,3978627,-5123623,-19622683,12092163,29077877,-14741988 ) + ), + new GroupElementPreComp( + new FieldElement( 5269168,-6859726,-13230211,-8020715,25932563,1763552,-5606110,-5505881,-20017847,2357889 ), + new FieldElement( 32264008,-15407652,-5387735,-1160093,-2091322,-3946900,23104804,-12869908,5727338,189038 ), + new FieldElement( 14609123,-8954470,-6000566,-16622781,-14577387,-7743898,-26745169,10942115,-25888931,-14884697 ) + ), + new GroupElementPreComp( + new FieldElement( 20513500,5557931,-15604613,7829531,26413943,-2019404,-21378968,7471781,13913677,-5137875 ), + new FieldElement( -25574376,11967826,29233242,12948236,-6754465,4713227,-8940970,14059180,12878652,8511905 ), + new FieldElement( -25656801,3393631,-2955415,-7075526,-2250709,9366908,-30223418,6812974,5568676,-3127656 ) + ), + new GroupElementPreComp( + new FieldElement( 11630004,12144454,2116339,13606037,27378885,15676917,-17408753,-13504373,-14395196,8070818 ), + new FieldElement( 27117696,-10007378,-31282771,-5570088,1127282,12772488,-29845906,10483306,-11552749,-1028714 ), + new FieldElement( 10637467,-5688064,5674781,1072708,-26343588,-6982302,-1683975,9177853,-27493162,15431203 ) + ), + new GroupElementPreComp( + new FieldElement( 20525145,10892566,-12742472,12779443,-29493034,16150075,-28240519,14943142,-15056790,-7935931 ), + new FieldElement( -30024462,5626926,-551567,-9981087,753598,11981191,25244767,-3239766,-3356550,9594024 ), + new FieldElement( -23752644,2636870,-5163910,-10103818,585134,7877383,11345683,-6492290,13352335,-10977084 ) + ), + new GroupElementPreComp( + new FieldElement( -1931799,-5407458,3304649,-12884869,17015806,-4877091,-29783850,-7752482,-13215537,-319204 ), + new FieldElement( 20239939,6607058,6203985,3483793,-18386976,-779229,-20723742,15077870,-22750759,14523817 ), + new FieldElement( 27406042,-6041657,27423596,-4497394,4996214,10002360,-28842031,-4545494,-30172742,-4805667 ) + ), + }, + new[]{ + new GroupElementPreComp( + new FieldElement( 11374242,12660715,17861383,-12540833,10935568,1099227,-13886076,-9091740,-27727044,11358504 ), + new FieldElement( -12730809,10311867,1510375,10778093,-2119455,-9145702,32676003,11149336,-26123651,4985768 ), + new FieldElement( -19096303,341147,-6197485,-239033,15756973,-8796662,-983043,13794114,-19414307,-15621255 ) + ), + new GroupElementPreComp( + new FieldElement( 6490081,11940286,25495923,-7726360,8668373,-8751316,3367603,6970005,-1691065,-9004790 ), + new FieldElement( 1656497,13457317,15370807,6364910,13605745,8362338,-19174622,-5475723,-16796596,-5031438 ), + new FieldElement( -22273315,-13524424,-64685,-4334223,-18605636,-10921968,-20571065,-7007978,-99853,-10237333 ) + ), + new GroupElementPreComp( + new FieldElement( 17747465,10039260,19368299,-4050591,-20630635,-16041286,31992683,-15857976,-29260363,-5511971 ), + new FieldElement( 31932027,-4986141,-19612382,16366580,22023614,88450,11371999,-3744247,4882242,-10626905 ), + new FieldElement( 29796507,37186,19818052,10115756,-11829032,3352736,18551198,3272828,-5190932,-4162409 ) + ), + new GroupElementPreComp( + new FieldElement( 12501286,4044383,-8612957,-13392385,-32430052,5136599,-19230378,-3529697,330070,-3659409 ), + new FieldElement( 6384877,2899513,17807477,7663917,-2358888,12363165,25366522,-8573892,-271295,12071499 ), + new FieldElement( -8365515,-4042521,25133448,-4517355,-6211027,2265927,-32769618,1936675,-5159697,3829363 ) + ), + new GroupElementPreComp( + new FieldElement( 28425966,-5835433,-577090,-4697198,-14217555,6870930,7921550,-6567787,26333140,14267664 ), + new FieldElement( -11067219,11871231,27385719,-10559544,-4585914,-11189312,10004786,-8709488,-21761224,8930324 ), + new FieldElement( -21197785,-16396035,25654216,-1725397,12282012,11008919,1541940,4757911,-26491501,-16408940 ) + ), + new GroupElementPreComp( + new FieldElement( 13537262,-7759490,-20604840,10961927,-5922820,-13218065,-13156584,6217254,-15943699,13814990 ), + new FieldElement( -17422573,15157790,18705543,29619,24409717,-260476,27361681,9257833,-1956526,-1776914 ), + new FieldElement( -25045300,-10191966,15366585,15166509,-13105086,8423556,-29171540,12361135,-18685978,4578290 ) + ), + new GroupElementPreComp( + new FieldElement( 24579768,3711570,1342322,-11180126,-27005135,14124956,-22544529,14074919,21964432,8235257 ), + new FieldElement( -6528613,-2411497,9442966,-5925588,12025640,-1487420,-2981514,-1669206,13006806,2355433 ), + new FieldElement( -16304899,-13605259,-6632427,-5142349,16974359,-10911083,27202044,1719366,1141648,-12796236 ) + ), + new GroupElementPreComp( + new FieldElement( -12863944,-13219986,-8318266,-11018091,-6810145,-4843894,13475066,-3133972,32674895,13715045 ), + new FieldElement( 11423335,-5468059,32344216,8962751,24989809,9241752,-13265253,16086212,-28740881,-15642093 ), + new FieldElement( -1409668,12530728,-6368726,10847387,19531186,-14132160,-11709148,7791794,-27245943,4383347 ) + ), + }, + new[]{ + new GroupElementPreComp( + new FieldElement( -28970898,5271447,-1266009,-9736989,-12455236,16732599,-4862407,-4906449,27193557,6245191 ), + new FieldElement( -15193956,5362278,-1783893,2695834,4960227,12840725,23061898,3260492,22510453,8577507 ), + new FieldElement( -12632451,11257346,-32692994,13548177,-721004,10879011,31168030,13952092,-29571492,-3635906 ) + ), + new GroupElementPreComp( + new FieldElement( 3877321,-9572739,32416692,5405324,-11004407,-13656635,3759769,11935320,5611860,8164018 ), + new FieldElement( -16275802,14667797,15906460,12155291,-22111149,-9039718,32003002,-8832289,5773085,-8422109 ), + new FieldElement( -23788118,-8254300,1950875,8937633,18686727,16459170,-905725,12376320,31632953,190926 ) + ), + new GroupElementPreComp( + new FieldElement( -24593607,-16138885,-8423991,13378746,14162407,6901328,-8288749,4508564,-25341555,-3627528 ), + new FieldElement( 8884438,-5884009,6023974,10104341,-6881569,-4941533,18722941,-14786005,-1672488,827625 ), + new FieldElement( -32720583,-16289296,-32503547,7101210,13354605,2659080,-1800575,-14108036,-24878478,1541286 ) + ), + new GroupElementPreComp( + new FieldElement( 2901347,-1117687,3880376,-10059388,-17620940,-3612781,-21802117,-3567481,20456845,-1885033 ), + new FieldElement( 27019610,12299467,-13658288,-1603234,-12861660,-4861471,-19540150,-5016058,29439641,15138866 ), + new FieldElement( 21536104,-6626420,-32447818,-10690208,-22408077,5175814,-5420040,-16361163,7779328,109896 ) + ), + new GroupElementPreComp( + new FieldElement( 30279744,14648750,-8044871,6425558,13639621,-743509,28698390,12180118,23177719,-554075 ), + new FieldElement( 26572847,3405927,-31701700,12890905,-19265668,5335866,-6493768,2378492,4439158,-13279347 ), + new FieldElement( -22716706,3489070,-9225266,-332753,18875722,-1140095,14819434,-12731527,-17717757,-5461437 ) + ), + new GroupElementPreComp( + new FieldElement( -5056483,16566551,15953661,3767752,-10436499,15627060,-820954,2177225,8550082,-15114165 ), + new FieldElement( -18473302,16596775,-381660,15663611,22860960,15585581,-27844109,-3582739,-23260460,-8428588 ), + new FieldElement( -32480551,15707275,-8205912,-5652081,29464558,2713815,-22725137,15860482,-21902570,1494193 ) + ), + new GroupElementPreComp( + new FieldElement( -19562091,-14087393,-25583872,-9299552,13127842,759709,21923482,16529112,8742704,12967017 ), + new FieldElement( -28464899,1553205,32536856,-10473729,-24691605,-406174,-8914625,-2933896,-29903758,15553883 ), + new FieldElement( 21877909,3230008,9881174,10539357,-4797115,2841332,11543572,14513274,19375923,-12647961 ) + ), + new GroupElementPreComp( + new FieldElement( 8832269,-14495485,13253511,5137575,5037871,4078777,24880818,-6222716,2862653,9455043 ), + new FieldElement( 29306751,5123106,20245049,-14149889,9592566,8447059,-2077124,-2990080,15511449,4789663 ), + new FieldElement( -20679756,7004547,8824831,-9434977,-4045704,-3750736,-5754762,108893,23513200,16652362 ) + ), + }, + new[]{ + new GroupElementPreComp( + new FieldElement( -33256173,4144782,-4476029,-6579123,10770039,-7155542,-6650416,-12936300,-18319198,10212860 ), + new FieldElement( 2756081,8598110,7383731,-6859892,22312759,-1105012,21179801,2600940,-9988298,-12506466 ), + new FieldElement( -24645692,13317462,-30449259,-15653928,21365574,-10869657,11344424,864440,-2499677,-16710063 ) + ), + new GroupElementPreComp( + new FieldElement( -26432803,6148329,-17184412,-14474154,18782929,-275997,-22561534,211300,2719757,4940997 ), + new FieldElement( -1323882,3911313,-6948744,14759765,-30027150,7851207,21690126,8518463,26699843,5276295 ), + new FieldElement( -13149873,-6429067,9396249,365013,24703301,-10488939,1321586,149635,-15452774,7159369 ) + ), + new GroupElementPreComp( + new FieldElement( 9987780,-3404759,17507962,9505530,9731535,-2165514,22356009,8312176,22477218,-8403385 ), + new FieldElement( 18155857,-16504990,19744716,9006923,15154154,-10538976,24256460,-4864995,-22548173,9334109 ), + new FieldElement( 2986088,-4911893,10776628,-3473844,10620590,-7083203,-21413845,14253545,-22587149,536906 ) + ), + new GroupElementPreComp( + new FieldElement( 4377756,8115836,24567078,15495314,11625074,13064599,7390551,10589625,10838060,-15420424 ), + new FieldElement( -19342404,867880,9277171,-3218459,-14431572,-1986443,19295826,-15796950,6378260,699185 ), + new FieldElement( 7895026,4057113,-7081772,-13077756,-17886831,-323126,-716039,15693155,-5045064,-13373962 ) + ), + new GroupElementPreComp( + new FieldElement( -7737563,-5869402,-14566319,-7406919,11385654,13201616,31730678,-10962840,-3918636,-9669325 ), + new FieldElement( 10188286,-15770834,-7336361,13427543,22223443,14896287,30743455,7116568,-21786507,5427593 ), + new FieldElement( 696102,13206899,27047647,-10632082,15285305,-9853179,10798490,-4578720,19236243,12477404 ) + ), + new GroupElementPreComp( + new FieldElement( -11229439,11243796,-17054270,-8040865,-788228,-8167967,-3897669,11180504,-23169516,7733644 ), + new FieldElement( 17800790,-14036179,-27000429,-11766671,23887827,3149671,23466177,-10538171,10322027,15313801 ), + new FieldElement( 26246234,11968874,32263343,-5468728,6830755,-13323031,-15794704,-101982,-24449242,10890804 ) + ), + new GroupElementPreComp( + new FieldElement( -31365647,10271363,-12660625,-6267268,16690207,-13062544,-14982212,16484931,25180797,-5334884 ), + new FieldElement( -586574,10376444,-32586414,-11286356,19801893,10997610,2276632,9482883,316878,13820577 ), + new FieldElement( -9882808,-4510367,-2115506,16457136,-11100081,11674996,30756178,-7515054,30696930,-3712849 ) + ), + new GroupElementPreComp( + new FieldElement( 32988917,-9603412,12499366,7910787,-10617257,-11931514,-7342816,-9985397,-32349517,7392473 ), + new FieldElement( -8855661,15927861,9866406,-3649411,-2396914,-16655781,-30409476,-9134995,25112947,-2926644 ), + new FieldElement( -2504044,-436966,25621774,-5678772,15085042,-5479877,-24884878,-13526194,5537438,-13914319 ) + ), + }, + new[]{ + new GroupElementPreComp( + new FieldElement( -11225584,2320285,-9584280,10149187,-33444663,5808648,-14876251,-1729667,31234590,6090599 ), + new FieldElement( -9633316,116426,26083934,2897444,-6364437,-2688086,609721,15878753,-6970405,-9034768 ), + new FieldElement( -27757857,247744,-15194774,-9002551,23288161,-10011936,-23869595,6503646,20650474,1804084 ) + ), + new GroupElementPreComp( + new FieldElement( -27589786,15456424,8972517,8469608,15640622,4439847,3121995,-10329713,27842616,-202328 ), + new FieldElement( -15306973,2839644,22530074,10026331,4602058,5048462,28248656,5031932,-11375082,12714369 ), + new FieldElement( 20807691,-7270825,29286141,11421711,-27876523,-13868230,-21227475,1035546,-19733229,12796920 ) + ), + new GroupElementPreComp( + new FieldElement( 12076899,-14301286,-8785001,-11848922,-25012791,16400684,-17591495,-12899438,3480665,-15182815 ), + new FieldElement( -32361549,5457597,28548107,7833186,7303070,-11953545,-24363064,-15921875,-33374054,2771025 ), + new FieldElement( -21389266,421932,26597266,6860826,22486084,-6737172,-17137485,-4210226,-24552282,15673397 ) + ), + new GroupElementPreComp( + new FieldElement( -20184622,2338216,19788685,-9620956,-4001265,-8740893,-20271184,4733254,3727144,-12934448 ), + new FieldElement( 6120119,814863,-11794402,-622716,6812205,-15747771,2019594,7975683,31123697,-10958981 ), + new FieldElement( 30069250,-11435332,30434654,2958439,18399564,-976289,12296869,9204260,-16432438,9648165 ) + ), + new GroupElementPreComp( + new FieldElement( 32705432,-1550977,30705658,7451065,-11805606,9631813,3305266,5248604,-26008332,-11377501 ), + new FieldElement( 17219865,2375039,-31570947,-5575615,-19459679,9219903,294711,15298639,2662509,-16297073 ), + new FieldElement( -1172927,-7558695,-4366770,-4287744,-21346413,-8434326,32087529,-1222777,32247248,-14389861 ) + ), + new GroupElementPreComp( + new FieldElement( 14312628,1221556,17395390,-8700143,-4945741,-8684635,-28197744,-9637817,-16027623,-13378845 ), + new FieldElement( -1428825,-9678990,-9235681,6549687,-7383069,-468664,23046502,9803137,17597934,2346211 ), + new FieldElement( 18510800,15337574,26171504,981392,-22241552,7827556,-23491134,-11323352,3059833,-11782870 ) + ), + new GroupElementPreComp( + new FieldElement( 10141598,6082907,17829293,-1947643,9830092,13613136,-25556636,-5544586,-33502212,3592096 ), + new FieldElement( 33114168,-15889352,-26525686,-13343397,33076705,8716171,1151462,1521897,-982665,-6837803 ), + new FieldElement( -32939165,-4255815,23947181,-324178,-33072974,-12305637,-16637686,3891704,26353178,693168 ) + ), + new GroupElementPreComp( + new FieldElement( 30374239,1595580,-16884039,13186931,4600344,406904,9585294,-400668,31375464,14369965 ), + new FieldElement( -14370654,-7772529,1510301,6434173,-18784789,-6262728,32732230,-13108839,17901441,16011505 ), + new FieldElement( 18171223,-11934626,-12500402,15197122,-11038147,-15230035,-19172240,-16046376,8764035,12309598 ) + ), + }, + new[]{ + new GroupElementPreComp( + new FieldElement( 5975908,-5243188,-19459362,-9681747,-11541277,14015782,-23665757,1228319,17544096,-10593782 ), + new FieldElement( 5811932,-1715293,3442887,-2269310,-18367348,-8359541,-18044043,-15410127,-5565381,12348900 ), + new FieldElement( -31399660,11407555,25755363,6891399,-3256938,14872274,-24849353,8141295,-10632534,-585479 ) + ), + new GroupElementPreComp( + new FieldElement( -12675304,694026,-5076145,13300344,14015258,-14451394,-9698672,-11329050,30944593,1130208 ), + new FieldElement( 8247766,-6710942,-26562381,-7709309,-14401939,-14648910,4652152,2488540,23550156,-271232 ), + new FieldElement( 17294316,-3788438,7026748,15626851,22990044,113481,2267737,-5908146,-408818,-137719 ) + ), + new GroupElementPreComp( + new FieldElement( 16091085,-16253926,18599252,7340678,2137637,-1221657,-3364161,14550936,3260525,-7166271 ), + new FieldElement( -4910104,-13332887,18550887,10864893,-16459325,-7291596,-23028869,-13204905,-12748722,2701326 ), + new FieldElement( -8574695,16099415,4629974,-16340524,-20786213,-6005432,-10018363,9276971,11329923,1862132 ) + ), + new GroupElementPreComp( + new FieldElement( 14763076,-15903608,-30918270,3689867,3511892,10313526,-21951088,12219231,-9037963,-940300 ), + new FieldElement( 8894987,-3446094,6150753,3013931,301220,15693451,-31981216,-2909717,-15438168,11595570 ), + new FieldElement( 15214962,3537601,-26238722,-14058872,4418657,-15230761,13947276,10730794,-13489462,-4363670 ) + ), + new GroupElementPreComp( + new FieldElement( -2538306,7682793,32759013,263109,-29984731,-7955452,-22332124,-10188635,977108,699994 ), + new FieldElement( -12466472,4195084,-9211532,550904,-15565337,12917920,19118110,-439841,-30534533,-14337913 ), + new FieldElement( 31788461,-14507657,4799989,7372237,8808585,-14747943,9408237,-10051775,12493932,-5409317 ) + ), + new GroupElementPreComp( + new FieldElement( -25680606,5260744,-19235809,-6284470,-3695942,16566087,27218280,2607121,29375955,6024730 ), + new FieldElement( 842132,-2794693,-4763381,-8722815,26332018,-12405641,11831880,6985184,-9940361,2854096 ), + new FieldElement( -4847262,-7969331,2516242,-5847713,9695691,-7221186,16512645,960770,12121869,16648078 ) + ), + new GroupElementPreComp( + new FieldElement( -15218652,14667096,-13336229,2013717,30598287,-464137,-31504922,-7882064,20237806,2838411 ), + new FieldElement( -19288047,4453152,15298546,-16178388,22115043,-15972604,12544294,-13470457,1068881,-12499905 ), + new FieldElement( -9558883,-16518835,33238498,13506958,30505848,-1114596,-8486907,-2630053,12521378,4845654 ) + ), + new GroupElementPreComp( + new FieldElement( -28198521,10744108,-2958380,10199664,7759311,-13088600,3409348,-873400,-6482306,-12885870 ), + new FieldElement( -23561822,6230156,-20382013,10655314,-24040585,-11621172,10477734,-1240216,-3113227,13974498 ), + new FieldElement( 12966261,15550616,-32038948,-1615346,21025980,-629444,5642325,7188737,18895762,12629579 ) + ), + }, + new[]{ + new GroupElementPreComp( + new FieldElement( 14741879,-14946887,22177208,-11721237,1279741,8058600,11758140,789443,32195181,3895677 ), + new FieldElement( 10758205,15755439,-4509950,9243698,-4879422,6879879,-2204575,-3566119,-8982069,4429647 ), + new FieldElement( -2453894,15725973,-20436342,-10410672,-5803908,-11040220,-7135870,-11642895,18047436,-15281743 ) + ), + new GroupElementPreComp( + new FieldElement( -25173001,-11307165,29759956,11776784,-22262383,-15820455,10993114,-12850837,-17620701,-9408468 ), + new FieldElement( 21987233,700364,-24505048,14972008,-7774265,-5718395,32155026,2581431,-29958985,8773375 ), + new FieldElement( -25568350,454463,-13211935,16126715,25240068,8594567,20656846,12017935,-7874389,-13920155 ) + ), + new GroupElementPreComp( + new FieldElement( 6028182,6263078,-31011806,-11301710,-818919,2461772,-31841174,-5468042,-1721788,-2776725 ), + new FieldElement( -12278994,16624277,987579,-5922598,32908203,1248608,7719845,-4166698,28408820,6816612 ), + new FieldElement( -10358094,-8237829,19549651,-12169222,22082623,16147817,20613181,13982702,-10339570,5067943 ) + ), + new GroupElementPreComp( + new FieldElement( -30505967,-3821767,12074681,13582412,-19877972,2443951,-19719286,12746132,5331210,-10105944 ), + new FieldElement( 30528811,3601899,-1957090,4619785,-27361822,-15436388,24180793,-12570394,27679908,-1648928 ), + new FieldElement( 9402404,-13957065,32834043,10838634,-26580150,-13237195,26653274,-8685565,22611444,-12715406 ) + ), + new GroupElementPreComp( + new FieldElement( 22190590,1118029,22736441,15130463,-30460692,-5991321,19189625,-4648942,4854859,6622139 ), + new FieldElement( -8310738,-2953450,-8262579,-3388049,-10401731,-271929,13424426,-3567227,26404409,13001963 ), + new FieldElement( -31241838,-15415700,-2994250,8939346,11562230,-12840670,-26064365,-11621720,-15405155,11020693 ) + ), + new GroupElementPreComp( + new FieldElement( 1866042,-7949489,-7898649,-10301010,12483315,13477547,3175636,-12424163,28761762,1406734 ), + new FieldElement( -448555,-1777666,13018551,3194501,-9580420,-11161737,24760585,-4347088,25577411,-13378680 ), + new FieldElement( -24290378,4759345,-690653,-1852816,2066747,10693769,-29595790,9884936,-9368926,4745410 ) + ), + new GroupElementPreComp( + new FieldElement( -9141284,6049714,-19531061,-4341411,-31260798,9944276,-15462008,-11311852,10931924,-11931931 ), + new FieldElement( -16561513,14112680,-8012645,4817318,-8040464,-11414606,-22853429,10856641,-20470770,13434654 ), + new FieldElement( 22759489,-10073434,-16766264,-1871422,13637442,-10168091,1765144,-12654326,28445307,-5364710 ) + ), + new GroupElementPreComp( + new FieldElement( 29875063,12493613,2795536,-3786330,1710620,15181182,-10195717,-8788675,9074234,1167180 ), + new FieldElement( -26205683,11014233,-9842651,-2635485,-26908120,7532294,-18716888,-9535498,3843903,9367684 ), + new FieldElement( -10969595,-6403711,9591134,9582310,11349256,108879,16235123,8601684,-139197,4242895 ) + ), + }, + new[]{ + new GroupElementPreComp( + new FieldElement( 22092954,-13191123,-2042793,-11968512,32186753,-11517388,-6574341,2470660,-27417366,16625501 ), + new FieldElement( -11057722,3042016,13770083,-9257922,584236,-544855,-7770857,2602725,-27351616,14247413 ), + new FieldElement( 6314175,-10264892,-32772502,15957557,-10157730,168750,-8618807,14290061,27108877,-1180880 ) + ), + new GroupElementPreComp( + new FieldElement( -8586597,-7170966,13241782,10960156,-32991015,-13794596,33547976,-11058889,-27148451,981874 ), + new FieldElement( 22833440,9293594,-32649448,-13618667,-9136966,14756819,-22928859,-13970780,-10479804,-16197962 ), + new FieldElement( -7768587,3326786,-28111797,10783824,19178761,14905060,22680049,13906969,-15933690,3797899 ) + ), + new GroupElementPreComp( + new FieldElement( 21721356,-4212746,-12206123,9310182,-3882239,-13653110,23740224,-2709232,20491983,-8042152 ), + new FieldElement( 9209270,-15135055,-13256557,-6167798,-731016,15289673,25947805,15286587,30997318,-6703063 ), + new FieldElement( 7392032,16618386,23946583,-8039892,-13265164,-1533858,-14197445,-2321576,17649998,-250080 ) + ), + new GroupElementPreComp( + new FieldElement( -9301088,-14193827,30609526,-3049543,-25175069,-1283752,-15241566,-9525724,-2233253,7662146 ), + new FieldElement( -17558673,1763594,-33114336,15908610,-30040870,-12174295,7335080,-8472199,-3174674,3440183 ), + new FieldElement( -19889700,-5977008,-24111293,-9688870,10799743,-16571957,40450,-4431835,4862400,1133 ) + ), + new GroupElementPreComp( + new FieldElement( -32856209,-7873957,-5422389,14860950,-16319031,7956142,7258061,311861,-30594991,-7379421 ), + new FieldElement( -3773428,-1565936,28985340,7499440,24445838,9325937,29727763,16527196,18278453,15405622 ), + new FieldElement( -4381906,8508652,-19898366,-3674424,-5984453,15149970,-13313598,843523,-21875062,13626197 ) + ), + new GroupElementPreComp( + new FieldElement( 2281448,-13487055,-10915418,-2609910,1879358,16164207,-10783882,3953792,13340839,15928663 ), + new FieldElement( 31727126,-7179855,-18437503,-8283652,2875793,-16390330,-25269894,-7014826,-23452306,5964753 ), + new FieldElement( 4100420,-5959452,-17179337,6017714,-18705837,12227141,-26684835,11344144,2538215,-7570755 ) + ), + new GroupElementPreComp( + new FieldElement( -9433605,6123113,11159803,-2156608,30016280,14966241,-20474983,1485421,-629256,-15958862 ), + new FieldElement( -26804558,4260919,11851389,9658551,-32017107,16367492,-20205425,-13191288,11659922,-11115118 ), + new FieldElement( 26180396,10015009,-30844224,-8581293,5418197,9480663,2231568,-10170080,33100372,-1306171 ) + ), + new GroupElementPreComp( + new FieldElement( 15121113,-5201871,-10389905,15427821,-27509937,-15992507,21670947,4486675,-5931810,-14466380 ), + new FieldElement( 16166486,-9483733,-11104130,6023908,-31926798,-1364923,2340060,-16254968,-10735770,-10039824 ), + new FieldElement( 28042865,-3557089,-12126526,12259706,-3717498,-6945899,6766453,-8689599,18036436,5803270 ) + ), + }, + new[]{ + new GroupElementPreComp( + new FieldElement( -817581,6763912,11803561,1585585,10958447,-2671165,23855391,4598332,-6159431,-14117438 ), + new FieldElement( -31031306,-14256194,17332029,-2383520,31312682,-5967183,696309,50292,-20095739,11763584 ), + new FieldElement( -594563,-2514283,-32234153,12643980,12650761,14811489,665117,-12613632,-19773211,-10713562 ) + ), + new GroupElementPreComp( + new FieldElement( 30464590,-11262872,-4127476,-12734478,19835327,-7105613,-24396175,2075773,-17020157,992471 ), + new FieldElement( 18357185,-6994433,7766382,16342475,-29324918,411174,14578841,8080033,-11574335,-10601610 ), + new FieldElement( 19598397,10334610,12555054,2555664,18821899,-10339780,21873263,16014234,26224780,16452269 ) + ), + new GroupElementPreComp( + new FieldElement( -30223925,5145196,5944548,16385966,3976735,2009897,-11377804,-7618186,-20533829,3698650 ), + new FieldElement( 14187449,3448569,-10636236,-10810935,-22663880,-3433596,7268410,-10890444,27394301,12015369 ), + new FieldElement( 19695761,16087646,28032085,12999827,6817792,11427614,20244189,-1312777,-13259127,-3402461 ) + ), + new GroupElementPreComp( + new FieldElement( 30860103,12735208,-1888245,-4699734,-16974906,2256940,-8166013,12298312,-8550524,-10393462 ), + new FieldElement( -5719826,-11245325,-1910649,15569035,26642876,-7587760,-5789354,-15118654,-4976164,12651793 ), + new FieldElement( -2848395,9953421,11531313,-5282879,26895123,-12697089,-13118820,-16517902,9768698,-2533218 ) + ), + new GroupElementPreComp( + new FieldElement( -24719459,1894651,-287698,-4704085,15348719,-8156530,32767513,12765450,4940095,10678226 ), + new FieldElement( 18860224,15980149,-18987240,-1562570,-26233012,-11071856,-7843882,13944024,-24372348,16582019 ), + new FieldElement( -15504260,4970268,-29893044,4175593,-20993212,-2199756,-11704054,15444560,-11003761,7989037 ) + ), + new GroupElementPreComp( + new FieldElement( 31490452,5568061,-2412803,2182383,-32336847,4531686,-32078269,6200206,-19686113,-14800171 ), + new FieldElement( -17308668,-15879940,-31522777,-2831,-32887382,16375549,8680158,-16371713,28550068,-6857132 ), + new FieldElement( -28126887,-5688091,16837845,-1820458,-6850681,12700016,-30039981,4364038,1155602,5988841 ) + ), + new GroupElementPreComp( + new FieldElement( 21890435,-13272907,-12624011,12154349,-7831873,15300496,23148983,-4470481,24618407,8283181 ), + new FieldElement( -33136107,-10512751,9975416,6841041,-31559793,16356536,3070187,-7025928,1466169,10740210 ), + new FieldElement( -1509399,-15488185,-13503385,-10655916,32799044,909394,-13938903,-5779719,-32164649,-15327040 ) + ), + new GroupElementPreComp( + new FieldElement( 3960823,-14267803,-28026090,-15918051,-19404858,13146868,15567327,951507,-3260321,-573935 ), + new FieldElement( 24740841,5052253,-30094131,8961361,25877428,6165135,-24368180,14397372,-7380369,-6144105 ), + new FieldElement( -28888365,3510803,-28103278,-1158478,-11238128,-10631454,-15441463,-14453128,-1625486,-6494814 ) + ), + }, + new[]{ + new GroupElementPreComp( + new FieldElement( 793299,-9230478,8836302,-6235707,-27360908,-2369593,33152843,-4885251,-9906200,-621852 ), + new FieldElement( 5666233,525582,20782575,-8038419,-24538499,14657740,16099374,1468826,-6171428,-15186581 ), + new FieldElement( -4859255,-3779343,-2917758,-6748019,7778750,11688288,-30404353,-9871238,-1558923,-9863646 ) + ), + new GroupElementPreComp( + new FieldElement( 10896332,-7719704,824275,472601,-19460308,3009587,25248958,14783338,-30581476,-15757844 ), + new FieldElement( 10566929,12612572,-31944212,11118703,-12633376,12362879,21752402,8822496,24003793,14264025 ), + new FieldElement( 27713862,-7355973,-11008240,9227530,27050101,2504721,23886875,-13117525,13958495,-5732453 ) + ), + new GroupElementPreComp( + new FieldElement( -23481610,4867226,-27247128,3900521,29838369,-8212291,-31889399,-10041781,7340521,-15410068 ), + new FieldElement( 4646514,-8011124,-22766023,-11532654,23184553,8566613,31366726,-1381061,-15066784,-10375192 ), + new FieldElement( -17270517,12723032,-16993061,14878794,21619651,-6197576,27584817,3093888,-8843694,3849921 ) + ), + new GroupElementPreComp( + new FieldElement( -9064912,2103172,25561640,-15125738,-5239824,9582958,32477045,-9017955,5002294,-15550259 ), + new FieldElement( -12057553,-11177906,21115585,-13365155,8808712,-12030708,16489530,13378448,-25845716,12741426 ), + new FieldElement( -5946367,10645103,-30911586,15390284,-3286982,-7118677,24306472,15852464,28834118,-7646072 ) + ), + new GroupElementPreComp( + new FieldElement( -17335748,-9107057,-24531279,9434953,-8472084,-583362,-13090771,455841,20461858,5491305 ), + new FieldElement( 13669248,-16095482,-12481974,-10203039,-14569770,-11893198,-24995986,11293807,-28588204,-9421832 ), + new FieldElement( 28497928,6272777,-33022994,14470570,8906179,-1225630,18504674,-14165166,29867745,-8795943 ) + ), + new GroupElementPreComp( + new FieldElement( -16207023,13517196,-27799630,-13697798,24009064,-6373891,-6367600,-13175392,22853429,-4012011 ), + new FieldElement( 24191378,16712145,-13931797,15217831,14542237,1646131,18603514,-11037887,12876623,-2112447 ), + new FieldElement( 17902668,4518229,-411702,-2829247,26878217,5258055,-12860753,608397,16031844,3723494 ) + ), + new GroupElementPreComp( + new FieldElement( -28632773,12763728,-20446446,7577504,33001348,-13017745,17558842,-7872890,23896954,-4314245 ), + new FieldElement( -20005381,-12011952,31520464,605201,2543521,5991821,-2945064,7229064,-9919646,-8826859 ), + new FieldElement( 28816045,298879,-28165016,-15920938,19000928,-1665890,-12680833,-2949325,-18051778,-2082915 ) + ), + new GroupElementPreComp( + new FieldElement( 16000882,-344896,3493092,-11447198,-29504595,-13159789,12577740,16041268,-19715240,7847707 ), + new FieldElement( 10151868,10572098,27312476,7922682,14825339,4723128,-32855931,-6519018,-10020567,3852848 ), + new FieldElement( -11430470,15697596,-21121557,-4420647,5386314,15063598,16514493,-15932110,29330899,-15076224 ) + ), + }, + new[]{ + new GroupElementPreComp( + new FieldElement( -25499735,-4378794,-15222908,-6901211,16615731,2051784,3303702,15490,-27548796,12314391 ), + new FieldElement( 15683520,-6003043,18109120,-9980648,15337968,-5997823,-16717435,15921866,16103996,-3731215 ), + new FieldElement( -23169824,-10781249,13588192,-1628807,-3798557,-1074929,-19273607,5402699,-29815713,-9841101 ) + ), + new GroupElementPreComp( + new FieldElement( 23190676,2384583,-32714340,3462154,-29903655,-1529132,-11266856,8911517,-25205859,2739713 ), + new FieldElement( 21374101,-3554250,-33524649,9874411,15377179,11831242,-33529904,6134907,4931255,11987849 ), + new FieldElement( -7732,-2978858,-16223486,7277597,105524,-322051,-31480539,13861388,-30076310,10117930 ) + ), + new GroupElementPreComp( + new FieldElement( -29501170,-10744872,-26163768,13051539,-25625564,5089643,-6325503,6704079,12890019,15728940 ), + new FieldElement( -21972360,-11771379,-951059,-4418840,14704840,2695116,903376,-10428139,12885167,8311031 ), + new FieldElement( -17516482,5352194,10384213,-13811658,7506451,13453191,26423267,4384730,1888765,-5435404 ) + ), + new GroupElementPreComp( + new FieldElement( -25817338,-3107312,-13494599,-3182506,30896459,-13921729,-32251644,-12707869,-19464434,-3340243 ), + new FieldElement( -23607977,-2665774,-526091,4651136,5765089,4618330,6092245,14845197,17151279,-9854116 ), + new FieldElement( -24830458,-12733720,-15165978,10367250,-29530908,-265356,22825805,-7087279,-16866484,16176525 ) + ), + new GroupElementPreComp( + new FieldElement( -23583256,6564961,20063689,3798228,-4740178,7359225,2006182,-10363426,-28746253,-10197509 ), + new FieldElement( -10626600,-4486402,-13320562,-5125317,3432136,-6393229,23632037,-1940610,32808310,1099883 ), + new FieldElement( 15030977,5768825,-27451236,-2887299,-6427378,-15361371,-15277896,-6809350,2051441,-15225865 ) + ), + new GroupElementPreComp( + new FieldElement( -3362323,-7239372,7517890,9824992,23555850,295369,5148398,-14154188,-22686354,16633660 ), + new FieldElement( 4577086,-16752288,13249841,-15304328,19958763,-14537274,18559670,-10759549,8402478,-9864273 ), + new FieldElement( -28406330,-1051581,-26790155,-907698,-17212414,-11030789,9453451,-14980072,17983010,9967138 ) + ), + new GroupElementPreComp( + new FieldElement( -25762494,6524722,26585488,9969270,24709298,1220360,-1677990,7806337,17507396,3651560 ), + new FieldElement( -10420457,-4118111,14584639,15971087,-15768321,8861010,26556809,-5574557,-18553322,-11357135 ), + new FieldElement( 2839101,14284142,4029895,3472686,14402957,12689363,-26642121,8459447,-5605463,-7621941 ) + ), + new GroupElementPreComp( + new FieldElement( -4839289,-3535444,9744961,2871048,25113978,3187018,-25110813,-849066,17258084,-7977739 ), + new FieldElement( 18164541,-10595176,-17154882,-1542417,19237078,-9745295,23357533,-15217008,26908270,12150756 ), + new FieldElement( -30264870,-7647865,5112249,-7036672,-1499807,-6974257,43168,-5537701,-32302074,16215819 ) + ), + }, + new[]{ + new GroupElementPreComp( + new FieldElement( -6898905,9824394,-12304779,-4401089,-31397141,-6276835,32574489,12532905,-7503072,-8675347 ), + new FieldElement( -27343522,-16515468,-27151524,-10722951,946346,16291093,254968,7168080,21676107,-1943028 ), + new FieldElement( 21260961,-8424752,-16831886,-11920822,-23677961,3968121,-3651949,-6215466,-3556191,-7913075 ) + ), + new GroupElementPreComp( + new FieldElement( 16544754,13250366,-16804428,15546242,-4583003,12757258,-2462308,-8680336,-18907032,-9662799 ), + new FieldElement( -2415239,-15577728,18312303,4964443,-15272530,-12653564,26820651,16690659,25459437,-4564609 ), + new FieldElement( -25144690,11425020,28423002,-11020557,-6144921,-15826224,9142795,-2391602,-6432418,-1644817 ) + ), + new GroupElementPreComp( + new FieldElement( -23104652,6253476,16964147,-3768872,-25113972,-12296437,-27457225,-16344658,6335692,7249989 ), + new FieldElement( -30333227,13979675,7503222,-12368314,-11956721,-4621693,-30272269,2682242,25993170,-12478523 ), + new FieldElement( 4364628,5930691,32304656,-10044554,-8054781,15091131,22857016,-10598955,31820368,15075278 ) + ), + new GroupElementPreComp( + new FieldElement( 31879134,-8918693,17258761,90626,-8041836,-4917709,24162788,-9650886,-17970238,12833045 ), + new FieldElement( 19073683,14851414,-24403169,-11860168,7625278,11091125,-19619190,2074449,-9413939,14905377 ), + new FieldElement( 24483667,-11935567,-2518866,-11547418,-1553130,15355506,-25282080,9253129,27628530,-7555480 ) + ), + new GroupElementPreComp( + new FieldElement( 17597607,8340603,19355617,552187,26198470,-3176583,4593324,-9157582,-14110875,15297016 ), + new FieldElement( 510886,14337390,-31785257,16638632,6328095,2713355,-20217417,-11864220,8683221,2921426 ), + new FieldElement( 18606791,11874196,27155355,-5281482,-24031742,6265446,-25178240,-1278924,4674690,13890525 ) + ), + new GroupElementPreComp( + new FieldElement( 13609624,13069022,-27372361,-13055908,24360586,9592974,14977157,9835105,4389687,288396 ), + new FieldElement( 9922506,-519394,13613107,5883594,-18758345,-434263,-12304062,8317628,23388070,16052080 ), + new FieldElement( 12720016,11937594,-31970060,-5028689,26900120,8561328,-20155687,-11632979,-14754271,-10812892 ) + ), + new GroupElementPreComp( + new FieldElement( 15961858,14150409,26716931,-665832,-22794328,13603569,11829573,7467844,-28822128,929275 ), + new FieldElement( 11038231,-11582396,-27310482,-7316562,-10498527,-16307831,-23479533,-9371869,-21393143,2465074 ), + new FieldElement( 20017163,-4323226,27915242,1529148,12396362,15675764,13817261,-9658066,2463391,-4622140 ) + ), + new GroupElementPreComp( + new FieldElement( -16358878,-12663911,-12065183,4996454,-1256422,1073572,9583558,12851107,4003896,12673717 ), + new FieldElement( -1731589,-15155870,-3262930,16143082,19294135,13385325,14741514,-9103726,7903886,2348101 ), + new FieldElement( 24536016,-16515207,12715592,-3862155,1511293,10047386,-3842346,-7129159,-28377538,10048127 ) + ), + }, + new[]{ + new GroupElementPreComp( + new FieldElement( -12622226,-6204820,30718825,2591312,-10617028,12192840,18873298,-7297090,-32297756,15221632 ), + new FieldElement( -26478122,-11103864,11546244,-1852483,9180880,7656409,-21343950,2095755,29769758,6593415 ), + new FieldElement( -31994208,-2907461,4176912,3264766,12538965,-868111,26312345,-6118678,30958054,8292160 ) + ), + new GroupElementPreComp( + new FieldElement( 31429822,-13959116,29173532,15632448,12174511,-2760094,32808831,3977186,26143136,-3148876 ), + new FieldElement( 22648901,1402143,-22799984,13746059,7936347,365344,-8668633,-1674433,-3758243,-2304625 ), + new FieldElement( -15491917,8012313,-2514730,-12702462,-23965846,-10254029,-1612713,-1535569,-16664475,8194478 ) + ), + new GroupElementPreComp( + new FieldElement( 27338066,-7507420,-7414224,10140405,-19026427,-6589889,27277191,8855376,28572286,3005164 ), + new FieldElement( 26287124,4821776,25476601,-4145903,-3764513,-15788984,-18008582,1182479,-26094821,-13079595 ), + new FieldElement( -7171154,3178080,23970071,6201893,-17195577,-4489192,-21876275,-13982627,32208683,-1198248 ) + ), + new GroupElementPreComp( + new FieldElement( -16657702,2817643,-10286362,14811298,6024667,13349505,-27315504,-10497842,-27672585,-11539858 ), + new FieldElement( 15941029,-9405932,-21367050,8062055,31876073,-238629,-15278393,-1444429,15397331,-4130193 ), + new FieldElement( 8934485,-13485467,-23286397,-13423241,-32446090,14047986,31170398,-1441021,-27505566,15087184 ) + ), + new GroupElementPreComp( + new FieldElement( -18357243,-2156491,24524913,-16677868,15520427,-6360776,-15502406,11461896,16788528,-5868942 ), + new FieldElement( -1947386,16013773,21750665,3714552,-17401782,-16055433,-3770287,-10323320,31322514,-11615635 ), + new FieldElement( 21426655,-5650218,-13648287,-5347537,-28812189,-4920970,-18275391,-14621414,13040862,-12112948 ) + ), + new GroupElementPreComp( + new FieldElement( 11293895,12478086,-27136401,15083750,-29307421,14748872,14555558,-13417103,1613711,4896935 ), + new FieldElement( -25894883,15323294,-8489791,-8057900,25967126,-13425460,2825960,-4897045,-23971776,-11267415 ), + new FieldElement( -15924766,-5229880,-17443532,6410664,3622847,10243618,20615400,12405433,-23753030,-8436416 ) + ), + new GroupElementPreComp( + new FieldElement( -7091295,12556208,-20191352,9025187,-17072479,4333801,4378436,2432030,23097949,-566018 ), + new FieldElement( 4565804,-16025654,20084412,-7842817,1724999,189254,24767264,10103221,-18512313,2424778 ), + new FieldElement( 366633,-11976806,8173090,-6890119,30788634,5745705,-7168678,1344109,-3642553,12412659 ) + ), + new GroupElementPreComp( + new FieldElement( -24001791,7690286,14929416,-168257,-32210835,-13412986,24162697,-15326504,-3141501,11179385 ), + new FieldElement( 18289522,-14724954,8056945,16430056,-21729724,7842514,-6001441,-1486897,-18684645,-11443503 ), + new FieldElement( 476239,6601091,-6152790,-9723375,17503545,-4863900,27672959,13403813,11052904,5219329 ) + ), + }, + new[]{ + new GroupElementPreComp( + new FieldElement( 20678546,-8375738,-32671898,8849123,-5009758,14574752,31186971,-3973730,9014762,-8579056 ), + new FieldElement( -13644050,-10350239,-15962508,5075808,-1514661,-11534600,-33102500,9160280,8473550,-3256838 ), + new FieldElement( 24900749,14435722,17209120,-15292541,-22592275,9878983,-7689309,-16335821,-24568481,11788948 ) + ), + new GroupElementPreComp( + new FieldElement( -3118155,-11395194,-13802089,14797441,9652448,-6845904,-20037437,10410733,-24568470,-1458691 ), + new FieldElement( -15659161,16736706,-22467150,10215878,-9097177,7563911,11871841,-12505194,-18513325,8464118 ), + new FieldElement( -23400612,8348507,-14585951,-861714,-3950205,-6373419,14325289,8628612,33313881,-8370517 ) + ), + new GroupElementPreComp( + new FieldElement( -20186973,-4967935,22367356,5271547,-1097117,-4788838,-24805667,-10236854,-8940735,-5818269 ), + new FieldElement( -6948785,-1795212,-32625683,-16021179,32635414,-7374245,15989197,-12838188,28358192,-4253904 ), + new FieldElement( -23561781,-2799059,-32351682,-1661963,-9147719,10429267,-16637684,4072016,-5351664,5596589 ) + ), + new GroupElementPreComp( + new FieldElement( -28236598,-3390048,12312896,6213178,3117142,16078565,29266239,2557221,1768301,15373193 ), + new FieldElement( -7243358,-3246960,-4593467,-7553353,-127927,-912245,-1090902,-4504991,-24660491,3442910 ), + new FieldElement( -30210571,5124043,14181784,8197961,18964734,-11939093,22597931,7176455,-18585478,13365930 ) + ), + new GroupElementPreComp( + new FieldElement( -7877390,-1499958,8324673,4690079,6261860,890446,24538107,-8570186,-9689599,-3031667 ), + new FieldElement( 25008904,-10771599,-4305031,-9638010,16265036,15721635,683793,-11823784,15723479,-15163481 ), + new FieldElement( -9660625,12374379,-27006999,-7026148,-7724114,-12314514,11879682,5400171,519526,-1235876 ) + ), + new GroupElementPreComp( + new FieldElement( 22258397,-16332233,-7869817,14613016,-22520255,-2950923,-20353881,7315967,16648397,7605640 ), + new FieldElement( -8081308,-8464597,-8223311,9719710,19259459,-15348212,23994942,-5281555,-9468848,4763278 ), + new FieldElement( -21699244,9220969,-15730624,1084137,-25476107,-2852390,31088447,-7764523,-11356529,728112 ) + ), + new GroupElementPreComp( + new FieldElement( 26047220,-11751471,-6900323,-16521798,24092068,9158119,-4273545,-12555558,-29365436,-5498272 ), + new FieldElement( 17510331,-322857,5854289,8403524,17133918,-3112612,-28111007,12327945,10750447,10014012 ), + new FieldElement( -10312768,3936952,9156313,-8897683,16498692,-994647,-27481051,-666732,3424691,7540221 ) + ), + new GroupElementPreComp( + new FieldElement( 30322361,-6964110,11361005,-4143317,7433304,4989748,-7071422,-16317219,-9244265,15258046 ), + new FieldElement( 13054562,-2779497,19155474,469045,-12482797,4566042,5631406,2711395,1062915,-5136345 ), + new FieldElement( -19240248,-11254599,-29509029,-7499965,-5835763,13005411,-6066489,12194497,32960380,1459310 ) + ), + }, + new[]{ + new GroupElementPreComp( + new FieldElement( 19852034,7027924,23669353,10020366,8586503,-6657907,394197,-6101885,18638003,-11174937 ), + new FieldElement( 31395534,15098109,26581030,8030562,-16527914,-5007134,9012486,-7584354,-6643087,-5442636 ), + new FieldElement( -9192165,-2347377,-1997099,4529534,25766844,607986,-13222,9677543,-32294889,-6456008 ) + ), + new GroupElementPreComp( + new FieldElement( -2444496,-149937,29348902,8186665,1873760,12489863,-30934579,-7839692,-7852844,-8138429 ), + new FieldElement( -15236356,-15433509,7766470,746860,26346930,-10221762,-27333451,10754588,-9431476,5203576 ), + new FieldElement( 31834314,14135496,-770007,5159118,20917671,-16768096,-7467973,-7337524,31809243,7347066 ) + ), + new GroupElementPreComp( + new FieldElement( -9606723,-11874240,20414459,13033986,13716524,-11691881,19797970,-12211255,15192876,-2087490 ), + new FieldElement( -12663563,-2181719,1168162,-3804809,26747877,-14138091,10609330,12694420,33473243,-13382104 ), + new FieldElement( 33184999,11180355,15832085,-11385430,-1633671,225884,15089336,-11023903,-6135662,14480053 ) + ), + new GroupElementPreComp( + new FieldElement( 31308717,-5619998,31030840,-1897099,15674547,-6582883,5496208,13685227,27595050,8737275 ), + new FieldElement( -20318852,-15150239,10933843,-16178022,8335352,-7546022,-31008351,-12610604,26498114,66511 ), + new FieldElement( 22644454,-8761729,-16671776,4884562,-3105614,-13559366,30540766,-4286747,-13327787,-7515095 ) + ), + new GroupElementPreComp( + new FieldElement( -28017847,9834845,18617207,-2681312,-3401956,-13307506,8205540,13585437,-17127465,15115439 ), + new FieldElement( 23711543,-672915,31206561,-8362711,6164647,-9709987,-33535882,-1426096,8236921,16492939 ), + new FieldElement( -23910559,-13515526,-26299483,-4503841,25005590,-7687270,19574902,10071562,6708380,-6222424 ) + ), + new GroupElementPreComp( + new FieldElement( 2101391,-4930054,19702731,2367575,-15427167,1047675,5301017,9328700,29955601,-11678310 ), + new FieldElement( 3096359,9271816,-21620864,-15521844,-14847996,-7592937,-25892142,-12635595,-9917575,6216608 ), + new FieldElement( -32615849,338663,-25195611,2510422,-29213566,-13820213,24822830,-6146567,-26767480,7525079 ) + ), + new GroupElementPreComp( + new FieldElement( -23066649,-13985623,16133487,-7896178,-3389565,778788,-910336,-2782495,-19386633,11994101 ), + new FieldElement( 21691500,-13624626,-641331,-14367021,3285881,-3483596,-25064666,9718258,-7477437,13381418 ), + new FieldElement( 18445390,-4202236,14979846,11622458,-1727110,-3582980,23111648,-6375247,28535282,15779576 ) + ), + new GroupElementPreComp( + new FieldElement( 30098053,3089662,-9234387,16662135,-21306940,11308411,-14068454,12021730,9955285,-16303356 ), + new FieldElement( 9734894,-14576830,-7473633,-9138735,2060392,11313496,-18426029,9924399,20194861,13380996 ), + new FieldElement( -26378102,-7965207,-22167821,15789297,-18055342,-6168792,-1984914,15707771,26342023,10146099 ) + ), + }, + new[]{ + new GroupElementPreComp( + new FieldElement( -26016874,-219943,21339191,-41388,19745256,-2878700,-29637280,2227040,21612326,-545728 ), + new FieldElement( -13077387,1184228,23562814,-5970442,-20351244,-6348714,25764461,12243797,-20856566,11649658 ), + new FieldElement( -10031494,11262626,27384172,2271902,26947504,-15997771,39944,6114064,33514190,2333242 ) + ), + new GroupElementPreComp( + new FieldElement( -21433588,-12421821,8119782,7219913,-21830522,-9016134,-6679750,-12670638,24350578,-13450001 ), + new FieldElement( -4116307,-11271533,-23886186,4843615,-30088339,690623,-31536088,-10406836,8317860,12352766 ), + new FieldElement( 18200138,-14475911,-33087759,-2696619,-23702521,-9102511,-23552096,-2287550,20712163,6719373 ) + ), + new GroupElementPreComp( + new FieldElement( 26656208,6075253,-7858556,1886072,-28344043,4262326,11117530,-3763210,26224235,-3297458 ), + new FieldElement( -17168938,-14854097,-3395676,-16369877,-19954045,14050420,21728352,9493610,18620611,-16428628 ), + new FieldElement( -13323321,13325349,11432106,5964811,18609221,6062965,-5269471,-9725556,-30701573,-16479657 ) + ), + new GroupElementPreComp( + new FieldElement( -23860538,-11233159,26961357,1640861,-32413112,-16737940,12248509,-5240639,13735342,1934062 ), + new FieldElement( 25089769,6742589,17081145,-13406266,21909293,-16067981,-15136294,-3765346,-21277997,5473616 ), + new FieldElement( 31883677,-7961101,1083432,-11572403,22828471,13290673,-7125085,12469656,29111212,-5451014 ) + ), + new GroupElementPreComp( + new FieldElement( 24244947,-15050407,-26262976,2791540,-14997599,16666678,24367466,6388839,-10295587,452383 ), + new FieldElement( -25640782,-3417841,5217916,16224624,19987036,-4082269,-24236251,-5915248,15766062,8407814 ), + new FieldElement( -20406999,13990231,15495425,16395525,5377168,15166495,-8917023,-4388953,-8067909,2276718 ) + ), + new GroupElementPreComp( + new FieldElement( 30157918,12924066,-17712050,9245753,19895028,3368142,-23827587,5096219,22740376,-7303417 ), + new FieldElement( 2041139,-14256350,7783687,13876377,-25946985,-13352459,24051124,13742383,-15637599,13295222 ), + new FieldElement( 33338237,-8505733,12532113,7977527,9106186,-1715251,-17720195,-4612972,-4451357,-14669444 ) + ), + new GroupElementPreComp( + new FieldElement( -20045281,5454097,-14346548,6447146,28862071,1883651,-2469266,-4141880,7770569,9620597 ), + new FieldElement( 23208068,7979712,33071466,8149229,1758231,-10834995,30945528,-1694323,-33502340,-14767970 ), + new FieldElement( 1439958,-16270480,-1079989,-793782,4625402,10647766,-5043801,1220118,30494170,-11440799 ) + ), + new GroupElementPreComp( + new FieldElement( -5037580,-13028295,-2970559,-3061767,15640974,-6701666,-26739026,926050,-1684339,-13333647 ), + new FieldElement( 13908495,-3549272,30919928,-6273825,-21521863,7989039,9021034,9078865,3353509,4033511 ), + new FieldElement( -29663431,-15113610,32259991,-344482,24295849,-12912123,23161163,8839127,27485041,7356032 ) + ), + }, + new[]{ + new GroupElementPreComp( + new FieldElement( 9661027,705443,11980065,-5370154,-1628543,14661173,-6346142,2625015,28431036,-16771834 ), + new FieldElement( -23839233,-8311415,-25945511,7480958,-17681669,-8354183,-22545972,14150565,15970762,4099461 ), + new FieldElement( 29262576,16756590,26350592,-8793563,8529671,-11208050,13617293,-9937143,11465739,8317062 ) + ), + new GroupElementPreComp( + new FieldElement( -25493081,-6962928,32500200,-9419051,-23038724,-2302222,14898637,3848455,20969334,-5157516 ), + new FieldElement( -20384450,-14347713,-18336405,13884722,-33039454,2842114,-21610826,-3649888,11177095,14989547 ), + new FieldElement( -24496721,-11716016,16959896,2278463,12066309,10137771,13515641,2581286,-28487508,9930240 ) + ), + new GroupElementPreComp( + new FieldElement( -17751622,-2097826,16544300,-13009300,-15914807,-14949081,18345767,-13403753,16291481,-5314038 ), + new FieldElement( -33229194,2553288,32678213,9875984,8534129,6889387,-9676774,6957617,4368891,9788741 ), + new FieldElement( 16660756,7281060,-10830758,12911820,20108584,-8101676,-21722536,-8613148,16250552,-11111103 ) + ), + new GroupElementPreComp( + new FieldElement( -19765507,2390526,-16551031,14161980,1905286,6414907,4689584,10604807,-30190403,4782747 ), + new FieldElement( -1354539,14736941,-7367442,-13292886,7710542,-14155590,-9981571,4383045,22546403,437323 ), + new FieldElement( 31665577,-12180464,-16186830,1491339,-18368625,3294682,27343084,2786261,-30633590,-14097016 ) + ), + new GroupElementPreComp( + new FieldElement( -14467279,-683715,-33374107,7448552,19294360,14334329,-19690631,2355319,-19284671,-6114373 ), + new FieldElement( 15121312,-15796162,6377020,-6031361,-10798111,-12957845,18952177,15496498,-29380133,11754228 ), + new FieldElement( -2637277,-13483075,8488727,-14303896,12728761,-1622493,7141596,11724556,22761615,-10134141 ) + ), + new GroupElementPreComp( + new FieldElement( 16918416,11729663,-18083579,3022987,-31015732,-13339659,-28741185,-12227393,32851222,11717399 ), + new FieldElement( 11166634,7338049,-6722523,4531520,-29468672,-7302055,31474879,3483633,-1193175,-4030831 ), + new FieldElement( -185635,9921305,31456609,-13536438,-12013818,13348923,33142652,6546660,-19985279,-3948376 ) + ), + new GroupElementPreComp( + new FieldElement( -32460596,11266712,-11197107,-7899103,31703694,3855903,-8537131,-12833048,-30772034,-15486313 ), + new FieldElement( -18006477,12709068,3991746,-6479188,-21491523,-10550425,-31135347,-16049879,10928917,3011958 ), + new FieldElement( -6957757,-15594337,31696059,334240,29576716,14796075,-30831056,-12805180,18008031,10258577 ) + ), + new GroupElementPreComp( + new FieldElement( -22448644,15655569,7018479,-4410003,-30314266,-1201591,-1853465,1367120,25127874,6671743 ), + new FieldElement( 29701166,-14373934,-10878120,9279288,-17568,13127210,21382910,11042292,25838796,4642684 ), + new FieldElement( -20430234,14955537,-24126347,8124619,-5369288,-5990470,30468147,-13900640,18423289,4177476 ) + ) + } + }; + } +} \ No newline at end of file diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/base.cs.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/base.cs.meta new file mode 100644 index 0000000..4e3e741 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/base.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f18db5e68563cbd409d36c08526de52d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/base2.cs b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/base2.cs new file mode 100644 index 0000000..03676e5 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/base2.cs @@ -0,0 +1,50 @@ +using System; + +namespace Chaos.NaCl.Internal.Ed25519Ref10 +{ + internal static partial class LookupTables + { + internal static readonly GroupElementPreComp[] Base2 = new GroupElementPreComp[]{ + new GroupElementPreComp( + new FieldElement( 25967493,-14356035,29566456,3660896,-12694345,4014787,27544626,-11754271,-6079156,2047605 ), + new FieldElement( -12545711,934262,-2722910,3049990,-727428,9406986,12720692,5043384,19500929,-15469378 ), + new FieldElement( -8738181,4489570,9688441,-14785194,10184609,-12363380,29287919,11864899,-24514362,-4438546 ) + ), + new GroupElementPreComp( + new FieldElement( 15636291,-9688557,24204773,-7912398,616977,-16685262,27787600,-14772189,28944400,-1550024 ), + new FieldElement( 16568933,4717097,-11556148,-1102322,15682896,-11807043,16354577,-11775962,7689662,11199574 ), + new FieldElement( 30464156,-5976125,-11779434,-15670865,23220365,15915852,7512774,10017326,-17749093,-9920357 ) + ), + new GroupElementPreComp( + new FieldElement( 10861363,11473154,27284546,1981175,-30064349,12577861,32867885,14515107,-15438304,10819380 ), + new FieldElement( 4708026,6336745,20377586,9066809,-11272109,6594696,-25653668,12483688,-12668491,5581306 ), + new FieldElement( 19563160,16186464,-29386857,4097519,10237984,-4348115,28542350,13850243,-23678021,-15815942 ) + ), + new GroupElementPreComp( + new FieldElement( 5153746,9909285,1723747,-2777874,30523605,5516873,19480852,5230134,-23952439,-15175766 ), + new FieldElement( -30269007,-3463509,7665486,10083793,28475525,1649722,20654025,16520125,30598449,7715701 ), + new FieldElement( 28881845,14381568,9657904,3680757,-20181635,7843316,-31400660,1370708,29794553,-1409300 ) + ), + new GroupElementPreComp( + new FieldElement( -22518993,-6692182,14201702,-8745502,-23510406,8844726,18474211,-1361450,-13062696,13821877 ), + new FieldElement( -6455177,-7839871,3374702,-4740862,-27098617,-10571707,31655028,-7212327,18853322,-14220951 ), + new FieldElement( 4566830,-12963868,-28974889,-12240689,-7602672,-2830569,-8514358,-10431137,2207753,-3209784 ) + ), + new GroupElementPreComp( + new FieldElement( -25154831,-4185821,29681144,7868801,-6854661,-9423865,-12437364,-663000,-31111463,-16132436 ), + new FieldElement( 25576264,-2703214,7349804,-11814844,16472782,9300885,3844789,15725684,171356,6466918 ), + new FieldElement( 23103977,13316479,9739013,-16149481,817875,-15038942,8965339,-14088058,-30714912,16193877 ) + ), + new GroupElementPreComp( + new FieldElement( -33521811,3180713,-2394130,14003687,-16903474,-16270840,17238398,4729455,-18074513,9256800 ), + new FieldElement( -25182317,-4174131,32336398,5036987,-21236817,11360617,22616405,9761698,-19827198,630305 ), + new FieldElement( -13720693,2639453,-24237460,-7406481,9494427,-5774029,-6554551,-15960994,-2449256,-14291300 ) + ), + new GroupElementPreComp( + new FieldElement( -3151181,-5046075,9282714,6866145,-31907062,-863023,-18940575,15033784,25105118,-7894876 ), + new FieldElement( -24326370,15950226,-31801215,-14592823,-11662737,-5090925,1573892,-2625887,2198790,-15804619 ), + new FieldElement( -3099351,10324967,-2241613,7453183,-5446979,-2735503,-13812022,-16236442,-32461234,-12290683 ) + ) + }; + } +} diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/base2.cs.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/base2.cs.meta new file mode 100644 index 0000000..b12c6cc --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/base2.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 34008919cebaf8d458129917866a35c0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/d.cs b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/d.cs new file mode 100644 index 0000000..9a9343a --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/d.cs @@ -0,0 +1,9 @@ +using System; + +namespace Chaos.NaCl.Internal.Ed25519Ref10 +{ + internal static partial class LookupTables + { + internal static FieldElement d = new FieldElement(-10913610, 13857413, -15372611, 6949391, 114729, -8787816, -6275908, -3247719, -18696448, -12055116); + } +} \ No newline at end of file diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/d.cs.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/d.cs.meta new file mode 100644 index 0000000..73d88c7 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/d.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7c06d66b34f18514cad8601e5fbcde20 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/d2.cs b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/d2.cs new file mode 100644 index 0000000..7479311 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/d2.cs @@ -0,0 +1,9 @@ +using System; + +namespace Chaos.NaCl.Internal.Ed25519Ref10 +{ + internal static partial class LookupTables + { + internal static FieldElement d2 = new FieldElement(-21827239, -5839606, -30745221, 13898782, 229458, 15978800, -12551817, -6495438, 29715968, 9444199); + } +} \ No newline at end of file diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/d2.cs.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/d2.cs.meta new file mode 100644 index 0000000..77d5338 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/d2.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: feeb142ffece95c41af5abca94d41161 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_0.cs b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_0.cs new file mode 100644 index 0000000..f207532 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_0.cs @@ -0,0 +1,12 @@ +using System; + +namespace Chaos.NaCl.Internal.Ed25519Ref10 +{ + internal static partial class FieldOperations + { + public static void fe_0(out FieldElement h) + { + h = default(FieldElement); + } + } +} \ No newline at end of file diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_0.cs.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_0.cs.meta new file mode 100644 index 0000000..3cfaed1 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_0.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6ee549334974767438afd033891af508 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_1.cs b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_1.cs new file mode 100644 index 0000000..822ea59 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_1.cs @@ -0,0 +1,13 @@ +using System; + +namespace Chaos.NaCl.Internal.Ed25519Ref10 +{ + internal static partial class FieldOperations + { + public static void fe_1(out FieldElement h) + { + h = default(FieldElement); + h.x0 = 1; + } + } +} \ No newline at end of file diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_1.cs.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_1.cs.meta new file mode 100644 index 0000000..587512d --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_1.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 14b872c65650a15479ca88d7c7f4c886 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_add.cs b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_add.cs new file mode 100644 index 0000000..a5c2fb7 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_add.cs @@ -0,0 +1,63 @@ +using System; + +namespace Chaos.NaCl.Internal.Ed25519Ref10 +{ + internal static partial class FieldOperations + { + /* + h = f + g + Can overlap h with f or g. + + Preconditions: + |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. + |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. + + Postconditions: + |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. + */ + //void fe_add(fe h,const fe f,const fe g) + internal static void fe_add(out FieldElement h, ref FieldElement f, ref FieldElement g) + { + Int32 f0 = f.x0; + Int32 f1 = f.x1; + Int32 f2 = f.x2; + Int32 f3 = f.x3; + Int32 f4 = f.x4; + Int32 f5 = f.x5; + Int32 f6 = f.x6; + Int32 f7 = f.x7; + Int32 f8 = f.x8; + Int32 f9 = f.x9; + Int32 g0 = g.x0; + Int32 g1 = g.x1; + Int32 g2 = g.x2; + Int32 g3 = g.x3; + Int32 g4 = g.x4; + Int32 g5 = g.x5; + Int32 g6 = g.x6; + Int32 g7 = g.x7; + Int32 g8 = g.x8; + Int32 g9 = g.x9; + Int32 h0 = f0 + g0; + Int32 h1 = f1 + g1; + Int32 h2 = f2 + g2; + Int32 h3 = f3 + g3; + Int32 h4 = f4 + g4; + Int32 h5 = f5 + g5; + Int32 h6 = f6 + g6; + Int32 h7 = f7 + g7; + Int32 h8 = f8 + g8; + Int32 h9 = f9 + g9; + h.x0 = h0; + h.x1 = h1; + h.x2 = h2; + h.x3 = h3; + h.x4 = h4; + h.x5 = h5; + h.x6 = h6; + h.x7 = h7; + h.x8 = h8; + h.x9 = h9; + } + } +} \ No newline at end of file diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_add.cs.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_add.cs.meta new file mode 100644 index 0000000..18fad38 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_add.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2f24766c3f8c31d43aaf88bf1b872b77 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_cmov.cs b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_cmov.cs new file mode 100644 index 0000000..039905b --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_cmov.cs @@ -0,0 +1,70 @@ +using System; + +namespace Chaos.NaCl.Internal.Ed25519Ref10 +{ + internal static partial class FieldOperations + { + /* + Replace (f,g) with (g,g) if b == 1; + replace (f,g) with (f,g) if b == 0. + + Preconditions: b in {0,1}. + */ + + //void fe_cmov(fe f,const fe g,unsigned int b) + internal static void fe_cmov(ref FieldElement f, ref FieldElement g, int b) + { + Int32 f0 = f.x0; + Int32 f1 = f.x1; + Int32 f2 = f.x2; + Int32 f3 = f.x3; + Int32 f4 = f.x4; + Int32 f5 = f.x5; + Int32 f6 = f.x6; + Int32 f7 = f.x7; + Int32 f8 = f.x8; + Int32 f9 = f.x9; + Int32 g0 = g.x0; + Int32 g1 = g.x1; + Int32 g2 = g.x2; + Int32 g3 = g.x3; + Int32 g4 = g.x4; + Int32 g5 = g.x5; + Int32 g6 = g.x6; + Int32 g7 = g.x7; + Int32 g8 = g.x8; + Int32 g9 = g.x9; + Int32 x0 = f0 ^ g0; + Int32 x1 = f1 ^ g1; + Int32 x2 = f2 ^ g2; + Int32 x3 = f3 ^ g3; + Int32 x4 = f4 ^ g4; + Int32 x5 = f5 ^ g5; + Int32 x6 = f6 ^ g6; + Int32 x7 = f7 ^ g7; + Int32 x8 = f8 ^ g8; + Int32 x9 = f9 ^ g9; + b = -b; + x0 &= b; + x1 &= b; + x2 &= b; + x3 &= b; + x4 &= b; + x5 &= b; + x6 &= b; + x7 &= b; + x8 &= b; + x9 &= b; + f.x0 = f0 ^ x0; + f.x1 = f1 ^ x1; + f.x2 = f2 ^ x2; + f.x3 = f3 ^ x3; + f.x4 = f4 ^ x4; + f.x5 = f5 ^ x5; + f.x6 = f6 ^ x6; + f.x7 = f7 ^ x7; + f.x8 = f8 ^ x8; + f.x9 = f9 ^ x9; + } + } +} \ No newline at end of file diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_cmov.cs.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_cmov.cs.meta new file mode 100644 index 0000000..01a4a02 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_cmov.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0699e7e757d5c1f4b89bff1d28df5b5f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_cswap.cs b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_cswap.cs new file mode 100644 index 0000000..b28bf20 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_cswap.cs @@ -0,0 +1,78 @@ +using System; + +namespace Chaos.NaCl.Internal.Ed25519Ref10 +{ + internal static partial class FieldOperations + { + /* + Replace (f,g) with (g,f) if b == 1; + replace (f,g) with (f,g) if b == 0. + + Preconditions: b in {0,1}. + */ + public static void fe_cswap(ref FieldElement f, ref FieldElement g, uint b) + { + Int32 f0 = f.x0; + Int32 f1 = f.x1; + Int32 f2 = f.x2; + Int32 f3 = f.x3; + Int32 f4 = f.x4; + Int32 f5 = f.x5; + Int32 f6 = f.x6; + Int32 f7 = f.x7; + Int32 f8 = f.x8; + Int32 f9 = f.x9; + Int32 g0 = g.x0; + Int32 g1 = g.x1; + Int32 g2 = g.x2; + Int32 g3 = g.x3; + Int32 g4 = g.x4; + Int32 g5 = g.x5; + Int32 g6 = g.x6; + Int32 g7 = g.x7; + Int32 g8 = g.x8; + Int32 g9 = g.x9; + Int32 x0 = f0 ^ g0; + Int32 x1 = f1 ^ g1; + Int32 x2 = f2 ^ g2; + Int32 x3 = f3 ^ g3; + Int32 x4 = f4 ^ g4; + Int32 x5 = f5 ^ g5; + Int32 x6 = f6 ^ g6; + Int32 x7 = f7 ^ g7; + Int32 x8 = f8 ^ g8; + Int32 x9 = f9 ^ g9; + int negb = unchecked((int)-b); + x0 &= negb; + x1 &= negb; + x2 &= negb; + x3 &= negb; + x4 &= negb; + x5 &= negb; + x6 &= negb; + x7 &= negb; + x8 &= negb; + x9 &= negb; + f.x0 = f0 ^ x0; + f.x1 = f1 ^ x1; + f.x2 = f2 ^ x2; + f.x3 = f3 ^ x3; + f.x4 = f4 ^ x4; + f.x5 = f5 ^ x5; + f.x6 = f6 ^ x6; + f.x7 = f7 ^ x7; + f.x8 = f8 ^ x8; + f.x9 = f9 ^ x9; + g.x0 = g0 ^ x0; + g.x1 = g1 ^ x1; + g.x2 = g2 ^ x2; + g.x3 = g3 ^ x3; + g.x4 = g4 ^ x4; + g.x5 = g5 ^ x5; + g.x6 = g6 ^ x6; + g.x7 = g7 ^ x7; + g.x8 = g8 ^ x8; + g.x9 = g9 ^ x9; + } + } +} \ No newline at end of file diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_cswap.cs.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_cswap.cs.meta new file mode 100644 index 0000000..5b4442e --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_cswap.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2ba28d617f95bcf419b5c9011786ba61 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_frombytes.cs b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_frombytes.cs new file mode 100644 index 0000000..49afb18 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_frombytes.cs @@ -0,0 +1,122 @@ +using System; + +namespace Chaos.NaCl.Internal.Ed25519Ref10 +{ + internal static partial class FieldOperations + { + private static Int64 load_3(byte[] data, int offset) + { + uint result; + result = (uint)data[offset + 0]; + result |= (uint)data[offset + 1] << 8; + result |= (uint)data[offset + 2] << 16; + return (Int64)(UInt64)result; + } + + private static Int64 load_4(byte[] data, int offset) + { + uint result; + result = (uint)data[offset + 0]; + result |= (uint)data[offset + 1] << 8; + result |= (uint)data[offset + 2] << 16; + result |= (uint)data[offset + 3] << 24; + return (Int64)(UInt64)result; + } + + // Ignores top bit of h. + internal static void fe_frombytes(out FieldElement h, byte[] data, int offset) + { + Int64 h0 = load_4(data, offset); + Int64 h1 = load_3(data, offset + 4) << 6; + Int64 h2 = load_3(data, offset + 7) << 5; + Int64 h3 = load_3(data, offset + 10) << 3; + Int64 h4 = load_3(data, offset + 13) << 2; + Int64 h5 = load_4(data, offset + 16); + Int64 h6 = load_3(data, offset + 20) << 7; + Int64 h7 = load_3(data, offset + 23) << 5; + Int64 h8 = load_3(data, offset + 26) << 4; + Int64 h9 = (load_3(data, offset + 29) & 8388607) << 2; + Int64 carry0; + Int64 carry1; + Int64 carry2; + Int64 carry3; + Int64 carry4; + Int64 carry5; + Int64 carry6; + Int64 carry7; + Int64 carry8; + Int64 carry9; + + carry9 = (h9 + (Int64)(1 << 24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; + carry1 = (h1 + (Int64)(1 << 24)) >> 25; h2 += carry1; h1 -= carry1 << 25; + carry3 = (h3 + (Int64)(1 << 24)) >> 25; h4 += carry3; h3 -= carry3 << 25; + carry5 = (h5 + (Int64)(1 << 24)) >> 25; h6 += carry5; h5 -= carry5 << 25; + carry7 = (h7 + (Int64)(1 << 24)) >> 25; h8 += carry7; h7 -= carry7 << 25; + + carry0 = (h0 + (Int64)(1 << 25)) >> 26; h1 += carry0; h0 -= carry0 << 26; + carry2 = (h2 + (Int64)(1 << 25)) >> 26; h3 += carry2; h2 -= carry2 << 26; + carry4 = (h4 + (Int64)(1 << 25)) >> 26; h5 += carry4; h4 -= carry4 << 26; + carry6 = (h6 + (Int64)(1 << 25)) >> 26; h7 += carry6; h6 -= carry6 << 26; + carry8 = (h8 + (Int64)(1 << 25)) >> 26; h9 += carry8; h8 -= carry8 << 26; + + h.x0 = (int)h0; + h.x1 = (int)h1; + h.x2 = (int)h2; + h.x3 = (int)h3; + h.x4 = (int)h4; + h.x5 = (int)h5; + h.x6 = (int)h6; + h.x7 = (int)h7; + h.x8 = (int)h8; + h.x9 = (int)h9; + } + + // does NOT ignore top bit + internal static void fe_frombytes2(out FieldElement h, byte[] data, int offset) + { + Int64 h0 = load_4(data, offset); + Int64 h1 = load_3(data, offset + 4) << 6; + Int64 h2 = load_3(data, offset + 7) << 5; + Int64 h3 = load_3(data, offset + 10) << 3; + Int64 h4 = load_3(data, offset + 13) << 2; + Int64 h5 = load_4(data, offset + 16); + Int64 h6 = load_3(data, offset + 20) << 7; + Int64 h7 = load_3(data, offset + 23) << 5; + Int64 h8 = load_3(data, offset + 26) << 4; + Int64 h9 = load_3(data, offset + 29) << 2; + Int64 carry0; + Int64 carry1; + Int64 carry2; + Int64 carry3; + Int64 carry4; + Int64 carry5; + Int64 carry6; + Int64 carry7; + Int64 carry8; + Int64 carry9; + + carry9 = (h9 + (Int64)(1 << 24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; + carry1 = (h1 + (Int64)(1 << 24)) >> 25; h2 += carry1; h1 -= carry1 << 25; + carry3 = (h3 + (Int64)(1 << 24)) >> 25; h4 += carry3; h3 -= carry3 << 25; + carry5 = (h5 + (Int64)(1 << 24)) >> 25; h6 += carry5; h5 -= carry5 << 25; + carry7 = (h7 + (Int64)(1 << 24)) >> 25; h8 += carry7; h7 -= carry7 << 25; + + carry0 = (h0 + (Int64)(1 << 25)) >> 26; h1 += carry0; h0 -= carry0 << 26; + carry2 = (h2 + (Int64)(1 << 25)) >> 26; h3 += carry2; h2 -= carry2 << 26; + carry4 = (h4 + (Int64)(1 << 25)) >> 26; h5 += carry4; h4 -= carry4 << 26; + carry6 = (h6 + (Int64)(1 << 25)) >> 26; h7 += carry6; h6 -= carry6 << 26; + carry8 = (h8 + (Int64)(1 << 25)) >> 26; h9 += carry8; h8 -= carry8 << 26; + + h.x0 = (int)h0; + h.x1 = (int)h1; + h.x2 = (int)h2; + h.x3 = (int)h3; + h.x4 = (int)h4; + h.x5 = (int)h5; + h.x6 = (int)h6; + h.x7 = (int)h7; + h.x8 = (int)h8; + h.x9 = (int)h9; + } + } +} diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_frombytes.cs.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_frombytes.cs.meta new file mode 100644 index 0000000..cb2c3ab --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_frombytes.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 36fce117b267548478fefe5651791940 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_invert.cs b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_invert.cs new file mode 100644 index 0000000..697fcc4 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_invert.cs @@ -0,0 +1,179 @@ +using System; + +namespace Chaos.NaCl.Internal.Ed25519Ref10 +{ + internal static partial class FieldOperations + { + internal static void fe_invert(out FieldElement result, ref FieldElement z) + { + FieldElement t0; + FieldElement t1; + FieldElement t2; + FieldElement t3; + int i; + + /* qhasm: fe z1 */ + + /* qhasm: fe z2 */ + + /* qhasm: fe z8 */ + + /* qhasm: fe z9 */ + + /* qhasm: fe z11 */ + + /* qhasm: fe z22 */ + + /* qhasm: fe z_5_0 */ + + /* qhasm: fe z_10_5 */ + + /* qhasm: fe z_10_0 */ + + /* qhasm: fe z_20_10 */ + + /* qhasm: fe z_20_0 */ + + /* qhasm: fe z_40_20 */ + + /* qhasm: fe z_40_0 */ + + /* qhasm: fe z_50_10 */ + + /* qhasm: fe z_50_0 */ + + /* qhasm: fe z_100_50 */ + + /* qhasm: fe z_100_0 */ + + /* qhasm: fe z_200_100 */ + + /* qhasm: fe z_200_0 */ + + /* qhasm: fe z_250_50 */ + + /* qhasm: fe z_250_0 */ + + /* qhasm: fe z_255_5 */ + + /* qhasm: fe z_255_21 */ + + /* qhasm: enter pow225521 */ + + /* qhasm: z2 = z1^2^1 */ + /* asm 1: fe_sq(>z2=fe#1,z2=fe#1,>z2=fe#1); */ + /* asm 2: fe_sq(>z2=t0,z2=t0,>z2=t0); */ + fe_sq(out t0, ref z); //for (i = 1; i < 1; ++i) fe_sq(out t0, ref t0); + + /* qhasm: z8 = z2^2^2 */ + /* asm 1: fe_sq(>z8=fe#2,z8=fe#2,>z8=fe#2); */ + /* asm 2: fe_sq(>z8=t1,z8=t1,>z8=t1); */ + fe_sq(out t1, ref t0); for (i = 1; i < 2; ++i) fe_sq(out t1, ref t1); + + /* qhasm: z9 = z1*z8 */ + /* asm 1: fe_mul(>z9=fe#2,z9=t1,z11=fe#1,z11=t0,z22=fe#3,z22=fe#3,>z22=fe#3); */ + /* asm 2: fe_sq(>z22=t2,z22=t2,>z22=t2); */ + fe_sq(out t2, ref t0); //for (i = 1; i < 1; ++i) fe_sq(out t2, ref t2); + + /* qhasm: z_5_0 = z9*z22 */ + /* asm 1: fe_mul(>z_5_0=fe#2,z_5_0=t1,z_10_5=fe#3,z_10_5=fe#3,>z_10_5=fe#3); */ + /* asm 2: fe_sq(>z_10_5=t2,z_10_5=t2,>z_10_5=t2); */ + fe_sq(out t2, ref t1); for (i = 1; i < 5; ++i) fe_sq(out t2, ref t2); + + /* qhasm: z_10_0 = z_10_5*z_5_0 */ + /* asm 1: fe_mul(>z_10_0=fe#2,z_10_0=t1,z_20_10=fe#3,z_20_10=fe#3,>z_20_10=fe#3); */ + /* asm 2: fe_sq(>z_20_10=t2,z_20_10=t2,>z_20_10=t2); */ + fe_sq(out t2, ref t1); for (i = 1; i < 10; ++i) fe_sq(out t2, ref t2); + + /* qhasm: z_20_0 = z_20_10*z_10_0 */ + /* asm 1: fe_mul(>z_20_0=fe#3,z_20_0=t2,z_40_20=fe#4,z_40_20=fe#4,>z_40_20=fe#4); */ + /* asm 2: fe_sq(>z_40_20=t3,z_40_20=t3,>z_40_20=t3); */ + fe_sq(out t3, ref t2); for (i = 1; i < 20; ++i) fe_sq(out t3, ref t3); + + /* qhasm: z_40_0 = z_40_20*z_20_0 */ + /* asm 1: fe_mul(>z_40_0=fe#3,z_40_0=t2,z_50_10=fe#3,z_50_10=fe#3,>z_50_10=fe#3); */ + /* asm 2: fe_sq(>z_50_10=t2,z_50_10=t2,>z_50_10=t2); */ + fe_sq(out t2, ref t2); for (i = 1; i < 10; ++i) fe_sq(out t2, ref t2); + + /* qhasm: z_50_0 = z_50_10*z_10_0 */ + /* asm 1: fe_mul(>z_50_0=fe#2,z_50_0=t1,z_100_50=fe#3,z_100_50=fe#3,>z_100_50=fe#3); */ + /* asm 2: fe_sq(>z_100_50=t2,z_100_50=t2,>z_100_50=t2); */ + fe_sq(out t2, ref t1); for (i = 1; i < 50; ++i) fe_sq(out t2, ref t2); + + /* qhasm: z_100_0 = z_100_50*z_50_0 */ + /* asm 1: fe_mul(>z_100_0=fe#3,z_100_0=t2,z_200_100=fe#4,z_200_100=fe#4,>z_200_100=fe#4); */ + /* asm 2: fe_sq(>z_200_100=t3,z_200_100=t3,>z_200_100=t3); */ + fe_sq(out t3, ref t2); for (i = 1; i < 100; ++i) fe_sq(out t3, ref t3); + + /* qhasm: z_200_0 = z_200_100*z_100_0 */ + /* asm 1: fe_mul(>z_200_0=fe#3,z_200_0=t2,z_250_50=fe#3,z_250_50=fe#3,>z_250_50=fe#3); */ + /* asm 2: fe_sq(>z_250_50=t2,z_250_50=t2,>z_250_50=t2); */ + fe_sq(out t2, ref t2); for (i = 1; i < 50; ++i) fe_sq(out t2, ref t2); + + /* qhasm: z_250_0 = z_250_50*z_50_0 */ + /* asm 1: fe_mul(>z_250_0=fe#2,z_250_0=t1,z_255_5=fe#2,z_255_5=fe#2,>z_255_5=fe#2); */ + /* asm 2: fe_sq(>z_255_5=t1,z_255_5=t1,>z_255_5=t1); */ + fe_sq(out t1, ref t1); for (i = 1; i < 5; ++i) fe_sq(out t1, ref t1); + + /* qhasm: z_255_21 = z_255_5*z11 */ + /* asm 1: fe_mul(>z_255_21=fe#12,z_255_21=out,> 31) ^ 1); + } + } +} \ No newline at end of file diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_isnonzero.cs.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_isnonzero.cs.meta new file mode 100644 index 0000000..4ffaad3 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_isnonzero.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 22c19f03ab398534b93c5ed058776830 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_mul.cs b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_mul.cs new file mode 100644 index 0000000..d3c755b --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_mul.cs @@ -0,0 +1,258 @@ +using System; + +namespace Chaos.NaCl.Internal.Ed25519Ref10 +{ + internal static partial class FieldOperations + { + /* + h = f * g + Can overlap h with f or g. + + Preconditions: + |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. + |g| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. + + Postconditions: + |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc. + */ + + /* + Notes on implementation strategy: + + Using schoolbook multiplication. + Karatsuba would save a little in some cost models. + + Most multiplications by 2 and 19 are 32-bit precomputations; + cheaper than 64-bit postcomputations. + + There is one remaining multiplication by 19 in the carry chain; + one *19 precomputation can be merged into this, + but the resulting data flow is considerably less clean. + + There are 12 carries below. + 10 of them are 2-way parallelizable and vectorizable. + Can get away with 11 carries, but then data flow is much deeper. + + With tighter constraints on inputs can squeeze carries into int32. + */ + + internal static void fe_mul(out FieldElement h, ref FieldElement f, ref FieldElement g) + { + Int32 f0 = f.x0; + Int32 f1 = f.x1; + Int32 f2 = f.x2; + Int32 f3 = f.x3; + Int32 f4 = f.x4; + Int32 f5 = f.x5; + Int32 f6 = f.x6; + Int32 f7 = f.x7; + Int32 f8 = f.x8; + Int32 f9 = f.x9; + Int32 g0 = g.x0; + Int32 g1 = g.x1; + Int32 g2 = g.x2; + Int32 g3 = g.x3; + Int32 g4 = g.x4; + Int32 g5 = g.x5; + Int32 g6 = g.x6; + Int32 g7 = g.x7; + Int32 g8 = g.x8; + Int32 g9 = g.x9; + Int32 g1_19 = 19 * g1; /* 1.959375*2^29 */ + Int32 g2_19 = 19 * g2; /* 1.959375*2^30; still ok */ + Int32 g3_19 = 19 * g3; + Int32 g4_19 = 19 * g4; + Int32 g5_19 = 19 * g5; + Int32 g6_19 = 19 * g6; + Int32 g7_19 = 19 * g7; + Int32 g8_19 = 19 * g8; + Int32 g9_19 = 19 * g9; + Int32 f1_2 = 2 * f1; + Int32 f3_2 = 2 * f3; + Int32 f5_2 = 2 * f5; + Int32 f7_2 = 2 * f7; + Int32 f9_2 = 2 * f9; + Int64 f0g0 = f0 * (Int64)g0; + Int64 f0g1 = f0 * (Int64)g1; + Int64 f0g2 = f0 * (Int64)g2; + Int64 f0g3 = f0 * (Int64)g3; + Int64 f0g4 = f0 * (Int64)g4; + Int64 f0g5 = f0 * (Int64)g5; + Int64 f0g6 = f0 * (Int64)g6; + Int64 f0g7 = f0 * (Int64)g7; + Int64 f0g8 = f0 * (Int64)g8; + Int64 f0g9 = f0 * (Int64)g9; + Int64 f1g0 = f1 * (Int64)g0; + Int64 f1g1_2 = f1_2 * (Int64)g1; + Int64 f1g2 = f1 * (Int64)g2; + Int64 f1g3_2 = f1_2 * (Int64)g3; + Int64 f1g4 = f1 * (Int64)g4; + Int64 f1g5_2 = f1_2 * (Int64)g5; + Int64 f1g6 = f1 * (Int64)g6; + Int64 f1g7_2 = f1_2 * (Int64)g7; + Int64 f1g8 = f1 * (Int64)g8; + Int64 f1g9_38 = f1_2 * (Int64)g9_19; + Int64 f2g0 = f2 * (Int64)g0; + Int64 f2g1 = f2 * (Int64)g1; + Int64 f2g2 = f2 * (Int64)g2; + Int64 f2g3 = f2 * (Int64)g3; + Int64 f2g4 = f2 * (Int64)g4; + Int64 f2g5 = f2 * (Int64)g5; + Int64 f2g6 = f2 * (Int64)g6; + Int64 f2g7 = f2 * (Int64)g7; + Int64 f2g8_19 = f2 * (Int64)g8_19; + Int64 f2g9_19 = f2 * (Int64)g9_19; + Int64 f3g0 = f3 * (Int64)g0; + Int64 f3g1_2 = f3_2 * (Int64)g1; + Int64 f3g2 = f3 * (Int64)g2; + Int64 f3g3_2 = f3_2 * (Int64)g3; + Int64 f3g4 = f3 * (Int64)g4; + Int64 f3g5_2 = f3_2 * (Int64)g5; + Int64 f3g6 = f3 * (Int64)g6; + Int64 f3g7_38 = f3_2 * (Int64)g7_19; + Int64 f3g8_19 = f3 * (Int64)g8_19; + Int64 f3g9_38 = f3_2 * (Int64)g9_19; + Int64 f4g0 = f4 * (Int64)g0; + Int64 f4g1 = f4 * (Int64)g1; + Int64 f4g2 = f4 * (Int64)g2; + Int64 f4g3 = f4 * (Int64)g3; + Int64 f4g4 = f4 * (Int64)g4; + Int64 f4g5 = f4 * (Int64)g5; + Int64 f4g6_19 = f4 * (Int64)g6_19; + Int64 f4g7_19 = f4 * (Int64)g7_19; + Int64 f4g8_19 = f4 * (Int64)g8_19; + Int64 f4g9_19 = f4 * (Int64)g9_19; + Int64 f5g0 = f5 * (Int64)g0; + Int64 f5g1_2 = f5_2 * (Int64)g1; + Int64 f5g2 = f5 * (Int64)g2; + Int64 f5g3_2 = f5_2 * (Int64)g3; + Int64 f5g4 = f5 * (Int64)g4; + Int64 f5g5_38 = f5_2 * (Int64)g5_19; + Int64 f5g6_19 = f5 * (Int64)g6_19; + Int64 f5g7_38 = f5_2 * (Int64)g7_19; + Int64 f5g8_19 = f5 * (Int64)g8_19; + Int64 f5g9_38 = f5_2 * (Int64)g9_19; + Int64 f6g0 = f6 * (Int64)g0; + Int64 f6g1 = f6 * (Int64)g1; + Int64 f6g2 = f6 * (Int64)g2; + Int64 f6g3 = f6 * (Int64)g3; + Int64 f6g4_19 = f6 * (Int64)g4_19; + Int64 f6g5_19 = f6 * (Int64)g5_19; + Int64 f6g6_19 = f6 * (Int64)g6_19; + Int64 f6g7_19 = f6 * (Int64)g7_19; + Int64 f6g8_19 = f6 * (Int64)g8_19; + Int64 f6g9_19 = f6 * (Int64)g9_19; + Int64 f7g0 = f7 * (Int64)g0; + Int64 f7g1_2 = f7_2 * (Int64)g1; + Int64 f7g2 = f7 * (Int64)g2; + Int64 f7g3_38 = f7_2 * (Int64)g3_19; + Int64 f7g4_19 = f7 * (Int64)g4_19; + Int64 f7g5_38 = f7_2 * (Int64)g5_19; + Int64 f7g6_19 = f7 * (Int64)g6_19; + Int64 f7g7_38 = f7_2 * (Int64)g7_19; + Int64 f7g8_19 = f7 * (Int64)g8_19; + Int64 f7g9_38 = f7_2 * (Int64)g9_19; + Int64 f8g0 = f8 * (Int64)g0; + Int64 f8g1 = f8 * (Int64)g1; + Int64 f8g2_19 = f8 * (Int64)g2_19; + Int64 f8g3_19 = f8 * (Int64)g3_19; + Int64 f8g4_19 = f8 * (Int64)g4_19; + Int64 f8g5_19 = f8 * (Int64)g5_19; + Int64 f8g6_19 = f8 * (Int64)g6_19; + Int64 f8g7_19 = f8 * (Int64)g7_19; + Int64 f8g8_19 = f8 * (Int64)g8_19; + Int64 f8g9_19 = f8 * (Int64)g9_19; + Int64 f9g0 = f9 * (Int64)g0; + Int64 f9g1_38 = f9_2 * (Int64)g1_19; + Int64 f9g2_19 = f9 * (Int64)g2_19; + Int64 f9g3_38 = f9_2 * (Int64)g3_19; + Int64 f9g4_19 = f9 * (Int64)g4_19; + Int64 f9g5_38 = f9_2 * (Int64)g5_19; + Int64 f9g6_19 = f9 * (Int64)g6_19; + Int64 f9g7_38 = f9_2 * (Int64)g7_19; + Int64 f9g8_19 = f9 * (Int64)g8_19; + Int64 f9g9_38 = f9_2 * (Int64)g9_19; + Int64 h0 = f0g0 + f1g9_38 + f2g8_19 + f3g7_38 + f4g6_19 + f5g5_38 + f6g4_19 + f7g3_38 + f8g2_19 + f9g1_38; + Int64 h1 = f0g1 + f1g0 + f2g9_19 + f3g8_19 + f4g7_19 + f5g6_19 + f6g5_19 + f7g4_19 + f8g3_19 + f9g2_19; + Int64 h2 = f0g2 + f1g1_2 + f2g0 + f3g9_38 + f4g8_19 + f5g7_38 + f6g6_19 + f7g5_38 + f8g4_19 + f9g3_38; + Int64 h3 = f0g3 + f1g2 + f2g1 + f3g0 + f4g9_19 + f5g8_19 + f6g7_19 + f7g6_19 + f8g5_19 + f9g4_19; + Int64 h4 = f0g4 + f1g3_2 + f2g2 + f3g1_2 + f4g0 + f5g9_38 + f6g8_19 + f7g7_38 + f8g6_19 + f9g5_38; + Int64 h5 = f0g5 + f1g4 + f2g3 + f3g2 + f4g1 + f5g0 + f6g9_19 + f7g8_19 + f8g7_19 + f9g6_19; + Int64 h6 = f0g6 + f1g5_2 + f2g4 + f3g3_2 + f4g2 + f5g1_2 + f6g0 + f7g9_38 + f8g8_19 + f9g7_38; + Int64 h7 = f0g7 + f1g6 + f2g5 + f3g4 + f4g3 + f5g2 + f6g1 + f7g0 + f8g9_19 + f9g8_19; + Int64 h8 = f0g8 + f1g7_2 + f2g6 + f3g5_2 + f4g4 + f5g3_2 + f6g2 + f7g1_2 + f8g0 + f9g9_38; + Int64 h9 = f0g9 + f1g8 + f2g7 + f3g6 + f4g5 + f5g4 + f6g3 + f7g2 + f8g1 + f9g0; + Int64 carry0; + Int64 carry1; + Int64 carry2; + Int64 carry3; + Int64 carry4; + Int64 carry5; + Int64 carry6; + Int64 carry7; + Int64 carry8; + Int64 carry9; + + /* + |h0| <= (1.65*1.65*2^52*(1+19+19+19+19)+1.65*1.65*2^50*(38+38+38+38+38)) + i.e. |h0| <= 1.4*2^60; narrower ranges for h2, h4, h6, h8 + |h1| <= (1.65*1.65*2^51*(1+1+19+19+19+19+19+19+19+19)) + i.e. |h1| <= 1.7*2^59; narrower ranges for h3, h5, h7, h9 + */ + + carry0 = (h0 + (Int64)(1 << 25)) >> 26; h1 += carry0; h0 -= carry0 << 26; + carry4 = (h4 + (Int64)(1 << 25)) >> 26; h5 += carry4; h4 -= carry4 << 26; + /* |h0| <= 2^25 */ + /* |h4| <= 2^25 */ + /* |h1| <= 1.71*2^59 */ + /* |h5| <= 1.71*2^59 */ + + carry1 = (h1 + (Int64)(1 << 24)) >> 25; h2 += carry1; h1 -= carry1 << 25; + carry5 = (h5 + (Int64)(1 << 24)) >> 25; h6 += carry5; h5 -= carry5 << 25; + /* |h1| <= 2^24; from now on fits into int32 */ + /* |h5| <= 2^24; from now on fits into int32 */ + /* |h2| <= 1.41*2^60 */ + /* |h6| <= 1.41*2^60 */ + + carry2 = (h2 + (Int64)(1 << 25)) >> 26; h3 += carry2; h2 -= carry2 << 26; + carry6 = (h6 + (Int64)(1 << 25)) >> 26; h7 += carry6; h6 -= carry6 << 26; + /* |h2| <= 2^25; from now on fits into int32 unchanged */ + /* |h6| <= 2^25; from now on fits into int32 unchanged */ + /* |h3| <= 1.71*2^59 */ + /* |h7| <= 1.71*2^59 */ + + carry3 = (h3 + (Int64)(1 << 24)) >> 25; h4 += carry3; h3 -= carry3 << 25; + carry7 = (h7 + (Int64)(1 << 24)) >> 25; h8 += carry7; h7 -= carry7 << 25; + /* |h3| <= 2^24; from now on fits into int32 unchanged */ + /* |h7| <= 2^24; from now on fits into int32 unchanged */ + /* |h4| <= 1.72*2^34 */ + /* |h8| <= 1.41*2^60 */ + + carry4 = (h4 + (Int64)(1 << 25)) >> 26; h5 += carry4; h4 -= carry4 << 26; + carry8 = (h8 + (Int64)(1 << 25)) >> 26; h9 += carry8; h8 -= carry8 << 26; + /* |h4| <= 2^25; from now on fits into int32 unchanged */ + /* |h8| <= 2^25; from now on fits into int32 unchanged */ + /* |h5| <= 1.01*2^24 */ + /* |h9| <= 1.71*2^59 */ + + carry9 = (h9 + (Int64)(1 << 24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; + /* |h9| <= 2^24; from now on fits into int32 unchanged */ + /* |h0| <= 1.1*2^39 */ + + carry0 = (h0 + (Int64)(1 << 25)) >> 26; h1 += carry0; h0 -= carry0 << 26; + /* |h0| <= 2^25; from now on fits into int32 unchanged */ + /* |h1| <= 1.01*2^24 */ + + h.x0 = (Int32)h0; + h.x1 = (Int32)h1; + h.x2 = (Int32)h2; + h.x3 = (Int32)h3; + h.x4 = (Int32)h4; + h.x5 = (Int32)h5; + h.x6 = (Int32)h6; + h.x7 = (Int32)h7; + h.x8 = (Int32)h8; + h.x9 = (Int32)h9; + } + } +} \ No newline at end of file diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_mul.cs.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_mul.cs.meta new file mode 100644 index 0000000..5ff1e4d --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_mul.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 441fe18af2803c041bf91302426eb7f8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_mul121666.cs b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_mul121666.cs new file mode 100644 index 0000000..9132527 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_mul121666.cs @@ -0,0 +1,76 @@ +using System; + +namespace Chaos.NaCl.Internal.Ed25519Ref10 +{ + internal static partial class FieldOperations + { + + /* + h = f * 121666 + Can overlap h with f. + + Preconditions: + |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. + + Postconditions: + |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. + */ + + public static void fe_mul121666(out FieldElement h, ref FieldElement f) + { + Int32 f0 = f.x0; + Int32 f1 = f.x1; + Int32 f2 = f.x2; + Int32 f3 = f.x3; + Int32 f4 = f.x4; + Int32 f5 = f.x5; + Int32 f6 = f.x6; + Int32 f7 = f.x7; + Int32 f8 = f.x8; + Int32 f9 = f.x9; + Int64 h0 = f0 * (Int64)121666; + Int64 h1 = f1 * (Int64)121666; + Int64 h2 = f2 * (Int64)121666; + Int64 h3 = f3 * (Int64)121666; + Int64 h4 = f4 * (Int64)121666; + Int64 h5 = f5 * (Int64)121666; + Int64 h6 = f6 * (Int64)121666; + Int64 h7 = f7 * (Int64)121666; + Int64 h8 = f8 * (Int64)121666; + Int64 h9 = f9 * (Int64)121666; + Int64 carry0; + Int64 carry1; + Int64 carry2; + Int64 carry3; + Int64 carry4; + Int64 carry5; + Int64 carry6; + Int64 carry7; + Int64 carry8; + Int64 carry9; + + carry9 = (h9 + (Int64)(1 << 24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; + carry1 = (h1 + (Int64)(1 << 24)) >> 25; h2 += carry1; h1 -= carry1 << 25; + carry3 = (h3 + (Int64)(1 << 24)) >> 25; h4 += carry3; h3 -= carry3 << 25; + carry5 = (h5 + (Int64)(1 << 24)) >> 25; h6 += carry5; h5 -= carry5 << 25; + carry7 = (h7 + (Int64)(1 << 24)) >> 25; h8 += carry7; h7 -= carry7 << 25; + + carry0 = (h0 + (Int64)(1 << 25)) >> 26; h1 += carry0; h0 -= carry0 << 26; + carry2 = (h2 + (Int64)(1 << 25)) >> 26; h3 += carry2; h2 -= carry2 << 26; + carry4 = (h4 + (Int64)(1 << 25)) >> 26; h5 += carry4; h4 -= carry4 << 26; + carry6 = (h6 + (Int64)(1 << 25)) >> 26; h7 += carry6; h6 -= carry6 << 26; + carry8 = (h8 + (Int64)(1 << 25)) >> 26; h9 += carry8; h8 -= carry8 << 26; + + h.x0 = (int)h0; + h.x1 = (int)h1; + h.x2 = (int)h2; + h.x3 = (int)h3; + h.x4 = (int)h4; + h.x5 = (int)h5; + h.x6 = (int)h6; + h.x7 = (int)h7; + h.x8 = (int)h8; + h.x9 = (int)h9; + } + } +} \ No newline at end of file diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_mul121666.cs.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_mul121666.cs.meta new file mode 100644 index 0000000..5f158f0 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_mul121666.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4a74bf513e05fd8449ddf128e6c94c3c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_neg.cs b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_neg.cs new file mode 100644 index 0000000..64665ec --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_neg.cs @@ -0,0 +1,50 @@ +using System; + +namespace Chaos.NaCl.Internal.Ed25519Ref10 +{ + internal static partial class FieldOperations + { + /* + h = -f + + Preconditions: + |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. + + Postconditions: + |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. + */ + internal static void fe_neg(out FieldElement h, ref FieldElement f) + { + Int32 f0 = f.x0; + Int32 f1 = f.x1; + Int32 f2 = f.x2; + Int32 f3 = f.x3; + Int32 f4 = f.x4; + Int32 f5 = f.x5; + Int32 f6 = f.x6; + Int32 f7 = f.x7; + Int32 f8 = f.x8; + Int32 f9 = f.x9; + Int32 h0 = -f0; + Int32 h1 = -f1; + Int32 h2 = -f2; + Int32 h3 = -f3; + Int32 h4 = -f4; + Int32 h5 = -f5; + Int32 h6 = -f6; + Int32 h7 = -f7; + Int32 h8 = -f8; + Int32 h9 = -f9; + h.x0 = h0; + h.x1 = h1; + h.x2 = h2; + h.x3 = h3; + h.x4 = h4; + h.x5 = h5; + h.x6 = h6; + h.x7 = h7; + h.x8 = h8; + h.x9 = h9; + } + } +} \ No newline at end of file diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_neg.cs.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_neg.cs.meta new file mode 100644 index 0000000..52f2065 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_neg.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5ad3f8be86276dc4084a57788c133022 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_pow22523.cs b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_pow22523.cs new file mode 100644 index 0000000..5018f6d --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_pow22523.cs @@ -0,0 +1,175 @@ +using System; + +namespace Chaos.NaCl.Internal.Ed25519Ref10 +{ + internal static partial class FieldOperations + { + internal static void fe_pow22523(out FieldElement result, ref FieldElement z) + { + FieldElement t0; + FieldElement t1; + FieldElement t2; + int i; + + /* qhasm: fe z1 */ + + /* qhasm: fe z2 */ + + /* qhasm: fe z8 */ + + /* qhasm: fe z9 */ + + /* qhasm: fe z11 */ + + /* qhasm: fe z22 */ + + /* qhasm: fe z_5_0 */ + + /* qhasm: fe z_10_5 */ + + /* qhasm: fe z_10_0 */ + + /* qhasm: fe z_20_10 */ + + /* qhasm: fe z_20_0 */ + + /* qhasm: fe z_40_20 */ + + /* qhasm: fe z_40_0 */ + + /* qhasm: fe z_50_10 */ + + /* qhasm: fe z_50_0 */ + + /* qhasm: fe z_100_50 */ + + /* qhasm: fe z_100_0 */ + + /* qhasm: fe z_200_100 */ + + /* qhasm: fe z_200_0 */ + + /* qhasm: fe z_250_50 */ + + /* qhasm: fe z_250_0 */ + + /* qhasm: fe z_252_2 */ + + /* qhasm: fe z_252_3 */ + + /* qhasm: enter pow22523 */ + + /* qhasm: z2 = z1^2^1 */ + /* asm 1: fe_sq(>z2=fe#1,z2=fe#1,>z2=fe#1); */ + /* asm 2: fe_sq(>z2=t0,z2=t0,>z2=t0); */ + fe_sq(out t0, ref z); //for (i = 1; i < 1; ++i) fe_sq(out t0, ref t0); + + /* qhasm: z8 = z2^2^2 */ + /* asm 1: fe_sq(>z8=fe#2,z8=fe#2,>z8=fe#2); */ + /* asm 2: fe_sq(>z8=t1,z8=t1,>z8=t1); */ + fe_sq(out t1, ref t0); for (i = 1; i < 2; ++i) fe_sq(out t1, ref t1); + + /* qhasm: z9 = z1*z8 */ + /* asm 1: fe_mul(>z9=fe#2,z9=t1,z11=fe#1,z11=t0,z22=fe#1,z22=fe#1,>z22=fe#1); */ + /* asm 2: fe_sq(>z22=t0,z22=t0,>z22=t0); */ + fe_sq(out t0, ref t0); //for (i = 1; i < 1; ++i) fe_sq(out t0, ref t0); + + /* qhasm: z_5_0 = z9*z22 */ + /* asm 1: fe_mul(>z_5_0=fe#1,z_5_0=t0,z_10_5=fe#2,z_10_5=fe#2,>z_10_5=fe#2); */ + /* asm 2: fe_sq(>z_10_5=t1,z_10_5=t1,>z_10_5=t1); */ + fe_sq(out t1, ref t0); for (i = 1; i < 5; ++i) fe_sq(out t1, ref t1); + + /* qhasm: z_10_0 = z_10_5*z_5_0 */ + /* asm 1: fe_mul(>z_10_0=fe#1,z_10_0=t0,z_20_10=fe#2,z_20_10=fe#2,>z_20_10=fe#2); */ + /* asm 2: fe_sq(>z_20_10=t1,z_20_10=t1,>z_20_10=t1); */ + fe_sq(out t1, ref t0); for (i = 1; i < 10; ++i) fe_sq(out t1, ref t1); + + /* qhasm: z_20_0 = z_20_10*z_10_0 */ + /* asm 1: fe_mul(>z_20_0=fe#2,z_20_0=t1,z_40_20=fe#3,z_40_20=fe#3,>z_40_20=fe#3); */ + /* asm 2: fe_sq(>z_40_20=t2,z_40_20=t2,>z_40_20=t2); */ + fe_sq(out t2, ref t1); for (i = 1; i < 20; ++i) fe_sq(out t2, ref t2); + + /* qhasm: z_40_0 = z_40_20*z_20_0 */ + /* asm 1: fe_mul(>z_40_0=fe#2,z_40_0=t1,z_50_10=fe#2,z_50_10=fe#2,>z_50_10=fe#2); */ + /* asm 2: fe_sq(>z_50_10=t1,z_50_10=t1,>z_50_10=t1); */ + fe_sq(out t1, ref t1); for (i = 1; i < 10; ++i) fe_sq(out t1, ref t1); + + /* qhasm: z_50_0 = z_50_10*z_10_0 */ + /* asm 1: fe_mul(>z_50_0=fe#1,z_50_0=t0,z_100_50=fe#2,z_100_50=fe#2,>z_100_50=fe#2); */ + /* asm 2: fe_sq(>z_100_50=t1,z_100_50=t1,>z_100_50=t1); */ + fe_sq(out t1, ref t0); for (i = 1; i < 50; ++i) fe_sq(out t1, ref t1); + + /* qhasm: z_100_0 = z_100_50*z_50_0 */ + /* asm 1: fe_mul(>z_100_0=fe#2,z_100_0=t1,z_200_100=fe#3,z_200_100=fe#3,>z_200_100=fe#3); */ + /* asm 2: fe_sq(>z_200_100=t2,z_200_100=t2,>z_200_100=t2); */ + fe_sq(out t2, ref t1); for (i = 1; i < 100; ++i) fe_sq(out t2, ref t2); + + /* qhasm: z_200_0 = z_200_100*z_100_0 */ + /* asm 1: fe_mul(>z_200_0=fe#2,z_200_0=t1,z_250_50=fe#2,z_250_50=fe#2,>z_250_50=fe#2); */ + /* asm 2: fe_sq(>z_250_50=t1,z_250_50=t1,>z_250_50=t1); */ + fe_sq(out t1, ref t1); for (i = 1; i < 50; ++i) fe_sq(out t1, ref t1); + + /* qhasm: z_250_0 = z_250_50*z_50_0 */ + /* asm 1: fe_mul(>z_250_0=fe#1,z_250_0=t0,z_252_2=fe#1,z_252_2=fe#1,>z_252_2=fe#1); */ + /* asm 2: fe_sq(>z_252_2=t0,z_252_2=t0,>z_252_2=t0); */ + fe_sq(out t0, ref t0); for (i = 1; i < 2; ++i) fe_sq(out t0, ref t0); + + /* qhasm: z_252_3 = z_252_2*z1 */ + /* asm 1: fe_mul(>z_252_3=fe#12,z_252_3=out,> 26; h1 += carry0; h0 -= carry0 << 26; + carry4 = (h4 + (Int64)(1 << 25)) >> 26; h5 += carry4; h4 -= carry4 << 26; + + carry1 = (h1 + (Int64)(1 << 24)) >> 25; h2 += carry1; h1 -= carry1 << 25; + carry5 = (h5 + (Int64)(1 << 24)) >> 25; h6 += carry5; h5 -= carry5 << 25; + + carry2 = (h2 + (Int64)(1 << 25)) >> 26; h3 += carry2; h2 -= carry2 << 26; + carry6 = (h6 + (Int64)(1 << 25)) >> 26; h7 += carry6; h6 -= carry6 << 26; + + carry3 = (h3 + (Int64)(1 << 24)) >> 25; h4 += carry3; h3 -= carry3 << 25; + carry7 = (h7 + (Int64)(1 << 24)) >> 25; h8 += carry7; h7 -= carry7 << 25; + + carry4 = (h4 + (Int64)(1 << 25)) >> 26; h5 += carry4; h4 -= carry4 << 26; + carry8 = (h8 + (Int64)(1 << 25)) >> 26; h9 += carry8; h8 -= carry8 << 26; + + carry9 = (h9 + (Int64)(1 << 24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; + + carry0 = (h0 + (Int64)(1 << 25)) >> 26; h1 += carry0; h0 -= carry0 << 26; + + h.x0 = (Int32)h0; + h.x1 = (Int32)h1; + h.x2 = (Int32)h2; + h.x3 = (Int32)h3; + h.x4 = (Int32)h4; + h.x5 = (Int32)h5; + h.x6 = (Int32)h6; + h.x7 = (Int32)h7; + h.x8 = (Int32)h8; + h.x9 = (Int32)h9; + } + } +} \ No newline at end of file diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_sq.cs.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_sq.cs.meta new file mode 100644 index 0000000..3e10509 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_sq.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e8a78758458a1d24ca9f5902d3148e09 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_sq2.cs b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_sq2.cs new file mode 100644 index 0000000..40913bb --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_sq2.cs @@ -0,0 +1,164 @@ +using System; + +namespace Chaos.NaCl.Internal.Ed25519Ref10 +{ + internal static partial class FieldOperations + { + /* +h = 2 * f * f +Can overlap h with f. + +Preconditions: + |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. + +Postconditions: + |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc. +*/ + + /* + See fe_mul.c for discussion of implementation strategy. + */ + internal static void fe_sq2(out FieldElement h, ref FieldElement f) + { + Int32 f0 = f.x0; + Int32 f1 = f.x1; + Int32 f2 = f.x2; + Int32 f3 = f.x3; + Int32 f4 = f.x4; + Int32 f5 = f.x5; + Int32 f6 = f.x6; + Int32 f7 = f.x7; + Int32 f8 = f.x8; + Int32 f9 = f.x9; + Int32 f0_2 = 2 * f0; + Int32 f1_2 = 2 * f1; + Int32 f2_2 = 2 * f2; + Int32 f3_2 = 2 * f3; + Int32 f4_2 = 2 * f4; + Int32 f5_2 = 2 * f5; + Int32 f6_2 = 2 * f6; + Int32 f7_2 = 2 * f7; + Int32 f5_38 = 38 * f5; /* 1.959375*2^30 */ + Int32 f6_19 = 19 * f6; /* 1.959375*2^30 */ + Int32 f7_38 = 38 * f7; /* 1.959375*2^30 */ + Int32 f8_19 = 19 * f8; /* 1.959375*2^30 */ + Int32 f9_38 = 38 * f9; /* 1.959375*2^30 */ + Int64 f0f0 = f0 * (Int64)f0; + Int64 f0f1_2 = f0_2 * (Int64)f1; + Int64 f0f2_2 = f0_2 * (Int64)f2; + Int64 f0f3_2 = f0_2 * (Int64)f3; + Int64 f0f4_2 = f0_2 * (Int64)f4; + Int64 f0f5_2 = f0_2 * (Int64)f5; + Int64 f0f6_2 = f0_2 * (Int64)f6; + Int64 f0f7_2 = f0_2 * (Int64)f7; + Int64 f0f8_2 = f0_2 * (Int64)f8; + Int64 f0f9_2 = f0_2 * (Int64)f9; + Int64 f1f1_2 = f1_2 * (Int64)f1; + Int64 f1f2_2 = f1_2 * (Int64)f2; + Int64 f1f3_4 = f1_2 * (Int64)f3_2; + Int64 f1f4_2 = f1_2 * (Int64)f4; + Int64 f1f5_4 = f1_2 * (Int64)f5_2; + Int64 f1f6_2 = f1_2 * (Int64)f6; + Int64 f1f7_4 = f1_2 * (Int64)f7_2; + Int64 f1f8_2 = f1_2 * (Int64)f8; + Int64 f1f9_76 = f1_2 * (Int64)f9_38; + Int64 f2f2 = f2 * (Int64)f2; + Int64 f2f3_2 = f2_2 * (Int64)f3; + Int64 f2f4_2 = f2_2 * (Int64)f4; + Int64 f2f5_2 = f2_2 * (Int64)f5; + Int64 f2f6_2 = f2_2 * (Int64)f6; + Int64 f2f7_2 = f2_2 * (Int64)f7; + Int64 f2f8_38 = f2_2 * (Int64)f8_19; + Int64 f2f9_38 = f2 * (Int64)f9_38; + Int64 f3f3_2 = f3_2 * (Int64)f3; + Int64 f3f4_2 = f3_2 * (Int64)f4; + Int64 f3f5_4 = f3_2 * (Int64)f5_2; + Int64 f3f6_2 = f3_2 * (Int64)f6; + Int64 f3f7_76 = f3_2 * (Int64)f7_38; + Int64 f3f8_38 = f3_2 * (Int64)f8_19; + Int64 f3f9_76 = f3_2 * (Int64)f9_38; + Int64 f4f4 = f4 * (Int64)f4; + Int64 f4f5_2 = f4_2 * (Int64)f5; + Int64 f4f6_38 = f4_2 * (Int64)f6_19; + Int64 f4f7_38 = f4 * (Int64)f7_38; + Int64 f4f8_38 = f4_2 * (Int64)f8_19; + Int64 f4f9_38 = f4 * (Int64)f9_38; + Int64 f5f5_38 = f5 * (Int64)f5_38; + Int64 f5f6_38 = f5_2 * (Int64)f6_19; + Int64 f5f7_76 = f5_2 * (Int64)f7_38; + Int64 f5f8_38 = f5_2 * (Int64)f8_19; + Int64 f5f9_76 = f5_2 * (Int64)f9_38; + Int64 f6f6_19 = f6 * (Int64)f6_19; + Int64 f6f7_38 = f6 * (Int64)f7_38; + Int64 f6f8_38 = f6_2 * (Int64)f8_19; + Int64 f6f9_38 = f6 * (Int64)f9_38; + Int64 f7f7_38 = f7 * (Int64)f7_38; + Int64 f7f8_38 = f7_2 * (Int64)f8_19; + Int64 f7f9_76 = f7_2 * (Int64)f9_38; + Int64 f8f8_19 = f8 * (Int64)f8_19; + Int64 f8f9_38 = f8 * (Int64)f9_38; + Int64 f9f9_38 = f9 * (Int64)f9_38; + Int64 h0 = f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38; + Int64 h1 = f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38; + Int64 h2 = f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19; + Int64 h3 = f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38; + Int64 h4 = f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38; + Int64 h5 = f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38; + Int64 h6 = f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19; + Int64 h7 = f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38; + Int64 h8 = f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38; + Int64 h9 = f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2; + Int64 carry0; + Int64 carry1; + Int64 carry2; + Int64 carry3; + Int64 carry4; + Int64 carry5; + Int64 carry6; + Int64 carry7; + Int64 carry8; + Int64 carry9; + + h0 += h0; + h1 += h1; + h2 += h2; + h3 += h3; + h4 += h4; + h5 += h5; + h6 += h6; + h7 += h7; + h8 += h8; + h9 += h9; + + carry0 = (h0 + (Int64)(1 << 25)) >> 26; h1 += carry0; h0 -= carry0 << 26; + carry4 = (h4 + (Int64)(1 << 25)) >> 26; h5 += carry4; h4 -= carry4 << 26; + + carry1 = (h1 + (Int64)(1 << 24)) >> 25; h2 += carry1; h1 -= carry1 << 25; + carry5 = (h5 + (Int64)(1 << 24)) >> 25; h6 += carry5; h5 -= carry5 << 25; + + carry2 = (h2 + (Int64)(1 << 25)) >> 26; h3 += carry2; h2 -= carry2 << 26; + carry6 = (h6 + (Int64)(1 << 25)) >> 26; h7 += carry6; h6 -= carry6 << 26; + + carry3 = (h3 + (Int64)(1 << 24)) >> 25; h4 += carry3; h3 -= carry3 << 25; + carry7 = (h7 + (Int64)(1 << 24)) >> 25; h8 += carry7; h7 -= carry7 << 25; + + carry4 = (h4 + (Int64)(1 << 25)) >> 26; h5 += carry4; h4 -= carry4 << 26; + carry8 = (h8 + (Int64)(1 << 25)) >> 26; h9 += carry8; h8 -= carry8 << 26; + + carry9 = (h9 + (Int64)(1 << 24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; + + carry0 = (h0 + (Int64)(1 << 25)) >> 26; h1 += carry0; h0 -= carry0 << 26; + + h.x0 = (Int32)h0; + h.x1 = (Int32)h1; + h.x2 = (Int32)h2; + h.x3 = (Int32)h3; + h.x4 = (Int32)h4; + h.x5 = (Int32)h5; + h.x6 = (Int32)h6; + h.x7 = (Int32)h7; + h.x8 = (Int32)h8; + h.x9 = (Int32)h9; + } + } +} \ No newline at end of file diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_sq2.cs.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_sq2.cs.meta new file mode 100644 index 0000000..f9267f6 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_sq2.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 303b7eb42a3136a46928ebc8c3c53a63 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_sub.cs b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_sub.cs new file mode 100644 index 0000000..4de0e6c --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_sub.cs @@ -0,0 +1,63 @@ +using System; + +namespace Chaos.NaCl.Internal.Ed25519Ref10 +{ + internal static partial class FieldOperations + { + /* + h = f - g + Can overlap h with f or g. + + Preconditions: + |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. + |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. + + Postconditions: + |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. + */ + + internal static void fe_sub(out FieldElement h, ref FieldElement f, ref FieldElement g) + { + Int32 f0 = f.x0; + Int32 f1 = f.x1; + Int32 f2 = f.x2; + Int32 f3 = f.x3; + Int32 f4 = f.x4; + Int32 f5 = f.x5; + Int32 f6 = f.x6; + Int32 f7 = f.x7; + Int32 f8 = f.x8; + Int32 f9 = f.x9; + Int32 g0 = g.x0; + Int32 g1 = g.x1; + Int32 g2 = g.x2; + Int32 g3 = g.x3; + Int32 g4 = g.x4; + Int32 g5 = g.x5; + Int32 g6 = g.x6; + Int32 g7 = g.x7; + Int32 g8 = g.x8; + Int32 g9 = g.x9; + Int32 h0 = f0 - g0; + Int32 h1 = f1 - g1; + Int32 h2 = f2 - g2; + Int32 h3 = f3 - g3; + Int32 h4 = f4 - g4; + Int32 h5 = f5 - g5; + Int32 h6 = f6 - g6; + Int32 h7 = f7 - g7; + Int32 h8 = f8 - g8; + Int32 h9 = f9 - g9; + h.x0 = h0; + h.x1 = h1; + h.x2 = h2; + h.x3 = h3; + h.x4 = h4; + h.x5 = h5; + h.x6 = h6; + h.x7 = h7; + h.x8 = h8; + h.x9 = h9; + } + } +} \ No newline at end of file diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_sub.cs.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_sub.cs.meta new file mode 100644 index 0000000..ee69b53 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_sub.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 63a6eb4f3d5321a46bc913d033a7cbf2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_tobytes.cs b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_tobytes.cs new file mode 100644 index 0000000..9a36a8f --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_tobytes.cs @@ -0,0 +1,154 @@ +using System; + +namespace Chaos.NaCl.Internal.Ed25519Ref10 +{ + internal static partial class FieldOperations + { + /* + Preconditions: + |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. + + Write p=2^255-19; q=floor(h/p). + Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))). + + Proof: + Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4. + Also have |h-2^230 h9|<2^231 so |19 2^(-255)(h-2^230 h9)|<1/4. + + Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9). + Then 0> 0); + s[offset + 1] = (byte) (h0 >> 8); + s[offset + 2] = (byte) (h0 >> 16); + s[offset + 3] = (byte) ((h0 >> 24) | (h1 << 2)); + s[offset + 4] = (byte) (h1 >> 6); + s[offset + 5] = (byte) (h1 >> 14); + s[offset + 6] = (byte) ((h1 >> 22) | (h2 << 3)); + s[offset + 7] = (byte) (h2 >> 5); + s[offset + 8] = (byte) (h2 >> 13); + s[offset + 9] = (byte) ((h2 >> 21) | (h3 << 5)); + s[offset + 10] = (byte) (h3 >> 3); + s[offset + 11] = (byte) (h3 >> 11); + s[offset + 12] = (byte) ((h3 >> 19) | (h4 << 6)); + s[offset + 13] = (byte) (h4 >> 2); + s[offset + 14] = (byte) (h4 >> 10); + s[offset + 15] = (byte) (h4 >> 18); + s[offset + 16] = (byte) (h5 >> 0); + s[offset + 17] = (byte) (h5 >> 8); + s[offset + 18] = (byte) (h5 >> 16); + s[offset + 19] = (byte) ((h5 >> 24) | (h6 << 1)); + s[offset + 20] = (byte) (h6 >> 7); + s[offset + 21] = (byte) (h6 >> 15); + s[offset + 22] = (byte) ((h6 >> 23) | (h7 << 3)); + s[offset + 23] = (byte) (h7 >> 5); + s[offset + 24] = (byte) (h7 >> 13); + s[offset + 25] = (byte) ((h7 >> 21) | (h8 << 4)); + s[offset + 26] = (byte) (h8 >> 4); + s[offset + 27] = (byte) (h8 >> 12); + s[offset + 28] = (byte) ((h8 >> 20) | (h9 << 6)); + s[offset + 29] = (byte) (h9 >> 2); + s[offset + 30] = (byte) (h9 >> 10); + s[offset + 31] = (byte) (h9 >> 18); + } + } + + internal static void fe_reduce(out FieldElement hr, ref FieldElement h) + { + Int32 h0 = h.x0; + Int32 h1 = h.x1; + Int32 h2 = h.x2; + Int32 h3 = h.x3; + Int32 h4 = h.x4; + Int32 h5 = h.x5; + Int32 h6 = h.x6; + Int32 h7 = h.x7; + Int32 h8 = h.x8; + Int32 h9 = h.x9; + Int32 q; + Int32 carry0; + Int32 carry1; + Int32 carry2; + Int32 carry3; + Int32 carry4; + Int32 carry5; + Int32 carry6; + Int32 carry7; + Int32 carry8; + Int32 carry9; + + q = (19 * h9 + (((Int32)1) << 24)) >> 25; + q = (h0 + q) >> 26; + q = (h1 + q) >> 25; + q = (h2 + q) >> 26; + q = (h3 + q) >> 25; + q = (h4 + q) >> 26; + q = (h5 + q) >> 25; + q = (h6 + q) >> 26; + q = (h7 + q) >> 25; + q = (h8 + q) >> 26; + q = (h9 + q) >> 25; + + /* Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. */ + h0 += 19 * q; + /* Goal: Output h-2^255 q, which is between 0 and 2^255-20. */ + + carry0 = h0 >> 26; h1 += carry0; h0 -= carry0 << 26; + carry1 = h1 >> 25; h2 += carry1; h1 -= carry1 << 25; + carry2 = h2 >> 26; h3 += carry2; h2 -= carry2 << 26; + carry3 = h3 >> 25; h4 += carry3; h3 -= carry3 << 25; + carry4 = h4 >> 26; h5 += carry4; h4 -= carry4 << 26; + carry5 = h5 >> 25; h6 += carry5; h5 -= carry5 << 25; + carry6 = h6 >> 26; h7 += carry6; h6 -= carry6 << 26; + carry7 = h7 >> 25; h8 += carry7; h7 -= carry7 << 25; + carry8 = h8 >> 26; h9 += carry8; h8 -= carry8 << 26; + carry9 = h9 >> 25; h9 -= carry9 << 25; + /* h10 = carry9 */ + + hr.x0 = h0; + hr.x1 = h1; + hr.x2 = h2; + hr.x3 = h3; + hr.x4 = h4; + hr.x5 = h5; + hr.x6 = h6; + hr.x7 = h7; + hr.x8 = h8; + hr.x9 = h9; + } + } +} \ No newline at end of file diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_tobytes.cs.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_tobytes.cs.meta new file mode 100644 index 0000000..f0b1d97 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/fe_tobytes.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1d581a91a1b5acb41be63495e800b337 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/ge_add.cs b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/ge_add.cs new file mode 100644 index 0000000..f80a817 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/ge_add.cs @@ -0,0 +1,113 @@ +using System; + +namespace Chaos.NaCl.Internal.Ed25519Ref10 +{ + internal static partial class GroupOperations + { + /* + r = p + q + */ + + internal static void ge_add(out GroupElementP1P1 r, ref GroupElementP3 p, ref GroupElementCached q) + { + FieldElement t0; + + /* qhasm: enter GroupElementadd */ + + /* qhasm: fe X1 */ + + /* qhasm: fe Y1 */ + + /* qhasm: fe Z1 */ + + /* qhasm: fe Z2 */ + + /* qhasm: fe T1 */ + + /* qhasm: fe ZZ */ + + /* qhasm: fe YpX2 */ + + /* qhasm: fe YmX2 */ + + /* qhasm: fe T2d2 */ + + /* qhasm: fe X3 */ + + /* qhasm: fe Y3 */ + + /* qhasm: fe Z3 */ + + /* qhasm: fe T3 */ + + /* qhasm: fe YpX1 */ + + /* qhasm: fe YmX1 */ + + /* qhasm: fe A */ + + /* qhasm: fe B */ + + /* qhasm: fe C */ + + /* qhasm: fe D */ + + /* qhasm: YpX1 = Y1+X1 */ + /* asm 1: fe_add(>YpX1=fe#1,YpX1=r.X,YmX1=fe#2,YmX1=r.Y,A=fe#3,A=r.Z,B=fe#2,B=r.Y,C=fe#4,C=r.T,ZZ=fe#1,ZZ=r.X,D=fe#5,D=t0,X3=fe#1,X3=r.X,Y3=fe#2,Y3=r.Y,Z3=fe#3,Z3=r.Z,T3=fe#4,T3=r.T,> 3] >> (i & 7))); + + for (i = 0; i < 256; ++i) + if (r[i] != 0) + { + for (b = 1; b <= 6 && i + b < 256; ++b) + { + if (r[i + b] != 0) + { + if (r[i] + (r[i + b] << b) <= 15) + { + r[i] += (sbyte)(r[i + b] << b); r[i + b] = 0; + } + else if (r[i] - (r[i + b] << b) >= -15) + { + r[i] -= (sbyte)(r[i + b] << b); + for (k = i + b; k < 256; ++k) + { + if (r[k] == 0) + { + r[k] = 1; + break; + } + r[k] = 0; + } + } + else + break; + } + } + } + + } + + /* + r = a * A + b * B + where a = a[0]+256*a[1]+...+256^31 a[31]. + and b = b[0]+256*b[1]+...+256^31 b[31]. + B is the Ed25519 base point (x,4/5) with x positive. + */ + + public static void ge_double_scalarmult_vartime(out GroupElementP2 r, byte[] a, ref GroupElementP3 A, byte[] b) + { + GroupElementPreComp[] Bi = LookupTables.Base2; + // todo: Perhaps remove these allocations? + sbyte[] aslide = new sbyte[256]; + sbyte[] bslide = new sbyte[256]; + GroupElementCached[] Ai = new GroupElementCached[8]; /* A,3A,5A,7A,9A,11A,13A,15A */ + GroupElementP1P1 t; + GroupElementP3 u; + GroupElementP3 A2; + int i; + + slide(aslide, a); + slide(bslide, b); + + ge_p3_to_cached(out Ai[0], ref A); + ge_p3_dbl(out t, ref A); ge_p1p1_to_p3(out A2, ref t); + ge_add(out t, ref A2, ref Ai[0]); ge_p1p1_to_p3(out u, ref t); ge_p3_to_cached(out Ai[1], ref u); + ge_add(out t, ref A2, ref Ai[1]); ge_p1p1_to_p3(out u, ref t); ge_p3_to_cached(out Ai[2], ref u); + ge_add(out t, ref A2, ref Ai[2]); ge_p1p1_to_p3(out u, ref t); ge_p3_to_cached(out Ai[3], ref u); + ge_add(out t, ref A2, ref Ai[3]); ge_p1p1_to_p3(out u, ref t); ge_p3_to_cached(out Ai[4], ref u); + ge_add(out t, ref A2, ref Ai[4]); ge_p1p1_to_p3(out u, ref t); ge_p3_to_cached(out Ai[5], ref u); + ge_add(out t, ref A2, ref Ai[5]); ge_p1p1_to_p3(out u, ref t); ge_p3_to_cached(out Ai[6], ref u); + ge_add(out t, ref A2, ref Ai[6]); ge_p1p1_to_p3(out u, ref t); ge_p3_to_cached(out Ai[7], ref u); + + ge_p2_0(out r); + + for (i = 255; i >= 0; --i) + { + if ((aslide[i] != 0) || (bslide[i] != 0)) break; + } + + for (; i >= 0; --i) + { + ge_p2_dbl(out t, ref r); + + if (aslide[i] > 0) + { + ge_p1p1_to_p3(out u, ref t); + ge_add(out t, ref u, ref Ai[aslide[i] / 2]); + } + else if (aslide[i] < 0) + { + ge_p1p1_to_p3(out u, ref t); + ge_sub(out t, ref u, ref Ai[(-aslide[i]) / 2]); + } + + if (bslide[i] > 0) + { + ge_p1p1_to_p3(out u, ref t); + ge_madd(out t, ref u, ref Bi[bslide[i] / 2]); + } + else if (bslide[i] < 0) + { + ge_p1p1_to_p3(out u, ref t); + ge_msub(out t, ref u, ref Bi[(-bslide[i]) / 2]); + } + + ge_p1p1_to_p2(out r, ref t); + } + } + + } +} \ No newline at end of file diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/ge_double_scalarmult.cs.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/ge_double_scalarmult.cs.meta new file mode 100644 index 0000000..d1cc992 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/ge_double_scalarmult.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: be96edd1cbc40de4499dcb541eb46675 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/ge_frombytes.cs b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/ge_frombytes.cs new file mode 100644 index 0000000..6ec8dc4 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/ge_frombytes.cs @@ -0,0 +1,54 @@ +using System; + +namespace Chaos.NaCl.Internal.Ed25519Ref10 +{ + internal static partial class GroupOperations + { + public static int ge_frombytes_negate_vartime(out GroupElementP3 h, byte[] data, int offset) + { + FieldElement u; + FieldElement v; + FieldElement v3; + FieldElement vxx; + FieldElement check; + + FieldOperations.fe_frombytes(out h.Y, data, offset); + FieldOperations.fe_1(out h.Z); + FieldOperations.fe_sq(out u, ref h.Y); + FieldOperations.fe_mul(out v, ref u, ref LookupTables.d); + FieldOperations.fe_sub(out u, ref u, ref h.Z); /* u = y^2-1 */ + FieldOperations.fe_add(out v, ref v, ref h.Z); /* v = dy^2+1 */ + + FieldOperations.fe_sq(out v3, ref v); + FieldOperations.fe_mul(out v3, ref v3, ref v); /* v3 = v^3 */ + FieldOperations.fe_sq(out h.X, ref v3); + FieldOperations.fe_mul(out h.X, ref h.X, ref v); + FieldOperations.fe_mul(out h.X, ref h.X, ref u); /* x = uv^7 */ + + FieldOperations.fe_pow22523(out h.X, ref h.X); /* x = (uv^7)^((q-5)/8) */ + FieldOperations.fe_mul(out h.X, ref h.X, ref v3); + FieldOperations.fe_mul(out h.X, ref h.X, ref u); /* x = uv^3(uv^7)^((q-5)/8) */ + + FieldOperations.fe_sq(out vxx, ref h.X); + FieldOperations.fe_mul(out vxx, ref vxx, ref v); + FieldOperations.fe_sub(out check, ref vxx, ref u); /* vx^2-u */ + if (FieldOperations.fe_isnonzero(ref check) != 0) + { + FieldOperations.fe_add(out check, ref vxx, ref u); /* vx^2+u */ + if (FieldOperations.fe_isnonzero(ref check) != 0) + { + h = default(GroupElementP3); + return -1; + } + FieldOperations.fe_mul(out h.X, ref h.X, ref LookupTables.sqrtm1); + } + + if (FieldOperations.fe_isnegative(ref h.X) == (data[offset + 31] >> 7)) + FieldOperations.fe_neg(out h.X, ref h.X); + + FieldOperations.fe_mul(out h.T, ref h.X, ref h.Y); + return 0; + } + + } +} \ No newline at end of file diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/ge_frombytes.cs.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/ge_frombytes.cs.meta new file mode 100644 index 0000000..865d571 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/ge_frombytes.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2a34b7a088a6745418f598e065501b04 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/ge_madd.cs b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/ge_madd.cs new file mode 100644 index 0000000..de80fa6 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/ge_madd.cs @@ -0,0 +1,105 @@ +using System; + +namespace Chaos.NaCl.Internal.Ed25519Ref10 +{ + internal static partial class GroupOperations + { + /* + r = p + q + */ + public static void ge_madd(out GroupElementP1P1 r, ref GroupElementP3 p, ref GroupElementPreComp q) + { + FieldElement t0; + + /* qhasm: enter ge_madd */ + + /* qhasm: fe X1 */ + + /* qhasm: fe Y1 */ + + /* qhasm: fe Z1 */ + + /* qhasm: fe T1 */ + + /* qhasm: fe ypx2 */ + + /* qhasm: fe ymx2 */ + + /* qhasm: fe xy2d2 */ + + /* qhasm: fe X3 */ + + /* qhasm: fe Y3 */ + + /* qhasm: fe Z3 */ + + /* qhasm: fe T3 */ + + /* qhasm: fe YpX1 */ + + /* qhasm: fe YmX1 */ + + /* qhasm: fe A */ + + /* qhasm: fe B */ + + /* qhasm: fe C */ + + /* qhasm: fe D */ + + /* qhasm: YpX1 = Y1+X1 */ + /* asm 1: fe_add(>YpX1=fe#1,YpX1=r.X,YmX1=fe#2,YmX1=r.Y,A=fe#3,A=r.Z,B=fe#2,B=r.Y,C=fe#4,C=r.T,D=fe#5,D=t0,X3=fe#1,X3=r.X,Y3=fe#2,Y3=r.Y,Z3=fe#3,Z3=r.Z,T3=fe#4,T3=r.T,YpX1=fe#1,YpX1=r.X,YmX1=fe#2,YmX1=r.Y,A=fe#3,A=r.Z,B=fe#2,B=r.Y,C=fe#4,C=r.T,D=fe#5,D=t0,X3=fe#1,X3=r.X,Y3=fe#2,Y3=r.Y,Z3=fe#3,Z3=r.Z,T3=fe#4,T3=r.T,XX=fe#1,XX=r.X,YY=fe#3,YY=r.Z,B=fe#4,B=r.T,A=fe#2,A=r.Y,AA=fe#5,AA=t0,Y3=fe#2,Y3=r.Y,Z3=fe#3,Z3=r.Z,X3=fe#1,X3=r.X,T3=fe#4,T3=r.T,>= 31; /* 1: yes; 0: no */ + return (byte)y; + } + + static byte negative(sbyte b) + { + ulong x = unchecked((ulong)(long)b); /* 18446744073709551361..18446744073709551615: yes; 0..255: no */ + x >>= 63; /* 1: yes; 0: no */ + return (byte)x; + } + + static void cmov(ref GroupElementPreComp t, ref GroupElementPreComp u, byte b) + { + FieldOperations.fe_cmov(ref t.yplusx, ref u.yplusx, b); + FieldOperations.fe_cmov(ref t.yminusx, ref u.yminusx, b); + FieldOperations.fe_cmov(ref t.xy2d, ref u.xy2d, b); + } + + static void select(out GroupElementPreComp t, int pos, sbyte b) + { + GroupElementPreComp minust; + byte bnegative = negative(b); + byte babs = (byte)(b - (((-bnegative) & b) << 1)); + + ge_precomp_0(out t); + var table = LookupTables.Base[pos]; + cmov(ref t, ref table[0], equal(babs, 1)); + cmov(ref t, ref table[1], equal(babs, 2)); + cmov(ref t, ref table[2], equal(babs, 3)); + cmov(ref t, ref table[3], equal(babs, 4)); + cmov(ref t, ref table[4], equal(babs, 5)); + cmov(ref t, ref table[5], equal(babs, 6)); + cmov(ref t, ref table[6], equal(babs, 7)); + cmov(ref t, ref table[7], equal(babs, 8)); + minust.yplusx = t.yminusx; + minust.yminusx = t.yplusx; + FieldOperations.fe_neg(out minust.xy2d, ref t.xy2d); + cmov(ref t, ref minust, bnegative); + } + + /* + h = a * B + where a = a[0]+256*a[1]+...+256^31 a[31] + B is the Ed25519 base point (x,4/5) with x positive. + + Preconditions: + a[31] <= 127 + */ + + public static void ge_scalarmult_base(out GroupElementP3 h, byte[] a, int offset) + { + // todo: Perhaps remove this allocation + sbyte[] e = new sbyte[64]; + sbyte carry; + GroupElementP1P1 r; + GroupElementP2 s; + GroupElementPreComp t; + int i; + + for (i = 0; i < 32; ++i) + { + e[2 * i + 0] = (sbyte)((a[offset + i] >> 0) & 15); + e[2 * i + 1] = (sbyte)((a[offset + i] >> 4) & 15); + } + /* each e[i] is between 0 and 15 */ + /* e[63] is between 0 and 7 */ + + carry = 0; + for (i = 0; i < 63; ++i) + { + e[i] += carry; + carry = (sbyte)(e[i] + 8); + carry >>= 4; + e[i] -= (sbyte)(carry << 4); + } + e[63] += carry; + /* each e[i] is between -8 and 8 */ + + ge_p3_0(out h); + for (i = 1; i < 64; i += 2) + { + select(out t, i / 2, e[i]); + ge_madd(out r, ref h, ref t); ge_p1p1_to_p3(out h, ref r); + } + + ge_p3_dbl(out r, ref h); ge_p1p1_to_p2(out s, ref r); + ge_p2_dbl(out r, ref s); ge_p1p1_to_p2(out s, ref r); + ge_p2_dbl(out r, ref s); ge_p1p1_to_p2(out s, ref r); + ge_p2_dbl(out r, ref s); ge_p1p1_to_p3(out h, ref r); + + for (i = 0; i < 64; i += 2) + { + select(out t, i / 2, e[i]); + ge_madd(out r, ref h, ref t); ge_p1p1_to_p3(out h, ref r); + } + } + + } +} \ No newline at end of file diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/ge_scalarmult_base.cs.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/ge_scalarmult_base.cs.meta new file mode 100644 index 0000000..80437ea --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/ge_scalarmult_base.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9ccdeab433c64504cbfd94e8811545a1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/ge_sub.cs b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/ge_sub.cs new file mode 100644 index 0000000..0965b53 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/ge_sub.cs @@ -0,0 +1,114 @@ +using System; + +namespace Chaos.NaCl.Internal.Ed25519Ref10 +{ + internal static partial class GroupOperations + { + /* + r = p - q + */ + + public static void ge_sub(out GroupElementP1P1 r, ref GroupElementP3 p, ref GroupElementCached q) + { + FieldElement t0; + + /* qhasm: enter ge_sub */ + + /* qhasm: fe X1 */ + + /* qhasm: fe Y1 */ + + /* qhasm: fe Z1 */ + + /* qhasm: fe Z2 */ + + /* qhasm: fe T1 */ + + /* qhasm: fe ZZ */ + + /* qhasm: fe YpX2 */ + + /* qhasm: fe YmX2 */ + + /* qhasm: fe T2d2 */ + + /* qhasm: fe X3 */ + + /* qhasm: fe Y3 */ + + /* qhasm: fe Z3 */ + + /* qhasm: fe T3 */ + + /* qhasm: fe YpX1 */ + + /* qhasm: fe YmX1 */ + + /* qhasm: fe A */ + + /* qhasm: fe B */ + + /* qhasm: fe C */ + + /* qhasm: fe D */ + + /* qhasm: YpX1 = Y1+X1 */ + /* asm 1: fe_add(>YpX1=fe#1,YpX1=r.X,YmX1=fe#2,YmX1=r.Y,A=fe#3,A=r.Z,B=fe#2,B=r.Y,C=fe#4,C=r.T,ZZ=fe#1,ZZ=r.X,D=fe#5,D=t0,X3=fe#1,X3=r.X,Y3=fe#2,Y3=r.Y,Z3=fe#3,Z3=r.Z,T3=fe#4,T3=r.T,> 5); + Int64 a2 = 2097151 & (load_3(a, 5) >> 2); + Int64 a3 = 2097151 & (load_4(a, 7) >> 7); + Int64 a4 = 2097151 & (load_4(a, 10) >> 4); + Int64 a5 = 2097151 & (load_3(a, 13) >> 1); + Int64 a6 = 2097151 & (load_4(a, 15) >> 6); + Int64 a7 = 2097151 & (load_3(a, 18) >> 3); + Int64 a8 = 2097151 & load_3(a, 21); + Int64 a9 = 2097151 & (load_4(a, 23) >> 5); + Int64 a10 = 2097151 & (load_3(a, 26) >> 2); + Int64 a11 = (load_4(a, 28) >> 7); + Int64 b0 = 2097151 & load_3(b, 0); + Int64 b1 = 2097151 & (load_4(b, 2) >> 5); + Int64 b2 = 2097151 & (load_3(b, 5) >> 2); + Int64 b3 = 2097151 & (load_4(b, 7) >> 7); + Int64 b4 = 2097151 & (load_4(b, 10) >> 4); + Int64 b5 = 2097151 & (load_3(b, 13) >> 1); + Int64 b6 = 2097151 & (load_4(b, 15) >> 6); + Int64 b7 = 2097151 & (load_3(b, 18) >> 3); + Int64 b8 = 2097151 & load_3(b, 21); + Int64 b9 = 2097151 & (load_4(b, 23) >> 5); + Int64 b10 = 2097151 & (load_3(b, 26) >> 2); + Int64 b11 = (load_4(b, 28) >> 7); + Int64 c0 = 2097151 & load_3(c, 0); + Int64 c1 = 2097151 & (load_4(c, 2) >> 5); + Int64 c2 = 2097151 & (load_3(c, 5) >> 2); + Int64 c3 = 2097151 & (load_4(c, 7) >> 7); + Int64 c4 = 2097151 & (load_4(c, 10) >> 4); + Int64 c5 = 2097151 & (load_3(c, 13) >> 1); + Int64 c6 = 2097151 & (load_4(c, 15) >> 6); + Int64 c7 = 2097151 & (load_3(c, 18) >> 3); + Int64 c8 = 2097151 & load_3(c, 21); + Int64 c9 = 2097151 & (load_4(c, 23) >> 5); + Int64 c10 = 2097151 & (load_3(c, 26) >> 2); + Int64 c11 = (load_4(c, 28) >> 7); + Int64 s0; + Int64 s1; + Int64 s2; + Int64 s3; + Int64 s4; + Int64 s5; + Int64 s6; + Int64 s7; + Int64 s8; + Int64 s9; + Int64 s10; + Int64 s11; + Int64 s12; + Int64 s13; + Int64 s14; + Int64 s15; + Int64 s16; + Int64 s17; + Int64 s18; + Int64 s19; + Int64 s20; + Int64 s21; + Int64 s22; + Int64 s23; + Int64 carry0; + Int64 carry1; + Int64 carry2; + Int64 carry3; + Int64 carry4; + Int64 carry5; + Int64 carry6; + Int64 carry7; + Int64 carry8; + Int64 carry9; + Int64 carry10; + Int64 carry11; + Int64 carry12; + Int64 carry13; + Int64 carry14; + Int64 carry15; + Int64 carry16; + Int64 carry17; + Int64 carry18; + Int64 carry19; + Int64 carry20; + Int64 carry21; + Int64 carry22; + + s0 = c0 + a0 * b0; + s1 = c1 + a0 * b1 + a1 * b0; + s2 = c2 + a0 * b2 + a1 * b1 + a2 * b0; + s3 = c3 + a0 * b3 + a1 * b2 + a2 * b1 + a3 * b0; + s4 = c4 + a0 * b4 + a1 * b3 + a2 * b2 + a3 * b1 + a4 * b0; + s5 = c5 + a0 * b5 + a1 * b4 + a2 * b3 + a3 * b2 + a4 * b1 + a5 * b0; + s6 = c6 + a0 * b6 + a1 * b5 + a2 * b4 + a3 * b3 + a4 * b2 + a5 * b1 + a6 * b0; + s7 = c7 + a0 * b7 + a1 * b6 + a2 * b5 + a3 * b4 + a4 * b3 + a5 * b2 + a6 * b1 + a7 * b0; + s8 = c8 + a0 * b8 + a1 * b7 + a2 * b6 + a3 * b5 + a4 * b4 + a5 * b3 + a6 * b2 + a7 * b1 + a8 * b0; + s9 = c9 + a0 * b9 + a1 * b8 + a2 * b7 + a3 * b6 + a4 * b5 + a5 * b4 + a6 * b3 + a7 * b2 + a8 * b1 + a9 * b0; + s10 = c10 + a0 * b10 + a1 * b9 + a2 * b8 + a3 * b7 + a4 * b6 + a5 * b5 + a6 * b4 + a7 * b3 + a8 * b2 + a9 * b1 + a10 * b0; + s11 = c11 + a0 * b11 + a1 * b10 + a2 * b9 + a3 * b8 + a4 * b7 + a5 * b6 + a6 * b5 + a7 * b4 + a8 * b3 + a9 * b2 + a10 * b1 + a11 * b0; + s12 = a1 * b11 + a2 * b10 + a3 * b9 + a4 * b8 + a5 * b7 + a6 * b6 + a7 * b5 + a8 * b4 + a9 * b3 + a10 * b2 + a11 * b1; + s13 = a2 * b11 + a3 * b10 + a4 * b9 + a5 * b8 + a6 * b7 + a7 * b6 + a8 * b5 + a9 * b4 + a10 * b3 + a11 * b2; + s14 = a3 * b11 + a4 * b10 + a5 * b9 + a6 * b8 + a7 * b7 + a8 * b6 + a9 * b5 + a10 * b4 + a11 * b3; + s15 = a4 * b11 + a5 * b10 + a6 * b9 + a7 * b8 + a8 * b7 + a9 * b6 + a10 * b5 + a11 * b4; + s16 = a5 * b11 + a6 * b10 + a7 * b9 + a8 * b8 + a9 * b7 + a10 * b6 + a11 * b5; + s17 = a6 * b11 + a7 * b10 + a8 * b9 + a9 * b8 + a10 * b7 + a11 * b6; + s18 = a7 * b11 + a8 * b10 + a9 * b9 + a10 * b8 + a11 * b7; + s19 = a8 * b11 + a9 * b10 + a10 * b9 + a11 * b8; + s20 = a9 * b11 + a10 * b10 + a11 * b9; + s21 = a10 * b11 + a11 * b10; + s22 = a11 * b11; + s23 = 0; + + carry0 = (s0 + (1 << 20)) >> 21; s1 += carry0; s0 -= carry0 << 21; + carry2 = (s2 + (1 << 20)) >> 21; s3 += carry2; s2 -= carry2 << 21; + carry4 = (s4 + (1 << 20)) >> 21; s5 += carry4; s4 -= carry4 << 21; + carry6 = (s6 + (1 << 20)) >> 21; s7 += carry6; s6 -= carry6 << 21; + carry8 = (s8 + (1 << 20)) >> 21; s9 += carry8; s8 -= carry8 << 21; + carry10 = (s10 + (1 << 20)) >> 21; s11 += carry10; s10 -= carry10 << 21; + carry12 = (s12 + (1 << 20)) >> 21; s13 += carry12; s12 -= carry12 << 21; + carry14 = (s14 + (1 << 20)) >> 21; s15 += carry14; s14 -= carry14 << 21; + carry16 = (s16 + (1 << 20)) >> 21; s17 += carry16; s16 -= carry16 << 21; + carry18 = (s18 + (1 << 20)) >> 21; s19 += carry18; s18 -= carry18 << 21; + carry20 = (s20 + (1 << 20)) >> 21; s21 += carry20; s20 -= carry20 << 21; + carry22 = (s22 + (1 << 20)) >> 21; s23 += carry22; s22 -= carry22 << 21; + + carry1 = (s1 + (1 << 20)) >> 21; s2 += carry1; s1 -= carry1 << 21; + carry3 = (s3 + (1 << 20)) >> 21; s4 += carry3; s3 -= carry3 << 21; + carry5 = (s5 + (1 << 20)) >> 21; s6 += carry5; s5 -= carry5 << 21; + carry7 = (s7 + (1 << 20)) >> 21; s8 += carry7; s7 -= carry7 << 21; + carry9 = (s9 + (1 << 20)) >> 21; s10 += carry9; s9 -= carry9 << 21; + carry11 = (s11 + (1 << 20)) >> 21; s12 += carry11; s11 -= carry11 << 21; + carry13 = (s13 + (1 << 20)) >> 21; s14 += carry13; s13 -= carry13 << 21; + carry15 = (s15 + (1 << 20)) >> 21; s16 += carry15; s15 -= carry15 << 21; + carry17 = (s17 + (1 << 20)) >> 21; s18 += carry17; s17 -= carry17 << 21; + carry19 = (s19 + (1 << 20)) >> 21; s20 += carry19; s19 -= carry19 << 21; + carry21 = (s21 + (1 << 20)) >> 21; s22 += carry21; s21 -= carry21 << 21; + + s11 += s23 * 666643; + s12 += s23 * 470296; + s13 += s23 * 654183; + s14 -= s23 * 997805; + s15 += s23 * 136657; + s16 -= s23 * 683901; + s23 = 0; + + s10 += s22 * 666643; + s11 += s22 * 470296; + s12 += s22 * 654183; + s13 -= s22 * 997805; + s14 += s22 * 136657; + s15 -= s22 * 683901; + s22 = 0; + + s9 += s21 * 666643; + s10 += s21 * 470296; + s11 += s21 * 654183; + s12 -= s21 * 997805; + s13 += s21 * 136657; + s14 -= s21 * 683901; + s21 = 0; + + s8 += s20 * 666643; + s9 += s20 * 470296; + s10 += s20 * 654183; + s11 -= s20 * 997805; + s12 += s20 * 136657; + s13 -= s20 * 683901; + s20 = 0; + + s7 += s19 * 666643; + s8 += s19 * 470296; + s9 += s19 * 654183; + s10 -= s19 * 997805; + s11 += s19 * 136657; + s12 -= s19 * 683901; + s19 = 0; + + s6 += s18 * 666643; + s7 += s18 * 470296; + s8 += s18 * 654183; + s9 -= s18 * 997805; + s10 += s18 * 136657; + s11 -= s18 * 683901; + s18 = 0; + + carry6 = (s6 + (1 << 20)) >> 21; s7 += carry6; s6 -= carry6 << 21; + carry8 = (s8 + (1 << 20)) >> 21; s9 += carry8; s8 -= carry8 << 21; + carry10 = (s10 + (1 << 20)) >> 21; s11 += carry10; s10 -= carry10 << 21; + carry12 = (s12 + (1 << 20)) >> 21; s13 += carry12; s12 -= carry12 << 21; + carry14 = (s14 + (1 << 20)) >> 21; s15 += carry14; s14 -= carry14 << 21; + carry16 = (s16 + (1 << 20)) >> 21; s17 += carry16; s16 -= carry16 << 21; + + carry7 = (s7 + (1 << 20)) >> 21; s8 += carry7; s7 -= carry7 << 21; + carry9 = (s9 + (1 << 20)) >> 21; s10 += carry9; s9 -= carry9 << 21; + carry11 = (s11 + (1 << 20)) >> 21; s12 += carry11; s11 -= carry11 << 21; + carry13 = (s13 + (1 << 20)) >> 21; s14 += carry13; s13 -= carry13 << 21; + carry15 = (s15 + (1 << 20)) >> 21; s16 += carry15; s15 -= carry15 << 21; + + s5 += s17 * 666643; + s6 += s17 * 470296; + s7 += s17 * 654183; + s8 -= s17 * 997805; + s9 += s17 * 136657; + s10 -= s17 * 683901; + s17 = 0; + + s4 += s16 * 666643; + s5 += s16 * 470296; + s6 += s16 * 654183; + s7 -= s16 * 997805; + s8 += s16 * 136657; + s9 -= s16 * 683901; + s16 = 0; + + s3 += s15 * 666643; + s4 += s15 * 470296; + s5 += s15 * 654183; + s6 -= s15 * 997805; + s7 += s15 * 136657; + s8 -= s15 * 683901; + s15 = 0; + + s2 += s14 * 666643; + s3 += s14 * 470296; + s4 += s14 * 654183; + s5 -= s14 * 997805; + s6 += s14 * 136657; + s7 -= s14 * 683901; + s14 = 0; + + s1 += s13 * 666643; + s2 += s13 * 470296; + s3 += s13 * 654183; + s4 -= s13 * 997805; + s5 += s13 * 136657; + s6 -= s13 * 683901; + s13 = 0; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = (s0 + (1 << 20)) >> 21; s1 += carry0; s0 -= carry0 << 21; + carry2 = (s2 + (1 << 20)) >> 21; s3 += carry2; s2 -= carry2 << 21; + carry4 = (s4 + (1 << 20)) >> 21; s5 += carry4; s4 -= carry4 << 21; + carry6 = (s6 + (1 << 20)) >> 21; s7 += carry6; s6 -= carry6 << 21; + carry8 = (s8 + (1 << 20)) >> 21; s9 += carry8; s8 -= carry8 << 21; + carry10 = (s10 + (1 << 20)) >> 21; s11 += carry10; s10 -= carry10 << 21; + + carry1 = (s1 + (1 << 20)) >> 21; s2 += carry1; s1 -= carry1 << 21; + carry3 = (s3 + (1 << 20)) >> 21; s4 += carry3; s3 -= carry3 << 21; + carry5 = (s5 + (1 << 20)) >> 21; s6 += carry5; s5 -= carry5 << 21; + carry7 = (s7 + (1 << 20)) >> 21; s8 += carry7; s7 -= carry7 << 21; + carry9 = (s9 + (1 << 20)) >> 21; s10 += carry9; s9 -= carry9 << 21; + carry11 = (s11 + (1 << 20)) >> 21; s12 += carry11; s11 -= carry11 << 21; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; + carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; + carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; + carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; + carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; + carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21; + carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21; + carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21; + carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21; + carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21; + carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21; + carry11 = s11 >> 21; s12 += carry11; s11 -= carry11 << 21; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; + carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; + carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; + carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; + carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; + carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21; + carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21; + carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21; + carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21; + carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21; + carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21; + + unchecked + { + s[0] = (byte)(s0 >> 0); + s[1] = (byte)(s0 >> 8); + s[2] = (byte)((s0 >> 16) | (s1 << 5)); + s[3] = (byte)(s1 >> 3); + s[4] = (byte)(s1 >> 11); + s[5] = (byte)((s1 >> 19) | (s2 << 2)); + s[6] = (byte)(s2 >> 6); + s[7] = (byte)((s2 >> 14) | (s3 << 7)); + s[8] = (byte)(s3 >> 1); + s[9] = (byte)(s3 >> 9); + s[10] = (byte)((s3 >> 17) | (s4 << 4)); + s[11] = (byte)(s4 >> 4); + s[12] = (byte)(s4 >> 12); + s[13] = (byte)((s4 >> 20) | (s5 << 1)); + s[14] = (byte)(s5 >> 7); + s[15] = (byte)((s5 >> 15) | (s6 << 6)); + s[16] = (byte)(s6 >> 2); + s[17] = (byte)(s6 >> 10); + s[18] = (byte)((s6 >> 18) | (s7 << 3)); + s[19] = (byte)(s7 >> 5); + s[20] = (byte)(s7 >> 13); + s[21] = (byte)(s8 >> 0); + s[22] = (byte)(s8 >> 8); + s[23] = (byte)((s8 >> 16) | (s9 << 5)); + s[24] = (byte)(s9 >> 3); + s[25] = (byte)(s9 >> 11); + s[26] = (byte)((s9 >> 19) | (s10 << 2)); + s[27] = (byte)(s10 >> 6); + s[28] = (byte)((s10 >> 14) | (s11 << 7)); + s[29] = (byte)(s11 >> 1); + s[30] = (byte)(s11 >> 9); + s[31] = (byte)(s11 >> 17); + } + } + } +} \ No newline at end of file diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/sc_mul_add.cs.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/sc_mul_add.cs.meta new file mode 100644 index 0000000..ca1ecf3 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/sc_mul_add.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6e055be6a3e5b7a48a706fad61f0dcc8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/sc_reduce.cs b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/sc_reduce.cs new file mode 100644 index 0000000..493bf5a --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/sc_reduce.cs @@ -0,0 +1,263 @@ +using System; + +namespace Chaos.NaCl.Internal.Ed25519Ref10 +{ + internal static partial class ScalarOperations + { + /* + Input: + s[0]+256*s[1]+...+256^63*s[63] = s + + Output: + s[0]+256*s[1]+...+256^31*s[31] = s mod l + where l = 2^252 + 27742317777372353535851937790883648493. + Overwrites s in place. + */ + + public static void sc_reduce(byte[] s) + { + Int64 s0 = 2097151 & load_3(s, 0); + Int64 s1 = 2097151 & (load_4(s, 2) >> 5); + Int64 s2 = 2097151 & (load_3(s, 5) >> 2); + Int64 s3 = 2097151 & (load_4(s, 7) >> 7); + Int64 s4 = 2097151 & (load_4(s, 10) >> 4); + Int64 s5 = 2097151 & (load_3(s, 13) >> 1); + Int64 s6 = 2097151 & (load_4(s, 15) >> 6); + Int64 s7 = 2097151 & (load_3(s, 18) >> 3); + Int64 s8 = 2097151 & load_3(s, 21); + Int64 s9 = 2097151 & (load_4(s, 23) >> 5); + Int64 s10 = 2097151 & (load_3(s, 26) >> 2); + Int64 s11 = 2097151 & (load_4(s, 28) >> 7); + Int64 s12 = 2097151 & (load_4(s, 31) >> 4); + Int64 s13 = 2097151 & (load_3(s, 34) >> 1); + Int64 s14 = 2097151 & (load_4(s, 36) >> 6); + Int64 s15 = 2097151 & (load_3(s, 39) >> 3); + Int64 s16 = 2097151 & load_3(s, 42); + Int64 s17 = 2097151 & (load_4(s, 44) >> 5); + Int64 s18 = 2097151 & (load_3(s, 47) >> 2); + Int64 s19 = 2097151 & (load_4(s, 49) >> 7); + Int64 s20 = 2097151 & (load_4(s, 52) >> 4); + Int64 s21 = 2097151 & (load_3(s, 55) >> 1); + Int64 s22 = 2097151 & (load_4(s, 57) >> 6); + Int64 s23 = (load_4(s, 60) >> 3); + Int64 carry0; + Int64 carry1; + Int64 carry2; + Int64 carry3; + Int64 carry4; + Int64 carry5; + Int64 carry6; + Int64 carry7; + Int64 carry8; + Int64 carry9; + Int64 carry10; + Int64 carry11; + Int64 carry12; + Int64 carry13; + Int64 carry14; + Int64 carry15; + Int64 carry16; + + s11 += s23 * 666643; + s12 += s23 * 470296; + s13 += s23 * 654183; + s14 -= s23 * 997805; + s15 += s23 * 136657; + s16 -= s23 * 683901; + s23 = 0; + + s10 += s22 * 666643; + s11 += s22 * 470296; + s12 += s22 * 654183; + s13 -= s22 * 997805; + s14 += s22 * 136657; + s15 -= s22 * 683901; + s22 = 0; + + s9 += s21 * 666643; + s10 += s21 * 470296; + s11 += s21 * 654183; + s12 -= s21 * 997805; + s13 += s21 * 136657; + s14 -= s21 * 683901; + s21 = 0; + + s8 += s20 * 666643; + s9 += s20 * 470296; + s10 += s20 * 654183; + s11 -= s20 * 997805; + s12 += s20 * 136657; + s13 -= s20 * 683901; + s20 = 0; + + s7 += s19 * 666643; + s8 += s19 * 470296; + s9 += s19 * 654183; + s10 -= s19 * 997805; + s11 += s19 * 136657; + s12 -= s19 * 683901; + s19 = 0; + + s6 += s18 * 666643; + s7 += s18 * 470296; + s8 += s18 * 654183; + s9 -= s18 * 997805; + s10 += s18 * 136657; + s11 -= s18 * 683901; + s18 = 0; + + carry6 = (s6 + (1 << 20)) >> 21; s7 += carry6; s6 -= carry6 << 21; + carry8 = (s8 + (1 << 20)) >> 21; s9 += carry8; s8 -= carry8 << 21; + carry10 = (s10 + (1 << 20)) >> 21; s11 += carry10; s10 -= carry10 << 21; + carry12 = (s12 + (1 << 20)) >> 21; s13 += carry12; s12 -= carry12 << 21; + carry14 = (s14 + (1 << 20)) >> 21; s15 += carry14; s14 -= carry14 << 21; + carry16 = (s16 + (1 << 20)) >> 21; s17 += carry16; s16 -= carry16 << 21; + + carry7 = (s7 + (1 << 20)) >> 21; s8 += carry7; s7 -= carry7 << 21; + carry9 = (s9 + (1 << 20)) >> 21; s10 += carry9; s9 -= carry9 << 21; + carry11 = (s11 + (1 << 20)) >> 21; s12 += carry11; s11 -= carry11 << 21; + carry13 = (s13 + (1 << 20)) >> 21; s14 += carry13; s13 -= carry13 << 21; + carry15 = (s15 + (1 << 20)) >> 21; s16 += carry15; s15 -= carry15 << 21; + + s5 += s17 * 666643; + s6 += s17 * 470296; + s7 += s17 * 654183; + s8 -= s17 * 997805; + s9 += s17 * 136657; + s10 -= s17 * 683901; + s17 = 0; + + s4 += s16 * 666643; + s5 += s16 * 470296; + s6 += s16 * 654183; + s7 -= s16 * 997805; + s8 += s16 * 136657; + s9 -= s16 * 683901; + s16 = 0; + + s3 += s15 * 666643; + s4 += s15 * 470296; + s5 += s15 * 654183; + s6 -= s15 * 997805; + s7 += s15 * 136657; + s8 -= s15 * 683901; + s15 = 0; + + s2 += s14 * 666643; + s3 += s14 * 470296; + s4 += s14 * 654183; + s5 -= s14 * 997805; + s6 += s14 * 136657; + s7 -= s14 * 683901; + s14 = 0; + + s1 += s13 * 666643; + s2 += s13 * 470296; + s3 += s13 * 654183; + s4 -= s13 * 997805; + s5 += s13 * 136657; + s6 -= s13 * 683901; + s13 = 0; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = (s0 + (1 << 20)) >> 21; s1 += carry0; s0 -= carry0 << 21; + carry2 = (s2 + (1 << 20)) >> 21; s3 += carry2; s2 -= carry2 << 21; + carry4 = (s4 + (1 << 20)) >> 21; s5 += carry4; s4 -= carry4 << 21; + carry6 = (s6 + (1 << 20)) >> 21; s7 += carry6; s6 -= carry6 << 21; + carry8 = (s8 + (1 << 20)) >> 21; s9 += carry8; s8 -= carry8 << 21; + carry10 = (s10 + (1 << 20)) >> 21; s11 += carry10; s10 -= carry10 << 21; + + carry1 = (s1 + (1 << 20)) >> 21; s2 += carry1; s1 -= carry1 << 21; + carry3 = (s3 + (1 << 20)) >> 21; s4 += carry3; s3 -= carry3 << 21; + carry5 = (s5 + (1 << 20)) >> 21; s6 += carry5; s5 -= carry5 << 21; + carry7 = (s7 + (1 << 20)) >> 21; s8 += carry7; s7 -= carry7 << 21; + carry9 = (s9 + (1 << 20)) >> 21; s10 += carry9; s9 -= carry9 << 21; + carry11 = (s11 + (1 << 20)) >> 21; s12 += carry11; s11 -= carry11 << 21; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; + carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; + carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; + carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; + carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; + carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21; + carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21; + carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21; + carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21; + carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21; + carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21; + carry11 = s11 >> 21; s12 += carry11; s11 -= carry11 << 21; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; + carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; + carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; + carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; + carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; + carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21; + carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21; + carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21; + carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21; + carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21; + carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21; + + unchecked + { + s[0] = (byte)(s0 >> 0); + s[1] = (byte)(s0 >> 8); + s[2] = (byte)((s0 >> 16) | (s1 << 5)); + s[3] = (byte)(s1 >> 3); + s[4] = (byte)(s1 >> 11); + s[5] = (byte)((s1 >> 19) | (s2 << 2)); + s[6] = (byte)(s2 >> 6); + s[7] = (byte)((s2 >> 14) | (s3 << 7)); + s[8] = (byte)(s3 >> 1); + s[9] = (byte)(s3 >> 9); + s[10] = (byte)((s3 >> 17) | (s4 << 4)); + s[11] = (byte)(s4 >> 4); + s[12] = (byte)(s4 >> 12); + s[13] = (byte)((s4 >> 20) | (s5 << 1)); + s[14] = (byte)(s5 >> 7); + s[15] = (byte)((s5 >> 15) | (s6 << 6)); + s[16] = (byte)(s6 >> 2); + s[17] = (byte)(s6 >> 10); + s[18] = (byte)((s6 >> 18) | (s7 << 3)); + s[19] = (byte)(s7 >> 5); + s[20] = (byte)(s7 >> 13); + s[21] = (byte)(s8 >> 0); + s[22] = (byte)(s8 >> 8); + s[23] = (byte)((s8 >> 16) | (s9 << 5)); + s[24] = (byte)(s9 >> 3); + s[25] = (byte)(s9 >> 11); + s[26] = (byte)((s9 >> 19) | (s10 << 2)); + s[27] = (byte)(s10 >> 6); + s[28] = (byte)((s10 >> 14) | (s11 << 7)); + s[29] = (byte)(s11 >> 1); + s[30] = (byte)(s11 >> 9); + s[31] = (byte)(s11 >> 17); + } + } + + } +} \ No newline at end of file diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/sc_reduce.cs.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/sc_reduce.cs.meta new file mode 100644 index 0000000..71fc25a --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/sc_reduce.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dd1832023ee22984ab2602c38a970bbe +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/scalarmult.cs b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/scalarmult.cs new file mode 100644 index 0000000..b0b1247 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Ed25519Ref10/scalarmult.cs @@ -0,0 +1,205 @@ +using System; + +namespace Chaos.NaCl.Internal.Ed25519Ref10 +{ + public static class MontgomeryOperations + { + public static void scalarmult( + byte[] q, int qoffset, + byte[] n, int noffset, + byte[] p, int poffset) + { + FieldElement p0; + FieldElement q0; + FieldOperations.fe_frombytes2(out p0, p, poffset); + scalarmult(out q0, n, noffset, ref p0); + FieldOperations.fe_tobytes(q, qoffset, ref q0); + } + + internal static void scalarmult( + out FieldElement q, + byte[] n, int noffset, + ref FieldElement p) + { + byte[] e = new byte[32];//ToDo: remove allocation + UInt32 i; + FieldElement x1; + FieldElement x2; + FieldElement z2; + FieldElement x3; + FieldElement z3; + FieldElement tmp0; + FieldElement tmp1; + int pos; + UInt32 swap; + UInt32 b; + + for (i = 0; i < 32; ++i) + e[i] = n[noffset + i]; + ScalarOperations.sc_clamp(e, 0); + x1 = p; + FieldOperations.fe_1(out x2); + FieldOperations.fe_0(out z2); + x3 = x1; + FieldOperations.fe_1(out z3); + + swap = 0; + for (pos = 254; pos >= 0; --pos) + { + b = (uint)(e[pos / 8] >> (pos & 7)); + b &= 1; + swap ^= b; + FieldOperations.fe_cswap(ref x2, ref x3, swap); + FieldOperations.fe_cswap(ref z2, ref z3, swap); + swap = b; + /* qhasm: fe X2 */ + + /* qhasm: fe Z2 */ + + /* qhasm: fe X3 */ + + /* qhasm: fe Z3 */ + + /* qhasm: fe X4 */ + + /* qhasm: fe Z4 */ + + /* qhasm: fe X5 */ + + /* qhasm: fe Z5 */ + + /* qhasm: fe A */ + + /* qhasm: fe B */ + + /* qhasm: fe C */ + + /* qhasm: fe D */ + + /* qhasm: fe E */ + + /* qhasm: fe AA */ + + /* qhasm: fe BB */ + + /* qhasm: fe DA */ + + /* qhasm: fe CB */ + + /* qhasm: fe t0 */ + + /* qhasm: fe t1 */ + + /* qhasm: fe t2 */ + + /* qhasm: fe t3 */ + + /* qhasm: fe t4 */ + + /* qhasm: enter ladder */ + + /* qhasm: D = X3-Z3 */ + /* asm 1: fe_sub(>D=fe#5,D=tmp0,B=fe#6,B=tmp1,A=fe#1,A=x2,C=fe#2,C=z2,DA=fe#4,DA=z3,CB=fe#2,CB=z2,BB=fe#5,BB=tmp0,AA=fe#6,AA=tmp1,t0=fe#3,t0=x3,t1=fe#2,t1=z2,X4=fe#1,X4=x2,E=fe#6,E=tmp1,t2=fe#2,t2=z2,t3=fe#4,t3=z3,X5=fe#3,X5=x3,t4=fe#5,t4=tmp0,Z5=fe#4,x1,Z5=z3,x1,Z4=fe#2,Z4=z2, key) + { + UInt32 t0, t1, t2, t3; + UInt32 h0, h1, h2, h3, h4; + UInt32 r0, r1, r2, r3, r4; + UInt32 s1, s2, s3, s4; + UInt32 b, nb; + int j; + UInt64 tt0, tt1, tt2, tt3, tt4; + UInt64 f0, f1, f2, f3; + UInt32 g0, g1, g2, g3, g4; + UInt64 c; + + /* clamp key */ + t0 = key.x0; + t1 = key.x1; + t2 = key.x2; + t3 = key.x3; + + /* precompute multipliers */ + r0 = t0 & 0x3ffffff; t0 >>= 26; t0 |= t1 << 6; + r1 = t0 & 0x3ffff03; t1 >>= 20; t1 |= t2 << 12; + r2 = t1 & 0x3ffc0ff; t2 >>= 14; t2 |= t3 << 18; + r3 = t2 & 0x3f03fff; t3 >>= 8; + r4 = t3 & 0x00fffff; + + s1 = r1 * 5; + s2 = r2 * 5; + s3 = r3 * 5; + s4 = r4 * 5; + + /* init state */ + h0 = 0; + h1 = 0; + h2 = 0; + h3 = 0; + h4 = 0; + + /* full blocks */ + if (mLength < 16) + goto poly1305_donna_atmost15bytes; + + poly1305_donna_16bytes: + mStart += 16; + mLength -= 16; + + t0 = ByteIntegerConverter.LoadLittleEndian32(m, mStart - 16); + t1 = ByteIntegerConverter.LoadLittleEndian32(m, mStart - 12); + t2 = ByteIntegerConverter.LoadLittleEndian32(m, mStart - 8); + t3 = ByteIntegerConverter.LoadLittleEndian32(m, mStart - 4); + + //todo: looks like these can be simplified a bit + h0 += t0 & 0x3ffffff; + h1 += (uint)(((((UInt64)t1 << 32) | t0) >> 26) & 0x3ffffff); + h2 += (uint)(((((UInt64)t2 << 32) | t1) >> 20) & 0x3ffffff); + h3 += (uint)(((((UInt64)t3 << 32) | t2) >> 14) & 0x3ffffff); + h4 += (t3 >> 8) | (1 << 24); + + + poly1305_donna_mul: + tt0 = (ulong)h0 * r0 + (ulong)h1 * s4 + (ulong)h2 * s3 + (ulong)h3 * s2 + (ulong)h4 * s1; + tt1 = (ulong)h0 * r1 + (ulong)h1 * r0 + (ulong)h2 * s4 + (ulong)h3 * s3 + (ulong)h4 * s2; + tt2 = (ulong)h0 * r2 + (ulong)h1 * r1 + (ulong)h2 * r0 + (ulong)h3 * s4 + (ulong)h4 * s3; + tt3 = (ulong)h0 * r3 + (ulong)h1 * r2 + (ulong)h2 * r1 + (ulong)h3 * r0 + (ulong)h4 * s4; + tt4 = (ulong)h0 * r4 + (ulong)h1 * r3 + (ulong)h2 * r2 + (ulong)h3 * r1 + (ulong)h4 * r0; + + unchecked + { + h0 = (UInt32)tt0 & 0x3ffffff; c = (tt0 >> 26); + tt1 += c; h1 = (UInt32)tt1 & 0x3ffffff; b = (UInt32)(tt1 >> 26); + tt2 += b; h2 = (UInt32)tt2 & 0x3ffffff; b = (UInt32)(tt2 >> 26); + tt3 += b; h3 = (UInt32)tt3 & 0x3ffffff; b = (UInt32)(tt3 >> 26); + tt4 += b; h4 = (UInt32)tt4 & 0x3ffffff; b = (UInt32)(tt4 >> 26); + } + h0 += b * 5; + + if (mLength >= 16) + goto poly1305_donna_16bytes; + + /* final bytes */ + poly1305_donna_atmost15bytes: + if (mLength == 0) + goto poly1305_donna_finish; + + byte[] mp = new byte[16];//todo remove allocation + + for (j = 0; j < mLength; j++) + mp[j] = m[mStart + j]; + mp[j++] = 1; + for (; j < 16; j++) + mp[j] = 0; + mLength = 0; + + t0 = ByteIntegerConverter.LoadLittleEndian32(mp, 0); + t1 = ByteIntegerConverter.LoadLittleEndian32(mp, 4); + t2 = ByteIntegerConverter.LoadLittleEndian32(mp, 8); + t3 = ByteIntegerConverter.LoadLittleEndian32(mp, 12); + CryptoBytes.Wipe(mp); + + h0 += t0 & 0x3ffffff; + h1 += (uint)(((((UInt64)t1 << 32) | t0) >> 26) & 0x3ffffff); + h2 += (uint)(((((UInt64)t2 << 32) | t1) >> 20) & 0x3ffffff); + h3 += (uint)(((((UInt64)t3 << 32) | t2) >> 14) & 0x3ffffff); + h4 += t3 >> 8; + + goto poly1305_donna_mul; + + poly1305_donna_finish: + b = h0 >> 26; h0 = h0 & 0x3ffffff; + h1 += b; b = h1 >> 26; h1 = h1 & 0x3ffffff; + h2 += b; b = h2 >> 26; h2 = h2 & 0x3ffffff; + h3 += b; b = h3 >> 26; h3 = h3 & 0x3ffffff; + h4 += b; b = h4 >> 26; h4 = h4 & 0x3ffffff; + h0 += b * 5; + + g0 = h0 + 5; b = g0 >> 26; g0 &= 0x3ffffff; + g1 = h1 + b; b = g1 >> 26; g1 &= 0x3ffffff; + g2 = h2 + b; b = g2 >> 26; g2 &= 0x3ffffff; + g3 = h3 + b; b = g3 >> 26; g3 &= 0x3ffffff; + g4 = unchecked(h4 + b - (1 << 26)); + + b = (g4 >> 31) - 1; + nb = ~b; + h0 = (h0 & nb) | (g0 & b); + h1 = (h1 & nb) | (g1 & b); + h2 = (h2 & nb) | (g2 & b); + h3 = (h3 & nb) | (g3 & b); + h4 = (h4 & nb) | (g4 & b); + + f0 = ((h0) | (h1 << 26)) + (UInt64)key.x4; + f1 = ((h1 >> 6) | (h2 << 20)) + (UInt64)key.x5; + f2 = ((h2 >> 12) | (h3 << 14)) + (UInt64)key.x6; + f3 = ((h3 >> 18) | (h4 << 8)) + (UInt64)key.x7; + + unchecked + { + ByteIntegerConverter.StoreLittleEndian32(output, outputOffset + 0, (uint)f0); f1 += (f0 >> 32); + ByteIntegerConverter.StoreLittleEndian32(output, outputOffset + 4, (uint)f1); f2 += (f1 >> 32); + ByteIntegerConverter.StoreLittleEndian32(output, outputOffset + 8, (uint)f2); f3 += (f2 >> 32); + ByteIntegerConverter.StoreLittleEndian32(output, outputOffset + 12, (uint)f3); + } + } + } +} diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Poly1305Donna.cs.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Poly1305Donna.cs.meta new file mode 100644 index 0000000..5ae9a07 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Poly1305Donna.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d25c39058627cec40a573dcbea134d5f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Salsa.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Salsa.meta new file mode 100644 index 0000000..2388086 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Salsa.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0f4e7aa84bdcdb043a618898ad82e54a +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Salsa/Salsa20.cs b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Salsa/Salsa20.cs new file mode 100644 index 0000000..4578f64 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Salsa/Salsa20.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; + +namespace Chaos.NaCl.Internal.Salsa +{ + internal class Salsa20 + { + public const uint SalsaConst0 = 0x61707865; + public const uint SalsaConst1 = 0x3320646e; + public const uint SalsaConst2 = 0x79622d32; + public const uint SalsaConst3 = 0x6b206574; + + public static void HSalsa20(byte[] output, int outputOffset, byte[] key, int keyOffset, byte[] nonce, int nonceOffset) + { + Array16 state; + state.x0 = SalsaConst0; + state.x1 = ByteIntegerConverter.LoadLittleEndian32(key, keyOffset + 0); + state.x2 = ByteIntegerConverter.LoadLittleEndian32(key, keyOffset + 4); + state.x3 = ByteIntegerConverter.LoadLittleEndian32(key, keyOffset + 8); + state.x4 = ByteIntegerConverter.LoadLittleEndian32(key, keyOffset + 12); + state.x5 = SalsaConst1; + state.x6 = ByteIntegerConverter.LoadLittleEndian32(nonce, nonceOffset + 0); + state.x7 = ByteIntegerConverter.LoadLittleEndian32(nonce, nonceOffset + 4); + state.x8 = ByteIntegerConverter.LoadLittleEndian32(nonce, nonceOffset + 8); + state.x9 = ByteIntegerConverter.LoadLittleEndian32(nonce, nonceOffset + 12); + state.x10 = SalsaConst2; + state.x11 = ByteIntegerConverter.LoadLittleEndian32(key, keyOffset + 16); + state.x12 = ByteIntegerConverter.LoadLittleEndian32(key, keyOffset + 20); + state.x13 = ByteIntegerConverter.LoadLittleEndian32(key, keyOffset + 24); + state.x14 = ByteIntegerConverter.LoadLittleEndian32(key, keyOffset + 28); + state.x15 = SalsaConst3; + + SalsaCore.HSalsa(out state, ref state, 20); + + ByteIntegerConverter.StoreLittleEndian32(output, outputOffset + 0, state.x0); + ByteIntegerConverter.StoreLittleEndian32(output, outputOffset + 4, state.x5); + ByteIntegerConverter.StoreLittleEndian32(output, outputOffset + 8, state.x10); + ByteIntegerConverter.StoreLittleEndian32(output, outputOffset + 12, state.x15); + ByteIntegerConverter.StoreLittleEndian32(output, outputOffset + 16, state.x6); + ByteIntegerConverter.StoreLittleEndian32(output, outputOffset + 20, state.x7); + ByteIntegerConverter.StoreLittleEndian32(output, outputOffset + 24, state.x8); + ByteIntegerConverter.StoreLittleEndian32(output, outputOffset + 28, state.x9); + } + } +} diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Salsa/Salsa20.cs.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Salsa/Salsa20.cs.meta new file mode 100644 index 0000000..8422ee2 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Salsa/Salsa20.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 05bdde9f7b4e5e5469cc01337257f862 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Salsa/SalsaCore.cs b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Salsa/SalsaCore.cs new file mode 100644 index 0000000..8e3ecad --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Salsa/SalsaCore.cs @@ -0,0 +1,263 @@ +using System; +using System.Collections.Generic; + +namespace Chaos.NaCl.Internal.Salsa +{ + internal static class SalsaCore + { + public static void HSalsa(out Array16 output, ref Array16 input, int rounds) + { + InternalAssert.Assert(rounds % 2 == 0, "Number of salsa rounds must be even"); + + int doubleRounds = rounds / 2; + + UInt32 x0 = input.x0; + UInt32 x1 = input.x1; + UInt32 x2 = input.x2; + UInt32 x3 = input.x3; + UInt32 x4 = input.x4; + UInt32 x5 = input.x5; + UInt32 x6 = input.x6; + UInt32 x7 = input.x7; + UInt32 x8 = input.x8; + UInt32 x9 = input.x9; + UInt32 x10 = input.x10; + UInt32 x11 = input.x11; + UInt32 x12 = input.x12; + UInt32 x13 = input.x13; + UInt32 x14 = input.x14; + UInt32 x15 = input.x15; + + unchecked + { + for (int i = 0; i < doubleRounds; i++) + { + UInt32 y; + + // row 0 + y = x0 + x12; + x4 ^= (y << 7) | (y >> (32 - 7)); + y = x4 + x0; + x8 ^= (y << 9) | (y >> (32 - 9)); + y = x8 + x4; + x12 ^= (y << 13) | (y >> (32 - 13)); + y = x12 + x8; + x0 ^= (y << 18) | (y >> (32 - 18)); + + // row 1 + y = x5 + x1; + x9 ^= (y << 7) | (y >> (32 - 7)); + y = x9 + x5; + x13 ^= (y << 9) | (y >> (32 - 9)); + y = x13 + x9; + x1 ^= (y << 13) | (y >> (32 - 13)); + y = x1 + x13; + x5 ^= (y << 18) | (y >> (32 - 18)); + + // row 2 + y = x10 + x6; + x14 ^= (y << 7) | (y >> (32 - 7)); + y = x14 + x10; + x2 ^= (y << 9) | (y >> (32 - 9)); + y = x2 + x14; + x6 ^= (y << 13) | (y >> (32 - 13)); + y = x6 + x2; + x10 ^= (y << 18) | (y >> (32 - 18)); + + // row 3 + y = x15 + x11; + x3 ^= (y << 7) | (y >> (32 - 7)); + y = x3 + x15; + x7 ^= (y << 9) | (y >> (32 - 9)); + y = x7 + x3; + x11 ^= (y << 13) | (y >> (32 - 13)); + y = x11 + x7; + x15 ^= (y << 18) | (y >> (32 - 18)); + + // column 0 + y = x0 + x3; + x1 ^= (y << 7) | (y >> (32 - 7)); + y = x1 + x0; + x2 ^= (y << 9) | (y >> (32 - 9)); + y = x2 + x1; + x3 ^= (y << 13) | (y >> (32 - 13)); + y = x3 + x2; + x0 ^= (y << 18) | (y >> (32 - 18)); + + // column 1 + y = x5 + x4; + x6 ^= (y << 7) | (y >> (32 - 7)); + y = x6 + x5; + x7 ^= (y << 9) | (y >> (32 - 9)); + y = x7 + x6; + x4 ^= (y << 13) | (y >> (32 - 13)); + y = x4 + x7; + x5 ^= (y << 18) | (y >> (32 - 18)); + + // column 2 + y = x10 + x9; + x11 ^= (y << 7) | (y >> (32 - 7)); + y = x11 + x10; + x8 ^= (y << 9) | (y >> (32 - 9)); + y = x8 + x11; + x9 ^= (y << 13) | (y >> (32 - 13)); + y = x9 + x8; + x10 ^= (y << 18) | (y >> (32 - 18)); + + // column 3 + y = x15 + x14; + x12 ^= (y << 7) | (y >> (32 - 7)); + y = x12 + x15; + x13 ^= (y << 9) | (y >> (32 - 9)); + y = x13 + x12; + x14 ^= (y << 13) | (y >> (32 - 13)); + y = x14 + x13; + x15 ^= (y << 18) | (y >> (32 - 18)); + } + } + + output.x0 = x0; + output.x1 = x1; + output.x2 = x2; + output.x3 = x3; + output.x4 = x4; + output.x5 = x5; + output.x6 = x6; + output.x7 = x7; + output.x8 = x8; + output.x9 = x9; + output.x10 = x10; + output.x11 = x11; + output.x12 = x12; + output.x13 = x13; + output.x14 = x14; + output.x15 = x15; + } + + public static void Salsa(out Array16 output, ref Array16 input, int rounds) + { + Array16 temp; + HSalsa(out temp, ref input, rounds); + unchecked + { + output.x0 = temp.x0 + input.x0; + output.x1 = temp.x1 + input.x1; + output.x2 = temp.x2 + input.x2; + output.x3 = temp.x3 + input.x3; + output.x4 = temp.x4 + input.x4; + output.x5 = temp.x5 + input.x5; + output.x6 = temp.x6 + input.x6; + output.x7 = temp.x7 + input.x7; + output.x8 = temp.x8 + input.x8; + output.x9 = temp.x9 + input.x9; + output.x10 = temp.x10 + input.x10; + output.x11 = temp.x11 + input.x11; + output.x12 = temp.x12 + input.x12; + output.x13 = temp.x13 + input.x13; + output.x14 = temp.x14 + input.x14; + output.x15 = temp.x15 + input.x15; + } + } + + /*public static void SalsaCore(int[] output, int outputOffset, int[] input, int inputOffset, int rounds) + { + if (rounds % 2 != 0) + throw new ArgumentException("rounds must be even"); + } + + +static void store_littleendian(unsigned char *x,uint32 u) +{ + x[0] = u; u >>= 8; + x[1] = u; u >>= 8; + x[2] = u; u >>= 8; + x[3] = u; +} + + public static void HSalsaCore(int[] output, int outputOffset, int[] input, int inputOffset, int rounds) + { + if (rounds % 2 != 0) + throw new ArgumentException("rounds must be even"); + static uint32 rotate(uint32 u,int c) +{ + return (u << c) | (u >> (32 - c)); +} + + + +int crypto_core( + unsigned char *out, + const unsigned char *in, + const unsigned char *k, + const unsigned char *c +) +{ + uint32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15; + int i; + + x0 = load_littleendian(c + 0); + x1 = load_littleendian(k + 0); + x2 = load_littleendian(k + 4); + x3 = load_littleendian(k + 8); + x4 = load_littleendian(k + 12); + x5 = load_littleendian(c + 4); + x6 = load_littleendian(in + 0); + x7 = load_littleendian(in + 4); + x8 = load_littleendian(in + 8); + x9 = load_littleendian(in + 12); + x10 = load_littleendian(c + 8); + x11 = load_littleendian(k + 16); + x12 = load_littleendian(k + 20); + x13 = load_littleendian(k + 24); + x14 = load_littleendian(k + 28); + x15 = load_littleendian(c + 12); + + for (i = ROUNDS;i > 0;i -= 2) { + x4 ^= rotate( x0+x12, 7); + x8 ^= rotate( x4+ x0, 9); + x12 ^= rotate( x8+ x4,13); + x0 ^= rotate(x12+ x8,18); + x9 ^= rotate( x5+ x1, 7); + x13 ^= rotate( x9+ x5, 9); + x1 ^= rotate(x13+ x9,13); + x5 ^= rotate( x1+x13,18); + x14 ^= rotate(x10+ x6, 7); + x2 ^= rotate(x14+x10, 9); + x6 ^= rotate( x2+x14,13); + x10 ^= rotate( x6+ x2,18); + x3 ^= rotate(x15+x11, 7); + x7 ^= rotate( x3+x15, 9); + x11 ^= rotate( x7+ x3,13); + x15 ^= rotate(x11+ x7,18); + x1 ^= rotate( x0+ x3, 7); + x2 ^= rotate( x1+ x0, 9); + x3 ^= rotate( x2+ x1,13); + x0 ^= rotate( x3+ x2,18); + x6 ^= rotate( x5+ x4, 7); + x7 ^= rotate( x6+ x5, 9); + x4 ^= rotate( x7+ x6,13); + x5 ^= rotate( x4+ x7,18); + x11 ^= rotate(x10+ x9, 7); + x8 ^= rotate(x11+x10, 9); + x9 ^= rotate( x8+x11,13); + x10 ^= rotate( x9+ x8,18); + x12 ^= rotate(x15+x14, 7); + x13 ^= rotate(x12+x15, 9); + x14 ^= rotate(x13+x12,13); + x15 ^= rotate(x14+x13,18); + } + + store_littleendian(out + 0,x0); + store_littleendian(out + 4,x5); + store_littleendian(out + 8,x10); + store_littleendian(out + 12,x15); + store_littleendian(out + 16,x6); + store_littleendian(out + 20,x7); + store_littleendian(out + 24,x8); + store_littleendian(out + 28,x9); + + return 0; +}*/ + + } +} diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Salsa/SalsaCore.cs.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Salsa/SalsaCore.cs.meta new file mode 100644 index 0000000..ac43274 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Salsa/SalsaCore.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8713610e35235494894934b54b691345 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Salsa/replace regex.txt b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Salsa/replace regex.txt new file mode 100644 index 0000000..f485689 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Salsa/replace regex.txt @@ -0,0 +1,2 @@ +x(\d+) ^= rotate\((.+), (\d+)\); +y = \2;\r\nx\1 ^= (y << \3) | (y >> (32 - \3)); \ No newline at end of file diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Salsa/replace regex.txt.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Salsa/replace regex.txt.meta new file mode 100644 index 0000000..67c9302 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Salsa/replace regex.txt.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: c1b31ef96ac53564a9891109cc9c8dd3 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Sha512Internal.cs b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Sha512Internal.cs new file mode 100644 index 0000000..37670d0 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Sha512Internal.cs @@ -0,0 +1,447 @@ +using System; +using System.Collections.Generic; + +namespace Chaos.NaCl.Internal +{ + internal static class Sha512Internal + { + private static readonly UInt64[] K = new UInt64[] + { + 0x428a2f98d728ae22,0x7137449123ef65cd,0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc, + 0x3956c25bf348b538,0x59f111f1b605d019,0x923f82a4af194f9b,0xab1c5ed5da6d8118, + 0xd807aa98a3030242,0x12835b0145706fbe,0x243185be4ee4b28c,0x550c7dc3d5ffb4e2, + 0x72be5d74f27b896f,0x80deb1fe3b1696b1,0x9bdc06a725c71235,0xc19bf174cf692694, + 0xe49b69c19ef14ad2,0xefbe4786384f25e3,0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65, + 0x2de92c6f592b0275,0x4a7484aa6ea6e483,0x5cb0a9dcbd41fbd4,0x76f988da831153b5, + 0x983e5152ee66dfab,0xa831c66d2db43210,0xb00327c898fb213f,0xbf597fc7beef0ee4, + 0xc6e00bf33da88fc2,0xd5a79147930aa725,0x06ca6351e003826f,0x142929670a0e6e70, + 0x27b70a8546d22ffc,0x2e1b21385c26c926,0x4d2c6dfc5ac42aed,0x53380d139d95b3df, + 0x650a73548baf63de,0x766a0abb3c77b2a8,0x81c2c92e47edaee6,0x92722c851482353b, + 0xa2bfe8a14cf10364,0xa81a664bbc423001,0xc24b8b70d0f89791,0xc76c51a30654be30, + 0xd192e819d6ef5218,0xd69906245565a910,0xf40e35855771202a,0x106aa07032bbd1b8, + 0x19a4c116b8d2d0c8,0x1e376c085141ab53,0x2748774cdf8eeb99,0x34b0bcb5e19b48a8, + 0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb,0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3, + 0x748f82ee5defb2fc,0x78a5636f43172f60,0x84c87814a1f0ab72,0x8cc702081a6439ec, + 0x90befffa23631e28,0xa4506cebde82bde9,0xbef9a3f7b2c67915,0xc67178f2e372532b, + 0xca273eceea26619c,0xd186b8c721c0c207,0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178, + 0x06f067aa72176fba,0x0a637dc5a2c898a6,0x113f9804bef90dae,0x1b710b35131c471b, + 0x28db77f523047d84,0x32caab7b40c72493,0x3c9ebe0a15c9bebc,0x431d67c49c100d4c, + 0x4cc5d4becb3e42b6,0x597f299cfc657e2a,0x5fcb6fab3ad6faec,0x6c44198c4a475817 + }; + + internal static void Sha512Init(out Array8 state) + { + state.x0 = 0x6a09e667f3bcc908; + state.x1 = 0xbb67ae8584caa73b; + state.x2 = 0x3c6ef372fe94f82b; + state.x3 = 0xa54ff53a5f1d36f1; + state.x4 = 0x510e527fade682d1; + state.x5 = 0x9b05688c2b3e6c1f; + state.x6 = 0x1f83d9abfb41bd6b; + state.x7 = 0x5be0cd19137e2179; + } + + internal static void Core(out Array8 outputState, ref Array8 inputState, ref Array16 input) + { + unchecked + { + UInt64 a = inputState.x0; + UInt64 b = inputState.x1; + UInt64 c = inputState.x2; + UInt64 d = inputState.x3; + UInt64 e = inputState.x4; + UInt64 f = inputState.x5; + UInt64 g = inputState.x6; + UInt64 h = inputState.x7; + + UInt64 w0 = input.x0; + UInt64 w1 = input.x1; + UInt64 w2 = input.x2; + UInt64 w3 = input.x3; + UInt64 w4 = input.x4; + UInt64 w5 = input.x5; + UInt64 w6 = input.x6; + UInt64 w7 = input.x7; + UInt64 w8 = input.x8; + UInt64 w9 = input.x9; + UInt64 w10 = input.x10; + UInt64 w11 = input.x11; + UInt64 w12 = input.x12; + UInt64 w13 = input.x13; + UInt64 w14 = input.x14; + UInt64 w15 = input.x15; + + int t = 0; + while (true) + { + ulong t1, t2; + + {//0 + t1 = h + + ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^ (e << (64 - 41))) + + //Sigma1(e) + ((e & f) ^ (~e & g)) + //Ch(e,f,g) + K[t] + w0; + t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^ (a << (64 - 39))) + + //Sigma0(a) + ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c) + h = g; + g = f; + f = e; + e = d + t1; + d = c; + c = b; + b = a; + a = t1 + t2; + t++; + } + {//1 + t1 = h + + ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^ (e << (64 - 41))) + + //Sigma1(e) + ((e & f) ^ (~e & g)) + //Ch(e,f,g) + K[t] + w1; + t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^ (a << (64 - 39))) + + //Sigma0(a) + ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c) + h = g; + g = f; + f = e; + e = d + t1; + d = c; + c = b; + b = a; + a = t1 + t2; + t++; + } + {//2 + t1 = h + + ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^ (e << (64 - 41))) + + //Sigma1(e) + ((e & f) ^ (~e & g)) + //Ch(e,f,g) + K[t] + w2; + t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^ (a << (64 - 39))) + + //Sigma0(a) + ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c) + h = g; + g = f; + f = e; + e = d + t1; + d = c; + c = b; + b = a; + a = t1 + t2; + t++; + } + {//3 + t1 = h + + ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^ (e << (64 - 41))) + + //Sigma1(e) + ((e & f) ^ (~e & g)) + //Ch(e,f,g) + K[t] + w3; + t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^ (a << (64 - 39))) + + //Sigma0(a) + ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c) + h = g; + g = f; + f = e; + e = d + t1; + d = c; + c = b; + b = a; + a = t1 + t2; + t++; + } + {//4 + t1 = h + + ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^ (e << (64 - 41))) + + //Sigma1(e) + ((e & f) ^ (~e & g)) + //Ch(e,f,g) + K[t] + w4; + t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^ (a << (64 - 39))) + + //Sigma0(a) + ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c) + h = g; + g = f; + f = e; + e = d + t1; + d = c; + c = b; + b = a; + a = t1 + t2; + t++; + } + {//5 + t1 = h + + ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^ (e << (64 - 41))) + + //Sigma1(e) + ((e & f) ^ (~e & g)) + //Ch(e,f,g) + K[t] + w5; + t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^ (a << (64 - 39))) + + //Sigma0(a) + ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c) + h = g; + g = f; + f = e; + e = d + t1; + d = c; + c = b; + b = a; + a = t1 + t2; + t++; + } + {//6 + t1 = h + + ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^ (e << (64 - 41))) + + //Sigma1(e) + ((e & f) ^ (~e & g)) + //Ch(e,f,g) + K[t] + w6; + t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^ (a << (64 - 39))) + + //Sigma0(a) + ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c) + h = g; + g = f; + f = e; + e = d + t1; + d = c; + c = b; + b = a; + a = t1 + t2; + t++; + } + {//7 + t1 = h + + ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^ (e << (64 - 41))) + + //Sigma1(e) + ((e & f) ^ (~e & g)) + //Ch(e,f,g) + K[t] + w7; + t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^ (a << (64 - 39))) + + //Sigma0(a) + ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c) + h = g; + g = f; + f = e; + e = d + t1; + d = c; + c = b; + b = a; + a = t1 + t2; + t++; + } + {//8 + t1 = h + + ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^ (e << (64 - 41))) + + //Sigma1(e) + ((e & f) ^ (~e & g)) + //Ch(e,f,g) + K[t] + w8; + t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^ (a << (64 - 39))) + + //Sigma0(a) + ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c) + h = g; + g = f; + f = e; + e = d + t1; + d = c; + c = b; + b = a; + a = t1 + t2; + t++; + } + {//9 + t1 = h + + ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^ (e << (64 - 41))) + + //Sigma1(e) + ((e & f) ^ (~e & g)) + //Ch(e,f,g) + K[t] + w9; + t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^ (a << (64 - 39))) + + //Sigma0(a) + ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c) + h = g; + g = f; + f = e; + e = d + t1; + d = c; + c = b; + b = a; + a = t1 + t2; + t++; + } + {//10 + t1 = h + + ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^ (e << (64 - 41))) + + //Sigma1(e) + ((e & f) ^ (~e & g)) + //Ch(e,f,g) + K[t] + w10; + t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^ (a << (64 - 39))) + + //Sigma0(a) + ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c) + h = g; + g = f; + f = e; + e = d + t1; + d = c; + c = b; + b = a; + a = t1 + t2; + t++; + } + {//11 + t1 = h + + ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^ (e << (64 - 41))) + + //Sigma1(e) + ((e & f) ^ (~e & g)) + //Ch(e,f,g) + K[t] + w11; + t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^ (a << (64 - 39))) + + //Sigma0(a) + ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c) + h = g; + g = f; + f = e; + e = d + t1; + d = c; + c = b; + b = a; + a = t1 + t2; + t++; + } + {//12 + t1 = h + + ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^ (e << (64 - 41))) + + //Sigma1(e) + ((e & f) ^ (~e & g)) + //Ch(e,f,g) + K[t] + w12; + t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^ (a << (64 - 39))) + + //Sigma0(a) + ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c) + h = g; + g = f; + f = e; + e = d + t1; + d = c; + c = b; + b = a; + a = t1 + t2; + t++; + } + {//13 + t1 = h + + ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^ (e << (64 - 41))) + + //Sigma1(e) + ((e & f) ^ (~e & g)) + //Ch(e,f,g) + K[t] + w13; + t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^ (a << (64 - 39))) + + //Sigma0(a) + ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c) + h = g; + g = f; + f = e; + e = d + t1; + d = c; + c = b; + b = a; + a = t1 + t2; + t++; + } + {//14 + t1 = h + + ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^ (e << (64 - 41))) + + //Sigma1(e) + ((e & f) ^ (~e & g)) + //Ch(e,f,g) + K[t] + w14; + t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^ (a << (64 - 39))) + + //Sigma0(a) + ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c) + h = g; + g = f; + f = e; + e = d + t1; + d = c; + c = b; + b = a; + a = t1 + t2; + t++; + } + {//15 + t1 = h + + ((e >> 14) ^ (e << (64 - 14)) ^ (e >> 18) ^ (e << (64 - 18)) ^ (e >> 41) ^ (e << (64 - 41))) + + //Sigma1(e) + ((e & f) ^ (~e & g)) + //Ch(e,f,g) + K[t] + w15; + t2 = ((a >> 28) ^ (a << (64 - 28)) ^ (a >> 34) ^ (a << (64 - 34)) ^ (a >> 39) ^ (a << (64 - 39))) + + //Sigma0(a) + ((a & b) ^ (a & c) ^ (b & c)); //Maj(a,b,c) + h = g; + g = f; + f = e; + e = d + t1; + d = c; + c = b; + b = a; + a = t1 + t2; + t++; + } + if (t == 80) + break; + + w0 += ((w14 >> 19) ^ (w14 << (64 - 19)) ^ (w14 >> 61) ^ (w14 << (64 - 61)) ^ (w14 >> 6)) + + w9 + + ((w1 >> 1) ^ (w1 << (64 - 1)) ^ (w1 >> 8) ^ (w1 << (64 - 8)) ^ (w1 >> 7)); + w1 += ((w15 >> 19) ^ (w15 << (64 - 19)) ^ (w15 >> 61) ^ (w15 << (64 - 61)) ^ (w15 >> 6)) + + w10 + + ((w2 >> 1) ^ (w2 << (64 - 1)) ^ (w2 >> 8) ^ (w2 << (64 - 8)) ^ (w2 >> 7)); + w2 += ((w0 >> 19) ^ (w0 << (64 - 19)) ^ (w0 >> 61) ^ (w0 << (64 - 61)) ^ (w0 >> 6)) + + w11 + + ((w3 >> 1) ^ (w3 << (64 - 1)) ^ (w3 >> 8) ^ (w3 << (64 - 8)) ^ (w3 >> 7)); + w3 += ((w1 >> 19) ^ (w1 << (64 - 19)) ^ (w1 >> 61) ^ (w1 << (64 - 61)) ^ (w1 >> 6)) + + w12 + + ((w4 >> 1) ^ (w4 << (64 - 1)) ^ (w4 >> 8) ^ (w4 << (64 - 8)) ^ (w4 >> 7)); + w4 += ((w2 >> 19) ^ (w2 << (64 - 19)) ^ (w2 >> 61) ^ (w2 << (64 - 61)) ^ (w2 >> 6)) + + w13 + + ((w5 >> 1) ^ (w5 << (64 - 1)) ^ (w5 >> 8) ^ (w5 << (64 - 8)) ^ (w5 >> 7)); + w5 += ((w3 >> 19) ^ (w3 << (64 - 19)) ^ (w3 >> 61) ^ (w3 << (64 - 61)) ^ (w3 >> 6)) + + w14 + + ((w6 >> 1) ^ (w6 << (64 - 1)) ^ (w6 >> 8) ^ (w6 << (64 - 8)) ^ (w6 >> 7)); + w6 += ((w4 >> 19) ^ (w4 << (64 - 19)) ^ (w4 >> 61) ^ (w4 << (64 - 61)) ^ (w4 >> 6)) + + w15 + + ((w7 >> 1) ^ (w7 << (64 - 1)) ^ (w7 >> 8) ^ (w7 << (64 - 8)) ^ (w7 >> 7)); + w7 += ((w5 >> 19) ^ (w5 << (64 - 19)) ^ (w5 >> 61) ^ (w5 << (64 - 61)) ^ (w5 >> 6)) + + w0 + + ((w8 >> 1) ^ (w8 << (64 - 1)) ^ (w8 >> 8) ^ (w8 << (64 - 8)) ^ (w8 >> 7)); + w8 += ((w6 >> 19) ^ (w6 << (64 - 19)) ^ (w6 >> 61) ^ (w6 << (64 - 61)) ^ (w6 >> 6)) + + w1 + + ((w9 >> 1) ^ (w9 << (64 - 1)) ^ (w9 >> 8) ^ (w9 << (64 - 8)) ^ (w9 >> 7)); + w9 += ((w7 >> 19) ^ (w7 << (64 - 19)) ^ (w7 >> 61) ^ (w7 << (64 - 61)) ^ (w7 >> 6)) + + w2 + + ((w10 >> 1) ^ (w10 << (64 - 1)) ^ (w10 >> 8) ^ (w10 << (64 - 8)) ^ (w10 >> 7)); + w10 += ((w8 >> 19) ^ (w8 << (64 - 19)) ^ (w8 >> 61) ^ (w8 << (64 - 61)) ^ (w8 >> 6)) + + w3 + + ((w11 >> 1) ^ (w11 << (64 - 1)) ^ (w11 >> 8) ^ (w11 << (64 - 8)) ^ (w11 >> 7)); + w11 += ((w9 >> 19) ^ (w9 << (64 - 19)) ^ (w9 >> 61) ^ (w9 << (64 - 61)) ^ (w9 >> 6)) + + w4 + + ((w12 >> 1) ^ (w12 << (64 - 1)) ^ (w12 >> 8) ^ (w12 << (64 - 8)) ^ (w12 >> 7)); + w12 += ((w10 >> 19) ^ (w10 << (64 - 19)) ^ (w10 >> 61) ^ (w10 << (64 - 61)) ^ (w10 >> 6)) + + w5 + + ((w13 >> 1) ^ (w13 << (64 - 1)) ^ (w13 >> 8) ^ (w13 << (64 - 8)) ^ (w13 >> 7)); + w13 += ((w11 >> 19) ^ (w11 << (64 - 19)) ^ (w11 >> 61) ^ (w11 << (64 - 61)) ^ (w11 >> 6)) + + w6 + + ((w14 >> 1) ^ (w14 << (64 - 1)) ^ (w14 >> 8) ^ (w14 << (64 - 8)) ^ (w14 >> 7)); + w14 += ((w12 >> 19) ^ (w12 << (64 - 19)) ^ (w12 >> 61) ^ (w12 << (64 - 61)) ^ (w12 >> 6)) + + w7 + + ((w15 >> 1) ^ (w15 << (64 - 1)) ^ (w15 >> 8) ^ (w15 << (64 - 8)) ^ (w15 >> 7)); + w15 += ((w13 >> 19) ^ (w13 << (64 - 19)) ^ (w13 >> 61) ^ (w13 << (64 - 61)) ^ (w13 >> 6)) + + w8 + + ((w0 >> 1) ^ (w0 << (64 - 1)) ^ (w0 >> 8) ^ (w0 << (64 - 8)) ^ (w0 >> 7)); + } + + outputState.x0 = inputState.x0 + a; + outputState.x1 = inputState.x1 + b; + outputState.x2 = inputState.x2 + c; + outputState.x3 = inputState.x3 + d; + outputState.x4 = inputState.x4 + e; + outputState.x5 = inputState.x5 + f; + outputState.x6 = inputState.x6 + g; + outputState.x7 = inputState.x7 + h; + } + } + } +} diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Sha512Internal.cs.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Sha512Internal.cs.meta new file mode 100644 index 0000000..deaf298 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Internal/Sha512Internal.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d5f29526ebe84dd4c879bc6959ef4b9e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/MontgomeryCurve25519.cs b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/MontgomeryCurve25519.cs new file mode 100644 index 0000000..562521f --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/MontgomeryCurve25519.cs @@ -0,0 +1,142 @@ +using System; +using System.Collections.Generic; +using Chaos.NaCl.Internal; +using Chaos.NaCl.Internal.Ed25519Ref10; +using Chaos.NaCl.Internal.Salsa; + +namespace Chaos.NaCl +{ + // This class is mainly for compatibility with NaCl's Curve25519 implementation + // If you don't need that compatibility, use Ed25519.KeyExchange + public static class MontgomeryCurve25519 + { + public static readonly int PublicKeySizeInBytes = 32; + public static readonly int PrivateKeySizeInBytes = 32; + public static readonly int SharedKeySizeInBytes = 32; + + public static byte[] GetPublicKey(byte[] privateKey) + { + if (privateKey == null) + throw new ArgumentNullException("privateKey"); + if (privateKey.Length != PrivateKeySizeInBytes) + throw new ArgumentException("privateKey.Length must be 32"); + var publicKey = new byte[32]; + GetPublicKey(new ArraySegment(publicKey), new ArraySegment(privateKey)); + return publicKey; + } + + static readonly byte[] _basePoint = new byte[32] + { + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0 ,0, 0, 0, 0, 0, + 0, 0, 0 ,0, 0, 0, 0, 0, + 0, 0, 0 ,0, 0, 0, 0, 0 + }; + + public static void GetPublicKey(ArraySegment publicKey, ArraySegment privateKey) + { + if (publicKey.Array == null) + throw new ArgumentNullException("publicKey.Array"); + if (privateKey.Array == null) + throw new ArgumentNullException("privateKey.Array"); + if (publicKey.Count != PublicKeySizeInBytes) + throw new ArgumentException("privateKey.Count must be 32"); + if (privateKey.Count != PrivateKeySizeInBytes) + throw new ArgumentException("privateKey.Count must be 32"); + + // hack: abusing publicKey as temporary storage + // todo: remove hack + for (int i = 0; i < 32; i++) + { + publicKey.Array[publicKey.Offset + i] = privateKey.Array[privateKey.Offset + i]; + } + ScalarOperations.sc_clamp(publicKey.Array, publicKey.Offset); + + GroupElementP3 A; + GroupOperations.ge_scalarmult_base(out A, publicKey.Array, publicKey.Offset); + FieldElement publicKeyFE; + EdwardsToMontgomeryX(out publicKeyFE, ref A.Y, ref A.Z); + FieldOperations.fe_tobytes(publicKey.Array, publicKey.Offset, ref publicKeyFE); + } + + // hashes like the Curve25519 paper says + internal static void KeyExchangeOutputHashCurve25519Paper(byte[] sharedKey, int offset) + { + //c = Curve25519output + const UInt32 c0 = 'C' | 'u' << 8 | 'r' << 16 | (UInt32)'v' << 24; + const UInt32 c1 = 'e' | '2' << 8 | '5' << 16 | (UInt32)'5' << 24; + const UInt32 c2 = '1' | '9' << 8 | 'o' << 16 | (UInt32)'u' << 24; + const UInt32 c3 = 't' | 'p' << 8 | 'u' << 16 | (UInt32)'t' << 24; + + Array16 salsaState; + salsaState.x0 = c0; + salsaState.x1 = ByteIntegerConverter.LoadLittleEndian32(sharedKey, offset + 0); + salsaState.x2 = 0; + salsaState.x3 = ByteIntegerConverter.LoadLittleEndian32(sharedKey, offset + 4); + salsaState.x4 = ByteIntegerConverter.LoadLittleEndian32(sharedKey, offset + 8); + salsaState.x5 = c1; + salsaState.x6 = ByteIntegerConverter.LoadLittleEndian32(sharedKey, offset + 12); + salsaState.x7 = 0; + salsaState.x8 = 0; + salsaState.x9 = ByteIntegerConverter.LoadLittleEndian32(sharedKey, offset + 16); + salsaState.x10 = c2; + salsaState.x11 = ByteIntegerConverter.LoadLittleEndian32(sharedKey, offset + 20); + salsaState.x12 = ByteIntegerConverter.LoadLittleEndian32(sharedKey, offset + 24); + salsaState.x13 = 0; + salsaState.x14 = ByteIntegerConverter.LoadLittleEndian32(sharedKey, offset + 28); + salsaState.x15 = c3; + SalsaCore.Salsa(out salsaState, ref salsaState, 20); + + ByteIntegerConverter.StoreLittleEndian32(sharedKey, offset + 0, salsaState.x0); + ByteIntegerConverter.StoreLittleEndian32(sharedKey, offset + 4, salsaState.x1); + ByteIntegerConverter.StoreLittleEndian32(sharedKey, offset + 8, salsaState.x2); + ByteIntegerConverter.StoreLittleEndian32(sharedKey, offset + 12, salsaState.x3); + ByteIntegerConverter.StoreLittleEndian32(sharedKey, offset + 16, salsaState.x4); + ByteIntegerConverter.StoreLittleEndian32(sharedKey, offset + 20, salsaState.x5); + ByteIntegerConverter.StoreLittleEndian32(sharedKey, offset + 24, salsaState.x6); + ByteIntegerConverter.StoreLittleEndian32(sharedKey, offset + 28, salsaState.x7); + } + + private static readonly byte[] _zero16 = new byte[16]; + + // hashes like the NaCl paper says instead i.e. HSalsa(x,0) + internal static void KeyExchangeOutputHashNaCl(byte[] sharedKey, int offset) + { + Salsa20.HSalsa20(sharedKey, offset, sharedKey, offset, _zero16, 0); + } + + public static byte[] KeyExchange(byte[] publicKey, byte[] privateKey) + { + var sharedKey = new byte[SharedKeySizeInBytes]; + KeyExchange(new ArraySegment(sharedKey), new ArraySegment(publicKey), new ArraySegment(privateKey)); + return sharedKey; + } + + public static void KeyExchange(ArraySegment sharedKey, ArraySegment publicKey, ArraySegment privateKey) + { + if (sharedKey.Array == null) + throw new ArgumentNullException("sharedKey.Array"); + if (publicKey.Array == null) + throw new ArgumentNullException("publicKey.Array"); + if (privateKey.Array == null) + throw new ArgumentNullException("privateKey"); + if (sharedKey.Count != 32) + throw new ArgumentException("sharedKey.Count != 32"); + if (publicKey.Count != 32) + throw new ArgumentException("publicKey.Count != 32"); + if (privateKey.Count != 32) + throw new ArgumentException("privateKey.Count != 32"); + MontgomeryOperations.scalarmult(sharedKey.Array, sharedKey.Offset, privateKey.Array, privateKey.Offset, publicKey.Array, publicKey.Offset); + KeyExchangeOutputHashNaCl(sharedKey.Array, sharedKey.Offset); + } + + internal static void EdwardsToMontgomeryX(out FieldElement montgomeryX, ref FieldElement edwardsY, ref FieldElement edwardsZ) + { + FieldElement tempX, tempZ; + FieldOperations.fe_add(out tempX, ref edwardsZ, ref edwardsY); + FieldOperations.fe_sub(out tempZ, ref edwardsZ, ref edwardsY); + FieldOperations.fe_invert(out tempZ, ref tempZ); + FieldOperations.fe_mul(out montgomeryX, ref tempX, ref tempZ); + } + } +} diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/MontgomeryCurve25519.cs.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/MontgomeryCurve25519.cs.meta new file mode 100644 index 0000000..6940eb7 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/MontgomeryCurve25519.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cc1862ee799d2cb4c8f72968831edad0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/OneTimeAuth.cs b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/OneTimeAuth.cs new file mode 100644 index 0000000..805e691 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/OneTimeAuth.cs @@ -0,0 +1,19 @@ +using System; + +namespace Chaos.NaCl +{ + public abstract class OneTimeAuth + { + private static readonly Poly1305 _poly1305 = new Poly1305(); + + public abstract int KeySizeInBytes { get; } + public abstract int SignatureSizeInBytes { get; } + + public abstract byte[] Sign(byte[] message, byte[] key); + public abstract void Sign(ArraySegment signature, ArraySegment message, ArraySegment key); + public abstract bool Verify(byte[] signature, byte[] message, byte[] key); + public abstract bool Verify(ArraySegment signature, ArraySegment message, ArraySegment key); + + public static OneTimeAuth Poly1305 { get { return _poly1305; } } + } +} diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/OneTimeAuth.cs.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/OneTimeAuth.cs.meta new file mode 100644 index 0000000..055fb3e --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/OneTimeAuth.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dc6fc19aed69ca64e95861042127d995 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Poly1305.cs b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Poly1305.cs new file mode 100644 index 0000000..4febd08 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Poly1305.cs @@ -0,0 +1,97 @@ +using System; +using System.Collections.Generic; +using Chaos.NaCl.Internal; + +namespace Chaos.NaCl +{ + internal sealed class Poly1305 : OneTimeAuth + { + public override int KeySizeInBytes + { + get { return 32; } + } + + public override int SignatureSizeInBytes + { + get { return 16; } + } + + [Obsolete("Needs more testing")] + public override byte[] Sign(byte[] message, byte[] key) + { + if (message == null) + throw new ArgumentNullException("message"); + if (key == null) + throw new ArgumentNullException("key"); + if (key.Length != 32) + throw new ArgumentException("Invalid key size", "key"); + + var result = new byte[16]; + Array8 internalKey; + ByteIntegerConverter.Array8LoadLittleEndian32(out internalKey, key, 0); + Poly1305Donna.poly1305_auth(result, 0, message, 0, message.Length, ref internalKey); + return result; + } + + [Obsolete("Needs more testing")] + public override void Sign(ArraySegment signature, ArraySegment message, ArraySegment key) + { + if (signature.Array == null) + throw new ArgumentNullException("signature.Array"); + if (message.Array == null) + throw new ArgumentNullException("message.Array"); + if (key.Array == null) + throw new ArgumentNullException("key.Array"); + if (key.Count != 32) + throw new ArgumentException("Invalid key size", "key"); + if (signature.Count != 16) + throw new ArgumentException("Invalid signature size", "signature"); + + Array8 internalKey; + ByteIntegerConverter.Array8LoadLittleEndian32(out internalKey, key.Array, key.Offset); + Poly1305Donna.poly1305_auth(signature.Array, signature.Offset, message.Array, message.Offset, message.Count, ref internalKey); + } + + [Obsolete("Needs more testing")] + public override bool Verify(byte[] signature, byte[] message, byte[] key) + { + if (signature == null) + throw new ArgumentNullException("signature"); + if (message == null) + throw new ArgumentNullException("message"); + if (key == null) + throw new ArgumentNullException("key"); + if (signature.Length != 16) + throw new ArgumentException("Invalid signature size", "signature"); + if (key.Length != 32) + throw new ArgumentException("Invalid key size", "key"); + + var tempBytes = new byte[16];//todo: remove allocation + Array8 internalKey; + ByteIntegerConverter.Array8LoadLittleEndian32(out internalKey, key, 0); + Poly1305Donna.poly1305_auth(tempBytes, 0, message, 0, message.Length, ref internalKey); + return CryptoBytes.ConstantTimeEquals(tempBytes, signature); + } + + [Obsolete("Needs more testing")] + public override bool Verify(ArraySegment signature, ArraySegment message, ArraySegment key) + { + if (signature.Array == null) + throw new ArgumentNullException("signature.Array"); + if (message.Array == null) + throw new ArgumentNullException("message.Array"); + if (key.Array == null) + throw new ArgumentNullException("key.Array"); + if (key.Count != 32) + throw new ArgumentException("Invalid key size", "key"); + if (signature.Count != 16) + throw new ArgumentException("Invalid signature size", "signature"); + + var tempBytes = new byte[16];//todo: remove allocation + Array8 internalKey; + ByteIntegerConverter.Array8LoadLittleEndian32(out internalKey, key.Array, key.Offset); + Poly1305Donna.poly1305_auth(tempBytes, 0, message.Array, message.Offset, message.Count, ref internalKey); + return CryptoBytes.ConstantTimeEquals(new ArraySegment(tempBytes), signature); + } + } +} diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Poly1305.cs.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Poly1305.cs.meta new file mode 100644 index 0000000..6078ac2 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Poly1305.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ba02ab521d2899444ac059d15eb3b403 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Properties.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Properties.meta new file mode 100644 index 0000000..cfa4722 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Properties.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e437316db226c854bbd0ce94b0b85333 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Properties/AssemblyInfo.cs b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..a8650f9 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Properties/AssemblyInfo.cs @@ -0,0 +1,30 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Chaos.NaCl")] +[assembly: AssemblyDescription("C# port of the NaCl cryptography library")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("CodesInChaos")] +[assembly: AssemblyProduct("Chaos.NaCl cryptography library")] +[assembly: AssemblyCopyright("public domain")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("0.1.0.0")] +[assembly: AssemblyFileVersion("0.1.0.0")] + +[assembly: InternalsVisibleTo("Chaos.NaCl.Tests")] +[assembly: InternalsVisibleTo("Chaos.NaCl.Benchmark")] \ No newline at end of file diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Properties/AssemblyInfo.cs.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Properties/AssemblyInfo.cs.meta new file mode 100644 index 0000000..eb9b440 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Properties/AssemblyInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7f9240cd6122f3a429e074522ea2d410 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Properties/AssemblyInfoFull.cs b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Properties/AssemblyInfoFull.cs new file mode 100644 index 0000000..80fd16c --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Properties/AssemblyInfoFull.cs @@ -0,0 +1,9 @@ +using System.Runtime.InteropServices; + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("f07e7dd1-d31c-4994-8948-e42de7ef16ec")] \ No newline at end of file diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Properties/AssemblyInfoFull.cs.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Properties/AssemblyInfoFull.cs.meta new file mode 100644 index 0000000..65bd506 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Properties/AssemblyInfoFull.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 203d679dcfa1dd14ba7cedd7101e6279 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Sha512.cs b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Sha512.cs new file mode 100644 index 0000000..60d7046 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Sha512.cs @@ -0,0 +1,132 @@ +using System; +using System.Collections.Generic; +using Chaos.NaCl.Internal; + +namespace Chaos.NaCl +{ + public class Sha512 + { + private Array8 _state; + private readonly byte[] _buffer; + private ulong _totalBytes; + public const int BlockSize = 128; + private static readonly byte[] _padding = new byte[] { 0x80 }; + + public Sha512() + { + _buffer = new byte[BlockSize];//todo: remove allocation + Init(); + } + + public void Init() + { + Sha512Internal.Sha512Init(out _state); + _totalBytes = 0; + } + + public void Update(ArraySegment data) + { + if (data.Array == null) + throw new ArgumentNullException("data.Array"); + Update(data.Array, data.Offset, data.Count); + } + + public void Update(byte[] data, int offset, int count) + { + if (data == null) + throw new ArgumentNullException("data"); + if (offset < 0) + throw new ArgumentOutOfRangeException("offset"); + if (count < 0) + throw new ArgumentOutOfRangeException("count"); + if (data.Length - offset < count) + throw new ArgumentException("Requires offset + count <= data.Length"); + + Array16 block; + int bytesInBuffer = (int)_totalBytes & (BlockSize - 1); + _totalBytes += (uint)count; + + if (_totalBytes >= ulong.MaxValue / 8) + throw new InvalidOperationException("Too much data"); + // Fill existing buffer + if (bytesInBuffer != 0) + { + var toCopy = Math.Min(BlockSize - bytesInBuffer, count); + Buffer.BlockCopy(data, offset, _buffer, bytesInBuffer, toCopy); + offset += toCopy; + count -= toCopy; + bytesInBuffer += toCopy; + if (bytesInBuffer == BlockSize) + { + ByteIntegerConverter.Array16LoadBigEndian64(out block, _buffer, 0); + Sha512Internal.Core(out _state, ref _state, ref block); + CryptoBytes.InternalWipe(_buffer, 0, _buffer.Length); + bytesInBuffer = 0; + } + } + // Hash complete blocks without copying + while (count >= BlockSize) + { + ByteIntegerConverter.Array16LoadBigEndian64(out block, data, offset); + Sha512Internal.Core(out _state, ref _state, ref block); + offset += BlockSize; + count -= BlockSize; + } + // Copy remainder into buffer + if (count > 0) + { + Buffer.BlockCopy(data, offset, _buffer, bytesInBuffer, count); + } + } + + public void Finish(ArraySegment output) + { + if (output.Array == null) + throw new ArgumentNullException("output.Array"); + if (output.Count != 64) + throw new ArgumentException("output.Count must be 64"); + + Update(_padding, 0, _padding.Length); + Array16 block; + ByteIntegerConverter.Array16LoadBigEndian64(out block, _buffer, 0); + CryptoBytes.InternalWipe(_buffer, 0, _buffer.Length); + int bytesInBuffer = (int)_totalBytes & (BlockSize - 1); + if (bytesInBuffer > BlockSize - 16) + { + Sha512Internal.Core(out _state, ref _state, ref block); + block = default(Array16); + } + block.x15 = (_totalBytes - 1) * 8; + Sha512Internal.Core(out _state, ref _state, ref block); + + ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 0, _state.x0); + ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 8, _state.x1); + ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 16, _state.x2); + ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 24, _state.x3); + ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 32, _state.x4); + ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 40, _state.x5); + ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 48, _state.x6); + ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 56, _state.x7); + _state = default(Array8); + } + + public byte[] Finish() + { + var result = new byte[64]; + Finish(new ArraySegment(result)); + return result; + } + + public static byte[] Hash(byte[] data) + { + return Hash(data, 0, data.Length); + } + + public static byte[] Hash(byte[] data, int offset, int count) + { + var hasher = new Sha512(); + hasher.Update(data, offset, count); + return hasher.Finish(); + } + } +} diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Sha512.cs.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Sha512.cs.meta new file mode 100644 index 0000000..301a1bc --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/Sha512.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5144cb1d0e1b7c0478b68b450d44ee57 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/XSalsa20Poly1305.cs b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/XSalsa20Poly1305.cs new file mode 100644 index 0000000..4523e44 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/XSalsa20Poly1305.cs @@ -0,0 +1,247 @@ +using System; +using System.Collections.Generic; +using Chaos.NaCl.Internal; +using Chaos.NaCl.Internal.Salsa; + +namespace Chaos.NaCl +{ + public static class XSalsa20Poly1305 + { + public static readonly int KeySizeInBytes = 32; + public static readonly int NonceSizeInBytes = 24; + public static readonly int MacSizeInBytes = 16; + + public static byte[] Encrypt(byte[] message, byte[] key, byte[] nonce) + { + if (message == null) + throw new ArgumentNullException("message"); + if (key == null) + throw new ArgumentNullException("key"); + if (nonce == null) + throw new ArgumentNullException("nonce"); + if (key.Length != KeySizeInBytes) + throw new ArgumentException("key.Length != 32"); + if (nonce.Length != NonceSizeInBytes) + throw new ArgumentException("nonce.Length != 24"); + + var ciphertext = new byte[message.Length + MacSizeInBytes]; + EncryptInternal(ciphertext, 0, message, 0, message.Length, key, 0, nonce, 0); + return ciphertext; + } + + public static void Encrypt(ArraySegment ciphertext, ArraySegment message, ArraySegment key, ArraySegment nonce) + { + if (key.Count != KeySizeInBytes) + throw new ArgumentException("key.Length != 32"); + if (nonce.Count != NonceSizeInBytes) + throw new ArgumentException("nonce.Length != 24"); + if (ciphertext.Count != message.Count + MacSizeInBytes) + throw new ArgumentException("ciphertext.Count != message.Count + 16"); + EncryptInternal(ciphertext.Array, ciphertext.Offset, message.Array, message.Offset, message.Count, key.Array, key.Offset, nonce.Array, nonce.Offset); + } + + /// + /// Decrypts the ciphertext and verifies its authenticity + /// + /// Plaintext if MAC validation succeeds, null if the data is invalid. + public static byte[] TryDecrypt(byte[] ciphertext, byte[] key, byte[] nonce) + { + if (ciphertext == null) + throw new ArgumentNullException("ciphertext"); + if (key == null) + throw new ArgumentNullException("key"); + if (nonce == null) + throw new ArgumentNullException("nonce"); + if (key.Length != KeySizeInBytes) + throw new ArgumentException("key.Length != 32"); + if (nonce.Length != NonceSizeInBytes) + throw new ArgumentException("nonce.Length != 24"); + + if (ciphertext.Length < MacSizeInBytes) + return null; + var plaintext = new byte[ciphertext.Length - MacSizeInBytes]; + bool success = DecryptInternal(plaintext, 0, ciphertext, 0, ciphertext.Length, key, 0, nonce, 0); + if (success) + return plaintext; + else + return null; + } + + /// + /// Decrypts the ciphertext and verifies its authenticity + /// + /// Plaintext if authentication succeeded, all zero if authentication failed, unmodified if argument verification fails + /// + /// Symmetric key. Must be identical to key specified for encryption. + /// Must be identical to nonce specified for encryption. + /// true if ciphertext is authentic, false otherwise + public static bool TryDecrypt(ArraySegment message, ArraySegment ciphertext, ArraySegment key, ArraySegment nonce) + { + if (key.Count != KeySizeInBytes) + throw new ArgumentException("key.Length != 32"); + if (nonce.Count != NonceSizeInBytes) + throw new ArgumentException("nonce.Length != 24"); + if (ciphertext.Count != message.Count + MacSizeInBytes) + throw new ArgumentException("ciphertext.Count != message.Count + 16"); + + return DecryptInternal(message.Array, message.Offset, ciphertext.Array, ciphertext.Offset, ciphertext.Count, key.Array, key.Offset, nonce.Array, nonce.Offset); + } + + private static void PrepareInternalKey(out Array16 internalKey, byte[] key, int keyOffset, byte[] nonce, int nonceOffset) + { + internalKey.x0 = Salsa20.SalsaConst0; + internalKey.x1 = ByteIntegerConverter.LoadLittleEndian32(key, keyOffset + 0); + internalKey.x2 = ByteIntegerConverter.LoadLittleEndian32(key, keyOffset + 4); + internalKey.x3 = ByteIntegerConverter.LoadLittleEndian32(key, keyOffset + 8); + internalKey.x4 = ByteIntegerConverter.LoadLittleEndian32(key, keyOffset + 12); + internalKey.x5 = Salsa20.SalsaConst1; + internalKey.x6 = ByteIntegerConverter.LoadLittleEndian32(nonce, nonceOffset + 0); + internalKey.x7 = ByteIntegerConverter.LoadLittleEndian32(nonce, nonceOffset + 4); + internalKey.x8 = ByteIntegerConverter.LoadLittleEndian32(nonce, nonceOffset + 8); + internalKey.x9 = ByteIntegerConverter.LoadLittleEndian32(nonce, nonceOffset + 12); + internalKey.x10 = Salsa20.SalsaConst2; + internalKey.x11 = ByteIntegerConverter.LoadLittleEndian32(key, keyOffset + 16); + internalKey.x12 = ByteIntegerConverter.LoadLittleEndian32(key, keyOffset + 20); + internalKey.x13 = ByteIntegerConverter.LoadLittleEndian32(key, keyOffset + 24); + internalKey.x14 = ByteIntegerConverter.LoadLittleEndian32(key, keyOffset + 28); + internalKey.x15 = Salsa20.SalsaConst3; + SalsaCore.HSalsa(out internalKey, ref internalKey, 20); + + //key + internalKey.x1 = internalKey.x0; + internalKey.x2 = internalKey.x5; + internalKey.x3 = internalKey.x10; + internalKey.x4 = internalKey.x15; + internalKey.x11 = internalKey.x6; + internalKey.x12 = internalKey.x7; + internalKey.x13 = internalKey.x8; + internalKey.x14 = internalKey.x9; + //const + internalKey.x0 = Salsa20.SalsaConst0; + internalKey.x5 = Salsa20.SalsaConst1; + internalKey.x10 = Salsa20.SalsaConst2; + internalKey.x15 = Salsa20.SalsaConst3; + //nonce + internalKey.x6 = ByteIntegerConverter.LoadLittleEndian32(nonce, nonceOffset + 16); + internalKey.x7 = ByteIntegerConverter.LoadLittleEndian32(nonce, nonceOffset + 20); + //offset + internalKey.x8 = 0; + internalKey.x9 = 0; + } + + private static bool DecryptInternal(byte[] plaintext, int plaintextOffset, byte[] ciphertext, int ciphertextOffset, int ciphertextLength, byte[] key, int keyOffset, byte[] nonce, int nonceOffset) + { + int plaintextLength = ciphertextLength - MacSizeInBytes; + Array16 internalKey; + PrepareInternalKey(out internalKey, key, keyOffset, nonce, nonceOffset); + + Array16 temp; + var tempBytes = new byte[64];//todo: remove allocation + + // first iteration + { + SalsaCore.Salsa(out temp, ref internalKey, 20); + + //first half is for Poly1305 + Array8 poly1305Key; + poly1305Key.x0 = temp.x0; + poly1305Key.x1 = temp.x1; + poly1305Key.x2 = temp.x2; + poly1305Key.x3 = temp.x3; + poly1305Key.x4 = temp.x4; + poly1305Key.x5 = temp.x5; + poly1305Key.x6 = temp.x6; + poly1305Key.x7 = temp.x7; + + // compute MAC + Poly1305Donna.poly1305_auth(tempBytes, 0, ciphertext, ciphertextOffset + 16, plaintextLength, ref poly1305Key); + if (!CryptoBytes.ConstantTimeEquals(tempBytes, 0, ciphertext, ciphertextOffset, MacSizeInBytes)) + { + Array.Clear(plaintext, plaintextOffset, plaintextLength); + return false; + } + + // rest for the message + ByteIntegerConverter.StoreLittleEndian32(tempBytes, 0, temp.x8); + ByteIntegerConverter.StoreLittleEndian32(tempBytes, 4, temp.x9); + ByteIntegerConverter.StoreLittleEndian32(tempBytes, 8, temp.x10); + ByteIntegerConverter.StoreLittleEndian32(tempBytes, 12, temp.x11); + ByteIntegerConverter.StoreLittleEndian32(tempBytes, 16, temp.x12); + ByteIntegerConverter.StoreLittleEndian32(tempBytes, 20, temp.x13); + ByteIntegerConverter.StoreLittleEndian32(tempBytes, 24, temp.x14); + ByteIntegerConverter.StoreLittleEndian32(tempBytes, 28, temp.x15); + int count = Math.Min(32, plaintextLength); + for (int i = 0; i < count; i++) + plaintext[plaintextOffset + i] = (byte)(ciphertext[MacSizeInBytes + ciphertextOffset + i] ^ tempBytes[i]); + } + + // later iterations + int blockOffset = 32; + while (blockOffset < plaintextLength) + { + internalKey.x8++; + SalsaCore.Salsa(out temp, ref internalKey, 20); + ByteIntegerConverter.Array16StoreLittleEndian32(tempBytes, 0, ref temp); + int count = Math.Min(64, plaintextLength - blockOffset); + for (int i = 0; i < count; i++) + plaintext[plaintextOffset + blockOffset + i] = (byte)(ciphertext[16 + ciphertextOffset + blockOffset + i] ^ tempBytes[i]); + blockOffset += 64; + } + return true; + } + + private static void EncryptInternal(byte[] ciphertext, int ciphertextOffset, byte[] message, int messageOffset, int messageLength, byte[] key, int keyOffset, byte[] nonce, int nonceOffset) + { + Array16 internalKey; + PrepareInternalKey(out internalKey, key, keyOffset, nonce, nonceOffset); + + Array16 temp; + var tempBytes = new byte[64];//todo: remove allocation + Array8 poly1305Key; + + // first iteration + { + SalsaCore.Salsa(out temp, ref internalKey, 20); + + //first half is for Poly1305 + poly1305Key.x0 = temp.x0; + poly1305Key.x1 = temp.x1; + poly1305Key.x2 = temp.x2; + poly1305Key.x3 = temp.x3; + poly1305Key.x4 = temp.x4; + poly1305Key.x5 = temp.x5; + poly1305Key.x6 = temp.x6; + poly1305Key.x7 = temp.x7; + + // second half for the message + ByteIntegerConverter.StoreLittleEndian32(tempBytes, 0, temp.x8); + ByteIntegerConverter.StoreLittleEndian32(tempBytes, 4, temp.x9); + ByteIntegerConverter.StoreLittleEndian32(tempBytes, 8, temp.x10); + ByteIntegerConverter.StoreLittleEndian32(tempBytes, 12, temp.x11); + ByteIntegerConverter.StoreLittleEndian32(tempBytes, 16, temp.x12); + ByteIntegerConverter.StoreLittleEndian32(tempBytes, 20, temp.x13); + ByteIntegerConverter.StoreLittleEndian32(tempBytes, 24, temp.x14); + ByteIntegerConverter.StoreLittleEndian32(tempBytes, 28, temp.x15); + int count = Math.Min(32, messageLength); + for (int i = 0; i < count; i++) + ciphertext[16 + ciphertextOffset + i] = (byte)(message[messageOffset + i] ^ tempBytes[i]); + } + + // later iterations + int blockOffset = 32; + while (blockOffset < messageLength) + { + internalKey.x8++; + SalsaCore.Salsa(out temp, ref internalKey, 20); + ByteIntegerConverter.Array16StoreLittleEndian32(tempBytes, 0, ref temp); + int count = Math.Min(64, messageLength - blockOffset); + for (int i = 0; i < count; i++) + ciphertext[16 + ciphertextOffset + blockOffset + i] = (byte)(message[messageOffset + blockOffset + i] ^ tempBytes[i]); + blockOffset += 64; + } + + // compute MAC + Poly1305Donna.poly1305_auth(ciphertext, ciphertextOffset, ciphertext, ciphertextOffset + 16, messageLength, ref poly1305Key); + } + } +} diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/XSalsa20Poly1305.cs.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/XSalsa20Poly1305.cs.meta new file mode 100644 index 0000000..97b3e02 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.NaCl/XSalsa20Poly1305.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fada2cfbd403a6a438186dd395e31a7f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.Nacl.asmdef b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.Nacl.asmdef new file mode 100644 index 0000000..bb31d98 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.Nacl.asmdef @@ -0,0 +1,3 @@ +{ + "name": "Chaos.Nacl" +} diff --git a/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.Nacl.asmdef.meta b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.Nacl.asmdef.meta new file mode 100644 index 0000000..c0477f3 --- /dev/null +++ b/Packages/Chaos.NaCl-master (1)/Chaos.NaCl-master/Chaos.Nacl.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: e81c8beff9ece1e43848e56b1b271dea +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Chaos.NaCl.dll b/Packages/Chaos.NaCl.dll deleted file mode 100644 index 99a22be..0000000 Binary files a/Packages/Chaos.NaCl.dll and /dev/null differ diff --git a/Packages/Chaos.NaCl.dll.meta b/Packages/Chaos.NaCl.dll.meta deleted file mode 100644 index d42c93e..0000000 --- a/Packages/Chaos.NaCl.dll.meta +++ /dev/null @@ -1,33 +0,0 @@ -fileFormatVersion: 2 -guid: 6143e5c7940264f48a5135f897adf240 -PluginImporter: - externalObjects: {} - serializedVersion: 2 - iconMap: {} - executionOrder: {} - defineConstraints: [] - isPreloaded: 0 - isOverridable: 1 - isExplicitlyReferenced: 0 - validateReferences: 1 - platformData: - - first: - Any: - second: - enabled: 1 - settings: {} - - first: - Editor: Editor - second: - enabled: 0 - settings: - DefaultValueInitialized: true - - first: - Windows Store Apps: WindowsStoreApps - second: - enabled: 0 - settings: - CPU: AnyCPU - userData: - assetBundleName: - assetBundleVariant: diff --git a/Packages/RestSharp.dll b/Packages/RestSharp.dll deleted file mode 100644 index e31ee28..0000000 Binary files a/Packages/RestSharp.dll and /dev/null differ diff --git a/Packages/RestSharp.dll.meta b/Packages/RestSharp.dll.meta deleted file mode 100644 index 4a8587d..0000000 --- a/Packages/RestSharp.dll.meta +++ /dev/null @@ -1,33 +0,0 @@ -fileFormatVersion: 2 -guid: 56b8c134d237243489522331ab49498d -PluginImporter: - externalObjects: {} - serializedVersion: 2 - iconMap: {} - executionOrder: {} - defineConstraints: [] - isPreloaded: 0 - isOverridable: 1 - isExplicitlyReferenced: 0 - validateReferences: 1 - platformData: - - first: - Any: - second: - enabled: 1 - settings: {} - - first: - Editor: Editor - second: - enabled: 0 - settings: - DefaultValueInitialized: true - - first: - Windows Store Apps: WindowsStoreApps - second: - enabled: 0 - settings: - CPU: AnyCPU - userData: - assetBundleName: - assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9.meta b/Packages/Solana.Unity-Core-2.6.0.9.meta new file mode 100644 index 0000000..e2fb2f6 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 955d922b15415fe4f992f67c0fcf3b54 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src.meta b/Packages/Solana.Unity-Core-2.6.0.9/src.meta new file mode 100644 index 0000000..98304c1 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 473ab981a8125634080032d49e50ea7b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/PredefineFix_IsExternalInit.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/PredefineFix_IsExternalInit.cs new file mode 100644 index 0000000..253f0e2 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/PredefineFix_IsExternalInit.cs @@ -0,0 +1,7 @@ +using System.ComponentModel; + +namespace System.Runtime.CompilerServices +{ + [EditorBrowsable(EditorBrowsableState.Never)] + internal static class IsExternalInit { } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/PredefineFix_IsExternalInit.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/PredefineFix_IsExternalInit.cs.meta new file mode 100644 index 0000000..c52cc2a --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/PredefineFix_IsExternalInit.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6d58a318867351844aea7183e8b1c8be +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples.meta new file mode 100644 index 0000000..e4ad65b --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 38438975b2cb39f41af5f3821075d0a4 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/AssociatedTokenAccountsExample.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/AssociatedTokenAccountsExample.cs new file mode 100644 index 0000000..7d8beac --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/AssociatedTokenAccountsExample.cs @@ -0,0 +1,127 @@ +using Solana.Unity.Programs; +using Solana.Unity.Rpc; +using Solana.Unity.Rpc.Builders; +using Solana.Unity.Rpc.Core.Http; +using Solana.Unity.Rpc.Messages; +using Solana.Unity.Rpc.Models; +using Solana.Unity.Rpc.Types; +using Solana.Unity.Wallet; +using System; +using System.Collections.Generic; +using System.Threading; + +namespace Solana.Unity.Examples +{ + public class AssociatedTokenAccountsExample : IExample + { + + private static readonly IRpcClient RpcClient = ClientFactory.GetClient(Cluster.TestNet); + + private const string MnemonicWords = + "route clerk disease box emerge airport loud waste attitude film army tray " + + "forward deal onion eight catalog surface unit card window walnut wealth medal"; + + public void Run() + { + Wallet.Wallet wallet = new Wallet.Wallet(MnemonicWords); + + /* + * The following region creates and initializes a mint account, it also creates a token account + * that is initialized with the same mint account and then mints tokens to this newly created token account. + */ + #region Create and Initialize a token Mint Account + + + RequestResult> blockHash = RpcClient.GetRecentBlockHash(); + + ulong minBalanceForExemptionAcc = + RpcClient.GetMinimumBalanceForRentExemption(TokenProgram.TokenAccountDataSize).Result; + ulong minBalanceForExemptionMint = + RpcClient.GetMinimumBalanceForRentExemption(TokenProgram.MintAccountDataSize).Result; + + Console.WriteLine($"MinBalanceForRentExemption Account >> {minBalanceForExemptionAcc}"); + Console.WriteLine($"MinBalanceForRentExemption Mint Account >> {minBalanceForExemptionMint}"); + + Account ownerAccount = wallet.GetAccount(10); + Account mintAccount = wallet.GetAccount(1004); + Account initialAccount = wallet.GetAccount(1104); + Console.WriteLine($"OwnerAccount: {ownerAccount}"); + Console.WriteLine($"MintAccount: {mintAccount}"); + Console.WriteLine($"InitialAccount: {initialAccount}"); + + byte[] createAndInitializeMintToTx = new TransactionBuilder(). + SetRecentBlockHash(blockHash.Result.Value.Blockhash). + SetFeePayer(ownerAccount). + AddInstruction(SystemProgram.CreateAccount( + ownerAccount, + mintAccount, + minBalanceForExemptionMint, + TokenProgram.MintAccountDataSize, + TokenProgram.ProgramIdKey)). + AddInstruction(TokenProgram.InitializeMint( + mintAccount.PublicKey, + 2, + ownerAccount.PublicKey, + ownerAccount.PublicKey)). + AddInstruction(SystemProgram.CreateAccount( + ownerAccount, + initialAccount, + minBalanceForExemptionAcc, + TokenProgram.TokenAccountDataSize, + TokenProgram.ProgramIdKey)). + AddInstruction(TokenProgram.InitializeAccount( + initialAccount.PublicKey, + mintAccount.PublicKey, + ownerAccount.PublicKey)). + AddInstruction(TokenProgram.MintTo( + mintAccount.PublicKey, + initialAccount.PublicKey, + 1_000_000, + ownerAccount)). + AddInstruction(MemoProgram.NewMemo(initialAccount, "Hello from Sol.Net")). + Build(new List { ownerAccount, mintAccount, initialAccount }); + + string createAndInitializeMintToTxSignature = Examples.SubmitTxSendAndLog(createAndInitializeMintToTx); + + Examples.PollConfirmedTx(createAndInitializeMintToTxSignature); + + #endregion + + /* + * The following region creates an associated token account (ATA) for a random account and a certain token mint + * (in this case it's the previously created token mintAccount) and transfers tokens from the previously created + * token account to the newly created ATA. + */ + #region Create Associated Token Account + + // this public key is from a random account created via www.sollet.io + // to test this locally I recommend creating a wallet on sollet and deriving this + PublicKey associatedTokenAccountOwner = new PublicKey("65EoWs57dkMEWbK4TJkPDM76rnbumq7r3fiZJnxggj2G"); + PublicKey associatedTokenAccount = + AssociatedTokenAccountProgram.DeriveAssociatedTokenAccount(associatedTokenAccountOwner, mintAccount); + Console.WriteLine($"AssociatedTokenAccountOwner: {associatedTokenAccountOwner}"); + Console.WriteLine($"AssociatedTokenAccount: {associatedTokenAccount}"); + + byte[] createAssociatedTokenAccountTx = new TransactionBuilder(). + SetRecentBlockHash(blockHash.Result.Value.Blockhash). + SetFeePayer(ownerAccount). + AddInstruction(AssociatedTokenAccountProgram.CreateAssociatedTokenAccount( + ownerAccount, + associatedTokenAccountOwner, + mintAccount)). + AddInstruction(TokenProgram.Transfer( + initialAccount, + associatedTokenAccount, + 25000, + ownerAccount)).// the ownerAccount was set as the mint authority + AddInstruction(MemoProgram.NewMemo(ownerAccount, "Hello from Sol.Net")). + Build(new List { ownerAccount }); + + string createAssociatedTokenAccountTxSignature = Examples.SubmitTxSendAndLog(createAssociatedTokenAccountTx); + + Examples.PollConfirmedTx(createAssociatedTokenAccountTxSignature); + + #endregion + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/AssociatedTokenAccountsExample.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/AssociatedTokenAccountsExample.cs.meta new file mode 100644 index 0000000..9ac3f57 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/AssociatedTokenAccountsExample.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1033101abffee2047968d4d79d36ef37 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/ExampleExplorer.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/ExampleExplorer.cs new file mode 100644 index 0000000..40458ef --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/ExampleExplorer.cs @@ -0,0 +1,39 @@ +using System; +using System.Linq; +using System.Reflection; + +namespace Solana.Unity.Examples +{ + public class ExampleExplorer + { + public static void Main(string[] args) + { + var examples = Assembly.GetEntryAssembly().GetExportedTypes().Where(t => typeof(IExample).IsAssignableFrom(t)).ToList(); + + while (true) + { + Console.WriteLine("Choose an example to run: "); + int i = 0; + foreach (var ex in examples) + { + Console.WriteLine($"{i++}){ex.Name}"); + } + + var option = Console.ReadLine(); + + if (int.TryParse(option, out int res) && res <= examples.Count && res >= 0) + { + var t = examples[res]; + var example = (IExample)t.GetConstructor(Type.EmptyTypes).Invoke(null); + + example.Run(); + } + else + { + Console.WriteLine("invalid option"); + } + } + + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/ExampleExplorer.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/ExampleExplorer.cs.meta new file mode 100644 index 0000000..4eceb30 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/ExampleExplorer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3671232f1c1725e478e337115b2f6ef8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/ExampleHelpers.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/ExampleHelpers.cs new file mode 100644 index 0000000..d28ad9d --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/ExampleHelpers.cs @@ -0,0 +1,131 @@ +using Solana.Unity.Programs; +using Solana.Unity.Rpc; +using Solana.Unity.Rpc.Core.Http; +using Solana.Unity.Rpc.Messages; +using Solana.Unity.Rpc.Models; +using Solana.Unity.Wallet; +using Solana.Unity.Wallet.Utilities; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; + +namespace Solana.Unity.Examples +{ + + public class Examples + { + private static readonly IRpcClient RpcClient = ClientFactory.GetClient(Cluster.TestNet); + + public static string PrettyPrintTransactionSimulationLogs(string[] logMessages) + { + return logMessages.Aggregate("", (current, log) => current + $"\t\t{log}\n"); + } + + /// + /// Submits a transaction and logs the output from SimulateTransaction. + /// + /// The transaction data ready to simulate or submit to the network. + public static string SubmitTxSendAndLog(byte[] tx) + { + Console.WriteLine($"Tx Data: {Convert.ToBase64String(tx)}"); + + RequestResult> txSim = RpcClient.SimulateTransaction(tx); + string logs = PrettyPrintTransactionSimulationLogs(txSim.Result.Value.Logs); + Console.WriteLine($"Transaction Simulation:\n\tError: {txSim.Result.Value.Error}\n\tLogs: \n" + logs); + + RequestResult txReq = RpcClient.SendTransaction(tx); + Console.WriteLine($"Tx Signature: {txReq.Result}"); + + return txReq.Result; + } + + /// + /// Polls the rpc client until a transaction signature has been confirmed. + /// + /// The first transaction signature. + public static void PollConfirmedTx(string signature) + { + RequestResult txMeta = RpcClient.GetTransaction(signature); + while (!txMeta.WasSuccessful) + { + Thread.Sleep(5000); + txMeta = RpcClient.GetTransaction(signature); + } + } + + /// + /// Decodes a message from wire format and logs it's content. + /// + /// The encoded message. + public static Message DecodeMessageFromWire(byte[] msgData) + { + + Console.WriteLine($"Message: {Convert.ToBase64String(msgData)}"); + Message msg = Message.Deserialize(Convert.ToBase64String(msgData)); + + Console.WriteLine("\n\tDECODING TRANSACTION FROM WIRE FORMAT\t"); + Console.WriteLine( + $"Message Header: {msg.Header.RequiredSignatures} {msg.Header.ReadOnlySignedAccounts} {msg.Header.ReadOnlyUnsignedAccounts}"); + Console.WriteLine($"Message BlockHash/Nonce: {msg.RecentBlockhash}"); + foreach (PublicKey account in msg.AccountKeys) + { + Console.WriteLine($"Message Account: {account}"); + } + + DecodeInstructionsFromMessageAndLog(msg); + + return msg; + } + + /// + /// Decodes the instructions in a message and logs them. + /// + /// The message. + public static void DecodeInstructionsFromMessageAndLog(Message message) + { + List decodedInstructions = InstructionDecoder.DecodeInstructions(message); + string aggregate = decodedInstructions.Aggregate( + "Message Decoded Instructions:", + (s, instruction) => + { + s += $"\n\tProgram: {instruction.ProgramName}\n\t\t\t Instruction: {instruction.InstructionName}\n"; + return instruction.Values.Aggregate( + s, + (current, entry) => + current + + $"\t\t\t\t{entry.Key} - {Convert.ChangeType(entry.Value, entry.Value.GetType())}\n"); + }); + Console.WriteLine(aggregate); + } + + /// + /// Logs the content of a transaction annd serializes it. + /// + /// + /// + public static byte[] LogTransactionAndSerialize(Transaction tx) + { + Console.WriteLine($"Tx FeePayer: {tx.FeePayer}"); + Console.WriteLine($"Tx BlockHash/Nonce: {tx.RecentBlockHash}"); + foreach (SignaturePubKeyPair signaturePubKeyPair in tx.Signatures) + { + Console.WriteLine( + $"Tx Signer: {signaturePubKeyPair.PublicKey} \tSignature: {Encoders.Base58.EncodeData(signaturePubKeyPair.Signature)}"); + } + + foreach (TransactionInstruction txInstruction in tx.Instructions) + { + Console.WriteLine( + $"Tx ProgramKey: {Encoders.Base58.EncodeData(txInstruction.ProgramId)}\n\tInstructionData: {Convert.ToBase64String(txInstruction.Data)}"); + foreach (AccountMeta accountMeta in txInstruction.Keys) + { + Console.WriteLine( + $"Tx \tAccountMeta: {accountMeta.PublicKey}\tWritable: {accountMeta.IsWritable}\tSigner: {accountMeta.IsSigner}"); + } + } + + return tx.Serialize(); + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/ExampleHelpers.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/ExampleHelpers.cs.meta new file mode 100644 index 0000000..c8c8a43 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/ExampleHelpers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2e5cf751b2cf60748af205cb057dd89e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/GetTokenAccountsByOwnerExample.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/GetTokenAccountsByOwnerExample.cs new file mode 100644 index 0000000..09393e3 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/GetTokenAccountsByOwnerExample.cs @@ -0,0 +1,58 @@ +using Solana.Unity.Rpc; +using Solana.Unity.Rpc.Core.Http; +using Solana.Unity.Rpc.Messages; +using Solana.Unity.Rpc.Models; +using Solana.Unity.Wallet; +using System; +using System.Collections.Generic; + +namespace Solana.Unity.Examples +{ + public class GetTokenAccountsByOwnerExample : IExample + { + private static readonly IRpcClient rpcClient = ClientFactory.GetClient(Cluster.TestNet); + private static readonly IRpcClient mRpcClient = ClientFactory.GetClient(Cluster.MainNet); + private const string MnemonicWords = + "route clerk disease box emerge airport loud waste attitude film army tray " + + "forward deal onion eight catalog surface unit card window walnut wealth medal"; + + public GetTokenAccountsByOwnerExample() + { + } + + public void Run() + { + Wallet.Wallet wallet = new Wallet.Wallet(MnemonicWords); + Account ownerAccount = wallet.GetAccount(10); + RequestResult>> token_accounts = rpcClient.GetTokenAccountsByOwner(ownerAccount.PublicKey, tokenProgramId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"); + + foreach (TokenAccount account in token_accounts.Result.Value) + { + Console.WriteLine( + $"Account: {account.PublicKey} - Mint: {account.Account.Data.Parsed.Info.Mint} - Balance: {account.Account.Data.Parsed.Info.TokenAmount.UiAmountString}"); + } + + var tokAccount = new PublicKey("CuieVDEDtLo7FypA9SbLM9saXFdb1dsshEkyErMqkRQq"); + var tokenAccounts = mRpcClient.GetTokenAccountsByOwner(tokAccount, tokenProgramId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"); + + foreach (TokenAccount account in tokenAccounts.Result.Value) + { + Console.WriteLine(account.Account.Data.Parsed.Info.DelegatedAmount == null ? + $"Account: {account.PublicKey} - Mint: {account.Account.Data.Parsed.Info.Mint} - TokenBalance: {account.Account.Data.Parsed.Info.TokenAmount.UiAmountString}" : + $"Account: {account.PublicKey} - Mint: {account.Account.Data.Parsed.Info.Mint} - TokenBalance: {account.Account.Data.Parsed.Info.TokenAmount.UiAmountString}" + + $" - Delegate: {account.Account.Data.Parsed.Info.Delegate} - DelegatedBalance: {account.Account.Data.Parsed.Info.DelegatedAmount.UiAmountString}"); + } + + var delegateKey = new PublicKey("4Nd1mBQtrMJVYVfKf2PJy9NZUZdTAsp7D4xWLs4gDB4T"); + var delegateTokenAccounts = mRpcClient.GetTokenAccountsByDelegate(delegateKey, "StepAscQoEioFxxWGnh2sLBDFp9d8rvKz2Yp39iDpyT"); + + foreach (TokenAccount account in delegateTokenAccounts.Result.Value) + { + Console.WriteLine(account.Account.Data.Parsed.Info.DelegatedAmount == null ? + $"Account: {account.PublicKey} - Mint: {account.Account.Data.Parsed.Info.Mint} - TokenBalance: {account.Account.Data.Parsed.Info.TokenAmount.UiAmountString}" : + $"Account: {account.PublicKey} - Mint: {account.Account.Data.Parsed.Info.Mint} - TokenBalance: {account.Account.Data.Parsed.Info.TokenAmount.UiAmountString}" + + $" - Delegate: {account.Account.Data.Parsed.Info.Delegate} - DelegatedBalance: {account.Account.Data.Parsed.Info.DelegatedAmount.UiAmountString}"); + } + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/GetTokenAccountsByOwnerExample.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/GetTokenAccountsByOwnerExample.cs.meta new file mode 100644 index 0000000..facc57f --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/GetTokenAccountsByOwnerExample.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 38188588b283c26468dd16315f612e83 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/HelloWorldExample.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/HelloWorldExample.cs new file mode 100644 index 0000000..13a4933 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/HelloWorldExample.cs @@ -0,0 +1,63 @@ +using Solana.Unity.Programs; +using Solana.Unity.Rpc; +using Solana.Unity.Rpc.Builders; +using Solana.Unity.Wallet; +using Solana.Unity.Wallet.Bip39; +using System; + +namespace Solana.Unity.Examples +{ + public class HelloWorldExample : IExample + { + public void Run() + { + var wallet = new Wallet.Wallet(WordCount.TwentyFour, WordList.English); + + Console.WriteLine("Hello World!"); + Console.WriteLine($"Mnemonic: {wallet.Mnemonic}"); + Console.WriteLine($"PubKey: {wallet.Account.PublicKey.Key}"); + Console.WriteLine($"PrivateKey: {wallet.Account.PrivateKey.Key}"); + + IRpcClient rpcClient = ClientFactory.GetClient(Cluster.TestNet); + + var balance = rpcClient.GetBalance(wallet.Account.PublicKey); + + Console.WriteLine($"Balance: {balance.Result.Value}"); + + var transactionHash = rpcClient.RequestAirdrop(wallet.Account.PublicKey, 100_000_000); + + Console.WriteLine($"TxHash: {transactionHash.Result}"); + + IStreamingRpcClient streamingRpcClient = ClientFactory.GetStreamingClient(Cluster.TestNet); + + streamingRpcClient.ConnectAsync().Wait(); + + var subscription = streamingRpcClient.SubscribeSignature(transactionHash.Result, (sub, data) => + { + if (data.Value.Error == null) + { + balance = rpcClient.GetBalance(wallet.Account.PublicKey); + + Console.WriteLine($"Balance: {balance.Result.Value}"); + + var memoInstruction = MemoProgram.NewMemoV2("Hello Solana World, using Solana.Unity :)"); + + var recentHash = rpcClient.GetRecentBlockHash(); + + var tx = new TransactionBuilder().AddInstruction(memoInstruction).SetFeePayer(wallet.Account) + .SetRecentBlockHash(recentHash.Result.Value.Blockhash).Build(wallet.Account); + + var txHash = rpcClient.SendTransaction(tx); + + Console.WriteLine($"TxHash: {txHash.Result}"); + } + else + { + Console.WriteLine($"Transaction error: {data.Value.Error.Type}"); + } + }); + + Console.ReadLine(); + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/HelloWorldExample.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/HelloWorldExample.cs.meta new file mode 100644 index 0000000..db0766e --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/HelloWorldExample.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b9435adad21fa9646a76881fdb2a175b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/IExample.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/IExample.cs new file mode 100644 index 0000000..6d1aa0d --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/IExample.cs @@ -0,0 +1,7 @@ +namespace Solana.Unity.Examples +{ + interface IExample + { + void Run(); + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/IExample.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/IExample.cs.meta new file mode 100644 index 0000000..ed7ff9f --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/IExample.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 84d9d96547af05147a21f04ac6e6f66a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/InstructionDecoderExample.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/InstructionDecoderExample.cs new file mode 100644 index 0000000..4a35630 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/InstructionDecoderExample.cs @@ -0,0 +1,107 @@ +using Solana.Unity.Programs; +using Solana.Unity.Rpc; +using Solana.Unity.Rpc.Builders; +using Solana.Unity.Rpc.Models; +using System; +using System.IO; +using System.Linq; + +namespace Solana.Unity.Examples +{ + public class InstructionDecoderFromMessageExample : IExample + { + private static readonly IRpcClient rpcClient = ClientFactory.GetClient(Cluster.TestNet); + + private const string MnemonicWords = + "route clerk disease box emerge airport loud waste attitude film army tray " + + "forward deal onion eight catalog surface unit card window walnut wealth medal"; + + public void Run() + { + var wallet = new Wallet.Wallet(MnemonicWords); + + var fromAccount = wallet.GetAccount(10); + var toAccount = wallet.GetAccount(8); + + var blockHash = rpcClient.GetRecentBlockHash(); + Console.WriteLine($"BlockHash >> {blockHash.Result.Value.Blockhash}"); + + var msgBytes = new TransactionBuilder() + .SetRecentBlockHash(blockHash.Result.Value.Blockhash) + .SetFeePayer(fromAccount) + .AddInstruction(SystemProgram.Transfer(fromAccount.PublicKey, toAccount.PublicKey, 10000000)) + .AddInstruction(MemoProgram.NewMemo(fromAccount.PublicKey, "Hello from Sol.Net :)")) + .CompileMessage(); + + string msgBytesBs64 = Convert.ToBase64String(msgBytes); + Console.WriteLine($"Message Base64: {msgBytesBs64}\n"); + + Console.WriteLine("\t\t\t\tDECODING MESSAGE FROM WIRE FORMAT\n"); + Message msg = Message.Deserialize(msgBytes); + var decodedInstructions = InstructionDecoder.DecodeInstructions(msg); + + string aggregate = decodedInstructions.Aggregate( + "Decoded Instructions:", + (s, instruction) => + { + s += $"\n\tProgram: {instruction.ProgramName}\n\t\t\t Instruction: {instruction.InstructionName}\n"; + return instruction.Values.Aggregate( + s, + (current, entry) => + current + $"\t\t\t\t{entry.Key} - {Convert.ChangeType(entry.Value, entry.Value.GetType())}\n"); + }); + Console.WriteLine(aggregate); + } + } + + public class InstructionDecoderFromBlockExample : IExample + { + private static readonly IRpcClient rpcClient = ClientFactory.GetClient(Cluster.TestNet); + public void Run() + { + var blockList = new ulong[] { 87731252, 87731314 }; + foreach (var slot in blockList) + { + var block = rpcClient.GetBlock(slot); + File.WriteAllText($"./response{slot}.json", block.RawRpcResponse); + Console.WriteLine($"BlockHash >> {block.Result.Blockhash}"); + + Console.WriteLine($"\n\t\t\tDECODING INSTRUCTIONS FROM TRANSACTIONS IN BLOCK {block.Result.Blockhash}\n"); + + foreach (TransactionMetaInfo txMeta in block.Result.Transactions) + { + if (txMeta.Transaction.Message.Instructions.Length == 1 && "Vote111111111111111111111111111111111111111" == txMeta.Transaction.Message.AccountKeys[txMeta.Transaction.Message.Instructions[0].ProgramIdIndex]) continue; + if (txMeta.Transaction.Message.Instructions.Length < 2) continue; + Console.WriteLine($"\n\t\tDECODING INSTRUCTIONS FROM TRANSACTION {txMeta.Transaction.Signatures[0]}"); + + Console.WriteLine($"Instructions: {txMeta.Transaction.Message.Instructions.Length}"); + Console.WriteLine($"InnerInstructions: {txMeta.Meta.InnerInstructions.Length}"); + var decodedInstructions = InstructionDecoder.DecodeInstructions(txMeta); + + string aggregate = decodedInstructions.Aggregate( + $"\tInstructions", + (s, instruction) => + { + s += $"\n\tProgram: {instruction.ProgramName}\tKey: {instruction.PublicKey}\n\t\tInstruction: {instruction.InstructionName}\n"; + s = instruction.Values.Aggregate( + s, (current, entry) => + current + $"\t\t\t{entry.Key} - {Convert.ChangeType(entry.Value, entry.Value.GetType())}\n"); + if (instruction.InnerInstructions.Count > 0) + return instruction.InnerInstructions.Aggregate( + s += $"\t\tInnerInstructions", + (inner, innerInstruction) => + { + inner += $"\n\t\tCPI: {innerInstruction.ProgramName}\tKey: {innerInstruction.PublicKey}\n\t\t\tInstruction: {innerInstruction.InstructionName}\n"; + return innerInstruction.Values.Aggregate( + inner, (current, entry) => + current + $"\t\t\t\t{entry.Key} - {Convert.ChangeType(entry.Value, entry.Value.GetType())}\n"); + }); + return s; + }); + Console.WriteLine(aggregate); + } + + } + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/InstructionDecoderExample.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/InstructionDecoderExample.cs.meta new file mode 100644 index 0000000..984009f --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/InstructionDecoderExample.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ff1f7b06b55bc8a4085fb009c8cae5ac +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/MultisigExamples.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/MultisigExamples.cs new file mode 100644 index 0000000..573fb8f --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/MultisigExamples.cs @@ -0,0 +1,1049 @@ +using Solana.Unity.Programs; +using Solana.Unity.Programs.Models.TokenProgram; +using Solana.Unity.Rpc; +using Solana.Unity.Rpc.Builders; +using Solana.Unity.Rpc.Core.Http; +using Solana.Unity.Rpc.Messages; +using Solana.Unity.Rpc.Models; +using Solana.Unity.Wallet; +using System; +using System.Collections.Generic; + +namespace Solana.Unity.Examples +{ + /// + /// An example on how to use multisig accounts to control the mint of a token. + /// + public class CreateInitializeAndMintToMultiSigExample : IExample + { + private static readonly IRpcClient rpcClient = ClientFactory.GetClient(Cluster.TestNet); + + private const string MnemonicWords = + "route clerk disease box emerge airport loud waste attitude film army tray " + + "forward deal onion eight catalog surface unit card window walnut wealth medal"; + + public void Run() + { + Wallet.Wallet wallet = new Wallet.Wallet(MnemonicWords); + + RequestResult> blockHash = rpcClient.GetRecentBlockHash(); + + ulong minBalanceForExemptionMultiSig = + rpcClient.GetMinimumBalanceForRentExemption(TokenProgram.MultisigAccountDataSize).Result; + Console.WriteLine($"MinBalanceForRentExemption MultiSig >> {minBalanceForExemptionMultiSig}"); + ulong minBalanceForExemptionAcc = + rpcClient.GetMinimumBalanceForRentExemption(TokenProgram.TokenAccountDataSize).Result; + Console.WriteLine($"MinBalanceForRentExemption Account >> {minBalanceForExemptionAcc}"); + ulong minBalanceForExemptionMint = + rpcClient.GetMinimumBalanceForRentExemption(TokenProgram.MintAccountDataSize).Result; + Console.WriteLine($"MinBalanceForRentExemption Mint Account >> {minBalanceForExemptionMint}"); + + Account ownerAccount = wallet.GetAccount(10); + Account mintAccount = wallet.GetAccount(94224); + Account initialAccount = wallet.GetAccount(84224); + + Account multiSignature = wallet.GetAccount(2011); + + Account signerAccount1 = wallet.GetAccount(25100); + Account signerAccount2 = wallet.GetAccount(25101); + Account signerAccount3 = wallet.GetAccount(25102); + Account signerAccount4 = wallet.GetAccount(25103); + Account signerAccount5 = wallet.GetAccount(25104); + + byte[] msgData = new TransactionBuilder().SetRecentBlockHash(blockHash.Result.Value.Blockhash) + .SetFeePayer(ownerAccount) + .AddInstruction(SystemProgram.CreateAccount( + ownerAccount.PublicKey, + multiSignature, + minBalanceForExemptionMultiSig, + TokenProgram.MultisigAccountDataSize, + TokenProgram.ProgramIdKey)) + .AddInstruction(TokenProgram.InitializeMultiSignature( + multiSignature, + new List { signerAccount1, signerAccount2, signerAccount3, signerAccount4, signerAccount5 }, + 3)) + .AddInstruction(SystemProgram.CreateAccount( + ownerAccount.PublicKey, + mintAccount.PublicKey, + minBalanceForExemptionMint, + TokenProgram.MintAccountDataSize, + TokenProgram.ProgramIdKey)) + .AddInstruction(TokenProgram.InitializeMint( + mintAccount.PublicKey, + 10, + multiSignature)) + .AddInstruction(MemoProgram.NewMemo(ownerAccount, "Hello from Sol.Net")) + .CompileMessage(); + + Message msg = Examples.DecodeMessageFromWire(msgData); + + Console.WriteLine("\n\tPOPULATING TRANSACTION WITH SIGNATURES\t"); + Transaction tx = Transaction.Populate(msg, + new List + { + ownerAccount.Sign(msgData), + multiSignature.Sign(msgData), + mintAccount.Sign(msgData), + }); + + byte[] txBytes = Examples.LogTransactionAndSerialize(tx); + + string createMultiSigAndMintSignature = Examples.SubmitTxSendAndLog(txBytes); + Examples.PollConfirmedTx(createMultiSigAndMintSignature); + + blockHash = rpcClient.GetRecentBlockHash(); + + msgData = new TransactionBuilder().SetRecentBlockHash(blockHash.Result.Value.Blockhash) + .SetFeePayer(ownerAccount) + .AddInstruction(SystemProgram.CreateAccount( + ownerAccount, + initialAccount, + minBalanceForExemptionAcc, + TokenProgram.TokenAccountDataSize, + TokenProgram.ProgramIdKey)) + .AddInstruction(TokenProgram.InitializeAccount( + initialAccount.PublicKey, + mintAccount.PublicKey, + ownerAccount.PublicKey)) + .AddInstruction(TokenProgram.MintTo( + mintAccount.PublicKey, + initialAccount.PublicKey, + 25000, + multiSignature, + new List + { + signerAccount1, + signerAccount2, + signerAccount4 + })) + .AddInstruction(MemoProgram.NewMemo(ownerAccount, "Hello from Sol.Net")) + .CompileMessage(); + + msg = Examples.DecodeMessageFromWire(msgData); + + Console.WriteLine("\n\tPOPULATING TRANSACTION WITH SIGNATURES\t"); + tx = Transaction.Populate(msg, + new List + { + ownerAccount.Sign(msgData), + initialAccount.Sign(msgData), + signerAccount1.Sign(msgData), + signerAccount2.Sign(msgData), + signerAccount4.Sign(msgData), + }); + + txBytes = Examples.LogTransactionAndSerialize(tx); + + string mintToSignature = Examples.SubmitTxSendAndLog(txBytes); + Examples.PollConfirmedTx(mintToSignature); + } + } + + /// + /// An example on how to use multisig accounts to control the mint of a token. + /// + public class MintToCheckedMultisigExample : IExample + { + private static readonly IRpcClient rpcClient = ClientFactory.GetClient(Cluster.TestNet); + + private const string MnemonicWords = + "route clerk disease box emerge airport loud waste attitude film army tray " + + "forward deal onion eight catalog surface unit card window walnut wealth medal"; + + public void Run() + { + Wallet.Wallet wallet = new Wallet.Wallet(MnemonicWords); + + RequestResult> blockHash = rpcClient.GetRecentBlockHash(); + + ulong minBalanceForExemptionMultiSig = + rpcClient.GetMinimumBalanceForRentExemption(TokenProgram.MultisigAccountDataSize).Result; + Console.WriteLine($"MinBalanceForRentExemption MultiSig >> {minBalanceForExemptionMultiSig}"); + ulong minBalanceForExemptionAcc = + rpcClient.GetMinimumBalanceForRentExemption(TokenProgram.TokenAccountDataSize).Result; + Console.WriteLine($"MinBalanceForRentExemption Account >> {minBalanceForExemptionAcc}"); + ulong minBalanceForExemptionMint = + rpcClient.GetMinimumBalanceForRentExemption(TokenProgram.MintAccountDataSize).Result; + Console.WriteLine($"MinBalanceForRentExemption Mint Account >> {minBalanceForExemptionMint}"); + + Account ownerAccount = wallet.GetAccount(10); + Account mintAccount = wallet.GetAccount(94224); + Account initialAccount = wallet.GetAccount(84224); + + Account multiSignature = wallet.GetAccount(2011); + + Account signerAccount1 = wallet.GetAccount(25100); + Account signerAccount2 = wallet.GetAccount(25101); + Account signerAccount4 = wallet.GetAccount(25103); + + byte[] msgData = new TransactionBuilder().SetRecentBlockHash(blockHash.Result.Value.Blockhash) + .SetFeePayer(ownerAccount) + .AddInstruction(TokenProgram.MintToChecked( + mintAccount.PublicKey, + initialAccount.PublicKey, + multiSignature, + 25000, + 10, + new List + { + signerAccount1, + signerAccount2, + signerAccount4 + })) + .AddInstruction(MemoProgram.NewMemo(ownerAccount, "Hello from Sol.Net")) + .CompileMessage(); + + Message msg = Examples.DecodeMessageFromWire(msgData); + + Console.WriteLine("\n\tPOPULATING TRANSACTION WITH SIGNATURES\t"); + Transaction tx = Transaction.Populate(msg, + new List + { + ownerAccount.Sign(msgData), + signerAccount1.Sign(msgData), + signerAccount2.Sign(msgData), + signerAccount4.Sign(msgData), + }); + + byte[] txBytes = Examples.LogTransactionAndSerialize(tx); + + string mintToSignature = Examples.SubmitTxSendAndLog(txBytes); + Examples.PollConfirmedTx(mintToSignature); + } + } + + /// + /// An example on how to use multisig accounts to control a token account. + /// + public class TransferCheckedMultiSigExample : IExample + { + private static readonly IRpcClient rpcClient = ClientFactory.GetClient(Cluster.TestNet); + + private const string MnemonicWords = + "route clerk disease box emerge airport loud waste attitude film army tray " + + "forward deal onion eight catalog surface unit card window walnut wealth medal"; + + public void Run() + { + Wallet.Wallet wallet = new Wallet.Wallet(MnemonicWords); + + RequestResult> blockHash = rpcClient.GetRecentBlockHash(); + + ulong minBalanceForExemptionMultiSig = + rpcClient.GetMinimumBalanceForRentExemption(TokenProgram.MultisigAccountDataSize).Result; + Console.WriteLine($"MinBalanceForRentExemption MultiSig >> {minBalanceForExemptionMultiSig}"); + ulong minBalanceForExemptionAcc = + rpcClient.GetMinimumBalanceForRentExemption(TokenProgram.TokenAccountDataSize).Result; + Console.WriteLine($"MinBalanceForRentExemption Account >> {minBalanceForExemptionAcc}"); + ulong minBalanceForExemptionMint = + rpcClient.GetMinimumBalanceForRentExemption(TokenProgram.MintAccountDataSize).Result; + Console.WriteLine($"MinBalanceForRentExemption Mint Account >> {minBalanceForExemptionMint}"); + + Account ownerAccount = wallet.GetAccount(10); + Account mintAccount = wallet.GetAccount(94224); + Account initialAccount = wallet.GetAccount(84224); + + Account tokenAccountWithMultisigOwner = wallet.GetAccount(3042); + Account tokenMultiSignature = wallet.GetAccount(3043); + + // The signers for the token account + Account tokenAccountSigner1 = wallet.GetAccount(25280); + Account tokenAccountSigner2 = wallet.GetAccount(25281); + Account tokenAccountSigner3 = wallet.GetAccount(25282); + Account tokenAccountSigner4 = wallet.GetAccount(25283); + Account tokenAccountSigner5 = wallet.GetAccount(25284); + + // First we create a multi sig account to use as the token account authority + // In this same transaction we transfer tokens using TransferChecked from the initialAccount in the example above + // to the same token account we just finished creating + byte[] msgData = new TransactionBuilder().SetRecentBlockHash(blockHash.Result.Value.Blockhash) + .SetFeePayer(ownerAccount) + .AddInstruction(SystemProgram.CreateAccount( + ownerAccount.PublicKey, + tokenMultiSignature, + minBalanceForExemptionMultiSig, + TokenProgram.MultisigAccountDataSize, + TokenProgram.ProgramIdKey)) + .AddInstruction(TokenProgram.InitializeMultiSignature( + tokenMultiSignature, + new List + { + tokenAccountSigner1, + tokenAccountSigner2, + tokenAccountSigner3, + tokenAccountSigner4, + tokenAccountSigner5 + }, + 3)) + .AddInstruction(SystemProgram.CreateAccount( + ownerAccount.PublicKey, + tokenAccountWithMultisigOwner, + minBalanceForExemptionAcc, + TokenProgram.TokenAccountDataSize, + TokenProgram.ProgramIdKey)) + .AddInstruction(TokenProgram.InitializeAccount( + tokenAccountWithMultisigOwner, + mintAccount, + tokenMultiSignature)) + .AddInstruction(TokenProgram.TransferChecked( + initialAccount, + tokenAccountWithMultisigOwner, + 10000, 10, + ownerAccount, + mintAccount)) + .CompileMessage(); + + Message msg = Examples.DecodeMessageFromWire(msgData); + + Console.WriteLine("\n\tPOPULATING TRANSACTION WITH SIGNATURES\t"); + Transaction tx = Transaction.Populate(msg, + new List + { + ownerAccount.Sign(msgData), + tokenMultiSignature.Sign(msgData), + tokenAccountWithMultisigOwner.Sign(msgData), + }); + + byte[] txBytes = Examples.LogTransactionAndSerialize(tx); + + string signature = Examples.SubmitTxSendAndLog(txBytes); + Examples.PollConfirmedTx(signature); + + // After the previous transaction is confirmed we use TransferChecked to transfer tokens using the + // multi sig account back to the initial account + msgData = new TransactionBuilder().SetRecentBlockHash(blockHash.Result.Value.Blockhash) + .SetFeePayer(ownerAccount) + .AddInstruction(TokenProgram.Transfer( + tokenAccountWithMultisigOwner, + initialAccount, + 10000, + tokenMultiSignature, + new List() + { + tokenAccountSigner3, + tokenAccountSigner4, + tokenAccountSigner5 + })).CompileMessage(); + + msg = Examples.DecodeMessageFromWire(msgData); + + Console.WriteLine("\n\tPOPULATING TRANSACTION WITH SIGNATURES\t"); + tx = Transaction.Populate(msg, + new List + { + ownerAccount.Sign(msgData), + tokenAccountSigner3.Sign(msgData), + tokenAccountSigner4.Sign(msgData), + tokenAccountSigner5.Sign(msgData) + }); + + txBytes = Examples.LogTransactionAndSerialize(tx); + + signature = Examples.SubmitTxSendAndLog(txBytes); + Examples.PollConfirmedTx(signature); + } + } + + /// + /// An example on how to control the freeze authority of a token using multi signatures + /// + public class FreezeAuthorityExample : IExample + { + private static readonly IRpcClient rpcClient = ClientFactory.GetClient(Cluster.TestNet); + + private const string MnemonicWords = + "route clerk disease box emerge airport loud waste attitude film army tray " + + "forward deal onion eight catalog surface unit card window walnut wealth medal"; + + public void Run() + { + Wallet.Wallet wallet = new Wallet.Wallet(MnemonicWords); + + RequestResult> blockHash = rpcClient.GetRecentBlockHash(); + + ulong minBalanceForExemptionMultiSig = + rpcClient.GetMinimumBalanceForRentExemption(TokenProgram.MultisigAccountDataSize).Result; + Console.WriteLine($"MinBalanceForRentExemption MultiSig >> {minBalanceForExemptionMultiSig}"); + ulong minBalanceForExemptionAcc = + rpcClient.GetMinimumBalanceForRentExemption(TokenProgram.TokenAccountDataSize).Result; + Console.WriteLine($"MinBalanceForRentExemption Account >> {minBalanceForExemptionAcc}"); + ulong minBalanceForExemptionMint = + rpcClient.GetMinimumBalanceForRentExemption(TokenProgram.MintAccountDataSize).Result; + Console.WriteLine($"MinBalanceForRentExemption Mint Account >> {minBalanceForExemptionMint}"); + + Account ownerAccount = wallet.GetAccount(10); + Account mintAccount = wallet.GetAccount(94330); + Account initialAccount = wallet.GetAccount(84330); + + // the signers for the token mint + Account mintMultiSignature = wallet.GetAccount(10116); + Account mintSigner1 = wallet.GetAccount(251280); + Account mintSigner2 = wallet.GetAccount(251281); + Account mintSigner3 = wallet.GetAccount(251282); + Account mintSigner4 = wallet.GetAccount(251283); + Account mintSigner5 = wallet.GetAccount(251284); + + // The signers for the freeze account + Account freezeMultiSignature = wallet.GetAccount(3057); + Account freezeSigner1 = wallet.GetAccount(25410); + Account freezeSigner2 = wallet.GetAccount(25411); + Account freezeSigner3 = wallet.GetAccount(25412); + Account freezeSigner4 = wallet.GetAccount(25413); + Account freezeSigner5 = wallet.GetAccount(25414); + + // First we create a multi sig account to use as the token's freeze authority + byte[] msgData = new TransactionBuilder().SetRecentBlockHash(blockHash.Result.Value.Blockhash) + .SetFeePayer(ownerAccount) + .AddInstruction(SystemProgram.CreateAccount( + ownerAccount, + freezeMultiSignature, + minBalanceForExemptionMultiSig, + TokenProgram.MultisigAccountDataSize, + TokenProgram.ProgramIdKey)) + .AddInstruction(TokenProgram.InitializeMultiSignature( + freezeMultiSignature, + new List + { + freezeSigner1, + freezeSigner2, + freezeSigner3, + freezeSigner4, + freezeSigner5 + }, 3)) + .CompileMessage(); + + Message msg = Examples.DecodeMessageFromWire(msgData); + + Console.WriteLine("\n\tPOPULATING TRANSACTION WITH SIGNATURES\t"); + Transaction tx = Transaction.Populate(msg, + new List + { + ownerAccount.Sign(msgData), + freezeMultiSignature.Sign(msgData), + }); + + byte[] txBytes = Examples.LogTransactionAndSerialize(tx); + + string signature = Examples.SubmitTxSendAndLog(txBytes); + Examples.PollConfirmedTx(signature); + + blockHash = rpcClient.GetRecentBlockHash(); + + + // Then we create an account which will be the token's mint authority + // In this same transaction we initialize the token mint with said authorities + msgData = new TransactionBuilder().SetRecentBlockHash(blockHash.Result.Value.Blockhash) + .SetFeePayer(ownerAccount) + .AddInstruction(SystemProgram.CreateAccount( + ownerAccount, + mintMultiSignature, + minBalanceForExemptionMultiSig, + TokenProgram.MultisigAccountDataSize, + TokenProgram.ProgramIdKey)) + .AddInstruction(TokenProgram.InitializeMultiSignature( + mintMultiSignature, + new List + { + mintSigner1, + mintSigner2, + mintSigner3, + mintSigner4, + mintSigner5 + }, 3)) + .AddInstruction(SystemProgram.CreateAccount( + ownerAccount, + mintAccount, + minBalanceForExemptionMint, + TokenProgram.MintAccountDataSize, + TokenProgram.ProgramIdKey)) + .AddInstruction(TokenProgram.InitializeMint( + mintAccount, + 10, + mintMultiSignature, + freezeMultiSignature)) + .CompileMessage(); + + msg = Examples.DecodeMessageFromWire(msgData); + + Console.WriteLine("\n\tPOPULATING TRANSACTION WITH SIGNATURES\t"); + tx = Transaction.Populate(msg, + new List + { + ownerAccount.Sign(msgData), + mintMultiSignature.Sign(msgData), + mintAccount.Sign(msgData), + }); + + txBytes = Examples.LogTransactionAndSerialize(tx); + + signature = Examples.SubmitTxSendAndLog(txBytes); + Examples.PollConfirmedTx(signature); + + blockHash = rpcClient.GetRecentBlockHash(); + + // Here we mint tokens to an account using the mint authority multi sig + msgData = new TransactionBuilder().SetRecentBlockHash(blockHash.Result.Value.Blockhash) + .SetFeePayer(ownerAccount) + .AddInstruction(SystemProgram.CreateAccount( + ownerAccount, + initialAccount, + minBalanceForExemptionAcc, + TokenProgram.TokenAccountDataSize, + TokenProgram.ProgramIdKey)) + .AddInstruction(TokenProgram.InitializeAccount( + initialAccount, + mintAccount, + ownerAccount.PublicKey)) + .AddInstruction(TokenProgram.MintTo( + mintAccount, + initialAccount, + 25000, + mintMultiSignature, + new List + { + mintSigner1, + mintSigner2, + mintSigner4 + })) + .AddInstruction(MemoProgram.NewMemo(ownerAccount, "Hello from Sol.Net")) + .CompileMessage(); + + msg = Examples.DecodeMessageFromWire(msgData); + + Console.WriteLine("\n\tPOPULATING TRANSACTION WITH SIGNATURES\t"); + tx = Transaction.Populate(msg, + new List + { + ownerAccount.Sign(msgData), + initialAccount.Sign(msgData), + mintSigner1.Sign(msgData), + mintSigner2.Sign(msgData), + mintSigner4.Sign(msgData), + }); + + txBytes = Examples.LogTransactionAndSerialize(tx); + + signature = Examples.SubmitTxSendAndLog(txBytes); + Examples.PollConfirmedTx(signature); + + blockHash = rpcClient.GetRecentBlockHash(); + + // After doing this, we freeze the account to which we just minted tokens + // Notice how the signers used are different, because the `freezeAuthority` has different signers + msgData = new TransactionBuilder().SetRecentBlockHash(blockHash.Result.Value.Blockhash) + .SetFeePayer(ownerAccount) + .AddInstruction(TokenProgram.FreezeAccount( + initialAccount, + mintAccount, + freezeMultiSignature, + TokenProgram.ProgramIdKey, + new List + { + freezeSigner2, + freezeSigner3, + freezeSigner4, + })) + .AddInstruction(MemoProgram.NewMemo(ownerAccount, "Hello from Sol.Net")) + .CompileMessage(); + + msg = Examples.DecodeMessageFromWire(msgData); + + Console.WriteLine("\n\tPOPULATING TRANSACTION WITH SIGNATURES\t"); + tx = Transaction.Populate(msg, + new List + { + ownerAccount.Sign(msgData), + freezeSigner2.Sign(msgData), + freezeSigner3.Sign(msgData), + freezeSigner4.Sign(msgData), + }); + + txBytes = Examples.LogTransactionAndSerialize(tx); + + signature = Examples.SubmitTxSendAndLog(txBytes); + Examples.PollConfirmedTx(signature); + + blockHash = rpcClient.GetRecentBlockHash(); + + // Because we're actually cool people, we now thaw that same account and then set the authority to nothing + msgData = new TransactionBuilder().SetRecentBlockHash(blockHash.Result.Value.Blockhash) + .SetFeePayer(ownerAccount) + .AddInstruction(TokenProgram.ThawAccount( + initialAccount, + mintAccount, + freezeMultiSignature, + TokenProgram.ProgramIdKey, + new List + { + freezeSigner2, + freezeSigner3, + freezeSigner4, + })) + .AddInstruction(TokenProgram.SetAuthority( + mintAccount, + AuthorityType.FreezeAccount, + freezeMultiSignature, + null, + new List + { + freezeSigner2, + freezeSigner3, + freezeSigner4, + })) + .AddInstruction(MemoProgram.NewMemo(ownerAccount, "Hello from Sol.Net")) + .CompileMessage(); + + msg = Examples.DecodeMessageFromWire(msgData); + + Console.WriteLine("\n\tPOPULATING TRANSACTION WITH SIGNATURES\t"); + tx = Transaction.Populate(msg, + new List + { + ownerAccount.Sign(msgData), + freezeSigner2.Sign(msgData), + freezeSigner3.Sign(msgData), + freezeSigner4.Sign(msgData), + }); + + txBytes = Examples.LogTransactionAndSerialize(tx); + + signature = Examples.SubmitTxSendAndLog(txBytes); + Examples.PollConfirmedTx(signature); + } + } + + /// + /// Example of how to approve and revoke a delegate to transfer tokens using multisig + /// + public class ApproveCheckedMultisigExample : IExample + { + private static readonly IRpcClient rpcClient = ClientFactory.GetClient(Cluster.TestNet); + + private const string MnemonicWords = + "route clerk disease box emerge airport loud waste attitude film army tray " + + "forward deal onion eight catalog surface unit card window walnut wealth medal"; + + public void Run() + { + Wallet.Wallet wallet = new Wallet.Wallet(MnemonicWords); + + RequestResult> blockHash = rpcClient.GetRecentBlockHash(); + + ulong minBalanceForExemptionMultiSig = + rpcClient.GetMinimumBalanceForRentExemption(TokenProgram.MultisigAccountDataSize).Result; + Console.WriteLine($"MinBalanceForRentExemption MultiSig >> {minBalanceForExemptionMultiSig}"); + ulong minBalanceForExemptionAcc = + rpcClient.GetMinimumBalanceForRentExemption(TokenProgram.TokenAccountDataSize).Result; + Console.WriteLine($"MinBalanceForRentExemption Account >> {minBalanceForExemptionAcc}"); + ulong minBalanceForExemptionMint = + rpcClient.GetMinimumBalanceForRentExemption(TokenProgram.MintAccountDataSize).Result; + Console.WriteLine($"MinBalanceForRentExemption Mint Account >> {minBalanceForExemptionMint}"); + + Account ownerAccount = wallet.GetAccount(10); + Account delegateAccount = wallet.GetAccount(194330); + Account mintAccount = wallet.GetAccount(94330); + Account initialAccount = wallet.GetAccount(84330); + + // the token mint multisig + Account mintMultiSignature = wallet.GetAccount(10116); + + // the signers for the token mint authority multisig + Account mintSigner1 = wallet.GetAccount(251280); + Account mintSigner2 = wallet.GetAccount(251281); + Account mintSigner3 = wallet.GetAccount(251282); + Account mintSigner4 = wallet.GetAccount(251283); + Account mintSigner5 = wallet.GetAccount(251284); + + // The token account + Account tokenAccountWithMultisigOwner = wallet.GetAccount(4044); + // The multisig which is the token account authority + Account tokenMultiSignature = wallet.GetAccount(4045); + + // the signers for the token authority multisig + Account tokenAccountSigner1 = wallet.GetAccount(25490); + Account tokenAccountSigner2 = wallet.GetAccount(25491); + Account tokenAccountSigner3 = wallet.GetAccount(25492); + Account tokenAccountSigner4 = wallet.GetAccount(25493); + Account tokenAccountSigner5 = wallet.GetAccount(25494); + + byte[] msgData = new TransactionBuilder().SetRecentBlockHash(blockHash.Result.Value.Blockhash) + .SetFeePayer(ownerAccount) + .AddInstruction(SystemProgram.CreateAccount( + ownerAccount.PublicKey, + tokenMultiSignature, + minBalanceForExemptionMultiSig, + TokenProgram.MultisigAccountDataSize, + TokenProgram.ProgramIdKey)) + .AddInstruction(TokenProgram.InitializeMultiSignature( + tokenMultiSignature, + new List + { + tokenAccountSigner1, + tokenAccountSigner2, + tokenAccountSigner3, + tokenAccountSigner4, + tokenAccountSigner5 + }, + 3)) + .AddInstruction(MemoProgram.NewMemo(ownerAccount, "Hello from Sol.Net")) + .CompileMessage(); + + Message msg = Examples.DecodeMessageFromWire(msgData); + + Console.WriteLine("\n\tPOPULATING TRANSACTION WITH SIGNATURES\t"); + Transaction tx = Transaction.Populate(msg, + new List + { + ownerAccount.Sign(msgData), + tokenMultiSignature.Sign(msgData), + }); + + byte[] txBytes = Examples.LogTransactionAndSerialize(tx); + + string signature = Examples.SubmitTxSendAndLog(txBytes); + Examples.PollConfirmedTx(signature); + + blockHash = rpcClient.GetRecentBlockHash(); + + msgData = new TransactionBuilder().SetRecentBlockHash(blockHash.Result.Value.Blockhash) + .SetFeePayer(ownerAccount) + .AddInstruction(SystemProgram.CreateAccount( + ownerAccount.PublicKey, + tokenAccountWithMultisigOwner, + minBalanceForExemptionAcc, + TokenProgram.TokenAccountDataSize, + TokenProgram.ProgramIdKey)) + .AddInstruction(TokenProgram.InitializeAccount( + tokenAccountWithMultisigOwner, + mintAccount, + tokenMultiSignature)) + .AddInstruction(TokenProgram.MintTo( + mintAccount, + tokenAccountWithMultisigOwner, + 25000, + mintMultiSignature, + new List + { + mintSigner1, + mintSigner2, + mintSigner4 + })) + .AddInstruction(MemoProgram.NewMemo(ownerAccount, "Hello from Sol.Net")) + .CompileMessage(); + + msg = Examples.DecodeMessageFromWire(msgData); + + Console.WriteLine("\n\tPOPULATING TRANSACTION WITH SIGNATURES\t"); + tx = Transaction.Populate(msg, + new List + { + ownerAccount.Sign(msgData), + tokenAccountWithMultisigOwner.Sign(msgData), + mintSigner1.Sign(msgData), + mintSigner2.Sign(msgData), + mintSigner4.Sign(msgData), + }); + + txBytes = Examples.LogTransactionAndSerialize(tx); + + signature = Examples.SubmitTxSendAndLog(txBytes); + Examples.PollConfirmedTx(signature); + + blockHash = rpcClient.GetRecentBlockHash(); + + msgData = new TransactionBuilder().SetRecentBlockHash(blockHash.Result.Value.Blockhash) + .SetFeePayer(ownerAccount) + .AddInstruction(TokenProgram.ApproveChecked( + tokenAccountWithMultisigOwner, + delegateAccount, + 5000, + 10, + tokenMultiSignature, + mintAccount, + new List + { + tokenAccountSigner1, + tokenAccountSigner2, + tokenAccountSigner3, + })) + .AddInstruction(MemoProgram.NewMemo(ownerAccount, "Hello from Sol.Net")) + .CompileMessage(); + + msg = Examples.DecodeMessageFromWire(msgData); + + Console.WriteLine("\n\tPOPULATING TRANSACTION WITH SIGNATURES\t"); + tx = Transaction.Populate(msg, + new List + { + ownerAccount.Sign(msgData), + tokenAccountSigner1.Sign(msgData), + tokenAccountSigner2.Sign(msgData), + tokenAccountSigner3.Sign(msgData), + }); + + txBytes = Examples.LogTransactionAndSerialize(tx); + + signature = Examples.SubmitTxSendAndLog(txBytes); + Examples.PollConfirmedTx(signature); + + blockHash = rpcClient.GetRecentBlockHash(); + + + msgData = new TransactionBuilder().SetRecentBlockHash(blockHash.Result.Value.Blockhash) + .SetFeePayer(ownerAccount) + .AddInstruction(TokenProgram.TransferChecked( + tokenAccountWithMultisigOwner, + initialAccount, + 5000, + 10, + delegateAccount, + mintAccount)) + .AddInstruction(TokenProgram.Revoke( + tokenAccountWithMultisigOwner, + tokenMultiSignature, + new List + { + tokenAccountSigner1, + tokenAccountSigner2, + tokenAccountSigner3, + })) + .AddInstruction(MemoProgram.NewMemo(ownerAccount, "Hello from Sol.Net")) + .CompileMessage(); + + msg = Examples.DecodeMessageFromWire(msgData); + + Console.WriteLine("\n\tPOPULATING TRANSACTION WITH SIGNATURES\t"); + tx = Transaction.Populate(msg, + new List { + ownerAccount.Sign(msgData), + delegateAccount.Sign(msgData), + tokenAccountSigner1.Sign(msgData), + tokenAccountSigner2.Sign(msgData), + tokenAccountSigner3.Sign(msgData) + }); + + txBytes = Examples.LogTransactionAndSerialize(tx); + + signature = Examples.SubmitTxSendAndLog(txBytes); + Examples.PollConfirmedTx(signature); + + } + } + + /// + /// Example of how to mint and burn using multisigs + /// + public class SimpleMintToAndBurnCheckedMultisigExample : IExample + { + private static readonly IRpcClient rpcClient = ClientFactory.GetClient(Cluster.TestNet); + + private const string MnemonicWords = + "route clerk disease box emerge airport loud waste attitude film army tray " + + "forward deal onion eight catalog surface unit card window walnut wealth medal"; + + public void Run() + { + Wallet.Wallet wallet = new Wallet.Wallet(MnemonicWords); + + RequestResult> blockHash = rpcClient.GetRecentBlockHash(); + + ulong minBalanceForExemptionMultiSig = + rpcClient.GetMinimumBalanceForRentExemption(TokenProgram.MultisigAccountDataSize).Result; + Console.WriteLine($"MinBalanceForRentExemption MultiSig >> {minBalanceForExemptionMultiSig}"); + ulong minBalanceForExemptionAcc = + rpcClient.GetMinimumBalanceForRentExemption(TokenProgram.TokenAccountDataSize).Result; + Console.WriteLine($"MinBalanceForRentExemption Account >> {minBalanceForExemptionAcc}"); + ulong minBalanceForExemptionMint = + rpcClient.GetMinimumBalanceForRentExemption(TokenProgram.MintAccountDataSize).Result; + Console.WriteLine($"MinBalanceForRentExemption Mint Account >> {minBalanceForExemptionMint}"); + + Account ownerAccount = wallet.GetAccount(10); + Account mintAccount = wallet.GetAccount(94330); + Account initialAccount = wallet.GetAccount(84330); + + // the token mint multisig + Account mintMultiSignature = wallet.GetAccount(10116); + Account mintSigner1 = wallet.GetAccount(251280); + Account mintSigner2 = wallet.GetAccount(251281); + Account mintSigner3 = wallet.GetAccount(251282); + + // The token account + Account tokenAccountWithMultisigOwner = wallet.GetAccount(4044); + // The multisig which is the token account authority + Account tokenMultiSignature = wallet.GetAccount(4045); + + // the signers for the token authority multisig + Account tokenAccountSigner1 = wallet.GetAccount(25490); + Account tokenAccountSigner2 = wallet.GetAccount(25491); + Account tokenAccountSigner3 = wallet.GetAccount(25492); + Account tokenAccountSigner4 = wallet.GetAccount(25493); + Account tokenAccountSigner5 = wallet.GetAccount(25494); + + byte[] msgData = new TransactionBuilder().SetRecentBlockHash(blockHash.Result.Value.Blockhash) + .SetFeePayer(ownerAccount) + .AddInstruction(TokenProgram.MintToChecked( + mintAccount, + tokenAccountWithMultisigOwner, + mintMultiSignature, + 1_000_000_000, + 10, + new List() + { + mintSigner1, + mintSigner2, + mintSigner3 + })) + .AddInstruction(TokenProgram.BurnChecked( + mintAccount, + tokenAccountWithMultisigOwner, + tokenMultiSignature, + 500_000, + 10, + new List() + { + tokenAccountSigner1, + tokenAccountSigner2, + tokenAccountSigner3 + })) + .AddInstruction(MemoProgram.NewMemo(ownerAccount, "Hello from Sol.Net")) + .CompileMessage(); + + Message msg = Examples.DecodeMessageFromWire(msgData); + + Console.WriteLine("\n\tPOPULATING TRANSACTION WITH SIGNATURES\t"); + Transaction tx = Transaction.Populate(msg, + new List + { + ownerAccount.Sign(msgData), + mintSigner1.Sign(msgData), + mintSigner2.Sign(msgData), + mintSigner3.Sign(msgData), + tokenAccountSigner1.Sign(msgData), + tokenAccountSigner2.Sign(msgData), + tokenAccountSigner3.Sign(msgData), + }); + + byte[] txBytes = Examples.LogTransactionAndSerialize(tx); + + string signature = Examples.SubmitTxSendAndLog(txBytes); + Examples.PollConfirmedTx(signature); + + } + } + + /// + /// Example of how to close a multisig account + /// + public class BurnCheckedAndCloseAccountMultisigExample : IExample + { + private static readonly IRpcClient rpcClient = ClientFactory.GetClient(Cluster.TestNet); + + private const string MnemonicWords = + "route clerk disease box emerge airport loud waste attitude film army tray " + + "forward deal onion eight catalog surface unit card window walnut wealth medal"; + + public void Run() + { + Wallet.Wallet wallet = new Wallet.Wallet(MnemonicWords); + + RequestResult> blockHash = rpcClient.GetRecentBlockHash(); + + ulong minBalanceForExemptionMultiSig = + rpcClient.GetMinimumBalanceForRentExemption(TokenProgram.MultisigAccountDataSize).Result; + Console.WriteLine($"MinBalanceForRentExemption MultiSig >> {minBalanceForExemptionMultiSig}"); + ulong minBalanceForExemptionAcc = + rpcClient.GetMinimumBalanceForRentExemption(TokenProgram.TokenAccountDataSize).Result; + Console.WriteLine($"MinBalanceForRentExemption Account >> {minBalanceForExemptionAcc}"); + ulong minBalanceForExemptionMint = + rpcClient.GetMinimumBalanceForRentExemption(TokenProgram.MintAccountDataSize).Result; + Console.WriteLine($"MinBalanceForRentExemption Mint Account >> {minBalanceForExemptionMint}"); + + Account ownerAccount = wallet.GetAccount(10); + Account mintAccount = wallet.GetAccount(94330); + + // The multisig which is the token account authority + Account tokenAccountWithMultisigOwner = wallet.GetAccount(4044); + Account tokenMultiSignature = wallet.GetAccount(4045); + Account tokenAccountSigner1 = wallet.GetAccount(25490); + Account tokenAccountSigner2 = wallet.GetAccount(25491); + Account tokenAccountSigner3 = wallet.GetAccount(25492); + + // The account has balance so we'll burn it before + RequestResult> balance = + rpcClient.GetTokenAccountBalance(tokenAccountWithMultisigOwner.PublicKey); + + Console.WriteLine($"Account Balance >> {balance.Result.Value.UiAmountString}"); + + byte[] msgData = new TransactionBuilder().SetRecentBlockHash(blockHash.Result.Value.Blockhash) + .SetFeePayer(ownerAccount) + .AddInstruction(TokenProgram.BurnChecked( + mintAccount, + tokenAccountWithMultisigOwner, + tokenMultiSignature, + balance.Result.Value.AmountUlong, + 10, + new List() + { + tokenAccountSigner1, + tokenAccountSigner2, + tokenAccountSigner3 + })) + .AddInstruction(TokenProgram.CloseAccount( + tokenAccountWithMultisigOwner, + ownerAccount, + tokenMultiSignature, + TokenProgram.ProgramIdKey, + new List() + { + tokenAccountSigner1, + tokenAccountSigner2, + tokenAccountSigner3 + })) + .AddInstruction(MemoProgram.NewMemo(ownerAccount, "Hello from Sol.Net")) + .CompileMessage(); + + Message msg = Examples.DecodeMessageFromWire(msgData); + + Console.WriteLine("\n\tPOPULATING TRANSACTION WITH SIGNATURES\t"); + Transaction tx = Transaction.Populate(msg, + new List + { + ownerAccount.Sign(msgData), + tokenAccountSigner1.Sign(msgData), + tokenAccountSigner2.Sign(msgData), + tokenAccountSigner3.Sign(msgData), + }); + + byte[] txBytes = Examples.LogTransactionAndSerialize(tx); + + string signature = Examples.SubmitTxSendAndLog(txBytes); + Examples.PollConfirmedTx(signature); + + } + } + + public class GetMultiSignatureAccountExample : IExample + { + private static readonly IRpcClient rpcClient = ClientFactory.GetClient(Cluster.TestNet); + + private const string MnemonicWords = + "route clerk disease box emerge airport loud waste attitude film army tray " + + "forward deal onion eight catalog surface unit card window walnut wealth medal"; + + + public void Run() + { + Wallet.Wallet wallet = new Wallet.Wallet(MnemonicWords); + + // The multisig which is the token account authority + Account tokenMultiSignature = wallet.GetAccount(4045); + + var account = rpcClient.GetAccountInfo(tokenMultiSignature.PublicKey); + + var multiSigAccount = MultiSignatureAccount.Deserialize(Convert.FromBase64String(account.Result.Value.Data[0])); + + + } + } + +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/MultisigExamples.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/MultisigExamples.cs.meta new file mode 100644 index 0000000..87360d6 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/MultisigExamples.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 24b58ffa9d3448147bbcd54a11a3ffd3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/NameServiceClientExample.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/NameServiceClientExample.cs new file mode 100644 index 0000000..52511c6 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/NameServiceClientExample.cs @@ -0,0 +1,100 @@ +using Solana.Unity.Programs.Clients; +using Solana.Unity.Rpc; +using System; + +namespace Solana.Unity.Examples +{ + + public class NameServiceClientExample : IExample + { + public void Run() + { + var rpc = ClientFactory.GetClient(Cluster.MainNet); + var wrpc = ClientFactory.GetStreamingClient(Cluster.MainNet); + + var c = new NameServiceClient(rpc); + + var test1 = c.GetAddressFromNameAsync("bonfida.sol").Result; + if (test1.WasSuccessful) + { + Console.WriteLine($"Name: 'bonfida.sol' \t Address: {test1.ParsedResult.Header.Owner}"); + Console.WriteLine($"Account Contents: "); + Console.WriteLine("------------------------------------ BASE 64 ---------------------------------------"); + Console.WriteLine(System.Convert.ToBase64String(test1.ParsedResult.Value)); + Console.WriteLine("------------------------------------------------------------------------------------"); + Console.WriteLine("--------------------------- TENTATIVE UTF8 DECODING --------------------------------"); + Console.WriteLine(System.Text.Encoding.UTF8.GetString(test1.ParsedResult.Value)); + Console.WriteLine("------------------------------------------------------------------------------------"); + } + else + { + Console.WriteLine($"Unable to resolve name."); + } + + var test2 = c.GetNamesFromAddressAsync("BriW4tTAiAm541uB2Fua3dUNoGayRa8Wt7pZUshUbrPB").Result; + if (test2 != null && test2.Count > 0) + { + foreach (var item in test2) + { + Console.WriteLine($"Record Type: {item.Type} \t Name: {item.Name} \t Address: {item.AccountAddress} "); + } + } + + var test3 = c.GetAddressFromTwitterHandleAsync("bonfida").Result; + if (test3.WasSuccessful) + { + Console.WriteLine($"Twitter: '@bonfida' \t Address: {test3.ParsedResult.Header.Owner}"); + Console.WriteLine($"Account Contents: "); + Console.WriteLine("------------------------------------ BASE 64 ---------------------------------------"); + Console.WriteLine(System.Convert.ToBase64String(test3.ParsedResult.Value)); + Console.WriteLine("------------------------------------------------------------------------------------"); + Console.WriteLine("--------------------------- TENTATIVE UTF8 DECODING --------------------------------"); + Console.WriteLine(System.Text.Encoding.UTF8.GetString(test3.ParsedResult.Value)); + Console.WriteLine("------------------------------------------------------------------------------------"); + } + else + { + Console.WriteLine($"Unable to resolve name."); + } + + var test4 = c.GetTwitterHandleFromAddressAsync("FidaeBkZkvDqi1GXNEwB8uWmj9Ngx2HXSS5nyGRuVFcZ").Result; + if (test4.WasSuccessful) + { + Console.WriteLine($"Address: {test4.ParsedResult.Header.Owner} \t Twitter: {test4.ParsedResult.TwitterHandle}"); + } + else + { + Console.WriteLine($"Unable to resolve name."); + } + + var test5 = c.GetAllNamesByOwnerAsync("FidaeBkZkvDqi1GXNEwB8uWmj9Ngx2HXSS5nyGRuVFcZ").Result; + if (test5 != null && test5.Count > 0) + { + foreach (var item in test5) + { + Console.WriteLine($"Record Type: {item.Type} \t Address: {item.AccountAddress} \t Value: {item.GetValue()} "); + } + } + + var test6 = c.GetTokenInfoFromMintAsync("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v").Result; + if (test6.WasSuccessful) + { + Console.WriteLine($"Mint Address: {test6.ParsedResult.Value.Mint} \t Ticker: ${test6.ParsedResult.Value.Ticker} \t Name: {test6.ParsedResult.Value.Name} \t Name: {test6.ParsedResult.Value.Website}"); + } + else + { + Console.WriteLine($"Unable to resolve token mint."); + } + + var test7 = c.GetMintFromTokenTickerAsync("USDC").Result; + if (test7.WasSuccessful) + { + Console.WriteLine($"Ticker: ${test6.ParsedResult.Value.Ticker} \t Mint Address: {test7.ParsedResult.Value} \t "); + } + else + { + Console.WriteLine($"Unable to resolve token mint."); + } + } + } +} diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/NameServiceClientExample.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/NameServiceClientExample.cs.meta new file mode 100644 index 0000000..1491a00 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/NameServiceClientExample.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ad96ceb060db6a848a599635524c92b9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/NameServiceProgramExamples.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/NameServiceProgramExamples.cs new file mode 100644 index 0000000..8e6846a --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/NameServiceProgramExamples.cs @@ -0,0 +1,105 @@ +using Solana.Unity.Programs; +using Solana.Unity.Rpc; +using Solana.Unity.Rpc.Builders; +using Solana.Unity.Wallet; +using System; + +namespace Solana.Unity.Examples +{ + public class CreateNameRegistryProgramExamples : IExample + { + private static readonly IRpcClient rpcClient = ClientFactory.GetClient(Cluster.TestNet); + + private const string MnemonicWords = + "route clerk disease box emerge airport loud waste attitude film army tray " + + "forward deal onion eight catalog surface unit card window walnut wealth medal"; + + /// + /// The public key of the Twitter Verification Authority. + /// + public static readonly PublicKey TwitterVerificationAuthorityKey = new PublicKey("867BLob5b52i81SNaV9Awm5ejkZV6VGSv9SxLcwukDDJ"); + + /// + /// The public key of the Twitter Root Parent Registry. + /// + public static readonly PublicKey TwitterRootParentRegistryKey = new PublicKey("AFrGkxNmVLBn3mKhvfJJABvm8RJkTtRhHDoaF97pQZaA"); + + /// + /// Get the derived account address for the reverse lookup. + /// + /// The public key. + /// The derived account public key. + public static PublicKey GetReverseRegistryKey(string publicKey) + { + byte[] hashedName = NameServiceProgram.ComputeHashedName(publicKey); + PublicKey nameAccountKey = NameServiceProgram.DeriveNameAccountKey(hashedName, TwitterVerificationAuthorityKey, null); + return nameAccountKey; + } + + /// + /// Get the derived account address for the twitter handle registry. + /// + /// The twitter handle. + /// The derived account public key. + public static PublicKey GetTwitterHandleRegistryKey(string twitterHandle) + { + byte[] hashedName = NameServiceProgram.ComputeHashedName(twitterHandle); + PublicKey nameAccountKey = NameServiceProgram.DeriveNameAccountKey(hashedName, null, TwitterRootParentRegistryKey); + return nameAccountKey; + } + + public void Run() + { + var wallet = new Wallet.Wallet(MnemonicWords); + + var blockHash = rpcClient.GetRecentBlockHash(); + var minBalanceForExemptionNameAcc = + rpcClient.GetMinimumBalanceForRentExemption(NameServiceProgram.NameAccountSize + 96).Result; + + Console.WriteLine($"MinBalanceForRentExemption NameAccount >> {minBalanceForExemptionNameAcc}"); + var minBalanceForExemptionNameReverseRegistry = + rpcClient.GetMinimumBalanceForRentExemption(96 + 18).Result; + Console.WriteLine($"MinBalanceForRentExemption ReverseRegistry >> {minBalanceForExemptionNameReverseRegistry}"); + + var payerAccount = wallet.GetAccount(10); + var ownerAccount = wallet.GetAccount(152); + Console.WriteLine($"PayerAccount: {payerAccount.PublicKey.Key}"); + Console.WriteLine($"OwnerAccount: {ownerAccount.PublicKey.Key}"); + + var hashedTwitterHandle = NameServiceProgram.ComputeHashedName("hoaktrades"); + Console.WriteLine($"HashedTwitterHandle: {hashedTwitterHandle}"); + var twitterHandleRegistry = GetTwitterHandleRegistryKey("hoaktrades"); + Console.WriteLine($"TwitterHandleRegistryKey: {twitterHandleRegistry.Key}"); + var hashedVerifiedPubkey = NameServiceProgram.ComputeHashedName(ownerAccount.PublicKey.Key); + Console.WriteLine($"HashedVerifiedKey: {hashedVerifiedPubkey}"); + var reverseRegistry = GetReverseRegistryKey(ownerAccount.PublicKey.Key); + Console.WriteLine($"ReverseRegistryKey: {reverseRegistry.Key}"); + + var tx = new TransactionBuilder().SetRecentBlockHash(blockHash.Result.Value.Blockhash) + .SetFeePayer(payerAccount).AddInstruction( + NameServiceProgram.CreateNameRegistry( + twitterHandleRegistry, + payerAccount, + ownerAccount.PublicKey, + minBalanceForExemptionNameReverseRegistry, + NameServiceProgram.NameAccountSize + 96) + ).AddInstruction( + NameServiceProgram.UpdateNameRegistry( + reverseRegistry, + 125, + new byte[] { 0, 0, 1, 1 }, + ownerAccount.PublicKey, + (PublicKey)"8ZhEweTBhjTVzuRyoJteCqNU7AiHdpYTfreD1y9FvoFu") + ).AddInstruction(MemoProgram.NewMemo(payerAccount, "Hello from Sol.Net")).CompileMessage(); + + Console.WriteLine($"Tx: {Convert.ToBase64String(tx)}"); + + var txSim = rpcClient.SimulateTransaction(tx); + var logs = Examples.PrettyPrintTransactionSimulationLogs(txSim.Result.Value.Logs); + Console.WriteLine($"Transaction Simulation:\n\tError: {txSim.Result.Value.Error}\n\tLogs: \n" + logs); + + var txReq = rpcClient.SendTransaction(tx); + Console.WriteLine($"Tx Signature: {txReq.Result}"); + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/NameServiceProgramExamples.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/NameServiceProgramExamples.cs.meta new file mode 100644 index 0000000..cef2893 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/NameServiceProgramExamples.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c3b3dbf7aafd9774d991ee8e9ce79d4f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/Solana.Unity.Examples.csproj.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/Solana.Unity.Examples.csproj.meta new file mode 100644 index 0000000..c54c6e1 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/Solana.Unity.Examples.csproj.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 9e57ec76cfe872f49ad0b56526f617d2 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/SolanaKeygenKeyGeneration.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/SolanaKeygenKeyGeneration.cs new file mode 100644 index 0000000..683473a --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/SolanaKeygenKeyGeneration.cs @@ -0,0 +1,34 @@ +using Solana.Unity.Wallet; +using Solana.Unity.Wallet.Bip39; +using System; + +namespace Solana.Unity.Examples +{ + public class SolanaKeygenWallet : IExample + { + public void Run() + { + const string expectedSolKeygenPublicKey = "AZzmpdbZWARkPzL8GKRHjjwY74st4URgk9v7QBubeWba"; + const string expectedSolKeygenPrivateKey = "2RitwnKZwoigHk9S3ftvFQhoTy5QQKAipNjZHDgCet8hyciUbJSuhMWDKRL8JKE784pK8jJPFaNerFsS6KXhY9K6"; + + // mnemonic and passphrase to derive seed + var passphrase = "thisiseightbytesithink"; + var mnemonic = new Mnemonic("route clerk disease box emerge airport loud waste attitude film army tray forward deal onion eight catalog surface unit card window walnut wealth medal", WordList.English); + + var solKeygenWallet = new Wallet.Wallet(mnemonic, passphrase, SeedMode.Bip39); + + Console.WriteLine($"SOLLET publicKey>b58 {solKeygenWallet.Account.PublicKey}"); + Console.WriteLine($"SOLLET privateKey>b58 {solKeygenWallet.Account.PrivateKey.Key}"); + + if (solKeygenWallet.Account.PublicKey.Key != expectedSolKeygenPublicKey || solKeygenWallet.Account.PrivateKey.Key != expectedSolKeygenPrivateKey) + { + Console.WriteLine("NOT GOOD FOR THE SOL"); + } + else + { + Console.WriteLine("GOOD FOR THE SOL"); + } + + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/SolanaKeygenKeyGeneration.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/SolanaKeygenKeyGeneration.cs.meta new file mode 100644 index 0000000..599fdfc --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/SolanaKeygenKeyGeneration.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 330f32be3695a324ea981cce4a9a865f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/SolletKeyGeneration.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/SolletKeyGeneration.cs new file mode 100644 index 0000000..adfecd6 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/SolletKeyGeneration.cs @@ -0,0 +1,45 @@ +using Solana.Unity.Wallet.Bip39; +using System; +using System.Collections.Generic; + +namespace Solana.Unity.Examples +{ + public class SolletKeyGeneration : IExample + { + public void Run() + { + var expectedSolletAddresses = new List + { + new []{"6bhhceZToGG9RsTe1nfNFXEMjavhj6CV55EsvearAt2z", "5S1UT7L6bQ8sVaPjpJyYFEEYh8HAXRXPFUEuj6kHQXs6ZE9F6a2wWrjdokAmSPP5HVP46bYxsrU8yr2FxxYmVBi6"}, + new []{"9we6kjtbcZ2vy3GSLLsZTEhbAqXPTRvEyoxa8wxSqKp5", "22J7rH3DFJb1yz8JuWUWfrpsQrNsvZKov8sznfwHbPGTznSgQ8u6LQ6KixPC2mYCJDsfzME1FbdX1x89zKq4MU3K"}, + new []{"3F2RNf2f2kWYgJ2XsqcjzVeh3rsEQnwf6cawtBiJGyKV", "5954a6aMxVnPTyMNdVKrSiqoVMRvZcwU7swGp9kHsV9HP9Eu81TebS4Mbq5ZGmZwUaJkkKoCJ2eJSY9cTdWzRXeF"}, + new []{"GyWQGKYpvzFmjhnG5Pfw9jfvgDM7LB31HnTRPopCCS9", "tUV1EeY6CARAbuEfVqKS46X136PRBea8PcmYfHRWNQc6yYB14GkSBZ6PTybUt5W14A7FSJ6Mm6NN22fLhUhDUGu"}, + new []{"GjtWSPacUQFVShQKRKPc342MLCdNiusn3WTJQKxuDfXi", "iLtErFEn6w5xbsUW63QLYMTJeX8TAgFTUDTgat3gxpaiN3AJbebv6ybtmTj1t1yvkqqY2k1uwFxaKZoCQAPcDZe"}, + new []{"DjGCyxjGxpvEo921Ad4tUUWquiRG6dziJUCk8HKZoaKK", "3uvEiJiMyXqQmELLjxV8r3E7CyRFg42LUAxzz6q7fPhzTCxCzPkaMCQ9ARpWYDNiDXhue2Uma1C7KR9AkiiWUS8y"}, + new []{"HU6aKFapq4RssJqV96rfE7vv1pepz5A5miPAMxGFso4X", "4xFZDEhhw3oVewE3UCvzLmhRWjjcqvVMxuYiETWiyaV2wJwEJ4ceDDE359NMirh43VYisViHAwsXjZ3F9fk6dAxB"}, + new []{"HunD57AAvhBiX2SxmEDMbrgQ9pcqrtRyWKy7dWPEWYkJ", "2Z5CFuVDPQXxrB3iw5g6SAnKqApE1djAqtTZDA83rLZ1NDi6z13rwDX17qdyUDCxK9nDwKAHdVuy3h6jeXspcYxA"}, + new []{"9KmfMX4Ne5ocb8C7PwjmJTWTpQTQcPhkeD2zY35mawhq", "c1BzdtL4RByNQnzcaUq3WuNLuyY4tQogGT7JWwy4YGBE8FGSgWUH8eNJFyJgXNYtwTKq4emhC4V132QX9REwujm"}, + new []{"7MrtfwpJBw2hn4eopB2CVEKR1kePJV5kKmKX3wUAFsJ9", "4skUmBVmaLoriN9Ge8xcF4xQFJmF554rnRRa2u1yDbre2zj2wUpgCXUaPETLSAWNudCkNAkWM5oJFJRaeZY1g9JR"} + }; + + // mnemonic and passphrase to derive seed + var mnemonic = new Mnemonic("route clerk disease box emerge airport loud waste attitude film army tray forward deal onion eight catalog surface unit card window walnut wealth medal", WordList.English); + + // The passphrase isn't used to harden the mnemonic in this case. + var solletWallet = new Wallet.Wallet(mnemonic); + var flag = true; + + // Mimic sollet key generation + for (int i = 0; i < 10; i++) + { + var account = solletWallet.GetAccount(i); + + Console.WriteLine($"SOLLET publicKey>b58 {account.PublicKey}"); + Console.WriteLine($"SOLLET privateKey>b58 {account.PrivateKey}"); + + if (account.PublicKey.Key != expectedSolletAddresses[i][0] || account.PrivateKey.Key != expectedSolletAddresses[i][1]) flag = false; + } + Console.WriteLine(flag ? "GOOD FOR THE SOLLET" : "NOT GOOD FOR THE SOLLET"); + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/SolletKeyGeneration.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/SolletKeyGeneration.cs.meta new file mode 100644 index 0000000..24fdd24 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/SolletKeyGeneration.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ab86623236223994aaebca091988e5af +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/SolletKeygenKeystore.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/SolletKeygenKeystore.cs new file mode 100644 index 0000000..615e7d5 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/SolletKeygenKeystore.cs @@ -0,0 +1,84 @@ +using Solana.Unity.KeyStore; +using Solana.Unity.Wallet; +using Solana.Unity.Wallet.Bip39; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Solana.Unity.Examples +{ + public class SolletKeygenKeystore : IExample + { + public void Run() + { + var expectedSolletAddresses = new List + { + new []{"6bhhceZToGG9RsTe1nfNFXEMjavhj6CV55EsvearAt2z", "5S1UT7L6bQ8sVaPjpJyYFEEYh8HAXRXPFUEuj6kHQXs6ZE9F6a2wWrjdokAmSPP5HVP46bYxsrU8yr2FxxYmVBi6"}, + new []{"9we6kjtbcZ2vy3GSLLsZTEhbAqXPTRvEyoxa8wxSqKp5", "22J7rH3DFJb1yz8JuWUWfrpsQrNsvZKov8sznfwHbPGTznSgQ8u6LQ6KixPC2mYCJDsfzME1FbdX1x89zKq4MU3K"}, + new []{"3F2RNf2f2kWYgJ2XsqcjzVeh3rsEQnwf6cawtBiJGyKV", "5954a6aMxVnPTyMNdVKrSiqoVMRvZcwU7swGp9kHsV9HP9Eu81TebS4Mbq5ZGmZwUaJkkKoCJ2eJSY9cTdWzRXeF"}, + new []{"GyWQGKYpvzFmjhnG5Pfw9jfvgDM7LB31HnTRPopCCS9", "tUV1EeY6CARAbuEfVqKS46X136PRBea8PcmYfHRWNQc6yYB14GkSBZ6PTybUt5W14A7FSJ6Mm6NN22fLhUhDUGu"}, + new []{"GjtWSPacUQFVShQKRKPc342MLCdNiusn3WTJQKxuDfXi", "iLtErFEn6w5xbsUW63QLYMTJeX8TAgFTUDTgat3gxpaiN3AJbebv6ybtmTj1t1yvkqqY2k1uwFxaKZoCQAPcDZe"}, + new []{"DjGCyxjGxpvEo921Ad4tUUWquiRG6dziJUCk8HKZoaKK", "3uvEiJiMyXqQmELLjxV8r3E7CyRFg42LUAxzz6q7fPhzTCxCzPkaMCQ9ARpWYDNiDXhue2Uma1C7KR9AkiiWUS8y"}, + new []{"HU6aKFapq4RssJqV96rfE7vv1pepz5A5miPAMxGFso4X", "4xFZDEhhw3oVewE3UCvzLmhRWjjcqvVMxuYiETWiyaV2wJwEJ4ceDDE359NMirh43VYisViHAwsXjZ3F9fk6dAxB"}, + new []{"HunD57AAvhBiX2SxmEDMbrgQ9pcqrtRyWKy7dWPEWYkJ", "2Z5CFuVDPQXxrB3iw5g6SAnKqApE1djAqtTZDA83rLZ1NDi6z13rwDX17qdyUDCxK9nDwKAHdVuy3h6jeXspcYxA"}, + new []{"9KmfMX4Ne5ocb8C7PwjmJTWTpQTQcPhkeD2zY35mawhq", "c1BzdtL4RByNQnzcaUq3WuNLuyY4tQogGT7JWwy4YGBE8FGSgWUH8eNJFyJgXNYtwTKq4emhC4V132QX9REwujm"}, + new []{"7MrtfwpJBw2hn4eopB2CVEKR1kePJV5kKmKX3wUAFsJ9", "4skUmBVmaLoriN9Ge8xcF4xQFJmF554rnRRa2u1yDbre2zj2wUpgCXUaPETLSAWNudCkNAkWM5oJFJRaeZY1g9JR"} + }; + const string _password = "password"; + const string mnemonicWords = + "route clerk disease box emerge airport loud waste attitude film army tray forward deal onion eight catalog surface unit card window walnut wealth medal"; + + var mnemonic = new Mnemonic(mnemonicWords, WordList.English); + + var keystoreService = new SecretKeyStoreService(); + + // no passphrase to generate same keys as sollet + var wallet = new Wallet.Wallet(mnemonic); + var seed = wallet.DeriveMnemonicSeed(); + Account account = null; + bool flag = true; // to check if the keys are the expected ones + Console.WriteLine($"Seed: {Encoding.Default.GetString(seed)}\nAddress: {wallet.Account.PublicKey}"); + + /* 1. Encrypt mnemonic derived seed and generate keystore as json + var keystoreJson = keystoreService.EncryptAndGenerateDefaultKeyStoreAsJson(_password, seed, wallet.Account.EncodedPublicKey); + */ + + /* 2. Encrypt the mnemonic as bytes */ + var stringByteArray = Encoding.UTF8.GetBytes(mnemonic.ToString()); + var encryptedKeystoreJson = keystoreService.EncryptAndGenerateDefaultKeyStoreAsJson(_password, stringByteArray, wallet.Account.PublicKey.Key); + + var keystoreJsonAddr = SecretKeyStoreService.GetAddressFromKeyStore(encryptedKeystoreJson); + + Console.WriteLine($"Keystore JSON: {encryptedKeystoreJson}\nKeystore Address: {keystoreJsonAddr}"); + + /* 1. Decrypt mnemonic derived seed and generate wallet from it + var decryptedKeystore = keystoreService.DecryptKeyStoreFromJson(_password, keystoreJson); + */ + + /* 2. Decrypt the mnemonic as bytes */ + var decryptedKeystore = keystoreService.DecryptKeyStoreFromJson(_password, encryptedKeystoreJson); + var mnemonicString = Encoding.UTF8.GetString(decryptedKeystore); + + /* 2. Restore the wallet from the restored mnemonic */ + var restoredMnemonic = new Mnemonic(mnemonicString); + var restoredWallet = new Wallet.Wallet(restoredMnemonic); + + // no passphrase to generate same keys as sollet + //var restoredWallet = new Wallet.Wallet(decryptedKeystore); + var restoredSeed = restoredWallet.DeriveMnemonicSeed(); + + Console.WriteLine($"Seed: {Encoding.Default.GetString(restoredSeed)}"); + + // Mimic sollet key generation + for (int i = 0; i < 10; i++) + { + account = restoredWallet.GetAccount(i); + + Console.WriteLine($"RESTORED SOLLET address {account.PublicKey}"); + + if (account.PublicKey.Key != expectedSolletAddresses[i][0] || account.PrivateKey.Key != expectedSolletAddresses[i][1]) flag = false; + } + Console.WriteLine(flag ? "GOOD RESTORE FOR THE SOLLET" : "NOT GOOD RESTORE FOR THE SOLLET"); + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/SolletKeygenKeystore.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/SolletKeygenKeystore.cs.meta new file mode 100644 index 0000000..c72c1a6 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/SolletKeygenKeystore.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 77d03474c2da6844cb3aafa6c7350337 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/StakeExample.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/StakeExample.cs new file mode 100644 index 0000000..40ee6b8 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/StakeExample.cs @@ -0,0 +1,288 @@ +using Solana.Unity.Programs; +using Solana.Unity.Rpc; +using Solana.Unity.Rpc.Builders; +using Solana.Unity.Rpc.Core.Http; +using Solana.Unity.Rpc.Messages; +using Solana.Unity.Rpc.Models; +using Solana.Unity.Wallet; +using System; +using System.Collections.Generic; +using static Solana.Unity.Programs.Models.Stake.State; +using Solana.Unity.Wallet.Bip39; +using Solana.Unity.Wallet.Utilities; + +namespace Solana.Unity.Examples +{ + public class CreateAccountFromSeedExample : IExample + { + private static readonly IRpcClient rpcClient = ClientFactory.GetClient(Cluster.TestNet); + + private const string MnemonicWords = + "clerk shoe noise umbrella apple gold alien swap desert rubber truck okay twenty fiscal near talent drastic present leg put balcony leader access glimpse"; + public void Run() + { + var wallet = new Wallet.Wallet(new Mnemonic(MnemonicWords)); + rpcClient.RequestAirdrop(wallet.Account.PublicKey, 100_000_000); + RequestResult> blockHash = rpcClient.GetRecentBlockHash(); + ulong minBalance = rpcClient.GetMinimumBalanceForRentExemption(StakeProgram.StakeAccountDataSize).Result; + Account fromAccount = wallet.Account; + PublicKey.TryCreateWithSeed(fromAccount.PublicKey, "yrdy1", StakeProgram.ProgramIdKey, out PublicKey stakeAccount); + Console.WriteLine($"BlockHash >> {blockHash.Result.Value.Blockhash}"); + + byte[] tx = new TransactionBuilder() + .SetRecentBlockHash(blockHash.Result.Value.Blockhash) + .SetFeePayer(fromAccount) + .AddInstruction(SystemProgram.CreateAccountWithSeed( + fromAccount, + stakeAccount, + fromAccount, + "yrdy1", + 3 * minBalance, + 200, + StakeProgram.ProgramIdKey)) + .Build(new List { fromAccount }); + Console.WriteLine($"Tx base64: {Convert.ToBase64String(tx)}"); + RequestResult> txSim = rpcClient.SimulateTransaction(tx); + + string logs = Examples.PrettyPrintTransactionSimulationLogs(txSim.Result.Value.Logs); + Console.WriteLine($"Transaction Simulation:\n\tError: {txSim.Result.Value.Error}\n\tLogs: \n" + logs); + RequestResult firstSig = rpcClient.SendTransaction(tx, skipPreflight: true); + Console.WriteLine($"First Tx Result: {firstSig.Result}"); + } + } + public class AuthorizeWithSeedExample : IExample + { + private static readonly IRpcClient rpcClient = ClientFactory.GetClient(Cluster.TestNet); + + private const string MnemonicWords = + "clerk shoe noise umbrella apple gold alien swap desert rubber truck okay twenty fiscal near talent drastic present leg put balcony leader access glimpse"; + public void Run() + { + var wallet = new Wallet.Wallet(new Mnemonic(MnemonicWords)); + var seed = wallet.DeriveMnemonicSeed(); + var b58 = new Base58Encoder(); + string f = b58.EncodeData(seed); + rpcClient.RequestAirdrop(wallet.Account.PublicKey, 100_000_000); + RequestResult> blockHash = rpcClient.GetRecentBlockHash(); + ulong minbalanceforexception = rpcClient.GetMinimumBalanceForRentExemption(StakeProgram.StakeAccountDataSize).Result; + Account fromAccount = wallet.Account; + Account toAccount = wallet.GetAccount(1); + rpcClient.RequestAirdrop(toAccount.PublicKey, 100_000_000); + PublicKey.TryCreateWithSeed(fromAccount.PublicKey, "dog5", StakeProgram.ProgramIdKey, out PublicKey stakeAccount); + + Console.WriteLine($"BlockHash >> {blockHash.Result.Value.Blockhash}"); + + byte[] tx = new TransactionBuilder() + .SetRecentBlockHash(blockHash.Result.Value.Blockhash) + .SetFeePayer(fromAccount) + .AddInstruction(StakeProgram.AuthorizeWithSeed( + stakeAccount, + fromAccount, + f, + fromAccount, + toAccount, + StakeAuthorize.Staker, + fromAccount)) + .Build(new List { fromAccount }); + + Console.WriteLine($"Tx base64: {Convert.ToBase64String(tx)}"); + RequestResult> txSim = rpcClient.SimulateTransaction(tx); + + string logs = Examples.PrettyPrintTransactionSimulationLogs(txSim.Result.Value.Logs); + Console.WriteLine($"Transaction Simulation:\n\tError: {txSim.Result.Value.Error}\n\tLogs: \n" + logs); + RequestResult firstSig = rpcClient.SendTransaction(tx, skipPreflight: true); + Console.WriteLine($"First Tx Result: {firstSig.Result}"); + } + } + public class AuthorizeExample : IExample + { + private static readonly IRpcClient rpcClient = ClientFactory.GetClient(Cluster.TestNet); + + private const string MnemonicWords = + "clerk shoe noise umbrella apple gold alien swap desert rubber truck okay twenty fiscal near talent drastic present leg put balcony leader access glimpse"; + public void Run() + { + var wallet = new Wallet.Wallet(new Mnemonic(MnemonicWords)); + rpcClient.RequestAirdrop(wallet.Account.PublicKey, 100_000_000); + RequestResult> blockHash = rpcClient.GetRecentBlockHash(); + + Account fromAccount = wallet.Account; + Account toAccount = wallet.GetAccount(1); + PublicKey.TryCreateWithSeed(fromAccount.PublicKey, "dog1", StakeProgram.ProgramIdKey, out PublicKey stakeAccount); + + Console.WriteLine($"BlockHash >> {blockHash.Result.Value.Blockhash}"); + + byte[] tx = new TransactionBuilder() + .SetRecentBlockHash(blockHash.Result.Value.Blockhash) + .SetFeePayer(fromAccount) + .AddInstruction(StakeProgram.Authorize( + stakeAccount, + fromAccount, + toAccount, + StakeAuthorize.Staker, + fromAccount)) + .Build(new List { fromAccount }); + Console.WriteLine($"Tx base64: {Convert.ToBase64String(tx)}"); + RequestResult> txSim = rpcClient.SimulateTransaction(tx); + + string logs = Examples.PrettyPrintTransactionSimulationLogs(txSim.Result.Value.Logs); + Console.WriteLine($"Transaction Simulation:\n\tError: {txSim.Result.Value.Error}\n\tLogs: \n" + logs); + RequestResult firstSig = rpcClient.SendTransaction(tx, skipPreflight: true); + Console.WriteLine($"First Tx Result: {firstSig.Result}"); + } + } + public class CreateAccountWithSeedAndInitializeStakeExample : IExample + { + private static readonly IRpcClient rpcClient = ClientFactory.GetClient(Cluster.TestNet); + + private const string MnemonicWords = + "clerk shoe noise umbrella apple gold alien swap desert rubber truck okay twenty fiscal near talent drastic present leg put balcony leader access glimpse"; + public void Run() + { + var wallet = new Wallet.Wallet(new Mnemonic(MnemonicWords)); + rpcClient.RequestAirdrop(wallet.Account.PublicKey, 100_000_000); + RequestResult> blockHash = rpcClient.GetRecentBlockHash(); + ulong minbalanceforexception = rpcClient.GetMinimumBalanceForRentExemption(StakeProgram.StakeAccountDataSize).Result; + Account fromAccount = wallet.Account; + PublicKey.TryCreateWithSeed(fromAccount.PublicKey, "dog5", StakeProgram.ProgramIdKey, out PublicKey stakeAccount); + Authorized authorized = new Authorized() + { + Staker = fromAccount, + Withdrawer = fromAccount + }; + Lockup lockup = new Lockup() + { + Custodian = fromAccount.PublicKey, + Epoch = 0, + UnixTimestamp = 0 + }; + + Console.WriteLine($"BlockHash >> {blockHash.Result.Value.Blockhash}"); + + byte[] tx = new TransactionBuilder() + .SetRecentBlockHash(blockHash.Result.Value.Blockhash) + .SetFeePayer(fromAccount) + .AddInstruction(SystemProgram.CreateAccountWithSeed( + fromAccount.PublicKey, + stakeAccount, + fromAccount.PublicKey, + "dog5", + 333 * minbalanceforexception + 42, + StakeProgram.StakeAccountDataSize, + StakeProgram.ProgramIdKey)) + .AddInstruction(StakeProgram.Initialize( + stakeAccount, + authorized, + lockup)) + .Build(new List { fromAccount }); + + Console.WriteLine($"Tx base64: {Convert.ToBase64String(tx)}"); + RequestResult> txSim = rpcClient.SimulateTransaction(tx); + + string logs = Examples.PrettyPrintTransactionSimulationLogs(txSim.Result.Value.Logs); + Console.WriteLine($"Transaction Simulation:\n\tError: {txSim.Result.Value.Error}\n\tLogs: \n" + logs); + RequestResult firstSig = rpcClient.SendTransaction(tx); + Console.WriteLine($"First Tx Result: {firstSig.Result}"); + } + } + public class CreateAccountAndInitializeStakeExample : IExample + { + private static readonly IRpcClient rpcClient = ClientFactory.GetClient(Cluster.TestNet); + + private const string MnemonicWords = + "clerk shoe noise umbrella apple gold alien swap desert rubber truck okay twenty fiscal near talent drastic present leg put balcony leader access glimpse"; + + public void Run() + { + var wallet = new Wallet.Wallet(new Mnemonic(MnemonicWords)); + rpcClient.RequestAirdrop(wallet.Account.PublicKey, 100_000_000); + RequestResult> blockHash = rpcClient.GetRecentBlockHash(); + ulong minbalanceforexception = rpcClient.GetMinimumBalanceForRentExemption(StakeProgram.StakeAccountDataSize).Result; + Account fromAccount = wallet.Account; + Account stakeAccount = wallet.GetAccount(22); + + Authorized authorized = new Authorized() + { + Staker = fromAccount, + Withdrawer = fromAccount + }; + Lockup lockup = new Lockup() + { + Custodian = fromAccount.PublicKey, + Epoch = 0, + UnixTimestamp = 0 + }; + + Console.WriteLine($"BlockHash >> {blockHash.Result.Value.Blockhash}"); + + byte[] tx = new TransactionBuilder() + .SetRecentBlockHash(blockHash.Result.Value.Blockhash) + .SetFeePayer(fromAccount) + .AddInstruction(SystemProgram.CreateAccount( + fromAccount.PublicKey, + stakeAccount, + minbalanceforexception + 42, + StakeProgram.StakeAccountDataSize, + StakeProgram.ProgramIdKey)) + .AddInstruction(StakeProgram.Initialize( + stakeAccount.PublicKey, + authorized, + lockup)) + .Build(new List { fromAccount, stakeAccount }); + Console.WriteLine($"Tx base64: {Convert.ToBase64String(tx)}"); + RequestResult> txSim = rpcClient.SimulateTransaction(tx); + + string logs = Examples.PrettyPrintTransactionSimulationLogs(txSim.Result.Value.Logs); + Console.WriteLine($"Transaction Simulation:\n\tError: {txSim.Result.Value.Error}\n\tLogs: \n" + logs); + RequestResult firstSig = rpcClient.SendTransaction(tx); + Console.WriteLine($"First Tx Result: {firstSig.Result}"); + } + } + public class MasterStakeBytesExample : IExample + { + private static readonly IRpcClient rpcClient = ClientFactory.GetClient(Cluster.TestNet); + + private const string MnemonicWords = + "clerk shoe noise umbrella apple gold alien swap desert rubber truck okay twenty fiscal near talent drastic present leg put balcony leader access glimpse"; + + public void Run() + { + var wallet = new Wallet.Wallet(new Mnemonic(MnemonicWords)); + rpcClient.RequestAirdrop(wallet.Account.PublicKey, 100_000_000); + RequestResult> blockHash = rpcClient.GetRecentBlockHash(); + ulong minBalance = rpcClient.GetMinimumBalanceForRentExemption(StakeProgram.StakeAccountDataSize).Result; + + Account a6 = wallet.GetAccount(6); + Account a5 = wallet.GetAccount(5); + Account a4 = wallet.GetAccount(4); + Account a3 = wallet.GetAccount(3); + + Console.WriteLine($"BlockHash >> {blockHash.Result.Value.Blockhash}"); + + byte[] tx = new TransactionBuilder() + .SetRecentBlockHash(blockHash.Result.Value.Blockhash) + .SetFeePayer(a6) + .AddInstruction(SystemProgram.CreateAccountWithSeed( + a6.PublicKey, + a5, + a6, + "dog1", + 3 * minBalance + 42, + StakeProgram.StakeAccountDataSize, + StakeProgram.ProgramIdKey)) + .AddInstruction(SystemProgram.Transfer( + a6, + a5, + 5 + )) + .CompileMessage(); + Console.WriteLine($"Tx base64: {Convert.ToBase64String(tx)}"); + RequestResult> txSim = rpcClient.SimulateTransaction(tx); + + string logs = Examples.PrettyPrintTransactionSimulationLogs(txSim.Result.Value.Logs); + Console.WriteLine($"Transaction Simulation:\n\tError: {txSim.Result.Value.Error}\n\tLogs: \n" + logs); + RequestResult firstSig = rpcClient.SendTransaction(tx); + Console.WriteLine($"First Tx Result: {firstSig.Result}"); + } + } +} diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/StakeExample.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/StakeExample.cs.meta new file mode 100644 index 0000000..c8071ab --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/StakeExample.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 800fcdcbe276c744c9f8d34c20eab479 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/TokenSwapExample.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/TokenSwapExample.cs new file mode 100644 index 0000000..67902ff --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/TokenSwapExample.cs @@ -0,0 +1,353 @@ +using Solana.Unity.Programs; +using Solana.Unity.Programs.TokenSwap; +using Solana.Unity.Programs.TokenSwap.Models; +using Solana.Unity.Rpc; +using Solana.Unity.Rpc.Builders; +using Solana.Unity.Rpc.Core.Http; +using Solana.Unity.Rpc.Messages; +using Solana.Unity.Rpc.Models; +using Solana.Unity.Wallet; +using System; + +namespace Solana.Unity.Examples +{ + public class TokenSwapExample : IExample + { + + private static readonly IRpcClient RpcClient = ClientFactory.GetClient(Cluster.TestNet); + + private const string MnemonicWords = + "route clerk disease box emerge airport loud waste attitude film army tray " + + "forward deal onion eight catalog surface unit card window walnut wealth medal"; + + public void Run() + { + //how to load current state + IRpcClient mainnetRpc = ClientFactory.GetClient(Cluster.MainNet); + var resp = mainnetRpc.GetAccountInfo("GAM8dQkm4LwYJgPZbML61mKPUCQX7uAquxu67p9oifSK"); + var obj = TokenSwapAccount.Deserialize(Convert.FromBase64String(resp.Result.Value.Data[0])); + Console.WriteLine($"Pool Mint: {obj.PoolMint}"); + + Wallet.Wallet wallet = new Wallet.Wallet(MnemonicWords); + + var tokenAMint = new Account(); + var tokenAUserAccount = new Account(); + var tokenBMint = new Account(); + var tokenBUserAccount = new Account(); + + //setup some mints and tokens owned by wallet + RequestResult> blockHash = RpcClient.GetRecentBlockHash(); + var tx = new TransactionBuilder() + .SetRecentBlockHash(blockHash.Result.Value.Blockhash) + .SetFeePayer(wallet.Account) + .AddInstruction(SystemProgram.CreateAccount( + wallet.Account, + tokenAMint, + RpcClient.GetMinimumBalanceForRentExemption(TokenProgram.MintAccountDataSize).Result, + TokenProgram.MintAccountDataSize, + TokenProgram.ProgramIdKey + )) + .AddInstruction(SystemProgram.CreateAccount( + wallet.Account, + tokenBMint, + RpcClient.GetMinimumBalanceForRentExemption(TokenProgram.MintAccountDataSize).Result, + TokenProgram.MintAccountDataSize, + TokenProgram.ProgramIdKey + )) + .AddInstruction(SystemProgram.CreateAccount( + wallet.Account, + tokenAUserAccount, + RpcClient.GetMinimumBalanceForRentExemption(TokenProgram.TokenAccountDataSize).Result, + TokenProgram.TokenAccountDataSize, + TokenProgram.ProgramIdKey + )) + .AddInstruction(SystemProgram.CreateAccount( + wallet.Account, + tokenBUserAccount, + RpcClient.GetMinimumBalanceForRentExemption(TokenProgram.TokenAccountDataSize).Result, + TokenProgram.TokenAccountDataSize, + TokenProgram.ProgramIdKey + )) + .AddInstruction(TokenProgram.InitializeMint( + tokenAMint, + 9, + wallet.Account + )) + .AddInstruction(TokenProgram.InitializeMint( + tokenBMint, + 9, + wallet.Account + )) + .AddInstruction(TokenProgram.InitializeAccount( + tokenAUserAccount, + tokenAMint, + wallet.Account + )) + .AddInstruction(TokenProgram.InitializeAccount( + tokenBUserAccount, + tokenBMint, + wallet.Account + )) + .AddInstruction(TokenProgram.MintTo( + tokenAMint, + tokenAUserAccount, + 1_000_000_000_000, + wallet.Account + )) + .AddInstruction(TokenProgram.MintTo( + tokenBMint, + tokenBUserAccount, + 1_000_000_000_000, + wallet.Account + )) + .Build(new Account[] { wallet.Account, tokenAMint, tokenBMint, tokenAUserAccount, tokenBUserAccount }); + var txSig = Examples.SubmitTxSendAndLog(tx); + Examples.PollConfirmedTx(txSig); + + var swap = new Account(); + var program = new TokenSwapProgram(); + var swapAuthority = program.CreateAuthority(swap).pubkey; + + var swapTokenAAccount= new Account(); + var swapTokenBAccount = new Account(); + + //init the swap authority's token accounts + blockHash = RpcClient.GetRecentBlockHash(); + tx = new TransactionBuilder() + .SetRecentBlockHash(blockHash.Result.Value.Blockhash) + .SetFeePayer(wallet.Account) + .AddInstruction(SystemProgram.CreateAccount( + wallet.Account, + swapTokenAAccount, + RpcClient.GetMinimumBalanceForRentExemption(TokenProgram.TokenAccountDataSize).Result, + TokenProgram.TokenAccountDataSize, + TokenProgram.ProgramIdKey + )) + .AddInstruction(TokenProgram.InitializeAccount( + swapTokenAAccount, + tokenAMint, + swapAuthority + )) + .AddInstruction(TokenProgram.Transfer( + tokenAUserAccount, + swapTokenAAccount, + 5_000_000_000, + wallet.Account + )) + .AddInstruction(SystemProgram.CreateAccount( + wallet.Account, + swapTokenBAccount, + RpcClient.GetMinimumBalanceForRentExemption(TokenProgram.TokenAccountDataSize).Result, + TokenProgram.TokenAccountDataSize, + TokenProgram.ProgramIdKey + )) + .AddInstruction(TokenProgram.InitializeAccount( + swapTokenBAccount, + tokenBMint, + swapAuthority + )) + .AddInstruction(TokenProgram.Transfer( + tokenBUserAccount, + swapTokenBAccount, + 5_000_000_000, + wallet.Account + )) + .Build(new Account[] { wallet.Account, swapTokenAAccount, swapTokenBAccount }); + txSig = Examples.SubmitTxSendAndLog(tx); + Examples.PollConfirmedTx(txSig); + + var poolMint = new Account(); + var poolUserAccount = new Account(); + var poolFeeAccount = new Account(); + + //create the pool mint and the user and fee pool token accounts + blockHash = RpcClient.GetRecentBlockHash(); + tx = new TransactionBuilder() + .SetRecentBlockHash(blockHash.Result.Value.Blockhash) + .SetFeePayer(wallet.Account) + .AddInstruction(SystemProgram.CreateAccount( + wallet.Account, + poolMint, + RpcClient.GetMinimumBalanceForRentExemption(TokenProgram.MintAccountDataSize).Result, + TokenProgram.MintAccountDataSize, + TokenProgram.ProgramIdKey + )) + .AddInstruction(TokenProgram.InitializeMint( + poolMint, + 9, + swapAuthority + )) + .AddInstruction(SystemProgram.CreateAccount( + wallet.Account, + poolUserAccount, + RpcClient.GetMinimumBalanceForRentExemption(TokenProgram.TokenAccountDataSize).Result, + TokenProgram.TokenAccountDataSize, + TokenProgram.ProgramIdKey + )) + .AddInstruction(TokenProgram.InitializeAccount( + poolUserAccount, + poolMint, + wallet.Account + )) + .AddInstruction(SystemProgram.CreateAccount( + wallet.Account, + poolFeeAccount, + RpcClient.GetMinimumBalanceForRentExemption(TokenProgram.TokenAccountDataSize).Result, + TokenProgram.TokenAccountDataSize, + TokenProgram.ProgramIdKey + )) + .AddInstruction(TokenProgram.InitializeAccount( + poolFeeAccount, + poolMint, + program.OwnerKey + )) + .Build(new Account[] { wallet.Account, poolMint, poolUserAccount, poolFeeAccount }); + txSig = Examples.SubmitTxSendAndLog(tx); + Examples.PollConfirmedTx(txSig); + + //create the swap + blockHash = RpcClient.GetRecentBlockHash(); + tx = new TransactionBuilder() + .SetRecentBlockHash(blockHash.Result.Value.Blockhash) + .SetFeePayer(wallet.Account) + .AddInstruction(SystemProgram.CreateAccount( + wallet.Account, + swap, + RpcClient.GetMinimumBalanceForRentExemption((long)TokenSwapProgram.TokenSwapAccountDataSize).Result, + TokenSwapProgram.TokenSwapAccountDataSize, + program.ProgramIdKey + )) + .AddInstruction(program.Initialize( + swap, + swapTokenAAccount, + swapTokenBAccount, + poolMint, + poolFeeAccount, + poolUserAccount, + new Fees() + { + TradeFeeNumerator = 25, + TradeFeeDenominator = 10000, + OwnerTradeFeeNumerator = 5, + OwnerTradeFeeDenomerator = 10000, + OwnerWithrawFeeNumerator = 0, + OwnerWithrawFeeDenomerator = 0, + HostFeeNumerator = 20, + HostFeeDenomerator = 100 + }, + SwapCurve.ConstantProduct + )) + .Build(new Account[] { wallet.Account, swap }); + Console.WriteLine($"Swap Account: {swap}"); + Console.WriteLine($"Swap Auth Account: {swapAuthority}"); + Console.WriteLine($"Pool Mint Account: {poolMint}"); + Console.WriteLine($"Pool User Account: {poolUserAccount}"); + Console.WriteLine($"Pool Fee Account: {poolFeeAccount}"); + txSig = Examples.SubmitTxSendAndLog(tx); + Examples.PollConfirmedTx(txSig); + + //now a user can swap in the pool + blockHash = RpcClient.GetRecentBlockHash(); + tx = new TransactionBuilder() + .SetRecentBlockHash(blockHash.Result.Value.Blockhash) + .SetFeePayer(wallet.Account) + .AddInstruction(program.Swap( + swap, + wallet.Account, + tokenAUserAccount, + swapTokenAAccount, + swapTokenBAccount, + tokenBUserAccount, + poolMint, + poolFeeAccount, + null, + 1_000_000_000, + 500_000)) + .Build(wallet.Account); + txSig = Examples.SubmitTxSendAndLog(tx); + Examples.PollConfirmedTx(txSig); + + //user can add liq + blockHash = RpcClient.GetRecentBlockHash(); + tx = new TransactionBuilder() + .SetRecentBlockHash(blockHash.Result.Value.Blockhash) + .SetFeePayer(wallet.Account) + .AddInstruction(program.DepositAllTokenTypes( + swap, + wallet.Account, + tokenAUserAccount, + tokenBUserAccount, + swapTokenAAccount, + swapTokenBAccount, + poolMint, + poolUserAccount, + 1_000_000, + 100_000_000_000, + 100_000_000_000)) + .Build(wallet.Account); + txSig = Examples.SubmitTxSendAndLog(tx); + Examples.PollConfirmedTx(txSig); + + //user can remove liq + blockHash = RpcClient.GetRecentBlockHash(); + tx = new TransactionBuilder() + .SetRecentBlockHash(blockHash.Result.Value.Blockhash) + .SetFeePayer(wallet.Account) + .AddInstruction(program.WithdrawAllTokenTypes( + swap, + wallet.Account, + poolMint, + poolUserAccount, + swapTokenAAccount, + swapTokenBAccount, + tokenAUserAccount, + tokenBUserAccount, + poolFeeAccount, + 1_000_000, + 1_000, + 1_000)) + .Build(wallet.Account); + txSig = Examples.SubmitTxSendAndLog(tx); + Examples.PollConfirmedTx(txSig); + + //user can deposit single + blockHash = RpcClient.GetRecentBlockHash(); + tx = new TransactionBuilder() + .SetRecentBlockHash(blockHash.Result.Value.Blockhash) + .SetFeePayer(wallet.Account) + .AddInstruction(program.DepositSingleTokenTypeExactAmountIn( + swap, + wallet.Account, + tokenAUserAccount, + swapTokenAAccount, + swapTokenBAccount, + poolMint, + poolUserAccount, + 1_000_000_000, + 1_000)) + .Build(wallet.Account); + txSig = Examples.SubmitTxSendAndLog(tx); + Examples.PollConfirmedTx(txSig); + + //user can withdraw single + blockHash = RpcClient.GetRecentBlockHash(); + tx = new TransactionBuilder() + .SetRecentBlockHash(blockHash.Result.Value.Blockhash) + .SetFeePayer(wallet.Account) + .AddInstruction(program.WithdrawSingleTokenTypeExactAmountOut( + swap, + wallet.Account, + poolMint, + poolUserAccount, + swapTokenAAccount, + swapTokenBAccount, + tokenAUserAccount, + poolFeeAccount, + 1_000_000, + 100_000)) + .Build(wallet.Account); + txSig = Examples.SubmitTxSendAndLog(tx); + Examples.PollConfirmedTx(txSig); + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/TokenSwapExample.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/TokenSwapExample.cs.meta new file mode 100644 index 0000000..7267a01 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/TokenSwapExample.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ffd33ea2613bcbf4c8db4c162754fa1e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/TokenWalletExample.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/TokenWalletExample.cs new file mode 100644 index 0000000..478548c --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/TokenWalletExample.cs @@ -0,0 +1,61 @@ +using Solana.Unity.Extensions; +using Solana.Unity.Extensions.TokenMint; +using Solana.Unity.Rpc; +using System; +using System.Linq; + +namespace Solana.Unity.Examples +{ + public class TokenWalletExample : IExample + { + + private static readonly IRpcClient RpcClient = ClientFactory.GetClient(Cluster.TestNet); + + private const string MnemonicWords = + "route clerk disease box emerge airport loud waste attitude film army tray " + + "forward deal onion eight catalog surface unit card window walnut wealth medal"; + + public void Run() + { + + Wallet.Wallet wallet = new Wallet.Wallet(MnemonicWords); + Wallet.Account ownerAccount = wallet.GetAccount(10); + + // add TokenDef for a TestNet minted token created by Solana.Unity examples + var tokens = new TokenMintResolver(); + tokens.Add(new TokenDef("AHRNasvVB8UDkU9knqPcn4aVfRbnbVC9HJgSTBwbx8re", "Solnet Test Token", "STT", 2)); + + // load snapshot of wallet and sub-accounts + TokenWallet tokenWallet = TokenWallet.Load(RpcClient, tokens, ownerAccount); + var balances = tokenWallet.Balances(); + var maxsym = balances.Max(x => x.Symbol.Length); + var maxname = balances.Max(x => x.TokenName.Length); + + // show individual token accounts + Console.WriteLine("Individual Accounts..."); + foreach (var account in tokenWallet.TokenAccounts()) + { + Console.WriteLine($"{account.Symbol.PadRight(maxsym)} {account.QuantityDecimal,14} {account.TokenName.PadRight(maxname)} {account.PublicKey} {(account.IsAssociatedTokenAccount ? "[ATA]" : "")}"); + } + Console.WriteLine(); + + // show filtered accounts + Console.WriteLine("Filtered Accounts..."); + var sublist = tokenWallet.TokenAccounts().WithSymbol("STT").WithMint("AHRNasvVB8UDkU9knqPcn4aVfRbnbVC9HJgSTBwbx8re"); + foreach (var account in sublist) + { + Console.WriteLine($"{account.Symbol.PadRight(maxsym)} {account.QuantityDecimal,14} {account.TokenName.PadRight(maxname)} {account.PublicKey} {(account.IsAssociatedTokenAccount ? "[ATA]" : "")}"); + } + Console.WriteLine(); + + // show consolidated balances + Console.WriteLine("Consolidated Balances..."); + foreach (var balance in tokenWallet.Balances()) + { + Console.WriteLine($"{balance.Symbol.PadRight(maxsym)} {balance.QuantityDecimal,14} {balance.TokenName.PadRight(maxname)} in {balance.AccountCount} {(balance.AccountCount == 1 ? "account" : "accounts")}"); + } + Console.WriteLine(); + + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/TokenWalletExample.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/TokenWalletExample.cs.meta new file mode 100644 index 0000000..16cc54e --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/TokenWalletExample.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 419fdf630c415ea47a8cc57ba797b822 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/TransactionBuilderExample.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/TransactionBuilderExample.cs new file mode 100644 index 0000000..4e5f0c1 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/TransactionBuilderExample.cs @@ -0,0 +1,479 @@ +using Solana.Unity.Programs; +using Solana.Unity.Programs.Models; +using Solana.Unity.Rpc; +using Solana.Unity.Rpc.Builders; +using Solana.Unity.Rpc.Core.Http; +using Solana.Unity.Rpc.Messages; +using Solana.Unity.Rpc.Models; +using Solana.Unity.Wallet; +using System; +using System.Collections.Generic; + +namespace Solana.Unity.Examples +{ + public class TransactionBuilderExample : IExample + { + private static readonly IRpcClient rpcClient = ClientFactory.GetClient(Cluster.TestNet); + + private const string MnemonicWords = + "route clerk disease box emerge airport loud waste attitude film army tray " + + "forward deal onion eight catalog surface unit card window walnut wealth medal"; + + public void Run() + { + Wallet.Wallet wallet = new Wallet.Wallet(MnemonicWords); + + Account fromAccount = wallet.GetAccount(10); + Account toAccount = wallet.GetAccount(8); + + RequestResult> blockHash = rpcClient.GetRecentBlockHash(); + Console.WriteLine($"BlockHash >> {blockHash.Result.Value.Blockhash}"); + + byte[] tx = new TransactionBuilder() + .SetRecentBlockHash(blockHash.Result.Value.Blockhash) + .SetFeePayer(fromAccount) + .AddInstruction(SystemProgram.Transfer(fromAccount.PublicKey, toAccount.PublicKey, 10000000)) + .AddInstruction(MemoProgram.NewMemo(fromAccount.PublicKey, "Hello from Sol.Net :)")) + .Build(fromAccount); + + Console.WriteLine($"Tx base64: {Convert.ToBase64String(tx)}"); + RequestResult> txSim = rpcClient.SimulateTransaction(tx); + string logs = Examples.PrettyPrintTransactionSimulationLogs(txSim.Result.Value.Logs); + Console.WriteLine($"Transaction Simulation:\n\tError: {txSim.Result.Value.Error}\n\tLogs: \n" + logs); + RequestResult firstSig = rpcClient.SendTransaction(tx); + Console.WriteLine($"First Tx Signature: {firstSig.Result}"); + } + } + + public class CreateInitializeAndMintToExample : IExample + { + private static readonly IRpcClient rpcClient = ClientFactory.GetClient(Cluster.TestNet); + + private const string MnemonicWords = + "route clerk disease box emerge airport loud waste attitude film army tray " + + "forward deal onion eight catalog surface unit card window walnut wealth medal"; + + public void Run() + { + Wallet.Wallet wallet = new Wallet.Wallet(MnemonicWords); + + RequestResult> blockHash = rpcClient.GetRecentBlockHash(); + ulong minBalanceForExemptionAcc = + rpcClient.GetMinimumBalanceForRentExemption(TokenProgram.TokenAccountDataSize).Result; + Console.WriteLine($"MinBalanceForRentExemption Account >> {minBalanceForExemptionAcc}"); + + ulong minBalanceForExemptionMint = + rpcClient.GetMinimumBalanceForRentExemption(TokenProgram.MintAccountDataSize).Result; + Console.WriteLine($"MinBalanceForRentExemption Mint Account >> {minBalanceForExemptionMint}"); + + Account mintAccount = wallet.GetAccount(2222); + Console.WriteLine($"MintAccount: {mintAccount}"); + Account ownerAccount = wallet.GetAccount(10); + Console.WriteLine($"OwnerAccount: {ownerAccount}"); + Account initialAccount = wallet.GetAccount(3333); + Console.WriteLine($"InitialAccount: {initialAccount}"); + + byte[] tx = new TransactionBuilder().SetRecentBlockHash(blockHash.Result.Value.Blockhash) + .SetFeePayer(ownerAccount) + .AddInstruction(SystemProgram.CreateAccount( + ownerAccount.PublicKey, + mintAccount.PublicKey, + minBalanceForExemptionMint, + TokenProgram.MintAccountDataSize, + TokenProgram.ProgramIdKey)) + .AddInstruction(TokenProgram.InitializeMint( + mintAccount.PublicKey, + 2, + ownerAccount.PublicKey, + ownerAccount.PublicKey)) + .AddInstruction(SystemProgram.CreateAccount( + ownerAccount, + initialAccount, + minBalanceForExemptionAcc, + TokenProgram.TokenAccountDataSize, + TokenProgram.ProgramIdKey)) + .AddInstruction(TokenProgram.InitializeAccount( + initialAccount.PublicKey, + mintAccount.PublicKey, + ownerAccount.PublicKey)) + .AddInstruction(TokenProgram.MintTo( + mintAccount.PublicKey, + initialAccount.PublicKey, + 25000, + ownerAccount.PublicKey)) + .AddInstruction(MemoProgram.NewMemo(initialAccount.PublicKey, "Hello from Sol.Net")) + .Build(new List { ownerAccount, mintAccount, initialAccount }); + + Console.WriteLine($"Tx: {Convert.ToBase64String(tx)}"); + + RequestResult> txSim = rpcClient.SimulateTransaction(tx); + string logs = Examples.PrettyPrintTransactionSimulationLogs(txSim.Result.Value.Logs); + Console.WriteLine($"Transaction Simulation:\n\tError: {txSim.Result.Value.Error}\n\tLogs: \n" + logs); + + RequestResult txReq = rpcClient.SendTransaction(tx); + Console.WriteLine($"Tx Signature: {txReq.Result}"); + } + } + + public class SimpleMintToExample : IExample + { + private static readonly IRpcClient rpcClient = ClientFactory.GetClient(Cluster.TestNet); + + private const string MnemonicWords = + "route clerk disease box emerge airport loud waste attitude film army tray " + + "forward deal onion eight catalog surface unit card window walnut wealth medal"; + + public void Run() + { + Wallet.Wallet wallet = new Wallet.Wallet(MnemonicWords); + + RequestResult> blockHash = rpcClient.GetRecentBlockHash(); + ulong minBalanceForExemptionAcc = + rpcClient.GetMinimumBalanceForRentExemption(TokenProgram.TokenAccountDataSize).Result; + Console.WriteLine($"MinBalanceForRentExemption Account >> {minBalanceForExemptionAcc}"); + + ulong minBalanceForExemptionMint = + rpcClient.GetMinimumBalanceForRentExemption(TokenProgram.MintAccountDataSize).Result; + Console.WriteLine($"MinBalanceForRentExemption Mint Account >> {minBalanceForExemptionMint}"); + + Account mintAccount = wallet.GetAccount(21); + Console.WriteLine($"MintAccount: {mintAccount}"); + Account ownerAccount = wallet.GetAccount(10); + Console.WriteLine($"OwnerAccount: {ownerAccount}"); + Account initialAccount = wallet.GetAccount(26); + Console.WriteLine($"InitialAccount: {initialAccount}"); + + byte[] tx = new TransactionBuilder().SetRecentBlockHash(blockHash.Result.Value.Blockhash) + .SetFeePayer(ownerAccount) + .AddInstruction(TokenProgram.MintTo( + mintAccount.PublicKey, + initialAccount.PublicKey, + 25000000, + ownerAccount.PublicKey)) + .AddInstruction(MemoProgram.NewMemo(initialAccount.PublicKey, "Hello from Sol.Net")) + .Build(new List { ownerAccount, initialAccount }); + + Console.WriteLine($"Tx: {Convert.ToBase64String(tx)}"); + + RequestResult> txSim = rpcClient.SimulateTransaction(tx); + string logs = Examples.PrettyPrintTransactionSimulationLogs(txSim.Result.Value.Logs); + Console.WriteLine($"Transaction Simulation:\n\tError: {txSim.Result.Value.Error}\n\tLogs: \n" + logs); + + RequestResult txReq = rpcClient.SendTransaction(tx); + Console.WriteLine($"Tx Signature: {txReq.Result}"); + } + } + + public class TransferTokenExample : IExample + { + private static readonly IRpcClient rpcClient = ClientFactory.GetClient(Cluster.TestNet); + + private const string MnemonicWords = + "route clerk disease box emerge airport loud waste attitude film army tray " + + "forward deal onion eight catalog surface unit card window walnut wealth medal"; + + public void Run() + { + Wallet.Wallet wallet = new Wallet.Wallet(MnemonicWords); + + RequestResult> blockHash = rpcClient.GetRecentBlockHash(); + ulong minBalanceForExemptionAcc = rpcClient.GetMinimumBalanceForRentExemption(TokenProgram.TokenAccountDataSize).Result; + Console.WriteLine($"MinBalanceForRentExemption Account >> {minBalanceForExemptionAcc}"); + + Account mintAccount = wallet.GetAccount(31); + Console.WriteLine($"MintAccount: {mintAccount}"); + Account ownerAccount = wallet.GetAccount(10); + Console.WriteLine($"OwnerAccount: {ownerAccount}"); + Account initialAccount = wallet.GetAccount(32); + Console.WriteLine($"InitialAccount: {initialAccount}"); + Account newAccount = wallet.GetAccount(33); + Console.WriteLine($"NewAccount: {newAccount}"); + + byte[] tx = new TransactionBuilder().SetRecentBlockHash(blockHash.Result.Value.Blockhash) + .SetFeePayer(ownerAccount) + .AddInstruction(SystemProgram.CreateAccount( + ownerAccount.PublicKey, + newAccount.PublicKey, + minBalanceForExemptionAcc, + TokenProgram.TokenAccountDataSize, + TokenProgram.ProgramIdKey)) + .AddInstruction(TokenProgram.InitializeAccount( + newAccount.PublicKey, + mintAccount.PublicKey, + ownerAccount.PublicKey)) + .AddInstruction(TokenProgram.Transfer( + initialAccount.PublicKey, + newAccount.PublicKey, + 25000, + ownerAccount)) + .AddInstruction(MemoProgram.NewMemo(initialAccount, "Hello from Sol.Net")) + .Build(new List { ownerAccount, newAccount, initialAccount }); + + Console.WriteLine($"Tx: {Convert.ToBase64String(tx)}"); + + RequestResult> txSim = rpcClient.SimulateTransaction(tx); + string logs = Examples.PrettyPrintTransactionSimulationLogs(txSim.Result.Value.Logs); + Console.WriteLine($"Transaction Simulation:\n\tError: {txSim.Result.Value.Error}\n\tLogs: \n" + logs); + + RequestResult txReq = rpcClient.SendTransaction(tx); + Console.WriteLine($"Tx Signature: {txReq.Result}"); + } + } + + public class TransferTokenCheckedExample : IExample + { + private static readonly IRpcClient rpcClient = ClientFactory.GetClient(Cluster.TestNet); + + private const string MnemonicWords = + "route clerk disease box emerge airport loud waste attitude film army tray " + + "forward deal onion eight catalog surface unit card window walnut wealth medal"; + + public void Run() + { + Wallet.Wallet wallet = new Wallet.Wallet(MnemonicWords); + + RequestResult> blockHash = rpcClient.GetRecentBlockHash(); + ulong minBalanceForExemptionAcc = + rpcClient.GetMinimumBalanceForRentExemption(TokenProgram.TokenAccountDataSize).Result; + Console.WriteLine($"MinBalanceForRentExemption Account >> {minBalanceForExemptionAcc}"); + + Account mintAccount = wallet.GetAccount(21); + Console.WriteLine($"MintAccount: {mintAccount}"); + Account ownerAccount = wallet.GetAccount(10); + Console.WriteLine($"OwnerAccount: {ownerAccount}"); + Account initialAccount = wallet.GetAccount(26); + Console.WriteLine($"InitialAccount: {initialAccount}"); + Account newAccount = wallet.GetAccount(27); + Console.WriteLine($"NewAccount: {newAccount}"); + + byte[] tx = new TransactionBuilder() + .SetRecentBlockHash(blockHash.Result.Value.Blockhash) + .SetFeePayer(ownerAccount) + .AddInstruction(SystemProgram.CreateAccount( + ownerAccount.PublicKey, + newAccount.PublicKey, + minBalanceForExemptionAcc, + TokenProgram.TokenAccountDataSize, + TokenProgram.ProgramIdKey)) + .AddInstruction(TokenProgram.InitializeAccount( + newAccount.PublicKey, + mintAccount.PublicKey, + ownerAccount.PublicKey)) + .AddInstruction(TokenProgram.TransferChecked( + initialAccount.PublicKey, + newAccount.PublicKey, + 25000, + 2, + ownerAccount, + mintAccount.PublicKey)) + .AddInstruction(MemoProgram.NewMemo( + initialAccount, + "Hello from Sol.Net")) + .Build(new List { ownerAccount, newAccount, initialAccount }); + + Console.WriteLine($"Tx: {Convert.ToBase64String(tx)}"); + + RequestResult> txSim = rpcClient.SimulateTransaction(tx); + string logs = Examples.PrettyPrintTransactionSimulationLogs(txSim.Result.Value.Logs); + Console.WriteLine($"Transaction Simulation:\n\tError: {txSim.Result.Value.Error}\n\tLogs: \n" + logs); + + RequestResult txReq = rpcClient.SendTransaction(tx); + Console.WriteLine($"Tx Signature: {txReq.Result}"); + } + } + + public class CreateNonceAccountExample : IExample + { + private static readonly IRpcClient rpcClient = ClientFactory.GetClient(Cluster.TestNet); + private const string MnemonicWords = + "route clerk disease box emerge airport loud waste attitude film army tray " + + "forward deal onion eight catalog surface unit card window walnut wealth medal"; + + public void Run() + { + Wallet.Wallet wallet = new Wallet.Wallet(MnemonicWords); + + RequestResult> blockHash = rpcClient.GetRecentBlockHash(); + ulong minBalanceForExemptionAcc = + rpcClient.GetMinimumBalanceForRentExemption(NonceAccount.AccountDataSize).Result; + + Account ownerAccount = wallet.GetAccount(10); + Console.WriteLine($"OwnerAccount: {ownerAccount}"); + Account nonceAccount = wallet.GetAccount(1119); + Console.WriteLine($"NonceAccount: {nonceAccount}"); + Account newAuthority = wallet.GetAccount(1129); + Console.WriteLine($"NewAuthority: {newAuthority}"); + + byte[] tx = new TransactionBuilder() + .SetRecentBlockHash(blockHash.Result.Value.Blockhash) + .SetFeePayer(ownerAccount) + .AddInstruction(SystemProgram.CreateAccount( + ownerAccount.PublicKey, + nonceAccount.PublicKey, + minBalanceForExemptionAcc, + NonceAccount.AccountDataSize, + SystemProgram.ProgramIdKey + )) + .AddInstruction(SystemProgram.InitializeNonceAccount( + nonceAccount, + ownerAccount)) + .Build(new List { ownerAccount, nonceAccount }); + + + Console.WriteLine($"Tx: {Convert.ToBase64String(tx)}"); + RequestResult> txSim = rpcClient.SimulateTransaction(tx); + string logs = Examples.PrettyPrintTransactionSimulationLogs(txSim.Result.Value.Logs); + Console.WriteLine($"Transaction Simulation:\n\tError: {txSim.Result.Value.Error}\n\tLogs: \n" + logs); + + RequestResult txReq = rpcClient.SendTransaction(tx); + Console.WriteLine($"Tx Signature: {txReq.Result}"); + } + } + + public class TransactionBuilderTransferWithDurableNonceExample : IExample + { + private static readonly IRpcClient rpcClient = ClientFactory.GetClient(Cluster.TestNet); + private const string MnemonicWords = + "route clerk disease box emerge airport loud waste attitude film army tray " + + "forward deal onion eight catalog surface unit card window walnut wealth medal"; + + public void Run() + { + Wallet.Wallet wallet = new Wallet.Wallet(MnemonicWords); + + Account ownerAccount = wallet.GetAccount(10); + Console.WriteLine($"OwnerAccount: {ownerAccount}"); + Account nonceAccount = wallet.GetAccount(1119); + Console.WriteLine($"NonceAccount: {nonceAccount}"); + Account toAccount = wallet.GetAccount(1); + Console.WriteLine($"ToAccount: {toAccount}"); + + // Get the Nonce Account to get the Nonce to use for the transaction + RequestResult> nonceAccountInfo = rpcClient.GetAccountInfo(nonceAccount.PublicKey); + byte[] accountDataBytes = Convert.FromBase64String(nonceAccountInfo.Result.Value.Data[0]); + NonceAccount nonceAccountData = NonceAccount.Deserialize(accountDataBytes); + Console.WriteLine($"NonceAccount Authority: {nonceAccountData.Authorized.Key}"); + Console.WriteLine($"NonceAccount Nonce: {nonceAccountData.Nonce.Key}"); + + // Initialize the nonce information to be used with the transaction + NonceInformation nonceInfo = new NonceInformation() + { + Nonce = nonceAccountData.Nonce, + Instruction = SystemProgram.AdvanceNonceAccount( + nonceAccount.PublicKey, + ownerAccount + ) + }; + + byte[] tx = new TransactionBuilder() + .SetFeePayer(ownerAccount) + .SetNonceInformation(nonceInfo) + .AddInstruction( + SystemProgram.Transfer( + ownerAccount, + toAccount, + 1_000_000_000) + ) + .Build(ownerAccount); + + Console.WriteLine($"Tx: {Convert.ToBase64String(tx)}"); + RequestResult> txSim = rpcClient.SimulateTransaction(tx); + string logs = Examples.PrettyPrintTransactionSimulationLogs(txSim.Result.Value.Logs); + Console.WriteLine($"Transaction Simulation:\n\tError: {txSim.Result.Value.Error}\n\tLogs: \n" + logs); + + RequestResult txReq = rpcClient.SendTransaction(tx); + Console.WriteLine($"Tx Signature: {txReq.Result}"); + } + } + + public class BurnExample : IExample + { + private static readonly IRpcClient rpcClient = ClientFactory.GetClient(Cluster.TestNet); + + private const string MnemonicWords = + "route clerk disease box emerge airport loud waste attitude film army tray " + + "forward deal onion eight catalog surface unit card window walnut wealth medal"; + + public void Run() + { + Wallet.Wallet wallet = new Wallet.Wallet(MnemonicWords); + + RequestResult> blockHash = rpcClient.GetRecentBlockHash(); + + ulong minBalanceForExemptionMultiSig = + rpcClient.GetMinimumBalanceForRentExemption(TokenProgram.MultisigAccountDataSize).Result; + Console.WriteLine($"MinBalanceForRentExemption MultiSig >> {minBalanceForExemptionMultiSig}"); + ulong minBalanceForExemptionAcc = + rpcClient.GetMinimumBalanceForRentExemption(TokenProgram.TokenAccountDataSize).Result; + Console.WriteLine($"MinBalanceForRentExemption Account >> {minBalanceForExemptionAcc}"); + ulong minBalanceForExemptionMint = + rpcClient.GetMinimumBalanceForRentExemption(TokenProgram.MintAccountDataSize).Result; + Console.WriteLine($"MinBalanceForRentExemption Mint Account >> {minBalanceForExemptionMint}"); + + Account ownerAccount = wallet.GetAccount(10); + Account mintAccount = wallet.GetAccount(21); + Account initialAccount = wallet.GetAccount(26); + + byte[] msgData = new TransactionBuilder().SetRecentBlockHash(blockHash.Result.Value.Blockhash) + .SetFeePayer(ownerAccount) + .AddInstruction(TokenProgram.Burn( + initialAccount.PublicKey, + mintAccount.PublicKey, + 200, + ownerAccount)) + .AddInstruction(MemoProgram.NewMemo(ownerAccount, "Hello from Sol.Net")) + .CompileMessage(); + + Message msg = Examples.DecodeMessageFromWire(msgData); + + Console.WriteLine("\n\tPOPULATING TRANSACTION WITH SIGNATURES\t"); + Transaction tx = Transaction.Populate(msg, + new List { ownerAccount.Sign(msgData) }); + + byte[] txBytes = Examples.LogTransactionAndSerialize(tx); + + string mintToSignature = Examples.SubmitTxSendAndLog(txBytes); + Examples.PollConfirmedTx(mintToSignature); + } + } + + public class AddSignatureExample : IExample + { + private static readonly IRpcClient rpcClient = ClientFactory.GetClient(Cluster.TestNet); + + private const string MnemonicWords = + "route clerk disease box emerge airport loud waste attitude film army tray " + + "forward deal onion eight catalog surface unit card window walnut wealth medal"; + + public void Run() + { + Wallet.Wallet wallet = new Wallet.Wallet(MnemonicWords); + + Account fromAccount = wallet.GetAccount(10); + Account toAccount = wallet.GetAccount(8); + + RequestResult> blockHash = rpcClient.GetRecentBlockHash(); + Console.WriteLine($"BlockHash >> {blockHash.Result.Value.Blockhash}"); + + TransactionBuilder txBuilder = new TransactionBuilder() + .SetRecentBlockHash(blockHash.Result.Value.Blockhash) + .SetFeePayer(fromAccount) + .AddInstruction(SystemProgram.Transfer(fromAccount.PublicKey, toAccount.PublicKey, 10000000)) + .AddInstruction(MemoProgram.NewMemo(fromAccount.PublicKey, "Hello from Sol.Net :)")); + + byte[] msgBytes = txBuilder.CompileMessage(); + byte[] signature = fromAccount.Sign(msgBytes); + + byte[] tx = txBuilder.AddSignature(signature) + .Serialize(); + + Console.WriteLine($"Tx base64: {Convert.ToBase64String(tx)}"); + RequestResult> txSim = rpcClient.SimulateTransaction(tx); + string logs = Examples.PrettyPrintTransactionSimulationLogs(txSim.Result.Value.Logs); + Console.WriteLine($"Transaction Simulation:\n\tError: {txSim.Result.Value.Error}\n\tLogs: \n" + logs); + RequestResult firstSig = rpcClient.SendTransaction(tx); + Console.WriteLine($"First Tx Signature: {firstSig.Result}"); + } + } + +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/TransactionBuilderExample.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/TransactionBuilderExample.cs.meta new file mode 100644 index 0000000..aab7aed --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/TransactionBuilderExample.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a904f4206d4776a45bf07795763c13c5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/TransactionDecodingExample.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/TransactionDecodingExample.cs new file mode 100644 index 0000000..4261770 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/TransactionDecodingExample.cs @@ -0,0 +1,116 @@ +using Solana.Unity.Programs; +using Solana.Unity.Programs.Models; +using Solana.Unity.Rpc; +using Solana.Unity.Rpc.Builders; +using Solana.Unity.Rpc.Core.Http; +using Solana.Unity.Rpc.Messages; +using Solana.Unity.Rpc.Models; +using Solana.Unity.Wallet; +using Solana.Unity.Wallet.Utilities; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Solana.Unity.Examples +{ + public class TransactionDecodingExample : IExample + { + + private static readonly IRpcClient RpcClient = ClientFactory.GetClient(Cluster.TestNet); + + private const string MnemonicWords = + "route clerk disease box emerge airport loud waste attitude film army tray " + + "forward deal onion eight catalog surface unit card window walnut wealth medal"; + + public void Run() + { + var wallet = new Wallet.Wallet(MnemonicWords); + + RequestResult> blockHash = RpcClient.GetRecentBlockHash(); + ulong minBalanceForExemptionAcc = + RpcClient.GetMinimumBalanceForRentExemption(TokenProgram.TokenAccountDataSize).Result; + ulong minBalanceForExemptionMint = + RpcClient.GetMinimumBalanceForRentExemption(TokenProgram.MintAccountDataSize).Result; + + Console.WriteLine($"MinBalanceForRentExemption Account >> {minBalanceForExemptionAcc}"); + Console.WriteLine($"MinBalanceForRentExemption Mint Account >> {minBalanceForExemptionMint}"); + + Account ownerAccount = wallet.GetAccount(10); + Account mintAccount = wallet.GetAccount(1002); + Account initialAccount = wallet.GetAccount(1102); + Console.WriteLine($"OwnerAccount: {ownerAccount}"); + Console.WriteLine($"MintAccount: {mintAccount}"); + Console.WriteLine($"InitialAccount: {initialAccount}"); + + byte[] msgData = new TransactionBuilder() + .SetRecentBlockHash(blockHash.Result.Value.Blockhash) + .SetFeePayer(ownerAccount) + .AddInstruction(TokenProgram.InitializeMint( + mintAccount.PublicKey, + 2, + ownerAccount.PublicKey, + ownerAccount.PublicKey)) + .AddInstruction(SystemProgram.AllocateWithSeed( + new PublicKey("EME9GxLahsC1mjopepKMJg9RtbUu37aeLaQyHVdEd7vZ"), + new PublicKey("Gg12mmahG97PDACxKiBta7ch2kkqDkXUzjn5oAcbPZct"), + "Some Seed", + 165UL, + new PublicKey("J6WZY5nuYGJmfFtBGZaXgwZSRVuLWxNR6gd4d3XTHqTk"))) + .AddInstruction(SystemProgram.TransferWithSeed( + new PublicKey("Gg12mmahG97PDACxKiBta7ch2kkqDkXUzjn5oAcbPZct"), + new PublicKey("EME9GxLahsC1mjopepKMJg9RtbUu37aeLaQyHVdEd7vZ"), + "Some Seed", + new PublicKey("5omQJtDUHA3gMFdHEQg1zZSvcBUVzey5WaKWYRmqF1Vj"), + new PublicKey("EME9GxLahsC1mjopepKMJg9RtbUu37aeLaQyHVdEd7vZ"), + 25000UL)) + .AddInstruction(TokenProgram.InitializeAccount( + initialAccount.PublicKey, + mintAccount.PublicKey, + ownerAccount.PublicKey)) + .AddInstruction(TokenProgram.MintTo( + mintAccount.PublicKey, + initialAccount.PublicKey, + 1_000_000, + ownerAccount)) + .AddInstruction(MemoProgram.NewMemo(initialAccount, "Hello from Sol.Net")) + .CompileMessage(); + + + Console.WriteLine($"Message: {Convert.ToBase64String(msgData)}"); + var txx = Transaction.Populate(Convert.ToBase64String(msgData), + new List { ownerAccount.Sign(msgData), mintAccount.Sign(msgData), initialAccount.Sign(msgData) }); + + byte[] txBytes = txx.Serialize(); + + var txSim = RpcClient.SimulateTransaction(txBytes); + string logs = Examples.PrettyPrintTransactionSimulationLogs(txSim.Result.Value.Logs); + Console.WriteLine($"Transaction Simulation:\n\tError: {txSim.Result.Value.Error}\n\tLogs: \n" + logs); + + Console.WriteLine("\tDECODING TRANSACTION FROM WIRE FORMAT\t"); + Transaction tx = Transaction.Deserialize(txBytes); + Console.WriteLine($"FeePayer: {tx.FeePayer}"); + Console.WriteLine($"BlockHash/Nonce: {tx.RecentBlockHash}"); + foreach (SignaturePubKeyPair signaturePubKeyPair in tx.Signatures) + { + Console.WriteLine( + $"Signer: {signaturePubKeyPair.PublicKey} \tSignature: {Encoders.Base58.EncodeData(signaturePubKeyPair.Signature)}"); + } + + foreach (TransactionInstruction txInstruction in tx.Instructions) + { + Console.WriteLine( + $"ProgramKey: {Encoders.Base58.EncodeData(txInstruction.ProgramId)}\n\tInstructionData: {Convert.ToBase64String(txInstruction.Data)}"); + foreach (AccountMeta accountMeta in txInstruction.Keys) + { + Console.WriteLine( + $"\tAccountMeta: {accountMeta.PublicKey}\tWritable: {accountMeta.IsWritable}\tSigner: {accountMeta.IsSigner}"); + } + } + + var txDecBytes = tx.Serialize(); + var txDecSim = RpcClient.SimulateTransaction(txDecBytes); + string decLogs = Examples.PrettyPrintTransactionSimulationLogs(txDecSim.Result.Value.Logs); + Console.WriteLine($"Transaction Simulation:\n\tError: {txDecSim.Result.Value.Error}\n\tLogs: \n" + decLogs); + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/TransactionDecodingExample.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/TransactionDecodingExample.cs.meta new file mode 100644 index 0000000..fdf3e34 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Examples/TransactionDecodingExample.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 11728ab55b2c5cf46b58f918bda8fb02 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions.meta new file mode 100644 index 0000000..b359e4c --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ea75ff87b33d7954a85bd71d5a3490de +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/ITokenMintResolver.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/ITokenMintResolver.cs new file mode 100644 index 0000000..c52f736 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/ITokenMintResolver.cs @@ -0,0 +1,24 @@ +using Solana.Unity.Rpc.Core.Http; +using Solana.Unity.Extensions.TokenMint; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Solana.Unity.Extensions +{ + /// + /// Contains the method used to resolve mint public key addresses into TokenDef objects. + /// + public interface ITokenMintResolver + { + /// + /// Resolve a mint public key address into a TokenDef object. + /// + /// + /// An instance of the TokenDef containing known info about this token or a constructed unknown entry. + TokenDef Resolve(string tokenMint); + + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/ITokenMintResolver.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/ITokenMintResolver.cs.meta new file mode 100644 index 0000000..6a2df26 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/ITokenMintResolver.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 493df82825453f54d8f3cb7186ef63a0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/ITokenWalletRpcProxy.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/ITokenWalletRpcProxy.cs new file mode 100644 index 0000000..dcf400c --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/ITokenWalletRpcProxy.cs @@ -0,0 +1,56 @@ +using Solana.Unity.Rpc.Core.Http; +using Solana.Unity.Rpc.Messages; +using Solana.Unity.Rpc.Models; +using Solana.Unity.Rpc.Types; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Solana.Unity.Extensions +{ + /// + /// This interface contains the subset of methods from RPC client used by TokenWallet. + /// + public interface ITokenWalletRpcProxy + { + + /// + /// Gets the balance asynchronously for a certain public key. + /// + /// The commitment parameter is optional, the default value is not sent. + /// + /// + /// The public key. + /// The state commitment to consider when querying the ledger state. + /// A task which may return a request result holding the context and address balance. + Task>> GetBalanceAsync(string pubKey, Commitment commitment = Commitment.Finalized); + + /// + /// Gets all SPL Token accounts by token owner. + /// + /// Public key of account owner query, as base-58 encoded string. + /// Public key of the specific token Mint to limit accounts to, as base-58 encoded string. + /// Public key of the Token program ID that owns the accounts, as base-58 encoded string. + /// The state commitment to consider when querying the ledger state. + /// Returns a task that holds the asynchronous operation result and state. + Task>>> GetTokenAccountsByOwnerAsync( + string ownerPubKey, string tokenMintPubKey = null, string tokenProgramId = null, Commitment commitment = Commitment.Finalized); + + /// + /// Gets a recent block hash. + /// + /// The state commitment to consider when querying the ledger state. + /// Returns a task that holds the asynchronous operation result and state. + Task>> GetRecentBlockHashAsync(Commitment commitment = Commitment.Finalized); + + /// + /// Sends a transaction. + /// + /// The signed transaction as byte array. + /// If true skip the prflight transaction checks (default false). + /// The block commitment used to retrieve block hashes and verify success. + /// Returns a task that holds the asynchronous operation result and state. + Task> SendTransactionAsync(byte[] transaction, bool skipPreflight = false, + Commitment commitment = Commitment.Finalized); + + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/ITokenWalletRpcProxy.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/ITokenWalletRpcProxy.cs.meta new file mode 100644 index 0000000..31b0e47 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/ITokenWalletRpcProxy.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e8755f8b26e7a9d4aa9648f4297aca34 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/Models.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/Models.meta new file mode 100644 index 0000000..ee4cb34 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/Models.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7ae1ab713b10d004594d1c63ba9cc49d +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/Models/TokenMint.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/Models/TokenMint.meta new file mode 100644 index 0000000..871f699 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/Models/TokenMint.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 32efa430b55eb554b90c402378d8c314 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/Models/TokenMint/TokenDef.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/Models/TokenMint/TokenDef.cs new file mode 100644 index 0000000..a9ce923 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/Models/TokenMint/TokenDef.cs @@ -0,0 +1,165 @@ +using System; +using System.Collections.Generic; + +namespace Solana.Unity.Extensions.TokenMint +{ + /// + /// Token Definition object used by the TokenMintResolver + /// TokenMint uniquely identifies a token on the Solana blockchain. + /// Symbol is purley cosmetic and is not sufficient to uniquely identify a token by itself. + /// + public class TokenDef + { + + /// + /// Constructs a TokenDef instance. + /// + /// The public key of the token mint address. + /// The display name for this token. + /// The token symbol used to display balances of this token. + /// + public TokenDef(string mint, string name, string symbol, int decimalPlaces) + { + TokenMint = mint ?? throw new ArgumentNullException(nameof(mint)); + TokenName = name ?? throw new ArgumentNullException(nameof(name)); + Symbol = symbol ?? throw new ArgumentNullException(nameof(symbol)); + DecimalPlaces = decimalPlaces; + } + + /// + /// The public key of the token mint address. + /// + public string TokenMint { get; init; } + + /// + /// The display name of this token, either user supplied or loaded from tokenlist.json + /// + public string TokenName { get; init; } + + /// + /// The symbol to use when displaying balances of this token to a user. + /// + public string Symbol { get; init; } + + /// + /// The number of decimal places this token uses. + /// + public int DecimalPlaces { get; init; } + + /// + /// The Coingecko identifier as supplied by the standard Solana token list or null + /// + public string CoinGeckoId { get; init; } + + /// + /// The token project / more info url as supplied by the standard Solana token list or null + /// + public string TokenProjectUrl { get; init; } + + /// + /// The token logo url as supplied by the standard Solana token list or null + /// + public string TokenLogoUrl { get; init; } + + /// + /// Create an instance of the TokenQuantity object with the raw token quanity value provided. + /// + /// Value as decimal. + /// Value as ulong. + /// A TokenQuantity instance. + public TokenQuantity CreateQuantity(decimal valueDecimal, ulong valueRaw) + { + return new TokenQuantity(this, valueDecimal, valueRaw); + } + + /// + /// Create an instance of the TokenQuantity object with the raw token quanity value provided. + /// + /// Value as ulong. + /// A TokenQuantity instance. + public TokenQuantity CreateQuantityWithRaw(ulong value) + { + return CreateQuantity(ConvertUlongToDecimal(value), value); + } + + /// + /// Create an instance of the TokenQuantity object with the decimal token quanity value provided. + /// + /// + /// A TokenQuantity instance. + public TokenQuantity CreateQuantityWithDecimal(decimal value) + { + return CreateQuantity(value, ConvertDecimalToUlong(value)); + } + + /// + /// Helper method to convert a decimal value to ulong value for this token's number of decimal places. + /// based on the number of decimal places + /// + /// + /// + public ulong ConvertDecimalToUlong(decimal value) + { + if (DecimalPlaces < 0) throw new ApplicationException($"DecimalPlaces is unknown for mint {TokenMint}"); + decimal impliedAmount = value; + for (int ix = 0; ix < DecimalPlaces; ix++) impliedAmount = decimal.Multiply(impliedAmount, 10); + ulong raw = Convert.ToUInt64(decimal.Floor(impliedAmount)); + return raw; + } + + /// + /// Helper method to convert a raw ulong to decimal value for this token's number of decimal places. + /// based on the number of decimal places + /// + /// + /// + public decimal ConvertUlongToDecimal(ulong value) + { + if (DecimalPlaces < 0) throw new ApplicationException($"DecimalPlaces is unknown for mint {TokenMint}"); + decimal impliedAmount = value; + for (int ix = 0; ix < DecimalPlaces; ix++) impliedAmount = decimal.Divide(impliedAmount, 10); + return impliedAmount; + } + + /// + /// Creates a clone of this TokenDef instance setting the decimalPlaces. + /// Used to go from a TokenDef with unknown decimal places (-1) to known decimal places. + /// + /// Number of decimal places for this token. + /// A new TokenDef instance. + internal TokenDef CloneWithKnownDecimals(int decimalPlaces) + { + if (decimalPlaces < 0) throw new ArgumentOutOfRangeException("Decimal places must be 0+"); + return new TokenDef(this.TokenMint, this.TokenName, this.Symbol, decimalPlaces) + { + CoinGeckoId = this.CoinGeckoId, + TokenLogoUrl = this.TokenLogoUrl, + TokenProjectUrl = this.TokenProjectUrl + }; + } + + + } + + /// + /// Internal class used to deserialize tokenlist.json + /// + internal class TokenListDoc + { + public IList tokens { get; set; } + } + + /// + /// Internal class used to deserialize tokenlist.json + /// + internal class TokenListItem + { + public string Address { get; set; } + public string Symbol { get; set; } + public string Name { get; set; } + public int Decimals { get; set; } + public string LogoUri { get; set; } + public Dictionary Extensions { get; set; } + } + +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/Models/TokenMint/TokenDef.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/Models/TokenMint/TokenDef.cs.meta new file mode 100644 index 0000000..28af457 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/Models/TokenMint/TokenDef.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2ed26a4680bd6034e8ac160b50d205db +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/Models/TokenWallet.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/Models/TokenWallet.meta new file mode 100644 index 0000000..f77e345 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/Models/TokenWallet.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: cfde91fa026cf674e812279eaa4e82bf +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/Models/TokenWallet/TokenQuantity.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/Models/TokenWallet/TokenQuantity.cs new file mode 100644 index 0000000..2981904 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/Models/TokenWallet/TokenQuantity.cs @@ -0,0 +1,100 @@ +using Solana.Unity.Extensions.TokenMint; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Solana.Unity.Extensions +{ + /// + /// Represents a token quantity of a known mint with a known number of decimal places. + /// + public class TokenQuantity + { + + /// + /// Constructs a TokenQuantity instance. + /// + /// A TokenDef instance that describes this token. + /// Token balance in decimal. + /// Token balance in raw ulong. + internal TokenQuantity(TokenDef tokenDef, + decimal balanceDecimal, + ulong balanceRaw) + { + TokenDef = tokenDef ?? throw new ArgumentNullException(nameof(tokenDef)); + Symbol = tokenDef.Symbol; + TokenName = tokenDef.TokenName; + TokenMint = tokenDef.TokenMint; + DecimalPlaces = tokenDef.DecimalPlaces; + QuantityDecimal = balanceDecimal; + QuantityRaw = balanceRaw; + } + + /// + /// The origin TokenDef instance + /// + public TokenDef TokenDef { get; init; } + + /// + /// The token mint public key address. + /// + public string TokenMint { get; init; } + + /// + /// The symbol this token uses. + /// + public string Symbol { get; init; } + + /// + /// The name of this token. + /// + public string TokenName { get; init; } + + /// + /// The number of decimal places this token uses. + /// + public int DecimalPlaces { get; init; } + + /// + /// Token balance in decimal. + /// + public decimal QuantityDecimal { get; init; } + + /// + /// Token balance in raw ulong. + /// + public ulong QuantityRaw { get; init; } + + /// + /// Provide a friendly to read balance with symbol and name. + /// + /// + public override string ToString() + { + if (Symbol == TokenName) + return $"{QuantityDecimal} {Symbol}"; + else + return $"{QuantityDecimal} {Symbol} ({TokenName})"; + } + + /// + /// Add the value of another TokenQuantity to this TokenQuantity. + /// + /// Number of tokens as decimal to add to this TokenQuantity. + /// Number of tokens as ulong to add to this TokenQuantity. + /// A new instance with this TokenQuantity added to the accumulators. + internal TokenQuantity AddQuantity(decimal valueDecimal, + ulong valueRaw) + { + + return new TokenQuantity(this.TokenDef, + QuantityDecimal + valueDecimal, + QuantityRaw + valueRaw); + + } + + } + +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/Models/TokenWallet/TokenQuantity.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/Models/TokenWallet/TokenQuantity.cs.meta new file mode 100644 index 0000000..7a918ab --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/Models/TokenWallet/TokenQuantity.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6ffac041cd063584c807a43319cc5134 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/Models/TokenWallet/TokenWalletAccount.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/Models/TokenWallet/TokenWalletAccount.cs new file mode 100644 index 0000000..21a4a35 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/Models/TokenWallet/TokenWalletAccount.cs @@ -0,0 +1,59 @@ +using Solana.Unity.Extensions.TokenMint; +using System; + +namespace Solana.Unity.Extensions +{ + /// + /// A token balance for an individual token account. + /// + public class TokenWalletAccount : TokenWalletBalance + { + /// + /// The public key of the account. + /// + public string PublicKey { get; init; } + + /// + /// The owner public key of the account. + /// + public string Owner { get; init; } + + /// + /// A flag to indicate whether this account is an Associated Token Account. + /// + public bool IsAssociatedTokenAccount { get; init; } + + /// + /// Construct an instance of the TokenWalletAccount. + /// + /// A TokenDef instance that describes this token. + /// Token balance in decimal. + /// Token balance in raw ulong. + /// How many lamports does this balance represent. + /// The public key of the account. + /// The owner public key of the account. + /// A flag to indicate whether this account is an Associated Token Account. + internal TokenWalletAccount(TokenDef tokenDef, + decimal balanceDecimal, + ulong balanceRaw, + ulong lamportsRaw, + string publicKey, + string owner, + bool isAta) : base(tokenDef, balanceDecimal, balanceRaw, lamportsRaw, 1) + { + PublicKey = publicKey ?? throw new ArgumentNullException(nameof(publicKey)); + Owner = owner ?? throw new ArgumentNullException(nameof(owner)); + IsAssociatedTokenAccount = isAta; + } + + /// + /// Provide a friendly to read balance with symbol and name and an ATA indicator. + /// + /// + public override string ToString() + { + return $"{base.ToString()} {(IsAssociatedTokenAccount ? "[ATA]" : "")}"; + } + + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/Models/TokenWallet/TokenWalletAccount.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/Models/TokenWallet/TokenWalletAccount.cs.meta new file mode 100644 index 0000000..8dce3ef --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/Models/TokenWallet/TokenWalletAccount.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8d1a5d3370b81c140ae1a73e76cbec01 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/Models/TokenWallet/TokenWalletBalance.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/Models/TokenWallet/TokenWalletBalance.cs new file mode 100644 index 0000000..2101772 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/Models/TokenWallet/TokenWalletBalance.cs @@ -0,0 +1,82 @@ +using Solana.Unity.Extensions.TokenMint; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Solana.Unity.Extensions +{ + /// + /// A consolidated token balance for a number of accounts of a given mint. + /// + public class TokenWalletBalance : TokenQuantity + { + + /// + /// Constructs a TokenWalletBalance instance. + /// + /// A TokenDef instance that describes this token. + /// Token balance in decimal. + /// Token balance in raw ulong. + /// How many lamports does this balance represent. + /// The number of accounts this balance represents. Start with 1. + internal TokenWalletBalance(TokenDef tokenDef, + decimal balanceDecimal, + ulong balanceRaw, + ulong lamportsRaw, + int accountCount) : base(tokenDef, + balanceDecimal, + balanceRaw) + { + Lamports = lamportsRaw; + AccountCount = accountCount; + } + + /// + /// How many lamports does this balance represent. + /// + public ulong Lamports { get; init; } + + /// + /// The number of accounts this balance represents. + /// + public int AccountCount { get; init; } + + /// + /// Provide a friendly to read balance with symbol and name. + /// + /// + public override string ToString() + { + if (Symbol == TokenName) + return $"{QuantityDecimal} {Symbol}"; + else + return $"{QuantityDecimal} {Symbol} ({TokenName})"; + } + + /// + /// Add the value of an account to this consolidated balance. + /// + /// Number of tokens as decimal to add to this consolidated balance. + /// Number of tokens as ulong to add to this consolidated balance. + /// Number of lamports to add to this consolidated balance. + /// Number of accounts to add to this consolidated balance. + /// A new instance with this account provdided added to the accumulators. + internal TokenWalletBalance AddAccount(decimal valueDecimal, + ulong valueRaw, + ulong lamportsRaw, + int accountCount) + { + + return new TokenWalletBalance( + this.TokenDef, + QuantityDecimal + valueDecimal, + QuantityRaw + valueRaw, Lamports + lamportsRaw, + AccountCount + accountCount); + + } + + } + +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/Models/TokenWallet/TokenWalletBalance.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/Models/TokenWallet/TokenWalletBalance.cs.meta new file mode 100644 index 0000000..57ce41d --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/Models/TokenWallet/TokenWalletBalance.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4c7f77a5bc721f44786053e044d79ff7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/Models/TokenWallet/TokenWalletFilterList.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/Models/TokenWallet/TokenWalletFilterList.cs new file mode 100644 index 0000000..a417f9c --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/Models/TokenWallet/TokenWalletFilterList.cs @@ -0,0 +1,159 @@ +using Solana.Unity.Extensions.TokenMint; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; + +namespace Solana.Unity.Extensions.Models +{ + /// + /// A filterable list of TokenWalletAccounts. + /// Use the filter methods to select the accounts that you want to interact with. + /// To filter a subset of accounts, see ForToken, WithSymbol, WithMint, WithAtLeast, WhichAreAssociatedTokenAccounts, + /// To select individual accounts, see: WithPublicKey, AssociatedTokenAccount + /// + public class TokenWalletFilterList : IEnumerable + { + /// + /// Private list storage. + /// + private IList _list; + + /// + /// Constructs an instance of TokenWalletFilterList with a list of accounts. + /// + /// Some accounts to add to the list. + public TokenWalletFilterList(IEnumerable accounts) + { + _list = new List(accounts ?? throw new ArgumentNullException(nameof(accounts))); + } + + /// + /// Get an enumerator for this list. + /// + /// An enumerator for this list. + public IEnumerator GetEnumerator() + { + return _list.GetEnumerator(); + } + + /// + /// Get an enumerator for this list. + /// + /// An enumerator for this list. + IEnumerator IEnumerable.GetEnumerator() + { + return _list.GetEnumerator(); + } + + /// + /// Keeps all accounts that match the TokenDef provided. + /// + /// An instance of TokenDef to use for filtering. + /// A filtered list of accounts that match the supplied TokenDef. + public TokenWalletFilterList ForToken(TokenDef token) + { + if (token == null) throw new ArgumentNullException(nameof(token)); + return new TokenWalletFilterList(_list.Where(x => x.TokenMint == token.TokenMint)); + } + + /// + /// Keeps all accounts with the token symbol supplied. + /// Be aware that token symbol does not guarentee you are interacting with the TokenMint you think. + /// It is much safer to identify tokens using their token mint public key address. + /// + /// A token symbol, e.g. USDC + /// A filtered list of accounts for the given token symbol. + public TokenWalletFilterList WithSymbol(string symbol) + { + if (string.IsNullOrWhiteSpace(symbol)) throw new ArgumentException(nameof(symbol)); + return new TokenWalletFilterList(_list.Where(x => x.Symbol == symbol)); + } + + /// + /// Get the TokenWalletAccount for the public key provided. + /// + /// Public key for the account + /// The account with the matching public key or null if not found. + public TokenWalletAccount WithPublicKey(string publicKey) + { + if (string.IsNullOrWhiteSpace(publicKey)) throw new ArgumentException(nameof(publicKey)); + return new TokenWalletFilterList(_list.Where(x => x.PublicKey == publicKey)).FirstOrDefault(); + } + + /// + /// Keeps all accounts for the given token mint address. + /// + /// Token mint public key address. + /// A filtered list of accounts for the given mint. + public TokenWalletFilterList WithMint(string mint) + { + return new TokenWalletFilterList(_list.Where(x => x.TokenMint == mint)); + } + + /// + /// Keeps all accounts with at least the supplied minimum balance. + /// + /// A minimum balance value as decimal. + /// A filtered list of accounts with at least the balance as decimal supplied. + public TokenWalletFilterList WithAtLeast(decimal minimumBalance) + { + return new TokenWalletFilterList(_list.Where(x => x.QuantityDecimal >= minimumBalance)); + } + + /// + /// Keeps all accounts with at least the supplied minimum balance. + /// + /// A minimum balance value as ulong. + /// A filtered list of accounts with at least the balance as raw ulong supplied. + public TokenWalletFilterList WithAtLeast(ulong minimumBalance) + { + return new TokenWalletFilterList(_list.Where(x => x.QuantityRaw == minimumBalance)); + } + + /// + /// Keeps all accounts with a non-zero balance. + /// + /// A filtered list of accounts with at least the balance as raw ulong supplied. + public TokenWalletFilterList WithNonZero() + { + return new TokenWalletFilterList(_list.Where(x => x.QuantityRaw > 0)); + } + + /// + /// Keeps all Associated Token Account instances in the list. + /// + /// A filtered list that only contains Associated Token Accounts. + public TokenWalletFilterList WhichAreAssociatedTokenAccounts() + { + return new TokenWalletFilterList(_list.Where(x => x.IsAssociatedTokenAccount)); + } + + /// + /// Return the first associated account found in the list or null. + /// Typically this would be used immediately after a WithMint + /// for ForToken filter to identify the Associated Token Account for that token. + /// + /// The first matching Assocated Token Accounts in the list or null if none were found. + public TokenWalletAccount AssociatedTokenAccount() + { + var list = WhichAreAssociatedTokenAccounts(); + if (list.Count() >= 1) + return list.First(); + else + return null; + } + + /// + /// Keeps all instances that satisfy the filter provided. + /// + /// The filter to use. + /// A filtered list that only contains matching. + public TokenWalletFilterList WithCustomFilter(Predicate filter) + { + if (filter == null) throw new ArgumentNullException(nameof(filter)); + return new TokenWalletFilterList(_list.Where(x => filter.Invoke(x))); + } + + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/Models/TokenWallet/TokenWalletFilterList.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/Models/TokenWallet/TokenWalletFilterList.cs.meta new file mode 100644 index 0000000..5f78581 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/Models/TokenWallet/TokenWalletFilterList.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f37259bdb312d4c46b6869b92bfdb499 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/Solana.Unity.Extensions.csproj.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/Solana.Unity.Extensions.csproj.meta new file mode 100644 index 0000000..5252a1e --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/Solana.Unity.Extensions.csproj.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: ad088393155e59645bcee5f9757da5a1 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/TokenMintResolver.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/TokenMintResolver.cs new file mode 100644 index 0000000..33c6f36 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/TokenMintResolver.cs @@ -0,0 +1,192 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using Newtonsoft.Json.Linq; +using Newtonsoft.Json.Serialization; +using Solana.Unity.Extensions.TokenMint; +using System; +using System.Collections.Generic; +using System.Net; +using System.Threading.Tasks; + +namespace Solana.Unity.Extensions +{ + /// + /// The default implementation of the TokenMintResolver. + /// You can create your own by implementing ITokenMintResolver. + /// You can use the Load method to load the Solana ecosystem's standard token list or + /// populate your own instance with TokenDef objects. + /// + public class TokenMintResolver : ITokenMintResolver + { + + /// + /// The URL of the standard token list + /// + private const string TOKENLIST_GITHUB_URL = "https://raw.githubusercontent.com/solana-labs/token-list/main/src/tokens/solana.tokenlist.json"; + + /// + /// Internal lookfor for resolving mint public key addresses to TokenDef objects. + /// + private Dictionary _tokens; + + /// + /// Map of known tokens. + /// + public IReadOnlyDictionary KnownTokens => _tokens; + + /// + /// Constructs an empty TokenMintResolver object. + /// + public TokenMintResolver() + { + _tokens = new Dictionary(); + } + + /// + /// Constructs an empty TokenMintResolver and populates with deserialized TokenListDoc. + /// + /// A deserialised token list. + internal TokenMintResolver(TokenListDoc tokenList) : this() + { + foreach (var token in tokenList.tokens) + { + Add(token); + } + } + + /// + /// Return an instance of the TokenMintResolver loaded with the Solana token list. + /// + /// An instance of the TokenMintResolver populated with Solana token list definitions. + public static TokenMintResolver Load() + { + return LoadAsync().Result; + } + + /// + /// Return an instance of the TokenMintResolver loaded dererialised token list JSON from the specified URL. + /// + /// + /// An instance of the TokenMintResolver populated with Solana token list definitions. + public static TokenMintResolver Load(string url) + { + return LoadAsync(url).Result; + } + + /// + /// Return an instance of the TokenMintResolver loaded with the Solana token list. + /// + /// A task that will result in an instance of the TokenMintResolver populated with Solana token list definitions. + public static async Task LoadAsync() + { + return await LoadAsync(TOKENLIST_GITHUB_URL); + } + + /// + /// Return an instance of the TokenMintResolver loaded with the Solana token list. + /// + /// A task that will result in an instance of the TokenMintResolver populated with Solana token list definitions. + public static async Task LoadAsync(string url) + { + using (var wc = new WebClient()) + { + var json = await wc.DownloadStringTaskAsync(url); + return ParseTokenList(json); + } + } + + /// + /// Return an instance of the TokenMintResolver loaded with the dererialised JSON string supplied. + /// + /// The JSON to parse - should be shaped the same as the Solana token list. + /// An instance of the TokenMintResolver populated with the deserialized JSON provided. + public static TokenMintResolver ParseTokenList(string json) + { + if (json is null) throw new ArgumentNullException(nameof(json)); + var options = new JsonSerializerSettings() + { + ContractResolver = new CamelCasePropertyNamesContractResolver(), + Converters = + { + new StringEnumConverter(new CamelCaseNamingStrategy()) + } + }; + var tokenList = JsonConvert.DeserializeObject(json, options); + return new TokenMintResolver(tokenList); + } + + /// + /// Resolve a token mint public key address into the token def. + /// + /// If a token is not known, a default Unknown TokenDef instance with be created for that mint and stashed for any future lookups. + /// + /// + /// Unknown tokens will have decimal places of -1 by design. + /// This will prevent their use when converting decimal balance values into lamports for TransactionBuilder. + /// It is unlikely this scenario will be encountered often as Unknown token are encounted by the TokenWallet Load method + /// when processing TokenAccountInfo RPC results that do contain the decimal places. + /// + /// + /// + /// + public TokenDef Resolve(string tokenMint) + { + if (tokenMint == null) throw new ArgumentNullException(nameof(tokenMint)); + if (_tokens.ContainsKey(tokenMint)) + { + return _tokens[tokenMint]; + } + else + { + var unknown = new TokenDef(tokenMint, $"Unknown {tokenMint}", string.Empty, -1); + _tokens[tokenMint] = unknown; + return unknown; + } + } + + /// + /// Add a token to the TokenMintResolver lookup. + /// Any collisions on token mint will replace the previous instance. + /// + /// An instance of TokenDef to be added. + public void Add(TokenDef token) + { + if (token is null) throw new ArgumentNullException(nameof(token)); + _tokens[token.TokenMint] = token; + } + + /// + /// Construct a TokenDef instance populated with extension goodies from the Solana token list. + /// + /// A TokenListItem instance. + internal void Add(TokenListItem tokenItem) + { + if (tokenItem is null) throw new ArgumentNullException(nameof(tokenItem)); + + // pick out the token logo or null + string logoUrl = tokenItem.LogoUri; + + // pick out the coingecko identifier if available + string coingeckoId = null; + if (tokenItem.Extensions?.ContainsKey("coingeckoId") ?? false) coingeckoId = tokenItem.Extensions["coingeckoId"].ToString(); + + // pick out the project website if available + string projectUrl = null; + if (tokenItem.Extensions?.ContainsKey("website") ?? false) projectUrl = tokenItem.Extensions["website"].ToString(); + + // construct the TokenDef instance + var token = new TokenDef(tokenItem.Address, tokenItem.Name, tokenItem.Symbol, tokenItem.Decimals) + { + CoinGeckoId = coingeckoId, + TokenLogoUrl = logoUrl, + TokenProjectUrl = projectUrl + }; + + // stash it + _tokens[token.TokenMint] = token; + } + + + } + +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/TokenMintResolver.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/TokenMintResolver.cs.meta new file mode 100644 index 0000000..c1aca2b --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/TokenMintResolver.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fc919f0110f891d4daa052e7f7fdb3d9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/TokenWallet.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/TokenWallet.cs new file mode 100644 index 0000000..64913c4 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/TokenWallet.cs @@ -0,0 +1,510 @@ +using Solana.Unity.Programs; +using Solana.Unity.Programs.Utilities; +using Solana.Unity.Rpc; +using Solana.Unity.Rpc.Builders; +using Solana.Unity.Rpc.Core.Http; +using Solana.Unity.Rpc.Models; +using Solana.Unity.Rpc.Types; +using Solana.Unity.Extensions.Models; +using Solana.Unity.Wallet; +using Solana.Unity.Wallet.Utilities; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Solana.Unity.Extensions +{ + /// + /// An object that represents the token wallet accounts that belong to a wallet address and methods to send tokens + /// to other wallets whilst transparantly handling the complexities of Associated Token Accounts. + /// Use Load method to get started and Send method to send tokens. + /// + public class TokenWallet + { + + /// + /// RPC client instance + /// + private ITokenWalletRpcProxy RpcClient { get; init; } + + /// + /// Resolver for token mint + /// + private ITokenMintResolver MintResolver { get; init; } + + /// + /// PublicKey for the wallet + /// + public PublicKey PublicKey { get; init; } + + /// + /// Cache of computed ATAs for mints + /// + private Dictionary _ataCache; + + /// + /// Native SOL balance in lamports + /// + public ulong Lamports { get; protected set; } + + /// + /// Native SOL balance as decimal + /// + public decimal Sol => SolHelper.ConvertToSol(this.Lamports); + + /// + /// List of TokenAccounts + /// + private List _tokenAccounts; + + /// + /// Private constructor, get your instances via Load methods + /// + private TokenWallet(ITokenWalletRpcProxy client, ITokenMintResolver mintResolver, PublicKey publicKey) + { + if (client is null) throw new ArgumentNullException(nameof(client)); + if (mintResolver is null) throw new ArgumentNullException(nameof(mintResolver)); + if (publicKey is null) throw new ArgumentNullException(nameof(publicKey)); + RpcClient = client; + MintResolver = mintResolver; + PublicKey = publicKey; + _ataCache = new Dictionary(); + } + + #region Overloaded Load methods + + /// + /// Load a TokenWallet instance for a given public key. + /// + /// An instance of the RPC client. + /// An instance of a mint resolver. + /// The account public key. + /// The state commitment to consider when querying the ledger state. + /// An instance of TokenWallet loaded with the token accounts of the publicKey provided. + public static TokenWallet Load(IRpcClient client, + ITokenMintResolver mintResolver, + string publicKey, + Commitment commitment = Commitment.Finalized) + { + var output = LoadAsync(new TokenWalletRpcProxy(client), mintResolver, new PublicKey(publicKey), commitment); + return output.Result; + } + + /// + /// Load a TokenWallet instance for a given public key. + /// + /// An instance of the RPC client. + /// An instance of a mint resolver. + /// The account public key. + /// The state commitment to consider when querying the ledger state. + /// An instance of TokenWallet loaded with the token accounts of the publicKey provided. + public static TokenWallet Load(IRpcClient client, + ITokenMintResolver mintResolver, + PublicKey publicKey, + Commitment commitment = Commitment.Finalized) + { + var output = LoadAsync(new TokenWalletRpcProxy(client), mintResolver, publicKey, commitment); + return output.Result; + } + + /// + /// Load a TokenWallet instance for a given public key. + /// + /// An instance of the RPC client. + /// An instance of a mint resolver. + /// The account public key. + /// The state commitment to consider when querying the ledger state. + /// An instance of TokenWallet loaded with the token accounts of the publicKey provided. + public static TokenWallet Load(ITokenWalletRpcProxy client, + ITokenMintResolver mintResolver, + string publicKey, + Commitment commitment = Commitment.Finalized) + { + if (publicKey == null) throw new ArgumentNullException(nameof(publicKey)); + var output = LoadAsync(client, mintResolver, new PublicKey(publicKey), commitment); + return output.Result; + } + + /// + /// Load a TokenWallet instance for a given public key. + /// + /// An instance of the RPC client. + /// An instance of a mint resolver. + /// The account public key. + /// The state commitment to consider when querying the ledger state. + /// An instance of TokenWallet loaded with the token accounts of the publicKey provided. + public static TokenWallet Load(ITokenWalletRpcProxy client, + ITokenMintResolver mintResolver, + PublicKey publicKey, + Commitment commitment = Commitment.Finalized) + { + var output = LoadAsync(client, mintResolver, publicKey, commitment); + return output.Result; + } + + /// + /// Load a TokenWallet instance for a given public key. + /// + /// An instance of the RPC client. + /// An instance of a mint resolver. + /// The account public key. + /// The state commitment to consider when querying the ledger state. + /// An instance of TokenWallet loaded with the token accounts of the publicKey provided. + public async static Task LoadAsync(IRpcClient client, + ITokenMintResolver mintResolver, + PublicKey publicKey, + Commitment commitment = Commitment.Finalized) + { + return await LoadAsync(new TokenWalletRpcProxy(client), mintResolver, publicKey, commitment); + } + + /// + /// Load a TokenWallet instance for a given public key. + /// + /// An instance of the RPC client. + /// An instance of a mint resolver. + /// The account public key. + /// The state commitment to consider when querying the ledger state. + /// A task that results in an instance of TokenWallet loaded with the token accounts of the publicKey provided. + public async static Task LoadAsync(ITokenWalletRpcProxy client, + ITokenMintResolver mintResolver, + PublicKey publicKey, + Commitment commitment = Commitment.Finalized) + { + if (client == null) throw new ArgumentNullException(nameof(client)); + if (mintResolver == null) throw new ArgumentNullException(nameof(mintResolver)); + if (publicKey == null) throw new ArgumentNullException(nameof(publicKey)); + if (!publicKey.IsOnCurve()) throw new ArgumentException("PublicKey not valid - check this is native wallet address (not an ATA, PDA or aux account)"); + var output = new TokenWallet(client, mintResolver, publicKey); + var unused = await output.RefreshAsync(commitment); + return output; + } + + #endregion + + /// + /// Refresh balances and token accounts + /// The state commitment to consider when querying the ledger state. + /// + public void Refresh(Commitment commitment = Commitment.Finalized) + { + var unused = RefreshAsync(commitment).Result; + } + + /// + /// Refresh balances and token accounts + /// The state commitment to consider when querying the ledger state. + /// A task that results true once complete. + /// + public async Task RefreshAsync(Commitment commitment = Commitment.Finalized) + { + + // get sol balance and token accounts + var balance = await RpcClient.GetBalanceAsync(PublicKey.Key, commitment); + var tokenAccounts = await RpcClient.GetTokenAccountsByOwnerAsync(PublicKey.Key, null, TokenProgram.ProgramIdKey, commitment); + + // handle balance response + if (balance.WasSuccessful) + Lamports = balance.Result.Value; + else + throw new TokenWalletException($"Could not load balance for {PublicKey}", balance); + + // handle token accounts response + if (tokenAccounts.WasSuccessful) + _tokenAccounts = tokenAccounts.Result.Value; + else + throw new TokenWalletException($"Could not load tokenAccounts for {PublicKey}", tokenAccounts); + + return true; + + } + + /// + /// Get consolidated token balances across all sub-accounts for each token mint in this wallet. + /// + /// An array of TokenWalletBalance objects, one per token mint in this wallet. + public TokenWalletBalance[] Balances() + { + var mintBalances = new Dictionary(); + foreach (var token in this._tokenAccounts) + { + var mint = token.Account.Data.Parsed.Info.Mint; + var lamportsRaw = token.Account.Lamports; + var balancRaw = token.Account.Data.Parsed.Info.TokenAmount.AmountUlong; + var balancDecimal = token.Account.Data.Parsed.Info.TokenAmount.AmountDecimal; + if (!mintBalances.ContainsKey(mint)) + { + var tokenDef = MintResolver.Resolve(mint); + var decimals = token.Account.Data.Parsed.Info.TokenAmount.Decimals; + + // have we gained knowledge about decimal places from token account + // where it was previously unknown? + if (tokenDef.DecimalPlaces == -1 && decimals >= 0) + tokenDef = tokenDef.CloneWithKnownDecimals(decimals); + + // create initial wallet balance for this mint + mintBalances[mint] = new TokenWalletBalance(tokenDef, balancDecimal, balancRaw, lamportsRaw, 1); + + } + else + mintBalances[mint] = mintBalances[mint].AddAccount(balancDecimal, balancRaw, lamportsRaw, 1); + } + + // transfer to output array + return mintBalances.Values.OrderBy(x => x.TokenName).ToArray(); + } + + /// + /// Returns a TokenWalletFilterList of sub-accounts in this wallet address. + /// Use the filter methods ForToken, WithSymbol, WithAtLeast, WithMint, AssociatedTokenAccount methods + /// to select the sub-account you want to use. + /// + /// + /// Results a list of TokenWalletAccounts for filtering. + public TokenWalletFilterList TokenAccounts() + { + var list = new List(); + foreach (var account in this._tokenAccounts) + { + var mint = account.Account.Data.Parsed.Info.Mint; + var ata = GetAssociatedTokenAddressForMint(mint); + var isAta = ata.ToString() == account.PublicKey; + var lamportsRaw = account.Account.Lamports; + var owner = account.Account.Data.Parsed.Info.Owner ?? PublicKey; + var decimals = account.Account.Data.Parsed.Info.TokenAmount.Decimals; + var balanceRaw = account.Account.Data.Parsed.Info.TokenAmount.AmountUlong; + var balanceDecimal = account.Account.Data.Parsed.Info.TokenAmount.AmountDecimal; + + // resolve the TokenDef + var tokenDef = MintResolver.Resolve(mint); + + // have we gained knowledge about decimal places from token account + // where it was previously unknown? + if (tokenDef.DecimalPlaces == -1 && decimals >= 0) + tokenDef = tokenDef.CloneWithKnownDecimals(decimals); + + // add the account instance + list.Add(new TokenWalletAccount(tokenDef, balanceDecimal, balanceRaw, lamportsRaw, account.PublicKey, owner, isAta)); + } + return new TokenWalletFilterList(list.OrderBy(x => x.TokenName)); + } + + /// + /// Send tokens from source to target wallet Associated Token Account for the token mint. + /// + /// + /// The source parameter is a TokenWalletAccount instance that tokens will be sent from. + /// They will be deposited into an Associated Token Account in the destination wallet. + /// If an Associated Token Account does not exist, it will be created at the cost of feePayer. + /// + /// Source account of tokens to be sent. + /// Human readable amount of tokens to send. + /// Destination wallet address. + /// PublicKey of the fee payer address. + /// Call back function used to sign the TransactionBuilder. + /// A task that results in the transaction signature submitted to the RPC node. + public RequestResult Send(TokenWalletAccount source, decimal amount, + PublicKey destination, PublicKey feePayer, + Func signTxCallback) + { + return SendAsync(source, amount, destination, feePayer, signTxCallback).Result; + } + + /// + /// Send tokens from source to target wallet Associated Token Account for the token mint. + /// + /// + /// The source parameter is a TokenWalletAccount instance that tokens will be sent from. + /// They will be deposited into an Associated Token Account in the destination wallet. + /// If an Associated Token Account does not exist, it will be created at the cost of feePayer. + /// + /// Source account of tokens to be sent. + /// Human readable amount of tokens to send. + /// Destination wallet address. + /// PublicKey of the fee payer address. + /// Call back function used to sign the TransactionBuilder. + /// The transaction signature submitted to the RPC node. + public RequestResult Send(TokenWalletAccount source, decimal amount, + string destination, PublicKey feePayer, + Func signTxCallback) + { + return SendAsync(source, amount, new PublicKey(destination), feePayer, signTxCallback).Result; + } + + /// + /// Send tokens from source to target wallet Associated Token Account for the token mint. + /// + /// + /// The source parameter is a TokenWalletAccount instance that tokens will be sent from. + /// They will be deposited into an Associated Token Account in the destination wallet. + /// If an Associated Token Account does not exist, it will be created at the cost of feePayer. + /// + /// Source account of tokens to be sent. + /// Human readable amount of tokens to send. + /// Destination wallet address. + /// PublicKey of the fee payer address. + /// Call back function used to sign the TransactionBuilder. + /// A task that results in the transaction signature submitted to the RPC node. + public async Task> SendAsync(TokenWalletAccount source, decimal amount, + string destination, PublicKey feePayer, + Func signTxCallback) + { + return await SendAsync(source, amount, new PublicKey(destination), feePayer, signTxCallback); + } + + /// + /// Send tokens from source to target wallet Associated Token Account for the token mint. + /// + /// + /// The source parameter is a TokenWalletAccount instance that tokens will be sent from. + /// They will be deposited into an Associated Token Account in the destination wallet. + /// If an Associated Token Account does not exist, it will be created at the cost of feePayer. + /// + /// Source account of tokens to be sent. + /// Human readable amount of tokens to send. + /// Destination wallet address. + /// PublicKey of the fee payer address. + /// Call back function used to sign the TransactionBuilder. + /// A task that results in the transaction signature submitted to the RPC node. + public async Task> SendAsync(TokenWalletAccount source, decimal amount, + PublicKey destination, PublicKey feePayer, + Func signTxCallback) + { + if (source == null) throw new ArgumentNullException(nameof(source)); + if (destination == null) throw new ArgumentNullException(nameof(destination)); + if (feePayer == null) throw new ArgumentNullException(nameof(feePayer)); + if (signTxCallback == null) throw new ArgumentNullException(nameof(signTxCallback)); + + // are destination and feePayer valid publicKeys? + if (!destination.IsOnCurve()) throw new ArgumentException($"Destination PublicKey {destination.Key} is invalid wallet address."); + if (!feePayer.IsOnCurve()) throw new ArgumentException($"feePayer PublicKey {feePayer.Key} is invalid wallet address."); + + // make sure source account originated from this wallet + if (source.Owner != this.PublicKey) throw new ApplicationException("Source account does not belong to this wallet."); + + // load destination wallet + TokenWallet destWallet = await TokenWallet.LoadAsync(RpcClient, MintResolver, destination); + + // get recent block hash + var blockHash = await RpcClient.GetRecentBlockHashAsync(); + + // prepare transaction + var builder = new TransactionBuilder(); + builder.SetRecentBlockHash(blockHash.Result.Value.Blockhash); + builder.SetFeePayer(feePayer); + + // create or reuse target ata for token + var targetAta = destWallet.JitCreateAssociatedTokenAccount(builder, source.TokenMint, feePayer); + + // resolve the source account TokenMint and convert to raw quantity + var tokenDef = MintResolver.Resolve(source.TokenMint); + var qtyRaw = tokenDef.ConvertDecimalToUlong(amount); + + // build transfer instruction + builder.AddInstruction( + Programs.TokenProgram.Transfer(new PublicKey(source.PublicKey), + targetAta, qtyRaw, PublicKey)); + + // request callee sign the transaction + var tx = signTxCallback.Invoke(builder); + if (tx == null) throw new ApplicationException($"Result from {signTxCallback} was null"); + + // execute + return await RpcClient.SendTransactionAsync(tx); + + } + + + /// + /// Checks for a target Associated Token Account for the given mint and prepares one if not found. + /// + /// + /// Use this method to conditionally create a target Associated Token Account in this wallet as part of your own builder. + /// + /// The TransactionBuilder create account logic will be added to if required. + /// The public key of the mint for the Associated Token Account. + /// The account that will fund the account creation if required. + /// The public key of the Associated Token Account that will be created. + public PublicKey JitCreateAssociatedTokenAccount(TransactionBuilder builder, string mint, PublicKey feePayer) + { + if (builder == null) throw new ArgumentNullException(nameof(builder)); + if (mint == null) throw new ArgumentNullException(nameof(mint)); + if (feePayer == null) throw new ArgumentNullException(nameof(feePayer)); + if (!feePayer.IsOnCurve()) throw new ArgumentException($"feePayer PublicKey {feePayer.ToString()} is invalid wallet address."); + + // find ata for this mint + var targets = TokenAccounts().WithMint(mint).WhichAreAssociatedTokenAccounts(); + if (targets.Count() == 0) + { + // derive ata address + var pubkey = GetAssociatedTokenAddressForMint(mint); + + // add instruction to create it on chain + builder.AddInstruction( + AssociatedTokenAccountProgram.CreateAssociatedTokenAccount( + feePayer, PublicKey, new PublicKey(mint))); + + // pass back for subsequent use (transfer to etc.) + return pubkey; + + } + else + { + + // use the match address + return new PublicKey(targets.First().PublicKey); + + } + + } + + + /// + /// Compute the Associated Token Account address in this wallet for a given mint. + /// + /// The public key of the mint for the Associated Token Account. + /// The public key of the Associated Token Account. + private PublicKey GetAssociatedTokenAddressForMint(string mint) + { + if (mint == null) throw new ArgumentNullException(nameof(mint)); + if (_ataCache.ContainsKey(mint)) + return _ataCache[mint]; + else + { + // derive deterministic associate token account + // see https://spl.solana.com/associated-token-account for more info + var targetPubkey = PublicKey; + var mintPubkey = new PublicKey(mint); + var address = AssociatedTokenAccountProgram.DeriveAssociatedTokenAccount(targetPubkey, mintPubkey); + _ataCache[mint] = address; + return address; + } + + } + + /// + /// Does a public key belong to a subaccount of this wallet? + /// + /// The public key of the sub-account to query. + /// True if this sub-account exists in this wallet. + public bool IsSubAccount(string pubkey) + { + if (pubkey == null) throw new ArgumentNullException(nameof(pubkey)); + return this._tokenAccounts.Any(x => x.PublicKey == pubkey); + } + + /// + /// Does a public key belong to a subaccount of this wallet? + /// + /// The public key of the sub-account to query. + /// True if this sub-account exists in this wallet. + public bool IsSubAccount(PublicKey pubkey) + { + if (pubkey == null) throw new ArgumentNullException(nameof(pubkey)); + return this._tokenAccounts.Any(x => x.PublicKey == pubkey.Key); + } + + } + +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/TokenWallet.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/TokenWallet.cs.meta new file mode 100644 index 0000000..c5b9438 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/TokenWallet.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a2a50711623ff774bb1c7ddbe93bc6a8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/TokenWalletException.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/TokenWalletException.cs new file mode 100644 index 0000000..861f795 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/TokenWalletException.cs @@ -0,0 +1,28 @@ +using Solana.Unity.Rpc.Core.Http; +using System; + +namespace Solana.Unity.Extensions +{ + /// + /// An exception thrown brown the TokenWallet that includes the failing Solnet RPC call + /// + public class TokenWalletException : ApplicationException + { + + /// + /// The failing RequestResult that caused the Exception. + /// + public IRequestResult RequestResult { get; private set; } + + /// + /// An Exception generated by an RPC failure within the TokenWallet. + /// + /// The exception message. + /// The failing RequestResult that caused the exception. + internal TokenWalletException(string message, IRequestResult failedResult) : base(message) + { + RequestResult = failedResult; + } + + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/TokenWalletException.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/TokenWalletException.cs.meta new file mode 100644 index 0000000..cb0b56e --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/TokenWalletException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0ac8a3bbc5e815e41a53675aa4b30c38 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/TokenWalletRpcProxy.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/TokenWalletRpcProxy.cs new file mode 100644 index 0000000..816c097 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/TokenWalletRpcProxy.cs @@ -0,0 +1,83 @@ +using Solana.Unity.Rpc; +using Solana.Unity.Rpc.Core.Http; +using Solana.Unity.Rpc.Messages; +using Solana.Unity.Rpc.Models; +using Solana.Unity.Rpc.Types; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Solana.Unity.Extensions +{ + /// + /// An internal RPC proxy that has everything required by TokenWallet. + /// + internal class TokenWalletRpcProxy : ITokenWalletRpcProxy + { + + /// + /// The RPC client to use. + /// + private IRpcClient _client; + + /// + /// Constructs an instance of the TokenWalletRpcProxy. + /// + /// + internal TokenWalletRpcProxy(IRpcClient client) + { + _client = client ?? throw new ArgumentNullException(nameof(client)); + } + + /// + /// Gets the balance asynchronously for a certain public key. + /// + /// The commitment parameter is optional, the default value is not sent. + /// + /// + /// The public key. + /// The state commitment to consider when querying the ledger state. + /// A task which may return a request result holding the context and address balance. + public async Task>> GetBalanceAsync(string pubKey, Commitment commitment = Commitment.Finalized) + { + return await _client.GetBalanceAsync(pubKey, commitment); + } + + /// + /// Gets a recent block hash. + /// + /// The state commitment to consider when querying the ledger state. + /// Returns a task that holds the asynchronous operation result and state. + public async Task>> GetRecentBlockHashAsync(Commitment commitment = Commitment.Finalized) + { + return await _client.GetRecentBlockHashAsync(commitment); + } + + /// + /// Gets all SPL Token accounts by token owner. + /// + /// Public key of account owner query, as base-58 encoded string. + /// Public key of the specific token Mint to limit accounts to, as base-58 encoded string. + /// Public key of the Token program ID that owns the accounts, as base-58 encoded string. + /// The state commitment to consider when querying the ledger state. + /// Returns a task that holds the asynchronous operation result and state. + public async Task>>> GetTokenAccountsByOwnerAsync(string ownerPubKey, string tokenMintPubKey = null, string tokenProgramId = null, Commitment commitment = Commitment.Finalized) + { + return await _client.GetTokenAccountsByOwnerAsync(ownerPubKey, tokenMintPubKey, tokenProgramId, commitment); + } + + /// + /// Sends a transaction. + /// + /// The signed transaction as byte array. + /// If true skip the prflight transaction checks (default false). + /// The block commitment used to retrieve block hashes and verify success. + /// Returns an object that wraps the result along with possible errors with the request. + public async Task> SendTransactionAsync(byte[] transaction, bool skipPreflight = false, Commitment commitment = Commitment.Finalized) + { + return await _client.SendTransactionAsync(transaction, skipPreflight, commitment); + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/TokenWalletRpcProxy.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/TokenWalletRpcProxy.cs.meta new file mode 100644 index 0000000..b8a8d30 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/TokenWalletRpcProxy.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6a07cf064aee4fc4cad658b1dbad7804 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/WellKnownTokens.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/WellKnownTokens.cs new file mode 100644 index 0000000..47080bf --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/WellKnownTokens.cs @@ -0,0 +1,169 @@ +using Solana.Unity.Extensions.TokenMint; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace Solana.Unity.Extensions +{ + /// + /// Defines well known tokens and their SPL Token Address, name, symbol and number of decimal places + /// + public static class WellKnownTokens + { + private static List _tokens; + + /// + /// Discover all well known tokens on class load. + /// + static WellKnownTokens() + { + // reflect to discover all defined well known tokens by class loader + var type = typeof(WellKnownTokens); + var list = new List(); + foreach (var field in type.GetFields(BindingFlags.Static | BindingFlags.Public)) + list.Add((TokenDef)field.GetValue(null)); + _tokens = list; + } + + /// + /// Get all TokenDefs in one list. + /// + /// A list of well known TokenDef + public static IList All() + { + // return new instance of list for immutability + return new List(_tokens); + } + + /// + /// Create a TokenMintResolver pre-loaded with well known tokens. + /// + /// An instance of the TokenMintResolver bootstrapped with the well known tokens. + public static TokenMintResolver CreateTokenMintResolver() + { + var resolver = new TokenMintResolver(); + foreach (var token in _tokens) + resolver.Add(token); + return resolver; + } + + /// + /// Wrapped SOL + /// + public static TokenDef WrappedSOL = new TokenDef("So11111111111111111111111111111111111111112", "Wrapped SOL", "SOL", 9); + + /// + /// USDC + /// + public static TokenDef USDC = new TokenDef("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", "USD Coin", "USDC", 6); + + /// + /// USDT + /// + public static TokenDef USDT = new TokenDef("Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB", "USDT", "USDT", 6); + + /// + /// SRM (Serum) + /// + public static TokenDef Serum = new TokenDef("SRMuApVNdxXokk5GT7XD5cUUgXMBCoAz2LHeuAoKWRt", "Serum", "SRM", 6); + + /// + /// RAY (Raydium) + /// + public static TokenDef Raydium = new TokenDef("4k3Dyjzvzp8eMZWUXbBCjEvwSkkk59S5iCNLY3QrkX6R", "Raydium", "RAY", 6); + + /// + /// FIDA (Bonfida) + /// + public static TokenDef Bonfida = new TokenDef("EchesyfXePKdLtoiZSL8pBe8Myagyy8ZRqsACNCFGnvp", "Bonfida", "FIDA", 6); + + /// + /// COPE + /// + public static TokenDef Cope = new TokenDef("8HGyAAB1yoM1ttS7pXjHMa3dukTFGQggnFFH3hJZgzQh", "Cope", "COPE", 6); + + /// + /// KIN + /// + public static TokenDef Kin = new TokenDef("kinXdEcpDQeHPEuQnqmUgtYykqKGVFq6CeVX5iAHJq6", "KIN", "KIN", 9); + + /// + /// TULIP (Tulip/Solfarm) + /// + public static TokenDef Tulip = new TokenDef("TuLipcqtGVXP9XR62wM8WWCm6a9vhLs7T1uoWBk6FDs", "Tulip", "TULIP", 6); + + /// + /// Orca + /// + public static TokenDef Orca = new TokenDef("orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE", "Orca", "ORCA", 6); + + /// + /// MNGO (Mango Markets) + /// + public static TokenDef Mango = new TokenDef("MangoCzJ36AjZyKwVj3VnYU4GTonjfVEnJmvvWaxLac", "Mango", "MNGO", 6); + + /// + /// SAMO (Samoyed Coin) + /// + public static TokenDef Samoyed = new TokenDef("7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU", "Samoyed Coin", "SAMO", 9); + + /// + /// SBR (Saber) + /// + public static TokenDef Saber = new TokenDef("Saber2gLauYim4Mvftnrasomsv6NvAuncvMEZwcLpD1", "Saber", "SBR", 6); + + /// + /// FAB (Fabric Protocol) + /// + public static TokenDef Fabric = new TokenDef("EdAhkbj5nF9sRM7XN7ewuW8C9XEUMs8P7cnoQ57SYE96", "Fabric", "FAB", 9); + + /// + /// BOP (Boring Protocol) + /// + public static TokenDef Boring = new TokenDef("BLwTnYKqf7u4qjgZrrsKeNs2EzWkMLqVCu6j8iHyrNA3", "Boring Protocol", "BOP", 9); + + /// + /// LIQ (Liquid) + /// + public static TokenDef Liquid = new TokenDef("4wjPQJ6PrkC4dHhYghwJzGBVP78DkBzA2U3kHoFNBuhj", "LIQ Protocol", "LIQ", 6); + + /// + /// Step + /// + public static TokenDef Step = new TokenDef("StepAscQoEioFxxWGnh2sLBDFp9d8rvKz2Yp39iDpyT", "Step", "STEP", 9); + + /// + /// SLRS (Solrise Finance) + /// + public static TokenDef Solrise = new TokenDef("SLRSSpSLUTP7okbCUBYStWCo1vUgyt775faPqz8HUMr", "Solrise Finance", "SLRS", 6); + + /// + /// LIKE (Only1) + /// + public static TokenDef Only1 = new TokenDef("3bRTivrVsitbmCTGtqwp7hxXPsybkjn4XLNtPsHqa3zR", "Only1", "LIKE", 9); + + /// + /// ATLAS (Star Atlas) + /// + public static TokenDef StarAtlas = new TokenDef("ATLASXmbPQxBUYbxPsV97usA3fPQYEqzQBUHgiFCUsXx", "Star Atlas", "ATLAS", 8); + + /// + /// POLIS (Star Atlas DAO) + /// + public static TokenDef StarAtlasDao = new TokenDef("poLisWXnNRwC6oBu1vHiuKQzFjGL4XDSu4g9qjz9qVk", "Star Atlas DAO", "POLIS", 8); + + /// + /// WOOF (WOOFENCOMICS) + /// + public static TokenDef Woof = new TokenDef("9nEqaUcb16sQ3Tn1psbkWqyhPdLmfHWjKGymREjsAgTE", "WOOFENOMICS", "WOOF", 6); + + /// + /// Shadow Token (SHDW) + /// + public static TokenDef ShadowToken = new TokenDef("SHDWyBxihqiCj6YekG2GUr7wqKLeLAMK1gHZck9pL6y", "Shadow Token", "SHDW", 9); + + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/WellKnownTokens.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/WellKnownTokens.cs.meta new file mode 100644 index 0000000..e7e0d12 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Extensions/WellKnownTokens.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e394dd874671e2d4499cb8eea28c168d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore.meta new file mode 100644 index 0000000..eecbe67 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d3aeda509957c7f49946a3b154731764 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Crypto.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Crypto.meta new file mode 100644 index 0000000..a7ae191 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Crypto.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 92d4d565327b363408a713befe971748 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Crypto/IRandomBytesGenerator.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Crypto/IRandomBytesGenerator.cs new file mode 100644 index 0000000..004ec0b --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Crypto/IRandomBytesGenerator.cs @@ -0,0 +1,8 @@ +namespace Solana.Unity.KeyStore.Crypto +{ + public interface IRandomBytesGenerator + { + byte[] GenerateRandomInitializationVector(); + byte[] GenerateRandomSalt(); + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Crypto/IRandomBytesGenerator.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Crypto/IRandomBytesGenerator.cs.meta new file mode 100644 index 0000000..eea1a6e --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Crypto/IRandomBytesGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fdf5603673d49ad42883b8dca60c6e66 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Crypto/KeyStoreCrypto.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Crypto/KeyStoreCrypto.cs new file mode 100644 index 0000000..f3c76da --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Crypto/KeyStoreCrypto.cs @@ -0,0 +1,113 @@ +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Solana.Unity.KeyStore.Exceptions; +using System; +using System.Text; + +namespace Solana.Unity.KeyStore.Crypto +{ + //https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition + public class KeyStoreCrypto + { + public byte[] GenerateDerivedScryptKey(byte[] password, byte[] salt, int n, int r, int p, int dkLen, bool checkRandN = false) + { + if (checkRandN) + { + if (r == 1 && n >= 65536) + { + throw new ArgumentException("Cost parameter N must be > 1 and < 65536."); + } + } + + return Scrypt.CryptoScrypt(password, salt, n, r, p, dkLen); + } + + public byte[] GenerateCipherKey(byte[] derivedKey) + { + var cypherKey = new byte[16]; + Array.Copy(derivedKey, cypherKey, 16); + return cypherKey; + } + + public byte[] CalculateKeccakHash(byte[] value) + { + var digest = new KeccakDigest(256); + var output = new byte[digest.GetDigestSize()]; + digest.BlockUpdate(value, 0, value.Length); + digest.DoFinal(output, 0); + return output; + } + + public byte[] GenerateMac(byte[] derivedKey, byte[] cipherText) + { + var result = new byte[16 + cipherText.Length]; + Array.Copy(derivedKey, 16, result, 0, 16); + Array.Copy(cipherText, 0, result, 16, cipherText.Length); + return CalculateKeccakHash(result); + } + + public byte[] GeneratePbkdf2Sha256DerivedKey(string password, byte[] salt, int count, int dklen) + { + var pdb = new Pkcs5S2ParametersGenerator(new Sha256Digest()); + + //note Pkcs5PasswordToUtf8Bytes is the same as Encoding.UTF8.GetBytes(password) + //changing it to keep it as bouncy + + pdb.Init(PbeParametersGenerator.Pkcs5PasswordToUtf8Bytes(password.ToCharArray()), salt, + count); + //if dklen == 32, then it is 256 (8 * 32) + var key = (KeyParameter)pdb.GenerateDerivedMacParameters(8 * dklen); + return key.GetKey(); + } + + public byte[] GenerateAesCtrCipher(byte[] iv, byte[] encryptKey, byte[] input) + { + var key = ParameterUtilities.CreateKeyParameter("AES", encryptKey); + + var parametersWithIv = new ParametersWithIV(key, iv); + + var cipher = CipherUtilities.GetCipher("AES/CTR/NoPadding"); + cipher.Init(true, parametersWithIv); + return cipher.DoFinal(input); + } + + public byte[] DecryptScrypt(string password, byte[] mac, byte[] iv, byte[] cipherText, int n, int p, int r, + byte[] salt, int dklen) + { + var derivedKey = GenerateDerivedScryptKey(GetPasswordAsBytes(password), salt, n, r, p, dklen, false); + return Decrypt(mac, iv, cipherText, derivedKey); + } + + public byte[] DecryptPbkdf2Sha256(string password, byte[] mac, byte[] iv, byte[] cipherText, int c, byte[] salt, + int dklen) + { + var derivedKey = GeneratePbkdf2Sha256DerivedKey(password, salt, c, dklen); + return Decrypt(mac, iv, cipherText, derivedKey); + } + + public byte[] Decrypt(byte[] mac, byte[] iv, byte[] cipherText, byte[] derivedKey) + { + ValidateMac(mac, cipherText, derivedKey); + var encryptKey = new byte[16]; + Array.Copy(derivedKey, encryptKey, 16); + var privateKey = GenerateAesCtrCipher(iv, encryptKey, cipherText); + return privateKey; + } + + private void ValidateMac(byte[] mac, byte[] cipherText, byte[] derivedKey) + { + var generatedMac = GenerateMac(derivedKey, cipherText); + if (generatedMac.ToHex() != mac.ToHex()) + throw new DecryptionException( + "Cannot derive the same mac as the one provided from the cipher and derived key"); + } + + public byte[] GetPasswordAsBytes(string password) + { + return Encoding.UTF8.GetBytes(password); + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Crypto/KeyStoreCrypto.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Crypto/KeyStoreCrypto.cs.meta new file mode 100644 index 0000000..5e305d5 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Crypto/KeyStoreCrypto.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: df8cd43e52e7b7648bae733be40b50a3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Crypto/RandomBytesGenerator.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Crypto/RandomBytesGenerator.cs new file mode 100644 index 0000000..ae3a00f --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Crypto/RandomBytesGenerator.cs @@ -0,0 +1,26 @@ +using Org.BouncyCastle.Security; + +namespace Solana.Unity.KeyStore.Crypto +{ + public class RandomBytesGenerator : IRandomBytesGenerator + { + private static readonly SecureRandom Random = new SecureRandom(); + + public byte[] GenerateRandomInitializationVector() + { + return GenerateRandomBytes(16); + } + + public byte[] GenerateRandomSalt() + { + return GenerateRandomBytes(32); + } + + private static byte[] GenerateRandomBytes(int size) + { + var bytes = new byte[size]; + Random.NextBytes(bytes); + return bytes; + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Crypto/RandomBytesGenerator.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Crypto/RandomBytesGenerator.cs.meta new file mode 100644 index 0000000..c3e9797 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Crypto/RandomBytesGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b892dd190d5e32447b012ca933d2f9da +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Crypto/Scrypt.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Crypto/Scrypt.cs new file mode 100644 index 0000000..9758cf1 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Crypto/Scrypt.cs @@ -0,0 +1,319 @@ +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Parameters; +using System; + +namespace Solana.Unity.KeyStore.Crypto +{ + public class Scrypt + { + private static byte[] SingleIterationPbkdf2(byte[] p, byte[] s, int dkLen) + { + PbeParametersGenerator pGen = new Pkcs5S2ParametersGenerator(new Sha256Digest()); + pGen.Init(p, s, 1); + KeyParameter key = (KeyParameter)pGen.GenerateDerivedMacParameters(dkLen * 8); + return key.GetKey(); + } + + public static unsafe byte[] CryptoScrypt(byte[] password, byte[] salt, int n, int r, int p, int dkLen) + { + var ba = new byte[128 * r * p + 63]; + var xYa = new byte[256 * r + 63]; + var va = new byte[128 * r * n + 63]; + var buf = new byte[32]; + + ba = SingleIterationPbkdf2(password, salt, p * 128 * r); + + fixed (byte* b = ba) + fixed (void* v = va) + fixed (void* xy = xYa) + { + /* 2: for i = 0 to p - 1 do */ + for (var i = 0; i < p; i++) + { + /* 3: B_i <-- MF(B_i, N) */ + SMix(&b[i * 128 * r], r, n, (uint*)v, (uint*)xy); + } + } + + /* 5: DK <-- PBKDF2(P, B, 1, dkLen) */ + return SingleIterationPbkdf2(password, ba, dkLen); + } + + + /// + /// Copies a specified number of bytes from a source pointer to a destination pointer. + /// + private static unsafe void BulkCopy(void* dst, void* src, int len) + { + var d = (byte*)dst; + var s = (byte*)src; + + while (len >= 8) + { + *(ulong*)d = *(ulong*)s; + d += 8; + s += 8; + len -= 8; + } + if (len >= 4) + { + *(uint*)d = *(uint*)s; + d += 4; + + s += 4; + len -= 4; + } + if (len >= 2) + { + *(ushort*)d = *(ushort*)s; + d += 2; + s += 2; + len -= 2; + } + if (len >= 1) + { + *d = *s; + } + } + + /// + /// Copies a specified number of bytes from a source pointer to a destination pointer. + /// + private static unsafe void BulkXor(void* dst, void* src, int len) + { + var d = (byte*)dst; + var s = (byte*)src; + + while (len >= 8) + { + *(ulong*)d ^= *(ulong*)s; + d += 8; + s += 8; + len -= 8; + } + if (len >= 4) + { + *(uint*)d ^= *(uint*)s; + d += 4; + s += 4; + len -= 4; + } + if (len >= 2) + { + *(ushort*)d ^= *(ushort*)s; + d += 2; + s += 2; + len -= 2; + } + if (len >= 1) + { + *d ^= *s; + } + } + + /// + /// Encode an integer to byte array on any alignment in little endian format. + /// + private static unsafe void Encode32(byte* p, uint x) + { + p[0] = (byte)(x & 0xff); + p[1] = (byte)((x >> 8) & 0xff); + p[2] = (byte)((x >> 16) & 0xff); + p[3] = (byte)((x >> 24) & 0xff); + } + + /// + /// Decode an integer from byte array on any alignment in little endian format. + /// + private static unsafe uint Decode32(byte* p) + { + return + (p[0] + + ((uint)(p[1]) << 8) + + ((uint)(p[2]) << 16) + + ((uint)(p[3]) << 24)); + } + + /// + /// Apply the salsa20/8 core to the provided block. + /// + private static unsafe void Salsa208(uint* b) + { + uint x0 = b[0]; + uint x1 = b[1]; + uint x2 = b[2]; + uint x3 = b[3]; + uint x4 = b[4]; + uint x5 = b[5]; + uint x6 = b[6]; + uint x7 = b[7]; + uint x8 = b[8]; + uint x9 = b[9]; + uint x10 = b[10]; + uint x11 = b[11]; + uint x12 = b[12]; + uint x13 = b[13]; + uint x14 = b[14]; + uint x15 = b[15]; + + for (var i = 0; i < 8; i += 2) + { + //((x0 + x12) << 7) | ((x0 + x12) >> (32 - 7)); + /* Operate on columns. */ + x4 ^= R(x0 + x12, 7); x8 ^= R(x4 + x0, 9); + x12 ^= R(x8 + x4, 13); x0 ^= R(x12 + x8, 18); + + x9 ^= R(x5 + x1, 7); x13 ^= R(x9 + x5, 9); + x1 ^= R(x13 + x9, 13); x5 ^= R(x1 + x13, 18); + + x14 ^= R(x10 + x6, 7); x2 ^= R(x14 + x10, 9); + x6 ^= R(x2 + x14, 13); x10 ^= R(x6 + x2, 18); + + x3 ^= R(x15 + x11, 7); x7 ^= R(x3 + x15, 9); + x11 ^= R(x7 + x3, 13); x15 ^= R(x11 + x7, 18); + + /* Operate on rows. */ + x1 ^= R(x0 + x3, 7); x2 ^= R(x1 + x0, 9); + x3 ^= R(x2 + x1, 13); x0 ^= R(x3 + x2, 18); + + x6 ^= R(x5 + x4, 7); x7 ^= R(x6 + x5, 9); + x4 ^= R(x7 + x6, 13); x5 ^= R(x4 + x7, 18); + + x11 ^= R(x10 + x9, 7); x8 ^= R(x11 + x10, 9); + x9 ^= R(x8 + x11, 13); x10 ^= R(x9 + x8, 18); + + x12 ^= R(x15 + x14, 7); x13 ^= R(x12 + x15, 9); + x14 ^= R(x13 + x12, 13); x15 ^= R(x14 + x13, 18); + } + + b[0] += x0; + b[1] += x1; + b[2] += x2; + b[3] += x3; + b[4] += x4; + b[5] += x5; + b[6] += x6; + b[7] += x7; + b[8] += x8; + b[9] += x9; + b[10] += x10; + b[11] += x11; + b[12] += x12; + b[13] += x13; + b[14] += x14; + b[15] += x15; + } + + /// + /// Utility method for Salsa208. + /// + private static unsafe uint R(uint a, int b) + { + return (a << b) | (a >> (32 - b)); + } + + /// + /// Compute Bout = BlockMix_{salsa20/8, r}(Bin). The input Bin must be 128r + /// bytes in length; the output Bout must also be the same size. + /// The temporary space X must be 64 bytes. + /// + private static unsafe void BlockMix(uint* bin, uint* bout, uint* x, int r) + { + /* 1: X <-- B_{2r - 1} */ + BulkCopy(x, &bin[(2 * r - 1) * 16], 64); + + /* 2: for i = 0 to 2r - 1 do */ + for (var i = 0; i < 2 * r; i += 2) + { + /* 3: X <-- H(X \xor B_i) */ + BulkXor(x, &bin[i * 16], 64); + Salsa208(x); + + /* 4: Y_i <-- X */ + /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ + BulkCopy(&bout[i * 8], x, 64); + + /* 3: X <-- H(X \xor B_i) */ + BulkXor(x, &bin[i * 16 + 16], 64); + Salsa208(x); + + /* 4: Y_i <-- X */ + /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ + BulkCopy(&bout[i * 8 + r * 16], x, 64); + } + } + + /// + /// Return the result of parsing B_{2r-1} as a little-endian integer. + /// + private static unsafe long Integerify(uint* b, int r) + { + var x = (uint*)(((byte*)b) + (2 * r - 1) * 64); + + return (((long)(x[1]) << 32) + x[0]); + } + + /// + /// Compute B = SMix_r(B, N). The input B must be 128r bytes in length; + /// the temporary storage V must be 128rN bytes in length; the temporary + /// storage XY must be 256r + 64 bytes in length. The value N must be a + /// power of 2 greater than 1. The arrays B, V, and XY must be aligned to a + /// multiple of 64 bytes. + /// + private static unsafe void SMix(byte* b, int r, int n, uint* v, uint* xy) + { + var x = xy; + var y = &xy[32 * r]; + var z = &xy[64 * r]; + + /* 1: X <-- B */ + for (var k = 0; k < 32 * r; k++) + { + x[k] = Decode32(&b[4 * k]); + } + + /* 2: for i = 0 to N - 1 do */ + for (var i = 0L; i < n; i += 2) + { + /* 3: V_i <-- X */ + BulkCopy(&v[i * (32 * r)], x, 128 * r); + + /* 4: X <-- H(X) */ + BlockMix(x, y, z, r); + + /* 3: V_i <-- X */ + BulkCopy(&v[(i + 1) * (32 * r)], y, 128 * r); + + /* 4: X <-- H(X) */ + BlockMix(y, x, z, r); + } + + /* 6: for i = 0 to N - 1 do */ + for (var i = 0; i < n; i += 2) + { + /* 7: j <-- Integerify(X) mod N */ + var j = Integerify(x, r) & (n - 1); + + /* 8: X <-- H(X \xor V_j) */ + BulkXor(x, &v[j * (32 * r)], 128 * r); + BlockMix(x, y, z, r); + + /* 7: j <-- Integerify(X) mod N */ + j = Integerify(y, r) & (n - 1); + + /* 8: X <-- H(X \xor V_j) */ + BulkXor(y, &v[j * (32 * r)], 128 * r); + BlockMix(y, x, z, r); + } + + /* 10: B' <-- X */ + for (var k = 0; k < 32 * r; k++) + { + Encode32(&b[4 * k], x[k]); + } + } + + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Crypto/Scrypt.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Crypto/Scrypt.cs.meta new file mode 100644 index 0000000..6a8eb73 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Crypto/Scrypt.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dcb9e074ea9f1f446ad0c65e88c1cc7e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Exceptions.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Exceptions.meta new file mode 100644 index 0000000..316a782 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Exceptions.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f4ab8d246d8211849ac8621a613e5b6e +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Exceptions/DecryptionException.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Exceptions/DecryptionException.cs new file mode 100644 index 0000000..86a7c98 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Exceptions/DecryptionException.cs @@ -0,0 +1,11 @@ +using System; + +namespace Solana.Unity.KeyStore.Exceptions +{ + public class DecryptionException : Exception + { + internal DecryptionException(string msg) : base(msg) + { + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Exceptions/DecryptionException.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Exceptions/DecryptionException.cs.meta new file mode 100644 index 0000000..ab9fa02 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Exceptions/DecryptionException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 100a09e8584ac8540adeaeb889409368 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Exceptions/InvalidKdfException.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Exceptions/InvalidKdfException.cs new file mode 100644 index 0000000..728c33d --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Exceptions/InvalidKdfException.cs @@ -0,0 +1,11 @@ +using System; + +namespace Solana.Unity.KeyStore.Exceptions +{ + public class InvalidKdfException : Exception + { + public InvalidKdfException(string kdf) : base("Invalid kdf:" + kdf) + { + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Exceptions/InvalidKdfException.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Exceptions/InvalidKdfException.cs.meta new file mode 100644 index 0000000..0af59fa --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Exceptions/InvalidKdfException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 623354f0a2b04cb489046a1c73ab2736 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/KeyStoreKdfChecker.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/KeyStoreKdfChecker.cs new file mode 100644 index 0000000..e926200 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/KeyStoreKdfChecker.cs @@ -0,0 +1,59 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using Solana.Unity.KeyStore.Exceptions; +using Solana.Unity.KeyStore.Model; +using Solana.Unity.KeyStore.Services; +using System; +using System.Runtime.Serialization; + +namespace Solana.Unity.KeyStore +{ + /// + /// Implements a checker for the 's . + /// + public static class KeyStoreKdfChecker + { + /// + /// Get the kdf type string from the json document. + /// + /// The json document. + /// The kdf type string. + /// Throws exception when json property crypto or kdf couldn't be found + private static string GetKdfTypeFromJson(JObject keyStoreDocument) + { + var cryptoObj = keyStoreDocument.Property("crypto"); + if (cryptoObj == null) throw new JsonException("could not get crypto params object from json"); + + var kdfObj = ((JObject)cryptoObj.Value).Property("kdf"); + if (kdfObj == null) throw new JsonException("could not get kdf object from json"); + + return kdfObj.Value.ToString(); + } + + /// + /// Gets the kdf type from the json keystore. + /// + /// The json keystore. + /// The kdf type. + /// Throws exception when json param is null. + /// Throws exception when file could not be processed to . + /// Throws exception when kdf json property is null. + /// Throws exception when the kdf json property has an invalid value. + public static KdfType GetKeyStoreKdfType(string json) + { + if (json == null) throw new ArgumentNullException(nameof(json)); + var keyStoreDocument = JsonConvert.DeserializeObject(json); + if (keyStoreDocument == null) throw new SerializationException("could not process json"); + + var kdfString = GetKdfTypeFromJson(keyStoreDocument); + + if (kdfString == null) throw new JsonException("could not get kdf type from json"); + return kdfString switch + { + KeyStorePbkdf2Service.KdfType => KdfType.Pbkdf2, + KeyStoreScryptService.KdfType => KdfType.Scrypt, + _ => throw new InvalidKdfException(kdfString) + }; + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/KeyStoreKdfChecker.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/KeyStoreKdfChecker.cs.meta new file mode 100644 index 0000000..280b943 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/KeyStoreKdfChecker.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: aa011195ea7a7c44691bc75e6d158e6e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Model.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Model.meta new file mode 100644 index 0000000..677b774 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Model.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: bd5d6d17aa0459547bf34e57f9c0de54 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Model/CipherParams.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Model/CipherParams.cs new file mode 100644 index 0000000..e00ce9f --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Model/CipherParams.cs @@ -0,0 +1,20 @@ +using Newtonsoft.Json; + +namespace Solana.Unity.KeyStore.Model +{ + public class CipherParams + { + public CipherParams() + { + } + + public CipherParams(byte[] iv) + { + Iv = iv.ToHex(); + } + + [JsonProperty("iv")] + // ReSharper disable once MemberCanBePrivate.Global + public string Iv { get; init; } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Model/CipherParams.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Model/CipherParams.cs.meta new file mode 100644 index 0000000..73dcd8b --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Model/CipherParams.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 67b7e9ec94d0f07459f80fbb866b3185 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Model/CryptoInfo.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Model/CryptoInfo.cs new file mode 100644 index 0000000..60888a7 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Model/CryptoInfo.cs @@ -0,0 +1,52 @@ +using Newtonsoft.Json; + +namespace Solana.Unity.KeyStore.Model +{ + public class CryptoInfo where TKdfParams : KdfParams + { + public CryptoInfo() + { + } + + public CryptoInfo(string cipher, byte[] cipherText, byte[] iv, byte[] mac, byte[] salt, TKdfParams kdfParams, + string kdfType) + { + Cipher = cipher; + CipherText = cipherText.ToHex(); + Mac = mac.ToHex(); + CipherParams = new CipherParams(iv); + Kdfparams = kdfParams; + Kdfparams.Salt = salt.ToHex(); + Kdf = kdfType; + } + + [JsonProperty("cipher")] + // ReSharper disable once MemberCanBePrivate.Global + // ReSharper disable once UnusedAutoPropertyAccessor.Global + public string Cipher { get; } + + [JsonProperty("ciphertext")] + // ReSharper disable once MemberCanBePrivate.Global + public string CipherText { get; init; } + + // ReSharper disable once StringLiteralTypo + [JsonProperty("cipherparams")] + // ReSharper disable once MemberCanBePrivate.Global + public CipherParams CipherParams { get; init; } + + [JsonProperty("kdf")] + // ReSharper disable once MemberCanBePrivate.Global + // ReSharper disable once UnusedAutoPropertyAccessor.Global + public string Kdf { get; } + + [JsonProperty("mac")] + // ReSharper disable once MemberCanBePrivate.Global + public string Mac { get; init; } + + // ReSharper disable once StringLiteralTypo + [JsonProperty("kdfparams")] + // ReSharper disable once IdentifierTypo + // ReSharper disable once MemberCanBePrivate.Global + public TKdfParams Kdfparams { get; init; } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Model/CryptoInfo.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Model/CryptoInfo.cs.meta new file mode 100644 index 0000000..a8432c3 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Model/CryptoInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 03f98e5711617294dadfe8b5e13c9792 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Model/KdfParams.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Model/KdfParams.cs new file mode 100644 index 0000000..0a5861e --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Model/KdfParams.cs @@ -0,0 +1,15 @@ +using Newtonsoft.Json; + +namespace Solana.Unity.KeyStore.Model +{ + public class KdfParams + { + // ReSharper disable once StringLiteralTypo + [JsonProperty("dklen")] + // ReSharper disable once IdentifierTypo + public int Dklen { get; init; } + + [JsonProperty("salt")] + public string Salt { get; set; } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Model/KdfParams.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Model/KdfParams.cs.meta new file mode 100644 index 0000000..be9f79c --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Model/KdfParams.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 87be873658bd27d4fb39a8ed19d0d0e0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Model/KdfType.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Model/KdfType.cs new file mode 100644 index 0000000..edfbd7b --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Model/KdfType.cs @@ -0,0 +1,8 @@ +namespace Solana.Unity.KeyStore.Model +{ + public enum KdfType + { + Scrypt, + Pbkdf2 + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Model/KdfType.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Model/KdfType.cs.meta new file mode 100644 index 0000000..d628c8d --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Model/KdfType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4cbf56836f3f9384293aa4bcc2dea1f9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Model/KeyStore.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Model/KeyStore.cs new file mode 100644 index 0000000..abdafb9 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Model/KeyStore.cs @@ -0,0 +1,19 @@ +using Newtonsoft.Json; + +namespace Solana.Unity.KeyStore.Model +{ + public class KeyStore where TKdfParams : KdfParams + { + [JsonProperty("crypto")] + public CryptoInfo Crypto { get; set; } + + [JsonProperty("id")] + public string Id { get; set; } + + [JsonProperty("address")] + public string Address { get; set; } + + [JsonProperty("version")] + public int Version { get; set; } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Model/KeyStore.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Model/KeyStore.cs.meta new file mode 100644 index 0000000..c2fbb06 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Model/KeyStore.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d8455458369fe894295da57bfab377ab +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Model/Pbkdf2Params.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Model/Pbkdf2Params.cs new file mode 100644 index 0000000..ee2af17 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Model/Pbkdf2Params.cs @@ -0,0 +1,14 @@ +using Newtonsoft.Json; + +namespace Solana.Unity.KeyStore.Model +{ + public class Pbkdf2Params : KdfParams + { + [JsonProperty("c")] + public int Count { get; init; } + + [JsonProperty("prf")] + // ReSharper disable once UnusedAutoPropertyAccessor.Global + public string Prf { get; init; } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Model/Pbkdf2Params.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Model/Pbkdf2Params.cs.meta new file mode 100644 index 0000000..a596afb --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Model/Pbkdf2Params.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: aa1fd4443b39f5b4f910c63cfc9df074 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Model/ScryptParams.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Model/ScryptParams.cs new file mode 100644 index 0000000..0c1c4f3 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Model/ScryptParams.cs @@ -0,0 +1,16 @@ +using Newtonsoft.Json; + +namespace Solana.Unity.KeyStore.Model +{ + public class ScryptParams : KdfParams + { + [JsonProperty("n")] + public int N { get; init; } + + [JsonProperty("r")] + public int R { get; init; } + + [JsonProperty("p")] + public int P { get; init; } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Model/ScryptParams.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Model/ScryptParams.cs.meta new file mode 100644 index 0000000..23e7450 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Model/ScryptParams.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6fbd42fdbf97bd7439397816031d7bab +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/README.md b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/README.md new file mode 100644 index 0000000..8dfd951 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/README.md @@ -0,0 +1 @@ +# Solana.Unity.KeyStore \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/README.md.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/README.md.meta new file mode 100644 index 0000000..2bf4b02 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/README.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: e41ea1f828effc04185070c139faf4d6 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/SecretKeyStoreService.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/SecretKeyStoreService.cs new file mode 100644 index 0000000..5f9cb3d --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/SecretKeyStoreService.cs @@ -0,0 +1,81 @@ +using Solana.Unity.KeyStore.Model; +using Solana.Unity.KeyStore.Services; +using System; +using System.IO; +using System.Runtime.Serialization; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Solana.Unity.KeyStore +{ + /// + /// Implements a keystore compatible with the web3 secret storage standard. + /// + public class SecretKeyStoreService + { + private readonly KeyStoreScryptService _keyStoreScryptService; + private readonly KeyStorePbkdf2Service _keyStorePbkdf2Service; + + public SecretKeyStoreService() + { + _keyStorePbkdf2Service = new KeyStorePbkdf2Service(); + _keyStoreScryptService = new KeyStoreScryptService(); + } + + public SecretKeyStoreService(KeyStoreScryptService keyStoreScryptService, KeyStorePbkdf2Service keyStorePbkdf2Service) + { + _keyStoreScryptService = keyStoreScryptService; + _keyStorePbkdf2Service = keyStorePbkdf2Service; + } + + public static string GetAddressFromKeyStore(string json) + { + if (json == null) throw new ArgumentNullException(nameof(json)); + var keyStoreDocument = JsonConvert.DeserializeObject(json); + if (keyStoreDocument == null) throw new SerializationException("could not process json"); + + var address = keyStoreDocument.Property("address"); + if (address == null) throw new JsonException("could not get address from json"); + + return address.Value.ToString(); + } + + public static string GenerateUtcFileName(string address) + { + if (address == null) throw new ArgumentNullException(nameof(address)); + return "utc--" + DateTime.UtcNow.ToString("O").Replace(":", "-") + "--" + address; + } + + public byte[] DecryptKeyStoreFromFile(string password, string filePath) + { + if (password == null) throw new ArgumentNullException(nameof(password)); + if (filePath == null) throw new ArgumentNullException(nameof(filePath)); + + using var file = File.OpenText(filePath); + var json = file.ReadToEnd(); + return DecryptKeyStoreFromJson(password, json); + } + + public byte[] DecryptKeyStoreFromJson(string password, string json) + { + if (password == null) throw new ArgumentNullException(nameof(password)); + if (json == null) throw new ArgumentNullException(nameof(json)); + + var type = KeyStoreKdfChecker.GetKeyStoreKdfType(json); + return type switch + { + KdfType.Pbkdf2 => _keyStorePbkdf2Service.DecryptKeyStoreFromJson(password, json), + KdfType.Scrypt => _keyStoreScryptService.DecryptKeyStoreFromJson(password, json), + _ => throw new Exception("Invalid kdf type") + }; + } + + public string EncryptAndGenerateDefaultKeyStoreAsJson(string password, byte[] key, string address) + { + if (password == null) throw new ArgumentNullException(nameof(password)); + if (address == null) throw new ArgumentNullException(nameof(address)); + + return _keyStoreScryptService.EncryptAndGenerateKeyStoreAsJson(password, key, address); + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/SecretKeyStoreService.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/SecretKeyStoreService.cs.meta new file mode 100644 index 0000000..55aedfc --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/SecretKeyStoreService.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4c90b11f43156af4285233c62b96c9ee +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Serialization.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Serialization.meta new file mode 100644 index 0000000..64a63cf --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Serialization.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 205da270b99869149975ffa95b1b0be1 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Serialization/JsonKeyStorePbkdf2Serializer.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Serialization/JsonKeyStorePbkdf2Serializer.cs new file mode 100644 index 0000000..f20cb63 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Serialization/JsonKeyStorePbkdf2Serializer.cs @@ -0,0 +1,18 @@ +using Solana.Unity.KeyStore.Model; +using Newtonsoft.Json; + +namespace Solana.Unity.KeyStore.Serialization +{ + public static class JsonKeyStorePbkdf2Serializer + { + public static string SerialisePbkdf2(KeyStore pbkdf2KeyStore) + { + return JsonConvert.SerializeObject(pbkdf2KeyStore); + } + + public static KeyStore DeserializePbkdf2(string json) + { + return JsonConvert.DeserializeObject>(json); + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Serialization/JsonKeyStorePbkdf2Serializer.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Serialization/JsonKeyStorePbkdf2Serializer.cs.meta new file mode 100644 index 0000000..8b6f86c --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Serialization/JsonKeyStorePbkdf2Serializer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b94acc8a8b7163843ba702cfac0fbab3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Serialization/JsonKeyStoreScryptSerializer.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Serialization/JsonKeyStoreScryptSerializer.cs new file mode 100644 index 0000000..48c2dc2 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Serialization/JsonKeyStoreScryptSerializer.cs @@ -0,0 +1,18 @@ +using Newtonsoft.Json; +using Solana.Unity.KeyStore.Model; + +namespace Solana.Unity.KeyStore.Serialization +{ + public static class JsonKeyStoreScryptSerializer + { + public static string SerializeScrypt(KeyStore scryptKeyStore) + { + return JsonConvert.SerializeObject(scryptKeyStore); + } + + public static KeyStore DeserializeScrypt(string json) + { + return JsonConvert.DeserializeObject>(json); + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Serialization/JsonKeyStoreScryptSerializer.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Serialization/JsonKeyStoreScryptSerializer.cs.meta new file mode 100644 index 0000000..52ee040 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Serialization/JsonKeyStoreScryptSerializer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a0f599033e9a0cf4f90cbddcc081e069 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Services.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Services.meta new file mode 100644 index 0000000..3b73439 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Services.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 35f4e9e1184c46f4190c0164c73d9eed +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Services/ISecretKeyStore.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Services/ISecretKeyStore.cs new file mode 100644 index 0000000..db5e649 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Services/ISecretKeyStore.cs @@ -0,0 +1,52 @@ +using Solana.Unity.KeyStore.Model; + +namespace Solana.Unity.KeyStore.Services +{ + public interface ISecretKeyStoreService where T : KdfParams + { + /// + /// Decrypt the keystore. + /// + /// + /// + /// + byte[] DecryptKeyStore(string password, KeyStore keyStore); + + /// + /// Deserialize keystore from json. + /// + /// + /// + KeyStore DeserializeKeyStoreFromJson(string json); + + /// + /// Encrypt and generate the keystore. + /// + /// + /// + /// + /// + KeyStore EncryptAndGenerateKeyStore(string password, byte[] privateKey, string address); + + /// + /// Encrypt and generate the keystore as json. + /// + /// + /// + /// + /// + string EncryptAndGenerateKeyStoreAsJson(string password, byte[] privateKey, string address); + + /// + /// Get keystore cipher type. + /// + /// + string GetCipherType(); + + /// + /// Get keystore key derivation function. + /// + /// + string GetKdfType(); + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Services/ISecretKeyStore.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Services/ISecretKeyStore.cs.meta new file mode 100644 index 0000000..675ea8a --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Services/ISecretKeyStore.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 48def944f11af7949ac89ffd2729b390 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Services/KeyStorePbkdf2Service.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Services/KeyStorePbkdf2Service.cs new file mode 100644 index 0000000..c885d97 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Services/KeyStorePbkdf2Service.cs @@ -0,0 +1,63 @@ +using Solana.Unity.KeyStore.Crypto; +using Solana.Unity.KeyStore.Model; +using Solana.Unity.KeyStore.Serialization; +using System; + +namespace Solana.Unity.KeyStore.Services +{ + public class KeyStorePbkdf2Service : KeyStoreServiceBase + { + public const string KdfType = "pbkdf2"; + + public KeyStorePbkdf2Service() + { + } + + public KeyStorePbkdf2Service(IRandomBytesGenerator randomBytesGenerator, KeyStoreCrypto keyStoreCrypto) : base( + randomBytesGenerator, keyStoreCrypto) + { + } + + public KeyStorePbkdf2Service(IRandomBytesGenerator randomBytesGenerator) : base(randomBytesGenerator) + { + } + + protected override byte[] GenerateDerivedKey(string password, byte[] salt, Pbkdf2Params kdfParams) + { + return KeyStoreCrypto.GeneratePbkdf2Sha256DerivedKey(password, salt, kdfParams.Count, kdfParams.Dklen); + } + + protected override Pbkdf2Params GetDefaultParams() + { + return new() { Dklen = 32, Count = 262144, Prf = "hmac-sha256" }; + } + + public override KeyStore DeserializeKeyStoreFromJson(string json) + { + return JsonKeyStorePbkdf2Serializer.DeserializePbkdf2(json); + } + + public override string SerializeKeyStoreToJson(KeyStore keyStore) + { + return JsonKeyStorePbkdf2Serializer.SerialisePbkdf2(keyStore); + } + + public override byte[] DecryptKeyStore(string password, KeyStore keyStore) + { + if (password == null) throw new ArgumentNullException(nameof(password)); + if (keyStore == null) throw new ArgumentNullException(nameof(keyStore)); + + return KeyStoreCrypto.DecryptPbkdf2Sha256(password, keyStore.Crypto.Mac.HexToByteArray(), + keyStore.Crypto.CipherParams.Iv.HexToByteArray(), + keyStore.Crypto.CipherText.HexToByteArray(), + keyStore.Crypto.Kdfparams.Count, + keyStore.Crypto.Kdfparams.Salt.HexToByteArray(), + keyStore.Crypto.Kdfparams.Dklen); + } + + public override string GetKdfType() + { + return KdfType; + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Services/KeyStorePbkdf2Service.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Services/KeyStorePbkdf2Service.cs.meta new file mode 100644 index 0000000..e82821b --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Services/KeyStorePbkdf2Service.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e25ffd129a5c05c469ce7990ba12792a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Services/KeyStoreScryptService.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Services/KeyStoreScryptService.cs new file mode 100644 index 0000000..7d5e4ed --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Services/KeyStoreScryptService.cs @@ -0,0 +1,68 @@ +using Solana.Unity.KeyStore.Crypto; +using Solana.Unity.KeyStore.Model; +using Solana.Unity.KeyStore.Serialization; +using System; + +namespace Solana.Unity.KeyStore.Services +{ + public class KeyStoreScryptService : KeyStoreServiceBase + { + public const string KdfType = "scrypt"; + + public KeyStoreScryptService() + { + } + + public KeyStoreScryptService(IRandomBytesGenerator randomBytesGenerator, KeyStoreCrypto keyStoreCrypto) : base( + randomBytesGenerator, keyStoreCrypto) + { + } + + public KeyStoreScryptService(IRandomBytesGenerator randomBytesGenerator) : base(randomBytesGenerator) + { + } + + protected override byte[] GenerateDerivedKey(string password, byte[] salt, ScryptParams kdfParams) + { + return KeyStoreCrypto.GenerateDerivedScryptKey(KeyStoreCrypto.GetPasswordAsBytes(password), salt, + kdfParams.N, kdfParams.R, + kdfParams.P, kdfParams.Dklen); + } + + protected override ScryptParams GetDefaultParams() + { + return new() { Dklen = 32, N = 262144, R = 1, P = 8 }; + } + + public override KeyStore DeserializeKeyStoreFromJson(string json) + { + var keystore = JsonKeyStoreScryptSerializer.DeserializeScrypt(json); + return keystore; + } + + public override string SerializeKeyStoreToJson(KeyStore keyStore) + { + return JsonKeyStoreScryptSerializer.SerializeScrypt(keyStore); + } + + public override byte[] DecryptKeyStore(string password, KeyStore keyStore) + { + if (password == null) throw new ArgumentNullException(nameof(password)); + if (keyStore == null) throw new ArgumentNullException(nameof(keyStore)); + + return KeyStoreCrypto.DecryptScrypt(password, keyStore.Crypto.Mac.HexToByteArray(), + keyStore.Crypto.CipherParams.Iv.HexToByteArray(), + keyStore.Crypto.CipherText.HexToByteArray(), + keyStore.Crypto.Kdfparams.N, + keyStore.Crypto.Kdfparams.P, + keyStore.Crypto.Kdfparams.R, + keyStore.Crypto.Kdfparams.Salt.HexToByteArray(), + keyStore.Crypto.Kdfparams.Dklen); + } + + public override string GetKdfType() + { + return KdfType; + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Services/KeyStoreScryptService.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Services/KeyStoreScryptService.cs.meta new file mode 100644 index 0000000..c762606 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Services/KeyStoreScryptService.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 31d45d156e3fe7441aee2f7668a05a7d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Services/KeyStoreServiceBase.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Services/KeyStoreServiceBase.cs new file mode 100644 index 0000000..89d10ab --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Services/KeyStoreServiceBase.cs @@ -0,0 +1,107 @@ +using Solana.Unity.KeyStore.Crypto; +using Solana.Unity.KeyStore.Model; +using System; + +namespace Solana.Unity.KeyStore.Services +{ + public abstract class KeyStoreServiceBase : ISecretKeyStoreService where T : KdfParams + { + public const int CurrentVersion = 3; + protected readonly KeyStoreCrypto KeyStoreCrypto; + protected readonly IRandomBytesGenerator RandomBytesGenerator; + + protected KeyStoreServiceBase() : this(new RandomBytesGenerator(), new KeyStoreCrypto()) + { + } + + protected KeyStoreServiceBase(IRandomBytesGenerator randomBytesGenerator, KeyStoreCrypto keyStoreCrypto) + { + RandomBytesGenerator = randomBytesGenerator; + KeyStoreCrypto = keyStoreCrypto; + } + + + protected KeyStoreServiceBase(IRandomBytesGenerator randomBytesGenerator) + { + RandomBytesGenerator = randomBytesGenerator; + KeyStoreCrypto = new KeyStoreCrypto(); + } + + public KeyStore EncryptAndGenerateKeyStore(string password, byte[] privateKey, string address) + { + var kdfParams = GetDefaultParams(); + return EncryptAndGenerateKeyStore(password, privateKey, address, kdfParams); + } + + public string EncryptAndGenerateKeyStoreAsJson(string password, byte[] privateKey, string address) + { + var keyStore = EncryptAndGenerateKeyStore(password, privateKey, address); + return SerializeKeyStoreToJson(keyStore); + } + + public abstract KeyStore DeserializeKeyStoreFromJson(string json); + public abstract string SerializeKeyStoreToJson(KeyStore keyStore); + + public abstract byte[] DecryptKeyStore(string password, KeyStore keyStore); + + public abstract string GetKdfType(); + + public virtual string GetCipherType() + { + return "aes-128-ctr"; + } + + public KeyStore EncryptAndGenerateKeyStore(string password, byte[] privateKey, string address, T kdfParams) + { + if (password == null) throw new ArgumentNullException(nameof(password)); + if (privateKey == null) throw new ArgumentNullException(nameof(privateKey)); + if (address == null) throw new ArgumentNullException(nameof(address)); + if (kdfParams == null) throw new ArgumentNullException(nameof(kdfParams)); + + var salt = RandomBytesGenerator.GenerateRandomSalt(); + + var derivedKey = GenerateDerivedKey(password, salt, kdfParams); + + var cipherKey = KeyStoreCrypto.GenerateCipherKey(derivedKey); + + var iv = RandomBytesGenerator.GenerateRandomInitializationVector(); + + var cipherText = GenerateCipher(privateKey, iv, cipherKey); + + var mac = KeyStoreCrypto.GenerateMac(derivedKey, cipherText); + + var cryptoInfo = new CryptoInfo(GetCipherType(), cipherText, iv, mac, salt, kdfParams, GetKdfType()); + + var keyStore = new KeyStore + { + Version = CurrentVersion, + Address = address, + Id = Guid.NewGuid().ToString(), + Crypto = cryptoInfo + }; + + return keyStore; + } + + public string EncryptAndGenerateKeyStoreAsJson(string password, byte[] privateKey, string address, T kdfParams) + { + var keyStore = EncryptAndGenerateKeyStore(password, privateKey, address, kdfParams); + return SerializeKeyStoreToJson(keyStore); + } + + public byte[] DecryptKeyStoreFromJson(string password, string json) + { + var keyStore = DeserializeKeyStoreFromJson(json); + return DecryptKeyStore(password, keyStore); + } + + protected virtual byte[] GenerateCipher(byte[] privateKey, byte[] iv, byte[] cipherKey) + { + return KeyStoreCrypto.GenerateAesCtrCipher(iv, cipherKey, privateKey); + } + + protected abstract byte[] GenerateDerivedKey(string password, byte[] salt, T kdfParams); + + protected abstract T GetDefaultParams(); + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Services/KeyStoreServiceBase.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Services/KeyStoreServiceBase.cs.meta new file mode 100644 index 0000000..4663bb7 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Services/KeyStoreServiceBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6449e4d932dfb084ebde946976f63c34 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Solana.Unity.KeyStore.csproj.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Solana.Unity.KeyStore.csproj.meta new file mode 100644 index 0000000..cf041a4 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Solana.Unity.KeyStore.csproj.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 291b2a6f9e915cc41af351af42e66252 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/SolanaKeyStore.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/SolanaKeyStore.cs new file mode 100644 index 0000000..b4d1339 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/SolanaKeyStore.cs @@ -0,0 +1,54 @@ +using Solana.Unity.Wallet; +using System.IO; +using System.Text; + +namespace Solana.Unity.KeyStore +{ + /// + /// Implements a keystore compatible with the solana-keygen made in rust. + /// + public class SolanaKeyStoreService + { + /// + /// Restores a keypair from a keystore compatible with the solana-keygen made in rust. + /// + /// The string with the private key bytes. + /// The passphrase used while originally generating the keys. + public Unity.Wallet.Wallet RestoreKeystore(string privateKey, string passphrase = "") + { + return InitializeWallet(privateKey.FromStringByteArray(), passphrase); + } + + /// + /// Restores a keypair from a keystore compatible with the solana-keygen made in rust. + /// + /// The path to the keystore. + /// The passphrase used while originally generating the keys. + public Unity.Wallet.Wallet RestoreKeystoreFromFile(string path, string passphrase = "") + { + var inputBytes = File.ReadAllText(path).FromStringByteArray(); + return InitializeWallet(inputBytes, passphrase); + } + + /// + /// Saves a keypair to a keystore compatible with the solana-keygen made in rust. + /// + /// The path to the keystore + /// The wallet to save to the keystore. + public void SaveKeystore(string path, Unity.Wallet.Wallet wallet) + { + File.WriteAllBytes(path, Encoding.ASCII.GetBytes(wallet.Account.PrivateKey.KeyBytes.ToStringByteArray())); + } + + /// + /// Initialize the wallet. + /// + /// The seed. + /// The passphrase. + /// The wallet. + private Unity.Wallet.Wallet InitializeWallet(byte[] seed, string passphrase = "") + { + return new Unity.Wallet.Wallet(seed, passphrase, SeedMode.Bip39); + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/SolanaKeyStore.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/SolanaKeyStore.cs.meta new file mode 100644 index 0000000..9460d67 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/SolanaKeyStore.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b77860268da6fb345b39e0c39b8374d0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Utils.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Utils.cs new file mode 100644 index 0000000..e71ae4e --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Utils.cs @@ -0,0 +1,131 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Solana.Unity.KeyStore +{ + public static class Utils + { + + /// + /// Helper function to convert a character to byte. + /// + /// The character to convert + /// The value that represents the character's position. + /// Number of bits to shift. + /// The corresponding byte. + /// Throws format exception when the character is not a valid alphanumeric character. + private static byte FromCharacterToByte(char character, int index, int shift = 0) + { + var value = (byte)character; + if (0x40 < value && 0x47 > value || 0x60 < value && 0x67 > value) + { + if (0x40 == (0x40 & value)) + if (0x20 == (0x20 & value)) + value = (byte)((value + 0xA - 0x61) << shift); + else + value = (byte)((value + 0xA - 0x41) << shift); + } + else if (0x29 < value && 0x40 > value) + { + value = (byte)((value - 0x30) << shift); + } + else + { + throw new FormatException( + $"Character '{character}' at index '{index}' is not valid alphanumeric character."); + } + + return value; + } + + /// + /// Performs the hex to byte array conversion. + /// + /// The string to convert to byte array. + /// The corresponding byte array. + private static byte[] HexToByteArrayInternal(string value) + { + byte[] bytes = null; + if (string.IsNullOrEmpty(value)) + { + bytes = new byte[] { }; + } + else + { + var stringLength = value.Length; + var writeIndex = 0; + bytes = new byte[stringLength / 2]; // Initialize our byte array to hold the converted string. + + for (var readIndex = 0; readIndex < value.Length; readIndex += 2) + { + var upper = FromCharacterToByte(value[readIndex], readIndex, 4); + var lower = FromCharacterToByte(value[readIndex + 1], readIndex + 1); + + bytes[writeIndex++] = (byte)(upper | lower); + } + } + + return bytes; + } + + /// + /// Convert the passed string to a byte array. + /// + /// The string to convert + /// The equivalent byte array. + /// Throws format exception when the string could not be converted. + public static byte[] HexToByteArray(this string value) + { + try + { + return HexToByteArrayInternal(value); + } + catch (FormatException ex) + { + throw new FormatException($"String '{value}' could not be converted to byte array (not hex?).", ex); + } + } + + /// + /// Convert a byte array into a hexadecimal string. + /// + /// The byte array to convert. + /// The string as hex. + public static string ToHex(this byte[] value) + { + return string.Concat(value.Select(b => b.ToString("x2")).ToArray()); + } + + /// + /// Formats a byte array into a string in order to be compatible with the original solana-keygen made in rust. + /// + /// The byte array to be formatted. + /// A formatted string. + public static string ToStringByteArray(this IEnumerable bytes) => "[" + string.Join(",", bytes) + "]"; + + /// + /// Formats a string into a byte array in order to be compatible with the original solana-keygen made in rust. + /// + /// The string to be formatted. + /// A formatted byte array. + public static byte[] FromStringByteArray(this string data) + { + var bytes = new byte[64]; + var index = 0; + var i = 0; + var newS = data.AsSpan(1, data.Length - 1); + + while ((i = newS.IndexOf(',')) != -1) + { + bytes[index++] = byte.Parse(newS[..i].ToString()); + newS = newS[(i + 1)..]; + } + + bytes[index] = byte.Parse(newS[..^1].ToString()); + if (index != 63) + throw new ArgumentException("invalid string for conversion", nameof(data)); + return bytes; + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Utils.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Utils.cs.meta new file mode 100644 index 0000000..61fd7a5 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.KeyStore/Utils.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 882f8f9f153bd464a816ddf28e569c27 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs.meta new file mode 100644 index 0000000..8bf5a83 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ee16215b624fa3b4886e9400f0530c8a +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract.meta new file mode 100644 index 0000000..a90a861 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 19d9529c694a6214a8cbb684bdb2e236 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/BaseClient.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/BaseClient.cs new file mode 100644 index 0000000..60614d0 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/BaseClient.cs @@ -0,0 +1,170 @@ +using Solana.Unity.Programs; +using Solana.Unity.Programs.Models; +using Solana.Unity.Rpc; +using Solana.Unity.Rpc.Builders; +using Solana.Unity.Rpc.Core.Http; +using Solana.Unity.Rpc.Core.Sockets; +using Solana.Unity.Rpc.Messages; +using Solana.Unity.Rpc.Models; +using Solana.Unity.Rpc.Types; +using Solana.Unity.Wallet; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Solana.Unity.Programs.Abstract +{ + /// + /// Implements the base client + /// + public abstract class BaseClient + { + /// + /// The program address. + /// + public PublicKey ProgramIdKey { get; } + + /// + /// The RPC client. + /// + public IRpcClient RpcClient { get; init; } + + /// + /// The streaming RPC client. + /// + public IStreamingRpcClient StreamingRpcClient { get; init; } + + /// + /// Initialize the base client with the given RPC clients. + /// + /// The RPC client instance. + /// The streaming RPC client instance. + /// The program ID. + protected BaseClient(IRpcClient rpcClient, IStreamingRpcClient streamingRpcClient, PublicKey programId) + { + RpcClient = rpcClient; + StreamingRpcClient = streamingRpcClient; + ProgramIdKey = programId; + } + + /// + /// Deserializes the given byte array into the specified type. + /// + /// The data to deserialize into the specified type. + /// The type. + /// An instance of the specified type or null in case it was unable to deserialize. + private static T DeserializeAccount(byte[] data) where T : class + { + System.Reflection.MethodInfo m = typeof(T).GetMethod("Deserialize", + System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static, + null, new[] { typeof(byte[]) }, null); + + if (m.IsGenericMethod) + { + m = m.MakeGenericMethod(typeof(T).GetGenericArguments()); + } + + if (m == null) + return null; + return (T)m.Invoke(null, new object[] { data }); + } + + /// + /// Gets the account info for the given account address and attempts to deserialize the account data into the specified type. + /// + /// The program account address. + /// The commitment parameter for the RPC request. + /// The filters to apply. + /// The expected account data size. + /// The specified type. + /// A containing the RPC response and the deserialized account if successful. + protected async Task>> GetProgramAccounts(string programAddress, List filters, + int? dataSize = null, Commitment commitment = Commitment.Finalized) where T : class + { + RequestResult> res = + await RpcClient.GetProgramAccountsAsync(programAddress, commitment, dataSize, filters); + + if (!res.WasSuccessful || !(res.Result?.Count > 0)) + return new ProgramAccountsResultWrapper>(res); + + List resultingAccounts = new(res.Result.Count); + resultingAccounts.AddRange(res.Result.Select(result => + DeserializeAccount(Convert.FromBase64String(result.Account.Data[0])))); + + return new ProgramAccountsResultWrapper>(res, resultingAccounts); + } + + /// + /// Gets the account info for the given account address and attempts to deserialize the account data into the specified type. + /// + /// The list of account addresses to fetch. + /// The commitment parameter for the RPC request. + /// The specified type. + /// A containing the RPC response and the deserialized account if successful. + protected async Task>> GetMultipleAccounts(List accountAddresses, + Commitment commitment = Commitment.Finalized) where T : class + { + RequestResult>> res = + await RpcClient.GetMultipleAccountsAsync(accountAddresses, commitment); + + if (!res.WasSuccessful || !(res.Result?.Value?.Count > 0)) + return new MultipleAccountsResultWrapper>(res); + + List resultingAccounts = new(res.Result.Value.Count); + resultingAccounts.AddRange(res.Result.Value.Select(result => + DeserializeAccount(Convert.FromBase64String(result.Data[0])))); + + return new MultipleAccountsResultWrapper>(res, resultingAccounts); + } + + /// + /// Gets the account info for the given account address and attempts to deserialize the account data into the specified type. + /// + /// The account address. + /// The commitment parameter for the RPC request. + /// The specified type. + /// A containing the RPC response and the deserialized account if successful. + protected async Task> GetAccount(string accountAddress, + Commitment commitment = Commitment.Finalized) where T : class + { + RequestResult> res = + await RpcClient.GetAccountInfoAsync(accountAddress, commitment); + + if (res.WasSuccessful && res.Result?.Value?.Data?.Count > 0) + { + return new AccountResultWrapper(res, + DeserializeAccount(Convert.FromBase64String(res.Result.Value.Data[0]))); + } + + return new AccountResultWrapper(res); + } + + /// + /// Subscribes to notifications on changes to the given account and deserializes the account data into the specified type. + /// + /// The account address. + /// The commitment parameter for the RPC request. + /// An action that is called when a notification is received + /// The specified type. + /// The subscription state. + protected async Task SubscribeAccount(string accountAddress, + Action, T> callback, + Commitment commitment = Commitment.Finalized) where T : class + { + SubscriptionState res = await StreamingRpcClient.SubscribeAccountInfoAsync(accountAddress, + (s, e) => + { + T parsingResult = null; + + if (e.Value?.Data?.Count > 0) + parsingResult = DeserializeAccount(Convert.FromBase64String(e.Value.Data[0])); + + callback(s, e, parsingResult); + }, commitment); + + return res; + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/BaseClient.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/BaseClient.cs.meta new file mode 100644 index 0000000..8489cb2 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/BaseClient.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0310dc5db515761468d0e4fa21322ed0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/BaseProgram.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/BaseProgram.cs new file mode 100644 index 0000000..42e6d58 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/BaseProgram.cs @@ -0,0 +1,39 @@ +using Solana.Unity.Wallet; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Solana.Unity.Programs.Abstract +{ + /// + /// A class to abstract some of the core program commonality + /// + public abstract class BaseProgram : Program + { + private PublicKey _programIdKey; + private string _programName; + + /// + /// The public key of the program. + /// + public virtual PublicKey ProgramIdKey => _programIdKey; + + /// + /// The program's name. + /// + public virtual string ProgramName => _programName; + + /// + /// Creates an instance of the base program class with specified id and name + /// + /// The program key + /// The program name + protected BaseProgram(PublicKey programIdKey, string programName) + { + _programIdKey = programIdKey; + _programName = programName; + } + } +} diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/BaseProgram.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/BaseProgram.cs.meta new file mode 100644 index 0000000..c509bc3 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/BaseProgram.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0088b471329e162428abc698b19cca4d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/ByteFlag.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/ByteFlag.cs new file mode 100644 index 0000000..a24ecd6 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/ByteFlag.cs @@ -0,0 +1,54 @@ +namespace Solana.Unity.Programs.Abstract +{ + /// + /// Represents a flag using a byte for masking. + /// + public class ByteFlag : Flag + { + /// + /// Check if the 1st bit is set. + /// + public bool Bit0 => IsKthBitSet(Value, 1); + + /// + /// Check if the 2nd bit is set. + /// + public bool Bit1 => IsKthBitSet(Value, 2); + + /// + /// Check if the 3rd bit is set. + /// + public bool Bit2 => IsKthBitSet(Value, 3); + + /// + /// Check if the 4th bit is set. + /// + public bool Bit3 => IsKthBitSet(Value, 4); + + /// + /// Check if the 5th bit is set. + /// + public bool Bit4 => IsKthBitSet(Value, 5); + + /// + /// Check if the 6th bit is set. + /// + public bool Bit5 => IsKthBitSet(Value, 6); + + /// + /// Check if the 7th bit is set. + /// + public bool Bit6 => IsKthBitSet(Value, 7); + + /// + /// Check if the 8th bit is set. + /// + public bool Bit7 => IsKthBitSet(Value, 8); + + /// + /// Initialize the flags with the given byte. + /// + /// The byte to use. + public ByteFlag(byte mask) : base(mask) { } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/ByteFlag.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/ByteFlag.cs.meta new file mode 100644 index 0000000..59cafa1 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/ByteFlag.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1580ec96333f6dd45ac92a595f0a7b34 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/Flag.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/Flag.cs new file mode 100644 index 0000000..30d59fa --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/Flag.cs @@ -0,0 +1,30 @@ +namespace Solana.Unity.Programs.Abstract +{ + /// + /// Represents bitmask flags for various types of accounts within Solana Programs. + /// + public abstract class Flag + { + /// + /// The mask for the account flags. + /// + public T Value { get; } + + /// + /// Initialize the flags with the given mask. + /// + /// The mask to use. + protected Flag(T mask) + { + Value = mask; + } + + /// + /// Checks whether the Kth bit for a given number N is set. + /// + /// The number to check against. + /// The bit to check. + /// true if it is, otherwise false. + protected static bool IsKthBitSet(ulong n, int k) => (n & (1UL << (k - 1))) > 0; + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/Flag.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/Flag.cs.meta new file mode 100644 index 0000000..e778867 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/Flag.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: da5e508eee256aa4caa4f887332795f9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/IntFlag.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/IntFlag.cs new file mode 100644 index 0000000..063b50e --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/IntFlag.cs @@ -0,0 +1,176 @@ +namespace Solana.Unity.Programs.Abstract +{ + + /// + /// Represents a flag using a long for masking. + /// + public class IntFlag : Flag + { + + /// + /// Check if the 1st bit is set. + /// + public bool Bit0 => IsKthBitSet(Value, 1); + + /// + /// Check if the 2nd bit is set. + /// + public bool Bit1 => IsKthBitSet(Value, 2); + + /// + /// Check if the 3rd bit is set. + /// + public bool Bit2 => IsKthBitSet(Value, 3); + + /// + /// Check if the 4th bit is set. + /// + public bool Bit3 => IsKthBitSet(Value, 4); + + /// + /// Check if the 5th bit is set. + /// + public bool Bit4 => IsKthBitSet(Value, 5); + + /// + /// Check if the 6th bit is set. + /// + public bool Bit5 => IsKthBitSet(Value, 6); + + /// + /// Check if the 7th bit is set. + /// + public bool Bit6 => IsKthBitSet(Value, 7); + + /// + /// Check if the 8th bit is set. + /// + public bool Bit7 => IsKthBitSet(Value, 8); + + /// + /// Check if the 9th bit is set. + /// + public bool Bit8 => IsKthBitSet(Value, 9); + + /// + /// Check if the 10th bit is set. + /// + public bool Bit9 => IsKthBitSet(Value, 10); + + /// + /// Check if the 11th bit is set. + /// + public bool Bit10 => IsKthBitSet(Value, 11); + + /// + /// Check if the 12th bit is set. + /// + public bool Bit11 => IsKthBitSet(Value, 12); + + /// + /// Check if the 13th bit is set. + /// + public bool Bit12 => IsKthBitSet(Value, 13); + + /// + /// Check if the 14th bit is set. + /// + public bool Bit13 => IsKthBitSet(Value, 14); + + /// + /// Check if the 15th bit is set. + /// + public bool Bit14 => IsKthBitSet(Value, 15); + + /// + /// Check if the 16th bit is set. + /// + public bool Bit15 => IsKthBitSet(Value, 16); + + /// + /// Check if the 17th bit is set. + /// + public bool Bit16 => IsKthBitSet(Value, 17); + + /// + /// Check if the 18th bit is set. + /// + public bool Bit17 => IsKthBitSet(Value, 18); + + /// + /// Check if the 19th bit is set. + /// + public bool Bit18 => IsKthBitSet(Value, 19); + + /// + /// Check if the 20th bit is set. + /// + public bool Bit19 => IsKthBitSet(Value, 20); + + /// + /// Check if the 21st bit is set. + /// + public bool Bit20 => IsKthBitSet(Value, 21); + + /// + /// Check if the 22nd bit is set. + /// + public bool Bit21 => IsKthBitSet(Value, 22); + + /// + /// Check if the 23rd bit is set. + /// + public bool Bit22 => IsKthBitSet(Value, 23); + + /// + /// Check if the 24th bit is set. + /// + public bool Bit23 => IsKthBitSet(Value, 24); + + /// + /// Check if the 25th bit is set. + /// + public bool Bit24 => IsKthBitSet(Value, 25); + + /// + /// Check if the 26th bit is set. + /// + public bool Bit25 => IsKthBitSet(Value, 26); + + /// + /// Check if the 27th bit is set. + /// + public bool Bit26 => IsKthBitSet(Value, 27); + + /// + /// Check if the 28th bit is set. + /// + public bool Bit27 => IsKthBitSet(Value, 28); + + /// + /// Check if the 29th bit is set. + /// + public bool Bit28 => IsKthBitSet(Value, 29); + + /// + /// Check if the 30th bit is set. + /// + public bool Bit29 => IsKthBitSet(Value, 30); + + /// + /// Check if the 31st bit is set. + /// + public bool Bit30 => IsKthBitSet(Value, 31); + + /// + /// Check if the 32nd bit is set. + /// + public bool Bit31 => IsKthBitSet(Value, 32); + + /// + /// Initialize the flags with the given uint. + /// + /// The uint to use. + public IntFlag(uint mask) : base(mask) { } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/IntFlag.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/IntFlag.cs.meta new file mode 100644 index 0000000..f032178 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/IntFlag.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0ede0f95287fd7f4d9c65bc9e1a597b2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/LongFlag.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/LongFlag.cs new file mode 100644 index 0000000..9fc889c --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/LongFlag.cs @@ -0,0 +1,335 @@ +namespace Solana.Unity.Programs.Abstract +{ + /// + /// Represents a flag using a long for masking. + /// + public class LongFlag : Flag + { + + /// + /// Check if the 1st bit is set. + /// + public bool Bit0 => IsKthBitSet(Value, 1); + + /// + /// Check if the 2nd bit is set. + /// + public bool Bit1 => IsKthBitSet(Value, 2); + + /// + /// Check if the 3rd bit is set. + /// + public bool Bit2 => IsKthBitSet(Value, 3); + + /// + /// Check if the 4th bit is set. + /// + public bool Bit3 => IsKthBitSet(Value, 4); + + /// + /// Check if the 5th bit is set. + /// + public bool Bit4 => IsKthBitSet(Value, 5); + + /// + /// Check if the 6th bit is set. + /// + public bool Bit5 => IsKthBitSet(Value, 6); + + /// + /// Check if the 7th bit is set. + /// + public bool Bit6 => IsKthBitSet(Value, 7); + + /// + /// Check if the 8th bit is set. + /// + public bool Bit7 => IsKthBitSet(Value, 8); + + /// + /// Check if the 9th bit is set. + /// + public bool Bit8 => IsKthBitSet(Value, 9); + + /// + /// Check if the 10th bit is set. + /// + public bool Bit9 => IsKthBitSet(Value, 10); + + /// + /// Check if the 11th bit is set. + /// + public bool Bit10 => IsKthBitSet(Value, 11); + + /// + /// Check if the 12th bit is set. + /// + public bool Bit11 => IsKthBitSet(Value, 12); + + /// + /// Check if the 13th bit is set. + /// + public bool Bit12 => IsKthBitSet(Value, 13); + + /// + /// Check if the 14th bit is set. + /// + public bool Bit13 => IsKthBitSet(Value, 14); + + /// + /// Check if the 15th bit is set. + /// + public bool Bit14 => IsKthBitSet(Value, 15); + + /// + /// Check if the 16th bit is set. + /// + public bool Bit15 => IsKthBitSet(Value, 16); + + /// + /// Check if the 17th bit is set. + /// + public bool Bit16 => IsKthBitSet(Value, 17); + + /// + /// Check if the 18th bit is set. + /// + public bool Bit17 => IsKthBitSet(Value, 18); + + /// + /// Check if the 19th bit is set. + /// + public bool Bit18 => IsKthBitSet(Value, 19); + + /// + /// Check if the 20th bit is set. + /// + public bool Bit19 => IsKthBitSet(Value, 20); + + /// + /// Check if the 21st bit is set. + /// + public bool Bit20 => IsKthBitSet(Value, 21); + + /// + /// Check if the 22nd bit is set. + /// + public bool Bit21 => IsKthBitSet(Value, 22); + + /// + /// Check if the 23rd bit is set. + /// + public bool Bit22 => IsKthBitSet(Value, 23); + + /// + /// Check if the 24th bit is set. + /// + public bool Bit23 => IsKthBitSet(Value, 24); + + /// + /// Check if the 25th bit is set. + /// + public bool Bit24 => IsKthBitSet(Value, 25); + + /// + /// Check if the 26th bit is set. + /// + public bool Bit25 => IsKthBitSet(Value, 26); + + /// + /// Check if the 27th bit is set. + /// + public bool Bit26 => IsKthBitSet(Value, 27); + + /// + /// Check if the 28th bit is set. + /// + public bool Bit27 => IsKthBitSet(Value, 28); + + /// + /// Check if the 29th bit is set. + /// + public bool Bit28 => IsKthBitSet(Value, 29); + + /// + /// Check if the 30th bit is set. + /// + public bool Bit29 => IsKthBitSet(Value, 30); + + /// + /// Check if the 31st bit is set. + /// + public bool Bit30 => IsKthBitSet(Value, 31); + + /// + /// Check if the 32nd bit is set. + /// + public bool Bit31 => IsKthBitSet(Value, 32); + + /// + /// Check if the 33rd bit is set. + /// + public bool Bit32 => IsKthBitSet(Value, 33); + + /// + /// Check if the 34th bit is set. + /// + public bool Bit33 => IsKthBitSet(Value, 34); + + /// + /// Check if the 35th bit is set. + /// + public bool Bit34 => IsKthBitSet(Value, 35); + + /// + /// Check if the 36th bit is set. + /// + public bool Bit35 => IsKthBitSet(Value, 36); + + /// + /// Check if the 37th bit is set. + /// + public bool Bit36 => IsKthBitSet(Value, 37); + + /// + /// Check if the 38th bit is set. + /// + public bool Bit37 => IsKthBitSet(Value, 38); + + /// + /// Check if the 39th bit is set. + /// + public bool Bit38 => IsKthBitSet(Value, 39); + + /// + /// Check if the 40th bit is set. + /// + public bool Bit39 => IsKthBitSet(Value, 40); + + /// + /// Check if the 41st bit is set. + /// + public bool Bit40 => IsKthBitSet(Value, 41); + + /// + /// Check if the 42nd bit is set. + /// + public bool Bit41 => IsKthBitSet(Value, 42); + + /// + /// Check if the 43rd bit is set. + /// + public bool Bit42 => IsKthBitSet(Value, 43); + + /// + /// Check if the 44th bit is set. + /// + public bool Bit43 => IsKthBitSet(Value, 44); + + /// + /// Check if the 45th bit is set. + /// + public bool Bit44 => IsKthBitSet(Value, 45); + + /// + /// Check if the 46th bit is set. + /// + public bool Bit45 => IsKthBitSet(Value, 46); + + /// + /// Check if the 47th bit is set. + /// + public bool Bit46 => IsKthBitSet(Value, 47); + + /// + /// Check if the 48th bit is set. + /// + public bool Bit47 => IsKthBitSet(Value, 48); + + /// + /// Check if the 49th bit is set. + /// + public bool Bit48 => IsKthBitSet(Value, 49); + + /// + /// Check if the 50th bit is set. + /// + public bool Bit49 => IsKthBitSet(Value, 50); + + /// + /// Check if the 51st bit is set. + /// + public bool Bit50 => IsKthBitSet(Value, 51); + + /// + /// Check if the 52nd bit is set. + /// + public bool Bit51 => IsKthBitSet(Value, 52); + + /// + /// Check if the 53rd bit is set. + /// + public bool Bit52 => IsKthBitSet(Value, 53); + + /// + /// Check if the 54th bit is set. + /// + public bool Bit53 => IsKthBitSet(Value, 54); + + /// + /// Check if the 55th bit is set. + /// + public bool Bit54 => IsKthBitSet(Value, 55); + + /// + /// Check if the 56th bit is set. + /// + public bool Bit55 => IsKthBitSet(Value, 56); + + /// + /// Check if the57th bit is set. + /// + public bool Bit56 => IsKthBitSet(Value, 57); + + /// + /// Check if the 58th bit is set. + /// + public bool Bit57 => IsKthBitSet(Value, 58); + + /// + /// Check if the 59th bit is set. + /// + public bool Bit58 => IsKthBitSet(Value, 59); + + /// + /// Check if the 60th bit is set. + /// + public bool Bit59 => IsKthBitSet(Value, 60); + + /// + /// Check if the 61st bit is set. + /// + public bool Bit60 => IsKthBitSet(Value, 61); + + /// + /// Check if the 62nd bit is set. + /// + public bool Bit61 => IsKthBitSet(Value, 62); + + /// + /// Check if the 63rd bit is set. + /// + public bool Bit62 => IsKthBitSet(Value, 63); + + /// + /// Check if the 64th bit is set. + /// + public bool Bit63 => IsKthBitSet(Value, 64); + + /// + /// Initialize the flags with the given ulong. + /// + /// The ulong to use. + public LongFlag(ulong mask) : base(mask) { } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/LongFlag.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/LongFlag.cs.meta new file mode 100644 index 0000000..6314c88 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/LongFlag.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 41ab3d3ea828b414a91822497c10333b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/Program.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/Program.cs new file mode 100644 index 0000000..ee1b7dc --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/Program.cs @@ -0,0 +1,24 @@ +using Solana.Unity.Wallet; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Solana.Unity.Programs.Abstract +{ + /// + /// Base Program interface. + /// + public interface Program + { + /// + /// The program's key + /// + PublicKey ProgramIdKey { get; } + /// + /// The name of the program + /// + string ProgramName { get; } + } +} diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/Program.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/Program.cs.meta new file mode 100644 index 0000000..ce00bf9 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/Program.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d9a6e5316dad6a04aa88f540a1efbb74 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/ShortFlag.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/ShortFlag.cs new file mode 100644 index 0000000..326ee7c --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/ShortFlag.cs @@ -0,0 +1,94 @@ +namespace Solana.Unity.Programs.Abstract +{ + /// + /// Represents a flag using a short for masking. + /// + public class ShortFlag : Flag + { + /// + /// Check if the 1st bit is set. + /// + public bool Bit0 => IsKthBitSet(Value, 1); + + /// + /// Check if the 2nd bit is set. + /// + public bool Bit1 => IsKthBitSet(Value, 2); + + /// + /// Check if the 3rd bit is set. + /// + public bool Bit2 => IsKthBitSet(Value, 3); + + /// + /// Check if the 4th bit is set. + /// + public bool Bit3 => IsKthBitSet(Value, 4); + + /// + /// Check if the 5th bit is set. + /// + public bool Bit4 => IsKthBitSet(Value, 5); + + /// + /// Check if the 6th bit is set. + /// + public bool Bit5 => IsKthBitSet(Value, 6); + + /// + /// Check if the 7th bit is set. + /// + public bool Bit6 => IsKthBitSet(Value, 7); + + /// + /// Check if the 8th bit is set. + /// + public bool Bit7 => IsKthBitSet(Value, 8); + + /// + /// Check if the 9th bit is set. + /// + public bool Bit8 => IsKthBitSet(Value, 9); + + /// + /// Check if the 10th bit is set. + /// + public bool Bit9 => IsKthBitSet(Value, 10); + + /// + /// Check if the 11th bit is set. + /// + public bool Bit10 => IsKthBitSet(Value, 11); + + /// + /// Check if the 12th bit is set. + /// + public bool Bit11 => IsKthBitSet(Value, 12); + + /// + /// Check if the 13th bit is set. + /// + public bool Bit12 => IsKthBitSet(Value, 13); + + /// + /// Check if the 14th bit is set. + /// + public bool Bit13 => IsKthBitSet(Value, 14); + + /// + /// Check if the 15th bit is set. + /// + public bool Bit14 => IsKthBitSet(Value, 15); + + /// + /// Check if the 16th bit is set. + /// + public bool Bit15 => IsKthBitSet(Value, 16); + + /// + /// Initialize the flags with the given ushort. + /// + /// The ushort to use. + public ShortFlag(ushort mask) : base(mask) { } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/ShortFlag.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/ShortFlag.cs.meta new file mode 100644 index 0000000..bf3bb6c --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/ShortFlag.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f70f4ac316aeffd4a91b2e546c321438 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/TransactionalBaseClient.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/TransactionalBaseClient.cs new file mode 100644 index 0000000..22b2d1c --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/TransactionalBaseClient.cs @@ -0,0 +1,154 @@ +using Solana.Unity.Rpc; +using Solana.Unity.Rpc.Builders; +using Solana.Unity.Rpc.Core.Http; +using Solana.Unity.Rpc.Models; +using Solana.Unity.Rpc.Types; +using Solana.Unity.Wallet; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Solana.Unity.Programs.Abstract +{ + /// + /// Transactional base client. Extends Base client and adds functionality related to transactions and error retrieval. + /// + /// The error enum type. + /// The enum values need to match the program error codes and be correctly mapped in BuildErrorsDictionary abstract method. + public abstract class TransactionalBaseClient : BaseClient where TEnum : Enum + { + /// + /// Mapping from error codes to error values (code, message and enum). + /// + protected Dictionary> ProgramErrors { get; } + + /// + /// Function that builds a mapping between error codes and error values. + /// This is used to populate the ProgramErrors dictionary that powers the GetProgramError methods. + /// + /// The dictionary with the possible errors. + protected abstract Dictionary> BuildErrorsDictionary(); + + /// + /// + /// + /// + /// + /// The program ID. + protected TransactionalBaseClient(IRpcClient rpcClient, IStreamingRpcClient streamingRpcClient, PublicKey programId) : base(rpcClient, streamingRpcClient, programId) + { + ProgramErrors = BuildErrorsDictionary(); + } + + /// + /// Signs and sends a given TransactionInstruction using signing delegate. + /// + /// The transaction to be sent. + /// The fee payer. + /// The callback used to sign the transaction. + /// This delegate is called once for each PublicKey account that needs write permissions according to the transaction data. + /// The commitment parameter for the RPC request. + /// + protected async Task> SignAndSendTransaction(TransactionInstruction instruction, PublicKey feePayer, + Func signingCallback, Commitment commitment = Commitment.Finalized) + { + TransactionBuilder tb = new TransactionBuilder(); + tb.AddInstruction(instruction); + + var recentHash = await RpcClient.GetRecentBlockHashAsync(); + + tb.SetRecentBlockHash(recentHash.Result.Value.Blockhash); + tb.SetFeePayer(feePayer); + + var wireFmt = tb.CompileMessage(); + + var msg = Message.Deserialize(wireFmt); + + for (int i = 0; i < msg.Header.RequiredSignatures; i++) + { + tb.AddSignature(signingCallback(wireFmt, msg.AccountKeys[i])); + } + + return await RpcClient.SendTransactionAsync(tb.Serialize(), commitment: commitment); + } + + /// + /// Try to retrieve a custom program error from a transaction or simulation result. + /// + /// The transaction error or simulation result. + /// The possible program error, if it was caused by this program. + public ProgramError GetProgramError(SimulationLogs logs) + { + if (logs is { Error: { InstructionError: { Type: InstructionErrorType.Custom } } }) + { + var id = logs.Error.InstructionError.CustomError.Value; + + if (ProgramIdKey != null && logs.Logs?.Length > 2) + { + var progReturn = logs.Logs[logs.Logs.Length - 1]; + + //check if error came from this program, in case its a multiple prog tx + if (!progReturn.StartsWith("Program " + ProgramIdKey.Key)) return null; + } + + ProgramErrors.TryGetValue(id, out var error); + return error; + } + return null; + } + + /// + /// Try to retrieve a custom program error from a transaction or simulation result. + /// + /// The transaction error or simulation result. + /// The possible program error, if it was caused by this program. + public ProgramError GetProgramError(TransactionError error) + { + if (error is { InstructionError: { Type: InstructionErrorType.Custom } }) + { + var id = error.InstructionError.CustomError.Value; + + ProgramErrors.TryGetValue(id, out var err); + return err; + } + return null; + } + + } + + /// + /// Represents a program error and the respective message. + /// + /// The underlying enum type. Enum values need to match program error codes. + public class ProgramError where T : Enum + { + /// + /// The error kinda according to the enum. + /// + public T ErrorKind { get; private set; } + + /// + /// The error message. + /// + public string Message { get; private set; } + + /// + /// The error code, according to the enum and program definition. + /// + public uint ErrorCode { get; private set; } + + /// + /// Default constructor that populates all values. + /// + /// The corresponding error value. + /// The error message that matches the error value. + public ProgramError(T value, string message) + { + ErrorCode = ((IConvertible)value).ToUInt32(null); + Message = message; + ErrorKind = value; + } + } +} diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/TransactionalBaseClient.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/TransactionalBaseClient.cs.meta new file mode 100644 index 0000000..21a56c6 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Abstract/TransactionalBaseClient.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f3bb976777b27c44492995ca86cbbdba +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/AssociatedTokenAccountProgram.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/AssociatedTokenAccountProgram.cs new file mode 100644 index 0000000..7de694b --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/AssociatedTokenAccountProgram.cs @@ -0,0 +1,107 @@ +using Solana.Unity.Rpc.Models; +using Solana.Unity.Rpc.Utilities; +using Solana.Unity.Wallet; +using Solana.Unity.Wallet.Utilities; +using System; +using System.Collections.Generic; + +namespace Solana.Unity.Programs +{ + /// + /// Implements the Associated Token Account Program methods. + /// + /// For more information see: https://spl.solana.com/associated-token-account + /// + /// + public static class AssociatedTokenAccountProgram + { + /// + /// The address of the Shared Memory Program. + /// + public static readonly PublicKey ProgramIdKey = new("ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"); + + /// + /// The program's name. + /// + private const string ProgramName = "Associated Token Account Program"; + + /// + /// The instruction's name. + /// + private const string InstructionName = "Create Associated Token Account"; + + /// + /// Initialize a new transaction which interacts with the Associated Token Account Program to create + /// a new associated token account. + /// + /// The public key of the account used to fund the associated token account. + /// The public key of the owner account for the new associated token account. + /// The public key of the mint for the new associated token account. + /// The transaction instruction, returns null whenever an associated token address could not be derived.. + public static TransactionInstruction CreateAssociatedTokenAccount(PublicKey payer, PublicKey owner, PublicKey mint) + { + PublicKey associatedTokenAddress = DeriveAssociatedTokenAccount(owner, mint); + + if (associatedTokenAddress == null) return null; + + List keys = new() + { + AccountMeta.Writable(payer, true), + AccountMeta.Writable(associatedTokenAddress, false), + AccountMeta.ReadOnly(owner, false), + AccountMeta.ReadOnly(mint, false), + AccountMeta.ReadOnly(SystemProgram.ProgramIdKey, false), + AccountMeta.ReadOnly(TokenProgram.ProgramIdKey, false), + AccountMeta.ReadOnly(SysVars.RentKey, false) + }; + + return new TransactionInstruction + { + ProgramId = ProgramIdKey.KeyBytes, + Keys = keys, + Data = Array.Empty() + }; + } + + /// + /// Derive the public key of the associated token account for the + /// + /// The public key of the owner account for the new associated token account. + /// The public key of the mint for the new associated token account. + /// The public key of the associated token account if it could be found, otherwise null. + public static PublicKey DeriveAssociatedTokenAccount(PublicKey owner, PublicKey mint) + { + bool success = PublicKey.TryFindProgramAddress( + new List { owner.KeyBytes, TokenProgram.ProgramIdKey.KeyBytes, mint.KeyBytes }, + ProgramIdKey, out PublicKey derivedAssociatedTokenAddress, out _); + return derivedAssociatedTokenAddress; + } + + /// + /// Decodes an instruction created by the Associated Token Account Program. + /// + /// The instruction data to decode. + /// The account keys present in the transaction. + /// The indices of the account keys for the instruction as they appear in the transaction. + /// A decoded instruction. + public static DecodedInstruction Decode(ReadOnlySpan data, IList keys, byte[] keyIndices) + { + DecodedInstruction decodedInstruction = new() + { + PublicKey = ProgramIdKey, + InstructionName = InstructionName, + ProgramName = ProgramName, + Values = new Dictionary + { + {"Payer", keys[keyIndices[0]]}, + {"Associated Token Account Address", keys[keyIndices[1]]}, + {"Owner", keys[keyIndices[2]]}, + {"Mint", keys[keyIndices[3]]}, + }, + InnerInstructions = new List(), + }; + + return decodedInstruction; + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/AssociatedTokenAccountProgram.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/AssociatedTokenAccountProgram.cs.meta new file mode 100644 index 0000000..8b49057 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/AssociatedTokenAccountProgram.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 81655e0296be90a46b1d35538a2b4916 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/AuthorityType.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/AuthorityType.cs new file mode 100644 index 0000000..5e28b75 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/AuthorityType.cs @@ -0,0 +1,28 @@ +namespace Solana.Unity.Programs +{ + /// + /// Represents the types of authorities for instructions. + /// + public enum AuthorityType : byte + { + /// + /// Authority to mint new tokens. + /// + MintTokens = 0, + + /// + /// Authority to freeze any account associated with the mint. + /// + FreezeAccount = 1, + + /// + /// Owner of a given account token. + /// + AccountOwner = 2, + + /// + /// Authority to close a given account. + /// + CloseAccount = 3, + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/AuthorityType.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/AuthorityType.cs.meta new file mode 100644 index 0000000..24684d5 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/AuthorityType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bb73a2be55d75924c9aa88fcbdcdc163 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Clients.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Clients.meta new file mode 100644 index 0000000..8289f2e --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Clients.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ead028059537e6d46acaaf97883a4814 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Clients/NameServiceClient.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Clients/NameServiceClient.cs new file mode 100644 index 0000000..6c6d8b1 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Clients/NameServiceClient.cs @@ -0,0 +1,344 @@ +using Solana.Unity.Programs.Abstract; +using Solana.Unity.Programs.Models; +using Solana.Unity.Programs.Models.NameService; +using Solana.Unity.Rpc; +using Solana.Unity.Rpc.Models; +using Solana.Unity.Wallet; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Solana.Unity.Programs.Clients +{ + /// + /// A client for the Spl Name Service. + /// Enables easy lookup into names and addresses. + /// + public class NameServiceClient : BaseClient + { + /// + /// The top level domain for the token registry. + /// + public static readonly PublicKey TokenTLD = new("6NSu2tci4apRKQtt257bAVcvqYjB3zV2H1dWo56vgpa6"); + + /// + /// The top level domain for the twitter registry. + /// + public static readonly PublicKey TwitterTLD = new("4YcexoW3r78zz16J2aqmukBLRwGq6rAvWzJpkYAXqebv"); + + /// + /// Class for the reverse twitter name derivation and lookup. + /// + public static readonly PublicKey ReverseTwitterNameClass = new("FvPH7PrVrLGKPfqaf3xJodFTjZriqrAXXLTVWEorTFBi"); + + /// + /// The top level domain for the .sol domain name registry. + /// + public static readonly PublicKey SolTLD = new("58PwtjSDuFHuUkYjH9BYnnQKHfwo9reZhC2zMJv9JPkx"); + + /// + /// Class for the reverse Sol name derivation and lookup. + /// + public static readonly PublicKey ReverseSolNameClass = new("33m47vH6Eav6jr5Ry86XjhRft2jRBLDnDgPSHoquXi2Z"); + + /// + /// Default constructor. + /// + /// The rpc client to connect to the network. + public NameServiceClient(IRpcClient rpcClient) : base(rpcClient, null, NameServiceProgram.ProgramIdKey) + { + + } + + /// + /// Gets all records owned by a given account. + /// + /// The owner address. + /// A list containing all records. + public async Task> GetAllNamesByOwnerAsync(string address) + { + var res = await RpcClient.GetProgramAccountsAsync(ProgramIdKey, Unity.Rpc.Types.Commitment.Confirmed, null, + new List() { new MemCmp() { Bytes = address, Offset = 32 } }); + + List result = new(); + + if(!res.WasSuccessful || res.Result == null || res.Result.Count == 0) return result; + + Dictionary nameToRecordMap = new Dictionary(); + + foreach (var add in res.Result) + { + var data = Convert.FromBase64String(add.Account.Data[0]); + var header = RecordHeader.Deserialize(data); + + if (header.ParentName == SolTLD) + { + var hashedName = NameServiceProgram.ComputeHashedName(add.PublicKey); + var pda = NameServiceProgram.DeriveNameAccountKey(hashedName, ReverseSolNameClass, null); + + var name = NameRecord.Deserialize(data); + + nameToRecordMap.Add(pda, name); + } + else if (header.ParentName == TwitterTLD) + { + if (header.Class == ReverseTwitterNameClass) //reverse twitter name res + { + var reverseTwitterName = ReverseTwitterRecord.Deserialize(data); + reverseTwitterName.AccountAddress = new(add.PublicKey); + + result.Add(reverseTwitterName); + } + else //twitter name resolution + { + var twitterName = NameRecord.Deserialize(data); + twitterName.AccountAddress = new(add.PublicKey); + + result.Add(twitterName); + } + } + else if (header.ParentName == TokenTLD) + { + if (data.Length == 224) // it seems reverse token names are 224 bytes + { + var revToken = ReverseTokenNameRecord.Deserialize(data); + revToken.AccountAddress = new(add.PublicKey); + + result.Add(revToken); + } + else // bigger account data to store all metadata related to the token + { + var tokenName = TokenNameRecord.Deserialize(data); + tokenName.AccountAddress = new(add.PublicKey); + + result.Add(tokenName); + } + } + } + + var reverseNameAddresses = nameToRecordMap.Keys.ToList(); + List accInfos = new(); + + var addressesCopy = new List(reverseNameAddresses); + + while (addressesCopy.Count > 0) + { + List currentReq = null; + if (addressesCopy.Count > 100) + { + currentReq = addressesCopy.Take(100).ToList(); + addressesCopy = addressesCopy.Skip(100).ToList(); + } + else + { + currentReq = new(addressesCopy); + addressesCopy.Clear(); + } + + var multipleAccs = await RpcClient.GetMultipleAccountsAsync(currentReq, Unity.Rpc.Types.Commitment.Confirmed); + + if (!multipleAccs.WasSuccessful) + { + break; + } + + multipleAccs.Result.Value.ForEach(x => accInfos.Add(x)); + } + + for (int i = 0; i < accInfos.Count; i++) + { + var nr = nameToRecordMap[reverseNameAddresses[i]]; + var current = accInfos[i]; + // it seems bonfida screwd up and some of these pdas are empty and impossible to get the name + // + if (current == null) + { + continue; + } + + var rev = ReverseNameRecord.Deserialize(Convert.FromBase64String(current.Data[0])); + + rev.Value = nr; + rev.AccountAddress = new(reverseNameAddresses[i]); + + result.Add(rev); + } + + return result; + } + + /// + /// Helper method that calls GetAccount<>() and sets common params on result object. + /// + /// The type to Serialize to. + /// The account to retrieve. + /// The lokup helper value to store in the returning object. + /// Returns the parsed account object according to the given type parameter . + private async Task> GetAccountAndSetMetadata(PublicKey accountAddress, string lookupValue) where T : RecordBase + { + var res = await GetAccount(accountAddress); + + if (res.WasSuccessful) + { + res.ParsedResult.AccountAddress = accountAddress; + res.ParsedResult.LookupValue = lookupValue; + } + + return res; + } + + /// + /// Gets the token info for a given token mint. + /// + /// The token mint address. + /// The token info record. + public async Task> GetTokenInfoFromMintAsync(string address) + { + var hashedName = NameServiceProgram.ComputeHashedName(address); + + var pda = NameServiceProgram.DeriveNameAccountKey(hashedName, null, TokenTLD); + + + return await GetAccountAndSetMetadata(pda, address); + } + + /// + /// Gets the token mint from a given token ticker. + /// + /// The ticker for the token. + /// The record containing the token mint address. + public async Task> GetMintFromTokenTickerAsync(string tokenTicker) + { + var hashedName = NameServiceProgram.ComputeHashedName(tokenTicker); + + var pda = NameServiceProgram.DeriveNameAccountKey(hashedName, null, TokenTLD); + + + return await GetAccountAndSetMetadata(pda, tokenTicker); + } + + /// + /// Gets the name record from a given twitter handle. + /// + /// The twitter handle. + /// The name record. + public async Task> GetAddressFromTwitterHandleAsync(string twitterHandle) + { + var hashedName = NameServiceProgram.ComputeHashedName(twitterHandle); + + var pda = NameServiceProgram.DeriveNameAccountKey(hashedName, null, TwitterTLD); + + return await GetAccountAndSetMetadata(pda, twitterHandle); + } + + /// + /// Get the reverse twitter record from a given address. + /// + /// The address. + /// The reverse record containing the twitter handle. + public async Task> GetTwitterHandleFromAddressAsync(string address) + { + var hashedName = NameServiceProgram.ComputeHashedName(address); + + var pda = NameServiceProgram.DeriveNameAccountKey(hashedName, ReverseTwitterNameClass, TwitterTLD); + + return await GetAccountAndSetMetadata(pda, address); + } + + /// + /// Gets the address record from a given .sol name. + /// + /// The name (either with ".sol" or without). + /// The address record from the given name. + public async Task> GetAddressFromNameAsync(string name) + { + if (name.EndsWith(".sol")) + { + name = name.Substring(0, name.Length - 4); + } + + var hashedName = NameServiceProgram.ComputeHashedName(name); + + var pda = NameServiceProgram.DeriveNameAccountKey(hashedName, null, SolTLD); + + return await GetAccountAndSetMetadata(pda, name); + } + + /// + /// Get name records owned by a given address. + /// + /// The owner address. + /// A collection of name records owned by the address. + public async Task> GetNamesFromAddressAsync(string address) + { + + var res = await RpcClient.GetProgramAccountsAsync(ProgramIdKey, Unity.Rpc.Types.Commitment.Confirmed, null, + new List() { new MemCmp() { Bytes = SolTLD, Offset = 0 }, new MemCmp() { Bytes = address, Offset = 32 } }); + + List ret = new(); + if(!res.WasSuccessful || res.Result == null || res.Result.Count == 0) return ret; + + Dictionary nameToRecordMap = new Dictionary(); + foreach (var add in res.Result) + { + var name = NameRecord.Deserialize(Convert.FromBase64String(add.Account.Data[0])); + var hashedName = NameServiceProgram.ComputeHashedName(add.PublicKey); + + var pda = NameServiceProgram.DeriveNameAccountKey(hashedName, ReverseSolNameClass, null); + + nameToRecordMap.Add(pda, name); + } + + var reverseNameAddresses = nameToRecordMap.Keys.ToList(); + List accInfos = new(); + + var addressesCopy = new List(reverseNameAddresses); + + while (addressesCopy.Count > 0) + { + List currentReq = null; + if (addressesCopy.Count > 100) + { + currentReq = addressesCopy.Take(100).ToList(); + addressesCopy = addressesCopy.Skip(100).ToList(); + } + else + { + currentReq = new(addressesCopy); + addressesCopy.Clear(); + } + + var multipleAccs = await RpcClient.GetMultipleAccountsAsync(currentReq, Unity.Rpc.Types.Commitment.Confirmed); + + if (!multipleAccs.WasSuccessful) + { + break; + } + + multipleAccs.Result.Value.ForEach(x => accInfos.Add(x)); + } + + for (int i = 0; i < accInfos.Count; i++) + { + var nr = nameToRecordMap[reverseNameAddresses[i]]; + var current = accInfos[i]; + // it seems bonfida screwd up and some of these pdas are empty and impossible to get the name + // + if (current == null) + { + continue; + } + + var rev = ReverseNameRecord.Deserialize(Convert.FromBase64String(current.Data[0])); + + rev.Value = nr; + rev.AccountAddress = new(reverseNameAddresses[i]); + + ret.Add(rev); + } + + return ret; + } + } +} diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Clients/NameServiceClient.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Clients/NameServiceClient.cs.meta new file mode 100644 index 0000000..cd56829 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Clients/NameServiceClient.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0af9fc9222651b749ae0cf61e3bc722b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/InstructionDecoder.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/InstructionDecoder.cs new file mode 100644 index 0000000..b4f89ad --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/InstructionDecoder.cs @@ -0,0 +1,198 @@ +using Solana.Unity.Programs.TokenSwap; +using Solana.Unity.Rpc.Builders; +using Solana.Unity.Rpc.Models; +using Solana.Unity.Wallet; +using Solana.Unity.Wallet.Utilities; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Solana.Unity.Programs +{ + /// + /// Implements instruction decoder functionality. + /// + public static class InstructionDecoder + { + /// + /// The dictionary which maps the program public keys to their decoding method. + /// + private static readonly Dictionary InstructionDictionary = new(); + + /// + /// The method type which is used to perform instruction decoding. + /// + public delegate DecodedInstruction DecodeMethodType(ReadOnlySpan data, IList keys, byte[] keyIndices); + + /// + /// Initialize the instruction decoder instance. + /// + static InstructionDecoder() + { + InstructionDictionary.Add(MemoProgram.ProgramIdKey, MemoProgram.Decode); + InstructionDictionary.Add(MemoProgram.ProgramIdKeyV2, MemoProgram.Decode); + InstructionDictionary.Add(SystemProgram.ProgramIdKey, SystemProgram.Decode); + InstructionDictionary.Add(TokenProgram.ProgramIdKey, TokenProgram.Decode); + InstructionDictionary.Add(TokenSwapProgram.TokenSwapProgramIdKey, TokenSwapProgram.Decode); + InstructionDictionary.Add(AssociatedTokenAccountProgram.ProgramIdKey, AssociatedTokenAccountProgram.Decode); + InstructionDictionary.Add(NameServiceProgram.ProgramIdKey, NameServiceProgram.Decode); + InstructionDictionary.Add(SharedMemoryProgram.ProgramIdKey, SharedMemoryProgram.Decode); + InstructionDictionary.Add(StakeProgram.ProgramIdKey, StakeProgram.Decode); + } + + /// + /// Register the public key of a program and it's method used for instruction decoding. + /// + /// The public key of the program to decode data from. + /// The method which is called to perform instruction decoding for the program. + public static void Register(PublicKey programKey, DecodeMethodType decodingMethod) + { + InstructionDictionary.Add(programKey, decodingMethod); + } + + /// + /// Decodes the given instruction data for a given program key + /// + /// The public key of the program to decode data from. + /// The instruction data to decode. + /// The account keys present in the transaction. + /// The indices of the account keys for the instruction as they appear in the transaction. + /// The decoded instruction data. + public static DecodedInstruction Decode(PublicKey programKey, ReadOnlySpan data, List keys, byte[] keyIndices) + { + bool exists = InstructionDictionary.TryGetValue(programKey, out DecodeMethodType method); + return !exists ? null : method?.Invoke(data, keys, keyIndices); + } + + /// + /// Decodes the instructions present in the given transaction and it's metadata information. + /// + /// The transaction metadata info object. + /// The decoded instructions data. + public static List DecodeInstructions(TransactionMetaInfo txMetaInfo) + { + List decodedInstructions = new(); + + for (int i = 0; i < txMetaInfo.Transaction.Message.Instructions.Length; i++) + { + DecodedInstruction decodedInstruction = null; + InstructionInfo instructionInfo = txMetaInfo.Transaction.Message.Instructions[i]; + string programKey = txMetaInfo.Transaction.Message.AccountKeys[instructionInfo.ProgramIdIndex]; + bool registered = InstructionDictionary.TryGetValue(programKey, out DecodeMethodType method); + + if (!registered) + { + decodedInstruction = AddUnknownInstruction( + instructionInfo, programKey, txMetaInfo.Transaction.Message.AccountKeys, + txMetaInfo.Transaction.Message.Instructions[i].Accounts); + } + else + { + decodedInstruction = method.Invoke( + Encoders.Base58.DecodeData(instructionInfo.Data), + txMetaInfo.Transaction.Message.AccountKeys.Select(a => new PublicKey(a)).ToList(), + instructionInfo.Accounts.Select(instr => (byte)instr).ToArray()); + } + + foreach (InnerInstruction innerInstruction in txMetaInfo.Meta.InnerInstructions) + { + if (innerInstruction.Index != i) continue; + + foreach (InstructionInfo innerInstructionInfo in innerInstruction.Instructions) + { + DecodedInstruction innerDecodedInstruction = null; + programKey = txMetaInfo.Transaction.Message.AccountKeys[innerInstructionInfo.ProgramIdIndex]; + registered = InstructionDictionary.TryGetValue(programKey, out method); + + if (!registered) + { + innerDecodedInstruction = AddUnknownInstruction( + innerInstructionInfo, programKey, txMetaInfo.Transaction.Message.AccountKeys, + txMetaInfo.Transaction.Message.Instructions[i].Accounts); + } + else + { + innerDecodedInstruction = method.Invoke( + Encoders.Base58.DecodeData(innerInstructionInfo.Data), + txMetaInfo.Transaction.Message.AccountKeys.Select(a => new PublicKey(a)).ToList(), + innerInstructionInfo.Accounts.Select(instr => (byte)instr).ToArray()); + } + if (innerDecodedInstruction != null) + decodedInstruction.InnerInstructions.Add(innerDecodedInstruction); + } + } + if (decodedInstruction != null) + decodedInstructions.Add(decodedInstruction); + } + return decodedInstructions; + } + + /// + /// Decodes the instructions present in the given transaction and its metadata information. + /// + /// The message object. + /// The decoded instructions data. + public static List DecodeInstructions(Message message) + { + List decodedInstructions = new(); + + foreach (CompiledInstruction compiledInstruction in message.Instructions) + { + string programKey = message.AccountKeys[compiledInstruction.ProgramIdIndex]; + bool registered = InstructionDictionary.TryGetValue(programKey, out DecodeMethodType method); + + if (!registered) + { + DecodedInstruction decodedInstruction = new() + { + InstructionName = "Unknown", + ProgramName = "Unknown", + Values = new Dictionary + { + { "Data", Encoders.Base58.EncodeData(compiledInstruction.Data) } + }, + InnerInstructions = new List(), + PublicKey = message.AccountKeys[compiledInstruction.ProgramIdIndex] + }; + for (int i = 0; i < compiledInstruction.KeyIndices.Length; i++) + { + decodedInstruction.Values.Add($"Account {i + 1}", message.AccountKeys[i]); + } + decodedInstructions.Add(decodedInstruction); + continue; + } + + decodedInstructions.Add(method.Invoke( + compiledInstruction.Data, + message.AccountKeys, + compiledInstruction.KeyIndices)); + } + return decodedInstructions; + } + + /// + /// Adds an unknown instruction to the given list of decoded instructions, with the given instruction info. + /// + private static DecodedInstruction AddUnknownInstruction( + InstructionInfo instructionInfo, string programKey, IReadOnlyList keys, IReadOnlyList keyIndices) + { + DecodedInstruction decodedInstruction = new() + { + Values = new Dictionary + { + {"Data", instructionInfo.Data} + }, + InnerInstructions = new List(), + InstructionName = "Unknown", + ProgramName = "Unknown", + PublicKey = new PublicKey(programKey) + }; + for (int j = 0; j < keyIndices.Count; j++) + { + decodedInstruction.Values.Add($"Account {j + 1}", keys[keyIndices[j]]); + } + + return decodedInstruction; + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/InstructionDecoder.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/InstructionDecoder.cs.meta new file mode 100644 index 0000000..16eef51 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/InstructionDecoder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 41c60707428cb124aaf3214eef355a86 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/MemoProgram.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/MemoProgram.cs new file mode 100644 index 0000000..f4a16ba --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/MemoProgram.cs @@ -0,0 +1,113 @@ +using Solana.Unity.Rpc.Models; +using Solana.Unity.Wallet; +using Solana.Unity.Wallet.Utilities; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Solana.Unity.Programs +{ + /// + /// Implements the Memo Program methods. + /// + /// For more information see: https://spl.solana.com/memo + /// + /// + public static class MemoProgram + { + /// + /// The public key of the Memo Program. + /// + public static readonly PublicKey ProgramIdKey = new("Memo1UhkJRfHyvLMcVucJwxXeuD728EqVDDwQDxFMNo"); + + /// + /// The public key of the Memo Program V2. + /// + public static readonly PublicKey ProgramIdKeyV2 = new("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"); + + /// + /// The program's name. + /// + private const string ProgramName = "Memo Program"; + + /// + /// The instruction's name. + /// + private const string InstructionName = "New Memo"; + + /// + /// Initialize a new transaction instruction which interacts with the Memo Program. + /// + /// The public key of the account associated with the memo. + /// The memo to be included in the transaction. + /// The which includes the memo data. + public static TransactionInstruction NewMemo(PublicKey account, string memo) + { + List keys = new() + { + AccountMeta.ReadOnly(account, true) + }; + byte[] memoBytes = Encoding.UTF8.GetBytes(memo); + + return new TransactionInstruction + { + ProgramId = ProgramIdKey.KeyBytes, + Keys = keys, + Data = memoBytes + }; + } + + /// + /// Initialize a new transaction instruction which interacts with the Memo Program. + /// + /// The public key of the account associated with the memo. + /// The memo to be included in the transaction. + /// The which includes the memo data. + public static TransactionInstruction NewMemoV2(string memo, PublicKey account = null) + { + List keys = new(); + if (account != null) + keys.Add(AccountMeta.ReadOnly(account, true)); + + byte[] memoBytes = Encoding.UTF8.GetBytes(memo); + + return new TransactionInstruction + { + ProgramId = ProgramIdKeyV2.KeyBytes, + Keys = keys, + Data = memoBytes + }; + } + + /// + /// Decodes an instruction created by the Memo Program. + /// + /// The instruction data to decode. + /// The account keys present in the transaction. + /// The indices of the account keys for the instruction as they appear in the transaction. + /// A decoded instruction. + public static DecodedInstruction Decode(ReadOnlySpan data, IList keys, byte[] keyIndices) + { + DecodedInstruction decodedInstruction = new() + { + PublicKey = keys.Any(x => x.Key == ProgramIdKey.Key) ? ProgramIdKey : ProgramIdKeyV2, + InstructionName = InstructionName, + ProgramName = ProgramName, + InnerInstructions = new List(), + Values = new Dictionary() + }; + if (keyIndices.Length > 0) + { + decodedInstruction.Values.Add("Signer", keys[keyIndices[0]]); + decodedInstruction.Values.Add("Memo", Encoding.UTF8.GetString(data.ToArray())); + } + else + { + decodedInstruction.Values.Add("Memo", Encoding.UTF8.GetString(data.ToArray())); + } + + return decodedInstruction; + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/MemoProgram.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/MemoProgram.cs.meta new file mode 100644 index 0000000..701c60c --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/MemoProgram.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0ce2377cc6ff2f54ea070d63c7b3edaf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models.meta new file mode 100644 index 0000000..060c03d --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 168ce7a8820e39e4ea99ef099c5fcb59 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/DecodedInstruction.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/DecodedInstruction.cs new file mode 100644 index 0000000..e12c31f --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/DecodedInstruction.cs @@ -0,0 +1,59 @@ +using Solana.Unity.Wallet; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Solana.Unity.Programs +{ + /// + /// Represents a decoded instruction. + /// + public class DecodedInstruction + { + /// + /// The public key of the program. + /// + public PublicKey PublicKey { get; set; } + + /// + /// The program name. + /// + public string ProgramName { get; set; } + + /// + /// The instruction name. + /// + public string InstructionName { get; set; } + + /// + /// Values decoded from the instruction. + /// + public Dictionary Values { get; set; } + + /// + /// The inner instructions related to this decoded instruction. + /// + public List InnerInstructions { get; set; } + + /// + /// Converts the decoded instructions to a string + /// + /// A string representation of the decoded instructions + public override string ToString() => ToString(0); + + /// + /// Converts the decoded instructions to a string, indented a certain amount + /// + /// A string representation of the decoded instructions, indented a certain amount + public string ToString(int indent) + { + var sb = new StringBuilder(); + sb.Append($"{new string(Enumerable.Repeat(' ', indent * 4).ToArray())}[{indent}] {PublicKey}:{ProgramName}:{InstructionName}\n"); + sb.Append($"{new string(Enumerable.Repeat(' ', indent * 4).ToArray())}[{indent}] [{string.Join(",", Values.Select(a=>a))}]\n"); + sb.Append($"{new string(Enumerable.Repeat(' ', indent * 4).ToArray())}[{indent}] InnerInstructions ({InnerInstructions.Count})\n"); + foreach (var item in InnerInstructions) + sb.Append(item.ToString(indent + 1)); + return sb.ToString(); + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/DecodedInstruction.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/DecodedInstruction.cs.meta new file mode 100644 index 0000000..5e37543 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/DecodedInstruction.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c8b0e9b9856394f48a7eca602309c88f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService.meta new file mode 100644 index 0000000..e7148d5 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 83578f4bd3f42254384193d62c7c98b8 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService/NameRecord.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService/NameRecord.cs new file mode 100644 index 0000000..29f6122 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService/NameRecord.cs @@ -0,0 +1,48 @@ +using Solana.Unity.Programs.Clients; +using Solana.Unity.Programs.Utilities; +using System.Diagnostics; + +namespace Solana.Unity.Programs.Models.NameService +{ + /// + /// Represents a naming record. + /// + [DebuggerDisplay("Type: {Type}, Address: {AccountAddress}")] + public class NameRecord : RecordBase + { + /// + /// Default constructor. + /// + /// The record header. + /// The type of the name record. + public NameRecord(RecordHeader header, RecordType type) : base(header, type) + { + } + + /// + /// The storage of this name record. + /// + public byte[] Value { get; set; } + + /// + public override object GetValue() => Value; + + /// + /// Deserialization method for a name record account. + /// + /// The raw data. + /// The deserialized record. + public static NameRecord Deserialize(byte[] input) + { + var header = RecordHeader.Deserialize(input); + + var recordType = header.ParentName == NameServiceClient.SolTLD ? RecordType.NameRecord : RecordType.TwitterRecord; + + var res = new NameRecord(header, recordType); + + res.Value = input.Slice(96); + + return res; + } + } +} diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService/NameRecord.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService/NameRecord.cs.meta new file mode 100644 index 0000000..b23f3dd --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService/NameRecord.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bf06a2dc1b21043408db5ebc44f40265 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService/RecordBase.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService/RecordBase.cs new file mode 100644 index 0000000..a80d484 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService/RecordBase.cs @@ -0,0 +1,49 @@ +using Solana.Unity.Wallet; +using System.Diagnostics; + +namespace Solana.Unity.Programs.Models.NameService +{ + /// + /// Base class containing record registration details. + /// + [DebuggerDisplay("Type: {Type}, Address: {AccountAddress}")] + public abstract class RecordBase + { + /// + /// The record header. + /// + public RecordHeader Header { get; } + + /// + /// The type of the record. + /// + public RecordType Type { get; } + + /// + /// The address of the native account containing this record. + /// + public PublicKey AccountAddress { get; internal set; } + + /// + /// The name lookup value (when applicable). + /// + public string LookupValue { get; internal set; } + + /// + /// Default constructor. + /// + /// The header of this record. + /// The type of this record (directly related to header TLD and Class). + public RecordBase(RecordHeader header, RecordType type) + { + Header = header; + Type = type; + } + + /// + /// Gets the value held by this record. + /// + /// The value. + public abstract object GetValue(); + } +} diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService/RecordBase.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService/RecordBase.cs.meta new file mode 100644 index 0000000..22e33e2 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService/RecordBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d68128cd5e8e1644d8a64ab260a04710 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService/RecordHeader.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService/RecordHeader.cs new file mode 100644 index 0000000..e9ce536 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService/RecordHeader.cs @@ -0,0 +1,82 @@ +using Solana.Unity.Programs.Utilities; +using Solana.Unity.Wallet; +using System; +using System.Diagnostics; + +namespace Solana.Unity.Programs.Models.NameService +{ + /// + /// Represents the record header. + /// + [DebuggerDisplay("Owner: {Owner}, TLD: {ParentName}, Class: {Class}")] + public class RecordHeader + { + /// + /// The Top Level Domain of a given record. + /// + public PublicKey ParentName { get; set; } + + /// + /// The owner of a given record. + /// For name records, its the account that owns the name. + /// For reverse name records, its a mess. + /// + public PublicKey Owner { get; set; } + + /// + /// The class of the record. + /// + public PublicKey Class { get; set; } + + /// + /// Deserializes a record header from a given account data. + /// + /// The raw account data. + /// The deserialized RecordHeader from the data. + public static RecordHeader Deserialize(byte[] input) + { + if (input.Length < 96) + throw new IndexOutOfRangeException($"Record headers are 96 bytes. Found {input.Length} bytes in the current buffer."); + + var data = new ReadOnlySpan(input); + var res = new RecordHeader(); + + res.ParentName = data.GetPubKey(0); + res.Owner = data.GetPubKey(32); + res.Class = data.GetPubKey(64); + + return res; + } + } + + /// + /// Type of record. + /// + public enum RecordType + { + /// + /// A naming record. The account holds binary storage. + /// + NameRecord, + /// + /// A reverse naming record. The account holds the name string. + /// + ReverseRecord, + /// + /// A twitter naming record. The account holds binary storage. + /// + TwitterRecord, + /// + /// A reverse twitter record. The account holds the twitter handle. + /// + ReverseTwitterRecord, + /// + /// A token naming record. The account holds token metadata. + /// + TokenRecord, + /// + /// A reverse token record. The account holds the mint address. + /// + ReverseTokenRecord + } +} diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService/RecordHeader.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService/RecordHeader.cs.meta new file mode 100644 index 0000000..96de801 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService/RecordHeader.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 483887f6038f42a4f9d9ea0b97b4e7a0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService/ReverseNameRecord.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService/ReverseNameRecord.cs new file mode 100644 index 0000000..56cf71b --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService/ReverseNameRecord.cs @@ -0,0 +1,54 @@ +using Solana.Unity.Programs.Utilities; +using System; +using System.Diagnostics; +using System.Text; + +namespace Solana.Unity.Programs.Models.NameService +{ + /// + /// Represents a reverse naming record. + /// + [DebuggerDisplay("Type: {Type}, Name: {Name}")] + public class ReverseNameRecord : RecordBase + { + /// + /// Default constructor + /// + /// The record header. + /// The name of this reverse record. + public ReverseNameRecord(RecordHeader header, string name) : base(header, RecordType.ReverseRecord) + { + Name = name; + } + + /// + /// The name of the record. + /// + public string Name { get; } + + /// + public override object GetValue() => Name; + + /// + /// The record this Name points to. + /// + public NameRecord Value { get; internal set; } + + /// + /// Deserialization method for a reverse name record account. + /// + /// The raw data. + /// The deserialized reverse record. + public static ReverseNameRecord Deserialize(byte[] input) + { + var data = new ReadOnlySpan(input, 96, input.Length - 96); + + var header = RecordHeader.Deserialize(input); + _ = data.GetBorshString(0, out var str); + + var res = new ReverseNameRecord(header, str); + + return res; + } + } +} diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService/ReverseNameRecord.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService/ReverseNameRecord.cs.meta new file mode 100644 index 0000000..151272e --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService/ReverseNameRecord.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1d63efb672c1e2a4e8c59e6113272b34 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService/ReverseTokenNameRecord.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService/ReverseTokenNameRecord.cs new file mode 100644 index 0000000..5270f11 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService/ReverseTokenNameRecord.cs @@ -0,0 +1,46 @@ +using Solana.Unity.Programs.Utilities; +using Solana.Unity.Wallet; +using System; +using System.Diagnostics; + +namespace Solana.Unity.Programs.Models.NameService +{ + /// + /// Represents a reverse token name record. + /// + [DebuggerDisplay("Type: {Type}, Mint: {Value}")] + public class ReverseTokenNameRecord : RecordBase + { + /// + /// Default constructor. + /// + /// The record header. + public ReverseTokenNameRecord(RecordHeader header) : base(header, RecordType.ReverseTokenRecord) + { + } + + /// + /// The token mint address. + /// + public PublicKey Value { get; set; } + + /// + public override object GetValue() => Value; + + /// + /// Deserialization method for a reverse token name record account. + /// + /// The raw data. + /// The deserialized reverse token name record. + public static ReverseTokenNameRecord Deserialize(byte[] input) + { + var data = new ReadOnlySpan(input); + var header = RecordHeader.Deserialize(input); + var res = new ReverseTokenNameRecord(header); + + res.Value = data.GetPubKey(96); + + return res; + } + } +} diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService/ReverseTokenNameRecord.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService/ReverseTokenNameRecord.cs.meta new file mode 100644 index 0000000..837bd4d --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService/ReverseTokenNameRecord.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 510550dcb5c428e4788bb346e33a23cf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService/ReverseTwitteRecord.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService/ReverseTwitteRecord.cs new file mode 100644 index 0000000..5b0c50b --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService/ReverseTwitteRecord.cs @@ -0,0 +1,55 @@ +using Solana.Unity.Programs.Utilities; +using Solana.Unity.Wallet; +using System; +using System.Diagnostics; +using System.Text; + +namespace Solana.Unity.Programs.Models.NameService +{ + /// + /// Represents a reverse twitter record. + /// + [DebuggerDisplay("Type: {Type}, TwitterHandle: {TwitterHandle}")] + public class ReverseTwitterRecord : RecordBase + { + /// + /// Default constructor. + /// + /// The record header. + public ReverseTwitterRecord(RecordHeader header) : base(header, RecordType.ReverseTwitterRecord) + { + } + + /// + /// The twitter registry address. + /// + public PublicKey TwitterRegistryKey { get; set; } + + /// + /// The twitter handle. + /// + public string TwitterHandle { get; set; } + + /// + public override object GetValue() => TwitterHandle; + + /// + /// Deserialization method for a reverse twitter name record account. + /// + /// The raw data. + /// The deserialized reverse twitter record. + public static ReverseTwitterRecord Deserialize(byte[] input) + { + var data = new ReadOnlySpan(input, 96, input.Length - 96); + var header = RecordHeader.Deserialize(input); + + var ret = new ReverseTwitterRecord(header); + + ret.TwitterRegistryKey = data.GetPubKey(0); + _ = data.GetBorshString(32, out var str); + ret.TwitterHandle = str; + + return ret; + } + } +} diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService/ReverseTwitteRecord.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService/ReverseTwitteRecord.cs.meta new file mode 100644 index 0000000..9589847 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService/ReverseTwitteRecord.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 51012c63552a8964e815d6731bf33e71 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService/TokenData.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService/TokenData.cs new file mode 100644 index 0000000..1d9b131 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService/TokenData.cs @@ -0,0 +1,75 @@ +using Solana.Unity.Wallet; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Solana.Unity.Programs.Utilities; + +namespace Solana.Unity.Programs.Models.NameService +{ + /// + /// Represents a Token metadata record. + /// + public class TokenData + { + /// + /// The name of the token. + /// + public string Name { get; set; } + + /// + /// The ticker of the token. + /// + public string Ticker { get; set; } + + /// + /// The mint account address of the token. + /// + public PublicKey Mint { get; set; } + + /// + /// The decimals used by the token. This dictates the minimum transferrable value. + /// + public byte Decimals { get; set; } + + /// + /// The website of the token or project. + /// + public string Website { get; set; } + + /// + /// The uri for the token logo. + /// + public string LogoUri { get; set; } + + /// + /// Deserialization method for a token metadata record account. + /// + /// The raw data. + /// The deserialized token metadata record. + public static TokenData Deserialize(byte[] input) + { + var data = new ReadOnlySpan(input, 96, input.Length - 96); + int offset = 0; + + offset += data.GetBorshString(0, out var name); + offset += data.GetBorshString(offset, out var ticker); + + var mint = data.GetPubKey(offset); + offset += 32; + + var decimals = data.GetU8(offset); + offset++; + string website = null, logo = null; + + if (data.GetBool(offset++)) + offset += data.GetBorshString(offset, out website); + + if (data.GetBool(offset++)) + data.GetBorshString(offset, out logo); + + return new TokenData() { Name = name, Ticker = ticker, Decimals = decimals, LogoUri = logo, Mint = mint, Website = website }; + } + } +} diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService/TokenData.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService/TokenData.cs.meta new file mode 100644 index 0000000..d8874fa --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService/TokenData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bbc308b998573d34c9900e9700816658 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService/TokenNameRecord.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService/TokenNameRecord.cs new file mode 100644 index 0000000..89b0152 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService/TokenNameRecord.cs @@ -0,0 +1,46 @@ +using System; +using System.Diagnostics; + +namespace Solana.Unity.Programs.Models.NameService +{ + /// + /// Represents a token naming record. + /// + [DebuggerDisplay("Type: {Type}, Symbol: {Value.Ticker}, Mint: {Value.Mint}")] + public class TokenNameRecord : RecordBase + { + /// + /// Default constructor. + /// + /// The record header. + public TokenNameRecord(RecordHeader header) : base(header, RecordType.TokenRecord) + { + } + + /// + /// The token metadata. + /// + public TokenData Value { get; set; } + + /// + public override object GetValue() => Value; + + /// + /// Deserialization method for a token name record account. + /// + /// The raw data. + /// The deserialized token name record. + public static TokenNameRecord Deserialize(byte[] input) + { + var data = new ReadOnlySpan(input); + + var header = RecordHeader.Deserialize(input); + + var res = new TokenNameRecord(header); + + res.Value = TokenData.Deserialize(input); + + return res; + } + } +} diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService/TokenNameRecord.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService/TokenNameRecord.cs.meta new file mode 100644 index 0000000..77ce1b0 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NameService/TokenNameRecord.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 63c5bd498af950b4cb305363546d5d53 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NonceAccount.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NonceAccount.cs new file mode 100644 index 0000000..3fb4c6e --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NonceAccount.cs @@ -0,0 +1,103 @@ +// unset + +using Solana.Unity.Programs.Utilities; +using Solana.Unity.Rpc.Models; +using Solana.Unity.Wallet; +using System; + +namespace Solana.Unity.Programs.Models +{ + /// + /// Represents a Nonce Account in Solana. + /// + public class NonceAccount + { + /// + /// The size of the data for a nonce account. + /// + public const int AccountDataSize = 80; + + #region Layout + + /// + /// Represents the layout of the data structure. + /// + internal static class Layout + { + /// + /// The offset at which the version value begins. + /// + internal const int VersionOffset = 0; + + /// + /// The offset at which the state value begins. + /// + internal const int StateOffset = 4; + + /// + /// The offset at which the authorized public key value begins. + /// + internal const int AuthorizedKeyOffset = 8; + + /// + /// The offset at which the current nonce public key value begins. + /// + internal const int NonceKeyOffset = 40; + + /// + /// The offset at which the fee calculator value begins. + /// + internal const int FeeCalculatorOffset = 72; + } + + #endregion + + /// + /// The value used to specify version. + /// + public uint Version; + + /// + /// The state of the nonce account. + /// + public uint State; + + /// + /// The public key of the account authorized to interact with the nonce account. + /// + public PublicKey Authorized; + + /// + /// The nonce. + /// + public PublicKey Nonce; + + /// + /// + /// + public FeeCalculator FeeCalculator; + + /// + /// Deserialize a span of bytes into a instance. + /// + /// The data to deserialize into the structure. + /// The Nonce Account structure. + public static NonceAccount Deserialize(ReadOnlySpan data) + { + if (data.Length != AccountDataSize) + throw new ArgumentException($"{nameof(data)} has wrong size. Expected {AccountDataSize} bytes, actual {data.Length} bytes."); + + return new() + { + Version = data.GetU32(Layout.VersionOffset), + State = data.GetU32(Layout.StateOffset), + Authorized = data.GetPubKey(Layout.AuthorizedKeyOffset), + Nonce = data.GetPubKey(Layout.NonceKeyOffset), + FeeCalculator = new FeeCalculator + { + LamportsPerSignature = data.GetU64(Layout.FeeCalculatorOffset) + } + }; + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NonceAccount.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NonceAccount.cs.meta new file mode 100644 index 0000000..58491b2 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/NonceAccount.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 318a0b307f5aa714fb799e888e49a747 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/ResultWrapper.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/ResultWrapper.cs new file mode 100644 index 0000000..7a3ebf8 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/ResultWrapper.cs @@ -0,0 +1,147 @@ +using Solana.Unity.Rpc.Core.Http; +using Solana.Unity.Rpc.Core.Sockets; +using Solana.Unity.Rpc.Messages; +using Solana.Unity.Rpc.Models; +using Solana.Unity.Wallet; +using System.Collections.Generic; + +namespace Solana.Unity.Programs.Models +{ + /// + /// Wraps a result to an RPC request. + /// + /// The underlying type of the request. + /// The underlying type of the request. + public class ResultWrapper + { + + /// + /// Initialize the result wrapper with the given result. + /// + /// The result of the request. + public ResultWrapper(RequestResult result) + { + OriginalRequest = result; + } + + /// + /// Initialize the result wrapper with the given result and it's parsed result type. + /// + /// The result of the request. + /// The parsed result type. + public ResultWrapper(RequestResult result, T2 parsedResult) + { + OriginalRequest = result; + ParsedResult = parsedResult; + } + + /// + /// The original response to the request. + /// + public RequestResult OriginalRequest { get; init; } + + /// + /// The desired type of the account data. + /// + public T2 ParsedResult { get; set; } + + /// + /// Whether the deserialization of the account data into the desired structure was successful. + /// + public bool WasDeserializationSuccessful => ParsedResult != null; + + /// + /// Whether the original request and the deserialization of the account data into the desired structure was successful. + /// + public bool WasSuccessful => OriginalRequest.WasSuccessful && WasDeserializationSuccessful; + } + + /// + /// + /// + /// + public class MultipleAccountsResultWrapper : ResultWrapper>, T> + { + /// + /// Initialize the result wrapper with the given result. + /// + /// The result of the request. + public MultipleAccountsResultWrapper(RequestResult>> result) : base(result) { } + + /// + /// Initialize the result wrapper with the given result. + /// + /// The result of the request. + /// The parsed result type. + public MultipleAccountsResultWrapper(RequestResult>> result, T parsedResult) : base(result, parsedResult) { } + } + + /// + /// + /// + /// + public class AccountResultWrapper : ResultWrapper, T> + { + /// + /// Initialize the result wrapper with the given result. + /// + /// The result of the request. + public AccountResultWrapper(RequestResult> result) : base(result) { } + + /// + /// Initialize the result wrapper with the given result. + /// + /// The result of the request. + /// The parsed result type. + public AccountResultWrapper(RequestResult> result, T parsedResult) : base(result, parsedResult) { } + } + + /// + /// + /// + /// + public class ProgramAccountsResultWrapper : ResultWrapper, T> + { + /// + /// Initialize the result wrapper with the given result. + /// + /// The result of the request. + public ProgramAccountsResultWrapper(RequestResult> result) : base(result) { } + + /// + /// Initialize the result wrapper with the given result. + /// + /// The result of the request. + /// The parsed result type. + public ProgramAccountsResultWrapper(RequestResult> result, T parsedResult) : base(result, parsedResult) { } + } + + /// + /// Wraps the base subscription to have the underlying data of the subscription, which is sometimes needed to perform + /// some logic before returning data to the subscription caller. + /// + /// The type of the subscription. + public class SubscriptionWrapper : Subscription + { + /// + /// The underlying data. + /// + public T Data; + } + + /// + /// Wraps a subscription with a generic type to hold either order book or trade events. + /// + public class Subscription + { + /// + /// The address associated with this data. + /// + public PublicKey Address; + + /// + /// The underlying subscription state. + /// + public SubscriptionState SubscriptionState; + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/ResultWrapper.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/ResultWrapper.cs.meta new file mode 100644 index 0000000..cca2bbc --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/ResultWrapper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 536f55f31f7760c46a317ba4052ea623 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/TokenProgram.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/TokenProgram.meta new file mode 100644 index 0000000..67ce60d --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/TokenProgram.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a8f3add7c26fe19498eeca4c6bee66ed +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/TokenProgram/MultiSignatureAccount.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/TokenProgram/MultiSignatureAccount.cs new file mode 100644 index 0000000..aec80ee --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/TokenProgram/MultiSignatureAccount.cs @@ -0,0 +1,97 @@ +using Solana.Unity.Programs.Utilities; +using Solana.Unity.Wallet; +using System; +using System.Collections.Generic; + +namespace Solana.Unity.Programs.Models.TokenProgram +{ + /// + /// Represents a Multi Signature Account in Solana. + /// + public class MultiSignatureAccount + { + /// + /// The maximum number of signers. + /// + public const int MaxSigners = 11; + + /// + /// The layout of the structure. + /// + public static class Layout + { + /// + /// The length of the structure. + /// + public const int Length = 355; + + /// + /// The offset at which the number of signers required value begins. + /// + public const int MinimumSignersOffset = 0; + + /// + /// The offset at which the number of valid signers value begins. + /// + public const int NumberSignersOffset = 1; + + /// + /// The offset at which the is initialized value begins. + /// + public const int IsInitializedOffset = 2; + + /// + /// The offset at which the array with signers' public keys begins. + /// + public const int SignersOffset = 3; + } + + /// + /// Number of signers required + /// + public byte MinimumSigners; + + /// + /// Number of valid signers + /// + public byte NumberSigners; + + /// + /// Whether the account has been initialized + /// + public bool IsInitialized; + + /// + /// Signer public keys + /// + public List Signers; + + /// + /// Deserialize the given data into the structure. + /// + /// The data. + /// The structure. + public static MultiSignatureAccount Deserialize(ReadOnlySpan data) + { + if (data.Length != Layout.Length) + throw new ArgumentException($"{nameof(data)} has wrong size. Expected {Layout.Length} bytes, actual {data.Length} bytes."); + + List signers = new(); + + for(int i= 0; i < MaxSigners; i++) + { + var signer = data.GetPubKey(Layout.SignersOffset + i * PublicKey.PublicKeyLength); + if (signer != SystemProgram.ProgramIdKey) + signers.Add(signer); + } + + return new MultiSignatureAccount + { + MinimumSigners = data.GetU8(Layout.MinimumSignersOffset), + NumberSigners = data.GetU8(Layout.NumberSignersOffset), + IsInitialized = data.GetBool(Layout.IsInitializedOffset), + Signers = signers + }; + } + } +} diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/TokenProgram/MultiSignatureAccount.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/TokenProgram/MultiSignatureAccount.cs.meta new file mode 100644 index 0000000..873c05c --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/TokenProgram/MultiSignatureAccount.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 19b71635173d88b46a33c741ebefcf66 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/TokenProgram/TokenAccount.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/TokenProgram/TokenAccount.cs new file mode 100644 index 0000000..c699880 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/TokenProgram/TokenAccount.cs @@ -0,0 +1,172 @@ +using Solana.Unity.Programs.Utilities; +using Solana.Unity.Wallet; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Solana.Unity.Programs.Models.TokenProgram +{ + /// + /// Represents a token account. + /// + public class TokenAccount + { + /// + /// Represents the state of a token account. + /// + public enum AccountState : byte + { + /// + /// Account is uninitialized. + /// + Uninitialized, + /// + /// Account is initialized. The owner and/or delegate may operate the account. + /// + Initialized, + /// + /// The account is frozen. The owner and delegate can't operate the account. + /// + Frozen + } + /// + /// The layout of the structure. + /// + public static class Layout + { + /// + /// The length of the structure. + /// + public const int Length = 165; + + /// + /// The offset at which the token mint pubkey begins. + /// + public const int MintOffset = 0; + + /// + /// The offset at which the owner pubkey begins. + /// + public const int OwnerOffset = 32; + + /// + /// The offset at which the amount value begins. + /// + public const int AmountOffset = 64; + + /// + /// The offset at which the delegate pubkey COption value begins. + /// + public const int DelegateOptionOffset = 72; + + /// + /// The offset at which the delegate pubkey value begins. + /// + public const int DelegateOffset = 76; + + /// + /// The offset at which the state value begins. + /// + public const int StateOffset = 108; + + /// + /// The offset at which the IsNative COption begins. + /// + public const int IsNativeOptionOffset = 109; + + /// + /// The offset at which the IsNative begins. + /// + public const int IsNativeOffset = 113; + + /// + /// The offset at which the delegaterrd amount value begins. + /// + public const int DelegatedAmountOffset = 121; + + /// + /// The offset at which the close authority pubkey COption begins. + /// + public const int CloseAuthorityOptionOffset = 129; + + /// + /// The offset at which the close authority pubkey begins. + /// + public const int CloseAuthorityOffset = 133; + } + + /// + /// The token mint. + /// + public PublicKey Mint { get; set; } + + /// + /// The owner of the token account. + /// + public PublicKey Owner { get; set; } + + /// + /// The amount of tokens this account holds. + /// + public ulong Amount { get; set; } + + /// + /// Delegate address. If Delegate has value then DelegatedAmount represents the amount authorized by the delegate. + /// + public PublicKey Delegate { get; set; } + + /// + /// Represents the state of this account. + /// + public AccountState State { get; set; } + + /// + /// If IsNative has value, this is a native token and the value logs the rent-exempt reserve. + /// + public ulong? IsNative { get; set; } + + /// + /// The amount delegated. + /// + public ulong DelegatedAmount { get; set; } + + /// + /// Optional authority to close the account. + /// + public PublicKey CloseAuthority { get; set; } + + /// + /// Deserialize the given data into the structure. + /// + /// The data. + /// The structure. + public static TokenAccount Deserialize(ReadOnlySpan data) + { + if (data.Length != Layout.Length) + throw new ArgumentException($"{nameof(data)} has wrong size. Expected {Layout.Length} bytes, actual {data.Length} bytes."); + + var res = new TokenAccount + { + Mint = data.GetPubKey(Layout.MintOffset), + Owner = data.GetPubKey(Layout.OwnerOffset), + Amount = data.GetU64(Layout.AmountOffset), + + State = (AccountState)data.GetU8(Layout.StateOffset), + DelegatedAmount = data.GetU64(Layout.DelegatedAmountOffset), + }; + + if (data.GetU32(Layout.DelegateOptionOffset) == 1) + res.Delegate = data.GetPubKey(Layout.DelegateOffset); + + if (data.GetU32(Layout.IsNativeOptionOffset) == 1) + res.IsNative = data.GetU64(Layout.IsNativeOffset); + + if (data.GetU32(Layout.CloseAuthorityOptionOffset) == 1) + res.CloseAuthority = data.GetPubKey(Layout.CloseAuthorityOffset); + + return res; + } + } +} diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/TokenProgram/TokenAccount.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/TokenProgram/TokenAccount.cs.meta new file mode 100644 index 0000000..5270816 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/TokenProgram/TokenAccount.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dc5280354afc6d84eb27642140b19d24 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/TokenProgram/TokenMint.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/TokenProgram/TokenMint.cs new file mode 100644 index 0000000..f160384 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/TokenProgram/TokenMint.cs @@ -0,0 +1,109 @@ +using Solana.Unity.Wallet; +using System; +using Solana.Unity.Programs.Utilities; + +namespace Solana.Unity.Programs.Models.TokenProgram +{ + /// + /// Represents a token mint account. + /// + public class TokenMint + { + /// + /// The layout of the structure. + /// + public static class Layout + { + /// + /// The length of the structure. + /// + public const int Length = 82; + + /// + /// The offset at which the mint authority COption begins. + /// + public const int MintAuthorityOptionOffset = 0; + + /// + /// The offset at which the mint authority pubkey value begins. + /// + public const int MintAuthorityOffset = 4; + + /// + /// The offset at which the supply value begins. + /// + public const int SupplyOffset = 36; + + /// + /// The offset at which the decimals value begins. + /// + public const int DecimalsOffset = 44; + + /// + /// The offset at which the is initialized value begins. + /// + public const int IsInitializedOffset = 45; + + /// + /// The offset at which the freeze authority COption begins. + /// + public const int FreezeAuthorityOptionOffset = 46; + + /// + /// The offset at which the freeze authority pubkey value begins. + /// + public const int FreezeAuthorityOffset = 50; + } + + /// + /// Optional authority to mint new tokens. If no mint authority is present, no new tokens can be issued. + /// + public PublicKey MintAuthority { get; set; } + + /// + /// Total supply of tokens. + /// + public ulong Supply { get; set; } + + /// + /// Number of base 10 digits to the right of the decimal polace. + /// + public byte Decimals { get; set; } + + /// + /// Whether or not the account has been initialized. + /// + public bool IsInitialized { get; set; } + + /// + /// Optional authority to freeze token accounts. + /// + public PublicKey FreezeAuthority { get; set; } + + + /// + /// Deserialize the given data into the structure. + /// + /// The data. + /// The structure. + public static TokenMint Deserialize(ReadOnlySpan data) + { + if (data.Length != Layout.Length) + throw new ArgumentException($"{nameof(data)} has wrong size. Expected {Layout.Length} bytes, actual {data.Length} bytes."); + + var res = new TokenMint(); + + if (data.GetU32(Layout.MintAuthorityOptionOffset) == 1) + res.MintAuthority = data.GetPubKey(Layout.MintAuthorityOffset); + + res.Supply = data.GetU64(Layout.SupplyOffset); + res.Decimals = data.GetU8(Layout.DecimalsOffset); + res.IsInitialized= data.GetBool(Layout.IsInitializedOffset); + + if (data.GetU32(Layout.FreezeAuthorityOptionOffset) == 1) + res.FreezeAuthority = data.GetPubKey(Layout.FreezeAuthorityOptionOffset); + + return res; + } + } +} diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/TokenProgram/TokenMint.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/TokenProgram/TokenMint.cs.meta new file mode 100644 index 0000000..a48736a --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Models/TokenProgram/TokenMint.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 92fa01c22e79bfe45ac6387224006579 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/NameServiceInstructions.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/NameServiceInstructions.cs new file mode 100644 index 0000000..4a02fdb --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/NameServiceInstructions.cs @@ -0,0 +1,74 @@ +// unset + +using System.Collections.Generic; + +namespace Solana.Unity.Programs +{ + /// + /// Represents the instruction types for the along with a friendly name so as not to use reflection. + /// + /// For more information see: + /// https://spl.solana.com/name-service + /// + /// + internal static class NameServiceInstructions + { + /// + /// Represents the user-friendly names for the instruction types for the . + /// + internal static readonly Dictionary Names = new() + { + { Values.Create, "Create Name Record" }, + { Values.Update, "Update Name Record" }, + { Values.Transfer, "Transfer Name Record" }, + { Values.Delete, "Delete Name Record" } + }; + + /// + /// Represents the instruction types for the . + /// + internal enum Values : byte + { + /// + /// Create a name record. + /// + /// The address of the name record (account #1) is a program-derived address with the following + /// seeds to ensure uniqueness: + /// + /// + /// + /// SHA256(HASH_PREFIX, name) + /// + /// + /// Account class (account #3) + /// + /// + /// Parent name record address (account #4) + /// + /// + /// + /// If this is a child record, the parent record's owner must approve by signing (account #5) + /// + /// + Create = 0, + + /// + /// Update the data in a name record. + /// + Update = 1, + + /// + /// Transfer ownership of a name record. + /// + Transfer = 2, + + /// + /// Delete a name record. + /// + /// Any lamports left in the account will be transferred to the refund account. + /// + /// + Delete = 3, + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/NameServiceInstructions.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/NameServiceInstructions.cs.meta new file mode 100644 index 0000000..ac44f0a --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/NameServiceInstructions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8c09795a91def384f81bb457778d3747 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/NameServiceProgram.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/NameServiceProgram.cs new file mode 100644 index 0000000..9e9a05a --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/NameServiceProgram.cs @@ -0,0 +1,421 @@ +using Solana.Unity.Programs.Utilities; +using Solana.Unity.Rpc.Models; +using Solana.Unity.Rpc.Utilities; +using Solana.Unity.Wallet; +using System; +using System.Collections.Generic; +using System.Security.Cryptography; +using System.Text; + +namespace Solana.Unity.Programs +{ + /// + /// Implements the Token Program methods. + /// + /// For more information see: https://spl.solana.com/name-service + /// + /// + public static class NameServiceProgram + { + /// + /// The hash prefix used to calculate the SHA256 of the name record to be created. + /// + private static readonly string HashPrefix = "SPL Name Service"; + + /// + /// The program's name. + /// + private const string ProgramName = "Name Service Program"; + + /// + /// The offset at which the value which defines the instruction method begins. + /// + private const int MethodOffset = 0; + + /// + /// The public key of the Name Service Program. + /// + public static readonly PublicKey ProgramIdKey = new("namesLPneVptA9Z5rqUDD9tMTWEJwofgaYwp8cawRkX"); + + /// + /// The space to be used when creating the name record. + /// + public const int NameAccountSize = 1000; + + /// + /// Initialize a new transaction instruction to create a name record. + /// + /// The name to use. + /// The account of the payer. + /// The public key of the name owner. + /// The public key of the account of the name class. + /// The public key of the parent name. + /// The public key of the account of the parent name owner. + /// The space to assign to the account. + /// The amount of lamports the account needs to be rate exempt. + /// The transaction instruction. + /// Thrown when it was not possible to derive a program address for the account. + public static TransactionInstruction CreateNameRegistry( + PublicKey name, PublicKey payer, PublicKey nameOwner, ulong lamports, uint space, PublicKey nameClass = null, + PublicKey parentNameOwner = null, PublicKey parentName = null) + { + byte[] hashedName = ComputeHashedName(name.Key); + PublicKey nameAccountKey = DeriveNameAccountKey(hashedName, nameClass, parentName); + if (nameAccountKey == null) throw new Exception("could not derive an address for the name account"); + return CreateNameRegistryInstruction( + nameAccountKey, nameOwner, payer, hashedName, lamports, space, nameClass, parentNameOwner, parentName); + } + + /// + /// Gets the hash for the given value with the attached hash prefix. + /// + /// The name to hash attach the prefix and hash. + /// The hash as bytes. + public static byte[] ComputeHashedName(string name) + { + string prefixedName = HashPrefix + name; + byte[] fullNameBytes = Encoding.UTF8.GetBytes(prefixedName); + + using SHA256 sha = SHA256.Create(); + return sha.ComputeHash(fullNameBytes, 0, fullNameBytes.Length); + } + + /// + /// Get's the program derived address for the name. + /// + /// The hash of the name with the name service hash prefix. + /// The account of the name class. + /// The public key of the parent name. + /// The program derived address for the name if it could be found, otherwise null. + public static PublicKey DeriveNameAccountKey(ReadOnlySpan hashedName, PublicKey nameClass = null, PublicKey parentName = null) + { + byte[] nameClassKey = new byte[32]; + byte[] parentNameKeyBytes = new byte[32]; + + if (nameClass != null) nameClassKey = nameClass.KeyBytes; + if (parentName != null) parentNameKeyBytes = parentName.KeyBytes; + + bool success = PublicKey.TryFindProgramAddress( + new List { hashedName.ToArray(), nameClassKey, parentNameKeyBytes }, ProgramIdKey, out PublicKey nameAccountPublicKey, out _); + return nameAccountPublicKey; + } + + + /// + /// Initialize a new transaction instruction to create a name record. + /// + /// The public key of the name record. + /// The public key of the name owner. + /// The public key of the account of the payer. + /// The hash of the name with the hash prefix. + /// The space to assign to the account. + /// The amount of lamports the account needs to be rate exempt. + /// The public key of the account of the name class. + /// The public key of the parent name. + /// The public key of the account of the parent name owner. + /// The transaction instruction. + private static TransactionInstruction CreateNameRegistryInstruction( + PublicKey nameKey, PublicKey nameOwner, PublicKey payer, ReadOnlySpan hashedName, ulong lamports, uint space, + PublicKey nameClass = null, PublicKey parentNameOwner = null, PublicKey parentName = null) + { + List keys = new() + { + AccountMeta.ReadOnly(SystemProgram.ProgramIdKey, false), + AccountMeta.Writable(payer, true), + AccountMeta.Writable(nameKey, false), + AccountMeta.ReadOnly(nameOwner, false), + nameClass != null + ? AccountMeta.ReadOnly(nameClass, true) + : AccountMeta.ReadOnly(new PublicKey(new byte[32]), false), + parentName != null + ? AccountMeta.ReadOnly(parentName, false) + : AccountMeta.ReadOnly(new PublicKey(new byte[32]), false) + }; + if (parentNameOwner != null) keys.Add(AccountMeta.ReadOnly(parentNameOwner, false)); + return new TransactionInstruction + { + Keys = keys, + ProgramId = ProgramIdKey.KeyBytes, + Data = EncodeCreateNameRegistryData(hashedName, lamports, space) + }; + } + + /// + /// Initialize a new transaction instruction to update the data of a name record. + /// + /// If the name class was defined upon name record creation then the name class parameter must be passed. + /// + /// + /// The public key of the name record. + /// The offset at which to update the data. + /// The data to insert. + /// The public key of the name owner. + /// The public key of the account of the name class. + /// The transaction instruction. + public static TransactionInstruction UpdateNameRegistry( + PublicKey nameKey, uint offset, ReadOnlySpan data, PublicKey nameOwner = null, PublicKey nameClass = null) + { + List keys = new() { AccountMeta.Writable(nameKey, false) }; + + if (nameOwner != null) + keys.Add(AccountMeta.ReadOnly(nameOwner, true)); + + if (nameClass != null) + keys.Add(AccountMeta.ReadOnly(nameClass, true)); + + return new TransactionInstruction + { + Keys = keys, + ProgramId = ProgramIdKey.KeyBytes, + Data = EncodeUpdateNameRegistryData(offset, data) + }; + } + + /// + /// Initialize a new transaction instruction to transfer ownership of a name record. + /// + /// If the name class was defined upon name record creation then the name class parameter must be passed. + /// + /// + /// The public key of the name record. + /// The public key of the new name owner. + /// The public key of the name owner. + /// The public key of the account of the name class. + /// The transaction instruction. + public static TransactionInstruction TransferNameRegistry( + PublicKey nameKey, PublicKey newOwner, PublicKey nameOwner, PublicKey nameClass = null) + { + List keys = new() + { + AccountMeta.Writable(nameKey, false), + AccountMeta.ReadOnly(nameOwner, true), + }; + + if (nameClass != null) + keys.Add(AccountMeta.ReadOnly(nameClass, true)); + + return new TransactionInstruction + { + Keys = keys, + ProgramId = ProgramIdKey.KeyBytes, + Data = EncodeTransferNameRegistryData(newOwner) + }; + } + + /// + /// Initialize a new transaction instruction to delete a name record. + /// + /// The public key of the name record. + /// The public key of the name owner. + /// The public key of the refund account. + /// The transaction instruction. + public static TransactionInstruction DeleteNameRegistry( + PublicKey nameKey, PublicKey nameOwner, PublicKey refundPublicKey) + { + List keys = new() + { + AccountMeta.Writable(nameKey, false), + AccountMeta.ReadOnly(nameOwner, true), + AccountMeta.Writable(refundPublicKey, false) + }; + + return new TransactionInstruction + { + Keys = keys, + ProgramId = ProgramIdKey.KeyBytes, + Data = EncodeDeleteNameRegistryData() + }; + } + + /// + /// Encode the instruction data to be used with the instruction. + /// + /// The hashed name for the record. + /// The number of lamports for rent exemption. + /// The space for the account. + /// The transaction instruction data. + private static byte[] EncodeCreateNameRegistryData(ReadOnlySpan hashedName, ulong lamports, uint space) + { + byte[] methodBuffer = new byte[17 + hashedName.Length]; + + methodBuffer.WriteU8((byte)NameServiceInstructions.Values.Create, MethodOffset); + methodBuffer.WriteU32((uint)hashedName.Length, 1); + methodBuffer.WriteSpan(hashedName, 5); + methodBuffer.WriteU64(lamports, 5 + hashedName.Length); + methodBuffer.WriteU32(space, 13 + hashedName.Length); + + return methodBuffer; + } + + /// + /// Encode the instruction data to be used with the instruction. + /// + /// The offset at which to update the data. + /// The data to insert. + /// The transaction instruction data. + private static byte[] EncodeUpdateNameRegistryData(uint offset, ReadOnlySpan data) + { + byte[] methodBuffer = new byte[data.Length + 5]; + + methodBuffer.WriteU8((byte)NameServiceInstructions.Values.Update, MethodOffset); + methodBuffer.WriteU32(offset, 1); + methodBuffer.WriteSpan(data, 5); + + return methodBuffer; + } + + /// + /// Encode the instruction data to be used with the instruction. + /// + /// The public key of the account to transfer ownership to. + /// The transaction instruction data. + private static byte[] EncodeTransferNameRegistryData(PublicKey newOwner) + { + byte[] methodBuffer = new byte[33]; + + methodBuffer.WriteU8((byte)NameServiceInstructions.Values.Transfer, MethodOffset); + methodBuffer.WritePubKey(newOwner, 1); + + return methodBuffer; + } + + /// + /// Encode the instruction data to be used with the instruction. + /// + /// The transaction instruction data. + private static byte[] EncodeDeleteNameRegistryData() + { + byte[] methodBuffer = new byte[1]; + + methodBuffer.WriteU8((byte)NameServiceInstructions.Values.Delete, MethodOffset); + + return methodBuffer; + } + + /// + /// Decodes the instruction instruction data for the method + /// + /// The decoded instruction to add data to. + /// The instruction data to decode. + /// The account keys present in the transaction. + /// The indices of the account keys for the instruction as they appear in the transaction. + private static void DecodeCreateNameRegistry(DecodedInstruction decodedInstruction, ReadOnlySpan data, + IList keys, byte[] keyIndices) + { + decodedInstruction.Values.Add("Payer", keys[keyIndices[1]]); + decodedInstruction.Values.Add("Name Account", keys[keyIndices[2]]); + decodedInstruction.Values.Add("Name Owner", keys[keyIndices[3]]); + + if (keyIndices.Length >= 5) + decodedInstruction.Values.Add("Name Class", keys[keyIndices[4]]); + + if (keyIndices.Length >= 6) + decodedInstruction.Values.Add("Parent Name", keys[keyIndices[5]]); + + if (keyIndices.Length >= 7) + decodedInstruction.Values.Add("Parent Name Owner", keys[keyIndices[6]]); + + uint nameLength = data.GetU32(1); + decodedInstruction.Values.Add("Hashed Name Length", nameLength); + decodedInstruction.Values.Add("Hashed Name", data.GetSpan(5, (int)nameLength).ToArray()); + decodedInstruction.Values.Add("Lamports", data.GetU64(5 + (int)nameLength)); + decodedInstruction.Values.Add("Space", data.GetU32(13 + (int)nameLength)); + } + + /// + /// Decodes the instruction instruction data for the method + /// + /// The decoded instruction to add data to. + /// The instruction data to decode. + /// The account keys present in the transaction. + /// The indices of the account keys for the instruction as they appear in the transaction. + private static void DecodeUpdateNameRegistry(DecodedInstruction decodedInstruction, ReadOnlySpan data, + IList keys, byte[] keyIndices) + { + decodedInstruction.Values.Add("Name Account", keys[keyIndices[0]]); + + if (keyIndices.Length == 2) + decodedInstruction.Values.Add("Name Owner", keys[keyIndices[1]]); + + if (keyIndices.Length == 3) + decodedInstruction.Values.Add("Name Class", keys[keyIndices[2]]); + + decodedInstruction.Values.Add("Offset", data.GetU32(1)); + decodedInstruction.Values.Add("Data", data[5..].ToArray()); + } + + /// + /// Decodes the instruction instruction data for the method + /// + /// The decoded instruction to add data to. + /// The instruction data to decode. + /// The account keys present in the transaction. + /// The indices of the account keys for the instruction as they appear in the transaction. + private static void DecodeTransferNameRegistry(DecodedInstruction decodedInstruction, ReadOnlySpan data, + IList keys, byte[] keyIndices) + { + decodedInstruction.Values.Add("Name Account", keys[keyIndices[0]]); + decodedInstruction.Values.Add("Name Owner", keys[keyIndices[1]]); + + if (keyIndices.Length == 3) + decodedInstruction.Values.Add("Name Class", keys[keyIndices[2]]); + + decodedInstruction.Values.Add("New Owner", data.GetPubKey(1)); + } + + /// + /// Decodes the instruction instruction data for the method + /// + /// The decoded instruction to add data to. + /// The account keys present in the transaction. + /// The indices of the account keys for the instruction as they appear in the transaction. + private static void DecodeDeleteNameRegistry(DecodedInstruction decodedInstruction, IList keys, + byte[] keyIndices) + { + decodedInstruction.Values.Add("Name Account", keys[keyIndices[0]]); + decodedInstruction.Values.Add("Name Owner", keys[keyIndices[1]]); + decodedInstruction.Values.Add("Refund Account", keys[keyIndices[2]]); + } + + /// + /// Decodes an instruction created by the System Program. + /// + /// The instruction data to decode. + /// The account keys present in the transaction. + /// The indices of the account keys for the instruction as they appear in the transaction. + /// A decoded instruction. + public static DecodedInstruction Decode(ReadOnlySpan data, IList keys, byte[] keyIndices) + { + byte instruction = data.GetU8(MethodOffset); + NameServiceInstructions.Values instructionValue = + (NameServiceInstructions.Values)Enum.Parse(typeof(NameServiceInstructions.Values), instruction.ToString()); + + DecodedInstruction decodedInstruction = new() + { + PublicKey = ProgramIdKey, + InstructionName = NameServiceInstructions.Names[instructionValue], + ProgramName = ProgramName, + Values = new Dictionary(), + InnerInstructions = new List() + }; + + switch (instructionValue) + { + case NameServiceInstructions.Values.Create: + DecodeCreateNameRegistry(decodedInstruction, data, keys, keyIndices); + break; + case NameServiceInstructions.Values.Update: + DecodeUpdateNameRegistry(decodedInstruction, data, keys, keyIndices); + break; + case NameServiceInstructions.Values.Transfer: + DecodeTransferNameRegistry(decodedInstruction, data, keys, keyIndices); + break; + case NameServiceInstructions.Values.Delete: + DecodeDeleteNameRegistry(decodedInstruction, keys, keyIndices); + break; + } + + return decodedInstruction; + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/NameServiceProgram.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/NameServiceProgram.cs.meta new file mode 100644 index 0000000..a8fba5c --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/NameServiceProgram.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0c9e638f978faf2459a861b2b3eefb5d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/SharedMemoryProgram.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/SharedMemoryProgram.cs new file mode 100644 index 0000000..24f7776 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/SharedMemoryProgram.cs @@ -0,0 +1,86 @@ +using Solana.Unity.Programs.Utilities; +using Solana.Unity.Rpc.Models; +using Solana.Unity.Wallet; +using Solana.Unity.Wallet.Utilities; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Solana.Unity.Programs +{ + /// + /// Helper class for the Shared Memory Program. + /// + /// Used to write data to a given account data. + /// Note: this program, as of writing this, was inactive in some clusters. + /// + /// + public static class SharedMemoryProgram + { + /// + /// The address of the Shared Memory Program. + /// + public static readonly PublicKey ProgramIdKey = new("shmem4EWT2sPdVGvTZCzXXRAURL9G5vpPxNwSeKhHUL"); + + /// + /// The program's name. + /// + private const string ProgramName = "Shared Memory Program"; + + /// + /// The instruction's name. + /// + private const string InstructionName = "Write"; + + /// + /// Creates an instruction used to interact with the Shared memory program. + /// This instruction writes data to a given program starting at a specific offset. + /// + /// The public key of the account where the data is to be written. + /// The data to be written. + /// The offset of the account data to write to. + /// The encoded that interacts with the shared memory program.. + public static TransactionInstruction Write(PublicKey dest, ReadOnlySpan payload, ulong offset) + { + List keys = new() + { + AccountMeta.Writable(dest, false) + }; + + byte[] transactionData = new byte[payload.Length + 8]; + + transactionData.WriteU64(offset, 0); + transactionData.WriteSpan(payload, 8); + + return new TransactionInstruction + { + ProgramId = ProgramIdKey.KeyBytes, + Keys = keys, + Data = transactionData + }; + } + + /// + /// Decodes an instruction created by the System Program. + /// + /// The instruction data to decode. + /// The account keys present in the transaction. + /// The indices of the account keys for the instruction as they appear in the transaction. + /// A decoded instruction. + public static DecodedInstruction Decode(ReadOnlySpan data, IList keys, byte[] keyIndices) + { + return new DecodedInstruction() + { + PublicKey = ProgramIdKey, + InstructionName = InstructionName, + ProgramName = ProgramName, + Values = new Dictionary() + { + {"Offset", data.GetU64(0)}, + {"Data", data[8..].ToArray()} + }, + InnerInstructions = new List() + }; + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/SharedMemoryProgram.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/SharedMemoryProgram.cs.meta new file mode 100644 index 0000000..7ef98d6 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/SharedMemoryProgram.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 02bf80f2ddf786b47af205b274603a30 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Solana.Unity.Programs.csproj.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Solana.Unity.Programs.csproj.meta new file mode 100644 index 0000000..0ba9f56 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Solana.Unity.Programs.csproj.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: ad41e1b41a6f164489e007fefd6056d7 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Stake.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Stake.meta new file mode 100644 index 0000000..d9e352f --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Stake.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: dacad9b0ecdbca54cb5f812c0b7c927e +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Stake/StakeProgram.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Stake/StakeProgram.cs new file mode 100644 index 0000000..3114e88 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Stake/StakeProgram.cs @@ -0,0 +1,475 @@ +using Solana.Unity.Programs.Utilities; +using Solana.Unity.Programs.Models.Stake; +using Solana.Unity.Rpc.Models; +using Solana.Unity.Wallet; +using System; +using System.Collections.Generic; +using static Solana.Unity.Programs.Models.Stake.State; + +namespace Solana.Unity.Programs +{ + /// + /// Implements the Stake Program methods. + /// + /// For more information see: + /// https://docs.rs/solana-program/latest/src/solana_program/stake/instruction.rs.html + /// https://github.com/solana-labs/solana/blob/master/sdk/program/src/stake/instruction.rs + /// + /// + public static class StakeProgram + { + /// + /// The public key of the Stake Program. + /// + public static readonly PublicKey ProgramIdKey = new("Stake11111111111111111111111111111111111111"); + /// + /// Stake Account Layout Size + /// + public const int StakeAccountDataSize = 200; + /// + /// Stake Config ID + /// + public static readonly PublicKey ConfigKey = new("StakeConfig11111111111111111111111111111111"); + /// + /// The program's name. + /// + private const string ProgramName = "Stake Program"; + /// + /// Initialize a stake with lockup and authorization information + /// + /// Uninitialized stake account + /// Carries pubkeys that must sign staker transactions and withdrawer transactions + /// Carries information about withdrawal restrictions + /// The transaction instruction. + public static TransactionInstruction Initialize(PublicKey stakePubkey, State.Authorized authorized, State.Lockup lockup) + { + List keys = new() + { + AccountMeta.Writable(stakePubkey, false), + AccountMeta.ReadOnly(SysVars.RentKey,false) + }; + return new TransactionInstruction + { + ProgramId = ProgramIdKey.KeyBytes, + Keys = keys, + Data = StakeProgramData.EncodeInitializeData(authorized,lockup) + }; + } + /// + /// Authorize a key to manage stake or withdrawal + /// + /// Stake account to be updated + /// Stake or withdraw authority + /// Key to be authorized by the transaction + /// Type of authority + /// Lockup authority pubkey if updated withdrawer before lockup expiration + /// The transaction instruction. + public static TransactionInstruction Authorize(PublicKey stakePubkey, PublicKey authorizedPubkey, PublicKey newAuthorizedPubkey, State.StakeAuthorize stakeAuthorize, PublicKey custodianPubkey) + { + List keys = new() + { + AccountMeta.Writable(stakePubkey,false), + AccountMeta.ReadOnly(SysVars.ClockKey,false), + AccountMeta.ReadOnly(authorizedPubkey,true) + }; + if (custodianPubkey != null) + { + keys.Add(AccountMeta.ReadOnly(custodianPubkey, true)); + } + return new TransactionInstruction + { + ProgramId = ProgramIdKey.KeyBytes, + Keys = keys, + Data = StakeProgramData.EncodeAuthorizeData(newAuthorizedPubkey, stakeAuthorize) + }; + } + /// + /// Delegate a stake to a particular vote account + /// + /// Initialized stake account to be delegated + /// Stake authority + /// Vote account to which this stake will be delegated + /// The transaction instruction. + public static TransactionInstruction DelegateStake(PublicKey stakePubkey, PublicKey authorizedPubkey, PublicKey votePubkey) + { + List keys = new() + { + AccountMeta.Writable(stakePubkey, false), + AccountMeta.ReadOnly(votePubkey, false), + AccountMeta.ReadOnly(SysVars.ClockKey, false), + AccountMeta.ReadOnly(SysVars.StakeHistoryKey, false), + AccountMeta.ReadOnly(ConfigKey, false), + AccountMeta.ReadOnly(authorizedPubkey, true) + }; + return new TransactionInstruction + { + ProgramId = ProgramIdKey.KeyBytes, + Keys = keys, + Data=StakeProgramData.EncodeDelegateStakeData() + }; + } + /// + /// Split u64 tokens and stake off a stake account into another stake account. + /// + /// Stake account to be split; must be in the Initialized or Stake state + /// Stake authority + /// Amount to be split + /// Uninitialized stake account that will take the split-off amount + /// The transaction instruction. + public static TransactionInstruction Split(PublicKey stakePubkey, PublicKey authorizedPubkey, ulong lamports, PublicKey splitStakePubkey) + { + List keys = new() + { + AccountMeta.Writable(stakePubkey, false), + AccountMeta.Writable(splitStakePubkey, false), + AccountMeta.ReadOnly(authorizedPubkey, true) + }; + return new TransactionInstruction + { + ProgramId = ProgramIdKey.KeyBytes, + Keys = keys, + Data = StakeProgramData.EncodeSplitData(lamports) + }; + } + /// + /// Withdraw unstaked lamports from the stake account + /// + /// Stake account from which to withdraw + /// Withdraw authority + /// Recipient account + /// Amount to withdraw + /// Lockup authority + /// The transaction instruction. + public static TransactionInstruction Withdraw(PublicKey stakePubkey, PublicKey withdrawerPubkey, PublicKey toPubkey, ulong lamports, PublicKey custodianPubkey) + { + List keys = new() + { + AccountMeta.Writable(stakePubkey, false), + AccountMeta.Writable(toPubkey, false), + AccountMeta.ReadOnly(SysVars.ClockKey, false), + AccountMeta.ReadOnly(SysVars.StakeHistoryKey,false), + AccountMeta.ReadOnly(withdrawerPubkey,true) + }; + if (custodianPubkey != null) + { + keys.Add(AccountMeta.ReadOnly(custodianPubkey, true)); + } + return new TransactionInstruction + { + ProgramId = ProgramIdKey.KeyBytes, + Keys = keys, + Data = StakeProgramData.EncodeWithdrawData(lamports) + }; + } + /// + /// Deactivates the stake in the account + /// + /// Delegated stake account + /// Stake authority + /// The transaction instruction. + public static TransactionInstruction Deactivate(PublicKey stakePubkey, PublicKey authorizedPubkey) + { + List keys = new() + { + AccountMeta.Writable(stakePubkey, false), + AccountMeta.ReadOnly(SysVars.ClockKey, false), + AccountMeta.ReadOnly(authorizedPubkey, true) + }; + return new TransactionInstruction + { + ProgramId = ProgramIdKey.KeyBytes, + Keys = keys, + Data = StakeProgramData.EncodeDeactivateData() + }; + } + /// + /// Set stake lockup + /// If a lockup is not active, the withdraw authority may set a new lockup + /// If a lockup is active, the lockup custodian may update the lockup parameters + /// + /// Initialized stake account + /// Lockup information + /// Lockup authority or withdraw authority + /// The transaction instruction. + public static TransactionInstruction SetLockup(PublicKey stakePubkey, State.Lockup lockup, PublicKey custodianPubkey) + { + List keys = new() + { + AccountMeta.Writable(stakePubkey, false), + AccountMeta.ReadOnly(custodianPubkey, true) + }; + return new TransactionInstruction + { + ProgramId = ProgramIdKey.KeyBytes, + Keys = keys, + Data = StakeProgramData.EncodeSetLockupData(lockup) + }; + } + /// + /// Merge two stake accounts. + /// + /// Both accounts must have identical lockup and authority keys. A merge + /// is possible between two stakes in the following states with no additional + /// conditions: + /// + /// * two deactivated stakes + /// * an inactive stake into an activating stake during its activation epoch + /// + /// For the following cases, the voter pubkey and vote credits observed must match: + /// + /// * two activated stakes + /// * two activating accounts that share an activation epoch, during the activation epoch + /// + /// All other combinations of stake states will fail to merge, including all + /// "transient" states, where a stake is activating or deactivating with a + /// non-zero effective stake. + /// + /// + /// Destination stake account for the merge + /// Source stake account for merge, will be drained + /// Stake authority + /// The transaction instruction. + public static TransactionInstruction Merge(PublicKey destinationStakePubkey, PublicKey sourceStakePubkey, PublicKey authorizedPubkey) + { + List keys = new() + { + AccountMeta.Writable(destinationStakePubkey, false), + AccountMeta.Writable(sourceStakePubkey, false), + AccountMeta.ReadOnly(SysVars.ClockKey, false), + AccountMeta.ReadOnly(SysVars.StakeHistoryKey, false), + AccountMeta.ReadOnly(authorizedPubkey, true) + }; + return new TransactionInstruction + { + ProgramId = ProgramIdKey.KeyBytes, + Keys = keys, + Data = StakeProgramData.EncodeMergeData() + }; + } + /// + /// Authorize a key to manage stake or withdrawal with a derived key + /// + /// Stake account to be updated + /// Base key of stake or withdraw authority + /// Seed + /// Authority owner + /// Pubkey authorized by the transaction + /// Type of stake authority + /// Custodian pubkey + /// The transaction instruction. + public static TransactionInstruction AuthorizeWithSeed(PublicKey stakePubkey, PublicKey authorityBase, string authoritySeed, PublicKey authorityOwner, PublicKey newAuthorizedPubkey, State.StakeAuthorize stakeAuthorize, PublicKey custodianPubkey) + { + List keys = new() + { + AccountMeta.Writable(stakePubkey, false), + AccountMeta.ReadOnly(authorityBase, true), + AccountMeta.ReadOnly(SysVars.ClockKey, false) + }; + if (custodianPubkey != null && custodianPubkey != authorityBase) + { + keys.Add(AccountMeta.ReadOnly(custodianPubkey, true)); + } + return new TransactionInstruction + { + ProgramId = ProgramIdKey.KeyBytes, + Keys = keys, + Data = StakeProgramData.EncodeAuthorizeWithSeedData(authoritySeed, newAuthorizedPubkey, stakeAuthorize, authorityOwner) + }; + } + /// + /// Initialize a stake with authorization information + /// + /// This instruction is similar to `Initialize` except that the withdraw authority + /// must be a signer, and no lockup is applied to the account. + /// + /// + /// Uninitialized stake account + /// Carries pubkeys that must sign staker transactions and withdrawer transactions + /// The transaction instruction. + public static TransactionInstruction InitializeChecked(PublicKey stakePubkey, State.Authorized authorized) + { + List keys = new() + { + AccountMeta.Writable(stakePubkey, false), + AccountMeta.ReadOnly(SysVars.RentKey, false), + AccountMeta.ReadOnly(authorized.Staker, false), + AccountMeta.ReadOnly(authorized.Withdrawer,true) + }; + return new TransactionInstruction + { + ProgramId = ProgramIdKey.KeyBytes, + Keys = keys, + Data = StakeProgramData.EncodeInitializeCheckedData() + }; + } + /// + /// Authorize a key to manage stake or withdrawal + /// + /// This instruction behaves like `Authorize` with the additional requirement that the new + /// stake or withdraw authority must also be a signer. + /// + /// + /// Stake account to be updated + /// Stake or withdraw authority + /// Key to be authorized by the transaction + /// Type of authority + /// Lockup authority pubkey if updated withdrawer before lockup expiration + /// The transaction instruction. + public static TransactionInstruction AuthorizeChecked(PublicKey stakePubkey, PublicKey authorizedPubkey, PublicKey newAuthorizedPubkey, State.StakeAuthorize stakeAuthorize, PublicKey custodianPubkey) + { + List keys = new() + { + AccountMeta.Writable(stakePubkey, false), + AccountMeta.ReadOnly(SysVars.ClockKey, false), + AccountMeta.ReadOnly(authorizedPubkey, true), + AccountMeta.ReadOnly(newAuthorizedPubkey,true) + }; + if (custodianPubkey != null) + { + keys.Add(AccountMeta.ReadOnly(custodianPubkey, true)); + } + return new TransactionInstruction + { + ProgramId = ProgramIdKey.KeyBytes, + Keys = keys, + Data = StakeProgramData.EncodeAuthorizeCheckedData(stakeAuthorize) + }; + } + /// + /// Authorize a key to manage stake or withdrawal with a derived key + /// + /// This instruction behaves like `AuthorizeWithSeed` with the additional requirement that + /// the new stake or withdraw authority must also be a signer. + /// + /// + /// Stake account to be updated + /// Base key of stake or withdraw authority + /// Seed + /// Authority owner + /// Key to be authorized by the transaction + /// Type of stake authority + /// Custodian pubkey + /// The transaction instruction. + public static TransactionInstruction AuthorizeCheckedWithSeed(PublicKey stakePubkey, PublicKey authorityBase, string authoritySeed, PublicKey authorityOwner, PublicKey newAuthorizedPubkey, State.StakeAuthorize stakeAuthorize, PublicKey custodianPubkey) + { + List keys = new() + { + AccountMeta.Writable(stakePubkey, false), + AccountMeta.ReadOnly(authorityBase, true), + AccountMeta.ReadOnly(SysVars.ClockKey, false), + AccountMeta.ReadOnly(newAuthorizedPubkey, true) + }; + if (custodianPubkey != null) + { + keys.Add(AccountMeta.ReadOnly(custodianPubkey, true)); + } + return new TransactionInstruction + { + ProgramId = ProgramIdKey.KeyBytes, + Keys = keys, + Data = StakeProgramData.EncodeAuthorizeCheckedWithSeedData(authoritySeed, authorityOwner, stakeAuthorize) + }; + } + /// + /// This instruction behaves like `SetLockup` with the additional requirement that + /// the new lockup authority also be a signer. + /// + /// If a lockup is not active, the withdraw authority may set a new lockup + /// If a lockup is active, the lockup custodian may update the lockup parameters + /// + /// + /// Initialized stake account + /// Lockup information + /// Lockup authority or withdraw authority + /// The transaction instruction. + public static TransactionInstruction SetLockupChecked(PublicKey stakePubkey, State.Lockup lockup, PublicKey custodianPubkey) + { + List keys = new() + { + AccountMeta.Writable(stakePubkey, false), + AccountMeta.ReadOnly(custodianPubkey, true) + }; + if (lockup.Custodian != null) + { + keys.Add(AccountMeta.ReadOnly(lockup.Custodian, true)); + } + State.Lockup lockupChecked = new State.Lockup + { + UnixTimestamp = lockup.UnixTimestamp, + Epoch = lockup.Epoch + }; + return new TransactionInstruction + { + ProgramId = ProgramIdKey.KeyBytes, + Keys = keys, + Data = StakeProgramData.EncodeSetLockupCheckedData(lockupChecked) + }; + } + /// + /// Decodes an instruction created by the Stake Program. + /// + /// The instruction data to decode. + /// The account keys present in the transaction. + /// The indices of the account keys for the instruction as they appear in the transaction. + /// A decoded instruction. + public static DecodedInstruction Decode(ReadOnlySpan data, IList keys, byte[] keyIndices) + { + uint instruction = data.GetU32(StakeProgramData.MethodOffset); + StakeProgramInstructions.Values instructionValue = + (StakeProgramInstructions.Values)Enum.Parse(typeof(StakeProgramInstructions.Values), instruction.ToString()); + + DecodedInstruction decodedInstruction = new () + { + PublicKey = ProgramIdKey, + InstructionName = StakeProgramInstructions.Names[instructionValue], + ProgramName = ProgramName, + Values = new Dictionary(){}, + InnerInstructions = new List() + }; + + switch (instructionValue) + { + case StakeProgramInstructions.Values.Initialize: + StakeProgramData.DecodeInitializeData(decodedInstruction, data, keys, keyIndices); + break; + case StakeProgramInstructions.Values.Authorize: + StakeProgramData.DecodeAuthorizeData(decodedInstruction, data, keys, keyIndices); + break; + case StakeProgramInstructions.Values.DelegateStake: + StakeProgramData.DecodeDelegateStakeData(decodedInstruction, data, keys, keyIndices); + break; + case StakeProgramInstructions.Values.Split: + StakeProgramData.DecodeSplitStakeData(decodedInstruction, data, keys, keyIndices); + break; + case StakeProgramInstructions.Values.Withdraw: + StakeProgramData.DecodeWithdrawStakeData(decodedInstruction, data, keys, keyIndices); + break; + case StakeProgramInstructions.Values.Deactivate: + StakeProgramData.DecodeDeactivateStakeData(decodedInstruction, data, keys, keyIndices); + break; + case StakeProgramInstructions.Values.SetLockup: + StakeProgramData.DecodeSetLockupStakeData(decodedInstruction, data, keys, keyIndices); + break; + case StakeProgramInstructions.Values.Merge: + StakeProgramData.DecodeMergeStakeData(decodedInstruction, data, keys, keyIndices); + break; + case StakeProgramInstructions.Values.AuthorizeWithSeed: + StakeProgramData.DecodeAuthorizeWithSeedStakeData(decodedInstruction, data, keys, keyIndices); + break; + case StakeProgramInstructions.Values.InitializeChecked: + StakeProgramData.DecodeInitializeCheckedStakeData(decodedInstruction, data, keys, keyIndices); + break; + case StakeProgramInstructions.Values.AuthorizeChecked: + StakeProgramData.DecodeAuthorizeCheckedStakeData(decodedInstruction, data, keys, keyIndices); + break; + case StakeProgramInstructions.Values.AuthorizeCheckedWithSeed: + StakeProgramData.DecodeAuthorizeCheckedWithSeedStakeData(decodedInstruction, data, keys, keyIndices); + break; + case StakeProgramInstructions.Values.SetLockupChecked: + StakeProgramData.DecodeSetLockupCheckedStakeData(decodedInstruction, data, keys, keyIndices); + break; + } + return decodedInstruction; + } + } +} diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Stake/StakeProgram.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Stake/StakeProgram.cs.meta new file mode 100644 index 0000000..339b4c0 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Stake/StakeProgram.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1b0122c284445354c9e2ad6a5d56dcbc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Stake/StakeProgramData.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Stake/StakeProgramData.cs new file mode 100644 index 0000000..c2ef8b7 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Stake/StakeProgramData.cs @@ -0,0 +1,267 @@ +using Solana.Unity.Programs.Models.Stake; +using Solana.Unity.Programs.Utilities; +using Solana.Unity.Wallet; +using System; +using System.Collections.Generic; +using static Solana.Unity.Programs.Models.Stake.State; + +namespace Solana.Unity.Programs +{ + /// + /// Implements the stake program data encodings. + /// + internal static class StakeProgramData + { + /// + /// The offset at which the value which defines the program method begins. + /// + internal const int MethodOffset = 0; + + static public string ToReadableByteArray(byte[] bytes) + { + return string.Join(", ", bytes); + } + + /// + /// Summary text here + /// + internal static byte[] EncodeInitializeData(State.Authorized authorized, State.Lockup lockup) + { + byte[] data = new byte[116]; + + data.WriteU32((uint)StakeProgramInstructions.Values.Initialize, MethodOffset); + data.WritePubKey(authorized.Staker, 4); + data.WritePubKey(authorized.Withdrawer, 36); + data.WriteS64(lockup.UnixTimestamp, 68); + data.WriteU64(lockup.Epoch, 76); + data.WritePubKey(lockup.Custodian, 84); + + var k = ToReadableByteArray(data); + + return data; + } + internal static byte[] EncodeAuthorizeData(PublicKey newAuthorizedPubkey, State.StakeAuthorize stakeAuthorize) + { + byte[] data = new byte[68]; + + data.WriteU32((uint)StakeProgramInstructions.Values.Authorize, MethodOffset); + data.WritePubKey(newAuthorizedPubkey, 4); + data.WriteU32((uint)stakeAuthorize, 36); + + return data; + } + + internal static byte[] EncodeDelegateStakeData() + { + byte[] data = new byte[4]; + + data.WriteU32((uint)StakeProgramInstructions.Values.DelegateStake, MethodOffset); + return data; + } + internal static byte[] EncodeSplitData(ulong lamports) + { + byte[] data = new byte[12]; + + data.WriteU32((uint)StakeProgramInstructions.Values.Split, MethodOffset); + data.WriteU64(lamports, 4); + return data; + } + + internal static byte[] EncodeWithdrawData(ulong lamports) + { + byte[] data = new byte[12]; + + data.WriteU32((uint)StakeProgramInstructions.Values.Withdraw, MethodOffset); + data.WriteU64(lamports, 4); + return data; + } + + internal static byte[] EncodeDeactivateData() + { + byte[] data = new byte[4]; + + data.WriteU32((uint)StakeProgramInstructions.Values.Deactivate, MethodOffset); + return data; + } + + internal static byte[] EncodeSetLockupData(State.Lockup lockup) + { + byte[] data = new byte[52]; + + data.WriteU32((uint)StakeProgramInstructions.Values.SetLockup, MethodOffset); + data.WriteS64(lockup.UnixTimestamp, 4); + data.WriteU64(lockup.Epoch, 12); + data.WritePubKey(lockup.Custodian, 20); + return data; + } + + internal static byte[] EncodeMergeData() + { + byte[] data = new byte[4]; + + data.WriteU32((uint)StakeProgramInstructions.Values.Merge, MethodOffset); + return data; + } + + internal static byte[] EncodeAuthorizeWithSeedData(string authoritySeed, PublicKey newAuthorizedPubKey, State.StakeAuthorize stakeAuthorize, PublicKey authorityOwner) + { + byte[] encodedSeed = Serialization.EncodeBincodeString(authoritySeed); + byte[] data = new byte[72 + encodedSeed.Length]; + + data.WriteU32((uint)StakeProgramInstructions.Values.AuthorizeWithSeed, MethodOffset); + data.WritePubKey(newAuthorizedPubKey, 4); + data.WriteU32((uint)stakeAuthorize, 36); + data.WriteSpan(encodedSeed, 40); + data.WritePubKey(authorityOwner, 40 + encodedSeed.Length); + return data; + } + + internal static byte[] EncodeInitializeCheckedData() + { + byte[] data = new byte[4]; + + data.WriteU32((uint)StakeProgramInstructions.Values.InitializeChecked, MethodOffset); + return data; + } + + internal static byte[] EncodeAuthorizeCheckedData(State.StakeAuthorize stakeAuthorize) + { + byte[] data = new byte[8]; + + data.WriteU32((uint)StakeProgramInstructions.Values.Authorize, MethodOffset); + data.WriteU32((uint)stakeAuthorize, 4); + return data; + } + + internal static byte[] EncodeAuthorizeCheckedWithSeedData(string authoritySeed, PublicKey authorityOwner, State.StakeAuthorize stakeAuthorize) + { + byte[] encodedSeed = Serialization.EncodeBincodeString(authoritySeed); + byte[] data = new byte[40 + encodedSeed.Length]; + + data.WriteU32((uint)StakeProgramInstructions.Values.AuthorizeCheckedWithSeed, MethodOffset); + data.WriteSpan(encodedSeed, 4); + data.WriteU32((uint)stakeAuthorize, 4 + encodedSeed.Length); + data.WritePubKey(authorityOwner, 8 + encodedSeed.Length); + return data; + } + internal static byte[] EncodeSetLockupCheckedData(State.Lockup lockup) + { + byte[] data = new byte[20]; + + data.WriteU32((uint)StakeProgramInstructions.Values.SetLockup, MethodOffset); + data.WriteS64(lockup.UnixTimestamp, 4); + data.WriteU64(lockup.Epoch, 12); + return data; + } + internal static void DecodeInitializeData(DecodedInstruction decodedInstruction, ReadOnlySpan data, IList keys, byte[] keyIndices) + { + decodedInstruction.Values.Add("Stake Account", keys[keyIndices[0]]); + decodedInstruction.Values.Add("Authorized Withdraw Account", data.GetPubKey(4)); + decodedInstruction.Values.Add("Authorized Stake Account", data.GetPubKey(36)); + decodedInstruction.Values.Add("Lockup Timestamp", data.GetS64(68)); + decodedInstruction.Values.Add("Lockup Epoch", data.GetU64(76)); + decodedInstruction.Values.Add("Lockup Custodian", data.GetPubKey(84)); + } + internal static void DecodeAuthorizeData(DecodedInstruction decodedInstruction, ReadOnlySpan data, IList keys, byte[] keyIndices) + { + decodedInstruction.Values.Add("Stake Account", keys[keyIndices[0]]); + decodedInstruction.Values.Add("Authorized Account", keys[keyIndices[2]]); + decodedInstruction.Values.Add("Custodian Account", keys[keyIndices[3]]); + decodedInstruction.Values.Add("New Authorized Account", data.GetPubKey(4)); + decodedInstruction.Values.Add("Stake Authorize", Enum.Parse(typeof(State.StakeAuthorize), data.GetU8(36).ToString())); + } + internal static void DecodeDelegateStakeData(DecodedInstruction decodedInstruction, ReadOnlySpan data, IList keys, byte[] keyIndices) + { + decodedInstruction.Values.Add("Stake Account", keys[keyIndices[0]]); + decodedInstruction.Values.Add("Vote Account", keys[keyIndices[1]]); + decodedInstruction.Values.Add("Authorized Account", keys[keyIndices[5]]); + } + internal static void DecodeSplitStakeData(DecodedInstruction decodedInstruction, ReadOnlySpan data, IList keys, byte[] keyIndices) + { + decodedInstruction.Values.Add("Stake Account", keys[keyIndices[0]]); + decodedInstruction.Values.Add("Split Stake Account", keys[keyIndices[1]]); + decodedInstruction.Values.Add("Authorized Account", keys[keyIndices[2]]); + decodedInstruction.Values.Add("Amount", data.GetU64(4)); + } + internal static void DecodeWithdrawStakeData(DecodedInstruction decodedInstruction, ReadOnlySpan data, IList keys, byte[] keyIndices) + { + decodedInstruction.Values.Add("Stake Account", keys[keyIndices[0]]); + decodedInstruction.Values.Add("To Account", keys[keyIndices[1]]); + decodedInstruction.Values.Add("Withdraw Account", keys[keyIndices[4]]); + decodedInstruction.Values.Add("Custodian Account", keys[keyIndices[5]]); + decodedInstruction.Values.Add("Amount", data.GetU64(4)); + } + internal static void DecodeDeactivateStakeData(DecodedInstruction decodedInstruction, ReadOnlySpan data, IList keys, byte[] keyIndices) + { + decodedInstruction.Values.Add("Stake Account", keys[keyIndices[0]]); + decodedInstruction.Values.Add("Authorized Account", keys[keyIndices[2]]); + } + internal static void DecodeSetLockupStakeData(DecodedInstruction decodedInstruction, ReadOnlySpan data, IList keys, byte[] keyIndices) + { + decodedInstruction.Values.Add("Stake Account", keys[keyIndices[0]]); + decodedInstruction.Values.Add("Custodian Account", keys[keyIndices[1]]); + decodedInstruction.Values.Add("Lockup Timestamp", data.GetS64(4)); + decodedInstruction.Values.Add("Lockup Epoch", data.GetU64(12)); + decodedInstruction.Values.Add("Lockup Custodian", data.GetPubKey(20)); + } + internal static void DecodeMergeStakeData(DecodedInstruction decodedInstruction, + ReadOnlySpan data, + IList keys, + byte[] keyIndices) + { + decodedInstruction.Values.Add("Destination Stake Account", keys[keyIndices[0]]); + decodedInstruction.Values.Add("Source Stake Account", keys[keyIndices[1]]); + decodedInstruction.Values.Add("Authorized Account", keys[keyIndices[4]]); + } + internal static void DecodeAuthorizeWithSeedStakeData(DecodedInstruction decodedInstruction, ReadOnlySpan data, IList keys, byte[] keyIndices) + { + decodedInstruction.Values.Add("Stake Account", keys[keyIndices[0]]); + decodedInstruction.Values.Add("Authority Base Account", keys[keyIndices[1]]); + decodedInstruction.Values.Add("Custodian Account", keys[keyIndices[3]]); + decodedInstruction.Values.Add("New Authorized Account", data.GetPubKey(4)); + decodedInstruction.Values.Add("Stake Authorize", Enum.Parse(typeof(State.StakeAuthorize), data.GetU8(36).ToString())); + (string authoritySeed, int seedLength) = data.DecodeBincodeString(37); + decodedInstruction.Values.Add("Authority Seed", authoritySeed); + decodedInstruction.Values.Add("Authority Owner Account", data.GetPubKey(37 + seedLength)); + } + internal static void DecodeInitializeCheckedStakeData(DecodedInstruction decodedInstruction, + ReadOnlySpan data, + IList keys, + byte[] keyIndices) + { + decodedInstruction.Values.Add("Stake Account", keys[keyIndices[0]]); + decodedInstruction.Values.Add("Authorized Staker Account", keys[keyIndices[2]]); + decodedInstruction.Values.Add("Authorized Withdrawer Account", keys[keyIndices[3]]); + } + internal static void DecodeAuthorizeCheckedStakeData(DecodedInstruction decodedInstruction, + ReadOnlySpan data, + IList keys, + byte[] keyIndices) + { + decodedInstruction.Values.Add("Stake Account", keys[keyIndices[0]]); + decodedInstruction.Values.Add("Authorized Account", keys[keyIndices[2]]); + decodedInstruction.Values.Add("Custodian Account", keys[keyIndices[4]]); + decodedInstruction.Values.Add("New Authorized Account", keys[keyIndices[3]]); + decodedInstruction.Values.Add("Stake Authorize", Enum.Parse(typeof(State.StakeAuthorize), data.GetU8(4).ToString())); + } + internal static void DecodeAuthorizeCheckedWithSeedStakeData(DecodedInstruction decodedInstruction, ReadOnlySpan data, IList keys, byte[] keyIndices) + { + decodedInstruction.Values.Add("Stake Account", keys[keyIndices[0]]); + decodedInstruction.Values.Add("Authority Base Account", keys[keyIndices[1]]); + decodedInstruction.Values.Add("Custodian Account", keys[keyIndices[4]]); + decodedInstruction.Values.Add("New Authorized Account", keys[keyIndices[3]]); + decodedInstruction.Values.Add("Stake Authorize", Enum.Parse(typeof(State.StakeAuthorize), data.GetU8(4).ToString())); + (string authoritySeed, int seedLength) = data.DecodeBincodeString(5); + decodedInstruction.Values.Add("Authority Seed", authoritySeed); + decodedInstruction.Values.Add("Authority Owner Account", data.GetPubKey(5 + seedLength)); + } + internal static void DecodeSetLockupCheckedStakeData(DecodedInstruction decodedInstruction, ReadOnlySpan data, IList keys, byte[] keyIndices) + { + decodedInstruction.Values.Add("Stake Account", keys[keyIndices[0]]); + decodedInstruction.Values.Add("Custodian Account", keys[keyIndices[1]]); + decodedInstruction.Values.Add("Lockup Timestamp", data.GetS64(4)); + decodedInstruction.Values.Add("Lockup Epoch", data.GetU64(12)); + decodedInstruction.Values.Add("Lockup Custodian", keys[keyIndices[2]]); + } + } +} diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Stake/StakeProgramData.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Stake/StakeProgramData.cs.meta new file mode 100644 index 0000000..0bbcd35 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Stake/StakeProgramData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 41a32a2f6d979274e92edcfecaaf7596 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Stake/StakeProgramInstructions.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Stake/StakeProgramInstructions.cs new file mode 100644 index 0000000..056adf4 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Stake/StakeProgramInstructions.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Solana.Unity.Programs +{ + /// + /// Represents the instruction types for the ??? along with a friendly name so as not to use reflection ???. + /// + /// For more information see: + /// https://docs.solana.com/developing/runtime-facilities/programs#stake-program + /// https://docs.rs/solana-sdk/1.7.14/solana_sdk/stake/instruction/enum.StakeInstruction.html + /// + /// + internal static class StakeProgramInstructions + { + /// + /// Represents the user-friendly names for the instruction types for the . + /// + internal static readonly Dictionary Names = new() + { + { Values.Initialize, "Initialize" }, + { Values.Authorize, "Authorize" }, + { Values.DelegateStake, "Delegate Stake" }, + { Values.Split, "Split" }, + { Values.Withdraw, "Withdraw" }, + { Values.Deactivate, "Deactivate" }, + { Values.SetLockup, "Set Lockup" }, + { Values.Merge, "Merge" }, + { Values.AuthorizeWithSeed, "Authorize With Seed" }, + { Values.InitializeChecked, "Initialize Checked" }, + { Values.AuthorizeChecked, "Authorize Checked" }, + { Values.AuthorizeCheckedWithSeed, "Authorize Checked With Seed" }, + { Values.SetLockupChecked, "Set Lockup Checked"} + }; + + /// + /// Represents the instruction types for the . + /// + internal enum Values : byte + { + Initialize = 0, + Authorize = 1, + DelegateStake =2, + Split = 3, + Withdraw = 4, + Deactivate = 5, + SetLockup = 6, + Merge = 7, + AuthorizeWithSeed = 8, + InitializeChecked = 9, + AuthorizeChecked = 10, + AuthorizeCheckedWithSeed = 11, + SetLockupChecked = 12 + } + } +} diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Stake/StakeProgramInstructions.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Stake/StakeProgramInstructions.cs.meta new file mode 100644 index 0000000..498a9c7 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Stake/StakeProgramInstructions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 815999eadc6424c4da4745d1d35aa64e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Stake/State.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Stake/State.cs new file mode 100644 index 0000000..02a6700 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Stake/State.cs @@ -0,0 +1,119 @@ +using Solana.Unity.Wallet; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Solana.Unity.Programs.Models.Stake +{ + /// + /// Represents State Structs in Solana. + /// + public class State + { + /// + /// A public key pair passed as an Authorized struct with staking and withdrawing authorities + /// + public struct Authorized + { + /// The staking authority + public PublicKey Staker { get; set; } + /// The withdrawing authority + public PublicKey Withdrawer { get; set; } + } + /// + /// A structure containing the information for delegating a stake + /// + public struct Delegation + { + /// + /// to whom the stake is delegated + /// + public PublicKey VoterPubkey { get; set; } + /// + /// activated stake amount, set at delegate() time + /// + public ulong Stake { get; set; } + /// + /// epoch at which this stake was activated, std::Epoch::MAX if is a bootstrap stake + /// + public ulong ActivationEpoch { get; set; } + /// + /// epoch the stake was deactivated, std::Epoch::MAX if not deactivated + /// + public ulong DeactivationEpoch { get; set; } + /// + /// how much stake we can activate per-epoch as a fraction of currently effective stake + /// + public float WarmupCooldownRate { get; set; } + } + /// + /// A structure containing the information for setting Lockup information for a stake + /// + public struct Lockup + { + /// + /// UnixTimestamp at which this stake will allow withdrawal, unless the + /// transaction is signed by the custodian + /// + public Int64 UnixTimestamp { get; set; } + /// + /// epoch height at which this stake will allow withdrawal, unless the + /// transaction is signed by the custodian + /// + public ulong Epoch { get; set; } + /// + /// custodian signature on a transaction exempts the operation from + /// lockup constraints + /// + public PublicKey Custodian { get; set; } + } + /// + /// A structure containing metadata for a stake + /// + public struct Meta + { + /// + /// The Rent Exempt Reserve amount + /// + public ulong RentExemptReserve { get; set; } + /// + /// An Authorized struct + /// + public Authorized Authorized { get; set; } + /// + /// A Lockup struct + /// + public Lockup Lockup { get; set; } + } + /// + /// A structure containing information about a redeemed or delegated vote account stake + /// + public struct Stake + { + /// + /// A Delegation struct + /// + public Delegation Delegation { get; set; } + /// + /// credits observed is credits from vote account state when delegated or redeemed + /// + public ulong CreditsObserved { get; set; } + } + /// + /// An enum representing Authority type + /// + public enum StakeAuthorize : byte + { + /// + /// Is staker + /// + Staker = 0, + /// + /// Is withdrawer + /// + Withdrawer = 1 + } + } +} diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Stake/State.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Stake/State.cs.meta new file mode 100644 index 0000000..f082822 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Stake/State.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 75ecf4ae4093e9e4d9c221957695705c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/SysVars.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/SysVars.cs new file mode 100644 index 0000000..43a91b7 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/SysVars.cs @@ -0,0 +1,38 @@ +using Solana.Unity.Wallet; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Solana.Unity.Programs +{ + /// + /// Represents the System Variables + /// + public static class SysVars + { + /// + /// The public key of the Recent Block Hashes System Variable. + /// + public static readonly PublicKey + RecentBlockHashesKey = new("SysvarRecentB1ockHashes11111111111111111111"); + + /// + /// The public key of the Rent System Variable. + /// + public static readonly PublicKey RentKey = new("SysvarRent111111111111111111111111111111111"); + /// + /// The public key of the Clock System Variable. + /// + public static readonly PublicKey ClockKey = new("SysvarC1ock11111111111111111111111111111111"); + /// + /// The public key of the Stake History System Variable. + /// + public static readonly PublicKey StakeHistoryKey = new("SysvarStakeHistory1111111111111111111111111"); + /// + /// The public key of the Instruction Account Variable. + /// + public static readonly PublicKey InstructionAccount = new("Sysvar1nstructions1111111111111111111111111"); + } +} diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/SysVars.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/SysVars.cs.meta new file mode 100644 index 0000000..e3b4283 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/SysVars.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4841355b9456b604f90742b68ddcf39c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/SystemProgram.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/SystemProgram.cs new file mode 100644 index 0000000..8ff5aa6 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/SystemProgram.cs @@ -0,0 +1,393 @@ +using Solana.Unity.Programs.Utilities; +using Solana.Unity.Rpc.Builders; +using Solana.Unity.Rpc.Models; +using Solana.Unity.Wallet; +using Solana.Unity.Wallet.Utilities; +using System; +using System.Collections.Generic; + +namespace Solana.Unity.Programs +{ + /// + /// Implements the System Program methods. + /// + /// For more information see: + /// https://docs.solana.com/developing/runtime-facilities/programs#system-program + /// https://docs.rs/solana-sdk/1.7.0/solana_sdk/system_instruction/enum.SystemInstruction.html + /// + /// + public static class SystemProgram + { + /// + /// The public key of the System Program. + /// + public static readonly PublicKey ProgramIdKey = new("11111111111111111111111111111111"); + + /// + /// The program's name. + /// + private const string ProgramName = "System Program"; + + /// + /// Initialize a new transaction instruction which interacts with the System Program to create a new account. + /// + /// The public key of the account from which the lamports will be transferred. + /// The public key of the account to which the lamports will be transferred. + /// The amount of lamports to transfer. + /// Number of bytes of memory to allocate for the account. + /// The program id of the account. + /// The transaction instruction. + public static TransactionInstruction CreateAccount( + PublicKey fromAccount, PublicKey newAccountPublicKey, ulong lamports, ulong space, PublicKey programId) + { + List keys = new() + { + AccountMeta.Writable(fromAccount, true), + AccountMeta.Writable(newAccountPublicKey, true) + }; + return new TransactionInstruction + { + ProgramId = ProgramIdKey.KeyBytes, + Keys = keys, + Data = SystemProgramData.EncodeCreateAccountData(programId, lamports, space) + }; + } + + /// + /// Initialize a new transaction instruction which interacts with the System Program to assign a new account owner. + /// + /// The public key of the account to assign a new owner. + /// The program id of the account to assign as owner. + /// The transaction instruction. + public static TransactionInstruction Assign(PublicKey account, PublicKey programId) + { + List keys = new() { AccountMeta.Writable(account, true) }; + + return new TransactionInstruction + { + ProgramId = ProgramIdKey.KeyBytes, + Keys = keys, + Data = SystemProgramData.EncodeAssignData(programId) + }; + } + + /// + /// Initialize a new transaction instruction which interacts with the System Program to transfer lamports. + /// + /// The public key of the account to transfer from. + /// The public key of the account to transfer to. + /// The amount of lamports. + /// The transaction instruction. + public static TransactionInstruction Transfer(PublicKey fromPublicKey, PublicKey toPublicKey, ulong lamports) + { + List keys = new() + { + AccountMeta.Writable(fromPublicKey, true), + AccountMeta.Writable(toPublicKey, false) + }; + return new TransactionInstruction + { + ProgramId = ProgramIdKey.KeyBytes, + Keys = keys, + Data = SystemProgramData.EncodeTransferData(lamports) + }; + } + + /// + /// Initialize a new transaction instruction which interacts with the System Program + /// to create a new account at an address derived from a base public key and a seed. + /// + /// The public key of the account to transfer from. + /// The public key of the account to transfer to. + /// The public key of the base account. + /// The seed to use to derive the account address. + /// The amount of lamports. + /// The number of bytes of space to allocate for the account. + /// The public key of the owner to use to derive the account address. + /// The transaction instruction. + public static TransactionInstruction CreateAccountWithSeed( + PublicKey fromPublicKey, PublicKey toPublicKey, PublicKey baseAccount, + string seed, ulong lamports, ulong space, PublicKey owner) + { + List keys = new() + { + AccountMeta.Writable(fromPublicKey, true), + AccountMeta.Writable(toPublicKey, false), + //AccountMeta.ReadOnly(baseAccount, true) + }; + if (baseAccount != fromPublicKey) + { + keys.Add(AccountMeta.ReadOnly(baseAccount, true)); + } + return new TransactionInstruction + { + ProgramId = ProgramIdKey.KeyBytes, + Keys = keys, + Data = SystemProgramData.EncodeCreateAccountWithSeedData( + baseAccount, owner, lamports, space, seed) + }; + } + + /// + /// Initialize a new transaction instruction which interacts with the System Program + /// to consume a stored nonce, replacing it with a successor. + /// + /// The public key of the nonce account. + /// The public key of the account authorized to perform nonce operations on the nonce account. + /// The transaction instruction. + public static TransactionInstruction AdvanceNonceAccount(PublicKey nonceAccountPublicKey, PublicKey authorized) + { + List keys = new() + { + AccountMeta.Writable(nonceAccountPublicKey, false), + AccountMeta.ReadOnly(SysVars.RecentBlockHashesKey, false), + AccountMeta.ReadOnly(authorized, true) + }; + return new TransactionInstruction + { + ProgramId = ProgramIdKey.KeyBytes, + Keys = keys, + Data = SystemProgramData.EncodeAdvanceNonceAccountData() + }; + } + + /// + /// Initialize a new transaction instruction which interacts with the System Program to withdraw funds from a nonce account. + /// + /// The public key of the nonce account. + /// The public key of the account to transfer to. + /// The public key of the account authorized to perform nonce operations on the nonce account. + /// The amount of lamports to transfer. + /// The transaction instruction. + public static TransactionInstruction WithdrawNonceAccount( + PublicKey nonceAccountPublicKey, PublicKey toPublicKey, PublicKey authorized, ulong lamports) + { + List keys = new() + { + AccountMeta.Writable(nonceAccountPublicKey, false), + AccountMeta.Writable(toPublicKey, false), + AccountMeta.ReadOnly(SysVars.RecentBlockHashesKey, false), + AccountMeta.ReadOnly(SysVars.RentKey, false), + AccountMeta.ReadOnly(authorized, true) + }; + return new TransactionInstruction + { + ProgramId = ProgramIdKey.KeyBytes, + Keys = keys, + Data = SystemProgramData.EncodeWithdrawNonceAccountData(lamports) + }; + } + + /// + /// Initialize a new transaction instruction which interacts with the System Program to drive the + /// state of an Uninitialized nonce account to Initialized, setting the nonce value. + /// + /// The public key of the nonce account. + /// The public key of the account authorized to perform nonce operations on the nonce account. + /// The transaction instruction. + public static TransactionInstruction InitializeNonceAccount(PublicKey nonceAccountPublicKey, PublicKey authorized) + { + List keys = new() + { + AccountMeta.Writable(nonceAccountPublicKey, false), + AccountMeta.ReadOnly(SysVars.RecentBlockHashesKey, false), + AccountMeta.ReadOnly(SysVars.RentKey, false), + }; + return new TransactionInstruction + { + ProgramId = ProgramIdKey.KeyBytes, + Keys = keys, + Data = SystemProgramData.EncodeInitializeNonceAccountData(authorized) + }; + } + + /// + /// Initialize a new transaction instruction which interacts with the System Program to change + /// the entity authorized to execute nonce instructions on the account. + /// + /// The public key of the nonce account. + /// The public key of the account authorized to perform nonce operations on the nonce account. + /// The public key of the new authority for the nonce operations. + /// The transaction instruction. + public static TransactionInstruction AuthorizeNonceAccount(PublicKey nonceAccountPublicKey, PublicKey authorized, PublicKey newAuthority) + { + List keys = new() + { + AccountMeta.Writable(nonceAccountPublicKey, false), + AccountMeta.ReadOnly(authorized, true), + }; + return new TransactionInstruction + { + ProgramId = ProgramIdKey.KeyBytes, + Keys = keys, + Data = SystemProgramData.EncodeAuthorizeNonceAccountData(newAuthority) + }; + } + + /// + /// Initialize a new transaction instruction which interacts with the System Program to + /// allocate space in a (possibly new) account without funding. + /// + /// The public key of the account to allocate space to. + /// The number of bytes of space to allocate. + /// The transaction instruction. + public static TransactionInstruction Allocate(PublicKey account, ulong space) + { + List keys = new() + { + AccountMeta.Writable(account, true) + }; + return new TransactionInstruction + { + ProgramId = ProgramIdKey.KeyBytes, + Keys = keys, + Data = SystemProgramData.EncodeAllocateData(space) + }; + } + + /// + /// Initialize a new transaction instruction which interacts with the System Program to + /// allocate space for and assign an account at an address derived from a base public key and a seed. + /// + /// The public key of the account to allocate space to. + /// The public key of the base account. + /// The seed to use to derive the account address. + /// The number of bytes of space to allocate. + /// The public key of the owner to use to derive the account address. + /// The transaction instruction. + public static TransactionInstruction AllocateWithSeed( + PublicKey account, PublicKey baseAccount, string seed, ulong space, PublicKey owner) + { + List keys = new() + { + AccountMeta.Writable(account, false), + AccountMeta.ReadOnly(baseAccount, true) + }; + return new TransactionInstruction + { + ProgramId = ProgramIdKey.KeyBytes, + Keys = keys, + Data = SystemProgramData.EncodeAllocateWithSeedData(baseAccount, owner, space, seed) + }; + } + + /// + /// Initialize a new transaction instruction which interacts with the System Program to + /// assign an account to a program based on a seed. + /// + /// The public key of the account to assign to. + /// The public key of the base account. + /// The seed to use to derive the account address. + /// The public key of the owner to use to derive the account address. + /// The transaction instruction. + public static TransactionInstruction AssignWithSeed( + PublicKey account, PublicKey baseAccount, string seed, PublicKey owner) + { + List keys = new() + { + AccountMeta.Writable(account, false), + AccountMeta.ReadOnly(baseAccount, true) + }; + return new TransactionInstruction + { + ProgramId = ProgramIdKey.KeyBytes, + Keys = keys, + Data = SystemProgramData.EncodeAssignWithSeedData(baseAccount, seed, owner) + }; + } + + /// + /// Initialize a new transaction instruction which interacts with the System Program to + /// transfer lamports from a derived address. + /// + /// The public key of the account to transfer from. + /// The public key of the base account. + /// The seed to use to derive the funding account address. + /// The public key of the owner to use to derive the funding account address. + /// The account to transfer to. + /// The amount of lamports to transfer. + /// The transaction instruction. + public static TransactionInstruction TransferWithSeed( + PublicKey fromPublicKey, PublicKey fromBaseAccount, string seed, PublicKey fromOwner, + PublicKey toPublicKey, ulong lamports) + { + List keys = new() + { + AccountMeta.Writable(fromPublicKey, false), + AccountMeta.ReadOnly(fromBaseAccount, true), + AccountMeta.ReadOnly(toPublicKey, false) + }; + return new TransactionInstruction + { + ProgramId = ProgramIdKey.KeyBytes, + Keys = keys, + Data = SystemProgramData.EncodeTransferWithSeedData(fromOwner, seed, lamports) + }; + } + + /// + /// Decodes an instruction created by the System Program. + /// + /// The instruction data to decode. + /// The account keys present in the transaction. + /// The indices of the account keys for the instruction as they appear in the transaction. + /// A decoded instruction. + public static DecodedInstruction Decode(ReadOnlySpan data, IList keys, byte[] keyIndices) + { + uint instruction = data.GetU32(SystemProgramData.MethodOffset); + SystemProgramInstructions.Values instructionValue = + (SystemProgramInstructions.Values)Enum.Parse(typeof(SystemProgramInstructions.Values), instruction.ToString()); + + DecodedInstruction decodedInstruction = new() + { + PublicKey = ProgramIdKey, + InstructionName = SystemProgramInstructions.Names[instructionValue], + ProgramName = ProgramName, + Values = new Dictionary(), + InnerInstructions = new List() + }; + + switch (instructionValue) + { + case SystemProgramInstructions.Values.CreateAccount: + SystemProgramData.DecodeCreateAccountData(decodedInstruction, data, keys, keyIndices); + break; + case SystemProgramInstructions.Values.Assign: + SystemProgramData.DecodeAssignData(decodedInstruction, data, keys, keyIndices); + break; + case SystemProgramInstructions.Values.Transfer: + SystemProgramData.DecodeTransferData(decodedInstruction, data, keys, keyIndices); + break; + case SystemProgramInstructions.Values.CreateAccountWithSeed: + SystemProgramData.DecodeCreateAccountWithSeedData(decodedInstruction, data, keys, keyIndices); + break; + case SystemProgramInstructions.Values.AdvanceNonceAccount: + SystemProgramData.DecodeAdvanceNonceAccountData(decodedInstruction, keys, keyIndices); + break; + case SystemProgramInstructions.Values.WithdrawNonceAccount: + SystemProgramData.DecodeWithdrawNonceAccountData(decodedInstruction, data, keys, keyIndices); + break; + case SystemProgramInstructions.Values.InitializeNonceAccount: + SystemProgramData.DecodeInitializeNonceAccountData(decodedInstruction, data, keys, keyIndices); + break; + case SystemProgramInstructions.Values.AuthorizeNonceAccount: + SystemProgramData.DecodeAuthorizeNonceAccountData(decodedInstruction, data, keys, keyIndices); + break; + case SystemProgramInstructions.Values.Allocate: + SystemProgramData.DecodeAllocateData(decodedInstruction, data, keys, keyIndices); + break; + case SystemProgramInstructions.Values.AllocateWithSeed: + SystemProgramData.DecodeAllocateWithSeedData(decodedInstruction, data, keys, keyIndices); + break; + case SystemProgramInstructions.Values.AssignWithSeed: + SystemProgramData.DecodeAssignWithSeedData(decodedInstruction, data, keys, keyIndices); + break; + case SystemProgramInstructions.Values.TransferWithSeed: + SystemProgramData.DecodeTransferWithSeedData(decodedInstruction, data, keys, keyIndices); + break; + } + + return decodedInstruction; + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/SystemProgram.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/SystemProgram.cs.meta new file mode 100644 index 0000000..c56195f --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/SystemProgram.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 906bd08b914a0a2408ce6f68828a8fe1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/SystemProgramData.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/SystemProgramData.cs new file mode 100644 index 0000000..a121ce6 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/SystemProgramData.cs @@ -0,0 +1,423 @@ +using Solana.Unity.Programs.Utilities; +using Solana.Unity.Wallet; +using System; +using System.Collections.Generic; + +namespace Solana.Unity.Programs +{ + /// + /// Implements the system program data encodings. + /// + internal static class SystemProgramData + { + /// + /// The offset at which the value which defines the program method begins. + /// + internal const int MethodOffset = 0; + + /// + /// Encode transaction instruction data for the method. + /// + /// The public key of the owner program account. + /// The number of lamports to fund the account. + /// The space to be allocated to the account. + /// The transaction instruction data. + internal static byte[] EncodeCreateAccountData(PublicKey owner, ulong lamports, ulong space) + { + byte[] data = new byte[52]; + + data.WriteU32((uint)SystemProgramInstructions.Values.CreateAccount, MethodOffset); + data.WriteU64(lamports, 4); + data.WriteU64(space, 12); + data.WritePubKey(owner, 20); + + return data; + } + + /// + /// Encode transaction instruction data for the method. + /// + /// The program id to set as the account owner. + /// The transaction instruction data. + internal static byte[] EncodeAssignData(PublicKey programId) + { + byte[] data = new byte[36]; + + data.WriteU32((uint)SystemProgramInstructions.Values.Assign, MethodOffset); + data.WritePubKey(programId, 4); + + return data; + } + + /// + /// Encode transaction instruction data for the method. + /// + /// The number of lamports to fund the account. + /// The transaction instruction data. + internal static byte[] EncodeTransferData(ulong lamports) + { + byte[] data = new byte[12]; + + data.WriteU32((uint)SystemProgramInstructions.Values.Transfer, MethodOffset); + data.WriteU64(lamports, 4); + + return data; + } + + /// + /// Encode transaction instruction data for the method. + /// + /// The public key of the base account used to derive the account address. + /// The public key of the owner program account address. + /// Number of lamports to transfer to the new account. + /// Number of bytes of memory to allocate. + /// Seed to use to derive the account address. + /// The transaction instruction data. + internal static byte[] EncodeCreateAccountWithSeedData( + PublicKey baseAccount, PublicKey owner, ulong lamports, ulong space, string seed) + { + byte[] encodedSeed = Serialization.EncodeBincodeString(seed); + byte[] data = new byte[84 + encodedSeed.Length]; + + data.WriteU32((uint)SystemProgramInstructions.Values.CreateAccountWithSeed, MethodOffset); + data.WritePubKey(baseAccount, 4); + data.WriteSpan(encodedSeed, 36); + data.WriteU64(lamports, 36 + encodedSeed.Length); + data.WriteU64(space, 44 + encodedSeed.Length); + data.WritePubKey(owner, 52 + encodedSeed.Length); + return data; + } + static public string ToReadableByteArray(byte[] bytes) + { + return string.Join(", ", bytes); + } + /// + /// Encode transaction instruction data for the method. + /// + /// The transaction instruction data. + internal static byte[] EncodeAdvanceNonceAccountData() + { + byte[] data = new byte[4]; + + data.WriteU32((uint)SystemProgramInstructions.Values.AdvanceNonceAccount, MethodOffset); + + return data; + } + + /// + /// Encode transaction instruction data for the method. + /// + /// + /// The transaction instruction data. + internal static byte[] EncodeWithdrawNonceAccountData(ulong lamports) + { + byte[] data = new byte[12]; + + data.WriteU32((uint)SystemProgramInstructions.Values.WithdrawNonceAccount, MethodOffset); + data.WriteU64(lamports, 4); + + return data; + } + + /// + /// Encode transaction instruction data for the method. + /// + /// The public key of the entity authorized to execute nonce instructions on the account. + /// The transaction instruction data. + internal static byte[] EncodeInitializeNonceAccountData(PublicKey authorized) + { + byte[] data = new byte[36]; + + data.WriteU32((uint)SystemProgramInstructions.Values.InitializeNonceAccount, MethodOffset); + data.WritePubKey(authorized, 4); + + return data; + } + + /// + /// Encode transaction instruction data for the method. + /// + /// The public key of the entity authorized to execute nonce instructions on the account. + /// The transaction instruction data. + internal static byte[] EncodeAuthorizeNonceAccountData(PublicKey authorized) + { + byte[] data = new byte[36]; + + data.WriteU32((uint)SystemProgramInstructions.Values.AuthorizeNonceAccount, MethodOffset); + data.WritePubKey(authorized, 4); + + return data; + } + + /// + /// Encode transaction instruction data for the method. + /// + /// Number of bytes of memory to allocate. + /// The transaction instruction data. + internal static byte[] EncodeAllocateData(ulong space) + { + byte[] data = new byte[12]; + + data.WriteU32((uint)SystemProgramInstructions.Values.Allocate, MethodOffset); + data.WriteU64(space, 4); + + return data; + } + + /// + /// Encode transaction instruction data for the method. + /// + /// The public key of the base account. + /// Number of bytes of memory to allocate. + /// Owner to use to derive the funding account address. + /// Seed to use to derive the funding account address. + /// The transaction instruction data. + internal static byte[] EncodeAllocateWithSeedData( + PublicKey baseAccount, PublicKey owner, ulong space, string seed) + { + byte[] encodedSeed = Serialization.EncodeBincodeString(seed); + byte[] data = new byte[76 + encodedSeed.Length]; + + data.WriteU32((uint)SystemProgramInstructions.Values.AllocateWithSeed, MethodOffset); + data.WritePubKey(baseAccount, 4); + data.WriteSpan(encodedSeed, 36); + data.WriteU64(space, 36 + encodedSeed.Length); + data.WritePubKey(owner, 44 + encodedSeed.Length); + + return data; + } + + /// + /// Encode transaction instruction data for the method. + /// + /// The public key of the base account. + /// Seed to use to derive the account address. + /// The public key of the owner program account. + /// The transaction instruction data. + internal static byte[] EncodeAssignWithSeedData( + PublicKey baseAccount, string seed, PublicKey owner) + { + byte[] encodedSeed = Serialization.EncodeBincodeString(seed); + byte[] data = new byte[68 + encodedSeed.Length]; + + data.WriteU32((uint)SystemProgramInstructions.Values.AssignWithSeed, MethodOffset); + data.WritePubKey(baseAccount, 4); + data.WriteSpan(encodedSeed, 36); + data.WritePubKey(owner, 36 + encodedSeed.Length); + + return data; + } + + /// + /// Encode transaction instruction data for the method. + /// + /// Owner to use to derive the funding account address. + /// Seed to use to derive the funding account address. + /// Amount of lamports to transfer. + /// The transaction instruction data. + internal static byte[] EncodeTransferWithSeedData(PublicKey owner, string seed, ulong lamports) + { + byte[] encodedSeed = Serialization.EncodeBincodeString(seed); + byte[] data = new byte[44 + encodedSeed.Length]; + + data.WriteU32((uint)SystemProgramInstructions.Values.TransferWithSeed, MethodOffset); + data.WriteU64(lamports, 4); + data.WriteSpan(encodedSeed, 12); + data.WritePubKey(owner, 12 + encodedSeed.Length); + + return data; + } + + /// + /// Decodes the instruction instruction data for the method + /// + /// The decoded instruction to add data to. + /// The instruction data to decode. + /// The account keys present in the transaction. + /// The indices of the account keys for the instruction as they appear in the transaction. + internal static void DecodeCreateAccountData(DecodedInstruction decodedInstruction, ReadOnlySpan data, + IList keys, byte[] keyIndices) + { + decodedInstruction.Values.Add("Owner Account", keys[keyIndices[0]]); + decodedInstruction.Values.Add("New Account", keys[keyIndices[1]]); + decodedInstruction.Values.Add("Amount", data.GetU64(4)); + decodedInstruction.Values.Add("Space", data.GetU64(12)); + } + + /// + /// Decodes the instruction instruction data for the method + /// + /// The decoded instruction to add data to. + /// The instruction data to decode. + /// The account keys present in the transaction. + /// The indices of the account keys for the instruction as they appear in the transaction. + internal static void DecodeAssignData(DecodedInstruction decodedInstruction, ReadOnlySpan data, + IList keys, byte[] keyIndices) + { + decodedInstruction.Values.Add("Account", keys[keyIndices[0]]); + decodedInstruction.Values.Add("Assign To", data.GetPubKey(4)); + } + + /// + /// Decodes the instruction instruction data for the method + /// + /// The decoded instruction to add data to. + /// The instruction data to decode. + /// The account keys present in the transaction. + /// The indices of the account keys for the instruction as they appear in the transaction. + internal static void DecodeTransferData(DecodedInstruction decodedInstruction, ReadOnlySpan data, + IList keys, byte[] keyIndices) + { + decodedInstruction.Values.Add("From Account", keys[keyIndices[0]]); + decodedInstruction.Values.Add("To Account", keys[keyIndices[1]]); + decodedInstruction.Values.Add("Amount", data.GetU64(4)); + } + + /// + /// Decodes the instruction instruction data for the method + /// + /// The decoded instruction to add data to. + /// The instruction data to decode. + /// The account keys present in the transaction. + /// The indices of the account keys for the instruction as they appear in the transaction. + internal static void DecodeCreateAccountWithSeedData(DecodedInstruction decodedInstruction, ReadOnlySpan data, + IList keys, byte[] keyIndices) + { + decodedInstruction.Values.Add("From Account", keys[keyIndices[0]]); + decodedInstruction.Values.Add("To Account", keys[keyIndices[1]]); + decodedInstruction.Values.Add("Base Account", data.GetPubKey(4)); + (string createSeed, int createLength) = data.DecodeBincodeString(36); + decodedInstruction.Values.Add("Seed", createSeed); + decodedInstruction.Values.Add("Amount", data.GetU64(36 + createLength)); + decodedInstruction.Values.Add("Space", data.GetU64(44 + createLength)); + decodedInstruction.Values.Add("Owner", data.GetPubKey(52 + createLength)); + } + + /// + /// Decodes the instruction instruction data for the method + /// + /// The decoded instruction to add data to. + /// The account keys present in the transaction. + /// The indices of the account keys for the instruction as they appear in the transaction. + internal static void DecodeAdvanceNonceAccountData(DecodedInstruction decodedInstruction, IList keys, + byte[] keyIndices) + { + decodedInstruction.Values.Add("Nonce Account", keys[keyIndices[0]]); + decodedInstruction.Values.Add("Authority", keys[keyIndices[2]]); + } + + /// + /// Decodes the instruction instruction data for the method + /// + /// The decoded instruction to add data to. + /// The instruction data to decode. + /// The account keys present in the transaction. + /// The indices of the account keys for the instruction as they appear in the transaction. + internal static void DecodeWithdrawNonceAccountData(DecodedInstruction decodedInstruction, ReadOnlySpan data, + IList keys, byte[] keyIndices) + { + decodedInstruction.Values.Add("Nonce Account", keys[keyIndices[0]]); + decodedInstruction.Values.Add("To Account", keys[keyIndices[1]]); + decodedInstruction.Values.Add("Authority", keys[keyIndices[4]]); + decodedInstruction.Values.Add("Amount", data.GetU64(4)); + } + + /// + /// Decodes the instruction instruction data for the method + /// + /// The decoded instruction to add data to. + /// The instruction data to decode. + /// The account keys present in the transaction. + /// The indices of the account keys for the instruction as they appear in the transaction. + internal static void DecodeInitializeNonceAccountData(DecodedInstruction decodedInstruction, ReadOnlySpan data, + IList keys, byte[] keyIndices) + { + decodedInstruction.Values.Add("Nonce Account", keys[keyIndices[0]]); + decodedInstruction.Values.Add("Authority", data.GetPubKey(4)); + } + + /// + /// Decodes the instruction instruction data for the method + /// + /// The decoded instruction to add data to. + /// The instruction data to decode. + /// The account keys present in the transaction. + /// The indices of the account keys for the instruction as they appear in the transaction. + internal static void DecodeAuthorizeNonceAccountData(DecodedInstruction decodedInstruction, ReadOnlySpan data, + IList keys, byte[] keyIndices) + { + decodedInstruction.Values.Add("Nonce Account", keys[keyIndices[0]]); + decodedInstruction.Values.Add("Current Authority", keys[keyIndices[1]]); + decodedInstruction.Values.Add("New Authority", data.GetPubKey(4)); + } + + /// + /// Decodes the instruction instruction data for the method + /// + /// The decoded instruction to add data to. + /// The instruction data to decode. + /// The account keys present in the transaction. + /// The indices of the account keys for the instruction as they appear in the transaction. + internal static void DecodeAllocateData(DecodedInstruction decodedInstruction, ReadOnlySpan data, + IList keys, byte[] keyIndices) + { + decodedInstruction.Values.Add("Account", keys[keyIndices[0]]); + decodedInstruction.Values.Add("Space", data.GetU64(4)); + } + + /// + /// Decodes the instruction instruction data for the method + /// + /// The decoded instruction to add data to. + /// The instruction data to decode. + /// The account keys present in the transaction. + /// The indices of the account keys for the instruction as they appear in the transaction. + internal static void DecodeAllocateWithSeedData(DecodedInstruction decodedInstruction, ReadOnlySpan data, + IList keys, byte[] keyIndices) + { + decodedInstruction.Values.Add("Account", keys[keyIndices[0]]); + decodedInstruction.Values.Add("Base Account", data.GetPubKey(4)); + (string allocateSeed, int allocateLength) = data.DecodeBincodeString(36); + decodedInstruction.Values.Add("Seed", allocateSeed); + decodedInstruction.Values.Add("Space", data.GetU64(36 + allocateLength)); + decodedInstruction.Values.Add("Owner", data.GetPubKey(44 + allocateLength)); + } + + /// + /// Decodes the instruction instruction data for the method + /// + /// The decoded instruction to add data to. + /// The instruction data to decode. + /// The account keys present in the transaction. + /// The indices of the account keys for the instruction as they appear in the transaction. + internal static void DecodeAssignWithSeedData(DecodedInstruction decodedInstruction, ReadOnlySpan data, + IList keys, byte[] keyIndices) + { + decodedInstruction.Values.Add("Account", keys[keyIndices[0]]); + decodedInstruction.Values.Add("Base Account", data.GetPubKey(4)); + (string assignSeed, int assignLength) = data.DecodeBincodeString(36); + decodedInstruction.Values.Add("Seed", assignSeed); + decodedInstruction.Values.Add("Owner", data.GetPubKey(36 + assignLength)); + } + + /// + /// Decodes the instruction instruction data for the method + /// + /// The decoded instruction to add data to. + /// The instruction data to decode. + /// The account keys present in the transaction. + /// The indices of the account keys for the instruction as they appear in the transaction. + internal static void DecodeTransferWithSeedData(DecodedInstruction decodedInstruction, ReadOnlySpan data, + IList keys, byte[] keyIndices) + { + decodedInstruction.Values.Add("From Account", keys[keyIndices[0]]); + decodedInstruction.Values.Add("From Base Account", keys[keyIndices[1]]); + decodedInstruction.Values.Add("To Account", keys[keyIndices[1]]); + decodedInstruction.Values.Add("Amount", data.GetU64(4)); + (string transferSeed, int transferLength) = data.DecodeBincodeString(12); + decodedInstruction.Values.Add("Seed", transferSeed); + decodedInstruction.Values.Add("From Owner", data.GetPubKey(12 + transferLength)); + } + + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/SystemProgramData.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/SystemProgramData.cs.meta new file mode 100644 index 0000000..2510f61 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/SystemProgramData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b89b98cc7f40d934784e134e12eabacf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/SystemProgramInstructions.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/SystemProgramInstructions.cs new file mode 100644 index 0000000..7572a36 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/SystemProgramInstructions.cs @@ -0,0 +1,100 @@ +using System.Collections.Generic; + +namespace Solana.Unity.Programs +{ + /// + /// Represents the instruction types for the along with a friendly name so as not to use reflection. + /// + /// For more information see: + /// https://docs.solana.com/developing/runtime-facilities/programs#system-program + /// https://docs.rs/solana-sdk/1.7.0/solana_sdk/system_instruction/enum.SystemInstruction.html + /// + /// + internal static class SystemProgramInstructions + { + /// + /// Represents the user-friendly names for the instruction types for the . + /// + internal static readonly Dictionary Names = new() + { + { Values.CreateAccount, "Create Account" }, + { Values.Assign, "Assign" }, + { Values.Transfer, "Transfer" }, + { Values.CreateAccountWithSeed, "Create Account With Seed" }, + { Values.AdvanceNonceAccount, "Advance Nonce Account" }, + { Values.WithdrawNonceAccount, "Withdraw Nonce Account" }, + { Values.InitializeNonceAccount, "Initialize Nonce Account" }, + { Values.AuthorizeNonceAccount, "Authorize Nonce Account" }, + { Values.Allocate, "Allocate" }, + { Values.AllocateWithSeed, "Allocate With Seed" }, + { Values.AssignWithSeed, "Assign With Seed" }, + { Values.TransferWithSeed, "Transfer With Seed" }, + }; + + /// + /// Represents the instruction types for the . + /// + internal enum Values : byte + { + /// + /// Create a new account. + /// + CreateAccount = 0, + + /// + /// Assign account to a program. + /// + Assign = 1, + + /// + /// Transfer lamports. + /// + Transfer = 2, + + /// + /// Create a new account at an address derived from a base public key and a seed. + /// + CreateAccountWithSeed = 3, + + /// + /// Consumes a stored nonce, replacing it with a successor. + /// + AdvanceNonceAccount = 4, + + /// + /// Withdraw funds from a nonce account. + /// + WithdrawNonceAccount = 5, + + /// + /// Drive state of uninitialized nonce account to Initialized, setting the nonce value. + /// + InitializeNonceAccount = 6, + + /// + /// Change the entity authorized to execute nonce instructions on the account. + /// + AuthorizeNonceAccount = 7, + + /// + /// Allocate space in a (possibly new) account without funding. + /// + Allocate = 8, + + /// + /// Allocate space for and assign an account at an address derived from a base public key and a seed. + /// + AllocateWithSeed = 9, + + /// + /// Assign account to a program based on a seed + /// + AssignWithSeed = 10, + + /// + /// Transfer lamports from a derived address. + /// + TransferWithSeed = 11 + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/SystemProgramInstructions.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/SystemProgramInstructions.cs.meta new file mode 100644 index 0000000..dff3ff8 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/SystemProgramInstructions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0b2fead973a4f774bbdd58d86222f830 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenProgram.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenProgram.cs new file mode 100644 index 0000000..45dae40 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenProgram.cs @@ -0,0 +1,626 @@ +using Solana.Unity.Programs.Utilities; +using Solana.Unity.Rpc.Models; +using Solana.Unity.Wallet; +using Solana.Unity.Wallet.Utilities; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Solana.Unity.Programs +{ + /// + /// Implements the Token Program methods. + /// + /// For more information see: + /// https://spl.solana.com/token + /// https://docs.rs/spl-token/3.2.0/spl_token/ + /// + /// + public static class TokenProgram + { + /// + /// The public key of the Token Program. + /// + public static readonly PublicKey ProgramIdKey = new("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"); + + /// + /// The program's name. + /// + private const string ProgramName = "Token Program"; + + /// + /// Mint account account layout size. + /// + public const int MintAccountDataSize = 82; + + /// + /// Account layout size. + /// + public const int TokenAccountDataSize = 165; + + /// + /// Multisig account layout size for the given number of signers. + /// + public const int MultisigAccountDataSize = 355; + + /// + /// Initializes an instruction to transfer tokens from one account to another either directly or via a delegate. + /// If this account is associated with the native mint then equal amounts of SOL and Tokens will be transferred to the destination account. + /// + /// The public key of the account to transfer tokens from. + /// The public key of the account to account to transfer tokens to. + /// The amount of tokens to transfer. + /// The public key of the authority. + /// Signing accounts if the authority is a multi signature. + /// The transaction instruction. + public static TransactionInstruction Transfer( + PublicKey source, PublicKey destination, ulong amount, PublicKey authority, IEnumerable signers = null) + { + List keys = new() + { + AccountMeta.Writable(source, false), + AccountMeta.Writable(destination, false), + }; + keys = AddSigners(keys, authority, signers); + return new TransactionInstruction + { + ProgramId = ProgramIdKey.KeyBytes, + Keys = keys, + Data = TokenProgramData.EncodeTransferData(amount) + }; + } + + /// + /// + /// Initializes an instruction to transfer tokens from one account to another either directly or via a delegate. + /// If this account is associated with the native mint then equal amounts of SOL and Tokens will be transferred to the destination account. + /// + /// + /// This instruction differs from Transfer in that the token mint and decimals value is checked by the caller. + /// This may be useful when creating transactions offline or within a hardware wallet. + /// + /// + /// The public key of the account to transfer tokens from. + /// The public key of the account to account to transfer tokens to. + /// The amount of tokens to transfer. + /// The token decimals. + /// The public key of the authority account. + /// The public key of the token mint. + /// Signing accounts if the authority is a multi signature. + /// The transaction instruction. + public static TransactionInstruction TransferChecked( + PublicKey source, PublicKey destination, ulong amount, int decimals, PublicKey authority, PublicKey tokenMint, + IEnumerable signers = null) + { + List keys = new() + { + AccountMeta.Writable(source, false), + AccountMeta.ReadOnly(tokenMint, false), + AccountMeta.Writable(destination, false), + }; + keys = AddSigners(keys, authority, signers); + return new TransactionInstruction + { + ProgramId = ProgramIdKey.KeyBytes, + Keys = keys, + Data = TokenProgramData.EncodeTransferCheckedData(amount, decimals) + }; + } + + /// + /// Initializes an instruction to initialize a new account to hold tokens. + /// If this account is associated with the native mint then the token balance of the initialized account will be equal to the amount of SOL in the account. + /// If this account is associated with another mint, that mint must be initialized before this command can succeed. + /// + /// + /// The InitializeAccount instruction requires no signers and MUST be included within the same Transaction + /// as the system program's "/> + /// instruction that creates the account being initialized. + /// Otherwise another party can acquire ownership of the uninitialized account. + /// + /// + /// The public key of the account to initialize. + /// The public key of the token mint. + /// The public key of the account to set as authority of the initialized account. + /// The transaction instruction. + public static TransactionInstruction InitializeAccount(PublicKey account, PublicKey mint, PublicKey authority) + { + List keys = new() + { + AccountMeta.Writable(account, false), + AccountMeta.ReadOnly(mint, false), + AccountMeta.ReadOnly(authority, false), + AccountMeta.ReadOnly(SysVars.RentKey, false) + }; + return new TransactionInstruction + { + ProgramId = ProgramIdKey.KeyBytes, + Keys = keys, + Data = TokenProgramData.EncodeInitializeAccountData() + }; + } + + /// + /// Initializes an instruction to initialize a multi signature token account. + /// + /// Public key of the multi signature account. + /// Addresses of multi signature signers. + /// The number of signatures required to validate this multi signature account. + public static TransactionInstruction InitializeMultiSignature(PublicKey multiSignature, + IEnumerable signers, int m) + { + List keys = new() + { + AccountMeta.Writable(multiSignature, false), + AccountMeta.ReadOnly(SysVars.RentKey, false) + }; + keys.AddRange(signers.Select(signer => AccountMeta.ReadOnly(signer, false))); + return new TransactionInstruction + { + ProgramId = ProgramIdKey.KeyBytes, + Keys = keys, + Data = TokenProgramData.EncodeInitializeMultiSignatureData(m) + }; + } + + /// + /// Initializes an instruction to transfer tokens from one account to another either directly or via a delegate. + /// If this account is associated with the native mint then equal amounts of SOL and Tokens will be transferred to the destination account. + /// + /// The public key of the token mint. + /// The token decimals. + /// The public key of the token mint authority. + /// The token freeze authority. + public static TransactionInstruction InitializeMint(PublicKey mint, int decimals, PublicKey mintAuthority, + PublicKey freezeAuthority = null) + { + List keys = new() + { + AccountMeta.Writable(mint, false), + AccountMeta.ReadOnly(SysVars.RentKey, false) + }; + + int freezeAuthorityOpt = freezeAuthority != null ? 1 : 0; + return new TransactionInstruction + { + ProgramId = ProgramIdKey.KeyBytes, + Keys = keys, + Data = TokenProgramData.EncodeInitializeMintData( + mintAuthority, + freezeAuthority ?? new Account().PublicKey, + decimals, + freezeAuthorityOpt) + }; + } + + /// + /// Initializes an instruction to mint tokens to a destination account. + /// + /// The public key token mint. + /// The public key of the account to mint tokens to. + /// The amount of tokens. + /// The token mint authority account. + /// Signing accounts if the authority is a multi signature. + /// The transaction instruction. + public static TransactionInstruction MintTo(PublicKey mint, PublicKey destination, ulong amount, + PublicKey mintAuthority, IEnumerable signers = null) + { + List keys = new() + { + AccountMeta.Writable(mint, false), + AccountMeta.Writable(destination, false), + }; + keys = AddSigners(keys, mintAuthority, signers); + + return new TransactionInstruction + { + ProgramId = ProgramIdKey.KeyBytes, + Keys = keys, + Data = TokenProgramData.EncodeMintToData(amount) + }; + } + + /// + /// Initializes an instruction to approve a transaction. + /// + /// The public key source account. + /// The public key of the delegate account authorized to perform a transfer from the source account. + /// The public key of the authority of the source account. + /// The maximum amount of tokens the delegate may transfer. + /// Signing accounts if the authority is a multi signature. + /// The transaction instruction. + public static TransactionInstruction Approve( + PublicKey source, PublicKey delegatePublicKey, PublicKey authority, ulong amount, + IEnumerable signers = null) + { + List keys = new() + { + AccountMeta.Writable(source, false), + AccountMeta.ReadOnly(delegatePublicKey, false) + }; + + keys = AddSigners(keys, authority, signers); + + return new TransactionInstruction + { + ProgramId = ProgramIdKey.KeyBytes, + Keys = keys, + Data = TokenProgramData.EncodeApproveData(amount) + }; + } + + /// + /// Initializes an instruction to revoke a transaction. + /// + /// The public key source account. + /// The public key of the authority of the source account. + /// Signing accounts if the authority is a multi signature. + /// The transaction instruction. + public static TransactionInstruction Revoke(PublicKey source, PublicKey authority, + IEnumerable signers = null) + { + List keys = new() + { + AccountMeta.Writable(source, false), + }; + keys = AddSigners(keys, authority, signers); + + return new TransactionInstruction + { + ProgramId = ProgramIdKey.KeyBytes, + Keys = keys, + Data = TokenProgramData.EncodeRevokeData() + }; + } + + /// + /// Initialize an instruction to set an authority on an account. + /// + /// The public key of the account to set the authority on. + /// The type of authority to set. + /// The public key of the current authority of the specified type. + /// The public key of the new authority. + /// Signing accounts if the authority is a multi signature. + /// The transaction instruction. + public static TransactionInstruction SetAuthority( + PublicKey account, AuthorityType authority, PublicKey currentAuthority, PublicKey newAuthority = null, + IEnumerable signers = null) + { + List keys = new() + { + AccountMeta.Writable(account, false), + }; + keys = AddSigners(keys, currentAuthority, signers); + + int newAuthorityOpt = newAuthority != null ? 1 : 0; + newAuthority ??= new Account().PublicKey; + return new TransactionInstruction + { + ProgramId = ProgramIdKey.KeyBytes, + Keys = keys, + Data = TokenProgramData.EncodeSetAuthorityData(authority, newAuthorityOpt, newAuthority) + }; + } + + /// + /// Initialize an instruction to burn tokens. + /// + /// The public key of the account to burn tokens from. + /// The public key of the token mint. + /// The amount of tokens to burn. + /// The public key of the authority of the source account. + /// Signing accounts if the authority is a multi signature. + /// The transaction instruction. + public static TransactionInstruction Burn(PublicKey source, PublicKey mint, ulong amount, PublicKey authority, + IEnumerable signers = null) + { + List keys = new() + { + AccountMeta.Writable(source, false), + AccountMeta.Writable(mint, false), + }; + keys = AddSigners(keys, authority, signers); + return new TransactionInstruction() + { + ProgramId = ProgramIdKey.KeyBytes, + Keys = keys, + Data = TokenProgramData.EncodeBurnData(amount) + }; + } + + /// + /// Initialize an instruction to close an account. + /// + /// The public key of the account to close. + /// The public key of the account that will receive the SOL. + /// The public key of the authority of the source account. + /// The public key which represents the associated program id. + /// Signing accounts if the authority is a multi signature. + /// The transaction instruction. + public static TransactionInstruction CloseAccount(PublicKey account, PublicKey destination, PublicKey authority, + PublicKey programId, IEnumerable signers = null) + { + List keys = new() + { + AccountMeta.Writable(account, false), + AccountMeta.Writable(destination, false), + }; + keys = AddSigners(keys, authority, signers); + return new TransactionInstruction() + { + ProgramId = programId.KeyBytes, + Keys = keys, + Data = TokenProgramData.EncodeCloseAccountData() + }; + } + + /// + /// Initialize an instruction to freeze a token account. + /// + /// The public key of the account to freeze. + /// The public key of the token mint. + /// The public key of the authority of the freeze authority for the token mint. + /// The public key which represents the associated program id. + /// Signing accounts if the freezeAuthority is a multi signature. + /// The transaction instruction. + public static TransactionInstruction FreezeAccount(PublicKey account, PublicKey mint, PublicKey freezeAuthority, + PublicKey programId, IEnumerable signers = null) + { + List keys = new() + { + AccountMeta.Writable(account, false), + AccountMeta.ReadOnly(mint, false), + }; + keys = AddSigners(keys, freezeAuthority, signers); + return new TransactionInstruction() + { + ProgramId = programId.KeyBytes, + Keys = keys, + Data = TokenProgramData.EncodeFreezeAccountData() + }; + } + + /// + /// Initialize an instruction to thaw a token account. + /// + /// The public key of the account to thaw. + /// The public key of the token mint. + /// The public key of the freeze authority for the token mint. + /// The public key which represents the associated program id. + /// Signing accounts if the authority is a multi signature. + /// The transaction instruction. + public static TransactionInstruction ThawAccount(PublicKey account, PublicKey mint, PublicKey freezeAuthority, + PublicKey programId, IEnumerable signers = null) + { + List keys = new() + { + AccountMeta.Writable(account, false), + AccountMeta.ReadOnly(mint, false), + }; + keys = AddSigners(keys, freezeAuthority, signers); + return new TransactionInstruction() + { + ProgramId = programId.KeyBytes, + Keys = keys, + Data = TokenProgramData.EncodeThawAccountData() + }; + } + + /// + /// Initialize an instruction to approve a transaction. + /// + /// This instruction differs from Approve in that the amount and decimals value is checked by the caller. + /// This may be useful when creating transactions offline or within a hardware wallet. + /// + /// + /// The public key of the source account. + /// The public key of the delegate account authorized to perform a transfer from the source account. + /// The public key of the authority of the source account. + /// The maximum amount of tokens the delegate may transfer. + /// Signing accounts if the authority is a multi signature. + /// The token decimals. + /// The public key of the token mint. + /// The transaction instruction. + public static TransactionInstruction ApproveChecked( + PublicKey source, PublicKey delegatePublicKey, ulong amount, byte decimals, PublicKey authority, PublicKey mint, + IEnumerable signers = null) + { + List keys = new() + { + AccountMeta.Writable(source, false), + AccountMeta.ReadOnly(mint, false), + AccountMeta.ReadOnly(delegatePublicKey, false), + }; + keys = AddSigners(keys, authority, signers); + return new TransactionInstruction + { + ProgramId = ProgramIdKey.KeyBytes, + Keys = keys, + Data = TokenProgramData.EncodeApproveCheckedData(amount, decimals) + }; + } + + /// + /// Initialize an instruction to approve a transaction. + /// + /// This instruction differs from MintTo in that the amount and decimals value is checked by the caller. + /// This may be useful when creating transactions offline or within a hardware wallet. + /// + /// + /// The public key of the token mint. + /// The public key of the account to mint tokens to. + /// The public key of the token's mint authority account. + /// The amount of tokens. + /// The token decimals. + /// Signing accounts if the mintAuthority is a multi signature. + /// The transaction instruction. + public static TransactionInstruction MintToChecked(PublicKey mint, PublicKey destination, + PublicKey mintAuthority, ulong amount, int decimals, IEnumerable signers = null) + { + List keys = new() + { + AccountMeta.Writable(mint, false), + AccountMeta.Writable(destination, false), + }; + keys = AddSigners(keys, mintAuthority, signers); + return new TransactionInstruction + { + ProgramId = ProgramIdKey.KeyBytes, + Keys = keys, + Data = TokenProgramData.EncodeMintToCheckedData(amount, decimals) + }; + } + + /// + /// Initialize an instruction to burn tokens. + /// + /// This instruction differs from Burn in that the amount and decimals value is checked by the caller. + /// This may be useful when creating transactions offline or within a hardware wallet. + /// + /// + /// The public key of the token mint. + /// The public key of the account to burn from. + /// The public key of the authority of the source account. + /// The amount of tokens. + /// The token decimals. + /// Signing accounts if the authority is a multi signature. + /// The transaction instruction. + public static TransactionInstruction BurnChecked(PublicKey mint, PublicKey account, PublicKey authority, + ulong amount, int decimals, IEnumerable signers = null) + { + List keys = new() + { + AccountMeta.Writable(account, false), + AccountMeta.Writable(mint, false), + }; + keys = AddSigners(keys, authority, signers); + return new TransactionInstruction + { + ProgramId = ProgramIdKey.KeyBytes, + Keys = keys, + Data = TokenProgramData.EncodeBurnCheckedData(amount, decimals) + }; + } + + /// + /// Initialize an instruction to sync native tokens. + /// + /// The public key of the token account. + /// The transaction instruction. + public static TransactionInstruction SyncNative(PublicKey account) + { + List keys = new() + { + AccountMeta.Writable(account, false) + }; + return new TransactionInstruction + { + ProgramId = ProgramIdKey.KeyBytes, + Keys = keys, + Data = TokenProgramData.EncodeSyncNativeData() + }; + } + + /// + /// Adds the list of signers to the list of keys. + /// + /// The instruction's list of keys. + /// The public key of the authority account. + /// The list of signers. + /// The list of keys with the added signers. + private static List AddSigners(List keys, PublicKey authority = null, + IEnumerable signers = null) + { + if (signers != null) + { + keys.Add(AccountMeta.ReadOnly(authority, false)); + keys.AddRange(signers.Select(signer => AccountMeta.ReadOnly(signer, true))); + } + else + { + keys.Add(AccountMeta.ReadOnly(authority, true)); + } + + return keys; + } + + /// + /// Decodes an instruction created by the System Program. + /// + /// The instruction data to decode. + /// The account keys present in the transaction. + /// The indices of the account keys for the instruction as they appear in the transaction. + /// A decoded instruction. + public static DecodedInstruction Decode(ReadOnlySpan data, IList keys, byte[] keyIndices) + { + uint instruction = data.GetU8(TokenProgramData.MethodOffset); + TokenProgramInstructions.Values instructionValue = + (TokenProgramInstructions.Values)Enum.Parse(typeof(TokenProgramInstructions.Values), instruction.ToString()); + + DecodedInstruction decodedInstruction = new() + { + PublicKey = ProgramIdKey, + InstructionName = TokenProgramInstructions.Names[instructionValue], + ProgramName = ProgramName, + Values = new Dictionary(), + InnerInstructions = new List() + }; + + switch (instructionValue) + { + case TokenProgramInstructions.Values.InitializeMint: + TokenProgramData.DecodeInitializeMintData(decodedInstruction, data, keys, keyIndices); + break; + case TokenProgramInstructions.Values.InitializeAccount: + TokenProgramData.DecodeInitializeAccountData(decodedInstruction, keys, keyIndices); + break; + case TokenProgramInstructions.Values.InitializeMultiSignature: + TokenProgramData.DecodeInitializeMultiSignatureData(decodedInstruction, data, keys, keyIndices); + break; + case TokenProgramInstructions.Values.Transfer: + TokenProgramData.DecodeTransferData(decodedInstruction, data, keys, keyIndices); + break; + case TokenProgramInstructions.Values.Approve: + TokenProgramData.DecodeApproveData(decodedInstruction, data, keys, keyIndices); + break; + case TokenProgramInstructions.Values.Revoke: + TokenProgramData.DecodeRevokeData(decodedInstruction, keys, keyIndices); + break; + case TokenProgramInstructions.Values.SetAuthority: + TokenProgramData.DecodeSetAuthorityData(decodedInstruction, data, keys, keyIndices); + break; + case TokenProgramInstructions.Values.MintTo: + TokenProgramData.DecodeMintToData(decodedInstruction, data, keys, keyIndices); + break; + case TokenProgramInstructions.Values.Burn: + TokenProgramData.DecodeBurnData(decodedInstruction, data, keys, keyIndices); + break; + case TokenProgramInstructions.Values.CloseAccount: + TokenProgramData.DecodeCloseAccountData(decodedInstruction, keys, keyIndices); + break; + case TokenProgramInstructions.Values.FreezeAccount: + TokenProgramData.DecodeFreezeAccountData(decodedInstruction, keys, keyIndices); + break; + case TokenProgramInstructions.Values.ThawAccount: + TokenProgramData.DecodeThawAccountData(decodedInstruction, keys, keyIndices); + break; + case TokenProgramInstructions.Values.TransferChecked: + TokenProgramData.DecodeTransferCheckedData(decodedInstruction, data, keys, keyIndices); + break; + case TokenProgramInstructions.Values.ApproveChecked: + TokenProgramData.DecodeApproveCheckedData(decodedInstruction, data, keys, keyIndices); + break; + case TokenProgramInstructions.Values.MintToChecked: + TokenProgramData.DecodeMintToCheckedData(decodedInstruction, data, keys, keyIndices); + break; + case TokenProgramInstructions.Values.BurnChecked: + TokenProgramData.DecodeBurnCheckedData(decodedInstruction, data, keys, keyIndices); + break; + case TokenProgramInstructions.Values.SyncNative: + TokenProgramData.DecodeSyncNativeData(decodedInstruction, keys, keyIndices); + break; + } + return decodedInstruction; + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenProgram.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenProgram.cs.meta new file mode 100644 index 0000000..f0514a5 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenProgram.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5541b0209e55e1a498fc595e7348e9a9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenProgramData.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenProgramData.cs new file mode 100644 index 0000000..df3de45 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenProgramData.cs @@ -0,0 +1,538 @@ +using Solana.Unity.Programs.Utilities; +using Solana.Unity.Wallet; +using System; +using System.Collections.Generic; + +namespace Solana.Unity.Programs +{ + /// + /// Implements the token program data encodings. + /// + internal static class TokenProgramData + { + /// + /// The offset at which the value which defines the method begins. + /// + internal const int MethodOffset = 0; + + /// + /// Encode the transaction instruction data for the method. + /// + /// The byte array with the encoded data. + internal static byte[] EncodeRevokeData() => new[] { (byte)TokenProgramInstructions.Values.Revoke }; + + /// + /// Encode the transaction instruction data for the method. + /// + /// The amount of tokens to approve the transfer of. + /// The byte array with the encoded data. + internal static byte[] EncodeApproveData(ulong amount) + => EncodeAmountLayout((byte)TokenProgramInstructions.Values.Approve, amount); + + /// + /// Encode the transaction instruction data for the method. + /// + /// The byte array with the encoded data. + internal static byte[] EncodeInitializeAccountData() => + new[] { (byte)TokenProgramInstructions.Values.InitializeAccount }; + + /// + /// Encode the transaction instruction data for the method. + /// + /// The mint authority for the token. + /// The freeze authority for the token. + /// The amount of decimals. + /// The freeze authority option for the token. + /// The freezeAuthorityOption parameter is related to the existence or not of a freeze authority. + /// The byte array with the encoded data. + internal static byte[] EncodeInitializeMintData( + PublicKey mintAuthority, PublicKey freezeAuthority, int decimals, int freezeAuthorityOption) + { + byte[] methodBuffer = new byte[67]; + + methodBuffer.WriteU8((byte)TokenProgramInstructions.Values.InitializeMint, MethodOffset); + methodBuffer.WriteU8((byte)decimals, 1); + methodBuffer.WritePubKey(mintAuthority, 2); + methodBuffer.WriteU8((byte)freezeAuthorityOption, 34); + methodBuffer.WritePubKey(freezeAuthority, 35); + + return methodBuffer; + } + + /// + /// Encode the transaction instruction data for the method. + /// + /// The amount of tokens. + /// The byte array with the encoded data. + internal static byte[] EncodeTransferData(ulong amount) + => EncodeAmountLayout((byte)TokenProgramInstructions.Values.Transfer, amount); + + /// + /// Encode the transaction instruction data for the method. + /// + /// The amount of tokens. + /// The number of decimals of the token. + /// The byte array with the encoded data. + internal static byte[] EncodeTransferCheckedData(ulong amount, int decimals) + => EncodeAmountCheckedLayout((byte)TokenProgramInstructions.Values.TransferChecked, amount, (byte)decimals); + + /// + /// Encode the transaction instruction data for the method. + /// + /// The amount of tokens. + /// The byte array with the encoded data. + internal static byte[] EncodeMintToData(ulong amount) + => EncodeAmountLayout((byte)TokenProgramInstructions.Values.MintTo, amount); + + /// + /// Encode the transaction instruction data for the method. + /// + /// The number of signers necessary to validate the account. + /// The byte array with the encoded data. + internal static byte[] EncodeInitializeMultiSignatureData(int m) + { + byte[] methodBuffer = new byte[2]; + + methodBuffer.WriteU8((byte)TokenProgramInstructions.Values.InitializeMultiSignature, MethodOffset); + methodBuffer.WriteU8((byte)m, 1); + + return methodBuffer; + } + + /// + /// Encode the transaction instruction data for the method. + /// + /// The byte array with the encoded data. + internal static byte[] EncodeSetAuthorityData(AuthorityType authorityType, int newAuthorityOption, + PublicKey newAuthority) + { + byte[] methodBuffer = new byte[35]; + + methodBuffer.WriteU8((byte)TokenProgramInstructions.Values.SetAuthority, MethodOffset); + methodBuffer.WriteU8((byte)authorityType, 1); + methodBuffer.WriteU8((byte)newAuthorityOption, 2); + methodBuffer.WritePubKey(newAuthority, 3); + + return methodBuffer; + } + + /// + /// Encode the transaction instruction data for the method. + /// + /// The amount of tokens. + /// The byte array with the encoded data. + internal static byte[] EncodeBurnData(ulong amount) + => EncodeAmountLayout((byte)TokenProgramInstructions.Values.Burn, amount); + + /// + /// Encode the transaction instruction data for the method. + /// + /// The byte array with the encoded data. + internal static byte[] EncodeCloseAccountData() => new[] { (byte)TokenProgramInstructions.Values.CloseAccount }; + + /// + /// Encode the transaction instruction data for the method. + /// + /// The byte array with the encoded data. + internal static byte[] EncodeFreezeAccountData() => + new[] { (byte)TokenProgramInstructions.Values.FreezeAccount }; + + /// + /// Encode the transaction instruction data for the method. + /// + /// The byte array with the encoded data. + internal static byte[] EncodeThawAccountData() => new[] { (byte)TokenProgramInstructions.Values.ThawAccount }; + + /// + /// Encodes the transaction instruction data for the method. + /// + /// The amount of tokens. + /// The decimals of the token. + /// The byte array with the encoded data. + internal static byte[] EncodeApproveCheckedData(ulong amount, int decimals) + => EncodeAmountCheckedLayout((byte)TokenProgramInstructions.Values.ApproveChecked, amount, (byte)decimals); + + /// + /// Encodes the transaction instruction data for the method. + /// + /// The amount of tokens. + /// The decimals of the token. + /// The byte array with the encoded data. + internal static byte[] EncodeMintToCheckedData(ulong amount, int decimals) + => EncodeAmountCheckedLayout((byte)TokenProgramInstructions.Values.MintToChecked, amount, (byte)decimals); + + /// + /// Encodes the transaction instruction data for the method. + /// + /// The amount of tokens. + /// The decimals of the token. + /// The byte array with the encoded data. + internal static byte[] EncodeBurnCheckedData(ulong amount, int decimals) + => EncodeAmountCheckedLayout((byte)TokenProgramInstructions.Values.BurnChecked, amount, (byte)decimals); + + /// + /// Encodes the transaction instruction data for the method. + /// + /// The byte array with the encoded data. + internal static byte[] EncodeSyncNativeData() => + new[] { (byte) TokenProgramInstructions.Values.SyncNative }; + + /// + /// Decodes the instruction instruction data for the method + /// + /// The decoded instruction to add data to. + /// The instruction data to decode. + /// The account keys present in the transaction. + /// The indices of the account keys for the instruction as they appear in the transaction. + internal static void DecodeInitializeMintData(DecodedInstruction decodedInstruction, ReadOnlySpan data, + IList keys, byte[] keyIndices) + { + decodedInstruction.Values.Add("Account", keys[keyIndices[0]]); + decodedInstruction.Values.Add("Decimals", data.GetU8(1)); + decodedInstruction.Values.Add("Mint Authority", data.GetPubKey(2)); + + var hasFreezeAuthority = data.GetBool(34); + + decodedInstruction.Values.Add("Freeze Authority Option", hasFreezeAuthority); + if(hasFreezeAuthority) + decodedInstruction.Values.Add("Freeze Authority", data.GetPubKey(35)); + } + + /// + /// Decodes the instruction instruction data for the method + /// + /// The decoded instruction to add data to. + /// The account keys present in the transaction. + /// The indices of the account keys for the instruction as they appear in the transaction. + internal static void DecodeInitializeAccountData(DecodedInstruction decodedInstruction, IList keys, + byte[] keyIndices) + { + decodedInstruction.Values.Add("Account", keys[keyIndices[0]]); + decodedInstruction.Values.Add("Mint", keys[keyIndices[1]]); + decodedInstruction.Values.Add("Authority", keys[keyIndices[2]]); + } + + /// + /// Decodes the instruction instruction data for the method + /// + /// The decoded instruction to add data to. + /// The instruction data to decode. + /// The account keys present in the transaction. + /// The indices of the account keys for the instruction as they appear in the transaction. + internal static void DecodeInitializeMultiSignatureData(DecodedInstruction decodedInstruction, + ReadOnlySpan data, IList keys, byte[] keyIndices) + { + decodedInstruction.Values.Add("Account", keys[keyIndices[0]]); + byte numSigners = data.GetU8(1); + decodedInstruction.Values.Add("Required Signers", numSigners); + for (int i = 2; i < keyIndices.Length; i++) + { + decodedInstruction.Values.Add($"Signer {i - 1}", keys[keyIndices[i]]); + } + } + + /// + /// Decodes the instruction instruction data for the method + /// + /// The decoded instruction to add data to. + /// The instruction data to decode. + /// The account keys present in the transaction. + /// The indices of the account keys for the instruction as they appear in the transaction. + internal static void DecodeTransferData(DecodedInstruction decodedInstruction, ReadOnlySpan data, + IList keys, byte[] keyIndices) + { + decodedInstruction.Values.Add("Source", keys[keyIndices[0]]); + decodedInstruction.Values.Add("Destination", keys[keyIndices[1]]); + decodedInstruction.Values.Add("Authority", keys[keyIndices[2]]); + decodedInstruction.Values.Add("Amount", data.GetU64(1)); + for (int i = 3; i < keyIndices.Length; i++) + { + decodedInstruction.Values.Add($"Signer {i - 2}", keys[keyIndices[i]]); + } + } + + /// + /// Decodes the instruction instruction data for the method + /// + /// The decoded instruction to add data to. + /// The instruction data to decode. + /// The account keys present in the transaction. + /// The indices of the account keys for the instruction as they appear in the transaction. + internal static void DecodeApproveData(DecodedInstruction decodedInstruction, ReadOnlySpan data, + IList keys, byte[] keyIndices) + { + decodedInstruction.Values.Add("Source", keys[keyIndices[0]]); + decodedInstruction.Values.Add("Delegate", keys[keyIndices[1]]); + decodedInstruction.Values.Add("Authority", keys[keyIndices[2]]); + decodedInstruction.Values.Add("Amount", data.GetU64(1)); + for (int i = 3; i < keyIndices.Length; i++) + { + decodedInstruction.Values.Add($"Signer {i - 2}", keys[keyIndices[i]]); + } + } + + /// + /// Decodes the instruction instruction data for the method + /// + /// The decoded instruction to add data to. + /// The account keys present in the transaction. + /// The indices of the account keys for the instruction as they appear in the transaction. + internal static void DecodeRevokeData(DecodedInstruction decodedInstruction, IList keys, + byte[] keyIndices) + { + decodedInstruction.Values.Add("Source", keys[keyIndices[0]]); + decodedInstruction.Values.Add("Authority", keys[keyIndices[1]]); + for (int i = 2; i < keyIndices.Length; i++) + { + decodedInstruction.Values.Add($"Signer {i - 1}", keys[keyIndices[i]]); + } + } + + /// + /// Decodes the instruction instruction data for the method + /// + /// The decoded instruction to add data to. + /// The instruction data to decode. + /// The account keys present in the transaction. + /// The indices of the account keys for the instruction as they appear in the transaction. + internal static void DecodeSetAuthorityData(DecodedInstruction decodedInstruction, ReadOnlySpan data, + IList keys, byte[] keyIndices) + { + decodedInstruction.Values.Add("Account", keys[keyIndices[0]]); + decodedInstruction.Values.Add("Current Authority", keys[keyIndices[1]]); + decodedInstruction.Values.Add("Authority Type", Enum.Parse(typeof(AuthorityType), data.GetU8(1).ToString())); + decodedInstruction.Values.Add("New Authority Option", data.GetU8(2)); + decodedInstruction.Values.Add("New Authority", data.GetPubKey(3)); + for (int i = 2; i < keyIndices.Length; i++) + { + decodedInstruction.Values.Add($"Signer {i - 1}", keys[keyIndices[i]]); + } + } + + /// + /// Decodes the instruction instruction data for the method + /// + /// The decoded instruction to add data to. + /// The instruction data to decode. + /// The account keys present in the transaction. + /// The indices of the account keys for the instruction as they appear in the transaction. + internal static void DecodeMintToData(DecodedInstruction decodedInstruction, ReadOnlySpan data, + IList keys, byte[] keyIndices) + { + decodedInstruction.Values.Add("Mint", keys[keyIndices[0]]); + decodedInstruction.Values.Add("Destination", keys[keyIndices[1]]); + decodedInstruction.Values.Add("Mint Authority", keys[keyIndices[2]]); + decodedInstruction.Values.Add("Amount", data.GetU64(1)); + for (int i = 3; i < keyIndices.Length; i++) + { + decodedInstruction.Values.Add($"Signer {i - 2}", keys[keyIndices[i]]); + } + } + + /// + /// Decodes the instruction instruction data for the method + /// + /// The decoded instruction to add data to. + /// The instruction data to decode. + /// The account keys present in the transaction. + /// The indices of the account keys for the instruction as they appear in the transaction. + internal static void DecodeBurnData(DecodedInstruction decodedInstruction, ReadOnlySpan data, + IList keys, byte[] keyIndices) + { + decodedInstruction.Values.Add("Account", keys[keyIndices[0]]); + decodedInstruction.Values.Add("Mint", keys[keyIndices[1]]); + decodedInstruction.Values.Add("Authority", keys[keyIndices[2]]); + decodedInstruction.Values.Add("Amount", data.GetU64(1)); + for (int i = 3; i < keyIndices.Length; i++) + { + decodedInstruction.Values.Add($"Signer {i - 2}", keys[keyIndices[i]]); + } + } + + /// + /// Decodes the instruction instruction data for the method + /// + /// The decoded instruction to add data to. + /// The account keys present in the transaction. + /// The indices of the account keys for the instruction as they appear in the transaction. + internal static void DecodeCloseAccountData(DecodedInstruction decodedInstruction, IList keys, + byte[] keyIndices) + { + decodedInstruction.Values.Add("Account", keys[keyIndices[0]]); + decodedInstruction.Values.Add("Destination", keys[keyIndices[1]]); + decodedInstruction.Values.Add("Authority", keys[keyIndices[2]]); + for (int i = 3; i < keyIndices.Length; i++) + { + decodedInstruction.Values.Add($"Signer {i - 2}", keys[keyIndices[i]]); + } + } + + /// + /// Decodes the instruction instruction data for the method + /// + /// The decoded instruction to add data to. + /// The account keys present in the transaction. + /// The indices of the account keys for the instruction as they appear in the transaction. + internal static void DecodeFreezeAccountData(DecodedInstruction decodedInstruction, IList keys, + byte[] keyIndices) + { + decodedInstruction.Values.Add("Account", keys[keyIndices[0]]); + decodedInstruction.Values.Add("Mint", keys[keyIndices[1]]); + decodedInstruction.Values.Add("Freeze Authority", keys[keyIndices[2]]); + for (int i = 3; i < keyIndices.Length; i++) + { + decodedInstruction.Values.Add($"Signer {i - 2}", keys[keyIndices[i]]); + } + } + + /// + /// Decodes the instruction instruction data for the method + /// + /// The decoded instruction to add data to. + /// The account keys present in the transaction. + /// The indices of the account keys for the instruction as they appear in the transaction. + internal static void DecodeThawAccountData(DecodedInstruction decodedInstruction, IList keys, + byte[] keyIndices) + { + decodedInstruction.Values.Add("Account", keys[keyIndices[0]]); + decodedInstruction.Values.Add("Mint", keys[keyIndices[1]]); + decodedInstruction.Values.Add("Freeze Authority", keys[keyIndices[2]]); + for (int i = 3; i < keyIndices.Length; i++) + { + decodedInstruction.Values.Add($"Signer {i - 2}", keys[keyIndices[i]]); + } + } + + /// + /// Decodes the instruction instruction data for the method + /// + /// The decoded instruction to add data to. + /// The instruction data to decode. + /// The account keys present in the transaction. + /// The indices of the account keys for the instruction as they appear in the transaction. + internal static void DecodeTransferCheckedData(DecodedInstruction decodedInstruction, ReadOnlySpan data, + IList keys, byte[] keyIndices) + { + decodedInstruction.Values.Add("Source", keys[keyIndices[0]]); + decodedInstruction.Values.Add("Mint", keys[keyIndices[1]]); + decodedInstruction.Values.Add("Destination", keys[keyIndices[2]]); + decodedInstruction.Values.Add("Authority", keys[keyIndices[3]]); + decodedInstruction.Values.Add("Amount", data.GetU64(1)); + decodedInstruction.Values.Add("Decimals", data.GetU8(9)); + for (int i = 4; i < keyIndices.Length; i++) + { + decodedInstruction.Values.Add($"Signer {i - 3}", keys[keyIndices[i]]); + } + } + + /// + /// Decodes the instruction instruction data for the method + /// + /// The decoded instruction to add data to. + /// The instruction data to decode. + /// The account keys present in the transaction. + /// The indices of the account keys for the instruction as they appear in the transaction. + internal static void DecodeApproveCheckedData(DecodedInstruction decodedInstruction, ReadOnlySpan data, + IList keys, byte[] keyIndices) + { + decodedInstruction.Values.Add("Source", keys[keyIndices[0]]); + decodedInstruction.Values.Add("Mint", keys[keyIndices[1]]); + decodedInstruction.Values.Add("Delegate", keys[keyIndices[2]]); + decodedInstruction.Values.Add("Authority", keys[keyIndices[3]]); + decodedInstruction.Values.Add("Amount", data.GetU64(1)); + decodedInstruction.Values.Add("Decimals", data.GetU8(9)); + for (int i = 4; i < keyIndices.Length; i++) + { + decodedInstruction.Values.Add($"Signer {i - 3}", keys[keyIndices[i]]); + } + } + + /// + /// Decodes the instruction instruction data for the method + /// + /// The decoded instruction to add data to. + /// The instruction data to decode. + /// The account keys present in the transaction. + /// The indices of the account keys for the instruction as they appear in the transaction. + internal static void DecodeMintToCheckedData(DecodedInstruction decodedInstruction, ReadOnlySpan data, + IList keys, byte[] keyIndices) + { + decodedInstruction.Values.Add("Mint", keys[keyIndices[0]]); + decodedInstruction.Values.Add("Destination", keys[keyIndices[1]]); + decodedInstruction.Values.Add("Mint Authority", keys[keyIndices[2]]); + decodedInstruction.Values.Add("Amount", data.GetU64(1)); + decodedInstruction.Values.Add("Decimals", data.GetU8(9)); + for (int i = 3; i < keyIndices.Length; i++) + { + decodedInstruction.Values.Add($"Signer {i - 2}", keys[keyIndices[i]]); + } + } + + /// + /// Decodes the instruction instruction data for the method + /// + /// The decoded instruction to add data to. + /// The instruction data to decode. + /// The account keys present in the transaction. + /// The indices of the account keys for the instruction as they appear in the transaction. + internal static void DecodeBurnCheckedData(DecodedInstruction decodedInstruction, ReadOnlySpan data, + IList keys, byte[] keyIndices) + { + decodedInstruction.Values.Add("Account", keys[keyIndices[0]]); + decodedInstruction.Values.Add("Mint", keys[keyIndices[1]]); + decodedInstruction.Values.Add("Authority", keys[keyIndices[2]]); + decodedInstruction.Values.Add("Amount", data.GetU64(1)); + decodedInstruction.Values.Add("Decimals", data.GetU8(9)); + for (int i = 3; i < keyIndices.Length; i++) + { + decodedInstruction.Values.Add($"Signer {i - 2}", keys[keyIndices[i]]); + } + } + + /// + /// Decodes the instruction instruction data for the method + /// + /// The decoded instruction to add data to. + /// The account keys present in the transaction. + /// The indices of the account keys for the instruction as they appear in the transaction. + internal static void DecodeSyncNativeData(DecodedInstruction decodedInstruction, IList keys, + byte[] keyIndices) + { + decodedInstruction.Values.Add("Account", keys[keyIndices[0]]); + } + + /// + /// Encodes the transaction instruction data for the methods which only require the amount. + /// + /// The method identifier. + /// The amount of tokens. + /// The byte array with the encoded data. + private static byte[] EncodeAmountLayout(byte method, ulong amount) + { + byte[] methodBuffer = new byte[9]; + + methodBuffer.WriteU8(method, MethodOffset); + methodBuffer.WriteU64(amount, 1); + + return methodBuffer; + } + + /// + /// Encodes the transaction instruction data for the methods which only require the amount and the number of decimals. + /// + /// The method identifier. + /// The amount of tokens. + /// The decimals of the token. + /// The byte array with the encoded data. + private static byte[] EncodeAmountCheckedLayout(byte method, ulong amount, byte decimals) + { + byte[] methodBuffer = new byte[10]; + + methodBuffer.WriteU8(method, MethodOffset); + methodBuffer.WriteU64(amount, 1); + methodBuffer.WriteU8(decimals, 9); + + return methodBuffer; + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenProgramData.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenProgramData.cs.meta new file mode 100644 index 0000000..a146c23 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenProgramData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dbcb0e22cb575c242bc123ee07efd518 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenProgramInstructions.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenProgramInstructions.cs new file mode 100644 index 0000000..d509d19 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenProgramInstructions.cs @@ -0,0 +1,139 @@ +using System.Collections.Generic; + +namespace Solana.Unity.Programs +{ + /// + /// Represents the instruction types for the along with a friendly name so as not to use reflection. + /// + /// For more information see: + /// https://spl.solana.com/token + /// https://docs.rs/spl-token/3.2.0/spl_token/ + /// + /// + internal static class TokenProgramInstructions + { + /// + /// Represents the user-friendly names for the instruction types for the . + /// + internal static readonly Dictionary Names = new() + { + { Values.InitializeMint, "Initialize Mint" }, + { Values.InitializeAccount, "Initialize Account" }, + { Values.InitializeMultiSignature, "Initialize Multisig" }, + { Values.Transfer, "Transfer" }, + { Values.Approve, "Approve" }, + { Values.Revoke, "Revoke" }, + { Values.SetAuthority, "Set Authority" }, + { Values.MintTo, "Mint To" }, + { Values.Burn, "Burn" }, + { Values.CloseAccount, "Close Account" }, + { Values.FreezeAccount, "Freeze Account" }, + { Values.ThawAccount, "Thaw Account" }, + { Values.TransferChecked, "Transfer Checked" }, + { Values.ApproveChecked, "Approve Checked" }, + { Values.MintToChecked, "Mint To Checked" }, + { Values.BurnChecked, "Burn Checked" }, + { Values.SyncNative, "Sync Native" } + }; + + /// + /// Represents the instruction types for the . + /// + internal enum Values : byte + { + /// + /// Initialize a token mint. + /// + InitializeMint = 0, + + /// + /// Initialize a token account. + /// + InitializeAccount = 1, + + /// + /// Initialize a multi signature token account. + /// + InitializeMultiSignature = 2, + + /// + /// Transfer token transaction. + /// + Transfer = 3, + + /// + /// Approve token transaction. + /// + Approve = 4, + + /// + /// Revoke token transaction. + /// + Revoke = 5, + + /// + /// Set token authority transaction. + /// + SetAuthority = 6, + + /// + /// MintTo token account transaction. + /// + MintTo = 7, + + /// + /// Burn token transaction. + /// + Burn = 8, + + /// + /// Close token account transaction. + /// + CloseAccount = 9, + + /// + /// Freeze token account transaction. + /// + FreezeAccount = 10, + + /// + /// Thaw token account transaction. + /// + ThawAccount = 11, + + /// + /// Transfer checked token transaction. + /// Differs from in that the decimals value is asserted by the caller. + /// + TransferChecked = 12, + + /// + /// Approve checked token transaction. + /// Differs from in that the decimals value is asserted by the caller. + /// + ApproveChecked = 13, + + /// + /// MintTo checked token transaction. + /// Differs from in that the decimals value is asserted by the caller. + /// + MintToChecked = 14, + + /// + /// Burn checked token transaction. + /// Differs from in that the decimals value is asserted by the caller. + /// + BurnChecked = 15, + + /// + /// SyncNative token transaction. + /// Given a wrapped / native token account (a token account containing SOL) + /// updates its amount field based on the account's underlying `lamports`. + /// This is useful if a non-wrapped SOL account uses `system_instruction::transfer` + /// to move lamports to a wrapped token account, and needs to have its token + /// `amount` field updated. + /// + SyncNative = 17 + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenProgramInstructions.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenProgramInstructions.cs.meta new file mode 100644 index 0000000..349d5de --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenProgramInstructions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f0217dd09c64afd48959ecf64eb7c6c4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap.meta new file mode 100644 index 0000000..3d5c043 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d25d5e82cd8eb954390c96ca9b8ee56f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/Models.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/Models.meta new file mode 100644 index 0000000..74d9bd1 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/Models.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 39932b8b4de41d9488d8a70f8c1ff6e6 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/Models/ConstantProductCurve.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/Models/ConstantProductCurve.cs new file mode 100644 index 0000000..7aee50d --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/Models/ConstantProductCurve.cs @@ -0,0 +1,21 @@ +using System; + +namespace Solana.Unity.Programs.TokenSwap.Models +{ + /// + /// Uniswap-style constant product curve, invariant = token_a_amount * token_b_amount + /// + public class ConstantProductCurve : CurveCalculator + { + + /// + /// Serialize the Fees + /// + /// Serialized Fees + public ReadOnlySpan Serialize() + { + return new Span(new byte[0]); + } + + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/Models/ConstantProductCurve.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/Models/ConstantProductCurve.cs.meta new file mode 100644 index 0000000..51f5cca --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/Models/ConstantProductCurve.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 119854193f74e9741aff5980b912715f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/Models/CurveCalculator.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/Models/CurveCalculator.cs new file mode 100644 index 0000000..4464a00 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/Models/CurveCalculator.cs @@ -0,0 +1,16 @@ +using System; + +namespace Solana.Unity.Programs.TokenSwap.Models +{ + /// + /// A curve calculator must serialize itself to 32 bytes + /// + public interface CurveCalculator + { + /// + /// Serialize this calculator type + /// + /// + ReadOnlySpan Serialize(); + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/Models/CurveCalculator.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/Models/CurveCalculator.cs.meta new file mode 100644 index 0000000..336aac2 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/Models/CurveCalculator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cd4c8593889fa5f44977b23de162be81 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/Models/CurveType.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/Models/CurveType.cs new file mode 100644 index 0000000..7ca0e0f --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/Models/CurveType.cs @@ -0,0 +1,17 @@ +namespace Solana.Unity.Programs.TokenSwap.Models +{ + /// + /// Curve type enum for an instruction + /// + public enum CurveType + { + /// Uniswap-style constant product curve, invariant = token_a_amount * token_b_amount + ConstantProduct = 0, + /// Flat line, always providing 1:1 from one token to another + ConstantPrice = 1, + /// Stable, like uniswap, but with wide zone of 1:1 instead of one point + Stable = 2, + /// Offset curve, like Uniswap, but the token B side has a faked offset + Offset = 3, + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/Models/CurveType.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/Models/CurveType.cs.meta new file mode 100644 index 0000000..2978cad --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/Models/CurveType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d159848ddf14a644b89c4f3beb4f33f0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/Models/Fees.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/Models/Fees.cs new file mode 100644 index 0000000..125e0e9 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/Models/Fees.cs @@ -0,0 +1,92 @@ +using System; +using System.Buffers.Binary; +using Solana.Unity.Programs.Utilities; + +namespace Solana.Unity.Programs.TokenSwap.Models +{ + /// + /// Encapsulates all fee information and calculations for swap operations + /// + public class Fees + { + /// + /// Trade fee numerator. + /// + public ulong TradeFeeNumerator; + + /// + /// Trade fee denominator. + /// + public ulong TradeFeeDenominator; + + /// + /// Owner trade fee numerator. + /// + public ulong OwnerTradeFeeNumerator; + + /// + /// Owner trade fee denominator. + /// + public ulong OwnerTradeFeeDenomerator; + + /// + /// Owner withdraw fee numerator. + /// + public ulong OwnerWithrawFeeNumerator; + + /// + /// Owner withdraw fee denominator. + /// + public ulong OwnerWithrawFeeDenomerator; + + /// + /// Host trading fee numerator. + /// + public ulong HostFeeNumerator; + + /// + /// Host trading fee denominator. + /// + public ulong HostFeeDenomerator; + + /// + /// Serialize the Fees + /// + /// Serialized Fees + public Span Serialize() + { + var ret = new byte[64]; + ret.WriteU64(TradeFeeNumerator, 0); + ret.WriteU64(TradeFeeDenominator, 8); + ret.WriteU64(OwnerTradeFeeNumerator, 16); + ret.WriteU64(OwnerTradeFeeDenomerator, 24); + ret.WriteU64(OwnerWithrawFeeNumerator, 32); + ret.WriteU64(OwnerWithrawFeeDenomerator, 40); + ret.WriteU64(HostFeeNumerator, 48); + ret.WriteU64(HostFeeDenomerator, 56); + return new Span(ret); + } + + /// + /// Deserializes the Fees struct from binary. + /// + /// The payload to decode. + /// The decoded Fee object. + public static Fees Deserialize(byte[] bytes) + { + var span = new Span(bytes); + var f = new Fees() + { + TradeFeeNumerator = BinaryPrimitives.ReadUInt64LittleEndian(span.Slice(0, 8)), + TradeFeeDenominator = BinaryPrimitives.ReadUInt64LittleEndian(span.Slice(8, 8)), + OwnerTradeFeeNumerator = BinaryPrimitives.ReadUInt64LittleEndian(span.Slice(16, 8)), + OwnerTradeFeeDenomerator = BinaryPrimitives.ReadUInt64LittleEndian(span.Slice(24, 8)), + OwnerWithrawFeeNumerator = BinaryPrimitives.ReadUInt64LittleEndian(span.Slice(32, 8)), + OwnerWithrawFeeDenomerator = BinaryPrimitives.ReadUInt64LittleEndian(span.Slice(40, 8)), + HostFeeNumerator = BinaryPrimitives.ReadUInt64LittleEndian(span.Slice(48, 8)), + HostFeeDenomerator = BinaryPrimitives.ReadUInt64LittleEndian(span.Slice(56, 8)), + }; + return f; + } + } +} diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/Models/Fees.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/Models/Fees.cs.meta new file mode 100644 index 0000000..37e502a --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/Models/Fees.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bf8640193a429ff47894c3bbc627328b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/Models/SwapCurve.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/Models/SwapCurve.cs new file mode 100644 index 0000000..84003bb --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/Models/SwapCurve.cs @@ -0,0 +1,64 @@ +using Solana.Unity.Programs.Utilities; +using System; +using System.Buffers.Binary; + +namespace Solana.Unity.Programs.TokenSwap.Models +{ + /// + /// A swap curve type of a token swap. The static construction methods should be used to construct + /// + public class SwapCurve + { + /// + /// The constant procuct curve + /// + public static SwapCurve ConstantProduct => new SwapCurve() { CurveType = CurveType.ConstantProduct, Calculator = new ConstantProductCurve() }; + + /// + /// The curve type. + /// + public CurveType CurveType { get; set; } + + /// + /// The calculator used + /// + public CurveCalculator Calculator { get; set; } + + /// + /// Create a swap curve class. Protected as factory methods should be used to create + /// + protected SwapCurve() { } + + /// + /// Serialize this swap curve for an instruction + /// + /// + public virtual ReadOnlySpan Serialize() + { + var ret = new byte[33]; + ret.WriteU8((byte)CurveType, 0); + ret.WriteSpan(Calculator.Serialize(), 1); + return new Span(ret); + } + + /// + /// Deserializes the SwapCurve object from binary. + /// + /// The payload to decode. + /// The decoded SwapCurve object. + public static SwapCurve Deserialize(byte[] bytes) + { + var s = new SwapCurve() + { + CurveType = (CurveType)bytes[0], + //todo other curves + Calculator = new ConstantProductCurve() + }; + if (s.CurveType != CurveType.ConstantProduct) + { + throw new NotSupportedException("Only constant product curves are supported by Solnet currently"); + } + return s; + } + } +} diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/Models/SwapCurve.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/Models/SwapCurve.cs.meta new file mode 100644 index 0000000..e9890f8 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/Models/SwapCurve.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 607d7b1d15eb5bb4fa40c99fdbbc9bf7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/Models/TokenSwapAccount.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/Models/TokenSwapAccount.cs new file mode 100644 index 0000000..12ea564 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/Models/TokenSwapAccount.cs @@ -0,0 +1,122 @@ +using Solana.Unity.Programs.Utilities; +using Solana.Unity.Wallet; + +namespace Solana.Unity.Programs.TokenSwap.Models +{ + + /// + /// TokenSwap program state + /// + public class TokenSwapAccount + { + /// + /// the size of this account in bytes + /// + public const int TOKEN_SWAP_DATA_LEN = 324; + + /// + /// Versions of this state account + /// + public enum SwapVersion + { + /// + /// Version 1. + /// + SwapV1 = 1 + } + + /// + /// Version of this state account + /// + public SwapVersion Version; + + /// + /// Initialized state + /// + public bool IsInitialized; + + /// + /// Nonce used in program address. + /// The program address is created deterministically with the nonce, + /// swap program id, and swap account pubkey. This program address has + /// authority over the swap's token A account, token B account, and pool + /// token mint. + /// + public byte Nonce; + + /// + /// Program ID of the tokens being exchanged. + /// + public PublicKey TokenProgramId; + + /// + /// Token A + /// + public PublicKey TokenAAccount; + + /// + /// Token B + /// + public PublicKey TokenBAccount; + + /// + /// Pool tokens are issued when A or B tokens are deposited. + /// Pool tokens can be withdrawn back to the original A or B token. + /// + public PublicKey PoolMint; + + /// + /// Mint information for token A + /// + public PublicKey TokenAMint; + + /// + /// Mint information for token B + /// + public PublicKey TokenBMint; + + /// + /// Pool token account to receive trading and / or withdrawal fees + /// + public PublicKey PoolFeeAccount; + + /// + /// All fee information + /// + public Fees Fees; + + /// + /// Swap curve parameters, to be unpacked and used by the SwapCurve, which + /// calculates swaps, deposits, and withdrawals + /// + public SwapCurve SwapCurve; + + /// + /// Deserilize a token swap from the bytes of an account + /// + /// + /// + public static TokenSwapAccount Deserialize(byte[] data) + { + if (data.Length != TOKEN_SWAP_DATA_LEN) + return null; + + var ret = new TokenSwapAccount() + { + Version = SwapVersion.SwapV1, + IsInitialized = data[1] == 1, + Nonce = data[2], + TokenProgramId = new PublicKey(data.Slice(3, 35)), + TokenAAccount = new PublicKey(data.Slice(35, 67)), + TokenBAccount = new PublicKey(data.Slice(67, 99)), + PoolMint = new PublicKey(data.Slice(99, 131)), + TokenAMint = new PublicKey(data.Slice(131, 163)), + TokenBMint = new PublicKey(data.Slice(163, 195)), + PoolFeeAccount = new PublicKey(data.Slice(195, 227)), + Fees = Fees.Deserialize(data.Slice(227, 291)), + SwapCurve = SwapCurve.Deserialize(data.Slice(291)), + }; + return ret; + } + } +} diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/Models/TokenSwapAccount.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/Models/TokenSwapAccount.cs.meta new file mode 100644 index 0000000..43b1ce9 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/Models/TokenSwapAccount.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 644b41c35474d3d4783cb2c03c96eba1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/TokenSwapProgram.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/TokenSwapProgram.cs new file mode 100644 index 0000000..c5550b8 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/TokenSwapProgram.cs @@ -0,0 +1,405 @@ +using Solana.Unity.Programs.Utilities; +using Solana.Unity.Programs.Abstract; +using Solana.Unity.Programs.TokenSwap.Models; +using Solana.Unity.Rpc.Models; +using Solana.Unity.Rpc.Utilities; +using Solana.Unity.Wallet; +using System; +using System.Collections.Generic; + +namespace Solana.Unity.Programs.TokenSwap +{ + /// + /// Implements the Token Swap Program methods. + /// + /// For more information see: + /// https://spl.solana.com/token-swap + /// https://docs.rs/spl-token-swap/2.1.0/spl_token_swap/ + /// + /// + public class TokenSwapProgram : BaseProgram + { + /// + /// SPL Token Swap Program Program ID + /// + public static readonly PublicKey TokenSwapProgramIdKey = new("SwaPpA9LAaLfeLi3a68M4DjnLqgtticKg6CnyNwgAC8"); + + /// + /// SPL Token Swap Program Program Name + /// + public static readonly string TokenSwapProgramName = "Token Swap Program"; + + + //instance vars + + /// + /// The owner key required to use as the fee account owner. + /// + public virtual PublicKey OwnerKey => new("HfoTxFR1Tm6kGmWgYWD6J7YHVy1UwqSULUGVLXkJqaKN"); + + /// + /// Token Swap account layout size. + /// + public static readonly ulong TokenSwapAccountDataSize = 323; + + /// + /// Create a token swap program instance with the standard programid and program name + /// + public TokenSwapProgram() : base(TokenSwapProgramIdKey, TokenSwapProgramName) { } + + /// + /// Create a token swap program instance with a custom programid + /// + /// The program id to use + public TokenSwapProgram(PublicKey programId) : base(programId, TokenSwapProgramName) { } + + /// + /// Create the authority + /// + /// The swap authority + /// No program account could be found (exhausted nonces) + public virtual (PublicKey pubkey, byte nonce) CreateAuthority(PublicKey tokenSwapAccount) + { + if (!PublicKey.TryFindProgramAddress(new[] { tokenSwapAccount.KeyBytes }, ProgramIdKey, out var auth, out var nonce)) + throw new InvalidProgramException(); + return (auth, nonce); + } + + /// + /// Initializes a new swap. + /// + /// The token swap account to initialize. + /// token_a Account. Must be non zero, owned by swap authority. + /// token_b Account. Must be non zero, owned by swap authority. + /// Pool Token Mint. Must be empty, owned by swap authority. + /// Pool Token Account to deposit trading and withdraw fees. Must be empty, not owned by swap authority. + /// Pool Token Account to deposit the initial pool token supply. Must be empty, not owned by swap authority. + /// Fees to use for this token swap. + /// Curve to use for this token swap. + /// The transaction instruction. + public virtual TransactionInstruction Initialize( + PublicKey tokenSwapAccount, + PublicKey tokenAAccount, + PublicKey tokenBAccount, + PublicKey poolTokenMint, + PublicKey poolTokenFeeAccount, + PublicKey userPoolTokenAccount, + Fees fees, SwapCurve swapCurve) + { + var (swapAuthority, nonce) = CreateAuthority(tokenSwapAccount); + List keys = new() + { + AccountMeta.Writable(tokenSwapAccount, true), + AccountMeta.ReadOnly(swapAuthority, false), + AccountMeta.ReadOnly(tokenAAccount, false), + AccountMeta.ReadOnly(tokenBAccount, false), + AccountMeta.Writable(poolTokenMint, false), + AccountMeta.ReadOnly(poolTokenFeeAccount, false), + AccountMeta.Writable(userPoolTokenAccount, false), + AccountMeta.ReadOnly(TokenProgram.ProgramIdKey, false), + }; + return new TransactionInstruction + { + ProgramId = ProgramIdKey.KeyBytes, + Keys = keys, + Data = TokenSwapProgramData.EncodeInitializeData(nonce, fees, swapCurve) + }; + } + + /// + /// Swap the tokens in the pool. + /// + /// The token swap account to operate over. + /// user transfer authority. + /// token_(A|B) SOURCE Account, amount is transferable by user transfer authority. + /// token_(A|B) Base Account to swap INTO. Must be the SOURCE token. + /// token_(A|B) Base Account to swap FROM. Must be the DESTINATION token. + /// token_(A|B) DESTINATION Account assigned to USER as the owner. + /// Pool token mint, to generate trading fees. + /// Fee account, to receive trading fees. + /// Host fee account to receive additional trading fees. + /// SOURCE amount to transfer, output to DESTINATION is based on the exchange rate. + /// Minimum amount of DESTINATION token to output, prevents excessive slippage. + /// The transaction instruction. + public virtual TransactionInstruction Swap( + PublicKey tokenSwapAccount, + PublicKey userTransferAuthority, + PublicKey tokenSourceAccount, + PublicKey tokenBaseIntoAccount, + PublicKey tokenBaseFromAccount, + PublicKey tokenDestinationAccount, + PublicKey poolTokenMint, + PublicKey poolTokenFeeAccount, + PublicKey poolTokenHostFeeAccount, + ulong amountIn, ulong amountOut) + { + var (swapAuthority, nonce) = CreateAuthority(tokenSwapAccount); + List keys = new() + { + AccountMeta.ReadOnly(tokenSwapAccount, false), + AccountMeta.ReadOnly(swapAuthority, false), + AccountMeta.ReadOnly(userTransferAuthority, false), + AccountMeta.Writable(tokenSourceAccount, false), + AccountMeta.Writable(tokenBaseIntoAccount, false), + AccountMeta.Writable(tokenBaseFromAccount, false), + AccountMeta.Writable(tokenDestinationAccount, false), + AccountMeta.Writable(poolTokenMint, false), + AccountMeta.Writable(poolTokenFeeAccount, false), + AccountMeta.ReadOnly(TokenProgram.ProgramIdKey, false), + }; + if (poolTokenHostFeeAccount != null) + { + keys.Add(AccountMeta.Writable(poolTokenHostFeeAccount, false)); + } + return new TransactionInstruction + { + ProgramId = ProgramIdKey.KeyBytes, + Keys = keys, + Data = TokenSwapProgramData.EncodeSwapData(amountIn, amountOut) + }; + } + + /// + /// Deposit both types of tokens into the pool. The output is a "pool" + /// token representing ownership in the pool. Inputs are converted to + /// the current ratio. + /// + /// The token swap account to operate over. + /// user transfer authority. + /// token_a - user transfer authority can transfer amount. + /// token_b - user transfer authority can transfer amount. + /// token_a Base Account to deposit into. + /// token_b Base Account to deposit into. + /// Pool MINT account, swap authority is the owner. + /// Pool Account to deposit the generated tokens, user is the owner. + /// Pool token amount to transfer. token_a and token_b amount are set by the current exchange rate and size of the pool. + /// Maximum token A amount to deposit, prevents excessive slippage. + /// Maximum token B amount to deposit, prevents excessive slippage. + /// The transaction instruction. + public virtual TransactionInstruction DepositAllTokenTypes( + PublicKey tokenSwapAccount, + PublicKey userTransferAuthority, + PublicKey tokenAuserAccount, + PublicKey tokenBuserAccount, + PublicKey tokenADepositAccount, + PublicKey tokenBDepositAccount, + PublicKey poolTokenMint, + PublicKey poolTokenUserAccount, + ulong poolTokenAmount, ulong maxTokenA, ulong maxTokenB) + { + var (swapAuthority, nonce) = CreateAuthority(tokenSwapAccount); + List keys = new() + { + AccountMeta.ReadOnly(tokenSwapAccount, false), + AccountMeta.ReadOnly(swapAuthority, false), + AccountMeta.ReadOnly(userTransferAuthority, false), + AccountMeta.Writable(tokenAuserAccount, false), + AccountMeta.Writable(tokenBuserAccount, false), + AccountMeta.Writable(tokenADepositAccount, false), + AccountMeta.Writable(tokenBDepositAccount, false), + AccountMeta.Writable(poolTokenMint, false), + AccountMeta.Writable(poolTokenUserAccount, false), + AccountMeta.ReadOnly(TokenProgram.ProgramIdKey, false), + }; + return new TransactionInstruction + { + ProgramId = ProgramIdKey.KeyBytes, + Keys = keys, + Data = TokenSwapProgramData.EncodeDepositAllTokenTypesData(poolTokenAmount, maxTokenA, maxTokenB) + }; + } + + /// + /// Withdraw both types of tokens from the pool at the current ratio, given + /// pool tokens. The pool tokens are burned in exchange for an equivalent + /// amount of token A and B. + /// + /// The token swap account to operate over. + /// user transfer authority. + /// Pool MINT account, swap authority is the owner. + /// SOURCE Pool account, amount is transferable by user transfer authority. + /// token_a Swap Account to withdraw FROM. + /// token_b Swap Account to withdraw FROM. + /// token_a user Account to credit. + /// token_b user Account to credit. + /// Fee account, to receive withdrawal fees. + /// Amount of pool tokens to burn. User receives an output of token a and b based on the percentage of the pool tokens that are returned. + /// Minimum amount of token A to receive, prevents excessive slippage. + /// Minimum amount of token B to receive, prevents excessive slippage. + /// The transaction instruction. + public virtual TransactionInstruction WithdrawAllTokenTypes( + PublicKey tokenSwapAccount, + PublicKey userTransferAuthority, + PublicKey poolTokenMint, + PublicKey sourcePoolAccount, + PublicKey tokenASwapAccount, + PublicKey tokenBSwapAccount, + PublicKey tokenAUserAccount, + PublicKey tokenBUserAccount, + PublicKey feeAccount, + ulong poolTokenAmount, ulong minTokenA, ulong minTokenB) + { + var (swapAuthority, nonce) = CreateAuthority(tokenSwapAccount); + List keys = new() + { + AccountMeta.ReadOnly(tokenSwapAccount, false), + AccountMeta.ReadOnly(swapAuthority, false), + AccountMeta.ReadOnly(userTransferAuthority, false), + AccountMeta.Writable(poolTokenMint, false), + AccountMeta.Writable(sourcePoolAccount, false), + AccountMeta.Writable(tokenASwapAccount, false), + AccountMeta.Writable(tokenBSwapAccount, false), + AccountMeta.Writable(tokenAUserAccount, false), + AccountMeta.Writable(tokenBUserAccount, false), + AccountMeta.Writable(feeAccount, false), + AccountMeta.ReadOnly(TokenProgram.ProgramIdKey, false), + }; + return new TransactionInstruction + { + ProgramId = ProgramIdKey.KeyBytes, + Keys = keys, + Data = TokenSwapProgramData.EncodeWithdrawAllTokenTypesData(poolTokenAmount, minTokenA, minTokenB) + }; + } + + /// + /// Deposit one type of tokens into the pool. The output is a "pool" token + /// representing ownership into the pool. Input token is converted as if + /// a swap and deposit all token types were performed. + /// + /// The token swap account to operate over. + /// user transfer authority. + /// token_(A|B) SOURCE Account, amount is transferable by user transfer authority. + /// token_a Swap Account, may deposit INTO. + /// token_b Swap Account, may deposit INTO. + /// Pool MINT account, swap authority is the owner. + /// Pool Account to deposit the generated tokens, user is the owner. + /// Token amount to deposit. + /// Pool token amount to receive in exchange. The amount is set by the current exchange rate and size of the pool. + /// The transaction instruction. + public virtual TransactionInstruction DepositSingleTokenTypeExactAmountIn( + PublicKey tokenSwapAccount, + PublicKey userTransferAuthority, + PublicKey sourceAccount, + PublicKey destinationTokenAAccount, + PublicKey destinationTokenBAccount, + PublicKey poolMintAccount, + PublicKey poolTokenUserAccount, + ulong sourceTokenAmount, ulong minPoolTokenAmount) + { + var (swapAuthority, nonce) = CreateAuthority(tokenSwapAccount); + List keys = new() + { + AccountMeta.ReadOnly(tokenSwapAccount, false), + AccountMeta.ReadOnly(swapAuthority, false), + AccountMeta.ReadOnly(userTransferAuthority, false), + AccountMeta.Writable(sourceAccount, false), + AccountMeta.Writable(destinationTokenAAccount, false), + AccountMeta.Writable(destinationTokenBAccount, false), + AccountMeta.Writable(poolMintAccount, false), + AccountMeta.Writable(poolTokenUserAccount, false), + AccountMeta.ReadOnly(TokenProgram.ProgramIdKey, false), + }; + return new TransactionInstruction + { + ProgramId = ProgramIdKey.KeyBytes, + Keys = keys, + Data = TokenSwapProgramData.EncodeDepositSingleTokenTypeExactAmountInData(sourceTokenAmount, minPoolTokenAmount) + }; + } + + /// + /// Withdraw one token type from the pool at the current ratio given the + /// exact amount out expected. + /// + /// The token swap account to operate over. + /// user transfer authority. + /// Pool mint account, swap authority is the owner. + /// SOURCE Pool account, amount is transferable by user transfer authority. + /// token_a Swap Account to potentially withdraw from. + /// token_b Swap Account to potentially withdraw from. + /// token_(A|B) User Account to credit. + /// Fee account, to receive withdrawal fees. + /// Amount of token A or B to receive. + /// Maximum amount of pool tokens to burn. User receives an output of token A or B based on the percentage of the pool tokens that are returned. + /// The transaction instruction. + public virtual TransactionInstruction WithdrawSingleTokenTypeExactAmountOut( + PublicKey tokenSwapAccount, + PublicKey userTransferAuthority, + PublicKey poolMintAccount, + PublicKey sourceUserAccount, + PublicKey tokenASwapAccount, + PublicKey tokenBSwapAccount, + PublicKey tokenUserAccount, + PublicKey feeAccount, + ulong destTokenAmount, ulong maxPoolTokenAmount) + { + var (swapAuthority, nonce) = CreateAuthority(tokenSwapAccount); + List keys = new() + { + AccountMeta.ReadOnly(tokenSwapAccount, false), + AccountMeta.ReadOnly(swapAuthority, false), + AccountMeta.ReadOnly(userTransferAuthority, false), + AccountMeta.Writable(poolMintAccount, false), + AccountMeta.Writable(sourceUserAccount, false), + AccountMeta.Writable(tokenASwapAccount, false), + AccountMeta.Writable(tokenBSwapAccount, false), + AccountMeta.Writable(tokenUserAccount, false), + AccountMeta.Writable(feeAccount, false), + AccountMeta.ReadOnly(TokenProgram.ProgramIdKey, false), + }; + return new TransactionInstruction + { + ProgramId = ProgramIdKey.KeyBytes, + Keys = keys, + Data = TokenSwapProgramData.EncodeWithdrawSingleTokenTypeExactAmountOutData(destTokenAmount, maxPoolTokenAmount) + }; + } + + /// + /// Decodes an instruction created by the System Program. + /// + /// The instruction data to decode. + /// The account keys present in the transaction. + /// The indices of the account keys for the instruction as they appear in the transaction. + /// A decoded instruction. + public static DecodedInstruction Decode(ReadOnlySpan data, IList keys, byte[] keyIndices) + { + uint instruction = data.GetU8(TokenProgramData.MethodOffset); + TokenSwapProgramInstructions.Values instructionValue = + (TokenSwapProgramInstructions.Values)Enum.Parse(typeof(TokenSwapProgramInstructions.Values), instruction.ToString()); + + DecodedInstruction decodedInstruction = new() + { + PublicKey = TokenSwapProgram.TokenSwapProgramIdKey, + InstructionName = TokenSwapProgramInstructions.Names[instructionValue], + ProgramName = TokenSwapProgram.TokenSwapProgramName, + Values = new Dictionary(), + InnerInstructions = new List() + }; + + switch (instructionValue) + { + case TokenSwapProgramInstructions.Values.Initialize: + TokenSwapProgramData.DecodeInitializeData(decodedInstruction, data, keys, keyIndices); + break; + case TokenSwapProgramInstructions.Values.Swap: + TokenSwapProgramData.DecodeSwapData(decodedInstruction, data, keys, keyIndices); + break; + case TokenSwapProgramInstructions.Values.DepositAllTokenTypes: + TokenSwapProgramData.DecodeDepositAllTokenTypesData(decodedInstruction, data, keys, keyIndices); + break; + case TokenSwapProgramInstructions.Values.WithdrawAllTokenTypes: + TokenSwapProgramData.DecodeWithdrawAllTokenTypesData(decodedInstruction, data, keys, keyIndices); + break; + case TokenSwapProgramInstructions.Values.DepositSingleTokenTypeExactAmountIn: + TokenSwapProgramData.DecodeDepositSingleTokenTypeExactAmountInData(decodedInstruction, data, keys, keyIndices); + break; + case TokenSwapProgramInstructions.Values.WithdrawSingleTokenTypeExactAmountOut: + TokenSwapProgramData.DecodeWithdrawSingleTokenTypeExactAmountOutData(decodedInstruction, data, keys, keyIndices); + break; + } + return decodedInstruction; + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/TokenSwapProgram.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/TokenSwapProgram.cs.meta new file mode 100644 index 0000000..c393569 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/TokenSwapProgram.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 829e1da16fdb75449ad2e625c92de320 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/TokenSwapProgramData.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/TokenSwapProgramData.cs new file mode 100644 index 0000000..30a7958 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/TokenSwapProgramData.cs @@ -0,0 +1,286 @@ +using Solana.Unity.Programs.Utilities; +using Solana.Unity.Programs.TokenSwap.Models; +using Solana.Unity.Wallet; +using System; +using System.Collections.Generic; + +namespace Solana.Unity.Programs.TokenSwap +{ + /// + /// Implements the token swap program data encodings. + /// + internal static class TokenSwapProgramData + { + /// + /// Encode the transaction instruction data for the method. + /// + /// nonce used to create valid program address. + /// all swap fees. + /// swap curve info for pool, including CurveType and anything else that may be required. + /// The freezeAuthorityOption parameter is related to the existence or not of a freeze authority. + /// The byte array with the encoded data. + internal static byte[] EncodeInitializeData(byte nonce, Fees fees, SwapCurve swapCurve) + { + byte[] methodBuffer = new byte[99]; + + methodBuffer.WriteU8((byte)TokenSwapProgramInstructions.Values.Initialize, 0); + methodBuffer.WriteU8(nonce, 1); + methodBuffer.WriteSpan(fees.Serialize(), 2); + methodBuffer.WriteSpan(swapCurve.Serialize(), 66); + + return methodBuffer; + } + + /// + /// Encode the transaction instruction data for the method. + /// + /// The amount of tokens in. + /// The amount of tokens out. + /// The byte array with the encoded data. + internal static byte[] EncodeSwapData(ulong amountIn, ulong amountOut) + { + byte[] methodBuffer = new byte[17]; + + methodBuffer.WriteU8((byte)TokenSwapProgramInstructions.Values.Swap, 0); + methodBuffer.WriteU64(amountIn, 1); + methodBuffer.WriteU64(amountOut, 9); + + return methodBuffer; + } + + /// + /// Encode the transaction instruction data for the method. + /// + /// The amount of tokens out. + /// The max amount of tokens A. + /// The max amount of tokens B. + /// The byte array with the encoded data. + internal static byte[] EncodeDepositAllTokenTypesData(ulong poolTokenAmount, ulong maxTokenAAmount, ulong maxTokenBAmount) + { + byte[] methodBuffer = new byte[25]; + + methodBuffer.WriteU8((byte)TokenSwapProgramInstructions.Values.DepositAllTokenTypes, 0); + methodBuffer.WriteU64(poolTokenAmount, 1); + methodBuffer.WriteU64(maxTokenAAmount, 9); + methodBuffer.WriteU64(maxTokenBAmount, 17); + + return methodBuffer; + } + + /// + /// Encode the transaction instruction data for the method. + /// + /// The amount of tokens in. + /// The maminx amount of tokens A. + /// The min amount of tokens B. + /// The byte array with the encoded data. + internal static byte[] EncodeWithdrawAllTokenTypesData(ulong poolTokenAmount, ulong minTokenAAmount, ulong minTokenBAmount) + { + byte[] methodBuffer = new byte[25]; + + methodBuffer.WriteU8((byte)TokenSwapProgramInstructions.Values.WithdrawAllTokenTypes, 0); + methodBuffer.WriteU64(poolTokenAmount, 1); + methodBuffer.WriteU64(minTokenAAmount, 9); + methodBuffer.WriteU64(minTokenBAmount, 17); + + return methodBuffer; + } + + /// + /// Encode the transaction instruction data for the method. + /// + /// The amount of tokens in. + /// The min amount of pool tokens out. + /// The byte array with the encoded data. + internal static byte[] EncodeDepositSingleTokenTypeExactAmountInData(ulong sourceTokenAmount, ulong minPoolTokenAmount) + { + byte[] methodBuffer = new byte[17]; + + methodBuffer.WriteU8((byte)TokenSwapProgramInstructions.Values.DepositSingleTokenTypeExactAmountIn, 0); + methodBuffer.WriteU64(sourceTokenAmount, 1); + methodBuffer.WriteU64(minPoolTokenAmount, 9); + + return methodBuffer; + } + + /// + /// Encode the transaction instruction data for the method. + /// + /// The amount of tokens out. + /// The max amount of pool tokens in. + /// The byte array with the encoded data. + internal static byte[] EncodeWithdrawSingleTokenTypeExactAmountOutData(ulong destTokenAmount, ulong maxPoolTokenAmount) + { + byte[] methodBuffer = new byte[17]; + + methodBuffer.WriteU8((byte)TokenSwapProgramInstructions.Values.WithdrawSingleTokenTypeExactAmountOut, 0); + methodBuffer.WriteU64(destTokenAmount, 1); + methodBuffer.WriteU64(maxPoolTokenAmount, 9); + + return methodBuffer; + } + + /// + /// Decodes the instruction instruction data for the method + /// + /// The decoded instruction to add data to. + /// The instruction data to decode. + /// The account keys present in the transaction. + /// The indices of the account keys for the instruction as they appear in the transaction. + internal static void DecodeInitializeData(DecodedInstruction decodedInstruction, ReadOnlySpan data, + IList keys, byte[] keyIndices) + { + decodedInstruction.Values.Add("Token Swap Account", keys[keyIndices[0]]); + decodedInstruction.Values.Add("Swap Authority", keys[keyIndices[1]]); + decodedInstruction.Values.Add("Token A Account", keys[keyIndices[2]]); + decodedInstruction.Values.Add("Token B Account", keys[keyIndices[3]]); + decodedInstruction.Values.Add("Pool Token Mint", keys[keyIndices[4]]); + decodedInstruction.Values.Add("Pool Token Fee Account", keys[keyIndices[5]]); + decodedInstruction.Values.Add("Pool Token Account", keys[keyIndices[6]]); + decodedInstruction.Values.Add("Token Program ID", keys[keyIndices[7]]); + + decodedInstruction.Values.Add("Nonce", data.GetU8(1)); + decodedInstruction.Values.Add("Trade Fee Numerator", data.GetU64(2)); + decodedInstruction.Values.Add("Trade Fee Denominator", data.GetU64(10)); + decodedInstruction.Values.Add("Owner Trade Fee Numerator", data.GetU64(18)); + decodedInstruction.Values.Add("Owner Trade Fee Denominator", data.GetU64(26)); + decodedInstruction.Values.Add("Owner Withraw Fee Numerator", data.GetU64(34)); + decodedInstruction.Values.Add("Owner Withraw Fee Denominator", data.GetU64(42)); + decodedInstruction.Values.Add("Host Fee Numerator", data.GetU64(50)); + decodedInstruction.Values.Add("Host Fee Denominator", data.GetU64(58)); + decodedInstruction.Values.Add("Curve Type", data.GetU64(59)); + //nothing to show for calculator unless hardcoding the switch stmt + } + + /// + /// Decodes the instruction instruction data for the method + /// + /// The decoded instruction to add data to. + /// The instruction data to decode. + /// The account keys present in the transaction. + /// The indices of the account keys for the instruction as they appear in the transaction. + internal static void DecodeSwapData(DecodedInstruction decodedInstruction, ReadOnlySpan data, + IList keys, byte[] keyIndices) + { + decodedInstruction.Values.Add("Token Swap Account", keys[keyIndices[0]]); + decodedInstruction.Values.Add("Swap Authority", keys[keyIndices[1]]); + decodedInstruction.Values.Add("User Transfer Authority", keys[keyIndices[2]]); + decodedInstruction.Values.Add("User Source Account", keys[keyIndices[3]]); + decodedInstruction.Values.Add("Token Base Into Account", keys[keyIndices[4]]); + decodedInstruction.Values.Add("Token Base From Account", keys[keyIndices[5]]); + decodedInstruction.Values.Add("User Destination Account", keys[keyIndices[6]]); + decodedInstruction.Values.Add("Pool Token Mint", keys[keyIndices[7]]); + decodedInstruction.Values.Add("Fee Account", keys[keyIndices[8]]); + decodedInstruction.Values.Add("Token Program ID", keys[keyIndices[9]]); + if (keyIndices.Length >= 11) + { + decodedInstruction.Values.Add("Host Fee Account", keys[keyIndices[10]]); + } + + decodedInstruction.Values.Add("Amount In", data.GetU64(1)); + decodedInstruction.Values.Add("Amount Out", data.GetU64(9)); + } + + /// + /// Decodes the instruction instruction data for the method + /// + /// The decoded instruction to add data to. + /// The instruction data to decode. + /// The account keys present in the transaction. + /// The indices of the account keys for the instruction as they appear in the transaction. + internal static void DecodeDepositAllTokenTypesData(DecodedInstruction decodedInstruction, ReadOnlySpan data, + IList keys, byte[] keyIndices) + { + decodedInstruction.Values.Add("Token Swap Account", keys[keyIndices[0]]); + decodedInstruction.Values.Add("Swap Authority", keys[keyIndices[1]]); + decodedInstruction.Values.Add("User Transfer Authority", keys[keyIndices[2]]); + decodedInstruction.Values.Add("User Token A Account", keys[keyIndices[3]]); + decodedInstruction.Values.Add("User Token B Account", keys[keyIndices[4]]); + decodedInstruction.Values.Add("Pool Token A Account", keys[keyIndices[5]]); + decodedInstruction.Values.Add("Pool Token B Account", keys[keyIndices[6]]); + decodedInstruction.Values.Add("Pool Token Mint", keys[keyIndices[7]]); + decodedInstruction.Values.Add("User Pool Token Account", keys[keyIndices[8]]); + decodedInstruction.Values.Add("Token Program ID", keys[keyIndices[9]]); + + decodedInstruction.Values.Add("Pool Tokens", data.GetU64(1)); + decodedInstruction.Values.Add("Max Token A", data.GetU64(9)); + decodedInstruction.Values.Add("Max Token B", data.GetU64(17)); + } + + /// + /// Decodes the instruction instruction data for the method + /// + /// The decoded instruction to add data to. + /// The instruction data to decode. + /// The account keys present in the transaction. + /// The indices of the account keys for the instruction as they appear in the transaction. + internal static void DecodeWithdrawAllTokenTypesData(DecodedInstruction decodedInstruction, ReadOnlySpan data, + IList keys, byte[] keyIndices) + { + decodedInstruction.Values.Add("Token Swap Account", keys[keyIndices[0]]); + decodedInstruction.Values.Add("Swap Authority", keys[keyIndices[1]]); + decodedInstruction.Values.Add("User Transfer Authority", keys[keyIndices[2]]); + decodedInstruction.Values.Add("Pool Token Account", keys[keyIndices[3]]); + decodedInstruction.Values.Add("User Pool Token Account", keys[keyIndices[4]]); + decodedInstruction.Values.Add("Pool Token A Account", keys[keyIndices[5]]); + decodedInstruction.Values.Add("Pool Token B Account", keys[keyIndices[6]]); + decodedInstruction.Values.Add("User Token A Account", keys[keyIndices[7]]); + decodedInstruction.Values.Add("User Token B Account", keys[keyIndices[8]]); + decodedInstruction.Values.Add("Fee Account", keys[keyIndices[9]]); + decodedInstruction.Values.Add("Token Program ID", keys[keyIndices[10]]); + + decodedInstruction.Values.Add("Pool Tokens", data.GetU64(1)); + decodedInstruction.Values.Add("Min Token A", data.GetU64(9)); + decodedInstruction.Values.Add("Min Token B", data.GetU64(17)); + } + + /// + /// Decodes the instruction instruction data for the method + /// + /// The decoded instruction to add data to. + /// The instruction data to decode. + /// The account keys present in the transaction. + /// The indices of the account keys for the instruction as they appear in the transaction. + internal static void DecodeDepositSingleTokenTypeExactAmountInData(DecodedInstruction decodedInstruction, ReadOnlySpan data, + IList keys, byte[] keyIndices) + { + decodedInstruction.Values.Add("Token Swap Account", keys[keyIndices[0]]); + decodedInstruction.Values.Add("Swap Authority", keys[keyIndices[1]]); + decodedInstruction.Values.Add("User Transfer Authority", keys[keyIndices[2]]); + decodedInstruction.Values.Add("User Source Token Account", keys[keyIndices[3]]); + decodedInstruction.Values.Add("Token A Swap Account", keys[keyIndices[4]]); + decodedInstruction.Values.Add("Token B Swap Account", keys[keyIndices[5]]); + decodedInstruction.Values.Add("Pool Mint Account", keys[keyIndices[6]]); + decodedInstruction.Values.Add("User Pool Token Account", keys[keyIndices[7]]); + decodedInstruction.Values.Add("Token Program ID", keys[keyIndices[8]]); + + decodedInstruction.Values.Add("Source Token Amount", data.GetU64(1)); + decodedInstruction.Values.Add("Min Pool Token Amount", data.GetU64(9)); + } + + /// + /// Decodes the instruction instruction data for the method + /// + /// The decoded instruction to add data to. + /// The instruction data to decode. + /// The account keys present in the transaction. + /// The indices of the account keys for the instruction as they appear in the transaction. + internal static void DecodeWithdrawSingleTokenTypeExactAmountOutData(DecodedInstruction decodedInstruction, ReadOnlySpan data, + IList keys, byte[] keyIndices) + { + decodedInstruction.Values.Add("Token Swap Account", keys[keyIndices[0]]); + decodedInstruction.Values.Add("Swap Authority", keys[keyIndices[1]]); + decodedInstruction.Values.Add("User Transfer Authority", keys[keyIndices[2]]); + decodedInstruction.Values.Add("Pool Mint Account", keys[keyIndices[3]]); + decodedInstruction.Values.Add("User Pool Token Account", keys[keyIndices[4]]); + decodedInstruction.Values.Add("Token A Swap Account", keys[keyIndices[5]]); + decodedInstruction.Values.Add("Token B Swap Account", keys[keyIndices[6]]); + decodedInstruction.Values.Add("User Token Account", keys[keyIndices[7]]); + decodedInstruction.Values.Add("Fee Account", keys[keyIndices[8]]); + decodedInstruction.Values.Add("Token Program ID", keys[keyIndices[9]]); + + decodedInstruction.Values.Add("Destination Token Amount", data.GetU64(1)); + decodedInstruction.Values.Add("Max Pool Token Amount", data.GetU64(9)); + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/TokenSwapProgramData.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/TokenSwapProgramData.cs.meta new file mode 100644 index 0000000..4f89420 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/TokenSwapProgramData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d2035fa368b2fe94aa2312fe14b4f0b6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/TokenSwapProgramInstructions.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/TokenSwapProgramInstructions.cs new file mode 100644 index 0000000..2ff874f --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/TokenSwapProgramInstructions.cs @@ -0,0 +1,65 @@ +using System.Collections.Generic; + +namespace Solana.Unity.Programs.TokenSwap +{ + /// + /// Represents the instruction types for the along with a friendly name so as not to use reflection. + /// + /// For more information see: + /// https://spl.solana.com/token-swap + /// https://docs.rs/spl-token-swap/2.1.0/spl_token_swap/ + /// + /// + internal static class TokenSwapProgramInstructions + { + /// + /// Represents the user-friendly names for the instruction types for the . + /// + internal static readonly Dictionary Names = new() + { + { Values.Initialize, "Initialize Swap" }, + { Values.Swap, "Swap" }, + { Values.DepositAllTokenTypes, "Deposit Both" }, + { Values.WithdrawAllTokenTypes, "Withdraw Both" }, + { Values.DepositSingleTokenTypeExactAmountIn, "Deposit Single" }, + { Values.WithdrawSingleTokenTypeExactAmountOut, "Withdraw Single" }, + }; + + /// + /// Represents the instruction types for the . + /// + internal enum Values : byte + { + /// + /// Initializes a new swap. + /// + Initialize = 0, + + /// + /// Swap the tokens in the pool. + /// + Swap = 1, + + /// + /// Deposit both types of tokens into the pool. + /// + DepositAllTokenTypes = 2, + + /// + /// Withdraw both types of tokens from the pool at the current ratio. + /// + WithdrawAllTokenTypes = 3, + + /// + /// Deposit one type of tokens into the pool. + /// + DepositSingleTokenTypeExactAmountIn = 4, + + /// + /// Withdraw one token type from the pool at the current ratio. + /// + WithdrawSingleTokenTypeExactAmountOut = 5, + + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/TokenSwapProgramInstructions.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/TokenSwapProgramInstructions.cs.meta new file mode 100644 index 0000000..b7fa52f --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/TokenSwap/TokenSwapProgramInstructions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 941ca58b222797441b69885eb9b1de54 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Utilities.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Utilities.meta new file mode 100644 index 0000000..8f563df --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Utilities.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f19e7c9dff9087e4f8f8b6c78d4b73ca +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Utilities/Deserialization.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Utilities/Deserialization.cs new file mode 100644 index 0000000..f7050ae --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Utilities/Deserialization.cs @@ -0,0 +1,275 @@ +using Solana.Unity.Wallet; +using System; +using System.Buffers.Binary; +using System.Diagnostics; +using System.Linq; +using System.Numerics; +using System.Text; + +namespace Solana.Unity.Programs.Utilities +{ + /// + /// Extension methods for deserialization of program data using . + /// + public static class Deserialization + { + /// + /// Get a 8-bit unsigned integer from the span at the given offset. + /// + /// The span to get data from. + /// The offset at which the 8-bit unsigned integer begins. + /// The 8-bit unsigned integer. + /// Thrown when the offset is too big for the span. + public static byte GetU8(this ReadOnlySpan data, int offset) + { + if (offset > data.Length - sizeof(byte)) + throw new ArgumentOutOfRangeException(nameof(offset)); + return data[offset]; + } + + /// + /// Get a 16-bit unsigned integer from the span at the given offset. + /// + /// The span to get data from. + /// The offset at which the 16-bit unsigned integer begins. + /// The 16-bit unsigned integer. + /// Thrown when the offset is too big for the span. + public static ushort GetU16(this ReadOnlySpan data, int offset) + { + if (offset + sizeof(ushort) > data.Length) + throw new ArgumentOutOfRangeException(nameof(offset)); + return BinaryPrimitives.ReadUInt16LittleEndian(data.Slice(offset, sizeof(ushort))); + } + + /// + /// Get a 32-bit unsigned integer from the span at the given offset. + /// + /// The span to get data from. + /// The offset at which the 32-bit unsigned integer begins. + /// The 32-bit unsigned integer. + /// Thrown when the offset is too big for the span. + public static uint GetU32(this ReadOnlySpan data, int offset) + { + if (offset + sizeof(uint) > data.Length) + throw new ArgumentOutOfRangeException(nameof(offset)); + return BinaryPrimitives.ReadUInt32LittleEndian(data.Slice(offset, sizeof(uint))); + } + + /// + /// Get a 64-bit unsigned integer from the span at the given offset. + /// + /// The span to get data from. + /// The offset at which the 64-bit unsigned integer begins. + /// The 64-bit unsigned integer. + /// Thrown when the offset is too big for the span. + public static ulong GetU64(this ReadOnlySpan data, int offset) + { + if (offset + sizeof(ulong) > data.Length) + throw new ArgumentOutOfRangeException(nameof(offset)); + return BinaryPrimitives.ReadUInt64LittleEndian(data.Slice(offset, sizeof(ulong))); + } + + /// + /// Get a 8-bit signed integer from the span at the given offset. + /// + /// The span to get data from. + /// The offset at which the 8-bit signed integer begins. + /// The 8-bit signed integer. + /// Thrown when the offset is too big for the span. + public static sbyte GetS8(this ReadOnlySpan data, int offset) + { + if (offset > data.Length - sizeof(sbyte)) + throw new ArgumentOutOfRangeException(nameof(offset)); + return (sbyte)data[offset]; + } + + /// + /// Get a 16-bit signed integer from the span at the given offset. + /// + /// The span to get data from. + /// The offset at which the 16-bit signed integer begins. + /// The 16-bit signed integer. + /// Thrown when the offset is too big for the span. + public static short GetS16(this ReadOnlySpan data, int offset) + { + if (offset + sizeof(short) > data.Length) + throw new ArgumentOutOfRangeException(nameof(offset)); + return BinaryPrimitives.ReadInt16LittleEndian(data.Slice(offset, sizeof(short))); + } + + /// + /// Get a 32-bit signed integer from the span at the given offset. + /// + /// The span to get data from. + /// The offset at which the 32-bit signed integer begins. + /// The 32-bit signed integer. + /// Thrown when the offset is too big for the span. + public static int GetS32(this ReadOnlySpan data, int offset) + { + if (offset + sizeof(int) > data.Length) + throw new ArgumentOutOfRangeException(nameof(offset)); + return BinaryPrimitives.ReadInt32LittleEndian(data.Slice(offset, sizeof(int))); + } + + /// + /// Get a 64-bit signed integer from the span at the given offset. + /// + /// The span to get data from. + /// The offset at which the 64-bit signed integer begins. + /// The 64-bit signed integer. + /// Thrown when the offset is too big for the span. + public static long GetS64(this ReadOnlySpan data, int offset) + { + if (offset + sizeof(long) > data.Length) + throw new ArgumentOutOfRangeException(nameof(offset)); + return BinaryPrimitives.ReadInt64LittleEndian(data.Slice(offset, sizeof(long))); + } + + /// + /// Get a span from the read-only span at the given offset with the given length. + /// + /// The span to get data from. + /// The offset at which the desired span begins. + /// The desired length for the new span. + /// A of bytes. + /// Thrown when the offset is too big for the span. + public static ReadOnlySpan GetSpan(this ReadOnlySpan data, int offset, int length) + { + if (offset + length > data.Length) + throw new ArgumentOutOfRangeException(nameof(offset)); + return data.Slice(offset, length); + } + + /// + /// Get a encoded as a 32 byte array from the span at the given offset. + /// + /// The span to get data from. + /// The offset at which the 32 byte array begins. + /// The instance. + /// Thrown when the offset is too big for the span. + public static PublicKey GetPubKey(this ReadOnlySpan data, int offset) + { + if (offset + PublicKey.PublicKeyLength > data.Length) + throw new ArgumentOutOfRangeException(nameof(offset)); + return new PublicKey(data.Slice(offset, PublicKey.PublicKeyLength).ToArray()); + } + + /// + /// Get an arbitrarily long number from the span at the given offset, specifying it's length in bytes. + /// Optionally specify if it's signed and the endianness. + /// + /// The span to get data from. + /// The offset at which the arbitrarily long number begins. + /// The byte-length of the arbitrarily long number. + /// Whether the value does not use signed encoding. + /// Whether the value is in big-endian byte order. + /// The instance that represents the value. + /// Thrown when the offset is too big for the span. + public static BigInteger GetBigInt(this ReadOnlySpan data, int offset, int length, + bool isUnsigned = false, bool isBigEndian = false) + { + if (offset + length > data.Length) + throw new ArgumentOutOfRangeException(nameof(offset)); + + return isBigEndian ? new BigInteger(data.Slice(offset, length).ToArray().Reverse().ToArray()) : new BigInteger(data.Slice(offset, length).ToArray()); + } + + /// + /// Get a double-precision floating-point number from the span at the given offset. + /// + /// The span to get data from. + /// The offset at which the double-precision floating-point number begins. + /// The instance that represents the value. + /// Thrown when the offset is too big for the span. + public static double GetDouble(this ReadOnlySpan data, int offset) + { + if (offset + sizeof(double) > data.Length) + throw new ArgumentOutOfRangeException(nameof(offset)); + + return BitConverter.ToDouble(data.Slice(offset, sizeof(double)).ToArray(), 0); + } + + /// + /// Get a single-precision floating-point number from the span at the given offset. + /// + /// The span to get data from. + /// The offset at which the single-precision floating-point number begins. + /// The instance that represents the value. + /// Thrown when the offset is too big for the span. + public static float GetSingle(this ReadOnlySpan data, int offset) + { + if (offset + sizeof(float) > data.Length) + throw new ArgumentOutOfRangeException(nameof(offset)); + + return BitConverter.ToSingle(data.Slice(offset, sizeof(float)).ToArray(), 0); + } + + + /// + /// Get a boolean value from the span at the given offset. + /// + /// The span to get data from. + /// The offset at which the boolean value is located. + /// The instance that represents the value. + /// Thrown when the offset is too big for the span. + public static bool GetBool(this ReadOnlySpan data, int offset) + { + return GetU8(data, offset) == 1; + } + + + /// + /// Decodes a string from a transaction instruction. + /// + /// The data to decode. + /// The offset at which the string begins. + /// The decoded data. + /// Thrown when the offset is too big for the span. + public static (string EncodedString, int Length) DecodeBincodeString(this ReadOnlySpan data, int offset) + { + if (offset + sizeof(ulong) > data.Length) + throw new ArgumentOutOfRangeException(nameof(offset)); + + int stringLength = (int)data.GetU64(offset); + byte[] stringBytes = data.GetSpan(offset + sizeof(ulong), stringLength).ToArray(); + + return (EncodedString: Encoding.UTF8.GetString(stringBytes), Length: stringLength + sizeof(ulong)); + } + + /// + /// Decodes a string from a transaction instruction. + /// + /// The data to decode. + /// The offset at which the string begins. + /// The decoded data./>. + /// The length in bytes that was read from the original buffer, including the + /// Thrown when the offset is too big for the span. + public static int GetBorshString(this ReadOnlySpan data, int offset, out string result) + { + if (offset + sizeof(uint) > data.Length) + throw new ArgumentOutOfRangeException(nameof(offset)); + + int stringLength = (int)data.GetU32(offset); + byte[] stringBytes = data.GetSpan(offset + sizeof(uint), stringLength).ToArray(); + result = Encoding.UTF8.GetString(stringBytes); + + return stringLength + sizeof(uint); + } + + + /// + /// Get a span from the read-only span at the given offset with the given length. + /// + /// The span to get data from. + /// The offset at which the desired byte[] begins. + /// The desired length for the new byte[]. + /// A byte[] of bytes. + /// Thrown when the offset is too big for the span. + public static byte[] GetBytes(this ReadOnlySpan data, int offset, int length) + { + if (offset + length > data.Length) + throw new ArgumentOutOfRangeException(nameof(offset)); + return data.Slice(offset, length).ToArray(); + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Utilities/Deserialization.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Utilities/Deserialization.cs.meta new file mode 100644 index 0000000..6a4b223 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Utilities/Deserialization.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ac4ff34680ac9374d89cfe0ab785b314 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Utilities/Serialization.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Utilities/Serialization.cs new file mode 100644 index 0000000..8371fdd --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Utilities/Serialization.cs @@ -0,0 +1,276 @@ +using Solana.Unity.Rpc.Utilities; +using Solana.Unity.Wallet; +using Solana.Unity.Wallet.Utilities; +using System; +using System.Buffers.Binary; +using System.Diagnostics; +using System.IO; +using System.Numerics; +using System.Runtime.InteropServices; +using System.Text; + +namespace Solana.Unity.Programs.Utilities +{ + /// + /// Extension methods for serialization of program data using . + /// + public static class Serialization + { + /// + /// Write a 8-bit unsigned integer to the byte array at the given offset. + /// + /// The byte array to write data to. + /// The 8-bit unsigned integer value to write. + /// The offset at which to write the 8-bit unsigned integer. + /// Thrown when the offset is too big for the data array. + public static void WriteU8(this byte[] data, byte value, int offset) + { + if (offset > data.Length - sizeof(byte)) + throw new ArgumentOutOfRangeException(nameof(offset)); + data[offset] = value; + } + /// + /// Write a boolean to the byte array at the given offset. + /// + /// The byte array to write data to. + /// The boolean value to write. + /// The offset at which to write the 8-bit unsigned integer. + /// Thrown when the offset is too big for the data array. + public static unsafe void WriteBool(this byte[] data, bool value, int offset) + { + if (offset > data.Length - sizeof(byte)) + throw new ArgumentOutOfRangeException(nameof(offset)); + data[offset] = *((byte*)(&value));; + } + + /// + /// Write a 16-bit unsigned integer to the byte array at the given offset. + /// + /// The byte array to write data to. + /// The 16-bit unsigned integer value to write. + /// The offset at which to write the 16-bit unsigned integer. + /// Thrown when the offset is too big for the data array. + public static void WriteU16(this byte[] data, ushort value, int offset) + { + if (offset + sizeof(ushort) > data.Length) + throw new ArgumentOutOfRangeException(nameof(offset)); + BinaryPrimitives.WriteUInt16LittleEndian(data.AsSpan(offset, sizeof(ushort)), value); + } + + /// + /// Write a 32-bit unsigned integer to the byte array at the given offset. + /// + /// The byte array to write data to. + /// The 32-bit unsigned integer value to write. + /// The offset at which to write the 32-bit unsigned integer. + /// Thrown when the offset is too big for the data array. + public static void WriteU32(this byte[] data, uint value, int offset) + { + if (offset + sizeof(uint) > data.Length) + throw new ArgumentOutOfRangeException(nameof(offset)); + BinaryPrimitives.WriteUInt32LittleEndian(data.AsSpan(offset, sizeof(uint)), value); + } + + /// + /// Write a 64-bit unsigned integer to the byte array at the given offset. + /// + /// The byte array to write data to. + /// The 64-bit unsigned integer value to write. + /// The offset at which to write the 64-bit unsigned integer. + /// Thrown when the offset is too big for the data array. + public static void WriteU64(this byte[] data, ulong value, int offset) + { + if (offset + sizeof(ulong) > data.Length) + throw new ArgumentOutOfRangeException(nameof(offset)); + BinaryPrimitives.WriteUInt64LittleEndian(data.AsSpan(offset, sizeof(ulong)), value); + } + + /// + /// Write a 8-bit signed integer to the byte array at the given offset. + /// + /// The byte array to write data to. + /// The 8-bit signed integer value to write. + /// The offset at which to write the 8-bit signed integer. + /// Thrown when the offset is too big for the data array. + public static void WriteS8(this byte[] data, sbyte value, int offset) + { + if (offset > data.Length - sizeof(sbyte)) + throw new ArgumentOutOfRangeException(nameof(offset)); + data[offset] = (byte)value; + } + + /// + /// Write a 16-bit signed integer to the byte array at the given offset. + /// + /// The byte array to write data to. + /// The 16-bit signed integer value to write. + /// The offset at which to write the 16-bit signed integer. + /// Thrown when the offset is too big for the data array. + public static void WriteS16(this byte[] data, short value, int offset) + { + if (offset + sizeof(short) > data.Length) + throw new ArgumentOutOfRangeException(nameof(offset)); + BinaryPrimitives.WriteInt16LittleEndian(data.AsSpan(offset, sizeof(short)), value); + } + + /// + /// Write a 32-bit signed integer to the byte array at the given offset. + /// + /// The byte array to write data to. + /// The 32-bit signed integer value to write. + /// The offset at which to write the 32-bit signed integer. + /// Thrown when the offset is too big for the data array. + public static void WriteS32(this byte[] data, int value, int offset) + { + if (offset + sizeof(int) > data.Length) + throw new ArgumentOutOfRangeException(nameof(offset)); + BinaryPrimitives.WriteInt32LittleEndian(data.AsSpan(offset, sizeof(int)), value); + } + + /// + /// Write a 64-bit signed integer to the byte array at the given offset. + /// + /// The byte array to write data to. + /// The 64-bit signed integer value to write. + /// The offset at which to write the 64-bit signed integer. + /// Thrown when the offset is too big for the data array. + public static void WriteS64(this byte[] data, long value, int offset) + { + if (offset + sizeof(long) > data.Length) + throw new ArgumentOutOfRangeException(nameof(offset)); + BinaryPrimitives.WriteInt64LittleEndian(data.AsSpan(offset, sizeof(long)), value); + } + + /// + /// Write a span of bytes to the byte array at the given offset. + /// + /// The byte array to write data to. + /// The to write. + /// The offset at which to write the . + /// Thrown when the offset is too big for the data array. + public static void WriteSpan(this byte[] data, ReadOnlySpan span, int offset) + { + if (offset + span.Length > data.Length) + throw new ArgumentOutOfRangeException(nameof(offset)); + span.CopyTo(data.AsSpan(offset, span.Length)); + } + + /// + /// Write a encoded as a 32 byte array to the byte array at the given offset. + /// + /// The byte array to write data to. + /// The to write. + /// The offset at which to write the . + /// Thrown when the offset is too big for the data array. + public static void WritePubKey(this byte[] data, PublicKey publicKey, int offset) + { + if (offset + publicKey.KeyBytes.Length > data.Length) + throw new ArgumentOutOfRangeException(nameof(offset)); + publicKey.KeyBytes.AsSpan().CopyTo(data.AsSpan(offset, publicKey.KeyBytes.Length)); + } + + /// + /// Write an arbitrarily long number to the byte array at the given offset, specifying it's length in bytes. + /// Optionally specify if it's signed and the endianness. + /// + /// The byte array to write data to. + /// The to write. + /// The offset at which to write the . + /// The length in bytes. + /// Whether the value does not use signed encoding. + /// Whether the value is in big-endian byte order. + /// An integer representing the number of bytes written to the byte array. + /// Thrown when the offset is too big for the data array. + public static int WriteBigInt(this byte[] data, BigInteger bigInteger, int offset, int length, + bool isUnsigned = false, bool isBigEndian = false) + { + int byteCount = bigInteger.ToByteArray().Length; + if (byteCount > length) throw new ArgumentOutOfRangeException($"BigInt too big."); + if (length + offset > data.Length) throw new ArgumentOutOfRangeException(nameof(offset)); + + var bigIntegerSpan = new Span(bigInteger.ToByteArray()); + var dataSpan = data.AsSpan(offset, byteCount); + bigIntegerSpan.CopyTo(dataSpan); + + if(!isUnsigned && bigInteger.Sign < 0) + { + while (byteCount < length) data[offset + byteCount++] = 0xFF; + } + + return byteCount; + } + + /// + /// Write a double-precision floating-point value to the byte array at the given offset. + /// + /// The byte array to write data to. + /// The to write. + /// The offset at which to write the . + /// Thrown when the offset is too big for the data array. + public static void WriteDouble(this byte[] data, double value, int offset) + { + if (offset + sizeof(double) > data.Length) + throw new ArgumentOutOfRangeException(nameof(offset)); + + var valueBytes = BitConverter.GetBytes(value); + var valueSpan = new Span(valueBytes); + var dataSpan = data.AsSpan(offset, sizeof(double)); + valueSpan.CopyTo(dataSpan); + } + + /// + /// Write a single-precision floating-point value to the byte array at the given offset. + /// + /// The byte array to write data to. + /// The to write. + /// The offset at which to write the . + /// Thrown when the offset is too big for the data array. + public static void WriteSingle(this byte[] data, float value, int offset) + { + if (offset + sizeof(float) > data.Length) + throw new ArgumentOutOfRangeException(nameof(offset)); + + var valueBytes = BitConverter.GetBytes(value); + var valueSpan = new Span(valueBytes); + var dataSpan = data.AsSpan(offset, sizeof(float)); + valueSpan.CopyTo(dataSpan); + } + + /// + /// Write a UTF8 string value to the byte array at the given offset. + /// + /// The byte array to write data to. + /// The to write. + /// The offset at which to write the . + /// Returns the number of bytes written. + public static int WriteBorshString(this byte[] data, string value, int offset) + { + byte[] stringBytes = Encoding.UTF8.GetBytes(value); + + if(offset + sizeof(uint) + stringBytes.Length > data.Length) + throw new ArgumentOutOfRangeException(nameof(offset)); + + data.WriteU32((uint)stringBytes.Length, offset); + data.WriteSpan(stringBytes, offset + sizeof(uint)); + + return stringBytes.Length + sizeof(uint); + } + + /// + /// Encodes a string for a transaction + /// + /// the string to be encoded + /// + public static byte[] EncodeBincodeString(string data) + { + byte[] stringBytes = Encoding.UTF8.GetBytes(data); + + byte[] encoded = new byte[stringBytes.Length+sizeof(ulong)]; + + encoded.WriteU64((ulong)stringBytes.Length, 0); + encoded.WriteSpan(stringBytes, 8); + + return encoded; + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Utilities/Serialization.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Utilities/Serialization.cs.meta new file mode 100644 index 0000000..90d8c3f --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Utilities/Serialization.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9d2c5ace508f4ec40bd8370d7bc83d24 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Utilities/SolHelper.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Utilities/SolHelper.cs new file mode 100644 index 0000000..affd69c --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Utilities/SolHelper.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Solana.Unity.Programs.Utilities +{ + /// + /// Helper class for conversion between Sol and Lamports. + /// + public class SolHelper + { + /// + /// Number of Lamports per Sol. + /// + public const ulong LAMPORTS_PER_SOL = 1000000000; + + /// + /// Convert Lamports value into Sol decimal value. + /// + /// + /// + public static decimal ConvertToSol(ulong lamports) + { + return Decimal.Round((decimal)lamports / (decimal)LAMPORTS_PER_SOL, 9); + } + + /// + /// Convert a decimal Sol value into Lamports ulong value. + /// + /// + /// + public static ulong ConvertToLamports(decimal sol) + { + return (ulong)(sol * LAMPORTS_PER_SOL); + } + } +} diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Utilities/SolHelper.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Utilities/SolHelper.cs.meta new file mode 100644 index 0000000..b013295 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Utilities/SolHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 600774bb42664fd4f96dcfb2fab89687 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Utilities/Utils.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Utilities/Utils.cs new file mode 100644 index 0000000..878586d --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Utilities/Utils.cs @@ -0,0 +1,42 @@ +namespace Solana.Unity.Programs.Utilities +{ + /// + /// Implements utility methods + /// + internal static class Utils + { + + /// + /// Slices the array, returning a new array starting at start index and ending at end index. + /// + /// The array to slice. + /// The starting index of the slicing. + /// The ending index of the slicing. + /// The array type. + /// The sliced array. + internal static T[] Slice(this T[] source, int start, int end) + { + if (end < 0) + end = source.Length; + + var len = end - start; + + // Return new array. + var res = new T[len]; + for (var i = 0; i < len; i++) res[i] = source[i + start]; + return res; + } + + /// + /// Slices the array, returning a new array starting at start. + /// + /// The array to slice. + /// The starting index of the slicing. + /// The array type. + /// The sliced array. + internal static T[] Slice(this T[] source, int start) + { + return Slice(source, start, -1); + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Utilities/Utils.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Utilities/Utils.cs.meta new file mode 100644 index 0000000..e615cad --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Programs/Utilities/Utils.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 126a1391f2028d84da4c98bf41056c5a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc.meta new file mode 100644 index 0000000..0834b7d --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 6e822cb9dc39ab04cb4265d8e4cb1699 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Builders.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Builders.meta new file mode 100644 index 0000000..d165263 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Builders.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 955ec3d50e6d37248bdfa1ddd69bf2e1 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Builders/MessageBuilder.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Builders/MessageBuilder.cs new file mode 100644 index 0000000..4cc989a --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Builders/MessageBuilder.cs @@ -0,0 +1,230 @@ +using Solana.Unity.Rpc.Models; +using Solana.Unity.Rpc.Utilities; +using Solana.Unity.Wallet; +using Solana.Unity.Wallet.Utilities; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace Solana.Unity.Rpc.Builders +{ + /// + /// A compiled instruction within the message. + /// + public class MessageBuilder + { + + /// + /// The length of the block hash. + /// + private const int BlockHashLength = 32; + + /// + /// The message header. + /// + private MessageHeader _messageHeader; + + /// + /// The account keys list. + /// + private readonly AccountKeysList _accountKeysList; + + /// + /// The list of instructions contained within this transaction. + /// + internal List Instructions { get; private set; } + + /// + /// The hash of a recent block. + /// + internal string RecentBlockHash { get; set; } + + /// + /// The nonce information to be used instead of the recent blockhash. + /// + internal NonceInformation NonceInformation { get; set; } + + /// + /// The transaction fee payer. + /// + internal PublicKey FeePayer { get; set; } + + /// + /// Initialize the message builder. + /// + internal MessageBuilder() + { + _accountKeysList = new AccountKeysList(); + Instructions = new List(); + } + + /// + /// Add an instruction to the message. + /// + /// The instruction to add to the message. + /// The message builder, so instruction addition can be chained. + internal MessageBuilder AddInstruction(TransactionInstruction instruction) + { + _accountKeysList.Add(instruction.Keys); + _accountKeysList.Add(AccountMeta.ReadOnly(new PublicKey(instruction.ProgramId), false)); + Instructions.Add(instruction); + return this; + } + + /// + /// Builds the message into the wire format. + /// + /// The encoded message. + internal byte[] Build() + { + if (RecentBlockHash == null && NonceInformation == null) + throw new Exception("recent block hash or nonce information is required"); + if (Instructions == null) + throw new Exception("no instructions provided in the transaction"); + + // In case the user specified nonce information, we'll use it. + if (NonceInformation != null) + { + RecentBlockHash = NonceInformation.Nonce; + _accountKeysList.Add(NonceInformation.Instruction.Keys); + _accountKeysList.Add(AccountMeta.ReadOnly(new PublicKey(NonceInformation.Instruction.ProgramId), + false)); + List newInstructions = new() { NonceInformation.Instruction }; + newInstructions.AddRange(Instructions); + Instructions = newInstructions; + } + + _messageHeader = new MessageHeader(); + + List keysList = GetAccountKeys(); + byte[] accountAddressesLength = ShortVectorEncoding.EncodeLength(keysList.Count); + int compiledInstructionsLength = 0; + List compiledInstructions = new(); + + foreach (TransactionInstruction instruction in Instructions) + { + int keyCount = instruction.Keys.Count; + byte[] keyIndices = new byte[keyCount]; + + for (int i = 0; i < keyCount; i++) + { + keyIndices[i] = FindAccountIndex(keysList, instruction.Keys[i].PublicKey); + } + + CompiledInstruction compiledInstruction = new CompiledInstruction + { + ProgramIdIndex = FindAccountIndex(keysList, instruction.ProgramId), + KeyIndicesCount = ShortVectorEncoding.EncodeLength(keyCount), + KeyIndices = keyIndices, + DataLength = ShortVectorEncoding.EncodeLength(instruction.Data.Length), + Data = instruction.Data + }; + compiledInstructions.Add(compiledInstruction); + compiledInstructionsLength += compiledInstruction.Length(); + } + + int accountKeysBufferSize = _accountKeysList.AccountList.Count * 32; + MemoryStream accountKeysBuffer = new MemoryStream(accountKeysBufferSize); + byte[] instructionsLength = ShortVectorEncoding.EncodeLength(compiledInstructions.Count); + + foreach (AccountMeta accountMeta in keysList) + { + accountKeysBuffer.Write(accountMeta.PublicKeyBytes, 0, accountMeta.PublicKeyBytes.Length); + if (accountMeta.IsSigner) + { + _messageHeader.RequiredSignatures += 1; + if (!accountMeta.IsWritable) + _messageHeader.ReadOnlySignedAccounts += 1; + } + else + { + if (!accountMeta.IsWritable) + _messageHeader.ReadOnlyUnsignedAccounts += 1; + } + } + + #region Build Message Body + + int messageBufferSize = MessageHeader.Layout.HeaderLength + BlockHashLength + + accountAddressesLength.Length + + +instructionsLength.Length + compiledInstructionsLength + accountKeysBufferSize; + MemoryStream buffer = new MemoryStream(messageBufferSize); + byte[] messageHeaderBytes = _messageHeader.ToBytes(); + + buffer.Write(messageHeaderBytes, 0, messageHeaderBytes.Length); + buffer.Write(accountAddressesLength, 0, accountAddressesLength.Length); + buffer.Write(accountKeysBuffer.ToArray(), 0, accountKeysBuffer.ToArray().Length); + var encodedRecentBlockHash = Encoders.Base58.DecodeData(RecentBlockHash); + buffer.Write(encodedRecentBlockHash, 0, encodedRecentBlockHash.Length); + buffer.Write(instructionsLength, 0, instructionsLength.Length); + + foreach (CompiledInstruction compiledInstruction in compiledInstructions) + { + buffer.WriteByte(compiledInstruction.ProgramIdIndex); + buffer.Write(compiledInstruction.KeyIndicesCount, 0, compiledInstruction.KeyIndicesCount.Length); + buffer.Write(compiledInstruction.KeyIndices, 0, compiledInstruction.KeyIndices.Length); + buffer.Write(compiledInstruction.DataLength, 0, compiledInstruction.DataLength.Length); + buffer.Write(compiledInstruction.Data, 0, compiledInstruction.Data.Length); + } + + #endregion + + return buffer.ToArray(); + } + + /// + /// Gets the keys for the accounts present in the message. + /// + /// The list of . + private List GetAccountKeys() + { + List newList = new(); + var keysList = _accountKeysList.AccountList; + int feePayerIndex = Array.FindIndex( _accountKeysList.AccountList.ToArray(), + x => x.PublicKey == FeePayer.Key); + + if (feePayerIndex == -1) + { + newList.Add(AccountMeta.Writable(FeePayer, true)); + } + else + { + keysList.RemoveAt(feePayerIndex); + newList.Add(AccountMeta.Writable(FeePayer, true)); + } + + newList.AddRange(keysList); + + return newList; + } + + /// + /// Finds the index of the given public key in the accounts list. + /// + /// The . + /// The public key. + /// The index of the + private static byte FindAccountIndex(IList accountMetas, byte[] publicKey) + { + string encodedKey = Encoders.Base58.EncodeData(publicKey); + return FindAccountIndex(accountMetas, encodedKey); + } + + /// + /// Finds the index of the given public key in the accounts list. + /// + /// The . + /// The public key. + /// The index of the + private static byte FindAccountIndex(IList accountMetas, string publicKey) + { + for (byte index = 0; index < accountMetas.Count; index++) + { + if (accountMetas[index].PublicKey == publicKey) return index; + } + + throw new Exception($"Something went wrong encoding this transaction. Account `{publicKey}` was not found among list of accounts. Should be impossible."); + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Builders/MessageBuilder.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Builders/MessageBuilder.cs.meta new file mode 100644 index 0000000..1572d76 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Builders/MessageBuilder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9a9c2cbc06f05184c9c6344f634d2c93 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Builders/TransactionBuilder.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Builders/TransactionBuilder.cs new file mode 100644 index 0000000..d39bd74 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Builders/TransactionBuilder.cs @@ -0,0 +1,180 @@ +using Solana.Unity.Rpc.Models; +using Solana.Unity.Rpc.Utilities; +using Solana.Unity.Wallet; +using Solana.Unity.Wallet.Utilities; +using System; +using System.Collections.Generic; +using System.IO; + +namespace Solana.Unity.Rpc.Builders +{ + /// + /// Implements a builder for transactions. + /// + public class TransactionBuilder + { + /// + /// The length of a signature. + /// + public const int SignatureLength = 64; + + /// + /// The builder of the message contained within the transaction. + /// + private readonly MessageBuilder _messageBuilder; + + /// + /// The signatures present in the message. + /// + private readonly List _signatures; + + /// + /// The message after being serialized. + /// + private byte[] _serializedMessage; + + /// + /// Default constructor that initializes the transaction builder. + /// + public TransactionBuilder() + { + _messageBuilder = new MessageBuilder(); + _signatures = new List(); + } + + /// + /// Serializes the message into a byte array. + /// + public byte[] Serialize() + { + byte[] signaturesLength = ShortVectorEncoding.EncodeLength(_signatures.Count); + if (_serializedMessage == null) + _serializedMessage = _messageBuilder.Build(); + MemoryStream buffer = new(signaturesLength.Length + _signatures.Count * SignatureLength + _serializedMessage.Length); + + buffer.Write(signaturesLength, 0, signaturesLength.Length); + foreach (string signature in _signatures) + { + var encodedSignature = Encoders.Base58.DecodeData(signature); + buffer.Write(encodedSignature, 0, encodedSignature.Length); + } + buffer.Write(_serializedMessage, 0, _serializedMessage.Length); + + return buffer.ToArray(); + } + + /// + /// Sign the transaction message with each of the signer's keys. + /// + /// The list of signers. + /// Throws exception when the list of signers is null or empty or when the fee payer hasn't been set. + private void Sign(IList signers) + { + if (signers == null || signers.Count == 0) throw new Exception("no signers for the transaction"); + + if (_messageBuilder.FeePayer == null) + throw new Exception("fee payer is required"); + + _serializedMessage = _messageBuilder.Build(); + + foreach (Account signer in signers) + { + byte[] signatureBytes = signer.Sign(_serializedMessage); + _signatures.Add(Encoders.Base58.EncodeData(signatureBytes)); + } + } + + /// + /// Adds a signature to the current transaction. + /// + /// The signature. + public TransactionBuilder AddSignature(byte[] signature) + => AddSignature(Encoders.Base58.EncodeData(signature)); + + /// + /// Adds a signature to the current transaction. + /// + /// The signature. + public TransactionBuilder AddSignature(string signature) + { + _signatures.Add(signature); + return this; + } + + /// + /// Sets the recent block hash for the transaction. + /// + /// The recent block hash as a base58 encoded string. + /// The transaction builder, so instruction addition can be chained. + public TransactionBuilder SetRecentBlockHash(string recentBlockHash) + { + _messageBuilder.RecentBlockHash = recentBlockHash; + return this; + } + + /// + /// Sets the nonce information for the transaction. + /// Whenever this is set, it is used instead of the blockhash. + /// + /// The nonce information object to use. + /// The transaction builder, so instruction addition can be chained. + public TransactionBuilder SetNonceInformation(NonceInformation nonceInfo) + { + _messageBuilder.NonceInformation = nonceInfo; + return this; + } + + /// + /// Sets the fee payer for the transaction. + /// + /// The public key of the account that will pay the transaction fee + /// The transaction builder, so instruction addition can be chained. + public TransactionBuilder SetFeePayer(PublicKey account) + { + _messageBuilder.FeePayer = account; + return this; + } + + /// + /// Adds a new instruction to the transaction. + /// + /// The instruction to add. + /// The transaction builder, so instruction addition can be chained. + public TransactionBuilder AddInstruction(TransactionInstruction instruction) + { + _messageBuilder.AddInstruction(instruction); + return this; + } + + /// + /// Compiles the transaction's message into wire format, ready to be signed. + /// + /// The serialized message. + public byte[] CompileMessage() + { + return _messageBuilder.Build(); + } + + /// + /// Signs the transaction's message with the passed signer and add it to the transaction, serializing it. + /// + /// The signer. + /// The serialized transaction. + public byte[] Build(Account signer) + { + return Build(new List { signer }); + } + + /// + /// Signs the transaction's message with the passed list of signers and adds them to the transaction, serializing it. + /// + /// The list of signers. + /// The serialized transaction. + public byte[] Build(IList signers) + { + Sign(signers); + + return Serialize(); + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Builders/TransactionBuilder.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Builders/TransactionBuilder.cs.meta new file mode 100644 index 0000000..9439d78 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Builders/TransactionBuilder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0715dc4bd50f2ef46a01828392b3ce72 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Builders/TransactionInstructionFactory.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Builders/TransactionInstructionFactory.cs new file mode 100644 index 0000000..ae1fc8d --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Builders/TransactionInstructionFactory.cs @@ -0,0 +1,42 @@ +using Solana.Unity.Rpc.Models; +using Solana.Unity.Wallet; +using System; +using System.Collections.Generic; + +namespace Solana.Unity.Rpc.Builders +{ + /// + /// Methods to create instances of the TransactionInstruction for languages that do not support init-only setters + /// + public static class TransactionInstructionFactory + { + + /// + /// Helper method to make TransactionInstruction objects available to outside Program implementations in + /// languages that do not currently support immutable init-only setters like VB.Net + /// + /// The program ID associated with the instruction. + /// The keys associated with the instruction. + /// The instruction-specific data. + /// + public static TransactionInstruction Create(PublicKey programId, + IList keys, + byte[] data) + { + + if (programId == null) throw new ArgumentNullException(nameof(programId)); + if (keys == null) throw new ArgumentNullException(nameof(keys)); + if (data == null) throw new ArgumentNullException(nameof(data)); + + return new TransactionInstruction + { + ProgramId = programId.KeyBytes, + Keys = keys, + Data = data + }; + + } + + } + +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Builders/TransactionInstructionFactory.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Builders/TransactionInstructionFactory.cs.meta new file mode 100644 index 0000000..7885de1 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Builders/TransactionInstructionFactory.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ec6668998e8c7d54f84c537c8a59c490 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/ClientFactory.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/ClientFactory.cs new file mode 100644 index 0000000..38b53e7 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/ClientFactory.cs @@ -0,0 +1,167 @@ +using Solana.Unity.Rpc.Utilities; +using System.Net.Http; +using System.Net.WebSockets; + +namespace Solana.Unity.Rpc +{ + /// + /// Implements a client factory for Solana RPC and Streaming RPC APIs. + /// + public static class ClientFactory + { + /// + /// The dev net cluster. + /// + private const string RpcDevNet = "https://api.devnet.solana.com"; + + /// + /// The test net cluster. + /// + private const string RpcTestNet = "https://api.testnet.solana.com"; + + /// + /// The main net cluster. + /// + private const string RpcMainNet = "https://api.mainnet-beta.solana.com"; + + + /// + /// The dev net cluster. + /// + private const string StreamingRpcDevNet = "wss://api.devnet.solana.com"; + + /// + /// The test net cluster. + /// + private const string StreamingRpcTestNet = "wss://api.testnet.solana.com"; + + /// + /// The main net cluster. + /// + private const string StreamingRpcMainNet = "wss://api.mainnet-beta.solana.com"; + + /// + /// Instantiate a http client. + /// + /// The network cluster. + /// The logger. + /// The http client. + public static IRpcClient GetClient(Cluster cluster, object logger) + { + return GetClient(cluster, logger, null); + } + + /// + /// Instantiate a http client. + /// + /// The network cluster. + /// The http client. + public static IRpcClient GetClient(Cluster cluster) + { + return GetClient(cluster, logger: null, rateLimiter: null); + } + + /// + /// Instantiate a http client. + /// + /// The network cluster. + /// The logger. + /// An IRateLimiter instance or null. + /// The http client. + public static IRpcClient GetClient( + Cluster cluster, + object logger = null, + IRateLimiter rateLimiter = null) + { + return GetClient(cluster, logger, httpClient: null, rateLimiter: rateLimiter); + } + + /// + /// Instantiate a http client. + /// + /// The network cluster. + /// The logger. + /// A HttpClient instance. If null, a new instance will be created. + /// An IRateLimiter instance or null. + /// The http client. + public static IRpcClient GetClient(Cluster cluster, object logger = null, + HttpClient httpClient = null, IRateLimiter rateLimiter = null) + { + var url = cluster switch + { + Cluster.DevNet => RpcDevNet, + Cluster.TestNet => RpcTestNet, + _ => RpcMainNet, + }; + + return GetClient(url, logger, httpClient, rateLimiter); + } + + /// + /// Instantiate a http client. + /// + /// The network cluster url. + /// The logger. + /// The http client. + public static IRpcClient GetClient(string url, object logger) + { + return GetClient(url, logger, null); + } + + /// + /// Instantiate a http client. + /// + /// The network cluster url. + /// The logger. + /// An IRateLimiter instance or null. + /// The http client. + public static IRpcClient GetClient(string url, object logger, IRateLimiter rateLimiter) + { + return GetClient(url, logger, httpClient: null, rateLimiter); + } + + /// + /// Instantiate a http client. + /// + /// The network cluster url. + /// The logger. + /// A HttpClient instance. If null, a new instance will be created. + /// An IRateLimiter instance or null. + /// The http client. + public static IRpcClient GetClient(string url, object logger = null, HttpClient httpClient = null, IRateLimiter rateLimiter = null) + { + return new SolanaRpcClient(url, logger, httpClient, rateLimiter); + } + + /// + /// Instantiate a streaming client. + /// + /// The network cluster. + /// The logger. + /// The streaming client. + public static IStreamingRpcClient GetStreamingClient( + Cluster cluster, + object logger = null) + { + var url = cluster switch + { + Cluster.DevNet => StreamingRpcDevNet, + Cluster.TestNet => StreamingRpcTestNet, + _ => StreamingRpcMainNet, + }; + return GetStreamingClient(url, logger); + } + + /// + /// Instantiate a streaming client. + /// + /// The network cluster url. + /// The logger. + /// A ClientWebSocket instance. If null, a new instance will be created. + /// The streaming client. + public static IStreamingRpcClient GetStreamingClient(string url, object logger = null, ClientWebSocket clientWebSocket = null) + { + return new SolanaStreamingRpcClient(url, logger, null, clientWebSocket); + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/ClientFactory.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/ClientFactory.cs.meta new file mode 100644 index 0000000..2b2020c --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/ClientFactory.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2a7cb4aa0db878c48a3248f1a2be52e6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Cluster.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Cluster.cs new file mode 100644 index 0000000..c46b124 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Cluster.cs @@ -0,0 +1,47 @@ +namespace Solana.Unity.Rpc +{ + /// + /// Represents the public solana clusters. + /// + public enum Cluster + { + /// + /// Devnet serves as a playground for anyone who wants to take Solana for a test drive, as a user, token holder, app developer, or validator. + /// + /// + /// Application developers should target Devnet. + /// Potential validators should first target Devnet. + /// Key points: + /// + /// Devnet tokens are not real + /// Devnet includes a token faucet for airdrops for application testing + /// Devnet may be subject to ledger resets + /// Devnet typically runs a newer software version than Mainnet Beta + /// + /// + DevNet, + + /// + /// Testnet is where Solana stress tests recent release features on a live cluster, particularly focused on network performance, stability and validator behavior. + /// + /// + /// Tour de SOL initiative runs on Testnet, where malicious behavior and attacks are encouraged on the network to help find and squash bugs or network vulnerabilities. + /// Key points: + /// + /// Devnet tokens are not real + /// Devnet includes a token faucet for airdrops for application testing + /// Devnet may be subject to ledger resets + /// Testnet typically runs a newer software release than both Devnet and Mainnet Beta + /// + /// + TestNet, + + /// + /// A permissionless, persistent cluster for early token holders and launch partners. Currently, rewards and inflation are disabled. + /// + /// + /// Tokens that are issued on Mainnet Beta are real SOL. + /// + MainNet + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Cluster.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Cluster.cs.meta new file mode 100644 index 0000000..2aa5606 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Cluster.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5eabea8d0ca6f9c44b039ddea2ba97b6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Converters.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Converters.meta new file mode 100644 index 0000000..8743c63 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Converters.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9f19076a1695d9343ba61189add88e0a +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Converters/AccountDataConverter.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Converters/AccountDataConverter.cs new file mode 100644 index 0000000..a033068 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Converters/AccountDataConverter.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Solana.Unity.Rpc.Converters +{ + /// + public class AccountDataConverter : JsonConverter> + { + /// + public override void WriteJson(JsonWriter writer, List value, JsonSerializer serializer) + { + throw new NotImplementedException(); + } + + /// + /// Read an AccountDataConverter from json into its model representation. + /// + /// + /// + /// + /// + /// + /// + /// + public override List ReadJson(JsonReader reader, Type objectType, List existingValue, bool hasExistingValue, JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.StartArray) + return serializer.Deserialize>(reader); + + if(reader.TokenType == JsonToken.StartObject) + { + var doc = JObject.Load(reader); + var jsonAsString = doc.Root.ToString(); + + return new List() { jsonAsString, "jsonParsed" }; + } + + throw new JsonException("Unable to parse account data"); + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Converters/AccountDataConverter.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Converters/AccountDataConverter.cs.meta new file mode 100644 index 0000000..540769a --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Converters/AccountDataConverter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bc8c37718664ca5408c9b736db43f6a5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Converters/EncodingConverter.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Converters/EncodingConverter.cs new file mode 100644 index 0000000..372d43a --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Converters/EncodingConverter.cs @@ -0,0 +1,33 @@ +using Newtonsoft.Json; +using Solana.Unity.Rpc.Types; +using System; + +namespace Solana.Unity.Rpc.Converters +{ + /// + public class EncodingConverter : JsonConverter + { + public override void WriteJson(JsonWriter writer, BinaryEncoding value, JsonSerializer serializer) + { + if(value == BinaryEncoding.JsonParsed) + { + writer.WriteValue("jsonParsed"); + } + else if (value == BinaryEncoding.Base64Zstd) + { + writer.WriteValue("base64+zstd"); + } + else + { + writer.WriteValue("base64"); + } + } + + /// + public override BinaryEncoding ReadJson(JsonReader reader, Type objectType, BinaryEncoding existingValue, bool hasExistingValue, + JsonSerializer serializer) + { + throw new NotImplementedException(); + } + } +} diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Converters/EncodingConverter.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Converters/EncodingConverter.cs.meta new file mode 100644 index 0000000..3215bf0 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Converters/EncodingConverter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 436378456f7d23740928427d80dce6df +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Converters/RpcErrorResponseConverter.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Converters/RpcErrorResponseConverter.cs new file mode 100644 index 0000000..643ee12 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Converters/RpcErrorResponseConverter.cs @@ -0,0 +1,82 @@ +using Newtonsoft.Json; +using Solana.Unity.Rpc.Messages; +using System; + +namespace Solana.Unity.Rpc.Converters +{ + /// + /// Converts a TransactionError from json into its model representation. + /// + public class RpcErrorResponseConverter : JsonConverter + { + + /// + /// Reads and converts the JSON to type JsonRpcErrorResponse. + /// + /// The reader. + /// The type to convert. + /// An existing values + /// If it has an existing values + /// The serializer + /// The converted value. + public override JsonRpcErrorResponse ReadJson(JsonReader reader, Type objectType, JsonRpcErrorResponse existingValue, + bool hasExistingValue, JsonSerializer serializer) + { + if (reader.TokenType != JsonToken.StartObject) return null; + + reader.Read(); + + var err = new JsonRpcErrorResponse(); + + while (reader.TokenType != JsonToken.EndObject) + { + var prop = (string)reader.Value; + + reader.Read(); + + if ("jsonrpc" == prop) + { + // do nothing + } + else if ("id" == prop) + { + err.Id = Convert.ToInt32(reader.Value); + } + else if ("error" == prop) + { + if(reader.TokenType == JsonToken.String) + { + err.ErrorMessage = (string)reader.Value; + } + else if(reader.TokenType == JsonToken.StartObject) + { + err.Error = serializer.Deserialize(reader); + } + else + { + reader.Skip(); + } + } + else + { + reader.Skip(); + } + + reader.Read(); + } + return err; + } + + /// + /// Not yet implemented + /// + /// + /// + /// + /// + public override void WriteJson(JsonWriter writer, JsonRpcErrorResponse value, JsonSerializer serializer) + { + throw new NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Converters/RpcErrorResponseConverter.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Converters/RpcErrorResponseConverter.cs.meta new file mode 100644 index 0000000..17c5975 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Converters/RpcErrorResponseConverter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0784e1ffe3ec8a24cbf8e0f98797cf87 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Converters/TransactionErrorJsonConverter.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Converters/TransactionErrorJsonConverter.cs new file mode 100644 index 0000000..d1c10c1 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Converters/TransactionErrorJsonConverter.cs @@ -0,0 +1,156 @@ +using Newtonsoft.Json; +using Solana.Unity.Rpc.Models; +using System; + + +namespace Solana.Unity.Rpc.Converters +{ + /// + /// Converts a TransactionError from json into its model representation. + /// + public class TransactionErrorJsonConverter : JsonConverter + { + /// + /// Reads and converts the JSON to type TransactionError. + /// + /// The reader. + /// The type to convert. + /// An existing values + /// If it has an existing values + /// The serializer + /// The converted value. + public override TransactionError ReadJson(JsonReader reader, Type objectType, TransactionError existingValue, bool hasExistingValue, + JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.Null) return null; + + var err = new TransactionError(); + + if (reader.TokenType == JsonToken.String) + { + var enumValue = reader.ReadAsString(); + + Enum.TryParse(enumValue, ignoreCase: false, out TransactionErrorType errorType); + err.Type = errorType; + reader.Read(); + return err; + } + + if (reader.TokenType != JsonToken.StartObject) + { + throw new JsonException("Unexpected error value."); + } + + reader.Read(); + + if (reader.TokenType != JsonToken.PropertyName) + { + throw new JsonException("Unexpected error value."); + } + + + { + var enumValue = (string)reader.Value; + Enum.TryParse(enumValue, ignoreCase: false, out TransactionErrorType errorType); + err.Type = errorType; + } + + reader.Read(); + err.InstructionError = new InstructionError(); + + if (reader.TokenType != JsonToken.StartArray) + { + throw new JsonException("Unexpected error value."); + } + + reader.Read(); + + if (reader.TokenType != JsonToken.Integer) + { + throw new JsonException("Unexpected error value."); + } + + err.InstructionError.InstructionIndex = Convert.ToInt32(reader.Value); + + reader.Read(); + + if (reader.TokenType == JsonToken.String) + { + var enumValue = (string)reader.Value; + + Enum.TryParse(enumValue, ignoreCase: false, out InstructionErrorType errorType); + err.InstructionError.Type = errorType; + reader.Read(); //string + + reader.Read(); //endarray + return err; + } + + if (reader.TokenType != JsonToken.StartObject) + { + throw new JsonException("Unexpected error value."); + } + + reader.Read(); + + + if (reader.TokenType != JsonToken.PropertyName) + { + throw new JsonException("Unexpected error value."); + } + { + var enumValue = (string)reader.Value; + Enum.TryParse(enumValue, ignoreCase: false, out InstructionErrorType errorType); + err.InstructionError.Type = errorType; + } + + reader.Read(); + + if (reader.TokenType == JsonToken.Integer) + { + err.InstructionError.CustomError = Convert.ToUInt32(reader.Value); + reader.Read(); //number + reader.Read(); //endobj + reader.Read(); //endarray + + return err; + } + + if (reader.TokenType != JsonToken.String) + { + throw new JsonException("Unexpected error value."); + } + + err.InstructionError.BorshIoError = reader.ReadAsString(); + reader.Read(); //string + reader.Read(); //endobj + reader.Read(); //endarray + + return err; + } + + public override void WriteJson(JsonWriter writer, TransactionError value, JsonSerializer serializer) + { + if (value.InstructionError != null) + { + + // looking to output something like this... + // { 'InstructionError': [0, 'InvalidAccountData'] } + writer.WriteStartObject(); + writer.WritePropertyName("InstructionError"); + + // innards + var enumName = value.InstructionError.Type.ToString(); + writer.WriteStartArray(); + writer.WriteValue(value.InstructionError.InstructionIndex); + writer.WriteValue(enumName); + writer.WriteEndArray(); + + writer.WriteEndObject(); + + } + else + throw new NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Converters/TransactionErrorJsonConverter.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Converters/TransactionErrorJsonConverter.cs.meta new file mode 100644 index 0000000..52ae81d --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Converters/TransactionErrorJsonConverter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 770352ba15d7611418b29435b462f0a7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core.meta new file mode 100644 index 0000000..e2c444b --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0da75fc3cfe7e1e4393771ce9b6e6119 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Http.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Http.meta new file mode 100644 index 0000000..004890c --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Http.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 464e9e7c9a5e4fb4c9916ee1495469b7 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Http/ConfigObject.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Http/ConfigObject.cs new file mode 100644 index 0000000..6bac265 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Http/ConfigObject.cs @@ -0,0 +1,125 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Solana.Unity.Rpc.Core.Http +{ + /// + /// Helper class that holds a key-value config pair that filters out null values. + /// + internal class KeyValue : Tuple + { + private KeyValue(string item1, object item2) : base(item1, item2) + { + } + + internal static KeyValue Create(string key, object value) + { + if (value != null) + { + return new KeyValue(key, value); + } + return null; + } + } + + /// + /// Helper class to create configuration objects with key-value pairs that filters out null values. + /// + internal static class ConfigObject + { + internal static Dictionary Create(KeyValue pair1) + { + if (pair1 != null) + { + return new Dictionary { { pair1.Item1, pair1.Item2 } }; + } + return null; + } + + internal static Dictionary Create(KeyValue pair1, KeyValue pair2) + { + var dict = Create(pair1) ?? new Dictionary(); + + if (pair2 != null) + { + dict.Add(pair2.Item1, pair2.Item2); + } + + return dict.Count > 0 ? dict : null; + } + + internal static Dictionary Create(KeyValue pair1, KeyValue pair2, KeyValue pair3) + { + var dict = Create(pair1, pair2) ?? new Dictionary(); + + if (pair3 != null) + { + dict.Add(pair3.Item1, pair3.Item2); + } + + return dict.Count > 0 ? dict : null; + } + + internal static Dictionary Create(KeyValue pair1, KeyValue pair2, KeyValue pair3, KeyValue pair4) + { + var dict = Create(pair1, pair2, pair3) ?? new Dictionary(); + + if (pair4 != null) + { + dict.Add(pair4.Item1, pair4.Item2); + } + + return dict.Count > 0 ? dict : null; + } + + internal static Dictionary Create(KeyValue pair1, KeyValue pair2, KeyValue pair3, KeyValue pair4, KeyValue pair5) + { + var dict = Create(pair1, pair2, pair3, pair4) ?? new Dictionary(); + + if (pair5 != null) + { + dict.Add(pair5.Item1, pair5.Item2); + } + + return dict.Count > 0 ? dict : null; + } + } + + /// + /// Helper class that creates a List of parameters and filters out null values. + /// + internal static class Parameters + { + internal static List Create(object val1) + { + if (val1 != null) + { + return new List { val1 }; + } + return null; + } + + internal static List Create(object val1, object val2) + { + var list = Create(val1) ?? new List(); + if (val2 != null) + { + list.Add(val2); + } + return list.Count > 0 ? list : null; + } + + internal static List Create(object val1, object val2, object val3) + { + var list = Create(val1, val2) ?? new List(); + if (val3 != null) + { + list.Add(val3); + } + return list.Count > 0 ? list : null; + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Http/ConfigObject.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Http/ConfigObject.cs.meta new file mode 100644 index 0000000..e8ab366 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Http/ConfigObject.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e2b9af664c4ff6640b6c8890e848648e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Http/IRequestResult.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Http/IRequestResult.cs new file mode 100644 index 0000000..64b7e75 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Http/IRequestResult.cs @@ -0,0 +1,59 @@ +using Solana.Unity.Rpc.Models; +using System.Collections.Generic; +using System.Net; + +namespace Solana.Unity.Rpc.Core.Http +{ + /// + /// Interface used to tepresent the result of a given request. + /// + public interface IRequestResult + { + /// + /// Returns true if the request was successfully handled and parsed. + /// + bool WasSuccessful { get; } + + /// + /// Returns true if the HTTP request was successful (e.g. Code 200). + /// + bool WasHttpRequestSuccessful { get; set; } + + /// + /// Returns true if the request was successfully handled by the server and no error parameters are found in the result. + /// + bool WasRequestSuccessfullyHandled { get; set; } + + /// + /// Returns a string with the reason for the error if is false. + /// + string Reason { get; set; } + + /// + /// Returns the of the request. + /// + HttpStatusCode HttpStatusCode { get; set; } + + /// + /// Returns the error code if one was found in the error object when the server is unable to handle the request. + /// + int ServerErrorCode { get; set; } + + /// + /// The error data, if applicable. + /// + ErrorData ErrorData { get; set; } + + /// + /// Contains the JSON RPC request payload + /// + string RawRpcRequest { get; } + + /// + /// Contains the JSON RPC response payload + /// + string RawRpcResponse { get; } + + } + +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Http/IRequestResult.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Http/IRequestResult.cs.meta new file mode 100644 index 0000000..68656a4 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Http/IRequestResult.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 913f6cb7a76143c4c84a0c93543654f8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Http/JsonRpcClient.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Http/JsonRpcClient.cs new file mode 100644 index 0000000..735d483 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Http/JsonRpcClient.cs @@ -0,0 +1,389 @@ +using Solana.Unity.Rpc.Messages; +using Solana.Unity.Rpc.Utilities; +using System; +using System.Linq; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using Newtonsoft.Json.Serialization; +using Solana.Unity.Rpc.Converters; +using System.ComponentModel; +using System.Net; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; +using UnityEngine.Networking; + +namespace Solana.Unity.Rpc.Core.Http +{ + /// + /// Base Rpc client class that abstracts the HttpClient handling. + /// + internal abstract class JsonRpcClient + { + + /// + /// The Json serializer options to be reused between calls. + /// + private readonly JsonSerializerSettings _serializerOptions; + + /// + /// The HttpClient. + /// + private readonly HttpClient _httpClient; + + /// + /// The logger instance. + /// + private readonly object _logger; + + /// + /// Rate limiting strategy + /// + private IRateLimiter _rateLimiter; + + /// + public Uri NodeAddress { get; } + + /// + /// The internal constructor that setups the client. + /// + /// The url of the RPC server. + /// The possible logger instance. + /// The possible HttpClient instance. If null, a new instance will be created. + /// An IRateLimiter instance or null for no rate limiting. + protected JsonRpcClient(string url, object logger = default, HttpClient httpClient = default, IRateLimiter rateLimiter = null) + { + _logger = logger; + NodeAddress = new Uri(url); + _httpClient = httpClient ?? new HttpClient { BaseAddress = NodeAddress }; + _rateLimiter = rateLimiter; + _serializerOptions = new JsonSerializerSettings + { + ContractResolver = new CamelCasePropertyNamesContractResolver(), + Converters = + { + new EncodingConverter(), + new StringEnumConverter(new CamelCaseNamingStrategy()) + } + }; + } + + /// + /// Sends a given message as a POST method and returns the deserialized message result based on the type parameter. + /// + /// The type of the result to deserialize from json. + /// The message request. + /// A task that represents the asynchronous operation that holds the request result. + protected async Task> SendRequest(JsonRpcRequest req) + { + var requestJson = JsonConvert.SerializeObject(req, _serializerOptions); + + try + { + // pre-flight check with rate limiter if set + _rateLimiter?.Fire(); + + // logging + if (_logger != null) + { + Console.WriteLine($"{req.Id} {req.Method} Sending request: {requestJson}"); + } + + // create byte buffer to avoid charset=utf-8 in content-type header + // as this is rejected by some RPC nodes + var buffer = Encoding.UTF8.GetBytes(requestJson); + using var httpReq = new HttpRequestMessage(HttpMethod.Post, (string)null) + { + Content = new ByteArrayContent(buffer) + { + Headers = { + { "Content-Type", "application/json"} + } + } + }; + + // execute POST + using (var response = await SendAsyncRequest(_httpClient, httpReq)) + { + var result = await HandleResult(req, response).ConfigureAwait(false); + result.RawRpcRequest = requestJson; + return result; + } + } + catch (HttpRequestException e) + { + var result = new RequestResult(System.Net.HttpStatusCode.BadRequest, e.Message); + result.RawRpcRequest = requestJson; + if (_logger != null) + { + Console.WriteLine($"{req.Id} {req.Method} Caught exception: {e.Message}"); + } + return result; + } + catch (Exception e) + { + var result = new RequestResult(System.Net.HttpStatusCode.BadRequest, e.Message); + result.RawRpcRequest = requestJson; + if (_logger != null) + { + Console.WriteLine($"{req.Id} {req.Method} Caught exception: {e.Message}"); + } + return result; + } + + } + + + /// + /// Handles the result after sending a request. + /// + /// The type of the result to deserialize from json. + /// The original message request. + /// The response obtained from the request. + /// A task that represents the asynchronous operation that holds the request result. + private async Task> HandleResult(JsonRpcRequest req, HttpResponseMessage response) + { + RequestResult result = new(response); + try + { + result.RawRpcResponse = await response.Content.ReadAsStringAsync().ConfigureAwait(false); + + if (_logger != null) + { + Console.WriteLine($"{req.Id} {req.Method} Result: {result.RawRpcResponse}"); + } + var res = JsonConvert.DeserializeObject>(result.RawRpcResponse, _serializerOptions); + + + if (res.Result != null) + { + result.Result = res.Result; + result.WasRequestSuccessfullyHandled = true; + } + else + { + var errorRes = JsonConvert.DeserializeObject(result.RawRpcResponse, _serializerOptions); + if (errorRes is { Error: { } }) + { + result.Reason = errorRes.Error.Message; + result.ServerErrorCode = errorRes.Error.Code; + result.ErrorData = errorRes.Error.Data; + } + else if(errorRes is { ErrorMessage: { } }) + { + result.Reason = errorRes.ErrorMessage; + } + else + { + result.Reason = "Something wrong happened."; + } + } + } + catch (JsonException e) + { + if (_logger != null) + { + Console.WriteLine($"{req.Id} {req.Method} Caught exception: {e.Message}"); + } + result.WasRequestSuccessfullyHandled = false; + result.Reason = "Unable to parse json."; + } + + return result; + } + + /// + /// Sends a batch of messages as a POST method and returns a collection of responses. + /// + /// The message request. + /// A task that represents the asynchronous operation that holds the request result. + public async Task> SendBatchRequestAsync(JsonRpcBatchRequest reqs) + { + if (reqs == null) throw new ArgumentNullException(nameof(reqs)); + if (reqs.Count == 0) throw new ArgumentException("Empty batch"); + var id_for_log = reqs.Min(x => x.Id); + var requestsJson = JsonConvert.SerializeObject(reqs, _serializerOptions); + try + { + // pre-flight check with rate limiter if set + _rateLimiter?.Fire(); + + if (_logger != null) + { + Console.WriteLine($"{id_for_log} [batch of {reqs.Count}] Sending request: {requestsJson}"); + } + + // create byte buffer to avoid charset=utf-8 in content-type header + // as this is rejected by some RPC nodes + var buffer = Encoding.UTF8.GetBytes(requestsJson); + using var httpReq = new HttpRequestMessage(HttpMethod.Post, (string)null) + { + Content = new ByteArrayContent(buffer) + { + Headers = { + { "Content-Type", "application/json"} + } + } + }; + + // execute POST + using (var response = await SendAsyncRequest(_httpClient, httpReq)) + { + var result = await HandleBatchResult(reqs, response).ConfigureAwait(false); + result.RawRpcRequest = requestsJson; + return result; + } + + } + catch (HttpRequestException e) + { + var result = new RequestResult(System.Net.HttpStatusCode.BadRequest, e.Message); + result.RawRpcRequest = requestsJson; + if (_logger != null) + { + Console.WriteLine($"{id_for_log} [batch of {reqs.Count}] Caught exception: {e.Message}"); + } + return result; + } + catch (Exception e) + { + var result = new RequestResult(System.Net.HttpStatusCode.BadRequest, e.Message); + result.RawRpcRequest = requestsJson; + if (_logger != null) + { + Console.WriteLine($"{id_for_log} [batch of {reqs.Count}] Caught exception: {e.Message}"); + } + return result; + } + + } + + /// + /// Handles the result after sending a batch of requests. + /// Outcome could be a collection of failures due to a single API issue or a mixed bag of + /// success and failure depending on the individual request outcomes. + /// + /// The original batch of request messages. + /// The batch of responses obtained from the HTTP request. + /// A task that represents the asynchronous operation that holds the request result. + private async Task> HandleBatchResult(JsonRpcBatchRequest reqs, HttpResponseMessage response) + { + var id_for_log = reqs.Min(x => x.Id); + RequestResult result = new RequestResult(response); + try + { + result.RawRpcResponse = await response.Content.ReadAsStringAsync().ConfigureAwait(false); + + if (_logger != null) + { + Console.WriteLine($"{id_for_log} [batch of {reqs.Count}] Result: {result.RawRpcResponse}"); + } + var res = JsonConvert.DeserializeObject(result.RawRpcResponse, _serializerOptions); + + if (res != null) + { + result.Result = res; + result.WasRequestSuccessfullyHandled = true; + } + else + { + var errorRes = JsonConvert.DeserializeObject(result.RawRpcResponse, _serializerOptions); + if (errorRes is { Error: { } }) + { + result.Reason = errorRes.Error.Message; + result.ServerErrorCode = errorRes.Error.Code; + result.ErrorData = errorRes.Error.Data; + } + else if (errorRes is { ErrorMessage: { } }) + { + result.Reason = errorRes.ErrorMessage; + } + else + { + result.Reason = "Something wrong happened."; + } + } + } + catch (JsonException e) + { + if (_logger != null) + { + Console.WriteLine($"{id_for_log} [batch of {reqs.Count}] Caught exception: {e.Message}"); + } + result.WasRequestSuccessfullyHandled = false; + result.Reason = "Unable to parse json."; + } + + return result; + } + + /// + /// Return True if running on Unity, False otherwise + /// + /// Return True if running on Unity, False otherwise + private bool IsUnityPlayer() + { + #if NETSTANDARD2_0 && !DEBUG + try + { + if (Application.platform != null) + { + return true; + } + } + catch (Exception) + { + return false; + } + #endif + return false; + } + + /// + /// Send an async request using HttpClient or UnityWebRequest if running on Unity + /// + /// + /// + /// + private async Task SendAsyncRequest(HttpClient httpClient, HttpRequestMessage httpReq) + { + if (IsUnityPlayer()) + { + return await SendUnityWebRequest(httpClient.BaseAddress, httpReq); + } + return await _httpClient.SendAsync(httpReq).ConfigureAwait(false); + } + + /// + /// Convert a httReq to a Unity Web request + /// + /// RPC URI + /// The http request + /// Http response + /// + private async Task SendUnityWebRequest(Uri uri, HttpRequestMessage httpReq) + { + Byte[] buffer = await httpReq.Content.ReadAsByteArrayAsync(); + using (var request = new UnityWebRequest(uri, httpReq.Method.ToString())) + { + request.uploadHandler = new UploadHandlerRaw(buffer); + request.downloadHandler = new DownloadHandlerBuffer(); + request.SetRequestHeader("Content-Type", "application/json"); + request.SendWebRequest(); + if (request.result == UnityWebRequest.Result.ConnectionError) + { + throw new HttpRequestException("Error While Sending: " + request.error); + } + while (!request.isDone) + { + await Task.Yield(); + } + var response = new HttpResponseMessage(HttpStatusCode.OK); + response.Content = new ByteArrayContent(Encoding.UTF8.GetBytes(request.downloadHandler.text)); + return response; + } + } + } + +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Http/JsonRpcClient.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Http/JsonRpcClient.cs.meta new file mode 100644 index 0000000..4cb4095 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Http/JsonRpcClient.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b219bad4cd04b034290bb78731fd83a1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Http/RequestResult.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Http/RequestResult.cs new file mode 100644 index 0000000..c12905a --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Http/RequestResult.cs @@ -0,0 +1,89 @@ +using Solana.Unity.Rpc.Models; +using System.Collections.Generic; +using System.Net; +using System.Net.Http; + +namespace Solana.Unity.Rpc.Core.Http +{ + /// + /// Represents the result of a given request. + /// + /// The type of the result. + public class RequestResult : IRequestResult + { + /// + /// Returns true if the request was successfully handled and parsed. + /// + public bool WasSuccessful => WasHttpRequestSuccessful && WasRequestSuccessfullyHandled; + + /// + /// Returns true if the HTTP request was successful (e.g. Code 200). + /// + public bool WasHttpRequestSuccessful { get; set; } + + /// + /// Returns true if the request was successfully handled by the server and no error parameters are found in the result. + /// + public bool WasRequestSuccessfullyHandled { get; set; } + + /// + /// Returns a string with the reason for the error if is false. + /// + public string Reason { get; set; } + + /// + /// Returns the actual result of the request if is true. + /// + public T Result { get; set; } + + /// + /// Returns the of the request. + /// + public HttpStatusCode HttpStatusCode { get; set; } + + /// + /// Returns the error code if one was found in the error object when the server is unable to handle the request. + /// + public int ServerErrorCode { get; set; } + + /// + /// The error data, if applicable. + /// + public ErrorData ErrorData { get; set; } + + /// + /// Contains the JSON RPC request payload + /// + public string RawRpcRequest { get; internal set; } + + /// + /// Contains the JSON RPC response payload + /// + public string RawRpcResponse { get; internal set; } + + /// + /// Initialize the request result. + /// An http request result. + /// The type of the request result. + /// + public RequestResult(HttpResponseMessage resultMsg, T result = default(T)) + { + HttpStatusCode = resultMsg.StatusCode; + WasHttpRequestSuccessful = resultMsg.IsSuccessStatusCode; + Reason = resultMsg.ReasonPhrase; + Result = result; + } + + /// + /// Added default constructor to facilitate unit tests. + /// + public RequestResult() { } + + internal RequestResult(HttpStatusCode code, string reason) + { + HttpStatusCode = code; + Reason = reason; + WasHttpRequestSuccessful = false; + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Http/RequestResult.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Http/RequestResult.cs.meta new file mode 100644 index 0000000..c7342ea --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Http/RequestResult.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1bacfe303fd08fa45ac955ec75dbd16f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/IdGenerator.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/IdGenerator.cs new file mode 100644 index 0000000..8be7162 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/IdGenerator.cs @@ -0,0 +1,26 @@ +namespace Solana.Unity.Rpc.Core +{ + /// + /// Id generator. + /// + internal class IdGenerator + { + + /// + /// The id of the last request performed + /// + private int _id; + + /// + /// Gets the id of the next request. + /// + /// The id. + internal int GetNextId() + { + lock (this) + { + return _id++; + } + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/IdGenerator.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/IdGenerator.cs.meta new file mode 100644 index 0000000..5e36aa1 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/IdGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dbcfc16e9ec89cd408cf6c93f46a5eb6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Sockets.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Sockets.meta new file mode 100644 index 0000000..3e35a37 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Sockets.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ee655c6efedf59f41bbbd2765686e1e0 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Sockets/IWebSocket.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Sockets/IWebSocket.cs new file mode 100644 index 0000000..25c082b --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Sockets/IWebSocket.cs @@ -0,0 +1,19 @@ +using System; +using System.Net.WebSockets; +using System.Threading; +using System.Threading.Tasks; + +namespace Solana.Unity.Rpc.Core.Sockets +{ + internal interface IWebSocket : IDisposable + { + WebSocketState State { get; } + string CloseStatusDescription { get; } + WebSocketCloseStatus? CloseStatus { get; } + Task ConnectAsync(Uri uri, CancellationToken cancellationToken); + Task CloseAsync(CancellationToken cancellationToken); + Task SendAsync(ReadOnlyMemory buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken); + Task CloseAsync(WebSocketCloseStatus closeStatus, string statusDescription, CancellationToken cancellationToken); + Task ReceiveAsync(Memory buffer, CancellationToken cancellationToken); + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Sockets/IWebSocket.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Sockets/IWebSocket.cs.meta new file mode 100644 index 0000000..4f5fc84 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Sockets/IWebSocket.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3d718a15187d7ed4f9cadf73bc1f2000 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Sockets/StreamingRpcClient.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Sockets/StreamingRpcClient.cs new file mode 100644 index 0000000..4e0b41f --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Sockets/StreamingRpcClient.cs @@ -0,0 +1,222 @@ +using Solana.Unity.Rpc.Types; +using System; +using System.IO; +using System.Net.WebSockets; +using System.Threading; +using System.Threading.Tasks; + +namespace Solana.Unity.Rpc.Core.Sockets +{ + /// + /// Base streaming Rpc client class that abstracts the websocket handling. + /// + internal abstract class StreamingRpcClient : IDisposable + { + private SemaphoreSlim _sem; + + /// + /// The web socket client abstraction. + /// + protected IWebSocket ClientSocket; + + private bool disposedValue; + + /// + /// The logger instance. + /// + protected readonly object _logger; + + /// + public Uri NodeAddress { get; } + + /// + public WebSocketState State => ClientSocket.State; + + /// + public event EventHandler ConnectionStateChangedEvent; + + private ConnectionStats _connectionStats; + + /// + /// Statistics of the current connection. + /// + public IConnectionStatistics Statistics => _connectionStats; + + /// + /// The internal constructor that setups the client. + /// + /// The url of the streaming RPC server. + /// The possible logger instance. + /// The possible websocket instance. A new instance will be created if null. + /// The possible ClientWebSocket instance. A new instance will be created if null. + protected StreamingRpcClient(string url, object logger, IWebSocket socket = default, ClientWebSocket clientWebSocket = default) + { + NodeAddress = new Uri(url); + ClientSocket = socket ?? new WebSocketWrapper(clientWebSocket ?? new ClientWebSocket()); + _logger = logger; + _sem = new SemaphoreSlim(1, 1); + _connectionStats = new ConnectionStats(); + } + + /// + /// Initializes the websocket connection and starts receiving messages asynchronously. + /// + /// Returns the task representing the asynchronous task. + public async Task ConnectAsync() + { + _sem.Wait(); + try + { + if (ClientSocket.State != WebSocketState.Open) + { + await ClientSocket.ConnectAsync(NodeAddress, CancellationToken.None).ConfigureAwait(false); + _ = Task.Run(StartListening); + ConnectionStateChangedEvent?.Invoke(this, State); + } + } + finally + { + _sem.Release(); + } + } + + /// + public async Task DisconnectAsync() + { + _sem.Wait(); + try + { + if (ClientSocket.State == WebSocketState.Open) + { + await ClientSocket.CloseAsync(CancellationToken.None); + + //notify at the end of StartListening loop, given that it should end as soon as we terminate connection here + //and will also notify when there is a non-user triggered disconnection event + + // handle disconnection cleanup + ClientSocket.Dispose(); + ClientSocket = new WebSocketWrapper(new ClientWebSocket()); + CleanupSubscriptions(); + } + } + finally + { + _sem.Release(); + } + } + + /// + /// Starts listeing to new messages. + /// + /// Returns the task representing the asynchronous task. + private async Task StartListening() + { + while (ClientSocket.State == WebSocketState.Open) + { + try + { + await ReadNextMessage().ConfigureAwait(false); + } + catch (Exception e) + { + if (_logger != null) + { + Console.WriteLine($"Exception trying to read next message: {e.Message}"); + } + } + } + + if (_logger != null) + { + Console.WriteLine($"Stopped reading messages. ClientSocket.State changed to {ClientSocket.State}"); + } + ConnectionStateChangedEvent?.Invoke(this, State); + } + + /// + /// Reads the next message from the socket. + /// + /// The cancelation token. + /// Returns the task representing the asynchronous task. + private async Task ReadNextMessage(CancellationToken cancellationToken = default) + { + var buffer = new byte[32768]; + Memory mem = new Memory(buffer); + WebSocketReceiveResult result = await ClientSocket.ReceiveAsync(mem, cancellationToken).ConfigureAwait(false); + int count = result.Count; + + if (result.MessageType == WebSocketMessageType.Close) + { + await ClientSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, cancellationToken); + } + else + { + if (!result.EndOfMessage) + { + MemoryStream ms = new MemoryStream(); + ms.Write(mem.Span.ToArray(), 0, mem.Span.Length); + + + while (!result.EndOfMessage) + { + result = await ClientSocket.ReceiveAsync(mem, cancellationToken).ConfigureAwait(false); + + var memSlice = mem.Slice(0, result.Count).Span.ToArray(); + ms.Write(memSlice, 0, memSlice.Length); + count += result.Count; + } + + mem = new Memory(ms.ToArray()); + } + else + { + mem = mem.Slice(0, count); + } + _connectionStats.AddReceived((uint)count); + HandleNewMessage(mem); + } + } + + /// + /// Handless a new message payload. + /// + /// The message payload. + protected abstract void HandleNewMessage(Memory messagePayload); + + /// + /// Clean up subscription objects after disconnection. + /// + protected abstract void CleanupSubscriptions(); + + protected virtual void Dispose(bool disposing) + { + if (!disposedValue) + { + if (disposing) + { + ClientSocket.Dispose(); + _sem.Dispose(); + } + + // TODO: free unmanaged resources (unmanaged objects) and override finalizer + // TODO: set large fields to null + disposedValue = true; + } + } + + // // TODO: override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources + // ~StreamingRpcClient() + // { + // // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + // Dispose(disposing: false); + // } + + /// + public void Dispose() + { + // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + Dispose(disposing: true); + GC.SuppressFinalize(this); + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Sockets/StreamingRpcClient.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Sockets/StreamingRpcClient.cs.meta new file mode 100644 index 0000000..e6155c6 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Sockets/StreamingRpcClient.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5664288b2d736a845a1f9e40265c715f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Sockets/SubscriptionChannel.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Sockets/SubscriptionChannel.cs new file mode 100644 index 0000000..6104526 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Sockets/SubscriptionChannel.cs @@ -0,0 +1,37 @@ +namespace Solana.Unity.Rpc.Core.Sockets +{ + /// + /// Represents the channel of a given subscription. + /// + public enum SubscriptionChannel + { + /// + /// Account subscription (accountSubscribe). + /// + TokenAccount, + /// + /// Account subscription (accountSubscribe). + /// + Account, + /// + /// Logs subscription (logsSubscribe). + /// + Logs, + /// + /// Program subscription (programSubscribe). + /// + Program, + /// + /// Signature subscription (signatureSubscribe). + /// + Signature, + /// + /// Slot subscription (slotSubscribe). + /// + Slot, + /// + /// Root subscription (rootSubscribe). + /// + Root + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Sockets/SubscriptionChannel.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Sockets/SubscriptionChannel.cs.meta new file mode 100644 index 0000000..7a65f2b --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Sockets/SubscriptionChannel.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f65143be0c12d28439826264e030c368 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Sockets/SubscriptionEvent.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Sockets/SubscriptionEvent.cs new file mode 100644 index 0000000..59ddf08 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Sockets/SubscriptionEvent.cs @@ -0,0 +1,38 @@ +using System; + +namespace Solana.Unity.Rpc.Core.Sockets +{ + /// + /// Represents an event related to a given subscription. + /// + public class SubscriptionEvent : EventArgs + { + /// + /// The new status of the subscription. + /// + public SubscriptionStatus Status { get; } + + /// + /// A possible error mssage for this event. + /// + public string Error { get; } + + /// + /// A possible error code for this event. + /// + public string Code { get; } + + /// + /// Constructor. + /// + /// The new status. + /// The possible error message. + /// The possible error code. + public SubscriptionEvent(SubscriptionStatus status, string error = default, string code = default) + { + Status = status; + Error = error; + Code = code; + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Sockets/SubscriptionEvent.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Sockets/SubscriptionEvent.cs.meta new file mode 100644 index 0000000..cc2dc0f --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Sockets/SubscriptionEvent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b5f1f13c2b658c7408b13313ee38aa26 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Sockets/SubscriptionState.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Sockets/SubscriptionState.cs new file mode 100644 index 0000000..00fc208 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Sockets/SubscriptionState.cs @@ -0,0 +1,127 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Solana.Unity.Rpc.Core.Sockets +{ + /// + /// Represents the state of a given subscription. + /// + public abstract class SubscriptionState + { + /// + /// Streaming client reference for easy unsubscription. + /// + private readonly IStreamingRpcClient _rpcClient; + + /// + /// The subscription ID as confirmed by the node. + /// + internal int SubscriptionId { get; set; } + + /// + /// The channel subscribed. + /// + public SubscriptionChannel Channel { get; protected set; } + + /// + /// The current state of the subscription. + /// + public SubscriptionStatus State { get; protected set; } + + /// + /// The last error message. + /// + public string LastError { get; protected set; } + + /// + /// The last error code. + /// + public string LastCode { get; protected set; } + + /// + /// The collection of parameters that were submitted for this subscription. + /// + public List AdditionalParameters { get; protected set; } + + /// + /// Event fired when the state of the subcription changes. + /// + public event EventHandler SubscriptionChanged; + + /// + /// Base constructor. + /// + /// The streaming rpc client reference. + /// The channel of this subscription. + /// Additional parameters for this given subscription. + protected SubscriptionState(IStreamingRpcClient rpcClient, SubscriptionChannel chan, IList additionalParameters = default) + { + _rpcClient = rpcClient; + Channel = chan; + AdditionalParameters = additionalParameters?.ToList(); + } + + /// + /// Default constructor to help setup tests. + /// + protected SubscriptionState() { } + + /// + /// Changes the state of the subscription and invokes the event. + /// + /// The new state of the subscription. + /// The possible error message. + /// The possible error code. + internal void ChangeState(SubscriptionStatus newState, string error = null, string code = null) + { + State = newState; + LastError = error; + LastCode = code; + SubscriptionChanged?.Invoke(this, new SubscriptionEvent(newState, error, code)); + } + + /// + /// Invokes the data handler. + /// + /// The data. + protected internal abstract void HandleData(object data); + + /// + /// Unsubscribes the current subscription. + /// + public void Unsubscribe() => _rpcClient.Unsubscribe(this); + + /// + public async Task UnsubscribeAsync() => await _rpcClient.UnsubscribeAsync(this).ConfigureAwait(false); + } + + /// + /// Represents the state of a given subscription with specified type handler. + /// + /// The type of the data received by this subscription. + internal class SubscriptionState : SubscriptionState + { + /// + /// The data handler reference. + /// + internal Action, T> DataHandler; + + /// + /// Constructor with all parameters related to a given subscription. + /// + /// The streaming rpc client reference. + /// The channel of this subscription. + /// The handler for the data received. + /// Additional parameters for this given subscription. + internal SubscriptionState(SolanaStreamingRpcClient rpcClient, SubscriptionChannel chan, Action handler, IList additionalParameters = default) + : base(rpcClient, chan, additionalParameters) + { + DataHandler = handler; + } + + /// + protected internal override void HandleData(object data) => DataHandler(this, (T)data); + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Sockets/SubscriptionState.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Sockets/SubscriptionState.cs.meta new file mode 100644 index 0000000..598a8b2 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Sockets/SubscriptionState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4d9889555bcd9774a83922f0f4a4af88 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Sockets/SubscriptionStatus.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Sockets/SubscriptionStatus.cs new file mode 100644 index 0000000..2b07c04 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Sockets/SubscriptionStatus.cs @@ -0,0 +1,28 @@ +namespace Solana.Unity.Rpc.Core.Sockets +{ + /// + /// Represents the status of a subscription. + /// + public enum SubscriptionStatus + { + /// + /// Waiting for the subscription message to be handled. + /// + WaitingResult, + + /// + /// The subscription was terminated. + /// + Unsubscribed, + + /// + /// The subscription is still alive. + /// + Subscribed, + + /// + /// There was an error during subscription. + /// + ErrorSubscribing + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Sockets/SubscriptionStatus.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Sockets/SubscriptionStatus.cs.meta new file mode 100644 index 0000000..654aee6 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Sockets/SubscriptionStatus.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ae8b57b5b2b501a49afeb656eca680df +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Sockets/WebSocketWrapper.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Sockets/WebSocketWrapper.cs new file mode 100644 index 0000000..98c8acd --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Sockets/WebSocketWrapper.cs @@ -0,0 +1,60 @@ +using System; +using System.Net.WebSockets; +using System.Threading; +using System.Threading.Tasks; + +namespace Solana.Unity.Rpc.Core.Sockets +{ + internal class WebSocketWrapper : IWebSocket + { + private readonly ClientWebSocket webSocket; + + internal WebSocketWrapper(ClientWebSocket webSocket) + { + this.webSocket = webSocket; + } + + public WebSocketCloseStatus? CloseStatus => webSocket.CloseStatus; + + public string CloseStatusDescription => webSocket.CloseStatusDescription; + + public WebSocketState State => webSocket.State; + + public Task CloseAsync(WebSocketCloseStatus closeStatus, string statusDescription, CancellationToken cancellationToken) + => webSocket.CloseAsync(closeStatus, statusDescription, cancellationToken); + + public Task ConnectAsync(Uri uri, CancellationToken cancellationToken) + => webSocket.ConnectAsync(uri, cancellationToken); + + public Task CloseAsync(CancellationToken cancellationToken) + => webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, null, cancellationToken); + + public Task ReceiveAsync(Memory buffer, CancellationToken cancellationToken) + => webSocket.ReceiveAsync(new ArraySegment(buffer.ToArray()), cancellationToken); + + public Task SendAsync(ReadOnlyMemory buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken) + => webSocket.SendAsync(new ArraySegment(buffer.ToArray()), messageType, endOfMessage, cancellationToken); + + #region IDisposable Support + private bool disposedValue = false; // To detect redundant calls + + private void Dispose(bool disposing) + { + if (!disposedValue) + { + if (disposing) + { + webSocket.Dispose(); + } + + disposedValue = true; + } + } + + public void Dispose() + { + Dispose(true); + } + #endregion + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Sockets/WebSocketWrapper.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Sockets/WebSocketWrapper.cs.meta new file mode 100644 index 0000000..48bf7b3 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Core/Sockets/WebSocketWrapper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fc6b39d435ccc544c88c86842367f79e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/IRpcClient.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/IRpcClient.cs new file mode 100644 index 0000000..d793134 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/IRpcClient.cs @@ -0,0 +1,1244 @@ +using Solana.Unity.Rpc.Core.Http; +using Solana.Unity.Rpc.Messages; +using Solana.Unity.Rpc.Models; +using Solana.Unity.Rpc.Types; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Solana.Unity.Rpc +{ + /// + /// Specifies the methods to interact with the JSON RPC API. + /// + public interface IRpcClient + { + /// + /// The address this client connects to. + /// + Uri NodeAddress { get; } + + /// + /// Gets the token mint info. This method only works if the target account is a SPL token mint. + /// + /// The commitment parameter is optional, the default value is not sent. + /// + /// + /// The token mint public key. + /// The state commitment to consider when querying the ledger state. + /// A task which may return a request result holding the context and account info. + Task>> GetTokenMintInfoAsync(string pubKey, + Commitment commitment = Commitment.Finalized); + + /// + /// Gets the token mint info. This method only works if the target account is a SPL token mint. + /// + /// The commitment parameter is optional, the default value is not sent. + /// + /// + /// The token mint public key. + /// The state commitment to consider when querying the ledger state. + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult> GetTokenMintInfo(string pubKey, Commitment commitment = Commitment.Finalized); + + /// + /// Gets the token account info. + /// + /// The commitment parameter is optional, the default value is not sent. + /// + /// + /// The token account public key. + /// The state commitment to consider when querying the ledger state. + /// A task which may return a request result holding the context and account info. + Task>> GetTokenAccountInfoAsync(string pubKey, + Commitment commitment = Commitment.Finalized); + + /// + /// Gets the token account info. + /// + /// The commitment parameter is optional, the default value is not sent. + /// + /// + /// The token account public key. + /// The state commitment to consider when querying the ledger state. + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult> GetTokenAccountInfo(string pubKey, Commitment commitment = Commitment.Finalized); + + /// + /// Gets the account info. + /// + /// The commitment parameter is optional, the default value is not sent. + /// + /// + /// The account public key. + /// The state commitment to consider when querying the ledger state. + /// The encoding of the account data. + /// A task which may return a request result holding the context and account info. + Task>> GetAccountInfoAsync(string pubKey, + Commitment commitment = Commitment.Finalized, BinaryEncoding encoding = BinaryEncoding.Base64); + + /// + /// Gets the account info. + /// + /// The commitment parameter is optional, the default value is not sent. + /// + /// + /// The account public key. + /// The state commitment to consider when querying the ledger state. + /// The encoding of the account data. + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult> GetAccountInfo(string pubKey, Commitment commitment = Commitment.Finalized, + BinaryEncoding encoding = BinaryEncoding.Base64); + + /// + /// Gets the balance asynchronously for a certain public key. + /// + /// The commitment parameter is optional, the default value is not sent. + /// + /// + /// The public key. + /// The state commitment to consider when querying the ledger state. + /// A task which may return a request result holding the context and address balance. + Task>> GetBalanceAsync(string pubKey, Commitment commitment = Commitment.Finalized); + + /// + /// Gets the balance synchronously for a certain public key. + /// + /// The commitment parameter is optional, the default value is not sent. + /// + /// + /// The public key. + /// The state commitment to consider when querying the ledger state. + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult> GetBalance(string pubKey, Commitment commitment = Commitment.Finalized); + + /// + /// Returns identity and transaction information about a block in the ledger. + /// + /// + /// The commitment parameter is optional, is not supported, + /// the default value is not sent. + /// + /// + /// The transactionDetails parameter is optional, the default value is not sent. + /// + /// + /// The blockRewards parameter is optional, the default value, false, is not sent. + /// + /// + /// + /// The slot. + /// The state commitment to consider when querying the ledger state. + /// The level of transaction detail to return, see . + /// Whether to populate the rewards array, the default includes rewards. + /// Returns a task that holds the asynchronous operation result and state. + Task> GetBlockAsync(ulong slot, Commitment commitment = Commitment.Finalized, + TransactionDetailsFilterType transactionDetails = TransactionDetailsFilterType.Full, bool blockRewards = false); + + /// + /// Returns identity and transaction information about a confirmed block in the ledger. + /// + /// + /// The commitment parameter is optional, is not supported, + /// the default value is not sent. + /// + /// + /// The transactionDetails parameter is optional, the default value is not sent. + /// + /// + /// The blockRewards parameter is optional, the default value, false, is not sent. + /// + /// + /// + /// The slot. + /// The state commitment to consider when querying the ledger state. + /// The level of transaction detail to return, see . + /// Whether to populate the rewards array, the default includes rewards. + /// Returns a task that holds the asynchronous operation result and state. + [Obsolete("Please use GetBlockAsync whenever possible instead. This method is expected to be removed in solana-core v1.8.")] + Task> GetConfirmedBlockAsync(ulong slot, Commitment commitment = Commitment.Finalized, + TransactionDetailsFilterType transactionDetails = TransactionDetailsFilterType.Full, bool blockRewards = false); + + /// + /// Returns identity and transaction information about a block in the ledger. + /// + /// + /// The commitment parameter is optional, is not supported, + /// the default value is not sent. + /// + /// + /// The transactionDetails parameter is optional, the default value is not sent. + /// + /// + /// The blockRewards parameter is optional, the default value, false, is not sent. + /// + /// + /// + /// The slot. + /// The state commitment to consider when querying the ledger state. + /// The level of transaction detail to return, see . + /// Whether to populate the rewards array, the default includes rewards. + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult GetBlock(ulong slot, Commitment commitment = Commitment.Finalized, + TransactionDetailsFilterType transactionDetails = TransactionDetailsFilterType.Full, bool blockRewards = false); + + /// + /// Returns identity and transaction information about a confirmed block in the ledger. + /// + /// + /// The commitment parameter is optional, is not supported, + /// the default value is not sent. + /// + /// + /// The transactionDetails parameter is optional, the default value is not sent. + /// + /// + /// The blockRewards parameter is optional, the default value, false, is not sent. + /// + /// + /// + /// The slot. + /// The state commitment to consider when querying the ledger state. + /// The level of transaction detail to return, see . + /// Whether to populate the rewards array, the default includes rewards. + /// Returns an object that wraps the result along with possible errors with the request. + [Obsolete("Please use GetBlock whenever possible instead. This method is expected to be removed in solana-core v1.8.")] + RequestResult GetConfirmedBlock(ulong slot, Commitment commitment = Commitment.Finalized, + TransactionDetailsFilterType transactionDetails = TransactionDetailsFilterType.Full, bool blockRewards = false); + + /// + /// Gets the block commitment of a certain block, identified by slot. + /// + /// The slot. + /// Returns a task that holds the asynchronous operation result and state. + Task> GetBlockCommitmentAsync(ulong slot); + + /// + /// Gets the block commitment of a certain block, identified by slot. + /// + /// The slot. + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult GetBlockCommitment(ulong slot); + + /// + /// Gets the current block height of the node. + /// + /// The commitment state to consider when querying the ledger state. + /// Returns a task that holds the asynchronous operation result and state. + Task> GetBlockHeightAsync(Commitment commitment = Commitment.Finalized); + + /// + /// Gets the current block height of the node. + /// + /// The commitment state to consider when querying the ledger state. + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult GetBlockHeight(Commitment commitment = Commitment.Finalized); + + /// + /// Returns recent block production information from the current or previous epoch. + /// + /// All the arguments are optional, but the lastSlot must be paired with a firstSlot argument. + /// + /// + /// Filter production details only for this given validator. + /// The first slot to return production information (inclusive). + /// The last slot to return production information (inclusive and optional). + /// The state commitment to consider when querying the ledger state. + /// Returns a task that holds the asynchronous operation result and state. + Task>> GetBlockProductionAsync(string identity = null, + ulong? firstSlot = null, ulong? lastSlot = null, Commitment commitment = Commitment.Finalized); + + /// + /// Returns recent block production information from the current or previous epoch. + /// + /// + /// All the arguments are optional, but the lastSlot must be paired with a firstSlot argument. + /// + /// Filter production details only for this given validator. + /// The first slot to return production information (inclusive). + /// The last slot to return production information (inclusive and optional). + /// The state commitment to consider when querying the ledger state. + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult> GetBlockProduction(string identity = null, + ulong? firstSlot = null, ulong? lastSlot = null, Commitment commitment = Commitment.Finalized); + + /// + /// Returns a list of blocks between two slots. + /// + /// The start slot (inclusive). + /// The start slot (inclusive and optional). + /// The state commitment to consider when querying the ledger state. + /// Returns a task that holds the asynchronous operation result and state. + Task>> GetBlocksAsync(ulong startSlot, ulong endSlot = 0, + Commitment commitment = Commitment.Finalized); + + /// + /// Returns a list of confirmed blocks between two slots. + /// + /// + /// + /// The commitment parameter is optional, is not supported, + /// the default value is not sent. + /// + /// + /// The start slot (inclusive). + /// The start slot (inclusive and optional). + /// The state commitment to consider when querying the ledger state. + /// Returns a task that holds the asynchronous operation result and state. + [Obsolete("Please use GetBlocksAsync whenever possible instead. This method is expected to be removed in solana-core v1.8.")] + Task>> GetConfirmedBlocksAsync(ulong startSlot, ulong endSlot = 0, Commitment commitment = Commitment.Finalized); + + /// + /// Returns a list of blocks between two slots. + /// + /// The start slot (inclusive). + /// The start slot (inclusive and optional). + /// The state commitment to consider when querying the ledger state. + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult> GetBlocks(ulong startSlot, ulong endSlot = 0, + Commitment commitment = Commitment.Finalized); + + /// + /// Returns a list of confirmed blocks between two slots. + /// + /// + /// + /// The commitment parameter is optional, is not supported, + /// the default value is not sent. + /// + /// + /// The start slot (inclusive). + /// The start slot (inclusive and optional). + /// The state commitment to consider when querying the ledger state. + /// Returns an object that wraps the result along with possible errors with the request. + [Obsolete("Please use GetBlocks whenever possible instead. This method is expected to be removed in solana-core v1.8.")] + RequestResult> GetConfirmedBlocks(ulong startSlot, ulong endSlot = 0, Commitment commitment = Commitment.Finalized); + + /// + /// Returns a list of confirmed blocks starting at the given slot. + /// + /// The start slot (inclusive). + /// The max number of blocks to return. + /// The state commitment to consider when querying the ledger state. + /// Returns a task that holds the asynchronous operation result and state. + Task>> GetBlocksWithLimitAsync(ulong startSlot, + ulong limit, Commitment commitment = Commitment.Finalized); + + /// + /// Returns a list of confirmed blocks starting at the given slot. + /// + /// The start slot (inclusive). + /// The max number of blocks to return. + /// The state commitment to consider when querying the ledger state. + /// Returns a task that holds the asynchronous operation result and state. + [Obsolete("Please use GetBlocksWithLimitAsync whenever possible instead. This method is expected to be removed in solana-core v1.8.")] + Task>> GetConfirmedBlocksWithLimitAsync(ulong startSlot, + ulong limit, Commitment commitment = Commitment.Finalized); + + /// + /// Returns a list of confirmed blocks starting at the given slot. + /// + /// The start slot (inclusive). + /// The max number of blocks to return. + /// The state commitment to consider when querying the ledger state. + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult> GetBlocksWithLimit(ulong startSlot, ulong limit, + Commitment commitment = Commitment.Finalized); + + /// + /// Returns a list of confirmed blocks starting at the given slot. + /// + /// The start slot (inclusive). + /// The max number of blocks to return. + /// The state commitment to consider when querying the ledger state. + /// Returns a task that holds the asynchronous operation result and state. + [Obsolete("Please use GetBlocksWithLimit whenever possible instead. This method is expected to be removed in solana-core v1.8.")] + RequestResult> GetConfirmedBlocksWithLimit(ulong startSlot, + ulong limit, Commitment commitment = Commitment.Finalized); + + /// + /// Gets the estimated production time for a certain block, identified by slot. + /// + /// The slot. + /// Returns a task that holds the asynchronous operation result and state. + Task> GetBlockTimeAsync(ulong slot); + + /// + /// Gets the estimated production time for a certain block, identified by slot. + /// + /// The slot. + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult GetBlockTime(ulong slot); + + /// + /// Gets the cluster nodes. + /// + /// Returns a task that holds the asynchronous operation result and state. + Task>> GetClusterNodesAsync(); + + /// + /// Gets the cluster nodes. + /// + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult> GetClusterNodes(); + + /// + /// Gets information about the current epoch. + /// + /// The commitment state to consider when querying the ledger state. + /// Returns a task that holds the asynchronous operation result and state. + Task> GetEpochInfoAsync(Commitment commitment = Commitment.Finalized); + + /// + /// Gets information about the current epoch. + /// + /// The commitment state to consider when querying the ledger state. + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult GetEpochInfo(Commitment commitment = Commitment.Finalized); + + /// + /// Gets epoch schedule information from this cluster's genesis config. + /// + /// Returns a task that holds the asynchronous operation result and state. + Task> GetEpochScheduleAsync(); + + /// + /// Gets epoch schedule information from this cluster's genesis config. + /// + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult GetEpochSchedule(); + + /// + /// Gets the fee calculator associated with the query blockhash, or null if the blockhash has expired. + /// + /// The blockhash to query, as base-58 encoded string. + /// The state commitment to consider when querying the ledger state. + /// Returns a task that holds the asynchronous operation result and state. + Task>> GetFeeCalculatorForBlockhashAsync( + string blockhash, Commitment commitment = Commitment.Finalized); + + /// + /// Gets the fee calculator associated with the query blockhash, or null if the blockhash has expired. + /// + /// The blockhash to query, as base-58 encoded string. + /// The state commitment to consider when querying the ledger state. + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult> GetFeeCalculatorForBlockhash(string blockhash, + Commitment commitment = Commitment.Finalized); + + /// + /// Gets the fee rate governor information from the root bank. + /// + /// Returns a task that holds the asynchronous operation result and state. + Task>> GetFeeRateGovernorAsync(); + + /// + /// Gets the fee rate governor information from the root bank. + /// + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult> GetFeeRateGovernor(); + + /// + /// Gets a recent block hash from the ledger, a fee schedule that can be used to compute the + /// cost of submitting a transaction using it, and the last slot in which the blockhash will be valid. + /// + /// The state commitment to consider when querying the ledger state. + /// Returns a task that holds the asynchronous operation result and state. + Task>> GetFeesAsync(Commitment commitment = Commitment.Finalized); + + /// + /// Gets a recent block hash from the ledger, a fee schedule that can be used to compute the + /// cost of submitting a transaction using it, and the last slot in which the blockhash will be valid. + /// + /// The state commitment to consider when querying the ledger state. + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult> GetFees(Commitment commitment = Commitment.Finalized); + + /// + /// Returns the slot of the lowest confirmed block that has not been purged from the ledger. + /// + /// Returns a task that holds the asynchronous operation result and state. + Task> GetFirstAvailableBlockAsync(); + + /// + /// Returns the slot of the lowest confirmed block that has not been purged from the ledger. + /// + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult GetFirstAvailableBlock(); + + /// + /// Gets the genesis hash of the ledger. + /// + /// Returns a task that holds the asynchronous operation result and state. + Task> GetGenesisHashAsync(); + + /// + /// Gets the genesis hash of the ledger. + /// + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult GetGenesisHash(); + + /// + /// Returns the current health of the node. + /// This method should return the string 'ok' if the node is healthy, or the error code along with any information provided otherwise. + /// + /// Returns a task that holds the asynchronous operation result and state. + Task> GetHealthAsync(); + + /// + /// Returns the current health of the node. + /// This method should return the string 'ok' if the node is healthy, or the error code along with any information provided otherwise. + /// + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult GetHealth(); + + /// + /// Gets the identity pubkey for the current node. + /// + /// Returns a task that holds the asynchronous operation result and state. + Task> GetIdentityAsync(); + + /// + /// Gets the identity pubkey for the current node. + /// + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult GetIdentity(); + + /// + /// Gets the current inflation governor. + /// + /// The state commitment to consider when querying the ledger state. + /// Returns a task that holds the asynchronous operation result and state. + Task> GetInflationGovernorAsync(Commitment commitment = Commitment.Finalized); + + /// + /// Gets the current inflation governor. + /// + /// The state commitment to consider when querying the ledger state. + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult GetInflationGovernor(Commitment commitment = Commitment.Finalized); + + /// + /// Gets the specific inflation values for the current epoch. + /// + /// Returns a task that holds the asynchronous operation result and state. + Task> GetInflationRateAsync(); + + /// + /// Gets the specific inflation values for the current epoch. + /// + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult GetInflationRate(); + + /// + /// Gets the inflation reward for a list of addresses for an epoch. + /// + /// The list of addresses to query, as base-58 encoded strings. + /// The epoch. + /// The state commitment to consider when querying the ledger state. + /// Returns a task that holds the asynchronous operation result and state. + Task>> GetInflationRewardAsync(IList addresses, + ulong epoch = 0, Commitment commitment = Commitment.Finalized); + + /// + /// Gets the inflation reward for a list of addresses for an epoch. + /// + /// The list of addresses to query, as base-58 encoded strings. + /// The epoch. + /// The state commitment to consider when querying the ledger state. + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult> GetInflationReward(IList addresses, ulong epoch = 0, + Commitment commitment = Commitment.Finalized); + + /// + /// Gets the 20 largest accounts, by lamport balance. + /// + /// Results may be cached up to two hours. + /// Filter results by account type. + /// The state commitment to consider when querying the ledger state. + /// Returns a task that holds the asynchronous operation result and state. + Task>>> GetLargestAccountsAsync(AccountFilterType? filter = null, + Commitment commitment = Commitment.Finalized); + + /// + /// Gets the 20 largest accounts, by lamport balance. + /// + /// Results may be cached up to two hours. + /// Filter results by account type. + /// The state commitment to consider when querying the ledger state. + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult>> GetLargestAccounts(AccountFilterType? filter = null, + Commitment commitment = Commitment.Finalized); + + /// + /// Returns the leader schedule for an epoch. + /// + /// Fetch the leader schedule for the epoch that corresponds to the provided slot. + /// If unspecified, the leader schedule for the current epoch is fetched. + /// Filter results for this validator only (base 58 encoded string and optional). + /// The state commitment to consider when querying the ledger state. + /// Returns a task that holds the asynchronous operation result and state. + Task>>> GetLeaderScheduleAsync(ulong slot = 0, + string identity = null, Commitment commitment = Commitment.Finalized); + + /// + /// Returns the leader schedule for an epoch. + /// + /// Fetch the leader schedule for the epoch that corresponds to the provided slot. + /// If unspecified, the leader schedule for the current epoch is fetched. + /// Filter results for this validator only (base 58 encoded string and optional). + /// The state commitment to consider when querying the ledger state. + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult>> GetLeaderSchedule(ulong slot = 0, + string identity = null, Commitment commitment = Commitment.Finalized); + + /// + /// Gets the maximum slot seen from retransmit stage. + /// + /// Returns a task that holds the asynchronous operation result and state. + Task> GetMaxRetransmitSlotAsync(); + + /// + /// Gets the maximum slot seen from retransmit stage. + /// + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult GetMaxRetransmitSlot(); + + /// + /// Gets the maximum slot seen from after shred insert. + /// + /// Returns a task that holds the asynchronous operation result and state. + Task> GetMaxShredInsertSlotAsync(); + + /// + /// Gets the maximum slot seen from after shred insert. + /// + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult GetMaxShredInsertSlot(); + + /// + /// Gets the minimum balance required to make account rent exempt. + /// + /// The account data size. + /// The state commitment to consider when querying the ledger state. + /// Returns a task that holds the asynchronous operation result and state. + Task> GetMinimumBalanceForRentExemptionAsync(long accountDataSize, + Commitment commitment = Commitment.Finalized); + + /// + /// Gets the minimum balance required to make account rent exempt. + /// + /// The account data size. + /// The state commitment to consider when querying the ledger state. + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult GetMinimumBalanceForRentExemption(long accountDataSize, + Commitment commitment = Commitment.Finalized); + + /// + /// Gets the lowest slot that the node has information about in its ledger. + /// + /// This value may decrease over time if a node is configured to purging data. + /// + /// + /// Returns a task that holds the asynchronous operation result and state. + Task> GetMinimumLedgerSlotAsync(); + + /// + /// Gets the lowest slot that the node has information about in its ledger. + /// + /// This value may decrease over time if a node is configured to purging data. + /// + /// + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult GetMinimumLedgerSlot(); + + /// + /// Gets the account info for multiple accounts. + /// + /// The list of the accounts public keys. + /// The state commitment to consider when querying the ledger state. + /// A task which may return a request result holding the context and account info. + Task>>> GetMultipleAccountsAsync(IList accounts, + Commitment commitment = Commitment.Finalized); + + /// + /// Gets the account info for multiple accounts. + /// + /// The list of the accounts public keys. + /// The state commitment to consider when querying the ledger state. + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult>> GetMultipleAccounts(IList accounts, + Commitment commitment = Commitment.Finalized); + + /// + /// Returns all accounts owned by the provided program Pubkey. + /// Accounts must meet all filter criteria to be included in the results. + /// + /// The program public key. + /// The state commitment to consider when querying the ledger state. + /// The data size of the account to compare against the program account data. + /// The list of comparisons to match against the program account data. + /// A task which may return a request result holding the context and account info. + Task>> GetProgramAccountsAsync(string pubKey, Commitment commitment = Commitment.Finalized, + int? dataSize = null, IList memCmpList = null); + + /// + /// Returns all accounts owned by the provided program Pubkey. + /// Accounts must meet all filter criteria to be included in the results. + /// + /// The program public key. + /// The state commitment to consider when querying the ledger state. + /// The data size of the account to compare against the program account data. + /// The list of comparisons to match against the program account data. + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult> GetProgramAccounts(string pubKey, Commitment commitment = Commitment.Finalized, + int? dataSize = null, IList memCmpList = null); + + /// + /// Gets a recent block hash. + /// + /// The state commitment to consider when querying the ledger state. + /// Returns a task that holds the asynchronous operation result and state. + Task>> GetRecentBlockHashAsync(Commitment commitment = Commitment.Finalized); + + /// + /// Gets a recent block hash. + /// + /// The state commitment to consider when querying the ledger state. + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult> GetRecentBlockHash(Commitment commitment = Commitment.Finalized); + + /// + /// Gets a list of recent performance samples. + /// + /// Unless searchTransactionHistory is included, this method only searches the recent status cache of signatures. + /// + /// + /// Maximum transaction signatures to return, between 1-720. Default is 720. + /// Returns a task that holds the asynchronous operation result and state. + Task>> GetRecentPerformanceSamplesAsync(ulong limit = 720); + + /// + /// Gets a list of recent performance samples. + /// + /// Unless searchTransactionHistory is included, this method only searches the recent status cache of signatures. + /// + /// + /// Maximum transaction signatures to return, between 1-720. Default is 720. + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult> GetRecentPerformanceSamples(ulong limit = 720); + + /// + /// Gets signatures with the given commitment for transactions involving the address. + /// + /// Unless searchTransactionHistory is included, this method only searches the recent status cache of signatures. + /// + /// + /// The account address as base-58 encoded string. + /// Maximum transaction signatures to return, between 1-1000. Default is 1000. + /// Start searching backwards from this transaction signature. + /// Search until this transaction signature, if found before limit is reached. + /// The state commitment to consider when querying the ledger state. + /// Returns a task that holds the asynchronous operation result and state. + Task>> GetSignaturesForAddressAsync(string accountPubKey, ulong limit = 1000, + string before = null, string until = null, Commitment commitment = Commitment.Finalized); + + /// + /// Gets confirmed signatures for transactions involving the address. + /// + /// Unless searchTransactionHistory is included, this method only searches the recent status cache of signatures. + /// + /// + /// The account address as base-58 encoded string. + /// Maximum transaction signatures to return, between 1-1000. Default is 1000. + /// Start searching backwards from this transaction signature. + /// Search until this transaction signature, if found before limit is reached. + /// The state commitment to consider when querying the ledger state. + /// Returns a task that holds the asynchronous operation result and state. + [Obsolete("Please use GetSignaturesForAddressAsync whenever possible instead. This method is expected to be removed in solana-core v1.8.")] + Task>> GetConfirmedSignaturesForAddress2Async(string accountPubKey, ulong limit = 1000, + string before = null, string until = null, Commitment commitment = Commitment.Finalized); + + /// + /// Gets signatures with the given commitment for transactions involving the address. + /// + /// Unless searchTransactionHistory is included, this method only searches the recent status cache of signatures. + /// + /// + /// The account address as base-58 encoded string. + /// Maximum transaction signatures to return, between 1-1000. Default is 1000. + /// Start searching backwards from this transaction signature. + /// Search until this transaction signature, if found before limit is reached. + /// The state commitment to consider when querying the ledger state. + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult> GetSignaturesForAddress(string accountPubKey, ulong limit = 1000, + string before = null, string until = null, Commitment commitment = Commitment.Finalized); + + /// + /// Gets confirmed signatures for transactions involving the address. + /// + /// Unless searchTransactionHistory is included, this method only searches the recent status cache of signatures. + /// + /// + /// The account address as base-58 encoded string. + /// Maximum transaction signatures to return, between 1-1000. Default is 1000. + /// Start searching backwards from this transaction signature. + /// Search until this transaction signature, if found before limit is reached. + /// The state commitment to consider when querying the ledger state. + /// Returns an object that wraps the result along with possible errors with the request. + [Obsolete("Please use GetSignaturesForAddress whenever possible instead. This method is expected to be removed in solana-core v1.8.")] + RequestResult> GetConfirmedSignaturesForAddress2(string accountPubKey, ulong limit = 1000, + string before = null, string until = null, Commitment commitment = Commitment.Finalized); + + /// + /// Gets the status of a list of signatures. + /// + /// Unless searchTransactionHistory is included, this method only searches the recent status cache of signatures. + /// + /// + /// The list of transactions to search status info for. + /// If the node should search for signatures in it's ledger cache. + /// Returns a task that holds the asynchronous operation result and state. + Task>>> GetSignatureStatusesAsync(List transactionHashes, + bool searchTransactionHistory = false); + + /// + /// Gets the status of a list of signatures. + /// + /// Unless searchTransactionHistory is included, this method only searches the recent status cache of signatures. + /// + /// + /// The list of transactions to search status info for. + /// If the node should search for signatures in it's ledger cache. + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult>> GetSignatureStatuses(List transactionHashes, + bool searchTransactionHistory = false); + + /// + /// Gets the current slot the node is processing + /// + /// The state commitment to consider when querying the ledger state. + /// Returns a task that holds the asynchronous operation result and state. + Task> GetSlotAsync(Commitment commitment = Commitment.Finalized); + + /// + /// Gets the current slot the node is processing + /// + /// The state commitment to consider when querying the ledger state. + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult GetSlot(Commitment commitment = Commitment.Finalized); + + /// + /// Gets the current slot leader. + /// + /// The state commitment to consider when querying the ledger state. + /// Returns a task that holds the asynchronous operation result and state. + Task> GetSlotLeaderAsync(Commitment commitment = Commitment.Finalized); + + /// + /// Gets the current slot leader. + /// + /// The state commitment to consider when querying the ledger state. + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult GetSlotLeader(Commitment commitment = Commitment.Finalized); + + /// + /// Gets the slot leaders for a given slot range. + /// + /// The start slot. + /// The result limit. + /// The state commitment to consider when querying the ledger state. + /// Returns a task that holds the asynchronous operation result and state. + Task>> GetSlotLeadersAsync(ulong start, ulong limit, + Commitment commitment = Commitment.Finalized); + + /// + /// Gets the slot leaders for a given slot range. + /// + /// The start slot. + /// The result limit. + /// The state commitment to consider when querying the ledger state. + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult> GetSlotLeaders(ulong start, ulong limit, Commitment commitment = Commitment.Finalized); + + /// + /// Gets the highest slot that the node has a snapshot for. + /// + /// Returns a task that holds the asynchronous operation result and state. + Task> GetSnapshotSlotAsync(); + + /// + /// Gets the highest slot that the node has a snapshot for. + /// + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult GetSnapshotSlot(); + + /// + /// Gets the epoch activation information for a stake account. + /// + /// Public key of account to query, as base-58 encoded string + /// Epoch for which to calculate activation details. + /// The state commitment to consider when querying the ledger state. + /// Returns a task that holds the asynchronous operation result and state. + Task> GetStakeActivationAsync(string publicKey, ulong epoch = 0, + Commitment commitment = Commitment.Finalized); + + /// + /// Gets the epoch activation information for a stake account. + /// + /// Public key of account to query, as base-58 encoded string + /// Epoch for which to calculate activation details. + /// The state commitment to consider when querying the ledger state. + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult GetStakeActivation(string publicKey, ulong epoch = 0, + Commitment commitment = Commitment.Finalized); + + /// + /// Gets information about the current supply. + /// + /// The state commitment to consider when querying the ledger state. + /// Returns a task that holds the asynchronous operation result and state. + Task>> GetSupplyAsync(Commitment commitment = Commitment.Finalized); + + /// + /// Gets information about the current supply. + /// + /// The state commitment to consider when querying the ledger state. + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult> GetSupply(Commitment commitment = Commitment.Finalized); + + /// + /// Gets the token balance of an SPL Token account. + /// + /// Public key of Token account to query, as base-58 encoded string. + /// The state commitment to consider when querying the ledger state. + /// Returns a task that holds the asynchronous operation result and state. + Task>> GetTokenAccountBalanceAsync(string splTokenAccountPublicKey, + Commitment commitment = Commitment.Finalized); + + /// + /// Gets the token balance of an SPL Token account. + /// + /// Public key of Token account to query, as base-58 encoded string. + /// The state commitment to consider when querying the ledger state. + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult> GetTokenAccountBalance(string splTokenAccountPublicKey, + Commitment commitment = Commitment.Finalized); + + /// + /// Gets all SPL Token accounts by approved delegate. + /// + /// Public key of account owner query, as base-58 encoded string. + /// Public key of the specific token Mint to limit accounts to, as base-58 encoded string. + /// Public key of the Token program ID that owns the accounts, as base-58 encoded string. + /// The state commitment to consider when querying the ledger state. + /// Returns a task that holds the asynchronous operation result and state. + Task>>> GetTokenAccountsByDelegateAsync( + string ownerPubKey, string tokenMintPubKey = null, string tokenProgramId = null, Commitment commitment = Commitment.Finalized); + + /// + /// Gets all SPL Token accounts by approved delegate. + /// + /// Public key of account owner query, as base-58 encoded string. + /// Public key of the specific token Mint to limit accounts to, as base-58 encoded string. + /// Public key of the Token program ID that owns the accounts, as base-58 encoded string. + /// The state commitment to consider when querying the ledger state. + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult>> GetTokenAccountsByDelegate( + string ownerPubKey, string tokenMintPubKey = null, string tokenProgramId = null, Commitment commitment = Commitment.Finalized); + + /// + /// Gets all SPL Token accounts by token owner. + /// + /// Public key of account owner query, as base-58 encoded string. + /// Public key of the specific token Mint to limit accounts to, as base-58 encoded string. + /// Public key of the Token program ID that owns the accounts, as base-58 encoded string. + /// The state commitment to consider when querying the ledger state. + /// Returns a task that holds the asynchronous operation result and state. + Task>>> GetTokenAccountsByOwnerAsync( + string ownerPubKey, string tokenMintPubKey = null, string tokenProgramId = null, Commitment commitment = Commitment.Finalized); + + /// + /// Gets all SPL Token accounts by token owner. + /// + /// Public key of account owner query, as base-58 encoded string. + /// Public key of the specific token Mint to limit accounts to, as base-58 encoded string. + /// Public key of the Token program ID that owns the accounts, as base-58 encoded string. + /// The state commitment to consider when querying the ledger state. + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult>> GetTokenAccountsByOwner( + string ownerPubKey, string tokenMintPubKey = null, string tokenProgramId = null, Commitment commitment = Commitment.Finalized); + + /// + /// Gets the 20 largest token accounts of a particular SPL Token. + /// + /// Public key of Token Mint to query, as base-58 encoded string. + /// The state commitment to consider when querying the ledger state. + /// Returns a task that holds the asynchronous operation result and state. + Task>>> GetTokenLargestAccountsAsync(string tokenMintPubKey, + Commitment commitment = Commitment.Finalized); + + /// + /// Gets the 20 largest token accounts of a particular SPL Token. + /// + /// Public key of Token Mint to query, as base-58 encoded string. + /// The state commitment to consider when querying the ledger state. + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult>> GetTokenLargestAccounts(string tokenMintPubKey, + Commitment commitment = Commitment.Finalized); + + /// + /// Get the token supply of an SPL Token type. + /// + /// Public key of Token Mint to query, as base-58 encoded string. + /// The state commitment to consider when querying the ledger state. + /// Returns a task that holds the asynchronous operation result and state. + Task>> GetTokenSupplyAsync(string tokenMintPubKey, + Commitment commitment = Commitment.Finalized); + + /// + /// Get the token supply of an SPL Token type. + /// + /// Public key of Token Mint to query, as base-58 encoded string. + /// The state commitment to consider when querying the ledger state. + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult> GetTokenSupply(string tokenMintPubKey, Commitment commitment = Commitment.Finalized); + + /// + /// Returns transaction details for a confirmed transaction. + /// + /// + /// The commitment parameter is optional, is not supported, + /// the default value is not sent. + /// + /// + /// + /// Transaction signature as base-58 encoded string. + /// The state commitment to consider when querying the ledger state. + /// Returns a task that holds the asynchronous operation result and state. + Task> GetTransactionAsync(string signature, + Commitment commitment = Commitment.Finalized); + + /// + /// Returns transaction details for a confirmed transaction. + /// + /// + /// The commitment parameter is optional, is not supported, + /// the default value is not sent. + /// + /// + /// + /// Transaction signature as base-58 encoded string. + /// The state commitment to consider when querying the ledger state. + /// Returns an object that wraps the result along with possible errors with the request. + [Obsolete("Please use GetTransactionAsync whenever possible instead. This method is expected to be removed in solana-core v1.8.")] + Task> GetConfirmedTransactionAsync(string signature, Commitment commitment = Commitment.Finalized); + + /// + /// Returns transaction details for a confirmed transaction. + /// + /// + /// The commitment parameter is optional, is not supported, + /// the default value is not sent. + /// + /// + /// + /// Transaction signature as base-58 encoded string. + /// The state commitment to consider when querying the ledger state. + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult GetTransaction(string signature, Commitment commitment = Commitment.Finalized); + + /// + /// Returns transaction details for a confirmed transaction. + /// + /// + /// The commitment parameter is optional, is not supported, + /// the default value is not sent. + /// + /// + /// + /// Transaction signature as base-58 encoded string. + /// The state commitment to consider when querying the ledger state. + /// Returns an object that wraps the result along with possible errors with the request. + [Obsolete("Please use GetTransaction whenever possible instead. This method is expected to be removed in solana-core v1.8.")] + RequestResult GetConfirmedTransaction(string signature, Commitment commitment = Commitment.Finalized); + + /// + /// Gets the total transaction count of the ledger. + /// + /// The state commitment to consider when querying the ledger state. + /// Returns a task that holds the asynchronous operation result and state. + Task> GetTransactionCountAsync(Commitment commitment = Commitment.Finalized); + + /// + /// Gets the total transaction count of the ledger. + /// + /// The state commitment to consider when querying the ledger state. + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult GetTransactionCount(Commitment commitment = Commitment.Finalized); + + /// + /// Gets the current node's software version info. + /// + /// Returns a task that holds the asynchronous operation result and state. + Task> GetVersionAsync(); + + /// + /// Gets the current node's software version info. + /// + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult GetVersion(); + + /// + /// Gets the account info and associated stake for all voting accounts in the current bank. + /// + /// Filter by validator vote address, base-58 encoded string. + /// The state commitment to consider when querying the ledger state. + /// Returns a task that holds the asynchronous operation result and state. + Task> GetVoteAccountsAsync(string votePubKey = null, Commitment commitment = Commitment.Finalized); + + /// + /// Gets the account info and associated stake for all voting accounts in the current bank. + /// + /// Filter by validator vote address, base-58 encoded string. + /// The state commitment to consider when querying the ledger state. + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult GetVoteAccounts(string votePubKey = null, Commitment commitment = Commitment.Finalized); + + /// + /// Requests an airdrop to the passed pubKey of the passed lamports amount. + /// + /// The commitment parameter is optional, the default is used. + /// + /// + /// The public key of to receive the airdrop. + /// The amount of lamports to request. + /// The block commitment used to retrieve block hashes and verify success. + /// Returns a task that holds the asynchronous operation result and state. + Task> RequestAirdropAsync(string pubKey, ulong lamports, + Commitment commitment = Commitment.Finalized); + + /// + /// Requests an airdrop to the passed pubKey of the passed lamports amount. + /// + /// The commitment parameter is optional, the default is used. + /// + /// + /// The public key of to receive the airdrop. + /// The amount of lamports to request. + /// The block commitment used to retrieve block hashes and verify success. + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult RequestAirdrop(string pubKey, ulong lamports, + Commitment commitment = Commitment.Finalized); + + /// + /// Sends a transaction. + /// + /// The signed transaction as base-64 encoded string. + /// If true skip the prflight transaction checks (default false). + /// The block commitment used for preflight. + /// Returns a task that holds the asynchronous operation result and state. + Task> SendTransactionAsync(string transaction, bool skipPreflight = false, + Commitment preFlightCommitment = Commitment.Finalized); + + /// + /// Sends a transaction. + /// + /// The signed transaction as base-64 encoded string. + /// If true skip the prflight transaction checks (default false). + /// The block commitment used for preflight. + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult SendTransaction(string transaction, bool skipPreflight = false, + Commitment preFlightCommitment = Commitment.Finalized); + + /// + /// Sends a transaction. + /// + /// The signed transaction as byte array. + /// If true skip the prflight transaction checks (default false). + /// The block commitment used to retrieve block hashes and verify success. + /// Returns a task that holds the asynchronous operation result and state. + Task> SendTransactionAsync(byte[] transaction, bool skipPreflight = false, + Commitment commitment = Commitment.Finalized); + + /// + /// Sends a transaction. + /// + /// The signed transaction as byte array. + /// If true skip the prflight transaction checks (default false). + /// The block commitment used to retrieve block hashes and verify success. + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult SendTransaction(byte[] transaction, bool skipPreflight = false, + Commitment commitment = Commitment.Finalized); + + /// + /// Simulate sending a transaction. + /// + /// The signed transaction as a base-64 encoded string. + /// If the transaction signatures should be verified + /// (default false, conflicts with replaceRecentBlockHash. + /// The block commitment used to retrieve block hashes and verify success. + /// If the transaction recent blockhash should be replaced with the most recent blockhash + /// (default false, conflicts with sigVerify + /// List of accounts to return, as base-58 encoded strings. + /// Returns a task that holds the asynchronous operation result and state. + Task>> SimulateTransactionAsync(string transaction, bool sigVerify = false, + Commitment commitment = Commitment.Finalized, bool replaceRecentBlockhash = false, IList accountsToReturn = null); + + /// + /// Simulate sending a transaction. + /// + /// The signed transaction base-64 encoded string. + /// If the transaction signatures should be verified + /// (default false, conflicts with replaceRecentBlockHash. + /// The block commitment used to retrieve block hashes and verify success. + /// If the transaction recent blockhash should be replaced with the most recent blockhash + /// (default false, conflicts with sigVerify + /// List of accounts to return, as base-58 encoded strings. + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult> SimulateTransaction(string transaction, bool sigVerify = false, + Commitment commitment = Commitment.Finalized, bool replaceRecentBlockhash = false, IList accountsToReturn = null); + + /// + /// Simulate sending a transaction. + /// + /// The signed transaction as a byte array. + /// If the transaction signatures should be verified + /// (default false, conflicts with replaceRecentBlockHash. + /// The block commitment used to retrieve block hashes and verify success. + /// If the transaction recent blockhash should be replaced with the most recent blockhash + /// (default false, conflicts with sigVerify + /// List of accounts to return, as base-58 encoded strings. + /// Returns an object that wraps the result along with possible errors with the request. + Task>> SimulateTransactionAsync(byte[] transaction, bool sigVerify = false, + Commitment commitment = Commitment.Finalized, bool replaceRecentBlockhash = false, IList accountsToReturn = null); + + /// + /// Simulate sending a transaction. + /// + /// The signed transaction as a byte array. + /// If the transaction signatures should be verified + /// (default false, conflicts with replaceRecentBlockHash. + /// The block commitment used to retrieve block hashes and verify success. + /// If the transaction recent blockhash should be replaced with the most recent blockhash + /// (default false, conflicts with sigVerify + /// List of accounts to return, as base-58 encoded strings. + /// Returns an object that wraps the result along with possible errors with the request. + RequestResult> SimulateTransaction(byte[] transaction, bool sigVerify = false, + Commitment commitment = Commitment.Finalized, bool replaceRecentBlockhash = false, IList accountsToReturn = null); + + /// + /// Low-level method to send a batch of JSON RPC requests + /// + /// + /// + Task> SendBatchRequestAsync(JsonRpcBatchRequest reqs); + + /// + /// Generates the next unique id for the request. + /// + /// The id. + int GetNextIdForReq(); + + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/IRpcClient.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/IRpcClient.cs.meta new file mode 100644 index 0000000..18fa919 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/IRpcClient.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b4dcc099c9d916546a52782c460da910 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/IStreamingRpcClient.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/IStreamingRpcClient.cs new file mode 100644 index 0000000..ea83f3e --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/IStreamingRpcClient.cs @@ -0,0 +1,233 @@ +using Solana.Unity.Rpc.Core.Sockets; +using Solana.Unity.Rpc.Messages; +using Solana.Unity.Rpc.Models; +using Solana.Unity.Rpc.Types; +using System; +using System.Net.WebSockets; +using System.Threading.Tasks; + +namespace Solana.Unity.Rpc +{ + /// + /// Represents the streaming RPC client for the solana API. + /// + public interface IStreamingRpcClient : IDisposable + { + /// + /// Current connection state. + /// + WebSocketState State { get; } + + /// + /// Event triggered when the connection status changes between connected and disconnected. + /// + event EventHandler ConnectionStateChangedEvent; + + /// + /// The address this client connects to. + /// + Uri NodeAddress { get; } + + /// + /// Statistics of the current connection. + /// + IConnectionStatistics Statistics { get; } + + /// + /// Subscribes asynchronously to AccountInfo notifications. + /// + /// + /// The commitment parameter is optional, the default value is not sent. + /// + /// The public key of the account. + /// The callback to handle data notifications. + /// The state commitment to consider when querying the ledger state. + /// The task object representing the asynchronous operation. + Task SubscribeAccountInfoAsync(string pubkey, Action> callback, Commitment commitment = Commitment.Finalized); + + /// + /// Subscribes to the AccountInfo. This is a synchronous and blocking function. + /// + /// + /// The commitment parameter is optional, the default value is not sent. + /// + /// The public key of the account. + /// The callback to handle data notifications. + /// The state commitment to consider when querying the ledger state. + /// Returns an object representing the state of the subscription. + SubscriptionState SubscribeAccountInfo(string pubkey, Action> callback, Commitment commitment = Commitment.Finalized); + + /// + /// Subscribes asynchronously to Token Account notifications. Note: Only works if the account is a Token Account. + /// + /// + /// The commitment parameter is optional, the default value is not sent. + /// + /// The public key of the account. + /// The callback to handle data notifications. + /// The state commitment to consider when querying the ledger state. + /// The task object representing the asynchronous operation. + Task SubscribeTokenAccountAsync(string pubkey, Action> callback, Commitment commitment = Commitment.Finalized); + + /// + /// Subscribes to Token Account notifications. Note: Only works if the account is a Token Account. + /// + /// + /// The commitment parameter is optional, the default value is not sent. + /// + /// The public key of the account. + /// The callback to handle data notifications. + /// The state commitment to consider when querying the ledger state. + /// Returns an object representing the state of the subscription. + SubscriptionState SubscribeTokenAccount(string pubkey, Action> callback, Commitment commitment = Commitment.Finalized); + + /// + /// Subscribes asynchronously to the logs notifications that mention a given public key. + /// + /// + /// The commitment parameter is optional, the default value is not sent. + /// + /// The public key to filter by mention. + /// The callback to handle data notifications. + /// The state commitment to consider when querying the ledger state. + /// The task object representing the asynchronous operation. + Task SubscribeLogInfoAsync(string pubkey, Action> callback, Commitment commitment = Commitment.Finalized); + + /// + /// Subscribes asynchronously to the logs notifications. + /// + /// + /// The commitment parameter is optional, the default value is not sent. + /// + /// The filter mechanism. + /// The callback to handle data notifications. + /// The state commitment to consider when querying the ledger state. + /// The task object representing the asynchronous operation. + Task SubscribeLogInfoAsync(LogsSubscriptionType subscriptionType, Action> callback, Commitment commitment = Commitment.Finalized); + + /// + /// Subscribes to the logs notifications that mention a given public key. This is a synchronous and blocking function. + /// + /// + /// The commitment parameter is optional, the default value is not sent. + /// + /// The public key to filter by mention. + /// The callback to handle data notifications. + /// The state commitment to consider when querying the ledger state. + /// Returns an object representing the state of the subscription. + SubscriptionState SubscribeLogInfo(string pubkey, Action> callback, Commitment commitment = Commitment.Finalized); + + /// + /// Subscribes to the logs notifications. This is a synchronous and blocking function. + /// + /// + /// The commitment parameter is optional, the default value is not sent. + /// + /// The filter mechanism. + /// The callback to handle data notifications. + /// The state commitment to consider when querying the ledger state. + /// Returns an object representing the state of the subscription. + SubscriptionState SubscribeLogInfo(LogsSubscriptionType subscriptionType, Action> callback, Commitment commitment = Commitment.Finalized); + + /// + /// Subscribes asynchronously to a transaction signature to receive notification when the transaction is confirmed. + /// + /// + /// The commitment parameter is optional, the default value is not sent. + /// + /// The transaction signature. + /// The callback to handle data notifications. + /// The state commitment to consider when querying the ledger state. + /// The task object representing the asynchronous operation. + Task SubscribeSignatureAsync(string transactionSignature, Action> callback, Commitment commitment = Commitment.Finalized); + + /// + /// Subscribes to a transaction signature to receive notification when the transaction is confirmed. This is a synchronous and blocking function. + /// + /// + /// The commitment parameter is optional, the default value is not sent. + /// + /// The transaction signature. + /// The callback to handle data notifications. + /// The state commitment to consider when querying the ledger state. + /// Returns an object representing the state of the subscription. + SubscriptionState SubscribeSignature(string transactionSignature, Action> callback, Commitment commitment = Commitment.Finalized); + + /// + /// Subscribes asynchronously to changes to a given program account data. + /// + /// + /// The commitment parameter is optional, the default value is not sent. + /// + /// The program pubkey. + /// The callback to handle data notifications. + /// The state commitment to consider when querying the ledger state. + /// The task object representing the asynchronous operation. + Task SubscribeProgramAsync(string programPubkey, Action> callback, Commitment commitment = Commitment.Finalized); + + /// + /// Subscribes to changes to a given program account data. This is a synchronous and blocking function. + /// + /// + /// The commitment parameter is optional, the default value is not sent. + /// + /// The program pubkey. + /// The callback to handle data notifications. + /// The state commitment to consider when querying the ledger state. + /// Returns an object representing the state of the subscription. + SubscriptionState SubscribeProgram(string programPubkey, Action> callback, Commitment commitment = Commitment.Finalized); + + /// + /// Subscribes asynchronously to receive notifications anytime a slot is processed by the validator. + /// + /// The callback to handle data notifications. + /// The task object representing the asynchronous operation. + Task SubscribeSlotInfoAsync(Action callback); + + /// + /// Subscribes to receive notifications anytime a slot is processed by the validator. This is a synchronous and blocking function. + /// + /// The callback to handle data notifications. + /// Returns an object representing the state of the subscription. + SubscriptionState SubscribeSlotInfo(Action callback); + + + /// + /// Subscribes asynchronously to receive notifications anytime a new root is set by the validator. + /// + /// The callback to handle data notifications. + /// The task object representing the asynchronous operation. + Task SubscribeRootAsync(Action callback); + + /// + /// Subscribes to receive notifications anytime a new root is set by the validator. This is a synchronous and blocking function. + /// + /// The callback to handle data notifications. + /// Returns an object representing the state of the subscription. + SubscriptionState SubscribeRoot(Action callback); + + /// + /// Asynchronously unsubscribes from a given subscription using the state object. + /// + /// The subscription state object. + /// The task object representing the asynchronous operation. + Task UnsubscribeAsync(SubscriptionState subscription); + + /// + /// Unsubscribes from a given subscription using the state object. This is a synchronous and blocking function. + /// + /// The subscription state object. + void Unsubscribe(SubscriptionState subscription); + + /// + /// Asynchronously initializes the client connection and starts listening for socket messages. + /// + /// The task object representing the asynchronous operation. + Task ConnectAsync(); + /// + /// Asynchronously disconnects and removes all running subscriptions. + /// + /// The task object representing the asynchronous operation. + Task DisconnectAsync(); + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/IStreamingRpcClient.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/IStreamingRpcClient.cs.meta new file mode 100644 index 0000000..89e91a4 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/IStreamingRpcClient.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1b58963d8560704439975d3947396248 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Messages.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Messages.meta new file mode 100644 index 0000000..44ee3ee --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Messages.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: edeb0b9b76e66584a89f860a52fd004c +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Messages/JsonRpcBase.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Messages/JsonRpcBase.cs new file mode 100644 index 0000000..0d35274 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Messages/JsonRpcBase.cs @@ -0,0 +1,18 @@ +namespace Solana.Unity.Rpc.Messages +{ + /// + /// Base JpnRpc message. + /// + public abstract class JsonRpcBase + { + /// + /// The rpc version. + /// + public string Jsonrpc { get; protected set; } + + /// + /// The id of the message. + /// + public int Id { get; set; } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Messages/JsonRpcBase.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Messages/JsonRpcBase.cs.meta new file mode 100644 index 0000000..7171d9d --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Messages/JsonRpcBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 373c544a295ad3646864205cec52b700 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Messages/JsonRpcBatchRequest.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Messages/JsonRpcBatchRequest.cs new file mode 100644 index 0000000..a2a0f4e --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Messages/JsonRpcBatchRequest.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; + +namespace Solana.Unity.Rpc.Messages +{ + /// + /// This class represents multiple JsonRpcRequest objects and is used for making + /// a of batch requests in a single HTTP request. + /// + public class JsonRpcBatchRequest : List + { + + // https://docs.solana.com/developing/clients/jsonrpc-api + // Requests can be sent in batches by sending an array of JSON-RPC request objects as the data for a single POST. + + } +} diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Messages/JsonRpcBatchRequest.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Messages/JsonRpcBatchRequest.cs.meta new file mode 100644 index 0000000..cd0b314 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Messages/JsonRpcBatchRequest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3edab52eba9c59a42892848d02046739 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Messages/JsonRpcBatchResponse.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Messages/JsonRpcBatchResponse.cs new file mode 100644 index 0000000..7c46ebc --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Messages/JsonRpcBatchResponse.cs @@ -0,0 +1,11 @@ +using System.Collections.Generic; + +namespace Solana.Unity.Rpc.Messages +{ + /// + /// This class represents the response from a request containing a batch of JSON RPC requests + /// + public class JsonRpcBatchResponse : List + { + } +} diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Messages/JsonRpcBatchResponse.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Messages/JsonRpcBatchResponse.cs.meta new file mode 100644 index 0000000..105e450 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Messages/JsonRpcBatchResponse.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b1960241c6ceb2f4ea0411db3fc003fc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Messages/JsonRpcBatchResponseItem.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Messages/JsonRpcBatchResponseItem.cs new file mode 100644 index 0000000..f34d10e --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Messages/JsonRpcBatchResponseItem.cs @@ -0,0 +1,32 @@ +using Newtonsoft.Json; +using System; + +namespace Solana.Unity.Rpc.Messages +{ + /// + /// An object that represents a response item from an API batch request. + /// The response type hint is supplied, + /// + public class JsonRpcBatchResponseItem : JsonRpcBase + { + /// + /// The anticipated runtime type of this result. + /// + [JsonIgnore] + public Type ResultType { get; set; } + + /// + /// The RPC result of a given request as object. + /// + public object Result { get; set; } + + /// + /// The RPC result of a given request cast as T + /// + public T ResultAs() + { + return (T) Result; + } + + } +} diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Messages/JsonRpcBatchResponseItem.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Messages/JsonRpcBatchResponseItem.cs.meta new file mode 100644 index 0000000..42fb5f6 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Messages/JsonRpcBatchResponseItem.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b5e02ed8b29a30d4cb933a1a6f1d1d53 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Messages/JsonRpcRequest.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Messages/JsonRpcRequest.cs new file mode 100644 index 0000000..fe91dc2 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Messages/JsonRpcRequest.cs @@ -0,0 +1,37 @@ +using System.Collections.Generic; + +namespace Solana.Unity.Rpc.Messages +{ + /// + /// Rpc request message. + /// + public class JsonRpcRequest : JsonRpcBase + { + /// + /// The request method. + /// + public string Method { get; } + + /// + /// The method parameters list. + /// + public IList Params { get; } + + + /// + /// Serialize params only if not null + /// + /// + public bool ShouldSerializeParams() + { + return Params != null; + } + internal JsonRpcRequest(int id, string method, IList parameters) + { + Params = parameters; + Method = method; + Id = id; + Jsonrpc = "2.0"; + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Messages/JsonRpcRequest.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Messages/JsonRpcRequest.cs.meta new file mode 100644 index 0000000..b174c0f --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Messages/JsonRpcRequest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 23a3b48422fdf824894aa4b722890a0d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Messages/JsonRpcResponse.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Messages/JsonRpcResponse.cs new file mode 100644 index 0000000..62bd726 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Messages/JsonRpcResponse.cs @@ -0,0 +1,83 @@ +using Newtonsoft.Json; +using Solana.Unity.Rpc.Converters; +using Solana.Unity.Rpc.Models; + +namespace Solana.Unity.Rpc.Messages +{ + /// + /// Holds a rpc request response. + /// + /// The type of the result. + public class JsonRpcResponse : JsonRpcBase + { + /// + /// The result of a given request. + /// + public T Result { get; set; } + } + + /// + /// Error message from a given request. + /// + [JsonConverter(typeof(RpcErrorResponseConverter))] + public class JsonRpcErrorResponse : JsonRpcBase + { + /// + /// The detailed error deserialized. + /// + public ErrorContent Error { get; set; } + + /// + /// An error message. + /// + public string ErrorMessage { get; set; } + } + + /// + /// Holds the contents of an error message. + /// + public class ErrorContent + { + /// + /// The error code. + /// + public int Code { get; set; } + /// + /// The string error message. + /// + public string Message { get; set; } + + /// + /// Possible extension data as a dictionary. + /// + public ErrorData Data { get; set; } + } + + /// + /// Context objects, holds the slot. + /// + public class ContextObj + { + /// + /// The slot. + /// + public ulong Slot { get; set; } + } + + /// + /// Contains the pair Context + Value from a given request. + /// + /// + public class ResponseValue + { + /// + /// The context object from a given request. + /// + public ContextObj Context { get; set; } + + /// + /// The value object from a given request. + /// + public T Value { get; set; } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Messages/JsonRpcResponse.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Messages/JsonRpcResponse.cs.meta new file mode 100644 index 0000000..f0e14cc --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Messages/JsonRpcResponse.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7ddf8ed830635404cb98941e54bfd377 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Messages/JsonRpcStreamResponse.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Messages/JsonRpcStreamResponse.cs new file mode 100644 index 0000000..48b76d4 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Messages/JsonRpcStreamResponse.cs @@ -0,0 +1,19 @@ +namespace Solana.Unity.Rpc.Messages +{ + /// + /// Holds a json rpc message from a streaming socket. + /// + /// The type of the result. + public class JsonRpcStreamResponse + { + /// + /// The message received. + /// + public T Result { get; set; } + + /// + /// The subscription id that the message belongs to. + /// + public int Subscription { get; set; } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Messages/JsonRpcStreamResponse.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Messages/JsonRpcStreamResponse.cs.meta new file mode 100644 index 0000000..a58781d --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Messages/JsonRpcStreamResponse.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: de73f19814a735342a07aa805f7bbebc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models.meta new file mode 100644 index 0000000..97d84fc --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: eb9373db6ab6ee54eb813da7921b2c9f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/AccountData.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/AccountData.cs new file mode 100644 index 0000000..2b2a2cc --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/AccountData.cs @@ -0,0 +1,249 @@ +// ReSharper disable ClassNeverInstantiated.Global +using System; +using System.Globalization; + +namespace Solana.Unity.Rpc.Models +{ + /// + /// Represents the account info for a given token account. + /// + public class TokenAccountInfo : AccountInfoBase + { + /// + /// The parsed token account data field. + /// + public TokenAccountData Data { get; set; } + } + + /// + /// Represents the account info for a given token account. + /// + public class TokenMintInfo : AccountInfoBase + { + /// + /// The parsed token account data field. + /// + public TokenMintData Data { get; set; } + } + + /// + /// Represents a Token Mint account data. + /// + public class TokenMintData + { + /// + /// The program responsible for the account data. + /// + public string Program { get; set; } + + /// + /// Account data space. + /// + public ulong Space { get; set; } + + /// + /// The parsed token mint data. + /// + public ParsedTokenMintData Parsed { get; set; } + } + + /// + /// Represents the Token Mint parsed data, as formatted per SPL token program. + /// + public class ParsedTokenMintData + { + /// + /// Contains the details of the token mint. + /// + public TokenMintInfoDetails Info { get; set; } + + /// + /// The type of the account managed by the SPL token program. + /// + public string Type { get; set; } + } + + /// + /// Represents a Token Mint account info as formatted per the SPL token program. + /// + public class TokenMintInfoDetails + { + /// + /// The freeze authority. + /// + public string FreezeAuthority { get; set; } + + /// + /// The mint authority. + /// + public string MintAuthority { get; set; } + + /// + /// The decimals cases to consider when converter to human readable token amounts. + /// + public byte Decimals { get; set; } + + /// + /// Is the mint account initialized? + /// + public bool IsInitialized { get; set; } + + /// + /// The current token supply. + /// + public string Supply { get; set; } + + /// + /// The current token supply parsed as ulong. + /// + public ulong SupplyUlong => ulong.Parse(Supply); + } + + /// + /// Represents the details of the info field of a token account. + /// + public class TokenAccountInfoDetails + { + /// + /// The token balance data. + /// + public TokenBalance TokenAmount { get; set; } + + /// + /// A base-58 encoded public key of the delegate. + /// + public string Delegate { get; set; } + + /// + /// The token balance that has been delegated. + /// + public TokenBalance DelegatedAmount { get; set; } + + /// + /// The account's state. + /// + public string State { get; set; } + + /// + /// If the account is a native token account. + /// + public bool IsNative { get; set; } + + /// + /// A base-58 encoded public key of the token's mint. + /// + public string Mint { get; set; } + + /// + /// A base-58 encoded public key of the program this account as been assigned to. + /// + public string Owner { get; set; } + } + + /// + /// Represents the parsed account data, as available by the program-specific state parser. + /// + public class ParsedTokenAccountData + { + /// + /// The type of account. + /// + public string Type { get; set; } + + /// + /// The token account info, containing account balances, delegation and ownership info. + /// + public TokenAccountInfoDetails Info { get; set; } + } + + /// + /// Represents a token account's data. + /// + public class TokenAccountData + { + /// + /// The program responsible for the account data. + /// + public string Program { get; set; } + + /// + /// Account data space. + /// + public ulong Space { get; set; } + + /// + /// The parsed account data, as available by the program-specific state parser. + /// + public ParsedTokenAccountData Parsed { get; set; } + } + + /// + /// Represents a large token account. + /// + public class LargeTokenAccount : TokenBalance + { + /// + /// The address of the token account. + /// + public string Address { get; set; } + } + + /// + /// Represents a large account. + /// + public class LargeAccount + { + /// + /// The lamports balance of the account. + /// + public ulong Lamports { get; set; } + + + /// + /// The address of the token account. + /// + public string Address { get; set; } + } + + /// + /// Represents the token balance of an account. + /// + public class TokenBalance + { + /// + /// The raw token account balance without decimals. + /// + public string Amount { get; set; } + + /// + /// The number of base 10 digits to the right of the decimal place. + /// + public int Decimals { get; set; } + + /// + /// The token account balance, using mint-prescribed decimals. DEPRECATED. + /// + [Obsolete("UiAmount is deprecated, please use UiAmountString instead.")] + public decimal? UiAmount { get; set; } + + /// + /// The token account balance as a string, using mint-prescribed decimals. + /// + public string UiAmountString { get; set; } + + /// + /// The token account balance as a ulong + /// + public ulong AmountUlong => Convert.ToUInt64(Amount); + + /// + /// The token account balance as a decimal + /// + public decimal AmountDecimal => Convert.ToDecimal(UiAmountString, CultureInfo.InvariantCulture); + + /// + /// The token account balance as a double + /// + public double AmountDouble => Convert.ToDouble(UiAmountString, CultureInfo.InvariantCulture); + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/AccountData.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/AccountData.cs.meta new file mode 100644 index 0000000..cbaac2e --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/AccountData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9884ea72d7d1a9e49ab1bfef847a616c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/AccountInfo.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/AccountInfo.cs new file mode 100644 index 0000000..f7c7c9f --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/AccountInfo.cs @@ -0,0 +1,71 @@ +// ReSharper disable UnusedAutoPropertyAccessor.Global +// ReSharper disable ClassNeverInstantiated.Global + +using Newtonsoft.Json; +using Solana.Unity.Rpc.Converters; +using System.Collections.Generic; + +namespace Solana.Unity.Rpc.Models +{ + /// + /// The base class of the account info, to be subclassed for token a account info classes. + /// + public class AccountInfoBase + { + /// + /// The lamports balance of the account. + /// + public ulong Lamports { get; set; } + + /// + /// The account owner. + /// + /// This value could be another regular address or a program. + /// + /// + public string Owner { get; set; } + + /// + /// Indicates whether the account contains a program (and is strictly read-only). + /// + public bool Executable { get; set; } + + /// + /// The epoch at which the account will next owe rent. + /// + public ulong RentEpoch { get; set; } + } + + /// + /// Represents the account info. + /// + public class AccountInfo : AccountInfoBase + { + /// + /// The actual account data. + /// + /// This field should contain two values: first value is the data, the second one is the encoding - should always read base64. + /// + /// + [JsonConverter(typeof(AccountDataConverter))] + public List Data { get; set; } + } + + /// + /// Represents the tuple account key and account data. + /// + public class AccountKeyPair + { + /// + /// The account info. + /// + public AccountInfo Account { get; set; } + + /// + /// A base-58 encoded public key representing the account's public key. + /// + [JsonProperty("pubkey")] + public string PublicKey { get; set; } + } + +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/AccountInfo.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/AccountInfo.cs.meta new file mode 100644 index 0000000..9a115a0 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/AccountInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a995bd5bf31d1af459dc51868c8fcc88 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/AccountKeysList.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/AccountKeysList.cs new file mode 100644 index 0000000..fce52c0 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/AccountKeysList.cs @@ -0,0 +1,90 @@ +using System.Collections.Generic; +using System.Linq; + +namespace Solana.Unity.Rpc.Models +{ + /// + /// A wrapper around a list of s that takes care of deduplication and ordering according to + /// the wire format specification. + /// + internal class AccountKeysList + { + /// + /// The account metas list. + /// + private readonly List _accounts; + + /// + /// Get the accounts as a list. + /// + internal List AccountList + { + get + { + List res = _accounts.Select(acc => acc).ToList(); + + res.Sort((x, y) => + { + if (x.IsSigner != y.IsSigner) + { + // Signers always come before non-signers + return x.IsSigner ? -1 : 1; + } + if (x.IsWritable != y.IsWritable) + { + // Writable accounts always come before read-only accounts + return x.IsWritable ? -1 : 1; + } + // Otherwise, sort by pubkey, stringwise. + return x.PublicKey.CompareTo(y.PublicKey); + }); + + return res; + } + } + + /// + /// Initialize the account keys list for use within transaction building. + /// + internal AccountKeysList() + { + _accounts = new List(); + } + + /// + /// Add an account meta to the list of accounts. + /// + /// The account meta to add. + internal void Add(AccountMeta accountMeta) + { + AccountMeta accMeta = _accounts.FirstOrDefault(x => x.PublicKey == accountMeta.PublicKey); + + if (accMeta == null) + { + _accounts.Add(accountMeta); + } + else if (!accMeta.IsSigner && accountMeta.IsSigner) + { + accMeta.IsSigner = true; + accMeta.IsWritable = accMeta.IsWritable || accountMeta.IsWritable; + } + else if(!accMeta.IsWritable && accountMeta.IsWritable) + { + accMeta.IsWritable = true; + } + + } + + /// + /// Add a list of account metas to the list of accounts. + /// + /// The account metas to add. + internal void Add(IEnumerable accountMetas) + { + foreach (AccountMeta accountMeta in accountMetas) + { + Add(accountMeta); + } + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/AccountKeysList.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/AccountKeysList.cs.meta new file mode 100644 index 0000000..616f23c --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/AccountKeysList.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2439eb8cec092034ab708dcf41149a7e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/AccountMeta.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/AccountMeta.cs new file mode 100644 index 0000000..a854c91 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/AccountMeta.cs @@ -0,0 +1,64 @@ +using Solana.Unity.Wallet; +using System.Diagnostics; + +namespace Solana.Unity.Rpc.Models +{ + /// + /// Implements the account meta logic, which defines if an account represented by public key is a signer, a writable account or both. + /// + [DebuggerDisplay("PK = {" + nameof(PublicKey) + "}")] + public class AccountMeta + { + /// + /// The public key as a byte array. + /// + public byte[] PublicKeyBytes { get; } + + /// + /// Get the public key encoded as base58. + /// + public string PublicKey { get; } + + /// + /// A boolean which defines if the account is a signer account. + /// + public bool IsSigner { get; internal set; } + + /// + /// A boolean which defines if the account is a writable account. + /// + public bool IsWritable { get; internal set; } + + /// + /// Initialize the account meta with the passed public key, being a non-signing account for the transaction. + /// + /// The public key. + /// Whether the account is writable. + /// Whether the account is a signer. + internal AccountMeta(PublicKey publicKey, bool isWritable, bool isSigner) + { + PublicKey = publicKey.Key; + PublicKeyBytes = publicKey.KeyBytes; + IsSigner = isSigner; + IsWritable = isWritable; + } + + /// + /// Initializes an for a writable account with the given + /// and a bool that signals whether the account is a signer or not. + /// + /// The public key. + /// Whether the account is a signer. + /// The instance. + public static AccountMeta Writable(PublicKey publicKey, bool isSigner) => new(publicKey, true, isSigner); + + /// + /// Initializes an for a read-only account with the given + /// and a bool that signals whether the account is a signer or not. + /// + /// The public key. + /// Whether the account is a signer. + /// The instance. + public static AccountMeta ReadOnly(PublicKey publicKey, bool isSigner) => new(publicKey, false, isSigner); + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/AccountMeta.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/AccountMeta.cs.meta new file mode 100644 index 0000000..a28af41 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/AccountMeta.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f65be06eaf99de54eabad5d494f8cfb4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Block.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Block.cs new file mode 100644 index 0000000..b6dd9b0 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Block.cs @@ -0,0 +1,364 @@ +// ReSharper disable UnusedAutoPropertyAccessor.Global +// ReSharper disable ClassNeverInstantiated.Global + +using Newtonsoft.Json; + +namespace Solana.Unity.Rpc.Models +{ + /// + /// Represents the block info. + /// + public class BlockInfo + { + /// + /// Estimated block production time. + /// + public long BlockTime { get; set; } + + /// + /// A base-58 encoded public key representing the block hash. + /// + public string Blockhash { get; set; } + + /// + /// A base-58 encoded public key representing the block hash of this block's parent. + /// + /// If the parent block is no longer available due to ledger cleanup, this field will return + /// '11111111111111111111111111111111' + /// + /// + public string PreviousBlockhash { get; set; } + + /// + /// The slot index of this block's parent. + /// + public ulong ParentSlot { get; set; } + + /// + /// The number of blocks beneath this block. + /// + public long? BlockHeight { get; set; } + + /// + /// The rewards for this given block. + /// + public RewardInfo[] Rewards { get; set; } + + /// + /// Collection of transactions and their metadata within this block. + /// + public TransactionMetaInfo[] Transactions { get; set; } + } + + /// + /// Represents the transaction, metadata and its containing slot. + /// + public class TransactionMetaSlotInfo : TransactionMetaInfo + { + /// + /// The slot this transaction was processed in. + /// + public ulong Slot { get; set; } + + /// + /// Estimated block production time. + /// + public long? BlockTime { get; set; } + } + + + /// + /// Represents the tuple transaction and metadata. + /// + public class TransactionMetaInfo + { + /// + /// The transaction information. + /// + public TransactionInfo Transaction { get; set; } + + /// + /// The metadata information. + /// + public TransactionMeta Meta { get; set; } + } + + /// + /// Represents the reward information related to a given account. + /// + public class RewardInfo + { + /// + /// The account pubkey as base58 encoded string. + /// + public string Pubkey { get; set; } + /// + /// Number of reward lamports credited or debited by the account. + /// + public long Lamports { get; set; } + + /// + /// Account balance in lamports after the reward was applied. + /// + public ulong PostBalance { get; set; } + + /// + /// Type of the reward. + /// + public RewardType RewardType { get; set; } + } + + /// + /// The type of the reward. + /// + public enum RewardType + { + /// + /// Default value in case the returned value is undefined. + /// + Unknown, + + /// + /// Fee reward. + /// + Fee, + + /// + /// Rent reward. + /// + Rent, + + /// + /// Voting reward. + /// + Voting, + + /// + /// Staking reward. + /// + Staking + } + + /// + /// Represents a transaction. + /// + public class TransactionInfo + { + /// + /// The signatures of this transaction. + /// + public string[] Signatures { get; set; } + + /// + /// The message contents of the transaction. + /// + public TransactionContentInfo Message { get; set; } + } + + /// + /// Represents the contents of the trasaction. + /// + public class TransactionContentInfo + { + /// + /// List of base-58 encoded public keys used by the transaction, including by the instructions and for signatures. + /// + public string[] AccountKeys { get; set; } + + /// + /// Details the account types and signatures required by the transaction. + /// + public TransactionHeaderInfo Header { get; set; } + + /// + /// A base-58 encoded hash of a recent block in the ledger used to prevent transaction duplication and to give transactions lifetimes. + /// + public string RecentBlockhash { get; set; } + + /// + /// List of program instructions that will be executed in sequence and committed in one atomic transaction if all succeed. + /// + public InstructionInfo[] Instructions { get; set; } + } + + /// + /// Details the number and type of accounts and signatures in a given transaction. + /// + public class TransactionHeaderInfo + { + /// + /// The total number of signatures required to make the transaction valid. + /// + public int NumRequiredSignatures { get; set; } + + /// + /// The last NumReadonlySignedAccounts of the signed keys are read-only accounts. + /// + public int NumReadonlySignedAccounts { get; set; } + + /// + /// The last NumReadonlyUnsignedAccounts of the unsigned keys are read-only accounts. + /// + public int NumReadonlyUnsignedAccounts { get; set; } + } + + /// + /// Represents the transaction metadata. + /// + public class TransactionMeta + { + /// + /// Possible transaction error. + /// + [JsonProperty("err")] + public TransactionError Error { get; set; } + + /// + /// Fee this transaction was charged. + /// + public ulong Fee { get; set; } + + /// + /// Collection of account balances from before the transaction was processed. + /// + public ulong[] PreBalances { get; set; } + + /// + /// Collection of account balances after the transaction was processed. + /// + public ulong[] PostBalances { get; set; } + + /// + /// List of inner instructions or omitted if inner instruction recording was not yet enabled during this transaction. + /// + public InnerInstruction[] InnerInstructions { get; set; } + + /// + /// List of token balances from before the transaction was processed or omitted if token balance recording was not yet enabled during this transaction. + /// + public TokenBalanceInfo[] PreTokenBalances { get; set; } + + /// + /// List of token balances from after the transaction was processed or omitted if token balance recording was not yet enabled during this transaction. + /// + public TokenBalanceInfo[] PostTokenBalances { get; set; } + + /// + /// Array of string log messages or omitted if log message recording was not yet enabled during this transaction. + /// + public string[] LogMessages { get; set; } + } + + /// + /// Represents the structure of a token balance metadata for a transaction. + /// + public class TokenBalanceInfo + { + /// + /// Index of the account in which the token balance is provided for. + /// + public int AccountIndex { get; set; } + + /// + /// Pubkey of the token's mint. + /// + public string Mint { get; set; } + + /// + /// Token balance details. + /// + public TokenBalance UiTokenAmount { get; set; } + } + + /// + /// Represents an inner instruction. Inner instruction are cross-program instructions that are invoked during transaction processing. + /// + public class InnerInstruction + { + /// + /// Index of the transaction instruction from which the inner instruction(s) originated + /// + public int Index { get; set; } + + /// + /// List of program instructions that will be executed in sequence and committed in one atomic transaction if all succeed. + /// + public InstructionInfo[] Instructions { get; set; } + } + + /// + /// Represents the data of given instruction. + /// + public class InstructionInfo + { + /// + /// Index into the Message.AccountKeys array indicating the program account that executes this instruction. + /// + public int ProgramIdIndex { get; set; } + + /// + /// List of ordered indices into the Message.AccountKeys array indicating which accounts to pass to the program. + /// + public int[] Accounts { get; set; } + + /// + /// The program input data encoded in a base-58 string. + /// + public string Data { get; set; } + } + + /// + /// Represents the block commitment info. + /// + public class BlockCommitment + { + /// + /// A list of values representing the amount of cluster stake in lamports that has + /// voted onn the block at each depth from 0 to (max lockout history + 1). + /// + public ulong[] Commitment { get; set; } + + /// + /// Total active stake, in lamports, of the current epoch. + /// + public ulong TotalStake { get; set; } + } + + /// + /// Represents the fee calculator info. + /// + public class FeeCalculator + { + /// + /// The amount, in lamports, to be paid per signature. + /// + public ulong LamportsPerSignature { get; set; } + } + + /// + /// Represents the fee calculator info. + /// + public class FeeCalculatorInfo + { + /// + /// The fee calculator info. + /// + public FeeCalculator FeeCalculator { get; set; } + } + + /// + /// Represents block hash info. + /// + public class BlockHash + { + /// + /// A base-58 encoded public key representing the block hash. + /// + public string Blockhash { get; set; } + + /// + /// The fee calculator data. + /// + public FeeCalculator FeeCalculator { get; set; } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Block.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Block.cs.meta new file mode 100644 index 0000000..4387cf6 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Block.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 384a7f644130412489cbaf9efb75c2a1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/BlockProductionInfo.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/BlockProductionInfo.cs new file mode 100644 index 0000000..380150d --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/BlockProductionInfo.cs @@ -0,0 +1,38 @@ +using System.Collections.Generic; + +namespace Solana.Unity.Rpc.Models +{ + /// + /// Holds the block production information. + /// + public class BlockProductionInfo + { + /// + /// The block production as a map from the validator to a list + /// of the number of leader slots and number of blocks produced + /// + public Dictionary> ByIdentity { get; set; } + + /// + /// The block production range by slots. + /// + public SlotRange Range { get; set; } + } + + /// + /// Represents a slot range. + /// + public class SlotRange + { + /// + /// The first slot of the range (inclusive). + /// + public ulong FirstSlot { get; set; } + + /// + /// The last slot of the range (inclusive). + /// + public ulong LastSlot { get; set; } + + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/BlockProductionInfo.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/BlockProductionInfo.cs.meta new file mode 100644 index 0000000..cd88820 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/BlockProductionInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6f9db4fb73b4b9a48aacb8f28832e11e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/ClusterNode.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/ClusterNode.cs new file mode 100644 index 0000000..7556815 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/ClusterNode.cs @@ -0,0 +1,48 @@ +// ReSharper disable ClassNeverInstantiated.Global + +using Newtonsoft.Json; + +namespace Solana.Unity.Rpc.Models +{ + /// + /// Represents a node in the cluster. + /// + public class ClusterNode + { + /// + /// Gossip network address for the node. + /// + public string Gossip { get; set; } + + /// + /// A base-58 encoded public key associated with the node. + /// + [JsonProperty("pubkey")] + public string PublicKey { get; set; } + + /// + /// JSON RPC network address for the node. The service may not be enabled. + /// + public string Rpc { get; set; } + + /// + /// TPU network address for the node. + /// + public string Tpu { get; set; } + + /// + /// The software version of the node. The information may not be available. + /// + public string Version { get; set; } + + /// + /// Unique identifier of the current software's feature set. + /// + public ulong? FeatureSet { get; set; } + + /// + /// The shred version the node has been configured to use. + /// + public ulong ShredVersion { get; set; } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/ClusterNode.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/ClusterNode.cs.meta new file mode 100644 index 0000000..e4633b4 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/ClusterNode.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 04d2e39720fc0aa49bcea33d0f68733e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Epoch.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Epoch.cs new file mode 100644 index 0000000..cd9b974 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Epoch.cs @@ -0,0 +1,64 @@ +namespace Solana.Unity.Rpc.Models +{ + /// + /// Represents information about the current epoch. + /// + public class EpochInfo + { + /// + /// The current slot. + /// + public ulong AbsoluteSlot { get; set; } + + /// + /// The current block height. + /// + public ulong BlockHeight { get; set; } + + /// + /// The current epoch. + /// + public ulong Epoch { get; set; } + + /// + /// The current slot relative to the start of the current epoch. + /// + public ulong SlotIndex { get; set; } + + /// + /// The number of slots in this epoch + /// + public ulong SlotsInEpoch { get; set; } + } + + /// + /// Represents information about the epoch schedule. + /// + public class EpochScheduleInfo + { + /// + /// The maximum number of slots in each epoch. + /// + public ulong SlotsPerEpoch { get; set; } + + /// + /// The number of slots before beginning of an epoch to calculate a leader schedule for that epoch. + /// + public ulong LeaderScheduleSlotOffset { get; set; } + + /// + /// The first normal-length epoch. + /// + public ulong FirstNormalEpoch { get; set; } + + /// + /// The first normal-length slot. + /// + public ulong FirstNormalSlot { get; set; } + + /// + /// Whether epochs start short and grow. + /// + public bool Warmup { get; set; } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Epoch.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Epoch.cs.meta new file mode 100644 index 0000000..259ec1f --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Epoch.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 02dc497d0f88cfd48b1902969ff7ce83 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/ErrorResult.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/ErrorResult.cs new file mode 100644 index 0000000..6a2b888 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/ErrorResult.cs @@ -0,0 +1,16 @@ +using Newtonsoft.Json; + +namespace Solana.Unity.Rpc.Models +{ + /// + /// Holds an error result. + /// + public class ErrorResult + { + /// + /// The error string. + /// + [JsonProperty("err")] + public TransactionError Error { get; set; } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/ErrorResult.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/ErrorResult.cs.meta new file mode 100644 index 0000000..1bb184d --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/ErrorResult.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bda15fd95db71dd4d92d73bc573dedf6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Fees.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Fees.cs new file mode 100644 index 0000000..47b2566 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Fees.cs @@ -0,0 +1,70 @@ +namespace Solana.Unity.Rpc.Models +{ + /// + /// Represents the fee rate governor. + /// + public class FeeRateGovernor + { + /// + /// Percentage of fees collected to be destroyed. + /// + public decimal BurnPercent { get; set; } + + /// + /// Highest value LamportsPerSignature can attain for the next slot. + /// + public ulong MaxLamportsPerSignature { get; set; } + + /// + /// Smallest value LamportsPerSignature can attain for the next slot. + /// + public ulong MinLamportsPerSignature { get; set; } + + /// + /// Desired fee rate for the cluster. + /// + public ulong TargetLamportsPerSignature { get; set; } + + /// + /// Desired signature rate for the cluster. + /// + public ulong TargetSignaturesPerSlot { get; set; } + } + + /// + /// Represents the fee rate governor info. + /// + public class FeeRateGovernorInfo + { + /// + /// The fee rate governor. + /// + public FeeRateGovernor FeeRateGovernor { get; set; } + } + + /// + /// Represents information about the fees. + /// + public class FeesInfo + { + /// + /// A block hash as base-58 encoded string. + /// + public string Blockhash { get; set; } + + /// + /// The fee calculator for this block hash. + /// + public FeeCalculator FeeCalculator { get; set; } + + /// + /// DEPRECATED - this value is inaccurate and should not be relied upon + /// + public ulong LastValidSlot { get; set; } + + /// + /// Last block height at which a blockhash will be valid. + /// + public ulong LastValidBlockHeight { get; set; } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Fees.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Fees.cs.meta new file mode 100644 index 0000000..c124637 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Fees.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b5e97603fb9c25548ae94e10b89384ab +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Filters.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Filters.cs new file mode 100644 index 0000000..4b8bad2 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Filters.cs @@ -0,0 +1,20 @@ +// unset + +namespace Solana.Unity.Rpc.Models +{ + /// + /// Represents the memcmp filter for the method. + /// + public class MemCmp + { + /// + /// The offset into program account data at which to start the comparison. + /// + public int Offset { get; set; } + + /// + /// The data to match against the program data, as base-58 encoded string and limited to 129 bytes. + /// + public string Bytes { get; set; } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Filters.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Filters.cs.meta new file mode 100644 index 0000000..11ffa61 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Filters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ed8c2e6764129c141930c1f02050c4b9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Identity.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Identity.cs new file mode 100644 index 0000000..cf51b64 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Identity.cs @@ -0,0 +1,13 @@ +namespace Solana.Unity.Rpc.Models +{ + /// + /// Represents the identity public key for the current node. + /// + public class NodeIdentity + { + /// + /// The identity public key of the current node, as base-58 encoded string. + /// + public string Identity { get; set; } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Identity.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Identity.cs.meta new file mode 100644 index 0000000..d172a86 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Identity.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e0decbc71aa4cb44a8c85c91fafc4f37 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Inflation.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Inflation.cs new file mode 100644 index 0000000..2c2a71f --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Inflation.cs @@ -0,0 +1,86 @@ +namespace Solana.Unity.Rpc.Models +{ + /// + /// Represents inflation governor information. + /// + public class InflationGovernor + { + /// + /// The initial inflation percentage from time zero. + /// + public decimal Initial { get; set; } + + /// + /// The terminal inflation percentage. + /// + public decimal Terminal { get; set; } + + /// + /// The rate per year at which inflation is lowered. + /// Rate reduction is derived using the target slot time as per genesis config. + /// + public decimal Taper { get; set; } + + /// + /// Percentage of total inflation allocated to the foundation. + /// + public decimal Foundation { get; set; } + + /// + /// Duration of foundation pool inflation in years. + /// + public decimal FoundationTerm { get; set; } + } + + /// + /// Represents the inflation rate information. + /// + public class InflationRate + { + /// + /// Epoch for which these values are valid. + /// + public decimal Epoch { get; set; } + + /// + /// Percentage of total inflation allocated to the foundation. + /// + public decimal Foundation { get; set; } + + /// + /// Percentage of total inflation. + /// + public decimal Total { get; set; } + + /// + /// Percentage of total inflation allocated to validators. + /// + public decimal Validator { get; set; } + } + + /// + /// Represents the inflation reward for a certain address. + /// + public class InflationReward + { + /// + /// Epoch for which a reward occurred. + /// + public ulong Epoch { get; set; } + + /// + /// The slot in which the rewards are effective. + /// + public ulong EffectiveSlot { get; set; } + + /// + /// The reward amount in lamports. + /// + public ulong Amount { get; set; } + + /// + /// Post balance of the account in lamports. + /// + public ulong PostBalance { get; set; } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Inflation.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Inflation.cs.meta new file mode 100644 index 0000000..b3b5021 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Inflation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 16d59ff57735f344ea3bdbe829a91d20 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/InstructionError.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/InstructionError.cs new file mode 100644 index 0000000..9833ee4 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/InstructionError.cs @@ -0,0 +1,237 @@ +namespace Solana.Unity.Rpc.Models +{ + /// + /// Represents an Instruction error. + /// + public class InstructionError + { + /// + /// The index of the instruction that caused the error. + /// + public int InstructionIndex { get; set; } + + /// + /// The type of the instruction error. + /// + public InstructionErrorType Type { get; set; } + + /// + /// Possible custom error id from a program. + /// + public uint? CustomError { get; set; } + + /// + /// Possible string from borsh error. + /// + public string BorshIoError { get; set; } + } + + /// + /// Possible Types of instruction errors. + /// + public enum InstructionErrorType + { + /// + /// The program instruction returned an error. (Deprecated) + /// + GenericError, + /// + /// The arguments provided to a program were invalid + /// + InvalidArgument, + /// + /// + /// An instruction's data contents were invalid + InvalidInstructionData, + /// + /// An account's data contents was invalid + /// + InvalidAccountData, + /// + /// An account's data was too small + /// + AccountDataTooSmall, + /// + /// An account's balance was too small to complete the instruction + /// + InsufficientFunds, + /// + /// The account did not have the expected program id + /// + IncorrectProgramId, + /// + /// A signature was required but not found + /// + MissingRequiredSignature, + /// + /// An initialize instruction was sent to an account that has already been initialized. + /// + AccountAlreadyInitialized, + /// + /// An attempt to operate on an account that hasn't been initialized. + /// + UninitializedAccount, + /// + /// Program's instruction lamport balance does not equal the balance after the instruction + /// + UnbalancedInstruction, + /// + /// Program modified an account's program id + /// + ModifiedProgramId, + /// + /// Program spent the lamports of an account that doesn't belong to it + /// + ExternalAccountLamportSpend, + /// + /// Program modified the data of an account that doesn't belong to it + /// + ExternalAccountDataModified, + /// + /// Read-only account's lamports modified + /// + ReadonlyLamportChange, + /// + /// Read-only account's data was modified + /// + ReadonlyDataModified, + /// + /// An account was referenced more than once in a single instruction + /// (Deprecated, instructions can now contain duplicate accounts) + /// + DuplicateAccountIndex, + /// + /// Executable bit on account changed, but shouldn't have + /// + ExecutableModified, + /// + /// Rent_epoch account changed, but shouldn't have + /// + RentEpochModified, + /// + /// The instruction expected additional account keys + /// + NotEnoughAccountKeys, + /// + /// A non-system program changed the size of the account data + /// + AccountDataSizeChanged, + /// + /// The instruction expected an executable account + /// + AccountNotExecutable, + /// + /// Failed to borrow a reference to account data, already borrowed + /// + AccountBorrowFailed, + /// + /// Account data has an outstanding reference after a program's execution + /// + AccountBorrowOutstanding, + /// + /// The same account was multiply passed to an on-chain program's entrypoint, but the program + /// modified them differently. A program can only modify one instance of the account because + /// the runtime cannot determine which changes to pick or how to merge them if both are modified + /// + DuplicateAccountOutOfSync, + /// + /// Allows on-chain programs to implement program-specific error types and see them returned + /// by the Solana runtime. A program-specific error may be any type that is represented as + /// or serialized to a u32 integer. + /// + Custom, //(u32) + /// + /// The return value from the program was invalid. Valid errors are either a defined builtin + /// error value or a user-defined error in the lower 32 bits. + /// + InvalidError, + /// + /// Executable account's data was modified + /// + ExecutableDataModified, + /// + /// Executable account's lamports modified + /// + ExecutableLamportChange, + /// + /// Executable accounts must be rent exempt + /// + ExecutableAccountNotRentExempt, + /// + /// Unsupported program id + /// + UnsupportedProgramId, + /// + /// Cross-program invocation call depth too deep + /// + CallDepth, + /// + /// An account required by the instruction is missing + /// + MissingAccount, + /// + /// Cross-program invocation reentrancy not allowed for this instruction + /// + ReentrancyNotAllowed, + /// + /// Length of the seed is too long for address generation + /// + MaxSeedLengthExceeded, + /// + /// Provided seeds do not result in a valid address + /// + InvalidSeeds, + /// + /// Failed to reallocate account data of this length + /// + InvalidRealloc, + /// + /// Computational budget exceeded + /// + ComputationalBudgetExceeded, + /// + /// Cross-program invocation with unauthorized signer or writable account + /// + PrivilegeEscalation, + /// + /// Failed to create program execution environment + /// + ProgramEnvironmentSetupFailure, + /// + /// Program failed to complete + /// + ProgramFailedToComplete, + /// + /// Program failed to compile + /// + ProgramFailedToCompile, + /// + /// Account is immutable + /// + Immutable, + /// + /// Incorrect authority provided + /// + IncorrectAuthority, + /// + /// Failed to serialize or deserialize account data + /// + BorshIoError, //(String) + /// + /// An account does not have enough lamports to be rent-exempt + /// + AccountNotRentExempt, + /// + /// Invalid account owner + /// + InvalidAccountOwner, + /// + /// Program arithmetic overflowed + /// + ArithmeticOverflow, + /// + /// Unsupported sysvar + /// + UnsupportedSysvar + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/InstructionError.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/InstructionError.cs.meta new file mode 100644 index 0000000..fd83829 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/InstructionError.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b19dae04892a20841b4fe256587e787d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Logs.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Logs.cs new file mode 100644 index 0000000..c0a4eef --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Logs.cs @@ -0,0 +1,76 @@ +// ReSharper disable UnusedAutoPropertyAccessor.Global +// ReSharper disable ClassNeverInstantiated.Global + +using Newtonsoft.Json; + +namespace Solana.Unity.Rpc.Models +{ + /// + /// Represents a log during transaction simulation. + /// + public class Log + { + /// + /// The error associated with the transaction simulation. + /// + [JsonProperty("err")] + public TransactionError Error { get; set; } + + /// + /// The log messages the transaction instructions output during execution. + /// + /// This will be null if the simulation failed before the transaction was able to execute. + /// + /// + public string[] Logs { get; set; } + } + + /// + /// Represents a log message when subscribing to the log output of the Streaming RPC. + /// + public class LogInfo : Log + { + /// + /// The signature of the transaction. + /// + public string Signature { get; set; } + } + + /// + /// Represents the result of a transaction simulation. + /// + public class SimulationLogs + { + /// + /// Account infos as requested in the simulateTransaction method. + /// + public AccountInfo[] Accounts { get; set; } + + /// + /// The error associated with the transaction simulation. + /// + [JsonProperty("err")] + public TransactionError Error { get; set; } + + + /// + /// The log messages the transaction instructions output during execution. + /// + /// This will be null if the simulation failed before the transaction was able to execute. + /// + /// + public string[] Logs { get; set; } + } + + /// + /// Represents a complete error message. + /// + /// See RpcError::RpcResponseError in solana\client\src\rpc_request.rs + public class ErrorData : SimulationLogs + { + /// + /// Represents the number of compute units consumed by the transactions. + /// + public ulong UnitsConsumed { get; set; } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Logs.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Logs.cs.meta new file mode 100644 index 0000000..1e36abf --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Logs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1f01fe1f4e910e14b81b230e828751a4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Message.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Message.cs new file mode 100644 index 0000000..98dd298 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Message.cs @@ -0,0 +1,246 @@ +using Solana.Unity.Rpc.Utilities; +using Solana.Unity.Wallet; +using Solana.Unity.Wallet.Utilities; +using System; +using System.Collections.Generic; +using System.IO; + +namespace Solana.Unity.Rpc.Models +{ + /// + /// The message header. + /// + public class MessageHeader + { + #region Layout + + /// + /// Represents the layout of the encoded values. + /// + internal static class Layout + { + /// + /// The offset at which the byte that defines the number of required signatures begins. + /// + internal const int RequiredSignaturesOffset = 0; + + /// + /// The offset at which the byte that defines the number of read-only signer accounts begins. + /// + internal const int ReadOnlySignedAccountsOffset = 1; + + /// + /// The offset at which the byte that defines the number of read-only non-signer accounts begins. + /// + internal const int ReadOnlyUnsignedAccountsOffset = 2; + + /// + /// The message header length. + /// + internal const int HeaderLength = 3; + } + + #endregion Layout + + /// + /// The number of required signatures. + /// + public byte RequiredSignatures { get; set; } + + /// + /// The number of read-only signed accounts. + /// + public byte ReadOnlySignedAccounts { get; set; } + + /// + /// The number of read-only non-signed accounts. + /// + public byte ReadOnlyUnsignedAccounts { get; set; } + + /// + /// Convert the message header to byte array format. + /// + /// The byte array. + internal byte[] ToBytes() + { + return new[] { RequiredSignatures, ReadOnlySignedAccounts, ReadOnlyUnsignedAccounts }; + } + } + + /// + /// Represents the Message of a Solana . + /// + public class Message + { + /// + /// The header of the . + /// + public MessageHeader Header { get; set; } + + /// + /// The list of account s present in the transaction. + /// + public IList AccountKeys { get; set; } + + /// + /// The list of s present in the transaction. + /// + public IList Instructions { get; set; } + + /// + /// The recent block hash for the transaction. + /// + public string RecentBlockhash { get; set; } + + /// + /// Check whether an account is writable. + /// + /// The index of the account in the account keys. + /// true if the account is writable, false otherwise. + public bool IsAccountWritable(int index) => index < Header.RequiredSignatures - Header.ReadOnlySignedAccounts || + (index >= Header.RequiredSignatures && + index < AccountKeys.Count - Header.ReadOnlyUnsignedAccounts); + + /// + /// Check whether an account is a signer. + /// + /// The index of the account in the account keys. + /// true if the account is an expected signer, false otherwise. + public bool IsAccountSigner(int index) => index < Header.RequiredSignatures; + + /// + /// Serialize the message into the wire format. + /// + /// A byte array corresponding to the serialized message. + public byte[] Serialize() + { + byte[] accountAddressesLength = ShortVectorEncoding.EncodeLength(AccountKeys.Count); + byte[] instructionsLength = ShortVectorEncoding.EncodeLength(Instructions.Count); + int accountKeysBufferSize = AccountKeys.Count * 32; + + MemoryStream accountKeysBuffer = new(accountKeysBufferSize); + + foreach (PublicKey key in AccountKeys) + { + accountKeysBuffer.Write(key.KeyBytes, 0, key.KeyBytes.Length); + } + + int messageBufferSize = MessageHeader.Layout.HeaderLength + PublicKey.PublicKeyLength + + accountAddressesLength.Length + + +instructionsLength.Length + Instructions.Count + accountKeysBufferSize; + MemoryStream buffer = new(messageBufferSize); + buffer.Write(Header.ToBytes(), 0, Header.ToBytes().Length); + buffer.Write(accountAddressesLength, 0, accountAddressesLength.Length); + buffer.Write(accountKeysBuffer.ToArray(), 0, accountKeysBuffer.ToArray().Length); + var decodedRecentBlockHash = Encoders.Base58.DecodeData(RecentBlockhash); + buffer.Write(decodedRecentBlockHash, 0, decodedRecentBlockHash.Length); + buffer.Write(instructionsLength, 0, instructionsLength.Length); + + foreach (CompiledInstruction compiledInstruction in Instructions) + { + buffer.WriteByte(compiledInstruction.ProgramIdIndex); + buffer.Write(compiledInstruction.KeyIndicesCount, 0, compiledInstruction.KeyIndicesCount.Length); + buffer.Write(compiledInstruction.KeyIndices, 0, compiledInstruction.KeyIndices.Length); + buffer.Write(compiledInstruction.DataLength, 0 ,compiledInstruction.DataLength.Length); + buffer.Write(compiledInstruction.Data, 0, compiledInstruction.Data.Length); + } + return buffer.ToArray(); + } + + /// + /// Deserialize a compiled message into a Message object. + /// + /// The data to deserialize into the Message object. + /// The Message object instance. + public static Message Deserialize(ReadOnlySpan data) + { + // Read message header + byte numRequiredSignatures = data[MessageHeader.Layout.RequiredSignaturesOffset]; + byte numReadOnlySignedAccounts = data[MessageHeader.Layout.ReadOnlySignedAccountsOffset]; + byte numReadOnlyUnsignedAccounts = data[MessageHeader.Layout.ReadOnlyUnsignedAccountsOffset]; + + // Read account keys + (int accountAddressLength, int accountAddressLengthEncodedLength) = + ShortVectorEncoding.DecodeLength(data.Slice(MessageHeader.Layout.HeaderLength, + ShortVectorEncoding.SpanLength)); + List accountKeys = new(accountAddressLength); + for (int i = 0; i < accountAddressLength; i++) + { + ReadOnlySpan keyBytes = data.Slice( + MessageHeader.Layout.HeaderLength + accountAddressLengthEncodedLength + + i * PublicKey.PublicKeyLength, + PublicKey.PublicKeyLength); + accountKeys.Add(new PublicKey(keyBytes)); + } + + // Read block hash + string blockHash = + Encoders.Base58.EncodeData(data.Slice( + MessageHeader.Layout.HeaderLength + accountAddressLengthEncodedLength + + accountAddressLength * PublicKey.PublicKeyLength, + PublicKey.PublicKeyLength).ToArray()); + + // Read the number of instructions in the message + (int instructionsLength, int instructionsLengthEncodedLength) = + ShortVectorEncoding.DecodeLength( + data.Slice( + MessageHeader.Layout.HeaderLength + accountAddressLengthEncodedLength + + (accountAddressLength * PublicKey.PublicKeyLength) + PublicKey.PublicKeyLength, + ShortVectorEncoding.SpanLength)); + + List instructions = new(instructionsLength); + int instructionsOffset = + MessageHeader.Layout.HeaderLength + accountAddressLengthEncodedLength + + (accountAddressLength * PublicKey.PublicKeyLength) + PublicKey.PublicKeyLength + + instructionsLengthEncodedLength; + ReadOnlySpan instructionsData = data[instructionsOffset..]; + + // Read the instructions in the message + for (int i = 0; i < instructionsLength; i++) + { + (CompiledInstruction compiledInstruction, int instructionLength) = + CompiledInstruction.Deserialize(instructionsData); + instructions.Add(compiledInstruction); + instructionsData = instructionsData[instructionLength..]; + } + + return new Message + { + Header = new MessageHeader + { + RequiredSignatures = numRequiredSignatures, + ReadOnlySignedAccounts = numReadOnlySignedAccounts, + ReadOnlyUnsignedAccounts = numReadOnlyUnsignedAccounts + }, + RecentBlockhash = blockHash, + AccountKeys = accountKeys, + Instructions = instructions, + }; + } + + /// + /// Deserialize a compiled message encoded as base-64 into a Message object. + /// + /// The data to deserialize into the Message object. + /// The Transaction object. + /// Thrown when the given string is null. + public static Message Deserialize(string data) + { + if (data == null) + throw new ArgumentNullException(nameof(data)); + + byte[] decodedBytes; + + try + { + decodedBytes = Convert.FromBase64String(data); + } + catch (Exception ex) + { + throw new Exception("could not decode message data from base64", ex); + } + + return Deserialize(decodedBytes); + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Message.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Message.cs.meta new file mode 100644 index 0000000..9d71a9d --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Message.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 90a2127b8a6bf884da47feb73ab5ee04 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Performance.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Performance.cs new file mode 100644 index 0000000..a90ee38 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Performance.cs @@ -0,0 +1,28 @@ +namespace Solana.Unity.Rpc.Models +{ + /// + /// Represents a performance sample. + /// + public class PerformanceSample + { + /// + /// Slot in which sample was taken at. + /// + public ulong Slot { get; set; } + + /// + /// Number of transactions in sample. + /// + public ulong NumTransactions { get; set; } + + /// + /// Number of slots in sample + /// + public ulong NumSlots { get; set; } + + /// + /// Number of seconds in a sample window. + /// + public int SamplePeriodSecs { get; set; } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Performance.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Performance.cs.meta new file mode 100644 index 0000000..4b3d36b --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Performance.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7616146b249ad424fae6e24afa72a64a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Signature.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Signature.cs new file mode 100644 index 0000000..d9d2071 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Signature.cs @@ -0,0 +1,47 @@ + +using Newtonsoft.Json; + +namespace Solana.Unity.Rpc.Models +{ + /// + /// Represents the signature status information. + /// + public class SignatureStatusInfo + { + /// + /// The slot the transaction was processed in. + /// + public ulong Slot { get; set; } + + /// + /// The number of blocks since signature confirmation. + /// + public ulong? Confirmations { get; set; } + + /// + /// The error if the transaction failed, null if it succeeded. + /// + [JsonProperty("err")] + public TransactionError Error { get; set; } + + /// + /// The transaction's cluster confirmation status, either "processed", "confirmed" or "finalized". + /// + public string ConfirmationStatus { get; set; } + + /// + /// Memo associated with the transaction, null if no memo is present. + /// + public string Memo { get; set; } + + /// + /// The transaction signature as base-58 encoded string. + /// + public string Signature { get; set; } + + /// + /// Estimated production time as Unix timestamp, null if not available. + /// + public ulong? BlockTime { get; set; } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Signature.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Signature.cs.meta new file mode 100644 index 0000000..b547f39 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Signature.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e76cb462d27a7ed4b807f91448056490 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/SlotInfo.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/SlotInfo.cs new file mode 100644 index 0000000..9c20ce8 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/SlotInfo.cs @@ -0,0 +1,25 @@ +// ReSharper disable ClassNeverInstantiated.Global + +namespace Solana.Unity.Rpc.Models +{ + /// + /// Represents the slot info. + /// + public class SlotInfo + { + /// + /// The parent slot. + /// + public int Parent { get; set; } + + /// + /// The root as set by the validator. + /// + public int Root { get; set; } + + /// + /// The current slot. + /// + public int Slot { get; set; } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/SlotInfo.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/SlotInfo.cs.meta new file mode 100644 index 0000000..2d1888f --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/SlotInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 711fccfb0bcde844fb615a94dc5cc5d5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/StakeActivation.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/StakeActivation.cs new file mode 100644 index 0000000..f50fa2e --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/StakeActivation.cs @@ -0,0 +1,23 @@ +namespace Solana.Unity.Rpc.Models +{ + /// + /// Represents the stake activation info. + /// + public class StakeActivationInfo + { + /// + /// Stake active during the epoch. + /// + public ulong Active { get; set; } + + /// + /// Stake inactive during the epoch. + /// + public ulong Inactive { get; set; } + + /// + /// The stake account's activation state, one of "active", "inactive", "activating", "deactivating". + /// + public string State { get; set; } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/StakeActivation.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/StakeActivation.cs.meta new file mode 100644 index 0000000..5d1d614 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/StakeActivation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 53acb8d284d0d52408d45d065f7bd2c4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Supply.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Supply.cs new file mode 100644 index 0000000..c64c8c3 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Supply.cs @@ -0,0 +1,31 @@ +// ReSharper disable ClassNeverInstantiated.Global +using System.Collections.Generic; + +namespace Solana.Unity.Rpc.Models +{ + /// + /// Represents supply info. + /// + public class Supply + { + /// + /// Circulating supply in lamports. + /// + public ulong Circulating { get; set; } + + /// + /// Non-circulating supply in lamports. + /// + public ulong NonCirculating { get; set; } + + /// + /// A list of account addresses of non-circulating accounts, as strings. + /// + public IList NonCirculatingAccounts { get; set; } + + /// + /// Total supply in lamports. + /// + public ulong Total { get; set; } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Supply.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Supply.cs.meta new file mode 100644 index 0000000..746efb5 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Supply.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d6ea03f0657dced4fbfaf632d709ab62 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/TokenAccount.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/TokenAccount.cs new file mode 100644 index 0000000..114de19 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/TokenAccount.cs @@ -0,0 +1,24 @@ +// ReSharper disable ClassNeverInstantiated.Global +// ReSharper disable UnusedAutoPropertyAccessor.Global + +using Newtonsoft.Json; + +namespace Solana.Unity.Rpc.Models +{ + /// + /// Represents a token account. + /// + public class TokenAccount + { + /// + /// The token account info. + /// + public TokenAccountInfo Account { get; set; } + + /// + /// A base-58 encoded public key representing the account's public key. + /// + [JsonProperty("pubkey")] + public string PublicKey { get; set; } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/TokenAccount.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/TokenAccount.cs.meta new file mode 100644 index 0000000..ebaabca --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/TokenAccount.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0eba31aea80daf847af986b5ff32a2de +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Transaction.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Transaction.cs new file mode 100644 index 0000000..e565ea0 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Transaction.cs @@ -0,0 +1,408 @@ +using Solana.Unity.Rpc.Builders; +using Solana.Unity.Rpc.Utilities; +using Solana.Unity.Wallet; +using Solana.Unity.Wallet.Utilities; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace Solana.Unity.Rpc.Models +{ + /// + /// A pair corresponding of a public key and it's verifiable signature. + /// + public class SignaturePubKeyPair + { + /// + /// The public key to verify the signature against. + /// + public PublicKey PublicKey { get; set; } + + /// + /// The signature created by the corresponding of this pair's . + /// + public byte[] Signature { get; set; } + } + + /// + /// Nonce information to be used to build an offline transaction. + /// + public class NonceInformation + { + /// + /// The current blockhash stored in the nonce account. + /// + public string Nonce { get; set; } + + /// + /// An AdvanceNonceAccount instruction. + /// + public TransactionInstruction Instruction { get; set; } + } + + /// + /// Represents a Transaction in Solana. + /// + public class Transaction + { + /// + /// The transaction's fee payer. + /// + public PublicKey FeePayer { get; set; } + + /// + /// The list of s present in the transaction. + /// + public List Instructions { get; set; } + + /// + /// The recent block hash for the transaction. + /// + public string RecentBlockHash { get; set; } + + /// + /// The nonce information of the transaction. + /// + /// When this is set, the 's Nonce is used as the RecentBlockhash. + /// + /// + public NonceInformation NonceInformation { get; set; } + + /// + /// The signatures for the transaction. + /// + /// These are typically created by invoking the Build(IList{Account} signers) method of the , + /// but can be created by deserializing a Transaction and adding signatures manually. + /// + /// + public List Signatures { get; set; } + + /// + /// Compile the transaction data. + /// + public byte[] CompileMessage() + { + MessageBuilder messageBuilder = new() { FeePayer = FeePayer }; + + if (RecentBlockHash != null) messageBuilder.RecentBlockHash = RecentBlockHash; + if (NonceInformation != null) messageBuilder.NonceInformation = NonceInformation; + + foreach (TransactionInstruction instruction in Instructions) + { + messageBuilder.AddInstruction(instruction); + } + + return messageBuilder.Build(); + } + + /// + /// Verifies the signatures a given serialized message. + /// + /// true if they are valid, false otherwise. + private bool VerifySignatures(byte[] serializedMessage) => + Signatures.All(pair => pair.PublicKey.Verify(serializedMessage, pair.Signature)); + + /// + /// Verifies the signatures of a complete and signed transaction. + /// + /// true if they are valid, false otherwise. + public bool VerifySignatures() => VerifySignatures(CompileMessage()); + + /// + /// Sign the transaction with the specified signers. Multiple signatures may be applied to a transaction. + /// The first signature is considered primary and is used to identify and confirm transaction. + /// + /// + /// If the transaction FeePayer is not set, the first signer will be used as the transaction fee payer account. + /// + /// + /// Transaction fields SHOULD NOT be modified after the first call to Sign or an externally created signature + /// has been added to the transaction object, doing so will invalidate the signature and cause the transaction to be + /// rejected by the cluster. + /// + /// + /// The transaction must have been assigned a valid RecentBlockHash or NonceInformation before invoking this method. + /// + /// + /// + /// The signer accounts. + public bool Sign(IList signers) + { + Signatures ??= new List(); + IEnumerable uniqueSigners = DeduplicateSigners(signers); + byte[] serializedMessage = CompileMessage(); + + foreach (Account account in uniqueSigners) + { + byte[] signatureBytes = account.Sign(serializedMessage); + Signatures.Add(new SignaturePubKeyPair { PublicKey = account.PublicKey, Signature = signatureBytes }); + } + + return VerifySignatures(); + } + + /// + /// Sign the transaction with the specified signer. Multiple signatures may be applied to a transaction. + /// The first signature is considered primary and is used to identify and confirm transaction. + /// + /// + /// If the transaction FeePayer is not set, the first signer will be used as the transaction fee payer account. + /// + /// + /// Transaction fields SHOULD NOT be modified after the first call to Sign or an externally created signature + /// has been added to the transaction object, doing so will invalidate the signature and cause the transaction to be + /// rejected by the cluster. + /// + /// + /// The transaction must have been assigned a valid RecentBlockHash or NonceInformation before invoking this method. + /// + /// + /// + /// The signer account. + public bool Sign(Account signer) => Sign(new List { signer }); + + /// + /// Partially sign a transaction with the specified accounts. + /// All accounts must correspond to either the fee payer or a signer account in the transaction instructions. + /// + /// The signer accounts. + public void PartialSign(IList signers) + { + Signatures ??= new List(); + IEnumerable uniqueSigners = DeduplicateSigners(signers); + byte[] serializedMessage = CompileMessage(); + + foreach (Account account in uniqueSigners) + { + byte[] signatureBytes = account.Sign(serializedMessage); + Signatures.Add(new SignaturePubKeyPair { PublicKey = account.PublicKey, Signature = signatureBytes }); + } + } + + /// + /// Deduplicate the list of given signers. + /// + /// The signer accounts. + /// The signer accounts with removed duplicates + private static IEnumerable DeduplicateSigners(IEnumerable signers) + { + List uniqueSigners = new(); + HashSet seen = new(); + + foreach (Account account in signers) + { + if (seen.Contains(account)) continue; + + seen.Add(account); + uniqueSigners.Add(account); + } + + return uniqueSigners; + } + + /// + /// Partially sign a transaction with the specified account. + /// The account must correspond to either the fee payer or a signer account in the transaction instructions. + /// + /// The signer account. + public void PartialSign(Account signer) => PartialSign(new List { signer }); + + /// + /// Signs the transaction's message with the passed signer and add it to the transaction, serializing it. + /// + /// The signer. + /// The serialized transaction. + public byte[] Build(Account signer) + { + return Build(new List { signer }); + } + + /// + /// Signs the transaction's message with the passed list of signers and adds them to the transaction, serializing it. + /// + /// The list of signers. + /// The serialized transaction. + public byte[] Build(IList signers) + { + Sign(signers); + + return Serialize(); + } + + /// + /// Adds an externally created signature to the transaction. + /// The public key must correspond to either the fee payer or a signer account in the transaction instructions. + /// + /// The public key of the account that signed the transaction. + /// The transaction signature. + public void AddSignature(PublicKey publicKey, byte[] signature) + { + Signatures ??= new List(); + Signatures.Add(new SignaturePubKeyPair { PublicKey = publicKey, Signature = signature }); + } + + /// + /// Adds one or more instructions to the transaction. + /// + /// The instructions to add. + /// The transaction instance. + public Transaction Add(IEnumerable instructions) + { + Instructions ??= new List(); + Instructions.AddRange(instructions); + return this; + } + + /// + /// Adds an instruction to the transaction. + /// + /// The instruction to add. + /// The transaction instance. + public Transaction Add(TransactionInstruction instruction) => + Add(new List { instruction }); + + /// + /// Serializes the transaction into wire format. + /// + /// The transaction encoded in wire format. + public byte[] Serialize() + { + byte[] signaturesLength = ShortVectorEncoding.EncodeLength(Signatures.Count); + byte[] serializedMessage = CompileMessage(); + MemoryStream buffer = new(signaturesLength.Length + Signatures.Count * TransactionBuilder.SignatureLength + + serializedMessage.Length); + + buffer.Write(signaturesLength, 0, signaturesLength.Length); + foreach (SignaturePubKeyPair signaturePair in Signatures) + { + buffer.Write(signaturePair.Signature, 0, signaturePair.Signature.Length); + } + + buffer.Write(serializedMessage, 0, serializedMessage.Length); + return buffer.ToArray(); + } + + /// + /// Populate the Transaction from the given message and signatures. + /// + /// The object. + /// The list of signatures. + /// The Transaction object. + public static Transaction Populate(Message message, IList signatures = null) + { + Transaction tx = new() + { + RecentBlockHash = message.RecentBlockhash, + Signatures = new List(), + Instructions = new List() + }; + + if (message.Header.RequiredSignatures > 0) + { + tx.FeePayer = message.AccountKeys[0]; + } + + if (signatures != null) + { + for (int i = 0; i < signatures.Count; i++) + { + tx.Signatures.Add(new SignaturePubKeyPair + { + PublicKey = message.AccountKeys[i], + Signature = signatures[i] + }); + } + } + + for (int i = 0; i < message.Instructions.Count; i++) + { + CompiledInstruction compiledInstruction = message.Instructions[i]; + (int accountLength, _) = ShortVectorEncoding.DecodeLength(compiledInstruction.KeyIndicesCount); + + List accounts = new(accountLength); + for (int j = 0; j < accountLength; j++) + { + int k = compiledInstruction.KeyIndices[j]; + accounts.Add(new AccountMeta(message.AccountKeys[k], message.IsAccountWritable(k), + tx.Signatures.Any(pair => pair.PublicKey.Key == message.AccountKeys[k].Key) || message.IsAccountSigner(k))); + } + + TransactionInstruction instruction = new() + { + Keys = accounts, + ProgramId = message.AccountKeys[compiledInstruction.ProgramIdIndex], + Data = compiledInstruction.Data + }; + if (i == 0 && accounts.Any(a => a.PublicKey == "SysvarRecentB1ockHashes11111111111111111111")) + { + tx.NonceInformation = new NonceInformation { Instruction = instruction, Nonce = tx.RecentBlockHash }; + continue; + } + tx.Instructions.Add(instruction); + } + + return tx; + } + + /// + /// Populate the Transaction from the given compiled message and signatures. + /// + /// The compiled message, as base-64 encoded string. + /// The list of signatures. + /// The Transaction object. + public static Transaction Populate(string message, IList signatures = null) + => Populate(Message.Deserialize(message), signatures); + + /// + /// Deserialize a wire format transaction into a Transaction object. + /// + /// The data to deserialize into the Transaction object. + /// The Transaction object. + public static Transaction Deserialize(ReadOnlySpan data) + { + // Read number of signatures + (int signaturesLength, int encodedLength) = + ShortVectorEncoding.DecodeLength(data[..ShortVectorEncoding.SpanLength]); + List signatures = new(signaturesLength); + + for (int i = 0; i < signaturesLength; i++) + { + ReadOnlySpan signature = + data.Slice(encodedLength + (i * TransactionBuilder.SignatureLength), + TransactionBuilder.SignatureLength); + signatures.Add(signature.ToArray()); + } + + return Populate( + Message.Deserialize(data[ + (encodedLength + (signaturesLength * TransactionBuilder.SignatureLength))..]), + signatures); + } + + /// + /// Deserialize a transaction encoded as base-64 into a Transaction object. + /// + /// The data to deserialize into the Transaction object. + /// The Transaction object. + /// Thrown when the given string is null. + public static Transaction Deserialize(string data) + { + if (data == null) + throw new ArgumentNullException(nameof(data)); + + byte[] decodedBytes; + + try + { + decodedBytes = Convert.FromBase64String(data); + } + catch (Exception ex) + { + throw new Exception("could not decode transaction data from base64", ex); + } + + return Deserialize(decodedBytes); + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Transaction.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Transaction.cs.meta new file mode 100644 index 0000000..c4d86a0 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Transaction.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: caa2f9b40dd811b448345ada85f350c4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/TransactionError.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/TransactionError.cs new file mode 100644 index 0000000..728079f --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/TransactionError.cs @@ -0,0 +1,104 @@ +using Newtonsoft.Json; +using Solana.Unity.Rpc.Converters; + +namespace Solana.Unity.Rpc.Models +{ + /// + /// Represents a Transaction Error. + /// + [JsonConverter(typeof(TransactionErrorJsonConverter))] + public class TransactionError + { + /// + /// The type of transaction error. + /// + public TransactionErrorType Type { get; set; } + + /// + /// The inner instruction error, if the Type is TransactionErrorType.InstructionError. + /// + public InstructionError InstructionError { get; set; } + } + + /// + /// The possible types of Transaction errors. + /// + public enum TransactionErrorType + { + /// + /// An account is already being processed in another transaction in a way + /// that does not support parallelism + /// + AccountInUse, + /// + /// A `Pubkey` appears twice in the transaction's `account_keys`. Instructions can reference + /// `Pubkey`s more than once but the message must contain a list with no duplicate keys + /// + AccountLoadedTwice, + /// + /// Attempt to debit an account but found no record of a prior credit. + /// + AccountNotFound, + /// + /// Attempt to load a program that does not exist + /// + ProgramAccountNotFound, + /// + /// The from `Pubkey` does not have sufficient balance to pay the fee to schedule the transaction + /// + InsufficientFundsForFee, + /// + /// This account may not be used to pay transaction fees + /// + InvalidAccountForFee, + /// + /// The bank has seen this transaction before. This can occur under normal operation + /// when a UDP packet is duplicated, as a user error from a client not updating + /// its `recent_blockhash`, or as a double-spend attack. + /// + AlreadyProcessed, + /// + /// The bank has not seen the given `recent_blockhash` or the transaction is too old and + /// the `recent_blockhash` has been discarded. + /// + BlockhashNotFound, + /// + /// An error occurred while processing an instruction. + /// + InstructionError, + /// + /// Loader call chain is too deep + /// + CallChainTooDeep, + /// + /// Transaction requires a fee but has no signature present + /// + MissingSignatureForFee, + /// + /// Transaction contains an invalid account reference + /// + InvalidAccountIndex, + /// + /// Transaction did not pass signature verification + /// + SignatureFailure, + /// + /// This program may not be used for executing instructions + /// + InvalidProgramForExecution, + /// + /// Transaction failed to sanitize accounts offsets correctly + /// implies that account locks are not taken for this TX, and should + /// not be unlocked. + /// + SanitizeFailure, + /// + /// Transactions are currently disabled due to cluster maintenance + /// + ClusterMaintenance, + /// + /// Transaction processing left an account with an outstanding borrowed reference + /// + AccountBorrowOutstanding + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/TransactionError.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/TransactionError.cs.meta new file mode 100644 index 0000000..a941d15 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/TransactionError.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 901f56bb3b5028b4f8713815f7e047d6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/TransactionInstruction.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/TransactionInstruction.cs new file mode 100644 index 0000000..864ac96 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/TransactionInstruction.cs @@ -0,0 +1,131 @@ +using Solana.Unity.Rpc.Utilities; +using System; +using System.Collections.Generic; + +namespace Solana.Unity.Rpc.Models +{ + /// + /// Represents a transaction instruction before being compiled into the transaction's message. + /// + public class TransactionInstruction + { + /// + /// The program ID associated with the instruction. + /// + public byte[] ProgramId { get; init; } + + /// + /// The keys associated with the instruction. + /// + public IList Keys { get; init; } + + /// + /// The instruction-specific data. + /// + public byte[] Data { get; init; } + } + + /// + /// A compiled instruction within the transaction's message. + /// + public class CompiledInstruction + { + #region Layout + + /// + /// Represents the layout of the encoded values. + /// + internal static class Layout + { + /// + /// The offset at which the program's id index value begins. + /// + internal const int ProgramIdIndexOffset = 0; + } + + #endregion + + /// + /// The index of the program's key in the transaction's account keys. + /// + public byte ProgramIdIndex { get; init; } + + /// + /// The encoded length representing the number of key indices. + /// + public byte[] KeyIndicesCount { get; init; } + + /// + /// The indices of the account keys for the instruction as they appear in the transaction. + /// + public byte[] KeyIndices { get; init; } + + /// + /// The encoded length representing the number of key indices. + /// + public byte[] DataLength { get; init; } + + /// + /// The instruction data. + /// + public byte[] Data { get; init; } + + /// + /// Get the length of the compiled instruction. + /// + /// The length. + internal int Length() + { + return 1 + KeyIndicesCount.Length + KeyIndices.Length + DataLength.Length + Data.Length; + } + + /// + /// Attempts to deserialize a compiled instruction from the given data. + /// + /// The data to deserialize. + public static (CompiledInstruction Instruction, int Length) Deserialize(ReadOnlySpan data) + { + int instructionLength = 0; + // Read the programId index + byte programIdIndex = data[Layout.ProgramIdIndexOffset]; + instructionLength += 1; // ProgramIdIndex is zero + + // Read the number of keys for the instruction + ReadOnlySpan encodedKeyIndicesLength = + data.Slice(instructionLength, ShortVectorEncoding.SpanLength); + (int keyIndicesLength, int keyIndicesLengthEncodedLength) = + ShortVectorEncoding.DecodeLength(encodedKeyIndicesLength); + instructionLength += keyIndicesLengthEncodedLength; + + // Read the key indices for the instruction accounts + byte[] keyIndices = new byte[keyIndicesLength]; + for (int j = 0; j < keyIndicesLength; j++) + { + keyIndices[j] = data[instructionLength]; + instructionLength++; + } + + // Read the length of the instruction's data + ReadOnlySpan encodedDataLength = + data.Length > instructionLength + ShortVectorEncoding.SpanLength ? + data.Slice(instructionLength, ShortVectorEncoding.SpanLength) + : data.Slice(instructionLength, data.Length - instructionLength); + + (int dataLength, int dataLengthEncodedLength) = ShortVectorEncoding.DecodeLength(encodedDataLength); + instructionLength += dataLengthEncodedLength; + + // Read the instruction data + byte[] instructionEncodedData = data.Slice(instructionLength, dataLength).ToArray(); + instructionLength += dataLength; + + return (Instruction: new CompiledInstruction + { + ProgramIdIndex = programIdIndex, + KeyIndicesCount = encodedKeyIndicesLength[..keyIndicesLengthEncodedLength].ToArray(), + KeyIndices = keyIndices, + DataLength = encodedDataLength[..dataLengthEncodedLength].ToArray(), + Data = instructionEncodedData + }, Length: instructionLength); + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/TransactionInstruction.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/TransactionInstruction.cs.meta new file mode 100644 index 0000000..b97b9d9 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/TransactionInstruction.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 32f4c0d0ddb9c1e47b770ea8284b5a6c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Version.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Version.cs new file mode 100644 index 0000000..83a9b55 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Version.cs @@ -0,0 +1,22 @@ +using Newtonsoft.Json; + +namespace Solana.Unity.Rpc.Models +{ + /// + /// Represents the current solana versions running on the node. + /// + public class NodeVersion + { + /// + /// Software version of solana-core. + /// + [JsonProperty("solana-core")] + public string SolanaCore { get; set; } + + /// + /// unique identifier of the current software's feature set. + /// + [JsonProperty("feature-set")] + public ulong? FeatureSet { get; set; } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Version.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Version.cs.meta new file mode 100644 index 0000000..4d9a22a --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/Version.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 86571b79f0ddfb9469f40540c516d327 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/VoteAccount.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/VoteAccount.cs new file mode 100644 index 0000000..a7f9b45 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/VoteAccount.cs @@ -0,0 +1,72 @@ + +using Newtonsoft.Json; + +namespace Solana.Unity.Rpc.Models +{ + /// + /// Represents the account info and associated stake for all the voting accounts in the current bank. + /// + public class VoteAccount + { + /// + /// The root slot for this vote account. + /// + public ulong RootSlot { get; set; } + + /// + /// The vote account address, as a base-58 encoded string. + /// + [JsonProperty("votePubkey")] + public string VotePublicKey { get; set; } + + /// + /// The validator identity, as a base-58 encoded string. + /// + [JsonProperty("nodePubkey")] + public string NodePublicKey { get; set; } + + /// + /// The stake, in lamports, delegated to this vote account and active in this epoch. + /// + public ulong ActivatedStake { get; set; } + + /// + /// Whether the vote account is staked for this epoch. + /// + public bool EpochVoteAccount { get; set; } + + /// + /// Percentage of rewards payout owed to the vote account. + /// + public decimal Commission { get; set; } + + /// + /// Most recent slot voted on by this vote account. + /// + public ulong LastVote { get; set; } + + /// + /// History of how many credits earned by the end of the each epoch. + /// + /// Each array contains [epoch, credits, previousCredits]; + /// + /// + public ulong[][] EpochCredits { get; set; } + } + + /// + /// Represents the vote accounts. + /// + public class VoteAccounts + { + /// + /// Current vote accounts. + /// + public VoteAccount[] Current { get; set; } + + /// + /// Delinquent vote accounts. + /// + public VoteAccount[] Delinquent { get; set; } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/VoteAccount.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/VoteAccount.cs.meta new file mode 100644 index 0000000..84561b2 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Models/VoteAccount.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0d9199d71e982af42a6a29eb1e1c3f8e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Solana.Unity.Rpc.csproj.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Solana.Unity.Rpc.csproj.meta new file mode 100644 index 0000000..34618d4 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Solana.Unity.Rpc.csproj.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 8f59640fb45096c4fae3a6d9fc500ab6 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/SolanaRpcBatchComposer.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/SolanaRpcBatchComposer.cs new file mode 100644 index 0000000..1b56741 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/SolanaRpcBatchComposer.cs @@ -0,0 +1,433 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using Newtonsoft.Json.Linq; +using Newtonsoft.Json.Serialization; +using Solana.Unity.Rpc.Core.Http; +using Solana.Unity.Rpc.Messages; +using Solana.Unity.Rpc.Types; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Solana.Unity.Rpc +{ + /// + /// This object allows a caller to compose a batch of RPC requests for batch submission + /// + public class SolanaRpcBatchComposer + { + + /// + /// The `IRpcClient` instance to use + /// + private IRpcClient _rpcClient; + + /// + /// Batch of requests and their handlers + /// + private List _reqs; + + /// + /// JSON serializer options + /// + private JsonSerializerSettings _jsonOptions; + + /// + /// How many requests are in this batch + /// + public int Count => _reqs.Count; + + /// + /// Holds the auto execution mode. + /// + private BatchAutoExecuteMode _autoMode; + + /// + /// Holds the batch size threshold for the auto batch execution mode. + /// + private int _autoBatchSize; + + /// + /// Constructs a new SolanaRpcBatchComposer instance + /// + /// An RPC client + public SolanaRpcBatchComposer(IRpcClient rpcClient) + { + _rpcClient = rpcClient ?? throw new ArgumentNullException(nameof(rpcClient)); + _reqs = new List(); + _jsonOptions = new JsonSerializerSettings() + { + ContractResolver = new CamelCasePropertyNamesContractResolver(), + Converters = + { + new StringEnumConverter(new CamelCaseNamingStrategy()) + } + }; + } + + #region Execution + + + /// + /// Sets the auto execute mode and trigger threshold + /// + /// The auto execute mode to use. + /// The number of requests that will trigger a batch execution. + public void AutoExecute(BatchAutoExecuteMode mode, int batchSizeTrigger) + { + this._autoMode = mode; + this._autoBatchSize = batchSizeTrigger; + } + + /// + /// Returns a batch of JSON RPC requests + /// + /// + public JsonRpcBatchRequest CreateJsonRequests() + { + var reqs = new JsonRpcBatchRequest(); + reqs.AddRange(_reqs.Select(x => x.Req)); + return reqs; + } + + /// + /// Execute a batch request and process the response into the expected native types. + /// Batch failure execption will invoke callbacks with an exception. + /// + public JsonRpcBatchResponse Execute() + { + return ExecuteAsync(_rpcClient).Result; + } + + /// + /// Execute a batch request and process the response into the expected native types. + /// Batch failure execption will invoke callbacks with an exception. + /// + /// The RPC client to execute this batch with + public JsonRpcBatchResponse Execute(IRpcClient client) + { + return ExecuteAsync(client).Result; + } + /// + /// Execute a batch request and process the response into the expected native types. + /// Batch failure execption will invoke callbacks with an exception. + /// + public async Task ExecuteAsync() + { + return await ExecuteAsync(_rpcClient); + } + + /// + /// Execute a batch request and process the response into the expected native types. + /// Batch failure execption will invoke callbacks with an exception. + /// + /// The RPC client to execute this batch with + public async Task ExecuteAsync(IRpcClient client) + { + var reqs = this.CreateJsonRequests(); + var response = await client.SendBatchRequestAsync(reqs); + if (response.WasSuccessful) + return ProcessBatchResponse(response); + else + return ProcessBatchFailure(response); + } + + /// + /// Execute a batch request and process the response into the expected native types. + /// Batch failure execption will throw an Exception and bypass callbacks. + /// + public JsonRpcBatchResponse ExecuteWithFatalFailure() + { + return ExecuteWithFatalFailureAsync(_rpcClient).Result; + } + + /// + /// Execute a batch request and process the response into the expected native types. + /// Batch failure execption will throw an Exception and bypass callbacks. + /// + /// The RPC client to execute this batch with + public JsonRpcBatchResponse ExecuteWithFatalFailure(IRpcClient client) + { + return ExecuteWithFatalFailureAsync(client).Result; + } + + /// + /// Execute a batch request and process the response into the expected native types. + /// Batch failure execption will throw an Exception and bypass callbacks. + /// + public async Task ExecuteWithFatalFailureAsync() + { + return await ExecuteWithFatalFailureAsync(_rpcClient); + } + + /// + /// Execute a batch request and process the response into the expected native types. + /// Batch failure execption will throw an Exception and bypass callbacks. + /// + /// + public async Task ExecuteWithFatalFailureAsync(IRpcClient client) + { + var reqs = this.CreateJsonRequests(); + var response = await client.SendBatchRequestAsync(reqs); + if (response.WasSuccessful) + return ProcessBatchResponse(response); + else + throw new ApplicationException($"Batch was unsuccessful: {response.Reason}"); + } + + /// + /// Handles the conversion of the generic JSON deserialized response objects to the native types. + /// + /// + /// + internal JsonRpcBatchResponse ProcessBatchResponse(RequestResult response) + { + // sanity check response matches request + if (response == null) throw new ArgumentNullException(nameof(response)); + if (_reqs.Count != response.Result.Count) throw new ApplicationException($"Batch req/resp size mismatch {_reqs.Count}/{response.Result.Count}"); + + // transfer expected type info to individual + // batch response items + for (int ix = 0; ix < _reqs.Count; ix++) + { + var req = _reqs[ix]; + var resp = response.Result[ix]; + + // set the runtime type + resp.ResultType = req.ResultType; + + // catch any type mapping exceptions and feed into callback + bool callbackInvoked = false; + try + { + // translate generic JSON deserialized content into POCO runtime types + if (req.ResultType != null) + { + resp.Result = MapJsonTypeToNativeType(resp.Result, req.ResultType); + } + + } + catch (Exception ex) + { + + // invoke callback with the exception + if (req.Callback != null) + { + callbackInvoked = true; + req.Callback.Invoke(null, ex); + } + + } + + // invoke callback with safe mapped data type + if (!callbackInvoked && req.Callback != null) + { + callbackInvoked = true; + req.Callback.Invoke(resp, null); + } + + } + + // reset ready for reuse + Clear(); + + // pass back the JSON batch innards + return response.Result; + } + + /// + /// Process a failed batch response by notifying all callbacks with the exception + /// + /// The failed batch RPC response + /// + internal JsonRpcBatchResponse ProcessBatchFailure(RequestResult response) + { + // create failed batch exception + var ex = new BatchRequestException(response); + + // transfer expected type info to individual + // batch response items + for (int ix = 0; ix < _reqs.Count; ix++) + { + // no response for each request as whole batch failed + var req = _reqs[ix]; + req.Callback.Invoke(null, ex); + } + + // reset ready for reuse + Clear(); + + // return the result + return response.Result; + + } + + + /// + /// Convert a possible JsonElement type into desired response native type. + /// + /// + /// + /// + public object MapJsonTypeToNativeType(object input, Type nativeType) + { + if (input is JObject or JArray) + { + // serializes + deserializes the JSON into runtime type - suboptimal but expedient + var bufferWriter = new MemoryStream(); + using (var writer = new JsonTextWriter(new StreamWriter( bufferWriter))) + if (input is JObject) + { + ((JObject)input).WriteTo(writer); + } + else + { + ((JArray)input).WriteTo(writer); + } + return JsonSerializer.Create(_jsonOptions) + .Deserialize( + new StringReader( Encoding.UTF8.GetString( bufferWriter.ToArray())), nativeType); + } + + return input; + } + + #endregion + + /// + /// Clears the internal list of requests + /// + public void Clear() + { + _reqs.Clear(); + } + + /// + /// Executes any batch using the auto execution mode (if set) or throws an execption. + /// + public void Flush() + { + switch (_autoMode) + { + case BatchAutoExecuteMode.ExecuteWithFatalFailure: + ExecuteWithFatalFailure(_rpcClient); + break; + + case BatchAutoExecuteMode.ExecuteWithCallbackFailures: + Execute(_rpcClient); + break; + + default: + throw new ApplicationException("BatchComposer AutoExecute mode not set"); + } + } + + internal void AddRequest(string method, IList parameters, Action callback) + { + var wrapped = WrapCallback(callback); + var handler = RpcBatchReqRespItem.Create(_rpcClient.GetNextIdForReq(), method, parameters, wrapped); + Add(handler); + } + + internal Task AddRequest(string method, IList parameters) + { + var taskSource = new TaskCompletionSource(); + var callback = WrapTaskSource(taskSource); + var handler = RpcBatchReqRespItem.Create(_rpcClient.GetNextIdForReq(), method, parameters, callback); + Add(handler); + return taskSource.Task; + } + + internal void Add(RpcBatchReqRespItem task) + { + // add to batch + _reqs.Add(task); + + // does this trigger an auto execute? + if (_autoMode != BatchAutoExecuteMode.Manual && _reqs.Count >= _autoBatchSize) + Flush(); + } + + private static Action WrapCallback(Action callback) + { + if (callback == null) return null; + + // wrap into common typed callback + Action wrapper = (item, ex) => + { + T obj = default(T); + if (item != null) obj = item.ResultAs(); + callback.Invoke(obj, ex); + }; + return wrapper; + } + + private static Action WrapTaskSource(TaskCompletionSource taskSource) + { + if (taskSource == null) return null; + + // wrap into common typed callback + Action wrapper = (item, ex) => + { + T obj = item.ResultAs(); + if (ex != null) + taskSource.SetException(ex); + else + taskSource.SetResult(obj); + }; + return wrapper; + } + + internal static KeyValue HandleCommitment(Commitment parameter, Commitment defaultValue = Commitment.Finalized) + => parameter != defaultValue ? KeyValue.Create("commitment", parameter) : null; + + } + + /// + /// Encapsulates the request, the expected return type and will handle the response callback/task/delegate. + /// + internal class RpcBatchReqRespItem + { + /// + /// Create an RpcBatchReqRespItem instance ready for execution. + /// + /// + /// + /// + /// + /// + /// + internal static RpcBatchReqRespItem Create(int id, string method, IList parameters, + Action callback) + { + var req = new JsonRpcRequest(id, method, parameters); + return new RpcBatchReqRespItem(req, typeof(T), callback); + } + + /// + /// Construct a RpcBatchReqRespItem instance. + /// + /// + /// + /// + private RpcBatchReqRespItem(JsonRpcRequest req, + Type resultType, + Action callback) + { + this.Req = req ?? throw new ArgumentNullException(nameof(req)); + this.ResultType = resultType ?? throw new ArgumentNullException(nameof(resultType)); + this.Callback = callback; + } + + public readonly JsonRpcRequest Req; + public readonly Type ResultType; + public readonly Action Callback; + + } + + +} + diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/SolanaRpcBatchComposer.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/SolanaRpcBatchComposer.cs.meta new file mode 100644 index 0000000..4c9ffa0 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/SolanaRpcBatchComposer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 23c20d4ac50e91644a4f3f461af209b2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/SolanaRpcBatchWithCallbacks.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/SolanaRpcBatchWithCallbacks.cs new file mode 100644 index 0000000..38a5082 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/SolanaRpcBatchWithCallbacks.cs @@ -0,0 +1,352 @@ +using Solana.Unity.Rpc.Core.Http; +using Solana.Unity.Rpc.Messages; +using Solana.Unity.Rpc.Models; +using Solana.Unity.Rpc.Types; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Solana.Unity.Rpc +{ + /// + /// This object is used to create a batch of RPC requests that can be executed as a single call to the RPC endpoint. + /// Use of batches can have give a significant performance improvement instead of making multiple requests. + /// The execution of batches can be controlled manually via the Flush method, or can be invoked automatically using auto-execute mode. + /// Auto-execute mode is useful when iterating through large worksets. + /// + public class SolanaRpcBatchWithCallbacks + { + + /// + /// Constructs a new SolanaRpcBatchWithCallbacks instance + /// + /// An RPC client + public SolanaRpcBatchWithCallbacks(IRpcClient rpcClient) + { + _composer = new SolanaRpcBatchComposer(rpcClient); + } + + /// + /// A batch composer instance + /// + private SolanaRpcBatchComposer _composer; + + /// + /// How many requests are in this batch + /// + public SolanaRpcBatchComposer Composer => _composer; + + /// + /// Sets the auto execute mode and trigger threshold + /// + /// The auto execute mode to use. + /// The number of requests that will trigger a batch execution. + public void AutoExecute(BatchAutoExecuteMode mode, int batchSizeTrigger) + { + _composer.AutoExecute(mode, batchSizeTrigger); + } + + /// + /// Used to execute any requests remaining in the batch. + /// + public void Flush() + { + _composer.Flush(); + } + + #region RPC Methods + + /// + /// Gets the balance for a certain public key. + /// + /// The commitment parameter is optional, the default value is not sent. + /// + /// + /// The public key. + /// The state commitment to consider when querying the ledger state. + /// The callback to handle the result. + public void GetBalance(string pubKey, Commitment commitment = Commitment.Finalized, + Action, Exception> callback = null) + { + var parameters = Parameters.Create(pubKey, ConfigObject.Create(HandleCommitment(commitment))); + _composer.AddRequest("getBalance", parameters, callback); + } + + /// + /// Gets all SPL Token accounts by token owner. + /// + /// Public key of account owner query, as base-58 encoded string. + /// Public key of the specific token Mint to limit accounts to, as base-58 encoded string. + /// Public key of the Token program ID that owns the accounts, as base-58 encoded string. + /// The state commitment to consider when querying the ledger state. + /// The callback to handle the result. + public void GetTokenAccountsByOwner(string ownerPubKey, string tokenMintPubKey = null, + string tokenProgramId = null, Commitment commitment = Commitment.Finalized, + Action>, Exception> callback = null) + { + if (string.IsNullOrWhiteSpace(tokenMintPubKey) && string.IsNullOrWhiteSpace(tokenProgramId)) + throw new ArgumentException("either tokenProgramId or tokenMintPubKey must be set"); + + var parameters = Parameters.Create( + ownerPubKey, + ConfigObject.Create( + KeyValue.Create("mint", tokenMintPubKey), + KeyValue.Create("programId", tokenProgramId)), + ConfigObject.Create( + HandleCommitment(commitment), + KeyValue.Create("encoding", "jsonParsed"))); + + _composer.AddRequest("getTokenAccountsByOwner", parameters, callback); + + } + + + /// + /// Gets signatures with the given commitment for transactions involving the address. + /// + /// Unless searchTransactionHistory is included, this method only searches the recent status cache of signatures. + /// + /// + /// The account address as base-58 encoded string. + /// Maximum transaction signatures to return, between 1-1000. Default is 1000. + /// Start searching backwards from this transaction signature. + /// Search until this transaction signature, if found before limit is reached. + /// The state commitment to consider when querying the ledger state. + /// The callback to handle the result. + public void GetSignaturesForAddress(string accountPubKey, ulong limit = 1000, + string before = null, string until = null, Commitment commitment = Commitment.Finalized, + Action, Exception> callback = null) + { + if (commitment == Commitment.Processed) + throw new ArgumentException("Commitment.Processed is not supported for this method."); + + var parameters = Parameters.Create( + accountPubKey, + ConfigObject.Create( + KeyValue.Create("limit", limit != 1000 ? limit : null), + KeyValue.Create("before", before), + KeyValue.Create("until", until), + HandleCommitment(commitment))); + + _composer.AddRequest("getSignaturesForAddress", parameters, callback); + } + + + /// + /// Gets confirmed signatures for transactions involving the address. + /// + /// Unless searchTransactionHistory is included, this method only searches the recent status cache of signatures. + /// + /// + /// The account address as base-58 encoded string. + /// Maximum transaction signatures to return, between 1-1000. Default is 1000. + /// Start searching backwards from this transaction signature. + /// Search until this transaction signature, if found before limit is reached. + /// The state commitment to consider when querying the ledger state. + /// The callback to handle the result. + [Obsolete("Please use GetSignaturesForAddressAsync whenever possible instead. This method is expected to be removed in solana-core v1.8.")] + public void GetConfirmedSignaturesForAddress2(string accountPubKey, ulong limit = 1000, + string before = null, string until = null, + Commitment commitment = Commitment.Finalized, + Action, Exception> callback = null) + { + if (commitment == Commitment.Processed) + throw new ArgumentException("Commitment.Processed is not supported for this method."); + + var parameters = Parameters.Create( + accountPubKey, + ConfigObject.Create( + KeyValue.Create("limit", limit != 1000 ? limit : null), + KeyValue.Create("before", before), + KeyValue.Create("until", until), + HandleCommitment(commitment))); + + _composer.AddRequest("getConfirmedSignaturesForAddress2", parameters, callback); + } + + + /// + /// Returns all accounts owned by the provided program Pubkey. + /// Accounts must meet all filter criteria to be included in the results. + /// + /// The program public key. + /// The state commitment to consider when querying the ledger state. + /// The data size of the account to compare against the program account data. + /// The list of comparisons to match against the program account data. + /// The callback to handle the result. + public void GetProgramAccounts(string pubKey, Commitment commitment = Commitment.Finalized, + int? dataSize = null, IList memCmpList = null, + Action, Exception> callback = null) + { + List filters = Parameters.Create(ConfigObject.Create(KeyValue.Create("dataSize", dataSize))); + if (memCmpList != null) + { + filters ??= new List(); + filters.AddRange(memCmpList.Select(filter => ConfigObject.Create(KeyValue.Create("memcmp", + ConfigObject.Create(KeyValue.Create("offset", filter.Offset), + KeyValue.Create("bytes", filter.Bytes)))))); + } + + var parameters = Parameters.Create( + pubKey, + ConfigObject.Create( + KeyValue.Create("encoding", "base64"), + KeyValue.Create("filters", filters), + HandleCommitment(commitment))); + + _composer.AddRequest("getProgramAccounts", parameters, callback); + + } + + + /// + /// Returns transaction details for a confirmed transaction. + /// + /// + /// The commitment parameter is optional, is not supported, + /// the default value is not sent. + /// + /// + /// + /// Transaction signature as base-58 encoded string. + /// The state commitment to consider when querying the ledger state. + /// The callback to handle the result. + public void GetTransaction(string signature, + Commitment commitment = Commitment.Finalized, + Action callback = null) + { + var parameters = Parameters.Create( + signature, + ConfigObject.Create( + KeyValue.Create("encoding", "json"), + HandleCommitment(commitment))); + + _composer.AddRequest("getTransaction", parameters, callback); + + } + + /// + /// Gets the account info. + /// + /// The commitment parameter is optional, the default value is not sent. + /// + /// + /// The account public key. + /// The state commitment to consider when querying the ledger state. + /// The encoding of the account data. + /// The callback to handle the result. + public void GetAccountInfo(string pubKey, Commitment commitment = Commitment.Finalized, + BinaryEncoding encoding = BinaryEncoding.Base64, Action, Exception> callback = null) + { + var parameters = Parameters.Create( + pubKey, + ConfigObject.Create( + KeyValue.Create("encoding", encoding), + HandleCommitment(commitment))); + _composer.AddRequest("getAccountInfo", parameters, callback); + } + + /// + /// Gets the 20 largest token accounts of a particular SPL Token. + /// + /// Public key of Token Mint to query, as base-58 encoded string. + /// The state commitment to consider when querying the ledger state. + /// The callback to handle the result. + public void GetTokenLargestAccounts(string tokenMintPubKey, Commitment commitment = Commitment.Finalized, + Action>, Exception> callback = null) + { + var parameters = Parameters.Create(tokenMintPubKey, ConfigObject.Create(HandleCommitment(commitment))); + + _composer.AddRequest("getTokenLargestAccounts", parameters, callback); + } + + /// + /// Sends a transaction. + /// + /// The signed transaction as byte array. + /// If true skip the prflight transaction checks (default false). + /// The block commitment used to retrieve block hashes and verify success. + /// The callback to handle the result. + public void SendTransaction(byte[] transaction, + bool skipPreflight = false, + Commitment preflightCommitment = Commitment.Finalized, + Action callback = null) => + SendTransaction(Convert.ToBase64String(transaction), skipPreflight, preflightCommitment, callback); + + + /// + /// Sends a transaction. + /// + /// The signed transaction as base-64 encoded string. + /// If true skip the prflight transaction checks (default false). + /// The block commitment used for preflight. + /// The callback to handle the result. + public void SendTransaction(string transaction, + bool skipPreflight = false, + Commitment preflightCommitment = Commitment.Finalized, + Action callback = null) + { + var parameters = Parameters.Create( + transaction, + ConfigObject.Create( + KeyValue.Create("skipPreflight", skipPreflight ? skipPreflight : null), + KeyValue.Create("preflightCommitment", + preflightCommitment == Commitment.Finalized ? null : preflightCommitment), + KeyValue.Create("encoding", BinaryEncoding.Base64))); + + _composer.AddRequest("sendTransaction", parameters, callback); + } + + + /// + /// Gets the account info for multiple accounts. + /// + /// The list of the accounts public keys. + /// The state commitment to consider when querying the ledger state. + /// The callback to handle the result. + public void GetMultipleAccounts(IList accounts, + Commitment commitment = Commitment.Finalized, + Action>, Exception> callback = null) + { + var parameters = Parameters.Create( + accounts, + ConfigObject.Create( + KeyValue.Create("encoding", "base64"), + HandleCommitment(commitment))); + + _composer.AddRequest("getMultipleAccounts", parameters, callback); + + } + + + /// + /// Gets the token account info. + /// + /// The commitment parameter is optional, the default value is not sent. + /// + /// + /// The token account public key. + /// The state commitment to consider when querying the ledger state. + /// The callback to handle the result. + public void GetTokenAccountInfo(string pubKey, + Commitment commitment = Commitment.Finalized, + Action, Exception> callback = null) + { + var parameters = Parameters.Create( + pubKey, + ConfigObject.Create( + KeyValue.Create("encoding", "jsonParsed"), + HandleCommitment(commitment))); + + _composer.AddRequest("getAccountInfo", parameters, callback); + + } + #endregion + + private KeyValue HandleCommitment(Commitment parameter, Commitment defaultValue = Commitment.Finalized) + => parameter != defaultValue ? KeyValue.Create("commitment", parameter) : null; + + } +} diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/SolanaRpcBatchWithCallbacks.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/SolanaRpcBatchWithCallbacks.cs.meta new file mode 100644 index 0000000..fa5cf34 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/SolanaRpcBatchWithCallbacks.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d6edd09c0bcfde9479c87795e3c0d0ce +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/SolanaRpcClient.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/SolanaRpcClient.cs new file mode 100644 index 0000000..c0a6005 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/SolanaRpcClient.cs @@ -0,0 +1,1072 @@ +using Solana.Unity.Rpc.Core; +using Solana.Unity.Rpc.Core.Http; +using Solana.Unity.Rpc.Messages; +using Solana.Unity.Rpc.Models; +using Solana.Unity.Rpc.Types; +using Solana.Unity.Rpc.Utilities; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; + +namespace Solana.Unity.Rpc +{ + /// + /// Implements functionality to interact with the Solana JSON RPC API. + /// + [DebuggerDisplay("Cluster = {" + nameof(NodeAddress) + "}")] + internal class SolanaRpcClient : JsonRpcClient, IRpcClient + { + /// + /// Message Id generator. + /// + private readonly IdGenerator _idGenerator = new IdGenerator(); + + /// + /// Initialize the Rpc Client with the passed url. + /// + /// The url of the node exposing the JSON RPC API. + /// The logger to use. + /// An http client. + + /// A rate limiting strategy or null. + internal SolanaRpcClient(string url, object logger, HttpClient httpClient = default, IRateLimiter rateLimiter = null) + : base(url, logger, httpClient, rateLimiter) + { + } + + #region RequestBuilder + + /// + /// Build the request for the passed RPC method and parameters. + /// + /// The request's RPC method. + /// A list of parameters to include in the request. + /// The type of the request result. + /// A task which may return a request result. + private JsonRpcRequest BuildRequest(string method, IList parameters) + => new JsonRpcRequest(_idGenerator.GetNextId(), method, parameters); + + /// + /// + /// + /// The request's RPC method. + /// The type of the request result. + /// A task which may return a request result. + private async Task> SendRequestAsync(string method) + { + JsonRpcRequest req = BuildRequest(method, null); + + return await SendRequest(req); + } + + /// + /// Send a request asynchronously. + /// + /// The request's RPC method. + /// A list of parameters to include in the request. + /// The type of the request result. + /// A task which may return a request result. + private async Task> SendRequestAsync(string method, IList parameters) + { + JsonRpcRequest req = BuildRequest(method, parameters); + return await SendRequest(req); + } + + private KeyValue HandleCommitment(Commitment parameter, Commitment defaultValue = Commitment.Finalized) + => parameter != defaultValue ? KeyValue.Create("commitment", parameter) : null; + + private KeyValue HandleTransactionDetails(TransactionDetailsFilterType parameter, + TransactionDetailsFilterType defaultValue = TransactionDetailsFilterType.Full) + => parameter != defaultValue ? KeyValue.Create("transactionDetails", parameter) : null; + + #endregion + + + #region Accounts + + /// + public async Task>> GetTokenMintInfoAsync(string pubKey, + Commitment commitment = Commitment.Finalized) + { + return await SendRequestAsync>("getAccountInfo", + Parameters.Create( + pubKey, + ConfigObject.Create( + KeyValue.Create("encoding", "jsonParsed"), + HandleCommitment(commitment)))); + } + + /// + public RequestResult> GetTokenMintInfo(string pubKey, + Commitment commitment = Commitment.Finalized) + => GetTokenMintInfoAsync(pubKey, commitment).Result; + + + /// + public async Task>> GetTokenAccountInfoAsync(string pubKey, + Commitment commitment = Commitment.Finalized) + { + return await SendRequestAsync>("getAccountInfo", + Parameters.Create( + pubKey, + ConfigObject.Create( + KeyValue.Create("encoding", "jsonParsed"), + HandleCommitment(commitment)))); + } + + /// + public RequestResult> GetTokenAccountInfo(string pubKey, + Commitment commitment = Commitment.Finalized) + => GetTokenAccountInfoAsync(pubKey, commitment).Result; + + + + /// + public async Task>> GetAccountInfoAsync(string pubKey, + Commitment commitment = Commitment.Finalized, BinaryEncoding encoding = BinaryEncoding.Base64) + { + return await SendRequestAsync>("getAccountInfo", + Parameters.Create( + pubKey, + ConfigObject.Create( + KeyValue.Create("encoding", encoding), + HandleCommitment(commitment)))); + } + + /// + public RequestResult> GetAccountInfo(string pubKey, + Commitment commitment = Commitment.Finalized, BinaryEncoding encoding = BinaryEncoding.Base64) + => GetAccountInfoAsync(pubKey, commitment, encoding).Result; + + + /// + public async Task>> GetProgramAccountsAsync(string pubKey, + Commitment commitment = Commitment.Finalized, int? dataSize = null, IList memCmpList = null) + { + List filters = Parameters.Create(ConfigObject.Create(KeyValue.Create("dataSize", dataSize))); + if (memCmpList != null) + { + filters ??= new List(); + filters.AddRange(memCmpList.Select(filter => ConfigObject.Create(KeyValue.Create("memcmp", + ConfigObject.Create(KeyValue.Create("offset", filter.Offset), + KeyValue.Create("bytes", filter.Bytes)))))); + } + + return await SendRequestAsync>("getProgramAccounts", + Parameters.Create( + pubKey, + ConfigObject.Create( + KeyValue.Create("encoding", "base64"), + KeyValue.Create("filters", filters), + HandleCommitment(commitment)))); + } + + /// + public RequestResult> GetProgramAccounts(string pubKey, + Commitment commitment = Commitment.Finalized, + int? dataSize = null, IList memCmpList = null) + => GetProgramAccountsAsync(pubKey, commitment, dataSize, memCmpList).Result; + + + /// + public async Task>>> GetMultipleAccountsAsync( + IList accounts, + Commitment commitment = Commitment.Finalized) + { + return await SendRequestAsync>>("getMultipleAccounts", + Parameters.Create( + accounts, + ConfigObject.Create( + KeyValue.Create("encoding", "base64"), + HandleCommitment(commitment)))); + } + + /// + public RequestResult>> GetMultipleAccounts(IList accounts, + Commitment commitment = Commitment.Finalized) + => GetMultipleAccountsAsync(accounts, commitment).Result; + + #endregion + + /// + public async Task>> GetBalanceAsync(string pubKey, + Commitment commitment = Commitment.Finalized) + { + return await SendRequestAsync>("getBalance", + Parameters.Create(pubKey, ConfigObject.Create(HandleCommitment(commitment)))); + } + + /// + public RequestResult> GetBalance(string pubKey, + Commitment commitment = Commitment.Finalized) + => GetBalanceAsync(pubKey, commitment).Result; + + #region Blocks + + /// + public async Task> GetBlockAsync(ulong slot, + Commitment commitment = Commitment.Finalized, + TransactionDetailsFilterType transactionDetails = TransactionDetailsFilterType.Full, + bool blockRewards = false) + { + if (commitment == Commitment.Processed) + { + throw new ArgumentException("Commitment.Processed is not supported for this method."); + } + + return await SendRequestAsync("getBlock", + Parameters.Create(slot, ConfigObject.Create( + KeyValue.Create("encoding", "json"), + HandleTransactionDetails(transactionDetails), + KeyValue.Create("rewards", blockRewards ? blockRewards : null), + HandleCommitment(commitment)))); + } + + /// + public RequestResult GetBlock(ulong slot, Commitment commitment = Commitment.Finalized, + TransactionDetailsFilterType transactionDetails = TransactionDetailsFilterType.Full, + bool blockRewards = false) + => GetBlockAsync(slot, commitment, transactionDetails, blockRewards).Result; + + + /// + public async Task>> GetBlocksAsync(ulong startSlot, ulong endSlot = 0, + Commitment commitment = Commitment.Finalized) + { + if (commitment == Commitment.Processed) + { + throw new ArgumentException("Commitment.Processed is not supported for this method."); + } + + return await SendRequestAsync>("getBlocks", + Parameters.Create(startSlot, endSlot > 0 ? endSlot : null, + ConfigObject.Create(HandleCommitment(commitment)))); + } + + /// + public async Task> GetConfirmedBlockAsync(ulong slot, + Commitment commitment = Commitment.Finalized, + TransactionDetailsFilterType transactionDetails = TransactionDetailsFilterType.Full, + bool blockRewards = false) + { + if (commitment == Commitment.Processed) + { + throw new ArgumentException("Commitment.Processed is not supported for this method."); + } + + return await SendRequestAsync("getConfirmedBlock", + Parameters.Create(slot, ConfigObject.Create( + KeyValue.Create("encoding", "json"), + HandleTransactionDetails(transactionDetails), + KeyValue.Create("rewards", blockRewards ? blockRewards : null), + HandleCommitment(commitment)))); + } + + /// + public RequestResult GetConfirmedBlock(ulong slot, Commitment commitment = Commitment.Finalized, + TransactionDetailsFilterType transactionDetails = TransactionDetailsFilterType.Full, + bool blockRewards = false) + => GetConfirmedBlockAsync(slot, commitment, transactionDetails, blockRewards).Result; + + + /// + public RequestResult> GetBlocks(ulong startSlot, ulong endSlot = 0, + Commitment commitment = Commitment.Finalized) + => GetBlocksAsync(startSlot, endSlot, commitment).Result; + + /// + public async Task>> GetConfirmedBlocksAsync(ulong startSlot, ulong endSlot = 0, + Commitment commitment = Commitment.Finalized) + { + if (commitment == Commitment.Processed) + { + throw new ArgumentException("Commitment.Processed is not supported for this method."); + } + + return await SendRequestAsync>("getConfirmedBlocks", + Parameters.Create(startSlot, endSlot > 0 ? endSlot : null, + ConfigObject.Create(HandleCommitment(commitment)))); + } + + /// + public RequestResult> GetConfirmedBlocks(ulong startSlot, ulong endSlot = 0, + Commitment commitment = Commitment.Finalized) + => GetConfirmedBlocksAsync(startSlot, endSlot, commitment).Result; + + /// + public async Task>> GetConfirmedBlocksWithLimitAsync(ulong startSlot, ulong limit, + Commitment commitment = Commitment.Finalized) + { + if (commitment == Commitment.Processed) + { + throw new ArgumentException("Commitment.Processed is not supported for this method."); + } + + return await SendRequestAsync>("getConfirmedBlocksWithLimit", + Parameters.Create(startSlot, limit, ConfigObject.Create(HandleCommitment(commitment)))); + } + + /// + public RequestResult> GetBlocksWithLimit(ulong startSlot, ulong limit, + Commitment commitment = Commitment.Finalized) + => GetBlocksWithLimitAsync(startSlot, limit, commitment).Result; + + /// + public RequestResult> GetConfirmedBlocksWithLimit(ulong startSlot, ulong limit, + Commitment commitment = Commitment.Finalized) + => GetConfirmedBlocksWithLimitAsync(startSlot, limit, commitment).Result; + + /// + public async Task>> GetBlocksWithLimitAsync(ulong startSlot, ulong limit, + Commitment commitment = Commitment.Finalized) + { + if (commitment == Commitment.Processed) + { + throw new ArgumentException("Commitment.Processed is not supported for this method."); + } + + return await SendRequestAsync>("getBlocksWithLimit", + Parameters.Create(startSlot, limit, ConfigObject.Create(HandleCommitment(commitment)))); + } + + + /// + public RequestResult GetFirstAvailableBlock() + => GetFirstAvailableBlockAsync().Result; + + /// + public async Task> GetFirstAvailableBlockAsync() + { + return await SendRequestAsync("getFirstAvailableBlock"); + } + + #endregion + + #region Block Production + + /// + public async Task>> GetBlockProductionAsync( + string identity = null, ulong? firstSlot = null, ulong? lastSlot = null, + Commitment commitment = Commitment.Finalized) + { + Dictionary parameters = new Dictionary(); + + if (commitment != Commitment.Finalized) + { + parameters.Add("commitment", commitment); + } + + if (!string.IsNullOrEmpty(identity)) + { + parameters.Add("identity", identity); + } + + if (firstSlot.HasValue) + { + Dictionary range = new Dictionary { { "firstSlot", firstSlot.Value } }; + + if (lastSlot.HasValue) + { + range.Add("lastSlot", lastSlot.Value); + } + + parameters.Add("range", range); + } + else if (lastSlot.HasValue) + { + throw new ArgumentException( + "Range parameters are optional, but the lastSlot argument must be paired with a firstSlot."); + } + + List args = parameters.Count > 0 ? new List { parameters } : null; + + return await SendRequestAsync>("getBlockProduction", args); + } + + /// + public RequestResult> GetBlockProduction(string identity = null, + ulong? firstSlot = null, ulong? lastSlot = null, Commitment commitment = Commitment.Finalized) + => GetBlockProductionAsync(identity, firstSlot, lastSlot, commitment).Result; + + #endregion + + /// + public RequestResult GetHealth() + => GetHealthAsync().Result; + + /// + public async Task> GetHealthAsync() + { + return await SendRequestAsync("getHealth"); + } + + + /// + public RequestResult>> GetLeaderSchedule(ulong slot = 0, + string identity = null, Commitment commitment = Commitment.Finalized) + => GetLeaderScheduleAsync(slot, identity, commitment).Result; + + /// + public async Task>>> GetLeaderScheduleAsync(ulong slot = 0, + string identity = null, Commitment commitment = Commitment.Finalized) + { + return await SendRequestAsync>>("getLeaderSchedule", + Parameters.Create( + slot > 0 ? slot : null, + ConfigObject.Create( + HandleCommitment(commitment), + KeyValue.Create("identity", identity)))); + } + + + /// + public async Task> GetTransactionAsync(string signature, + Commitment commitment = Commitment.Finalized) + { + return await SendRequestAsync("getTransaction", + Parameters.Create(signature, + ConfigObject.Create(KeyValue.Create("encoding", "json"), HandleCommitment(commitment)))); + } + + /// + public async Task> GetConfirmedTransactionAsync(string signature, + Commitment commitment = Commitment.Finalized) + { + return await SendRequestAsync("getConfirmedTransaction", + Parameters.Create(signature, + ConfigObject.Create(KeyValue.Create("encoding", "json"), HandleCommitment(commitment)))); + } + + /// + public RequestResult GetTransaction(string signature, + Commitment commitment = Commitment.Finalized) + => GetTransactionAsync(signature, commitment).Result; + + /// + public RequestResult GetConfirmedTransaction(string signature, + Commitment commitment = Commitment.Finalized) => + GetConfirmedTransactionAsync(signature, commitment).Result; + + /// + public async Task> GetBlockHeightAsync(Commitment commitment = Commitment.Finalized) + { + return await SendRequestAsync("getBlockHeight", + Parameters.Create(ConfigObject.Create(HandleCommitment(commitment)))); + } + + /// + public RequestResult GetBlockHeight(Commitment commitment = Commitment.Finalized) + => GetBlockHeightAsync(commitment).Result; + + /// + public async Task> GetBlockCommitmentAsync(ulong slot) + { + return await SendRequestAsync("getBlockCommitment", Parameters.Create(slot)); + } + + /// + public RequestResult GetBlockCommitment(ulong slot) + => GetBlockCommitmentAsync(slot).Result; + + /// + public async Task> GetBlockTimeAsync(ulong slot) + { + return await SendRequestAsync("getBlockTime", Parameters.Create(slot)); + } + + /// + public RequestResult GetBlockTime(ulong slot) + => GetBlockTimeAsync(slot).Result; + + /// + public async Task>> GetClusterNodesAsync() + { + return await SendRequestAsync>("getClusterNodes"); + } + + /// + public RequestResult> GetClusterNodes() + => GetClusterNodesAsync().Result; + + /// + public async Task> GetEpochInfoAsync(Commitment commitment = Commitment.Finalized) + { + return await SendRequestAsync("getEpochInfo", + Parameters.Create(ConfigObject.Create(HandleCommitment(commitment)))); + } + + /// + public RequestResult GetEpochInfo(Commitment commitment = Commitment.Finalized) => + GetEpochInfoAsync(commitment).Result; + + /// + public async Task> GetEpochScheduleAsync() + { + return await SendRequestAsync("getEpochSchedule"); + } + + /// + public RequestResult GetEpochSchedule() => GetEpochScheduleAsync().Result; + + + /// + public async Task>> GetFeeCalculatorForBlockhashAsync( + string blockhash, Commitment commitment = Commitment.Finalized) + { + List parameters = Parameters.Create(blockhash, ConfigObject.Create(HandleCommitment(commitment))); + + return await SendRequestAsync>("getFeeCalculatorForBlockhash", parameters); + } + + /// + public RequestResult> GetFeeCalculatorForBlockhash(string blockhash, + Commitment commitment = Commitment.Finalized) => + GetFeeCalculatorForBlockhashAsync(blockhash, commitment).Result; + + /// + public async Task>> GetFeeRateGovernorAsync() + { + return await SendRequestAsync>("getFeeRateGovernor"); + } + + /// + public RequestResult> GetFeeRateGovernor() + => GetFeeRateGovernorAsync().Result; + + /// + public async Task>> GetFeesAsync( + Commitment commitment = Commitment.Finalized) + { + return await SendRequestAsync>("getFees", + Parameters.Create(ConfigObject.Create(HandleCommitment(commitment)))); + } + + + /// + public RequestResult> GetFees(Commitment commitment = Commitment.Finalized) + => GetFeesAsync(commitment).Result; + + /// + public async Task>> GetRecentBlockHashAsync( + Commitment commitment = Commitment.Finalized) + { + return await SendRequestAsync>("getRecentBlockhash", + Parameters.Create(ConfigObject.Create(HandleCommitment(commitment)))); + } + + /// + public RequestResult> GetRecentBlockHash(Commitment commitment = Commitment.Finalized) + => GetRecentBlockHashAsync(commitment).Result; + + /// + public async Task> GetMaxRetransmitSlotAsync() + { + return await SendRequestAsync("getMaxRetransmitSlot"); + } + + /// + public RequestResult GetMaxRetransmitSlot() + => GetMaxRetransmitSlotAsync().Result; + + /// + public async Task> GetMaxShredInsertSlotAsync() + { + return await SendRequestAsync("getMaxShredInsertSlot"); + } + + /// + public RequestResult GetMaxShredInsertSlot() + => GetMaxShredInsertSlotAsync().Result; + + /// + public async Task> GetMinimumBalanceForRentExemptionAsync(long accountDataSize, + Commitment commitment = Commitment.Finalized) + { + return await SendRequestAsync("getMinimumBalanceForRentExemption", + Parameters.Create(accountDataSize, ConfigObject.Create(HandleCommitment(commitment)))); + } + + /// + public RequestResult GetMinimumBalanceForRentExemption(long accountDataSize, + Commitment commitment = Commitment.Finalized) + => GetMinimumBalanceForRentExemptionAsync(accountDataSize, commitment).Result; + + /// + public async Task> GetGenesisHashAsync() + { + return await SendRequestAsync("getGenesisHash"); + } + + /// + public RequestResult GetGenesisHash() + => GetGenesisHashAsync().Result; + + /// + public async Task> GetIdentityAsync() + { + return await SendRequestAsync("getIdentity"); + } + + /// + public RequestResult GetIdentity() + => GetIdentityAsync().Result; + + /// + public async Task> GetInflationGovernorAsync( + Commitment commitment = Commitment.Finalized) + { + return await SendRequestAsync("getInflationGovernor", + Parameters.Create(ConfigObject.Create(HandleCommitment(commitment)))); + } + + /// + public RequestResult GetInflationGovernor(Commitment commitment = Commitment.Finalized) + => GetInflationGovernorAsync(commitment).Result; + + /// + public async Task> GetInflationRateAsync() + { + return await SendRequestAsync("getInflationRate"); + } + + /// + public RequestResult GetInflationRate() + => GetInflationRateAsync().Result; + + /// + public async Task>> GetInflationRewardAsync(IList addresses, + ulong epoch = 0, Commitment commitment = Commitment.Finalized) + { + return await SendRequestAsync>("getInflationReward", + Parameters.Create( + addresses, + ConfigObject.Create( + HandleCommitment(commitment), + KeyValue.Create("epoch", epoch > 0 ? epoch : null)))); + } + + /// + public RequestResult> GetInflationReward(IList addresses, ulong epoch = 0, + Commitment commitment = Commitment.Finalized) + => GetInflationRewardAsync(addresses, epoch, commitment).Result; + + /// + public async Task>>> GetLargestAccountsAsync( + AccountFilterType? filter = null, + Commitment commitment = Commitment.Finalized) + { + return await SendRequestAsync>>("getLargestAccounts", + Parameters.Create( + ConfigObject.Create( + HandleCommitment(commitment), + KeyValue.Create("filter", filter)))); + } + + /// + public RequestResult>> GetLargestAccounts(AccountFilterType? filter = null, + Commitment commitment = Commitment.Finalized) + => GetLargestAccountsAsync(filter, commitment).Result; + + /// + public async Task> GetSnapshotSlotAsync() + { + return await SendRequestAsync("getSnapshotSlot"); + } + + /// + public RequestResult GetSnapshotSlot() => GetSnapshotSlotAsync().Result; + + /// + public async Task>> GetRecentPerformanceSamplesAsync(ulong limit = 720) + { + return await SendRequestAsync>("getRecentPerformanceSamples", + new List { limit }); + } + + /// + public RequestResult> GetRecentPerformanceSamples(ulong limit = 720) + => GetRecentPerformanceSamplesAsync(limit).Result; + + /// + public async Task>> GetSignaturesForAddressAsync(string accountPubKey, + ulong limit = 1000, string before = null, string until = null, Commitment commitment = Commitment.Finalized) + { + if (commitment == Commitment.Processed) + throw new ArgumentException("Commitment.Processed is not supported for this method."); + + return await SendRequestAsync>("getSignaturesForAddress", + Parameters.Create( + accountPubKey, + ConfigObject.Create( + KeyValue.Create("limit", limit != 1000 ? limit : null), + KeyValue.Create("before", before), + KeyValue.Create("until", until), + HandleCommitment(commitment)))); + } + + /// + public async Task>> GetConfirmedSignaturesForAddress2Async( + string accountPubKey, ulong limit = 1000, string before = null, string until = null, + Commitment commitment = Commitment.Finalized) + { + if (commitment == Commitment.Processed) + throw new ArgumentException("Commitment.Processed is not supported for this method."); + + return await SendRequestAsync>("getConfirmedSignaturesForAddress2", + Parameters.Create( + accountPubKey, + ConfigObject.Create( + KeyValue.Create("limit", limit != 1000 ? limit : null), + KeyValue.Create("before", before), + KeyValue.Create("until", until), + HandleCommitment(commitment)))); + } + + /// + public RequestResult> GetSignaturesForAddress(string accountPubKey, + ulong limit = 1000, + string before = null, string until = null, Commitment commitment = Commitment.Finalized) + => GetSignaturesForAddressAsync(accountPubKey, limit, before, until, commitment).Result; + + /// + public RequestResult> GetConfirmedSignaturesForAddress2(string accountPubKey, + ulong limit = 1000, string before = null, + string until = null, Commitment commitment = Commitment.Finalized) + => GetConfirmedSignaturesForAddress2Async(accountPubKey, limit, before, until, commitment).Result; + + /// + public async Task>>> GetSignatureStatusesAsync( + List transactionHashes, + bool searchTransactionHistory = false) + { + return await SendRequestAsync>>("getSignatureStatuses", + Parameters.Create( + transactionHashes, + ConfigObject.Create( + KeyValue.Create("searchTransactionHistory", + searchTransactionHistory ? searchTransactionHistory : null)))); + } + + /// + public RequestResult>> GetSignatureStatuses( + List transactionHashes, + bool searchTransactionHistory = false) + => GetSignatureStatusesAsync(transactionHashes, searchTransactionHistory).Result; + + /// + public async Task> GetSlotAsync(Commitment commitment = Commitment.Finalized) + { + return await SendRequestAsync("getSlot", + Parameters.Create(ConfigObject.Create(HandleCommitment(commitment)))); + } + + /// + public RequestResult GetSlot(Commitment commitment = Commitment.Finalized) => + GetSlotAsync(commitment).Result; + + /// + public async Task> GetSlotLeaderAsync(Commitment commitment = Commitment.Finalized) + { + return await SendRequestAsync("getSlotLeader", + Parameters.Create(ConfigObject.Create(HandleCommitment(commitment)))); + } + + /// + public RequestResult GetSlotLeader(Commitment commitment = Commitment.Finalized) => + GetSlotLeaderAsync(commitment).Result; + + /// + public async Task>> GetSlotLeadersAsync(ulong start, ulong limit, + Commitment commitment = Commitment.Finalized) + { + return await SendRequestAsync>("getSlotLeaders", + Parameters.Create(start, limit, ConfigObject.Create(HandleCommitment(commitment)))); + } + + /// + public RequestResult> GetSlotLeaders(ulong start, ulong limit, + Commitment commitment = Commitment.Finalized) + => GetSlotLeadersAsync(start, limit, commitment).Result; + + #region Token Supply and Balances + + /// + public async Task> GetStakeActivationAsync(string publicKey, ulong epoch = 0, + Commitment commitment = Commitment.Finalized) + { + return await SendRequestAsync("getStakeActivation", + Parameters.Create( + publicKey, + ConfigObject.Create( + HandleCommitment(commitment), + KeyValue.Create("epoch", epoch > 0 ? epoch : null)))); + } + + /// + public RequestResult GetStakeActivation(string publicKey, ulong epoch = 0, + Commitment commitment = Commitment.Finalized) => + GetStakeActivationAsync(publicKey, epoch, commitment).Result; + + /// + public async Task>> GetSupplyAsync( + Commitment commitment = Commitment.Finalized) + { + return await SendRequestAsync>("getSupply", + Parameters.Create(ConfigObject.Create(HandleCommitment(commitment)))); + } + + /// + public RequestResult> GetSupply(Commitment commitment = Commitment.Finalized) + => GetSupplyAsync(commitment).Result; + + /// + public async Task>> GetTokenAccountBalanceAsync( + string splTokenAccountPublicKey, Commitment commitment = Commitment.Finalized) + { + return await SendRequestAsync>("getTokenAccountBalance", + Parameters.Create(splTokenAccountPublicKey, ConfigObject.Create(HandleCommitment(commitment)))); + } + + /// + public RequestResult> GetTokenAccountBalance(string splTokenAccountPublicKey, + Commitment commitment = Commitment.Finalized) + => GetTokenAccountBalanceAsync(splTokenAccountPublicKey, commitment).Result; + + /// + public async Task>>> GetTokenAccountsByDelegateAsync( + string ownerPubKey, string tokenMintPubKey = null, string tokenProgramId = null, + Commitment commitment = Commitment.Finalized) + { + if (string.IsNullOrWhiteSpace(tokenMintPubKey) && string.IsNullOrWhiteSpace(tokenProgramId)) + throw new ArgumentException("either tokenProgramId or tokenMintPubKey must be set"); + + return await SendRequestAsync>>("getTokenAccountsByDelegate", + Parameters.Create( + ownerPubKey, + ConfigObject.Create( + KeyValue.Create("mint", tokenMintPubKey), + KeyValue.Create("programId", tokenProgramId)), + ConfigObject.Create( + HandleCommitment(commitment), + KeyValue.Create("encoding", "jsonParsed")))); + } + + /// + public RequestResult>> GetTokenAccountsByDelegate(string ownerPubKey, + string tokenMintPubKey = null, string tokenProgramId = null, Commitment commitment = Commitment.Finalized) + => GetTokenAccountsByDelegateAsync(ownerPubKey, tokenMintPubKey, tokenProgramId, commitment).Result; + + /// + public async Task>>> GetTokenAccountsByOwnerAsync( + string ownerPubKey, string tokenMintPubKey = null, string tokenProgramId = null, + Commitment commitment = Commitment.Finalized) + { + if (string.IsNullOrWhiteSpace(tokenMintPubKey) && string.IsNullOrWhiteSpace(tokenProgramId)) + throw new ArgumentException("either tokenProgramId or tokenMintPubKey must be set"); + + return await SendRequestAsync>>("getTokenAccountsByOwner", + Parameters.Create( + ownerPubKey, + ConfigObject.Create( + KeyValue.Create("mint", tokenMintPubKey), + KeyValue.Create("programId", tokenProgramId)), + ConfigObject.Create( + HandleCommitment(commitment), + KeyValue.Create("encoding", "jsonParsed")))); + } + + /// + public RequestResult>> GetTokenAccountsByOwner( + string ownerPubKey, string tokenMintPubKey = null, string tokenProgramId = null, + Commitment commitment = Commitment.Finalized) + => GetTokenAccountsByOwnerAsync(ownerPubKey, tokenMintPubKey, tokenProgramId, commitment).Result; + + /// + public async Task>>> GetTokenLargestAccountsAsync( + string tokenMintPubKey, Commitment commitment = Commitment.Finalized) + { + return await SendRequestAsync>>("getTokenLargestAccounts", + Parameters.Create(tokenMintPubKey, ConfigObject.Create(HandleCommitment(commitment)))); + } + + /// + public RequestResult>> GetTokenLargestAccounts(string tokenMintPubKey, + Commitment commitment = Commitment.Finalized) + => GetTokenLargestAccountsAsync(tokenMintPubKey, commitment).Result; + + /// + public async Task>> GetTokenSupplyAsync(string tokenMintPubKey, + Commitment commitment = Commitment.Finalized) + { + return await SendRequestAsync>("getTokenSupply", + Parameters.Create(tokenMintPubKey, ConfigObject.Create(HandleCommitment(commitment)))); + } + + /// + public RequestResult> GetTokenSupply(string tokenMintPubKey, + Commitment commitment = Commitment.Finalized) + => GetTokenSupplyAsync(tokenMintPubKey, commitment).Result; + + #endregion + + /// + public async Task> GetTransactionCountAsync(Commitment commitment = Commitment.Finalized) + { + return await SendRequestAsync("getTransactionCount", + Parameters.Create(ConfigObject.Create(HandleCommitment(commitment)))); + } + + /// + public RequestResult GetTransactionCount(Commitment commitment = Commitment.Finalized) + => GetTransactionCountAsync(commitment).Result; + + /// + public async Task> GetVersionAsync() + { + return await SendRequestAsync("getVersion"); + } + + /// + public RequestResult GetVersion() + => GetVersionAsync().Result; + + /// + public async Task> GetVoteAccountsAsync(string votePubKey = null, + Commitment commitment = Commitment.Finalized) + { + return await SendRequestAsync("getVoteAccounts", + Parameters.Create(ConfigObject.Create(HandleCommitment(commitment), + KeyValue.Create("votePubkey", votePubKey)))); + } + + /// + public RequestResult GetVoteAccounts(string votePubKey = null, + Commitment commitment = Commitment.Finalized) + => GetVoteAccountsAsync(votePubKey, commitment).Result; + + /// + public async Task> GetMinimumLedgerSlotAsync() + { + return await SendRequestAsync("minimumLedgerSlot"); + } + + /// + public RequestResult GetMinimumLedgerSlot() + => GetMinimumLedgerSlotAsync().Result; + + /// + public async Task> RequestAirdropAsync(string pubKey, ulong lamports, + Commitment commitment = Commitment.Finalized) + { + return await SendRequestAsync("requestAirdrop", + Parameters.Create(pubKey, lamports, ConfigObject.Create(HandleCommitment(commitment)))); + } + + /// + public RequestResult RequestAirdrop(string pubKey, ulong lamports, + Commitment commitment = Commitment.Finalized) + => RequestAirdropAsync(pubKey, lamports, commitment).Result; + + #region Transactions + + /// + public async Task> SendTransactionAsync(byte[] transaction, bool skipPreflight = false, + Commitment preflightCommitment = Commitment.Finalized) + { + return await SendTransactionAsync(Convert.ToBase64String(transaction), skipPreflight, preflightCommitment) + .ConfigureAwait(false); + } + + + /// + public async Task> SendTransactionAsync(string transaction, bool skipPreflight = false, + Commitment preflightCommitment = Commitment.Finalized) + { + return await SendRequestAsync("sendTransaction", + Parameters.Create( + transaction, + ConfigObject.Create( + KeyValue.Create("skipPreflight", skipPreflight ? skipPreflight : null), + KeyValue.Create("preflightCommitment", + preflightCommitment == Commitment.Finalized ? null : preflightCommitment), + KeyValue.Create("encoding", BinaryEncoding.Base64)))); + } + + /// + public RequestResult SendTransaction(string transaction, bool skipPreFlight = false, + Commitment preFlightCommitment = Commitment.Finalized) + => SendTransactionAsync(transaction, skipPreFlight, preFlightCommitment).Result; + + /// + public RequestResult SendTransaction(byte[] transaction, bool skipPreFlight = false, + Commitment preFlightCommitment = Commitment.Finalized) + => SendTransactionAsync(transaction, skipPreFlight, preFlightCommitment).Result; + + /// + public async Task>> SimulateTransactionAsync(string transaction, + bool sigVerify = false, + Commitment commitment = Commitment.Finalized, bool replaceRecentBlockhash = false, + IList accountsToReturn = null) + { + if (sigVerify && replaceRecentBlockhash) + { + throw new ArgumentException( + $"Parameters {nameof(sigVerify)} and {nameof(replaceRecentBlockhash)} are incompatible, only one can be set to true."); + } + + return await SendRequestAsync>("simulateTransaction", + Parameters.Create( + transaction, + ConfigObject.Create( + KeyValue.Create("sigVerify", sigVerify ? sigVerify : null), + HandleCommitment(commitment), + KeyValue.Create("encoding", BinaryEncoding.Base64), + KeyValue.Create("replaceRecentBlockhash", + replaceRecentBlockhash ? replaceRecentBlockhash : null), + KeyValue.Create("accounts", accountsToReturn != null + ? ConfigObject.Create( + KeyValue.Create("encoding", BinaryEncoding.Base64), + KeyValue.Create("addresses", accountsToReturn)) + : null)))); + } + + /// + public async Task>> SimulateTransactionAsync(byte[] transaction, + bool sigVerify = false, + Commitment commitment = Commitment.Finalized, bool replaceRecentBlockhash = false, + IList accountsToReturn = null) + { + return await SimulateTransactionAsync(Convert.ToBase64String(transaction), sigVerify, commitment, + replaceRecentBlockhash, accountsToReturn) + .ConfigureAwait(false); + } + + /// + public RequestResult> SimulateTransaction(string transaction, + bool sigVerify = false, + Commitment commitment = Commitment.Finalized, bool replaceRecentBlockhash = false, + IList accountsToReturn = null) + => SimulateTransactionAsync(transaction, sigVerify, commitment, replaceRecentBlockhash, accountsToReturn) + .Result; + + /// + public RequestResult> SimulateTransaction(byte[] transaction, + bool sigVerify = false, + Commitment commitment = Commitment.Finalized, bool replaceRecentBlockhash = false, + IList accountsToReturn = null) + => SimulateTransactionAsync(transaction, sigVerify, commitment, replaceRecentBlockhash, accountsToReturn) + .Result; + + #endregion + + /// + /// Gets the id for the next request. + /// + /// The id. + int IRpcClient.GetNextIdForReq() => _idGenerator.GetNextId(); + + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/SolanaRpcClient.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/SolanaRpcClient.cs.meta new file mode 100644 index 0000000..1835b95 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/SolanaRpcClient.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 04f8d3ec6ab2eac48adaab37eaea8326 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/SolanaStreamingRpcClient.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/SolanaStreamingRpcClient.cs new file mode 100644 index 0000000..4f4636b --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/SolanaStreamingRpcClient.cs @@ -0,0 +1,532 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using Newtonsoft.Json.Linq; +using Newtonsoft.Json.Serialization; +using Solana.Unity.Rpc.Converters; +using Solana.Unity.Rpc.Core; +using Solana.Unity.Rpc.Core.Sockets; +using Solana.Unity.Rpc.Messages; +using Solana.Unity.Rpc.Models; +using Solana.Unity.Rpc.Types; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Net.WebSockets; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace Solana.Unity.Rpc +{ + /// + /// Implementation of the Solana streaming RPC API abstraction client. + /// + [DebuggerDisplay("Cluster = {" + nameof(NodeAddress) + "}")] + internal class SolanaStreamingRpcClient : StreamingRpcClient, IStreamingRpcClient + { + /// + /// Message Id generator. + /// + private readonly IdGenerator _idGenerator = new IdGenerator(); + + /// + /// Maps the internal ids to the unconfirmed subscription state objects. + /// + private readonly Dictionary unconfirmedRequests = new Dictionary(); + + /// + /// Maps the server ids to the confirmed subscription state objects. + /// + private readonly Dictionary confirmedSubscriptions = new Dictionary(); + + /// + /// Internal constructor. + /// + /// The url of the server to connect to. + /// The possible ILogger instance. + /// The possible IWebSocket instance. + /// The possible ClientWebSocket instance. + internal SolanaStreamingRpcClient(string url, object logger = null, IWebSocket websocket = default, ClientWebSocket clientWebSocket = default) : base(url, logger, websocket, clientWebSocket) + { + } + + /// + protected override void CleanupSubscriptions() + { + foreach (var sub in confirmedSubscriptions) + { + sub.Value.ChangeState(SubscriptionStatus.Unsubscribed, "Connection terminated"); + } + + foreach (var sub in unconfirmedRequests) + { + sub.Value.ChangeState(SubscriptionStatus.Unsubscribed, "Connection terminated"); + } + unconfirmedRequests.Clear(); + confirmedSubscriptions.Clear(); + } + + + /// + protected override void HandleNewMessage(Memory messagePayload) + { + bool parsedValue; + + var jToken = JToken.Parse(Encoding.UTF8.GetString(messagePayload.Span.ToArray())); + + if (_logger != null) + { + var str = jToken.ToString(); + Console.WriteLine($"[Received]{str}"); + } + + if (jToken["error"] != null) + { + HandleError(jToken); + }else if(jToken["method"] != null && jToken["params"] != null && jToken["params"]["subscription"] != null) + { + var id = Convert.ToInt32(jToken["params"]["subscription"]); + var method = jToken["method"].ToString(); + HandleDataMessage(jToken["params"], method, id); + }else if (jToken["id"] != null && jToken["result"] != null + && Boolean.TryParse(jToken["result"].ToString(), out parsedValue) && parsedValue) + { + RemoveSubscription(Convert.ToInt32(jToken["id"]), true); + } + else if (jToken["id"] != null && jToken["result"] != null ) + { + ConfirmSubscription(Convert.ToInt32(jToken["id"]), Convert.ToInt32(jToken["result"])); + } + } + + /// + /// Handles and finishes parsing the contents of an error message. + /// + /// The jtoken that read the message so far. + private void HandleError(JToken jToken) + { + JsonSerializerSettings opts = new() { MaxDepth = 64, ContractResolver = new CamelCasePropertyNamesContractResolver() }; + var err = jToken["error"].ToObject(JsonSerializer.Create(opts)); + + var id = Convert.ToInt32(jToken["id"]); + + var sub = RemoveUnconfirmedSubscription(id); + + sub?.ChangeState(SubscriptionStatus.ErrorSubscribing, err.Message, err.Code.ToString()); + } + + + #region SubscriptionMapHandling + /// + /// Removes an unconfirmed subscription. + /// + /// The subscription id. + /// Returns the subscription object if it was found. + private SubscriptionState RemoveUnconfirmedSubscription(int id) + { + SubscriptionState sub; + lock (this) + { + unconfirmedRequests.TryGetValue(id, out sub); + if (!unconfirmedRequests.Remove(id)) + { + if (_logger != null) + { + Console.WriteLine($"No unconfirmed subscription found with ID:{id}"); + } + } + } + return sub; + } + + /// + /// Removes a given subscription object from the map and notifies the object of the unsubscription. + /// + /// The subscription id. + /// Whether or not to notify that the subscription was removed. + private void RemoveSubscription(int id, bool shouldNotify) + { + SubscriptionState sub; + lock (this) + { + confirmedSubscriptions.TryGetValue(id, out sub); + if (!confirmedSubscriptions.Remove(id)) + { + if (_logger != null) + { + Console.WriteLine($"No subscription found with ID:{id}"); + } + } + } + if (shouldNotify) + { + sub?.ChangeState(SubscriptionStatus.Unsubscribed); + } + } + + /// + /// Confirms a given subcription based on the internal subscription id and the newly received external id. + /// Moves the subcription state object from the unconfirmed map to the confirmed map. + /// + /// + /// + private void ConfirmSubscription(int internalId, int resultId) + { + SubscriptionState sub; + lock (this) + { + unconfirmedRequests.TryGetValue(internalId, out sub); + if (unconfirmedRequests.Remove(internalId)) + { + sub.SubscriptionId = resultId; + confirmedSubscriptions.Add(resultId, sub); + } + } + + sub?.ChangeState(SubscriptionStatus.Subscribed); + } + + /// + /// Adds a new subscription state object into the unconfirmed subscriptions map. + /// + /// The subcription to add. + /// The internally generated id of the subscription. + private void AddSubscription(SubscriptionState subscription, int internalId) + { + lock (this) + { + unconfirmedRequests.Add(internalId, subscription); + } + } + + /// + /// Safely retrieves a subscription state object from a given subscription id. + /// + /// The subscription id. + /// The subscription state object. + private SubscriptionState RetrieveSubscription(int subscriptionId) + { + lock (this) + { + return confirmedSubscriptions[subscriptionId]; + } + } + #endregion + /// + /// Handles a notification message and finishes parsing the contents. + /// + /// The current JToken being used to parse the message. + /// The method parameter already parsed within the message. + /// The subscriptionId for this message. + private void HandleDataMessage(JToken jToken, string method, int subscriptionId) + { + JsonSerializerSettings opts = new() { MaxDepth = 64, ContractResolver = new CamelCasePropertyNamesContractResolver() }; + + var sub = RetrieveSubscription(subscriptionId); + + object result = null; + + switch (method) + { + case "accountNotification": + { + if (sub.Channel == SubscriptionChannel.TokenAccount) + { + var tokenAccNotification = jToken.ToObject>>(JsonSerializer.Create(opts)); + result = tokenAccNotification.Result; + } + else + { + var accNotification = jToken.ToObject>>(JsonSerializer.Create(opts)); + result = accNotification.Result; + } + break; + } + case "logsNotification": + var logsNotification = jToken.ToObject>>(JsonSerializer.Create(opts)); + result = logsNotification.Result; + break; + case "programNotification": + var programNotification = jToken.ToObject>>(JsonSerializer.Create(opts)); + result = programNotification.Result; + break; + case "signatureNotification": + var signatureNotification = jToken.ToObject>>(JsonSerializer.Create(opts)); + result = signatureNotification.Result; + RemoveSubscription(signatureNotification.Subscription, true); + break; + case "slotNotification": + var slotNotification = jToken.ToObject>(JsonSerializer.Create(opts)); + result = slotNotification.Result; + break; + case "rootNotification": + var rootNotification = jToken.ToObject>(JsonSerializer.Create(opts)); + result = rootNotification.Result; + break; + } + + sub.HandleData(result); + } + + #region AccountInfo + /// + public async Task SubscribeAccountInfoAsync(string pubkey, Action> callback, Commitment commitment = Commitment.Finalized) + + { + var parameters = new List { pubkey }; + var configParams = new Dictionary { { "encoding", "base64" } }; + + if (commitment != Commitment.Finalized) + { + configParams.Add("commitment", commitment); + } + + parameters.Add(configParams); + + var sub = new SubscriptionState>(this, SubscriptionChannel.Account, callback, parameters); + + var msg = new JsonRpcRequest(_idGenerator.GetNextId(), "accountSubscribe", parameters); + + return await Subscribe(sub, msg).ConfigureAwait(false); + } + + /// + public SubscriptionState SubscribeAccountInfo(string pubkey, Action> callback, Commitment commitment = Commitment.Finalized) + => SubscribeAccountInfoAsync(pubkey, callback, commitment).Result; + #endregion + + #region TokenAccount + /// + public async Task SubscribeTokenAccountAsync(string pubkey, Action> callback, Commitment commitment = Commitment.Finalized) + + { + var parameters = new List { pubkey }; + var configParams = new Dictionary { { "encoding", "jsonParsed" } }; + + if (commitment != Commitment.Finalized) + { + configParams.Add("commitment", commitment); + } + + parameters.Add(configParams); + + var sub = new SubscriptionState>(this, SubscriptionChannel.TokenAccount, callback, parameters); + + var msg = new JsonRpcRequest(_idGenerator.GetNextId(), "accountSubscribe", parameters); + + return await Subscribe(sub, msg).ConfigureAwait(false); + } + + /// + public SubscriptionState SubscribeTokenAccount(string pubkey, Action> callback, Commitment commitment = Commitment.Finalized) + => SubscribeTokenAccountAsync(pubkey, callback, commitment).Result; + #endregion + + #region Logs + /// + public async Task SubscribeLogInfoAsync(string pubkey, Action> callback, Commitment commitment = Commitment.Finalized) + { + var parameters = new List { new Dictionary { { "mentions", new List { pubkey } } } }; + + if (commitment != Commitment.Finalized) + { + var configParams = new Dictionary { { "commitment", commitment } }; + parameters.Add(configParams); + } + + var sub = new SubscriptionState>(this, SubscriptionChannel.Logs, callback, parameters); + + var msg = new JsonRpcRequest(_idGenerator.GetNextId(), "logsSubscribe", parameters); + return await Subscribe(sub, msg).ConfigureAwait(false); + } + + /// + public SubscriptionState SubscribeLogInfo(string pubkey, Action> callback, Commitment commitment = Commitment.Finalized) + => SubscribeLogInfoAsync(pubkey, callback, commitment).Result; + + /// + public async Task SubscribeLogInfoAsync(LogsSubscriptionType subscriptionType, Action> callback, Commitment commitment = Commitment.Finalized) + { + var parameters = new List { subscriptionType }; + + if (commitment != Commitment.Finalized) + { + var configParams = new Dictionary { { "commitment", commitment } }; + parameters.Add(configParams); + } + + var sub = new SubscriptionState>(this, SubscriptionChannel.Logs, callback, parameters); + + var msg = new JsonRpcRequest(_idGenerator.GetNextId(), "logsSubscribe", parameters); + return await Subscribe(sub, msg).ConfigureAwait(false); + } + + /// + public SubscriptionState SubscribeLogInfo(LogsSubscriptionType subscriptionType, Action> callback, Commitment commitment = Commitment.Finalized) + => SubscribeLogInfoAsync(subscriptionType, callback, commitment).Result; + #endregion + + #region Signature + /// + public async Task SubscribeSignatureAsync(string transactionSignature, Action> callback, Commitment commitment = Commitment.Finalized) + { + var parameters = new List { transactionSignature }; + + if (commitment != Commitment.Finalized) + { + var configParams = new Dictionary { { "commitment", commitment } }; + parameters.Add(configParams); + } + + var sub = new SubscriptionState>(this, SubscriptionChannel.Signature, callback, parameters); + + var msg = new JsonRpcRequest(_idGenerator.GetNextId(), "signatureSubscribe", parameters); + return await Subscribe(sub, msg).ConfigureAwait(false); + } + + /// + public SubscriptionState SubscribeSignature(string transactionSignature, Action> callback, Commitment commitment = Commitment.Finalized) + => SubscribeSignatureAsync(transactionSignature, callback, commitment).Result; + #endregion + + #region Program + /// + public async Task SubscribeProgramAsync(string programPubkey, Action> callback, Commitment commitment = Commitment.Finalized) + { + var parameters = new List { programPubkey }; + var configParams = new Dictionary { { "encoding", "base64" } }; + + if (commitment != Commitment.Finalized) + { + configParams.Add("commitment", commitment); + } + + parameters.Add(configParams); + + var sub = new SubscriptionState>(this, SubscriptionChannel.Program, callback, parameters); + + var msg = new JsonRpcRequest(_idGenerator.GetNextId(), "programSubscribe", parameters); + return await Subscribe(sub, msg).ConfigureAwait(false); + } + + /// + public SubscriptionState SubscribeProgram(string programPubkey, Action> callback, Commitment commitment = Commitment.Finalized) + => SubscribeProgramAsync(programPubkey, callback, commitment).Result; + #endregion + + #region SlotInfo + /// + public async Task SubscribeSlotInfoAsync(Action callback) + { + var sub = new SubscriptionState(this, SubscriptionChannel.Slot, callback); + + var msg = new JsonRpcRequest(_idGenerator.GetNextId(), "slotSubscribe", null); + return await Subscribe(sub, msg).ConfigureAwait(false); + } + + /// + public SubscriptionState SubscribeSlotInfo(Action callback) + => SubscribeSlotInfoAsync(callback).Result; + #endregion + + #region Root + /// + public async Task SubscribeRootAsync(Action callback) + { + var sub = new SubscriptionState(this, SubscriptionChannel.Root, callback); + + var msg = new JsonRpcRequest(_idGenerator.GetNextId(), "rootSubscribe", null); + return await Subscribe(sub, msg).ConfigureAwait(false); + } + + /// + public SubscriptionState SubscribeRoot(Action callback) + => SubscribeRootAsync(callback).Result; + #endregion + + /// + /// Internal subscribe function, finishes the serialization and sends the message payload. + /// + /// The subscription state object. + /// The message to be serialized and sent. + /// A task representing the state of the asynchronous operation- + private async Task Subscribe(SubscriptionState sub, JsonRpcRequest msg) + { + + var opts = new JsonSerializerSettings() + { + Formatting = Formatting.None, + ContractResolver = new CamelCasePropertyNamesContractResolver(), + Converters = + { + new EncodingConverter(), + new StringEnumConverter(new CamelCaseNamingStrategy()) + } + }; + var json = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(msg, opts)); + + if (_logger != null) + { + var jsonString = Encoding.UTF8.GetString(json); + Console.WriteLine($"{msg.Id} {msg.Method} [Sending]{jsonString}"); + } + + ReadOnlyMemory mem = new ReadOnlyMemory(json); + + try + { + await ClientSocket.SendAsync(mem, WebSocketMessageType.Text, true, CancellationToken.None).ConfigureAwait(false); + AddSubscription(sub, msg.Id); + } + catch (Exception e) + { + sub.ChangeState(SubscriptionStatus.ErrorSubscribing, e.Message); + if (_logger != null) + { + Console.WriteLine($"{msg.Id} {msg.Method} Unable to send message"); + } + + } + + return sub; + } + + private string GetUnsubscribeMethodName(SubscriptionChannel channel) => channel switch + { + SubscriptionChannel.Account => "accountUnsubscribe", + SubscriptionChannel.Logs => "logsUnsubscribe", + SubscriptionChannel.Program => "programUnsubscribe", + SubscriptionChannel.Root => "rootUnsubscribe", + SubscriptionChannel.Signature => "signatureUnsubscribe", + SubscriptionChannel.Slot => "slotUnsubscribe", + _ => throw new ArgumentOutOfRangeException(nameof(channel), channel, "invalid message type") + }; + + /// + public async Task UnsubscribeAsync(SubscriptionState subscription) + { + var msg = new JsonRpcRequest(_idGenerator.GetNextId(), GetUnsubscribeMethodName(subscription.Channel), new List { subscription.SubscriptionId }); + + await Subscribe(subscription, msg).ConfigureAwait(false); + } + + /// + public void Unsubscribe(SubscriptionState subscription) => UnsubscribeAsync(subscription).Wait(); + + /// + /// Clones a object via shallow copy + /// + /// Object Type to Clone + /// Object to Clone + /// New Object reference + public static T CloneObject(T obj) where T : class + { + if (obj == null) return null; + System.Reflection.MethodInfo inst = obj.GetType().GetMethod("MemberwiseClone", + System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); + if (inst != null) + return (T)inst.Invoke(obj, null); + return null; + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/SolanaStreamingRpcClient.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/SolanaStreamingRpcClient.cs.meta new file mode 100644 index 0000000..d57ba4d --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/SolanaStreamingRpcClient.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 075a491fa57822d438af6e817f83589d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types.meta new file mode 100644 index 0000000..73bff44 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 3979235c26fe34c4fa8e2ccc173980f4 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/AccountFilterType.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/AccountFilterType.cs new file mode 100644 index 0000000..8fcccd7 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/AccountFilterType.cs @@ -0,0 +1,17 @@ +namespace Solana.Unity.Rpc.Types +{ + /// + /// Represents the filter account type. + /// + public enum AccountFilterType + { + /// + /// Circulating accounts. + /// + Circulating, + /// + /// Non circulating accounts. + /// + NonCirculating + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/AccountFilterType.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/AccountFilterType.cs.meta new file mode 100644 index 0000000..41ee514 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/AccountFilterType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 03f87e5a58f630b4c87812bd9da9256a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/BatchAutoExecuteMode.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/BatchAutoExecuteMode.cs new file mode 100644 index 0000000..d09bdfb --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/BatchAutoExecuteMode.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Solana.Unity.Rpc.Types +{ + /// + /// Represents the different auto execute modes for an `SolanaRpcBatchComposer` + /// + public enum BatchAutoExecuteMode + { + /// + /// No auto execution. + /// + Manual = 0, + + /// + /// Execute with RPC batch failure throwing an Exception. + /// + ExecuteWithFatalFailure = 1, + + /// + /// Execute with RPC batch failures execptions routed into callbacks. + /// + ExecuteWithCallbackFailures = 2 + } +} diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/BatchAutoExecuteMode.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/BatchAutoExecuteMode.cs.meta new file mode 100644 index 0000000..8fb6ae9 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/BatchAutoExecuteMode.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8e1078bbf1f8d6e449b8a666c37ab438 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/BatchRequestException.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/BatchRequestException.cs new file mode 100644 index 0000000..a5657e4 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/BatchRequestException.cs @@ -0,0 +1,31 @@ +using Solana.Unity.Rpc.Core.Http; +using Solana.Unity.Rpc.Messages; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Solana.Unity.Rpc.Types +{ + /// + /// Encapsulates the batch request failure that is relayed to all callbacks + /// + public class BatchRequestException : ApplicationException + { + /// + /// The RPC result that failed + /// + public RequestResult RpcResult; + + /// + /// Contructs a BatchRequestException based on the JsonRpcBatchResponse result. + /// + /// + public BatchRequestException(RequestResult result) : base($"Batch request failure - {result.Reason}") + { + RpcResult = result; + } + + } +} diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/BatchRequestException.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/BatchRequestException.cs.meta new file mode 100644 index 0000000..e16dac2 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/BatchRequestException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 54593f3b706438746a50b132e0eca463 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/BinaryEncoding.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/BinaryEncoding.cs new file mode 100644 index 0000000..9f00565 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/BinaryEncoding.cs @@ -0,0 +1,21 @@ +namespace Solana.Unity.Rpc.Types +{ + /// + /// The encodings used for binary data to interact with the Solana nodes. + /// + public enum BinaryEncoding + { + /// + /// Request json parsed data, when a parser is available. + /// + JsonParsed, + /// + /// Base64 encoding. + /// + Base64, + /// + /// Base64+Zstd encoding. + /// + Base64Zstd + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/BinaryEncoding.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/BinaryEncoding.cs.meta new file mode 100644 index 0000000..bc25adc --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/BinaryEncoding.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ba4e83b044118144390212c9c61c02de +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/Commitment.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/Commitment.cs new file mode 100644 index 0000000..12ec617 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/Commitment.cs @@ -0,0 +1,22 @@ +namespace Solana.Unity.Rpc.Types +{ + /// + /// The commitment describes how finalized a block is at that point in time. + /// + public enum Commitment + { + /// + /// The node will query the most recent block confirmed by supermajority of the cluster as having reached maximum lockout, meaning the cluster has recognized this block as finalized. + /// + Finalized, + /// + /// The node will query the most recent block that has been voted on by supermajority of the cluster. + /// + Confirmed, + + /// + /// The node will query its most recent block. Note that the block may not be complete. + /// + Processed + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/Commitment.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/Commitment.cs.meta new file mode 100644 index 0000000..cf8d7ac --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/Commitment.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4da335683a502de4b8d632b2af14b031 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/ConnectionStats.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/ConnectionStats.cs new file mode 100644 index 0000000..4672b7f --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/ConnectionStats.cs @@ -0,0 +1,106 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Timers; + +namespace Solana.Unity.Rpc.Types +{ + internal class ConnectionStats : IConnectionStatistics + { + private Timer _timer; + + private Dictionary _historicData; + + private ulong _totalReceived; + + public ulong TotalReceivedBytes + { + get { return _totalReceived; } + set { _totalReceived = value; } + } + + private ulong _averageReceived10s; + + public ulong AverageThroughput10Seconds + { + get { return _averageReceived10s; } + set { _averageReceived10s = value; } + } + + private ulong _averageReceived60s; + + public ulong AverageThroughput60Seconds + { + get { return _averageReceived60s; } + set { _averageReceived60s = value; } + } + + + internal void AddReceived(uint count) + { + TotalReceivedBytes += count; + var secs = (long)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds; + + lock (this) + { + if (!_timer.Enabled) + _timer.Start(); + + if (_historicData.TryGetValue(secs, out var current)) + { + _historicData[secs] = current + count; + } + else + { + _historicData[secs] = count; + } + + AverageThroughput60Seconds += count / 60; + AverageThroughput10Seconds += count / 10; + } + } + + internal ConnectionStats() + { + _timer = new Timer(1000); + _timer.AutoReset = true; + _timer.Elapsed += RemoveOutdatedData; + _historicData = new Dictionary(); + } + + private void RemoveOutdatedData(object sender, ElapsedEventArgs e) + { + var currentSec = (long)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds; + + lock (this) + { + if (_historicData.ContainsKey(currentSec - 60)) + { + _historicData.Remove(currentSec - 60); + } + if (_historicData.Count == 0) + { + _timer.Stop(); + AverageThroughput60Seconds = 0; + AverageThroughput10Seconds = 0; + } + else + { + ulong total = 0, tenSecTotal = 0; + foreach (var kvp in _historicData) + { + total += kvp.Value; + if (kvp.Key > currentSec - 10) + { + tenSecTotal += kvp.Value; + } + } + AverageThroughput60Seconds = total / 60; + AverageThroughput10Seconds = tenSecTotal / 10; + } + } + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/ConnectionStats.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/ConnectionStats.cs.meta new file mode 100644 index 0000000..634052f --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/ConnectionStats.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cae9f9eedff64904393087698b421fa5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/IConnectionStatistics.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/IConnectionStatistics.cs new file mode 100644 index 0000000..4c4e755 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/IConnectionStatistics.cs @@ -0,0 +1,23 @@ +namespace Solana.Unity.Rpc.Types +{ + /// + /// Contains several statistics regarding connection speed and dat usage. + /// + public interface IConnectionStatistics + { + /// + /// Average throughput in the last 10s. Measured in bytes/s. + /// + ulong AverageThroughput10Seconds { get; set; } + + /// + /// Average throughput in the last minute. Measured in bytes/s. + /// + ulong AverageThroughput60Seconds { get; set; } + + /// + /// Total bytes downloaded. + /// + ulong TotalReceivedBytes { get; set; } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/IConnectionStatistics.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/IConnectionStatistics.cs.meta new file mode 100644 index 0000000..694d04f --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/IConnectionStatistics.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e38d6ea7fd389004fb70b43f4cbcdd44 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/LogsSubscriptionType.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/LogsSubscriptionType.cs new file mode 100644 index 0000000..804842d --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/LogsSubscriptionType.cs @@ -0,0 +1,18 @@ +namespace Solana.Unity.Rpc.Types +{ + /// + /// Enum with the possible vote selection parameter for the log subscription method. + /// + public enum LogsSubscriptionType + { + /// + /// Subscribes to All logs. + /// + All, + + /// + /// Subscribes to All logs including votes. + /// + AllWithVotes + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/LogsSubscriptionType.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/LogsSubscriptionType.cs.meta new file mode 100644 index 0000000..c8b98cb --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/LogsSubscriptionType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e1681388d8255ad44aa03f3be3bb7ba2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/TransactionDetails.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/TransactionDetails.cs new file mode 100644 index 0000000..a1314b7 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/TransactionDetails.cs @@ -0,0 +1,21 @@ +namespace Solana.Unity.Rpc.Types +{ + /// + /// Used to specify which block data to retrieve. + /// + public enum TransactionDetails + { + /// + /// Retrieve the full block data. + /// + Full, + /// + /// Retrieve only signatures, leaving out detailed transaction data. + /// + Signatures, + /// + /// Retrieve only basic block data. + /// + None + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/TransactionDetails.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/TransactionDetails.cs.meta new file mode 100644 index 0000000..a062d9b --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/TransactionDetails.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9bc62760a4b62564c8313dc14517d988 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/TransactionDetailsFilterType.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/TransactionDetailsFilterType.cs new file mode 100644 index 0000000..bb7cf48 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/TransactionDetailsFilterType.cs @@ -0,0 +1,23 @@ +namespace Solana.Unity.Rpc.Types +{ + /// + /// Represents the filter type for block data. + /// + public enum TransactionDetailsFilterType + { + /// + /// Returns no transaction details. + /// + None, + + /// + /// Returns only transaction signatures. + /// + Signatures, + + /// + /// Returns full transaction details. + /// + Full + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/TransactionDetailsFilterType.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/TransactionDetailsFilterType.cs.meta new file mode 100644 index 0000000..f04ce21 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Types/TransactionDetailsFilterType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 62162a5df81ec6a488e3b4f660994ee5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Utilities.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Utilities.meta new file mode 100644 index 0000000..b780e8f --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Utilities.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 6ace4e1cb8ff11a459d9462c46de188a +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Utilities/IRateLimiter.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Utilities/IRateLimiter.cs new file mode 100644 index 0000000..92d1ccd --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Utilities/IRateLimiter.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Solana.Unity.Rpc.Utilities +{ + /// + /// Provides rate limiting behaviour for RPC interactions. + /// + public interface IRateLimiter + { + + /// + /// Fire or block until we can fire. + /// + void Fire(); + + /// + /// Would a fire method succeed? + /// + /// + bool CanFire(); + + } +} diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Utilities/IRateLimiter.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Utilities/IRateLimiter.cs.meta new file mode 100644 index 0000000..6ea7431 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Utilities/IRateLimiter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4496db53c4b219f4e97839a553d5ae9b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Utilities/RateLimiter.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Utilities/RateLimiter.cs new file mode 100644 index 0000000..6a6ab6a --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Utilities/RateLimiter.cs @@ -0,0 +1,148 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace Solana.Unity.Rpc.Utilities +{ + /// + /// A primitive blocking sliding time window rate limiter. Not thread-safe. + /// + public class RateLimiter : IRateLimiter + { + private int _hits; + private int _duration_ms; + private Queue _hit_list; + + /// + /// Create a simple rate-limit tracking instance. + /// This allows a number of hits within a window of duration_ms. + /// + /// Number of allowed hits + /// Duration of timespan in miliseconds + public RateLimiter(int hits, int duration_ms) + { + _hits = hits; + _duration_ms = duration_ms; + _hit_list = new Queue(); + } + + /// + /// Create a simple rate-limit tracking instance. + /// Configure using `PerSeconds` and `AllowHits` + /// + public static RateLimiter Create() + { + return new RateLimiter(1, 0); + } + + /// + /// Would a fire request be allowed without delay? + /// + /// + public bool CanFire() + { + var checkTime = DateTime.UtcNow; + var resumeTime = NextFireAllowed(checkTime); + return checkTime >= resumeTime; + } + + /// + /// Pre-fire check - this will block if fire rates exceed defined limits until valid. + /// + public void Fire() + { + + var checkTime = DateTime.UtcNow; + var resumeTime = NextFireAllowed(checkTime); + var snoozeMs = resumeTime.Subtract(checkTime).TotalMilliseconds; + while (DateTime.UtcNow <= resumeTime) + Thread.Sleep(50); + + // record this trigger + if (_duration_ms > 0) + _hit_list.Enqueue(DateTime.UtcNow); + + } + + /// + /// When is a next fire allowed? + /// + /// + /// + private DateTime NextFireAllowed(DateTime checkTime) + { + DateTime resumeTime = checkTime; + + // sliding window not set, allow everything through immediately + if (_duration_ms == 0) return resumeTime; + + // empty queue + if (_hit_list.Count == 0) return resumeTime; + + // drop any hits before the time window + var cutOff = checkTime.AddMilliseconds(-_duration_ms); + while (_hit_list.Count > 0 && _hit_list.Peek().Subtract(cutOff).TotalMilliseconds < 0) + _hit_list.Dequeue(); + + // are we left with more than we are allowed? + // do we need to waste some time? + if (_hit_list.Count >= _hits) + { + var oldestHit = _hit_list.Peek(); + return oldestHit.AddMilliseconds(_duration_ms); + } + else + return checkTime; + } + + /// + /// Modify a rate limit + /// + /// Number of seconds + /// + public RateLimiter PerSeconds(int seconds) + { + this._duration_ms = seconds * 1000; + return this; + } + + /// + /// Modify a rate limit + /// + /// Number of milliseconds + /// + public RateLimiter PerMs(int ms) + { + this._duration_ms = ms; + return this; + } + + /// + /// Create a new RateLimiter instance setting the number of hits. + /// + /// Number of hits allowed per sliding time window. + /// An instance of the rate limiter with a sliding time window. + public RateLimiter AllowHits(int hits) + { + this._hits = hits; + return this; + } + + /// + /// Show info about this rate limiter + /// + /// + public override string ToString() + { + if (_hit_list.Count>0) + return $"{_hit_list.Count}-{_hit_list.Peek().ToString("HH:mm:ss.fff")}"; + else + return $"(empty)"; + } + + } + +} diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Utilities/RateLimiter.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Utilities/RateLimiter.cs.meta new file mode 100644 index 0000000..03ef194 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Utilities/RateLimiter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b7ae642817174824c947345ea2b9d90b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Utilities/ShortVectorEncoding.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Utilities/ShortVectorEncoding.cs new file mode 100644 index 0000000..7f84a2a --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Utilities/ShortVectorEncoding.cs @@ -0,0 +1,75 @@ +using Solana.Unity.Rpc.Models; +using System; + +namespace Solana.Unity.Rpc.Utilities +{ + /// + /// Implements the short vector encoding used in Solana transaction s. + /// + internal static class ShortVectorEncoding + { + /// + /// The length of the compact-u16 multi-byte encoding. + /// + internal const int SpanLength = 3; + + /// + /// Encodes the number of account keys present in the transaction as a short vector, see remarks. + /// + /// See the documentation for more information on this encoding: + /// https://docs.solana.com/developing/programming-model/transactions#compact-array-format + /// + /// + /// The number of account keys present in the transaction. + /// The short vector encoded data. + internal static byte[] EncodeLength(int len) + { + byte[] output = new byte[10]; + int remLen = len; + int cursor = 0; + + for (; ; ) + { + int elem = remLen & 0x7f; + remLen >>= 7; + if (remLen == 0) + { + output[cursor] = (byte)elem; + break; + } + elem |= 0x80; + output[cursor] = (byte)elem; + cursor += 1; + } + + byte[] bytes = new byte[cursor + 1]; + Array.Copy(output, 0, bytes, 0, cursor + 1); + + return bytes; + } + + /// + /// Decodes the number of account keys present in the transaction following a specific format. + /// + /// See the documentation for more information on this encoding: + /// https://docs.solana.com/developing/programming-model/transactions#compact-array-format + /// + /// + /// The short vector encoded data. + /// The number of account keys present in the transaction. + internal static (int Value, int Length) DecodeLength(ReadOnlySpan data) + { + int len = 0; + int size = 0; + + foreach (byte elem in data) + { + len |= (elem & 0x7f) << (size * 7); + size += 1; + + if ((elem & 0x80) == 0) break; + } + return (len, size); + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Utilities/ShortVectorEncoding.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Utilities/ShortVectorEncoding.cs.meta new file mode 100644 index 0000000..c912589 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Rpc/Utilities/ShortVectorEncoding.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e56b64f0fb3b31746b0b2e173f270c8a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet.meta new file mode 100644 index 0000000..aa399ec --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4ed6760c31f4a7e4588b4dbc9d59c82f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Account.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Account.cs new file mode 100644 index 0000000..96c4301 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Account.cs @@ -0,0 +1,108 @@ +using Chaos.NaCl; +using Solana.Unity.Wallet.Utilities; +using System.Diagnostics; + +namespace Solana.Unity.Wallet +{ + /// + /// Implements account functionality. + /// + [DebuggerDisplay("PubKey = {ToString()}")] + public class Account + { + /// + /// The private key. + /// + public PrivateKey PrivateKey { get; } + + /// + /// The public key. + /// + public PublicKey PublicKey { get; } + + /// + /// Initialize an account. Generating a random seed for the Ed25519 key pair. + /// + public Account() + { + byte[] seed = GenerateRandomSeed(); + + (byte[] privateKey, byte[] publicKey) = Utils.EdKeyPairFromSeed(seed); + + PrivateKey = new PrivateKey(privateKey); + PublicKey = new PublicKey(publicKey); + } + + /// + /// Initialize an account with the passed private and public keys. + /// + /// The private key. + /// The public key. + public Account(string privateKey, string publicKey) + { + PrivateKey = new PrivateKey(privateKey); + PublicKey = new PublicKey(publicKey); + } + + /// + public Account(byte[] privateKey, byte[] publicKey) + { + PrivateKey = new PrivateKey(privateKey); + PublicKey = new PublicKey(publicKey); + } + + /// + /// Verify the signed message. + /// + /// The signed message. + /// The signature of the message. + /// + public bool Verify(byte[] message, byte[] signature) => PublicKey.Verify(message, signature); + + /// + /// Sign the data. + /// + /// The data to sign. + /// The signature of the data. + public byte[] Sign(byte[] message) => PrivateKey.Sign(message); + + /// + /// Generates a random seed for the Ed25519 key pair. + /// + /// The seed as byte array. + private static byte[] GenerateRandomSeed() + { + byte[] bytes = new byte[Ed25519.PrivateKeySeedSizeInBytes]; + RandomUtils.GetBytes(bytes); + return bytes; + } + + /// + public override bool Equals(object obj) + { + if (obj is Account account) return account.PublicKey == this.PublicKey; + + return false; + } + + /// + /// Conversion between a object and the corresponding private key. + /// + /// The Account object. + /// The private key. + public static implicit operator PrivateKey(Account account) => account.PrivateKey; + + /// + /// Conversion between a object and the corresponding public key. + /// + /// The Account object. + /// The public key as a byte array. + public static implicit operator PublicKey(Account account) => account.PublicKey; + + /// + public override string ToString() => PublicKey; + + /// + public override int GetHashCode() => PublicKey.GetHashCode(); + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Account.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Account.cs.meta new file mode 100644 index 0000000..7f877cb --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Account.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6a183ba6e4c35094685c0cf0a8b3607f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Bip39.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Bip39.meta new file mode 100644 index 0000000..878a989 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Bip39.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a02d9827f824e5b4aadc67704d530be6 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Bip39/HardcodedWordListSource.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Bip39/HardcodedWordListSource.cs new file mode 100644 index 0000000..2793af2 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Bip39/HardcodedWordListSource.cs @@ -0,0 +1,81 @@ +using Solana.Unity.Wallet.Utilities; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Solana.Unity.Wallet.Bip39 +{ + /// + /// Implements a hardcoded word list source. + /// + internal class HardcodedWordlistSource : IWordlistSource + { + /// + /// The word lists. + /// + private static readonly Dictionary WordLists; + + /// + /// Initialize the static instance of the hardcoded word list source. + /// + static HardcodedWordlistSource() + { + Dictionary dict = new() + { + { + "chinese_simplified", + "çš„\n一\n是\n在\nä¸\n了\n有\nå’Œ\n人\nè¿™\n中\n大\n为\n上\n个\n国\n我\n以\nè¦\nä»–\næ—¶\næ¥\n用\n们\n生\n到\n作\n地\n于\n出\nå°±\n分\n对\næˆ\n会\nå¯\n主\nå‘\nå¹´\n动\nåŒ\nå·¥\n也\n能\n下\n过\nå­\n说\n产\nç§\né¢\n而\næ–¹\nåŽ\n多\n定\n行\nå­¦\n法\n所\næ°‘\nå¾—\nç»\nå\n三\n之\nè¿›\nç€\nç­‰\n部\n度\nå®¶\n电\n力\n里\n如\næ°´\n化\n高\n自\n二\nç†\nèµ·\nå°\n物\n现\n实\n加\né‡\n都\n两\n体\n制\n机\n当\n使\n点\n从\n业\n本\n去\n把\n性\n好\n应\nå¼€\n它\nåˆ\n还\nå› \nç”±\nå…¶\n些\nç„¶\nå‰\n外\n天\n政\nå››\næ—¥\né‚£\n社\n义\n事\nå¹³\nå½¢\n相\nå…¨\n表\né—´\næ ·\n与\nå…³\nå„\né‡\næ–°\n线\n内\næ•°\næ­£\n心\nå\nä½ \n明\n看\n原\nåˆ\n么\n利\n比\n或\n但\nè´¨\næ°”\n第\nå‘\né“\n命\næ­¤\nå˜\næ¡\nåª\n没\n结\nè§£\né—®\næ„\n建\n月\nå…¬\næ— \nç³»\n军\n很\n情\n者\n最\nç«‹\n代\n想\nå·²\n通\nå¹¶\næ\nç›´\n题\nå…š\n程\n展\n五\næžœ\næ–™\n象\n员\né©\nä½\nå…¥\n常\næ–‡\n总\n次\nå“\nå¼\næ´»\n设\nåŠ\n管\n特\nä»¶\né•¿\n求\nè€\n头\n基\n资\nè¾¹\næµ\nè·¯\n级\nå°‘\n图\nå±±\n统\n接\n知\n较\nå°†\n组\nè§\n计\n别\n她\n手\nè§’\n期\næ ¹\n论\nè¿\n农\n指\n几\nä¹\n区\n强\n放\n决\n西\n被\nå¹²\nåš\nå¿…\n战\nå…ˆ\n回\n则\nä»»\nå–\næ®\n处\n队\nå—\nç»™\n色\nå…‰\né—¨\nå³\nä¿\næ²»\n北\n造\n百\nè§„\n热\n领\n七\næµ·\nå£\n东\n导\n器\n压\nå¿—\n世\n金\n增\n争\n济\n阶\næ²¹\næ€\n术\næž\n交\nå—\nè”\n什\n认\nå…­\nå…±\næƒ\næ”¶\nè¯\n改\n清\n美\nå†\n采\n转\næ›´\nå•\n风\n切\n打\n白\næ•™\n速\n花\n带\n安\n场\n身\n车\n例\n真\n务\nå…·\n万\næ¯\nç›®\n至\nè¾¾\nèµ°\n积\n示\nè®®\n声\n报\næ–—\n完\nç±»\nå…«\n离\nåŽ\nå\nç¡®\næ‰\nç§‘\nå¼ \nä¿¡\n马\n节\nè¯\nç±³\næ•´\n空\nå…ƒ\n况\n今\n集\n温\nä¼ \n土\n许\næ­¥\n群\n广\n石\nè®°\n需\n段\nç ”\n界\n拉\næž—\n律\nå«\n且\nç©¶\nè§‚\nè¶Š\n织\n装\nå½±\nç®—\n低\næŒ\n音\nä¼—\n书\n布\nå¤\n容\nå„¿\né¡»\né™…\n商\néž\n验\n连\næ–­\næ·±\néš¾\nè¿‘\n矿\nåƒ\n周\nå§”\nç´ \n技\n备\nåŠ\n办\né’\nçœ\n列\nä¹ \nå“\n约\n支\n般\nå²\n感\n劳\n便\n团\nå¾€\né…¸\n历\n市\nå…‹\n何\n除\n消\næž„\n府\nç§°\n太\n准\nç²¾\n值\nå·\n率\næ—\nç»´\n划\n选\næ ‡\n写\nå­˜\n候\n毛\n亲\nå¿«\n效\næ–¯\n院\n查\n江\nåž‹\n眼\n王\n按\næ ¼\nå…»\n易\nç½®\næ´¾\n层\n片\nå§‹\nå´\n专\n状\n育\n厂\n京\n识\n适\n属\n圆\n包\nç«\nä½\nè°ƒ\n满\n县\nå±€\nç…§\nå‚\n红\n细\n引\nå¬\n该\né“\nä»·\n严\n首\n底\næ¶²\n官\nå¾·\néš\nç—…\nè‹\n失\nå°”\næ­»\n讲\né…\n女\n黄\n推\n显\nè°ˆ\n罪\n神\n艺\nå‘¢\n席\nå«\nä¼\n望\n密\n批\nè¥\n项\n防\n举\nçƒ\n英\næ°§\n势\n告\næŽ\nå°\nè½\n木\n帮\nè½®\nç ´\n亚\n师\nå›´\n注\n远\nå­—\næ\n排\nä¾›\næ²³\næ€\nå°\nå¦\næ–½\nå‡\næ ‘\n溶\n怎\næ­¢\n案\n言\n士\nå‡\næ­¦\n固\nå¶\né±¼\næ³¢\n视\nä»…\nè´¹\nç´§\n爱\nå·¦\nç« \næ—©\næœ\n害\nç»­\nè½»\næœ\n试\n食\nå……\nå…µ\næº\n判\n护\nå¸\nè¶³\næŸ\n练\nå·®\n致\næ¿\nç”°\né™\n黑\n犯\nè´Ÿ\n击\n范\nç»§\nå…´\nä¼¼\nä½™\nåš\n曲\n输\nä¿®\næ•…\n城\n夫\n够\né€\n笔\n船\nå \nå³\nè´¢\nåƒ\n富\n春\nèŒ\n觉\n汉\nç”»\n功\nå·´\nè·Ÿ\n虽\næ‚\n飞\n检\nå¸\n助\nå‡\n阳\n互\nåˆ\n创\n抗\n考\n投\nå\nç­–\nå¤\n径\næ¢\n未\nè·‘\nç•™\né’¢\n曾\n端\nè´£\nç«™\n简\nè¿°\né’±\n副\nå°½\nå¸\nå°„\nè‰\n冲\n承\n独\n令\né™\n阿\n宣\n环\nåŒ\n请\nè¶…\nå¾®\n让\n控\nå·ž\n良\nè½´\n找\nå¦\n纪\n益\nä¾\n优\né¡¶\nç¡€\nè½½\n倒\n房\nçª\nå\n粉\n敌\nç•¥\n客\nè¢\n冷\n胜\nç»\næž\nå—\n剂\n测\nä¸\nå\n诉\n念\n陈\nä»\nç½—\nç›\nå‹\næ´‹\né”™\n苦\n夜\n刑\nç§»\n频\né€\né \næ··\næ¯\n短\nçš®\n终\nèš\næ±½\næ‘\n云\n哪\næ—¢\nè·\nå«\nåœ\n烈\n央\n察\n烧\nè¿…\n境\nè‹¥\nå°\næ´²\n刻\n括\næ¿€\nå­”\næž\n甚\n室\nå¾…\næ ¸\næ ¡\næ•£\nä¾µ\nå§\n甲\n游\nä¹…\nèœ\n味\næ—§\n模\næ¹–\nè´§\næŸ\n预\n阻\n毫\næ™®\n稳\nä¹™\n妈\næ¤\næ¯\n扩\né“¶\n语\n挥\né…’\n守\næ‹¿\nåº\n纸\n医\n缺\n雨\nå—\né’ˆ\n刘\n啊\n急\nå”±\n误\nè®­\næ„¿\n审\n附\n获\n茶\n鲜\nç²®\næ–¤\nå­©\n脱\nç¡«\nè‚¥\nå–„\né¾™\næ¼”\n父\næ¸\nè¡€\n欢\n械\n掌\næ­Œ\næ²™\n刚\næ”»\nè°“\n盾\n讨\n晚\nç²’\nä¹±\n燃\n矛\n乎\næ€\nè¯\nå®\né²\nè´µ\né’Ÿ\nç…¤\n读\nç­\n伯\n香\n介\nè¿«\nå¥\n丰\n培\næ¡\nå…°\næ‹…\n弦\n蛋\n沉\nå‡\nç©¿\n执\nç­”\nä¹\nè°\n顺\n烟\n缩\nå¾\n脸\nå–œ\næ¾\n脚\nå›°\n异\nå…\n背\n星\nç¦\nä¹°\n染\n井\n概\næ…¢\n怕\nç£\nå€\n祖\n皇\n促\né™\nè¡¥\n评\nç¿»\n肉\nè·µ\nå°¼\nè¡£\n宽\n扬\n棉\n希\n伤\næ“\nåž‚\nç§‹\n宜\næ°¢\n套\nç£\n振\næž¶\n亮\n末\n宪\n庆\nç¼–\n牛\n触\n映\né›·\n销\n诗\n座\nå±…\n抓\n裂\n胞\n呼\n娘\n景\nå¨\n绿\næ™¶\n厚\n盟\nè¡¡\n鸡\nå­™\nå»¶\nå±\n胶\n屋\n乡\n临\n陆\n顾\n掉\nå‘€\nç¯\nå²\n措\næŸ\nè€\n剧\n玉\nèµµ\nè·³\nå“¥\nå­£\n课\n凯\n胡\né¢\n款\nç»\nå·\né½\n伟\nè’¸\næ®–\næ°¸\nå®—\nè‹—\nå·\n炉\n岩\nå¼±\né›¶\næ¨\nå¥\n沿\n露\næ†\n探\n滑\n镇\n饭\n浓\n航\n怀\nèµ¶\n库\n夺\n伊\nçµ\n税\n途\nç­\nèµ›\nå½’\nå¬\n鼓\næ’­\n盘\nè£\n险\n康\n唯\n录\nèŒ\n纯\n借\nç³–\nç›–\n横\n符\nç§\n努\nå ‚\n域\n枪\n润\nå¹…\n哈\n竟\n熟\n虫\næ³½\nè„‘\n壤\n碳\n欧\né\nä¾§\n寨\næ•¢\nå½»\n虑\næ–œ\nè–„\n庭\n纳\nå¼¹\n饲\n伸\n折\n麦\n湿\næš—\nè·\n瓦\n塞\n床\nç­‘\næ¶\n户\n访\nå¡”\n奇\né€\næ¢\n刀\næ—‹\n迹\nå¡\næ°¯\né‡\n份\n毒\næ³¥\n退\næ´—\n摆\nç°\n彩\nå–\n耗\nå¤\næ‹©\nå¿™\n铜\n献\n硬\n予\nç¹\n圈\n雪\n函\n亦\n抽\n篇\n阵\n阴\nä¸\nå°º\n追\nå †\n雄\n迎\næ³›\n爸\n楼\né¿\nè°‹\nå¨\n野\n猪\næ——\nç´¯\nå\nå…¸\n馆\nç´¢\n秦\nè„‚\næ½®\n爷\n豆\n忽\n托\n惊\nå¡‘\né—\n愈\n朱\n替\n纤\nç²—\n倾\nå°š\nç—›\n楚\nè°¢\n奋\nè´­\n磨\nå›\næ± \næ—\n碎\n骨\n监\næ•\n弟\næš´\n割\nè´¯\n殊\n释\nè¯\n亡\nå£\né¡¿\nå®\nåˆ\nå°˜\né—»\næ­\nç‚®\n残\n冬\næ¡¥\n妇\nè­¦\n综\næ‹›\nå´\n付\næµ®\né­\nå¾\n您\n摇\nè°·\n赞\nç®±\néš”\n订\nç”·\nå¹\nå›­\n纷\nå”\nè´¥\n宋\n玻\nå·¨\n耕\nå¦\nè£\né—­\næ¹¾\né”®\n凡\né©»\né”…\næ•‘\næ©\n剥\nå‡\n碱\n齿\n截\n炼\n麻\n纺\nç¦\n废\nç››\n版\n缓\n净\nç›\n昌\n婚\n涉\nç­’\n嘴\næ’\n岸\n朗\n庄\nè¡—\nè—\nå§‘\nè´¸\nè…\n奴\n啦\n惯\n乘\nä¼™\næ¢\n匀\n纱\n扎\n辩\n耳\n彪\n臣\n亿\nç’ƒ\n抵\n脉\nç§€\nè¨\nä¿„\n网\n舞\n店\nå–·\n纵\n寸\næ±—\n挂\næ´ª\nè´º\né—ª\n柬\n爆\n烯\næ´¥\n稻\n墙\n软\n勇\nåƒ\n滚\n厘\nè’™\n芳\n肯\nå¡\n柱\nè¡\nè…¿\n仪\næ—…\nå°¾\nè½§\n冰\nè´¡\nç™»\n黎\n削\né’»\nå‹’\n逃\néšœ\næ°¨\n郭\nå³°\nå¸\n港\nä¼\n轨\n亩\n毕\n擦\n莫\n刺\n浪\n秘\næ´\næ ª\nå¥\nå”®\nè‚¡\nå²›\n甘\n泡\nç¡\nç«¥\n铸\n汤\n阀\n休\n汇\nèˆ\n牧\n绕\n炸\n哲\n磷\n绩\n朋\næ·¡\nå°–\nå¯\né™·\n柴\n呈\nå¾’\n颜\n泪\nç¨\n忘\næ³µ\nè“\næ‹–\næ´ž\n授\n镜\nè¾›\n壮\n锋\nè´«\n虚\n弯\næ‘©\næ³°\nå¹¼\nå»·\nå°Š\n窗\n纲\n弄\néš¶\nç–‘\næ°\n宫\nå§\n震\n瑞\n怪\nå°¤\nç´\n循\næ\n膜\nè¿\n夹\nè…°\n缘\nç \nç©·\n森\næž\n竹\n沟\n催\n绳\n忆\n邦\n剩\n幸\n浆\næ \næ‹¥\n牙\nè´®\n礼\n滤\né’ \n纹\nç½¢\næ‹\nå’±\nå–Š\n袖\n埃\n勤\n罚\n焦\n潜\nä¼\n墨\n欲\nç¼\nå§“\n刊\n饱\n仿\n奖\né“\n鬼\n丽\nè·¨\n默\n挖\n链\n扫\nå–\n袋\nç‚­\n污\n幕\n诸\nå¼§\n励\n梅\n奶\næ´\nç¾\n舟\n鉴\n苯\n讼\n抱\næ¯\n懂\n寒\n智\n埔\n寄\n届\nè·ƒ\n渡\n挑\n丹\n艰\nè´\n碰\næ‹”\n爹\n戴\nç \n梦\n芽\n熔\n赤\n渔\nå“­\n敬\n颗\n奔\né“…\n仲\n虎\n稀\n妹\nä¹\nç\n申\n桌\néµ\nå…\n隆\n螺\n仓\né­\né”\n晓\næ°®\nå…¼\néš\nç¢\n赫\n拨\nå¿ \n肃\n缸\n牵\n抢\nåš\nå·§\n壳\nå…„\næœ\n讯\n诚\n碧\n祥\n柯\n页\nå·¡\n矩\n悲\nçŒ\n龄\n伦\n票\n寻\næ¡‚\n铺\n圣\næ\næ°\n郑\nè¶£\n抬\nè’\nè…¾\nè´´\n柔\næ»´\n猛\n阔\n辆\n妻\nå¡«\næ’¤\n储\nç­¾\né—¹\n扰\nç´«\nç ‚\n递\næˆ\nåŠ\né™¶\nä¼\nå–‚\nç–—\nç“¶\n婆\n抚\n臂\n摸\nå¿\n虾\n蜡\né‚»\n胸\nå·©\n挤\nå¶\n弃\næ§½\n劲\nä¹³\né‚“\nå‰\nä»\n烂\nç –\nç§Ÿ\n乌\n舰\nä¼´\n瓜\næµ…\n丙\næš‚\n燥\næ©¡\n柳\nè¿·\næš–\n牌\nç§§\n胆\n详\nç°§\nè¸\nç“·\nè°±\n呆\n宾\n糊\næ´›\n辉\n愤\n竞\néš™\n怒\n粘\n乃\n绪\nè‚©\nç±\næ•\næ¶‚\n熙\n皆\n侦\n悬\n掘\n享\n纠\n醒\nç‹‚\né”\næ·€\næ¨\n牲\n霸\n爬\nèµ\n逆\n玩\n陵\nç¥\nç§’\næµ™\n貌\nå½¹\nå½¼\n悉\n鸭\nè¶‹\n凤\n晨\n畜\n辈\nç§©\nåµ\nç½²\n梯\n炎\n滩\n棋\n驱\nç­›\n峡\n冒\nå•¥\n寿\n译\n浸\n泉\n帽\n迟\nç¡…\nç–†\nè´·\næ¼\n稿\n冠\nå«©\nèƒ\n芯\n牢\nå›\n蚀\n奥\n鸣\nå²­\n羊\n凭\n串\n塘\n绘\né…µ\nèž\n盆\n锡\n庙\nç­¹\n冻\nè¾…\næ‘„\n袭\nç­‹\næ‹’\n僚\næ—±\né’¾\n鸟\n漆\n沈\n眉\nç–\næ·»\n棒\nç©—\nç¡\n韩\n逼\n扭\n侨\n凉\n挺\n碗\næ ½\nç‚’\næ¯\næ‚£\né¦\nåŠ\n豪\nè¾½\n勃\n鸿\næ—¦\nå\n拜\nç‹—\n埋\n辊\n掩\n饮\næ¬\n骂\n辞\n勾\n扣\nä¼°\nè’‹\nç»’\n雾\n丈\n朵\n姆\n拟\n宇\n辑\n陕\n雕\nå¿\nè“„\nå´‡\n剪\n倡\n厅\nå’¬\né©¶\nè–¯\n刷\næ–¥\n番\n赋\n奉\nä½›\n浇\n漫\n曼\n扇\né’™\n桃\n扶\nä»”\nè¿”\nä¿—\näº\nè…”\néž‹\n棱\n覆\n框\næ‚„\nå”\næ’ž\n骗\n勘\næ—º\n沸\nå­¤\nå\nå­Ÿ\n渠\n屈\nç–¾\n妙\n惜\nä»°\nç‹ \n胀\nè°\n抛\n霉\næ¡‘\nå²—\n嘛\nè¡°\nç›—\n渗\nè„\nèµ–\næ¶Œ\n甜\n曹\n阅\n肌\nå“©\n厉\n烃\n纬\n毅\n昨\n伪\nç—‡\nç…®\nå¹\né’‰\næ­\n茎\n笼\né…·\nå·\n弓\n锥\næ’\næ°\nå‘\né¼»\n翼\n纶\nå™\n狱\n逮\nç½\n络\n棚\n抑\n膨\n蔬\n寺\n骤\n穆\n冶\n枯\n册\nå°¸\n凸\nç»…\nå¯\n牺\nç„°\nè½°\n欣\n晋\n瘦\n御\né”­\n锦\n丧\næ—¬\né”»\nåž„\næœ\n扑\né‚€\n亭\né…¯\n迈\n舒\n脆\né…¶\né—²\nå¿§\né…š\n顽\nç¾½\n涨\nå¸\nä»—\n陪\n辟\n惩\næ­\nå§š\n肚\næ‰\n飘\n漂\n昆\n欺\nå¾\n郎\n烷\næ±\n呵\n饰\nè§\né›…\né‚®\nè¿\n燕\næ’’\nå§»\nèµ´\nå®´\n烦\n债\nå¸\næ–‘\n铃\næ—¨\n醇\nè‘£\n饼\né›\nå§¿\n拌\nå‚…\nè…¹\n妥\næ‰\nè´¤\n拆\næ­ª\nè‘¡\n胺\n丢\n浩\nå¾½\n昂\nåž«\n挡\n览\nè´ª\næ…°\nç¼´\n汪\næ…Œ\n冯\n诺\nå§œ\nè°Š\n凶\n劣\n诬\n耀\næ˜\n躺\n盈\n骑\nä¹”\n溪\n丛\nå¢\n抹\né—·\nå’¨\n刮\n驾\n缆\n悟\n摘\né“’\n掷\n颇\nå¹»\n柄\n惠\n惨\nä½³\n仇\nè…Š\nçª\n涤\n剑\nçž§\nå ¡\næ³¼\n葱\n罩\néœ\næž\n胎\nè‹\n滨\nä¿©\næ…\n湘\nç \n霞\n邵\nè„\nç–¯\næ·®\né‚\n熊\n粪\n烘\n宿\næ¡£\n戈\n驳\nå«‚\n裕\nå¾™\nç®­\næ\nè‚ \næ’‘\næ™’\n辨\n殿\n莲\n摊\næ…\né…±\nå±\nç–«\nå“€\n蔡\nå µ\n沫\nçš±\nç•…\nå \né˜\n莱\n敲\nè¾–\né’©\nç—•\nå\nå··\n饿\n祸\n丘\n玄\n溜\næ›°\n逻\nå½­\nå°\nå¿\n妨\n艇\nåž\n韦\n怨\n矮\næ­‡\n" + }, + { + "chinese_traditional", + "çš„\n一\n是\n在\nä¸\n了\n有\nå’Œ\n人\n這\n中\n大\n為\n上\n個\n國\n我\n以\nè¦\nä»–\n時\n來\n用\n們\n生\n到\n作\n地\næ–¼\n出\nå°±\n分\nå°\næˆ\n會\nå¯\n主\n發\nå¹´\nå‹•\nåŒ\nå·¥\n也\n能\n下\néŽ\nå­\n說\n產\n種\né¢\n而\næ–¹\n後\n多\n定\n行\nå­¸\n法\n所\næ°‘\nå¾—\nç¶“\nå\n三\n之\n進\nè‘—\nç­‰\n部\n度\nå®¶\né›»\n力\n裡\n如\næ°´\n化\n高\n自\n二\nç†\nèµ·\nå°\n物\nç¾\n實\n加\né‡\n都\nå…©\né«”\n制\n機\nç•¶\n使\n點\n從\n業\n本\n去\n把\n性\n好\n應\né–‹\n它\nåˆ\né‚„\nå› \nç”±\nå…¶\n些\nç„¶\nå‰\n外\n天\n政\nå››\næ—¥\né‚£\n社\n義\n事\nå¹³\nå½¢\n相\nå…¨\n表\né–“\n樣\n與\né—œ\nå„\né‡\næ–°\nç·š\nå…§\n數\næ­£\n心\nå\nä½ \n明\n看\n原\nåˆ\n麼\n利\n比\n或\n但\n質\næ°£\n第\nå‘\né“\n命\næ­¤\n變\næ¢\nåª\næ²’\nçµ\nè§£\nå•\næ„\n建\n月\nå…¬\nç„¡\nç³»\nè»\n很\n情\n者\n最\nç«‹\n代\n想\nå·²\n通\n並\næ\nç›´\n題\n黨\n程\n展\n五\næžœ\næ–™\n象\nå“¡\né©\nä½\nå…¥\n常\næ–‡\n總\n次\nå“\nå¼\næ´»\n設\nåŠ\n管\n特\nä»¶\né•·\n求\nè€\né ­\n基\n資\n邊\næµ\nè·¯\nç´š\nå°‘\n圖\nå±±\nçµ±\n接\n知\n較\nå°‡\n組\n見\n計\n別\n她\n手\nè§’\n期\næ ¹\nè«–\né‹\nè¾²\n指\nå¹¾\nä¹\nå€\nå¼·\n放\n決\n西\n被\nå¹¹\nåš\nå¿…\n戰\nå…ˆ\n回\n則\nä»»\nå–\n據\n處\n隊\nå—\n給\n色\nå…‰\né–€\nå³\nä¿\næ²»\n北\n造\n百\nè¦\n熱\né ˜\n七\næµ·\nå£\næ±\nå°Ž\n器\n壓\nå¿—\n世\n金\n增\n爭\n濟\n階\næ²¹\næ€\nè¡“\n極\n交\nå—\nè¯\n什\nèª\nå…­\nå…±\n權\næ”¶\nè­‰\n改\n清\n美\nå†\n採\n轉\næ›´\nå–®\n風\n切\n打\n白\næ•™\n速\n花\n帶\n安\nå ´\n身\n車\n例\n真\nå‹™\nå…·\nè¬\næ¯\nç›®\n至\né”\nèµ°\nç©\n示\nè­°\nè²\nå ±\n鬥\n完\n類\nå…«\n離\nè¯\nå\n確\næ‰\nç§‘\nå¼µ\nä¿¡\n馬\n節\n話\nç±³\næ•´\n空\nå…ƒ\næ³\n今\n集\n溫\n傳\n土\n許\næ­¥\n群\n廣\n石\n記\n需\n段\nç ”\n界\n拉\næž—\n律\nå«\n且\nç©¶\nè§€\nè¶Š\nç¹”\nè£\nå½±\nç®—\n低\næŒ\n音\n眾\n書\n布\nå¤\n容\nå…’\né ˆ\néš›\n商\néž\né©—\n連\næ–·\næ·±\n難\nè¿‘\n礦\nåƒ\n週\nå§”\nç´ \n技\nå‚™\nåŠ\n辦\né’\nçœ\n列\nç¿’\n響\nç´„\n支\n般\nå²\n感\n勞\n便\n團\nå¾€\né…¸\næ­·\n市\nå…‹\n何\n除\n消\næ§‹\n府\n稱\n太\n準\nç²¾\n值\n號\n率\næ—\nç¶­\n劃\né¸\n標\n寫\nå­˜\n候\n毛\n親\nå¿«\n效\næ–¯\n院\n查\n江\nåž‹\n眼\n王\n按\næ ¼\n養\n易\nç½®\næ´¾\n層\n片\nå§‹\nå»\nå°ˆ\nç‹€\n育\nå» \n京\nè­˜\né©\n屬\n圓\n包\nç«\nä½\n調\n滿\n縣\nå±€\nç…§\nåƒ\nç´…\nç´°\n引\nè½\n該\néµ\n價\nåš´\n首\n底\næ¶²\n官\nå¾·\n隨\nç—…\n蘇\n失\n爾\næ­»\n講\né…\n女\n黃\n推\n顯\n談\n罪\n神\nè—\nå‘¢\n席\nå«\nä¼\n望\n密\n批\n營\né …\n防\n舉\nçƒ\n英\næ°§\nå‹¢\n告\næŽ\nå°\nè½\n木\n幫\n輪\nç ´\n亞\n師\nåœ\n注\né \nå­—\næ\n排\nä¾›\næ²³\næ…‹\nå°\nå¦\næ–½\n減\n樹\n溶\n怎\næ­¢\n案\n言\n士\nå‡\næ­¦\n固\n葉\né­š\næ³¢\n視\n僅\nè²»\nç·Š\næ„›\nå·¦\nç« \næ—©\næœ\n害\n續\n輕\næœ\n試\n食\nå……\nå…µ\næº\n判\nè­·\nå¸\nè¶³\næŸ\nç·´\nå·®\n致\næ¿\nç”°\né™\n黑\n犯\nè² \n擊\n范\nç¹¼\n興\nä¼¼\n餘\nå …\n曲\n輸\nä¿®\næ•…\n城\n夫\n夠\né€\nç­†\n船\nä½”\nå³\n財\nåƒ\n富\n春\nè·\n覺\næ¼¢\nç•«\n功\nå·´\nè·Ÿ\né›–\n雜\n飛\n檢\nå¸\n助\n昇\n陽\n互\nåˆ\n創\n抗\n考\n投\n壞\nç­–\nå¤\n徑\næ›\n未\nè·‘\nç•™\n鋼\n曾\n端\n責\nç«™\nç°¡\nè¿°\n錢\n副\n盡\nå¸\nå°„\nè‰\nè¡\n承\nç¨\n令\né™\n阿\n宣\nç’°\né›™\nè«‹\nè¶…\nå¾®\n讓\n控\nå·ž\n良\n軸\n找\nå¦\nç´€\n益\nä¾\n優\né ‚\n礎\n載\n倒\n房\nçª\nå\n粉\n敵\nç•¥\n客\nè¢\n冷\nå‹\n絕\næž\n塊\n劑\n測\nçµ²\nå”\n訴\n念\n陳\nä»\nç¾…\né¹½\nå‹\næ´‹\n錯\n苦\n夜\n刑\nç§»\né »\né€\né \næ··\næ¯\n短\nçš®\n終\nèš\næ±½\næ‘\n雲\n哪\næ—¢\nè·\nè¡›\nåœ\n烈\n央\n察\n燒\nè¿…\n境\nè‹¥\nå°\næ´²\n刻\n括\næ¿€\nå­”\næž\n甚\n室\nå¾…\næ ¸\næ ¡\næ•£\nä¾µ\nå§\n甲\néŠ\nä¹…\nèœ\n味\n舊\n模\næ¹–\n貨\næ\né \n阻\n毫\næ™®\nç©©\nä¹™\n媽\næ¤\næ¯\næ“´\n銀\n語\næ®\né…’\n守\næ‹¿\nåº\nç´™\n醫\n缺\n雨\nå—Ž\né‡\n劉\n啊\n急\nå”±\n誤\n訓\n願\n審\n附\nç²\n茶\né®®\nç³§\næ–¤\nå­©\nè„«\nç¡«\nè‚¥\nå–„\né¾\næ¼”\n父\n漸\nè¡€\næ­¡\n械\n掌\næ­Œ\næ²™\n剛\næ”»\n謂\n盾\n討\n晚\nç²’\n亂\n燃\n矛\n乎\n殺\nè—¥\n寧\né­¯\nè²´\né˜\nç…¤\n讀\nç­\n伯\n香\n介\nè¿«\nå¥\nè±\n培\næ¡\n蘭\næ“”\n弦\n蛋\n沉\nå‡\nç©¿\n執\nç­”\n樂\n誰\né †\nç…™\n縮\nå¾µ\n臉\nå–œ\næ¾\nè…³\nå›°\nç•°\nå…\n背\n星\nç¦\nè²·\n染\n井\n概\næ…¢\n怕\nç£\nå€\n祖\n皇\n促\néœ\n補\nè©•\nç¿»\n肉\nè¸\nå°¼\nè¡£\n寬\næš\n棉\n希\nå‚·\næ“\nåž‚\nç§‹\n宜\næ°«\n套\nç£\n振\næž¶\n亮\n末\n憲\næ…¶\nç·¨\n牛\n觸\n映\né›·\n銷\nè©©\n座\nå±…\n抓\n裂\n胞\n呼\n娘\n景\nå¨\nç¶ \næ™¶\n厚\n盟\nè¡¡\n雞\nå­«\nå»¶\nå±\n膠\n屋\n鄉\n臨\n陸\né¡§\n掉\nå‘€\n燈\næ­²\n措\næŸ\nè€\n劇\n玉\nè¶™\nè·³\nå“¥\nå­£\n課\n凱\n胡\né¡\n款\nç´¹\nå·\n齊\nå‰\nè’¸\næ®–\næ°¸\nå®—\nè‹—\nå·\nçˆ\n岩\nå¼±\né›¶\n楊\nå¥\n沿\n露\næ¡¿\n探\n滑\n鎮\n飯\n濃\n航\n懷\nè¶•\n庫\n奪\n伊\néˆ\n稅\n途\næ»…\nè³½\næ­¸\nå¬\n鼓\næ’­\n盤\nè£\n險\n康\n唯\n錄\nèŒ\nç´”\n借\nç³–\nè“‹\næ©«\n符\nç§\n努\nå ‚\n域\næ§\n潤\nå¹…\n哈\n竟\n熟\n蟲\n澤\nè…¦\n壤\n碳\næ­\né\nå´\n寨\næ•¢\nå¾¹\næ…®\næ–œ\nè–„\n庭\nç´\n彈\n飼\n伸\n折\n麥\næ¿•\næš—\nè·\n瓦\n塞\n床\n築\n惡\n戶\n訪\nå¡”\n奇\né€\næ¢\n刀\næ—‹\nè·¡\nå¡\næ°¯\né‡\n份\n毒\næ³¥\n退\næ´—\n擺\nç°\n彩\nè³£\n耗\nå¤\n擇\nå¿™\n銅\nç»\n硬\n予\nç¹\n圈\n雪\n函\n亦\n抽\n篇\n陣\né™°\nä¸\nå°º\n追\nå †\n雄\n迎\næ³›\n爸\n樓\né¿\n謀\n噸\n野\n豬\næ——\nç´¯\nå\nå…¸\n館\nç´¢\n秦\nè„‚\næ½®\n爺\n豆\n忽\n托\n驚\nå¡‘\néº\n愈\n朱\n替\n纖\nç²—\n傾\nå°š\nç—›\n楚\nè¬\n奮\nè³¼\n磨\nå›\næ± \næ—\n碎\n骨\n監\næ•\n弟\næš´\n割\n貫\n殊\n釋\n詞\n亡\nå£\né “\n寶\nåˆ\n塵\nèž\næ­\nç‚®\n殘\n冬\næ©‹\n婦\nè­¦\nç¶œ\næ‹›\nå³\n付\næµ®\né­\nå¾\n您\næ–\nè°·\nè´Š\nç®±\néš”\n訂\nç”·\nå¹\n園\nç´›\nå”\næ•—\n宋\n玻\nå·¨\n耕\nå¦\n榮\né–‰\nç£\néµ\n凡\né§\né‹\næ•‘\næ©\nå‰\nå‡\né¹¼\né½’\n截\nç…‰\n麻\nç´¡\nç¦\n廢\nç››\n版\nç·©\næ·¨\nç›\n昌\n婚\n涉\nç­’\n嘴\næ’\n岸\n朗\n莊\nè¡—\nè—\nå§‘\n貿\nè…\n奴\n啦\næ…£\n乘\n夥\næ¢\nå‹»\nç´—\n扎\n辯\n耳\n彪\n臣\nå„„\nç’ƒ\n抵\n脈\nç§€\nè–©\nä¿„\nç¶²\n舞\n店\nå™´\n縱\n寸\næ±—\n掛\næ´ª\nè³€\né–ƒ\n柬\n爆\n烯\næ´¥\n稻\n牆\n軟\n勇\nåƒ\n滾\n厘\nè’™\n芳\n肯\nå¡\n柱\n盪\nè…¿\nå„€\næ—…\nå°¾\n軋\n冰\nè²¢\nç™»\n黎\n削\n鑽\nå‹’\n逃\néšœ\næ°¨\n郭\nå³°\nå¹£\n港\nä¼\n軌\nç•\nç•¢\n擦\n莫\n刺\n浪\n秘\næ´\næ ª\nå¥\nå”®\nè‚¡\nå³¶\n甘\n泡\nç¡\nç«¥\né‘„\n湯\né–¥\n休\n匯\nèˆ\n牧\n繞\n炸\n哲\n磷\n績\n朋\næ·¡\nå°–\n啟\né™·\n柴\n呈\nå¾’\né¡\næ·š\nç¨\n忘\næ³µ\nè—\næ‹–\næ´ž\n授\né¡\nè¾›\n壯\né‹’\nè²§\nè™›\n彎\næ‘©\næ³°\nå¹¼\nå»·\nå°Š\n窗\nç¶±\n弄\n隸\nç–‘\næ°\nå®®\nå§\n震\n瑞\n怪\nå°¤\nç´\n循\næ\n膜\né•\n夾\nè…°\nç·£\nç \n窮\n森\næž\n竹\næº\n催\n繩\n憶\n邦\n剩\n幸\n漿\n欄\næ“\n牙\n貯\n禮\n濾\n鈉\nç´‹\nç½·\næ‹\nå’±\nå–Š\n袖\n埃\n勤\nç½°\n焦\næ½›\nä¼\n墨\n欲\n縫\nå§“\n刊\n飽\n仿\nçŽ\né‹\n鬼\n麗\nè·¨\n默\n挖\néˆ\n掃\nå–\n袋\nç‚­\n污\n幕\n諸\nå¼§\n勵\n梅\n奶\næ½”\nç½\n舟\né‘‘\n苯\n訟\n抱\n毀\n懂\n寒\n智\n埔\n寄\n屆\nèº\n渡\n挑\n丹\n艱\nè²\n碰\næ‹”\n爹\n戴\n碼\n夢\n芽\n熔\n赤\næ¼\nå“­\n敬\n顆\n奔\n鉛\n仲\n虎\n稀\n妹\nä¹\nç\n申\n桌\néµ\nå…\n隆\n螺\n倉\né­\n銳\n曉\næ°®\nå…¼\néš±\n礙\n赫\næ’¥\nå¿ \nè‚…\n缸\n牽\næ¶\nåš\nå·§\n殼\nå…„\næœ\n訊\n誠\n碧\n祥\n柯\né \nå·¡\n矩\n悲\nçŒ\n齡\n倫\n票\nå°‹\næ¡‚\n鋪\nè–\næ\næ°\né„­\nè¶£\n抬\nè’\n騰\nè²¼\n柔\næ»´\n猛\né—Š\nè¼›\n妻\nå¡«\næ’¤\n儲\nç°½\n鬧\n擾\nç´«\nç ‚\néž\n戲\nåŠ\né™¶\nä¼\n餵\n療\nç“¶\n婆\næ’«\n臂\n摸\nå¿\nè¦\nè Ÿ\né„°\n胸\néž\næ“ \nå¶\n棄\næ§½\nå‹\nä¹³\né„§\nå‰\nä»\n爛\n磚\nç§Ÿ\nçƒ\n艦\nä¼´\n瓜\næ·º\n丙\næš«\n燥\næ©¡\n柳\nè¿·\næš–\n牌\nç§§\n膽\n詳\nç°§\nè¸\nç“·\nè­œ\n呆\n賓\n糊\næ´›\nè¼\n憤\nç«¶\néš™\n怒\n粘\n乃\nç·’\nè‚©\nç±\næ•\nå¡—\n熙\n皆\nåµ\n懸\n掘\n享\nç³¾\n醒\nç‹‚\n鎖\næ·€\næ¨\n牲\n霸\n爬\n賞\n逆\n玩\n陵\nç¥\nç§’\næµ™\n貌\nå½¹\nå½¼\n悉\né´¨\n趨\né³³\n晨\n畜\n輩\nç§©\nåµ\nç½²\n梯\n炎\nç˜\n棋\né©…\n篩\nå³½\n冒\nå•¥\n壽\nè­¯\n浸\n泉\n帽\né²\n矽\nç–†\n貸\næ¼\n稿\n冠\nå«©\nè„…\n芯\n牢\nå›\nè•\n奧\né³´\n嶺\n羊\n憑\n串\n塘\n繪\né…µ\nèž\n盆\n錫\n廟\n籌\nå‡\nè¼”\næ”\n襲\nç­‹\næ‹’\n僚\næ—±\n鉀\né³¥\n漆\n沈\n眉\nç–\næ·»\n棒\nç©—\nç¡\n韓\n逼\n扭\n僑\næ¶¼\n挺\n碗\næ ½\nç‚’\næ¯\næ‚£\n餾\n勸\n豪\né¼\n勃\né´»\næ—¦\nå\n拜\nç‹—\n埋\nè¼¥\n掩\n飲\næ¬\nç½µ\nè¾­\n勾\n扣\nä¼°\n蔣\n絨\n霧\n丈\n朵\n姆\n擬\n宇\n輯\né™\n雕\n償\nè“„\nå´‡\n剪\n倡\n廳\nå’¬\né§›\nè–¯\n刷\næ–¥\n番\n賦\n奉\nä½›\n澆\n漫\n曼\n扇\n鈣\n桃\n扶\nä»”\nè¿”\nä¿—\nè™§\nè…”\néž‹\n棱\n覆\n框\næ‚„\nå”\næ’ž\n騙\n勘\næ—º\n沸\nå­¤\nå\nå­Ÿ\n渠\n屈\nç–¾\n妙\n惜\nä»°\nç‹ \n脹\nè«§\næ‹‹\né»´\næ¡‘\nå´—\n嘛\nè¡°\n盜\n滲\n臟\nè³´\næ¹§\n甜\n曹\né–±\n肌\nå“©\n厲\n烴\nç·¯\n毅\n昨\nå½\nç—‡\nç…®\n嘆\n釘\næ­\n莖\nç± \né…·\nå·\n弓\néŒ\næ†\nå‚‘\nå‘\né¼»\n翼\n綸\n敘\nç„\n逮\nç½\n絡\n棚\n抑\n膨\n蔬\n寺\n驟\n穆\n冶\n枯\n冊\nå±\n凸\nç´³\nå¯\n犧\nç„°\n轟\n欣\n晉\n瘦\n禦\n錠\n錦\nå–ª\næ—¬\né›\n壟\næœ\næ’²\né‚€\n亭\né…¯\né‚\n舒\n脆\né…¶\né–’\n憂\né…š\né ‘\nç¾½\næ¼²\nå¸\nä»—\n陪\né—¢\n懲\næ­\nå§š\n肚\næ‰\n飄\n漂\n昆\n欺\nå¾\n郎\n烷\næ±\n呵\n飾\nè•­\né›…\n郵\né·\n燕\næ’’\nå§»\nèµ´\nå®´\nç…©\n債\n帳\næ–‘\n鈴\næ—¨\n醇\nè‘£\n餅\né››\nå§¿\n拌\nå‚…\nè…¹\n妥\næ‰\nè³¢\n拆\næ­ª\nè‘¡\n胺\n丟\n浩\nå¾½\n昂\n墊\næ“‹\n覽\n貪\næ…°\nç¹³\n汪\næ…Œ\n馮\n諾\nå§œ\n誼\nå…‡\n劣\n誣\n耀\næ˜\n躺\n盈\n騎\nå–¬\n溪\nå¢\nç›§\n抹\næ‚¶\nè«®\n刮\né§•\n纜\n悟\n摘\n鉺\n擲\né —\nå¹»\n柄\n惠\næ…˜\nä½³\n仇\n臘\n窩\n滌\nåŠ\nçž§\nå ¡\n潑\n蔥\n罩\néœ\næ’ˆ\n胎\nè’¼\n濱\n倆\næ…\n湘\nç \n霞\n邵\nè„\n瘋\næ·®\né‚\n熊\n糞\n烘\n宿\n檔\n戈\né§\nå«‚\n裕\nå¾™\nç®­\næ\nè…¸\næ’\n曬\n辨\n殿\nè“®\n攤\n攪\n醬\nå±\nç–«\nå“€\n蔡\nå µ\n沫\n皺\n暢\nç–Š\né–£\nèŠ\n敲\n轄\n鉤\nç—•\n壩\nå··\n餓\nç¦\n丘\n玄\n溜\næ›°\né‚\nå½­\n嘗\nå¿\n妨\n艇\nåž\n韋\n怨\n矮\næ­‡\n" + }, + { + "english", + "abandon\nability\nable\nabout\nabove\nabsent\nabsorb\nabstract\nabsurd\nabuse\naccess\naccident\naccount\naccuse\nachieve\nacid\nacoustic\nacquire\nacross\nact\naction\nactor\nactress\nactual\nadapt\nadd\naddict\naddress\nadjust\nadmit\nadult\nadvance\nadvice\naerobic\naffair\nafford\nafraid\nagain\nage\nagent\nagree\nahead\naim\nair\nairport\naisle\nalarm\nalbum\nalcohol\nalert\nalien\nall\nalley\nallow\nalmost\nalone\nalpha\nalready\nalso\nalter\nalways\namateur\namazing\namong\namount\namused\nanalyst\nanchor\nancient\nanger\nangle\nangry\nanimal\nankle\nannounce\nannual\nanother\nanswer\nantenna\nantique\nanxiety\nany\napart\napology\nappear\napple\napprove\napril\narch\narctic\narea\narena\nargue\narm\narmed\narmor\narmy\naround\narrange\narrest\narrive\narrow\nart\nartefact\nartist\nartwork\nask\naspect\nassault\nasset\nassist\nassume\nasthma\nathlete\natom\nattack\nattend\nattitude\nattract\nauction\naudit\naugust\naunt\nauthor\nauto\nautumn\naverage\navocado\navoid\nawake\naware\naway\nawesome\nawful\nawkward\naxis\nbaby\nbachelor\nbacon\nbadge\nbag\nbalance\nbalcony\nball\nbamboo\nbanana\nbanner\nbar\nbarely\nbargain\nbarrel\nbase\nbasic\nbasket\nbattle\nbeach\nbean\nbeauty\nbecause\nbecome\nbeef\nbefore\nbegin\nbehave\nbehind\nbelieve\nbelow\nbelt\nbench\nbenefit\nbest\nbetray\nbetter\nbetween\nbeyond\nbicycle\nbid\nbike\nbind\nbiology\nbird\nbirth\nbitter\nblack\nblade\nblame\nblanket\nblast\nbleak\nbless\nblind\nblood\nblossom\nblouse\nblue\nblur\nblush\nboard\nboat\nbody\nboil\nbomb\nbone\nbonus\nbook\nboost\nborder\nboring\nborrow\nboss\nbottom\nbounce\nbox\nboy\nbracket\nbrain\nbrand\nbrass\nbrave\nbread\nbreeze\nbrick\nbridge\nbrief\nbright\nbring\nbrisk\nbroccoli\nbroken\nbronze\nbroom\nbrother\nbrown\nbrush\nbubble\nbuddy\nbudget\nbuffalo\nbuild\nbulb\nbulk\nbullet\nbundle\nbunker\nburden\nburger\nburst\nbus\nbusiness\nbusy\nbutter\nbuyer\nbuzz\ncabbage\ncabin\ncable\ncactus\ncage\ncake\ncall\ncalm\ncamera\ncamp\ncan\ncanal\ncancel\ncandy\ncannon\ncanoe\ncanvas\ncanyon\ncapable\ncapital\ncaptain\ncar\ncarbon\ncard\ncargo\ncarpet\ncarry\ncart\ncase\ncash\ncasino\ncastle\ncasual\ncat\ncatalog\ncatch\ncategory\ncattle\ncaught\ncause\ncaution\ncave\nceiling\ncelery\ncement\ncensus\ncentury\ncereal\ncertain\nchair\nchalk\nchampion\nchange\nchaos\nchapter\ncharge\nchase\nchat\ncheap\ncheck\ncheese\nchef\ncherry\nchest\nchicken\nchief\nchild\nchimney\nchoice\nchoose\nchronic\nchuckle\nchunk\nchurn\ncigar\ncinnamon\ncircle\ncitizen\ncity\ncivil\nclaim\nclap\nclarify\nclaw\nclay\nclean\nclerk\nclever\nclick\nclient\ncliff\nclimb\nclinic\nclip\nclock\nclog\nclose\ncloth\ncloud\nclown\nclub\nclump\ncluster\nclutch\ncoach\ncoast\ncoconut\ncode\ncoffee\ncoil\ncoin\ncollect\ncolor\ncolumn\ncombine\ncome\ncomfort\ncomic\ncommon\ncompany\nconcert\nconduct\nconfirm\ncongress\nconnect\nconsider\ncontrol\nconvince\ncook\ncool\ncopper\ncopy\ncoral\ncore\ncorn\ncorrect\ncost\ncotton\ncouch\ncountry\ncouple\ncourse\ncousin\ncover\ncoyote\ncrack\ncradle\ncraft\ncram\ncrane\ncrash\ncrater\ncrawl\ncrazy\ncream\ncredit\ncreek\ncrew\ncricket\ncrime\ncrisp\ncritic\ncrop\ncross\ncrouch\ncrowd\ncrucial\ncruel\ncruise\ncrumble\ncrunch\ncrush\ncry\ncrystal\ncube\nculture\ncup\ncupboard\ncurious\ncurrent\ncurtain\ncurve\ncushion\ncustom\ncute\ncycle\ndad\ndamage\ndamp\ndance\ndanger\ndaring\ndash\ndaughter\ndawn\nday\ndeal\ndebate\ndebris\ndecade\ndecember\ndecide\ndecline\ndecorate\ndecrease\ndeer\ndefense\ndefine\ndefy\ndegree\ndelay\ndeliver\ndemand\ndemise\ndenial\ndentist\ndeny\ndepart\ndepend\ndeposit\ndepth\ndeputy\nderive\ndescribe\ndesert\ndesign\ndesk\ndespair\ndestroy\ndetail\ndetect\ndevelop\ndevice\ndevote\ndiagram\ndial\ndiamond\ndiary\ndice\ndiesel\ndiet\ndiffer\ndigital\ndignity\ndilemma\ndinner\ndinosaur\ndirect\ndirt\ndisagree\ndiscover\ndisease\ndish\ndismiss\ndisorder\ndisplay\ndistance\ndivert\ndivide\ndivorce\ndizzy\ndoctor\ndocument\ndog\ndoll\ndolphin\ndomain\ndonate\ndonkey\ndonor\ndoor\ndose\ndouble\ndove\ndraft\ndragon\ndrama\ndrastic\ndraw\ndream\ndress\ndrift\ndrill\ndrink\ndrip\ndrive\ndrop\ndrum\ndry\nduck\ndumb\ndune\nduring\ndust\ndutch\nduty\ndwarf\ndynamic\neager\neagle\nearly\nearn\nearth\neasily\neast\neasy\necho\necology\neconomy\nedge\nedit\neducate\neffort\negg\neight\neither\nelbow\nelder\nelectric\nelegant\nelement\nelephant\nelevator\nelite\nelse\nembark\nembody\nembrace\nemerge\nemotion\nemploy\nempower\nempty\nenable\nenact\nend\nendless\nendorse\nenemy\nenergy\nenforce\nengage\nengine\nenhance\nenjoy\nenlist\nenough\nenrich\nenroll\nensure\nenter\nentire\nentry\nenvelope\nepisode\nequal\nequip\nera\nerase\nerode\nerosion\nerror\nerupt\nescape\nessay\nessence\nestate\neternal\nethics\nevidence\nevil\nevoke\nevolve\nexact\nexample\nexcess\nexchange\nexcite\nexclude\nexcuse\nexecute\nexercise\nexhaust\nexhibit\nexile\nexist\nexit\nexotic\nexpand\nexpect\nexpire\nexplain\nexpose\nexpress\nextend\nextra\neye\neyebrow\nfabric\nface\nfaculty\nfade\nfaint\nfaith\nfall\nfalse\nfame\nfamily\nfamous\nfan\nfancy\nfantasy\nfarm\nfashion\nfat\nfatal\nfather\nfatigue\nfault\nfavorite\nfeature\nfebruary\nfederal\nfee\nfeed\nfeel\nfemale\nfence\nfestival\nfetch\nfever\nfew\nfiber\nfiction\nfield\nfigure\nfile\nfilm\nfilter\nfinal\nfind\nfine\nfinger\nfinish\nfire\nfirm\nfirst\nfiscal\nfish\nfit\nfitness\nfix\nflag\nflame\nflash\nflat\nflavor\nflee\nflight\nflip\nfloat\nflock\nfloor\nflower\nfluid\nflush\nfly\nfoam\nfocus\nfog\nfoil\nfold\nfollow\nfood\nfoot\nforce\nforest\nforget\nfork\nfortune\nforum\nforward\nfossil\nfoster\nfound\nfox\nfragile\nframe\nfrequent\nfresh\nfriend\nfringe\nfrog\nfront\nfrost\nfrown\nfrozen\nfruit\nfuel\nfun\nfunny\nfurnace\nfury\nfuture\ngadget\ngain\ngalaxy\ngallery\ngame\ngap\ngarage\ngarbage\ngarden\ngarlic\ngarment\ngas\ngasp\ngate\ngather\ngauge\ngaze\ngeneral\ngenius\ngenre\ngentle\ngenuine\ngesture\nghost\ngiant\ngift\ngiggle\nginger\ngiraffe\ngirl\ngive\nglad\nglance\nglare\nglass\nglide\nglimpse\nglobe\ngloom\nglory\nglove\nglow\nglue\ngoat\ngoddess\ngold\ngood\ngoose\ngorilla\ngospel\ngossip\ngovern\ngown\ngrab\ngrace\ngrain\ngrant\ngrape\ngrass\ngravity\ngreat\ngreen\ngrid\ngrief\ngrit\ngrocery\ngroup\ngrow\ngrunt\nguard\nguess\nguide\nguilt\nguitar\ngun\ngym\nhabit\nhair\nhalf\nhammer\nhamster\nhand\nhappy\nharbor\nhard\nharsh\nharvest\nhat\nhave\nhawk\nhazard\nhead\nhealth\nheart\nheavy\nhedgehog\nheight\nhello\nhelmet\nhelp\nhen\nhero\nhidden\nhigh\nhill\nhint\nhip\nhire\nhistory\nhobby\nhockey\nhold\nhole\nholiday\nhollow\nhome\nhoney\nhood\nhope\nhorn\nhorror\nhorse\nhospital\nhost\nhotel\nhour\nhover\nhub\nhuge\nhuman\nhumble\nhumor\nhundred\nhungry\nhunt\nhurdle\nhurry\nhurt\nhusband\nhybrid\nice\nicon\nidea\nidentify\nidle\nignore\nill\nillegal\nillness\nimage\nimitate\nimmense\nimmune\nimpact\nimpose\nimprove\nimpulse\ninch\ninclude\nincome\nincrease\nindex\nindicate\nindoor\nindustry\ninfant\ninflict\ninform\ninhale\ninherit\ninitial\ninject\ninjury\ninmate\ninner\ninnocent\ninput\ninquiry\ninsane\ninsect\ninside\ninspire\ninstall\nintact\ninterest\ninto\ninvest\ninvite\ninvolve\niron\nisland\nisolate\nissue\nitem\nivory\njacket\njaguar\njar\njazz\njealous\njeans\njelly\njewel\njob\njoin\njoke\njourney\njoy\njudge\njuice\njump\njungle\njunior\njunk\njust\nkangaroo\nkeen\nkeep\nketchup\nkey\nkick\nkid\nkidney\nkind\nkingdom\nkiss\nkit\nkitchen\nkite\nkitten\nkiwi\nknee\nknife\nknock\nknow\nlab\nlabel\nlabor\nladder\nlady\nlake\nlamp\nlanguage\nlaptop\nlarge\nlater\nlatin\nlaugh\nlaundry\nlava\nlaw\nlawn\nlawsuit\nlayer\nlazy\nleader\nleaf\nlearn\nleave\nlecture\nleft\nleg\nlegal\nlegend\nleisure\nlemon\nlend\nlength\nlens\nleopard\nlesson\nletter\nlevel\nliar\nliberty\nlibrary\nlicense\nlife\nlift\nlight\nlike\nlimb\nlimit\nlink\nlion\nliquid\nlist\nlittle\nlive\nlizard\nload\nloan\nlobster\nlocal\nlock\nlogic\nlonely\nlong\nloop\nlottery\nloud\nlounge\nlove\nloyal\nlucky\nluggage\nlumber\nlunar\nlunch\nluxury\nlyrics\nmachine\nmad\nmagic\nmagnet\nmaid\nmail\nmain\nmajor\nmake\nmammal\nman\nmanage\nmandate\nmango\nmansion\nmanual\nmaple\nmarble\nmarch\nmargin\nmarine\nmarket\nmarriage\nmask\nmass\nmaster\nmatch\nmaterial\nmath\nmatrix\nmatter\nmaximum\nmaze\nmeadow\nmean\nmeasure\nmeat\nmechanic\nmedal\nmedia\nmelody\nmelt\nmember\nmemory\nmention\nmenu\nmercy\nmerge\nmerit\nmerry\nmesh\nmessage\nmetal\nmethod\nmiddle\nmidnight\nmilk\nmillion\nmimic\nmind\nminimum\nminor\nminute\nmiracle\nmirror\nmisery\nmiss\nmistake\nmix\nmixed\nmixture\nmobile\nmodel\nmodify\nmom\nmoment\nmonitor\nmonkey\nmonster\nmonth\nmoon\nmoral\nmore\nmorning\nmosquito\nmother\nmotion\nmotor\nmountain\nmouse\nmove\nmovie\nmuch\nmuffin\nmule\nmultiply\nmuscle\nmuseum\nmushroom\nmusic\nmust\nmutual\nmyself\nmystery\nmyth\nnaive\nname\nnapkin\nnarrow\nnasty\nnation\nnature\nnear\nneck\nneed\nnegative\nneglect\nneither\nnephew\nnerve\nnest\nnet\nnetwork\nneutral\nnever\nnews\nnext\nnice\nnight\nnoble\nnoise\nnominee\nnoodle\nnormal\nnorth\nnose\nnotable\nnote\nnothing\nnotice\nnovel\nnow\nnuclear\nnumber\nnurse\nnut\noak\nobey\nobject\noblige\nobscure\nobserve\nobtain\nobvious\noccur\nocean\noctober\nodor\noff\noffer\noffice\noften\noil\nokay\nold\nolive\nolympic\nomit\nonce\none\nonion\nonline\nonly\nopen\nopera\nopinion\noppose\noption\norange\norbit\norchard\norder\nordinary\norgan\norient\noriginal\norphan\nostrich\nother\noutdoor\nouter\noutput\noutside\noval\noven\nover\nown\nowner\noxygen\noyster\nozone\npact\npaddle\npage\npair\npalace\npalm\npanda\npanel\npanic\npanther\npaper\nparade\nparent\npark\nparrot\nparty\npass\npatch\npath\npatient\npatrol\npattern\npause\npave\npayment\npeace\npeanut\npear\npeasant\npelican\npen\npenalty\npencil\npeople\npepper\nperfect\npermit\nperson\npet\nphone\nphoto\nphrase\nphysical\npiano\npicnic\npicture\npiece\npig\npigeon\npill\npilot\npink\npioneer\npipe\npistol\npitch\npizza\nplace\nplanet\nplastic\nplate\nplay\nplease\npledge\npluck\nplug\nplunge\npoem\npoet\npoint\npolar\npole\npolice\npond\npony\npool\npopular\nportion\nposition\npossible\npost\npotato\npottery\npoverty\npowder\npower\npractice\npraise\npredict\nprefer\nprepare\npresent\npretty\nprevent\nprice\npride\nprimary\nprint\npriority\nprison\nprivate\nprize\nproblem\nprocess\nproduce\nprofit\nprogram\nproject\npromote\nproof\nproperty\nprosper\nprotect\nproud\nprovide\npublic\npudding\npull\npulp\npulse\npumpkin\npunch\npupil\npuppy\npurchase\npurity\npurpose\npurse\npush\nput\npuzzle\npyramid\nquality\nquantum\nquarter\nquestion\nquick\nquit\nquiz\nquote\nrabbit\nraccoon\nrace\nrack\nradar\nradio\nrail\nrain\nraise\nrally\nramp\nranch\nrandom\nrange\nrapid\nrare\nrate\nrather\nraven\nraw\nrazor\nready\nreal\nreason\nrebel\nrebuild\nrecall\nreceive\nrecipe\nrecord\nrecycle\nreduce\nreflect\nreform\nrefuse\nregion\nregret\nregular\nreject\nrelax\nrelease\nrelief\nrely\nremain\nremember\nremind\nremove\nrender\nrenew\nrent\nreopen\nrepair\nrepeat\nreplace\nreport\nrequire\nrescue\nresemble\nresist\nresource\nresponse\nresult\nretire\nretreat\nreturn\nreunion\nreveal\nreview\nreward\nrhythm\nrib\nribbon\nrice\nrich\nride\nridge\nrifle\nright\nrigid\nring\nriot\nripple\nrisk\nritual\nrival\nriver\nroad\nroast\nrobot\nrobust\nrocket\nromance\nroof\nrookie\nroom\nrose\nrotate\nrough\nround\nroute\nroyal\nrubber\nrude\nrug\nrule\nrun\nrunway\nrural\nsad\nsaddle\nsadness\nsafe\nsail\nsalad\nsalmon\nsalon\nsalt\nsalute\nsame\nsample\nsand\nsatisfy\nsatoshi\nsauce\nsausage\nsave\nsay\nscale\nscan\nscare\nscatter\nscene\nscheme\nschool\nscience\nscissors\nscorpion\nscout\nscrap\nscreen\nscript\nscrub\nsea\nsearch\nseason\nseat\nsecond\nsecret\nsection\nsecurity\nseed\nseek\nsegment\nselect\nsell\nseminar\nsenior\nsense\nsentence\nseries\nservice\nsession\nsettle\nsetup\nseven\nshadow\nshaft\nshallow\nshare\nshed\nshell\nsheriff\nshield\nshift\nshine\nship\nshiver\nshock\nshoe\nshoot\nshop\nshort\nshoulder\nshove\nshrimp\nshrug\nshuffle\nshy\nsibling\nsick\nside\nsiege\nsight\nsign\nsilent\nsilk\nsilly\nsilver\nsimilar\nsimple\nsince\nsing\nsiren\nsister\nsituate\nsix\nsize\nskate\nsketch\nski\nskill\nskin\nskirt\nskull\nslab\nslam\nsleep\nslender\nslice\nslide\nslight\nslim\nslogan\nslot\nslow\nslush\nsmall\nsmart\nsmile\nsmoke\nsmooth\nsnack\nsnake\nsnap\nsniff\nsnow\nsoap\nsoccer\nsocial\nsock\nsoda\nsoft\nsolar\nsoldier\nsolid\nsolution\nsolve\nsomeone\nsong\nsoon\nsorry\nsort\nsoul\nsound\nsoup\nsource\nsouth\nspace\nspare\nspatial\nspawn\nspeak\nspecial\nspeed\nspell\nspend\nsphere\nspice\nspider\nspike\nspin\nspirit\nsplit\nspoil\nsponsor\nspoon\nsport\nspot\nspray\nspread\nspring\nspy\nsquare\nsqueeze\nsquirrel\nstable\nstadium\nstaff\nstage\nstairs\nstamp\nstand\nstart\nstate\nstay\nsteak\nsteel\nstem\nstep\nstereo\nstick\nstill\nsting\nstock\nstomach\nstone\nstool\nstory\nstove\nstrategy\nstreet\nstrike\nstrong\nstruggle\nstudent\nstuff\nstumble\nstyle\nsubject\nsubmit\nsubway\nsuccess\nsuch\nsudden\nsuffer\nsugar\nsuggest\nsuit\nsummer\nsun\nsunny\nsunset\nsuper\nsupply\nsupreme\nsure\nsurface\nsurge\nsurprise\nsurround\nsurvey\nsuspect\nsustain\nswallow\nswamp\nswap\nswarm\nswear\nsweet\nswift\nswim\nswing\nswitch\nsword\nsymbol\nsymptom\nsyrup\nsystem\ntable\ntackle\ntag\ntail\ntalent\ntalk\ntank\ntape\ntarget\ntask\ntaste\ntattoo\ntaxi\nteach\nteam\ntell\nten\ntenant\ntennis\ntent\nterm\ntest\ntext\nthank\nthat\ntheme\nthen\ntheory\nthere\nthey\nthing\nthis\nthought\nthree\nthrive\nthrow\nthumb\nthunder\nticket\ntide\ntiger\ntilt\ntimber\ntime\ntiny\ntip\ntired\ntissue\ntitle\ntoast\ntobacco\ntoday\ntoddler\ntoe\ntogether\ntoilet\ntoken\ntomato\ntomorrow\ntone\ntongue\ntonight\ntool\ntooth\ntop\ntopic\ntopple\ntorch\ntornado\ntortoise\ntoss\ntotal\ntourist\ntoward\ntower\ntown\ntoy\ntrack\ntrade\ntraffic\ntragic\ntrain\ntransfer\ntrap\ntrash\ntravel\ntray\ntreat\ntree\ntrend\ntrial\ntribe\ntrick\ntrigger\ntrim\ntrip\ntrophy\ntrouble\ntruck\ntrue\ntruly\ntrumpet\ntrust\ntruth\ntry\ntube\ntuition\ntumble\ntuna\ntunnel\nturkey\nturn\nturtle\ntwelve\ntwenty\ntwice\ntwin\ntwist\ntwo\ntype\ntypical\nugly\numbrella\nunable\nunaware\nuncle\nuncover\nunder\nundo\nunfair\nunfold\nunhappy\nuniform\nunique\nunit\nuniverse\nunknown\nunlock\nuntil\nunusual\nunveil\nupdate\nupgrade\nuphold\nupon\nupper\nupset\nurban\nurge\nusage\nuse\nused\nuseful\nuseless\nusual\nutility\nvacant\nvacuum\nvague\nvalid\nvalley\nvalve\nvan\nvanish\nvapor\nvarious\nvast\nvault\nvehicle\nvelvet\nvendor\nventure\nvenue\nverb\nverify\nversion\nvery\nvessel\nveteran\nviable\nvibrant\nvicious\nvictory\nvideo\nview\nvillage\nvintage\nviolin\nvirtual\nvirus\nvisa\nvisit\nvisual\nvital\nvivid\nvocal\nvoice\nvoid\nvolcano\nvolume\nvote\nvoyage\nwage\nwagon\nwait\nwalk\nwall\nwalnut\nwant\nwarfare\nwarm\nwarrior\nwash\nwasp\nwaste\nwater\nwave\nway\nwealth\nweapon\nwear\nweasel\nweather\nweb\nwedding\nweekend\nweird\nwelcome\nwest\nwet\nwhale\nwhat\nwheat\nwheel\nwhen\nwhere\nwhip\nwhisper\nwide\nwidth\nwife\nwild\nwill\nwin\nwindow\nwine\nwing\nwink\nwinner\nwinter\nwire\nwisdom\nwise\nwish\nwitness\nwolf\nwoman\nwonder\nwood\nwool\nword\nwork\nworld\nworry\nworth\nwrap\nwreck\nwrestle\nwrist\nwrite\nwrong\nyard\nyear\nyellow\nyou\nyoung\nyouth\nzebra\nzero\nzone\nzoo\n" + }, + { + "japanese", + "ã‚ã„ã“ãã—ã‚“\nã‚ã„ã•ã¤\nã‚ã„ãŸã‚™\nã‚ãŠã゙ら\nã‚ã‹ã¡ã‚ƒã‚“\nã‚ãã‚‹\nã‚ã‘ã‹ã‚™ãŸ\nã‚ã‘ã‚‹\nã‚ã“ã‹ã‚™ã‚Œã‚‹\nã‚ã•ã„\nã‚ã•ã²\nã‚ã—ã‚ã¨\nã‚ã—ã‚™ã‚ã†\nã‚ã™ã‚™ã‹ã‚‹\nã‚ã™ã‚™ã\nã‚ããµã‚™\nã‚ãŸãˆã‚‹\nã‚ãŸãŸã‚ã‚‹\nã‚ãŸã‚Šã¾ãˆ\nã‚ãŸã‚‹\nã‚ã¤ã„\nã‚ã¤ã‹ã†\nã‚ã£ã—ã‚…ã\nã‚ã¤ã¾ã‚Š\nã‚ã¤ã‚ã‚‹\nã‚ã¦ãª\nã‚ã¦ã¯ã¾ã‚‹\nã‚ã²ã‚‹\nã‚ãµã‚™ã‚‰\nã‚ãµã‚™ã‚‹\nã‚ãµã‚Œã‚‹\nã‚ã¾ã„\nã‚ã¾ã¨ã‚™\nã‚ã¾ã‚„ã‹ã™\nã‚ã¾ã‚Š\nã‚ã¿ã‚‚ã®\nã‚ã‚りã‹\nã‚ã‚„ã¾ã‚‹\nã‚ゆむ\nã‚らã„ãã‚™ã¾\nã‚らã—\nã‚らã™ã—ã‚™\nã‚らãŸã‚ã‚‹\nã‚らゆる\nã‚らã‚ã™\nã‚りã‹ã‚™ã¨ã†\nã‚ã‚ã›ã‚‹\nã‚ã‚ã¦ã‚‹\nã‚ã‚“ã„\nã‚ã‚“ã‹ã‚™ã„\nã‚ã‚“ã“\nã‚ã‚“ã›ã‚™ã‚“\nã‚ã‚“ã¦ã„\nã‚ã‚“ãªã„\nã‚ã‚“ã¾ã‚Š\nã„ã„ãŸã‚™ã™\nã„ãŠã‚“\nã„ã‹ã‚™ã„\nã„ã‹ã‚™ã\nã„ããŠã„\nã„ããªã‚Š\nã„ãã‚‚ã®\nã„ãã‚‹\nã„ãã—ã‚™\nã„ããµã‚™ã‚“\nã„ã‘ã¯ã‚™ãª\nã„ã‘ã‚“\nã„ã“ã†\nã„ã“ã\nã„ã“ã¤\nã„ã•ã¾ã—ã„\nã„ã•ã‚“\nã„ã—ã\nã„ã—゙ゅã†\nã„ã—゙ょã†\nã„ã—ã‚™ã‚ã‚‹\nã„ã™ã‚™ã¿\nã„ã™ã‚™ã‚Œ\nã„ã›ã„\nã„ã›ãˆã²ã‚™\nã„ã›ã‹ã„\nã„ã›ã\nã„ã›ã‚™ã‚“\nã„ãã†ã‚ã†\nã„ãã‹ã‚™ã—ã„\nã„ãŸã‚™ã„\nã„ãŸã‚™ã\nã„ãŸã™ã‚™ã‚‰\nã„ãŸã¿\nã„ãŸã‚Šã‚\nã„ã¡ãŠã†\nã„ã¡ã—ã‚™\nã„ã¡ã¨ã‚™\nã„ã¡ã¯ã‚™\nã„ã¡ãµã‚™\nã„ã¡ã‚Šã‚…ã†\nã„ã¤ã‹\nã„ã£ã—ã‚…ã‚“\nã„ã£ã›ã„\nã„ã£ãã†\nã„ã£ãŸã‚“\nã„ã£ã¡\nã„ã£ã¦ã„\nã„ã£ã»ã‚šã†\nã„ã¦ã•ã‚™\nã„ã¦ã‚“\nã„ã¨ã‚™ã†\nã„ã¨ã“\nã„ãªã„\nã„ãªã‹\nã„ã­ã‚€ã‚Š\nã„ã®ã¡\nã„ã®ã‚‹\nã„ã¯ã¤\nã„ã¯ã‚™ã‚‹\nã„ã¯ã‚“\nã„ã²ã‚™ã\nã„ã²ã‚“\nã„ãµã\nã„ã¸ã‚“\nã„ã»ã†\nã„ã¿ã‚“\nã„ã‚‚ã†ã¨\nã„ã‚‚ãŸã‚Œ\nã„もり\nã„ã‚„ã‹ã‚™ã‚‹\nã„ã‚„ã™\nã„よã‹ã‚“\nã„よã\nã„らã„\nã„らã™ã¨\nã„りãã‚™ã¡\nã„りょã†\nã„れã„\nã„れもã®\nã„れる\nã„ã‚ãˆã‚“ã²ã‚šã¤\nã„ã‚ã„\nã„ã‚ã†\nã„ã‚ã‹ã‚“\nã„ã‚ã¯ã‚™\nã„ã‚ゆる\nã„ã‚“ã‘゙んã¾ã‚\nã„ã‚“ã•ã¤\nã„ã‚“ã—ょã†\nã„んよã†\nã†ãˆã\nã†ãˆã‚‹\nã†ãŠã•ã‚™\nã†ã‹ã‚™ã„\nã†ã‹ãµã‚™\nã†ã‹ã¸ã‚™ã‚‹\nã†ãã‚\nã†ãらã„ãª\nã†ãれれ\nã†ã‘ãŸã¾ã‚ã‚‹\nã†ã‘ã¤ã‘\nã†ã‘ã¨ã‚‹\nã†ã‘ã‚‚ã¤\nã†ã‘ã‚‹\nã†ã“ã‚™ã‹ã™\nã†ã“ã‚™ã\nã†ã“ã‚“\nã†ã•ãã‚™\nã†ã—ãªã†\nã†ã—ã‚ã‹ã‚™ã¿\nã†ã™ã„\nã†ã™ãã‚™\nã†ã™ã゙らã„\nã†ã™ã‚ã‚‹\nã†ã›ã¤\nã†ã¡ã‚ã‚ã›\nã†ã¡ã‹ã‚™ã‚\nã†ã¡ã\nã†ã¡ã‚…ã†\nã†ã£ã‹ã‚Š\nã†ã¤ãã—ã„\nã†ã£ãŸãˆã‚‹\nã†ã¤ã‚‹\nã†ã¨ã‚™ã‚“\nã†ãªãã‚™\nã†ãªã—ã‚™\nã†ãªã™ã‚™ã\nã†ãªã‚‹\nã†ã­ã‚‹\nã†ã®ã†\nã†ãµã‚™ã‘ã‚™\nã†ãµã‚™ã“ã‚™ãˆ\nã†ã¾ã‚Œã‚‹\nã†ã‚ã‚‹\nã†ã‚‚ã†\nã†ã‚„ã¾ã†\nã†ã‚ˆã\nã†ã‚‰ã‹ã‚™ãˆã™\nã†ã‚‰ãã‚™ã¡\nã†ã‚‰ãªã„\nã†ã‚Šã‚ã‘ã‚™\nã†ã‚Šãれ\nã†ã‚‹ã•ã„\nã†ã‚Œã—ã„\nã†ã‚Œã‚†ã\nã†ã‚Œã‚‹\nã†ã‚ã“\nã†ã‚ã\nã†ã‚ã•\nã†ã‚“ã“ã†\nã†ã‚“ã¡ã‚“\nã†ã‚“ã¦ã‚“\nã†ã‚“ã¨ã‚™ã†\nãˆã„ãˆã‚“\nãˆã„ã‹ã‚™\nãˆã„ãょã†\nãˆã„ã“ã‚™\nãˆã„ã›ã„\nãˆã„ãµã‚™ã‚“\nãˆã„よã†\nãˆã„ã‚\nãˆãŠã‚Š\nãˆã‹ã‚™ãŠ\nãˆã‹ã‚™ã\nãˆããŸã„\nãˆãã›ã‚‹\nãˆã—ゃã\nãˆã™ã¦\nãˆã¤ã‚‰ã‚“\nãˆã®ãã‚™\nãˆã»ã†ã¾ã\nãˆã»ã‚“\nãˆã¾ã\nãˆã‚‚ã—ã‚™\nãˆã‚‚ã®\nãˆã‚‰ã„\nãˆã‚‰ãµã‚™\nãˆã‚Šã‚\nãˆã‚“ãˆã‚“\nãˆã‚“ã‹ã„\nãˆã‚“ãã‚™\nãˆã‚“ã‘ã‚™ã\nãˆã‚“ã—ã‚…ã†\nãˆã‚“ã›ã‚™ã¤\nãˆã‚“ãã\nãˆã‚“ã¡ã‚‡ã†\nãˆã‚“ã¨ã¤\nãŠã„ã‹ã‘ã‚‹\nãŠã„ã“ã™\nãŠã„ã—ã„\nãŠã„ã¤ã\nãŠã†ãˆã‚“\nãŠã†ã•ã¾\nãŠã†ã—ã‚™\nãŠã†ã›ã¤\nãŠã†ãŸã„\nãŠã†ãµã\nãŠã†ã¸ã‚™ã„\nãŠã†ã‚ˆã†\nãŠãˆã‚‹\nãŠãŠã„\nãŠãŠã†\nãŠãŠã¨ã‚™ãŠã‚Š\nãŠãŠã‚„\nãŠãŠã‚ˆã\nãŠã‹ãˆã‚Š\nãŠã‹ã™ã‚™\nãŠã‹ã‚™ã‚€\nãŠã‹ã‚り\nãŠãã‚™ãªã†\nãŠãã‚‹\nãŠãã•ã¾\nãŠãã—゙ょã†\nãŠãりã‹ã‚™ãª\nãŠãã‚‹\nãŠãれる\nãŠã“ã™\nãŠã“ãªã†\nãŠã“ã‚‹\nãŠã•ãˆã‚‹\nãŠã•ãªã„\nãŠã•ã‚ã‚‹\nãŠã—ã„れ\nãŠã—ãˆã‚‹\nãŠã—ã‚™ãã‚™\nãŠã—ã‚™ã•ã‚“\nãŠã—ゃれ\nãŠãらã\nãŠãã‚ã‚‹\nãŠãŸã‹ã‚™ã„\nãŠãŸã\nãŠãŸã‚™ã‚„ã‹\nãŠã¡ã¤ã\nãŠã£ã¨\nãŠã¤ã‚Š\nãŠã¦ã‚™ã‹ã‘\nãŠã¨ã—ã‚‚ã®\nãŠã¨ãªã—ã„\nãŠã¨ã‚™ã‚Š\nãŠã¨ã‚™ã‚ã‹ã™\nãŠã¯ã‚™ã•ã‚“\nãŠã¾ã„り\nãŠã‚ã¦ã‚™ã¨ã†\nãŠã‚‚ã„ã¦ã‚™\nãŠã‚‚ã†\nãŠã‚‚ãŸã„\nãŠã‚‚ã¡ã‚ƒ\nãŠã‚„ã¤\nãŠã‚„ゆã²ã‚™\nãŠã‚ˆã»ã‚™ã™\nãŠã‚‰ã‚“ãŸã‚™\nãŠã‚ã™\nãŠã‚“ã‹ã‚™ã\nãŠã‚“ã‘ã„\nãŠã‚“ã—ゃ\nãŠã‚“ã›ã‚“\nãŠã‚“ãŸã‚™ã‚“\nãŠã‚“ã¡ã‚…ã†\nãŠã‚“ã¨ã‚™ã‘ã„\nã‹ã‚ã¤\nã‹ã„ã‹ã‚™\nã‹ã‚™ã„ã\nã‹ã‚™ã„ã‘ã‚“\nã‹ã‚™ã„ã“ã†\nã‹ã„ã•ã¤\nã‹ã„ã—ゃ\nã‹ã„ã™ã„よã\nã‹ã„ã›ã‚™ã‚“\nã‹ã„ãã‚™ã†ã¨ã‚™\nã‹ã„ã¤ã†\nã‹ã„ã¦ã‚“\nã‹ã„ã¨ã†\nã‹ã„ãµã\nã‹ã‚™ã„ã¸ã\nã‹ã„ã»ã†\nã‹ã„よã†\nã‹ã‚™ã„らã„\nã‹ã„ã‚\nã‹ãˆã‚‹\nã‹ãŠã‚Š\nã‹ã‹ãˆã‚‹\nã‹ã‹ã‚™ã\nã‹ã‹ã‚™ã—\nã‹ã‹ã‚™ã¿\nã‹ãã“ã‚™\nã‹ãã¨ã\nã‹ã•゙る\nã‹ã‚™ãã‚™ã†\nã‹ãŸã„\nã‹ãŸã¡\nã‹ã‚™ã¡ã‚‡ã†\nã‹ã‚™ã£ãã‚…ã†\nã‹ã‚™ã£ã“ã†\nã‹ã‚™ã£ã•ã‚“\nã‹ã‚™ã£ã—ょã†\nã‹ãªã•ã‚™ã‚ã—\nã‹ã®ã†\nã‹ã‚™ã¯ã\nã‹ãµã‚™ã‹\nã‹ã»ã†\nã‹ã»ã“ã‚™\nã‹ã¾ã†\nã‹ã¾ã»ã‚™ã“\nã‹ã‚れãŠã‚“\nã‹ã‚†ã„\nã‹ã‚ˆã†ã²ã‚™\nã‹ã‚‰ã„\nã‹ã‚‹ã„\nã‹ã‚ã†\nã‹ã‚ã\nã‹ã‚ら\nã‹ã‚™ã‚“ã‹\nã‹ã‚“ã‘ã„\nã‹ã‚“ã“ã†\nã‹ã‚“ã—ゃ\nã‹ã‚“ãã†\nã‹ã‚“ãŸã‚“\nã‹ã‚“ã¡\nã‹ã‚™ã‚“ã¯ã‚™ã‚‹\nãã‚ã„\nãã‚ã¤\nãã„ã‚\nãã‚™ã„ã‚“\nãã†ã„\nãã†ã‚“\nããˆã‚‹\nããŠã†\nããŠã\nããŠã¡\nããŠã‚“\nãã‹ã„\nãã‹ã\nãã‹ã‚“ã—ゃ\nããã¦\nããã¯ã‚™ã‚Š\nããらã‘ã‚™\nãã‘ã‚“ã›ã„\nãã“ã†\nãã“ãˆã‚‹\nãã“ã\nãã•ã„\nãã•ã\nãã•ã¾\nãã•らãã‚™\nãã‚™ã—ã‚™ã‹ã‹ã‚™ã\nãã‚™ã—ã\nãã‚™ã—ã‚™ãŸã„ã‘ã‚“\nãã‚™ã—ã‚™ã«ã£ã¦ã„\nãã‚™ã—゙ゅã¤ã—ゃ\nãã™ã†\nãã›ã„\nãã›ã\nãã›ã¤\nããã†\nããã‚™ã\nãã゙ん\nããŸãˆã‚‹\nãã¡ã‚‡ã†\nãã¤ãˆã‚“\nãã‚™ã£ã¡ã‚Š\nãã¤ã¤ã\nãã¤ã­\nãã¦ã„\nãã¨ã‚™ã†\nãã¨ã‚™ã\nããªã„\nããªã‹ã‚™\nããªã“\nãã¬ã“ã‚™ã—\nãã­ã‚“\nãã®ã†\nãã®ã—ãŸ\nãã¯ã\nãã²ã‚™ã—ã„\nãã²ã‚“\nããµã\nããµã‚™ã‚“\nãã»ã‚™ã†\nãã»ã‚“\nãã¾ã‚‹\nãã¿ã¤\nãã‚€ã™ã‚™ã‹ã—ã„\nãã‚ã‚‹\nãã‚‚ãŸã‚™ã‚ã—\nãã‚‚ã¡\nãã‚‚ã®\nãゃã\nãã‚„ã\nã゙ゅã†ã«ã\nãよã†\nãょã†ã‚Šã‚…ã†\nãらã„\nãらã\nãりん\nãれã„\nãれã¤\nãã‚ã\nãã‚™ã‚ã‚“\nãã‚ã‚ã‚‹\nã゙んã„ã‚\nãã‚“ã‹ãã—ã‚™\nãã‚“ã—゙ょ\nãんよã†ã²ã‚™\nãã‚™ã‚ã„\nãã„ã™ã‚™\nãã†ã‹ã‚“\nãã†ã\nãã†ã゙ん\nãã†ã“ã†\nãã‚™ã†ã›ã„\nãã†ãã†\nãã‚™ã†ãŸã‚‰\nãã†ãµã\nãã†ã»ã‚™\nãã‹ã‚“\nããょã†\nãã‘゙ん\nãã‚™ã“ã†\nãã•ã„\nãã•ã\nãã•ã¯ã‚™ãª\nãã•ã‚‹\nãã—ゃã¿\nãã—ょã†\nãã™ã®ã\nãã™ã‚Šã‚†ã²ã‚™\nãã›ã‘ã‚™\nãã›ã‚“\nãã‚™ãŸã„ã¦ã\nããŸã‚™ã•ã‚‹\nããŸã²ã‚™ã‚Œã‚‹\nãã¡ã“ã¿\nãã¡ã•ã\nãã¤ã—ãŸ\nãã‚™ã£ã™ã‚Š\nãã¤ã‚ãã‚™\nãã¨ã†ã¦ã‚“\nãã¨ã‚™ã\nããªã‚“\nãã­ãã­\nãã®ã†\nããµã†\nãã¿ã‚ã‚ã›\nãã¿ãŸã¦ã‚‹\nãã‚ã‚‹\nãã‚„ãã—ょ\nãらã™\nãらã¸ã‚™ã‚‹\nãã‚‹ã¾\nãれる\nãã‚ã†\nãã‚ã—ã„\nã゙んã‹ã‚“\nã゙んã—ょã\nã゙んãŸã„\nã゙んã¦\nã‘ã‚ãª\nã‘ã„ã‹ã\nã‘ã„ã‘ã‚“\nã‘ã„ã“\nã‘ã„ã•ã¤\nã‘ã‚™ã„ã—゙ゅã¤\nã‘ã„ãŸã„\nã‘ã‚™ã„ã®ã†ã—゙ん\nã‘ã„れã\nã‘ã„ã‚\nã‘ãŠã¨ã™\nã‘ãŠã‚Šã‚‚ã®\nã‘ã‚™ãã‹\nã‘ã‚™ãã‘゙ん\nã‘ã‚™ããŸã‚™ã‚“\nã‘ã‚™ãã¡ã‚“\nã‘ã‚™ãã¨ã¤\nã‘ã‚™ãã¯\nã‘ã‚™ãã‚„ã\nã‘ã‚™ã“ã†\nã‘ã‚™ã“ãã—゙ょã†\nã‘ã‚™ã•ã‚™ã„\nã‘ã•ã\nã‘ã‚™ã•゙ん\nã‘ã—ã\nã‘ã—ã“゙む\nã‘ã—ょã†\nã‘ã‚™ã™ã¨\nã‘ãŸã¯ã‚™\nã‘ã¡ã‚ƒã£ãµã‚š\nã‘ã¡ã‚‰ã™\nã‘ã¤ã‚ã¤\nã‘ã¤ã„\nã‘ã¤ãˆã\nã‘ã£ã“ã‚“\nã‘ã¤ã—゙ょ\nã‘ã£ã›ã\nã‘ã£ã¦ã„\nã‘ã¤ã¾ã¤\nã‘ã‚™ã¤ã‚ˆã†ã²ã‚™\nã‘ã‚™ã¤ã‚Œã„\nã‘ã¤ã‚ã‚“\nã‘ã‚™ã¨ã‚™ã\nã‘ã¨ã¯ã‚™ã™\nã‘ã¨ã‚‹\nã‘ãªã‘ã‚™\nã‘ãªã™\nã‘ãªã¿\nã‘ã¬ã\nã‘ã‚™ã­ã¤\nã‘ã­ã‚“\nã‘ã¯ã„\nã‘ã‚™ã²ã‚“\nã‘ãµã‚™ã‹ã„\nã‘ã‚™ã»ã‚™ã\nã‘ã¾ã‚Š\nã‘ã¿ã‹ã‚‹\nã‘ã‚€ã—\nã‘むり\nã‘ã‚‚ã®\nã‘らã„\nã‘ã‚ã‘ã‚\nã‘ã‚ã—ã„\nã‘ã‚“ã„\nã‘ã‚“ãˆã¤\nã‘ã‚“ãŠ\nã‘ã‚“ã‹\nã‘゙んã\nã‘ã‚“ã‘゙ん\nã‘ã‚“ã“ã†\nã‘ã‚“ã•ã\nã‘ã‚“ã—ã‚…ã†\nã‘ã‚“ã™ã†\nã‘゙んãã†\nã‘ã‚“ã¡ã\nã‘ã‚“ã¦ã„\nã‘ã‚“ã¨ã†\nã‘ã‚“ãªã„\nã‘ã‚“ã«ã‚“\nã‘゙んãµã‚™ã¤\nã‘ã‚“ã¾\nã‘ã‚“ã¿ã‚“\nã‘ã‚“ã‚ã„\nã‘んらん\nã‘んり\nã“ã‚ãã¾\nã“ã„ã¬\nã“ã„ã²ã‚™ã¨\nã“ã‚™ã†ã„\nã“ã†ãˆã‚“\nã“ã†ãŠã‚“\nã“ã†ã‹ã‚“\nã“ã‚™ã†ãã‚…ã†\nã“ã‚™ã†ã‘ã„\nã“ã†ã“ã†\nã“ã†ã•ã„\nã“ã†ã—ã‚™\nã“ã†ã™ã„\nã“ã‚™ã†ã›ã„\nã“ã†ãã\nã“ã†ãŸã„\nã“ã†ã¡ã‚ƒ\nã“ã†ã¤ã†\nã“ã†ã¦ã„\nã“ã†ã¨ã‚™ã†\nã“ã†ãªã„\nã“ã†ã¯ã„\nã“ã‚™ã†ã»ã†\nã“ã‚™ã†ã¾ã‚“\nã“ã†ã‚‚ã\nã“ã†ã‚Šã¤\nã“ãˆã‚‹\nã“ãŠã‚Š\nã“ã‚™ã‹ã„\nã“ã‚™ã‹ã‚™ã¤\nã“ã‚™ã‹ã‚“\nã“ãã“ã‚™\nã“ãã•ã„\nã“ãã¨ã†\nã“ããªã„\nã“ãã¯ã\nã“ãã‚™ã¾\nã“ã‘ã„\nã“ã‘ã‚‹\nã“ã“ã®ã‹\nã“ã“ã‚\nã“ã•ã‚\nã“ã—ã¤\nã“ã™ã†\nã“ã›ã„\nã“ã›ã\nã“ã›ã‚™ã‚“\nã“ããŸã‚™ã¦\nã“ãŸã„\nã“ãŸãˆã‚‹\nã“ãŸã¤\nã“ã¡ã‚‡ã†\nã“ã£ã‹\nã“ã¤ã“ã¤\nã“ã¤ã¯ã‚™ã‚“\nã“ã¤ãµã‚™\nã“ã¦ã„\nã“ã¦ã‚“\nã“ã¨ã‹ã‚™ã‚‰\nã“ã¨ã—\nã“ã¨ã¯ã‚™\nã“ã¨ã‚Š\nã“ãªã“ã‚™ãª\nã“ã­ã“ã­\nã“ã®ã¾ã¾\nã“ã®ã¿\nã“ã®ã‚ˆ\nã“ã‚™ã¯ã‚“\nã“ã²ã¤ã—ã‚™\nã“ãµã†\nã“ãµã‚“\nã“ã»ã‚™ã‚Œã‚‹\nã“ã‚™ã¾ã‚ãµã‚™ã‚‰\nã“ã¾ã‹ã„\nã“ã‚™ã¾ã™ã‚Š\nã“ã¾ã¤ãª\nã“ã¾ã‚‹\nã“ã‚€ãã‚™ã“\nã“ã‚‚ã—ã‚™\nã“ã‚‚ã¡\nã“ã‚‚ã®\nã“ã‚‚ã‚“\nã“ã‚„ã\nã“ã‚„ã¾\nã“ゆã†\nã“ゆã²ã‚™\nã“よã„\nã“よã†\nã“りる\nã“れãã—ょん\nã“ã‚ã£ã‘\nã“ã‚ã‚‚ã¦\nã“ã‚れる\nã“ã‚“ã„ã‚“\nã“ã‚“ã‹ã„\nã“ã‚“ã\nã“ã‚“ã—ã‚…ã†\nã“ã‚“ã™ã„\nã“ã‚“ãŸã‚™ã¦\nã“ã‚“ã¨ã‚“\nã“ã‚“ãªã‚“\nã“ã‚“ã²ã‚™ã«\nã“ã‚“ã»ã‚šã‚“\nã“ã‚“ã¾ã‘\nã“ã‚“ã‚„\nã“んれã„\nã“ã‚“ã‚ã\nã•ã‚™ã„ãˆã\nã•ã„ã‹ã„\nã•ã„ãã‚“\nã•ã‚™ã„ã‘゙ん\nã•ã‚™ã„ã“\nã•ã„ã—ょ\nã•ã„ã›ã„\nã•ã‚™ã„ãŸã\nã•ã‚™ã„ã¡ã‚…ã†\nã•ã„ã¦ã\nã•ã‚™ã„りょã†\nã•ã†ãª\nã•ã‹ã„ã—\nã•ã‹ã‚™ã™\nã•ã‹ãª\nã•ã‹ã¿ã¡\nã•ã‹ã‚™ã‚‹\nã•ã゙ょã†\nã•ãã—\nã•ãã²ã‚“\nã•ãら\nã•ã“ã\nã•ã“ã¤\nã•ã™ã‚™ã‹ã‚‹\nã•ã‚™ã›ã\nã•ãŸã‚“\nã•ã¤ãˆã„\nã•ã‚™ã¤ãŠã‚“\nã•ã‚™ã£ã‹\nã•ã‚™ã¤ã‹ã‚™ã\nã•ã£ãょã\nã•ã‚™ã£ã—\nã•ã¤ã—゙ん\nã•ã‚™ã£ãã†\nã•ã¤ãŸã¯ã‚™\nã•ã¤ã¾ã„ã‚‚\nã•ã¦ã„\nã•ã¨ã„ã‚‚\nã•ã¨ã†\nã•ã¨ãŠã‚„\nã•ã¨ã—\nã•ã¨ã‚‹\nã•ã®ã†\nã•ã¯ã‚™ã\nã•ã²ã‚™ã—ã„\nã•ã¸ã‚™ã¤\nã•ã»ã†\nã•ã»ã¨ã‚™\nã•ã¾ã™\nã•ã¿ã—ã„\nã•ã¿ãŸã‚™ã‚Œ\nã•ã‚€ã‘\nã•ã‚ã‚‹\nã•ã‚„ãˆã‚“ã¨ã‚™ã†\nã•ゆã†\nã•よã†\nã•よã\nã•らãŸã‚™\nã•゙るãã¯ã‚™\nã•ã‚ã‚„ã‹\nã•ã‚ã‚‹\nã•ã‚“ã„ã‚“\nã•ã‚“ã‹\nã•ã‚“ãゃã\nã•ã‚“ã“ã†\nã•ã‚“ã•ã„\nã•゙んã—ょ\nã•ã‚“ã™ã†\nã•ã‚“ã›ã„\nã•ã‚“ã\nã•ã‚“ã¡\nã•ã‚“ã¾\nã•ã‚“ã¿\nã•んらん\nã—ã‚ã„\nã—ã‚ã‘ã‚™\nã—ã‚ã•ã£ã¦\nã—ã‚ã‚ã›\nã—ã„ã\nã—ã„ã‚“\nã—ã†ã¡\nã—ãˆã„\nã—ãŠã‘\nã—ã‹ã„\nã—ã‹ã\nã—ã‚™ã‹ã‚“\nã—ã“ã‚™ã¨\nã—ã™ã†\nã—ã‚™ãŸã‚™ã„\nã—ãŸã†ã‘\nã—ãŸãã‚™\nã—ãŸã¦\nã—ãŸã¿\nã—ã¡ã‚‡ã†\nã—ã¡ã‚Šã‚“\nã—ã£ã‹ã‚Š\nã—ã¤ã—ã‚™\nã—ã¤ã‚‚ã‚“\nã—ã¦ã„\nã—ã¦ã\nã—ã¦ã¤\nã—ã‚™ã¦ã‚“\nã—ã‚™ã¨ã‚™ã†\nã—ãªã゙れ\nã—ãªã‚‚ã®\nã—ãªã‚“\nã—ã­ã¾\nã—ã­ã‚“\nã—ã®ãã‚™\nã—ã®ãµã‚™\nã—ã¯ã„\nã—ã¯ã‚™ã‹ã‚Š\nã—ã¯ã¤\nã—ã¯ã‚‰ã„\nã—ã¯ã‚“\nã—ã²ã‚‡ã†\nã—ãµã\nã—ã‚™ãµã‚™ã‚“\nã—ã¸ã„\nã—ã»ã†\nã—ã»ã‚“\nã—ã¾ã†\nã—ã¾ã‚‹\nã—ã¿ã‚“\nã—ã‚€ã‘ã‚‹\nã—゙むã—ょ\nã—ã‚ã„\nã—ã‚ã‚‹\nã—ã‚‚ã‚“\nã—ゃã„ã‚“\nã—ゃã†ã‚“\nã—ゃãŠã‚“\nã—゙ゃã‹ã‚™ã„ã‚‚\nã—ã‚„ãã—ょ\nã—ゃãã»ã†\nã—ゃã‘ã‚“\nã—ゃã“\nã—ゃã•ã‚™ã„\nã—ゃã—ã‚“\nã—ゃã›ã‚“\nã—ゃãã†\nã—ゃãŸã„\nã—ゃã¡ã‚‡ã†\nã—ゃã£ãã‚“\nã—゙ゃã¾\nã—ゃりん\nã—ゃれã„\nã—゙ゆã†\nã—゙ゅã†ã—ょ\nã—ã‚…ãã¯ã\nã—゙ゅã—ã‚“\nã—ã‚…ã£ã›ã\nã—ã‚…ã¿\nã—ゅらã¯ã‚™\nã—゙ゅんã¯ã‚™ã‚“\nã—ょã†ã‹ã„\nã—ょããŸã\nã—ょã£ã‘ã‚“\nã—ょã¨ã‚™ã†\nã—ょもã¤\nã—らã›ã‚‹\nã—らã¸ã‚™ã‚‹\nã—ã‚“ã‹\nã—ã‚“ã“ã†\nã—゙んã—゙ゃ\nã—ã‚“ã›ã„ã—ã‚™\nã—ã‚“ã¡ã\nã—んりん\nã™ã‚ã‘ã‚™\nã™ã‚ã—\nã™ã‚ãª\nã™ã‚™ã‚ã‚“\nã™ã„ãˆã„\nã™ã„ã‹\nã™ã„ã¨ã†\nã™ã‚™ã„ãµã‚™ã‚“\nã™ã„よã†ã²ã‚™\nã™ã†ã‹ã‚™ã\nã™ã†ã—ã‚™ã¤\nã™ã†ã›ã‚“\nã™ãŠã¨ã‚™ã‚Š\nã™ãã¾\nã™ãã†\nã™ããªã„\nã™ã‘ã‚‹\nã™ã“ã‚™ã„\nã™ã“ã—\nã™ã‚™ã•ã‚“\nã™ã™ã‚™ã—ã„\nã™ã™ã‚€\nã™ã™ã‚ã‚‹\nã™ã£ã‹ã‚Š\nã™ã‚™ã£ã—り\nã™ã‚™ã£ã¨\nã™ã¦ã\nã™ã¦ã‚‹\nã™ã­ã‚‹\nã™ã®ã“\nã™ã¯ãŸã‚™\nã™ã¯ã‚™ã‚‰ã—ã„\nã™ã‚™ã²ã‚‡ã†\nã™ã‚™ãµã‚™ã¬ã‚Œ\nã™ãµã‚™ã‚Š\nã™ãµã‚Œ\nã™ã¸ã‚™ã¦\nã™ã¸ã‚™ã‚‹\nã™ã‚™ã»ã†\nã™ã»ã‚™ã‚“\nã™ã¾ã„\nã™ã‚ã—\nã™ã‚‚ã†\nã™ã‚„ã\nã™ã‚‰ã™ã‚‰\nã™ã‚‹ã‚\nã™ã‚Œã¡ã‹ã‚™ã†\nã™ã‚ã£ã¨\nã™ã‚ã‚‹\nã™ã‚“ã›ã‚™ã‚“\nã™ã‚“ã»ã‚šã†\nã›ã‚ãµã‚™ã‚‰\nã›ã„ã‹ã¤\nã›ã„ã‘゙ん\nã›ã„ã—ã‚™\nã›ã„よã†\nã›ãŠã†\nã›ã‹ã„ã‹ã‚“\nã›ãã«ã‚“\nã›ãã‚€\nã›ãゆ\nã›ãらんã†ã‚“\nã›ã‘ã‚“\nã›ã“ã†\nã›ã™ã—ã‚™\nã›ãŸã„\nã›ãŸã‘\nã›ã£ã‹ã\nã›ã£ãゃã\nã›ã‚™ã£ã\nã›ã£ã‘ã‚“\nã›ã£ã“ã¤\nã›ã£ã•ãŸãã¾\nã›ã¤ãã‚™ã\nã›ã¤ãŸã‚™ã‚“\nã›ã¤ã¦ã‚™ã‚“\nã›ã£ã¯ã‚šã‚“\nã›ã¤ã²ã‚™\nã›ã¤ãµã‚™ã‚“\nã›ã¤ã‚ã„\nã›ã¤ã‚Šã¤\nã›ãªã‹\nã›ã®ã²ã‚™\nã›ã¯ã¯ã‚™\nã›ã²ã‚™ã‚\nã›ã»ã‚™ã­\nã›ã¾ã„\nã›ã¾ã‚‹\nã›ã‚ã‚‹\nã›ã‚‚ãŸã‚Œ\nã›ã‚Šãµ\nã›ã‚™ã‚“ã‚ã\nã›ã‚“ã„\nã›ã‚“ãˆã„\nã›ã‚“ã‹\nã›ã‚“ãょ\nã›ã‚“ã\nã›ã‚“ã‘゙ん\nã›ã‚™ã‚“ã“ã‚™\nã›ã‚“ã•ã„\nã›ã‚“ã—ã‚…\nã›ã‚“ã™ã„\nã›ã‚“ã›ã„\nã›ã‚“ãã‚™\nã›ã‚“ãŸã\nã›ã‚“ã¡ã‚‡ã†\nã›ã‚“ã¦ã„\nã›ã‚“ã¨ã†\nã›ã‚“ã¬ã\nã›ã‚“ã­ã‚“\nã›ã‚“ã¯ã‚šã„\nã›ã‚™ã‚“ãµã‚™\nã›ã‚™ã‚“ã»ã‚šã†\nã›ã‚“ã‚€\nã›ã‚“ã‚ã‚“ã—゙ょ\nã›ã‚“ã‚‚ã‚“\nã›ã‚“ã‚„ã\nã›ã‚“ゆã†\nã›ã‚“よã†\nã›ã‚™ã‚“ら\nã›ã‚™ã‚“りゃã\nã›ã‚“れã„\nã›ã‚“ã‚\nãã‚ã\nãã„ã¨ã‘゙る\nãã„ã­\nãã†ã‹ã‚™ã‚“ãょã†\nãã†ã\nãã†ã“ã‚™\nãã†ã—ã‚“\nãã†ãŸã‚™ã‚“\nãã†ãªã‚“\nãã†ã²ã‚™\nãã†ã‚ã‚“\nãã†ã‚Š\nããˆã‚‚ã®\nããˆã‚“\nãã‹ã‚™ã„\nãã‘ã‚™ã\nãã“ã†\nãã“ãã“\nãã•ã‚™ã„\nãã—ãª\nãã›ã„\nãã›ã‚“\nãããã‚™\nããŸã‚™ã¦ã‚‹\nãã¤ã†\nãã¤ãˆã‚“\nãã£ã‹ã‚“\nãã¤ã゙ょã†\nãã£ã‘ã¤\nãã£ã“ã†\nãã£ã›ã‚“\nãã£ã¨\nãã¨ã‹ã‚™ã‚\nãã¨ã¤ã‚™ã‚‰\nããªãˆã‚‹\nããªãŸ\nããµã»ã‚™\nãã»ã‚™ã\nãã»ã‚™ã‚\nãã¾ã¤\nãã¾ã‚‹\nãã‚€ã\nãむりãˆ\nãã‚ã‚‹\nãã‚‚ãã‚‚\nãよã‹ã›ã‚™\nãらã¾ã‚\nãã‚ã†\nãã‚“ã‹ã„\nãã‚“ã‘ã„\nãã‚“ã•ã‚™ã„\nãã‚“ã—ã¤\nãã‚“ãã‚™ã\nãã‚“ã¡ã‚‡ã†\nã゙んã²ã‚™\nã゙んãµã‚™ã‚“\nãã‚“ã¿ã‚“\nãŸã‚ã„\nãŸã„ã„ã‚“\nãŸã„ã†ã‚“\nãŸã„ãˆã\nãŸã„ãŠã†\nãŸã‚™ã„ã‹ã‚™ã\nãŸã„ã\nãŸã„ãã‚™ã†\nãŸã„ã‘ã‚“\nãŸã„ã“\nãŸã„ã•ã‚™ã„\nãŸã‚™ã„ã—゙ょã†ãµã‚™\nãŸã‚™ã„ã™ã\nãŸã„ã›ã¤\nãŸã„ãã†\nãŸã‚™ã„ãŸã„\nãŸã„ã¡ã‚‡ã†\nãŸã„ã¦ã„\nãŸã‚™ã„ã¨ã‚™ã“ã‚\nãŸã„ãªã„\nãŸã„ã­ã¤\nãŸã„ã®ã†\nãŸã„ã¯ã‚“\nãŸã‚™ã„ã²ã‚‡ã†\nãŸã„ãµã†\nãŸã„ã¸ã‚“\nãŸã„ã»\nãŸã„ã¾ã¤ã¯ã‚™ãª\nãŸã„ã¿ã‚“ãã‚™\nãŸã„ã‚€\nãŸã„ã‚ã‚“\nãŸã„ã‚„ã\nãŸã„よã†\nãŸã„ら\nãŸã„りょã\nãŸã„ã‚‹\nãŸã„ã‚ã‚“\nãŸã†ãˆ\nãŸãˆã‚‹\nãŸãŠã™\nãŸãŠã‚‹\nãŸãŠã‚Œã‚‹\nãŸã‹ã„\nãŸã‹ã­\nãŸãã²ã‚™\nãŸãã•ã‚“\nãŸã“ã\nãŸã“ã‚„ã\nãŸã•ã„\nãŸã—ã•゙ん\nãŸã‚™ã—゙ゃれ\nãŸã™ã‘ã‚‹\nãŸã™ã‚™ã•ã‚ã‚‹\nãŸãã‹ã‚™ã‚Œ\nãŸãŸã‹ã†\nãŸãŸã\nãŸãŸã‚™ã—ã„\nãŸãŸã¿\nãŸã¡ã¯ã‚™ãª\nãŸã‚™ã£ã‹ã„\nãŸã‚™ã£ãゃã\nãŸã‚™ã£ã“\nãŸã‚™ã£ã—ã‚…ã¤\nãŸã‚™ã£ãŸã„\nãŸã¦ã‚‹\nãŸã¨ãˆã‚‹\nãŸãªã¯ã‚™ãŸ\nãŸã«ã‚“\nãŸã¬ã\nãŸã®ã—ã¿\nãŸã¯ã¤\nãŸãµã‚™ã‚“\nãŸã¸ã‚™ã‚‹\nãŸã»ã‚™ã†\nãŸã¾ã“ã‚™\nãŸã¾ã‚‹\nãŸã‚™ã‚€ã‚‹\nãŸã‚ã„ã\nãŸã‚ã™\nãŸã‚ã‚‹\nãŸã‚‚ã¤\nãŸã‚„ã™ã„\nãŸã‚ˆã‚‹\nãŸã‚‰ã™\nãŸã‚Šãã»ã‚“ã‹ã‚™ã‚“\nãŸã‚Šã‚‡ã†\nãŸã‚Šã‚‹\nãŸã‚‹ã¨\nãŸã‚Œã‚‹\nãŸã‚Œã‚“ã¨\nãŸã‚ã£ã¨\nãŸã‚むれる\nãŸã‚™ã‚“ã‚ã¤\nãŸã‚“ã„\nãŸã‚“ãŠã‚“\nãŸã‚“ã‹\nãŸã‚“ã\nãŸã‚“ã‘ã‚“\nãŸã‚“ã“ã‚™\nãŸã‚“ã•ã‚“\nãŸã‚“ã—゙ょã†ã²ã‚™\nãŸã‚™ã‚“ã›ã„\nãŸã‚“ãã\nãŸã‚“ãŸã„\nãŸã‚™ã‚“ã¡\nãŸã‚“ã¦ã„\nãŸã‚“ã¨ã†\nãŸã‚™ã‚“ãª\nãŸã‚“ã«ã‚“\nãŸã‚™ã‚“ã­ã¤\nãŸã‚“ã®ã†\nãŸã‚“ã²ã‚šã‚“\nãŸã‚™ã‚“ã»ã‚™ã†\nãŸã‚“ã¾ã¤\nãŸã‚“ã‚ã„\nãŸã‚™ã‚“れã¤\nãŸã‚™ã‚“ã‚\nãŸã‚™ã‚“ã‚\nã¡ã‚ã„\nã¡ã‚ã‚“\nã¡ã„ã\nã¡ã„ã•ã„\nã¡ãˆã‚“\nã¡ã‹ã„\nã¡ã‹ã‚‰\nã¡ãã‚…ã†\nã¡ãã‚“\nã¡ã‘ã„ã™ã‚™\nã¡ã‘ã‚“\nã¡ã“ã\nã¡ã•ã„\nã¡ã—ã\nã¡ã—りょã†\nã¡ã›ã„\nã¡ãã†\nã¡ãŸã„\nã¡ãŸã‚“\nã¡ã¡ãŠã‚„\nã¡ã¤ã—゙ょ\nã¡ã¦ã\nã¡ã¦ã‚“\nã¡ã¬ã\nã¡ã¬ã‚Š\nã¡ã®ã†\nã¡ã²ã‚‡ã†\nã¡ã¸ã„ã›ã‚“\nã¡ã»ã†\nã¡ã¾ãŸ\nã¡ã¿ã¤\nã¡ã¿ã¨ã‚™ã‚\nã¡ã‚ã„ã¨ã‚™\nã¡ã‚ƒã‚“ã“ãªã¸ã‚™\nã¡ã‚…ã†ã„\nã¡ã‚†ã‚Šã‚‡ã\nã¡ã‚‡ã†ã—\nã¡ã‚‡ã•ãã‘ã‚“\nã¡ã‚‰ã—\nã¡ã‚‰ã¿\nã¡ã‚Šã‹ã‚™ã¿\nã¡ã‚Šã‚‡ã†\nã¡ã‚‹ã¨ã‚™\nã¡ã‚ã‚\nã¡ã‚“ãŸã„\nã¡ã‚“ã‚‚ã\nã¤ã„ã‹\nã¤ã„ãŸã¡\nã¤ã†ã‹\nã¤ã†ã—゙ょã†\nã¤ã†ã¯ã‚“\nã¤ã†ã‚\nã¤ã‹ã†\nã¤ã‹ã‚Œã‚‹\nã¤ãã­\nã¤ãã‚‹\nã¤ã‘ã­\nã¤ã‘ã‚‹\nã¤ã“ã‚™ã†\nã¤ãŸãˆã‚‹\nã¤ã¤ã‚™ã\nã¤ã¤ã—ã‚™\nã¤ã¤ã‚€\nã¤ã¨ã‚ã‚‹\nã¤ãªã‹ã‚™ã‚‹\nã¤ãªã¿\nã¤ã­ã¤ã‚™ã­\nã¤ã®ã‚‹\nã¤ãµã‚™ã™\nã¤ã¾ã‚‰ãªã„\nã¤ã¾ã‚‹\nã¤ã¿ã\nã¤ã‚ãŸã„\nã¤ã‚‚り\nã¤ã‚‚ã‚‹\nã¤ã‚ˆã„\nã¤ã‚‹ã»ã‚™\nã¤ã‚‹ã¿ã\nã¤ã‚ã‚‚ã®\nã¤ã‚り\nã¦ã‚ã—\nã¦ã‚ã¦\nã¦ã‚ã¿\nã¦ã„ãŠã‚“\nã¦ã„ã‹\nã¦ã„ã\nã¦ã„ã‘ã„\nã¦ã„ã“ã\nã¦ã„ã•ã¤\nã¦ã„ã—\nã¦ã„ã›ã„\nã¦ã„ãŸã„\nã¦ã„ã¨ã‚™\nã¦ã„ã­ã„\nã¦ã„ã²ã‚‡ã†\nã¦ã„ã¸ã‚“\nã¦ã„ã»ã‚™ã†\nã¦ã†ã¡\nã¦ãŠãれ\nã¦ãã¨ã†\nã¦ãã²ã‚™\nã¦ã‚™ã“ã»ã‚™ã“\nã¦ã•ã゙ょã†\nã¦ã•ã‘ã‚™\nã¦ã™ã‚Š\nã¦ãã†\nã¦ã¡ã‹ã‚™ã„\nã¦ã¡ã‚‡ã†\nã¦ã¤ã‹ã‚™ã\nã¦ã¤ã¤ã‚™ã\nã¦ã‚™ã£ã¯ã‚š\nã¦ã¤ã»ã‚™ã†\nã¦ã¤ã‚„\nã¦ã‚™ã¬ã‹ãˆ\nã¦ã¬ã\nã¦ã¬ãã‚™ã„\nã¦ã®ã²ã‚‰\nã¦ã¯ã„\nã¦ãµã‚™ãã‚\nã¦ãµãŸã‚™\nã¦ã»ã¨ã‚™ã\nã¦ã»ã‚“\nã¦ã¾ãˆ\nã¦ã¾ãã™ã‚™ã—\nã¦ã¿ã—ã‚™ã‹\nã¦ã¿ã‚„ã‘ã‚™\nã¦ã‚‰ã™\nã¦ã‚Œã²ã‚™\nã¦ã‚ã‘\nã¦ã‚ãŸã—\nã¦ã‚™ã‚“ã‚ã¤\nã¦ã‚“ã„ã‚“\nã¦ã‚“ã‹ã„\nã¦ã‚“ã\nã¦ã‚“ãã‚™\nã¦ã‚“ã‘ã‚“\nã¦ã‚“ã“ã‚™ã\nã¦ã‚“ã•ã„\nã¦ã‚“ã—\nã¦ã‚“ã™ã†\nã¦ã‚™ã‚“ã¡\nã¦ã‚“ã¦ã\nã¦ã‚“ã¨ã†\nã¦ã‚“ãªã„\nã¦ã‚“ãµã‚šã‚‰\nã¦ã‚“ã»ã‚™ã†ãŸã‚™ã„\nã¦ã‚“ã‚ã¤\nã¦ã‚“らんã‹ã„\nã¦ã‚™ã‚“りょã\nã¦ã‚™ã‚“ã‚\nã¨ã‚™ã‚ã„\nã¨ã„れ\nã¨ã‚™ã†ã‹ã‚“\nã¨ã†ãã‚…ã†\nã¨ã‚™ã†ãã‚™\nã¨ã†ã—\nã¨ã†ã‚€ãã‚™\nã¨ãŠã„\nã¨ãŠã‹\nã¨ãŠã\nã¨ãŠã™\nã¨ãŠã‚‹\nã¨ã‹ã„\nã¨ã‹ã™\nã¨ããŠã‚Š\nã¨ãã¨ã‚™ã\nã¨ãã„\nã¨ãã—ã‚…ã†\nã¨ãã¦ã‚“\nã¨ãã«\nã¨ãã¸ã‚™ã¤\nã¨ã‘ã„\nã¨ã‘ã‚‹\nã¨ã“ã‚„\nã¨ã•ã‹\nã¨ã—ょã‹ã‚“\nã¨ãã†\nã¨ãŸã‚“\nã¨ã¡ã‚…ã†\nã¨ã£ãã‚…ã†\nã¨ã£ãã‚“\nã¨ã¤ã›ã‚™ã‚“\nã¨ã¤ã«ã‚…ã†\nã¨ã¨ã‚™ã‘ã‚‹\nã¨ã¨ã®ãˆã‚‹\nã¨ãªã„\nã¨ãªãˆã‚‹\nã¨ãªã‚Š\nã¨ã®ã•ã¾\nã¨ã¯ã‚™ã™\nã¨ã‚™ãµã‚™ã‹ã‚™ã‚\nã¨ã»ã†\nã¨ã¾ã‚‹\nã¨ã‚ã‚‹\nã¨ã‚‚ãŸã‚™ã¡\nã¨ã‚‚ã‚‹\nã¨ã‚™ã‚ˆã†ã²ã‚™\nã¨ã‚‰ãˆã‚‹\nã¨ã‚“ã‹ã¤\nã¨ã‚™ã‚“ãµã‚™ã‚Š\nãªã„ã‹ã\nãªã„ã“ã†\nãªã„ã—ょ\nãªã„ã™\nãªã„ã›ã‚“\nãªã„ãã†\nãªãŠã™\nãªã‹ã‚™ã„\nãªãã™\nãªã‘゙る\nãªã“ã†ã¨ã‚™\nãªã•ã‘\nãªãŸã¦ã‚™ã“ã“\nãªã£ã¨ã†\nãªã¤ã‚„ã™ã¿\nãªãªãŠã—\nãªã«ã“ã‚™ã¨\nãªã«ã‚‚ã®\nãªã«ã‚\nãªã®ã‹\nãªãµãŸã‚™\nãªã¾ã„ã\nãªã¾ãˆ\nãªã¾ã¿\nãªã¿ãŸã‚™\nãªã‚らã‹\nãªã‚ã‚‹\nãªã‚„ã‚€\nãªã‚‰ã†\nãªã‚‰ã²ã‚™\nãªã‚‰ãµã‚™\nãªã‚Œã‚‹\nãªã‚ã¨ã²ã‚™\nãªã‚ã¯ã‚™ã‚Š\nã«ã‚ã†\nã«ã„ã‹ã‚™ãŸ\nã«ã†ã‘\nã«ãŠã„\nã«ã‹ã„\nã«ã‹ã‚™ã¦\nã«ãã²ã‚™\nã«ãã—ã¿\nã«ãã¾ã‚“\nã«ã‘゙る\nã«ã•ã‚“ã‹ãŸã‚“ã\nã«ã—ã\nã«ã›ã‚‚ã®\nã«ã¡ã—゙ょã†\nã«ã¡ã‚ˆã†ã²ã‚™\nã«ã£ã‹\nã«ã£ã\nã«ã£ã‘ã„\nã«ã£ã“ã†\nã«ã£ã•ã‚“\nã«ã£ã—ょã\nã«ã£ã™ã†\nã«ã£ã›ã\nã«ã£ã¦ã„\nã«ãªã†\nã«ã»ã‚“\nã«ã¾ã‚\nã«ã‚‚ã¤\nã«ã‚„り\nã«ã‚…ã†ã„ã‚“\nã«ã‚Šã‚“ã—ゃ\nã«ã‚ã¨ã‚Š\nã«ã‚“ã„\nã«ã‚“ã‹\nã«ã‚“ã\nã«ã‚“ã‘゙ん\nã«ã‚“ã—ã\nã«ã‚“ã™ã‚™ã†\nã«ã‚“ãã†\nã«ã‚“ãŸã„\nã«ã‚“ã¡\nã«ã‚“ã¦ã„\nã«ã‚“ã«ã\nã«ã‚“ãµã‚š\nã«ã‚“ã¾ã‚Š\nã«ã‚“ã‚€\nã«ã‚“ã‚ã„\nã«ã‚“よã†\nã¬ã„ããã‚™\nã¬ã‹ã™\nã¬ãã‚™ã„ã¨ã‚‹\nã¬ãã‚™ã†\nã¬ãもり\nã¬ã™ã‚€\nã¬ã¾ãˆã²ã‚™\nã¬ã‚り\nã¬ã‚‰ã™\nã¬ã‚“ã¡ã‚ƒã\nã­ã‚ã‘ã‚™\nã­ã„ã\nã­ã„ã‚‹\nã­ã„ã‚\nã­ãã‚™ã›\nã­ããŸã„\nã­ãら\nã­ã“ã›ã‚™\nã­ã“ã‚€\nã­ã•ã‘ã‚™\nã­ã™ã“ã‚™ã™\nã­ãã¸ã‚™ã‚‹\nã­ãŸã‚™ã‚“\nã­ã¤ã„\nã­ã£ã—ã‚“\nã­ã¤ãã‚™ã†\nã­ã£ãŸã„ã゙ょ\nã­ãµã‚™ãã\nã­ãµãŸã‚™\nã­ã»ã‚™ã†\nã­ã»ã‚Šã¯ã»ã‚Š\nã­ã¾ã\nã­ã¾ã‚ã—\nã­ã¿ã¿\nã­ã‚€ã„\nã­ã‚€ãŸã„\nã­ã‚‚ã¨\nã­ã‚‰ã†\nã­ã‚ã•ã‚™\nã­ã‚“ã„り\nã­ã‚“ãŠã—\nã­ã‚“ã‹ã‚“\nã­ã‚“ãã‚“\nã­ã‚“ãã‚™\nã­ã‚“ã•ã‚™\nã­ã‚“ã—\nã­ã‚“ã¡ã‚ƒã\nã­ã‚“ã¨ã‚™\nã­ã‚“ã²ã‚š\nã­ã‚“ãµã‚™ã¤\nã­ã‚“ã¾ã¤\nã­ã‚“りょã†\nã­ã‚“れã„\nã®ã„ã™ã‚™\nã®ãŠã¤ã‚™ã¾\nã®ã‹ã‚™ã™\nã®ããªã¿\nã®ã“ã゙り\nã®ã“ã™\nã®ã“ã‚‹\nã®ã›ã‚‹\nã®ãã‚™ã\nã®ã゙む\nã®ãŸã¾ã†\nã®ã¡ã»ã¨ã‚™\nã®ã£ã\nã®ã¯ã‚™ã™\nã®ã¯ã‚‰\nã®ã¸ã‚™ã‚‹\nã®ã»ã‚™ã‚‹\nã®ã¿ã‚‚ã®\nã®ã‚„ã¾\nã®ã‚‰ã„ã¬\nã®ã‚‰ã­ã“\nã®ã‚Šã‚‚ã®\nã®ã‚Šã‚†ã\nã®ã‚Œã‚“\nã®ã‚“ã\nã¯ã‚™ã‚ã„\nã¯ã‚ã\nã¯ã‚™ã‚ã•ã‚“\nã¯ã‚™ã„ã‹\nã¯ã‚™ã„ã\nã¯ã„ã‘ã‚“\nã¯ã„ã“ã‚™\nã¯ã„ã—ã‚“\nã¯ã„ã™ã„\nã¯ã„ã›ã‚“\nã¯ã„ãã†\nã¯ã„ã¡\nã¯ã‚™ã„ã¯ã‚™ã„\nã¯ã„れã¤\nã¯ãˆã‚‹\nã¯ãŠã‚‹\nã¯ã‹ã„\nã¯ã‚™ã‹ã‚Š\nã¯ã‹ã‚‹\nã¯ãã—ã‚…\nã¯ã‘ã‚“\nã¯ã“ãµã‚™\nã¯ã•ã¿\nã¯ã•ã‚“\nã¯ã—ã“ã‚™\nã¯ã‚™ã—ょ\nã¯ã—ã‚‹\nã¯ã›ã‚‹\nã¯ã‚šãã“ã‚“\nã¯ãã‚“\nã¯ãŸã‚“\nã¯ã¡ã¿ã¤\nã¯ã¤ãŠã‚“\nã¯ã£ã‹ã\nã¯ã¤ã‚™ã\nã¯ã£ãり\nã¯ã£ãã¤\nã¯ã£ã‘ã‚“\nã¯ã£ã“ã†\nã¯ã£ã•ã‚“\nã¯ã£ã—ã‚“\nã¯ã£ãŸã¤\nã¯ã£ã¡ã‚…ã†\nã¯ã£ã¦ã‚“\nã¯ã£ã²ã‚šã‚‡ã†\nã¯ã£ã»ã‚šã†\nã¯ãªã™\nã¯ãªã²ã‚™\nã¯ã«ã‹ã‚€\nã¯ãµã‚™ã‚‰ã—\nã¯ã¿ã‹ã‚™ã\nã¯ã‚€ã‹ã†\nã¯ã‚ã¤\nã¯ã‚„ã„\nã¯ã‚„ã—\nã¯ã‚‰ã†\nã¯ã‚ã†ãƒã‚“\nã¯ã‚ã„\nã¯ã‚“ã„\nã¯ã‚“ãˆã„\nã¯ã‚“ãŠã‚“\nã¯ã‚“ã‹ã\nã¯ã‚“ãょã†\nã¯ã‚™ã‚“ãã‚™ã¿\nã¯ã‚“ã“\nã¯ã‚“ã—ゃ\nã¯ã‚“ã™ã†\nã¯ã‚“ãŸã‚™ã‚“\nã¯ã‚šã‚“ã¡\nã¯ã‚šã‚“ã¤\nã¯ã‚“ã¦ã„\nã¯ã‚“ã¨ã—\nã¯ã‚“ã®ã†\nã¯ã‚“ã¯ã‚š\nã¯ã‚“ãµã‚™ã‚“\nã¯ã‚“ã¸ã‚šã‚“\nã¯ã‚“ã»ã‚™ã†ã\nã¯ã‚“ã‚ã„\nã¯ã‚“らん\nã¯ã‚“ã‚ã‚“\nã²ã„ã\nã²ã†ã‚“\nã²ãˆã‚‹\nã²ã‹ã\nã²ã‹ã‚Š\nã²ã‹ã‚‹\nã²ã‹ã‚“\nã²ãã„\nã²ã‘ã¤\nã²ã“ã†ã\nã²ã“ã\nã²ã•ã„\nã²ã•ã—ãµã‚™ã‚Š\nã²ã•ã‚“\nã²ã‚™ã—゙ゅã¤ã‹ã‚“\nã²ã—ょ\nã²ãã‹\nã²ãã‚€\nã²ãŸã‚€ã\nã²ãŸã‚™ã‚Š\nã²ãŸã‚‹\nã²ã¤ãã‚™\nã²ã£ã“ã—\nã²ã£ã—\nã²ã¤ã—゙ゅã²ã‚“\nã²ã£ã™\nã²ã¤ã›ã‚™ã‚“\nã²ã‚šã£ãŸã‚Š\nã²ã‚šã£ã¡ã‚Š\nã²ã¤ã‚ˆã†\nã²ã¦ã„\nã²ã¨ã“ã‚™ã¿\nã²ãªã¾ã¤ã‚Š\nã²ãªã‚“\nã²ã­ã‚‹\nã²ã¯ã‚“\nã²ã²ã‚™ã\nã²ã²ã‚‡ã†\nã²ã»ã†\nã²ã¾ã‚り\nã²ã¾ã‚“\nã²ã¿ã¤\nã²ã‚ã„\nã²ã‚ã—ã‚™ã—\nã²ã‚„ã‘\nã²ã‚„ã™\nã²ã‚ˆã†\nã²ã‚™ã‚‡ã†ã\nã²ã‚‰ã‹ã‚™ãª\nã²ã‚‰ã\nã²ã‚Šã¤\nã²ã‚Šã‚‡ã†\nã²ã‚‹ã¾\nã²ã‚‹ã‚„ã™ã¿\nã²ã‚Œã„\nã²ã‚ã„\nã²ã‚ã†\nã²ã‚ã\nã²ã‚ゆã\nã²ã‚“ã‹ã\nã²ã‚“ã‘ã¤\nã²ã‚“ã“ã‚“\nã²ã‚“ã—ã‚…\nã²ã‚“ãã†\nã²ã‚šã‚“ã¡\nã²ã‚“ã¯ã‚šã‚“\nã²ã‚™ã‚“ã»ã‚™ã†\nãµã‚ã‚“\nãµã„ã†ã¡\nãµã†ã‘ã„\nãµã†ã›ã‚“\nãµã‚šã†ãŸã‚ã†\nãµã†ã¨ã†\nãµã†ãµ\nãµãˆã‚‹\nãµãŠã‚“\nãµã‹ã„\nãµãã‚“\nãµãã•ã‚™ã¤\nãµããµã‚™ãã‚\nãµã“ã†\nãµã•ã„\nãµã—ãã‚™\nãµã—ã‚™ã¿\nãµã™ã¾\nãµã›ã„\nãµã›ãã‚™\nãµãã\nãµã‚™ãŸã«ã\nãµãŸã‚“\nãµã¡ã‚‡ã†\nãµã¤ã†\nãµã¤ã‹\nãµã£ã‹ã¤\nãµã£ã\nãµã£ã“ã\nãµã‚™ã¨ã‚™ã†\nãµã¨ã‚‹\nãµã¨ã‚“\nãµã®ã†\nãµã¯ã„\nãµã²ã‚‡ã†\nãµã¸ã‚“\nãµã¾ã‚“\nãµã¿ã‚“\nãµã‚ã¤\nãµã‚ã‚“\nãµã‚ˆã†\nãµã‚Šã“\nãµã‚Šã‚‹\nãµã‚‹ã„\nãµã‚“ã„ã\nãµã‚™ã‚“ã‹ã‚™ã\nãµã‚™ã‚“ãã‚™\nãµã‚“ã—ã¤\nãµã‚™ã‚“ã›ã\nãµã‚“ãã†\nãµã‚™ã‚“ã»ã‚šã†\nã¸ã„ã‚ã‚“\nã¸ã„ãŠã‚“\nã¸ã„ã‹ã‚™ã„\nã¸ã„ã\nã¸ã„ã‘゙ん\nã¸ã„ã“ã†\nã¸ã„ã•\nã¸ã„ã—ゃ\nã¸ã„ã›ã¤\nã¸ã„ã\nã¸ã„ãŸã\nã¸ã„ã¦ã‚“\nã¸ã„ã­ã¤\nã¸ã„ã‚\nã¸ãã‹ã‚™\nã¸ã“ã‚€\nã¸ã‚™ã«ã„ã‚\nã¸ã‚™ã«ã—ょã†ã‹ã‚™\nã¸ã‚‰ã™\nã¸ã‚“ã‹ã‚“\nã¸ã‚™ã‚“ãょã†\nã¸ã‚™ã‚“ã“ã‚™ã—\nã¸ã‚“ã•ã„\nã¸ã‚“ãŸã„\nã¸ã‚™ã‚“り\nã»ã‚ã‚“\nã»ã„ã\nã»ã‚™ã†ã゙ょ\nã»ã†ã“ã\nã»ã†ãã†\nã»ã†ã»ã†\nã»ã†ã‚‚ã‚“\nã»ã†ã‚Šã¤\nã»ãˆã‚‹\nã»ãŠã‚“\nã»ã‹ã‚“\nã»ãょã†\nã»ã‚™ãã‚“\nã»ãã‚\nã»ã‘ã¤\nã»ã‘ã‚“\nã»ã“ã†\nã»ã“ã‚‹\nã»ã—ã„\nã»ã—ã¤\nã»ã—ã‚…\nã»ã—ょã†\nã»ã›ã„\nã»ãã„\nã»ãã\nã»ãŸã¦\nã»ãŸã‚‹\nã»ã‚šã¡ãµã‚™ãã‚\nã»ã£ãょã\nã»ã£ã•\nã»ã£ãŸã‚“\nã»ã¨ã‚“ã¨ã‚™\nã»ã‚ã‚‹\nã»ã‚“ã„\nã»ã‚“ã\nã»ã‚“ã‘\nã»ã‚“ã—ã¤\nã»ã‚“ã‚„ã\nã¾ã„ã«ã¡\nã¾ã‹ã„\nã¾ã‹ã›ã‚‹\nã¾ã‹ã‚™ã‚‹\nã¾ã‘ã‚‹\nã¾ã“ã¨\nã¾ã•ã¤\nã¾ã—ã‚™ã‚\nã¾ã™ã\nã¾ã›ã‚™ã‚‹\nã¾ã¤ã‚Š\nã¾ã¨ã‚\nã¾ãªãµã‚™\nã¾ã¬ã‘\nã¾ã­ã\nã¾ã»ã†\nã¾ã‚‚ã‚‹\nã¾ã‚†ã‘ã‚™\nã¾ã‚ˆã†\nã¾ã‚ã‚„ã‹\nã¾ã‚ã™\nã¾ã‚り\nã¾ã‚ã‚‹\nã¾ã‚“ã‹ã‚™\nã¾ã‚“ãã¤\nã¾ã‚“ãã‚™ã\nã¾ã‚“ãªã‹\nã¿ã„ら\nã¿ã†ã¡\nã¿ãˆã‚‹\nã¿ã‹ã‚™ã\nã¿ã‹ãŸ\nã¿ã‹ã‚“\nã¿ã‘ã‚“\nã¿ã“ã‚“\nã¿ã—ã‚™ã‹ã„\nã¿ã™ã„\nã¿ã™ãˆã‚‹\nã¿ã›ã‚‹\nã¿ã£ã‹\nã¿ã¤ã‹ã‚‹\nã¿ã¤ã‘ã‚‹\nã¿ã¦ã„\nã¿ã¨ã‚ã‚‹\nã¿ãªã¨\nã¿ãªã¿ã‹ã•ã„\nã¿ã­ã‚‰ã‚‹\nã¿ã®ã†\nã¿ã®ã‹ã‚™ã™\nã¿ã»ã‚“\nã¿ã‚‚ã¨\nã¿ã‚„ã‘ã‚™\nã¿ã‚‰ã„\nã¿ã‚Šã‚‡ã\nã¿ã‚ã\nã¿ã‚“ã‹\nã¿ã‚“ãã‚™ã\nã‚€ã„ã‹\nã‚€ãˆã\nã‚€ãˆã‚“\nã‚€ã‹ã„\nã‚€ã‹ã†\nã‚€ã‹ãˆ\nã‚€ã‹ã—\nã‚€ãã‚™ã¡ã‚ƒ\nã‚€ã‘ã‚‹\nã‚€ã‘゙ん\nã‚€ã•ã»ã‚™ã‚‹\nã‚€ã—ã‚ã¤ã„\nã‚€ã—ã¯ã‚™\nã‚€ã—゙ゅん\nã‚€ã—ã‚\nã‚€ã™ã†\nã‚€ã™ã“\nã‚€ã™ãµã‚™\nã‚€ã™ã‚\nã‚€ã›ã‚‹\nã‚€ã›ã‚“\nã‚€ã¡ã‚…ã†\nã‚€ãªã—ã„\nã‚€ã®ã†\nむやã¿\nむよã†\nむらã•ã\nむりょã†\nã‚€ã‚ã‚“\nã‚ã„ã‚ã‚“\nã‚ã„ã†ã‚“\nã‚ã„ãˆã‚“\nã‚ã„ã‹ã\nã‚ã„ãょã\nã‚ã„ã•ã„\nã‚ã„ã—\nã‚ã„ãã†\nã‚ã„ãµã‚™ã¤\nã‚ã„れã„\nã‚ã„ã‚ã\nã‚ãã‚™ã¾ã‚Œã‚‹\nã‚ã•ã‚™ã™\nã‚ã—ãŸ\nã‚ã™ã‚™ã‚‰ã—ã„\nã‚ãŸã‚™ã¤\nã‚ã¾ã„\nã‚ã‚„ã™\nã‚ã‚“ãょ\nã‚ã‚“ã›ã\nã‚ã‚“ã¨ã‚™ã†\nã‚‚ã†ã—ã‚ã‘゙る\nã‚‚ã†ã¨ã‚™ã†ã‘ã‚“\nã‚‚ãˆã‚‹\nã‚‚ãã—\nã‚‚ãã¦ã\nã‚‚ãよã†ã²ã‚™\nã‚‚ã¡ã‚ã‚“\nã‚‚ã¨ã‚™ã‚‹\nもらã†\nã‚‚ã‚“ã\nã‚‚ã‚“ãŸã‚™ã„\nã‚„ãŠã‚„\nã‚„ã‘ã‚‹\nã‚„ã•ã„\nã‚„ã•ã—ã„\nã‚„ã™ã„\nã‚„ã™ãŸã‚ã†\nã‚„ã™ã¿\nã‚„ã›ã‚‹\nã‚„ãã†\nã‚„ãŸã„\nã‚„ã¡ã‚“\nã‚„ã£ã¨\nã‚„ã£ã¯ã‚šã‚Š\nã‚„ãµã‚™ã‚‹\nã‚„ã‚ã‚‹\nã‚„ã‚„ã“ã—ã„\nやよã„\nã‚„ã‚らã‹ã„\nゆã†ã\nゆã†ã²ã‚™ã‚“ãょã\nゆã†ã¸ã‚™\nゆã†ã‚ã„\nゆã‘ã¤\nゆã—ã‚…ã¤\nゆã›ã‚“\nゆãã†\nゆãŸã‹\nゆã¡ã‚ƒã\nゆã¦ã‚™ã‚‹\nゆã«ã‚…ã†\nゆã²ã‚™ã‚\nゆらã„\nゆれる\nよã†ã„\nよã†ã‹\nよã†ãã‚…ã†\nよã†ã—ã‚™\nよã†ã™\nよã†ã¡ãˆã‚“\nよã‹ã›ã‚™\nよã‹ã‚“\nよãã‚“\nよãã›ã„\nよãã»ã‚™ã†\nよã‘ã„\nよã“゙れる\nよã•ã‚“\nよã—ã‚…ã†\nよãã†\nよãã\nよã£ã‹\nよã¦ã„\nよã¨ã‚™ã‹ã‚™ã‚ã\nよã­ã¤\nよやã\nよゆã†\nよã‚ã“ãµã‚™\nよã‚ã—ã„\nらã„ã†\nらãã‹ã‚™ã\nらãã“ã‚™\nらãã•ã¤\nらããŸã‚™\nらã—ã‚“ã¯ã‚™ã‚“\nらã›ã‚“\nらãã‚™ã\nらãŸã„\nらã£ã‹\nられã¤\nりãˆã\nりã‹ã„\nりãã•ã\nりãã›ã¤\nりãã゙ん\nりãã¤\nりã‘ã‚“\nりã“ã†\nりã›ã„\nりãã†\nりãã\nりã¦ã‚“\nりã­ã‚“\nりゆã†\nりゅã†ã‹ã‚™ã\nりよã†\nりょã†ã‚Š\nりょã‹ã‚“\nりょãã¡ã‚ƒ\nりょã“ã†\nりりã\nりれã\nりã‚ã‚“\nりんã“ã‚™\nã‚‹ã„ã‘ã„\nã‚‹ã„ã•ã„\nã‚‹ã„ã—ã‚™\nã‚‹ã„ã›ã\nã‚‹ã™ã¯ã‚™ã‚“\nるりã‹ã‚™ã‚ら\nれã„ã‹ã‚“\nれã„ãã‚™\nれã„ã›ã„\nれã„ãã‚™ã†ã“\nれã„ã¨ã†\nれã„ã»ã‚™ã†\nれãã—\nれããŸã‚™ã„\nれんã‚ã„\nれんã‘ã„\nれんã“ã‚“\nれんã•ã„\nれんã—ã‚…ã†\nれんãã‚™ã\nれんらã\nã‚ã†ã‹\nã‚ã†ã“ã‚™\nã‚ã†ã—゙ん\nã‚ã†ãã\nã‚ãã‹ã‚™\nã‚ã“ã¤\nã‚ã—ã‚™ã†ã‚‰\nã‚ã—ã‚…ã¤\nã‚ã›ã‚“\nã‚ã¦ã‚“\nã‚ã‚ã‚“\nã‚れã¤\nã‚ã‚“ãã‚™\nã‚ã‚“ã¯ã‚š\nã‚ã‚“ãµã‚™ã‚“\nã‚んり\nã‚ã‹ã™\nã‚ã‹ã‚\nã‚ã‹ã‚„ã¾\nã‚ã‹ã‚Œã‚‹\nã‚ã—ã¤\nã‚ã—ã‚™ã¾ã—\nã‚ã™ã‚Œã‚‚ã®\nã‚らã†\nã‚れる\n" + }, + { + "spanish", + "aÌbaco\nabdomen\nabeja\nabierto\nabogado\nabono\naborto\nabrazo\nabrir\nabuelo\nabuso\nacabar\nacademia\nacceso\naccioÌn\naceite\nacelga\nacento\naceptar\naÌcido\naclarar\nacneÌ\nacoger\nacoso\nactivo\nacto\nactriz\nactuar\nacudir\nacuerdo\nacusar\nadicto\nadmitir\nadoptar\nadorno\naduana\nadulto\naeÌreo\nafectar\naficioÌn\nafinar\nafirmar\naÌgil\nagitar\nagoniÌa\nagosto\nagotar\nagregar\nagrio\nagua\nagudo\naÌguila\naguja\nahogo\nahorro\naire\naislar\najedrez\najeno\najuste\nalacraÌn\nalambre\nalarma\nalba\naÌlbum\nalcalde\naldea\nalegre\nalejar\nalerta\naleta\nalfiler\nalga\nalgodoÌn\naliado\naliento\nalivio\nalma\nalmeja\nalmiÌbar\naltar\nalteza\naltivo\nalto\naltura\nalumno\nalzar\namable\namante\namapola\namargo\namasar\naÌmbar\naÌmbito\nameno\namigo\namistad\namor\namparo\namplio\nancho\nanciano\nancla\nandar\nandeÌn\nanemia\naÌngulo\nanillo\naÌnimo\naniÌs\nanotar\nantena\nantiguo\nantojo\nanual\nanular\nanuncio\nañadir\nañejo\naño\napagar\naparato\napetito\napio\naplicar\napodo\naporte\napoyo\naprender\naprobar\napuesta\napuro\narado\naraña\narar\naÌrbitro\naÌrbol\narbusto\narchivo\narco\narder\nardilla\narduo\naÌrea\naÌrido\naries\narmoniÌa\narneÌs\naroma\narpa\narpoÌn\narreglo\narroz\narruga\narte\nartista\nasa\nasado\nasalto\nascenso\nasegurar\naseo\nasesor\nasiento\nasilo\nasistir\nasno\nasombro\naÌspero\nastilla\nastro\nastuto\nasumir\nasunto\natajo\nataque\natar\natento\nateo\naÌtico\natleta\naÌtomo\natraer\natroz\natuÌn\naudaz\naudio\nauge\naula\naumento\nausente\nautor\naval\navance\navaro\nave\navellana\navena\navestruz\navioÌn\naviso\nayer\nayuda\nayuno\nazafraÌn\nazar\nazote\nazuÌcar\nazufre\nazul\nbaba\nbabor\nbache\nbahiÌa\nbaile\nbajar\nbalanza\nbalcoÌn\nbalde\nbambuÌ\nbanco\nbanda\nbaño\nbarba\nbarco\nbarniz\nbarro\nbaÌscula\nbastoÌn\nbasura\nbatalla\nbateriÌa\nbatir\nbatuta\nbauÌl\nbazar\nbebeÌ\nbebida\nbello\nbesar\nbeso\nbestia\nbicho\nbien\nbingo\nblanco\nbloque\nblusa\nboa\nbobina\nbobo\nboca\nbocina\nboda\nbodega\nboina\nbola\nbolero\nbolsa\nbomba\nbondad\nbonito\nbono\nbonsaÌi\nborde\nborrar\nbosque\nbote\nbotiÌn\nboÌveda\nbozal\nbravo\nbrazo\nbrecha\nbreve\nbrillo\nbrinco\nbrisa\nbroca\nbroma\nbronce\nbrote\nbruja\nbrusco\nbruto\nbuceo\nbucle\nbueno\nbuey\nbufanda\nbufoÌn\nbuÌho\nbuitre\nbulto\nburbuja\nburla\nburro\nbuscar\nbutaca\nbuzoÌn\ncaballo\ncabeza\ncabina\ncabra\ncacao\ncadaÌver\ncadena\ncaer\ncafeÌ\ncaiÌda\ncaimaÌn\ncaja\ncajoÌn\ncal\ncalamar\ncalcio\ncaldo\ncalidad\ncalle\ncalma\ncalor\ncalvo\ncama\ncambio\ncamello\ncamino\ncampo\ncaÌncer\ncandil\ncanela\ncanguro\ncanica\ncanto\ncaña\ncañoÌn\ncaoba\ncaos\ncapaz\ncapitaÌn\ncapote\ncaptar\ncapucha\ncara\ncarboÌn\ncaÌrcel\ncareta\ncarga\ncariño\ncarne\ncarpeta\ncarro\ncarta\ncasa\ncasco\ncasero\ncaspa\ncastor\ncatorce\ncatre\ncaudal\ncausa\ncazo\ncebolla\nceder\ncedro\ncelda\nceÌlebre\nceloso\nceÌlula\ncemento\nceniza\ncentro\ncerca\ncerdo\ncereza\ncero\ncerrar\ncerteza\nceÌsped\ncetro\nchacal\nchaleco\nchampuÌ\nchancla\nchapa\ncharla\nchico\nchiste\nchivo\nchoque\nchoza\nchuleta\nchupar\ncicloÌn\nciego\ncielo\ncien\ncierto\ncifra\ncigarro\ncima\ncinco\ncine\ncinta\ncipreÌs\ncirco\nciruela\ncisne\ncita\nciudad\nclamor\nclan\nclaro\nclase\nclave\ncliente\nclima\ncliÌnica\ncobre\ncoccioÌn\ncochino\ncocina\ncoco\ncoÌdigo\ncodo\ncofre\ncoger\ncohete\ncojiÌn\ncojo\ncola\ncolcha\ncolegio\ncolgar\ncolina\ncollar\ncolmo\ncolumna\ncombate\ncomer\ncomida\ncoÌmodo\ncompra\nconde\nconejo\nconga\nconocer\nconsejo\ncontar\ncopa\ncopia\ncorazoÌn\ncorbata\ncorcho\ncordoÌn\ncorona\ncorrer\ncoser\ncosmos\ncosta\ncraÌneo\ncraÌter\ncrear\ncrecer\ncreiÌdo\ncrema\ncriÌa\ncrimen\ncripta\ncrisis\ncromo\ncroÌnica\ncroqueta\ncrudo\ncruz\ncuadro\ncuarto\ncuatro\ncubo\ncubrir\ncuchara\ncuello\ncuento\ncuerda\ncuesta\ncueva\ncuidar\nculebra\nculpa\nculto\ncumbre\ncumplir\ncuna\ncuneta\ncuota\ncupoÌn\ncuÌpula\ncurar\ncurioso\ncurso\ncurva\ncutis\ndama\ndanza\ndar\ndardo\ndaÌtil\ndeber\ndeÌbil\ndeÌcada\ndecir\ndedo\ndefensa\ndefinir\ndejar\ndelfiÌn\ndelgado\ndelito\ndemora\ndenso\ndental\ndeporte\nderecho\nderrota\ndesayuno\ndeseo\ndesfile\ndesnudo\ndestino\ndesviÌo\ndetalle\ndetener\ndeuda\ndiÌa\ndiablo\ndiadema\ndiamante\ndiana\ndiario\ndibujo\ndictar\ndiente\ndieta\ndiez\ndifiÌcil\ndigno\ndilema\ndiluir\ndinero\ndirecto\ndirigir\ndisco\ndiseño\ndisfraz\ndiva\ndivino\ndoble\ndoce\ndolor\ndomingo\ndon\ndonar\ndorado\ndormir\ndorso\ndos\ndosis\ndragoÌn\ndroga\nducha\nduda\nduelo\ndueño\ndulce\nduÌo\nduque\ndurar\ndureza\nduro\neÌbano\nebrio\nechar\neco\necuador\nedad\nedicioÌn\nedificio\neditor\neducar\nefecto\neficaz\neje\nejemplo\nelefante\nelegir\nelemento\nelevar\nelipse\neÌlite\nelixir\nelogio\neludir\nembudo\nemitir\nemocioÌn\nempate\nempeño\nempleo\nempresa\nenano\nencargo\nenchufe\nenciÌa\nenemigo\nenero\nenfado\nenfermo\nengaño\nenigma\nenlace\nenorme\nenredo\nensayo\nenseñar\nentero\nentrar\nenvase\nenviÌo\neÌpoca\nequipo\nerizo\nescala\nescena\nescolar\nescribir\nescudo\nesencia\nesfera\nesfuerzo\nespada\nespejo\nespiÌa\nesposa\nespuma\nesquiÌ\nestar\neste\nestilo\nestufa\netapa\neterno\neÌtica\netnia\nevadir\nevaluar\nevento\nevitar\nexacto\nexamen\nexceso\nexcusa\nexento\nexigir\nexilio\nexistir\neÌxito\nexperto\nexplicar\nexponer\nextremo\nfaÌbrica\nfaÌbula\nfachada\nfaÌcil\nfactor\nfaena\nfaja\nfalda\nfallo\nfalso\nfaltar\nfama\nfamilia\nfamoso\nfaraoÌn\nfarmacia\nfarol\nfarsa\nfase\nfatiga\nfauna\nfavor\nfax\nfebrero\nfecha\nfeliz\nfeo\nferia\nferoz\nfeÌrtil\nfervor\nfestiÌn\nfiable\nfianza\nfiar\nfibra\nficcioÌn\nficha\nfideo\nfiebre\nfiel\nfiera\nfiesta\nfigura\nfijar\nfijo\nfila\nfilete\nfilial\nfiltro\nfin\nfinca\nfingir\nfinito\nfirma\nflaco\nflauta\nflecha\nflor\nflota\nfluir\nflujo\nfluÌor\nfobia\nfoca\nfogata\nfogoÌn\nfolio\nfolleto\nfondo\nforma\nforro\nfortuna\nforzar\nfosa\nfoto\nfracaso\nfraÌgil\nfranja\nfrase\nfraude\nfreiÌr\nfreno\nfresa\nfriÌo\nfrito\nfruta\nfuego\nfuente\nfuerza\nfuga\nfumar\nfuncioÌn\nfunda\nfurgoÌn\nfuria\nfusil\nfuÌtbol\nfuturo\ngacela\ngafas\ngaita\ngajo\ngala\ngaleriÌa\ngallo\ngamba\nganar\ngancho\nganga\nganso\ngaraje\ngarza\ngasolina\ngastar\ngato\ngavilaÌn\ngemelo\ngemir\ngen\ngeÌnero\ngenio\ngente\ngeranio\ngerente\ngermen\ngesto\ngigante\ngimnasio\ngirar\ngiro\nglaciar\nglobo\ngloria\ngol\ngolfo\ngoloso\ngolpe\ngoma\ngordo\ngorila\ngorra\ngota\ngoteo\ngozar\ngrada\ngraÌfico\ngrano\ngrasa\ngratis\ngrave\ngrieta\ngrillo\ngripe\ngris\ngrito\ngrosor\ngruÌa\ngrueso\ngrumo\ngrupo\nguante\nguapo\nguardia\nguerra\nguiÌa\nguiño\nguion\nguiso\nguitarra\ngusano\ngustar\nhaber\nhaÌbil\nhablar\nhacer\nhacha\nhada\nhallar\nhamaca\nharina\nhaz\nhazaña\nhebilla\nhebra\nhecho\nhelado\nhelio\nhembra\nherir\nhermano\nheÌroe\nhervir\nhielo\nhierro\nhiÌgado\nhigiene\nhijo\nhimno\nhistoria\nhocico\nhogar\nhoguera\nhoja\nhombre\nhongo\nhonor\nhonra\nhora\nhormiga\nhorno\nhostil\nhoyo\nhueco\nhuelga\nhuerta\nhueso\nhuevo\nhuida\nhuir\nhumano\nhuÌmedo\nhumilde\nhumo\nhundir\nhuracaÌn\nhurto\nicono\nideal\nidioma\niÌdolo\niglesia\nigluÌ\nigual\nilegal\nilusioÌn\nimagen\nimaÌn\nimitar\nimpar\nimperio\nimponer\nimpulso\nincapaz\niÌndice\ninerte\ninfiel\ninforme\ningenio\ninicio\ninmenso\ninmune\ninnato\ninsecto\ninstante\nintereÌs\niÌntimo\nintuir\ninuÌtil\ninvierno\nira\niris\nironiÌa\nisla\nislote\njabaliÌ\njaboÌn\njamoÌn\njarabe\njardiÌn\njarra\njaula\njazmiÌn\njefe\njeringa\njinete\njornada\njoroba\njoven\njoya\njuerga\njueves\njuez\njugador\njugo\njuguete\njuicio\njunco\njungla\njunio\njuntar\njuÌpiter\njurar\njusto\njuvenil\njuzgar\nkilo\nkoala\nlabio\nlacio\nlacra\nlado\nladroÌn\nlagarto\nlaÌgrima\nlaguna\nlaico\nlamer\nlaÌmina\nlaÌmpara\nlana\nlancha\nlangosta\nlanza\nlaÌpiz\nlargo\nlarva\nlaÌstima\nlata\nlaÌtex\nlatir\nlaurel\nlavar\nlazo\nleal\nleccioÌn\nleche\nlector\nleer\nlegioÌn\nlegumbre\nlejano\nlengua\nlento\nleña\nleoÌn\nleopardo\nlesioÌn\nletal\nletra\nleve\nleyenda\nlibertad\nlibro\nlicor\nliÌder\nlidiar\nlienzo\nliga\nligero\nlima\nliÌmite\nlimoÌn\nlimpio\nlince\nlindo\nliÌnea\nlingote\nlino\nlinterna\nliÌquido\nliso\nlista\nlitera\nlitio\nlitro\nllaga\nllama\nllanto\nllave\nllegar\nllenar\nllevar\nllorar\nllover\nlluvia\nlobo\nlocioÌn\nloco\nlocura\nloÌgica\nlogro\nlombriz\nlomo\nlonja\nlote\nlucha\nlucir\nlugar\nlujo\nluna\nlunes\nlupa\nlustro\nluto\nluz\nmaceta\nmacho\nmadera\nmadre\nmaduro\nmaestro\nmafia\nmagia\nmago\nmaiÌz\nmaldad\nmaleta\nmalla\nmalo\nmamaÌ\nmambo\nmamut\nmanco\nmando\nmanejar\nmanga\nmaniquiÌ\nmanjar\nmano\nmanso\nmanta\nmañana\nmapa\nmaÌquina\nmar\nmarco\nmarea\nmarfil\nmargen\nmarido\nmaÌrmol\nmarroÌn\nmartes\nmarzo\nmasa\nmaÌscara\nmasivo\nmatar\nmateria\nmatiz\nmatriz\nmaÌximo\nmayor\nmazorca\nmecha\nmedalla\nmedio\nmeÌdula\nmejilla\nmejor\nmelena\nmeloÌn\nmemoria\nmenor\nmensaje\nmente\nmenuÌ\nmercado\nmerengue\nmeÌrito\nmes\nmesoÌn\nmeta\nmeter\nmeÌtodo\nmetro\nmezcla\nmiedo\nmiel\nmiembro\nmiga\nmil\nmilagro\nmilitar\nmilloÌn\nmimo\nmina\nminero\nmiÌnimo\nminuto\nmiope\nmirar\nmisa\nmiseria\nmisil\nmismo\nmitad\nmito\nmochila\nmocioÌn\nmoda\nmodelo\nmoho\nmojar\nmolde\nmoler\nmolino\nmomento\nmomia\nmonarca\nmoneda\nmonja\nmonto\nmoño\nmorada\nmorder\nmoreno\nmorir\nmorro\nmorsa\nmortal\nmosca\nmostrar\nmotivo\nmover\nmoÌvil\nmozo\nmucho\nmudar\nmueble\nmuela\nmuerte\nmuestra\nmugre\nmujer\nmula\nmuleta\nmulta\nmundo\nmuñeca\nmural\nmuro\nmuÌsculo\nmuseo\nmusgo\nmuÌsica\nmuslo\nnaÌcar\nnacioÌn\nnadar\nnaipe\nnaranja\nnariz\nnarrar\nnasal\nnatal\nnativo\nnatural\nnaÌusea\nnaval\nnave\nnavidad\nnecio\nneÌctar\nnegar\nnegocio\nnegro\nneoÌn\nnervio\nneto\nneutro\nnevar\nnevera\nnicho\nnido\nniebla\nnieto\nniñez\nniño\nniÌtido\nnivel\nnobleza\nnoche\nnoÌmina\nnoria\nnorma\nnorte\nnota\nnoticia\nnovato\nnovela\nnovio\nnube\nnuca\nnuÌcleo\nnudillo\nnudo\nnuera\nnueve\nnuez\nnulo\nnuÌmero\nnutria\noasis\nobeso\nobispo\nobjeto\nobra\nobrero\nobservar\nobtener\nobvio\noca\nocaso\noceÌano\nochenta\nocho\nocio\nocre\noctavo\noctubre\noculto\nocupar\nocurrir\nodiar\nodio\nodisea\noeste\nofensa\noferta\noficio\nofrecer\nogro\noiÌdo\noiÌr\nojo\nola\noleada\nolfato\nolivo\nolla\nolmo\nolor\nolvido\nombligo\nonda\nonza\nopaco\nopcioÌn\noÌpera\nopinar\noponer\noptar\noÌptica\nopuesto\noracioÌn\norador\noral\noÌrbita\norca\norden\noreja\noÌrgano\norgiÌa\norgullo\noriente\norigen\norilla\noro\norquesta\noruga\nosadiÌa\noscuro\nosezno\noso\nostra\notoño\notro\noveja\noÌvulo\noÌxido\noxiÌgeno\noyente\nozono\npacto\npadre\npaella\npaÌgina\npago\npaiÌs\npaÌjaro\npalabra\npalco\npaleta\npaÌlido\npalma\npaloma\npalpar\npan\npanal\npaÌnico\npantera\npañuelo\npapaÌ\npapel\npapilla\npaquete\nparar\nparcela\npared\nparir\nparo\npaÌrpado\nparque\npaÌrrafo\nparte\npasar\npaseo\npasioÌn\npaso\npasta\npata\npatio\npatria\npausa\npauta\npavo\npayaso\npeatoÌn\npecado\npecera\npecho\npedal\npedir\npegar\npeine\npelar\npeldaño\npelea\npeligro\npellejo\npelo\npeluca\npena\npensar\npeñoÌn\npeoÌn\npeor\npepino\npequeño\npera\npercha\nperder\npereza\nperfil\nperico\nperla\npermiso\nperro\npersona\npesa\npesca\npeÌsimo\npestaña\npeÌtalo\npetroÌleo\npez\npezuña\npicar\npichoÌn\npie\npiedra\npierna\npieza\npijama\npilar\npiloto\npimienta\npino\npintor\npinza\npiña\npiojo\npipa\npirata\npisar\npiscina\npiso\npista\npitoÌn\npizca\nplaca\nplan\nplata\nplaya\nplaza\npleito\npleno\nplomo\npluma\nplural\npobre\npoco\npoder\npodio\npoema\npoesiÌa\npoeta\npolen\npoliciÌa\npollo\npolvo\npomada\npomelo\npomo\npompa\nponer\nporcioÌn\nportal\nposada\nposeer\nposible\nposte\npotencia\npotro\npozo\nprado\nprecoz\npregunta\npremio\nprensa\npreso\nprevio\nprimo\npriÌncipe\nprisioÌn\nprivar\nproa\nprobar\nproceso\nproducto\nproeza\nprofesor\nprograma\nprole\npromesa\npronto\npropio\nproÌximo\nprueba\npuÌblico\npuchero\npudor\npueblo\npuerta\npuesto\npulga\npulir\npulmoÌn\npulpo\npulso\npuma\npunto\npuñal\npuño\npupa\npupila\npureÌ\nquedar\nqueja\nquemar\nquerer\nqueso\nquieto\nquiÌmica\nquince\nquitar\nraÌbano\nrabia\nrabo\nracioÌn\nradical\nraiÌz\nrama\nrampa\nrancho\nrango\nrapaz\nraÌpido\nrapto\nrasgo\nraspa\nrato\nrayo\nraza\nrazoÌn\nreaccioÌn\nrealidad\nrebaño\nrebote\nrecaer\nreceta\nrechazo\nrecoger\nrecreo\nrecto\nrecurso\nred\nredondo\nreducir\nreflejo\nreforma\nrefraÌn\nrefugio\nregalo\nregir\nregla\nregreso\nreheÌn\nreino\nreiÌr\nreja\nrelato\nrelevo\nrelieve\nrelleno\nreloj\nremar\nremedio\nremo\nrencor\nrendir\nrenta\nreparto\nrepetir\nreposo\nreptil\nres\nrescate\nresina\nrespeto\nresto\nresumen\nretiro\nretorno\nretrato\nreunir\nreveÌs\nrevista\nrey\nrezar\nrico\nriego\nrienda\nriesgo\nrifa\nriÌgido\nrigor\nrincoÌn\nriñoÌn\nriÌo\nriqueza\nrisa\nritmo\nrito\nrizo\nroble\nroce\nrociar\nrodar\nrodeo\nrodilla\nroer\nrojizo\nrojo\nromero\nromper\nron\nronco\nronda\nropa\nropero\nrosa\nrosca\nrostro\nrotar\nrubiÌ\nrubor\nrudo\nrueda\nrugir\nruido\nruina\nruleta\nrulo\nrumbo\nrumor\nruptura\nruta\nrutina\nsaÌbado\nsaber\nsabio\nsable\nsacar\nsagaz\nsagrado\nsala\nsaldo\nsalero\nsalir\nsalmoÌn\nsaloÌn\nsalsa\nsalto\nsalud\nsalvar\nsamba\nsancioÌn\nsandiÌa\nsanear\nsangre\nsanidad\nsano\nsanto\nsapo\nsaque\nsardina\nsarteÌn\nsastre\nsataÌn\nsauna\nsaxofoÌn\nseccioÌn\nseco\nsecreto\nsecta\nsed\nseguir\nseis\nsello\nselva\nsemana\nsemilla\nsenda\nsensor\nseñal\nseñor\nseparar\nsepia\nsequiÌa\nser\nserie\nsermoÌn\nservir\nsesenta\nsesioÌn\nseta\nsetenta\nsevero\nsexo\nsexto\nsidra\nsiesta\nsiete\nsiglo\nsigno\nsiÌlaba\nsilbar\nsilencio\nsilla\nsiÌmbolo\nsimio\nsirena\nsistema\nsitio\nsituar\nsobre\nsocio\nsodio\nsol\nsolapa\nsoldado\nsoledad\nsoÌlido\nsoltar\nsolucioÌn\nsombra\nsondeo\nsonido\nsonoro\nsonrisa\nsopa\nsoplar\nsoporte\nsordo\nsorpresa\nsorteo\nsosteÌn\nsoÌtano\nsuave\nsubir\nsuceso\nsudor\nsuegra\nsuelo\nsueño\nsuerte\nsufrir\nsujeto\nsultaÌn\nsumar\nsuperar\nsuplir\nsuponer\nsupremo\nsur\nsurco\nsureño\nsurgir\nsusto\nsutil\ntabaco\ntabique\ntabla\ntabuÌ\ntaco\ntacto\ntajo\ntalar\ntalco\ntalento\ntalla\ntaloÌn\ntamaño\ntambor\ntango\ntanque\ntapa\ntapete\ntapia\ntapoÌn\ntaquilla\ntarde\ntarea\ntarifa\ntarjeta\ntarot\ntarro\ntarta\ntatuaje\ntauro\ntaza\ntazoÌn\nteatro\ntecho\ntecla\nteÌcnica\ntejado\ntejer\ntejido\ntela\nteleÌfono\ntema\ntemor\ntemplo\ntenaz\ntender\ntener\ntenis\ntenso\nteoriÌa\nterapia\nterco\nteÌrmino\nternura\nterror\ntesis\ntesoro\ntestigo\ntetera\ntexto\ntez\ntibio\ntiburoÌn\ntiempo\ntienda\ntierra\ntieso\ntigre\ntijera\ntilde\ntimbre\ntiÌmido\ntimo\ntinta\ntiÌo\ntiÌpico\ntipo\ntira\ntiroÌn\ntitaÌn\ntiÌtere\ntiÌtulo\ntiza\ntoalla\ntobillo\ntocar\ntocino\ntodo\ntoga\ntoldo\ntomar\ntono\ntonto\ntopar\ntope\ntoque\ntoÌrax\ntorero\ntormenta\ntorneo\ntoro\ntorpedo\ntorre\ntorso\ntortuga\ntos\ntosco\ntoser\ntoÌxico\ntrabajo\ntractor\ntraer\ntraÌfico\ntrago\ntraje\ntramo\ntrance\ntrato\ntrauma\ntrazar\ntreÌbol\ntregua\ntreinta\ntren\ntrepar\ntres\ntribu\ntrigo\ntripa\ntriste\ntriunfo\ntrofeo\ntrompa\ntronco\ntropa\ntrote\ntrozo\ntruco\ntrueno\ntrufa\ntuberiÌa\ntubo\ntuerto\ntumba\ntumor\ntuÌnel\ntuÌnica\nturbina\nturismo\nturno\ntutor\nubicar\nuÌlcera\numbral\nunidad\nunir\nuniverso\nuno\nuntar\nuña\nurbano\nurbe\nurgente\nurna\nusar\nusuario\nuÌtil\nutopiÌa\nuva\nvaca\nvaciÌo\nvacuna\nvagar\nvago\nvaina\nvajilla\nvale\nvaÌlido\nvalle\nvalor\nvaÌlvula\nvampiro\nvara\nvariar\nvaroÌn\nvaso\nvecino\nvector\nvehiÌculo\nveinte\nvejez\nvela\nvelero\nveloz\nvena\nvencer\nvenda\nveneno\nvengar\nvenir\nventa\nvenus\nver\nverano\nverbo\nverde\nvereda\nverja\nverso\nverter\nviÌa\nviaje\nvibrar\nvicio\nviÌctima\nvida\nviÌdeo\nvidrio\nviejo\nviernes\nvigor\nvil\nvilla\nvinagre\nvino\nviñedo\nvioliÌn\nviral\nvirgo\nvirtud\nvisor\nviÌspera\nvista\nvitamina\nviudo\nvivaz\nvivero\nvivir\nvivo\nvolcaÌn\nvolumen\nvolver\nvoraz\nvotar\nvoto\nvoz\nvuelo\nvulgar\nyacer\nyate\nyegua\nyema\nyerno\nyeso\nyodo\nyoga\nyogur\nzafiro\nzanja\nzapato\nzarza\nzona\nzorro\nzumo\nzurdo\n" + }, + { + "french", + "abaisser\nabandon\nabdiquer\nabeille\nabolir\naborder\naboutir\naboyer\nabrasif\nabreuver\nabriter\nabroger\nabrupt\nabsence\nabsolu\nabsurde\nabusif\nabyssal\nacadeÌmie\nacajou\nacarien\naccabler\naccepter\nacclamer\naccolade\naccroche\naccuser\nacerbe\nachat\nacheter\naciduler\nacier\nacompte\nacqueÌrir\nacronyme\nacteur\nactif\nactuel\nadepte\nadeÌquat\nadheÌsif\nadjectif\nadjuger\nadmettre\nadmirer\nadopter\nadorer\nadoucir\nadresse\nadroit\nadulte\nadverbe\naeÌrer\naeÌronef\naffaire\naffecter\naffiche\naffreux\naffubler\nagacer\nagencer\nagile\nagiter\nagrafer\nagreÌable\nagrume\naider\naiguille\nailier\naimable\naisance\najouter\najuster\nalarmer\nalchimie\nalerte\nalgeÌ€bre\nalgue\nalieÌner\naliment\nalleÌger\nalliage\nallouer\nallumer\nalourdir\nalpaga\naltesse\nalveÌole\namateur\nambigu\nambre\nameÌnager\namertume\namidon\namiral\namorcer\namour\namovible\namphibie\nampleur\namusant\nanalyse\nanaphore\nanarchie\nanatomie\nancien\naneÌantir\nangle\nangoisse\nanguleux\nanimal\nannexer\nannonce\nannuel\nanodin\nanomalie\nanonyme\nanormal\nantenne\nantidote\nanxieux\napaiser\napeÌritif\naplanir\napologie\nappareil\nappeler\napporter\nappuyer\naquarium\naqueduc\narbitre\narbuste\nardeur\nardoise\nargent\narlequin\narmature\narmement\narmoire\narmure\narpenter\narracher\narriver\narroser\narsenic\narteÌriel\narticle\naspect\nasphalte\naspirer\nassaut\nasservir\nassiette\nassocier\nassurer\nasticot\nastre\nastuce\natelier\natome\natrium\natroce\nattaque\nattentif\nattirer\nattraper\naubaine\nauberge\naudace\naudible\naugurer\naurore\nautomne\nautruche\navaler\navancer\navarice\navenir\naverse\naveugle\naviateur\navide\navion\naviser\navoine\navouer\navril\naxial\naxiome\nbadge\nbafouer\nbagage\nbaguette\nbaignade\nbalancer\nbalcon\nbaleine\nbalisage\nbambin\nbancaire\nbandage\nbanlieue\nbannieÌ€re\nbanquier\nbarbier\nbaril\nbaron\nbarque\nbarrage\nbassin\nbastion\nbataille\nbateau\nbatterie\nbaudrier\nbavarder\nbelette\nbeÌlier\nbelote\nbeÌneÌfice\nberceau\nberger\nberline\nbermuda\nbesace\nbesogne\nbeÌtail\nbeurre\nbiberon\nbicycle\nbidule\nbijou\nbilan\nbilingue\nbillard\nbinaire\nbiologie\nbiopsie\nbiotype\nbiscuit\nbison\nbistouri\nbitume\nbizarre\nblafard\nblague\nblanchir\nblessant\nblinder\nblond\nbloquer\nblouson\nbobard\nbobine\nboire\nboiser\nbolide\nbonbon\nbondir\nbonheur\nbonifier\nbonus\nbordure\nborne\nbotte\nboucle\nboueux\nbougie\nboulon\nbouquin\nbourse\nboussole\nboutique\nboxeur\nbranche\nbrasier\nbrave\nbrebis\nbreÌ€che\nbreuvage\nbricoler\nbrigade\nbrillant\nbrioche\nbrique\nbrochure\nbroder\nbronzer\nbrousse\nbroyeur\nbrume\nbrusque\nbrutal\nbruyant\nbuffle\nbuisson\nbulletin\nbureau\nburin\nbustier\nbutiner\nbutoir\nbuvable\nbuvette\ncabanon\ncabine\ncachette\ncadeau\ncadre\ncafeÌine\ncaillou\ncaisson\ncalculer\ncalepin\ncalibre\ncalmer\ncalomnie\ncalvaire\ncamarade\ncameÌra\ncamion\ncampagne\ncanal\ncaneton\ncanon\ncantine\ncanular\ncapable\ncaporal\ncaprice\ncapsule\ncapter\ncapuche\ncarabine\ncarbone\ncaresser\ncaribou\ncarnage\ncarotte\ncarreau\ncarton\ncascade\ncasier\ncasque\ncassure\ncauser\ncaution\ncavalier\ncaverne\ncaviar\nceÌdille\nceinture\nceÌleste\ncellule\ncendrier\ncensurer\ncentral\ncercle\nceÌreÌbral\ncerise\ncerner\ncerveau\ncesser\nchagrin\nchaise\nchaleur\nchambre\nchance\nchapitre\ncharbon\nchasseur\nchaton\nchausson\nchavirer\nchemise\nchenille\ncheÌquier\nchercher\ncheval\nchien\nchiffre\nchignon\nchimeÌ€re\nchiot\nchlorure\nchocolat\nchoisir\nchose\nchouette\nchrome\nchute\ncigare\ncigogne\ncimenter\ncineÌma\ncintrer\ncirculer\ncirer\ncirque\nciterne\ncitoyen\ncitron\ncivil\nclairon\nclameur\nclaquer\nclasse\nclavier\nclient\ncligner\nclimat\nclivage\ncloche\nclonage\ncloporte\ncobalt\ncobra\ncocasse\ncocotier\ncoder\ncodifier\ncoffre\ncogner\ncoheÌsion\ncoiffer\ncoincer\ncoleÌ€re\ncolibri\ncolline\ncolmater\ncolonel\ncombat\ncomeÌdie\ncommande\ncompact\nconcert\nconduire\nconfier\ncongeler\nconnoter\nconsonne\ncontact\nconvexe\ncopain\ncopie\ncorail\ncorbeau\ncordage\ncorniche\ncorpus\ncorrect\ncorteÌ€ge\ncosmique\ncostume\ncoton\ncoude\ncoupure\ncourage\ncouteau\ncouvrir\ncoyote\ncrabe\ncrainte\ncravate\ncrayon\ncreÌature\ncreÌditer\ncreÌmeux\ncreuser\ncrevette\ncribler\ncrier\ncristal\ncriteÌ€re\ncroire\ncroquer\ncrotale\ncrucial\ncruel\ncrypter\ncubique\ncueillir\ncuilleÌ€re\ncuisine\ncuivre\nculminer\ncultiver\ncumuler\ncupide\ncuratif\ncurseur\ncyanure\ncycle\ncylindre\ncynique\ndaigner\ndamier\ndanger\ndanseur\ndauphin\ndeÌbattre\ndeÌbiter\ndeÌborder\ndeÌbrider\ndeÌbutant\ndeÌcaler\ndeÌcembre\ndeÌchirer\ndeÌcider\ndeÌclarer\ndeÌcorer\ndeÌcrire\ndeÌcupler\ndeÌdale\ndeÌductif\ndeÌesse\ndeÌfensif\ndeÌfiler\ndeÌfrayer\ndeÌgager\ndeÌgivrer\ndeÌglutir\ndeÌgrafer\ndeÌjeuner\ndeÌlice\ndeÌloger\ndemander\ndemeurer\ndeÌmolir\ndeÌnicher\ndeÌnouer\ndentelle\ndeÌnuder\ndeÌpart\ndeÌpenser\ndeÌphaser\ndeÌplacer\ndeÌposer\ndeÌranger\ndeÌrober\ndeÌsastre\ndescente\ndeÌsert\ndeÌsigner\ndeÌsobeÌir\ndessiner\ndestrier\ndeÌtacher\ndeÌtester\ndeÌtourer\ndeÌtresse\ndevancer\ndevenir\ndeviner\ndevoir\ndiable\ndialogue\ndiamant\ndicter\ndiffeÌrer\ndigeÌrer\ndigital\ndigne\ndiluer\ndimanche\ndiminuer\ndioxyde\ndirectif\ndiriger\ndiscuter\ndisposer\ndissiper\ndistance\ndivertir\ndiviser\ndocile\ndocteur\ndogme\ndoigt\ndomaine\ndomicile\ndompter\ndonateur\ndonjon\ndonner\ndopamine\ndortoir\ndorure\ndosage\ndoseur\ndossier\ndotation\ndouanier\ndouble\ndouceur\ndouter\ndoyen\ndragon\ndraper\ndresser\ndribbler\ndroiture\nduperie\nduplexe\ndurable\ndurcir\ndynastie\neÌblouir\neÌcarter\neÌcharpe\neÌchelle\neÌclairer\neÌclipse\neÌclore\neÌcluse\neÌcole\neÌconomie\neÌcorce\neÌcouter\neÌcraser\neÌcreÌmer\neÌcrivain\neÌcrou\neÌcume\neÌcureuil\neÌdifier\neÌduquer\neffacer\neffectif\neffigie\neffort\neffrayer\neffusion\neÌgaliser\neÌgarer\neÌjecter\neÌlaborer\neÌlargir\neÌlectron\neÌleÌgant\neÌleÌphant\neÌleÌ€ve\neÌligible\neÌlitisme\neÌloge\neÌlucider\neÌluder\nemballer\nembellir\nembryon\neÌmeraude\neÌmission\nemmener\neÌmotion\neÌmouvoir\nempereur\nemployer\nemporter\nemprise\neÌmulsion\nencadrer\nencheÌ€re\nenclave\nencoche\nendiguer\nendosser\nendroit\nenduire\neÌnergie\nenfance\nenfermer\nenfouir\nengager\nengin\nenglober\neÌnigme\nenjamber\nenjeu\nenlever\nennemi\nennuyeux\nenrichir\nenrobage\nenseigne\nentasser\nentendre\nentier\nentourer\nentraver\neÌnumeÌrer\nenvahir\nenviable\nenvoyer\nenzyme\neÌolien\neÌpaissir\neÌpargne\neÌpatant\neÌpaule\neÌpicerie\neÌpideÌmie\neÌpier\neÌpilogue\neÌpine\neÌpisode\neÌpitaphe\neÌpoque\neÌpreuve\neÌprouver\neÌpuisant\neÌquerre\neÌquipe\neÌriger\neÌrosion\nerreur\neÌruption\nescalier\nespadon\nespeÌ€ce\nespieÌ€gle\nespoir\nesprit\nesquiver\nessayer\nessence\nessieu\nessorer\nestime\nestomac\nestrade\neÌtageÌ€re\neÌtaler\neÌtanche\neÌtatique\neÌteindre\neÌtendoir\neÌternel\neÌthanol\neÌthique\nethnie\neÌtirer\neÌtoffer\neÌtoile\neÌtonnant\neÌtourdir\neÌtrange\neÌtroit\neÌtude\neuphorie\neÌvaluer\neÌvasion\neÌventail\neÌvidence\neÌviter\neÌvolutif\neÌvoquer\nexact\nexageÌrer\nexaucer\nexceller\nexcitant\nexclusif\nexcuse\nexeÌcuter\nexemple\nexercer\nexhaler\nexhorter\nexigence\nexiler\nexister\nexotique\nexpeÌdier\nexplorer\nexposer\nexprimer\nexquis\nextensif\nextraire\nexulter\nfable\nfabuleux\nfacette\nfacile\nfacture\nfaiblir\nfalaise\nfameux\nfamille\nfarceur\nfarfelu\nfarine\nfarouche\nfasciner\nfatal\nfatigue\nfaucon\nfautif\nfaveur\nfavori\nfeÌbrile\nfeÌconder\nfeÌdeÌrer\nfeÌlin\nfemme\nfeÌmur\nfendoir\nfeÌodal\nfermer\nfeÌroce\nferveur\nfestival\nfeuille\nfeutre\nfeÌvrier\nfiasco\nficeler\nfictif\nfideÌ€le\nfigure\nfilature\nfiletage\nfilieÌ€re\nfilleul\nfilmer\nfilou\nfiltrer\nfinancer\nfinir\nfiole\nfirme\nfissure\nfixer\nflairer\nflamme\nflasque\nflatteur\nfleÌau\nfleÌ€che\nfleur\nflexion\nflocon\nflore\nfluctuer\nfluide\nfluvial\nfolie\nfonderie\nfongible\nfontaine\nforcer\nforgeron\nformuler\nfortune\nfossile\nfoudre\nfougeÌ€re\nfouiller\nfoulure\nfourmi\nfragile\nfraise\nfranchir\nfrapper\nfrayeur\nfreÌgate\nfreiner\nfrelon\nfreÌmir\nfreÌneÌsie\nfreÌ€re\nfriable\nfriction\nfrisson\nfrivole\nfroid\nfromage\nfrontal\nfrotter\nfruit\nfugitif\nfuite\nfureur\nfurieux\nfurtif\nfusion\nfutur\ngagner\ngalaxie\ngalerie\ngambader\ngarantir\ngardien\ngarnir\ngarrigue\ngazelle\ngazon\ngeÌant\ngeÌlatine\ngeÌlule\ngendarme\ngeÌneÌral\ngeÌnie\ngenou\ngentil\ngeÌologie\ngeÌomeÌ€tre\ngeÌranium\ngerme\ngestuel\ngeyser\ngibier\ngicler\ngirafe\ngivre\nglace\nglaive\nglisser\nglobe\ngloire\nglorieux\ngolfeur\ngomme\ngonfler\ngorge\ngorille\ngoudron\ngouffre\ngoulot\ngoupille\ngourmand\ngoutte\ngraduel\ngraffiti\ngraine\ngrand\ngrappin\ngratuit\ngravir\ngrenat\ngriffure\ngriller\ngrimper\ngrogner\ngronder\ngrotte\ngroupe\ngruger\ngrutier\ngruyeÌ€re\ngueÌpard\nguerrier\nguide\nguimauve\nguitare\ngustatif\ngymnaste\ngyrostat\nhabitude\nhachoir\nhalte\nhameau\nhangar\nhanneton\nharicot\nharmonie\nharpon\nhasard\nheÌlium\nheÌmatome\nherbe\nheÌrisson\nhermine\nheÌron\nheÌsiter\nheureux\nhiberner\nhibou\nhilarant\nhistoire\nhiver\nhomard\nhommage\nhomogeÌ€ne\nhonneur\nhonorer\nhonteux\nhorde\nhorizon\nhorloge\nhormone\nhorrible\nhouleux\nhousse\nhublot\nhuileux\nhumain\nhumble\nhumide\nhumour\nhurler\nhydromel\nhygieÌ€ne\nhymne\nhypnose\nidylle\nignorer\niguane\nillicite\nillusion\nimage\nimbiber\nimiter\nimmense\nimmobile\nimmuable\nimpact\nimpeÌrial\nimplorer\nimposer\nimprimer\nimputer\nincarner\nincendie\nincident\nincliner\nincolore\nindexer\nindice\ninductif\nineÌdit\nineptie\ninexact\ninfini\ninfliger\ninformer\ninfusion\ningeÌrer\ninhaler\ninhiber\ninjecter\ninjure\ninnocent\ninoculer\ninonder\ninscrire\ninsecte\ninsigne\ninsolite\ninspirer\ninstinct\ninsulter\nintact\nintense\nintime\nintrigue\nintuitif\ninutile\ninvasion\ninventer\ninviter\ninvoquer\nironique\nirradier\nirreÌel\nirriter\nisoler\nivoire\nivresse\njaguar\njaillir\njambe\njanvier\njardin\njauger\njaune\njavelot\njetable\njeton\njeudi\njeunesse\njoindre\njoncher\njongler\njoueur\njouissif\njournal\njovial\njoyau\njoyeux\njubiler\njugement\njunior\njupon\njuriste\njustice\njuteux\njuveÌnile\nkayak\nkimono\nkiosque\nlabel\nlabial\nlabourer\nlaceÌrer\nlactose\nlagune\nlaine\nlaisser\nlaitier\nlambeau\nlamelle\nlampe\nlanceur\nlangage\nlanterne\nlapin\nlargeur\nlarme\nlaurier\nlavabo\nlavoir\nlecture\nleÌgal\nleÌger\nleÌgume\nlessive\nlettre\nlevier\nlexique\nleÌzard\nliasse\nlibeÌrer\nlibre\nlicence\nlicorne\nlieÌ€ge\nlieÌ€vre\nligature\nligoter\nligue\nlimer\nlimite\nlimonade\nlimpide\nlineÌaire\nlingot\nlionceau\nliquide\nlisieÌ€re\nlister\nlithium\nlitige\nlittoral\nlivreur\nlogique\nlointain\nloisir\nlombric\nloterie\nlouer\nlourd\nloutre\nlouve\nloyal\nlubie\nlucide\nlucratif\nlueur\nlugubre\nluisant\nlumieÌ€re\nlunaire\nlundi\nluron\nlutter\nluxueux\nmachine\nmagasin\nmagenta\nmagique\nmaigre\nmaillon\nmaintien\nmairie\nmaison\nmajorer\nmalaxer\nmaleÌfice\nmalheur\nmalice\nmallette\nmammouth\nmandater\nmaniable\nmanquant\nmanteau\nmanuel\nmarathon\nmarbre\nmarchand\nmardi\nmaritime\nmarqueur\nmarron\nmarteler\nmascotte\nmassif\nmateÌriel\nmatieÌ€re\nmatraque\nmaudire\nmaussade\nmauve\nmaximal\nmeÌchant\nmeÌconnu\nmeÌdaille\nmeÌdecin\nmeÌditer\nmeÌduse\nmeilleur\nmeÌlange\nmeÌlodie\nmembre\nmeÌmoire\nmenacer\nmener\nmenhir\nmensonge\nmentor\nmercredi\nmeÌrite\nmerle\nmessager\nmesure\nmeÌtal\nmeÌteÌore\nmeÌthode\nmeÌtier\nmeuble\nmiauler\nmicrobe\nmiette\nmignon\nmigrer\nmilieu\nmillion\nmimique\nmince\nmineÌral\nminimal\nminorer\nminute\nmiracle\nmiroiter\nmissile\nmixte\nmobile\nmoderne\nmoelleux\nmondial\nmoniteur\nmonnaie\nmonotone\nmonstre\nmontagne\nmonument\nmoqueur\nmorceau\nmorsure\nmortier\nmoteur\nmotif\nmouche\nmoufle\nmoulin\nmousson\nmouton\nmouvant\nmultiple\nmunition\nmuraille\nmureÌ€ne\nmurmure\nmuscle\nmuseÌum\nmusicien\nmutation\nmuter\nmutuel\nmyriade\nmyrtille\nmysteÌ€re\nmythique\nnageur\nnappe\nnarquois\nnarrer\nnatation\nnation\nnature\nnaufrage\nnautique\nnavire\nneÌbuleux\nnectar\nneÌfaste\nneÌgation\nneÌgliger\nneÌgocier\nneige\nnerveux\nnettoyer\nneurone\nneutron\nneveu\nniche\nnickel\nnitrate\nniveau\nnoble\nnocif\nnocturne\nnoirceur\nnoisette\nnomade\nnombreux\nnommer\nnormatif\nnotable\nnotifier\nnotoire\nnourrir\nnouveau\nnovateur\nnovembre\nnovice\nnuage\nnuancer\nnuire\nnuisible\nnumeÌro\nnuptial\nnuque\nnutritif\nobeÌir\nobjectif\nobliger\nobscur\nobserver\nobstacle\nobtenir\nobturer\noccasion\noccuper\noceÌan\noctobre\noctroyer\noctupler\noculaire\nodeur\nodorant\noffenser\nofficier\noffrir\nogive\noiseau\noisillon\nolfactif\nolivier\nombrage\nomettre\nonctueux\nonduler\noneÌreux\nonirique\nopale\nopaque\nopeÌrer\nopinion\nopportun\nopprimer\nopter\noptique\norageux\norange\norbite\nordonner\noreille\norgane\norgueil\norifice\nornement\norque\nortie\nosciller\nosmose\nossature\notarie\nouragan\nourson\noutil\noutrager\nouvrage\novation\noxyde\noxygeÌ€ne\nozone\npaisible\npalace\npalmareÌ€s\npalourde\npalper\npanache\npanda\npangolin\npaniquer\npanneau\npanorama\npantalon\npapaye\npapier\npapoter\npapyrus\nparadoxe\nparcelle\nparesse\nparfumer\nparler\nparole\nparrain\nparsemer\npartager\nparure\nparvenir\npassion\npasteÌ€que\npaternel\npatience\npatron\npavillon\npavoiser\npayer\npaysage\npeigne\npeintre\npelage\npeÌlican\npelle\npelouse\npeluche\npendule\npeÌneÌtrer\npeÌnible\npensif\npeÌnurie\npeÌpite\npeÌplum\nperdrix\nperforer\npeÌriode\npermuter\nperplexe\npersil\nperte\npeser\npeÌtale\npetit\npeÌtrir\npeuple\npharaon\nphobie\nphoque\nphoton\nphrase\nphysique\npiano\npictural\npieÌ€ce\npierre\npieuvre\npilote\npinceau\npipette\npiquer\npirogue\npiscine\npiston\npivoter\npixel\npizza\nplacard\nplafond\nplaisir\nplaner\nplaque\nplastron\nplateau\npleurer\nplexus\npliage\nplomb\nplonger\npluie\nplumage\npochette\npoeÌsie\npoeÌ€te\npointe\npoirier\npoisson\npoivre\npolaire\npolicier\npollen\npolygone\npommade\npompier\nponctuel\npondeÌrer\nponey\nportique\nposition\nposseÌder\nposture\npotager\npoteau\npotion\npouce\npoulain\npoumon\npourpre\npoussin\npouvoir\nprairie\npratique\npreÌcieux\npreÌdire\npreÌfixe\npreÌlude\npreÌnom\npreÌsence\npreÌtexte\npreÌvoir\nprimitif\nprince\nprison\npriver\nprobleÌ€me\nproceÌder\nprodige\nprofond\nprogreÌ€s\nproie\nprojeter\nprologue\npromener\npropre\nprospeÌ€re\nproteÌger\nprouesse\nproverbe\nprudence\npruneau\npsychose\npublic\npuceron\npuiser\npulpe\npulsar\npunaise\npunitif\npupitre\npurifier\npuzzle\npyramide\nquasar\nquerelle\nquestion\nquieÌtude\nquitter\nquotient\nracine\nraconter\nradieux\nragondin\nraideur\nraisin\nralentir\nrallonge\nramasser\nrapide\nrasage\nratisser\nravager\nravin\nrayonner\nreÌactif\nreÌagir\nreÌaliser\nreÌanimer\nrecevoir\nreÌciter\nreÌclamer\nreÌcolter\nrecruter\nreculer\nrecycler\nreÌdiger\nredouter\nrefaire\nreÌflexe\nreÌformer\nrefrain\nrefuge\nreÌgalien\nreÌgion\nreÌglage\nreÌgulier\nreÌiteÌrer\nrejeter\nrejouer\nrelatif\nrelever\nrelief\nremarque\nremeÌ€de\nremise\nremonter\nremplir\nremuer\nrenard\nrenfort\nrenifler\nrenoncer\nrentrer\nrenvoi\nreplier\nreporter\nreprise\nreptile\nrequin\nreÌserve\nreÌsineux\nreÌsoudre\nrespect\nrester\nreÌsultat\nreÌtablir\nretenir\nreÌticule\nretomber\nretracer\nreÌunion\nreÌussir\nrevanche\nrevivre\nreÌvolte\nreÌvulsif\nrichesse\nrideau\nrieur\nrigide\nrigoler\nrincer\nriposter\nrisible\nrisque\nrituel\nrival\nrivieÌ€re\nrocheux\nromance\nrompre\nronce\nrondin\nroseau\nrosier\nrotatif\nrotor\nrotule\nrouge\nrouille\nrouleau\nroutine\nroyaume\nruban\nrubis\nruche\nruelle\nrugueux\nruiner\nruisseau\nruser\nrustique\nrythme\nsabler\nsaboter\nsabre\nsacoche\nsafari\nsagesse\nsaisir\nsalade\nsalive\nsalon\nsaluer\nsamedi\nsanction\nsanglier\nsarcasme\nsardine\nsaturer\nsaugrenu\nsaumon\nsauter\nsauvage\nsavant\nsavonner\nscalpel\nscandale\nsceÌleÌrat\nsceÌnario\nsceptre\nscheÌma\nscience\nscinder\nscore\nscrutin\nsculpter\nseÌance\nseÌcable\nseÌcher\nsecouer\nseÌcreÌter\nseÌdatif\nseÌduire\nseigneur\nseÌjour\nseÌlectif\nsemaine\nsembler\nsemence\nseÌminal\nseÌnateur\nsensible\nsentence\nseÌparer\nseÌquence\nserein\nsergent\nseÌrieux\nserrure\nseÌrum\nservice\nseÌsame\nseÌvir\nsevrage\nsextuple\nsideÌral\nsieÌ€cle\nsieÌger\nsiffler\nsigle\nsignal\nsilence\nsilicium\nsimple\nsinceÌ€re\nsinistre\nsiphon\nsirop\nsismique\nsituer\nskier\nsocial\nsocle\nsodium\nsoigneux\nsoldat\nsoleil\nsolitude\nsoluble\nsombre\nsommeil\nsomnoler\nsonde\nsongeur\nsonnette\nsonore\nsorcier\nsortir\nsosie\nsottise\nsoucieux\nsoudure\nsouffle\nsoulever\nsoupape\nsource\nsoutirer\nsouvenir\nspacieux\nspatial\nspeÌcial\nspheÌ€re\nspiral\nstable\nstation\nsternum\nstimulus\nstipuler\nstrict\nstudieux\nstupeur\nstyliste\nsublime\nsubstrat\nsubtil\nsubvenir\nsucceÌ€s\nsucre\nsuffixe\nsuggeÌrer\nsuiveur\nsulfate\nsuperbe\nsupplier\nsurface\nsuricate\nsurmener\nsurprise\nsursaut\nsurvie\nsuspect\nsyllabe\nsymbole\nsymeÌtrie\nsynapse\nsyntaxe\nsysteÌ€me\ntabac\ntablier\ntactile\ntailler\ntalent\ntalisman\ntalonner\ntambour\ntamiser\ntangible\ntapis\ntaquiner\ntarder\ntarif\ntartine\ntasse\ntatami\ntatouage\ntaupe\ntaureau\ntaxer\nteÌmoin\ntemporel\ntenaille\ntendre\nteneur\ntenir\ntension\nterminer\nterne\nterrible\nteÌtine\ntexte\ntheÌ€me\ntheÌorie\ntheÌrapie\nthorax\ntibia\ntieÌ€de\ntimide\ntirelire\ntiroir\ntissu\ntitane\ntitre\ntituber\ntoboggan\ntoleÌrant\ntomate\ntonique\ntonneau\ntoponyme\ntorche\ntordre\ntornade\ntorpille\ntorrent\ntorse\ntortue\ntotem\ntoucher\ntournage\ntousser\ntoxine\ntraction\ntrafic\ntragique\ntrahir\ntrain\ntrancher\ntravail\ntreÌ€fle\ntremper\ntreÌsor\ntreuil\ntriage\ntribunal\ntricoter\ntrilogie\ntriomphe\ntripler\ntriturer\ntrivial\ntrombone\ntronc\ntropical\ntroupeau\ntuile\ntulipe\ntumulte\ntunnel\nturbine\ntuteur\ntutoyer\ntuyau\ntympan\ntyphon\ntypique\ntyran\nubuesque\nultime\nultrason\nunanime\nunifier\nunion\nunique\nunitaire\nunivers\nuranium\nurbain\nurticant\nusage\nusine\nusuel\nusure\nutile\nutopie\nvacarme\nvaccin\nvagabond\nvague\nvaillant\nvaincre\nvaisseau\nvalable\nvalise\nvallon\nvalve\nvampire\nvanille\nvapeur\nvarier\nvaseux\nvassal\nvaste\nvecteur\nvedette\nveÌgeÌtal\nveÌhicule\nveinard\nveÌloce\nvendredi\nveÌneÌrer\nvenger\nvenimeux\nventouse\nverdure\nveÌrin\nvernir\nverrou\nverser\nvertu\nveston\nveÌteÌran\nveÌtuste\nvexant\nvexer\nviaduc\nviande\nvictoire\nvidange\nvideÌo\nvignette\nvigueur\nvilain\nvillage\nvinaigre\nviolon\nvipeÌ€re\nvirement\nvirtuose\nvirus\nvisage\nviseur\nvision\nvisqueux\nvisuel\nvital\nvitesse\nviticole\nvitrine\nvivace\nvivipare\nvocation\nvoguer\nvoile\nvoisin\nvoiture\nvolaille\nvolcan\nvoltiger\nvolume\nvorace\nvortex\nvoter\nvouloir\nvoyage\nvoyelle\nwagon\nxeÌnon\nyacht\nzeÌ€bre\nzeÌnith\nzeste\nzoologie" + }, + { + "portuguese_brazil", + "abacate\nabaixo\nabandono\nabencoar\naberto\nabertura\nabobora\nabraco\nabril\nabsorver\nabstrato\nabsurdo\nabuso\nacademia\nacampamento\nacao\nacesso\nacidente\nacido\nacima\naco\nacolher\nacordado\nacordar\nacordo\nacreditar\nacrescentar\nacucar\nacusar\nacustico\nadaptar\nadiante\nadicionar\nadivinhar\nadmitem\nadotivo\nadquirir\nadulto\naerobico\naeroporto\nafastar\nafetivo\nafetuoso\nafiado\nafinidade\naflicao\nagachar\nagarrar\nagente\nagora\nagosto\nagua\naguarde\naguia\nainda\naipo\naja\najustar\nalarme\nalbum\nalcancar\nalcance\nalcool\naldeia\naleatoria\nalegre\nalegria\naleia\nalem\nalerta\nalfa\nalgodao\nalguem\nalho\nalimentacao\nalistar\nalivio\nalma\nalmoco\nalmofada\nalteracao\nalterar\nalto\naltura\naluguel\naluna\naluno\nalvo\nalvorecer\namador\namanha\namar\namarelo\namargo\nambito\nameaca\namendoim\namigos\namostra\nampliar\nanalista\nanao\nancora\nandar\nanel\nangulo\nanimal\nano\nanoitecer\nansiedade\nansioso\nantena\nantes\nantigo\nantiguidade\nanual\nanunciar\napagar\naparar\naparecer\naperto\naplaudir\naplicar\napoiar\naposentar\napreciar\naprender\naprovar\napto\nar\naranha\narcaico\narco\narea\nareia\narena\nargila\nargumentar\nargumento\narma\narmadilha\narmado\narmadura\narmario\narquivo\narrepender\narrepio\narroz\narte\nartefato\nartico\nartista\nartwork\narvore\nasa\nasma\nasno\naspecto\naspero\nassado\nassalto\nassemelhar\nassento\nassumir\nataque\nate\natinar\natirar\natitude\natividade\nativo\natleta\natomo\nator\natrai\natras\natraves\natriz\natual\natualidade\natualizacao\natualizar\natum\nauditar\naumentar\nausente\nauto\nautor\nautoria\nautorizar\nauxiliar\navancar\naventura\navestruz\naviso\navistar\nazul\nbaboseira\nbacharel\nbacon\nbagagem\nbairrista\nbala\nbalanco\nbaleia\nbambino\nbambu\nbanana\nbancada\nbanco\nbandeira\nbandeja\nbando\nbanheiro\nbarato\nbarco\nbarganha\nbarra\nbarraca\nbarril\nbarulho\nbase\nbasico\nbatalha\nbatata\nbatedeira\nbatedor\nbatida\nbebe\nbeber\nbeijo\nbeira\nbeleza\nbem\nbeneficiar\nberco\nbiblioteca\nbicicleta\nbife\nbilhete\nbiologia\nbitola\nblusa\nboa\nboba\nbobina\nbode\nbola\nbolha\nbolo\nbolsa\nbom\nbomba\nboneca\nbonita\nbonitinho\nbonus\nborda\nbordo\nborracha\nborrao\nbraco\nbravo\nbrecha\nbreu\nbreve\nbrilhante\nbrilho\nbrinquedo\nbrisa\nbroca\nbrocolis\nbronze\nbufalo\nbulbo\nburaco\nburro\nbuscar\ncabeca\ncabelo\ncaber\ncabine\ncabo\ncacar\ncacareco\ncacarejar\ncachorro\ncacto\ncadeira\ncafe\ncair\ncaixa\ncalmo\ncaloroso\ncamada\ncamarada\ncamarao\ncambalhota\ncamera\ncaminhao\ncaminho\ncampeao\ncampo\ncampones\ncanal\ncancao\ncancelar\ncanela\ncaneta\ncanguru\ncanhao\ncanoa\ncansado\ncantar\ncaos\ncapacete\ncapacidade\ncapaz\ncapital\ncapitao\ncapitulo\ncaptura\ncapturados\ncapuz\ncara\ncaracteristica\ncarbono\ncardapio\ncarga\ncarimbo\ncarne\ncarpo\ncarranca\ncarregar\ncarrinho\ncarro\ncarta\ncartao\ncarvalho\ncarvoeira\ncasa\ncasal\ncasamento\ncaso\ncassino\ncasta\ncastanha\ncastanho\ncastelo\ncasual\ncatalogo\ncategoria\ncausa\ncavalo\ncaverna\ncebola\ncedo\ncego\ncelere\ncem\ncena\ncenso\nceramica\ncerca\ncercar\ncerco\ncereal\ncerebro\ncereja\ncerne\ncerto\ncervo\ncesta\nchama\nchamine\nchao\nchapeu\ncharuto\nchateado\nchave\nchef\nchefe\nchegar\nchicote\nchifre\nchique\nchoque\nchorar\nchuva\nciclo\ncidadao\ncidade\nciencia\ncimento\ncinto\ncirculo\ncitacao\ncitar\nciumes\ncivil\nclemencia\ncliente\nclima\nclinica\nclique\nclube\ncobertor\ncobertura\ncobre\ncobrir\ncoco\ncodigo\ncoelho\ncofre\ncogumelo\ncoiote\ncoisa\ncola\ncoletar\ncolheita\ncolher\ncolisao\ncolocar\ncolossal\ncoluna\ncombinar\ncombustivel\ncomecar\ncomercio\ncomicio\ncomida\ncompanhia\ncomparecer\ncompartilhar\ncomponente\ncomportamento\ncompra\ncomprador\ncomprimento\ncomprimido\ncomum\nconceder\nconcha\nconcordar\nconduta\nconectados\nconectar\nconfiar\nconfiguracao\nconfirmar\nconforto\ncongeladas\ncongresso\nconhecer\nconjurar\nconsciente\nconselho\nconsentir\nconsertar\nconsiderar\nconstruir\nconta\ncontar\ncontato\ncontemplacao\ncontente\ncontratar\ncontrolar\nconvencer\nconversa\nconversar\nconvir\nconvite\ncopia\ncopo\ncor\ncoracao\ncoragem\ncoral\ncorar\ncorpo\ncorre\ncorredor\ncorreto\ncorrida\ncorrigir\ncorroer\ncortina\ncorvo\ncosta\ncostela\ncotovelo\ncozinha\ncozinhar\ncracha\ncranio\ncratera\ncredito\ncremalheira\ncreme\ncrescer\ncrianca\ncriceto\ncrime\ncrise\ncristal\ncritico\ncronica\ncru\ncrucial\ncruel\ncruz\ncruzeiro\ncubo\ncuidado\nculpa\ncultura\ncume\ncurioso\ncurso\ncurto\ncurva\ncusto\ncustodia\ndados\ndanca\ndanificar\ndar\ndebaixo\ndebate\ndecada\ndecidir\ndeclinio\ndecorar\ndecretar\ndedicar\ndedo\ndefesa\ndefinir\ndelgado\ndelicado\ndemitir\ndemolir\ndemora\ndente\ndentista\ndentro\ndepender\ndepois\ndeposito\ndepressa\ndeputado\nderiva\nderivar\ndesafiar\ndesagradavel\ndesajeitado\ndesaparecer\ndescobrir\ndesconhecido\ndescrever\ndesculpa\ndesde\ndesdobrar\ndesejo\ndesenhar\ndesenvolver\ndeserto\ndesespero\ndesfazer\ndesfiladeiro\ndesistir\ndeslizar\ndesmaio\ndesnivelado\ndesordem\ndesperdicio\ndestravar\ndestruir\ndesvaneca\ndesvendar\ndesviar\ndetalhe\ndetritos\ndeusa\ndever\ndevo\ndez\ndezembro\ndia\ndiagrama\ndiamante\ndiario\ndica\ndiesel\ndieta\ndiferir\ndificil\ndigital\ndigitalizacao\ndigitar\ndignidade\ndilema\ndiminuir\ndinamico\ndinheiro\ndinossauro\ndireto\ndirigir\ndiscar\ndiscordar\ndisparo\ndispor\ndispositivo\ndistancia\ndistinto\ndiversao\ndiverso\ndivertido\ndividido\ndividir\ndivorcio\ndizer\ndoador\ndoar\ndobra\ndoce\ndocumento\ndoenca\ndoente\ndois\ndominar\ndominio\ndoninha\ndormir\ndose\ndoze\ndragao\ndrama\ndrastico\nduna\nduplo\ndurante\nduto\neco\necologia\neconomia\neditar\neducar\nefemero\nefetivo\neixo\nelator\nelefante\nelegante\nelemento\neles\neletrico\nelevador\nelite\nembaralhar\nembarcacao\nembarcar\nemblema\nembreagem\nembrulho\nemergir\nemocao\nempenhar\nempinar\nempregada\nempregar\nempresa\nemprestado\nemprestar\nemprestimo\nempurrao\nempurrar\nencarnar\nencontrado\nencontrar\nendereco\nendossar\nenergia\nenfadonho\nenfermeira\nenfermo\nengenho\nengolir\nengracado\nenigma\nenorme\nenriquecer\nensaio\nenseada\nensinar\nensino\nensolarado\nentornar\nentrada\nentrar\nentre\nentregar\nentulho\nentupir\nenvelope\nenviar\nenvolver\nenxame\nepisodio\nequilibrar\nequipamento\nequipar\nequipe\nera\nerguido\nermo\nerosao\nerrado\nerro\nerupcao\nesboco\nescada\nescala\nescalada\nescambo\nescapar\nescape\nesclarecer\nescola\nescolha\nescolher\nescondido\nescorpiao\nescova\nescreva\nescrita\nescritorio\nescriturario\nescrivaninha\nescudo\nesfarelar\nesfera\nesforco\nesfregar\nesmagamento\nespacial\nespaco\nespada\nespalhar\nespecial\nespeciaria\nespelho\nesperanca\nesperar\nespero\nesperto\nespiao\nespigao\nespirito\nesporte\nesposa\nespuma\nesquadra\nesqueco\nesquema\nesquerda\nesqui\nesquilo\nesquisito\nessencia\nesta\nestacao\nestadio\nestado\nestalo\nestavel\nestereo\nestilo\nestimacao\nestojo\nestomago\nestoque\nestrada\nestragar\nestrangeiro\nestrategia\netapa\neterno\netica\netiqueta\nevidencia\nevidente\nevita\nevitar\nevocar\nevoluir\nexame\nexato\nexcesso\nexcitar\nexcluir\nexclusivo\nexecutar\nexemplo\nexercicio\nexercito\nexibicao\nexigem\nexigir\nexilio\nexistir\nexotico\nexpandir\nexpediente\nexperimentar\nexpirar\nexplicar\nexplosao\nexpor\nexposicao\nexposto\nexpressar\nextenso\nexterior\nexterno\nextra\nfaca\nfacil\nfacilmente\nfaco\nfaculdade\nfadiga\nfalar\nfalcao\nfalecimento\nfalha\nfalso\nfama\nfamilia\nfaminto\nfamoso\nfantasia\nfantasma\nfardo\nfarejar\nfatal\nfatia\nfavor\nfavorito\nfazenda\nfe\nfebre\nfechar\nfederal\nfeijao\nfeio\nfeliz\nfemea\nfenda\nferiado\nferido\nferramenta\nferro\nferver\nfesta\nfestival\nfevereiro\nfibra\nficcao\nfiel\nfigura\nfilha\nfilme\nfiltro\nfim\nfinal\nfino\nfio\nfique\nfiscal\nfisico\nfita\nflash\nflecha\nflor\nfloresta\nfluido\nflutuador\nflutuar\nfoco\nfofoca\nfogao\nfogo\nfoguete\nfolha\nfonte\nfora\nforca\nfornalha\nfornecedor\nfornecem\nfornecer\nforno\nforte\nfortuna\nforum\nfosforo\nfossil\nfoto\nfotografia\nfragil\nfragmento\nfrango\nfranja\nfrase\nfrente\nfrequente\nfrequentemente\nfresco\nfrete\nfronteira\nfrustrar\nfruta\nfugir\nfulgor\nfumaca\nfuncionarios\nfundicao\nfundir\nfuria\nfutebol\nfuturamente\nfuturo\ngado\ngafe\ngaiola\ngalaxia\ngaleria\ngalinha\nganhar\nganho\nganso\ngaragem\ngarantia\ngarantir\ngarfo\ngaroto\ngarra\ngarrucha\ngas\ngastar\ngatilho\ngatinho\ngato\ngeada\ngeleia\ngelo\ngemeo\ngenero\ngengibre\ngenio\ngenuino\ngeral\ngerir\ngesto\ngigante\nginastica\ngirafa\ngirar\ngiro\ngiz\nglobo\ngloria\ngolfinho\ngordo\ngorila\ngospel\ngostar\ngosto\ngotejamento\ngoverno\ngraca\ngracejo\ngrade\ngrama\ngramado\ngrampo\ngrande\ngrao\ngrau\ngravidade\ngreve\ngrilo\ngrosseiro\ngrunhido\ngrupo\nguarda\nguardanapo\nguaxinim\nguerra\nguerreiro\nguia\nguindaste\nguri\nha\nhabilidade\nhabilitar\nhabitante\nhabito\nhamburguer\nhaste\nherdar\nheroi\nhibrido\nhistoria\nhoje\nholandes\nhomem\nhoquei\nhora\nhorrivel\nhorror\nhospedeiro\nhospital\nhotel\nhumano\nhumilde\nhumor\nicone\nidade\nideia\nidentificar\nignorar\nigual\niguaria\nilegal\nilha\nimagem\nimenso\nimitar\nimpacto\nimpor\nimportam\nimprecisao\nimpressao\nimpressionante\nimpulsionar\nimpulso\nimune\ninalar\ninativo\nincapaz\ninclinar\nincluir\nincomum\ninconsciente\nincorporado\nindagacao\nindicar\nindice\nindustria\ninexato\ninfantil\ninfeliz\ninferior\ninfligir\ninformar\ningenuo\ninicial\ninicio\ninimigo\ninjetar\ninjusto\ninocente\ninquerito\ninquilino\ninsano\ninscrever\ninseto\ninsignia\ninspirar\ninstalar\ninstar\nintacto\ninteligente\ninteresse\ninterior\ninterminavel\ninterruptor\ninutil\ninverno\ninvestir\ninvez\nirma\nirmao\nisolar\nitem\nja\njaguar\njamais\njanela\njantar\njaqueta\njarda\njardim\njarra\njazz\njeans\njeito\njoelho\njogo\njoia\njornada\njovem\njuiz\njunior\njunte\njuntos\njurar\njuventude\nkalanga\nketchup\nkiwi\nla\nlabaro\nlabirinto\nlaboratorio\nlaco\nlacuna\nlado\nlagarto\nlago\nlagoa\nlagosta\nlaje\nlamina\nlampada\nlancamento\nlancar\nlanche\nlapis\nlaptop\nlaranja\nlargo\nlargura\nlata\nlatino\nlava\nlavanderia\nlavar\nlazer\nleao\nlegal\nlei\nleilao\nleite\nlembrar\nlenda\nlente\nlento\nleopardo\nlerdo\nleste\nletra\nlevantar\nleve\nliberdade\nlicao\nlicenca\nlider\nligacao\nligar\nligeiro\nlimao\nlimitar\nlimite\nlimpar\nlingua\nlinguica\nlinha\nliquido\nlista\nlisura\nlivre\nlivro\nlixo\nlobo\nlocal\nlocalidade\nlocomocao\nlogica\nloja\nlona\nlonge\nlongo\nloteria\nlouco\nlouvor\nlua\nlucro\nlugar\nlunar\nluta\nlutar\nluva\nluxo\nmaca\nmacaco\nmadeira\nmadrugada\nmae\nmagia\nmagnetico\nmaior\nmais\nmal\nmalha\nmaluco\nmamae\nmamifero\nmandato\nmanga\nmanha\nmansao\nmanteiga\nmanual\nmao\nmaquina\nmar\nmaravilha\nmarca\nmarcha\nmare\nmarfim\nmargem\nmarido\nmarinho\nmarmore\nmartelo\nmascara\nmassa\nmatematica\nmaterial\nmatriz\nmaximo\nmazela\nmecanico\nmedalha\nmedia\nmedico\nmedida\nmeia\nmeio\nmel\nmelancolia\nmelhor\nmelhorar\nmelodia\nmembro\nmemoria\nmencao\nmenina\nmenor\nmensagem\nmente\nmentiroso\nmercado\nmercearia\nmergulho\nmerito\nmes\nmesa\nmesmo\nmetade\nmetal\nmetodo\nmetro\nmidia\nmilagre\nmilhao\nmilho\nminimo\nminusculo\nminuto\nmira\nmiseria\nmisericordia\nmisterio\nmistura\nmisturado\nmisturar\nmito\nmoda\nmodelo\nmoderno\nmodificar\nmoeda\nmoita\nmolhado\nmolho\nmomento\nmonitor\nmonstro\nmontanha\nmonte\nmoral\nmosca\nmosquito\nmostra\nmotor\nmovel\nmover\nmovimento\nmudanca\nmuito\nmula\nmulher\nmultidao\nmultiplicar\nmundo\nmusculo\nmuseu\nmusica\nmutuo\nnacao\nnaco\nnada\nnadar\nnanico\nnariz\nnascimento\nnatureza\nnavalha\nnavio\nnecessidade\nnecessitar\nnegacao\nnegar\nnegativo\nnegligencia\nnegocio\nnem\nnervo\nneutro\nneve\nnevoa\nninho\nnivel\nnobre\nnoite\nnoivado\nnome\nnomeacao\nnoodle\nnormal\nnorte\nnota\nnotavel\nnoticia\nnovamente\nnovela\nnoz\nnuclear\nnumero\nnunca\nnuvem\nobedecer\nobjetivo\nobjeto\nobrigado\nobrigar\nobscurecer\nobservar\nobstaculo\nobtivermos\nobvio\noceano\noco\nocorrencia\nocorrer\nocupado\nodor\noeste\noferta\noficio\noito\nok\nola\noleo\nolho\nolimpico\noliva\nombro\nombros\nomitir\nonda\nonde\nondulacao\nonibus\nopcao\nopera\nopiniao\nopor\norbita\norcamento\nordem\nordenar\norfao\norganizar\norgao\norgulho\norgulhoso\norientar\noriginal\nosso\nostra\nou\nourico\nouro\nousado\noutono\noutro\noutrora\noutros\noutubro\noval\novas\novo\noxigenio\nozonio\npa\npaciente\npacote\npacto\npadrao\npadre\npagamento\npagina\npai\npainel\npais\npalacio\npalavra\npalestra\npalhaco\npalma\npalpavel\npanda\npanico\npano\npantano\npantera\npao\npapagaio\npapel\npar\nparada\nparagem\nparede\nparente\nparodiar\nparque\nparte\npartido\npartilhado\npassar\npassaro\npassatempo\npasseio\npasso\npatife\npatim\npato\npatrao\npatrocinador\npatrulha\npausa\npavimentar\npaz\npe\npeca\npedra\npeito\npeixe\npele\npelicano\npelicula\npena\npenhasco\npenhor\npensamento\npequeno\npera\nperdao\nperfeito\nperguntar\npericia\nperigo\npermanecer\npermitir\nperna\npersonalizadas\nperto\nperu\npesado\npescoco\npesquisa\npessoa\npessoas\npiano\npicada\npiloto\npimenta\npioneiro\npipa\npiquenique\npiramide\npiscadela\npiscina\npista\npistola\npizza\nplaneta\nplano\nplanta\nplastico\nplugue\npo\npobreza\npoder\npoeira\npoema\npoeta\npolar\npolegada\npolegar\npolicia\npolo\npolpa\npomar\npomba\npombo\nponei\npontape\nponte\nponto\npopular\nporco\nporque\nporrete\nporta\nportao\nporto\nposicao\npossivel\npostar\npoucos\npoupar\nprado\npraia\nprata\npratica\nprato\nprazer\nprazo\npreco\npreferir\npreguicoso\nprejuizo\npremio\nprender\npreocupacao\npreparar\npresente\npressa\npreto\nprever\nprimario\nprimavera\nprimeiro\nprimo\nprimor\nprincipal\nprincipio\nprioridade\nprisao\nprivado\nproblema\nprocesso\nprocurar\nproduzir\nprofundidade\nprograma\nprogredir\nprojeto\npromover\npronto\npropelir\nproposito\npropriedade\nproprietario\nproprio\nprosperar\nproteger\nprova\nprovincia\nproximo\npublico\npudim\npulso\npureza\npuxar\nquadrado\nquadril\nquadrinho\nquadro\nquais\nqualidade\nqualquer\nquando\nquantidade\nquarto\nquase\nque\nquebradico\nqueijo\nqueque\nquer\nquestao\nquestionario\nquota\nra\nrabo\nradar\nradio\nraiva\nrampa\nrancho\nranhura\nrapido\nraposa\nraro\nrascunho\nraso\nrastejar\nrastrear\nrato\nrazao\nreabrir\nreal\nrebanho\nrebelde\nreceber\nreceita\nreceoso\nreciclar\nrecompensa\nreconstruir\nrecordacao\nrecruta\nrecurso\nrecusar\nrede\nredor\nreduzir\nrefletir\nreforma\nrefrigerante\nregalo\nregiao\nregime\nregional\nregistro\nregra\nregulado\nregular\nreino\nreivindicacao\nrejeitar\nrelance\nrelativamente\nrelatorio\nrelaxe\nrelogio\nreluzente\nrelva\nremendo\nremeter\nremover\nrenda\nrender\nrenovar\nreparar\nrepente\nrepetir\nrepolho\nresgatar\nresistir\nresolver\nresponda\nresposta\nressalto\nrestante\nresto\nresultado\nresvalar\nretiro\nretorna\nreuniao\nreunir\nrevelar\nrevisao\nrico\nrifle\nrigido\nrim\nrio\nriqueza\nrir\nrisadinha\nrisco\nritmo\nritual\nrival\nrobo\nrobusto\nroda\nrodar\nromance\nromaria\nrosa\nrota\nrotulo\nrua\nrubor\nrubrica\nrural\nsabedoria\nsabonete\nsabor\nsafra\nsaia\nsaida\nsair\nsal\nsalada\nsalao\nsalario\nsalmao\nsaltar\nsalvar\nsangue\nsapato\nsatisfazer\nsatoshi\nsaudacao\nsaude\nsecao\nseco\nseculo\nseda\nsegmento\nsegredo\nsegue\nsegundo\nseguranca\nseguro\nseis\nsela\nselecionar\nselva\nselvagem\nsemelhante\nsemente\nseminario\nsempre\nsenhora\nsenhorita\nsenior\nsensato\nsentido\nsentir\nsereia\nserie\nserpente\nservico\nsessao\nsete\nshow\nsignificar\nsilencioso\nsilica\nsimbolo\nsimples\nsinal\nsino\nsintoma\nsistema\nsituar\nslogan\nso\nsobrancelha\nsobre\nsobrinho\nsocial\nsoco\nsocorro\nsofa\nsofrer\nsol\nsolar\nsoldado\nsoletrar\nsolido\nsolitario\nsolta\nsolucao\nsom\nsombra\nsombrinha\nsomente\nsonho\nsopa\nsorrir\nsorte\nsozinho\nspray\nsuave\nsubstituir\nsucesso\nsuco\nsuficiente\nsufoco\nsugerir\nsugestao\nsujeira\nsujeito\nsul\nsuper\nsuperficie\nsuperior\nsuporte\nsupremo\nsurpreendente\nsurpresa\nsuspeito\nsuspiro\nsussurro\nsustentar\nsusto\ntabaco\ntal\ntalento\ntamanho\ntambem\ntambor\ntamborete\ntanque\ntapete\ntarde\ntarefa\ntarifa\ntartaruga\ntatuagem\ntaxa\ntaxi\ntecido\ntela\ntelefone\ntema\ntempo\ntendencia\ntenis\ntentativas\nteoria\nter\nterminar\nterno\nterra\ntesouras\nteste\ntestemunha\ntestemunho\nteto\ntexto\ntia\ntigre\ntijolo\ntimido\ntio\ntipica\ntipo\ntitulo\ntocha\ntodo\ntodos\ntom\ntomate\ntombar\ntonto\ntopo\ntoque\ntorcao\ntornado\ntornozelo\ntorrada\ntorre\ntorrente\ntotal\ntotalidade\ntrabalho\ntraco\ntrafego\ntragico\ntrair\ntrama\ntramela\ntrancar\ntransferir\ntransportar\ntratar\ntrazer\ntreinador\ntrem\ntres\ntriangulo\ntribo\ntrigo\ntrilho\ntrimestre\ntriplo\ntriste\ntristeza\ntriunfar\ntroca\ntrofeu\ntrombada\ntrombeta\ntropecar\ntrovao\ntruque\ntubo\ntumulto\ntunel\nturista\num\numido\nunico\nunidade\nuniforme\nuniverso\nurbano\nurdidura\nusar\nusava\nuso\nusual\nutil\nutilidade\nuva\nvacuo\nvagao\nvago\nvale\nvalido\nvalise\nvalor\nvalvula\nvan\nvapor\nvara\nvaranda\nvarios\nvassoura\nvazio\nveiculo\nvela\nvelho\nvelocidade\nveludo\nvencedora\nvender\nventilador\nverao\nverbo\nverdade\nverdadeiramente\nverdadeiro\nverde\nvereda\nverifica\nverificar\nversao\nverter\nvespa\nvestem\nvestido\nvestigio\nvestir\nvestuario\nveterano\nvez\nviagem\nviavel\nvibrante\nviciado\nvicioso\nvida\nvideo\nvidro\nvincular\nvinho\nvintage\nvinte\nviolao\nviolino\nvir\nvirtual\nvirus\nvisa\nvisao\nvisita\nvislumbre\nvista\nvisual\nvital\nvitoria\nviver\nvivido\nvivo\nvoar\nvocal\nvoce\nvolta\nvolume\nvontade\nvoto\nvoz\nvulcao\nxarope\nxerife\nzangado\nzebra\nzero\nzona\nzoologico\nzumbido\n" + }, + { + "czech", + "abdikace\nabeceda\nadresa\nagrese\nakce\naktovka\nalej\nalkohol\namputace\nananas\nandulka\nanekdota\nanketa\nantika\nanulovat\narcha\narogance\nasfalt\nasistent\naspirace\nastma\nastronom\natlas\natletika\natol\nautobus\nazyl\nbabka\nbachor\nbacil\nbaculka\nbadatel\nbageta\nbagr\nbahno\nbakterie\nbalada\nbaletka\nbalkon\nbalonek\nbalvan\nbalza\nbambus\nbankomat\nbarbar\nbaret\nbarman\nbaroko\nbarva\nbaterka\nbatoh\nbavlna\nbazalka\nbazilika\nbazuka\nbedna\nberan\nbeseda\nbestie\nbeton\nbezinka\nbezmoc\nbeztak\nbicykl\nbidlo\nbiftek\nbikiny\nbilance\nbiograf\nbiolog\nbitva\nbizon\nblahobyt\nblatouch\nblecha\nbledule\nblesk\nblikat\nblizna\nblokovat\nbloudit\nblud\nbobek\nbobr\nbodlina\nbodnout\nbohatost\nbojkot\nbojovat\nbokorys\nbolest\nborec\nborovice\nbota\nboubel\nbouchat\nbouda\nboule\nbourat\nboxer\nbradavka\nbrambora\nbranka\nbratr\nbrepta\nbriketa\nbrko\nbrloh\nbronz\nbroskev\nbrunetka\nbrusinka\nbrzda\nbrzy\nbublina\nbubnovat\nbuchta\nbuditel\nbudka\nbudova\nbufet\nbujarost\nbukvice\nbuldok\nbulva\nbunda\nbunkr\nburza\nbutik\nbuvol\nbuzola\nbydlet\nbylina\nbytovka\nbzukot\ncapart\ncarevna\ncedr\ncedule\ncejch\ncejn\ncela\nceler\ncelkem\ncelnice\ncenina\ncennost\ncenovka\ncentrum\ncenzor\ncestopis\ncetka\nchalupa\nchapadlo\ncharita\nchata\nchechtat\nchemie\nchichot\nchirurg\nchlad\nchleba\nchlubit\nchmel\nchmura\nchobot\nchochol\nchodba\ncholera\nchomout\nchopit\nchoroba\nchov\nchrapot\nchrlit\nchrt\nchrup\nchtivost\nchudina\nchutnat\nchvat\nchvilka\nchvost\nchyba\nchystat\nchytit\ncibule\ncigareta\ncihelna\ncihla\ncinkot\ncirkus\ncisterna\ncitace\ncitrus\ncizinec\ncizost\nclona\ncokoliv\ncouvat\nctitel\nctnost\ncudnost\ncuketa\ncukr\ncupot\ncvaknout\ncval\ncvik\ncvrkot\ncyklista\ndaleko\ndareba\ndatel\ndatum\ndcera\ndebata\ndechovka\ndecibel\ndeficit\ndeflace\ndekl\ndekret\ndemokrat\ndeprese\nderby\ndeska\ndetektiv\ndikobraz\ndiktovat\ndioda\ndiplom\ndisk\ndisplej\ndivadlo\ndivoch\ndlaha\ndlouho\ndluhopis\ndnes\ndobro\ndobytek\ndocent\ndochutit\ndodnes\ndohled\ndohoda\ndohra\ndojem\ndojnice\ndoklad\ndokola\ndoktor\ndokument\ndolar\ndoleva\ndolina\ndoma\ndominant\ndomluvit\ndomov\ndonutit\ndopad\ndopis\ndoplnit\ndoposud\ndoprovod\ndopustit\ndorazit\ndorost\ndort\ndosah\ndoslov\ndostatek\ndosud\ndosyta\ndotaz\ndotek\ndotknout\ndoufat\ndoutnat\ndovozce\ndozadu\ndoznat\ndozorce\ndrahota\ndrak\ndramatik\ndravec\ndraze\ndrdol\ndrobnost\ndrogerie\ndrozd\ndrsnost\ndrtit\ndrzost\nduben\nduchovno\ndudek\nduha\nduhovka\ndusit\ndusno\ndutost\ndvojice\ndvorec\ndynamit\nekolog\nekonomie\nelektron\nelipsa\nemail\nemise\nemoce\nempatie\nepizoda\nepocha\nepopej\nepos\nesej\nesence\neskorta\neskymo\netiketa\neuforie\nevoluce\nexekuce\nexkurze\nexpedice\nexploze\nexport\nextrakt\nfacka\nfajfka\nfakulta\nfanatik\nfantazie\nfarmacie\nfavorit\nfazole\nfederace\nfejeton\nfenka\nfialka\nfigurant\nfilozof\nfiltr\nfinance\nfinta\nfixace\nfjord\nflanel\nflirt\nflotila\nfond\nfosfor\nfotbal\nfotka\nfoton\nfrakce\nfreska\nfronta\nfukar\nfunkce\nfyzika\ngaleje\ngarant\ngenetika\ngeolog\ngilotina\nglazura\nglejt\ngolem\ngolfista\ngotika\ngraf\ngramofon\ngranule\ngrep\ngril\ngrog\ngroteska\nguma\nhadice\nhadr\nhala\nhalenka\nhanba\nhanopis\nharfa\nharpuna\nhavran\nhebkost\nhejkal\nhejno\nhejtman\nhektar\nhelma\nhematom\nherec\nherna\nheslo\nhezky\nhistorik\nhladovka\nhlasivky\nhlava\nhledat\nhlen\nhlodavec\nhloh\nhloupost\nhltat\nhlubina\nhluchota\nhmat\nhmota\nhmyz\nhnis\nhnojivo\nhnout\nhoblina\nhoboj\nhoch\nhodiny\nhodlat\nhodnota\nhodovat\nhojnost\nhokej\nholinka\nholka\nholub\nhomole\nhonitba\nhonorace\nhoral\nhorda\nhorizont\nhorko\nhorlivec\nhormon\nhornina\nhoroskop\nhorstvo\nhospoda\nhostina\nhotovost\nhouba\nhouf\nhoupat\nhouska\nhovor\nhradba\nhranice\nhravost\nhrazda\nhrbolek\nhrdina\nhrdlo\nhrdost\nhrnek\nhrobka\nhromada\nhrot\nhrouda\nhrozen\nhrstka\nhrubost\nhryzat\nhubenost\nhubnout\nhudba\nhukot\nhumr\nhusita\nhustota\nhvozd\nhybnost\nhydrant\nhygiena\nhymna\nhysterik\nidylka\nihned\nikona\niluze\nimunita\ninfekce\ninflace\ninkaso\ninovace\ninspekce\ninternet\ninvalida\ninvestor\ninzerce\nironie\njablko\njachta\njahoda\njakmile\njakost\njalovec\njantar\njarmark\njaro\njasan\njasno\njatka\njavor\njazyk\njedinec\njedle\njednatel\njehlan\njekot\njelen\njelito\njemnost\njenom\njepice\njeseter\njevit\njezdec\njezero\njinak\njindy\njinoch\njiskra\njistota\njitrnice\njizva\njmenovat\njogurt\njurta\nkabaret\nkabel\nkabinet\nkachna\nkadet\nkadidlo\nkahan\nkajak\nkajuta\nkakao\nkaktus\nkalamita\nkalhoty\nkalibr\nkalnost\nkamera\nkamkoliv\nkamna\nkanibal\nkanoe\nkantor\nkapalina\nkapela\nkapitola\nkapka\nkaple\nkapota\nkapr\nkapusta\nkapybara\nkaramel\nkarotka\nkarton\nkasa\nkatalog\nkatedra\nkauce\nkauza\nkavalec\nkazajka\nkazeta\nkazivost\nkdekoliv\nkdesi\nkedluben\nkemp\nkeramika\nkino\nklacek\nkladivo\nklam\nklapot\nklasika\nklaun\nklec\nklenba\nklepat\nklesnout\nklid\nklima\nklisna\nklobouk\nklokan\nklopa\nkloub\nklubovna\nklusat\nkluzkost\nkmen\nkmitat\nkmotr\nkniha\nknot\nkoalice\nkoberec\nkobka\nkobliha\nkobyla\nkocour\nkohout\nkojenec\nkokos\nkoktejl\nkolaps\nkoleda\nkolize\nkolo\nkomando\nkometa\nkomik\nkomnata\nkomora\nkompas\nkomunita\nkonat\nkoncept\nkondice\nkonec\nkonfese\nkongres\nkonina\nkonkurs\nkontakt\nkonzerva\nkopanec\nkopie\nkopnout\nkoprovka\nkorbel\nkorektor\nkormidlo\nkoroptev\nkorpus\nkoruna\nkoryto\nkorzet\nkosatec\nkostka\nkotel\nkotleta\nkotoul\nkoukat\nkoupelna\nkousek\nkouzlo\nkovboj\nkoza\nkozoroh\nkrabice\nkrach\nkrajina\nkralovat\nkrasopis\nkravata\nkredit\nkrejcar\nkresba\nkreveta\nkriket\nkritik\nkrize\nkrkavec\nkrmelec\nkrmivo\nkrocan\nkrok\nkronika\nkropit\nkroupa\nkrovka\nkrtek\nkruhadlo\nkrupice\nkrutost\nkrvinka\nkrychle\nkrypta\nkrystal\nkryt\nkudlanka\nkufr\nkujnost\nkukla\nkulajda\nkulich\nkulka\nkulomet\nkultura\nkuna\nkupodivu\nkurt\nkurzor\nkutil\nkvalita\nkvasinka\nkvestor\nkynolog\nkyselina\nkytara\nkytice\nkytka\nkytovec\nkyvadlo\nlabrador\nlachtan\nladnost\nlaik\nlakomec\nlamela\nlampa\nlanovka\nlasice\nlaso\nlastura\nlatinka\nlavina\nlebka\nleckdy\nleden\nlednice\nledovka\nledvina\nlegenda\nlegie\nlegrace\nlehce\nlehkost\nlehnout\nlektvar\nlenochod\nlentilka\nlepenka\nlepidlo\nletadlo\nletec\nletmo\nletokruh\nlevhart\nlevitace\nlevobok\nlibra\nlichotka\nlidojed\nlidskost\nlihovina\nlijavec\nlilek\nlimetka\nlinie\nlinka\nlinoleum\nlistopad\nlitina\nlitovat\nlobista\nlodivod\nlogika\nlogoped\nlokalita\nloket\nlomcovat\nlopata\nlopuch\nlord\nlosos\nlotr\nloudal\nlouh\nlouka\nlouskat\nlovec\nlstivost\nlucerna\nlucifer\nlump\nlusk\nlustrace\nlvice\nlyra\nlyrika\nlysina\nmadam\nmadlo\nmagistr\nmahagon\nmajetek\nmajitel\nmajorita\nmakak\nmakovice\nmakrela\nmalba\nmalina\nmalovat\nmalvice\nmaminka\nmandle\nmanko\nmarnost\nmasakr\nmaskot\nmasopust\nmatice\nmatrika\nmaturita\nmazanec\nmazivo\nmazlit\nmazurka\nmdloba\nmechanik\nmeditace\nmedovina\nmelasa\nmeloun\nmentolka\nmetla\nmetoda\nmetr\nmezera\nmigrace\nmihnout\nmihule\nmikina\nmikrofon\nmilenec\nmilimetr\nmilost\nmimika\nmincovna\nminibar\nminomet\nminulost\nmiska\nmistr\nmixovat\nmladost\nmlha\nmlhovina\nmlok\nmlsat\nmluvit\nmnich\nmnohem\nmobil\nmocnost\nmodelka\nmodlitba\nmohyla\nmokro\nmolekula\nmomentka\nmonarcha\nmonokl\nmonstrum\nmontovat\nmonzun\nmosaz\nmoskyt\nmost\nmotivace\nmotorka\nmotyka\nmoucha\nmoudrost\nmozaika\nmozek\nmozol\nmramor\nmravenec\nmrkev\nmrtvola\nmrzet\nmrzutost\nmstitel\nmudrc\nmuflon\nmulat\nmumie\nmunice\nmuset\nmutace\nmuzeum\nmuzikant\nmyslivec\nmzda\nnabourat\nnachytat\nnadace\nnadbytek\nnadhoz\nnadobro\nnadpis\nnahlas\nnahnat\nnahodile\nnahradit\nnaivita\nnajednou\nnajisto\nnajmout\nnaklonit\nnakonec\nnakrmit\nnalevo\nnamazat\nnamluvit\nnanometr\nnaoko\nnaopak\nnaostro\nnapadat\nnapevno\nnaplnit\nnapnout\nnaposled\nnaprosto\nnarodit\nnaruby\nnarychlo\nnasadit\nnasekat\nnaslepo\nnastat\nnatolik\nnavenek\nnavrch\nnavzdory\nnazvat\nnebe\nnechat\nnecky\nnedaleko\nnedbat\nneduh\nnegace\nnehet\nnehoda\nnejen\nnejprve\nneklid\nnelibost\nnemilost\nnemoc\nneochota\nneonka\nnepokoj\nnerost\nnerv\nnesmysl\nnesoulad\nnetvor\nneuron\nnevina\nnezvykle\nnicota\nnijak\nnikam\nnikdy\nnikl\nnikterak\nnitro\nnocleh\nnohavice\nnominace\nnora\nnorek\nnositel\nnosnost\nnouze\nnoviny\nnovota\nnozdra\nnuda\nnudle\nnuget\nnutit\nnutnost\nnutrie\nnymfa\nobal\nobarvit\nobava\nobdiv\nobec\nobehnat\nobejmout\nobezita\nobhajoba\nobilnice\nobjasnit\nobjekt\nobklopit\noblast\noblek\nobliba\nobloha\nobluda\nobnos\nobohatit\nobojek\nobout\nobrazec\nobrna\nobruba\nobrys\nobsah\nobsluha\nobstarat\nobuv\nobvaz\nobvinit\nobvod\nobvykle\nobyvatel\nobzor\nocas\nocel\nocenit\nochladit\nochota\nochrana\nocitnout\nodboj\nodbyt\nodchod\nodcizit\nodebrat\nodeslat\nodevzdat\nodezva\nodhadce\nodhodit\nodjet\nodjinud\nodkaz\nodkoupit\nodliv\nodluka\nodmlka\nodolnost\nodpad\nodpis\nodplout\nodpor\nodpustit\nodpykat\nodrazka\nodsoudit\nodstup\nodsun\nodtok\nodtud\nodvaha\nodveta\nodvolat\nodvracet\nodznak\nofina\nofsajd\nohlas\nohnisko\nohrada\nohrozit\nohryzek\nokap\nokenice\noklika\nokno\nokouzlit\nokovy\nokrasa\nokres\nokrsek\nokruh\nokupant\nokurka\nokusit\nolejnina\nolizovat\nomak\nomeleta\nomezit\nomladina\nomlouvat\nomluva\nomyl\nonehdy\nopakovat\nopasek\noperace\nopice\nopilost\nopisovat\nopora\nopozice\nopravdu\noproti\norbital\norchestr\norgie\norlice\norloj\nortel\nosada\noschnout\nosika\nosivo\noslava\noslepit\noslnit\noslovit\nosnova\nosoba\nosolit\nospalec\nosten\nostraha\nostuda\nostych\nosvojit\noteplit\notisk\notop\notrhat\notrlost\notrok\notruby\notvor\novanout\novar\noves\novlivnit\novoce\noxid\nozdoba\npachatel\npacient\npadouch\npahorek\npakt\npalanda\npalec\npalivo\npaluba\npamflet\npamlsek\npanenka\npanika\npanna\npanovat\npanstvo\npantofle\npaprika\nparketa\nparodie\nparta\nparuka\nparyba\npaseka\npasivita\npastelka\npatent\npatrona\npavouk\npazneht\npazourek\npecka\npedagog\npejsek\npeklo\npeloton\npenalta\npendrek\npenze\nperiskop\npero\npestrost\npetarda\npetice\npetrolej\npevnina\npexeso\npianista\npiha\npijavice\npikle\npiknik\npilina\npilnost\npilulka\npinzeta\npipeta\npisatel\npistole\npitevna\npivnice\npivovar\nplacenta\nplakat\nplamen\nplaneta\nplastika\nplatit\nplavidlo\nplaz\nplech\nplemeno\nplenta\nples\npletivo\nplevel\nplivat\nplnit\nplno\nplocha\nplodina\nplomba\nplout\npluk\nplyn\npobavit\npobyt\npochod\npocit\npoctivec\npodat\npodcenit\npodepsat\npodhled\npodivit\npodklad\npodmanit\npodnik\npodoba\npodpora\npodraz\npodstata\npodvod\npodzim\npoezie\npohanka\npohnutka\npohovor\npohroma\npohyb\npointa\npojistka\npojmout\npokazit\npokles\npokoj\npokrok\npokuta\npokyn\npoledne\npolibek\npolknout\npoloha\npolynom\npomalu\npominout\npomlka\npomoc\npomsta\npomyslet\nponechat\nponorka\nponurost\npopadat\npopel\npopisek\npoplach\npoprosit\npopsat\npopud\nporadce\nporce\nporod\nporucha\nporyv\nposadit\nposed\nposila\nposkok\nposlanec\nposoudit\npospolu\npostava\nposudek\nposyp\npotah\npotkan\npotlesk\npotomek\npotrava\npotupa\npotvora\npoukaz\npouto\npouzdro\npovaha\npovidla\npovlak\npovoz\npovrch\npovstat\npovyk\npovzdech\npozdrav\npozemek\npoznatek\npozor\npozvat\npracovat\nprahory\npraktika\nprales\npraotec\npraporek\nprase\npravda\nprincip\nprkno\nprobudit\nprocento\nprodej\nprofese\nprohra\nprojekt\nprolomit\npromile\npronikat\npropad\nprorok\nprosba\nproton\nproutek\nprovaz\nprskavka\nprsten\nprudkost\nprut\nprvek\nprvohory\npsanec\npsovod\npstruh\nptactvo\npuberta\npuch\npudl\npukavec\npuklina\npukrle\npult\npumpa\npunc\npupen\npusa\npusinka\npustina\nputovat\nputyka\npyramida\npysk\npytel\nracek\nrachot\nradiace\nradnice\nradon\nraft\nragby\nraketa\nrakovina\nrameno\nrampouch\nrande\nrarach\nrarita\nrasovna\nrastr\nratolest\nrazance\nrazidlo\nreagovat\nreakce\nrecept\nredaktor\nreferent\nreflex\nrejnok\nreklama\nrekord\nrekrut\nrektor\nreputace\nrevize\nrevma\nrevolver\nrezerva\nriskovat\nriziko\nrobotika\nrodokmen\nrohovka\nrokle\nrokoko\nromaneto\nropovod\nropucha\nrorejs\nrosol\nrostlina\nrotmistr\nrotoped\nrotunda\nroubenka\nroucho\nroup\nroura\nrovina\nrovnice\nrozbor\nrozchod\nrozdat\nrozeznat\nrozhodce\nrozinka\nrozjezd\nrozkaz\nrozloha\nrozmar\nrozpad\nrozruch\nrozsah\nroztok\nrozum\nrozvod\nrubrika\nruchadlo\nrukavice\nrukopis\nryba\nrybolov\nrychlost\nrydlo\nrypadlo\nrytina\nryzost\nsadista\nsahat\nsako\nsamec\nsamizdat\nsamota\nsanitka\nsardinka\nsasanka\nsatelit\nsazba\nsazenice\nsbor\nschovat\nsebranka\nsecese\nsedadlo\nsediment\nsedlo\nsehnat\nsejmout\nsekera\nsekta\nsekunda\nsekvoje\nsemeno\nseno\nservis\nsesadit\nseshora\nseskok\nseslat\nsestra\nsesuv\nsesypat\nsetba\nsetina\nsetkat\nsetnout\nsetrvat\nsever\nseznam\nshoda\nshrnout\nsifon\nsilnice\nsirka\nsirotek\nsirup\nsituace\nskafandr\nskalisko\nskanzen\nskaut\nskeptik\nskica\nskladba\nsklenice\nsklo\nskluz\nskoba\nskokan\nskoro\nskripta\nskrz\nskupina\nskvost\nskvrna\nslabika\nsladidlo\nslanina\nslast\nslavnost\nsledovat\nslepec\nsleva\nslezina\nslib\nslina\nsliznice\nslon\nsloupek\nslovo\nsluch\nsluha\nslunce\nslupka\nslza\nsmaragd\nsmetana\nsmilstvo\nsmlouva\nsmog\nsmrad\nsmrk\nsmrtka\nsmutek\nsmysl\nsnad\nsnaha\nsnob\nsobota\nsocha\nsodovka\nsokol\nsopka\nsotva\nsouboj\nsoucit\nsoudce\nsouhlas\nsoulad\nsoumrak\nsouprava\nsoused\nsoutok\nsouviset\nspalovna\nspasitel\nspis\nsplav\nspodek\nspojenec\nspolu\nsponzor\nspornost\nspousta\nsprcha\nspustit\nsranda\nsraz\nsrdce\nsrna\nsrnec\nsrovnat\nsrpen\nsrst\nsrub\nstanice\nstarosta\nstatika\nstavba\nstehno\nstezka\nstodola\nstolek\nstopa\nstorno\nstoupat\nstrach\nstres\nstrhnout\nstrom\nstruna\nstudna\nstupnice\nstvol\nstyk\nsubjekt\nsubtropy\nsuchar\nsudost\nsukno\nsundat\nsunout\nsurikata\nsurovina\nsvah\nsvalstvo\nsvetr\nsvatba\nsvazek\nsvisle\nsvitek\nsvoboda\nsvodidlo\nsvorka\nsvrab\nsykavka\nsykot\nsynek\nsynovec\nsypat\nsypkost\nsyrovost\nsysel\nsytost\ntabletka\ntabule\ntahoun\ntajemno\ntajfun\ntajga\ntajit\ntajnost\ntaktika\ntamhle\ntampon\ntancovat\ntanec\ntanker\ntapeta\ntavenina\ntazatel\ntechnika\ntehdy\ntekutina\ntelefon\ntemnota\ntendence\ntenista\ntenor\nteplota\ntepna\nteprve\nterapie\ntermoska\ntextil\nticho\ntiskopis\ntitulek\ntkadlec\ntkanina\ntlapka\ntleskat\ntlukot\ntlupa\ntmel\ntoaleta\ntopinka\ntopol\ntorzo\ntouha\ntoulec\ntradice\ntraktor\ntramp\ntrasa\ntraverza\ntrefit\ntrest\ntrezor\ntrhavina\ntrhlina\ntrochu\ntrojice\ntroska\ntrouba\ntrpce\ntrpitel\ntrpkost\ntrubec\ntruchlit\ntruhlice\ntrus\ntrvat\ntudy\ntuhnout\ntuhost\ntundra\nturista\nturnaj\ntuzemsko\ntvaroh\ntvorba\ntvrdost\ntvrz\ntygr\ntykev\nubohost\nuboze\nubrat\nubrousek\nubrus\nubytovna\nucho\nuctivost\nudivit\nuhradit\nujednat\nujistit\nujmout\nukazatel\nuklidnit\nuklonit\nukotvit\nukrojit\nulice\nulita\nulovit\numyvadlo\nunavit\nuniforma\nuniknout\nupadnout\nuplatnit\nuplynout\nupoutat\nupravit\nuran\nurazit\nusednout\nusilovat\nusmrtit\nusnadnit\nusnout\nusoudit\nustlat\nustrnout\nutahovat\nutkat\nutlumit\nutonout\nutopenec\nutrousit\nuvalit\nuvolnit\nuvozovka\nuzdravit\nuzel\nuzenina\nuzlina\nuznat\nvagon\nvalcha\nvaloun\nvana\nvandal\nvanilka\nvaran\nvarhany\nvarovat\nvcelku\nvchod\nvdova\nvedro\nvegetace\nvejce\nvelbloud\nveletrh\nvelitel\nvelmoc\nvelryba\nvenkov\nveranda\nverze\nveselka\nveskrze\nvesnice\nvespodu\nvesta\nveterina\nveverka\nvibrace\nvichr\nvideohra\nvidina\nvidle\nvila\nvinice\nviset\nvitalita\nvize\nvizitka\nvjezd\nvklad\nvkus\nvlajka\nvlak\nvlasec\nvlevo\nvlhkost\nvliv\nvlnovka\nvloupat\nvnucovat\nvnuk\nvoda\nvodivost\nvodoznak\nvodstvo\nvojensky\nvojna\nvojsko\nvolant\nvolba\nvolit\nvolno\nvoskovka\nvozidlo\nvozovna\nvpravo\nvrabec\nvracet\nvrah\nvrata\nvrba\nvrcholek\nvrhat\nvrstva\nvrtule\nvsadit\nvstoupit\nvstup\nvtip\nvybavit\nvybrat\nvychovat\nvydat\nvydra\nvyfotit\nvyhledat\nvyhnout\nvyhodit\nvyhradit\nvyhubit\nvyjasnit\nvyjet\nvyjmout\nvyklopit\nvykonat\nvylekat\nvymazat\nvymezit\nvymizet\nvymyslet\nvynechat\nvynikat\nvynutit\nvypadat\nvyplatit\nvypravit\nvypustit\nvyrazit\nvyrovnat\nvyrvat\nvyslovit\nvysoko\nvystavit\nvysunout\nvysypat\nvytasit\nvytesat\nvytratit\nvyvinout\nvyvolat\nvyvrhel\nvyzdobit\nvyznat\nvzadu\nvzbudit\nvzchopit\nvzdor\nvzduch\nvzdychat\nvzestup\nvzhledem\nvzkaz\nvzlykat\nvznik\nvzorek\nvzpoura\nvztah\nvztek\nxylofon\nzabrat\nzabydlet\nzachovat\nzadarmo\nzadusit\nzafoukat\nzahltit\nzahodit\nzahrada\nzahynout\nzajatec\nzajet\nzajistit\nzaklepat\nzakoupit\nzalepit\nzamezit\nzamotat\nzamyslet\nzanechat\nzanikat\nzaplatit\nzapojit\nzapsat\nzarazit\nzastavit\nzasunout\nzatajit\nzatemnit\nzatknout\nzaujmout\nzavalit\nzavelet\nzavinit\nzavolat\nzavrtat\nzazvonit\nzbavit\nzbrusu\nzbudovat\nzbytek\nzdaleka\nzdarma\nzdatnost\nzdivo\nzdobit\nzdroj\nzdvih\nzdymadlo\nzelenina\nzeman\nzemina\nzeptat\nzezadu\nzezdola\nzhatit\nzhltnout\nzhluboka\nzhotovit\nzhruba\nzima\nzimnice\nzjemnit\nzklamat\nzkoumat\nzkratka\nzkumavka\nzlato\nzlehka\nzloba\nzlom\nzlost\nzlozvyk\nzmapovat\nzmar\nzmatek\nzmije\nzmizet\nzmocnit\nzmodrat\nzmrzlina\nzmutovat\nznak\nznalost\nznamenat\nznovu\nzobrazit\nzotavit\nzoubek\nzoufale\nzplodit\nzpomalit\nzprava\nzprostit\nzprudka\nzprvu\nzrada\nzranit\nzrcadlo\nzrnitost\nzrno\nzrovna\nzrychlit\nzrzavost\nzticha\nztratit\nzubovina\nzubr\nzvednout\nzvenku\nzvesela\nzvon\nzvrat\nzvukovod\nzvyk" + } + }; + + WordLists = dict; + } + + #region IWordlistSource Members + + /// + /// Load the word list for the given name. This is an asynchronous operation. + /// + /// The name. + /// A task which returns the word list. + public Task LoadAsync(string name) + { + string list = WordLists.TryGet(name); + if (list == null) + return null; + return Task.FromResult(new WordList(list.Split(new[] { "\n" }, StringSplitOptions.RemoveEmptyEntries), + name == "japanese" ? ' ' : ' ', name + )); + } + + #endregion + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Bip39/HardcodedWordListSource.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Bip39/HardcodedWordListSource.cs.meta new file mode 100644 index 0000000..a931b8e --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Bip39/HardcodedWordListSource.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0b78649f1b5ffe6439173cee44edcac3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Bip39/IWordListSource.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Bip39/IWordListSource.cs new file mode 100644 index 0000000..3592e61 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Bip39/IWordListSource.cs @@ -0,0 +1,17 @@ +using System.Threading.Tasks; + +namespace Solana.Unity.Wallet.Bip39 +{ + /// + /// Specifies functionality for the wordlist source. + /// + internal interface IWordlistSource + { + /// + /// Load the wordlist. + /// + /// The name of the wordlist. + /// A task that returns the wordlist. + Task LoadAsync(string name); + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Bip39/IWordListSource.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Bip39/IWordListSource.cs.meta new file mode 100644 index 0000000..9364c10 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Bip39/IWordListSource.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 788e10e171f309a438529c85f89b0a09 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Bip39/KdTable.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Bip39/KdTable.cs new file mode 100644 index 0000000..96c5518 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Bip39/KdTable.cs @@ -0,0 +1,106 @@ +// unset + +using System; +using System.Linq; +using System.Text; + +namespace Solana.Unity.Wallet.Bip39 +{ + /// + /// Implements the functionality for normalization. + /// + internal static class KdTable + { + /// + /// Normalizes the passed string. + /// + /// The string to normalize. + /// The normalized string. + /// Thrown if the input string could not be normalized. + public static string NormalizeKd(string str) + { + StringBuilder builder = new(str.Length); + foreach (char c in str) + { + if (!Supported(c)) + { + throw new PlatformNotSupportedException("the input string can't be normalized on this platform"); + } + Substitute(c, builder); + } + return builder.ToString(); + } + + /// + /// Substitutes the given character according to the substitution table. + /// + /// The character to substitute. + /// The string builder. + private static void Substitute(char c, StringBuilder builder) + { + for (int i = 0; i < SubstitutionTable.Length; i++) + { + char substitutedChar = SubstitutionTable[i]; + if (substitutedChar == c) + { + Substitute(i, builder); + return; + } + if (substitutedChar > c) + break; + while (SubstitutionTable[i] != '\n') + i++; + } + builder.Append(c); + } + + /// + /// Substitutes the given position according to the substitution table. + /// + /// The position. + /// The string builder. + private static void Substitute(int pos, StringBuilder builder) + { + for (int i = pos + 1; i < SubstitutionTable.Length; i++) + { + if (SubstitutionTable[i] == '\n') + break; + builder.Append(SubstitutionTable[i]); + } + } + + /// + /// Checks if the character is supported. + /// + /// The character to check. + /// True if it is, otherwise false. + private static bool Supported(char c) + { + return SupportedChars.Any(r => r[0] <= c && c <= r[1]); + } + + /// + /// The supported characters. + /// + private static readonly int[][] SupportedChars = { + new[]{0,1000}, + new[]{12352,12447}, + new[]{12448,12543}, + new[]{19968,40959}, + new[]{13312,19967}, + new[]{131072,173791}, + new[]{63744,64255}, + new[]{194560,195103}, + new[]{13056,13311}, + new[]{12288,12351}, + new[]{65280,65535}, + new[]{8192,8303}, + new[]{8352,8399}, + }; + + /// + /// The substitution table for normalization. + /// + private const string SubstitutionTable = " \n¨ ̈\nªa\n¯ Ì„\n²2\n³3\n´ Ì\nµμ\n¸ ̧\n¹1\nºo\n¼1â„4\n½1â„2\n¾3â„4\nÀAÌ€\nÃAÌ\nÂAÌ‚\nÃÃ\nÄÄ\nÃ…AÌŠ\nÇÇ\nÈEÌ€\nÉEÌ\nÊEÌ‚\nËË\nÃŒIÌ€\nÃIÌ\nÃŽIÌ‚\nÃÏ\nÑÑ\nÃ’OÌ€\nÓOÌ\nÔOÌ‚\nÕÕ\nÖÖ\nÙUÌ€\nÚUÌ\nÛUÌ‚\nÜÜ\nÃYÌ\nàaÌ€\náaÌ\nâaÌ‚\nãã\nää\nÃ¥aÌŠ\nçç\nèeÌ€\néeÌ\nêeÌ‚\nëë\nìiÌ€\níiÌ\nîiÌ‚\nïï\nññ\nòoÌ€\nóoÌ\nôoÌ‚\nõõ\nöö\nùuÌ€\núuÌ\nûuÌ‚\nüü\nýyÌ\nÿÿ\nÄ€AÌ„\nÄaÌ„\nÄ‚Ă\năă\nÄ„Ą\nÄ…ą\nĆCÌ\nćcÌ\nĈCÌ‚\nĉcÌ‚\nÄŠĊ\nÄ‹ċ\nÄŒCÌŒ\nÄcÌŒ\nÄŽDÌŒ\nÄdÌŒ\nÄ’EÌ„\nÄ“eÌ„\nÄ”Ĕ\nÄ•ĕ\nÄ–Ė\nÄ—ė\nĘĘ\nÄ™ę\nÄšEÌŒ\nÄ›eÌŒ\nÄœGÌ‚\nÄgÌ‚\nÄžĞ\nÄŸğ\nÄ Ġ\nÄ¡ġ\nÄ¢Ģ\nÄ£ģ\nĤHÌ‚\nÄ¥hÌ‚\nĨĨ\nÄ©ĩ\nĪIÌ„\nÄ«iÌ„\nĬĬ\nÄ­ĭ\nÄ®Į\nįį\nİİ\nIJIJ\nijij\nÄ´JÌ‚\nĵjÌ‚\nĶĶ\nÄ·ķ\nĹLÌ\nĺlÌ\nÄ»Ļ\nļļ\nĽLÌŒ\nľlÌŒ\nÄ¿L·\nÅ€l·\nŃNÌ\nÅ„nÌ\nÅ…Ņ\nņņ\nŇNÌŒ\nňnÌŒ\nʼnʼn\nÅŒOÌ„\nÅoÌ„\nÅŽŎ\nÅŏ\nÅOÌ‹\nÅ‘oÌ‹\nÅ”RÌ\nÅ•rÌ\nÅ–Ŗ\nÅ—ŗ\nŘRÌŒ\nÅ™rÌŒ\nÅšSÌ\nÅ›sÌ\nÅœSÌ‚\nÅsÌ‚\nÅžŞ\nÅŸş\nÅ SÌŒ\nÅ¡sÌŒ\nÅ¢Ţ\nÅ£ţ\nŤTÌŒ\nÅ¥tÌŒ\nŨŨ\nÅ©ũ\nŪUÌ„\nÅ«uÌ„\nŬŬ\nÅ­ŭ\nÅ®UÌŠ\nůuÌŠ\nŰUÌ‹\nűuÌ‹\nŲŲ\nųų\nÅ´WÌ‚\nŵwÌ‚\nŶYÌ‚\nÅ·yÌ‚\nŸŸ\nŹZÌ\nźzÌ\nÅ»Ż\nżż\nŽZÌŒ\nžzÌŒ\nÅ¿s\nÆ OÌ›\nÆ¡oÌ›\nƯUÌ›\nưuÌ›\nÇ„DZÌŒ\nÇ…DzÌŒ\ndždzÌŒ\nLJLJ\nLjLj\nljlj\nÇŠNJ\nÇ‹Nj\nÇŒnj\nÇAÌŒ\nÇŽaÌŒ\nÇIÌŒ\nÇiÌŒ\nÇ‘OÌŒ\nÇ’oÌŒ\nÇ“UÌŒ\nÇ”uÌŒ\nÇ•Ǖ\nÇ–ǖ\nÇ—ÜÌ\nǘüÌ\nÇ™Ǚ\nÇšǚ\nÇ›Ǜ\nÇœǜ\nÇžǞ\nÇŸǟ\nÇ Ǡ\nÇ¡ǡ\nǢǢ\nǣǣ\nǦGÌŒ\nǧgÌŒ\nǨKÌŒ\nÇ©kÌŒ\nǪǪ\nÇ«ǫ\nǬǬ\nÇ­ǭ\nǮǮ\nǯǯ\nǰjÌŒ\nDZDZ\nDzDz\ndzdz\nÇ´GÌ\nǵgÌ\nǸNÌ€\nǹnÌ€\nǺAÌŠÌ\nÇ»aÌŠÌ\nǼÆÌ\nǽæÌ\nǾØÌ\nǿøÌ\nÈ€AÌ\nÈaÌ\nÈ‚AÌ‘\nȃaÌ‘\nÈ„EÌ\nÈ…eÌ\nȆEÌ‘\nȇeÌ‘\nȈIÌ\nȉiÌ\nÈŠIÌ‘\nÈ‹iÌ‘\nÈŒOÌ\nÈoÌ\nÈŽOÌ‘\nÈoÌ‘\nÈRÌ\nÈ‘rÌ\nÈ’RÌ‘\nÈ“rÌ‘\nÈ”UÌ\nÈ•uÌ\nÈ–UÌ‘\nÈ—uÌ‘\nȘȘ\nÈ™ș\nÈšȚ\nÈ›ț\nÈžHÌŒ\nÈŸhÌŒ\nȦȦ\nȧȧ\nȨȨ\nÈ©ȩ\nȪȪ\nÈ«ȫ\nȬȬ\nÈ­ȭ\nÈ®Ȯ\nȯȯ\nȰȰ\nȱȱ\nȲYÌ„\nȳyÌ„\nʰh\nʱɦ\nʲj\nʳr\nʴɹ\nʵɻ\nʶÊ\nÊ·w\nʸy\n˘ ̆\nË™ ̇\nËš ÌŠ\nË› ̨\nËœ ̃\nË Ì‹\nˠɣ\nË¡l\nË¢s\nË£x\nˤʕ\ǹ̀\nÍÌ\n̓̓\n̈́̈Ì\nʹʹ\nͺ Í…\n;;\n΄ Ì\nÎ… ̈Ì\nΆΑÌ\n··\nΈΕÌ\nΉΗÌ\nΊΙÌ\nΌΟÌ\nÎŽÎ¥Ì\nÎΩÌ\nÎϊÌ\nΪΪ\nΫΫ\nάαÌ\nέεÌ\nήηÌ\nίιÌ\nΰϋÌ\nϊϊ\nϋϋ\nόοÌ\nÏÏ…Ì\nώωÌ\nÏβ\nϑθ\nÏ’Î¥\nϓΥÌ\nϔΫ\nϕφ\nÏ–Ï€\nϰκ\nϱÏ\nϲς\nϴΘ\nϵε\nϹΣ\nЀЀ\nÐЁ\nЃГÌ\nЇЇ\nЌКÌ\nÐЍ\nЎЎ\nЙЙ\nйй\nÑѐ\nёё\nѓгÌ\nїї\nќкÌ\nÑѝ\nўў\nѶѴÌ\nѷѵÌ\nÓӁ\nӂӂ\nÓÐ̆\nӑӑ\nÓ’Ð̈\nӓӓ\nӖӖ\nӗӗ\nӚӚ\nӛӛ\nӜӜ\nÓӝ\nӞӞ\nӟӟ\nӢӢ\nӣӣ\nӤӤ\nӥӥ\nӦӦ\nӧӧ\nӪӪ\nӫӫ\nӬӬ\nÓ­Ñ̈\nӮӮ\nӯӯ\nӰӰ\nӱӱ\nӲӲ\nӳӳ\nӴӴ\nӵӵ\nӸӸ\nӹӹ\nÖ‡Õ¥Ö‚\nآآ\nأأ\nؤؤ\nإإ\nئئ\nٵاٴ\nٶوٴ\nÙ·Û‡Ù´\nٸيٴ\nÛ€Û•Ù”\nÛ‚ÛÙ”\nÛ“Û’Ù”\nऩऩ\nऱऱ\nऴऴ\nक़क़\nख़ख़\nग़ग़\nज़ज़\nड़ड़\nà¥à¤¢à¤¼\nफ़फ़\nय़य़\nোো\nৌৌ\nড়ড়\nà§à¦¢à¦¼\nয়য়\nਲ਼ਲ਼\nਸ਼ਸ਼\nਖ਼ਖ਼\nਗ਼ਗ਼\nਜ਼ਜ਼\nਫ਼ਫ਼\nୈୈ\nୋୋ\nୌୌ\nଡ଼ଡ଼\nà­à¬¢à¬¼\nஔஔ\nொொ\nோோ\nௌௌ\nైై\nೀೀ\nೇೇ\nೈೈ\nೊೊ\nೋೋ\nൊൊ\nോോ\nൌൌ\nේේ\nොෙà·\nà·à·™à·à·Š\nෞෞ\nำà¹à¸²\nຳà»àº²\nໜຫນ\nà»àº«àº¡\n༌་\nགྷགྷ\nà½à½Œà¾·\nདྷདྷ\nབྷབྷ\nཛྷཛྷ\nཀྵཀྵ\nཱཱིི\nཱཱུུ\nྲྀྲྀ\nཷྲཱྀ\nླྀླྀ\nཹླཱྀ\nà¾à½±à¾€\nྒྷྒྷ\nà¾à¾œà¾·\nྡྷྡྷ\nྦྷྦྷ\nྫྷྫྷ\nྐྵà¾à¾µ\nဦဦ\nჼნ\nᬆᬆ\nᬈᬈ\nᬊᬊ\nᬌᬌ\nᬎá¬á¬µ\nᬒᬒ\nᬻᬻ\nᬽᬽ\nᭀᭀ\ná­á¬¿á¬µ\nᭃᭃ\ná´¬A\nᴭÆ\ná´®B\ná´°D\ná´±E\nᴲƎ\ná´³G\ná´´H\ná´µI\ná´¶J\ná´·K\ná´¸L\ná´¹M\ná´ºN\ná´¼O\nᴽȢ\ná´¾P\ná´¿R\náµ€T\náµU\nᵂW\nᵃa\nᵄÉ\náµ…É‘\nᵆᴂ\nᵇb\nᵈd\nᵉe\nᵊə\nᵋɛ\nᵌɜ\náµg\náµk\náµm\nᵑŋ\náµ’o\nᵓɔ\nᵔᴖ\nᵕᴗ\náµ–p\náµ—t\nᵘu\náµ™á´\nᵚɯ\náµ›v\nᵜᴥ\náµÎ²\nᵞγ\nᵟδ\nᵠφ\nᵡχ\náµ¢i\náµ£r\nᵤu\náµ¥v\nᵦβ\nᵧγ\nᵨÏ\nᵩφ\nᵪχ\nᵸн\nᶛɒ\ná¶œc\ná¶É•\nᶞð\ná¶ŸÉœ\ná¶ f\ná¶¡ÉŸ\nᶢɡ\nᶣɥ\nᶤɨ\nᶥɩ\nᶦɪ\ná¶§áµ»\nᶨÊ\ná¶©É­\nᶪᶅ\ná¶«ÊŸ\nᶬɱ\nᶭɰ\nᶮɲ\nᶯɳ\ná¶°É´\nᶱɵ\nᶲɸ\nᶳʂ\nᶴʃ\nᶵƫ\nᶶʉ\ná¶·ÊŠ\nᶸᴜ\nᶹʋ\nᶺʌ\ná¶»z\ná¶¼Ê\nᶽʑ\nᶾʒ\nᶿθ\nḀAÌ¥\ná¸aÌ¥\nḂḂ\nḃḃ\nḄBÌ£\nḅbÌ£\nḆḆ\nḇḇ\nḈÇÌ\nḉçÌ\nḊḊ\nḋḋ\nḌDÌ£\ná¸dÌ£\nḎḎ\ná¸ḏ\ná¸Ḑ\nḑḑ\nḒDÌ­\nḓdÌ­\nḔḔ\nḕḕ\nḖEÌ„Ì\nḗeÌ„Ì\nḘEÌ­\nḙeÌ­\nḚḚ\nḛḛ\nḜḜ\ná¸ḝ\nḞḞ\nḟḟ\nḠGÌ„\nḡgÌ„\nḢḢ\nḣḣ\nḤHÌ£\nḥhÌ£\nḦḦ\nḧḧ\nḨḨ\nḩḩ\nḪHÌ®\nḫhÌ®\nḬḬ\nḭḭ\nḮÏÌ\nḯïÌ\nḰKÌ\nḱkÌ\nḲKÌ£\nḳkÌ£\nḴḴ\nḵḵ\nḶLÌ£\nḷlÌ£\nḸḸ\nḹḹ\nḺḺ\nḻḻ\nḼLÌ­\nḽlÌ­\nḾMÌ\nḿmÌ\ná¹€Ṁ\ná¹ṁ\nṂMÌ£\nṃmÌ£\nṄṄ\ná¹…ṅ\nṆNÌ£\nṇnÌ£\nṈṈ\nṉṉ\nṊNÌ­\nṋnÌ­\nṌÕÌ\ná¹õÌ\nṎṎ\ná¹ṏ\ná¹Ṑ\nṑṑ\ná¹’OÌ„Ì\nṓoÌ„Ì\ná¹”PÌ\nṕpÌ\ná¹–Ṗ\ná¹—ṗ\nṘṘ\ná¹™ṙ\nṚRÌ£\ná¹›rÌ£\nṜṜ\ná¹ṝ\nṞṞ\nṟṟ\ná¹ Ṡ\nṡṡ\ná¹¢SÌ£\ná¹£sÌ£\nṤSÌ̇\ná¹¥sÌ̇\nṦṦ\ná¹§ṧ\nṨṨ\nṩṩ\nṪṪ\nṫṫ\nṬTÌ£\ná¹­tÌ£\ná¹®Ṯ\nṯṯ\ná¹°TÌ­\ná¹±tÌ­\ná¹²Ṳ\ná¹³ṳ\ná¹´Ṵ\ná¹µṵ\ná¹¶UÌ­\ná¹·uÌ­\nṸŨÌ\ná¹¹ũÌ\nṺṺ\ná¹»ṻ\ná¹¼Ṽ\ná¹½ṽ\ná¹¾VÌ£\nṿvÌ£\nẀWÌ€\náºwÌ€\nẂWÌ\nẃwÌ\nẄẄ\nẅẅ\nẆẆ\nẇẇ\nẈWÌ£\nẉwÌ£\nẊẊ\nẋẋ\nẌẌ\náºẍ\nẎẎ\náºẏ\náºZÌ‚\nẑzÌ‚\nẒZÌ£\nẓzÌ£\nẔẔ\nẕẕ\nẖẖ\nẗẗ\nẘwÌŠ\nẙyÌŠ\nẚaʾ\nẛṡ\nẠAÌ£\nạaÌ£\nẢẢ\nảả\nẤAÌ‚Ì\nấaÌ‚Ì\nẦẦ\nầầ\nẨẨ\nẩẩ\nẪẪ\nẫẫ\nẬẬ\nậậ\nẮĂÌ\nắăÌ\nẰẰ\nằằ\nẲẲ\nẳẳ\nẴẴ\nẵẵ\nẶẶ\nặặ\nẸEÌ£\nẹeÌ£\nẺẺ\nẻẻ\nẼẼ\nẽẽ\nẾEÌ‚Ì\nếeÌ‚Ì\nỀỀ\ná»ề\nỂỂ\nểể\nỄỄ\ná»…ễ\nỆỆ\nệệ\nỈỈ\nỉỉ\nỊIÌ£\nịiÌ£\nỌOÌ£\ná»oÌ£\nỎỎ\ná»ỏ\ná»OÌ‚Ì\nốoÌ‚Ì\ná»’Ồ\nồồ\ná»”Ổ\nổổ\ná»–Ỗ\ná»—ỗ\nỘỘ\ná»™ộ\nỚOÌ›Ì\ná»›oÌ›Ì\nỜỜ\ná»ờ\nỞỞ\nởở\ná» Ỡ\nỡỡ\nỢỢ\nợợ\nỤUÌ£\nụuÌ£\nỦỦ\ná»§ủ\nỨUÌ›Ì\nứuÌ›Ì\nỪỪ\nừừ\nỬỬ\ná»­ử\ná»®Ữ\nữữ\ná»°Ự\ná»±ự\nỲYÌ€\nỳyÌ€\ná»´YÌ£\nỵyÌ£\ná»¶Ỷ\ná»·ỷ\nỸỸ\nỹỹ\nἀἀ\ná¼Î±Ì”\nἂἂ\nἃἃ\nἄἀÌ\nἅἁÌ\nἆἆ\nἇἇ\nἈἈ\nἉἉ\nἊἊ\nἋἋ\nἌἈÌ\ná¼Î‘Ì”Ì\nἎἎ\ná¼Î‘̔͂\ná¼ÎµÌ“\nἑἑ\nἒἒ\nἓἓ\nἔἐÌ\nἕἑÌ\nἘἘ\nἙἙ\nἚἚ\nἛἛ\nἜἘÌ\ná¼Î•Ì”Ì\nἠἠ\nἡἡ\nἢἢ\nἣἣ\nἤἠÌ\nἥἡÌ\nἦἦ\nἧἧ\nἨἨ\nἩἩ\nἪἪ\nἫἫ\nἬἨÌ\nἭἩÌ\nἮἮ\nἯἯ\nἰἰ\nἱἱ\nἲἲ\nἳἳ\nἴἰÌ\nἵἱÌ\nἶἶ\nἷἷ\nἸἸ\nἹἹ\nἺἺ\nἻἻ\nἼἸÌ\nἽἹÌ\nἾἾ\nἿἿ\nὀὀ\ná½Î¿Ì”\nὂὂ\nὃὃ\nὄὀÌ\nὅὁÌ\nὈὈ\nὉὉ\nὊὊ\nὋὋ\nὌὈÌ\ná½ÎŸÌ”Ì\ná½Ï…Ì“\nὑὑ\nὒὒ\nὓὓ\nὔὐÌ\nὕὑÌ\nὖὖ\nὗὗ\nὙὙ\nὛὛ\ná½Î¥Ì”Ì\nὟὟ\nὠὠ\nὡὡ\nὢὢ\nὣὣ\nὤὠÌ\nὥὡÌ\nὦὦ\nὧὧ\nὨὨ\nὩὩ\nὪὪ\nὫὫ\nὬὨÌ\nὭὩÌ\nὮὮ\nὯὯ\nὰὰ\nάαÌ\nὲὲ\nέεÌ\nὴὴ\nήηÌ\nὶὶ\nίιÌ\nὸὸ\nόοÌ\nὺὺ\nύυÌ\nὼὼ\nώωÌ\nᾀᾀ\ná¾Î±Ì”Í…\nᾂᾂ\nᾃᾃ\nᾄἀÌÍ…\nᾅἁÌÍ…\nᾆᾆ\nᾇᾇ\nᾈᾈ\nᾉᾉ\nᾊᾊ\nᾋᾋ\nᾌἈÌÍ…\ná¾Î‘Ì”ÌÍ…\nᾎᾎ\ná¾Î‘̔͂ͅ\ná¾Î·Ì“Í…\nᾑᾑ\nᾒᾒ\nᾓᾓ\nᾔἠÌÍ…\nᾕἡÌÍ…\nᾖᾖ\nᾗᾗ\nᾘᾘ\nᾙᾙ\nᾚᾚ\nᾛᾛ\nᾜἨÌÍ…\ná¾Î—Ì”ÌÍ…\nᾞᾞ\nᾟᾟ\nᾠᾠ\nᾡᾡ\nᾢᾢ\nᾣᾣ\nᾤὠÌÍ…\nᾥὡÌÍ…\nᾦᾦ\nᾧᾧ\nᾨᾨ\nᾩᾩ\nᾪᾪ\nᾫᾫ\nᾬὨÌÍ…\nᾭὩÌÍ…\nᾮᾮ\nᾯᾯ\nᾰᾰ\nᾱᾱ\nᾲᾲ\nᾳᾳ\nᾴαÌÍ…\nᾶᾶ\nᾷᾷ\nᾸᾸ\nᾹᾹ\nᾺᾺ\nΆΑÌ\nᾼᾼ\ná¾½ Ì“\nιι\n᾿ Ì“\ná¿€ Í‚\nῠ̈͂\nῂῂ\nῃῃ\nῄηÌÍ…\nῆῆ\nῇῇ\nῈῈ\nΈΕÌ\nῊῊ\nΉΗÌ\nῌῌ\nῠ̓̀\n῎ Ì“Ì\nῠ̓͂\ná¿Î¹Ì†\nῑῑ\nῒῒ\nΐϊÌ\nῖῖ\nῗῗ\nῘῘ\nῙῙ\nῚῚ\nΊΙÌ\nῠ̔̀\n῞ Ì”Ì\n῟ ̔͂\nῠῠ\ná¿¡Ï…Ì„\nῢῢ\nΰϋÌ\nῤÏÌ“\ná¿¥ÏÌ”\nῦῦ\nῧῧ\nῨῨ\nῩῩ\nῪῪ\ná¿«Î¥Ì\nῬῬ\ná¿­ ̈̀\ná¿® ̈Ì\n``\nῲῲ\nῳῳ\nῴωÌÍ…\nῶῶ\nῷῷ\nῸῸ\nΌΟÌ\nῺῺ\nΏΩÌ\nῼῼ\n´ Ì\n῾ Ì”\n  \n†\n  \n  \n  \n  \n  \n  \n  \n  \n  \n‑â€\n‗ ̳\n․.\n‥..\n…...\n  \n″′′\n‴′′′\n‶‵‵\n‷‵‵‵\n‼!!\n‾ Ì…\nâ‡??\nâˆ?!\nâ‰!?\nâ—′′′′\n⟠\nâ°0\nâ±i\nâ´4\nâµ5\nâ¶6\nâ·7\nâ¸8\nâ¹9\nâº+\nâ»âˆ’\nâ¼=\nâ½(\nâ¾)\nâ¿n\nâ‚€0\nâ‚1\nâ‚‚2\n₃3\nâ‚„4\nâ‚…5\n₆6\n₇7\n₈8\n₉9\n₊+\n₋−\n₌=\nâ‚(\n₎)\nâ‚a\nâ‚‘e\nâ‚’o\nâ‚“x\nₔə\n₨Rs\nâ„€a/c\nâ„a/s\nâ„‚C\n℃°C\nâ„…c/o\n℆c/u\nℇÆ\n℉°F\nℊg\nâ„‹H\nℌH\nâ„H\nℎh\nâ„ħ\nâ„I\nâ„‘I\nâ„’L\nâ„“l\nâ„•N\nâ„–No\nâ„™P\nℚQ\nâ„›R\nℜR\nâ„R\nâ„ SM\nâ„¡TEL\nâ„¢TM\nℤZ\nΩΩ\nℨZ\nKK\nâ„«AÌŠ\nℬB\nâ„­C\nℯe\nâ„°E\nℱF\nℳM\nâ„´o\nℵ×\nℶב\nâ„·×’\nℸד\nℹi\nâ„»FAX\nℼπ\nℽγ\nℾΓ\nℿΠ\n⅀∑\nâ……D\nâ…†d\nâ…‡e\nâ…ˆi\nâ…‰j\nâ…“1â„3\nâ…”2â„3\nâ…•1â„5\nâ…–2â„5\nâ…—3â„5\nâ…˜4â„5\nâ…™1â„6\nâ…š5â„6\nâ…›1â„8\nâ…œ3â„8\nâ…5â„8\nâ…ž7â„8\nâ…Ÿ1â„\nâ… I\nâ…¡II\nâ…¢III\nâ…£IV\nâ…¤V\nâ…¥VI\nâ…¦VII\nâ…§VIII\nâ…¨IX\nâ…©X\nâ…ªXI\nâ…«XII\nâ…¬L\nâ…­C\nâ…®D\nâ…¯M\nâ…°i\nâ…±ii\nâ…²iii\nâ…³iv\nâ…´v\nâ…µvi\nâ…¶vii\nâ…·viii\nâ…¸ix\nâ…¹x\nâ…ºxi\nâ…»xii\nâ…¼l\nâ…½c\nâ…¾d\nâ…¿m\n↚â†Ì¸\n↛↛\n↮↮\nâ‡â‡Ì¸\n⇎⇎\nâ‡â‡’̸\n∄∄\n∉∉\n∌∌\n∤∤\n∦∦\n∬∫∫\n∭∫∫∫\n∯∮∮\n∰∮∮∮\nâ‰âˆ¼Ì¸\n≄≄\n≇≇\n≉≉\n≠≠\n≢≢\n≭â‰Ì¸\n≮≮\n≯≯\n≰≰\n≱≱\n≴≴\n≵≵\n≸≸\n≹≹\n⊀⊀\nâŠâ‰»Ì¸\n⊄⊄\n⊅⊅\n⊈⊈\n⊉⊉\n⊬⊬\n⊭⊭\n⊮⊮\n⊯⊯\n⋠⋠\n⋡⋡\n⋢⋢\n⋣⋣\n⋪⋪\n⋫⋫\n⋬⋬\n⋭⋭\n〈〈\n〉〉\nâ‘ 1\nâ‘¡2\nâ‘¢3\nâ‘£4\n⑤5\nâ‘¥6\n⑦7\nâ‘§8\n⑨9\nâ‘©10\n⑪11\nâ‘«12\n⑬13\nâ‘­14\nâ‘®15\n⑯16\nâ‘°17\n⑱18\n⑲19\n⑳20\nâ‘´(1)\n⑵(2)\nâ‘¶(3)\nâ‘·(4)\n⑸(5)\n⑹(6)\n⑺(7)\nâ‘»(8)\n⑼(9)\n⑽(10)\n⑾(11)\nâ‘¿(12)\nâ’€(13)\nâ’(14)\nâ’‚(15)\nâ’ƒ(16)\nâ’„(17)\nâ’…(18)\nâ’†(19)\nâ’‡(20)\nâ’ˆ1.\nâ’‰2.\nâ’Š3.\nâ’‹4.\nâ’Œ5.\nâ’6.\nâ’Ž7.\nâ’8.\nâ’9.\nâ’‘10.\nâ’’11.\nâ’“12.\nâ’”13.\nâ’•14.\nâ’–15.\nâ’—16.\nâ’˜17.\nâ’™18.\nâ’š19.\nâ’›20.\nâ’œ(a)\nâ’(b)\nâ’ž(c)\nâ’Ÿ(d)\nâ’ (e)\nâ’¡(f)\nâ’¢(g)\nâ’£(h)\nâ’¤(i)\nâ’¥(j)\nâ’¦(k)\nâ’§(l)\nâ’¨(m)\nâ’©(n)\nâ’ª(o)\nâ’«(p)\nâ’¬(q)\nâ’­(r)\nâ’®(s)\nâ’¯(t)\nâ’°(u)\nâ’±(v)\nâ’²(w)\nâ’³(x)\nâ’´(y)\nâ’µ(z)\nâ’¶A\nâ’·B\nâ’¸C\nâ’¹D\nâ’ºE\nâ’»F\nâ’¼G\nâ’½H\nâ’¾I\nâ’¿J\nâ“€K\nâ“L\nâ“‚M\nⓃN\nâ“„O\nâ“…P\nⓆQ\nⓇR\nⓈS\nⓉT\nⓊU\nâ“‹V\nⓌW\nâ“X\nⓎY\nâ“Z\nâ“a\nâ“‘b\nâ“’c\nâ““d\nâ“”e\nâ“•f\nâ“–g\nâ“—h\nⓘi\nâ“™j\nⓚk\nâ“›l\nⓜm\nâ“n\nⓞo\nⓟp\nâ“ q\nâ“¡r\nâ“¢s\nâ“£t\nⓤu\nâ“¥v\nⓦw\nâ“§x\nⓨy\nâ“©z\n⓪0\n⨌∫∫∫∫\nâ©´::=\n⩵==\nâ©¶===\n⫝̸â«Ì¸\nâ±¼j\nâ±½V\nⵯⵡ\n⺟æ¯\n⻳龟\n⼀一\nâ¼ä¸¨\n⼂丶\n⼃丿\n⼄乙\n⼅亅\n⼆二\n⼇亠\n⼈人\n⼉儿\n⼊入\n⼋八\n⼌冂\nâ¼å†–\n⼎冫\nâ¼å‡ \nâ¼å‡µ\n⼑刀\n⼒力\n⼓勹\n⼔匕\n⼕匚\n⼖匸\nâ¼—å\n⼘åœ\nâ¼™å©\n⼚厂\n⼛厶\n⼜åˆ\nâ¼å£\n⼞囗\n⼟土\n⼠士\n⼡夂\n⼢夊\n⼣夕\n⼤大\n⼥女\n⼦å­\n⼧宀\n⼨寸\n⼩å°\n⼪尢\n⼫尸\n⼬屮\nâ¼­å±±\n⼮巛\n⼯工\nâ¼°å·±\n⼱巾\n⼲干\n⼳幺\n⼴广\n⼵廴\n⼶廾\n⼷弋\n⼸弓\nâ¼¹å½\n⼺彡\n⼻彳\n⼼心\n⼽戈\n⼾戶\n⼿手\n⽀支\nâ½æ”´\n⽂文\n⽃斗\n⽄斤\nâ½…æ–¹\n⽆无\n⽇日\n⽈曰\n⽉月\n⽊木\n⽋欠\n⽌止\nâ½æ­¹\n⽎殳\nâ½æ¯‹\nâ½æ¯”\n⽑毛\nâ½’æ°\n⽓气\n⽔水\n⽕ç«\n⽖爪\n⽗父\n⽘爻\n⽙爿\n⽚片\n⽛牙\n⽜牛\nâ½çЬ\n⽞玄\n⽟玉\n⽠瓜\n⽡瓦\n⽢甘\n⽣生\n⽤用\n⽥田\n⽦疋\nâ½§ç–’\n⽨癶\n⽩白\n⽪皮\n⽫皿\n⽬目\n⽭矛\n⽮矢\n⽯石\n⽰示\n⽱禸\n⽲禾\n⽳穴\nâ½´ç«‹\n⽵竹\nâ½¶ç±³\n⽷糸\n⽸缶\n⽹网\n⽺羊\n⽻羽\nâ½¼è€\n⽽而\n⽾耒\n⽿耳\nâ¾€è¿\nâ¾è‚‰\n⾂臣\n⾃自\n⾄至\n⾅臼\n⾆舌\n⾇舛\n⾈舟\n⾉艮\n⾊色\n⾋艸\n⾌è™\nâ¾è™«\n⾎血\nâ¾è¡Œ\nâ¾è¡£\n⾑襾\n⾒見\n⾓角\n⾔言\n⾕谷\n⾖豆\n⾗豕\n⾘豸\nâ¾™è²\n⾚赤\n⾛走\n⾜足\nâ¾èº«\n⾞車\n⾟辛\nâ¾ è¾°\n⾡辵\n⾢邑\n⾣酉\n⾤釆\n⾥里\n⾦金\nâ¾§é•·\n⾨門\n⾩阜\n⾪隶\n⾫隹\n⾬雨\nâ¾­é‘\nâ¾®éž\n⾯é¢\nâ¾°é©\n⾱韋\n⾲韭\n⾳音\nâ¾´é \n⾵風\n⾶飛\n⾷食\n⾸首\n⾹香\n⾺馬\n⾻骨\n⾼高\n⾽髟\n⾾鬥\n⾿鬯\n⿀鬲\nâ¿é¬¼\nâ¿‚é­š\n⿃鳥\nâ¿„é¹µ\n⿅鹿\n⿆麥\n⿇麻\n⿈黃\n⿉é»\n⿊黑\n⿋黹\n⿌黽\nâ¿é¼Ž\n⿎鼓\nâ¿é¼ \nâ¿é¼»\n⿑齊\nâ¿’é½’\nâ¿“é¾\n⿔龜\nâ¿•é¾ \n  \n〶〒\n〸å\n〹å„\n〺å…\nãŒã‹ã‚™\nãŽãã‚™\nããã‚™\nã’ã‘ã‚™\nã”ã“ã‚™\nã–ã•ã‚™\nã˜ã—ã‚™\nãšã™ã‚™\nãœã›ã‚™\nãžãã‚™\nã ãŸã‚™\nã¢ã¡ã‚™\nã¥ã¤ã‚™\nã§ã¦ã‚™\nã©ã¨ã‚™\nã°ã¯ã‚™\nã±ã¯ã‚š\nã³ã²ã‚™\nã´ã²ã‚š\nã¶ãµã‚™\nã·ãµã‚š\nã¹ã¸ã‚™\nãºã¸ã‚š\nã¼ã»ã‚™\nã½ã»ã‚š\nã‚”ã†ã‚™\nã‚› ã‚™\n゜ ゚\nゞã‚ã‚™\nゟより\nガガ\nギギ\nググ\nゲゲ\nゴゴ\nザザ\nジジ\nズズ\nゼゼ\nゾゾ\nダダ\nヂãƒã‚™\nヅヅ\nデデ\nドド\nãƒãƒã‚™\nパãƒã‚š\nビビ\nピピ\nブブ\nププ\nベベ\nペペ\nボボ\nãƒãƒ›ã‚š\nヴヴ\nヷヷ\nヸヸ\nヹヹ\nヺヺ\nヾヾ\nヿコト\nㄱᄀ\nㄲá„\nㄳᆪ\nã„´á„‚\nㄵᆬ\nㄶᆭ\nㄷᄃ\nㄸᄄ\nㄹᄅ\nㄺᆰ\nㄻᆱ\nㄼᆲ\nㄽᆳ\nㄾᆴ\nㄿᆵ\nㅀᄚ\nã…ᄆ\nㅂᄇ\nㅃᄈ\nã…„á„¡\nㅅᄉ\nㅆᄊ\nㅇᄋ\nㅈᄌ\nã…‰á„\nㅊᄎ\nã…‹á„\nã…Œá„\nã…á„‘\nã…Žá„’\nã…á…¡\nã…á…¢\nã…‘á…£\nã…’á…¤\nã…“á…¥\nㅔᅦ\nã…•á…§\nã…–á…¨\nã…—á…©\nㅘᅪ\nㅙᅫ\nã…šá…¬\nㅛᅭ\nㅜᅮ\nã…á…¯\nã…žá…°\nã…Ÿá…±\nã… á…²\nã…¡á…³\nㅢᅴ\nㅣᅵ\nㅤᅠ\nㅥᄔ\nㅦᄕ\nㅧᇇ\nㅨᇈ\nㅩᇌ\nㅪᇎ\nㅫᇓ\nㅬᇗ\nㅭᇙ\nㅮᄜ\nã…¯á‡\nㅰᇟ\nã…±á„\nㅲᄞ\nㅳᄠ\nã…´á„¢\nㅵᄣ\nã…¶á„§\nã…·á„©\nㅸᄫ\nㅹᄬ\nㅺᄭ\nㅻᄮ\nㅼᄯ\nㅽᄲ\nㅾᄶ\nã…¿á…€\nㆀᅇ\nã†á…Œ\nㆂᇱ\nㆃᇲ\nㆄᅗ\nㆅᅘ\nㆆᅙ\nㆇᆄ\nㆈᆅ\nㆉᆈ\nㆊᆑ\nㆋᆒ\nㆌᆔ\nã†á†ž\nㆎᆡ\n㆒一\n㆓二\n㆔三\n㆕四\n㆖上\n㆗中\n㆘下\n㆙甲\n㆚乙\n㆛丙\n㆜ä¸\nã†å¤©\n㆞地\n㆟人\n㈀(á„€)\nãˆ(á„‚)\n㈂(ᄃ)\n㈃(á„…)\n㈄(ᄆ)\n㈅(ᄇ)\n㈆(ᄉ)\n㈇(á„‹)\n㈈(ᄌ)\n㈉(ᄎ)\n㈊(á„)\n㈋(á„)\n㈌(á„‘)\nãˆ(á„’)\n㈎(가)\nãˆ(á„‚á…¡)\nãˆ(다)\n㈑(á„…á…¡)\n㈒(마)\n㈓(바)\n㈔(사)\n㈕(á„‹á…¡)\n㈖(자)\n㈗(차)\n㈘(á„á…¡)\n㈙(á„á…¡)\n㈚(á„‘á…¡)\n㈛(á„’á…¡)\n㈜(주)\nãˆ(오전)\n㈞(á„‹á…©á„’á…®)\n㈠(一)\n㈡(二)\n㈢(三)\n㈣(å››)\n㈤(五)\n㈥(å…­)\n㈦(七)\n㈧(å…«)\n㈨(ä¹)\n㈩(å)\n㈪(月)\n㈫(ç«)\n㈬(æ°´)\n㈭(木)\n㈮(金)\n㈯(土)\n㈰(æ—¥)\n㈱(æ ª)\n㈲(有)\n㈳(社)\n㈴(å)\n㈵(特)\n㈶(財)\n㈷(ç¥)\n㈸(労)\n㈹(代)\n㈺(呼)\n㈻(å­¦)\n㈼(監)\n㈽(ä¼)\n㈾(資)\n㈿(å”)\n㉀(祭)\nã‰(休)\n㉂(自)\n㉃(至)\nã‰PTE\n㉑21\n㉒22\n㉓23\n㉔24\n㉕25\n㉖26\n㉗27\n㉘28\n㉙29\n㉚30\n㉛31\n㉜32\nã‰33\n㉞34\n㉟35\n㉠ᄀ\n㉡ᄂ\n㉢ᄃ\n㉣ᄅ\n㉤ᄆ\n㉥ᄇ\n㉦ᄉ\n㉧ᄋ\n㉨ᄌ\n㉩ᄎ\n㉪á„\n㉫á„\n㉬ᄑ\n㉭ᄒ\n㉮가\n㉯나\n㉰다\n㉱라\n㉲마\n㉳바\n㉴사\n㉵아\n㉶자\n㉷차\n㉸á„á…¡\n㉹á„á…¡\n㉺파\n㉻하\n㉼참고\n㉽주의\n㉾우\n㊀一\nãŠäºŒ\n㊂三\n㊃四\n㊄五\n㊅六\n㊆七\n㊇八\n㊈ä¹\n㊉å\n㊊月\n㊋ç«\n㊌水\nãŠæœ¨\n㊎金\nãŠåœŸ\nãŠæ—¥\n㊑株\n㊒有\n㊓社\n㊔å\n㊕特\n㊖財\n㊗ç¥\n㊘労\n㊙秘\n㊚男\n㊛女\n㊜é©\nãŠå„ª\n㊞å°\n㊟注\n㊠項\n㊡休\n㊢写\n㊣正\n㊤上\n㊥中\n㊦下\n㊧左\n㊨å³\n㊩医\n㊪宗\n㊫学\n㊬監\n㊭ä¼\n㊮資\n㊯å”\n㊰夜\n㊱36\n㊲37\n㊳38\n㊴39\n㊵40\n㊶41\n㊷42\n㊸43\n㊹44\n㊺45\n㊻46\n㊼47\n㊽48\n㊾49\n㊿50\nã‹€1月\nã‹2月\nã‹‚3月\n㋃4月\nã‹„5月\nã‹…6月\n㋆7月\n㋇8月\n㋈9月\n㋉10月\n㋊11月\nã‹‹12月\n㋌Hg\nã‹erg\n㋎eV\nã‹LTD\nã‹ã‚¢\n㋑イ\n㋒ウ\n㋓エ\n㋔オ\nã‹•ã‚«\nã‹–ã‚­\n㋗ク\n㋘ケ\n㋙コ\n㋚サ\n㋛シ\n㋜ス\nã‹ã‚»\n㋞ソ\n㋟タ\nã‹ ãƒ\n㋡ツ\n㋢テ\n㋣ト\n㋤ナ\n㋥ニ\n㋦ヌ\nã‹§ãƒ\n㋨ノ\nã‹©ãƒ\n㋪ヒ\n㋫フ\n㋬ヘ\n㋭ホ\n㋮マ\n㋯ミ\n㋰ム\n㋱メ\n㋲モ\n㋳ヤ\n㋴ユ\n㋵ヨ\n㋶ラ\n㋷リ\n㋸ル\n㋹レ\n㋺ロ\n㋻ワ\n㋼ヰ\n㋽ヱ\n㋾ヲ\n㌀アãƒã‚šãƒ¼ãƒˆ\nãŒã‚¢ãƒ«ãƒ•ã‚¡\n㌂アンペア\n㌃アール\n㌄イニング\n㌅インãƒ\n㌆ウォン\n㌇エスクード\n㌈エーカー\n㌉オンス\n㌊オーム\n㌋カイリ\n㌌カラット\nãŒã‚«ãƒ­ãƒªãƒ¼\n㌎ガロン\nãŒã‚«ã‚™ãƒ³ãƒž\nãŒã‚­ã‚™ã‚«ã‚™\n㌑ギニー\n㌒キュリー\n㌓ギルダー\n㌔キロ\n㌕キログラム\n㌖キロメートル\n㌗キロワット\n㌘グラム\n㌙グラムトン\n㌚クルゼイロ\n㌛クローãƒ\n㌜ケース\nãŒã‚³ãƒ«ãƒŠ\n㌞コーポ\n㌟サイクル\n㌠サンãƒãƒ¼ãƒ \n㌡シリング\n㌢センãƒ\n㌣セント\n㌤ダース\n㌥デシ\n㌦ドル\n㌧トン\n㌨ナノ\n㌩ノット\n㌪ãƒã‚¤ãƒ„\n㌫ãƒã‚šãƒ¼ã‚»ãƒ³ãƒˆ\n㌬ãƒã‚šãƒ¼ãƒ„\n㌭ãƒã‚™ãƒ¼ãƒ¬ãƒ«\n㌮ピアストル\n㌯ピクル\n㌰ピコ\n㌱ビル\n㌲ファラッド\n㌳フィート\n㌴ブッシェル\n㌵フラン\n㌶ヘクタール\n㌷ペソ\n㌸ペニヒ\n㌹ヘルツ\n㌺ペンス\n㌻ページ\n㌼ベータ\n㌽ポイント\n㌾ボルト\n㌿ホン\nã€ãƒ›ã‚šãƒ³ãƒˆã‚™\nãホール\nã‚ホーン\nãƒãƒžã‚¤ã‚¯ãƒ­\nã„マイル\nã…マッãƒ\nã†ãƒžãƒ«ã‚¯\nã‡ãƒžãƒ³ã‚·ãƒ§ãƒ³\nãˆãƒŸã‚¯ãƒ­ãƒ³\nã‰ãƒŸãƒª\nãŠãƒŸãƒªãƒã‚™ãƒ¼ãƒ«\nã‹ãƒ¡ã‚«ã‚™\nãŒãƒ¡ã‚«ã‚™ãƒˆãƒ³\nãメートル\nãŽãƒ¤ãƒ¼ãƒˆã‚™\nãヤール\nãユアン\nã‘リットル\nã’リラ\nã“ルピー\nã”ルーブル\nã•レム\nã–レントゲン\nã—ワット\nã˜0点\nã™1点\nãš2点\nã›3点\nãœ4点\nã5点\nãž6点\nãŸ7点\nã 8点\nã¡9点\nã¢10点\nã£11点\nã¤12点\nã¥13点\nã¦14点\nã§15点\nã¨16点\nã©17点\nãª18点\nã«19点\nã¬20点\nã­21点\nã®22点\nã¯23点\nã°24点\nã±hPa\nã²da\nã³AU\nã´bar\nãµoV\nã¶pc\nã·dm\nã¸dm2\nã¹dm3\nãºIU\nã»å¹³æˆ\nã¼æ˜­å’Œ\nã½å¤§æ­£\nã¾æ˜Žæ²»\nã¿æ ªå¼ä¼šç¤¾\n㎀pA\nãŽnA\n㎂μA\n㎃mA\n㎄kA\n㎅KB\n㎆MB\n㎇GB\n㎈cal\n㎉kcal\n㎊pF\n㎋nF\n㎌μF\nãŽÎ¼g\n㎎mg\nãŽkg\nãŽHz\n㎑kHz\n㎒MHz\n㎓GHz\n㎔THz\n㎕μl\n㎖ml\n㎗dl\n㎘kl\n㎙fm\n㎚nm\n㎛μm\n㎜mm\nãŽcm\n㎞km\n㎟mm2\n㎠cm2\n㎡m2\n㎢km2\n㎣mm3\n㎤cm3\n㎥m3\n㎦km3\n㎧m∕s\n㎨m∕s2\n㎩Pa\n㎪kPa\n㎫MPa\n㎬GPa\n㎭rad\n㎮rad∕s\n㎯rad∕s2\n㎰ps\n㎱ns\n㎲μs\n㎳ms\n㎴pV\n㎵nV\n㎶μV\n㎷mV\n㎸kV\n㎹MV\n㎺pW\n㎻nW\n㎼μW\n㎽mW\n㎾kW\n㎿MW\nã€kΩ\nãMΩ\nã‚a.m.\nãƒBq\nã„cc\nã…cd\nã†C∕kg\nã‡Co.\nãˆdB\nã‰Gy\nãŠha\nã‹HP\nãŒin\nãKK\nãŽKM\nãkt\nãlm\nã‘ln\nã’log\nã“lx\nã”mb\nã•mil\nã–mol\nã—PH\nã˜p.m.\nã™PPM\nãšPR\nã›sr\nãœSv\nãWb\nãžV∕m\nãŸA∕m\nã 1æ—¥\nã¡2æ—¥\nã¢3æ—¥\nã£4æ—¥\nã¤5æ—¥\nã¥6æ—¥\nã¦7æ—¥\nã§8æ—¥\nã¨9æ—¥\nã©10æ—¥\nãª11æ—¥\nã«12æ—¥\nã¬13æ—¥\nã­14æ—¥\nã®15æ—¥\nã¯16æ—¥\nã°17æ—¥\nã±18æ—¥\nã²19æ—¥\nã³20æ—¥\nã´21æ—¥\nãµ22æ—¥\nã¶23æ—¥\nã·24æ—¥\nã¸25æ—¥\nã¹26æ—¥\nãº27æ—¥\nã»28æ—¥\nã¼29æ—¥\nã½30æ—¥\nã¾31æ—¥\nã¿gal\n豈豈\nï¤æ›´\n車車\n賈賈\n滑滑\n串串\n句å¥\n龜龜\n龜龜\n契契\n金金\n喇喇\n奈奈\nï¤æ‡¶\n癩癩\nï¤ç¾…\nï¤è˜¿\n螺螺\n裸裸\n邏é‚\n樂樂\n洛洛\n烙烙\n珞çž\n落è½\n酪酪\n駱駱\n亂亂\n卵åµ\nï¤æ¬„\n爛爛\n蘭蘭\n鸞鸞\n嵐åµ\n濫濫\n藍è—\n襤襤\n拉拉\n臘臘\n蠟蠟\n廊廊\n朗朗\n浪浪\n狼狼\n郎郎\n來來\n冷冷\n勞勞\n擄擄\n櫓櫓\n爐çˆ\n盧盧\n老è€\n蘆蘆\n虜虜\n路路\n露露\n魯魯\n鷺鷺\n碌碌\n祿祿\n綠綠\n菉è‰\n錄錄\n鹿鹿\nï¥è«–\n壟壟\n弄弄\n籠籠\n聾è¾\n牢牢\n磊磊\n賂賂\n雷雷\n壘壘\n屢屢\n樓樓\nï¥æ·š\n漏æ¼\nï¥ç´¯\nï¥ç¸·\n陋陋\n勒勒\n肋肋\n凜凜\n凌凌\n稜稜\n綾綾\n菱è±\n陵陵\n讀讀\n拏æ‹\n樂樂\nï¥è«¾\n丹丹\n寧寧\n怒怒\n率率\n異異\n北北\n磻磻\n便便\n復復\n不ä¸\n泌泌\n數數\n索索\n參åƒ\n塞塞\n省çœ\n葉葉\n說說\n殺殺\n辰辰\n沈沈\n拾拾\n若若\n掠掠\n略略\n亮亮\n兩兩\n凉凉\n梁æ¢\n糧糧\n良良\n諒諒\n量é‡\n勵勵\n呂呂\nï¦å¥³\n廬廬\n旅旅\n濾濾\n礪礪\n閭閭\n驪驪\n麗麗\n黎黎\n力力\n曆曆\n歷歷\nï¦è½¢\n年年\nï¦æ†\nï¦æˆ€\n撚撚\n漣漣\n煉煉\n璉璉\n秊秊\n練練\n聯è¯\n輦輦\n蓮蓮\n連連\n鍊éŠ\n列列\nï¦åŠ£\n咽咽\n烈烈\n裂裂\n說說\n廉廉\n念念\n捻æ»\n殮殮\n簾簾\n獵çµ\n令令\n囹囹\n寧寧\n嶺嶺\n怜怜\n玲玲\n瑩瑩\n羚羚\n聆è†\n鈴鈴\n零零\n靈éˆ\n領領\n例例\n禮禮\n醴醴\n隸隸\n惡惡\n了了\n僚僚\n寮寮\n尿尿\n料料\n樂樂\n燎燎\nï§ç™‚\n蓼蓼\n遼é¼\nï§„é¾\n暈暈\n阮阮\n劉劉\n杻æ»\n柳柳\nï§Šæµ\n溜溜\nï§Œç‰\nï§ç•™\nï§Žç¡«\nï§ç´\nï§é¡ž\nï§‘å…­\n戮戮\n陸陸\n倫倫\nï§•å´™\nï§–æ·ª\n輪輪\n律律\n慄慄\nï§šæ —\n率率\n隆隆\nï§åˆ©\nï§žå\nï§Ÿå±¥\n易易\nï§¡æŽ\n梨梨\n泥泥\n理ç†\n痢痢\n罹罹\nï§§è£\n裡裡\n里里\n離離\n匿匿\n溺溺\nï§­å\nï§®ç‡\n璘璘\nï§°è—º\n隣隣\n鱗鱗\n麟麟\nï§´æž—\n淋淋\n臨臨\nï§·ç«‹\n笠笠\n粒粒\n狀狀\n炙炙\n識識\n什什\n茶茶\n刺刺\n切切\nï¨åº¦\n拓拓\n糖糖\n宅宅\n洞洞\n暴暴\n輻輻\n行行\n降é™\n見見\n廓廓\n兀兀\nï¨å—€\nï¨å¡š\n晴晴\n凞凞\n猪猪\n益益\n礼礼\n神神\n祥祥\n福ç¦\n靖é–\nï¨ç²¾\n羽羽\n蘒蘒\n諸諸\n逸逸\n都都\n飯飯\n飼飼\n館館\n鶴鶴\n侮侮\n僧僧\n免å…\n勉勉\n勤勤\n卑å‘\n喝å–\n嘆嘆\n器器\n塀塀\n墨墨\n層層\n屮屮\n悔悔\n慨慨\n憎憎\n懲懲\nï©æ•\nï©‚æ—¢\n暑暑\n梅梅\nï©…æµ·\n渚渚\n漢漢\n煮煮\n爫爫\n琢ç¢\n碑碑\n社社\nï©ç¥‰\n祈祈\nï©ç¥\nï©ç¥–\nï©‘ç¥\nï©’ç¦\n禎禎\n穀穀\nï©•çª\n節節\nï©—ç·´\n縉縉\nï©™ç¹\n署署\n者者\n臭臭\nï©è‰¹\n艹艹\n著著\nï© è¤\n視視\nï©¢è¬\n謹謹\n賓賓\n贈贈\n辶辶\n逸逸\n難難\n響響\n頻頻\n並並\n况况\n全全\n侀侀\nï©´å……\n冀冀\n勇勇\n勺勺\n喝å–\n啕啕\n喙喙\n嗢嗢\n塚塚\n墳墳\n奄奄\n奔奔\n婢婢\nïªå¬¨\n廒廒\n廙廙\n彩彩\n徭徭\n惘惘\n慎慎\n愈愈\n憎憎\n慠慠\n懲懲\n戴戴\nïªæ„\n搜æœ\nïªæ‘’\nïªæ•–\n晴晴\n朗朗\n望望\n杖æ–\n歹歹\n殺殺\n流æµ\n滛滛\n滋滋\n漢漢\n瀞瀞\n煮煮\nïªçž§\n爵爵\n犯犯\n猪猪\n瑱瑱\n甆甆\n画画\n瘝ç˜\n瘟瘟\n益益\n盛盛\n直直\n睊çŠ\n着ç€\n磌磌\n窱窱\n節節\n类类\n絛絛\n練練\n缾缾\n者者\n荒è’\n華è¯\n蝹è¹\n襁è¥\n覆覆\n視視\n調調\n諸諸\n請請\n謁è¬\n諾諾\n諭諭\n謹謹\n變變\nï«è´ˆ\n輸輸\n遲é²\n醙醙\n鉶鉶\n陼陼\n難難\n靖é–\n韛韛\n響響\nï«‹é ‹\n頻頻\nï«é¬’\n龜龜\nï«ð¢¡Š\nï«ð¢¡„\nï«‘ð£•\nï«’ã®\n䀘䀘\n䀹䀹\n𥉉𥉉\nï«–ð¥³\n𧻓𧻓\n齃齃\n龎龎\nï¼!\n"\"\n##\n$$\nï¼…%\n&&\n''\n((\n))\n**\n++\n,,\nï¼-\n..\nï¼/\nï¼0\n11\nï¼’2\n33\nï¼”4\n55\nï¼–6\nï¼—7\n88\nï¼™9\n::\nï¼›;\n<<\nï¼=\n>>\n??\nï¼ @\nAA\nï¼¢B\nï¼£C\nDD\nï¼¥E\nFF\nï¼§G\nHH\nII\nJJ\nKK\nLL\nï¼­M\nï¼®N\nOO\nï¼°P\nï¼±Q\nï¼²R\nï¼³S\nï¼´T\nï¼µU\nï¼¶V\nï¼·W\nXX\nï¼¹Y\nZZ\nï¼»[\nï¼¼\\nï¼½]\nï¼¾^\n__\nï½€`\nï½a\nbb\ncc\ndd\nï½…e\nff\ngg\nhh\nii\njj\nkk\nll\nï½m\nnn\nï½o\nï½p\nqq\nï½’r\nss\nï½”t\nuu\nï½–v\nï½—w\nxx\nï½™y\nzz\nï½›{\n||\nï½}\n~~\n⦅⦅\n⦆⦆\n。。\n「「\nï½£ã€\n、ã€\n・・\nヲヲ\nï½§ã‚¡\nィィ\nゥゥ\nェェ\nォォ\nャャ\nュュ\nョョ\nッッ\nーー\nアア\nイイ\nウウ\nエエ\nオオ\nï½¶ã‚«\nï½·ã‚­\nクク\nケケ\nココ\nササ\nシシ\nスス\nセセ\nソソ\nタタ\nï¾ãƒ\nツツ\nテテ\nトト\nナナ\nニニ\nヌヌ\nネãƒ\nノノ\nハãƒ\nヒヒ\nフフ\nï¾ãƒ˜\nホホ\nï¾ãƒž\nï¾ãƒŸ\nムム\nメメ\nモモ\nヤヤ\nユユ\nヨヨ\nララ\nリリ\nルル\nレレ\nロロ\nワワ\nï¾ãƒ³\n゙゙\n゚゚\nï¾ á… \nᄀᄀ\nï¾¢á„\nᆪᆪ\nᄂᄂ\nᆬᆬ\nᆭᆭ\nᄃᄃ\nᄄᄄ\nᄅᄅ\nᆰᆰ\nᆱᆱ\nᆲᆲ\nᆳᆳ\nᆴᆴ\nᆵᆵ\nᄚᄚ\nᄆᄆ\nᄇᄇ\nᄈᄈ\nï¾´á„¡\nᄉᄉ\nᄊᄊ\nï¾·á„‹\nᄌᄌ\nï¾¹á„\nᄎᄎ\nï¾»á„\nï¾¼á„\nᄑᄑ\nᄒᄒ\nï¿‚á…¡\nᅢᅢ\nï¿„á…£\nï¿…á…¤\nᅥᅥ\nᅦᅦ\nᅧᅧ\nï¿‹á…¨\nᅩᅩ\nï¿á…ª\nᅫᅫ\nï¿á…¬\nï¿’á…­\nï¿“á…®\nᅯᅯ\nï¿•á…°\nï¿–á…±\nï¿—á…²\nᅳᅳ\nᅴᅴ\nᅵᅵ\n¢¢\n££\n¬¬\nï¿£ Ì„\n¦¦\n¥¥\n₩₩\n││\nï¿©â†\n↑↑\n→→\n↓↓\nï¿­â– \n○○\n"; + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Bip39/KdTable.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Bip39/KdTable.cs.meta new file mode 100644 index 0000000..6ae966b --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Bip39/KdTable.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: eb5e191b7da7a574cb692cb31014e195 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Bip39/Language.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Bip39/Language.cs new file mode 100644 index 0000000..0a23fbe --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Bip39/Language.cs @@ -0,0 +1,47 @@ +// unset + +namespace Solana.Unity.Wallet.Bip39 +{ + /// + /// Specifies the available languages for mnemonic generation. + /// + public enum Language + { + /// + /// English. + /// + English, + /// + /// Japanese. + /// + Japanese, + /// + /// Spanish. + /// + Spanish, + /// + /// Simplified Chinese. + /// + ChineseSimplified, + /// + /// Traditional Chinese. + /// + ChineseTraditional, + /// + /// French. + /// + French, + /// + /// Brazilian portuguese. + /// + PortugueseBrazil, + /// + /// Czech. + /// + Czech, + /// + /// Unknown. + /// + Unknown + }; +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Bip39/Language.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Bip39/Language.cs.meta new file mode 100644 index 0000000..10a7ba0 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Bip39/Language.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 880bb5e82d1b35c4cab4aec86d1786e9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Bip39/Mnemonic.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Bip39/Mnemonic.cs new file mode 100644 index 0000000..55d7ae4 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Bip39/Mnemonic.cs @@ -0,0 +1,287 @@ +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Parameters; +using Solana.Unity.Wallet.Utilities; +using System; +using System.Collections; +using System.Diagnostics; +using System.Linq; +using System.Text; + +namespace Solana.Unity.Wallet.Bip39 +{ + /// + /// A .NET implementation of the Bitcoin Improvement Proposal - 39 (BIP39) + /// BIP39 specification used as reference located here: https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki + /// This implementation was taken from NBitcoin: https://github.com/MetacoSA/NBitcoin/ + /// + [DebuggerDisplay("Mnemonic = {" + nameof(_mnemonic) + "}")] + public class Mnemonic + { + /// + /// Initialize a mnemonic from the given string and wordList type. + /// + /// The mnemonic string. + /// The word list type. + /// Thrown when the mnemonic string is null. + /// Thrown when the word count of the mnemonic is invalid. + public Mnemonic(string mnemonic, WordList wordList = null) + { + if (mnemonic == null) + throw new ArgumentNullException(nameof(mnemonic)); + _mnemonic = mnemonic.Trim(); + + wordList ??= WordList.AutoDetect(mnemonic) ?? WordList.English; + + string[] words = mnemonic.Split((char[])null, StringSplitOptions.RemoveEmptyEntries); + _mnemonic = string.Join(wordList.Space.ToString(), words); + + //if the sentence is not at least 12 characters or cleanly divisible by 3, it is bad! + if (!CorrectWordCount(words.Length)) + { + throw new FormatException("Word count should be 12,15,18,21 or 24"); + } + Words = words; + WordList = wordList; + Indices = wordList.ToIndices(words); + } + + /// + /// Generate a mnemonic + /// + /// The word list of the mnemonic. + /// The entropy. + private Mnemonic(WordList wordList, byte[] entropy = null) + { + wordList ??= WordList.English; + WordList = wordList; + entropy ??= RandomUtils.GetBytes(32); + + int i = Array.IndexOf(EntArray, entropy.Length * 8); + if (i == -1) + throw new ArgumentException("The length for entropy should be " + string.Join(",", EntArray) + " bits", nameof(entropy)); + + int cs = CsArray[i]; + byte[] checksum = Utils.Sha256(entropy); + BitWriter entropyResult = new(); + + entropyResult.Write(entropy); + entropyResult.Write(checksum, cs); + Indices = entropyResult.ToIntegers(); + Words = WordList.GetWords(Indices); + _mnemonic = WordList.GetSentence(Indices); + } + + /// + /// Initialize a mnemonic from the given word list and word count.. + /// + /// The word list. + /// The word count. + public Mnemonic(WordList wordList, WordCount wordCount) : this(wordList, GenerateEntropy(wordCount)) { } + + /// + /// Generate entropy for the given word count. + /// + /// + /// + /// Thrown when the word count is invalid. + private static byte[] GenerateEntropy(WordCount wordCount) + { + int ms = (int)wordCount; + if (!CorrectWordCount(ms)) + throw new ArgumentException("Word count should be 12,15,18,21 or 24", nameof(wordCount)); + int i = Array.IndexOf(MsArray, (int)wordCount); + return RandomUtils.GetBytes(EntArray[i] / 8); + } + + /// + /// The word count array. + /// + private static readonly int[] MsArray = { 12, 15, 18, 21, 24 }; + + /// + /// The bit count array. + /// + private static readonly int[] CsArray = { 4, 5, 6, 7, 8 }; + + /// + /// The entropy value array. + /// + private static readonly int[] EntArray = { 128, 160, 192, 224, 256 }; + + /// + /// Whether the checksum of the mnemonic is valid. + /// + private bool? _isValidChecksum; + + /// + /// Whether the checksum of the mnemonic is valid. + /// + public bool IsValidChecksum + { + get + { + if (_isValidChecksum != null) + { + return _isValidChecksum.Value; + } + + int i = Array.IndexOf(MsArray, Indices.Length); + int cs = CsArray[i]; + int ent = EntArray[i]; + + BitWriter writer = new(); + BitArray bits = WordList.ToBits(Indices); + writer.Write(bits, ent); + byte[] entropy = writer.ToBytes(); + byte[] checksum = Utils.Sha256(entropy); + + writer.Write(checksum, cs); + int[] expectedIndices = writer.ToIntegers(); + _isValidChecksum = expectedIndices.SequenceEqual(Indices); + return _isValidChecksum.Value; + } + } + + /// + /// Whether the word count is correct. + /// + /// The number of words. + /// True if it is, otherwise false. + private static bool CorrectWordCount(int ms) + { + return MsArray.Any(_ => _ == ms); + } + + /// + /// The word list. + /// + public WordList WordList { get; } + + /// + /// The indices. + /// + public int[] Indices { get; } + + /// + /// The words of the mnemonic. + /// + public string[] Words { get; } + + /// + /// Utf8 encoding. + /// + private static readonly Encoding _noBomutf8 = new UTF8Encoding(false); + + /// + /// Derives the mnemonic seed. + /// + /// The passphrase. + /// The seed. + public byte[] DeriveSeed(string passphrase = null) + { + passphrase ??= ""; + byte[] salt = Concat(_noBomutf8.GetBytes("mnemonic"), Normalize(passphrase)); + byte[] bytes = Normalize(_mnemonic); + + return GenerateSeed(bytes, salt); + } + + /// + /// Generate the seed using pbkdf with sha 512. + /// + /// The password to derive the key from. + /// The salt to use for key derivation. + /// The derived key. + private static byte[] GenerateSeed(byte[] password, byte[] salt) + { + Pkcs5S2ParametersGenerator gen = new(new Sha512Digest()); + gen.Init(password, salt, 2048); + return ((KeyParameter)gen.GenerateDerivedParameters(512)).GetKey(); + } + + /// + /// Get the normalized the string as a byte array. + /// + /// The string to normalize. + /// The byte array. + private static byte[] Normalize(string str) + { + return _noBomutf8.GetBytes(NormalizeString(str)); + } + + /// + /// Normalize the string. + /// + /// The string to normalize. + /// The normalized string. + internal static string NormalizeString(string word) + { + return !SupportOsNormalization() ? KdTable.NormalizeKd(word) : word.Normalize(NormalizationForm.FormKD); + } + + /// + /// Whether the OS normalization is supported. + /// + private static bool? _supportOsNormalization; + + /// + /// Checks for OS normalization support. + /// + /// True if available, otherwise false. + private static bool SupportOsNormalization() + { + if (_supportOsNormalization != null) + { + return _supportOsNormalization.Value; + } + + const string notNormalized = "ã‚ãŠãžã‚‰"; + const string normalized = "ã‚ãŠã゙ら"; + + if (notNormalized.Equals(normalized, StringComparison.Ordinal)) + { + _supportOsNormalization = false; + } + else + { + try + { + _supportOsNormalization = notNormalized.Normalize(NormalizationForm.FormKD).Equals(normalized, StringComparison.Ordinal); + } + catch { _supportOsNormalization = false; } + } + return _supportOsNormalization.Value; + } + + /// + /// Concatenate an array of bytes. + /// + /// The first array. + /// The second array. + /// The concatenated array of bytes. + private static byte[] Concat(byte[] source1, byte[] source2) + { + //Most efficient way to merge two arrays this according to http://stackoverflow.com/questions/415291/best-way-to-combine-two-or-more-byte-arrays-in-c-sharp + byte[] buffer = new byte[source1.Length + source2.Length]; + Buffer.BlockCopy(source1, 0, buffer, 0, source1.Length); + Buffer.BlockCopy(source2, 0, buffer, source1.Length, source2.Length); + + return buffer; + } + + /// + /// The mnemonic string. + /// + private readonly string _mnemonic; + + /// + /// Gets the mnemonic string. + /// + /// The string. + public override string ToString() + { + return _mnemonic; + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Bip39/Mnemonic.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Bip39/Mnemonic.cs.meta new file mode 100644 index 0000000..a07bbcb --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Bip39/Mnemonic.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c39fe9ff404f8e2429655787d5ef36c0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Bip39/WordCount.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Bip39/WordCount.cs new file mode 100644 index 0000000..ada5eff --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Bip39/WordCount.cs @@ -0,0 +1,33 @@ +namespace Solana.Unity.Wallet.Bip39 +{ + /// + /// Specifies the available lengths for the mnemonic. + /// + public enum WordCount + { + /// + /// Twelve words. + /// + Twelve = 12, + + /// + /// Fifteen words. + /// + Fifteen = 15, + + /// + /// Eighteen words. + /// + Eighteen = 18, + + /// + /// Twenty one words. + /// + TwentyOne = 21, + + /// + /// Twenty four words. + /// + TwentyFour = 24 + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Bip39/WordCount.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Bip39/WordCount.cs.meta new file mode 100644 index 0000000..4bd8ff9 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Bip39/WordCount.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 58635d0856e700548856bfc9a43101f0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Bip39/WordList.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Bip39/WordList.cs new file mode 100644 index 0000000..e34ef0d --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Bip39/WordList.cs @@ -0,0 +1,432 @@ +using Solana.Unity.Wallet.Utilities; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Solana.Unity.Wallet.Bip39 +{ + /// + /// Implements the word list functionality. + /// + public class WordList + { + /// + /// Initialize the static word list instance. + /// + static WordList() + { + WordlistSource = new HardcodedWordlistSource(); + } + + /// + /// The japanese word list. + /// + private static WordList _japanese; + + /// + /// The japanese word list. + /// + public static WordList Japanese => _japanese ??= LoadWordList(Language.Japanese).Result; + + /// + /// The simplified chinese word list. + /// + private static WordList _chineseSimplified; + + /// + /// The simplified chinese word list. + /// + public static WordList ChineseSimplified => _chineseSimplified ??= LoadWordList(Language.ChineseSimplified).Result; + + /// + /// The traditional chinese word list. + /// + private static WordList _chineseTraditional; + + /// + /// The traditional chinese word list. + /// + public static WordList ChineseTraditional => _chineseTraditional ??= LoadWordList(Language.ChineseTraditional).Result; + + /// + /// The spanish word list. + /// + private static WordList _spanish; + + /// + /// The spanish word list. + /// + public static WordList Spanish => _spanish ??= LoadWordList(Language.Spanish).Result; + + /// + /// The english word list. + /// + private static WordList _english; + + /// + /// The english word list. + /// + public static WordList English => _english ??= LoadWordList(Language.English).Result; + + /// + /// The french word list. + /// + private static WordList _french; + + /// + /// The french word list. + /// + public static WordList French => _french ??= LoadWordList(Language.French).Result; + + /// + /// The brazilian portuguese word list. + /// + private static WordList _portugueseBrazil; + + /// + /// The brazilian portuguese word list. + /// + public static WordList PortugueseBrazil => _portugueseBrazil ??= LoadWordList(Language.PortugueseBrazil).Result; + + /// + /// The czech word list. + /// + private static WordList _czech; + + /// + /// The czech word list. + /// + public static WordList Czech => _czech ??= LoadWordList(Language.Czech).Result; + + /// + /// Load the word list for the given language. This operation is asynchronous. + /// + /// The language. + /// A task which returns the word list. + public static Task LoadWordList(Language language) + { + string name = GetLanguageFileName(language); + return LoadWordList(name); + } + + /// + /// Gets the name of the file for the given language. + /// + /// The language. + /// The file name. + /// Thrown when the language is not supported. + private static string GetLanguageFileName(Language language) + { + string name = language switch + { + Language.ChineseTraditional => "chinese_traditional", + Language.ChineseSimplified => "chinese_simplified", + Language.English => "english", + Language.Japanese => "japanese", + Language.Spanish => "spanish", + Language.French => "french", + Language.PortugueseBrazil => "portuguese_brazil", + Language.Czech => "czech", + Language.Unknown => throw new NotSupportedException(language.ToString()), + _ => throw new NotSupportedException(language.ToString()) + }; + return name; + } + + /// + /// The loaded word lists. + /// + private static readonly Dictionary LoadedLists = new(); + + /// + /// Loads a word list by name. + /// + /// The name of the word list. + /// A task which returns the word list. + /// Thrown when the word list name is null. + /// Thrown when the word list source is not initialized. + private static async Task LoadWordList(string name) + { + if (name == null) + throw new ArgumentNullException(nameof(name)); + WordList result; + lock (LoadedLists) + { + LoadedLists.TryGetValue(name, out result); + } + if (result != null) + return await Task.FromResult(result).ConfigureAwait(false); + + if (WordlistSource == null) + throw new InvalidOperationException("WordList.WordlistSource is not initialized, could not fetch word list."); + result = await WordlistSource.LoadAsync(name).ConfigureAwait(false); + + if (result != null) + lock (LoadedLists) + { + LoadedLists.AddOrReplace(name, result); + } + + return result; + } + + /// + /// The word list source. + /// + private static IWordlistSource WordlistSource { get; } + + /// + /// The words of the word list. + /// + private readonly string[] _words; + + /// + /// Constructor used by inheritance only. + /// + /// The words to be used in the wordlist + /// The words to be used in the wordlist + /// The words to be used in the wordlist + public WordList(IEnumerable words, char space, string name) + { + _words = words + .Select(Mnemonic.NormalizeString) + .ToArray(); + _name = name; + Space = space; + } + + /// + /// The name of the word list. + /// + private readonly string _name; + + /// + /// The space character of the word list. + /// + public char Space { get; } + + /// + /// Method to determine if word exists in word list, great for auto language detection + /// + /// The word to check for existence + /// The index of the word. + /// True if it exists, otherwise false. + public bool WordExists(string word, out int index) + { + word = Mnemonic.NormalizeString(word); + if (_words.Contains(word)) + { + index = Array.IndexOf(_words, word); + return true; + } + + //index -1 means word is not in wordlist + index = -1; + return false; + } + + /// + /// Returns a string containing the word at the specified index of the wordlist + /// + /// Index of word to return + /// Word + private string GetWordAtIndex(int index) + { + return _words[index]; + } + + /// + /// The number of all the words in the wordlist + /// + public int WordCount => _words.Length; + + /// + /// Auto detects the language of the word list. + /// + /// The sentence to detect language from. + /// The word list. + public static WordList AutoDetect(string sentence) + { + return LoadWordList(AutoDetectLanguage(sentence)).Result; + } + + /// + /// Auto detects the language of the word list given as an enumerable of strings. + /// + /// The sentence to detect language from. + /// The language. + public static Language AutoDetectLanguage(IEnumerable words) + { + List languageCount = new(new[] { 0, 0, 0, 0, 0, 0, 0, 0 }); + + foreach (string s in words) + { + if (English.WordExists(s, out int _)) + { + //english is at 0 + languageCount[0]++; + } + + if (Japanese.WordExists(s, out int _)) + { + //japanese is at 1 + languageCount[1]++; + } + + if (Spanish.WordExists(s, out int _)) + { + //spanish is at 2 + languageCount[2]++; + } + + if (ChineseSimplified.WordExists(s, out int _)) + { + //chinese simplified is at 3 + languageCount[3]++; + } + + if (ChineseTraditional.WordExists(s, out int _) && !ChineseSimplified.WordExists(s, out int _)) + { + //chinese traditional is at 4 + languageCount[4]++; + } + if (French.WordExists(s, out int _)) + { + languageCount[5]++; + } + + if (PortugueseBrazil.WordExists(s, out int _)) + { + //portuguese_brazil is at 6 + languageCount[6]++; + } + + if (Czech.WordExists(s, out int _)) + { + //czech is at 7 + languageCount[7]++; + } + } + + //no hits found for any language unknown + if (languageCount.Max() == 0) + { + return Language.Unknown; + } + + return languageCount.IndexOf(languageCount.Max()) switch + { + 0 => Language.English, + 1 => Language.Japanese, + 2 => Language.Spanish, + 3 when languageCount[4] > 0 => Language.ChineseTraditional, + 3 => Language.ChineseSimplified, + 4 => Language.ChineseTraditional, + 5 => Language.French, + 6 => Language.PortugueseBrazil, + 7 => Language.Czech, + _ => Language.Unknown + }; + } + + /// + /// Auto detects the language of the word list. + /// + /// The sentence to detect language from. + /// The language. + private static Language AutoDetectLanguage(string sentence) + { + string[] words = sentence.Split(' ', ' '); //normal space and JP space + + return AutoDetectLanguage(words); + } + + /// + /// Gets the name of the word list. + /// + /// A string. + public override string ToString() + { + return _name; + } + + /// + /// Gets the words of the word list. + /// + /// The words. + public IEnumerable GetWords() + { + return _words; + } + + /// + /// Gets the words for the given indices. + /// + /// The indices. + /// An array of strings. + public string[] GetWords(IEnumerable indices) + { + return + indices + .Select(GetWordAtIndex) + .ToArray(); + } + + /// + /// Gets the sentence for the given indices. + /// + /// The indices. + /// A string. + public string GetSentence(IEnumerable indices) + { + return string.Join(Space.ToString(), GetWords(indices)); + + } + + /// + /// Converts the array of strings to indices. + /// + /// The words. + /// The indices of the words. + /// Thrown when a word is not in the word list. + public int[] ToIndices(string[] words) + { + int[] indices = new int[words.Length]; + for (int i = 0; i < words.Length; i++) + { + if (!WordExists(words[i], out int idx)) + { + throw new FormatException("Word " + words[i] + " is not in the wordlist for this language, cannot continue to rebuild entropy from wordlist"); + } + indices[i] = idx; + } + return indices; + } + + /// + /// Converts the given array of integers to a bit array. + /// + /// The array of integers to convert. + /// The bit array. + /// Thrown when values are invalid. + public static BitArray ToBits(int[] values) + { + if (values.Any(v => v >= 2048)) + throw new ArgumentException("values should be between 0 and 2048", nameof(values)); + BitArray result = new(values.Length * 11); + int i = 0; + foreach (int val in values) + { + for (int p = 0; p < 11; p++) + { + bool v = (val & (1 << (10 - p))) != 0; + result.Set(i, v); + i++; + } + } + return result; + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Bip39/WordList.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Bip39/WordList.cs.meta new file mode 100644 index 0000000..d503c9e --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Bip39/WordList.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3b9196c63035c70498da8b6899c74fcf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Ed25519Bip32.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Ed25519Bip32.cs new file mode 100644 index 0000000..e2bc89c --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Ed25519Bip32.cs @@ -0,0 +1,146 @@ +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Macs; +using Org.BouncyCastle.Crypto.Parameters; +using Solana.Unity.Wallet.Utilities; +using System; +using System.Buffers.Binary; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; + +namespace Solana.Unity.Wallet +{ + /// + /// An implementation of Ed25519 based BIP32 key generation. + /// + public class Ed25519Bip32 + { + /// + /// The seed for the Ed25519 BIP32 HMAC-SHA512 master key calculation. + /// + private const string Curve = "ed25519 seed"; + + /// + /// + /// + private const uint HardenedOffset = 0x80000000; + + /// + /// The computed master key. + /// + private readonly byte[] _masterKey; + + /// + /// The computed chain code. + /// + private readonly byte[] _chainCode; + + /// + /// Initialize the ed25519 based bip32 key generator with the passed seed. + /// + /// The seed. + public Ed25519Bip32(byte[] seed) + { + (_masterKey, _chainCode) = GetMasterKeyFromSeed(seed); + } + + /// + /// Gets the master key used for key generation from the passed seed. + /// + /// The seed used to calculate the master key. + /// A tuple consisting of the key and corresponding chain code. + private static (byte[] Key, byte[] ChainCode) GetMasterKeyFromSeed(byte[] seed) + => HmacSha512(Encoding.UTF8.GetBytes(Curve), seed); + + /// + /// Computes the child key. + /// + /// The key used to derive from. + /// The chain code for derivation. + /// The index of the key to the derive. + /// A tuple consisting of the key and corresponding chain code. + private static (byte[] Key, byte[] ChainCode) GetChildKeyDerivation(byte[] key, byte[] chainCode, uint index) + { + MemoryStream buffer = new(); + + buffer.Write(new byte[] { 0 }, 0, 1); + buffer.Write(key, 0, key.Length); + byte[] indexBytes = new byte[4]; + BinaryPrimitives.WriteUInt32BigEndian(indexBytes, index); + buffer.Write(indexBytes, 0, indexBytes.Length); + + return HmacSha512(chainCode, buffer.ToArray()); + } + + /// + /// Computes the HMAC SHA 512 of the byte array passed into data. + /// + /// The byte array to be used as the HMAC SHA512 key. + /// The data to calculate the HMAC SHA512 on. + /// A tuple consisting of the key and corresponding chain code. + private static (byte[] Key, byte[] ChainCode) HmacSha512(byte[] keyBuffer, byte[] data) + { + byte[] i = new byte[64]; + Sha512Digest digest = new(); + HMac hmac = new(digest); + + hmac.Init(new KeyParameter(keyBuffer)); + hmac.BlockUpdate(data, 0, data.Length); + hmac.DoFinal(i, 0); + + byte[] il = i.Slice(0, 32); + byte[] ir = i.Slice(32); + + return (Key: il, ChainCode: ir); + } + + /// + /// Checks if the derivation path is valid. + /// Returns true if the path is valid, otherwise false. + /// + /// The derivation path. + /// A boolean. + private static bool IsValidPath(string path) + { + Regex regex = new("^m(\\/[0-9]+')+$"); + + if (!regex.IsMatch(path)) + return false; + + bool valid = !(path.Split('/') + .Slice(1) + .Select(a => a.Replace("'", "")) + .Any(a => !int.TryParse(a, out _))); + + return valid; + } + + /// + /// Derives a child key from the passed derivation path. + /// + /// The derivation path. + /// The key and chaincode. + /// Thrown when the passed derivation path is invalid. + public (byte[] Key, byte[] ChainCode) DerivePath(string path) + { + if (!IsValidPath(path)) + throw new FormatException("Invalid derivation path"); + + IEnumerable segments = path + .Split('/') + .Slice(1) + .Select(a => a.Replace("'", "")) + .Select(a => Convert.ToUInt32(a, 10)); + + (byte[] _masterKey, byte[] _chainCode) results = segments + .Aggregate( + (_masterKey, _chainCode), + (masterKeyFromSeed, next) => + GetChildKeyDerivation(masterKeyFromSeed._masterKey, masterKeyFromSeed._chainCode, next + HardenedOffset)); + + return results; + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Ed25519Bip32.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Ed25519Bip32.cs.meta new file mode 100644 index 0000000..4a05ef0 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Ed25519Bip32.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ea946695bef5ff94eb3c98c6a3401020 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/PrivateKey.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/PrivateKey.cs new file mode 100644 index 0000000..bc15c4f --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/PrivateKey.cs @@ -0,0 +1,150 @@ +// unset + +using Chaos.NaCl; +using Solana.Unity.Wallet.Utilities; +using System; +using System.Diagnostics; + +namespace Solana.Unity.Wallet +{ + /// + /// Implements the private key functionality. + /// + [DebuggerDisplay("Key = {ToString()}")] + public class PrivateKey + { + /// + /// Private key length. + /// + public const int PrivateKeyLength = 64; + + private string _key; + + /// + /// The key as base-58 encoded string. + /// + public string Key + { + get + { + if (_key == null) + { + Key = Encoders.Base58.EncodeData(KeyBytes); + } + return _key; + } + set => _key = value; + } + + + private byte[] _keyBytes; + + /// + /// The bytes of the key. + /// + public byte[] KeyBytes + { + get + { + if (_keyBytes == null) + { + KeyBytes = Encoders.Base58.DecodeData(Key); + } + return _keyBytes; + } + set => _keyBytes = value; + } + + + /// + /// Initialize the public key from the given byte array. + /// + /// The public key as byte array. + public PrivateKey(byte[] key) + { + if (key == null) + throw new ArgumentNullException(nameof(key)); + if (key.Length != PrivateKeyLength) + throw new ArgumentException("invalid key length", nameof(key)); + KeyBytes = new byte[PrivateKeyLength]; + Array.Copy(key, KeyBytes, PrivateKeyLength); + } + + /// + /// Initialize the public key from the given string. + /// + /// The public key as base58 encoded string. + public PrivateKey(string key) + { + Key = key ?? throw new ArgumentNullException(nameof(key)); + } + + /// + /// Initialize the public key from the given string. + /// + /// The public key as base58 encoded string. + public PrivateKey(ReadOnlySpan key) + { + if (key.Length != PrivateKeyLength) + throw new ArgumentException("invalid key length", nameof(key)); + KeyBytes = new byte[PrivateKeyLength]; + key.CopyTo(KeyBytes.AsSpan()); + } + + /// + /// Sign the data. + /// + /// The data to sign. + /// The signature of the data. + public byte[] Sign(byte[] message) + { + ArraySegment signature = new ArraySegment(new byte[64]); + Ed25519.Sign(signature, + new ArraySegment(message), + new ArraySegment(KeyBytes)); + return signature.Array; + } + + /// + public override bool Equals(object obj) + { + if (obj is PrivateKey pk) return pk.Key == this.Key; + + return false; + } + + /// + /// Conversion between a object and the corresponding base-58 encoded private key. + /// + /// The PrivateKey object. + /// The base-58 encoded private key. + public static implicit operator string(PrivateKey privateKey) => privateKey.Key; + + /// + /// Conversion between a base-58 encoded private key and the object. + /// + /// The base-58 encoded private key. + /// The PrivateKey object. + public static explicit operator PrivateKey(string address) => new(address); + + /// + /// Conversion between a object and the private key as a byte array. + /// + /// The PrivateKey object. + /// The private key as a byte array. + public static implicit operator byte[](PrivateKey privateKey) => privateKey.KeyBytes; + + /// + /// Conversion between a private key as a byte array and the corresponding object. + /// + /// The private key as a byte array. + /// The PrivateKey object. + public static explicit operator PrivateKey(byte[] keyBytes) => new(keyBytes); + + /// + public override string ToString() => Key; + + /// + public override int GetHashCode() => Key.GetHashCode(); + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/PrivateKey.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/PrivateKey.cs.meta new file mode 100644 index 0000000..a365d66 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/PrivateKey.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0ac748b6116287945bf1ade180d90d14 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/PublicKey.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/PublicKey.cs new file mode 100644 index 0000000..8552a51 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/PublicKey.cs @@ -0,0 +1,369 @@ +using Chaos.NaCl; +using Solana.Unity.Wallet.Utilities; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Security.Cryptography; +using System.Text; + +namespace Solana.Unity.Wallet +{ + /// + /// Implements the public key functionality. + /// + [DebuggerDisplay("Key = {ToString()}")] + public class PublicKey + { + /// + /// Public key length. + /// + public const int PublicKeyLength = 32; + + private string _key; + + /// + /// The key as base-58 encoded string. + /// + public string Key + { + get + { + if (_key == null) + { + Key = Encoders.Base58.EncodeData(KeyBytes); + } + return _key; + } + set => _key = value; + } + + + private byte[] _keyBytes; + + /// + /// The bytes of the key. + /// + public byte[] KeyBytes + { + get + { + if (_keyBytes == null) + { + KeyBytes = Encoders.Base58.DecodeData(Key); + } + return _keyBytes; + } + set => _keyBytes = value; + } + + + /// + /// Initialize the public key from the given byte array. + /// + /// The public key as byte array. + public PublicKey(byte[] key) + { + if (key == null) + throw new ArgumentNullException(nameof(key)); + if (key.Length != PublicKeyLength) + throw new ArgumentException("invalid key length", nameof(key)); + KeyBytes = new byte[PublicKeyLength]; + Array.Copy(key, KeyBytes, PublicKeyLength); + } + + /// + /// Initialize the public key from the given string. + /// + /// The public key as base58 encoded string. + public PublicKey(string key) + { + Key = key ?? throw new ArgumentNullException(nameof(key)); + } + + /// + /// Initialize the public key from the given string. + /// + /// The public key as base58 encoded string. + public PublicKey(ReadOnlySpan key) + { + if (key.Length != PublicKeyLength) + throw new ArgumentException("invalid key length", nameof(key)); + KeyBytes = new byte[PublicKeyLength]; + key.CopyTo(KeyBytes.AsSpan()); + } + + /// + /// Verify the signed message. + /// + /// The signed message. + /// The signature of the message. + /// + public bool Verify(byte[] message, byte[] signature) + { + return Ed25519.Verify(signature, message, KeyBytes); + } + + /// + public override bool Equals(object obj) + { + if (obj is PublicKey pk) return pk.Key == this.Key; + + return false; + } + + /// + public static bool operator ==(PublicKey lhs, PublicKey rhs) + { + + if (lhs is null) + { + if (rhs is null) + { + return true; + } + + // Only the left side is null. + return false; + } + // Equals handles case of null on right side. + return lhs.Equals(rhs); + } + + /// + public static bool operator !=(PublicKey lhs, PublicKey rhs) => !(lhs == rhs); + + /// + /// Conversion between a object and the corresponding base-58 encoded public key. + /// + /// The PublicKey object. + /// The base-58 encoded public key. + public static implicit operator string(PublicKey publicKey) => publicKey.Key; + + /// + /// Conversion between a base-58 encoded public key and the object. + /// + /// The base-58 encoded public key. + /// The PublicKey object. + public static explicit operator PublicKey(string address) => new(address); + + /// + /// Conversion between a object and the public key as a byte array. + /// + /// The PublicKey object. + /// The public key as a byte array. + public static implicit operator byte[](PublicKey publicKey) => publicKey.KeyBytes; + + /// + /// Conversion between a public key as a byte array and the corresponding object. + /// + /// The public key as a byte array. + /// The PublicKey object. + public static explicit operator PublicKey(byte[] keyBytes) => new(keyBytes); + + /// + public override string ToString() => Key; + + /// + public override int GetHashCode() => Key.GetHashCode(); + + + /// + /// Checks if this object is a valid Ed25519 PublicKey. + /// + /// Returns true if it is a valid key, false otherwise. + public bool IsOnCurve() + { + return Ed25519Extensions.IsOnCurve(KeyBytes); + } + + /// + /// Checks if this object is a valid Solana PublicKey. + /// + /// Returns true if it is a valid key, false otherwise. + public bool IsValid() + { + return KeyBytes != null && KeyBytes.Length == PublicKeyLength; + } + + /// + /// Checks if a given string forms a valid PublicKey in base58. + /// + /// + /// Any set of 32 bytes can constitute a valid solana public key. However, not all 32-byte public keys are valid Ed25519 public keys.
+ /// Two concrete examples:
+ /// - A user wallet key must be on the curve (otherwise a user wouldn't be able to sign transactions).
+ /// - A program derived address must NOT be on the curve. + ///
+ /// The base58 encoded public key. + /// Whether or not to validate if the public key belongs to the Ed25519 curve. + /// Returns true if the input is a valid key, false otherwise. + public static bool IsValid(string key, bool validateCurve = false) + { + if(!string.IsNullOrEmpty(key)) + { + try + { + return IsValid(Encoders.Base58.DecodeData(key), validateCurve); + } + catch(Exception) + { + return false; + } + } + return false; + } + + /// + /// Checks if a given set of bytes forms a valid PublicKey. + /// + /// + /// Any set of 32 bytes can constitute a valid solana public key. However, not all 32-byte public keys are valid Ed25519 public keys.
+ /// Two concrete examples:
+ /// - A user wallet key must be on the curve (otherwise a user wouldn't be able to sign transactions).
+ /// - A program derived address must NOT be on the curve. + ///
+ /// The key bytes. + /// Whether or not to validate if the public key belongs to the Ed25519 curve. + /// Returns true if the input is a valid key, false otherwise. + public static bool IsValid(byte[] key, bool validateCurve = false) + { + return key != null && key.Length == PublicKeyLength && (!validateCurve || key.IsOnCurve()); + } + + /// + /// Checks if a given set of bytes forms a valid PublicKey. + /// + /// + /// Any set of 32 bytes can constitute a valid solana public key. However, not all 32-byte public keys are valid Ed25519 public keys.
+ /// Two concrete examples:
+ /// - A user wallet key must be on the curve (otherwise a user wouldn't be able to sign transactions).
+ /// - A program derived address must NOT be on the curve. + ///
+ /// The key bytes. + /// Whether or not to validate if the public key belongs to the Ed25519 curve. + /// Returns true if the input is a valid key, false otherwise. + public static bool IsValid(ReadOnlySpan key, bool validateCurve = false) + { + return key != null && key.Length == PublicKeyLength && (!validateCurve || key.IsOnCurve()); + } + + #region KeyDerivation + + /// + /// The bytes of the `ProgramDerivedAddress` string. + /// + private static readonly byte[] ProgramDerivedAddressBytes = Encoding.UTF8.GetBytes("ProgramDerivedAddress"); + + /// + /// Derives a program address. + /// + /// The address seeds. + /// The program Id. + /// The derived public key, returned as inline out. + /// true if it could derive the program address for the given seeds, otherwise false.. + /// Throws exception when one of the seeds has an invalid length. + public static bool TryCreateProgramAddress(ICollection seeds, PublicKey programId, out PublicKey publicKey) + { + MemoryStream buffer = new(PublicKeyLength * seeds.Count + ProgramDerivedAddressBytes.Length + programId.KeyBytes.Length); + + foreach (byte[] seed in seeds) + { + if (seed.Length > PublicKeyLength) + { + throw new ArgumentException("max seed length exceeded", nameof(seeds)); + } + buffer.Write(seed,0, seed.Length); + } + + buffer.Write(programId.KeyBytes, 0, programId.KeyBytes.Length); + buffer.Write(ProgramDerivedAddressBytes, 0, ProgramDerivedAddressBytes.Length); + + SHA256 sha256 = SHA256.Create(); + byte[] hash = sha256.ComputeHash(new ReadOnlySpan(buffer.GetBuffer(), 0, (int)buffer.Length).ToArray()); + + if (hash.IsOnCurve()) + { + publicKey = null; + return false; + } + publicKey = new(hash); + return true; + } + + /// + /// Attempts to find a program address for the passed seeds and program Id. + /// + /// The address seeds. + /// The program Id. + /// The derived address, returned as inline out. + /// The bump used to derive the address, returned as inline out. + /// True whenever the address for a nonce was found, otherwise false. + public static bool TryFindProgramAddress(IEnumerable seeds, PublicKey programId, out PublicKey address, out byte bump) + { + byte seedBump = 255; + List buffer = seeds.ToList(); + var bumpArray = new byte[1]; + buffer.Add(bumpArray); + + while (seedBump != 0) + { + bumpArray[0] = seedBump; + bool success = TryCreateProgramAddress(buffer, programId, out PublicKey derivedAddress); + + if (success) + { + address = derivedAddress; + bump = seedBump; + return true; + } + + seedBump--; + } + + address = null; + bump = 0; + return false; + } + + /// + /// Derives a new public key from an existing public key and seed + /// + /// The extant pubkey + /// The seed + /// The programid + /// The derived public key + /// True whenever the address was successfully created, otherwise false. + /// To fail address creation, means the created address was a PDA. + public static bool TryCreateWithSeed(PublicKey fromPublicKey, string seed, PublicKey programId, out PublicKey publicKeyOut) + { + var b58 = new Base58Encoder(); + MemoryStream buffer = new(); + + buffer.Write(fromPublicKey.KeyBytes, 0, fromPublicKey.KeyBytes.Length); + buffer.Write(Encoding.UTF8.GetBytes(seed), 0, Encoding.UTF8.GetBytes(seed).Length); + buffer.Write(programId.KeyBytes, 0, programId.KeyBytes.Length); + + var seeds = new ReadOnlySpan(buffer.GetBuffer(), 0, (int)buffer.Length); + + if(seeds.Length >= ProgramDerivedAddressBytes.Length) + { + var slice = seeds.Slice(seeds.Length - ProgramDerivedAddressBytes.Length); + + if(slice.SequenceEqual(ProgramDerivedAddressBytes)) + { + publicKeyOut = null; + return false; + } + } + + SHA256 sha256 = SHA256.Create(); + byte[] hash = sha256.ComputeHash(seeds.ToArray()); + publicKeyOut = new PublicKey(hash); + return true; + } + + #endregion + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/PublicKey.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/PublicKey.cs.meta new file mode 100644 index 0000000..c28c762 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/PublicKey.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ad49a1693b15d4d41aeffa820d47cd82 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/SeedMode.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/SeedMode.cs new file mode 100644 index 0000000..9348bc0 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/SeedMode.cs @@ -0,0 +1,24 @@ +namespace Solana.Unity.Wallet +{ + /// + /// Specifies the available seed modes for key generation. + /// + /// Available modes: + /// + /// + /// + /// + public enum SeedMode + { + /// + /// Generates Ed25519 based BIP32 keys. + /// This seed mode is compatible with the keys generated in the Sollet/SPL Token Wallet, it does not use a passphrase to harden the mnemonic seed. + /// + Ed25519Bip32, + /// + /// Generates BIP39 keys. + /// This seed mode is compatible with the keys generated in the solana-keygen cli, it uses a passphrase to harden the mnemonic seed. + /// + Bip39 + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/SeedMode.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/SeedMode.cs.meta new file mode 100644 index 0000000..2b6d049 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/SeedMode.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 84eae6d8b0bdcf643b747cf28c782e6d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Solana.Unity.Wallet.csproj.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Solana.Unity.Wallet.csproj.meta new file mode 100644 index 0000000..8c784ca --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Solana.Unity.Wallet.csproj.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: bfd7c4d7ddb3d9e43be687036159fc3a +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Utilities.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Utilities.meta new file mode 100644 index 0000000..967c57f --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Utilities.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5aae04bba770d9e4293dee094d7040a6 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Utilities/Base58Encoder.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Utilities/Base58Encoder.cs new file mode 100644 index 0000000..e121fb3 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Utilities/Base58Encoder.cs @@ -0,0 +1,180 @@ +// unset + +using System; +using System.Collections; +using System.Linq; + +namespace Solana.Unity.Wallet.Utilities +{ + /// + /// Implements a base58 encoder. + /// + public sealed class Base58Encoder : DataEncoder + { + /// + /// The base58 characters. + /// + private static readonly char[] PszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz".ToCharArray(); + + /// + /// + /// + private static readonly int[] MapBase58 = { + -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8,-1,-1,-1,-1,-1,-1, + -1, 9,10,11,12,13,14,15, 16,-1,17,18,19,20,21,-1, + 22,23,24,25,26,27,28,29, 30,31,32,-1,-1,-1,-1,-1, + -1,33,34,35,36,37,38,39, 40,41,42,43,-1,44,45,46, + 47,48,49,50,51,52,53,54, 55,56,57,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, + }; + /// + /// Fast check if the string to know if base58 str + /// + /// + /// + public bool IsMaybeEncoded(string str) + { + bool maybeB58 = str.All(t => ((IList)PszBase58).Contains(t)); + + return maybeB58 && str.Length > 0; + } + + /// + /// Encode the data. + /// + /// The data to encode. + /// The offset at which to start encoding. + /// The number of bytes to encode. + /// The encoded data. + /// Thrown if the data array is null. + public override string EncodeData(byte[] data, int offset, int count) + { + if (data == null) + throw new ArgumentNullException(nameof(data)); + + // Skip & count leading zeroes. + int zeroes = 0; + int length = 0; + while (offset != count && data[offset] == 0) + { + offset++; + zeroes++; + } + + // Allocate enough space in big-endian base58 representation. + int size = (count - offset) * 138 / 100 + 1; // log(256) / log(58), rounded up. + byte[] b58 = new byte[size]; + + // Process the bytes. + while (offset != count) + { + int carry = data[offset]; + int i = 0; + + // Apply "b58 = b58 * 256 + ch". + for (int it = size - 1; (carry != 0 || i < length) && it >= 0; i++, it--) + { + carry += 256 * b58[it]; + b58[it] = (byte)(carry % 58); + carry /= 58; + } + + length = i; + offset++; + } + + // Skip leading zeroes in base58 result. + int it2 = (size - length); + while (it2 != size && b58[it2] == 0) + it2++; + + // Translate the result into a string. + char[] str = new char[zeroes + size - it2]; + for (int i = 0; i < zeroes; i++) + { + str[i] = '1'; + } + int i2 = zeroes; + while (it2 != size) + str[i2++] = PszBase58[b58[it2++]]; + return new string(str); + } + + /// + /// Decode the data. + /// + /// The data to decode. + /// The decoded data. + /// Thrown if the encoded data is null. + /// Thrown if the data is invalid. + public override byte[] DecodeData(string encoded) + { + if (encoded == null) + throw new ArgumentNullException(nameof(encoded)); + int psz = 0; + + // Skip leading spaces. + while (psz < encoded.Length && IsSpace(encoded[psz])) + psz++; + + // Skip and count leading '1's. + int zeroes = 0; + int length = 0; + while (psz < encoded.Length && encoded[psz] == '1') + { + zeroes++; + psz++; + } + + // Allocate enough space in big-endian base256 representation. + int size = (encoded.Length - psz) * 733 / 1000 + 1; // log(58) / log(256), rounded up. + byte[] b256 = new byte[size]; + + // Process the characters. + while (psz < encoded.Length && !IsSpace(encoded[psz])) + { + // Decode base58 character + int carry = MapBase58[(byte)encoded[psz]]; + if (carry == -1) // Invalid b58 character + throw new FormatException("Invalid base58 data"); + int i = 0; + for (int it = size - 1; (carry != 0 || i < length) && it >= 0; i++, it--) + { + carry += 58 * b256[it]; + b256[it] = (byte)(carry % 256); + carry /= 256; + } + length = i; + psz++; + } + + // Skip trailing spaces. + while (psz < encoded.Length && IsSpace(encoded[psz])) + psz++; + if (psz != encoded.Length) + throw new FormatException("Invalid base58 data"); + // Skip leading zeroes in b256. + int it2 = size - length; + // Copy result into output vector. + byte[] vch = new byte[zeroes + size - it2]; + for (int i = 0; i < zeroes; i++) + { + vch[i] = 0; + } + int i2 = zeroes; + while (it2 != size) + vch[i2++] = b256[it2++]; + return vch; + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Utilities/Base58Encoder.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Utilities/Base58Encoder.cs.meta new file mode 100644 index 0000000..e6e29fe --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Utilities/Base58Encoder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 32062f63d5067bc44aeccc474ec150c2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Utilities/BitWriter.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Utilities/BitWriter.cs new file mode 100644 index 0000000..85d992f --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Utilities/BitWriter.cs @@ -0,0 +1,182 @@ +using Solana.Unity.Wallet.Bip39; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Solana.Unity.Wallet.Utilities +{ + /// + /// Implements a bit writer. + /// + internal class BitWriter + { + /// + /// The values of the bit writer. + /// + private readonly List _values = new(); + + /// + /// The number of values. + /// + private int Count => _values.Count; + + /// + /// Writes a value to the writer buffer. + /// + /// The value. + private void Write(bool value) + { + _values.Insert(Position, value); + Position++; + } + + /// + /// Writes a byte array to the writer buffer. + /// + /// The byte array. + internal void Write(byte[] bytes) + { + Write(bytes, bytes.Length * 8); + } + + /// + /// Writes a byte array to the writer buffer. + /// + /// The byte array. + /// The bit count. + public void Write(byte[] bytes, int bitCount) + { + bytes = SwapEndianBytes(bytes); + BitArray array = new(bytes); + _values.InsertRange(Position, array.OfType().Take(bitCount)); + Position += bitCount; + } + + /// + /// Gets the bit writer's buffer as a byte array. + /// + /// The byte array. + public byte[] ToBytes() + { + BitArray array = ToBitArray(); + byte[] bytes = ToByteArray(array); + bytes = SwapEndianBytes(bytes); + return bytes; + } + + /// + /// Convert a bit array to a byte array. + /// + /// The bit array to convert. + /// The byte array. + private static byte[] ToByteArray(BitArray bits) + { + int arrayLength = bits.Length / 8; + if (bits.Length % 8 != 0) + arrayLength++; + byte[] array = new byte[arrayLength]; + + for (int i = 0; i < bits.Length; i++) + { + int b = i / 8; + int offset = i % 8; + array[b] |= bits.Get(i) ? (byte)(1 << offset) : (byte)0; + } + return array; + } + + /// + /// Gets the bit writer's buffer as a bit array. + /// + /// The bit array. + public BitArray ToBitArray() + { + return new(_values.ToArray()); + } + + /// + /// Gets the bit writer's buffer as an array of integers. + /// + /// The array of integers. + public int[] ToIntegers() + { + BitArray array = new(_values.ToArray()); + return ToIntegers(array); + } + + /// + /// Swaps the endianness of the bytes. + /// + /// The bytes to swap. + /// The swapped byte array. + private static byte[] SwapEndianBytes(IReadOnlyList bytes) + { + byte[] output = new byte[bytes.Count]; + for (int i = 0; i < output.Length; i++) + { + byte newByte = 0; + for (int ib = 0; ib < 8; ib++) + { + newByte += (byte)(((bytes[i] >> ib) & 1) << (7 - ib)); + } + output[i] = newByte; + } + return output; + } + + /// + /// The current position of the bit writer. + /// + public int Position { get; set; } + + /// + /// Write + /// + /// + /// + public void Write(BitArray bitArray, int bitCount) + { + for (int i = 0; i < bitCount; i++) + { + Write(bitArray.Get(i)); + } + } + + /// + /// Convert the bit array to integers. + /// + /// The bit array. + /// The int array. + public static int[] ToIntegers(BitArray bits) + { + return + bits + .OfType() + .Select((v, i) => new + { + Group = i / 11, + Value = v ? 1 << (10 - (i % 11)) : 0 + }) + .GroupBy(_ => _.Group, _ => _.Value) + .Select(g => g.Sum()) + .ToArray(); + } + + /// + /// Encode the writer as string. + /// + /// The string. + public override string ToString() + { + StringBuilder builder = new(_values.Count); + for (int i = 0; i < Count; i++) + { + if (i != 0 && i % 8 == 0) + builder.Append(' '); + builder.Append(_values[i] ? "1" : "0"); + } + return builder.ToString(); + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Utilities/BitWriter.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Utilities/BitWriter.cs.meta new file mode 100644 index 0000000..6f0361e --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Utilities/BitWriter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f8ad77b01357f264aa2245d810df7cda +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Utilities/DataEncoder.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Utilities/DataEncoder.cs new file mode 100644 index 0000000..342d201 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Utilities/DataEncoder.cs @@ -0,0 +1,77 @@ +namespace Solana.Unity.Wallet.Utilities +{ + /// + /// Abstract data encoder class. + /// + public abstract class DataEncoder + { + /// + /// Check if the character is a space... + /// + /// The character. + /// True if it is, otherwise false. + public static bool IsSpace(char c) + { + switch (c) + { + case ' ': + case '\t': + case '\n': + case '\v': + case '\f': + case '\r': + return true; + } + return false; + } + + /// + /// Initialize the data encoder. + /// + internal DataEncoder() + { + } + + /// + /// Encode the data. + /// + /// The data to encode. + /// The data encoded. + public string EncodeData(byte[] data) + { + return EncodeData(data, 0, data.Length); + } + + /// + /// Encode the data. + /// + /// The data to encode. + /// The offset at which to start encoding. + /// The number of bytes to encode. + /// The encoded data. + public abstract string EncodeData(byte[] data, int offset, int count); + + /// + /// Decode the data. + /// + /// The data to decode. + /// The decoded data. + public abstract byte[] DecodeData(string encoded); + } + + /// + /// A static encoder instance. + /// + public static class Encoders + { + /// + /// The encoder. + /// + private static readonly Base58Encoder _base58 = new(); + + /// + /// The encoder. + /// + public static DataEncoder Base58 => _base58; + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Utilities/DataEncoder.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Utilities/DataEncoder.cs.meta new file mode 100644 index 0000000..d895ea7 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Utilities/DataEncoder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cb5aa93a908a28e42a3774d156137abe +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Utilities/Ed25519Extensions.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Utilities/Ed25519Extensions.cs new file mode 100644 index 0000000..83b41aa --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Utilities/Ed25519Extensions.cs @@ -0,0 +1,121 @@ +using System; +using System.Numerics; + +namespace Solana.Unity.Wallet.Utilities +{ + /* Ported and refactored from Java to C# by Hans Wolff, 10/10/2013 + * Released to the public domain + * / + /* Java code written by k3d3 + * Source: https://github.com/k3d3/ed25519-java/blob/master/ed25519.java + * Released to the public domain + */ + + /// + /// Helper methods for ED25519 checks + /// Edwards-curve Digital Signature Algorithm (EdDSA) + /// https://en.wikipedia.org/wiki/EdDSA#Ed25519 + /// + public static class Ed25519Extensions + { + private static BigInteger ExpMod(BigInteger number, BigInteger exponent, BigInteger modulo) + { + if (exponent.Equals(BigInteger.Zero)) + { + return BigInteger.One; + } + BigInteger t = BigInteger.Pow(ExpMod(number, exponent / Two, modulo), 2).Mod(modulo); + if (!exponent.IsEven) + { + t *= number; + t = t.Mod(modulo); + } + return t; + } + + private static BigInteger Inv(BigInteger x) + { + return ExpMod(x, Qm2, Q); + } + + private static BigInteger RecoverX(BigInteger y) + { + BigInteger y2 = y * y; + BigInteger xx = (y2 - 1) * Inv(D * y2 + 1); + BigInteger x = ExpMod(xx, Qp3 / Eight, Q); + if (!(x * x - xx).Mod(Q).Equals(BigInteger.Zero)) + { + x = (x * I).Mod(Q); + } + if (!x.IsEven) + { + x = Q - x; + } + return x; + } + + private static bool IsOnCurve(BigInteger x, BigInteger y) + { + BigInteger xx = x * x; + BigInteger yy = y * y; + BigInteger dxxyy = D * yy * xx; + return (yy - xx - dxxyy - 1).Mod(Q).Equals(BigInteger.Zero); + } + + /// + /// Checks whether the PublicKey bytes are 'On The Curve' + /// + /// PublicKey as byte array + /// + public static bool IsOnCurve(this byte[] key) + { + BigInteger y = new BigInteger(key) & Un; + BigInteger x = RecoverX(y); + + return IsOnCurve(x, y); + } + + /// + /// Checks whether the PublicKey bytes are 'On The Curve' + /// + /// PublicKey as byte array + /// + public static bool IsOnCurve(this ReadOnlySpan key) + { + BigInteger y = new BigInteger(key.ToArray()) & Un; + BigInteger x = RecoverX(y); + + return IsOnCurve(x, y); + } + + private static readonly BigInteger Q = + BigInteger.Parse("57896044618658097711785492504343953926634992332820282019728792003956564819949"); + + private static readonly BigInteger Qm2 = + BigInteger.Parse("57896044618658097711785492504343953926634992332820282019728792003956564819947"); + + private static readonly BigInteger Qp3 = + BigInteger.Parse("57896044618658097711785492504343953926634992332820282019728792003956564819952"); + + private static readonly BigInteger D = + BigInteger.Parse("-4513249062541557337682894930092624173785641285191125241628941591882900924598840740"); + + private static readonly BigInteger I = + BigInteger.Parse("19681161376707505956807079304988542015446066515923890162744021073123829784752"); + + private static readonly BigInteger Un = + BigInteger.Parse("57896044618658097711785492504343953926634992332820282019728792003956564819967"); + + private static readonly BigInteger Two = new(2); + private static readonly BigInteger Eight = new(8); + } + + internal static class BigIntegerHelpers + { + internal static BigInteger Mod(this BigInteger num, BigInteger modulo) + { + var result = num % modulo; + return result < 0 ? result + modulo : result; + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Utilities/Ed25519Extensions.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Utilities/Ed25519Extensions.cs.meta new file mode 100644 index 0000000..a77fd4c --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Utilities/Ed25519Extensions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a024177c553c1a043873d141c45b156c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Utilities/RandomUtils.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Utilities/RandomUtils.cs new file mode 100644 index 0000000..51e6a42 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Utilities/RandomUtils.cs @@ -0,0 +1,162 @@ +using Org.BouncyCastle.Security; +using System; + +namespace Solana.Unity.Wallet.Utilities +{ + /// + /// Implements a random number generator using the crypto service provider. + /// + public class RngCryptoServiceProviderRandom : IRandom + { + /// + /// The instance of the crypto service provider. + /// + private readonly SecureRandom _instance; + + /// + /// Initialize the random number generator. + /// + public RngCryptoServiceProviderRandom() + { + _instance = new SecureRandom(); + } + + #region IRandom Members + + /// + public void GetBytes(byte[] output) + { + _instance.NextBytes(output); + } + + #endregion + } + + /// + /// Specifies functionality for a random number generator. + /// + public interface IRandom + { + /// + /// Get bytes. + /// + /// The output array of bytes. + void GetBytes(byte[] output); + } + + /// + /// Implements utilities to be used with random number generation. + /// + public static class RandomUtils + { + /// + /// Whether to use additional entropy or not. + /// + public static bool UseAdditionalEntropy { get; set; } = true; + + /// + /// Initialize the static instance of the random number generator. + /// + static RandomUtils() + { + Random = new RngCryptoServiceProviderRandom(); + AddEntropy(Guid.NewGuid().ToByteArray()); + } + + /// + /// The random number generator. + /// + public static IRandom Random + { + get; + set; + } + + /// + /// Get random bytes. + /// + /// The number of bytes to get. + /// The byte array. + /// Thrown when the random number generator has not been initialized + public static byte[] GetBytes(int length) + { + byte[] data = new byte[length]; + if (Random == null) + throw new InvalidOperationException("You must initialize the random number generator before generating numbers."); + Random.GetBytes(data); + PushEntropy(data); + return data; + } + + /// + /// Get random bytes. + /// + /// The array of bytes to write the random bytes to. + /// The byte array. + /// Thrown when the random number generator has not been initialized + public static byte[] GetBytes(byte[] output) + { + if (Random == null) + throw new InvalidOperationException("You must initialize the random number generator before generating numbers."); + Random.GetBytes(output); + PushEntropy(output); + return output; + } + + /// + /// Pushes entropy to the given array of bytes. + /// + /// The array of bytes. + private static void PushEntropy(byte[] data) + { + if (!UseAdditionalEntropy || _additionalEntropy == null || data.Length == 0) + return; + int pos = _entropyIndex; + var entropy = _additionalEntropy; + for (int i = 0; i < data.Length; i++) + { + data[i] ^= entropy[pos % 32]; + pos++; + } + entropy = Utils.Sha256(data); + for (int i = 0; i < data.Length; i++) + { + data[i] ^= entropy[pos % 32]; + pos++; + } + _entropyIndex = pos % 32; + } + + /// + /// The additional entropy. + /// + private static volatile byte[] _additionalEntropy = null; + + /// + /// The entropy index.. + /// + private static volatile int _entropyIndex = 0; + + /// + /// Add entropy to the given data. + /// + /// The data to add entropy to. + /// Thrown if the data array is null. + public static void AddEntropy(byte[] data) + { + if (data == null) + throw new ArgumentNullException(nameof(data)); + var entropy = Utils.Sha256(data); + if (_additionalEntropy == null) + _additionalEntropy = entropy; + else + { + for (int i = 0; i < 32; i++) + { + _additionalEntropy[i] ^= entropy[i]; + } + _additionalEntropy = Utils.Sha256(_additionalEntropy); + } + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Utilities/RandomUtils.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Utilities/RandomUtils.cs.meta new file mode 100644 index 0000000..f11258e --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Utilities/RandomUtils.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: aa2f1d7556e9d8b4d93fc88c1b2d504c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Utilities/Utils.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Utilities/Utils.cs new file mode 100644 index 0000000..1e4718c --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Utilities/Utils.cs @@ -0,0 +1,107 @@ +using Chaos.NaCl; +using System; +using System.Collections.Generic; +using System.Security.Cryptography; + +namespace Solana.Unity.Wallet.Utilities +{ + /// + /// Implements utility methods to be used in the wallet. + /// + internal static class Utils + { + /// + /// Adds or replaces a value in a dictionary. + /// + /// The dictionary. + /// The key to add or replace. + /// The value. + /// The type of the key. + /// The type of the value. + internal static void AddOrReplace(this IDictionary dictionary, TKey key, TValue value) + { + if (dictionary.ContainsKey(key)) + dictionary[key] = value; + else + dictionary.Add(key, value); + } + + /// + /// Attempts to get a value from a dictionary. + /// + /// The dictionary to get the value from. + /// The key to get. + /// The type of the key. + /// The type of the value. + /// The value. + internal static TValue TryGet(this IDictionary dictionary, TKey key) + { + dictionary.TryGetValue(key, out TValue value); + return value; + } + + /// + /// Slices the array, returning a new array starting at start index and ending at end index. + /// + /// The array to slice. + /// The starting index of the slicing. + /// The ending index of the slicing. + /// The array type. + /// The sliced array. + internal static T[] Slice(this T[] source, int start, int end) + { + if (end < 0) + end = source.Length; + + var len = end - start; + + // Return new array. + var res = new T[len]; + for (var i = 0; i < len; i++) res[i] = source[i + start]; + return res; + } + + /// + /// Slices the array, returning a new array starting at start. + /// + /// The array to slice. + /// The starting index of the slicing. + /// The array type. + /// The sliced array. + internal static T[] Slice(this T[] source, int start) + { + return Slice(source, start, -1); + } + + /// + /// Calculates the Sha256 of the given data. + /// + /// The data to hash. + /// The hash. + public static byte[] Sha256(ReadOnlySpan data) + { + return Sha256(data.ToArray(), 0, data.Length); + } + + /// + /// Calculates the SHA256 of the given data. + /// + /// The data to hash. + /// The offset at which to start. + /// The number of bytes to in the array to use as data. + /// The hash. + private static byte[] Sha256(byte[] data, int offset, int count) + { + var SHA256CHECKSUM = SHA256.Create(); + return SHA256CHECKSUM.ComputeHash(data.AsSpan(offset,count).ToArray()); + } + + /// + /// Gets the corresponding ed25519 key pair from the passed seed. + /// + /// The seed + /// The key pair. + internal static (byte[] privateKey, byte[] publicKey) EdKeyPairFromSeed(byte[] seed) => + new(Ed25519.ExpandedPrivateKeyFromSeed(seed), Ed25519.PublicKeyFromSeed(seed)); + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Utilities/Utils.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Utilities/Utils.cs.meta new file mode 100644 index 0000000..029edf8 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Utilities/Utils.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1d1b1f2fe8171734eb495bdf681ff656 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Wallet.cs b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Wallet.cs new file mode 100644 index 0000000..668b09b --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Wallet.cs @@ -0,0 +1,224 @@ +using Chaos.NaCl; +using Solana.Unity.Wallet.Bip39; +using Solana.Unity.Wallet.Utilities; +using System; +using System.Linq; + +namespace Solana.Unity.Wallet +{ + /// + /// Represents a wallet. + /// + public class Wallet + { + /// + /// The derivation path. + /// + private const string DerivationPath = "m/44'/501'/x'/0'"; + + /// + /// The seed mode used for key generation. + /// + private readonly SeedMode _seedMode; + + /// + /// The seed derived from the mnemonic and/or passphrase. + /// + private byte[] _seed; + + /// + /// The method used for key generation. + /// + private Ed25519Bip32 _ed25519Bip32; + + /// + /// The passphrase string. + /// + private string Passphrase { get; } + + /// + /// The key pair. + /// + public Account Account { get; private set; } + + /// + /// The mnemonic words. + /// + // ReSharper disable once MemberCanBePrivate.Global + public Mnemonic Mnemonic { get; } + + /// + /// Initialize a wallet from passed word count and word list for the mnemonic and passphrase. + /// + /// The mnemonic word count. + /// The language of the mnemonic words. + /// The passphrase. + /// The seed generation mode. + public Wallet(WordCount wordCount, WordList wordList, string passphrase = "", SeedMode seedMode = SeedMode.Ed25519Bip32) + : this(new Mnemonic(wordList, wordCount), passphrase, seedMode) + { + } + + /// + /// Initialize a wallet from the passed mnemonic and passphrase. + /// + /// The mnemonic. + /// The passphrase. + /// The seed generation mode. + public Wallet(Mnemonic mnemonic, string passphrase = "", SeedMode seedMode = SeedMode.Ed25519Bip32) + { + Mnemonic = mnemonic; + Passphrase = passphrase; + + _seedMode = seedMode; + InitializeSeed(); + } + + /// + /// Initialize a wallet from the passed mnemonic and passphrase. + /// + /// The mnemonic words. + /// The language of the mnemonic words. Defaults to . + /// The passphrase. + /// The seed generation mode. + public Wallet(string mnemonicWords, WordList wordList = null, string passphrase = "", SeedMode seedMode = SeedMode.Ed25519Bip32) + { + Mnemonic = new Mnemonic(mnemonicWords, wordList ?? WordList.English); + Passphrase = passphrase; + + _seedMode = seedMode; + InitializeSeed(); + } + + /// + /// Initializes a wallet from the passed seed byte array. + /// + /// The seed used for key derivation. + /// The passphrase. + /// The seed mode. + public Wallet(byte[] seed, string passphrase = "", SeedMode seedMode = SeedMode.Ed25519Bip32) + { + if (seed.Length != Ed25519.ExpandedPrivateKeySizeInBytes) + throw new ArgumentException("invalid seed length", nameof(seed)); + + Passphrase = passphrase; + + _seedMode = seedMode; + _seed = seed; + InitializeFirstAccount(); + } + + /// + /// Verify the signed message. + /// + /// The signed message. + /// The signature of the message. + /// The index of the account used to verify the signed message. + /// + public bool Verify(byte[] message, byte[] signature, int accountIndex) + { + if (_seedMode != SeedMode.Ed25519Bip32) + throw new Exception("cannot verify bip39 signatures using ed25519 based bip32 keys"); + + Account account = GetAccount(accountIndex); + return account.Verify(message, signature); + } + + /// + /// Verify the signed message. + /// + /// The signed message. + /// The signature of the message. + /// + public bool Verify(byte[] message, byte[] signature) + { + return Account.Verify(message, signature); + } + + /// + /// Sign the data. + /// + /// The data to sign. + /// The account used to sign the data. + /// The signature of the data. + public byte[] Sign(byte[] message, int accountIndex) + { + if (_seedMode != SeedMode.Ed25519Bip32) + throw new Exception("cannot compute bip39 signature using ed25519 based bip32 keys "); + + Account account = GetAccount(accountIndex); + byte[] signature = account.Sign(message); + + return signature.ToArray(); + } + + /// + /// Sign the data. + /// + /// The data to sign. + /// The signature of the data. + public byte[] Sign(byte[] message) + { + byte[] signature = Account.Sign(message); + return signature.ToArray(); + } + + /// + /// Gets the account at the passed index using the ed25519 bip32 derivation path. + /// + /// The index of the account. + /// The account. + public Account GetAccount(int index) + { + if (_seedMode != SeedMode.Ed25519Bip32) + throw new Exception($"seed mode: {_seedMode} cannot derive Ed25519 based BIP32 keys"); + + string path = DerivationPath.Replace("x", index.ToString()); + (byte[] account, byte[] _) = _ed25519Bip32.DerivePath(path); + (byte[] privateKey, byte[] publicKey) = Utils.EdKeyPairFromSeed(account); + return new Account(privateKey, publicKey); + } + + /// + /// Derive a seed from the passed mnemonic and/or passphrase, depending on . + /// + /// The seed. + public byte[] DeriveMnemonicSeed() + { + if (_seed != null) return _seed; + return _seedMode switch + { + SeedMode.Ed25519Bip32 => Mnemonic.DeriveSeed(), + SeedMode.Bip39 => Mnemonic.DeriveSeed(Passphrase), + _ => Mnemonic.DeriveSeed() + }; + } + + /// + /// Initializes the first account with a key pair derived from the initialized seed. + /// + private void InitializeFirstAccount() + { + if (_seedMode == SeedMode.Ed25519Bip32) + { + _ed25519Bip32 = new Ed25519Bip32(_seed); + Account = GetAccount(0); + } + else + { + (byte[] privateKey, byte[] publicKey) = Utils.EdKeyPairFromSeed(_seed.Slice(0, 32)); + Account = new Account(privateKey, publicKey); + } + } + + /// + /// Derive the mnemonic seed and generate the key pair for the configured wallet. + /// + private void InitializeSeed() + { + _seed = DeriveMnemonicSeed(); + + InitializeFirstAccount(); + } + } +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Wallet.cs.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Wallet.cs.meta new file mode 100644 index 0000000..1e02eab --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.Wallet/Wallet.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8641a9137a8756b4fa77965d80c2ae01 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.asmdef b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.asmdef new file mode 100644 index 0000000..8220d65 --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.asmdef @@ -0,0 +1,17 @@ +{ + "name": "Solana.Unity", + "rootNamespace": "", + "references": [ + "GUID:b3e39678a8864ed408212bd7910fd844", + "GUID:e81c8beff9ece1e43848e56b1b271dea" + ], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": true, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.asmdef.meta b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.asmdef.meta new file mode 100644 index 0000000..71f1d6b --- /dev/null +++ b/Packages/Solana.Unity-Core-2.6.0.9/src/Solana.Unity.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 3faeb4f0d920c5041a297aa38b21a5fe +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Solana.Unity.KeyStore.dll b/Packages/Solana.Unity.KeyStore.dll deleted file mode 100644 index 4bbf3b6..0000000 Binary files a/Packages/Solana.Unity.KeyStore.dll and /dev/null differ diff --git a/Packages/Solana.Unity.KeyStore.dll.meta b/Packages/Solana.Unity.KeyStore.dll.meta deleted file mode 100644 index 1241199..0000000 --- a/Packages/Solana.Unity.KeyStore.dll.meta +++ /dev/null @@ -1,33 +0,0 @@ -fileFormatVersion: 2 -guid: 8c0681e38993347f9856e419d9400456 -PluginImporter: - externalObjects: {} - serializedVersion: 2 - iconMap: {} - executionOrder: {} - defineConstraints: [] - isPreloaded: 0 - isOverridable: 1 - isExplicitlyReferenced: 0 - validateReferences: 1 - platformData: - - first: - Any: - second: - enabled: 1 - settings: {} - - first: - Editor: Editor - second: - enabled: 0 - settings: - DefaultValueInitialized: true - - first: - Windows Store Apps: WindowsStoreApps - second: - enabled: 0 - settings: - CPU: AnyCPU - userData: - assetBundleName: - assetBundleVariant: diff --git a/Packages/Solana.Unity.Programs.dll b/Packages/Solana.Unity.Programs.dll deleted file mode 100644 index e6145d5..0000000 Binary files a/Packages/Solana.Unity.Programs.dll and /dev/null differ diff --git a/Packages/Solana.Unity.Programs.dll.meta b/Packages/Solana.Unity.Programs.dll.meta deleted file mode 100644 index 393c4a1..0000000 --- a/Packages/Solana.Unity.Programs.dll.meta +++ /dev/null @@ -1,33 +0,0 @@ -fileFormatVersion: 2 -guid: c5d767c3edfcc4912958b6abedb18a2d -PluginImporter: - externalObjects: {} - serializedVersion: 2 - iconMap: {} - executionOrder: {} - defineConstraints: [] - isPreloaded: 0 - isOverridable: 1 - isExplicitlyReferenced: 0 - validateReferences: 1 - platformData: - - first: - Any: - second: - enabled: 1 - settings: {} - - first: - Editor: Editor - second: - enabled: 0 - settings: - DefaultValueInitialized: true - - first: - Windows Store Apps: WindowsStoreApps - second: - enabled: 0 - settings: - CPU: AnyCPU - userData: - assetBundleName: - assetBundleVariant: diff --git a/Packages/Solana.Unity.Rpc.dll b/Packages/Solana.Unity.Rpc.dll deleted file mode 100644 index 734ebd1..0000000 Binary files a/Packages/Solana.Unity.Rpc.dll and /dev/null differ diff --git a/Packages/Solana.Unity.Rpc.dll.meta b/Packages/Solana.Unity.Rpc.dll.meta deleted file mode 100644 index 3427287..0000000 --- a/Packages/Solana.Unity.Rpc.dll.meta +++ /dev/null @@ -1,33 +0,0 @@ -fileFormatVersion: 2 -guid: 25b4ece20791e4536bb82d407fab9302 -PluginImporter: - externalObjects: {} - serializedVersion: 2 - iconMap: {} - executionOrder: {} - defineConstraints: [] - isPreloaded: 0 - isOverridable: 1 - isExplicitlyReferenced: 0 - validateReferences: 1 - platformData: - - first: - Any: - second: - enabled: 1 - settings: {} - - first: - Editor: Editor - second: - enabled: 0 - settings: - DefaultValueInitialized: true - - first: - Windows Store Apps: WindowsStoreApps - second: - enabled: 0 - settings: - CPU: AnyCPU - userData: - assetBundleName: - assetBundleVariant: diff --git a/Packages/Solana.Unity.Wallet.dll b/Packages/Solana.Unity.Wallet.dll deleted file mode 100644 index bfb72d7..0000000 Binary files a/Packages/Solana.Unity.Wallet.dll and /dev/null differ diff --git a/Packages/Solana.Unity.Wallet.dll.meta b/Packages/Solana.Unity.Wallet.dll.meta deleted file mode 100644 index ddddbad..0000000 --- a/Packages/Solana.Unity.Wallet.dll.meta +++ /dev/null @@ -1,33 +0,0 @@ -fileFormatVersion: 2 -guid: c16cd03807b784b8a8382c6de57bdae3 -PluginImporter: - externalObjects: {} - serializedVersion: 2 - iconMap: {} - executionOrder: {} - defineConstraints: [] - isPreloaded: 0 - isOverridable: 1 - isExplicitlyReferenced: 0 - validateReferences: 1 - platformData: - - first: - Any: - second: - enabled: 1 - settings: {} - - first: - Editor: Editor - second: - enabled: 0 - settings: - DefaultValueInitialized: true - - first: - Windows Store Apps: WindowsStoreApps - second: - enabled: 0 - settings: - CPU: AnyCPU - userData: - assetBundleName: - assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0.meta b/Packages/bc-csharp-pcl-v1.9.0.meta new file mode 100644 index 0000000..f313ae8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: bb66ddc8ca899484face974c60c1920b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0.meta new file mode 100644 index 0000000..842741b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: efcc3f84bdf745749aeec84806992f93 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/BouncyCastle.asmdef b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/BouncyCastle.asmdef new file mode 100644 index 0000000..e110815 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/BouncyCastle.asmdef @@ -0,0 +1,14 @@ +{ + "name": "NewAssembly", + "rootNamespace": "", + "references": [], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": true, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/BouncyCastle.asmdef.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/BouncyCastle.asmdef.meta new file mode 100644 index 0000000..900afda --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/BouncyCastle.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: b3e39678a8864ed408212bd7910fd844 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/bzip2.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/bzip2.meta new file mode 100644 index 0000000..60d44ad --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/bzip2.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5ee9072fa49719a4ebfb7e4aa447e88d +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/bzip2/src.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/bzip2/src.meta new file mode 100644 index 0000000..3b5cc74 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/bzip2/src.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9d4e6d157b7496a4f9359ade573ff445 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/bzip2/src/BZip2Constants.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/bzip2/src/BZip2Constants.cs new file mode 100644 index 0000000..4a5442d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/bzip2/src/BZip2Constants.cs @@ -0,0 +1,103 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/* + * This package is based on the work done by Keiron Liddle, Aftex Software + * to whom the Ant project is very grateful for his + * great code. + */ + +using System; + +namespace Org.BouncyCastle.Apache.Bzip2 +{ + /** + * Base class for both the compress and decompress classes. + * Holds common arrays, and static data. + * + * @author Keiron Liddle + */ + public class BZip2Constants { + + public const int baseBlockSize = 100000; + public const int MAX_ALPHA_SIZE = 258; + public const int MAX_CODE_LEN = 23; + public const int RUNA = 0; + public const int RUNB = 1; + public const int N_GROUPS = 6; + public const int G_SIZE = 50; + public const int N_ITERS = 4; + public const int MAX_SELECTORS = (2 + (900000 / G_SIZE)); + public const int NUM_OVERSHOOT_BYTES = 20; + + public static readonly int[] rNums = { + 619, 720, 127, 481, 931, 816, 813, 233, 566, 247, + 985, 724, 205, 454, 863, 491, 741, 242, 949, 214, + 733, 859, 335, 708, 621, 574, 73, 654, 730, 472, + 419, 436, 278, 496, 867, 210, 399, 680, 480, 51, + 878, 465, 811, 169, 869, 675, 611, 697, 867, 561, + 862, 687, 507, 283, 482, 129, 807, 591, 733, 623, + 150, 238, 59, 379, 684, 877, 625, 169, 643, 105, + 170, 607, 520, 932, 727, 476, 693, 425, 174, 647, + 73, 122, 335, 530, 442, 853, 695, 249, 445, 515, + 909, 545, 703, 919, 874, 474, 882, 500, 594, 612, + 641, 801, 220, 162, 819, 984, 589, 513, 495, 799, + 161, 604, 958, 533, 221, 400, 386, 867, 600, 782, + 382, 596, 414, 171, 516, 375, 682, 485, 911, 276, + 98, 553, 163, 354, 666, 933, 424, 341, 533, 870, + 227, 730, 475, 186, 263, 647, 537, 686, 600, 224, + 469, 68, 770, 919, 190, 373, 294, 822, 808, 206, + 184, 943, 795, 384, 383, 461, 404, 758, 839, 887, + 715, 67, 618, 276, 204, 918, 873, 777, 604, 560, + 951, 160, 578, 722, 79, 804, 96, 409, 713, 940, + 652, 934, 970, 447, 318, 353, 859, 672, 112, 785, + 645, 863, 803, 350, 139, 93, 354, 99, 820, 908, + 609, 772, 154, 274, 580, 184, 79, 626, 630, 742, + 653, 282, 762, 623, 680, 81, 927, 626, 789, 125, + 411, 521, 938, 300, 821, 78, 343, 175, 128, 250, + 170, 774, 972, 275, 999, 639, 495, 78, 352, 126, + 857, 956, 358, 619, 580, 124, 737, 594, 701, 612, + 669, 112, 134, 694, 363, 992, 809, 743, 168, 974, + 944, 375, 748, 52, 600, 747, 642, 182, 862, 81, + 344, 805, 988, 739, 511, 655, 814, 334, 249, 515, + 897, 955, 664, 981, 649, 113, 974, 459, 893, 228, + 433, 837, 553, 268, 926, 240, 102, 654, 459, 51, + 686, 754, 806, 760, 493, 403, 415, 394, 687, 700, + 946, 670, 656, 610, 738, 392, 760, 799, 887, 653, + 978, 321, 576, 617, 626, 502, 894, 679, 243, 440, + 680, 879, 194, 572, 640, 724, 926, 56, 204, 700, + 707, 151, 457, 449, 797, 195, 791, 558, 945, 679, + 297, 59, 87, 824, 713, 663, 412, 693, 342, 606, + 134, 108, 571, 364, 631, 212, 174, 643, 304, 329, + 343, 97, 430, 751, 497, 314, 983, 374, 822, 928, + 140, 206, 73, 263, 980, 736, 876, 478, 430, 305, + 170, 514, 364, 692, 829, 82, 855, 953, 676, 246, + 369, 970, 294, 750, 807, 827, 150, 790, 288, 923, + 804, 378, 215, 828, 592, 281, 565, 555, 710, 82, + 896, 831, 547, 261, 524, 462, 293, 465, 502, 56, + 661, 821, 976, 991, 658, 869, 905, 758, 745, 193, + 768, 550, 608, 933, 378, 286, 215, 979, 792, 961, + 61, 688, 793, 644, 986, 403, 106, 366, 905, 644, + 372, 567, 466, 434, 645, 210, 389, 550, 919, 135, + 780, 773, 635, 389, 707, 100, 626, 958, 165, 504, + 920, 176, 193, 713, 857, 265, 203, 50, 668, 108, + 645, 990, 626, 197, 510, 357, 358, 850, 858, 364, + 936, 638 + }; + } +} \ No newline at end of file diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/bzip2/src/BZip2Constants.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/bzip2/src/BZip2Constants.cs.meta new file mode 100644 index 0000000..f04f607 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/bzip2/src/BZip2Constants.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b97ec50f1b20ac14580fbe34cb549c09 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/bzip2/src/CBZip2InputStream.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/bzip2/src/CBZip2InputStream.cs new file mode 100644 index 0000000..82f397d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/bzip2/src/CBZip2InputStream.cs @@ -0,0 +1,972 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/* + * This package is based on the work done by Keiron Liddle, Aftex Software + * to whom the Ant project is very grateful for his + * great code. + */ + +using System; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Apache.Bzip2 +{ + /** + * An input stream that decompresses from the BZip2 format (with the file + * header chars) to be read as any other stream. + * + * @author Keiron Liddle + * + * NB: note this class has been modified to read the leading BZ from the + * start of the BZIP2 stream to make it compatible with other PGP programs. + */ + public class CBZip2InputStream : Stream + { + private static void Cadvise() { + //System.out.Println("CRC Error"); + //throw new CCoruptionError(); + } + +// private static void BadBGLengths() { +// Cadvise(); +// } +// +// private static void BitStreamEOF() { +// Cadvise(); +// } + + private static void CompressedStreamEOF() { + Cadvise(); + } + + private void MakeMaps() + { + nInUse = 0; + for (int i = 0; i < 256; i++) + { + if (inUse[i]) + { + seqToUnseq[nInUse] = (char)i; + unseqToSeq[i] = (char)nInUse; + nInUse++; + } + } + } + + /* + index of the last char in the block, so + the block size == last + 1. + */ + private int last; + + /* + index in zptr[] of original string after sorting. + */ + private int origPtr; + + /* + always: in the range 0 .. 9. + The current block size is 100000 * this number. + */ + private int blockSize100k; + + private bool blockRandomised; + + private int bsBuff; + private int bsLive; + private CRC mCrc = new CRC(); + + private bool[] inUse = new bool[256]; + private int nInUse; + + private char[] seqToUnseq = new char[256]; + private char[] unseqToSeq = new char[256]; + + private char[] selector = new char[BZip2Constants.MAX_SELECTORS]; + private char[] selectorMtf = new char[BZip2Constants.MAX_SELECTORS]; + + private int[] tt; + private char[] ll8; + + /* + freq table collected to save a pass over the data + during decompression. + */ + private int[] unzftab = new int[256]; + + private int[][] limit = InitIntArray(BZip2Constants.N_GROUPS, BZip2Constants.MAX_ALPHA_SIZE); + private int[][] basev = InitIntArray(BZip2Constants.N_GROUPS, BZip2Constants.MAX_ALPHA_SIZE); + private int[][] perm = InitIntArray(BZip2Constants.N_GROUPS, BZip2Constants.MAX_ALPHA_SIZE); + private int[] minLens = new int[BZip2Constants.N_GROUPS]; + + private Stream bsStream; + + private bool streamEnd = false; + + private int currentChar = -1; + + private const int START_BLOCK_STATE = 1; + private const int RAND_PART_A_STATE = 2; + private const int RAND_PART_B_STATE = 3; + private const int RAND_PART_C_STATE = 4; + private const int NO_RAND_PART_A_STATE = 5; + private const int NO_RAND_PART_B_STATE = 6; + private const int NO_RAND_PART_C_STATE = 7; + + private int currentState = START_BLOCK_STATE; + + private int storedBlockCRC, storedCombinedCRC; + private int computedBlockCRC, computedCombinedCRC; + + int i2, count, chPrev, ch2; + int i, tPos; + int rNToGo = 0; + int rTPos = 0; + int j2; + char z; + + public CBZip2InputStream(Stream zStream) { + ll8 = null; + tt = null; + BsSetStream(zStream); + Initialize(); + InitBlock(); + SetupBlock(); + } + + internal static int[][] InitIntArray(int n1, int n2) + { + int[][] a = new int[n1][]; + for (int k = 0; k < n1; ++k) + { + a[k] = new int[n2]; + } + return a; + } + + internal static byte[][] InitByteArray(int n1, int n2) + { + byte[][] a = new byte[n1][]; + for (int k = 0; k < n1; ++k) + { + a[k] = new byte[n2]; + } + return a; + } + + public override int ReadByte() + { + if (streamEnd) + return -1; + + int retChar = currentChar; + switch (currentState) + { + case START_BLOCK_STATE: + break; + case RAND_PART_A_STATE: + break; + case RAND_PART_B_STATE: + SetupRandPartB(); + break; + case RAND_PART_C_STATE: + SetupRandPartC(); + break; + case NO_RAND_PART_A_STATE: + break; + case NO_RAND_PART_B_STATE: + SetupNoRandPartB(); + break; + case NO_RAND_PART_C_STATE: + SetupNoRandPartC(); + break; + default: + break; + } + return retChar; + } + + private void Initialize() { + char magic3, magic4; + magic3 = BsGetUChar(); + magic4 = BsGetUChar(); + if (magic3 != 'B' && magic4 != 'Z') + { + throw new IOException("Not a BZIP2 marked stream"); + } + magic3 = BsGetUChar(); + magic4 = BsGetUChar(); + if (magic3 != 'h' || magic4 < '1' || magic4 > '9') { + BsFinishedWithStream(); + streamEnd = true; + return; + } + + SetDecompressStructureSizes(magic4 - '0'); + computedCombinedCRC = 0; + } + + private void InitBlock() { + char magic1, magic2, magic3, magic4; + char magic5, magic6; + magic1 = BsGetUChar(); + magic2 = BsGetUChar(); + magic3 = BsGetUChar(); + magic4 = BsGetUChar(); + magic5 = BsGetUChar(); + magic6 = BsGetUChar(); + if (magic1 == 0x17 && magic2 == 0x72 && magic3 == 0x45 + && magic4 == 0x38 && magic5 == 0x50 && magic6 == 0x90) { + Complete(); + return; + } + + if (magic1 != 0x31 || magic2 != 0x41 || magic3 != 0x59 + || magic4 != 0x26 || magic5 != 0x53 || magic6 != 0x59) { + BadBlockHeader(); + streamEnd = true; + return; + } + + storedBlockCRC = BsGetInt32(); + + blockRandomised = BsR(1) == 1; + + GetAndMoveToFrontDecode(); + + mCrc.InitialiseCRC(); + currentState = START_BLOCK_STATE; + } + + private void EndBlock() + { + computedBlockCRC = mCrc.GetFinalCRC(); + /* A bad CRC is considered a fatal error. */ + if (storedBlockCRC != computedBlockCRC) + { + CrcError(); + } + + computedCombinedCRC = Integers.RotateLeft(computedCombinedCRC, 1) ^ computedBlockCRC; + } + + private void Complete() { + storedCombinedCRC = BsGetInt32(); + if (storedCombinedCRC != computedCombinedCRC) { + CrcError(); + } + + BsFinishedWithStream(); + streamEnd = true; + } + + private static void BlockOverrun() { + Cadvise(); + } + + private static void BadBlockHeader() { + Cadvise(); + } + + private static void CrcError() { + Cadvise(); + } + + private void BsFinishedWithStream() { + try { + if (this.bsStream != null) { + Platform.Dispose(this.bsStream); + this.bsStream = null; + } + } catch { + //ignore + } + } + + private void BsSetStream(Stream f) { + bsStream = f; + bsLive = 0; + bsBuff = 0; + } + + private int BsR(int n) { + int v; + while (bsLive < n) { + int zzi; + char thech = '\0'; + try { + thech = (char)bsStream.ReadByte(); + } catch (IOException) { + CompressedStreamEOF(); + } + if (thech == '\uffff') { + CompressedStreamEOF(); + } + zzi = thech; + bsBuff = (bsBuff << 8) | (zzi & 0xff); + bsLive += 8; + } + + v = (bsBuff >> (bsLive - n)) & ((1 << n) - 1); + bsLive -= n; + return v; + } + + private char BsGetUChar() + { + return (char)BsR(8); + } + + private int BsGetint() + { + //int u = 0; + //u = (u << 8) | BsR(8); + //u = (u << 8) | BsR(8); + //u = (u << 8) | BsR(8); + //u = (u << 8) | BsR(8); + //return u; + int u = BsR(16) << 16; + return u | BsR(16); + } + + private int BsGetIntVS(int numBits) + { + return BsR(numBits); + } + + private int BsGetInt32() + { + return BsGetint(); + } + + private void HbCreateDecodeTables(int[] limit, int[] basev, int[] perm, byte[] length, int minLen, int maxLen, + int alphaSize) + { + int i, j, vec; + + int pp = 0; + for (i = minLen; i <= maxLen; i++) { + for (j = 0; j < alphaSize; j++) { + if (length[j] == i) { + perm[pp] = j; + pp++; + } + } + } + + for (i = 0; i < BZip2Constants.MAX_CODE_LEN; i++) { + basev[i] = 0; + } + for (i = 0; i < alphaSize; i++) { + basev[length[i] + 1]++; + } + + for (i = 1; i < BZip2Constants.MAX_CODE_LEN; i++) { + basev[i] += basev[i - 1]; + } + + for (i = 0; i < BZip2Constants.MAX_CODE_LEN; i++) { + limit[i] = 0; + } + vec = 0; + + for (i = minLen; i <= maxLen; i++) { + vec += (basev[i + 1] - basev[i]); + limit[i] = vec - 1; + vec <<= 1; + } + for (i = minLen + 1; i <= maxLen; i++) { + basev[i] = ((limit[i - 1] + 1) << 1) - basev[i]; + } + } + + private void RecvDecodingTables() + { + byte[][] len = InitByteArray(BZip2Constants.N_GROUPS, BZip2Constants.MAX_ALPHA_SIZE); + int i, j, t, nGroups, nSelectors, alphaSize; + int minLen, maxLen; + bool[] inUse16 = new bool[16]; + + /* Receive the mapping table */ + for (i = 0; i < 16; i++) + { + inUse16[i] = BsR(1) == 1; + } + + for (i = 0; i < 16; i++) + { + int i16 = i * 16; + if (inUse16[i]) + { + for (j = 0; j < 16; j++) + { + inUse[i16 + j] = BsR(1) == 1; + } + } + else + { + for (j = 0; j < 16; j++) + { + inUse[i16 + j] = false; + } + } + } + + MakeMaps(); + alphaSize = nInUse + 2; + + /* Now the selectors */ + nGroups = BsR(3); + nSelectors = BsR(15); + for (i = 0; i < nSelectors; i++) { + j = 0; + while (BsR(1) == 1) { + j++; + } + selectorMtf[i] = (char)j; + } + + /* Undo the MTF values for the selectors. */ + { + char[] pos = new char[BZip2Constants.N_GROUPS]; + char tmp, v; + for (v = '\0'; v < nGroups; v++) { + pos[v] = v; + } + + for (i = 0; i < nSelectors; i++) { + v = selectorMtf[i]; + tmp = pos[v]; + while (v > 0) { + pos[v] = pos[v - 1]; + v--; + } + pos[0] = tmp; + selector[i] = tmp; + } + } + + /* Now the coding tables */ + for (t = 0; t < nGroups; t++) + { + byte[] len_t = len[t]; + int curr = BsR(5); + for (i = 0; i < alphaSize; i++) + { + while (BsR(1) == 1) + { + if (BsR(1) == 0) + { + curr++; + } + else + { + curr--; + } + } + len_t[i] = (byte)curr; + } + } + + /* Create the Huffman decoding tables */ + for (t = 0; t < nGroups; t++) + { + minLen = 32; + maxLen = 0; + byte[] len_t = len[t]; + for (i = 0; i < alphaSize; i++) + { + int lti = len_t[i]; + if (lti > maxLen) + { + maxLen = lti; + } + if (lti < minLen) + { + minLen = lti; + } + } + HbCreateDecodeTables(limit[t], basev[t], perm[t], len_t, minLen, maxLen, alphaSize); + minLens[t] = minLen; + } + } + + private void GetAndMoveToFrontDecode() + { + char[] yy = new char[256]; + int i, j, nextSym, limitLast; + int EOB, groupNo, groupPos; + + limitLast = BZip2Constants.baseBlockSize * blockSize100k; + origPtr = BsGetIntVS(24); + + RecvDecodingTables(); + EOB = nInUse + 1; + groupNo = -1; + groupPos = 0; + + /* + Setting up the unzftab entries here is not strictly + necessary, but it does save having to do it later + in a separate pass, and so saves a block's worth of + cache misses. + */ + for (i = 0; i <= 255; i++) + { + unzftab[i] = 0; + } + + for (i = 0; i <= 255; i++) + { + yy[i] = (char)i; + } + + last = -1; + + { + int zt, zn, zvec, zj; + if (groupPos == 0) + { + groupNo++; + groupPos = BZip2Constants.G_SIZE; + } + groupPos--; + zt = selector[groupNo]; + zn = minLens[zt]; + zvec = BsR(zn); + while (zvec > limit[zt][zn]) + { + zn++; + { + { + while (bsLive < 1) + { + int zzi; + char thech = '\0'; + try + { + thech = (char)bsStream.ReadByte(); + } + catch (IOException) + { + CompressedStreamEOF(); + } + if (thech == '\uffff') + { + CompressedStreamEOF(); + } + zzi = thech; + bsBuff = (bsBuff << 8) | (zzi & 0xff); + bsLive += 8; + } + } + zj = (bsBuff >> (bsLive - 1)) & 1; + bsLive--; + } + zvec = (zvec << 1) | zj; + } + nextSym = perm[zt][zvec - basev[zt][zn]]; + } + + while (nextSym != EOB) + { + if (nextSym == BZip2Constants.RUNA || nextSym == BZip2Constants.RUNB) + { + char ch; + int s = -1; + int N = 1; + do + { + if (nextSym == BZip2Constants.RUNA) + { + s += (0 + 1) * N; + } + else if (nextSym == BZip2Constants.RUNB) + { + s += (1 + 1) * N; + } + N = N * 2; + { + int zt, zn, zvec, zj; + if (groupPos == 0) + { + groupNo++; + groupPos = BZip2Constants.G_SIZE; + } + groupPos--; + zt = selector[groupNo]; + zn = minLens[zt]; + zvec = BsR(zn); + while (zvec > limit[zt][zn]) + { + zn++; + { + { + while (bsLive < 1) + { + int zzi; + char thech = '\0'; + try + { + thech = (char)bsStream.ReadByte(); + } + catch (IOException) + { + CompressedStreamEOF(); + } + if (thech == '\uffff') + { + CompressedStreamEOF(); + } + zzi = thech; + bsBuff = (bsBuff << 8) | (zzi & 0xff); + bsLive += 8; + } + } + zj = (bsBuff >> (bsLive - 1)) & 1; + bsLive--; + } + zvec = (zvec << 1) | zj; + } + nextSym = perm[zt][zvec - basev[zt][zn]]; + } + } + while (nextSym == BZip2Constants.RUNA || nextSym == BZip2Constants.RUNB); + + s++; + ch = seqToUnseq[yy[0]]; + unzftab[ch] += s; + + while (s > 0) + { + last++; + ll8[last] = ch; + s--; + } + + if (last >= limitLast) + { + BlockOverrun(); + } + continue; + } + else + { + if (++last >= limitLast) + { + BlockOverrun(); + } + + char tmp = yy[nextSym - 1]; + unzftab[seqToUnseq[tmp]]++; + ll8[last] = seqToUnseq[tmp]; + + /* + * This loop is hammered during decompression, hence avoid + * native method call overhead of Array.Copy for very + * small ranges to copy. + */ + if (nextSym <= 16) + { + for (j = nextSym - 1; j > 0; --j) + { + yy[j] = yy[j - 1]; + } + } + else + { + Array.Copy(yy, 0, yy, 1, nextSym - 1); + } + + yy[0] = tmp; + + { + int zt, zn, zvec, zj; + if (groupPos == 0) + { + groupNo++; + groupPos = BZip2Constants.G_SIZE; + } + groupPos--; + zt = selector[groupNo]; + zn = minLens[zt]; + zvec = BsR(zn); + while (zvec > limit[zt][zn]) + { + zn++; + { + { + while (bsLive < 1) + { + int zzi; + char thech = '\0'; + try + { + thech = (char)bsStream.ReadByte(); + } + catch (IOException) + { + CompressedStreamEOF(); + } + zzi = thech; + bsBuff = (bsBuff << 8) | (zzi & 0xff); + bsLive += 8; + } + } + zj = (bsBuff >> (bsLive - 1)) & 1; + bsLive--; + } + zvec = (zvec << 1) | zj; + } + nextSym = perm[zt][zvec - basev[zt][zn]]; + } + continue; + } + } + } + + private void SetupBlock() { + int[] cftab = new int[257]; + char ch; + + cftab[0] = 0; + for (i = 1; i <= 256; i++) { + cftab[i] = unzftab[i - 1]; + } + for (i = 1; i <= 256; i++) { + cftab[i] += cftab[i - 1]; + } + + for (i = 0; i <= last; i++) { + ch = ll8[i]; + tt[cftab[ch]] = i; + cftab[ch]++; + } + cftab = null; + + tPos = tt[origPtr]; + + count = 0; + i2 = 0; + ch2 = 256; /* not a char and not EOF */ + + if (blockRandomised) { + rNToGo = 0; + rTPos = 0; + SetupRandPartA(); + } else { + SetupNoRandPartA(); + } + } + + private void SetupRandPartA() { + if (i2 <= last) { + chPrev = ch2; + ch2 = ll8[tPos]; + tPos = tt[tPos]; + if (rNToGo == 0) { + rNToGo = BZip2Constants.rNums[rTPos]; + rTPos++; + if (rTPos == 512) { + rTPos = 0; + } + } + rNToGo--; + ch2 ^= (int) ((rNToGo == 1) ? 1 : 0); + i2++; + + currentChar = ch2; + currentState = RAND_PART_B_STATE; + mCrc.UpdateCRC(ch2); + } else { + EndBlock(); + InitBlock(); + SetupBlock(); + } + } + + private void SetupNoRandPartA() { + if (i2 <= last) { + chPrev = ch2; + ch2 = ll8[tPos]; + tPos = tt[tPos]; + i2++; + + currentChar = ch2; + currentState = NO_RAND_PART_B_STATE; + mCrc.UpdateCRC(ch2); + } else { + EndBlock(); + InitBlock(); + SetupBlock(); + } + } + + private void SetupRandPartB() { + if (ch2 != chPrev) { + currentState = RAND_PART_A_STATE; + count = 1; + SetupRandPartA(); + } else { + count++; + if (count >= 4) { + z = ll8[tPos]; + tPos = tt[tPos]; + if (rNToGo == 0) { + rNToGo = BZip2Constants.rNums[rTPos]; + rTPos++; + if (rTPos == 512) { + rTPos = 0; + } + } + rNToGo--; + z ^= (char)((rNToGo == 1) ? 1 : 0); + j2 = 0; + currentState = RAND_PART_C_STATE; + SetupRandPartC(); + } else { + currentState = RAND_PART_A_STATE; + SetupRandPartA(); + } + } + } + + private void SetupRandPartC() { + if (j2 < (int) z) { + currentChar = ch2; + mCrc.UpdateCRC(ch2); + j2++; + } else { + currentState = RAND_PART_A_STATE; + i2++; + count = 0; + SetupRandPartA(); + } + } + + private void SetupNoRandPartB() { + if (ch2 != chPrev) { + currentState = NO_RAND_PART_A_STATE; + count = 1; + SetupNoRandPartA(); + } else { + count++; + if (count >= 4) { + z = ll8[tPos]; + tPos = tt[tPos]; + currentState = NO_RAND_PART_C_STATE; + j2 = 0; + SetupNoRandPartC(); + } else { + currentState = NO_RAND_PART_A_STATE; + SetupNoRandPartA(); + } + } + } + + private void SetupNoRandPartC() { + if (j2 < (int) z) { + currentChar = ch2; + mCrc.UpdateCRC(ch2); + j2++; + } else { + currentState = NO_RAND_PART_A_STATE; + i2++; + count = 0; + SetupNoRandPartA(); + } + } + + private void SetDecompressStructureSizes(int newSize100k) { + if (!(0 <= newSize100k && newSize100k <= 9 && 0 <= blockSize100k + && blockSize100k <= 9)) { + // throw new IOException("Invalid block size"); + } + + blockSize100k = newSize100k; + + if (newSize100k == 0) { + return; + } + + int n = BZip2Constants.baseBlockSize * newSize100k; + ll8 = new char[n]; + tt = new int[n]; + } + + public override void Flush() { + } + + public override int Read(byte[] buffer, int offset, int count) { + int c = -1; + int k; + for (k = 0; k < count; ++k) { + c = ReadByte(); + if (c == -1) + break; + buffer[k + offset] = (byte)c; + } + return k; + } + + public override long Seek(long offset, SeekOrigin origin) { + return 0; + } + + public override void SetLength(long value) { + } + + public override void Write(byte[] buffer, int offset, int count) { + } + + public override bool CanRead { + get { + return true; + } + } + + public override bool CanSeek { + get { + return false; + } + } + + public override bool CanWrite { + get { + return false; + } + } + + public override long Length { + get { + return 0; + } + } + + public override long Position { + get { + return 0; + } + set { + } + } + } +} \ No newline at end of file diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/bzip2/src/CBZip2InputStream.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/bzip2/src/CBZip2InputStream.cs.meta new file mode 100644 index 0000000..2a75383 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/bzip2/src/CBZip2InputStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cf8f6f74bd44c2944bb94a45316effb4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/bzip2/src/CBZip2OutputStream.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/bzip2/src/CBZip2OutputStream.cs new file mode 100644 index 0000000..e81f6ff --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/bzip2/src/CBZip2OutputStream.cs @@ -0,0 +1,1746 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/* + * This package is based on the work done by Keiron Liddle, Aftex Software + * to whom the Ant project is very grateful for his + * great code. + */ + +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Apache.Bzip2 +{ + /** + * An output stream that compresses into the BZip2 format (with the file + * header chars) into another stream. + * + * @author Keiron Liddle + * + * TODO: Update to BZip2 1.0.1 + * NB: note this class has been modified to add a leading BZ to the + * start of the BZIP2 stream to make it compatible with other PGP programs. + */ + public class CBZip2OutputStream : Stream + { + protected const int SETMASK = 1 << 21; + protected const int CLEARMASK = ~SETMASK; + protected const int GREATER_ICOST = 15; + protected const int LESSER_ICOST = 0; + protected const int SMALL_THRESH = 20; + protected const int DEPTH_THRESH = 10; + + private bool finished; + + private static void Panic() + { + throw new InvalidOperationException(); + } + + private void MakeMaps() + { + int i; + nInUse = 0; + for (i = 0; i < 256; i++) + { + if (inUse[i]) + { + seqToUnseq[nInUse] = (char) i; + unseqToSeq[i] = (char) nInUse; + nInUse++; + } + } + } + + protected static void HbMakeCodeLengths(byte[] len, int[] freq, int alphaSize, int maxLen) + { + /* + Nodes and heap entries run from 1. Entry 0 + for both the heap and nodes is a sentinel. + */ + int[] heap = new int[BZip2Constants.MAX_ALPHA_SIZE + 2]; + int[] weight = new int[BZip2Constants.MAX_ALPHA_SIZE * 2]; + int[] parent = new int[BZip2Constants.MAX_ALPHA_SIZE * 2]; + + for (int i = 0; i < alphaSize; i++) + { + weight[i + 1] = (freq[i] == 0 ? 1 : freq[i]) << 8; + } + + while (true) + { + int nNodes = alphaSize; + int nHeap = 0; + + heap[0] = 0; + weight[0] = 0; + parent[0] = -2; + + for (int i = 1; i <= alphaSize; i++) + { + parent[i] = -1; + heap[++nHeap] = i; + { + int zz = nHeap; + int tmp = heap[zz]; + while (weight[tmp] < weight[heap[zz >> 1]]) + { + heap[zz] = heap[zz >> 1]; + zz >>= 1; + } + heap[zz] = tmp; + } + } + if (!(nHeap < (BZip2Constants.MAX_ALPHA_SIZE + 2))) + { + Panic(); + } + + while (nHeap > 1) + { + int n1 = heap[1]; + heap[1] = heap[nHeap--]; + { + int zz = 1; + int tmp = heap[zz]; + while (true) { + int yy = zz << 1; + if (yy > nHeap) + break; + + if (yy < nHeap + && weight[heap[yy + 1]] < weight[heap[yy]]) + { + yy++; + } + + if (weight[tmp] < weight[heap[yy]]) + break; + + heap[zz] = heap[yy]; + zz = yy; + } + heap[zz] = tmp; + } + int n2 = heap[1]; + heap[1] = heap[nHeap--]; + { + int zz = 1; + int tmp = heap[zz]; + while (true) + { + int yy = zz << 1; + if (yy > nHeap) + break; + + if (yy < nHeap + && weight[heap[yy + 1]] < weight[heap[yy]]) + { + yy++; + } + + if (weight[tmp] < weight[heap[yy]]) + break; + + heap[zz] = heap[yy]; + zz = yy; + } + heap[zz] = tmp; + } + nNodes++; + parent[n1] = parent[n2] = nNodes; + + weight[nNodes] = (int)((uint)((weight[n1] & 0xffffff00) + + (weight[n2] & 0xffffff00)) + | (uint)(1 + (((weight[n1] & 0x000000ff) > + (weight[n2] & 0x000000ff)) ? + (weight[n1] & 0x000000ff) : + (weight[n2] & 0x000000ff)))); + + parent[nNodes] = -1; + heap[++nHeap] = nNodes; + { + int zz = nHeap; + int tmp = heap[zz]; + while (weight[tmp] < weight[heap[zz >> 1]]) + { + heap[zz] = heap[zz >> 1]; + zz >>= 1; + } + heap[zz] = tmp; + } + } + if (!(nNodes < (BZip2Constants.MAX_ALPHA_SIZE * 2))) + { + Panic(); + } + + bool tooLong = false; + for (int i = 1; i <= alphaSize; i++) + { + int j = 0; + int k = i; + while (parent[k] >= 0) + { + k = parent[k]; + j++; + } + len[i - 1] = (byte)j; + if (j > maxLen) + { + tooLong = true; + } + } + + if (!tooLong) + break; + + for (int i = 1; i < alphaSize; i++) + { + int j = weight[i] >> 8; + j = 1 + (j / 2); + weight[i] = j << 8; + } + } + } + + /* + * number of characters in the block + */ + int count; + + /* + index in zptr[] of original string after sorting. + */ + int origPtr; + + /* + always: in the range 0 .. 9. + The current block size is 100000 * this number. + */ + readonly int blockSize100k; + + private int allowableBlockSize; + + bool blockRandomised; + + int bsBuff; + int bsLive; + readonly CRC mCrc = new CRC(); + + private bool[] inUse = new bool[256]; + private int nInUse; + + private char[] seqToUnseq = new char[256]; + private char[] unseqToSeq = new char[256]; + + private char[] selector = new char[BZip2Constants.MAX_SELECTORS]; + private char[] selectorMtf = new char[BZip2Constants.MAX_SELECTORS]; + + private byte[] blockBytes; + private ushort[] quadrantShorts; + private int[] zptr; + private int[] szptr; + private int[] ftab; + + private int nMTF; + + private int[] mtfFreq = new int[BZip2Constants.MAX_ALPHA_SIZE]; + + /* + * Used when sorting. If too many long comparisons + * happen, we stop sorting, randomise the block + * slightly, and try again. + */ + private int workFactor; + private int workDone; + private int workLimit; + private bool firstAttempt; + + private int currentByte = -1; + private int runLength = 0; + + public CBZip2OutputStream(Stream outStream) + : this(outStream, 9) + { + } + + public CBZip2OutputStream(Stream outStream, int blockSize) + { + blockBytes = null; + quadrantShorts = null; + zptr = null; + ftab = null; + + outStream.WriteByte((byte)'B'); + outStream.WriteByte((byte)'Z'); + + BsSetStream(outStream); + + workFactor = 50; + if (blockSize > 9) { + blockSize = 9; + } + if (blockSize < 1) { + blockSize = 1; + } + blockSize100k = blockSize; + AllocateCompressStructures(); + Initialize(); + InitBlock(); + } + + /** + * + * modified by Oliver Merkel, 010128 + * + */ + public override void WriteByte(byte b) + { + if (currentByte == b) + { + runLength++; + if (runLength > 254) + { + WriteRun(); + currentByte = -1; + runLength = 0; + } + } + else if (currentByte == -1) + { + currentByte = b; + runLength++; + } + else + { + WriteRun(); + runLength = 1; + currentByte = b; + } + } + + private void WriteRun() + { + if (count > allowableBlockSize) + { + EndBlock(); + InitBlock(); + } + + inUse[currentByte] = true; + + for (int i = 0; i < runLength; i++) + { + mCrc.UpdateCRC(currentByte); + } + + switch (runLength) + { + case 1: + blockBytes[++count] = (byte)currentByte; + break; + case 2: + blockBytes[++count] = (byte)currentByte; + blockBytes[++count] = (byte)currentByte; + break; + case 3: + blockBytes[++count] = (byte)currentByte; + blockBytes[++count] = (byte)currentByte; + blockBytes[++count] = (byte)currentByte; + break; + default: + inUse[runLength - 4] = true; + blockBytes[++count] = (byte)currentByte; + blockBytes[++count] = (byte)currentByte; + blockBytes[++count] = (byte)currentByte; + blockBytes[++count] = (byte)currentByte; + blockBytes[++count] = (byte)(runLength - 4); + break; + } + } + + bool closed = false; + +// protected void Finalize() { +// Close(); +// } + +#if PORTABLE + protected override void Dispose(bool disposing) + { + if (disposing) + { + if (closed) + return; + + Finish(); + closed = true; + Platform.Dispose(this.bsStream); + } + base.Dispose(disposing); + } +#else + public override void Close() + { + if (closed) + return; + + Finish(); + + closed = true; + Platform.Dispose(this.bsStream); + + base.Close(); + } +#endif + + public void Finish() + { + if (finished) + return; + + if (runLength > 0) + { + WriteRun(); + } + currentByte = -1; + if (count > 0) + { + EndBlock(); + } + EndCompression(); + finished = true; + Flush(); + } + + public override void Flush() + { + bsStream.Flush(); + } + + private int blockCRC, combinedCRC; + + private void Initialize() + { + /* Write `magic' bytes h indicating file-format == huffmanised, + followed by a digit indicating blockSize100k. + */ + BsPutUChar('h'); + BsPutUChar('0' + blockSize100k); + + combinedCRC = 0; + } + + private void InitBlock() + { + mCrc.InitialiseCRC(); + count = 0; + + for (int i = 0; i < 256; i++) + { + inUse[i] = false; + } + + /* 20 is just a paranoia constant */ + allowableBlockSize = BZip2Constants.baseBlockSize * blockSize100k - 20; + } + + private void EndBlock() + { + blockCRC = mCrc.GetFinalCRC(); + combinedCRC = Integers.RotateLeft(combinedCRC, 1) ^ blockCRC; + + /* sort the block and establish posn of original string */ + DoReversibleTransformation(); + + /* + A 6-byte block header, the value chosen arbitrarily + as 0x314159265359 :-). A 32 bit value does not really + give a strong enough guarantee that the value will not + appear by chance in the compressed datastream. Worst-case + probability of this event, for a 900k block, is about + 2.0e-3 for 32 bits, 1.0e-5 for 40 bits and 4.0e-8 for 48 bits. + For a compressed file of size 100Gb -- about 100000 blocks -- + only a 48-bit marker will do. NB: normal compression/ + decompression do *not* rely on these statistical properties. + They are only important when trying to recover blocks from + damaged files. + */ + BsPutUChar(0x31); + BsPutUChar(0x41); + BsPutUChar(0x59); + BsPutUChar(0x26); + BsPutUChar(0x53); + BsPutUChar(0x59); + + /* Now the block's CRC, so it is in a known place. */ + BsPutint(blockCRC); + + /* Now a single bit indicating randomisation. */ + BsW(1, blockRandomised ? 1 : 0); + + /* Finally, block's contents proper. */ + MoveToFrontCodeAndSend(); + } + + private void EndCompression() { + /* + Now another magic 48-bit number, 0x177245385090, to + indicate the end of the last block. (Sqrt(pi), if + you want to know. I did want to use e, but it contains + too much repetition -- 27 18 28 18 28 46 -- for me + to feel statistically comfortable. Call me paranoid.) + */ + BsPutUChar(0x17); + BsPutUChar(0x72); + BsPutUChar(0x45); + BsPutUChar(0x38); + BsPutUChar(0x50); + BsPutUChar(0x90); + + BsPutint(combinedCRC); + + BsFinishedWithStream(); + } + + private void HbAssignCodes(int[] code, byte[] length, int minLen, int maxLen, int alphaSize) + { + int vec = 0; + for (int n = minLen; n <= maxLen; n++) + { + for (int i = 0; i < alphaSize; i++) + { + if (length[i] == n) + { + code[i] = vec; + vec++; + } + } + vec <<= 1; + } + } + + private void BsSetStream(Stream f) + { + bsStream = f; + bsLive = 0; + bsBuff = 0; + } + + private void BsFinishedWithStream() + { + while (bsLive > 0) + { + bsStream.WriteByte((byte)(bsBuff >> 24)); // write 8-bit + bsBuff <<= 8; + bsLive -= 8; + } + } + + private void BsW(int n, int v) + { + while (bsLive >= 8) + { + bsStream.WriteByte((byte)(bsBuff >> 24)); // write 8-bit + bsBuff <<= 8; + bsLive -= 8; + } + bsBuff |= v << (32 - bsLive - n); + bsLive += n; + } + + private void BsPutUChar(int c) + { + BsW(8, c); + } + + private void BsPutint(int u) + { + //BsW(8, (u >> 24) & 0xff); + //BsW(8, (u >> 16) & 0xff); + //BsW(8, (u >> 8) & 0xff); + //BsW(8, u & 0xff); + BsW(16, (u >> 16) & 0xFFFF); + BsW(16, u & 0xFFFF); + } + + private void BsPutIntVS(int numBits, int c) + { + BsW(numBits, c); + } + + private void SendMTFValues() + { + byte[][] len = CBZip2InputStream.InitByteArray(BZip2Constants.N_GROUPS, BZip2Constants.MAX_ALPHA_SIZE); + + int v, t, i, j, gs, ge, bt, bc, iter; + int nSelectors = 0, alphaSize, minLen, maxLen, selCtr; + int nGroups; + + alphaSize = nInUse + 2; + for (t = 0; t < BZip2Constants.N_GROUPS; t++) + { + byte[] len_t = len[t]; + for (v = 0; v < alphaSize; v++) + { + len_t[v] = GREATER_ICOST; + } + } + + /* Decide how many coding tables to use */ + if (nMTF <= 0) + { + Panic(); + } + + if (nMTF < 200) + { + nGroups = 2; + } + else if (nMTF < 600) + { + nGroups = 3; + } + else if (nMTF < 1200) + { + nGroups = 4; + } + else if (nMTF < 2400) + { + nGroups = 5; + } + else + { + nGroups = 6; + } + + /* Generate an initial set of coding tables */ + { + int tFreq, aFreq; + + int nPart = nGroups; + int remF = nMTF; + gs = 0; + while (nPart > 0) + { + tFreq = remF / nPart; + ge = gs - 1; + aFreq = 0; + while (aFreq < tFreq && ge < alphaSize - 1) + { + aFreq += mtfFreq[++ge]; + } + + if (ge > gs && nPart != nGroups && nPart != 1 + && ((nGroups - nPart) % 2 == 1)) + { + aFreq -= mtfFreq[ge--]; + } + + byte[] len_np = len[nPart - 1]; + for (v = 0; v < alphaSize; v++) + { + if (v >= gs && v <= ge) + { + len_np[v] = LESSER_ICOST; + } + else + { + len_np[v] = GREATER_ICOST; + } + } + + nPart--; + gs = ge + 1; + remF -= aFreq; + } + } + + int[][] rfreq = CBZip2InputStream.InitIntArray(BZip2Constants.N_GROUPS, BZip2Constants.MAX_ALPHA_SIZE); + int[] fave = new int[BZip2Constants.N_GROUPS]; + short[] cost = new short[BZip2Constants.N_GROUPS]; + byte[] len_0 = len[0]; + byte[] len_1 = len[1]; + byte[] len_2 = len[2]; + byte[] len_3 = len[3]; + byte[] len_4 = len[4]; + byte[] len_5 = len[5]; + + /* + Iterate up to N_ITERS times to improve the tables. + */ + for (iter = 0; iter < BZip2Constants.N_ITERS; iter++) + { + for (t = 0; t < nGroups; t++) + { + fave[t] = 0; + + int[] rfreq_t = rfreq[t]; + for (v = 0; v < alphaSize; v++) + { + rfreq_t[v] = 0; + } + } + + nSelectors = 0; + gs = 0; + while (gs < nMTF) + { + /* Set group start & end marks. */ + + /* + * Calculate the cost of this group as coded by each of the coding tables. + */ + + ge = System.Math.Min(gs + BZip2Constants.G_SIZE - 1, nMTF - 1); + + if (nGroups == 6) + { + short cost0 = 0, cost1 = 0, cost2 = 0, cost3 = 0, cost4 = 0, cost5 = 0; + + for (i = gs; i <= ge; i++) + { + int icv = szptr[i]; + cost0 += len_0[icv]; + cost1 += len_1[icv]; + cost2 += len_2[icv]; + cost3 += len_3[icv]; + cost4 += len_4[icv]; + cost5 += len_5[icv]; + } + + cost[0] = cost0; + cost[1] = cost1; + cost[2] = cost2; + cost[3] = cost3; + cost[4] = cost4; + cost[5] = cost5; + } + else + { + for (t = 0; t < nGroups; t++) + { + cost[t] = 0; + } + + for (i = gs; i <= ge; i++) + { + int icv = szptr[i]; + for (t = 0; t < nGroups; t++) + { + cost[t] += len[t][icv]; + } + } + } + + /* + Find the coding table which is best for this group, + and record its identity in the selector table. + */ + bc = 999999999; + bt = -1; + for (t = 0; t < nGroups; t++) + { + if (cost[t] < bc) + { + bc = cost[t]; + bt = t; + } + } + fave[bt]++; + selector[nSelectors] = (char) bt; + nSelectors++; + + /* + Increment the symbol frequencies for the selected table. + */ + int[] rfreq_bt = rfreq[bt]; + for (i = gs; i <= ge; i++) + { + rfreq_bt[szptr[i]]++; + } + + gs = ge + 1; + } + + /* + Recompute the tables based on the accumulated frequencies. + */ + for (t = 0; t < nGroups; t++) + { + HbMakeCodeLengths(len[t], rfreq[t], alphaSize, 20); + } + } + + rfreq = null; + fave = null; + cost = null; + + if (!(nGroups < 8)) + { + Panic(); + } + if (!(nSelectors < 32768 && nSelectors <= (2 + (900000 / BZip2Constants.G_SIZE)))) + { + Panic(); + } + + /* Compute MTF values for the selectors. */ + { + char[] pos = new char[BZip2Constants.N_GROUPS]; + char ll_i, tmp2, tmp; + for (i = 0; i < nGroups; i++) + { + pos[i] = (char)i; + } + for (i = 0; i < nSelectors; i++) + { + ll_i = selector[i]; + j = 0; + tmp = pos[j]; + while (ll_i != tmp) + { + j++; + tmp2 = tmp; + tmp = pos[j]; + pos[j] = tmp2; + } + pos[0] = tmp; + selectorMtf[i] = (char)j; + } + } + + int[][] code = CBZip2InputStream.InitIntArray(BZip2Constants.N_GROUPS, BZip2Constants.MAX_ALPHA_SIZE); + + /* Assign actual codes for the tables. */ + for (t = 0; t < nGroups; t++) + { + minLen = 32; + maxLen = 0; + byte[] len_t = len[t]; + for (i = 0; i < alphaSize; i++) + { + int lti = len_t[i]; + if (lti > maxLen) + { + maxLen = lti; + } + if (lti < minLen) + { + minLen = lti; + } + } + if (maxLen > 20) + { + Panic(); + } + if (minLen < 1) + { + Panic(); + } + HbAssignCodes(code[t], len[t], minLen, maxLen, alphaSize); + } + + /* Transmit the mapping table. */ + { + bool[] inUse16 = new bool[16]; + for (i = 0; i < 16; i++) + { + inUse16[i] = false; + int i16 = i * 16; + for (j = 0; j < 16; j++) + { + if (inUse[i16 + j]) + { + inUse16[i] = true; + break; + } + } + } + + for (i = 0; i < 16; i++) + { + BsW(1, inUse16[i] ? 1 : 0); + } + + for (i = 0; i < 16; i++) + { + if (inUse16[i]) + { + int i16 = i * 16; + for (j = 0; j < 16; j++) + { + BsW(1, inUse[i16 + j] ? 1 : 0); + } + } + } + } + + /* Now the selectors. */ + BsW(3, nGroups); + BsW(15, nSelectors); + for (i = 0; i < nSelectors; i++) + { + int count = selectorMtf[i]; + //for (j = 0; j < count; j++) + //{ + // BsW(1, 1); + //} + //BsW(1, 0); + while (count >= 24) + { + BsW(24, 0xFFFFFF); + count -= 24; + } + BsW(count + 1, (1 << (count + 1)) - 2); + } + + /* Now the coding tables. */ + for (t = 0; t < nGroups; t++) + { + byte[] len_t = len[t]; + int curr = len_t[0]; + BsW(5, curr); + for (i = 0; i < alphaSize; i++) + { + int lti = len_t[i]; + while (curr < lti) + { + BsW(2, 2); + curr++; /* 10 */ + } + while (curr > lti) + { + BsW(2, 3); + curr--; /* 11 */ + } + BsW(1, 0); + } + } + + /* And finally, the block data proper */ + selCtr = 0; + gs = 0; + while (gs < nMTF) + { + ge = System.Math.Min(gs + BZip2Constants.G_SIZE - 1, nMTF - 1); + + int selector_selCtr = selector[selCtr]; + byte[] len_selCtr = len[selector_selCtr]; + int[] code_selCtr = code[selector_selCtr]; + + for (i = gs; i <= ge; i++) + { + int sfmap_i = szptr[i]; + BsW(len_selCtr[sfmap_i], code_selCtr[sfmap_i]); + } + + gs = ge + 1; + selCtr++; + } + if (!(selCtr == nSelectors)) + { + Panic(); + } + } + + private void MoveToFrontCodeAndSend() + { + BsPutIntVS(24, origPtr); + GenerateMTFValues(); + SendMTFValues(); + } + + private Stream bsStream; + + private void SimpleSort(int lo, int hi, int d) + { + int i, j, h, v; + + int bigN = hi - lo + 1; + if (bigN < 2) + return; + + int hp = 0; + while (incs[hp] < bigN) + { + hp++; + } + hp--; + + for (; hp >= 0; hp--) + { + h = incs[hp]; + + i = lo + h; + while (i <= hi) + { + /* copy 1 */ + v = zptr[i]; + j = i; + while (FullGtU(zptr[j - h] + d, v + d)) + { + zptr[j] = zptr[j - h]; + j = j - h; + if (j <= (lo + h - 1)) + break; + } + zptr[j] = v; + + /* copy 2 */ + if (++i > hi) + break; + + v = zptr[i]; + j = i; + while (FullGtU(zptr[j - h] + d, v + d)) + { + zptr[j] = zptr[j - h]; + j = j - h; + if (j <= (lo + h - 1)) + break; + } + zptr[j] = v; + + /* copy 3 */ + if (++i > hi) + break; + + v = zptr[i]; + j = i; + while (FullGtU(zptr[j - h] + d, v + d)) + { + zptr[j] = zptr[j - h]; + j = j - h; + if (j <= (lo + h - 1)) + break; + } + zptr[j] = v; + i++; + + if (workDone > workLimit && firstAttempt) + return; + } + } + } + + private void Vswap(int p1, int p2, int n) + { + while (--n >= 0) + { + int t1 = zptr[p1], t2 = zptr[p2]; + zptr[p1++] = t2; + zptr[p2++] = t1; + } + } + + private int Med3(int a, int b, int c) + { + return a > b + ? (c < b ? b : c > a ? a : c) + : (c < a ? a : c > b ? b : c); + } + + internal class StackElem + { + internal int ll; + internal int hh; + internal int dd; + } + + private static void PushStackElem(IList stack, int stackCount, int ll, int hh, int dd) + { + StackElem stackElem; + if (stackCount < stack.Count) + { + stackElem = (StackElem)stack[stackCount]; + } + else + { + stackElem = new StackElem(); + stack.Add(stackElem); + } + + stackElem.ll = ll; + stackElem.hh = hh; + stackElem.dd = dd; + } + + private void QSort3(int loSt, int hiSt, int dSt) + { + int unLo, unHi, ltLo, gtHi, n, m; + + IList stack = Platform.CreateArrayList(); + int stackCount = 0; + StackElem stackElem; + + int lo = loSt; + int hi = hiSt; + int d = dSt; + + for (;;) + { + if (hi - lo < SMALL_THRESH || d > DEPTH_THRESH) + { + SimpleSort(lo, hi, d); + if (stackCount < 1 || (workDone > workLimit && firstAttempt)) + return; + + stackElem = (StackElem)stack[--stackCount]; + lo = stackElem.ll; + hi = stackElem.hh; + d = stackElem.dd; + continue; + } + + int d1 = d + 1; + int med = Med3( + blockBytes[zptr[lo] + d1], + blockBytes[zptr[hi] + d1], + blockBytes[zptr[(lo + hi) >> 1] + d1]); + + unLo = ltLo = lo; + unHi = gtHi = hi; + + while (true) + { + while (unLo <= unHi) + { + int zUnLo = zptr[unLo]; + n = blockBytes[zUnLo + d1] - med; + if (n > 0) + break; + + if (n == 0) + { + zptr[unLo] = zptr[ltLo]; + zptr[ltLo++] = zUnLo; + } + unLo++; + } + while (unLo <= unHi) + { + int zUnHi = zptr[unHi]; + n = blockBytes[zUnHi + d1] - med; + if (n < 0) + break; + + if (n == 0) + { + zptr[unHi] = zptr[gtHi]; + zptr[gtHi--] = zUnHi; + } + unHi--; + } + if (unLo > unHi) + break; + + int temp = zptr[unLo]; + zptr[unLo++] = zptr[unHi]; + zptr[unHi--] = temp; + } + + if (gtHi < ltLo) + { + d = d1; + continue; + } + + n = System.Math.Min(ltLo - lo, unLo - ltLo); + Vswap(lo, unLo - n, n); + + m = System.Math.Min(hi - gtHi, gtHi - unHi); + Vswap(unLo, hi - m + 1, m); + + n = lo + (unLo - ltLo); + m = hi - (gtHi - unHi); + + PushStackElem(stack, stackCount++, lo, n - 1, d); + PushStackElem(stack, stackCount++, n, m, d1); + + lo = m + 1; + } + } + + private void MainSort() + { + int i, j, ss, sb; + int[] runningOrder = new int[256]; + int[] copy = new int[256]; + bool[] bigDone = new bool[256]; + int c1, c2; + + /* + In the various block-sized structures, live data runs + from 0 to last+NUM_OVERSHOOT_BYTES inclusive. First, + set up the overshoot area for block. + */ + for (i = 0; i < BZip2Constants.NUM_OVERSHOOT_BYTES; i++) + { + blockBytes[count + i + 1] = blockBytes[(i % count) + 1]; + } + for (i = 0; i <= count + BZip2Constants.NUM_OVERSHOOT_BYTES; i++) + { + quadrantShorts[i] = 0; + } + + blockBytes[0] = blockBytes[count]; + + if (count <= 4000) + { + /* + Use SimpleSort(), since the full sorting mechanism + has quite a large constant overhead. + */ + for (i = 0; i < count; i++) + { + zptr[i] = i; + } + firstAttempt = false; + workDone = workLimit = 0; + SimpleSort(0, count - 1, 0); + } + else + { + for (i = 0; i <= 255; i++) + { + bigDone[i] = false; + } + + for (i = 0; i <= 65536; i++) + { + ftab[i] = 0; + } + + c1 = blockBytes[0]; + for (i = 1; i <= count; i++) + { + c2 = blockBytes[i]; + ftab[(c1 << 8) + c2]++; + c1 = c2; + } + + for (i = 0; i < 65536; i++) + { + ftab[i + 1] += ftab[i]; + } + + c1 = blockBytes[1]; + for (i = 0; i < (count - 1); i++) + { + c2 = blockBytes[i + 2]; + j = (c1 << 8) + c2; + c1 = c2; + ftab[j]--; + zptr[ftab[j]] = i; + } + + j = ((int)blockBytes[count] << 8) + blockBytes[1]; + ftab[j]--; + zptr[ftab[j]] = count - 1; + + /* + Now ftab contains the first loc of every small bucket. + Calculate the running order, from smallest to largest + big bucket. + */ + + for (i = 0; i <= 255; i++) + { + runningOrder[i] = i; + } + + { + int h = 1; + do + { + h = 3 * h + 1; + } + while (h <= 256); + do + { + h = h / 3; + for (i = h; i <= 255; i++) + { + int vv = runningOrder[i]; + j = i; + while ((ftab[(runningOrder[j - h] + 1) << 8] - ftab[runningOrder[j - h] << 8]) + > (ftab[(vv + 1) << 8] - ftab[vv << 8])) + { + runningOrder[j] = runningOrder[j - h]; + j = j - h; + if (j < h) + break; + } + runningOrder[j] = vv; + } + } + while (h != 1); + } + + /* + The main sorting loop. + */ + for (i = 0; i <= 255; i++) + { + /* + Process big buckets, starting with the least full. + */ + ss = runningOrder[i]; + + /* + Complete the big bucket [ss] by quicksorting + any unsorted small buckets [ss, j]. Hopefully + previous pointer-scanning phases have already + completed many of the small buckets [ss, j], so + we don't have to sort them at all. + */ + for (j = 0; j <= 255; j++) + { + sb = (ss << 8) + j; + if ((ftab[sb] & SETMASK) != SETMASK) + { + int lo = ftab[sb] & CLEARMASK; + int hi = (ftab[sb + 1] & CLEARMASK) - 1; + if (hi > lo) + { + QSort3(lo, hi, 2); + if (workDone > workLimit && firstAttempt) + return; + } + ftab[sb] |= SETMASK; + } + } + + /* + The ss big bucket is now done. Record this fact, + and update the quadrant descriptors. Remember to + update quadrants in the overshoot area too, if + necessary. The "if (i < 255)" test merely skips + this updating for the last bucket processed, since + updating for the last bucket is pointless. + */ + bigDone[ss] = true; + + if (i < 255) + { + int bbStart = ftab[ss << 8] & CLEARMASK; + int bbSize = (ftab[(ss + 1) << 8] & CLEARMASK) - bbStart; + + int shifts = 0; + while ((bbSize >> shifts) > 65534) + { + shifts++; + } + + for (j = 0; j < bbSize; j++) + { + int a2update = zptr[bbStart + j] + 1; + ushort qVal = (ushort)(j >> shifts); + quadrantShorts[a2update] = qVal; + if (a2update <= BZip2Constants.NUM_OVERSHOOT_BYTES) + { + quadrantShorts[a2update + count] = qVal; + } + } + + if (!(((bbSize - 1) >> shifts) <= 65535)) + { + Panic(); + } + } + + /* + Now scan this big bucket so as to synthesise the + sorted order for small buckets [t, ss] for all t != ss. + */ + for (j = 0; j <= 255; j++) + { + copy[j] = ftab[(j << 8) + ss] & CLEARMASK; + } + + for (j = ftab[ss << 8] & CLEARMASK; + j < (ftab[(ss + 1) << 8] & CLEARMASK); j++) + { + int zptr_j = zptr[j]; + c1 = blockBytes[zptr_j]; + if (!bigDone[c1]) + { + zptr[copy[c1]] = (zptr_j == 0 ? count : zptr_j) - 1; + copy[c1]++; + } + } + + for (j = 0; j <= 255; j++) + { + ftab[(j << 8) + ss] |= SETMASK; + } + } + } + } + + private void RandomiseBlock() + { + for (int i = 0; i < 256; i++) + { + inUse[i] = false; + } + + int rNToGo = 0; + int rTPos = 0; + + for (int i = 0; i < count; i++) + { + if (rNToGo == 0) + { + rNToGo = BZip2Constants.rNums[rTPos]; + + if (++rTPos == 512) + { + rTPos = 0; + } + } + rNToGo--; + blockBytes[i + 1] ^= (byte)((rNToGo == 1) ? 1 : 0); + + inUse[blockBytes[i + 1]] = true; + } + } + + private void DoReversibleTransformation() + { + workLimit = workFactor * (count - 1); + workDone = 0; + blockRandomised = false; + firstAttempt = true; + + MainSort(); + + if (workDone > workLimit && firstAttempt) + { + RandomiseBlock(); + workLimit = workDone = 0; + blockRandomised = true; + firstAttempt = false; + MainSort(); + } + + origPtr = -1; + for (int i = 0; i < count; i++) + { + if (zptr[i] == 0) + { + origPtr = i; + break; + } + } + + if (origPtr == -1) + { + Panic(); + } + } + + private bool FullGtU(int i1, int i2) + { + int c1, c2; + + c1 = blockBytes[++i1]; + c2 = blockBytes[++i2]; + if (c1 != c2) + return c1 > c2; + + c1 = blockBytes[++i1]; + c2 = blockBytes[++i2]; + if (c1 != c2) + return c1 > c2; + + c1 = blockBytes[++i1]; + c2 = blockBytes[++i2]; + if (c1 != c2) + return c1 > c2; + + c1 = blockBytes[++i1]; + c2 = blockBytes[++i2]; + if (c1 != c2) + return c1 > c2; + + c1 = blockBytes[++i1]; + c2 = blockBytes[++i2]; + if (c1 != c2) + return c1 > c2; + + c1 = blockBytes[++i1]; + c2 = blockBytes[++i2]; + if (c1 != c2) + return c1 > c2; + + int k = count; + int s1, s2; + + do + { + c1 = blockBytes[++i1]; + c2 = blockBytes[++i2]; + if (c1 != c2) + return c1 > c2; + + s1 = quadrantShorts[i1]; + s2 = quadrantShorts[i2]; + if (s1 != s2) + return s1 > s2; + + c1 = blockBytes[++i1]; + c2 = blockBytes[++i2]; + if (c1 != c2) + return c1 > c2; + + s1 = quadrantShorts[i1]; + s2 = quadrantShorts[i2]; + if (s1 != s2) + return s1 > s2; + + c1 = blockBytes[++i1]; + c2 = blockBytes[++i2]; + if (c1 != c2) + return c1 > c2; + + s1 = quadrantShorts[i1]; + s2 = quadrantShorts[i2]; + if (s1 != s2) + return s1 > s2; + + c1 = blockBytes[++i1]; + c2 = blockBytes[++i2]; + if (c1 != c2) + return c1 > c2; + + s1 = quadrantShorts[i1]; + s2 = quadrantShorts[i2]; + if (s1 != s2) + return s1 > s2; + + if (i1 >= count) + { + i1 -= count; + } + if (i2 >= count) + { + i2 -= count; + } + + k -= 4; + workDone++; + } + while (k >= 0); + + return false; + } + + /* + Knuth's increments seem to work better + than Incerpi-Sedgewick here. Possibly + because the number of elems to sort is + usually small, typically <= 20. + */ + private static readonly int[] incs = { 1, 4, 13, 40, 121, 364, 1093, 3280, 9841, 29524, 88573, 265720, 797161, + 2391484 }; + + private void AllocateCompressStructures() + { + int n = BZip2Constants.baseBlockSize * blockSize100k; + blockBytes = new byte[(n + 1 + BZip2Constants.NUM_OVERSHOOT_BYTES)]; + quadrantShorts = new ushort[(n + 1 + BZip2Constants.NUM_OVERSHOOT_BYTES)]; + zptr = new int[n]; + ftab = new int[65537]; + + /* + The back end needs a place to store the MTF values + whilst it calculates the coding tables. We could + put them in the zptr array. However, these values + will fit in a short, so we overlay szptr at the + start of zptr, in the hope of reducing the number + of cache misses induced by the multiple traversals + of the MTF values when calculating coding tables. + Seems to improve compression speed by about 1%. + */ + // NOTE: We can't "overlay" in C#, so we just share zptr + szptr = zptr; + } + + private void GenerateMTFValues() + { + char[] yy = new char[256]; + int i, j; + char tmp; + char tmp2; + int zPend; + int wr; + int EOB; + + MakeMaps(); + EOB = nInUse + 1; + + for (i = 0; i <= EOB; i++) + { + mtfFreq[i] = 0; + } + + wr = 0; + zPend = 0; + for (i = 0; i < nInUse; i++) + { + yy[i] = (char) i; + } + + for (i = 0; i < count; i++) + { + char ll_i; + + ll_i = unseqToSeq[blockBytes[zptr[i]]]; + + j = 0; + tmp = yy[j]; + while (ll_i != tmp) + { + j++; + tmp2 = tmp; + tmp = yy[j]; + yy[j] = tmp2; + } + yy[0] = tmp; + + if (j == 0) + { + zPend++; + } + else + { + if (zPend > 0) + { + zPend--; + while (true) + { + switch (zPend % 2) + { + case 0: + szptr[wr++] = BZip2Constants.RUNA; + mtfFreq[BZip2Constants.RUNA]++; + break; + case 1: + szptr[wr++] = BZip2Constants.RUNB; + mtfFreq[BZip2Constants.RUNB]++; + break; + } + + if (zPend < 2) + break; + + zPend = (zPend - 2) / 2; + } + zPend = 0; + } + szptr[wr++] = j + 1; + mtfFreq[j + 1]++; + } + } + + if (zPend > 0) + { + zPend--; + while (true) + { + switch (zPend % 2) + { + case 0: + szptr[wr++] = BZip2Constants.RUNA; + mtfFreq[BZip2Constants.RUNA]++; + break; + case 1: + szptr[wr++] = BZip2Constants.RUNB; + mtfFreq[BZip2Constants.RUNB]++; + break; + } + + if (zPend < 2) + break; + + zPend = (zPend - 2) / 2; + } + } + + szptr[wr++] = EOB; + mtfFreq[EOB]++; + + nMTF = wr; + } + + public override int Read(byte[] buffer, int offset, int count) + { + return 0; + } + + public override long Seek(long offset, SeekOrigin origin) + { + return 0; + } + + public override void SetLength(long value) + { + } + + public override void Write(byte[] buffer, int offset, int count) + { + for (int k = 0; k < count; ++k) + { + WriteByte(buffer[k + offset]); + } + } + + public override bool CanRead + { + get { return false; } + } + + public override bool CanSeek + { + get { return false; } + } + + public override bool CanWrite + { + get { return true; } + } + + public override long Length + { + get { return 0; } + } + + public override long Position + { + get { return 0; } + set {} + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/bzip2/src/CBZip2OutputStream.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/bzip2/src/CBZip2OutputStream.cs.meta new file mode 100644 index 0000000..90977f8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/bzip2/src/CBZip2OutputStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f4498dcb3d8f9d34e99106b214a08fcf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/bzip2/src/CRC.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/bzip2/src/CRC.cs new file mode 100644 index 0000000..278a9f3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/bzip2/src/CRC.cs @@ -0,0 +1,134 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/* + * This package is based on the work done by Keiron Liddle), Aftex Software + * to whom the Ant project is very grateful for his + * great code. + */ + +using System; + +namespace Org.BouncyCastle.Apache.Bzip2 +{ + /** + * A simple class the hold and calculate the CRC for sanity checking + * of the data. + * + * @author Keiron Liddle + */ + internal class CRC + { + public static readonly int[] crc32Table = { + unchecked((int)0x00000000), unchecked((int)0x04c11db7), unchecked((int)0x09823b6e), unchecked((int)0x0d4326d9), + unchecked((int)0x130476dc), unchecked((int)0x17c56b6b), unchecked((int)0x1a864db2), unchecked((int)0x1e475005), + unchecked((int)0x2608edb8), unchecked((int)0x22c9f00f), unchecked((int)0x2f8ad6d6), unchecked((int)0x2b4bcb61), + unchecked((int)0x350c9b64), unchecked((int)0x31cd86d3), unchecked((int)0x3c8ea00a), unchecked((int)0x384fbdbd), + unchecked((int)0x4c11db70), unchecked((int)0x48d0c6c7), unchecked((int)0x4593e01e), unchecked((int)0x4152fda9), + unchecked((int)0x5f15adac), unchecked((int)0x5bd4b01b), unchecked((int)0x569796c2), unchecked((int)0x52568b75), + unchecked((int)0x6a1936c8), unchecked((int)0x6ed82b7f), unchecked((int)0x639b0da6), unchecked((int)0x675a1011), + unchecked((int)0x791d4014), unchecked((int)0x7ddc5da3), unchecked((int)0x709f7b7a), unchecked((int)0x745e66cd), + unchecked((int)0x9823b6e0), unchecked((int)0x9ce2ab57), unchecked((int)0x91a18d8e), unchecked((int)0x95609039), + unchecked((int)0x8b27c03c), unchecked((int)0x8fe6dd8b), unchecked((int)0x82a5fb52), unchecked((int)0x8664e6e5), + unchecked((int)0xbe2b5b58), unchecked((int)0xbaea46ef), unchecked((int)0xb7a96036), unchecked((int)0xb3687d81), + unchecked((int)0xad2f2d84), unchecked((int)0xa9ee3033), unchecked((int)0xa4ad16ea), unchecked((int)0xa06c0b5d), + unchecked((int)0xd4326d90), unchecked((int)0xd0f37027), unchecked((int)0xddb056fe), unchecked((int)0xd9714b49), + unchecked((int)0xc7361b4c), unchecked((int)0xc3f706fb), unchecked((int)0xceb42022), unchecked((int)0xca753d95), + unchecked((int)0xf23a8028), unchecked((int)0xf6fb9d9f), unchecked((int)0xfbb8bb46), unchecked((int)0xff79a6f1), + unchecked((int)0xe13ef6f4), unchecked((int)0xe5ffeb43), unchecked((int)0xe8bccd9a), unchecked((int)0xec7dd02d), + unchecked((int)0x34867077), unchecked((int)0x30476dc0), unchecked((int)0x3d044b19), unchecked((int)0x39c556ae), + unchecked((int)0x278206ab), unchecked((int)0x23431b1c), unchecked((int)0x2e003dc5), unchecked((int)0x2ac12072), + unchecked((int)0x128e9dcf), unchecked((int)0x164f8078), unchecked((int)0x1b0ca6a1), unchecked((int)0x1fcdbb16), + unchecked((int)0x018aeb13), unchecked((int)0x054bf6a4), unchecked((int)0x0808d07d), unchecked((int)0x0cc9cdca), + unchecked((int)0x7897ab07), unchecked((int)0x7c56b6b0), unchecked((int)0x71159069), unchecked((int)0x75d48dde), + unchecked((int)0x6b93dddb), unchecked((int)0x6f52c06c), unchecked((int)0x6211e6b5), unchecked((int)0x66d0fb02), + unchecked((int)0x5e9f46bf), unchecked((int)0x5a5e5b08), unchecked((int)0x571d7dd1), unchecked((int)0x53dc6066), + unchecked((int)0x4d9b3063), unchecked((int)0x495a2dd4), unchecked((int)0x44190b0d), unchecked((int)0x40d816ba), + unchecked((int)0xaca5c697), unchecked((int)0xa864db20), unchecked((int)0xa527fdf9), unchecked((int)0xa1e6e04e), + unchecked((int)0xbfa1b04b), unchecked((int)0xbb60adfc), unchecked((int)0xb6238b25), unchecked((int)0xb2e29692), + unchecked((int)0x8aad2b2f), unchecked((int)0x8e6c3698), unchecked((int)0x832f1041), unchecked((int)0x87ee0df6), + unchecked((int)0x99a95df3), unchecked((int)0x9d684044), unchecked((int)0x902b669d), unchecked((int)0x94ea7b2a), + unchecked((int)0xe0b41de7), unchecked((int)0xe4750050), unchecked((int)0xe9362689), unchecked((int)0xedf73b3e), + unchecked((int)0xf3b06b3b), unchecked((int)0xf771768c), unchecked((int)0xfa325055), unchecked((int)0xfef34de2), + unchecked((int)0xc6bcf05f), unchecked((int)0xc27dede8), unchecked((int)0xcf3ecb31), unchecked((int)0xcbffd686), + unchecked((int)0xd5b88683), unchecked((int)0xd1799b34), unchecked((int)0xdc3abded), unchecked((int)0xd8fba05a), + unchecked((int)0x690ce0ee), unchecked((int)0x6dcdfd59), unchecked((int)0x608edb80), unchecked((int)0x644fc637), + unchecked((int)0x7a089632), unchecked((int)0x7ec98b85), unchecked((int)0x738aad5c), unchecked((int)0x774bb0eb), + unchecked((int)0x4f040d56), unchecked((int)0x4bc510e1), unchecked((int)0x46863638), unchecked((int)0x42472b8f), + unchecked((int)0x5c007b8a), unchecked((int)0x58c1663d), unchecked((int)0x558240e4), unchecked((int)0x51435d53), + unchecked((int)0x251d3b9e), unchecked((int)0x21dc2629), unchecked((int)0x2c9f00f0), unchecked((int)0x285e1d47), + unchecked((int)0x36194d42), unchecked((int)0x32d850f5), unchecked((int)0x3f9b762c), unchecked((int)0x3b5a6b9b), + unchecked((int)0x0315d626), unchecked((int)0x07d4cb91), unchecked((int)0x0a97ed48), unchecked((int)0x0e56f0ff), + unchecked((int)0x1011a0fa), unchecked((int)0x14d0bd4d), unchecked((int)0x19939b94), unchecked((int)0x1d528623), + unchecked((int)0xf12f560e), unchecked((int)0xf5ee4bb9), unchecked((int)0xf8ad6d60), unchecked((int)0xfc6c70d7), + unchecked((int)0xe22b20d2), unchecked((int)0xe6ea3d65), unchecked((int)0xeba91bbc), unchecked((int)0xef68060b), + unchecked((int)0xd727bbb6), unchecked((int)0xd3e6a601), unchecked((int)0xdea580d8), unchecked((int)0xda649d6f), + unchecked((int)0xc423cd6a), unchecked((int)0xc0e2d0dd), unchecked((int)0xcda1f604), unchecked((int)0xc960ebb3), + unchecked((int)0xbd3e8d7e), unchecked((int)0xb9ff90c9), unchecked((int)0xb4bcb610), unchecked((int)0xb07daba7), + unchecked((int)0xae3afba2), unchecked((int)0xaafbe615), unchecked((int)0xa7b8c0cc), unchecked((int)0xa379dd7b), + unchecked((int)0x9b3660c6), unchecked((int)0x9ff77d71), unchecked((int)0x92b45ba8), unchecked((int)0x9675461f), + unchecked((int)0x8832161a), unchecked((int)0x8cf30bad), unchecked((int)0x81b02d74), unchecked((int)0x857130c3), + unchecked((int)0x5d8a9099), unchecked((int)0x594b8d2e), unchecked((int)0x5408abf7), unchecked((int)0x50c9b640), + unchecked((int)0x4e8ee645), unchecked((int)0x4a4ffbf2), unchecked((int)0x470cdd2b), unchecked((int)0x43cdc09c), + unchecked((int)0x7b827d21), unchecked((int)0x7f436096), unchecked((int)0x7200464f), unchecked((int)0x76c15bf8), + unchecked((int)0x68860bfd), unchecked((int)0x6c47164a), unchecked((int)0x61043093), unchecked((int)0x65c52d24), + unchecked((int)0x119b4be9), unchecked((int)0x155a565e), unchecked((int)0x18197087), unchecked((int)0x1cd86d30), + unchecked((int)0x029f3d35), unchecked((int)0x065e2082), unchecked((int)0x0b1d065b), unchecked((int)0x0fdc1bec), + unchecked((int)0x3793a651), unchecked((int)0x3352bbe6), unchecked((int)0x3e119d3f), unchecked((int)0x3ad08088), + unchecked((int)0x2497d08d), unchecked((int)0x2056cd3a), unchecked((int)0x2d15ebe3), unchecked((int)0x29d4f654), + unchecked((int)0xc5a92679), unchecked((int)0xc1683bce), unchecked((int)0xcc2b1d17), unchecked((int)0xc8ea00a0), + unchecked((int)0xd6ad50a5), unchecked((int)0xd26c4d12), unchecked((int)0xdf2f6bcb), unchecked((int)0xdbee767c), + unchecked((int)0xe3a1cbc1), unchecked((int)0xe760d676), unchecked((int)0xea23f0af), unchecked((int)0xeee2ed18), + unchecked((int)0xf0a5bd1d), unchecked((int)0xf464a0aa), unchecked((int)0xf9278673), unchecked((int)0xfde69bc4), + unchecked((int)0x89b8fd09), unchecked((int)0x8d79e0be), unchecked((int)0x803ac667), unchecked((int)0x84fbdbd0), + unchecked((int)0x9abc8bd5), unchecked((int)0x9e7d9662), unchecked((int)0x933eb0bb), unchecked((int)0x97ffad0c), + unchecked((int)0xafb010b1), unchecked((int)0xab710d06), unchecked((int)0xa6322bdf), unchecked((int)0xa2f33668), + unchecked((int)0xbcb4666d), unchecked((int)0xb8757bda), unchecked((int)0xb5365d03), unchecked((int)0xb1f740b4) + }; + + public CRC() { + InitialiseCRC(); + } + + internal void InitialiseCRC() { + globalCrc = unchecked((int)0xffffffff); + } + + internal int GetFinalCRC() { + return ~globalCrc; + } + + internal int GetGlobalCRC() { + return globalCrc; + } + + internal void SetGlobalCRC(int newCrc) { + globalCrc = newCrc; + } + + internal void UpdateCRC(int inCh) { + int temp = (globalCrc >> 24) ^ inCh; + if (temp < 0) { + temp = 256 + temp; + } + globalCrc = (globalCrc << 8) ^ CRC.crc32Table[temp]; + } + + internal int globalCrc; + } +} \ No newline at end of file diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/bzip2/src/CRC.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/bzip2/src/CRC.cs.meta new file mode 100644 index 0000000..5a4a923 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/bzip2/src/CRC.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cd2770b33793035459fdd4c21bfb6f2c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src.meta new file mode 100644 index 0000000..e66ba46 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5fc58d84e80735142a0b2c7eb7716a99 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/AssemblyInfo.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/AssemblyInfo.cs new file mode 100644 index 0000000..f2eec4a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/AssemblyInfo.cs @@ -0,0 +1,88 @@ +using System; +using System.Reflection; +using System.Runtime.CompilerServices; +//using System.Security.Permissions; + +#if PORTABLE +using System.Linq; +#else +using System.Runtime.InteropServices; +#endif + +[assembly: CLSCompliant(true)] +#if !PORTABLE +[assembly: ComVisible(false)] +#endif + +[assembly: InternalsVisibleTo("crypto.test, PublicKey=002400000480000094000000060200000024000052534131000400000100010083A6A1D0D41B8A0FD3061C8DD2BA14DA98F9BF53576AD386A4D021ABD235EE41BC5416683314816908765FAC4951301E159153CF02BF1B31BEC8A2CE6C0110C30CC7BEF54E514D530B703D37629078AB3ECCE1AFA5ED3F9D63F3B50398188A811ADA59827B9E1A4EEEB87D05E4AFE45BEFD69BF2CDFD37F38334B748C8CB7FBC")] + +// Start with no permissions +//[assembly: PermissionSet(SecurityAction.RequestOptional, Unrestricted=false)] +//...and explicitly add those we need + +// see Org.BouncyCastle.Crypto.Encodings.Pkcs1Encoding.StrictLengthEnabledProperty +//[assembly: EnvironmentPermission(SecurityAction.RequestOptional, Read="Org.BouncyCastle.Pkcs1.Strict")] + +internal class AssemblyInfo +{ + private static string version = null; + + public static string Version + { + get + { + if (version == null) + { +#if PORTABLE +#if NEW_REFLECTION + var a = typeof(AssemblyInfo).GetTypeInfo().Assembly; + var c = a.GetCustomAttributes(typeof(AssemblyVersionAttribute)); +#else + var a = typeof(AssemblyInfo).Assembly; + var c = a.GetCustomAttributes(typeof(AssemblyVersionAttribute), false); +#endif + var v = (AssemblyVersionAttribute)c.FirstOrDefault(); + if (v != null) + { + version = v.Version; + } +#else + version = Assembly.GetExecutingAssembly().GetName().Version.ToString(); +#endif + + // if we're still here, then don't try again + if (version == null) + { + version = string.Empty; + } + } + + return version; + } + } +} + + +#if NET40 +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace System.Reflection +{ + [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true, Inherited = false)] + internal sealed class AssemblyMetadataAttribute : Attribute + { + public AssemblyMetadataAttribute(string key, string value) + { + Key = key; + Value = value; + } + + public string Key { get; } + + public string Value { get; } + } +} + +#endif diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/AssemblyInfo.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/AssemblyInfo.cs.meta new file mode 100644 index 0000000..42c3b93 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/AssemblyInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 05140a03d24060e4f86ba4e082de4d8e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1.meta new file mode 100644 index 0000000..da5b33e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a3cd50e4f77e34043a78136a5955752f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ASN1Generator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ASN1Generator.cs new file mode 100644 index 0000000..d064b80 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ASN1Generator.cs @@ -0,0 +1,29 @@ +using System.Collections; +using System.IO; + +namespace Org.BouncyCastle.Asn1 +{ + public abstract class Asn1Generator + { + private Stream _out; + + protected Asn1Generator( + Stream outStream) + { + _out = outStream; + } + + protected Stream Out + { + get { return _out; } + } + + public abstract void AddObject(Asn1Encodable obj); + + public abstract void AddObject(Asn1Object obj); + + public abstract Stream GetRawOutputStream(); + + public abstract void Close(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ASN1Generator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ASN1Generator.cs.meta new file mode 100644 index 0000000..3a144f6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ASN1Generator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a2762f7424d64bf4bb4982237b62d4a3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ASN1OctetStringParser.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ASN1OctetStringParser.cs new file mode 100644 index 0000000..5815aa4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ASN1OctetStringParser.cs @@ -0,0 +1,10 @@ +using System.IO; + +namespace Org.BouncyCastle.Asn1 +{ + public interface Asn1OctetStringParser + : IAsn1Convertible + { + Stream GetOctetStream(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ASN1OctetStringParser.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ASN1OctetStringParser.cs.meta new file mode 100644 index 0000000..55c3ca1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ASN1OctetStringParser.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9c3e869989eee104fa80aee30134f35b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ASN1SequenceParser.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ASN1SequenceParser.cs new file mode 100644 index 0000000..9e88ac7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ASN1SequenceParser.cs @@ -0,0 +1,8 @@ +namespace Org.BouncyCastle.Asn1 +{ + public interface Asn1SequenceParser + : IAsn1Convertible + { + IAsn1Convertible ReadObject(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ASN1SequenceParser.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ASN1SequenceParser.cs.meta new file mode 100644 index 0000000..43d32f0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ASN1SequenceParser.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5c32269a59e3ff54ea13215607a73df7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ASN1SetParser.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ASN1SetParser.cs new file mode 100644 index 0000000..d1b9c64 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ASN1SetParser.cs @@ -0,0 +1,8 @@ +namespace Org.BouncyCastle.Asn1 +{ + public interface Asn1SetParser + : IAsn1Convertible + { + IAsn1Convertible ReadObject(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ASN1SetParser.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ASN1SetParser.cs.meta new file mode 100644 index 0000000..96ba04e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ASN1SetParser.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a04c0d758c3c7874f98cb9e9483d09d0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ASN1StreamParser.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ASN1StreamParser.cs new file mode 100644 index 0000000..a92a3ad --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ASN1StreamParser.cs @@ -0,0 +1,239 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Asn1 +{ + public class Asn1StreamParser + { + private readonly Stream _in; + private readonly int _limit; + + private readonly byte[][] tmpBuffers; + + public Asn1StreamParser(Stream input) + : this(input, Asn1InputStream.FindLimit(input)) + { + } + + public Asn1StreamParser(byte[] encoding) + : this(new MemoryStream(encoding, false), encoding.Length) + { + } + + public Asn1StreamParser(Stream input, int limit) + : this(input, limit, new byte[16][]) + { + } + + internal Asn1StreamParser(Stream input, int limit, byte[][] tmpBuffers) + { + if (!input.CanRead) + throw new ArgumentException("Expected stream to be readable", "input"); + + this._in = input; + this._limit = limit; + this.tmpBuffers = tmpBuffers; + } + + internal IAsn1Convertible ReadIndef(int tagValue) + { + // Note: INDEF => CONSTRUCTED + + // TODO There are other tags that may be constructed (e.g. BIT_STRING) + switch (tagValue) + { + case Asn1Tags.External: + return new DerExternalParser(this); + case Asn1Tags.OctetString: + return new BerOctetStringParser(this); + case Asn1Tags.Sequence: + return new BerSequenceParser(this); + case Asn1Tags.Set: + return new BerSetParser(this); + default: + throw new Asn1Exception("unknown BER object encountered: 0x" + tagValue.ToString("X")); + } + } + + internal IAsn1Convertible ReadImplicit(bool constructed, int tag) + { + if (_in is IndefiniteLengthInputStream) + { + if (!constructed) + throw new IOException("indefinite-length primitive encoding encountered"); + + return ReadIndef(tag); + } + + if (constructed) + { + switch (tag) + { + case Asn1Tags.Set: + return new DerSetParser(this); + case Asn1Tags.Sequence: + return new DerSequenceParser(this); + case Asn1Tags.OctetString: + return new BerOctetStringParser(this); + } + } + else + { + switch (tag) + { + case Asn1Tags.Set: + throw new Asn1Exception("sequences must use constructed encoding (see X.690 8.9.1/8.10.1)"); + case Asn1Tags.Sequence: + throw new Asn1Exception("sets must use constructed encoding (see X.690 8.11.1/8.12.1)"); + case Asn1Tags.OctetString: + return new DerOctetStringParser((DefiniteLengthInputStream)_in); + } + } + + throw new Asn1Exception("implicit tagging not implemented"); + } + + internal Asn1Object ReadTaggedObject(bool constructed, int tag) + { + if (!constructed) + { + // Note: !CONSTRUCTED => IMPLICIT + DefiniteLengthInputStream defIn = (DefiniteLengthInputStream)_in; + return new DerTaggedObject(false, tag, new DerOctetString(defIn.ToArray())); + } + + Asn1EncodableVector v = ReadVector(); + + if (_in is IndefiniteLengthInputStream) + { + return v.Count == 1 + ? new BerTaggedObject(true, tag, v[0]) + : new BerTaggedObject(false, tag, BerSequence.FromVector(v)); + } + + return v.Count == 1 + ? new DerTaggedObject(true, tag, v[0]) + : new DerTaggedObject(false, tag, DerSequence.FromVector(v)); + } + + public virtual IAsn1Convertible ReadObject() + { + int tag = _in.ReadByte(); + if (tag == -1) + return null; + + // turn of looking for "00" while we resolve the tag + Set00Check(false); + + // + // calculate tag number + // + int tagNo = Asn1InputStream.ReadTagNumber(_in, tag); + + bool isConstructed = (tag & Asn1Tags.Constructed) != 0; + + // + // calculate length + // + int length = Asn1InputStream.ReadLength(_in, _limit, + tagNo == Asn1Tags.OctetString || tagNo == Asn1Tags.Sequence || tagNo == Asn1Tags.Set || tagNo == Asn1Tags.External); + + if (length < 0) // indefinite-length method + { + if (!isConstructed) + throw new IOException("indefinite-length primitive encoding encountered"); + + IndefiniteLengthInputStream indIn = new IndefiniteLengthInputStream(_in, _limit); + Asn1StreamParser sp = new Asn1StreamParser(indIn, _limit, tmpBuffers); + + int tagClass = tag & Asn1Tags.Private; + if (0 != tagClass) + { + if ((tag & Asn1Tags.Application) != 0) + return new BerApplicationSpecificParser(tagNo, sp); + + return new BerTaggedObjectParser(true, tagNo, sp); + } + + return sp.ReadIndef(tagNo); + } + else + { + DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(_in, length, _limit); + + int tagClass = tag & Asn1Tags.Private; + if (0 != tagClass) + { + if ((tag & Asn1Tags.Application) != 0) + return new DerApplicationSpecific(isConstructed, tagNo, defIn.ToArray()); + + return new BerTaggedObjectParser(isConstructed, tagNo, + new Asn1StreamParser(defIn, defIn.Remaining, tmpBuffers)); + } + + if (!isConstructed) + { + // Some primitive encodings can be handled by parsers too... + switch (tagNo) + { + case Asn1Tags.OctetString: + return new DerOctetStringParser(defIn); + } + + try + { + return Asn1InputStream.CreatePrimitiveDerObject(tagNo, defIn, tmpBuffers); + } + catch (ArgumentException e) + { + throw new Asn1Exception("corrupted stream detected", e); + } + } + + Asn1StreamParser sp = new Asn1StreamParser(defIn, defIn.Remaining, tmpBuffers); + + // TODO There are other tags that may be constructed (e.g. BitString) + switch (tagNo) + { + case Asn1Tags.OctetString: + // + // yes, people actually do this... + // + return new BerOctetStringParser(sp); + case Asn1Tags.Sequence: + return new DerSequenceParser(sp); + case Asn1Tags.Set: + return new DerSetParser(sp); + case Asn1Tags.External: + return new DerExternalParser(sp); + default: + throw new IOException("unknown tag " + tagNo + " encountered"); + } + } + } + + private void Set00Check( + bool enabled) + { + if (_in is IndefiniteLengthInputStream) + { + ((IndefiniteLengthInputStream) _in).SetEofOn00(enabled); + } + } + + internal Asn1EncodableVector ReadVector() + { + IAsn1Convertible obj = ReadObject(); + if (null == obj) + return new Asn1EncodableVector(0); + + Asn1EncodableVector v = new Asn1EncodableVector(); + do + { + v.Add(obj.ToAsn1Object()); + } + while ((obj = ReadObject()) != null); + return v; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ASN1StreamParser.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ASN1StreamParser.cs.meta new file mode 100644 index 0000000..b86a69a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ASN1StreamParser.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1e9aadaaa1fb0ee4abf6dd90737b7165 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ASN1TaggedObjectParser.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ASN1TaggedObjectParser.cs new file mode 100644 index 0000000..32327a2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ASN1TaggedObjectParser.cs @@ -0,0 +1,10 @@ +namespace Org.BouncyCastle.Asn1 +{ + public interface Asn1TaggedObjectParser + : IAsn1Convertible + { + int TagNo { get; } + + IAsn1Convertible GetObjectParser(int tag, bool isExplicit); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ASN1TaggedObjectParser.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ASN1TaggedObjectParser.cs.meta new file mode 100644 index 0000000..7840cb9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ASN1TaggedObjectParser.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 32cdba725d5009c4db01280aad3c511c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1Encodable.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1Encodable.cs new file mode 100644 index 0000000..247b0e0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1Encodable.cs @@ -0,0 +1,76 @@ +using System.IO; + +namespace Org.BouncyCastle.Asn1 +{ + public abstract class Asn1Encodable + : IAsn1Convertible + { + public const string Der = "DER"; + public const string Ber = "BER"; + + public virtual void EncodeTo(Stream output) + { + ToAsn1Object().EncodeTo(output); + } + + public virtual void EncodeTo(Stream output, string encoding) + { + ToAsn1Object().EncodeTo(output, encoding); + } + + public byte[] GetEncoded() + { + MemoryStream bOut = new MemoryStream(); + EncodeTo(bOut); + return bOut.ToArray(); + } + + public byte[] GetEncoded(string encoding) + { + MemoryStream bOut = new MemoryStream(); + EncodeTo(bOut, encoding); + return bOut.ToArray(); + } + + /** + * Return the DER encoding of the object, null if the DER encoding can not be made. + * + * @return a DER byte array, null otherwise. + */ + public byte[] GetDerEncoded() + { + try + { + return GetEncoded(Der); + } + catch (IOException) + { + return null; + } + } + + public sealed override int GetHashCode() + { + return ToAsn1Object().CallAsn1GetHashCode(); + } + + public sealed override bool Equals( + object obj) + { + if (obj == this) + return true; + + IAsn1Convertible other = obj as IAsn1Convertible; + + if (other == null) + return false; + + Asn1Object o1 = ToAsn1Object(); + Asn1Object o2 = other.ToAsn1Object(); + + return o1 == o2 || (null != o2 && o1.CallAsn1Equals(o2)); + } + + public abstract Asn1Object ToAsn1Object(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1Encodable.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1Encodable.cs.meta new file mode 100644 index 0000000..9f11878 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1Encodable.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f1807b51cb6dbf94aa0b04f06e682c20 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1EncodableVector.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1EncodableVector.cs new file mode 100644 index 0000000..987aa52 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1EncodableVector.cs @@ -0,0 +1,191 @@ +using System; +using System.Collections; + +namespace Org.BouncyCastle.Asn1 +{ + /** + * Mutable class for building ASN.1 constructed objects such as SETs or SEQUENCEs. + */ + public class Asn1EncodableVector + : IEnumerable + { + internal static readonly Asn1Encodable[] EmptyElements = new Asn1Encodable[0]; + + private const int DefaultCapacity = 10; + + private Asn1Encodable[] elements; + private int elementCount; + private bool copyOnWrite; + + public static Asn1EncodableVector FromEnumerable(IEnumerable e) + { + Asn1EncodableVector v = new Asn1EncodableVector(); + foreach (Asn1Encodable obj in e) + { + v.Add(obj); + } + return v; + } + + public Asn1EncodableVector() + : this(DefaultCapacity) + { + } + + public Asn1EncodableVector(int initialCapacity) + { + if (initialCapacity < 0) + throw new ArgumentException("must not be negative", "initialCapacity"); + + this.elements = (initialCapacity == 0) ? EmptyElements : new Asn1Encodable[initialCapacity]; + this.elementCount = 0; + this.copyOnWrite = false; + } + + public Asn1EncodableVector(params Asn1Encodable[] v) + : this() + { + Add(v); + } + + public void Add(Asn1Encodable element) + { + if (null == element) + throw new ArgumentNullException("element"); + + int capacity = elements.Length; + int minCapacity = elementCount + 1; + if ((minCapacity > capacity) | copyOnWrite) + { + Reallocate(minCapacity); + } + + this.elements[elementCount] = element; + this.elementCount = minCapacity; + } + + public void Add(params Asn1Encodable[] objs) + { + foreach (Asn1Encodable obj in objs) + { + Add(obj); + } + } + + public void AddOptional(params Asn1Encodable[] objs) + { + if (objs != null) + { + foreach (Asn1Encodable obj in objs) + { + if (obj != null) + { + Add(obj); + } + } + } + } + + public void AddOptionalTagged(bool isExplicit, int tagNo, Asn1Encodable obj) + { + if (null != obj) + { + Add(new DerTaggedObject(isExplicit, tagNo, obj)); + } + } + + public void AddAll(Asn1EncodableVector other) + { + if (null == other) + throw new ArgumentNullException("other"); + + int otherElementCount = other.Count; + if (otherElementCount < 1) + return; + + int capacity = elements.Length; + int minCapacity = elementCount + otherElementCount; + if ((minCapacity > capacity) | copyOnWrite) + { + Reallocate(minCapacity); + } + + int i = 0; + do + { + Asn1Encodable otherElement = other[i]; + if (null == otherElement) + throw new NullReferenceException("'other' elements cannot be null"); + + this.elements[elementCount + i] = otherElement; + } + while (++i < otherElementCount); + + this.elementCount = minCapacity; + } + + public Asn1Encodable this[int index] + { + get + { + if (index >= elementCount) + throw new IndexOutOfRangeException(index + " >= " + elementCount); + + return elements[index]; + } + } + + public int Count + { + get { return elementCount; } + } + + public IEnumerator GetEnumerator() + { + return CopyElements().GetEnumerator(); + } + + internal Asn1Encodable[] CopyElements() + { + if (0 == elementCount) + return EmptyElements; + + Asn1Encodable[] copy = new Asn1Encodable[elementCount]; + Array.Copy(elements, 0, copy, 0, elementCount); + return copy; + } + + internal Asn1Encodable[] TakeElements() + { + if (0 == elementCount) + return EmptyElements; + + if (elements.Length == elementCount) + { + this.copyOnWrite = true; + return elements; + } + + Asn1Encodable[] copy = new Asn1Encodable[elementCount]; + Array.Copy(elements, 0, copy, 0, elementCount); + return copy; + } + + private void Reallocate(int minCapacity) + { + int oldCapacity = elements.Length; + int newCapacity = System.Math.Max(oldCapacity, minCapacity + (minCapacity >> 1)); + + Asn1Encodable[] copy = new Asn1Encodable[newCapacity]; + Array.Copy(elements, 0, copy, 0, elementCount); + + this.elements = copy; + this.copyOnWrite = false; + } + + internal static Asn1Encodable[] CloneElements(Asn1Encodable[] elements) + { + return elements.Length < 1 ? EmptyElements : (Asn1Encodable[])elements.Clone(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1EncodableVector.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1EncodableVector.cs.meta new file mode 100644 index 0000000..4a0dc98 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1EncodableVector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5339fb202ee991842bdcbf74a9ab16d8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1Exception.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1Exception.cs new file mode 100644 index 0000000..1dfe173 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1Exception.cs @@ -0,0 +1,30 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Asn1 +{ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE) + [Serializable] +#endif + public class Asn1Exception + : IOException + { + public Asn1Exception() + : base() + { + } + + public Asn1Exception( + string message) + : base(message) + { + } + + public Asn1Exception( + string message, + Exception exception) + : base(message, exception) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1Exception.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1Exception.cs.meta new file mode 100644 index 0000000..840894d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1Exception.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: afd09138105ec8e4fbe1f20ffdcb5439 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1InputStream.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1InputStream.cs new file mode 100644 index 0000000..20734fd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1InputStream.cs @@ -0,0 +1,472 @@ +using System; +using System.Diagnostics; +using System.IO; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Asn1 +{ + /** + * a general purpose ASN.1 decoder - note: this class differs from the + * others in that it returns null after it has read the last object in + * the stream. If an ASN.1 Null is encountered a Der/BER Null object is + * returned. + */ + public class Asn1InputStream + : FilterStream + { + private readonly int limit; + + internal readonly byte[][] tmpBuffers; + + internal static int FindLimit(Stream input) + { + if (input is LimitedInputStream) + return ((LimitedInputStream)input).Limit; + + if (input is Asn1InputStream) + return ((Asn1InputStream)input).Limit; + + if (input is MemoryStream) + { + MemoryStream mem = (MemoryStream)input; + return (int)(mem.Length - mem.Position); + } + + return int.MaxValue; + } + + public Asn1InputStream(Stream input) + : this(input, FindLimit(input)) + { + } + + /** + * Create an ASN1InputStream based on the input byte array. The length of DER objects in + * the stream is automatically limited to the length of the input array. + * + * @param input array containing ASN.1 encoded data. + */ + public Asn1InputStream(byte[] input) + : this(new MemoryStream(input, false), input.Length) + { + } + + /** + * Create an ASN1InputStream where no DER object will be longer than limit. + * + * @param input stream containing ASN.1 encoded data. + * @param limit maximum size of a DER encoded object. + */ + public Asn1InputStream(Stream input, int limit) + : this(input, limit, new byte[16][]) + { + } + + internal Asn1InputStream(Stream input, int limit, byte[][] tmpBuffers) + : base(input) + { + this.limit = limit; + this.tmpBuffers = tmpBuffers; + } + + /** + * build an object given its tag and the number of bytes to construct it from. + */ + private Asn1Object BuildObject( + int tag, + int tagNo, + int length) + { + bool isConstructed = (tag & Asn1Tags.Constructed) != 0; + + DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(this, length, limit); + + int tagClass = tag & Asn1Tags.Private; + if (0 != tagClass) + { + if ((tag & Asn1Tags.Application) != 0) + return new DerApplicationSpecific(isConstructed, tagNo, defIn.ToArray()); + + return new Asn1StreamParser(defIn, defIn.Remaining, tmpBuffers).ReadTaggedObject(isConstructed, tagNo); + } + + if (!isConstructed) + return CreatePrimitiveDerObject(tagNo, defIn, tmpBuffers); + + switch (tagNo) + { + case Asn1Tags.BitString: + { + return BuildConstructedBitString(ReadVector(defIn)); + } + case Asn1Tags.OctetString: + { + // + // yes, people actually do this... + // + return BuildConstructedOctetString(ReadVector(defIn)); + } + case Asn1Tags.Sequence: + return CreateDerSequence(defIn); + case Asn1Tags.Set: + return CreateDerSet(defIn); + case Asn1Tags.External: + return new DerExternal(ReadVector(defIn)); + default: + throw new IOException("unknown tag " + tagNo + " encountered"); + } + } + + internal virtual Asn1EncodableVector ReadVector() + { + Asn1Object o = ReadObject(); + if (null == o) + return new Asn1EncodableVector(0); + + Asn1EncodableVector v = new Asn1EncodableVector(); + do + { + v.Add(o); + } + while ((o = ReadObject()) != null); + return v; + } + + internal virtual Asn1EncodableVector ReadVector(DefiniteLengthInputStream defIn) + { + int remaining = defIn.Remaining; + if (remaining < 1) + return new Asn1EncodableVector(0); + + return new Asn1InputStream(defIn, remaining, tmpBuffers).ReadVector(); + } + + internal virtual DerSequence CreateDerSequence( + DefiniteLengthInputStream dIn) + { + return DerSequence.FromVector(ReadVector(dIn)); + } + + internal virtual DerSet CreateDerSet( + DefiniteLengthInputStream dIn) + { + return DerSet.FromVector(ReadVector(dIn), false); + } + + public Asn1Object ReadObject() + { + int tag = ReadByte(); + if (tag <= 0) + { + if (tag == 0) + throw new IOException("unexpected end-of-contents marker"); + + return null; + } + + int tagNo = ReadTagNumber(this, tag); + int length = ReadLength(this, limit, false); + + if (length >= 0) + { + // definite-length + try + { + return BuildObject(tag, tagNo, length); + } + catch (ArgumentException e) + { + throw new Asn1Exception("corrupted stream detected", e); + } + } + + // indefinite-length + + if (0 == (tag & Asn1Tags.Constructed)) + throw new IOException("indefinite-length primitive encoding encountered"); + + IndefiniteLengthInputStream indIn = new IndefiniteLengthInputStream(this, limit); + Asn1StreamParser sp = new Asn1StreamParser(indIn, limit, tmpBuffers); + + int tagClass = tag & Asn1Tags.Private; + if (0 != tagClass) + { + if ((tag & Asn1Tags.Application) != 0) + return new BerApplicationSpecificParser(tagNo, sp).ToAsn1Object(); + + return new BerTaggedObjectParser(true, tagNo, sp).ToAsn1Object(); + } + + // TODO There are other tags that may be constructed (e.g. BitString) + switch (tagNo) + { + case Asn1Tags.OctetString: + return BerOctetStringParser.Parse(sp); + case Asn1Tags.Sequence: + return BerSequenceParser.Parse(sp); + case Asn1Tags.Set: + return BerSetParser.Parse(sp); + case Asn1Tags.External: + return DerExternalParser.Parse(sp); + default: + throw new IOException("unknown BER object encountered"); + } + } + + internal virtual DerBitString BuildConstructedBitString(Asn1EncodableVector contentsElements) + { + DerBitString[] bitStrings = new DerBitString[contentsElements.Count]; + + for (int i = 0; i != bitStrings.Length; i++) + { + DerBitString bitString = contentsElements[i] as DerBitString; + if (null == bitString) + throw new Asn1Exception("unknown object encountered in constructed BIT STRING: " + + Platform.GetTypeName(contentsElements[i])); + + bitStrings[i] = bitString; + } + + // TODO Probably ought to be DLBitString + return new BerBitString(bitStrings); + } + + internal virtual Asn1OctetString BuildConstructedOctetString(Asn1EncodableVector contentsElements) + { + Asn1OctetString[] octetStrings = new Asn1OctetString[contentsElements.Count]; + + for (int i = 0; i != octetStrings.Length; i++) + { + Asn1OctetString octetString = contentsElements[i] as Asn1OctetString; + if (null == octetString) + throw new Asn1Exception("unknown object encountered in constructed OCTET STRING: " + + Platform.GetTypeName(contentsElements[i])); + + octetStrings[i] = octetString; + } + + // TODO Probably ought to be DerOctetString (no DLOctetString available) + return new BerOctetString(octetStrings); + } + + internal virtual int Limit + { + get { return limit; } + } + + internal static int ReadTagNumber(Stream s, int tag) + { + int tagNo = tag & 0x1f; + + // + // with tagged object tag number is bottom 5 bits, or stored at the start of the content + // + if (tagNo == 0x1f) + { + tagNo = 0; + + int b = s.ReadByte(); + if (b < 31) + { + if (b < 0) + throw new EndOfStreamException("EOF found inside tag value."); + + throw new IOException("corrupted stream - high tag number < 31 found"); + } + + // X.690-0207 8.1.2.4.2 + // "c) bits 7 to 1 of the first subsequent octet shall not all be zero." + if ((b & 0x7f) == 0) + throw new IOException("corrupted stream - invalid high tag number found"); + + while ((b & 0x80) != 0) + { + if (((uint)tagNo >> 24) != 0U) + throw new IOException("Tag number more than 31 bits"); + + tagNo |= b & 0x7f; + tagNo <<= 7; + b = s.ReadByte(); + if (b < 0) + throw new EndOfStreamException("EOF found inside tag value."); + } + + tagNo |= b & 0x7f; + } + + return tagNo; + } + + internal static int ReadLength(Stream s, int limit, bool isParsing) + { + int length = s.ReadByte(); + if (0U == ((uint)length >> 7)) + { + // definite-length short form + return length; + } + if (0x80 == length) + { + // indefinite-length + return -1; + } + if (length < 0) + { + throw new EndOfStreamException("EOF found when length expected"); + } + if (0xFF == length) + { + throw new IOException("invalid long form definite-length 0xFF"); + } + + int octetsCount = length & 0x7F, octetsPos = 0; + + length = 0; + do + { + int octet = s.ReadByte(); + if (octet < 0) + throw new EndOfStreamException("EOF found reading length"); + + if (((uint)length >> 23) != 0U) + throw new IOException("long form definite-length more than 31 bits"); + + length = (length << 8) + octet; + } + while (++octetsPos < octetsCount); + + if (length >= limit && !isParsing) // after all we must have read at least 1 byte + throw new IOException("corrupted stream - out of bounds length found: " + length + " >= " + limit); + + return length; + } + + private static byte[] GetBuffer(DefiniteLengthInputStream defIn, byte[][] tmpBuffers) + { + int len = defIn.Remaining; + if (len >= tmpBuffers.Length) + { + return defIn.ToArray(); + } + + byte[] buf = tmpBuffers[len]; + if (buf == null) + { + buf = tmpBuffers[len] = new byte[len]; + } + + defIn.ReadAllIntoByteArray(buf); + + return buf; + } + + private static char[] GetBmpCharBuffer(DefiniteLengthInputStream defIn) + { + int remainingBytes = defIn.Remaining; + if (0 != (remainingBytes & 1)) + throw new IOException("malformed BMPString encoding encountered"); + + char[] str = new char[remainingBytes / 2]; + int stringPos = 0; + + byte[] buf = new byte[8]; + while (remainingBytes >= 8) + { + if (Streams.ReadFully(defIn, buf, 0, 8) != 8) + throw new EndOfStreamException("EOF encountered in middle of BMPString"); + + str[stringPos ] = (char)((buf[0] << 8) | (buf[1] & 0xFF)); + str[stringPos + 1] = (char)((buf[2] << 8) | (buf[3] & 0xFF)); + str[stringPos + 2] = (char)((buf[4] << 8) | (buf[5] & 0xFF)); + str[stringPos + 3] = (char)((buf[6] << 8) | (buf[7] & 0xFF)); + stringPos += 4; + remainingBytes -= 8; + } + if (remainingBytes > 0) + { + if (Streams.ReadFully(defIn, buf, 0, remainingBytes) != remainingBytes) + throw new EndOfStreamException("EOF encountered in middle of BMPString"); + + int bufPos = 0; + do + { + int b1 = buf[bufPos++] << 8; + int b2 = buf[bufPos++] & 0xFF; + str[stringPos++] = (char)(b1 | b2); + } + while (bufPos < remainingBytes); + } + + if (0 != defIn.Remaining || str.Length != stringPos) + throw new InvalidOperationException(); + + return str; + } + + internal static Asn1Object CreatePrimitiveDerObject( + int tagNo, + DefiniteLengthInputStream defIn, + byte[][] tmpBuffers) + { + switch (tagNo) + { + case Asn1Tags.BmpString: + return new DerBmpString(GetBmpCharBuffer(defIn)); + case Asn1Tags.Boolean: + return DerBoolean.FromOctetString(GetBuffer(defIn, tmpBuffers)); + case Asn1Tags.Enumerated: + return DerEnumerated.FromOctetString(GetBuffer(defIn, tmpBuffers)); + case Asn1Tags.ObjectIdentifier: + // TODO Ideally only clone if we used a buffer + return DerObjectIdentifier.CreatePrimitive(GetBuffer(defIn, tmpBuffers), true); + } + + byte[] bytes = defIn.ToArray(); + + switch (tagNo) + { + case Asn1Tags.BitString: + return DerBitString.CreatePrimitive(bytes); + case Asn1Tags.GeneralizedTime: + return new DerGeneralizedTime(bytes); + case Asn1Tags.GeneralString: + return new DerGeneralString(bytes); + case Asn1Tags.GraphicString: + return new DerGraphicString(bytes); + case Asn1Tags.IA5String: + return new DerIA5String(bytes); + case Asn1Tags.Integer: + return new DerInteger(bytes, false); + case Asn1Tags.Null: + { + if (0 != bytes.Length) + throw new InvalidOperationException("malformed NULL encoding encountered"); + + return DerNull.Instance; + } + case Asn1Tags.NumericString: + return new DerNumericString(bytes); + case Asn1Tags.OctetString: + return new DerOctetString(bytes); + case Asn1Tags.PrintableString: + return new DerPrintableString(bytes); + case Asn1Tags.T61String: + return new DerT61String(bytes); + case Asn1Tags.UniversalString: + return new DerUniversalString(bytes); + case Asn1Tags.UtcTime: + return new DerUtcTime(bytes); + case Asn1Tags.Utf8String: + return new DerUtf8String(bytes); + case Asn1Tags.VideotexString: + return new DerVideotexString(bytes); + case Asn1Tags.VisibleString: + return new DerVisibleString(bytes); + default: + throw new IOException("unknown tag " + tagNo + " encountered"); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1InputStream.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1InputStream.cs.meta new file mode 100644 index 0000000..6caa769 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1InputStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 199ac2c48b106b948b07d47bda02862e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1Null.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1Null.cs new file mode 100644 index 0000000..d54019f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1Null.cs @@ -0,0 +1,18 @@ +namespace Org.BouncyCastle.Asn1 +{ + /** + * A Null object. + */ + public abstract class Asn1Null + : Asn1Object + { + internal Asn1Null() + { + } + + public override string ToString() + { + return "NULL"; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1Null.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1Null.cs.meta new file mode 100644 index 0000000..a1360ba --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1Null.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2ed63eace347c7640ac429b03e20bbaa +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1Object.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1Object.cs new file mode 100644 index 0000000..415c0a7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1Object.cs @@ -0,0 +1,82 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Asn1 +{ + public abstract class Asn1Object + : Asn1Encodable + { + public override void EncodeTo(Stream output) + { + Asn1OutputStream.Create(output).WriteObject(this); + } + + public override void EncodeTo(Stream output, string encoding) + { + Asn1OutputStream.Create(output, encoding).WriteObject(this); + } + + /// Create a base ASN.1 object from a byte array. + /// The byte array to parse. + /// The base ASN.1 object represented by the byte array. + /// + /// If there is a problem parsing the data, or parsing an object did not exhaust the available data. + /// + public static Asn1Object FromByteArray( + byte[] data) + { + try + { + MemoryStream input = new MemoryStream(data, false); + Asn1InputStream asn1 = new Asn1InputStream(input, data.Length); + Asn1Object result = asn1.ReadObject(); + if (input.Position != input.Length) + throw new IOException("extra data found after object"); + return result; + } + catch (InvalidCastException) + { + throw new IOException("cannot recognise object in byte array"); + } + } + + /// Read a base ASN.1 object from a stream. + /// The stream to parse. + /// The base ASN.1 object represented by the byte array. + /// If there is a problem parsing the data. + public static Asn1Object FromStream( + Stream inStr) + { + try + { + return new Asn1InputStream(inStr).ReadObject(); + } + catch (InvalidCastException) + { + throw new IOException("cannot recognise object in stream"); + } + } + + public sealed override Asn1Object ToAsn1Object() + { + return this; + } + + internal abstract int EncodedLength(bool withID); + + internal abstract void Encode(Asn1OutputStream asn1Out, bool withID); + + protected abstract bool Asn1Equals(Asn1Object asn1Object); + protected abstract int Asn1GetHashCode(); + + internal bool CallAsn1Equals(Asn1Object obj) + { + return Asn1Equals(obj); + } + + internal int CallAsn1GetHashCode() + { + return Asn1GetHashCode(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1Object.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1Object.cs.meta new file mode 100644 index 0000000..ef7732f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1Object.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b5a75b4db14695d4f99b8dbcde0910f8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1OctetString.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1OctetString.cs new file mode 100644 index 0000000..83156e0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1OctetString.cs @@ -0,0 +1,129 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Asn1 +{ + public abstract class Asn1OctetString + : Asn1Object, Asn1OctetStringParser + { + internal static readonly byte[] EmptyOctets = new byte[0]; + + internal byte[] str; + + /** + * return an Octet string from a tagged object. + * + * @param obj the tagged object holding the object we want. + * @param explicitly true if the object is meant to be explicitly + * tagged false otherwise. + * @exception ArgumentException if the tagged object cannot + * be converted. + */ + public static Asn1OctetString GetInstance( + Asn1TaggedObject obj, + bool isExplicit) + { + Asn1Object o = obj.GetObject(); + + if (isExplicit || o is Asn1OctetString) + { + return GetInstance(o); + } + + return BerOctetString.FromSequence(Asn1Sequence.GetInstance(o)); + } + + /** + * return an Octet string from the given object. + * + * @param obj the object we want converted. + * @exception ArgumentException if the object cannot be converted. + */ + public static Asn1OctetString GetInstance(object obj) + { + if (obj == null || obj is Asn1OctetString) + { + return (Asn1OctetString)obj; + } + else if (obj is byte[]) + { + try + { + return GetInstance(FromByteArray((byte[])obj)); + } + catch (IOException e) + { + throw new ArgumentException("failed to construct OCTET STRING from byte[]: " + e.Message); + } + } + // TODO: this needs to be deleted in V2 + else if (obj is Asn1TaggedObject) + { + return GetInstance(((Asn1TaggedObject)obj).GetObject()); + } + else if (obj is Asn1Encodable) + { + Asn1Object primitive = ((Asn1Encodable)obj).ToAsn1Object(); + + if (primitive is Asn1OctetString) + { + return (Asn1OctetString)primitive; + } + } + + throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj)); + } + + /** + * @param string the octets making up the octet string. + */ + internal Asn1OctetString( + byte[] str) + { + if (str == null) + throw new ArgumentNullException("str"); + + this.str = str; + } + + public Stream GetOctetStream() + { + return new MemoryStream(str, false); + } + + public Asn1OctetStringParser Parser + { + get { return this; } + } + + public virtual byte[] GetOctets() + { + return str; + } + + protected override int Asn1GetHashCode() + { + return Arrays.GetHashCode(GetOctets()); + } + + protected override bool Asn1Equals( + Asn1Object asn1Object) + { + DerOctetString other = asn1Object as DerOctetString; + + if (other == null) + return false; + + return Arrays.AreEqual(GetOctets(), other.GetOctets()); + } + + public override string ToString() + { + return "#" + Hex.ToHexString(str); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1OctetString.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1OctetString.cs.meta new file mode 100644 index 0000000..d742531 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1OctetString.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 36af04e66283da740aef321bac06d641 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1OutputStream.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1OutputStream.cs new file mode 100644 index 0000000..f1e9aec --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1OutputStream.cs @@ -0,0 +1,233 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Asn1 +{ + public class Asn1OutputStream + : DerOutputStream + { + public static Asn1OutputStream Create(Stream output) + { + return new Asn1OutputStream(output); + } + + public static Asn1OutputStream Create(Stream output, string encoding) + { + if (Asn1Encodable.Der.Equals(encoding)) + { + return new DerOutputStreamNew(output); + } + else + { + return new Asn1OutputStream(output); + } + } + + [Obsolete("Use static Create method(s)")] + public Asn1OutputStream(Stream os) + : base(os) + { + } + + public override void WriteObject(Asn1Encodable encodable) + { + if (null == encodable) + throw new IOException("null object detected"); + + WritePrimitive(encodable.ToAsn1Object(), true); + FlushInternal(); + } + + public override void WriteObject(Asn1Object primitive) + { + if (null == primitive) + throw new IOException("null object detected"); + + WritePrimitive(primitive, true); + FlushInternal(); + } + + internal void FlushInternal() + { + // Placeholder to support future internal buffering + } + + internal virtual bool IsBer + { + get { return true; } + } + + internal void WriteDL(int length) + { + if (length < 128) + { + WriteByte((byte)length); + } + else + { + byte[] stack = new byte[5]; + int pos = stack.Length; + + do + { + stack[--pos] = (byte)length; + length >>= 8; + } + while (length > 0); + + int count = stack.Length - pos; + stack[--pos] = (byte)(0x80 | count); + + Write(stack, pos, count + 1); + } + } + + internal virtual void WriteElements(Asn1Encodable[] elements) + { + for (int i = 0, count = elements.Length; i < count; ++i) + { + elements[i].ToAsn1Object().Encode(this, true); + } + } + + internal void WriteEncodingDL(bool withID, int identifier, byte contents) + { + WriteIdentifier(withID, identifier); + WriteDL(1); + WriteByte(contents); + } + + internal void WriteEncodingDL(bool withID, int identifier, byte[] contents) + { + WriteIdentifier(withID, identifier); + WriteDL(contents.Length); + Write(contents, 0, contents.Length); + } + + internal void WriteEncodingDL(bool withID, int identifier, byte[] contents, int contentsOff, int contentsLen) + { + WriteIdentifier(withID, identifier); + WriteDL(contentsLen); + Write(contents, contentsOff, contentsLen); + } + + internal void WriteEncodingDL(bool withID, int identifier, byte contentsPrefix, byte[] contents, + int contentsOff, int contentsLen) + { + WriteIdentifier(withID, identifier); + WriteDL(1 + contentsLen); + WriteByte(contentsPrefix); + Write(contents, contentsOff, contentsLen); + } + + internal void WriteEncodingDL(bool withID, int identifier, byte[] contents, int contentsOff, int contentsLen, + byte contentsSuffix) + { + WriteIdentifier(withID, identifier); + WriteDL(contentsLen + 1); + Write(contents, contentsOff, contentsLen); + WriteByte(contentsSuffix); + } + + internal void WriteEncodingDL(bool withID, int flags, int tag, byte[] contents) + { + WriteIdentifier(withID, flags, tag); + WriteDL(contents.Length); + Write(contents, 0, contents.Length); + } + + internal void WriteEncodingIL(bool withID, int identifier, Asn1Encodable[] elements) + { + WriteIdentifier(withID, identifier); + WriteByte(0x80); + WriteElements(elements); + WriteByte(0x00); + WriteByte(0x00); + } + + internal void WriteIdentifier(bool withID, int identifier) + { + if (withID) + { + WriteByte((byte)identifier); + } + } + + internal void WriteIdentifier(bool withID, int flags, int tag) + { + if (!withID) + { + // Don't write the identifier + } + else if (tag < 31) + { + WriteByte((byte)(flags | tag)); + } + else + { + byte[] stack = new byte[6]; + int pos = stack.Length; + + stack[--pos] = (byte)(tag & 0x7F); + while (tag > 127) + { + tag >>= 7; + stack[--pos] = (byte)(tag & 0x7F | 0x80); + } + + stack[--pos] = (byte)(flags | 0x1F); + + Write(stack, pos, stack.Length - pos); + } + } + + internal virtual void WritePrimitive(Asn1Object primitive, bool withID) + { + primitive.Encode(this, withID); + } + + internal virtual void WritePrimitives(Asn1Object[] primitives) + { + for (int i = 0, count = primitives.Length; i < count; ++i) + { + WritePrimitive(primitives[i], true); + } + } + + internal static int GetLengthOfDL(int dl) + { + if (dl < 128) + return 1; + + int length = 2; + while ((dl >>= 8) > 0) + { + ++length; + } + return length; + } + + internal static int GetLengthOfEncodingDL(bool withID, int contentsLength) + { + return (withID ? 1 : 0) + GetLengthOfDL(contentsLength) + contentsLength; + } + + internal static int GetLengthOfEncodingDL(bool withID, int tag, int contentsLength) + { + return (withID ? GetLengthOfIdentifier(tag) : 0) + GetLengthOfDL(contentsLength) + contentsLength; + } + + internal static int GetLengthOfIdentifier(int tag) + { + if (tag < 31) + return 1; + + int length = 2; + while ((tag >>= 7) > 0) + { + ++length; + } + return length; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1OutputStream.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1OutputStream.cs.meta new file mode 100644 index 0000000..d45ca00 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1OutputStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 80ee90d5347ec19479625ac0deb5dcaf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1ParsingException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1ParsingException.cs new file mode 100644 index 0000000..84cdb78 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1ParsingException.cs @@ -0,0 +1,29 @@ +using System; + +namespace Org.BouncyCastle.Asn1 +{ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE) + [Serializable] +#endif + public class Asn1ParsingException + : InvalidOperationException + { + public Asn1ParsingException() + : base() + { + } + + public Asn1ParsingException( + string message) + : base(message) + { + } + + public Asn1ParsingException( + string message, + Exception exception) + : base(message, exception) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1ParsingException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1ParsingException.cs.meta new file mode 100644 index 0000000..3c5a903 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1ParsingException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3b8425126249e7849aa76072c654735f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1Sequence.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1Sequence.cs new file mode 100644 index 0000000..286b731 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1Sequence.cs @@ -0,0 +1,252 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Asn1 +{ + public abstract class Asn1Sequence + : Asn1Object, IEnumerable + { + // NOTE: Only non-readonly to support LazyDerSequence + internal Asn1Encodable[] elements; + + /** + * return an Asn1Sequence from the given object. + * + * @param obj the object we want converted. + * @exception ArgumentException if the object cannot be converted. + */ + public static Asn1Sequence GetInstance( + object obj) + { + if (obj == null || obj is Asn1Sequence) + { + return (Asn1Sequence)obj; + } + else if (obj is Asn1SequenceParser) + { + return GetInstance(((Asn1SequenceParser)obj).ToAsn1Object()); + } + else if (obj is byte[]) + { + try + { + return GetInstance(FromByteArray((byte[])obj)); + } + catch (IOException e) + { + throw new ArgumentException("failed to construct sequence from byte[]: " + e.Message); + } + } + else if (obj is Asn1Encodable) + { + Asn1Object primitive = ((Asn1Encodable)obj).ToAsn1Object(); + + if (primitive is Asn1Sequence) + { + return (Asn1Sequence)primitive; + } + } + + throw new ArgumentException("Unknown object in GetInstance: " + Platform.GetTypeName(obj), "obj"); + } + + /** + * Return an ASN1 sequence from a tagged object. There is a special + * case here, if an object appears to have been explicitly tagged on + * reading but we were expecting it to be implicitly tagged in the + * normal course of events it indicates that we lost the surrounding + * sequence - so we need to add it back (this will happen if the tagged + * object is a sequence that contains other sequences). If you are + * dealing with implicitly tagged sequences you really should + * be using this method. + * + * @param obj the tagged object. + * @param explicitly true if the object is meant to be explicitly tagged, + * false otherwise. + * @exception ArgumentException if the tagged object cannot + * be converted. + */ + public static Asn1Sequence GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + Asn1Object inner = obj.GetObject(); + + if (explicitly) + { + if (!obj.IsExplicit()) + throw new ArgumentException("object implicit - explicit expected."); + + return (Asn1Sequence) inner; + } + + // + // constructed object which appears to be explicitly tagged + // when it should be implicit means we have to add the + // surrounding sequence. + // + if (obj.IsExplicit()) + { + if (obj is BerTaggedObject) + { + return new BerSequence(inner); + } + + return new DerSequence(inner); + } + + if (inner is Asn1Sequence) + { + return (Asn1Sequence) inner; + } + + throw new ArgumentException("Unknown object in GetInstance: " + Platform.GetTypeName(obj), "obj"); + } + + protected internal Asn1Sequence() + { + this.elements = Asn1EncodableVector.EmptyElements; + } + + protected internal Asn1Sequence(Asn1Encodable element) + { + if (null == element) + throw new ArgumentNullException("element"); + + this.elements = new Asn1Encodable[]{ element }; + } + + protected internal Asn1Sequence(params Asn1Encodable[] elements) + { + if (Arrays.IsNullOrContainsNull(elements)) + throw new NullReferenceException("'elements' cannot be null, or contain null"); + + this.elements = Asn1EncodableVector.CloneElements(elements); + } + + protected internal Asn1Sequence(Asn1EncodableVector elementVector) + { + if (null == elementVector) + throw new ArgumentNullException("elementVector"); + + this.elements = elementVector.TakeElements(); + } + + public virtual IEnumerator GetEnumerator() + { + return elements.GetEnumerator(); + } + + private class Asn1SequenceParserImpl + : Asn1SequenceParser + { + private readonly Asn1Sequence outer; + private readonly int max; + private int index; + + public Asn1SequenceParserImpl( + Asn1Sequence outer) + { + this.outer = outer; + this.max = outer.Count; + } + + public IAsn1Convertible ReadObject() + { + if (index == max) + return null; + + Asn1Encodable obj = outer[index++]; + + if (obj is Asn1Sequence) + return ((Asn1Sequence)obj).Parser; + + if (obj is Asn1Set) + return ((Asn1Set)obj).Parser; + + // NB: Asn1OctetString implements Asn1OctetStringParser directly +// if (obj is Asn1OctetString) +// return ((Asn1OctetString)obj).Parser; + + return obj; + } + + public Asn1Object ToAsn1Object() + { + return outer; + } + } + + public virtual Asn1SequenceParser Parser + { + get { return new Asn1SequenceParserImpl(this); } + } + + /** + * return the object at the sequence position indicated by index. + * + * @param index the sequence number (starting at zero) of the object + * @return the object at the sequence position indicated by index. + */ + public virtual Asn1Encodable this[int index] + { + get { return elements[index]; } + } + + public virtual int Count + { + get { return elements.Length; } + } + + public virtual Asn1Encodable[] ToArray() + { + return Asn1EncodableVector.CloneElements(elements); + } + + protected override int Asn1GetHashCode() + { + //return Arrays.GetHashCode(elements); + int i = elements.Length; + int hc = i + 1; + + while (--i >= 0) + { + hc *= 257; + hc ^= elements[i].ToAsn1Object().CallAsn1GetHashCode(); + } + + return hc; + } + + protected override bool Asn1Equals(Asn1Object asn1Object) + { + Asn1Sequence that = asn1Object as Asn1Sequence; + if (null == that) + return false; + + int count = this.Count; + if (that.Count != count) + return false; + + for (int i = 0; i < count; ++i) + { + Asn1Object o1 = this.elements[i].ToAsn1Object(); + Asn1Object o2 = that.elements[i].ToAsn1Object(); + + if (o1 != o2 && !o1.CallAsn1Equals(o2)) + return false; + } + + return true; + } + + public override string ToString() + { + return CollectionUtilities.ToString(elements); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1Sequence.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1Sequence.cs.meta new file mode 100644 index 0000000..beb9abd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1Sequence.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 63d59aa062cf15a4a9009d057741d90e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1Set.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1Set.cs new file mode 100644 index 0000000..8c6e2f0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1Set.cs @@ -0,0 +1,339 @@ +using System; +using System.Collections; +using System.Diagnostics; +using System.IO; + +#if PORTABLE +using System.Collections.Generic; +using System.Linq; +#endif + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Asn1 +{ + abstract public class Asn1Set + : Asn1Object, IEnumerable + { + // NOTE: Only non-readonly to support LazyDerSet + internal Asn1Encodable[] elements; + + /** + * return an ASN1Set from the given object. + * + * @param obj the object we want converted. + * @exception ArgumentException if the object cannot be converted. + */ + public static Asn1Set GetInstance( + object obj) + { + if (obj == null || obj is Asn1Set) + { + return (Asn1Set)obj; + } + else if (obj is Asn1SetParser) + { + return Asn1Set.GetInstance(((Asn1SetParser)obj).ToAsn1Object()); + } + else if (obj is byte[]) + { + try + { + return Asn1Set.GetInstance(FromByteArray((byte[])obj)); + } + catch (IOException e) + { + throw new ArgumentException("failed to construct set from byte[]: " + e.Message); + } + } + else if (obj is Asn1Encodable) + { + Asn1Object primitive = ((Asn1Encodable)obj).ToAsn1Object(); + + if (primitive is Asn1Set) + { + return (Asn1Set)primitive; + } + } + + throw new ArgumentException("Unknown object in GetInstance: " + Platform.GetTypeName(obj), "obj"); + } + + /** + * Return an ASN1 set from a tagged object. There is a special + * case here, if an object appears to have been explicitly tagged on + * reading but we were expecting it to be implicitly tagged in the + * normal course of events it indicates that we lost the surrounding + * set - so we need to add it back (this will happen if the tagged + * object is a sequence that contains other sequences). If you are + * dealing with implicitly tagged sets you really should + * be using this method. + * + * @param obj the tagged object. + * @param explicitly true if the object is meant to be explicitly tagged + * false otherwise. + * @exception ArgumentException if the tagged object cannot + * be converted. + */ + public static Asn1Set GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + Asn1Object inner = obj.GetObject(); + + if (explicitly) + { + if (!obj.IsExplicit()) + throw new ArgumentException("object implicit - explicit expected."); + + return (Asn1Set) inner; + } + + // + // constructed object which appears to be explicitly tagged + // and it's really implicit means we have to add the + // surrounding sequence. + // + if (obj.IsExplicit()) + { + return new DerSet(inner); + } + + if (inner is Asn1Set) + { + return (Asn1Set) inner; + } + + // + // in this case the parser returns a sequence, convert it + // into a set. + // + if (inner is Asn1Sequence) + { + Asn1EncodableVector v = new Asn1EncodableVector(); + Asn1Sequence s = (Asn1Sequence) inner; + + foreach (Asn1Encodable ae in s) + { + v.Add(ae); + } + + // TODO Should be able to construct set directly from sequence? + return new DerSet(v, false); + } + + throw new ArgumentException("Unknown object in GetInstance: " + Platform.GetTypeName(obj), "obj"); + } + + protected internal Asn1Set() + { + this.elements = Asn1EncodableVector.EmptyElements; + } + + protected internal Asn1Set(Asn1Encodable element) + { + if (null == element) + throw new ArgumentNullException("element"); + + this.elements = new Asn1Encodable[]{ element }; + } + + protected internal Asn1Set(params Asn1Encodable[] elements) + { + if (Arrays.IsNullOrContainsNull(elements)) + throw new NullReferenceException("'elements' cannot be null, or contain null"); + + this.elements = Asn1EncodableVector.CloneElements(elements); + } + + protected internal Asn1Set(Asn1EncodableVector elementVector) + { + if (null == elementVector) + throw new ArgumentNullException("elementVector"); + + this.elements = elementVector.TakeElements(); + } + + public virtual IEnumerator GetEnumerator() + { + return elements.GetEnumerator(); + } + + /** + * return the object at the set position indicated by index. + * + * @param index the set number (starting at zero) of the object + * @return the object at the set position indicated by index. + */ + public virtual Asn1Encodable this[int index] + { + get { return elements[index]; } + } + + public virtual int Count + { + get { return elements.Length; } + } + + public virtual Asn1Encodable[] ToArray() + { + return Asn1EncodableVector.CloneElements(elements); + } + + private class Asn1SetParserImpl + : Asn1SetParser + { + private readonly Asn1Set outer; + private readonly int max; + private int index; + + public Asn1SetParserImpl( + Asn1Set outer) + { + this.outer = outer; + this.max = outer.Count; + } + + public IAsn1Convertible ReadObject() + { + if (index == max) + return null; + + Asn1Encodable obj = outer[index++]; + if (obj is Asn1Sequence) + return ((Asn1Sequence)obj).Parser; + + if (obj is Asn1Set) + return ((Asn1Set)obj).Parser; + + // NB: Asn1OctetString implements Asn1OctetStringParser directly +// if (obj is Asn1OctetString) +// return ((Asn1OctetString)obj).Parser; + + return obj; + } + + public virtual Asn1Object ToAsn1Object() + { + return outer; + } + } + + public Asn1SetParser Parser + { + get { return new Asn1SetParserImpl(this); } + } + + protected override int Asn1GetHashCode() + { + //return Arrays.GetHashCode(elements); + int i = elements.Length; + int hc = i + 1; + + while (--i >= 0) + { + hc *= 257; + hc ^= elements[i].ToAsn1Object().CallAsn1GetHashCode(); + } + + return hc; + } + + protected override bool Asn1Equals(Asn1Object asn1Object) + { + Asn1Set that = asn1Object as Asn1Set; + if (null == that) + return false; + + int count = this.Count; + if (that.Count != count) + return false; + + for (int i = 0; i < count; ++i) + { + Asn1Object o1 = this.elements[i].ToAsn1Object(); + Asn1Object o2 = that.elements[i].ToAsn1Object(); + + if (o1 != o2 && !o1.CallAsn1Equals(o2)) + return false; + } + + return true; + } + + protected internal void Sort() + { + if (elements.Length < 2) + return; + +#if PORTABLE + this.elements = elements + .Cast() + .Select(a => new { Item = a, Key = a.GetEncoded(Asn1Encodable.Der) }) + .OrderBy(t => t.Key, new DerComparer()) + .Select(t => t.Item) + .ToArray(); +#else + int count = elements.Length; + byte[][] keys = new byte[count][]; + for (int i = 0; i < count; ++i) + { + keys[i] = elements[i].GetEncoded(Der); + } + Array.Sort(keys, elements, new DerComparer()); +#endif + } + + public override string ToString() + { + return CollectionUtilities.ToString(elements); + } + +#if PORTABLE + private class DerComparer + : IComparer + { + public int Compare(byte[] x, byte[] y) + { + byte[] a = x, b = y; +#else + private class DerComparer + : IComparer + { + public int Compare(object x, object y) + { + byte[] a = (byte[])x, b = (byte[])y; +#endif + Debug.Assert(a.Length >= 2 && b.Length >= 2); + + /* + * NOTE: Set elements in DER encodings are ordered first according to their tags (class and + * number); the CONSTRUCTED bit is not part of the tag. + * + * For SET-OF, this is unimportant. All elements have the same tag and DER requires them to + * either all be in constructed form or all in primitive form, according to that tag. The + * elements are effectively ordered according to their content octets. + * + * For SET, the elements will have distinct tags, and each will be in constructed or + * primitive form accordingly. Failing to ignore the CONSTRUCTED bit could therefore lead to + * ordering inversions. + */ + int a0 = a[0] & ~Asn1Tags.Constructed; + int b0 = b[0] & ~Asn1Tags.Constructed; + if (a0 != b0) + return a0 < b0 ? -1 : 1; + + int len = System.Math.Min(a.Length, b.Length); + for (int i = 1; i < len; ++i) + { + byte ai = a[i], bi = b[i]; + if (ai != bi) + return ai < bi ? -1 : 1; + } + Debug.Assert(a.Length == b.Length); + return 0; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1Set.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1Set.cs.meta new file mode 100644 index 0000000..2c88d4d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1Set.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a3d1ef4504948a240b7e2861fb17e9fc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1TaggedObject.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1TaggedObject.cs new file mode 100644 index 0000000..14b1bc6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1TaggedObject.cs @@ -0,0 +1,188 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + /** + * ASN.1 TaggedObject - in ASN.1 notation this is any object preceded by + * a [n] where n is some number - these are assumed to follow the construction + * rules (as with sequences). + */ + public abstract class Asn1TaggedObject + : Asn1Object, Asn1TaggedObjectParser + { + internal static bool IsConstructed(bool isExplicit, Asn1Object obj) + { + if (isExplicit || obj is Asn1Sequence || obj is Asn1Set) + return true; + Asn1TaggedObject tagged = obj as Asn1TaggedObject; + if (tagged == null) + return false; + return IsConstructed(tagged.IsExplicit(), tagged.GetObject()); + } + + internal int tagNo; +// internal bool empty; + internal bool explicitly = true; + internal Asn1Encodable obj; + + static public Asn1TaggedObject GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + if (explicitly) + { + return GetInstance(obj.GetObject()); + } + + throw new ArgumentException("implicitly tagged tagged object"); + } + + static public Asn1TaggedObject GetInstance( + object obj) + { + if (obj == null || obj is Asn1TaggedObject) + { + return (Asn1TaggedObject) obj; + } + + throw new ArgumentException("Unknown object in GetInstance: " + Platform.GetTypeName(obj), "obj"); + } + + /** + * @param tagNo the tag number for this object. + * @param obj the tagged object. + */ + protected Asn1TaggedObject( + int tagNo, + Asn1Encodable obj) + { + this.explicitly = true; + this.tagNo = tagNo; + this.obj = obj; + } + + /** + * @param explicitly true if the object is explicitly tagged. + * @param tagNo the tag number for this object. + * @param obj the tagged object. + */ + protected Asn1TaggedObject( + bool explicitly, + int tagNo, + Asn1Encodable obj) + { + // IAsn1Choice marker interface 'insists' on explicit tagging + this.explicitly = explicitly || (obj is IAsn1Choice); + this.tagNo = tagNo; + this.obj = obj; + } + + protected override bool Asn1Equals( + Asn1Object asn1Object) + { + Asn1TaggedObject other = asn1Object as Asn1TaggedObject; + + if (other == null) + return false; + + return this.tagNo == other.tagNo +// && this.empty == other.empty + && this.explicitly == other.explicitly // TODO Should this be part of equality? + && Platform.Equals(GetObject(), other.GetObject()); + } + + protected override int Asn1GetHashCode() + { + int code = tagNo.GetHashCode(); + + // TODO: actually this is wrong - the problem is that a re-encoded + // object may end up with a different hashCode due to implicit + // tagging. As implicit tagging is ambiguous if a sequence is involved + // it seems the only correct method for both equals and hashCode is to + // compare the encodings... +// code ^= explicitly.GetHashCode(); + + if (obj != null) + { + code ^= obj.GetHashCode(); + } + + return code; + } + + public int TagNo + { + get { return tagNo; } + } + + /** + * return whether or not the object may be explicitly tagged. + *

+ * Note: if the object has been read from an input stream, the only + * time you can be sure if isExplicit is returning the true state of + * affairs is if it returns false. An implicitly tagged object may appear + * to be explicitly tagged, so you need to understand the context under + * which the reading was done as well, see GetObject below.

+ */ + public bool IsExplicit() + { + return explicitly; + } + + public bool IsEmpty() + { + return false; //empty; + } + + /** + * return whatever was following the tag. + *

+ * Note: tagged objects are generally context dependent if you're + * trying to extract a tagged object you should be going via the + * appropriate GetInstance method.

+ */ + public Asn1Object GetObject() + { + if (obj != null) + { + return obj.ToAsn1Object(); + } + + return null; + } + + /** + * Return the object held in this tagged object as a parser assuming it has + * the type of the passed in tag. If the object doesn't have a parser + * associated with it, the base object is returned. + */ + public IAsn1Convertible GetObjectParser( + int tag, + bool isExplicit) + { + switch (tag) + { + case Asn1Tags.Set: + return Asn1Set.GetInstance(this, isExplicit).Parser; + case Asn1Tags.Sequence: + return Asn1Sequence.GetInstance(this, isExplicit).Parser; + case Asn1Tags.OctetString: + return Asn1OctetString.GetInstance(this, isExplicit).Parser; + } + + if (isExplicit) + { + return GetObject(); + } + + throw Platform.CreateNotImplementedException("implicit tagging for tag: " + tag); + } + + public override string ToString() + { + return "[" + tagNo + "]" + obj; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1TaggedObject.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1TaggedObject.cs.meta new file mode 100644 index 0000000..c56570d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1TaggedObject.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 91d08cbace40caa48a9115ed7cf01e69 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1Tags.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1Tags.cs new file mode 100644 index 0000000..692acdf --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1Tags.cs @@ -0,0 +1,49 @@ +using System; + +namespace Org.BouncyCastle.Asn1 +{ + public class Asn1Tags + { + public const int Boolean = 0x01; + public const int Integer = 0x02; + public const int BitString = 0x03; + public const int OctetString = 0x04; + public const int Null = 0x05; + public const int ObjectIdentifier = 0x06; + public const int ObjectDescriptor = 0x07; + public const int External = 0x08; + public const int Real = 0x09; + public const int Enumerated = 0x0a; + public const int EmbeddedPdv = 0x0b; + public const int Utf8String = 0x0c; + public const int RelativeOid = 0x0d; + // NOTE: 14-15 are reserved. + public const int Sequence = 0x10; + public const int SequenceOf = 0x10; // for completeness + public const int Set = 0x11; + public const int SetOf = 0x11; // for completeness + + public const int NumericString = 0x12; + public const int PrintableString = 0x13; + public const int T61String = 0x14; + public const int VideotexString = 0x15; + public const int IA5String = 0x16; + public const int UtcTime = 0x17; + public const int GeneralizedTime = 0x18; + public const int GraphicString = 0x19; + public const int VisibleString = 0x1a; + public const int GeneralString = 0x1b; + public const int UniversalString = 0x1c; + public const int UnrestrictedString = 0x1d; + public const int BmpString = 0x1e; + + public const int Constructed = 0x20; + + public const int Universal = 0x00; + public const int Application = 0x40; + [Obsolete("Use 'ContextSpecific' instead")] + public const int Tagged = 0x80; + public const int ContextSpecific = 0x80; + public const int Private = 0xC0; + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1Tags.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1Tags.cs.meta new file mode 100644 index 0000000..72d0960 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/Asn1Tags.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 94a4bc8f66c0ea7438044f04cb838ff0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BERBitString.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BERBitString.cs new file mode 100644 index 0000000..1756ee9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BERBitString.cs @@ -0,0 +1,199 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + public class BerBitString + : DerBitString + { + private const int DefaultSegmentLimit = 1000; + + internal static byte[] FlattenBitStrings(DerBitString[] bitStrings) + { + int count = bitStrings.Length; + switch (count) + { + case 0: + // No bits + return new byte[]{ 0 }; + case 1: + return bitStrings[0].contents; + default: + { + int last = count - 1, totalLength = 0; + for (int i = 0; i < last; ++i) + { + byte[] elementContents = bitStrings[i].contents; + if (elementContents[0] != 0) + throw new ArgumentException("only the last nested bitstring can have padding", "bitStrings"); + + totalLength += elementContents.Length - 1; + } + + // Last one can have padding + byte[] lastElementContents = bitStrings[last].contents; + byte padBits = lastElementContents[0]; + totalLength += lastElementContents.Length; + + byte[] contents = new byte[totalLength]; + contents[0] = padBits; + + int pos = 1; + for (int i = 0; i < count; ++i) + { + byte[] elementContents = bitStrings[i].contents; + int length = elementContents.Length - 1; + Array.Copy(elementContents, 1, contents, pos, length); + pos += length; + } + + Debug.Assert(pos == totalLength); + return contents; + } + } + } + + private readonly int segmentLimit; + private readonly DerBitString[] elements; + + public BerBitString(byte data, int padBits) + : base(data, padBits) + { + this.elements = null; + this.segmentLimit = DefaultSegmentLimit; + } + + public BerBitString(byte[] data) + : this(data, 0) + { + } + + public BerBitString(byte[] data, int padBits) + : this(data, padBits, DefaultSegmentLimit) + { + } + + public BerBitString(byte[] data, int padBits, int segmentLimit) + : base(data, padBits) + { + this.elements = null; + this.segmentLimit = segmentLimit; + } + + public BerBitString(int namedBits) + : base(namedBits) + { + this.elements = null; + this.segmentLimit = DefaultSegmentLimit; + } + + public BerBitString(Asn1Encodable obj) + : this(obj.GetDerEncoded(), 0) + { + } + + public BerBitString(DerBitString[] elements) + : this(elements, DefaultSegmentLimit) + { + } + + public BerBitString(DerBitString[] elements, int segmentLimit) + : base(FlattenBitStrings(elements), false) + { + this.elements = elements; + this.segmentLimit = segmentLimit; + } + + internal BerBitString(byte[] contents, bool check) + : base(contents, check) + { + this.elements = null; + this.segmentLimit = DefaultSegmentLimit; + } + + private bool IsConstructed + { + get { return null != elements || contents.Length > segmentLimit; } + } + + internal override int EncodedLength(bool withID) + { + throw Platform.CreateNotImplementedException("BerBitString.EncodedLength"); + + // TODO This depends on knowing it's not DER + //if (!IsConstructed) + // return EncodedLength(withID, contents.Length); + + //int totalLength = withID ? 4 : 3; + + //if (null != elements) + //{ + // for (int i = 0; i < elements.Length; ++i) + // { + // totalLength += elements[i].EncodedLength(true); + // } + //} + //else if (contents.Length < 2) + //{ + // // No bits + //} + //else + //{ + // int extraSegments = (contents.Length - 2) / (segmentLimit - 1); + // totalLength += extraSegments * EncodedLength(true, segmentLimit); + + // int lastSegmentLength = contents.Length - (extraSegments * (segmentLimit - 1)); + // totalLength += EncodedLength(true, lastSegmentLength); + //} + + //return totalLength; + } + + internal override void Encode(Asn1OutputStream asn1Out, bool withID) + { + if (!asn1Out.IsBer) + { + base.Encode(asn1Out, withID); + return; + } + + if (!IsConstructed) + { + Encode(asn1Out, withID, contents, 0, contents.Length); + return; + } + + asn1Out.WriteIdentifier(withID, Asn1Tags.Constructed | Asn1Tags.BitString); + asn1Out.WriteByte(0x80); + + if (null != elements) + { + asn1Out.WritePrimitives(elements); + } + else if (contents.Length < 2) + { + // No bits + } + else + { + byte pad = contents[0]; + int length = contents.Length; + int remaining = length - 1; + int segmentLength = segmentLimit - 1; + + while (remaining > segmentLength) + { + Encode(asn1Out, true, (byte)0, contents, length - remaining, segmentLength); + remaining -= segmentLength; + } + + Encode(asn1Out, true, pad, contents, length - remaining, remaining); + } + + asn1Out.WriteByte(0x00); + asn1Out.WriteByte(0x00); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BERBitString.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BERBitString.cs.meta new file mode 100644 index 0000000..64dca19 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BERBitString.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b1d94cc00cbbd104caa9d50f488a7b7c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BERGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BERGenerator.cs new file mode 100644 index 0000000..e43d9f8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BERGenerator.cs @@ -0,0 +1,106 @@ +using System.IO; + +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Asn1 +{ + public abstract class BerGenerator + : Asn1Generator + { + private bool _tagged = false; + private bool _isExplicit; + private int _tagNo; + + protected BerGenerator( + Stream outStream) + : base(outStream) + { + } + + protected BerGenerator( + Stream outStream, + int tagNo, + bool isExplicit) + : base(outStream) + { + _tagged = true; + _isExplicit = isExplicit; + _tagNo = tagNo; + } + + public override void AddObject(Asn1Encodable obj) + { + obj.EncodeTo(Out); + } + + public override void AddObject(Asn1Object obj) + { + obj.EncodeTo(Out); + } + + public override Stream GetRawOutputStream() + { + return Out; + } + + public override void Close() + { + WriteBerEnd(); + } + + private void WriteHdr( + int tag) + { + Out.WriteByte((byte) tag); + Out.WriteByte(0x80); + } + + protected void WriteBerHeader( + int tag) + { + if (_tagged) + { + int tagNum = _tagNo | Asn1Tags.ContextSpecific; + + if (_isExplicit) + { + WriteHdr(tagNum | Asn1Tags.Constructed); + WriteHdr(tag); + } + else + { + if ((tag & Asn1Tags.Constructed) != 0) + { + WriteHdr(tagNum | Asn1Tags.Constructed); + } + else + { + WriteHdr(tagNum); + } + } + } + else + { + WriteHdr(tag); + } + } + + protected void WriteBerBody( + Stream contentStream) + { + Streams.PipeAll(contentStream, Out); + } + + protected void WriteBerEnd() + { + Out.WriteByte(0x00); + Out.WriteByte(0x00); + + if (_tagged && _isExplicit) // write extra end for tag header + { + Out.WriteByte(0x00); + Out.WriteByte(0x00); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BERGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BERGenerator.cs.meta new file mode 100644 index 0000000..20fb63c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BERGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d7676b2378cbdc44fb33e1ce7a3d5197 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BEROctetStringGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BEROctetStringGenerator.cs new file mode 100644 index 0000000..37e46be --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BEROctetStringGenerator.cs @@ -0,0 +1,137 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Asn1 +{ + public class BerOctetStringGenerator + : BerGenerator + { + public BerOctetStringGenerator(Stream outStream) + : base(outStream) + { + WriteBerHeader(Asn1Tags.Constructed | Asn1Tags.OctetString); + } + + public BerOctetStringGenerator( + Stream outStream, + int tagNo, + bool isExplicit) + : base(outStream, tagNo, isExplicit) + { + WriteBerHeader(Asn1Tags.Constructed | Asn1Tags.OctetString); + } + + public Stream GetOctetOutputStream() + { + return GetOctetOutputStream(new byte[1000]); // limit for CER encoding. + } + + public Stream GetOctetOutputStream( + int bufSize) + { + return bufSize < 1 + ? GetOctetOutputStream() + : GetOctetOutputStream(new byte[bufSize]); + } + + public Stream GetOctetOutputStream( + byte[] buf) + { + return new BufferedBerOctetStream(this, buf); + } + + private class BufferedBerOctetStream + : BaseOutputStream + { + private byte[] _buf; + private int _off; + private readonly BerOctetStringGenerator _gen; + private readonly Asn1OutputStream _derOut; + + internal BufferedBerOctetStream( + BerOctetStringGenerator gen, + byte[] buf) + { + _gen = gen; + _buf = buf; + _off = 0; + _derOut = Asn1OutputStream.Create(_gen.Out, Asn1Encodable.Der); + } + + public override void WriteByte( + byte b) + { + _buf[_off++] = b; + + if (_off == _buf.Length) + { + DerOctetString.Encode(_derOut, true, _buf, 0, _off); + _off = 0; + } + } + + public override void Write(byte[] b, int off, int len) + { + int bufLen = _buf.Length; + int available = bufLen - _off; + if (len < available) + { + Array.Copy(b, off, _buf, _off, len); + _off += len; + return; + } + + int count = 0; + if (_off > 0) + { + Array.Copy(b, off, _buf, _off, available); + count += available; + DerOctetString.Encode(_derOut, true, _buf, 0, bufLen); + } + + int remaining; + while ((remaining = len - count) >= bufLen) + { + DerOctetString.Encode(_derOut, true, b, off + count, bufLen); + count += bufLen; + } + + Array.Copy(b, off + count, _buf, 0, remaining); + this._off = remaining; + } + +#if PORTABLE + protected override void Dispose(bool disposing) + { + if (disposing) + { + if (_off != 0) + { + DerOctetString.Encode(_derOut, true, _buf, 0, _off); + } + + _derOut.FlushInternal(); + + _gen.WriteBerEnd(); + } + base.Dispose(disposing); + } +#else + public override void Close() + { + if (_off != 0) + { + DerOctetString.Encode(_derOut, true, _buf, 0, _off); + } + + _derOut.FlushInternal(); + + _gen.WriteBerEnd(); + base.Close(); + } +#endif + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BEROctetStringGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BEROctetStringGenerator.cs.meta new file mode 100644 index 0000000..47cbefb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BEROctetStringGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 536488de61c485746b65981e2b52da21 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BEROctetStringParser.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BEROctetStringParser.cs new file mode 100644 index 0000000..c8c344e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BEROctetStringParser.cs @@ -0,0 +1,40 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Asn1 +{ + public class BerOctetStringParser + : Asn1OctetStringParser + { + private readonly Asn1StreamParser _parser; + + internal BerOctetStringParser(Asn1StreamParser parser) + { + _parser = parser; + } + + public Stream GetOctetStream() + { + return new ConstructedOctetStream(_parser); + } + + public Asn1Object ToAsn1Object() + { + try + { + return Parse(_parser); + } + catch (IOException e) + { + throw new Asn1ParsingException("IOException converting stream to byte array: " + e.Message, e); + } + } + + internal static BerOctetString Parse(Asn1StreamParser sp) + { + return new BerOctetString(Streams.ReadAll(new ConstructedOctetStream(sp))); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BEROctetStringParser.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BEROctetStringParser.cs.meta new file mode 100644 index 0000000..ccbdb34 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BEROctetStringParser.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 921ab6bbbc76f6e48a5dc0039a1b9a76 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BERSequenceGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BERSequenceGenerator.cs new file mode 100644 index 0000000..5ea2c9b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BERSequenceGenerator.cs @@ -0,0 +1,24 @@ +using System.IO; + +namespace Org.BouncyCastle.Asn1 +{ + public class BerSequenceGenerator + : BerGenerator + { + public BerSequenceGenerator( + Stream outStream) + : base(outStream) + { + WriteBerHeader(Asn1Tags.Constructed | Asn1Tags.Sequence); + } + + public BerSequenceGenerator( + Stream outStream, + int tagNo, + bool isExplicit) + : base(outStream, tagNo, isExplicit) + { + WriteBerHeader(Asn1Tags.Constructed | Asn1Tags.Sequence); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BERSequenceGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BERSequenceGenerator.cs.meta new file mode 100644 index 0000000..93c3f8f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BERSequenceGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8f1d40e593b8e784ba1c55142ee79da2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BERSequenceParser.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BERSequenceParser.cs new file mode 100644 index 0000000..5fa1de8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BERSequenceParser.cs @@ -0,0 +1,30 @@ +using System; + +namespace Org.BouncyCastle.Asn1 +{ + public class BerSequenceParser + : Asn1SequenceParser + { + private readonly Asn1StreamParser _parser; + + internal BerSequenceParser(Asn1StreamParser parser) + { + this._parser = parser; + } + + public IAsn1Convertible ReadObject() + { + return _parser.ReadObject(); + } + + public Asn1Object ToAsn1Object() + { + return Parse(_parser); + } + + internal static BerSequence Parse(Asn1StreamParser sp) + { + return new BerSequence(sp.ReadVector()); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BERSequenceParser.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BERSequenceParser.cs.meta new file mode 100644 index 0000000..bb1d987 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BERSequenceParser.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5f588d19861c98d4e9ed4f895a723f6c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BERSetGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BERSetGenerator.cs new file mode 100644 index 0000000..72b1f90 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BERSetGenerator.cs @@ -0,0 +1,24 @@ +using System.IO; + +namespace Org.BouncyCastle.Asn1 +{ + public class BerSetGenerator + : BerGenerator + { + public BerSetGenerator( + Stream outStream) + : base(outStream) + { + WriteBerHeader(Asn1Tags.Constructed | Asn1Tags.Set); + } + + public BerSetGenerator( + Stream outStream, + int tagNo, + bool isExplicit) + : base(outStream, tagNo, isExplicit) + { + WriteBerHeader(Asn1Tags.Constructed | Asn1Tags.Set); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BERSetGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BERSetGenerator.cs.meta new file mode 100644 index 0000000..db4c4c4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BERSetGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d9994cc76e97cc74198424ef14ed442d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BERSetParser.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BERSetParser.cs new file mode 100644 index 0000000..9da964c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BERSetParser.cs @@ -0,0 +1,30 @@ +using System; + +namespace Org.BouncyCastle.Asn1 +{ + public class BerSetParser + : Asn1SetParser + { + private readonly Asn1StreamParser _parser; + + internal BerSetParser(Asn1StreamParser parser) + { + this._parser = parser; + } + + public IAsn1Convertible ReadObject() + { + return _parser.ReadObject(); + } + + public Asn1Object ToAsn1Object() + { + return Parse(_parser); + } + + internal static BerSet Parse(Asn1StreamParser sp) + { + return new BerSet(sp.ReadVector()); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BERSetParser.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BERSetParser.cs.meta new file mode 100644 index 0000000..2bc57ff --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BERSetParser.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4f109a49e2203b04f81ef4dfe7cf9c92 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BERTaggedObjectParser.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BERTaggedObjectParser.cs new file mode 100644 index 0000000..354437a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BERTaggedObjectParser.cs @@ -0,0 +1,71 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + public class BerTaggedObjectParser + : Asn1TaggedObjectParser + { + private bool _constructed; + private int _tagNumber; + private Asn1StreamParser _parser; + + [Obsolete] + internal BerTaggedObjectParser( + int baseTag, + int tagNumber, + Stream contentStream) + : this((baseTag & Asn1Tags.Constructed) != 0, tagNumber, new Asn1StreamParser(contentStream)) + { + } + + internal BerTaggedObjectParser( + bool constructed, + int tagNumber, + Asn1StreamParser parser) + { + _constructed = constructed; + _tagNumber = tagNumber; + _parser = parser; + } + + public bool IsConstructed + { + get { return _constructed; } + } + + public int TagNo + { + get { return _tagNumber; } + } + + public IAsn1Convertible GetObjectParser( + int tag, + bool isExplicit) + { + if (isExplicit) + { + if (!_constructed) + throw new IOException("Explicit tags must be constructed (see X.690 8.14.2)"); + + return _parser.ReadObject(); + } + + return _parser.ReadImplicit(_constructed, tag); + } + + public Asn1Object ToAsn1Object() + { + try + { + return _parser.ReadTaggedObject(_constructed, _tagNumber); + } + catch (IOException e) + { + throw new Asn1ParsingException(e.Message); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BERTaggedObjectParser.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BERTaggedObjectParser.cs.meta new file mode 100644 index 0000000..73bd853 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BERTaggedObjectParser.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9a74a610454321349a517ec7ce850b5e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BerApplicationSpecific.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BerApplicationSpecific.cs new file mode 100644 index 0000000..65fbecb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BerApplicationSpecific.cs @@ -0,0 +1,15 @@ +using System; + +namespace Org.BouncyCastle.Asn1 +{ + public class BerApplicationSpecific + : DerApplicationSpecific + { + public BerApplicationSpecific( + int tagNo, + Asn1EncodableVector vec) + : base(tagNo, vec) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BerApplicationSpecific.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BerApplicationSpecific.cs.meta new file mode 100644 index 0000000..a25169e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BerApplicationSpecific.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 200c3f135bcdf4c4bb55b0d918e4a17d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BerApplicationSpecificParser.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BerApplicationSpecificParser.cs new file mode 100644 index 0000000..7d2c4b3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BerApplicationSpecificParser.cs @@ -0,0 +1,29 @@ +using System; + +namespace Org.BouncyCastle.Asn1 +{ + public class BerApplicationSpecificParser + : IAsn1ApplicationSpecificParser + { + private readonly int tag; + private readonly Asn1StreamParser parser; + + internal BerApplicationSpecificParser( + int tag, + Asn1StreamParser parser) + { + this.tag = tag; + this.parser = parser; + } + + public IAsn1Convertible ReadObject() + { + return parser.ReadObject(); + } + + public Asn1Object ToAsn1Object() + { + return new BerApplicationSpecific(tag, parser.ReadVector()); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BerApplicationSpecificParser.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BerApplicationSpecificParser.cs.meta new file mode 100644 index 0000000..0248df8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BerApplicationSpecificParser.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c88d81786daa99840a669e71a372e62b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BerNull.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BerNull.cs new file mode 100644 index 0000000..90067d4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BerNull.cs @@ -0,0 +1,20 @@ +using System; + +namespace Org.BouncyCastle.Asn1 +{ + /** + * A BER Null object. + */ + [Obsolete("Use 'DerNull' instead")] + public class BerNull + : DerNull + { + [Obsolete("Use 'DerNull.Instance' instead")] + public static new readonly BerNull Instance = new BerNull(); + + private BerNull() + : base() + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BerNull.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BerNull.cs.meta new file mode 100644 index 0000000..88e50a3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BerNull.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bc73f7f2395bb86418ecab317c59c44b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BerOctetString.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BerOctetString.cs new file mode 100644 index 0000000..9963819 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BerOctetString.cs @@ -0,0 +1,239 @@ +using System; +using System.Collections; +using System.Diagnostics; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + public class BerOctetString + : DerOctetString, IEnumerable + { + private const int DefaultSegmentLimit = 1000; + + public static BerOctetString FromSequence(Asn1Sequence seq) + { + int count = seq.Count; + Asn1OctetString[] v = new Asn1OctetString[count]; + for (int i = 0; i < count; ++i) + { + v[i] = GetInstance(seq[i]); + } + return new BerOctetString(v); + } + + internal static byte[] FlattenOctetStrings(Asn1OctetString[] octetStrings) + { + int count = octetStrings.Length; + switch (count) + { + case 0: + return EmptyOctets; + case 1: + return octetStrings[0].str; + default: + { + int totalOctets = 0; + for (int i = 0; i < count; ++i) + { + totalOctets += octetStrings[i].str.Length; + } + + byte[] str = new byte[totalOctets]; + int pos = 0; + for (int i = 0; i < count; ++i) + { + byte[] octets = octetStrings[i].str; + Array.Copy(octets, 0, str, pos, octets.Length); + pos += octets.Length; + } + + Debug.Assert(pos == totalOctets); + return str; + } + } + } + + private static Asn1OctetString[] ToOctetStringArray(IEnumerable e) + { + IList list = Platform.CreateArrayList(e); + + int count = list.Count; + Asn1OctetString[] v = new Asn1OctetString[count]; + for (int i = 0; i < count; ++i) + { + v[i] = GetInstance(list[i]); + } + return v; + } + + private readonly int segmentLimit; + private readonly Asn1OctetString[] elements; + + [Obsolete("Will be removed")] + public BerOctetString(IEnumerable e) + : this(ToOctetStringArray(e)) + { + } + + public BerOctetString(byte[] str) + : this(str, DefaultSegmentLimit) + { + } + + public BerOctetString(Asn1OctetString[] elements) + : this(elements, DefaultSegmentLimit) + { + } + + public BerOctetString(byte[] str, int segmentLimit) + : this(str, null, segmentLimit) + { + } + + public BerOctetString(Asn1OctetString[] elements, int segmentLimit) + : this(FlattenOctetStrings(elements), elements, segmentLimit) + { + } + + private BerOctetString(byte[] octets, Asn1OctetString[] elements, int segmentLimit) + : base(octets) + { + this.elements = elements; + this.segmentLimit = segmentLimit; + } + + /** + * return the DER octets that make up this string. + */ + public IEnumerator GetEnumerator() + { + if (elements == null) + return new ChunkEnumerator(str, segmentLimit); + + return elements.GetEnumerator(); + } + + [Obsolete("Use GetEnumerator() instead")] + public IEnumerator GetObjects() + { + return GetEnumerator(); + } + + private bool IsConstructed + { + get { return null != elements || str.Length > segmentLimit; } + } + + internal override int EncodedLength(bool withID) + { + throw Platform.CreateNotImplementedException("BerOctetString.EncodedLength"); + + // TODO This depends on knowing it's not DER + //if (!IsConstructed) + // return EncodedLength(withID, str.Length); + + //int totalLength = withID ? 4 : 3; + + //if (null != elements) + //{ + // for (int i = 0; i < elements.Length; ++i) + // { + // totalLength += elements[i].EncodedLength(true); + // } + //} + //else + //{ + // int fullSegments = str.Length / segmentLimit; + // totalLength += fullSegments * EncodedLength(true, segmentLimit); + + // int lastSegmentLength = str.Length - (fullSegments * segmentLimit); + // if (lastSegmentLength > 0) + // { + // totalLength += EncodedLength(true, lastSegmentLength); + // } + //} + + //return totalLength; + } + + internal override void Encode(Asn1OutputStream asn1Out, bool withID) + { + if (!asn1Out.IsBer || !IsConstructed) + { + base.Encode(asn1Out, withID); + return; + } + + asn1Out.WriteIdentifier(withID, Asn1Tags.Constructed | Asn1Tags.OctetString); + asn1Out.WriteByte(0x80); + + if (null != elements) + { + asn1Out.WritePrimitives(elements); + } + else + { + int pos = 0; + while (pos < str.Length) + { + int segmentLength = System.Math.Min(str.Length - pos, segmentLimit); + Encode(asn1Out, true, str, pos, segmentLength); + pos += segmentLength; + } + } + + asn1Out.WriteByte(0x00); + asn1Out.WriteByte(0x00); + } + + private class ChunkEnumerator + : IEnumerator + { + private readonly byte[] octets; + private readonly int segmentLimit; + + private DerOctetString currentSegment = null; + private int nextSegmentPos = 0; + + internal ChunkEnumerator(byte[] octets, int segmentLimit) + { + this.octets = octets; + this.segmentLimit = segmentLimit; + } + + public object Current + { + get + { + if (null == currentSegment) + throw new InvalidOperationException(); + + return currentSegment; + } + } + + public bool MoveNext() + { + if (nextSegmentPos >= octets.Length) + { + this.currentSegment = null; + return false; + } + + int length = System.Math.Min(octets.Length - nextSegmentPos, segmentLimit); + byte[] segment = new byte[length]; + Array.Copy(octets, nextSegmentPos, segment, 0, length); + this.currentSegment = new DerOctetString(segment); + this.nextSegmentPos += length; + return true; + } + + public void Reset() + { + this.currentSegment = null; + this.nextSegmentPos = 0; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BerOctetString.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BerOctetString.cs.meta new file mode 100644 index 0000000..1d6bd71 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BerOctetString.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c06abcd9eee2f084dab211c01551ad21 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BerOutputStream.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BerOutputStream.cs new file mode 100644 index 0000000..1486368 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BerOutputStream.cs @@ -0,0 +1,26 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Asn1 +{ + [Obsolete("Use 'Asn1OutputStream' instead")] + public class BerOutputStream + : DerOutputStream + { + [Obsolete("Use 'Asn1OutputStream.Create' instead")] + public BerOutputStream(Stream os) + : base(os) + { + } + + public override void WriteObject(Asn1Encodable encodable) + { + Asn1OutputStream.Create(s).WriteObject(encodable); + } + + public override void WriteObject(Asn1Object primitive) + { + Asn1OutputStream.Create(s).WriteObject(primitive); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BerOutputStream.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BerOutputStream.cs.meta new file mode 100644 index 0000000..7ba195c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BerOutputStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6156b20a3b4e206479efe890a42036d7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BerSequence.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BerSequence.cs new file mode 100644 index 0000000..068f0a2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BerSequence.cs @@ -0,0 +1,63 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + public class BerSequence + : DerSequence + { + public static new readonly BerSequence Empty = new BerSequence(); + + public static new BerSequence FromVector(Asn1EncodableVector elementVector) + { + return elementVector.Count < 1 ? Empty : new BerSequence(elementVector); + } + + /** + * create an empty sequence + */ + public BerSequence() + : base() + { + } + + /** + * create a sequence containing one object + */ + public BerSequence(Asn1Encodable element) + : base(element) + { + } + + public BerSequence(params Asn1Encodable[] elements) + : base(elements) + { + } + + /** + * create a sequence containing a vector of objects. + */ + public BerSequence(Asn1EncodableVector elementVector) + : base(elementVector) + { + } + + internal override int EncodedLength(bool withID) + { + throw Platform.CreateNotImplementedException("BerSequence.EncodedLength"); + } + + internal override void Encode(Asn1OutputStream asn1Out, bool withID) + { + if (asn1Out.IsBer) + { + asn1Out.WriteEncodingIL(withID, Asn1Tags.Constructed | Asn1Tags.Sequence, elements); + } + else + { + base.Encode(asn1Out, withID); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BerSequence.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BerSequence.cs.meta new file mode 100644 index 0000000..57c560b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BerSequence.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d2f8b0e0610a60342a5b4acd50a6c2aa +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BerSet.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BerSet.cs new file mode 100644 index 0000000..5d61db6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BerSet.cs @@ -0,0 +1,68 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + public class BerSet + : DerSet + { + public static new readonly BerSet Empty = new BerSet(); + + public static new BerSet FromVector(Asn1EncodableVector elementVector) + { + return elementVector.Count < 1 ? Empty : new BerSet(elementVector); + } + + internal static new BerSet FromVector(Asn1EncodableVector elementVector, bool needsSorting) + { + return elementVector.Count < 1 ? Empty : new BerSet(elementVector, needsSorting); + } + + /** + * create an empty sequence + */ + public BerSet() + : base() + { + } + + /** + * create a set containing one object + */ + public BerSet(Asn1Encodable element) + : base(element) + { + } + + /** + * create a set containing a vector of objects. + */ + public BerSet(Asn1EncodableVector elementVector) + : base(elementVector, false) + { + } + + internal BerSet(Asn1EncodableVector elementVector, bool needsSorting) + : base(elementVector, needsSorting) + { + } + + internal override int EncodedLength(bool withID) + { + throw Platform.CreateNotImplementedException("BerSet.EncodedLength"); + } + + internal override void Encode(Asn1OutputStream asn1Out, bool withID) + { + if (asn1Out.IsBer) + { + asn1Out.WriteEncodingIL(withID, Asn1Tags.Constructed | Asn1Tags.Set, elements); + } + else + { + base.Encode(asn1Out, withID); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BerSet.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BerSet.cs.meta new file mode 100644 index 0000000..835e0f3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BerSet.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 44c6928d57de12c48ab9b0604264d23f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BerTaggedObject.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BerTaggedObject.cs new file mode 100644 index 0000000..82a65db --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BerTaggedObject.cs @@ -0,0 +1,116 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + /** + * BER TaggedObject - in ASN.1 notation this is any object preceded by + * a [n] where n is some number - these are assumed to follow the construction + * rules (as with sequences). + */ + public class BerTaggedObject + : DerTaggedObject + { + /** + * @param tagNo the tag number for this object. + * @param obj the tagged object. + */ + public BerTaggedObject( + int tagNo, + Asn1Encodable obj) + : base(tagNo, obj) + { + } + + /** + * @param explicitly true if an explicitly tagged object. + * @param tagNo the tag number for this object. + * @param obj the tagged object. + */ + public BerTaggedObject( + bool explicitly, + int tagNo, + Asn1Encodable obj) + : base(explicitly, tagNo, obj) + { + } + + /** + * create an implicitly tagged object that contains a zero + * length sequence. + */ + public BerTaggedObject( + int tagNo) + : base(false, tagNo, BerSequence.Empty) + { + } + + internal override int EncodedLength(bool withID) + { + throw Platform.CreateNotImplementedException("BerTaggedObject.EncodedLength"); + } + + internal override void Encode(Asn1OutputStream asn1Out, bool withID) + { + if (asn1Out.IsBer) + { + if (withID) + { + asn1Out.WriteIdentifier(true, Asn1Tags.Constructed | Asn1Tags.ContextSpecific, tagNo); + } + + asn1Out.WriteByte(0x80); + + if (!IsEmpty()) + { + if (!explicitly) + { + IEnumerable eObj; + if (obj is Asn1OctetString) + { + if (obj is BerOctetString) + { + eObj = (BerOctetString) obj; + } + else + { + Asn1OctetString octs = (Asn1OctetString)obj; + eObj = new BerOctetString(octs.GetOctets()); + } + } + else if (obj is Asn1Sequence) + { + eObj = (Asn1Sequence) obj; + } + else if (obj is Asn1Set) + { + eObj = (Asn1Set) obj; + } + else + { + throw Platform.CreateNotImplementedException(Platform.GetTypeName(obj)); + } + + foreach (Asn1Encodable o in eObj) + { + asn1Out.WritePrimitive(o.ToAsn1Object(), true); + } + } + else + { + asn1Out.WritePrimitive(obj.ToAsn1Object(), true); + } + } + + asn1Out.WriteByte(0x00); + asn1Out.WriteByte(0x00); + } + else + { + base.Encode(asn1Out, withID); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BerTaggedObject.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BerTaggedObject.cs.meta new file mode 100644 index 0000000..6127500 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/BerTaggedObject.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 209c1b7ee82c78c4fafc6861e98d91cf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ConstructedOctetStream.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ConstructedOctetStream.cs new file mode 100644 index 0000000..829a9a4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ConstructedOctetStream.cs @@ -0,0 +1,109 @@ +using System.IO; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Asn1 +{ + internal class ConstructedOctetStream + : BaseInputStream + { + private readonly Asn1StreamParser _parser; + + private bool _first = true; + private Stream _currentStream; + + internal ConstructedOctetStream( + Asn1StreamParser parser) + { + _parser = parser; + } + + public override int Read(byte[] buffer, int offset, int count) + { + if (_currentStream == null) + { + if (!_first) + return 0; + + Asn1OctetStringParser next = GetNextParser(); + if (next == null) + return 0; + + _first = false; + _currentStream = next.GetOctetStream(); + } + + int totalRead = 0; + + for (;;) + { + int numRead = _currentStream.Read(buffer, offset + totalRead, count - totalRead); + + if (numRead > 0) + { + totalRead += numRead; + + if (totalRead == count) + return totalRead; + } + else + { + Asn1OctetStringParser next = GetNextParser(); + if (next == null) + { + _currentStream = null; + return totalRead; + } + + _currentStream = next.GetOctetStream(); + } + } + } + + public override int ReadByte() + { + if (_currentStream == null) + { + if (!_first) + return 0; + + Asn1OctetStringParser next = GetNextParser(); + if (next == null) + return 0; + + _first = false; + _currentStream = next.GetOctetStream(); + } + + for (;;) + { + int b = _currentStream.ReadByte(); + + if (b >= 0) + return b; + + Asn1OctetStringParser next = GetNextParser(); + if (next == null) + { + _currentStream = null; + return -1; + } + + _currentStream = next.GetOctetStream(); + } + } + + private Asn1OctetStringParser GetNextParser() + { + IAsn1Convertible asn1Obj = _parser.ReadObject(); + if (asn1Obj == null) + return null; + + if (asn1Obj is Asn1OctetStringParser) + return (Asn1OctetStringParser)asn1Obj; + + throw new IOException("unknown object encountered: " + Platform.GetTypeName(asn1Obj)); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ConstructedOctetStream.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ConstructedOctetStream.cs.meta new file mode 100644 index 0000000..201392f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ConstructedOctetStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5a74271c741360644b9a07950f48c2e7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DERExternal.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DERExternal.cs new file mode 100644 index 0000000..f457917 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DERExternal.cs @@ -0,0 +1,227 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + /** + * Class representing the DER-type External + */ + public class DerExternal + : Asn1Object + { + private DerObjectIdentifier directReference; + private DerInteger indirectReference; + private Asn1Object dataValueDescriptor; + private int encoding; + private Asn1Object externalContent; + + public DerExternal( + Asn1EncodableVector vector) + { + int offset = 0; + Asn1Object enc = GetObjFromVector(vector, offset); + if (enc is DerObjectIdentifier) + { + directReference = (DerObjectIdentifier)enc; + offset++; + enc = GetObjFromVector(vector, offset); + } + if (enc is DerInteger) + { + indirectReference = (DerInteger) enc; + offset++; + enc = GetObjFromVector(vector, offset); + } + if (!(enc is Asn1TaggedObject)) + { + dataValueDescriptor = enc; + offset++; + enc = GetObjFromVector(vector, offset); + } + + if (vector.Count != offset + 1) + throw new ArgumentException("input vector too large", "vector"); + + if (!(enc is Asn1TaggedObject)) + throw new ArgumentException("No tagged object found in vector. Structure doesn't seem to be of type External", "vector"); + + Asn1TaggedObject obj = (Asn1TaggedObject)enc; + + // Use property accessor to include check on value + Encoding = obj.TagNo; + + if (encoding < 0 || encoding > 2) + throw new InvalidOperationException("invalid encoding value"); + + externalContent = obj.GetObject(); + } + + /** + * Creates a new instance of DerExternal + * See X.690 for more informations about the meaning of these parameters + * @param directReference The direct reference or null if not set. + * @param indirectReference The indirect reference or null if not set. + * @param dataValueDescriptor The data value descriptor or null if not set. + * @param externalData The external data in its encoded form. + */ + public DerExternal(DerObjectIdentifier directReference, DerInteger indirectReference, Asn1Object dataValueDescriptor, DerTaggedObject externalData) + : this(directReference, indirectReference, dataValueDescriptor, externalData.TagNo, externalData.ToAsn1Object()) + { + } + + /** + * Creates a new instance of DerExternal. + * See X.690 for more informations about the meaning of these parameters + * @param directReference The direct reference or null if not set. + * @param indirectReference The indirect reference or null if not set. + * @param dataValueDescriptor The data value descriptor or null if not set. + * @param encoding The encoding to be used for the external data + * @param externalData The external data + */ + public DerExternal(DerObjectIdentifier directReference, DerInteger indirectReference, Asn1Object dataValueDescriptor, int encoding, Asn1Object externalData) + { + DirectReference = directReference; + IndirectReference = indirectReference; + DataValueDescriptor = dataValueDescriptor; + Encoding = encoding; + ExternalContent = externalData.ToAsn1Object(); + } + + internal override int EncodedLength(bool withID) + { + int contentsLength = 0; + if (directReference != null) + { + contentsLength += directReference.EncodedLength(true); + } + if (indirectReference != null) + { + contentsLength += indirectReference.EncodedLength(true); + } + if (dataValueDescriptor != null) + { + // TODO[asn1] + //contentsLength += dataValueDescriptor.ToDerObject().EncodedLength(true); + contentsLength += dataValueDescriptor.GetDerEncoded().Length; + } + + // TODO[asn1] + //contentsLength += new DerTaggedObject(true, encoding, externalContent).EncodedLength(true); + contentsLength += new DerTaggedObject(Asn1Tags.External, externalContent).EncodedLength(true); + + return Asn1OutputStream.GetLengthOfEncodingDL(withID, contentsLength); + } + + internal override void Encode(Asn1OutputStream asn1Out, bool withID) + { + MemoryStream ms = new MemoryStream(); + WriteEncodable(ms, directReference); + WriteEncodable(ms, indirectReference); + WriteEncodable(ms, dataValueDescriptor); + WriteEncodable(ms, new DerTaggedObject(Asn1Tags.External, externalContent)); + + asn1Out.WriteEncodingDL(withID, Asn1Tags.Constructed | Asn1Tags.External, ms.ToArray()); + } + + protected override int Asn1GetHashCode() + { + int ret = externalContent.GetHashCode(); + if (directReference != null) + { + ret ^= directReference.GetHashCode(); + } + if (indirectReference != null) + { + ret ^= indirectReference.GetHashCode(); + } + if (dataValueDescriptor != null) + { + ret ^= dataValueDescriptor.GetHashCode(); + } + return ret; + } + + protected override bool Asn1Equals( + Asn1Object asn1Object) + { + if (this == asn1Object) + return true; + + DerExternal other = asn1Object as DerExternal; + + if (other == null) + return false; + + return Platform.Equals(directReference, other.directReference) + && Platform.Equals(indirectReference, other.indirectReference) + && Platform.Equals(dataValueDescriptor, other.dataValueDescriptor) + && externalContent.Equals(other.externalContent); + } + + public Asn1Object DataValueDescriptor + { + get { return dataValueDescriptor; } + set { this.dataValueDescriptor = value; } + } + + public DerObjectIdentifier DirectReference + { + get { return directReference; } + set { this.directReference = value; } + } + + /** + * The encoding of the content. Valid values are + *
    + *
  • 0 single-ASN1-type
  • + *
  • 1 OCTET STRING
  • + *
  • 2 BIT STRING
  • + *
+ */ + public int Encoding + { + get + { + return encoding; + } + set + { + if (encoding < 0 || encoding > 2) + throw new InvalidOperationException("invalid encoding value: " + encoding); + + this.encoding = value; + } + } + + public Asn1Object ExternalContent + { + get { return externalContent; } + set { this.externalContent = value; } + } + + public DerInteger IndirectReference + { + get { return indirectReference; } + set { this.indirectReference = value; } + } + + private static Asn1Object GetObjFromVector(Asn1EncodableVector v, int index) + { + if (v.Count <= index) + throw new ArgumentException("too few objects in input vector", "v"); + + return v[index].ToAsn1Object(); + } + + private static void WriteEncodable(MemoryStream ms, Asn1Encodable e) + { + if (e != null) + { + byte[] bs = e.GetDerEncoded(); + ms.Write(bs, 0, bs.Length); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DERExternal.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DERExternal.cs.meta new file mode 100644 index 0000000..0345a31 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DERExternal.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1b2875b088874a64ba4866a95ff533bb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DERExternalParser.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DERExternalParser.cs new file mode 100644 index 0000000..5e52e63 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DERExternalParser.cs @@ -0,0 +1,31 @@ +using System; + +namespace Org.BouncyCastle.Asn1 +{ + public class DerExternalParser + : Asn1Encodable + { + private readonly Asn1StreamParser _parser; + + [Obsolete("Will be removed")] + public DerExternalParser(Asn1StreamParser parser) + { + this._parser = parser; + } + + public IAsn1Convertible ReadObject() + { + return _parser.ReadObject(); + } + + public override Asn1Object ToAsn1Object() + { + return Parse(_parser); + } + + internal static DerExternal Parse(Asn1StreamParser sp) + { + return new DerExternal(sp.ReadVector()); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DERExternalParser.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DERExternalParser.cs.meta new file mode 100644 index 0000000..274e626 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DERExternalParser.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e96e400066a6aba478c2d14c104075c1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DERGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DERGenerator.cs new file mode 100644 index 0000000..387a2c5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DERGenerator.cs @@ -0,0 +1,107 @@ +using System.IO; + +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Asn1 +{ + public abstract class DerGenerator + : Asn1Generator + { + private bool _tagged = false; + private bool _isExplicit; + private int _tagNo; + + protected DerGenerator( + Stream outStream) + : base(outStream) + { + } + + protected DerGenerator( + Stream outStream, + int tagNo, + bool isExplicit) + : base(outStream) + { + _tagged = true; + _isExplicit = isExplicit; + _tagNo = tagNo; + } + + private static void WriteLength( + Stream outStr, + int length) + { + if (length > 127) + { + int size = 1; + int val = length; + + while ((val >>= 8) != 0) + { + size++; + } + + outStr.WriteByte((byte)(size | 0x80)); + + for (int i = (size - 1) * 8; i >= 0; i -= 8) + { + outStr.WriteByte((byte)(length >> i)); + } + } + else + { + outStr.WriteByte((byte)length); + } + } + + internal static void WriteDerEncoded( + Stream outStream, + int tag, + byte[] bytes) + { + outStream.WriteByte((byte) tag); + WriteLength(outStream, bytes.Length); + outStream.Write(bytes, 0, bytes.Length); + } + + internal void WriteDerEncoded( + int tag, + byte[] bytes) + { + if (_tagged) + { + int tagNum = _tagNo | Asn1Tags.ContextSpecific; + + if (_isExplicit) + { + int newTag = _tagNo | Asn1Tags.Constructed | Asn1Tags.ContextSpecific; + MemoryStream bOut = new MemoryStream(); + WriteDerEncoded(bOut, tag, bytes); + WriteDerEncoded(Out, newTag, bOut.ToArray()); + } + else + { + if ((tag & Asn1Tags.Constructed) != 0) + { + tagNum |= Asn1Tags.Constructed; + } + + WriteDerEncoded(Out, tagNum, bytes); + } + } + else + { + WriteDerEncoded(Out, tag, bytes); + } + } + + internal static void WriteDerEncoded( + Stream outStr, + int tag, + Stream inStr) + { + WriteDerEncoded(outStr, tag, Streams.ReadAll(inStr)); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DERGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DERGenerator.cs.meta new file mode 100644 index 0000000..a20cb46 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DERGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 406aee1505b971c4784ef18ec3f5eac2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DEROctetStringParser.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DEROctetStringParser.cs new file mode 100644 index 0000000..b0d3ad8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DEROctetStringParser.cs @@ -0,0 +1,36 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Asn1 +{ + public class DerOctetStringParser + : Asn1OctetStringParser + { + private readonly DefiniteLengthInputStream stream; + + internal DerOctetStringParser( + DefiniteLengthInputStream stream) + { + this.stream = stream; + } + + public Stream GetOctetStream() + { + return stream; + } + + public Asn1Object ToAsn1Object() + { + try + { + return new DerOctetString(stream.ToArray()); + } + catch (IOException e) + { + throw new InvalidOperationException("IOException converting stream to byte array: " + e.Message, e); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DEROctetStringParser.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DEROctetStringParser.cs.meta new file mode 100644 index 0000000..6e65a96 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DEROctetStringParser.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ee7b05cb9fba8d84d855e62edb8550a2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DERSequenceGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DERSequenceGenerator.cs new file mode 100644 index 0000000..12c9785 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DERSequenceGenerator.cs @@ -0,0 +1,44 @@ +using System.IO; + +namespace Org.BouncyCastle.Asn1 +{ + public class DerSequenceGenerator + : DerGenerator + { + private readonly MemoryStream _bOut = new MemoryStream(); + + public DerSequenceGenerator( + Stream outStream) + : base(outStream) + { + } + + public DerSequenceGenerator( + Stream outStream, + int tagNo, + bool isExplicit) + : base(outStream, tagNo, isExplicit) + { + } + + public override void AddObject(Asn1Encodable obj) + { + obj.EncodeTo(_bOut, Asn1Encodable.Der); + } + + public override void AddObject(Asn1Object obj) + { + obj.EncodeTo(_bOut, Asn1Encodable.Der); + } + + public override Stream GetRawOutputStream() + { + return _bOut; + } + + public override void Close() + { + WriteDerEncoded(Asn1Tags.Constructed | Asn1Tags.Sequence, _bOut.ToArray()); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DERSequenceGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DERSequenceGenerator.cs.meta new file mode 100644 index 0000000..34d5721 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DERSequenceGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d9916f3eb87e6f846a0c5e39d8a85959 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DERSequenceParser.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DERSequenceParser.cs new file mode 100644 index 0000000..69c2b9b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DERSequenceParser.cs @@ -0,0 +1,24 @@ +namespace Org.BouncyCastle.Asn1 +{ + public class DerSequenceParser + : Asn1SequenceParser + { + private readonly Asn1StreamParser _parser; + + internal DerSequenceParser( + Asn1StreamParser parser) + { + this._parser = parser; + } + + public IAsn1Convertible ReadObject() + { + return _parser.ReadObject(); + } + + public Asn1Object ToAsn1Object() + { + return new DerSequence(_parser.ReadVector()); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DERSequenceParser.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DERSequenceParser.cs.meta new file mode 100644 index 0000000..0f61b4b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DERSequenceParser.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8a5737bda33b5924e97017e971d7122d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DERSetGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DERSetGenerator.cs new file mode 100644 index 0000000..6772417 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DERSetGenerator.cs @@ -0,0 +1,44 @@ +using System.IO; + +namespace Org.BouncyCastle.Asn1 +{ + public class DerSetGenerator + : DerGenerator + { + private readonly MemoryStream _bOut = new MemoryStream(); + + public DerSetGenerator( + Stream outStream) + : base(outStream) + { + } + + public DerSetGenerator( + Stream outStream, + int tagNo, + bool isExplicit) + : base(outStream, tagNo, isExplicit) + { + } + + public override void AddObject(Asn1Encodable obj) + { + obj.EncodeTo(_bOut, Asn1Encodable.Der); + } + + public override void AddObject(Asn1Object obj) + { + obj.EncodeTo(_bOut, Asn1Encodable.Der); + } + + public override Stream GetRawOutputStream() + { + return _bOut; + } + + public override void Close() + { + WriteDerEncoded(Asn1Tags.Constructed | Asn1Tags.Set, _bOut.ToArray()); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DERSetGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DERSetGenerator.cs.meta new file mode 100644 index 0000000..c388801 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DERSetGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 85c352bcebb6de441b09c7e39c713f8c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DERSetParser.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DERSetParser.cs new file mode 100644 index 0000000..d67f135 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DERSetParser.cs @@ -0,0 +1,24 @@ +namespace Org.BouncyCastle.Asn1 +{ + public class DerSetParser + : Asn1SetParser + { + private readonly Asn1StreamParser _parser; + + internal DerSetParser( + Asn1StreamParser parser) + { + this._parser = parser; + } + + public IAsn1Convertible ReadObject() + { + return _parser.ReadObject(); + } + + public Asn1Object ToAsn1Object() + { + return new DerSet(_parser.ReadVector(), false); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DERSetParser.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DERSetParser.cs.meta new file mode 100644 index 0000000..4cadf5a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DERSetParser.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ea74bb5eb6087ba47b65169a75132f3b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DefiniteLengthInputStream.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DefiniteLengthInputStream.cs new file mode 100644 index 0000000..e3b9b57 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DefiniteLengthInputStream.cs @@ -0,0 +1,111 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Asn1 +{ + class DefiniteLengthInputStream + : LimitedInputStream + { + private static readonly byte[] EmptyBytes = new byte[0]; + + private readonly int _originalLength; + private int _remaining; + + internal DefiniteLengthInputStream(Stream inStream, int length, int limit) + : base(inStream, limit) + { + if (length <= 0) + { + if (length < 0) + throw new ArgumentException("negative lengths not allowed", "length"); + + SetParentEofDetect(true); + } + + this._originalLength = length; + this._remaining = length; + } + + internal int Remaining + { + get { return _remaining; } + } + + public override int ReadByte() + { + if (_remaining == 0) + return -1; + + int b = _in.ReadByte(); + + if (b < 0) + throw new EndOfStreamException("DEF length " + _originalLength + " object truncated by " + _remaining); + + if (--_remaining == 0) + { + SetParentEofDetect(true); + } + + return b; + } + + public override int Read( + byte[] buf, + int off, + int len) + { + if (_remaining == 0) + return 0; + + int toRead = System.Math.Min(len, _remaining); + int numRead = _in.Read(buf, off, toRead); + + if (numRead < 1) + throw new EndOfStreamException("DEF length " + _originalLength + " object truncated by " + _remaining); + + if ((_remaining -= numRead) == 0) + { + SetParentEofDetect(true); + } + + return numRead; + } + + internal void ReadAllIntoByteArray(byte[] buf) + { + if (_remaining != buf.Length) + throw new ArgumentException("buffer length not right for data"); + + if (_remaining == 0) + return; + + // make sure it's safe to do this! + int limit = Limit; + if (_remaining >= limit) + throw new IOException("corrupted stream - out of bounds length found: " + _remaining + " >= " + limit); + + if ((_remaining -= Streams.ReadFully(_in, buf)) != 0) + throw new EndOfStreamException("DEF length " + _originalLength + " object truncated by " + _remaining); + SetParentEofDetect(true); + } + + internal byte[] ToArray() + { + if (_remaining == 0) + return EmptyBytes; + + // make sure it's safe to do this! + int limit = Limit; + if (_remaining >= limit) + throw new IOException("corrupted stream - out of bounds length found: " + _remaining + " >= " + limit); + + byte[] bytes = new byte[_remaining]; + if ((_remaining -= Streams.ReadFully(_in, bytes)) != 0) + throw new EndOfStreamException("DEF length " + _originalLength + " object truncated by " + _remaining); + SetParentEofDetect(true); + return bytes; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DefiniteLengthInputStream.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DefiniteLengthInputStream.cs.meta new file mode 100644 index 0000000..5abb324 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DefiniteLengthInputStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8b121f4244c23eb4aa50b75dee6f8f31 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerApplicationSpecific.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerApplicationSpecific.cs new file mode 100644 index 0000000..5626383 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerApplicationSpecific.cs @@ -0,0 +1,230 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + /** + * Base class for an application specific object + */ + public class DerApplicationSpecific + : Asn1Object + { + private readonly bool isConstructed; + private readonly int tag; + private readonly byte[] octets; + + internal DerApplicationSpecific( + bool isConstructed, + int tag, + byte[] octets) + { + this.isConstructed = isConstructed; + this.tag = tag; + this.octets = octets; + } + + public DerApplicationSpecific( + int tag, + byte[] octets) + : this(false, tag, octets) + { + } + + public DerApplicationSpecific( + int tag, + Asn1Encodable obj) + : this(true, tag, obj) + { + } + + public DerApplicationSpecific( + bool isExplicit, + int tag, + Asn1Encodable obj) + { + Asn1Object asn1Obj = obj.ToAsn1Object(); + + byte[] data = asn1Obj.GetDerEncoded(); + + this.isConstructed = Asn1TaggedObject.IsConstructed(isExplicit, asn1Obj); + this.tag = tag; + + if (isExplicit) + { + this.octets = data; + } + else + { + int lenBytes = GetLengthOfHeader(data); + byte[] tmp = new byte[data.Length - lenBytes]; + Array.Copy(data, lenBytes, tmp, 0, tmp.Length); + this.octets = tmp; + } + } + + public DerApplicationSpecific( + int tagNo, + Asn1EncodableVector vec) + { + this.tag = tagNo; + this.isConstructed = true; + MemoryStream bOut = new MemoryStream(); + + for (int i = 0; i != vec.Count; i++) + { + try + { + byte[] bs = vec[i].GetDerEncoded(); + bOut.Write(bs, 0, bs.Length); + } + catch (IOException e) + { + throw new InvalidOperationException("malformed object", e); + } + } + this.octets = bOut.ToArray(); + } + + private int GetLengthOfHeader( + byte[] data) + { + int length = data[1]; // TODO: assumes 1 byte tag + + if (length == 0x80) + { + return 2; // indefinite-length encoding + } + + if (length > 127) + { + int size = length & 0x7f; + + // Note: The invalid long form "0xff" (see X.690 8.1.3.5c) will be caught here + if (size > 4) + { + throw new InvalidOperationException("DER length more than 4 bytes: " + size); + } + + return size + 2; + } + + return 2; + } + + public bool IsConstructed() + { + return isConstructed; + } + + public byte[] GetContents() + { + return octets; + } + + public int ApplicationTag + { + get { return tag; } + } + + /** + * Return the enclosed object assuming explicit tagging. + * + * @return the resulting object + * @throws IOException if reconstruction fails. + */ + public Asn1Object GetObject() + { + return FromByteArray(GetContents()); + } + + /** + * Return the enclosed object assuming implicit tagging. + * + * @param derTagNo the type tag that should be applied to the object's contents. + * @return the resulting object + * @throws IOException if reconstruction fails. + */ + public Asn1Object GetObject( + int derTagNo) + { + if (derTagNo >= 0x1f) + throw new IOException("unsupported tag number"); + + byte[] orig = this.GetEncoded(); + byte[] tmp = ReplaceTagNumber(derTagNo, orig); + + if ((orig[0] & Asn1Tags.Constructed) != 0) + { + tmp[0] |= Asn1Tags.Constructed; + } + + return FromByteArray(tmp); + } + + internal override int EncodedLength(bool withID) + { + return Asn1OutputStream.GetLengthOfEncodingDL(withID, tag, octets.Length); + } + + internal override void Encode(Asn1OutputStream asn1Out, bool withID) + { + int flags = Asn1Tags.Application; + if (isConstructed) + { + flags |= Asn1Tags.Constructed; + } + + asn1Out.WriteEncodingDL(withID, flags, tag, octets); + } + + protected override bool Asn1Equals( + Asn1Object asn1Object) + { + DerApplicationSpecific other = asn1Object as DerApplicationSpecific; + + if (other == null) + return false; + + return this.isConstructed == other.isConstructed + && this.tag == other.tag + && Arrays.AreEqual(this.octets, other.octets); + } + + protected override int Asn1GetHashCode() + { + return isConstructed.GetHashCode() ^ tag.GetHashCode() ^ Arrays.GetHashCode(octets); + } + + private byte[] ReplaceTagNumber( + int newTag, + byte[] input) + { + int tagNo = input[0] & 0x1f; + int index = 1; + + // with tagged object tag number is bottom 5 bits, or stored at the start of the content + if (tagNo == 0x1f) + { + int b = input[index++]; + + // X.690-0207 8.1.2.4.2 + // "c) bits 7 to 1 of the first subsequent octet shall not all be zero." + if ((b & 0x7f) == 0) // Note: -1 will pass + throw new IOException("corrupted stream - invalid high tag number found"); + + while ((b & 0x80) != 0) + { + b = input[index++]; + } + } + + int remaining = input.Length - index; + byte[] tmp = new byte[1 + remaining]; + tmp[0] = (byte)newTag; + Array.Copy(input, index, tmp, 1, remaining); + return tmp; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerApplicationSpecific.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerApplicationSpecific.cs.meta new file mode 100644 index 0000000..3494215 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerApplicationSpecific.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 69f23705eec5c0447b21594be587ae1a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerBMPString.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerBMPString.cs new file mode 100644 index 0000000..1847dae --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerBMPString.cs @@ -0,0 +1,133 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + /** + * Der BMPString object. + */ + public class DerBmpString + : DerStringBase + { + private readonly string str; + + /** + * return a BMP string from the given object. + * + * @param obj the object we want converted. + * @exception ArgumentException if the object cannot be converted. + */ + public static DerBmpString GetInstance( + object obj) + { + if (obj == null || obj is DerBmpString) + { + return (DerBmpString)obj; + } + + throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj)); + } + + /** + * return a BMP string from a tagged object. + * + * @param obj the tagged object holding the object we want + * @param explicitly true if the object is meant to be explicitly + * tagged false otherwise. + * @exception ArgumentException if the tagged object cannot + * be converted. + */ + public static DerBmpString GetInstance( + Asn1TaggedObject obj, + bool isExplicit) + { + Asn1Object o = obj.GetObject(); + + if (isExplicit || o is DerBmpString) + { + return GetInstance(o); + } + + return new DerBmpString(Asn1OctetString.GetInstance(o).GetOctets()); + } + + /** + * basic constructor - byte encoded string. + */ + [Obsolete("Will become internal")] + public DerBmpString(byte[] str) + { + if (str == null) + throw new ArgumentNullException("str"); + + int byteLen = str.Length; + if (0 != (byteLen & 1)) + throw new ArgumentException("malformed BMPString encoding encountered", "str"); + + int charLen = byteLen / 2; + char[] cs = new char[charLen]; + + for (int i = 0; i != charLen; i++) + { + cs[i] = (char)((str[2 * i] << 8) | (str[2 * i + 1] & 0xff)); + } + + this.str = new string(cs); + } + + internal DerBmpString(char[] str) + { + if (str == null) + throw new ArgumentNullException("str"); + + this.str = new string(str); + } + + /** + * basic constructor + */ + public DerBmpString(string str) + { + if (str == null) + throw new ArgumentNullException("str"); + + this.str = str; + } + + public override string GetString() + { + return str; + } + + protected override bool Asn1Equals( + Asn1Object asn1Object) + { + DerBmpString other = asn1Object as DerBmpString; + + if (other == null) + return false; + + return this.str.Equals(other.str); + } + + internal override int EncodedLength(bool withID) + { + return Asn1OutputStream.GetLengthOfEncodingDL(withID, str.Length * 2); + } + + internal override void Encode(Asn1OutputStream asn1Out, bool withID) + { + char[] c = str.ToCharArray(); + byte[] b = new byte[c.Length * 2]; + + for (int i = 0; i != c.Length; i++) + { + b[2 * i] = (byte)(c[i] >> 8); + b[2 * i + 1] = (byte)c[i]; + } + + asn1Out.WriteEncodingDL(withID, Asn1Tags.BmpString, b); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerBMPString.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerBMPString.cs.meta new file mode 100644 index 0000000..1669647 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerBMPString.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 032f83f364be75143a66b3e110c1af0c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerBitString.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerBitString.cs new file mode 100644 index 0000000..caf5d6f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerBitString.cs @@ -0,0 +1,332 @@ +using System; +using System.Diagnostics; +using System.Text; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + public class DerBitString + : DerStringBase + { + private static readonly char[] table + = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + + /** + * return a Bit string from the passed in object + * + * @exception ArgumentException if the object cannot be converted. + */ + public static DerBitString GetInstance(object obj) + { + if (obj == null || obj is DerBitString) + { + return (DerBitString) obj; + } + if (obj is byte[]) + { + try + { + return (DerBitString)FromByteArray((byte[])obj); + } + catch (Exception e) + { + throw new ArgumentException("encoding error in GetInstance: " + e.ToString()); + } + } + + throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj)); + } + + /** + * return a Bit string from a tagged object. + * + * @param obj the tagged object holding the object we want + * @param explicitly true if the object is meant to be explicitly + * tagged false otherwise. + * @exception ArgumentException if the tagged object cannot + * be converted. + */ + public static DerBitString GetInstance(Asn1TaggedObject obj, bool isExplicit) + { + Asn1Object o = obj.GetObject(); + + if (isExplicit || o is DerBitString) + { + return GetInstance(o); + } + + // Not copied because assumed to be a tagged implicit primitive from the parser + return CreatePrimitive(((Asn1OctetString)o).GetOctets()); + } + + internal readonly byte[] contents; + + public DerBitString(byte data, int padBits) + { + if (padBits > 7 || padBits < 0) + throw new ArgumentException("pad bits cannot be greater than 7 or less than 0", "padBits"); + + this.contents = new byte[] { (byte)padBits, data }; + } + + public DerBitString(byte[] data) + : this(data, 0) + { + } + + /** + * @param data the octets making up the bit string. + * @param padBits the number of extra bits at the end of the string. + */ + public DerBitString(byte[] data, int padBits) + { + if (data == null) + throw new ArgumentNullException("data"); + if (padBits < 0 || padBits > 7) + throw new ArgumentException("must be in the range 0 to 7", "padBits"); + if (data.Length == 0 && padBits != 0) + throw new ArgumentException("if 'data' is empty, 'padBits' must be 0"); + + this.contents = Arrays.Prepend(data, (byte)padBits); + } + + public DerBitString(int namedBits) + { + if (namedBits == 0) + { + this.contents = new byte[]{ 0 }; + return; + } + + int bits = BigInteger.BitLen(namedBits); + int bytes = (bits + 7) / 8; + Debug.Assert(0 < bytes && bytes <= 4); + + byte[] data = new byte[1 + bytes]; + + for (int i = 1; i < bytes; i++) + { + data[i] = (byte)namedBits; + namedBits >>= 8; + } + + Debug.Assert((namedBits & 0xFF) != 0); + data[bytes] = (byte)namedBits; + + int padBits = 0; + while ((namedBits & (1 << padBits)) == 0) + { + ++padBits; + } + + Debug.Assert(padBits < 8); + data[0] = (byte)padBits; + + this.contents = data; + } + + public DerBitString(Asn1Encodable obj) + : this(obj.GetDerEncoded()) + { + } + + internal DerBitString(byte[] contents, bool check) + { + if (check) + { + if (null == contents) + throw new ArgumentNullException("contents"); + if (contents.Length < 1) + throw new ArgumentException("cannot be empty", "contents"); + + int padBits = contents[0]; + if (padBits > 0) + { + if (contents.Length < 2) + throw new ArgumentException("zero length data with non-zero pad bits", "contents"); + if (padBits > 7) + throw new ArgumentException("pad bits cannot be greater than 7 or less than 0", "contents"); + } + } + + this.contents = contents; + } + + /** + * Return the octets contained in this BIT STRING, checking that this BIT STRING really + * does represent an octet aligned string. Only use this method when the standard you are + * following dictates that the BIT STRING will be octet aligned. + * + * @return a copy of the octet aligned data. + */ + public virtual byte[] GetOctets() + { + if (contents[0] != 0) + throw new InvalidOperationException("attempt to get non-octet aligned data from BIT STRING"); + + return Arrays.CopyOfRange(contents, 1, contents.Length); + } + + public virtual byte[] GetBytes() + { + if (contents.Length == 1) + return Asn1OctetString.EmptyOctets; + + int padBits = contents[0]; + byte[] rv = Arrays.CopyOfRange(contents, 1, contents.Length); + // DER requires pad bits be zero + rv[rv.Length - 1] &= (byte)(0xFF << padBits); + return rv; + } + + public virtual int PadBits + { + get { return contents[0]; } + } + + /** + * @return the value of the bit string as an int (truncating if necessary) + */ + public virtual int IntValue + { + get + { + int value = 0, end = System.Math.Min(5, contents.Length - 1); + for (int i = 1; i < end; ++i) + { + value |= (int)contents[i] << (8 * (i - 1)); + } + if (1 <= end && end < 5) + { + int padBits = contents[0]; + byte der = (byte)(contents[end] & (0xFF << padBits)); + value |= (int)der << (8 * (end - 1)); + } + return value; + } + } + + internal override int EncodedLength(bool withID) + { + return Asn1OutputStream.GetLengthOfEncodingDL(withID, contents.Length); + } + + internal override void Encode(Asn1OutputStream asn1Out, bool withID) + { + int padBits = contents[0]; + int length = contents.Length; + int last = length - 1; + + byte lastOctet = contents[last]; + byte lastOctetDer = (byte)(contents[last] & (0xFF << padBits)); + + if (lastOctet == lastOctetDer) + { + asn1Out.WriteEncodingDL(withID, Asn1Tags.BitString, contents); + } + else + { + asn1Out.WriteEncodingDL(withID, Asn1Tags.BitString, contents, 0, last, lastOctetDer); + } + } + + protected override int Asn1GetHashCode() + { + if (contents.Length < 2) + return 1; + + int padBits = contents[0]; + int last = contents.Length - 1; + + byte lastOctetDer = (byte)(contents[last] & (0xFF << padBits)); + + int hc = Arrays.GetHashCode(contents, 0, last); + hc *= 257; + hc ^= lastOctetDer; + return hc; + } + + protected override bool Asn1Equals(Asn1Object asn1Object) + { + DerBitString that = asn1Object as DerBitString; + if (null == that) + return false; + + byte[] thisContents = this.contents, thatContents = that.contents; + + int length = thisContents.Length; + if (thatContents.Length != length) + return false; + if (length == 1) + return true; + + int last = length - 1; + for (int i = 0; i < last; ++i) + { + if (thisContents[i] != thatContents[i]) + return false; + } + + int padBits = thisContents[0]; + byte thisLastOctetDer = (byte)(thisContents[last] & (0xFF << padBits)); + byte thatLastOctetDer = (byte)(thatContents[last] & (0xFF << padBits)); + + return thisLastOctetDer == thatLastOctetDer; + } + + public override string GetString() + { + StringBuilder buffer = new StringBuilder("#"); + + byte[] str = GetDerEncoded(); + + for (int i = 0; i != str.Length; i++) + { + uint ubyte = str[i]; + buffer.Append(table[(ubyte >> 4) & 0xf]); + buffer.Append(table[str[i] & 0xf]); + } + + return buffer.ToString(); + } + + internal static int EncodedLength(bool withID, int contentsLength) + { + return Asn1OutputStream.GetLengthOfEncodingDL(withID, contentsLength); + } + + internal static void Encode(Asn1OutputStream asn1Out, bool withID, byte[] buf, int off, int len) + { + asn1Out.WriteEncodingDL(withID, Asn1Tags.BitString, buf, off, len); + } + + internal static void Encode(Asn1OutputStream asn1Out, bool withID, byte pad, byte[] buf, int off, int len) + { + asn1Out.WriteEncodingDL(withID, Asn1Tags.BitString, pad, buf, off, len); + } + + internal static DerBitString CreatePrimitive(byte[] contents) + { + int length = contents.Length; + if (length < 1) + throw new ArgumentException("truncated BIT STRING detected", "contents"); + + int padBits = contents[0]; + if (padBits > 0) + { + if (padBits > 7 || length < 2) + throw new ArgumentException("invalid pad bits detected", "contents"); + + byte finalOctet = contents[length - 1]; + if (finalOctet != (byte)(finalOctet & (0xFF << padBits))) + { + return new BerBitString(contents, false); + } + } + + return new DerBitString(contents, false); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerBitString.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerBitString.cs.meta new file mode 100644 index 0000000..391b64c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerBitString.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 85c1f776b2e190f46bb07a73f6274975 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerBoolean.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerBoolean.cs new file mode 100644 index 0000000..e2885f1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerBoolean.cs @@ -0,0 +1,128 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + public class DerBoolean + : Asn1Object + { + private readonly byte value; + + public static readonly DerBoolean False = new DerBoolean(false); + public static readonly DerBoolean True = new DerBoolean(true); + + /** + * return a bool from the passed in object. + * + * @exception ArgumentException if the object cannot be converted. + */ + public static DerBoolean GetInstance( + object obj) + { + if (obj == null || obj is DerBoolean) + { + return (DerBoolean) obj; + } + + throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj)); + } + + /** + * return a DerBoolean from the passed in bool. + */ + public static DerBoolean GetInstance( + bool value) + { + return value ? True : False; + } + + /** + * return a Boolean from a tagged object. + * + * @param obj the tagged object holding the object we want + * @param explicitly true if the object is meant to be explicitly + * tagged false otherwise. + * @exception ArgumentException if the tagged object cannot + * be converted. + */ + public static DerBoolean GetInstance( + Asn1TaggedObject obj, + bool isExplicit) + { + Asn1Object o = obj.GetObject(); + + if (isExplicit || o is DerBoolean) + { + return GetInstance(o); + } + + return FromOctetString(((Asn1OctetString)o).GetOctets()); + } + + public DerBoolean( + byte[] val) + { + if (val.Length != 1) + throw new ArgumentException("byte value should have 1 byte in it", "val"); + + // TODO Are there any constraints on the possible byte values? + this.value = val[0]; + } + + private DerBoolean( + bool value) + { + this.value = value ? (byte)0xff : (byte)0; + } + + public bool IsTrue + { + get { return value != 0; } + } + + internal override int EncodedLength(bool withID) + { + return Asn1OutputStream.GetLengthOfEncodingDL(withID, 1); + } + + internal override void Encode(Asn1OutputStream asn1Out, bool withID) + { + // TODO Should we make sure the byte value is one of '0' or '0xff' here? + asn1Out.WriteEncodingDL(withID, Asn1Tags.Boolean, value); + } + + protected override bool Asn1Equals( + Asn1Object asn1Object) + { + DerBoolean other = asn1Object as DerBoolean; + + if (other == null) + return false; + + return IsTrue == other.IsTrue; + } + + protected override int Asn1GetHashCode() + { + return IsTrue.GetHashCode(); + } + + public override string ToString() + { + return IsTrue ? "TRUE" : "FALSE"; + } + + internal static DerBoolean FromOctetString(byte[] value) + { + if (value.Length != 1) + { + throw new ArgumentException("BOOLEAN value should have 1 byte in it", "value"); + } + + byte b = value[0]; + + return b == 0 ? False : b == 0xFF ? True : new DerBoolean(value); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerBoolean.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerBoolean.cs.meta new file mode 100644 index 0000000..d855dfd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerBoolean.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 351f96b65966b6445a413a339fc9ecb0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerEnumerated.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerEnumerated.cs new file mode 100644 index 0000000..227af18 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerEnumerated.cs @@ -0,0 +1,167 @@ +using System; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + public class DerEnumerated + : Asn1Object + { + private readonly byte[] bytes; + private readonly int start; + + /** + * return an integer from the passed in object + * + * @exception ArgumentException if the object cannot be converted. + */ + public static DerEnumerated GetInstance( + object obj) + { + if (obj == null || obj is DerEnumerated) + { + return (DerEnumerated)obj; + } + + throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj)); + } + + /** + * return an Enumerated from a tagged object. + * + * @param obj the tagged object holding the object we want + * @param explicitly true if the object is meant to be explicitly + * tagged false otherwise. + * @exception ArgumentException if the tagged object cannot + * be converted. + */ + public static DerEnumerated GetInstance( + Asn1TaggedObject obj, + bool isExplicit) + { + Asn1Object o = obj.GetObject(); + + if (isExplicit || o is DerEnumerated) + { + return GetInstance(o); + } + + return FromOctetString(((Asn1OctetString)o).GetOctets()); + } + + public DerEnumerated(int val) + { + if (val < 0) + throw new ArgumentException("enumerated must be non-negative", "val"); + + this.bytes = BigInteger.ValueOf(val).ToByteArray(); + this.start = 0; + } + + public DerEnumerated(long val) + { + if (val < 0L) + throw new ArgumentException("enumerated must be non-negative", "val"); + + this.bytes = BigInteger.ValueOf(val).ToByteArray(); + this.start = 0; + } + + public DerEnumerated(BigInteger val) + { + if (val.SignValue < 0) + throw new ArgumentException("enumerated must be non-negative", "val"); + + this.bytes = val.ToByteArray(); + this.start = 0; + } + + public DerEnumerated(byte[] bytes) + { + if (DerInteger.IsMalformed(bytes)) + throw new ArgumentException("malformed enumerated", "bytes"); + if (0 != (bytes[0] & 0x80)) + throw new ArgumentException("enumerated must be non-negative", "bytes"); + + this.bytes = Arrays.Clone(bytes); + this.start = DerInteger.SignBytesToSkip(bytes); + } + + public BigInteger Value + { + get { return new BigInteger(bytes); } + } + + public bool HasValue(int x) + { + return (bytes.Length - start) <= 4 + && DerInteger.IntValue(bytes, start, DerInteger.SignExtSigned) == x; + } + + public bool HasValue(BigInteger x) + { + return null != x + // Fast check to avoid allocation + && DerInteger.IntValue(bytes, start, DerInteger.SignExtSigned) == x.IntValue + && Value.Equals(x); + } + + public int IntValueExact + { + get + { + int count = bytes.Length - start; + if (count > 4) + throw new ArithmeticException("ASN.1 Enumerated out of int range"); + + return DerInteger.IntValue(bytes, start, DerInteger.SignExtSigned); + } + } + + internal override int EncodedLength(bool withID) + { + return Asn1OutputStream.GetLengthOfEncodingDL(withID, bytes.Length); + } + + internal override void Encode(Asn1OutputStream asn1Out, bool withID) + { + asn1Out.WriteEncodingDL(withID, Asn1Tags.Enumerated, bytes); + } + + protected override bool Asn1Equals(Asn1Object asn1Object) + { + DerEnumerated other = asn1Object as DerEnumerated; + if (other == null) + return false; + + return Arrays.AreEqual(this.bytes, other.bytes); + } + + protected override int Asn1GetHashCode() + { + return Arrays.GetHashCode(bytes); + } + + private static readonly DerEnumerated[] cache = new DerEnumerated[12]; + + internal static DerEnumerated FromOctetString(byte[] enc) + { + if (enc.Length > 1) + return new DerEnumerated(enc); + if (enc.Length == 0) + throw new ArgumentException("ENUMERATED has zero length", "enc"); + + int value = enc[0]; + if (value >= cache.Length) + return new DerEnumerated(enc); + + DerEnumerated possibleMatch = cache[value]; + if (possibleMatch == null) + { + cache[value] = possibleMatch = new DerEnumerated(enc); + } + return possibleMatch; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerEnumerated.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerEnumerated.cs.meta new file mode 100644 index 0000000..f732449 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerEnumerated.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 193f0adc31c4d3a49bc656f0189c1590 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerGeneralString.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerGeneralString.cs new file mode 100644 index 0000000..01c75e2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerGeneralString.cs @@ -0,0 +1,85 @@ +using System; +using System.Text; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + public class DerGeneralString + : DerStringBase + { + private readonly string str; + + public static DerGeneralString GetInstance( + object obj) + { + if (obj == null || obj is DerGeneralString) + { + return (DerGeneralString) obj; + } + + throw new ArgumentException("illegal object in GetInstance: " + + Platform.GetTypeName(obj)); + } + + public static DerGeneralString GetInstance( + Asn1TaggedObject obj, + bool isExplicit) + { + Asn1Object o = obj.GetObject(); + + if (isExplicit || o is DerGeneralString) + { + return GetInstance(o); + } + + return new DerGeneralString(((Asn1OctetString)o).GetOctets()); + } + + public DerGeneralString( + byte[] str) + : this(Strings.FromAsciiByteArray(str)) + { + } + + public DerGeneralString( + string str) + { + if (str == null) + throw new ArgumentNullException("str"); + + this.str = str; + } + + public override string GetString() + { + return str; + } + + public byte[] GetOctets() + { + return Strings.ToAsciiByteArray(str); + } + + internal override int EncodedLength(bool withID) + { + return Asn1OutputStream.GetLengthOfEncodingDL(withID, str.Length); + } + + internal override void Encode(Asn1OutputStream asn1Out, bool withID) + { + asn1Out.WriteEncodingDL(withID, Asn1Tags.GeneralString, GetOctets()); + } + + protected override bool Asn1Equals( + Asn1Object asn1Object) + { + DerGeneralString other = asn1Object as DerGeneralString; + + if (other == null) + return false; + + return this.str.Equals(other.str); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerGeneralString.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerGeneralString.cs.meta new file mode 100644 index 0000000..4f6263d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerGeneralString.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a0782193b4e388d4b84c27cfe3e405e6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerGeneralizedTime.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerGeneralizedTime.cs new file mode 100644 index 0000000..bf4072b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerGeneralizedTime.cs @@ -0,0 +1,324 @@ +using System; +using System.Globalization; +using System.Text; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + /** + * Generalized time object. + */ + public class DerGeneralizedTime + : Asn1Object + { + private readonly string time; + + /** + * return a generalized time from the passed in object + * + * @exception ArgumentException if the object cannot be converted. + */ + public static DerGeneralizedTime GetInstance( + object obj) + { + if (obj == null || obj is DerGeneralizedTime) + { + return (DerGeneralizedTime)obj; + } + + throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj), "obj"); + } + + /** + * return a Generalized Time object from a tagged object. + * + * @param obj the tagged object holding the object we want + * @param explicitly true if the object is meant to be explicitly + * tagged false otherwise. + * @exception ArgumentException if the tagged object cannot + * be converted. + */ + public static DerGeneralizedTime GetInstance( + Asn1TaggedObject obj, + bool isExplicit) + { + Asn1Object o = obj.GetObject(); + + if (isExplicit || o is DerGeneralizedTime) + { + return GetInstance(o); + } + + return new DerGeneralizedTime(((Asn1OctetString)o).GetOctets()); + } + + /** + * The correct format for this is YYYYMMDDHHMMSS[.f]Z, or without the Z + * for local time, or Z+-HHMM on the end, for difference between local + * time and UTC time. The fractional second amount f must consist of at + * least one number with trailing zeroes removed. + * + * @param time the time string. + * @exception ArgumentException if string is an illegal format. + */ + public DerGeneralizedTime( + string time) + { + this.time = time; + + try + { + ToDateTime(); + } + catch (FormatException e) + { + throw new ArgumentException("invalid date string: " + e.Message); + } + } + + /** + * base constructor from a local time object + */ + public DerGeneralizedTime( + DateTime time) + { +#if PORTABLE + this.time = time.ToUniversalTime().ToString(@"yyyyMMddHHmmss\Z"); +#else + this.time = time.ToString(@"yyyyMMddHHmmss\Z"); +#endif + } + + internal DerGeneralizedTime( + byte[] bytes) + { + // + // explicitly convert to characters + // + this.time = Strings.FromAsciiByteArray(bytes); + } + + /** + * Return the time. + * @return The time string as it appeared in the encoded object. + */ + public string TimeString + { + get { return time; } + } + + /** + * return the time - always in the form of + * YYYYMMDDhhmmssGMT(+hh:mm|-hh:mm). + *

+ * Normally in a certificate we would expect "Z" rather than "GMT", + * however adding the "GMT" means we can just use: + *

+         *     dateF = new SimpleDateFormat("yyyyMMddHHmmssz");
+         * 
+ * To read in the time and Get a date which is compatible with our local + * time zone.

+ */ + public string GetTime() + { + // + // standardise the format. + // + if (time[time.Length - 1] == 'Z') + { + return time.Substring(0, time.Length - 1) + "GMT+00:00"; + } + else + { + int signPos = time.Length - 5; + char sign = time[signPos]; + if (sign == '-' || sign == '+') + { + return time.Substring(0, signPos) + + "GMT" + + time.Substring(signPos, 3) + + ":" + + time.Substring(signPos + 3); + } + else + { + signPos = time.Length - 3; + sign = time[signPos]; + if (sign == '-' || sign == '+') + { + return time.Substring(0, signPos) + + "GMT" + + time.Substring(signPos) + + ":00"; + } + } + } + + return time + CalculateGmtOffset(); + } + + private string CalculateGmtOffset() + { + char sign = '+'; + DateTime time = ToDateTime(); + +#if SILVERLIGHT || PORTABLE + long offset = time.Ticks - time.ToUniversalTime().Ticks; + if (offset < 0) + { + sign = '-'; + offset = -offset; + } + int hours = (int)(offset / TimeSpan.TicksPerHour); + int minutes = (int)(offset / TimeSpan.TicksPerMinute) % 60; +#else + // Note: GetUtcOffset incorporates Daylight Savings offset + TimeSpan offset = TimeZone.CurrentTimeZone.GetUtcOffset(time); + if (offset.CompareTo(TimeSpan.Zero) < 0) + { + sign = '-'; + offset = offset.Duration(); + } + int hours = offset.Hours; + int minutes = offset.Minutes; +#endif + + return "GMT" + sign + Convert(hours) + ":" + Convert(minutes); + } + + private static string Convert( + int time) + { + if (time < 10) + { + return "0" + time; + } + + return time.ToString(); + } + + public DateTime ToDateTime() + { + string formatStr; + string d = time; + bool makeUniversal = false; + + if (Platform.EndsWith(d, "Z")) + { + if (HasFractionalSeconds) + { + int fCount = d.Length - d.IndexOf('.') - 2; + formatStr = @"yyyyMMddHHmmss." + FString(fCount) + @"\Z"; + } + else + { + formatStr = @"yyyyMMddHHmmss\Z"; + } + } + else if (time.IndexOf('-') > 0 || time.IndexOf('+') > 0) + { + d = GetTime(); + makeUniversal = true; + + if (HasFractionalSeconds) + { + int fCount = Platform.IndexOf(d, "GMT") - 1 - d.IndexOf('.'); + formatStr = @"yyyyMMddHHmmss." + FString(fCount) + @"'GMT'zzz"; + } + else + { + formatStr = @"yyyyMMddHHmmss'GMT'zzz"; + } + } + else + { + if (HasFractionalSeconds) + { + int fCount = d.Length - 1 - d.IndexOf('.'); + formatStr = @"yyyyMMddHHmmss." + FString(fCount); + } + else + { + formatStr = @"yyyyMMddHHmmss"; + } + + // TODO? +// dateF.setTimeZone(new SimpleTimeZone(0, TimeZone.getDefault().getID())); + } + + return ParseDateString(d, formatStr, makeUniversal); + } + + private string FString( + int count) + { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < count; ++i) + { + sb.Append('f'); + } + return sb.ToString(); + } + + private DateTime ParseDateString(string s, string format, bool makeUniversal) + { + /* + * NOTE: DateTime.Kind and DateTimeStyles.AssumeUniversal not available in .NET 1.1 + */ + DateTimeStyles style = DateTimeStyles.None; + if (Platform.EndsWith(format, "Z")) + { + try + { + style = (DateTimeStyles)Enums.GetEnumValue(typeof(DateTimeStyles), "AssumeUniversal"); + } + catch (Exception) + { + } + + style |= DateTimeStyles.AdjustToUniversal; + } + + DateTime dt = DateTime.ParseExact(s, format, DateTimeFormatInfo.InvariantInfo, style); + + return makeUniversal ? dt.ToUniversalTime() : dt; + } + + private bool HasFractionalSeconds + { + get { return time.IndexOf('.') == 14; } + } + + private byte[] GetOctets() + { + return Strings.ToAsciiByteArray(time); + } + + internal override int EncodedLength(bool withID) + { + return Asn1OutputStream.GetLengthOfEncodingDL(withID, time.Length); + } + + internal override void Encode(Asn1OutputStream asn1Out, bool withID) + { + asn1Out.WriteEncodingDL(withID, Asn1Tags.GeneralizedTime, GetOctets()); + } + + protected override bool Asn1Equals( + Asn1Object asn1Object) + { + DerGeneralizedTime other = asn1Object as DerGeneralizedTime; + + if (other == null) + return false; + + return this.time.Equals(other.time); + } + + protected override int Asn1GetHashCode() + { + return time.GetHashCode(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerGeneralizedTime.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerGeneralizedTime.cs.meta new file mode 100644 index 0000000..0bce0a5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerGeneralizedTime.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dae6fefeb321d1f428df93e8a0724c36 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerGraphicString.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerGraphicString.cs new file mode 100644 index 0000000..598b8bc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerGraphicString.cs @@ -0,0 +1,108 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + public class DerGraphicString + : DerStringBase + { + private readonly byte[] mString; + + /** + * return a Graphic String from the passed in object + * + * @param obj a DerGraphicString or an object that can be converted into one. + * @exception IllegalArgumentException if the object cannot be converted. + * @return a DerGraphicString instance, or null. + */ + public static DerGraphicString GetInstance(object obj) + { + if (obj == null || obj is DerGraphicString) + { + return (DerGraphicString)obj; + } + + if (obj is byte[]) + { + try + { + return (DerGraphicString)FromByteArray((byte[])obj); + } + catch (Exception e) + { + throw new ArgumentException("encoding error in GetInstance: " + e.ToString(), "obj"); + } + } + + throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj), "obj"); + } + + /** + * return a Graphic String from a tagged object. + * + * @param obj the tagged object holding the object we want + * @param explicit true if the object is meant to be explicitly + * tagged false otherwise. + * @exception IllegalArgumentException if the tagged object cannot + * be converted. + * @return a DerGraphicString instance, or null. + */ + public static DerGraphicString GetInstance(Asn1TaggedObject obj, bool isExplicit) + { + Asn1Object o = obj.GetObject(); + + if (isExplicit || o is DerGraphicString) + { + return GetInstance(o); + } + + return new DerGraphicString(((Asn1OctetString)o).GetOctets()); + } + + /** + * basic constructor - with bytes. + * @param string the byte encoding of the characters making up the string. + */ + public DerGraphicString(byte[] encoding) + { + this.mString = Arrays.Clone(encoding); + } + + public override string GetString() + { + return Strings.FromByteArray(mString); + } + + public byte[] GetOctets() + { + return Arrays.Clone(mString); + } + + internal override int EncodedLength(bool withID) + { + return Asn1OutputStream.GetLengthOfEncodingDL(withID, mString.Length); + } + + internal override void Encode(Asn1OutputStream asn1Out, bool withID) + { + asn1Out.WriteEncodingDL(withID, Asn1Tags.GraphicString, mString); + } + + protected override int Asn1GetHashCode() + { + return Arrays.GetHashCode(mString); + } + + protected override bool Asn1Equals( + Asn1Object asn1Object) + { + DerGraphicString other = asn1Object as DerGraphicString; + + if (other == null) + return false; + + return Arrays.AreEqual(mString, other.mString); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerGraphicString.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerGraphicString.cs.meta new file mode 100644 index 0000000..925f740 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerGraphicString.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8cd879fa3d9155e45810f046e3b77980 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerIA5String.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerIA5String.cs new file mode 100644 index 0000000..c23a483 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerIA5String.cs @@ -0,0 +1,149 @@ +using System; +using System.Text; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + /** + * Der IA5String object - this is an ascii string. + */ + public class DerIA5String + : DerStringBase + { + private readonly string str; + + /** + * return a IA5 string from the passed in object + * + * @exception ArgumentException if the object cannot be converted. + */ + public static DerIA5String GetInstance( + object obj) + { + if (obj == null || obj is DerIA5String) + { + return (DerIA5String)obj; + } + + throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj)); + } + + /** + * return an IA5 string from a tagged object. + * + * @param obj the tagged object holding the object we want + * @param explicitly true if the object is meant to be explicitly + * tagged false otherwise. + * @exception ArgumentException if the tagged object cannot + * be converted. + */ + public static DerIA5String GetInstance( + Asn1TaggedObject obj, + bool isExplicit) + { + Asn1Object o = obj.GetObject(); + + if (isExplicit || o is DerIA5String) + { + return GetInstance(o); + } + + return new DerIA5String(((Asn1OctetString)o).GetOctets()); + } + + /** + * basic constructor - with bytes. + */ + public DerIA5String( + byte[] str) + : this(Strings.FromAsciiByteArray(str), false) + { + } + + /** + * basic constructor - without validation. + */ + public DerIA5String( + string str) + : this(str, false) + { + } + + /** + * Constructor with optional validation. + * + * @param string the base string to wrap. + * @param validate whether or not to check the string. + * @throws ArgumentException if validate is true and the string + * contains characters that should not be in an IA5String. + */ + public DerIA5String( + string str, + bool validate) + { + if (str == null) + throw new ArgumentNullException("str"); + if (validate && !IsIA5String(str)) + throw new ArgumentException("string contains illegal characters", "str"); + + this.str = str; + } + + public override string GetString() + { + return str; + } + + public byte[] GetOctets() + { + return Strings.ToAsciiByteArray(str); + } + + internal override int EncodedLength(bool withID) + { + return Asn1OutputStream.GetLengthOfEncodingDL(withID, str.Length); + } + + internal override void Encode(Asn1OutputStream asn1Out, bool withID) + { + asn1Out.WriteEncodingDL(withID, Asn1Tags.IA5String, GetOctets()); + } + + protected override int Asn1GetHashCode() + { + return this.str.GetHashCode(); + } + + protected override bool Asn1Equals( + Asn1Object asn1Object) + { + DerIA5String other = asn1Object as DerIA5String; + + if (other == null) + return false; + + return this.str.Equals(other.str); + } + + /** + * return true if the passed in String can be represented without + * loss as an IA5String, false otherwise. + * + * @return true if in printable set, false otherwise. + */ + public static bool IsIA5String( + string str) + { + foreach (char ch in str) + { + if (ch > 0x007f) + { + return false; + } + } + + return true; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerIA5String.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerIA5String.cs.meta new file mode 100644 index 0000000..223e22c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerIA5String.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5b47db2009ecd9d4e97d6ec4b8734eac +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerInteger.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerInteger.cs new file mode 100644 index 0000000..fc30ad5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerInteger.cs @@ -0,0 +1,257 @@ +using System; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + public class DerInteger + : Asn1Object + { + public const string AllowUnsafeProperty = "Org.BouncyCastle.Asn1.AllowUnsafeInteger"; + + internal static bool AllowUnsafe() + { + string allowUnsafeValue = Platform.GetEnvironmentVariable(AllowUnsafeProperty); + return allowUnsafeValue != null && Platform.EqualsIgnoreCase("true", allowUnsafeValue); + } + + internal const int SignExtSigned = -1; + internal const int SignExtUnsigned = 0xFF; + + private readonly byte[] bytes; + private readonly int start; + + /** + * return an integer from the passed in object + * + * @exception ArgumentException if the object cannot be converted. + */ + public static DerInteger GetInstance( + object obj) + { + if (obj == null || obj is DerInteger) + { + return (DerInteger)obj; + } + + throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj)); + } + + /** + * return an Integer from a tagged object. + * + * @param obj the tagged object holding the object we want + * @param isExplicit true if the object is meant to be explicitly + * tagged false otherwise. + * @exception ArgumentException if the tagged object cannot + * be converted. + */ + public static DerInteger GetInstance( + Asn1TaggedObject obj, + bool isExplicit) + { + if (obj == null) + throw new ArgumentNullException("obj"); + + Asn1Object o = obj.GetObject(); + + if (isExplicit || o is DerInteger) + { + return GetInstance(o); + } + + return new DerInteger(Asn1OctetString.GetInstance(o).GetOctets()); + } + + public DerInteger(int value) + { + this.bytes = BigInteger.ValueOf(value).ToByteArray(); + this.start = 0; + } + + public DerInteger(long value) + { + this.bytes = BigInteger.ValueOf(value).ToByteArray(); + this.start = 0; + } + + public DerInteger(BigInteger value) + { + if (value == null) + throw new ArgumentNullException("value"); + + this.bytes = value.ToByteArray(); + this.start = 0; + } + + public DerInteger(byte[] bytes) + : this(bytes, true) + { + } + + internal DerInteger(byte[] bytes, bool clone) + { + if (IsMalformed(bytes)) + throw new ArgumentException("malformed integer", "bytes"); + + this.bytes = clone ? Arrays.Clone(bytes) : bytes; + this.start = SignBytesToSkip(bytes); + } + + /** + * in some cases positive values Get crammed into a space, + * that's not quite big enough... + */ + public BigInteger PositiveValue + { + get { return new BigInteger(1, bytes); } + } + + public BigInteger Value + { + get { return new BigInteger(bytes); } + } + + public bool HasValue(int x) + { + return (bytes.Length - start) <= 4 + && IntValue(bytes, start, SignExtSigned) == x; + } + + public bool HasValue(long x) + { + return (bytes.Length - start) <= 8 + && LongValue(bytes, start, SignExtSigned) == x; + } + + public bool HasValue(BigInteger x) + { + return null != x + // Fast check to avoid allocation + && IntValue(bytes, start, SignExtSigned) == x.IntValue + && Value.Equals(x); + } + + public int IntPositiveValueExact + { + get + { + int count = bytes.Length - start; + if (count > 4 || (count == 4 && 0 != (bytes[start] & 0x80))) + throw new ArithmeticException("ASN.1 Integer out of positive int range"); + + return IntValue(bytes, start, SignExtUnsigned); + } + } + + public int IntValueExact + { + get + { + int count = bytes.Length - start; + if (count > 4) + throw new ArithmeticException("ASN.1 Integer out of int range"); + + return IntValue(bytes, start, SignExtSigned); + } + } + + public long LongValueExact + { + get + { + int count = bytes.Length - start; + if (count > 8) + throw new ArithmeticException("ASN.1 Integer out of long range"); + + return LongValue(bytes, start, SignExtSigned); + } + } + + internal override int EncodedLength(bool withID) + { + return Asn1OutputStream.GetLengthOfEncodingDL(withID, bytes.Length); + } + + internal override void Encode(Asn1OutputStream asn1Out, bool withID) + { + asn1Out.WriteEncodingDL(withID, Asn1Tags.Integer, bytes); + } + + protected override int Asn1GetHashCode() + { + return Arrays.GetHashCode(bytes); + } + + protected override bool Asn1Equals(Asn1Object asn1Object) + { + DerInteger other = asn1Object as DerInteger; + if (other == null) + return false; + + return Arrays.AreEqual(this.bytes, other.bytes); + } + + public override string ToString() + { + return Value.ToString(); + } + + internal static int IntValue(byte[] bytes, int start, int signExt) + { + int length = bytes.Length; + int pos = System.Math.Max(start, length - 4); + + int val = (sbyte)bytes[pos] & signExt; + while (++pos < length) + { + val = (val << 8) | bytes[pos]; + } + return val; + } + + internal static long LongValue(byte[] bytes, int start, int signExt) + { + int length = bytes.Length; + int pos = System.Math.Max(start, length - 8); + + long val = (sbyte)bytes[pos] & signExt; + while (++pos < length) + { + val = (val << 8) | bytes[pos]; + } + return val; + } + + /** + * Apply the correct validation for an INTEGER primitive following the BER rules. + * + * @param bytes The raw encoding of the integer. + * @return true if the (in)put fails this validation. + */ + internal static bool IsMalformed(byte[] bytes) + { + switch (bytes.Length) + { + case 0: + return true; + case 1: + return false; + default: + return (sbyte)bytes[0] == ((sbyte)bytes[1] >> 7) && !AllowUnsafe(); + } + } + + internal static int SignBytesToSkip(byte[] bytes) + { + int pos = 0, last = bytes.Length - 1; + while (pos < last + && (sbyte)bytes[pos] == ((sbyte)bytes[pos + 1] >> 7)) + { + ++pos; + } + return pos; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerInteger.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerInteger.cs.meta new file mode 100644 index 0000000..21d4423 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerInteger.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0ad6d978951d7f04ba21c70bdffd612a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerNull.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerNull.cs new file mode 100644 index 0000000..1ee374d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerNull.cs @@ -0,0 +1,39 @@ +using System; + +namespace Org.BouncyCastle.Asn1 +{ + /** + * A Null object. + */ + public class DerNull + : Asn1Null + { + public static readonly DerNull Instance = new DerNull(); + + private static readonly byte[] ZeroBytes = new byte[0]; + + protected internal DerNull() + { + } + + internal override int EncodedLength(bool withID) + { + return Asn1OutputStream.GetLengthOfEncodingDL(withID, 0); + } + + internal override void Encode(Asn1OutputStream asn1Out, bool withID) + { + asn1Out.WriteEncodingDL(withID, Asn1Tags.Null, ZeroBytes); + } + + protected override bool Asn1Equals(Asn1Object asn1Object) + { + return asn1Object is DerNull; + } + + protected override int Asn1GetHashCode() + { + return -1; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerNull.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerNull.cs.meta new file mode 100644 index 0000000..e78a33a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerNull.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 386733b5f1af370429e8b17111fa8055 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerNumericString.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerNumericString.cs new file mode 100644 index 0000000..310c18e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerNumericString.cs @@ -0,0 +1,142 @@ +using System; +using System.Text; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + /** + * Der NumericString object - this is an ascii string of characters {0,1,2,3,4,5,6,7,8,9, }. + */ + public class DerNumericString + : DerStringBase + { + private readonly string str; + + /** + * return a Numeric string from the passed in object + * + * @exception ArgumentException if the object cannot be converted. + */ + public static DerNumericString GetInstance( + object obj) + { + if (obj == null || obj is DerNumericString) + { + return (DerNumericString)obj; + } + + throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj)); + } + + /** + * return an Numeric string from a tagged object. + * + * @param obj the tagged object holding the object we want + * @param explicitly true if the object is meant to be explicitly + * tagged false otherwise. + * @exception ArgumentException if the tagged object cannot + * be converted. + */ + public static DerNumericString GetInstance( + Asn1TaggedObject obj, + bool isExplicit) + { + Asn1Object o = obj.GetObject(); + + if (isExplicit || o is DerNumericString) + { + return GetInstance(o); + } + + return new DerNumericString(Asn1OctetString.GetInstance(o).GetOctets()); + } + + /** + * basic constructor - with bytes. + */ + public DerNumericString( + byte[] str) + : this(Strings.FromAsciiByteArray(str), false) + { + } + + /** + * basic constructor - without validation.. + */ + public DerNumericString( + string str) + : this(str, false) + { + } + + /** + * Constructor with optional validation. + * + * @param string the base string to wrap. + * @param validate whether or not to check the string. + * @throws ArgumentException if validate is true and the string + * contains characters that should not be in a NumericString. + */ + public DerNumericString( + string str, + bool validate) + { + if (str == null) + throw new ArgumentNullException("str"); + if (validate && !IsNumericString(str)) + throw new ArgumentException("string contains illegal characters", "str"); + + this.str = str; + } + + public override string GetString() + { + return str; + } + + public byte[] GetOctets() + { + return Strings.ToAsciiByteArray(str); + } + + internal override int EncodedLength(bool withID) + { + return Asn1OutputStream.GetLengthOfEncodingDL(withID, str.Length); + } + + internal override void Encode(Asn1OutputStream asn1Out, bool withID) + { + asn1Out.WriteEncodingDL(withID, Asn1Tags.NumericString, GetOctets()); + } + + protected override bool Asn1Equals( + Asn1Object asn1Object) + { + DerNumericString other = asn1Object as DerNumericString; + + if (other == null) + return false; + + return this.str.Equals(other.str); + } + + /** + * Return true if the string can be represented as a NumericString ('0'..'9', ' ') + * + * @param str string to validate. + * @return true if numeric, fale otherwise. + */ + public static bool IsNumericString( + string str) + { + foreach (char ch in str) + { + if (ch > 0x007f || (ch != ' ' && !char.IsDigit(ch))) + return false; + } + + return true; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerNumericString.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerNumericString.cs.meta new file mode 100644 index 0000000..7f3a234 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerNumericString.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5fe3e00e83aea23438ae65cccea8d560 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerObjectIdentifier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerObjectIdentifier.cs new file mode 100644 index 0000000..d9cd800 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerObjectIdentifier.cs @@ -0,0 +1,372 @@ +using System; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + public class DerObjectIdentifier + : Asn1Object + { + public static DerObjectIdentifier FromContents(byte[] contents) + { + return CreatePrimitive(contents, true); + } + + private readonly string identifier; + private byte[] contents; + + /** + * return an Oid from the passed in object + * + * @exception ArgumentException if the object cannot be converted. + */ + public static DerObjectIdentifier GetInstance(object obj) + { + if (obj == null || obj is DerObjectIdentifier) + return (DerObjectIdentifier) obj; + + if (obj is Asn1Encodable) + { + Asn1Object asn1Obj = ((Asn1Encodable)obj).ToAsn1Object(); + + if (asn1Obj is DerObjectIdentifier) + return (DerObjectIdentifier)asn1Obj; + } + + if (obj is byte[]) + return (DerObjectIdentifier)FromByteArray((byte[])obj); + + throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj), "obj"); + } + + /** + * return an object Identifier from a tagged object. + * + * @param obj the tagged object holding the object we want + * @param explicitly true if the object is meant to be explicitly + * tagged false otherwise. + * @exception ArgumentException if the tagged object cannot + * be converted. + */ + public static DerObjectIdentifier GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + Asn1Object o = obj.GetObject(); + + if (explicitly || o is DerObjectIdentifier) + { + return GetInstance(o); + } + + return FromContents(Asn1OctetString.GetInstance(o).GetOctets()); + } + + public DerObjectIdentifier( + string identifier) + { + if (identifier == null) + throw new ArgumentNullException("identifier"); + if (!IsValidIdentifier(identifier)) + throw new FormatException("string " + identifier + " not an OID"); + + this.identifier = identifier; + } + + internal DerObjectIdentifier(DerObjectIdentifier oid, string branchID) + { + if (!IsValidBranchID(branchID, 0)) + throw new ArgumentException("string " + branchID + " not a valid OID branch", "branchID"); + + this.identifier = oid.Id + "." + branchID; + } + + // TODO Change to ID? + public string Id + { + get { return identifier; } + } + + public virtual DerObjectIdentifier Branch(string branchID) + { + return new DerObjectIdentifier(this, branchID); + } + + /** + * Return true if this oid is an extension of the passed in branch, stem. + * @param stem the arc or branch that is a possible parent. + * @return true if the branch is on the passed in stem, false otherwise. + */ + public virtual bool On(DerObjectIdentifier stem) + { + string id = Id, stemId = stem.Id; + return id.Length > stemId.Length && id[stemId.Length] == '.' && Platform.StartsWith(id, stemId); + } + + internal DerObjectIdentifier(byte[] contents, bool clone) + { + this.identifier = MakeOidStringFromBytes(contents); + this.contents = clone ? Arrays.Clone(contents) : contents; + } + + private void WriteField( + Stream outputStream, + long fieldValue) + { + byte[] result = new byte[9]; + int pos = 8; + result[pos] = (byte)(fieldValue & 0x7f); + while (fieldValue >= (1L << 7)) + { + fieldValue >>= 7; + result[--pos] = (byte)((fieldValue & 0x7f) | 0x80); + } + outputStream.Write(result, pos, 9 - pos); + } + + private void WriteField( + Stream outputStream, + BigInteger fieldValue) + { + int byteCount = (fieldValue.BitLength + 6) / 7; + if (byteCount == 0) + { + outputStream.WriteByte(0); + } + else + { + BigInteger tmpValue = fieldValue; + byte[] tmp = new byte[byteCount]; + for (int i = byteCount-1; i >= 0; i--) + { + tmp[i] = (byte) ((tmpValue.IntValue & 0x7f) | 0x80); + tmpValue = tmpValue.ShiftRight(7); + } + tmp[byteCount-1] &= 0x7f; + outputStream.Write(tmp, 0, tmp.Length); + } + } + + private void DoOutput(MemoryStream bOut) + { + OidTokenizer tok = new OidTokenizer(identifier); + + string token = tok.NextToken(); + int first = int.Parse(token) * 40; + + token = tok.NextToken(); + if (token.Length <= 18) + { + WriteField(bOut, first + Int64.Parse(token)); + } + else + { + WriteField(bOut, new BigInteger(token).Add(BigInteger.ValueOf(first))); + } + + while (tok.HasMoreTokens) + { + token = tok.NextToken(); + if (token.Length <= 18) + { + WriteField(bOut, Int64.Parse(token)); + } + else + { + WriteField(bOut, new BigInteger(token)); + } + } + } + + private byte[] GetContents() + { + lock (this) + { + if (contents == null) + { + MemoryStream bOut = new MemoryStream(); + DoOutput(bOut); + contents = bOut.ToArray(); + } + + return contents; + } + } + + internal override int EncodedLength(bool withID) + { + return Asn1OutputStream.GetLengthOfEncodingDL(withID, GetContents().Length); + } + + internal override void Encode(Asn1OutputStream asn1Out, bool withID) + { + asn1Out.WriteEncodingDL(withID, Asn1Tags.ObjectIdentifier, GetContents()); + } + + protected override int Asn1GetHashCode() + { + return identifier.GetHashCode(); + } + + protected override bool Asn1Equals( + Asn1Object asn1Object) + { + DerObjectIdentifier other = asn1Object as DerObjectIdentifier; + + if (other == null) + return false; + + return this.identifier.Equals(other.identifier); + } + + public override string ToString() + { + return identifier; + } + + private static bool IsValidBranchID(string branchID, int start) + { + int digitCount = 0; + + int pos = branchID.Length; + while (--pos >= start) + { + char ch = branchID[pos]; + + if (ch == '.') + { + if (0 == digitCount || (digitCount > 1 && branchID[pos + 1] == '0')) + return false; + + digitCount = 0; + } + else if ('0' <= ch && ch <= '9') + { + ++digitCount; + } + else + { + return false; + } + } + + if (0 == digitCount || (digitCount > 1 && branchID[pos + 1] == '0')) + return false; + + return true; + } + + private static bool IsValidIdentifier(string identifier) + { + if (identifier.Length < 3 || identifier[1] != '.') + return false; + + char first = identifier[0]; + if (first < '0' || first > '2') + return false; + + return IsValidBranchID(identifier, 2); + } + + private const long LONG_LIMIT = (long.MaxValue >> 7) - 0x7f; + + private static string MakeOidStringFromBytes( + byte[] bytes) + { + StringBuilder objId = new StringBuilder(); + long value = 0; + BigInteger bigValue = null; + bool first = true; + + for (int i = 0; i != bytes.Length; i++) + { + int b = bytes[i]; + + if (value <= LONG_LIMIT) + { + value += (b & 0x7f); + if ((b & 0x80) == 0) // end of number reached + { + if (first) + { + if (value < 40) + { + objId.Append('0'); + } + else if (value < 80) + { + objId.Append('1'); + value -= 40; + } + else + { + objId.Append('2'); + value -= 80; + } + first = false; + } + + objId.Append('.'); + objId.Append(value); + value = 0; + } + else + { + value <<= 7; + } + } + else + { + if (bigValue == null) + { + bigValue = BigInteger.ValueOf(value); + } + bigValue = bigValue.Or(BigInteger.ValueOf(b & 0x7f)); + if ((b & 0x80) == 0) + { + if (first) + { + objId.Append('2'); + bigValue = bigValue.Subtract(BigInteger.ValueOf(80)); + first = false; + } + + objId.Append('.'); + objId.Append(bigValue); + bigValue = null; + value = 0; + } + else + { + bigValue = bigValue.ShiftLeft(7); + } + } + } + + return objId.ToString(); + } + + private static readonly DerObjectIdentifier[] cache = new DerObjectIdentifier[1024]; + + internal static DerObjectIdentifier CreatePrimitive(byte[] contents, bool clone) + { + int hashCode = Arrays.GetHashCode(contents); + int first = hashCode & 1023; + + lock (cache) + { + DerObjectIdentifier entry = cache[first]; + if (entry != null && Arrays.AreEqual(contents, entry.GetContents())) + { + return entry; + } + + return cache[first] = new DerObjectIdentifier(contents, clone); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerObjectIdentifier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerObjectIdentifier.cs.meta new file mode 100644 index 0000000..6baf85a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerObjectIdentifier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6cda490525aa1b044aeed42ef9674907 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerOctetString.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerOctetString.cs new file mode 100644 index 0000000..bcd4e73 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerOctetString.cs @@ -0,0 +1,45 @@ +using System; + +namespace Org.BouncyCastle.Asn1 +{ + public class DerOctetString + : Asn1OctetString + { + /// The octets making up the octet string. + public DerOctetString( + byte[] str) + : base(str) + { + } + + public DerOctetString(IAsn1Convertible obj) + : this(obj.ToAsn1Object()) + { + } + + public DerOctetString(Asn1Encodable obj) + : base(obj.GetEncoded(Der)) + { + } + + internal override int EncodedLength(bool withID) + { + return Asn1OutputStream.GetLengthOfEncodingDL(withID, str.Length); + } + + internal override void Encode(Asn1OutputStream asn1Out, bool withID) + { + asn1Out.WriteEncodingDL(withID, Asn1Tags.OctetString, str); + } + + internal static void Encode(Asn1OutputStream asn1Out, bool withID, byte[] buf, int off, int len) + { + asn1Out.WriteEncodingDL(withID, Asn1Tags.OctetString, buf, off, len); + } + + internal static int EncodedLength(bool withID, int contentsLength) + { + return Asn1OutputStream.GetLengthOfEncodingDL(withID, contentsLength); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerOctetString.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerOctetString.cs.meta new file mode 100644 index 0000000..db97e13 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerOctetString.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 00cffcec40fb6554094f99ee00f8bf86 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerOutputStream.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerOutputStream.cs new file mode 100644 index 0000000..b8cbe9e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerOutputStream.cs @@ -0,0 +1,57 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Asn1 +{ + [Obsolete("Use 'Asn1OutputStream' instead")] + public class DerOutputStream + : FilterStream + { + [Obsolete("Use 'Asn1OutputStream.Create' instead")] + public DerOutputStream(Stream os) + : base(os) + { + } + + public virtual void WriteObject(Asn1Encodable encodable) + { + Asn1OutputStream.Create(s, Asn1Encodable.Der).WriteObject(encodable); + } + + public virtual void WriteObject(Asn1Object primitive) + { + Asn1OutputStream.Create(s, Asn1Encodable.Der).WriteObject(primitive); + } + } + + internal class DerOutputStreamNew + : Asn1OutputStream + { + internal DerOutputStreamNew(Stream os) + : base(os) + { + } + + internal override bool IsBer + { + get { return false; } + } + + internal override void WritePrimitive(Asn1Object primitive, bool withID) + { + Asn1Set asn1Set = primitive as Asn1Set; + if (null != asn1Set) + { + /* + * NOTE: Even a DerSet isn't necessarily already in sorted order (particularly from DerSetParser), + * so all sets have to be converted here. + */ + primitive = new DerSet(asn1Set.elements); + } + + primitive.Encode(this, withID); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerOutputStream.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerOutputStream.cs.meta new file mode 100644 index 0000000..e1bfeda --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerOutputStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b7520d29b3d83e94fa9c36ae17e4061b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerPrintableString.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerPrintableString.cs new file mode 100644 index 0000000..f450e28 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerPrintableString.cs @@ -0,0 +1,167 @@ +using System; +using System.Text; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + /** + * Der PrintableString object. + */ + public class DerPrintableString + : DerStringBase + { + private readonly string str; + + /** + * return a printable string from the passed in object. + * + * @exception ArgumentException if the object cannot be converted. + */ + public static DerPrintableString GetInstance( + object obj) + { + if (obj == null || obj is DerPrintableString) + { + return (DerPrintableString)obj; + } + + throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj)); + } + + /** + * return a Printable string from a tagged object. + * + * @param obj the tagged object holding the object we want + * @param explicitly true if the object is meant to be explicitly + * tagged false otherwise. + * @exception ArgumentException if the tagged object cannot + * be converted. + */ + public static DerPrintableString GetInstance( + Asn1TaggedObject obj, + bool isExplicit) + { + Asn1Object o = obj.GetObject(); + + if (isExplicit || o is DerPrintableString) + { + return GetInstance(o); + } + + return new DerPrintableString(Asn1OctetString.GetInstance(o).GetOctets()); + } + + /** + * basic constructor - byte encoded string. + */ + public DerPrintableString( + byte[] str) + : this(Strings.FromAsciiByteArray(str), false) + { + } + + /** + * basic constructor - this does not validate the string + */ + public DerPrintableString( + string str) + : this(str, false) + { + } + + /** + * Constructor with optional validation. + * + * @param string the base string to wrap. + * @param validate whether or not to check the string. + * @throws ArgumentException if validate is true and the string + * contains characters that should not be in a PrintableString. + */ + public DerPrintableString( + string str, + bool validate) + { + if (str == null) + throw new ArgumentNullException("str"); + if (validate && !IsPrintableString(str)) + throw new ArgumentException("string contains illegal characters", "str"); + + this.str = str; + } + + public override string GetString() + { + return str; + } + + public byte[] GetOctets() + { + return Strings.ToAsciiByteArray(str); + } + + internal override int EncodedLength(bool withID) + { + return Asn1OutputStream.GetLengthOfEncodingDL(withID, str.Length); + } + + internal override void Encode(Asn1OutputStream asn1Out, bool withID) + { + asn1Out.WriteEncodingDL(withID, Asn1Tags.PrintableString, GetOctets()); + } + + protected override bool Asn1Equals( + Asn1Object asn1Object) + { + DerPrintableString other = asn1Object as DerPrintableString; + + if (other == null) + return false; + + return this.str.Equals(other.str); + } + + /** + * return true if the passed in String can be represented without + * loss as a PrintableString, false otherwise. + * + * @return true if in printable set, false otherwise. + */ + public static bool IsPrintableString( + string str) + { + foreach (char ch in str) + { + if (ch > 0x007f) + return false; + + if (char.IsLetterOrDigit(ch)) + continue; + +// if (char.IsPunctuation(ch)) +// continue; + + switch (ch) + { + case ' ': + case '\'': + case '(': + case ')': + case '+': + case '-': + case '.': + case ':': + case '=': + case '?': + case '/': + case ',': + continue; + } + + return false; + } + + return true; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerPrintableString.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerPrintableString.cs.meta new file mode 100644 index 0000000..efa1d38 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerPrintableString.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 047567b3e832eea4c9afc69d893e9808 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerSequence.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerSequence.cs new file mode 100644 index 0000000..6750b8a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerSequence.cs @@ -0,0 +1,88 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + public class DerSequence + : Asn1Sequence + { + public static readonly DerSequence Empty = new DerSequence(); + + public static DerSequence FromVector(Asn1EncodableVector elementVector) + { + return elementVector.Count < 1 ? Empty : new DerSequence(elementVector); + } + + /** + * create an empty sequence + */ + public DerSequence() + : base() + { + } + + /** + * create a sequence containing one object + */ + public DerSequence(Asn1Encodable element) + : base(element) + { + } + + public DerSequence(params Asn1Encodable[] elements) + : base(elements) + { + } + + /** + * create a sequence containing a vector of objects. + */ + public DerSequence(Asn1EncodableVector elementVector) + : base(elementVector) + { + } + + internal override int EncodedLength(bool withID) + { + throw Platform.CreateNotImplementedException("DerSequence.EncodedLength"); + } + + /* + * A note on the implementation: + *

+ * As Der requires the constructed, definite-length model to + * be used for structured types, this varies slightly from the + * ASN.1 descriptions given. Rather than just outputing Sequence, + * we also have to specify Constructed, and the objects length. + */ + internal override void Encode(Asn1OutputStream asn1Out, bool withID) + { + if (Count < 1) + { + asn1Out.WriteEncodingDL(withID, Asn1Tags.Constructed | Asn1Tags.Sequence, Asn1OctetString.EmptyOctets); + return; + } + + // TODO Intermediate buffer could be avoided if we could calculate expected length + MemoryStream bOut = new MemoryStream(); + Asn1OutputStream dOut = Asn1OutputStream.Create(bOut, Der); + dOut.WriteElements(elements); + dOut.Flush(); + +#if PORTABLE + byte[] bytes = bOut.ToArray(); + int length = bytes.Length; +#else + byte[] bytes = bOut.GetBuffer(); + int length = (int)bOut.Position; +#endif + + asn1Out.WriteEncodingDL(withID, Asn1Tags.Constructed | Asn1Tags.Sequence, bytes, 0, length); + + Platform.Dispose(dOut); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerSequence.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerSequence.cs.meta new file mode 100644 index 0000000..5663cf0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerSequence.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cb2415e9e2abcbe4eac99d5438df4761 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerSet.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerSet.cs new file mode 100644 index 0000000..d401d3a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerSet.cs @@ -0,0 +1,105 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + /** + * A Der encoded set object + */ + public class DerSet + : Asn1Set + { + public static readonly DerSet Empty = new DerSet(); + + public static DerSet FromVector(Asn1EncodableVector elementVector) + { + return elementVector.Count < 1 ? Empty : new DerSet(elementVector); + } + + internal static DerSet FromVector(Asn1EncodableVector elementVector, bool needsSorting) + { + return elementVector.Count < 1 ? Empty : new DerSet(elementVector, needsSorting); + } + + /** + * create an empty set + */ + public DerSet() + : base() + { + } + + /** + * @param obj - a single object that makes up the set. + */ + public DerSet(Asn1Encodable element) + : base(element) + { + } + + public DerSet(params Asn1Encodable[] elements) + : base(elements) + { + Sort(); + } + + /** + * @param v - a vector of objects making up the set. + */ + public DerSet(Asn1EncodableVector elementVector) + : this(elementVector, true) + { + } + + internal DerSet(Asn1EncodableVector elementVector, bool needsSorting) + : base(elementVector) + { + if (needsSorting) + { + Sort(); + } + } + + internal override int EncodedLength(bool withID) + { + throw Platform.CreateNotImplementedException("DerSet.EncodedLength"); + } + + /* + * A note on the implementation: + *

+ * As Der requires the constructed, definite-length model to + * be used for structured types, this varies slightly from the + * ASN.1 descriptions given. Rather than just outputing Set, + * we also have to specify Constructed, and the objects length. + */ + internal override void Encode(Asn1OutputStream asn1Out, bool withID) + { + if (Count < 1) + { + asn1Out.WriteEncodingDL(withID, Asn1Tags.Constructed | Asn1Tags.Set, Asn1OctetString.EmptyOctets); + return; + } + + // TODO Intermediate buffer could be avoided if we could calculate expected length + MemoryStream bOut = new MemoryStream(); + Asn1OutputStream dOut = Asn1OutputStream.Create(bOut, Der); + dOut.WriteElements(elements); + dOut.Flush(); + +#if PORTABLE + byte[] bytes = bOut.ToArray(); + int length = bytes.Length; +#else + byte[] bytes = bOut.GetBuffer(); + int length = (int)bOut.Position; +#endif + + asn1Out.WriteEncodingDL(withID, Asn1Tags.Constructed | Asn1Tags.Set, bytes, 0, length); + + Platform.Dispose(dOut); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerSet.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerSet.cs.meta new file mode 100644 index 0000000..37f9255 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerSet.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c7986f2a8dbbdbd4a80263205a447f45 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerStringBase.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerStringBase.cs new file mode 100644 index 0000000..2a5fb04 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerStringBase.cs @@ -0,0 +1,22 @@ +namespace Org.BouncyCastle.Asn1 +{ + public abstract class DerStringBase + : Asn1Object, IAsn1String + { + protected DerStringBase() + { + } + + public abstract string GetString(); + + public override string ToString() + { + return GetString(); + } + + protected override int Asn1GetHashCode() + { + return GetString().GetHashCode(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerStringBase.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerStringBase.cs.meta new file mode 100644 index 0000000..1be7c69 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerStringBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8263b03b45d07b8428bcea52365474ea +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerT61String.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerT61String.cs new file mode 100644 index 0000000..82a8b3a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerT61String.cs @@ -0,0 +1,106 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + /** + * Der T61String (also the teletex string) - 8-bit characters + */ + public class DerT61String + : DerStringBase + { + private readonly string str; + + /** + * return a T61 string from the passed in object. + * + * @exception ArgumentException if the object cannot be converted. + */ + public static DerT61String GetInstance( + object obj) + { + if (obj == null || obj is DerT61String) + { + return (DerT61String)obj; + } + + throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj)); + } + + /** + * return an T61 string from a tagged object. + * + * @param obj the tagged object holding the object we want + * @param explicitly true if the object is meant to be explicitly + * tagged false otherwise. + * @exception ArgumentException if the tagged object cannot + * be converted. + */ + public static DerT61String GetInstance( + Asn1TaggedObject obj, + bool isExplicit) + { + Asn1Object o = obj.GetObject(); + + if (isExplicit || o is DerT61String) + { + return GetInstance(o); + } + + return new DerT61String(Asn1OctetString.GetInstance(o).GetOctets()); + } + + /** + * basic constructor - with bytes. + */ + public DerT61String( + byte[] str) + : this(Strings.FromByteArray(str)) + { + } + + /** + * basic constructor - with string. + */ + public DerT61String( + string str) + { + if (str == null) + throw new ArgumentNullException("str"); + + this.str = str; + } + + public override string GetString() + { + return str; + } + + internal override int EncodedLength(bool withID) + { + return Asn1OutputStream.GetLengthOfEncodingDL(withID, str.Length); + } + + internal override void Encode(Asn1OutputStream asn1Out, bool withID) + { + asn1Out.WriteEncodingDL(withID, Asn1Tags.T61String, GetOctets()); + } + + public byte[] GetOctets() + { + return Strings.ToByteArray(str); + } + + protected override bool Asn1Equals( + Asn1Object asn1Object) + { + DerT61String other = asn1Object as DerT61String; + + if (other == null) + return false; + + return this.str.Equals(other.str); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerT61String.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerT61String.cs.meta new file mode 100644 index 0000000..6a8a232 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerT61String.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 44c130da9c4a08c48a7c3996fed5fbe9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerTaggedObject.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerTaggedObject.cs new file mode 100644 index 0000000..8a00142 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerTaggedObject.cs @@ -0,0 +1,85 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + /** + * DER TaggedObject - in ASN.1 notation this is any object preceded by + * a [n] where n is some number - these are assumed to follow the construction + * rules (as with sequences). + */ + public class DerTaggedObject + : Asn1TaggedObject + { + /** + * @param tagNo the tag number for this object. + * @param obj the tagged object. + */ + public DerTaggedObject( + int tagNo, + Asn1Encodable obj) + : base(tagNo, obj) + { + } + + /** + * @param explicitly true if an explicitly tagged object. + * @param tagNo the tag number for this object. + * @param obj the tagged object. + */ + public DerTaggedObject( + bool explicitly, + int tagNo, + Asn1Encodable obj) + : base(explicitly, tagNo, obj) + { + } + + /** + * create an implicitly tagged object that contains a zero + * length sequence. + */ + public DerTaggedObject( + int tagNo) + : base(false, tagNo, DerSequence.Empty) + { + } + + internal override int EncodedLength(bool withID) + { + throw Platform.CreateNotImplementedException("DerTaggedObject.EncodedLength"); + } + + internal override void Encode(Asn1OutputStream asn1Out, bool withID) + { + if (!IsEmpty()) + { + byte[] bytes = obj.GetDerEncoded(); + + if (explicitly) + { + asn1Out.WriteEncodingDL(withID, Asn1Tags.Constructed | Asn1Tags.ContextSpecific, tagNo, bytes); + } + else + { + // + // need to mark constructed types... (preserve Constructed tag) + // + if (withID) + { + int flags = (bytes[0] & Asn1Tags.Constructed) | Asn1Tags.ContextSpecific; + asn1Out.WriteIdentifier(true, flags, tagNo); + } + + asn1Out.Write(bytes, 1, bytes.Length - 1); + } + } + else + { + asn1Out.WriteEncodingDL(withID, Asn1Tags.Constructed | Asn1Tags.ContextSpecific, tagNo, + Asn1OctetString.EmptyOctets); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerTaggedObject.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerTaggedObject.cs.meta new file mode 100644 index 0000000..39ba05e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerTaggedObject.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fa4a92f7e5cec004b9c399447fa11f15 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerUTCTime.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerUTCTime.cs new file mode 100644 index 0000000..90b2999 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerUTCTime.cs @@ -0,0 +1,271 @@ +using System; +using System.Globalization; +using System.Text; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + /** + * UTC time object. + */ + public class DerUtcTime + : Asn1Object + { + private readonly string time; + + /** + * return an UTC Time from the passed in object. + * + * @exception ArgumentException if the object cannot be converted. + */ + public static DerUtcTime GetInstance( + object obj) + { + if (obj == null || obj is DerUtcTime) + { + return (DerUtcTime)obj; + } + + throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj)); + } + + /** + * return an UTC Time from a tagged object. + * + * @param obj the tagged object holding the object we want + * @param explicitly true if the object is meant to be explicitly + * tagged false otherwise. + * @exception ArgumentException if the tagged object cannot + * be converted. + */ + public static DerUtcTime GetInstance( + Asn1TaggedObject obj, + bool isExplicit) + { + Asn1Object o = obj.GetObject(); + + if (isExplicit || o is DerUtcTime) + { + return GetInstance(o); + } + + return new DerUtcTime(((Asn1OctetString)o).GetOctets()); + } + + /** + * The correct format for this is YYMMDDHHMMSSZ (it used to be that seconds were + * never encoded. When you're creating one of these objects from scratch, that's + * what you want to use, otherwise we'll try to deal with whatever Gets read from + * the input stream... (this is why the input format is different from the GetTime() + * method output). + *

+ * @param time the time string.

+ */ + public DerUtcTime( + string time) + { + if (time == null) + throw new ArgumentNullException("time"); + + this.time = time; + + try + { + ToDateTime(); + } + catch (FormatException e) + { + throw new ArgumentException("invalid date string: " + e.Message); + } + } + + /** + * base constructor from a DateTime object + */ + public DerUtcTime( + DateTime time) + { +#if PORTABLE + this.time = time.ToUniversalTime().ToString("yyMMddHHmmss", CultureInfo.InvariantCulture) + "Z"; +#else + this.time = time.ToString("yyMMddHHmmss", CultureInfo.InvariantCulture) + "Z"; +#endif + } + + internal DerUtcTime( + byte[] bytes) + { + // + // explicitly convert to characters + // + this.time = Strings.FromAsciiByteArray(bytes); + } + +// public DateTime ToDateTime() +// { +// string tm = this.AdjustedTimeString; +// +// return new DateTime( +// Int16.Parse(tm.Substring(0, 4)), +// Int16.Parse(tm.Substring(4, 2)), +// Int16.Parse(tm.Substring(6, 2)), +// Int16.Parse(tm.Substring(8, 2)), +// Int16.Parse(tm.Substring(10, 2)), +// Int16.Parse(tm.Substring(12, 2))); +// } + + /** + * return the time as a date based on whatever a 2 digit year will return. For + * standardised processing use ToAdjustedDateTime(). + * + * @return the resulting date + * @exception ParseException if the date string cannot be parsed. + */ + public DateTime ToDateTime() + { + return ParseDateString(TimeString, @"yyMMddHHmmss'GMT'zzz"); + } + + /** + * return the time as an adjusted date + * in the range of 1950 - 2049. + * + * @return a date in the range of 1950 to 2049. + * @exception ParseException if the date string cannot be parsed. + */ + public DateTime ToAdjustedDateTime() + { + return ParseDateString(AdjustedTimeString, @"yyyyMMddHHmmss'GMT'zzz"); + } + + private DateTime ParseDateString( + string dateStr, + string formatStr) + { + DateTime dt = DateTime.ParseExact( + dateStr, + formatStr, + DateTimeFormatInfo.InvariantInfo); + + return dt.ToUniversalTime(); + } + + /** + * return the time - always in the form of + * YYMMDDhhmmssGMT(+hh:mm|-hh:mm). + *

+ * Normally in a certificate we would expect "Z" rather than "GMT", + * however adding the "GMT" means we can just use: + *

+         *     dateF = new SimpleDateFormat("yyMMddHHmmssz");
+         * 
+ * To read in the time and Get a date which is compatible with our local + * time zone.

+ *

+ * Note: In some cases, due to the local date processing, this + * may lead to unexpected results. If you want to stick the normal + * convention of 1950 to 2049 use the GetAdjustedTime() method.

+ */ + public string TimeString + { + get + { + // + // standardise the format. + // + if (time.IndexOf('-') < 0 && time.IndexOf('+') < 0) + { + if (time.Length == 11) + { + return time.Substring(0, 10) + "00GMT+00:00"; + } + else + { + return time.Substring(0, 12) + "GMT+00:00"; + } + } + else + { + int index = time.IndexOf('-'); + if (index < 0) + { + index = time.IndexOf('+'); + } + string d = time; + + if (index == time.Length - 3) + { + d += "00"; + } + + if (index == 10) + { + return d.Substring(0, 10) + "00GMT" + d.Substring(10, 3) + ":" + d.Substring(13, 2); + } + else + { + return d.Substring(0, 12) + "GMT" + d.Substring(12, 3) + ":" + d.Substring(15, 2); + } + } + } + } + + [Obsolete("Use 'AdjustedTimeString' property instead")] + public string AdjustedTime + { + get { return AdjustedTimeString; } + } + + /// + /// Return a time string as an adjusted date with a 4 digit year. + /// This goes in the range of 1950 - 2049. + /// + public string AdjustedTimeString + { + get + { + string d = TimeString; + string c = d[0] < '5' ? "20" : "19"; + + return c + d; + } + } + + private byte[] GetOctets() + { + return Strings.ToAsciiByteArray(time); + } + + internal override int EncodedLength(bool withID) + { + return Asn1OutputStream.GetLengthOfEncodingDL(withID, time.Length); + } + + internal override void Encode(Asn1OutputStream asn1Out, bool withID) + { + asn1Out.WriteEncodingDL(withID, Asn1Tags.UtcTime, GetOctets()); + } + + protected override bool Asn1Equals( + Asn1Object asn1Object) + { + DerUtcTime other = asn1Object as DerUtcTime; + + if (other == null) + return false; + + return this.time.Equals(other.time); + } + + protected override int Asn1GetHashCode() + { + return time.GetHashCode(); + } + + public override string ToString() + { + return time; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerUTCTime.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerUTCTime.cs.meta new file mode 100644 index 0000000..0e427b5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerUTCTime.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 57f1d819e62097c4ab166ea70eb00723 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerUTF8String.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerUTF8String.cs new file mode 100644 index 0000000..8126e10 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerUTF8String.cs @@ -0,0 +1,102 @@ +using System; +using System.Text; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + /** + * Der UTF8String object. + */ + public class DerUtf8String + : DerStringBase + { + private readonly string str; + + /** + * return an UTF8 string from the passed in object. + * + * @exception ArgumentException if the object cannot be converted. + */ + public static DerUtf8String GetInstance( + object obj) + { + if (obj == null || obj is DerUtf8String) + { + return (DerUtf8String)obj; + } + + throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj)); + } + + /** + * return an UTF8 string from a tagged object. + * + * @param obj the tagged object holding the object we want + * @param explicitly true if the object is meant to be explicitly + * tagged false otherwise. + * @exception ArgumentException if the tagged object cannot + * be converted. + */ + public static DerUtf8String GetInstance( + Asn1TaggedObject obj, + bool isExplicit) + { + Asn1Object o = obj.GetObject(); + + if (isExplicit || o is DerUtf8String) + { + return GetInstance(o); + } + + return new DerUtf8String(Asn1OctetString.GetInstance(o).GetOctets()); + } + + /** + * basic constructor - byte encoded string. + */ + public DerUtf8String( + byte[] str) + : this(Encoding.UTF8.GetString(str, 0, str.Length)) + { + } + + /** + * basic constructor + */ + public DerUtf8String( + string str) + { + if (str == null) + throw new ArgumentNullException("str"); + + this.str = str; + } + + public override string GetString() + { + return str; + } + + protected override bool Asn1Equals( + Asn1Object asn1Object) + { + DerUtf8String other = asn1Object as DerUtf8String; + + if (other == null) + return false; + + return this.str.Equals(other.str); + } + + internal override int EncodedLength(bool withID) + { + return Asn1OutputStream.GetLengthOfEncodingDL(withID, Encoding.UTF8.GetByteCount(str)); + } + + internal override void Encode(Asn1OutputStream asn1Out, bool withID) + { + asn1Out.WriteEncodingDL(withID, Asn1Tags.Utf8String, Encoding.UTF8.GetBytes(str)); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerUTF8String.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerUTF8String.cs.meta new file mode 100644 index 0000000..60e680e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerUTF8String.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a01fecc111759e241b45ff50d924f75a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerUniversalString.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerUniversalString.cs new file mode 100644 index 0000000..2e9baa7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerUniversalString.cs @@ -0,0 +1,111 @@ +using System; +using System.Text; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + /** + * Der UniversalString object. + */ + public class DerUniversalString + : DerStringBase + { + private static readonly char[] table = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + + private readonly byte[] str; + + /** + * return a Universal string from the passed in object. + * + * @exception ArgumentException if the object cannot be converted. + */ + public static DerUniversalString GetInstance( + object obj) + { + if (obj == null || obj is DerUniversalString) + { + return (DerUniversalString)obj; + } + + throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj)); + } + + /** + * return a Universal string from a tagged object. + * + * @param obj the tagged object holding the object we want + * @param explicitly true if the object is meant to be explicitly + * tagged false otherwise. + * @exception ArgumentException if the tagged object cannot + * be converted. + */ + public static DerUniversalString GetInstance( + Asn1TaggedObject obj, + bool isExplicit) + { + Asn1Object o = obj.GetObject(); + + if (isExplicit || o is DerUniversalString) + { + return GetInstance(o); + } + + return new DerUniversalString(Asn1OctetString.GetInstance(o).GetOctets()); + } + + /** + * basic constructor - byte encoded string. + */ + public DerUniversalString( + byte[] str) + { + if (str == null) + throw new ArgumentNullException("str"); + + this.str = str; + } + + public override string GetString() + { + StringBuilder buffer = new StringBuilder("#"); + byte[] enc = GetDerEncoded(); + + for (int i = 0; i != enc.Length; i++) + { + uint ubyte = enc[i]; + buffer.Append(table[(ubyte >> 4) & 0xf]); + buffer.Append(table[enc[i] & 0xf]); + } + + return buffer.ToString(); + } + + public byte[] GetOctets() + { + return (byte[]) str.Clone(); + } + + internal override int EncodedLength(bool withID) + { + return Asn1OutputStream.GetLengthOfEncodingDL(withID, this.str.Length); + } + + internal override void Encode(Asn1OutputStream asn1Out, bool withID) + { + asn1Out.WriteEncodingDL(withID, Asn1Tags.UniversalString, this.str); + } + + protected override bool Asn1Equals( + Asn1Object asn1Object) + { + DerUniversalString other = asn1Object as DerUniversalString; + + if (other == null) + return false; + +// return this.GetString().Equals(other.GetString()); + return Arrays.AreEqual(this.str, other.str); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerUniversalString.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerUniversalString.cs.meta new file mode 100644 index 0000000..aa3c8f8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerUniversalString.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cb453b4379b80b44d8e6abe75ab6c0e2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerVideotexString.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerVideotexString.cs new file mode 100644 index 0000000..fcb535e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerVideotexString.cs @@ -0,0 +1,108 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + public class DerVideotexString + : DerStringBase + { + private readonly byte[] mString; + + /** + * return a Videotex String from the passed in object + * + * @param obj a DERVideotexString or an object that can be converted into one. + * @exception IllegalArgumentException if the object cannot be converted. + * @return a DERVideotexString instance, or null. + */ + public static DerVideotexString GetInstance(object obj) + { + if (obj == null || obj is DerVideotexString) + { + return (DerVideotexString)obj; + } + + if (obj is byte[]) + { + try + { + return (DerVideotexString)FromByteArray((byte[])obj); + } + catch (Exception e) + { + throw new ArgumentException("encoding error in GetInstance: " + e.ToString(), "obj"); + } + } + + throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj), "obj"); + } + + /** + * return a Videotex String from a tagged object. + * + * @param obj the tagged object holding the object we want + * @param explicit true if the object is meant to be explicitly + * tagged false otherwise. + * @exception IllegalArgumentException if the tagged object cannot + * be converted. + * @return a DERVideotexString instance, or null. + */ + public static DerVideotexString GetInstance(Asn1TaggedObject obj, bool isExplicit) + { + Asn1Object o = obj.GetObject(); + + if (isExplicit || o is DerVideotexString) + { + return GetInstance(o); + } + + return new DerVideotexString(((Asn1OctetString)o).GetOctets()); + } + + /** + * basic constructor - with bytes. + * @param string the byte encoding of the characters making up the string. + */ + public DerVideotexString(byte[] encoding) + { + this.mString = Arrays.Clone(encoding); + } + + public override string GetString() + { + return Strings.FromByteArray(mString); + } + + public byte[] GetOctets() + { + return Arrays.Clone(mString); + } + + internal override int EncodedLength(bool withID) + { + return Asn1OutputStream.GetLengthOfEncodingDL(withID, mString.Length); + } + + internal override void Encode(Asn1OutputStream asn1Out, bool withID) + { + asn1Out.WriteEncodingDL(withID, Asn1Tags.VideotexString, mString); + } + + protected override int Asn1GetHashCode() + { + return Arrays.GetHashCode(mString); + } + + protected override bool Asn1Equals( + Asn1Object asn1Object) + { + DerVideotexString other = asn1Object as DerVideotexString; + + if (other == null) + return false; + + return Arrays.AreEqual(mString, other.mString); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerVideotexString.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerVideotexString.cs.meta new file mode 100644 index 0000000..7428989 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerVideotexString.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3038ce158ec563a4ca804e7c004d16c4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerVisibleString.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerVisibleString.cs new file mode 100644 index 0000000..21b01fe --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerVisibleString.cs @@ -0,0 +1,115 @@ +using System; +using System.Text; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + /** + * Der VisibleString object. + */ + public class DerVisibleString + : DerStringBase + { + private readonly string str; + + /** + * return a Visible string from the passed in object. + * + * @exception ArgumentException if the object cannot be converted. + */ + public static DerVisibleString GetInstance( + object obj) + { + if (obj == null || obj is DerVisibleString) + { + return (DerVisibleString)obj; + } + + if (obj is Asn1OctetString) + { + return new DerVisibleString(((Asn1OctetString)obj).GetOctets()); + } + + if (obj is Asn1TaggedObject) + { + return GetInstance(((Asn1TaggedObject)obj).GetObject()); + } + + throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj)); + } + + /** + * return a Visible string from a tagged object. + * + * @param obj the tagged object holding the object we want + * @param explicitly true if the object is meant to be explicitly + * tagged false otherwise. + * @exception ArgumentException if the tagged object cannot + * be converted. + */ + public static DerVisibleString GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(obj.GetObject()); + } + + /** + * basic constructor - byte encoded string. + */ + public DerVisibleString( + byte[] str) + : this(Strings.FromAsciiByteArray(str)) + { + } + + /** + * basic constructor + */ + public DerVisibleString( + string str) + { + if (str == null) + throw new ArgumentNullException("str"); + + this.str = str; + } + + public override string GetString() + { + return str; + } + + public byte[] GetOctets() + { + return Strings.ToAsciiByteArray(str); + } + + internal override int EncodedLength(bool withID) + { + return Asn1OutputStream.GetLengthOfEncodingDL(withID, str.Length); + } + + internal override void Encode(Asn1OutputStream asn1Out, bool withID) + { + asn1Out.WriteEncodingDL(withID, Asn1Tags.VisibleString, GetOctets()); + } + + protected override bool Asn1Equals( + Asn1Object asn1Object) + { + DerVisibleString other = asn1Object as DerVisibleString; + + if (other == null) + return false; + + return this.str.Equals(other.str); + } + + protected override int Asn1GetHashCode() + { + return this.str.GetHashCode(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerVisibleString.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerVisibleString.cs.meta new file mode 100644 index 0000000..b8ababb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/DerVisibleString.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d35a5a040e48e7d4b95163aa4369ecb0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/IAsn1ApplicationSpecificParser.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/IAsn1ApplicationSpecificParser.cs new file mode 100644 index 0000000..89cf64c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/IAsn1ApplicationSpecificParser.cs @@ -0,0 +1,10 @@ +using System; + +namespace Org.BouncyCastle.Asn1 +{ + public interface IAsn1ApplicationSpecificParser + : IAsn1Convertible + { + IAsn1Convertible ReadObject(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/IAsn1ApplicationSpecificParser.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/IAsn1ApplicationSpecificParser.cs.meta new file mode 100644 index 0000000..39dcf20 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/IAsn1ApplicationSpecificParser.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 84f96a148d9fbb547a5b2bdd3c4979e7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/IAsn1Choice.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/IAsn1Choice.cs new file mode 100644 index 0000000..ecd76e4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/IAsn1Choice.cs @@ -0,0 +1,17 @@ + +namespace Org.BouncyCastle.Asn1 +{ + /** + * Marker interface for CHOICE objects - if you implement this in a roll-your-own + * object, any attempt to tag the object implicitly will convert the tag to an + * explicit one as the encoding rules require. + *

+ * If you use this interface your class should also implement the getInstance + * pattern which takes a tag object and the tagging mode used. + *

+ */ + public interface IAsn1Choice + { + // marker interface + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/IAsn1Choice.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/IAsn1Choice.cs.meta new file mode 100644 index 0000000..6a3c267 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/IAsn1Choice.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: df3bc7aa4a5bbe344ac1ddde10284031 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/IAsn1Convertible.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/IAsn1Convertible.cs new file mode 100644 index 0000000..d3f83af --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/IAsn1Convertible.cs @@ -0,0 +1,7 @@ +namespace Org.BouncyCastle.Asn1 +{ + public interface IAsn1Convertible + { + Asn1Object ToAsn1Object(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/IAsn1Convertible.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/IAsn1Convertible.cs.meta new file mode 100644 index 0000000..78eb09d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/IAsn1Convertible.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7a03d6ae95a7c0842b9643068300f263 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/IAsn1String.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/IAsn1String.cs new file mode 100644 index 0000000..cbc2635 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/IAsn1String.cs @@ -0,0 +1,10 @@ +namespace Org.BouncyCastle.Asn1 +{ + /** + * basic interface for Der string objects. + */ + public interface IAsn1String + { + string GetString(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/IAsn1String.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/IAsn1String.cs.meta new file mode 100644 index 0000000..64df56b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/IAsn1String.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e2d757d6bdb0b2c459dd8d2c09c66ae5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/IndefiniteLengthInputStream.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/IndefiniteLengthInputStream.cs new file mode 100644 index 0000000..09d0e3a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/IndefiniteLengthInputStream.cs @@ -0,0 +1,170 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Asn1 +{ + class IndefiniteLengthInputStream + : LimitedInputStream + { + private int _lookAhead; + private bool _eofOn00 = true; + + internal IndefiniteLengthInputStream( + Stream inStream, + int limit) + : base(inStream, limit) + { + _lookAhead = RequireByte(); + CheckForEof(); + } + + internal void SetEofOn00( + bool eofOn00) + { + _eofOn00 = eofOn00; + if (_eofOn00) + { + CheckForEof(); + } + } + + private bool CheckForEof() + { + if (_lookAhead == 0x00) + { + int extra = RequireByte(); + if (extra != 0) + { + throw new IOException("malformed end-of-contents marker"); + } + + _lookAhead = -1; + SetParentEofDetect(true); + return true; + } + return _lookAhead < 0; + } + + public override int Read( + byte[] buffer, + int offset, + int count) + { + // Only use this optimisation if we aren't checking for 00 + if (_eofOn00 || count <= 1) + return base.Read(buffer, offset, count); + + if (_lookAhead < 0) + return 0; + + int numRead = _in.Read(buffer, offset + 1, count - 1); + + if (numRead <= 0) + { + // Corrupted stream + throw new EndOfStreamException(); + } + + buffer[offset] = (byte)_lookAhead; + _lookAhead = RequireByte(); + + return numRead + 1; + } + + public override int ReadByte() + { + if (_eofOn00 && CheckForEof()) + return -1; + + int result = _lookAhead; + _lookAhead = RequireByte(); + return result; + } + + private int RequireByte() + { + int b = _in.ReadByte(); + if (b < 0) + { + // Corrupted stream + throw new EndOfStreamException(); + } + return b; + } + } +} + +//using System; +//using System.IO; + +//namespace Org.BouncyCastle.Asn1 +//{ +// class IndefiniteLengthInputStream +// : LimitedInputStream +// { +// private bool _eofReached = false; +// private bool _eofOn00 = true; + +// internal IndefiniteLengthInputStream( +// Stream inStream, +// int limit) +// : base(inStream, limit) +// { +// } + +// internal void SetEofOn00( +// bool eofOn00) +// { +// _eofOn00 = eofOn00; +// } + +// public override int Read( +// byte[] buffer, +// int offset, +// int count) +// { +// if (_eofReached) +// return 0; + +// if (_eofOn00) +// return base.Read(buffer, offset, count); + +// int numRead = _in.Read(buffer, offset, count); + +// if (numRead <= 0) +// throw new EndOfStreamException(); + +// return numRead; +// } + +// public override int ReadByte() +// { +// if (_eofReached) +// return -1; + +// int b1 = _in.ReadByte(); + +// if (b1 < 0) +// throw new EndOfStreamException(); + +// if (b1 == 0 && _eofOn00) +// { +// int b2 = _in.ReadByte(); + +// if (b2 < 0) +// throw new EndOfStreamException(); + +// if (b2 == 0) +// { +// _eofReached = true; +// SetParentEofDetect(true); +// return -1; +// } + +// throw new InvalidDataException(); +// } + +// return b1; +// } +// } +//} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/IndefiniteLengthInputStream.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/IndefiniteLengthInputStream.cs.meta new file mode 100644 index 0000000..44ae2bc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/IndefiniteLengthInputStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e8aa3586ce8e2e744a24a7f74542c5d0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/LazyASN1InputStream.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/LazyASN1InputStream.cs new file mode 100644 index 0000000..1a85e45 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/LazyASN1InputStream.cs @@ -0,0 +1,47 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Asn1 +{ + public class LazyAsn1InputStream + : Asn1InputStream + { + public LazyAsn1InputStream( + byte[] input) + : base(input) + { + } + + public LazyAsn1InputStream( + Stream inputStream) + : base(inputStream) + { + } + + internal LazyAsn1InputStream(Stream input, int limit, byte[][] tmpBuffers) + : base(input, limit, tmpBuffers) + { + } + + internal override DerSequence CreateDerSequence( + DefiniteLengthInputStream dIn) + { + return new LazyDerSequence(dIn.ToArray()); + } + + internal override DerSet CreateDerSet( + DefiniteLengthInputStream dIn) + { + return new LazyDerSet(dIn.ToArray()); + } + + internal override Asn1EncodableVector ReadVector(DefiniteLengthInputStream defIn) + { + int remaining = defIn.Remaining; + if (remaining < 1) + return new Asn1EncodableVector(0); + + return new LazyAsn1InputStream(defIn, remaining, tmpBuffers).ReadVector(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/LazyASN1InputStream.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/LazyASN1InputStream.cs.meta new file mode 100644 index 0000000..081ccab --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/LazyASN1InputStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9edcfb5aeb0b84c47a5539e2d1132215 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/LazyDERSequence.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/LazyDERSequence.cs new file mode 100644 index 0000000..26ec1ef --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/LazyDERSequence.cs @@ -0,0 +1,92 @@ +using System; +using System.Collections; + +namespace Org.BouncyCastle.Asn1 +{ + internal class LazyDerSequence + : DerSequence + { + private byte[] encoded; + + internal LazyDerSequence(byte[] encoded) + : base() + { + if (null == encoded) + throw new ArgumentNullException("encoded"); + + this.encoded = encoded; + } + + private void Parse() + { + lock (this) + { + if (null != encoded) + { + Asn1InputStream e = new LazyAsn1InputStream(encoded); + Asn1EncodableVector v = e.ReadVector(); + + this.elements = v.TakeElements(); + this.encoded = null; + } + } + } + + public override Asn1Encodable this[int index] + { + get + { + Parse(); + + return base[index]; + } + } + + public override IEnumerator GetEnumerator() + { + Parse(); + + return base.GetEnumerator(); + } + + public override int Count + { + get + { + Parse(); + + return base.Count; + } + } + + internal override int EncodedLength(bool withID) + { + lock (this) + { + if (encoded == null) + { + return base.EncodedLength(withID); + } + else + { + return Asn1OutputStream.GetLengthOfEncodingDL(withID, encoded.Length); + } + } + } + + internal override void Encode(Asn1OutputStream asn1Out, bool withID) + { + lock (this) + { + if (encoded == null) + { + base.Encode(asn1Out, withID); + } + else + { + asn1Out.WriteEncodingDL(withID, Asn1Tags.Constructed | Asn1Tags.Sequence, encoded); + } + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/LazyDERSequence.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/LazyDERSequence.cs.meta new file mode 100644 index 0000000..f879e63 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/LazyDERSequence.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ce7812fa6ed135c47867342eb41aa3df +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/LazyDERSet.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/LazyDERSet.cs new file mode 100644 index 0000000..32d9e26 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/LazyDERSet.cs @@ -0,0 +1,92 @@ +using System; +using System.Collections; + +namespace Org.BouncyCastle.Asn1 +{ + internal class LazyDerSet + : DerSet + { + private byte[] encoded; + + internal LazyDerSet(byte[] encoded) + : base() + { + if (null == encoded) + throw new ArgumentNullException("encoded"); + + this.encoded = encoded; + } + + private void Parse() + { + lock (this) + { + if (encoded != null) + { + Asn1InputStream e = new LazyAsn1InputStream(encoded); + Asn1EncodableVector v = e.ReadVector(); + + this.elements = v.TakeElements(); + this.encoded = null; + } + } + } + + public override Asn1Encodable this[int index] + { + get + { + Parse(); + + return base[index]; + } + } + + public override IEnumerator GetEnumerator() + { + Parse(); + + return base.GetEnumerator(); + } + + public override int Count + { + get + { + Parse(); + + return base.Count; + } + } + + internal override int EncodedLength(bool withID) + { + lock (this) + { + if (encoded == null) + { + return base.EncodedLength(withID); + } + else + { + return Asn1OutputStream.GetLengthOfEncodingDL(withID, encoded.Length); + } + } + } + + internal override void Encode(Asn1OutputStream asn1Out, bool withID) + { + lock (this) + { + if (encoded == null) + { + base.Encode(asn1Out, withID); + } + else + { + asn1Out.WriteEncodingDL(withID, Asn1Tags.Constructed | Asn1Tags.Set, encoded); + } + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/LazyDERSet.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/LazyDERSet.cs.meta new file mode 100644 index 0000000..980a013 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/LazyDERSet.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 12f2e04f0c44c3540b8a85f700e343bd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/LimitedInputStream.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/LimitedInputStream.cs new file mode 100644 index 0000000..98a4587 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/LimitedInputStream.cs @@ -0,0 +1,32 @@ +using System.IO; + +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Asn1 +{ + internal abstract class LimitedInputStream + : BaseInputStream + { + protected readonly Stream _in; + private int _limit; + + internal LimitedInputStream(Stream inStream, int limit) + { + this._in = inStream; + this._limit = limit; + } + + internal virtual int Limit + { + get { return _limit; } + } + + protected virtual void SetParentEofDetect(bool on) + { + if (_in is IndefiniteLengthInputStream) + { + ((IndefiniteLengthInputStream)_in).SetEofOn00(on); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/LimitedInputStream.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/LimitedInputStream.cs.meta new file mode 100644 index 0000000..5615f6d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/LimitedInputStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 14b25f083d8f7ae4784ee644cffb8270 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/OidTokenizer.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/OidTokenizer.cs new file mode 100644 index 0000000..6e76e8c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/OidTokenizer.cs @@ -0,0 +1,45 @@ +namespace Org.BouncyCastle.Asn1 +{ + /** + * class for breaking up an Oid into it's component tokens, ala + * java.util.StringTokenizer. We need this class as some of the + * lightweight Java environment don't support classes like + * StringTokenizer. + */ + public class OidTokenizer + { + private string oid; + private int index; + + public OidTokenizer( + string oid) + { + this.oid = oid; + } + + public bool HasMoreTokens + { + get { return index != -1; } + } + + public string NextToken() + { + if (index == -1) + { + return null; + } + + int end = oid.IndexOf('.', index); + if (end == -1) + { + string lastToken = oid.Substring(index); + index = -1; + return lastToken; + } + + string nextToken = oid.Substring(index, end - index); + index = end + 1; + return nextToken; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/OidTokenizer.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/OidTokenizer.cs.meta new file mode 100644 index 0000000..a3dcddc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/OidTokenizer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5e1eef216639c6a42863d1a1f61f7e3a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/anssi.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/anssi.meta new file mode 100644 index 0000000..0a0c743 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/anssi.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c59d56123b810cd43be33ef37c00582c +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/anssi/ANSSINamedCurves.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/anssi/ANSSINamedCurves.cs new file mode 100644 index 0000000..2622258 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/anssi/ANSSINamedCurves.cs @@ -0,0 +1,130 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Math.EC.Multiplier; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Asn1.Anssi +{ + public class AnssiNamedCurves + { + private static X9ECPoint ConfigureBasepoint(ECCurve curve, string encoding) + { + X9ECPoint G = new X9ECPoint(curve, Hex.DecodeStrict(encoding)); + WNafUtilities.ConfigureBasepoint(G.Point); + return G; + } + + private static ECCurve ConfigureCurve(ECCurve curve) + { + return curve; + } + + private static BigInteger FromHex(string hex) + { + return new BigInteger(1, Hex.DecodeStrict(hex)); + } + + /* + * FRP256v1 + */ + internal class Frp256v1Holder + : X9ECParametersHolder + { + private Frp256v1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Frp256v1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger p = FromHex("F1FD178C0B3AD58F10126DE8CE42435B3961ADBCABC8CA6DE8FCF353D86E9C03"); + BigInteger a = FromHex("F1FD178C0B3AD58F10126DE8CE42435B3961ADBCABC8CA6DE8FCF353D86E9C00"); + BigInteger b = FromHex("EE353FCA5428A9300D4ABA754A44C00FDFEC0C9AE4B1A1803075ED967B7BB73F"); + byte[] S = null; + BigInteger n = FromHex("F1FD178C0B3AD58F10126DE8CE42435B53DC67E140D2BF941FFDD459C6D655E1"); + BigInteger h = BigInteger.One; + + ECCurve curve = ConfigureCurve(new FpCurve(p, a, b, n, h)); + X9ECPoint G = ConfigureBasepoint(curve, + "04B6B3D4C356C139EB31183D4749D423958C27D2DCAF98B70164C97A2DD98F5CFF6142E0F7C8B204911F9271F0F3ECEF8C2701C307E8E4C9E183115A1554062CFB"); + + return new X9ECParameters(curve, G, n, h, S); + } + }; + + + private static readonly IDictionary objIds = Platform.CreateHashtable(); + private static readonly IDictionary curves = Platform.CreateHashtable(); + private static readonly IDictionary names = Platform.CreateHashtable(); + + private static void DefineCurve( + string name, + DerObjectIdentifier oid, + X9ECParametersHolder holder) + { + objIds.Add(Platform.ToUpperInvariant(name), oid); + names.Add(oid, name); + curves.Add(oid, holder); + } + + static AnssiNamedCurves() + { + DefineCurve("FRP256v1", AnssiObjectIdentifiers.FRP256v1, Frp256v1Holder.Instance); + } + + public static X9ECParameters GetByName( + string name) + { + DerObjectIdentifier oid = GetOid(name); + return oid == null ? null : GetByOid(oid); + } + + /** + * return the X9ECParameters object for the named curve represented by + * the passed in object identifier. Null if the curve isn't present. + * + * @param oid an object identifier representing a named curve, if present. + */ + public static X9ECParameters GetByOid( + DerObjectIdentifier oid) + { + X9ECParametersHolder holder = (X9ECParametersHolder)curves[oid]; + return holder == null ? null : holder.Parameters; + } + + /** + * return the object identifier signified by the passed in name. Null + * if there is no object identifier associated with name. + * + * @return the object identifier associated with name, if present. + */ + public static DerObjectIdentifier GetOid( + string name) + { + return (DerObjectIdentifier)objIds[Platform.ToUpperInvariant(name)]; + } + + /** + * return the named curve name represented by the given object identifier. + */ + public static string GetName( + DerObjectIdentifier oid) + { + return (string)names[oid]; + } + + /** + * returns an enumeration containing the name strings for curves + * contained in this structure. + */ + public static IEnumerable Names + { + get { return new EnumerableProxy(names.Values); } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/anssi/ANSSINamedCurves.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/anssi/ANSSINamedCurves.cs.meta new file mode 100644 index 0000000..fbdf73b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/anssi/ANSSINamedCurves.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 776197e03ce02c946972d19331e51f9b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/anssi/ANSSIObjectIdentifiers.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/anssi/ANSSIObjectIdentifiers.cs new file mode 100644 index 0000000..d230832 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/anssi/ANSSIObjectIdentifiers.cs @@ -0,0 +1,13 @@ +using System; + +namespace Org.BouncyCastle.Asn1.Anssi +{ + public sealed class AnssiObjectIdentifiers + { + private AnssiObjectIdentifiers() + { + } + + public static readonly DerObjectIdentifier FRP256v1 = new DerObjectIdentifier("1.2.250.1.223.101.256.1"); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/anssi/ANSSIObjectIdentifiers.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/anssi/ANSSIObjectIdentifiers.cs.meta new file mode 100644 index 0000000..9ec74ab --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/anssi/ANSSIObjectIdentifiers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dc7d552017a9b9a468be9862dfc84732 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/bc.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/bc.meta new file mode 100644 index 0000000..d58ed45 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/bc.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 17cafbc716df900409686ab21e9742ac +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/bc/BCObjectIdentifiers.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/bc/BCObjectIdentifiers.cs new file mode 100644 index 0000000..0ffd65d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/bc/BCObjectIdentifiers.cs @@ -0,0 +1,114 @@ +using System; + +namespace Org.BouncyCastle.Asn1.BC +{ + public abstract class BCObjectIdentifiers + { + /** + * iso.org.dod.internet.private.enterprise.legion-of-the-bouncy-castle + *

1.3.6.1.4.1.22554

+ */ + public static readonly DerObjectIdentifier bc = new DerObjectIdentifier("1.3.6.1.4.1.22554"); + + /** + * pbe(1) algorithms + *

1.3.6.1.4.1.22554.1

+ */ + public static readonly DerObjectIdentifier bc_pbe = bc.Branch("1"); + + /** + * SHA-1(1) + *

1.3.6.1.4.1.22554.1.1

+ */ + public static readonly DerObjectIdentifier bc_pbe_sha1 = bc_pbe.Branch("1"); + + /** SHA-2.SHA-256; 1.3.6.1.4.1.22554.1.2.1 */ + public static readonly DerObjectIdentifier bc_pbe_sha256 = bc_pbe.Branch("2.1"); + /** SHA-2.SHA-384; 1.3.6.1.4.1.22554.1.2.2 */ + public static readonly DerObjectIdentifier bc_pbe_sha384 = bc_pbe.Branch("2.2"); + /** SHA-2.SHA-512; 1.3.6.1.4.1.22554.1.2.3 */ + public static readonly DerObjectIdentifier bc_pbe_sha512 = bc_pbe.Branch("2.3"); + /** SHA-2.SHA-224; 1.3.6.1.4.1.22554.1.2.4 */ + public static readonly DerObjectIdentifier bc_pbe_sha224 = bc_pbe.Branch("2.4"); + + /** + * PKCS-5(1)|PKCS-12(2) + */ + /** SHA-1.PKCS5; 1.3.6.1.4.1.22554.1.1.1 */ + public static readonly DerObjectIdentifier bc_pbe_sha1_pkcs5 = bc_pbe_sha1.Branch("1"); + /** SHA-1.PKCS12; 1.3.6.1.4.1.22554.1.1.2 */ + public static readonly DerObjectIdentifier bc_pbe_sha1_pkcs12 = bc_pbe_sha1.Branch("2"); + + /** SHA-256.PKCS12; 1.3.6.1.4.1.22554.1.2.1.1 */ + public static readonly DerObjectIdentifier bc_pbe_sha256_pkcs5 = bc_pbe_sha256.Branch("1"); + /** SHA-256.PKCS12; 1.3.6.1.4.1.22554.1.2.1.2 */ + public static readonly DerObjectIdentifier bc_pbe_sha256_pkcs12 = bc_pbe_sha256.Branch("2"); + + /** + * AES(1) . (CBC-128(2)|CBC-192(22)|CBC-256(42)) + */ + /** 1.3.6.1.4.1.22554.1.1.2.1.2 */ + public static readonly DerObjectIdentifier bc_pbe_sha1_pkcs12_aes128_cbc = bc_pbe_sha1_pkcs12.Branch("1.2"); + /** 1.3.6.1.4.1.22554.1.1.2.1.22 */ + public static readonly DerObjectIdentifier bc_pbe_sha1_pkcs12_aes192_cbc = bc_pbe_sha1_pkcs12.Branch("1.22"); + /** 1.3.6.1.4.1.22554.1.1.2.1.42 */ + public static readonly DerObjectIdentifier bc_pbe_sha1_pkcs12_aes256_cbc = bc_pbe_sha1_pkcs12.Branch("1.42"); + + /** 1.3.6.1.4.1.22554.1.1.2.2.2 */ + public static readonly DerObjectIdentifier bc_pbe_sha256_pkcs12_aes128_cbc = bc_pbe_sha256_pkcs12.Branch("1.2"); + /** 1.3.6.1.4.1.22554.1.1.2.2.22 */ + public static readonly DerObjectIdentifier bc_pbe_sha256_pkcs12_aes192_cbc = bc_pbe_sha256_pkcs12.Branch("1.22"); + /** 1.3.6.1.4.1.22554.1.1.2.2.42 */ + public static readonly DerObjectIdentifier bc_pbe_sha256_pkcs12_aes256_cbc = bc_pbe_sha256_pkcs12.Branch("1.42"); + + /** + * signature(2) algorithms + */ + public static readonly DerObjectIdentifier bc_sig = bc.Branch("2"); + + /** + * Sphincs-256 + */ + public static readonly DerObjectIdentifier sphincs256 = bc_sig.Branch("1"); + public static readonly DerObjectIdentifier sphincs256_with_BLAKE512 = sphincs256.Branch("1"); + public static readonly DerObjectIdentifier sphincs256_with_SHA512 = sphincs256.Branch("2"); + public static readonly DerObjectIdentifier sphincs256_with_SHA3_512 = sphincs256.Branch("3"); + + /** + * XMSS + */ + public static readonly DerObjectIdentifier xmss = bc_sig.Branch("2"); + public static readonly DerObjectIdentifier xmss_with_SHA256 = xmss.Branch("1"); + public static readonly DerObjectIdentifier xmss_with_SHA512 = xmss.Branch("2"); + public static readonly DerObjectIdentifier xmss_with_SHAKE128 = xmss.Branch("3"); + public static readonly DerObjectIdentifier xmss_with_SHAKE256 = xmss.Branch("4"); + + /** + * XMSS^MT + */ + public static readonly DerObjectIdentifier xmss_mt = bc_sig.Branch("3"); + public static readonly DerObjectIdentifier xmss_mt_with_SHA256 = xmss_mt.Branch("1"); + public static readonly DerObjectIdentifier xmss_mt_with_SHA512 = xmss_mt.Branch("2"); + public static readonly DerObjectIdentifier xmss_mt_with_SHAKE128 = xmss_mt.Branch("3"); + public static readonly DerObjectIdentifier xmss_mt_with_SHAKE256 = xmss_mt.Branch("4"); + + /** + * key_exchange(3) algorithms + */ + public static readonly DerObjectIdentifier bc_exch = bc.Branch("3"); + + /** + * NewHope + */ + public static readonly DerObjectIdentifier newHope = bc_exch.Branch("1"); + + /** + * X.509 extension(4) values + *

+ * 1.3.6.1.4.1.22554.4 + */ + public static readonly DerObjectIdentifier bc_ext = bc.Branch("4"); + + public static readonly DerObjectIdentifier linkedCertificate = bc_ext.Branch("1"); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/bc/BCObjectIdentifiers.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/bc/BCObjectIdentifiers.cs.meta new file mode 100644 index 0000000..9af0927 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/bc/BCObjectIdentifiers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f629da980cc0f4149867e62d4ea390bc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/bc/LinkedCertificate.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/bc/LinkedCertificate.cs new file mode 100644 index 0000000..c8d05d8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/bc/LinkedCertificate.cs @@ -0,0 +1,100 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; + +namespace Org.BouncyCastle.Asn1.BC +{ + /** + * Extension to tie an alternate certificate to the containing certificate. + *

+     *     LinkedCertificate := SEQUENCE {
+     *         digest        DigestInfo,                   -- digest of PQC certificate
+     *         certLocation  GeneralName,                  -- location of PQC certificate
+     *         certIssuer    [0] Name OPTIONAL,            -- issuer of PQC cert (if different from current certificate)
+     *         cACerts       [1] GeneralNames OPTIONAL,    -- CA certificates for PQC cert (one of more locations)
+     * }
+     * 
+ */ + public class LinkedCertificate + : Asn1Encodable + { + private readonly DigestInfo mDigest; + private readonly GeneralName mCertLocation; + + private X509Name mCertIssuer; + private GeneralNames mCACerts; + + public LinkedCertificate(DigestInfo digest, GeneralName certLocation) + : this(digest, certLocation, null, null) + { + } + + public LinkedCertificate(DigestInfo digest, GeneralName certLocation, X509Name certIssuer, GeneralNames caCerts) + { + this.mDigest = digest; + this.mCertLocation = certLocation; + this.mCertIssuer = certIssuer; + this.mCACerts = caCerts; + } + + private LinkedCertificate(Asn1Sequence seq) + { + this.mDigest = DigestInfo.GetInstance(seq[0]); + this.mCertLocation = GeneralName.GetInstance(seq[1]); + + for (int i = 2; i < seq.Count; ++i) + { + Asn1TaggedObject tagged = Asn1TaggedObject.GetInstance(seq[i]); + + switch (tagged.TagNo) + { + case 0: + this.mCertIssuer = X509Name.GetInstance(tagged, false); + break; + case 1: + this.mCACerts = GeneralNames.GetInstance(tagged, false); + break; + default: + throw new ArgumentException("unknown tag in tagged field"); + } + } + } + + public static LinkedCertificate GetInstance(object obj) + { + if (obj is LinkedCertificate) + return (LinkedCertificate)obj; + if (obj != null) + return new LinkedCertificate(Asn1Sequence.GetInstance(obj)); + return null; + } + + public virtual DigestInfo Digest + { + get { return mDigest; } + } + + public virtual GeneralName CertLocation + { + get { return mCertLocation; } + } + + public virtual X509Name CertIssuer + { + get { return mCertIssuer; } + } + + public virtual GeneralNames CACerts + { + get { return mCACerts; } + } + + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(mDigest, mCertLocation); + v.AddOptionalTagged(false, 0, mCertIssuer); + v.AddOptionalTagged(false, 1, mCACerts); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/bc/LinkedCertificate.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/bc/LinkedCertificate.cs.meta new file mode 100644 index 0000000..54b244b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/bc/LinkedCertificate.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: da5acc7b55595f54e8bb6ed2a225a312 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/bsi.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/bsi.meta new file mode 100644 index 0000000..4a7678a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/bsi.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: cf95993f95ce95c4ab9438051d0cd5d4 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/bsi/BsiObjectIdentifiers.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/bsi/BsiObjectIdentifiers.cs new file mode 100644 index 0000000..50ada2e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/bsi/BsiObjectIdentifiers.cs @@ -0,0 +1,102 @@ +using System; + +namespace Org.BouncyCastle.Asn1.Bsi +{ + /// See https://www.bsi.bund.de/cae/servlet/contentblob/471398/publicationFile/30615/BSI-TR-03111_pdf.pdf + public abstract class BsiObjectIdentifiers + { + public static readonly DerObjectIdentifier bsi_de = new DerObjectIdentifier("0.4.0.127.0.7"); + + /* 0.4.0.127.0.7.1.1 */ + public static readonly DerObjectIdentifier id_ecc = bsi_de.Branch("1.1"); + + /* 0.4.0.127.0.7.1.1.4.1 */ + public static readonly DerObjectIdentifier ecdsa_plain_signatures = id_ecc.Branch("4.1"); + + /* 0.4.0.127.0.7.1.1.4.1.1 */ + public static readonly DerObjectIdentifier ecdsa_plain_SHA1 = ecdsa_plain_signatures.Branch("1"); + + /* 0.4.0.127.0.7.1.1.4.1.2 */ + public static readonly DerObjectIdentifier ecdsa_plain_SHA224 = ecdsa_plain_signatures.Branch("2"); + + /* 0.4.0.127.0.7.1.1.4.1.3 */ + public static readonly DerObjectIdentifier ecdsa_plain_SHA256 = ecdsa_plain_signatures.Branch("3"); + + /* 0.4.0.127.0.7.1.1.4.1.4 */ + public static readonly DerObjectIdentifier ecdsa_plain_SHA384 = ecdsa_plain_signatures.Branch("4"); + + /* 0.4.0.127.0.7.1.1.4.1.5 */ + public static readonly DerObjectIdentifier ecdsa_plain_SHA512 = ecdsa_plain_signatures.Branch("5"); + + /* 0.4.0.127.0.7.1.1.4.1.6 */ + public static readonly DerObjectIdentifier ecdsa_plain_RIPEMD160 = ecdsa_plain_signatures.Branch("6"); + + /** 0.4.0.127.0.7.1 */ + public static readonly DerObjectIdentifier algorithm = bsi_de.Branch("1"); + + public static readonly DerObjectIdentifier ecka_eg = id_ecc.Branch("5.1"); + + /** ElGamal Elliptic Curve Key Agreement and Key Derivation according to X963 OID: 0.4.0.127.0.7.1.1.5.1.1 */ + public static readonly DerObjectIdentifier ecka_eg_X963kdf = ecka_eg.Branch("1"); + + /** ElGamal Elliptic Curve Key Agreement and Key Derivation according to X963 + * with hash function SHA-1 + * OID: 0.4.0.127.0.7.1.1.5.1.1.1 */ + public static readonly DerObjectIdentifier ecka_eg_X963kdf_SHA1 = ecka_eg_X963kdf.Branch("1"); + + /** ElGamal Elliptic Curve Key Agreement and Key Derivation according to X963 + * with hash function SHA224 + * OID: 0.4.0.127.0.7.1.1.5.1.1.2 */ + public static readonly DerObjectIdentifier ecka_eg_X963kdf_SHA224 = ecka_eg_X963kdf.Branch("2"); + + /** ElGamal Elliptic Curve Key Agreement and Key Derivation according to X963 + * with hash function SHA256 + * OID: 0.4.0.127.0.7.1.1.5.1.1.3 */ + public static readonly DerObjectIdentifier ecka_eg_X963kdf_SHA256 = ecka_eg_X963kdf.Branch("3"); + + /** ElGamal Elliptic Curve Key Agreement and Key Derivation according to X963 + * with hash function SHA384 + * OID: 0.4.0.127.0.7.1.1.5.1.1.4 */ + public static readonly DerObjectIdentifier ecka_eg_X963kdf_SHA384 = ecka_eg_X963kdf.Branch("4"); + + /** ElGamal Elliptic Curve Key Agreement and Key Derivation according to X963 + * with hash function SHA512 + * OID: 0.4.0.127.0.7.1.1.5.1.1.5 */ + public static readonly DerObjectIdentifier ecka_eg_X963kdf_SHA512 = ecka_eg_X963kdf.Branch("5"); + + /** ElGamal Elliptic Curve Key Agreement and Key Derivation according to X963 + * with hash function RIPEMD160 + * OID: 0.4.0.127.0.7.1.1.5.1.1.6 */ + public static readonly DerObjectIdentifier ecka_eg_X963kdf_RIPEMD160 = ecka_eg_X963kdf.Branch("6"); + + /** + * Key Derivation Function for Session Keys + */ + public static readonly DerObjectIdentifier ecka_eg_SessionKDF = ecka_eg.Branch("2"); + + public static readonly DerObjectIdentifier ecka_eg_SessionKDF_3DES = ecka_eg_SessionKDF.Branch("1"); + public static readonly DerObjectIdentifier ecka_eg_SessionKDF_AES128 = ecka_eg_SessionKDF.Branch("2"); + public static readonly DerObjectIdentifier ecka_eg_SessionKDF_AES192 = ecka_eg_SessionKDF.Branch("3"); + public static readonly DerObjectIdentifier ecka_eg_SessionKDF_AES256 = ecka_eg_SessionKDF.Branch("4"); + + /* AES encryption (CBC) and authentication (CMAC) + * OID: 0.4.0.127.0.7.1.x */ + //TODO: replace "1" with correct OID + //public static readonly DerObjectIdentifier aes_cbc_cmac = algorithm.Branch("1"); + + /* AES encryption (CBC) and authentication (CMAC) with 128 bit + * OID: 0.4.0.127.0.7.1.x.y1 */ + //TODO: replace "1" with correct OID + //public static readonly DerObjectIdentifier id_aes128_CBC_CMAC = aes_cbc_cmac.Branch("1"); + + /* AES encryption (CBC) and authentication (CMAC) with 192 bit + * OID: 0.4.0.127.0.7.1.x.y2 */ + //TODO: replace "1" with correct OID + //public static readonly DerObjectIdentifier id_aes192_CBC_CMAC = aes_cbc_cmac.Branch("1"); + + /* AES encryption (CBC) and authentication (CMAC) with 256 bit + * OID: 0.4.0.127.0.7.1.x.y3 */ + //TODO: replace "1" with correct OID + //public static readonly DerObjectIdentifier id_aes256_CBC_CMAC = aes_cbc_cmac.Branch("1"); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/bsi/BsiObjectIdentifiers.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/bsi/BsiObjectIdentifiers.cs.meta new file mode 100644 index 0000000..fc84ff5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/bsi/BsiObjectIdentifiers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8a6087d7c85db2346b53e614a9d5e0e8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp.meta new file mode 100644 index 0000000..cb571e0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ed24fc2e346c59a43ae7ee05cb42dafd +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CAKeyUpdAnnContent.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CAKeyUpdAnnContent.cs new file mode 100644 index 0000000..b74bac8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CAKeyUpdAnnContent.cs @@ -0,0 +1,62 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cmp +{ + public class CAKeyUpdAnnContent + : Asn1Encodable + { + private readonly CmpCertificate oldWithNew; + private readonly CmpCertificate newWithOld; + private readonly CmpCertificate newWithNew; + + private CAKeyUpdAnnContent(Asn1Sequence seq) + { + oldWithNew = CmpCertificate.GetInstance(seq[0]); + newWithOld = CmpCertificate.GetInstance(seq[1]); + newWithNew = CmpCertificate.GetInstance(seq[2]); + } + + public static CAKeyUpdAnnContent GetInstance(object obj) + { + if (obj is CAKeyUpdAnnContent) + return (CAKeyUpdAnnContent)obj; + + if (obj is Asn1Sequence) + return new CAKeyUpdAnnContent((Asn1Sequence)obj); + + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + } + + public virtual CmpCertificate OldWithNew + { + get { return oldWithNew; } + } + + public virtual CmpCertificate NewWithOld + { + get { return newWithOld; } + } + + public virtual CmpCertificate NewWithNew + { + get { return newWithNew; } + } + + /** + *
+		 * CAKeyUpdAnnContent ::= SEQUENCE {
+		 *                             oldWithNew   CmpCertificate, -- old pub signed with new priv
+		 *                             newWithOld   CmpCertificate, -- new pub signed with old priv
+		 *                             newWithNew   CmpCertificate  -- new pub signed with new priv
+		 *  }
+		 * 
+ * @return a basic ASN.1 object representation. + */ + public override Asn1Object ToAsn1Object() + { + return new DerSequence(oldWithNew, newWithOld, newWithNew); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CAKeyUpdAnnContent.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CAKeyUpdAnnContent.cs.meta new file mode 100644 index 0000000..28647ff --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CAKeyUpdAnnContent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 474e41298a854bd44bfd4efa9809936f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CertConfirmContent.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CertConfirmContent.cs new file mode 100644 index 0000000..370a9e7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CertConfirmContent.cs @@ -0,0 +1,49 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cmp +{ + public class CertConfirmContent + : Asn1Encodable + { + private readonly Asn1Sequence content; + + private CertConfirmContent(Asn1Sequence seq) + { + content = seq; + } + + public static CertConfirmContent GetInstance(object obj) + { + if (obj is CertConfirmContent) + return (CertConfirmContent)obj; + + if (obj is Asn1Sequence) + return new CertConfirmContent((Asn1Sequence)obj); + + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + } + + public virtual CertStatus[] ToCertStatusArray() + { + CertStatus[] result = new CertStatus[content.Count]; + for (int i = 0; i != result.Length; i++) + { + result[i] = CertStatus.GetInstance(content[i]); + } + return result; + } + + /** + *
+		 * CertConfirmContent ::= SEQUENCE OF CertStatus
+		 * 
+ * @return a basic ASN.1 object representation. + */ + public override Asn1Object ToAsn1Object() + { + return content; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CertConfirmContent.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CertConfirmContent.cs.meta new file mode 100644 index 0000000..7ee73b6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CertConfirmContent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 85f021d28db90c144a31fe081af237f5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CertOrEncCert.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CertOrEncCert.cs new file mode 100644 index 0000000..eb200e1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CertOrEncCert.cs @@ -0,0 +1,86 @@ +using System; + +using Org.BouncyCastle.Asn1.Crmf; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cmp +{ + public class CertOrEncCert + : Asn1Encodable, IAsn1Choice + { + private readonly CmpCertificate certificate; + private readonly EncryptedValue encryptedCert; + + private CertOrEncCert(Asn1TaggedObject tagged) + { + if (tagged.TagNo == 0) + { + certificate = CmpCertificate.GetInstance(tagged.GetObject()); + } + else if (tagged.TagNo == 1) + { + encryptedCert = EncryptedValue.GetInstance(tagged.GetObject()); + } + else + { + throw new ArgumentException("unknown tag: " + tagged.TagNo, "tagged"); + } + } + + public static CertOrEncCert GetInstance(object obj) + { + if (obj is CertOrEncCert) + return (CertOrEncCert)obj; + + if (obj is Asn1TaggedObject) + return new CertOrEncCert((Asn1TaggedObject)obj); + + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + } + + public CertOrEncCert(CmpCertificate certificate) + { + if (certificate == null) + throw new ArgumentNullException("certificate"); + + this.certificate = certificate; + } + + public CertOrEncCert(EncryptedValue encryptedCert) + { + if (encryptedCert == null) + throw new ArgumentNullException("encryptedCert"); + + this.encryptedCert = encryptedCert; + } + + public virtual CmpCertificate Certificate + { + get { return certificate; } + } + + public virtual EncryptedValue EncryptedCert + { + get { return encryptedCert; } + } + + /** + *
+		 * CertOrEncCert ::= CHOICE {
+		 *                      certificate     [0] CMPCertificate,
+		 *                      encryptedCert   [1] EncryptedValue
+		 *           }
+		 * 
+ * @return a basic ASN.1 object representation. + */ + public override Asn1Object ToAsn1Object() + { + if (certificate != null) + { + return new DerTaggedObject(true, 0, certificate); + } + + return new DerTaggedObject(true, 1, encryptedCert); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CertOrEncCert.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CertOrEncCert.cs.meta new file mode 100644 index 0000000..ae56f6c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CertOrEncCert.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: be5c4bf70f5b7dd499457931ea36a39e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CertRepMessage.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CertRepMessage.cs new file mode 100644 index 0000000..d24dd96 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CertRepMessage.cs @@ -0,0 +1,90 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cmp +{ + public class CertRepMessage + : Asn1Encodable + { + private readonly Asn1Sequence caPubs; + private readonly Asn1Sequence response; + + private CertRepMessage(Asn1Sequence seq) + { + int index = 0; + + if (seq.Count > 1) + { + caPubs = Asn1Sequence.GetInstance((Asn1TaggedObject)seq[index++], true); + } + + response = Asn1Sequence.GetInstance(seq[index]); + } + + public static CertRepMessage GetInstance(object obj) + { + if (obj is CertRepMessage) + return (CertRepMessage)obj; + + if (obj is Asn1Sequence) + return new CertRepMessage((Asn1Sequence)obj); + + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + } + + public CertRepMessage(CmpCertificate[] caPubs, CertResponse[] response) + { + if (response == null) + throw new ArgumentNullException("response"); + + if (caPubs != null) + { + this.caPubs = new DerSequence(caPubs); + } + + this.response = new DerSequence(response); + } + + public virtual CmpCertificate[] GetCAPubs() + { + if (caPubs == null) + return null; + + CmpCertificate[] results = new CmpCertificate[caPubs.Count]; + for (int i = 0; i != results.Length; ++i) + { + results[i] = CmpCertificate.GetInstance(caPubs[i]); + } + return results; + } + + public virtual CertResponse[] GetResponse() + { + CertResponse[] results = new CertResponse[response.Count]; + for (int i = 0; i != results.Length; ++i) + { + results[i] = CertResponse.GetInstance(response[i]); + } + return results; + } + + /** + *
+		 * CertRepMessage ::= SEQUENCE {
+		 *                          caPubs       [1] SEQUENCE SIZE (1..MAX) OF CMPCertificate
+		 *                                                                             OPTIONAL,
+		 *                          response         SEQUENCE OF CertResponse
+		 * }
+		 * 
+ * @return a basic ASN.1 object representation. + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + v.AddOptionalTagged(true, 1, caPubs); + v.Add(response); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CertRepMessage.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CertRepMessage.cs.meta new file mode 100644 index 0000000..71f56ff --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CertRepMessage.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 15c3190d4f585414ca861734175fa89c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CertResponse.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CertResponse.cs new file mode 100644 index 0000000..843fd92 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CertResponse.cs @@ -0,0 +1,116 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cmp +{ + public class CertResponse + : Asn1Encodable + { + private readonly DerInteger certReqId; + private readonly PkiStatusInfo status; + private readonly CertifiedKeyPair certifiedKeyPair; + private readonly Asn1OctetString rspInfo; + + private CertResponse(Asn1Sequence seq) + { + certReqId = DerInteger.GetInstance(seq[0]); + status = PkiStatusInfo.GetInstance(seq[1]); + + if (seq.Count >= 3) + { + if (seq.Count == 3) + { + Asn1Encodable o = seq[2]; + if (o is Asn1OctetString) + { + rspInfo = Asn1OctetString.GetInstance(o); + } + else + { + certifiedKeyPair = CertifiedKeyPair.GetInstance(o); + } + } + else + { + certifiedKeyPair = CertifiedKeyPair.GetInstance(seq[2]); + rspInfo = Asn1OctetString.GetInstance(seq[3]); + } + } + } + + public static CertResponse GetInstance(object obj) + { + if (obj is CertResponse) + return (CertResponse)obj; + + if (obj is Asn1Sequence) + return new CertResponse((Asn1Sequence)obj); + + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + } + + public CertResponse( + DerInteger certReqId, + PkiStatusInfo status) + : this(certReqId, status, null, null) + { + } + + public CertResponse( + DerInteger certReqId, + PkiStatusInfo status, + CertifiedKeyPair certifiedKeyPair, + Asn1OctetString rspInfo) + { + if (certReqId == null) + throw new ArgumentNullException("certReqId"); + + if (status == null) + throw new ArgumentNullException("status"); + + this.certReqId = certReqId; + this.status = status; + this.certifiedKeyPair = certifiedKeyPair; + this.rspInfo = rspInfo; + } + + public virtual DerInteger CertReqID + { + get { return certReqId; } + } + + public virtual PkiStatusInfo Status + { + get { return status; } + } + + public virtual CertifiedKeyPair CertifiedKeyPair + { + get { return certifiedKeyPair; } + } + + /** + *
+		 * CertResponse ::= SEQUENCE {
+		 *                            certReqId           INTEGER,
+		 *                            -- to match this response with corresponding request (a value
+		 *                            -- of -1 is to be used if certReqId is not specified in the
+		 *                            -- corresponding request)
+		 *                            status              PKIStatusInfo,
+		 *                            certifiedKeyPair    CertifiedKeyPair    OPTIONAL,
+		 *                            rspInfo             OCTET STRING        OPTIONAL
+		 *                            -- analogous to the id-regInfo-utf8Pairs string defined
+		 *                            -- for regInfo in CertReqMsg [CRMF]
+		 *             }
+		 * 
+ * @return a basic ASN.1 object representation. + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(certReqId, status); + v.AddOptional(certifiedKeyPair, rspInfo); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CertResponse.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CertResponse.cs.meta new file mode 100644 index 0000000..7c5c848 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CertResponse.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 90c72bf7e4fcc2943babbc73279ae02e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CertStatus.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CertStatus.cs new file mode 100644 index 0000000..d437b57 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CertStatus.cs @@ -0,0 +1,85 @@ +using System; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cmp +{ + public class CertStatus + : Asn1Encodable + { + private readonly Asn1OctetString certHash; + private readonly DerInteger certReqId; + private readonly PkiStatusInfo statusInfo; + + private CertStatus(Asn1Sequence seq) + { + certHash = Asn1OctetString.GetInstance(seq[0]); + certReqId = DerInteger.GetInstance(seq[1]); + + if (seq.Count > 2) + { + statusInfo = PkiStatusInfo.GetInstance(seq[2]); + } + } + + public CertStatus(byte[] certHash, BigInteger certReqId) + { + this.certHash = new DerOctetString(certHash); + this.certReqId = new DerInteger(certReqId); + } + + public CertStatus(byte[] certHash, BigInteger certReqId, PkiStatusInfo statusInfo) + { + this.certHash = new DerOctetString(certHash); + this.certReqId = new DerInteger(certReqId); + this.statusInfo = statusInfo; + } + + public static CertStatus GetInstance(object obj) + { + if (obj is CertStatus) + return (CertStatus)obj; + + if (obj is Asn1Sequence) + return new CertStatus((Asn1Sequence)obj); + + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + } + + public virtual Asn1OctetString CertHash + { + get { return certHash; } + } + + public virtual DerInteger CertReqID + { + get { return certReqId; } + } + + public virtual PkiStatusInfo StatusInfo + { + get { return statusInfo; } + } + + /** + *
+		 * CertStatus ::= SEQUENCE {
+		 *                   certHash    OCTET STRING,
+		 *                   -- the hash of the certificate, using the same hash algorithm
+		 *                   -- as is used to create and verify the certificate signature
+		 *                   certReqId   INTEGER,
+		 *                   -- to match this confirmation with the corresponding req/rep
+		 *                   statusInfo  PKIStatusInfo OPTIONAL
+		 * }
+		 * 
+ * @return a basic ASN.1 object representation. + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(certHash, certReqId); + v.AddOptional(statusInfo); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CertStatus.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CertStatus.cs.meta new file mode 100644 index 0000000..032a795 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CertStatus.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 592eeb00acc7d574ba98151ae3c80553 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CertifiedKeyPair.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CertifiedKeyPair.cs new file mode 100644 index 0000000..0b1c5d4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CertifiedKeyPair.cs @@ -0,0 +1,106 @@ +using System; + +using Org.BouncyCastle.Asn1.Crmf; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cmp +{ + public class CertifiedKeyPair + : Asn1Encodable + { + private readonly CertOrEncCert certOrEncCert; + private readonly EncryptedValue privateKey; + private readonly PkiPublicationInfo publicationInfo; + + private CertifiedKeyPair(Asn1Sequence seq) + { + certOrEncCert = CertOrEncCert.GetInstance(seq[0]); + + if (seq.Count >= 2) + { + if (seq.Count == 2) + { + Asn1TaggedObject tagged = Asn1TaggedObject.GetInstance(seq[1]); + if (tagged.TagNo == 0) + { + privateKey = EncryptedValue.GetInstance(tagged.GetObject()); + } + else + { + publicationInfo = PkiPublicationInfo.GetInstance(tagged.GetObject()); + } + } + else + { + privateKey = EncryptedValue.GetInstance(Asn1TaggedObject.GetInstance(seq[1])); + publicationInfo = PkiPublicationInfo.GetInstance(Asn1TaggedObject.GetInstance(seq[2])); + } + } + } + + public static CertifiedKeyPair GetInstance(object obj) + { + if (obj is CertifiedKeyPair) + return (CertifiedKeyPair)obj; + + if (obj is Asn1Sequence) + return new CertifiedKeyPair((Asn1Sequence)obj); + + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + } + + public CertifiedKeyPair( + CertOrEncCert certOrEncCert) + : this(certOrEncCert, null, null) + { + } + + public CertifiedKeyPair( + CertOrEncCert certOrEncCert, + EncryptedValue privateKey, + PkiPublicationInfo publicationInfo + ) + { + if (certOrEncCert == null) + throw new ArgumentNullException("certOrEncCert"); + + this.certOrEncCert = certOrEncCert; + this.privateKey = privateKey; + this.publicationInfo = publicationInfo; + } + + public virtual CertOrEncCert CertOrEncCert + { + get { return certOrEncCert; } + } + + public virtual EncryptedValue PrivateKey + { + get { return privateKey; } + } + + public virtual PkiPublicationInfo PublicationInfo + { + get { return publicationInfo; } + } + + /** + *
+		 * CertifiedKeyPair ::= SEQUENCE {
+		 *                                  certOrEncCert       CertOrEncCert,
+		 *                                  privateKey      [0] EncryptedValue      OPTIONAL,
+		 *                                  -- see [CRMF] for comment on encoding
+		 *                                  publicationInfo [1] PKIPublicationInfo  OPTIONAL
+		 *       }
+		 * 
+ * @return a basic ASN.1 object representation. + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(certOrEncCert); + v.AddOptionalTagged(true, 0, privateKey); + v.AddOptionalTagged(true, 1, publicationInfo); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CertifiedKeyPair.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CertifiedKeyPair.cs.meta new file mode 100644 index 0000000..df8f4b3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CertifiedKeyPair.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cd661ff02661f724e9b795f1741e1096 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/Challenge.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/Challenge.cs new file mode 100644 index 0000000..016c082 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/Challenge.cs @@ -0,0 +1,79 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cmp +{ + public class Challenge + : Asn1Encodable + { + private readonly AlgorithmIdentifier owf; + private readonly Asn1OctetString witness; + private readonly Asn1OctetString challenge; + + private Challenge(Asn1Sequence seq) + { + int index = 0; + + if (seq.Count == 3) + { + owf = AlgorithmIdentifier.GetInstance(seq[index++]); + } + + witness = Asn1OctetString.GetInstance(seq[index++]); + challenge = Asn1OctetString.GetInstance(seq[index]); + } + + public static Challenge GetInstance(object obj) + { + if (obj is Challenge) + return (Challenge)obj; + + if (obj is Asn1Sequence) + return new Challenge((Asn1Sequence)obj); + + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + } + + public virtual AlgorithmIdentifier Owf + { + get { return owf; } + } + + /** + *
+		 * Challenge ::= SEQUENCE {
+		 *                 owf                 AlgorithmIdentifier  OPTIONAL,
+		 *
+		 *                 -- MUST be present in the first Challenge; MAY be omitted in
+		 *                 -- any subsequent Challenge in POPODecKeyChallContent (if
+		 *                 -- omitted, then the owf used in the immediately preceding
+		 *                 -- Challenge is to be used).
+		 *
+		 *                 witness             OCTET STRING,
+		 *                 -- the result of applying the one-way function (owf) to a
+		 *                 -- randomly-generated INTEGER, A.  [Note that a different
+		 *                 -- INTEGER MUST be used for each Challenge.]
+		 *                 challenge           OCTET STRING
+		 *                 -- the encryption (under the public key for which the cert.
+		 *                 -- request is being made) of Rand, where Rand is specified as
+		 *                 --   Rand ::= SEQUENCE {
+		 *                 --      int      INTEGER,
+		 *                 --       - the randomly-generated INTEGER A (above)
+		 *                 --      sender   GeneralName
+		 *                 --       - the sender's name (as included in PKIHeader)
+		 *                 --   }
+		 *      }
+		 * 
+ * @return a basic ASN.1 object representation. + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + v.AddOptional(owf); + v.Add(witness, challenge); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/Challenge.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/Challenge.cs.meta new file mode 100644 index 0000000..700c1f3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/Challenge.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d1d036b30e773c647bb44d0e13e2c650 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CmpCertificate.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CmpCertificate.cs new file mode 100644 index 0000000..33356b4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CmpCertificate.cs @@ -0,0 +1,81 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cmp +{ + public class CmpCertificate + : Asn1Encodable, IAsn1Choice + { + private readonly X509CertificateStructure x509v3PKCert; + private readonly AttributeCertificate x509v2AttrCert; + + /** + * Note: the addition of attribute certificates is a BC extension. + */ + public CmpCertificate(AttributeCertificate x509v2AttrCert) + { + this.x509v2AttrCert = x509v2AttrCert; + } + + public CmpCertificate(X509CertificateStructure x509v3PKCert) + { + if (x509v3PKCert.Version != 3) + throw new ArgumentException("only version 3 certificates allowed", "x509v3PKCert"); + + this.x509v3PKCert = x509v3PKCert; + } + + public static CmpCertificate GetInstance(object obj) + { + if (obj is CmpCertificate) + return (CmpCertificate)obj; + + if (obj is Asn1Sequence) + return new CmpCertificate(X509CertificateStructure.GetInstance(obj)); + + if (obj is Asn1TaggedObject) + return new CmpCertificate(AttributeCertificate.GetInstance(((Asn1TaggedObject)obj).GetObject())); + + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + } + + public virtual bool IsX509v3PKCert + { + get { return x509v3PKCert != null; } + } + + public virtual X509CertificateStructure X509v3PKCert + { + get { return x509v3PKCert; } + } + + public virtual AttributeCertificate X509v2AttrCert + { + get { return x509v2AttrCert; } + } + + /** + *
+         * CMPCertificate ::= CHOICE {
+         *            x509v3PKCert        Certificate
+         *            x509v2AttrCert      [1] AttributeCertificate
+         *  }
+         * 
+ * Note: the addition of attribute certificates is a BC extension. + * + * @return a basic ASN.1 object representation. + */ + public override Asn1Object ToAsn1Object() + { + if (x509v2AttrCert != null) + { + // explicit following CMP conventions + return new DerTaggedObject(true, 1, x509v2AttrCert); + } + + return x509v3PKCert.ToAsn1Object(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CmpCertificate.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CmpCertificate.cs.meta new file mode 100644 index 0000000..bd28fb0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CmpCertificate.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2d89b48b8615b6546b13d746b72c5b8f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CmpObjectIdentifiers.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CmpObjectIdentifiers.cs new file mode 100644 index 0000000..7e82741 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CmpObjectIdentifiers.cs @@ -0,0 +1,106 @@ +using System; + +namespace Org.BouncyCastle.Asn1.Cmp +{ + public abstract class CmpObjectIdentifiers + { + // RFC 4210 + + // id-PasswordBasedMac OBJECT IDENTIFIER ::= {1 2 840 113533 7 66 13} + public static readonly DerObjectIdentifier passwordBasedMac = new DerObjectIdentifier("1.2.840.113533.7.66.13"); + + // id-DHBasedMac OBJECT IDENTIFIER ::= {1 2 840 113533 7 66 30} + public static readonly DerObjectIdentifier dhBasedMac = new DerObjectIdentifier("1.2.840.113533.7.66.30"); + + // Example InfoTypeAndValue contents include, but are not limited + // to, the following (un-comment in this ASN.1 module and use as + // appropriate for a given environment): + // + // id-it-caProtEncCert OBJECT IDENTIFIER ::= {id-it 1} + // CAProtEncCertValue ::= CMPCertificate + // id-it-signKeyPairTypes OBJECT IDENTIFIER ::= {id-it 2} + // SignKeyPairTypesValue ::= SEQUENCE OF AlgorithmIdentifier + // id-it-encKeyPairTypes OBJECT IDENTIFIER ::= {id-it 3} + // EncKeyPairTypesValue ::= SEQUENCE OF AlgorithmIdentifier + // id-it-preferredSymmAlg OBJECT IDENTIFIER ::= {id-it 4} + // PreferredSymmAlgValue ::= AlgorithmIdentifier + // id-it-caKeyUpdateInfo OBJECT IDENTIFIER ::= {id-it 5} + // CAKeyUpdateInfoValue ::= CAKeyUpdAnnContent + // id-it-currentCRL OBJECT IDENTIFIER ::= {id-it 6} + // CurrentCRLValue ::= CertificateList + // id-it-unsupportedOIDs OBJECT IDENTIFIER ::= {id-it 7} + // UnsupportedOIDsValue ::= SEQUENCE OF OBJECT IDENTIFIER + // id-it-keyPairParamReq OBJECT IDENTIFIER ::= {id-it 10} + // KeyPairParamReqValue ::= OBJECT IDENTIFIER + // id-it-keyPairParamRep OBJECT IDENTIFIER ::= {id-it 11} + // KeyPairParamRepValue ::= AlgorithmIdentifer + // id-it-revPassphrase OBJECT IDENTIFIER ::= {id-it 12} + // RevPassphraseValue ::= EncryptedValue + // id-it-implicitConfirm OBJECT IDENTIFIER ::= {id-it 13} + // ImplicitConfirmValue ::= NULL + // id-it-confirmWaitTime OBJECT IDENTIFIER ::= {id-it 14} + // ConfirmWaitTimeValue ::= GeneralizedTime + // id-it-origPKIMessage OBJECT IDENTIFIER ::= {id-it 15} + // OrigPKIMessageValue ::= PKIMessages + // id-it-suppLangTags OBJECT IDENTIFIER ::= {id-it 16} + // SuppLangTagsValue ::= SEQUENCE OF UTF8String + // + // where + // + // id-pkix OBJECT IDENTIFIER ::= { + // iso(1) identified-organization(3) + // dod(6) internet(1) security(5) mechanisms(5) pkix(7)} + // and + // id-it OBJECT IDENTIFIER ::= {id-pkix 4} + public static readonly DerObjectIdentifier it_caProtEncCert = new DerObjectIdentifier("1.3.6.1.5.5.7.4.1"); + public static readonly DerObjectIdentifier it_signKeyPairTypes = new DerObjectIdentifier("1.3.6.1.5.5.7.4.2"); + public static readonly DerObjectIdentifier it_encKeyPairTypes = new DerObjectIdentifier("1.3.6.1.5.5.7.4.3"); + public static readonly DerObjectIdentifier it_preferredSymAlg = new DerObjectIdentifier("1.3.6.1.5.5.7.4.4"); + public static readonly DerObjectIdentifier it_caKeyUpdateInfo = new DerObjectIdentifier("1.3.6.1.5.5.7.4.5"); + public static readonly DerObjectIdentifier it_currentCRL = new DerObjectIdentifier("1.3.6.1.5.5.7.4.6"); + public static readonly DerObjectIdentifier it_unsupportedOIDs = new DerObjectIdentifier("1.3.6.1.5.5.7.4.7"); + public static readonly DerObjectIdentifier it_keyPairParamReq = new DerObjectIdentifier("1.3.6.1.5.5.7.4.10"); + public static readonly DerObjectIdentifier it_keyPairParamRep = new DerObjectIdentifier("1.3.6.1.5.5.7.4.11"); + public static readonly DerObjectIdentifier it_revPassphrase = new DerObjectIdentifier("1.3.6.1.5.5.7.4.12"); + public static readonly DerObjectIdentifier it_implicitConfirm = new DerObjectIdentifier("1.3.6.1.5.5.7.4.13"); + public static readonly DerObjectIdentifier it_confirmWaitTime = new DerObjectIdentifier("1.3.6.1.5.5.7.4.14"); + public static readonly DerObjectIdentifier it_origPKIMessage = new DerObjectIdentifier("1.3.6.1.5.5.7.4.15"); + public static readonly DerObjectIdentifier it_suppLangTags = new DerObjectIdentifier("1.3.6.1.5.5.7.4.16"); + + // RFC 4211 + + // id-pkix OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) + // dod(6) internet(1) security(5) mechanisms(5) pkix(7) } + // + // arc for Internet X.509 PKI protocols and their components + // id-pkip OBJECT IDENTIFIER :: { id-pkix pkip(5) } + // + // arc for Registration Controls in CRMF + // id-regCtrl OBJECT IDENTIFIER ::= { id-pkip regCtrl(1) } + // + // arc for Registration Info in CRMF + // id-regInfo OBJECT IDENTIFIER ::= { id-pkip id-regInfo(2) } + + public static readonly DerObjectIdentifier regCtrl_regToken = new DerObjectIdentifier("1.3.6.1.5.5.7.5.1.1"); + public static readonly DerObjectIdentifier regCtrl_authenticator = new DerObjectIdentifier("1.3.6.1.5.5.7.5.1.2"); + public static readonly DerObjectIdentifier regCtrl_pkiPublicationInfo = new DerObjectIdentifier("1.3.6.1.5.5.7.5.1.3"); + public static readonly DerObjectIdentifier regCtrl_pkiArchiveOptions = new DerObjectIdentifier("1.3.6.1.5.5.7.5.1.4"); + public static readonly DerObjectIdentifier regCtrl_oldCertID = new DerObjectIdentifier("1.3.6.1.5.5.7.5.1.5"); + public static readonly DerObjectIdentifier regCtrl_protocolEncrKey = new DerObjectIdentifier("1.3.6.1.5.5.7.5.1.6"); + + // From RFC4210: + // id-regCtrl-altCertTemplate OBJECT IDENTIFIER ::= {id-regCtrl 7} + public static readonly DerObjectIdentifier regCtrl_altCertTemplate = new DerObjectIdentifier("1.3.6.1.5.5.7.5.1.7"); + + public static readonly DerObjectIdentifier regInfo_utf8Pairs = new DerObjectIdentifier("1.3.6.1.5.5.7.5.2.1"); + public static readonly DerObjectIdentifier regInfo_certReq = new DerObjectIdentifier("1.3.6.1.5.5.7.5.2.2"); + + // id-smime OBJECT IDENTIFIER ::= { iso(1) member-body(2) + // us(840) rsadsi(113549) pkcs(1) pkcs9(9) 16 } + // + // id-ct OBJECT IDENTIFIER ::= { id-smime 1 } -- content types + // + // id-ct-encKeyWithID OBJECT IDENTIFIER ::= {id-ct 21} + public static readonly DerObjectIdentifier ct_encKeyWithID = new DerObjectIdentifier("1.2.840.113549.1.9.16.1.21"); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CmpObjectIdentifiers.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CmpObjectIdentifiers.cs.meta new file mode 100644 index 0000000..dbf7402 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CmpObjectIdentifiers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 23e40538d0d4d6f4698184ba03838e17 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CrlAnnContent.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CrlAnnContent.cs new file mode 100644 index 0000000..db8ecfa --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CrlAnnContent.cs @@ -0,0 +1,50 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cmp +{ + public class CrlAnnContent + : Asn1Encodable + { + private readonly Asn1Sequence content; + + private CrlAnnContent(Asn1Sequence seq) + { + content = seq; + } + + public static CrlAnnContent GetInstance(object obj) + { + if (obj is CrlAnnContent) + return (CrlAnnContent)obj; + + if (obj is Asn1Sequence) + return new CrlAnnContent((Asn1Sequence)obj); + + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + } + + public virtual CertificateList[] ToCertificateListArray() + { + CertificateList[] result = new CertificateList[content.Count]; + for (int i = 0; i != result.Length; ++ i) + { + result[i] = CertificateList.GetInstance(content[i]); + } + return result; + } + + /** + *
+		 * CrlAnnContent ::= SEQUENCE OF CertificateList
+		 * 
+ * @return a basic ASN.1 object representation. + */ + public override Asn1Object ToAsn1Object() + { + return content; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CrlAnnContent.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CrlAnnContent.cs.meta new file mode 100644 index 0000000..b672f3d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/CrlAnnContent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7c68dd71817a7f448a4231d01e266ed3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/ErrorMsgContent.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/ErrorMsgContent.cs new file mode 100644 index 0000000..5d2132b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/ErrorMsgContent.cs @@ -0,0 +1,95 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cmp +{ + public class ErrorMsgContent + : Asn1Encodable + { + private readonly PkiStatusInfo pkiStatusInfo; + private readonly DerInteger errorCode; + private readonly PkiFreeText errorDetails; + + private ErrorMsgContent(Asn1Sequence seq) + { + pkiStatusInfo = PkiStatusInfo.GetInstance(seq[0]); + + for (int pos = 1; pos < seq.Count; ++pos) + { + Asn1Encodable ae = seq[pos]; + if (ae is DerInteger) + { + errorCode = DerInteger.GetInstance(ae); + } + else + { + errorDetails = PkiFreeText.GetInstance(ae); + } + } + } + + public static ErrorMsgContent GetInstance(object obj) + { + if (obj is ErrorMsgContent) + return (ErrorMsgContent)obj; + + if (obj is Asn1Sequence) + return new ErrorMsgContent((Asn1Sequence)obj); + + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + } + + public ErrorMsgContent(PkiStatusInfo pkiStatusInfo) + : this(pkiStatusInfo, null, null) + { + } + + public ErrorMsgContent( + PkiStatusInfo pkiStatusInfo, + DerInteger errorCode, + PkiFreeText errorDetails) + { + if (pkiStatusInfo == null) + throw new ArgumentNullException("pkiStatusInfo"); + + this.pkiStatusInfo = pkiStatusInfo; + this.errorCode = errorCode; + this.errorDetails = errorDetails; + } + + public virtual PkiStatusInfo PkiStatusInfo + { + get { return pkiStatusInfo; } + } + + public virtual DerInteger ErrorCode + { + get { return errorCode; } + } + + public virtual PkiFreeText ErrorDetails + { + get { return errorDetails; } + } + + /** + *
+		 * ErrorMsgContent ::= SEQUENCE {
+		 *                        pKIStatusInfo          PKIStatusInfo,
+		 *                        errorCode              INTEGER           OPTIONAL,
+		 *                        -- implementation-specific error codes
+		 *                        errorDetails           PKIFreeText       OPTIONAL
+		 *                        -- implementation-specific error details
+		 * }
+		 * 
+ * @return a basic ASN.1 object representation. + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(pkiStatusInfo); + v.AddOptional(errorCode, errorDetails); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/ErrorMsgContent.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/ErrorMsgContent.cs.meta new file mode 100644 index 0000000..9efaae1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/ErrorMsgContent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f255bdc7c064018429d76562ba761dc9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/GenMsgContent.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/GenMsgContent.cs new file mode 100644 index 0000000..f3142b5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/GenMsgContent.cs @@ -0,0 +1,54 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cmp +{ + public class GenMsgContent + : Asn1Encodable + { + private readonly Asn1Sequence content; + + private GenMsgContent(Asn1Sequence seq) + { + content = seq; + } + + public static GenMsgContent GetInstance(object obj) + { + if (obj is GenMsgContent) + return (GenMsgContent)obj; + + if (obj is Asn1Sequence) + return new GenMsgContent((Asn1Sequence)obj); + + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + } + + public GenMsgContent(params InfoTypeAndValue[] itv) + { + content = new DerSequence(itv); + } + + public virtual InfoTypeAndValue[] ToInfoTypeAndValueArray() + { + InfoTypeAndValue[] result = new InfoTypeAndValue[content.Count]; + for (int i = 0; i != result.Length; ++i) + { + result[i] = InfoTypeAndValue.GetInstance(content[i]); + } + return result; + } + + /** + *
+		 * GenMsgContent ::= SEQUENCE OF InfoTypeAndValue
+		 * 
+ * @return a basic ASN.1 object representation. + */ + public override Asn1Object ToAsn1Object() + { + return content; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/GenMsgContent.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/GenMsgContent.cs.meta new file mode 100644 index 0000000..6384fa4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/GenMsgContent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9e78c318056ca214ab107b038b86c843 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/GenRepContent.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/GenRepContent.cs new file mode 100644 index 0000000..3c3573e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/GenRepContent.cs @@ -0,0 +1,54 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cmp +{ + public class GenRepContent + : Asn1Encodable + { + private readonly Asn1Sequence content; + + private GenRepContent(Asn1Sequence seq) + { + content = seq; + } + + public static GenRepContent GetInstance(object obj) + { + if (obj is GenRepContent) + return (GenRepContent)obj; + + if (obj is Asn1Sequence) + return new GenRepContent((Asn1Sequence)obj); + + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + } + + public GenRepContent(params InfoTypeAndValue[] itv) + { + content = new DerSequence(itv); + } + + public virtual InfoTypeAndValue[] ToInfoTypeAndValueArray() + { + InfoTypeAndValue[] result = new InfoTypeAndValue[content.Count]; + for (int i = 0; i != result.Length; ++i) + { + result[i] = InfoTypeAndValue.GetInstance(content[i]); + } + return result; + } + + /** + *
+		 * GenRepContent ::= SEQUENCE OF InfoTypeAndValue
+		 * 
+ * @return a basic ASN.1 object representation. + */ + public override Asn1Object ToAsn1Object() + { + return content; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/GenRepContent.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/GenRepContent.cs.meta new file mode 100644 index 0000000..b602ada --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/GenRepContent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cf873e8844838444387334c9838b73d3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/InfoTypeAndValue.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/InfoTypeAndValue.cs new file mode 100644 index 0000000..305d6e5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/InfoTypeAndValue.cs @@ -0,0 +1,118 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cmp +{ + /** + * Example InfoTypeAndValue contents include, but are not limited + * to, the following (un-comment in this ASN.1 module and use as + * appropriate for a given environment): + *
+     *   id-it-caProtEncCert    OBJECT IDENTIFIER ::= {id-it 1}
+     *      CAProtEncCertValue      ::= CMPCertificate
+     *   id-it-signKeyPairTypes OBJECT IDENTIFIER ::= {id-it 2}
+     *     SignKeyPairTypesValue   ::= SEQUENCE OF AlgorithmIdentifier
+     *   id-it-encKeyPairTypes  OBJECT IDENTIFIER ::= {id-it 3}
+     *     EncKeyPairTypesValue    ::= SEQUENCE OF AlgorithmIdentifier
+     *   id-it-preferredSymmAlg OBJECT IDENTIFIER ::= {id-it 4}
+     *      PreferredSymmAlgValue   ::= AlgorithmIdentifier
+     *   id-it-caKeyUpdateInfo  OBJECT IDENTIFIER ::= {id-it 5}
+     *      CAKeyUpdateInfoValue    ::= CAKeyUpdAnnContent
+     *   id-it-currentCRL       OBJECT IDENTIFIER ::= {id-it 6}
+     *      CurrentCRLValue         ::= CertificateList
+     *   id-it-unsupportedOIDs  OBJECT IDENTIFIER ::= {id-it 7}
+     *      UnsupportedOIDsValue    ::= SEQUENCE OF OBJECT IDENTIFIER
+     *   id-it-keyPairParamReq  OBJECT IDENTIFIER ::= {id-it 10}
+     *      KeyPairParamReqValue    ::= OBJECT IDENTIFIER
+     *   id-it-keyPairParamRep  OBJECT IDENTIFIER ::= {id-it 11}
+     *      KeyPairParamRepValue    ::= AlgorithmIdentifer
+     *   id-it-revPassphrase    OBJECT IDENTIFIER ::= {id-it 12}
+     *      RevPassphraseValue      ::= EncryptedValue
+     *   id-it-implicitConfirm  OBJECT IDENTIFIER ::= {id-it 13}
+     *      ImplicitConfirmValue    ::= NULL
+     *   id-it-confirmWaitTime  OBJECT IDENTIFIER ::= {id-it 14}
+     *      ConfirmWaitTimeValue    ::= GeneralizedTime
+     *   id-it-origPKIMessage   OBJECT IDENTIFIER ::= {id-it 15}
+     *      OrigPKIMessageValue     ::= PKIMessages
+     *   id-it-suppLangTags     OBJECT IDENTIFIER ::= {id-it 16}
+     *      SuppLangTagsValue       ::= SEQUENCE OF UTF8String
+     *
+     * where
+     *
+     *   id-pkix OBJECT IDENTIFIER ::= {
+     *      iso(1) identified-organization(3)
+     *      dod(6) internet(1) security(5) mechanisms(5) pkix(7)}
+     * and
+     *      id-it   OBJECT IDENTIFIER ::= {id-pkix 4}
+     * 
+ */ + public class InfoTypeAndValue + : Asn1Encodable + { + private readonly DerObjectIdentifier infoType; + private readonly Asn1Encodable infoValue; + + private InfoTypeAndValue(Asn1Sequence seq) + { + infoType = DerObjectIdentifier.GetInstance(seq[0]); + + if (seq.Count > 1) + { + infoValue = (Asn1Encodable)seq[1]; + } + } + + public static InfoTypeAndValue GetInstance(object obj) + { + if (obj is InfoTypeAndValue) + return (InfoTypeAndValue)obj; + + if (obj is Asn1Sequence) + return new InfoTypeAndValue((Asn1Sequence)obj); + + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + } + + public InfoTypeAndValue( + DerObjectIdentifier infoType) + { + this.infoType = infoType; + this.infoValue = null; + } + + public InfoTypeAndValue( + DerObjectIdentifier infoType, + Asn1Encodable optionalValue) + { + this.infoType = infoType; + this.infoValue = optionalValue; + } + + public virtual DerObjectIdentifier InfoType + { + get { return infoType; } + } + + public virtual Asn1Encodable InfoValue + { + get { return infoValue; } + } + + /** + *
+         * InfoTypeAndValue ::= SEQUENCE {
+         *                         infoType               OBJECT IDENTIFIER,
+         *                         infoValue              ANY DEFINED BY infoType  OPTIONAL
+         * }
+         * 
+ * @return a basic ASN.1 object representation. + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(infoType); + v.AddOptional(infoValue); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/InfoTypeAndValue.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/InfoTypeAndValue.cs.meta new file mode 100644 index 0000000..2262bb1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/InfoTypeAndValue.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a51323cc59e78874fa43730f6e8666da +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/KeyRecRepContent.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/KeyRecRepContent.cs new file mode 100644 index 0000000..e35c0e3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/KeyRecRepContent.cs @@ -0,0 +1,109 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cmp +{ + public class KeyRecRepContent + : Asn1Encodable + { + private readonly PkiStatusInfo status; + private readonly CmpCertificate newSigCert; + private readonly Asn1Sequence caCerts; + private readonly Asn1Sequence keyPairHist; + + private KeyRecRepContent(Asn1Sequence seq) + { + status = PkiStatusInfo.GetInstance(seq[0]); + + for (int pos = 1; pos < seq.Count; ++pos) + { + Asn1TaggedObject tObj = Asn1TaggedObject.GetInstance(seq[pos]); + + switch (tObj.TagNo) + { + case 0: + newSigCert = CmpCertificate.GetInstance(tObj.GetObject()); + break; + case 1: + caCerts = Asn1Sequence.GetInstance(tObj.GetObject()); + break; + case 2: + keyPairHist = Asn1Sequence.GetInstance(tObj.GetObject()); + break; + default: + throw new ArgumentException("unknown tag number: " + tObj.TagNo, "seq"); + } + } + } + + public static KeyRecRepContent GetInstance(object obj) + { + if (obj is KeyRecRepContent) + return (KeyRecRepContent)obj; + + if (obj is Asn1Sequence) + return new KeyRecRepContent((Asn1Sequence)obj); + + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + } + + public virtual PkiStatusInfo Status + { + get { return status; } + } + + public virtual CmpCertificate NewSigCert + { + get { return newSigCert; } + } + + public virtual CmpCertificate[] GetCACerts() + { + if (caCerts == null) + return null; + + CmpCertificate[] results = new CmpCertificate[caCerts.Count]; + for (int i = 0; i != results.Length; ++i) + { + results[i] = CmpCertificate.GetInstance(caCerts[i]); + } + return results; + } + + public virtual CertifiedKeyPair[] GetKeyPairHist() + { + if (keyPairHist == null) + return null; + + CertifiedKeyPair[] results = new CertifiedKeyPair[keyPairHist.Count]; + for (int i = 0; i != results.Length; ++i) + { + results[i] = CertifiedKeyPair.GetInstance(keyPairHist[i]); + } + return results; + } + + /** + *
+		 * KeyRecRepContent ::= SEQUENCE {
+		 *                         status                  PKIStatusInfo,
+		 *                         newSigCert          [0] CMPCertificate OPTIONAL,
+		 *                         caCerts             [1] SEQUENCE SIZE (1..MAX) OF
+		 *                                                           CMPCertificate OPTIONAL,
+		 *                         keyPairHist         [2] SEQUENCE SIZE (1..MAX) OF
+		 *                                                           CertifiedKeyPair OPTIONAL
+		 *              }
+		 * 
+ * @return a basic ASN.1 object representation. + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(status); + v.AddOptionalTagged(true, 0, newSigCert); + v.AddOptionalTagged(true, 1, caCerts); + v.AddOptionalTagged(true, 2, keyPairHist); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/KeyRecRepContent.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/KeyRecRepContent.cs.meta new file mode 100644 index 0000000..aa35c60 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/KeyRecRepContent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c80679d86131035478e4a1eadf02713c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/OobCertHash.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/OobCertHash.cs new file mode 100644 index 0000000..434939c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/OobCertHash.cs @@ -0,0 +1,79 @@ +using System; + +using Org.BouncyCastle.Asn1.Crmf; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cmp +{ + public class OobCertHash + : Asn1Encodable + { + private readonly AlgorithmIdentifier hashAlg; + private readonly CertId certId; + private readonly DerBitString hashVal; + + private OobCertHash(Asn1Sequence seq) + { + int index = seq.Count - 1; + + hashVal = DerBitString.GetInstance(seq[index--]); + + for (int i = index; i >= 0; i--) + { + Asn1TaggedObject tObj = (Asn1TaggedObject)seq[i]; + + if (tObj.TagNo == 0) + { + hashAlg = AlgorithmIdentifier.GetInstance(tObj, true); + } + else + { + certId = CertId.GetInstance(tObj, true); + } + } + } + + public static OobCertHash GetInstance(object obj) + { + if (obj is OobCertHash) + return (OobCertHash)obj; + + if (obj is Asn1Sequence) + return new OobCertHash((Asn1Sequence)obj); + + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + } + + public virtual AlgorithmIdentifier HashAlg + { + get { return hashAlg; } + } + + public virtual CertId CertID + { + get { return certId; } + } + + /** + *
+		 * OobCertHash ::= SEQUENCE {
+		 *                      hashAlg     [0] AlgorithmIdentifier     OPTIONAL,
+		 *                      certId      [1] CertId                  OPTIONAL,
+		 *                      hashVal         BIT STRING
+		 *                      -- hashVal is calculated over the Der encoding of the
+		 *                      -- self-signed certificate with the identifier certID.
+		 *       }
+		 * 
+ * @return a basic ASN.1 object representation. + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + v.AddOptionalTagged(true, 0, hashAlg); + v.AddOptionalTagged(true, 1, certId); + v.Add(hashVal); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/OobCertHash.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/OobCertHash.cs.meta new file mode 100644 index 0000000..403dd6b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/OobCertHash.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ffb0b1eca53f9884994e499f799ca4e4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIBody.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIBody.cs new file mode 100644 index 0000000..f17eed6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIBody.cs @@ -0,0 +1,187 @@ +using System; + +using Org.BouncyCastle.Asn1.Crmf; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cmp +{ + public class PkiBody + : Asn1Encodable, IAsn1Choice + { + public const int TYPE_INIT_REQ = 0; + public const int TYPE_INIT_REP = 1; + public const int TYPE_CERT_REQ = 2; + public const int TYPE_CERT_REP = 3; + public const int TYPE_P10_CERT_REQ = 4; + public const int TYPE_POPO_CHALL = 5; + public const int TYPE_POPO_REP = 6; + public const int TYPE_KEY_UPDATE_REQ = 7; + public const int TYPE_KEY_UPDATE_REP = 8; + public const int TYPE_KEY_RECOVERY_REQ = 9; + public const int TYPE_KEY_RECOVERY_REP = 10; + public const int TYPE_REVOCATION_REQ = 11; + public const int TYPE_REVOCATION_REP = 12; + public const int TYPE_CROSS_CERT_REQ = 13; + public const int TYPE_CROSS_CERT_REP = 14; + public const int TYPE_CA_KEY_UPDATE_ANN = 15; + public const int TYPE_CERT_ANN = 16; + public const int TYPE_REVOCATION_ANN = 17; + public const int TYPE_CRL_ANN = 18; + public const int TYPE_CONFIRM = 19; + public const int TYPE_NESTED = 20; + public const int TYPE_GEN_MSG = 21; + public const int TYPE_GEN_REP = 22; + public const int TYPE_ERROR = 23; + public const int TYPE_CERT_CONFIRM = 24; + public const int TYPE_POLL_REQ = 25; + public const int TYPE_POLL_REP = 26; + + private int tagNo; + private Asn1Encodable body; + + public static PkiBody GetInstance(object obj) + { + if (obj is PkiBody) + return (PkiBody)obj; + + if (obj is Asn1TaggedObject) + return new PkiBody((Asn1TaggedObject)obj); + + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + } + + private PkiBody(Asn1TaggedObject tagged) + { + tagNo = tagged.TagNo; + body = GetBodyForType(tagNo, tagged.GetObject()); + } + + /** + * Creates a new PkiBody. + * @param type one of the TYPE_* constants + * @param content message content + */ + public PkiBody( + int type, + Asn1Encodable content) + { + tagNo = type; + body = GetBodyForType(type, content); + } + + private static Asn1Encodable GetBodyForType( + int type, + Asn1Encodable o) + { + switch (type) + { + case TYPE_INIT_REQ: + return CertReqMessages.GetInstance(o); + case TYPE_INIT_REP: + return CertRepMessage.GetInstance(o); + case TYPE_CERT_REQ: + return CertReqMessages.GetInstance(o); + case TYPE_CERT_REP: + return CertRepMessage.GetInstance(o); + case TYPE_P10_CERT_REQ: + return CertificationRequest.GetInstance(o); + case TYPE_POPO_CHALL: + return PopoDecKeyChallContent.GetInstance(o); + case TYPE_POPO_REP: + return PopoDecKeyRespContent.GetInstance(o); + case TYPE_KEY_UPDATE_REQ: + return CertReqMessages.GetInstance(o); + case TYPE_KEY_UPDATE_REP: + return CertRepMessage.GetInstance(o); + case TYPE_KEY_RECOVERY_REQ: + return CertReqMessages.GetInstance(o); + case TYPE_KEY_RECOVERY_REP: + return KeyRecRepContent.GetInstance(o); + case TYPE_REVOCATION_REQ: + return RevReqContent.GetInstance(o); + case TYPE_REVOCATION_REP: + return RevRepContent.GetInstance(o); + case TYPE_CROSS_CERT_REQ: + return CertReqMessages.GetInstance(o); + case TYPE_CROSS_CERT_REP: + return CertRepMessage.GetInstance(o); + case TYPE_CA_KEY_UPDATE_ANN: + return CAKeyUpdAnnContent.GetInstance(o); + case TYPE_CERT_ANN: + return CmpCertificate.GetInstance(o); + case TYPE_REVOCATION_ANN: + return RevAnnContent.GetInstance(o); + case TYPE_CRL_ANN: + return CrlAnnContent.GetInstance(o); + case TYPE_CONFIRM: + return PkiConfirmContent.GetInstance(o); + case TYPE_NESTED: + return PkiMessages.GetInstance(o); + case TYPE_GEN_MSG: + return GenMsgContent.GetInstance(o); + case TYPE_GEN_REP: + return GenRepContent.GetInstance(o); + case TYPE_ERROR: + return ErrorMsgContent.GetInstance(o); + case TYPE_CERT_CONFIRM: + return CertConfirmContent.GetInstance(o); + case TYPE_POLL_REQ: + return PollReqContent.GetInstance(o); + case TYPE_POLL_REP: + return PollRepContent.GetInstance(o); + default: + throw new ArgumentException("unknown tag number: " + type, "type"); + } + } + + public virtual int Type + { + get { return tagNo; } + } + + public virtual Asn1Encodable Content + { + get { return body; } + } + + /** + *
+         * PkiBody ::= CHOICE {       -- message-specific body elements
+         *        ir       [0]  CertReqMessages,        --Initialization Request
+         *        ip       [1]  CertRepMessage,         --Initialization Response
+         *        cr       [2]  CertReqMessages,        --Certification Request
+         *        cp       [3]  CertRepMessage,         --Certification Response
+         *        p10cr    [4]  CertificationRequest,   --imported from [PKCS10]
+         *        popdecc  [5]  POPODecKeyChallContent, --pop Challenge
+         *        popdecr  [6]  POPODecKeyRespContent,  --pop Response
+         *        kur      [7]  CertReqMessages,        --Key Update Request
+         *        kup      [8]  CertRepMessage,         --Key Update Response
+         *        krr      [9]  CertReqMessages,        --Key Recovery Request
+         *        krp      [10] KeyRecRepContent,       --Key Recovery Response
+         *        rr       [11] RevReqContent,          --Revocation Request
+         *        rp       [12] RevRepContent,          --Revocation Response
+         *        ccr      [13] CertReqMessages,        --Cross-Cert. Request
+         *        ccp      [14] CertRepMessage,         --Cross-Cert. Response
+         *        ckuann   [15] CAKeyUpdAnnContent,     --CA Key Update Ann.
+         *        cann     [16] CertAnnContent,         --Certificate Ann.
+         *        rann     [17] RevAnnContent,          --Revocation Ann.
+         *        crlann   [18] CRLAnnContent,          --CRL Announcement
+         *        pkiconf  [19] PKIConfirmContent,      --Confirmation
+         *        nested   [20] NestedMessageContent,   --Nested Message
+         *        genm     [21] GenMsgContent,          --General Message
+         *        genp     [22] GenRepContent,          --General Response
+         *        error    [23] ErrorMsgContent,        --Error Message
+         *        certConf [24] CertConfirmContent,     --Certificate confirm
+         *        pollReq  [25] PollReqContent,         --Polling request
+         *        pollRep  [26] PollRepContent          --Polling response
+         * }
+         * 
+ * @return a basic ASN.1 object representation. + */ + public override Asn1Object ToAsn1Object() + { + return new DerTaggedObject(true, tagNo, body); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIBody.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIBody.cs.meta new file mode 100644 index 0000000..0614152 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIBody.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3fafa620ddb503e4b987a9a8f1cfecfb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIConfirmContent.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIConfirmContent.cs new file mode 100644 index 0000000..d154427 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIConfirmContent.cs @@ -0,0 +1,36 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cmp +{ + public class PkiConfirmContent + : Asn1Encodable + { + public static PkiConfirmContent GetInstance(object obj) + { + if (obj is PkiConfirmContent) + return (PkiConfirmContent)obj; + + if (obj is Asn1Null) + return new PkiConfirmContent(); + + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + } + + public PkiConfirmContent() + { + } + + /** + *
+		 * PkiConfirmContent ::= NULL
+		 * 
+ * @return a basic ASN.1 object representation. + */ + public override Asn1Object ToAsn1Object() + { + return DerNull.Instance; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIConfirmContent.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIConfirmContent.cs.meta new file mode 100644 index 0000000..5dce050 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIConfirmContent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e52f92cdd81153845b659125672b95de +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIFailureInfo.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIFailureInfo.cs new file mode 100644 index 0000000..75a3ff0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIFailureInfo.cs @@ -0,0 +1,96 @@ +using System; + +namespace Org.BouncyCastle.Asn1.Cmp +{ + /** + *
+     * PKIFailureInfo ::= BIT STRING {
+     * badAlg               (0),
+     *   -- unrecognized or unsupported Algorithm Identifier
+     * badMessageCheck      (1), -- integrity check failed (e.g., signature did not verify)
+     * badRequest           (2),
+     *   -- transaction not permitted or supported
+     * badTime              (3), -- messageTime was not sufficiently close to the system time, as defined by local policy
+     * badCertId            (4), -- no certificate could be found matching the provided criteria
+     * badDataFormat        (5),
+     *   -- the data submitted has the wrong format
+     * wrongAuthority       (6), -- the authority indicated in the request is different from the one creating the response token
+     * incorrectData        (7), -- the requester's data is incorrect (for notary services)
+     * missingTimeStamp     (8), -- when the timestamp is missing but should be there (by policy)
+     * badPOP               (9)  -- the proof-of-possession failed
+     * certRevoked         (10),
+     * certConfirmed       (11),
+     * wrongIntegrity      (12),
+     * badRecipientNonce   (13), 
+     * timeNotAvailable    (14),
+     *   -- the TSA's time source is not available
+     * unacceptedPolicy    (15),
+     *   -- the requested TSA policy is not supported by the TSA
+     * unacceptedExtension (16),
+     *   -- the requested extension is not supported by the TSA
+     * addInfoNotAvailable (17)
+     *   -- the additional information requested could not be understood
+     *   -- or is not available
+     * badSenderNonce      (18),
+     * badCertTemplate     (19),
+     * signerNotTrusted    (20),
+     * transactionIdInUse  (21),
+     * unsupportedVersion  (22),
+     * notAuthorized       (23),
+     * systemUnavail       (24),    
+     * systemFailure       (25),
+     *   -- the request cannot be handled due to system failure
+     * duplicateCertReq    (26) 
+     * 
+ */ + public class PkiFailureInfo + : DerBitString + { + public const int BadAlg = (1 << 7); // unrecognized or unsupported Algorithm Identifier + public const int BadMessageCheck = (1 << 6); // integrity check failed (e.g., signature did not verify) + public const int BadRequest = (1 << 5); + public const int BadTime = (1 << 4); // -- messageTime was not sufficiently close to the system time, as defined by local policy + public const int BadCertId = (1 << 3); // no certificate could be found matching the provided criteria + public const int BadDataFormat = (1 << 2); + public const int WrongAuthority = (1 << 1); // the authority indicated in the request is different from the one creating the response token + public const int IncorrectData = 1; // the requester's data is incorrect (for notary services) + public const int MissingTimeStamp = (1 << 15); // when the timestamp is missing but should be there (by policy) + public const int BadPop = (1 << 14); // the proof-of-possession failed + public const int CertRevoked = (1 << 13); + public const int CertConfirmed = (1 << 12); + public const int WrongIntegrity = (1 << 11); + public const int BadRecipientNonce = (1 << 10); + public const int TimeNotAvailable = (1 << 9); // the TSA's time source is not available + public const int UnacceptedPolicy = (1 << 8); // the requested TSA policy is not supported by the TSA + public const int UnacceptedExtension = (1 << 23); //the requested extension is not supported by the TSA + public const int AddInfoNotAvailable = (1 << 22); //the additional information requested could not be understood or is not available + public const int BadSenderNonce = (1 << 21); + public const int BadCertTemplate = (1 << 20); + public const int SignerNotTrusted = (1 << 19); + public const int TransactionIdInUse = (1 << 18); + public const int UnsupportedVersion = (1 << 17); + public const int NotAuthorized = (1 << 16); + public const int SystemUnavail = (1 << 31); + public const int SystemFailure = (1 << 30); //the request cannot be handled due to system failure + public const int DuplicateCertReq = (1 << 29); + + /** + * Basic constructor. + */ + public PkiFailureInfo(int info) + : base(info) + { + } + + public PkiFailureInfo( + DerBitString info) + : base(info.GetBytes(), info.PadBits) + { + } + + public override string ToString() + { + return "PkiFailureInfo: 0x" + this.IntValue.ToString("X"); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIFailureInfo.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIFailureInfo.cs.meta new file mode 100644 index 0000000..405315a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIFailureInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4299c5e01167c4348917457ea0a8b0e5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIFreeText.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIFreeText.cs new file mode 100644 index 0000000..fef5254 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIFreeText.cs @@ -0,0 +1,99 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cmp +{ + public class PkiFreeText + : Asn1Encodable + { + internal Asn1Sequence strings; + + public static PkiFreeText GetInstance( + Asn1TaggedObject obj, + bool isExplicit) + { + return GetInstance(Asn1Sequence.GetInstance(obj, isExplicit)); + } + + public static PkiFreeText GetInstance( + object obj) + { + if (obj is PkiFreeText) + { + return (PkiFreeText)obj; + } + else if (obj is Asn1Sequence) + { + return new PkiFreeText((Asn1Sequence)obj); + } + + throw new ArgumentException("Unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + public PkiFreeText( + Asn1Sequence seq) + { + foreach (object o in seq) + { + if (!(o is DerUtf8String)) + { + throw new ArgumentException("attempt to insert non UTF8 STRING into PkiFreeText"); + } + } + + this.strings = seq; + } + + public PkiFreeText( + DerUtf8String p) + { + strings = new DerSequence(p); + } + + /** + * Return the number of string elements present. + * + * @return number of elements present. + */ + [Obsolete("Use 'Count' property instead")] + public int Size + { + get { return strings.Count; } + } + + public int Count + { + get { return strings.Count; } + } + + /** + * Return the UTF8STRING at index. + * + * @param index index of the string of interest + * @return the string at index. + */ + public DerUtf8String this[int index] + { + get { return (DerUtf8String) strings[index]; } + } + + [Obsolete("Use 'object[index]' syntax instead")] + public DerUtf8String GetStringAt( + int index) + { + return this[index]; + } + + /** + *
+		 * PkiFreeText ::= SEQUENCE SIZE (1..MAX) OF UTF8String
+		 * 
+ */ + public override Asn1Object ToAsn1Object() + { + return strings; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIFreeText.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIFreeText.cs.meta new file mode 100644 index 0000000..5938977 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIFreeText.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e36bc5212e5cc9d45886ac8a0bddd028 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIHeader.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIHeader.cs new file mode 100644 index 0000000..7b62962 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIHeader.cs @@ -0,0 +1,228 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cmp +{ + public class PkiHeader + : Asn1Encodable + { + /** + * Value for a "null" recipient or sender. + */ + public static readonly GeneralName NULL_NAME = new GeneralName(X509Name.GetInstance(new DerSequence())); + + public static readonly int CMP_1999 = 1; + public static readonly int CMP_2000 = 2; + + private readonly DerInteger pvno; + private readonly GeneralName sender; + private readonly GeneralName recipient; + private readonly DerGeneralizedTime messageTime; + private readonly AlgorithmIdentifier protectionAlg; + private readonly Asn1OctetString senderKID; // KeyIdentifier + private readonly Asn1OctetString recipKID; // KeyIdentifier + private readonly Asn1OctetString transactionID; + private readonly Asn1OctetString senderNonce; + private readonly Asn1OctetString recipNonce; + private readonly PkiFreeText freeText; + private readonly Asn1Sequence generalInfo; + + private PkiHeader(Asn1Sequence seq) + { + pvno = DerInteger.GetInstance(seq[0]); + sender = GeneralName.GetInstance(seq[1]); + recipient = GeneralName.GetInstance(seq[2]); + + for (int pos = 3; pos < seq.Count; ++pos) + { + Asn1TaggedObject tObj = (Asn1TaggedObject)seq[pos]; + + switch (tObj.TagNo) + { + case 0: + messageTime = DerGeneralizedTime.GetInstance(tObj, true); + break; + case 1: + protectionAlg = AlgorithmIdentifier.GetInstance(tObj, true); + break; + case 2: + senderKID = Asn1OctetString.GetInstance(tObj, true); + break; + case 3: + recipKID = Asn1OctetString.GetInstance(tObj, true); + break; + case 4: + transactionID = Asn1OctetString.GetInstance(tObj, true); + break; + case 5: + senderNonce = Asn1OctetString.GetInstance(tObj, true); + break; + case 6: + recipNonce = Asn1OctetString.GetInstance(tObj, true); + break; + case 7: + freeText = PkiFreeText.GetInstance(tObj, true); + break; + case 8: + generalInfo = Asn1Sequence.GetInstance(tObj, true); + break; + default: + throw new ArgumentException("unknown tag number: " + tObj.TagNo, "seq"); + } + } + } + + public static PkiHeader GetInstance(object obj) + { + if (obj is PkiHeader) + return (PkiHeader)obj; + + if (obj is Asn1Sequence) + return new PkiHeader((Asn1Sequence)obj); + + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + } + + public PkiHeader( + int pvno, + GeneralName sender, + GeneralName recipient) + : this(new DerInteger(pvno), sender, recipient) + { + } + + private PkiHeader( + DerInteger pvno, + GeneralName sender, + GeneralName recipient) + { + this.pvno = pvno; + this.sender = sender; + this.recipient = recipient; + } + + public virtual DerInteger Pvno + { + get { return pvno; } + } + + public virtual GeneralName Sender + { + get { return sender; } + } + + public virtual GeneralName Recipient + { + get { return recipient; } + } + + public virtual DerGeneralizedTime MessageTime + { + get { return messageTime; } + } + + public virtual AlgorithmIdentifier ProtectionAlg + { + get { return protectionAlg; } + } + + public virtual Asn1OctetString SenderKID + { + get { return senderKID; } + } + + public virtual Asn1OctetString RecipKID + { + get { return recipKID; } + } + + public virtual Asn1OctetString TransactionID + { + get { return transactionID; } + } + + public virtual Asn1OctetString SenderNonce + { + get { return senderNonce; } + } + + public virtual Asn1OctetString RecipNonce + { + get { return recipNonce; } + } + + public virtual PkiFreeText FreeText + { + get { return freeText; } + } + + public virtual InfoTypeAndValue[] GetGeneralInfo() + { + if (generalInfo == null) + { + return null; + } + InfoTypeAndValue[] results = new InfoTypeAndValue[generalInfo.Count]; + for (int i = 0; i < results.Length; i++) + { + results[i] = InfoTypeAndValue.GetInstance(generalInfo[i]); + } + return results; + } + + /** + *
+         *  PkiHeader ::= SEQUENCE {
+         *            pvno                INTEGER     { cmp1999(1), cmp2000(2) },
+         *            sender              GeneralName,
+         *            -- identifies the sender
+         *            recipient           GeneralName,
+         *            -- identifies the intended recipient
+         *            messageTime     [0] GeneralizedTime         OPTIONAL,
+         *            -- time of production of this message (used when sender
+         *            -- believes that the transport will be "suitable"; i.e.,
+         *            -- that the time will still be meaningful upon receipt)
+         *            protectionAlg   [1] AlgorithmIdentifier     OPTIONAL,
+         *            -- algorithm used for calculation of protection bits
+         *            senderKID       [2] KeyIdentifier           OPTIONAL,
+         *            recipKID        [3] KeyIdentifier           OPTIONAL,
+         *            -- to identify specific keys used for protection
+         *            transactionID   [4] OCTET STRING            OPTIONAL,
+         *            -- identifies the transaction; i.e., this will be the same in
+         *            -- corresponding request, response, certConf, and PKIConf
+         *            -- messages
+         *            senderNonce     [5] OCTET STRING            OPTIONAL,
+         *            recipNonce      [6] OCTET STRING            OPTIONAL,
+         *            -- nonces used to provide replay protection, senderNonce
+         *            -- is inserted by the creator of this message; recipNonce
+         *            -- is a nonce previously inserted in a related message by
+         *            -- the intended recipient of this message
+         *            freeText        [7] PKIFreeText             OPTIONAL,
+         *            -- this may be used to indicate context-specific instructions
+         *            -- (this field is intended for human consumption)
+         *            generalInfo     [8] SEQUENCE SIZE (1..MAX) OF
+         *                                 InfoTypeAndValue     OPTIONAL
+         *            -- this may be used to convey context-specific information
+         *            -- (this field not primarily intended for human consumption)
+         * }
+         * 
+ * @return a basic ASN.1 object representation. + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(pvno, sender, recipient); + v.AddOptionalTagged(true, 0, messageTime); + v.AddOptionalTagged(true, 1, protectionAlg); + v.AddOptionalTagged(true, 2, senderKID); + v.AddOptionalTagged(true, 3, recipKID); + v.AddOptionalTagged(true, 4, transactionID); + v.AddOptionalTagged(true, 5, senderNonce); + v.AddOptionalTagged(true, 6, recipNonce); + v.AddOptionalTagged(true, 7, freeText); + v.AddOptionalTagged(true, 8, generalInfo); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIHeader.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIHeader.cs.meta new file mode 100644 index 0000000..db1d989 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIHeader.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6a4fd1a63b539754080ad05a592aa98c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIHeaderBuilder.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIHeaderBuilder.cs new file mode 100644 index 0000000..d771dda --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIHeaderBuilder.cs @@ -0,0 +1,223 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; + +namespace Org.BouncyCastle.Asn1.Cmp +{ + public class PkiHeaderBuilder + { + private DerInteger pvno; + private GeneralName sender; + private GeneralName recipient; + private DerGeneralizedTime messageTime; + private AlgorithmIdentifier protectionAlg; + private Asn1OctetString senderKID; // KeyIdentifier + private Asn1OctetString recipKID; // KeyIdentifier + private Asn1OctetString transactionID; + private Asn1OctetString senderNonce; + private Asn1OctetString recipNonce; + private PkiFreeText freeText; + private Asn1Sequence generalInfo; + + public PkiHeaderBuilder( + int pvno, + GeneralName sender, + GeneralName recipient) + : this(new DerInteger(pvno), sender, recipient) + { + } + + private PkiHeaderBuilder( + DerInteger pvno, + GeneralName sender, + GeneralName recipient) + { + this.pvno = pvno; + this.sender = sender; + this.recipient = recipient; + } + + public virtual PkiHeaderBuilder SetMessageTime(DerGeneralizedTime time) + { + messageTime = time; + return this; + } + + public virtual PkiHeaderBuilder SetProtectionAlg(AlgorithmIdentifier aid) + { + protectionAlg = aid; + return this; + } + + public virtual PkiHeaderBuilder SetSenderKID(byte[] kid) + { + return SetSenderKID(kid == null ? null : new DerOctetString(kid)); + } + + public virtual PkiHeaderBuilder SetSenderKID(Asn1OctetString kid) + { + senderKID = kid; + return this; + } + + public virtual PkiHeaderBuilder SetRecipKID(byte[] kid) + { + return SetRecipKID(kid == null ? null : new DerOctetString(kid)); + } + + public virtual PkiHeaderBuilder SetRecipKID(Asn1OctetString kid) + { + recipKID = kid; + return this; + } + + public virtual PkiHeaderBuilder SetTransactionID(byte[] tid) + { + return SetTransactionID(tid == null ? null : new DerOctetString(tid)); + } + + public virtual PkiHeaderBuilder SetTransactionID(Asn1OctetString tid) + { + transactionID = tid; + return this; + } + + public virtual PkiHeaderBuilder SetSenderNonce(byte[] nonce) + { + return SetSenderNonce(nonce == null ? null : new DerOctetString(nonce)); + } + + public virtual PkiHeaderBuilder SetSenderNonce(Asn1OctetString nonce) + { + senderNonce = nonce; + return this; + } + + public virtual PkiHeaderBuilder SetRecipNonce(byte[] nonce) + { + return SetRecipNonce(nonce == null ? null : new DerOctetString(nonce)); + } + + public virtual PkiHeaderBuilder SetRecipNonce(Asn1OctetString nonce) + { + recipNonce = nonce; + return this; + } + + public virtual PkiHeaderBuilder SetFreeText(PkiFreeText text) + { + freeText = text; + return this; + } + + public virtual PkiHeaderBuilder SetGeneralInfo(InfoTypeAndValue genInfo) + { + return SetGeneralInfo(MakeGeneralInfoSeq(genInfo)); + } + + public virtual PkiHeaderBuilder SetGeneralInfo(InfoTypeAndValue[] genInfos) + { + return SetGeneralInfo(MakeGeneralInfoSeq(genInfos)); + } + + public virtual PkiHeaderBuilder SetGeneralInfo(Asn1Sequence seqOfInfoTypeAndValue) + { + generalInfo = seqOfInfoTypeAndValue; + return this; + } + + private static Asn1Sequence MakeGeneralInfoSeq( + InfoTypeAndValue generalInfo) + { + return new DerSequence(generalInfo); + } + + private static Asn1Sequence MakeGeneralInfoSeq( + InfoTypeAndValue[] generalInfos) + { + Asn1Sequence genInfoSeq = null; + if (generalInfos != null) + { + Asn1EncodableVector v = new Asn1EncodableVector(); + for (int i = 0; i < generalInfos.Length; ++i) + { + v.Add(generalInfos[i]); + } + genInfoSeq = new DerSequence(v); + } + return genInfoSeq; + } + + /** + *
+		 *  PKIHeader ::= SEQUENCE {
+		 *            pvno                INTEGER     { cmp1999(1), cmp2000(2) },
+		 *            sender              GeneralName,
+		 *            -- identifies the sender
+		 *            recipient           GeneralName,
+		 *            -- identifies the intended recipient
+		 *            messageTime     [0] GeneralizedTime         OPTIONAL,
+		 *            -- time of production of this message (used when sender
+		 *            -- believes that the transport will be "suitable"; i.e.,
+		 *            -- that the time will still be meaningful upon receipt)
+		 *            protectionAlg   [1] AlgorithmIdentifier     OPTIONAL,
+		 *            -- algorithm used for calculation of protection bits
+		 *            senderKID       [2] KeyIdentifier           OPTIONAL,
+		 *            recipKID        [3] KeyIdentifier           OPTIONAL,
+		 *            -- to identify specific keys used for protection
+		 *            transactionID   [4] OCTET STRING            OPTIONAL,
+		 *            -- identifies the transaction; i.e., this will be the same in
+		 *            -- corresponding request, response, certConf, and PKIConf
+		 *            -- messages
+		 *            senderNonce     [5] OCTET STRING            OPTIONAL,
+		 *            recipNonce      [6] OCTET STRING            OPTIONAL,
+		 *            -- nonces used to provide replay protection, senderNonce
+		 *            -- is inserted by the creator of this message; recipNonce
+		 *            -- is a nonce previously inserted in a related message by
+		 *            -- the intended recipient of this message
+		 *            freeText        [7] PKIFreeText             OPTIONAL,
+		 *            -- this may be used to indicate context-specific instructions
+		 *            -- (this field is intended for human consumption)
+		 *            generalInfo     [8] SEQUENCE SIZE (1..MAX) OF
+		 *                                 InfoTypeAndValue     OPTIONAL
+		 *            -- this may be used to convey context-specific information
+		 *            -- (this field not primarily intended for human consumption)
+		 * }
+		 * 
+ * @return a basic ASN.1 object representation. + */ + public virtual PkiHeader Build() + { + Asn1EncodableVector v = new Asn1EncodableVector(pvno, sender, recipient); + AddOptional(v, 0, messageTime); + AddOptional(v, 1, protectionAlg); + AddOptional(v, 2, senderKID); + AddOptional(v, 3, recipKID); + AddOptional(v, 4, transactionID); + AddOptional(v, 5, senderNonce); + AddOptional(v, 6, recipNonce); + AddOptional(v, 7, freeText); + AddOptional(v, 8, generalInfo); + + messageTime = null; + protectionAlg = null; + senderKID = null; + recipKID = null; + transactionID = null; + senderNonce = null; + recipNonce = null; + freeText = null; + generalInfo = null; + + return PkiHeader.GetInstance(new DerSequence(v)); + } + + private void AddOptional(Asn1EncodableVector v, int tagNo, Asn1Encodable obj) + { + if (obj != null) + { + v.Add(new DerTaggedObject(true, tagNo, obj)); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIHeaderBuilder.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIHeaderBuilder.cs.meta new file mode 100644 index 0000000..f34ddaf --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIHeaderBuilder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 68f88df74c499de4e89c1877d5177580 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIMessage.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIMessage.cs new file mode 100644 index 0000000..c87bf21 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIMessage.cs @@ -0,0 +1,130 @@ +using System; + +namespace Org.BouncyCastle.Asn1.Cmp +{ + public class PkiMessage + : Asn1Encodable + { + private readonly PkiHeader header; + private readonly PkiBody body; + private readonly DerBitString protection; + private readonly Asn1Sequence extraCerts; + + private PkiMessage(Asn1Sequence seq) + { + header = PkiHeader.GetInstance(seq[0]); + body = PkiBody.GetInstance(seq[1]); + + for (int pos = 2; pos < seq.Count; ++pos) + { + Asn1TaggedObject tObj = (Asn1TaggedObject)seq[pos].ToAsn1Object(); + + if (tObj.TagNo == 0) + { + protection = DerBitString.GetInstance(tObj, true); + } + else + { + extraCerts = Asn1Sequence.GetInstance(tObj, true); + } + } + } + + public static PkiMessage GetInstance(object obj) + { + if (obj is PkiMessage) + return (PkiMessage)obj; + + if (obj != null) + return new PkiMessage(Asn1Sequence.GetInstance(obj)); + + return null; + } + + /** + * Creates a new PkiMessage. + * + * @param header message header + * @param body message body + * @param protection message protection (may be null) + * @param extraCerts extra certificates (may be null) + */ + public PkiMessage( + PkiHeader header, + PkiBody body, + DerBitString protection, + CmpCertificate[] extraCerts) + { + this.header = header; + this.body = body; + this.protection = protection; + if (extraCerts != null) + { + this.extraCerts = new DerSequence(extraCerts); + } + } + + public PkiMessage( + PkiHeader header, + PkiBody body, + DerBitString protection) + : this(header, body, protection, null) + { + } + + public PkiMessage( + PkiHeader header, + PkiBody body) + : this(header, body, null, null) + { + } + + public virtual PkiHeader Header + { + get { return header; } + } + + public virtual PkiBody Body + { + get { return body; } + } + + public virtual DerBitString Protection + { + get { return protection; } + } + + public virtual CmpCertificate[] GetExtraCerts() + { + if (extraCerts == null) + return null; + + CmpCertificate[] results = new CmpCertificate[extraCerts.Count]; + for (int i = 0; i < results.Length; ++i) + { + results[i] = CmpCertificate.GetInstance(extraCerts[i]); + } + return results; + } + + /** + *
+         * PkiMessage ::= SEQUENCE {
+         *                  header           PKIHeader,
+         *                  body             PKIBody,
+         *                  protection   [0] PKIProtection OPTIONAL,
+         *                  extraCerts   [1] SEQUENCE SIZE (1..MAX) OF CMPCertificate
+         *                                                                     OPTIONAL
+         * }
+         * 
+ * @return a basic ASN.1 object representation. + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(header, body); + v.AddOptionalTagged(true, 0, protection); + v.AddOptionalTagged(true, 1, extraCerts); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIMessage.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIMessage.cs.meta new file mode 100644 index 0000000..54a02c5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIMessage.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c1729165e80018d449c3a9743548d0f2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIMessages.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIMessages.cs new file mode 100644 index 0000000..eb01e54 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIMessages.cs @@ -0,0 +1,54 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cmp +{ + public class PkiMessages + : Asn1Encodable + { + private Asn1Sequence content; + + private PkiMessages(Asn1Sequence seq) + { + content = seq; + } + + public static PkiMessages GetInstance(object obj) + { + if (obj is PkiMessages) + return (PkiMessages)obj; + + if (obj is Asn1Sequence) + return new PkiMessages((Asn1Sequence)obj); + + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + } + + public PkiMessages(params PkiMessage[] msgs) + { + content = new DerSequence(msgs); + } + + public virtual PkiMessage[] ToPkiMessageArray() + { + PkiMessage[] result = new PkiMessage[content.Count]; + for (int i = 0; i != result.Length; ++i) + { + result[i] = PkiMessage.GetInstance(content[i]); + } + return result; + } + + /** + *
+         * PkiMessages ::= SEQUENCE SIZE (1..MAX) OF PkiMessage
+         * 
+ * @return a basic ASN.1 object representation. + */ + public override Asn1Object ToAsn1Object() + { + return content; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIMessages.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIMessages.cs.meta new file mode 100644 index 0000000..814c586 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIMessages.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 46febb4a24891aa40b44fbff265fe0f2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIStatus.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIStatus.cs new file mode 100644 index 0000000..ba757df --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIStatus.cs @@ -0,0 +1,63 @@ +using System; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cmp +{ + public enum PkiStatus + { + Granted = 0, + GrantedWithMods = 1, + Rejection = 2, + Waiting = 3, + RevocationWarning = 4, + RevocationNotification = 5, + KeyUpdateWarning = 6, + } + + public class PkiStatusEncodable + : Asn1Encodable + { + public static readonly PkiStatusEncodable granted = new PkiStatusEncodable(PkiStatus.Granted); + public static readonly PkiStatusEncodable grantedWithMods = new PkiStatusEncodable(PkiStatus.GrantedWithMods); + public static readonly PkiStatusEncodable rejection = new PkiStatusEncodable(PkiStatus.Rejection); + public static readonly PkiStatusEncodable waiting = new PkiStatusEncodable(PkiStatus.Waiting); + public static readonly PkiStatusEncodable revocationWarning = new PkiStatusEncodable(PkiStatus.RevocationWarning); + public static readonly PkiStatusEncodable revocationNotification = new PkiStatusEncodable(PkiStatus.RevocationNotification); + public static readonly PkiStatusEncodable keyUpdateWaiting = new PkiStatusEncodable(PkiStatus.KeyUpdateWarning); + + private readonly DerInteger status; + + private PkiStatusEncodable(PkiStatus status) + : this(new DerInteger((int)status)) + { + } + + private PkiStatusEncodable(DerInteger status) + { + this.status = status; + } + + public static PkiStatusEncodable GetInstance(object obj) + { + if (obj is PkiStatusEncodable) + return (PkiStatusEncodable)obj; + + if (obj is DerInteger) + return new PkiStatusEncodable((DerInteger)obj); + + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + } + + public virtual BigInteger Value + { + get { return status.Value; } + } + + public override Asn1Object ToAsn1Object() + { + return status; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIStatus.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIStatus.cs.meta new file mode 100644 index 0000000..1b228ca --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIStatus.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8ae8161376e11ee4285f181432aef5e6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIStatusInfo.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIStatusInfo.cs new file mode 100644 index 0000000..c9f64bf --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIStatusInfo.cs @@ -0,0 +1,156 @@ +using System; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cmp +{ + public class PkiStatusInfo + : Asn1Encodable + { + DerInteger status; + PkiFreeText statusString; + DerBitString failInfo; + + public static PkiStatusInfo GetInstance( + Asn1TaggedObject obj, + bool isExplicit) + { + return GetInstance(Asn1Sequence.GetInstance(obj, isExplicit)); + } + + public static PkiStatusInfo GetInstance( + object obj) + { + if (obj is PkiStatusInfo) + { + return (PkiStatusInfo)obj; + } + else if (obj is Asn1Sequence) + { + return new PkiStatusInfo((Asn1Sequence)obj); + } + + throw new ArgumentException("Unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + public PkiStatusInfo( + Asn1Sequence seq) + { + this.status = DerInteger.GetInstance(seq[0]); + + this.statusString = null; + this.failInfo = null; + + if (seq.Count > 2) + { + this.statusString = PkiFreeText.GetInstance(seq[1]); + this.failInfo = DerBitString.GetInstance(seq[2]); + } + else if (seq.Count > 1) + { + object obj = seq[1]; + if (obj is DerBitString) + { + this.failInfo = DerBitString.GetInstance(obj); + } + else + { + this.statusString = PkiFreeText.GetInstance(obj); + } + } + } + + /** + * @param status + */ + public PkiStatusInfo(int status) + { + this.status = new DerInteger(status); + } + + /** + * @param status + * @param statusString + */ + public PkiStatusInfo( + int status, + PkiFreeText statusString) + { + this.status = new DerInteger(status); + this.statusString = statusString; + } + + public PkiStatusInfo( + int status, + PkiFreeText statusString, + PkiFailureInfo failInfo) + { + this.status = new DerInteger(status); + this.statusString = statusString; + this.failInfo = failInfo; + } + + public BigInteger Status + { + get + { + return status.Value; + } + } + + public PkiFreeText StatusString + { + get + { + return statusString; + } + } + + public DerBitString FailInfo + { + get + { + return failInfo; + } + } + + /** + *
+		 * PkiStatusInfo ::= SEQUENCE {
+		 *     status        PKIStatus,                (INTEGER)
+		 *     statusString  PkiFreeText     OPTIONAL,
+		 *     failInfo      PkiFailureInfo  OPTIONAL  (BIT STRING)
+		 * }
+		 *
+		 * PKIStatus:
+		 *   granted                (0), -- you got exactly what you asked for
+		 *   grantedWithMods        (1), -- you got something like what you asked for
+		 *   rejection              (2), -- you don't get it, more information elsewhere in the message
+		 *   waiting                (3), -- the request body part has not yet been processed, expect to hear more later
+		 *   revocationWarning      (4), -- this message contains a warning that a revocation is imminent
+		 *   revocationNotification (5), -- notification that a revocation has occurred
+		 *   keyUpdateWarning       (6)  -- update already done for the oldCertId specified in CertReqMsg
+		 *
+		 * PkiFailureInfo:
+		 *   badAlg           (0), -- unrecognized or unsupported Algorithm Identifier
+		 *   badMessageCheck  (1), -- integrity check failed (e.g., signature did not verify)
+		 *   badRequest       (2), -- transaction not permitted or supported
+		 *   badTime          (3), -- messageTime was not sufficiently close to the system time, as defined by local policy
+		 *   badCertId        (4), -- no certificate could be found matching the provided criteria
+		 *   badDataFormat    (5), -- the data submitted has the wrong format
+		 *   wrongAuthority   (6), -- the authority indicated in the request is different from the one creating the response token
+		 *   incorrectData    (7), -- the requester's data is incorrect (for notary services)
+		 *   missingTimeStamp (8), -- when the timestamp is missing but should be there (by policy)
+		 *   badPOP           (9)  -- the proof-of-possession failed
+		 *
+		 * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(status); + v.AddOptional(statusString, failInfo); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIStatusInfo.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIStatusInfo.cs.meta new file mode 100644 index 0000000..81f04b7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PKIStatusInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2097125d0abf7a844b940e4075da2059 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PbmParameter.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PbmParameter.cs new file mode 100644 index 0000000..206b89b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PbmParameter.cs @@ -0,0 +1,101 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cmp +{ + public class PbmParameter + : Asn1Encodable + { + private Asn1OctetString salt; + private AlgorithmIdentifier owf; + private DerInteger iterationCount; + private AlgorithmIdentifier mac; + + private PbmParameter(Asn1Sequence seq) + { + salt = Asn1OctetString.GetInstance(seq[0]); + owf = AlgorithmIdentifier.GetInstance(seq[1]); + iterationCount = DerInteger.GetInstance(seq[2]); + mac = AlgorithmIdentifier.GetInstance(seq[3]); + } + + public static PbmParameter GetInstance(object obj) + { + if (obj is PbmParameter) + return (PbmParameter)obj; + + if (obj is Asn1Sequence) + return new PbmParameter((Asn1Sequence)obj); + + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + } + + public PbmParameter( + byte[] salt, + AlgorithmIdentifier owf, + int iterationCount, + AlgorithmIdentifier mac) + : this(new DerOctetString(salt), owf, new DerInteger(iterationCount), mac) + { + } + + public PbmParameter( + Asn1OctetString salt, + AlgorithmIdentifier owf, + DerInteger iterationCount, + AlgorithmIdentifier mac) + { + this.salt = salt; + this.owf = owf; + this.iterationCount = iterationCount; + this.mac = mac; + } + + public virtual Asn1OctetString Salt + { + get { return salt; } + } + + public virtual AlgorithmIdentifier Owf + { + get { return owf; } + } + + public virtual DerInteger IterationCount + { + get { return iterationCount; } + } + + public virtual AlgorithmIdentifier Mac + { + get { return mac; } + } + + /** + *
+         *  PbmParameter ::= SEQUENCE {
+         *                        salt                OCTET STRING,
+         *                        -- note:  implementations MAY wish to limit acceptable sizes
+         *                        -- of this string to values appropriate for their environment
+         *                        -- in order to reduce the risk of denial-of-service attacks
+         *                        owf                 AlgorithmIdentifier,
+         *                        -- AlgId for a One-Way Function (SHA-1 recommended)
+         *                        iterationCount      INTEGER,
+         *                        -- number of times the OWF is applied
+         *                        -- note:  implementations MAY wish to limit acceptable sizes
+         *                        -- of this integer to values appropriate for their environment
+         *                        -- in order to reduce the risk of denial-of-service attacks
+         *                        mac                 AlgorithmIdentifier
+         *                        -- the MAC AlgId (e.g., DES-MAC, Triple-DES-MAC [PKCS11],
+         *    }   -- or HMAC [RFC2104, RFC2202])
+         * 
+ * @return a basic ASN.1 object representation. + */ + public override Asn1Object ToAsn1Object() + { + return new DerSequence(salt, owf, iterationCount, mac); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PbmParameter.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PbmParameter.cs.meta new file mode 100644 index 0000000..f8ea25e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PbmParameter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 97b52a2329a02fd429940b6772f150b7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PollRepContent.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PollRepContent.cs new file mode 100644 index 0000000..ff75d7d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PollRepContent.cs @@ -0,0 +1,87 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cmp +{ + public class PollRepContent + : Asn1Encodable + { + private readonly DerInteger certReqId; + private readonly DerInteger checkAfter; + private readonly PkiFreeText reason; + + private PollRepContent(Asn1Sequence seq) + { + certReqId = DerInteger.GetInstance(seq[0]); + checkAfter = DerInteger.GetInstance(seq[1]); + + if (seq.Count > 2) + { + reason = PkiFreeText.GetInstance(seq[2]); + } + } + + public static PollRepContent GetInstance(object obj) + { + if (obj is PollRepContent) + return (PollRepContent)obj; + + if (obj is Asn1Sequence) + return new PollRepContent((Asn1Sequence)obj); + + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + } + + public PollRepContent( + DerInteger certReqId, + DerInteger checkAfter) + { + this.certReqId = certReqId; + this.checkAfter = checkAfter; + this.reason = null; + } + + public PollRepContent( + DerInteger certReqId, + DerInteger checkAfter, + PkiFreeText reason) + { + this.certReqId = certReqId; + this.checkAfter = checkAfter; + this.reason = reason; + } + + public virtual DerInteger CertReqID + { + get { return certReqId; } + } + + public virtual DerInteger CheckAfter + { + get { return checkAfter; } + } + + public virtual PkiFreeText Reason + { + get { return reason; } + } + + /** + *
+		 * PollRepContent ::= SEQUENCE OF SEQUENCE {
+		 *         certReqId              INTEGER,
+		 *         checkAfter             INTEGER,  -- time in seconds
+		 *         reason                 PKIFreeText OPTIONAL
+		 *     }
+		 * 
+ * @return a basic ASN.1 object representation. + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(certReqId, checkAfter); + v.AddOptional(reason); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PollRepContent.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PollRepContent.cs.meta new file mode 100644 index 0000000..6e73802 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PollRepContent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 36aeec80862369e458baadf6fc4a3d71 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PollReqContent.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PollReqContent.cs new file mode 100644 index 0000000..dd9b0c3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PollReqContent.cs @@ -0,0 +1,61 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cmp +{ + public class PollReqContent + : Asn1Encodable + { + private readonly Asn1Sequence content; + + private PollReqContent(Asn1Sequence seq) + { + content = seq; + } + + public static PollReqContent GetInstance(object obj) + { + if (obj is PollReqContent) + return (PollReqContent)obj; + + if (obj is Asn1Sequence) + return new PollReqContent((Asn1Sequence)obj); + + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + } + + public virtual DerInteger[][] GetCertReqIDs() + { + DerInteger[][] result = new DerInteger[content.Count][]; + for (int i = 0; i != result.Length; ++i) + { + result[i] = SequenceToDerIntegerArray((Asn1Sequence)content[i]); + } + return result; + } + + private static DerInteger[] SequenceToDerIntegerArray(Asn1Sequence seq) + { + DerInteger[] result = new DerInteger[seq.Count]; + for (int i = 0; i != result.Length; ++i) + { + result[i] = DerInteger.GetInstance(seq[i]); + } + return result; + } + + /** + *
+		 * PollReqContent ::= SEQUENCE OF SEQUENCE {
+		 *                        certReqId              INTEGER
+		 * }
+		 * 
+ * @return a basic ASN.1 object representation. + */ + public override Asn1Object ToAsn1Object() + { + return content; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PollReqContent.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PollReqContent.cs.meta new file mode 100644 index 0000000..7c1932b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PollReqContent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2cfd8127b2002c34c8b3ae51ab93e067 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PopoDecKeyChallContent.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PopoDecKeyChallContent.cs new file mode 100644 index 0000000..03a13a5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PopoDecKeyChallContent.cs @@ -0,0 +1,49 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cmp +{ + public class PopoDecKeyChallContent + : Asn1Encodable + { + private readonly Asn1Sequence content; + + private PopoDecKeyChallContent(Asn1Sequence seq) + { + content = seq; + } + + public static PopoDecKeyChallContent GetInstance(object obj) + { + if (obj is PopoDecKeyChallContent) + return (PopoDecKeyChallContent)obj; + + if (obj is Asn1Sequence) + return new PopoDecKeyChallContent((Asn1Sequence)obj); + + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + } + + public virtual Challenge[] ToChallengeArray() + { + Challenge[] result = new Challenge[content.Count]; + for (int i = 0; i != result.Length; ++i) + { + result[i] = Challenge.GetInstance(content[i]); + } + return result; + } + + /** + *
+	     * PopoDecKeyChallContent ::= SEQUENCE OF Challenge
+	     * 
+ * @return a basic ASN.1 object representation. + */ + public override Asn1Object ToAsn1Object() + { + return content; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PopoDecKeyChallContent.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PopoDecKeyChallContent.cs.meta new file mode 100644 index 0000000..7fa38f1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PopoDecKeyChallContent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 39ee76571ba390d4b9a2cebc42c29fde +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PopoDecKeyRespContent.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PopoDecKeyRespContent.cs new file mode 100644 index 0000000..73f59b7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PopoDecKeyRespContent.cs @@ -0,0 +1,49 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cmp +{ + public class PopoDecKeyRespContent + : Asn1Encodable + { + private readonly Asn1Sequence content; + + private PopoDecKeyRespContent(Asn1Sequence seq) + { + content = seq; + } + + public static PopoDecKeyRespContent GetInstance(object obj) + { + if (obj is PopoDecKeyRespContent) + return (PopoDecKeyRespContent)obj; + + if (obj is Asn1Sequence) + return new PopoDecKeyRespContent((Asn1Sequence)obj); + + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + } + + public virtual DerInteger[] ToDerIntegerArray() + { + DerInteger[] result = new DerInteger[content.Count]; + for (int i = 0; i != result.Length; ++i) + { + result[i] = DerInteger.GetInstance(content[i]); + } + return result; + } + + /** + *
+		 * PopoDecKeyRespContent ::= SEQUENCE OF INTEGER
+		 * 
+ * @return a basic ASN.1 object representation. + */ + public override Asn1Object ToAsn1Object() + { + return content; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PopoDecKeyRespContent.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PopoDecKeyRespContent.cs.meta new file mode 100644 index 0000000..24f1151 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/PopoDecKeyRespContent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f993a711a046a5d4fb8dd4438fe55178 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/ProtectedPart.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/ProtectedPart.cs new file mode 100644 index 0000000..ed90708 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/ProtectedPart.cs @@ -0,0 +1,60 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cmp +{ + public class ProtectedPart + : Asn1Encodable + { + private readonly PkiHeader header; + private readonly PkiBody body; + + private ProtectedPart(Asn1Sequence seq) + { + header = PkiHeader.GetInstance(seq[0]); + body = PkiBody.GetInstance(seq[1]); + } + + public static ProtectedPart GetInstance(object obj) + { + if (obj is ProtectedPart) + return (ProtectedPart)obj; + + if (obj is Asn1Sequence) + return new ProtectedPart((Asn1Sequence)obj); + + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + } + + public ProtectedPart(PkiHeader header, PkiBody body) + { + this.header = header; + this.body = body; + } + + public virtual PkiHeader Header + { + get { return header; } + } + + public virtual PkiBody Body + { + get { return body; } + } + + /** + *
+		 * ProtectedPart ::= SEQUENCE {
+		 *                    header    PKIHeader,
+		 *                    body      PKIBody
+		 * }
+		 * 
+ * @return a basic ASN.1 object representation. + */ + public override Asn1Object ToAsn1Object() + { + return new DerSequence(header, body); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/ProtectedPart.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/ProtectedPart.cs.meta new file mode 100644 index 0000000..8157881 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/ProtectedPart.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6ac17f43b5644b143b0a9373211022ff +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/RevAnnContent.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/RevAnnContent.cs new file mode 100644 index 0000000..d5d4262 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/RevAnnContent.cs @@ -0,0 +1,87 @@ +using System; + +using Org.BouncyCastle.Asn1.Crmf; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cmp +{ + public class RevAnnContent + : Asn1Encodable + { + private readonly PkiStatusEncodable status; + private readonly CertId certId; + private readonly DerGeneralizedTime willBeRevokedAt; + private readonly DerGeneralizedTime badSinceDate; + private readonly X509Extensions crlDetails; + + private RevAnnContent(Asn1Sequence seq) + { + status = PkiStatusEncodable.GetInstance(seq[0]); + certId = CertId.GetInstance(seq[1]); + willBeRevokedAt = DerGeneralizedTime.GetInstance(seq[2]); + badSinceDate = DerGeneralizedTime.GetInstance(seq[3]); + + if (seq.Count > 4) + { + crlDetails = X509Extensions.GetInstance(seq[4]); + } + } + + public static RevAnnContent GetInstance(object obj) + { + if (obj is RevAnnContent) + return (RevAnnContent)obj; + + if (obj is Asn1Sequence) + return new RevAnnContent((Asn1Sequence)obj); + + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + } + + public virtual PkiStatusEncodable Status + { + get { return status; } + } + + public virtual CertId CertID + { + get { return certId; } + } + + public virtual DerGeneralizedTime WillBeRevokedAt + { + get { return willBeRevokedAt; } + } + + public virtual DerGeneralizedTime BadSinceDate + { + get { return badSinceDate; } + } + + public virtual X509Extensions CrlDetails + { + get { return crlDetails; } + } + + /** + *
+		 * RevAnnContent ::= SEQUENCE {
+		 *       status              PKIStatus,
+		 *       certId              CertId,
+		 *       willBeRevokedAt     GeneralizedTime,
+		 *       badSinceDate        GeneralizedTime,
+		 *       crlDetails          Extensions  OPTIONAL
+		 *        -- extra CRL details (e.g., crl number, reason, location, etc.)
+		 * }
+		 * 
+ * @return a basic ASN.1 object representation. + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(status, certId, willBeRevokedAt, badSinceDate); + v.AddOptional(crlDetails); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/RevAnnContent.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/RevAnnContent.cs.meta new file mode 100644 index 0000000..2e7f6cb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/RevAnnContent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7454987d91dc6104bb0d78b8db8ab950 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/RevDetails.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/RevDetails.cs new file mode 100644 index 0000000..7d2a65a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/RevDetails.cs @@ -0,0 +1,75 @@ +using System; + +using Org.BouncyCastle.Asn1.Crmf; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cmp +{ + public class RevDetails + : Asn1Encodable + { + private readonly CertTemplate certDetails; + private readonly X509Extensions crlEntryDetails; + + private RevDetails(Asn1Sequence seq) + { + certDetails = CertTemplate.GetInstance(seq[0]); + crlEntryDetails = seq.Count <= 1 + ? null + : X509Extensions.GetInstance(seq[1]); + } + + public static RevDetails GetInstance(object obj) + { + if (obj is RevDetails) + return (RevDetails)obj; + + if (obj is Asn1Sequence) + return new RevDetails((Asn1Sequence)obj); + + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + } + + public RevDetails(CertTemplate certDetails) + : this(certDetails, null) + { + } + + public RevDetails(CertTemplate certDetails, X509Extensions crlEntryDetails) + { + this.certDetails = certDetails; + this.crlEntryDetails = crlEntryDetails; + } + + public virtual CertTemplate CertDetails + { + get { return certDetails; } + } + + public virtual X509Extensions CrlEntryDetails + { + get { return crlEntryDetails; } + } + + /** + *
+		* RevDetails ::= SEQUENCE {
+		*                  certDetails         CertTemplate,
+		*                   -- allows requester to specify as much as they can about
+		*                   -- the cert. for which revocation is requested
+		*                   -- (e.g., for cases in which serialNumber is not available)
+		*                   crlEntryDetails     Extensions       OPTIONAL
+		*                   -- requested crlEntryExtensions
+		*             }
+		* 
+ * @return a basic ASN.1 object representation. + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(certDetails); + v.AddOptional(crlEntryDetails); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/RevDetails.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/RevDetails.cs.meta new file mode 100644 index 0000000..d915daf --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/RevDetails.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d420b9e694e8719438e60ce16fc8e2e3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/RevRepContent.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/RevRepContent.cs new file mode 100644 index 0000000..4b3f82b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/RevRepContent.cs @@ -0,0 +1,104 @@ +using System; + +using Org.BouncyCastle.Asn1.Crmf; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cmp +{ + public class RevRepContent + : Asn1Encodable + { + private readonly Asn1Sequence status; + private readonly Asn1Sequence revCerts; + private readonly Asn1Sequence crls; + + private RevRepContent(Asn1Sequence seq) + { + status = Asn1Sequence.GetInstance(seq[0]); + + for (int pos = 1; pos < seq.Count; ++pos) + { + Asn1TaggedObject tObj = Asn1TaggedObject.GetInstance(seq[pos]); + + if (tObj.TagNo == 0) + { + revCerts = Asn1Sequence.GetInstance(tObj, true); + } + else + { + crls = Asn1Sequence.GetInstance(tObj, true); + } + } + } + + public static RevRepContent GetInstance(object obj) + { + if (obj is RevRepContent) + return (RevRepContent)obj; + + if (obj is Asn1Sequence) + return new RevRepContent((Asn1Sequence)obj); + + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + } + + public virtual PkiStatusInfo[] GetStatus() + { + PkiStatusInfo[] results = new PkiStatusInfo[status.Count]; + for (int i = 0; i != results.Length; ++i) + { + results[i] = PkiStatusInfo.GetInstance(status[i]); + } + return results; + } + + public virtual CertId[] GetRevCerts() + { + if (revCerts == null) + return null; + + CertId[] results = new CertId[revCerts.Count]; + for (int i = 0; i != results.Length; ++i) + { + results[i] = CertId.GetInstance(revCerts[i]); + } + return results; + } + + public virtual CertificateList[] GetCrls() + { + if (crls == null) + return null; + + CertificateList[] results = new CertificateList[crls.Count]; + for (int i = 0; i != results.Length; ++i) + { + results[i] = CertificateList.GetInstance(crls[i]); + } + return results; + } + + /** + *
+		 * RevRepContent ::= SEQUENCE {
+		 *        status       SEQUENCE SIZE (1..MAX) OF PKIStatusInfo,
+		 *        -- in same order as was sent in RevReqContent
+		 *        revCerts [0] SEQUENCE SIZE (1..MAX) OF CertId OPTIONAL,
+		 *        -- IDs for which revocation was requested
+		 *        -- (same order as status)
+		 *        crls     [1] SEQUENCE SIZE (1..MAX) OF CertificateList OPTIONAL
+		 *        -- the resulting CRLs (there may be more than one)
+		 *   }
+		 * 
+ * @return a basic ASN.1 object representation. + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(status); + v.AddOptionalTagged(true, 0, revCerts); + v.AddOptionalTagged(true, 1, crls); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/RevRepContent.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/RevRepContent.cs.meta new file mode 100644 index 0000000..f2e6b1f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/RevRepContent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4758a06b7333f9e4babd65020dd4ea58 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/RevRepContentBuilder.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/RevRepContentBuilder.cs new file mode 100644 index 0000000..cc17d1d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/RevRepContentBuilder.cs @@ -0,0 +1,55 @@ +using System; + +using Org.BouncyCastle.Asn1.Crmf; +using Org.BouncyCastle.Asn1.X509; + +namespace Org.BouncyCastle.Asn1.Cmp +{ + public class RevRepContentBuilder + { + private readonly Asn1EncodableVector status = new Asn1EncodableVector(); + private readonly Asn1EncodableVector revCerts = new Asn1EncodableVector(); + private readonly Asn1EncodableVector crls = new Asn1EncodableVector(); + + public virtual RevRepContentBuilder Add(PkiStatusInfo status) + { + this.status.Add(status); + return this; + } + + public virtual RevRepContentBuilder Add(PkiStatusInfo status, CertId certId) + { + if (this.status.Count != this.revCerts.Count) + throw new InvalidOperationException("status and revCerts sequence must be in common order"); + + this.status.Add(status); + this.revCerts.Add(certId); + return this; + } + + public virtual RevRepContentBuilder AddCrl(CertificateList crl) + { + this.crls.Add(crl); + return this; + } + + public virtual RevRepContent Build() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + + v.Add(new DerSequence(status)); + + if (revCerts.Count != 0) + { + v.Add(new DerTaggedObject(true, 0, new DerSequence(revCerts))); + } + + if (crls.Count != 0) + { + v.Add(new DerTaggedObject(true, 1, new DerSequence(crls))); + } + + return RevRepContent.GetInstance(new DerSequence(v)); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/RevRepContentBuilder.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/RevRepContentBuilder.cs.meta new file mode 100644 index 0000000..752a139 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/RevRepContentBuilder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c5f6a624b639bd94dbd30d46539a3fc4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/RevReqContent.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/RevReqContent.cs new file mode 100644 index 0000000..1522d37 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/RevReqContent.cs @@ -0,0 +1,54 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cmp +{ + public class RevReqContent + : Asn1Encodable + { + private readonly Asn1Sequence content; + + private RevReqContent(Asn1Sequence seq) + { + content = seq; + } + + public static RevReqContent GetInstance(object obj) + { + if (obj is RevReqContent) + return (RevReqContent)obj; + + if (obj is Asn1Sequence) + return new RevReqContent((Asn1Sequence)obj); + + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + } + + public RevReqContent(params RevDetails[] revDetails) + { + this.content = new DerSequence(revDetails); + } + + public virtual RevDetails[] ToRevDetailsArray() + { + RevDetails[] result = new RevDetails[content.Count]; + for (int i = 0; i != result.Length; ++i) + { + result[i] = RevDetails.GetInstance(content[i]); + } + return result; + } + + /** + *
+		 * RevReqContent ::= SEQUENCE OF RevDetails
+		 * 
+ * @return a basic ASN.1 object representation. + */ + public override Asn1Object ToAsn1Object() + { + return content; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/RevReqContent.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/RevReqContent.cs.meta new file mode 100644 index 0000000..23f9777 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cmp/RevReqContent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b05b60fc1c39efc4cbae10aef69fd06a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms.meta new file mode 100644 index 0000000..de09ae1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4bcc37a92dd23fd448747e829bdf8eca +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/Attribute.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/Attribute.cs new file mode 100644 index 0000000..69ac441 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/Attribute.cs @@ -0,0 +1,70 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cms +{ + public class Attribute + : Asn1Encodable + { + private DerObjectIdentifier attrType; + private Asn1Set attrValues; + + /** + * return an Attribute object from the given object. + * + * @param o the object we want converted. + * @exception ArgumentException if the object cannot be converted. + */ + public static Attribute GetInstance( + object obj) + { + if (obj == null || obj is Attribute) + return (Attribute) obj; + + if (obj is Asn1Sequence) + return new Attribute((Asn1Sequence) obj); + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + public Attribute( + Asn1Sequence seq) + { + attrType = (DerObjectIdentifier)seq[0]; + attrValues = (Asn1Set)seq[1]; + } + + public Attribute( + DerObjectIdentifier attrType, + Asn1Set attrValues) + { + this.attrType = attrType; + this.attrValues = attrValues; + } + + public DerObjectIdentifier AttrType + { + get { return attrType; } + } + + public Asn1Set AttrValues + { + get { return attrValues; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+        * Attribute ::= SEQUENCE {
+        *     attrType OBJECT IDENTIFIER,
+        *     attrValues SET OF AttributeValue
+        * }
+        * 
+ */ + public override Asn1Object ToAsn1Object() + { + return new DerSequence(attrType, attrValues); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/Attribute.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/Attribute.cs.meta new file mode 100644 index 0000000..42ee2e7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/Attribute.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: de4b4354c27103a48a0ec81bdcce5584 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/AttributeTable.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/AttributeTable.cs new file mode 100644 index 0000000..8d357f1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/AttributeTable.cs @@ -0,0 +1,231 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cms +{ + public class AttributeTable + { + private readonly IDictionary attributes; + +#if !(SILVERLIGHT || PORTABLE) + [Obsolete] + public AttributeTable( + Hashtable attrs) + { + this.attributes = Platform.CreateHashtable(attrs); + } +#endif + + public AttributeTable( + IDictionary attrs) + { + this.attributes = Platform.CreateHashtable(attrs); + } + + public AttributeTable( + Asn1EncodableVector v) + { + this.attributes = Platform.CreateHashtable(v.Count); + + foreach (Asn1Encodable o in v) + { + Attribute a = Attribute.GetInstance(o); + + AddAttribute(a); + } + } + + public AttributeTable( + Asn1Set s) + { + this.attributes = Platform.CreateHashtable(s.Count); + + for (int i = 0; i != s.Count; i++) + { + Attribute a = Attribute.GetInstance(s[i]); + + AddAttribute(a); + } + } + + public AttributeTable( + Attributes attrs) + : this(Asn1Set.GetInstance(attrs.ToAsn1Object())) + { + } + + private void AddAttribute( + Attribute a) + { + DerObjectIdentifier oid = a.AttrType; + object obj = attributes[oid]; + + if (obj == null) + { + attributes[oid] = a; + } + else + { + IList v; + + if (obj is Attribute) + { + v = Platform.CreateArrayList(); + + v.Add(obj); + v.Add(a); + } + else + { + v = (IList) obj; + + v.Add(a); + } + + attributes[oid] = v; + } + } + + /// Return the first attribute matching the given OBJECT IDENTIFIER + public Attribute this[DerObjectIdentifier oid] + { + get + { + object obj = attributes[oid]; + + if (obj is IList) + { + return (Attribute)((IList)obj)[0]; + } + + return (Attribute) obj; + } + } + + [Obsolete("Use 'object[oid]' syntax instead")] + public Attribute Get( + DerObjectIdentifier oid) + { + return this[oid]; + } + + /** + * Return all the attributes matching the OBJECT IDENTIFIER oid. The vector will be + * empty if there are no attributes of the required type present. + * + * @param oid type of attribute required. + * @return a vector of all the attributes found of type oid. + */ + public Asn1EncodableVector GetAll( + DerObjectIdentifier oid) + { + Asn1EncodableVector v = new Asn1EncodableVector(); + + object obj = attributes[oid]; + + if (obj is IList) + { + foreach (Attribute a in (IList)obj) + { + v.Add(a); + } + } + else if (obj != null) + { + v.Add((Attribute) obj); + } + + return v; + } + + public int Count + { + get + { + int total = 0; + + foreach (object o in attributes.Values) + { + if (o is IList) + { + total += ((IList)o).Count; + } + else + { + ++total; + } + } + + return total; + } + } + + public IDictionary ToDictionary() + { + return Platform.CreateHashtable(attributes); + } + +#if !(SILVERLIGHT || PORTABLE) + [Obsolete("Use 'ToDictionary' instead")] + public Hashtable ToHashtable() + { + return new Hashtable(attributes); + } +#endif + + public Asn1EncodableVector ToAsn1EncodableVector() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + + foreach (object obj in attributes.Values) + { + if (obj is IList) + { + foreach (object el in (IList)obj) + { + v.Add(Attribute.GetInstance(el)); + } + } + else + { + v.Add(Attribute.GetInstance(obj)); + } + } + + return v; + } + + public Attributes ToAttributes() + { + return new Attributes(this.ToAsn1EncodableVector()); + } + + /** + * Return a new table with the passed in attribute added. + * + * @param attrType + * @param attrValue + * @return + */ + public AttributeTable Add(DerObjectIdentifier attrType, Asn1Encodable attrValue) + { + AttributeTable newTable = new AttributeTable(attributes); + + newTable.AddAttribute(new Attribute(attrType, new DerSet(attrValue))); + + return newTable; + } + + public AttributeTable Remove(DerObjectIdentifier attrType) + { + AttributeTable newTable = new AttributeTable(attributes); + + newTable.attributes.Remove(attrType); + + return newTable; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/AttributeTable.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/AttributeTable.cs.meta new file mode 100644 index 0000000..b16d5d0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/AttributeTable.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bebe497a64b44034e9ea479784dc8d28 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/Attributes.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/Attributes.cs new file mode 100644 index 0000000..5b6b130 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/Attributes.cs @@ -0,0 +1,55 @@ +using System; + +namespace Org.BouncyCastle.Asn1.Cms +{ + public class Attributes + : Asn1Encodable + { + private readonly Asn1Set attributes; + + private Attributes(Asn1Set attributes) + { + this.attributes = attributes; + } + + public Attributes(Asn1EncodableVector v) + { + attributes = new BerSet(v); + } + + public static Attributes GetInstance(object obj) + { + if (obj is Attributes) + return (Attributes)obj; + + if (obj != null) + return new Attributes(Asn1Set.GetInstance(obj)); + + return null; + } + + public virtual Attribute[] GetAttributes() + { + Attribute[] rv = new Attribute[attributes.Count]; + + for (int i = 0; i != rv.Length; i++) + { + rv[i] = Attribute.GetInstance(attributes[i]); + } + + return rv; + } + + /** + *
+         * Attributes ::=
+         *   SET SIZE(1..MAX) OF Attribute -- according to RFC 5652
+         * 
+ * @return + */ + public override Asn1Object ToAsn1Object() + { + return attributes; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/Attributes.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/Attributes.cs.meta new file mode 100644 index 0000000..0be0f6a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/Attributes.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bfac666f3da56af4b907bafd4ece3fba +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/AuthEnvelopedData.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/AuthEnvelopedData.cs new file mode 100644 index 0000000..4ca86e9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/AuthEnvelopedData.cs @@ -0,0 +1,205 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cms +{ + public class AuthEnvelopedData + : Asn1Encodable + { + private DerInteger version; + private OriginatorInfo originatorInfo; + private Asn1Set recipientInfos; + private EncryptedContentInfo authEncryptedContentInfo; + private Asn1Set authAttrs; + private Asn1OctetString mac; + private Asn1Set unauthAttrs; + + public AuthEnvelopedData( + OriginatorInfo originatorInfo, + Asn1Set recipientInfos, + EncryptedContentInfo authEncryptedContentInfo, + Asn1Set authAttrs, + Asn1OctetString mac, + Asn1Set unauthAttrs) + { + // "It MUST be set to 0." + this.version = new DerInteger(0); + + this.originatorInfo = originatorInfo; + + // "There MUST be at least one element in the collection." + this.recipientInfos = recipientInfos; + if (this.recipientInfos.Count < 1) + throw new ArgumentException("AuthEnvelopedData requires at least 1 RecipientInfo"); + + this.authEncryptedContentInfo = authEncryptedContentInfo; + + // "The authAttrs MUST be present if the content type carried in + // EncryptedContentInfo is not id-data." + this.authAttrs = authAttrs; + if (!authEncryptedContentInfo.ContentType.Equals(CmsObjectIdentifiers.Data)) + { + if (authAttrs == null || authAttrs.Count < 1) + throw new ArgumentException("authAttrs must be present with non-data content"); + } + + this.mac = mac; + + this.unauthAttrs = unauthAttrs; + } + + private AuthEnvelopedData( + Asn1Sequence seq) + { + int index = 0; + + // "It MUST be set to 0." + Asn1Object tmp = seq[index++].ToAsn1Object(); + version = DerInteger.GetInstance(tmp); + if (!version.HasValue(0)) + throw new ArgumentException("AuthEnvelopedData version number must be 0"); + + tmp = seq[index++].ToAsn1Object(); + if (tmp is Asn1TaggedObject) + { + originatorInfo = OriginatorInfo.GetInstance((Asn1TaggedObject)tmp, false); + tmp = seq[index++].ToAsn1Object(); + } + + // "There MUST be at least one element in the collection." + recipientInfos = Asn1Set.GetInstance(tmp); + if (recipientInfos.Count < 1) + throw new ArgumentException("AuthEnvelopedData requires at least 1 RecipientInfo"); + + tmp = seq[index++].ToAsn1Object(); + authEncryptedContentInfo = EncryptedContentInfo.GetInstance(tmp); + + tmp = seq[index++].ToAsn1Object(); + if (tmp is Asn1TaggedObject) + { + authAttrs = Asn1Set.GetInstance((Asn1TaggedObject)tmp, false); + tmp = seq[index++].ToAsn1Object(); + } + else + { + // "The authAttrs MUST be present if the content type carried in + // EncryptedContentInfo is not id-data." + if (!authEncryptedContentInfo.ContentType.Equals(CmsObjectIdentifiers.Data)) + { + if (authAttrs == null || authAttrs.Count < 1) + throw new ArgumentException("authAttrs must be present with non-data content"); + } + } + + mac = Asn1OctetString.GetInstance(tmp); + + if (seq.Count > index) + { + tmp = seq[index++].ToAsn1Object(); + unauthAttrs = Asn1Set.GetInstance((Asn1TaggedObject)tmp, false); + } + } + + /** + * return an AuthEnvelopedData object from a tagged object. + * + * @param obj the tagged object holding the object we want. + * @param isExplicit true if the object is meant to be explicitly + * tagged false otherwise. + * @throws ArgumentException if the object held by the + * tagged object cannot be converted. + */ + public static AuthEnvelopedData GetInstance( + Asn1TaggedObject obj, + bool isExplicit) + { + return GetInstance(Asn1Sequence.GetInstance(obj, isExplicit)); + } + + /** + * return an AuthEnvelopedData object from the given object. + * + * @param obj the object we want converted. + * @throws ArgumentException if the object cannot be converted. + */ + public static AuthEnvelopedData GetInstance( + object obj) + { + if (obj == null || obj is AuthEnvelopedData) + return (AuthEnvelopedData)obj; + + if (obj is Asn1Sequence) + return new AuthEnvelopedData((Asn1Sequence)obj); + + throw new ArgumentException("Invalid AuthEnvelopedData: " + Platform.GetTypeName(obj)); + } + + public DerInteger Version + { + get { return version; } + } + + public OriginatorInfo OriginatorInfo + { + get { return originatorInfo; } + } + + public Asn1Set RecipientInfos + { + get { return recipientInfos; } + } + + public EncryptedContentInfo AuthEncryptedContentInfo + { + get { return authEncryptedContentInfo; } + } + + public Asn1Set AuthAttrs + { + get { return authAttrs; } + } + + public Asn1OctetString Mac + { + get { return mac; } + } + + public Asn1Set UnauthAttrs + { + get { return unauthAttrs; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+		 * AuthEnvelopedData ::= SEQUENCE {
+		 *   version CMSVersion,
+		 *   originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL,
+		 *   recipientInfos RecipientInfos,
+		 *   authEncryptedContentInfo EncryptedContentInfo,
+		 *   authAttrs [1] IMPLICIT AuthAttributes OPTIONAL,
+		 *   mac MessageAuthenticationCode,
+		 *   unauthAttrs [2] IMPLICIT UnauthAttributes OPTIONAL }
+		 * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(version); + v.AddOptionalTagged(false, 0, originatorInfo); + v.Add(recipientInfos, authEncryptedContentInfo); + + // "authAttrs optionally contains the authenticated attributes." + // "AuthAttributes MUST be DER encoded, even if the rest of the + // AuthEnvelopedData structure is BER encoded." + v.AddOptionalTagged(false, 1, authAttrs); + + v.Add(mac); + + // "unauthAttrs optionally contains the unauthenticated attributes." + v.AddOptionalTagged(false, 2, unauthAttrs); + + return new BerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/AuthEnvelopedData.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/AuthEnvelopedData.cs.meta new file mode 100644 index 0000000..56092b7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/AuthEnvelopedData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 28afca6fa5054a34fbe98fbec6e1bfde +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/AuthEnvelopedDataParser.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/AuthEnvelopedDataParser.cs new file mode 100644 index 0000000..1e1e72c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/AuthEnvelopedDataParser.cs @@ -0,0 +1,150 @@ +using System; + +namespace Org.BouncyCastle.Asn1.Cms +{ + /** + * Produce an object suitable for an Asn1OutputStream. + * + *
+	 * AuthEnvelopedData ::= SEQUENCE {
+	 *   version CMSVersion,
+	 *   originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL,
+	 *   recipientInfos RecipientInfos,
+	 *   authEncryptedContentInfo EncryptedContentInfo,
+	 *   authAttrs [1] IMPLICIT AuthAttributes OPTIONAL,
+	 *   mac MessageAuthenticationCode,
+	 *   unauthAttrs [2] IMPLICIT UnauthAttributes OPTIONAL }
+	 * 
+ */ + public class AuthEnvelopedDataParser + { + private Asn1SequenceParser seq; + private DerInteger version; + private IAsn1Convertible nextObject; + private bool originatorInfoCalled; + private bool isData; + + public AuthEnvelopedDataParser( + Asn1SequenceParser seq) + { + this.seq = seq; + + // "It MUST be set to 0." + this.version = (DerInteger)seq.ReadObject(); + if (!version.HasValue(0)) + throw new Asn1ParsingException("AuthEnvelopedData version number must be 0"); + } + + public DerInteger Version + { + get { return version; } + } + + public OriginatorInfo GetOriginatorInfo() + { + originatorInfoCalled = true; + + if (nextObject == null) + { + nextObject = seq.ReadObject(); + } + + if (nextObject is Asn1TaggedObjectParser && ((Asn1TaggedObjectParser)nextObject).TagNo == 0) + { + Asn1SequenceParser originatorInfo = (Asn1SequenceParser) ((Asn1TaggedObjectParser)nextObject).GetObjectParser(Asn1Tags.Sequence, false); + nextObject = null; + return OriginatorInfo.GetInstance(originatorInfo.ToAsn1Object()); + } + + return null; + } + + public Asn1SetParser GetRecipientInfos() + { + if (!originatorInfoCalled) + { + GetOriginatorInfo(); + } + + if (nextObject == null) + { + nextObject = seq.ReadObject(); + } + + Asn1SetParser recipientInfos = (Asn1SetParser)nextObject; + nextObject = null; + return recipientInfos; + } + + public EncryptedContentInfoParser GetAuthEncryptedContentInfo() + { + if (nextObject == null) + { + nextObject = seq.ReadObject(); + } + + if (nextObject != null) + { + Asn1SequenceParser o = (Asn1SequenceParser) nextObject; + nextObject = null; + EncryptedContentInfoParser encryptedContentInfoParser = new EncryptedContentInfoParser(o); + isData = CmsObjectIdentifiers.Data.Equals(encryptedContentInfoParser.ContentType); + return encryptedContentInfoParser; + } + + return null; + } + + public Asn1SetParser GetAuthAttrs() + { + if (nextObject == null) + { + nextObject = seq.ReadObject(); + } + + if (nextObject is Asn1TaggedObjectParser) + { + IAsn1Convertible o = nextObject; + nextObject = null; + return (Asn1SetParser)((Asn1TaggedObjectParser)o).GetObjectParser(Asn1Tags.Set, false); + } + + // "The authAttrs MUST be present if the content type carried in + // EncryptedContentInfo is not id-data." + if (!isData) + throw new Asn1ParsingException("authAttrs must be present with non-data content"); + + return null; + } + + public Asn1OctetString GetMac() + { + if (nextObject == null) + { + nextObject = seq.ReadObject(); + } + + IAsn1Convertible o = nextObject; + nextObject = null; + + return Asn1OctetString.GetInstance(o.ToAsn1Object()); + } + + public Asn1SetParser GetUnauthAttrs() + { + if (nextObject == null) + { + nextObject = seq.ReadObject(); + } + + if (nextObject != null) + { + IAsn1Convertible o = nextObject; + nextObject = null; + return (Asn1SetParser)((Asn1TaggedObjectParser)o).GetObjectParser(Asn1Tags.Set, false); + } + + return null; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/AuthEnvelopedDataParser.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/AuthEnvelopedDataParser.cs.meta new file mode 100644 index 0000000..a3ed994 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/AuthEnvelopedDataParser.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 379f2b25458604a468060065d6977357 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/AuthenticatedData.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/AuthenticatedData.cs new file mode 100644 index 0000000..eb9f820 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/AuthenticatedData.cs @@ -0,0 +1,251 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cms +{ + public class AuthenticatedData + : Asn1Encodable + { + private DerInteger version; + private OriginatorInfo originatorInfo; + private Asn1Set recipientInfos; + private AlgorithmIdentifier macAlgorithm; + private AlgorithmIdentifier digestAlgorithm; + private ContentInfo encapsulatedContentInfo; + private Asn1Set authAttrs; + private Asn1OctetString mac; + private Asn1Set unauthAttrs; + + public AuthenticatedData( + OriginatorInfo originatorInfo, + Asn1Set recipientInfos, + AlgorithmIdentifier macAlgorithm, + AlgorithmIdentifier digestAlgorithm, + ContentInfo encapsulatedContent, + Asn1Set authAttrs, + Asn1OctetString mac, + Asn1Set unauthAttrs) + { + if (digestAlgorithm != null || authAttrs != null) + { + if (digestAlgorithm == null || authAttrs == null) + { + throw new ArgumentException("digestAlgorithm and authAttrs must be set together"); + } + } + + version = new DerInteger(CalculateVersion(originatorInfo)); + + this.originatorInfo = originatorInfo; + this.macAlgorithm = macAlgorithm; + this.digestAlgorithm = digestAlgorithm; + this.recipientInfos = recipientInfos; + this.encapsulatedContentInfo = encapsulatedContent; + this.authAttrs = authAttrs; + this.mac = mac; + this.unauthAttrs = unauthAttrs; + } + + private AuthenticatedData( + Asn1Sequence seq) + { + int index = 0; + + version = (DerInteger)seq[index++]; + + Asn1Encodable tmp = seq[index++]; + if (tmp is Asn1TaggedObject) + { + originatorInfo = OriginatorInfo.GetInstance((Asn1TaggedObject)tmp, false); + tmp = seq[index++]; + } + + recipientInfos = Asn1Set.GetInstance(tmp); + macAlgorithm = AlgorithmIdentifier.GetInstance(seq[index++]); + + tmp = seq[index++]; + if (tmp is Asn1TaggedObject) + { + digestAlgorithm = AlgorithmIdentifier.GetInstance((Asn1TaggedObject)tmp, false); + tmp = seq[index++]; + } + + encapsulatedContentInfo = ContentInfo.GetInstance(tmp); + + tmp = seq[index++]; + if (tmp is Asn1TaggedObject) + { + authAttrs = Asn1Set.GetInstance((Asn1TaggedObject)tmp, false); + tmp = seq[index++]; + } + + mac = Asn1OctetString.GetInstance(tmp); + + if (seq.Count > index) + { + unauthAttrs = Asn1Set.GetInstance((Asn1TaggedObject)seq[index], false); + } + } + + /** + * return an AuthenticatedData object from a tagged object. + * + * @param obj the tagged object holding the object we want. + * @param isExplicit true if the object is meant to be explicitly + * tagged false otherwise. + * @throws ArgumentException if the object held by the + * tagged object cannot be converted. + */ + public static AuthenticatedData GetInstance( + Asn1TaggedObject obj, + bool isExplicit) + { + return GetInstance(Asn1Sequence.GetInstance(obj, isExplicit)); + } + + /** + * return an AuthenticatedData object from the given object. + * + * @param obj the object we want converted. + * @throws ArgumentException if the object cannot be converted. + */ + public static AuthenticatedData GetInstance( + object obj) + { + if (obj == null || obj is AuthenticatedData) + { + return (AuthenticatedData)obj; + } + + if (obj is Asn1Sequence) + { + return new AuthenticatedData((Asn1Sequence)obj); + } + + throw new ArgumentException("Invalid AuthenticatedData: " + Platform.GetTypeName(obj)); + } + + public DerInteger Version + { + get { return version; } + } + + public OriginatorInfo OriginatorInfo + { + get { return originatorInfo; } + } + + public Asn1Set RecipientInfos + { + get { return recipientInfos; } + } + + public AlgorithmIdentifier MacAlgorithm + { + get { return macAlgorithm; } + } + + public AlgorithmIdentifier DigestAlgorithm + { + get { return digestAlgorithm; } + } + + public ContentInfo EncapsulatedContentInfo + { + get { return encapsulatedContentInfo; } + } + + public Asn1Set AuthAttrs + { + get { return authAttrs; } + } + + public Asn1OctetString Mac + { + get { return mac; } + } + + public Asn1Set UnauthAttrs + { + get { return unauthAttrs; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+		 * AuthenticatedData ::= SEQUENCE {
+		 *       version CMSVersion,
+		 *       originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL,
+		 *       recipientInfos RecipientInfos,
+		 *       macAlgorithm MessageAuthenticationCodeAlgorithm,
+		 *       digestAlgorithm [1] DigestAlgorithmIdentifier OPTIONAL,
+		 *       encapContentInfo EncapsulatedContentInfo,
+		 *       authAttrs [2] IMPLICIT AuthAttributes OPTIONAL,
+		 *       mac MessageAuthenticationCode,
+		 *       unauthAttrs [3] IMPLICIT UnauthAttributes OPTIONAL }
+		 *
+		 * AuthAttributes ::= SET SIZE (1..MAX) OF Attribute
+		 *
+		 * UnauthAttributes ::= SET SIZE (1..MAX) OF Attribute
+		 *
+		 * MessageAuthenticationCode ::= OCTET STRING
+		 * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(version); + v.AddOptionalTagged(false, 0, originatorInfo); + v.Add(recipientInfos, macAlgorithm); + v.AddOptionalTagged(false, 1, digestAlgorithm); + v.Add(encapsulatedContentInfo); + v.AddOptionalTagged(false, 2, authAttrs); + v.Add(mac); + v.AddOptionalTagged(false, 3, unauthAttrs); + return new BerSequence(v); + } + + public static int CalculateVersion(OriginatorInfo origInfo) + { + if (origInfo == null) + return 0; + + int ver = 0; + + foreach (object obj in origInfo.Certificates) + { + if (obj is Asn1TaggedObject) + { + Asn1TaggedObject tag = (Asn1TaggedObject)obj; + + if (tag.TagNo == 2) + { + ver = 1; + } + else if (tag.TagNo == 3) + { + ver = 3; + break; + } + } + } + + foreach (object obj in origInfo.Crls) + { + if (obj is Asn1TaggedObject) + { + Asn1TaggedObject tag = (Asn1TaggedObject)obj; + + if (tag.TagNo == 1) + { + ver = 3; + break; + } + } + } + + return ver; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/AuthenticatedData.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/AuthenticatedData.cs.meta new file mode 100644 index 0000000..8578791 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/AuthenticatedData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c1ac6d352cffe4c4b86307537feafa4d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/AuthenticatedDataParser.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/AuthenticatedDataParser.cs new file mode 100644 index 0000000..4b80d1b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/AuthenticatedDataParser.cs @@ -0,0 +1,182 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; + +namespace Org.BouncyCastle.Asn1.Cms +{ + /** + * Produce an object suitable for an Asn1OutputStream. + *
+	 * AuthenticatedData ::= SEQUENCE {
+	 *       version CMSVersion,
+	 *       originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL,
+	 *       recipientInfos RecipientInfos,
+	 *       macAlgorithm MessageAuthenticationCodeAlgorithm,
+	 *       digestAlgorithm [1] DigestAlgorithmIdentifier OPTIONAL,
+	 *       encapContentInfo EncapsulatedContentInfo,
+	 *       authAttrs [2] IMPLICIT AuthAttributes OPTIONAL,
+	 *       mac MessageAuthenticationCode,
+	 *       unauthAttrs [3] IMPLICIT UnauthAttributes OPTIONAL }
+	 *
+	 * AuthAttributes ::= SET SIZE (1..MAX) OF Attribute
+	 *
+	 * UnauthAttributes ::= SET SIZE (1..MAX) OF Attribute
+	 *
+	 * MessageAuthenticationCode ::= OCTET STRING
+	 * 
+ */ + public class AuthenticatedDataParser + { + private Asn1SequenceParser seq; + private DerInteger version; + private IAsn1Convertible nextObject; + private bool originatorInfoCalled; + + public AuthenticatedDataParser( + Asn1SequenceParser seq) + { + this.seq = seq; + this.version = (DerInteger)seq.ReadObject(); + } + + public DerInteger Version + { + get { return version; } + } + + public OriginatorInfo GetOriginatorInfo() + { + originatorInfoCalled = true; + + if (nextObject == null) + { + nextObject = seq.ReadObject(); + } + + if (nextObject is Asn1TaggedObjectParser && ((Asn1TaggedObjectParser)nextObject).TagNo == 0) + { + Asn1SequenceParser originatorInfo = (Asn1SequenceParser) ((Asn1TaggedObjectParser)nextObject).GetObjectParser(Asn1Tags.Sequence, false); + nextObject = null; + return OriginatorInfo.GetInstance(originatorInfo.ToAsn1Object()); + } + + return null; + } + + public Asn1SetParser GetRecipientInfos() + { + if (!originatorInfoCalled) + { + GetOriginatorInfo(); + } + + if (nextObject == null) + { + nextObject = seq.ReadObject(); + } + + Asn1SetParser recipientInfos = (Asn1SetParser)nextObject; + nextObject = null; + return recipientInfos; + } + + public AlgorithmIdentifier GetMacAlgorithm() + { + if (nextObject == null) + { + nextObject = seq.ReadObject(); + } + + if (nextObject != null) + { + Asn1SequenceParser o = (Asn1SequenceParser)nextObject; + nextObject = null; + return AlgorithmIdentifier.GetInstance(o.ToAsn1Object()); + } + + return null; + } + + public AlgorithmIdentifier GetDigestAlgorithm() + { + if (nextObject == null) + { + nextObject = seq.ReadObject(); + } + + if (nextObject is Asn1TaggedObjectParser) + { + AlgorithmIdentifier obj = AlgorithmIdentifier.GetInstance( + (Asn1TaggedObject)nextObject.ToAsn1Object(), false); + nextObject = null; + return obj; + } + + return null; + } + + public ContentInfoParser GetEnapsulatedContentInfo() + { + if (nextObject == null) + { + nextObject = seq.ReadObject(); + } + + if (nextObject != null) + { + Asn1SequenceParser o = (Asn1SequenceParser)nextObject; + nextObject = null; + return new ContentInfoParser(o); + } + + return null; + } + + public Asn1SetParser GetAuthAttrs() + { + if (nextObject == null) + { + nextObject = seq.ReadObject(); + } + + if (nextObject is Asn1TaggedObjectParser) + { + IAsn1Convertible o = nextObject; + nextObject = null; + return (Asn1SetParser)((Asn1TaggedObjectParser)o).GetObjectParser(Asn1Tags.Set, false); + } + + return null; + } + + public Asn1OctetString GetMac() + { + if (nextObject == null) + { + nextObject = seq.ReadObject(); + } + + IAsn1Convertible o = nextObject; + nextObject = null; + + return Asn1OctetString.GetInstance(o.ToAsn1Object()); + } + + public Asn1SetParser GetUnauthAttrs() + { + if (nextObject == null) + { + nextObject = seq.ReadObject(); + } + + if (nextObject != null) + { + IAsn1Convertible o = nextObject; + nextObject = null; + return (Asn1SetParser)((Asn1TaggedObjectParser)o).GetObjectParser(Asn1Tags.Set, false); + } + + return null; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/AuthenticatedDataParser.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/AuthenticatedDataParser.cs.meta new file mode 100644 index 0000000..3e981e1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/AuthenticatedDataParser.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5eb61d1135ef2f34990f149cd910dfe7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/CMSAttributes.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/CMSAttributes.cs new file mode 100644 index 0000000..fca2b67 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/CMSAttributes.cs @@ -0,0 +1,14 @@ +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Pkcs; + +namespace Org.BouncyCastle.Asn1.Cms +{ + public abstract class CmsAttributes + { + public static readonly DerObjectIdentifier ContentType = PkcsObjectIdentifiers.Pkcs9AtContentType; + public static readonly DerObjectIdentifier MessageDigest = PkcsObjectIdentifiers.Pkcs9AtMessageDigest; + public static readonly DerObjectIdentifier SigningTime = PkcsObjectIdentifiers.Pkcs9AtSigningTime; + public static readonly DerObjectIdentifier CounterSignature = PkcsObjectIdentifiers.Pkcs9AtCounterSignature; + public static readonly DerObjectIdentifier ContentHint = PkcsObjectIdentifiers.IdAAContentHint; + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/CMSAttributes.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/CMSAttributes.cs.meta new file mode 100644 index 0000000..6cc6bf8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/CMSAttributes.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a56e56d044355034ebba54badb4d32e8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/CMSObjectIdentifiers.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/CMSObjectIdentifiers.cs new file mode 100644 index 0000000..2ad0a3c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/CMSObjectIdentifiers.cs @@ -0,0 +1,28 @@ +using Org.BouncyCastle.Asn1.Pkcs; + +namespace Org.BouncyCastle.Asn1.Cms +{ + public abstract class CmsObjectIdentifiers + { + public static readonly DerObjectIdentifier Data = PkcsObjectIdentifiers.Data; + public static readonly DerObjectIdentifier SignedData = PkcsObjectIdentifiers.SignedData; + public static readonly DerObjectIdentifier EnvelopedData = PkcsObjectIdentifiers.EnvelopedData; + public static readonly DerObjectIdentifier SignedAndEnvelopedData = PkcsObjectIdentifiers.SignedAndEnvelopedData; + public static readonly DerObjectIdentifier DigestedData = PkcsObjectIdentifiers.DigestedData; + public static readonly DerObjectIdentifier EncryptedData = PkcsObjectIdentifiers.EncryptedData; + public static readonly DerObjectIdentifier AuthenticatedData = PkcsObjectIdentifiers.IdCTAuthData; + public static readonly DerObjectIdentifier CompressedData = PkcsObjectIdentifiers.IdCTCompressedData; + public static readonly DerObjectIdentifier AuthEnvelopedData = PkcsObjectIdentifiers.IdCTAuthEnvelopedData; + public static readonly DerObjectIdentifier timestampedData = PkcsObjectIdentifiers.IdCTTimestampedData; + + /** + * The other Revocation Info arc + * id-ri OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) + * dod(6) internet(1) security(5) mechanisms(5) pkix(7) ri(16) } + */ + public static readonly DerObjectIdentifier id_ri = new DerObjectIdentifier("1.3.6.1.5.5.7.16"); + + public static readonly DerObjectIdentifier id_ri_ocsp_response = id_ri.Branch("2"); + public static readonly DerObjectIdentifier id_ri_scvp = id_ri.Branch("4"); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/CMSObjectIdentifiers.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/CMSObjectIdentifiers.cs.meta new file mode 100644 index 0000000..3d84869 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/CMSObjectIdentifiers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0063fdd7de0fe554e98411dfe30fac3c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/CompressedData.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/CompressedData.cs new file mode 100644 index 0000000..154ed35 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/CompressedData.cs @@ -0,0 +1,96 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cms +{ + /** + * RFC 3274 - CMS Compressed Data. + *
+     * CompressedData ::= Sequence {
+     *  version CMSVersion,
+     *  compressionAlgorithm CompressionAlgorithmIdentifier,
+     *  encapContentInfo EncapsulatedContentInfo
+     * }
+     * 
+ */ + public class CompressedData + : Asn1Encodable + { + private DerInteger version; + private AlgorithmIdentifier compressionAlgorithm; + private ContentInfo encapContentInfo; + + public CompressedData( + AlgorithmIdentifier compressionAlgorithm, + ContentInfo encapContentInfo) + { + this.version = new DerInteger(0); + this.compressionAlgorithm = compressionAlgorithm; + this.encapContentInfo = encapContentInfo; + } + + public CompressedData( + Asn1Sequence seq) + { + this.version = (DerInteger) seq[0]; + this.compressionAlgorithm = AlgorithmIdentifier.GetInstance(seq[1]); + this.encapContentInfo = ContentInfo.GetInstance(seq[2]); + } + + /** + * return a CompressedData object from a tagged object. + * + * @param ato the tagged object holding the object we want. + * @param explicitly true if the object is meant to be explicitly + * tagged false otherwise. + * @exception ArgumentException if the object held by the + * tagged object cannot be converted. + */ + public static CompressedData GetInstance( + Asn1TaggedObject ato, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(ato, explicitly)); + } + + /** + * return a CompressedData object from the given object. + * + * @param _obj the object we want converted. + * @exception ArgumentException if the object cannot be converted. + */ + public static CompressedData GetInstance( + object obj) + { + if (obj == null || obj is CompressedData) + return (CompressedData)obj; + + if (obj is Asn1Sequence) + return new CompressedData((Asn1Sequence) obj); + + throw new ArgumentException("Invalid CompressedData: " + Platform.GetTypeName(obj)); + } + + public DerInteger Version + { + get { return version; } + } + + public AlgorithmIdentifier CompressionAlgorithmIdentifier + { + get { return compressionAlgorithm; } + } + + public ContentInfo EncapContentInfo + { + get { return encapContentInfo; } + } + + public override Asn1Object ToAsn1Object() + { + return new BerSequence(version, compressionAlgorithm, encapContentInfo); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/CompressedData.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/CompressedData.cs.meta new file mode 100644 index 0000000..8e1b19a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/CompressedData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a2e048cd8f455684b9cbc96cd4cb69ee +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/CompressedDataParser.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/CompressedDataParser.cs new file mode 100644 index 0000000..7c53453 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/CompressedDataParser.cs @@ -0,0 +1,47 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; + +namespace Org.BouncyCastle.Asn1.Cms +{ + /** + * RFC 3274 - CMS Compressed Data. + *
+	* CompressedData ::= SEQUENCE {
+	*  version CMSVersion,
+	*  compressionAlgorithm CompressionAlgorithmIdentifier,
+	*  encapContentInfo EncapsulatedContentInfo
+	* }
+	* 
+ */ + public class CompressedDataParser + { + private DerInteger _version; + private AlgorithmIdentifier _compressionAlgorithm; + private ContentInfoParser _encapContentInfo; + + public CompressedDataParser( + Asn1SequenceParser seq) + { + this._version = (DerInteger)seq.ReadObject(); + this._compressionAlgorithm = AlgorithmIdentifier.GetInstance(seq.ReadObject().ToAsn1Object()); + this._encapContentInfo = new ContentInfoParser((Asn1SequenceParser)seq.ReadObject()); + } + + public DerInteger Version + { + get { return _version; } + } + + public AlgorithmIdentifier CompressionAlgorithmIdentifier + { + get { return _compressionAlgorithm; } + } + + public ContentInfoParser GetEncapContentInfo() + { + return _encapContentInfo; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/CompressedDataParser.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/CompressedDataParser.cs.meta new file mode 100644 index 0000000..da1f869 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/CompressedDataParser.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 33f11158b5848ac4aa486d2191127d2d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/ContentInfo.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/ContentInfo.cs new file mode 100644 index 0000000..f130a4b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/ContentInfo.cs @@ -0,0 +1,88 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cms +{ + public class ContentInfo + : Asn1Encodable + { + private readonly DerObjectIdentifier contentType; + private readonly Asn1Encodable content; + + public static ContentInfo GetInstance( + object obj) + { + if (obj == null || obj is ContentInfo) + return (ContentInfo) obj; + + if (obj is Asn1Sequence) + return new ContentInfo((Asn1Sequence) obj); + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj)); + } + + public static ContentInfo GetInstance(Asn1TaggedObject obj, bool isExplicit) + { + return GetInstance(Asn1Sequence.GetInstance(obj, isExplicit)); + } + + private ContentInfo( + Asn1Sequence seq) + { + if (seq.Count < 1 || seq.Count > 2) + throw new ArgumentException("Bad sequence size: " + seq.Count, "seq"); + + contentType = (DerObjectIdentifier) seq[0]; + + if (seq.Count > 1) + { + Asn1TaggedObject tagged = (Asn1TaggedObject) seq[1]; + if (!tagged.IsExplicit() || tagged.TagNo != 0) + throw new ArgumentException("Bad tag for 'content'", "seq"); + + content = tagged.GetObject(); + } + } + + public ContentInfo( + DerObjectIdentifier contentType, + Asn1Encodable content) + { + this.contentType = contentType; + this.content = content; + } + + public DerObjectIdentifier ContentType + { + get { return contentType; } + } + + public Asn1Encodable Content + { + get { return content; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * ContentInfo ::= Sequence {
+         *          contentType ContentType,
+         *          content
+         *          [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(contentType); + + if (content != null) + { + v.Add(new BerTaggedObject(0, content)); + } + + return new BerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/ContentInfo.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/ContentInfo.cs.meta new file mode 100644 index 0000000..bb30108 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/ContentInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f7e3e44ba2f3e4041adbbf003e3c4917 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/ContentInfoParser.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/ContentInfoParser.cs new file mode 100644 index 0000000..541cc0f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/ContentInfoParser.cs @@ -0,0 +1,40 @@ +using System; + +namespace Org.BouncyCastle.Asn1.Cms +{ + /** + * Produce an object suitable for an Asn1OutputStream. + *
+	* ContentInfo ::= SEQUENCE {
+	*          contentType ContentType,
+	*          content
+	*          [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL }
+	* 
+ */ + public class ContentInfoParser + { + private DerObjectIdentifier contentType; + private Asn1TaggedObjectParser content; + + public ContentInfoParser( + Asn1SequenceParser seq) + { + contentType = (DerObjectIdentifier)seq.ReadObject(); + content = (Asn1TaggedObjectParser)seq.ReadObject(); + } + + public DerObjectIdentifier ContentType + { + get { return contentType; } + } + + public IAsn1Convertible GetContent( + int tag) + { + if (content == null) + return null; + + return content.GetObjectParser(tag, true); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/ContentInfoParser.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/ContentInfoParser.cs.meta new file mode 100644 index 0000000..8d8b722 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/ContentInfoParser.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fb0f492edb124ca41b7fba4d1bd766fb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/EncryptedContentInfo.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/EncryptedContentInfo.cs new file mode 100644 index 0000000..999f2a0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/EncryptedContentInfo.cs @@ -0,0 +1,94 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cms +{ + public class EncryptedContentInfo + : Asn1Encodable + { + private DerObjectIdentifier contentType; + private AlgorithmIdentifier contentEncryptionAlgorithm; + private Asn1OctetString encryptedContent; + + public EncryptedContentInfo( + DerObjectIdentifier contentType, + AlgorithmIdentifier contentEncryptionAlgorithm, + Asn1OctetString encryptedContent) + { + this.contentType = contentType; + this.contentEncryptionAlgorithm = contentEncryptionAlgorithm; + this.encryptedContent = encryptedContent; + } + + public EncryptedContentInfo( + Asn1Sequence seq) + { + contentType = (DerObjectIdentifier) seq[0]; + contentEncryptionAlgorithm = AlgorithmIdentifier.GetInstance(seq[1]); + + if (seq.Count > 2) + { + encryptedContent = Asn1OctetString.GetInstance( + (Asn1TaggedObject) seq[2], false); + } + } + + /** + * return an EncryptedContentInfo object from the given object. + * + * @param obj the object we want converted. + * @exception ArgumentException if the object cannot be converted. + */ + public static EncryptedContentInfo GetInstance( + object obj) + { + if (obj == null || obj is EncryptedContentInfo) + return (EncryptedContentInfo)obj; + + if (obj is Asn1Sequence) + return new EncryptedContentInfo((Asn1Sequence)obj); + + throw new ArgumentException("Invalid EncryptedContentInfo: " + Platform.GetTypeName(obj)); + } + + public DerObjectIdentifier ContentType + { + get { return contentType; } + } + + public AlgorithmIdentifier ContentEncryptionAlgorithm + { + get { return contentEncryptionAlgorithm; } + } + + public Asn1OctetString EncryptedContent + { + get { return encryptedContent; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * EncryptedContentInfo ::= Sequence {
+         *     contentType ContentType,
+         *     contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier,
+         *     encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL
+         * }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector( + contentType, contentEncryptionAlgorithm); + + if (encryptedContent != null) + { + v.Add(new BerTaggedObject(false, 0, encryptedContent)); + } + + return new BerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/EncryptedContentInfo.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/EncryptedContentInfo.cs.meta new file mode 100644 index 0000000..b9faf81 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/EncryptedContentInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2d7ab4d35cda0ca40b2ebd37e85b2b53 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/EncryptedContentInfoParser.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/EncryptedContentInfoParser.cs new file mode 100644 index 0000000..af748b1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/EncryptedContentInfoParser.cs @@ -0,0 +1,46 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; + +namespace Org.BouncyCastle.Asn1.Cms +{ + /** + *
+	* EncryptedContentInfo ::= SEQUENCE {
+	*     contentType ContentType,
+	*     contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier,
+	*     encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL
+	* }
+	* 
+ */ + public class EncryptedContentInfoParser + { + private DerObjectIdentifier _contentType; + private AlgorithmIdentifier _contentEncryptionAlgorithm; + private Asn1TaggedObjectParser _encryptedContent; + + public EncryptedContentInfoParser( + Asn1SequenceParser seq) + { + _contentType = (DerObjectIdentifier)seq.ReadObject(); + _contentEncryptionAlgorithm = AlgorithmIdentifier.GetInstance(seq.ReadObject().ToAsn1Object()); + _encryptedContent = (Asn1TaggedObjectParser)seq.ReadObject(); + } + + public DerObjectIdentifier ContentType + { + get { return _contentType; } + } + + public AlgorithmIdentifier ContentEncryptionAlgorithm + { + get { return _contentEncryptionAlgorithm; } + } + + public IAsn1Convertible GetEncryptedContent( + int tag) + { + return _encryptedContent.GetObjectParser(tag, false); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/EncryptedContentInfoParser.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/EncryptedContentInfoParser.cs.meta new file mode 100644 index 0000000..31886da --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/EncryptedContentInfoParser.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 60e0f5608d0fde74fac60f8ff91fa684 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/EncryptedData.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/EncryptedData.cs new file mode 100644 index 0000000..b8492d1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/EncryptedData.cs @@ -0,0 +1,97 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cms +{ + public class EncryptedData + : Asn1Encodable + { + private readonly DerInteger version; + private readonly EncryptedContentInfo encryptedContentInfo; + private readonly Asn1Set unprotectedAttrs; + + public static EncryptedData GetInstance( + object obj) + { + if (obj is EncryptedData) + return (EncryptedData) obj; + + if (obj is Asn1Sequence) + return new EncryptedData((Asn1Sequence) obj); + + throw new ArgumentException("Invalid EncryptedData: " + Platform.GetTypeName(obj)); + } + + public EncryptedData( + EncryptedContentInfo encInfo) + : this(encInfo, null) + { + } + + public EncryptedData( + EncryptedContentInfo encInfo, + Asn1Set unprotectedAttrs) + { + if (encInfo == null) + throw new ArgumentNullException("encInfo"); + + this.version = new DerInteger((unprotectedAttrs == null) ? 0 : 2); + this.encryptedContentInfo = encInfo; + this.unprotectedAttrs = unprotectedAttrs; + } + + private EncryptedData( + Asn1Sequence seq) + { + if (seq == null) + throw new ArgumentNullException("seq"); + if (seq.Count < 2 || seq.Count > 3) + throw new ArgumentException("Bad sequence size: " + seq.Count, "seq"); + + this.version = DerInteger.GetInstance(seq[0]); + this.encryptedContentInfo = EncryptedContentInfo.GetInstance(seq[1]); + + if (seq.Count > 2) + { + this.unprotectedAttrs = Asn1Set.GetInstance((Asn1TaggedObject)seq[2], false); + } + } + + public virtual DerInteger Version + { + get { return version; } + } + + public virtual EncryptedContentInfo EncryptedContentInfo + { + get { return encryptedContentInfo; } + } + + public virtual Asn1Set UnprotectedAttrs + { + get { return unprotectedAttrs; } + } + + /** + *
+		*       EncryptedData ::= SEQUENCE {
+		*                     version CMSVersion,
+		*                     encryptedContentInfo EncryptedContentInfo,
+		*                     unprotectedAttrs [1] IMPLICIT UnprotectedAttributes OPTIONAL }
+		* 
+ * @return a basic ASN.1 object representation. + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(version, encryptedContentInfo); + + if (unprotectedAttrs != null) + { + v.Add(new BerTaggedObject(false, 1, unprotectedAttrs)); + } + + return new BerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/EncryptedData.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/EncryptedData.cs.meta new file mode 100644 index 0000000..64c7826 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/EncryptedData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a49cb874300473e499d915933162d128 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/EnvelopedData.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/EnvelopedData.cs new file mode 100644 index 0000000..8897fe3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/EnvelopedData.cs @@ -0,0 +1,166 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; + +namespace Org.BouncyCastle.Asn1.Cms +{ + public class EnvelopedData + : Asn1Encodable + { + private DerInteger version; + private OriginatorInfo originatorInfo; + private Asn1Set recipientInfos; + private EncryptedContentInfo encryptedContentInfo; + private Asn1Set unprotectedAttrs; + + public EnvelopedData( + OriginatorInfo originatorInfo, + Asn1Set recipientInfos, + EncryptedContentInfo encryptedContentInfo, + Asn1Set unprotectedAttrs) + { + this.version = new DerInteger(CalculateVersion(originatorInfo, recipientInfos, unprotectedAttrs)); + this.originatorInfo = originatorInfo; + this.recipientInfos = recipientInfos; + this.encryptedContentInfo = encryptedContentInfo; + this.unprotectedAttrs = unprotectedAttrs; + } + + public EnvelopedData( + OriginatorInfo originatorInfo, + Asn1Set recipientInfos, + EncryptedContentInfo encryptedContentInfo, + Attributes unprotectedAttrs) + { + this.version = new DerInteger(CalculateVersion(originatorInfo, recipientInfos, Asn1Set.GetInstance(unprotectedAttrs))); + this.originatorInfo = originatorInfo; + this.recipientInfos = recipientInfos; + this.encryptedContentInfo = encryptedContentInfo; + this.unprotectedAttrs = Asn1Set.GetInstance(unprotectedAttrs); + } + + [Obsolete("Use 'GetInstance' instead")] + public EnvelopedData( + Asn1Sequence seq) + { + int index = 0; + + version = (DerInteger) seq[index++]; + + object tmp = seq[index++]; + + if (tmp is Asn1TaggedObject) + { + originatorInfo = OriginatorInfo.GetInstance((Asn1TaggedObject) tmp, false); + tmp = seq[index++]; + } + + recipientInfos = Asn1Set.GetInstance(tmp); + encryptedContentInfo = EncryptedContentInfo.GetInstance(seq[index++]); + + if (seq.Count > index) + { + unprotectedAttrs = Asn1Set.GetInstance((Asn1TaggedObject) seq[index], false); + } + } + + /** + * return an EnvelopedData object from a tagged object. + * + * @param obj the tagged object holding the object we want. + * @param explicitly true if the object is meant to be explicitly + * tagged false otherwise. + * @exception ArgumentException if the object held by the + * tagged object cannot be converted. + */ + public static EnvelopedData GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + /** + * return an EnvelopedData object from the given object. + * + * @param obj the object we want converted. + * @exception ArgumentException if the object cannot be converted. + */ + public static EnvelopedData GetInstance( + object obj) + { + if (obj is EnvelopedData) + return (EnvelopedData)obj; + if (obj == null) + return null; + return new EnvelopedData(Asn1Sequence.GetInstance(obj)); + } + + public DerInteger Version + { + get { return version; } + } + + public OriginatorInfo OriginatorInfo + { + get { return originatorInfo; } + } + + public Asn1Set RecipientInfos + { + get { return recipientInfos; } + } + + public EncryptedContentInfo EncryptedContentInfo + { + get { return encryptedContentInfo; } + } + + public Asn1Set UnprotectedAttrs + { + get { return unprotectedAttrs; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * EnvelopedData ::= Sequence {
+         *     version CMSVersion,
+         *     originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL,
+         *     recipientInfos RecipientInfos,
+         *     encryptedContentInfo EncryptedContentInfo,
+         *     unprotectedAttrs [1] IMPLICIT UnprotectedAttributes OPTIONAL
+         * }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(version); + v.AddOptionalTagged(false, 0, originatorInfo); + v.Add(recipientInfos, encryptedContentInfo); + v.AddOptionalTagged(false, 1, unprotectedAttrs); + return new BerSequence(v); + } + + public static int CalculateVersion(OriginatorInfo originatorInfo, Asn1Set recipientInfos, Asn1Set unprotectedAttrs) + { + if (originatorInfo != null || unprotectedAttrs != null) + { + return 2; + } + + foreach (object o in recipientInfos) + { + RecipientInfo ri = RecipientInfo.GetInstance(o); + + if (!ri.Version.HasValue(0)) + { + return 2; + } + } + + return 0; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/EnvelopedData.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/EnvelopedData.cs.meta new file mode 100644 index 0000000..854139e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/EnvelopedData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 82aed2101bb26f4429d7868dd97f24de +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/EnvelopedDataParser.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/EnvelopedDataParser.cs new file mode 100644 index 0000000..5993537 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/EnvelopedDataParser.cs @@ -0,0 +1,107 @@ +using System; + +namespace Org.BouncyCastle.Asn1.Cms +{ + /** + * Produce an object suitable for an Asn1OutputStream. + *
+	* EnvelopedData ::= SEQUENCE {
+	*     version CMSVersion,
+	*     originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL,
+	*     recipientInfos RecipientInfos,
+	*     encryptedContentInfo EncryptedContentInfo,
+	*     unprotectedAttrs [1] IMPLICIT UnprotectedAttributes OPTIONAL
+	* }
+	* 
+ */ + public class EnvelopedDataParser + { + private Asn1SequenceParser _seq; + private DerInteger _version; + private IAsn1Convertible _nextObject; + private bool _originatorInfoCalled; + + public EnvelopedDataParser( + Asn1SequenceParser seq) + { + this._seq = seq; + this._version = (DerInteger)seq.ReadObject(); + } + + public DerInteger Version + { + get { return _version; } + } + + public OriginatorInfo GetOriginatorInfo() + { + _originatorInfoCalled = true; + + if (_nextObject == null) + { + _nextObject = _seq.ReadObject(); + } + + if (_nextObject is Asn1TaggedObjectParser && ((Asn1TaggedObjectParser)_nextObject).TagNo == 0) + { + Asn1SequenceParser originatorInfo = (Asn1SequenceParser) + ((Asn1TaggedObjectParser)_nextObject).GetObjectParser(Asn1Tags.Sequence, false); + _nextObject = null; + return OriginatorInfo.GetInstance(originatorInfo.ToAsn1Object()); + } + + return null; + } + + public Asn1SetParser GetRecipientInfos() + { + if (!_originatorInfoCalled) + { + GetOriginatorInfo(); + } + + if (_nextObject == null) + { + _nextObject = _seq.ReadObject(); + } + + Asn1SetParser recipientInfos = (Asn1SetParser)_nextObject; + _nextObject = null; + return recipientInfos; + } + + public EncryptedContentInfoParser GetEncryptedContentInfo() + { + if (_nextObject == null) + { + _nextObject = _seq.ReadObject(); + } + + if (_nextObject != null) + { + Asn1SequenceParser o = (Asn1SequenceParser) _nextObject; + _nextObject = null; + return new EncryptedContentInfoParser(o); + } + + return null; + } + + public Asn1SetParser GetUnprotectedAttrs() + { + if (_nextObject == null) + { + _nextObject = _seq.ReadObject(); + } + + if (_nextObject != null) + { + IAsn1Convertible o = _nextObject; + _nextObject = null; + return (Asn1SetParser)((Asn1TaggedObjectParser)o).GetObjectParser(Asn1Tags.Set, false); + } + + return null; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/EnvelopedDataParser.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/EnvelopedDataParser.cs.meta new file mode 100644 index 0000000..b0fbb90 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/EnvelopedDataParser.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6fddb54035b538c42b644aaec7e637ff +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/Evidence.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/Evidence.cs new file mode 100644 index 0000000..b12f090 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/Evidence.cs @@ -0,0 +1,73 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cms +{ + public class Evidence + : Asn1Encodable, IAsn1Choice + { + private TimeStampTokenEvidence tstEvidence; + private Asn1Sequence otherEvidence; + + public Evidence(TimeStampTokenEvidence tstEvidence) + { + this.tstEvidence = tstEvidence; + } + + private Evidence(Asn1TaggedObject tagged) + { + if (tagged.TagNo == 0) + { + this.tstEvidence = TimeStampTokenEvidence.GetInstance(tagged, false); + } + //else if (tagged.TagNo == 1) + //{ + // this.ersEvidence = EvidenceRecord.GetInstance(tagged, false); + //} + else if (tagged.TagNo == 2) + { + this.otherEvidence = Asn1Sequence.GetInstance(tagged, false); + } + else + { + throw new ArgumentException("unknown tag in Evidence", "tagged"); + } + } + + public static Evidence GetInstance(object obj) + { + if (obj is Evidence) + return (Evidence)obj; + + if (obj is Asn1TaggedObject) + return new Evidence(Asn1TaggedObject.GetInstance(obj)); + + throw new ArgumentException("Unknown object in GetInstance: " + Platform.GetTypeName(obj), "obj"); + } + + public static Evidence GetInstance(Asn1TaggedObject obj, bool isExplicit) + { + return GetInstance(obj.GetObject()); // must be explicitly tagged + } + + public virtual TimeStampTokenEvidence TstEvidence + { + get { return tstEvidence; } + } + + //public EvidenceRecord ErsEvidence + //{ + // get { return ersEvidence; } + //} + + public override Asn1Object ToAsn1Object() + { + if (tstEvidence != null) + return new DerTaggedObject(false, 0, tstEvidence); + //if (ersEvidence != null) + // return new DerTaggedObject(false, 1, ersEvidence); + return new DerTaggedObject(false, 2, otherEvidence); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/Evidence.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/Evidence.cs.meta new file mode 100644 index 0000000..e995c99 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/Evidence.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 992aec7bcd1c08c4e86c699e11fdb786 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/IssuerAndSerialNumber.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/IssuerAndSerialNumber.cs new file mode 100644 index 0000000..b509e7e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/IssuerAndSerialNumber.cs @@ -0,0 +1,64 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Asn1.Cms +{ + public class IssuerAndSerialNumber + : Asn1Encodable + { + private X509Name name; + private DerInteger serialNumber; + + public static IssuerAndSerialNumber GetInstance(object obj) + { + if (obj == null) + return null; + IssuerAndSerialNumber existing = obj as IssuerAndSerialNumber; + if (existing != null) + return existing; + return new IssuerAndSerialNumber(Asn1Sequence.GetInstance(obj)); + } + + [Obsolete("Use GetInstance() instead")] + public IssuerAndSerialNumber( + Asn1Sequence seq) + { + this.name = X509Name.GetInstance(seq[0]); + this.serialNumber = (DerInteger) seq[1]; + } + + public IssuerAndSerialNumber( + X509Name name, + BigInteger serialNumber) + { + this.name = name; + this.serialNumber = new DerInteger(serialNumber); + } + + public IssuerAndSerialNumber( + X509Name name, + DerInteger serialNumber) + { + this.name = name; + this.serialNumber = serialNumber; + } + + public X509Name Name + { + get { return name; } + } + + public DerInteger SerialNumber + { + get { return serialNumber; } + } + + public override Asn1Object ToAsn1Object() + { + return new DerSequence(name, serialNumber); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/IssuerAndSerialNumber.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/IssuerAndSerialNumber.cs.meta new file mode 100644 index 0000000..753e391 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/IssuerAndSerialNumber.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2b6c9282795cf4447a6685d38bc7c2a5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/KEKIdentifier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/KEKIdentifier.cs new file mode 100644 index 0000000..a422174 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/KEKIdentifier.cs @@ -0,0 +1,119 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cms +{ + public class KekIdentifier + : Asn1Encodable + { + private Asn1OctetString keyIdentifier; + private DerGeneralizedTime date; + private OtherKeyAttribute other; + + public KekIdentifier( + byte[] keyIdentifier, + DerGeneralizedTime date, + OtherKeyAttribute other) + { + this.keyIdentifier = new DerOctetString(keyIdentifier); + this.date = date; + this.other = other; + } + + public KekIdentifier( + Asn1Sequence seq) + { + keyIdentifier = (Asn1OctetString) seq[0]; + + switch (seq.Count) + { + case 1: + break; + case 2: + if (seq[1] is DerGeneralizedTime) + { + date = (DerGeneralizedTime) seq[1]; + } + else + { + other = OtherKeyAttribute.GetInstance(seq[2]); + } + break; + case 3: + date = (DerGeneralizedTime) seq[1]; + other = OtherKeyAttribute.GetInstance(seq[2]); + break; + default: + throw new ArgumentException("Invalid KekIdentifier"); + } + } + + /** + * return a KekIdentifier object from a tagged object. + * + * @param obj the tagged object holding the object we want. + * @param explicitly true if the object is meant to be explicitly + * tagged false otherwise. + * @exception ArgumentException if the object held by the + * tagged object cannot be converted. + */ + public static KekIdentifier GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + /** + * return a KekIdentifier object from the given object. + * + * @param obj the object we want converted. + * @exception ArgumentException if the object cannot be converted. + */ + public static KekIdentifier GetInstance( + object obj) + { + if (obj == null || obj is KekIdentifier) + return (KekIdentifier)obj; + + if (obj is Asn1Sequence) + return new KekIdentifier((Asn1Sequence)obj); + + throw new ArgumentException("Invalid KekIdentifier: " + Platform.GetTypeName(obj)); + } + + public Asn1OctetString KeyIdentifier + { + get { return keyIdentifier; } + } + + public DerGeneralizedTime Date + { + get { return date; } + } + + public OtherKeyAttribute Other + { + get { return other; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * KekIdentifier ::= Sequence {
+         *     keyIdentifier OCTET STRING,
+         *     date GeneralizedTime OPTIONAL,
+         *     other OtherKeyAttribute OPTIONAL
+         * }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(keyIdentifier); + v.AddOptional(date, other); + return new DerSequence(v); + } + } +} + diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/KEKIdentifier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/KEKIdentifier.cs.meta new file mode 100644 index 0000000..9007fd9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/KEKIdentifier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 51119a5633d231243bf14c2eb7d733da +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/KEKRecipientInfo.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/KEKRecipientInfo.cs new file mode 100644 index 0000000..810e7fc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/KEKRecipientInfo.cs @@ -0,0 +1,106 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cms +{ + public class KekRecipientInfo + : Asn1Encodable + { + private DerInteger version; + private KekIdentifier kekID; + private AlgorithmIdentifier keyEncryptionAlgorithm; + private Asn1OctetString encryptedKey; + + public KekRecipientInfo( + KekIdentifier kekID, + AlgorithmIdentifier keyEncryptionAlgorithm, + Asn1OctetString encryptedKey) + { + this.version = new DerInteger(4); + this.kekID = kekID; + this.keyEncryptionAlgorithm = keyEncryptionAlgorithm; + this.encryptedKey = encryptedKey; + } + + public KekRecipientInfo( + Asn1Sequence seq) + { + version = (DerInteger) seq[0]; + kekID = KekIdentifier.GetInstance(seq[1]); + keyEncryptionAlgorithm = AlgorithmIdentifier.GetInstance(seq[2]); + encryptedKey = (Asn1OctetString) seq[3]; + } + + /** + * return a KekRecipientInfo object from a tagged object. + * + * @param obj the tagged object holding the object we want. + * @param explicitly true if the object is meant to be explicitly + * tagged false otherwise. + * @exception ArgumentException if the object held by the + * tagged object cannot be converted. + */ + public static KekRecipientInfo GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + /** + * return a KekRecipientInfo object from the given object. + * + * @param obj the object we want converted. + * @exception ArgumentException if the object cannot be converted. + */ + public static KekRecipientInfo GetInstance( + object obj) + { + if (obj == null || obj is KekRecipientInfo) + return (KekRecipientInfo)obj; + + if(obj is Asn1Sequence) + return new KekRecipientInfo((Asn1Sequence)obj); + + throw new ArgumentException("Invalid KekRecipientInfo: " + Platform.GetTypeName(obj)); + } + + public DerInteger Version + { + get { return version; } + } + + public KekIdentifier KekID + { + get { return kekID; } + } + + public AlgorithmIdentifier KeyEncryptionAlgorithm + { + get { return keyEncryptionAlgorithm; } + } + + public Asn1OctetString EncryptedKey + { + get { return encryptedKey; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * KekRecipientInfo ::= Sequence {
+         *     version CMSVersion,  -- always set to 4
+         *     kekID KekIdentifier,
+         *     keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier,
+         *     encryptedKey EncryptedKey
+         * }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + return new DerSequence(version, kekID, keyEncryptionAlgorithm, encryptedKey); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/KEKRecipientInfo.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/KEKRecipientInfo.cs.meta new file mode 100644 index 0000000..5ca6cac --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/KEKRecipientInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 68472fbe9160c494a88c06242d434368 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/KeyAgreeRecipientIdentifier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/KeyAgreeRecipientIdentifier.cs new file mode 100644 index 0000000..0256c2d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/KeyAgreeRecipientIdentifier.cs @@ -0,0 +1,94 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cms +{ + public class KeyAgreeRecipientIdentifier + : Asn1Encodable, IAsn1Choice + { + /** + * return an KeyAgreeRecipientIdentifier object from a tagged object. + * + * @param obj the tagged object holding the object we want. + * @param isExplicit true if the object is meant to be explicitly + * tagged false otherwise. + * @exception ArgumentException if the object held by the + * tagged object cannot be converted. + */ + public static KeyAgreeRecipientIdentifier GetInstance( + Asn1TaggedObject obj, + bool isExplicit) + { + return GetInstance(Asn1Sequence.GetInstance(obj, isExplicit)); + } + + /** + * return an KeyAgreeRecipientIdentifier object from the given object. + * + * @param obj the object we want converted. + * @exception ArgumentException if the object cannot be converted. + */ + public static KeyAgreeRecipientIdentifier GetInstance( + object obj) + { + if (obj == null || obj is KeyAgreeRecipientIdentifier) + return (KeyAgreeRecipientIdentifier)obj; + + if (obj is Asn1Sequence) + return new KeyAgreeRecipientIdentifier(IssuerAndSerialNumber.GetInstance(obj)); + + if (obj is Asn1TaggedObject && ((Asn1TaggedObject)obj).TagNo == 0) + { + return new KeyAgreeRecipientIdentifier(RecipientKeyIdentifier.GetInstance( + (Asn1TaggedObject)obj, false)); + } + + throw new ArgumentException("Invalid KeyAgreeRecipientIdentifier: " + Platform.GetTypeName(obj), "obj"); + } + + private readonly IssuerAndSerialNumber issuerSerial; + private readonly RecipientKeyIdentifier rKeyID; + + public KeyAgreeRecipientIdentifier( + IssuerAndSerialNumber issuerSerial) + { + this.issuerSerial = issuerSerial; + } + + public KeyAgreeRecipientIdentifier( + RecipientKeyIdentifier rKeyID) + { + this.rKeyID = rKeyID; + } + + public IssuerAndSerialNumber IssuerAndSerialNumber + { + get { return issuerSerial; } + } + + public RecipientKeyIdentifier RKeyID + { + get { return rKeyID; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+		 * KeyAgreeRecipientIdentifier ::= CHOICE {
+		 *     issuerAndSerialNumber IssuerAndSerialNumber,
+		 *     rKeyId [0] IMPLICIT RecipientKeyIdentifier
+		 * }
+		 * 
+ */ + public override Asn1Object ToAsn1Object() + { + if (issuerSerial != null) + { + return issuerSerial.ToAsn1Object(); + } + + return new DerTaggedObject(false, 0, rKeyID); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/KeyAgreeRecipientIdentifier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/KeyAgreeRecipientIdentifier.cs.meta new file mode 100644 index 0000000..4f520b7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/KeyAgreeRecipientIdentifier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cd5660984b554a846987fbb3d47e4930 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/KeyAgreeRecipientInfo.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/KeyAgreeRecipientInfo.cs new file mode 100644 index 0000000..52eb7d4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/KeyAgreeRecipientInfo.cs @@ -0,0 +1,134 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cms +{ + public class KeyAgreeRecipientInfo + : Asn1Encodable + { + private DerInteger version; + private OriginatorIdentifierOrKey originator; + private Asn1OctetString ukm; + private AlgorithmIdentifier keyEncryptionAlgorithm; + private Asn1Sequence recipientEncryptedKeys; + + public KeyAgreeRecipientInfo( + OriginatorIdentifierOrKey originator, + Asn1OctetString ukm, + AlgorithmIdentifier keyEncryptionAlgorithm, + Asn1Sequence recipientEncryptedKeys) + { + this.version = new DerInteger(3); + this.originator = originator; + this.ukm = ukm; + this.keyEncryptionAlgorithm = keyEncryptionAlgorithm; + this.recipientEncryptedKeys = recipientEncryptedKeys; + } + + public KeyAgreeRecipientInfo( + Asn1Sequence seq) + { + int index = 0; + + version = (DerInteger) seq[index++]; + originator = OriginatorIdentifierOrKey.GetInstance( + (Asn1TaggedObject) seq[index++], true); + + if (seq[index] is Asn1TaggedObject) + { + ukm = Asn1OctetString.GetInstance( + (Asn1TaggedObject) seq[index++], true); + } + + keyEncryptionAlgorithm = AlgorithmIdentifier.GetInstance( + seq[index++]); + + recipientEncryptedKeys = (Asn1Sequence) seq[index++]; + } + + /** + * return a KeyAgreeRecipientInfo object from a tagged object. + * + * @param obj the tagged object holding the object we want. + * @param explicitly true if the object is meant to be explicitly + * tagged false otherwise. + * @exception ArgumentException if the object held by the + * tagged object cannot be converted. + */ + public static KeyAgreeRecipientInfo GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + /** + * return a KeyAgreeRecipientInfo object from the given object. + * + * @param obj the object we want converted. + * @exception ArgumentException if the object cannot be converted. + */ + public static KeyAgreeRecipientInfo GetInstance( + object obj) + { + if (obj == null || obj is KeyAgreeRecipientInfo) + return (KeyAgreeRecipientInfo)obj; + + if (obj is Asn1Sequence) + return new KeyAgreeRecipientInfo((Asn1Sequence)obj); + + throw new ArgumentException( + "Illegal object in KeyAgreeRecipientInfo: " + Platform.GetTypeName(obj)); + + } + + public DerInteger Version + { + get { return version; } + } + + public OriginatorIdentifierOrKey Originator + { + get { return originator; } + } + + public Asn1OctetString UserKeyingMaterial + { + get { return ukm; } + } + + public AlgorithmIdentifier KeyEncryptionAlgorithm + { + get { return keyEncryptionAlgorithm; } + } + + public Asn1Sequence RecipientEncryptedKeys + { + get { return recipientEncryptedKeys; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * KeyAgreeRecipientInfo ::= Sequence {
+         *     version CMSVersion,  -- always set to 3
+         *     originator [0] EXPLICIT OriginatorIdentifierOrKey,
+         *     ukm [1] EXPLICIT UserKeyingMaterial OPTIONAL,
+         *     keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier,
+         *     recipientEncryptedKeys RecipientEncryptedKeys
+         * }
+		 *
+		 * UserKeyingMaterial ::= OCTET STRING
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(version, new DerTaggedObject(true, 0, originator)); + v.AddOptionalTagged(true, 1, ukm); + v.Add(keyEncryptionAlgorithm, recipientEncryptedKeys); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/KeyAgreeRecipientInfo.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/KeyAgreeRecipientInfo.cs.meta new file mode 100644 index 0000000..8103e8d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/KeyAgreeRecipientInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 67b9e47898becaa4387af71100ea0467 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/KeyTransRecipientInfo.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/KeyTransRecipientInfo.cs new file mode 100644 index 0000000..5e4fd22 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/KeyTransRecipientInfo.cs @@ -0,0 +1,99 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cms +{ + public class KeyTransRecipientInfo + : Asn1Encodable + { + private DerInteger version; + private RecipientIdentifier rid; + private AlgorithmIdentifier keyEncryptionAlgorithm; + private Asn1OctetString encryptedKey; + + public KeyTransRecipientInfo( + RecipientIdentifier rid, + AlgorithmIdentifier keyEncryptionAlgorithm, + Asn1OctetString encryptedKey) + { + if (rid.ToAsn1Object() is Asn1TaggedObject) + { + this.version = new DerInteger(2); + } + else + { + this.version = new DerInteger(0); + } + + this.rid = rid; + this.keyEncryptionAlgorithm = keyEncryptionAlgorithm; + this.encryptedKey = encryptedKey; + } + + public KeyTransRecipientInfo( + Asn1Sequence seq) + { + this.version = (DerInteger) seq[0]; + this.rid = RecipientIdentifier.GetInstance(seq[1]); + this.keyEncryptionAlgorithm = AlgorithmIdentifier.GetInstance(seq[2]); + this.encryptedKey = (Asn1OctetString) seq[3]; + } + + /** + * return a KeyTransRecipientInfo object from the given object. + * + * @param obj the object we want converted. + * @exception ArgumentException if the object cannot be converted. + */ + public static KeyTransRecipientInfo GetInstance( + object obj) + { + if (obj == null || obj is KeyTransRecipientInfo) + return (KeyTransRecipientInfo) obj; + + if(obj is Asn1Sequence) + return new KeyTransRecipientInfo((Asn1Sequence) obj); + + throw new ArgumentException( + "Illegal object in KeyTransRecipientInfo: " + Platform.GetTypeName(obj)); + } + + public DerInteger Version + { + get { return version; } + } + + public RecipientIdentifier RecipientIdentifier + { + get { return rid; } + } + + public AlgorithmIdentifier KeyEncryptionAlgorithm + { + get { return keyEncryptionAlgorithm; } + } + + public Asn1OctetString EncryptedKey + { + get { return encryptedKey; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * KeyTransRecipientInfo ::= Sequence {
+         *     version CMSVersion,  -- always set to 0 or 2
+         *     rid RecipientIdentifier,
+         *     keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier,
+         *     encryptedKey EncryptedKey
+         * }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + return new DerSequence(version, rid, keyEncryptionAlgorithm, encryptedKey); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/KeyTransRecipientInfo.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/KeyTransRecipientInfo.cs.meta new file mode 100644 index 0000000..aa835f2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/KeyTransRecipientInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b6c312bec4d9d1a4ca4a31a9d5465b1e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/MetaData.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/MetaData.cs new file mode 100644 index 0000000..ad2b5c4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/MetaData.cs @@ -0,0 +1,94 @@ +using System; + +namespace Org.BouncyCastle.Asn1.Cms +{ + public class MetaData + : Asn1Encodable + { + private DerBoolean hashProtected; + private DerUtf8String fileName; + private DerIA5String mediaType; + private Attributes otherMetaData; + + public MetaData( + DerBoolean hashProtected, + DerUtf8String fileName, + DerIA5String mediaType, + Attributes otherMetaData) + { + this.hashProtected = hashProtected; + this.fileName = fileName; + this.mediaType = mediaType; + this.otherMetaData = otherMetaData; + } + + private MetaData(Asn1Sequence seq) + { + this.hashProtected = DerBoolean.GetInstance(seq[0]); + + int index = 1; + + if (index < seq.Count && seq[index] is DerUtf8String) + { + this.fileName = DerUtf8String.GetInstance(seq[index++]); + } + if (index < seq.Count && seq[index] is DerIA5String) + { + this.mediaType = DerIA5String.GetInstance(seq[index++]); + } + if (index < seq.Count) + { + this.otherMetaData = Attributes.GetInstance(seq[index++]); + } + } + + public static MetaData GetInstance(object obj) + { + if (obj is MetaData) + return (MetaData)obj; + + if (obj != null) + return new MetaData(Asn1Sequence.GetInstance(obj)); + + return null; + } + + /** + *
+		 * MetaData ::= SEQUENCE {
+		 *   hashProtected        BOOLEAN,
+		 *   fileName             UTF8String OPTIONAL,
+		 *   mediaType            IA5String OPTIONAL,
+		 *   otherMetaData        Attributes OPTIONAL
+		 * }
+		 * 
+ * @return + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(hashProtected); + v.AddOptional(fileName, mediaType, otherMetaData); + return new DerSequence(v); + } + + public virtual bool IsHashProtected + { + get { return hashProtected.IsTrue; } + } + + public virtual DerUtf8String FileName + { + get { return fileName; } + } + + public virtual DerIA5String MediaType + { + get { return mediaType; } + } + + public virtual Attributes OtherMetaData + { + get { return otherMetaData; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/MetaData.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/MetaData.cs.meta new file mode 100644 index 0000000..91715a2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/MetaData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 248edb82c5d136a49b6bdb8d175411e3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/OriginatorIdentifierOrKey.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/OriginatorIdentifierOrKey.cs new file mode 100644 index 0000000..f197fe9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/OriginatorIdentifierOrKey.cs @@ -0,0 +1,168 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cms +{ + public class OriginatorIdentifierOrKey + : Asn1Encodable, IAsn1Choice + { + private Asn1Encodable id; + + public OriginatorIdentifierOrKey( + IssuerAndSerialNumber id) + { + this.id = id; + } + + [Obsolete("Use version taking a 'SubjectKeyIdentifier'")] + public OriginatorIdentifierOrKey( + Asn1OctetString id) + : this(new SubjectKeyIdentifier(id)) + { + } + + public OriginatorIdentifierOrKey( + SubjectKeyIdentifier id) + { + this.id = new DerTaggedObject(false, 0, id); + } + + public OriginatorIdentifierOrKey( + OriginatorPublicKey id) + { + this.id = new DerTaggedObject(false, 1, id); + } + + [Obsolete("Use more specific version")] + public OriginatorIdentifierOrKey( + Asn1Object id) + { + this.id = id; + } + + private OriginatorIdentifierOrKey( + Asn1TaggedObject id) + { + // TODO Add validation + this.id = id; + } + + /** + * return an OriginatorIdentifierOrKey object from a tagged object. + * + * @param o the tagged object holding the object we want. + * @param explicitly true if the object is meant to be explicitly + * tagged false otherwise. + * @exception ArgumentException if the object held by the + * tagged object cannot be converted. + */ + public static OriginatorIdentifierOrKey GetInstance( + Asn1TaggedObject o, + bool explicitly) + { + if (!explicitly) + { + throw new ArgumentException( + "Can't implicitly tag OriginatorIdentifierOrKey"); + } + + return GetInstance(o.GetObject()); + } + + /** + * return an OriginatorIdentifierOrKey object from the given object. + * + * @param o the object we want converted. + * @exception ArgumentException if the object cannot be converted. + */ + public static OriginatorIdentifierOrKey GetInstance( + object o) + { + if (o == null || o is OriginatorIdentifierOrKey) + return (OriginatorIdentifierOrKey)o; + + if (o is IssuerAndSerialNumber) + return new OriginatorIdentifierOrKey((IssuerAndSerialNumber)o); + + if (o is SubjectKeyIdentifier) + return new OriginatorIdentifierOrKey((SubjectKeyIdentifier)o); + + if (o is OriginatorPublicKey) + return new OriginatorIdentifierOrKey((OriginatorPublicKey)o); + + if (o is Asn1TaggedObject) + return new OriginatorIdentifierOrKey((Asn1TaggedObject)o); + + throw new ArgumentException("Invalid OriginatorIdentifierOrKey: " + Platform.GetTypeName(o)); + } + + public Asn1Encodable ID + { + get { return id; } + } + + public IssuerAndSerialNumber IssuerAndSerialNumber + { + get + { + if (id is IssuerAndSerialNumber) + { + return (IssuerAndSerialNumber)id; + } + + return null; + } + } + + public SubjectKeyIdentifier SubjectKeyIdentifier + { + get + { + if (id is Asn1TaggedObject && ((Asn1TaggedObject)id).TagNo == 0) + { + return SubjectKeyIdentifier.GetInstance((Asn1TaggedObject)id, false); + } + + return null; + } + } + + [Obsolete("Use 'OriginatorPublicKey' property")] + public OriginatorPublicKey OriginatorKey + { + get { return OriginatorPublicKey; } + } + + public OriginatorPublicKey OriginatorPublicKey + { + get + { + if (id is Asn1TaggedObject && ((Asn1TaggedObject)id).TagNo == 1) + { + return OriginatorPublicKey.GetInstance((Asn1TaggedObject)id, false); + } + + return null; + } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * OriginatorIdentifierOrKey ::= CHOICE {
+         *     issuerAndSerialNumber IssuerAndSerialNumber,
+         *     subjectKeyIdentifier [0] SubjectKeyIdentifier,
+         *     originatorKey [1] OriginatorPublicKey
+         * }
+         *
+         * SubjectKeyIdentifier ::= OCTET STRING
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + return id.ToAsn1Object(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/OriginatorIdentifierOrKey.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/OriginatorIdentifierOrKey.cs.meta new file mode 100644 index 0000000..c104f22 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/OriginatorIdentifierOrKey.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c126d0dfb3748c74b95e12e2e3f3e82e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/OriginatorInfo.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/OriginatorInfo.cs new file mode 100644 index 0000000..23acc2d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/OriginatorInfo.cs @@ -0,0 +1,112 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cms +{ + public class OriginatorInfo + : Asn1Encodable + { + private Asn1Set certs; + private Asn1Set crls; + + public OriginatorInfo( + Asn1Set certs, + Asn1Set crls) + { + this.certs = certs; + this.crls = crls; + } + + public OriginatorInfo( + Asn1Sequence seq) + { + switch (seq.Count) + { + case 0: // empty + break; + case 1: + Asn1TaggedObject o = (Asn1TaggedObject) seq[0]; + switch (o.TagNo) + { + case 0 : + certs = Asn1Set.GetInstance(o, false); + break; + case 1 : + crls = Asn1Set.GetInstance(o, false); + break; + default: + throw new ArgumentException("Bad tag in OriginatorInfo: " + o.TagNo); + } + break; + case 2: + certs = Asn1Set.GetInstance((Asn1TaggedObject) seq[0], false); + crls = Asn1Set.GetInstance((Asn1TaggedObject) seq[1], false); + break; + default: + throw new ArgumentException("OriginatorInfo too big"); + } + } + + /** + * return an OriginatorInfo object from a tagged object. + * + * @param obj the tagged object holding the object we want. + * @param explicitly true if the object is meant to be explicitly + * tagged false otherwise. + * @exception ArgumentException if the object held by the + * tagged object cannot be converted. + */ + public static OriginatorInfo GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + /** + * return an OriginatorInfo object from the given object. + * + * @param obj the object we want converted. + * @exception ArgumentException if the object cannot be converted. + */ + public static OriginatorInfo GetInstance( + object obj) + { + if (obj == null || obj is OriginatorInfo) + return (OriginatorInfo)obj; + + if (obj is Asn1Sequence) + return new OriginatorInfo((Asn1Sequence)obj); + + throw new ArgumentException("Invalid OriginatorInfo: " + Platform.GetTypeName(obj)); + } + + public Asn1Set Certificates + { + get { return certs; } + } + + public Asn1Set Crls + { + get { return crls; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * OriginatorInfo ::= Sequence {
+         *     certs [0] IMPLICIT CertificateSet OPTIONAL,
+         *     crls [1] IMPLICIT CertificateRevocationLists OPTIONAL
+         * }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + v.AddOptionalTagged(false, 0, certs); + v.AddOptionalTagged(false, 1, crls); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/OriginatorInfo.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/OriginatorInfo.cs.meta new file mode 100644 index 0000000..e2875a9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/OriginatorInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ba2e6b63e8a02814893533947e8c7dfa +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/OriginatorPublicKey.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/OriginatorPublicKey.cs new file mode 100644 index 0000000..9f29c62 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/OriginatorPublicKey.cs @@ -0,0 +1,88 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cms +{ + public class OriginatorPublicKey + : Asn1Encodable + { + private readonly AlgorithmIdentifier mAlgorithm; + private readonly DerBitString mPublicKey; + + public OriginatorPublicKey( + AlgorithmIdentifier algorithm, + byte[] publicKey) + { + this.mAlgorithm = algorithm; + this.mPublicKey = new DerBitString(publicKey); + } + + [Obsolete("Use 'GetInstance' instead")] + public OriginatorPublicKey( + Asn1Sequence seq) + { + this.mAlgorithm = AlgorithmIdentifier.GetInstance(seq[0]); + this.mPublicKey = DerBitString.GetInstance(seq[1]); + } + + /** + * return an OriginatorPublicKey object from a tagged object. + * + * @param obj the tagged object holding the object we want. + * @param explicitly true if the object is meant to be explicitly + * tagged false otherwise. + * @exception ArgumentException if the object held by the + * tagged object cannot be converted. + */ + public static OriginatorPublicKey GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + /** + * return an OriginatorPublicKey object from the given object. + * + * @param obj the object we want converted. + * @exception ArgumentException if the object cannot be converted. + */ + public static OriginatorPublicKey GetInstance( + object obj) + { + if (obj == null || obj is OriginatorPublicKey) + return (OriginatorPublicKey)obj; + + if (obj is Asn1Sequence) + return new OriginatorPublicKey(Asn1Sequence.GetInstance(obj)); + + throw new ArgumentException("Invalid OriginatorPublicKey: " + Platform.GetTypeName(obj)); + } + + public AlgorithmIdentifier Algorithm + { + get { return mAlgorithm; } + } + + public DerBitString PublicKey + { + get { return mPublicKey; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * OriginatorPublicKey ::= Sequence {
+         *     algorithm AlgorithmIdentifier,
+         *     publicKey BIT STRING
+         * }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + return new DerSequence(mAlgorithm, mPublicKey); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/OriginatorPublicKey.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/OriginatorPublicKey.cs.meta new file mode 100644 index 0000000..2312502 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/OriginatorPublicKey.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f4013acf90bbebe4fa90c90561f38d12 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/OtherKeyAttribute.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/OtherKeyAttribute.cs new file mode 100644 index 0000000..285c881 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/OtherKeyAttribute.cs @@ -0,0 +1,70 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cms +{ + public class OtherKeyAttribute + : Asn1Encodable + { + private DerObjectIdentifier keyAttrId; + private Asn1Encodable keyAttr; + + /** + * return an OtherKeyAttribute object from the given object. + * + * @param o the object we want converted. + * @exception ArgumentException if the object cannot be converted. + */ + public static OtherKeyAttribute GetInstance( + object obj) + { + if (obj == null || obj is OtherKeyAttribute) + return (OtherKeyAttribute) obj; + + if (obj is Asn1Sequence) + return new OtherKeyAttribute((Asn1Sequence) obj); + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + public OtherKeyAttribute( + Asn1Sequence seq) + { + keyAttrId = (DerObjectIdentifier) seq[0]; + keyAttr = seq[1]; + } + + public OtherKeyAttribute( + DerObjectIdentifier keyAttrId, + Asn1Encodable keyAttr) + { + this.keyAttrId = keyAttrId; + this.keyAttr = keyAttr; + } + + public DerObjectIdentifier KeyAttrId + { + get { return keyAttrId; } + } + + public Asn1Encodable KeyAttr + { + get { return keyAttr; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * OtherKeyAttribute ::= Sequence {
+         *     keyAttrId OBJECT IDENTIFIER,
+         *     keyAttr ANY DEFINED BY keyAttrId OPTIONAL
+         * }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + return new DerSequence(keyAttrId, keyAttr); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/OtherKeyAttribute.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/OtherKeyAttribute.cs.meta new file mode 100644 index 0000000..996a03d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/OtherKeyAttribute.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1afda5a5aca3376439954e52f8f60306 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/OtherRecipientInfo.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/OtherRecipientInfo.cs new file mode 100644 index 0000000..80dd68e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/OtherRecipientInfo.cs @@ -0,0 +1,83 @@ +using System; + +namespace Org.BouncyCastle.Asn1.Cms +{ + public class OtherRecipientInfo + : Asn1Encodable + { + private readonly DerObjectIdentifier oriType; + private readonly Asn1Encodable oriValue; + + public OtherRecipientInfo( + DerObjectIdentifier oriType, + Asn1Encodable oriValue) + { + this.oriType = oriType; + this.oriValue = oriValue; + } + + [Obsolete("Use GetInstance() instead")] + public OtherRecipientInfo( + Asn1Sequence seq) + { + oriType = DerObjectIdentifier.GetInstance(seq[0]); + oriValue = seq[1]; + } + + /** + * return a OtherRecipientInfo object from a tagged object. + * + * @param obj the tagged object holding the object we want. + * @param explicitly true if the object is meant to be explicitly + * tagged false otherwise. + * @exception ArgumentException if the object held by the + * tagged object cannot be converted. + */ + public static OtherRecipientInfo GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + /** + * return a OtherRecipientInfo object from the given object. + * + * @param obj the object we want converted. + * @exception ArgumentException if the object cannot be converted. + */ + public static OtherRecipientInfo GetInstance( + object obj) + { + if (obj == null) + return null; + OtherRecipientInfo existing = obj as OtherRecipientInfo; + if (existing != null) + return existing; + return new OtherRecipientInfo(Asn1Sequence.GetInstance(obj)); + } + + public virtual DerObjectIdentifier OriType + { + get { return oriType; } + } + + public virtual Asn1Encodable OriValue + { + get { return oriValue; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * OtherRecipientInfo ::= Sequence {
+         *    oriType OBJECT IDENTIFIER,
+         *    oriValue ANY DEFINED BY oriType }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + return new DerSequence(oriType, oriValue); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/OtherRecipientInfo.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/OtherRecipientInfo.cs.meta new file mode 100644 index 0000000..d08037a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/OtherRecipientInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b89db691af73bfb46ba157f8aad2c53b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/OtherRevocationInfoFormat.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/OtherRevocationInfoFormat.cs new file mode 100644 index 0000000..7835489 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/OtherRevocationInfoFormat.cs @@ -0,0 +1,77 @@ +using System; + +namespace Org.BouncyCastle.Asn1.Cms +{ + public class OtherRevocationInfoFormat + : Asn1Encodable + { + private readonly DerObjectIdentifier otherRevInfoFormat; + private readonly Asn1Encodable otherRevInfo; + + public OtherRevocationInfoFormat( + DerObjectIdentifier otherRevInfoFormat, + Asn1Encodable otherRevInfo) + { + this.otherRevInfoFormat = otherRevInfoFormat; + this.otherRevInfo = otherRevInfo; + } + + private OtherRevocationInfoFormat(Asn1Sequence seq) + { + otherRevInfoFormat = DerObjectIdentifier.GetInstance(seq[0]); + otherRevInfo = seq[1]; + } + + /** + * return a OtherRevocationInfoFormat object from a tagged object. + * + * @param obj the tagged object holding the object we want. + * @param explicit true if the object is meant to be explicitly + * tagged false otherwise. + * @exception IllegalArgumentException if the object held by the + * tagged object cannot be converted. + */ + public static OtherRevocationInfoFormat GetInstance(Asn1TaggedObject obj, bool isExplicit) + { + return GetInstance(Asn1Sequence.GetInstance(obj, isExplicit)); + } + + /** + * return a OtherRevocationInfoFormat object from the given object. + * + * @param obj the object we want converted. + * @exception IllegalArgumentException if the object cannot be converted. + */ + public static OtherRevocationInfoFormat GetInstance(object obj) + { + if (obj is OtherRevocationInfoFormat) + return (OtherRevocationInfoFormat)obj; + if (obj != null) + return new OtherRevocationInfoFormat(Asn1Sequence.GetInstance(obj)); + return null; + } + + public virtual DerObjectIdentifier InfoFormat + { + get { return otherRevInfoFormat; } + } + + public virtual Asn1Encodable Info + { + get { return otherRevInfo; } + } + + /** + * Produce an object suitable for an ASN1OutputStream. + *
+         * OtherRevocationInfoFormat ::= SEQUENCE {
+         *      otherRevInfoFormat OBJECT IDENTIFIER,
+         *      otherRevInfo ANY DEFINED BY otherRevInfoFormat }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + return new DerSequence(otherRevInfoFormat, otherRevInfo); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/OtherRevocationInfoFormat.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/OtherRevocationInfoFormat.cs.meta new file mode 100644 index 0000000..25befe1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/OtherRevocationInfoFormat.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 791cfa5552bb03b4abc4e0258b81edd7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/PasswordRecipientInfo.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/PasswordRecipientInfo.cs new file mode 100644 index 0000000..596dd95 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/PasswordRecipientInfo.cs @@ -0,0 +1,127 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cms +{ + public class PasswordRecipientInfo + : Asn1Encodable + { + private readonly DerInteger version; + private readonly AlgorithmIdentifier keyDerivationAlgorithm; + private readonly AlgorithmIdentifier keyEncryptionAlgorithm; + private readonly Asn1OctetString encryptedKey; + + public PasswordRecipientInfo( + AlgorithmIdentifier keyEncryptionAlgorithm, + Asn1OctetString encryptedKey) + { + this.version = new DerInteger(0); + this.keyEncryptionAlgorithm = keyEncryptionAlgorithm; + this.encryptedKey = encryptedKey; + } + + public PasswordRecipientInfo( + AlgorithmIdentifier keyDerivationAlgorithm, + AlgorithmIdentifier keyEncryptionAlgorithm, + Asn1OctetString encryptedKey) + { + this.version = new DerInteger(0); + this.keyDerivationAlgorithm = keyDerivationAlgorithm; + this.keyEncryptionAlgorithm = keyEncryptionAlgorithm; + this.encryptedKey = encryptedKey; + } + + public PasswordRecipientInfo( + Asn1Sequence seq) + { + version = (DerInteger) seq[0]; + + if (seq[1] is Asn1TaggedObject) + { + keyDerivationAlgorithm = AlgorithmIdentifier.GetInstance((Asn1TaggedObject) seq[1], false); + keyEncryptionAlgorithm = AlgorithmIdentifier.GetInstance(seq[2]); + encryptedKey = (Asn1OctetString) seq[3]; + } + else + { + keyEncryptionAlgorithm = AlgorithmIdentifier.GetInstance(seq[1]); + encryptedKey = (Asn1OctetString) seq[2]; + } + } + + /** + * return a PasswordRecipientInfo object from a tagged object. + * + * @param obj the tagged object holding the object we want. + * @param explicitly true if the object is meant to be explicitly + * tagged false otherwise. + * @exception ArgumentException if the object held by the + * tagged object cannot be converted. + */ + public static PasswordRecipientInfo GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + /** + * return a PasswordRecipientInfo object from the given object. + * + * @param obj the object we want converted. + * @exception ArgumentException if the object cannot be converted. + */ + public static PasswordRecipientInfo GetInstance( + object obj) + { + if (obj == null || obj is PasswordRecipientInfo) + return (PasswordRecipientInfo) obj; + + if (obj is Asn1Sequence) + return new PasswordRecipientInfo((Asn1Sequence) obj); + + throw new ArgumentException("Invalid PasswordRecipientInfo: " + Platform.GetTypeName(obj)); + } + + public DerInteger Version + { + get { return version; } + } + + public AlgorithmIdentifier KeyDerivationAlgorithm + { + get { return keyDerivationAlgorithm; } + } + + public AlgorithmIdentifier KeyEncryptionAlgorithm + { + get { return keyEncryptionAlgorithm; } + } + + public Asn1OctetString EncryptedKey + { + get { return encryptedKey; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * PasswordRecipientInfo ::= Sequence {
+         *   version CMSVersion,   -- Always set to 0
+         *   keyDerivationAlgorithm [0] KeyDerivationAlgorithmIdentifier
+         *                             OPTIONAL,
+         *  keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier,
+         *  encryptedKey EncryptedKey }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(version); + v.AddOptionalTagged(false, 0, keyDerivationAlgorithm); + v.Add(keyEncryptionAlgorithm, encryptedKey); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/PasswordRecipientInfo.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/PasswordRecipientInfo.cs.meta new file mode 100644 index 0000000..7756d97 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/PasswordRecipientInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5638bed0a169f4d4f8a78fc91e82d3f2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/RecipientEncryptedKey.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/RecipientEncryptedKey.cs new file mode 100644 index 0000000..1afba4a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/RecipientEncryptedKey.cs @@ -0,0 +1,90 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cms +{ + public class RecipientEncryptedKey + : Asn1Encodable + { + private readonly KeyAgreeRecipientIdentifier identifier; + private readonly Asn1OctetString encryptedKey; + + private RecipientEncryptedKey( + Asn1Sequence seq) + { + identifier = KeyAgreeRecipientIdentifier.GetInstance(seq[0]); + encryptedKey = (Asn1OctetString) seq[1]; + } + + /** + * return an RecipientEncryptedKey object from a tagged object. + * + * @param obj the tagged object holding the object we want. + * @param isExplicit true if the object is meant to be explicitly + * tagged false otherwise. + * @exception ArgumentException if the object held by the + * tagged object cannot be converted. + */ + public static RecipientEncryptedKey GetInstance( + Asn1TaggedObject obj, + bool isExplicit) + { + return GetInstance(Asn1Sequence.GetInstance(obj, isExplicit)); + } + + /** + * return a RecipientEncryptedKey object from the given object. + * + * @param obj the object we want converted. + * @exception ArgumentException if the object cannot be converted. + */ + public static RecipientEncryptedKey GetInstance( + object obj) + { + if (obj == null || obj is RecipientEncryptedKey) + { + return (RecipientEncryptedKey) obj; + } + + if (obj is Asn1Sequence) + { + return new RecipientEncryptedKey((Asn1Sequence) obj); + } + + throw new ArgumentException("Invalid RecipientEncryptedKey: " + Platform.GetTypeName(obj), "obj"); + } + + public RecipientEncryptedKey( + KeyAgreeRecipientIdentifier id, + Asn1OctetString encryptedKey) + { + this.identifier = id; + this.encryptedKey = encryptedKey; + } + + public KeyAgreeRecipientIdentifier Identifier + { + get { return identifier; } + } + + public Asn1OctetString EncryptedKey + { + get { return encryptedKey; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+		 * RecipientEncryptedKey ::= SEQUENCE {
+		 *     rid KeyAgreeRecipientIdentifier,
+		 *     encryptedKey EncryptedKey
+		 * }
+		 * 
+ */ + public override Asn1Object ToAsn1Object() + { + return new DerSequence(identifier, encryptedKey); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/RecipientEncryptedKey.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/RecipientEncryptedKey.cs.meta new file mode 100644 index 0000000..33ffbd8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/RecipientEncryptedKey.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c288d9338f290f643869110cae5edda4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/RecipientIdentifier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/RecipientIdentifier.cs new file mode 100644 index 0000000..f29fa8d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/RecipientIdentifier.cs @@ -0,0 +1,89 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cms +{ + public class RecipientIdentifier + : Asn1Encodable, IAsn1Choice + { + private Asn1Encodable id; + + public RecipientIdentifier( + IssuerAndSerialNumber id) + { + this.id = id; + } + + public RecipientIdentifier( + Asn1OctetString id) + { + this.id = new DerTaggedObject(false, 0, id); + } + + public RecipientIdentifier( + Asn1Object id) + { + this.id = id; + } + + /** + * return a RecipientIdentifier object from the given object. + * + * @param o the object we want converted. + * @exception ArgumentException if the object cannot be converted. + */ + public static RecipientIdentifier GetInstance( + object o) + { + if (o == null || o is RecipientIdentifier) + return (RecipientIdentifier)o; + + if (o is IssuerAndSerialNumber) + return new RecipientIdentifier((IssuerAndSerialNumber) o); + + if (o is Asn1OctetString) + return new RecipientIdentifier((Asn1OctetString) o); + + if (o is Asn1Object) + return new RecipientIdentifier((Asn1Object) o); + + throw new ArgumentException( + "Illegal object in RecipientIdentifier: " + Platform.GetTypeName(o)); + } + + public bool IsTagged + { + get { return (id is Asn1TaggedObject); } + } + + public Asn1Encodable ID + { + get + { + if (id is Asn1TaggedObject) + { + return Asn1OctetString.GetInstance((Asn1TaggedObject) id, false); + } + + return IssuerAndSerialNumber.GetInstance(id); + } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * RecipientIdentifier ::= CHOICE {
+         *     issuerAndSerialNumber IssuerAndSerialNumber,
+         *     subjectKeyIdentifier [0] SubjectKeyIdentifier
+         * }
+         *
+         * SubjectKeyIdentifier ::= OCTET STRING
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + return id.ToAsn1Object(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/RecipientIdentifier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/RecipientIdentifier.cs.meta new file mode 100644 index 0000000..57caa67 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/RecipientIdentifier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3e8b984fad4560746a16f25f0f6b17ea +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/RecipientInfo.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/RecipientInfo.cs new file mode 100644 index 0000000..c03ad90 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/RecipientInfo.cs @@ -0,0 +1,145 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cms +{ + public class RecipientInfo + : Asn1Encodable, IAsn1Choice + { + internal Asn1Encodable info; + + public RecipientInfo( + KeyTransRecipientInfo info) + { + this.info = info; + } + + public RecipientInfo( + KeyAgreeRecipientInfo info) + { + this.info = new DerTaggedObject(false, 1, info); + } + + public RecipientInfo( + KekRecipientInfo info) + { + this.info = new DerTaggedObject(false, 2, info); + } + + public RecipientInfo( + PasswordRecipientInfo info) + { + this.info = new DerTaggedObject(false, 3, info); + } + + public RecipientInfo( + OtherRecipientInfo info) + { + this.info = new DerTaggedObject(false, 4, info); + } + + public RecipientInfo( + Asn1Object info) + { + this.info = info; + } + + public static RecipientInfo GetInstance( + object o) + { + if (o == null || o is RecipientInfo) + return (RecipientInfo) o; + + if (o is Asn1Sequence) + return new RecipientInfo((Asn1Sequence) o); + + if (o is Asn1TaggedObject) + return new RecipientInfo((Asn1TaggedObject) o); + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(o)); + } + + public DerInteger Version + { + get + { + if (info is Asn1TaggedObject) + { + Asn1TaggedObject o = (Asn1TaggedObject) info; + + switch (o.TagNo) + { + case 1: + return KeyAgreeRecipientInfo.GetInstance(o, false).Version; + case 2: + return GetKekInfo(o).Version; + case 3: + return PasswordRecipientInfo.GetInstance(o, false).Version; + case 4: + return new DerInteger(0); // no syntax version for OtherRecipientInfo + default: + throw new InvalidOperationException("unknown tag"); + } + } + + return KeyTransRecipientInfo.GetInstance(info).Version; + } + } + + public bool IsTagged + { + get { return info is Asn1TaggedObject; } + } + + public Asn1Encodable Info + { + get + { + if (info is Asn1TaggedObject) + { + Asn1TaggedObject o = (Asn1TaggedObject) info; + + switch (o.TagNo) + { + case 1: + return KeyAgreeRecipientInfo.GetInstance(o, false); + case 2: + return GetKekInfo(o); + case 3: + return PasswordRecipientInfo.GetInstance(o, false); + case 4: + return OtherRecipientInfo.GetInstance(o, false); + default: + throw new InvalidOperationException("unknown tag"); + } + } + + return KeyTransRecipientInfo.GetInstance(info); + } + } + + private KekRecipientInfo GetKekInfo( + Asn1TaggedObject o) + { + // For compatibility with erroneous version, we don't always pass 'false' here + return KekRecipientInfo.GetInstance(o, o.IsExplicit()); + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * RecipientInfo ::= CHOICE {
+         *     ktri KeyTransRecipientInfo,
+         *     kari [1] KeyAgreeRecipientInfo,
+         *     kekri [2] KekRecipientInfo,
+         *     pwri [3] PasswordRecipientInfo,
+         *     ori [4] OtherRecipientInfo }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + return info.ToAsn1Object(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/RecipientInfo.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/RecipientInfo.cs.meta new file mode 100644 index 0000000..710019f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/RecipientInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2a32ec78a8b2d054aaf371b32f91c8e6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/RecipientKeyIdentifier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/RecipientKeyIdentifier.cs new file mode 100644 index 0000000..995ddab --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/RecipientKeyIdentifier.cs @@ -0,0 +1,137 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cms +{ + public class RecipientKeyIdentifier + : Asn1Encodable + { + private Asn1OctetString subjectKeyIdentifier; + private DerGeneralizedTime date; + private OtherKeyAttribute other; + + public RecipientKeyIdentifier( + Asn1OctetString subjectKeyIdentifier, + DerGeneralizedTime date, + OtherKeyAttribute other) + { + this.subjectKeyIdentifier = subjectKeyIdentifier; + this.date = date; + this.other = other; + } + + public RecipientKeyIdentifier( + byte[] subjectKeyIdentifier) + : this(subjectKeyIdentifier, null, null) + { + } + + public RecipientKeyIdentifier( + byte[] subjectKeyIdentifier, + DerGeneralizedTime date, + OtherKeyAttribute other) + { + this.subjectKeyIdentifier = new DerOctetString(subjectKeyIdentifier); + this.date = date; + this.other = other; + } + + public RecipientKeyIdentifier( + Asn1Sequence seq) + { + subjectKeyIdentifier = Asn1OctetString.GetInstance( + seq[0]); + + switch(seq.Count) + { + case 1: + break; + case 2: + if (seq[1] is DerGeneralizedTime) + { + date = (DerGeneralizedTime) seq[1]; + } + else + { + other = OtherKeyAttribute.GetInstance(seq[2]); + } + break; + case 3: + date = (DerGeneralizedTime) seq[1]; + other = OtherKeyAttribute.GetInstance(seq[2]); + break; + default: + throw new ArgumentException("Invalid RecipientKeyIdentifier"); + } + } + + /** + * return a RecipientKeyIdentifier object from a tagged object. + * + * @param _ato the tagged object holding the object we want. + * @param _explicit true if the object is meant to be explicitly + * tagged false otherwise. + * @exception ArgumentException if the object held by the + * tagged object cannot be converted. + */ + public static RecipientKeyIdentifier GetInstance( + Asn1TaggedObject ato, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(ato, explicitly)); + } + + /** + * return a RecipientKeyIdentifier object from the given object. + * + * @param _obj the object we want converted. + * @exception ArgumentException if the object cannot be converted. + */ + public static RecipientKeyIdentifier GetInstance( + object obj) + { + if (obj == null || obj is RecipientKeyIdentifier) + return (RecipientKeyIdentifier) obj; + + if (obj is Asn1Sequence) + return new RecipientKeyIdentifier((Asn1Sequence) obj); + + throw new ArgumentException("Invalid RecipientKeyIdentifier: " + Platform.GetTypeName(obj)); + } + + public Asn1OctetString SubjectKeyIdentifier + { + get { return subjectKeyIdentifier; } + } + + public DerGeneralizedTime Date + { + get { return date; } + } + + public OtherKeyAttribute OtherKeyAttribute + { + get { return other; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * RecipientKeyIdentifier ::= Sequence {
+         *     subjectKeyIdentifier SubjectKeyIdentifier,
+         *     date GeneralizedTime OPTIONAL,
+         *     other OtherKeyAttribute OPTIONAL
+         * }
+         *
+         * SubjectKeyIdentifier ::= OCTET STRING
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(subjectKeyIdentifier); + v.AddOptional(date, other); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/RecipientKeyIdentifier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/RecipientKeyIdentifier.cs.meta new file mode 100644 index 0000000..69527c2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/RecipientKeyIdentifier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 304ba205fb669264289f46e4250a962a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/SCVPReqRes.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/SCVPReqRes.cs new file mode 100644 index 0000000..a6ebf73 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/SCVPReqRes.cs @@ -0,0 +1,71 @@ +using System; + +namespace Org.BouncyCastle.Asn1.Cms +{ + public class ScvpReqRes + : Asn1Encodable + { + private readonly ContentInfo request; + private readonly ContentInfo response; + + public static ScvpReqRes GetInstance(object obj) + { + if (obj is ScvpReqRes) + return (ScvpReqRes)obj; + if (obj != null) + return new ScvpReqRes(Asn1Sequence.GetInstance(obj)); + return null; + } + + private ScvpReqRes(Asn1Sequence seq) + { + if (seq[0] is Asn1TaggedObject) + { + this.request = ContentInfo.GetInstance(Asn1TaggedObject.GetInstance(seq[0]), true); + this.response = ContentInfo.GetInstance(seq[1]); + } + else + { + this.request = null; + this.response = ContentInfo.GetInstance(seq[0]); + } + } + + public ScvpReqRes(ContentInfo response) + : this(null, response) + { + } + + public ScvpReqRes(ContentInfo request, ContentInfo response) + { + this.request = request; + this.response = response; + } + + public virtual ContentInfo Request + { + get { return request; } + } + + public virtual ContentInfo Response + { + get { return response; } + } + + /** + *
+         *    ScvpReqRes ::= SEQUENCE {
+         *    request  [0] EXPLICIT ContentInfo OPTIONAL,
+         *    response     ContentInfo }
+         * 
+ * @return the ASN.1 primitive representation. + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + v.AddOptionalTagged(true, 0, request); + v.Add(response); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/SCVPReqRes.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/SCVPReqRes.cs.meta new file mode 100644 index 0000000..3e25607 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/SCVPReqRes.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b8b7f860e294ab647810f80d5ef4a0c7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/SignedData.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/SignedData.cs new file mode 100644 index 0000000..1e97346 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/SignedData.cs @@ -0,0 +1,284 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cms +{ + /** + * a signed data object. + */ + public class SignedData + : Asn1Encodable + { + private static readonly DerInteger Version1 = new DerInteger(1); + private static readonly DerInteger Version3 = new DerInteger(3); + private static readonly DerInteger Version4 = new DerInteger(4); + private static readonly DerInteger Version5 = new DerInteger(5); + + private readonly DerInteger version; + private readonly Asn1Set digestAlgorithms; + private readonly ContentInfo contentInfo; + private readonly Asn1Set certificates; + private readonly Asn1Set crls; + private readonly Asn1Set signerInfos; + private readonly bool certsBer; + private readonly bool crlsBer; + + public static SignedData GetInstance(object obj) + { + if (obj is SignedData) + return (SignedData)obj; + if (obj == null) + return null; + return new SignedData(Asn1Sequence.GetInstance(obj)); + } + + public SignedData( + Asn1Set digestAlgorithms, + ContentInfo contentInfo, + Asn1Set certificates, + Asn1Set crls, + Asn1Set signerInfos) + { + this.version = CalculateVersion(contentInfo.ContentType, certificates, crls, signerInfos); + this.digestAlgorithms = digestAlgorithms; + this.contentInfo = contentInfo; + this.certificates = certificates; + this.crls = crls; + this.signerInfos = signerInfos; + this.crlsBer = crls is BerSet; + this.certsBer = certificates is BerSet; + } + + // RFC3852, section 5.1: + // IF ((certificates is present) AND + // (any certificates with a type of other are present)) OR + // ((crls is present) AND + // (any crls with a type of other are present)) + // THEN version MUST be 5 + // ELSE + // IF (certificates is present) AND + // (any version 2 attribute certificates are present) + // THEN version MUST be 4 + // ELSE + // IF ((certificates is present) AND + // (any version 1 attribute certificates are present)) OR + // (any SignerInfo structures are version 3) OR + // (encapContentInfo eContentType is other than id-data) + // THEN version MUST be 3 + // ELSE version MUST be 1 + // + private DerInteger CalculateVersion( + DerObjectIdentifier contentOid, + Asn1Set certs, + Asn1Set crls, + Asn1Set signerInfs) + { + bool otherCert = false; + bool otherCrl = false; + bool attrCertV1Found = false; + bool attrCertV2Found = false; + + if (certs != null) + { + foreach (object obj in certs) + { + if (obj is Asn1TaggedObject) + { + Asn1TaggedObject tagged = (Asn1TaggedObject)obj; + + if (tagged.TagNo == 1) + { + attrCertV1Found = true; + } + else if (tagged.TagNo == 2) + { + attrCertV2Found = true; + } + else if (tagged.TagNo == 3) + { + otherCert = true; + break; + } + } + } + } + + if (otherCert) + { + return Version5; + } + + if (crls != null) + { + foreach (object obj in crls) + { + if (obj is Asn1TaggedObject) + { + otherCrl = true; + break; + } + } + } + + if (otherCrl) + { + return Version5; + } + + if (attrCertV2Found) + { + return Version4; + } + + if (attrCertV1Found || !CmsObjectIdentifiers.Data.Equals(contentOid) || CheckForVersion3(signerInfs)) + { + return Version3; + } + + return Version1; + } + + private bool CheckForVersion3( + Asn1Set signerInfs) + { + foreach (object obj in signerInfs) + { + SignerInfo s = SignerInfo.GetInstance(obj); + + if (s.Version.HasValue(3)) + { + return true; + } + } + + return false; + } + + private SignedData( + Asn1Sequence seq) + { + IEnumerator e = seq.GetEnumerator(); + + e.MoveNext(); + version = (DerInteger)e.Current; + + e.MoveNext(); + digestAlgorithms = ((Asn1Set)e.Current); + + e.MoveNext(); + contentInfo = ContentInfo.GetInstance(e.Current); + + while (e.MoveNext()) + { + Asn1Object o = (Asn1Object)e.Current; + + // + // an interesting feature of SignedData is that there appear + // to be varying implementations... + // for the moment we ignore anything which doesn't fit. + // + if (o is Asn1TaggedObject) + { + Asn1TaggedObject tagged = (Asn1TaggedObject)o; + + switch (tagged.TagNo) + { + case 0: + certsBer = tagged is BerTaggedObject; + certificates = Asn1Set.GetInstance(tagged, false); + break; + case 1: + crlsBer = tagged is BerTaggedObject; + crls = Asn1Set.GetInstance(tagged, false); + break; + default: + throw new ArgumentException("unknown tag value " + tagged.TagNo); + } + } + else + { + signerInfos = (Asn1Set) o; + } + } + } + + public DerInteger Version + { + get { return version; } + } + + public Asn1Set DigestAlgorithms + { + get { return digestAlgorithms; } + } + + public ContentInfo EncapContentInfo + { + get { return contentInfo; } + } + + public Asn1Set Certificates + { + get { return certificates; } + } + + public Asn1Set CRLs + { + get { return crls; } + } + + public Asn1Set SignerInfos + { + get { return signerInfos; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * SignedData ::= Sequence {
+         *     version CMSVersion,
+         *     digestAlgorithms DigestAlgorithmIdentifiers,
+         *     encapContentInfo EncapsulatedContentInfo,
+         *     certificates [0] IMPLICIT CertificateSet OPTIONAL,
+         *     crls [1] IMPLICIT CertificateRevocationLists OPTIONAL,
+         *     signerInfos SignerInfos
+         *   }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector( + version, digestAlgorithms, contentInfo); + + if (certificates != null) + { + if (certsBer) + { + v.Add(new BerTaggedObject(false, 0, certificates)); + } + else + { + v.Add(new DerTaggedObject(false, 0, certificates)); + } + } + + if (crls != null) + { + if (crlsBer) + { + v.Add(new BerTaggedObject(false, 1, crls)); + } + else + { + v.Add(new DerTaggedObject(false, 1, crls)); + } + } + + v.Add(signerInfos); + + return new BerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/SignedData.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/SignedData.cs.meta new file mode 100644 index 0000000..8719563 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/SignedData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: be9465ba0fabaef4695c02ae84d2855a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/SignedDataParser.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/SignedDataParser.cs new file mode 100644 index 0000000..cd07f40 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/SignedDataParser.cs @@ -0,0 +1,114 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cms +{ + /** + *
+	* SignedData ::= SEQUENCE {
+	*     version CMSVersion,
+	*     digestAlgorithms DigestAlgorithmIdentifiers,
+	*     encapContentInfo EncapsulatedContentInfo,
+	*     certificates [0] IMPLICIT CertificateSet OPTIONAL,
+	*     crls [1] IMPLICIT CertificateRevocationLists OPTIONAL,
+	*     signerInfos SignerInfos
+	*   }
+	* 
+ */ + public class SignedDataParser + { + private Asn1SequenceParser _seq; + private DerInteger _version; + private object _nextObject; + private bool _certsCalled; + private bool _crlsCalled; + + public static SignedDataParser GetInstance( + object o) + { + if (o is Asn1Sequence) + return new SignedDataParser(((Asn1Sequence)o).Parser); + + if (o is Asn1SequenceParser) + return new SignedDataParser((Asn1SequenceParser)o); + + throw new IOException("unknown object encountered: " + Platform.GetTypeName(o)); + } + + public SignedDataParser( + Asn1SequenceParser seq) + { + this._seq = seq; + this._version = (DerInteger)seq.ReadObject(); + } + + public DerInteger Version + { + get { return _version; } + } + + public Asn1SetParser GetDigestAlgorithms() + { + return (Asn1SetParser)_seq.ReadObject(); + } + + public ContentInfoParser GetEncapContentInfo() + { + return new ContentInfoParser((Asn1SequenceParser)_seq.ReadObject()); + } + + public Asn1SetParser GetCertificates() + { + _certsCalled = true; + _nextObject = _seq.ReadObject(); + + if (_nextObject is Asn1TaggedObjectParser && ((Asn1TaggedObjectParser)_nextObject).TagNo == 0) + { + Asn1SetParser certs = (Asn1SetParser)((Asn1TaggedObjectParser)_nextObject).GetObjectParser(Asn1Tags.Set, false); + _nextObject = null; + + return certs; + } + + return null; + } + + public Asn1SetParser GetCrls() + { + if (!_certsCalled) + throw new IOException("GetCerts() has not been called."); + + _crlsCalled = true; + + if (_nextObject == null) + { + _nextObject = _seq.ReadObject(); + } + + if (_nextObject is Asn1TaggedObjectParser && ((Asn1TaggedObjectParser)_nextObject).TagNo == 1) + { + Asn1SetParser crls = (Asn1SetParser)((Asn1TaggedObjectParser)_nextObject).GetObjectParser(Asn1Tags.Set, false); + _nextObject = null; + + return crls; + } + + return null; + } + + public Asn1SetParser GetSignerInfos() + { + if (!_certsCalled || !_crlsCalled) + throw new IOException("GetCerts() and/or GetCrls() has not been called."); + + if (_nextObject == null) + { + _nextObject = _seq.ReadObject(); + } + + return (Asn1SetParser)_nextObject; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/SignedDataParser.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/SignedDataParser.cs.meta new file mode 100644 index 0000000..580f3da --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/SignedDataParser.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c4d86d6d7b9f11145a541c755ebaa697 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/SignerIdentifier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/SignerIdentifier.cs new file mode 100644 index 0000000..195ab74 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/SignerIdentifier.cs @@ -0,0 +1,89 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cms +{ + public class SignerIdentifier + : Asn1Encodable, IAsn1Choice + { + private Asn1Encodable id; + + public SignerIdentifier( + IssuerAndSerialNumber id) + { + this.id = id; + } + + public SignerIdentifier( + Asn1OctetString id) + { + this.id = new DerTaggedObject(false, 0, id); + } + + public SignerIdentifier( + Asn1Object id) + { + this.id = id; + } + + /** + * return a SignerIdentifier object from the given object. + * + * @param o the object we want converted. + * @exception ArgumentException if the object cannot be converted. + */ + public static SignerIdentifier GetInstance( + object o) + { + if (o == null || o is SignerIdentifier) + return (SignerIdentifier) o; + + if (o is IssuerAndSerialNumber) + return new SignerIdentifier((IssuerAndSerialNumber) o); + + if (o is Asn1OctetString) + return new SignerIdentifier((Asn1OctetString) o); + + if (o is Asn1Object) + return new SignerIdentifier((Asn1Object) o); + + throw new ArgumentException( + "Illegal object in SignerIdentifier: " + Platform.GetTypeName(o)); + } + + public bool IsTagged + { + get { return (id is Asn1TaggedObject); } + } + + public Asn1Encodable ID + { + get + { + if (id is Asn1TaggedObject) + { + return Asn1OctetString.GetInstance((Asn1TaggedObject)id, false); + } + + return id; + } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * SignerIdentifier ::= CHOICE {
+         *     issuerAndSerialNumber IssuerAndSerialNumber,
+         *     subjectKeyIdentifier [0] SubjectKeyIdentifier
+         * }
+         *
+         * SubjectKeyIdentifier ::= OCTET STRING
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + return id.ToAsn1Object(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/SignerIdentifier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/SignerIdentifier.cs.meta new file mode 100644 index 0000000..f2279bb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/SignerIdentifier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3b9862c951a01e84cac2b913f88e5960 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/SignerInfo.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/SignerInfo.cs new file mode 100644 index 0000000..44d4dcf --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/SignerInfo.cs @@ -0,0 +1,174 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cms +{ + public class SignerInfo + : Asn1Encodable + { + private DerInteger version; + private SignerIdentifier sid; + private AlgorithmIdentifier digAlgorithm; + private Asn1Set authenticatedAttributes; + private AlgorithmIdentifier digEncryptionAlgorithm; + private Asn1OctetString encryptedDigest; + private Asn1Set unauthenticatedAttributes; + + public static SignerInfo GetInstance( + object obj) + { + if (obj == null || obj is SignerInfo) + return (SignerInfo) obj; + + if (obj is Asn1Sequence) + return new SignerInfo((Asn1Sequence) obj); + + throw new ArgumentException("Unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + public SignerInfo( + SignerIdentifier sid, + AlgorithmIdentifier digAlgorithm, + Asn1Set authenticatedAttributes, + AlgorithmIdentifier digEncryptionAlgorithm, + Asn1OctetString encryptedDigest, + Asn1Set unauthenticatedAttributes) + { + this.version = new DerInteger(sid.IsTagged ? 3 : 1); + this.sid = sid; + this.digAlgorithm = digAlgorithm; + this.authenticatedAttributes = authenticatedAttributes; + this.digEncryptionAlgorithm = digEncryptionAlgorithm; + this.encryptedDigest = encryptedDigest; + this.unauthenticatedAttributes = unauthenticatedAttributes; + } + + public SignerInfo( + SignerIdentifier sid, + AlgorithmIdentifier digAlgorithm, + Attributes authenticatedAttributes, + AlgorithmIdentifier digEncryptionAlgorithm, + Asn1OctetString encryptedDigest, + Attributes unauthenticatedAttributes) + { + this.version = new DerInteger(sid.IsTagged ? 3 : 1); + this.sid = sid; + this.digAlgorithm = digAlgorithm; + this.authenticatedAttributes = Asn1Set.GetInstance(authenticatedAttributes); + this.digEncryptionAlgorithm = digEncryptionAlgorithm; + this.encryptedDigest = encryptedDigest; + this.unauthenticatedAttributes = Asn1Set.GetInstance(unauthenticatedAttributes); + } + + [Obsolete("Use 'GetInstance' instead")] + public SignerInfo( + Asn1Sequence seq) + { + IEnumerator e = seq.GetEnumerator(); + + e.MoveNext(); + version = (DerInteger) e.Current; + + e.MoveNext(); + sid = SignerIdentifier.GetInstance(e.Current); + + e.MoveNext(); + digAlgorithm = AlgorithmIdentifier.GetInstance(e.Current); + + e.MoveNext(); + object obj = e.Current; + + if (obj is Asn1TaggedObject) + { + authenticatedAttributes = Asn1Set.GetInstance((Asn1TaggedObject) obj, false); + + e.MoveNext(); + digEncryptionAlgorithm = AlgorithmIdentifier.GetInstance(e.Current); + } + else + { + authenticatedAttributes = null; + digEncryptionAlgorithm = AlgorithmIdentifier.GetInstance(obj); + } + + e.MoveNext(); + encryptedDigest = DerOctetString.GetInstance(e.Current); + + if (e.MoveNext()) + { + unauthenticatedAttributes = Asn1Set.GetInstance((Asn1TaggedObject) e.Current, false); + } + else + { + unauthenticatedAttributes = null; + } + } + + public DerInteger Version + { + get { return version; } + } + + public SignerIdentifier SignerID + { + get { return sid; } + } + + public Asn1Set AuthenticatedAttributes + { + get { return authenticatedAttributes; } + } + + public AlgorithmIdentifier DigestAlgorithm + { + get { return digAlgorithm; } + } + + public Asn1OctetString EncryptedDigest + { + get { return encryptedDigest; } + } + + public AlgorithmIdentifier DigestEncryptionAlgorithm + { + get { return digEncryptionAlgorithm; } + } + + public Asn1Set UnauthenticatedAttributes + { + get { return unauthenticatedAttributes; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         *  SignerInfo ::= Sequence {
+         *      version Version,
+         *      SignerIdentifier sid,
+         *      digestAlgorithm DigestAlgorithmIdentifier,
+         *      authenticatedAttributes [0] IMPLICIT Attributes OPTIONAL,
+         *      digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier,
+         *      encryptedDigest EncryptedDigest,
+         *      unauthenticatedAttributes [1] IMPLICIT Attributes OPTIONAL
+         *  }
+         *
+         *  EncryptedDigest ::= OCTET STRING
+         *
+         *  DigestAlgorithmIdentifier ::= AlgorithmIdentifier
+         *
+         *  DigestEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(version, sid, digAlgorithm); + v.AddOptionalTagged(false, 0, authenticatedAttributes); + v.Add(digEncryptionAlgorithm, encryptedDigest); + v.AddOptionalTagged(false, 1, unauthenticatedAttributes); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/SignerInfo.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/SignerInfo.cs.meta new file mode 100644 index 0000000..93fe799 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/SignerInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fd1cbe25c0cfdb644833a99175a554f1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/Time.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/Time.cs new file mode 100644 index 0000000..52fb4f9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/Time.cs @@ -0,0 +1,115 @@ +using System; +using System.Globalization; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cms +{ + public class Time + : Asn1Encodable, IAsn1Choice + { + private readonly Asn1Object time; + + public static Time GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(obj.GetObject()); + } + + public Time( + Asn1Object time) + { + if (time == null) + throw new ArgumentNullException("time"); + if (!(time is DerUtcTime) && !(time is DerGeneralizedTime)) + throw new ArgumentException("unknown object passed to Time"); + + this.time = time; + } + + /** + * creates a time object from a given date - if the date is between 1950 + * and 2049 a UTCTime object is Generated, otherwise a GeneralizedTime + * is used. + */ + public Time( + DateTime date) + { + string d = date.ToString("yyyyMMddHHmmss", CultureInfo.InvariantCulture) + "Z"; + + int year = int.Parse(d.Substring(0, 4)); + + if (year < 1950 || year > 2049) + { + time = new DerGeneralizedTime(d); + } + else + { + time = new DerUtcTime(d.Substring(2)); + } + } + + public static Time GetInstance( + object obj) + { + if (obj == null || obj is Time) + return (Time)obj; + if (obj is DerUtcTime) + return new Time((DerUtcTime)obj); + if (obj is DerGeneralizedTime) + return new Time((DerGeneralizedTime)obj); + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + public string TimeString + { + get + { + if (time is DerUtcTime) + { + return ((DerUtcTime)time).AdjustedTimeString; + } + else + { + return ((DerGeneralizedTime)time).GetTime(); + } + } + } + + public DateTime Date + { + get + { + try + { + if (time is DerUtcTime) + { + return ((DerUtcTime)time).ToAdjustedDateTime(); + } + + return ((DerGeneralizedTime)time).ToDateTime(); + } + catch (FormatException e) + { + // this should never happen + throw new InvalidOperationException("invalid date string: " + e.Message); + } + } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * Time ::= CHOICE {
+         *             utcTime        UTCTime,
+         *             generalTime    GeneralizedTime }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + return time; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/Time.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/Time.cs.meta new file mode 100644 index 0000000..f1b0434 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/Time.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 59992c59e7bebe24d926342f9e0c3cd2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/TimeStampAndCRL.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/TimeStampAndCRL.cs new file mode 100644 index 0000000..4cb5f2a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/TimeStampAndCRL.cs @@ -0,0 +1,62 @@ +using System; + +namespace Org.BouncyCastle.Asn1.Cms +{ + public class TimeStampAndCrl + : Asn1Encodable + { + private ContentInfo timeStamp; + private X509.CertificateList crl; + + public TimeStampAndCrl(ContentInfo timeStamp) + { + this.timeStamp = timeStamp; + } + + private TimeStampAndCrl(Asn1Sequence seq) + { + this.timeStamp = ContentInfo.GetInstance(seq[0]); + if (seq.Count == 2) + { + this.crl = X509.CertificateList.GetInstance(seq[1]); + } + } + + public static TimeStampAndCrl GetInstance(object obj) + { + if (obj is TimeStampAndCrl) + return (TimeStampAndCrl)obj; + + if (obj != null) + return new TimeStampAndCrl(Asn1Sequence.GetInstance(obj)); + + return null; + } + + public virtual ContentInfo TimeStampToken + { + get { return this.timeStamp; } + } + + public virtual X509.CertificateList Crl + { + get { return this.crl; } + } + + /** + *
+		 * TimeStampAndCRL ::= SEQUENCE {
+		 *     timeStamp   TimeStampToken,          -- according to RFC 3161
+		 *     crl         CertificateList OPTIONAL -- according to RFC 5280
+		 *  }
+		 * 
+ * @return + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(timeStamp); + v.AddOptional(crl); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/TimeStampAndCRL.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/TimeStampAndCRL.cs.meta new file mode 100644 index 0000000..137df88 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/TimeStampAndCRL.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8fb81f15c679d8644b50bbdb654b1a21 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/TimeStampTokenEvidence.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/TimeStampTokenEvidence.cs new file mode 100644 index 0000000..8625d05 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/TimeStampTokenEvidence.cs @@ -0,0 +1,65 @@ +using System; + +namespace Org.BouncyCastle.Asn1.Cms +{ + public class TimeStampTokenEvidence + : Asn1Encodable + { + private TimeStampAndCrl[] timeStampAndCrls; + + public TimeStampTokenEvidence(TimeStampAndCrl[] timeStampAndCrls) + { + this.timeStampAndCrls = timeStampAndCrls; + } + + public TimeStampTokenEvidence(TimeStampAndCrl timeStampAndCrl) + { + this.timeStampAndCrls = new TimeStampAndCrl[]{ timeStampAndCrl }; + } + + private TimeStampTokenEvidence(Asn1Sequence seq) + { + this.timeStampAndCrls = new TimeStampAndCrl[seq.Count]; + + int count = 0; + + foreach (Asn1Encodable ae in seq) + { + this.timeStampAndCrls[count++] = TimeStampAndCrl.GetInstance(ae.ToAsn1Object()); + } + } + + public static TimeStampTokenEvidence GetInstance(Asn1TaggedObject tagged, bool isExplicit) + { + return GetInstance(Asn1Sequence.GetInstance(tagged, isExplicit)); + } + + public static TimeStampTokenEvidence GetInstance(object obj) + { + if (obj is TimeStampTokenEvidence) + return (TimeStampTokenEvidence)obj; + + if (obj != null) + return new TimeStampTokenEvidence(Asn1Sequence.GetInstance(obj)); + + return null; + } + + public virtual TimeStampAndCrl[] ToTimeStampAndCrlArray() + { + return (TimeStampAndCrl[])timeStampAndCrls.Clone(); + } + + /** + *
+		 * TimeStampTokenEvidence ::=
+		 *    SEQUENCE SIZE(1..MAX) OF TimeStampAndCrl
+		 * 
+ * @return + */ + public override Asn1Object ToAsn1Object() + { + return new DerSequence(timeStampAndCrls); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/TimeStampTokenEvidence.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/TimeStampTokenEvidence.cs.meta new file mode 100644 index 0000000..91e794a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/TimeStampTokenEvidence.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6a93155cb8aec0440ad5f8cf792a4c81 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/TimeStampedData.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/TimeStampedData.cs new file mode 100644 index 0000000..15448a9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/TimeStampedData.cs @@ -0,0 +1,95 @@ +using System; + +namespace Org.BouncyCastle.Asn1.Cms +{ + public class TimeStampedData + : Asn1Encodable + { + private DerInteger version; + private DerIA5String dataUri; + private MetaData metaData; + private Asn1OctetString content; + private Evidence temporalEvidence; + + public TimeStampedData(DerIA5String dataUri, MetaData metaData, Asn1OctetString content, + Evidence temporalEvidence) + { + this.version = new DerInteger(1); + this.dataUri = dataUri; + this.metaData = metaData; + this.content = content; + this.temporalEvidence = temporalEvidence; + } + + private TimeStampedData(Asn1Sequence seq) + { + this.version = DerInteger.GetInstance(seq[0]); + + int index = 1; + if (seq[index] is DerIA5String) + { + this.dataUri = DerIA5String.GetInstance(seq[index++]); + } + if (seq[index] is MetaData || seq[index] is Asn1Sequence) + { + this.metaData = MetaData.GetInstance(seq[index++]); + } + if (seq[index] is Asn1OctetString) + { + this.content = Asn1OctetString.GetInstance(seq[index++]); + } + this.temporalEvidence = Evidence.GetInstance(seq[index]); + } + + public static TimeStampedData GetInstance(object obj) + { + if (obj is TimeStampedData) + return (TimeStampedData)obj; + + if (obj != null) + return new TimeStampedData(Asn1Sequence.GetInstance(obj)); + + return null; + } + + public virtual DerIA5String DataUri + { + get { return dataUri; } + } + + public MetaData MetaData + { + get { return metaData; } + } + + public Asn1OctetString Content + { + get { return content; } + } + + public Evidence TemporalEvidence + { + get { return temporalEvidence; } + } + + /** + *
+		 * TimeStampedData ::= SEQUENCE {
+		 *   version              INTEGER { v1(1) },
+		 *   dataUri              IA5String OPTIONAL,
+		 *   metaData             MetaData OPTIONAL,
+		 *   content              OCTET STRING OPTIONAL,
+		 *   temporalEvidence     Evidence
+		 * }
+		 * 
+ * @return + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(version); + v.AddOptional(dataUri, metaData, content); + v.Add(temporalEvidence); + return new BerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/TimeStampedData.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/TimeStampedData.cs.meta new file mode 100644 index 0000000..e582449 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/TimeStampedData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6a4524d4586a8144686ff111d76e0f7f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/TimeStampedDataParser.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/TimeStampedDataParser.cs new file mode 100644 index 0000000..90307bf --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/TimeStampedDataParser.cs @@ -0,0 +1,76 @@ +using System; + +namespace Org.BouncyCastle.Asn1.Cms +{ + public class TimeStampedDataParser + { + private DerInteger version; + private DerIA5String dataUri; + private MetaData metaData; + private Asn1OctetStringParser content; + private Evidence temporalEvidence; + private Asn1SequenceParser parser; + + private TimeStampedDataParser(Asn1SequenceParser parser) + { + this.parser = parser; + this.version = DerInteger.GetInstance(parser.ReadObject()); + + Asn1Object obj = parser.ReadObject().ToAsn1Object(); + + if (obj is DerIA5String) + { + this.dataUri = DerIA5String.GetInstance(obj); + obj = parser.ReadObject().ToAsn1Object(); + } + + if (//obj is MetaData || + obj is Asn1SequenceParser) + { + this.metaData = MetaData.GetInstance(obj.ToAsn1Object()); + obj = parser.ReadObject().ToAsn1Object(); + } + + if (obj is Asn1OctetStringParser) + { + this.content = (Asn1OctetStringParser)obj; + } + } + + public static TimeStampedDataParser GetInstance(object obj) + { + if (obj is Asn1Sequence) + return new TimeStampedDataParser(((Asn1Sequence)obj).Parser); + + if (obj is Asn1SequenceParser) + return new TimeStampedDataParser((Asn1SequenceParser)obj); + + return null; + } + + public virtual DerIA5String DataUri + { + get { return dataUri; } + } + + public virtual MetaData MetaData + { + get { return metaData; } + } + + public virtual Asn1OctetStringParser Content + { + get { return content; } + } + + public virtual Evidence GetTemporalEvidence() + { + if (temporalEvidence == null) + { + temporalEvidence = Evidence.GetInstance(parser.ReadObject().ToAsn1Object()); + } + + return temporalEvidence; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/TimeStampedDataParser.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/TimeStampedDataParser.cs.meta new file mode 100644 index 0000000..1ead205 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/TimeStampedDataParser.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 40d73fcce1570784081145503ca96625 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/ecc.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/ecc.meta new file mode 100644 index 0000000..e3b9aad --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/ecc.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 8c2f5f62600a46e4e814f47466892324 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/ecc/MQVuserKeyingMaterial.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/ecc/MQVuserKeyingMaterial.cs new file mode 100644 index 0000000..3a4761e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/ecc/MQVuserKeyingMaterial.cs @@ -0,0 +1,100 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cms.Ecc +{ + public class MQVuserKeyingMaterial + : Asn1Encodable + { + private OriginatorPublicKey ephemeralPublicKey; + private Asn1OctetString addedukm; + + public MQVuserKeyingMaterial( + OriginatorPublicKey ephemeralPublicKey, + Asn1OctetString addedukm) + { + // TODO Check ephemeralPublicKey not null + + this.ephemeralPublicKey = ephemeralPublicKey; + this.addedukm = addedukm; + } + + private MQVuserKeyingMaterial( + Asn1Sequence seq) + { + // TODO Check seq has either 1 or 2 elements + + this.ephemeralPublicKey = OriginatorPublicKey.GetInstance(seq[0]); + + if (seq.Count > 1) + { + this.addedukm = Asn1OctetString.GetInstance( + (Asn1TaggedObject)seq[1], true); + } + } + + /** + * return an AuthEnvelopedData object from a tagged object. + * + * @param obj the tagged object holding the object we want. + * @param isExplicit true if the object is meant to be explicitly + * tagged false otherwise. + * @throws ArgumentException if the object held by the + * tagged object cannot be converted. + */ + public static MQVuserKeyingMaterial GetInstance( + Asn1TaggedObject obj, + bool isExplicit) + { + return GetInstance(Asn1Sequence.GetInstance(obj, isExplicit)); + } + + /** + * return an AuthEnvelopedData object from the given object. + * + * @param obj the object we want converted. + * @throws ArgumentException if the object cannot be converted. + */ + public static MQVuserKeyingMaterial GetInstance( + object obj) + { + if (obj == null || obj is MQVuserKeyingMaterial) + { + return (MQVuserKeyingMaterial)obj; + } + + if (obj is Asn1Sequence) + { + return new MQVuserKeyingMaterial((Asn1Sequence)obj); + } + + throw new ArgumentException("Invalid MQVuserKeyingMaterial: " + Platform.GetTypeName(obj)); + } + + public OriginatorPublicKey EphemeralPublicKey + { + get { return ephemeralPublicKey; } + } + + public Asn1OctetString AddedUkm + { + get { return addedukm; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+		* MQVuserKeyingMaterial ::= SEQUENCE {
+		*   ephemeralPublicKey OriginatorPublicKey,
+		*   addedukm [0] EXPLICIT UserKeyingMaterial OPTIONAL  }
+		* 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(ephemeralPublicKey); + v.AddOptionalTagged(true, 0, addedukm); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/ecc/MQVuserKeyingMaterial.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/ecc/MQVuserKeyingMaterial.cs.meta new file mode 100644 index 0000000..e3d5aeb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cms/ecc/MQVuserKeyingMaterial.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fff6caa9d7e3eac4887ef5541f527281 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf.meta new file mode 100644 index 0000000..22eaf6b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 55efa214af88d3540a218279d5967924 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/AttributeTypeAndValue.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/AttributeTypeAndValue.cs new file mode 100644 index 0000000..e758789 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/AttributeTypeAndValue.cs @@ -0,0 +1,68 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Crmf +{ + public class AttributeTypeAndValue + : Asn1Encodable + { + private readonly DerObjectIdentifier type; + private readonly Asn1Encodable value; + + private AttributeTypeAndValue(Asn1Sequence seq) + { + type = (DerObjectIdentifier)seq[0]; + value = (Asn1Encodable)seq[1]; + } + + public static AttributeTypeAndValue GetInstance(object obj) + { + if (obj is AttributeTypeAndValue) + return (AttributeTypeAndValue)obj; + + if (obj is Asn1Sequence) + return new AttributeTypeAndValue((Asn1Sequence)obj); + + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + } + + public AttributeTypeAndValue( + string oid, + Asn1Encodable value) + : this(new DerObjectIdentifier(oid), value) + { + } + + public AttributeTypeAndValue( + DerObjectIdentifier type, + Asn1Encodable value) + { + this.type = type; + this.value = value; + } + + public virtual DerObjectIdentifier Type + { + get { return type; } + } + + public virtual Asn1Encodable Value + { + get { return value; } + } + + /** + *
+         * AttributeTypeAndValue ::= SEQUENCE {
+         *           type         OBJECT IDENTIFIER,
+         *           value        ANY DEFINED BY type }
+         * 
+ * @return a basic ASN.1 object representation. + */ + public override Asn1Object ToAsn1Object() + { + return new DerSequence(type, value); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/AttributeTypeAndValue.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/AttributeTypeAndValue.cs.meta new file mode 100644 index 0000000..717a8c9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/AttributeTypeAndValue.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b75e0771daddf594c9bea3f67901b5e8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/CertId.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/CertId.cs new file mode 100644 index 0000000..f0cc946 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/CertId.cs @@ -0,0 +1,59 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Crmf +{ + public class CertId + : Asn1Encodable + { + private readonly GeneralName issuer; + private readonly DerInteger serialNumber; + + private CertId(Asn1Sequence seq) + { + issuer = GeneralName.GetInstance(seq[0]); + serialNumber = DerInteger.GetInstance(seq[1]); + } + + public static CertId GetInstance(object obj) + { + if (obj is CertId) + return (CertId)obj; + + if (obj is Asn1Sequence) + return new CertId((Asn1Sequence)obj); + + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + } + + public static CertId GetInstance(Asn1TaggedObject obj, bool isExplicit) + { + return GetInstance(Asn1Sequence.GetInstance(obj, isExplicit)); + } + + public virtual GeneralName Issuer + { + get { return issuer; } + } + + public virtual DerInteger SerialNumber + { + get { return serialNumber; } + } + + /** + *
+         * CertId ::= SEQUENCE {
+         *                 issuer           GeneralName,
+         *                 serialNumber     INTEGER }
+         * 
+ * @return a basic ASN.1 object representation. + */ + public override Asn1Object ToAsn1Object() + { + return new DerSequence(issuer, serialNumber); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/CertId.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/CertId.cs.meta new file mode 100644 index 0000000..c239e43 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/CertId.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3f625b2a425bc20499164625ea36c54e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/CertReqMessages.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/CertReqMessages.cs new file mode 100644 index 0000000..422950b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/CertReqMessages.cs @@ -0,0 +1,54 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Crmf +{ + public class CertReqMessages + : Asn1Encodable + { + private readonly Asn1Sequence content; + + private CertReqMessages(Asn1Sequence seq) + { + content = seq; + } + + public static CertReqMessages GetInstance(object obj) + { + if (obj is CertReqMessages) + return (CertReqMessages)obj; + + if (obj is Asn1Sequence) + return new CertReqMessages((Asn1Sequence)obj); + + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + } + + public CertReqMessages(params CertReqMsg[] msgs) + { + content = new DerSequence(msgs); + } + + public virtual CertReqMsg[] ToCertReqMsgArray() + { + CertReqMsg[] result = new CertReqMsg[content.Count]; + for (int i = 0; i != result.Length; ++i) + { + result[i] = CertReqMsg.GetInstance(content[i]); + } + return result; + } + + /** + *
+         * CertReqMessages ::= SEQUENCE SIZE (1..MAX) OF CertReqMsg
+         * 
+ * @return a basic ASN.1 object representation. + */ + public override Asn1Object ToAsn1Object() + { + return content; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/CertReqMessages.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/CertReqMessages.cs.meta new file mode 100644 index 0000000..522fe89 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/CertReqMessages.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2e8052293a2f7bc4684d79f9172569a6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/CertReqMsg.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/CertReqMsg.cs new file mode 100644 index 0000000..03ce32d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/CertReqMsg.cs @@ -0,0 +1,112 @@ +using System; + +namespace Org.BouncyCastle.Asn1.Crmf +{ + public class CertReqMsg + : Asn1Encodable + { + private readonly CertRequest certReq; + private readonly ProofOfPossession popo; + private readonly Asn1Sequence regInfo; + + private CertReqMsg(Asn1Sequence seq) + { + certReq = CertRequest.GetInstance(seq[0]); + + for (int pos = 1; pos < seq.Count; ++pos) + { + object o = seq[pos]; + + if (o is Asn1TaggedObject || o is ProofOfPossession) + { + popo = ProofOfPossession.GetInstance(o); + } + else + { + regInfo = Asn1Sequence.GetInstance(o); + } + } + } + + public static CertReqMsg GetInstance(object obj) + { + if (obj is CertReqMsg) + return (CertReqMsg)obj; + + if (obj != null) + return new CertReqMsg(Asn1Sequence.GetInstance(obj)); + + return null; + } + + public static CertReqMsg GetInstance( + Asn1TaggedObject obj, + bool isExplicit) + { + return GetInstance(Asn1Sequence.GetInstance(obj, isExplicit)); + } + + /** + * Creates a new CertReqMsg. + * @param certReq CertRequest + * @param popo may be null + * @param regInfo may be null + */ + public CertReqMsg( + CertRequest certReq, + ProofOfPossession popo, + AttributeTypeAndValue[] regInfo) + { + if (certReq == null) + throw new ArgumentNullException("certReq"); + + this.certReq = certReq; + this.popo = popo; + + if (regInfo != null) + { + this.regInfo = new DerSequence(regInfo); + } + } + + public virtual CertRequest CertReq + { + get { return certReq; } + } + + public virtual ProofOfPossession Popo + { + get { return popo; } + } + + public virtual AttributeTypeAndValue[] GetRegInfo() + { + if (regInfo == null) + return null; + + AttributeTypeAndValue[] results = new AttributeTypeAndValue[regInfo.Count]; + for (int i = 0; i != results.Length; ++i) + { + results[i] = AttributeTypeAndValue.GetInstance(regInfo[i]); + } + return results; + } + + /** + *
+         * CertReqMsg ::= SEQUENCE {
+         *                    certReq   CertRequest,
+         *                    pop       ProofOfPossession  OPTIONAL,
+         *                    -- content depends upon key type
+         *                    regInfo   SEQUENCE SIZE(1..MAX) OF AttributeTypeAndValue OPTIONAL }
+         * 
+ * @return a basic ASN.1 object representation. + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(certReq); + v.AddOptional(popo, regInfo); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/CertReqMsg.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/CertReqMsg.cs.meta new file mode 100644 index 0000000..a19a5a0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/CertReqMsg.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7a664b473f9e41d4fa1e5531a416647c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/CertRequest.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/CertRequest.cs new file mode 100644 index 0000000..bf6182f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/CertRequest.cs @@ -0,0 +1,83 @@ +using System; +using Org.BouncyCastle.Crmf; + +namespace Org.BouncyCastle.Asn1.Crmf +{ + public class CertRequest + : Asn1Encodable + { + private readonly DerInteger certReqId; + private readonly CertTemplate certTemplate; + private readonly Controls controls; + + private CertRequest(Asn1Sequence seq) + { + certReqId = DerInteger.GetInstance(seq[0]); + certTemplate = CertTemplate.GetInstance(seq[1]); + if (seq.Count > 2) + { + controls = Controls.GetInstance(seq[2]); + } + } + + public static CertRequest GetInstance(object obj) + { + if (obj is CertRequest) + return (CertRequest)obj; + + if (obj != null) + return new CertRequest(Asn1Sequence.GetInstance(obj)); + + return null; + } + + public CertRequest( + int certReqId, + CertTemplate certTemplate, + Controls controls) + : this(new DerInteger(certReqId), certTemplate, controls) + { + } + + public CertRequest( + DerInteger certReqId, + CertTemplate certTemplate, + Controls controls) + { + this.certReqId = certReqId; + this.certTemplate = certTemplate; + this.controls = controls; + } + + public virtual DerInteger CertReqID + { + get { return certReqId; } + } + + public virtual CertTemplate CertTemplate + { + get { return certTemplate; } + } + + public virtual Controls Controls + { + get { return controls; } + } + + /** + *
+         * CertRequest ::= SEQUENCE {
+         *                      certReqId     INTEGER,          -- ID for matching request and reply
+         *                      certTemplate  CertTemplate,  -- Selected fields of cert to be issued
+         *                      controls      Controls OPTIONAL }   -- Attributes affecting issuance
+         * 
+ * @return a basic ASN.1 object representation. + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(certReqId, certTemplate); + v.AddOptional(controls); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/CertRequest.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/CertRequest.cs.meta new file mode 100644 index 0000000..6045db0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/CertRequest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fcaf7526d4527de49ba6ee2acf201870 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/CertTemplate.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/CertTemplate.cs new file mode 100644 index 0000000..f731ac1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/CertTemplate.cs @@ -0,0 +1,149 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; + +namespace Org.BouncyCastle.Asn1.Crmf +{ + public class CertTemplate + : Asn1Encodable + { + private readonly Asn1Sequence seq; + + private readonly DerInteger version; + private readonly DerInteger serialNumber; + private readonly AlgorithmIdentifier signingAlg; + private readonly X509Name issuer; + private readonly OptionalValidity validity; + private readonly X509Name subject; + private readonly SubjectPublicKeyInfo publicKey; + private readonly DerBitString issuerUID; + private readonly DerBitString subjectUID; + private readonly X509Extensions extensions; + + private CertTemplate(Asn1Sequence seq) + { + this.seq = seq; + + foreach (Asn1TaggedObject tObj in seq) + { + switch (tObj.TagNo) + { + case 0: + version = DerInteger.GetInstance(tObj, false); + break; + case 1: + serialNumber = DerInteger.GetInstance(tObj, false); + break; + case 2: + signingAlg = AlgorithmIdentifier.GetInstance(tObj, false); + break; + case 3: + issuer = X509Name.GetInstance(tObj, true); // CHOICE + break; + case 4: + validity = OptionalValidity.GetInstance(Asn1Sequence.GetInstance(tObj, false)); + break; + case 5: + subject = X509Name.GetInstance(tObj, true); // CHOICE + break; + case 6: + publicKey = SubjectPublicKeyInfo.GetInstance(tObj, false); + break; + case 7: + issuerUID = DerBitString.GetInstance(tObj, false); + break; + case 8: + subjectUID = DerBitString.GetInstance(tObj, false); + break; + case 9: + extensions = X509Extensions.GetInstance(tObj, false); + break; + default: + throw new ArgumentException("unknown tag: " + tObj.TagNo, "seq"); + } + } + } + + public static CertTemplate GetInstance(object obj) + { + if (obj is CertTemplate) + return (CertTemplate)obj; + + if (obj != null) + return new CertTemplate(Asn1Sequence.GetInstance(obj)); + + return null; + } + + public virtual int Version + { + get { return version.IntValueExact; } + } + + public virtual DerInteger SerialNumber + { + get { return serialNumber; } + } + + public virtual AlgorithmIdentifier SigningAlg + { + get { return signingAlg; } + } + + public virtual X509Name Issuer + { + get { return issuer; } + } + + public virtual OptionalValidity Validity + { + get { return validity; } + } + + public virtual X509Name Subject + { + get { return subject; } + } + + public virtual SubjectPublicKeyInfo PublicKey + { + get { return publicKey; } + } + + public virtual DerBitString IssuerUID + { + get { return issuerUID; } + } + + public virtual DerBitString SubjectUID + { + get { return subjectUID; } + } + + public virtual X509Extensions Extensions + { + get { return extensions; } + } + + /** + *
+         *  CertTemplate ::= SEQUENCE {
+         *      version      [0] Version               OPTIONAL,
+         *      serialNumber [1] INTEGER               OPTIONAL,
+         *      signingAlg   [2] AlgorithmIdentifier   OPTIONAL,
+         *      issuer       [3] Name                  OPTIONAL,
+         *      validity     [4] OptionalValidity      OPTIONAL,
+         *      subject      [5] Name                  OPTIONAL,
+         *      publicKey    [6] SubjectPublicKeyInfo  OPTIONAL,
+         *      issuerUID    [7] UniqueIdentifier      OPTIONAL,
+         *      subjectUID   [8] UniqueIdentifier      OPTIONAL,
+         *      extensions   [9] Extensions            OPTIONAL }
+         * 
+ * @return a basic ASN.1 object representation. + */ + public override Asn1Object ToAsn1Object() + { + return seq; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/CertTemplate.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/CertTemplate.cs.meta new file mode 100644 index 0000000..c717b2b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/CertTemplate.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f93bc9b5ba867b844b85d615b3c1cfb9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/CertTemplateBuilder.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/CertTemplateBuilder.cs new file mode 100644 index 0000000..51c73c4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/CertTemplateBuilder.cs @@ -0,0 +1,125 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; + +namespace Org.BouncyCastle.Asn1.Crmf +{ + public class CertTemplateBuilder + { + private DerInteger version; + private DerInteger serialNumber; + private AlgorithmIdentifier signingAlg; + private X509Name issuer; + private OptionalValidity validity; + private X509Name subject; + private SubjectPublicKeyInfo publicKey; + private DerBitString issuerUID; + private DerBitString subjectUID; + private X509Extensions extensions; + + /** Sets the X.509 version. Note: for X509v3, use 2 here. */ + public virtual CertTemplateBuilder SetVersion(int ver) + { + version = new DerInteger(ver); + return this; + } + + public virtual CertTemplateBuilder SetSerialNumber(DerInteger ser) + { + serialNumber = ser; + return this; + } + + public virtual CertTemplateBuilder SetSigningAlg(AlgorithmIdentifier aid) + { + signingAlg = aid; + return this; + } + + public virtual CertTemplateBuilder SetIssuer(X509Name name) + { + issuer = name; + return this; + } + + public virtual CertTemplateBuilder SetValidity(OptionalValidity v) + { + validity = v; + return this; + } + + public virtual CertTemplateBuilder SetSubject(X509Name name) + { + subject = name; + return this; + } + + public virtual CertTemplateBuilder SetPublicKey(SubjectPublicKeyInfo spki) + { + publicKey = spki; + return this; + } + + /** Sets the issuer unique ID (deprecated in X.509v3) */ + public virtual CertTemplateBuilder SetIssuerUID(DerBitString uid) + { + issuerUID = uid; + return this; + } + + /** Sets the subject unique ID (deprecated in X.509v3) */ + public virtual CertTemplateBuilder SetSubjectUID(DerBitString uid) + { + subjectUID = uid; + return this; + } + + public virtual CertTemplateBuilder SetExtensions(X509Extensions extens) + { + extensions = extens; + return this; + } + + /** + *
+         *  CertTemplate ::= SEQUENCE {
+         *      version      [0] Version               OPTIONAL,
+         *      serialNumber [1] INTEGER               OPTIONAL,
+         *      signingAlg   [2] AlgorithmIdentifier   OPTIONAL,
+         *      issuer       [3] Name                  OPTIONAL,
+         *      validity     [4] OptionalValidity      OPTIONAL,
+         *      subject      [5] Name                  OPTIONAL,
+         *      publicKey    [6] SubjectPublicKeyInfo  OPTIONAL,
+         *      issuerUID    [7] UniqueIdentifier      OPTIONAL,
+         *      subjectUID   [8] UniqueIdentifier      OPTIONAL,
+         *      extensions   [9] Extensions            OPTIONAL }
+         * 
+ * @return a basic ASN.1 object representation. + */ + public virtual CertTemplate Build() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + + AddOptional(v, 0, false, version); + AddOptional(v, 1, false, serialNumber); + AddOptional(v, 2, false, signingAlg); + AddOptional(v, 3, true, issuer); // CHOICE + AddOptional(v, 4, false, validity); + AddOptional(v, 5, true, subject); // CHOICE + AddOptional(v, 6, false, publicKey); + AddOptional(v, 7, false, issuerUID); + AddOptional(v, 8, false, subjectUID); + AddOptional(v, 9, false, extensions); + + return CertTemplate.GetInstance(new DerSequence(v)); + } + + private void AddOptional(Asn1EncodableVector v, int tagNo, bool isExplicit, Asn1Encodable obj) + { + if (obj != null) + { + v.Add(new DerTaggedObject(isExplicit, tagNo, obj)); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/CertTemplateBuilder.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/CertTemplateBuilder.cs.meta new file mode 100644 index 0000000..50e81f0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/CertTemplateBuilder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a3fb08bcecd08a040919050882425760 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/Controls.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/Controls.cs new file mode 100644 index 0000000..70b48a9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/Controls.cs @@ -0,0 +1,55 @@ +using System; +using System.Text; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Crmf +{ + public class Controls + : Asn1Encodable + { + private readonly Asn1Sequence content; + + private Controls(Asn1Sequence seq) + { + content = seq; + } + + public static Controls GetInstance(object obj) + { + if (obj is Controls) + return (Controls)obj; + + if (obj is Asn1Sequence) + return new Controls((Asn1Sequence)obj); + + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + } + + public Controls(params AttributeTypeAndValue[] atvs) + { + content = new DerSequence(atvs); + } + + public virtual AttributeTypeAndValue[] ToAttributeTypeAndValueArray() + { + AttributeTypeAndValue[] result = new AttributeTypeAndValue[content.Count]; + for (int i = 0; i != result.Length; ++i) + { + result[i] = AttributeTypeAndValue.GetInstance(content[i]); + } + return result; + } + + /** + *
+         * Controls  ::= SEQUENCE SIZE(1..MAX) OF AttributeTypeAndValue
+         * 
+ * @return a basic ASN.1 object representation. + */ + public override Asn1Object ToAsn1Object() + { + return content; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/Controls.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/Controls.cs.meta new file mode 100644 index 0000000..576f55b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/Controls.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d55172768555e904f9f37076492bc167 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/CrmfObjectIdentifiers.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/CrmfObjectIdentifiers.cs new file mode 100644 index 0000000..eaa1f7b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/CrmfObjectIdentifiers.cs @@ -0,0 +1,23 @@ +using System; + +using Org.BouncyCastle.Asn1.Pkcs; + +namespace Org.BouncyCastle.Asn1.Crmf +{ + public abstract class CrmfObjectIdentifiers + { + public static readonly DerObjectIdentifier id_pkix = new DerObjectIdentifier("1.3.6.1.5.5.7"); + + // arc for Internet X.509 PKI protocols and their components + + public static readonly DerObjectIdentifier id_pkip = id_pkix.Branch("5"); + + public static readonly DerObjectIdentifier id_regCtrl = id_pkip.Branch("1"); + public static readonly DerObjectIdentifier id_regCtrl_regToken = id_regCtrl.Branch("1"); + public static readonly DerObjectIdentifier id_regCtrl_authenticator = id_regCtrl.Branch("2"); + public static readonly DerObjectIdentifier id_regCtrl_pkiPublicationInfo = id_regCtrl.Branch("3"); + public static readonly DerObjectIdentifier id_regCtrl_pkiArchiveOptions = id_regCtrl.Branch("4"); + + public static readonly DerObjectIdentifier id_ct_encKeyWithID = new DerObjectIdentifier(PkcsObjectIdentifiers.IdCT + ".21"); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/CrmfObjectIdentifiers.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/CrmfObjectIdentifiers.cs.meta new file mode 100644 index 0000000..282d192 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/CrmfObjectIdentifiers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ea59e10e6405b034283933f7c2abdf86 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/EncKeyWithID.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/EncKeyWithID.cs new file mode 100644 index 0000000..6de56fa --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/EncKeyWithID.cs @@ -0,0 +1,103 @@ +using System; + +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.X509; + +namespace Org.BouncyCastle.Asn1.Crmf +{ + public class EncKeyWithID + : Asn1Encodable + { + private readonly PrivateKeyInfo privKeyInfo; + private readonly Asn1Encodable identifier; + + public static EncKeyWithID GetInstance(object obj) + { + if (obj is EncKeyWithID) + return (EncKeyWithID)obj; + + if (obj != null) + return new EncKeyWithID(Asn1Sequence.GetInstance(obj)); + + return null; + } + + private EncKeyWithID(Asn1Sequence seq) + { + this.privKeyInfo = PrivateKeyInfo.GetInstance(seq[0]); + + if (seq.Count > 1) + { + if (!(seq[1] is DerUtf8String)) + { + this.identifier = GeneralName.GetInstance(seq[1]); + } + else + { + this.identifier = (Asn1Encodable)seq[1]; + } + } + else + { + this.identifier = null; + } + } + + public EncKeyWithID(PrivateKeyInfo privKeyInfo) + { + this.privKeyInfo = privKeyInfo; + this.identifier = null; + } + + public EncKeyWithID(PrivateKeyInfo privKeyInfo, DerUtf8String str) + { + this.privKeyInfo = privKeyInfo; + this.identifier = str; + } + + public EncKeyWithID(PrivateKeyInfo privKeyInfo, GeneralName generalName) + { + this.privKeyInfo = privKeyInfo; + this.identifier = generalName; + } + + public virtual PrivateKeyInfo PrivateKey + { + get { return privKeyInfo; } + } + + public virtual bool HasIdentifier + { + get { return identifier != null; } + } + + public virtual bool IsIdentifierUtf8String + { + get { return identifier is DerUtf8String; } + } + + public virtual Asn1Encodable Identifier + { + get { return identifier; } + } + + /** + *
+         * EncKeyWithID ::= SEQUENCE {
+         *      privateKey           PrivateKeyInfo,
+         *      identifier CHOICE {
+         *         string               UTF8String,
+         *         generalName          GeneralName
+         *     } OPTIONAL
+         * }
+         * 
+ * @return + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(privKeyInfo); + v.AddOptional(identifier); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/EncKeyWithID.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/EncKeyWithID.cs.meta new file mode 100644 index 0000000..a24ec93 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/EncKeyWithID.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5a9e5becf56412648926ce6b1379ec0b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/EncryptedKey.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/EncryptedKey.cs new file mode 100644 index 0000000..850fbd2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/EncryptedKey.cs @@ -0,0 +1,78 @@ +using System; + +using Org.BouncyCastle.Asn1.Cms; + +namespace Org.BouncyCastle.Asn1.Crmf +{ + public class EncryptedKey + : Asn1Encodable, IAsn1Choice + { + private readonly EnvelopedData envelopedData; + private readonly EncryptedValue encryptedValue; + + public static EncryptedKey GetInstance(object o) + { + if (o is EncryptedKey) + { + return (EncryptedKey)o; + } + else if (o is Asn1TaggedObject) + { + return new EncryptedKey(EnvelopedData.GetInstance((Asn1TaggedObject)o, false)); + } + else if (o is EncryptedValue) + { + return new EncryptedKey((EncryptedValue)o); + } + else + { + return new EncryptedKey(EncryptedValue.GetInstance(o)); + } + } + + public EncryptedKey(EnvelopedData envelopedData) + { + this.envelopedData = envelopedData; + } + + public EncryptedKey(EncryptedValue encryptedValue) + { + this.encryptedValue = encryptedValue; + } + + public virtual bool IsEncryptedValue + { + get { return encryptedValue != null; } + } + + public virtual Asn1Encodable Value + { + get + { + if (encryptedValue != null) + return encryptedValue; + + return envelopedData; + } + } + + /** + *
+         *    EncryptedKey ::= CHOICE {
+         *        encryptedValue        EncryptedValue, -- deprecated
+         *        envelopedData     [0] EnvelopedData }
+         *        -- The encrypted private key MUST be placed in the envelopedData
+         *        -- encryptedContentInfo encryptedContent OCTET STRING.
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + if (encryptedValue != null) + { + return encryptedValue.ToAsn1Object(); + } + + return new DerTaggedObject(false, 0, envelopedData); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/EncryptedKey.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/EncryptedKey.cs.meta new file mode 100644 index 0000000..49dbde1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/EncryptedKey.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fe336d2e07d3c404d9889827b9e5ee3d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/EncryptedValue.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/EncryptedValue.cs new file mode 100644 index 0000000..7c5cf18 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/EncryptedValue.cs @@ -0,0 +1,143 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; + +namespace Org.BouncyCastle.Asn1.Crmf +{ + public class EncryptedValue + : Asn1Encodable + { + private readonly AlgorithmIdentifier intendedAlg; + private readonly AlgorithmIdentifier symmAlg; + private readonly DerBitString encSymmKey; + private readonly AlgorithmIdentifier keyAlg; + private readonly Asn1OctetString valueHint; + private readonly DerBitString encValue; + + private EncryptedValue(Asn1Sequence seq) + { + int index = 0; + while (seq[index] is Asn1TaggedObject) + { + Asn1TaggedObject tObj = (Asn1TaggedObject)seq[index]; + + switch (tObj.TagNo) + { + case 0: + intendedAlg = AlgorithmIdentifier.GetInstance(tObj, false); + break; + case 1: + symmAlg = AlgorithmIdentifier.GetInstance(tObj, false); + break; + case 2: + encSymmKey = DerBitString.GetInstance(tObj, false); + break; + case 3: + keyAlg = AlgorithmIdentifier.GetInstance(tObj, false); + break; + case 4: + valueHint = Asn1OctetString.GetInstance(tObj, false); + break; + } + ++index; + } + + encValue = DerBitString.GetInstance(seq[index]); + } + + public static EncryptedValue GetInstance(object obj) + { + if (obj is EncryptedValue) + return (EncryptedValue)obj; + + if (obj != null) + return new EncryptedValue(Asn1Sequence.GetInstance(obj)); + + return null; + } + + public EncryptedValue( + AlgorithmIdentifier intendedAlg, + AlgorithmIdentifier symmAlg, + DerBitString encSymmKey, + AlgorithmIdentifier keyAlg, + Asn1OctetString valueHint, + DerBitString encValue) + { + if (encValue == null) + { + throw new ArgumentNullException("encValue"); + } + + this.intendedAlg = intendedAlg; + this.symmAlg = symmAlg; + this.encSymmKey = encSymmKey; + this.keyAlg = keyAlg; + this.valueHint = valueHint; + this.encValue = encValue; + } + + public virtual AlgorithmIdentifier IntendedAlg + { + get { return intendedAlg; } + } + + public virtual AlgorithmIdentifier SymmAlg + { + get { return symmAlg; } + } + + public virtual DerBitString EncSymmKey + { + get { return encSymmKey; } + } + + public virtual AlgorithmIdentifier KeyAlg + { + get { return keyAlg; } + } + + public virtual Asn1OctetString ValueHint + { + get { return valueHint; } + } + + public virtual DerBitString EncValue + { + get { return encValue; } + } + + /** + *
+         * EncryptedValue ::= SEQUENCE {
+         *                     intendedAlg   [0] AlgorithmIdentifier  OPTIONAL,
+         *                     -- the intended algorithm for which the value will be used
+         *                     symmAlg       [1] AlgorithmIdentifier  OPTIONAL,
+         *                     -- the symmetric algorithm used to encrypt the value
+         *                     encSymmKey    [2] BIT STRING           OPTIONAL,
+         *                     -- the (encrypted) symmetric key used to encrypt the value
+         *                     keyAlg        [3] AlgorithmIdentifier  OPTIONAL,
+         *                     -- algorithm used to encrypt the symmetric key
+         *                     valueHint     [4] OCTET STRING         OPTIONAL,
+         *                     -- a brief description or identifier of the encValue content
+         *                     -- (may be meaningful only to the sending entity, and used only
+         *                     -- if EncryptedValue might be re-examined by the sending entity
+         *                     -- in the future)
+         *                     encValue       BIT STRING }
+         *                     -- the encrypted value itself
+         * 
+ * @return a basic ASN.1 object representation. + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + v.AddOptionalTagged(false, 0, intendedAlg); + v.AddOptionalTagged(false, 1, symmAlg); + v.AddOptionalTagged(false, 2, encSymmKey); + v.AddOptionalTagged(false, 3, keyAlg); + v.AddOptionalTagged(false, 4, valueHint); + v.Add(encValue); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/EncryptedValue.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/EncryptedValue.cs.meta new file mode 100644 index 0000000..bf29c6f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/EncryptedValue.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f54a15b1bcfb44b41a99bd3bcc5be478 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/OptionalValidity.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/OptionalValidity.cs new file mode 100644 index 0000000..d608ea5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/OptionalValidity.cs @@ -0,0 +1,68 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; + +namespace Org.BouncyCastle.Asn1.Crmf +{ + public class OptionalValidity + : Asn1Encodable + { + private readonly Time notBefore; + private readonly Time notAfter; + + private OptionalValidity(Asn1Sequence seq) + { + foreach (Asn1TaggedObject tObj in seq) + { + if (tObj.TagNo == 0) + { + notBefore = Time.GetInstance(tObj, true); + } + else + { + notAfter = Time.GetInstance(tObj, true); + } + } + } + + public static OptionalValidity GetInstance(object obj) + { + if (obj == null || obj is OptionalValidity) + return (OptionalValidity)obj; + + return new OptionalValidity(Asn1Sequence.GetInstance(obj)); + } + + public OptionalValidity(Time notBefore, Time notAfter) + { + this.notBefore = notBefore; + this.notAfter = notAfter; + } + + public virtual Time NotBefore + { + get { return notBefore; } + } + + public virtual Time NotAfter + { + get { return notAfter; } + } + + /** + *
+         * OptionalValidity ::= SEQUENCE {
+         *                        notBefore  [0] Time OPTIONAL,
+         *                        notAfter   [1] Time OPTIONAL } --at least one MUST be present
+         * 
+ * @return a basic ASN.1 object representation. + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + v.AddOptionalTagged(true, 0, notBefore); + v.AddOptionalTagged(true, 1, notAfter); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/OptionalValidity.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/OptionalValidity.cs.meta new file mode 100644 index 0000000..faa372d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/OptionalValidity.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ee8549207eb9b0444900ec27becbdede +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/PKIArchiveOptions.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/PKIArchiveOptions.cs new file mode 100644 index 0000000..1813d87 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/PKIArchiveOptions.cs @@ -0,0 +1,107 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Crmf +{ + public class PkiArchiveOptions + : Asn1Encodable, IAsn1Choice + { + public const int encryptedPrivKey = 0; + public const int keyGenParameters = 1; + public const int archiveRemGenPrivKey = 2; + + private readonly Asn1Encodable value; + + public static PkiArchiveOptions GetInstance(object obj) + { + if (obj is PkiArchiveOptions) + return (PkiArchiveOptions)obj; + + if (obj is Asn1TaggedObject) + return new PkiArchiveOptions((Asn1TaggedObject)obj); + + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + } + + private PkiArchiveOptions(Asn1TaggedObject tagged) + { + switch (tagged.TagNo) + { + case encryptedPrivKey: + value = EncryptedKey.GetInstance(tagged.GetObject()); + break; + case keyGenParameters: + value = Asn1OctetString.GetInstance(tagged, false); + break; + case archiveRemGenPrivKey: + value = DerBoolean.GetInstance(tagged, false); + break; + default: + throw new ArgumentException("unknown tag number: " + tagged.TagNo, "tagged"); + } + } + + public PkiArchiveOptions(EncryptedKey encKey) + { + this.value = encKey; + } + + public PkiArchiveOptions(Asn1OctetString keyGenParameters) + { + this.value = keyGenParameters; + } + + public PkiArchiveOptions(bool archiveRemGenPrivKey) + { + this.value = DerBoolean.GetInstance(archiveRemGenPrivKey); + } + + public virtual int Type + { + get + { + if (value is EncryptedKey) + return encryptedPrivKey; + + if (value is Asn1OctetString) + return keyGenParameters; + + return archiveRemGenPrivKey; + } + } + + public virtual Asn1Encodable Value + { + get { return value; } + } + + /** + *
+         *  PkiArchiveOptions ::= CHOICE {
+         *      encryptedPrivKey     [0] EncryptedKey,
+         *      -- the actual value of the private key
+         *      keyGenParameters     [1] KeyGenParameters,
+         *      -- parameters which allow the private key to be re-generated
+         *      archiveRemGenPrivKey [2] BOOLEAN }
+         *      -- set to TRUE if sender wishes receiver to archive the private
+         *      -- key of a key pair that the receiver generates in response to
+         *      -- this request; set to FALSE if no archival is desired.
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + if (value is EncryptedKey) + { + return new DerTaggedObject(true, encryptedPrivKey, value); // choice + } + + if (value is Asn1OctetString) + { + return new DerTaggedObject(false, keyGenParameters, value); + } + + return new DerTaggedObject(false, archiveRemGenPrivKey, value); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/PKIArchiveOptions.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/PKIArchiveOptions.cs.meta new file mode 100644 index 0000000..52e8b78 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/PKIArchiveOptions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6ae24e0794d047347b18838e5699a300 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/PKIPublicationInfo.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/PKIPublicationInfo.cs new file mode 100644 index 0000000..a7d2bc6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/PKIPublicationInfo.cs @@ -0,0 +1,66 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Crmf +{ + public class PkiPublicationInfo + : Asn1Encodable + { + private readonly DerInteger action; + private readonly Asn1Sequence pubInfos; + + private PkiPublicationInfo(Asn1Sequence seq) + { + action = DerInteger.GetInstance(seq[0]); + pubInfos = Asn1Sequence.GetInstance(seq[1]); + } + + public static PkiPublicationInfo GetInstance(object obj) + { + if (obj is PkiPublicationInfo) + return (PkiPublicationInfo)obj; + + if (obj is Asn1Sequence) + return new PkiPublicationInfo((Asn1Sequence)obj); + + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + } + + public virtual DerInteger Action + { + get { return action; } + } + + public virtual SinglePubInfo[] GetPubInfos() + { + if (pubInfos == null) + return null; + + SinglePubInfo[] results = new SinglePubInfo[pubInfos.Count]; + for (int i = 0; i != results.Length; ++i) + { + results[i] = SinglePubInfo.GetInstance(pubInfos[i]); + } + return results; + } + + /** + *
+         * PkiPublicationInfo ::= SEQUENCE {
+         *                  action     INTEGER {
+         *                                 dontPublish (0),
+         *                                 pleasePublish (1) },
+         *                  pubInfos  SEQUENCE SIZE (1..MAX) OF SinglePubInfo OPTIONAL }
+         * -- pubInfos MUST NOT be present if action is "dontPublish"
+         * -- (if action is "pleasePublish" and pubInfos is omitted,
+         * -- "dontCare" is assumed)
+         * 
+ * @return a basic ASN.1 object representation. + */ + public override Asn1Object ToAsn1Object() + { + return new DerSequence(action, pubInfos); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/PKIPublicationInfo.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/PKIPublicationInfo.cs.meta new file mode 100644 index 0000000..420fe0a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/PKIPublicationInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 63164a917a3173a419b482d866978b79 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/PKMacValue.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/PKMacValue.cs new file mode 100644 index 0000000..e104c08 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/PKMacValue.cs @@ -0,0 +1,90 @@ +using System; + +using Org.BouncyCastle.Asn1.Cmp; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Crmf +{ + /** + * Password-based MAC value for use with POPOSigningKeyInput. + */ + public class PKMacValue + : Asn1Encodable + { + private readonly AlgorithmIdentifier algID; + private readonly DerBitString macValue; + + private PKMacValue(Asn1Sequence seq) + { + this.algID = AlgorithmIdentifier.GetInstance(seq[0]); + this.macValue = DerBitString.GetInstance(seq[1]); + } + + public static PKMacValue GetInstance(object obj) + { + if (obj is PKMacValue) + return (PKMacValue)obj; + + if (obj is Asn1Sequence) + return new PKMacValue((Asn1Sequence)obj); + + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + } + + public static PKMacValue GetInstance(Asn1TaggedObject obj, bool isExplicit) + { + return GetInstance(Asn1Sequence.GetInstance(obj, isExplicit)); + } + + /** + * Creates a new PKMACValue. + * @param params parameters for password-based MAC + * @param value MAC of the DER-encoded SubjectPublicKeyInfo + */ + public PKMacValue( + PbmParameter pbmParams, + DerBitString macValue) + : this(new AlgorithmIdentifier(CmpObjectIdentifiers.passwordBasedMac, pbmParams), macValue) + { + } + + /** + * Creates a new PKMACValue. + * @param aid CMPObjectIdentifiers.passwordBasedMAC, with PBMParameter + * @param value MAC of the DER-encoded SubjectPublicKeyInfo + */ + public PKMacValue( + AlgorithmIdentifier algID, + DerBitString macValue) + { + this.algID = algID; + this.macValue = macValue; + } + + public virtual AlgorithmIdentifier AlgID + { + get { return algID; } + } + + public virtual DerBitString MacValue + { + get { return macValue; } + } + + /** + *
+         * PKMACValue ::= SEQUENCE {
+         *      algId  AlgorithmIdentifier,
+         *      -- algorithm value shall be PasswordBasedMac 1.2.840.113533.7.66.13
+         *      -- parameter value is PBMParameter
+         *      value  BIT STRING }
+         * 
+ * @return a basic ASN.1 object representation. + */ + public override Asn1Object ToAsn1Object() + { + return new DerSequence(algID, macValue); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/PKMacValue.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/PKMacValue.cs.meta new file mode 100644 index 0000000..f5f2cdd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/PKMacValue.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b765919239715a745b7105bbe96d36c7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/PopoPrivKey.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/PopoPrivKey.cs new file mode 100644 index 0000000..95a4484 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/PopoPrivKey.cs @@ -0,0 +1,84 @@ +using System; + +using Org.BouncyCastle.Asn1.Cms; + +namespace Org.BouncyCastle.Asn1.Crmf +{ + public class PopoPrivKey + : Asn1Encodable, IAsn1Choice + { + public const int thisMessage = 0; + public const int subsequentMessage = 1; + public const int dhMAC = 2; + public const int agreeMAC = 3; + public const int encryptedKey = 4; + + private readonly int tagNo; + private readonly Asn1Encodable obj; + + private PopoPrivKey(Asn1TaggedObject obj) + { + this.tagNo = obj.TagNo; + + switch (tagNo) + { + case thisMessage: + this.obj = DerBitString.GetInstance(obj, false); + break; + case subsequentMessage: + this.obj = SubsequentMessage.ValueOf(DerInteger.GetInstance(obj, false).IntValueExact); + break; + case dhMAC: + this.obj = DerBitString.GetInstance(obj, false); + break; + case agreeMAC: + this.obj = PKMacValue.GetInstance(obj, false); + break; + case encryptedKey: + this.obj = EnvelopedData.GetInstance(obj, false); + break; + default: + throw new ArgumentException("unknown tag in PopoPrivKey", "obj"); + } + } + + public static PopoPrivKey GetInstance(Asn1TaggedObject tagged, bool isExplicit) + { + return new PopoPrivKey(Asn1TaggedObject.GetInstance(tagged, true)); + } + + public PopoPrivKey(SubsequentMessage msg) + { + this.tagNo = subsequentMessage; + this.obj = msg; + } + + public virtual int Type + { + get { return tagNo; } + } + + public virtual Asn1Encodable Value + { + get { return obj; } + } + + /** + *
+         * PopoPrivKey ::= CHOICE {
+         *        thisMessage       [0] BIT STRING,         -- Deprecated
+         *         -- possession is proven in this message (which contains the private
+         *         -- key itself (encrypted for the CA))
+         *        subsequentMessage [1] SubsequentMessage,
+         *         -- possession will be proven in a subsequent message
+         *        dhMAC             [2] BIT STRING,         -- Deprecated
+         *        agreeMAC          [3] PKMACValue,
+         *        encryptedKey      [4] EnvelopedData }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + return new DerTaggedObject(false, tagNo, obj); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/PopoPrivKey.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/PopoPrivKey.cs.meta new file mode 100644 index 0000000..11b2eb2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/PopoPrivKey.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4a0bdbaeb1baea245a0d0678bb1914ee +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/PopoSigningKey.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/PopoSigningKey.cs new file mode 100644 index 0000000..11e7354 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/PopoSigningKey.cs @@ -0,0 +1,110 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Crmf +{ + public class PopoSigningKey + : Asn1Encodable + { + private readonly PopoSigningKeyInput poposkInput; + private readonly AlgorithmIdentifier algorithmIdentifier; + private readonly DerBitString signature; + + private PopoSigningKey(Asn1Sequence seq) + { + int index = 0; + + if (seq[index] is Asn1TaggedObject) + { + Asn1TaggedObject tagObj + = (Asn1TaggedObject) seq[index++]; + if (tagObj.TagNo != 0) + { + throw new ArgumentException( "Unknown PopoSigningKeyInput tag: " + tagObj.TagNo, "seq"); + } + poposkInput = PopoSigningKeyInput.GetInstance(tagObj.GetObject()); + } + algorithmIdentifier = AlgorithmIdentifier.GetInstance(seq[index++]); + signature = DerBitString.GetInstance(seq[index]); + } + + public static PopoSigningKey GetInstance(object obj) + { + if (obj is PopoSigningKey) + return (PopoSigningKey)obj; + + if (obj is Asn1Sequence) + return new PopoSigningKey((Asn1Sequence)obj); + + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + } + + public static PopoSigningKey GetInstance(Asn1TaggedObject obj, bool isExplicit) + { + return GetInstance(Asn1Sequence.GetInstance(obj, isExplicit)); + } + + /** + * Creates a new Proof of Possession object for a signing key. + * @param poposkIn the PopoSigningKeyInput structure, or null if the + * CertTemplate includes both subject and publicKey values. + * @param aid the AlgorithmIdentifier used to sign the proof of possession. + * @param signature a signature over the DER-encoded value of poposkIn, + * or the DER-encoded value of certReq if poposkIn is null. + */ + public PopoSigningKey( + PopoSigningKeyInput poposkIn, + AlgorithmIdentifier aid, + DerBitString signature) + { + this.poposkInput = poposkIn; + this.algorithmIdentifier = aid; + this.signature = signature; + } + + public virtual PopoSigningKeyInput PoposkInput + { + get { return poposkInput; } + } + + public virtual AlgorithmIdentifier AlgorithmIdentifier + { + get { return algorithmIdentifier; } + } + + public virtual DerBitString Signature + { + get { return signature; } + } + + /** + *
+         * PopoSigningKey ::= SEQUENCE {
+         *                      poposkInput           [0] PopoSigningKeyInput OPTIONAL,
+         *                      algorithmIdentifier   AlgorithmIdentifier,
+         *                      signature             BIT STRING }
+         *  -- The signature (using "algorithmIdentifier") is on the
+         *  -- DER-encoded value of poposkInput.  NOTE: If the CertReqMsg
+         *  -- certReq CertTemplate contains the subject and publicKey values,
+         *  -- then poposkInput MUST be omitted and the signature MUST be
+         *  -- computed on the DER-encoded value of CertReqMsg certReq.  If
+         *  -- the CertReqMsg certReq CertTemplate does not contain the public
+         *  -- key and subject values, then poposkInput MUST be present and
+         *  -- MUST be signed.  This strategy ensures that the public key is
+         *  -- not present in both the poposkInput and CertReqMsg certReq
+         *  -- CertTemplate fields.
+         * 
+ * @return a basic ASN.1 object representation. + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + v.AddOptionalTagged(false, 0, poposkInput); + v.Add(algorithmIdentifier); + v.Add(signature); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/PopoSigningKey.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/PopoSigningKey.cs.meta new file mode 100644 index 0000000..1c0b1c9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/PopoSigningKey.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f7d074ff5e8b01a4aa9a9d616691ba43 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/PopoSigningKeyInput.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/PopoSigningKeyInput.cs new file mode 100644 index 0000000..e43fa13 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/PopoSigningKeyInput.cs @@ -0,0 +1,116 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Crmf +{ + public class PopoSigningKeyInput + : Asn1Encodable + { + private readonly GeneralName sender; + private readonly PKMacValue publicKeyMac; + private readonly SubjectPublicKeyInfo publicKey; + + private PopoSigningKeyInput(Asn1Sequence seq) + { + Asn1Encodable authInfo = (Asn1Encodable)seq[0]; + + if (authInfo is Asn1TaggedObject) + { + Asn1TaggedObject tagObj = (Asn1TaggedObject)authInfo; + if (tagObj.TagNo != 0) + { + throw new ArgumentException("Unknown authInfo tag: " + tagObj.TagNo, "seq"); + } + sender = GeneralName.GetInstance(tagObj.GetObject()); + } + else + { + publicKeyMac = PKMacValue.GetInstance(authInfo); + } + + publicKey = SubjectPublicKeyInfo.GetInstance(seq[1]); + } + + public static PopoSigningKeyInput GetInstance(object obj) + { + if (obj is PopoSigningKeyInput) + return (PopoSigningKeyInput)obj; + + if (obj is Asn1Sequence) + return new PopoSigningKeyInput((Asn1Sequence)obj); + + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + } + + /** Creates a new PopoSigningKeyInput with sender name as authInfo. */ + public PopoSigningKeyInput( + GeneralName sender, + SubjectPublicKeyInfo spki) + { + this.sender = sender; + this.publicKey = spki; + } + + /** Creates a new PopoSigningKeyInput using password-based MAC. */ + public PopoSigningKeyInput( + PKMacValue pkmac, + SubjectPublicKeyInfo spki) + { + this.publicKeyMac = pkmac; + this.publicKey = spki; + } + + /** Returns the sender field, or null if authInfo is publicKeyMac */ + public virtual GeneralName Sender + { + get { return sender; } + } + + /** Returns the publicKeyMac field, or null if authInfo is sender */ + public virtual PKMacValue PublicKeyMac + { + get { return publicKeyMac; } + } + + public virtual SubjectPublicKeyInfo PublicKey + { + get { return publicKey; } + } + + /** + *
+         * PopoSigningKeyInput ::= SEQUENCE {
+         *        authInfo             CHOICE {
+         *                                 sender              [0] GeneralName,
+         *                                 -- used only if an authenticated identity has been
+         *                                 -- established for the sender (e.g., a DN from a
+         *                                 -- previously-issued and currently-valid certificate
+         *                                 publicKeyMac        PKMacValue },
+         *                                 -- used if no authenticated GeneralName currently exists for
+         *                                 -- the sender; publicKeyMac contains a password-based MAC
+         *                                 -- on the DER-encoded value of publicKey
+         *        publicKey           SubjectPublicKeyInfo }  -- from CertTemplate
+         * 
+ * @return a basic ASN.1 object representation. + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + + if (sender != null) + { + v.Add(new DerTaggedObject(false, 0, sender)); + } + else + { + v.Add(publicKeyMac); + } + + v.Add(publicKey); + + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/PopoSigningKeyInput.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/PopoSigningKeyInput.cs.meta new file mode 100644 index 0000000..fb5ccaf --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/PopoSigningKeyInput.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f42334ec256c5cb41976be442da46fd7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/ProofOfPossession.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/ProofOfPossession.cs new file mode 100644 index 0000000..8957169 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/ProofOfPossession.cs @@ -0,0 +1,100 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Crmf +{ + public class ProofOfPossession + : Asn1Encodable, IAsn1Choice + { + public const int TYPE_RA_VERIFIED = 0; + public const int TYPE_SIGNING_KEY = 1; + public const int TYPE_KEY_ENCIPHERMENT = 2; + public const int TYPE_KEY_AGREEMENT = 3; + + private readonly int tagNo; + private readonly Asn1Encodable obj; + + private ProofOfPossession(Asn1TaggedObject tagged) + { + tagNo = tagged.TagNo; + switch (tagNo) + { + case 0: + obj = DerNull.Instance; + break; + case 1: + obj = PopoSigningKey.GetInstance(tagged, false); + break; + case 2: + case 3: + obj = PopoPrivKey.GetInstance(tagged, false); + break; + default: + throw new ArgumentException("unknown tag: " + tagNo, "tagged"); + } + } + + public static ProofOfPossession GetInstance(object obj) + { + if (obj is ProofOfPossession) + return (ProofOfPossession)obj; + + if (obj is Asn1TaggedObject) + return new ProofOfPossession((Asn1TaggedObject)obj); + + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + } + + /** Creates a ProofOfPossession with type raVerified. */ + public ProofOfPossession() + { + tagNo = TYPE_RA_VERIFIED; + obj = DerNull.Instance; + } + + /** Creates a ProofOfPossession for a signing key. */ + public ProofOfPossession(PopoSigningKey Poposk) + { + tagNo = TYPE_SIGNING_KEY; + obj = Poposk; + } + + /** + * Creates a ProofOfPossession for key encipherment or agreement. + * @param type one of TYPE_KEY_ENCIPHERMENT or TYPE_KEY_AGREEMENT + */ + public ProofOfPossession(int type, PopoPrivKey privkey) + { + tagNo = type; + obj = privkey; + } + + public virtual int Type + { + get { return tagNo; } + } + + public virtual Asn1Encodable Object + { + get { return obj; } + } + + /** + *
+         * ProofOfPossession ::= CHOICE {
+         *                           raVerified        [0] NULL,
+         *                           -- used if the RA has already verified that the requester is in
+         *                           -- possession of the private key
+         *                           signature         [1] PopoSigningKey,
+         *                           keyEncipherment   [2] PopoPrivKey,
+         *                           keyAgreement      [3] PopoPrivKey }
+         * 
+ * @return a basic ASN.1 object representation. + */ + public override Asn1Object ToAsn1Object() + { + return new DerTaggedObject(false, tagNo, obj); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/ProofOfPossession.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/ProofOfPossession.cs.meta new file mode 100644 index 0000000..87c4418 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/ProofOfPossession.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4b9c364acf9babc428dc8cd5c614eae7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/SinglePubInfo.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/SinglePubInfo.cs new file mode 100644 index 0000000..5205ce3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/SinglePubInfo.cs @@ -0,0 +1,59 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Crmf +{ + public class SinglePubInfo + : Asn1Encodable + { + private readonly DerInteger pubMethod; + private readonly GeneralName pubLocation; + + private SinglePubInfo(Asn1Sequence seq) + { + pubMethod = DerInteger.GetInstance(seq[0]); + + if (seq.Count == 2) + { + pubLocation = GeneralName.GetInstance(seq[1]); + } + } + + public static SinglePubInfo GetInstance(object obj) + { + if (obj is SinglePubInfo) + return (SinglePubInfo)obj; + + if (obj is Asn1Sequence) + return new SinglePubInfo((Asn1Sequence)obj); + + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + } + + public virtual GeneralName PubLocation + { + get { return pubLocation; } + } + + /** + *
+         * SinglePubInfo ::= SEQUENCE {
+         *        pubMethod    INTEGER {
+         *           dontCare    (0),
+         *           x500        (1),
+         *           web         (2),
+         *           ldap        (3) },
+         *       pubLocation  GeneralName OPTIONAL }
+         * 
+ * @return a basic ASN.1 object representation. + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(pubMethod); + v.AddOptional(pubLocation); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/SinglePubInfo.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/SinglePubInfo.cs.meta new file mode 100644 index 0000000..85a6b59 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/SinglePubInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b4135611537a65f47b9f85959c638ae4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/SubsequentMessage.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/SubsequentMessage.cs new file mode 100644 index 0000000..cc1c164 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/SubsequentMessage.cs @@ -0,0 +1,27 @@ +using System; + +namespace Org.BouncyCastle.Asn1.Crmf +{ + public class SubsequentMessage + : DerInteger + { + public static readonly SubsequentMessage encrCert = new SubsequentMessage(0); + public static readonly SubsequentMessage challengeResp = new SubsequentMessage(1); + + private SubsequentMessage(int value) + : base(value) + { + } + + public static SubsequentMessage ValueOf(int value) + { + if (value == 0) + return encrCert; + + if (value == 1) + return challengeResp; + + throw new ArgumentException("unknown value: " + value, "value"); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/SubsequentMessage.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/SubsequentMessage.cs.meta new file mode 100644 index 0000000..034d26a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/crmf/SubsequentMessage.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7b1260c8485545e499c1df4ddde4ab14 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cryptopro.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cryptopro.meta new file mode 100644 index 0000000..32f08f1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cryptopro.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4a987f4ba1f1767489236c0a9255532a +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cryptopro/CryptoProObjectIdentifiers.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cryptopro/CryptoProObjectIdentifiers.cs new file mode 100644 index 0000000..e2f2c18 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cryptopro/CryptoProObjectIdentifiers.cs @@ -0,0 +1,51 @@ +using System; + +using Org.BouncyCastle.Asn1; + +namespace Org.BouncyCastle.Asn1.CryptoPro +{ + public abstract class CryptoProObjectIdentifiers + { + // GOST Algorithms OBJECT IDENTIFIERS : + // { iso(1) member-body(2) ru(643) rans(2) cryptopro(2)} + public const string GostID = "1.2.643.2.2"; + + public static readonly DerObjectIdentifier GostR3411 = new DerObjectIdentifier(GostID + ".9"); + public static readonly DerObjectIdentifier GostR3411Hmac = new DerObjectIdentifier(GostID + ".10"); + + public static readonly DerObjectIdentifier GostR28147Cbc = new DerObjectIdentifier(GostID + ".21"); + + public static readonly DerObjectIdentifier ID_Gost28147_89_CryptoPro_A_ParamSet = new DerObjectIdentifier(GostID + ".31.1"); + + public static readonly DerObjectIdentifier GostR3410x94 = new DerObjectIdentifier(GostID + ".20"); + public static readonly DerObjectIdentifier GostR3410x2001 = new DerObjectIdentifier(GostID + ".19"); + public static readonly DerObjectIdentifier GostR3411x94WithGostR3410x94 = new DerObjectIdentifier(GostID + ".4"); + public static readonly DerObjectIdentifier GostR3411x94WithGostR3410x2001 = new DerObjectIdentifier(GostID + ".3"); + + // { iso(1) member-body(2) ru(643) rans(2) cryptopro(2) hashes(30) } + public static readonly DerObjectIdentifier GostR3411x94CryptoProParamSet = new DerObjectIdentifier(GostID + ".30.1"); + + // { iso(1) member-body(2) ru(643) rans(2) cryptopro(2) signs(32) } + public static readonly DerObjectIdentifier GostR3410x94CryptoProA = new DerObjectIdentifier(GostID + ".32.2"); + public static readonly DerObjectIdentifier GostR3410x94CryptoProB = new DerObjectIdentifier(GostID + ".32.3"); + public static readonly DerObjectIdentifier GostR3410x94CryptoProC = new DerObjectIdentifier(GostID + ".32.4"); + public static readonly DerObjectIdentifier GostR3410x94CryptoProD = new DerObjectIdentifier(GostID + ".32.5"); + + // { iso(1) member-body(2) ru(643) rans(2) cryptopro(2) exchanges(33) } + public static readonly DerObjectIdentifier GostR3410x94CryptoProXchA = new DerObjectIdentifier(GostID + ".33.1"); + public static readonly DerObjectIdentifier GostR3410x94CryptoProXchB = new DerObjectIdentifier(GostID + ".33.2"); + public static readonly DerObjectIdentifier GostR3410x94CryptoProXchC = new DerObjectIdentifier(GostID + ".33.3"); + + //{ iso(1) member-body(2)ru(643) rans(2) cryptopro(2) ecc-signs(35) } + public static readonly DerObjectIdentifier GostR3410x2001CryptoProA = new DerObjectIdentifier(GostID + ".35.1"); + public static readonly DerObjectIdentifier GostR3410x2001CryptoProB = new DerObjectIdentifier(GostID + ".35.2"); + public static readonly DerObjectIdentifier GostR3410x2001CryptoProC = new DerObjectIdentifier(GostID + ".35.3"); + + // { iso(1) member-body(2) ru(643) rans(2) cryptopro(2) ecc-exchanges(36) } + public static readonly DerObjectIdentifier GostR3410x2001CryptoProXchA = new DerObjectIdentifier(GostID + ".36.0"); + public static readonly DerObjectIdentifier GostR3410x2001CryptoProXchB = new DerObjectIdentifier(GostID + ".36.1"); + + public static readonly DerObjectIdentifier GostElSgDH3410Default = new DerObjectIdentifier(GostID + ".36.0"); + public static readonly DerObjectIdentifier GostElSgDH3410x1 = new DerObjectIdentifier(GostID + ".36.1"); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cryptopro/CryptoProObjectIdentifiers.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cryptopro/CryptoProObjectIdentifiers.cs.meta new file mode 100644 index 0000000..30bcf89 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cryptopro/CryptoProObjectIdentifiers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 63c2e89383bc6f5439b357102307daed +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cryptopro/ECGOST3410NamedCurves.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cryptopro/ECGOST3410NamedCurves.cs new file mode 100644 index 0000000..99fb34b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cryptopro/ECGOST3410NamedCurves.cs @@ -0,0 +1,281 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1.Rosstandart; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Math.EC.Multiplier; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Asn1.CryptoPro +{ + /// + /// Table of the available named parameters for GOST 3410-2001 / 2012. + /// + public sealed class ECGost3410NamedCurves + { + private static ECPoint ConfigureBasepoint(ECCurve curve, BigInteger x, BigInteger y) + { + ECPoint G = curve.CreatePoint(x, y); + WNafUtilities.ConfigureBasepoint(G); + return G; + } + + private static ECCurve ConfigureCurve(ECCurve curve) + { + return curve; + } + + private ECGost3410NamedCurves() + { + } + + internal static readonly IDictionary objIds = Platform.CreateHashtable(); + internal static readonly IDictionary parameters = Platform.CreateHashtable(); + internal static readonly IDictionary names = Platform.CreateHashtable(); + + static ECGost3410NamedCurves() + { + BigInteger mod_p = new BigInteger("115792089237316195423570985008687907853269984665640564039457584007913129639319"); + BigInteger mod_q = new BigInteger("115792089237316195423570985008687907853073762908499243225378155805079068850323"); + + ECCurve curve = ConfigureCurve(new FpCurve( + mod_p, // p + new BigInteger("115792089237316195423570985008687907853269984665640564039457584007913129639316"), // a + new BigInteger("166"), // b + mod_q, BigInteger.One)); + + ECDomainParameters ecParams = new ECDomainParameters( + curve, + ConfigureBasepoint(curve, + new BigInteger("1"), // x + new BigInteger("64033881142927202683649881450433473985931760268884941288852745803908878638612")), // y + mod_q, BigInteger.One); + + parameters[CryptoProObjectIdentifiers.GostR3410x2001CryptoProA] = ecParams; + + mod_p = new BigInteger("115792089237316195423570985008687907853269984665640564039457584007913129639319"); + mod_q = new BigInteger("115792089237316195423570985008687907853073762908499243225378155805079068850323"); + + curve = ConfigureCurve(new FpCurve( + mod_p, // p + new BigInteger("115792089237316195423570985008687907853269984665640564039457584007913129639316"), + new BigInteger("166"), + mod_q, BigInteger.One)); + + ecParams = new ECDomainParameters( + curve, + ConfigureBasepoint(curve, + new BigInteger("1"), // x + new BigInteger("64033881142927202683649881450433473985931760268884941288852745803908878638612")), // y + mod_q, BigInteger.One); + + parameters[CryptoProObjectIdentifiers.GostR3410x2001CryptoProXchA] = ecParams; + + mod_p = new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564823193"); //p + mod_q = new BigInteger("57896044618658097711785492504343953927102133160255826820068844496087732066703"); //q + + curve = ConfigureCurve(new FpCurve( + mod_p, // p + new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564823190"), // a + new BigInteger("28091019353058090096996979000309560759124368558014865957655842872397301267595"), // b + mod_q, BigInteger.One)); + + ecParams = new ECDomainParameters( + curve, + ConfigureBasepoint(curve, + new BigInteger("1"), // x + new BigInteger("28792665814854611296992347458380284135028636778229113005756334730996303888124")), // y + mod_q, BigInteger.One); + + parameters[CryptoProObjectIdentifiers.GostR3410x2001CryptoProB] = ecParams; + + mod_p = new BigInteger("70390085352083305199547718019018437841079516630045180471284346843705633502619"); + mod_q = new BigInteger("70390085352083305199547718019018437840920882647164081035322601458352298396601"); + + curve = ConfigureCurve(new FpCurve( + mod_p, // p + new BigInteger("70390085352083305199547718019018437841079516630045180471284346843705633502616"), + new BigInteger("32858"), + mod_q, BigInteger.One)); + + ecParams = new ECDomainParameters( + curve, + ConfigureBasepoint(curve, + new BigInteger("0"), + new BigInteger("29818893917731240733471273240314769927240550812383695689146495261604565990247")), + mod_q, BigInteger.One); + + parameters[CryptoProObjectIdentifiers.GostR3410x2001CryptoProXchB] = ecParams; + + mod_p = new BigInteger("70390085352083305199547718019018437841079516630045180471284346843705633502619"); //p + mod_q = new BigInteger("70390085352083305199547718019018437840920882647164081035322601458352298396601"); //q + + curve = ConfigureCurve(new FpCurve( + mod_p, // p + new BigInteger("70390085352083305199547718019018437841079516630045180471284346843705633502616"), // a + new BigInteger("32858"), // b + mod_q, BigInteger.One)); + + ecParams = new ECDomainParameters( + curve, + ConfigureBasepoint(curve, + new BigInteger("0"), // x + new BigInteger("29818893917731240733471273240314769927240550812383695689146495261604565990247")), // y + mod_q, BigInteger.One); + + parameters[CryptoProObjectIdentifiers.GostR3410x2001CryptoProC] = ecParams; + + //GOST34.10 2012 + mod_p = new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD97", 16); //p + mod_q = new BigInteger("400000000000000000000000000000000FD8CDDFC87B6635C115AF556C360C67", 16); //q + + curve = ConfigureCurve(new FpCurve( + mod_p, // p + new BigInteger("C2173F1513981673AF4892C23035A27CE25E2013BF95AA33B22C656F277E7335", 16), // a + new BigInteger("295F9BAE7428ED9CCC20E7C359A9D41A22FCCD9108E17BF7BA9337A6F8AE9513", 16), // b + mod_q, BigInteger.Four)); + + ecParams = new ECDomainParameters( + curve, + ConfigureBasepoint(curve, + new BigInteger("91E38443A5E82C0D880923425712B2BB658B9196932E02C78B2582FE742DAA28", 16), // x + new BigInteger("32879423AB1A0375895786C4BB46E9565FDE0B5344766740AF268ADB32322E5C", 16)), // y + mod_q, BigInteger.Four); + + parameters[RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256_paramSetA] = ecParams; + + mod_p = new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC7", 16); //p + mod_q = new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27E69532F48D89116FF22B8D4E0560609B4B38ABFAD2B85DCACDB1411F10B275", 16); //q + + curve = ConfigureCurve(new FpCurve( + mod_p, // p + new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC4", 16), // a + new BigInteger("E8C2505DEDFC86DDC1BD0B2B6667F1DA34B82574761CB0E879BD081CFD0B6265EE3CB090F30D27614CB4574010DA90DD862EF9D4EBEE4761503190785A71C760", 16), // b + mod_q, BigInteger.One)); + + ecParams = new ECDomainParameters( + curve, + ConfigureBasepoint(curve, + new BigInteger("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003"), // x + new BigInteger("7503CFE87A836AE3A61B8816E25450E6CE5E1C93ACF1ABC1778064FDCBEFA921DF1626BE4FD036E93D75E6A50E3A41E98028FE5FC235F5B889A589CB5215F2A4", 16)), // y + mod_q, BigInteger.One); + + parameters[RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512_paramSetA] = ecParams; + + mod_p = new BigInteger("8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006F", 16); //p + mod_q = new BigInteger("800000000000000000000000000000000000000000000000000000000000000149A1EC142565A545ACFDB77BD9D40CFA8B996712101BEA0EC6346C54374F25BD", 16); //q + + curve = ConfigureCurve(new FpCurve( + mod_p, // p + new BigInteger("8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006C", 16), // a + new BigInteger("687D1B459DC841457E3E06CF6F5E2517B97C7D614AF138BCBF85DC806C4B289F3E965D2DB1416D217F8B276FAD1AB69C50F78BEE1FA3106EFB8CCBC7C5140116", 16), // b + mod_q, BigInteger.One)); + + ecParams = new ECDomainParameters( + curve, + ConfigureBasepoint(curve, + new BigInteger("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002"), // x + new BigInteger("1A8F7EDA389B094C2C071E3647A8940F3C123B697578C213BE6DD9E6C8EC7335DCB228FD1EDF4A39152CBCAAF8C0398828041055F94CEEEC7E21340780FE41BD", 16)), // y + mod_q, BigInteger.One); + + parameters[RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512_paramSetB] = ecParams; + + mod_p = new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC7", 16); //p + mod_q = new BigInteger("3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC98CDBA46506AB004C33A9FF5147502CC8EDA9E7A769A12694623CEF47F023ED", 16); //q + + curve = ConfigureCurve(new FpCurve( + mod_p, // p + new BigInteger("DC9203E514A721875485A529D2C722FB187BC8980EB866644DE41C68E143064546E861C0E2C9EDD92ADE71F46FCF50FF2AD97F951FDA9F2A2EB6546F39689BD3", 16), // a + new BigInteger("B4C4EE28CEBC6C2C8AC12952CF37F16AC7EFB6A9F69F4B57FFDA2E4F0DE5ADE038CBC2FFF719D2C18DE0284B8BFEF3B52B8CC7A5F5BF0A3C8D2319A5312557E1", 16), // b + mod_q, BigInteger.Four)); + + ecParams = new ECDomainParameters( + curve, + ConfigureBasepoint(curve, + new BigInteger("E2E31EDFC23DE7BDEBE241CE593EF5DE2295B7A9CBAEF021D385F7074CEA043AA27272A7AE602BF2A7B9033DB9ED3610C6FB85487EAE97AAC5BC7928C1950148", 16), // x + new BigInteger("F5CE40D95B5EB899ABBCCFF5911CB8577939804D6527378B8C108C3D2090FF9BE18E2D33E3021ED2EF32D85822423B6304F726AA854BAE07D0396E9A9ADDC40F", 16)), // y + mod_q, BigInteger.Four); + + parameters[RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512_paramSetC] = ecParams; + + objIds["GostR3410-2001-CryptoPro-A"] = CryptoProObjectIdentifiers.GostR3410x2001CryptoProA; + objIds["GostR3410-2001-CryptoPro-B"] = CryptoProObjectIdentifiers.GostR3410x2001CryptoProB; + objIds["GostR3410-2001-CryptoPro-C"] = CryptoProObjectIdentifiers.GostR3410x2001CryptoProC; + objIds["GostR3410-2001-CryptoPro-XchA"] = CryptoProObjectIdentifiers.GostR3410x2001CryptoProXchA; + objIds["GostR3410-2001-CryptoPro-XchB"] = CryptoProObjectIdentifiers.GostR3410x2001CryptoProXchB; + objIds["Tc26-Gost-3410-12-256-paramSetA"] = RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256_paramSetA; + objIds["Tc26-Gost-3410-12-512-paramSetA"] = RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512_paramSetA; + objIds["Tc26-Gost-3410-12-512-paramSetB"] = RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512_paramSetB; + objIds["Tc26-Gost-3410-12-512-paramSetC"] = RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512_paramSetC; + + names[CryptoProObjectIdentifiers.GostR3410x2001CryptoProA] = "GostR3410-2001-CryptoPro-A"; + names[CryptoProObjectIdentifiers.GostR3410x2001CryptoProB] = "GostR3410-2001-CryptoPro-B"; + names[CryptoProObjectIdentifiers.GostR3410x2001CryptoProC] = "GostR3410-2001-CryptoPro-C"; + names[CryptoProObjectIdentifiers.GostR3410x2001CryptoProXchA] = "GostR3410-2001-CryptoPro-XchA"; + names[CryptoProObjectIdentifiers.GostR3410x2001CryptoProXchB] = "GostR3410-2001-CryptoPro-XchB"; + names[RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256_paramSetA] = "Tc26-Gost-3410-12-256-paramSetA"; + names[RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512_paramSetA] = "Tc26-Gost-3410-12-512-paramSetA"; + names[RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512_paramSetB] = "Tc26-Gost-3410-12-512-paramSetB"; + names[RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512_paramSetC] = "Tc26-Gost-3410-12-512-paramSetC"; + } + + /** + * return the ECDomainParameters object for the given OID, null if it + * isn't present. + * + * @param oid an object identifier representing a named parameters, if present. + */ + [Obsolete("Use 'GetByOidX9' instead")] + public static ECDomainParameters GetByOid(DerObjectIdentifier oid) + { + return (ECDomainParameters)parameters[oid]; + } + + public static X9ECParameters GetByOidX9(DerObjectIdentifier oid) + { + ECDomainParameters ec = (ECDomainParameters)parameters[oid]; + return ec == null ? null : new X9ECParameters(ec.Curve, new X9ECPoint(ec.G, false), ec.N, ec.H, ec.GetSeed()); + } + + /** + * returns an enumeration containing the name strings for curves + * contained in this structure. + */ + public static IEnumerable Names + { + get { return new EnumerableProxy(names.Values); } + } + + [Obsolete("Use 'GetByNameX9' instead")] + public static ECDomainParameters GetByName(string name) + { + DerObjectIdentifier oid = (DerObjectIdentifier)objIds[name]; + return oid == null ? null : (ECDomainParameters)parameters[oid]; + } + + public static X9ECParameters GetByNameX9(string name) + { + DerObjectIdentifier oid = (DerObjectIdentifier)objIds[name]; + return oid == null ? null : GetByOidX9(oid); + } + + /** + * return the named curve name represented by the given object identifier. + */ + public static string GetName( + DerObjectIdentifier oid) + { + return (string)names[oid]; + } + + public static DerObjectIdentifier GetOid( + string name) + { + return (DerObjectIdentifier)objIds[name]; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cryptopro/ECGOST3410NamedCurves.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cryptopro/ECGOST3410NamedCurves.cs.meta new file mode 100644 index 0000000..d29dad9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cryptopro/ECGOST3410NamedCurves.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9017e8cc096554e41a33d14dcfcd3fc5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cryptopro/ECGOST3410ParamSetParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cryptopro/ECGOST3410ParamSetParameters.cs new file mode 100644 index 0000000..8e568a2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cryptopro/ECGOST3410ParamSetParameters.cs @@ -0,0 +1,87 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.CryptoPro +{ + public class ECGost3410ParamSetParameters + : Asn1Encodable + { + internal readonly DerInteger p, q, a, b, x, y; + + public static ECGost3410ParamSetParameters GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static ECGost3410ParamSetParameters GetInstance( + object obj) + { + if (obj == null || obj is ECGost3410ParamSetParameters) + { + return (ECGost3410ParamSetParameters) obj; + } + + if (obj is Asn1Sequence) + { + return new ECGost3410ParamSetParameters((Asn1Sequence) obj); + } + + throw new ArgumentException("Invalid GOST3410Parameter: " + Platform.GetTypeName(obj)); + } + + public ECGost3410ParamSetParameters( + BigInteger a, + BigInteger b, + BigInteger p, + BigInteger q, + int x, + BigInteger y) + { + this.a = new DerInteger(a); + this.b = new DerInteger(b); + this.p = new DerInteger(p); + this.q = new DerInteger(q); + this.x = new DerInteger(x); + this.y = new DerInteger(y); + } + + public ECGost3410ParamSetParameters( + Asn1Sequence seq) + { + if (seq.Count != 6) + throw new ArgumentException("Wrong number of elements in sequence", "seq"); + + this.a = DerInteger.GetInstance(seq[0]); + this.b = DerInteger.GetInstance(seq[1]); + this.p = DerInteger.GetInstance(seq[2]); + this.q = DerInteger.GetInstance(seq[3]); + this.x = DerInteger.GetInstance(seq[4]); + this.y = DerInteger.GetInstance(seq[5]); + } + + public BigInteger P + { + get { return p.PositiveValue; } + } + + public BigInteger Q + { + get { return q.PositiveValue; } + } + + public BigInteger A + { + get { return a.PositiveValue; } + } + + public override Asn1Object ToAsn1Object() + { + return new DerSequence(a, b, p, q, x, y); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cryptopro/ECGOST3410ParamSetParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cryptopro/ECGOST3410ParamSetParameters.cs.meta new file mode 100644 index 0000000..374137f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cryptopro/ECGOST3410ParamSetParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6df1f3f286a280c4987f99a121cd3a7d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cryptopro/GOST28147Parameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cryptopro/GOST28147Parameters.cs new file mode 100644 index 0000000..fc0d792 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cryptopro/GOST28147Parameters.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.CryptoPro +{ + public class Gost28147Parameters + : Asn1Encodable + { + private readonly Asn1OctetString iv; + private readonly DerObjectIdentifier paramSet; + + public static Gost28147Parameters GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static Gost28147Parameters GetInstance( + object obj) + { + if (obj == null || obj is Gost28147Parameters) + { + return (Gost28147Parameters) obj; + } + + if (obj is Asn1Sequence) + { + return new Gost28147Parameters((Asn1Sequence) obj); + } + + throw new ArgumentException("Invalid GOST3410Parameter: " + Platform.GetTypeName(obj)); + } + + private Gost28147Parameters( + Asn1Sequence seq) + { + if (seq.Count != 2) + throw new ArgumentException("Wrong number of elements in sequence", "seq"); + + this.iv = Asn1OctetString.GetInstance(seq[0]); + this.paramSet = DerObjectIdentifier.GetInstance(seq[1]); + } + + /** + *
+         * Gost28147-89-Parameters ::=
+         *               SEQUENCE {
+         *                       iv                   Gost28147-89-IV,
+         *                       encryptionParamSet   OBJECT IDENTIFIER
+         *                }
+         *
+         *   Gost28147-89-IV ::= OCTET STRING (SIZE (8))
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + return new DerSequence(iv, paramSet); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cryptopro/GOST28147Parameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cryptopro/GOST28147Parameters.cs.meta new file mode 100644 index 0000000..06c6765 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cryptopro/GOST28147Parameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8f4efc2721371e44ead81bde4e75983f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cryptopro/GOST3410NamedParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cryptopro/GOST3410NamedParameters.cs new file mode 100644 index 0000000..66dba51 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cryptopro/GOST3410NamedParameters.cs @@ -0,0 +1,123 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Asn1.CryptoPro +{ + /** + * table of the available named parameters for GOST 3410-94. + */ + public sealed class Gost3410NamedParameters + { + private Gost3410NamedParameters() + { + } + + private static readonly IDictionary objIds = Platform.CreateHashtable(); + private static readonly IDictionary parameters = Platform.CreateHashtable(); + + private static readonly Gost3410ParamSetParameters cryptoProA = new Gost3410ParamSetParameters( + 1024, + new BigInteger("127021248288932417465907042777176443525787653508916535812817507265705031260985098497423188333483401180925999995120988934130659205614996724254121049274349357074920312769561451689224110579311248812610229678534638401693520013288995000362260684222750813532307004517341633685004541062586971416883686778842537820383"), + new BigInteger("68363196144955700784444165611827252895102170888761442055095051287550314083023"), + new BigInteger("100997906755055304772081815535925224869841082572053457874823515875577147990529272777244152852699298796483356699682842027972896052747173175480590485607134746852141928680912561502802222185647539190902656116367847270145019066794290930185446216399730872221732889830323194097355403213400972588322876850946740663962") + // validationAlgorithm { + // algorithm + // id-GostR3410-94-bBis, + // parameters + // GostR3410-94-ValidationBisParameters: { + // x0 1376285941, + // c 3996757427 + // } + // } + + ); + + private static readonly Gost3410ParamSetParameters cryptoProB = new Gost3410ParamSetParameters( + 1024, + new BigInteger("139454871199115825601409655107690713107041707059928031797758001454375765357722984094124368522288239833039114681648076688236921220737322672160740747771700911134550432053804647694904686120113087816240740184800477047157336662926249423571248823968542221753660143391485680840520336859458494803187341288580489525163"), + new BigInteger("79885141663410976897627118935756323747307951916507639758300472692338873533959"), + new BigInteger("42941826148615804143873447737955502392672345968607143066798112994089471231420027060385216699563848719957657284814898909770759462613437669456364882730370838934791080835932647976778601915343474400961034231316672578686920482194932878633360203384797092684342247621055760235016132614780652761028509445403338652341") + // validationAlgorithm { + // algorithm + // id-GostR3410-94-bBis, + // parameters + // GostR3410-94-ValidationBisParameters: { + // x0 1536654555, + // c 1855361757, + // d 14408629386140014567655 + //4902939282056547857802241461782996702017713059974755104394739915140 + //6115284791024439062735788342744854120601660303926203867703556828005 + //8957203818114895398976594425537561271800850306 + // } + // } + //} + ); + + private static readonly Gost3410ParamSetParameters cryptoProXchA = new Gost3410ParamSetParameters( + 1024, + new BigInteger("142011741597563481196368286022318089743276138395243738762872573441927459393512718973631166078467600360848946623567625795282774719212241929071046134208380636394084512691828894000571524625445295769349356752728956831541775441763139384457191755096847107846595662547942312293338483924514339614727760681880609734239"), + new BigInteger("91771529896554605945588149018382750217296858393520724172743325725474374979801"), + new BigInteger("133531813272720673433859519948319001217942375967847486899482359599369642528734712461590403327731821410328012529253871914788598993103310567744136196364803064721377826656898686468463277710150809401182608770201615324990468332931294920912776241137878030224355746606283971659376426832674269780880061631528163475887") + ); + + static Gost3410NamedParameters() + { + parameters[CryptoProObjectIdentifiers.GostR3410x94CryptoProA] = cryptoProA; + parameters[CryptoProObjectIdentifiers.GostR3410x94CryptoProB] = cryptoProB; + //parameters[CryptoProObjectIdentifiers.GostR3410x94CryptoProC] = cryptoProC; + //parameters[CryptoProObjectIdentifiers.GostR3410x94CryptoProD] = cryptoProD; + parameters[CryptoProObjectIdentifiers.GostR3410x94CryptoProXchA] = cryptoProXchA; + //parameters[CryptoProObjectIdentifiers.GostR3410x94CryptoProXchB] = cryptoProXchA; + //parameters[CryptoProObjectIdentifiers.GostR3410x94CryptoProXchC] = cryptoProXchA; + + objIds["GostR3410-94-CryptoPro-A"] = CryptoProObjectIdentifiers.GostR3410x94CryptoProA; + objIds["GostR3410-94-CryptoPro-B"] = CryptoProObjectIdentifiers.GostR3410x94CryptoProB; + objIds["GostR3410-94-CryptoPro-XchA"] = CryptoProObjectIdentifiers.GostR3410x94CryptoProXchA; + } + + /** + * return the GOST3410ParamSetParameters object for the given OID, null if it + * isn't present. + * + * @param oid an object identifier representing a named parameters, if present. + */ + public static Gost3410ParamSetParameters GetByOid( + DerObjectIdentifier oid) + { + return (Gost3410ParamSetParameters) parameters[oid]; + } + + /** + * returns an enumeration containing the name strings for parameters + * contained in this structure. + */ + public static IEnumerable Names + { + get { return new EnumerableProxy(objIds.Keys); } + } + + public static Gost3410ParamSetParameters GetByName( + string name) + { + DerObjectIdentifier oid = (DerObjectIdentifier) objIds[name]; + + if (oid != null) + { + return (Gost3410ParamSetParameters) parameters[oid]; + } + + return null; + } + + public static DerObjectIdentifier GetOid( + string name) + { + return (DerObjectIdentifier) objIds[name]; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cryptopro/GOST3410NamedParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cryptopro/GOST3410NamedParameters.cs.meta new file mode 100644 index 0000000..075ee0a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cryptopro/GOST3410NamedParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4e45a0a42a302814e91f9e60ce01308e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cryptopro/GOST3410ParamSetParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cryptopro/GOST3410ParamSetParameters.cs new file mode 100644 index 0000000..ee6ed8c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cryptopro/GOST3410ParamSetParameters.cs @@ -0,0 +1,87 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.CryptoPro +{ + public class Gost3410ParamSetParameters + : Asn1Encodable + { + private readonly int keySize; + private readonly DerInteger p, q, a; + + public static Gost3410ParamSetParameters GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static Gost3410ParamSetParameters GetInstance( + object obj) + { + if (obj == null || obj is Gost3410ParamSetParameters) + { + return (Gost3410ParamSetParameters) obj; + } + + if (obj is Asn1Sequence) + { + return new Gost3410ParamSetParameters((Asn1Sequence) obj); + } + + throw new ArgumentException("Invalid GOST3410Parameter: " + Platform.GetTypeName(obj)); + } + + public Gost3410ParamSetParameters( + int keySize, + BigInteger p, + BigInteger q, + BigInteger a) + { + this.keySize = keySize; + this.p = new DerInteger(p); + this.q = new DerInteger(q); + this.a = new DerInteger(a); + } + + private Gost3410ParamSetParameters( + Asn1Sequence seq) + { + if (seq.Count != 4) + throw new ArgumentException("Wrong number of elements in sequence", "seq"); + + this.keySize = DerInteger.GetInstance(seq[0]).IntValueExact; + this.p = DerInteger.GetInstance(seq[1]); + this.q = DerInteger.GetInstance(seq[2]); + this.a = DerInteger.GetInstance(seq[3]); + } + + public int KeySize + { + get { return keySize; } + } + + public BigInteger P + { + get { return p.PositiveValue; } + } + + public BigInteger Q + { + get { return q.PositiveValue; } + } + + public BigInteger A + { + get { return a.PositiveValue; } + } + + public override Asn1Object ToAsn1Object() + { + return new DerSequence(new DerInteger(keySize), p, q, a); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cryptopro/GOST3410ParamSetParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cryptopro/GOST3410ParamSetParameters.cs.meta new file mode 100644 index 0000000..80c3e17 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cryptopro/GOST3410ParamSetParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 65a6a1c54de5e0245a9ae992e0e9494a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cryptopro/GOST3410PublicKeyAlgParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cryptopro/GOST3410PublicKeyAlgParameters.cs new file mode 100644 index 0000000..c32025e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cryptopro/GOST3410PublicKeyAlgParameters.cs @@ -0,0 +1,87 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.CryptoPro +{ + public class Gost3410PublicKeyAlgParameters + : Asn1Encodable + { + private DerObjectIdentifier publicKeyParamSet; + private DerObjectIdentifier digestParamSet; + private DerObjectIdentifier encryptionParamSet; + + public static Gost3410PublicKeyAlgParameters GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static Gost3410PublicKeyAlgParameters GetInstance( + object obj) + { + if (obj == null || obj is Gost3410PublicKeyAlgParameters) + return (Gost3410PublicKeyAlgParameters)obj; + + return new Gost3410PublicKeyAlgParameters(Asn1Sequence.GetInstance((obj))); + } + + public Gost3410PublicKeyAlgParameters( + DerObjectIdentifier publicKeyParamSet, + DerObjectIdentifier digestParamSet) + : this (publicKeyParamSet, digestParamSet, null) + { + } + + public Gost3410PublicKeyAlgParameters( + DerObjectIdentifier publicKeyParamSet, + DerObjectIdentifier digestParamSet, + DerObjectIdentifier encryptionParamSet) + { + if (publicKeyParamSet == null) + throw new ArgumentNullException("publicKeyParamSet"); + if (digestParamSet == null) + throw new ArgumentNullException("digestParamSet"); + + this.publicKeyParamSet = publicKeyParamSet; + this.digestParamSet = digestParamSet; + this.encryptionParamSet = encryptionParamSet; + } + + [Obsolete("Use 'GetInstance' instead")] + public Gost3410PublicKeyAlgParameters( + Asn1Sequence seq) + { + this.publicKeyParamSet = (DerObjectIdentifier) seq[0]; + this.digestParamSet = (DerObjectIdentifier) seq[1]; + + if (seq.Count > 2) + { + this.encryptionParamSet = (DerObjectIdentifier) seq[2]; + } + } + + public DerObjectIdentifier PublicKeyParamSet + { + get { return publicKeyParamSet; } + } + + public DerObjectIdentifier DigestParamSet + { + get { return digestParamSet; } + } + + public DerObjectIdentifier EncryptionParamSet + { + get { return encryptionParamSet; } + } + + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(publicKeyParamSet, digestParamSet); + v.AddOptional(encryptionParamSet); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cryptopro/GOST3410PublicKeyAlgParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cryptopro/GOST3410PublicKeyAlgParameters.cs.meta new file mode 100644 index 0000000..5c4e877 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/cryptopro/GOST3410PublicKeyAlgParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bbdd43d61bc26cb40ae4fb6fe4b0bc1a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/eac.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/eac.meta new file mode 100644 index 0000000..d64f716 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/eac.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 536346cad4e915a40bc454d3c00385f2 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/eac/EACObjectIdentifiers.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/eac/EACObjectIdentifiers.cs new file mode 100644 index 0000000..d54ef0e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/eac/EACObjectIdentifiers.cs @@ -0,0 +1,50 @@ +using System; + +using Org.BouncyCastle.Asn1; + +namespace Org.BouncyCastle.Asn1.Eac +{ + public abstract class EacObjectIdentifiers + { + // bsi-de OBJECT IDENTIFIER ::= { + // itu-t(0) identified-organization(4) etsi(0) + // reserved(127) etsi-identified-organization(0) 7 + // } + public static readonly DerObjectIdentifier bsi_de = new DerObjectIdentifier("0.4.0.127.0.7"); + + // id-PK OBJECT IDENTIFIER ::= { + // bsi-de protocols(2) smartcard(2) 1 + // } + public static readonly DerObjectIdentifier id_PK = new DerObjectIdentifier(bsi_de + ".2.2.1"); + + public static readonly DerObjectIdentifier id_PK_DH = new DerObjectIdentifier(id_PK + ".1"); + public static readonly DerObjectIdentifier id_PK_ECDH = new DerObjectIdentifier(id_PK + ".2"); + + // id-CA OBJECT IDENTIFIER ::= { + // bsi-de protocols(2) smartcard(2) 3 + // } + public static readonly DerObjectIdentifier id_CA = new DerObjectIdentifier(bsi_de + ".2.2.3"); + public static readonly DerObjectIdentifier id_CA_DH = new DerObjectIdentifier(id_CA + ".1"); + public static readonly DerObjectIdentifier id_CA_DH_3DES_CBC_CBC = new DerObjectIdentifier(id_CA_DH + ".1"); + public static readonly DerObjectIdentifier id_CA_ECDH = new DerObjectIdentifier(id_CA + ".2"); + public static readonly DerObjectIdentifier id_CA_ECDH_3DES_CBC_CBC = new DerObjectIdentifier(id_CA_ECDH + ".1"); + + // + // id-TA OBJECT IDENTIFIER ::= { + // bsi-de protocols(2) smartcard(2) 2 + // } + public static readonly DerObjectIdentifier id_TA = new DerObjectIdentifier(bsi_de + ".2.2.2"); + + public static readonly DerObjectIdentifier id_TA_RSA = new DerObjectIdentifier(id_TA + ".1"); + public static readonly DerObjectIdentifier id_TA_RSA_v1_5_SHA_1 = new DerObjectIdentifier(id_TA_RSA + ".1"); + public static readonly DerObjectIdentifier id_TA_RSA_v1_5_SHA_256 = new DerObjectIdentifier(id_TA_RSA + ".2"); + public static readonly DerObjectIdentifier id_TA_RSA_PSS_SHA_1 = new DerObjectIdentifier(id_TA_RSA + ".3"); + public static readonly DerObjectIdentifier id_TA_RSA_PSS_SHA_256 = new DerObjectIdentifier(id_TA_RSA + ".4"); + public static readonly DerObjectIdentifier id_TA_ECDSA = new DerObjectIdentifier(id_TA + ".2"); + public static readonly DerObjectIdentifier id_TA_ECDSA_SHA_1 = new DerObjectIdentifier(id_TA_ECDSA + ".1"); + public static readonly DerObjectIdentifier id_TA_ECDSA_SHA_224 = new DerObjectIdentifier(id_TA_ECDSA + ".2"); + public static readonly DerObjectIdentifier id_TA_ECDSA_SHA_256 = new DerObjectIdentifier(id_TA_ECDSA + ".3"); + public static readonly DerObjectIdentifier id_TA_ECDSA_SHA_384 = new DerObjectIdentifier(id_TA_ECDSA + ".4"); + public static readonly DerObjectIdentifier id_TA_ECDSA_SHA_512 = new DerObjectIdentifier(id_TA_ECDSA + ".5"); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/eac/EACObjectIdentifiers.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/eac/EACObjectIdentifiers.cs.meta new file mode 100644 index 0000000..4e7d37a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/eac/EACObjectIdentifiers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 39ed5f06122c14c428a0c75564dd0a16 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/edec.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/edec.meta new file mode 100644 index 0000000..589e834 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/edec.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: cea6fe5e920d41a4da8771b1b46c3ce3 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/edec/EdECObjectIdentifiers.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/edec/EdECObjectIdentifiers.cs new file mode 100644 index 0000000..f8c5713 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/edec/EdECObjectIdentifiers.cs @@ -0,0 +1,17 @@ +using System; + +namespace Org.BouncyCastle.Asn1.EdEC +{ + /** + * Edwards Elliptic Curve Object Identifiers (RFC 8410) + */ + public abstract class EdECObjectIdentifiers + { + public static readonly DerObjectIdentifier id_edwards_curve_algs = new DerObjectIdentifier("1.3.101"); + + public static readonly DerObjectIdentifier id_X25519 = id_edwards_curve_algs.Branch("110"); + public static readonly DerObjectIdentifier id_X448 = id_edwards_curve_algs.Branch("111"); + public static readonly DerObjectIdentifier id_Ed25519 = id_edwards_curve_algs.Branch("112"); + public static readonly DerObjectIdentifier id_Ed448 = id_edwards_curve_algs.Branch("113"); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/edec/EdECObjectIdentifiers.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/edec/EdECObjectIdentifiers.cs.meta new file mode 100644 index 0000000..91ea4cf --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/edec/EdECObjectIdentifiers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: baee2d064fb329e4cb37437b085daa8a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf.meta new file mode 100644 index 0000000..26aecd2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 74c9abb93cdf274478bc7dac89a4c45d +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CertificateValues.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CertificateValues.cs new file mode 100644 index 0000000..30a7191 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CertificateValues.cs @@ -0,0 +1,86 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Asn1.Esf +{ + /// + /// RFC 3126: 4.3.1 Certificate Values Attribute Definition + /// + /// CertificateValues ::= SEQUENCE OF Certificate + /// + /// + public class CertificateValues + : Asn1Encodable + { + private readonly Asn1Sequence certificates; + + public static CertificateValues GetInstance( + object obj) + { + if (obj == null || obj is CertificateValues) + return (CertificateValues) obj; + + if (obj is Asn1Sequence) + return new CertificateValues((Asn1Sequence) obj); + + throw new ArgumentException( + "Unknown object in 'CertificateValues' factory: " + + Platform.GetTypeName(obj), + "obj"); + } + + private CertificateValues( + Asn1Sequence seq) + { + if (seq == null) + throw new ArgumentNullException("seq"); + + foreach (Asn1Encodable ae in seq) + { + X509CertificateStructure.GetInstance(ae.ToAsn1Object()); + } + + this.certificates = seq; + } + + public CertificateValues( + params X509CertificateStructure[] certificates) + { + if (certificates == null) + throw new ArgumentNullException("certificates"); + + this.certificates = new DerSequence(certificates); + } + + public CertificateValues( + IEnumerable certificates) + { + if (certificates == null) + throw new ArgumentNullException("certificates"); + if (!CollectionUtilities.CheckElementsAreOfType(certificates, typeof(X509CertificateStructure))) + throw new ArgumentException("Must contain only 'X509CertificateStructure' objects", "certificates"); + + this.certificates = new DerSequence( + Asn1EncodableVector.FromEnumerable(certificates)); + } + + public X509CertificateStructure[] GetCertificates() + { + X509CertificateStructure[] result = new X509CertificateStructure[certificates.Count]; + for (int i = 0; i < certificates.Count; ++i) + { + result[i] = X509CertificateStructure.GetInstance(certificates[i]); + } + return result; + } + + public override Asn1Object ToAsn1Object() + { + return certificates; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CertificateValues.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CertificateValues.cs.meta new file mode 100644 index 0000000..d8a316d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CertificateValues.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8601d106c2284584a9f16cb01ebc0412 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CommitmentTypeIdentifier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CommitmentTypeIdentifier.cs new file mode 100644 index 0000000..65cd45b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CommitmentTypeIdentifier.cs @@ -0,0 +1,17 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Pkcs; + +namespace Org.BouncyCastle.Asn1.Esf +{ + public abstract class CommitmentTypeIdentifier + { + public static readonly DerObjectIdentifier ProofOfOrigin = PkcsObjectIdentifiers.IdCtiEtsProofOfOrigin; + public static readonly DerObjectIdentifier ProofOfReceipt = PkcsObjectIdentifiers.IdCtiEtsProofOfReceipt; + public static readonly DerObjectIdentifier ProofOfDelivery = PkcsObjectIdentifiers.IdCtiEtsProofOfDelivery; + public static readonly DerObjectIdentifier ProofOfSender = PkcsObjectIdentifiers.IdCtiEtsProofOfSender; + public static readonly DerObjectIdentifier ProofOfApproval = PkcsObjectIdentifiers.IdCtiEtsProofOfApproval; + public static readonly DerObjectIdentifier ProofOfCreation = PkcsObjectIdentifiers.IdCtiEtsProofOfCreation; + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CommitmentTypeIdentifier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CommitmentTypeIdentifier.cs.meta new file mode 100644 index 0000000..3fb0c59 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CommitmentTypeIdentifier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6531c69f26872464e912f12267d31110 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CommitmentTypeIndication.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CommitmentTypeIndication.cs new file mode 100644 index 0000000..ecdb100 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CommitmentTypeIndication.cs @@ -0,0 +1,90 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Esf +{ + public class CommitmentTypeIndication + : Asn1Encodable + { + private readonly DerObjectIdentifier commitmentTypeId; + private readonly Asn1Sequence commitmentTypeQualifier; + + public static CommitmentTypeIndication GetInstance( + object obj) + { + if (obj == null || obj is CommitmentTypeIndication) + return (CommitmentTypeIndication) obj; + + if (obj is Asn1Sequence) + return new CommitmentTypeIndication((Asn1Sequence) obj); + + throw new ArgumentException( + "Unknown object in 'CommitmentTypeIndication' factory: " + + Platform.GetTypeName(obj), + "obj"); + } + + public CommitmentTypeIndication( + Asn1Sequence seq) + { + if (seq == null) + throw new ArgumentNullException("seq"); + if (seq.Count < 1 || seq.Count > 2) + throw new ArgumentException("Bad sequence size: " + seq.Count, "seq"); + + this.commitmentTypeId = (DerObjectIdentifier) seq[0].ToAsn1Object(); + + if (seq.Count > 1) + { + this.commitmentTypeQualifier = (Asn1Sequence) seq[1].ToAsn1Object(); + } + } + + public CommitmentTypeIndication( + DerObjectIdentifier commitmentTypeId) + : this(commitmentTypeId, null) + { + } + + public CommitmentTypeIndication( + DerObjectIdentifier commitmentTypeId, + Asn1Sequence commitmentTypeQualifier) + { + if (commitmentTypeId == null) + throw new ArgumentNullException("commitmentTypeId"); + + this.commitmentTypeId = commitmentTypeId; + + if (commitmentTypeQualifier != null) + { + this.commitmentTypeQualifier = commitmentTypeQualifier; + } + } + + public DerObjectIdentifier CommitmentTypeID + { + get { return commitmentTypeId; } + } + + public Asn1Sequence CommitmentTypeQualifier + { + get { return commitmentTypeQualifier; } + } + + /** + *
+        * CommitmentTypeIndication ::= SEQUENCE {
+        *      commitmentTypeId   CommitmentTypeIdentifier,
+        *      commitmentTypeQualifier   SEQUENCE SIZE (1..MAX) OF
+        *              CommitmentTypeQualifier OPTIONAL }
+        * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(commitmentTypeId); + v.AddOptional(commitmentTypeQualifier); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CommitmentTypeIndication.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CommitmentTypeIndication.cs.meta new file mode 100644 index 0000000..eb95e43 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CommitmentTypeIndication.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e4be3e8d07d3ed5448c1dd534352cc61 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CommitmentTypeQualifier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CommitmentTypeQualifier.cs new file mode 100644 index 0000000..acf19f9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CommitmentTypeQualifier.cs @@ -0,0 +1,113 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Esf +{ + /** + * Commitment type qualifiers, used in the Commitment-Type-Indication attribute (RFC3126). + * + *
+    *   CommitmentTypeQualifier ::= SEQUENCE {
+    *       commitmentTypeIdentifier  CommitmentTypeIdentifier,
+    *       qualifier          ANY DEFINED BY commitmentTypeIdentifier OPTIONAL }
+    * 
+ */ + public class CommitmentTypeQualifier + : Asn1Encodable + { + private readonly DerObjectIdentifier commitmentTypeIdentifier; + private readonly Asn1Object qualifier; + + /** + * Creates a new CommitmentTypeQualifier instance. + * + * @param commitmentTypeIdentifier a CommitmentTypeIdentifier value + */ + public CommitmentTypeQualifier( + DerObjectIdentifier commitmentTypeIdentifier) + : this(commitmentTypeIdentifier, null) + { + } + + /** + * Creates a new CommitmentTypeQualifier instance. + * + * @param commitmentTypeIdentifier a CommitmentTypeIdentifier value + * @param qualifier the qualifier, defined by the above field. + */ + public CommitmentTypeQualifier( + DerObjectIdentifier commitmentTypeIdentifier, + Asn1Encodable qualifier) + { + if (commitmentTypeIdentifier == null) + throw new ArgumentNullException("commitmentTypeIdentifier"); + + this.commitmentTypeIdentifier = commitmentTypeIdentifier; + + if (qualifier != null) + { + this.qualifier = qualifier.ToAsn1Object(); + } + } + + /** + * Creates a new CommitmentTypeQualifier instance. + * + * @param as CommitmentTypeQualifier structure + * encoded as an Asn1Sequence. + */ + public CommitmentTypeQualifier( + Asn1Sequence seq) + { + if (seq == null) + throw new ArgumentNullException("seq"); + if (seq.Count < 1 || seq.Count > 2) + throw new ArgumentException("Bad sequence size: " + seq.Count, "seq"); + + commitmentTypeIdentifier = (DerObjectIdentifier) seq[0].ToAsn1Object(); + + if (seq.Count > 1) + { + qualifier = seq[1].ToAsn1Object(); + } + } + + public static CommitmentTypeQualifier GetInstance( + object obj) + { + if (obj == null || obj is CommitmentTypeQualifier) + return (CommitmentTypeQualifier) obj; + + if (obj is Asn1Sequence) + return new CommitmentTypeQualifier((Asn1Sequence) obj); + + throw new ArgumentException( + "Unknown object in 'CommitmentTypeQualifier' factory: " + + Platform.GetTypeName(obj), + "obj"); + } + + public DerObjectIdentifier CommitmentTypeIdentifier + { + get { return commitmentTypeIdentifier; } + } + + public Asn1Object Qualifier + { + get { return qualifier; } + } + + /** + * Returns a DER-encodable representation of this instance. + * + * @return a Asn1Object value + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(commitmentTypeIdentifier); + v.AddOptional(qualifier); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CommitmentTypeQualifier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CommitmentTypeQualifier.cs.meta new file mode 100644 index 0000000..6a102f7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CommitmentTypeQualifier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b4acd2d522c6bfc4bafd46fa22c5a925 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CompleteCertificateRefs.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CompleteCertificateRefs.cs new file mode 100644 index 0000000..af93700 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CompleteCertificateRefs.cs @@ -0,0 +1,85 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Asn1.Esf +{ + /// + /// RFC 3126: 4.2.1 Complete Certificate Refs Attribute Definition + /// + /// CompleteCertificateRefs ::= SEQUENCE OF OtherCertID + /// + /// + public class CompleteCertificateRefs + : Asn1Encodable + { + private readonly Asn1Sequence otherCertIDs; + + public static CompleteCertificateRefs GetInstance( + object obj) + { + if (obj == null || obj is CompleteCertificateRefs) + return (CompleteCertificateRefs) obj; + + if (obj is Asn1Sequence) + return new CompleteCertificateRefs((Asn1Sequence) obj); + + throw new ArgumentException( + "Unknown object in 'CompleteCertificateRefs' factory: " + + Platform.GetTypeName(obj), + "obj"); + } + + private CompleteCertificateRefs( + Asn1Sequence seq) + { + if (seq == null) + throw new ArgumentNullException("seq"); + + foreach (Asn1Encodable ae in seq) + { + OtherCertID.GetInstance(ae.ToAsn1Object()); + } + + this.otherCertIDs = seq; + } + + public CompleteCertificateRefs( + params OtherCertID[] otherCertIDs) + { + if (otherCertIDs == null) + throw new ArgumentNullException("otherCertIDs"); + + this.otherCertIDs = new DerSequence(otherCertIDs); + } + + public CompleteCertificateRefs( + IEnumerable otherCertIDs) + { + if (otherCertIDs == null) + throw new ArgumentNullException("otherCertIDs"); + if (!CollectionUtilities.CheckElementsAreOfType(otherCertIDs, typeof(OtherCertID))) + throw new ArgumentException("Must contain only 'OtherCertID' objects", "otherCertIDs"); + + this.otherCertIDs = new DerSequence( + Asn1EncodableVector.FromEnumerable(otherCertIDs)); + } + + public OtherCertID[] GetOtherCertIDs() + { + OtherCertID[] result = new OtherCertID[otherCertIDs.Count]; + for (int i = 0; i < otherCertIDs.Count; ++i) + { + result[i] = OtherCertID.GetInstance(otherCertIDs[i].ToAsn1Object()); + } + return result; + } + + public override Asn1Object ToAsn1Object() + { + return otherCertIDs; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CompleteCertificateRefs.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CompleteCertificateRefs.cs.meta new file mode 100644 index 0000000..f2ed55f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CompleteCertificateRefs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5583c76846e9f994ba970663c165936f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CompleteRevocationRefs.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CompleteRevocationRefs.cs new file mode 100644 index 0000000..348e63f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CompleteRevocationRefs.cs @@ -0,0 +1,85 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Asn1.Esf +{ + /// + /// RFC 3126: 4.2.2 Complete Revocation Refs Attribute Definition + /// + /// CompleteRevocationRefs ::= SEQUENCE OF CrlOcspRef + /// + /// + public class CompleteRevocationRefs + : Asn1Encodable + { + private readonly Asn1Sequence crlOcspRefs; + + public static CompleteRevocationRefs GetInstance( + object obj) + { + if (obj == null || obj is CompleteRevocationRefs) + return (CompleteRevocationRefs) obj; + + if (obj is Asn1Sequence) + return new CompleteRevocationRefs((Asn1Sequence) obj); + + throw new ArgumentException( + "Unknown object in 'CompleteRevocationRefs' factory: " + + Platform.GetTypeName(obj), + "obj"); + } + + private CompleteRevocationRefs( + Asn1Sequence seq) + { + if (seq == null) + throw new ArgumentNullException("seq"); + + foreach (Asn1Encodable ae in seq) + { + CrlOcspRef.GetInstance(ae.ToAsn1Object()); + } + + this.crlOcspRefs = seq; + } + + public CompleteRevocationRefs( + params CrlOcspRef[] crlOcspRefs) + { + if (crlOcspRefs == null) + throw new ArgumentNullException("crlOcspRefs"); + + this.crlOcspRefs = new DerSequence(crlOcspRefs); + } + + public CompleteRevocationRefs( + IEnumerable crlOcspRefs) + { + if (crlOcspRefs == null) + throw new ArgumentNullException("crlOcspRefs"); + if (!CollectionUtilities.CheckElementsAreOfType(crlOcspRefs, typeof(CrlOcspRef))) + throw new ArgumentException("Must contain only 'CrlOcspRef' objects", "crlOcspRefs"); + + this.crlOcspRefs = new DerSequence( + Asn1EncodableVector.FromEnumerable(crlOcspRefs)); + } + + public CrlOcspRef[] GetCrlOcspRefs() + { + CrlOcspRef[] result = new CrlOcspRef[crlOcspRefs.Count]; + for (int i = 0; i < crlOcspRefs.Count; ++i) + { + result[i] = CrlOcspRef.GetInstance(crlOcspRefs[i].ToAsn1Object()); + } + return result; + } + + public override Asn1Object ToAsn1Object() + { + return crlOcspRefs; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CompleteRevocationRefs.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CompleteRevocationRefs.cs.meta new file mode 100644 index 0000000..283b540 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CompleteRevocationRefs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ead944604b4284d4497541d46ccf1362 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CrlIdentifier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CrlIdentifier.cs new file mode 100644 index 0000000..a8e40c8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CrlIdentifier.cs @@ -0,0 +1,105 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Esf +{ + /// + /// RFC 3126: 4.2.2 Complete Revocation Refs Attribute Definition + /// + /// CrlIdentifier ::= SEQUENCE + /// { + /// crlissuer Name, + /// crlIssuedTime UTCTime, + /// crlNumber INTEGER OPTIONAL + /// } + /// + /// + public class CrlIdentifier + : Asn1Encodable + { + private readonly X509Name crlIssuer; + private readonly DerUtcTime crlIssuedTime; + private readonly DerInteger crlNumber; + + public static CrlIdentifier GetInstance( + object obj) + { + if (obj == null || obj is CrlIdentifier) + return (CrlIdentifier) obj; + + if (obj is Asn1Sequence) + return new CrlIdentifier((Asn1Sequence) obj); + + throw new ArgumentException( + "Unknown object in 'CrlIdentifier' factory: " + + Platform.GetTypeName(obj), + "obj"); + } + + private CrlIdentifier( + Asn1Sequence seq) + { + if (seq == null) + throw new ArgumentNullException("seq"); + if (seq.Count < 2 || seq.Count > 3) + throw new ArgumentException("Bad sequence size: " + seq.Count, "seq"); + + this.crlIssuer = X509Name.GetInstance(seq[0]); + this.crlIssuedTime = DerUtcTime.GetInstance(seq[1]); + + if (seq.Count > 2) + { + this.crlNumber = DerInteger.GetInstance(seq[2]); + } + } + + public CrlIdentifier( + X509Name crlIssuer, + DateTime crlIssuedTime) + : this(crlIssuer, crlIssuedTime, null) + { + } + + public CrlIdentifier( + X509Name crlIssuer, + DateTime crlIssuedTime, + BigInteger crlNumber) + { + if (crlIssuer == null) + throw new ArgumentNullException("crlIssuer"); + + this.crlIssuer = crlIssuer; + this.crlIssuedTime = new DerUtcTime(crlIssuedTime); + + if (crlNumber != null) + { + this.crlNumber = new DerInteger(crlNumber); + } + } + + public X509Name CrlIssuer + { + get { return crlIssuer; } + } + + public DateTime CrlIssuedTime + { + get { return crlIssuedTime.ToAdjustedDateTime(); } + } + + public BigInteger CrlNumber + { + get { return crlNumber == null ? null : crlNumber.Value; } + } + + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(crlIssuer.ToAsn1Object(), crlIssuedTime); + v.AddOptional(crlNumber); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CrlIdentifier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CrlIdentifier.cs.meta new file mode 100644 index 0000000..cbc16ad --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CrlIdentifier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0ddf0feae0bde184694424c197a608d7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CrlListID.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CrlListID.cs new file mode 100644 index 0000000..fbd4fb2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CrlListID.cs @@ -0,0 +1,90 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Asn1.Esf +{ + /// + /// RFC 3126: 4.2.2 Complete Revocation Refs Attribute Definition + /// + /// CRLListID ::= SEQUENCE + /// { + /// crls SEQUENCE OF CrlValidatedID + /// } + /// + /// + public class CrlListID + : Asn1Encodable + { + private readonly Asn1Sequence crls; + + public static CrlListID GetInstance( + object obj) + { + if (obj == null || obj is CrlListID) + return (CrlListID) obj; + + if (obj is Asn1Sequence) + return new CrlListID((Asn1Sequence) obj); + + throw new ArgumentException( + "Unknown object in 'CrlListID' factory: " + + Platform.GetTypeName(obj), + "obj"); + } + + private CrlListID( + Asn1Sequence seq) + { + if (seq == null) + throw new ArgumentNullException("seq"); + if (seq.Count != 1) + throw new ArgumentException("Bad sequence size: " + seq.Count, "seq"); + + this.crls = (Asn1Sequence) seq[0].ToAsn1Object(); + + foreach (Asn1Encodable ae in this.crls) + { + CrlValidatedID.GetInstance(ae.ToAsn1Object()); + } + } + + public CrlListID( + params CrlValidatedID[] crls) + { + if (crls == null) + throw new ArgumentNullException("crls"); + + this.crls = new DerSequence(crls); + } + + public CrlListID( + IEnumerable crls) + { + if (crls == null) + throw new ArgumentNullException("crls"); + if (!CollectionUtilities.CheckElementsAreOfType(crls, typeof(CrlValidatedID))) + throw new ArgumentException("Must contain only 'CrlValidatedID' objects", "crls"); + + this.crls = new DerSequence( + Asn1EncodableVector.FromEnumerable(crls)); + } + + public CrlValidatedID[] GetCrls() + { + CrlValidatedID[] result = new CrlValidatedID[crls.Count]; + for (int i = 0; i < crls.Count; ++i) + { + result[i] = CrlValidatedID.GetInstance(crls[i].ToAsn1Object()); + } + return result; + } + + public override Asn1Object ToAsn1Object() + { + return new DerSequence(crls); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CrlListID.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CrlListID.cs.meta new file mode 100644 index 0000000..72ad739 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CrlListID.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 792dfd9450caf2b42b149b12ef97d686 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CrlOcspRef.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CrlOcspRef.cs new file mode 100644 index 0000000..6153e0c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CrlOcspRef.cs @@ -0,0 +1,113 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Esf +{ + /// + /// RFC 3126: 4.2.2 Complete Revocation Refs Attribute Definition + /// + /// CrlOcspRef ::= SEQUENCE { + /// crlids [0] CRLListID OPTIONAL, + /// ocspids [1] OcspListID OPTIONAL, + /// otherRev [2] OtherRevRefs OPTIONAL + /// } + /// + /// + public class CrlOcspRef + : Asn1Encodable + { + private readonly CrlListID crlids; + private readonly OcspListID ocspids; + private readonly OtherRevRefs otherRev; + + public static CrlOcspRef GetInstance( + object obj) + { + if (obj == null || obj is CrlOcspRef) + return (CrlOcspRef) obj; + + if (obj is Asn1Sequence) + return new CrlOcspRef((Asn1Sequence) obj); + + throw new ArgumentException( + "Unknown object in 'CrlOcspRef' factory: " + + Platform.GetTypeName(obj), + "obj"); + } + + private CrlOcspRef( + Asn1Sequence seq) + { + if (seq == null) + throw new ArgumentNullException("seq"); + + foreach (Asn1TaggedObject taggedObj in seq) + { + Asn1Object asn1Obj = taggedObj.GetObject(); + + switch (taggedObj.TagNo) + { + case 0: + this.crlids = CrlListID.GetInstance(asn1Obj); + break; + case 1: + this.ocspids = OcspListID.GetInstance(asn1Obj); + break; + case 2: + this.otherRev = OtherRevRefs.GetInstance(asn1Obj); + break; + default: + throw new ArgumentException("Illegal tag in CrlOcspRef", "seq"); + } + } + } + + public CrlOcspRef( + CrlListID crlids, + OcspListID ocspids, + OtherRevRefs otherRev) + { + this.crlids = crlids; + this.ocspids = ocspids; + this.otherRev = otherRev; + } + + public CrlListID CrlIDs + { + get { return crlids; } + } + + public OcspListID OcspIDs + { + get { return ocspids; } + } + + public OtherRevRefs OtherRev + { + get { return otherRev; } + } + + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + + if (crlids != null) + { + v.Add(new DerTaggedObject(true, 0, crlids.ToAsn1Object())); + } + + if (ocspids != null) + { + v.Add(new DerTaggedObject(true, 1, ocspids.ToAsn1Object())); + } + + if (otherRev != null) + { + v.Add(new DerTaggedObject(true, 2, otherRev.ToAsn1Object())); + } + + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CrlOcspRef.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CrlOcspRef.cs.meta new file mode 100644 index 0000000..b463013 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CrlOcspRef.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8c5e17242c151134a9770e29e06e5316 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CrlValidatedID.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CrlValidatedID.cs new file mode 100644 index 0000000..e8cd17a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CrlValidatedID.cs @@ -0,0 +1,91 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Esf +{ + /// + /// RFC 3126: 4.2.2 Complete Revocation Refs Attribute Definition + /// + /// CrlValidatedID ::= SEQUENCE { + /// crlHash OtherHash, + /// crlIdentifier CrlIdentifier OPTIONAL} + /// + /// + public class CrlValidatedID + : Asn1Encodable + { + private readonly OtherHash crlHash; + private readonly CrlIdentifier crlIdentifier; + + public static CrlValidatedID GetInstance( + object obj) + { + if (obj == null || obj is CrlValidatedID) + return (CrlValidatedID) obj; + + if (obj is Asn1Sequence) + return new CrlValidatedID((Asn1Sequence) obj); + + throw new ArgumentException( + "Unknown object in 'CrlValidatedID' factory: " + + Platform.GetTypeName(obj), + "obj"); + } + + private CrlValidatedID( + Asn1Sequence seq) + { + if (seq == null) + throw new ArgumentNullException("seq"); + if (seq.Count < 1 || seq.Count > 2) + throw new ArgumentException("Bad sequence size: " + seq.Count, "seq"); + + this.crlHash = OtherHash.GetInstance(seq[0].ToAsn1Object()); + + if (seq.Count > 1) + { + this.crlIdentifier = CrlIdentifier.GetInstance(seq[1].ToAsn1Object()); + } + } + + public CrlValidatedID( + OtherHash crlHash) + : this(crlHash, null) + { + } + + public CrlValidatedID( + OtherHash crlHash, + CrlIdentifier crlIdentifier) + { + if (crlHash == null) + throw new ArgumentNullException("crlHash"); + + this.crlHash = crlHash; + this.crlIdentifier = crlIdentifier; + } + + public OtherHash CrlHash + { + get { return crlHash; } + } + + public CrlIdentifier CrlIdentifier + { + get { return crlIdentifier; } + } + + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(crlHash.ToAsn1Object()); + + if (crlIdentifier != null) + { + v.Add(crlIdentifier.ToAsn1Object()); + } + + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CrlValidatedID.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CrlValidatedID.cs.meta new file mode 100644 index 0000000..11d7586 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/CrlValidatedID.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8dc8a430c0235d546a6f7f5ec14f109b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/ESFAttributes.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/ESFAttributes.cs new file mode 100644 index 0000000..9401ffb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/ESFAttributes.cs @@ -0,0 +1,25 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Pkcs; + +namespace Org.BouncyCastle.Asn1.Esf +{ + public abstract class EsfAttributes + { + public static readonly DerObjectIdentifier SigPolicyId = PkcsObjectIdentifiers.IdAAEtsSigPolicyID; + public static readonly DerObjectIdentifier CommitmentType = PkcsObjectIdentifiers.IdAAEtsCommitmentType; + public static readonly DerObjectIdentifier SignerLocation = PkcsObjectIdentifiers.IdAAEtsSignerLocation; + public static readonly DerObjectIdentifier SignerAttr = PkcsObjectIdentifiers.IdAAEtsSignerAttr; + public static readonly DerObjectIdentifier OtherSigCert = PkcsObjectIdentifiers.IdAAEtsOtherSigCert; + public static readonly DerObjectIdentifier ContentTimestamp = PkcsObjectIdentifiers.IdAAEtsContentTimestamp; + public static readonly DerObjectIdentifier CertificateRefs = PkcsObjectIdentifiers.IdAAEtsCertificateRefs; + public static readonly DerObjectIdentifier RevocationRefs = PkcsObjectIdentifiers.IdAAEtsRevocationRefs; + public static readonly DerObjectIdentifier CertValues = PkcsObjectIdentifiers.IdAAEtsCertValues; + public static readonly DerObjectIdentifier RevocationValues = PkcsObjectIdentifiers.IdAAEtsRevocationValues; + public static readonly DerObjectIdentifier EscTimeStamp = PkcsObjectIdentifiers.IdAAEtsEscTimeStamp; + public static readonly DerObjectIdentifier CertCrlTimestamp = PkcsObjectIdentifiers.IdAAEtsCertCrlTimestamp; + public static readonly DerObjectIdentifier ArchiveTimestamp = PkcsObjectIdentifiers.IdAAEtsArchiveTimestamp; + public static readonly DerObjectIdentifier ArchiveTimestampV2 = new DerObjectIdentifier(PkcsObjectIdentifiers.IdAA + ".48"); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/ESFAttributes.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/ESFAttributes.cs.meta new file mode 100644 index 0000000..e9de7ec --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/ESFAttributes.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b2e42c769c6a7e84f8637b4069e88565 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OcspIdentifier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OcspIdentifier.cs new file mode 100644 index 0000000..e65f1cf --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OcspIdentifier.cs @@ -0,0 +1,78 @@ +using System; + +using Org.BouncyCastle.Asn1.Ocsp; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Esf +{ + /// + /// RFC 3126: 4.2.2 Complete Revocation Refs Attribute Definition + /// + /// OcspIdentifier ::= SEQUENCE { + /// ocspResponderID ResponderID, + /// -- As in OCSP response data + /// producedAt GeneralizedTime + /// -- As in OCSP response data + /// } + /// + /// + public class OcspIdentifier + : Asn1Encodable + { + private readonly ResponderID ocspResponderID; + private readonly DerGeneralizedTime producedAt; + + public static OcspIdentifier GetInstance( + object obj) + { + if (obj == null || obj is OcspIdentifier) + return (OcspIdentifier) obj; + + if (obj is Asn1Sequence) + return new OcspIdentifier((Asn1Sequence) obj); + + throw new ArgumentException( + "Unknown object in 'OcspIdentifier' factory: " + + Platform.GetTypeName(obj), + "obj"); + } + + private OcspIdentifier( + Asn1Sequence seq) + { + if (seq == null) + throw new ArgumentNullException("seq"); + if (seq.Count != 2) + throw new ArgumentException("Bad sequence size: " + seq.Count, "seq"); + + this.ocspResponderID = ResponderID.GetInstance(seq[0].ToAsn1Object()); + this.producedAt = (DerGeneralizedTime) seq[1].ToAsn1Object(); + } + + public OcspIdentifier( + ResponderID ocspResponderID, + DateTime producedAt) + { + if (ocspResponderID == null) + throw new ArgumentNullException(); + + this.ocspResponderID = ocspResponderID; + this.producedAt = new DerGeneralizedTime(producedAt); + } + + public ResponderID OcspResponderID + { + get { return ocspResponderID; } + } + + public DateTime ProducedAt + { + get { return producedAt.ToDateTime(); } + } + + public override Asn1Object ToAsn1Object() + { + return new DerSequence(ocspResponderID, producedAt); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OcspIdentifier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OcspIdentifier.cs.meta new file mode 100644 index 0000000..08caa02 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OcspIdentifier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7945afe1e2372b14ba72b1dac4c87111 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OcspListID.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OcspListID.cs new file mode 100644 index 0000000..1c8edb1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OcspListID.cs @@ -0,0 +1,89 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Asn1.Esf +{ + /// + /// RFC 3126: 4.2.2 Complete Revocation Refs Attribute Definition + /// + /// OcspListID ::= SEQUENCE { + /// ocspResponses SEQUENCE OF OcspResponsesID + /// } + /// + /// + public class OcspListID + : Asn1Encodable + { + private readonly Asn1Sequence ocspResponses; + + public static OcspListID GetInstance( + object obj) + { + if (obj == null || obj is OcspListID) + return (OcspListID) obj; + + if (obj is Asn1Sequence) + return new OcspListID((Asn1Sequence) obj); + + throw new ArgumentException( + "Unknown object in 'OcspListID' factory: " + + Platform.GetTypeName(obj), + "obj"); + } + + private OcspListID( + Asn1Sequence seq) + { + if (seq == null) + throw new ArgumentNullException("seq"); + if (seq.Count != 1) + throw new ArgumentException("Bad sequence size: " + seq.Count, "seq"); + + this.ocspResponses = (Asn1Sequence) seq[0].ToAsn1Object(); + + foreach (Asn1Encodable ae in this.ocspResponses) + { + OcspResponsesID.GetInstance(ae.ToAsn1Object()); + } + } + + public OcspListID( + params OcspResponsesID[] ocspResponses) + { + if (ocspResponses == null) + throw new ArgumentNullException("ocspResponses"); + + this.ocspResponses = new DerSequence(ocspResponses); + } + + public OcspListID( + IEnumerable ocspResponses) + { + if (ocspResponses == null) + throw new ArgumentNullException("ocspResponses"); + if (!CollectionUtilities.CheckElementsAreOfType(ocspResponses, typeof(OcspResponsesID))) + throw new ArgumentException("Must contain only 'OcspResponsesID' objects", "ocspResponses"); + + this.ocspResponses = new DerSequence( + Asn1EncodableVector.FromEnumerable(ocspResponses)); + } + + public OcspResponsesID[] GetOcspResponses() + { + OcspResponsesID[] result = new OcspResponsesID[ocspResponses.Count]; + for (int i = 0; i < ocspResponses.Count; ++i) + { + result[i] = OcspResponsesID.GetInstance(ocspResponses[i].ToAsn1Object()); + } + return result; + } + + public override Asn1Object ToAsn1Object() + { + return new DerSequence(ocspResponses); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OcspListID.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OcspListID.cs.meta new file mode 100644 index 0000000..34ecd59 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OcspListID.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 753c2e5451b4e664f8aa2a9d74005208 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OcspResponsesID.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OcspResponsesID.cs new file mode 100644 index 0000000..8718188 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OcspResponsesID.cs @@ -0,0 +1,94 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Esf +{ + /// + /// RFC 3126: 4.2.2 Complete Revocation Refs Attribute Definition + /// + /// OcspResponsesID ::= SEQUENCE { + /// ocspIdentifier OcspIdentifier, + /// ocspRepHash OtherHash OPTIONAL + /// } + /// + /// + public class OcspResponsesID + : Asn1Encodable + { + private readonly OcspIdentifier ocspIdentifier; + private readonly OtherHash ocspRepHash; + + public static OcspResponsesID GetInstance( + object obj) + { + if (obj == null || obj is OcspResponsesID) + return (OcspResponsesID) obj; + + if (obj is Asn1Sequence) + return new OcspResponsesID((Asn1Sequence) obj); + + throw new ArgumentException( + "Unknown object in 'OcspResponsesID' factory: " + + Platform.GetTypeName(obj), + "obj"); + } + + private OcspResponsesID( + Asn1Sequence seq) + { + if (seq == null) + throw new ArgumentNullException("seq"); + if (seq.Count < 1 || seq.Count > 2) + throw new ArgumentException("Bad sequence size: " + seq.Count, "seq"); + + this.ocspIdentifier = OcspIdentifier.GetInstance(seq[0].ToAsn1Object()); + + if (seq.Count > 1) + { + this.ocspRepHash = OtherHash.GetInstance(seq[1].ToAsn1Object()); + } + } + + public OcspResponsesID( + OcspIdentifier ocspIdentifier) + : this(ocspIdentifier, null) + { + } + + public OcspResponsesID( + OcspIdentifier ocspIdentifier, + OtherHash ocspRepHash) + { + if (ocspIdentifier == null) + throw new ArgumentNullException("ocspIdentifier"); + + this.ocspIdentifier = ocspIdentifier; + this.ocspRepHash = ocspRepHash; + } + + public OcspIdentifier OcspIdentifier + { + get { return ocspIdentifier; } + } + + public OtherHash OcspRepHash + { + get { return ocspRepHash; } + } + + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector( + ocspIdentifier.ToAsn1Object()); + + if (ocspRepHash != null) + { + v.Add(ocspRepHash.ToAsn1Object()); + } + + return new DerSequence(v); + } + + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OcspResponsesID.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OcspResponsesID.cs.meta new file mode 100644 index 0000000..f8ba2f4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OcspResponsesID.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0874b51b07a321d4f82116bf52a9cf93 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OtherCertID.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OtherCertID.cs new file mode 100644 index 0000000..19d173a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OtherCertID.cs @@ -0,0 +1,94 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Esf +{ + /// + /// + /// OtherCertID ::= SEQUENCE { + /// otherCertHash OtherHash, + /// issuerSerial IssuerSerial OPTIONAL + /// } + /// + /// + public class OtherCertID + : Asn1Encodable + { + private readonly OtherHash otherCertHash; + private readonly IssuerSerial issuerSerial; + + public static OtherCertID GetInstance( + object obj) + { + if (obj == null || obj is OtherCertID) + return (OtherCertID) obj; + + if (obj is Asn1Sequence) + return new OtherCertID((Asn1Sequence) obj); + + throw new ArgumentException( + "Unknown object in 'OtherCertID' factory: " + + Platform.GetTypeName(obj), + "obj"); + } + + private OtherCertID( + Asn1Sequence seq) + { + if (seq == null) + throw new ArgumentNullException("seq"); + if (seq.Count < 1 || seq.Count > 2) + throw new ArgumentException("Bad sequence size: " + seq.Count, "seq"); + + this.otherCertHash = OtherHash.GetInstance(seq[0].ToAsn1Object()); + + if (seq.Count > 1) + { + this.issuerSerial = IssuerSerial.GetInstance(seq[1].ToAsn1Object()); + } + } + + public OtherCertID( + OtherHash otherCertHash) + : this(otherCertHash, null) + { + } + + public OtherCertID( + OtherHash otherCertHash, + IssuerSerial issuerSerial) + { + if (otherCertHash == null) + throw new ArgumentNullException("otherCertHash"); + + this.otherCertHash = otherCertHash; + this.issuerSerial = issuerSerial; + } + + public OtherHash OtherCertHash + { + get { return otherCertHash; } + } + + public IssuerSerial IssuerSerial + { + get { return issuerSerial; } + } + + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector( + otherCertHash.ToAsn1Object()); + + if (issuerSerial != null) + { + v.Add(issuerSerial.ToAsn1Object()); + } + + return new DerSequence(v); + } + + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OtherCertID.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OtherCertID.cs.meta new file mode 100644 index 0000000..dc90fe2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OtherCertID.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e396081a4b67c4a46857fa48883a35fa +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OtherHash.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OtherHash.cs new file mode 100644 index 0000000..2ee1624 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OtherHash.cs @@ -0,0 +1,88 @@ +using System; + +using Org.BouncyCastle.Asn1.Oiw; +using Org.BouncyCastle.Asn1.X509; + +namespace Org.BouncyCastle.Asn1.Esf +{ + /// + /// + /// OtherHash ::= CHOICE { + /// sha1Hash OtherHashValue, -- This contains a SHA-1 hash + /// otherHash OtherHashAlgAndValue + /// } + /// + /// OtherHashValue ::= OCTET STRING + /// + /// + public class OtherHash + : Asn1Encodable, IAsn1Choice + { + private readonly Asn1OctetString sha1Hash; + private readonly OtherHashAlgAndValue otherHash; + + public static OtherHash GetInstance( + object obj) + { + if (obj == null || obj is OtherHash) + return (OtherHash) obj; + + if (obj is Asn1OctetString) + return new OtherHash((Asn1OctetString) obj); + + return new OtherHash( + OtherHashAlgAndValue.GetInstance(obj)); + } + + public OtherHash( + byte[] sha1Hash) + { + if (sha1Hash == null) + throw new ArgumentNullException("sha1Hash"); + + this.sha1Hash = new DerOctetString(sha1Hash); + } + + public OtherHash( + Asn1OctetString sha1Hash) + { + if (sha1Hash == null) + throw new ArgumentNullException("sha1Hash"); + + this.sha1Hash = sha1Hash; + } + + public OtherHash( + OtherHashAlgAndValue otherHash) + { + if (otherHash == null) + throw new ArgumentNullException("otherHash"); + + this.otherHash = otherHash; + } + + public AlgorithmIdentifier HashAlgorithm + { + get + { + return otherHash == null + ? new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1) + : otherHash.HashAlgorithm; + } + } + + public byte[] GetHashValue() + { + return otherHash == null + ? sha1Hash.GetOctets() + : otherHash.GetHashValue(); + } + + public override Asn1Object ToAsn1Object() + { + return otherHash == null + ? sha1Hash + : otherHash.ToAsn1Object(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OtherHash.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OtherHash.cs.meta new file mode 100644 index 0000000..14d4d7b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OtherHash.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b899f1275ea9bdb4cb129f5cfba39f6a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OtherHashAlgAndValue.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OtherHashAlgAndValue.cs new file mode 100644 index 0000000..00eb24c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OtherHashAlgAndValue.cs @@ -0,0 +1,95 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Esf +{ + /// + /// Summary description for OtherHashAlgAndValue. + /// + /// + /// + /// OtherHashAlgAndValue ::= SEQUENCE { + /// hashAlgorithm AlgorithmIdentifier, + /// hashValue OtherHashValue + /// } + /// + /// OtherHashValue ::= OCTET STRING + /// + /// + public class OtherHashAlgAndValue + : Asn1Encodable + { + private readonly AlgorithmIdentifier hashAlgorithm; + private readonly Asn1OctetString hashValue; + + public static OtherHashAlgAndValue GetInstance( + object obj) + { + if (obj == null || obj is OtherHashAlgAndValue) + return (OtherHashAlgAndValue) obj; + + if (obj is Asn1Sequence) + return new OtherHashAlgAndValue((Asn1Sequence) obj); + + throw new ArgumentException( + "Unknown object in 'OtherHashAlgAndValue' factory: " + + Platform.GetTypeName(obj), + "obj"); + } + + private OtherHashAlgAndValue( + Asn1Sequence seq) + { + if (seq == null) + throw new ArgumentNullException("seq"); + if (seq.Count != 2) + throw new ArgumentException("Bad sequence size: " + seq.Count, "seq"); + + this.hashAlgorithm = AlgorithmIdentifier.GetInstance(seq[0].ToAsn1Object()); + this.hashValue = (Asn1OctetString) seq[1].ToAsn1Object(); + } + + public OtherHashAlgAndValue( + AlgorithmIdentifier hashAlgorithm, + byte[] hashValue) + { + if (hashAlgorithm == null) + throw new ArgumentNullException("hashAlgorithm"); + if (hashValue == null) + throw new ArgumentNullException("hashValue"); + + this.hashAlgorithm = hashAlgorithm; + this.hashValue = new DerOctetString(hashValue); + } + + public OtherHashAlgAndValue( + AlgorithmIdentifier hashAlgorithm, + Asn1OctetString hashValue) + { + if (hashAlgorithm == null) + throw new ArgumentNullException("hashAlgorithm"); + if (hashValue == null) + throw new ArgumentNullException("hashValue"); + + this.hashAlgorithm = hashAlgorithm; + this.hashValue = hashValue; + } + + public AlgorithmIdentifier HashAlgorithm + { + get { return hashAlgorithm; } + } + + public byte[] GetHashValue() + { + return hashValue.GetOctets(); + } + + public override Asn1Object ToAsn1Object() + { + return new DerSequence(hashAlgorithm, hashValue); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OtherHashAlgAndValue.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OtherHashAlgAndValue.cs.meta new file mode 100644 index 0000000..75dfec4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OtherHashAlgAndValue.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d671a2566ab858a44b1317ed18e7c8b8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OtherRevRefs.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OtherRevRefs.cs new file mode 100644 index 0000000..446031e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OtherRevRefs.cs @@ -0,0 +1,80 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Esf +{ + /// + /// RFC 3126: 4.2.2 Complete Revocation Refs Attribute Definition + /// + /// OtherRevRefs ::= SEQUENCE + /// { + /// otherRevRefType OtherRevRefType, + /// otherRevRefs ANY DEFINED BY otherRevRefType + /// } + /// + /// OtherRevRefType ::= OBJECT IDENTIFIER + /// + /// + public class OtherRevRefs + : Asn1Encodable + { + private readonly DerObjectIdentifier otherRevRefType; + private readonly Asn1Object otherRevRefs; + + public static OtherRevRefs GetInstance( + object obj) + { + if (obj == null || obj is OtherRevRefs) + return (OtherRevRefs) obj; + + if (obj is Asn1Sequence) + return new OtherRevRefs((Asn1Sequence) obj); + + throw new ArgumentException( + "Unknown object in 'OtherRevRefs' factory: " + + Platform.GetTypeName(obj), + "obj"); + } + + private OtherRevRefs( + Asn1Sequence seq) + { + if (seq == null) + throw new ArgumentNullException("seq"); + if (seq.Count != 2) + throw new ArgumentException("Bad sequence size: " + seq.Count, "seq"); + + this.otherRevRefType = (DerObjectIdentifier) seq[0].ToAsn1Object(); + this.otherRevRefs = seq[1].ToAsn1Object(); + } + + public OtherRevRefs( + DerObjectIdentifier otherRevRefType, + Asn1Encodable otherRevRefs) + { + if (otherRevRefType == null) + throw new ArgumentNullException("otherRevRefType"); + if (otherRevRefs == null) + throw new ArgumentNullException("otherRevRefs"); + + this.otherRevRefType = otherRevRefType; + this.otherRevRefs = otherRevRefs.ToAsn1Object(); + } + + public DerObjectIdentifier OtherRevRefType + { + get { return otherRevRefType; } + } + + public Asn1Object OtherRevRefsObject + { + get { return otherRevRefs; } + } + + public override Asn1Object ToAsn1Object() + { + return new DerSequence(otherRevRefType, otherRevRefs); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OtherRevRefs.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OtherRevRefs.cs.meta new file mode 100644 index 0000000..4bc204e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OtherRevRefs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b6095120b0485534588412af5346128f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OtherRevVals.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OtherRevVals.cs new file mode 100644 index 0000000..7b90456 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OtherRevVals.cs @@ -0,0 +1,80 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Esf +{ + /// + /// RFC 3126: 4.3.2 Revocation Values Attribute Definition + /// + /// OtherRevVals ::= SEQUENCE + /// { + /// otherRevValType OtherRevValType, + /// otherRevVals ANY DEFINED BY otherRevValType + /// } + /// + /// OtherRevValType ::= OBJECT IDENTIFIER + /// + /// + public class OtherRevVals + : Asn1Encodable + { + private readonly DerObjectIdentifier otherRevValType; + private readonly Asn1Object otherRevVals; + + public static OtherRevVals GetInstance( + object obj) + { + if (obj == null || obj is OtherRevVals) + return (OtherRevVals) obj; + + if (obj is Asn1Sequence) + return new OtherRevVals((Asn1Sequence) obj); + + throw new ArgumentException( + "Unknown object in 'OtherRevVals' factory: " + + Platform.GetTypeName(obj), + "obj"); + } + + private OtherRevVals( + Asn1Sequence seq) + { + if (seq == null) + throw new ArgumentNullException("seq"); + if (seq.Count != 2) + throw new ArgumentException("Bad sequence size: " + seq.Count, "seq"); + + this.otherRevValType = (DerObjectIdentifier) seq[0].ToAsn1Object(); + this.otherRevVals = seq[1].ToAsn1Object(); + } + + public OtherRevVals( + DerObjectIdentifier otherRevValType, + Asn1Encodable otherRevVals) + { + if (otherRevValType == null) + throw new ArgumentNullException("otherRevValType"); + if (otherRevVals == null) + throw new ArgumentNullException("otherRevVals"); + + this.otherRevValType = otherRevValType; + this.otherRevVals = otherRevVals.ToAsn1Object(); + } + + public DerObjectIdentifier OtherRevValType + { + get { return otherRevValType; } + } + + public Asn1Object OtherRevValsObject + { + get { return otherRevVals; } + } + + public override Asn1Object ToAsn1Object() + { + return new DerSequence(otherRevValType, otherRevVals); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OtherRevVals.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OtherRevVals.cs.meta new file mode 100644 index 0000000..040f53e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OtherRevVals.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 186fa7d80873ee6449e077a9ab4e73c8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OtherSigningCertificate.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OtherSigningCertificate.cs new file mode 100644 index 0000000..2b6d646 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OtherSigningCertificate.cs @@ -0,0 +1,134 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Asn1.Esf +{ + /// + /// + /// OtherSigningCertificate ::= SEQUENCE { + /// certs SEQUENCE OF OtherCertID, + /// policies SEQUENCE OF PolicyInformation OPTIONAL + /// } + /// + /// + public class OtherSigningCertificate + : Asn1Encodable + { + private readonly Asn1Sequence certs; + private readonly Asn1Sequence policies; + + public static OtherSigningCertificate GetInstance( + object obj) + { + if (obj == null || obj is OtherSigningCertificate) + return (OtherSigningCertificate) obj; + + if (obj is Asn1Sequence) + return new OtherSigningCertificate((Asn1Sequence) obj); + + throw new ArgumentException( + "Unknown object in 'OtherSigningCertificate' factory: " + + Platform.GetTypeName(obj), + "obj"); + } + + private OtherSigningCertificate( + Asn1Sequence seq) + { + if (seq == null) + throw new ArgumentNullException("seq"); + if (seq.Count < 1 || seq.Count > 2) + throw new ArgumentException("Bad sequence size: " + seq.Count, "seq"); + + this.certs = Asn1Sequence.GetInstance(seq[0].ToAsn1Object()); + + if (seq.Count > 1) + { + this.policies = Asn1Sequence.GetInstance(seq[1].ToAsn1Object()); + } + } + + public OtherSigningCertificate( + params OtherCertID[] certs) + : this(certs, null) + { + } + + public OtherSigningCertificate( + OtherCertID[] certs, + params PolicyInformation[] policies) + { + if (certs == null) + throw new ArgumentNullException("certs"); + + this.certs = new DerSequence(certs); + + if (policies != null) + { + this.policies = new DerSequence(policies); + } + } + + public OtherSigningCertificate( + IEnumerable certs) + : this(certs, null) + { + } + + public OtherSigningCertificate( + IEnumerable certs, + IEnumerable policies) + { + if (certs == null) + throw new ArgumentNullException("certs"); + if (!CollectionUtilities.CheckElementsAreOfType(certs, typeof(OtherCertID))) + throw new ArgumentException("Must contain only 'OtherCertID' objects", "certs"); + + this.certs = new DerSequence( + Asn1EncodableVector.FromEnumerable(certs)); + + if (policies != null) + { + if (!CollectionUtilities.CheckElementsAreOfType(policies, typeof(PolicyInformation))) + throw new ArgumentException("Must contain only 'PolicyInformation' objects", "policies"); + + this.policies = new DerSequence( + Asn1EncodableVector.FromEnumerable(policies)); + } + } + + public OtherCertID[] GetCerts() + { + OtherCertID[] cs = new OtherCertID[certs.Count]; + for (int i = 0; i < certs.Count; ++i) + { + cs[i] = OtherCertID.GetInstance(certs[i].ToAsn1Object()); + } + return cs; + } + + public PolicyInformation[] GetPolicies() + { + if (policies == null) + return null; + + PolicyInformation[] ps = new PolicyInformation[policies.Count]; + for (int i = 0; i < policies.Count; ++i) + { + ps[i] = PolicyInformation.GetInstance(policies[i].ToAsn1Object()); + } + return ps; + } + + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(certs); + v.AddOptional(policies); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OtherSigningCertificate.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OtherSigningCertificate.cs.meta new file mode 100644 index 0000000..55512f5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/OtherSigningCertificate.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 93d3231f23fa265428dfd24a861d4462 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/RevocationValues.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/RevocationValues.cs new file mode 100644 index 0000000..5be080f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/RevocationValues.cs @@ -0,0 +1,157 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1.Ocsp; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Asn1.Esf +{ + /// + /// RFC 5126: 6.3.4. revocation-values Attribute Definition + /// + /// RevocationValues ::= SEQUENCE { + /// crlVals [0] SEQUENCE OF CertificateList OPTIONAL, + /// ocspVals [1] SEQUENCE OF BasicOCSPResponse OPTIONAL, + /// otherRevVals [2] OtherRevVals OPTIONAL + /// } + /// + /// + public class RevocationValues + : Asn1Encodable + { + private readonly Asn1Sequence crlVals; + private readonly Asn1Sequence ocspVals; + private readonly OtherRevVals otherRevVals; + + public static RevocationValues GetInstance( + object obj) + { + if (obj == null || obj is RevocationValues) + return (RevocationValues) obj; + + return new RevocationValues(Asn1Sequence.GetInstance(obj)); + } + + private RevocationValues( + Asn1Sequence seq) + { + if (seq == null) + throw new ArgumentNullException("seq"); + if (seq.Count > 3) + throw new ArgumentException("Bad sequence size: " + seq.Count, "seq"); + + foreach (Asn1TaggedObject taggedObj in seq) + { + Asn1Object asn1Obj = taggedObj.GetObject(); + switch (taggedObj.TagNo) + { + case 0: + Asn1Sequence crlValsSeq = (Asn1Sequence) asn1Obj; + foreach (Asn1Encodable ae in crlValsSeq) + { + CertificateList.GetInstance(ae.ToAsn1Object()); + } + this.crlVals = crlValsSeq; + break; + case 1: + Asn1Sequence ocspValsSeq = (Asn1Sequence) asn1Obj; + foreach (Asn1Encodable ae in ocspValsSeq) + { + BasicOcspResponse.GetInstance(ae.ToAsn1Object()); + } + this.ocspVals = ocspValsSeq; + break; + case 2: + this.otherRevVals = OtherRevVals.GetInstance(asn1Obj); + break; + default: + throw new ArgumentException("Illegal tag in RevocationValues", "seq"); + } + } + } + + public RevocationValues( + CertificateList[] crlVals, + BasicOcspResponse[] ocspVals, + OtherRevVals otherRevVals) + { + if (crlVals != null) + { + this.crlVals = new DerSequence(crlVals); + } + + if (ocspVals != null) + { + this.ocspVals = new DerSequence(ocspVals); + } + + this.otherRevVals = otherRevVals; + } + + public RevocationValues( + IEnumerable crlVals, + IEnumerable ocspVals, + OtherRevVals otherRevVals) + { + if (crlVals != null) + { + if (!CollectionUtilities.CheckElementsAreOfType(crlVals, typeof(CertificateList))) + throw new ArgumentException("Must contain only 'CertificateList' objects", "crlVals"); + + this.crlVals = new DerSequence( + Asn1EncodableVector.FromEnumerable(crlVals)); + } + + if (ocspVals != null) + { + if (!CollectionUtilities.CheckElementsAreOfType(ocspVals, typeof(BasicOcspResponse))) + throw new ArgumentException("Must contain only 'BasicOcspResponse' objects", "ocspVals"); + + this.ocspVals = new DerSequence( + Asn1EncodableVector.FromEnumerable(ocspVals)); + } + + this.otherRevVals = otherRevVals; + } + + public CertificateList[] GetCrlVals() + { + CertificateList[] result = new CertificateList[crlVals.Count]; + for (int i = 0; i < crlVals.Count; ++i) + { + result[i] = CertificateList.GetInstance(crlVals[i].ToAsn1Object()); + } + return result; + } + + public BasicOcspResponse[] GetOcspVals() + { + BasicOcspResponse[] result = new BasicOcspResponse[ocspVals.Count]; + for (int i = 0; i < ocspVals.Count; ++i) + { + result[i] = BasicOcspResponse.GetInstance(ocspVals[i].ToAsn1Object()); + } + return result; + } + + public OtherRevVals OtherRevVals + { + get { return otherRevVals; } + } + + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + v.AddOptionalTagged(true, 0, crlVals); + v.AddOptionalTagged(true, 1, ocspVals); + + if (otherRevVals != null) + { + v.Add(new DerTaggedObject(true, 2, otherRevVals.ToAsn1Object())); + } + + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/RevocationValues.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/RevocationValues.cs.meta new file mode 100644 index 0000000..bbdc689 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/RevocationValues.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d57751e3fa796ab4185fdbbf43b98f8d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/SigPolicyQualifierInfo.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/SigPolicyQualifierInfo.cs new file mode 100644 index 0000000..470c5c8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/SigPolicyQualifierInfo.cs @@ -0,0 +1,73 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Esf +{ + /// + /// + /// SigPolicyQualifierInfo ::= SEQUENCE { + /// sigPolicyQualifierId SigPolicyQualifierId, + /// sigQualifier ANY DEFINED BY sigPolicyQualifierId + /// } + /// + /// SigPolicyQualifierId ::= OBJECT IDENTIFIER + /// + /// + public class SigPolicyQualifierInfo + : Asn1Encodable + { + private readonly DerObjectIdentifier sigPolicyQualifierId; + private readonly Asn1Object sigQualifier; + + public static SigPolicyQualifierInfo GetInstance( + object obj) + { + if (obj == null || obj is SigPolicyQualifierInfo) + return (SigPolicyQualifierInfo) obj; + + if (obj is Asn1Sequence) + return new SigPolicyQualifierInfo((Asn1Sequence) obj); + + throw new ArgumentException( + "Unknown object in 'SigPolicyQualifierInfo' factory: " + + Platform.GetTypeName(obj), + "obj"); + } + + private SigPolicyQualifierInfo( + Asn1Sequence seq) + { + if (seq == null) + throw new ArgumentNullException("seq"); + if (seq.Count != 2) + throw new ArgumentException("Bad sequence size: " + seq.Count, "seq"); + + this.sigPolicyQualifierId = (DerObjectIdentifier) seq[0].ToAsn1Object(); + this.sigQualifier = seq[1].ToAsn1Object(); + } + + public SigPolicyQualifierInfo( + DerObjectIdentifier sigPolicyQualifierId, + Asn1Encodable sigQualifier) + { + this.sigPolicyQualifierId = sigPolicyQualifierId; + this.sigQualifier = sigQualifier.ToAsn1Object(); + } + + public DerObjectIdentifier SigPolicyQualifierId + { + get { return sigPolicyQualifierId; } + } + + public Asn1Object SigQualifier + { + get { return sigQualifier; } + } + + public override Asn1Object ToAsn1Object() + { + return new DerSequence(sigPolicyQualifierId, sigQualifier); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/SigPolicyQualifierInfo.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/SigPolicyQualifierInfo.cs.meta new file mode 100644 index 0000000..b2197aa --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/SigPolicyQualifierInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bdb0bad107a2ebc4489968eadba16618 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/SignaturePolicyId.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/SignaturePolicyId.cs new file mode 100644 index 0000000..7146bb4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/SignaturePolicyId.cs @@ -0,0 +1,146 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Asn1.Esf +{ + /// + /// + /// SignaturePolicyId ::= SEQUENCE { + /// sigPolicyIdentifier SigPolicyId, + /// sigPolicyHash SigPolicyHash, + /// sigPolicyQualifiers SEQUENCE SIZE (1..MAX) OF SigPolicyQualifierInfo OPTIONAL + /// } + /// + /// SigPolicyId ::= OBJECT IDENTIFIER + /// + /// SigPolicyHash ::= OtherHashAlgAndValue + /// + /// + public class SignaturePolicyId + : Asn1Encodable + { + private readonly DerObjectIdentifier sigPolicyIdentifier; + private readonly OtherHashAlgAndValue sigPolicyHash; + private readonly Asn1Sequence sigPolicyQualifiers; + + public static SignaturePolicyId GetInstance( + object obj) + { + if (obj == null || obj is SignaturePolicyId) + return (SignaturePolicyId) obj; + + if (obj is Asn1Sequence) + return new SignaturePolicyId((Asn1Sequence) obj); + + throw new ArgumentException( + "Unknown object in 'SignaturePolicyId' factory: " + + Platform.GetTypeName(obj), + "obj"); + } + + private SignaturePolicyId( + Asn1Sequence seq) + { + if (seq == null) + throw new ArgumentNullException("seq"); + if (seq.Count < 2 || seq.Count > 3) + throw new ArgumentException("Bad sequence size: " + seq.Count, "seq"); + + this.sigPolicyIdentifier = (DerObjectIdentifier) seq[0].ToAsn1Object(); + this.sigPolicyHash = OtherHashAlgAndValue.GetInstance(seq[1].ToAsn1Object()); + + if (seq.Count > 2) + { + this.sigPolicyQualifiers = (Asn1Sequence) seq[2].ToAsn1Object(); + } + } + + public SignaturePolicyId( + DerObjectIdentifier sigPolicyIdentifier, + OtherHashAlgAndValue sigPolicyHash) + : this(sigPolicyIdentifier, sigPolicyHash, null) + { + } + + public SignaturePolicyId( + DerObjectIdentifier sigPolicyIdentifier, + OtherHashAlgAndValue sigPolicyHash, + params SigPolicyQualifierInfo[] sigPolicyQualifiers) + { + if (sigPolicyIdentifier == null) + throw new ArgumentNullException("sigPolicyIdentifier"); + if (sigPolicyHash == null) + throw new ArgumentNullException("sigPolicyHash"); + + this.sigPolicyIdentifier = sigPolicyIdentifier; + this.sigPolicyHash = sigPolicyHash; + + if (sigPolicyQualifiers != null) + { + this.sigPolicyQualifiers = new DerSequence(sigPolicyQualifiers); + } + } + + public SignaturePolicyId( + DerObjectIdentifier sigPolicyIdentifier, + OtherHashAlgAndValue sigPolicyHash, + IEnumerable sigPolicyQualifiers) + { + if (sigPolicyIdentifier == null) + throw new ArgumentNullException("sigPolicyIdentifier"); + if (sigPolicyHash == null) + throw new ArgumentNullException("sigPolicyHash"); + + this.sigPolicyIdentifier = sigPolicyIdentifier; + this.sigPolicyHash = sigPolicyHash; + + if (sigPolicyQualifiers != null) + { + if (!CollectionUtilities.CheckElementsAreOfType(sigPolicyQualifiers, typeof(SigPolicyQualifierInfo))) + throw new ArgumentException("Must contain only 'SigPolicyQualifierInfo' objects", "sigPolicyQualifiers"); + + this.sigPolicyQualifiers = new DerSequence( + Asn1EncodableVector.FromEnumerable(sigPolicyQualifiers)); + } + } + + public DerObjectIdentifier SigPolicyIdentifier + { + get { return sigPolicyIdentifier; } + } + + public OtherHashAlgAndValue SigPolicyHash + { + get { return sigPolicyHash; } + } + + public SigPolicyQualifierInfo[] GetSigPolicyQualifiers() + { + if (sigPolicyQualifiers == null) + return null; + + SigPolicyQualifierInfo[] infos = new SigPolicyQualifierInfo[sigPolicyQualifiers.Count]; + for (int i = 0; i < sigPolicyQualifiers.Count; ++i) + { + infos[i] = SigPolicyQualifierInfo.GetInstance(sigPolicyQualifiers[i]); + } + return infos; + } + + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector( + sigPolicyIdentifier, sigPolicyHash.ToAsn1Object()); + + if (sigPolicyQualifiers != null) + { + v.Add(sigPolicyQualifiers.ToAsn1Object()); + } + + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/SignaturePolicyId.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/SignaturePolicyId.cs.meta new file mode 100644 index 0000000..125e7f9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/SignaturePolicyId.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d3059df2a81ad5d429a0d90f0cce853a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/SignaturePolicyIdentifier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/SignaturePolicyIdentifier.cs new file mode 100644 index 0000000..12257f2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/SignaturePolicyIdentifier.cs @@ -0,0 +1,66 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Esf +{ + /// + /// + /// SignaturePolicyIdentifier ::= CHOICE { + /// SignaturePolicyId SignaturePolicyId, + /// SignaturePolicyImplied SignaturePolicyImplied + /// } + /// + /// SignaturePolicyImplied ::= NULL + /// + /// + public class SignaturePolicyIdentifier + : Asn1Encodable, IAsn1Choice + { + private readonly SignaturePolicyId sigPolicy; + + public static SignaturePolicyIdentifier GetInstance( + object obj) + { + if (obj == null || obj is SignaturePolicyIdentifier) + return (SignaturePolicyIdentifier) obj; + + if (obj is SignaturePolicyId) + return new SignaturePolicyIdentifier((SignaturePolicyId) obj); + + if (obj is Asn1Null) + return new SignaturePolicyIdentifier(); + + throw new ArgumentException( + "Unknown object in 'SignaturePolicyIdentifier' factory: " + + Platform.GetTypeName(obj), + "obj"); + } + + public SignaturePolicyIdentifier() + { + this.sigPolicy = null; + } + + public SignaturePolicyIdentifier( + SignaturePolicyId signaturePolicyId) + { + if (signaturePolicyId == null) + throw new ArgumentNullException("signaturePolicyId"); + + this.sigPolicy = signaturePolicyId; + } + + public SignaturePolicyId SignaturePolicyId + { + get { return sigPolicy; } + } + + public override Asn1Object ToAsn1Object() + { + return sigPolicy == null + ? DerNull.Instance + : sigPolicy.ToAsn1Object(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/SignaturePolicyIdentifier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/SignaturePolicyIdentifier.cs.meta new file mode 100644 index 0000000..c1eb91d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/SignaturePolicyIdentifier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 35d03d0c21ab74f40b38636b9765a2cd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/SignerAttribute.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/SignerAttribute.cs new file mode 100644 index 0000000..39bd910 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/SignerAttribute.cs @@ -0,0 +1,97 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Esf +{ + public class SignerAttribute + : Asn1Encodable + { + private Asn1Sequence claimedAttributes; + private AttributeCertificate certifiedAttributes; + + public static SignerAttribute GetInstance( + object obj) + { + if (obj == null || obj is SignerAttribute) + return (SignerAttribute) obj; + + if (obj is Asn1Sequence) + return new SignerAttribute(obj); + + throw new ArgumentException( + "Unknown object in 'SignerAttribute' factory: " + + Platform.GetTypeName(obj), + "obj"); + } + + private SignerAttribute( + object obj) + { + Asn1Sequence seq = (Asn1Sequence) obj; + DerTaggedObject taggedObject = (DerTaggedObject) seq[0]; + if (taggedObject.TagNo == 0) + { + claimedAttributes = Asn1Sequence.GetInstance(taggedObject, true); + } + else if (taggedObject.TagNo == 1) + { + certifiedAttributes = AttributeCertificate.GetInstance(taggedObject); + } + else + { + throw new ArgumentException("illegal tag.", "obj"); + } + } + + public SignerAttribute( + Asn1Sequence claimedAttributes) + { + this.claimedAttributes = claimedAttributes; + } + + public SignerAttribute( + AttributeCertificate certifiedAttributes) + { + this.certifiedAttributes = certifiedAttributes; + } + + public virtual Asn1Sequence ClaimedAttributes + { + get { return claimedAttributes; } + } + + public virtual AttributeCertificate CertifiedAttributes + { + get { return certifiedAttributes; } + } + + /** + * + *
+		*  SignerAttribute ::= SEQUENCE OF CHOICE {
+		*      claimedAttributes   [0] ClaimedAttributes,
+		*      certifiedAttributes [1] CertifiedAttributes }
+		*
+		*  ClaimedAttributes ::= SEQUENCE OF Attribute
+		*  CertifiedAttributes ::= AttributeCertificate -- as defined in RFC 3281: see clause 4.1.
+		* 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + + if (claimedAttributes != null) + { + v.Add(new DerTaggedObject(0, claimedAttributes)); + } + else + { + v.Add(new DerTaggedObject(1, certifiedAttributes)); + } + + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/SignerAttribute.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/SignerAttribute.cs.meta new file mode 100644 index 0000000..67da04c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/SignerAttribute.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 52c416758a52bfb49b51d5776a4c8a8c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/SignerLocation.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/SignerLocation.cs new file mode 100644 index 0000000..0095c0e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/SignerLocation.cs @@ -0,0 +1,159 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1.X500; + +namespace Org.BouncyCastle.Asn1.Esf +{ + /** + * Signer-Location attribute (RFC3126). + * + *
+	*   SignerLocation ::= SEQUENCE {
+	*       countryName        [0] DirectoryString OPTIONAL,
+	*       localityName       [1] DirectoryString OPTIONAL,
+	*       postalAddress      [2] PostalAddress OPTIONAL }
+	*
+	*   PostalAddress ::= SEQUENCE SIZE(1..6) OF DirectoryString
+	* 
+ */ + public class SignerLocation + : Asn1Encodable + { + private DirectoryString countryName; + private DirectoryString localityName; + private Asn1Sequence postalAddress; + + public SignerLocation( + Asn1Sequence seq) + { + foreach (Asn1TaggedObject obj in seq) + { + switch (obj.TagNo) + { + case 0: + this.countryName = DirectoryString.GetInstance(obj, true); + break; + case 1: + this.localityName = DirectoryString.GetInstance(obj, true); + break; + case 2: + bool isExplicit = obj.IsExplicit(); // handle erroneous implicitly tagged sequences + this.postalAddress = Asn1Sequence.GetInstance(obj, isExplicit); + if (postalAddress != null && postalAddress.Count > 6) + throw new ArgumentException("postal address must contain less than 6 strings"); + break; + default: + throw new ArgumentException("illegal tag"); + } + } + } + + private SignerLocation( + DirectoryString countryName, + DirectoryString localityName, + Asn1Sequence postalAddress) + { + if (postalAddress != null && postalAddress.Count > 6) + throw new ArgumentException("postal address must contain less than 6 strings"); + + this.countryName = countryName; + this.localityName = localityName; + this.postalAddress = postalAddress; + } + + public SignerLocation( + DirectoryString countryName, + DirectoryString localityName, + DirectoryString[] postalAddress) + : this(countryName, localityName, new DerSequence(postalAddress)) + { + } + + public SignerLocation( + DerUtf8String countryName, + DerUtf8String localityName, + Asn1Sequence postalAddress) + : this(DirectoryString.GetInstance(countryName), DirectoryString.GetInstance(localityName), postalAddress) + { + } + + public static SignerLocation GetInstance( + object obj) + { + if (obj == null || obj is SignerLocation) + { + return (SignerLocation) obj; + } + + return new SignerLocation(Asn1Sequence.GetInstance(obj)); + } + + public DirectoryString Country + { + get { return countryName; } + } + + public DirectoryString Locality + { + get { return localityName; } + } + + public DirectoryString[] GetPostal() + { + if (postalAddress == null) + return null; + + DirectoryString[] dirStrings = new DirectoryString[postalAddress.Count]; + for (int i = 0; i != dirStrings.Length; i++) + { + dirStrings[i] = DirectoryString.GetInstance(postalAddress[i]); + } + + return dirStrings; + } + + [Obsolete("Use 'Country' property instead")] + public DerUtf8String CountryName + { + get { return countryName == null ? null : new DerUtf8String(countryName.GetString()); } + } + + [Obsolete("Use 'Locality' property instead")] + public DerUtf8String LocalityName + { + get { return localityName == null ? null : new DerUtf8String(localityName.GetString()); } + } + + public Asn1Sequence PostalAddress + { + get { return postalAddress; } + } + + /** + *
+		*   SignerLocation ::= SEQUENCE {
+		*       countryName        [0] DirectoryString OPTIONAL,
+		*       localityName       [1] DirectoryString OPTIONAL,
+		*       postalAddress      [2] PostalAddress OPTIONAL }
+		*
+		*   PostalAddress ::= SEQUENCE SIZE(1..6) OF DirectoryString
+		*
+		*   DirectoryString ::= CHOICE {
+		*         teletexString           TeletexString (SIZE (1..MAX)),
+		*         printableString         PrintableString (SIZE (1..MAX)),
+		*         universalString         UniversalString (SIZE (1..MAX)),
+		*         utf8String              UTF8String (SIZE (1.. MAX)),
+		*         bmpString               BMPString (SIZE (1..MAX)) }
+		* 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + v.AddOptionalTagged(true, 0, countryName); + v.AddOptionalTagged(true, 1, localityName); + v.AddOptionalTagged(true, 2, postalAddress); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/SignerLocation.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/SignerLocation.cs.meta new file mode 100644 index 0000000..04285bd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/esf/SignerLocation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0fe4216675451f64bb3f60a8488565b2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess.meta new file mode 100644 index 0000000..20aac46 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: cfbb483cd67a9ae4c982bcbf16c28918 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess/ContentHints.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess/ContentHints.cs new file mode 100644 index 0000000..81ba0a1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess/ContentHints.cs @@ -0,0 +1,88 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Ess +{ + public class ContentHints + : Asn1Encodable + { + private readonly DerUtf8String contentDescription; + private readonly DerObjectIdentifier contentType; + + public static ContentHints GetInstance( + object o) + { + if (o == null || o is ContentHints) + { + return (ContentHints)o; + } + + if (o is Asn1Sequence) + { + return new ContentHints((Asn1Sequence)o); + } + + throw new ArgumentException("unknown object in 'ContentHints' factory : " + + Platform.GetTypeName(o) + "."); + } + + /** + * constructor + */ + private ContentHints( + Asn1Sequence seq) + { + IAsn1Convertible field = seq[0]; + if (field.ToAsn1Object() is DerUtf8String) + { + contentDescription = DerUtf8String.GetInstance(field); + contentType = DerObjectIdentifier.GetInstance(seq[1]); + } + else + { + contentType = DerObjectIdentifier.GetInstance(seq[0]); + } + } + + public ContentHints( + DerObjectIdentifier contentType) + { + this.contentType = contentType; + this.contentDescription = null; + } + + public ContentHints( + DerObjectIdentifier contentType, + DerUtf8String contentDescription) + { + this.contentType = contentType; + this.contentDescription = contentDescription; + } + + public DerObjectIdentifier ContentType + { + get { return contentType; } + } + + public DerUtf8String ContentDescription + { + get { return contentDescription; } + } + + /** + *
+		 * ContentHints ::= SEQUENCE {
+		 *   contentDescription UTF8String (SIZE (1..MAX)) OPTIONAL,
+		 *   contentType ContentType }
+		 * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + v.AddOptional(contentDescription); + v.Add(contentType); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess/ContentHints.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess/ContentHints.cs.meta new file mode 100644 index 0000000..89e04e7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess/ContentHints.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7a27d82e5583131489b57e4c287f58b5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess/ContentIdentifier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess/ContentIdentifier.cs new file mode 100644 index 0000000..430185e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess/ContentIdentifier.cs @@ -0,0 +1,67 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Ess +{ + public class ContentIdentifier + : Asn1Encodable + { + private Asn1OctetString value; + + public static ContentIdentifier GetInstance( + object o) + { + if (o == null || o is ContentIdentifier) + { + return (ContentIdentifier) o; + } + + if (o is Asn1OctetString) + { + return new ContentIdentifier((Asn1OctetString) o); + } + + throw new ArgumentException( + "unknown object in 'ContentIdentifier' factory : " + + Platform.GetTypeName(o) + "."); + } + + /** + * Create from OCTET STRING whose octets represent the identifier. + */ + public ContentIdentifier( + Asn1OctetString value) + { + this.value = value; + } + + /** + * Create from byte array representing the identifier. + */ + public ContentIdentifier( + byte[] value) + : this(new DerOctetString(value)) + { + } + + public Asn1OctetString Value + { + get { return value; } + } + + /** + * The definition of ContentIdentifier is + *
+		 * ContentIdentifier ::=  OCTET STRING
+		 * 
+ * id-aa-contentIdentifier OBJECT IDENTIFIER ::= { iso(1) + * member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs9(9) + * smime(16) id-aa(2) 7 } + */ + public override Asn1Object ToAsn1Object() + { + return value; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess/ContentIdentifier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess/ContentIdentifier.cs.meta new file mode 100644 index 0000000..84e939e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess/ContentIdentifier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 71df6006c799941419acda1451a48711 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess/ESSCertID.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess/ESSCertID.cs new file mode 100644 index 0000000..7e5fe4c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess/ESSCertID.cs @@ -0,0 +1,89 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Ess +{ + public class EssCertID + : Asn1Encodable + { + private Asn1OctetString certHash; + private IssuerSerial issuerSerial; + + public static EssCertID GetInstance( + object o) + { + if (o == null || o is EssCertID) + { + return (EssCertID) o; + } + + if (o is Asn1Sequence) + { + return new EssCertID((Asn1Sequence) o); + } + + throw new ArgumentException( + "unknown object in 'EssCertID' factory : " + + Platform.GetTypeName(o) + "."); + } + + /** + * constructor + */ + public EssCertID( + Asn1Sequence seq) + { + if (seq.Count < 1 || seq.Count > 2) + { + throw new ArgumentException("Bad sequence size: " + seq.Count); + } + + this.certHash = Asn1OctetString.GetInstance(seq[0]); + + if (seq.Count > 1) + { + issuerSerial = IssuerSerial.GetInstance(seq[1]); + } + } + + public EssCertID( + byte[] hash) + { + certHash = new DerOctetString(hash); + } + + public EssCertID( + byte[] hash, + IssuerSerial issuerSerial) + { + this.certHash = new DerOctetString(hash); + this.issuerSerial = issuerSerial; + } + + public byte[] GetCertHash() + { + return certHash.GetOctets(); + } + + public IssuerSerial IssuerSerial + { + get { return issuerSerial; } + } + + /** + *
+		 * EssCertID ::= SEQUENCE {
+		 *     certHash Hash,
+		 *     issuerSerial IssuerSerial OPTIONAL }
+		 * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(certHash); + v.AddOptional(issuerSerial); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess/ESSCertID.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess/ESSCertID.cs.meta new file mode 100644 index 0000000..50f163b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess/ESSCertID.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7f22064e444d70f469697ad3a5e33b2a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess/ESSCertIDv2.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess/ESSCertIDv2.cs new file mode 100644 index 0000000..1711a76 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess/ESSCertIDv2.cs @@ -0,0 +1,141 @@ +using System; + +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Ess +{ + public class EssCertIDv2 + : Asn1Encodable + { + private readonly AlgorithmIdentifier hashAlgorithm; + private readonly byte[] certHash; + private readonly IssuerSerial issuerSerial; + + private static readonly AlgorithmIdentifier DefaultAlgID = new AlgorithmIdentifier( + NistObjectIdentifiers.IdSha256); + + public static EssCertIDv2 GetInstance(object obj) + { + if (obj == null) + return null; + EssCertIDv2 existing = obj as EssCertIDv2; + if (existing != null) + return existing; + return new EssCertIDv2(Asn1Sequence.GetInstance(obj)); + } + + private EssCertIDv2( + Asn1Sequence seq) + { + if (seq.Count > 3) + throw new ArgumentException("Bad sequence size: " + seq.Count, "seq"); + + int count = 0; + + if (seq[0] is Asn1OctetString) + { + // Default value + this.hashAlgorithm = DefaultAlgID; + } + else + { + this.hashAlgorithm = AlgorithmIdentifier.GetInstance(seq[count++].ToAsn1Object()); + } + + this.certHash = Asn1OctetString.GetInstance(seq[count++].ToAsn1Object()).GetOctets(); + + if (seq.Count > count) + { + this.issuerSerial = IssuerSerial.GetInstance( + Asn1Sequence.GetInstance(seq[count].ToAsn1Object())); + } + } + + public EssCertIDv2(byte[] certHash) + : this(null, certHash, null) + { + } + + public EssCertIDv2( + AlgorithmIdentifier algId, + byte[] certHash) + : this(algId, certHash, null) + { + } + + public EssCertIDv2( + byte[] certHash, + IssuerSerial issuerSerial) + : this(null, certHash, issuerSerial) + { + } + + public EssCertIDv2( + AlgorithmIdentifier algId, + byte[] certHash, + IssuerSerial issuerSerial) + { + if (algId == null) + { + // Default value + this.hashAlgorithm = DefaultAlgID; + } + else + { + this.hashAlgorithm = algId; + } + + this.certHash = certHash; + this.issuerSerial = issuerSerial; + } + + public AlgorithmIdentifier HashAlgorithm + { + get { return this.hashAlgorithm; } + } + + public byte[] GetCertHash() + { + return Arrays.Clone(certHash); + } + + public IssuerSerial IssuerSerial + { + get { return issuerSerial; } + } + + /** + *
+         * EssCertIDv2 ::=  SEQUENCE {
+         *     hashAlgorithm     AlgorithmIdentifier
+         *              DEFAULT {algorithm id-sha256},
+         *     certHash          Hash,
+         *     issuerSerial      IssuerSerial OPTIONAL
+         * }
+         *
+         * Hash ::= OCTET STRING
+         *
+         * IssuerSerial ::= SEQUENCE {
+         *     issuer         GeneralNames,
+         *     serialNumber   CertificateSerialNumber
+         * }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + + if (!hashAlgorithm.Equals(DefaultAlgID)) + { + v.Add(hashAlgorithm); + } + + v.Add(new DerOctetString(certHash).ToAsn1Object()); + v.AddOptional(issuerSerial); + return new DerSequence(v); + } + + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess/ESSCertIDv2.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess/ESSCertIDv2.cs.meta new file mode 100644 index 0000000..9b3ac58 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess/ESSCertIDv2.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5f5312329d83fd143ab0369fc44b54d8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess/OtherCertID.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess/OtherCertID.cs new file mode 100644 index 0000000..183055e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess/OtherCertID.cs @@ -0,0 +1,129 @@ +using System; + +using Org.BouncyCastle.Asn1.Oiw; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Ess +{ + [Obsolete("Use version in Asn1.Esf instead")] + public class OtherCertID + : Asn1Encodable + { + private Asn1Encodable otherCertHash; + private IssuerSerial issuerSerial; + + public static OtherCertID GetInstance( + object o) + { + if (o == null || o is OtherCertID) + { + return (OtherCertID) o; + } + + if (o is Asn1Sequence) + { + return new OtherCertID((Asn1Sequence) o); + } + + throw new ArgumentException( + "unknown object in 'OtherCertID' factory : " + + Platform.GetTypeName(o) + "."); + } + + /** + * constructor + */ + public OtherCertID( + Asn1Sequence seq) + { + if (seq.Count < 1 || seq.Count > 2) + { + throw new ArgumentException("Bad sequence size: " + seq.Count); + } + + if (seq[0].ToAsn1Object() is Asn1OctetString) + { + otherCertHash = Asn1OctetString.GetInstance(seq[0]); + } + else + { + otherCertHash = DigestInfo.GetInstance(seq[0]); + } + + if (seq.Count > 1) + { + issuerSerial = IssuerSerial.GetInstance(Asn1Sequence.GetInstance(seq[1])); + } + } + + public OtherCertID( + AlgorithmIdentifier algId, + byte[] digest) + { + this.otherCertHash = new DigestInfo(algId, digest); + } + + public OtherCertID( + AlgorithmIdentifier algId, + byte[] digest, + IssuerSerial issuerSerial) + { + this.otherCertHash = new DigestInfo(algId, digest); + this.issuerSerial = issuerSerial; + } + + public AlgorithmIdentifier AlgorithmHash + { + get + { + if (otherCertHash.ToAsn1Object() is Asn1OctetString) + { + // SHA-1 + return new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1); + } + + return DigestInfo.GetInstance(otherCertHash).AlgorithmID; + } + } + + public byte[] GetCertHash() + { + if (otherCertHash.ToAsn1Object() is Asn1OctetString) + { + // SHA-1 + return ((Asn1OctetString) otherCertHash.ToAsn1Object()).GetOctets(); + } + + return DigestInfo.GetInstance(otherCertHash).GetDigest(); + } + + public IssuerSerial IssuerSerial + { + get { return issuerSerial; } + } + + /** + *
+		 * OtherCertID ::= SEQUENCE {
+		 *     otherCertHash    OtherHash,
+		 *     issuerSerial     IssuerSerial OPTIONAL }
+		 *
+		 * OtherHash ::= CHOICE {
+		 *     sha1Hash     OCTET STRING,
+		 *     otherHash    OtherHashAlgAndValue }
+		 *
+		 * OtherHashAlgAndValue ::= SEQUENCE {
+		 *     hashAlgorithm    AlgorithmIdentifier,
+		 *     hashValue        OCTET STRING }
+		 *
+		 * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(otherCertHash); + v.AddOptional(issuerSerial); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess/OtherCertID.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess/OtherCertID.cs.meta new file mode 100644 index 0000000..923354f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess/OtherCertID.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c2c6a0002fe19314d9f0b06d63fe7543 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess/OtherSigningCertificate.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess/OtherSigningCertificate.cs new file mode 100644 index 0000000..65152b6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess/OtherSigningCertificate.cs @@ -0,0 +1,105 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Ess +{ + [Obsolete("Use version in Asn1.Esf instead")] + public class OtherSigningCertificate + : Asn1Encodable + { + private Asn1Sequence certs, policies; + + public static OtherSigningCertificate GetInstance( + object o) + { + if (o == null || o is OtherSigningCertificate) + { + return (OtherSigningCertificate) o; + } + + if (o is Asn1Sequence) + { + return new OtherSigningCertificate((Asn1Sequence) o); + } + + throw new ArgumentException( + "unknown object in 'OtherSigningCertificate' factory : " + + Platform.GetTypeName(o) + "."); + } + + /** + * constructors + */ + public OtherSigningCertificate( + Asn1Sequence seq) + { + if (seq.Count < 1 || seq.Count > 2) + { + throw new ArgumentException("Bad sequence size: " + seq.Count); + } + + this.certs = Asn1Sequence.GetInstance(seq[0]); + + if (seq.Count > 1) + { + this.policies = Asn1Sequence.GetInstance(seq[1]); + } + } + + public OtherSigningCertificate( + OtherCertID otherCertID) + { + certs = new DerSequence(otherCertID); + } + + public OtherCertID[] GetCerts() + { + OtherCertID[] cs = new OtherCertID[certs.Count]; + + for (int i = 0; i != certs.Count; ++i) + { + cs[i] = OtherCertID.GetInstance(certs[i]); + } + + return cs; + } + + public PolicyInformation[] GetPolicies() + { + if (policies == null) + { + return null; + } + + PolicyInformation[] ps = new PolicyInformation[policies.Count]; + + for (int i = 0; i != policies.Count; i++) + { + ps[i] = PolicyInformation.GetInstance(policies[i]); + } + + return ps; + } + + /** + * The definition of OtherSigningCertificate is + *
+		 * OtherSigningCertificate ::=  SEQUENCE {
+		 *      certs        SEQUENCE OF OtherCertID,
+		 *      policies     SEQUENCE OF PolicyInformation OPTIONAL
+		 * }
+		 * 
+ * id-aa-ets-otherSigCert OBJECT IDENTIFIER ::= { iso(1) + * member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs9(9) + * smime(16) id-aa(2) 19 } + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(certs); + v.AddOptional(policies); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess/OtherSigningCertificate.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess/OtherSigningCertificate.cs.meta new file mode 100644 index 0000000..6719055 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess/OtherSigningCertificate.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9a42a63f0730a3c4fa3242fdb778b3d1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess/SigningCertificate.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess/SigningCertificate.cs new file mode 100644 index 0000000..6b8deee --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess/SigningCertificate.cs @@ -0,0 +1,104 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Ess +{ + public class SigningCertificate + : Asn1Encodable + { + private Asn1Sequence certs, policies; + + public static SigningCertificate GetInstance( + object o) + { + if (o == null || o is SigningCertificate) + { + return (SigningCertificate) o; + } + + if (o is Asn1Sequence) + { + return new SigningCertificate((Asn1Sequence) o); + } + + throw new ArgumentException( + "unknown object in 'SigningCertificate' factory : " + + Platform.GetTypeName(o) + "."); + } + + /** + * constructors + */ + public SigningCertificate( + Asn1Sequence seq) + { + if (seq.Count < 1 || seq.Count > 2) + { + throw new ArgumentException("Bad sequence size: " + seq.Count); + } + + this.certs = Asn1Sequence.GetInstance(seq[0]); + + if (seq.Count > 1) + { + this.policies = Asn1Sequence.GetInstance(seq[1]); + } + } + + public SigningCertificate( + EssCertID essCertID) + { + certs = new DerSequence(essCertID); + } + + public EssCertID[] GetCerts() + { + EssCertID[] cs = new EssCertID[certs.Count]; + + for (int i = 0; i != certs.Count; i++) + { + cs[i] = EssCertID.GetInstance(certs[i]); + } + + return cs; + } + + public PolicyInformation[] GetPolicies() + { + if (policies == null) + { + return null; + } + + PolicyInformation[] ps = new PolicyInformation[policies.Count]; + + for (int i = 0; i != policies.Count; i++) + { + ps[i] = PolicyInformation.GetInstance(policies[i]); + } + + return ps; + } + + /** + * The definition of SigningCertificate is + *
+		 * SigningCertificate ::=  SEQUENCE {
+		 *      certs        SEQUENCE OF EssCertID,
+		 *      policies     SEQUENCE OF PolicyInformation OPTIONAL
+		 * }
+		 * 
+ * id-aa-signingCertificate OBJECT IDENTIFIER ::= { iso(1) + * member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs9(9) + * smime(16) id-aa(2) 12 } + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(certs); + v.AddOptional(policies); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess/SigningCertificate.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess/SigningCertificate.cs.meta new file mode 100644 index 0000000..1894de4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess/SigningCertificate.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b5d820def2ad4334a86db3f7b44f8c30 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess/SigningCertificateV2.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess/SigningCertificateV2.cs new file mode 100644 index 0000000..4694098 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess/SigningCertificateV2.cs @@ -0,0 +1,108 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Ess +{ + public class SigningCertificateV2 + : Asn1Encodable + { + private readonly Asn1Sequence certs; + private readonly Asn1Sequence policies; + + public static SigningCertificateV2 GetInstance( + object o) + { + if (o == null || o is SigningCertificateV2) + return (SigningCertificateV2) o; + + if (o is Asn1Sequence) + return new SigningCertificateV2((Asn1Sequence) o); + + throw new ArgumentException( + "unknown object in 'SigningCertificateV2' factory : " + + Platform.GetTypeName(o) + "."); + } + + private SigningCertificateV2( + Asn1Sequence seq) + { + if (seq.Count < 1 || seq.Count > 2) + throw new ArgumentException("Bad sequence size: " + seq.Count, "seq"); + + this.certs = Asn1Sequence.GetInstance(seq[0].ToAsn1Object()); + + if (seq.Count > 1) + { + this.policies = Asn1Sequence.GetInstance(seq[1].ToAsn1Object()); + } + } + + public SigningCertificateV2( + EssCertIDv2 cert) + { + this.certs = new DerSequence(cert); + } + + public SigningCertificateV2( + EssCertIDv2[] certs) + { + this.certs = new DerSequence(certs); + } + + public SigningCertificateV2( + EssCertIDv2[] certs, + PolicyInformation[] policies) + { + this.certs = new DerSequence(certs); + + if (policies != null) + { + this.policies = new DerSequence(policies); + } + } + + public EssCertIDv2[] GetCerts() + { + EssCertIDv2[] certIds = new EssCertIDv2[certs.Count]; + for (int i = 0; i != certs.Count; i++) + { + certIds[i] = EssCertIDv2.GetInstance(certs[i]); + } + return certIds; + } + + public PolicyInformation[] GetPolicies() + { + if (policies == null) + return null; + + PolicyInformation[] policyInformations = new PolicyInformation[policies.Count]; + for (int i = 0; i != policies.Count; i++) + { + policyInformations[i] = PolicyInformation.GetInstance(policies[i]); + } + return policyInformations; + } + + /** + * The definition of SigningCertificateV2 is + *
+         * SigningCertificateV2 ::=  SEQUENCE {
+         *      certs        SEQUENCE OF EssCertIDv2,
+         *      policies     SEQUENCE OF PolicyInformation OPTIONAL
+         * }
+         * 
+ * id-aa-signingCertificateV2 OBJECT IDENTIFIER ::= { iso(1) + * member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs9(9) + * smime(16) id-aa(2) 47 } + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(certs); + v.AddOptional(policies); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess/SigningCertificateV2.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess/SigningCertificateV2.cs.meta new file mode 100644 index 0000000..3ced2de --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ess/SigningCertificateV2.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 82df487dada74274bb717008602138fe +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/gm.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/gm.meta new file mode 100644 index 0000000..284df78 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/gm.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a9c83a747a453d4478e9e2f47172967b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/gm/GMNamedCurves.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/gm/GMNamedCurves.cs new file mode 100644 index 0000000..866733c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/gm/GMNamedCurves.cs @@ -0,0 +1,161 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Math.EC.Multiplier; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Asn1.GM +{ + public sealed class GMNamedCurves + { + private GMNamedCurves() + { + } + + private static X9ECPoint ConfigureBasepoint(ECCurve curve, string encoding) + { + X9ECPoint G = new X9ECPoint(curve, Hex.DecodeStrict(encoding)); + WNafUtilities.ConfigureBasepoint(G.Point); + return G; + } + + private static ECCurve ConfigureCurve(ECCurve curve) + { + return curve; + } + + private static BigInteger FromHex(string hex) + { + return new BigInteger(1, Hex.DecodeStrict(hex)); + } + + /* + * sm2p256v1 + */ + internal class SM2P256V1Holder + : X9ECParametersHolder + { + private SM2P256V1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new SM2P256V1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger p = FromHex("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF"); + BigInteger a = FromHex("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC"); + BigInteger b = FromHex("28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93"); + byte[] S = null; + BigInteger n = FromHex("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123"); + BigInteger h = BigInteger.One; + + ECCurve curve = ConfigureCurve(new FpCurve(p, a, b, n, h)); + X9ECPoint G = ConfigureBasepoint(curve, + "0432C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0"); + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * wapip192v1 + */ + internal class WapiP192V1Holder + : X9ECParametersHolder + { + private WapiP192V1Holder() { } + + internal static readonly X9ECParametersHolder Instance = new WapiP192V1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger p = FromHex("BDB6F4FE3E8B1D9E0DA8C0D46F4C318CEFE4AFE3B6B8551F"); + BigInteger a = FromHex("BB8E5E8FBC115E139FE6A814FE48AAA6F0ADA1AA5DF91985"); + BigInteger b = FromHex("1854BEBDC31B21B7AEFC80AB0ECD10D5B1B3308E6DBF11C1"); + byte[] S = null; + BigInteger n = FromHex("BDB6F4FE3E8B1D9E0DA8C0D40FC962195DFAE76F56564677"); + BigInteger h = BigInteger.One; + + ECCurve curve = ConfigureCurve(new FpCurve(p, a, b, n, h)); + X9ECPoint G = ConfigureBasepoint(curve, + "044AD5F7048DE709AD51236DE65E4D4B482C836DC6E410664002BB3A02D4AAADACAE24817A4CA3A1B014B5270432DB27D2"); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + + private static readonly IDictionary objIds = Platform.CreateHashtable(); + private static readonly IDictionary curves = Platform.CreateHashtable(); + private static readonly IDictionary names = Platform.CreateHashtable(); + + private static void DefineCurve( + string name, + DerObjectIdentifier oid, + X9ECParametersHolder holder) + { + objIds.Add(Platform.ToUpperInvariant(name), oid); + names.Add(oid, name); + curves.Add(oid, holder); + } + + static GMNamedCurves() + { + DefineCurve("wapip192v1", GMObjectIdentifiers.wapip192v1, WapiP192V1Holder.Instance); + DefineCurve("sm2p256v1", GMObjectIdentifiers.sm2p256v1, SM2P256V1Holder.Instance); + } + + public static X9ECParameters GetByName( + string name) + { + DerObjectIdentifier oid = GetOid(name); + return oid == null ? null : GetByOid(oid); + } + + /** + * return the X9ECParameters object for the named curve represented by + * the passed in object identifier. Null if the curve isn't present. + * + * @param oid an object identifier representing a named curve, if present. + */ + public static X9ECParameters GetByOid( + DerObjectIdentifier oid) + { + X9ECParametersHolder holder = (X9ECParametersHolder)curves[oid]; + return holder == null ? null : holder.Parameters; + } + + /** + * return the object identifier signified by the passed in name. Null + * if there is no object identifier associated with name. + * + * @return the object identifier associated with name, if present. + */ + public static DerObjectIdentifier GetOid( + string name) + { + return (DerObjectIdentifier)objIds[Platform.ToUpperInvariant(name)]; + } + + /** + * return the named curve name represented by the given object identifier. + */ + public static string GetName( + DerObjectIdentifier oid) + { + return (string)names[oid]; + } + + /** + * returns an enumeration containing the name strings for curves + * contained in this structure. + */ + public static IEnumerable Names + { + get { return new EnumerableProxy(names.Values); } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/gm/GMNamedCurves.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/gm/GMNamedCurves.cs.meta new file mode 100644 index 0000000..5232fca --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/gm/GMNamedCurves.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 02257e1fe0f95ce4c9d3a05d7f9341e1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/gm/GMObjectIdentifiers.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/gm/GMObjectIdentifiers.cs new file mode 100644 index 0000000..edb3a41 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/gm/GMObjectIdentifiers.cs @@ -0,0 +1,85 @@ +using System; + +namespace Org.BouncyCastle.Asn1.GM +{ + public abstract class GMObjectIdentifiers + { + public static readonly DerObjectIdentifier sm_scheme = new DerObjectIdentifier("1.2.156.10197.1"); + + public static readonly DerObjectIdentifier sm6_ecb = sm_scheme.Branch("101.1"); + public static readonly DerObjectIdentifier sm6_cbc = sm_scheme.Branch("101.2"); + public static readonly DerObjectIdentifier sm6_ofb128 = sm_scheme.Branch("101.3"); + public static readonly DerObjectIdentifier sm6_cfb128 = sm_scheme.Branch("101.4"); + + public static readonly DerObjectIdentifier sm1_ecb = sm_scheme.Branch("102.1"); + public static readonly DerObjectIdentifier sm1_cbc = sm_scheme.Branch("102.2"); + public static readonly DerObjectIdentifier sm1_ofb128 = sm_scheme.Branch("102.3"); + public static readonly DerObjectIdentifier sm1_cfb128 = sm_scheme.Branch("102.4"); + public static readonly DerObjectIdentifier sm1_cfb1 = sm_scheme.Branch("102.5"); + public static readonly DerObjectIdentifier sm1_cfb8 = sm_scheme.Branch("102.6"); + + public static readonly DerObjectIdentifier ssf33_ecb = sm_scheme.Branch("103.1"); + public static readonly DerObjectIdentifier ssf33_cbc = sm_scheme.Branch("103.2"); + public static readonly DerObjectIdentifier ssf33_ofb128 = sm_scheme.Branch("103.3"); + public static readonly DerObjectIdentifier ssf33_cfb128 = sm_scheme.Branch("103.4"); + public static readonly DerObjectIdentifier ssf33_cfb1 = sm_scheme.Branch("103.5"); + public static readonly DerObjectIdentifier ssf33_cfb8 = sm_scheme.Branch("103.6"); + + public static readonly DerObjectIdentifier sms4_ecb = sm_scheme.Branch("104.1"); + public static readonly DerObjectIdentifier sms4_cbc = sm_scheme.Branch("104.2"); + public static readonly DerObjectIdentifier sms4_ofb128 = sm_scheme.Branch("104.3"); + public static readonly DerObjectIdentifier sms4_cfb128 = sm_scheme.Branch("104.4"); + public static readonly DerObjectIdentifier sms4_cfb1 = sm_scheme.Branch("104.5"); + public static readonly DerObjectIdentifier sms4_cfb8 = sm_scheme.Branch("104.6"); + public static readonly DerObjectIdentifier sms4_ctr = sm_scheme.Branch("104.7"); + public static readonly DerObjectIdentifier sms4_gcm = sm_scheme.Branch("104.8"); + public static readonly DerObjectIdentifier sms4_ccm = sm_scheme.Branch("104.9"); + public static readonly DerObjectIdentifier sms4_xts = sm_scheme.Branch("104.10"); + public static readonly DerObjectIdentifier sms4_wrap = sm_scheme.Branch("104.11"); + public static readonly DerObjectIdentifier sms4_wrap_pad = sm_scheme.Branch("104.12"); + public static readonly DerObjectIdentifier sms4_ocb = sm_scheme.Branch("104.100"); + + public static readonly DerObjectIdentifier sm5 = sm_scheme.Branch("201"); + + public static readonly DerObjectIdentifier sm2p256v1 = sm_scheme.Branch("301"); + public static readonly DerObjectIdentifier sm2sign = sm_scheme.Branch("301.1"); + public static readonly DerObjectIdentifier sm2exchange = sm_scheme.Branch("301.2"); + public static readonly DerObjectIdentifier sm2encrypt = sm_scheme.Branch("301.3"); + + public static readonly DerObjectIdentifier wapip192v1 = sm_scheme.Branch("301.101"); + + public static readonly DerObjectIdentifier sm2encrypt_recommendedParameters = sm2encrypt.Branch("1"); + public static readonly DerObjectIdentifier sm2encrypt_specifiedParameters = sm2encrypt.Branch("2"); + public static readonly DerObjectIdentifier sm2encrypt_with_sm3 = sm2encrypt.Branch("2.1"); + public static readonly DerObjectIdentifier sm2encrypt_with_sha1 = sm2encrypt.Branch("2.2"); + public static readonly DerObjectIdentifier sm2encrypt_with_sha224 = sm2encrypt.Branch("2.3"); + public static readonly DerObjectIdentifier sm2encrypt_with_sha256 = sm2encrypt.Branch("2.4"); + public static readonly DerObjectIdentifier sm2encrypt_with_sha384 = sm2encrypt.Branch("2.5"); + public static readonly DerObjectIdentifier sm2encrypt_with_sha512 = sm2encrypt.Branch("2.6"); + public static readonly DerObjectIdentifier sm2encrypt_with_rmd160 = sm2encrypt.Branch("2.7"); + public static readonly DerObjectIdentifier sm2encrypt_with_whirlpool = sm2encrypt.Branch("2.8"); + public static readonly DerObjectIdentifier sm2encrypt_with_blake2b512 = sm2encrypt.Branch("2.9"); + public static readonly DerObjectIdentifier sm2encrypt_with_blake2s256 = sm2encrypt.Branch("2.10"); + public static readonly DerObjectIdentifier sm2encrypt_with_md5 = sm2encrypt.Branch("2.11"); + + public static readonly DerObjectIdentifier id_sm9PublicKey = sm_scheme.Branch("302"); + public static readonly DerObjectIdentifier sm9sign = sm_scheme.Branch("302.1"); + public static readonly DerObjectIdentifier sm9keyagreement = sm_scheme.Branch("302.2"); + public static readonly DerObjectIdentifier sm9encrypt = sm_scheme.Branch("302.3"); + + public static readonly DerObjectIdentifier sm3 = sm_scheme.Branch("401"); + + public static readonly DerObjectIdentifier hmac_sm3 = sm3.Branch("2"); + + public static readonly DerObjectIdentifier sm2sign_with_sm3 = sm_scheme.Branch("501"); + public static readonly DerObjectIdentifier sm2sign_with_sha1 = sm_scheme.Branch("502"); + public static readonly DerObjectIdentifier sm2sign_with_sha256 = sm_scheme.Branch("503"); + public static readonly DerObjectIdentifier sm2sign_with_sha512 = sm_scheme.Branch("504"); + public static readonly DerObjectIdentifier sm2sign_with_sha224 = sm_scheme.Branch("505"); + public static readonly DerObjectIdentifier sm2sign_with_sha384 = sm_scheme.Branch("506"); + public static readonly DerObjectIdentifier sm2sign_with_rmd160 = sm_scheme.Branch("507"); + public static readonly DerObjectIdentifier sm2sign_with_whirlpool = sm_scheme.Branch("520"); + public static readonly DerObjectIdentifier sm2sign_with_blake2b512 = sm_scheme.Branch("521"); + public static readonly DerObjectIdentifier sm2sign_with_blake2s256 = sm_scheme.Branch("522"); + } +} \ No newline at end of file diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/gm/GMObjectIdentifiers.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/gm/GMObjectIdentifiers.cs.meta new file mode 100644 index 0000000..cdade08 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/gm/GMObjectIdentifiers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 333910ffed2aa23429ca16ec51ab59a0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/gnu.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/gnu.meta new file mode 100644 index 0000000..a9fd9f7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/gnu.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7855561df71bcb24ab7990722c61c83c +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/gnu/GNUObjectIdentifiers.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/gnu/GNUObjectIdentifiers.cs new file mode 100644 index 0000000..b322ef2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/gnu/GNUObjectIdentifiers.cs @@ -0,0 +1,36 @@ +using System; + +namespace Org.BouncyCastle.Asn1.Gnu +{ + public abstract class GnuObjectIdentifiers + { + public static readonly DerObjectIdentifier Gnu = new DerObjectIdentifier("1.3.6.1.4.1.11591.1"); // GNU Radius + public static readonly DerObjectIdentifier GnuPG = new DerObjectIdentifier("1.3.6.1.4.1.11591.2"); // GnuPG (Ägypten) + public static readonly DerObjectIdentifier Notation = new DerObjectIdentifier("1.3.6.1.4.1.11591.2.1"); // notation + public static readonly DerObjectIdentifier PkaAddress = new DerObjectIdentifier("1.3.6.1.4.1.11591.2.1.1"); // pkaAddress + public static readonly DerObjectIdentifier GnuRadar = new DerObjectIdentifier("1.3.6.1.4.1.11591.3"); // GNU Radar + public static readonly DerObjectIdentifier DigestAlgorithm = new DerObjectIdentifier("1.3.6.1.4.1.11591.12"); // digestAlgorithm + public static readonly DerObjectIdentifier Tiger192 = new DerObjectIdentifier("1.3.6.1.4.1.11591.12.2"); // TIGER/192 + public static readonly DerObjectIdentifier EncryptionAlgorithm = new DerObjectIdentifier("1.3.6.1.4.1.11591.13"); // encryptionAlgorithm + public static readonly DerObjectIdentifier Serpent = new DerObjectIdentifier("1.3.6.1.4.1.11591.13.2"); // Serpent + public static readonly DerObjectIdentifier Serpent128Ecb = new DerObjectIdentifier("1.3.6.1.4.1.11591.13.2.1"); // Serpent-128-ECB + public static readonly DerObjectIdentifier Serpent128Cbc = new DerObjectIdentifier("1.3.6.1.4.1.11591.13.2.2"); // Serpent-128-CBC + public static readonly DerObjectIdentifier Serpent128Ofb = new DerObjectIdentifier("1.3.6.1.4.1.11591.13.2.3"); // Serpent-128-OFB + public static readonly DerObjectIdentifier Serpent128Cfb = new DerObjectIdentifier("1.3.6.1.4.1.11591.13.2.4"); // Serpent-128-CFB + public static readonly DerObjectIdentifier Serpent192Ecb = new DerObjectIdentifier("1.3.6.1.4.1.11591.13.2.21"); // Serpent-192-ECB + public static readonly DerObjectIdentifier Serpent192Cbc = new DerObjectIdentifier("1.3.6.1.4.1.11591.13.2.22"); // Serpent-192-CBC + public static readonly DerObjectIdentifier Serpent192Ofb = new DerObjectIdentifier("1.3.6.1.4.1.11591.13.2.23"); // Serpent-192-OFB + public static readonly DerObjectIdentifier Serpent192Cfb = new DerObjectIdentifier("1.3.6.1.4.1.11591.13.2.24"); // Serpent-192-CFB + public static readonly DerObjectIdentifier Serpent256Ecb = new DerObjectIdentifier("1.3.6.1.4.1.11591.13.2.41"); // Serpent-256-ECB + public static readonly DerObjectIdentifier Serpent256Cbc = new DerObjectIdentifier("1.3.6.1.4.1.11591.13.2.42"); // Serpent-256-CBC + public static readonly DerObjectIdentifier Serpent256Ofb = new DerObjectIdentifier("1.3.6.1.4.1.11591.13.2.43"); // Serpent-256-OFB + public static readonly DerObjectIdentifier Serpent256Cfb = new DerObjectIdentifier("1.3.6.1.4.1.11591.13.2.44"); // Serpent-256-CFB + public static readonly DerObjectIdentifier Crc = new DerObjectIdentifier("1.3.6.1.4.1.11591.14"); // CRC algorithms + public static readonly DerObjectIdentifier Crc32 = new DerObjectIdentifier("1.3.6.1.4.1.11591.14.1"); // CRC 32 + + /** 1.3.6.1.4.1.11591.15 - ellipticCurve */ + public static readonly DerObjectIdentifier EllipticCurve = new DerObjectIdentifier("1.3.6.1.4.1.11591.15"); + + public static readonly DerObjectIdentifier Ed25519 = EllipticCurve.Branch("1"); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/gnu/GNUObjectIdentifiers.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/gnu/GNUObjectIdentifiers.cs.meta new file mode 100644 index 0000000..c6b9be0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/gnu/GNUObjectIdentifiers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 879a45e5b6dc9ef4fa3f54668802d2a9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/iana.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/iana.meta new file mode 100644 index 0000000..2fda6c0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/iana.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ebbc36fe568e535429bc4600d8136c6a +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/iana/IANAObjectIdentifiers.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/iana/IANAObjectIdentifiers.cs new file mode 100644 index 0000000..63343f5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/iana/IANAObjectIdentifiers.cs @@ -0,0 +1,18 @@ +namespace Org.BouncyCastle.Asn1.Iana +{ + public abstract class IanaObjectIdentifiers + { + // id-SHA1 OBJECT IDENTIFIER ::= + // {iso(1) identified-organization(3) dod(6) internet(1) security(5) mechanisms(5) ipsec(8) isakmpOakley(1)} + // + + public static readonly DerObjectIdentifier IsakmpOakley = new DerObjectIdentifier("1.3.6.1.5.5.8.1"); + + public static readonly DerObjectIdentifier HmacMD5 = new DerObjectIdentifier(IsakmpOakley + ".1"); + public static readonly DerObjectIdentifier HmacSha1 = new DerObjectIdentifier(IsakmpOakley + ".2"); + + public static readonly DerObjectIdentifier HmacTiger = new DerObjectIdentifier(IsakmpOakley + ".3"); + + public static readonly DerObjectIdentifier HmacRipeMD160 = new DerObjectIdentifier(IsakmpOakley + ".4"); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/iana/IANAObjectIdentifiers.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/iana/IANAObjectIdentifiers.cs.meta new file mode 100644 index 0000000..cb667c1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/iana/IANAObjectIdentifiers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7ec440f9d6ce99e4a86a1867b0ca6b00 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/icao.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/icao.meta new file mode 100644 index 0000000..8d19b94 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/icao.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d14b2d6ed305b2444869d8c1860595c9 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/icao/CscaMasterList.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/icao/CscaMasterList.cs new file mode 100644 index 0000000..d03b3ad --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/icao/CscaMasterList.cs @@ -0,0 +1,83 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; + +namespace Org.BouncyCastle.Asn1.Icao +{ + /** + * The CscaMasterList object. This object can be wrapped in a + * CMSSignedData to be published in LDAP. + * + *
+	 * CscaMasterList ::= SEQUENCE {
+	 *   version                CscaMasterListVersion,
+	 *   certList               SET OF Certificate }
+	 *   
+	 * CscaMasterListVersion :: INTEGER {v0(0)}
+	 * 
+ */ + public class CscaMasterList + : Asn1Encodable + { + private DerInteger version = new DerInteger(0); + private X509CertificateStructure[] certList; + + public static CscaMasterList GetInstance( + object obj) + { + if (obj is CscaMasterList) + return (CscaMasterList)obj; + + if (obj != null) + return new CscaMasterList(Asn1Sequence.GetInstance(obj)); + + return null; + } + + private CscaMasterList( + Asn1Sequence seq) + { + if (seq == null || seq.Count == 0) + throw new ArgumentException("null or empty sequence passed."); + + if (seq.Count != 2) + throw new ArgumentException("Incorrect sequence size: " + seq.Count); + + this.version = DerInteger.GetInstance(seq[0]); + + Asn1Set certSet = Asn1Set.GetInstance(seq[1]); + + this.certList = new X509CertificateStructure[certSet.Count]; + for (int i = 0; i < certList.Length; i++) + { + certList[i] = X509CertificateStructure.GetInstance(certSet[i]); + } + } + + public CscaMasterList( + X509CertificateStructure[] certStructs) + { + certList = CopyCertList(certStructs); + } + + public virtual int Version + { + get { return version.IntValueExact; } + } + + public X509CertificateStructure[] GetCertStructs() + { + return CopyCertList(certList); + } + + private static X509CertificateStructure[] CopyCertList(X509CertificateStructure[] orig) + { + return (X509CertificateStructure[])orig.Clone(); + } + + public override Asn1Object ToAsn1Object() + { + return new DerSequence(version, new DerSet(certList)); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/icao/CscaMasterList.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/icao/CscaMasterList.cs.meta new file mode 100644 index 0000000..cbc4479 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/icao/CscaMasterList.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 83b7a07ea01bc2741a0f60e7b5747f9e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/icao/DataGroupHash.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/icao/DataGroupHash.cs new file mode 100644 index 0000000..bf83718 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/icao/DataGroupHash.cs @@ -0,0 +1,86 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; + +namespace Org.BouncyCastle.Asn1.Icao +{ + /** + * The DataGroupHash object. + *
+    * DataGroupHash  ::=  SEQUENCE {
+    *      dataGroupNumber         DataGroupNumber,
+    *      dataGroupHashValue     OCTET STRING }
+    *
+    * DataGroupNumber ::= INTEGER {
+    *         dataGroup1    (1),
+    *         dataGroup1    (2),
+    *         dataGroup1    (3),
+    *         dataGroup1    (4),
+    *         dataGroup1    (5),
+    *         dataGroup1    (6),
+    *         dataGroup1    (7),
+    *         dataGroup1    (8),
+    *         dataGroup1    (9),
+    *         dataGroup1    (10),
+    *         dataGroup1    (11),
+    *         dataGroup1    (12),
+    *         dataGroup1    (13),
+    *         dataGroup1    (14),
+    *         dataGroup1    (15),
+    *         dataGroup1    (16) }
+    *
+    * 
+ */ + public class DataGroupHash + : Asn1Encodable + { + private readonly DerInteger dataGroupNumber; + private readonly Asn1OctetString dataGroupHashValue; + + public static DataGroupHash GetInstance( + object obj) + { + if (obj is DataGroupHash) + return (DataGroupHash)obj; + + if (obj != null) + return new DataGroupHash(Asn1Sequence.GetInstance(obj)); + + return null; + } + + private DataGroupHash( + Asn1Sequence seq) + { + if (seq.Count != 2) + throw new ArgumentException("Wrong number of elements in sequence", "seq"); + + this.dataGroupNumber = DerInteger.GetInstance(seq[0]); + this.dataGroupHashValue = Asn1OctetString.GetInstance(seq[1]); + } + + public DataGroupHash( + int dataGroupNumber, + Asn1OctetString dataGroupHashValue) + { + this.dataGroupNumber = new DerInteger(dataGroupNumber); + this.dataGroupHashValue = dataGroupHashValue; + } + + public int DataGroupNumber + { + get { return dataGroupNumber.IntValueExact; } + } + + public Asn1OctetString DataGroupHashValue + { + get { return dataGroupHashValue; } + } + + public override Asn1Object ToAsn1Object() + { + return new DerSequence(dataGroupNumber, dataGroupHashValue); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/icao/DataGroupHash.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/icao/DataGroupHash.cs.meta new file mode 100644 index 0000000..589a065 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/icao/DataGroupHash.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 737a26bf1a1374140b916f09234b4c5e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/icao/ICAOObjectIdentifiers.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/icao/ICAOObjectIdentifiers.cs new file mode 100644 index 0000000..389d4da --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/icao/ICAOObjectIdentifiers.cs @@ -0,0 +1,34 @@ +using System; + +namespace Org.BouncyCastle.Asn1.Icao +{ + public abstract class IcaoObjectIdentifiers + { + // + // base id + // + public static readonly DerObjectIdentifier IdIcao = new DerObjectIdentifier("2.23.136"); + + public static readonly DerObjectIdentifier IdIcaoMrtd = IdIcao.Branch("1"); + public static readonly DerObjectIdentifier IdIcaoMrtdSecurity = IdIcaoMrtd.Branch("1"); + + // LDS security object, see ICAO Doc 9303-Volume 2-Section IV-A3.2 + public static readonly DerObjectIdentifier IdIcaoLdsSecurityObject = IdIcaoMrtdSecurity.Branch("1"); + + // CSCA master list, see TR CSCA Countersigning and Master List issuance + public static readonly DerObjectIdentifier IdIcaoCscaMasterList = IdIcaoMrtdSecurity.Branch("2"); + public static readonly DerObjectIdentifier IdIcaoCscaMasterListSigningKey = IdIcaoMrtdSecurity.Branch("3"); + + // document type list, see draft TR LDS and PKI Maintenance, par. 3.2.1 + public static readonly DerObjectIdentifier IdIcaoDocumentTypeList = IdIcaoMrtdSecurity.Branch("4"); + + // Active Authentication protocol, see draft TR LDS and PKI Maintenance, + // par. 5.2.2 + public static readonly DerObjectIdentifier IdIcaoAAProtocolObject = IdIcaoMrtdSecurity.Branch("5"); + + // CSCA name change and key reoll-over, see draft TR LDS and PKI + // Maintenance, par. 3.2.1 + public static readonly DerObjectIdentifier IdIcaoExtensions = IdIcaoMrtdSecurity.Branch("6"); + public static readonly DerObjectIdentifier IdIcaoExtensionsNamechangekeyrollover = IdIcaoExtensions.Branch("1"); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/icao/ICAOObjectIdentifiers.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/icao/ICAOObjectIdentifiers.cs.meta new file mode 100644 index 0000000..2ee12fc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/icao/ICAOObjectIdentifiers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ab97368628cbb354c801b33a972c8225 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/icao/LDSSecurityObject.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/icao/LDSSecurityObject.cs new file mode 100644 index 0000000..5d7331a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/icao/LDSSecurityObject.cs @@ -0,0 +1,139 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Asn1.Icao +{ + /** + * The LDSSecurityObject object (V1.8). + *
+	 * LDSSecurityObject ::= SEQUENCE {
+	 *   version                LDSSecurityObjectVersion,
+	 *   hashAlgorithm          DigestAlgorithmIdentifier,
+	 *   dataGroupHashValues    SEQUENCE SIZE (2..ub-DataGroups) OF DataHashGroup,
+	 *   ldsVersionInfo         LDSVersionInfo OPTIONAL
+	 *     -- if present, version MUST be v1 }
+	 *
+	 * DigestAlgorithmIdentifier ::= AlgorithmIdentifier,
+	 *
+	 * LDSSecurityObjectVersion :: INTEGER {V0(0)}
+	 * 
+ */ + public class LdsSecurityObject + : Asn1Encodable + { + public const int UBDataGroups = 16; + + private DerInteger version = new DerInteger(0); + private AlgorithmIdentifier digestAlgorithmIdentifier; + private DataGroupHash[] datagroupHash; + private LdsVersionInfo versionInfo; + + public static LdsSecurityObject GetInstance( + object obj) + { + if (obj is LdsSecurityObject) + return (LdsSecurityObject)obj; + + if (obj != null) + return new LdsSecurityObject(Asn1Sequence.GetInstance(obj)); + + return null; + } + + private LdsSecurityObject( + Asn1Sequence seq) + { + if (seq == null || seq.Count == 0) + throw new ArgumentException("null or empty sequence passed."); + + IEnumerator e = seq.GetEnumerator(); + + // version + e.MoveNext(); + version = DerInteger.GetInstance(e.Current); + // digestAlgorithmIdentifier + e.MoveNext(); + digestAlgorithmIdentifier = AlgorithmIdentifier.GetInstance(e.Current); + + e.MoveNext(); + Asn1Sequence datagroupHashSeq = Asn1Sequence.GetInstance(e.Current); + + if (version.HasValue(1)) + { + e.MoveNext(); + versionInfo = LdsVersionInfo.GetInstance(e.Current); + } + + CheckDatagroupHashSeqSize(datagroupHashSeq.Count); + + datagroupHash = new DataGroupHash[datagroupHashSeq.Count]; + for (int i= 0; i< datagroupHashSeq.Count; i++) + { + datagroupHash[i] = DataGroupHash.GetInstance(datagroupHashSeq[i]); + } + } + + public LdsSecurityObject( + AlgorithmIdentifier digestAlgorithmIdentifier, + DataGroupHash[] datagroupHash) + { + this.version = new DerInteger(0); + this.digestAlgorithmIdentifier = digestAlgorithmIdentifier; + this.datagroupHash = datagroupHash; + + CheckDatagroupHashSeqSize(datagroupHash.Length); + } + + + public LdsSecurityObject( + AlgorithmIdentifier digestAlgorithmIdentifier, + DataGroupHash[] datagroupHash, + LdsVersionInfo versionInfo) + { + this.version = new DerInteger(1); + this.digestAlgorithmIdentifier = digestAlgorithmIdentifier; + this.datagroupHash = datagroupHash; + this.versionInfo = versionInfo; + + CheckDatagroupHashSeqSize(datagroupHash.Length); + } + + private void CheckDatagroupHashSeqSize(int size) + { + if (size < 2 || size > UBDataGroups) + throw new ArgumentException("wrong size in DataGroupHashValues : not in (2.."+ UBDataGroups +")"); + } + + public BigInteger Version + { + get { return version.Value; } + } + + public AlgorithmIdentifier DigestAlgorithmIdentifier + { + get { return digestAlgorithmIdentifier; } + } + + public DataGroupHash[] GetDatagroupHash() + { + return datagroupHash; + } + + public LdsVersionInfo VersionInfo + { + get { return versionInfo; } + } + + public override Asn1Object ToAsn1Object() + { + DerSequence hashSeq = new DerSequence(datagroupHash); + + Asn1EncodableVector v = new Asn1EncodableVector(version, digestAlgorithmIdentifier, hashSeq); + v.AddOptional(versionInfo); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/icao/LDSSecurityObject.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/icao/LDSSecurityObject.cs.meta new file mode 100644 index 0000000..fda8563 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/icao/LDSSecurityObject.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 83f949ad9df4efe4eabd16b2de7f75b1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/icao/LDSVersionInfo.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/icao/LDSVersionInfo.cs new file mode 100644 index 0000000..2cdcad2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/icao/LDSVersionInfo.cs @@ -0,0 +1,61 @@ +using System; + +namespace Org.BouncyCastle.Asn1.Icao +{ + public class LdsVersionInfo + : Asn1Encodable + { + private DerPrintableString ldsVersion; + private DerPrintableString unicodeVersion; + + public LdsVersionInfo(string ldsVersion, string unicodeVersion) + { + this.ldsVersion = new DerPrintableString(ldsVersion); + this.unicodeVersion = new DerPrintableString(unicodeVersion); + } + + private LdsVersionInfo(Asn1Sequence seq) + { + if (seq.Count != 2) + throw new ArgumentException("sequence wrong size for LDSVersionInfo", "seq"); + + this.ldsVersion = DerPrintableString.GetInstance(seq[0]); + this.unicodeVersion = DerPrintableString.GetInstance(seq[1]); + } + + public static LdsVersionInfo GetInstance(object obj) + { + if (obj is LdsVersionInfo) + return (LdsVersionInfo)obj; + + if (obj != null) + return new LdsVersionInfo(Asn1Sequence.GetInstance(obj)); + + return null; + } + + public virtual string GetLdsVersion() + { + return ldsVersion.GetString(); + } + + public virtual string GetUnicodeVersion() + { + return unicodeVersion.GetString(); + } + + /** + *
+		 * LDSVersionInfo ::= SEQUENCE {
+		 *    ldsVersion PRINTABLE STRING
+		 *    unicodeVersion PRINTABLE STRING
+		 *  }
+		 * 
+ * @return + */ + public override Asn1Object ToAsn1Object() + { + return new DerSequence(ldsVersion, unicodeVersion); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/icao/LDSVersionInfo.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/icao/LDSVersionInfo.cs.meta new file mode 100644 index 0000000..52638f7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/icao/LDSVersionInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dd2695bd331d49741b6f8e72782cb5fd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt.meta new file mode 100644 index 0000000..7c2f950 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 2ca500689c6b3574482643f401bb884d +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/ISISMTTObjectIdentifiers.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/ISISMTTObjectIdentifiers.cs new file mode 100644 index 0000000..af60b03 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/ISISMTTObjectIdentifiers.cs @@ -0,0 +1,177 @@ +namespace Org.BouncyCastle.Asn1.IsisMtt +{ + public abstract class IsisMttObjectIdentifiers + { + public static readonly DerObjectIdentifier IdIsisMtt = new DerObjectIdentifier("1.3.36.8"); + + public static readonly DerObjectIdentifier IdIsisMttCP = new DerObjectIdentifier(IdIsisMtt + ".1"); + + /** + * The id-isismtt-cp-accredited OID indicates that the certificate is a + * qualified certificate according to Directive 1999/93/EC of the European + * Parliament and of the Council of 13 December 1999 on a Community + * Framework for Electronic Signatures, which additionally conforms the + * special requirements of the SigG and has been issued by an accredited CA. + */ + public static readonly DerObjectIdentifier IdIsisMttCPAccredited = new DerObjectIdentifier(IdIsisMttCP + ".1"); + + public static readonly DerObjectIdentifier IdIsisMttAT = new DerObjectIdentifier(IdIsisMtt + ".3"); + + /** + * Certificate extensionDate of certificate generation + * + *
+		 *		DateOfCertGenSyntax ::= GeneralizedTime
+		 * 
+ */ + public static readonly DerObjectIdentifier IdIsisMttATDateOfCertGen = new DerObjectIdentifier(IdIsisMttAT + ".1"); + + /** + * Attribute to indicate that the certificate holder may sign in the name of + * a third person. May also be used as extension in a certificate. + */ + public static readonly DerObjectIdentifier IdIsisMttATProcuration = new DerObjectIdentifier(IdIsisMttAT + ".2"); + + /** + * Attribute to indicate admissions to certain professions. May be used as + * attribute in attribute certificate or as extension in a certificate + */ + public static readonly DerObjectIdentifier IdIsisMttATAdmission = new DerObjectIdentifier(IdIsisMttAT + ".3"); + + /** + * Monetary limit for transactions. The QcEuMonetaryLimit QC statement MUST + * be used in new certificates in place of the extension/attribute + * MonetaryLimit since January 1, 2004. For the sake of backward + * compatibility with certificates already in use, SigG conforming + * components MUST support MonetaryLimit (as well as QcEuLimitValue). + */ + public static readonly DerObjectIdentifier IdIsisMttATMonetaryLimit = new DerObjectIdentifier(IdIsisMttAT + ".4"); + + /** + * A declaration of majority. May be used as attribute in attribute + * certificate or as extension in a certificate + */ + public static readonly DerObjectIdentifier IdIsisMttATDeclarationOfMajority = new DerObjectIdentifier(IdIsisMttAT + ".5"); + + /** + * + * Serial number of the smart card containing the corresponding private key + * + *
+		 *		ICCSNSyntax ::= OCTET STRING (SIZE(8..20))
+		 * 
+ */ + public static readonly DerObjectIdentifier IdIsisMttATIccsn = new DerObjectIdentifier(IdIsisMttAT + ".6"); + + /** + * + * Reference for a file of a smartcard that stores the public key of this + * certificate and that is used as �security anchor�. + * + *
+		 *		PKReferenceSyntax ::= OCTET STRING (SIZE(20))
+		 * 
+ */ + public static readonly DerObjectIdentifier IdIsisMttATPKReference = new DerObjectIdentifier(IdIsisMttAT + ".7"); + + /** + * Some other restriction regarding the usage of this certificate. May be + * used as attribute in attribute certificate or as extension in a + * certificate. + * + *
+		 *		RestrictionSyntax ::= DirectoryString (SIZE(1..1024))
+		 * 
+ * + * @see Org.BouncyCastle.Asn1.IsisMtt.X509.Restriction + */ + public static readonly DerObjectIdentifier IdIsisMttATRestriction = new DerObjectIdentifier(IdIsisMttAT + ".8"); + + /** + * + * (Single)Request extension: Clients may include this extension in a + * (single) Request to request the responder to send the certificate in the + * response message along with the status information. Besides the LDAP + * service, this extension provides another mechanism for the distribution + * of certificates, which MAY optionally be provided by certificate + * repositories. + * + *
+		 *		RetrieveIfAllowed ::= BOOLEAN
+		 * 
+ */ + public static readonly DerObjectIdentifier IdIsisMttATRetrieveIfAllowed = new DerObjectIdentifier(IdIsisMttAT + ".9"); + + /** + * SingleOCSPResponse extension: The certificate requested by the client by + * inserting the RetrieveIfAllowed extension in the request, will be + * returned in this extension. + * + * @see Org.BouncyCastle.Asn1.IsisMtt.Ocsp.RequestedCertificate + */ + public static readonly DerObjectIdentifier IdIsisMttATRequestedCertificate = new DerObjectIdentifier(IdIsisMttAT + ".10"); + + /** + * Base ObjectIdentifier for naming authorities + */ + public static readonly DerObjectIdentifier IdIsisMttATNamingAuthorities = new DerObjectIdentifier(IdIsisMttAT + ".11"); + + /** + * SingleOCSPResponse extension: Date, when certificate has been published + * in the directory and status information has become available. Currently, + * accrediting authorities enforce that SigG-conforming OCSP servers include + * this extension in the responses. + * + *
+		 *		CertInDirSince ::= GeneralizedTime
+		 * 
+ */ + public static readonly DerObjectIdentifier IdIsisMttATCertInDirSince = new DerObjectIdentifier(IdIsisMttAT + ".12"); + + /** + * Hash of a certificate in OCSP. + * + * @see Org.BouncyCastle.Asn1.IsisMtt.Ocsp.CertHash + */ + public static readonly DerObjectIdentifier IdIsisMttATCertHash = new DerObjectIdentifier(IdIsisMttAT + ".13"); + + /** + *
+		 *		NameAtBirth ::= DirectoryString(SIZE(1..64)
+		 * 
+ * + * Used in + * {@link Org.BouncyCastle.Asn1.X509.SubjectDirectoryAttributes SubjectDirectoryAttributes} + */ + public static readonly DerObjectIdentifier IdIsisMttATNameAtBirth = new DerObjectIdentifier(IdIsisMttAT + ".14"); + + /** + * Some other information of non-restrictive nature regarding the usage of + * this certificate. May be used as attribute in atribute certificate or as + * extension in a certificate. + * + *
+		 *               AdditionalInformationSyntax ::= DirectoryString (SIZE(1..2048))
+		 * 
+ * + * @see Org.BouncyCastle.Asn1.IsisMtt.X509.AdditionalInformationSyntax + */ + public static readonly DerObjectIdentifier IdIsisMttATAdditionalInformation = new DerObjectIdentifier(IdIsisMttAT + ".15"); + + /** + * Indicates that an attribute certificate exists, which limits the + * usability of this public key certificate. Whenever verifying a signature + * with the help of this certificate, the content of the corresponding + * attribute certificate should be concerned. This extension MUST be + * included in a PKC, if a corresponding attribute certificate (having the + * PKC as base certificate) contains some attribute that restricts the + * usability of the PKC too. Attribute certificates with restricting content + * MUST always be included in the signed document. + * + *
+		 *		LiabilityLimitationFlagSyntax ::= BOOLEAN
+		 * 
+ */ + public static readonly DerObjectIdentifier IdIsisMttATLiabilityLimitationFlag = new DerObjectIdentifier("0.2.262.1.10.12.0"); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/ISISMTTObjectIdentifiers.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/ISISMTTObjectIdentifiers.cs.meta new file mode 100644 index 0000000..be49b02 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/ISISMTTObjectIdentifiers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d8f395afebd80de4aa358ca98aee662f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/ocsp.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/ocsp.meta new file mode 100644 index 0000000..caf9047 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/ocsp.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 14c9e1030bdb9a548a8afa6fc35ab995 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/ocsp/CertHash.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/ocsp/CertHash.cs new file mode 100644 index 0000000..5773e1c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/ocsp/CertHash.cs @@ -0,0 +1,122 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.IsisMtt.Ocsp +{ + /** + * ISIS-MTT PROFILE: The responder may include this extension in a response to + * send the hash of the requested certificate to the responder. This hash is + * cryptographically bound to the certificate and serves as evidence that the + * certificate is known to the responder (i.e. it has been issued and is present + * in the directory). Hence, this extension is a means to provide a positive + * statement of availability as described in T8.[8]. As explained in T13.[1], + * clients may rely on this information to be able to validate signatures after + * the expiry of the corresponding certificate. Hence, clients MUST support this + * extension. If a positive statement of availability is to be delivered, this + * extension syntax and OID MUST be used. + *

+ *

+ *

+	*     CertHash ::= SEQUENCE {
+	*       hashAlgorithm AlgorithmIdentifier,
+	*       certificateHash OCTET STRING
+	*     }
+	* 
+ */ + public class CertHash + : Asn1Encodable + { + private readonly AlgorithmIdentifier hashAlgorithm; + private readonly byte[] certificateHash; + + public static CertHash GetInstance( + object obj) + { + if (obj == null || obj is CertHash) + { + return (CertHash) obj; + } + + if (obj is Asn1Sequence) + { + return new CertHash((Asn1Sequence) obj); + } + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + /** + * Constructor from Asn1Sequence. + *

+ * The sequence is of type CertHash: + *

+ *

+		*     CertHash ::= SEQUENCE {
+		*       hashAlgorithm AlgorithmIdentifier,
+		*       certificateHash OCTET STRING
+		*     }
+		* 
+ * + * @param seq The ASN.1 sequence. + */ + private CertHash( + Asn1Sequence seq) + { + if (seq.Count != 2) + throw new ArgumentException("Bad sequence size: " + seq.Count); + + this.hashAlgorithm = AlgorithmIdentifier.GetInstance(seq[0]); + this.certificateHash = DerOctetString.GetInstance(seq[1]).GetOctets(); + } + + /** + * Constructor from a given details. + * + * @param hashAlgorithm The hash algorithm identifier. + * @param certificateHash The hash of the whole DER encoding of the certificate. + */ + public CertHash( + AlgorithmIdentifier hashAlgorithm, + byte[] certificateHash) + { + if (hashAlgorithm == null) + throw new ArgumentNullException("hashAlgorithm"); + if (certificateHash == null) + throw new ArgumentNullException("certificateHash"); + + this.hashAlgorithm = hashAlgorithm; + this.certificateHash = (byte[]) certificateHash.Clone(); + } + + public AlgorithmIdentifier HashAlgorithm + { + get { return hashAlgorithm; } + } + + public byte[] CertificateHash + { + get { return (byte[]) certificateHash.Clone(); } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *

+ * Returns: + *

+ *

+		*     CertHash ::= SEQUENCE {
+		*       hashAlgorithm AlgorithmIdentifier,
+		*       certificateHash OCTET STRING
+		*     }
+		* 
+ * + * @return an Asn1Object + */ + public override Asn1Object ToAsn1Object() + { + return new DerSequence(hashAlgorithm, new DerOctetString(certificateHash)); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/ocsp/CertHash.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/ocsp/CertHash.cs.meta new file mode 100644 index 0000000..02e1bda --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/ocsp/CertHash.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3a2d47d0bb1884545a1b23c4e9bc0600 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/ocsp/RequestedCertificate.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/ocsp/RequestedCertificate.cs new file mode 100644 index 0000000..413b3bd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/ocsp/RequestedCertificate.cs @@ -0,0 +1,188 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.IsisMtt.Ocsp +{ + /** + * ISIS-MTT-Optional: The certificate requested by the client by inserting the + * RetrieveIfAllowed extension in the request, will be returned in this + * extension. + *

+ * ISIS-MTT-SigG: The signature act allows publishing certificates only then, + * when the certificate owner gives his isExplicit permission. Accordingly, there + * may be �nondownloadable� certificates, about which the responder must provide + * status information, but MUST NOT include them in the response. Clients may + * get therefore the following three kind of answers on a single request + * including the RetrieveIfAllowed extension: + *

    + *
  • a) the responder supports the extension and is allowed to publish the + * certificate: RequestedCertificate returned including the requested + * certificate
  • + *
  • b) the responder supports the extension but is NOT allowed to publish + * the certificate: RequestedCertificate returned including an empty OCTET + * STRING
  • + *
  • c) the responder does not support the extension: RequestedCertificate is + * not included in the response
  • + *
+ * Clients requesting RetrieveIfAllowed MUST be able to handle these cases. If + * any of the OCTET STRING options is used, it MUST contain the DER encoding of + * the requested certificate. + *

+ *

+	*            RequestedCertificate ::= CHOICE {
+	*              Certificate Certificate,
+	*              publicKeyCertificate [0] EXPLICIT OCTET STRING,
+	*              attributeCertificate [1] EXPLICIT OCTET STRING
+	*            }
+	* 
+ */ + public class RequestedCertificate + : Asn1Encodable, IAsn1Choice + { + public enum Choice + { + Certificate = -1, + PublicKeyCertificate = 0, + AttributeCertificate = 1 + } + + private readonly X509CertificateStructure cert; + private readonly byte[] publicKeyCert; + private readonly byte[] attributeCert; + + public static RequestedCertificate GetInstance( + object obj) + { + if (obj == null || obj is RequestedCertificate) + { + return (RequestedCertificate) obj; + } + + if (obj is Asn1Sequence) + { + return new RequestedCertificate(X509CertificateStructure.GetInstance(obj)); + } + + if (obj is Asn1TaggedObject) + { + return new RequestedCertificate((Asn1TaggedObject) obj); + } + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + public static RequestedCertificate GetInstance( + Asn1TaggedObject obj, + bool isExplicit) + { + if (!isExplicit) + throw new ArgumentException("choice item must be explicitly tagged"); + + return GetInstance(obj.GetObject()); + } + + private RequestedCertificate( + Asn1TaggedObject tagged) + { + switch ((Choice) tagged.TagNo) + { + case Choice.AttributeCertificate: + this.attributeCert = Asn1OctetString.GetInstance(tagged, true).GetOctets(); + break; + case Choice.PublicKeyCertificate: + this.publicKeyCert = Asn1OctetString.GetInstance(tagged, true).GetOctets(); + break; + default: + throw new ArgumentException("unknown tag number: " + tagged.TagNo); + } + } + + /** + * Constructor from a given details. + *

+ * Only one parameter can be given. All other must be null. + * + * @param certificate Given as Certificate + */ + public RequestedCertificate( + X509CertificateStructure certificate) + { + this.cert = certificate; + } + + public RequestedCertificate( + Choice type, + byte[] certificateOctets) + : this(new DerTaggedObject((int) type, new DerOctetString(certificateOctets))) + { + } + + public Choice Type + { + get + { + if (cert != null) + return Choice.Certificate; + + if (publicKeyCert != null) + return Choice.PublicKeyCertificate; + + return Choice.AttributeCertificate; + } + } + + public byte[] GetCertificateBytes() + { + if (cert != null) + { + try + { + return cert.GetEncoded(); + } + catch (IOException e) + { + throw new InvalidOperationException("can't decode certificate: " + e); + } + } + + if (publicKeyCert != null) + return publicKeyCert; + + return attributeCert; + } + + + /** + * Produce an object suitable for an Asn1OutputStream. + *

+ * Returns: + *

+ *

+		*            RequestedCertificate ::= CHOICE {
+		*              Certificate Certificate,
+		*              publicKeyCertificate [0] EXPLICIT OCTET STRING,
+		*              attributeCertificate [1] EXPLICIT OCTET STRING
+		*            }
+		* 
+ * + * @return an Asn1Object + */ + public override Asn1Object ToAsn1Object() + { + if (publicKeyCert != null) + { + return new DerTaggedObject(0, new DerOctetString(publicKeyCert)); + } + + if (attributeCert != null) + { + return new DerTaggedObject(1, new DerOctetString(attributeCert)); + } + + return cert.ToAsn1Object(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/ocsp/RequestedCertificate.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/ocsp/RequestedCertificate.cs.meta new file mode 100644 index 0000000..7abb982 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/ocsp/RequestedCertificate.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8c1736620abd380499b7c2cd8952b202 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509.meta new file mode 100644 index 0000000..8d97e30 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e151a10801b9606418d149aa52de44f9 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/AdditionalInformationSyntax.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/AdditionalInformationSyntax.cs new file mode 100644 index 0000000..53a8e98 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/AdditionalInformationSyntax.cs @@ -0,0 +1,71 @@ +using System; + +using Org.BouncyCastle.Asn1.X500; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.IsisMtt.X509 +{ + /** + * Some other information of non-restrictive nature regarding the usage of this + * certificate. + * + *
+	*    AdditionalInformationSyntax ::= DirectoryString (SIZE(1..2048))
+	* 
+ */ + public class AdditionalInformationSyntax + : Asn1Encodable + { + private readonly DirectoryString information; + + public static AdditionalInformationSyntax GetInstance( + object obj) + { + if (obj is AdditionalInformationSyntax) + return (AdditionalInformationSyntax) obj; + + if (obj is IAsn1String) + return new AdditionalInformationSyntax(DirectoryString.GetInstance(obj)); + + throw new ArgumentException("Unknown object in GetInstance: " + Platform.GetTypeName(obj), "obj"); + } + + private AdditionalInformationSyntax( + DirectoryString information) + { + this.information = information; + } + + /** + * Constructor from a given details. + * + * @param information The describtion of the information. + */ + public AdditionalInformationSyntax( + string information) + { + this.information = new DirectoryString(information); + } + + public virtual DirectoryString Information + { + get { return information; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *

+ * Returns: + *

+ *

+		*   AdditionalInformationSyntax ::= DirectoryString (SIZE(1..2048))
+		* 
+ * + * @return an Asn1Object + */ + public override Asn1Object ToAsn1Object() + { + return information.ToAsn1Object(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/AdditionalInformationSyntax.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/AdditionalInformationSyntax.cs.meta new file mode 100644 index 0000000..fbcfec4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/AdditionalInformationSyntax.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 64bdb2cf033dc494fb1a43e065ec8de1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/AdmissionSyntax.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/AdmissionSyntax.cs new file mode 100644 index 0000000..a45075e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/AdmissionSyntax.cs @@ -0,0 +1,275 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.IsisMtt.X509 +{ + /** + * Attribute to indicate admissions to certain professions. + *

+ *

+    *     AdmissionSyntax ::= SEQUENCE
+    *     {
+    *       admissionAuthority GeneralName OPTIONAL,
+    *       contentsOfAdmissions SEQUENCE OF Admissions
+    *     }
+    * 

+ * Admissions ::= SEQUENCE + * { + * admissionAuthority [0] EXPLICIT GeneralName OPTIONAL + * namingAuthority [1] EXPLICIT NamingAuthority OPTIONAL + * professionInfos SEQUENCE OF ProfessionInfo + * } + *

+ * NamingAuthority ::= SEQUENCE + * { + * namingAuthorityId OBJECT IDENTIFIER OPTIONAL, + * namingAuthorityUrl IA5String OPTIONAL, + * namingAuthorityText DirectoryString(SIZE(1..128)) OPTIONAL + * } + *

+ * ProfessionInfo ::= SEQUENCE + * { + * namingAuthority [0] EXPLICIT NamingAuthority OPTIONAL, + * professionItems SEQUENCE OF DirectoryString (SIZE(1..128)), + * professionOIDs SEQUENCE OF OBJECT IDENTIFIER OPTIONAL, + * registrationNumber PrintableString(SIZE(1..128)) OPTIONAL, + * addProfessionInfo OCTET STRING OPTIONAL + * } + *

+ *

+ *

+ * ISIS-MTT PROFILE: The relatively complex structure of AdmissionSyntax + * supports the following concepts and requirements: + *

    + *
  • External institutions (e.g. professional associations, chambers, unions, + * administrative bodies, companies, etc.), which are responsible for granting + * and verifying professional admissions, are indicated by means of the data + * field admissionAuthority. An admission authority is indicated by a + * GeneralName object. Here an X.501 directory name (distinguished name) can be + * indicated in the field directoryName, a URL address can be indicated in the + * field uniformResourceIdentifier, and an object identifier can be indicated in + * the field registeredId.
  • + *
  • The names of authorities which are responsible for the administration of + * title registers are indicated in the data field namingAuthority. The name of + * the authority can be identified by an object identifier in the field + * namingAuthorityId, by means of a text string in the field + * namingAuthorityText, by means of a URL address in the field + * namingAuthorityUrl, or by a combination of them. For example, the text string + * can contain the name of the authority, the country and the name of the title + * register. The URL-option refers to a web page which contains lists with + * officially registered professions (text and possibly OID) as well as + * further information on these professions. Object identifiers for the + * component namingAuthorityId are grouped under the OID-branch + * id-isis-at-namingAuthorities and must be applied for.
  • + *
  • See http://www.teletrust.de/anwend.asp?Id=30200&Sprache=E_&HomePG=0 + * for an application form and http://www.teletrust.de/links.asp?id=30220,11 + * for an overview of registered naming authorities.
  • + *
  • By means of the data type ProfessionInfo certain professions, + * specializations, disciplines, fields of activity, etc. are identified. A + * profession is represented by one or more text strings, resp. profession OIDs + * in the fields professionItems and professionOIDs and by a registration number + * in the field registrationNumber. An indication in text form must always be + * present, whereas the other indications are optional. The component + * addProfessionInfo may contain additional applicationspecific information in + * DER-encoded form.
  • + *
+ *

+ * By means of different namingAuthority-OIDs or profession OIDs hierarchies of + * professions, specializations, disciplines, fields of activity, etc. can be + * expressed. The issuing admission authority should always be indicated (field + * admissionAuthority), whenever a registration number is presented. Still, + * information on admissions can be given without indicating an admission or a + * naming authority by the exclusive use of the component professionItems. In + * this case the certification authority is responsible for the verification of + * the admission information. + *

+ *

+ *

+ * This attribute is single-valued. Still, several admissions can be captured in + * the sequence structure of the component contentsOfAdmissions of + * AdmissionSyntax or in the component professionInfos of Admissions. The + * component admissionAuthority of AdmissionSyntax serves as default value for + * the component admissionAuthority of Admissions. Within the latter component + * the default value can be overwritten, in case that another authority is + * responsible. The component namingAuthority of Admissions serves as a default + * value for the component namingAuthority of ProfessionInfo. Within the latter + * component the default value can be overwritten, in case that another naming + * authority needs to be recorded. + *

+ * The length of the string objects is limited to 128 characters. It is + * recommended to indicate a namingAuthorityURL in all issued attribute + * certificates. If a namingAuthorityURL is indicated, the field professionItems + * of ProfessionInfo should contain only registered titles. If the field + * professionOIDs exists, it has to contain the OIDs of the professions listed + * in professionItems in the same order. In general, the field professionInfos + * should contain only one entry, unless the admissions that are to be listed + * are logically connected (e.g. they have been issued under the same admission + * number). + * + * @see Org.BouncyCastle.Asn1.IsisMtt.X509.Admissions + * @see Org.BouncyCastle.Asn1.IsisMtt.X509.ProfessionInfo + * @see Org.BouncyCastle.Asn1.IsisMtt.X509.NamingAuthority + */ + public class AdmissionSyntax + : Asn1Encodable + { + private readonly GeneralName admissionAuthority; + private readonly Asn1Sequence contentsOfAdmissions; + + public static AdmissionSyntax GetInstance( + object obj) + { + if (obj == null || obj is AdmissionSyntax) + { + return (AdmissionSyntax)obj; + } + + if (obj is Asn1Sequence) + { + return new AdmissionSyntax((Asn1Sequence)obj); + } + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + /** + * Constructor from Asn1Sequence. + *

+ * The sequence is of type ProcurationSyntax: + *

+ *

+        *     AdmissionSyntax ::= SEQUENCE
+        *     {
+        *       admissionAuthority GeneralName OPTIONAL,
+        *       contentsOfAdmissions SEQUENCE OF Admissions
+        *     }
+        * 

+ * Admissions ::= SEQUENCE + * { + * admissionAuthority [0] EXPLICIT GeneralName OPTIONAL + * namingAuthority [1] EXPLICIT NamingAuthority OPTIONAL + * professionInfos SEQUENCE OF ProfessionInfo + * } + *

+ * NamingAuthority ::= SEQUENCE + * { + * namingAuthorityId OBJECT IDENTIFIER OPTIONAL, + * namingAuthorityUrl IA5String OPTIONAL, + * namingAuthorityText DirectoryString(SIZE(1..128)) OPTIONAL + * } + *

+ * ProfessionInfo ::= SEQUENCE + * { + * namingAuthority [0] EXPLICIT NamingAuthority OPTIONAL, + * professionItems SEQUENCE OF DirectoryString (SIZE(1..128)), + * professionOIDs SEQUENCE OF OBJECT IDENTIFIER OPTIONAL, + * registrationNumber PrintableString(SIZE(1..128)) OPTIONAL, + * addProfessionInfo OCTET STRING OPTIONAL + * } + *

+ * + * @param seq The ASN.1 sequence. + */ + private AdmissionSyntax( + Asn1Sequence seq) + { + switch (seq.Count) + { + case 1: + this.contentsOfAdmissions = DerSequence.GetInstance(seq[0]); + break; + case 2: + admissionAuthority = GeneralName.GetInstance(seq[0]); + contentsOfAdmissions = DerSequence.GetInstance(seq[1]); + break; + default: + throw new ArgumentException("Bad sequence size: " + seq.Count); + } + } + + /** + * Constructor from given details. + * + * @param admissionAuthority The admission authority. + * @param contentsOfAdmissions The admissions. + */ + public AdmissionSyntax( + GeneralName admissionAuthority, + Asn1Sequence contentsOfAdmissions) + { + this.admissionAuthority = admissionAuthority; + this.contentsOfAdmissions = contentsOfAdmissions; + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *

+ * Returns: + *

+ *

+        *     AdmissionSyntax ::= SEQUENCE
+        *     {
+        *       admissionAuthority GeneralName OPTIONAL,
+        *       contentsOfAdmissions SEQUENCE OF Admissions
+        *     }
+        * 

+ * Admissions ::= SEQUENCE + * { + * admissionAuthority [0] EXPLICIT GeneralName OPTIONAL + * namingAuthority [1] EXPLICIT NamingAuthority OPTIONAL + * professionInfos SEQUENCE OF ProfessionInfo + * } + *

+ * NamingAuthority ::= SEQUENCE + * { + * namingAuthorityId OBJECT IDENTIFIER OPTIONAL, + * namingAuthorityUrl IA5String OPTIONAL, + * namingAuthorityText DirectoryString(SIZE(1..128)) OPTIONAL + * } + *

+ * ProfessionInfo ::= SEQUENCE + * { + * namingAuthority [0] EXPLICIT NamingAuthority OPTIONAL, + * professionItems SEQUENCE OF DirectoryString (SIZE(1..128)), + * professionOIDs SEQUENCE OF OBJECT IDENTIFIER OPTIONAL, + * registrationNumber PrintableString(SIZE(1..128)) OPTIONAL, + * addProfessionInfo OCTET STRING OPTIONAL + * } + *

+ * + * @return an Asn1Object + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + v.AddOptional(admissionAuthority); + v.Add(contentsOfAdmissions); + return new DerSequence(v); + } + + /** + * @return Returns the admissionAuthority if present, null otherwise. + */ + public virtual GeneralName AdmissionAuthority + { + get { return admissionAuthority; } + } + + /** + * @return Returns the contentsOfAdmissions. + */ + public virtual Admissions[] GetContentsOfAdmissions() + { + Admissions[] result = new Admissions[contentsOfAdmissions.Count]; + + for (int i = 0; i < contentsOfAdmissions.Count; ++i) + { + result[i] = Admissions.GetInstance(contentsOfAdmissions[i]); + } + + return result; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/AdmissionSyntax.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/AdmissionSyntax.cs.meta new file mode 100644 index 0000000..754129b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/AdmissionSyntax.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c03d854379061e4408400b09e23b9d20 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/Admissions.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/Admissions.cs new file mode 100644 index 0000000..2aa6764 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/Admissions.cs @@ -0,0 +1,177 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.IsisMtt.X509 +{ + /** + * An Admissions structure. + *

+ *

+	*            Admissions ::= SEQUENCE
+	*            {
+	*              admissionAuthority [0] EXPLICIT GeneralName OPTIONAL
+	*              namingAuthority [1] EXPLICIT NamingAuthority OPTIONAL
+	*              professionInfos SEQUENCE OF ProfessionInfo
+	*            }
+	* 

+ *

+ * + * @see Org.BouncyCastle.Asn1.IsisMtt.X509.AdmissionSyntax + * @see Org.BouncyCastle.Asn1.IsisMtt.X509.ProfessionInfo + * @see Org.BouncyCastle.Asn1.IsisMtt.X509.NamingAuthority + */ + public class Admissions + : Asn1Encodable + { + private readonly GeneralName admissionAuthority; + private readonly NamingAuthority namingAuthority; + private readonly Asn1Sequence professionInfos; + + public static Admissions GetInstance( + object obj) + { + if (obj == null || obj is Admissions) + { + return (Admissions) obj; + } + + if (obj is Asn1Sequence) + { + return new Admissions((Asn1Sequence) obj); + } + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + /** + * Constructor from Asn1Sequence. + *

+ * The sequence is of type ProcurationSyntax: + *

+ *

+		*            Admissions ::= SEQUENCE
+		*            {
+		*              admissionAuthority [0] EXPLICIT GeneralName OPTIONAL
+		*              namingAuthority [1] EXPLICIT NamingAuthority OPTIONAL
+		*              professionInfos SEQUENCE OF ProfessionInfo
+		*            }
+		* 
+ * + * @param seq The ASN.1 sequence. + */ + private Admissions( + Asn1Sequence seq) + { + if (seq.Count > 3) + throw new ArgumentException("Bad sequence size: " + seq.Count); + + IEnumerator e = seq.GetEnumerator(); + + e.MoveNext(); + Asn1Encodable o = (Asn1Encodable) e.Current; + if (o is Asn1TaggedObject) + { + switch (((Asn1TaggedObject)o).TagNo) + { + case 0: + admissionAuthority = GeneralName.GetInstance((Asn1TaggedObject)o, true); + break; + case 1: + namingAuthority = NamingAuthority.GetInstance((Asn1TaggedObject)o, true); + break; + default: + throw new ArgumentException("Bad tag number: " + ((Asn1TaggedObject)o).TagNo); + } + e.MoveNext(); + o = (Asn1Encodable) e.Current; + } + if (o is Asn1TaggedObject) + { + switch (((Asn1TaggedObject)o).TagNo) + { + case 1: + namingAuthority = NamingAuthority.GetInstance((Asn1TaggedObject)o, true); + break; + default: + throw new ArgumentException("Bad tag number: " + ((Asn1TaggedObject)o).TagNo); + } + e.MoveNext(); + o = (Asn1Encodable) e.Current; + } + professionInfos = Asn1Sequence.GetInstance(o); + if (e.MoveNext()) + { + throw new ArgumentException("Bad object encountered: " + Platform.GetTypeName(e.Current)); + } + } + + /** + * Constructor from a given details. + *

+ * Parameter professionInfos is mandatory. + * + * @param admissionAuthority The admission authority. + * @param namingAuthority The naming authority. + * @param professionInfos The profession infos. + */ + public Admissions( + GeneralName admissionAuthority, + NamingAuthority namingAuthority, + ProfessionInfo[] professionInfos) + { + this.admissionAuthority = admissionAuthority; + this.namingAuthority = namingAuthority; + this.professionInfos = new DerSequence(professionInfos); + } + + public virtual GeneralName AdmissionAuthority + { + get { return admissionAuthority; } + } + + public virtual NamingAuthority NamingAuthority + { + get { return namingAuthority; } + } + + public ProfessionInfo[] GetProfessionInfos() + { + ProfessionInfo[] infos = new ProfessionInfo[professionInfos.Count]; + int count = 0; + foreach (Asn1Encodable ae in professionInfos) + { + infos[count++] = ProfessionInfo.GetInstance(ae); + } + return infos; + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *

+ * Returns: + *

+ *

+		*       Admissions ::= SEQUENCE
+		*       {
+		*         admissionAuthority [0] EXPLICIT GeneralName OPTIONAL
+		*         namingAuthority [1] EXPLICIT NamingAuthority OPTIONAL
+		*         professionInfos SEQUENCE OF ProfessionInfo
+		*       }
+		* 

+ *

+ * + * @return an Asn1Object + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + v.AddOptionalTagged(true, 0, admissionAuthority); + v.AddOptionalTagged(true, 1, namingAuthority); + v.Add(professionInfos); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/Admissions.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/Admissions.cs.meta new file mode 100644 index 0000000..b4824f0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/Admissions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bcd7db6a2a159084394cea9da01b44ba +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/DeclarationOfMajority.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/DeclarationOfMajority.cs new file mode 100644 index 0000000..b82c937 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/DeclarationOfMajority.cs @@ -0,0 +1,172 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.IsisMtt.X509 +{ + /** + * A declaration of majority. + *

+ *

+	*           DeclarationOfMajoritySyntax ::= CHOICE
+	*           {
+	*             notYoungerThan [0] IMPLICIT INTEGER,
+	*             fullAgeAtCountry [1] IMPLICIT SEQUENCE
+	*             {
+	*               fullAge BOOLEAN DEFAULT TRUE,
+	*               country PrintableString (SIZE(2))
+	*             }
+	*             dateOfBirth [2] IMPLICIT GeneralizedTime
+	*           }
+	* 
+ *

+ * fullAgeAtCountry indicates the majority of the owner with respect to the laws + * of a specific country. + */ + public class DeclarationOfMajority + : Asn1Encodable, IAsn1Choice + { + public enum Choice + { + NotYoungerThan = 0, + FullAgeAtCountry = 1, + DateOfBirth = 2 + }; + + private readonly Asn1TaggedObject declaration; + + public DeclarationOfMajority( + int notYoungerThan) + { + declaration = new DerTaggedObject(false, 0, new DerInteger(notYoungerThan)); + } + + public DeclarationOfMajority( + bool fullAge, + string country) + { + if (country.Length > 2) + throw new ArgumentException("country can only be 2 characters"); + + DerPrintableString countryString = new DerPrintableString(country, true); + + DerSequence seq; + if (fullAge) + { + seq = new DerSequence(countryString); + } + else + { + seq = new DerSequence(DerBoolean.False, countryString); + } + + this.declaration = new DerTaggedObject(false, 1, seq); + } + + public DeclarationOfMajority( + DerGeneralizedTime dateOfBirth) + { + this.declaration = new DerTaggedObject(false, 2, dateOfBirth); + } + + public static DeclarationOfMajority GetInstance( + object obj) + { + if (obj == null || obj is DeclarationOfMajority) + { + return (DeclarationOfMajority) obj; + } + + if (obj is Asn1TaggedObject) + { + return new DeclarationOfMajority((Asn1TaggedObject) obj); + } + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + private DeclarationOfMajority( + Asn1TaggedObject o) + { + if (o.TagNo > 2) + throw new ArgumentException("Bad tag number: " + o.TagNo); + + this.declaration = o; + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *

+ * Returns: + *

+ *

+		*           DeclarationOfMajoritySyntax ::= CHOICE
+		*           {
+		*             notYoungerThan [0] IMPLICIT INTEGER,
+		*             fullAgeAtCountry [1] IMPLICIT SEQUENCE
+		*             {
+		*               fullAge BOOLEAN DEFAULT TRUE,
+		*               country PrintableString (SIZE(2))
+		*             }
+		*             dateOfBirth [2] IMPLICIT GeneralizedTime
+		*           }
+		* 
+ * + * @return an Asn1Object + */ + public override Asn1Object ToAsn1Object() + { + return declaration; + } + + public Choice Type + { + get { return (Choice) declaration.TagNo; } + } + + /** + * @return notYoungerThan if that's what we are, -1 otherwise + */ + public virtual int NotYoungerThan + { + get + { + switch ((Choice) declaration.TagNo) + { + case Choice.NotYoungerThan: + return DerInteger.GetInstance(declaration, false).IntValueExact; + default: + return -1; + } + } + } + + public virtual Asn1Sequence FullAgeAtCountry + { + get + { + switch ((Choice) declaration.TagNo) + { + case Choice.FullAgeAtCountry: + return Asn1Sequence.GetInstance(declaration, false); + default: + return null; + } + } + } + + public virtual DerGeneralizedTime DateOfBirth + { + get + { + switch ((Choice) declaration.TagNo) + { + case Choice.DateOfBirth: + return DerGeneralizedTime.GetInstance(declaration, false); + default: + return null; + } + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/DeclarationOfMajority.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/DeclarationOfMajority.cs.meta new file mode 100644 index 0000000..ce92e2e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/DeclarationOfMajority.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a61ec17aa0ccb174daa96b88a06066ec +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/MonetaryLimit.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/MonetaryLimit.cs new file mode 100644 index 0000000..b792fff --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/MonetaryLimit.cs @@ -0,0 +1,122 @@ +using System; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.IsisMtt.X509 +{ + /** + * Monetary limit for transactions. The QcEuMonetaryLimit QC statement MUST be + * used in new certificates in place of the extension/attribute MonetaryLimit + * since January 1, 2004. For the sake of backward compatibility with + * certificates already in use, components SHOULD support MonetaryLimit (as well + * as QcEuLimitValue). + *

+ * Indicates a monetary limit within which the certificate holder is authorized + * to act. (This value DOES NOT express a limit on the liability of the + * certification authority). + *

+ *

+	*    MonetaryLimitSyntax ::= SEQUENCE
+	*    {
+	*      currency PrintableString (SIZE(3)),
+	*      amount INTEGER,
+	*      exponent INTEGER
+	*    }
+	* 
+ *

+ * currency must be the ISO code. + *

+ * value = amount�10*exponent + */ + public class MonetaryLimit + : Asn1Encodable + { + private readonly DerPrintableString currency; + private readonly DerInteger amount; + private readonly DerInteger exponent; + + public static MonetaryLimit GetInstance( + object obj) + { + if (obj == null || obj is MonetaryLimit) + { + return (MonetaryLimit) obj; + } + + if (obj is Asn1Sequence) + { + return new MonetaryLimit(Asn1Sequence.GetInstance(obj)); + } + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + private MonetaryLimit( + Asn1Sequence seq) + { + if (seq.Count != 3) + throw new ArgumentException("Bad sequence size: " + seq.Count); + + currency = DerPrintableString.GetInstance(seq[0]); + amount = DerInteger.GetInstance(seq[1]); + exponent = DerInteger.GetInstance(seq[2]); + } + + /** + * Constructor from a given details. + *

+ *

+ * value = amount�10^exponent + * + * @param currency The currency. Must be the ISO code. + * @param amount The amount + * @param exponent The exponent + */ + public MonetaryLimit( + string currency, + int amount, + int exponent) + { + this.currency = new DerPrintableString(currency, true); + this.amount = new DerInteger(amount); + this.exponent = new DerInteger(exponent); + } + + public virtual string Currency + { + get { return currency.GetString(); } + } + + public virtual BigInteger Amount + { + get { return amount.Value; } + } + + public virtual BigInteger Exponent + { + get { return exponent.Value; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *

+ * Returns: + *

+ *

+		*    MonetaryLimitSyntax ::= SEQUENCE
+		*    {
+		*      currency PrintableString (SIZE(3)),
+		*      amount INTEGER,
+		*      exponent INTEGER
+		*    }
+		* 
+ * + * @return an Asn1Object + */ + public override Asn1Object ToAsn1Object() + { + return new DerSequence(currency, amount, exponent); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/MonetaryLimit.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/MonetaryLimit.cs.meta new file mode 100644 index 0000000..fc1658a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/MonetaryLimit.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 642aaff2769805949a9869186be102cb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/NamingAuthority.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/NamingAuthority.cs new file mode 100644 index 0000000..543dcec --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/NamingAuthority.cs @@ -0,0 +1,211 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1.X500; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.IsisMtt.X509 +{ + /** + * Names of authorities which are responsible for the administration of title + * registers. + * + *
+	*             NamingAuthority ::= SEQUENCE 
+	*             {
+	*               namingAuthorityID OBJECT IDENTIFIER OPTIONAL,
+	*               namingAuthorityUrl IA5String OPTIONAL,
+	*               namingAuthorityText DirectoryString(SIZE(1..128)) OPTIONAL
+	*             }
+	* 
+ * @see Org.BouncyCastle.Asn1.IsisMtt.X509.AdmissionSyntax + * + */ + public class NamingAuthority + : Asn1Encodable + { + /** + * Profession OIDs should always be defined under the OID branch of the + * responsible naming authority. At the time of this writing, the work group + * �Recht, Wirtschaft, Steuern� (�Law, Economy, Taxes�) is registered as the + * first naming authority under the OID id-isismtt-at-namingAuthorities. + */ + public static readonly DerObjectIdentifier IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + = new DerObjectIdentifier(IsisMttObjectIdentifiers.IdIsisMttATNamingAuthorities + ".1"); + + private readonly DerObjectIdentifier namingAuthorityID; + private readonly string namingAuthorityUrl; + private readonly DirectoryString namingAuthorityText; + + public static NamingAuthority GetInstance( + object obj) + { + if (obj == null || obj is NamingAuthority) + { + return (NamingAuthority) obj; + } + + if (obj is Asn1Sequence) + { + return new NamingAuthority((Asn1Sequence) obj); + } + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + public static NamingAuthority GetInstance( + Asn1TaggedObject obj, + bool isExplicit) + { + return GetInstance(Asn1Sequence.GetInstance(obj, isExplicit)); + } + + /** + * Constructor from Asn1Sequence. + *

+ *

+ *

+		*             NamingAuthority ::= SEQUENCE
+		*             {
+		*               namingAuthorityID OBJECT IDENTIFIER OPTIONAL,
+		*               namingAuthorityUrl IA5String OPTIONAL,
+		*               namingAuthorityText DirectoryString(SIZE(1..128)) OPTIONAL
+		*             }
+		* 
+ * + * @param seq The ASN.1 sequence. + */ + private NamingAuthority( + Asn1Sequence seq) + { + if (seq.Count > 3) + throw new ArgumentException("Bad sequence size: " + seq.Count); + + IEnumerator e = seq.GetEnumerator(); + + if (e.MoveNext()) + { + Asn1Encodable o = (Asn1Encodable) e.Current; + if (o is DerObjectIdentifier) + { + namingAuthorityID = (DerObjectIdentifier) o; + } + else if (o is DerIA5String) + { + namingAuthorityUrl = DerIA5String.GetInstance(o).GetString(); + } + else if (o is IAsn1String) + { + namingAuthorityText = DirectoryString.GetInstance(o); + } + else + { + throw new ArgumentException("Bad object encountered: " + Platform.GetTypeName(o)); + } + } + + if (e.MoveNext()) + { + Asn1Encodable o = (Asn1Encodable) e.Current; + if (o is DerIA5String) + { + namingAuthorityUrl = DerIA5String.GetInstance(o).GetString(); + } + else if (o is IAsn1String) + { + namingAuthorityText = DirectoryString.GetInstance(o); + } + else + { + throw new ArgumentException("Bad object encountered: " + Platform.GetTypeName(o)); + } + } + + if (e.MoveNext()) + { + Asn1Encodable o = (Asn1Encodable) e.Current; + if (o is IAsn1String) + { + namingAuthorityText = DirectoryString.GetInstance(o); + } + else + { + throw new ArgumentException("Bad object encountered: " + Platform.GetTypeName(o)); + } + } + } + + /** + * @return Returns the namingAuthorityID. + */ + public virtual DerObjectIdentifier NamingAuthorityID + { + get { return namingAuthorityID; } + } + + /** + * @return Returns the namingAuthorityText. + */ + public virtual DirectoryString NamingAuthorityText + { + get { return namingAuthorityText; } + } + + /** + * @return Returns the namingAuthorityUrl. + */ + public virtual string NamingAuthorityUrl + { + get { return namingAuthorityUrl; } + } + + /** + * Constructor from given details. + *

+ * All parameters can be combined. + * + * @param namingAuthorityID ObjectIdentifier for naming authority. + * @param namingAuthorityUrl URL for naming authority. + * @param namingAuthorityText Textual representation of naming authority. + */ + public NamingAuthority( + DerObjectIdentifier namingAuthorityID, + string namingAuthorityUrl, + DirectoryString namingAuthorityText) + { + this.namingAuthorityID = namingAuthorityID; + this.namingAuthorityUrl = namingAuthorityUrl; + this.namingAuthorityText = namingAuthorityText; + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *

+ * Returns: + *

+ *

+		*             NamingAuthority ::= SEQUENCE
+		*             {
+		*               namingAuthorityID OBJECT IDENTIFIER OPTIONAL,
+		*               namingAuthorityUrl IA5String OPTIONAL,
+		*               namingAuthorityText DirectoryString(SIZE(1..128)) OPTIONAL
+		*             }
+		* 
+ * + * @return an Asn1Object + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + v.AddOptional(namingAuthorityID); + + if (namingAuthorityUrl != null) + { + v.Add(new DerIA5String(namingAuthorityUrl, true)); + } + + v.AddOptional(namingAuthorityText); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/NamingAuthority.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/NamingAuthority.cs.meta new file mode 100644 index 0000000..c4ede1a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/NamingAuthority.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7d6013d25c45b6044b5270a581decd5d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/ProcurationSyntax.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/ProcurationSyntax.cs new file mode 100644 index 0000000..60d3a88 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/ProcurationSyntax.cs @@ -0,0 +1,233 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1.X500; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.IsisMtt.X509 +{ + /** + * Attribute to indicate that the certificate holder may sign in the name of a + * third person. + *

+ * ISIS-MTT PROFILE: The corresponding ProcurationSyntax contains either the + * name of the person who is represented (subcomponent thirdPerson) or a + * reference to his/her base certificate (in the component signingFor, + * subcomponent certRef), furthermore the optional components country and + * typeSubstitution to indicate the country whose laws apply, and respectively + * the type of procuration (e.g. manager, procuration, custody). + *

+ *

+ * ISIS-MTT PROFILE: The GeneralName MUST be of type directoryName and MAY only + * contain: - RFC3039 attributes, except pseudonym (countryName, commonName, + * surname, givenName, serialNumber, organizationName, organizationalUnitName, + * stateOrProvincename, localityName, postalAddress) and - SubjectDirectoryName + * attributes (title, dateOfBirth, placeOfBirth, gender, countryOfCitizenship, + * countryOfResidence and NameAtBirth). + *

+ *
+	*               ProcurationSyntax ::= SEQUENCE {
+	*                 country [1] EXPLICIT PrintableString(SIZE(2)) OPTIONAL,
+	*                 typeOfSubstitution [2] EXPLICIT DirectoryString (SIZE(1..128)) OPTIONAL,
+	*                 signingFor [3] EXPLICIT SigningFor 
+	*               }
+	*               
+	*               SigningFor ::= CHOICE 
+	*               { 
+	*                 thirdPerson GeneralName,
+	*                 certRef IssuerSerial 
+	*               }
+	* 
+ * + */ + public class ProcurationSyntax + : Asn1Encodable + { + private readonly string country; + private readonly DirectoryString typeOfSubstitution; + private readonly GeneralName thirdPerson; + private readonly IssuerSerial certRef; + + public static ProcurationSyntax GetInstance( + object obj) + { + if (obj == null || obj is ProcurationSyntax) + { + return (ProcurationSyntax) obj; + } + + if (obj is Asn1Sequence) + { + return new ProcurationSyntax((Asn1Sequence) obj); + } + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + /** + * Constructor from Asn1Sequence. + *

+ * The sequence is of type ProcurationSyntax: + *

+ *

+		*               ProcurationSyntax ::= SEQUENCE {
+		*                 country [1] EXPLICIT PrintableString(SIZE(2)) OPTIONAL,
+		*                 typeOfSubstitution [2] EXPLICIT DirectoryString (SIZE(1..128)) OPTIONAL,
+		*                 signingFor [3] EXPLICIT SigningFor
+		*               }
+		* 

+ * SigningFor ::= CHOICE + * { + * thirdPerson GeneralName, + * certRef IssuerSerial + * } + *

+ * + * @param seq The ASN.1 sequence. + */ + private ProcurationSyntax( + Asn1Sequence seq) + { + if (seq.Count < 1 || seq.Count > 3) + throw new ArgumentException("Bad sequence size: " + seq.Count); + + IEnumerator e = seq.GetEnumerator(); + + while (e.MoveNext()) + { + Asn1TaggedObject o = Asn1TaggedObject.GetInstance(e.Current); + switch (o.TagNo) + { + case 1: + country = DerPrintableString.GetInstance(o, true).GetString(); + break; + case 2: + typeOfSubstitution = DirectoryString.GetInstance(o, true); + break; + case 3: + Asn1Object signingFor = o.GetObject(); + if (signingFor is Asn1TaggedObject) + { + thirdPerson = GeneralName.GetInstance(signingFor); + } + else + { + certRef = IssuerSerial.GetInstance(signingFor); + } + break; + default: + throw new ArgumentException("Bad tag number: " + o.TagNo); + } + } + } + + /** + * Constructor from a given details. + *

+ *

+ * Either generalName or certRef MUST be + * null. + * + * @param country The country code whose laws apply. + * @param typeOfSubstitution The type of procuration. + * @param certRef Reference to certificate of the person who is represented. + */ + public ProcurationSyntax( + string country, + DirectoryString typeOfSubstitution, + IssuerSerial certRef) + { + this.country = country; + this.typeOfSubstitution = typeOfSubstitution; + this.thirdPerson = null; + this.certRef = certRef; + } + + /** + * Constructor from a given details. + *

+ *

+ * Either generalName or certRef MUST be + * null. + * + * @param country The country code whose laws apply. + * @param typeOfSubstitution The type of procuration. + * @param thirdPerson The GeneralName of the person who is represented. + */ + public ProcurationSyntax( + string country, + DirectoryString typeOfSubstitution, + GeneralName thirdPerson) + { + this.country = country; + this.typeOfSubstitution = typeOfSubstitution; + this.thirdPerson = thirdPerson; + this.certRef = null; + } + + public virtual string Country + { + get { return country; } + } + + public virtual DirectoryString TypeOfSubstitution + { + get { return typeOfSubstitution; } + } + + public virtual GeneralName ThirdPerson + { + get { return thirdPerson; } + } + + public virtual IssuerSerial CertRef + { + get { return certRef; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *

+ * Returns: + *

+ *

+		*               ProcurationSyntax ::= SEQUENCE {
+		*                 country [1] EXPLICIT PrintableString(SIZE(2)) OPTIONAL,
+		*                 typeOfSubstitution [2] EXPLICIT DirectoryString (SIZE(1..128)) OPTIONAL,
+		*                 signingFor [3] EXPLICIT SigningFor
+		*               }
+		* 

+ * SigningFor ::= CHOICE + * { + * thirdPerson GeneralName, + * certRef IssuerSerial + * } + *

+ * + * @return an Asn1Object + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + + if (country != null) + { + v.Add(new DerTaggedObject(true, 1, new DerPrintableString(country, true))); + } + + v.AddOptionalTagged(true, 2, typeOfSubstitution); + + if (thirdPerson != null) + { + v.Add(new DerTaggedObject(true, 3, thirdPerson)); + } + else + { + v.Add(new DerTaggedObject(true, 3, certRef)); + } + + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/ProcurationSyntax.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/ProcurationSyntax.cs.meta new file mode 100644 index 0000000..a2cdc0e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/ProcurationSyntax.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0b0928ba4fc4f5b4d9e73bf9fee5aca7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/ProfessionInfo.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/ProfessionInfo.cs new file mode 100644 index 0000000..b65757c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/ProfessionInfo.cs @@ -0,0 +1,380 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1.X500; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.IsisMtt.X509 +{ + /** + * Professions, specializations, disciplines, fields of activity, etc. + * + *
+	*               ProfessionInfo ::= SEQUENCE 
+	*               {
+	*                 namingAuthority [0] EXPLICIT NamingAuthority OPTIONAL,
+	*                 professionItems SEQUENCE OF DirectoryString (SIZE(1..128)),
+	*                 professionOids SEQUENCE OF OBJECT IDENTIFIER OPTIONAL,
+	*                 registrationNumber PrintableString(SIZE(1..128)) OPTIONAL,
+	*                 addProfessionInfo OCTET STRING OPTIONAL 
+	*               }
+	* 
+ * + * @see Org.BouncyCastle.Asn1.IsisMtt.X509.AdmissionSyntax + */ + public class ProfessionInfo + : Asn1Encodable + { + /** + * Rechtsanw�ltin + */ + public static readonly DerObjectIdentifier Rechtsanwltin = new DerObjectIdentifier( + NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".1"); + + /** + * Rechtsanwalt + */ + public static readonly DerObjectIdentifier Rechtsanwalt = new DerObjectIdentifier( + NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".2"); + + /** + * Rechtsbeistand + */ + public static readonly DerObjectIdentifier Rechtsbeistand = new DerObjectIdentifier( + NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".3"); + + /** + * Steuerberaterin + */ + public static readonly DerObjectIdentifier Steuerberaterin = new DerObjectIdentifier( + NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".4"); + + /** + * Steuerberater + */ + public static readonly DerObjectIdentifier Steuerberater = new DerObjectIdentifier( + NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".5"); + + /** + * Steuerbevollm�chtigte + */ + public static readonly DerObjectIdentifier Steuerbevollmchtigte = new DerObjectIdentifier( + NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".6"); + + /** + * Steuerbevollm�chtigter + */ + public static readonly DerObjectIdentifier Steuerbevollmchtigter = new DerObjectIdentifier( + NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".7"); + + /** + * Notarin + */ + public static readonly DerObjectIdentifier Notarin = new DerObjectIdentifier( + NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".8"); + + /** + * Notar + */ + public static readonly DerObjectIdentifier Notar = new DerObjectIdentifier( + NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".9"); + + /** + * Notarvertreterin + */ + public static readonly DerObjectIdentifier Notarvertreterin = new DerObjectIdentifier( + NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".10"); + + /** + * Notarvertreter + */ + public static readonly DerObjectIdentifier Notarvertreter = new DerObjectIdentifier( + NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".11"); + + /** + * Notariatsverwalterin + */ + public static readonly DerObjectIdentifier Notariatsverwalterin = new DerObjectIdentifier( + NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".12"); + + /** + * Notariatsverwalter + */ + public static readonly DerObjectIdentifier Notariatsverwalter = new DerObjectIdentifier( + NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".13"); + + /** + * Wirtschaftspr�ferin + */ + public static readonly DerObjectIdentifier Wirtschaftsprferin = new DerObjectIdentifier( + NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".14"); + + /** + * Wirtschaftspr�fer + */ + public static readonly DerObjectIdentifier Wirtschaftsprfer = new DerObjectIdentifier( + NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".15"); + + /** + * Vereidigte Buchpr�ferin + */ + public static readonly DerObjectIdentifier VereidigteBuchprferin = new DerObjectIdentifier( + NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".16"); + + /** + * Vereidigter Buchpr�fer + */ + public static readonly DerObjectIdentifier VereidigterBuchprfer = new DerObjectIdentifier( + NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".17"); + + /** + * Patentanw�ltin + */ + public static readonly DerObjectIdentifier Patentanwltin = new DerObjectIdentifier( + NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".18"); + + /** + * Patentanwalt + */ + public static readonly DerObjectIdentifier Patentanwalt = new DerObjectIdentifier( + NamingAuthority.IdIsisMttATNamingAuthoritiesRechtWirtschaftSteuern + ".19"); + + private readonly NamingAuthority namingAuthority; + private readonly Asn1Sequence professionItems; + private readonly Asn1Sequence professionOids; + private readonly string registrationNumber; + private readonly Asn1OctetString addProfessionInfo; + + public static ProfessionInfo GetInstance( + object obj) + { + if (obj == null || obj is ProfessionInfo) + { + return (ProfessionInfo) obj; + } + + if (obj is Asn1Sequence) + { + return new ProfessionInfo((Asn1Sequence) obj); + } + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + /** + * Constructor from Asn1Sequence. + *

+ *

+ *

+		*               ProfessionInfo ::= SEQUENCE
+		*               {
+		*                 namingAuthority [0] EXPLICIT NamingAuthority OPTIONAL,
+		*                 professionItems SEQUENCE OF DirectoryString (SIZE(1..128)),
+		*                 professionOids SEQUENCE OF OBJECT IDENTIFIER OPTIONAL,
+		*                 registrationNumber PrintableString(SIZE(1..128)) OPTIONAL,
+		*                 addProfessionInfo OCTET STRING OPTIONAL
+		*               }
+		* 
+ * + * @param seq The ASN.1 sequence. + */ + private ProfessionInfo( + Asn1Sequence seq) + { + if (seq.Count > 5) + throw new ArgumentException("Bad sequence size: " + seq.Count); + + IEnumerator e = seq.GetEnumerator(); + + e.MoveNext(); + Asn1Encodable o = (Asn1Encodable) e.Current; + + if (o is Asn1TaggedObject) + { + Asn1TaggedObject ato = (Asn1TaggedObject) o; + if (ato.TagNo != 0) + throw new ArgumentException("Bad tag number: " + ato.TagNo); + + namingAuthority = NamingAuthority.GetInstance(ato, true); + e.MoveNext(); + o = (Asn1Encodable) e.Current; + } + + professionItems = Asn1Sequence.GetInstance(o); + + if (e.MoveNext()) + { + o = (Asn1Encodable) e.Current; + if (o is Asn1Sequence) + { + professionOids = Asn1Sequence.GetInstance(o); + } + else if (o is DerPrintableString) + { + registrationNumber = DerPrintableString.GetInstance(o).GetString(); + } + else if (o is Asn1OctetString) + { + addProfessionInfo = Asn1OctetString.GetInstance(o); + } + else + { + throw new ArgumentException("Bad object encountered: " + Platform.GetTypeName(o)); + } + } + + if (e.MoveNext()) + { + o = (Asn1Encodable) e.Current; + if (o is DerPrintableString) + { + registrationNumber = DerPrintableString.GetInstance(o).GetString(); + } + else if (o is DerOctetString) + { + addProfessionInfo = (DerOctetString) o; + } + else + { + throw new ArgumentException("Bad object encountered: " + Platform.GetTypeName(o)); + } + } + + if (e.MoveNext()) + { + o = (Asn1Encodable) e.Current; + if (o is DerOctetString) + { + addProfessionInfo = (DerOctetString) o; + } + else + { + throw new ArgumentException("Bad object encountered: " + Platform.GetTypeName(o)); + } + } + } + + /** + * Constructor from given details. + *

+ * professionItems is mandatory, all other parameters are + * optional. + * + * @param namingAuthority The naming authority. + * @param professionItems Directory strings of the profession. + * @param professionOids DERObjectIdentfier objects for the + * profession. + * @param registrationNumber Registration number. + * @param addProfessionInfo Additional infos in encoded form. + */ + public ProfessionInfo( + NamingAuthority namingAuthority, + DirectoryString[] professionItems, + DerObjectIdentifier[] professionOids, + string registrationNumber, + Asn1OctetString addProfessionInfo) + { + this.namingAuthority = namingAuthority; + this.professionItems = new DerSequence(professionItems); + if (professionOids != null) + { + this.professionOids = new DerSequence(professionOids); + } + this.registrationNumber = registrationNumber; + this.addProfessionInfo = addProfessionInfo; + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *

+ * Returns: + *

+ *

+		*               ProfessionInfo ::= SEQUENCE
+		*               {
+		*                 namingAuthority [0] EXPLICIT NamingAuthority OPTIONAL,
+		*                 professionItems SEQUENCE OF DirectoryString (SIZE(1..128)),
+		*                 professionOids SEQUENCE OF OBJECT IDENTIFIER OPTIONAL,
+		*                 registrationNumber PrintableString(SIZE(1..128)) OPTIONAL,
+		*                 addProfessionInfo OCTET STRING OPTIONAL
+		*               }
+		* 
+ * + * @return an Asn1Object + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + v.AddOptionalTagged(true, 0, namingAuthority); + v.Add(professionItems); + v.AddOptional(professionOids); + + if (registrationNumber != null) + { + v.Add(new DerPrintableString(registrationNumber, true)); + } + + v.AddOptional(addProfessionInfo); + return new DerSequence(v); + } + + /** + * @return Returns the addProfessionInfo. + */ + public virtual Asn1OctetString AddProfessionInfo + { + get { return addProfessionInfo; } + } + + /** + * @return Returns the namingAuthority. + */ + public virtual NamingAuthority NamingAuthority + { + get { return namingAuthority; } + } + + /** + * @return Returns the professionItems. + */ + public virtual DirectoryString[] GetProfessionItems() + { + DirectoryString[] result = new DirectoryString[professionItems.Count]; + + for (int i = 0; i < professionItems.Count; ++i) + { + result[i] = DirectoryString.GetInstance(professionItems[i]); + } + + return result; + } + + /** + * @return Returns the professionOids. + */ + public virtual DerObjectIdentifier[] GetProfessionOids() + { + if (professionOids == null) + { + return new DerObjectIdentifier[0]; + } + + DerObjectIdentifier[] result = new DerObjectIdentifier[professionOids.Count]; + + for (int i = 0; i < professionOids.Count; ++i) + { + result[i] = DerObjectIdentifier.GetInstance(professionOids[i]); + } + + return result; + } + + /** + * @return Returns the registrationNumber. + */ + public virtual string RegistrationNumber + { + get { return registrationNumber; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/ProfessionInfo.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/ProfessionInfo.cs.meta new file mode 100644 index 0000000..dc9bdb8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/ProfessionInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 26704f20603e0034aa5fa5ad7bb98997 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/Restriction.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/Restriction.cs new file mode 100644 index 0000000..75df252 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/Restriction.cs @@ -0,0 +1,82 @@ +using System; + +using Org.BouncyCastle.Asn1.X500; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.IsisMtt.X509 +{ + /** + * Some other restriction regarding the usage of this certificate. + *

+ *

+	*  RestrictionSyntax ::= DirectoryString (SIZE(1..1024))
+	* 
+ */ + public class Restriction + : Asn1Encodable + { + private readonly DirectoryString restriction; + + public static Restriction GetInstance( + object obj) + { + if (obj is Restriction) + return (Restriction) obj; + + if (obj is IAsn1String) + return new Restriction(DirectoryString.GetInstance(obj)); + + throw new ArgumentException("Unknown object in GetInstance: " + Platform.GetTypeName(obj), "obj"); + } + + /** + * Constructor from DirectoryString. + *

+ * The DirectoryString is of type RestrictionSyntax: + *

+ *

+		*      RestrictionSyntax ::= DirectoryString (SIZE(1..1024))
+		* 
+ * + * @param restriction A IAsn1String. + */ + private Restriction( + DirectoryString restriction) + { + this.restriction = restriction; + } + + /** + * Constructor from a given details. + * + * @param restriction The description of the restriction. + */ + public Restriction( + string restriction) + { + this.restriction = new DirectoryString(restriction); + } + + public virtual DirectoryString RestrictionString + { + get { return restriction; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *

+ * Returns: + *

+ *

+		*      RestrictionSyntax ::= DirectoryString (SIZE(1..1024))
+		* 

+ *

+ * + * @return an Asn1Object + */ + public override Asn1Object ToAsn1Object() + { + return restriction.ToAsn1Object(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/Restriction.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/Restriction.cs.meta new file mode 100644 index 0000000..e930d80 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/isismtt/x509/Restriction.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1ea339009e31deb4a8938b66b8342a79 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/kisa.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/kisa.meta new file mode 100644 index 0000000..2bcaf1e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/kisa.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 79b474d8cd2b5be4f85fc4b80c3d93df +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/kisa/KISAObjectIdentifiers.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/kisa/KISAObjectIdentifiers.cs new file mode 100644 index 0000000..05351ec --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/kisa/KISAObjectIdentifiers.cs @@ -0,0 +1,8 @@ +namespace Org.BouncyCastle.Asn1.Kisa +{ + public abstract class KisaObjectIdentifiers + { + public static readonly DerObjectIdentifier IdSeedCbc = new DerObjectIdentifier("1.2.410.200004.1.4"); + public static readonly DerObjectIdentifier IdNpkiAppCmsSeedWrap = new DerObjectIdentifier("1.2.410.200004.7.1.1.1"); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/kisa/KISAObjectIdentifiers.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/kisa/KISAObjectIdentifiers.cs.meta new file mode 100644 index 0000000..6bf90a1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/kisa/KISAObjectIdentifiers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 768aaa3d170387f4ba4d1c5a4faef454 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/microsoft.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/microsoft.meta new file mode 100644 index 0000000..e1b2c72 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/microsoft.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 57b893a0575ce7743bc7fd318e03e8b3 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/microsoft/MicrosoftObjectIdentifiers.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/microsoft/MicrosoftObjectIdentifiers.cs new file mode 100644 index 0000000..bc48c3f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/microsoft/MicrosoftObjectIdentifiers.cs @@ -0,0 +1,19 @@ +using System; + +namespace Org.BouncyCastle.Asn1.Microsoft +{ + public abstract class MicrosoftObjectIdentifiers + { + // + // Microsoft + // iso(1) identified-organization(3) dod(6) internet(1) private(4) enterprise(1) Microsoft(311) + // + public static readonly DerObjectIdentifier Microsoft = new DerObjectIdentifier("1.3.6.1.4.1.311"); + public static readonly DerObjectIdentifier MicrosoftCertTemplateV1 = Microsoft.Branch("20.2"); + public static readonly DerObjectIdentifier MicrosoftCAVersion = Microsoft.Branch("21.1"); + public static readonly DerObjectIdentifier MicrosoftPrevCACertHash = Microsoft.Branch("21.2"); + public static readonly DerObjectIdentifier MicrosoftCrlNextPublish = Microsoft.Branch("21.4"); + public static readonly DerObjectIdentifier MicrosoftCertTemplateV2 = Microsoft.Branch("21.7"); + public static readonly DerObjectIdentifier MicrosoftAppPolicies = Microsoft.Branch("21.10"); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/microsoft/MicrosoftObjectIdentifiers.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/microsoft/MicrosoftObjectIdentifiers.cs.meta new file mode 100644 index 0000000..79590e8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/microsoft/MicrosoftObjectIdentifiers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a1e5f284842b4444e8323487df227c74 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/misc.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/misc.meta new file mode 100644 index 0000000..22c6da0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/misc.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 79131ff8a3c2fa346b3a8dd2c6459232 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/misc/CAST5CBCParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/misc/CAST5CBCParameters.cs new file mode 100644 index 0000000..7bd9f1e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/misc/CAST5CBCParameters.cs @@ -0,0 +1,74 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Misc +{ + public class Cast5CbcParameters + : Asn1Encodable + { + private readonly DerInteger keyLength; + private readonly Asn1OctetString iv; + + public static Cast5CbcParameters GetInstance( + object o) + { + if (o is Cast5CbcParameters) + { + return (Cast5CbcParameters) o; + } + + if (o is Asn1Sequence) + { + return new Cast5CbcParameters((Asn1Sequence) o); + } + + throw new ArgumentException("unknown object in Cast5CbcParameters factory"); + } + + public Cast5CbcParameters( + byte[] iv, + int keyLength) + { + this.iv = new DerOctetString(iv); + this.keyLength = new DerInteger(keyLength); + } + + private Cast5CbcParameters( + Asn1Sequence seq) + { + if (seq.Count != 2) + throw new ArgumentException("Wrong number of elements in sequence", "seq"); + + iv = (Asn1OctetString) seq[0]; + keyLength = (DerInteger) seq[1]; + } + + public byte[] GetIV() + { + return Arrays.Clone(iv.GetOctets()); + } + + public int KeyLength + { + get { return keyLength.IntValueExact; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * cast5CBCParameters ::= Sequence {
+         *                           iv         OCTET STRING DEFAULT 0,
+         *                                  -- Initialization vector
+         *                           keyLength  Integer
+         *                                  -- Key length, in bits
+         *                      }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + return new DerSequence(iv, keyLength); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/misc/CAST5CBCParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/misc/CAST5CBCParameters.cs.meta new file mode 100644 index 0000000..06ef8cf --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/misc/CAST5CBCParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ce3ee62a363a0914ab56734f8be356e3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/misc/IDEACBCPar.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/misc/IDEACBCPar.cs new file mode 100644 index 0000000..9ae9f6f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/misc/IDEACBCPar.cs @@ -0,0 +1,63 @@ +using System; + +using Org.BouncyCastle.Asn1; + +namespace Org.BouncyCastle.Asn1.Misc +{ + public class IdeaCbcPar + : Asn1Encodable + { + internal Asn1OctetString iv; + + public static IdeaCbcPar GetInstance( + object o) + { + if (o is IdeaCbcPar) + { + return (IdeaCbcPar) o; + } + + if (o is Asn1Sequence) + { + return new IdeaCbcPar((Asn1Sequence) o); + } + + throw new ArgumentException("unknown object in IDEACBCPar factory"); + } + + public IdeaCbcPar( + byte[] iv) + { + this.iv = new DerOctetString(iv); + } + + private IdeaCbcPar( + Asn1Sequence seq) + { + if (seq.Count == 1) + { + iv = (Asn1OctetString) seq[0]; + } + } + + public byte[] GetIV() + { + return iv == null ? null : iv.GetOctets(); + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * IDEA-CBCPar ::= Sequence {
+         *                      iv    OCTET STRING OPTIONAL -- exactly 8 octets
+         *                  }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + v.AddOptional(iv); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/misc/IDEACBCPar.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/misc/IDEACBCPar.cs.meta new file mode 100644 index 0000000..cc885b8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/misc/IDEACBCPar.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ba803efb4ab0efe4d90e30433d5e2b8d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/misc/MiscObjectIdentifiers.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/misc/MiscObjectIdentifiers.cs new file mode 100644 index 0000000..1f10188 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/misc/MiscObjectIdentifiers.cs @@ -0,0 +1,96 @@ +namespace Org.BouncyCastle.Asn1.Misc +{ + public abstract class MiscObjectIdentifiers + { + // + // Netscape + // iso/itu(2) joint-assign(16) us(840) uscompany(1) Netscape(113730) cert-extensions(1) } + // + public static readonly DerObjectIdentifier Netscape = new DerObjectIdentifier("2.16.840.1.113730.1"); + public static readonly DerObjectIdentifier NetscapeCertType = Netscape.Branch("1"); + public static readonly DerObjectIdentifier NetscapeBaseUrl = Netscape.Branch("2"); + public static readonly DerObjectIdentifier NetscapeRevocationUrl = Netscape.Branch("3"); + public static readonly DerObjectIdentifier NetscapeCARevocationUrl = Netscape.Branch("4"); + public static readonly DerObjectIdentifier NetscapeRenewalUrl = Netscape.Branch("7"); + public static readonly DerObjectIdentifier NetscapeCAPolicyUrl = Netscape.Branch("8"); + public static readonly DerObjectIdentifier NetscapeSslServerName = Netscape.Branch("12"); + public static readonly DerObjectIdentifier NetscapeCertComment = Netscape.Branch("13"); + + // + // Verisign + // iso/itu(2) joint-assign(16) us(840) uscompany(1) verisign(113733) cert-extensions(1) } + // + public static readonly DerObjectIdentifier Verisign = new DerObjectIdentifier("2.16.840.1.113733.1"); + + // + // CZAG - country, zip, age, and gender + // + public static readonly DerObjectIdentifier VerisignCzagExtension = Verisign.Branch("6.3"); + + public static readonly DerObjectIdentifier VerisignPrivate_6_9 = Verisign.Branch("6.9"); + public static readonly DerObjectIdentifier VerisignOnSiteJurisdictionHash = Verisign.Branch("6.11"); + public static readonly DerObjectIdentifier VerisignBitString_6_13 = Verisign.Branch("6.13"); + + // D&B D-U-N-S number + public static readonly DerObjectIdentifier VerisignDnbDunsNumber = Verisign.Branch("6.15"); + + public static readonly DerObjectIdentifier VerisignIssStrongCrypto = Verisign.Branch("8.1"); + + // + // Novell + // iso/itu(2) country(16) us(840) organization(1) novell(113719) + // + public static readonly string Novell = "2.16.840.1.113719"; + public static readonly DerObjectIdentifier NovellSecurityAttribs = new DerObjectIdentifier(Novell + ".1.9.4.1"); + + // + // Entrust + // iso(1) member-body(16) us(840) nortelnetworks(113533) entrust(7) + // + public static readonly string Entrust = "1.2.840.113533.7"; + public static readonly DerObjectIdentifier EntrustVersionExtension = new DerObjectIdentifier(Entrust + ".65.0"); + + public static readonly DerObjectIdentifier cast5CBC = new DerObjectIdentifier(Entrust+ ".66.10"); + + // + // HMAC-SHA1 hMAC-SHA1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) + // dod(6) internet(1) security(5) mechanisms(5) 8 1 2 } + // + public static readonly DerObjectIdentifier HMAC_SHA1 = new DerObjectIdentifier("1.3.6.1.5.5.8.1.2"); + + // + // Ascom + // + public static readonly DerObjectIdentifier as_sys_sec_alg_ideaCBC = new DerObjectIdentifier("1.3.6.1.4.1.188.7.1.1.2"); + + // + // Peter Gutmann's Cryptlib + // + public static readonly DerObjectIdentifier cryptlib = new DerObjectIdentifier("1.3.6.1.4.1.3029"); + + public static readonly DerObjectIdentifier cryptlib_algorithm = cryptlib.Branch("1"); + public static readonly DerObjectIdentifier cryptlib_algorithm_blowfish_ECB = cryptlib_algorithm.Branch("1.1"); + public static readonly DerObjectIdentifier cryptlib_algorithm_blowfish_CBC = cryptlib_algorithm.Branch("1.2"); + public static readonly DerObjectIdentifier cryptlib_algorithm_blowfish_CFB = cryptlib_algorithm.Branch("1.3"); + public static readonly DerObjectIdentifier cryptlib_algorithm_blowfish_OFB = cryptlib_algorithm.Branch("1.4"); + + // + // Blake2b + // + public static readonly DerObjectIdentifier blake2 = new DerObjectIdentifier("1.3.6.1.4.1.1722.12.2"); + + public static readonly DerObjectIdentifier id_blake2b160 = blake2.Branch("1.5"); + public static readonly DerObjectIdentifier id_blake2b256 = blake2.Branch("1.8"); + public static readonly DerObjectIdentifier id_blake2b384 = blake2.Branch("1.12"); + public static readonly DerObjectIdentifier id_blake2b512 = blake2.Branch("1.16"); + + public static readonly DerObjectIdentifier id_blake2s128 = blake2.Branch("2.4"); + public static readonly DerObjectIdentifier id_blake2s160 = blake2.Branch("2.5"); + public static readonly DerObjectIdentifier id_blake2s224 = blake2.Branch("2.7"); + public static readonly DerObjectIdentifier id_blake2s256 = blake2.Branch("2.8"); + + // + // Scrypt + public static readonly DerObjectIdentifier id_scrypt = new DerObjectIdentifier("1.3.6.1.4.1.11591.4.11"); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/misc/MiscObjectIdentifiers.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/misc/MiscObjectIdentifiers.cs.meta new file mode 100644 index 0000000..c77436e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/misc/MiscObjectIdentifiers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d158a2faba4455446967d8ba73bcf1b0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/misc/NetscapeCertType.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/misc/NetscapeCertType.cs new file mode 100644 index 0000000..d809eae --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/misc/NetscapeCertType.cs @@ -0,0 +1,54 @@ +using Org.BouncyCastle.Asn1; + +namespace Org.BouncyCastle.Asn1.Misc +{ + /** + * The NetscapeCertType object. + *
+     *    NetscapeCertType ::= BIT STRING {
+     *         SSLClient               (0),
+     *         SSLServer               (1),
+     *         S/MIME                  (2),
+     *         Object Signing          (3),
+     *         Reserved                (4),
+     *         SSL CA                  (5),
+     *         S/MIME CA               (6),
+     *         Object Signing CA       (7) }
+     * 
+ */ + public class NetscapeCertType + : DerBitString + { + public const int SslClient = (1 << 7); + public const int SslServer = (1 << 6); + public const int Smime = (1 << 5); + public const int ObjectSigning = (1 << 4); + public const int Reserved = (1 << 3); + public const int SslCA = (1 << 2); + public const int SmimeCA = (1 << 1); + public const int ObjectSigningCA = (1 << 0); + + /** + * Basic constructor. + * + * @param usage - the bitwise OR of the Key Usage flags giving the + * allowed uses for the key. + * e.g. (X509NetscapeCertType.sslCA | X509NetscapeCertType.smimeCA) + */ + public NetscapeCertType(int usage) + : base(usage) + { + } + + public NetscapeCertType(DerBitString usage) + : base(usage.GetBytes(), usage.PadBits) + { + } + + public override string ToString() + { + byte[] data = GetBytes(); + return "NetscapeCertType: 0x" + (data[0] & 0xff).ToString("X"); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/misc/NetscapeCertType.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/misc/NetscapeCertType.cs.meta new file mode 100644 index 0000000..b708b45 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/misc/NetscapeCertType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 09bc540528bec39408d4f425168c6b94 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/misc/NetscapeRevocationURL.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/misc/NetscapeRevocationURL.cs new file mode 100644 index 0000000..6cac031 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/misc/NetscapeRevocationURL.cs @@ -0,0 +1,18 @@ +using Org.BouncyCastle.Asn1; + +namespace Org.BouncyCastle.Asn1.Misc +{ + public class NetscapeRevocationUrl + : DerIA5String + { + public NetscapeRevocationUrl(DerIA5String str) + : base(str.GetString()) + { + } + + public override string ToString() + { + return "NetscapeRevocationUrl: " + this.GetString(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/misc/NetscapeRevocationURL.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/misc/NetscapeRevocationURL.cs.meta new file mode 100644 index 0000000..73d04d4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/misc/NetscapeRevocationURL.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6619304b9c610ec4f97183962a9ee6ad +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/misc/VerisignCzagExtension.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/misc/VerisignCzagExtension.cs new file mode 100644 index 0000000..1c3054b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/misc/VerisignCzagExtension.cs @@ -0,0 +1,18 @@ +using Org.BouncyCastle.Asn1; + +namespace Org.BouncyCastle.Asn1.Misc +{ + public class VerisignCzagExtension + : DerIA5String + { + public VerisignCzagExtension(DerIA5String str) + : base(str.GetString()) + { + } + + public override string ToString() + { + return "VerisignCzagExtension: " + this.GetString(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/misc/VerisignCzagExtension.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/misc/VerisignCzagExtension.cs.meta new file mode 100644 index 0000000..acebd28 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/misc/VerisignCzagExtension.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 44d372bac8e0e934e958000a9b90cd49 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/mozilla.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/mozilla.meta new file mode 100644 index 0000000..7936d76 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/mozilla.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 6eb611974c5662e46b544d29256f28e4 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/mozilla/PublicKeyAndChallenge.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/mozilla/PublicKeyAndChallenge.cs new file mode 100644 index 0000000..ff2a119 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/mozilla/PublicKeyAndChallenge.cs @@ -0,0 +1,68 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Mozilla +{ + /** + * This is designed to parse + * the PublicKeyAndChallenge created by the KEYGEN tag included by + * Mozilla based browsers. + *
+	 *  PublicKeyAndChallenge ::= SEQUENCE {
+	 *    spki SubjectPublicKeyInfo,
+	 *    challenge IA5STRING
+	 *  }
+	 *
+	 *  
+ */ + public class PublicKeyAndChallenge + : Asn1Encodable + { + private Asn1Sequence pkacSeq; + private SubjectPublicKeyInfo spki; + private DerIA5String challenge; + + public static PublicKeyAndChallenge GetInstance( + object obj) + { + if (obj is PublicKeyAndChallenge) + { + return (PublicKeyAndChallenge) obj; + } + + if (obj is Asn1Sequence) + { + return new PublicKeyAndChallenge((Asn1Sequence) obj); + } + + throw new ArgumentException( + "unknown object in 'PublicKeyAndChallenge' factory : " + + Platform.GetTypeName(obj) + "."); + } + + public PublicKeyAndChallenge( + Asn1Sequence seq) + { + pkacSeq = seq; + spki = SubjectPublicKeyInfo.GetInstance(seq[0]); + challenge = DerIA5String.GetInstance(seq[1]); + } + + public override Asn1Object ToAsn1Object() + { + return pkacSeq; + } + + public SubjectPublicKeyInfo SubjectPublicKeyInfo + { + get { return spki; } + } + + public DerIA5String Challenge + { + get { return challenge; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/mozilla/PublicKeyAndChallenge.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/mozilla/PublicKeyAndChallenge.cs.meta new file mode 100644 index 0000000..2d3c2d6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/mozilla/PublicKeyAndChallenge.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 43e6f4d82a4904442a7c34b99c7ad88d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/nist.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/nist.meta new file mode 100644 index 0000000..693cbd2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/nist.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e942e7ecba7c41448ad5f166248192cd +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/nist/KMACwithSHAKE128_params.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/nist/KMACwithSHAKE128_params.cs new file mode 100644 index 0000000..a1fd8f4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/nist/KMACwithSHAKE128_params.cs @@ -0,0 +1,103 @@ +using Org.BouncyCastle.Utilities; +using System; + + +namespace Org.BouncyCastle.Asn1.Nist +{ + /// + /// KMACwithSHAKE128-params ::= SEQUENCE { + /// kMACOutputLength INTEGER DEFAULT 256, -- Output length in bits + /// customizationString OCTET STRING DEFAULT ''H + /// } + /// +public class KMacWithShake128Params : Asn1Encodable +{ + private static readonly byte[] EMPTY_STRING = new byte[0]; + private static readonly int DEF_LENGTH = 256; + + private readonly int outputLength; + private readonly byte[] customizationString; + + public KMacWithShake128Params(int outputLength) + { + this.outputLength = outputLength; + this.customizationString = EMPTY_STRING; + } + + public KMacWithShake128Params(int outputLength, byte[] customizationString) + { + this.outputLength = outputLength; + this.customizationString = Arrays.Clone(customizationString); + } + + public static KMacWithShake128Params GetInstance(object o) + { + if (o is KMacWithShake128Params) + { + return (KMacWithShake128Params)o; + } + else if (o != null) + { + return new KMacWithShake128Params(Asn1Sequence.GetInstance(o)); + } + + return null; + } + + private KMacWithShake128Params(Asn1Sequence seq) + { + if (seq.Count > 2) + throw new InvalidOperationException("sequence size greater than 2"); + + if (seq.Count == 2) + { + this.outputLength = DerInteger.GetInstance(seq[0]).IntValueExact; + this.customizationString = Arrays.Clone(Asn1OctetString.GetInstance(seq[1]).GetOctets()); + } + else if (seq.Count == 1) + { + if (seq[0] is DerInteger) + { + this.outputLength = DerInteger.GetInstance(seq[0]).IntValueExact; + this.customizationString = EMPTY_STRING; + } + else + { + this.outputLength = DEF_LENGTH; + this.customizationString = Arrays.Clone(Asn1OctetString.GetInstance(seq[0]).GetOctets()); + } + } + else + { + this.outputLength = DEF_LENGTH; + this.customizationString = EMPTY_STRING; + } + } + + public int OutputLength + { + get { return outputLength; } + } + + public byte[] CustomizationString + { + get { return Arrays.Clone(customizationString); } + } + + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + if (outputLength != DEF_LENGTH) + { + v.Add(new DerInteger(outputLength)); + } + + if (customizationString.Length != 0) + { + v.Add(new DerOctetString(CustomizationString)); + } + + return new DerSequence(v); + } +} +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/nist/KMACwithSHAKE128_params.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/nist/KMACwithSHAKE128_params.cs.meta new file mode 100644 index 0000000..a0be420 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/nist/KMACwithSHAKE128_params.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c04f49b36955d3a449d9c3679ee412f2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/nist/KMACwithSHAKE256_params.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/nist/KMACwithSHAKE256_params.cs new file mode 100644 index 0000000..fa74719 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/nist/KMACwithSHAKE256_params.cs @@ -0,0 +1,102 @@ +using Org.BouncyCastle.Utilities; +using System; + +namespace Org.BouncyCastle.Asn1.Nist +{ + /// + /// KMACwithSHAKE256-params ::= SEQUENCE { + /// kMACOutputLength INTEGER DEFAULT 512, -- Output length in bits + /// customizationString OCTET STRING DEFAULT ''H + /// } + /// +public class KMacWithShake256Params : Asn1Encodable +{ + private static readonly byte[] EMPTY_STRING = new byte[0]; + private static readonly int DEF_LENGTH = 512; + + private readonly int outputLength; + private readonly byte[] customizationString; + + public KMacWithShake256Params(int outputLength) + { + this.outputLength = outputLength; + this.customizationString = EMPTY_STRING; + } + + public KMacWithShake256Params(int outputLength, byte[] customizationString) + { + this.outputLength = outputLength; + this.customizationString = Arrays.Clone(customizationString); + } + + public static KMacWithShake256Params GetInstance(Object o) + { + if (o is KMacWithShake256Params) + { + return (KMacWithShake256Params)o; + } + else if (o != null) + { + return new KMacWithShake256Params(Asn1Sequence.GetInstance(o)); + } + + return null; + } + + private KMacWithShake256Params(Asn1Sequence seq) + { + if (seq.Count > 2) + throw new InvalidOperationException("sequence size greater than 2"); + + if (seq.Count == 2) + { + this.outputLength = DerInteger.GetInstance(seq[0]).IntValueExact; + this.customizationString = Arrays.Clone(Asn1OctetString.GetInstance(seq[1]).GetOctets()); + } + else if (seq.Count == 1) + { + if (seq[0] is DerInteger) + { + this.outputLength = DerInteger.GetInstance(seq[0]).IntValueExact; + this.customizationString = EMPTY_STRING; + } + else + { + this.outputLength = DEF_LENGTH; + this.customizationString = Arrays.Clone(Asn1OctetString.GetInstance(seq[0]).GetOctets()); + } + } + else + { + this.outputLength = DEF_LENGTH; + this.customizationString = EMPTY_STRING; + } + } + + public int OutputLength + { + get { return outputLength; } + } + + public byte[] CustomizationString + { + get { return Arrays.Clone(customizationString); } + } + + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + if (outputLength != DEF_LENGTH) + { + v.Add(new DerInteger(outputLength)); + } + + if (customizationString.Length != 0) + { + v.Add(new DerOctetString(CustomizationString)); + } + + return new DerSequence(v); + } +} +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/nist/KMACwithSHAKE256_params.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/nist/KMACwithSHAKE256_params.cs.meta new file mode 100644 index 0000000..61f965a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/nist/KMACwithSHAKE256_params.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1eb65ee7c9509b746a66403bef8ab54d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/nist/NISTNamedCurves.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/nist/NISTNamedCurves.cs new file mode 100644 index 0000000..f6c1598 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/nist/NISTNamedCurves.cs @@ -0,0 +1,102 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Sec; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Asn1.Nist +{ + /** + * Utility class for fetching curves using their NIST names as published in FIPS-PUB 186-3 + */ + public sealed class NistNamedCurves + { + private NistNamedCurves() + { + } + + private static readonly IDictionary objIds = Platform.CreateHashtable(); + private static readonly IDictionary names = Platform.CreateHashtable(); + + private static void DefineCurveAlias( + string name, + DerObjectIdentifier oid) + { + objIds.Add(Platform.ToUpperInvariant(name), oid); + names.Add(oid, name); + } + + static NistNamedCurves() + { + DefineCurveAlias("B-163", SecObjectIdentifiers.SecT163r2); + DefineCurveAlias("B-233", SecObjectIdentifiers.SecT233r1); + DefineCurveAlias("B-283", SecObjectIdentifiers.SecT283r1); + DefineCurveAlias("B-409", SecObjectIdentifiers.SecT409r1); + DefineCurveAlias("B-571", SecObjectIdentifiers.SecT571r1); + + DefineCurveAlias("K-163", SecObjectIdentifiers.SecT163k1); + DefineCurveAlias("K-233", SecObjectIdentifiers.SecT233k1); + DefineCurveAlias("K-283", SecObjectIdentifiers.SecT283k1); + DefineCurveAlias("K-409", SecObjectIdentifiers.SecT409k1); + DefineCurveAlias("K-571", SecObjectIdentifiers.SecT571k1); + + DefineCurveAlias("P-192", SecObjectIdentifiers.SecP192r1); + DefineCurveAlias("P-224", SecObjectIdentifiers.SecP224r1); + DefineCurveAlias("P-256", SecObjectIdentifiers.SecP256r1); + DefineCurveAlias("P-384", SecObjectIdentifiers.SecP384r1); + DefineCurveAlias("P-521", SecObjectIdentifiers.SecP521r1); + } + + public static X9ECParameters GetByName( + string name) + { + DerObjectIdentifier oid = GetOid(name); + return oid == null ? null : GetByOid(oid); + } + + /** + * return the X9ECParameters object for the named curve represented by + * the passed in object identifier. Null if the curve isn't present. + * + * @param oid an object identifier representing a named curve, if present. + */ + public static X9ECParameters GetByOid( + DerObjectIdentifier oid) + { + return SecNamedCurves.GetByOid(oid); + } + + /** + * return the object identifier signified by the passed in name. Null + * if there is no object identifier associated with name. + * + * @return the object identifier associated with name, if present. + */ + public static DerObjectIdentifier GetOid( + string name) + { + return (DerObjectIdentifier) objIds[Platform.ToUpperInvariant(name)]; + } + + /** + * return the named curve name represented by the given object identifier. + */ + public static string GetName( + DerObjectIdentifier oid) + { + return (string) names[oid]; + } + + /** + * returns an enumeration containing the name strings for curves + * contained in this structure. + */ + public static IEnumerable Names + { + get { return new EnumerableProxy(names.Values); } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/nist/NISTNamedCurves.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/nist/NISTNamedCurves.cs.meta new file mode 100644 index 0000000..cb501a7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/nist/NISTNamedCurves.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 83a6673679878ba4d98d82541d6d7f82 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/nist/NISTObjectIdentifiers.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/nist/NISTObjectIdentifiers.cs new file mode 100644 index 0000000..417fa8d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/nist/NISTObjectIdentifiers.cs @@ -0,0 +1,108 @@ +using Org.BouncyCastle.Asn1; + +namespace Org.BouncyCastle.Asn1.Nist +{ + public sealed class NistObjectIdentifiers + { + private NistObjectIdentifiers() + { + } + + // + // NIST + // iso/itu(2) joint-assign(16) us(840) organization(1) gov(101) csor(3) + + // + // nistalgorithms(4) + // + public static readonly DerObjectIdentifier NistAlgorithm = new DerObjectIdentifier("2.16.840.1.101.3.4"); + + public static readonly DerObjectIdentifier HashAlgs = NistAlgorithm.Branch("2"); + + public static readonly DerObjectIdentifier IdSha256 = HashAlgs.Branch("1"); + public static readonly DerObjectIdentifier IdSha384 = HashAlgs.Branch("2"); + public static readonly DerObjectIdentifier IdSha512 = HashAlgs.Branch("3"); + public static readonly DerObjectIdentifier IdSha224 = HashAlgs.Branch("4"); + public static readonly DerObjectIdentifier IdSha512_224 = HashAlgs.Branch("5"); + public static readonly DerObjectIdentifier IdSha512_256 = HashAlgs.Branch("6"); + public static readonly DerObjectIdentifier IdSha3_224 = HashAlgs.Branch("7"); + public static readonly DerObjectIdentifier IdSha3_256 = HashAlgs.Branch("8"); + public static readonly DerObjectIdentifier IdSha3_384 = HashAlgs.Branch("9"); + public static readonly DerObjectIdentifier IdSha3_512 = HashAlgs.Branch("10"); + public static readonly DerObjectIdentifier IdShake128 = HashAlgs.Branch("11"); + public static readonly DerObjectIdentifier IdShake256 = HashAlgs.Branch("12"); + public static readonly DerObjectIdentifier IdHMacWithSha3_224 = HashAlgs.Branch("13"); + public static readonly DerObjectIdentifier IdHMacWithSha3_256 = HashAlgs.Branch("14"); + public static readonly DerObjectIdentifier IdHMacWithSha3_384 = HashAlgs.Branch("15"); + public static readonly DerObjectIdentifier IdHMacWithSha3_512 = HashAlgs.Branch("16"); + public static readonly DerObjectIdentifier IdShake128Len = HashAlgs.Branch("17"); + public static readonly DerObjectIdentifier IdShake256Len = HashAlgs.Branch("18"); + public static readonly DerObjectIdentifier IdKmacWithShake128 = HashAlgs.Branch("19"); + public static readonly DerObjectIdentifier IdKmacWithShake256 = HashAlgs.Branch("20"); + + public static readonly DerObjectIdentifier Aes = new DerObjectIdentifier(NistAlgorithm + ".1"); + + public static readonly DerObjectIdentifier IdAes128Ecb = new DerObjectIdentifier(Aes + ".1"); + public static readonly DerObjectIdentifier IdAes128Cbc = new DerObjectIdentifier(Aes + ".2"); + public static readonly DerObjectIdentifier IdAes128Ofb = new DerObjectIdentifier(Aes + ".3"); + public static readonly DerObjectIdentifier IdAes128Cfb = new DerObjectIdentifier(Aes + ".4"); + public static readonly DerObjectIdentifier IdAes128Wrap = new DerObjectIdentifier(Aes + ".5"); + public static readonly DerObjectIdentifier IdAes128Gcm = new DerObjectIdentifier(Aes + ".6"); + public static readonly DerObjectIdentifier IdAes128Ccm = new DerObjectIdentifier(Aes + ".7"); + + public static readonly DerObjectIdentifier IdAes192Ecb = new DerObjectIdentifier(Aes + ".21"); + public static readonly DerObjectIdentifier IdAes192Cbc = new DerObjectIdentifier(Aes + ".22"); + public static readonly DerObjectIdentifier IdAes192Ofb = new DerObjectIdentifier(Aes + ".23"); + public static readonly DerObjectIdentifier IdAes192Cfb = new DerObjectIdentifier(Aes + ".24"); + public static readonly DerObjectIdentifier IdAes192Wrap = new DerObjectIdentifier(Aes + ".25"); + public static readonly DerObjectIdentifier IdAes192Gcm = new DerObjectIdentifier(Aes + ".26"); + public static readonly DerObjectIdentifier IdAes192Ccm = new DerObjectIdentifier(Aes + ".27"); + + public static readonly DerObjectIdentifier IdAes256Ecb = new DerObjectIdentifier(Aes + ".41"); + public static readonly DerObjectIdentifier IdAes256Cbc = new DerObjectIdentifier(Aes + ".42"); + public static readonly DerObjectIdentifier IdAes256Ofb = new DerObjectIdentifier(Aes + ".43"); + public static readonly DerObjectIdentifier IdAes256Cfb = new DerObjectIdentifier(Aes + ".44"); + public static readonly DerObjectIdentifier IdAes256Wrap = new DerObjectIdentifier(Aes + ".45"); + public static readonly DerObjectIdentifier IdAes256Gcm = new DerObjectIdentifier(Aes + ".46"); + public static readonly DerObjectIdentifier IdAes256Ccm = new DerObjectIdentifier(Aes + ".47"); + + // + // signatures + // + public static readonly DerObjectIdentifier IdDsaWithSha2 = new DerObjectIdentifier(NistAlgorithm + ".3"); + + public static readonly DerObjectIdentifier DsaWithSha224 = new DerObjectIdentifier(IdDsaWithSha2 + ".1"); + public static readonly DerObjectIdentifier DsaWithSha256 = new DerObjectIdentifier(IdDsaWithSha2 + ".2"); + public static readonly DerObjectIdentifier DsaWithSha384 = new DerObjectIdentifier(IdDsaWithSha2 + ".3"); + public static readonly DerObjectIdentifier DsaWithSha512 = new DerObjectIdentifier(IdDsaWithSha2 + ".4"); + + /** 2.16.840.1.101.3.4.3.5 */ + public static readonly DerObjectIdentifier IdDsaWithSha3_224 = new DerObjectIdentifier(IdDsaWithSha2 + ".5"); + /** 2.16.840.1.101.3.4.3.6 */ + public static readonly DerObjectIdentifier IdDsaWithSha3_256 = new DerObjectIdentifier(IdDsaWithSha2 + ".6"); + /** 2.16.840.1.101.3.4.3.7 */ + public static readonly DerObjectIdentifier IdDsaWithSha3_384 = new DerObjectIdentifier(IdDsaWithSha2 + ".7"); + /** 2.16.840.1.101.3.4.3.8 */ + public static readonly DerObjectIdentifier IdDsaWithSha3_512 = new DerObjectIdentifier(IdDsaWithSha2 + ".8"); + + // ECDSA with SHA-3 + /** 2.16.840.1.101.3.4.3.9 */ + public static readonly DerObjectIdentifier IdEcdsaWithSha3_224 = new DerObjectIdentifier(IdDsaWithSha2 + ".9"); + /** 2.16.840.1.101.3.4.3.10 */ + public static readonly DerObjectIdentifier IdEcdsaWithSha3_256 = new DerObjectIdentifier(IdDsaWithSha2 + ".10"); + /** 2.16.840.1.101.3.4.3.11 */ + public static readonly DerObjectIdentifier IdEcdsaWithSha3_384 = new DerObjectIdentifier(IdDsaWithSha2 + ".11"); + /** 2.16.840.1.101.3.4.3.12 */ + public static readonly DerObjectIdentifier IdEcdsaWithSha3_512 = new DerObjectIdentifier(IdDsaWithSha2 + ".12"); + + // RSA PKCS #1 v1.5 Signature with SHA-3 family. + /** 2.16.840.1.101.3.4.3.9 */ + public static readonly DerObjectIdentifier IdRsassaPkcs1V15WithSha3_224 = new DerObjectIdentifier(IdDsaWithSha2 + ".13"); + /** 2.16.840.1.101.3.4.3.10 */ + public static readonly DerObjectIdentifier IdRsassaPkcs1V15WithSha3_256 = new DerObjectIdentifier(IdDsaWithSha2 + ".14"); + /** 2.16.840.1.101.3.4.3.11 */ + public static readonly DerObjectIdentifier IdRsassaPkcs1V15WithSha3_384 = new DerObjectIdentifier(IdDsaWithSha2 + ".15"); + /** 2.16.840.1.101.3.4.3.12 */ + public static readonly DerObjectIdentifier IdRsassaPkcs1V15WithSha3_512 = new DerObjectIdentifier(IdDsaWithSha2 + ".16"); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/nist/NISTObjectIdentifiers.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/nist/NISTObjectIdentifiers.cs.meta new file mode 100644 index 0000000..2f790ee --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/nist/NISTObjectIdentifiers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6fa7b36b5f7e2a04ea6f33ddf0db2733 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/nsri.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/nsri.meta new file mode 100644 index 0000000..27550b7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/nsri.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c3292af98b04b1545a9c53fd794b23c8 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/nsri/NsriObjectIdentifiers.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/nsri/NsriObjectIdentifiers.cs new file mode 100644 index 0000000..69d393f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/nsri/NsriObjectIdentifiers.cs @@ -0,0 +1,59 @@ +using System; + +namespace Org.BouncyCastle.Asn1.Nsri +{ + public sealed class NsriObjectIdentifiers + { + public static readonly DerObjectIdentifier nsri = new DerObjectIdentifier("1.2.410.200046"); + + public static readonly DerObjectIdentifier id_algorithm = nsri.Branch("1"); + + public static readonly DerObjectIdentifier id_sea = id_algorithm.Branch("1"); + public static readonly DerObjectIdentifier id_pad = id_algorithm.Branch("2"); + + public static readonly DerObjectIdentifier id_pad_null = id_algorithm.Branch("0"); + public static readonly DerObjectIdentifier id_pad_1 = id_algorithm.Branch("1"); + + public static readonly DerObjectIdentifier id_aria128_ecb = id_sea.Branch("1"); + public static readonly DerObjectIdentifier id_aria128_cbc = id_sea.Branch("2"); + public static readonly DerObjectIdentifier id_aria128_cfb = id_sea.Branch("3"); + public static readonly DerObjectIdentifier id_aria128_ofb = id_sea.Branch("4"); + public static readonly DerObjectIdentifier id_aria128_ctr = id_sea.Branch("5"); + + public static readonly DerObjectIdentifier id_aria192_ecb = id_sea.Branch("6"); + public static readonly DerObjectIdentifier id_aria192_cbc = id_sea.Branch("7"); + public static readonly DerObjectIdentifier id_aria192_cfb = id_sea.Branch("8"); + public static readonly DerObjectIdentifier id_aria192_ofb = id_sea.Branch("9"); + public static readonly DerObjectIdentifier id_aria192_ctr = id_sea.Branch("10"); + + public static readonly DerObjectIdentifier id_aria256_ecb = id_sea.Branch("11"); + public static readonly DerObjectIdentifier id_aria256_cbc = id_sea.Branch("12"); + public static readonly DerObjectIdentifier id_aria256_cfb = id_sea.Branch("13"); + public static readonly DerObjectIdentifier id_aria256_ofb = id_sea.Branch("14"); + public static readonly DerObjectIdentifier id_aria256_ctr = id_sea.Branch("15"); + + public static readonly DerObjectIdentifier id_aria128_cmac = id_sea.Branch("21"); + public static readonly DerObjectIdentifier id_aria192_cmac = id_sea.Branch("22"); + public static readonly DerObjectIdentifier id_aria256_cmac = id_sea.Branch("23"); + + public static readonly DerObjectIdentifier id_aria128_ocb2 = id_sea.Branch("31"); + public static readonly DerObjectIdentifier id_aria192_ocb2 = id_sea.Branch("32"); + public static readonly DerObjectIdentifier id_aria256_ocb2 = id_sea.Branch("33"); + + public static readonly DerObjectIdentifier id_aria128_gcm = id_sea.Branch("34"); + public static readonly DerObjectIdentifier id_aria192_gcm = id_sea.Branch("35"); + public static readonly DerObjectIdentifier id_aria256_gcm = id_sea.Branch("36"); + + public static readonly DerObjectIdentifier id_aria128_ccm = id_sea.Branch("37"); + public static readonly DerObjectIdentifier id_aria192_ccm = id_sea.Branch("38"); + public static readonly DerObjectIdentifier id_aria256_ccm = id_sea.Branch("39"); + + public static readonly DerObjectIdentifier id_aria128_kw = id_sea.Branch("40"); + public static readonly DerObjectIdentifier id_aria192_kw = id_sea.Branch("41"); + public static readonly DerObjectIdentifier id_aria256_kw = id_sea.Branch("42"); + + public static readonly DerObjectIdentifier id_aria128_kwp = id_sea.Branch("43"); + public static readonly DerObjectIdentifier id_aria192_kwp = id_sea.Branch("44"); + public static readonly DerObjectIdentifier id_aria256_kwp = id_sea.Branch("45"); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/nsri/NsriObjectIdentifiers.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/nsri/NsriObjectIdentifiers.cs.meta new file mode 100644 index 0000000..f0092a6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/nsri/NsriObjectIdentifiers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 817f5005b6850d2499a809fe145dd0fc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ntt.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ntt.meta new file mode 100644 index 0000000..de71b78 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ntt.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5c615192c2f7ce24cb4f61964e8a18cd +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ntt/NTTObjectIdentifiers.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ntt/NTTObjectIdentifiers.cs new file mode 100644 index 0000000..cd25956 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ntt/NTTObjectIdentifiers.cs @@ -0,0 +1,14 @@ +namespace Org.BouncyCastle.Asn1.Ntt +{ + /// From RFC 3657 + public abstract class NttObjectIdentifiers + { + public static readonly DerObjectIdentifier IdCamellia128Cbc = new DerObjectIdentifier("1.2.392.200011.61.1.1.1.2"); + public static readonly DerObjectIdentifier IdCamellia192Cbc = new DerObjectIdentifier("1.2.392.200011.61.1.1.1.3"); + public static readonly DerObjectIdentifier IdCamellia256Cbc = new DerObjectIdentifier("1.2.392.200011.61.1.1.1.4"); + + public static readonly DerObjectIdentifier IdCamellia128Wrap = new DerObjectIdentifier("1.2.392.200011.61.1.1.3.2"); + public static readonly DerObjectIdentifier IdCamellia192Wrap = new DerObjectIdentifier("1.2.392.200011.61.1.1.3.3"); + public static readonly DerObjectIdentifier IdCamellia256Wrap = new DerObjectIdentifier("1.2.392.200011.61.1.1.3.4"); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ntt/NTTObjectIdentifiers.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ntt/NTTObjectIdentifiers.cs.meta new file mode 100644 index 0000000..135fbc5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ntt/NTTObjectIdentifiers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ac8cbeac184f4d543a903d64f545eae2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp.meta new file mode 100644 index 0000000..fa18e1c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7c0cea57e64fac147a3e0ca49b0fc11e +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/BasicOCSPResponse.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/BasicOCSPResponse.cs new file mode 100644 index 0000000..45dadba --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/BasicOCSPResponse.cs @@ -0,0 +1,131 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Ocsp +{ + public class BasicOcspResponse + : Asn1Encodable + { + private readonly ResponseData tbsResponseData; + private readonly AlgorithmIdentifier signatureAlgorithm; + private readonly DerBitString signature; + private readonly Asn1Sequence certs; + + public static BasicOcspResponse GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static BasicOcspResponse GetInstance( + object obj) + { + if (obj == null || obj is BasicOcspResponse) + { + return (BasicOcspResponse)obj; + } + + if (obj is Asn1Sequence) + { + return new BasicOcspResponse((Asn1Sequence)obj); + } + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + public BasicOcspResponse( + ResponseData tbsResponseData, + AlgorithmIdentifier signatureAlgorithm, + DerBitString signature, + Asn1Sequence certs) + { + this.tbsResponseData = tbsResponseData; + this.signatureAlgorithm = signatureAlgorithm; + this.signature = signature; + this.certs = certs; + } + + private BasicOcspResponse( + Asn1Sequence seq) + { + this.tbsResponseData = ResponseData.GetInstance(seq[0]); + this.signatureAlgorithm = AlgorithmIdentifier.GetInstance(seq[1]); + this.signature = (DerBitString)seq[2]; + + if (seq.Count > 3) + { + this.certs = Asn1Sequence.GetInstance((Asn1TaggedObject)seq[3], true); + } + } + + [Obsolete("Use TbsResponseData property instead")] + public ResponseData GetTbsResponseData() + { + return tbsResponseData; + } + + public ResponseData TbsResponseData + { + get { return tbsResponseData; } + } + + [Obsolete("Use SignatureAlgorithm property instead")] + public AlgorithmIdentifier GetSignatureAlgorithm() + { + return signatureAlgorithm; + } + + public AlgorithmIdentifier SignatureAlgorithm + { + get { return signatureAlgorithm; } + } + + [Obsolete("Use Signature property instead")] + public DerBitString GetSignature() + { + return signature; + } + + public DerBitString Signature + { + get { return signature; } + } + + public byte[] GetSignatureOctets() + { + return signature.GetOctets(); + } + + [Obsolete("Use Certs property instead")] + public Asn1Sequence GetCerts() + { + return certs; + } + + public Asn1Sequence Certs + { + get { return certs; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * BasicOcspResponse       ::= Sequence {
+         *      tbsResponseData      ResponseData,
+         *      signatureAlgorithm   AlgorithmIdentifier,
+         *      signature            BIT STRING,
+         *      certs                [0] EXPLICIT Sequence OF Certificate OPTIONAL }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(tbsResponseData, signatureAlgorithm, signature); + v.AddOptionalTagged(true, 0, certs); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/BasicOCSPResponse.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/BasicOCSPResponse.cs.meta new file mode 100644 index 0000000..f15dc6f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/BasicOCSPResponse.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a6822bd1732881245a1b3f5f6d6c37ec +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/CertID.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/CertID.cs new file mode 100644 index 0000000..523f6b8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/CertID.cs @@ -0,0 +1,99 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Ocsp +{ + public class CertID + : Asn1Encodable + { + private readonly AlgorithmIdentifier hashAlgorithm; + private readonly Asn1OctetString issuerNameHash; + private readonly Asn1OctetString issuerKeyHash; + private readonly DerInteger serialNumber; + + public static CertID GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static CertID GetInstance( + object obj) + { + if (obj == null || obj is CertID) + { + return (CertID)obj; + } + + if (obj is Asn1Sequence) + { + return new CertID((Asn1Sequence)obj); + } + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + public CertID( + AlgorithmIdentifier hashAlgorithm, + Asn1OctetString issuerNameHash, + Asn1OctetString issuerKeyHash, + DerInteger serialNumber) + { + this.hashAlgorithm = hashAlgorithm; + this.issuerNameHash = issuerNameHash; + this.issuerKeyHash = issuerKeyHash; + this.serialNumber = serialNumber; + } + + private CertID( + Asn1Sequence seq) + { + if (seq.Count != 4) + throw new ArgumentException("Wrong number of elements in sequence", "seq"); + + this.hashAlgorithm = AlgorithmIdentifier.GetInstance(seq[0]); + this.issuerNameHash = Asn1OctetString.GetInstance(seq[1]); + this.issuerKeyHash = Asn1OctetString.GetInstance(seq[2]); + this.serialNumber = DerInteger.GetInstance(seq[3]); + } + + public AlgorithmIdentifier HashAlgorithm + { + get { return hashAlgorithm; } + } + + public Asn1OctetString IssuerNameHash + { + get { return issuerNameHash; } + } + + public Asn1OctetString IssuerKeyHash + { + get { return issuerKeyHash; } + } + + public DerInteger SerialNumber + { + get { return serialNumber; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * CertID          ::=     Sequence {
+         *     hashAlgorithm       AlgorithmIdentifier,
+         *     issuerNameHash      OCTET STRING, -- Hash of Issuer's DN
+         *     issuerKeyHash       OCTET STRING, -- Hash of Issuers public key
+         *     serialNumber        CertificateSerialNumber }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + return new DerSequence(hashAlgorithm, issuerNameHash, issuerKeyHash, serialNumber); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/CertID.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/CertID.cs.meta new file mode 100644 index 0000000..30baf33 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/CertID.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1291c6c4f701ea04b8d36d7ca14c16fc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/CertStatus.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/CertStatus.cs new file mode 100644 index 0000000..7dd99b8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/CertStatus.cs @@ -0,0 +1,96 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Ocsp +{ + public class CertStatus + : Asn1Encodable, IAsn1Choice + { + private readonly int tagNo; + private readonly Asn1Encodable value; + + /** + * create a CertStatus object with a tag of zero. + */ + public CertStatus() + { + tagNo = 0; + value = DerNull.Instance; + } + + public CertStatus( + RevokedInfo info) + { + tagNo = 1; + value = info; + } + + public CertStatus( + int tagNo, + Asn1Encodable value) + { + this.tagNo = tagNo; + this.value = value; + } + + public CertStatus( + Asn1TaggedObject choice) + { + this.tagNo = choice.TagNo; + + switch (choice.TagNo) + { + case 1: + value = RevokedInfo.GetInstance(choice, false); + break; + case 0: + case 2: + value = DerNull.Instance; + break; + default: + throw new ArgumentException("Unknown tag encountered: " + choice.TagNo); + } + } + + public static CertStatus GetInstance( + object obj) + { + if (obj == null || obj is CertStatus) + { + return (CertStatus)obj; + } + + if (obj is Asn1TaggedObject) + { + return new CertStatus((Asn1TaggedObject)obj); + } + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + public int TagNo + { + get { return tagNo; } + } + + public Asn1Encodable Status + { + get { return value; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         *  CertStatus ::= CHOICE {
+         *                  good        [0]     IMPLICIT Null,
+         *                  revoked     [1]     IMPLICIT RevokedInfo,
+         *                  unknown     [2]     IMPLICIT UnknownInfo }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + return new DerTaggedObject(false, tagNo, value); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/CertStatus.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/CertStatus.cs.meta new file mode 100644 index 0000000..526827f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/CertStatus.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 567357627b42be046853cbc2d01e93c6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/CrlID.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/CrlID.cs new file mode 100644 index 0000000..3b3869a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/CrlID.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections; + +namespace Org.BouncyCastle.Asn1.Ocsp +{ + public class CrlID + : Asn1Encodable + { + private readonly DerIA5String crlUrl; + private readonly DerInteger crlNum; + private readonly DerGeneralizedTime crlTime; + + // TODO Add GetInstance method(s) and amke this private? + public CrlID( + Asn1Sequence seq) + { + foreach (Asn1TaggedObject o in seq) + { + switch (o.TagNo) + { + case 0: + crlUrl = DerIA5String.GetInstance(o, true); + break; + case 1: + crlNum = DerInteger.GetInstance(o, true); + break; + case 2: + crlTime = DerGeneralizedTime.GetInstance(o, true); + break; + default: + throw new ArgumentException("unknown tag number: " + o.TagNo); + } + } + } + + public DerIA5String CrlUrl + { + get { return crlUrl; } + } + + public DerInteger CrlNum + { + get { return crlNum; } + } + + public DerGeneralizedTime CrlTime + { + get { return crlTime; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * CrlID ::= Sequence {
+         *     crlUrl               [0]     EXPLICIT IA5String OPTIONAL,
+         *     crlNum               [1]     EXPLICIT Integer OPTIONAL,
+         *     crlTime              [2]     EXPLICIT GeneralizedTime OPTIONAL }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + v.AddOptionalTagged(true, 0, crlUrl); + v.AddOptionalTagged(true, 1, crlNum); + v.AddOptionalTagged(true, 2, crlTime); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/CrlID.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/CrlID.cs.meta new file mode 100644 index 0000000..1294575 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/CrlID.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bf09917f65a3161418923d29560a5173 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/OCSPObjectIdentifiers.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/OCSPObjectIdentifiers.cs new file mode 100644 index 0000000..a37c855 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/OCSPObjectIdentifiers.cs @@ -0,0 +1,23 @@ +using Org.BouncyCastle.Asn1; + +namespace Org.BouncyCastle.Asn1.Ocsp +{ + public abstract class OcspObjectIdentifiers + { + internal const string PkixOcspId = "1.3.6.1.5.5.7.48.1"; + + public static readonly DerObjectIdentifier PkixOcsp = new DerObjectIdentifier(PkixOcspId); + public static readonly DerObjectIdentifier PkixOcspBasic = new DerObjectIdentifier(PkixOcspId + ".1"); + + // + // extensions + // + public static readonly DerObjectIdentifier PkixOcspNonce = new DerObjectIdentifier(PkixOcsp + ".2"); + public static readonly DerObjectIdentifier PkixOcspCrl = new DerObjectIdentifier(PkixOcsp + ".3"); + + public static readonly DerObjectIdentifier PkixOcspResponse = new DerObjectIdentifier(PkixOcsp + ".4"); + public static readonly DerObjectIdentifier PkixOcspNocheck = new DerObjectIdentifier(PkixOcsp + ".5"); + public static readonly DerObjectIdentifier PkixOcspArchiveCutoff = new DerObjectIdentifier(PkixOcsp + ".6"); + public static readonly DerObjectIdentifier PkixOcspServiceLocator = new DerObjectIdentifier(PkixOcsp + ".7"); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/OCSPObjectIdentifiers.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/OCSPObjectIdentifiers.cs.meta new file mode 100644 index 0000000..aae6cab --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/OCSPObjectIdentifiers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fffe67553aa4d89499e8ed2d51297cd4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/OCSPRequest.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/OCSPRequest.cs new file mode 100644 index 0000000..6ecd29c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/OCSPRequest.cs @@ -0,0 +1,84 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Ocsp +{ + public class OcspRequest + : Asn1Encodable + { + private readonly TbsRequest tbsRequest; + private readonly Signature optionalSignature; + + public static OcspRequest GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static OcspRequest GetInstance( + object obj) + { + if (obj == null || obj is OcspRequest) + { + return (OcspRequest)obj; + } + + if (obj is Asn1Sequence) + { + return new OcspRequest((Asn1Sequence)obj); + } + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + public OcspRequest( + TbsRequest tbsRequest, + Signature optionalSignature) + { + if (tbsRequest == null) + throw new ArgumentNullException("tbsRequest"); + + this.tbsRequest = tbsRequest; + this.optionalSignature = optionalSignature; + } + + private OcspRequest( + Asn1Sequence seq) + { + tbsRequest = TbsRequest.GetInstance(seq[0]); + + if (seq.Count == 2) + { + optionalSignature = Signature.GetInstance( + (Asn1TaggedObject)seq[1], true); + } + } + + public TbsRequest TbsRequest + { + get { return tbsRequest; } + } + + public Signature OptionalSignature + { + get { return optionalSignature; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * OcspRequest     ::=     Sequence {
+         *     tbsRequest                  TBSRequest,
+         *     optionalSignature   [0]     EXPLICIT Signature OPTIONAL }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(tbsRequest); + v.AddOptionalTagged(true, 0, optionalSignature); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/OCSPRequest.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/OCSPRequest.cs.meta new file mode 100644 index 0000000..db861f0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/OCSPRequest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5fa15f7a470eaf2479604f4506033a9c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/OCSPResponse.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/OCSPResponse.cs new file mode 100644 index 0000000..6491729 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/OCSPResponse.cs @@ -0,0 +1,85 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Ocsp +{ + public class OcspResponse + : Asn1Encodable + { + private readonly OcspResponseStatus responseStatus; + private readonly ResponseBytes responseBytes; + + public static OcspResponse GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static OcspResponse GetInstance( + object obj) + { + if (obj == null || obj is OcspResponse) + { + return (OcspResponse)obj; + } + + if (obj is Asn1Sequence) + { + return new OcspResponse((Asn1Sequence)obj); + } + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + public OcspResponse( + OcspResponseStatus responseStatus, + ResponseBytes responseBytes) + { + if (responseStatus == null) + throw new ArgumentNullException("responseStatus"); + + this.responseStatus = responseStatus; + this.responseBytes = responseBytes; + } + + private OcspResponse( + Asn1Sequence seq) + { + responseStatus = new OcspResponseStatus( + DerEnumerated.GetInstance(seq[0])); + + if (seq.Count == 2) + { + responseBytes = ResponseBytes.GetInstance( + (Asn1TaggedObject)seq[1], true); + } + } + + public OcspResponseStatus ResponseStatus + { + get { return responseStatus; } + } + + public ResponseBytes ResponseBytes + { + get { return responseBytes; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * OcspResponse ::= Sequence {
+         *     responseStatus         OcspResponseStatus,
+         *     responseBytes          [0] EXPLICIT ResponseBytes OPTIONAL }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(responseStatus); + v.AddOptionalTagged(true, 0, responseBytes); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/OCSPResponse.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/OCSPResponse.cs.meta new file mode 100644 index 0000000..aa73292 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/OCSPResponse.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f3d74019f162b1a4cbd2ac36ae30bb75 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/OCSPResponseStatus.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/OCSPResponseStatus.cs new file mode 100644 index 0000000..cf52c73 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/OCSPResponseStatus.cs @@ -0,0 +1,41 @@ +using System; + +using Org.BouncyCastle.Asn1; + +namespace Org.BouncyCastle.Asn1.Ocsp +{ + public class OcspResponseStatus + : DerEnumerated + { + public const int Successful = 0; + public const int MalformedRequest = 1; + public const int InternalError = 2; + public const int TryLater = 3; + public const int SignatureRequired = 5; + public const int Unauthorized = 6; + + /** + * The OcspResponseStatus enumeration. + *
+         * OcspResponseStatus ::= Enumerated {
+         *     successful            (0),  --Response has valid confirmations
+         *     malformedRequest      (1),  --Illegal confirmation request
+         *     internalError         (2),  --Internal error in issuer
+         *     tryLater              (3),  --Try again later
+         *                                 --(4) is not used
+         *     sigRequired           (5),  --Must sign the request
+         *     unauthorized          (6)   --Request unauthorized
+         * }
+         * 
+ */ + public OcspResponseStatus(int value) + : base(value) + { + } + + public OcspResponseStatus(DerEnumerated value) + : base(value.IntValueExact) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/OCSPResponseStatus.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/OCSPResponseStatus.cs.meta new file mode 100644 index 0000000..f31d880 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/OCSPResponseStatus.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3731e934210d5f546a11ff552ade9d6b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/Request.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/Request.cs new file mode 100644 index 0000000..21121cb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/Request.cs @@ -0,0 +1,86 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Ocsp +{ + public class Request + : Asn1Encodable + { + private readonly CertID reqCert; + private readonly X509Extensions singleRequestExtensions; + + public static Request GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static Request GetInstance( + object obj) + { + if (obj == null || obj is Request) + { + return (Request)obj; + } + + if (obj is Asn1Sequence) + { + return new Request((Asn1Sequence)obj); + } + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + public Request( + CertID reqCert, + X509Extensions singleRequestExtensions) + { + if (reqCert == null) + throw new ArgumentNullException("reqCert"); + + this.reqCert = reqCert; + this.singleRequestExtensions = singleRequestExtensions; + } + + private Request( + Asn1Sequence seq) + { + reqCert = CertID.GetInstance(seq[0]); + + if (seq.Count == 2) + { + singleRequestExtensions = X509Extensions.GetInstance( + (Asn1TaggedObject)seq[1], true); + } + } + + public CertID ReqCert + { + get { return reqCert; } + } + + public X509Extensions SingleRequestExtensions + { + get { return singleRequestExtensions; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * Request         ::=     Sequence {
+         *     reqCert                     CertID,
+         *     singleRequestExtensions     [0] EXPLICIT Extensions OPTIONAL }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(reqCert); + v.AddOptionalTagged(true, 0, singleRequestExtensions); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/Request.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/Request.cs.meta new file mode 100644 index 0000000..6938b64 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/Request.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ce95086ab3b7ead478409315521b1c8d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/ResponderID.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/ResponderID.cs new file mode 100644 index 0000000..143b173 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/ResponderID.cs @@ -0,0 +1,107 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; + +namespace Org.BouncyCastle.Asn1.Ocsp +{ + public class ResponderID + : Asn1Encodable, IAsn1Choice + { + private readonly Asn1Encodable id; + + public static ResponderID GetInstance( + object obj) + { + if (obj == null || obj is ResponderID) + { + return (ResponderID)obj; + } + + if (obj is DerOctetString) + { + return new ResponderID((DerOctetString)obj); + } + + if (obj is Asn1TaggedObject) + { + Asn1TaggedObject o = (Asn1TaggedObject)obj; + + if (o.TagNo == 1) + { + return new ResponderID(X509Name.GetInstance(o, true)); + } + + return new ResponderID(Asn1OctetString.GetInstance(o, true)); + } + + return new ResponderID(X509Name.GetInstance(obj)); + } + + public ResponderID( + Asn1OctetString id) + { + if (id == null) + throw new ArgumentNullException("id"); + + this.id = id; + } + + public ResponderID( + X509Name id) + { + if (id == null) + throw new ArgumentNullException("id"); + + this.id = id; + } + + public static ResponderID GetInstance( + Asn1TaggedObject obj, + bool isExplicit) + { + return GetInstance(obj.GetObject()); // must be explicitly tagged + } + + public virtual byte[] GetKeyHash() + { + if (id is Asn1OctetString) + { + return ((Asn1OctetString)id).GetOctets(); + } + + return null; + } + + public virtual X509Name Name + { + get + { + if (id is Asn1OctetString) + { + return null; + } + + return X509Name.GetInstance(id); + } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * ResponderID ::= CHOICE {
+         *      byName          [1] Name,
+         *      byKey           [2] KeyHash }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + if (id is Asn1OctetString) + { + return new DerTaggedObject(true, 2, id); + } + + return new DerTaggedObject(true, 1, id); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/ResponderID.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/ResponderID.cs.meta new file mode 100644 index 0000000..beffd62 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/ResponderID.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 419b21fa5edd2a2419f6bdb7e26a2735 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/ResponseBytes.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/ResponseBytes.cs new file mode 100644 index 0000000..d3ea044 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/ResponseBytes.cs @@ -0,0 +1,82 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Ocsp +{ + public class ResponseBytes + : Asn1Encodable + { + private readonly DerObjectIdentifier responseType; + private readonly Asn1OctetString response; + + public static ResponseBytes GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static ResponseBytes GetInstance( + object obj) + { + if (obj == null || obj is ResponseBytes) + { + return (ResponseBytes)obj; + } + + if (obj is Asn1Sequence) + { + return new ResponseBytes((Asn1Sequence)obj); + } + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + public ResponseBytes( + DerObjectIdentifier responseType, + Asn1OctetString response) + { + if (responseType == null) + throw new ArgumentNullException("responseType"); + if (response == null) + throw new ArgumentNullException("response"); + + this.responseType = responseType; + this.response = response; + } + + private ResponseBytes( + Asn1Sequence seq) + { + if (seq.Count != 2) + throw new ArgumentException("Wrong number of elements in sequence", "seq"); + + this.responseType = DerObjectIdentifier.GetInstance(seq[0]); + this.response = Asn1OctetString.GetInstance(seq[1]); + } + + public DerObjectIdentifier ResponseType + { + get { return responseType; } + } + + public Asn1OctetString Response + { + get { return response; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * ResponseBytes ::=       Sequence {
+         *     responseType   OBJECT IDENTIFIER,
+         *     response       OCTET STRING }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + return new DerSequence(responseType, response); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/ResponseBytes.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/ResponseBytes.cs.meta new file mode 100644 index 0000000..b2f8ee6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/ResponseBytes.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5ed9f75ffceca4d4a8f84a0cfd3cc433 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/ResponseData.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/ResponseData.cs new file mode 100644 index 0000000..a5769c0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/ResponseData.cs @@ -0,0 +1,153 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Ocsp +{ + public class ResponseData + : Asn1Encodable + { + private static readonly DerInteger V1 = new DerInteger(0); + + private readonly bool versionPresent; + private readonly DerInteger version; + private readonly ResponderID responderID; + private readonly DerGeneralizedTime producedAt; + private readonly Asn1Sequence responses; + private readonly X509Extensions responseExtensions; + + public static ResponseData GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static ResponseData GetInstance( + object obj) + { + if (obj == null || obj is ResponseData) + { + return (ResponseData)obj; + } + + if (obj is Asn1Sequence) + { + return new ResponseData((Asn1Sequence)obj); + } + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + public ResponseData( + DerInteger version, + ResponderID responderID, + DerGeneralizedTime producedAt, + Asn1Sequence responses, + X509Extensions responseExtensions) + { + this.version = version; + this.responderID = responderID; + this.producedAt = producedAt; + this.responses = responses; + this.responseExtensions = responseExtensions; + } + + public ResponseData( + ResponderID responderID, + DerGeneralizedTime producedAt, + Asn1Sequence responses, + X509Extensions responseExtensions) + : this(V1, responderID, producedAt, responses, responseExtensions) + { + } + + private ResponseData( + Asn1Sequence seq) + { + int index = 0; + + Asn1Encodable enc = seq[0]; + if (enc is Asn1TaggedObject) + { + Asn1TaggedObject o = (Asn1TaggedObject)enc; + + if (o.TagNo == 0) + { + this.versionPresent = true; + this.version = DerInteger.GetInstance(o, true); + index++; + } + else + { + this.version = V1; + } + } + else + { + this.version = V1; + } + + this.responderID = ResponderID.GetInstance(seq[index++]); + this.producedAt = (DerGeneralizedTime)seq[index++]; + this.responses = (Asn1Sequence)seq[index++]; + + if (seq.Count > index) + { + this.responseExtensions = X509Extensions.GetInstance( + (Asn1TaggedObject)seq[index], true); + } + } + + public DerInteger Version + { + get { return version; } + } + + public ResponderID ResponderID + { + get { return responderID; } + } + + public DerGeneralizedTime ProducedAt + { + get { return producedAt; } + } + + public Asn1Sequence Responses + { + get { return responses; } + } + + public X509Extensions ResponseExtensions + { + get { return responseExtensions; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * ResponseData ::= Sequence {
+         *     version              [0] EXPLICIT Version DEFAULT v1,
+         *     responderID              ResponderID,
+         *     producedAt               GeneralizedTime,
+         *     responses                Sequence OF SingleResponse,
+         *     responseExtensions   [1] EXPLICIT Extensions OPTIONAL }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + + if (versionPresent || !version.Equals(V1)) + { + v.Add(new DerTaggedObject(true, 0, version)); + } + + v.Add(responderID, producedAt, responses); + v.AddOptionalTagged(true, 1, responseExtensions); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/ResponseData.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/ResponseData.cs.meta new file mode 100644 index 0000000..448db3d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/ResponseData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 721d8544eac173d479697ac0526e2587 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/RevokedInfo.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/RevokedInfo.cs new file mode 100644 index 0000000..c67be06 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/RevokedInfo.cs @@ -0,0 +1,91 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Ocsp +{ + public class RevokedInfo + : Asn1Encodable + { + private readonly DerGeneralizedTime revocationTime; + private readonly CrlReason revocationReason; + + public static RevokedInfo GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static RevokedInfo GetInstance( + object obj) + { + if (obj == null || obj is RevokedInfo) + { + return (RevokedInfo) obj; + } + + if (obj is Asn1Sequence) + { + return new RevokedInfo((Asn1Sequence) obj); + } + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + public RevokedInfo( + DerGeneralizedTime revocationTime) + : this(revocationTime, null) + { + } + + public RevokedInfo( + DerGeneralizedTime revocationTime, + CrlReason revocationReason) + { + if (revocationTime == null) + throw new ArgumentNullException("revocationTime"); + + this.revocationTime = revocationTime; + this.revocationReason = revocationReason; + } + + private RevokedInfo( + Asn1Sequence seq) + { + this.revocationTime = (DerGeneralizedTime) seq[0]; + + if (seq.Count > 1) + { + this.revocationReason = new CrlReason( + DerEnumerated.GetInstance((Asn1TaggedObject) seq[1], true)); + } + } + + public DerGeneralizedTime RevocationTime + { + get { return revocationTime; } + } + + public CrlReason RevocationReason + { + get { return revocationReason; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * RevokedInfo ::= Sequence {
+         *      revocationTime              GeneralizedTime,
+         *      revocationReason    [0]     EXPLICIT CRLReason OPTIONAL }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(revocationTime); + v.AddOptionalTagged(true, 0, revocationReason); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/RevokedInfo.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/RevokedInfo.cs.meta new file mode 100644 index 0000000..8a2df5e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/RevokedInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 362a202b44a39c240bb5a552ebbc9ae5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/ServiceLocator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/ServiceLocator.cs new file mode 100644 index 0000000..c6a9514 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/ServiceLocator.cs @@ -0,0 +1,90 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Ocsp +{ + public class ServiceLocator + : Asn1Encodable + { + private readonly X509Name issuer; + private readonly Asn1Object locator; + + public static ServiceLocator GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static ServiceLocator GetInstance( + object obj) + { + if (obj == null || obj is ServiceLocator) + { + return (ServiceLocator) obj; + } + + if (obj is Asn1Sequence) + { + return new ServiceLocator((Asn1Sequence) obj); + } + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + public ServiceLocator( + X509Name issuer) + : this(issuer, null) + { + } + + public ServiceLocator( + X509Name issuer, + Asn1Object locator) + { + if (issuer == null) + throw new ArgumentNullException("issuer"); + + this.issuer = issuer; + this.locator = locator; + } + + private ServiceLocator( + Asn1Sequence seq) + { + this.issuer = X509Name.GetInstance(seq[0]); + + if (seq.Count > 1) + { + this.locator = seq[1].ToAsn1Object(); + } + } + + public X509Name Issuer + { + get { return issuer; } + } + + public Asn1Object Locator + { + get { return locator; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * ServiceLocator ::= Sequence {
+         *     issuer    Name,
+         *     locator   AuthorityInfoAccessSyntax OPTIONAL }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(issuer); + v.AddOptional(locator); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/ServiceLocator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/ServiceLocator.cs.meta new file mode 100644 index 0000000..c5214b0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/ServiceLocator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4bb05a4b9fde96d43b343d88571c945b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/Signature.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/Signature.cs new file mode 100644 index 0000000..c6f149d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/Signature.cs @@ -0,0 +1,109 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Ocsp +{ + public class Signature + : Asn1Encodable + { + internal AlgorithmIdentifier signatureAlgorithm; + internal DerBitString signatureValue; + internal Asn1Sequence certs; + + public static Signature GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static Signature GetInstance( + object obj) + { + if (obj == null || obj is Signature) + { + return (Signature)obj; + } + + if (obj is Asn1Sequence) + { + return new Signature((Asn1Sequence)obj); + } + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + public Signature( + AlgorithmIdentifier signatureAlgorithm, + DerBitString signatureValue) + : this(signatureAlgorithm, signatureValue, null) + { + } + + public Signature( + AlgorithmIdentifier signatureAlgorithm, + DerBitString signatureValue, + Asn1Sequence certs) + { + if (signatureAlgorithm == null) + throw new ArgumentException("signatureAlgorithm"); + if (signatureValue == null) + throw new ArgumentException("signatureValue"); + + this.signatureAlgorithm = signatureAlgorithm; + this.signatureValue = signatureValue; + this.certs = certs; + } + + private Signature( + Asn1Sequence seq) + { + signatureAlgorithm = AlgorithmIdentifier.GetInstance(seq[0]); + signatureValue = (DerBitString)seq[1]; + + if (seq.Count == 3) + { + certs = Asn1Sequence.GetInstance( + (Asn1TaggedObject)seq[2], true); + } + } + + public AlgorithmIdentifier SignatureAlgorithm + { + get { return signatureAlgorithm; } + } + + public DerBitString SignatureValue + { + get { return signatureValue; } + } + + public byte[] GetSignatureOctets() + { + return signatureValue.GetOctets(); + } + + public Asn1Sequence Certs + { + get { return certs; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * Signature       ::=     Sequence {
+         *     signatureAlgorithm      AlgorithmIdentifier,
+         *     signature               BIT STRING,
+         *     certs               [0] EXPLICIT Sequence OF Certificate OPTIONAL}
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(signatureAlgorithm, signatureValue); + v.AddOptionalTagged(true, 0, certs); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/Signature.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/Signature.cs.meta new file mode 100644 index 0000000..72da82a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/Signature.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3a5027f39cb79f84a866661cb09428d2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/SingleResponse.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/SingleResponse.cs new file mode 100644 index 0000000..ecdf3da --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/SingleResponse.cs @@ -0,0 +1,127 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Ocsp +{ + public class SingleResponse + : Asn1Encodable + { + private readonly CertID certID; + private readonly CertStatus certStatus; + private readonly DerGeneralizedTime thisUpdate; + private readonly DerGeneralizedTime nextUpdate; + private readonly X509Extensions singleExtensions; + + public SingleResponse( + CertID certID, + CertStatus certStatus, + DerGeneralizedTime thisUpdate, + DerGeneralizedTime nextUpdate, + X509Extensions singleExtensions) + { + this.certID = certID; + this.certStatus = certStatus; + this.thisUpdate = thisUpdate; + this.nextUpdate = nextUpdate; + this.singleExtensions = singleExtensions; + } + + public SingleResponse( + Asn1Sequence seq) + { + this.certID = CertID.GetInstance(seq[0]); + this.certStatus = CertStatus.GetInstance(seq[1]); + this.thisUpdate = (DerGeneralizedTime)seq[2]; + + if (seq.Count > 4) + { + this.nextUpdate = DerGeneralizedTime.GetInstance( + (Asn1TaggedObject) seq[3], true); + this.singleExtensions = X509Extensions.GetInstance( + (Asn1TaggedObject) seq[4], true); + } + else if (seq.Count > 3) + { + Asn1TaggedObject o = (Asn1TaggedObject) seq[3]; + + if (o.TagNo == 0) + { + this.nextUpdate = DerGeneralizedTime.GetInstance(o, true); + } + else + { + this.singleExtensions = X509Extensions.GetInstance(o, true); + } + } + } + + public static SingleResponse GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static SingleResponse GetInstance( + object obj) + { + if (obj == null || obj is SingleResponse) + { + return (SingleResponse)obj; + } + + if (obj is Asn1Sequence) + { + return new SingleResponse((Asn1Sequence)obj); + } + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + public CertID CertId + { + get { return certID; } + } + + public CertStatus CertStatus + { + get { return certStatus; } + } + + public DerGeneralizedTime ThisUpdate + { + get { return thisUpdate; } + } + + public DerGeneralizedTime NextUpdate + { + get { return nextUpdate; } + } + + public X509Extensions SingleExtensions + { + get { return singleExtensions; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         *  SingleResponse ::= Sequence {
+         *          certID                       CertID,
+         *          certStatus                   CertStatus,
+         *          thisUpdate                   GeneralizedTime,
+         *          nextUpdate         [0]       EXPLICIT GeneralizedTime OPTIONAL,
+         *          singleExtensions   [1]       EXPLICIT Extensions OPTIONAL }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(certID, certStatus, thisUpdate); + v.AddOptionalTagged(true, 0, nextUpdate); + v.AddOptionalTagged(true, 1, singleExtensions); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/SingleResponse.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/SingleResponse.cs.meta new file mode 100644 index 0000000..1d7a452 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/SingleResponse.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3672cfc0df12db9438d47feaa8f1a030 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/TBSRequest.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/TBSRequest.cs new file mode 100644 index 0000000..0166c53 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/TBSRequest.cs @@ -0,0 +1,142 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Ocsp +{ + public class TbsRequest + : Asn1Encodable + { + private static readonly DerInteger V1 = new DerInteger(0); + + private readonly DerInteger version; + private readonly GeneralName requestorName; + private readonly Asn1Sequence requestList; + private readonly X509Extensions requestExtensions; + + private bool versionSet; + + public static TbsRequest GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static TbsRequest GetInstance( + object obj) + { + if (obj == null || obj is TbsRequest) + { + return (TbsRequest)obj; + } + + if (obj is Asn1Sequence) + { + return new TbsRequest((Asn1Sequence)obj); + } + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + public TbsRequest( + GeneralName requestorName, + Asn1Sequence requestList, + X509Extensions requestExtensions) + { + this.version = V1; + this.requestorName = requestorName; + this.requestList = requestList; + this.requestExtensions = requestExtensions; + } + + private TbsRequest( + Asn1Sequence seq) + { + int index = 0; + + Asn1Encodable enc = seq[0]; + if (enc is Asn1TaggedObject) + { + Asn1TaggedObject o = (Asn1TaggedObject) enc; + + if (o.TagNo == 0) + { + versionSet = true; + version = DerInteger.GetInstance(o, true); + index++; + } + else + { + version = V1; + } + } + else + { + version = V1; + } + + if (seq[index] is Asn1TaggedObject) + { + requestorName = GeneralName.GetInstance((Asn1TaggedObject) seq[index++], true); + } + + requestList = (Asn1Sequence) seq[index++]; + + if (seq.Count == (index + 1)) + { + requestExtensions = X509Extensions.GetInstance((Asn1TaggedObject) seq[index], true); + } + } + + public DerInteger Version + { + get { return version; } + } + + public GeneralName RequestorName + { + get { return requestorName; } + } + + public Asn1Sequence RequestList + { + get { return requestList; } + } + + public X509Extensions RequestExtensions + { + get { return requestExtensions; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * TBSRequest      ::=     Sequence {
+         *     version             [0]     EXPLICIT Version DEFAULT v1,
+         *     requestorName       [1]     EXPLICIT GeneralName OPTIONAL,
+         *     requestList                 Sequence OF Request,
+         *     requestExtensions   [2]     EXPLICIT Extensions OPTIONAL }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + + // + // if default don't include - unless explicitly provided. Not strictly correct + // but required for some requests + // + if (!version.Equals(V1) || versionSet) + { + v.Add(new DerTaggedObject(true, 0, version)); + } + + v.AddOptionalTagged(true, 1, requestorName); + v.Add(requestList); + v.AddOptionalTagged(true, 2, requestExtensions); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/TBSRequest.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/TBSRequest.cs.meta new file mode 100644 index 0000000..12f7140 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ocsp/TBSRequest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c8352f15d2bb0ff4ca6becfe5719fa4a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/oiw.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/oiw.meta new file mode 100644 index 0000000..6faee38 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/oiw.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7eb6a0b601ede974097d8de54ee9d9b0 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/oiw/ElGamalParameter.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/oiw/ElGamalParameter.cs new file mode 100644 index 0000000..3e020f0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/oiw/ElGamalParameter.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Asn1.Oiw +{ + public class ElGamalParameter + : Asn1Encodable + { + internal DerInteger p, g; + + public ElGamalParameter( + BigInteger p, + BigInteger g) + { + this.p = new DerInteger(p); + this.g = new DerInteger(g); + } + + public ElGamalParameter( + Asn1Sequence seq) + { + if (seq.Count != 2) + throw new ArgumentException("Wrong number of elements in sequence", "seq"); + + p = DerInteger.GetInstance(seq[0]); + g = DerInteger.GetInstance(seq[1]); + } + + public BigInteger P + { + get { return p.PositiveValue; } + } + + public BigInteger G + { + get { return g.PositiveValue; } + } + + public override Asn1Object ToAsn1Object() + { + return new DerSequence(p, g); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/oiw/ElGamalParameter.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/oiw/ElGamalParameter.cs.meta new file mode 100644 index 0000000..d0e73cf --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/oiw/ElGamalParameter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9bd7d36c36ba7d3469bc07dfd177b5b6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/oiw/OIWObjectIdentifiers.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/oiw/OIWObjectIdentifiers.cs new file mode 100644 index 0000000..3da2263 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/oiw/OIWObjectIdentifiers.cs @@ -0,0 +1,29 @@ +namespace Org.BouncyCastle.Asn1.Oiw +{ + public abstract class OiwObjectIdentifiers + { + public static readonly DerObjectIdentifier MD4WithRsa = new DerObjectIdentifier("1.3.14.3.2.2"); + public static readonly DerObjectIdentifier MD5WithRsa = new DerObjectIdentifier("1.3.14.3.2.3"); + public static readonly DerObjectIdentifier MD4WithRsaEncryption = new DerObjectIdentifier("1.3.14.3.2.4"); + + public static readonly DerObjectIdentifier DesEcb = new DerObjectIdentifier("1.3.14.3.2.6"); + public static readonly DerObjectIdentifier DesCbc = new DerObjectIdentifier("1.3.14.3.2.7"); + public static readonly DerObjectIdentifier DesOfb = new DerObjectIdentifier("1.3.14.3.2.8"); + public static readonly DerObjectIdentifier DesCfb = new DerObjectIdentifier("1.3.14.3.2.9"); + + public static readonly DerObjectIdentifier DesEde = new DerObjectIdentifier("1.3.14.3.2.17"); + + // id-SHA1 OBJECT IDENTIFIER ::= + // {iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) 26 } // + public static readonly DerObjectIdentifier IdSha1 = new DerObjectIdentifier("1.3.14.3.2.26"); + + public static readonly DerObjectIdentifier DsaWithSha1 = new DerObjectIdentifier("1.3.14.3.2.27"); + + public static readonly DerObjectIdentifier Sha1WithRsa = new DerObjectIdentifier("1.3.14.3.2.29"); + + // ElGamal Algorithm OBJECT IDENTIFIER ::= + // {iso(1) identified-organization(3) oiw(14) dirservsig(7) algorithm(2) encryption(1) 1 } + // + public static readonly DerObjectIdentifier ElGamalAlgorithm = new DerObjectIdentifier("1.3.14.7.2.1.1"); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/oiw/OIWObjectIdentifiers.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/oiw/OIWObjectIdentifiers.cs.meta new file mode 100644 index 0000000..51cba79 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/oiw/OIWObjectIdentifiers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ca5eaf760742c4c47954bae2926b1ca5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs.meta new file mode 100644 index 0000000..1a7111e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 48acbcf8f63893a40ab376873df02146 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/Attribute.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/Attribute.cs new file mode 100644 index 0000000..1858285 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/Attribute.cs @@ -0,0 +1,79 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + public class AttributePkcs + : Asn1Encodable + { + private readonly DerObjectIdentifier attrType; + private readonly Asn1Set attrValues; + + /** + * return an Attribute object from the given object. + * + * @param o the object we want converted. + * @exception ArgumentException if the object cannot be converted. + */ + public static AttributePkcs GetInstance( + object obj) + { + AttributePkcs attr = obj as AttributePkcs; + if (obj == null || attr != null) + { + return attr; + } + + Asn1Sequence seq = obj as Asn1Sequence; + if (seq != null) + { + return new AttributePkcs(seq); + } + + throw new ArgumentException("Unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + private AttributePkcs( + Asn1Sequence seq) + { + if (seq.Count != 2) + throw new ArgumentException("Wrong number of elements in sequence", "seq"); + + attrType = DerObjectIdentifier.GetInstance(seq[0]); + attrValues = Asn1Set.GetInstance(seq[1]); + } + + public AttributePkcs( + DerObjectIdentifier attrType, + Asn1Set attrValues) + { + this.attrType = attrType; + this.attrValues = attrValues; + } + + public DerObjectIdentifier AttrType + { + get { return attrType; } + } + + public Asn1Set AttrValues + { + get { return attrValues; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * Attr ::= Sequence {
+         *     attrType OBJECT IDENTIFIER,
+         *     attrValues Set OF AttributeValue
+         * }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + return new DerSequence(attrType, attrValues); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/Attribute.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/Attribute.cs.meta new file mode 100644 index 0000000..3299e43 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/Attribute.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 532995d8d9a70c740a2af79a4e630b0c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/AuthenticatedSafe.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/AuthenticatedSafe.cs new file mode 100644 index 0000000..6f3b4c8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/AuthenticatedSafe.cs @@ -0,0 +1,63 @@ +using System; + +using Org.BouncyCastle.Asn1; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + public class AuthenticatedSafe + : Asn1Encodable + { + private static ContentInfo[] Copy(ContentInfo[] info) + { + return (ContentInfo[])info.Clone(); + } + + public static AuthenticatedSafe GetInstance(object obj) + { + if (obj is AuthenticatedSafe) + return (AuthenticatedSafe)obj; + if (obj == null) + return null; + return new AuthenticatedSafe(Asn1Sequence.GetInstance(obj)); + } + + private readonly ContentInfo[] info; + private readonly bool isBer; + + private AuthenticatedSafe(Asn1Sequence seq) + { + info = new ContentInfo[seq.Count]; + + for (int i = 0; i != info.Length; i++) + { + info[i] = ContentInfo.GetInstance(seq[i]); + } + + isBer = seq is BerSequence; + } + + public AuthenticatedSafe( + ContentInfo[] info) + { + this.info = Copy(info); + this.isBer = true; + } + + public ContentInfo[] GetContentInfo() + { + return Copy(info); + } + + public override Asn1Object ToAsn1Object() + { + if (isBer) + { + return new BerSequence(info); + } + + // TODO bc-java uses DL sequence + //return new DLSequence(info); + return new DerSequence(info); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/AuthenticatedSafe.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/AuthenticatedSafe.cs.meta new file mode 100644 index 0000000..b246072 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/AuthenticatedSafe.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 300e27889f137f040bca4252dba62f12 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/CertBag.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/CertBag.cs new file mode 100644 index 0000000..ddaa353 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/CertBag.cs @@ -0,0 +1,52 @@ +using System; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + public class CertBag + : Asn1Encodable + { + public static CertBag GetInstance(object obj) + { + if (obj is CertBag) + return (CertBag)obj; + if (obj == null) + return null; + return new CertBag(Asn1Sequence.GetInstance(obj)); + } + + private readonly DerObjectIdentifier certID; + private readonly Asn1Object certValue; + + private CertBag(Asn1Sequence seq) + { + if (seq.Count != 2) + throw new ArgumentException("Wrong number of elements in sequence", "seq"); + + this.certID = DerObjectIdentifier.GetInstance(seq[0]); + this.certValue = Asn1TaggedObject.GetInstance(seq[1]).GetObject(); + } + + public CertBag( + DerObjectIdentifier certID, + Asn1Object certValue) + { + this.certID = certID; + this.certValue = certValue; + } + + public virtual DerObjectIdentifier CertID + { + get { return certID; } + } + + public virtual Asn1Object CertValue + { + get { return certValue; } + } + + public override Asn1Object ToAsn1Object() + { + return new DerSequence(certID, new DerTaggedObject(0, certValue)); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/CertBag.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/CertBag.cs.meta new file mode 100644 index 0000000..cf1f67a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/CertBag.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 17df03278a59589419b10814780f9227 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/CertificationRequest.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/CertificationRequest.cs new file mode 100644 index 0000000..98caa22 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/CertificationRequest.cs @@ -0,0 +1,87 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + /** + * Pkcs10 Certfication request object. + *
+     * CertificationRequest ::= Sequence {
+     *   certificationRequestInfo  CertificationRequestInfo,
+     *   signatureAlgorithm        AlgorithmIdentifier{{ SignatureAlgorithms }},
+     *   signature                 BIT STRING
+     * }
+     * 
+ */ + public class CertificationRequest + : Asn1Encodable + { + protected CertificationRequestInfo reqInfo; + protected AlgorithmIdentifier sigAlgId; + protected DerBitString sigBits; + + public static CertificationRequest GetInstance( + object obj) + { + if (obj is CertificationRequest) + return (CertificationRequest)obj; + + if (obj != null) + return new CertificationRequest((Asn1Sequence)obj); + + return null; + } + + protected CertificationRequest() + { + } + + public CertificationRequest( + CertificationRequestInfo requestInfo, + AlgorithmIdentifier algorithm, + DerBitString signature) + { + this.reqInfo = requestInfo; + this.sigAlgId = algorithm; + this.sigBits = signature; + } + + [Obsolete("Use 'GetInstance' instead")] + public CertificationRequest( + Asn1Sequence seq) + { + if (seq.Count != 3) + throw new ArgumentException("Wrong number of elements in sequence", "seq"); + + reqInfo = CertificationRequestInfo.GetInstance(seq[0]); + sigAlgId = AlgorithmIdentifier.GetInstance(seq[1]); + sigBits = DerBitString.GetInstance(seq[2]); + } + + public CertificationRequestInfo GetCertificationRequestInfo() + { + return reqInfo; + } + + public AlgorithmIdentifier SignatureAlgorithm + { + get { return sigAlgId; } + } + + public DerBitString Signature + { + get { return sigBits; } + } + + public byte[] GetSignatureOctets() + { + return sigBits.GetOctets(); + } + + public override Asn1Object ToAsn1Object() + { + return new DerSequence(reqInfo, sigAlgId, sigBits); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/CertificationRequest.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/CertificationRequest.cs.meta new file mode 100644 index 0000000..597de77 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/CertificationRequest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f66a79af7cd95a345add6bf854c25407 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/CertificationRequestInfo.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/CertificationRequestInfo.cs new file mode 100644 index 0000000..b775014 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/CertificationRequestInfo.cs @@ -0,0 +1,131 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + /** + * Pkcs10 CertificationRequestInfo object. + *
+     *  CertificationRequestInfo ::= Sequence {
+     *   version             Integer { v1(0) } (v1,...),
+     *   subject             Name,
+     *   subjectPKInfo   SubjectPublicKeyInfo{{ PKInfoAlgorithms }},
+     *   attributes          [0] Attributes{{ CRIAttributes }}
+     *  }
+     *
+     *  Attributes { ATTRIBUTE:IOSet } ::= Set OF Attr{{ IOSet }}
+     *
+     *  Attr { ATTRIBUTE:IOSet } ::= Sequence {
+     *    type    ATTRIBUTE.&id({IOSet}),
+     *    values  Set SIZE(1..MAX) OF ATTRIBUTE.&Type({IOSet}{\@type})
+     *  }
+     * 
+ */ + public class CertificationRequestInfo + : Asn1Encodable + { + internal DerInteger version = new DerInteger(0); + internal X509Name subject; + internal SubjectPublicKeyInfo subjectPKInfo; + internal Asn1Set attributes; + + public static CertificationRequestInfo GetInstance(object obj) + { + if (obj is CertificationRequestInfo) + return (CertificationRequestInfo)obj; + if (obj != null) + return new CertificationRequestInfo(Asn1Sequence.GetInstance(obj)); + return null; + } + + public CertificationRequestInfo( + X509Name subject, + SubjectPublicKeyInfo pkInfo, + Asn1Set attributes) + { + this.subject = subject; + this.subjectPKInfo = pkInfo; + this.attributes = attributes; + + ValidateAttributes(attributes); + + if (subject == null || version == null || subjectPKInfo == null) + { + throw new ArgumentException( + "Not all mandatory fields set in CertificationRequestInfo generator."); + } + } + + private CertificationRequestInfo( + Asn1Sequence seq) + { + version = (DerInteger) seq[0]; + + subject = X509Name.GetInstance(seq[1]); + subjectPKInfo = SubjectPublicKeyInfo.GetInstance(seq[2]); + + // + // some CertificationRequestInfo objects seem to treat this field + // as optional. + // + if (seq.Count > 3) + { + DerTaggedObject tagobj = (DerTaggedObject) seq[3]; + attributes = Asn1Set.GetInstance(tagobj, false); + } + + ValidateAttributes(attributes); + + if (subject == null || version == null || subjectPKInfo == null) + { + throw new ArgumentException( + "Not all mandatory fields set in CertificationRequestInfo generator."); + } + } + + public DerInteger Version + { + get { return version; } + } + + public X509Name Subject + { + get { return subject; } + } + + public SubjectPublicKeyInfo SubjectPublicKeyInfo + { + get { return subjectPKInfo; } + } + + public Asn1Set Attributes + { + get { return attributes; } + } + + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(version, subject, subjectPKInfo); + v.AddOptionalTagged(false, 0, attributes); + return new DerSequence(v); + } + + private static void ValidateAttributes(Asn1Set attributes) + { + if (attributes == null) + return; + + foreach (Asn1Encodable ae in attributes) + { + Asn1Object obj = ae.ToAsn1Object(); + AttributePkcs attr = AttributePkcs.GetInstance(obj); + if (attr.AttrType.Equals(PkcsObjectIdentifiers.Pkcs9AtChallengePassword)) + { + if (attr.AttrValues.Count != 1) + throw new ArgumentException("challengePassword attribute must have one value"); + } + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/CertificationRequestInfo.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/CertificationRequestInfo.cs.meta new file mode 100644 index 0000000..b425866 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/CertificationRequestInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b6834ea40a777d84fb3e32d2740c4b64 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/ContentInfo.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/ContentInfo.cs new file mode 100644 index 0000000..526a3c4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/ContentInfo.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + public class ContentInfo + : Asn1Encodable + { + private readonly DerObjectIdentifier contentType; + private readonly Asn1Encodable content; + + public static ContentInfo GetInstance(object obj) + { + if (obj == null) + return null; + ContentInfo existing = obj as ContentInfo; + if (existing != null) + return existing; + return new ContentInfo(Asn1Sequence.GetInstance(obj)); + } + + private ContentInfo( + Asn1Sequence seq) + { + contentType = (DerObjectIdentifier) seq[0]; + + if (seq.Count > 1) + { + content = ((Asn1TaggedObject) seq[1]).GetObject(); + } + } + + public ContentInfo( + DerObjectIdentifier contentType, + Asn1Encodable content) + { + this.contentType = contentType; + this.content = content; + } + + public DerObjectIdentifier ContentType + { + get { return contentType; } + } + + public Asn1Encodable Content + { + get { return content; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * ContentInfo ::= Sequence {
+         *          contentType ContentType,
+         *          content
+         *          [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(contentType); + + if (content != null) + { + v.Add(new BerTaggedObject(0, content)); + } + + return new BerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/ContentInfo.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/ContentInfo.cs.meta new file mode 100644 index 0000000..083f1b2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/ContentInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 90b7c8e7238feb844a66305ee4648720 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/DHParameter.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/DHParameter.cs new file mode 100644 index 0000000..23be5d2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/DHParameter.cs @@ -0,0 +1,67 @@ +using Org.BouncyCastle.Asn1; +using System; +using System.Collections; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + public class DHParameter + : Asn1Encodable + { + internal DerInteger p, g, l; + + public DHParameter( + BigInteger p, + BigInteger g, + int l) + { + this.p = new DerInteger(p); + this.g = new DerInteger(g); + + if (l != 0) + { + this.l = new DerInteger(l); + } + } + + public DHParameter( + Asn1Sequence seq) + { + IEnumerator e = seq.GetEnumerator(); + + e.MoveNext(); + p = (DerInteger)e.Current; + + e.MoveNext(); + g = (DerInteger)e.Current; + + if (e.MoveNext()) + { + l = (DerInteger) e.Current; + } + } + + public BigInteger P + { + get { return p.PositiveValue; } + } + + public BigInteger G + { + get { return g.PositiveValue; } + } + + public BigInteger L + { + get { return l == null ? null : l.PositiveValue; } + } + + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(p, g); + v.AddOptional(l); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/DHParameter.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/DHParameter.cs.meta new file mode 100644 index 0000000..8b189bd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/DHParameter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 150298a1927edd946a953c2aeab23990 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/EncryptedData.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/EncryptedData.cs new file mode 100644 index 0000000..cb04f34 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/EncryptedData.cs @@ -0,0 +1,103 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + /** + * The EncryptedData object. + *
+     *      EncryptedData ::= Sequence {
+     *           version Version,
+     *           encryptedContentInfo EncryptedContentInfo
+     *      }
+     *
+     *
+     *      EncryptedContentInfo ::= Sequence {
+     *          contentType ContentType,
+     *          contentEncryptionAlgorithm  ContentEncryptionAlgorithmIdentifier,
+     *          encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL
+     *    }
+     *
+     *    EncryptedContent ::= OCTET STRING
+     * 
+ */ + public class EncryptedData + : Asn1Encodable + { + private readonly Asn1Sequence data; +// private readonly DerObjectIdentifier bagId; +// private readonly Asn1Object bagValue; + + public static EncryptedData GetInstance( + object obj) + { + if (obj is EncryptedData) + { + return (EncryptedData) obj; + } + + if (obj is Asn1Sequence) + { + return new EncryptedData((Asn1Sequence) obj); + } + + throw new ArgumentException("Unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + private EncryptedData( + Asn1Sequence seq) + { + if (seq.Count != 2) + throw new ArgumentException("Wrong number of elements in sequence", "seq"); + + DerInteger version = (DerInteger)seq[0]; + if (!version.HasValue(0)) + throw new ArgumentException("sequence not version 0"); + + this.data = (Asn1Sequence) seq[1]; + } + + public EncryptedData( + DerObjectIdentifier contentType, + AlgorithmIdentifier encryptionAlgorithm, + Asn1Encodable content) + { + data = new BerSequence( + contentType, + encryptionAlgorithm.ToAsn1Object(), + new BerTaggedObject(false, 0, content)); + } + + public DerObjectIdentifier ContentType + { + get { return (DerObjectIdentifier) data[0]; } + } + + public AlgorithmIdentifier EncryptionAlgorithm + { + get { return AlgorithmIdentifier.GetInstance(data[1]); } + } + + public Asn1OctetString Content + { + get + { + if (data.Count == 3) + { + DerTaggedObject o = (DerTaggedObject) data[2]; + + return Asn1OctetString.GetInstance(o, false); + } + + return null; + } + } + + public override Asn1Object ToAsn1Object() + { + return new BerSequence(new DerInteger(0), data); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/EncryptedData.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/EncryptedData.cs.meta new file mode 100644 index 0000000..f9d6ebe --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/EncryptedData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a681047d46d192b43963f98aba3e5ccd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/EncryptedPrivateKeyInfo.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/EncryptedPrivateKeyInfo.cs new file mode 100644 index 0000000..9870270 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/EncryptedPrivateKeyInfo.cs @@ -0,0 +1,79 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + public class EncryptedPrivateKeyInfo + : Asn1Encodable + { + private readonly AlgorithmIdentifier algId; + private readonly Asn1OctetString data; + + private EncryptedPrivateKeyInfo( + Asn1Sequence seq) + { + if (seq.Count != 2) + throw new ArgumentException("Wrong number of elements in sequence", "seq"); + + algId = AlgorithmIdentifier.GetInstance(seq[0]); + data = Asn1OctetString.GetInstance(seq[1]); + } + + public EncryptedPrivateKeyInfo( + AlgorithmIdentifier algId, + byte[] encoding) + { + this.algId = algId; + this.data = new DerOctetString(encoding); + } + + public static EncryptedPrivateKeyInfo GetInstance( + object obj) + { + if (obj is EncryptedPrivateKeyInfo) + { + return (EncryptedPrivateKeyInfo) obj; + } + + if (obj is Asn1Sequence) + { + return new EncryptedPrivateKeyInfo((Asn1Sequence) obj); + } + + throw new ArgumentException("Unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + public AlgorithmIdentifier EncryptionAlgorithm + { + get { return algId; } + } + + public byte[] GetEncryptedData() + { + return data.GetOctets(); + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * EncryptedPrivateKeyInfo ::= Sequence {
+         *      encryptionAlgorithm AlgorithmIdentifier {{KeyEncryptionAlgorithms}},
+         *      encryptedData EncryptedData
+         * }
+         *
+         * EncryptedData ::= OCTET STRING
+         *
+         * KeyEncryptionAlgorithms ALGORITHM-IDENTIFIER ::= {
+         *          ... -- For local profiles
+         * }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + return new DerSequence(algId, data); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/EncryptedPrivateKeyInfo.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/EncryptedPrivateKeyInfo.cs.meta new file mode 100644 index 0000000..59a172f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/EncryptedPrivateKeyInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 85632ae8b9aeba841800bb1c90ff7637 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/EncryptionScheme.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/EncryptionScheme.cs new file mode 100644 index 0000000..34d26e1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/EncryptionScheme.cs @@ -0,0 +1,55 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + public class EncryptionScheme + : AlgorithmIdentifier + { + public EncryptionScheme( + DerObjectIdentifier objectID) + : base(objectID) + { + } + + public EncryptionScheme( + DerObjectIdentifier objectID, + Asn1Encodable parameters) + : base(objectID, parameters) + { + } + + internal EncryptionScheme( + Asn1Sequence seq) + : this((DerObjectIdentifier)seq[0], seq[1]) + { + } + + public new static EncryptionScheme GetInstance(object obj) + { + if (obj is EncryptionScheme) + { + return (EncryptionScheme)obj; + } + + if (obj is Asn1Sequence) + { + return new EncryptionScheme((Asn1Sequence)obj); + } + + throw new ArgumentException("Unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + public Asn1Object Asn1Object + { + get { return Parameters.ToAsn1Object(); } + } + + public override Asn1Object ToAsn1Object() + { + return new DerSequence(Algorithm, Parameters); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/EncryptionScheme.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/EncryptionScheme.cs.meta new file mode 100644 index 0000000..81cedad --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/EncryptionScheme.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6dad90baacb14d44da879b0570a9aec7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/IssuerAndSerialNumber.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/IssuerAndSerialNumber.cs new file mode 100644 index 0000000..da863cb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/IssuerAndSerialNumber.cs @@ -0,0 +1,72 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + public class IssuerAndSerialNumber + : Asn1Encodable + { + private readonly X509Name name; + private readonly DerInteger certSerialNumber; + + public static IssuerAndSerialNumber GetInstance( + object obj) + { + if (obj is IssuerAndSerialNumber) + { + return (IssuerAndSerialNumber) obj; + } + + if (obj is Asn1Sequence) + { + return new IssuerAndSerialNumber((Asn1Sequence) obj); + } + + throw new ArgumentException("Unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + private IssuerAndSerialNumber( + Asn1Sequence seq) + { + if (seq.Count != 2) + throw new ArgumentException("Wrong number of elements in sequence", "seq"); + + this.name = X509Name.GetInstance(seq[0]); + this.certSerialNumber = DerInteger.GetInstance(seq[1]); + } + + public IssuerAndSerialNumber( + X509Name name, + BigInteger certSerialNumber) + { + this.name = name; + this.certSerialNumber = new DerInteger(certSerialNumber); + } + + public IssuerAndSerialNumber( + X509Name name, + DerInteger certSerialNumber) + { + this.name = name; + this.certSerialNumber = certSerialNumber; + } + + public X509Name Name + { + get { return name; } + } + + public DerInteger CertificateSerialNumber + { + get { return certSerialNumber; } + } + + public override Asn1Object ToAsn1Object() + { + return new DerSequence(name, certSerialNumber); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/IssuerAndSerialNumber.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/IssuerAndSerialNumber.cs.meta new file mode 100644 index 0000000..3faad8f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/IssuerAndSerialNumber.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2169267e9fffd3041be6117066397f6b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/KeyDerivationFunc.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/KeyDerivationFunc.cs new file mode 100644 index 0000000..9fc8985 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/KeyDerivationFunc.cs @@ -0,0 +1,21 @@ +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + public class KeyDerivationFunc + : AlgorithmIdentifier + { + internal KeyDerivationFunc(Asn1Sequence seq) + : base(seq) + { + } + + public KeyDerivationFunc( + DerObjectIdentifier id, + Asn1Encodable parameters) + : base(id, parameters) + { + } + } +} \ No newline at end of file diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/KeyDerivationFunc.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/KeyDerivationFunc.cs.meta new file mode 100644 index 0000000..5612842 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/KeyDerivationFunc.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3391fed766f4c304ba0dc07446627f59 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/MacData.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/MacData.cs new file mode 100644 index 0000000..c4b7df1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/MacData.cs @@ -0,0 +1,96 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + public class MacData + : Asn1Encodable + { + internal DigestInfo digInfo; + internal byte[] salt; + internal BigInteger iterationCount; + + public static MacData GetInstance( + object obj) + { + if (obj is MacData) + { + return (MacData) obj; + } + + if (obj is Asn1Sequence) + { + return new MacData((Asn1Sequence) obj); + } + + throw new ArgumentException("Unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + private MacData( + Asn1Sequence seq) + { + this.digInfo = DigestInfo.GetInstance(seq[0]); + this.salt = ((Asn1OctetString) seq[1]).GetOctets(); + + if (seq.Count == 3) + { + this.iterationCount = ((DerInteger) seq[2]).Value; + } + else + { + this.iterationCount = BigInteger.One; + } + } + + public MacData( + DigestInfo digInfo, + byte[] salt, + int iterationCount) + { + this.digInfo = digInfo; + this.salt = (byte[]) salt.Clone(); + this.iterationCount = BigInteger.ValueOf(iterationCount); + } + + public DigestInfo Mac + { + get { return digInfo; } + } + + public byte[] GetSalt() + { + return (byte[]) salt.Clone(); + } + + public BigInteger IterationCount + { + get { return iterationCount; } + } + + /** + *
+		 * MacData ::= SEQUENCE {
+		 *     mac      DigestInfo,
+		 *     macSalt  OCTET STRING,
+		 *     iterations INTEGER DEFAULT 1
+		 *     -- Note: The default is for historic reasons and its use is deprecated. A
+		 *     -- higher value, like 1024 is recommended.
+		 * 
+ * @return the basic DERObject construction. + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(digInfo, new DerOctetString(salt)); + + if (!iterationCount.Equals(BigInteger.One)) + { + v.Add(new DerInteger(iterationCount)); + } + + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/MacData.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/MacData.cs.meta new file mode 100644 index 0000000..4ee1785 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/MacData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 108596f8a69a1474bbc5e3df70430576 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/PBEParameter.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/PBEParameter.cs new file mode 100644 index 0000000..56cea5f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/PBEParameter.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + public class PbeParameter + : Asn1Encodable + { + private readonly Asn1OctetString salt; + private readonly DerInteger iterationCount; + + public static PbeParameter GetInstance(object obj) + { + if (obj is PbeParameter || obj == null) + { + return (PbeParameter) obj; + } + + if (obj is Asn1Sequence) + { + return new PbeParameter((Asn1Sequence) obj); + } + + throw new ArgumentException("Unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + private PbeParameter(Asn1Sequence seq) + { + if (seq.Count != 2) + throw new ArgumentException("Wrong number of elements in sequence", "seq"); + + salt = Asn1OctetString.GetInstance(seq[0]); + iterationCount = DerInteger.GetInstance(seq[1]); + } + + public PbeParameter(byte[] salt, int iterationCount) + { + this.salt = new DerOctetString(salt); + this.iterationCount = new DerInteger(iterationCount); + } + + public byte[] GetSalt() + { + return salt.GetOctets(); + } + + public BigInteger IterationCount + { + get { return iterationCount.Value; } + } + + public override Asn1Object ToAsn1Object() + { + return new DerSequence(salt, iterationCount); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/PBEParameter.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/PBEParameter.cs.meta new file mode 100644 index 0000000..253adf1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/PBEParameter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 00f1c216afd333046830b49763f118f8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/PBES2Parameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/PBES2Parameters.cs new file mode 100644 index 0000000..fc6904e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/PBES2Parameters.cs @@ -0,0 +1,65 @@ +using System; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + public class PbeS2Parameters + : Asn1Encodable + { + private readonly KeyDerivationFunc func; + private readonly EncryptionScheme scheme; + + public static PbeS2Parameters GetInstance(object obj) + { + if (obj == null) + return null; + PbeS2Parameters existing = obj as PbeS2Parameters; + if (existing != null) + return existing; + return new PbeS2Parameters(Asn1Sequence.GetInstance(obj)); + } + + public PbeS2Parameters(KeyDerivationFunc keyDevFunc, EncryptionScheme encScheme) + { + this.func = keyDevFunc; + this.scheme = encScheme; + } + + [Obsolete("Use GetInstance() instead")] + public PbeS2Parameters( + Asn1Sequence seq) + { + if (seq.Count != 2) + throw new ArgumentException("Wrong number of elements in sequence", "seq"); + + Asn1Sequence funcSeq = (Asn1Sequence)seq[0].ToAsn1Object(); + + // TODO Not sure if this special case is really necessary/appropriate + if (funcSeq[0].Equals(PkcsObjectIdentifiers.IdPbkdf2)) + { + func = new KeyDerivationFunc(PkcsObjectIdentifiers.IdPbkdf2, + Pbkdf2Params.GetInstance(funcSeq[1])); + } + else + { + func = new KeyDerivationFunc(funcSeq); + } + + scheme = EncryptionScheme.GetInstance(seq[1].ToAsn1Object()); + } + + public KeyDerivationFunc KeyDerivationFunc + { + get { return func; } + } + + public EncryptionScheme EncryptionScheme + { + get { return scheme; } + } + + public override Asn1Object ToAsn1Object() + { + return new DerSequence(func, scheme); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/PBES2Parameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/PBES2Parameters.cs.meta new file mode 100644 index 0000000..89ce9b3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/PBES2Parameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3f85b503bfd1f9b4b9691d8b68143eaa +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/PBKDF2Params.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/PBKDF2Params.cs new file mode 100644 index 0000000..13f469c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/PBKDF2Params.cs @@ -0,0 +1,140 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + public class Pbkdf2Params + : Asn1Encodable + { + private static AlgorithmIdentifier algid_hmacWithSHA1 = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdHmacWithSha1, DerNull.Instance); + + private readonly Asn1OctetString octStr; + private readonly DerInteger iterationCount, keyLength; + private readonly AlgorithmIdentifier prf; + + public static Pbkdf2Params GetInstance( + object obj) + { + if (obj == null || obj is Pbkdf2Params) + return (Pbkdf2Params)obj; + + if (obj is Asn1Sequence) + return new Pbkdf2Params((Asn1Sequence)obj); + + throw new ArgumentException("Unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + public Pbkdf2Params( + Asn1Sequence seq) + { + if (seq.Count < 2 || seq.Count > 4) + throw new ArgumentException("Wrong number of elements in sequence", "seq"); + + this.octStr = (Asn1OctetString)seq[0]; + this.iterationCount = (DerInteger)seq[1]; + + Asn1Encodable kl = null, d = null; + if (seq.Count > 3) + { + kl = seq[2]; + d = seq[3]; + } + else if (seq.Count > 2) + { + if (seq[2] is DerInteger) + { + kl = seq[2]; + } + else + { + d = seq[2]; + } + } + if (kl != null) + { + keyLength = (DerInteger)kl; + } + if (d != null) + { + prf = AlgorithmIdentifier.GetInstance(d); + } + } + + public Pbkdf2Params( + byte[] salt, + int iterationCount) + { + this.octStr = new DerOctetString(salt); + this.iterationCount = new DerInteger(iterationCount); + } + + public Pbkdf2Params( + byte[] salt, + int iterationCount, + int keyLength) + : this(salt, iterationCount) + { + this.keyLength = new DerInteger(keyLength); + } + + public Pbkdf2Params( + byte[] salt, + int iterationCount, + int keyLength, + AlgorithmIdentifier prf) + : this(salt, iterationCount, keyLength) + { + this.prf = prf; + } + + public Pbkdf2Params( + byte[] salt, + int iterationCount, + AlgorithmIdentifier prf) + : this(salt, iterationCount) + { + this.prf = prf; + } + + public byte[] GetSalt() + { + return octStr.GetOctets(); + } + + public BigInteger IterationCount + { + get { return iterationCount.Value; } + } + + public BigInteger KeyLength + { + get { return keyLength == null ? null : keyLength.Value; } + } + + public bool IsDefaultPrf + { + get { return prf == null || prf.Equals(algid_hmacWithSHA1); } + } + + public AlgorithmIdentifier Prf + { + get { return prf != null ? prf : algid_hmacWithSHA1; } + } + + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(octStr, iterationCount); + v.AddOptional(keyLength); + + if (!IsDefaultPrf) + { + v.Add(prf); + } + + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/PBKDF2Params.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/PBKDF2Params.cs.meta new file mode 100644 index 0000000..6ff18d0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/PBKDF2Params.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: db4ef7e1ee5e65b478659861b287b606 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/PKCS12PBEParams.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/PKCS12PBEParams.cs new file mode 100644 index 0000000..b41c289 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/PKCS12PBEParams.cs @@ -0,0 +1,63 @@ +using System; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + public class Pkcs12PbeParams + : Asn1Encodable + { + private readonly DerInteger iterations; + private readonly Asn1OctetString iv; + + public Pkcs12PbeParams( + byte[] salt, + int iterations) + { + this.iv = new DerOctetString(salt); + this.iterations = new DerInteger(iterations); + } + + private Pkcs12PbeParams( + Asn1Sequence seq) + { + if (seq.Count != 2) + throw new ArgumentException("Wrong number of elements in sequence", "seq"); + + iv = Asn1OctetString.GetInstance(seq[0]); + iterations = DerInteger.GetInstance(seq[1]); + } + + public static Pkcs12PbeParams GetInstance( + object obj) + { + if (obj is Pkcs12PbeParams) + { + return (Pkcs12PbeParams) obj; + } + + if (obj is Asn1Sequence) + { + return new Pkcs12PbeParams((Asn1Sequence) obj); + } + + throw new ArgumentException("Unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + public BigInteger Iterations + { + get { return iterations.Value; } + } + + public byte[] GetIV() + { + return iv.GetOctets(); + } + + public override Asn1Object ToAsn1Object() + { + return new DerSequence(iv, iterations); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/PKCS12PBEParams.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/PKCS12PBEParams.cs.meta new file mode 100644 index 0000000..10bd652 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/PKCS12PBEParams.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 528077a4e809a9340a10376723d256b5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/PKCSObjectIdentifiers.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/PKCSObjectIdentifiers.cs new file mode 100644 index 0000000..6c7fed4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/PKCSObjectIdentifiers.cs @@ -0,0 +1,305 @@ +using System; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + public abstract class PkcsObjectIdentifiers + { + // + // pkcs-1 OBJECT IDENTIFIER ::= { + // iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 1 } + // + public const string Pkcs1 = "1.2.840.113549.1.1"; + internal static readonly DerObjectIdentifier Pkcs1Oid = new DerObjectIdentifier(Pkcs1); + + public static readonly DerObjectIdentifier RsaEncryption = Pkcs1Oid.Branch("1"); + public static readonly DerObjectIdentifier MD2WithRsaEncryption = Pkcs1Oid.Branch("2"); + public static readonly DerObjectIdentifier MD4WithRsaEncryption = Pkcs1Oid.Branch("3"); + public static readonly DerObjectIdentifier MD5WithRsaEncryption = Pkcs1Oid.Branch("4"); + public static readonly DerObjectIdentifier Sha1WithRsaEncryption = Pkcs1Oid.Branch("5"); + public static readonly DerObjectIdentifier SrsaOaepEncryptionSet = Pkcs1Oid.Branch("6"); + public static readonly DerObjectIdentifier IdRsaesOaep = Pkcs1Oid.Branch("7"); + public static readonly DerObjectIdentifier IdMgf1 = Pkcs1Oid.Branch("8"); + public static readonly DerObjectIdentifier IdPSpecified = Pkcs1Oid.Branch("9"); + public static readonly DerObjectIdentifier IdRsassaPss = Pkcs1Oid.Branch("10"); + public static readonly DerObjectIdentifier Sha256WithRsaEncryption = Pkcs1Oid.Branch("11"); + public static readonly DerObjectIdentifier Sha384WithRsaEncryption = Pkcs1Oid.Branch("12"); + public static readonly DerObjectIdentifier Sha512WithRsaEncryption = Pkcs1Oid.Branch("13"); + public static readonly DerObjectIdentifier Sha224WithRsaEncryption = Pkcs1Oid.Branch("14"); + /** PKCS#1: 1.2.840.113549.1.1.15 */ + public static readonly DerObjectIdentifier Sha512_224WithRSAEncryption = Pkcs1Oid.Branch("15"); + /** PKCS#1: 1.2.840.113549.1.1.16 */ + public static readonly DerObjectIdentifier Sha512_256WithRSAEncryption = Pkcs1Oid.Branch("16"); + + // + // pkcs-3 OBJECT IDENTIFIER ::= { + // iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 3 } + // + public const string Pkcs3 = "1.2.840.113549.1.3"; + + public static readonly DerObjectIdentifier DhKeyAgreement = new DerObjectIdentifier(Pkcs3 + ".1"); + + // + // pkcs-5 OBJECT IDENTIFIER ::= { + // iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 5 } + // + public const string Pkcs5 = "1.2.840.113549.1.5"; + + public static readonly DerObjectIdentifier PbeWithMD2AndDesCbc = new DerObjectIdentifier(Pkcs5 + ".1"); + public static readonly DerObjectIdentifier PbeWithMD2AndRC2Cbc = new DerObjectIdentifier(Pkcs5 + ".4"); + public static readonly DerObjectIdentifier PbeWithMD5AndDesCbc = new DerObjectIdentifier(Pkcs5 + ".3"); + public static readonly DerObjectIdentifier PbeWithMD5AndRC2Cbc = new DerObjectIdentifier(Pkcs5 + ".6"); + public static readonly DerObjectIdentifier PbeWithSha1AndDesCbc = new DerObjectIdentifier(Pkcs5 + ".10"); + public static readonly DerObjectIdentifier PbeWithSha1AndRC2Cbc = new DerObjectIdentifier(Pkcs5 + ".11"); + + public static readonly DerObjectIdentifier IdPbeS2 = new DerObjectIdentifier(Pkcs5 + ".13"); + public static readonly DerObjectIdentifier IdPbkdf2 = new DerObjectIdentifier(Pkcs5 + ".12"); + + // + // encryptionAlgorithm OBJECT IDENTIFIER ::= { + // iso(1) member-body(2) us(840) rsadsi(113549) 3 } + // + public const string EncryptionAlgorithm = "1.2.840.113549.3"; + + public static readonly DerObjectIdentifier DesEde3Cbc = new DerObjectIdentifier(EncryptionAlgorithm + ".7"); + public static readonly DerObjectIdentifier RC2Cbc = new DerObjectIdentifier(EncryptionAlgorithm + ".2"); + public static readonly DerObjectIdentifier rc4 = new DerObjectIdentifier(EncryptionAlgorithm + ".4"); + + // + // object identifiers for digests + // + public const string DigestAlgorithm = "1.2.840.113549.2"; + + // + // md2 OBJECT IDENTIFIER ::= + // {iso(1) member-body(2) US(840) rsadsi(113549) DigestAlgorithm(2) 2} + // + public static readonly DerObjectIdentifier MD2 = new DerObjectIdentifier(DigestAlgorithm + ".2"); + + // + // md4 OBJECT IDENTIFIER ::= + // {iso(1) member-body(2) US(840) rsadsi(113549) DigestAlgorithm(2) 4} + // + public static readonly DerObjectIdentifier MD4 = new DerObjectIdentifier(DigestAlgorithm + ".4"); + + // + // md5 OBJECT IDENTIFIER ::= + // {iso(1) member-body(2) US(840) rsadsi(113549) DigestAlgorithm(2) 5} + // + public static readonly DerObjectIdentifier MD5 = new DerObjectIdentifier(DigestAlgorithm + ".5"); + + public static readonly DerObjectIdentifier IdHmacWithSha1 = new DerObjectIdentifier(DigestAlgorithm + ".7"); + public static readonly DerObjectIdentifier IdHmacWithSha224 = new DerObjectIdentifier(DigestAlgorithm + ".8"); + public static readonly DerObjectIdentifier IdHmacWithSha256 = new DerObjectIdentifier(DigestAlgorithm + ".9"); + public static readonly DerObjectIdentifier IdHmacWithSha384 = new DerObjectIdentifier(DigestAlgorithm + ".10"); + public static readonly DerObjectIdentifier IdHmacWithSha512 = new DerObjectIdentifier(DigestAlgorithm + ".11"); + + // + // pkcs-7 OBJECT IDENTIFIER ::= { + // iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 7 } + // + public const string Pkcs7 = "1.2.840.113549.1.7"; + + public static readonly DerObjectIdentifier Data = new DerObjectIdentifier(Pkcs7 + ".1"); + public static readonly DerObjectIdentifier SignedData = new DerObjectIdentifier(Pkcs7 + ".2"); + public static readonly DerObjectIdentifier EnvelopedData = new DerObjectIdentifier(Pkcs7 + ".3"); + public static readonly DerObjectIdentifier SignedAndEnvelopedData = new DerObjectIdentifier(Pkcs7 + ".4"); + public static readonly DerObjectIdentifier DigestedData = new DerObjectIdentifier(Pkcs7 + ".5"); + public static readonly DerObjectIdentifier EncryptedData = new DerObjectIdentifier(Pkcs7 + ".6"); + + // + // pkcs-9 OBJECT IDENTIFIER ::= { + // iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 9 } + // + public const string Pkcs9 = "1.2.840.113549.1.9"; + + public static readonly DerObjectIdentifier Pkcs9AtEmailAddress = new DerObjectIdentifier(Pkcs9 + ".1"); + public static readonly DerObjectIdentifier Pkcs9AtUnstructuredName = new DerObjectIdentifier(Pkcs9 + ".2"); + public static readonly DerObjectIdentifier Pkcs9AtContentType = new DerObjectIdentifier(Pkcs9 + ".3"); + public static readonly DerObjectIdentifier Pkcs9AtMessageDigest = new DerObjectIdentifier(Pkcs9 + ".4"); + public static readonly DerObjectIdentifier Pkcs9AtSigningTime = new DerObjectIdentifier(Pkcs9 + ".5"); + public static readonly DerObjectIdentifier Pkcs9AtCounterSignature = new DerObjectIdentifier(Pkcs9 + ".6"); + public static readonly DerObjectIdentifier Pkcs9AtChallengePassword = new DerObjectIdentifier(Pkcs9 + ".7"); + public static readonly DerObjectIdentifier Pkcs9AtUnstructuredAddress = new DerObjectIdentifier(Pkcs9 + ".8"); + public static readonly DerObjectIdentifier Pkcs9AtExtendedCertificateAttributes = new DerObjectIdentifier(Pkcs9 + ".9"); + public static readonly DerObjectIdentifier Pkcs9AtSigningDescription = new DerObjectIdentifier(Pkcs9 + ".13"); + public static readonly DerObjectIdentifier Pkcs9AtExtensionRequest = new DerObjectIdentifier(Pkcs9 + ".14"); + public static readonly DerObjectIdentifier Pkcs9AtSmimeCapabilities = new DerObjectIdentifier(Pkcs9 + ".15"); + public static readonly DerObjectIdentifier IdSmime = new DerObjectIdentifier(Pkcs9 + ".16"); + + public static readonly DerObjectIdentifier Pkcs9AtFriendlyName = new DerObjectIdentifier(Pkcs9 + ".20"); + public static readonly DerObjectIdentifier Pkcs9AtLocalKeyID = new DerObjectIdentifier(Pkcs9 + ".21"); + + [Obsolete("Use X509Certificate instead")] + public static readonly DerObjectIdentifier X509CertType = new DerObjectIdentifier(Pkcs9 + ".22.1"); + + public const string CertTypes = Pkcs9 + ".22"; + public static readonly DerObjectIdentifier X509Certificate = new DerObjectIdentifier(CertTypes + ".1"); + public static readonly DerObjectIdentifier SdsiCertificate = new DerObjectIdentifier(CertTypes + ".2"); + + public const string CrlTypes = Pkcs9 + ".23"; + public static readonly DerObjectIdentifier X509Crl = new DerObjectIdentifier(CrlTypes + ".1"); + + public static readonly DerObjectIdentifier IdAlg = IdSmime.Branch("3"); + + public static readonly DerObjectIdentifier IdAlgEsdh = IdAlg.Branch("5"); + public static readonly DerObjectIdentifier IdAlgCms3DesWrap = IdAlg.Branch("6"); + public static readonly DerObjectIdentifier IdAlgCmsRC2Wrap = IdAlg.Branch("7"); + public static readonly DerObjectIdentifier IdAlgPwriKek = IdAlg.Branch("9"); + public static readonly DerObjectIdentifier IdAlgSsdh = IdAlg.Branch("10"); + + /* + *
+         * -- RSA-KEM Key Transport Algorithm
+         *
+         * id-rsa-kem OID ::= {
+         *      iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1)
+         *      pkcs-9(9) smime(16) alg(3) 14
+         *   }
+         * 
+ */ + public static readonly DerObjectIdentifier IdRsaKem = IdAlg.Branch("14"); + + /** + *
+         * id-alg-AEADChaCha20Poly1305 OBJECT IDENTIFIER ::=
+         * { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1)
+         *    pkcs9(9) smime(16) alg(3) 18 }
+         *
+         * AEADChaCha20Poly1305Nonce ::= OCTET STRING (SIZE(12))
+         * 
+ */ + public static readonly DerObjectIdentifier IdAlgAeadChaCha20Poly1305 = IdAlg.Branch("18"); + + // + // SMIME capability sub oids. + // + public static readonly DerObjectIdentifier PreferSignedData = Pkcs9AtSmimeCapabilities.Branch("1"); + public static readonly DerObjectIdentifier CannotDecryptAny = Pkcs9AtSmimeCapabilities.Branch("2"); + public static readonly DerObjectIdentifier SmimeCapabilitiesVersions = Pkcs9AtSmimeCapabilities.Branch("3"); + + // + // other SMIME attributes + // + public static readonly DerObjectIdentifier IdAAReceiptRequest = IdSmime.Branch("2.1"); + + // + // id-ct OBJECT IDENTIFIER ::= {iso(1) member-body(2) usa(840) + // rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) ct(1)} + // + public const string IdCT = "1.2.840.113549.1.9.16.1"; + + public static readonly DerObjectIdentifier IdCTAuthData = new DerObjectIdentifier(IdCT + ".2"); + public static readonly DerObjectIdentifier IdCTTstInfo = new DerObjectIdentifier(IdCT + ".4"); + public static readonly DerObjectIdentifier IdCTCompressedData = new DerObjectIdentifier(IdCT + ".9"); + public static readonly DerObjectIdentifier IdCTAuthEnvelopedData = new DerObjectIdentifier(IdCT + ".23"); + public static readonly DerObjectIdentifier IdCTTimestampedData = new DerObjectIdentifier(IdCT + ".31"); + + // + // id-cti OBJECT IDENTIFIER ::= {iso(1) member-body(2) usa(840) + // rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) cti(6)} + // + public const string IdCti = "1.2.840.113549.1.9.16.6"; + + public static readonly DerObjectIdentifier IdCtiEtsProofOfOrigin = new DerObjectIdentifier(IdCti + ".1"); + public static readonly DerObjectIdentifier IdCtiEtsProofOfReceipt = new DerObjectIdentifier(IdCti + ".2"); + public static readonly DerObjectIdentifier IdCtiEtsProofOfDelivery = new DerObjectIdentifier(IdCti + ".3"); + public static readonly DerObjectIdentifier IdCtiEtsProofOfSender = new DerObjectIdentifier(IdCti + ".4"); + public static readonly DerObjectIdentifier IdCtiEtsProofOfApproval = new DerObjectIdentifier(IdCti + ".5"); + public static readonly DerObjectIdentifier IdCtiEtsProofOfCreation = new DerObjectIdentifier(IdCti + ".6"); + + // + // id-aa OBJECT IDENTIFIER ::= {iso(1) member-body(2) usa(840) + // rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) attributes(2)} + // + public const string IdAA = "1.2.840.113549.1.9.16.2"; + public static readonly DerObjectIdentifier IdAAOid = new DerObjectIdentifier(IdAA); + + public static readonly DerObjectIdentifier IdAAContentHint = new DerObjectIdentifier(IdAA + ".4"); // See RFC 2634 + public static readonly DerObjectIdentifier IdAAMsgSigDigest = new DerObjectIdentifier(IdAA + ".5"); + public static readonly DerObjectIdentifier IdAAContentReference = new DerObjectIdentifier(IdAA + ".10"); + + /* + * id-aa-encrypKeyPref OBJECT IDENTIFIER ::= {id-aa 11} + * + */ + public static readonly DerObjectIdentifier IdAAEncrypKeyPref = new DerObjectIdentifier(IdAA + ".11"); + public static readonly DerObjectIdentifier IdAASigningCertificate = new DerObjectIdentifier(IdAA + ".12"); + public static readonly DerObjectIdentifier IdAASigningCertificateV2 = new DerObjectIdentifier(IdAA + ".47"); + + public static readonly DerObjectIdentifier IdAAContentIdentifier = new DerObjectIdentifier(IdAA + ".7"); // See RFC 2634 + + /* + * RFC 3126 + */ + public static readonly DerObjectIdentifier IdAASignatureTimeStampToken = new DerObjectIdentifier(IdAA + ".14"); + + public static readonly DerObjectIdentifier IdAAEtsSigPolicyID = new DerObjectIdentifier(IdAA + ".15"); + public static readonly DerObjectIdentifier IdAAEtsCommitmentType = new DerObjectIdentifier(IdAA + ".16"); + public static readonly DerObjectIdentifier IdAAEtsSignerLocation = new DerObjectIdentifier(IdAA + ".17"); + public static readonly DerObjectIdentifier IdAAEtsSignerAttr = new DerObjectIdentifier(IdAA + ".18"); + public static readonly DerObjectIdentifier IdAAEtsOtherSigCert = new DerObjectIdentifier(IdAA + ".19"); + public static readonly DerObjectIdentifier IdAAEtsContentTimestamp = new DerObjectIdentifier(IdAA + ".20"); + public static readonly DerObjectIdentifier IdAAEtsCertificateRefs = new DerObjectIdentifier(IdAA + ".21"); + public static readonly DerObjectIdentifier IdAAEtsRevocationRefs = new DerObjectIdentifier(IdAA + ".22"); + public static readonly DerObjectIdentifier IdAAEtsCertValues = new DerObjectIdentifier(IdAA + ".23"); + public static readonly DerObjectIdentifier IdAAEtsRevocationValues = new DerObjectIdentifier(IdAA + ".24"); + public static readonly DerObjectIdentifier IdAAEtsEscTimeStamp = new DerObjectIdentifier(IdAA + ".25"); + public static readonly DerObjectIdentifier IdAAEtsCertCrlTimestamp = new DerObjectIdentifier(IdAA + ".26"); + public static readonly DerObjectIdentifier IdAAEtsArchiveTimestamp = new DerObjectIdentifier(IdAA + ".27"); + + /** PKCS#9: 1.2.840.113549.1.9.16.2.37 - RFC 4108 */ + public static readonly DerObjectIdentifier IdAADecryptKeyID = IdAAOid.Branch("37"); + + /** PKCS#9: 1.2.840.113549.1.9.16.2.38 - RFC 4108 */ + public static readonly DerObjectIdentifier IdAAImplCryptoAlgs = IdAAOid.Branch("38"); + + /** PKCS#9: 1.2.840.113549.1.9.16.2.54 RFC7030*/ + public static readonly DerObjectIdentifier IdAAAsymmDecryptKeyID = IdAAOid.Branch("54"); + + /** PKCS#9: 1.2.840.113549.1.9.16.2.43 RFC7030*/ + public static readonly DerObjectIdentifier IdAAImplCompressAlgs = IdAAOid.Branch("43"); + /** PKCS#9: 1.2.840.113549.1.9.16.2.40 RFC7030*/ + public static readonly DerObjectIdentifier IdAACommunityIdentifiers = IdAAOid.Branch("40"); + + [Obsolete("Use 'IdAAEtsSigPolicyID' instead")] + public static readonly DerObjectIdentifier IdAASigPolicyID = IdAAEtsSigPolicyID; + [Obsolete("Use 'IdAAEtsCommitmentType' instead")] + public static readonly DerObjectIdentifier IdAACommitmentType = IdAAEtsCommitmentType; + [Obsolete("Use 'IdAAEtsSignerLocation' instead")] + public static readonly DerObjectIdentifier IdAASignerLocation = IdAAEtsSignerLocation; + [Obsolete("Use 'IdAAEtsOtherSigCert' instead")] + public static readonly DerObjectIdentifier IdAAOtherSigCert = IdAAEtsOtherSigCert; + + // + // id-spq OBJECT IDENTIFIER ::= {iso(1) member-body(2) usa(840) + // rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) id-spq(5)} + // + public const string IdSpq = "1.2.840.113549.1.9.16.5"; + + public static readonly DerObjectIdentifier IdSpqEtsUri = new DerObjectIdentifier(IdSpq + ".1"); + public static readonly DerObjectIdentifier IdSpqEtsUNotice = new DerObjectIdentifier(IdSpq + ".2"); + + // + // pkcs-12 OBJECT IDENTIFIER ::= { + // iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 12 } + // + public const string Pkcs12 = "1.2.840.113549.1.12"; + public const string BagTypes = Pkcs12 + ".10.1"; + + public static readonly DerObjectIdentifier KeyBag = new DerObjectIdentifier(BagTypes + ".1"); + public static readonly DerObjectIdentifier Pkcs8ShroudedKeyBag = new DerObjectIdentifier(BagTypes + ".2"); + public static readonly DerObjectIdentifier CertBag = new DerObjectIdentifier(BagTypes + ".3"); + public static readonly DerObjectIdentifier CrlBag = new DerObjectIdentifier(BagTypes + ".4"); + public static readonly DerObjectIdentifier SecretBag = new DerObjectIdentifier(BagTypes + ".5"); + public static readonly DerObjectIdentifier SafeContentsBag = new DerObjectIdentifier(BagTypes + ".6"); + + public const string Pkcs12PbeIds = Pkcs12 + ".1"; + + public static readonly DerObjectIdentifier PbeWithShaAnd128BitRC4 = new DerObjectIdentifier(Pkcs12PbeIds + ".1"); + public static readonly DerObjectIdentifier PbeWithShaAnd40BitRC4 = new DerObjectIdentifier(Pkcs12PbeIds + ".2"); + public static readonly DerObjectIdentifier PbeWithShaAnd3KeyTripleDesCbc = new DerObjectIdentifier(Pkcs12PbeIds + ".3"); + public static readonly DerObjectIdentifier PbeWithShaAnd2KeyTripleDesCbc = new DerObjectIdentifier(Pkcs12PbeIds + ".4"); + public static readonly DerObjectIdentifier PbeWithShaAnd128BitRC2Cbc = new DerObjectIdentifier(Pkcs12PbeIds + ".5"); + public static readonly DerObjectIdentifier PbewithShaAnd40BitRC2Cbc = new DerObjectIdentifier(Pkcs12PbeIds + ".6"); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/PKCSObjectIdentifiers.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/PKCSObjectIdentifiers.cs.meta new file mode 100644 index 0000000..3258a31 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/PKCSObjectIdentifiers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5caa5369f2ec3a74da71d8f6903048f4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/Pfx.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/Pfx.cs new file mode 100644 index 0000000..c1399e5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/Pfx.cs @@ -0,0 +1,63 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + /** + * the infamous Pfx from Pkcs12 + */ + public class Pfx + : Asn1Encodable + { + public static Pfx GetInstance(object obj) + { + if (obj is Pfx) + return (Pfx)obj; + if (obj == null) + return null; + return new Pfx(Asn1Sequence.GetInstance(obj)); + } + + private readonly ContentInfo contentInfo; + private readonly MacData macData; + + private Pfx(Asn1Sequence seq) + { + DerInteger version = DerInteger.GetInstance(seq[0]); + if (!version.HasValue(3)) + throw new ArgumentException("wrong version for PFX PDU"); + + this.contentInfo = ContentInfo.GetInstance(seq[1]); + + if (seq.Count == 3) + { + this.macData = MacData.GetInstance(seq[2]); + } + } + + public Pfx(ContentInfo contentInfo, MacData macData) + { + this.contentInfo = contentInfo; + this.macData = macData; + } + + public ContentInfo AuthSafe + { + get { return contentInfo; } + } + + public MacData MacData + { + get { return macData; } + } + + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(new DerInteger(3), contentInfo); + v.AddOptional(macData); + return new BerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/Pfx.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/Pfx.cs.meta new file mode 100644 index 0000000..faac37b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/Pfx.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2c8b6a76144e93a479822d1420e7f351 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/PrivateKeyInfo.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/PrivateKeyInfo.cs new file mode 100644 index 0000000..d52a31f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/PrivateKeyInfo.cs @@ -0,0 +1,205 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + /** + * RFC 5958 + * + *
+     *  [IMPLICIT TAGS]
+     *
+     *  OneAsymmetricKey ::= SEQUENCE {
+     *      version                   Version,
+     *      privateKeyAlgorithm       PrivateKeyAlgorithmIdentifier,
+     *      privateKey                PrivateKey,
+     *      attributes            [0] Attributes OPTIONAL,
+     *      ...,
+     *      [[2: publicKey        [1] PublicKey OPTIONAL ]],
+     *      ...
+     *  }
+     *
+     *  PrivateKeyInfo ::= OneAsymmetricKey
+     *
+     *  Version ::= INTEGER { v1(0), v2(1) } (v1, ..., v2)
+     *
+     *  PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
+     *                                     { PUBLIC-KEY,
+     *                                       { PrivateKeyAlgorithms } }
+     *
+     *  PrivateKey ::= OCTET STRING
+     *                     -- Content varies based on type of key.  The
+     *                     -- algorithm identifier dictates the format of
+     *                     -- the key.
+     *
+     *  PublicKey ::= BIT STRING
+     *                     -- Content varies based on type of key.  The
+     *                     -- algorithm identifier dictates the format of
+     *                     -- the key.
+     *
+     *  Attributes ::= SET OF Attribute { { OneAsymmetricKeyAttributes } }
+     *  
+ */ + public class PrivateKeyInfo + : Asn1Encodable + { + private readonly DerInteger version; + private readonly AlgorithmIdentifier privateKeyAlgorithm; + private readonly Asn1OctetString privateKey; + private readonly Asn1Set attributes; + private readonly DerBitString publicKey; + + public static PrivateKeyInfo GetInstance(Asn1TaggedObject obj, bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static PrivateKeyInfo GetInstance( + object obj) + { + if (obj == null) + return null; + if (obj is PrivateKeyInfo) + return (PrivateKeyInfo)obj; + return new PrivateKeyInfo(Asn1Sequence.GetInstance(obj)); + } + + private static int GetVersionValue(DerInteger version) + { + BigInteger bigValue = version.Value; + if (bigValue.CompareTo(BigInteger.Zero) < 0 || bigValue.CompareTo(BigInteger.One) > 0) + throw new ArgumentException("invalid version for private key info", "version"); + + return bigValue.IntValue; + } + + public PrivateKeyInfo( + AlgorithmIdentifier privateKeyAlgorithm, + Asn1Encodable privateKey) + : this(privateKeyAlgorithm, privateKey, null, null) + { + } + + public PrivateKeyInfo( + AlgorithmIdentifier privateKeyAlgorithm, + Asn1Encodable privateKey, + Asn1Set attributes) + : this(privateKeyAlgorithm, privateKey, attributes, null) + { + } + + public PrivateKeyInfo( + AlgorithmIdentifier privateKeyAlgorithm, + Asn1Encodable privateKey, + Asn1Set attributes, + byte[] publicKey) + { + this.version = new DerInteger(publicKey != null ? BigInteger.One : BigInteger.Zero); + this.privateKeyAlgorithm = privateKeyAlgorithm; + this.privateKey = new DerOctetString(privateKey); + this.attributes = attributes; + this.publicKey = publicKey == null ? null : new DerBitString(publicKey); + } + + private PrivateKeyInfo(Asn1Sequence seq) + { + IEnumerator e = seq.GetEnumerator(); + + this.version = DerInteger.GetInstance(CollectionUtilities.RequireNext(e)); + + int versionValue = GetVersionValue(version); + + this.privateKeyAlgorithm = AlgorithmIdentifier.GetInstance(CollectionUtilities.RequireNext(e)); + this.privateKey = Asn1OctetString.GetInstance(CollectionUtilities.RequireNext(e)); + + int lastTag = -1; + while (e.MoveNext()) + { + Asn1TaggedObject tagged = (Asn1TaggedObject)e.Current; + + int tag = tagged.TagNo; + if (tag <= lastTag) + throw new ArgumentException("invalid optional field in private key info", "seq"); + + lastTag = tag; + + switch (tag) + { + case 0: + { + this.attributes = Asn1Set.GetInstance(tagged, false); + break; + } + case 1: + { + if (versionValue < 1) + throw new ArgumentException("'publicKey' requires version v2(1) or later", "seq"); + + this.publicKey = DerBitString.GetInstance(tagged, false); + break; + } + default: + { + throw new ArgumentException("unknown optional field in private key info", "seq"); + } + } + } + } + + public virtual DerInteger Version + { + get { return version; } + } + + public virtual Asn1Set Attributes + { + get { return attributes; } + } + + /// Return true if a public key is present, false otherwise. + public virtual bool HasPublicKey + { + get { return publicKey != null; } + } + + public virtual AlgorithmIdentifier PrivateKeyAlgorithm + { + get { return privateKeyAlgorithm; } + } + + public virtual Asn1OctetString PrivateKeyData + { + get { return privateKey; } + } + + public virtual Asn1Object ParsePrivateKey() + { + return Asn1Object.FromByteArray(privateKey.GetOctets()); + } + + /// For when the public key is an ASN.1 encoding. + public virtual Asn1Object ParsePublicKey() + { + return publicKey == null ? null : Asn1Object.FromByteArray(publicKey.GetOctets()); + } + + /// Return the public key as a raw bit string. + public virtual DerBitString PublicKeyData + { + get { return publicKey; } + } + + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(version, privateKeyAlgorithm, privateKey); + v.AddOptionalTagged(false, 0, attributes); + v.AddOptionalTagged(false, 1, publicKey); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/PrivateKeyInfo.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/PrivateKeyInfo.cs.meta new file mode 100644 index 0000000..b13cb28 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/PrivateKeyInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 02d4ea2660f8dbb4780e7954d90629a0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/RC2CBCParameter.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/RC2CBCParameter.cs new file mode 100644 index 0000000..48591f2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/RC2CBCParameter.cs @@ -0,0 +1,74 @@ +using System; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + public class RC2CbcParameter + : Asn1Encodable + { + internal DerInteger version; + internal Asn1OctetString iv; + + public static RC2CbcParameter GetInstance( + object obj) + { + if (obj is Asn1Sequence) + { + return new RC2CbcParameter((Asn1Sequence) obj); + } + + throw new ArgumentException("Unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + public RC2CbcParameter( + byte[] iv) + { + this.iv = new DerOctetString(iv); + } + + public RC2CbcParameter( + int parameterVersion, + byte[] iv) + { + this.version = new DerInteger(parameterVersion); + this.iv = new DerOctetString(iv); + } + + private RC2CbcParameter( + Asn1Sequence seq) + { + if (seq.Count == 1) + { + iv = (Asn1OctetString)seq[0]; + } + else + { + version = (DerInteger)seq[0]; + iv = (Asn1OctetString)seq[1]; + } + } + + public BigInteger RC2ParameterVersion + { + get + { + return version == null ? null : version.Value; + } + } + + public byte[] GetIV() + { + return Arrays.Clone(iv.GetOctets()); + } + + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + v.AddOptional(version); + v.Add(iv); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/RC2CBCParameter.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/RC2CBCParameter.cs.meta new file mode 100644 index 0000000..3451610 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/RC2CBCParameter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d906194da9022f746a6544f1b0a9a55f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/RSAESOAEPparams.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/RSAESOAEPparams.cs new file mode 100644 index 0000000..2419e33 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/RSAESOAEPparams.cs @@ -0,0 +1,151 @@ +using System; + +using Org.BouncyCastle.Asn1.Oiw; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + public class RsaesOaepParameters + : Asn1Encodable + { + private AlgorithmIdentifier hashAlgorithm; + private AlgorithmIdentifier maskGenAlgorithm; + private AlgorithmIdentifier pSourceAlgorithm; + + public readonly static AlgorithmIdentifier DefaultHashAlgorithm = new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1, DerNull.Instance); + public readonly static AlgorithmIdentifier DefaultMaskGenFunction = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, DefaultHashAlgorithm); + public readonly static AlgorithmIdentifier DefaultPSourceAlgorithm = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdPSpecified, new DerOctetString(new byte[0])); + + public static RsaesOaepParameters GetInstance( + object obj) + { + if (obj is RsaesOaepParameters) + { + return (RsaesOaepParameters)obj; + } + else if (obj is Asn1Sequence) + { + return new RsaesOaepParameters((Asn1Sequence)obj); + } + + throw new ArgumentException("Unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + /** + * The default version + */ + public RsaesOaepParameters() + : this(DefaultHashAlgorithm, DefaultMaskGenFunction, DefaultPSourceAlgorithm) + { + } + + public RsaesOaepParameters( + AlgorithmIdentifier hashAlgorithm, + AlgorithmIdentifier maskGenAlgorithm) + : this(hashAlgorithm, maskGenAlgorithm, DefaultPSourceAlgorithm) + { + } + + public RsaesOaepParameters( + AlgorithmIdentifier hashAlgorithm, + AlgorithmIdentifier maskGenAlgorithm, + AlgorithmIdentifier pSourceAlgorithm) + { + this.hashAlgorithm = hashAlgorithm; + this.maskGenAlgorithm = maskGenAlgorithm; + this.pSourceAlgorithm = pSourceAlgorithm; + } + + public RsaesOaepParameters( + Asn1Sequence seq) + { + hashAlgorithm = DefaultHashAlgorithm; + maskGenAlgorithm = DefaultMaskGenFunction; + pSourceAlgorithm = DefaultPSourceAlgorithm; + + for (int i = 0; i != seq.Count; i++) + { + Asn1TaggedObject o = (Asn1TaggedObject)seq[i]; + + switch (o.TagNo) + { + case 0: + hashAlgorithm = AlgorithmIdentifier.GetInstance(o, true); + break; + case 1: + maskGenAlgorithm = AlgorithmIdentifier.GetInstance(o, true); + break; + case 2: + pSourceAlgorithm = AlgorithmIdentifier.GetInstance(o, true); + break; + default: + throw new ArgumentException("unknown tag"); + } + } + } + + public AlgorithmIdentifier HashAlgorithm + { + get { return hashAlgorithm; } + } + + public AlgorithmIdentifier MaskGenAlgorithm + { + get { return maskGenAlgorithm; } + } + + public AlgorithmIdentifier PSourceAlgorithm + { + get { return pSourceAlgorithm; } + } + + /** + *
+		 *  RSAES-OAEP-params ::= SEQUENCE {
+		 *     hashAlgorithm      [0] OAEP-PSSDigestAlgorithms     DEFAULT sha1,
+		 *     maskGenAlgorithm   [1] PKCS1MGFAlgorithms  DEFAULT mgf1SHA1,
+		 *     pSourceAlgorithm   [2] PKCS1PSourceAlgorithms  DEFAULT pSpecifiedEmpty
+		 *   }
+		 *
+		 *   OAEP-PSSDigestAlgorithms    ALGORITHM-IDENTIFIER ::= {
+		 *     { OID id-sha1 PARAMETERS NULL   }|
+		 *     { OID id-sha256 PARAMETERS NULL }|
+		 *     { OID id-sha384 PARAMETERS NULL }|
+		 *     { OID id-sha512 PARAMETERS NULL },
+		 *     ...  -- Allows for future expansion --
+		 *   }
+		 *   PKCS1MGFAlgorithms    ALGORITHM-IDENTIFIER ::= {
+		 *     { OID id-mgf1 PARAMETERS OAEP-PSSDigestAlgorithms },
+		 *    ...  -- Allows for future expansion --
+		 *   }
+		 *   PKCS1PSourceAlgorithms    ALGORITHM-IDENTIFIER ::= {
+		 *     { OID id-pSpecified PARAMETERS OCTET STRING },
+		 *     ...  -- Allows for future expansion --
+		 *  }
+		 * 
+ * @return the asn1 primitive representing the parameters. + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + + if (!hashAlgorithm.Equals(DefaultHashAlgorithm)) + { + v.Add(new DerTaggedObject(true, 0, hashAlgorithm)); + } + + if (!maskGenAlgorithm.Equals(DefaultMaskGenFunction)) + { + v.Add(new DerTaggedObject(true, 1, maskGenAlgorithm)); + } + + if (!pSourceAlgorithm.Equals(DefaultPSourceAlgorithm)) + { + v.Add(new DerTaggedObject(true, 2, pSourceAlgorithm)); + } + + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/RSAESOAEPparams.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/RSAESOAEPparams.cs.meta new file mode 100644 index 0000000..1e9154a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/RSAESOAEPparams.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5a9b994e723999a479a3d478518810bf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/RSAPrivateKeyStructure.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/RSAPrivateKeyStructure.cs new file mode 100644 index 0000000..738a97e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/RSAPrivateKeyStructure.cs @@ -0,0 +1,146 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + public class RsaPrivateKeyStructure + : Asn1Encodable + { + private readonly BigInteger modulus; + private readonly BigInteger publicExponent; + private readonly BigInteger privateExponent; + private readonly BigInteger prime1; + private readonly BigInteger prime2; + private readonly BigInteger exponent1; + private readonly BigInteger exponent2; + private readonly BigInteger coefficient; + + public static RsaPrivateKeyStructure GetInstance(Asn1TaggedObject obj, bool isExplicit) + { + return GetInstance(Asn1Sequence.GetInstance(obj, isExplicit)); + } + + public static RsaPrivateKeyStructure GetInstance(object obj) + { + if (obj == null) + return null; + if (obj is RsaPrivateKeyStructure) + return (RsaPrivateKeyStructure)obj; + return new RsaPrivateKeyStructure(Asn1Sequence.GetInstance(obj)); + } + + public RsaPrivateKeyStructure( + BigInteger modulus, + BigInteger publicExponent, + BigInteger privateExponent, + BigInteger prime1, + BigInteger prime2, + BigInteger exponent1, + BigInteger exponent2, + BigInteger coefficient) + { + this.modulus = modulus; + this.publicExponent = publicExponent; + this.privateExponent = privateExponent; + this.prime1 = prime1; + this.prime2 = prime2; + this.exponent1 = exponent1; + this.exponent2 = exponent2; + this.coefficient = coefficient; + } + + [Obsolete("Use 'GetInstance' method(s) instead")] + public RsaPrivateKeyStructure( + Asn1Sequence seq) + { + BigInteger version = ((DerInteger)seq[0]).Value; + if (version.IntValue != 0) + throw new ArgumentException("wrong version for RSA private key"); + + modulus = ((DerInteger)seq[1]).Value; + publicExponent = ((DerInteger)seq[2]).Value; + privateExponent = ((DerInteger)seq[3]).Value; + prime1 = ((DerInteger)seq[4]).Value; + prime2 = ((DerInteger)seq[5]).Value; + exponent1 = ((DerInteger)seq[6]).Value; + exponent2 = ((DerInteger)seq[7]).Value; + coefficient = ((DerInteger)seq[8]).Value; + } + + public BigInteger Modulus + { + get { return modulus; } + } + + public BigInteger PublicExponent + { + get { return publicExponent; } + } + + public BigInteger PrivateExponent + { + get { return privateExponent; } + } + + public BigInteger Prime1 + { + get { return prime1; } + } + + public BigInteger Prime2 + { + get { return prime2; } + } + + public BigInteger Exponent1 + { + get { return exponent1; } + } + + public BigInteger Exponent2 + { + get { return exponent2; } + } + + public BigInteger Coefficient + { + get { return coefficient; } + } + + /** + * This outputs the key in Pkcs1v2 format. + *
+         *      RsaPrivateKey ::= Sequence {
+         *                          version Version,
+         *                          modulus Integer, -- n
+         *                          publicExponent Integer, -- e
+         *                          privateExponent Integer, -- d
+         *                          prime1 Integer, -- p
+         *                          prime2 Integer, -- q
+         *                          exponent1 Integer, -- d mod (p-1)
+         *                          exponent2 Integer, -- d mod (q-1)
+         *                          coefficient Integer -- (inverse of q) mod p
+         *                      }
+         *
+         *      Version ::= Integer
+         * 
+ *

This routine is written to output Pkcs1 version 0, private keys.

+ */ + public override Asn1Object ToAsn1Object() + { + return new DerSequence( + new DerInteger(0), // version + new DerInteger(Modulus), + new DerInteger(PublicExponent), + new DerInteger(PrivateExponent), + new DerInteger(Prime1), + new DerInteger(Prime2), + new DerInteger(Exponent1), + new DerInteger(Exponent2), + new DerInteger(Coefficient)); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/RSAPrivateKeyStructure.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/RSAPrivateKeyStructure.cs.meta new file mode 100644 index 0000000..458ee04 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/RSAPrivateKeyStructure.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ba9f967b5d564554fbfe7adc831127d4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/RSASSAPSSparams.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/RSASSAPSSparams.cs new file mode 100644 index 0000000..85849c3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/RSASSAPSSparams.cs @@ -0,0 +1,166 @@ +using System; + +using Org.BouncyCastle.Asn1.Oiw; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + public class RsassaPssParameters + : Asn1Encodable + { + private AlgorithmIdentifier hashAlgorithm; + private AlgorithmIdentifier maskGenAlgorithm; + private DerInteger saltLength; + private DerInteger trailerField; + + public readonly static AlgorithmIdentifier DefaultHashAlgorithm = new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1, DerNull.Instance); + public readonly static AlgorithmIdentifier DefaultMaskGenFunction = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, DefaultHashAlgorithm); + public readonly static DerInteger DefaultSaltLength = new DerInteger(20); + public readonly static DerInteger DefaultTrailerField = new DerInteger(1); + + public static RsassaPssParameters GetInstance( + object obj) + { + if (obj == null || obj is RsassaPssParameters) + { + return (RsassaPssParameters)obj; + } + + if (obj is Asn1Sequence) + { + return new RsassaPssParameters((Asn1Sequence)obj); + } + + throw new ArgumentException("Unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + /** + * The default version + */ + public RsassaPssParameters() + { + hashAlgorithm = DefaultHashAlgorithm; + maskGenAlgorithm = DefaultMaskGenFunction; + saltLength = DefaultSaltLength; + trailerField = DefaultTrailerField; + } + + public RsassaPssParameters( + AlgorithmIdentifier hashAlgorithm, + AlgorithmIdentifier maskGenAlgorithm, + DerInteger saltLength, + DerInteger trailerField) + { + this.hashAlgorithm = hashAlgorithm; + this.maskGenAlgorithm = maskGenAlgorithm; + this.saltLength = saltLength; + this.trailerField = trailerField; + } + + public RsassaPssParameters( + Asn1Sequence seq) + { + hashAlgorithm = DefaultHashAlgorithm; + maskGenAlgorithm = DefaultMaskGenFunction; + saltLength = DefaultSaltLength; + trailerField = DefaultTrailerField; + + for (int i = 0; i != seq.Count; i++) + { + Asn1TaggedObject o = (Asn1TaggedObject)seq[i]; + + switch (o.TagNo) + { + case 0: + hashAlgorithm = AlgorithmIdentifier.GetInstance(o, true); + break; + case 1: + maskGenAlgorithm = AlgorithmIdentifier.GetInstance(o, true); + break; + case 2: + saltLength = DerInteger.GetInstance(o, true); + break; + case 3: + trailerField = DerInteger.GetInstance(o, true); + break; + default: + throw new ArgumentException("unknown tag"); + } + } + } + + public AlgorithmIdentifier HashAlgorithm + { + get { return hashAlgorithm; } + } + + public AlgorithmIdentifier MaskGenAlgorithm + { + get { return maskGenAlgorithm; } + } + + public DerInteger SaltLength + { + get { return saltLength; } + } + + public DerInteger TrailerField + { + get { return trailerField; } + } + + /** + *
+		 * RSASSA-PSS-params ::= SEQUENCE {
+		 *   hashAlgorithm      [0] OAEP-PSSDigestAlgorithms  DEFAULT sha1,
+		 *    maskGenAlgorithm   [1] PKCS1MGFAlgorithms  DEFAULT mgf1SHA1,
+		 *    saltLength         [2] INTEGER  DEFAULT 20,
+		 *    trailerField       [3] TrailerField  DEFAULT trailerFieldBC
+		 *  }
+		 *
+		 * OAEP-PSSDigestAlgorithms    ALGORITHM-IDENTIFIER ::= {
+		 *    { OID id-sha1 PARAMETERS NULL   }|
+		 *    { OID id-sha256 PARAMETERS NULL }|
+		 *    { OID id-sha384 PARAMETERS NULL }|
+		 *    { OID id-sha512 PARAMETERS NULL },
+		 *    ...  -- Allows for future expansion --
+		 * }
+		 *
+		 * PKCS1MGFAlgorithms    ALGORITHM-IDENTIFIER ::= {
+		 *   { OID id-mgf1 PARAMETERS OAEP-PSSDigestAlgorithms },
+		 *    ...  -- Allows for future expansion --
+		 * }
+		 *
+		 * TrailerField ::= INTEGER { trailerFieldBC(1) }
+		 * 
+ * @return the asn1 primitive representing the parameters. + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + + if (!hashAlgorithm.Equals(DefaultHashAlgorithm)) + { + v.Add(new DerTaggedObject(true, 0, hashAlgorithm)); + } + + if (!maskGenAlgorithm.Equals(DefaultMaskGenFunction)) + { + v.Add(new DerTaggedObject(true, 1, maskGenAlgorithm)); + } + + if (!saltLength.Equals(DefaultSaltLength)) + { + v.Add(new DerTaggedObject(true, 2, saltLength)); + } + + if (!trailerField.Equals(DefaultTrailerField)) + { + v.Add(new DerTaggedObject(true, 3, trailerField)); + } + + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/RSASSAPSSparams.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/RSASSAPSSparams.cs.meta new file mode 100644 index 0000000..812ee7a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/RSASSAPSSparams.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 59dd828eb0209a64f83f6db92f1cd770 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/SafeBag.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/SafeBag.cs new file mode 100644 index 0000000..0ec9fa4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/SafeBag.cs @@ -0,0 +1,74 @@ +using System; + +using Org.BouncyCastle.Asn1; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + public class SafeBag + : Asn1Encodable + { + public static SafeBag GetInstance(object obj) + { + if (obj is SafeBag) + return (SafeBag)obj; + if (obj == null) + return null; + return new SafeBag(Asn1Sequence.GetInstance(obj)); + } + + private readonly DerObjectIdentifier bagID; + private readonly Asn1Object bagValue; + private readonly Asn1Set bagAttributes; + + public SafeBag( + DerObjectIdentifier oid, + Asn1Object obj) + { + this.bagID = oid; + this.bagValue = obj; + this.bagAttributes = null; + } + + public SafeBag( + DerObjectIdentifier oid, + Asn1Object obj, + Asn1Set bagAttributes) + { + this.bagID = oid; + this.bagValue = obj; + this.bagAttributes = bagAttributes; + } + + private SafeBag(Asn1Sequence seq) + { + this.bagID = (DerObjectIdentifier)seq[0]; + this.bagValue = ((DerTaggedObject)seq[1]).GetObject(); + if (seq.Count == 3) + { + this.bagAttributes = (Asn1Set)seq[2]; + } + } + + public DerObjectIdentifier BagID + { + get { return bagID; } + } + + public Asn1Object BagValue + { + get { return bagValue; } + } + + public Asn1Set BagAttributes + { + get { return bagAttributes; } + } + + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(bagID, new DerTaggedObject(0, bagValue)); + v.AddOptional(bagAttributes); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/SafeBag.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/SafeBag.cs.meta new file mode 100644 index 0000000..cec85cb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/SafeBag.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 96b2cb404c1b94e4897cbac9f2f30606 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/SignedData.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/SignedData.cs new file mode 100644 index 0000000..ae33510 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/SignedData.cs @@ -0,0 +1,146 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + /** + * a Pkcs#7 signed data object. + */ + public class SignedData + : Asn1Encodable + { + private readonly DerInteger version; + private readonly Asn1Set digestAlgorithms; + private readonly ContentInfo contentInfo; + private readonly Asn1Set certificates; + private readonly Asn1Set crls; + private readonly Asn1Set signerInfos; + + public static SignedData GetInstance(object obj) + { + if (obj == null) + return null; + SignedData existing = obj as SignedData; + if (existing != null) + return existing; + return new SignedData(Asn1Sequence.GetInstance(obj)); + } + + public SignedData( + DerInteger _version, + Asn1Set _digestAlgorithms, + ContentInfo _contentInfo, + Asn1Set _certificates, + Asn1Set _crls, + Asn1Set _signerInfos) + { + version = _version; + digestAlgorithms = _digestAlgorithms; + contentInfo = _contentInfo; + certificates = _certificates; + crls = _crls; + signerInfos = _signerInfos; + } + + private SignedData( + Asn1Sequence seq) + { + IEnumerator e = seq.GetEnumerator(); + + e.MoveNext(); + version = (DerInteger) e.Current; + + e.MoveNext(); + digestAlgorithms = (Asn1Set) e.Current; + + e.MoveNext(); + contentInfo = ContentInfo.GetInstance(e.Current); + + while (e.MoveNext()) + { + Asn1Object o = (Asn1Object) e.Current; + + // + // an interesting feature of SignedData is that there appear to be varying implementations... + // for the moment we ignore anything which doesn't fit. + // + if (o is Asn1TaggedObject) + { + Asn1TaggedObject tagged = (Asn1TaggedObject)o; + + switch (tagged.TagNo) + { + case 0: + certificates = Asn1Set.GetInstance(tagged, false); + break; + case 1: + crls = Asn1Set.GetInstance(tagged, false); + break; + default: + throw new ArgumentException("unknown tag value " + tagged.TagNo); + } + } + else + { + signerInfos = (Asn1Set) o; + } + } + } + + public DerInteger Version + { + get { return version; } + } + + public Asn1Set DigestAlgorithms + { + get { return digestAlgorithms; } + } + + public ContentInfo ContentInfo + { + get { return contentInfo; } + } + + public Asn1Set Certificates + { + get { return certificates; } + } + + public Asn1Set Crls + { + get { return crls; } + } + + public Asn1Set SignerInfos + { + get { return signerInfos; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         *  SignedData ::= Sequence {
+         *      version Version,
+         *      digestAlgorithms DigestAlgorithmIdentifiers,
+         *      contentInfo ContentInfo,
+         *      certificates
+         *          [0] IMPLICIT ExtendedCertificatesAndCertificates
+         *                   OPTIONAL,
+         *      crls
+         *          [1] IMPLICIT CertificateRevocationLists OPTIONAL,
+         *      signerInfos SignerInfos }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(version, digestAlgorithms, contentInfo); + v.AddOptionalTagged(false, 0, certificates); + v.AddOptionalTagged(false, 1, crls); + v.Add(signerInfos); + return new BerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/SignedData.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/SignedData.cs.meta new file mode 100644 index 0000000..daa2650 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/SignedData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2b2d51c8c7a25dc48abdf7423852ccf7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/SignerInfo.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/SignerInfo.cs new file mode 100644 index 0000000..c594b45 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/SignerInfo.cs @@ -0,0 +1,143 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Pkcs +{ + /** + * a Pkcs#7 signer info object. + */ + public class SignerInfo + : Asn1Encodable + { + private DerInteger version; + private IssuerAndSerialNumber issuerAndSerialNumber; + private AlgorithmIdentifier digAlgorithm; + private Asn1Set authenticatedAttributes; + private AlgorithmIdentifier digEncryptionAlgorithm; + private Asn1OctetString encryptedDigest; + private Asn1Set unauthenticatedAttributes; + + public static SignerInfo GetInstance( + object obj) + { + if (obj is SignerInfo) + { + return (SignerInfo) obj; + } + + if (obj is Asn1Sequence) + { + return new SignerInfo((Asn1Sequence) obj); + } + + throw new ArgumentException("Unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + public SignerInfo( + DerInteger version, + IssuerAndSerialNumber issuerAndSerialNumber, + AlgorithmIdentifier digAlgorithm, + Asn1Set authenticatedAttributes, + AlgorithmIdentifier digEncryptionAlgorithm, + Asn1OctetString encryptedDigest, + Asn1Set unauthenticatedAttributes) + { + this.version = version; + this.issuerAndSerialNumber = issuerAndSerialNumber; + this.digAlgorithm = digAlgorithm; + this.authenticatedAttributes = authenticatedAttributes; + this.digEncryptionAlgorithm = digEncryptionAlgorithm; + this.encryptedDigest = encryptedDigest; + this.unauthenticatedAttributes = unauthenticatedAttributes; + } + + public SignerInfo( + Asn1Sequence seq) + { + IEnumerator e = seq.GetEnumerator(); + + e.MoveNext(); + version = (DerInteger) e.Current; + + e.MoveNext(); + issuerAndSerialNumber = IssuerAndSerialNumber.GetInstance(e.Current); + + e.MoveNext(); + digAlgorithm = AlgorithmIdentifier.GetInstance(e.Current); + + e.MoveNext(); + object obj = e.Current; + + if (obj is Asn1TaggedObject) + { + authenticatedAttributes = Asn1Set.GetInstance((Asn1TaggedObject) obj, false); + + e.MoveNext(); + digEncryptionAlgorithm = AlgorithmIdentifier.GetInstance(e.Current); + } + else + { + authenticatedAttributes = null; + digEncryptionAlgorithm = AlgorithmIdentifier.GetInstance(obj); + } + + e.MoveNext(); + encryptedDigest = DerOctetString.GetInstance(e.Current); + + if (e.MoveNext()) + { + unauthenticatedAttributes = Asn1Set.GetInstance((Asn1TaggedObject)e.Current, false); + } + else + { + unauthenticatedAttributes = null; + } + } + + public DerInteger Version { get { return version; } } + + public IssuerAndSerialNumber IssuerAndSerialNumber { get { return issuerAndSerialNumber; } } + + public Asn1Set AuthenticatedAttributes { get { return authenticatedAttributes; } } + + public AlgorithmIdentifier DigestAlgorithm { get { return digAlgorithm; } } + + public Asn1OctetString EncryptedDigest { get { return encryptedDigest; } } + + public AlgorithmIdentifier DigestEncryptionAlgorithm { get { return digEncryptionAlgorithm; } } + + public Asn1Set UnauthenticatedAttributes { get { return unauthenticatedAttributes; } } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         *  SignerInfo ::= Sequence {
+         *      version Version,
+         *      issuerAndSerialNumber IssuerAndSerialNumber,
+         *      digestAlgorithm DigestAlgorithmIdentifier,
+         *      authenticatedAttributes [0] IMPLICIT Attributes OPTIONAL,
+         *      digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier,
+         *      encryptedDigest EncryptedDigest,
+         *      unauthenticatedAttributes [1] IMPLICIT Attributes OPTIONAL
+         *  }
+         *
+         *  EncryptedDigest ::= OCTET STRING
+         *
+         *  DigestAlgorithmIdentifier ::= AlgorithmIdentifier
+         *
+         *  DigestEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(version, issuerAndSerialNumber, digAlgorithm); + v.AddOptionalTagged(false, 0, authenticatedAttributes); + v.Add(digEncryptionAlgorithm, encryptedDigest); + v.AddOptionalTagged(false, 1, unauthenticatedAttributes); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/SignerInfo.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/SignerInfo.cs.meta new file mode 100644 index 0000000..d28a96a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/pkcs/SignerInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a42807ad9349c7a4aad408b670895f18 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/rosstandart.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/rosstandart.meta new file mode 100644 index 0000000..f9d4d5a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/rosstandart.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f966b21e8504e7043b18bb428cd67fcd +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/rosstandart/RosstandartObjectIdentifiers.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/rosstandart/RosstandartObjectIdentifiers.cs new file mode 100644 index 0000000..86fedb7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/rosstandart/RosstandartObjectIdentifiers.cs @@ -0,0 +1,47 @@ +using System; + +namespace Org.BouncyCastle.Asn1.Rosstandart +{ + public abstract class RosstandartObjectIdentifiers + { + public static readonly DerObjectIdentifier rosstandart = new DerObjectIdentifier("1.2.643.7"); + + public static readonly DerObjectIdentifier id_tc26 = rosstandart.Branch("1"); + + public static readonly DerObjectIdentifier id_tc26_gost_3411_12_256 = id_tc26.Branch("1.2.2"); + + public static readonly DerObjectIdentifier id_tc26_gost_3411_12_512 = id_tc26.Branch("1.2.3"); + + public static readonly DerObjectIdentifier id_tc26_hmac_gost_3411_12_256 = id_tc26.Branch("1.4.1"); + + public static readonly DerObjectIdentifier id_tc26_hmac_gost_3411_12_512 = id_tc26.Branch("1.4.2"); + + public static readonly DerObjectIdentifier id_tc26_gost_3410_12_256 = id_tc26.Branch("1.1.1"); + + public static readonly DerObjectIdentifier id_tc26_gost_3410_12_512 = id_tc26.Branch("1.1.2"); + + public static readonly DerObjectIdentifier id_tc26_signwithdigest_gost_3410_12_256 = id_tc26.Branch("1.3.2"); + + public static readonly DerObjectIdentifier id_tc26_signwithdigest_gost_3410_12_512 = id_tc26.Branch("1.3.3"); + + public static readonly DerObjectIdentifier id_tc26_agreement = id_tc26.Branch("1.6"); + + public static readonly DerObjectIdentifier id_tc26_agreement_gost_3410_12_256 = id_tc26_agreement.Branch("1"); + + public static readonly DerObjectIdentifier id_tc26_agreement_gost_3410_12_512 = id_tc26_agreement.Branch("2"); + + public static readonly DerObjectIdentifier id_tc26_gost_3410_12_256_paramSet = id_tc26.Branch("2.1.1"); + + public static readonly DerObjectIdentifier id_tc26_gost_3410_12_256_paramSetA = id_tc26_gost_3410_12_256_paramSet.Branch("1"); + + public static readonly DerObjectIdentifier id_tc26_gost_3410_12_512_paramSet = id_tc26.Branch("2.1.2"); + + public static readonly DerObjectIdentifier id_tc26_gost_3410_12_512_paramSetA = id_tc26_gost_3410_12_512_paramSet.Branch("1"); + + public static readonly DerObjectIdentifier id_tc26_gost_3410_12_512_paramSetB = id_tc26_gost_3410_12_512_paramSet.Branch("2"); + + public static readonly DerObjectIdentifier id_tc26_gost_3410_12_512_paramSetC = id_tc26_gost_3410_12_512_paramSet.Branch("3"); + + public static readonly DerObjectIdentifier id_tc26_gost_28147_param_Z = id_tc26.Branch("2.5.1.1"); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/rosstandart/RosstandartObjectIdentifiers.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/rosstandart/RosstandartObjectIdentifiers.cs.meta new file mode 100644 index 0000000..eae4549 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/rosstandart/RosstandartObjectIdentifiers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3ff547dc61145094ba6a42e69506dccd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/sec.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/sec.meta new file mode 100644 index 0000000..4cece3e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/sec.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c13a19356d51d0f41a6a81e3b92eda6f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/sec/ECPrivateKeyStructure.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/sec/ECPrivateKeyStructure.cs new file mode 100644 index 0000000..aec8e0a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/sec/ECPrivateKeyStructure.cs @@ -0,0 +1,175 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Sec +{ + /** + * the elliptic curve private key object from SEC 1 + */ + public class ECPrivateKeyStructure + : Asn1Encodable + { + private readonly Asn1Sequence seq; + + public static ECPrivateKeyStructure GetInstance(object obj) + { + if (obj == null) + return null; + if (obj is ECPrivateKeyStructure) + return (ECPrivateKeyStructure)obj; + return new ECPrivateKeyStructure(Asn1Sequence.GetInstance(obj)); + } + + [Obsolete("Use 'GetInstance' instead")] + public ECPrivateKeyStructure( + Asn1Sequence seq) + { + if (seq == null) + throw new ArgumentNullException("seq"); + + this.seq = seq; + } + + [Obsolete("Use constructor which takes 'orderBitLength' instead, to guarantee correct encoding")] + public ECPrivateKeyStructure( + BigInteger key) + { + if (key == null) + throw new ArgumentNullException("key"); + + this.seq = new DerSequence( + new DerInteger(1), + new DerOctetString(key.ToByteArrayUnsigned())); + } + + public ECPrivateKeyStructure( + int orderBitLength, + BigInteger key) + : this(orderBitLength, key, null) + { + } + + [Obsolete("Use constructor which takes 'orderBitLength' instead, to guarantee correct encoding")] + public ECPrivateKeyStructure( + BigInteger key, + Asn1Encodable parameters) + : this(key, null, parameters) + { + } + + [Obsolete("Use constructor which takes 'orderBitLength' instead, to guarantee correct encoding")] + public ECPrivateKeyStructure( + BigInteger key, + DerBitString publicKey, + Asn1Encodable parameters) + { + if (key == null) + throw new ArgumentNullException("key"); + + Asn1EncodableVector v = new Asn1EncodableVector( + new DerInteger(1), + new DerOctetString(key.ToByteArrayUnsigned())); + + if (parameters != null) + { + v.Add(new DerTaggedObject(true, 0, parameters)); + } + + if (publicKey != null) + { + v.Add(new DerTaggedObject(true, 1, publicKey)); + } + + this.seq = new DerSequence(v); + } + + public ECPrivateKeyStructure( + int orderBitLength, + BigInteger key, + Asn1Encodable parameters) + : this(orderBitLength, key, null, parameters) + { + } + + public ECPrivateKeyStructure( + int orderBitLength, + BigInteger key, + DerBitString publicKey, + Asn1Encodable parameters) + { + if (key == null) + throw new ArgumentNullException("key"); + if (orderBitLength < key.BitLength) + throw new ArgumentException("must be >= key bitlength", "orderBitLength"); + + byte[] bytes = BigIntegers.AsUnsignedByteArray((orderBitLength + 7) / 8, key); + + Asn1EncodableVector v = new Asn1EncodableVector( + new DerInteger(1), + new DerOctetString(bytes)); + + if (parameters != null) + { + v.Add(new DerTaggedObject(true, 0, parameters)); + } + + if (publicKey != null) + { + v.Add(new DerTaggedObject(true, 1, publicKey)); + } + + this.seq = new DerSequence(v); + } + + public virtual BigInteger GetKey() + { + Asn1OctetString octs = (Asn1OctetString) seq[1]; + + return new BigInteger(1, octs.GetOctets()); + } + + public virtual DerBitString GetPublicKey() + { + return (DerBitString) GetObjectInTag(1); + } + + public virtual Asn1Object GetParameters() + { + return GetObjectInTag(0); + } + + private Asn1Object GetObjectInTag(int tagNo) + { + foreach (Asn1Encodable ae in seq) + { + Asn1Object obj = ae.ToAsn1Object(); + + if (obj is Asn1TaggedObject) + { + Asn1TaggedObject tag = (Asn1TaggedObject) obj; + if (tag.TagNo == tagNo) + { + return tag.GetObject(); + } + } + } + + return null; + } + + /** + * ECPrivateKey ::= SEQUENCE { + * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), + * privateKey OCTET STRING, + * parameters [0] Parameters OPTIONAL, + * publicKey [1] BIT STRING OPTIONAL } + */ + public override Asn1Object ToAsn1Object() + { + return seq; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/sec/ECPrivateKeyStructure.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/sec/ECPrivateKeyStructure.cs.meta new file mode 100644 index 0000000..9b92680 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/sec/ECPrivateKeyStructure.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 80263d4329b7ea54598d60e027404bf9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/sec/SECNamedCurves.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/sec/SECNamedCurves.cs new file mode 100644 index 0000000..8ca0a6e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/sec/SECNamedCurves.cs @@ -0,0 +1,1204 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Math.EC.Endo; +using Org.BouncyCastle.Math.EC.Multiplier; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Asn1.Sec +{ + public sealed class SecNamedCurves + { + private SecNamedCurves() + { + } + + private static X9ECPoint ConfigureBasepoint(ECCurve curve, string encoding) + { + X9ECPoint G = new X9ECPoint(curve, Hex.DecodeStrict(encoding)); + WNafUtilities.ConfigureBasepoint(G.Point); + return G; + } + + private static ECCurve ConfigureCurve(ECCurve curve) + { + return curve; + } + + private static ECCurve ConfigureCurveGlv(ECCurve c, GlvTypeBParameters p) + { + return c.Configure().SetEndomorphism(new GlvTypeBEndomorphism(c, p)).Create(); + } + + private static BigInteger FromHex(string hex) + { + return new BigInteger(1, Hex.DecodeStrict(hex)); + } + + /* + * secp112r1 + */ + internal class Secp112r1Holder + : X9ECParametersHolder + { + private Secp112r1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Secp112r1Holder(); + + protected override X9ECParameters CreateParameters() + { + // p = (2^128 - 3) / 76439 + BigInteger p = FromHex("DB7C2ABF62E35E668076BEAD208B"); + BigInteger a = FromHex("DB7C2ABF62E35E668076BEAD2088"); + BigInteger b = FromHex("659EF8BA043916EEDE8911702B22"); + byte[] S = Hex.DecodeStrict("00F50B028E4D696E676875615175290472783FB1"); + BigInteger n = FromHex("DB7C2ABF62E35E7628DFAC6561C5"); + BigInteger h = BigInteger.One; + + ECCurve curve = ConfigureCurve(new FpCurve(p, a, b, n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "0409487239995A5EE76B55F9C2F098A89CE5AF8724C0A23E0E0FF77500"); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * secp112r2 + */ + internal class Secp112r2Holder + : X9ECParametersHolder + { + private Secp112r2Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Secp112r2Holder(); + + protected override X9ECParameters CreateParameters() + { + // p = (2^128 - 3) / 76439 + BigInteger p = FromHex("DB7C2ABF62E35E668076BEAD208B"); + BigInteger a = FromHex("6127C24C05F38A0AAAF65C0EF02C"); + BigInteger b = FromHex("51DEF1815DB5ED74FCC34C85D709"); + byte[] S = Hex.DecodeStrict("002757A1114D696E6768756151755316C05E0BD4"); + BigInteger n = FromHex("36DF0AAFD8B8D7597CA10520D04B"); + BigInteger h = BigInteger.ValueOf(4); + + ECCurve curve = ConfigureCurve(new FpCurve(p, a, b, n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "044BA30AB5E892B4E1649DD0928643ADCD46F5882E3747DEF36E956E97"); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * secp128r1 + */ + internal class Secp128r1Holder + : X9ECParametersHolder + { + private Secp128r1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Secp128r1Holder(); + + protected override X9ECParameters CreateParameters() + { + // p = 2^128 - 2^97 - 1 + BigInteger p = FromHex("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF"); + BigInteger a = FromHex("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC"); + BigInteger b = FromHex("E87579C11079F43DD824993C2CEE5ED3"); + byte[] S = Hex.DecodeStrict("000E0D4D696E6768756151750CC03A4473D03679"); + BigInteger n = FromHex("FFFFFFFE0000000075A30D1B9038A115"); + BigInteger h = BigInteger.One; + + ECCurve curve = ConfigureCurve(new FpCurve(p, a, b, n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "04161FF7528B899B2D0C28607CA52C5B86CF5AC8395BAFEB13C02DA292DDED7A83"); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * secp128r2 + */ + internal class Secp128r2Holder + : X9ECParametersHolder + { + private Secp128r2Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Secp128r2Holder(); + + protected override X9ECParameters CreateParameters() + { + // p = 2^128 - 2^97 - 1 + BigInteger p = FromHex("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF"); + BigInteger a = FromHex("D6031998D1B3BBFEBF59CC9BBFF9AEE1"); + BigInteger b = FromHex("5EEEFCA380D02919DC2C6558BB6D8A5D"); + byte[] S = Hex.DecodeStrict("004D696E67687561517512D8F03431FCE63B88F4"); + BigInteger n = FromHex("3FFFFFFF7FFFFFFFBE0024720613B5A3"); + BigInteger h = BigInteger.ValueOf(4); + + ECCurve curve = ConfigureCurve(new FpCurve(p, a, b, n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "047B6AA5D85E572983E6FB32A7CDEBC14027B6916A894D3AEE7106FE805FC34B44"); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * secp160k1 + */ + internal class Secp160k1Holder + : X9ECParametersHolder + { + private Secp160k1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Secp160k1Holder(); + + protected override X9ECParameters CreateParameters() + { + // p = 2^160 - 2^32 - 2^14 - 2^12 - 2^9 - 2^8 - 2^7 - 2^3 - 2^2 - 1 + BigInteger p = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73"); + BigInteger a = BigInteger.Zero; + BigInteger b = BigInteger.ValueOf(7); + byte[] S = null; + BigInteger n = FromHex("0100000000000000000001B8FA16DFAB9ACA16B6B3"); + BigInteger h = BigInteger.One; + + GlvTypeBParameters glv = new GlvTypeBParameters( + new BigInteger("9ba48cba5ebcb9b6bd33b92830b2a2e0e192f10a", 16), + new BigInteger("c39c6c3b3a36d7701b9c71a1f5804ae5d0003f4", 16), + new ScalarSplitParameters( + new BigInteger[]{ + new BigInteger("9162fbe73984472a0a9e", 16), + new BigInteger("-96341f1138933bc2f505", 16) }, + new BigInteger[]{ + new BigInteger("127971af8721782ecffa3", 16), + new BigInteger("9162fbe73984472a0a9e", 16) }, + new BigInteger("9162fbe73984472a0a9d0590", 16), + new BigInteger("96341f1138933bc2f503fd44", 16), + 176)); + + ECCurve curve = ConfigureCurveGlv(new FpCurve(p, a, b, n, h), glv); + + X9ECPoint G = ConfigureBasepoint(curve, + "043B4C382CE37AA192A4019E763036F4F5DD4D7EBB938CF935318FDCED6BC28286531733C3F03C4FEE"); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * secp160r1 + */ + internal class Secp160r1Holder + : X9ECParametersHolder + { + private Secp160r1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Secp160r1Holder(); + + protected override X9ECParameters CreateParameters() + { + // p = 2^160 - 2^31 - 1 + BigInteger p = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF"); + BigInteger a = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC"); + BigInteger b = FromHex("1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45"); + byte[] S = Hex.DecodeStrict("1053CDE42C14D696E67687561517533BF3F83345"); + BigInteger n = FromHex("0100000000000000000001F4C8F927AED3CA752257"); + BigInteger h = BigInteger.One; + + ECCurve curve = ConfigureCurve(new FpCurve(p, a, b, n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "044A96B5688EF573284664698968C38BB913CBFC8223A628553168947D59DCC912042351377AC5FB32"); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * secp160r2 + */ + internal class Secp160r2Holder + : X9ECParametersHolder + { + private Secp160r2Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Secp160r2Holder(); + + protected override X9ECParameters CreateParameters() + { + // p = 2^160 - 2^32 - 2^14 - 2^12 - 2^9 - 2^8 - 2^7 - 2^3 - 2^2 - 1 + BigInteger p = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73"); + BigInteger a = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70"); + BigInteger b = FromHex("B4E134D3FB59EB8BAB57274904664D5AF50388BA"); + byte[] S = Hex.DecodeStrict("B99B99B099B323E02709A4D696E6768756151751"); + BigInteger n = FromHex("0100000000000000000000351EE786A818F3A1A16B"); + BigInteger h = BigInteger.One; + + ECCurve curve = ConfigureCurve(new FpCurve(p, a, b, n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "0452DCB034293A117E1F4FF11B30F7199D3144CE6DFEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E"); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * secp192k1 + */ + internal class Secp192k1Holder + : X9ECParametersHolder + { + private Secp192k1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Secp192k1Holder(); + + protected override X9ECParameters CreateParameters() + { + // p = 2^192 - 2^32 - 2^12 - 2^8 - 2^7 - 2^6 - 2^3 - 1 + BigInteger p = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37"); + BigInteger a = BigInteger.Zero; + BigInteger b = BigInteger.ValueOf(3); + byte[] S = null; + BigInteger n = FromHex("FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D"); + BigInteger h = BigInteger.One; + + GlvTypeBParameters glv = new GlvTypeBParameters( + new BigInteger("bb85691939b869c1d087f601554b96b80cb4f55b35f433c2", 16), + new BigInteger("3d84f26c12238d7b4f3d516613c1759033b1a5800175d0b1", 16), + new ScalarSplitParameters( + new BigInteger[]{ + new BigInteger("71169be7330b3038edb025f1", 16), + new BigInteger("-b3fb3400dec5c4adceb8655c", 16) }, + new BigInteger[]{ + new BigInteger("12511cfe811d0f4e6bc688b4d", 16), + new BigInteger("71169be7330b3038edb025f1", 16) }, + new BigInteger("71169be7330b3038edb025f1d0f9", 16), + new BigInteger("b3fb3400dec5c4adceb8655d4c94", 16), + 208)); + + ECCurve curve = ConfigureCurveGlv(new FpCurve(p, a, b, n, h), glv); + + X9ECPoint G = ConfigureBasepoint(curve, + "04DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D"); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * secp192r1 + */ + internal class Secp192r1Holder + : X9ECParametersHolder + { + private Secp192r1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Secp192r1Holder(); + + protected override X9ECParameters CreateParameters() + { + // p = 2^192 - 2^64 - 1 + BigInteger p = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"); + BigInteger a = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC"); + BigInteger b = FromHex("64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1"); + byte[] S = Hex.DecodeStrict("3045AE6FC8422F64ED579528D38120EAE12196D5"); + BigInteger n = FromHex("FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831"); + BigInteger h = BigInteger.One; + + ECCurve curve = ConfigureCurve(new FpCurve(p, a, b, n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "04188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF101207192B95FFC8DA78631011ED6B24CDD573F977A11E794811"); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * secp224k1 + */ + internal class Secp224k1Holder + : X9ECParametersHolder + { + private Secp224k1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Secp224k1Holder(); + + protected override X9ECParameters CreateParameters() + { + // p = 2^224 - 2^32 - 2^12 - 2^11 - 2^9 - 2^7 - 2^4 - 2 - 1 + BigInteger p = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D"); + BigInteger a = BigInteger.Zero; + BigInteger b = BigInteger.ValueOf(5); + byte[] S = null; + BigInteger n = FromHex("010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7"); + BigInteger h = BigInteger.One; + + GlvTypeBParameters glv = new GlvTypeBParameters( + new BigInteger("fe0e87005b4e83761908c5131d552a850b3f58b749c37cf5b84d6768", 16), + new BigInteger("60dcd2104c4cbc0be6eeefc2bdd610739ec34e317f9b33046c9e4788", 16), + new ScalarSplitParameters( + new BigInteger[]{ + new BigInteger("6b8cf07d4ca75c88957d9d670591", 16), + new BigInteger("-b8adf1378a6eb73409fa6c9c637d", 16) }, + new BigInteger[]{ + new BigInteger("1243ae1b4d71613bc9f780a03690e", 16), + new BigInteger("6b8cf07d4ca75c88957d9d670591", 16) }, + new BigInteger("6b8cf07d4ca75c88957d9d67059037a4", 16), + new BigInteger("b8adf1378a6eb73409fa6c9c637ba7f5", 16), + 240)); + + ECCurve curve = ConfigureCurveGlv(new FpCurve(p, a, b, n, h), glv); + + X9ECPoint G = ConfigureBasepoint(curve, + "04A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5"); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * secp224r1 + */ + internal class Secp224r1Holder + : X9ECParametersHolder + { + private Secp224r1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Secp224r1Holder(); + + protected override X9ECParameters CreateParameters() + { + // p = 2^224 - 2^96 + 1 + BigInteger p = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001"); + BigInteger a = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE"); + BigInteger b = FromHex("B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4"); + byte[] S = Hex.DecodeStrict("BD71344799D5C7FCDC45B59FA3B9AB8F6A948BC5"); + BigInteger n = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D"); + BigInteger h = BigInteger.One; + + ECCurve curve = ConfigureCurve(new FpCurve(p, a, b, n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "04B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34"); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * secp256k1 + */ + internal class Secp256k1Holder + : X9ECParametersHolder + { + private Secp256k1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Secp256k1Holder(); + + protected override X9ECParameters CreateParameters() + { + // p = 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1 + BigInteger p = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F"); + BigInteger a = BigInteger.Zero; + BigInteger b = BigInteger.ValueOf(7); + byte[] S = null; + BigInteger n = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"); + BigInteger h = BigInteger.One; + + GlvTypeBParameters glv = new GlvTypeBParameters( + new BigInteger("7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee", 16), + new BigInteger("5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72", 16), + new ScalarSplitParameters( + new BigInteger[]{ + new BigInteger("3086d221a7d46bcde86c90e49284eb15", 16), + new BigInteger("-e4437ed6010e88286f547fa90abfe4c3", 16) }, + new BigInteger[]{ + new BigInteger("114ca50f7a8e2f3f657c1108d9d44cfd8", 16), + new BigInteger("3086d221a7d46bcde86c90e49284eb15", 16) }, + new BigInteger("3086d221a7d46bcde86c90e49284eb153dab", 16), + new BigInteger("e4437ed6010e88286f547fa90abfe4c42212", 16), + 272)); + + ECCurve curve = ConfigureCurveGlv(new FpCurve(p, a, b, n, h), glv); + + X9ECPoint G = ConfigureBasepoint(curve, + "0479BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8"); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * secp256r1 + */ + internal class Secp256r1Holder + : X9ECParametersHolder + { + private Secp256r1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Secp256r1Holder(); + + protected override X9ECParameters CreateParameters() + { + // p = 2^224 (2^32 - 1) + 2^192 + 2^96 - 1 + BigInteger p = FromHex("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF"); + BigInteger a = FromHex("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC"); + BigInteger b = FromHex("5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B"); + byte[] S = Hex.DecodeStrict("C49D360886E704936A6678E1139D26B7819F7E90"); + BigInteger n = FromHex("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551"); + BigInteger h = BigInteger.One; + + ECCurve curve = ConfigureCurve(new FpCurve(p, a, b, n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5"); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * secp384r1 + */ + internal class Secp384r1Holder + : X9ECParametersHolder + { + private Secp384r1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Secp384r1Holder(); + + protected override X9ECParameters CreateParameters() + { + // p = 2^384 - 2^128 - 2^96 + 2^32 - 1 + BigInteger p = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF"); + BigInteger a = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC"); + BigInteger b = FromHex("B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF"); + byte[] S = Hex.DecodeStrict("A335926AA319A27A1D00896A6773A4827ACDAC73"); + BigInteger n = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973"); + BigInteger h = BigInteger.One; + + ECCurve curve = ConfigureCurve(new FpCurve(p, a, b, n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, "04" + + "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7" + + "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F"); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * secp521r1 + */ + internal class Secp521r1Holder + : X9ECParametersHolder + { + private Secp521r1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Secp521r1Holder(); + + protected override X9ECParameters CreateParameters() + { + // p = 2^521 - 1 + BigInteger p = FromHex("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"); + BigInteger a = FromHex("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC"); + BigInteger b = FromHex("0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00"); + byte[] S = Hex.DecodeStrict("D09E8800291CB85396CC6717393284AAA0DA64BA"); + BigInteger n = FromHex("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409"); + BigInteger h = BigInteger.One; + + ECCurve curve = ConfigureCurve(new FpCurve(p, a, b, n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, "04" + + "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66" + + "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650"); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * sect113r1 + */ + internal class Sect113r1Holder + : X9ECParametersHolder + { + private Sect113r1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Sect113r1Holder(); + + private const int m = 113; + private const int k = 9; + + protected override X9ECParameters CreateParameters() + { + BigInteger a = FromHex("003088250CA6E7C7FE649CE85820F7"); + BigInteger b = FromHex("00E8BEE4D3E2260744188BE0E9C723"); + byte[] S = Hex.DecodeStrict("10E723AB14D696E6768756151756FEBF8FCB49A9"); + BigInteger n = FromHex("0100000000000000D9CCEC8A39E56F"); + BigInteger h = BigInteger.ValueOf(2); + + ECCurve curve = new F2mCurve(m, k, a, b, n, h); + + X9ECPoint G = ConfigureBasepoint(curve, + "04009D73616F35F4AB1407D73562C10F00A52830277958EE84D1315ED31886"); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * sect113r2 + */ + internal class Sect113r2Holder + : X9ECParametersHolder + { + private Sect113r2Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Sect113r2Holder(); + + private const int m = 113; + private const int k = 9; + + protected override X9ECParameters CreateParameters() + { + BigInteger a = FromHex("00689918DBEC7E5A0DD6DFC0AA55C7"); + BigInteger b = FromHex("0095E9A9EC9B297BD4BF36E059184F"); + byte[] S = Hex.DecodeStrict("10C0FB15760860DEF1EEF4D696E676875615175D"); + BigInteger n = FromHex("010000000000000108789B2496AF93"); + BigInteger h = BigInteger.ValueOf(2); + + ECCurve curve = new F2mCurve(m, k, a, b, n, h); + + X9ECPoint G = ConfigureBasepoint(curve, + "0401A57A6A7B26CA5EF52FCDB816479700B3ADC94ED1FE674C06E695BABA1D"); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * sect131r1 + */ + internal class Sect131r1Holder + : X9ECParametersHolder + { + private Sect131r1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Sect131r1Holder(); + + private const int m = 131; + private const int k1 = 2; + private const int k2 = 3; + private const int k3 = 8; + + protected override X9ECParameters CreateParameters() + { + BigInteger a = FromHex("07A11B09A76B562144418FF3FF8C2570B8"); + BigInteger b = FromHex("0217C05610884B63B9C6C7291678F9D341"); + byte[] S = Hex.DecodeStrict("4D696E676875615175985BD3ADBADA21B43A97E2"); + BigInteger n = FromHex("0400000000000000023123953A9464B54D"); + BigInteger h = BigInteger.ValueOf(2); + + ECCurve curve = new F2mCurve(m, k1, k2, k3, a, b, n, h); + + X9ECPoint G = ConfigureBasepoint(curve, + "040081BAF91FDF9833C40F9C181343638399078C6E7EA38C001F73C8134B1B4EF9E150"); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * sect131r2 + */ + internal class Sect131r2Holder + : X9ECParametersHolder + { + private Sect131r2Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Sect131r2Holder(); + + private const int m = 131; + private const int k1 = 2; + private const int k2 = 3; + private const int k3 = 8; + + protected override X9ECParameters CreateParameters() + { + BigInteger a = FromHex("03E5A88919D7CAFCBF415F07C2176573B2"); + BigInteger b = FromHex("04B8266A46C55657AC734CE38F018F2192"); + byte[] S = Hex.DecodeStrict("985BD3ADBAD4D696E676875615175A21B43A97E3"); + BigInteger n = FromHex("0400000000000000016954A233049BA98F"); + BigInteger h = BigInteger.ValueOf(2); + + ECCurve curve = new F2mCurve(m, k1, k2, k3, a, b, n, h); + + X9ECPoint G = ConfigureBasepoint(curve, + "040356DCD8F2F95031AD652D23951BB366A80648F06D867940A5366D9E265DE9EB240F"); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * sect163k1 + */ + internal class Sect163k1Holder + : X9ECParametersHolder + { + private Sect163k1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Sect163k1Holder(); + + private const int m = 163; + private const int k1 = 3; + private const int k2 = 6; + private const int k3 = 7; + + protected override X9ECParameters CreateParameters() + { + BigInteger a = BigInteger.One; + BigInteger b = BigInteger.One; + byte[] S = null; + BigInteger n = FromHex("04000000000000000000020108A2E0CC0D99F8A5EF"); + BigInteger h = BigInteger.ValueOf(2); + + ECCurve curve = new F2mCurve(m, k1, k2, k3, a, b, n, h); + + X9ECPoint G = ConfigureBasepoint(curve, + "0402FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE80289070FB05D38FF58321F2E800536D538CCDAA3D9"); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * sect163r1 + */ + internal class Sect163r1Holder + : X9ECParametersHolder + { + private Sect163r1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Sect163r1Holder(); + + private const int m = 163; + private const int k1 = 3; + private const int k2 = 6; + private const int k3 = 7; + + protected override X9ECParameters CreateParameters() + { + BigInteger a = FromHex("07B6882CAAEFA84F9554FF8428BD88E246D2782AE2"); + BigInteger b = FromHex("0713612DCDDCB40AAB946BDA29CA91F73AF958AFD9"); + byte[] S = Hex.DecodeStrict("24B7B137C8A14D696E6768756151756FD0DA2E5C"); + BigInteger n = FromHex("03FFFFFFFFFFFFFFFFFFFF48AAB689C29CA710279B"); + BigInteger h = BigInteger.ValueOf(2); + + ECCurve curve = new F2mCurve(m, k1, k2, k3, a, b, n, h); + + X9ECPoint G = ConfigureBasepoint(curve, + "040369979697AB43897789566789567F787A7876A65400435EDB42EFAFB2989D51FEFCE3C80988F41FF883"); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * sect163r2 + */ + internal class Sect163r2Holder + : X9ECParametersHolder + { + private Sect163r2Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Sect163r2Holder(); + + private const int m = 163; + private const int k1 = 3; + private const int k2 = 6; + private const int k3 = 7; + + protected override X9ECParameters CreateParameters() + { + BigInteger a = BigInteger.One; + BigInteger b = FromHex("020A601907B8C953CA1481EB10512F78744A3205FD"); + byte[] S = Hex.DecodeStrict("85E25BFE5C86226CDB12016F7553F9D0E693A268"); + BigInteger n = FromHex("040000000000000000000292FE77E70C12A4234C33"); + BigInteger h = BigInteger.ValueOf(2); + + ECCurve curve = new F2mCurve(m, k1, k2, k3, a, b, n, h); + + X9ECPoint G = ConfigureBasepoint(curve, + "0403F0EBA16286A2D57EA0991168D4994637E8343E3600D51FBC6C71A0094FA2CDD545B11C5C0C797324F1"); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * sect193r1 + */ + internal class Sect193r1Holder + : X9ECParametersHolder + { + private Sect193r1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Sect193r1Holder(); + + private const int m = 193; + private const int k = 15; + + protected override X9ECParameters CreateParameters() + { + BigInteger a = FromHex("0017858FEB7A98975169E171F77B4087DE098AC8A911DF7B01"); + BigInteger b = FromHex("00FDFB49BFE6C3A89FACADAA7A1E5BBC7CC1C2E5D831478814"); + byte[] S = Hex.DecodeStrict("103FAEC74D696E676875615175777FC5B191EF30"); + BigInteger n = FromHex("01000000000000000000000000C7F34A778F443ACC920EBA49"); + BigInteger h = BigInteger.ValueOf(2); + + ECCurve curve = new F2mCurve(m, k, a, b, n, h); + + X9ECPoint G = ConfigureBasepoint(curve, + "0401F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E10025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05"); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * sect193r2 + */ + internal class Sect193r2Holder + : X9ECParametersHolder + { + private Sect193r2Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Sect193r2Holder(); + + private const int m = 193; + private const int k = 15; + + protected override X9ECParameters CreateParameters() + { + BigInteger a = FromHex("0163F35A5137C2CE3EA6ED8667190B0BC43ECD69977702709B"); + BigInteger b = FromHex("00C9BB9E8927D4D64C377E2AB2856A5B16E3EFB7F61D4316AE"); + byte[] S = Hex.DecodeStrict("10B7B4D696E676875615175137C8A16FD0DA2211"); + BigInteger n = FromHex("010000000000000000000000015AAB561B005413CCD4EE99D5"); + BigInteger h = BigInteger.ValueOf(2); + + ECCurve curve = new F2mCurve(m, k, a, b, n, h); + + X9ECPoint G = ConfigureBasepoint(curve, + "0400D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C"); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * sect233k1 + */ + internal class Sect233k1Holder + : X9ECParametersHolder + { + private Sect233k1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Sect233k1Holder(); + + private const int m = 233; + private const int k = 74; + + protected override X9ECParameters CreateParameters() + { + BigInteger a = BigInteger.Zero; + BigInteger b = BigInteger.One; + byte[] S = null; + BigInteger n = FromHex("8000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF"); + BigInteger h = BigInteger.ValueOf(4); + + ECCurve curve = new F2mCurve(m, k, a, b, n, h); + + X9ECPoint G = ConfigureBasepoint(curve, + "04017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD612601DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3"); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * sect233r1 + */ + internal class Sect233r1Holder + : X9ECParametersHolder + { + private Sect233r1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Sect233r1Holder(); + + private const int m = 233; + private const int k = 74; + + protected override X9ECParameters CreateParameters() + { + BigInteger a = BigInteger.One; + BigInteger b = FromHex("0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD"); + byte[] S = Hex.DecodeStrict("74D59FF07F6B413D0EA14B344B20A2DB049B50C3"); + BigInteger n = FromHex("01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7"); + BigInteger h = BigInteger.ValueOf(2); + + ECCurve curve = new F2mCurve(m, k, a, b, n, h); + + X9ECPoint G = ConfigureBasepoint(curve, + "0400FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052"); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * sect239k1 + */ + internal class Sect239k1Holder + : X9ECParametersHolder + { + private Sect239k1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Sect239k1Holder(); + + private const int m = 239; + private const int k = 158; + + protected override X9ECParameters CreateParameters() + { + BigInteger a = BigInteger.Zero; + BigInteger b = BigInteger.One; + byte[] S = null; + BigInteger n = FromHex("2000000000000000000000000000005A79FEC67CB6E91F1C1DA800E478A5"); + BigInteger h = BigInteger.ValueOf(4); + + ECCurve curve = new F2mCurve(m, k, a, b, n, h); + + X9ECPoint G = ConfigureBasepoint(curve, + "0429A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA"); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * sect283k1 + */ + internal class Sect283k1Holder + : X9ECParametersHolder + { + private Sect283k1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Sect283k1Holder(); + + private const int m = 283; + private const int k1 = 5; + private const int k2 = 7; + private const int k3 = 12; + + protected override X9ECParameters CreateParameters() + { + BigInteger a = BigInteger.Zero; + BigInteger b = BigInteger.One; + byte[] S = null; + BigInteger n = FromHex("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61"); + BigInteger h = BigInteger.ValueOf(4); + + ECCurve curve = new F2mCurve(m, k1, k2, k3, a, b, n, h); + + X9ECPoint G = ConfigureBasepoint(curve, "04" + + "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836" + + "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259"); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * sect283r1 + */ + internal class Sect283r1Holder + : X9ECParametersHolder + { + private Sect283r1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Sect283r1Holder(); + + private const int m = 283; + private const int k1 = 5; + private const int k2 = 7; + private const int k3 = 12; + + protected override X9ECParameters CreateParameters() + { + BigInteger a = BigInteger.One; + BigInteger b = FromHex("027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5"); + byte[] S = Hex.DecodeStrict("77E2B07370EB0F832A6DD5B62DFC88CD06BB84BE"); + BigInteger n = FromHex("03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307"); + BigInteger h = BigInteger.ValueOf(2); + + ECCurve curve = new F2mCurve(m, k1, k2, k3, a, b, n, h); + + X9ECPoint G = ConfigureBasepoint(curve, "04" + + "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053" + + "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4"); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * sect409k1 + */ + internal class Sect409k1Holder + : X9ECParametersHolder + { + private Sect409k1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Sect409k1Holder(); + + private const int m = 409; + private const int k = 87; + + protected override X9ECParameters CreateParameters() + { + BigInteger a = BigInteger.Zero; + BigInteger b = BigInteger.One; + byte[] S = null; + BigInteger n = FromHex("7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF"); + BigInteger h = BigInteger.ValueOf(4); + + ECCurve curve = new F2mCurve(m, k, a, b, n, h); + + X9ECPoint G = ConfigureBasepoint(curve, "04" + + "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746" + + "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B"); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * sect409r1 + */ + internal class Sect409r1Holder + : X9ECParametersHolder + { + private Sect409r1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Sect409r1Holder(); + + private const int m = 409; + private const int k = 87; + + protected override X9ECParameters CreateParameters() + { + BigInteger a = BigInteger.One; + BigInteger b = FromHex("0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F"); + byte[] S = Hex.DecodeStrict("4099B5A457F9D69F79213D094C4BCD4D4262210B"); + BigInteger n = FromHex("010000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173"); + BigInteger h = BigInteger.ValueOf(2); + + ECCurve curve = new F2mCurve(m, k, a, b, n, h); + + X9ECPoint G = ConfigureBasepoint(curve, "04" + + "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7" + + "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706"); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * sect571k1 + */ + internal class Sect571k1Holder + : X9ECParametersHolder + { + private Sect571k1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Sect571k1Holder(); + + private const int m = 571; + private const int k1 = 2; + private const int k2 = 5; + private const int k3 = 10; + + protected override X9ECParameters CreateParameters() + { + BigInteger a = BigInteger.Zero; + BigInteger b = BigInteger.One; + byte[] S = null; + BigInteger n = FromHex("020000000000000000000000000000000000000000000000000000000000000000000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001"); + BigInteger h = BigInteger.ValueOf(4); + + ECCurve curve = new F2mCurve(m, k1, k2, k3, a, b, n, h); + + X9ECPoint G = ConfigureBasepoint(curve, "04" + + "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972" + + "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3"); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + /* + * sect571r1 + */ + internal class Sect571r1Holder + : X9ECParametersHolder + { + private Sect571r1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Sect571r1Holder(); + + private const int m = 571; + private const int k1 = 2; + private const int k2 = 5; + private const int k3 = 10; + + protected override X9ECParameters CreateParameters() + { + BigInteger a = BigInteger.One; + BigInteger b = FromHex("02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A"); + byte[] S = Hex.DecodeStrict("2AA058F73A0E33AB486B0F610410C53A7F132310"); + BigInteger n = FromHex("03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47"); + BigInteger h = BigInteger.ValueOf(2); + + ECCurve curve = new F2mCurve(m, k1, k2, k3, a, b, n, h); + + X9ECPoint G = ConfigureBasepoint(curve, "04" + + "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19" + + "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B"); + + return new X9ECParameters(curve, G, n, h, S); + } + } + + + private static readonly IDictionary objIds = Platform.CreateHashtable(); + private static readonly IDictionary curves = Platform.CreateHashtable(); + private static readonly IDictionary names = Platform.CreateHashtable(); + + private static void DefineCurve( + string name, + DerObjectIdentifier oid, + X9ECParametersHolder holder) + { + objIds.Add(Platform.ToUpperInvariant(name), oid); + names.Add(oid, name); + curves.Add(oid, holder); + } + + static SecNamedCurves() + { + DefineCurve("secp112r1", SecObjectIdentifiers.SecP112r1, Secp112r1Holder.Instance); + DefineCurve("secp112r2", SecObjectIdentifiers.SecP112r2, Secp112r2Holder.Instance); + DefineCurve("secp128r1", SecObjectIdentifiers.SecP128r1, Secp128r1Holder.Instance); + DefineCurve("secp128r2", SecObjectIdentifiers.SecP128r2, Secp128r2Holder.Instance); + DefineCurve("secp160k1", SecObjectIdentifiers.SecP160k1, Secp160k1Holder.Instance); + DefineCurve("secp160r1", SecObjectIdentifiers.SecP160r1, Secp160r1Holder.Instance); + DefineCurve("secp160r2", SecObjectIdentifiers.SecP160r2, Secp160r2Holder.Instance); + DefineCurve("secp192k1", SecObjectIdentifiers.SecP192k1, Secp192k1Holder.Instance); + DefineCurve("secp192r1", SecObjectIdentifiers.SecP192r1, Secp192r1Holder.Instance); + DefineCurve("secp224k1", SecObjectIdentifiers.SecP224k1, Secp224k1Holder.Instance); + DefineCurve("secp224r1", SecObjectIdentifiers.SecP224r1, Secp224r1Holder.Instance); + DefineCurve("secp256k1", SecObjectIdentifiers.SecP256k1, Secp256k1Holder.Instance); + DefineCurve("secp256r1", SecObjectIdentifiers.SecP256r1, Secp256r1Holder.Instance); + DefineCurve("secp384r1", SecObjectIdentifiers.SecP384r1, Secp384r1Holder.Instance); + DefineCurve("secp521r1", SecObjectIdentifiers.SecP521r1, Secp521r1Holder.Instance); + + DefineCurve("sect113r1", SecObjectIdentifiers.SecT113r1, Sect113r1Holder.Instance); + DefineCurve("sect113r2", SecObjectIdentifiers.SecT113r2, Sect113r2Holder.Instance); + DefineCurve("sect131r1", SecObjectIdentifiers.SecT131r1, Sect131r1Holder.Instance); + DefineCurve("sect131r2", SecObjectIdentifiers.SecT131r2, Sect131r2Holder.Instance); + DefineCurve("sect163k1", SecObjectIdentifiers.SecT163k1, Sect163k1Holder.Instance); + DefineCurve("sect163r1", SecObjectIdentifiers.SecT163r1, Sect163r1Holder.Instance); + DefineCurve("sect163r2", SecObjectIdentifiers.SecT163r2, Sect163r2Holder.Instance); + DefineCurve("sect193r1", SecObjectIdentifiers.SecT193r1, Sect193r1Holder.Instance); + DefineCurve("sect193r2", SecObjectIdentifiers.SecT193r2, Sect193r2Holder.Instance); + DefineCurve("sect233k1", SecObjectIdentifiers.SecT233k1, Sect233k1Holder.Instance); + DefineCurve("sect233r1", SecObjectIdentifiers.SecT233r1, Sect233r1Holder.Instance); + DefineCurve("sect239k1", SecObjectIdentifiers.SecT239k1, Sect239k1Holder.Instance); + DefineCurve("sect283k1", SecObjectIdentifiers.SecT283k1, Sect283k1Holder.Instance); + DefineCurve("sect283r1", SecObjectIdentifiers.SecT283r1, Sect283r1Holder.Instance); + DefineCurve("sect409k1", SecObjectIdentifiers.SecT409k1, Sect409k1Holder.Instance); + DefineCurve("sect409r1", SecObjectIdentifiers.SecT409r1, Sect409r1Holder.Instance); + DefineCurve("sect571k1", SecObjectIdentifiers.SecT571k1, Sect571k1Holder.Instance); + DefineCurve("sect571r1", SecObjectIdentifiers.SecT571r1, Sect571r1Holder.Instance); + } + + public static X9ECParameters GetByName( + string name) + { + DerObjectIdentifier oid = GetOid(name); + return oid == null ? null : GetByOid(oid); + } + + /** + * return the X9ECParameters object for the named curve represented by + * the passed in object identifier. Null if the curve isn't present. + * + * @param oid an object identifier representing a named curve, if present. + */ + public static X9ECParameters GetByOid( + DerObjectIdentifier oid) + { + X9ECParametersHolder holder = (X9ECParametersHolder)curves[oid]; + return holder == null ? null : holder.Parameters; + } + + /** + * return the object identifier signified by the passed in name. Null + * if there is no object identifier associated with name. + * + * @return the object identifier associated with name, if present. + */ + public static DerObjectIdentifier GetOid( + string name) + { + return (DerObjectIdentifier)objIds[Platform.ToUpperInvariant(name)]; + } + + /** + * return the named curve name represented by the given object identifier. + */ + public static string GetName( + DerObjectIdentifier oid) + { + return (string)names[oid]; + } + + /** + * returns an enumeration containing the name strings for curves + * contained in this structure. + */ + public static IEnumerable Names + { + get { return new EnumerableProxy(names.Values); } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/sec/SECNamedCurves.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/sec/SECNamedCurves.cs.meta new file mode 100644 index 0000000..2b3bc77 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/sec/SECNamedCurves.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 482052f775c1f7342bb1e7820787e31f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/sec/SECObjectIdentifiers.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/sec/SECObjectIdentifiers.cs new file mode 100644 index 0000000..afc10e1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/sec/SECObjectIdentifiers.cs @@ -0,0 +1,52 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X9; + +namespace Org.BouncyCastle.Asn1.Sec +{ + public abstract class SecObjectIdentifiers + { + /** + * EllipticCurve OBJECT IDENTIFIER ::= { + * iso(1) identified-organization(3) certicom(132) curve(0) + * } + */ + public static readonly DerObjectIdentifier EllipticCurve = new DerObjectIdentifier("1.3.132.0"); + + public static readonly DerObjectIdentifier SecT163k1 = new DerObjectIdentifier(EllipticCurve + ".1"); + public static readonly DerObjectIdentifier SecT163r1 = new DerObjectIdentifier(EllipticCurve + ".2"); + public static readonly DerObjectIdentifier SecT239k1 = new DerObjectIdentifier(EllipticCurve + ".3"); + public static readonly DerObjectIdentifier SecT113r1 = new DerObjectIdentifier(EllipticCurve + ".4"); + public static readonly DerObjectIdentifier SecT113r2 = new DerObjectIdentifier(EllipticCurve + ".5"); + public static readonly DerObjectIdentifier SecP112r1 = new DerObjectIdentifier(EllipticCurve + ".6"); + public static readonly DerObjectIdentifier SecP112r2 = new DerObjectIdentifier(EllipticCurve + ".7"); + public static readonly DerObjectIdentifier SecP160r1 = new DerObjectIdentifier(EllipticCurve + ".8"); + public static readonly DerObjectIdentifier SecP160k1 = new DerObjectIdentifier(EllipticCurve + ".9"); + public static readonly DerObjectIdentifier SecP256k1 = new DerObjectIdentifier(EllipticCurve + ".10"); + public static readonly DerObjectIdentifier SecT163r2 = new DerObjectIdentifier(EllipticCurve + ".15"); + public static readonly DerObjectIdentifier SecT283k1 = new DerObjectIdentifier(EllipticCurve + ".16"); + public static readonly DerObjectIdentifier SecT283r1 = new DerObjectIdentifier(EllipticCurve + ".17"); + public static readonly DerObjectIdentifier SecT131r1 = new DerObjectIdentifier(EllipticCurve + ".22"); + public static readonly DerObjectIdentifier SecT131r2 = new DerObjectIdentifier(EllipticCurve + ".23"); + public static readonly DerObjectIdentifier SecT193r1 = new DerObjectIdentifier(EllipticCurve + ".24"); + public static readonly DerObjectIdentifier SecT193r2 = new DerObjectIdentifier(EllipticCurve + ".25"); + public static readonly DerObjectIdentifier SecT233k1 = new DerObjectIdentifier(EllipticCurve + ".26"); + public static readonly DerObjectIdentifier SecT233r1 = new DerObjectIdentifier(EllipticCurve + ".27"); + public static readonly DerObjectIdentifier SecP128r1 = new DerObjectIdentifier(EllipticCurve + ".28"); + public static readonly DerObjectIdentifier SecP128r2 = new DerObjectIdentifier(EllipticCurve + ".29"); + public static readonly DerObjectIdentifier SecP160r2 = new DerObjectIdentifier(EllipticCurve + ".30"); + public static readonly DerObjectIdentifier SecP192k1 = new DerObjectIdentifier(EllipticCurve + ".31"); + public static readonly DerObjectIdentifier SecP224k1 = new DerObjectIdentifier(EllipticCurve + ".32"); + public static readonly DerObjectIdentifier SecP224r1 = new DerObjectIdentifier(EllipticCurve + ".33"); + public static readonly DerObjectIdentifier SecP384r1 = new DerObjectIdentifier(EllipticCurve + ".34"); + public static readonly DerObjectIdentifier SecP521r1 = new DerObjectIdentifier(EllipticCurve + ".35"); + public static readonly DerObjectIdentifier SecT409k1 = new DerObjectIdentifier(EllipticCurve + ".36"); + public static readonly DerObjectIdentifier SecT409r1 = new DerObjectIdentifier(EllipticCurve + ".37"); + public static readonly DerObjectIdentifier SecT571k1 = new DerObjectIdentifier(EllipticCurve + ".38"); + public static readonly DerObjectIdentifier SecT571r1 = new DerObjectIdentifier(EllipticCurve + ".39"); + + public static readonly DerObjectIdentifier SecP192r1 = X9ObjectIdentifiers.Prime192v1; + public static readonly DerObjectIdentifier SecP256r1 = X9ObjectIdentifiers.Prime256v1; + } +} \ No newline at end of file diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/sec/SECObjectIdentifiers.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/sec/SECObjectIdentifiers.cs.meta new file mode 100644 index 0000000..f9aa3ab --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/sec/SECObjectIdentifiers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ecac332794acdc94cb44416a4798ad4f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/smime.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/smime.meta new file mode 100644 index 0000000..5352d93 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/smime.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 095127449a8773241987daa0ed510b9b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/smime/SMIMEAttributes.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/smime/SMIMEAttributes.cs new file mode 100644 index 0000000..e154e5e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/smime/SMIMEAttributes.cs @@ -0,0 +1,11 @@ +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Pkcs; + +namespace Org.BouncyCastle.Asn1.Smime +{ + public abstract class SmimeAttributes + { + public static readonly DerObjectIdentifier SmimeCapabilities = PkcsObjectIdentifiers.Pkcs9AtSmimeCapabilities; + public static readonly DerObjectIdentifier EncrypKeyPref = PkcsObjectIdentifiers.IdAAEncrypKeyPref; + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/smime/SMIMEAttributes.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/smime/SMIMEAttributes.cs.meta new file mode 100644 index 0000000..c7b9500 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/smime/SMIMEAttributes.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ba3d2536ec178cf4494d40156db253a6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/smime/SMIMECapabilities.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/smime/SMIMECapabilities.cs new file mode 100644 index 0000000..5bf48f3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/smime/SMIMECapabilities.cs @@ -0,0 +1,134 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.X509; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Smime +{ + /** + * Handler class for dealing with S/MIME Capabilities + */ + public class SmimeCapabilities + : Asn1Encodable + { + /** + * general preferences + */ + public static readonly DerObjectIdentifier PreferSignedData = PkcsObjectIdentifiers.PreferSignedData; + public static readonly DerObjectIdentifier CannotDecryptAny = PkcsObjectIdentifiers.CannotDecryptAny; + public static readonly DerObjectIdentifier SmimeCapabilitesVersions = PkcsObjectIdentifiers.SmimeCapabilitiesVersions; + + /** + * encryption algorithms preferences + */ + public static readonly DerObjectIdentifier Aes256Cbc = NistObjectIdentifiers.IdAes256Cbc; + public static readonly DerObjectIdentifier Aes192Cbc = NistObjectIdentifiers.IdAes192Cbc; + public static readonly DerObjectIdentifier Aes128Cbc = NistObjectIdentifiers.IdAes128Cbc; + public static readonly DerObjectIdentifier IdeaCbc = new DerObjectIdentifier("1.3.6.1.4.1.188.7.1.1.2"); + public static readonly DerObjectIdentifier Cast5Cbc = new DerObjectIdentifier("1.2.840.113533.7.66.10"); + public static readonly DerObjectIdentifier DesCbc = new DerObjectIdentifier("1.3.14.3.2.7"); + public static readonly DerObjectIdentifier DesEde3Cbc = PkcsObjectIdentifiers.DesEde3Cbc; + public static readonly DerObjectIdentifier RC2Cbc = PkcsObjectIdentifiers.RC2Cbc; + + private Asn1Sequence capabilities; + + /** + * return an Attr object from the given object. + * + * @param o the object we want converted. + * @exception ArgumentException if the object cannot be converted. + */ + public static SmimeCapabilities GetInstance( + object obj) + { + if (obj == null || obj is SmimeCapabilities) + { + return (SmimeCapabilities) obj; + } + + if (obj is Asn1Sequence) + { + return new SmimeCapabilities((Asn1Sequence) obj); + } + + if (obj is AttributeX509) + { + return new SmimeCapabilities( + (Asn1Sequence)(((AttributeX509) obj).AttrValues[0])); + } + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + public SmimeCapabilities( + Asn1Sequence seq) + { + capabilities = seq; + } + +#if !(SILVERLIGHT || PORTABLE) + [Obsolete("Use 'GetCapabilitiesForOid' instead")] + public ArrayList GetCapabilities( + DerObjectIdentifier capability) + { + ArrayList list = new ArrayList(); + DoGetCapabilitiesForOid(capability, list); + return list; + } +#endif + + /** + * returns an ArrayList with 0 or more objects of all the capabilities + * matching the passed in capability Oid. If the Oid passed is null the + * entire set is returned. + */ + public IList GetCapabilitiesForOid( + DerObjectIdentifier capability) + { + IList list = Platform.CreateArrayList(); + DoGetCapabilitiesForOid(capability, list); + return list; + } + + private void DoGetCapabilitiesForOid(DerObjectIdentifier capability, IList list) + { + if (capability == null) + { + foreach (object o in capabilities) + { + SmimeCapability cap = SmimeCapability.GetInstance(o); + + list.Add(cap); + } + } + else + { + foreach (object o in capabilities) + { + SmimeCapability cap = SmimeCapability.GetInstance(o); + + if (capability.Equals(cap.CapabilityID)) + { + list.Add(cap); + } + } + } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * SMIMECapabilities ::= Sequence OF SMIMECapability
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + return capabilities; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/smime/SMIMECapabilities.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/smime/SMIMECapabilities.cs.meta new file mode 100644 index 0000000..229a004 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/smime/SMIMECapabilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 88cb80e6e1113084aa541e0b6e68e113 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/smime/SMIMECapabilitiesAttribute.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/smime/SMIMECapabilitiesAttribute.cs new file mode 100644 index 0000000..310c478 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/smime/SMIMECapabilitiesAttribute.cs @@ -0,0 +1,16 @@ +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; + +namespace Org.BouncyCastle.Asn1.Smime +{ + public class SmimeCapabilitiesAttribute + : AttributeX509 + { + public SmimeCapabilitiesAttribute( + SmimeCapabilityVector capabilities) + : base(SmimeAttributes.SmimeCapabilities, + new DerSet(new DerSequence(capabilities.ToAsn1EncodableVector()))) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/smime/SMIMECapabilitiesAttribute.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/smime/SMIMECapabilitiesAttribute.cs.meta new file mode 100644 index 0000000..335bd41 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/smime/SMIMECapabilitiesAttribute.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9ab0e5b64f5cdb64c8d7231b2d890048 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/smime/SMIMECapability.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/smime/SMIMECapability.cs new file mode 100644 index 0000000..9b30c6d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/smime/SMIMECapability.cs @@ -0,0 +1,96 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Pkcs; + +namespace Org.BouncyCastle.Asn1.Smime +{ + public class SmimeCapability + : Asn1Encodable + { + /** + * general preferences + */ + public static readonly DerObjectIdentifier PreferSignedData = PkcsObjectIdentifiers.PreferSignedData; + public static readonly DerObjectIdentifier CannotDecryptAny = PkcsObjectIdentifiers.CannotDecryptAny; + public static readonly DerObjectIdentifier SmimeCapabilitiesVersions = PkcsObjectIdentifiers.SmimeCapabilitiesVersions; + + /** + * encryption algorithms preferences + */ + public static readonly DerObjectIdentifier DesCbc = new DerObjectIdentifier("1.3.14.3.2.7"); + public static readonly DerObjectIdentifier DesEde3Cbc = PkcsObjectIdentifiers.DesEde3Cbc; + public static readonly DerObjectIdentifier RC2Cbc = PkcsObjectIdentifiers.RC2Cbc; + + private DerObjectIdentifier capabilityID; + private Asn1Object parameters; + + public SmimeCapability( + Asn1Sequence seq) + { + capabilityID = (DerObjectIdentifier) seq[0].ToAsn1Object(); + + if (seq.Count > 1) + { + parameters = seq[1].ToAsn1Object(); + } + } + + public SmimeCapability( + DerObjectIdentifier capabilityID, + Asn1Encodable parameters) + { + if (capabilityID == null) + throw new ArgumentNullException("capabilityID"); + + this.capabilityID = capabilityID; + + if (parameters != null) + { + this.parameters = parameters.ToAsn1Object(); + } + } + + public static SmimeCapability GetInstance( + object obj) + { + if (obj == null || obj is SmimeCapability) + { + return (SmimeCapability) obj; + } + + if (obj is Asn1Sequence) + { + return new SmimeCapability((Asn1Sequence) obj); + } + + throw new ArgumentException("Invalid SmimeCapability"); + } + + public DerObjectIdentifier CapabilityID + { + get { return capabilityID; } + } + + public Asn1Object Parameters + { + get { return parameters; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * SMIMECapability ::= Sequence {
+         *     capabilityID OBJECT IDENTIFIER,
+         *     parameters ANY DEFINED BY capabilityID OPTIONAL
+         * }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(capabilityID); + v.AddOptional(parameters); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/smime/SMIMECapability.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/smime/SMIMECapability.cs.meta new file mode 100644 index 0000000..f1d8e16 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/smime/SMIMECapability.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0de451aac684e654aa508cf9a9750d63 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/smime/SMIMECapabilityVector.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/smime/SMIMECapabilityVector.cs new file mode 100644 index 0000000..842825b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/smime/SMIMECapabilityVector.cs @@ -0,0 +1,37 @@ +using Org.BouncyCastle.Asn1; + +namespace Org.BouncyCastle.Asn1.Smime +{ + /** + * Handler for creating a vector S/MIME Capabilities + */ + public class SmimeCapabilityVector + { + private readonly Asn1EncodableVector capabilities = new Asn1EncodableVector(); + + public void AddCapability( + DerObjectIdentifier capability) + { + capabilities.Add(new DerSequence(capability)); + } + + public void AddCapability( + DerObjectIdentifier capability, + int value) + { + capabilities.Add(new DerSequence(capability, new DerInteger(value))); + } + + public void AddCapability( + DerObjectIdentifier capability, + Asn1Encodable parameters) + { + capabilities.Add(new DerSequence(capability, parameters)); + } + + public Asn1EncodableVector ToAsn1EncodableVector() + { + return capabilities; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/smime/SMIMECapabilityVector.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/smime/SMIMECapabilityVector.cs.meta new file mode 100644 index 0000000..1740383 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/smime/SMIMECapabilityVector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3746d769dfb1cb84cbc0501a3f23cacc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/smime/SMIMEEncryptionKeyPreferenceAttribute.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/smime/SMIMEEncryptionKeyPreferenceAttribute.cs new file mode 100644 index 0000000..19c5fd7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/smime/SMIMEEncryptionKeyPreferenceAttribute.cs @@ -0,0 +1,44 @@ +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Asn1.X509; + +namespace Org.BouncyCastle.Asn1.Smime +{ + /** + * The SmimeEncryptionKeyPreference object. + *
+     * SmimeEncryptionKeyPreference ::= CHOICE {
+     *     issuerAndSerialNumber   [0] IssuerAndSerialNumber,
+     *     receipentKeyId          [1] RecipientKeyIdentifier,
+     *     subjectAltKeyIdentifier [2] SubjectKeyIdentifier
+     * }
+     * 
+ */ + public class SmimeEncryptionKeyPreferenceAttribute + : AttributeX509 + { + public SmimeEncryptionKeyPreferenceAttribute( + IssuerAndSerialNumber issAndSer) + : base(SmimeAttributes.EncrypKeyPref, + new DerSet(new DerTaggedObject(false, 0, issAndSer))) + { + } + + public SmimeEncryptionKeyPreferenceAttribute( + RecipientKeyIdentifier rKeyID) + : base(SmimeAttributes.EncrypKeyPref, + new DerSet(new DerTaggedObject(false, 1, rKeyID))) + { + } + + /** + * @param sKeyId the subjectKeyIdentifier value (normally the X.509 one) + */ + public SmimeEncryptionKeyPreferenceAttribute( + Asn1OctetString sKeyID) + : base(SmimeAttributes.EncrypKeyPref, + new DerSet(new DerTaggedObject(false, 2, sKeyID))) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/smime/SMIMEEncryptionKeyPreferenceAttribute.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/smime/SMIMEEncryptionKeyPreferenceAttribute.cs.meta new file mode 100644 index 0000000..0828a98 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/smime/SMIMEEncryptionKeyPreferenceAttribute.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: efe410b27bea4bb48b8d5822d0baa50a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/teletrust.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/teletrust.meta new file mode 100644 index 0000000..2f42a72 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/teletrust.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a5adbde3b64d1f3428d2b68e9ca6377a +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/teletrust/TeleTrusTNamedCurves.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/teletrust/TeleTrusTNamedCurves.cs new file mode 100644 index 0000000..c9a1e7d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/teletrust/TeleTrusTNamedCurves.cs @@ -0,0 +1,483 @@ +using System.Collections; + +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Math.EC.Multiplier; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Asn1.TeleTrust +{ + /** + * elliptic curves defined in "ECC Brainpool Standard Curves and Curve Generation" + * http://www.ecc-brainpool.org/download/draft_pkix_additional_ecc_dp.txt + */ + public class TeleTrusTNamedCurves + { + private static X9ECPoint ConfigureBasepoint(ECCurve curve, string encoding) + { + X9ECPoint G = new X9ECPoint(curve, Hex.DecodeStrict(encoding)); + WNafUtilities.ConfigureBasepoint(G.Point); + return G; + } + + private static ECCurve ConfigureCurve(ECCurve curve) + { + return curve; + } + + private static BigInteger FromHex(string hex) + { + return new BigInteger(1, Hex.DecodeStrict(hex)); + } + + internal class BrainpoolP160r1Holder + : X9ECParametersHolder + { + private BrainpoolP160r1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new BrainpoolP160r1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = FromHex("E95E4A5F737059DC60DF5991D45029409E60FC09"); + BigInteger h = BigInteger.One; + + ECCurve curve = ConfigureCurve(new FpCurve( + FromHex("E95E4A5F737059DC60DFC7AD95B3D8139515620F"), // q + FromHex("340E7BE2A280EB74E2BE61BADA745D97E8F7C300"), // a + FromHex("1E589A8595423412134FAA2DBDEC95C8D8675E58"), // b + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "04BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC31667CB477A1A8EC338F94741669C976316DA6321"); + + return new X9ECParameters(curve, G, n, h); + } + } + + internal class BrainpoolP160t1Holder + : X9ECParametersHolder + { + private BrainpoolP160t1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new BrainpoolP160t1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = FromHex("E95E4A5F737059DC60DF5991D45029409E60FC09"); + BigInteger h = BigInteger.One; + + ECCurve curve = ConfigureCurve(new FpCurve( + //FromHex("24DBFF5DEC9B986BBFE5295A29BFBAE45E0F5D0B"), // Z + FromHex("E95E4A5F737059DC60DFC7AD95B3D8139515620F"), // q + FromHex("E95E4A5F737059DC60DFC7AD95B3D8139515620C"), // a + FromHex("7A556B6DAE535B7B51ED2C4D7DAA7A0B5C55F380"), // b + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "04B199B13B9B34EFC1397E64BAEB05ACC265FF2378ADD6718B7C7C1961F0991B842443772152C9E0AD"); + + return new X9ECParameters(curve, G, n, h); + } + } + + internal class BrainpoolP192r1Holder + : X9ECParametersHolder + { + private BrainpoolP192r1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new BrainpoolP192r1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = FromHex("C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1"); + BigInteger h = BigInteger.One; + + ECCurve curve = ConfigureCurve(new FpCurve( + FromHex("C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297"), // q + FromHex("6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF"), // a + FromHex("469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9"), // b + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "04C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD614B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F"); + + return new X9ECParameters(curve, G, n, h); + } + } + + internal class BrainpoolP192t1Holder + : X9ECParametersHolder + { + private BrainpoolP192t1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new BrainpoolP192t1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = FromHex("C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1"); + BigInteger h = BigInteger.One; + + ECCurve curve = ConfigureCurve(new FpCurve( + //FromHex("1B6F5CC8DB4DC7AF19458A9CB80DC2295E5EB9C3732104CB") // Z + FromHex("C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297"), // q + FromHex("C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86294"), // a + FromHex("13D56FFAEC78681E68F9DEB43B35BEC2FB68542E27897B79"), // b + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "043AE9E58C82F63C30282E1FE7BBF43FA72C446AF6F4618129097E2C5667C2223A902AB5CA449D0084B7E5B3DE7CCC01C9"); + + return new X9ECParameters(curve, G, n, h); + } + } + + internal class BrainpoolP224r1Holder + : X9ECParametersHolder + { + private BrainpoolP224r1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new BrainpoolP224r1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = FromHex("D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F"); + BigInteger h = BigInteger.One; + + ECCurve curve = ConfigureCurve(new FpCurve( + FromHex("D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF"), // q + FromHex("68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43"), // a + FromHex("2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B"), // b + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "040D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD"); + + return new X9ECParameters(curve, G, n, h); + } + } + + internal class BrainpoolP224t1Holder + : X9ECParametersHolder + { + private BrainpoolP224t1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new BrainpoolP224t1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = FromHex("D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F"); + BigInteger h = BigInteger.One; + + ECCurve curve = ConfigureCurve(new FpCurve( + //FromHex("2DF271E14427A346910CF7A2E6CFA7B3F484E5C2CCE1C8B730E28B3F") // Z + FromHex("D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF"), // q + FromHex("D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FC"), // a + FromHex("4B337D934104CD7BEF271BF60CED1ED20DA14C08B3BB64F18A60888D"), // b + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "046AB1E344CE25FF3896424E7FFE14762ECB49F8928AC0C76029B4D5800374E9F5143E568CD23F3F4D7C0D4B1E41C8CC0D1C6ABD5F1A46DB4C"); + + return new X9ECParameters(curve, G, n, h); + } + } + + internal class BrainpoolP256r1Holder + : X9ECParametersHolder + { + private BrainpoolP256r1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new BrainpoolP256r1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = FromHex("A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7"); + BigInteger h = BigInteger.One; + + ECCurve curve = ConfigureCurve(new FpCurve( + FromHex("A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377"), // q + FromHex("7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9"), // a + FromHex("26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6"), // b + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "048BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997"); + + return new X9ECParameters(curve, G, n, h); + } + } + + internal class BrainpoolP256t1Holder + : X9ECParametersHolder + { + private BrainpoolP256t1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new BrainpoolP256t1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = FromHex("A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7"); + BigInteger h = BigInteger.One; + + ECCurve curve = ConfigureCurve(new FpCurve( + //FromHex("3E2D4BD9597B58639AE7AA669CAB9837CF5CF20A2C852D10F655668DFC150EF0") // Z + FromHex("A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377"), // q + FromHex("A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5374"), // a + FromHex("662C61C430D84EA4FE66A7733D0B76B7BF93EBC4AF2F49256AE58101FEE92B04"), // b + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "04A3E8EB3CC1CFE7B7732213B23A656149AFA142C47AAFBC2B79A191562E1305F42D996C823439C56D7F7B22E14644417E69BCB6DE39D027001DABE8F35B25C9BE"); + + return new X9ECParameters(curve, G, n, h); + } + } + + internal class BrainpoolP320r1Holder + : X9ECParametersHolder + { + private BrainpoolP320r1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new BrainpoolP320r1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = FromHex("D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311"); + BigInteger h = BigInteger.One; + + ECCurve curve = ConfigureCurve(new FpCurve( + FromHex("D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27"), // q + FromHex("3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4"), // a + FromHex("520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6"), // b + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "0443BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E2061114FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1"); + + return new X9ECParameters(curve, G, n, h); + } + } + + internal class BrainpoolP320t1Holder + : X9ECParametersHolder + { + private BrainpoolP320t1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new BrainpoolP320t1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = FromHex("D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311"); + BigInteger h = BigInteger.One; + + ECCurve curve = ConfigureCurve(new FpCurve( + //FromHex("15F75CAF668077F7E85B42EB01F0A81FF56ECD6191D55CB82B7D861458A18FEFC3E5AB7496F3C7B1") // Z + FromHex("D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27"), // q + FromHex("D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E24"), // a + FromHex("A7F561E038EB1ED560B3D147DB782013064C19F27ED27C6780AAF77FB8A547CEB5B4FEF422340353"), // b + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "04925BE9FB01AFC6FB4D3E7D4990010F813408AB106C4F09CB7EE07868CC136FFF3357F624A21BED5263BA3A7A27483EBF6671DBEF7ABB30EBEE084E58A0B077AD42A5A0989D1EE71B1B9BC0455FB0D2C3"); + + return new X9ECParameters(curve, G, n, h); + } + } + + internal class BrainpoolP384r1Holder + : X9ECParametersHolder + { + private BrainpoolP384r1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new BrainpoolP384r1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = FromHex("8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565"); + BigInteger h = BigInteger.One; + + ECCurve curve = ConfigureCurve(new FpCurve( + FromHex("8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53"), // q + FromHex("7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826"), // a + FromHex("04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11"), // b + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "041D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315"); + + return new X9ECParameters(curve, G, n, h); + } + } + + internal class BrainpoolP384t1Holder + : X9ECParametersHolder + { + private BrainpoolP384t1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new BrainpoolP384t1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = FromHex("8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565"); + BigInteger h = BigInteger.One; + + ECCurve curve = ConfigureCurve(new FpCurve( + //FromHex("41DFE8DD399331F7166A66076734A89CD0D2BCDB7D068E44E1F378F41ECBAE97D2D63DBC87BCCDDCCC5DA39E8589291C") // Z + FromHex("8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53"), // q + FromHex("8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC50"), // a + FromHex("7F519EADA7BDA81BD826DBA647910F8C4B9346ED8CCDC64E4B1ABD11756DCE1D2074AA263B88805CED70355A33B471EE"), // b + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "0418DE98B02DB9A306F2AFCD7235F72A819B80AB12EBD653172476FECD462AABFFC4FF191B946A5F54D8D0AA2F418808CC25AB056962D30651A114AFD2755AD336747F93475B7A1FCA3B88F2B6A208CCFE469408584DC2B2912675BF5B9E582928"); + + return new X9ECParameters(curve, G, n, h); + } + } + + internal class BrainpoolP512r1Holder + : X9ECParametersHolder + { + private BrainpoolP512r1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new BrainpoolP512r1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = FromHex("AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069"); + BigInteger h = BigInteger.One; + + ECCurve curve = ConfigureCurve(new FpCurve( + FromHex("AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3"), // q + FromHex("7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA"), // a + FromHex("3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723"), // b + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "0481AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F8227DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892"); + + return new X9ECParameters(curve, G, n, h); + } + } + + internal class BrainpoolP512t1Holder + : X9ECParametersHolder + { + private BrainpoolP512t1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new BrainpoolP512t1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = FromHex("AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069"); + BigInteger h = BigInteger.One; + + ECCurve curve = ConfigureCurve(new FpCurve( + //FromHex("12EE58E6764838B69782136F0F2D3BA06E27695716054092E60A80BEDB212B64E585D90BCE13761F85C3F1D2A64E3BE8FEA2220F01EBA5EEB0F35DBD29D922AB") // Z + FromHex("AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3"), // q + FromHex("AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F0"), // a + FromHex("7CBBBCF9441CFAB76E1890E46884EAE321F70C0BCB4981527897504BEC3E36A62BCDFA2304976540F6450085F2DAE145C22553B465763689180EA2571867423E"), // b + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "04640ECE5C12788717B9C1BA06CBC2A6FEBA85842458C56DDE9DB1758D39C0313D82BA51735CDB3EA499AA77A7D6943A64F7A3F25FE26F06B51BAA2696FA9035DA5B534BD595F5AF0FA2C892376C84ACE1BB4E3019B71634C01131159CAE03CEE9D9932184BEEF216BD71DF2DADF86A627306ECFF96DBB8BACE198B61E00F8B332"); + + return new X9ECParameters(curve, G, n, h); + } + } + + + private static readonly IDictionary objIds = Platform.CreateHashtable(); + private static readonly IDictionary curves = Platform.CreateHashtable(); + private static readonly IDictionary names = Platform.CreateHashtable(); + + private static void DefineCurve( + string name, + DerObjectIdentifier oid, + X9ECParametersHolder holder) + { + objIds.Add(Platform.ToUpperInvariant(name), oid); + names.Add(oid, name); + curves.Add(oid, holder); + } + + static TeleTrusTNamedCurves() + { + DefineCurve("brainpoolP160r1", TeleTrusTObjectIdentifiers.BrainpoolP160R1, BrainpoolP160r1Holder.Instance); + DefineCurve("brainpoolP160t1", TeleTrusTObjectIdentifiers.BrainpoolP160T1, BrainpoolP160t1Holder.Instance); + DefineCurve("brainpoolP192r1", TeleTrusTObjectIdentifiers.BrainpoolP192R1, BrainpoolP192r1Holder.Instance); + DefineCurve("brainpoolP192t1", TeleTrusTObjectIdentifiers.BrainpoolP192T1, BrainpoolP192t1Holder.Instance); + DefineCurve("brainpoolP224r1", TeleTrusTObjectIdentifiers.BrainpoolP224R1, BrainpoolP224r1Holder.Instance); + DefineCurve("brainpoolP224t1", TeleTrusTObjectIdentifiers.BrainpoolP224T1, BrainpoolP224t1Holder.Instance); + DefineCurve("brainpoolP256r1", TeleTrusTObjectIdentifiers.BrainpoolP256R1, BrainpoolP256r1Holder.Instance); + DefineCurve("brainpoolP256t1", TeleTrusTObjectIdentifiers.BrainpoolP256T1, BrainpoolP256t1Holder.Instance); + DefineCurve("brainpoolP320r1", TeleTrusTObjectIdentifiers.BrainpoolP320R1, BrainpoolP320r1Holder.Instance); + DefineCurve("brainpoolP320t1", TeleTrusTObjectIdentifiers.BrainpoolP320T1, BrainpoolP320t1Holder.Instance); + DefineCurve("brainpoolP384r1", TeleTrusTObjectIdentifiers.BrainpoolP384R1, BrainpoolP384r1Holder.Instance); + DefineCurve("brainpoolP384t1", TeleTrusTObjectIdentifiers.BrainpoolP384T1, BrainpoolP384t1Holder.Instance); + DefineCurve("brainpoolP512r1", TeleTrusTObjectIdentifiers.BrainpoolP512R1, BrainpoolP512r1Holder.Instance); + DefineCurve("brainpoolP512t1", TeleTrusTObjectIdentifiers.BrainpoolP512T1, BrainpoolP512t1Holder.Instance); + } + + public static X9ECParameters GetByName( + string name) + { + DerObjectIdentifier oid = GetOid(name); + return oid == null ? null : GetByOid(oid); + } + + /** + * return the X9ECParameters object for the named curve represented by + * the passed in object identifier. Null if the curve isn't present. + * + * @param oid an object identifier representing a named curve, if present. + */ + public static X9ECParameters GetByOid( + DerObjectIdentifier oid) + { + X9ECParametersHolder holder = (X9ECParametersHolder)curves[oid]; + return holder == null ? null : holder.Parameters; + } + + /** + * return the object identifier signified by the passed in name. Null + * if there is no object identifier associated with name. + * + * @return the object identifier associated with name, if present. + */ + public static DerObjectIdentifier GetOid( + string name) + { + return (DerObjectIdentifier)objIds[Platform.ToUpperInvariant(name)]; + } + + /** + * return the named curve name represented by the given object identifier. + */ + public static string GetName( + DerObjectIdentifier oid) + { + return (string)names[oid]; + } + + /** + * returns an enumeration containing the name strings for curves + * contained in this structure. + */ + public static IEnumerable Names + { + get { return new EnumerableProxy(names.Values); } + } + + public static DerObjectIdentifier GetOid( + short curvesize, + bool twisted) + { + return GetOid("brainpoolP" + curvesize + (twisted ? "t" : "r") + "1"); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/teletrust/TeleTrusTNamedCurves.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/teletrust/TeleTrusTNamedCurves.cs.meta new file mode 100644 index 0000000..6a6ca82 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/teletrust/TeleTrusTNamedCurves.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6c3c2004983d97741bb6c2c7bff1cd82 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/teletrust/TeleTrusTObjectIdentifiers.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/teletrust/TeleTrusTObjectIdentifiers.cs new file mode 100644 index 0000000..56e7084 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/teletrust/TeleTrusTObjectIdentifiers.cs @@ -0,0 +1,45 @@ +namespace Org.BouncyCastle.Asn1.TeleTrust +{ + public sealed class TeleTrusTObjectIdentifiers + { + private TeleTrusTObjectIdentifiers() + { + } + + public static readonly DerObjectIdentifier TeleTrusTAlgorithm = new DerObjectIdentifier("1.3.36.3"); + + public static readonly DerObjectIdentifier RipeMD160 = new DerObjectIdentifier(TeleTrusTAlgorithm + ".2.1"); + public static readonly DerObjectIdentifier RipeMD128 = new DerObjectIdentifier(TeleTrusTAlgorithm + ".2.2"); + public static readonly DerObjectIdentifier RipeMD256 = new DerObjectIdentifier(TeleTrusTAlgorithm + ".2.3"); + + public static readonly DerObjectIdentifier TeleTrusTRsaSignatureAlgorithm = new DerObjectIdentifier(TeleTrusTAlgorithm + ".3.1"); + + public static readonly DerObjectIdentifier RsaSignatureWithRipeMD160 = new DerObjectIdentifier(TeleTrusTRsaSignatureAlgorithm + ".2"); + public static readonly DerObjectIdentifier RsaSignatureWithRipeMD128 = new DerObjectIdentifier(TeleTrusTRsaSignatureAlgorithm + ".3"); + public static readonly DerObjectIdentifier RsaSignatureWithRipeMD256 = new DerObjectIdentifier(TeleTrusTRsaSignatureAlgorithm + ".4"); + + public static readonly DerObjectIdentifier ECSign = new DerObjectIdentifier(TeleTrusTAlgorithm + ".3.2"); + + public static readonly DerObjectIdentifier ECSignWithSha1 = new DerObjectIdentifier(ECSign + ".1"); + public static readonly DerObjectIdentifier ECSignWithRipeMD160 = new DerObjectIdentifier(ECSign + ".2"); + + public static readonly DerObjectIdentifier EccBrainpool = new DerObjectIdentifier(TeleTrusTAlgorithm + ".3.2.8"); + public static readonly DerObjectIdentifier EllipticCurve = new DerObjectIdentifier(EccBrainpool + ".1"); + public static readonly DerObjectIdentifier VersionOne = new DerObjectIdentifier(EllipticCurve + ".1"); + + public static readonly DerObjectIdentifier BrainpoolP160R1 = new DerObjectIdentifier(VersionOne + ".1"); + public static readonly DerObjectIdentifier BrainpoolP160T1 = new DerObjectIdentifier(VersionOne + ".2"); + public static readonly DerObjectIdentifier BrainpoolP192R1 = new DerObjectIdentifier(VersionOne + ".3"); + public static readonly DerObjectIdentifier BrainpoolP192T1 = new DerObjectIdentifier(VersionOne + ".4"); + public static readonly DerObjectIdentifier BrainpoolP224R1 = new DerObjectIdentifier(VersionOne + ".5"); + public static readonly DerObjectIdentifier BrainpoolP224T1 = new DerObjectIdentifier(VersionOne + ".6"); + public static readonly DerObjectIdentifier BrainpoolP256R1 = new DerObjectIdentifier(VersionOne + ".7"); + public static readonly DerObjectIdentifier BrainpoolP256T1 = new DerObjectIdentifier(VersionOne + ".8"); + public static readonly DerObjectIdentifier BrainpoolP320R1 = new DerObjectIdentifier(VersionOne + ".9"); + public static readonly DerObjectIdentifier BrainpoolP320T1 = new DerObjectIdentifier(VersionOne + ".10"); + public static readonly DerObjectIdentifier BrainpoolP384R1 = new DerObjectIdentifier(VersionOne + ".11"); + public static readonly DerObjectIdentifier BrainpoolP384T1 = new DerObjectIdentifier(VersionOne + ".12"); + public static readonly DerObjectIdentifier BrainpoolP512R1 = new DerObjectIdentifier(VersionOne + ".13"); + public static readonly DerObjectIdentifier BrainpoolP512T1 = new DerObjectIdentifier(VersionOne + ".14"); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/teletrust/TeleTrusTObjectIdentifiers.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/teletrust/TeleTrusTObjectIdentifiers.cs.meta new file mode 100644 index 0000000..91c0370 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/teletrust/TeleTrusTObjectIdentifiers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ed07e344a2f775b40a15b6d340f7396c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/tsp.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/tsp.meta new file mode 100644 index 0000000..1cff6b2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/tsp.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ec43bc0b080ff234da1e52baf586342f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/tsp/Accuracy.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/tsp/Accuracy.cs new file mode 100644 index 0000000..0cbc731 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/tsp/Accuracy.cs @@ -0,0 +1,120 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Tsp +{ + public class Accuracy + : Asn1Encodable + { + private readonly DerInteger seconds; + private readonly DerInteger millis; + private readonly DerInteger micros; + + // constants + protected const int MinMillis = 1; + protected const int MaxMillis = 999; + protected const int MinMicros = 1; + protected const int MaxMicros = 999; + + public Accuracy( + DerInteger seconds, + DerInteger millis, + DerInteger micros) + { + if (null != millis) + { + int millisValue = millis.IntValueExact; + if (millisValue < MinMillis || millisValue > MaxMillis) + throw new ArgumentException("Invalid millis field : not in (1..999)"); + } + if (null != micros) + { + int microsValue = micros.IntValueExact; + if (microsValue < MinMicros || microsValue > MaxMicros) + throw new ArgumentException("Invalid micros field : not in (1..999)"); + } + + this.seconds = seconds; + this.millis = millis; + this.micros = micros; + } + + private Accuracy( + Asn1Sequence seq) + { + for (int i = 0; i < seq.Count; ++i) + { + // seconds + if (seq[i] is DerInteger) + { + seconds = (DerInteger) seq[i]; + } + else if (seq[i] is Asn1TaggedObject) + { + Asn1TaggedObject extra = (Asn1TaggedObject)seq[i]; + + switch (extra.TagNo) + { + case 0: + millis = DerInteger.GetInstance(extra, false); + int millisValue = millis.IntValueExact; + if (millisValue < MinMillis || millisValue > MaxMillis) + throw new ArgumentException("Invalid millis field : not in (1..999)"); + break; + case 1: + micros = DerInteger.GetInstance(extra, false); + int microsValue = micros.IntValueExact; + if (microsValue < MinMicros || microsValue > MaxMicros) + throw new ArgumentException("Invalid micros field : not in (1..999)"); + break; + default: + throw new ArgumentException("Invalid tag number"); + } + } + } + } + + public static Accuracy GetInstance(object obj) + { + if (obj is Accuracy) + return (Accuracy)obj; + if (obj == null) + return null; + return new Accuracy(Asn1Sequence.GetInstance(obj)); + } + + public DerInteger Seconds + { + get { return seconds; } + } + + public DerInteger Millis + { + get { return millis; } + } + + public DerInteger Micros + { + get { return micros; } + } + + /** + *
+		 * Accuracy ::= SEQUENCE {
+		 *             seconds        INTEGER              OPTIONAL,
+		 *             millis     [0] INTEGER  (1..999)    OPTIONAL,
+		 *             micros     [1] INTEGER  (1..999)    OPTIONAL
+		 *             }
+		 * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + v.AddOptional(seconds); + v.AddOptionalTagged(false, 0, millis); + v.AddOptionalTagged(false, 1, micros); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/tsp/Accuracy.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/tsp/Accuracy.cs.meta new file mode 100644 index 0000000..54c51ee --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/tsp/Accuracy.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 233509d0aa112ba498c470dd7028c335 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/tsp/MessageImprint.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/tsp/MessageImprint.cs new file mode 100644 index 0000000..cb72862 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/tsp/MessageImprint.cs @@ -0,0 +1,63 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Tsp +{ + public class MessageImprint + : Asn1Encodable + { + private readonly AlgorithmIdentifier hashAlgorithm; + private readonly byte[] hashedMessage; + + public static MessageImprint GetInstance(object obj) + { + if (obj is MessageImprint) + return (MessageImprint)obj; + if (obj == null) + return null; + return new MessageImprint(Asn1Sequence.GetInstance(obj)); + } + + private MessageImprint( + Asn1Sequence seq) + { + if (seq.Count != 2) + throw new ArgumentException("Wrong number of elements in sequence", "seq"); + + this.hashAlgorithm = AlgorithmIdentifier.GetInstance(seq[0]); + this.hashedMessage = Asn1OctetString.GetInstance(seq[1]).GetOctets(); + } + + public MessageImprint( + AlgorithmIdentifier hashAlgorithm, + byte[] hashedMessage) + { + this.hashAlgorithm = hashAlgorithm; + this.hashedMessage = hashedMessage; + } + + public AlgorithmIdentifier HashAlgorithm + { + get { return hashAlgorithm; } + } + + public byte[] GetHashedMessage() + { + return hashedMessage; + } + + /** + *
+		 *    MessageImprint ::= SEQUENCE  {
+		 *       hashAlgorithm                AlgorithmIdentifier,
+		 *       hashedMessage                OCTET STRING  }
+		 * 
+ */ + public override Asn1Object ToAsn1Object() + { + return new DerSequence(hashAlgorithm, new DerOctetString(hashedMessage)); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/tsp/MessageImprint.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/tsp/MessageImprint.cs.meta new file mode 100644 index 0000000..686719c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/tsp/MessageImprint.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 185030f62eade294c99d7894039b7b15 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/tsp/TSTInfo.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/tsp/TSTInfo.cs new file mode 100644 index 0000000..3f5ab28 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/tsp/TSTInfo.cs @@ -0,0 +1,211 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Tsp +{ + public class TstInfo + : Asn1Encodable + { + private readonly DerInteger version; + private readonly DerObjectIdentifier tsaPolicyId; + private readonly MessageImprint messageImprint; + private readonly DerInteger serialNumber; + private readonly DerGeneralizedTime genTime; + private readonly Accuracy accuracy; + private readonly DerBoolean ordering; + private readonly DerInteger nonce; + private readonly GeneralName tsa; + private readonly X509Extensions extensions; + + public static TstInfo GetInstance(object obj) + { + if (obj is TstInfo) + return (TstInfo)obj; + if (obj == null) + return null; + return new TstInfo(Asn1Sequence.GetInstance(obj)); + } + + private TstInfo( + Asn1Sequence seq) + { + IEnumerator e = seq.GetEnumerator(); + + // version + e.MoveNext(); + version = DerInteger.GetInstance(e.Current); + + // tsaPolicy + e.MoveNext(); + tsaPolicyId = DerObjectIdentifier.GetInstance(e.Current); + + // messageImprint + e.MoveNext(); + messageImprint = MessageImprint.GetInstance(e.Current); + + // serialNumber + e.MoveNext(); + serialNumber = DerInteger.GetInstance(e.Current); + + // genTime + e.MoveNext(); + genTime = DerGeneralizedTime.GetInstance(e.Current); + + // default for ordering + ordering = DerBoolean.False; + + while (e.MoveNext()) + { + Asn1Object o = (Asn1Object) e.Current; + + if (o is Asn1TaggedObject) + { + DerTaggedObject tagged = (DerTaggedObject) o; + + switch (tagged.TagNo) + { + case 0: + tsa = GeneralName.GetInstance(tagged, true); + break; + case 1: + extensions = X509Extensions.GetInstance(tagged, false); + break; + default: + throw new ArgumentException("Unknown tag value " + tagged.TagNo); + } + } + + if (o is DerSequence) + { + accuracy = Accuracy.GetInstance(o); + } + + if (o is DerBoolean) + { + ordering = DerBoolean.GetInstance(o); + } + + if (o is DerInteger) + { + nonce = DerInteger.GetInstance(o); + } + } + } + + public TstInfo( + DerObjectIdentifier tsaPolicyId, + MessageImprint messageImprint, + DerInteger serialNumber, + DerGeneralizedTime genTime, + Accuracy accuracy, + DerBoolean ordering, + DerInteger nonce, + GeneralName tsa, + X509Extensions extensions) + { + this.version = new DerInteger(1); + this.tsaPolicyId = tsaPolicyId; + this.messageImprint = messageImprint; + this.serialNumber = serialNumber; + this.genTime = genTime; + this.accuracy = accuracy; + this.ordering = ordering; + this.nonce = nonce; + this.tsa = tsa; + this.extensions = extensions; + } + + public DerInteger Version + { + get { return version; } + } + + public MessageImprint MessageImprint + { + get { return messageImprint; } + } + + public DerObjectIdentifier Policy + { + get { return tsaPolicyId; } + } + + public DerInteger SerialNumber + { + get { return serialNumber; } + } + + public Accuracy Accuracy + { + get { return accuracy; } + } + + public DerGeneralizedTime GenTime + { + get { return genTime; } + } + + public DerBoolean Ordering + { + get { return ordering; } + } + + public DerInteger Nonce + { + get { return nonce; } + } + + public GeneralName Tsa + { + get { return tsa; } + } + + public X509Extensions Extensions + { + get { return extensions; } + } + + /** + *
+		 *
+		 *     TstInfo ::= SEQUENCE  {
+		 *        version                      INTEGER  { v1(1) },
+		 *        policy                       TSAPolicyId,
+		 *        messageImprint               MessageImprint,
+		 *          -- MUST have the same value as the similar field in
+		 *          -- TimeStampReq
+		 *        serialNumber                 INTEGER,
+		 *         -- Time-Stamping users MUST be ready to accommodate integers
+		 *         -- up to 160 bits.
+		 *        genTime                      GeneralizedTime,
+		 *        accuracy                     Accuracy                 OPTIONAL,
+		 *        ordering                     BOOLEAN             DEFAULT FALSE,
+		 *        nonce                        INTEGER                  OPTIONAL,
+		 *          -- MUST be present if the similar field was present
+		 *          -- in TimeStampReq.  In that case it MUST have the same value.
+		 *        tsa                          [0] GeneralName          OPTIONAL,
+		 *        extensions                   [1] IMPLICIT Extensions   OPTIONAL  }
+		 *
+		 * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(version, tsaPolicyId, messageImprint, serialNumber, genTime); + v.AddOptional(accuracy); + + if (ordering != null && ordering.IsTrue) + { + v.Add(ordering); + } + + v.AddOptional(nonce); + v.AddOptionalTagged(true, 0, tsa); + v.AddOptionalTagged(false, 1, extensions); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/tsp/TSTInfo.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/tsp/TSTInfo.cs.meta new file mode 100644 index 0000000..0245147 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/tsp/TSTInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 55e172987e25e19429488695fb9f593c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/tsp/TimeStampReq.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/tsp/TimeStampReq.cs new file mode 100644 index 0000000..7173172 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/tsp/TimeStampReq.cs @@ -0,0 +1,143 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Tsp +{ + public class TimeStampReq + : Asn1Encodable + { + private readonly DerInteger version; + private readonly MessageImprint messageImprint; + private readonly DerObjectIdentifier tsaPolicy; + private readonly DerInteger nonce; + private readonly DerBoolean certReq; + private readonly X509Extensions extensions; + + public static TimeStampReq GetInstance(object obj) + { + if (obj is TimeStampReq) + return (TimeStampReq)obj; + if (obj == null) + return null; + return new TimeStampReq(Asn1Sequence.GetInstance(obj)); + } + + private TimeStampReq( + Asn1Sequence seq) + { + int nbObjects = seq.Count; + int seqStart = 0; + + // version + version = DerInteger.GetInstance(seq[seqStart++]); + + // messageImprint + messageImprint = MessageImprint.GetInstance(seq[seqStart++]); + + for (int opt = seqStart; opt < nbObjects; opt++) + { + // tsaPolicy + if (seq[opt] is DerObjectIdentifier) + { + tsaPolicy = DerObjectIdentifier.GetInstance(seq[opt]); + } + // nonce + else if (seq[opt] is DerInteger) + { + nonce = DerInteger.GetInstance(seq[opt]); + } + // certReq + else if (seq[opt] is DerBoolean) + { + certReq = DerBoolean.GetInstance(seq[opt]); + } + // extensions + else if (seq[opt] is Asn1TaggedObject) + { + Asn1TaggedObject tagged = (Asn1TaggedObject) seq[opt]; + if (tagged.TagNo == 0) + { + extensions = X509Extensions.GetInstance(tagged, false); + } + } + } + } + + public TimeStampReq( + MessageImprint messageImprint, + DerObjectIdentifier tsaPolicy, + DerInteger nonce, + DerBoolean certReq, + X509Extensions extensions) + { + // default + this.version = new DerInteger(1); + + this.messageImprint = messageImprint; + this.tsaPolicy = tsaPolicy; + this.nonce = nonce; + this.certReq = certReq; + this.extensions = extensions; + } + + public DerInteger Version + { + get { return version; } + } + + public MessageImprint MessageImprint + { + get { return messageImprint; } + } + + public DerObjectIdentifier ReqPolicy + { + get { return tsaPolicy; } + } + + public DerInteger Nonce + { + get { return nonce; } + } + + public DerBoolean CertReq + { + get { return certReq; } + } + + public X509Extensions Extensions + { + get { return extensions; } + } + + /** + *
+		 * TimeStampReq ::= SEQUENCE  {
+		 *  version                      INTEGER  { v1(1) },
+		 *  messageImprint               MessageImprint,
+		 *    --a hash algorithm OID and the hash value of the data to be
+		 *    --time-stamped
+		 *  reqPolicy             TSAPolicyId              OPTIONAL,
+		 *  nonce                 INTEGER                  OPTIONAL,
+		 *  certReq               BOOLEAN                  DEFAULT FALSE,
+		 *  extensions            [0] IMPLICIT Extensions  OPTIONAL
+		 * }
+		 * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(version, messageImprint); + v.AddOptional(tsaPolicy, nonce); + + if (certReq != null && certReq.IsTrue) + { + v.Add(certReq); + } + + v.AddOptionalTagged(false, 0, extensions); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/tsp/TimeStampReq.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/tsp/TimeStampReq.cs.meta new file mode 100644 index 0000000..4b97f5a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/tsp/TimeStampReq.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 80c11b502995fc5459a74683064fd4de +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/tsp/TimeStampResp.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/tsp/TimeStampResp.cs new file mode 100644 index 0000000..3dde0df --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/tsp/TimeStampResp.cs @@ -0,0 +1,67 @@ +using System; + +using Org.BouncyCastle.Asn1.Cmp; +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Tsp +{ + public class TimeStampResp + : Asn1Encodable + { + private readonly PkiStatusInfo pkiStatusInfo; + private readonly ContentInfo timeStampToken; + + public static TimeStampResp GetInstance(object obj) + { + if (obj is TimeStampResp) + return (TimeStampResp)obj; + if (obj == null) + return null; + return new TimeStampResp(Asn1Sequence.GetInstance(obj)); + } + + private TimeStampResp( + Asn1Sequence seq) + { + this.pkiStatusInfo = PkiStatusInfo.GetInstance(seq[0]); + + if (seq.Count > 1) + { + this.timeStampToken = ContentInfo.GetInstance(seq[1]); + } + } + + public TimeStampResp( + PkiStatusInfo pkiStatusInfo, + ContentInfo timeStampToken) + { + this.pkiStatusInfo = pkiStatusInfo; + this.timeStampToken = timeStampToken; + } + + public PkiStatusInfo Status + { + get { return pkiStatusInfo; } + } + + public ContentInfo TimeStampToken + { + get { return timeStampToken; } + } + + /** + *
+		 * TimeStampResp ::= SEQUENCE  {
+		 *   status                  PkiStatusInfo,
+		 *   timeStampToken          TimeStampToken     OPTIONAL  }
+		 * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(pkiStatusInfo); + v.AddOptional(timeStampToken); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/tsp/TimeStampResp.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/tsp/TimeStampResp.cs.meta new file mode 100644 index 0000000..b2913aa --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/tsp/TimeStampResp.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 689c91b39f96f6048ad13a972fb50d6c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ua.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ua.meta new file mode 100644 index 0000000..3b93fd1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ua.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: de56d7cd099ef944fb326abd9575f1b8 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ua/UAObjectIdentifiers.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ua/UAObjectIdentifiers.cs new file mode 100644 index 0000000..9beca3a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ua/UAObjectIdentifiers.cs @@ -0,0 +1,107 @@ +namespace Org.BouncyCastle.Asn1.UA +{ + /** + * Ukrainian object identifiers + *

+ * {iso(1) member-body(2) Ukraine(804) root(2) security(1) cryptography(1) pki(1)} + *

+ * { ... pki-alg(1) pki-alg-sym(3) Dstu4145WithGost34311(1) PB(1)} + *

+ * DSTU4145 in polynomial basis has 2 oids, one for little-endian representation and one for big-endian + */ + public abstract class UAObjectIdentifiers + { + /** Base OID: 1.2.804.2.1.1.1 */ + public static readonly DerObjectIdentifier UaOid = new DerObjectIdentifier("1.2.804.2.1.1.1"); + + /** DSTU4145 Little Endian presentation. OID: 1.2.804.2.1.1.1.1.3.1.1 */ + public static readonly DerObjectIdentifier dstu4145le = UaOid.Branch("1.3.1.1"); + /** DSTU4145 Big Endian presentation. OID: 1.2.804.2.1.1.1.1.3.1.1.1 */ + public static readonly DerObjectIdentifier dstu4145be = UaOid.Branch("1.3.1.1.1.1"); + + /** DSTU7564 256-bit digest presentation. */ + public static readonly DerObjectIdentifier dstu7564digest_256 = UaOid.Branch("1.2.2.1"); + /** DSTU7564 384-bit digest presentation. */ + public static readonly DerObjectIdentifier dstu7564digest_384 = UaOid.Branch("1.2.2.2"); + /** DSTU7564 512-bit digest presentation. */ + public static readonly DerObjectIdentifier dstu7564digest_512 = UaOid.Branch("1.2.2.3"); + + /** DSTU7564 256-bit mac presentation. */ + public static readonly DerObjectIdentifier dstu7564mac_256 = UaOid.Branch("1.2.2.4"); + /** DSTU7564 384-bit mac presentation. */ + public static readonly DerObjectIdentifier dstu7564mac_384 = UaOid.Branch("1.2.2.5"); + /** DSTU7564 512-bit mac presentation. */ + public static readonly DerObjectIdentifier dstu7564mac_512 = UaOid.Branch("1.2.2.6"); + + + /** DSTU7624 in ECB mode with 128 bit block/key presentation */ + public static readonly DerObjectIdentifier dstu7624ecb_128 = UaOid.Branch("1.1.3.1.1"); + /** DSTU7624 in ECB mode with 256 bit block/key presentation */ + public static readonly DerObjectIdentifier dstu7624ecb_256 = UaOid.Branch("1.1.3.1.2"); + /** DSTU7624 in ECB mode with 512 bit block/key presentation */ + public static readonly DerObjectIdentifier dstu7624ecb_512 = UaOid.Branch("1.1.3.1.3"); + + /** DSTU7624 in CTR mode with 128 bit block/key presentation */ + public static readonly DerObjectIdentifier dstu7624ctr_128 = UaOid.Branch("1.1.3.2.1"); + /** DSTU7624 in CTR mode with 256 bit block/key presentation */ + public static readonly DerObjectIdentifier dstu7624ctr_256 = UaOid.Branch("1.1.3.2.2"); + /** DSTU7624 in CTR mode with 512 bit block/key presentation */ + public static readonly DerObjectIdentifier dstu7624ctr_512 = UaOid.Branch("1.1.3.2.3"); + + /** DSTU7624 in CFB mode with 128 bit block/key presentation */ + public static readonly DerObjectIdentifier dstu7624cfb_128 = UaOid.Branch("1.1.3.3.1"); + /** DSTU7624 in CFB mode with 256 bit block/key presentation */ + public static readonly DerObjectIdentifier dstu7624cfb_256 = UaOid.Branch("1.1.3.3.2"); + /** DSTU7624 in CFB mode with 512 bit block/key presentation */ + public static readonly DerObjectIdentifier dstu7624cfb_512 = UaOid.Branch("1.1.3.3.3"); + + /** DSTU7624 in MAC mode with 128 bit block/key presentation */ + public static readonly DerObjectIdentifier dstu7624cmac_128 = UaOid.Branch("1.1.3.4.1"); + /** DSTU7624 in MAC mode with 256 bit block/key presentation */ + public static readonly DerObjectIdentifier dstu7624cmac_256 = UaOid.Branch("1.1.3.4.2"); + /** DSTU7624 in MAC mode with 512 bit block/key presentation */ + public static readonly DerObjectIdentifier dstu7624cmac_512 = UaOid.Branch("1.1.3.4.3"); + + /** DSTU7624 in CBC mode with 128 bit block/key presentation */ + public static readonly DerObjectIdentifier dstu7624cbc_128 = UaOid.Branch("1.1.3.5.1"); + /** DSTU7624 in CBC mode with 256 bit block/key presentation */ + public static readonly DerObjectIdentifier dstu7624cbc_256 = UaOid.Branch("1.1.3.5.2"); + /** DSTU7624 in CBC mode with 512 bit block/key presentation */ + public static readonly DerObjectIdentifier dstu7624cbc_512 = UaOid.Branch("1.1.3.5.3"); + + /** DSTU7624 in OFB mode with 128 bit block/key presentation */ + public static readonly DerObjectIdentifier dstu7624ofb_128 = UaOid.Branch("1.1.3.6.1"); + /** DSTU7624 in OFB mode with 256 bit block/key presentation */ + public static readonly DerObjectIdentifier dstu7624ofb_256 = UaOid.Branch("1.1.3.6.2"); + /** DSTU7624 in OFB mode with 512 bit block/key presentation */ + public static readonly DerObjectIdentifier dstu7624ofb_512 = UaOid.Branch("1.1.3.6.3"); + + /** DSTU7624 in GMAC (GCM witout encryption) mode with 128 bit block/key presentation */ + public static readonly DerObjectIdentifier dstu7624gmac_128 = UaOid.Branch("1.1.3.7.1"); + /** DSTU7624 in GMAC (GCM witout encryption) mode with 256 bit block/key presentation */ + public static readonly DerObjectIdentifier dstu7624gmac_256 = UaOid.Branch("1.1.3.7.2"); + /** DSTU7624 in GMAC (GCM witout encryption) mode with 512 bit block/key presentation */ + public static readonly DerObjectIdentifier dstu7624gmac_512 = UaOid.Branch("1.1.3.7.3"); + + /** DSTU7624 in CCM mode with 128 bit block/key presentation */ + public static readonly DerObjectIdentifier dstu7624ccm_128 = UaOid.Branch("1.1.3.8.1"); + /** DSTU7624 in CCM mode with 256 bit block/key presentation */ + public static readonly DerObjectIdentifier dstu7624ccm_256 = UaOid.Branch("1.1.3.8.2"); + /** DSTU7624 in CCM mode with 512 bit block/key presentation */ + public static readonly DerObjectIdentifier dstu7624ccm_512 = UaOid.Branch("1.1.3.8.3"); + + /** DSTU7624 in XTS mode with 128 bit block/key presentation */ + public static readonly DerObjectIdentifier dstu7624xts_128 = UaOid.Branch("1.1.3.9.1"); + /** DSTU7624 in XTS mode with 256 bit block/key presentation */ + public static readonly DerObjectIdentifier dstu7624xts_256 = UaOid.Branch("1.1.3.9.2"); + /** DSTU7624 in XTS mode with 512 bit block/key presentation */ + public static readonly DerObjectIdentifier dstu7624xts_512 = UaOid.Branch("1.1.3.9.3"); + + /** DSTU7624 in key wrap (KW) mode with 128 bit block/key presentation */ + public static readonly DerObjectIdentifier dstu7624kw_128 = UaOid.Branch("1.1.3.10.1"); + /** DSTU7624 in key wrap (KW) mode with 256 bit block/key presentation */ + public static readonly DerObjectIdentifier dstu7624kw_256 = UaOid.Branch("1.1.3.10.2"); + /** DSTU7624 in key wrap (KW) mode with 512 bit block/key presentation */ + public static readonly DerObjectIdentifier dstu7624kw_512 = UaOid.Branch("1.1.3.10.3"); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ua/UAObjectIdentifiers.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ua/UAObjectIdentifiers.cs.meta new file mode 100644 index 0000000..94823d3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/ua/UAObjectIdentifiers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f17989400eafc9444bfc98322c6a3aab +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/util.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/util.meta new file mode 100644 index 0000000..127e8d6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/util.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 6a6642b894820da458e05b72a8005a20 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/util/Asn1Dump.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/util/Asn1Dump.cs new file mode 100644 index 0000000..511bc30 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/util/Asn1Dump.cs @@ -0,0 +1,345 @@ +using System; +using System.IO; +using System.Text; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Asn1.Utilities +{ + public sealed class Asn1Dump + { + private static readonly string NewLine = Platform.NewLine; + + private Asn1Dump() + { + } + + private const string Tab = " "; + private const int SampleSize = 32; + + /** + * dump a Der object as a formatted string with indentation + * + * @param obj the Asn1Object to be dumped out. + */ + private static void AsString( + string indent, + bool verbose, + Asn1Object obj, + StringBuilder buf) + { + if (obj is Asn1Null) + { + buf.Append(indent); + buf.Append("NULL"); + buf.Append(NewLine); + } + else if (obj is Asn1Sequence) + { + buf.Append(indent); + if (obj is BerSequence) + { + buf.Append("BER Sequence"); + } + else if (obj is DerSequence) + { + buf.Append("DER Sequence"); + } + else + { + buf.Append("Sequence"); + } + buf.Append(NewLine); + + Asn1Sequence sequence = (Asn1Sequence)obj; + string elementsIndent = indent + Tab; + + for (int i = 0, count = sequence.Count; i < count; ++i) + { + AsString(elementsIndent, verbose, sequence[i].ToAsn1Object(), buf); + } + } + else if (obj is Asn1Set) + { + buf.Append(indent); + if (obj is BerSet) + { + buf.Append("BER Set"); + } + else if (obj is DerSet) + { + buf.Append("DER Set"); + } + else + { + buf.Append("Set"); + } + buf.Append(NewLine); + + Asn1Set set = (Asn1Set)obj; + string elementsIndent = indent + Tab; + + for (int i = 0, count = set.Count; i < count; ++i) + { + AsString(elementsIndent, verbose, set[i].ToAsn1Object(), buf); + } + } + else if (obj is Asn1TaggedObject) + { + string tab = indent + Tab; + buf.Append(indent); + if (obj is BerTaggedObject) + { + buf.Append("BER Tagged ["); + } + else + { + buf.Append("Tagged ["); + } + + Asn1TaggedObject o = (Asn1TaggedObject)obj; + + buf.Append(o.TagNo.ToString()); + buf.Append(']'); + + if (!o.IsExplicit()) + { + buf.Append(" IMPLICIT "); + } + + buf.Append(NewLine); + + if (o.IsEmpty()) + { + buf.Append(tab); + buf.Append("EMPTY"); + buf.Append(NewLine); + } + else + { + AsString(tab, verbose, o.GetObject(), buf); + } + } + else if (obj is DerObjectIdentifier) + { + buf.Append(indent + "ObjectIdentifier(" + ((DerObjectIdentifier)obj).Id + ")" + NewLine); + } + else if (obj is DerBoolean) + { + buf.Append(indent + "Boolean(" + ((DerBoolean)obj).IsTrue + ")" + NewLine); + } + else if (obj is DerInteger) + { + buf.Append(indent + "Integer(" + ((DerInteger)obj).Value + ")" + NewLine); + } + else if (obj is BerOctetString) + { + byte[] octets = ((Asn1OctetString)obj).GetOctets(); + string extra = verbose ? dumpBinaryDataAsString(indent, octets) : ""; + buf.Append(indent + "BER Octet String" + "[" + octets.Length + "] " + extra + NewLine); + } + else if (obj is DerOctetString) + { + byte[] octets = ((Asn1OctetString)obj).GetOctets(); + string extra = verbose ? dumpBinaryDataAsString(indent, octets) : ""; + buf.Append(indent + "DER Octet String" + "[" + octets.Length + "] " + extra + NewLine); + } + else if (obj is DerBitString) + { + DerBitString bt = (DerBitString)obj; + byte[] bytes = bt.GetBytes(); + string extra = verbose ? dumpBinaryDataAsString(indent, bytes) : ""; + buf.Append(indent + "DER Bit String" + "[" + bytes.Length + ", " + bt.PadBits + "] " + extra + NewLine); + } + else if (obj is DerIA5String) + { + buf.Append(indent + "IA5String(" + ((DerIA5String)obj).GetString() + ") " + NewLine); + } + else if (obj is DerUtf8String) + { + buf.Append(indent + "UTF8String(" + ((DerUtf8String)obj).GetString() + ") " + NewLine); + } + else if (obj is DerPrintableString) + { + buf.Append(indent + "PrintableString(" + ((DerPrintableString)obj).GetString() + ") " + NewLine); + } + else if (obj is DerVisibleString) + { + buf.Append(indent + "VisibleString(" + ((DerVisibleString)obj).GetString() + ") " + NewLine); + } + else if (obj is DerBmpString) + { + buf.Append(indent + "BMPString(" + ((DerBmpString)obj).GetString() + ") " + NewLine); + } + else if (obj is DerT61String) + { + buf.Append(indent + "T61String(" + ((DerT61String)obj).GetString() + ") " + NewLine); + } + else if (obj is DerGraphicString) + { + buf.Append(indent + "GraphicString(" + ((DerGraphicString)obj).GetString() + ") " + NewLine); + } + else if (obj is DerVideotexString) + { + buf.Append(indent + "VideotexString(" + ((DerVideotexString)obj).GetString() + ") " + NewLine); + } + else if (obj is DerUtcTime) + { + buf.Append(indent + "UTCTime(" + ((DerUtcTime)obj).TimeString + ") " + NewLine); + } + else if (obj is DerGeneralizedTime) + { + buf.Append(indent + "GeneralizedTime(" + ((DerGeneralizedTime)obj).GetTime() + ") " + NewLine); + } + else if (obj is BerApplicationSpecific) + { + buf.Append(outputApplicationSpecific("BER", indent, verbose, (BerApplicationSpecific)obj)); + } + else if (obj is DerApplicationSpecific) + { + buf.Append(outputApplicationSpecific("DER", indent, verbose, (DerApplicationSpecific)obj)); + } + else if (obj is DerEnumerated) + { + DerEnumerated en = (DerEnumerated)obj; + buf.Append(indent + "DER Enumerated(" + en.Value + ")" + NewLine); + } + else if (obj is DerExternal) + { + DerExternal ext = (DerExternal)obj; + buf.Append(indent + "External " + NewLine); + string tab = indent + Tab; + + if (ext.DirectReference != null) + { + buf.Append(tab + "Direct Reference: " + ext.DirectReference.Id + NewLine); + } + if (ext.IndirectReference != null) + { + buf.Append(tab + "Indirect Reference: " + ext.IndirectReference.ToString() + NewLine); + } + if (ext.DataValueDescriptor != null) + { + AsString(tab, verbose, ext.DataValueDescriptor, buf); + } + buf.Append(tab + "Encoding: " + ext.Encoding + NewLine); + AsString(tab, verbose, ext.ExternalContent, buf); + } + else + { + buf.Append(indent + obj.ToString() + NewLine); + } + } + + private static string outputApplicationSpecific( + string type, + string indent, + bool verbose, + DerApplicationSpecific app) + { + StringBuilder buf = new StringBuilder(); + + if (app.IsConstructed()) + { + try + { + Asn1Sequence s = Asn1Sequence.GetInstance(app.GetObject(Asn1Tags.Sequence)); + buf.Append(indent + type + " ApplicationSpecific[" + app.ApplicationTag + "]" + NewLine); + foreach (Asn1Encodable ae in s) + { + AsString(indent + Tab, verbose, ae.ToAsn1Object(), buf); + } + } + catch (IOException e) + { + buf.Append(e); + } + return buf.ToString(); + } + + return indent + type + " ApplicationSpecific[" + app.ApplicationTag + "] (" + + Hex.ToHexString(app.GetContents()) + ")" + NewLine; + } + + /** + * dump out a DER object as a formatted string, in non-verbose mode + * + * @param obj the Asn1Encodable to be dumped out. + * @return the resulting string. + */ + public static string DumpAsString( + Asn1Encodable obj) + { + return DumpAsString(obj, false); + } + + /** + * Dump out the object as a string + * + * @param obj the Asn1Encodable to be dumped out. + * @param verbose if true, dump out the contents of octet and bit strings. + * @return the resulting string. + */ + public static string DumpAsString( + Asn1Encodable obj, + bool verbose) + { + StringBuilder buf = new StringBuilder(); + AsString("", verbose, obj.ToAsn1Object(), buf); + return buf.ToString(); + } + + private static string dumpBinaryDataAsString(string indent, byte[] bytes) + { + indent += Tab; + + StringBuilder buf = new StringBuilder(NewLine); + + for (int i = 0; i < bytes.Length; i += SampleSize) + { + if (bytes.Length - i > SampleSize) + { + buf.Append(indent); + buf.Append(Hex.ToHexString(bytes, i, SampleSize)); + buf.Append(Tab); + buf.Append(calculateAscString(bytes, i, SampleSize)); + buf.Append(NewLine); + } + else + { + buf.Append(indent); + buf.Append(Hex.ToHexString(bytes, i, bytes.Length - i)); + for (int j = bytes.Length - i; j != SampleSize; j++) + { + buf.Append(" "); + } + buf.Append(Tab); + buf.Append(calculateAscString(bytes, i, bytes.Length - i)); + buf.Append(NewLine); + } + } + + return buf.ToString(); + } + + private static string calculateAscString( + byte[] bytes, + int off, + int len) + { + StringBuilder buf = new StringBuilder(); + + for (int i = off; i != off + len; i++) + { + char c = (char)bytes[i]; + if (c >= ' ' && c <= '~') + { + buf.Append(c); + } + } + + return buf.ToString(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/util/Asn1Dump.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/util/Asn1Dump.cs.meta new file mode 100644 index 0000000..c6a088d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/util/Asn1Dump.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9d58221256e916a48a13465421b1cf41 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/util/Dump.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/util/Dump.cs new file mode 100644 index 0000000..e313fe8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/util/Dump.cs @@ -0,0 +1,30 @@ +#if !PORTABLE +using System; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Utilities +{ + public sealed class Dump + { + private Dump() + { + } + + public static void Main(string[] args) + { + FileStream fIn = File.OpenRead(args[0]); + Asn1InputStream bIn = new Asn1InputStream(fIn); + + Asn1Object obj; + while ((obj = bIn.ReadObject()) != null) + { + Console.WriteLine(Asn1Dump.DumpAsString(obj)); + } + + Platform.Dispose(bIn); + } + } +} +#endif diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/util/Dump.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/util/Dump.cs.meta new file mode 100644 index 0000000..0ab6792 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/util/Dump.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ee04c6d26b4bdf241999b0cdb0412e50 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/util/FilterStream.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/util/FilterStream.cs new file mode 100644 index 0000000..0c38c5b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/util/FilterStream.cs @@ -0,0 +1,83 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Utilities +{ + [Obsolete("Use Org.BouncyCastle.Utilities.IO.FilterStream")] + public class FilterStream : Stream + { + [Obsolete("Use Org.BouncyCastle.Utilities.IO.FilterStream")] + public FilterStream(Stream s) + { + this.s = s; + } + public override bool CanRead + { + get { return s.CanRead; } + } + public override bool CanSeek + { + get { return s.CanSeek; } + } + public override bool CanWrite + { + get { return s.CanWrite; } + } + public override long Length + { + get { return s.Length; } + } + public override long Position + { + get { return s.Position; } + set { s.Position = value; } + } +#if PORTABLE + protected override void Dispose(bool disposing) + { + if (disposing) + { + Platform.Dispose(s); + } + base.Dispose(disposing); + } +#else + public override void Close() + { + Platform.Dispose(s); + base.Close(); + } +#endif + public override void Flush() + { + s.Flush(); + } + public override long Seek(long offset, SeekOrigin origin) + { + return s.Seek(offset, origin); + } + public override void SetLength(long value) + { + s.SetLength(value); + } + public override int Read(byte[] buffer, int offset, int count) + { + return s.Read(buffer, offset, count); + } + public override int ReadByte() + { + return s.ReadByte(); + } + public override void Write(byte[] buffer, int offset, int count) + { + s.Write(buffer, offset, count); + } + public override void WriteByte(byte value) + { + s.WriteByte(value); + } + protected readonly Stream s; + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/util/FilterStream.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/util/FilterStream.cs.meta new file mode 100644 index 0000000..fb3a806 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/util/FilterStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ad976c4da206f1e4fae0e328c75e03fd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x500.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x500.meta new file mode 100644 index 0000000..486a277 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x500.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c46591fa93ecdaa4baf03feab8465c04 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x500/AttributeTypeAndValue.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x500/AttributeTypeAndValue.cs new file mode 100644 index 0000000..eb6b3ca --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x500/AttributeTypeAndValue.cs @@ -0,0 +1,60 @@ +using System; + +namespace Org.BouncyCastle.Asn1.X500 +{ + /** + * Holding class for the AttributeTypeAndValue structures that make up an RDN. + */ + public class AttributeTypeAndValue + : Asn1Encodable + { + private readonly DerObjectIdentifier type; + private readonly Asn1Encodable value; + + private AttributeTypeAndValue(Asn1Sequence seq) + { + type = (DerObjectIdentifier)seq[0]; + value = seq[1]; + } + + public static AttributeTypeAndValue GetInstance(object obj) + { + if (obj is AttributeTypeAndValue) + return (AttributeTypeAndValue)obj; + if (null != obj) + return new AttributeTypeAndValue(Asn1Sequence.GetInstance(obj)); + throw new ArgumentNullException("obj"); + } + + public AttributeTypeAndValue( + DerObjectIdentifier type, + Asn1Encodable value) + { + this.type = type; + this.value = value; + } + + public virtual DerObjectIdentifier Type + { + get { return type; } + } + + public virtual Asn1Encodable Value + { + get { return value; } + } + + /** + *

+         * AttributeTypeAndValue ::= SEQUENCE {
+         *           type         OBJECT IDENTIFIER,
+         *           value        ANY DEFINED BY type }
+         * 
+ * @return a basic ASN.1 object representation. + */ + public override Asn1Object ToAsn1Object() + { + return new DerSequence(type, value); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x500/AttributeTypeAndValue.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x500/AttributeTypeAndValue.cs.meta new file mode 100644 index 0000000..5ca7ddd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x500/AttributeTypeAndValue.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 26bd0517be7e73e4eb98a8c2208a73c5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x500/DirectoryString.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x500/DirectoryString.cs new file mode 100644 index 0000000..6585fcd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x500/DirectoryString.cs @@ -0,0 +1,74 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X500 +{ + public class DirectoryString + : Asn1Encodable, IAsn1Choice, IAsn1String + { + private readonly DerStringBase str; + + public static DirectoryString GetInstance(object obj) + { + if (obj == null || obj is DirectoryString) + return (DirectoryString) obj; + + if (obj is DerStringBase) + { + if (obj is DerT61String + || obj is DerPrintableString + || obj is DerUniversalString + || obj is DerUtf8String + || obj is DerBmpString) + { + return new DirectoryString((DerStringBase) obj); + } + } + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + public static DirectoryString GetInstance( + Asn1TaggedObject obj, + bool isExplicit) + { + if (!isExplicit) + throw new ArgumentException("choice item must be explicitly tagged"); + + return GetInstance(obj.GetObject()); + } + + private DirectoryString( + DerStringBase str) + { + this.str = str; + } + + public DirectoryString( + string str) + { + this.str = new DerUtf8String(str); + } + + public string GetString() + { + return str.GetString(); + } + + /** + *
+		 *  DirectoryString ::= CHOICE {
+		 *    teletexString               TeletexString (SIZE (1..MAX)),
+		 *    printableString             PrintableString (SIZE (1..MAX)),
+		 *    universalString             UniversalString (SIZE (1..MAX)),
+		 *    utf8String                  UTF8String (SIZE (1..MAX)),
+		 *    bmpString                   BMPString (SIZE (1..MAX))  }
+		 * 
+ */ + public override Asn1Object ToAsn1Object() + { + return str.ToAsn1Object(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x500/DirectoryString.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x500/DirectoryString.cs.meta new file mode 100644 index 0000000..051a613 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x500/DirectoryString.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2e4a5e4b60ecc934f9d2db3873bef0c8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x500/Rdn.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x500/Rdn.cs new file mode 100644 index 0000000..4881d08 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x500/Rdn.cs @@ -0,0 +1,104 @@ +using System; + +namespace Org.BouncyCastle.Asn1.X500 +{ + /** + * Holding class for a single Relative Distinguished Name (RDN). + */ + public class Rdn + : Asn1Encodable + { + private readonly Asn1Set values; + + private Rdn(Asn1Set values) + { + this.values = values; + } + + public static Rdn GetInstance(object obj) + { + if (obj is Rdn) + return (Rdn)obj; + if (null != obj) + return new Rdn(Asn1Set.GetInstance(obj)); + return null; + } + + /** + * Create a single valued RDN. + * + * @param oid RDN type. + * @param value RDN value. + */ + public Rdn(DerObjectIdentifier oid, Asn1Encodable value) + { + this.values = new DerSet(new DerSequence(oid, value)); + } + + public Rdn(AttributeTypeAndValue attrTAndV) + { + this.values = new DerSet(attrTAndV); + } + + /** + * Create a multi-valued RDN. + * + * @param aAndVs attribute type/value pairs making up the RDN + */ + public Rdn(AttributeTypeAndValue[] aAndVs) + { + this.values = new DerSet(aAndVs); + } + + public virtual bool IsMultiValued + { + get { return this.values.Count > 1; } + } + + /** + * Return the number of AttributeTypeAndValue objects in this RDN, + * + * @return size of RDN, greater than 1 if multi-valued. + */ + public virtual int Count + { + get { return this.values.Count; } + } + + public virtual AttributeTypeAndValue GetFirst() + { + if (this.values.Count == 0) + return null; + + return AttributeTypeAndValue.GetInstance(this.values[0]); + } + + public virtual AttributeTypeAndValue[] GetTypesAndValues() + { + AttributeTypeAndValue[] tmp = new AttributeTypeAndValue[values.Count]; + + for (int i = 0; i < tmp.Length; ++i) + { + tmp[i] = AttributeTypeAndValue.GetInstance(values[i]); + } + + return tmp; + } + + /** + *
+         * RelativeDistinguishedName ::=
+         *                     SET OF AttributeTypeAndValue
+
+         * AttributeTypeAndValue ::= SEQUENCE {
+         *        type     AttributeType,
+         *        value    AttributeValue }
+         * 
+ * @return this object as its ASN1Primitive type + */ + public override Asn1Object ToAsn1Object() + { + return values; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x500/Rdn.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x500/Rdn.cs.meta new file mode 100644 index 0000000..106d2fa --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x500/Rdn.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c35c5c0bc8a28324c8977cdd5fecd8aa +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x500/style.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x500/style.meta new file mode 100644 index 0000000..8cc56c2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x500/style.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7aa953408e1b0104dab8dbdd97badd6a +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x500/style/IetfUtilities.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x500/style/IetfUtilities.cs new file mode 100644 index 0000000..53e5fcc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x500/style/IetfUtilities.cs @@ -0,0 +1,214 @@ +using System; +using System.Collections; +using System.IO; +using System.Text; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Asn1.X500.Style +{ + public abstract class IetfUtilities + { + public static string ValueToString(Asn1Encodable value) + { + StringBuilder vBuf = new StringBuilder(); + + if (value is IAsn1String && !(value is DerUniversalString)) + { + string v = ((IAsn1String)value).GetString(); + if (v.Length > 0 && v[0] == '#') + { + vBuf.Append('\\'); + } + + vBuf.Append(v); + } + else + { + try + { + vBuf.Append('#'); + vBuf.Append(Hex.ToHexString(value.ToAsn1Object().GetEncoded(Asn1Encodable.Der))); + } + catch (IOException e) + { + throw new ArgumentException("Other value has no encoded form", e); + } + } + + int end = vBuf.Length; + int index = 0; + + if (vBuf.Length >= 2 && vBuf[0] == '\\' && vBuf[1] == '#') + { + index += 2; + } + + while (index != end) + { + switch (vBuf[index]) + { + case ',': + case '"': + case '\\': + case '+': + case '=': + case '<': + case '>': + case ';': + { + vBuf.Insert(index, "\\"); + index += 2; + ++end; + break; + } + default: + { + ++index; + break; + } + } + } + + int start = 0; + if (vBuf.Length > 0) + { + while (vBuf.Length > start && vBuf[start] == ' ') + { + vBuf.Insert(start, "\\"); + start += 2; + } + } + + int endBuf = vBuf.Length - 1; + + while (endBuf >= 0 && vBuf[endBuf] == ' ') + { + vBuf.Insert(endBuf, "\\"); + endBuf--; + } + + return vBuf.ToString(); + } + + public static string Canonicalize(string s) + { + string value = Platform.ToLowerInvariant(s); + + if (value.Length > 0 && value[0] == '#') + { + Asn1Object obj = DecodeObject(value); + + if (obj is IAsn1String) + { + value = Platform.ToLowerInvariant(((IAsn1String)obj).GetString()); + } + } + + if (value.Length > 1) + { + int start = 0; + while (start + 1 < value.Length && value[start] == '\\' && value[start + 1] == ' ') + { + start += 2; + } + + int end = value.Length - 1; + while (end - 1 > 0 && value[end - 1] == '\\' && value[end] == ' ') + { + end -= 2; + } + + if (start > 0 || end < value.Length - 1) + { + value = value.Substring(start, end + 1 - start); + } + } + + return StripInternalSpaces(value); + } + + public static string CanonicalString(Asn1Encodable value) + { + return Canonicalize(ValueToString(value)); + } + + private static Asn1Object DecodeObject(string oValue) + { + try + { + return Asn1Object.FromByteArray(Hex.DecodeStrict(oValue, 1, oValue.Length - 1)); + } + catch (IOException e) + { + throw new InvalidOperationException("unknown encoding in name: " + e); + } + } + + public static string StripInternalSpaces(string str) + { + if (str.IndexOf(" ") < 0) + return str; + + StringBuilder res = new StringBuilder(); + + char c1 = str[0]; + res.Append(c1); + + for (int k = 1; k < str.Length; k++) + { + char c2 = str[k]; + if (!(' ' == c1 && ' ' == c2)) + { + res.Append(c2); + c1 = c2; + } + } + + return res.ToString(); + } + + public static bool RdnAreEqual(Rdn rdn1, Rdn rdn2) + { + if (rdn1.Count != rdn2.Count) + return false; + + AttributeTypeAndValue[] atvs1 = rdn1.GetTypesAndValues(); + AttributeTypeAndValue[] atvs2 = rdn2.GetTypesAndValues(); + + if (atvs1.Length != atvs2.Length) + return false; + + for (int i = 0; i != atvs1.Length; i++) + { + if (!AtvAreEqual(atvs1[i], atvs2[i])) + return false; + } + + return true; + } + + private static bool AtvAreEqual(AttributeTypeAndValue atv1, AttributeTypeAndValue atv2) + { + if (atv1 == atv2) + return true; + if (null == atv1 || null == atv2) + return false; + + DerObjectIdentifier o1 = atv1.Type; + DerObjectIdentifier o2 = atv2.Type; + + if (!o1.Equals(o2)) + return false; + + string v1 = CanonicalString(atv1.Value); + string v2 = CanonicalString(atv2.Value); + + if (!v1.Equals(v2)) + return false; + + return true; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x500/style/IetfUtilities.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x500/style/IetfUtilities.cs.meta new file mode 100644 index 0000000..cf8469c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x500/style/IetfUtilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 77d15165eee90bd45bacb2d03235776e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509.meta new file mode 100644 index 0000000..4b2a09d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 8cb8a067cb7597e499a9e6566ff5a82a +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AccessDescription.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AccessDescription.cs new file mode 100644 index 0000000..47374be --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AccessDescription.cs @@ -0,0 +1,85 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * The AccessDescription object. + *
+	 * AccessDescription  ::=  SEQUENCE {
+	 *       accessMethod          OBJECT IDENTIFIER,
+	 *       accessLocation        GeneralName  }
+	 * 
+ */ + public class AccessDescription + : Asn1Encodable + { + public readonly static DerObjectIdentifier IdADCAIssuers = new DerObjectIdentifier("1.3.6.1.5.5.7.48.2"); + public readonly static DerObjectIdentifier IdADOcsp = new DerObjectIdentifier("1.3.6.1.5.5.7.48.1"); + + private readonly DerObjectIdentifier accessMethod; + private readonly GeneralName accessLocation; + + public static AccessDescription GetInstance( + object obj) + { + if (obj is AccessDescription) + return (AccessDescription) obj; + + if (obj is Asn1Sequence) + return new AccessDescription((Asn1Sequence) obj); + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + private AccessDescription( + Asn1Sequence seq) + { + if (seq.Count != 2) + throw new ArgumentException("wrong number of elements in sequence"); + + accessMethod = DerObjectIdentifier.GetInstance(seq[0]); + accessLocation = GeneralName.GetInstance(seq[1]); + } + + /** + * create an AccessDescription with the oid and location provided. + */ + public AccessDescription( + DerObjectIdentifier oid, + GeneralName location) + { + accessMethod = oid; + accessLocation = location; + } + + /** + * + * @return the access method. + */ + public DerObjectIdentifier AccessMethod + { + get { return accessMethod; } + } + + /** + * + * @return the access location + */ + public GeneralName AccessLocation + { + get { return accessLocation; } + } + + public override Asn1Object ToAsn1Object() + { + return new DerSequence(accessMethod, accessLocation); + } + + public override string ToString() + { + return "AccessDescription: Oid(" + this.accessMethod.Id + ")"; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AccessDescription.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AccessDescription.cs.meta new file mode 100644 index 0000000..b7c29c6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AccessDescription.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e29747a9892b8d844b497014b5565459 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AlgorithmIdentifier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AlgorithmIdentifier.cs new file mode 100644 index 0000000..00e7ad8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AlgorithmIdentifier.cs @@ -0,0 +1,96 @@ +using System; + +namespace Org.BouncyCastle.Asn1.X509 +{ + public class AlgorithmIdentifier + : Asn1Encodable + { + private readonly DerObjectIdentifier algorithm; + private readonly Asn1Encodable parameters; + + public static AlgorithmIdentifier GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static AlgorithmIdentifier GetInstance( + object obj) + { + if (obj == null) + return null; + if (obj is AlgorithmIdentifier) + return (AlgorithmIdentifier)obj; + return new AlgorithmIdentifier(Asn1Sequence.GetInstance(obj)); + } + + public AlgorithmIdentifier( + DerObjectIdentifier algorithm) + { + this.algorithm = algorithm; + } + + [Obsolete("Use version taking a DerObjectIdentifier")] + public AlgorithmIdentifier( + string algorithm) + { + this.algorithm = new DerObjectIdentifier(algorithm); + } + + public AlgorithmIdentifier( + DerObjectIdentifier algorithm, + Asn1Encodable parameters) + { + this.algorithm = algorithm; + this.parameters = parameters; + } + + internal AlgorithmIdentifier( + Asn1Sequence seq) + { + if (seq.Count < 1 || seq.Count > 2) + throw new ArgumentException("Bad sequence size: " + seq.Count); + + this.algorithm = DerObjectIdentifier.GetInstance(seq[0]); + this.parameters = seq.Count < 2 ? null : seq[1]; + } + + /// + /// Return the OID in the Algorithm entry of this identifier. + /// + public virtual DerObjectIdentifier Algorithm + { + get { return algorithm; } + } + + [Obsolete("Use 'Algorithm' property instead")] + public virtual DerObjectIdentifier ObjectID + { + get { return algorithm; } + } + + /// + /// Return the parameters structure in the Parameters entry of this identifier. + /// + public virtual Asn1Encodable Parameters + { + get { return parameters; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         *      AlgorithmIdentifier ::= Sequence {
+         *                            algorithm OBJECT IDENTIFIER,
+         *                            parameters ANY DEFINED BY algorithm OPTIONAL }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(algorithm); + v.AddOptional(parameters); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AlgorithmIdentifier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AlgorithmIdentifier.cs.meta new file mode 100644 index 0000000..aa95f4d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AlgorithmIdentifier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 29039b2b36673954c9030ee96e5d02ed +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AttCertIssuer.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AttCertIssuer.cs new file mode 100644 index 0000000..407c4ae --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AttCertIssuer.cs @@ -0,0 +1,86 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X509 +{ + public class AttCertIssuer + : Asn1Encodable, IAsn1Choice + { + internal readonly Asn1Encodable obj; + internal readonly Asn1Object choiceObj; + + public static AttCertIssuer GetInstance( + object obj) + { + if (obj is AttCertIssuer) + { + return (AttCertIssuer)obj; + } + else if (obj is V2Form) + { + return new AttCertIssuer(V2Form.GetInstance(obj)); + } + else if (obj is GeneralNames) + { + return new AttCertIssuer((GeneralNames)obj); + } + else if (obj is Asn1TaggedObject) + { + return new AttCertIssuer(V2Form.GetInstance((Asn1TaggedObject)obj, false)); + } + else if (obj is Asn1Sequence) + { + return new AttCertIssuer(GeneralNames.GetInstance(obj)); + } + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + public static AttCertIssuer GetInstance( + Asn1TaggedObject obj, + bool isExplicit) + { + return GetInstance(obj.GetObject()); // must be explictly tagged + } + + /// + /// Don't use this one if you are trying to be RFC 3281 compliant. + /// Use it for v1 attribute certificates only. + /// + /// Our GeneralNames structure + public AttCertIssuer( + GeneralNames names) + { + obj = names; + choiceObj = obj.ToAsn1Object(); + } + + public AttCertIssuer( + V2Form v2Form) + { + obj = v2Form; + choiceObj = new DerTaggedObject(false, 0, obj); + } + + public Asn1Encodable Issuer + { + get { return obj; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         *  AttCertIssuer ::= CHOICE {
+         *       v1Form   GeneralNames,  -- MUST NOT be used in this
+         *                               -- profile
+         *       v2Form   [0] V2Form     -- v2 only
+         *  }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + return choiceObj; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AttCertIssuer.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AttCertIssuer.cs.meta new file mode 100644 index 0000000..567dc1b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AttCertIssuer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e3d8399518a5e964aba5bacba9ab5045 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AttCertValidityPeriod.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AttCertValidityPeriod.cs new file mode 100644 index 0000000..d31e074 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AttCertValidityPeriod.cs @@ -0,0 +1,78 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X509 +{ + public class AttCertValidityPeriod + : Asn1Encodable + { + private readonly DerGeneralizedTime notBeforeTime; + private readonly DerGeneralizedTime notAfterTime; + + public static AttCertValidityPeriod GetInstance( + object obj) + { + if (obj is AttCertValidityPeriod || obj == null) + { + return (AttCertValidityPeriod) obj; + } + + if (obj is Asn1Sequence) + { + return new AttCertValidityPeriod((Asn1Sequence) obj); + } + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + public static AttCertValidityPeriod GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + private AttCertValidityPeriod( + Asn1Sequence seq) + { + if (seq.Count != 2) + throw new ArgumentException("Bad sequence size: " + seq.Count); + + notBeforeTime = DerGeneralizedTime.GetInstance(seq[0]); + notAfterTime = DerGeneralizedTime.GetInstance(seq[1]); + } + + public AttCertValidityPeriod( + DerGeneralizedTime notBeforeTime, + DerGeneralizedTime notAfterTime) + { + this.notBeforeTime = notBeforeTime; + this.notAfterTime = notAfterTime; + } + + public DerGeneralizedTime NotBeforeTime + { + get { return notBeforeTime; } + } + + public DerGeneralizedTime NotAfterTime + { + get { return notAfterTime; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         *  AttCertValidityPeriod  ::= Sequence {
+         *       notBeforeTime  GeneralizedTime,
+         *       notAfterTime   GeneralizedTime
+         *  }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + return new DerSequence(notBeforeTime, notAfterTime); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AttCertValidityPeriod.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AttCertValidityPeriod.cs.meta new file mode 100644 index 0000000..e4e2f49 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AttCertValidityPeriod.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 13d4d0f2fc0b7d84aa29f4c1767444e5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/Attribute.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/Attribute.cs new file mode 100644 index 0000000..da59b42 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/Attribute.cs @@ -0,0 +1,82 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X509 +{ + public class AttributeX509 + : Asn1Encodable + { + private readonly DerObjectIdentifier attrType; + private readonly Asn1Set attrValues; + + /** + * return an Attr object from the given object. + * + * @param o the object we want converted. + * @exception ArgumentException if the object cannot be converted. + */ + public static AttributeX509 GetInstance( + object obj) + { + if (obj == null || obj is AttributeX509) + { + return (AttributeX509) obj; + } + + if (obj is Asn1Sequence) + { + return new AttributeX509((Asn1Sequence) obj); + } + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + private AttributeX509( + Asn1Sequence seq) + { + if (seq.Count != 2) + throw new ArgumentException("Bad sequence size: " + seq.Count); + + attrType = DerObjectIdentifier.GetInstance(seq[0]); + attrValues = Asn1Set.GetInstance(seq[1]); + } + + public AttributeX509( + DerObjectIdentifier attrType, + Asn1Set attrValues) + { + this.attrType = attrType; + this.attrValues = attrValues; + } + + public DerObjectIdentifier AttrType + { + get { return attrType; } + } + + public Asn1Encodable[] GetAttributeValues() + { + return attrValues.ToArray(); + } + + public Asn1Set AttrValues + { + get { return attrValues; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * Attr ::= Sequence {
+         *     attrType OBJECT IDENTIFIER,
+         *     attrValues Set OF AttributeValue
+         * }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + return new DerSequence(attrType, attrValues); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/Attribute.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/Attribute.cs.meta new file mode 100644 index 0000000..e8d585a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/Attribute.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e54ccf665a1aa164e98632bf47d3c02a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AttributeCertificate.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AttributeCertificate.cs new file mode 100644 index 0000000..41893b6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AttributeCertificate.cs @@ -0,0 +1,86 @@ +using System; + +using Org.BouncyCastle.Asn1; + +namespace Org.BouncyCastle.Asn1.X509 +{ + public class AttributeCertificate + : Asn1Encodable + { + private readonly AttributeCertificateInfo acinfo; + private readonly AlgorithmIdentifier signatureAlgorithm; + private readonly DerBitString signatureValue; + + /** + * @param obj + * @return + */ + public static AttributeCertificate GetInstance( + object obj) + { + if (obj is AttributeCertificate) + return (AttributeCertificate) obj; + + if (obj != null) + return new AttributeCertificate(Asn1Sequence.GetInstance(obj)); + + return null; + } + + public AttributeCertificate( + AttributeCertificateInfo acinfo, + AlgorithmIdentifier signatureAlgorithm, + DerBitString signatureValue) + { + this.acinfo = acinfo; + this.signatureAlgorithm = signatureAlgorithm; + this.signatureValue = signatureValue; + } + + private AttributeCertificate( + Asn1Sequence seq) + { + if (seq.Count != 3) + throw new ArgumentException("Bad sequence size: " + seq.Count); + + this.acinfo = AttributeCertificateInfo.GetInstance(seq[0]); + this.signatureAlgorithm = AlgorithmIdentifier.GetInstance(seq[1]); + this.signatureValue = DerBitString.GetInstance(seq[2]); + } + + public AttributeCertificateInfo ACInfo + { + get { return acinfo; } + } + + public AlgorithmIdentifier SignatureAlgorithm + { + get { return signatureAlgorithm; } + } + + public DerBitString SignatureValue + { + get { return signatureValue; } + } + + public byte[] GetSignatureOctets() + { + return signatureValue.GetOctets(); + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         *  AttributeCertificate ::= Sequence {
+         *       acinfo               AttributeCertificateInfo,
+         *       signatureAlgorithm   AlgorithmIdentifier,
+         *       signatureValue       BIT STRING
+         *  }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + return new DerSequence(acinfo, signatureAlgorithm, signatureValue); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AttributeCertificate.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AttributeCertificate.cs.meta new file mode 100644 index 0000000..54367f7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AttributeCertificate.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e745f6ca08e32e141b7c7bbeb78cd4ba +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AttributeCertificateInfo.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AttributeCertificateInfo.cs new file mode 100644 index 0000000..d466bbd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AttributeCertificateInfo.cs @@ -0,0 +1,163 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X509 +{ + public class AttributeCertificateInfo + : Asn1Encodable + { + internal readonly DerInteger version; + internal readonly Holder holder; + internal readonly AttCertIssuer issuer; + internal readonly AlgorithmIdentifier signature; + internal readonly DerInteger serialNumber; + internal readonly AttCertValidityPeriod attrCertValidityPeriod; + internal readonly Asn1Sequence attributes; + internal readonly DerBitString issuerUniqueID; + internal readonly X509Extensions extensions; + + public static AttributeCertificateInfo GetInstance( + Asn1TaggedObject obj, + bool isExplicit) + { + return GetInstance(Asn1Sequence.GetInstance(obj, isExplicit)); + } + + public static AttributeCertificateInfo GetInstance( + object obj) + { + if (obj is AttributeCertificateInfo) + { + return (AttributeCertificateInfo) obj; + } + + if (obj is Asn1Sequence) + { + return new AttributeCertificateInfo((Asn1Sequence) obj); + } + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + private AttributeCertificateInfo( + Asn1Sequence seq) + { + if (seq.Count < 6 || seq.Count > 9) + { + throw new ArgumentException("Bad sequence size: " + seq.Count); + } + + int start; + if (seq[0] is DerInteger) // in version 1 certs version is DEFAULT v1(0) + { + this.version = DerInteger.GetInstance(seq[0]); + start = 1; + } + else + { + this.version = new DerInteger(0); + start = 0; + } + + this.holder = Holder.GetInstance(seq[start]); + this.issuer = AttCertIssuer.GetInstance(seq[start + 1]); + this.signature = AlgorithmIdentifier.GetInstance(seq[start + 2]); + this.serialNumber = DerInteger.GetInstance(seq[start + 3]); + this.attrCertValidityPeriod = AttCertValidityPeriod.GetInstance(seq[start + 4]); + this.attributes = Asn1Sequence.GetInstance(seq[start + 5]); + + for (int i = start + 6; i < seq.Count; i++) + { + Asn1Encodable obj = (Asn1Encodable) seq[i]; + + if (obj is DerBitString) + { + this.issuerUniqueID = DerBitString.GetInstance(seq[i]); + } + else if (obj is Asn1Sequence || obj is X509Extensions) + { + this.extensions = X509Extensions.GetInstance(seq[i]); + } + } + } + + public DerInteger Version + { + get { return version; } + } + + public Holder Holder + { + get { return holder; } + } + + public AttCertIssuer Issuer + { + get { return issuer; } + } + + public AlgorithmIdentifier Signature + { + get { return signature; } + } + + public DerInteger SerialNumber + { + get { return serialNumber; } + } + + public AttCertValidityPeriod AttrCertValidityPeriod + { + get { return attrCertValidityPeriod; } + } + + public Asn1Sequence Attributes + { + get { return attributes; } + } + + public DerBitString IssuerUniqueID + { + get { return issuerUniqueID; } + } + + public X509Extensions Extensions + { + get { return extensions; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         *  AttributeCertificateInfo ::= Sequence {
+         *       version              AttCertVersion -- version is v2,
+         *       holder               Holder,
+         *       issuer               AttCertIssuer,
+         *       signature            AlgorithmIdentifier,
+         *       serialNumber         CertificateSerialNumber,
+         *       attrCertValidityPeriod   AttCertValidityPeriod,
+         *       attributes           Sequence OF Attr,
+         *       issuerUniqueID       UniqueIdentifier OPTIONAL,
+         *       extensions           Extensions OPTIONAL
+         *  }
+         *
+         *  AttCertVersion ::= Integer { v2(1) }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(9); + + if (!version.HasValue(0)) + { + v.Add(version); + } + + v.Add(holder, issuer, signature, serialNumber, attrCertValidityPeriod, attributes); + v.AddOptional(issuerUniqueID, extensions); + + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AttributeCertificateInfo.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AttributeCertificateInfo.cs.meta new file mode 100644 index 0000000..a8fdb9d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AttributeCertificateInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7fbe1fdee4083d145aacc8cbc5e3f2b7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AttributeTable.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AttributeTable.cs new file mode 100644 index 0000000..33faad6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AttributeTable.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X509 +{ + public class AttributeTable + { + private readonly IDictionary attributes; + + public AttributeTable( + IDictionary attrs) + { + this.attributes = Platform.CreateHashtable(attrs); + } + +#if !(SILVERLIGHT || PORTABLE) + [Obsolete] + public AttributeTable( + Hashtable attrs) + { + this.attributes = Platform.CreateHashtable(attrs); + } +#endif + + public AttributeTable( + Asn1EncodableVector v) + { + this.attributes = Platform.CreateHashtable(v.Count); + + for (int i = 0; i != v.Count; i++) + { + AttributeX509 a = AttributeX509.GetInstance(v[i]); + + attributes.Add(a.AttrType, a); + } + } + + public AttributeTable( + Asn1Set s) + { + this.attributes = Platform.CreateHashtable(s.Count); + + for (int i = 0; i != s.Count; i++) + { + AttributeX509 a = AttributeX509.GetInstance(s[i]); + + attributes.Add(a.AttrType, a); + } + } + + public AttributeX509 Get( + DerObjectIdentifier oid) + { + return (AttributeX509) attributes[oid]; + } + +#if !(SILVERLIGHT || PORTABLE) + [Obsolete("Use 'ToDictionary' instead")] + public Hashtable ToHashtable() + { + return new Hashtable(attributes); + } +#endif + + public IDictionary ToDictionary() + { + return Platform.CreateHashtable(attributes); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AttributeTable.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AttributeTable.cs.meta new file mode 100644 index 0000000..9362042 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AttributeTable.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3bdc7e0813789c1478b8dea4b499e1d7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AuthorityInformationAccess.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AuthorityInformationAccess.cs new file mode 100644 index 0000000..f4b694c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AuthorityInformationAccess.cs @@ -0,0 +1,114 @@ +using System; +using System.Collections; +using System.Text; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * The AuthorityInformationAccess object. + *
+     * id-pe-authorityInfoAccess OBJECT IDENTIFIER ::= { id-pe 1 }
+     *
+     * AuthorityInfoAccessSyntax  ::=
+     *      Sequence SIZE (1..MAX) OF AccessDescription
+     * AccessDescription  ::=  Sequence {
+     *       accessMethod          OBJECT IDENTIFIER,
+     *       accessLocation        GeneralName  }
+     *
+     * id-ad OBJECT IDENTIFIER ::= { id-pkix 48 }
+     * id-ad-caIssuers OBJECT IDENTIFIER ::= { id-ad 2 }
+     * id-ad-ocsp OBJECT IDENTIFIER ::= { id-ad 1 }
+     * 
+ */ + public class AuthorityInformationAccess + : Asn1Encodable + { + private static AccessDescription[] Copy(AccessDescription[] descriptions) + { + return (AccessDescription[])descriptions.Clone(); + } + + public static AuthorityInformationAccess GetInstance(object obj) + { + if (obj is AuthorityInformationAccess) + return (AuthorityInformationAccess)obj; + if (obj == null) + return null; + return new AuthorityInformationAccess(Asn1Sequence.GetInstance(obj)); + } + + public static AuthorityInformationAccess FromExtensions(X509Extensions extensions) + { + return GetInstance(X509Extensions.GetExtensionParsedValue(extensions, X509Extensions.AuthorityInfoAccess)); + } + + private readonly AccessDescription[] descriptions; + + private AuthorityInformationAccess( + Asn1Sequence seq) + { + if (seq.Count < 1) + throw new ArgumentException("sequence may not be empty"); + + this.descriptions = new AccessDescription[seq.Count]; + + for (int i = 0; i < seq.Count; ++i) + { + descriptions[i] = AccessDescription.GetInstance(seq[i]); + } + } + + public AuthorityInformationAccess( + AccessDescription description) + { + this.descriptions = new AccessDescription[]{ description }; + } + + public AuthorityInformationAccess( + AccessDescription[] descriptions) + { + this.descriptions = Copy(descriptions); + } + + /** + * create an AuthorityInformationAccess with the oid and location provided. + */ + public AuthorityInformationAccess(DerObjectIdentifier oid, GeneralName location) + : this(new AccessDescription(oid, location)) + { + } + + public AccessDescription[] GetAccessDescriptions() + { + return Copy(descriptions); + } + + public override Asn1Object ToAsn1Object() + { + return new DerSequence(descriptions); + } + + public override string ToString() + { + //return "AuthorityInformationAccess: Oid(" + this.descriptions[0].AccessMethod.Id + ")"; + + StringBuilder buf = new StringBuilder(); + string sep = Platform.NewLine; + + buf.Append("AuthorityInformationAccess:"); + buf.Append(sep); + + foreach (AccessDescription description in descriptions) + { + buf.Append(" "); + buf.Append(description); + buf.Append(sep); + } + + return buf.ToString(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AuthorityInformationAccess.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AuthorityInformationAccess.cs.meta new file mode 100644 index 0000000..120711f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AuthorityInformationAccess.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ce2a057c84b680f4297c64b992114c7b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AuthorityKeyIdentifier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AuthorityKeyIdentifier.cs new file mode 100644 index 0000000..e7f1201 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AuthorityKeyIdentifier.cs @@ -0,0 +1,185 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * The AuthorityKeyIdentifier object. + *
+     * id-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::=  { id-ce 35 }
+     *
+     *   AuthorityKeyIdentifier ::= Sequence {
+     *      keyIdentifier             [0] IMPLICIT KeyIdentifier           OPTIONAL,
+     *      authorityCertIssuer       [1] IMPLICIT GeneralNames            OPTIONAL,
+     *      authorityCertSerialNumber [2] IMPLICIT CertificateSerialNumber OPTIONAL  }
+     *
+     *   KeyIdentifier ::= OCTET STRING
+     * 
+ * + */ + public class AuthorityKeyIdentifier + : Asn1Encodable + { + public static AuthorityKeyIdentifier GetInstance(Asn1TaggedObject obj, bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static AuthorityKeyIdentifier GetInstance(object obj) + { + if (obj is AuthorityKeyIdentifier) + return (AuthorityKeyIdentifier)obj; + if (obj is X509Extension) + return GetInstance(X509Extension.ConvertValueToObject((X509Extension)obj)); + if (obj == null) + return null; + return new AuthorityKeyIdentifier(Asn1Sequence.GetInstance(obj)); + } + + public static AuthorityKeyIdentifier FromExtensions(X509Extensions extensions) + { + return GetInstance(X509Extensions.GetExtensionParsedValue(extensions, X509Extensions.AuthorityKeyIdentifier)); + } + + private readonly Asn1OctetString keyidentifier; + private readonly GeneralNames certissuer; + private readonly DerInteger certserno; + + protected internal AuthorityKeyIdentifier( + Asn1Sequence seq) + { + foreach (Asn1Encodable element in seq) + { + Asn1TaggedObject obj = Asn1TaggedObject.GetInstance(element); + + switch (obj.TagNo) + { + case 0: + this.keyidentifier = Asn1OctetString.GetInstance(obj, false); + break; + case 1: + this.certissuer = GeneralNames.GetInstance(obj, false); + break; + case 2: + this.certserno = DerInteger.GetInstance(obj, false); + break; + default: + throw new ArgumentException("illegal tag"); + } + } + } + + /** + * + * Calulates the keyidentifier using a SHA1 hash over the BIT STRING + * from SubjectPublicKeyInfo as defined in RFC2459. + * + * Example of making a AuthorityKeyIdentifier: + *
+	     *   SubjectPublicKeyInfo apki = new SubjectPublicKeyInfo((ASN1Sequence)new ASN1InputStream(
+		 *       publicKey.getEncoded()).readObject());
+         *   AuthorityKeyIdentifier aki = new AuthorityKeyIdentifier(apki);
+         * 
+ * + **/ + public AuthorityKeyIdentifier( + SubjectPublicKeyInfo spki) + : this(spki, null, null) + { + } + + /** + * create an AuthorityKeyIdentifier with the GeneralNames tag and + * the serial number provided as well. + */ + public AuthorityKeyIdentifier( + SubjectPublicKeyInfo spki, + GeneralNames name, + BigInteger serialNumber) + { + IDigest digest = new Sha1Digest(); + byte[] resBuf = new byte[digest.GetDigestSize()]; + byte[] bytes = spki.PublicKeyData.GetBytes(); + digest.BlockUpdate(bytes, 0, bytes.Length); + digest.DoFinal(resBuf, 0); + + this.keyidentifier = new DerOctetString(resBuf); + this.certissuer = name; + this.certserno = serialNumber == null ? null : new DerInteger(serialNumber); + } + + /** + * create an AuthorityKeyIdentifier with the GeneralNames tag and + * the serial number provided. + */ + public AuthorityKeyIdentifier( + GeneralNames name, + BigInteger serialNumber) + : this((byte[])null, name, serialNumber) + { + } + + /** + * create an AuthorityKeyIdentifier with a precomputed key identifier + */ + public AuthorityKeyIdentifier( + byte[] keyIdentifier) + : this(keyIdentifier, null, null) + { + } + + /** + * create an AuthorityKeyIdentifier with a precomupted key identifier + * and the GeneralNames tag and the serial number provided as well. + */ + public AuthorityKeyIdentifier( + byte[] keyIdentifier, + GeneralNames name, + BigInteger serialNumber) + { + this.keyidentifier = keyIdentifier == null ? null : new DerOctetString(keyIdentifier); + this.certissuer = name; + this.certserno = serialNumber == null ? null : new DerInteger(serialNumber); + } + + public byte[] GetKeyIdentifier() + { + return keyidentifier == null ? null : keyidentifier.GetOctets(); + } + + public GeneralNames AuthorityCertIssuer + { + get { return certissuer; } + } + + public BigInteger AuthorityCertSerialNumber + { + get { return certserno == null ? null : certserno.Value; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + v.AddOptionalTagged(false, 0, keyidentifier); + v.AddOptionalTagged(false, 1, certissuer); + v.AddOptionalTagged(false, 2, certserno); + return new DerSequence(v); + } + + public override string ToString() + { + string keyID = (keyidentifier != null) ? Hex.ToHexString(keyidentifier.GetOctets()) : "null"; + + return "AuthorityKeyIdentifier: KeyID(" + keyID + ")"; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AuthorityKeyIdentifier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AuthorityKeyIdentifier.cs.meta new file mode 100644 index 0000000..72a167b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/AuthorityKeyIdentifier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ac18f504c048bb245abd21b5aacd7f31 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/BasicConstraints.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/BasicConstraints.cs new file mode 100644 index 0000000..deecae2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/BasicConstraints.cs @@ -0,0 +1,117 @@ +using System; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X509 +{ + public class BasicConstraints + : Asn1Encodable + { + public static BasicConstraints GetInstance(Asn1TaggedObject obj, bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static BasicConstraints GetInstance(object obj) + { + if (obj is BasicConstraints) + return (BasicConstraints)obj; + if (obj is X509Extension) + return GetInstance(X509Extension.ConvertValueToObject((X509Extension)obj)); + if (obj == null) + return null; + return new BasicConstraints(Asn1Sequence.GetInstance(obj)); + } + + public static BasicConstraints FromExtensions(X509Extensions extensions) + { + return GetInstance(X509Extensions.GetExtensionParsedValue(extensions, X509Extensions.BasicConstraints)); + } + + private readonly DerBoolean cA; + private readonly DerInteger pathLenConstraint; + + private BasicConstraints( + Asn1Sequence seq) + { + if (seq.Count > 0) + { + if (seq[0] is DerBoolean) + { + this.cA = DerBoolean.GetInstance(seq[0]); + } + else + { + this.pathLenConstraint = DerInteger.GetInstance(seq[0]); + } + + if (seq.Count > 1) + { + if (this.cA == null) + throw new ArgumentException("wrong sequence in constructor", "seq"); + + this.pathLenConstraint = DerInteger.GetInstance(seq[1]); + } + } + } + + public BasicConstraints( + bool cA) + { + if (cA) + { + this.cA = DerBoolean.True; + } + } + + /** + * create a cA=true object for the given path length constraint. + * + * @param pathLenConstraint + */ + public BasicConstraints( + int pathLenConstraint) + { + this.cA = DerBoolean.True; + this.pathLenConstraint = new DerInteger(pathLenConstraint); + } + + public bool IsCA() + { + return cA != null && cA.IsTrue; + } + + public BigInteger PathLenConstraint + { + get { return pathLenConstraint == null ? null : pathLenConstraint.Value; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * BasicConstraints := Sequence {
+         *    cA                  Boolean DEFAULT FALSE,
+         *    pathLenConstraint   Integer (0..MAX) OPTIONAL
+         * }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(2); + v.AddOptional(cA, + pathLenConstraint); // yes some people actually do this when cA is false... + return new DerSequence(v); + } + + public override string ToString() + { + if (pathLenConstraint == null) + { + return "BasicConstraints: isCa(" + this.IsCA() + ")"; + } + + return "BasicConstraints: isCa(" + this.IsCA() + "), pathLenConstraint = " + pathLenConstraint.Value; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/BasicConstraints.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/BasicConstraints.cs.meta new file mode 100644 index 0000000..9b9967f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/BasicConstraints.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 81ba994220a5f03498906c305e7a3d1a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/CRLDistPoint.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/CRLDistPoint.cs new file mode 100644 index 0000000..446bb19 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/CRLDistPoint.cs @@ -0,0 +1,89 @@ +using System; +using System.Text; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X509 +{ + public class CrlDistPoint + : Asn1Encodable + { + public static CrlDistPoint GetInstance(Asn1TaggedObject obj, bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static CrlDistPoint GetInstance(object obj) + { + if (obj is CrlDistPoint) + return (CrlDistPoint)obj; + if (obj == null) + return null; + return new CrlDistPoint(Asn1Sequence.GetInstance(obj)); + } + + public static CrlDistPoint FromExtensions(X509Extensions extensions) + { + return GetInstance(X509Extensions.GetExtensionParsedValue(extensions, X509Extensions.CrlDistributionPoints)); + } + + internal readonly Asn1Sequence seq; + + private CrlDistPoint( + Asn1Sequence seq) + { + this.seq = seq; + } + + public CrlDistPoint( + DistributionPoint[] points) + { + seq = new DerSequence(points); + } + + /** + * Return the distribution points making up the sequence. + * + * @return DistributionPoint[] + */ + public DistributionPoint[] GetDistributionPoints() + { + DistributionPoint[] dp = new DistributionPoint[seq.Count]; + + for (int i = 0; i != seq.Count; ++i) + { + dp[i] = DistributionPoint.GetInstance(seq[i]); + } + + return dp; + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * CrlDistPoint ::= Sequence SIZE {1..MAX} OF DistributionPoint
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + return seq; + } + + public override string ToString() + { + StringBuilder buf = new StringBuilder(); + string sep = Platform.NewLine; + + buf.Append("CRLDistPoint:"); + buf.Append(sep); + DistributionPoint[] dp = GetDistributionPoints(); + for (int i = 0; i != dp.Length; i++) + { + buf.Append(" "); + buf.Append(dp[i]); + buf.Append(sep); + } + return buf.ToString(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/CRLDistPoint.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/CRLDistPoint.cs.meta new file mode 100644 index 0000000..ee6b5de --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/CRLDistPoint.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7b8f7bc53bb3caf4c800df3d16fc14d5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/CRLNumber.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/CRLNumber.cs new file mode 100644 index 0000000..d744416 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/CRLNumber.cs @@ -0,0 +1,30 @@ +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * The CRLNumber object. + *
+     * CRLNumber::= Integer(0..MAX)
+     * 
+ */ + public class CrlNumber + : DerInteger + { + public CrlNumber( + BigInteger number) + : base(number) + { + } + + public BigInteger Number + { + get { return PositiveValue; } + } + + public override string ToString() + { + return "CRLNumber: " + Number; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/CRLNumber.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/CRLNumber.cs.meta new file mode 100644 index 0000000..c1e1427 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/CRLNumber.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e40fab408ae41bd48a4566fb5cb82691 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/CRLReason.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/CRLReason.cs new file mode 100644 index 0000000..050ceb3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/CRLReason.cs @@ -0,0 +1,60 @@ +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * The CRLReason enumeration. + *
+     * CRLReason ::= Enumerated {
+     *  unspecified             (0),
+     *  keyCompromise           (1),
+     *  cACompromise            (2),
+     *  affiliationChanged      (3),
+     *  superseded              (4),
+     *  cessationOfOperation    (5),
+     *  certificateHold         (6),
+     *  removeFromCRL           (8),
+     *  privilegeWithdrawn      (9),
+     *  aACompromise           (10)
+     * }
+     * 
+ */ + public class CrlReason + : DerEnumerated + { + public const int Unspecified = 0; + public const int KeyCompromise = 1; + public const int CACompromise = 2; + public const int AffiliationChanged = 3; + public const int Superseded = 4; + public const int CessationOfOperation = 5; + public const int CertificateHold = 6; + // 7 -> Unknown + public const int RemoveFromCrl = 8; + public const int PrivilegeWithdrawn = 9; + public const int AACompromise = 10; + + private static readonly string[] ReasonString = new string[] + { + "Unspecified", "KeyCompromise", "CACompromise", "AffiliationChanged", + "Superseded", "CessationOfOperation", "CertificateHold", "Unknown", + "RemoveFromCrl", "PrivilegeWithdrawn", "AACompromise" + }; + + public CrlReason( + int reason) + : base(reason) + { + } + + public CrlReason(DerEnumerated reason) + : base(reason.IntValueExact) + { + } + + public override string ToString() + { + int reason = IntValueExact; + string str = (reason < 0 || reason > 10) ? "Invalid" : ReasonString[reason]; + return "CrlReason: " + str; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/CRLReason.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/CRLReason.cs.meta new file mode 100644 index 0000000..944148a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/CRLReason.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7ff88d21bbef6dd4292f8467410e48a6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/CertPolicyId.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/CertPolicyId.cs new file mode 100644 index 0000000..11cebcd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/CertPolicyId.cs @@ -0,0 +1,20 @@ +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * CertPolicyId, used in the CertificatePolicies and PolicyMappings + * X509V3 Extensions. + * + *
+     *     CertPolicyId ::= OBJECT IDENTIFIER
+     * 
+ */ + public class CertPolicyID + : DerObjectIdentifier + { + public CertPolicyID( + string id) + : base(id) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/CertPolicyId.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/CertPolicyId.cs.meta new file mode 100644 index 0000000..4cb67ef --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/CertPolicyId.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 54945bfec699dbd4b9e03c5503019194 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/CertificateList.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/CertificateList.cs new file mode 100644 index 0000000..567cf13 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/CertificateList.cs @@ -0,0 +1,113 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * PKIX RFC-2459 + * + * The X.509 v2 CRL syntax is as follows. For signature calculation, + * the data that is to be signed is ASN.1 Der encoded. + * + *
+     * CertificateList  ::=  Sequence  {
+     *      tbsCertList          TbsCertList,
+     *      signatureAlgorithm   AlgorithmIdentifier,
+     *      signatureValue       BIT STRING  }
+     * 
+ */ + public class CertificateList + : Asn1Encodable + { + private readonly TbsCertificateList tbsCertList; + private readonly AlgorithmIdentifier sigAlgID; + private readonly DerBitString sig; + + public static CertificateList GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static CertificateList GetInstance( + object obj) + { + if (obj is CertificateList) + return (CertificateList) obj; + + if (obj != null) + return new CertificateList(Asn1Sequence.GetInstance(obj)); + + return null; + } + + private CertificateList( + Asn1Sequence seq) + { + if (seq.Count != 3) + throw new ArgumentException("sequence wrong size for CertificateList", "seq"); + + tbsCertList = TbsCertificateList.GetInstance(seq[0]); + sigAlgID = AlgorithmIdentifier.GetInstance(seq[1]); + sig = DerBitString.GetInstance(seq[2]); + } + + public TbsCertificateList TbsCertList + { + get { return tbsCertList; } + } + + public CrlEntry[] GetRevokedCertificates() + { + return tbsCertList.GetRevokedCertificates(); + } + + public IEnumerable GetRevokedCertificateEnumeration() + { + return tbsCertList.GetRevokedCertificateEnumeration(); + } + + public AlgorithmIdentifier SignatureAlgorithm + { + get { return sigAlgID; } + } + + public DerBitString Signature + { + get { return sig; } + } + + public byte[] GetSignatureOctets() + { + return sig.GetOctets(); + } + + public int Version + { + get { return tbsCertList.Version; } + } + + public X509Name Issuer + { + get { return tbsCertList.Issuer; } + } + + public Time ThisUpdate + { + get { return tbsCertList.ThisUpdate; } + } + + public Time NextUpdate + { + get { return tbsCertList.NextUpdate; } + } + + public override Asn1Object ToAsn1Object() + { + return new DerSequence(tbsCertList, sigAlgID, sig); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/CertificateList.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/CertificateList.cs.meta new file mode 100644 index 0000000..d9be8d6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/CertificateList.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3577acee1ce82fa4fb155d6357cfa347 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/CertificatePair.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/CertificatePair.cs new file mode 100644 index 0000000..69861e1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/CertificatePair.cs @@ -0,0 +1,153 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * This class helps to support crossCerfificatePairs in a LDAP directory + * according RFC 2587 + * + *
+	*     crossCertificatePairATTRIBUTE::={
+	*       WITH SYNTAX   CertificatePair
+	*       EQUALITY MATCHING RULE certificatePairExactMatch
+	*       ID joint-iso-ccitt(2) ds(5) attributeType(4) crossCertificatePair(40)}
+	* 
+ * + *
The forward elements of the crossCertificatePair attribute of a + * CA's directory entry shall be used to store all, except self-issued + * certificates issued to this CA. Optionally, the reverse elements of the + * crossCertificatePair attribute, of a CA's directory entry may contain a + * subset of certificates issued by this CA to other CAs. When both the forward + * and the reverse elements are present in a single attribute value, issuer name + * in one certificate shall match the subject name in the other and vice versa, + * and the subject public key in one certificate shall be capable of verifying + * the digital signature on the other certificate and vice versa. + * + * When a reverse element is present, the forward element value and the reverse + * element value need not be stored in the same attribute value; in other words, + * they can be stored in either a single attribute value or two attribute + * values.
+ * + *
+	*       CertificatePair ::= SEQUENCE {
+	*         forward		[0]	Certificate OPTIONAL,
+	*         reverse		[1]	Certificate OPTIONAL,
+	*         -- at least one of the pair shall be present -- }
+	* 
+ */ + public class CertificatePair + : Asn1Encodable + { + private X509CertificateStructure forward, reverse; + + public static CertificatePair GetInstance( + object obj) + { + if (obj == null || obj is CertificatePair) + { + return (CertificatePair) obj; + } + + if (obj is Asn1Sequence) + { + return new CertificatePair((Asn1Sequence) obj); + } + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + /** + * Constructor from Asn1Sequence. + *

+ * The sequence is of type CertificatePair: + *

+ *

+		*       CertificatePair ::= SEQUENCE {
+		*         forward		[0]	Certificate OPTIONAL,
+		*         reverse		[1]	Certificate OPTIONAL,
+		*         -- at least one of the pair shall be present -- }
+		* 
+ * + * @param seq The ASN.1 sequence. + */ + private CertificatePair( + Asn1Sequence seq) + { + if (seq.Count != 1 && seq.Count != 2) + { + throw new ArgumentException("Bad sequence size: " + seq.Count, "seq"); + } + + foreach (object obj in seq) + { + Asn1TaggedObject o = Asn1TaggedObject.GetInstance(obj); + if (o.TagNo == 0) + { + forward = X509CertificateStructure.GetInstance(o, true); + } + else if (o.TagNo == 1) + { + reverse = X509CertificateStructure.GetInstance(o, true); + } + else + { + throw new ArgumentException("Bad tag number: " + o.TagNo); + } + } + } + + /** + * Constructor from a given details. + * + * @param forward Certificates issued to this CA. + * @param reverse Certificates issued by this CA to other CAs. + */ + public CertificatePair( + X509CertificateStructure forward, + X509CertificateStructure reverse) + { + this.forward = forward; + this.reverse = reverse; + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *

+ * Returns: + *

+ *

+		*       CertificatePair ::= SEQUENCE {
+		*         forward		[0]	Certificate OPTIONAL,
+		*         reverse		[1]	Certificate OPTIONAL,
+		*         -- at least one of the pair shall be present -- }
+		* 
+ * + * @return a DERObject + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + v.AddOptionalTagged(true, 0, forward); + v.AddOptionalTagged(true, 1, reverse); + return new DerSequence(v); + } + + /** + * @return Returns the forward. + */ + public X509CertificateStructure Forward + { + get { return forward; } + } + + /** + * @return Returns the reverse. + */ + public X509CertificateStructure Reverse + { + get { return reverse; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/CertificatePair.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/CertificatePair.cs.meta new file mode 100644 index 0000000..07fce66 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/CertificatePair.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d7fbd72791d26714982b0a1efb9647b7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/CertificatePolicies.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/CertificatePolicies.cs new file mode 100644 index 0000000..97214bd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/CertificatePolicies.cs @@ -0,0 +1,105 @@ +using System; +using System.Text; + +namespace Org.BouncyCastle.Asn1.X509 +{ + public class CertificatePolicies + : Asn1Encodable + { + private static PolicyInformation[] Copy(PolicyInformation[] policyInfo) + { + return (PolicyInformation[])policyInfo.Clone(); + } + + public static CertificatePolicies GetInstance(object obj) + { + if (obj is CertificatePolicies) + return (CertificatePolicies)obj; + if (obj == null) + return null; + return new CertificatePolicies(Asn1Sequence.GetInstance(obj)); + } + + public static CertificatePolicies GetInstance(Asn1TaggedObject obj, bool isExplicit) + { + return GetInstance(Asn1Sequence.GetInstance(obj, isExplicit)); + } + + public static CertificatePolicies FromExtensions(X509Extensions extensions) + { + return GetInstance(X509Extensions.GetExtensionParsedValue(extensions, X509Extensions.CertificatePolicies)); + } + + private readonly PolicyInformation[] policyInformation; + + /** + * Construct a CertificatePolicies object containing one PolicyInformation. + * + * @param name the name to be contained. + */ + public CertificatePolicies(PolicyInformation name) + { + this.policyInformation = new PolicyInformation[] { name }; + } + + public CertificatePolicies(PolicyInformation[] policyInformation) + { + this.policyInformation = Copy(policyInformation); + } + + private CertificatePolicies(Asn1Sequence seq) + { + this.policyInformation = new PolicyInformation[seq.Count]; + + for (int i = 0; i < seq.Count; ++i) + { + policyInformation[i] = PolicyInformation.GetInstance(seq[i]); + } + } + + public virtual PolicyInformation[] GetPolicyInformation() + { + return Copy(policyInformation); + } + + public virtual PolicyInformation GetPolicyInformation(DerObjectIdentifier policyIdentifier) + { + for (int i = 0; i != policyInformation.Length; i++) + { + if (policyIdentifier.Equals(policyInformation[i].PolicyIdentifier)) + { + return policyInformation[i]; + } + } + + return null; + } + + /** + * Produce an object suitable for an ASN1OutputStream. + *
+         * CertificatePolicies ::= SEQUENCE SIZE {1..MAX} OF PolicyInformation
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + return new DerSequence(policyInformation); + } + + public override string ToString() + { + StringBuilder sb = new StringBuilder("CertificatePolicies:"); + if (policyInformation != null && policyInformation.Length > 0) + { + sb.Append(' '); + sb.Append(policyInformation[0]); + for (int i = 1; i < policyInformation.Length; ++i) + { + sb.Append(", "); + sb.Append(policyInformation[i]); + } + } + return sb.ToString(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/CertificatePolicies.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/CertificatePolicies.cs.meta new file mode 100644 index 0000000..9ceae92 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/CertificatePolicies.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: aae85a64e82915c499c749da596e7057 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/DSAParameter.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/DSAParameter.cs new file mode 100644 index 0000000..2eb6502 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/DSAParameter.cs @@ -0,0 +1,78 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X509 +{ + public class DsaParameter + : Asn1Encodable + { + internal readonly DerInteger p, q, g; + + public static DsaParameter GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static DsaParameter GetInstance( + object obj) + { + if(obj == null || obj is DsaParameter) + { + return (DsaParameter) obj; + } + + if(obj is Asn1Sequence) + { + return new DsaParameter((Asn1Sequence) obj); + } + + throw new ArgumentException("Invalid DsaParameter: " + Platform.GetTypeName(obj)); + } + + public DsaParameter( + BigInteger p, + BigInteger q, + BigInteger g) + { + this.p = new DerInteger(p); + this.q = new DerInteger(q); + this.g = new DerInteger(g); + } + + private DsaParameter( + Asn1Sequence seq) + { + if (seq.Count != 3) + throw new ArgumentException("Bad sequence size: " + seq.Count, "seq"); + + this.p = DerInteger.GetInstance(seq[0]); + this.q = DerInteger.GetInstance(seq[1]); + this.g = DerInteger.GetInstance(seq[2]); + } + + public BigInteger P + { + get { return p.PositiveValue; } + } + + public BigInteger Q + { + get { return q.PositiveValue; } + } + + public BigInteger G + { + get { return g.PositiveValue; } + } + + public override Asn1Object ToAsn1Object() + { + return new DerSequence(p, q, g); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/DSAParameter.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/DSAParameter.cs.meta new file mode 100644 index 0000000..7f1cc65 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/DSAParameter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c9bfb6ffc2f46f945b8188f45aa6652c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/DigestInfo.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/DigestInfo.cs new file mode 100644 index 0000000..3ac535e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/DigestInfo.cs @@ -0,0 +1,78 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * The DigestInfo object. + *
+     * DigestInfo::=Sequence{
+     *          digestAlgorithm  AlgorithmIdentifier,
+     *          digest OCTET STRING }
+     * 
+ */ + public class DigestInfo + : Asn1Encodable + { + private readonly byte[] digest; + private readonly AlgorithmIdentifier algID; + + public static DigestInfo GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static DigestInfo GetInstance( + object obj) + { + if (obj is DigestInfo) + { + return (DigestInfo) obj; + } + + if (obj is Asn1Sequence) + { + return new DigestInfo((Asn1Sequence) obj); + } + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + public DigestInfo( + AlgorithmIdentifier algID, + byte[] digest) + { + this.digest = digest; + this.algID = algID; + } + + private DigestInfo( + Asn1Sequence seq) + { + if (seq.Count != 2) + throw new ArgumentException("Wrong number of elements in sequence", "seq"); + + algID = AlgorithmIdentifier.GetInstance(seq[0]); + digest = Asn1OctetString.GetInstance(seq[1]).GetOctets(); + } + + public AlgorithmIdentifier AlgorithmID + { + get { return algID; } + } + + public byte[] GetDigest() + { + return digest; + } + + public override Asn1Object ToAsn1Object() + { + return new DerSequence(algID, new DerOctetString(digest)); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/DigestInfo.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/DigestInfo.cs.meta new file mode 100644 index 0000000..d5e0946 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/DigestInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b236924b96beef6499f9aa1697796964 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/DisplayText.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/DisplayText.cs new file mode 100644 index 0000000..39b3c98 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/DisplayText.cs @@ -0,0 +1,174 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * DisplayText class, used in + * CertificatePolicies X509 V3 extensions (in policy qualifiers). + * + *

It stores a string in a chosen encoding. + *

+	 * DisplayText ::= CHOICE {
+	 *      ia5String        IA5String      (SIZE (1..200)),
+	 *      visibleString    VisibleString  (SIZE (1..200)),
+	 *      bmpString        BMPString      (SIZE (1..200)),
+	 *      utf8String       UTF8String     (SIZE (1..200)) }
+	 * 

+ * @see PolicyQualifierInfo + * @see PolicyInformation + */ + public class DisplayText + : Asn1Encodable, IAsn1Choice + { + /** + * Constant corresponding to ia5String encoding. + * + */ + public const int ContentTypeIA5String = 0; + /** + * Constant corresponding to bmpString encoding. + * + */ + public const int ContentTypeBmpString = 1; + /** + * Constant corresponding to utf8String encoding. + * + */ + public const int ContentTypeUtf8String = 2; + /** + * Constant corresponding to visibleString encoding. + * + */ + public const int ContentTypeVisibleString = 3; + /** + * Describe constant DisplayTextMaximumSize here. + * + */ + public const int DisplayTextMaximumSize = 200; + + internal readonly int contentType; + internal readonly IAsn1String contents; + + /** + * Creates a new DisplayText instance. + * + * @param type the desired encoding type for the text. + * @param text the text to store. Strings longer than 200 + * characters are truncated. + */ + public DisplayText( + int type, + string text) + { + if (text.Length > DisplayTextMaximumSize) + { + // RFC3280 limits these strings to 200 chars + // truncate the string + text = text.Substring(0, DisplayTextMaximumSize); + } + + contentType = type; + switch (type) + { + case ContentTypeIA5String: + contents = (IAsn1String)new DerIA5String (text); + break; + case ContentTypeUtf8String: + contents = (IAsn1String)new DerUtf8String(text); + break; + case ContentTypeVisibleString: + contents = (IAsn1String)new DerVisibleString(text); + break; + case ContentTypeBmpString: + contents = (IAsn1String)new DerBmpString(text); + break; + default: + contents = (IAsn1String)new DerUtf8String(text); + break; + } + } + +// /** +// * return true if the passed in string can be represented without +// * loss as a PrintableString, false otherwise. +// */ +// private bool CanBePrintable( +// string str) +// { +// for (int i = str.Length - 1; i >= 0; i--) +// { +// if (str[i] > 0x007f) +// { +// return false; +// } +// } +// +// return true; +// } + + /** + * Creates a new DisplayText instance. + * + * @param text the text to encapsulate. Strings longer than 200 + * characters are truncated. + */ + public DisplayText( + string text) + { + // by default use UTF8String + if (text.Length > DisplayTextMaximumSize) + { + text = text.Substring(0, DisplayTextMaximumSize); + } + + contentType = ContentTypeUtf8String; + contents = new DerUtf8String(text); + } + + /** + * Creates a new DisplayText instance. + *

Useful when reading back a DisplayText class + * from it's Asn1Encodable form.

+ * + * @param contents an Asn1Encodable instance. + */ + public DisplayText( + IAsn1String contents) + { + this.contents = contents; + } + + public static DisplayText GetInstance( + object obj) + { + if (obj is IAsn1String) + { + return new DisplayText((IAsn1String) obj); + } + + if (obj is DisplayText) + { + return (DisplayText) obj; + } + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + public override Asn1Object ToAsn1Object() + { + return (Asn1Object) contents; + } + + /** + * Returns the stored string object. + * + * @return the stored text as a string. + */ + public string GetString() + { + return contents.GetString(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/DisplayText.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/DisplayText.cs.meta new file mode 100644 index 0000000..a26686a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/DisplayText.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a00d1cfb36c1418468fc46e99ee287d0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/DistributionPoint.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/DistributionPoint.cs new file mode 100644 index 0000000..54ab930 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/DistributionPoint.cs @@ -0,0 +1,148 @@ +using System; +using System.Text; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * The DistributionPoint object. + *
+     * DistributionPoint ::= Sequence {
+     *      distributionPoint [0] DistributionPointName OPTIONAL,
+     *      reasons           [1] ReasonFlags OPTIONAL,
+     *      cRLIssuer         [2] GeneralNames OPTIONAL
+     * }
+     * 
+ */ + public class DistributionPoint + : Asn1Encodable + { + internal readonly DistributionPointName distributionPoint; + internal readonly ReasonFlags reasons; + internal readonly GeneralNames cRLIssuer; + + public static DistributionPoint GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static DistributionPoint GetInstance( + object obj) + { + if(obj == null || obj is DistributionPoint) + { + return (DistributionPoint) obj; + } + + if(obj is Asn1Sequence) + { + return new DistributionPoint((Asn1Sequence) obj); + } + + throw new ArgumentException("Invalid DistributionPoint: " + Platform.GetTypeName(obj)); + } + + private DistributionPoint( + Asn1Sequence seq) + { + for (int i = 0; i != seq.Count; i++) + { + Asn1TaggedObject t = Asn1TaggedObject.GetInstance(seq[i]); + + switch (t.TagNo) + { + case 0: + distributionPoint = DistributionPointName.GetInstance(t, true); + break; + case 1: + reasons = new ReasonFlags(DerBitString.GetInstance(t, false)); + break; + case 2: + cRLIssuer = GeneralNames.GetInstance(t, false); + break; + } + } + } + + public DistributionPoint( + DistributionPointName distributionPointName, + ReasonFlags reasons, + GeneralNames crlIssuer) + { + this.distributionPoint = distributionPointName; + this.reasons = reasons; + this.cRLIssuer = crlIssuer; + } + + public DistributionPointName DistributionPointName + { + get { return distributionPoint; } + } + + public ReasonFlags Reasons + { + get { return reasons; } + } + + public GeneralNames CrlIssuer + { + get { return cRLIssuer; } + } + + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + + // As this is a CHOICE it must be explicitly tagged + v.AddOptionalTagged(true, 0, distributionPoint); + + v.AddOptionalTagged(false, 1, reasons); + v.AddOptionalTagged(false, 2, cRLIssuer); + return new DerSequence(v); + } + + public override string ToString() + { + string sep = Platform.NewLine; + StringBuilder buf = new StringBuilder(); + buf.Append("DistributionPoint: ["); + buf.Append(sep); + if (distributionPoint != null) + { + appendObject(buf, sep, "distributionPoint", distributionPoint.ToString()); + } + if (reasons != null) + { + appendObject(buf, sep, "reasons", reasons.ToString()); + } + if (cRLIssuer != null) + { + appendObject(buf, sep, "cRLIssuer", cRLIssuer.ToString()); + } + buf.Append("]"); + buf.Append(sep); + return buf.ToString(); + } + + private void appendObject( + StringBuilder buf, + string sep, + string name, + string val) + { + string indent = " "; + + buf.Append(indent); + buf.Append(name); + buf.Append(":"); + buf.Append(sep); + buf.Append(indent); + buf.Append(indent); + buf.Append(val); + buf.Append(sep); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/DistributionPoint.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/DistributionPoint.cs.meta new file mode 100644 index 0000000..9d5728d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/DistributionPoint.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dfbf20d264234254b8f765d73fadc784 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/DistributionPointName.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/DistributionPointName.cs new file mode 100644 index 0000000..43fdaf5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/DistributionPointName.cs @@ -0,0 +1,130 @@ +using System; +using System.Text; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * The DistributionPointName object. + *
+     * DistributionPointName ::= CHOICE {
+     *     fullName                 [0] GeneralNames,
+     *     nameRelativeToCRLIssuer  [1] RDN
+     * }
+     * 
+ */ + public class DistributionPointName + : Asn1Encodable, IAsn1Choice + { + internal readonly Asn1Encodable name; + internal readonly int type; + + public const int FullName = 0; + public const int NameRelativeToCrlIssuer = 1; + + public static DistributionPointName GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1TaggedObject.GetInstance(obj, true)); + } + + public static DistributionPointName GetInstance( + object obj) + { + if (obj == null || obj is DistributionPointName) + { + return (DistributionPointName) obj; + } + + if (obj is Asn1TaggedObject) + { + return new DistributionPointName((Asn1TaggedObject) obj); + } + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + public DistributionPointName( + int type, + Asn1Encodable name) + { + this.type = type; + this.name = name; + } + + public DistributionPointName( + GeneralNames name) + : this(FullName, name) + { + } + + public int PointType + { + get { return type; } + } + + public Asn1Encodable Name + { + get { return name; } + } + + public DistributionPointName( + Asn1TaggedObject obj) + { + this.type = obj.TagNo; + + if (type == FullName) + { + this.name = GeneralNames.GetInstance(obj, false); + } + else + { + this.name = Asn1Set.GetInstance(obj, false); + } + } + + public override Asn1Object ToAsn1Object() + { + return new DerTaggedObject(false, type, name); + } + + public override string ToString() + { + string sep = Platform.NewLine; + StringBuilder buf = new StringBuilder(); + buf.Append("DistributionPointName: ["); + buf.Append(sep); + if (type == FullName) + { + appendObject(buf, sep, "fullName", name.ToString()); + } + else + { + appendObject(buf, sep, "nameRelativeToCRLIssuer", name.ToString()); + } + buf.Append("]"); + buf.Append(sep); + return buf.ToString(); + } + + private void appendObject( + StringBuilder buf, + string sep, + string name, + string val) + { + string indent = " "; + + buf.Append(indent); + buf.Append(name); + buf.Append(":"); + buf.Append(sep); + buf.Append(indent); + buf.Append(indent); + buf.Append(val); + buf.Append(sep); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/DistributionPointName.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/DistributionPointName.cs.meta new file mode 100644 index 0000000..a931ddc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/DistributionPointName.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: eeb05f8aba4c6ce45b574f3a8a6b17ee +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/ExtendedKeyUsage.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/ExtendedKeyUsage.cs new file mode 100644 index 0000000..7e8c7a3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/ExtendedKeyUsage.cs @@ -0,0 +1,127 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * The extendedKeyUsage object. + *
+     *      extendedKeyUsage ::= Sequence SIZE (1..MAX) OF KeyPurposeId
+     * 
+ */ + public class ExtendedKeyUsage + : Asn1Encodable + { + public static ExtendedKeyUsage GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static ExtendedKeyUsage GetInstance( + object obj) + { + if (obj is ExtendedKeyUsage) + return (ExtendedKeyUsage)obj; + if (obj is X509Extension) + return GetInstance(X509Extension.ConvertValueToObject((X509Extension)obj)); + if (obj == null) + return null; + return new ExtendedKeyUsage(Asn1Sequence.GetInstance(obj)); + } + + public static ExtendedKeyUsage FromExtensions(X509Extensions extensions) + { + return GetInstance(X509Extensions.GetExtensionParsedValue(extensions, X509Extensions.ExtendedKeyUsage)); + } + + internal readonly IDictionary usageTable = Platform.CreateHashtable(); + internal readonly Asn1Sequence seq; + + private ExtendedKeyUsage( + Asn1Sequence seq) + { + this.seq = seq; + + foreach (Asn1Encodable element in seq) + { + DerObjectIdentifier oid = DerObjectIdentifier.GetInstance(element); + + this.usageTable[oid] = oid; + } + } + + public ExtendedKeyUsage( + params KeyPurposeID[] usages) + { + this.seq = new DerSequence(usages); + + foreach (KeyPurposeID usage in usages) + { + this.usageTable[usage] = usage; + } + } + +#if !(SILVERLIGHT || PORTABLE) + [Obsolete] + public ExtendedKeyUsage( + ArrayList usages) + : this((IEnumerable)usages) + { + } +#endif + + public ExtendedKeyUsage( + IEnumerable usages) + { + Asn1EncodableVector v = new Asn1EncodableVector(); + + foreach (object usage in usages) + { + DerObjectIdentifier oid = DerObjectIdentifier.GetInstance(usage); + + v.Add(oid); + this.usageTable[oid] = oid; + } + + this.seq = new DerSequence(v); + } + + public bool HasKeyPurposeId( + KeyPurposeID keyPurposeId) + { + return usageTable.Contains(keyPurposeId); + } + +#if !(SILVERLIGHT || PORTABLE) + [Obsolete("Use 'GetAllUsages'")] + public ArrayList GetUsages() + { + return new ArrayList(usageTable.Values); + } +#endif + + /** + * Returns all extended key usages. + * The returned ArrayList contains DerObjectIdentifier instances. + * @return An ArrayList with all key purposes. + */ + public IList GetAllUsages() + { + return Platform.CreateArrayList(usageTable.Values); + } + + public int Count + { + get { return usageTable.Count; } + } + + public override Asn1Object ToAsn1Object() + { + return seq; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/ExtendedKeyUsage.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/ExtendedKeyUsage.cs.meta new file mode 100644 index 0000000..d6f36aa --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/ExtendedKeyUsage.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ab7155a8f500b044eb9e0ed241cf1c97 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/GeneralName.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/GeneralName.cs new file mode 100644 index 0000000..fe00323 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/GeneralName.cs @@ -0,0 +1,422 @@ +using System; +using System.Collections; +using System.Globalization; +using System.IO; +using System.Text; + +using Org.BouncyCastle.Utilities; +using NetUtils = Org.BouncyCastle.Utilities.Net; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * The GeneralName object. + *
+     * GeneralName ::= CHOICE {
+     *      otherName                       [0]     OtherName,
+     *      rfc822Name                      [1]     IA5String,
+     *      dNSName                         [2]     IA5String,
+     *      x400Address                     [3]     ORAddress,
+     *      directoryName                   [4]     Name,
+     *      ediPartyName                    [5]     EDIPartyName,
+     *      uniformResourceIdentifier       [6]     IA5String,
+     *      iPAddress                       [7]     OCTET STRING,
+     *      registeredID                    [8]     OBJECT IDENTIFIER}
+     *
+     * OtherName ::= Sequence {
+     *      type-id    OBJECT IDENTIFIER,
+     *      value      [0] EXPLICIT ANY DEFINED BY type-id }
+     *
+     * EDIPartyName ::= Sequence {
+     *      nameAssigner            [0]     DirectoryString OPTIONAL,
+     *      partyName               [1]     DirectoryString }
+     * 
+ */ + public class GeneralName + : Asn1Encodable, IAsn1Choice + { + public const int OtherName = 0; + public const int Rfc822Name = 1; + public const int DnsName = 2; + public const int X400Address = 3; + public const int DirectoryName = 4; + public const int EdiPartyName = 5; + public const int UniformResourceIdentifier = 6; + public const int IPAddress = 7; + public const int RegisteredID = 8; + + internal readonly Asn1Encodable obj; + internal readonly int tag; + + public GeneralName( + X509Name directoryName) + { + this.obj = directoryName; + this.tag = 4; + } + + /** + * When the subjectAltName extension contains an Internet mail address, + * the address MUST be included as an rfc822Name. The format of an + * rfc822Name is an "addr-spec" as defined in RFC 822 [RFC 822]. + * + * When the subjectAltName extension contains a domain name service + * label, the domain name MUST be stored in the dNSName (an IA5String). + * The name MUST be in the "preferred name syntax," as specified by RFC + * 1034 [RFC 1034]. + * + * When the subjectAltName extension contains a URI, the name MUST be + * stored in the uniformResourceIdentifier (an IA5String). The name MUST + * be a non-relative URL, and MUST follow the URL syntax and encoding + * rules specified in [RFC 1738]. The name must include both a scheme + * (e.g., "http" or "ftp") and a scheme-specific-part. The scheme- + * specific-part must include a fully qualified domain name or IP + * address as the host. + * + * When the subjectAltName extension contains a iPAddress, the address + * MUST be stored in the octet string in "network byte order," as + * specified in RFC 791 [RFC 791]. The least significant bit (LSB) of + * each octet is the LSB of the corresponding byte in the network + * address. For IP Version 4, as specified in RFC 791, the octet string + * MUST contain exactly four octets. For IP Version 6, as specified in + * RFC 1883, the octet string MUST contain exactly sixteen octets [RFC + * 1883]. + */ + public GeneralName( + Asn1Object name, + int tag) + { + this.obj = name; + this.tag = tag; + } + + public GeneralName( + int tag, + Asn1Encodable name) + { + this.obj = name; + this.tag = tag; + } + + /** + * Create a GeneralName for the given tag from the passed in string. + *

+ * This constructor can handle: + *

    + *
  • rfc822Name
  • + *
  • iPAddress
  • + *
  • directoryName
  • + *
  • dNSName
  • + *
  • uniformResourceIdentifier
  • + *
  • registeredID
  • + *
+ * For x400Address, otherName and ediPartyName there is no common string + * format defined. + *

+ * Note: A directory name can be encoded in different ways into a byte + * representation. Be aware of this if the byte representation is used for + * comparing results. + *

+ * + * @param tag tag number + * @param name string representation of name + * @throws ArgumentException if the string encoding is not correct or + * not supported. + */ + public GeneralName( + int tag, + string name) + { + this.tag = tag; + + if (tag == Rfc822Name || tag == DnsName || tag == UniformResourceIdentifier) + { + this.obj = new DerIA5String(name); + } + else if (tag == RegisteredID) + { + this.obj = new DerObjectIdentifier(name); + } + else if (tag == DirectoryName) + { + this.obj = new X509Name(name); + } + else if (tag == IPAddress) + { + byte[] enc = toGeneralNameEncoding(name); + if (enc == null) + throw new ArgumentException("IP Address is invalid", "name"); + + this.obj = new DerOctetString(enc); + } + else + { + throw new ArgumentException("can't process string for tag: " + tag, "tag"); + } + } + + public static GeneralName GetInstance( + object obj) + { + if (obj == null || obj is GeneralName) + { + return (GeneralName) obj; + } + + if (obj is Asn1TaggedObject) + { + Asn1TaggedObject tagObj = (Asn1TaggedObject) obj; + int tag = tagObj.TagNo; + + switch (tag) + { + case EdiPartyName: + case OtherName: + case X400Address: + return new GeneralName(tag, Asn1Sequence.GetInstance(tagObj, false)); + + case DnsName: + case Rfc822Name: + case UniformResourceIdentifier: + return new GeneralName(tag, DerIA5String.GetInstance(tagObj, false)); + + case DirectoryName: + return new GeneralName(tag, X509Name.GetInstance(tagObj, true)); + case IPAddress: + return new GeneralName(tag, Asn1OctetString.GetInstance(tagObj, false)); + case RegisteredID: + return new GeneralName(tag, DerObjectIdentifier.GetInstance(tagObj, false)); + + default: + throw new ArgumentException("unknown tag: " + tag); + } + } + + if (obj is byte[]) + { + try + { + return GetInstance(Asn1Object.FromByteArray((byte[])obj)); + } + catch (IOException) + { + throw new ArgumentException("unable to parse encoded general name"); + } + } + + throw new ArgumentException("unknown object in GetInstance: " + Platform.GetTypeName(obj), "obj"); + } + + public static GeneralName GetInstance( + Asn1TaggedObject tagObj, + bool explicitly) + { + return GetInstance(Asn1TaggedObject.GetInstance(tagObj, true)); + } + + public int TagNo + { + get { return tag; } + } + + public Asn1Encodable Name + { + get { return obj; } + } + + public override string ToString() + { + StringBuilder buf = new StringBuilder(); + buf.Append(tag); + buf.Append(": "); + + switch (tag) + { + case Rfc822Name: + case DnsName: + case UniformResourceIdentifier: + buf.Append(DerIA5String.GetInstance(obj).GetString()); + break; + case DirectoryName: + buf.Append(X509Name.GetInstance(obj).ToString()); + break; + default: + buf.Append(obj.ToString()); + break; + } + + return buf.ToString(); + } + + private byte[] toGeneralNameEncoding( + string ip) + { + if (NetUtils.IPAddress.IsValidIPv6WithNetmask(ip) || NetUtils.IPAddress.IsValidIPv6(ip)) + { + int slashIndex = ip.IndexOf('/'); + + if (slashIndex < 0) + { + byte[] addr = new byte[16]; + int[] parsedIp = parseIPv6(ip); + copyInts(parsedIp, addr, 0); + + return addr; + } + else + { + byte[] addr = new byte[32]; + int[] parsedIp = parseIPv6(ip.Substring(0, slashIndex)); + copyInts(parsedIp, addr, 0); + string mask = ip.Substring(slashIndex + 1); + if (mask.IndexOf(':') > 0) + { + parsedIp = parseIPv6(mask); + } + else + { + parsedIp = parseMask(mask); + } + copyInts(parsedIp, addr, 16); + + return addr; + } + } + else if (NetUtils.IPAddress.IsValidIPv4WithNetmask(ip) || NetUtils.IPAddress.IsValidIPv4(ip)) + { + int slashIndex = ip.IndexOf('/'); + + if (slashIndex < 0) + { + byte[] addr = new byte[4]; + + parseIPv4(ip, addr, 0); + + return addr; + } + else + { + byte[] addr = new byte[8]; + + parseIPv4(ip.Substring(0, slashIndex), addr, 0); + + string mask = ip.Substring(slashIndex + 1); + if (mask.IndexOf('.') > 0) + { + parseIPv4(mask, addr, 4); + } + else + { + parseIPv4Mask(mask, addr, 4); + } + + return addr; + } + } + + return null; + } + + private void parseIPv4Mask(string mask, byte[] addr, int offset) + { + int maskVal = Int32.Parse(mask); + + for (int i = 0; i != maskVal; i++) + { + addr[(i / 8) + offset] |= (byte)(1 << (i % 8)); + } + } + + private void parseIPv4(string ip, byte[] addr, int offset) + { + foreach (string token in ip.Split('.', '/')) + { + addr[offset++] = (byte)Int32.Parse(token); + } + } + + private int[] parseMask(string mask) + { + int[] res = new int[8]; + int maskVal = Int32.Parse(mask); + + for (int i = 0; i != maskVal; i++) + { + res[i / 16] |= 1 << (i % 16); + } + return res; + } + + private void copyInts(int[] parsedIp, byte[] addr, int offSet) + { + for (int i = 0; i != parsedIp.Length; i++) + { + addr[(i * 2) + offSet] = (byte)(parsedIp[i] >> 8); + addr[(i * 2 + 1) + offSet] = (byte)parsedIp[i]; + } + } + + private int[] parseIPv6(string ip) + { + if (Platform.StartsWith(ip, "::")) + { + ip = ip.Substring(1); + } + else if (Platform.EndsWith(ip, "::")) + { + ip = ip.Substring(0, ip.Length - 1); + } + + IEnumerator sEnum = ip.Split(':').GetEnumerator(); + + int index = 0; + int[] val = new int[8]; + + int doubleColon = -1; + + while (sEnum.MoveNext()) + { + string e = (string) sEnum.Current; + + if (e.Length == 0) + { + doubleColon = index; + val[index++] = 0; + } + else + { + if (e.IndexOf('.') < 0) + { + val[index++] = Int32.Parse(e, NumberStyles.AllowHexSpecifier); + } + else + { + string[] tokens = e.Split('.'); + + val[index++] = (Int32.Parse(tokens[0]) << 8) | Int32.Parse(tokens[1]); + val[index++] = (Int32.Parse(tokens[2]) << 8) | Int32.Parse(tokens[3]); + } + } + } + + if (index != val.Length) + { + Array.Copy(val, doubleColon, val, val.Length - (index - doubleColon), index - doubleColon); + for (int i = doubleColon; i != val.Length - (index - doubleColon); i++) + { + val[i] = 0; + } + } + + return val; + } + + public override Asn1Object ToAsn1Object() + { + // directoryName is explicitly tagged as it is a CHOICE + bool isExplicit = (tag == DirectoryName); + + return new DerTaggedObject(isExplicit, tag, obj); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/GeneralName.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/GeneralName.cs.meta new file mode 100644 index 0000000..eaf80be --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/GeneralName.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 19d443ae9fb314546aca8b8c17327ab8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/GeneralNames.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/GeneralNames.cs new file mode 100644 index 0000000..c105f3b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/GeneralNames.cs @@ -0,0 +1,96 @@ +using System; +using System.Text; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X509 +{ + public class GeneralNames + : Asn1Encodable + { + private static GeneralName[] Copy(GeneralName[] names) + { + return (GeneralName[])names.Clone(); + } + + public static GeneralNames GetInstance(object obj) + { + if (obj is GeneralNames) + return (GeneralNames)obj; + if (obj == null) + return null; + return new GeneralNames(Asn1Sequence.GetInstance(obj)); + } + + public static GeneralNames GetInstance(Asn1TaggedObject obj, bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static GeneralNames FromExtensions(X509Extensions extensions, DerObjectIdentifier extOid) + { + return GetInstance(X509Extensions.GetExtensionParsedValue(extensions, extOid)); + } + + private readonly GeneralName[] names; + + /// Construct a GeneralNames object containing one GeneralName. + /// The name to be contained. + public GeneralNames( + GeneralName name) + { + names = new GeneralName[]{ name }; + } + + public GeneralNames( + GeneralName[] names) + { + this.names = Copy(names); + } + + private GeneralNames( + Asn1Sequence seq) + { + this.names = new GeneralName[seq.Count]; + + for (int i = 0; i != seq.Count; i++) + { + names[i] = GeneralName.GetInstance(seq[i]); + } + } + + public GeneralName[] GetNames() + { + return Copy(names); + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+		 * GeneralNames ::= Sequence SIZE {1..MAX} OF GeneralName
+		 * 
+ */ + public override Asn1Object ToAsn1Object() + { + return new DerSequence(names); + } + + public override string ToString() + { + StringBuilder buf = new StringBuilder(); + string sep = Platform.NewLine; + + buf.Append("GeneralNames:"); + buf.Append(sep); + + foreach (GeneralName name in names) + { + buf.Append(" "); + buf.Append(name); + buf.Append(sep); + } + + return buf.ToString(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/GeneralNames.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/GeneralNames.cs.meta new file mode 100644 index 0000000..6f7c3a1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/GeneralNames.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5bf61ecc402ffe34d9df190c1c58c1a7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/GeneralSubtree.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/GeneralSubtree.cs new file mode 100644 index 0000000..7dbacd2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/GeneralSubtree.cs @@ -0,0 +1,185 @@ +using System; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * Class for containing a restriction object subtrees in NameConstraints. See + * RFC 3280. + * + *
+	 *
+	 *       GeneralSubtree ::= SEQUENCE
+	 *       {
+	 *         baseName                    GeneralName,
+	 *         minimum         [0]     BaseDistance DEFAULT 0,
+	 *         maximum         [1]     BaseDistance OPTIONAL
+	 *       }
+	 * 
+ * + * @see org.bouncycastle.asn1.x509.NameConstraints + * + */ + public class GeneralSubtree + : Asn1Encodable + { + private readonly GeneralName baseName; + private readonly DerInteger minimum; + private readonly DerInteger maximum; + + private GeneralSubtree( + Asn1Sequence seq) + { + baseName = GeneralName.GetInstance(seq[0]); + + switch (seq.Count) + { + case 1: + break; + case 2: + { + Asn1TaggedObject o = Asn1TaggedObject.GetInstance(seq[1]); + switch (o.TagNo) + { + case 0: + minimum = DerInteger.GetInstance(o, false); + break; + case 1: + maximum = DerInteger.GetInstance(o, false); + break; + default: + throw new ArgumentException("Bad tag number: " + o.TagNo); + } + break; + } + case 3: + { + { + Asn1TaggedObject oMin = Asn1TaggedObject.GetInstance(seq[1]); + if (oMin.TagNo != 0) + throw new ArgumentException("Bad tag number for 'minimum': " + oMin.TagNo); + minimum = DerInteger.GetInstance(oMin, false); + } + + { + Asn1TaggedObject oMax = Asn1TaggedObject.GetInstance(seq[2]); + if (oMax.TagNo != 1) + throw new ArgumentException("Bad tag number for 'maximum': " + oMax.TagNo); + maximum = DerInteger.GetInstance(oMax, false); + } + + break; + } + default: + throw new ArgumentException("Bad sequence size: " + seq.Count); + } + } + + /** + * Constructor from a given details. + * + * According RFC 3280, the minimum and maximum fields are not used with any + * name forms, thus minimum MUST be zero, and maximum MUST be absent. + *

+ * If minimum is null, zero is assumed, if + * maximum is null, maximum is absent.

+ * + * @param baseName + * A restriction. + * @param minimum + * Minimum + * + * @param maximum + * Maximum + */ + public GeneralSubtree( + GeneralName baseName, + BigInteger minimum, + BigInteger maximum) + { + this.baseName = baseName; + if (minimum != null) + { + this.minimum = new DerInteger(minimum); + } + if (maximum != null) + { + this.maximum = new DerInteger(maximum); + } + } + + public GeneralSubtree( + GeneralName baseName) + : this(baseName, null, null) + { + } + + public static GeneralSubtree GetInstance( + Asn1TaggedObject o, + bool isExplicit) + { + return new GeneralSubtree(Asn1Sequence.GetInstance(o, isExplicit)); + } + + public static GeneralSubtree GetInstance( + object obj) + { + if (obj == null) + { + return null; + } + + if (obj is GeneralSubtree) + { + return (GeneralSubtree) obj; + } + + return new GeneralSubtree(Asn1Sequence.GetInstance(obj)); + } + + public GeneralName Base + { + get { return baseName; } + } + + public BigInteger Minimum + { + get { return minimum == null ? BigInteger.Zero : minimum.Value; } + } + + public BigInteger Maximum + { + get { return maximum == null ? null : maximum.Value; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + * + * Returns: + * + *
+		 *       GeneralSubtree ::= SEQUENCE
+		 *       {
+		 *         baseName                    GeneralName,
+		 *         minimum         [0]     BaseDistance DEFAULT 0,
+		 *         maximum         [1]     BaseDistance OPTIONAL
+		 *       }
+		 * 
+ * + * @return a DERObject + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(baseName); + + if (minimum != null && !minimum.HasValue(0)) + { + v.Add(new DerTaggedObject(false, 0, minimum)); + } + + v.AddOptionalTagged(false, 1, maximum); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/GeneralSubtree.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/GeneralSubtree.cs.meta new file mode 100644 index 0000000..0779c73 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/GeneralSubtree.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e94981b3ac3345d469079f9c4324cdf0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/Holder.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/Holder.cs new file mode 100644 index 0000000..90df75a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/Holder.cs @@ -0,0 +1,246 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * The Holder object. + *

+ * For an v2 attribute certificate this is: + * + *

+	 *            Holder ::= SEQUENCE {
+	 *                  baseCertificateID   [0] IssuerSerial OPTIONAL,
+	 *                           -- the issuer and serial number of
+	 *                           -- the holder's Public Key Certificate
+	 *                  entityName          [1] GeneralNames OPTIONAL,
+	 *                           -- the name of the claimant or role
+	 *                  objectDigestInfo    [2] ObjectDigestInfo OPTIONAL
+	 *                           -- used to directly authenticate the holder,
+	 *                           -- for example, an executable
+	 *            }
+	 * 
+ *

+ *

+ * For an v1 attribute certificate this is: + * + *

+	 *         subject CHOICE {
+	 *          baseCertificateID [0] EXPLICIT IssuerSerial,
+	 *          -- associated with a Public Key Certificate
+	 *          subjectName [1] EXPLICIT GeneralNames },
+	 *          -- associated with a name
+	 * 
+ *

+ */ + public class Holder + : Asn1Encodable + { + internal readonly IssuerSerial baseCertificateID; + internal readonly GeneralNames entityName; + internal readonly ObjectDigestInfo objectDigestInfo; + private readonly int version; + + public static Holder GetInstance( + object obj) + { + if (obj is Holder) + { + return (Holder) obj; + } + + if (obj is Asn1Sequence) + { + return new Holder((Asn1Sequence) obj); + } + + if (obj is Asn1TaggedObject) + { + return new Holder((Asn1TaggedObject) obj); + } + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + /** + * Constructor for a holder for an v1 attribute certificate. + * + * @param tagObj The ASN.1 tagged holder object. + */ + public Holder( + Asn1TaggedObject tagObj) + { + switch (tagObj.TagNo) + { + case 0: + baseCertificateID = IssuerSerial.GetInstance(tagObj, true); + break; + case 1: + entityName = GeneralNames.GetInstance(tagObj, true); + break; + default: + throw new ArgumentException("unknown tag in Holder"); + } + + this.version = 0; + } + + /** + * Constructor for a holder for an v2 attribute certificate. * + * + * @param seq The ASN.1 sequence. + */ + private Holder( + Asn1Sequence seq) + { + if (seq.Count > 3) + throw new ArgumentException("Bad sequence size: " + seq.Count); + + for (int i = 0; i != seq.Count; i++) + { + Asn1TaggedObject tObj = Asn1TaggedObject.GetInstance(seq[i]); + + switch (tObj.TagNo) + { + case 0: + baseCertificateID = IssuerSerial.GetInstance(tObj, false); + break; + case 1: + entityName = GeneralNames.GetInstance(tObj, false); + break; + case 2: + objectDigestInfo = ObjectDigestInfo.GetInstance(tObj, false); + break; + default: + throw new ArgumentException("unknown tag in Holder"); + } + } + + this.version = 1; + } + + public Holder( + IssuerSerial baseCertificateID) + : this(baseCertificateID, 1) + { + } + + /** + * Constructs a holder from a IssuerSerial. + * @param baseCertificateID The IssuerSerial. + * @param version The version of the attribute certificate. + */ + public Holder( + IssuerSerial baseCertificateID, + int version) + { + this.baseCertificateID = baseCertificateID; + this.version = version; + } + + /** + * Returns 1 for v2 attribute certificates or 0 for v1 attribute + * certificates. + * @return The version of the attribute certificate. + */ + public int Version + { + get { return version; } + } + + /** + * Constructs a holder with an entityName for v2 attribute certificates or + * with a subjectName for v1 attribute certificates. + * + * @param entityName The entity or subject name. + */ + public Holder( + GeneralNames entityName) + : this(entityName, 1) + { + } + + /** + * Constructs a holder with an entityName for v2 attribute certificates or + * with a subjectName for v1 attribute certificates. + * + * @param entityName The entity or subject name. + * @param version The version of the attribute certificate. + */ + public Holder( + GeneralNames entityName, + int version) + { + this.entityName = entityName; + this.version = version; + } + + /** + * Constructs a holder from an object digest info. + * + * @param objectDigestInfo The object digest info object. + */ + public Holder( + ObjectDigestInfo objectDigestInfo) + { + this.objectDigestInfo = objectDigestInfo; + this.version = 1; + } + + public IssuerSerial BaseCertificateID + { + get { return baseCertificateID; } + } + + /** + * Returns the entityName for an v2 attribute certificate or the subjectName + * for an v1 attribute certificate. + * + * @return The entityname or subjectname. + */ + public GeneralNames EntityName + { + get { return entityName; } + } + + public ObjectDigestInfo ObjectDigestInfo + { + get { return objectDigestInfo; } + } + + /** + * The Holder object. + *
+         *  Holder ::= Sequence {
+         *        baseCertificateID   [0] IssuerSerial OPTIONAL,
+         *                 -- the issuer and serial number of
+         *                 -- the holder's Public Key Certificate
+         *        entityName          [1] GeneralNames OPTIONAL,
+         *                 -- the name of the claimant or role
+         *        objectDigestInfo    [2] ObjectDigestInfo OPTIONAL
+         *                 -- used to directly authenticate the holder,
+         *                 -- for example, an executable
+         *  }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + if (version == 1) + { + Asn1EncodableVector v = new Asn1EncodableVector(3); + v.AddOptionalTagged(false, 0, baseCertificateID); + v.AddOptionalTagged(false, 1, entityName); + v.AddOptionalTagged(false, 2, objectDigestInfo); + return new DerSequence(v); + } + + if (entityName != null) + { + return new DerTaggedObject(true, 1, entityName); + } + + return new DerTaggedObject(true, 0, baseCertificateID); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/Holder.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/Holder.cs.meta new file mode 100644 index 0000000..ef164e3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/Holder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ae73349b8f6fa984eafc695450d33893 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/IetfAttrSyntax.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/IetfAttrSyntax.cs new file mode 100644 index 0000000..05313b1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/IetfAttrSyntax.cs @@ -0,0 +1,155 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * Implementation of IetfAttrSyntax as specified by RFC3281. + */ + public class IetfAttrSyntax + : Asn1Encodable + { + public const int ValueOctets = 1; + public const int ValueOid = 2; + public const int ValueUtf8 = 3; + + internal readonly GeneralNames policyAuthority; + internal readonly Asn1EncodableVector values = new Asn1EncodableVector(); + + internal int valueChoice = -1; + + /** + * + */ + public IetfAttrSyntax( + Asn1Sequence seq) + { + int i = 0; + + if (seq[0] is Asn1TaggedObject) + { + policyAuthority = GeneralNames.GetInstance(((Asn1TaggedObject)seq[0]), false); + i++; + } + else if (seq.Count == 2) + { // VOMS fix + policyAuthority = GeneralNames.GetInstance(seq[0]); + i++; + } + + if (!(seq[i] is Asn1Sequence)) + { + throw new ArgumentException("Non-IetfAttrSyntax encoding"); + } + + seq = (Asn1Sequence) seq[i]; + + foreach (Asn1Object obj in seq) + { + int type; + + if (obj is DerObjectIdentifier) + { + type = ValueOid; + } + else if (obj is DerUtf8String) + { + type = ValueUtf8; + } + else if (obj is DerOctetString) + { + type = ValueOctets; + } + else + { + throw new ArgumentException("Bad value type encoding IetfAttrSyntax"); + } + + if (valueChoice < 0) + { + valueChoice = type; + } + + if (type != valueChoice) + { + throw new ArgumentException("Mix of value types in IetfAttrSyntax"); + } + + values.Add(obj); + } + } + + public GeneralNames PolicyAuthority + { + get { return policyAuthority; } + } + + public int ValueType + { + get { return valueChoice; } + } + + public object[] GetValues() + { + if (this.ValueType == ValueOctets) + { + Asn1OctetString[] tmp = new Asn1OctetString[values.Count]; + + for (int i = 0; i != tmp.Length; i++) + { + tmp[i] = (Asn1OctetString) values[i]; + } + + return tmp; + } + + if (this.ValueType == ValueOid) + { + DerObjectIdentifier[] tmp = new DerObjectIdentifier[values.Count]; + + for (int i = 0; i != tmp.Length; i++) + { + tmp[i] = (DerObjectIdentifier) values[i]; + } + + return tmp; + } + + { + DerUtf8String[] tmp = new DerUtf8String[values.Count]; + + for (int i = 0; i != tmp.Length; i++) + { + tmp[i] = (DerUtf8String) values[i]; + } + + return tmp; + } + } + + /** + * + *
+         *
+         *  IetfAttrSyntax ::= Sequence {
+         *    policyAuthority [0] GeneralNames OPTIONAL,
+         *    values Sequence OF CHOICE {
+         *      octets OCTET STRING,
+         *      oid OBJECT IDENTIFIER,
+         *      string UTF8String
+         *    }
+         *  }
+         *
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + v.AddOptionalTagged(true, 0, policyAuthority); + v.Add(new DerSequence(values)); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/IetfAttrSyntax.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/IetfAttrSyntax.cs.meta new file mode 100644 index 0000000..82e91fc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/IetfAttrSyntax.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 798472ff0936d924ba9711980540c1dc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/IssuerSerial.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/IssuerSerial.cs new file mode 100644 index 0000000..2c26339 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/IssuerSerial.cs @@ -0,0 +1,94 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X509 +{ + public class IssuerSerial + : Asn1Encodable + { + internal readonly GeneralNames issuer; + internal readonly DerInteger serial; + internal readonly DerBitString issuerUid; + + public static IssuerSerial GetInstance( + object obj) + { + if (obj == null || obj is IssuerSerial) + { + return (IssuerSerial) obj; + } + + if (obj is Asn1Sequence) + { + return new IssuerSerial((Asn1Sequence) obj); + } + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + public static IssuerSerial GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + private IssuerSerial( + Asn1Sequence seq) + { + if (seq.Count != 2 && seq.Count != 3) + { + throw new ArgumentException("Bad sequence size: " + seq.Count); + } + + issuer = GeneralNames.GetInstance(seq[0]); + serial = DerInteger.GetInstance(seq[1]); + + if (seq.Count == 3) + { + issuerUid = DerBitString.GetInstance(seq[2]); + } + } + + public IssuerSerial( + GeneralNames issuer, + DerInteger serial) + { + this.issuer = issuer; + this.serial = serial; + } + + public GeneralNames Issuer + { + get { return issuer; } + } + + public DerInteger Serial + { + get { return serial; } + } + + public DerBitString IssuerUid + { + get { return issuerUid; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         *  IssuerSerial  ::=  Sequence {
+         *       issuer         GeneralNames,
+         *       serial         CertificateSerialNumber,
+         *       issuerUid      UniqueIdentifier OPTIONAL
+         *  }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(issuer, serial); + v.AddOptional(issuerUid); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/IssuerSerial.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/IssuerSerial.cs.meta new file mode 100644 index 0000000..d7fc820 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/IssuerSerial.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b2b58bcd54aaef14a81b15e01c0de0fc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/IssuingDistributionPoint.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/IssuingDistributionPoint.cs new file mode 100644 index 0000000..8e9362b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/IssuingDistributionPoint.cs @@ -0,0 +1,247 @@ +using System; +using System.Text; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + *
+	 * IssuingDistributionPoint ::= SEQUENCE { 
+	 *   distributionPoint          [0] DistributionPointName OPTIONAL, 
+	 *   onlyContainsUserCerts      [1] BOOLEAN DEFAULT FALSE, 
+	 *   onlyContainsCACerts        [2] BOOLEAN DEFAULT FALSE, 
+	 *   onlySomeReasons            [3] ReasonFlags OPTIONAL, 
+	 *   indirectCRL                [4] BOOLEAN DEFAULT FALSE,
+	 *   onlyContainsAttributeCerts [5] BOOLEAN DEFAULT FALSE }
+	 * 
+ */ + public class IssuingDistributionPoint + : Asn1Encodable + { + private readonly DistributionPointName _distributionPoint; + private readonly bool _onlyContainsUserCerts; + private readonly bool _onlyContainsCACerts; + private readonly ReasonFlags _onlySomeReasons; + private readonly bool _indirectCRL; + private readonly bool _onlyContainsAttributeCerts; + + private readonly Asn1Sequence seq; + + public static IssuingDistributionPoint GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static IssuingDistributionPoint GetInstance( + object obj) + { + if (obj == null || obj is IssuingDistributionPoint) + { + return (IssuingDistributionPoint) obj; + } + + if (obj is Asn1Sequence) + { + return new IssuingDistributionPoint((Asn1Sequence) obj); + } + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + /** + * Constructor from given details. + * + * @param distributionPoint + * May contain an URI as pointer to most current CRL. + * @param onlyContainsUserCerts Covers revocation information for end certificates. + * @param onlyContainsCACerts Covers revocation information for CA certificates. + * + * @param onlySomeReasons + * Which revocation reasons does this point cover. + * @param indirectCRL + * If true then the CRL contains revocation + * information about certificates ssued by other CAs. + * @param onlyContainsAttributeCerts Covers revocation information for attribute certificates. + */ + public IssuingDistributionPoint( + DistributionPointName distributionPoint, + bool onlyContainsUserCerts, + bool onlyContainsCACerts, + ReasonFlags onlySomeReasons, + bool indirectCRL, + bool onlyContainsAttributeCerts) + { + this._distributionPoint = distributionPoint; + this._indirectCRL = indirectCRL; + this._onlyContainsAttributeCerts = onlyContainsAttributeCerts; + this._onlyContainsCACerts = onlyContainsCACerts; + this._onlyContainsUserCerts = onlyContainsUserCerts; + this._onlySomeReasons = onlySomeReasons; + + Asn1EncodableVector vec = new Asn1EncodableVector(); + if (distributionPoint != null) + { // CHOICE item so explicitly tagged + vec.Add(new DerTaggedObject(true, 0, distributionPoint)); + } + if (onlyContainsUserCerts) + { + vec.Add(new DerTaggedObject(false, 1, DerBoolean.True)); + } + if (onlyContainsCACerts) + { + vec.Add(new DerTaggedObject(false, 2, DerBoolean.True)); + } + if (onlySomeReasons != null) + { + vec.Add(new DerTaggedObject(false, 3, onlySomeReasons)); + } + if (indirectCRL) + { + vec.Add(new DerTaggedObject(false, 4, DerBoolean.True)); + } + if (onlyContainsAttributeCerts) + { + vec.Add(new DerTaggedObject(false, 5, DerBoolean.True)); + } + + seq = new DerSequence(vec); + } + + /** + * Constructor from Asn1Sequence + */ + private IssuingDistributionPoint( + Asn1Sequence seq) + { + this.seq = seq; + + for (int i = 0; i != seq.Count; i++) + { + Asn1TaggedObject o = Asn1TaggedObject.GetInstance(seq[i]); + + switch (o.TagNo) + { + case 0: + // CHOICE so explicit + _distributionPoint = DistributionPointName.GetInstance(o, true); + break; + case 1: + _onlyContainsUserCerts = DerBoolean.GetInstance(o, false).IsTrue; + break; + case 2: + _onlyContainsCACerts = DerBoolean.GetInstance(o, false).IsTrue; + break; + case 3: + _onlySomeReasons = new ReasonFlags(ReasonFlags.GetInstance(o, false)); + break; + case 4: + _indirectCRL = DerBoolean.GetInstance(o, false).IsTrue; + break; + case 5: + _onlyContainsAttributeCerts = DerBoolean.GetInstance(o, false).IsTrue; + break; + default: + throw new ArgumentException("unknown tag in IssuingDistributionPoint"); + } + } + } + + public bool OnlyContainsUserCerts + { + get { return _onlyContainsUserCerts; } + } + + public bool OnlyContainsCACerts + { + get { return _onlyContainsCACerts; } + } + + public bool IsIndirectCrl + { + get { return _indirectCRL; } + } + + public bool OnlyContainsAttributeCerts + { + get { return _onlyContainsAttributeCerts; } + } + + /** + * @return Returns the distributionPoint. + */ + public DistributionPointName DistributionPoint + { + get { return _distributionPoint; } + } + + /** + * @return Returns the onlySomeReasons. + */ + public ReasonFlags OnlySomeReasons + { + get { return _onlySomeReasons; } + } + + public override Asn1Object ToAsn1Object() + { + return seq; + } + + public override string ToString() + { + string sep = Platform.NewLine; + StringBuilder buf = new StringBuilder(); + + buf.Append("IssuingDistributionPoint: ["); + buf.Append(sep); + if (_distributionPoint != null) + { + appendObject(buf, sep, "distributionPoint", _distributionPoint.ToString()); + } + if (_onlyContainsUserCerts) + { + appendObject(buf, sep, "onlyContainsUserCerts", _onlyContainsUserCerts.ToString()); + } + if (_onlyContainsCACerts) + { + appendObject(buf, sep, "onlyContainsCACerts", _onlyContainsCACerts.ToString()); + } + if (_onlySomeReasons != null) + { + appendObject(buf, sep, "onlySomeReasons", _onlySomeReasons.ToString()); + } + if (_onlyContainsAttributeCerts) + { + appendObject(buf, sep, "onlyContainsAttributeCerts", _onlyContainsAttributeCerts.ToString()); + } + if (_indirectCRL) + { + appendObject(buf, sep, "indirectCRL", _indirectCRL.ToString()); + } + buf.Append("]"); + buf.Append(sep); + return buf.ToString(); + } + + private void appendObject( + StringBuilder buf, + string sep, + string name, + string val) + { + string indent = " "; + + buf.Append(indent); + buf.Append(name); + buf.Append(":"); + buf.Append(sep); + buf.Append(indent); + buf.Append(indent); + buf.Append(val); + buf.Append(sep); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/IssuingDistributionPoint.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/IssuingDistributionPoint.cs.meta new file mode 100644 index 0000000..3099c2e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/IssuingDistributionPoint.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4392a4df003adb54dbdbf56d195fb63d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/KeyPurposeId.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/KeyPurposeId.cs new file mode 100644 index 0000000..1a564b9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/KeyPurposeId.cs @@ -0,0 +1,38 @@ +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * The KeyPurposeID object. + *
+     *     KeyPurposeID ::= OBJECT IDENTIFIER
+     * 
+ */ + public sealed class KeyPurposeID + : DerObjectIdentifier + { + private const string IdKP = "1.3.6.1.5.5.7.3"; + + private KeyPurposeID( + string id) + : base(id) + { + } + + public static readonly KeyPurposeID AnyExtendedKeyUsage = new KeyPurposeID(X509Extensions.ExtendedKeyUsage.Id + ".0"); + public static readonly KeyPurposeID IdKPServerAuth = new KeyPurposeID(IdKP + ".1"); + public static readonly KeyPurposeID IdKPClientAuth = new KeyPurposeID(IdKP + ".2"); + public static readonly KeyPurposeID IdKPCodeSigning = new KeyPurposeID(IdKP + ".3"); + public static readonly KeyPurposeID IdKPEmailProtection = new KeyPurposeID(IdKP + ".4"); + public static readonly KeyPurposeID IdKPIpsecEndSystem = new KeyPurposeID(IdKP + ".5"); + public static readonly KeyPurposeID IdKPIpsecTunnel = new KeyPurposeID(IdKP + ".6"); + public static readonly KeyPurposeID IdKPIpsecUser = new KeyPurposeID(IdKP + ".7"); + public static readonly KeyPurposeID IdKPTimeStamping = new KeyPurposeID(IdKP + ".8"); + public static readonly KeyPurposeID IdKPOcspSigning = new KeyPurposeID(IdKP + ".9"); + + // + // microsoft key purpose ids + // + public static readonly KeyPurposeID IdKPSmartCardLogon = new KeyPurposeID("1.3.6.1.4.1.311.20.2.2"); + + public static readonly KeyPurposeID IdKPMacAddress = new KeyPurposeID("1.3.6.1.1.1.1.22"); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/KeyPurposeId.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/KeyPurposeId.cs.meta new file mode 100644 index 0000000..954c590 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/KeyPurposeId.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5ef6346e68d000a44ad3099cadaac35f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/KeyUsage.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/KeyUsage.cs new file mode 100644 index 0000000..b31b543 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/KeyUsage.cs @@ -0,0 +1,78 @@ +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * The KeyUsage object. + *
+     *    id-ce-keyUsage OBJECT IDENTIFIER ::=  { id-ce 15 }
+     *
+     *    KeyUsage ::= BIT STRING {
+     *         digitalSignature        (0),
+     *         nonRepudiation          (1),
+     *         keyEncipherment         (2),
+     *         dataEncipherment        (3),
+     *         keyAgreement            (4),
+     *         keyCertSign             (5),
+     *         cRLSign                 (6),
+     *         encipherOnly            (7),
+     *         decipherOnly            (8) }
+     * 
+ */ + public class KeyUsage + : DerBitString + { + public const int DigitalSignature = (1 << 7); + public const int NonRepudiation = (1 << 6); + public const int KeyEncipherment = (1 << 5); + public const int DataEncipherment = (1 << 4); + public const int KeyAgreement = (1 << 3); + public const int KeyCertSign = (1 << 2); + public const int CrlSign = (1 << 1); + public const int EncipherOnly = (1 << 0); + public const int DecipherOnly = (1 << 15); + + public static new KeyUsage GetInstance(object obj) + { + if (obj is KeyUsage) + return (KeyUsage)obj; + if (obj is X509Extension) + return GetInstance(X509Extension.ConvertValueToObject((X509Extension)obj)); + if (obj == null) + return null; + return new KeyUsage(DerBitString.GetInstance(obj)); + } + + public static KeyUsage FromExtensions(X509Extensions extensions) + { + return GetInstance(X509Extensions.GetExtensionParsedValue(extensions, X509Extensions.KeyUsage)); + } + + /** + * Basic constructor. + * + * @param usage - the bitwise OR of the Key Usage flags giving the + * allowed uses for the key. + * e.g. (KeyUsage.keyEncipherment | KeyUsage.dataEncipherment) + */ + public KeyUsage(int usage) + : base(usage) + { + } + + private KeyUsage( + DerBitString usage) + : base(usage.GetBytes(), usage.PadBits) + { + } + + public override string ToString() + { + byte[] data = GetBytes(); + if (data.Length == 1) + { + return "KeyUsage: 0x" + (data[0] & 0xff).ToString("X"); + } + + return "KeyUsage: 0x" + ((data[1] & 0xff) << 8 | (data[0] & 0xff)).ToString("X"); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/KeyUsage.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/KeyUsage.cs.meta new file mode 100644 index 0000000..0059fb5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/KeyUsage.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dfa05c1c3869cc3418a65c77cc8519f2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/NameConstraints.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/NameConstraints.cs new file mode 100644 index 0000000..b8cc7c0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/NameConstraints.cs @@ -0,0 +1,111 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X509 +{ + public class NameConstraints + : Asn1Encodable + { + private Asn1Sequence permitted, excluded; + + public static NameConstraints GetInstance( + object obj) + { + if (obj == null || obj is NameConstraints) + { + return (NameConstraints) obj; + } + + if (obj is Asn1Sequence) + { + return new NameConstraints((Asn1Sequence) obj); + } + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + public NameConstraints( + Asn1Sequence seq) + { + foreach (Asn1TaggedObject o in seq) + { + switch (o.TagNo) + { + case 0: + permitted = Asn1Sequence.GetInstance(o, false); + break; + case 1: + excluded = Asn1Sequence.GetInstance(o, false); + break; + } + } + } + +#if !(SILVERLIGHT || PORTABLE) + public NameConstraints( + ArrayList permitted, + ArrayList excluded) + : this((IList)permitted, (IList)excluded) + { + } +#endif + + /** + * Constructor from a given details. + * + *

permitted and excluded are Vectors of GeneralSubtree objects.

+ * + * @param permitted Permitted subtrees + * @param excluded Excluded subtrees + */ + public NameConstraints( + IList permitted, + IList excluded) + { + if (permitted != null) + { + this.permitted = CreateSequence(permitted); + } + + if (excluded != null) + { + this.excluded = CreateSequence(excluded); + } + } + + private DerSequence CreateSequence( + IList subtrees) + { + GeneralSubtree[] gsts = new GeneralSubtree[subtrees.Count]; + for (int i = 0; i < subtrees.Count; ++i) + { + gsts[i] = (GeneralSubtree)subtrees[i]; + } + return new DerSequence(gsts); + } + + public Asn1Sequence PermittedSubtrees + { + get { return permitted; } + } + + public Asn1Sequence ExcludedSubtrees + { + get { return excluded; } + } + + /* + * NameConstraints ::= SEQUENCE { permittedSubtrees [0] GeneralSubtrees + * OPTIONAL, excludedSubtrees [1] GeneralSubtrees OPTIONAL } + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + v.AddOptionalTagged(false, 0, permitted); + v.AddOptionalTagged(false, 1, excluded); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/NameConstraints.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/NameConstraints.cs.meta new file mode 100644 index 0000000..774380a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/NameConstraints.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e8914f9588979ae448fb3d0819a57c6a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/NoticeReference.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/NoticeReference.cs new file mode 100644 index 0000000..f0d3a7b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/NoticeReference.cs @@ -0,0 +1,143 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * NoticeReference class, used in + * CertificatePolicies X509 V3 extensions + * (in policy qualifiers). + * + *
+     *  NoticeReference ::= Sequence {
+     *      organization     DisplayText,
+     *      noticeNumbers    Sequence OF Integer }
+     *
+     * 
+ * + * @see PolicyQualifierInfo + * @see PolicyInformation + */ + public class NoticeReference + : Asn1Encodable + { + private readonly DisplayText organization; + private readonly Asn1Sequence noticeNumbers; + + private static Asn1EncodableVector ConvertVector(IList numbers) + { + Asn1EncodableVector av = new Asn1EncodableVector(); + + foreach (object o in numbers) + { + DerInteger di; + + if (o is BigInteger) + { + di = new DerInteger((BigInteger)o); + } + else if (o is int) + { + di = new DerInteger((int)o); + } + else + { + throw new ArgumentException(); + } + + av.Add(di); + } + return av; + } + + /** + * Creates a new NoticeReference instance. + * + * @param organization a String value + * @param numbers a Vector value + */ + public NoticeReference(string organization, IList numbers) + : this(organization, ConvertVector(numbers)) + { + } + + /** + * Creates a new NoticeReference instance. + * + * @param organization a String value + * @param noticeNumbers an ASN1EncodableVector value + */ + public NoticeReference(string organization, Asn1EncodableVector noticeNumbers) + : this(new DisplayText(organization), noticeNumbers) + { + } + + /** + * Creates a new NoticeReference instance. + * + * @param organization displayText + * @param noticeNumbers an ASN1EncodableVector value + */ + public NoticeReference(DisplayText organization, Asn1EncodableVector noticeNumbers) + { + this.organization = organization; + this.noticeNumbers = new DerSequence(noticeNumbers); + } + + /** + * Creates a new NoticeReference instance. + *

Useful for reconstructing a NoticeReference + * instance from its encodable/encoded form.

+ * + * @param as an Asn1Sequence value obtained from either + * calling @{link ToAsn1Object()} for a NoticeReference + * instance or from parsing it from a Der-encoded stream. + */ + private NoticeReference(Asn1Sequence seq) + { + if (seq.Count != 2) + throw new ArgumentException("Bad sequence size: " + seq.Count, "seq"); + + organization = DisplayText.GetInstance(seq[0]); + noticeNumbers = Asn1Sequence.GetInstance(seq[1]); + } + + public static NoticeReference GetInstance(object obj) + { + if (obj is NoticeReference) + return (NoticeReference)obj; + if (obj == null) + return null; + return new NoticeReference(Asn1Sequence.GetInstance(obj)); + } + + public virtual DisplayText Organization + { + get { return organization; } + } + + public virtual DerInteger[] GetNoticeNumbers() + { + DerInteger[] tmp = new DerInteger[noticeNumbers.Count]; + + for (int i = 0; i != noticeNumbers.Count; ++i) + { + tmp[i] = DerInteger.GetInstance(noticeNumbers[i]); + } + + return tmp; + } + + /** + * Describe ToAsn1Object method here. + * + * @return a Asn1Object value + */ + public override Asn1Object ToAsn1Object() + { + return new DerSequence(organization, noticeNumbers); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/NoticeReference.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/NoticeReference.cs.meta new file mode 100644 index 0000000..d70aa78 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/NoticeReference.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 374c0e0058848c24c82bb5d34bb28329 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/ObjectDigestInfo.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/ObjectDigestInfo.cs new file mode 100644 index 0000000..190243c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/ObjectDigestInfo.cs @@ -0,0 +1,173 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * ObjectDigestInfo ASN.1 structure used in v2 attribute certificates. + * + *
+	 *  
+	 *    ObjectDigestInfo ::= SEQUENCE {
+	 *         digestedObjectType  ENUMERATED {
+	 *                 publicKey            (0),
+	 *                 publicKeyCert        (1),
+	 *                 otherObjectTypes     (2) },
+	 *                         -- otherObjectTypes MUST NOT
+	 *                         -- be used in this profile
+	 *         otherObjectTypeID   OBJECT IDENTIFIER OPTIONAL,
+	 *         digestAlgorithm     AlgorithmIdentifier,
+	 *         objectDigest        BIT STRING
+	 *    }
+	 *   
+	 * 
+ * + */ + public class ObjectDigestInfo + : Asn1Encodable + { + /** + * The public key is hashed. + */ + public const int PublicKey = 0; + + /** + * The public key certificate is hashed. + */ + public const int PublicKeyCert = 1; + + /** + * An other object is hashed. + */ + public const int OtherObjectDigest = 2; + + internal readonly DerEnumerated digestedObjectType; + internal readonly DerObjectIdentifier otherObjectTypeID; + internal readonly AlgorithmIdentifier digestAlgorithm; + internal readonly DerBitString objectDigest; + + public static ObjectDigestInfo GetInstance( + object obj) + { + if (obj == null || obj is ObjectDigestInfo) + { + return (ObjectDigestInfo) obj; + } + + if (obj is Asn1Sequence) + { + return new ObjectDigestInfo((Asn1Sequence) obj); + } + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + public static ObjectDigestInfo GetInstance( + Asn1TaggedObject obj, + bool isExplicit) + { + return GetInstance(Asn1Sequence.GetInstance(obj, isExplicit)); + } + + /** + * Constructor from given details. + *

+ * If digestedObjectType is not {@link #publicKeyCert} or + * {@link #publicKey} otherObjectTypeID must be given, + * otherwise it is ignored.

+ * + * @param digestedObjectType The digest object type. + * @param otherObjectTypeID The object type ID for + * otherObjectDigest. + * @param digestAlgorithm The algorithm identifier for the hash. + * @param objectDigest The hash value. + */ + public ObjectDigestInfo( + int digestedObjectType, + string otherObjectTypeID, + AlgorithmIdentifier digestAlgorithm, + byte[] objectDigest) + { + this.digestedObjectType = new DerEnumerated(digestedObjectType); + + if (digestedObjectType == OtherObjectDigest) + { + this.otherObjectTypeID = new DerObjectIdentifier(otherObjectTypeID); + } + + this.digestAlgorithm = digestAlgorithm; + + this.objectDigest = new DerBitString(objectDigest); + } + + private ObjectDigestInfo( + Asn1Sequence seq) + { + if (seq.Count > 4 || seq.Count < 3) + { + throw new ArgumentException("Bad sequence size: " + seq.Count); + } + + digestedObjectType = DerEnumerated.GetInstance(seq[0]); + + int offset = 0; + + if (seq.Count == 4) + { + otherObjectTypeID = DerObjectIdentifier.GetInstance(seq[1]); + offset++; + } + + digestAlgorithm = AlgorithmIdentifier.GetInstance(seq[1 + offset]); + objectDigest = DerBitString.GetInstance(seq[2 + offset]); + } + + public DerEnumerated DigestedObjectType + { + get { return digestedObjectType; } + } + + public DerObjectIdentifier OtherObjectTypeID + { + get { return otherObjectTypeID; } + } + + public AlgorithmIdentifier DigestAlgorithm + { + get { return digestAlgorithm; } + } + + public DerBitString ObjectDigest + { + get { return objectDigest; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + * + *
+		 *  
+		 *    ObjectDigestInfo ::= SEQUENCE {
+		 *         digestedObjectType  ENUMERATED {
+		 *                 publicKey            (0),
+		 *                 publicKeyCert        (1),
+		 *                 otherObjectTypes     (2) },
+		 *                         -- otherObjectTypes MUST NOT
+		 *                         -- be used in this profile
+		 *         otherObjectTypeID   OBJECT IDENTIFIER OPTIONAL,
+		 *         digestAlgorithm     AlgorithmIdentifier,
+		 *         objectDigest        BIT STRING
+		 *    }
+		 *   
+		 * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(digestedObjectType); + v.AddOptional(otherObjectTypeID); + v.Add(digestAlgorithm, objectDigest); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/ObjectDigestInfo.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/ObjectDigestInfo.cs.meta new file mode 100644 index 0000000..396904a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/ObjectDigestInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0ba921330c01e78418f7f8503a1f7529 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/OtherName.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/OtherName.cs new file mode 100644 index 0000000..3e6a614 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/OtherName.cs @@ -0,0 +1,71 @@ +using System; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * The OtherName object. + *
+     * OtherName ::= SEQUENCE {
+     *      type-id    OBJECT IDENTIFIER,
+     *      value      [0] EXPLICIT ANY DEFINED BY type-id }
+     * 
+ */ + public class OtherName + : Asn1Encodable + { + private readonly DerObjectIdentifier typeID; + private readonly Asn1Encodable value; + + /** + * OtherName factory method. + * @param obj the object used to construct an instance of + * OtherName. It must be an instance of OtherName + * or ASN1Sequence. + * @return the instance of OtherName built from the + * supplied object. + * @throws java.lang.IllegalArgumentException if the object passed + * to the factory is not an instance of OtherName or something that + * can be converted into an appropriate ASN1Sequence. + */ + public static OtherName GetInstance(object obj) + { + if (obj is OtherName) + return (OtherName)obj; + if (obj == null) + return null; + return new OtherName(Asn1Sequence.GetInstance(obj)); + } + + /** + * Base constructor. + * @param typeID the type of the other name. + * @param value the ANY object that represents the value. + */ + public OtherName(DerObjectIdentifier typeID, Asn1Encodable value) + { + this.typeID = typeID; + this.value = value; + } + + private OtherName(Asn1Sequence seq) + { + this.typeID = DerObjectIdentifier.GetInstance(seq[0]); + this.value = DerTaggedObject.GetInstance(seq[1]).GetObject(); // explicitly tagged + } + + public virtual DerObjectIdentifier TypeID + { + get { return typeID; } + } + + public Asn1Encodable Value + { + get { return value; } + } + + public override Asn1Object ToAsn1Object() + { + return new DerSequence(typeID, new DerTaggedObject(true, 0, value)); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/OtherName.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/OtherName.cs.meta new file mode 100644 index 0000000..d904168 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/OtherName.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b6d553ce71c251740a247d74493af1eb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/PolicyInformation.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/PolicyInformation.cs new file mode 100644 index 0000000..90db29a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/PolicyInformation.cs @@ -0,0 +1,75 @@ +using System; + +namespace Org.BouncyCastle.Asn1.X509 +{ + public class PolicyInformation + : Asn1Encodable + { + private readonly DerObjectIdentifier policyIdentifier; + private readonly Asn1Sequence policyQualifiers; + + private PolicyInformation( + Asn1Sequence seq) + { + if (seq.Count < 1 || seq.Count > 2) + { + throw new ArgumentException("Bad sequence size: " + seq.Count); + } + + policyIdentifier = DerObjectIdentifier.GetInstance(seq[0]); + + if (seq.Count > 1) + { + policyQualifiers = Asn1Sequence.GetInstance(seq[1]); + } + } + + public PolicyInformation( + DerObjectIdentifier policyIdentifier) + { + this.policyIdentifier = policyIdentifier; + } + + public PolicyInformation( + DerObjectIdentifier policyIdentifier, + Asn1Sequence policyQualifiers) + { + this.policyIdentifier = policyIdentifier; + this.policyQualifiers = policyQualifiers; + } + + public static PolicyInformation GetInstance( + object obj) + { + if (obj == null || obj is PolicyInformation) + { + return (PolicyInformation) obj; + } + + return new PolicyInformation(Asn1Sequence.GetInstance(obj)); + } + + public DerObjectIdentifier PolicyIdentifier + { + get { return policyIdentifier; } + } + + public Asn1Sequence PolicyQualifiers + { + get { return policyQualifiers; } + } + + /* + * PolicyInformation ::= Sequence { + * policyIdentifier CertPolicyId, + * policyQualifiers Sequence SIZE (1..MAX) OF + * PolicyQualifierInfo OPTIONAL } + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(policyIdentifier); + v.AddOptional(policyQualifiers); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/PolicyInformation.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/PolicyInformation.cs.meta new file mode 100644 index 0000000..c79c9a7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/PolicyInformation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 97a0b14e51d8580429f0f06b09389ea8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/PolicyMappings.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/PolicyMappings.cs new file mode 100644 index 0000000..928ad13 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/PolicyMappings.cs @@ -0,0 +1,70 @@ +using System.Collections; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * PolicyMappings V3 extension, described in RFC3280. + *
+	 *    PolicyMappings ::= Sequence SIZE (1..MAX) OF Sequence {
+	 *      issuerDomainPolicy      CertPolicyId,
+	 *      subjectDomainPolicy     CertPolicyId }
+	 * 
+ * + * @see RFC 3280, section 4.2.1.6 + */ + public class PolicyMappings + : Asn1Encodable + { + private readonly Asn1Sequence seq; + + /** + * Creates a new PolicyMappings instance. + * + * @param seq an Asn1Sequence constructed as specified + * in RFC 3280 + */ + public PolicyMappings( + Asn1Sequence seq) + { + this.seq = seq; + } + +#if !(SILVERLIGHT || PORTABLE) + public PolicyMappings( + Hashtable mappings) + : this((IDictionary)mappings) + { + } +#endif + + /** + * Creates a new PolicyMappings instance. + * + * @param mappings a HashMap value that maps + * string oids + * to other string oids. + */ + public PolicyMappings( + IDictionary mappings) + { + Asn1EncodableVector v = new Asn1EncodableVector(); + + foreach (string idp in mappings.Keys) + { + string sdp = (string) mappings[idp]; + + v.Add( + new DerSequence( + new DerObjectIdentifier(idp), + new DerObjectIdentifier(sdp))); + } + + seq = new DerSequence(v); + } + + public override Asn1Object ToAsn1Object() + { + return seq; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/PolicyMappings.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/PolicyMappings.cs.meta new file mode 100644 index 0000000..86a87d6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/PolicyMappings.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 616626e940855514fbcd70d25381e761 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/PolicyQualifierId.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/PolicyQualifierId.cs new file mode 100644 index 0000000..c858f08 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/PolicyQualifierId.cs @@ -0,0 +1,28 @@ +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * PolicyQualifierId, used in the CertificatePolicies + * X509V3 extension. + * + *
+	 *    id-qt          OBJECT IDENTIFIER ::=  { id-pkix 2 }
+	 *    id-qt-cps      OBJECT IDENTIFIER ::=  { id-qt 1 }
+	 *    id-qt-unotice  OBJECT IDENTIFIER ::=  { id-qt 2 }
+	 *  PolicyQualifierId ::=
+	 *       OBJECT IDENTIFIER ( id-qt-cps | id-qt-unotice )
+	 * 
+ */ + public sealed class PolicyQualifierID : DerObjectIdentifier + { + private const string IdQt = "1.3.6.1.5.5.7.2"; + + private PolicyQualifierID( + string id) + : base(id) + { + } + + public static readonly PolicyQualifierID IdQtCps = new PolicyQualifierID(IdQt + ".1"); + public static readonly PolicyQualifierID IdQtUnotice = new PolicyQualifierID(IdQt + ".2"); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/PolicyQualifierId.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/PolicyQualifierId.cs.meta new file mode 100644 index 0000000..84d6b22 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/PolicyQualifierId.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d7967dcb9f27cba429990c8260adfe2d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/PolicyQualifierInfo.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/PolicyQualifierInfo.cs new file mode 100644 index 0000000..3cf6d7e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/PolicyQualifierInfo.cs @@ -0,0 +1,95 @@ +using System; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * Policy qualifiers, used in the X509V3 CertificatePolicies + * extension. + * + *
+     *   PolicyQualifierInfo ::= Sequence {
+     *       policyQualifierId  PolicyQualifierId,
+     *       qualifier          ANY DEFINED BY policyQualifierId }
+     * 
+ */ + public class PolicyQualifierInfo + : Asn1Encodable + { + private readonly DerObjectIdentifier policyQualifierId; + private readonly Asn1Encodable qualifier; + + /** + * Creates a new PolicyQualifierInfo instance. + * + * @param policyQualifierId a PolicyQualifierId value + * @param qualifier the qualifier, defined by the above field. + */ + public PolicyQualifierInfo( + DerObjectIdentifier policyQualifierId, + Asn1Encodable qualifier) + { + this.policyQualifierId = policyQualifierId; + this.qualifier = qualifier; + } + + /** + * Creates a new PolicyQualifierInfo containing a + * cPSuri qualifier. + * + * @param cps the CPS (certification practice statement) uri as a + * string. + */ + public PolicyQualifierInfo( + string cps) + { + policyQualifierId = PolicyQualifierID.IdQtCps; + qualifier = new DerIA5String(cps); + } + + /** + * Creates a new PolicyQualifierInfo instance. + * + * @param as PolicyQualifierInfo X509 structure + * encoded as an Asn1Sequence. + */ + private PolicyQualifierInfo( + Asn1Sequence seq) + { + if (seq.Count != 2) + throw new ArgumentException("Bad sequence size: " + seq.Count, "seq"); + + policyQualifierId = DerObjectIdentifier.GetInstance(seq[0]); + qualifier = seq[1]; + } + + public static PolicyQualifierInfo GetInstance( + object obj) + { + if (obj is PolicyQualifierInfo) + return (PolicyQualifierInfo)obj; + if (obj == null) + return null; + return new PolicyQualifierInfo(Asn1Sequence.GetInstance(obj)); + } + + public virtual DerObjectIdentifier PolicyQualifierId + { + get { return policyQualifierId; } + } + + public virtual Asn1Encodable Qualifier + { + get { return qualifier; } + } + + /** + * Returns a Der-encodable representation of this instance. + * + * @return a Asn1Object value + */ + public override Asn1Object ToAsn1Object() + { + return new DerSequence(policyQualifierId, qualifier); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/PolicyQualifierInfo.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/PolicyQualifierInfo.cs.meta new file mode 100644 index 0000000..f141557 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/PolicyQualifierInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2dd8185ffb0fcf247b36a16a4e1466b2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/PrivateKeyUsagePeriod.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/PrivateKeyUsagePeriod.cs new file mode 100644 index 0000000..89e8de6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/PrivateKeyUsagePeriod.cs @@ -0,0 +1,75 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /// + ///
+	/// PrivateKeyUsagePeriod ::= SEQUENCE
+	/// {
+	/// notBefore       [0]     GeneralizedTime OPTIONAL,
+	/// notAfter        [1]     GeneralizedTime OPTIONAL }
+	/// 
+ ///
+ public class PrivateKeyUsagePeriod + : Asn1Encodable + { + public static PrivateKeyUsagePeriod GetInstance( + object obj) + { + if (obj is PrivateKeyUsagePeriod) + { + return (PrivateKeyUsagePeriod) obj; + } + + if (obj is Asn1Sequence) + { + return new PrivateKeyUsagePeriod((Asn1Sequence) obj); + } + + if (obj is X509Extension) + { + return GetInstance(X509Extension.ConvertValueToObject((X509Extension) obj)); + } + + throw new ArgumentException("unknown object in GetInstance: " + Platform.GetTypeName(obj), "obj"); + } + + private DerGeneralizedTime _notBefore, _notAfter; + + private PrivateKeyUsagePeriod( + Asn1Sequence seq) + { + foreach (Asn1TaggedObject tObj in seq) + { + if (tObj.TagNo == 0) + { + _notBefore = DerGeneralizedTime.GetInstance(tObj, false); + } + else if (tObj.TagNo == 1) + { + _notAfter = DerGeneralizedTime.GetInstance(tObj, false); + } + } + } + + public DerGeneralizedTime NotBefore + { + get { return _notBefore; } + } + + public DerGeneralizedTime NotAfter + { + get { return _notAfter; } + } + + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + v.AddOptionalTagged(false, 0, _notBefore); + v.AddOptionalTagged(false, 1, _notAfter); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/PrivateKeyUsagePeriod.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/PrivateKeyUsagePeriod.cs.meta new file mode 100644 index 0000000..5dd2fdd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/PrivateKeyUsagePeriod.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2be7e8e6d80043e4c84f251f03ca183f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/RSAPublicKeyStructure.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/RSAPublicKeyStructure.cs new file mode 100644 index 0000000..20fdd96 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/RSAPublicKeyStructure.cs @@ -0,0 +1,93 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X509 +{ + public class RsaPublicKeyStructure + : Asn1Encodable + { + private BigInteger modulus; + private BigInteger publicExponent; + + public static RsaPublicKeyStructure GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static RsaPublicKeyStructure GetInstance( + object obj) + { + if (obj == null || obj is RsaPublicKeyStructure) + { + return (RsaPublicKeyStructure) obj; + } + + if (obj is Asn1Sequence) + { + return new RsaPublicKeyStructure((Asn1Sequence) obj); + } + + throw new ArgumentException("Invalid RsaPublicKeyStructure: " + Platform.GetTypeName(obj)); + } + + public RsaPublicKeyStructure( + BigInteger modulus, + BigInteger publicExponent) + { + if (modulus == null) + throw new ArgumentNullException("modulus"); + if (publicExponent == null) + throw new ArgumentNullException("publicExponent"); + if (modulus.SignValue <= 0) + throw new ArgumentException("Not a valid RSA modulus", "modulus"); + if (publicExponent.SignValue <= 0) + throw new ArgumentException("Not a valid RSA public exponent", "publicExponent"); + + this.modulus = modulus; + this.publicExponent = publicExponent; + } + + private RsaPublicKeyStructure( + Asn1Sequence seq) + { + if (seq.Count != 2) + throw new ArgumentException("Bad sequence size: " + seq.Count); + + // Note: we are accepting technically incorrect (i.e. negative) values here + modulus = DerInteger.GetInstance(seq[0]).PositiveValue; + publicExponent = DerInteger.GetInstance(seq[1]).PositiveValue; + } + + public BigInteger Modulus + { + get { return modulus; } + } + + public BigInteger PublicExponent + { + get { return publicExponent; } + } + + /** + * This outputs the key in Pkcs1v2 format. + *
+         *      RSAPublicKey ::= Sequence {
+         *                          modulus Integer, -- n
+         *                          publicExponent Integer, -- e
+         *                      }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + return new DerSequence( + new DerInteger(Modulus), + new DerInteger(PublicExponent)); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/RSAPublicKeyStructure.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/RSAPublicKeyStructure.cs.meta new file mode 100644 index 0000000..eaf88f3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/RSAPublicKeyStructure.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5663147ad66138445a67f3c99706a1f6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/ReasonFlags.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/ReasonFlags.cs new file mode 100644 index 0000000..ad45e84 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/ReasonFlags.cs @@ -0,0 +1,45 @@ +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * The ReasonFlags object. + *
+     * ReasonFlags ::= BIT STRING {
+     *    unused(0),
+     *    keyCompromise(1),
+     *    cACompromise(2),
+     *    affiliationChanged(3),
+     *    superseded(4),
+     *    cessationOfOperation(5),
+     *    certficateHold(6)
+     * }
+     * 
+ */ + public class ReasonFlags + : DerBitString + { + public const int Unused = (1 << 7); + public const int KeyCompromise = (1 << 6); + public const int CACompromise = (1 << 5); + public const int AffiliationChanged = (1 << 4); + public const int Superseded = (1 << 3); + public const int CessationOfOperation = (1 << 2); + public const int CertificateHold = (1 << 1); + public const int PrivilegeWithdrawn = (1 << 0); + public const int AACompromise = (1 << 15); + + /** + * @param reasons - the bitwise OR of the Key Reason flags giving the + * allowed uses for the key. + */ + public ReasonFlags(int reasons) + : base(reasons) + { + } + + public ReasonFlags( + DerBitString reasons) + : base(reasons.GetBytes(), reasons.PadBits) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/ReasonFlags.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/ReasonFlags.cs.meta new file mode 100644 index 0000000..69ddc94 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/ReasonFlags.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 82d1e1671d85db6439b587f584ccfe92 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/RoleSyntax.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/RoleSyntax.cs new file mode 100644 index 0000000..b5b217b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/RoleSyntax.cs @@ -0,0 +1,224 @@ +using System; +using System.Text; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * Implementation of the RoleSyntax object as specified by the RFC3281. + * + *
+	* RoleSyntax ::= SEQUENCE {
+	*                 roleAuthority  [0] GeneralNames OPTIONAL,
+	*                 roleName       [1] GeneralName
+	*           }
+	* 
+ */ + public class RoleSyntax + : Asn1Encodable + { + private readonly GeneralNames roleAuthority; + private readonly GeneralName roleName; + + /** + * RoleSyntax factory method. + * @param obj the object used to construct an instance of + * RoleSyntax. It must be an instance of RoleSyntax + * or Asn1Sequence. + * @return the instance of RoleSyntax built from the + * supplied object. + * @throws java.lang.ArgumentException if the object passed + * to the factory is not an instance of RoleSyntax or + * Asn1Sequence. + */ + public static RoleSyntax GetInstance( + object obj) + { + if (obj is RoleSyntax) + return (RoleSyntax)obj; + + if (obj != null) + return new RoleSyntax(Asn1Sequence.GetInstance(obj)); + + return null; + } + + /** + * Constructor. + * @param roleAuthority the role authority of this RoleSyntax. + * @param roleName the role name of this RoleSyntax. + */ + public RoleSyntax( + GeneralNames roleAuthority, + GeneralName roleName) + { + if (roleName == null + || roleName.TagNo != GeneralName.UniformResourceIdentifier + || ((IAsn1String) roleName.Name).GetString().Equals("")) + { + throw new ArgumentException("the role name MUST be non empty and MUST " + + "use the URI option of GeneralName"); + } + + this.roleAuthority = roleAuthority; + this.roleName = roleName; + } + + /** + * Constructor. Invoking this constructor is the same as invoking + * new RoleSyntax(null, roleName). + * @param roleName the role name of this RoleSyntax. + */ + public RoleSyntax( + GeneralName roleName) + : this(null, roleName) + { + } + + /** + * Utility constructor. Takes a string argument representing + * the role name, builds a GeneralName to hold the role name + * and calls the constructor that takes a GeneralName. + * @param roleName + */ + public RoleSyntax( + string roleName) + : this(new GeneralName(GeneralName.UniformResourceIdentifier, + (roleName == null)? "": roleName)) + { + } + + /** + * Constructor that builds an instance of RoleSyntax by + * extracting the encoded elements from the Asn1Sequence + * object supplied. + * @param seq an instance of Asn1Sequence that holds + * the encoded elements used to build this RoleSyntax. + */ + private RoleSyntax( + Asn1Sequence seq) + { + if (seq.Count < 1 || seq.Count > 2) + { + throw new ArgumentException("Bad sequence size: " + seq.Count); + } + + for (int i = 0; i != seq.Count; i++) + { + Asn1TaggedObject taggedObject = Asn1TaggedObject.GetInstance(seq[i]); + switch (taggedObject.TagNo) + { + case 0: + roleAuthority = GeneralNames.GetInstance(taggedObject, false); + break; + case 1: + roleName = GeneralName.GetInstance(taggedObject, true); + break; + default: + throw new ArgumentException("Unknown tag in RoleSyntax"); + } + } + } + + /** + * Gets the role authority of this RoleSyntax. + * @return an instance of GeneralNames holding the + * role authority of this RoleSyntax. + */ + public GeneralNames RoleAuthority + { + get { return this.roleAuthority; } + } + + /** + * Gets the role name of this RoleSyntax. + * @return an instance of GeneralName holding the + * role name of this RoleSyntax. + */ + public GeneralName RoleName + { + get { return this.roleName; } + } + + /** + * Gets the role name as a java.lang.string object. + * @return the role name of this RoleSyntax represented as a + * string object. + */ + public string GetRoleNameAsString() + { + return ((IAsn1String) this.roleName.Name).GetString(); + } + + /** + * Gets the role authority as a string[] object. + * @return the role authority of this RoleSyntax represented as a + * string[] array. + */ + public string[] GetRoleAuthorityAsString() + { + if (roleAuthority == null) + { + return new string[0]; + } + + GeneralName[] names = roleAuthority.GetNames(); + string[] namesString = new string[names.Length]; + for(int i = 0; i < names.Length; i++) + { + Asn1Encodable asn1Value = names[i].Name; + if (asn1Value is IAsn1String) + { + namesString[i] = ((IAsn1String) asn1Value).GetString(); + } + else + { + namesString[i] = asn1Value.ToString(); + } + } + + return namesString; + } + + /** + * Implementation of the method ToAsn1Object as + * required by the superclass ASN1Encodable. + * + *
+		* RoleSyntax ::= SEQUENCE {
+		*                 roleAuthority  [0] GeneralNames OPTIONAL,
+		*                 roleName       [1] GeneralName
+		*           }
+		* 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + v.AddOptionalTagged(false, 0, roleAuthority); + v.Add(new DerTaggedObject(true, 1, roleName)); + return new DerSequence(v); + } + + public override string ToString() + { + StringBuilder buff = new StringBuilder("Name: " + this.GetRoleNameAsString() + + " - Auth: "); + + if (this.roleAuthority == null || roleAuthority.GetNames().Length == 0) + { + buff.Append("N/A"); + } + else + { + string[] names = this.GetRoleAuthorityAsString(); + buff.Append('[').Append(names[0]); + for(int i = 1; i < names.Length; i++) + { + buff.Append(", ").Append(names[i]); + } + buff.Append(']'); + } + + return buff.ToString(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/RoleSyntax.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/RoleSyntax.cs.meta new file mode 100644 index 0000000..f2b3b03 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/RoleSyntax.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 74f77168bd7c41e419bc82b46acd8dfc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/SubjectDirectoryAttributes.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/SubjectDirectoryAttributes.cs new file mode 100644 index 0000000..77923e0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/SubjectDirectoryAttributes.cs @@ -0,0 +1,142 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * This extension may contain further X.500 attributes of the subject. See also + * RFC 3039. + * + *
+	 *     SubjectDirectoryAttributes ::= Attributes
+	 *     Attributes ::= SEQUENCE SIZE (1..MAX) OF Attribute
+	 *     Attribute ::= SEQUENCE
+	 *     {
+	 *       type AttributeType
+	 *       values SET OF AttributeValue
+	 *     }
+	 *
+	 *     AttributeType ::= OBJECT IDENTIFIER
+	 *     AttributeValue ::= ANY DEFINED BY AttributeType
+	 * 
+ * + * @see org.bouncycastle.asn1.x509.X509Name for AttributeType ObjectIdentifiers. + */ + public class SubjectDirectoryAttributes + : Asn1Encodable + { + private readonly IList attributes; + + public static SubjectDirectoryAttributes GetInstance( + object obj) + { + if (obj == null || obj is SubjectDirectoryAttributes) + { + return (SubjectDirectoryAttributes) obj; + } + + if (obj is Asn1Sequence) + { + return new SubjectDirectoryAttributes((Asn1Sequence) obj); + } + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + /** + * Constructor from Asn1Sequence. + * + * The sequence is of type SubjectDirectoryAttributes: + * + *
+		 *      SubjectDirectoryAttributes ::= Attributes
+		 *      Attributes ::= SEQUENCE SIZE (1..MAX) OF Attribute
+		 *      Attribute ::= SEQUENCE
+		 *      {
+		 *        type AttributeType
+		 *        values SET OF AttributeValue
+		 *      }
+		 *
+		 *      AttributeType ::= OBJECT IDENTIFIER
+		 *      AttributeValue ::= ANY DEFINED BY AttributeType
+		 * 
+ * + * @param seq + * The ASN.1 sequence. + */ + private SubjectDirectoryAttributes( + Asn1Sequence seq) + { + this.attributes = Platform.CreateArrayList(); + foreach (object o in seq) + { + Asn1Sequence s = Asn1Sequence.GetInstance(o); + attributes.Add(AttributeX509.GetInstance(s)); + } + } + +#if !(SILVERLIGHT || PORTABLE) + [Obsolete] + public SubjectDirectoryAttributes( + ArrayList attributes) + : this((IList)attributes) + { + } +#endif + + /** + * Constructor from an ArrayList of attributes. + * + * The ArrayList consists of attributes of type {@link Attribute Attribute} + * + * @param attributes The attributes. + * + */ + public SubjectDirectoryAttributes( + IList attributes) + { + this.attributes = Platform.CreateArrayList(attributes); + } + + /** + * Produce an object suitable for an Asn1OutputStream. + * + * Returns: + * + *
+		 *      SubjectDirectoryAttributes ::= Attributes
+		 *      Attributes ::= SEQUENCE SIZE (1..MAX) OF Attribute
+		 *      Attribute ::= SEQUENCE
+		 *      {
+		 *        type AttributeType
+		 *        values SET OF AttributeValue
+		 *      }
+		 *
+		 *      AttributeType ::= OBJECT IDENTIFIER
+		 *      AttributeValue ::= ANY DEFINED BY AttributeType
+		 * 
+ * + * @return a DERObject + */ + public override Asn1Object ToAsn1Object() + { + AttributeX509[] v = new AttributeX509[attributes.Count]; + for (int i = 0; i < attributes.Count; ++i) + { + v[i] = (AttributeX509)attributes[i]; + } + return new DerSequence(v); + } + + /** + * @return Returns the attributes. + */ + public IEnumerable Attributes + { + get { return new EnumerableProxy(attributes); } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/SubjectDirectoryAttributes.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/SubjectDirectoryAttributes.cs.meta new file mode 100644 index 0000000..5dca0cf --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/SubjectDirectoryAttributes.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d1a4f49943717f849b5895ef615d1116 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/SubjectKeyIdentifier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/SubjectKeyIdentifier.cs new file mode 100644 index 0000000..bb69468 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/SubjectKeyIdentifier.cs @@ -0,0 +1,132 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * The SubjectKeyIdentifier object. + *
+     * SubjectKeyIdentifier::= OCTET STRING
+     * 
+ */ + public class SubjectKeyIdentifier + : Asn1Encodable + { + public static SubjectKeyIdentifier GetInstance(Asn1TaggedObject obj, bool explicitly) + { + return GetInstance(Asn1OctetString.GetInstance(obj, explicitly)); + } + + public static SubjectKeyIdentifier GetInstance(object obj) + { + if (obj is SubjectKeyIdentifier) + return (SubjectKeyIdentifier)obj; + if (obj is SubjectPublicKeyInfo) + return new SubjectKeyIdentifier((SubjectPublicKeyInfo)obj); + if (obj is X509Extension) + return GetInstance(X509Extension.ConvertValueToObject((X509Extension)obj)); + if (obj == null) + return null; + return new SubjectKeyIdentifier(Asn1OctetString.GetInstance(obj)); + } + + public static SubjectKeyIdentifier FromExtensions(X509Extensions extensions) + { + return GetInstance(X509Extensions.GetExtensionParsedValue(extensions, X509Extensions.SubjectKeyIdentifier)); + } + + private readonly byte[] keyIdentifier; + + public SubjectKeyIdentifier( + byte[] keyID) + { + if (keyID == null) + throw new ArgumentNullException("keyID"); + + this.keyIdentifier = Arrays.Clone(keyID); + } + + public SubjectKeyIdentifier( + Asn1OctetString keyID) + : this(keyID.GetOctets()) + { + } + + /** + * Calculates the keyIdentifier using a SHA1 hash over the BIT STRING + * from SubjectPublicKeyInfo as defined in RFC3280. + * + * @param spki the subject public key info. + */ + public SubjectKeyIdentifier( + SubjectPublicKeyInfo spki) + { + this.keyIdentifier = GetDigest(spki); + } + + public byte[] GetKeyIdentifier() + { + return Arrays.Clone(keyIdentifier); + } + + public override Asn1Object ToAsn1Object() + { + return new DerOctetString(GetKeyIdentifier()); + } + + /** + * Return a RFC 3280 type 1 key identifier. As in: + *
+		 * (1) The keyIdentifier is composed of the 160-bit SHA-1 hash of the
+		 * value of the BIT STRING subjectPublicKey (excluding the tag,
+		 * length, and number of unused bits).
+		 * 
+ * @param keyInfo the key info object containing the subjectPublicKey field. + * @return the key identifier. + */ + public static SubjectKeyIdentifier CreateSha1KeyIdentifier( + SubjectPublicKeyInfo keyInfo) + { + return new SubjectKeyIdentifier(keyInfo); + } + + /** + * Return a RFC 3280 type 2 key identifier. As in: + *
+		 * (2) The keyIdentifier is composed of a four bit type field with
+		 * the value 0100 followed by the least significant 60 bits of the
+		 * SHA-1 hash of the value of the BIT STRING subjectPublicKey.
+		 * 
+ * @param keyInfo the key info object containing the subjectPublicKey field. + * @return the key identifier. + */ + public static SubjectKeyIdentifier CreateTruncatedSha1KeyIdentifier( + SubjectPublicKeyInfo keyInfo) + { + byte[] dig = GetDigest(keyInfo); + byte[] id = new byte[8]; + + Array.Copy(dig, dig.Length - 8, id, 0, id.Length); + + id[0] &= 0x0f; + id[0] |= 0x40; + + return new SubjectKeyIdentifier(id); + } + + private static byte[] GetDigest( + SubjectPublicKeyInfo spki) + { + IDigest digest = new Sha1Digest(); + byte[] resBuf = new byte[digest.GetDigestSize()]; + + byte[] bytes = spki.PublicKeyData.GetBytes(); + digest.BlockUpdate(bytes, 0, bytes.Length); + digest.DoFinal(resBuf, 0); + return resBuf; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/SubjectKeyIdentifier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/SubjectKeyIdentifier.cs.meta new file mode 100644 index 0000000..90b4ca2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/SubjectKeyIdentifier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b564a75fd5338044cba8075415681d4d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/SubjectPublicKeyInfo.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/SubjectPublicKeyInfo.cs new file mode 100644 index 0000000..ae44a45 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/SubjectPublicKeyInfo.cs @@ -0,0 +1,115 @@ +using System; +using System.Collections; +using System.IO; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * The object that contains the public key stored in a certficate. + *

+ * The GetEncoded() method in the public keys in the JCE produces a DER + * encoded one of these.

+ */ + public class SubjectPublicKeyInfo + : Asn1Encodable + { + private readonly AlgorithmIdentifier algID; + private readonly DerBitString keyData; + + public static SubjectPublicKeyInfo GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static SubjectPublicKeyInfo GetInstance( + object obj) + { + if (obj is SubjectPublicKeyInfo) + return (SubjectPublicKeyInfo) obj; + + if (obj != null) + return new SubjectPublicKeyInfo(Asn1Sequence.GetInstance(obj)); + + return null; + } + + public SubjectPublicKeyInfo( + AlgorithmIdentifier algID, + Asn1Encodable publicKey) + { + this.keyData = new DerBitString(publicKey); + this.algID = algID; + } + + public SubjectPublicKeyInfo( + AlgorithmIdentifier algID, + byte[] publicKey) + { + this.keyData = new DerBitString(publicKey); + this.algID = algID; + } + + private SubjectPublicKeyInfo( + Asn1Sequence seq) + { + if (seq.Count != 2) + throw new ArgumentException("Bad sequence size: " + seq.Count, "seq"); + + this.algID = AlgorithmIdentifier.GetInstance(seq[0]); + this.keyData = DerBitString.GetInstance(seq[1]); + } + + public AlgorithmIdentifier AlgorithmID + { + get { return algID; } + } + + /** + * for when the public key is an encoded object - if the bitstring + * can't be decoded this routine raises an IOException. + * + * @exception IOException - if the bit string doesn't represent a Der + * encoded object. + */ + public Asn1Object ParsePublicKey() + { + return Asn1Object.FromByteArray(keyData.GetOctets()); + } + + /** + * for when the public key is an encoded object - if the bitstring + * can't be decoded this routine raises an IOException. + * + * @exception IOException - if the bit string doesn't represent a Der + * encoded object. + */ + [Obsolete("Use 'ParsePublicKey' instead")] + public Asn1Object GetPublicKey() + { + return Asn1Object.FromByteArray(keyData.GetOctets()); + } + + /** + * for when the public key is raw bits... + */ + public DerBitString PublicKeyData + { + get { return keyData; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * SubjectPublicKeyInfo ::= Sequence {
+         *                          algorithm AlgorithmIdentifier,
+         *                          publicKey BIT STRING }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + return new DerSequence(algID, keyData); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/SubjectPublicKeyInfo.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/SubjectPublicKeyInfo.cs.meta new file mode 100644 index 0000000..45e292c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/SubjectPublicKeyInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 683b61f77cb920b4c8da6c39e63a841f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/TBSCertList.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/TBSCertList.cs new file mode 100644 index 0000000..a427ba2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/TBSCertList.cs @@ -0,0 +1,275 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Asn1.X509 +{ + public class CrlEntry + : Asn1Encodable + { + internal Asn1Sequence seq; + internal DerInteger userCertificate; + internal Time revocationDate; + internal X509Extensions crlEntryExtensions; + + public CrlEntry( + Asn1Sequence seq) + { + if (seq.Count < 2 || seq.Count > 3) + { + throw new ArgumentException("Bad sequence size: " + seq.Count); + } + + this.seq = seq; + + userCertificate = DerInteger.GetInstance(seq[0]); + revocationDate = Time.GetInstance(seq[1]); + } + + public DerInteger UserCertificate + { + get { return userCertificate; } + } + + public Time RevocationDate + { + get { return revocationDate; } + } + + public X509Extensions Extensions + { + get + { + if (crlEntryExtensions == null && seq.Count == 3) + { + crlEntryExtensions = X509Extensions.GetInstance(seq[2]); + } + + return crlEntryExtensions; + } + } + + public override Asn1Object ToAsn1Object() + { + return seq; + } + } + + /** + * PKIX RFC-2459 - TbsCertList object. + *
+     * TbsCertList  ::=  Sequence  {
+     *      version                 Version OPTIONAL,
+     *                                   -- if present, shall be v2
+     *      signature               AlgorithmIdentifier,
+     *      issuer                  Name,
+     *      thisUpdate              Time,
+     *      nextUpdate              Time OPTIONAL,
+     *      revokedCertificates     Sequence OF Sequence  {
+     *           userCertificate         CertificateSerialNumber,
+     *           revocationDate          Time,
+     *           crlEntryExtensions      Extensions OPTIONAL
+     *                                         -- if present, shall be v2
+     *                                }  OPTIONAL,
+     *      crlExtensions           [0]  EXPLICIT Extensions OPTIONAL
+     *                                         -- if present, shall be v2
+     *                                }
+     * 
+ */ + public class TbsCertificateList + : Asn1Encodable + { + private class RevokedCertificatesEnumeration + : IEnumerable + { + private readonly IEnumerable en; + + internal RevokedCertificatesEnumeration( + IEnumerable en) + { + this.en = en; + } + + public IEnumerator GetEnumerator() + { + return new RevokedCertificatesEnumerator(en.GetEnumerator()); + } + + private class RevokedCertificatesEnumerator + : IEnumerator + { + private readonly IEnumerator e; + + internal RevokedCertificatesEnumerator( + IEnumerator e) + { + this.e = e; + } + + public bool MoveNext() + { + return e.MoveNext(); + } + + public void Reset() + { + e.Reset(); + } + + public object Current + { + get { return new CrlEntry(Asn1Sequence.GetInstance(e.Current)); } + } + } + } + + internal Asn1Sequence seq; + internal DerInteger version; + internal AlgorithmIdentifier signature; + internal X509Name issuer; + internal Time thisUpdate; + internal Time nextUpdate; + internal Asn1Sequence revokedCertificates; + internal X509Extensions crlExtensions; + + public static TbsCertificateList GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static TbsCertificateList GetInstance( + object obj) + { + TbsCertificateList list = obj as TbsCertificateList; + + if (obj == null || list != null) + { + return list; + } + + if (obj is Asn1Sequence) + { + return new TbsCertificateList((Asn1Sequence) obj); + } + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + internal TbsCertificateList( + Asn1Sequence seq) + { + if (seq.Count < 3 || seq.Count > 7) + { + throw new ArgumentException("Bad sequence size: " + seq.Count); + } + + int seqPos = 0; + + this.seq = seq; + + if (seq[seqPos] is DerInteger) + { + version = DerInteger.GetInstance(seq[seqPos++]); + } + else + { + version = new DerInteger(0); + } + + signature = AlgorithmIdentifier.GetInstance(seq[seqPos++]); + issuer = X509Name.GetInstance(seq[seqPos++]); + thisUpdate = Time.GetInstance(seq[seqPos++]); + + if (seqPos < seq.Count + && (seq[seqPos] is DerUtcTime + || seq[seqPos] is DerGeneralizedTime + || seq[seqPos] is Time)) + { + nextUpdate = Time.GetInstance(seq[seqPos++]); + } + + if (seqPos < seq.Count + && !(seq[seqPos] is Asn1TaggedObject)) + { + revokedCertificates = Asn1Sequence.GetInstance(seq[seqPos++]); + } + + if (seqPos < seq.Count + && seq[seqPos] is Asn1TaggedObject) + { + crlExtensions = X509Extensions.GetInstance(seq[seqPos]); + } + } + + public int Version + { + get { return version.IntValueExact + 1; } + } + + public DerInteger VersionNumber + { + get { return version; } + } + + public AlgorithmIdentifier Signature + { + get { return signature; } + } + + public X509Name Issuer + { + get { return issuer; } + } + + public Time ThisUpdate + { + get { return thisUpdate; } + } + + public Time NextUpdate + { + get { return nextUpdate; } + } + + public CrlEntry[] GetRevokedCertificates() + { + if (revokedCertificates == null) + { + return new CrlEntry[0]; + } + + CrlEntry[] entries = new CrlEntry[revokedCertificates.Count]; + + for (int i = 0; i < entries.Length; i++) + { + entries[i] = new CrlEntry(Asn1Sequence.GetInstance(revokedCertificates[i])); + } + + return entries; + } + + public IEnumerable GetRevokedCertificateEnumeration() + { + if (revokedCertificates == null) + { + return EmptyEnumerable.Instance; + } + + return new RevokedCertificatesEnumeration(revokedCertificates); + } + + public X509Extensions Extensions + { + get { return crlExtensions; } + } + + public override Asn1Object ToAsn1Object() + { + return seq; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/TBSCertList.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/TBSCertList.cs.meta new file mode 100644 index 0000000..cc7f68d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/TBSCertList.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1dd5bf3af6d6b2d4994af08efef24fbe +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/TBSCertificateStructure.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/TBSCertificateStructure.cs new file mode 100644 index 0000000..bd08d8b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/TBSCertificateStructure.cs @@ -0,0 +1,256 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * The TbsCertificate object. + *
+     * TbsCertificate ::= Sequence {
+     *      version          [ 0 ]  Version DEFAULT v1(0),
+     *      serialNumber            CertificateSerialNumber,
+     *      signature               AlgorithmIdentifier,
+     *      issuer                  Name,
+     *      validity                Validity,
+     *      subject                 Name,
+     *      subjectPublicKeyInfo    SubjectPublicKeyInfo,
+     *      issuerUniqueID    [ 1 ] IMPLICIT UniqueIdentifier OPTIONAL,
+     *      subjectUniqueID   [ 2 ] IMPLICIT UniqueIdentifier OPTIONAL,
+     *      extensions        [ 3 ] Extensions OPTIONAL
+     *      }
+     * 
+ *

+ * Note: issuerUniqueID and subjectUniqueID are both deprecated by the IETF. This class + * will parse them, but you really shouldn't be creating new ones.

+ */ + public class TbsCertificateStructure + : Asn1Encodable + { + internal Asn1Sequence seq; + internal DerInteger version; + internal DerInteger serialNumber; + internal AlgorithmIdentifier signature; + internal X509Name issuer; + internal Time startDate, endDate; + internal X509Name subject; + internal SubjectPublicKeyInfo subjectPublicKeyInfo; + internal DerBitString issuerUniqueID; + internal DerBitString subjectUniqueID; + internal X509Extensions extensions; + + public static TbsCertificateStructure GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static TbsCertificateStructure GetInstance( + object obj) + { + if (obj is TbsCertificateStructure) + return (TbsCertificateStructure) obj; + + if (obj != null) + return new TbsCertificateStructure(Asn1Sequence.GetInstance(obj)); + + return null; + } + + internal TbsCertificateStructure( + Asn1Sequence seq) + { + int seqStart = 0; + + this.seq = seq; + + // + // some certficates don't include a version number - we assume v1 + // + if (seq[0] is Asn1TaggedObject) + { + version = DerInteger.GetInstance((Asn1TaggedObject)seq[0], true); + } + else + { + seqStart = -1; // field 0 is missing! + version = new DerInteger(0); + } + + bool isV1 = false; + bool isV2 = false; + + if (version.HasValue(0)) + { + isV1 = true; + } + else if (version.HasValue(1)) + { + isV2 = true; + } + else if (!version.HasValue(2)) + { + throw new ArgumentException("version number not recognised"); + } + + serialNumber = DerInteger.GetInstance(seq[seqStart + 1]); + + signature = AlgorithmIdentifier.GetInstance(seq[seqStart + 2]); + issuer = X509Name.GetInstance(seq[seqStart + 3]); + + // + // before and after dates + // + Asn1Sequence dates = (Asn1Sequence)seq[seqStart + 4]; + + startDate = Time.GetInstance(dates[0]); + endDate = Time.GetInstance(dates[1]); + + subject = X509Name.GetInstance(seq[seqStart + 5]); + + // + // public key info. + // + subjectPublicKeyInfo = SubjectPublicKeyInfo.GetInstance(seq[seqStart + 6]); + + int extras = seq.Count - (seqStart + 6) - 1; + if (extras != 0 && isV1) + throw new ArgumentException("version 1 certificate contains extra data"); + + while (extras > 0) + { + Asn1TaggedObject extra = Asn1TaggedObject.GetInstance(seq[seqStart + 6 + extras]); + switch (extra.TagNo) + { + case 1: + { + issuerUniqueID = DerBitString.GetInstance(extra, false); + break; + } + case 2: + { + subjectUniqueID = DerBitString.GetInstance(extra, false); + break; + } + case 3: + { + if (isV2) + throw new ArgumentException("version 2 certificate cannot contain extensions"); + + extensions = X509Extensions.GetInstance(Asn1Sequence.GetInstance(extra, true)); + break; + } + default: + { + throw new ArgumentException("Unknown tag encountered in structure: " + extra.TagNo); + } + } + extras--; + } + } + + public int Version + { + get { return version.IntValueExact + 1; } + } + + public DerInteger VersionNumber + { + get { return version; } + } + + public DerInteger SerialNumber + { + get { return serialNumber; } + } + + public AlgorithmIdentifier Signature + { + get { return signature; } + } + + public X509Name Issuer + { + get { return issuer; } + } + + public Time StartDate + { + get { return startDate; } + } + + public Time EndDate + { + get { return endDate; } + } + + public X509Name Subject + { + get { return subject; } + } + + public SubjectPublicKeyInfo SubjectPublicKeyInfo + { + get { return subjectPublicKeyInfo; } + } + + public DerBitString IssuerUniqueID + { + get { return issuerUniqueID; } + } + + public DerBitString SubjectUniqueID + { + get { return subjectUniqueID; } + } + + public X509Extensions Extensions + { + get { return extensions; } + } + + public override Asn1Object ToAsn1Object() + { + string property = Platform.GetEnvironmentVariable("Org.BouncyCastle.X509.Allow_Non-DER_TBSCert"); + if (null == property || Platform.EqualsIgnoreCase("true", property)) + return seq; + + Asn1EncodableVector v = new Asn1EncodableVector(); + + // DEFAULT Zero + if (!version.HasValue(0)) + { + v.Add(new DerTaggedObject(true, 0, version)); + } + + v.Add(serialNumber, signature, issuer); + + // + // before and after dates + // + v.Add(new DerSequence(startDate, endDate)); + + if (subject != null) + { + v.Add(subject); + } + else + { + v.Add(DerSequence.Empty); + } + + v.Add(subjectPublicKeyInfo); + + // Note: implicit tag + v.AddOptionalTagged(false, 1, issuerUniqueID); + + // Note: implicit tag + v.AddOptionalTagged(false, 2, subjectUniqueID); + + v.AddOptionalTagged(true, 3, extensions); + + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/TBSCertificateStructure.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/TBSCertificateStructure.cs.meta new file mode 100644 index 0000000..417623e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/TBSCertificateStructure.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 35b2fe8d6964e82419e03bb9ee9b8b41 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/Target.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/Target.cs new file mode 100644 index 0000000..7c4f9db --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/Target.cs @@ -0,0 +1,141 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * Target structure used in target information extension for attribute + * certificates from RFC 3281. + * + *
+	 *     Target  ::= CHOICE {
+	 *       targetName          [0] GeneralName,
+	 *       targetGroup         [1] GeneralName,
+	 *       targetCert          [2] TargetCert
+	 *     }
+	 * 
+ * + *

+ * The targetCert field is currently not supported and must not be used + * according to RFC 3281.

+ */ + public class Target + : Asn1Encodable, IAsn1Choice + { + public enum Choice + { + Name = 0, + Group = 1 + }; + + private readonly GeneralName targetName; + private readonly GeneralName targetGroup; + + /** + * Creates an instance of a Target from the given object. + *

+ * obj can be a Target or a {@link Asn1TaggedObject}

+ * + * @param obj The object. + * @return A Target instance. + * @throws ArgumentException if the given object cannot be + * interpreted as Target. + */ + public static Target GetInstance( + object obj) + { + if (obj is Target) + { + return (Target) obj; + } + + if (obj is Asn1TaggedObject) + { + return new Target((Asn1TaggedObject) obj); + } + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + /** + * Constructor from Asn1TaggedObject. + * + * @param tagObj The tagged object. + * @throws ArgumentException if the encoding is wrong. + */ + private Target( + Asn1TaggedObject tagObj) + { + switch ((Choice) tagObj.TagNo) + { + case Choice.Name: // GeneralName is already a choice so explicit + targetName = GeneralName.GetInstance(tagObj, true); + break; + case Choice.Group: + targetGroup = GeneralName.GetInstance(tagObj, true); + break; + default: + throw new ArgumentException("unknown tag: " + tagObj.TagNo); + } + } + + /** + * Constructor from given details. + *

+ * Exactly one of the parameters must be not null.

+ * + * @param type the choice type to apply to the name. + * @param name the general name. + * @throws ArgumentException if type is invalid. + */ + public Target( + Choice type, + GeneralName name) + : this(new DerTaggedObject((int) type, name)) + { + } + + /** + * @return Returns the targetGroup. + */ + public virtual GeneralName TargetGroup + { + get { return targetGroup; } + } + + /** + * @return Returns the targetName. + */ + public virtual GeneralName TargetName + { + get { return targetName; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + * + * Returns: + * + *
+		 *     Target  ::= CHOICE {
+		 *       targetName          [0] GeneralName,
+		 *       targetGroup         [1] GeneralName,
+		 *       targetCert          [2] TargetCert
+		 *     }
+		 * 
+ * + * @return an Asn1Object + */ + public override Asn1Object ToAsn1Object() + { + // GeneralName is a choice already so most be explicitly tagged + if (targetName != null) + { + return new DerTaggedObject(true, 0, targetName); + } + + return new DerTaggedObject(true, 1, targetGroup); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/Target.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/Target.cs.meta new file mode 100644 index 0000000..af85d86 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/Target.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f50fdc6d76a4932479c9d9103fa8290c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/TargetInformation.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/TargetInformation.cs new file mode 100644 index 0000000..2bf2189 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/TargetInformation.cs @@ -0,0 +1,125 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * Target information extension for attributes certificates according to RFC + * 3281. + * + *
+	 *           SEQUENCE OF Targets
+	 * 
+ * + */ + public class TargetInformation + : Asn1Encodable + { + private readonly Asn1Sequence targets; + + /** + * Creates an instance of a TargetInformation from the given object. + *

+ * obj can be a TargetInformation or a {@link Asn1Sequence}

+ * + * @param obj The object. + * @return A TargetInformation instance. + * @throws ArgumentException if the given object cannot be interpreted as TargetInformation. + */ + public static TargetInformation GetInstance( + object obj) + { + if (obj is TargetInformation) + { + return (TargetInformation) obj; + } + + if (obj is Asn1Sequence) + { + return new TargetInformation((Asn1Sequence) obj); + } + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + /** + * Constructor from a Asn1Sequence. + * + * @param seq The Asn1Sequence. + * @throws ArgumentException if the sequence does not contain + * correctly encoded Targets elements. + */ + private TargetInformation( + Asn1Sequence targets) + { + this.targets = targets; + } + + /** + * Returns the targets in this target information extension. + *

+ * The ArrayList is cloned before it is returned.

+ * + * @return Returns the targets. + */ + public virtual Targets[] GetTargetsObjects() + { + Targets[] result = new Targets[targets.Count]; + + for (int i = 0; i < targets.Count; ++i) + { + result[i] = Targets.GetInstance(targets[i]); + } + + return result; + } + + /** + * Constructs a target information from a single targets element. + * According to RFC 3281 only one targets element must be produced. + * + * @param targets A Targets instance. + */ + public TargetInformation( + Targets targets) + { + this.targets = new DerSequence(targets); + } + + /** + * According to RFC 3281 only one targets element must be produced. If + * multiple targets are given they must be merged in + * into one targets element. + * + * @param targets An array with {@link Targets}. + */ + public TargetInformation( + Target[] targets) + : this(new Targets(targets)) + { + } + + /** + * Produce an object suitable for an Asn1OutputStream. + * + * Returns: + * + *
+		 *          SEQUENCE OF Targets
+		 * 
+ * + *

+ * According to RFC 3281 only one targets element must be produced. If + * multiple targets are given in the constructor they are merged into one + * targets element. If this was produced from a + * {@link Org.BouncyCastle.Asn1.Asn1Sequence} the encoding is kept.

+ * + * @return an Asn1Object + */ + public override Asn1Object ToAsn1Object() + { + return targets; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/TargetInformation.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/TargetInformation.cs.meta new file mode 100644 index 0000000..d1822f6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/TargetInformation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b402a1e8d82411449a86a931a10ef099 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/Targets.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/Targets.cs new file mode 100644 index 0000000..0387e1f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/Targets.cs @@ -0,0 +1,123 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * Targets structure used in target information extension for attribute + * certificates from RFC 3281. + * + *
+	 *            Targets ::= SEQUENCE OF Target
+	 *           
+	 *            Target  ::= CHOICE {
+	 *              targetName          [0] GeneralName,
+	 *              targetGroup         [1] GeneralName,
+	 *              targetCert          [2] TargetCert
+	 *            }
+	 *           
+	 *            TargetCert  ::= SEQUENCE {
+	 *              targetCertificate    IssuerSerial,
+	 *              targetName           GeneralName OPTIONAL,
+	 *              certDigestInfo       ObjectDigestInfo OPTIONAL
+	 *            }
+	 * 
+ * + * @see org.bouncycastle.asn1.x509.Target + * @see org.bouncycastle.asn1.x509.TargetInformation + */ + public class Targets + : Asn1Encodable + { + private readonly Asn1Sequence targets; + + /** + * Creates an instance of a Targets from the given object. + *

+ * obj can be a Targets or a {@link Asn1Sequence}

+ * + * @param obj The object. + * @return A Targets instance. + * @throws ArgumentException if the given object cannot be interpreted as Target. + */ + public static Targets GetInstance( + object obj) + { + if (obj is Targets) + { + return (Targets) obj; + } + + if (obj is Asn1Sequence) + { + return new Targets((Asn1Sequence) obj); + } + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + /** + * Constructor from Asn1Sequence. + * + * @param targets The ASN.1 SEQUENCE. + * @throws ArgumentException if the contents of the sequence are + * invalid. + */ + private Targets( + Asn1Sequence targets) + { + this.targets = targets; + } + + /** + * Constructor from given targets. + *

+ * The ArrayList is copied.

+ * + * @param targets An ArrayList of {@link Target}s. + * @see Target + * @throws ArgumentException if the ArrayList contains not only Targets. + */ + public Targets( + Target[] targets) + { + this.targets = new DerSequence(targets); + } + + /** + * Returns the targets in an ArrayList. + *

+ * The ArrayList is cloned before it is returned.

+ * + * @return Returns the targets. + */ + public virtual Target[] GetTargets() + { + Target[] result = new Target[targets.Count]; + + for (int i = 0; i < targets.Count; ++i) + { + result[i] = Target.GetInstance(targets[i]); + } + + return result; + } + + /** + * Produce an object suitable for an Asn1OutputStream. + * + * Returns: + * + *
+		 *            Targets ::= SEQUENCE OF Target
+		 * 
+ * + * @return an Asn1Object + */ + public override Asn1Object ToAsn1Object() + { + return targets; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/Targets.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/Targets.cs.meta new file mode 100644 index 0000000..50721f9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/Targets.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 678b101a28687664ca5b0b3872227f41 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/Time.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/Time.cs new file mode 100644 index 0000000..fa3936d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/Time.cs @@ -0,0 +1,122 @@ +using System; +using System.Globalization; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X509 +{ + public class Time + : Asn1Encodable, IAsn1Choice + { + private readonly Asn1Object time; + + public static Time GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(obj.GetObject()); + } + + public Time( + Asn1Object time) + { + if (time == null) + throw new ArgumentNullException("time"); + if (!(time is DerUtcTime) && !(time is DerGeneralizedTime)) + throw new ArgumentException("unknown object passed to Time"); + + this.time = time; + } + + /** + * creates a time object from a given date - if the date is between 1950 + * and 2049 a UTCTime object is Generated, otherwise a GeneralizedTime + * is used. + */ + public Time( + DateTime date) + { +#if PORTABLE + string d = date.ToUniversalTime().ToString("yyyyMMddHHmmss", CultureInfo.InvariantCulture) + "Z"; +#else + string d = date.ToString("yyyyMMddHHmmss", CultureInfo.InvariantCulture) + "Z"; +#endif + + int year = int.Parse(d.Substring(0, 4)); + + if (year < 1950 || year > 2049) + { + time = new DerGeneralizedTime(d); + } + else + { + time = new DerUtcTime(d.Substring(2)); + } + } + + public static Time GetInstance( + object obj) + { + if (obj == null || obj is Time) + return (Time)obj; + if (obj is DerUtcTime) + return new Time((DerUtcTime)obj); + if (obj is DerGeneralizedTime) + return new Time((DerGeneralizedTime)obj); + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + public string GetTime() + { + if (time is DerUtcTime) + { + return ((DerUtcTime) time).AdjustedTimeString; + } + + return ((DerGeneralizedTime) time).GetTime(); + } + + /// + /// Return our time as DateTime. + /// + /// A date time. + public DateTime ToDateTime() + { + try + { + if (time is DerUtcTime) + { + return ((DerUtcTime)time).ToAdjustedDateTime(); + } + else + { + return ((DerGeneralizedTime)time).ToDateTime(); + } + } + catch (FormatException e) + { + // this should never happen + throw new InvalidOperationException("invalid date string: " + e.Message); + } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * Time ::= CHOICE {
+         *             utcTime        UTCTime,
+         *             generalTime    GeneralizedTime }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + return time; + } + + public override string ToString() + { + return GetTime(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/Time.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/Time.cs.meta new file mode 100644 index 0000000..d1a4443 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/Time.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1b213e87975c9504095ccca5a7952587 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/UserNotice.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/UserNotice.cs new file mode 100644 index 0000000..6311c76 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/UserNotice.cs @@ -0,0 +1,120 @@ +using System; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * UserNotice class, used in + * CertificatePolicies X509 extensions (in policy + * qualifiers). + *
+     * UserNotice ::= Sequence {
+     *      noticeRef        NoticeReference OPTIONAL,
+     *      explicitText     DisplayText OPTIONAL}
+     *
+     * 
+ * + * @see PolicyQualifierId + * @see PolicyInformation + */ + public class UserNotice + : Asn1Encodable + { + private readonly NoticeReference noticeRef; + private readonly DisplayText explicitText; + + /** + * Creates a new UserNotice instance. + * + * @param noticeRef a NoticeReference value + * @param explicitText a DisplayText value + */ + public UserNotice( + NoticeReference noticeRef, + DisplayText explicitText) + { + this.noticeRef = noticeRef; + this.explicitText = explicitText; + } + + /** + * Creates a new UserNotice instance. + * + * @param noticeRef a NoticeReference value + * @param str the explicitText field as a string. + */ + public UserNotice( + NoticeReference noticeRef, + string str) + : this(noticeRef, new DisplayText(str)) + { + } + + /** + * Creates a new UserNotice instance. + *

Useful from reconstructing a UserNotice instance + * from its encodable/encoded form. + * + * @param as an ASN1Sequence value obtained from either + * calling @{link toASN1Object()} for a UserNotice + * instance or from parsing it from a DER-encoded stream.

+ */ + [Obsolete("Use GetInstance() instead")] + public UserNotice( + Asn1Sequence seq) + { + if (seq.Count == 2) + { + noticeRef = NoticeReference.GetInstance(seq[0]); + explicitText = DisplayText.GetInstance(seq[1]); + } + else if (seq.Count == 1) + { + if (seq[0].ToAsn1Object() is Asn1Sequence) + { + noticeRef = NoticeReference.GetInstance(seq[0]); + explicitText = null; + } + else + { + noticeRef = null; + explicitText = DisplayText.GetInstance(seq[0]); + } + } + else if (seq.Count == 0) + { + noticeRef = null; // neither field set! + explicitText = null; + } + else + { + throw new ArgumentException("Bad sequence size: " + seq.Count); + } + } + + public static UserNotice GetInstance(object obj) + { + if (obj is UserNotice) + return (UserNotice)obj; + if (obj == null) + return null; + return new UserNotice(Asn1Sequence.GetInstance(obj)); + } + + public virtual NoticeReference NoticeRef + { + get { return noticeRef; } + } + + public virtual DisplayText ExplicitText + { + get { return explicitText; } + } + + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + v.AddOptional(noticeRef, explicitText); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/UserNotice.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/UserNotice.cs.meta new file mode 100644 index 0000000..7a3b369 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/UserNotice.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4c9acedba17c89d4bbf3916649c77345 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/V1TBSCertificateGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/V1TBSCertificateGenerator.cs new file mode 100644 index 0000000..20b525a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/V1TBSCertificateGenerator.cs @@ -0,0 +1,108 @@ +using System; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * Generator for Version 1 TbsCertificateStructures. + *
+     * TbsCertificate ::= Sequence {
+     *      version          [ 0 ]  Version DEFAULT v1(0),
+     *      serialNumber            CertificateSerialNumber,
+     *      signature               AlgorithmIdentifier,
+     *      issuer                  Name,
+     *      validity                Validity,
+     *      subject                 Name,
+     *      subjectPublicKeyInfo    SubjectPublicKeyInfo,
+     *      }
+     * 
+ * + */ + public class V1TbsCertificateGenerator + { + internal DerTaggedObject version = new DerTaggedObject(0, new DerInteger(0)); + internal DerInteger serialNumber; + internal AlgorithmIdentifier signature; + internal X509Name issuer; + internal Time startDate, endDate; + internal X509Name subject; + internal SubjectPublicKeyInfo subjectPublicKeyInfo; + + public V1TbsCertificateGenerator() + { + } + + public void SetSerialNumber( + DerInteger serialNumber) + { + this.serialNumber = serialNumber; + } + + public void SetSignature( + AlgorithmIdentifier signature) + { + this.signature = signature; + } + + public void SetIssuer( + X509Name issuer) + { + this.issuer = issuer; + } + + public void SetStartDate( + Time startDate) + { + this.startDate = startDate; + } + + public void SetStartDate( + DerUtcTime startDate) + { + this.startDate = new Time(startDate); + } + + public void SetEndDate( + Time endDate) + { + this.endDate = endDate; + } + + public void SetEndDate( + DerUtcTime endDate) + { + this.endDate = new Time(endDate); + } + + public void SetSubject( + X509Name subject) + { + this.subject = subject; + } + + public void SetSubjectPublicKeyInfo( + SubjectPublicKeyInfo pubKeyInfo) + { + this.subjectPublicKeyInfo = pubKeyInfo; + } + + public TbsCertificateStructure GenerateTbsCertificate() + { + if ((serialNumber == null) || (signature == null) + || (issuer == null) || (startDate == null) || (endDate == null) + || (subject == null) || (subjectPublicKeyInfo == null)) + { + throw new InvalidOperationException("not all mandatory fields set in V1 TBScertificate generator"); + } + + return new TbsCertificateStructure( + new DerSequence( + //version, - not required as default value + serialNumber, + signature, + issuer, + new DerSequence(startDate, endDate), // before and after dates + subject, + subjectPublicKeyInfo)); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/V1TBSCertificateGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/V1TBSCertificateGenerator.cs.meta new file mode 100644 index 0000000..42a22af --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/V1TBSCertificateGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ae12024932590cf4d8845ca8b953e6e9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/V2AttributeCertificateInfoGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/V2AttributeCertificateInfoGenerator.cs new file mode 100644 index 0000000..02580b5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/V2AttributeCertificateInfoGenerator.cs @@ -0,0 +1,137 @@ +using System; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * Generator for Version 2 AttributeCertificateInfo + *
+     * AttributeCertificateInfo ::= Sequence {
+     *       version              AttCertVersion -- version is v2,
+     *       holder               Holder,
+     *       issuer               AttCertIssuer,
+     *       signature            AlgorithmIdentifier,
+     *       serialNumber         CertificateSerialNumber,
+     *       attrCertValidityPeriod   AttCertValidityPeriod,
+     *       attributes           Sequence OF Attr,
+     *       issuerUniqueID       UniqueIdentifier OPTIONAL,
+     *       extensions           Extensions OPTIONAL
+     * }
+     * 
+ * + */ + public class V2AttributeCertificateInfoGenerator + { + internal DerInteger version; + internal Holder holder; + internal AttCertIssuer issuer; + internal AlgorithmIdentifier signature; + internal DerInteger serialNumber; +// internal AttCertValidityPeriod attrCertValidityPeriod; + internal Asn1EncodableVector attributes; + internal DerBitString issuerUniqueID; + internal X509Extensions extensions; + internal DerGeneralizedTime startDate, endDate; + + public V2AttributeCertificateInfoGenerator() + { + this.version = new DerInteger(1); + attributes = new Asn1EncodableVector(); + } + + public void SetHolder( + Holder holder) + { + this.holder = holder; + } + + public void AddAttribute( + string oid, + Asn1Encodable value) + { + attributes.Add(new AttributeX509(new DerObjectIdentifier(oid), new DerSet(value))); + } + + /** + * @param attribute + */ + public void AddAttribute(AttributeX509 attribute) + { + attributes.Add(attribute); + } + + public void SetSerialNumber( + DerInteger serialNumber) + { + this.serialNumber = serialNumber; + } + + public void SetSignature( + AlgorithmIdentifier signature) + { + this.signature = signature; + } + + public void SetIssuer( + AttCertIssuer issuer) + { + this.issuer = issuer; + } + + public void SetStartDate( + DerGeneralizedTime startDate) + { + this.startDate = startDate; + } + + public void SetEndDate( + DerGeneralizedTime endDate) + { + this.endDate = endDate; + } + + public void SetIssuerUniqueID( + DerBitString issuerUniqueID) + { + this.issuerUniqueID = issuerUniqueID; + } + + public void SetExtensions( + X509Extensions extensions) + { + this.extensions = extensions; + } + + public AttributeCertificateInfo GenerateAttributeCertificateInfo() + { + if ((serialNumber == null) || (signature == null) + || (issuer == null) || (startDate == null) || (endDate == null) + || (holder == null) || (attributes == null)) + { + throw new InvalidOperationException("not all mandatory fields set in V2 AttributeCertificateInfo generator"); + } + + Asn1EncodableVector v = new Asn1EncodableVector( + version, holder, issuer, signature, serialNumber); + + // + // before and after dates => AttCertValidityPeriod + // + v.Add(new AttCertValidityPeriod(startDate, endDate)); + + // Attributes + v.Add(new DerSequence(attributes)); + + if (issuerUniqueID != null) + { + v.Add(issuerUniqueID); + } + + if (extensions != null) + { + v.Add(extensions); + } + + return AttributeCertificateInfo.GetInstance(new DerSequence(v)); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/V2AttributeCertificateInfoGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/V2AttributeCertificateInfoGenerator.cs.meta new file mode 100644 index 0000000..83ca3b7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/V2AttributeCertificateInfoGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bbe2622f229c0df43ae88618e9117b2a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/V2Form.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/V2Form.cs new file mode 100644 index 0000000..53475ff --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/V2Form.cs @@ -0,0 +1,124 @@ +using System; + +namespace Org.BouncyCastle.Asn1.X509 +{ + public class V2Form + : Asn1Encodable + { + internal GeneralNames issuerName; + internal IssuerSerial baseCertificateID; + internal ObjectDigestInfo objectDigestInfo; + + public static V2Form GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static V2Form GetInstance(object obj) + { + if (obj is V2Form) + return (V2Form)obj; + if (obj != null) + return new V2Form(Asn1Sequence.GetInstance(obj)); + return null; + } + + public V2Form(GeneralNames issuerName) + : this(issuerName, null, null) + { + } + + public V2Form(GeneralNames issuerName, IssuerSerial baseCertificateID) + : this(issuerName, baseCertificateID, null) + { + } + + public V2Form(GeneralNames issuerName, ObjectDigestInfo objectDigestInfo) + : this(issuerName, null, objectDigestInfo) + { + } + + public V2Form( + GeneralNames issuerName, + IssuerSerial baseCertificateID, + ObjectDigestInfo objectDigestInfo) + { + this.issuerName = issuerName; + this.baseCertificateID = baseCertificateID; + this.objectDigestInfo = objectDigestInfo; + } + + private V2Form( + Asn1Sequence seq) + { + if (seq.Count > 3) + { + throw new ArgumentException("Bad sequence size: " + seq.Count); + } + + int index = 0; + + if (!(seq[0] is Asn1TaggedObject)) + { + index++; + this.issuerName = GeneralNames.GetInstance(seq[0]); + } + + for (int i = index; i != seq.Count; i++) + { + Asn1TaggedObject o = Asn1TaggedObject.GetInstance(seq[i]); + if (o.TagNo == 0) + { + baseCertificateID = IssuerSerial.GetInstance(o, false); + } + else if (o.TagNo == 1) + { + objectDigestInfo = ObjectDigestInfo.GetInstance(o, false); + } + else + { + throw new ArgumentException("Bad tag number: " + o.TagNo); + } + } + } + + public GeneralNames IssuerName + { + get { return issuerName; } + } + + public IssuerSerial BaseCertificateID + { + get { return baseCertificateID; } + } + + public ObjectDigestInfo ObjectDigestInfo + { + get { return objectDigestInfo; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         *  V2Form ::= Sequence {
+         *       issuerName            GeneralNames  OPTIONAL,
+         *       baseCertificateID     [0] IssuerSerial  OPTIONAL,
+         *       objectDigestInfo      [1] ObjectDigestInfo  OPTIONAL
+         *         -- issuerName MUST be present in this profile
+         *         -- baseCertificateID and objectDigestInfo MUST NOT
+         *         -- be present in this profile
+         *  }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + v.AddOptional(issuerName); + v.AddOptionalTagged(false, 0, baseCertificateID); + v.AddOptionalTagged(false, 1, objectDigestInfo); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/V2Form.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/V2Form.cs.meta new file mode 100644 index 0000000..2528990 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/V2Form.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cf1bafc88c6c3eb40aff1f3c5022164b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/V2TBSCertListGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/V2TBSCertListGenerator.cs new file mode 100644 index 0000000..2c92918 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/V2TBSCertListGenerator.cs @@ -0,0 +1,201 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * Generator for Version 2 TbsCertList structures. + *
+     *  TbsCertList  ::=  Sequence  {
+     *       version                 Version OPTIONAL,
+     *                                    -- if present, shall be v2
+     *       signature               AlgorithmIdentifier,
+     *       issuer                  Name,
+     *       thisUpdate              Time,
+     *       nextUpdate              Time OPTIONAL,
+     *       revokedCertificates     Sequence OF Sequence  {
+     *            userCertificate         CertificateSerialNumber,
+     *            revocationDate          Time,
+     *            crlEntryExtensions      Extensions OPTIONAL
+     *                                          -- if present, shall be v2
+     *                                 }  OPTIONAL,
+     *       crlExtensions           [0]  EXPLICIT Extensions OPTIONAL
+     *                                          -- if present, shall be v2
+     *                                 }
+     * 
+ * + * Note: This class may be subject to change + */ + public class V2TbsCertListGenerator + { + private DerInteger version = new DerInteger(1); + private AlgorithmIdentifier signature; + private X509Name issuer; + private Time thisUpdate, nextUpdate; + private X509Extensions extensions; + private IList crlEntries; + + public V2TbsCertListGenerator() + { + } + + public void SetSignature( + AlgorithmIdentifier signature) + { + this.signature = signature; + } + + public void SetIssuer( + X509Name issuer) + { + this.issuer = issuer; + } + + public void SetThisUpdate( + DerUtcTime thisUpdate) + { + this.thisUpdate = new Time(thisUpdate); + } + + public void SetNextUpdate( + DerUtcTime nextUpdate) + { + this.nextUpdate = (nextUpdate != null) + ? new Time(nextUpdate) + : null; + } + + public void SetThisUpdate( + Time thisUpdate) + { + this.thisUpdate = thisUpdate; + } + + public void SetNextUpdate( + Time nextUpdate) + { + this.nextUpdate = nextUpdate; + } + + public void AddCrlEntry( + Asn1Sequence crlEntry) + { + if (crlEntries == null) + { + crlEntries = Platform.CreateArrayList(); + } + + crlEntries.Add(crlEntry); + } + + public void AddCrlEntry(DerInteger userCertificate, DerUtcTime revocationDate, int reason) + { + AddCrlEntry(userCertificate, new Time(revocationDate), reason); + } + + public void AddCrlEntry(DerInteger userCertificate, Time revocationDate, int reason) + { + AddCrlEntry(userCertificate, revocationDate, reason, null); + } + + public void AddCrlEntry(DerInteger userCertificate, Time revocationDate, int reason, + DerGeneralizedTime invalidityDate) + { + IList extOids = Platform.CreateArrayList(); + IList extValues = Platform.CreateArrayList(); + + if (reason != 0) + { + CrlReason crlReason = new CrlReason(reason); + + try + { + extOids.Add(X509Extensions.ReasonCode); + extValues.Add(new X509Extension(false, new DerOctetString(crlReason.GetEncoded()))); + } + catch (IOException e) + { + throw new ArgumentException("error encoding reason: " + e); + } + } + + if (invalidityDate != null) + { + try + { + extOids.Add(X509Extensions.InvalidityDate); + extValues.Add(new X509Extension(false, new DerOctetString(invalidityDate.GetEncoded()))); + } + catch (IOException e) + { + throw new ArgumentException("error encoding invalidityDate: " + e); + } + } + + if (extOids.Count != 0) + { + AddCrlEntry(userCertificate, revocationDate, new X509Extensions(extOids, extValues)); + } + else + { + AddCrlEntry(userCertificate, revocationDate, null); + } + } + + public void AddCrlEntry(DerInteger userCertificate, Time revocationDate, X509Extensions extensions) + { + Asn1EncodableVector v = new Asn1EncodableVector( + userCertificate, revocationDate); + + if (extensions != null) + { + v.Add(extensions); + } + + AddCrlEntry(new DerSequence(v)); + } + + public void SetExtensions( + X509Extensions extensions) + { + this.extensions = extensions; + } + + public TbsCertificateList GenerateTbsCertList() + { + if ((signature == null) || (issuer == null) || (thisUpdate == null)) + { + throw new InvalidOperationException("Not all mandatory fields set in V2 TbsCertList generator."); + } + + Asn1EncodableVector v = new Asn1EncodableVector( + version, signature, issuer, thisUpdate); + + if (nextUpdate != null) + { + v.Add(nextUpdate); + } + + // Add CRLEntries if they exist + if (crlEntries != null) + { + Asn1Sequence[] certs = new Asn1Sequence[crlEntries.Count]; + for (int i = 0; i < crlEntries.Count; ++i) + { + certs[i] = (Asn1Sequence)crlEntries[i]; + } + v.Add(new DerSequence(certs)); + } + + if (extensions != null) + { + v.Add(new DerTaggedObject(0, extensions)); + } + + return new TbsCertificateList(new DerSequence(v)); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/V2TBSCertListGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/V2TBSCertListGenerator.cs.meta new file mode 100644 index 0000000..7aa312c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/V2TBSCertListGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 964463435c87eb746b39a8656a712a63 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/V3TBSCertificateGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/V3TBSCertificateGenerator.cs new file mode 100644 index 0000000..beb469a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/V3TBSCertificateGenerator.cs @@ -0,0 +1,168 @@ +using System; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * Generator for Version 3 TbsCertificateStructures. + *
+     * TbsCertificate ::= Sequence {
+     *      version          [ 0 ]  Version DEFAULT v1(0),
+     *      serialNumber            CertificateSerialNumber,
+     *      signature               AlgorithmIdentifier,
+     *      issuer                  Name,
+     *      validity                Validity,
+     *      subject                 Name,
+     *      subjectPublicKeyInfo    SubjectPublicKeyInfo,
+     *      issuerUniqueID    [ 1 ] IMPLICIT UniqueIdentifier OPTIONAL,
+     *      subjectUniqueID   [ 2 ] IMPLICIT UniqueIdentifier OPTIONAL,
+     *      extensions        [ 3 ] Extensions OPTIONAL
+     *      }
+     * 
+ * + */ + public class V3TbsCertificateGenerator + { + internal DerTaggedObject version = new DerTaggedObject(0, new DerInteger(2)); + internal DerInteger serialNumber; + internal AlgorithmIdentifier signature; + internal X509Name issuer; + internal Time startDate, endDate; + internal X509Name subject; + internal SubjectPublicKeyInfo subjectPublicKeyInfo; + internal X509Extensions extensions; + + private bool altNamePresentAndCritical; + private DerBitString issuerUniqueID; + private DerBitString subjectUniqueID; + + public V3TbsCertificateGenerator() + { + } + + public void SetSerialNumber( + DerInteger serialNumber) + { + this.serialNumber = serialNumber; + } + + public void SetSignature( + AlgorithmIdentifier signature) + { + this.signature = signature; + } + + public void SetIssuer( + X509Name issuer) + { + this.issuer = issuer; + } + + public void SetStartDate( + DerUtcTime startDate) + { + this.startDate = new Time(startDate); + } + + public void SetStartDate( + Time startDate) + { + this.startDate = startDate; + } + + public void SetEndDate( + DerUtcTime endDate) + { + this.endDate = new Time(endDate); + } + + public void SetEndDate( + Time endDate) + { + this.endDate = endDate; + } + + public void SetSubject( + X509Name subject) + { + this.subject = subject; + } + + public void SetIssuerUniqueID( + DerBitString uniqueID) + { + this.issuerUniqueID = uniqueID; + } + + public void SetSubjectUniqueID( + DerBitString uniqueID) + { + this.subjectUniqueID = uniqueID; + } + + public void SetSubjectPublicKeyInfo( + SubjectPublicKeyInfo pubKeyInfo) + { + this.subjectPublicKeyInfo = pubKeyInfo; + } + + public void SetExtensions( + X509Extensions extensions) + { + this.extensions = extensions; + + if (extensions != null) + { + X509Extension altName = extensions.GetExtension(X509Extensions.SubjectAlternativeName); + + if (altName != null && altName.IsCritical) + { + altNamePresentAndCritical = true; + } + } + } + + public TbsCertificateStructure GenerateTbsCertificate() + { + if ((serialNumber == null) || (signature == null) + || (issuer == null) || (startDate == null) || (endDate == null) + || (subject == null && !altNamePresentAndCritical) + || (subjectPublicKeyInfo == null)) + { + throw new InvalidOperationException("not all mandatory fields set in V3 TBScertificate generator"); + } + + DerSequence validity = new DerSequence(startDate, endDate); // before and after dates + + Asn1EncodableVector v = new Asn1EncodableVector( + version, serialNumber, signature, issuer, validity); + + if (subject != null) + { + v.Add(subject); + } + else + { + v.Add(DerSequence.Empty); + } + + v.Add(subjectPublicKeyInfo); + + if (issuerUniqueID != null) + { + v.Add(new DerTaggedObject(false, 1, issuerUniqueID)); + } + + if (subjectUniqueID != null) + { + v.Add(new DerTaggedObject(false, 2, subjectUniqueID)); + } + + if (extensions != null) + { + v.Add(new DerTaggedObject(3, extensions)); + } + + return new TbsCertificateStructure(new DerSequence(v)); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/V3TBSCertificateGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/V3TBSCertificateGenerator.cs.meta new file mode 100644 index 0000000..1001559 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/V3TBSCertificateGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7201010e52f8b5e46ba1ec7bff86b3ec +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509Attributes.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509Attributes.cs new file mode 100644 index 0000000..291329a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509Attributes.cs @@ -0,0 +1,9 @@ +using System; + +namespace Org.BouncyCastle.Asn1.X509 +{ + public class X509Attributes + { + public static readonly DerObjectIdentifier RoleSyntax = new DerObjectIdentifier("2.5.4.72"); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509Attributes.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509Attributes.cs.meta new file mode 100644 index 0000000..ea9c223 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509Attributes.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 50729f1055a19cd43902965ea2316804 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509CertificateStructure.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509CertificateStructure.cs new file mode 100644 index 0000000..6e7c85d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509CertificateStructure.cs @@ -0,0 +1,132 @@ +using System; + +using Org.BouncyCastle.Asn1.Pkcs; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * an X509Certificate structure. + *
+     *  Certificate ::= Sequence {
+     *      tbsCertificate          TbsCertificate,
+     *      signatureAlgorithm      AlgorithmIdentifier,
+     *      signature               BIT STRING
+     *  }
+     * 
+ */ + public class X509CertificateStructure + : Asn1Encodable + { + private readonly TbsCertificateStructure tbsCert; + private readonly AlgorithmIdentifier sigAlgID; + private readonly DerBitString sig; + + public static X509CertificateStructure GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static X509CertificateStructure GetInstance( + object obj) + { + if (obj is X509CertificateStructure) + return (X509CertificateStructure)obj; + if (obj == null) + return null; + return new X509CertificateStructure(Asn1Sequence.GetInstance(obj)); + } + + public X509CertificateStructure( + TbsCertificateStructure tbsCert, + AlgorithmIdentifier sigAlgID, + DerBitString sig) + { + if (tbsCert == null) + throw new ArgumentNullException("tbsCert"); + if (sigAlgID == null) + throw new ArgumentNullException("sigAlgID"); + if (sig == null) + throw new ArgumentNullException("sig"); + + this.tbsCert = tbsCert; + this.sigAlgID = sigAlgID; + this.sig = sig; + } + + private X509CertificateStructure( + Asn1Sequence seq) + { + if (seq.Count != 3) + throw new ArgumentException("sequence wrong size for a certificate", "seq"); + + // + // correct x509 certficate + // + tbsCert = TbsCertificateStructure.GetInstance(seq[0]); + sigAlgID = AlgorithmIdentifier.GetInstance(seq[1]); + sig = DerBitString.GetInstance(seq[2]); + } + + public TbsCertificateStructure TbsCertificate + { + get { return tbsCert; } + } + + public int Version + { + get { return tbsCert.Version; } + } + + public DerInteger SerialNumber + { + get { return tbsCert.SerialNumber; } + } + + public X509Name Issuer + { + get { return tbsCert.Issuer; } + } + + public Time StartDate + { + get { return tbsCert.StartDate; } + } + + public Time EndDate + { + get { return tbsCert.EndDate; } + } + + public X509Name Subject + { + get { return tbsCert.Subject; } + } + + public SubjectPublicKeyInfo SubjectPublicKeyInfo + { + get { return tbsCert.SubjectPublicKeyInfo; } + } + + public AlgorithmIdentifier SignatureAlgorithm + { + get { return sigAlgID; } + } + + public DerBitString Signature + { + get { return sig; } + } + + public byte[] GetSignatureOctets() + { + return sig.GetOctets(); + } + + public override Asn1Object ToAsn1Object() + { + return new DerSequence(tbsCert, sigAlgID, sig); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509CertificateStructure.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509CertificateStructure.cs.meta new file mode 100644 index 0000000..b45de6e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509CertificateStructure.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cce1f8d7bd29ea94eb74ecdb021064f3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509DefaultEntryConverter.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509DefaultEntryConverter.cs new file mode 100644 index 0000000..7282ead --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509DefaultEntryConverter.cs @@ -0,0 +1,63 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * The default converter for X509 DN entries when going from their + * string value to ASN.1 strings. + */ + public class X509DefaultEntryConverter + : X509NameEntryConverter + { + /** + * Apply default conversion for the given value depending on the oid + * and the character range of the value. + * + * @param oid the object identifier for the DN entry + * @param value the value associated with it + * @return the ASN.1 equivalent for the string value. + */ + public override Asn1Object GetConvertedValue( + DerObjectIdentifier oid, + string value) + { + if (value.Length != 0 && value[0] == '#') + { + try + { + return ConvertHexEncoded(value, 1); + } + catch (IOException) + { + throw new Exception("can't recode value for oid " + oid.Id); + } + } + + if (value.Length != 0 && value[0] == '\\') + { + value = value.Substring(1); + } + + if (oid.Equals(X509Name.EmailAddress) || oid.Equals(X509Name.DC)) + { + return new DerIA5String(value); + } + + if (oid.Equals(X509Name.DateOfBirth)) // accept time string as well as # (for compatibility) + { + return new DerGeneralizedTime(value); + } + + if (oid.Equals(X509Name.C) + || oid.Equals(X509Name.SerialNumber) + || oid.Equals(X509Name.DnQualifier) + || oid.Equals(X509Name.TelephoneNumber)) + { + return new DerPrintableString(value); + } + + return new DerUtf8String(value); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509DefaultEntryConverter.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509DefaultEntryConverter.cs.meta new file mode 100644 index 0000000..a55a55b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509DefaultEntryConverter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a0360c62038dc764ea454e456050082c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509Extension.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509Extension.cs new file mode 100644 index 0000000..430ce44 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509Extension.cs @@ -0,0 +1,79 @@ +using System; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * an object for the elements in the X.509 V3 extension block. + */ + public class X509Extension + { + internal bool critical; + internal Asn1OctetString value; + + public X509Extension( + DerBoolean critical, + Asn1OctetString value) + { + if (critical == null) + { + throw new ArgumentNullException("critical"); + } + + this.critical = critical.IsTrue; + this.value = value; + } + + public X509Extension( + bool critical, + Asn1OctetString value) + { + this.critical = critical; + this.value = value; + } + + public bool IsCritical { get { return critical; } } + + public Asn1OctetString Value { get { return value; } } + + public Asn1Encodable GetParsedValue() + { + return ConvertValueToObject(this); + } + + public override int GetHashCode() + { + int vh = this.Value.GetHashCode(); + + return IsCritical ? vh : ~vh; + } + + public override bool Equals( + object obj) + { + X509Extension other = obj as X509Extension; + if (other == null) + { + return false; + } + + return Value.Equals(other.Value) && IsCritical == other.IsCritical; + } + + /// Convert the value of the passed in extension to an object. + /// The extension to parse. + /// The object the value string contains. + /// If conversion is not possible. + public static Asn1Object ConvertValueToObject( + X509Extension ext) + { + try + { + return Asn1Object.FromByteArray(ext.Value.GetOctets()); + } + catch (Exception e) + { + throw new ArgumentException("can't convert extension", e); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509Extension.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509Extension.cs.meta new file mode 100644 index 0000000..606978f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509Extension.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8f8dc626ecb304446a9e8953ef1412ae +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509Extensions.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509Extensions.cs new file mode 100644 index 0000000..42121fa --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509Extensions.cs @@ -0,0 +1,482 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Asn1.X509 +{ + public class X509Extensions + : Asn1Encodable + { + /** + * Subject Directory Attributes + */ + public static readonly DerObjectIdentifier SubjectDirectoryAttributes = new DerObjectIdentifier("2.5.29.9"); + + /** + * Subject Key Identifier + */ + public static readonly DerObjectIdentifier SubjectKeyIdentifier = new DerObjectIdentifier("2.5.29.14"); + + /** + * Key Usage + */ + public static readonly DerObjectIdentifier KeyUsage = new DerObjectIdentifier("2.5.29.15"); + + /** + * Private Key Usage Period + */ + public static readonly DerObjectIdentifier PrivateKeyUsagePeriod = new DerObjectIdentifier("2.5.29.16"); + + /** + * Subject Alternative Name + */ + public static readonly DerObjectIdentifier SubjectAlternativeName = new DerObjectIdentifier("2.5.29.17"); + + /** + * Issuer Alternative Name + */ + public static readonly DerObjectIdentifier IssuerAlternativeName = new DerObjectIdentifier("2.5.29.18"); + + /** + * Basic Constraints + */ + public static readonly DerObjectIdentifier BasicConstraints = new DerObjectIdentifier("2.5.29.19"); + + /** + * CRL Number + */ + public static readonly DerObjectIdentifier CrlNumber = new DerObjectIdentifier("2.5.29.20"); + + /** + * Reason code + */ + public static readonly DerObjectIdentifier ReasonCode = new DerObjectIdentifier("2.5.29.21"); + + /** + * Hold Instruction Code + */ + public static readonly DerObjectIdentifier InstructionCode = new DerObjectIdentifier("2.5.29.23"); + + /** + * Invalidity Date + */ + public static readonly DerObjectIdentifier InvalidityDate = new DerObjectIdentifier("2.5.29.24"); + + /** + * Delta CRL indicator + */ + public static readonly DerObjectIdentifier DeltaCrlIndicator = new DerObjectIdentifier("2.5.29.27"); + + /** + * Issuing Distribution Point + */ + public static readonly DerObjectIdentifier IssuingDistributionPoint = new DerObjectIdentifier("2.5.29.28"); + + /** + * Certificate Issuer + */ + public static readonly DerObjectIdentifier CertificateIssuer = new DerObjectIdentifier("2.5.29.29"); + + /** + * Name Constraints + */ + public static readonly DerObjectIdentifier NameConstraints = new DerObjectIdentifier("2.5.29.30"); + + /** + * CRL Distribution Points + */ + public static readonly DerObjectIdentifier CrlDistributionPoints = new DerObjectIdentifier("2.5.29.31"); + + /** + * Certificate Policies + */ + public static readonly DerObjectIdentifier CertificatePolicies = new DerObjectIdentifier("2.5.29.32"); + + /** + * Policy Mappings + */ + public static readonly DerObjectIdentifier PolicyMappings = new DerObjectIdentifier("2.5.29.33"); + + /** + * Authority Key Identifier + */ + public static readonly DerObjectIdentifier AuthorityKeyIdentifier = new DerObjectIdentifier("2.5.29.35"); + + /** + * Policy Constraints + */ + public static readonly DerObjectIdentifier PolicyConstraints = new DerObjectIdentifier("2.5.29.36"); + + /** + * Extended Key Usage + */ + public static readonly DerObjectIdentifier ExtendedKeyUsage = new DerObjectIdentifier("2.5.29.37"); + + /** + * Freshest CRL + */ + public static readonly DerObjectIdentifier FreshestCrl = new DerObjectIdentifier("2.5.29.46"); + + /** + * Inhibit Any Policy + */ + public static readonly DerObjectIdentifier InhibitAnyPolicy = new DerObjectIdentifier("2.5.29.54"); + + /** + * Authority Info Access + */ + public static readonly DerObjectIdentifier AuthorityInfoAccess = new DerObjectIdentifier("1.3.6.1.5.5.7.1.1"); + + /** + * Subject Info Access + */ + public static readonly DerObjectIdentifier SubjectInfoAccess = new DerObjectIdentifier("1.3.6.1.5.5.7.1.11"); + + /** + * Logo Type + */ + public static readonly DerObjectIdentifier LogoType = new DerObjectIdentifier("1.3.6.1.5.5.7.1.12"); + + /** + * BiometricInfo + */ + public static readonly DerObjectIdentifier BiometricInfo = new DerObjectIdentifier("1.3.6.1.5.5.7.1.2"); + + /** + * QCStatements + */ + public static readonly DerObjectIdentifier QCStatements = new DerObjectIdentifier("1.3.6.1.5.5.7.1.3"); + + /** + * Audit identity extension in attribute certificates. + */ + public static readonly DerObjectIdentifier AuditIdentity = new DerObjectIdentifier("1.3.6.1.5.5.7.1.4"); + + /** + * NoRevAvail extension in attribute certificates. + */ + public static readonly DerObjectIdentifier NoRevAvail = new DerObjectIdentifier("2.5.29.56"); + + /** + * TargetInformation extension in attribute certificates. + */ + public static readonly DerObjectIdentifier TargetInformation = new DerObjectIdentifier("2.5.29.55"); + + /** + * Expired Certificates on CRL extension + */ + public static readonly DerObjectIdentifier ExpiredCertsOnCrl = new DerObjectIdentifier("2.5.29.60"); + + private readonly IDictionary extensions = Platform.CreateHashtable(); + private readonly IList ordering; + + public static X509Extension GetExtension(X509Extensions extensions, DerObjectIdentifier oid) + { + return null == extensions ? null : extensions.GetExtension(oid); + } + + public static Asn1Encodable GetExtensionParsedValue(X509Extensions extensions, DerObjectIdentifier oid) + { + return null == extensions ? null : extensions.GetExtensionParsedValue(oid); + } + + public static X509Extensions GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static X509Extensions GetInstance( + object obj) + { + if (obj == null || obj is X509Extensions) + { + return (X509Extensions) obj; + } + + if (obj is Asn1Sequence) + { + return new X509Extensions((Asn1Sequence) obj); + } + + if (obj is Asn1TaggedObject) + { + return GetInstance(((Asn1TaggedObject) obj).GetObject()); + } + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + /** + * Constructor from Asn1Sequence. + * + * the extensions are a list of constructed sequences, either with (Oid, OctetString) or (Oid, Boolean, OctetString) + */ + private X509Extensions( + Asn1Sequence seq) + { + this.ordering = Platform.CreateArrayList(); + + foreach (Asn1Encodable ae in seq) + { + Asn1Sequence s = Asn1Sequence.GetInstance(ae.ToAsn1Object()); + + if (s.Count < 2 || s.Count > 3) + throw new ArgumentException("Bad sequence size: " + s.Count); + + DerObjectIdentifier oid = DerObjectIdentifier.GetInstance(s[0].ToAsn1Object()); + + bool isCritical = s.Count == 3 + && DerBoolean.GetInstance(s[1].ToAsn1Object()).IsTrue; + + Asn1OctetString octets = Asn1OctetString.GetInstance(s[s.Count - 1].ToAsn1Object()); + + if (extensions.Contains(oid)) + throw new ArgumentException("repeated extension found: " + oid); + + extensions.Add(oid, new X509Extension(isCritical, octets)); + ordering.Add(oid); + } + } + + /** + * constructor from a table of extensions. + *

+ * it's is assumed the table contains Oid/string pairs.

+ */ + public X509Extensions( + IDictionary extensions) + : this(null, extensions) + { + } + + /** + * Constructor from a table of extensions with ordering. + *

+ * It's is assumed the table contains Oid/string pairs.

+ */ + public X509Extensions( + IList ordering, + IDictionary extensions) + { + if (ordering == null) + { + this.ordering = Platform.CreateArrayList(extensions.Keys); + } + else + { + this.ordering = Platform.CreateArrayList(ordering); + } + + foreach (DerObjectIdentifier oid in this.ordering) + { + this.extensions.Add(oid, (X509Extension)extensions[oid]); + } + } + + /** + * Constructor from two vectors + * + * @param objectIDs an ArrayList of the object identifiers. + * @param values an ArrayList of the extension values. + */ + public X509Extensions( + IList oids, + IList values) + { + this.ordering = Platform.CreateArrayList(oids); + + int count = 0; + foreach (DerObjectIdentifier oid in this.ordering) + { + this.extensions.Add(oid, (X509Extension)values[count++]); + } + } + +#if !(SILVERLIGHT || PORTABLE) + /** + * constructor from a table of extensions. + *

+ * it's is assumed the table contains Oid/string pairs.

+ */ + [Obsolete] + public X509Extensions( + Hashtable extensions) + : this(null, extensions) + { + } + + /** + * Constructor from a table of extensions with ordering. + *

+ * It's is assumed the table contains Oid/string pairs.

+ */ + [Obsolete] + public X509Extensions( + ArrayList ordering, + Hashtable extensions) + { + if (ordering == null) + { + this.ordering = Platform.CreateArrayList(extensions.Keys); + } + else + { + this.ordering = Platform.CreateArrayList(ordering); + } + + foreach (DerObjectIdentifier oid in this.ordering) + { + this.extensions.Add(oid, (X509Extension) extensions[oid]); + } + } + + /** + * Constructor from two vectors + * + * @param objectIDs an ArrayList of the object identifiers. + * @param values an ArrayList of the extension values. + */ + [Obsolete] + public X509Extensions( + ArrayList oids, + ArrayList values) + { + this.ordering = Platform.CreateArrayList(oids); + + int count = 0; + foreach (DerObjectIdentifier oid in this.ordering) + { + this.extensions.Add(oid, (X509Extension) values[count++]); + } + } +#endif + + [Obsolete("Use ExtensionOids IEnumerable property")] + public IEnumerator Oids() + { + return ExtensionOids.GetEnumerator(); + } + + /** + * return an Enumeration of the extension field's object ids. + */ + public IEnumerable ExtensionOids + { + get { return new EnumerableProxy(ordering); } + } + + /** + * return the extension represented by the object identifier + * passed in. + * + * @return the extension if it's present, null otherwise. + */ + public X509Extension GetExtension( + DerObjectIdentifier oid) + { + return (X509Extension)extensions[oid]; + } + + /** + * return the parsed value of the extension represented by the object identifier + * passed in. + * + * @return the parsed value of the extension if it's present, null otherwise. + */ + public Asn1Encodable GetExtensionParsedValue(DerObjectIdentifier oid) + { + X509Extension ext = GetExtension(oid); + + return ext == null ? null : ext.GetParsedValue(); + } + + /** + *
+		 *     Extensions        ::=   SEQUENCE SIZE (1..MAX) OF Extension
+		 *
+		 *     Extension         ::=   SEQUENCE {
+		 *        extnId            EXTENSION.&id ({ExtensionSet}),
+		 *        critical          BOOLEAN DEFAULT FALSE,
+		 *        extnValue         OCTET STRING }
+		 * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector vec = new Asn1EncodableVector(); + + foreach (DerObjectIdentifier oid in ordering) + { + X509Extension ext = (X509Extension) extensions[oid]; + Asn1EncodableVector v = new Asn1EncodableVector(oid); + + if (ext.IsCritical) + { + v.Add(DerBoolean.True); + } + + v.Add(ext.Value); + + vec.Add(new DerSequence(v)); + } + + return new DerSequence(vec); + } + + public bool Equivalent( + X509Extensions other) + { + if (extensions.Count != other.extensions.Count) + return false; + + foreach (DerObjectIdentifier oid in extensions.Keys) + { + if (!extensions[oid].Equals(other.extensions[oid])) + return false; + } + + return true; + } + + public DerObjectIdentifier[] GetExtensionOids() + { + return ToOidArray(ordering); + } + + public DerObjectIdentifier[] GetNonCriticalExtensionOids() + { + return GetExtensionOids(false); + } + + public DerObjectIdentifier[] GetCriticalExtensionOids() + { + return GetExtensionOids(true); + } + + private DerObjectIdentifier[] GetExtensionOids(bool isCritical) + { + IList oids = Platform.CreateArrayList(); + + foreach (DerObjectIdentifier oid in this.ordering) + { + X509Extension ext = (X509Extension)extensions[oid]; + if (ext.IsCritical == isCritical) + { + oids.Add(oid); + } + } + + return ToOidArray(oids); + } + + private static DerObjectIdentifier[] ToOidArray(IList oids) + { + DerObjectIdentifier[] oidArray = new DerObjectIdentifier[oids.Count]; + oids.CopyTo(oidArray, 0); + return oidArray; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509Extensions.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509Extensions.cs.meta new file mode 100644 index 0000000..dbfab4e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509Extensions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f525c495362deb94686f3e1a1c6cb80a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509ExtensionsGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509ExtensionsGenerator.cs new file mode 100644 index 0000000..3b952ff --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509ExtensionsGenerator.cs @@ -0,0 +1,137 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /// Generator for X.509 extensions + public class X509ExtensionsGenerator + { + private IDictionary extensions = Platform.CreateHashtable(); + private IList extOrdering = Platform.CreateArrayList(); + + private static readonly IDictionary dupsAllowed = Platform.CreateHashtable(); + + static X509ExtensionsGenerator() + { + dupsAllowed.Add(X509Extensions.SubjectAlternativeName, true); + dupsAllowed.Add(X509Extensions.IssuerAlternativeName, true); + dupsAllowed.Add(X509Extensions.SubjectDirectoryAttributes, true); + dupsAllowed.Add(X509Extensions.CertificateIssuer, true); + + } + + + + /// Reset the generator + public void Reset() + { + extensions = Platform.CreateHashtable(); + extOrdering = Platform.CreateArrayList(); + } + + /// + /// Add an extension with the given oid and the passed in value to be included + /// in the OCTET STRING associated with the extension. + /// + /// OID for the extension. + /// True if critical, false otherwise. + /// The ASN.1 object to be included in the extension. + public void AddExtension( + DerObjectIdentifier oid, + bool critical, + Asn1Encodable extValue) + { + byte[] encoded; + try + { + encoded = extValue.GetDerEncoded(); + } + catch (Exception e) + { + throw new ArgumentException("error encoding value: " + e); + } + + this.AddExtension(oid, critical, encoded); + } + + /// + /// Add an extension with the given oid and the passed in byte array to be wrapped + /// in the OCTET STRING associated with the extension. + /// + /// OID for the extension. + /// True if critical, false otherwise. + /// The byte array to be wrapped. + public void AddExtension( + DerObjectIdentifier oid, + bool critical, + byte[] extValue) + { + if (extensions.Contains(oid)) + { + if (dupsAllowed.Contains(oid)) + { + X509Extension existingExtension = (X509Extension)extensions[oid]; + + Asn1Sequence seq1 = Asn1Sequence.GetInstance(DerOctetString.GetInstance(existingExtension.Value).GetOctets()); + Asn1EncodableVector items = Asn1EncodableVector.FromEnumerable(seq1); + Asn1Sequence seq2 = Asn1Sequence.GetInstance(extValue); + + foreach (Asn1Encodable enc in seq2) + { + items.Add(enc); + } + + extensions[oid] = new X509Extension(existingExtension.IsCritical, new DerOctetString(new DerSequence(items).GetEncoded())); + + } + else + { + throw new ArgumentException("extension " + oid + " already added"); + } + } + else + { + extOrdering.Add(oid); + extensions.Add(oid, new X509Extension(critical, new DerOctetString(extValue))); + } + } + + public void AddExtensions(X509Extensions extensions) + { + foreach (DerObjectIdentifier ident in extensions.ExtensionOids) + { + X509Extension ext = extensions.GetExtension(ident); + AddExtension(ident, ext.critical, ext.Value.GetOctets()); + } + } + + + + /// Return true if there are no extension present in this generator. + /// True if empty, false otherwise + public bool IsEmpty + { + get { return extOrdering.Count < 1; } + } + + /// Generate an X509Extensions object based on the current state of the generator. + /// An X509Extensions object + public X509Extensions Generate() + { + return new X509Extensions(extOrdering, extensions); + } + + internal void AddExtension(DerObjectIdentifier oid, X509Extension x509Extension) + { + if (extensions.Contains(oid)) + { + throw new ArgumentException("extension " + oid + " already added"); + } + + extOrdering.Add(oid); + extensions.Add(oid, x509Extension); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509ExtensionsGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509ExtensionsGenerator.cs.meta new file mode 100644 index 0000000..cf6b4a1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509ExtensionsGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9e64dc7483339b34cb0ee055b8a05202 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509Name.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509Name.cs new file mode 100644 index 0000000..bd8f9fb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509Name.cs @@ -0,0 +1,1080 @@ +using System; +using System.Collections; +using System.IO; +using System.Text; + +#if SILVERLIGHT || PORTABLE +using System.Collections.Generic; +#endif + +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + *
+    *     RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
+    *
+    *     RelativeDistinguishedName ::= SET SIZE (1..MAX) OF AttributeTypeAndValue
+    *
+    *     AttributeTypeAndValue ::= SEQUENCE {
+    *                                   type  OBJECT IDENTIFIER,
+    *                                   value ANY }
+    * 
+ */ + public class X509Name + : Asn1Encodable + { + /** + * country code - StringType(SIZE(2)) + */ + public static readonly DerObjectIdentifier C = new DerObjectIdentifier("2.5.4.6"); + + /** + * organization - StringType(SIZE(1..64)) + */ + public static readonly DerObjectIdentifier O = new DerObjectIdentifier("2.5.4.10"); + + /** + * organizational unit name - StringType(SIZE(1..64)) + */ + public static readonly DerObjectIdentifier OU = new DerObjectIdentifier("2.5.4.11"); + + /** + * Title + */ + public static readonly DerObjectIdentifier T = new DerObjectIdentifier("2.5.4.12"); + + /** + * common name - StringType(SIZE(1..64)) + */ + public static readonly DerObjectIdentifier CN = new DerObjectIdentifier("2.5.4.3"); + + /** + * street - StringType(SIZE(1..64)) + */ + public static readonly DerObjectIdentifier Street = new DerObjectIdentifier("2.5.4.9"); + + /** + * device serial number name - StringType(SIZE(1..64)) + */ + public static readonly DerObjectIdentifier SerialNumber = new DerObjectIdentifier("2.5.4.5"); + + /** + * locality name - StringType(SIZE(1..64)) + */ + public static readonly DerObjectIdentifier L = new DerObjectIdentifier("2.5.4.7"); + + /** + * state, or province name - StringType(SIZE(1..64)) + */ + public static readonly DerObjectIdentifier ST = new DerObjectIdentifier("2.5.4.8"); + + /** + * Naming attributes of type X520name + */ + public static readonly DerObjectIdentifier Surname = new DerObjectIdentifier("2.5.4.4"); + public static readonly DerObjectIdentifier GivenName = new DerObjectIdentifier("2.5.4.42"); + public static readonly DerObjectIdentifier Initials = new DerObjectIdentifier("2.5.4.43"); + public static readonly DerObjectIdentifier Generation = new DerObjectIdentifier("2.5.4.44"); + public static readonly DerObjectIdentifier UniqueIdentifier = new DerObjectIdentifier("2.5.4.45"); + + /** + * businessCategory - DirectoryString(SIZE(1..128) + */ + public static readonly DerObjectIdentifier BusinessCategory = new DerObjectIdentifier( + "2.5.4.15"); + + /** + * postalCode - DirectoryString(SIZE(1..40) + */ + public static readonly DerObjectIdentifier PostalCode = new DerObjectIdentifier( + "2.5.4.17"); + + /** + * dnQualifier - DirectoryString(SIZE(1..64) + */ + public static readonly DerObjectIdentifier DnQualifier = new DerObjectIdentifier( + "2.5.4.46"); + + /** + * RFC 3039 Pseudonym - DirectoryString(SIZE(1..64) + */ + public static readonly DerObjectIdentifier Pseudonym = new DerObjectIdentifier( + "2.5.4.65"); + + /** + * RFC 3039 DateOfBirth - GeneralizedTime - YYYYMMDD000000Z + */ + public static readonly DerObjectIdentifier DateOfBirth = new DerObjectIdentifier( + "1.3.6.1.5.5.7.9.1"); + + /** + * RFC 3039 PlaceOfBirth - DirectoryString(SIZE(1..128) + */ + public static readonly DerObjectIdentifier PlaceOfBirth = new DerObjectIdentifier( + "1.3.6.1.5.5.7.9.2"); + + /** + * RFC 3039 DateOfBirth - PrintableString (SIZE(1)) -- "M", "F", "m" or "f" + */ + public static readonly DerObjectIdentifier Gender = new DerObjectIdentifier( + "1.3.6.1.5.5.7.9.3"); + + /** + * RFC 3039 CountryOfCitizenship - PrintableString (SIZE (2)) -- ISO 3166 + * codes only + */ + public static readonly DerObjectIdentifier CountryOfCitizenship = new DerObjectIdentifier( + "1.3.6.1.5.5.7.9.4"); + + /** + * RFC 3039 CountryOfCitizenship - PrintableString (SIZE (2)) -- ISO 3166 + * codes only + */ + public static readonly DerObjectIdentifier CountryOfResidence = new DerObjectIdentifier( + "1.3.6.1.5.5.7.9.5"); + + /** + * ISIS-MTT NameAtBirth - DirectoryString(SIZE(1..64) + */ + public static readonly DerObjectIdentifier NameAtBirth = new DerObjectIdentifier("1.3.36.8.3.14"); + + /** + * RFC 3039 PostalAddress - SEQUENCE SIZE (1..6) OF + * DirectoryString(SIZE(1..30)) + */ + public static readonly DerObjectIdentifier PostalAddress = new DerObjectIdentifier("2.5.4.16"); + + /** + * RFC 2256 dmdName + */ + public static readonly DerObjectIdentifier DmdName = new DerObjectIdentifier("2.5.4.54"); + + /** + * id-at-telephoneNumber + */ + public static readonly DerObjectIdentifier TelephoneNumber = X509ObjectIdentifiers.id_at_telephoneNumber; + + /** + * id-at-organizationIdentifier + */ + public static readonly DerObjectIdentifier OrganizationIdentifier = X509ObjectIdentifiers.id_at_organizationIdentifier; + + /** + * id-at-name + */ + public static readonly DerObjectIdentifier Name = X509ObjectIdentifiers.id_at_name; + + /** + * Email address (RSA PKCS#9 extension) - IA5String. + *

Note: if you're trying to be ultra orthodox, don't use this! It shouldn't be in here.

+ */ + public static readonly DerObjectIdentifier EmailAddress = PkcsObjectIdentifiers.Pkcs9AtEmailAddress; + + /** + * more from PKCS#9 + */ + public static readonly DerObjectIdentifier UnstructuredName = PkcsObjectIdentifiers.Pkcs9AtUnstructuredName; + public static readonly DerObjectIdentifier UnstructuredAddress = PkcsObjectIdentifiers.Pkcs9AtUnstructuredAddress; + + /** + * email address in Verisign certificates + */ + public static readonly DerObjectIdentifier E = EmailAddress; + + /* + * others... + */ + public static readonly DerObjectIdentifier DC = new DerObjectIdentifier("0.9.2342.19200300.100.1.25"); + + /** + * LDAP User id. + */ + public static readonly DerObjectIdentifier UID = new DerObjectIdentifier("0.9.2342.19200300.100.1.1"); + + /** + * determines whether or not strings should be processed and printed + * from back to front. + */ +// public static bool DefaultReverse = false; + public static bool DefaultReverse + { + get { return defaultReverse[0]; } + set { defaultReverse[0] = value; } + } + + private static readonly bool[] defaultReverse = { false }; + +#if SILVERLIGHT || PORTABLE + /** + * default look up table translating OID values into their common symbols following + * the convention in RFC 2253 with a few extras + */ + public static readonly IDictionary DefaultSymbols = Platform.CreateHashtable(); + + /** + * look up table translating OID values into their common symbols following the convention in RFC 2253 + */ + public static readonly IDictionary RFC2253Symbols = Platform.CreateHashtable(); + + /** + * look up table translating OID values into their common symbols following the convention in RFC 1779 + * + */ + public static readonly IDictionary RFC1779Symbols = Platform.CreateHashtable(); + + /** + * look up table translating common symbols into their OIDS. + */ + public static readonly IDictionary DefaultLookup = Platform.CreateHashtable(); +#else + /** + * default look up table translating OID values into their common symbols following + * the convention in RFC 2253 with a few extras + */ + public static readonly Hashtable DefaultSymbols = new Hashtable(); + + /** + * look up table translating OID values into their common symbols following the convention in RFC 2253 + */ + public static readonly Hashtable RFC2253Symbols = new Hashtable(); + + /** + * look up table translating OID values into their common symbols following the convention in RFC 1779 + * + */ + public static readonly Hashtable RFC1779Symbols = new Hashtable(); + + /** + * look up table translating common symbols into their OIDS. + */ + public static readonly Hashtable DefaultLookup = new Hashtable(); +#endif + + static X509Name() + { + DefaultSymbols.Add(C, "C"); + DefaultSymbols.Add(O, "O"); + DefaultSymbols.Add(T, "T"); + DefaultSymbols.Add(OU, "OU"); + DefaultSymbols.Add(CN, "CN"); + DefaultSymbols.Add(L, "L"); + DefaultSymbols.Add(ST, "ST"); + DefaultSymbols.Add(SerialNumber, "SERIALNUMBER"); + DefaultSymbols.Add(EmailAddress, "E"); + DefaultSymbols.Add(DC, "DC"); + DefaultSymbols.Add(UID, "UID"); + DefaultSymbols.Add(Street, "STREET"); + DefaultSymbols.Add(Surname, "SURNAME"); + DefaultSymbols.Add(GivenName, "GIVENNAME"); + DefaultSymbols.Add(Initials, "INITIALS"); + DefaultSymbols.Add(Generation, "GENERATION"); + DefaultSymbols.Add(UnstructuredAddress, "unstructuredAddress"); + DefaultSymbols.Add(UnstructuredName, "unstructuredName"); + DefaultSymbols.Add(UniqueIdentifier, "UniqueIdentifier"); + DefaultSymbols.Add(DnQualifier, "DN"); + DefaultSymbols.Add(Pseudonym, "Pseudonym"); + DefaultSymbols.Add(PostalAddress, "PostalAddress"); + DefaultSymbols.Add(NameAtBirth, "NameAtBirth"); + DefaultSymbols.Add(CountryOfCitizenship, "CountryOfCitizenship"); + DefaultSymbols.Add(CountryOfResidence, "CountryOfResidence"); + DefaultSymbols.Add(Gender, "Gender"); + DefaultSymbols.Add(PlaceOfBirth, "PlaceOfBirth"); + DefaultSymbols.Add(DateOfBirth, "DateOfBirth"); + DefaultSymbols.Add(PostalCode, "PostalCode"); + DefaultSymbols.Add(BusinessCategory, "BusinessCategory"); + DefaultSymbols.Add(TelephoneNumber, "TelephoneNumber"); + + RFC2253Symbols.Add(C, "C"); + RFC2253Symbols.Add(O, "O"); + RFC2253Symbols.Add(OU, "OU"); + RFC2253Symbols.Add(CN, "CN"); + RFC2253Symbols.Add(L, "L"); + RFC2253Symbols.Add(ST, "ST"); + RFC2253Symbols.Add(Street, "STREET"); + RFC2253Symbols.Add(DC, "DC"); + RFC2253Symbols.Add(UID, "UID"); + + RFC1779Symbols.Add(C, "C"); + RFC1779Symbols.Add(O, "O"); + RFC1779Symbols.Add(OU, "OU"); + RFC1779Symbols.Add(CN, "CN"); + RFC1779Symbols.Add(L, "L"); + RFC1779Symbols.Add(ST, "ST"); + RFC1779Symbols.Add(Street, "STREET"); + + DefaultLookup.Add("c", C); + DefaultLookup.Add("o", O); + DefaultLookup.Add("t", T); + DefaultLookup.Add("ou", OU); + DefaultLookup.Add("cn", CN); + DefaultLookup.Add("l", L); + DefaultLookup.Add("st", ST); + DefaultLookup.Add("serialnumber", SerialNumber); + DefaultLookup.Add("street", Street); + DefaultLookup.Add("emailaddress", E); + DefaultLookup.Add("dc", DC); + DefaultLookup.Add("e", E); + DefaultLookup.Add("uid", UID); + DefaultLookup.Add("surname", Surname); + DefaultLookup.Add("givenname", GivenName); + DefaultLookup.Add("initials", Initials); + DefaultLookup.Add("generation", Generation); + DefaultLookup.Add("unstructuredaddress", UnstructuredAddress); + DefaultLookup.Add("unstructuredname", UnstructuredName); + DefaultLookup.Add("uniqueidentifier", UniqueIdentifier); + DefaultLookup.Add("dn", DnQualifier); + DefaultLookup.Add("pseudonym", Pseudonym); + DefaultLookup.Add("postaladdress", PostalAddress); + DefaultLookup.Add("nameofbirth", NameAtBirth); + DefaultLookup.Add("countryofcitizenship", CountryOfCitizenship); + DefaultLookup.Add("countryofresidence", CountryOfResidence); + DefaultLookup.Add("gender", Gender); + DefaultLookup.Add("placeofbirth", PlaceOfBirth); + DefaultLookup.Add("dateofbirth", DateOfBirth); + DefaultLookup.Add("postalcode", PostalCode); + DefaultLookup.Add("businesscategory", BusinessCategory); + DefaultLookup.Add("telephonenumber", TelephoneNumber); + } + + private readonly IList ordering = Platform.CreateArrayList(); + private readonly X509NameEntryConverter converter; + + private IList values = Platform.CreateArrayList(); + private IList added = Platform.CreateArrayList(); + private Asn1Sequence seq; + + /** + * Return a X509Name based on the passed in tagged object. + * + * @param obj tag object holding name. + * @param explicitly true if explicitly tagged false otherwise. + * @return the X509Name + */ + public static X509Name GetInstance( + Asn1TaggedObject obj, + bool explicitly) + { + return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); + } + + public static X509Name GetInstance( + object obj) + { + if (obj is X509Name) + return (X509Name)obj; + if (obj == null) + return null; + return new X509Name(Asn1Sequence.GetInstance(obj)); + } + + protected X509Name() + { + } + + /** + * Constructor from Asn1Sequence + * + * the principal will be a list of constructed sets, each containing an (OID, string) pair. + */ + protected X509Name( + Asn1Sequence seq) + { + this.seq = seq; + + foreach (Asn1Encodable asn1Obj in seq) + { + Asn1Set asn1Set = Asn1Set.GetInstance(asn1Obj.ToAsn1Object()); + + for (int i = 0; i < asn1Set.Count; i++) + { + Asn1Sequence s = Asn1Sequence.GetInstance(asn1Set[i].ToAsn1Object()); + + if (s.Count != 2) + throw new ArgumentException("badly sized pair"); + + ordering.Add(DerObjectIdentifier.GetInstance(s[0].ToAsn1Object())); + + Asn1Object derValue = s[1].ToAsn1Object(); + if (derValue is IAsn1String && !(derValue is DerUniversalString)) + { + string v = ((IAsn1String)derValue).GetString(); + if (Platform.StartsWith(v, "#")) + { + v = "\\" + v; + } + + values.Add(v); + } + else + { + values.Add("#" + Hex.ToHexString(derValue.GetEncoded())); + } + + added.Add(i != 0); + } + } + } + + /** + * Constructor from a table of attributes with ordering. + *

+ * it's is assumed the table contains OID/string pairs, and the contents + * of the table are copied into an internal table as part of the + * construction process. The ordering ArrayList should contain the OIDs + * in the order they are meant to be encoded or printed in ToString.

+ */ + public X509Name( + IList ordering, + IDictionary attributes) + : this(ordering, attributes, new X509DefaultEntryConverter()) + { + } + + /** + * Constructor from a table of attributes with ordering. + *

+ * it's is assumed the table contains OID/string pairs, and the contents + * of the table are copied into an internal table as part of the + * construction process. The ordering ArrayList should contain the OIDs + * in the order they are meant to be encoded or printed in ToString.

+ *

+ * The passed in converter will be used to convert the strings into their + * ASN.1 counterparts.

+ */ + public X509Name( + IList ordering, + IDictionary attributes, + X509NameEntryConverter converter) + { + this.converter = converter; + + foreach (DerObjectIdentifier oid in ordering) + { + object attribute = attributes[oid]; + if (attribute == null) + { + throw new ArgumentException("No attribute for object id - " + oid + " - passed to distinguished name"); + } + + this.ordering.Add(oid); + this.added.Add(false); + this.values.Add(attribute); // copy the hash table + } + } + + /** + * Takes two vectors one of the oids and the other of the values. + */ + public X509Name( + IList oids, + IList values) + : this(oids, values, new X509DefaultEntryConverter()) + { + } + + /** + * Takes two vectors one of the oids and the other of the values. + *

+ * The passed in converter will be used to convert the strings into their + * ASN.1 counterparts.

+ */ + public X509Name( + IList oids, + IList values, + X509NameEntryConverter converter) + { + this.converter = converter; + + if (oids.Count != values.Count) + { + throw new ArgumentException("'oids' must be same length as 'values'."); + } + + for (int i = 0; i < oids.Count; i++) + { + this.ordering.Add(oids[i]); + this.values.Add(values[i]); + this.added.Add(false); + } + } + + /** + * Takes an X509 dir name as a string of the format "C=AU, ST=Victoria", or + * some such, converting it into an ordered set of name attributes. + */ + public X509Name( + string dirName) + : this(DefaultReverse, (IDictionary)DefaultLookup, dirName) + { + } + + /** + * Takes an X509 dir name as a string of the format "C=AU, ST=Victoria", or + * some such, converting it into an ordered set of name attributes with each + * string value being converted to its associated ASN.1 type using the passed + * in converter. + */ + public X509Name( + string dirName, + X509NameEntryConverter converter) + : this(DefaultReverse, DefaultLookup, dirName, converter) + { + } + + /** + * Takes an X509 dir name as a string of the format "C=AU, ST=Victoria", or + * some such, converting it into an ordered set of name attributes. If reverse + * is true, create the encoded version of the sequence starting from the + * last element in the string. + */ + public X509Name( + bool reverse, + string dirName) + : this(reverse, (IDictionary)DefaultLookup, dirName) + { + } + + /** + * Takes an X509 dir name as a string of the format "C=AU, ST=Victoria", or + * some such, converting it into an ordered set of name attributes with each + * string value being converted to its associated ASN.1 type using the passed + * in converter. If reverse is true the ASN.1 sequence representing the DN will + * be built by starting at the end of the string, rather than the start. + */ + public X509Name( + bool reverse, + string dirName, + X509NameEntryConverter converter) + : this(reverse, DefaultLookup, dirName, converter) + { + } + + /** + * Takes an X509 dir name as a string of the format "C=AU, ST=Victoria", or + * some such, converting it into an ordered set of name attributes. lookUp + * should provide a table of lookups, indexed by lowercase only strings and + * yielding a DerObjectIdentifier, other than that OID. and numeric oids + * will be processed automatically. + *
+ * If reverse is true, create the encoded version of the sequence + * starting from the last element in the string. + * @param reverse true if we should start scanning from the end (RFC 2553). + * @param lookUp table of names and their oids. + * @param dirName the X.500 string to be parsed. + */ + public X509Name( + bool reverse, + IDictionary lookUp, + string dirName) + : this(reverse, lookUp, dirName, new X509DefaultEntryConverter()) + { + } + + private DerObjectIdentifier DecodeOid( + string name, + IDictionary lookUp) + { + if (Platform.StartsWith(Platform.ToUpperInvariant(name), "OID.")) + { + return new DerObjectIdentifier(name.Substring(4)); + } + else if (name[0] >= '0' && name[0] <= '9') + { + return new DerObjectIdentifier(name); + } + + DerObjectIdentifier oid = (DerObjectIdentifier)lookUp[Platform.ToLowerInvariant(name)]; + if (oid == null) + { + throw new ArgumentException("Unknown object id - " + name + " - passed to distinguished name"); + } + + return oid; + } + + /** + * Takes an X509 dir name as a string of the format "C=AU, ST=Victoria", or + * some such, converting it into an ordered set of name attributes. lookUp + * should provide a table of lookups, indexed by lowercase only strings and + * yielding a DerObjectIdentifier, other than that OID. and numeric oids + * will be processed automatically. The passed in converter is used to convert the + * string values to the right of each equals sign to their ASN.1 counterparts. + *
+ * @param reverse true if we should start scanning from the end, false otherwise. + * @param lookUp table of names and oids. + * @param dirName the string dirName + * @param converter the converter to convert string values into their ASN.1 equivalents + */ + public X509Name( + bool reverse, + IDictionary lookUp, + string dirName, + X509NameEntryConverter converter) + { + this.converter = converter; + X509NameTokenizer nTok = new X509NameTokenizer(dirName); + + while (nTok.HasMoreTokens()) + { + string token = nTok.NextToken(); + int index = token.IndexOf('='); + + if (index == -1) + { + throw new ArgumentException("badly formated directory string"); + } + + string name = token.Substring(0, index); + string value = token.Substring(index + 1); + DerObjectIdentifier oid = DecodeOid(name, lookUp); + + if (value.IndexOf('+') > 0) + { + X509NameTokenizer vTok = new X509NameTokenizer(value, '+'); + string v = vTok.NextToken(); + + this.ordering.Add(oid); + this.values.Add(v); + this.added.Add(false); + + while (vTok.HasMoreTokens()) + { + string sv = vTok.NextToken(); + int ndx = sv.IndexOf('='); + + string nm = sv.Substring(0, ndx); + string vl = sv.Substring(ndx + 1); + this.ordering.Add(DecodeOid(nm, lookUp)); + this.values.Add(vl); + this.added.Add(true); + } + } + else + { + this.ordering.Add(oid); + this.values.Add(value); + this.added.Add(false); + } + } + + if (reverse) + { +// this.ordering.Reverse(); +// this.values.Reverse(); +// this.added.Reverse(); + IList o = Platform.CreateArrayList(); + IList v = Platform.CreateArrayList(); + IList a = Platform.CreateArrayList(); + int count = 1; + + for (int i = 0; i < this.ordering.Count; i++) + { + if (!((bool) this.added[i])) + { + count = 0; + } + + int index = count++; + + o.Insert(index, this.ordering[i]); + v.Insert(index, this.values[i]); + a.Insert(index, this.added[i]); + } + + this.ordering = o; + this.values = v; + this.added = a; + } + } + + /** + * return an IList of the oids in the name, in the order they were found. + */ + public IList GetOidList() + { + return Platform.CreateArrayList(ordering); + } + + /** + * return an IList of the values found in the name, in the order they + * were found. + */ + public IList GetValueList() + { + return GetValueList(null); + } + + /** + * return an IList of the values found in the name, in the order they + * were found, with the DN label corresponding to passed in oid. + */ + public IList GetValueList(DerObjectIdentifier oid) + { + IList v = Platform.CreateArrayList(); + for (int i = 0; i != values.Count; i++) + { + if (null == oid || oid.Equals(ordering[i])) + { + string val = (string)values[i]; + + if (Platform.StartsWith(val, "\\#")) + { + val = val.Substring(1); + } + + v.Add(val); + } + } + return v; + } + + public override Asn1Object ToAsn1Object() + { + if (seq == null) + { + Asn1EncodableVector vec = new Asn1EncodableVector(); + Asn1EncodableVector sVec = new Asn1EncodableVector(); + DerObjectIdentifier lstOid = null; + + for (int i = 0; i != ordering.Count; i++) + { + DerObjectIdentifier oid = (DerObjectIdentifier)ordering[i]; + string str = (string)values[i]; + + if (lstOid == null + || ((bool)this.added[i])) + { + } + else + { + vec.Add(new DerSet(sVec)); + sVec = new Asn1EncodableVector(); + } + + sVec.Add( + new DerSequence( + oid, + converter.GetConvertedValue(oid, str))); + + lstOid = oid; + } + + vec.Add(new DerSet(sVec)); + + seq = new DerSequence(vec); + } + + return seq; + } + + /// The X509Name object to test equivalency against. + /// If true, the order of elements must be the same, + /// as well as the values associated with each element. + public bool Equivalent( + X509Name other, + bool inOrder) + { + if (!inOrder) + return this.Equivalent(other); + + if (other == null) + return false; + + if (other == this) + return true; + + int orderingSize = ordering.Count; + + if (orderingSize != other.ordering.Count) + return false; + + for (int i = 0; i < orderingSize; i++) + { + DerObjectIdentifier oid = (DerObjectIdentifier) ordering[i]; + DerObjectIdentifier oOid = (DerObjectIdentifier) other.ordering[i]; + + if (!oid.Equals(oOid)) + return false; + + string val = (string) values[i]; + string oVal = (string) other.values[i]; + + if (!equivalentStrings(val, oVal)) + return false; + } + + return true; + } + + /** + * test for equivalence - note: case is ignored. + */ + public bool Equivalent( + X509Name other) + { + if (other == null) + return false; + + if (other == this) + return true; + + int orderingSize = ordering.Count; + + if (orderingSize != other.ordering.Count) + { + return false; + } + + bool[] indexes = new bool[orderingSize]; + int start, end, delta; + + if (ordering[0].Equals(other.ordering[0])) // guess forward + { + start = 0; + end = orderingSize; + delta = 1; + } + else // guess reversed - most common problem + { + start = orderingSize - 1; + end = -1; + delta = -1; + } + + for (int i = start; i != end; i += delta) + { + bool found = false; + DerObjectIdentifier oid = (DerObjectIdentifier)ordering[i]; + string value = (string)values[i]; + + for (int j = 0; j < orderingSize; j++) + { + if (indexes[j]) + { + continue; + } + + DerObjectIdentifier oOid = (DerObjectIdentifier)other.ordering[j]; + + if (oid.Equals(oOid)) + { + string oValue = (string)other.values[j]; + + if (equivalentStrings(value, oValue)) + { + indexes[j] = true; + found = true; + break; + } + } + } + + if (!found) + { + return false; + } + } + + return true; + } + + private static bool equivalentStrings( + string s1, + string s2) + { + string v1 = canonicalize(s1); + string v2 = canonicalize(s2); + + if (!v1.Equals(v2)) + { + v1 = stripInternalSpaces(v1); + v2 = stripInternalSpaces(v2); + + if (!v1.Equals(v2)) + { + return false; + } + } + + return true; + } + + private static string canonicalize( + string s) + { + string v = Platform.ToLowerInvariant(s).Trim(); + + if (Platform.StartsWith(v, "#")) + { + Asn1Object obj = decodeObject(v); + + if (obj is IAsn1String) + { + v = Platform.ToLowerInvariant(((IAsn1String)obj).GetString()).Trim(); + } + } + + return v; + } + + private static Asn1Object decodeObject( + string v) + { + try + { + return Asn1Object.FromByteArray(Hex.DecodeStrict(v, 1, v.Length - 1)); + } + catch (IOException e) + { + throw new InvalidOperationException("unknown encoding in name: " + e.Message, e); + } + } + + private static string stripInternalSpaces( + string str) + { + StringBuilder res = new StringBuilder(); + + if (str.Length != 0) + { + char c1 = str[0]; + + res.Append(c1); + + for (int k = 1; k < str.Length; k++) + { + char c2 = str[k]; + if (!(c1 == ' ' && c2 == ' ')) + { + res.Append(c2); + } + c1 = c2; + } + } + + return res.ToString(); + } + + private void AppendValue( + StringBuilder buf, + IDictionary oidSymbols, + DerObjectIdentifier oid, + string val) + { + string sym = (string)oidSymbols[oid]; + + if (sym != null) + { + buf.Append(sym); + } + else + { + buf.Append(oid.Id); + } + + buf.Append('='); + + int index = buf.Length; + + buf.Append(val); + + int end = buf.Length; + + if (Platform.StartsWith(val, "\\#")) + { + index += 2; + } + + while (index != end) + { + if ((buf[index] == ',') + || (buf[index] == '"') + || (buf[index] == '\\') + || (buf[index] == '+') + || (buf[index] == '=') + || (buf[index] == '<') + || (buf[index] == '>') + || (buf[index] == ';')) + { + buf.Insert(index++, "\\"); + end++; + } + + index++; + } + } + + /** + * convert the structure to a string - if reverse is true the + * oids and values are listed out starting with the last element + * in the sequence (ala RFC 2253), otherwise the string will begin + * with the first element of the structure. If no string definition + * for the oid is found in oidSymbols the string value of the oid is + * added. Two standard symbol tables are provided DefaultSymbols, and + * RFC2253Symbols as part of this class. + * + * @param reverse if true start at the end of the sequence and work back. + * @param oidSymbols look up table strings for oids. + */ + public string ToString( + bool reverse, + IDictionary oidSymbols) + { +#if SILVERLIGHT || PORTABLE + List components = new List(); +#else + ArrayList components = new ArrayList(); +#endif + + StringBuilder ava = null; + + for (int i = 0; i < ordering.Count; i++) + { + if ((bool) added[i]) + { + ava.Append('+'); + AppendValue(ava, oidSymbols, + (DerObjectIdentifier)ordering[i], + (string)values[i]); + } + else + { + ava = new StringBuilder(); + AppendValue(ava, oidSymbols, + (DerObjectIdentifier)ordering[i], + (string)values[i]); + components.Add(ava); + } + } + + if (reverse) + { + components.Reverse(); + } + + StringBuilder buf = new StringBuilder(); + + if (components.Count > 0) + { + buf.Append(components[0].ToString()); + + for (int i = 1; i < components.Count; ++i) + { + buf.Append(','); + buf.Append(components[i].ToString()); + } + } + + return buf.ToString(); + } + + public override string ToString() + { + return ToString(DefaultReverse, (IDictionary)DefaultSymbols); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509Name.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509Name.cs.meta new file mode 100644 index 0000000..35bce9a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509Name.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 968eddd7b6c8ce744803bd67e676195b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509NameEntryConverter.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509NameEntryConverter.cs new file mode 100644 index 0000000..a5a00cc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509NameEntryConverter.cs @@ -0,0 +1,87 @@ +using System; +using System.Globalization; +using System.IO; +using System.Text; + +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * It turns out that the number of standard ways the fields in a DN should be + * encoded into their ASN.1 counterparts is rapidly approaching the + * number of machines on the internet. By default the X509Name class + * will produce UTF8Strings in line with the current recommendations (RFC 3280). + *

+ * An example of an encoder look like below: + *

+     * public class X509DirEntryConverter
+     *     : X509NameEntryConverter
+     * {
+     *     public Asn1Object GetConvertedValue(
+     *         DerObjectIdentifier  oid,
+     *         string               value)
+     *     {
+     *         if (str.Length() != 0 && str.charAt(0) == '#')
+     *         {
+     *             return ConvertHexEncoded(str, 1);
+     *         }
+     *         if (oid.Equals(EmailAddress))
+     *         {
+     *             return new DerIA5String(str);
+     *         }
+     *         else if (CanBePrintable(str))
+     *         {
+     *             return new DerPrintableString(str);
+     *         }
+     *         else if (CanBeUTF8(str))
+     *         {
+     *             return new DerUtf8String(str);
+     *         }
+     *         else
+     *         {
+     *             return new DerBmpString(str);
+     *         }
+     *     }
+     * }
+	 * 
+ *

+ */ + public abstract class X509NameEntryConverter + { + /** + * Convert an inline encoded hex string rendition of an ASN.1 + * object back into its corresponding ASN.1 object. + * + * @param str the hex encoded object + * @param off the index at which the encoding starts + * @return the decoded object + */ + protected Asn1Object ConvertHexEncoded( + string hexString, + int offset) + { + return Asn1Object.FromByteArray(Hex.DecodeStrict(hexString, offset, hexString.Length - offset)); + } + + /** + * return true if the passed in string can be represented without + * loss as a PrintableString, false otherwise. + */ + protected bool CanBePrintable( + string str) + { + return DerPrintableString.IsPrintableString(str); + } + + /** + * Convert the passed in string value into the appropriate ASN.1 + * encoded object. + * + * @param oid the oid associated with the value in the DN. + * @param value the value of the particular DN component. + * @return the ASN.1 equivalent for the value. + */ + public abstract Asn1Object GetConvertedValue(DerObjectIdentifier oid, string value); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509NameEntryConverter.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509NameEntryConverter.cs.meta new file mode 100644 index 0000000..28a904d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509NameEntryConverter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4eb5af2055210bc4488c453a4aae726c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509NameTokenizer.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509NameTokenizer.cs new file mode 100644 index 0000000..ab55295 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509NameTokenizer.cs @@ -0,0 +1,104 @@ +using System.Text; + +namespace Org.BouncyCastle.Asn1.X509 +{ + /** + * class for breaking up an X500 Name into it's component tokens, ala + * java.util.StringTokenizer. We need this class as some of the + * lightweight Java environment don't support classes like + * StringTokenizer. + */ + public class X509NameTokenizer + { + private string value; + private int index; + private char separator; + private StringBuilder buffer = new StringBuilder(); + + public X509NameTokenizer( + string oid) + : this(oid, ',') + { + } + + public X509NameTokenizer( + string oid, + char separator) + { + this.value = oid; + this.index = -1; + this.separator = separator; + } + + public bool HasMoreTokens() + { + return index != value.Length; + } + + public string NextToken() + { + if (index == value.Length) + { + return null; + } + + int end = index + 1; + bool quoted = false; + bool escaped = false; + + buffer.Remove(0, buffer.Length); + + while (end != value.Length) + { + char c = value[end]; + + if (c == '"') + { + if (!escaped) + { + quoted = !quoted; + } + else + { + buffer.Append(c); + escaped = false; + } + } + else + { + if (escaped || quoted) + { + if (c == '#' && buffer[buffer.Length - 1] == '=') + { + buffer.Append('\\'); + } + else if (c == '+' && separator != '+') + { + buffer.Append('\\'); + } + buffer.Append(c); + escaped = false; + } + else if (c == '\\') + { + escaped = true; + } + else if (c == separator) + { + break; + } + else + { + buffer.Append(c); + } + } + + end++; + } + + index = end; + + return buffer.ToString().Trim(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509NameTokenizer.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509NameTokenizer.cs.meta new file mode 100644 index 0000000..d1b8ff7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509NameTokenizer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c16746ff4307f8941a6cbe5923a04228 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509ObjectIdentifiers.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509ObjectIdentifiers.cs new file mode 100644 index 0000000..4df5bba --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509ObjectIdentifiers.cs @@ -0,0 +1,61 @@ +namespace Org.BouncyCastle.Asn1.X509 +{ + public abstract class X509ObjectIdentifiers + { + // + // base id + // + internal const string ID = "2.5.4"; + + public static readonly DerObjectIdentifier CommonName = new DerObjectIdentifier(ID + ".3"); + public static readonly DerObjectIdentifier CountryName = new DerObjectIdentifier(ID + ".6"); + public static readonly DerObjectIdentifier LocalityName = new DerObjectIdentifier(ID + ".7"); + public static readonly DerObjectIdentifier StateOrProvinceName = new DerObjectIdentifier(ID + ".8"); + public static readonly DerObjectIdentifier Organization = new DerObjectIdentifier(ID + ".10"); + public static readonly DerObjectIdentifier OrganizationalUnitName = new DerObjectIdentifier(ID + ".11"); + + public static readonly DerObjectIdentifier id_at_telephoneNumber = new DerObjectIdentifier(ID + ".20"); + public static readonly DerObjectIdentifier id_at_name = new DerObjectIdentifier(ID + ".41"); + + public static readonly DerObjectIdentifier id_at_organizationIdentifier = new DerObjectIdentifier("2.5.4.97"); + + // id-SHA1 OBJECT IDENTIFIER ::= + // {iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) 26 } // + public static readonly DerObjectIdentifier IdSha1 = new DerObjectIdentifier("1.3.14.3.2.26"); + + // + // ripemd160 OBJECT IDENTIFIER ::= + // {iso(1) identified-organization(3) TeleTrust(36) algorithm(3) hashAlgorithm(2) RipeMD-160(1)} + // + public static readonly DerObjectIdentifier RipeMD160 = new DerObjectIdentifier("1.3.36.3.2.1"); + + // + // ripemd160WithRSAEncryption OBJECT IDENTIFIER ::= + // {iso(1) identified-organization(3) TeleTrust(36) algorithm(3) signatureAlgorithm(3) rsaSignature(1) rsaSignatureWithripemd160(2) } + // + public static readonly DerObjectIdentifier RipeMD160WithRsaEncryption = new DerObjectIdentifier("1.3.36.3.3.1.2"); + + public static readonly DerObjectIdentifier IdEARsa = new DerObjectIdentifier("2.5.8.1.1"); + + // id-pkix + public static readonly DerObjectIdentifier IdPkix = new DerObjectIdentifier("1.3.6.1.5.5.7"); + + // + // private internet extensions + // + public static readonly DerObjectIdentifier IdPE = new DerObjectIdentifier(IdPkix + ".1"); + + // + // authority information access + // + public static readonly DerObjectIdentifier IdAD = new DerObjectIdentifier(IdPkix + ".48"); + public static readonly DerObjectIdentifier IdADCAIssuers = new DerObjectIdentifier(IdAD + ".2"); + public static readonly DerObjectIdentifier IdADOcsp = new DerObjectIdentifier(IdAD + ".1"); + + // + // OID for ocsp and crl uri in AuthorityInformationAccess extension + // + public static readonly DerObjectIdentifier OcspAccessMethod = IdADOcsp; + public static readonly DerObjectIdentifier CrlAccessMethod = IdADCAIssuers; + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509ObjectIdentifiers.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509ObjectIdentifiers.cs.meta new file mode 100644 index 0000000..4bcabd2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/X509ObjectIdentifiers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e7637cdd9284b204abc761f403dc9025 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified.meta new file mode 100644 index 0000000..d39c340 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 05c49c4976085b14f9279630810e1448 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified/BiometricData.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified/BiometricData.cs new file mode 100644 index 0000000..816ffd2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified/BiometricData.cs @@ -0,0 +1,104 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X509.Qualified +{ + /** + * The BiometricData object. + *
+    * BiometricData  ::=  SEQUENCE {
+    *       typeOfBiometricData  TypeOfBiometricData,
+    *       hashAlgorithm        AlgorithmIdentifier,
+    *       biometricDataHash    OCTET STRING,
+    *       sourceDataUri        IA5String OPTIONAL  }
+    * 
+ */ + public class BiometricData + : Asn1Encodable + { + private readonly TypeOfBiometricData typeOfBiometricData; + private readonly AlgorithmIdentifier hashAlgorithm; + private readonly Asn1OctetString biometricDataHash; + private readonly DerIA5String sourceDataUri; + + public static BiometricData GetInstance( + object obj) + { + if (obj == null || obj is BiometricData) + { + return (BiometricData)obj; + } + + if (obj is Asn1Sequence) + { + return new BiometricData(Asn1Sequence.GetInstance(obj)); + } + + throw new ArgumentException("unknown object in GetInstance: " + Platform.GetTypeName(obj), "obj"); + } + + private BiometricData( + Asn1Sequence seq) + { + typeOfBiometricData = TypeOfBiometricData.GetInstance(seq[0]); + hashAlgorithm = AlgorithmIdentifier.GetInstance(seq[1]); + biometricDataHash = Asn1OctetString.GetInstance(seq[2]); + + if (seq.Count > 3) + { + sourceDataUri = DerIA5String.GetInstance(seq[3]); + } + } + + public BiometricData( + TypeOfBiometricData typeOfBiometricData, + AlgorithmIdentifier hashAlgorithm, + Asn1OctetString biometricDataHash, + DerIA5String sourceDataUri) + { + this.typeOfBiometricData = typeOfBiometricData; + this.hashAlgorithm = hashAlgorithm; + this.biometricDataHash = biometricDataHash; + this.sourceDataUri = sourceDataUri; + } + + public BiometricData( + TypeOfBiometricData typeOfBiometricData, + AlgorithmIdentifier hashAlgorithm, + Asn1OctetString biometricDataHash) + { + this.typeOfBiometricData = typeOfBiometricData; + this.hashAlgorithm = hashAlgorithm; + this.biometricDataHash = biometricDataHash; + this.sourceDataUri = null; + } + + public TypeOfBiometricData TypeOfBiometricData + { + get { return typeOfBiometricData; } + } + + public AlgorithmIdentifier HashAlgorithm + { + get { return hashAlgorithm; } + } + + public Asn1OctetString BiometricDataHash + { + get { return biometricDataHash; } + } + + public DerIA5String SourceDataUri + { + get { return sourceDataUri; } + } + + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(typeOfBiometricData, hashAlgorithm, biometricDataHash); + v.AddOptional(sourceDataUri); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified/BiometricData.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified/BiometricData.cs.meta new file mode 100644 index 0000000..c984345 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified/BiometricData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7d6864db04d8e514bb54eb1909bb8db4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified/ETSIQCObjectIdentifiers.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified/ETSIQCObjectIdentifiers.cs new file mode 100644 index 0000000..86a4eee --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified/ETSIQCObjectIdentifiers.cs @@ -0,0 +1,19 @@ +using System; + +using Org.BouncyCastle.Asn1; + +namespace Org.BouncyCastle.Asn1.X509.Qualified +{ + public abstract class EtsiQCObjectIdentifiers + { + // + // base id + // + public static readonly DerObjectIdentifier IdEtsiQcs = new DerObjectIdentifier("0.4.0.1862.1"); + + public static readonly DerObjectIdentifier IdEtsiQcsQcCompliance = new DerObjectIdentifier(IdEtsiQcs+".1"); + public static readonly DerObjectIdentifier IdEtsiQcsLimitValue = new DerObjectIdentifier(IdEtsiQcs+".2"); + public static readonly DerObjectIdentifier IdEtsiQcsRetentionPeriod = new DerObjectIdentifier(IdEtsiQcs+".3"); + public static readonly DerObjectIdentifier IdEtsiQcsQcSscd = new DerObjectIdentifier(IdEtsiQcs+".4"); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified/ETSIQCObjectIdentifiers.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified/ETSIQCObjectIdentifiers.cs.meta new file mode 100644 index 0000000..a83e03e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified/ETSIQCObjectIdentifiers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5e002e5cb9f7f8a489ff60bd6ea319e6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified/Iso4217CurrencyCode.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified/Iso4217CurrencyCode.cs new file mode 100644 index 0000000..a90a33a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified/Iso4217CurrencyCode.cs @@ -0,0 +1,84 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X509.Qualified +{ + /** + * The Iso4217CurrencyCode object. + *
+    * Iso4217CurrencyCode  ::=  CHOICE {
+    *       alphabetic              PrintableString (SIZE 3), --Recommended
+    *       numeric              INTEGER (1..999) }
+    * -- Alphabetic or numeric currency code as defined in ISO 4217
+    * -- It is recommended that the Alphabetic form is used
+    * 
+ */ + public class Iso4217CurrencyCode + : Asn1Encodable, IAsn1Choice + { + internal const int AlphabeticMaxSize = 3; + internal const int NumericMinSize = 1; + internal const int NumericMaxSize = 999; + + internal Asn1Encodable obj; +// internal int numeric; + + public static Iso4217CurrencyCode GetInstance( + object obj) + { + if (obj == null || obj is Iso4217CurrencyCode) + { + return (Iso4217CurrencyCode) obj; + } + + if (obj is DerInteger) + { + DerInteger numericobj = DerInteger.GetInstance(obj); + int numeric = numericobj.IntValueExact; + return new Iso4217CurrencyCode(numeric); + } + + if (obj is DerPrintableString) + { + DerPrintableString alphabetic = DerPrintableString.GetInstance(obj); + return new Iso4217CurrencyCode(alphabetic.GetString()); + } + + throw new ArgumentException("unknown object in GetInstance: " + Platform.GetTypeName(obj), "obj"); + } + + public Iso4217CurrencyCode( + int numeric) + { + if (numeric > NumericMaxSize || numeric < NumericMinSize) + { + throw new ArgumentException("wrong size in numeric code : not in (" + NumericMinSize + ".." + NumericMaxSize + ")"); + } + + obj = new DerInteger(numeric); + } + + public Iso4217CurrencyCode( + string alphabetic) + { + if (alphabetic.Length > AlphabeticMaxSize) + { + throw new ArgumentException("wrong size in alphabetic code : max size is " + AlphabeticMaxSize); + } + + obj = new DerPrintableString(alphabetic); + } + + public bool IsAlphabetic { get { return obj is DerPrintableString; } } + + public string Alphabetic { get { return ((DerPrintableString) obj).GetString(); } } + + public int Numeric { get { return ((DerInteger)obj).IntValueExact; } } + + public override Asn1Object ToAsn1Object() + { + return obj.ToAsn1Object(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified/Iso4217CurrencyCode.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified/Iso4217CurrencyCode.cs.meta new file mode 100644 index 0000000..86937ab --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified/Iso4217CurrencyCode.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 66f3a194bb269e54bb0cd2f9ca778db1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified/MonetaryValue.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified/MonetaryValue.cs new file mode 100644 index 0000000..d703de9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified/MonetaryValue.cs @@ -0,0 +1,83 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X509.Qualified +{ + /** + * The MonetaryValue object. + *
+    * MonetaryValue  ::=  SEQUENCE {
+    *       currency              Iso4217CurrencyCode,
+    *       amount               INTEGER,
+    *       exponent             INTEGER }
+    * -- value = amount * 10^exponent
+    * 
+ */ + public class MonetaryValue + : Asn1Encodable + { + internal Iso4217CurrencyCode currency; + internal DerInteger amount; + internal DerInteger exponent; + + public static MonetaryValue GetInstance( + object obj) + { + if (obj == null || obj is MonetaryValue) + { + return (MonetaryValue) obj; + } + + if (obj is Asn1Sequence) + { + return new MonetaryValue(Asn1Sequence.GetInstance(obj)); + } + + throw new ArgumentException("unknown object in GetInstance: " + Platform.GetTypeName(obj), "obj"); + } + + private MonetaryValue( + Asn1Sequence seq) + { + if (seq.Count != 3) + throw new ArgumentException("Bad sequence size: " + seq.Count, "seq"); + + currency = Iso4217CurrencyCode.GetInstance(seq[0]); + amount = DerInteger.GetInstance(seq[1]); + exponent = DerInteger.GetInstance(seq[2]); + } + + public MonetaryValue( + Iso4217CurrencyCode currency, + int amount, + int exponent) + { + this.currency = currency; + this.amount = new DerInteger(amount); + this.exponent = new DerInteger(exponent); + } + + public Iso4217CurrencyCode Currency + { + get { return currency; } + } + + public BigInteger Amount + { + get { return amount.Value; } + } + + public BigInteger Exponent + { + get { return exponent.Value; } + } + + public override Asn1Object ToAsn1Object() + { + return new DerSequence(currency, amount, exponent); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified/MonetaryValue.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified/MonetaryValue.cs.meta new file mode 100644 index 0000000..5bd9283 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified/MonetaryValue.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fed2e7604627fe244bbe8f011462eb96 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified/QCStatement.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified/QCStatement.cs new file mode 100644 index 0000000..bfa5153 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified/QCStatement.cs @@ -0,0 +1,79 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X509.Qualified +{ + /** + * The QCStatement object. + *
+    * QCStatement ::= SEQUENCE {
+    *   statementId        OBJECT IDENTIFIER,
+    *   statementInfo      ANY DEFINED BY statementId OPTIONAL}
+    * 
+ */ + public class QCStatement + : Asn1Encodable + { + private readonly DerObjectIdentifier qcStatementId; + private readonly Asn1Encodable qcStatementInfo; + + public static QCStatement GetInstance( + object obj) + { + if (obj == null || obj is QCStatement) + { + return (QCStatement) obj; + } + + if (obj is Asn1Sequence) + { + return new QCStatement(Asn1Sequence.GetInstance(obj)); + } + + throw new ArgumentException("unknown object in GetInstance: " + Platform.GetTypeName(obj), "obj"); + } + + private QCStatement( + Asn1Sequence seq) + { + qcStatementId = DerObjectIdentifier.GetInstance(seq[0]); + + if (seq.Count > 1) + { + qcStatementInfo = seq[1]; + } + } + + public QCStatement( + DerObjectIdentifier qcStatementId) + { + this.qcStatementId = qcStatementId; + } + + public QCStatement( + DerObjectIdentifier qcStatementId, + Asn1Encodable qcStatementInfo) + { + this.qcStatementId = qcStatementId; + this.qcStatementInfo = qcStatementInfo; + } + + public DerObjectIdentifier StatementId + { + get { return qcStatementId; } + } + + public Asn1Encodable StatementInfo + { + get { return qcStatementInfo; } + } + + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(qcStatementId); + v.AddOptional(qcStatementInfo); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified/QCStatement.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified/QCStatement.cs.meta new file mode 100644 index 0000000..a511e84 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified/QCStatement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 101eaef1d9c85bd49b6f29432303dc59 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified/RFC3739QCObjectIdentifiers.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified/RFC3739QCObjectIdentifiers.cs new file mode 100644 index 0000000..8ebd69e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified/RFC3739QCObjectIdentifiers.cs @@ -0,0 +1,21 @@ +using System; + +using Org.BouncyCastle.Asn1; + +namespace Org.BouncyCastle.Asn1.X509.Qualified +{ + public sealed class Rfc3739QCObjectIdentifiers + { + private Rfc3739QCObjectIdentifiers() + { + } + + // + // base id + // + public static readonly DerObjectIdentifier IdQcs = new DerObjectIdentifier("1.3.6.1.5.5.7.11"); + + public static readonly DerObjectIdentifier IdQcsPkixQCSyntaxV1 = new DerObjectIdentifier(IdQcs+".1"); + public static readonly DerObjectIdentifier IdQcsPkixQCSyntaxV2 = new DerObjectIdentifier(IdQcs+".2"); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified/RFC3739QCObjectIdentifiers.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified/RFC3739QCObjectIdentifiers.cs.meta new file mode 100644 index 0000000..ca1e69e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified/RFC3739QCObjectIdentifiers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c6e5a0a8400aa5d4c8332ad6b55b65c8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified/SemanticsInformation.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified/SemanticsInformation.cs new file mode 100644 index 0000000..379e6d1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified/SemanticsInformation.cs @@ -0,0 +1,120 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X509.Qualified +{ + /** + * The SemanticsInformation object. + *
+    *       SemanticsInformation ::= SEQUENCE {
+    *         semanticsIdentifier        OBJECT IDENTIFIER   OPTIONAL,
+    *         nameRegistrationAuthorities NameRegistrationAuthorities
+    *                                                         OPTIONAL }
+    *         (WITH COMPONENTS {..., semanticsIdentifier PRESENT}|
+    *          WITH COMPONENTS {..., nameRegistrationAuthorities PRESENT})
+    *
+    *     NameRegistrationAuthorities ::=  SEQUENCE SIZE (1..MAX) OF
+    *         GeneralName
+    * 
+ */ + public class SemanticsInformation + : Asn1Encodable + { + private readonly DerObjectIdentifier semanticsIdentifier; + private readonly GeneralName[] nameRegistrationAuthorities; + + public static SemanticsInformation GetInstance( + object obj) + { + if (obj == null || obj is SemanticsInformation) + { + return (SemanticsInformation) obj; + } + + if (obj is Asn1Sequence) + { + return new SemanticsInformation(Asn1Sequence.GetInstance(obj)); + } + + throw new ArgumentException("unknown object in GetInstance: " + Platform.GetTypeName(obj), "obj"); + } + + public SemanticsInformation( + Asn1Sequence seq) + { + if (seq.Count < 1) + { + throw new ArgumentException("no objects in SemanticsInformation"); + } + + IEnumerator e = seq.GetEnumerator(); + e.MoveNext(); + object obj = e.Current; + if (obj is DerObjectIdentifier) + { + semanticsIdentifier = DerObjectIdentifier.GetInstance(obj); + if (e.MoveNext()) + { + obj = e.Current; + } + else + { + obj = null; + } + } + + if (obj != null) + { + Asn1Sequence generalNameSeq = Asn1Sequence.GetInstance(obj ); + nameRegistrationAuthorities = new GeneralName[generalNameSeq.Count]; + for (int i= 0; i < generalNameSeq.Count; i++) + { + nameRegistrationAuthorities[i] = GeneralName.GetInstance(generalNameSeq[i]); + } + } + } + + public SemanticsInformation( + DerObjectIdentifier semanticsIdentifier, + GeneralName[] generalNames) + { + this.semanticsIdentifier = semanticsIdentifier; + this.nameRegistrationAuthorities = generalNames; + } + + public SemanticsInformation( + DerObjectIdentifier semanticsIdentifier) + { + this.semanticsIdentifier = semanticsIdentifier; + } + + public SemanticsInformation( + GeneralName[] generalNames) + { + this.nameRegistrationAuthorities = generalNames; + } + + public DerObjectIdentifier SemanticsIdentifier { get { return semanticsIdentifier; } } + + public GeneralName[] GetNameRegistrationAuthorities() + { + return nameRegistrationAuthorities; + } + + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + v.AddOptional(semanticsIdentifier); + + if (null != nameRegistrationAuthorities) + { + v.Add(new DerSequence(nameRegistrationAuthorities)); + } + + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified/SemanticsInformation.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified/SemanticsInformation.cs.meta new file mode 100644 index 0000000..4556bd6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified/SemanticsInformation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fccd6a324827ea847ad006dd96528982 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified/TypeOfBiometricData.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified/TypeOfBiometricData.cs new file mode 100644 index 0000000..a4e2e45 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified/TypeOfBiometricData.cs @@ -0,0 +1,91 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X509.Qualified +{ + /** + * The TypeOfBiometricData object. + *
+    * TypeOfBiometricData ::= CHOICE {
+    *   predefinedBiometricType   PredefinedBiometricType,
+    *   biometricDataOid          OBJECT IDENTIFIER }
+    *
+    * PredefinedBiometricType ::= INTEGER {
+    *   picture(0),handwritten-signature(1)}
+    *   (picture|handwritten-signature)
+    * 
+ */ + public class TypeOfBiometricData + : Asn1Encodable, IAsn1Choice + { + public const int Picture = 0; + public const int HandwrittenSignature = 1; + + internal Asn1Encodable obj; + + public static TypeOfBiometricData GetInstance( + object obj) + { + if (obj == null || obj is TypeOfBiometricData) + { + return (TypeOfBiometricData) obj; + } + + if (obj is DerInteger) + { + DerInteger predefinedBiometricTypeObj = DerInteger.GetInstance(obj); + int predefinedBiometricType = predefinedBiometricTypeObj.IntValueExact; + + return new TypeOfBiometricData(predefinedBiometricType); + } + + if (obj is DerObjectIdentifier) + { + DerObjectIdentifier BiometricDataOid = DerObjectIdentifier.GetInstance(obj); + return new TypeOfBiometricData(BiometricDataOid); + } + + throw new ArgumentException("unknown object in GetInstance: " + Platform.GetTypeName(obj), "obj"); + } + + public TypeOfBiometricData( + int predefinedBiometricType) + { + if (predefinedBiometricType == Picture || predefinedBiometricType == HandwrittenSignature) + { + obj = new DerInteger(predefinedBiometricType); + } + else + { + throw new ArgumentException("unknow PredefinedBiometricType : " + predefinedBiometricType); + } + } + + public TypeOfBiometricData( + DerObjectIdentifier biometricDataOid) + { + obj = biometricDataOid; + } + + public bool IsPredefined + { + get { return obj is DerInteger; } + } + + public int PredefinedBiometricType + { + get { return ((DerInteger)obj).IntValueExact; } + } + + public DerObjectIdentifier BiometricDataOid + { + get { return (DerObjectIdentifier) obj; } + } + + public override Asn1Object ToAsn1Object() + { + return obj.ToAsn1Object(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified/TypeOfBiometricData.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified/TypeOfBiometricData.cs.meta new file mode 100644 index 0000000..f400baf --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/qualified/TypeOfBiometricData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6c30cae4ff54c404fbef1f824c4cde94 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/sigi.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/sigi.meta new file mode 100644 index 0000000..65893bd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/sigi.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 3beb5810fbf734543b07b8566f8d309c +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/sigi/NameOrPseudonym.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/sigi/NameOrPseudonym.cs new file mode 100644 index 0000000..2402e38 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/sigi/NameOrPseudonym.cs @@ -0,0 +1,178 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1.X500; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X509.SigI +{ + /** + * Structure for a name or pseudonym. + * + *
+	*       NameOrPseudonym ::= CHOICE {
+	*     	   surAndGivenName SEQUENCE {
+	*     	     surName DirectoryString,
+	*     	     givenName SEQUENCE OF DirectoryString 
+	*         },
+	*     	   pseudonym DirectoryString 
+	*       }
+	* 
+ * + * @see org.bouncycastle.asn1.x509.sigi.PersonalData + * + */ + public class NameOrPseudonym + : Asn1Encodable, IAsn1Choice + { + private readonly DirectoryString pseudonym; + private readonly DirectoryString surname; + private readonly Asn1Sequence givenName; + + public static NameOrPseudonym GetInstance( + object obj) + { + if (obj == null || obj is NameOrPseudonym) + { + return (NameOrPseudonym)obj; + } + + if (obj is IAsn1String) + { + return new NameOrPseudonym(DirectoryString.GetInstance(obj)); + } + + if (obj is Asn1Sequence) + { + return new NameOrPseudonym((Asn1Sequence) obj); + } + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + /** + * Constructor from DERString. + *

+ * The sequence is of type NameOrPseudonym: + *

+ *

+		*       NameOrPseudonym ::= CHOICE {
+		*     	   surAndGivenName SEQUENCE {
+		*     	     surName DirectoryString,
+		*     	     givenName SEQUENCE OF DirectoryString
+		*         },
+		*     	   pseudonym DirectoryString
+		*       }
+		* 
+ * @param pseudonym pseudonym value to use. + */ + public NameOrPseudonym( + DirectoryString pseudonym) + { + this.pseudonym = pseudonym; + } + + /** + * Constructor from Asn1Sequence. + *

+ * The sequence is of type NameOrPseudonym: + *

+ *

+		*       NameOrPseudonym ::= CHOICE {
+		*     	   surAndGivenName SEQUENCE {
+		*     	     surName DirectoryString,
+		*     	     givenName SEQUENCE OF DirectoryString
+		*         },
+		*     	   pseudonym DirectoryString
+		*       }
+		* 
+ * + * @param seq The ASN.1 sequence. + */ + private NameOrPseudonym( + Asn1Sequence seq) + { + if (seq.Count != 2) + throw new ArgumentException("Bad sequence size: " + seq.Count); + + if (!(seq[0] is IAsn1String)) + throw new ArgumentException("Bad object encountered: " + Platform.GetTypeName(seq[0])); + + surname = DirectoryString.GetInstance(seq[0]); + givenName = Asn1Sequence.GetInstance(seq[1]); + } + + /** + * Constructor from a given details. + * + * @param pseudonym The pseudonym. + */ + public NameOrPseudonym( + string pseudonym) + : this(new DirectoryString(pseudonym)) + { + } + + /** + * Constructor from a given details. + * + * @param surname The surname. + * @param givenName A sequence of directory strings making up the givenName + */ + public NameOrPseudonym( + DirectoryString surname, + Asn1Sequence givenName) + { + this.surname = surname; + this.givenName = givenName; + } + + public DirectoryString Pseudonym + { + get { return pseudonym; } + } + + public DirectoryString Surname + { + get { return surname; } + } + + public DirectoryString[] GetGivenName() + { + DirectoryString[] items = new DirectoryString[givenName.Count]; + int count = 0; + foreach (object o in givenName) + { + items[count++] = DirectoryString.GetInstance(o); + } + return items; + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *

+ * Returns: + *

+ *

+		*       NameOrPseudonym ::= CHOICE {
+		*     	   surAndGivenName SEQUENCE {
+		*     	     surName DirectoryString,
+		*     	     givenName SEQUENCE OF DirectoryString
+		*         },
+		*     	   pseudonym DirectoryString
+		*       }
+		* 
+ * + * @return an Asn1Object + */ + public override Asn1Object ToAsn1Object() + { + if (pseudonym != null) + { + return pseudonym.ToAsn1Object(); + } + + return new DerSequence(surname, givenName); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/sigi/NameOrPseudonym.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/sigi/NameOrPseudonym.cs.meta new file mode 100644 index 0000000..6571fde --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/sigi/NameOrPseudonym.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 88896898c8fa23c4a862ba1bb37964b5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/sigi/PersonalData.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/sigi/PersonalData.cs new file mode 100644 index 0000000..0e0bb53 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/sigi/PersonalData.cs @@ -0,0 +1,205 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1.X500; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X509.SigI +{ + /** + * Contains personal data for the otherName field in the subjectAltNames + * extension. + *

+ *

+	*     PersonalData ::= SEQUENCE {
+	*       nameOrPseudonym NameOrPseudonym,
+	*       nameDistinguisher [0] INTEGER OPTIONAL,
+	*       dateOfBirth [1] GeneralizedTime OPTIONAL,
+	*       placeOfBirth [2] DirectoryString OPTIONAL,
+	*       gender [3] PrintableString OPTIONAL,
+	*       postalAddress [4] DirectoryString OPTIONAL
+	*       }
+	* 
+ * + * @see org.bouncycastle.asn1.x509.sigi.NameOrPseudonym + * @see org.bouncycastle.asn1.x509.sigi.SigIObjectIdentifiers + */ + public class PersonalData + : Asn1Encodable + { + private readonly NameOrPseudonym nameOrPseudonym; + private readonly BigInteger nameDistinguisher; + private readonly DerGeneralizedTime dateOfBirth; + private readonly DirectoryString placeOfBirth; + private readonly string gender; + private readonly DirectoryString postalAddress; + + public static PersonalData GetInstance( + object obj) + { + if (obj == null || obj is PersonalData) + { + return (PersonalData) obj; + } + + if (obj is Asn1Sequence) + { + return new PersonalData((Asn1Sequence) obj); + } + + throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + } + + /** + * Constructor from Asn1Sequence. + *

+ * The sequence is of type NameOrPseudonym: + *

+ *

+		*     PersonalData ::= SEQUENCE {
+		*       nameOrPseudonym NameOrPseudonym,
+		*       nameDistinguisher [0] INTEGER OPTIONAL,
+		*       dateOfBirth [1] GeneralizedTime OPTIONAL,
+		*       placeOfBirth [2] DirectoryString OPTIONAL,
+		*       gender [3] PrintableString OPTIONAL,
+		*       postalAddress [4] DirectoryString OPTIONAL
+		*       }
+		* 
+ * + * @param seq The ASN.1 sequence. + */ + private PersonalData( + Asn1Sequence seq) + { + if (seq.Count < 1) + throw new ArgumentException("Bad sequence size: " + seq.Count); + + IEnumerator e = seq.GetEnumerator(); + e.MoveNext(); + + nameOrPseudonym = NameOrPseudonym.GetInstance(e.Current); + + while (e.MoveNext()) + { + Asn1TaggedObject o = Asn1TaggedObject.GetInstance(e.Current); + int tag = o.TagNo; + switch (tag) + { + case 0: + nameDistinguisher = DerInteger.GetInstance(o, false).Value; + break; + case 1: + dateOfBirth = DerGeneralizedTime.GetInstance(o, false); + break; + case 2: + placeOfBirth = DirectoryString.GetInstance(o, true); + break; + case 3: + gender = DerPrintableString.GetInstance(o, false).GetString(); + break; + case 4: + postalAddress = DirectoryString.GetInstance(o, true); + break; + default: + throw new ArgumentException("Bad tag number: " + o.TagNo); + } + } + } + + /** + * Constructor from a given details. + * + * @param nameOrPseudonym Name or pseudonym. + * @param nameDistinguisher Name distinguisher. + * @param dateOfBirth Date of birth. + * @param placeOfBirth Place of birth. + * @param gender Gender. + * @param postalAddress Postal Address. + */ + public PersonalData( + NameOrPseudonym nameOrPseudonym, + BigInteger nameDistinguisher, + DerGeneralizedTime dateOfBirth, + DirectoryString placeOfBirth, + string gender, + DirectoryString postalAddress) + { + this.nameOrPseudonym = nameOrPseudonym; + this.dateOfBirth = dateOfBirth; + this.gender = gender; + this.nameDistinguisher = nameDistinguisher; + this.postalAddress = postalAddress; + this.placeOfBirth = placeOfBirth; + } + + public NameOrPseudonym NameOrPseudonym + { + get { return nameOrPseudonym; } + } + + public BigInteger NameDistinguisher + { + get { return nameDistinguisher; } + } + + public DerGeneralizedTime DateOfBirth + { + get { return dateOfBirth; } + } + + public DirectoryString PlaceOfBirth + { + get { return placeOfBirth; } + } + + public string Gender + { + get { return gender; } + } + + public DirectoryString PostalAddress + { + get { return postalAddress; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *

+ * Returns: + *

+ *

+		*     PersonalData ::= SEQUENCE {
+		*       nameOrPseudonym NameOrPseudonym,
+		*       nameDistinguisher [0] INTEGER OPTIONAL,
+		*       dateOfBirth [1] GeneralizedTime OPTIONAL,
+		*       placeOfBirth [2] DirectoryString OPTIONAL,
+		*       gender [3] PrintableString OPTIONAL,
+		*       postalAddress [4] DirectoryString OPTIONAL
+		*       }
+		* 
+ * + * @return an Asn1Object + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(nameOrPseudonym); + + if (null != nameDistinguisher) + { + v.Add(new DerTaggedObject(false, 0, new DerInteger(nameDistinguisher))); + } + + v.AddOptionalTagged(false, 1, dateOfBirth); + v.AddOptionalTagged(true, 2, placeOfBirth); + + if (null != gender) + { + v.Add(new DerTaggedObject(false, 3, new DerPrintableString(gender, true))); + } + + v.AddOptionalTagged(true, 4, postalAddress); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/sigi/PersonalData.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/sigi/PersonalData.cs.meta new file mode 100644 index 0000000..2b369d5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/sigi/PersonalData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ce5e6e15b2087bf499777486e7def2ba +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/sigi/SigIObjectIdentifiers.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/sigi/SigIObjectIdentifiers.cs new file mode 100644 index 0000000..682311a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/sigi/SigIObjectIdentifiers.cs @@ -0,0 +1,49 @@ +using System; + +namespace Org.BouncyCastle.Asn1.X509.SigI +{ + /** + * Object Identifiers of SigI specifciation (German Signature Law + * Interoperability specification). + */ + public sealed class SigIObjectIdentifiers + { + private SigIObjectIdentifiers() + { + } + + public readonly static DerObjectIdentifier IdSigI = new DerObjectIdentifier("1.3.36.8"); + + /** + * Key purpose IDs for German SigI (Signature Interoperability + * Specification) + */ + public readonly static DerObjectIdentifier IdSigIKP = new DerObjectIdentifier(IdSigI + ".2"); + + /** + * Certificate policy IDs for German SigI (Signature Interoperability + * Specification) + */ + public readonly static DerObjectIdentifier IdSigICP = new DerObjectIdentifier(IdSigI + ".1"); + + /** + * Other Name IDs for German SigI (Signature Interoperability Specification) + */ + public readonly static DerObjectIdentifier IdSigION = new DerObjectIdentifier(IdSigI + ".4"); + + /** + * To be used for for the generation of directory service certificates. + */ + public static readonly DerObjectIdentifier IdSigIKPDirectoryService = new DerObjectIdentifier(IdSigIKP + ".1"); + + /** + * ID for PersonalData + */ + public static readonly DerObjectIdentifier IdSigIONPersonalData = new DerObjectIdentifier(IdSigION + ".1"); + + /** + * Certificate is conform to german signature law. + */ + public static readonly DerObjectIdentifier IdSigICPSigConform = new DerObjectIdentifier(IdSigICP + ".1"); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/sigi/SigIObjectIdentifiers.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/sigi/SigIObjectIdentifiers.cs.meta new file mode 100644 index 0000000..52cf811 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x509/sigi/SigIObjectIdentifiers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2926a041c1705994e9bd5f8f05a2d62f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9.meta new file mode 100644 index 0000000..85c97f9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f4696ca88bad44b40a0050afc35e466c +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/DHDomainParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/DHDomainParameters.cs new file mode 100644 index 0000000..a923227 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/DHDomainParameters.cs @@ -0,0 +1,108 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X9 +{ + public class DHDomainParameters + : Asn1Encodable + { + private readonly DerInteger p, g, q, j; + private readonly DHValidationParms validationParms; + + public static DHDomainParameters GetInstance(Asn1TaggedObject obj, bool isExplicit) + { + return GetInstance(Asn1Sequence.GetInstance(obj, isExplicit)); + } + + public static DHDomainParameters GetInstance(object obj) + { + if (obj == null || obj is DHDomainParameters) + return (DHDomainParameters)obj; + + if (obj is Asn1Sequence) + return new DHDomainParameters((Asn1Sequence)obj); + + throw new ArgumentException("Invalid DHDomainParameters: " + Platform.GetTypeName(obj), "obj"); + } + + public DHDomainParameters(DerInteger p, DerInteger g, DerInteger q, DerInteger j, + DHValidationParms validationParms) + { + if (p == null) + throw new ArgumentNullException("p"); + if (g == null) + throw new ArgumentNullException("g"); + if (q == null) + throw new ArgumentNullException("q"); + + this.p = p; + this.g = g; + this.q = q; + this.j = j; + this.validationParms = validationParms; + } + + private DHDomainParameters(Asn1Sequence seq) + { + if (seq.Count < 3 || seq.Count > 5) + throw new ArgumentException("Bad sequence size: " + seq.Count, "seq"); + + IEnumerator e = seq.GetEnumerator(); + this.p = DerInteger.GetInstance(GetNext(e)); + this.g = DerInteger.GetInstance(GetNext(e)); + this.q = DerInteger.GetInstance(GetNext(e)); + + Asn1Encodable next = GetNext(e); + + if (next != null && next is DerInteger) + { + this.j = DerInteger.GetInstance(next); + next = GetNext(e); + } + + if (next != null) + { + this.validationParms = DHValidationParms.GetInstance(next.ToAsn1Object()); + } + } + + private static Asn1Encodable GetNext(IEnumerator e) + { + return e.MoveNext() ? (Asn1Encodable)e.Current : null; + } + + public DerInteger P + { + get { return this.p; } + } + + public DerInteger G + { + get { return this.g; } + } + + public DerInteger Q + { + get { return this.q; } + } + + public DerInteger J + { + get { return this.j; } + } + + public DHValidationParms ValidationParms + { + get { return this.validationParms; } + } + + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(p, g, q); + v.AddOptional(j, validationParms); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/DHDomainParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/DHDomainParameters.cs.meta new file mode 100644 index 0000000..c11614a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/DHDomainParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e150f44f5a1139d419954d980862c87e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/DHPublicKey.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/DHPublicKey.cs new file mode 100644 index 0000000..74a14a2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/DHPublicKey.cs @@ -0,0 +1,46 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X9 +{ + public class DHPublicKey + : Asn1Encodable + { + private readonly DerInteger y; + + public static DHPublicKey GetInstance(Asn1TaggedObject obj, bool isExplicit) + { + return GetInstance(DerInteger.GetInstance(obj, isExplicit)); + } + + public static DHPublicKey GetInstance(object obj) + { + if (obj == null || obj is DHPublicKey) + return (DHPublicKey)obj; + + if (obj is DerInteger) + return new DHPublicKey((DerInteger)obj); + + throw new ArgumentException("Invalid DHPublicKey: " + Platform.GetTypeName(obj), "obj"); + } + + public DHPublicKey(DerInteger y) + { + if (y == null) + throw new ArgumentNullException("y"); + + this.y = y; + } + + public DerInteger Y + { + get { return this.y; } + } + + public override Asn1Object ToAsn1Object() + { + return this.y; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/DHPublicKey.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/DHPublicKey.cs.meta new file mode 100644 index 0000000..82f6c38 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/DHPublicKey.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: aa285ff3c20aa174c963a7f4df6a1b49 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/DHValidationParms.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/DHValidationParms.cs new file mode 100644 index 0000000..ec34f89 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/DHValidationParms.cs @@ -0,0 +1,64 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X9 +{ + public class DHValidationParms + : Asn1Encodable + { + private readonly DerBitString seed; + private readonly DerInteger pgenCounter; + + public static DHValidationParms GetInstance(Asn1TaggedObject obj, bool isExplicit) + { + return GetInstance(Asn1Sequence.GetInstance(obj, isExplicit)); + } + + public static DHValidationParms GetInstance(object obj) + { + if (obj == null || obj is DHValidationParms) + return (DHValidationParms)obj; + + if (obj is Asn1Sequence) + return new DHValidationParms((Asn1Sequence)obj); + + throw new ArgumentException("Invalid DHValidationParms: " + Platform.GetTypeName(obj), "obj"); + } + + public DHValidationParms(DerBitString seed, DerInteger pgenCounter) + { + if (seed == null) + throw new ArgumentNullException("seed"); + if (pgenCounter == null) + throw new ArgumentNullException("pgenCounter"); + + this.seed = seed; + this.pgenCounter = pgenCounter; + } + + private DHValidationParms(Asn1Sequence seq) + { + if (seq.Count != 2) + throw new ArgumentException("Bad sequence size: " + seq.Count, "seq"); + + this.seed = DerBitString.GetInstance(seq[0]); + this.pgenCounter = DerInteger.GetInstance(seq[1]); + } + + public DerBitString Seed + { + get { return this.seed; } + } + + public DerInteger PgenCounter + { + get { return this.pgenCounter; } + } + + public override Asn1Object ToAsn1Object() + { + return new DerSequence(seed, pgenCounter); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/DHValidationParms.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/DHValidationParms.cs.meta new file mode 100644 index 0000000..82c095d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/DHValidationParms.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: af93ee15cb72c68489cd874e9e7648d2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/ECNamedCurveTable.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/ECNamedCurveTable.cs new file mode 100644 index 0000000..fcd2810 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/ECNamedCurveTable.cs @@ -0,0 +1,180 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1.Anssi; +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Asn1.GM; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Sec; +using Org.BouncyCastle.Asn1.TeleTrust; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Asn1.X9 +{ + /** + * A general class that reads all X9.62 style EC curve tables. + */ + public class ECNamedCurveTable + { + /** + * return a X9ECParameters object representing the passed in named + * curve. The routine returns null if the curve is not present. + * + * @param name the name of the curve requested + * @return an X9ECParameters object or null if the curve is not available. + */ + public static X9ECParameters GetByName(string name) + { + X9ECParameters ecP = X962NamedCurves.GetByName(name); + if (ecP == null) + { + ecP = SecNamedCurves.GetByName(name); + } + if (ecP == null) + { + ecP = NistNamedCurves.GetByName(name); + } + if (ecP == null) + { + ecP = TeleTrusTNamedCurves.GetByName(name); + } + if (ecP == null) + { + ecP = AnssiNamedCurves.GetByName(name); + } + if (ecP == null) + { + ecP = ECGost3410NamedCurves.GetByNameX9(name); + } + if (ecP == null) + { + ecP = GMNamedCurves.GetByName(name); + } + return ecP; + } + + public static string GetName(DerObjectIdentifier oid) + { + string name = X962NamedCurves.GetName(oid); + if (name == null) + { + name = SecNamedCurves.GetName(oid); + } + if (name == null) + { + name = NistNamedCurves.GetName(oid); + } + if (name == null) + { + name = TeleTrusTNamedCurves.GetName(oid); + } + if (name == null) + { + name = AnssiNamedCurves.GetName(oid); + } + if (name == null) + { + name = ECGost3410NamedCurves.GetName(oid); + } + if (name == null) + { + name = GMNamedCurves.GetName(oid); + } + return name; + } + + /** + * return the object identifier signified by the passed in name. Null + * if there is no object identifier associated with name. + * + * @return the object identifier associated with name, if present. + */ + public static DerObjectIdentifier GetOid(string name) + { + DerObjectIdentifier oid = X962NamedCurves.GetOid(name); + if (oid == null) + { + oid = SecNamedCurves.GetOid(name); + } + if (oid == null) + { + oid = NistNamedCurves.GetOid(name); + } + if (oid == null) + { + oid = TeleTrusTNamedCurves.GetOid(name); + } + if (oid == null) + { + oid = AnssiNamedCurves.GetOid(name); + } + if (oid == null) + { + oid = ECGost3410NamedCurves.GetOid(name); + } + if (oid == null) + { + oid = GMNamedCurves.GetOid(name); + } + return oid; + } + + /** + * return a X9ECParameters object representing the passed in named + * curve. + * + * @param oid the object id of the curve requested + * @return an X9ECParameters object or null if the curve is not available. + */ + public static X9ECParameters GetByOid(DerObjectIdentifier oid) + { + X9ECParameters ecP = X962NamedCurves.GetByOid(oid); + if (ecP == null) + { + ecP = SecNamedCurves.GetByOid(oid); + } + + // NOTE: All the NIST curves are currently from SEC, so no point in redundant OID lookup + + if (ecP == null) + { + ecP = TeleTrusTNamedCurves.GetByOid(oid); + } + if (ecP == null) + { + ecP = AnssiNamedCurves.GetByOid(oid); + } + if (ecP == null) + { + ecP = ECGost3410NamedCurves.GetByOidX9(oid); + } + if (ecP == null) + { + ecP = GMNamedCurves.GetByOid(oid); + } + return ecP; + } + + /** + * return an enumeration of the names of the available curves. + * + * @return an enumeration of the names of the available curves. + */ + public static IEnumerable Names + { + get + { + IList v = Platform.CreateArrayList(); + CollectionUtilities.AddRange(v, X962NamedCurves.Names); + CollectionUtilities.AddRange(v, SecNamedCurves.Names); + CollectionUtilities.AddRange(v, NistNamedCurves.Names); + CollectionUtilities.AddRange(v, TeleTrusTNamedCurves.Names); + CollectionUtilities.AddRange(v, AnssiNamedCurves.Names); + CollectionUtilities.AddRange(v, ECGost3410NamedCurves.Names); + CollectionUtilities.AddRange(v, GMNamedCurves.Names); + return v; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/ECNamedCurveTable.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/ECNamedCurveTable.cs.meta new file mode 100644 index 0000000..6538373 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/ECNamedCurveTable.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 120562b034c96fb4e8d5a12a0e46d2eb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/KeySpecificInfo.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/KeySpecificInfo.cs new file mode 100644 index 0000000..4629864 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/KeySpecificInfo.cs @@ -0,0 +1,58 @@ +using System.Collections; + +namespace Org.BouncyCastle.Asn1.X9 +{ + /** + * ASN.1 def for Diffie-Hellman key exchange KeySpecificInfo structure. See + * RFC 2631, or X9.42, for further details. + */ + public class KeySpecificInfo + : Asn1Encodable + { + private DerObjectIdentifier algorithm; + private Asn1OctetString counter; + + public KeySpecificInfo( + DerObjectIdentifier algorithm, + Asn1OctetString counter) + { + this.algorithm = algorithm; + this.counter = counter; + } + + public KeySpecificInfo( + Asn1Sequence seq) + { + IEnumerator e = seq.GetEnumerator(); + + e.MoveNext(); + algorithm = (DerObjectIdentifier)e.Current; + e.MoveNext(); + counter = (Asn1OctetString)e.Current; + } + + public DerObjectIdentifier Algorithm + { + get { return algorithm; } + } + + public Asn1OctetString Counter + { + get { return counter; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         *  KeySpecificInfo ::= Sequence {
+         *      algorithm OBJECT IDENTIFIER,
+         *      counter OCTET STRING SIZE (4..4)
+         *  }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + return new DerSequence(algorithm, counter); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/KeySpecificInfo.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/KeySpecificInfo.cs.meta new file mode 100644 index 0000000..955250e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/KeySpecificInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a66c61fa21a7fc24699545dc6e7237a8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/OtherInfo.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/OtherInfo.cs new file mode 100644 index 0000000..4a52b72 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/OtherInfo.cs @@ -0,0 +1,82 @@ +using System.Collections; + +namespace Org.BouncyCastle.Asn1.X9 +{ + /** + * ANS.1 def for Diffie-Hellman key exchange OtherInfo structure. See + * RFC 2631, or X9.42, for further details. + */ + public class OtherInfo + : Asn1Encodable + { + private KeySpecificInfo keyInfo; + private Asn1OctetString partyAInfo; + private Asn1OctetString suppPubInfo; + + public OtherInfo( + KeySpecificInfo keyInfo, + Asn1OctetString partyAInfo, + Asn1OctetString suppPubInfo) + { + this.keyInfo = keyInfo; + this.partyAInfo = partyAInfo; + this.suppPubInfo = suppPubInfo; + } + + public OtherInfo( + Asn1Sequence seq) + { + IEnumerator e = seq.GetEnumerator(); + + e.MoveNext(); + keyInfo = new KeySpecificInfo((Asn1Sequence) e.Current); + + while (e.MoveNext()) + { + DerTaggedObject o = (DerTaggedObject) e.Current; + + if (o.TagNo == 0) + { + partyAInfo = (Asn1OctetString) o.GetObject(); + } + else if ((int) o.TagNo == 2) + { + suppPubInfo = (Asn1OctetString) o.GetObject(); + } + } + } + + public KeySpecificInfo KeyInfo + { + get { return keyInfo; } + } + + public Asn1OctetString PartyAInfo + { + get { return partyAInfo; } + } + + public Asn1OctetString SuppPubInfo + { + get { return suppPubInfo; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         *  OtherInfo ::= Sequence {
+         *      keyInfo KeySpecificInfo,
+         *      partyAInfo [0] OCTET STRING OPTIONAL,
+         *      suppPubInfo [2] OCTET STRING
+         *  }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(keyInfo); + v.AddOptionalTagged(true, 0, partyAInfo); + v.Add(new DerTaggedObject(2, suppPubInfo)); + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/OtherInfo.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/OtherInfo.cs.meta new file mode 100644 index 0000000..039e296 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/OtherInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4b94441c3681f694a92b891aced3a2a0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X962NamedCurves.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X962NamedCurves.cs new file mode 100644 index 0000000..131e58e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X962NamedCurves.cs @@ -0,0 +1,725 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Math.EC.Multiplier; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Asn1.X9 +{ + /** + * table of the current named curves defined in X.962 EC-DSA. + */ + public sealed class X962NamedCurves + { + private X962NamedCurves() + { + } + + private static X9ECPoint ConfigureBasepoint(ECCurve curve, string encoding) + { + X9ECPoint G = new X9ECPoint(curve, Hex.DecodeStrict(encoding)); + WNafUtilities.ConfigureBasepoint(G.Point); + return G; + } + + private static ECCurve ConfigureCurve(ECCurve curve) + { + return curve; + } + + private static BigInteger FromHex(string hex) + { + return new BigInteger(1, Hex.DecodeStrict(hex)); + } + + internal class Prime192v1Holder + : X9ECParametersHolder + { + private Prime192v1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Prime192v1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = FromHex("ffffffffffffffffffffffff99def836146bc9b1b4d22831"); + BigInteger h = BigInteger.One; + + ECCurve curve = ConfigureCurve(new FpCurve( + FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"), + FromHex("fffffffffffffffffffffffffffffffefffffffffffffffc"), + FromHex("64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1"), + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "03188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012"); + + return new X9ECParameters(curve, G, n, h, Hex.DecodeStrict("3045AE6FC8422f64ED579528D38120EAE12196D5")); + } + } + + internal class Prime192v2Holder + : X9ECParametersHolder + { + private Prime192v2Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Prime192v2Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = FromHex("fffffffffffffffffffffffe5fb1a724dc80418648d8dd31"); + BigInteger h = BigInteger.One; + + ECCurve curve = ConfigureCurve(new FpCurve( + FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"), + FromHex("fffffffffffffffffffffffffffffffefffffffffffffffc"), + FromHex("cc22d6dfb95c6b25e49c0d6364a4e5980c393aa21668d953"), + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "03eea2bae7e1497842f2de7769cfe9c989c072ad696f48034a"); + + return new X9ECParameters(curve, G, n, h, Hex.DecodeStrict("31a92ee2029fd10d901b113e990710f0d21ac6b6")); + } + } + + internal class Prime192v3Holder + : X9ECParametersHolder + { + private Prime192v3Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Prime192v3Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = FromHex("ffffffffffffffffffffffff7a62d031c83f4294f640ec13"); + BigInteger h = BigInteger.One; + + ECCurve curve = ConfigureCurve(new FpCurve( + FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"), + FromHex("fffffffffffffffffffffffffffffffefffffffffffffffc"), + FromHex("22123dc2395a05caa7423daeccc94760a7d462256bd56916"), + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "027d29778100c65a1da1783716588dce2b8b4aee8e228f1896"); + + return new X9ECParameters(curve, G, n, h, Hex.DecodeStrict("c469684435deb378c4b65ca9591e2a5763059a2e")); + } + } + + internal class Prime239v1Holder + : X9ECParametersHolder + { + private Prime239v1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Prime239v1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = FromHex("7fffffffffffffffffffffff7fffff9e5e9a9f5d9071fbd1522688909d0b"); + BigInteger h = BigInteger.One; + + ECCurve curve = ConfigureCurve(new FpCurve( + new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), + FromHex("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc"), + FromHex("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a"), + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf"); + + return new X9ECParameters(curve, G, n, h, Hex.DecodeStrict("e43bb460f0b80cc0c0b075798e948060f8321b7d")); + } + } + + internal class Prime239v2Holder + : X9ECParametersHolder + { + private Prime239v2Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Prime239v2Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = FromHex("7fffffffffffffffffffffff800000cfa7e8594377d414c03821bc582063"); + BigInteger h = BigInteger.One; + + ECCurve curve = ConfigureCurve(new FpCurve( + new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), + FromHex("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc"), + FromHex("617fab6832576cbbfed50d99f0249c3fee58b94ba0038c7ae84c8c832f2c"), + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "0238af09d98727705120c921bb5e9e26296a3cdcf2f35757a0eafd87b830e7"); + + return new X9ECParameters(curve, G, n, h, Hex.DecodeStrict("e8b4011604095303ca3b8099982be09fcb9ae616")); + } + } + + internal class Prime239v3Holder + : X9ECParametersHolder + { + private Prime239v3Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Prime239v3Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = FromHex("7fffffffffffffffffffffff7fffff975deb41b3a6057c3c432146526551"); + BigInteger h = BigInteger.One; + + ECCurve curve = ConfigureCurve(new FpCurve( + new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), + FromHex("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc"), + FromHex("255705fa2a306654b1f4cb03d6a750a30c250102d4988717d9ba15ab6d3e"), + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "036768ae8e18bb92cfcf005c949aa2c6d94853d0e660bbf854b1c9505fe95a"); + + return new X9ECParameters(curve, G, n, h, Hex.DecodeStrict("7d7374168ffe3471b60a857686a19475d3bfa2ff")); + } + } + + internal class Prime256v1Holder + : X9ECParametersHolder + { + private Prime256v1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new Prime256v1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = FromHex("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551"); + BigInteger h = BigInteger.One; + + ECCurve curve = ConfigureCurve(new FpCurve( + new BigInteger("115792089210356248762697446949407573530086143415290314195533631308867097853951"), + FromHex("ffffffff00000001000000000000000000000000fffffffffffffffffffffffc"), + FromHex("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b"), + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296"); + + return new X9ECParameters(curve, G, n, h, Hex.DecodeStrict("c49d360886e704936a6678e1139d26b7819f7e90")); + } + } + + /* + * F2m Curves + */ + internal class C2pnb163v1Holder + : X9ECParametersHolder + { + private C2pnb163v1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new C2pnb163v1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = FromHex("0400000000000000000001E60FC8821CC74DAEAFC1"); + BigInteger h = BigInteger.Two; + + ECCurve curve = ConfigureCurve(new F2mCurve( + 163, + 1, 2, 8, + FromHex("072546B5435234A422E0789675F432C89435DE5242"), + FromHex("00C9517D06D5240D3CFF38C74B20B6CD4D6F9DD4D9"), + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "0307AF69989546103D79329FCC3D74880F33BBE803CB"); + + return new X9ECParameters(curve, G, n, h, Hex.DecodeStrict("D2C0FB15760860DEF1EEF4D696E6768756151754")); + } + } + + internal class C2pnb163v2Holder + : X9ECParametersHolder + { + private C2pnb163v2Holder() {} + + internal static readonly X9ECParametersHolder Instance = new C2pnb163v2Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = FromHex("03FFFFFFFFFFFFFFFFFFFDF64DE1151ADBB78F10A7"); + BigInteger h = BigInteger.Two; + + ECCurve curve = ConfigureCurve(new F2mCurve( + 163, + 1, 2, 8, + FromHex("0108B39E77C4B108BED981ED0E890E117C511CF072"), + FromHex("0667ACEB38AF4E488C407433FFAE4F1C811638DF20"), + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "030024266E4EB5106D0A964D92C4860E2671DB9B6CC5"); + + return new X9ECParameters(curve, G, n, h); + } + } + + internal class C2pnb163v3Holder + : X9ECParametersHolder + { + private C2pnb163v3Holder() {} + + internal static readonly X9ECParametersHolder Instance = new C2pnb163v3Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = FromHex("03FFFFFFFFFFFFFFFFFFFE1AEE140F110AFF961309"); + BigInteger h = BigInteger.Two; + + ECCurve curve = ConfigureCurve(new F2mCurve( + 163, + 1, 2, 8, + FromHex("07A526C63D3E25A256A007699F5447E32AE456B50E"), + FromHex("03F7061798EB99E238FD6F1BF95B48FEEB4854252B"), + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "0202F9F87B7C574D0BDECF8A22E6524775F98CDEBDCB"); + + return new X9ECParameters(curve, G, n, h); + } + } + + internal class C2pnb176w1Holder + : X9ECParametersHolder + { + private C2pnb176w1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new C2pnb176w1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = FromHex("010092537397ECA4F6145799D62B0A19CE06FE26AD"); + BigInteger h = BigInteger.ValueOf(0xFF6E); + + ECCurve curve = ConfigureCurve(new F2mCurve( + 176, + 1, 2, 43, + FromHex("E4E6DB2995065C407D9D39B8D0967B96704BA8E9C90B"), + FromHex("5DDA470ABE6414DE8EC133AE28E9BBD7FCEC0AE0FFF2"), + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "038D16C2866798B600F9F08BB4A8E860F3298CE04A5798"); + + return new X9ECParameters(curve, G, n, h); + } + } + + internal class C2tnb191v1Holder + : X9ECParametersHolder + { + private C2tnb191v1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new C2tnb191v1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = FromHex("40000000000000000000000004A20E90C39067C893BBB9A5"); + BigInteger h = BigInteger.Two; + + ECCurve curve = ConfigureCurve(new F2mCurve( + 191, + 9, + FromHex("2866537B676752636A68F56554E12640276B649EF7526267"), + FromHex("2E45EF571F00786F67B0081B9495A3D95462F5DE0AA185EC"), + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "0236B3DAF8A23206F9C4F299D7B21A9C369137F2C84AE1AA0D"); + + return new X9ECParameters(curve, G, n, h, Hex.DecodeStrict("4E13CA542744D696E67687561517552F279A8C84")); + } + } + + internal class C2tnb191v2Holder + : X9ECParametersHolder + { + private C2tnb191v2Holder() {} + + internal static readonly X9ECParametersHolder Instance = new C2tnb191v2Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = FromHex("20000000000000000000000050508CB89F652824E06B8173"); + BigInteger h = BigInteger.ValueOf(4); + + ECCurve curve = ConfigureCurve(new F2mCurve( + 191, + 9, + FromHex("401028774D7777C7B7666D1366EA432071274F89FF01E718"), + FromHex("0620048D28BCBD03B6249C99182B7C8CD19700C362C46A01"), + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "023809B2B7CC1B28CC5A87926AAD83FD28789E81E2C9E3BF10"); + + return new X9ECParameters(curve, G, n, h); + } + } + + internal class C2tnb191v3Holder + : X9ECParametersHolder + { + private C2tnb191v3Holder() {} + + internal static readonly X9ECParametersHolder Instance = new C2tnb191v3Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = FromHex("155555555555555555555555610C0B196812BFB6288A3EA3"); + BigInteger h = BigInteger.ValueOf(6); + + ECCurve curve = ConfigureCurve(new F2mCurve( + 191, + 9, + FromHex("6C01074756099122221056911C77D77E77A777E7E7E77FCB"), + FromHex("71FE1AF926CF847989EFEF8DB459F66394D90F32AD3F15E8"), + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "03375D4CE24FDE434489DE8746E71786015009E66E38A926DD"); + + return new X9ECParameters(curve, G, n, h); + } + } + + internal class C2pnb208w1Holder + : X9ECParametersHolder + { + private C2pnb208w1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new C2pnb208w1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = FromHex("0101BAF95C9723C57B6C21DA2EFF2D5ED588BDD5717E212F9D"); + BigInteger h = BigInteger.ValueOf(0xFE48); + + ECCurve curve = ConfigureCurve(new F2mCurve( + 208, + 1, 2, 83, + BigInteger.Zero, + FromHex("C8619ED45A62E6212E1160349E2BFA844439FAFC2A3FD1638F9E"), + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "0289FDFBE4ABE193DF9559ECF07AC0CE78554E2784EB8C1ED1A57A"); + + return new X9ECParameters(curve, G, n, h); + } + } + + internal class C2tnb239v1Holder + : X9ECParametersHolder + { + private C2tnb239v1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new C2tnb239v1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = FromHex("2000000000000000000000000000000F4D42FFE1492A4993F1CAD666E447"); + BigInteger h = BigInteger.ValueOf(4); + + ECCurve curve = ConfigureCurve(new F2mCurve( + 239, + 36, + FromHex("32010857077C5431123A46B808906756F543423E8D27877578125778AC76"), + FromHex("790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16"), + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "0257927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D"); + + return new X9ECParameters(curve, G, n, h); + } + } + + internal class C2tnb239v2Holder + : X9ECParametersHolder + { + private C2tnb239v2Holder() {} + + internal static readonly X9ECParametersHolder Instance = new C2tnb239v2Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = FromHex("1555555555555555555555555555553C6F2885259C31E3FCDF154624522D"); + BigInteger h = BigInteger.ValueOf(6); + + ECCurve curve = ConfigureCurve(new F2mCurve( + 239, + 36, + FromHex("4230017757A767FAE42398569B746325D45313AF0766266479B75654E65F"), + FromHex("5037EA654196CFF0CD82B2C14A2FCF2E3FF8775285B545722F03EACDB74B"), + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "0228F9D04E900069C8DC47A08534FE76D2B900B7D7EF31F5709F200C4CA205"); + + return new X9ECParameters(curve, G, n, h); + } + } + + internal class C2tnb239v3Holder + : X9ECParametersHolder + { + private C2tnb239v3Holder() {} + + internal static readonly X9ECParametersHolder Instance = new C2tnb239v3Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = FromHex("0CCCCCCCCCCCCCCCCCCCCCCCCCCCCCAC4912D2D9DF903EF9888B8A0E4CFF"); + BigInteger h = BigInteger.ValueOf(10); + + ECCurve curve = ConfigureCurve(new F2mCurve( + 239, + 36, + FromHex("01238774666A67766D6676F778E676B66999176666E687666D8766C66A9F"), + FromHex("6A941977BA9F6A435199ACFC51067ED587F519C5ECB541B8E44111DE1D40"), + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "0370F6E9D04D289C4E89913CE3530BFDE903977D42B146D539BF1BDE4E9C92"); + + return new X9ECParameters(curve, G, n, h); + } + } + + internal class C2pnb272w1Holder + : X9ECParametersHolder + { + private C2pnb272w1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new C2pnb272w1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = FromHex("0100FAF51354E0E39E4892DF6E319C72C8161603FA45AA7B998A167B8F1E629521"); + BigInteger h = BigInteger.ValueOf(0xFF06); + + ECCurve curve = ConfigureCurve(new F2mCurve( + 272, + 1, 3, 56, + FromHex("91A091F03B5FBA4AB2CCF49C4EDD220FB028712D42BE752B2C40094DBACDB586FB20"), + FromHex("7167EFC92BB2E3CE7C8AAAFF34E12A9C557003D7C73A6FAF003F99F6CC8482E540F7"), + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "026108BABB2CEEBCF787058A056CBE0CFE622D7723A289E08A07AE13EF0D10D171DD8D"); + + return new X9ECParameters(curve, G, n, h); + } + } + + internal class C2pnb304w1Holder + : X9ECParametersHolder + { + private C2pnb304w1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new C2pnb304w1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = FromHex("0101D556572AABAC800101D556572AABAC8001022D5C91DD173F8FB561DA6899164443051D"); + BigInteger h = BigInteger.ValueOf(0xFE2E); + + ECCurve curve = ConfigureCurve(new F2mCurve( + 304, + 1, 2, 11, + FromHex("FD0D693149A118F651E6DCE6802085377E5F882D1B510B44160074C1288078365A0396C8E681"), + FromHex("BDDB97E555A50A908E43B01C798EA5DAA6788F1EA2794EFCF57166B8C14039601E55827340BE"), + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "02197B07845E9BE2D96ADB0F5F3C7F2CFFBD7A3EB8B6FEC35C7FD67F26DDF6285A644F740A2614"); + + return new X9ECParameters(curve, G, n, h); + } + } + + internal class C2tnb359v1Holder + : X9ECParametersHolder + { + private C2tnb359v1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new C2tnb359v1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = FromHex("01AF286BCA1AF286BCA1AF286BCA1AF286BCA1AF286BC9FB8F6B85C556892C20A7EB964FE7719E74F490758D3B"); + BigInteger h = BigInteger.ValueOf(0x4C); + + ECCurve curve = ConfigureCurve(new F2mCurve( + 359, + 68, + FromHex("5667676A654B20754F356EA92017D946567C46675556F19556A04616B567D223A5E05656FB549016A96656A557"), + FromHex("2472E2D0197C49363F1FE7F5B6DB075D52B6947D135D8CA445805D39BC345626089687742B6329E70680231988"), + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "033C258EF3047767E7EDE0F1FDAA79DAEE3841366A132E163ACED4ED2401DF9C6BDCDE98E8E707C07A2239B1B097"); + + return new X9ECParameters(curve, G, n, h); + } + } + + internal class C2pnb368w1Holder + : X9ECParametersHolder + { + private C2pnb368w1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new C2pnb368w1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = FromHex("010090512DA9AF72B08349D98A5DD4C7B0532ECA51CE03E2D10F3B7AC579BD87E909AE40A6F131E9CFCE5BD967"); + BigInteger h = BigInteger.ValueOf(0xFF70); + + ECCurve curve = ConfigureCurve(new F2mCurve( + 368, + 1, 2, 85, + FromHex("E0D2EE25095206F5E2A4F9ED229F1F256E79A0E2B455970D8D0D865BD94778C576D62F0AB7519CCD2A1A906AE30D"), + FromHex("FC1217D4320A90452C760A58EDCD30C8DD069B3C34453837A34ED50CB54917E1C2112D84D164F444F8F74786046A"), + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "021085E2755381DCCCE3C1557AFA10C2F0C0C2825646C5B34A394CBCFA8BC16B22E7E789E927BE216F02E1FB136A5F"); + + return new X9ECParameters(curve, G, n, h); + } + } + + internal class C2tnb431r1Holder + : X9ECParametersHolder + { + private C2tnb431r1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new C2tnb431r1Holder(); + + protected override X9ECParameters CreateParameters() + { + BigInteger n = FromHex("0340340340340340340340340340340340340340340340340340340323C313FAB50589703B5EC68D3587FEC60D161CC149C1AD4A91"); + BigInteger h = BigInteger.ValueOf(0x2760); + + ECCurve curve = ConfigureCurve(new F2mCurve( + 431, + 120, + FromHex("1A827EF00DD6FC0E234CAF046C6A5D8A85395B236CC4AD2CF32A0CADBDC9DDF620B0EB9906D0957F6C6FEACD615468DF104DE296CD8F"), + FromHex("10D9B4A3D9047D8B154359ABFB1B7F5485B04CEB868237DDC9DEDA982A679A5A919B626D4E50A8DD731B107A9962381FB5D807BF2618"), + n, h)); + + X9ECPoint G = ConfigureBasepoint(curve, + "02120FC05D3C67A99DE161D2F4092622FECA701BE4F50F4758714E8A87BBF2A658EF8C21E7C5EFE965361F6C2999C0C247B0DBD70CE6B7"); + + return new X9ECParameters(curve, G, n, h); + } + } + + + private static readonly IDictionary objIds = Platform.CreateHashtable(); + private static readonly IDictionary curves = Platform.CreateHashtable(); + private static readonly IDictionary names = Platform.CreateHashtable(); + + private static void DefineCurve( + string name, + DerObjectIdentifier oid, + X9ECParametersHolder holder) + { + objIds.Add(Platform.ToUpperInvariant(name), oid); + names.Add(oid, name); + curves.Add(oid, holder); + } + + static X962NamedCurves() + { + DefineCurve("prime192v1", X9ObjectIdentifiers.Prime192v1, Prime192v1Holder.Instance); + DefineCurve("prime192v2", X9ObjectIdentifiers.Prime192v2, Prime192v2Holder.Instance); + DefineCurve("prime192v3", X9ObjectIdentifiers.Prime192v3, Prime192v3Holder.Instance); + DefineCurve("prime239v1", X9ObjectIdentifiers.Prime239v1, Prime239v1Holder.Instance); + DefineCurve("prime239v2", X9ObjectIdentifiers.Prime239v2, Prime239v2Holder.Instance); + DefineCurve("prime239v3", X9ObjectIdentifiers.Prime239v3, Prime239v3Holder.Instance); + DefineCurve("prime256v1", X9ObjectIdentifiers.Prime256v1, Prime256v1Holder.Instance); + DefineCurve("c2pnb163v1", X9ObjectIdentifiers.C2Pnb163v1, C2pnb163v1Holder.Instance); + DefineCurve("c2pnb163v2", X9ObjectIdentifiers.C2Pnb163v2, C2pnb163v2Holder.Instance); + DefineCurve("c2pnb163v3", X9ObjectIdentifiers.C2Pnb163v3, C2pnb163v3Holder.Instance); + DefineCurve("c2pnb176w1", X9ObjectIdentifiers.C2Pnb176w1, C2pnb176w1Holder.Instance); + DefineCurve("c2tnb191v1", X9ObjectIdentifiers.C2Tnb191v1, C2tnb191v1Holder.Instance); + DefineCurve("c2tnb191v2", X9ObjectIdentifiers.C2Tnb191v2, C2tnb191v2Holder.Instance); + DefineCurve("c2tnb191v3", X9ObjectIdentifiers.C2Tnb191v3, C2tnb191v3Holder.Instance); + DefineCurve("c2pnb208w1", X9ObjectIdentifiers.C2Pnb208w1, C2pnb208w1Holder.Instance); + DefineCurve("c2tnb239v1", X9ObjectIdentifiers.C2Tnb239v1, C2tnb239v1Holder.Instance); + DefineCurve("c2tnb239v2", X9ObjectIdentifiers.C2Tnb239v2, C2tnb239v2Holder.Instance); + DefineCurve("c2tnb239v3", X9ObjectIdentifiers.C2Tnb239v3, C2tnb239v3Holder.Instance); + DefineCurve("c2pnb272w1", X9ObjectIdentifiers.C2Pnb272w1, C2pnb272w1Holder.Instance); + DefineCurve("c2pnb304w1", X9ObjectIdentifiers.C2Pnb304w1, C2pnb304w1Holder.Instance); + DefineCurve("c2tnb359v1", X9ObjectIdentifiers.C2Tnb359v1, C2tnb359v1Holder.Instance); + DefineCurve("c2pnb368w1", X9ObjectIdentifiers.C2Pnb368w1, C2pnb368w1Holder.Instance); + DefineCurve("c2tnb431r1", X9ObjectIdentifiers.C2Tnb431r1, C2tnb431r1Holder.Instance); + } + + public static X9ECParameters GetByName( + string name) + { + DerObjectIdentifier oid = GetOid(name); + return oid == null ? null : GetByOid(oid); + } + + /** + * return the X9ECParameters object for the named curve represented by + * the passed in object identifier. Null if the curve isn't present. + * + * @param oid an object identifier representing a named curve, if present. + */ + public static X9ECParameters GetByOid( + DerObjectIdentifier oid) + { + X9ECParametersHolder holder = (X9ECParametersHolder)curves[oid]; + return holder == null ? null : holder.Parameters; + } + + /** + * return the object identifier signified by the passed in name. Null + * if there is no object identifier associated with name. + * + * @return the object identifier associated with name, if present. + */ + public static DerObjectIdentifier GetOid( + string name) + { + return (DerObjectIdentifier)objIds[Platform.ToUpperInvariant(name)]; + } + + /** + * return the named curve name represented by the given object identifier. + */ + public static string GetName( + DerObjectIdentifier oid) + { + return (string)names[oid]; + } + + /** + * returns an enumeration containing the name strings for curves + * contained in this structure. + */ + public static IEnumerable Names + { + get { return new EnumerableProxy(names.Values); } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X962NamedCurves.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X962NamedCurves.cs.meta new file mode 100644 index 0000000..bdcb81c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X962NamedCurves.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 15c59226c53a2cb41a99bab17b7b3b16 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X962Parameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X962Parameters.cs new file mode 100644 index 0000000..5bdabc6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X962Parameters.cs @@ -0,0 +1,95 @@ +using System; + +using Org.BouncyCastle.Asn1; + +namespace Org.BouncyCastle.Asn1.X9 +{ + public class X962Parameters + : Asn1Encodable, IAsn1Choice + { + private readonly Asn1Object _params; + + public static X962Parameters GetInstance( + object obj) + { + if (obj == null || obj is X962Parameters) + { + return (X962Parameters)obj; + } + + if (obj is Asn1Object) + { + return new X962Parameters((Asn1Object)obj); + } + + if (obj is byte[]) + { + try + { + return new X962Parameters(Asn1Object.FromByteArray((byte[])obj)); + } + catch (Exception e) + { + throw new ArgumentException("unable to parse encoded data: " + e.Message, e); + } + } + + throw new ArgumentException("unknown object in getInstance()"); + } + + public X962Parameters( + X9ECParameters ecParameters) + { + this._params = ecParameters.ToAsn1Object(); + } + + public X962Parameters( + DerObjectIdentifier namedCurve) + { + this._params = namedCurve; + } + + public X962Parameters( + Asn1Null obj) + { + this._params = obj; + } + + [Obsolete("Use 'GetInstance' instead")] + public X962Parameters( + Asn1Object obj) + { + this._params = obj; + } + + public bool IsNamedCurve + { + get { return (_params is DerObjectIdentifier); } + } + + public bool IsImplicitlyCA + { + get { return (_params is Asn1Null); } + } + + public Asn1Object Parameters + { + get { return _params; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         * Parameters ::= CHOICE {
+         *    ecParameters ECParameters,
+         *    namedCurve   CURVES.&id({CurveNames}),
+         *    implicitlyCA Null
+         * }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + return _params; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X962Parameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X962Parameters.cs.meta new file mode 100644 index 0000000..bb2720a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X962Parameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d7cad75650ffc59409f1ed21f13838ed +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X9Curve.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X9Curve.cs new file mode 100644 index 0000000..0be9bf9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X9Curve.cs @@ -0,0 +1,155 @@ +using System; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X9 +{ + /** + * ASN.1 def for Elliptic-Curve Curve structure. See + * X9.62, for further details. + */ + public class X9Curve + : Asn1Encodable + { + private readonly ECCurve curve; + private readonly byte[] seed; + private readonly DerObjectIdentifier fieldIdentifier; + + public X9Curve( + ECCurve curve) + : this(curve, null) + { + } + + public X9Curve( + ECCurve curve, + byte[] seed) + { + if (curve == null) + throw new ArgumentNullException("curve"); + + this.curve = curve; + this.seed = Arrays.Clone(seed); + + if (ECAlgorithms.IsFpCurve(curve)) + { + this.fieldIdentifier = X9ObjectIdentifiers.PrimeField; + } + else if (ECAlgorithms.IsF2mCurve(curve)) + { + this.fieldIdentifier = X9ObjectIdentifiers.CharacteristicTwoField; + } + else + { + throw new ArgumentException("This type of ECCurve is not implemented"); + } + } + + [Obsolete("Use constructor including order/cofactor")] + public X9Curve( + X9FieldID fieldID, + Asn1Sequence seq) + : this(fieldID, null, null, seq) + { + } + + public X9Curve( + X9FieldID fieldID, + BigInteger order, + BigInteger cofactor, + Asn1Sequence seq) + { + if (fieldID == null) + throw new ArgumentNullException("fieldID"); + if (seq == null) + throw new ArgumentNullException("seq"); + + this.fieldIdentifier = fieldID.Identifier; + + if (fieldIdentifier.Equals(X9ObjectIdentifiers.PrimeField)) + { + BigInteger p = ((DerInteger)fieldID.Parameters).Value; + BigInteger A = new BigInteger(1, Asn1OctetString.GetInstance(seq[0]).GetOctets()); + BigInteger B = new BigInteger(1, Asn1OctetString.GetInstance(seq[1]).GetOctets()); + curve = new FpCurve(p, A, B, order, cofactor); + } + else if (fieldIdentifier.Equals(X9ObjectIdentifiers.CharacteristicTwoField)) + { + // Characteristic two field + DerSequence parameters = (DerSequence)fieldID.Parameters; + int m = ((DerInteger)parameters[0]).IntValueExact; + DerObjectIdentifier representation = (DerObjectIdentifier)parameters[1]; + + int k1 = 0; + int k2 = 0; + int k3 = 0; + if (representation.Equals(X9ObjectIdentifiers.TPBasis)) + { + // Trinomial basis representation + k1 = ((DerInteger)parameters[2]).IntValueExact; + } + else + { + // Pentanomial basis representation + DerSequence pentanomial = (DerSequence) parameters[2]; + k1 = ((DerInteger)pentanomial[0]).IntValueExact; + k2 = ((DerInteger)pentanomial[1]).IntValueExact; + k3 = ((DerInteger)pentanomial[2]).IntValueExact; + } + BigInteger A = new BigInteger(1, Asn1OctetString.GetInstance(seq[0]).GetOctets()); + BigInteger B = new BigInteger(1, Asn1OctetString.GetInstance(seq[1]).GetOctets()); + curve = new F2mCurve(m, k1, k2, k3, A, B, order, cofactor); + } + else + { + throw new ArgumentException("This type of ECCurve is not implemented"); + } + + if (seq.Count == 3) + { + seed = ((DerBitString)seq[2]).GetBytes(); + } + } + + public ECCurve Curve + { + get { return curve; } + } + + public byte[] GetSeed() + { + return Arrays.Clone(seed); + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         *  Curve ::= Sequence {
+         *      a               FieldElement,
+         *      b               FieldElement,
+         *      seed            BIT STRING      OPTIONAL
+         *  }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + + if (fieldIdentifier.Equals(X9ObjectIdentifiers.PrimeField) + || fieldIdentifier.Equals(X9ObjectIdentifiers.CharacteristicTwoField)) + { + v.Add(new X9FieldElement(curve.A).ToAsn1Object()); + v.Add(new X9FieldElement(curve.B).ToAsn1Object()); + } + + if (seed != null) + { + v.Add(new DerBitString(seed)); + } + + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X9Curve.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X9Curve.cs.meta new file mode 100644 index 0000000..82ea59e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X9Curve.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dc116676005418b4fb2835d4e9967dac +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X9ECParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X9ECParameters.cs new file mode 100644 index 0000000..aa84063 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X9ECParameters.cs @@ -0,0 +1,230 @@ +using System; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Math.Field; + +namespace Org.BouncyCastle.Asn1.X9 +{ + /** + * ASN.1 def for Elliptic-Curve ECParameters structure. See + * X9.62, for further details. + */ + public class X9ECParameters + : Asn1Encodable + { + private X9FieldID fieldID; + private ECCurve curve; + private X9ECPoint g; + private BigInteger n; + private BigInteger h; + private byte[] seed; + + public static X9ECParameters GetInstance(Object obj) + { + if (obj is X9ECParameters) + return (X9ECParameters)obj; + + if (obj != null) + return new X9ECParameters(Asn1Sequence.GetInstance(obj)); + + return null; + } + + public X9ECParameters( + Asn1Sequence seq) + { + if (!(seq[0] is DerInteger) + || !((DerInteger)seq[0]).HasValue(1)) + { + throw new ArgumentException("bad version in X9ECParameters"); + } + + this.n = ((DerInteger)seq[4]).Value; + + if (seq.Count == 6) + { + this.h = ((DerInteger)seq[5]).Value; + } + + X9Curve x9c = new X9Curve( + X9FieldID.GetInstance(seq[1]), n, h, + Asn1Sequence.GetInstance(seq[2])); + + this.curve = x9c.Curve; + object p = seq[3]; + + if (p is X9ECPoint) + { + this.g = (X9ECPoint)p; + } + else + { + this.g = new X9ECPoint(curve, (Asn1OctetString)p); + } + + this.seed = x9c.GetSeed(); + } + + public X9ECParameters( + ECCurve curve, + ECPoint g, + BigInteger n) + : this(curve, g, n, null, null) + { + } + + public X9ECParameters( + ECCurve curve, + X9ECPoint g, + BigInteger n, + BigInteger h) + : this(curve, g, n, h, null) + { + } + + public X9ECParameters( + ECCurve curve, + ECPoint g, + BigInteger n, + BigInteger h) + : this(curve, g, n, h, null) + { + } + + public X9ECParameters( + ECCurve curve, + ECPoint g, + BigInteger n, + BigInteger h, + byte[] seed) + : this(curve, new X9ECPoint(g), n, h, seed) + { + } + + public X9ECParameters( + ECCurve curve, + X9ECPoint g, + BigInteger n, + BigInteger h, + byte[] seed) + { + this.curve = curve; + this.g = g; + this.n = n; + this.h = h; + this.seed = seed; + + if (ECAlgorithms.IsFpCurve(curve)) + { + this.fieldID = new X9FieldID(curve.Field.Characteristic); + } + else if (ECAlgorithms.IsF2mCurve(curve)) + { + IPolynomialExtensionField field = (IPolynomialExtensionField)curve.Field; + int[] exponents = field.MinimalPolynomial.GetExponentsPresent(); + if (exponents.Length == 3) + { + this.fieldID = new X9FieldID(exponents[2], exponents[1]); + } + else if (exponents.Length == 5) + { + this.fieldID = new X9FieldID(exponents[4], exponents[1], exponents[2], exponents[3]); + } + else + { + throw new ArgumentException("Only trinomial and pentomial curves are supported"); + } + } + else + { + throw new ArgumentException("'curve' is of an unsupported type"); + } + } + + public ECCurve Curve + { + get { return curve; } + } + + public ECPoint G + { + get { return g.Point; } + } + + public BigInteger N + { + get { return n; } + } + + public BigInteger H + { + get { return h; } + } + + public byte[] GetSeed() + { + return seed; + } + + /** + * Return the ASN.1 entry representing the Curve. + * + * @return the X9Curve for the curve in these parameters. + */ + public X9Curve CurveEntry + { + get { return new X9Curve(curve, seed); } + } + + /** + * Return the ASN.1 entry representing the FieldID. + * + * @return the X9FieldID for the FieldID in these parameters. + */ + public X9FieldID FieldIDEntry + { + get { return fieldID; } + } + + /** + * Return the ASN.1 entry representing the base point G. + * + * @return the X9ECPoint for the base point in these parameters. + */ + public X9ECPoint BaseEntry + { + get { return g; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         *  ECParameters ::= Sequence {
+         *      version         Integer { ecpVer1(1) } (ecpVer1),
+         *      fieldID         FieldID {{FieldTypes}},
+         *      curve           X9Curve,
+         *      base            X9ECPoint,
+         *      order           Integer,
+         *      cofactor        Integer OPTIONAL
+         *  }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector( + new DerInteger(BigInteger.One), + fieldID, + new X9Curve(curve, seed), + g, + new DerInteger(n)); + + if (h != null) + { + v.Add(new DerInteger(h)); + } + + return new DerSequence(v); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X9ECParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X9ECParameters.cs.meta new file mode 100644 index 0000000..f25e1da --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X9ECParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 181acf43dc11e2e43b11dfdf85e6299c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X9ECParametersHolder.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X9ECParametersHolder.cs new file mode 100644 index 0000000..e802b73 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X9ECParametersHolder.cs @@ -0,0 +1,25 @@ +namespace Org.BouncyCastle.Asn1.X9 +{ + public abstract class X9ECParametersHolder + { + private X9ECParameters parameters; + + public X9ECParameters Parameters + { + get + { + lock (this) + { + if (parameters == null) + { + parameters = CreateParameters(); + } + + return parameters; + } + } + } + + protected abstract X9ECParameters CreateParameters(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X9ECParametersHolder.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X9ECParametersHolder.cs.meta new file mode 100644 index 0000000..8786ba4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X9ECParametersHolder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b647f364611decf4c962a0e094c561e7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X9ECPoint.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X9ECPoint.cs new file mode 100644 index 0000000..7ef4f13 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X9ECPoint.cs @@ -0,0 +1,80 @@ +using Org.BouncyCastle.Math.EC; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.X9 +{ + /** + * class for describing an ECPoint as a Der object. + */ + public class X9ECPoint + : Asn1Encodable + { + private readonly Asn1OctetString encoding; + + private ECCurve c; + private ECPoint p; + + public X9ECPoint(ECPoint p) + : this(p, false) + { + } + + public X9ECPoint(ECPoint p, bool compressed) + { + this.p = p.Normalize(); + this.encoding = new DerOctetString(p.GetEncoded(compressed)); + } + + public X9ECPoint(ECCurve c, byte[] encoding) + { + this.c = c; + this.encoding = new DerOctetString(Arrays.Clone(encoding)); + } + + public X9ECPoint(ECCurve c, Asn1OctetString s) + : this(c, s.GetOctets()) + { + } + + public byte[] GetPointEncoding() + { + return Arrays.Clone(encoding.GetOctets()); + } + + public ECPoint Point + { + get + { + if (p == null) + { + p = c.DecodePoint(encoding.GetOctets()).Normalize(); + } + + return p; + } + } + + public bool IsPointCompressed + { + get + { + byte[] octets = encoding.GetOctets(); + return octets != null && octets.Length > 0 && (octets[0] == 2 || octets[0] == 3); + } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         *  ECPoint ::= OCTET STRING
+         * 
+ *

+ * Octet string produced using ECPoint.GetEncoded().

+ */ + public override Asn1Object ToAsn1Object() + { + return encoding; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X9ECPoint.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X9ECPoint.cs.meta new file mode 100644 index 0000000..a16b2bc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X9ECPoint.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2ae1df3f3d172df45aca4feb62694721 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X9FieldElement.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X9FieldElement.cs new file mode 100644 index 0000000..222b4cf --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X9FieldElement.cs @@ -0,0 +1,71 @@ +using System; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; + +namespace Org.BouncyCastle.Asn1.X9 +{ + /** + * Class for processing an ECFieldElement as a DER object. + */ + public class X9FieldElement + : Asn1Encodable + { + private ECFieldElement f; + + public X9FieldElement( + ECFieldElement f) + { + this.f = f; + } + + [Obsolete("Will be removed")] + public X9FieldElement( + BigInteger p, + Asn1OctetString s) + : this(new FpFieldElement(p, new BigInteger(1, s.GetOctets()))) + { + } + + [Obsolete("Will be removed")] + public X9FieldElement( + int m, + int k1, + int k2, + int k3, + Asn1OctetString s) + : this(new F2mFieldElement(m, k1, k2, k3, new BigInteger(1, s.GetOctets()))) + { + } + + public ECFieldElement Value + { + get { return f; } + } + + /** + * Produce an object suitable for an Asn1OutputStream. + *
+         *  FieldElement ::= OCTET STRING
+         * 
+ *

+ *

    + *
  1. if q is an odd prime then the field element is + * processed as an Integer and converted to an octet string + * according to x 9.62 4.3.1.
  2. + *
  3. if q is 2m then the bit string + * contained in the field element is converted into an octet + * string with the same ordering padded at the front if necessary. + *
  4. + *
+ *

+ */ + public override Asn1Object ToAsn1Object() + { + int byteCount = X9IntegerConverter.GetByteLength(f); + byte[] paddedBigInteger = X9IntegerConverter.IntegerToBytes(f.ToBigInteger(), byteCount); + + return new DerOctetString(paddedBigInteger); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X9FieldElement.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X9FieldElement.cs.meta new file mode 100644 index 0000000..2cda5c5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X9FieldElement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7114b9790141d134d8021c99539de3aa +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X9FieldID.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X9FieldID.cs new file mode 100644 index 0000000..08d7d71 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X9FieldID.cs @@ -0,0 +1,132 @@ +using System; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Asn1.X9 +{ + /** + * ASN.1 def for Elliptic-Curve Field ID structure. See + * X9.62, for further details. + */ + public class X9FieldID + : Asn1Encodable + { + private readonly DerObjectIdentifier id; + private readonly Asn1Object parameters; + + /** + * Constructor for elliptic curves over prime fields + * F2. + * @param primeP The prime p defining the prime field. + */ + public X9FieldID( + BigInteger primeP) + { + this.id = X9ObjectIdentifiers.PrimeField; + this.parameters = new DerInteger(primeP); + } + + /** + * Constructor for elliptic curves over binary fields + * F2m. + * @param m The exponent m of + * F2m. + * @param k1 The integer k1 where xm + + * xk1 + 1 + * represents the reduction polynomial f(z). + */ + public X9FieldID(int m, int k1) + : this(m, k1, 0, 0) + { + } + + /** + * Constructor for elliptic curves over binary fields + * F2m. + * @param m The exponent m of + * F2m. + * @param k1 The integer k1 where xm + + * xk3 + xk2 + xk1 + 1 + * represents the reduction polynomial f(z). + * @param k2 The integer k2 where xm + + * xk3 + xk2 + xk1 + 1 + * represents the reduction polynomial f(z). + * @param k3 The integer k3 where xm + + * xk3 + xk2 + xk1 + 1 + * represents the reduction polynomial f(z).. + */ + public X9FieldID( + int m, + int k1, + int k2, + int k3) + { + this.id = X9ObjectIdentifiers.CharacteristicTwoField; + + Asn1EncodableVector fieldIdParams = new Asn1EncodableVector(new DerInteger(m)); + + if (k2 == 0) + { + if (k3 != 0) + throw new ArgumentException("inconsistent k values"); + + fieldIdParams.Add( + X9ObjectIdentifiers.TPBasis, + new DerInteger(k1)); + } + else + { + if (k2 <= k1 || k3 <= k2) + throw new ArgumentException("inconsistent k values"); + + fieldIdParams.Add( + X9ObjectIdentifiers.PPBasis, + new DerSequence( + new DerInteger(k1), + new DerInteger(k2), + new DerInteger(k3))); + } + + this.parameters = new DerSequence(fieldIdParams); + } + + private X9FieldID(Asn1Sequence seq) + { + this.id = DerObjectIdentifier.GetInstance(seq[0]); + this.parameters = seq[1].ToAsn1Object(); + } + + public static X9FieldID GetInstance(object obj) + { + if (obj is X9FieldID) + return (X9FieldID)obj; + if (obj == null) + return null; + return new X9FieldID(Asn1Sequence.GetInstance(obj)); + } + + public DerObjectIdentifier Identifier + { + get { return id; } + } + + public Asn1Object Parameters + { + get { return parameters; } + } + + /** + * Produce a Der encoding of the following structure. + *
+         *  FieldID ::= Sequence {
+         *      fieldType       FIELD-ID.&id({IOSet}),
+         *      parameters      FIELD-ID.&Type({IOSet}{@fieldType})
+         *  }
+         * 
+ */ + public override Asn1Object ToAsn1Object() + { + return new DerSequence(id, parameters); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X9FieldID.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X9FieldID.cs.meta new file mode 100644 index 0000000..63312a9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X9FieldID.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9f04908977b952c459a978e7bbeecae6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X9IntegerConverter.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X9IntegerConverter.cs new file mode 100644 index 0000000..e8f4571 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X9IntegerConverter.cs @@ -0,0 +1,40 @@ +using System; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; + +namespace Org.BouncyCastle.Asn1.X9 +{ + public abstract class X9IntegerConverter + { + public static int GetByteLength(ECFieldElement fe) + { + return (fe.FieldSize + 7) / 8; + } + + public static int GetByteLength(ECCurve c) + { + return (c.FieldSize + 7) / 8; + } + + public static byte[] IntegerToBytes(BigInteger s, int qLength) + { + byte[] bytes = s.ToByteArrayUnsigned(); + + if (qLength < bytes.Length) + { + byte[] tmp = new byte[qLength]; + Array.Copy(bytes, bytes.Length - tmp.Length, tmp, 0, tmp.Length); + return tmp; + } + else if (qLength > bytes.Length) + { + byte[] tmp = new byte[qLength]; + Array.Copy(bytes, 0, tmp, tmp.Length - bytes.Length, bytes.Length); + return tmp; + } + + return bytes; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X9IntegerConverter.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X9IntegerConverter.cs.meta new file mode 100644 index 0000000..077e744 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X9IntegerConverter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: be045c1cdaa1e7247b67f32592641b23 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X9ObjectIdentifiers.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X9ObjectIdentifiers.cs new file mode 100644 index 0000000..9d7ecae --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X9ObjectIdentifiers.cs @@ -0,0 +1,137 @@ +using System; + +namespace Org.BouncyCastle.Asn1.X9 +{ + public abstract class X9ObjectIdentifiers + { + // + // X9.62 + // + // ansi-X9-62 OBJECT IDENTIFIER ::= { iso(1) member-body(2) + // us(840) ansi-x962(10045) } + // + + internal const string AnsiX962 = "1.2.840.10045"; + + public static readonly DerObjectIdentifier ansi_X9_62 = new DerObjectIdentifier(AnsiX962); + + public static readonly DerObjectIdentifier IdFieldType = ansi_X9_62.Branch("1"); + + public static readonly DerObjectIdentifier PrimeField = IdFieldType.Branch("1"); + public static readonly DerObjectIdentifier CharacteristicTwoField = IdFieldType.Branch("2"); + + public static readonly DerObjectIdentifier GNBasis = CharacteristicTwoField.Branch("3.1"); + public static readonly DerObjectIdentifier TPBasis = CharacteristicTwoField.Branch("3.2"); + public static readonly DerObjectIdentifier PPBasis = CharacteristicTwoField.Branch("3.3"); + + [Obsolete("Use 'id_ecSigType' instead")] + public const string IdECSigType = AnsiX962 + ".4"; + public static readonly DerObjectIdentifier id_ecSigType = ansi_X9_62.Branch("4"); + + public static readonly DerObjectIdentifier ECDsaWithSha1 = id_ecSigType.Branch("1"); + + [Obsolete("Use 'id_publicKeyType' instead")] + public const string IdPublicKeyType = AnsiX962 + ".2"; + public static readonly DerObjectIdentifier id_publicKeyType = ansi_X9_62.Branch("2"); + + public static readonly DerObjectIdentifier IdECPublicKey = id_publicKeyType.Branch("1"); + + public static readonly DerObjectIdentifier ECDsaWithSha2 = id_ecSigType.Branch("3"); + + public static readonly DerObjectIdentifier ECDsaWithSha224 = ECDsaWithSha2.Branch("1"); + public static readonly DerObjectIdentifier ECDsaWithSha256 = ECDsaWithSha2.Branch("2"); + public static readonly DerObjectIdentifier ECDsaWithSha384 = ECDsaWithSha2.Branch("3"); + public static readonly DerObjectIdentifier ECDsaWithSha512 = ECDsaWithSha2.Branch("4"); + + + // + // named curves + // + public static readonly DerObjectIdentifier EllipticCurve = ansi_X9_62.Branch("3"); + + // + // Two Curves + // + public static readonly DerObjectIdentifier CTwoCurve = EllipticCurve.Branch("0"); + + public static readonly DerObjectIdentifier C2Pnb163v1 = CTwoCurve.Branch("1"); + public static readonly DerObjectIdentifier C2Pnb163v2 = CTwoCurve.Branch("2"); + public static readonly DerObjectIdentifier C2Pnb163v3 = CTwoCurve.Branch("3"); + public static readonly DerObjectIdentifier C2Pnb176w1 = CTwoCurve.Branch("4"); + public static readonly DerObjectIdentifier C2Tnb191v1 = CTwoCurve.Branch("5"); + public static readonly DerObjectIdentifier C2Tnb191v2 = CTwoCurve.Branch("6"); + public static readonly DerObjectIdentifier C2Tnb191v3 = CTwoCurve.Branch("7"); + public static readonly DerObjectIdentifier C2Onb191v4 = CTwoCurve.Branch("8"); + public static readonly DerObjectIdentifier C2Onb191v5 = CTwoCurve.Branch("9"); + public static readonly DerObjectIdentifier C2Pnb208w1 = CTwoCurve.Branch("10"); + public static readonly DerObjectIdentifier C2Tnb239v1 = CTwoCurve.Branch("11"); + public static readonly DerObjectIdentifier C2Tnb239v2 = CTwoCurve.Branch("12"); + public static readonly DerObjectIdentifier C2Tnb239v3 = CTwoCurve.Branch("13"); + public static readonly DerObjectIdentifier C2Onb239v4 = CTwoCurve.Branch("14"); + public static readonly DerObjectIdentifier C2Onb239v5 = CTwoCurve.Branch("15"); + public static readonly DerObjectIdentifier C2Pnb272w1 = CTwoCurve.Branch("16"); + public static readonly DerObjectIdentifier C2Pnb304w1 = CTwoCurve.Branch("17"); + public static readonly DerObjectIdentifier C2Tnb359v1 = CTwoCurve.Branch("18"); + public static readonly DerObjectIdentifier C2Pnb368w1 = CTwoCurve.Branch("19"); + public static readonly DerObjectIdentifier C2Tnb431r1 = CTwoCurve.Branch("20"); + + // + // Prime + // + public static readonly DerObjectIdentifier PrimeCurve = EllipticCurve.Branch("1"); + + public static readonly DerObjectIdentifier Prime192v1 = PrimeCurve.Branch("1"); + public static readonly DerObjectIdentifier Prime192v2 = PrimeCurve.Branch("2"); + public static readonly DerObjectIdentifier Prime192v3 = PrimeCurve.Branch("3"); + public static readonly DerObjectIdentifier Prime239v1 = PrimeCurve.Branch("4"); + public static readonly DerObjectIdentifier Prime239v2 = PrimeCurve.Branch("5"); + public static readonly DerObjectIdentifier Prime239v3 = PrimeCurve.Branch("6"); + public static readonly DerObjectIdentifier Prime256v1 = PrimeCurve.Branch("7"); + + // + // DSA + // + // dsapublicnumber OBJECT IDENTIFIER ::= { iso(1) member-body(2) + // us(840) ansi-x957(10040) number-type(4) 1 } + public static readonly DerObjectIdentifier IdDsa = new DerObjectIdentifier("1.2.840.10040.4.1"); + + /** + * id-dsa-with-sha1 OBJECT IDENTIFIER ::= { iso(1) member-body(2) + * us(840) x9-57 (10040) x9cm(4) 3 } + */ + public static readonly DerObjectIdentifier IdDsaWithSha1 = new DerObjectIdentifier("1.2.840.10040.4.3"); + + /** + * X9.63 + */ + public static readonly DerObjectIdentifier X9x63Scheme = new DerObjectIdentifier("1.3.133.16.840.63.0"); + public static readonly DerObjectIdentifier DHSinglePassStdDHSha1KdfScheme = X9x63Scheme.Branch("2"); + public static readonly DerObjectIdentifier DHSinglePassCofactorDHSha1KdfScheme = X9x63Scheme.Branch("3"); + public static readonly DerObjectIdentifier MqvSinglePassSha1KdfScheme = X9x63Scheme.Branch("16"); + + /** + * X9.42 + */ + + public static readonly DerObjectIdentifier ansi_x9_42 = new DerObjectIdentifier("1.2.840.10046"); + + // + // Diffie-Hellman + // + // dhpublicnumber OBJECT IDENTIFIER ::= { iso(1) member-body(2) + // us(840) ansi-x942(10046) number-type(2) 1 } + // + public static readonly DerObjectIdentifier DHPublicNumber = ansi_x9_42.Branch("2.1"); + + public static readonly DerObjectIdentifier X9x42Schemes = ansi_x9_42.Branch("2.3"); + + public static readonly DerObjectIdentifier DHStatic = X9x42Schemes.Branch("1"); + public static readonly DerObjectIdentifier DHEphem = X9x42Schemes.Branch("2"); + public static readonly DerObjectIdentifier DHOneFlow = X9x42Schemes.Branch("3"); + public static readonly DerObjectIdentifier DHHybrid1 = X9x42Schemes.Branch("4"); + public static readonly DerObjectIdentifier DHHybrid2 = X9x42Schemes.Branch("5"); + public static readonly DerObjectIdentifier DHHybridOneFlow = X9x42Schemes.Branch("6"); + public static readonly DerObjectIdentifier Mqv2 = X9x42Schemes.Branch("7"); + public static readonly DerObjectIdentifier Mqv1 = X9x42Schemes.Branch("8"); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X9ObjectIdentifiers.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X9ObjectIdentifiers.cs.meta new file mode 100644 index 0000000..2a3e336 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/asn1/x9/X9ObjectIdentifiers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 430fc90d0c427124392c75fa259f6237 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg.meta new file mode 100644 index 0000000..dee3194 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f1467c9ea07220b429ff19a21a346ec1 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ArmoredInputStream.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ArmoredInputStream.cs new file mode 100644 index 0000000..2895c37 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ArmoredInputStream.cs @@ -0,0 +1,541 @@ +using System; +using System.Collections; +using System.IO; +using System.Text; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Bcpg +{ + /** + * reader for Base64 armored objects - read the headers and then start returning + * bytes when the data is reached. An IOException is thrown if the CRC check + * is detected and fails. + *

+ * By default a missing CRC will not cause an exception. To force CRC detection use: + *

+     *     ArmoredInputStream aIn = ...
+     *
+     *     aIn.setDetectMissingCRC(true);
+     * 
+ *

+ */ + public class ArmoredInputStream + : BaseInputStream + { + /* + * set up the decoding table. + */ + private readonly static byte[] decodingTable; + static ArmoredInputStream() + { + decodingTable = new byte[128]; + Arrays.Fill(decodingTable, 0xff); + for (int i = 'A'; i <= 'Z'; i++) + { + decodingTable[i] = (byte)(i - 'A'); + } + for (int i = 'a'; i <= 'z'; i++) + { + decodingTable[i] = (byte)(i - 'a' + 26); + } + for (int i = '0'; i <= '9'; i++) + { + decodingTable[i] = (byte)(i - '0' + 52); + } + decodingTable['+'] = 62; + decodingTable['/'] = 63; + } + + /** + * decode the base 64 encoded input data. + * + * @return the offset the data starts in out. + */ + private static int Decode(int in0, int in1, int in2, int in3, int[] result) + { + if (in3 < 0) + throw new EndOfStreamException("unexpected end of file in armored stream."); + + int b1, b2, b3, b4; + if (in2 == '=') + { + b1 = decodingTable[in0]; + b2 = decodingTable[in1]; + if ((b1 | b2) >= 128) + throw new IOException("invalid armor"); + + result[2] = ((b1 << 2) | (b2 >> 4)) & 0xff; + return 2; + } + else if (in3 == '=') + { + b1 = decodingTable[in0]; + b2 = decodingTable[in1]; + b3 = decodingTable[in2]; + if ((b1 | b2 | b3) >= 128) + throw new IOException("invalid armor"); + + result[1] = ((b1 << 2) | (b2 >> 4)) & 0xff; + result[2] = ((b2 << 4) | (b3 >> 2)) & 0xff; + return 1; + } + else + { + b1 = decodingTable[in0]; + b2 = decodingTable[in1]; + b3 = decodingTable[in2]; + b4 = decodingTable[in3]; + if ((b1 | b2 | b3 | b4) >= 128) + throw new IOException("invalid armor"); + + result[0] = ((b1 << 2) | (b2 >> 4)) & 0xff; + result[1] = ((b2 << 4) | (b3 >> 2)) & 0xff; + result[2] = ((b3 << 6) | b4) & 0xff; + return 0; + } + } + + /* + * Ignore missing CRC checksums. + * https://tests.sequoia-pgp.org/#ASCII_Armor suggests that missing CRC sums do not invalidate the message. + */ + private bool detectMissingChecksum = false; + + Stream input; + bool start = true; + int[] outBuf = new int[3]; + int bufPtr = 3; + Crc24 crc = new Crc24(); + bool crcFound = false; + bool hasHeaders = true; + string header = null; + bool newLineFound = false; + bool clearText = false; + bool restart = false; + IList headerList = Platform.CreateArrayList(); + int lastC = 0; + bool isEndOfStream; + + /** + * Create a stream for reading a PGP armoured message, parsing up to a header + * and then reading the data that follows. + * + * @param input + */ + public ArmoredInputStream(Stream input) + : this(input, true) + { + } + + /** + * Create an armoured input stream which will assume the data starts + * straight away, or parse for headers first depending on the value of + * hasHeaders. + * + * @param input + * @param hasHeaders true if headers are to be looked for, false otherwise. + */ + public ArmoredInputStream(Stream input, bool hasHeaders) + { + this.input = input; + this.hasHeaders = hasHeaders; + + if (hasHeaders) + { + ParseHeaders(); + } + + start = false; + } + + private bool ParseHeaders() + { + header = null; + + int c; + int last = 0; + bool headerFound = false; + + headerList = Platform.CreateArrayList(); + + // + // if restart we already have a header + // + if (restart) + { + headerFound = true; + } + else + { + while ((c = input.ReadByte()) >= 0) + { + if (c == '-' && (last == 0 || last == '\n' || last == '\r')) + { + headerFound = true; + break; + } + + last = c; + } + } + + if (headerFound) + { + StringBuilder buf = new StringBuilder("-"); + bool eolReached = false; + bool crLf = false; + + if (restart) // we've had to look ahead two '-' + { + buf.Append('-'); + } + + while ((c = input.ReadByte()) >= 0) + { + if (last == '\r' && c == '\n') + { + crLf = true; + } + if (eolReached && (last != '\r' && c == '\n')) + { + break; + } + if (eolReached && c == '\r') + { + break; + } + if (c == '\r' || (last != '\r' && c == '\n')) + { + string line = buf.ToString(); + if (line.Trim().Length < 1) + break; + + if (headerList.Count > 0 && line.IndexOf(':') < 0) + throw new IOException("invalid armor header"); + + headerList.Add(line); + buf.Length = 0; + } + + if (c != '\n' && c != '\r') + { + buf.Append((char)c); + eolReached = false; + } + else + { + if (c == '\r' || (last != '\r' && c == '\n')) + { + eolReached = true; + } + } + + last = c; + } + + if (crLf) + { + input.ReadByte(); // skip last \n + } + } + + if (headerList.Count > 0) + { + header = (string)headerList[0]; + } + + clearText = "-----BEGIN PGP SIGNED MESSAGE-----".Equals(header); + newLineFound = true; + + return headerFound; + } + + /** + * @return true if we are inside the clear text section of a PGP + * signed message. + */ + public bool IsClearText() + { + return clearText; + } + + /** + * @return true if the stream is actually at end of file. + */ + public bool IsEndOfStream() + { + return isEndOfStream; + } + + /** + * Return the armor header line (if there is one) + * @return the armor header line, null if none present. + */ + public string GetArmorHeaderLine() + { + return header; + } + + /** + * Return the armor headers (the lines after the armor header line), + * @return an array of armor headers, null if there aren't any. + */ + public string[] GetArmorHeaders() + { + if (headerList.Count <= 1) + return null; + + string[] hdrs = new string[headerList.Count - 1]; + for (int i = 0; i != hdrs.Length; i++) + { + hdrs[i] = (string)headerList[i + 1]; + } + + return hdrs; + } + + private int ReadIgnoreSpace() + { + int c; + do + { + c = input.ReadByte(); + } + while (c == ' ' || c == '\t' || c == '\f' || c == '\u000B') ; // \u000B ~ \v + + if (c >= 128) + throw new IOException("invalid armor"); + + return c; + } + + public override int ReadByte() + { + if (start) + { + if (hasHeaders) + { + ParseHeaders(); + } + + crc.Reset(); + start = false; + } + + int c; + + if (clearText) + { + c = input.ReadByte(); + + if (c == '\r' || (c == '\n' && lastC != '\r')) + { + newLineFound = true; + } + else if (newLineFound && c == '-') + { + c = input.ReadByte(); + if (c == '-') // a header, not dash escaped + { + clearText = false; + start = true; + restart = true; + } + else // a space - must be a dash escape + { + c = input.ReadByte(); + } + newLineFound = false; + } + else + { + if (c != '\n' && lastC != '\r') + { + newLineFound = false; + } + } + + lastC = c; + + if (c < 0) + { + isEndOfStream = true; + } + + return c; + } + + if (bufPtr > 2 || crcFound) + { + c = ReadIgnoreSpace(); + + if (c == '\r' || c == '\n') + { + c = ReadIgnoreSpace(); + + while (c == '\n' || c == '\r') + { + c = ReadIgnoreSpace(); + } + + if (c < 0) // EOF + { + isEndOfStream = true; + return -1; + } + + if (c == '=') // crc reached + { + bufPtr = Decode(ReadIgnoreSpace(), ReadIgnoreSpace(), ReadIgnoreSpace(), ReadIgnoreSpace(), outBuf); + if (bufPtr == 0) + { + int i = ((outBuf[0] & 0xff) << 16) + | ((outBuf[1] & 0xff) << 8) + | (outBuf[2] & 0xff); + + crcFound = true; + + if (i != crc.Value) + { + throw new IOException("crc check failed in armored message."); + } + return ReadByte(); + } + else + { + if (detectMissingChecksum) + { + throw new IOException("no crc found in armored message"); + } + } + } + else if (c == '-') // end of record reached + { + while ((c = input.ReadByte()) >= 0) + { + if (c == '\n' || c == '\r') + { + break; + } + } + + if (!crcFound && detectMissingChecksum) + { + throw new IOException("crc check not found"); + } + + crcFound = false; + start = true; + bufPtr = 3; + + if (c < 0) + { + isEndOfStream = true; + } + + return -1; + } + else // data + { + bufPtr = Decode(c, ReadIgnoreSpace(), ReadIgnoreSpace(), ReadIgnoreSpace(), outBuf); + } + } + else + { + if (c >= 0) + { + bufPtr = Decode(c, ReadIgnoreSpace(), ReadIgnoreSpace(), ReadIgnoreSpace(), outBuf); + } + else + { + isEndOfStream = true; + return -1; + } + } + } + + c = outBuf[bufPtr++]; + + crc.Update(c); + + return c; + } + + /** + * Reads up to len bytes of data from the input stream into + * an array of bytes. An attempt is made to read as many as + * len bytes, but a smaller number may be read. + * The number of bytes actually read is returned as an integer. + * + * The first byte read is stored into element b[off], the + * next one into b[off+1], and so on. The number of bytes read + * is, at most, equal to len. + * + * NOTE: We need to override the custom behavior of Java's {@link InputStream#read(byte[], int, int)}, + * as the upstream method silently swallows {@link IOException IOExceptions}. + * This would cause CRC checksum errors to go unnoticed. + * + * @see Related BC bug report + * @param b byte array + * @param off offset at which we start writing data to the array + * @param len number of bytes we write into the array + * @return total number of bytes read into the buffer + * + * @throws IOException if an exception happens AT ANY POINT + */ + public override int Read(byte[] b, int off, int len) + { + CheckIndexSize(b.Length, off, len); + + int pos = 0; + while (pos < len) + { + int c = ReadByte(); + if (c < 0) + break; + + b[off + pos++] = (byte)c; + } + return pos; + } + + private void CheckIndexSize(int size, int off, int len) + { + if (off < 0 || len < 0) + throw new IndexOutOfRangeException("Offset and length cannot be negative."); + if (off > size - len) + throw new IndexOutOfRangeException("Invalid offset and length."); + } + +#if PORTABLE + protected override void Dispose(bool disposing) + { + if (disposing) + { + Platform.Dispose(input); + } + base.Dispose(disposing); + } +#else + public override void Close() + { + Platform.Dispose(input); + base.Close(); + } +#endif + + /** + * Change how the stream should react if it encounters missing CRC checksum. + * The default value is false (ignore missing CRC checksums). If the behavior is set to true, + * an {@link IOException} will be thrown if a missing CRC checksum is encountered. + * + * @param detectMissing ignore missing CRC sums + */ + public virtual void SetDetectMissingCrc(bool detectMissing) + { + this.detectMissingChecksum = detectMissing; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ArmoredInputStream.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ArmoredInputStream.cs.meta new file mode 100644 index 0000000..ba6cbec --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ArmoredInputStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4e8a010555be6314fa307a68e7f55a7f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ArmoredOutputStream.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ArmoredOutputStream.cs new file mode 100644 index 0000000..0df5d11 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ArmoredOutputStream.cs @@ -0,0 +1,415 @@ +using System; +using System.Collections; +using System.Diagnostics; +using System.IO; +using System.Reflection; +using System.Text; + +#if PORTABLE +using System.Linq; +#endif + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Bcpg +{ + /** + * Basic output stream. + */ + public class ArmoredOutputStream + : BaseOutputStream + { + public static readonly string HeaderVersion = "Version"; + + private static readonly byte[] encodingTable = + { + (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G', + (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N', + (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U', + (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z', + (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g', + (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n', + (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u', + (byte)'v', + (byte)'w', (byte)'x', (byte)'y', (byte)'z', + (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', + (byte)'7', (byte)'8', (byte)'9', + (byte)'+', (byte)'/' + }; + + /** + * encode the input data producing a base 64 encoded byte array. + */ + private static void Encode( + Stream outStream, + int[] data, + int len) + { + Debug.Assert(len > 0); + Debug.Assert(len < 4); + + byte[] bs = new byte[4]; + int d1 = data[0]; + bs[0] = encodingTable[(d1 >> 2) & 0x3f]; + + switch (len) + { + case 1: + { + bs[1] = encodingTable[(d1 << 4) & 0x3f]; + bs[2] = (byte)'='; + bs[3] = (byte)'='; + break; + } + case 2: + { + int d2 = data[1]; + bs[1] = encodingTable[((d1 << 4) | (d2 >> 4)) & 0x3f]; + bs[2] = encodingTable[(d2 << 2) & 0x3f]; + bs[3] = (byte)'='; + break; + } + case 3: + { + int d2 = data[1]; + int d3 = data[2]; + bs[1] = encodingTable[((d1 << 4) | (d2 >> 4)) & 0x3f]; + bs[2] = encodingTable[((d2 << 2) | (d3 >> 6)) & 0x3f]; + bs[3] = encodingTable[d3 & 0x3f]; + break; + } + } + + outStream.Write(bs, 0, bs.Length); + } + + private readonly Stream outStream; + private int[] buf = new int[3]; + private int bufPtr = 0; + private Crc24 crc = new Crc24(); + private int chunkCount = 0; + private int lastb; + + private bool start = true; + private bool clearText = false; + private bool newLine = false; + + private string type; + + private static readonly string nl = Platform.NewLine; + private static readonly string headerStart = "-----BEGIN PGP "; + private static readonly string headerTail = "-----"; + private static readonly string footerStart = "-----END PGP "; + private static readonly string footerTail = "-----"; + + private static readonly string Version = "BCPG C# v" + AssemblyInfo.Version; + + private readonly IDictionary headers; + + public ArmoredOutputStream(Stream outStream) + { + this.outStream = outStream; + this.headers = Platform.CreateHashtable(1); + SetHeader(HeaderVersion, Version); + } + + public ArmoredOutputStream(Stream outStream, IDictionary headers) + : this(outStream) + { + foreach (string header in headers.Keys) + { + IList headerList = Platform.CreateArrayList(1); + headerList.Add(headers[header]); + + this.headers[header] = headerList; + } + } + + /** + * Set an additional header entry. Any current value(s) under the same name will be + * replaced by the new one. A null value will clear the entry for name. * + * @param name the name of the header entry. + * @param v the value of the header entry. + */ + public void SetHeader(string name, string val) + { + if (val == null) + { + this.headers.Remove(name); + } + else + { + IList valueList = (IList)headers[name]; + if (valueList == null) + { + valueList = Platform.CreateArrayList(1); + this.headers[name] = valueList; + } + else + { + valueList.Clear(); + } + valueList.Add(val); + } + } + + /** + * Set an additional header entry. The current value(s) will continue to exist together + * with the new one. Adding a null value has no effect. + * + * @param name the name of the header entry. + * @param value the value of the header entry. + */ + public void AddHeader(string name, string val) + { + if (val == null || name == null) + return; + + IList valueList = (IList)headers[name]; + if (valueList == null) + { + valueList = Platform.CreateArrayList(1); + this.headers[name] = valueList; + } + valueList.Add(val); + } + + /** + * Reset the headers to only contain a Version string (if one is present). + */ + public void ResetHeaders() + { + IList versions = (IList)headers[HeaderVersion]; + + headers.Clear(); + + if (versions != null) + { + headers[HeaderVersion] = versions; + } + } + + /** + * Start a clear text signed message. + * @param hashAlgorithm + */ + public void BeginClearText( + HashAlgorithmTag hashAlgorithm) + { + string hash; + + switch (hashAlgorithm) + { + case HashAlgorithmTag.Sha1: + hash = "SHA1"; + break; + case HashAlgorithmTag.Sha256: + hash = "SHA256"; + break; + case HashAlgorithmTag.Sha384: + hash = "SHA384"; + break; + case HashAlgorithmTag.Sha512: + hash = "SHA512"; + break; + case HashAlgorithmTag.MD2: + hash = "MD2"; + break; + case HashAlgorithmTag.MD5: + hash = "MD5"; + break; + case HashAlgorithmTag.RipeMD160: + hash = "RIPEMD160"; + break; + default: + throw new IOException("unknown hash algorithm tag in beginClearText: " + hashAlgorithm); + } + + DoWrite("-----BEGIN PGP SIGNED MESSAGE-----" + nl); + DoWrite("Hash: " + hash + nl + nl); + + clearText = true; + newLine = true; + lastb = 0; + } + + public void EndClearText() + { + clearText = false; + } + + public override void WriteByte( + byte b) + { + if (clearText) + { + outStream.WriteByte(b); + + if (newLine) + { + if (!(b == '\n' && lastb == '\r')) + { + newLine = false; + } + if (b == '-') + { + outStream.WriteByte((byte)' '); + outStream.WriteByte((byte)'-'); // dash escape + } + } + if (b == '\r' || (b == '\n' && lastb != '\r')) + { + newLine = true; + } + lastb = b; + return; + } + + if (start) + { + bool newPacket = (b & 0x40) != 0; + + int tag; + if (newPacket) + { + tag = b & 0x3f; + } + else + { + tag = (b & 0x3f) >> 2; + } + + switch ((PacketTag)tag) + { + case PacketTag.PublicKey: + type = "PUBLIC KEY BLOCK"; + break; + case PacketTag.SecretKey: + type = "PRIVATE KEY BLOCK"; + break; + case PacketTag.Signature: + type = "SIGNATURE"; + break; + default: + type = "MESSAGE"; + break; + } + + DoWrite(headerStart + type + headerTail + nl); + + { + IList versionHeaders = (IList)headers[HeaderVersion]; + if (versionHeaders != null) + { + WriteHeaderEntry(HeaderVersion, versionHeaders[0].ToString()); + } + } + + foreach (DictionaryEntry de in headers) + { + string k = (string)de.Key; + if (k != HeaderVersion) + { + IList values = (IList)de.Value; + foreach (string v in values) + { + WriteHeaderEntry(k, v); + } + } + } + + DoWrite(nl); + + start = false; + } + + if (bufPtr == 3) + { + Encode(outStream, buf, bufPtr); + bufPtr = 0; + if ((++chunkCount & 0xf) == 0) + { + DoWrite(nl); + } + } + + crc.Update(b); + buf[bufPtr++] = b & 0xff; + } + + /** + * Note: Close() does not close the underlying stream. So it is possible to write + * multiple objects using armoring to a single stream. + */ +#if PORTABLE + protected override void Dispose(bool disposing) + { + if (disposing) + { + if (type == null) + return; + + DoClose(); + + type = null; + start = true; + } + base.Dispose(disposing); + } +#else + public override void Close() + { + if (type == null) + return; + + DoClose(); + + type = null; + start = true; + + base.Close(); + } +#endif + + private void DoClose() + { + if (bufPtr > 0) + { + Encode(outStream, buf, bufPtr); + } + + DoWrite(nl + '='); + + int crcV = crc.Value; + + buf[0] = ((crcV >> 16) & 0xff); + buf[1] = ((crcV >> 8) & 0xff); + buf[2] = (crcV & 0xff); + + Encode(outStream, buf, 3); + + DoWrite(nl); + DoWrite(footerStart); + DoWrite(type); + DoWrite(footerTail); + DoWrite(nl); + + outStream.Flush(); + } + + private void WriteHeaderEntry( + string name, + string v) + { + DoWrite(name + ": " + v + nl); + } + + private void DoWrite( + string s) + { + byte[] bs = Strings.ToAsciiByteArray(s); + outStream.Write(bs, 0, bs.Length); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ArmoredOutputStream.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ArmoredOutputStream.cs.meta new file mode 100644 index 0000000..778c61b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ArmoredOutputStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 376526e849993b246a2b2e8d2a420b94 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/BcpgInputStream.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/BcpgInputStream.cs new file mode 100644 index 0000000..5efef19 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/BcpgInputStream.cs @@ -0,0 +1,379 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Bcpg +{ + /// Reader for PGP objects. + public class BcpgInputStream + : BaseInputStream + { + private Stream m_in; + private bool next = false; + private int nextB; + + internal static BcpgInputStream Wrap( + Stream inStr) + { + if (inStr is BcpgInputStream) + { + return (BcpgInputStream) inStr; + } + + return new BcpgInputStream(inStr); + } + + private BcpgInputStream( + Stream inputStream) + { + this.m_in = inputStream; + } + + public override int ReadByte() + { + if (next) + { + next = false; + return nextB; + } + + return m_in.ReadByte(); + } + + public override int Read( + byte[] buffer, + int offset, + int count) + { + // Strangely, when count == 0, we should still attempt to read a byte +// if (count == 0) +// return 0; + + if (!next) + return m_in.Read(buffer, offset, count); + + // We have next byte waiting, so return it + + if (nextB < 0) + return 0; // EndOfStream + + if (buffer == null) + throw new ArgumentNullException("buffer"); + + buffer[offset] = (byte) nextB; + next = false; + + return 1; + } + + public byte[] ReadAll() + { + return Streams.ReadAll(this); + } + + public void ReadFully( + byte[] buffer, + int off, + int len) + { + if (Streams.ReadFully(this, buffer, off, len) < len) + throw new EndOfStreamException(); + } + + public void ReadFully( + byte[] buffer) + { + ReadFully(buffer, 0, buffer.Length); + } + + /// Returns the next packet tag in the stream. + public PacketTag NextPacketTag() + { + if (!next) + { + try + { + nextB = m_in.ReadByte(); + } + catch (EndOfStreamException) + { + nextB = -1; + } + + next = true; + } + + if (nextB < 0) + return (PacketTag)nextB; + + int maskB = nextB & 0x3f; + if ((nextB & 0x40) == 0) // old + { + maskB >>= 2; + } + return (PacketTag)maskB; + } + + public Packet ReadPacket() + { + int hdr = this.ReadByte(); + + if (hdr < 0) + { + return null; + } + + if ((hdr & 0x80) == 0) + { + throw new IOException("invalid header encountered"); + } + + bool newPacket = (hdr & 0x40) != 0; + PacketTag tag = 0; + int bodyLen = 0; + bool partial = false; + + if (newPacket) + { + tag = (PacketTag)(hdr & 0x3f); + + int l = this.ReadByte(); + + if (l < 192) + { + bodyLen = l; + } + else if (l <= 223) + { + int b = m_in.ReadByte(); + bodyLen = ((l - 192) << 8) + (b) + 192; + } + else if (l == 255) + { + bodyLen = (m_in.ReadByte() << 24) | (m_in.ReadByte() << 16) + | (m_in.ReadByte() << 8) | m_in.ReadByte(); + } + else + { + partial = true; + bodyLen = 1 << (l & 0x1f); + } + } + else + { + int lengthType = hdr & 0x3; + + tag = (PacketTag)((hdr & 0x3f) >> 2); + + switch (lengthType) + { + case 0: + bodyLen = this.ReadByte(); + break; + case 1: + bodyLen = (this.ReadByte() << 8) | this.ReadByte(); + break; + case 2: + bodyLen = (this.ReadByte() << 24) | (this.ReadByte() << 16) + | (this.ReadByte() << 8) | this.ReadByte(); + break; + case 3: + partial = true; + break; + default: + throw new IOException("unknown length type encountered"); + } + } + + BcpgInputStream objStream; + if (bodyLen == 0 && partial) + { + objStream = this; + } + else + { + PartialInputStream pis = new PartialInputStream(this, partial, bodyLen); +#if NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE + Stream buf = pis; +#else + Stream buf = new BufferedStream(pis); +#endif + objStream = new BcpgInputStream(buf); + } + + switch (tag) + { + case PacketTag.Reserved: + return new InputStreamPacket(objStream); + case PacketTag.PublicKeyEncryptedSession: + return new PublicKeyEncSessionPacket(objStream); + case PacketTag.Signature: + return new SignaturePacket(objStream); + case PacketTag.SymmetricKeyEncryptedSessionKey: + return new SymmetricKeyEncSessionPacket(objStream); + case PacketTag.OnePassSignature: + return new OnePassSignaturePacket(objStream); + case PacketTag.SecretKey: + return new SecretKeyPacket(objStream); + case PacketTag.PublicKey: + return new PublicKeyPacket(objStream); + case PacketTag.SecretSubkey: + return new SecretSubkeyPacket(objStream); + case PacketTag.CompressedData: + return new CompressedDataPacket(objStream); + case PacketTag.SymmetricKeyEncrypted: + return new SymmetricEncDataPacket(objStream); + case PacketTag.Marker: + return new MarkerPacket(objStream); + case PacketTag.LiteralData: + return new LiteralDataPacket(objStream); + case PacketTag.Trust: + return new TrustPacket(objStream); + case PacketTag.UserId: + return new UserIdPacket(objStream); + case PacketTag.UserAttribute: + return new UserAttributePacket(objStream); + case PacketTag.PublicSubkey: + return new PublicSubkeyPacket(objStream); + case PacketTag.SymmetricEncryptedIntegrityProtected: + return new SymmetricEncIntegrityPacket(objStream); + case PacketTag.ModificationDetectionCode: + return new ModDetectionCodePacket(objStream); + case PacketTag.Experimental1: + case PacketTag.Experimental2: + case PacketTag.Experimental3: + case PacketTag.Experimental4: + return new ExperimentalPacket(tag, objStream); + default: + throw new IOException("unknown packet type encountered: " + tag); + } + } + + public PacketTag SkipMarkerPackets() + { + PacketTag tag; + while ((tag = NextPacketTag()) == PacketTag.Marker) + { + ReadPacket(); + } + + return tag; + } + +#if PORTABLE + protected override void Dispose(bool disposing) + { + if (disposing) + { + Platform.Dispose(m_in); + } + base.Dispose(disposing); + } +#else + public override void Close() + { + Platform.Dispose(m_in); + base.Close(); + } +#endif + + /// + /// A stream that overlays our input stream, allowing the user to only read a segment of it. + /// NB: dataLength will be negative if the segment length is in the upper range above 2**31. + /// + private class PartialInputStream + : BaseInputStream + { + private BcpgInputStream m_in; + private bool partial; + private int dataLength; + + internal PartialInputStream( + BcpgInputStream bcpgIn, + bool partial, + int dataLength) + { + this.m_in = bcpgIn; + this.partial = partial; + this.dataLength = dataLength; + } + + public override int ReadByte() + { + do + { + if (dataLength != 0) + { + int ch = m_in.ReadByte(); + if (ch < 0) + { + throw new EndOfStreamException("Premature end of stream in PartialInputStream"); + } + dataLength--; + return ch; + } + } + while (partial && ReadPartialDataLength() >= 0); + + return -1; + } + + public override int Read(byte[] buffer, int offset, int count) + { + do + { + if (dataLength != 0) + { + int readLen = (dataLength > count || dataLength < 0) ? count : dataLength; + int len = m_in.Read(buffer, offset, readLen); + if (len < 1) + { + throw new EndOfStreamException("Premature end of stream in PartialInputStream"); + } + dataLength -= len; + return len; + } + } + while (partial && ReadPartialDataLength() >= 0); + + return 0; + } + + private int ReadPartialDataLength() + { + int l = m_in.ReadByte(); + + if (l < 0) + { + return -1; + } + + partial = false; + + if (l < 192) + { + dataLength = l; + } + else if (l <= 223) + { + dataLength = ((l - 192) << 8) + (m_in.ReadByte()) + 192; + } + else if (l == 255) + { + dataLength = (m_in.ReadByte() << 24) | (m_in.ReadByte() << 16) + | (m_in.ReadByte() << 8) | m_in.ReadByte(); + } + else + { + partial = true; + dataLength = 1 << (l & 0x1f); + } + + return 0; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/BcpgInputStream.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/BcpgInputStream.cs.meta new file mode 100644 index 0000000..79ecef5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/BcpgInputStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a07e5e2c4a530a644bbad516d5d4c9b0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/BcpgObject.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/BcpgObject.cs new file mode 100644 index 0000000..4807ad4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/BcpgObject.cs @@ -0,0 +1,22 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Bcpg +{ + /// Base class for a PGP object. + public abstract class BcpgObject + { + public virtual byte[] GetEncoded() + { + MemoryStream bOut = new MemoryStream(); + BcpgOutputStream pOut = new BcpgOutputStream(bOut); + + pOut.WriteObject(this); + + return bOut.ToArray(); + } + + public abstract void Encode(BcpgOutputStream bcpgOut); + } +} + diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/BcpgObject.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/BcpgObject.cs.meta new file mode 100644 index 0000000..bf69caf --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/BcpgObject.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 11144df5a9773ce45a2bb9af1aded846 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/BcpgOutputStream.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/BcpgOutputStream.cs new file mode 100644 index 0000000..738c282 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/BcpgOutputStream.cs @@ -0,0 +1,405 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Bcpg +{ + /// Basic output stream. + public class BcpgOutputStream + : BaseOutputStream + { + internal static BcpgOutputStream Wrap( + Stream outStr) + { + if (outStr is BcpgOutputStream) + { + return (BcpgOutputStream) outStr; + } + + return new BcpgOutputStream(outStr); + } + + private Stream outStr; + private byte[] partialBuffer; + private int partialBufferLength; + private int partialPower; + private int partialOffset; + private const int BufferSizePower = 16; // 2^16 size buffer on long files + + /// Create a stream representing a general packet. + /// Output stream to write to. + public BcpgOutputStream( + Stream outStr) + { + if (outStr == null) + throw new ArgumentNullException("outStr"); + + this.outStr = outStr; + } + + /// Create a stream representing an old style partial object. + /// Output stream to write to. + /// The packet tag for the object. + public BcpgOutputStream( + Stream outStr, + PacketTag tag) + { + if (outStr == null) + throw new ArgumentNullException("outStr"); + + this.outStr = outStr; + this.WriteHeader(tag, true, true, 0); + } + + /// Create a stream representing a general packet. + /// Output stream to write to. + /// Packet tag. + /// Size of chunks making up the packet. + /// If true, the header is written out in old format. + public BcpgOutputStream( + Stream outStr, + PacketTag tag, + long length, + bool oldFormat) + { + if (outStr == null) + throw new ArgumentNullException("outStr"); + + this.outStr = outStr; + + if (length > 0xFFFFFFFFL) + { + this.WriteHeader(tag, false, true, 0); + this.partialBufferLength = 1 << BufferSizePower; + this.partialBuffer = new byte[partialBufferLength]; + this.partialPower = BufferSizePower; + this.partialOffset = 0; + } + else + { + this.WriteHeader(tag, oldFormat, false, length); + } + } + + /// Create a new style partial input stream buffered into chunks. + /// Output stream to write to. + /// Packet tag. + /// Size of chunks making up the packet. + public BcpgOutputStream( + Stream outStr, + PacketTag tag, + long length) + { + if (outStr == null) + throw new ArgumentNullException("outStr"); + + this.outStr = outStr; + this.WriteHeader(tag, false, false, length); + } + + /// Create a new style partial input stream buffered into chunks. + /// Output stream to write to. + /// Packet tag. + /// Buffer to use for collecting chunks. + public BcpgOutputStream( + Stream outStr, + PacketTag tag, + byte[] buffer) + { + if (outStr == null) + throw new ArgumentNullException("outStr"); + + this.outStr = outStr; + this.WriteHeader(tag, false, true, 0); + + this.partialBuffer = buffer; + + uint length = (uint) partialBuffer.Length; + for (partialPower = 0; length != 1; partialPower++) + { + length >>= 1; + } + + if (partialPower > 30) + { + throw new IOException("Buffer cannot be greater than 2^30 in length."); + } + this.partialBufferLength = 1 << partialPower; + this.partialOffset = 0; + } + + private void WriteNewPacketLength( + long bodyLen) + { + if (bodyLen < 192) + { + outStr.WriteByte((byte)bodyLen); + } + else if (bodyLen <= 8383) + { + bodyLen -= 192; + + outStr.WriteByte((byte)(((bodyLen >> 8) & 0xff) + 192)); + outStr.WriteByte((byte)bodyLen); + } + else + { + outStr.WriteByte(0xff); + outStr.WriteByte((byte)(bodyLen >> 24)); + outStr.WriteByte((byte)(bodyLen >> 16)); + outStr.WriteByte((byte)(bodyLen >> 8)); + outStr.WriteByte((byte)bodyLen); + } + } + + private void WriteHeader( + PacketTag tag, + bool oldPackets, + bool partial, + long bodyLen) + { + int hdr = 0x80; + + if (partialBuffer != null) + { + PartialFlush(true); + partialBuffer = null; + } + + if (oldPackets) + { + hdr |= ((int) tag) << 2; + + if (partial) + { + this.WriteByte((byte)(hdr | 0x03)); + } + else + { + if (bodyLen <= 0xff) + { + this.WriteByte((byte) hdr); + this.WriteByte((byte)bodyLen); + } + else if (bodyLen <= 0xffff) + { + this.WriteByte((byte)(hdr | 0x01)); + this.WriteByte((byte)(bodyLen >> 8)); + this.WriteByte((byte)(bodyLen)); + } + else + { + this.WriteByte((byte)(hdr | 0x02)); + this.WriteByte((byte)(bodyLen >> 24)); + this.WriteByte((byte)(bodyLen >> 16)); + this.WriteByte((byte)(bodyLen >> 8)); + this.WriteByte((byte)bodyLen); + } + } + } + else + { + hdr |= 0x40 | (int) tag; + this.WriteByte((byte) hdr); + + if (partial) + { + partialOffset = 0; + } + else + { + this.WriteNewPacketLength(bodyLen); + } + } + } + + private void PartialFlush( + bool isLast) + { + if (isLast) + { + WriteNewPacketLength(partialOffset); + outStr.Write(partialBuffer, 0, partialOffset); + } + else + { + outStr.WriteByte((byte)(0xE0 | partialPower)); + outStr.Write(partialBuffer, 0, partialBufferLength); + } + + partialOffset = 0; + } + + private void WritePartial( + byte b) + { + if (partialOffset == partialBufferLength) + { + PartialFlush(false); + } + + partialBuffer[partialOffset++] = b; + } + + private void WritePartial( + byte[] buffer, + int off, + int len) + { + if (partialOffset == partialBufferLength) + { + PartialFlush(false); + } + + if (len <= (partialBufferLength - partialOffset)) + { + Array.Copy(buffer, off, partialBuffer, partialOffset, len); + partialOffset += len; + } + else + { + int diff = partialBufferLength - partialOffset; + Array.Copy(buffer, off, partialBuffer, partialOffset, diff); + off += diff; + len -= diff; + PartialFlush(false); + while (len > partialBufferLength) + { + Array.Copy(buffer, off, partialBuffer, 0, partialBufferLength); + off += partialBufferLength; + len -= partialBufferLength; + PartialFlush(false); + } + Array.Copy(buffer, off, partialBuffer, 0, len); + partialOffset += len; + } + } + public override void WriteByte( + byte value) + { + if (partialBuffer != null) + { + WritePartial(value); + } + else + { + outStr.WriteByte(value); + } + } + public override void Write( + byte[] buffer, + int offset, + int count) + { + if (partialBuffer != null) + { + WritePartial(buffer, offset, count); + } + else + { + outStr.Write(buffer, offset, count); + } + } + + // Additional helper methods to write primitive types + internal virtual void WriteShort( + short n) + { + this.Write( + (byte)(n >> 8), + (byte)n); + } + internal virtual void WriteInt( + int n) + { + this.Write( + (byte)(n >> 24), + (byte)(n >> 16), + (byte)(n >> 8), + (byte)n); + } + internal virtual void WriteLong( + long n) + { + this.Write( + (byte)(n >> 56), + (byte)(n >> 48), + (byte)(n >> 40), + (byte)(n >> 32), + (byte)(n >> 24), + (byte)(n >> 16), + (byte)(n >> 8), + (byte)n); + } + + public void WritePacket( + ContainedPacket p) + { + p.Encode(this); + } + + internal void WritePacket( + PacketTag tag, + byte[] body, + bool oldFormat) + { + this.WriteHeader(tag, oldFormat, false, body.Length); + this.Write(body); + } + + public void WriteObject( + BcpgObject bcpgObject) + { + bcpgObject.Encode(this); + } + + public void WriteObjects( + params BcpgObject[] v) + { + foreach (BcpgObject o in v) + { + o.Encode(this); + } + } + + /// Flush the underlying stream. + public override void Flush() + { + outStr.Flush(); + } + + /// Finish writing out the current packet without closing the underlying stream. + public void Finish() + { + if (partialBuffer != null) + { + PartialFlush(true); + Array.Clear(partialBuffer, 0, partialBuffer.Length); + partialBuffer = null; + } + } + +#if PORTABLE + protected override void Dispose(bool disposing) + { + if (disposing) + { + this.Finish(); + outStr.Flush(); + Platform.Dispose(outStr); + } + base.Dispose(disposing); + } +#else + public override void Close() + { + this.Finish(); + outStr.Flush(); + Platform.Dispose(outStr); + base.Close(); + } +#endif + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/BcpgOutputStream.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/BcpgOutputStream.cs.meta new file mode 100644 index 0000000..4d75a10 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/BcpgOutputStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7bdac1fdff596304e9a478ff76eec826 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/CompressedDataPacket.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/CompressedDataPacket.cs new file mode 100644 index 0000000..2432825 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/CompressedDataPacket.cs @@ -0,0 +1,24 @@ +using System.IO; + +namespace Org.BouncyCastle.Bcpg +{ + /// Generic compressed data object. + public class CompressedDataPacket + : InputStreamPacket + { + private readonly CompressionAlgorithmTag algorithm; + + internal CompressedDataPacket( + BcpgInputStream bcpgIn) + : base(bcpgIn) + { + this.algorithm = (CompressionAlgorithmTag) bcpgIn.ReadByte(); + } + + /// The algorithm tag value. + public CompressionAlgorithmTag Algorithm + { + get { return algorithm; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/CompressedDataPacket.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/CompressedDataPacket.cs.meta new file mode 100644 index 0000000..77a2db6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/CompressedDataPacket.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ac72f480015fcd040a27daf528b64b2c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/CompressionAlgorithmTags.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/CompressionAlgorithmTags.cs new file mode 100644 index 0000000..0e45229 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/CompressionAlgorithmTags.cs @@ -0,0 +1,11 @@ +namespace Org.BouncyCastle.Bcpg +{ + /// Basic tags for compression algorithms. + public enum CompressionAlgorithmTag + { + Uncompressed = 0, // Uncompressed + Zip = 1, // ZIP (RFC 1951) + ZLib = 2, // ZLIB (RFC 1950) + BZip2 = 3, // BZ2 + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/CompressionAlgorithmTags.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/CompressionAlgorithmTags.cs.meta new file mode 100644 index 0000000..a1fd5f2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/CompressionAlgorithmTags.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: deca02d48c0fb4e4c83fc6da551ae889 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ContainedPacket.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ContainedPacket.cs new file mode 100644 index 0000000..e8f387c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ContainedPacket.cs @@ -0,0 +1,22 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Bcpg +{ + /// Basic type for a PGP packet. + public abstract class ContainedPacket + : Packet + { + public byte[] GetEncoded() + { + MemoryStream bOut = new MemoryStream(); + BcpgOutputStream pOut = new BcpgOutputStream(bOut); + + pOut.WritePacket(this); + + return bOut.ToArray(); + } + + public abstract void Encode(BcpgOutputStream bcpgOut); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ContainedPacket.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ContainedPacket.cs.meta new file mode 100644 index 0000000..50efae0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ContainedPacket.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 846f2df2566d7d54d9aaea23cf608efd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/Crc24.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/Crc24.cs new file mode 100644 index 0000000..97846f4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/Crc24.cs @@ -0,0 +1,46 @@ +using System; + +namespace Org.BouncyCastle.Bcpg +{ + public class Crc24 + { + private const int Crc24Init = 0x0b704ce; + private const int Crc24Poly = 0x1864cfb; + + private int crc = Crc24Init; + + public Crc24() + { + } + + public void Update( + int b) + { + crc ^= b << 16; + for (int i = 0; i < 8; i++) + { + crc <<= 1; + if ((crc & 0x1000000) != 0) + { + crc ^= Crc24Poly; + } + } + } + + [Obsolete("Use 'Value' property instead")] + public int GetValue() + { + return crc; + } + + public int Value + { + get { return crc; } + } + + public void Reset() + { + crc = Crc24Init; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/Crc24.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/Crc24.cs.meta new file mode 100644 index 0000000..f09ff92 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/Crc24.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c6f2c41a0704f314aa1230567b3e5092 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/DsaPublicBcpgKey.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/DsaPublicBcpgKey.cs new file mode 100644 index 0000000..11294cc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/DsaPublicBcpgKey.cs @@ -0,0 +1,80 @@ +using System; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Bcpg +{ + /// Base class for a DSA public key. + public class DsaPublicBcpgKey + : BcpgObject, IBcpgKey + { + private readonly MPInteger p, q, g, y; + + /// The stream to read the packet from. + public DsaPublicBcpgKey( + BcpgInputStream bcpgIn) + { + this.p = new MPInteger(bcpgIn); + this.q = new MPInteger(bcpgIn); + this.g = new MPInteger(bcpgIn); + this.y = new MPInteger(bcpgIn); + } + + public DsaPublicBcpgKey( + BigInteger p, + BigInteger q, + BigInteger g, + BigInteger y) + { + this.p = new MPInteger(p); + this.q = new MPInteger(q); + this.g = new MPInteger(g); + this.y = new MPInteger(y); + } + + /// The format, as a string, always "PGP". + public string Format + { + get { return "PGP"; } + } + + /// Return the standard PGP encoding of the key. + public override byte[] GetEncoded() + { + try + { + return base.GetEncoded(); + } + catch (Exception) + { + return null; + } + } + + public override void Encode( + BcpgOutputStream bcpgOut) + { + bcpgOut.WriteObjects(p, q, g, y); + } + + public BigInteger G + { + get { return g.Value; } + } + + public BigInteger P + { + get { return p.Value; } + } + + public BigInteger Q + { + get { return q.Value; } + } + + public BigInteger Y + { + get { return y.Value; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/DsaPublicBcpgKey.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/DsaPublicBcpgKey.cs.meta new file mode 100644 index 0000000..a656357 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/DsaPublicBcpgKey.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9ba6946abe4625245954860c783a41fe +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/DsaSecretBcpgKey.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/DsaSecretBcpgKey.cs new file mode 100644 index 0000000..41835d4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/DsaSecretBcpgKey.cs @@ -0,0 +1,61 @@ +using System; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Bcpg +{ + /// Base class for a DSA secret key. + public class DsaSecretBcpgKey + : BcpgObject, IBcpgKey + { + internal MPInteger x; + + /** + * @param in + */ + public DsaSecretBcpgKey( + BcpgInputStream bcpgIn) + { + this.x = new MPInteger(bcpgIn); + } + + public DsaSecretBcpgKey( + BigInteger x) + { + this.x = new MPInteger(x); + } + + /// The format, as a string, always "PGP". + public string Format + { + get { return "PGP"; } + } + + /// Return the standard PGP encoding of the key. + public override byte[] GetEncoded() + { + try + { + return base.GetEncoded(); + } + catch (Exception) + { + return null; + } + } + + public override void Encode( + BcpgOutputStream bcpgOut) + { + bcpgOut.WriteObject(x); + } + + /** + * @return x + */ + public BigInteger X + { + get { return x.Value; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/DsaSecretBcpgKey.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/DsaSecretBcpgKey.cs.meta new file mode 100644 index 0000000..d4b7884 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/DsaSecretBcpgKey.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6d012a45e36148841a4d1fe57a7dd8c0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ECDHPublicBCPGKey.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ECDHPublicBCPGKey.cs new file mode 100644 index 0000000..dc225e3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ECDHPublicBCPGKey.cs @@ -0,0 +1,102 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Math.EC; + +namespace Org.BouncyCastle.Bcpg +{ + /// Base class for an ECDH Public Key. + public class ECDHPublicBcpgKey + : ECPublicBcpgKey + { + private byte reserved; + private HashAlgorithmTag hashFunctionId; + private SymmetricKeyAlgorithmTag symAlgorithmId; + + /// The stream to read the packet from. + public ECDHPublicBcpgKey( + BcpgInputStream bcpgIn) + : base(bcpgIn) + { + int length = bcpgIn.ReadByte(); + byte[] kdfParameters = new byte[length]; + if (kdfParameters.Length != 3) + throw new InvalidOperationException("kdf parameters size of 3 expected."); + + bcpgIn.ReadFully(kdfParameters); + + reserved = kdfParameters[0]; + hashFunctionId = (HashAlgorithmTag)kdfParameters[1]; + symAlgorithmId = (SymmetricKeyAlgorithmTag)kdfParameters[2]; + + VerifyHashAlgorithm(); + VerifySymmetricKeyAlgorithm(); + } + + public ECDHPublicBcpgKey( + DerObjectIdentifier oid, + ECPoint point, + HashAlgorithmTag hashAlgorithm, + SymmetricKeyAlgorithmTag symmetricKeyAlgorithm) + : base(oid, point) + { + reserved = 1; + hashFunctionId = hashAlgorithm; + symAlgorithmId = symmetricKeyAlgorithm; + + VerifyHashAlgorithm(); + VerifySymmetricKeyAlgorithm(); + } + + public virtual byte Reserved + { + get { return reserved; } + } + + public virtual HashAlgorithmTag HashAlgorithm + { + get { return hashFunctionId; } + } + + public virtual SymmetricKeyAlgorithmTag SymmetricKeyAlgorithm + { + get { return symAlgorithmId; } + } + + public override void Encode( + BcpgOutputStream bcpgOut) + { + base.Encode(bcpgOut); + bcpgOut.WriteByte(0x3); + bcpgOut.WriteByte(reserved); + bcpgOut.WriteByte((byte)hashFunctionId); + bcpgOut.WriteByte((byte)symAlgorithmId); + } + + private void VerifyHashAlgorithm() + { + switch ((HashAlgorithmTag)hashFunctionId) + { + case HashAlgorithmTag.Sha256: + case HashAlgorithmTag.Sha384: + case HashAlgorithmTag.Sha512: + break; + default: + throw new InvalidOperationException("Hash algorithm must be SHA-256 or stronger."); + } + } + + private void VerifySymmetricKeyAlgorithm() + { + switch ((SymmetricKeyAlgorithmTag)symAlgorithmId) + { + case SymmetricKeyAlgorithmTag.Aes128: + case SymmetricKeyAlgorithmTag.Aes192: + case SymmetricKeyAlgorithmTag.Aes256: + break; + default: + throw new InvalidOperationException("Symmetric key algorithm must be AES-128 or stronger."); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ECDHPublicBCPGKey.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ECDHPublicBCPGKey.cs.meta new file mode 100644 index 0000000..236be28 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ECDHPublicBCPGKey.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 02705f5bff713924a98fc35e713bc8d3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ECDsaPublicBCPGKey.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ECDsaPublicBCPGKey.cs new file mode 100644 index 0000000..5f0c8ac --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ECDsaPublicBCPGKey.cs @@ -0,0 +1,34 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; + +namespace Org.BouncyCastle.Bcpg +{ + /// Base class for an ECDSA Public Key. + public class ECDsaPublicBcpgKey + : ECPublicBcpgKey + { + /// The stream to read the packet from. + protected internal ECDsaPublicBcpgKey( + BcpgInputStream bcpgIn) + : base(bcpgIn) + { + } + + public ECDsaPublicBcpgKey( + DerObjectIdentifier oid, + ECPoint point) + : base(oid, point) + { + } + + public ECDsaPublicBcpgKey( + DerObjectIdentifier oid, + BigInteger encodedPoint) + : base(oid, encodedPoint) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ECDsaPublicBCPGKey.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ECDsaPublicBCPGKey.cs.meta new file mode 100644 index 0000000..9d102f9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ECDsaPublicBCPGKey.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 161114cb70273754891fd51df203d8e1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ECPublicBCPGKey.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ECPublicBCPGKey.cs new file mode 100644 index 0000000..4733ee6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ECPublicBCPGKey.cs @@ -0,0 +1,99 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; + +namespace Org.BouncyCastle.Bcpg +{ + /// Base class for an EC Public Key. + public abstract class ECPublicBcpgKey + : BcpgObject, IBcpgKey + { + internal DerObjectIdentifier oid; + internal BigInteger point; + + /// The stream to read the packet from. + protected ECPublicBcpgKey( + BcpgInputStream bcpgIn) + { + this.oid = DerObjectIdentifier.GetInstance(Asn1Object.FromByteArray(ReadBytesOfEncodedLength(bcpgIn))); + this.point = new MPInteger(bcpgIn).Value; + } + + protected ECPublicBcpgKey( + DerObjectIdentifier oid, + ECPoint point) + { + this.point = new BigInteger(1, point.GetEncoded(false)); + this.oid = oid; + } + + protected ECPublicBcpgKey( + DerObjectIdentifier oid, + BigInteger encodedPoint) + { + this.point = encodedPoint; + this.oid = oid; + } + + /// The format, as a string, always "PGP". + public string Format + { + get { return "PGP"; } + } + + /// Return the standard PGP encoding of the key. + public override byte[] GetEncoded() + { + try + { + return base.GetEncoded(); + } + catch (IOException) + { + return null; + } + } + + public override void Encode( + BcpgOutputStream bcpgOut) + { + byte[] oid = this.oid.GetEncoded(); + bcpgOut.Write(oid, 1, oid.Length - 1); + + MPInteger point = new MPInteger(this.point); + bcpgOut.WriteObject(point); + } + + public virtual BigInteger EncodedPoint + { + get { return point; } + } + + public virtual DerObjectIdentifier CurveOid + { + get { return oid; } + } + + protected static byte[] ReadBytesOfEncodedLength( + BcpgInputStream bcpgIn) + { + int length = bcpgIn.ReadByte(); + if (length < 0) + throw new EndOfStreamException(); + if (length == 0 || length == 0xFF) + throw new IOException("future extensions not yet implemented"); + if (length > 127) + throw new IOException("unsupported OID"); + + byte[] buffer = new byte[length + 2]; + bcpgIn.ReadFully(buffer, 2, buffer.Length - 2); + buffer[0] = (byte)0x06; + buffer[1] = (byte)length; + + return buffer; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ECPublicBCPGKey.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ECPublicBCPGKey.cs.meta new file mode 100644 index 0000000..a84c6a8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ECPublicBCPGKey.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d07d15d1482dce84b97e6b50406f4116 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ECSecretBCPGKey.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ECSecretBCPGKey.cs new file mode 100644 index 0000000..22e0a34 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ECSecretBCPGKey.cs @@ -0,0 +1,56 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Bcpg +{ + /// Base class for an EC Secret Key. + public class ECSecretBcpgKey + : BcpgObject, IBcpgKey + { + internal MPInteger x; + + public ECSecretBcpgKey( + BcpgInputStream bcpgIn) + { + this.x = new MPInteger(bcpgIn); + } + + public ECSecretBcpgKey( + BigInteger x) + { + this.x = new MPInteger(x); + } + + /// The format, as a string, always "PGP". + public string Format + { + get { return "PGP"; } + } + + /// Return the standard PGP encoding of the key. + public override byte[] GetEncoded() + { + try + { + return base.GetEncoded(); + } + catch (Exception) + { + return null; + } + } + + public override void Encode( + BcpgOutputStream bcpgOut) + { + bcpgOut.WriteObject(x); + } + + public virtual BigInteger X + { + get { return x.Value; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ECSecretBCPGKey.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ECSecretBCPGKey.cs.meta new file mode 100644 index 0000000..fa071b5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ECSecretBCPGKey.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2190c506a5a620f4785b59eef4fa4b10 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ElGamalPublicBcpgKey.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ElGamalPublicBcpgKey.cs new file mode 100644 index 0000000..808e427 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ElGamalPublicBcpgKey.cs @@ -0,0 +1,71 @@ +using System; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Bcpg +{ + /// Base class for an ElGamal public key. + public class ElGamalPublicBcpgKey + : BcpgObject, IBcpgKey + { + internal MPInteger p, g, y; + + public ElGamalPublicBcpgKey( + BcpgInputStream bcpgIn) + { + this.p = new MPInteger(bcpgIn); + this.g = new MPInteger(bcpgIn); + this.y = new MPInteger(bcpgIn); + } + + public ElGamalPublicBcpgKey( + BigInteger p, + BigInteger g, + BigInteger y) + { + this.p = new MPInteger(p); + this.g = new MPInteger(g); + this.y = new MPInteger(y); + } + + /// The format, as a string, always "PGP". + public string Format + { + get { return "PGP"; } + } + + /// Return the standard PGP encoding of the key. + public override byte[] GetEncoded() + { + try + { + return base.GetEncoded(); + } + catch (Exception) + { + return null; + } + } + + public BigInteger P + { + get { return p.Value; } + } + + public BigInteger G + { + get { return g.Value; } + } + + public BigInteger Y + { + get { return y.Value; } + } + + public override void Encode( + BcpgOutputStream bcpgOut) + { + bcpgOut.WriteObjects(p, g, y); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ElGamalPublicBcpgKey.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ElGamalPublicBcpgKey.cs.meta new file mode 100644 index 0000000..bf60de0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ElGamalPublicBcpgKey.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6f7541f593c8f424e88dec9a0dd88e8a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ElGamalSecretBcpgKey.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ElGamalSecretBcpgKey.cs new file mode 100644 index 0000000..2d95b29 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ElGamalSecretBcpgKey.cs @@ -0,0 +1,61 @@ +using System; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Bcpg +{ + /// Base class for an ElGamal secret key. + public class ElGamalSecretBcpgKey + : BcpgObject, IBcpgKey + { + internal MPInteger x; + + /** + * @param in + */ + public ElGamalSecretBcpgKey( + BcpgInputStream bcpgIn) + { + this.x = new MPInteger(bcpgIn); + } + + /** + * @param x + */ + public ElGamalSecretBcpgKey( + BigInteger x) + { + this.x = new MPInteger(x); + } + + /// The format, as a string, always "PGP". + public string Format + { + get { return "PGP"; } + } + + public BigInteger X + { + get { return x.Value; } + } + + /// Return the standard PGP encoding of the key. + public override byte[] GetEncoded() + { + try + { + return base.GetEncoded(); + } + catch (Exception) + { + return null; + } + } + + public override void Encode( + BcpgOutputStream bcpgOut) + { + bcpgOut.WriteObject(x); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ElGamalSecretBcpgKey.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ElGamalSecretBcpgKey.cs.meta new file mode 100644 index 0000000..f447186 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ElGamalSecretBcpgKey.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a16bf19b9db6a9b4bae12824878758c7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ExperimentalPacket.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ExperimentalPacket.cs new file mode 100644 index 0000000..36a254b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ExperimentalPacket.cs @@ -0,0 +1,38 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Bcpg +{ + /// Basic packet for an experimental packet. + public class ExperimentalPacket + : ContainedPacket //, PublicKeyAlgorithmTag + { + private readonly PacketTag tag; + private readonly byte[] contents; + + internal ExperimentalPacket( + PacketTag tag, + BcpgInputStream bcpgIn) + { + this.tag = tag; + + this.contents = bcpgIn.ReadAll(); + } + + public PacketTag Tag + { + get { return tag; } + } + + public byte[] GetContents() + { + return (byte[]) contents.Clone(); + } + + public override void Encode( + BcpgOutputStream bcpgOut) + { + bcpgOut.WritePacket(tag, contents, true); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ExperimentalPacket.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ExperimentalPacket.cs.meta new file mode 100644 index 0000000..153c4c2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ExperimentalPacket.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 69275d6d804838941af20559e6f1e6d6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/HashAlgorithmTags.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/HashAlgorithmTags.cs new file mode 100644 index 0000000..96c0091 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/HashAlgorithmTags.cs @@ -0,0 +1,19 @@ +namespace Org.BouncyCastle.Bcpg +{ + /// Basic tags for hash algorithms. + public enum HashAlgorithmTag + { + MD5 = 1, // MD5 + Sha1 = 2, // SHA-1 + RipeMD160 = 3, // RIPE-MD/160 + DoubleSha = 4, // Reserved for double-width SHA (experimental) + MD2 = 5, // MD2 + Tiger192 = 6, // Reserved for TIGER/192 + Haval5pass160 = 7, // Reserved for HAVAL (5 pass, 160-bit) + + Sha256 = 8, // SHA-256 + Sha384 = 9, // SHA-384 + Sha512 = 10, // SHA-512 + Sha224 = 11, // SHA-224 + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/HashAlgorithmTags.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/HashAlgorithmTags.cs.meta new file mode 100644 index 0000000..39ee0f4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/HashAlgorithmTags.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 90d127d2cd3cfd24cb27e0565c0f6206 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/IBcpgKey.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/IBcpgKey.cs new file mode 100644 index 0000000..2754617 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/IBcpgKey.cs @@ -0,0 +1,16 @@ +using System; + +namespace Org.BouncyCastle.Bcpg +{ + /// Base interface for a PGP key. + public interface IBcpgKey + { + /// + /// The base format for this key - in the case of the symmetric keys it will generally + /// be raw indicating that the key is just a straight byte representation, for an asymmetric + /// key the format will be PGP, indicating the key is a string of MPIs encoded in PGP format. + /// + /// "RAW" or "PGP". + string Format { get; } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/IBcpgKey.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/IBcpgKey.cs.meta new file mode 100644 index 0000000..6c4728b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/IBcpgKey.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5376bdf69c340bd429e783f5f9f88d9d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/InputStreamPacket.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/InputStreamPacket.cs new file mode 100644 index 0000000..c45efab --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/InputStreamPacket.cs @@ -0,0 +1,20 @@ +namespace Org.BouncyCastle.Bcpg +{ + public class InputStreamPacket + : Packet + { + private readonly BcpgInputStream bcpgIn; + + public InputStreamPacket( + BcpgInputStream bcpgIn) + { + this.bcpgIn = bcpgIn; + } + + /// Note: you can only read from this once... + public BcpgInputStream GetInputStream() + { + return bcpgIn; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/InputStreamPacket.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/InputStreamPacket.cs.meta new file mode 100644 index 0000000..9c62c76 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/InputStreamPacket.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 36dc18bb554b3fe40ac794cb382df127 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/LiteralDataPacket.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/LiteralDataPacket.cs new file mode 100644 index 0000000..b4d28a2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/LiteralDataPacket.cs @@ -0,0 +1,61 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Bcpg +{ + /// Generic literal data packet. + public class LiteralDataPacket + : InputStreamPacket + { + private int format; + private byte[] fileName; + private long modDate; + + internal LiteralDataPacket( + BcpgInputStream bcpgIn) + : base(bcpgIn) + { + format = bcpgIn.ReadByte(); + int len = bcpgIn.ReadByte(); + + fileName = new byte[len]; + for (int i = 0; i != len; ++i) + { + int ch = bcpgIn.ReadByte(); + if (ch < 0) + throw new IOException("literal data truncated in header"); + + fileName[i] = (byte)ch; + } + + modDate = (((uint)bcpgIn.ReadByte() << 24) + | ((uint)bcpgIn.ReadByte() << 16) + | ((uint)bcpgIn.ReadByte() << 8) + | (uint)bcpgIn.ReadByte()) * 1000L; + } + + /// The format tag value. + public int Format + { + get { return format; } + } + + /// The modification time of the file in milli-seconds (since Jan 1, 1970 UTC) + public long ModificationTime + { + get { return modDate; } + } + + public string FileName + { + get { return Strings.FromUtf8ByteArray(fileName); } + } + + public byte[] GetRawFileName() + { + return Arrays.Clone(fileName); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/LiteralDataPacket.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/LiteralDataPacket.cs.meta new file mode 100644 index 0000000..fdfb16e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/LiteralDataPacket.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 911db6abc7f258d458e8c4f71046025d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/MPInteger.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/MPInteger.cs new file mode 100644 index 0000000..4414072 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/MPInteger.cs @@ -0,0 +1,59 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Bcpg +{ + /// A multiple precision integer + public class MPInteger + : BcpgObject + { + private readonly BigInteger val; + + public MPInteger( + BcpgInputStream bcpgIn) + { + if (bcpgIn == null) + throw new ArgumentNullException("bcpgIn"); + + int length = (bcpgIn.ReadByte() << 8) | bcpgIn.ReadByte(); + byte[] bytes = new byte[(length + 7) / 8]; + + bcpgIn.ReadFully(bytes); + + this.val = new BigInteger(1, bytes); + } + + public MPInteger( + BigInteger val) + { + if (val == null) + throw new ArgumentNullException("val"); + if (val.SignValue < 0) + throw new ArgumentException("Values must be positive", "val"); + + this.val = val; + } + + public BigInteger Value + { + get { return val; } + } + + public override void Encode( + BcpgOutputStream bcpgOut) + { + bcpgOut.WriteShort((short) val.BitLength); + bcpgOut.Write(val.ToByteArrayUnsigned()); + } + + internal static void Encode( + BcpgOutputStream bcpgOut, + BigInteger val) + { + bcpgOut.WriteShort((short) val.BitLength); + bcpgOut.Write(val.ToByteArrayUnsigned()); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/MPInteger.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/MPInteger.cs.meta new file mode 100644 index 0000000..9a4fb38 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/MPInteger.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 19e60d36e93fe7c4ca1f6897ec39037f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/MarkerPacket.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/MarkerPacket.cs new file mode 100644 index 0000000..4dc4b5a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/MarkerPacket.cs @@ -0,0 +1,24 @@ +using System.IO; + +namespace Org.BouncyCastle.Bcpg +{ + /// Basic type for a marker packet. + public class MarkerPacket + : ContainedPacket + { + // "PGP" + byte[] marker = { (byte)0x50, (byte)0x47, (byte)0x50 }; + + public MarkerPacket( + BcpgInputStream bcpgIn) + { + bcpgIn.ReadFully(marker); + } + + public override void Encode( + BcpgOutputStream bcpgOut) + { + bcpgOut.WritePacket(PacketTag.Marker, marker, true); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/MarkerPacket.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/MarkerPacket.cs.meta new file mode 100644 index 0000000..7c40209 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/MarkerPacket.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 87f57d3a536b1d94c803ac37a34c50e0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ModDetectionCodePacket.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ModDetectionCodePacket.cs new file mode 100644 index 0000000..6bb2364 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ModDetectionCodePacket.cs @@ -0,0 +1,42 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Bcpg +{ + /// Basic packet for a modification detection code packet. + public class ModDetectionCodePacket + : ContainedPacket + { + private readonly byte[] digest; + + internal ModDetectionCodePacket( + BcpgInputStream bcpgIn) + { + if (bcpgIn == null) + throw new ArgumentNullException("bcpgIn"); + + this.digest = new byte[20]; + bcpgIn.ReadFully(this.digest); + } + + public ModDetectionCodePacket( + byte[] digest) + { + if (digest == null) + throw new ArgumentNullException("digest"); + + this.digest = (byte[]) digest.Clone(); + } + + public byte[] GetDigest() + { + return (byte[]) digest.Clone(); + } + + public override void Encode( + BcpgOutputStream bcpgOut) + { + bcpgOut.WritePacket(PacketTag.ModificationDetectionCode, digest, false); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ModDetectionCodePacket.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ModDetectionCodePacket.cs.meta new file mode 100644 index 0000000..9b2d057 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/ModDetectionCodePacket.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2c0be2dd946262646abd49ec5719bf30 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/OnePassSignaturePacket.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/OnePassSignaturePacket.cs new file mode 100644 index 0000000..b67df0a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/OnePassSignaturePacket.cs @@ -0,0 +1,93 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Bcpg +{ + /// Generic signature object + public class OnePassSignaturePacket + : ContainedPacket + { + private int version; + private int sigType; + private HashAlgorithmTag hashAlgorithm; + private PublicKeyAlgorithmTag keyAlgorithm; + private long keyId; + private int nested; + + internal OnePassSignaturePacket( + BcpgInputStream bcpgIn) + { + version = bcpgIn.ReadByte(); + sigType = bcpgIn.ReadByte(); + hashAlgorithm = (HashAlgorithmTag) bcpgIn.ReadByte(); + keyAlgorithm = (PublicKeyAlgorithmTag) bcpgIn.ReadByte(); + + keyId |= (long)bcpgIn.ReadByte() << 56; + keyId |= (long)bcpgIn.ReadByte() << 48; + keyId |= (long)bcpgIn.ReadByte() << 40; + keyId |= (long)bcpgIn.ReadByte() << 32; + keyId |= (long)bcpgIn.ReadByte() << 24; + keyId |= (long)bcpgIn.ReadByte() << 16; + keyId |= (long)bcpgIn.ReadByte() << 8; + keyId |= (uint)bcpgIn.ReadByte(); + + nested = bcpgIn.ReadByte(); + } + + public OnePassSignaturePacket( + int sigType, + HashAlgorithmTag hashAlgorithm, + PublicKeyAlgorithmTag keyAlgorithm, + long keyId, + bool isNested) + { + this.version = 3; + this.sigType = sigType; + this.hashAlgorithm = hashAlgorithm; + this.keyAlgorithm = keyAlgorithm; + this.keyId = keyId; + this.nested = (isNested) ? 0 : 1; + } + + public int SignatureType + { + get { return sigType; } + } + + /// The encryption algorithm tag. + public PublicKeyAlgorithmTag KeyAlgorithm + { + get { return keyAlgorithm; } + } + + /// The hash algorithm tag. + public HashAlgorithmTag HashAlgorithm + { + get { return hashAlgorithm; } + } + + public long KeyId + { + get { return keyId; } + } + + public override void Encode( + BcpgOutputStream bcpgOut) + { + MemoryStream bOut = new MemoryStream(); + BcpgOutputStream pOut = new BcpgOutputStream(bOut); + + pOut.Write( + (byte) version, + (byte) sigType, + (byte) hashAlgorithm, + (byte) keyAlgorithm); + + pOut.WriteLong(keyId); + + pOut.WriteByte((byte) nested); + + bcpgOut.WritePacket(PacketTag.OnePassSignature, bOut.ToArray(), true); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/OnePassSignaturePacket.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/OnePassSignaturePacket.cs.meta new file mode 100644 index 0000000..59db35f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/OnePassSignaturePacket.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e9b5bbe30b8f5794f9d3fbd7d15c3045 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/OutputStreamPacket.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/OutputStreamPacket.cs new file mode 100644 index 0000000..aa8316d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/OutputStreamPacket.cs @@ -0,0 +1,24 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Bcpg +{ + public abstract class OutputStreamPacket + { + private readonly BcpgOutputStream bcpgOut; + + internal OutputStreamPacket( + BcpgOutputStream bcpgOut) + { + if (bcpgOut == null) + throw new ArgumentNullException("bcpgOut"); + + this.bcpgOut = bcpgOut; + } + + public abstract BcpgOutputStream Open(); + + public abstract void Close(); + } +} + diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/OutputStreamPacket.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/OutputStreamPacket.cs.meta new file mode 100644 index 0000000..701cf61 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/OutputStreamPacket.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0c288c9ed2d6815429ff66debf704ded +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/Packet.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/Packet.cs new file mode 100644 index 0000000..83f6d1f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/Packet.cs @@ -0,0 +1,7 @@ +namespace Org.BouncyCastle.Bcpg +{ + public class Packet + //: PacketTag + { + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/Packet.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/Packet.cs.meta new file mode 100644 index 0000000..5b68306 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/Packet.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 75f2d921b082bfd49b3bff3ee2dd30e8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/PacketTags.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/PacketTags.cs new file mode 100644 index 0000000..5a53d4e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/PacketTags.cs @@ -0,0 +1,30 @@ +namespace Org.BouncyCastle.Bcpg +{ + /// Basic PGP packet tag types. + public enum PacketTag + { + Reserved = 0, // Reserved - a packet tag must not have this value + PublicKeyEncryptedSession = 1, // Public-Key Encrypted Session Key Packet + Signature = 2, // Signature Packet + SymmetricKeyEncryptedSessionKey = 3, // Symmetric-Key Encrypted Session Key Packet + OnePassSignature = 4, // One-Pass Signature Packet + SecretKey = 5, // Secret Key Packet + PublicKey = 6, // Public Key Packet + SecretSubkey = 7, // Secret Subkey Packet + CompressedData = 8, // Compressed Data Packet + SymmetricKeyEncrypted = 9, // Symmetrically Encrypted Data Packet + Marker = 10, // Marker Packet + LiteralData = 11, // Literal Data Packet + Trust = 12, // Trust Packet + UserId = 13, // User ID Packet + PublicSubkey = 14, // Public Subkey Packet + UserAttribute = 17, // User attribute + SymmetricEncryptedIntegrityProtected = 18, // Symmetric encrypted, integrity protected + ModificationDetectionCode = 19, // Modification detection code + + Experimental1 = 60, // Private or Experimental Values + Experimental2 = 61, + Experimental3 = 62, + Experimental4 = 63 + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/PacketTags.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/PacketTags.cs.meta new file mode 100644 index 0000000..eaa1a58 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/PacketTags.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 139b3dd598ed9e14aa0de09d021ca18d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/PublicKeyAlgorithmTags.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/PublicKeyAlgorithmTags.cs new file mode 100644 index 0000000..7c93964 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/PublicKeyAlgorithmTags.cs @@ -0,0 +1,33 @@ +using System; + +namespace Org.BouncyCastle.Bcpg +{ + /// Public Key Algorithm tag numbers. + public enum PublicKeyAlgorithmTag + { + RsaGeneral = 1, // RSA (Encrypt or Sign) + RsaEncrypt = 2, // RSA Encrypt-Only + RsaSign = 3, // RSA Sign-Only + ElGamalEncrypt = 16, // Elgamal (Encrypt-Only), see [ELGAMAL] + Dsa = 17, // DSA (Digital Signature Standard) + [Obsolete("Use 'ECDH' instead")] + EC = 18, // Reserved for Elliptic Curve + ECDH = 18, // Reserved for Elliptic Curve (actual algorithm name) + ECDsa = 19, // Reserved for ECDSA + ElGamalGeneral = 20, // Elgamal (Encrypt or Sign) + DiffieHellman = 21, // Reserved for Diffie-Hellman (X9.42, as defined for IETF-S/MIME) + EdDsa = 22, // EdDSA - (internet draft, but appearing in use) + + Experimental_1 = 100, + Experimental_2 = 101, + Experimental_3 = 102, + Experimental_4 = 103, + Experimental_5 = 104, + Experimental_6 = 105, + Experimental_7 = 106, + Experimental_8 = 107, + Experimental_9 = 108, + Experimental_10 = 109, + Experimental_11 = 110, + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/PublicKeyAlgorithmTags.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/PublicKeyAlgorithmTags.cs.meta new file mode 100644 index 0000000..8936369 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/PublicKeyAlgorithmTags.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fbec7c30eb81a3043b68aa91975d9ded +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/PublicKeyEncSessionPacket.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/PublicKeyEncSessionPacket.cs new file mode 100644 index 0000000..831b5a1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/PublicKeyEncSessionPacket.cs @@ -0,0 +1,115 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Bcpg +{ + /// Basic packet for a PGP public key. + public class PublicKeyEncSessionPacket + : ContainedPacket //, PublicKeyAlgorithmTag + { + private int version; + private long keyId; + private PublicKeyAlgorithmTag algorithm; + private byte[][] data; + + internal PublicKeyEncSessionPacket( + BcpgInputStream bcpgIn) + { + version = bcpgIn.ReadByte(); + + keyId |= (long)bcpgIn.ReadByte() << 56; + keyId |= (long)bcpgIn.ReadByte() << 48; + keyId |= (long)bcpgIn.ReadByte() << 40; + keyId |= (long)bcpgIn.ReadByte() << 32; + keyId |= (long)bcpgIn.ReadByte() << 24; + keyId |= (long)bcpgIn.ReadByte() << 16; + keyId |= (long)bcpgIn.ReadByte() << 8; + keyId |= (uint)bcpgIn.ReadByte(); + + algorithm = (PublicKeyAlgorithmTag) bcpgIn.ReadByte(); + + switch ((PublicKeyAlgorithmTag) algorithm) + { + case PublicKeyAlgorithmTag.RsaEncrypt: + case PublicKeyAlgorithmTag.RsaGeneral: + data = new byte[][]{ new MPInteger(bcpgIn).GetEncoded() }; + break; + case PublicKeyAlgorithmTag.ElGamalEncrypt: + case PublicKeyAlgorithmTag.ElGamalGeneral: + MPInteger p = new MPInteger(bcpgIn); + MPInteger g = new MPInteger(bcpgIn); + data = new byte[][]{ + p.GetEncoded(), + g.GetEncoded(), + }; + break; + case PublicKeyAlgorithmTag.ECDH: + data = new byte[][]{ Streams.ReadAll(bcpgIn) }; + break; + default: + throw new IOException("unknown PGP public key algorithm encountered"); + } + } + + public PublicKeyEncSessionPacket( + long keyId, + PublicKeyAlgorithmTag algorithm, + byte[][] data) + { + this.version = 3; + this.keyId = keyId; + this.algorithm = algorithm; + this.data = new byte[data.Length][]; + for (int i = 0; i < data.Length; ++i) + { + this.data[i] = Arrays.Clone(data[i]); + } + } + + public int Version + { + get { return version; } + } + + public long KeyId + { + get { return keyId; } + } + + public PublicKeyAlgorithmTag Algorithm + { + get { return algorithm; } + } + + public byte[][] GetEncSessionKey() + { + return data; + } + + public override void Encode( + BcpgOutputStream bcpgOut) + { + MemoryStream bOut = new MemoryStream(); + BcpgOutputStream pOut = new BcpgOutputStream(bOut); + + pOut.WriteByte((byte) version); + + pOut.WriteLong(keyId); + + pOut.WriteByte((byte)algorithm); + + for (int i = 0; i < data.Length; ++i) + { + pOut.Write(data[i]); + } + + Platform.Dispose(pOut); + + bcpgOut.WritePacket(PacketTag.PublicKeyEncryptedSession , bOut.ToArray(), true); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/PublicKeyEncSessionPacket.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/PublicKeyEncSessionPacket.cs.meta new file mode 100644 index 0000000..1a5f9d8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/PublicKeyEncSessionPacket.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8f09e510bef8e574e803178aeae07556 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/PublicKeyPacket.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/PublicKeyPacket.cs new file mode 100644 index 0000000..bbed941 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/PublicKeyPacket.cs @@ -0,0 +1,121 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Utilities.Date; + +namespace Org.BouncyCastle.Bcpg +{ + /// Basic packet for a PGP public key. + public class PublicKeyPacket + : ContainedPacket //, PublicKeyAlgorithmTag + { + private int version; + private long time; + private int validDays; + private PublicKeyAlgorithmTag algorithm; + private IBcpgKey key; + + internal PublicKeyPacket( + BcpgInputStream bcpgIn) + { + version = bcpgIn.ReadByte(); + + time = ((uint)bcpgIn.ReadByte() << 24) | ((uint)bcpgIn.ReadByte() << 16) + | ((uint)bcpgIn.ReadByte() << 8) | (uint)bcpgIn.ReadByte(); + + if (version <= 3) + { + validDays = (bcpgIn.ReadByte() << 8) | bcpgIn.ReadByte(); + } + + algorithm = (PublicKeyAlgorithmTag) bcpgIn.ReadByte(); + + switch ((PublicKeyAlgorithmTag) algorithm) + { + case PublicKeyAlgorithmTag.RsaEncrypt: + case PublicKeyAlgorithmTag.RsaGeneral: + case PublicKeyAlgorithmTag.RsaSign: + key = new RsaPublicBcpgKey(bcpgIn); + break; + case PublicKeyAlgorithmTag.Dsa: + key = new DsaPublicBcpgKey(bcpgIn); + break; + case PublicKeyAlgorithmTag.ElGamalEncrypt: + case PublicKeyAlgorithmTag.ElGamalGeneral: + key = new ElGamalPublicBcpgKey(bcpgIn); + break; + case PublicKeyAlgorithmTag.ECDH: + key = new ECDHPublicBcpgKey(bcpgIn); + break; + case PublicKeyAlgorithmTag.ECDsa: + key = new ECDsaPublicBcpgKey(bcpgIn); + break; + default: + throw new IOException("unknown PGP public key algorithm encountered"); + } + } + + /// Construct a version 4 public key packet. + public PublicKeyPacket( + PublicKeyAlgorithmTag algorithm, + DateTime time, + IBcpgKey key) + { + this.version = 4; + this.time = DateTimeUtilities.DateTimeToUnixMs(time) / 1000L; + this.algorithm = algorithm; + this.key = key; + } + + public virtual int Version + { + get { return version; } + } + + public virtual PublicKeyAlgorithmTag Algorithm + { + get { return algorithm; } + } + + public virtual int ValidDays + { + get { return validDays; } + } + + public virtual DateTime GetTime() + { + return DateTimeUtilities.UnixMsToDateTime(time * 1000L); + } + + public virtual IBcpgKey Key + { + get { return key; } + } + + public virtual byte[] GetEncodedContents() + { + MemoryStream bOut = new MemoryStream(); + BcpgOutputStream pOut = new BcpgOutputStream(bOut); + + pOut.WriteByte((byte) version); + pOut.WriteInt((int) time); + + if (version <= 3) + { + pOut.WriteShort((short) validDays); + } + + pOut.WriteByte((byte) algorithm); + + pOut.WriteObject((BcpgObject)key); + + return bOut.ToArray(); + } + + public override void Encode( + BcpgOutputStream bcpgOut) + { + bcpgOut.WritePacket(PacketTag.PublicKey, GetEncodedContents(), true); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/PublicKeyPacket.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/PublicKeyPacket.cs.meta new file mode 100644 index 0000000..5102692 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/PublicKeyPacket.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1eaf566146fe5874aa29526100284c04 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/PublicSubkeyPacket.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/PublicSubkeyPacket.cs new file mode 100644 index 0000000..6e1aeda --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/PublicSubkeyPacket.cs @@ -0,0 +1,30 @@ +using System; +using System.IO; +namespace Org.BouncyCastle.Bcpg +{ + /// Basic packet for a PGP public subkey + public class PublicSubkeyPacket + : PublicKeyPacket + { + internal PublicSubkeyPacket( + BcpgInputStream bcpgIn) + : base(bcpgIn) + { + } + + /// Construct a version 4 public subkey packet. + public PublicSubkeyPacket( + PublicKeyAlgorithmTag algorithm, + DateTime time, + IBcpgKey key) + : base(algorithm, time, key) + { + } + + public override void Encode( + BcpgOutputStream bcpgOut) + { + bcpgOut.WritePacket(PacketTag.PublicSubkey, GetEncodedContents(), true); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/PublicSubkeyPacket.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/PublicSubkeyPacket.cs.meta new file mode 100644 index 0000000..3ebec03 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/PublicSubkeyPacket.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f320aa873239b314295bbb4edb2e6a26 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/RsaPublicBcpgKey.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/RsaPublicBcpgKey.cs new file mode 100644 index 0000000..fd2313c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/RsaPublicBcpgKey.cs @@ -0,0 +1,66 @@ +using System; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Bcpg +{ + /// Base class for an RSA public key. + public class RsaPublicBcpgKey + : BcpgObject, IBcpgKey + { + private readonly MPInteger n, e; + + /// Construct an RSA public key from the passed in stream. + public RsaPublicBcpgKey( + BcpgInputStream bcpgIn) + { + this.n = new MPInteger(bcpgIn); + this.e = new MPInteger(bcpgIn); + } + + /// The modulus. + /// The public exponent. + public RsaPublicBcpgKey( + BigInteger n, + BigInteger e) + { + this.n = new MPInteger(n); + this.e = new MPInteger(e); + } + + public BigInteger PublicExponent + { + get { return e.Value; } + } + + public BigInteger Modulus + { + get { return n.Value; } + } + + /// The format, as a string, always "PGP". + public string Format + { + get { return "PGP"; } + } + + /// Return the standard PGP encoding of the key. + public override byte[] GetEncoded() + { + try + { + return base.GetEncoded(); + } + catch (Exception) + { + return null; + } + } + + public override void Encode( + BcpgOutputStream bcpgOut) + { + bcpgOut.WriteObjects(n, e); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/RsaPublicBcpgKey.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/RsaPublicBcpgKey.cs.meta new file mode 100644 index 0000000..d4e51f8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/RsaPublicBcpgKey.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 19d8fe0cc8e0a4f4597c4ef88fa2da2f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/RsaSecretBcpgKey.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/RsaSecretBcpgKey.cs new file mode 100644 index 0000000..783f083 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/RsaSecretBcpgKey.cs @@ -0,0 +1,115 @@ +using System; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Bcpg +{ + /// Base class for an RSA secret (or priate) key. + public class RsaSecretBcpgKey + : BcpgObject, IBcpgKey + { + private readonly MPInteger d, p, q, u; + private readonly BigInteger expP, expQ, crt; + + public RsaSecretBcpgKey( + BcpgInputStream bcpgIn) + { + this.d = new MPInteger(bcpgIn); + this.p = new MPInteger(bcpgIn); + this.q = new MPInteger(bcpgIn); + this.u = new MPInteger(bcpgIn); + + this.expP = d.Value.Remainder(p.Value.Subtract(BigInteger.One)); + this.expQ = d.Value.Remainder(q.Value.Subtract(BigInteger.One)); + this.crt = BigIntegers.ModOddInverse(p.Value, q.Value); + } + + public RsaSecretBcpgKey( + BigInteger d, + BigInteger p, + BigInteger q) + { + // PGP requires (p < q) + int cmp = p.CompareTo(q); + if (cmp >= 0) + { + if (cmp == 0) + throw new ArgumentException("p and q cannot be equal"); + + BigInteger tmp = p; + p = q; + q = tmp; + } + + this.d = new MPInteger(d); + this.p = new MPInteger(p); + this.q = new MPInteger(q); + this.u = new MPInteger(BigIntegers.ModOddInverse(q, p)); + + this.expP = d.Remainder(p.Subtract(BigInteger.One)); + this.expQ = d.Remainder(q.Subtract(BigInteger.One)); + this.crt = BigIntegers.ModOddInverse(p, q); + } + + public BigInteger Modulus + { + get { return p.Value.Multiply(q.Value); } + } + + public BigInteger PrivateExponent + { + get { return d.Value; } + } + + public BigInteger PrimeP + { + get { return p.Value; } + } + + public BigInteger PrimeQ + { + get { return q.Value; } + } + + public BigInteger PrimeExponentP + { + get { return expP; } + } + + public BigInteger PrimeExponentQ + { + get { return expQ; } + } + + public BigInteger CrtCoefficient + { + get { return crt; } + } + + /// The format, as a string, always "PGP". + public string Format + { + get { return "PGP"; } + } + + /// Return the standard PGP encoding of the key. + public override byte[] GetEncoded() + { + try + { + return base.GetEncoded(); + } + catch (Exception) + { + return null; + } + } + + public override void Encode( + BcpgOutputStream bcpgOut) + { + bcpgOut.WriteObjects(d, p, q, u); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/RsaSecretBcpgKey.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/RsaSecretBcpgKey.cs.meta new file mode 100644 index 0000000..e1f0096 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/RsaSecretBcpgKey.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e616081c62080144a88f2a239833109b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/S2k.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/S2k.cs new file mode 100644 index 0000000..33fd792 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/S2k.cs @@ -0,0 +1,149 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Bcpg +{ + /// The string to key specifier class. + public class S2k + : BcpgObject + { + private const int ExpBias = 6; + + public const int Simple = 0; + public const int Salted = 1; + public const int SaltedAndIterated = 3; + public const int GnuDummyS2K = 101; + public const int GnuProtectionModeNoPrivateKey = 1; + public const int GnuProtectionModeDivertToCard = 2; + + internal int type; + internal HashAlgorithmTag algorithm; + internal byte[] iv; + internal int itCount = -1; + internal int protectionMode = -1; + + internal S2k( + Stream inStr) + { + type = inStr.ReadByte(); + algorithm = (HashAlgorithmTag) inStr.ReadByte(); + + // + // if this happens we have a dummy-S2k packet. + // + if (type != GnuDummyS2K) + { + if (type != 0) + { + iv = new byte[8]; + if (Streams.ReadFully(inStr, iv, 0, iv.Length) < iv.Length) + throw new EndOfStreamException(); + + if (type == 3) + { + itCount = inStr.ReadByte(); + } + } + } + else + { + inStr.ReadByte(); // G + inStr.ReadByte(); // N + inStr.ReadByte(); // U + protectionMode = inStr.ReadByte(); // protection mode + } + } + + public S2k( + HashAlgorithmTag algorithm) + { + this.type = 0; + this.algorithm = algorithm; + } + + public S2k( + HashAlgorithmTag algorithm, + byte[] iv) + { + this.type = 1; + this.algorithm = algorithm; + this.iv = iv; + } + + public S2k( + HashAlgorithmTag algorithm, + byte[] iv, + int itCount) + { + this.type = 3; + this.algorithm = algorithm; + this.iv = iv; + this.itCount = itCount; + } + + public virtual int Type + { + get { return type; } + } + + /// The hash algorithm. + public virtual HashAlgorithmTag HashAlgorithm + { + get { return algorithm; } + } + + /// The IV for the key generation algorithm. + public virtual byte[] GetIV() + { + return Arrays.Clone(iv); + } + + [Obsolete("Use 'IterationCount' property instead")] + public long GetIterationCount() + { + return IterationCount; + } + + /// The iteration count + public virtual long IterationCount + { + get { return (16 + (itCount & 15)) << ((itCount >> 4) + ExpBias); } + } + + /// The protection mode - only if GnuDummyS2K + public virtual int ProtectionMode + { + get { return protectionMode; } + } + + public override void Encode( + BcpgOutputStream bcpgOut) + { + bcpgOut.WriteByte((byte) type); + bcpgOut.WriteByte((byte) algorithm); + + if (type != GnuDummyS2K) + { + if (type != 0) + { + bcpgOut.Write(iv); + } + + if (type == 3) + { + bcpgOut.WriteByte((byte) itCount); + } + } + else + { + bcpgOut.WriteByte((byte) 'G'); + bcpgOut.WriteByte((byte) 'N'); + bcpgOut.WriteByte((byte) 'U'); + bcpgOut.WriteByte((byte) protectionMode); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/S2k.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/S2k.cs.meta new file mode 100644 index 0000000..50985cb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/S2k.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b3bcdc0363073c442bf817eb5eeb8367 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SecretKeyPacket.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SecretKeyPacket.cs new file mode 100644 index 0000000..d9ceab4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SecretKeyPacket.cs @@ -0,0 +1,170 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Bcpg +{ + /// Basic packet for a PGP secret key. + public class SecretKeyPacket + : ContainedPacket //, PublicKeyAlgorithmTag + { + public const int UsageNone = 0x00; + public const int UsageChecksum = 0xff; + public const int UsageSha1 = 0xfe; + + private PublicKeyPacket pubKeyPacket; + private readonly byte[] secKeyData; + private int s2kUsage; + private SymmetricKeyAlgorithmTag encAlgorithm; + private S2k s2k; + private byte[] iv; + + internal SecretKeyPacket( + BcpgInputStream bcpgIn) + { + if (this is SecretSubkeyPacket) + { + pubKeyPacket = new PublicSubkeyPacket(bcpgIn); + } + else + { + pubKeyPacket = new PublicKeyPacket(bcpgIn); + } + + s2kUsage = bcpgIn.ReadByte(); + + if (s2kUsage == UsageChecksum || s2kUsage == UsageSha1) + { + encAlgorithm = (SymmetricKeyAlgorithmTag) bcpgIn.ReadByte(); + s2k = new S2k(bcpgIn); + } + else + { + encAlgorithm = (SymmetricKeyAlgorithmTag) s2kUsage; + } + + if (!(s2k != null && s2k.Type == S2k.GnuDummyS2K && s2k.ProtectionMode == 0x01)) + { + if (s2kUsage != 0) + { + if (((int) encAlgorithm) < 7) + { + iv = new byte[8]; + } + else + { + iv = new byte[16]; + } + bcpgIn.ReadFully(iv); + } + } + + secKeyData = bcpgIn.ReadAll(); + } + + public SecretKeyPacket( + PublicKeyPacket pubKeyPacket, + SymmetricKeyAlgorithmTag encAlgorithm, + S2k s2k, + byte[] iv, + byte[] secKeyData) + { + this.pubKeyPacket = pubKeyPacket; + this.encAlgorithm = encAlgorithm; + + if (encAlgorithm != SymmetricKeyAlgorithmTag.Null) + { + this.s2kUsage = UsageChecksum; + } + else + { + this.s2kUsage = UsageNone; + } + + this.s2k = s2k; + this.iv = Arrays.Clone(iv); + this.secKeyData = secKeyData; + } + + public SecretKeyPacket( + PublicKeyPacket pubKeyPacket, + SymmetricKeyAlgorithmTag encAlgorithm, + int s2kUsage, + S2k s2k, + byte[] iv, + byte[] secKeyData) + { + this.pubKeyPacket = pubKeyPacket; + this.encAlgorithm = encAlgorithm; + this.s2kUsage = s2kUsage; + this.s2k = s2k; + this.iv = Arrays.Clone(iv); + this.secKeyData = secKeyData; + } + + public SymmetricKeyAlgorithmTag EncAlgorithm + { + get { return encAlgorithm; } + } + + public int S2kUsage + { + get { return s2kUsage; } + } + + public byte[] GetIV() + { + return Arrays.Clone(iv); + } + + public S2k S2k + { + get { return s2k; } + } + + public PublicKeyPacket PublicKeyPacket + { + get { return pubKeyPacket; } + } + + public byte[] GetSecretKeyData() + { + return secKeyData; + } + + public byte[] GetEncodedContents() + { + MemoryStream bOut = new MemoryStream(); + BcpgOutputStream pOut = new BcpgOutputStream(bOut); + + pOut.Write(pubKeyPacket.GetEncodedContents()); + + pOut.WriteByte((byte) s2kUsage); + + if (s2kUsage == UsageChecksum || s2kUsage == UsageSha1) + { + pOut.WriteByte((byte) encAlgorithm); + pOut.WriteObject(s2k); + } + + if (iv != null) + { + pOut.Write(iv); + } + + if (secKeyData != null && secKeyData.Length > 0) + { + pOut.Write(secKeyData); + } + + return bOut.ToArray(); + } + + public override void Encode( + BcpgOutputStream bcpgOut) + { + bcpgOut.WritePacket(PacketTag.SecretKey, GetEncodedContents(), true); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SecretKeyPacket.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SecretKeyPacket.cs.meta new file mode 100644 index 0000000..b194b25 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SecretKeyPacket.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2878df59ccde4b1449a9d28529b3e206 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SecretSubkeyPacket.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SecretSubkeyPacket.cs new file mode 100644 index 0000000..8f17469 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SecretSubkeyPacket.cs @@ -0,0 +1,43 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Bcpg +{ + /// Basic packet for a PGP secret key. + public class SecretSubkeyPacket + : SecretKeyPacket + { + internal SecretSubkeyPacket( + BcpgInputStream bcpgIn) + : base(bcpgIn) + { + } + + public SecretSubkeyPacket( + PublicKeyPacket pubKeyPacket, + SymmetricKeyAlgorithmTag encAlgorithm, + S2k s2k, + byte[] iv, + byte[] secKeyData) + : base(pubKeyPacket, encAlgorithm, s2k, iv, secKeyData) + { + } + + public SecretSubkeyPacket( + PublicKeyPacket pubKeyPacket, + SymmetricKeyAlgorithmTag encAlgorithm, + int s2kUsage, + S2k s2k, + byte[] iv, + byte[] secKeyData) + : base(pubKeyPacket, encAlgorithm, s2kUsage, s2k, iv, secKeyData) + { + } + + public override void Encode( + BcpgOutputStream bcpgOut) + { + bcpgOut.WritePacket(PacketTag.SecretSubkey, GetEncodedContents(), true); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SecretSubkeyPacket.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SecretSubkeyPacket.cs.meta new file mode 100644 index 0000000..82bd53e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SecretSubkeyPacket.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2a3f2a0227956a749bc540b9ee1f1c75 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SignaturePacket.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SignaturePacket.cs new file mode 100644 index 0000000..9a664f9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SignaturePacket.cs @@ -0,0 +1,486 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Bcpg.Sig; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Date; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Bcpg +{ + /// Generic signature packet. + public class SignaturePacket + : ContainedPacket //, PublicKeyAlgorithmTag + { + private int version; + private int signatureType; + private long creationTime; + private long keyId; + private PublicKeyAlgorithmTag keyAlgorithm; + private HashAlgorithmTag hashAlgorithm; + private MPInteger[] signature; + private byte[] fingerprint; + private SignatureSubpacket[] hashedData; + private SignatureSubpacket[] unhashedData; + private byte[] signatureEncoding; + + internal SignaturePacket( + BcpgInputStream bcpgIn) + { + version = bcpgIn.ReadByte(); + + if (version == 3 || version == 2) + { +// int l = + bcpgIn.ReadByte(); + + signatureType = bcpgIn.ReadByte(); + creationTime = (((long)bcpgIn.ReadByte() << 24) | ((long)bcpgIn.ReadByte() << 16) + | ((long)bcpgIn.ReadByte() << 8) | (uint)bcpgIn.ReadByte()) * 1000L; + + keyId |= (long)bcpgIn.ReadByte() << 56; + keyId |= (long)bcpgIn.ReadByte() << 48; + keyId |= (long)bcpgIn.ReadByte() << 40; + keyId |= (long)bcpgIn.ReadByte() << 32; + keyId |= (long)bcpgIn.ReadByte() << 24; + keyId |= (long)bcpgIn.ReadByte() << 16; + keyId |= (long)bcpgIn.ReadByte() << 8; + keyId |= (uint)bcpgIn.ReadByte(); + + keyAlgorithm = (PublicKeyAlgorithmTag) bcpgIn.ReadByte(); + hashAlgorithm = (HashAlgorithmTag) bcpgIn.ReadByte(); + } + else if (version == 4) + { + signatureType = bcpgIn.ReadByte(); + keyAlgorithm = (PublicKeyAlgorithmTag) bcpgIn.ReadByte(); + hashAlgorithm = (HashAlgorithmTag) bcpgIn.ReadByte(); + + int hashedLength = (bcpgIn.ReadByte() << 8) | bcpgIn.ReadByte(); + byte[] hashed = new byte[hashedLength]; + + bcpgIn.ReadFully(hashed); + + // + // read the signature sub packet data. + // + SignatureSubpacketsParser sIn = new SignatureSubpacketsParser( + new MemoryStream(hashed, false)); + + IList v = Platform.CreateArrayList(); + SignatureSubpacket sub; + while ((sub = sIn.ReadPacket()) != null) + { + v.Add(sub); + } + + hashedData = new SignatureSubpacket[v.Count]; + + for (int i = 0; i != hashedData.Length; i++) + { + SignatureSubpacket p = (SignatureSubpacket)v[i]; + if (p is IssuerKeyId) + { + keyId = ((IssuerKeyId)p).KeyId; + } + else if (p is SignatureCreationTime) + { + creationTime = DateTimeUtilities.DateTimeToUnixMs( + ((SignatureCreationTime)p).GetTime()); + } + + hashedData[i] = p; + } + + int unhashedLength = (bcpgIn.ReadByte() << 8) | bcpgIn.ReadByte(); + byte[] unhashed = new byte[unhashedLength]; + + bcpgIn.ReadFully(unhashed); + + sIn = new SignatureSubpacketsParser(new MemoryStream(unhashed, false)); + + v.Clear(); + + while ((sub = sIn.ReadPacket()) != null) + { + v.Add(sub); + } + + unhashedData = new SignatureSubpacket[v.Count]; + + for (int i = 0; i != unhashedData.Length; i++) + { + SignatureSubpacket p = (SignatureSubpacket)v[i]; + if (p is IssuerKeyId) + { + keyId = ((IssuerKeyId)p).KeyId; + } + + unhashedData[i] = p; + } + } + else + { + Streams.Drain(bcpgIn); + + throw new UnsupportedPacketVersionException("unsupported version: " + version); + } + + fingerprint = new byte[2]; + bcpgIn.ReadFully(fingerprint); + + switch (keyAlgorithm) + { + case PublicKeyAlgorithmTag.RsaGeneral: + case PublicKeyAlgorithmTag.RsaSign: + MPInteger v = new MPInteger(bcpgIn); + signature = new MPInteger[]{ v }; + break; + case PublicKeyAlgorithmTag.Dsa: + MPInteger r = new MPInteger(bcpgIn); + MPInteger s = new MPInteger(bcpgIn); + signature = new MPInteger[]{ r, s }; + break; + case PublicKeyAlgorithmTag.ElGamalEncrypt: // yep, this really does happen sometimes. + case PublicKeyAlgorithmTag.ElGamalGeneral: + MPInteger p = new MPInteger(bcpgIn); + MPInteger g = new MPInteger(bcpgIn); + MPInteger y = new MPInteger(bcpgIn); + signature = new MPInteger[]{ p, g, y }; + break; + case PublicKeyAlgorithmTag.ECDsa: + MPInteger ecR = new MPInteger(bcpgIn); + MPInteger ecS = new MPInteger(bcpgIn); + signature = new MPInteger[]{ ecR, ecS }; + break; + default: + if (keyAlgorithm >= PublicKeyAlgorithmTag.Experimental_1 && keyAlgorithm <= PublicKeyAlgorithmTag.Experimental_11) + { + signature = null; + MemoryStream bOut = new MemoryStream(); + int ch; + while ((ch = bcpgIn.ReadByte()) >= 0) + { + bOut.WriteByte((byte) ch); + } + signatureEncoding = bOut.ToArray(); + } + else + { + throw new IOException("unknown signature key algorithm: " + keyAlgorithm); + } + break; + } + } + + /** + * Generate a version 4 signature packet. + * + * @param signatureType + * @param keyAlgorithm + * @param hashAlgorithm + * @param hashedData + * @param unhashedData + * @param fingerprint + * @param signature + */ + public SignaturePacket( + int signatureType, + long keyId, + PublicKeyAlgorithmTag keyAlgorithm, + HashAlgorithmTag hashAlgorithm, + SignatureSubpacket[] hashedData, + SignatureSubpacket[] unhashedData, + byte[] fingerprint, + MPInteger[] signature) + : this(4, signatureType, keyId, keyAlgorithm, hashAlgorithm, hashedData, unhashedData, fingerprint, signature) + { + } + + /** + * Generate a version 2/3 signature packet. + * + * @param signatureType + * @param keyAlgorithm + * @param hashAlgorithm + * @param fingerprint + * @param signature + */ + public SignaturePacket( + int version, + int signatureType, + long keyId, + PublicKeyAlgorithmTag keyAlgorithm, + HashAlgorithmTag hashAlgorithm, + long creationTime, + byte[] fingerprint, + MPInteger[] signature) + : this(version, signatureType, keyId, keyAlgorithm, hashAlgorithm, null, null, fingerprint, signature) + { + this.creationTime = creationTime; + } + + public SignaturePacket( + int version, + int signatureType, + long keyId, + PublicKeyAlgorithmTag keyAlgorithm, + HashAlgorithmTag hashAlgorithm, + SignatureSubpacket[] hashedData, + SignatureSubpacket[] unhashedData, + byte[] fingerprint, + MPInteger[] signature) + { + this.version = version; + this.signatureType = signatureType; + this.keyId = keyId; + this.keyAlgorithm = keyAlgorithm; + this.hashAlgorithm = hashAlgorithm; + this.hashedData = hashedData; + this.unhashedData = unhashedData; + this.fingerprint = fingerprint; + this.signature = signature; + + if (hashedData != null) + { + setCreationTime(); + } + } + + public int Version + { + get { return version; } + } + + public int SignatureType + { + get { return signatureType; } + } + + /** + * return the keyId + * @return the keyId that created the signature. + */ + public long KeyId + { + get { return keyId; } + } + + /** + * return the signature trailer that must be included with the data + * to reconstruct the signature + * + * @return byte[] + */ + public byte[] GetSignatureTrailer() + { + byte[] trailer = null; + + if (version == 3) + { + trailer = new byte[5]; + + long time = creationTime / 1000L; + + trailer[0] = (byte)signatureType; + trailer[1] = (byte)(time >> 24); + trailer[2] = (byte)(time >> 16); + trailer[3] = (byte)(time >> 8); + trailer[4] = (byte)(time); + } + else + { + MemoryStream sOut = new MemoryStream(); + + sOut.WriteByte((byte)this.Version); + sOut.WriteByte((byte)this.SignatureType); + sOut.WriteByte((byte)this.KeyAlgorithm); + sOut.WriteByte((byte)this.HashAlgorithm); + + MemoryStream hOut = new MemoryStream(); + SignatureSubpacket[] hashed = this.GetHashedSubPackets(); + + for (int i = 0; i != hashed.Length; i++) + { + hashed[i].Encode(hOut); + } + + byte[] data = hOut.ToArray(); + + sOut.WriteByte((byte)(data.Length >> 8)); + sOut.WriteByte((byte)data.Length); + sOut.Write(data, 0, data.Length); + + byte[] hData = sOut.ToArray(); + + sOut.WriteByte((byte)this.Version); + sOut.WriteByte((byte)0xff); + sOut.WriteByte((byte)(hData.Length>> 24)); + sOut.WriteByte((byte)(hData.Length >> 16)); + sOut.WriteByte((byte)(hData.Length >> 8)); + sOut.WriteByte((byte)(hData.Length)); + + trailer = sOut.ToArray(); + } + + return trailer; + } + + public PublicKeyAlgorithmTag KeyAlgorithm + { + get { return keyAlgorithm; } + } + + public HashAlgorithmTag HashAlgorithm + { + get { return hashAlgorithm; } + } + + /** + * return the signature as a set of integers - note this is normalised to be the + * ASN.1 encoding of what appears in the signature packet. + */ + public MPInteger[] GetSignature() + { + return signature; + } + + /** + * Return the byte encoding of the signature section. + * @return uninterpreted signature bytes. + */ + public byte[] GetSignatureBytes() + { + if (signatureEncoding != null) + { + return (byte[]) signatureEncoding.Clone(); + } + + MemoryStream bOut = new MemoryStream(); + BcpgOutputStream bcOut = new BcpgOutputStream(bOut); + + foreach (MPInteger sigObj in signature) + { + try + { + bcOut.WriteObject(sigObj); + } + catch (IOException e) + { + throw new Exception("internal error: " + e); + } + } + + return bOut.ToArray(); + } + + public SignatureSubpacket[] GetHashedSubPackets() + { + return hashedData; + } + + public SignatureSubpacket[] GetUnhashedSubPackets() + { + return unhashedData; + } + + /// Return the creation time in milliseconds since 1 Jan., 1970 UTC. + public long CreationTime + { + get { return creationTime; } + } + + public override void Encode( + BcpgOutputStream bcpgOut) + { + MemoryStream bOut = new MemoryStream(); + BcpgOutputStream pOut = new BcpgOutputStream(bOut); + + pOut.WriteByte((byte) version); + + if (version == 3 || version == 2) + { + pOut.Write( + 5, // the length of the next block + (byte) signatureType); + + pOut.WriteInt((int)(creationTime / 1000L)); + + pOut.WriteLong(keyId); + + pOut.Write( + (byte) keyAlgorithm, + (byte) hashAlgorithm); + } + else if (version == 4) + { + pOut.Write( + (byte) signatureType, + (byte) keyAlgorithm, + (byte) hashAlgorithm); + + EncodeLengthAndData(pOut, GetEncodedSubpackets(hashedData)); + + EncodeLengthAndData(pOut, GetEncodedSubpackets(unhashedData)); + } + else + { + throw new IOException("unknown version: " + version); + } + + pOut.Write(fingerprint); + + if (signature != null) + { + pOut.WriteObjects(signature); + } + else + { + pOut.Write(signatureEncoding); + } + + bcpgOut.WritePacket(PacketTag.Signature, bOut.ToArray(), true); + } + + private static void EncodeLengthAndData( + BcpgOutputStream pOut, + byte[] data) + { + pOut.WriteShort((short) data.Length); + pOut.Write(data); + } + + private static byte[] GetEncodedSubpackets( + SignatureSubpacket[] ps) + { + MemoryStream sOut = new MemoryStream(); + + foreach (SignatureSubpacket p in ps) + { + p.Encode(sOut); + } + + return sOut.ToArray(); + } + + private void setCreationTime() + { + foreach (SignatureSubpacket p in hashedData) + { + if (p is SignatureCreationTime) + { + creationTime = DateTimeUtilities.DateTimeToUnixMs( + ((SignatureCreationTime)p).GetTime()); + break; + } + } + } + public static SignaturePacket FromByteArray(byte[] data) + { + BcpgInputStream input = BcpgInputStream.Wrap(new MemoryStream(data)); + + return new SignaturePacket(input); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SignaturePacket.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SignaturePacket.cs.meta new file mode 100644 index 0000000..265b820 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SignaturePacket.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e183341cfa16dbd4fb241ec31209a0ca +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SignatureSubpacket.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SignatureSubpacket.cs new file mode 100644 index 0000000..5accadc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SignatureSubpacket.cs @@ -0,0 +1,115 @@ +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Bcpg +{ + /// Basic type for a PGP Signature sub-packet. + public class SignatureSubpacket + { + private readonly SignatureSubpacketTag type; + private readonly bool critical; + private readonly bool isLongLength; + internal byte[] data; + + protected internal SignatureSubpacket( + SignatureSubpacketTag type, + bool critical, + bool isLongLength, + byte[] data) + { + this.type = type; + this.critical = critical; + this.isLongLength = isLongLength; + this.data = data; + } + + public SignatureSubpacketTag SubpacketType + { + get { return type; } + } + + public bool IsCritical() + { + return critical; + } + + public bool IsLongLength() + { + return isLongLength; + } + + /// Return the generic data making up the packet. + public byte[] GetData() + { + return (byte[]) data.Clone(); + } + + public void Encode( + Stream os) + { + int bodyLen = data.Length + 1; + + if (isLongLength) + { + os.WriteByte(0xff); + os.WriteByte((byte)(bodyLen >> 24)); + os.WriteByte((byte)(bodyLen >> 16)); + os.WriteByte((byte)(bodyLen >> 8)); + os.WriteByte((byte)bodyLen); + } + else + { + if (bodyLen < 192) + { + os.WriteByte((byte)bodyLen); + } + else if (bodyLen <= 8383) + { + bodyLen -= 192; + + os.WriteByte((byte)(((bodyLen >> 8) & 0xff) + 192)); + os.WriteByte((byte)bodyLen); + } + else + { + os.WriteByte(0xff); + os.WriteByte((byte)(bodyLen >> 24)); + os.WriteByte((byte)(bodyLen >> 16)); + os.WriteByte((byte)(bodyLen >> 8)); + os.WriteByte((byte)bodyLen); + } + } + + if (critical) + { + os.WriteByte((byte)(0x80 | (int) type)); + } + else + { + os.WriteByte((byte) type); + } + + os.Write(data, 0, data.Length); + } + + public override int GetHashCode() + { + return (critical ? 1 : 0) + 7 * (int)type + 49 * Arrays.GetHashCode(data); + } + + public override bool Equals(object obj) + { + if (obj == this) + return true; + + SignatureSubpacket other = obj as SignatureSubpacket; + if (null == other) + return false; + + return this.type == other.type + && this.critical == other.critical + && Arrays.AreEqual(this.data, other.data); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SignatureSubpacket.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SignatureSubpacket.cs.meta new file mode 100644 index 0000000..843eac7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SignatureSubpacket.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 25ec6d4139530fd4299b20c3d5b755a2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SignatureSubpacketTags.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SignatureSubpacketTags.cs new file mode 100644 index 0000000..1a8e254 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SignatureSubpacketTags.cs @@ -0,0 +1,33 @@ +namespace Org.BouncyCastle.Bcpg +{ + /** + * Basic PGP signature sub-packet tag types. + */ + public enum SignatureSubpacketTag + { + CreationTime = 2, // signature creation time + ExpireTime = 3, // signature expiration time + Exportable = 4, // exportable certification + TrustSig = 5, // trust signature + RegExp = 6, // regular expression + Revocable = 7, // revocable + KeyExpireTime = 9, // key expiration time + Placeholder = 10, // placeholder for backward compatibility + PreferredSymmetricAlgorithms = 11, // preferred symmetric algorithms + RevocationKey = 12, // revocation key + IssuerKeyId = 16, // issuer key ID + NotationData = 20, // notation data + PreferredHashAlgorithms = 21, // preferred hash algorithms + PreferredCompressionAlgorithms = 22, // preferred compression algorithms + KeyServerPreferences = 23, // key server preferences + PreferredKeyServer = 24, // preferred key server + PrimaryUserId = 25, // primary user id + PolicyUrl = 26, // policy URL + KeyFlags = 27, // key flags + SignerUserId = 28, // signer's user id + RevocationReason = 29, // reason for revocation + Features = 30, // features + SignatureTarget = 31, // signature target + EmbeddedSignature = 32 // embedded signature + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SignatureSubpacketTags.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SignatureSubpacketTags.cs.meta new file mode 100644 index 0000000..18625d3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SignatureSubpacketTags.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f5701f01697aa3e4e8722f6214c1640c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SignatureSubpacketsReader.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SignatureSubpacketsReader.cs new file mode 100644 index 0000000..45dc968 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SignatureSubpacketsReader.cs @@ -0,0 +1,131 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Bcpg.Sig; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Bcpg +{ + /** + * reader for signature sub-packets + */ + public class SignatureSubpacketsParser + { + private readonly Stream input; + + public SignatureSubpacketsParser( + Stream input) + { + this.input = input; + } + + public SignatureSubpacket ReadPacket() + { + int l = input.ReadByte(); + if (l < 0) + return null; + + int bodyLen = 0; + bool isLongLength = false; + + if (l < 192) + { + bodyLen = l; + } + else if (l <= 223) + { + bodyLen = ((l - 192) << 8) + (input.ReadByte()) + 192; + } + else if (l == 255) + { + isLongLength = true; + bodyLen = (input.ReadByte() << 24) | (input.ReadByte() << 16) + | (input.ReadByte() << 8) | input.ReadByte(); + } + else + { + throw new IOException("unexpected length header"); + } + + int tag = input.ReadByte(); + if (tag < 0) + throw new EndOfStreamException("unexpected EOF reading signature sub packet"); + + if (bodyLen <= 0) + throw new EndOfStreamException("out of range data found in signature sub packet"); + + byte[] data = new byte[bodyLen - 1]; + + // + // this may seem a bit strange but it turns out some applications miscode the length + // in fixed length fields, so we check the length we do get, only throwing an exception if + // we really cannot continue + // + int bytesRead = Streams.ReadFully(input, data); + + bool isCritical = ((tag & 0x80) != 0); + SignatureSubpacketTag type = (SignatureSubpacketTag)(tag & 0x7f); + + if (bytesRead != data.Length) + { + switch (type) + { + case SignatureSubpacketTag.CreationTime: + data = CheckData(data, 4, bytesRead, "Signature Creation Time"); + break; + case SignatureSubpacketTag.IssuerKeyId: + data = CheckData(data, 8, bytesRead, "Issuer"); + break; + case SignatureSubpacketTag.KeyExpireTime: + data = CheckData(data, 4, bytesRead, "Signature Key Expiration Time"); + break; + case SignatureSubpacketTag.ExpireTime: + data = CheckData(data, 4, bytesRead, "Signature Expiration Time"); + break; + default: + throw new EndOfStreamException("truncated subpacket data."); + } + } + + switch (type) + { + case SignatureSubpacketTag.CreationTime: + return new SignatureCreationTime(isCritical, isLongLength, data); + case SignatureSubpacketTag.KeyExpireTime: + return new KeyExpirationTime(isCritical, isLongLength, data); + case SignatureSubpacketTag.ExpireTime: + return new SignatureExpirationTime(isCritical, isLongLength, data); + case SignatureSubpacketTag.Revocable: + return new Revocable(isCritical, isLongLength, data); + case SignatureSubpacketTag.Exportable: + return new Exportable(isCritical, isLongLength, data); + case SignatureSubpacketTag.IssuerKeyId: + return new IssuerKeyId(isCritical, isLongLength, data); + case SignatureSubpacketTag.TrustSig: + return new TrustSignature(isCritical, isLongLength, data); + case SignatureSubpacketTag.PreferredCompressionAlgorithms: + case SignatureSubpacketTag.PreferredHashAlgorithms: + case SignatureSubpacketTag.PreferredSymmetricAlgorithms: + return new PreferredAlgorithms(type, isCritical, isLongLength, data); + case SignatureSubpacketTag.KeyFlags: + return new KeyFlags(isCritical, isLongLength, data); + case SignatureSubpacketTag.PrimaryUserId: + return new PrimaryUserId(isCritical, isLongLength, data); + case SignatureSubpacketTag.SignerUserId: + return new SignerUserId(isCritical, isLongLength, data); + case SignatureSubpacketTag.NotationData: + return new NotationData(isCritical, isLongLength, data); + } + return new SignatureSubpacket(type, isCritical, isLongLength, data); + } + + private byte[] CheckData(byte[] data, int expected, int bytesRead, string name) + { + if (bytesRead != expected) + throw new EndOfStreamException("truncated " + name + " subpacket data."); + + return Arrays.CopyOfRange(data, 0, expected); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SignatureSubpacketsReader.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SignatureSubpacketsReader.cs.meta new file mode 100644 index 0000000..4da5447 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SignatureSubpacketsReader.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 31873eb2bc3a4d84686bb9d7f14d784f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SymmetricEncDataPacket.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SymmetricEncDataPacket.cs new file mode 100644 index 0000000..17ee55b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SymmetricEncDataPacket.cs @@ -0,0 +1,15 @@ +using System; + +namespace Org.BouncyCastle.Bcpg +{ + /// Basic type for a symmetric key encrypted packet. + public class SymmetricEncDataPacket + : InputStreamPacket + { + public SymmetricEncDataPacket( + BcpgInputStream bcpgIn) + : base(bcpgIn) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SymmetricEncDataPacket.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SymmetricEncDataPacket.cs.meta new file mode 100644 index 0000000..4b017c5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SymmetricEncDataPacket.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a7cd93bcc9f69104b9a3c16c942d99f4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SymmetricEncIntegrityPacket.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SymmetricEncIntegrityPacket.cs new file mode 100644 index 0000000..a9b6d06 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SymmetricEncIntegrityPacket.cs @@ -0,0 +1,18 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Bcpg +{ + public class SymmetricEncIntegrityPacket + : InputStreamPacket + { + internal readonly int version; + + internal SymmetricEncIntegrityPacket( + BcpgInputStream bcpgIn) + : base(bcpgIn) + { + version = bcpgIn.ReadByte(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SymmetricEncIntegrityPacket.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SymmetricEncIntegrityPacket.cs.meta new file mode 100644 index 0000000..72cd6de --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SymmetricEncIntegrityPacket.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b2a358ae74ae3aa43b1c306ab29743c0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SymmetricKeyAlgorithmTags.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SymmetricKeyAlgorithmTags.cs new file mode 100644 index 0000000..e05a486 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SymmetricKeyAlgorithmTags.cs @@ -0,0 +1,23 @@ +namespace Org.BouncyCastle.Bcpg +{ + /** + * Basic tags for symmetric key algorithms + */ + public enum SymmetricKeyAlgorithmTag + { + Null = 0, // Plaintext or unencrypted data + Idea = 1, // IDEA [IDEA] + TripleDes = 2, // Triple-DES (DES-EDE, as per spec -168 bit key derived from 192) + Cast5 = 3, // Cast5 (128 bit key, as per RFC 2144) + Blowfish = 4, // Blowfish (128 bit key, 16 rounds) [Blowfish] + Safer = 5, // Safer-SK128 (13 rounds) [Safer] + Des = 6, // Reserved for DES/SK + Aes128 = 7, // Reserved for AES with 128-bit key + Aes192 = 8, // Reserved for AES with 192-bit key + Aes256 = 9, // Reserved for AES with 256-bit key + Twofish = 10, // Reserved for Twofish + Camellia128 = 11, // Reserved for AES with 128-bit key + Camellia192 = 12, // Reserved for AES with 192-bit key + Camellia256 = 13 // Reserved for AES with 256-bit key + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SymmetricKeyAlgorithmTags.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SymmetricKeyAlgorithmTags.cs.meta new file mode 100644 index 0000000..b88c331 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SymmetricKeyAlgorithmTags.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6d2911be203898a48b142d068ca2cdb6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SymmetricKeyEncSessionPacket.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SymmetricKeyEncSessionPacket.cs new file mode 100644 index 0000000..0381fa3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SymmetricKeyEncSessionPacket.cs @@ -0,0 +1,91 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Bcpg +{ + /** + * Basic type for a symmetric encrypted session key packet + */ + public class SymmetricKeyEncSessionPacket + : ContainedPacket + { + private int version; + private SymmetricKeyAlgorithmTag encAlgorithm; + private S2k s2k; + private readonly byte[] secKeyData; + + public SymmetricKeyEncSessionPacket( + BcpgInputStream bcpgIn) + { + version = bcpgIn.ReadByte(); + encAlgorithm = (SymmetricKeyAlgorithmTag) bcpgIn.ReadByte(); + + s2k = new S2k(bcpgIn); + + secKeyData = bcpgIn.ReadAll(); + } + + public SymmetricKeyEncSessionPacket( + SymmetricKeyAlgorithmTag encAlgorithm, + S2k s2k, + byte[] secKeyData) + { + this.version = 4; + this.encAlgorithm = encAlgorithm; + this.s2k = s2k; + this.secKeyData = secKeyData; + } + + /** + * @return int + */ + public SymmetricKeyAlgorithmTag EncAlgorithm + { + get { return encAlgorithm; } + } + + /** + * @return S2k + */ + public S2k S2k + { + get { return s2k; } + } + + /** + * @return byte[] + */ + public byte[] GetSecKeyData() + { + return secKeyData; + } + + /** + * @return int + */ + public int Version + { + get { return version; } + } + + public override void Encode( + BcpgOutputStream bcpgOut) + { + MemoryStream bOut = new MemoryStream(); + BcpgOutputStream pOut = new BcpgOutputStream(bOut); + + pOut.Write( + (byte) version, + (byte) encAlgorithm); + + pOut.WriteObject(s2k); + + if (secKeyData != null && secKeyData.Length > 0) + { + pOut.Write(secKeyData); + } + + bcpgOut.WritePacket(PacketTag.SymmetricKeyEncryptedSessionKey, bOut.ToArray(), true); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SymmetricKeyEncSessionPacket.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SymmetricKeyEncSessionPacket.cs.meta new file mode 100644 index 0000000..6d8b500 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/SymmetricKeyEncSessionPacket.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8b6453cfc4559204e85f9c6581d6a732 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/TrustPacket.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/TrustPacket.cs new file mode 100644 index 0000000..6f1969c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/TrustPacket.cs @@ -0,0 +1,43 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Bcpg +{ + /// Basic type for a trust packet. + public class TrustPacket + : ContainedPacket + { + private readonly byte[] levelAndTrustAmount; + + public TrustPacket( + BcpgInputStream bcpgIn) + { + MemoryStream bOut = new MemoryStream(); + + int ch; + while ((ch = bcpgIn.ReadByte()) >= 0) + { + bOut.WriteByte((byte) ch); + } + + levelAndTrustAmount = bOut.ToArray(); + } + + public TrustPacket( + int trustCode) + { + this.levelAndTrustAmount = new byte[]{ (byte) trustCode }; + } + + public byte[] GetLevelAndTrustAmount() + { + return (byte[]) levelAndTrustAmount.Clone(); + } + + public override void Encode( + BcpgOutputStream bcpgOut) + { + bcpgOut.WritePacket(PacketTag.Trust, levelAndTrustAmount, true); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/TrustPacket.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/TrustPacket.cs.meta new file mode 100644 index 0000000..8d2cf4b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/TrustPacket.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f4206decb99c23645bdfa50b6c3df28a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/UnsupportedPacketVersionException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/UnsupportedPacketVersionException.cs new file mode 100644 index 0000000..447d752 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/UnsupportedPacketVersionException.cs @@ -0,0 +1,13 @@ +using System; + +namespace Org.BouncyCastle.Bcpg +{ + public class UnsupportedPacketVersionException + : Exception + { + public UnsupportedPacketVersionException(string msg) + : base(msg) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/UnsupportedPacketVersionException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/UnsupportedPacketVersionException.cs.meta new file mode 100644 index 0000000..d3b77f5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/UnsupportedPacketVersionException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f3bba133b55e0c7499404df940bfb6b8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/UserAttributePacket.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/UserAttributePacket.cs new file mode 100644 index 0000000..20e3598 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/UserAttributePacket.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Bcpg +{ + /** + * Basic type for a user attribute packet. + */ + public class UserAttributePacket + : ContainedPacket + { + private readonly UserAttributeSubpacket[] subpackets; + + public UserAttributePacket( + BcpgInputStream bcpgIn) + { + UserAttributeSubpacketsParser sIn = new UserAttributeSubpacketsParser(bcpgIn); + UserAttributeSubpacket sub; + + IList v = Platform.CreateArrayList(); + while ((sub = sIn.ReadPacket()) != null) + { + v.Add(sub); + } + + subpackets = new UserAttributeSubpacket[v.Count]; + + for (int i = 0; i != subpackets.Length; i++) + { + subpackets[i] = (UserAttributeSubpacket)v[i]; + } + } + + public UserAttributePacket( + UserAttributeSubpacket[] subpackets) + { + this.subpackets = subpackets; + } + + public UserAttributeSubpacket[] GetSubpackets() + { + return subpackets; + } + + public override void Encode( + BcpgOutputStream bcpgOut) + { + MemoryStream bOut = new MemoryStream(); + + for (int i = 0; i != subpackets.Length; i++) + { + subpackets[i].Encode(bOut); + } + + bcpgOut.WritePacket(PacketTag.UserAttribute, bOut.ToArray(), false); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/UserAttributePacket.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/UserAttributePacket.cs.meta new file mode 100644 index 0000000..7d96ad2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/UserAttributePacket.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9fc6a7750edb3b34085d3ce90d5f41d9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/UserAttributeSubpacket.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/UserAttributeSubpacket.cs new file mode 100644 index 0000000..05f60ac --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/UserAttributeSubpacket.cs @@ -0,0 +1,90 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Bcpg +{ + /** + * Basic type for a user attribute sub-packet. + */ + public class UserAttributeSubpacket + { + internal readonly UserAttributeSubpacketTag type; + private readonly bool longLength; // we preserve this as not everyone encodes length properly. + protected readonly byte[] data; + + protected internal UserAttributeSubpacket(UserAttributeSubpacketTag type, byte[] data) + : this(type, false, data) + { + } + + protected internal UserAttributeSubpacket(UserAttributeSubpacketTag type, bool forceLongLength, byte[] data) + { + this.type = type; + this.longLength = forceLongLength; + this.data = data; + } + + public virtual UserAttributeSubpacketTag SubpacketType + { + get { return type; } + } + + /** + * return the generic data making up the packet. + */ + public virtual byte[] GetData() + { + return data; + } + + public virtual void Encode(Stream os) + { + int bodyLen = data.Length + 1; + + if (bodyLen < 192 && !longLength) + { + os.WriteByte((byte)bodyLen); + } + else if (bodyLen <= 8383 && !longLength) + { + bodyLen -= 192; + + os.WriteByte((byte)(((bodyLen >> 8) & 0xff) + 192)); + os.WriteByte((byte)bodyLen); + } + else + { + os.WriteByte(0xff); + os.WriteByte((byte)(bodyLen >> 24)); + os.WriteByte((byte)(bodyLen >> 16)); + os.WriteByte((byte)(bodyLen >> 8)); + os.WriteByte((byte)bodyLen); + } + + os.WriteByte((byte) type); + os.Write(data, 0, data.Length); + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + UserAttributeSubpacket other = obj as UserAttributeSubpacket; + + if (other == null) + return false; + + return type == other.type + && Arrays.AreEqual(data, other.data); + } + + public override int GetHashCode() + { + return type.GetHashCode() ^ Arrays.GetHashCode(data); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/UserAttributeSubpacket.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/UserAttributeSubpacket.cs.meta new file mode 100644 index 0000000..3610e12 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/UserAttributeSubpacket.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e1dc20c9a52492e468be2929a38fb33e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/UserAttributeSubpacketTags.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/UserAttributeSubpacketTags.cs new file mode 100644 index 0000000..7a9cd1d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/UserAttributeSubpacketTags.cs @@ -0,0 +1,10 @@ +namespace Org.BouncyCastle.Bcpg +{ + /** + * Basic PGP user attribute sub-packet tag types. + */ + public enum UserAttributeSubpacketTag + { + ImageAttribute = 1 + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/UserAttributeSubpacketTags.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/UserAttributeSubpacketTags.cs.meta new file mode 100644 index 0000000..5f843d8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/UserAttributeSubpacketTags.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7a60ba94c0d3c704a83f5654fd664bdf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/UserAttributeSubpacketsReader.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/UserAttributeSubpacketsReader.cs new file mode 100644 index 0000000..f0cc1b8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/UserAttributeSubpacketsReader.cs @@ -0,0 +1,65 @@ +using System; +using System.IO; +using Org.BouncyCastle.Bcpg.Attr; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Bcpg +{ + /** + * reader for user attribute sub-packets + */ + public class UserAttributeSubpacketsParser + { + private readonly Stream input; + + public UserAttributeSubpacketsParser( + Stream input) + { + this.input = input; + } + + public virtual UserAttributeSubpacket ReadPacket() + { + int l = input.ReadByte(); + if (l < 0) + return null; + + int bodyLen = 0; + bool longLength = false; + if (l < 192) + { + bodyLen = l; + } + else if (l <= 223) + { + bodyLen = ((l - 192) << 8) + (input.ReadByte()) + 192; + } + else if (l == 255) + { + bodyLen = (input.ReadByte() << 24) | (input.ReadByte() << 16) + | (input.ReadByte() << 8) | input.ReadByte(); + longLength = true; + } + else + { + throw new IOException("unrecognised length reading user attribute sub packet"); + } + + int tag = input.ReadByte(); + if (tag < 0) + throw new EndOfStreamException("unexpected EOF reading user attribute sub packet"); + + byte[] data = new byte[bodyLen - 1]; + if (Streams.ReadFully(input, data) < data.Length) + throw new EndOfStreamException(); + + UserAttributeSubpacketTag type = (UserAttributeSubpacketTag) tag; + switch (type) + { + case UserAttributeSubpacketTag.ImageAttribute: + return new ImageAttrib(longLength, data); + } + return new UserAttributeSubpacket(type, longLength, data); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/UserAttributeSubpacketsReader.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/UserAttributeSubpacketsReader.cs.meta new file mode 100644 index 0000000..da4afff --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/UserAttributeSubpacketsReader.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 642330c070478aa44820a43d3fcb6b0e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/UserIdPacket.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/UserIdPacket.cs new file mode 100644 index 0000000..a175e74 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/UserIdPacket.cs @@ -0,0 +1,37 @@ +using System; +using System.Text; + +namespace Org.BouncyCastle.Bcpg +{ + /** + * Basic type for a user ID packet. + */ + public class UserIdPacket + : ContainedPacket + { + private readonly byte[] idData; + + public UserIdPacket( + BcpgInputStream bcpgIn) + { + this.idData = bcpgIn.ReadAll(); + } + + public UserIdPacket( + string id) + { + this.idData = Encoding.UTF8.GetBytes(id); + } + + public string GetId() + { + return Encoding.UTF8.GetString(idData, 0, idData.Length); + } + + public override void Encode( + BcpgOutputStream bcpgOut) + { + bcpgOut.WritePacket(PacketTag.UserId, idData, true); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/UserIdPacket.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/UserIdPacket.cs.meta new file mode 100644 index 0000000..9e69a6d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/UserIdPacket.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 373bd69e49a76354f884d5db09522b3b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/attr.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/attr.meta new file mode 100644 index 0000000..84dd400 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/attr.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7f6e0845e19cb49428594be3816ca0dc +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/attr/ImageAttrib.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/attr/ImageAttrib.cs new file mode 100644 index 0000000..2d0fef8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/attr/ImageAttrib.cs @@ -0,0 +1,72 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Bcpg.Attr +{ + /// Basic type for a image attribute packet. + public class ImageAttrib + : UserAttributeSubpacket + { + public enum Format : byte + { + Jpeg = 1 + } + + private static readonly byte[] Zeroes = new byte[12]; + + private int hdrLength; + private int _version; + private int _encoding; + private byte[] imageData; + + public ImageAttrib(byte[] data) + : this(false, data) + { + } + + public ImageAttrib(bool forceLongLength, byte[] data) + : base(UserAttributeSubpacketTag.ImageAttribute, forceLongLength, data) + { + hdrLength = ((data[1] & 0xff) << 8) | (data[0] & 0xff); + _version = data[2] & 0xff; + _encoding = data[3] & 0xff; + + imageData = new byte[data.Length - hdrLength]; + Array.Copy(data, hdrLength, imageData, 0, imageData.Length); + } + + public ImageAttrib( + Format imageType, + byte[] imageData) + : this(ToByteArray(imageType, imageData)) + { + } + + private static byte[] ToByteArray( + Format imageType, + byte[] imageData) + { + MemoryStream bOut = new MemoryStream(); + bOut.WriteByte(0x10); bOut.WriteByte(0x00); bOut.WriteByte(0x01); + bOut.WriteByte((byte) imageType); + bOut.Write(Zeroes, 0, Zeroes.Length); + bOut.Write(imageData, 0, imageData.Length); + return bOut.ToArray(); + } + + public virtual int Version + { + get { return _version; } + } + + public virtual int Encoding + { + get { return _encoding; } + } + + public virtual byte[] GetImageData() + { + return imageData; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/attr/ImageAttrib.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/attr/ImageAttrib.cs.meta new file mode 100644 index 0000000..34afedd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/attr/ImageAttrib.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9e8e420709df77849a3e0a351c813eb4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig.meta new file mode 100644 index 0000000..54a934b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: fc9f4c7a2197e5b4b9689d535c8af2dc +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/EmbeddedSignature.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/EmbeddedSignature.cs new file mode 100644 index 0000000..fffdaef --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/EmbeddedSignature.cs @@ -0,0 +1,19 @@ +using System; + +namespace Org.BouncyCastle.Bcpg.Sig +{ + /** + * Packet embedded signature + */ + public class EmbeddedSignature + : SignatureSubpacket + { + public EmbeddedSignature( + bool critical, + bool isLongLength, + byte[] data) + : base(SignatureSubpacketTag.EmbeddedSignature, critical, isLongLength, data) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/EmbeddedSignature.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/EmbeddedSignature.cs.meta new file mode 100644 index 0000000..e2afe51 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/EmbeddedSignature.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 99812fb9dffed8b468c17c3cf8f6cba6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/Exportable.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/Exportable.cs new file mode 100644 index 0000000..4d03034 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/Exportable.cs @@ -0,0 +1,46 @@ +using System; + +namespace Org.BouncyCastle.Bcpg.Sig +{ + /** + * packet giving signature creation time. + */ + public class Exportable + : SignatureSubpacket + { + private static byte[] BooleanToByteArray(bool val) + { + byte[] data = new byte[1]; + + if (val) + { + data[0] = 1; + return data; + } + else + { + return data; + } + } + + public Exportable( + bool critical, + bool isLongLength, + byte[] data) + : base(SignatureSubpacketTag.Exportable, critical, isLongLength, data) + { + } + + public Exportable( + bool critical, + bool isExportable) + : base(SignatureSubpacketTag.Exportable, critical, false, BooleanToByteArray(isExportable)) + { + } + + public bool IsExportable() + { + return data[0] != 0; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/Exportable.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/Exportable.cs.meta new file mode 100644 index 0000000..e62132b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/Exportable.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 89c49ae44721cdf45a3fd2818f1293c6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/Features.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/Features.cs new file mode 100644 index 0000000..135d7f5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/Features.cs @@ -0,0 +1,65 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Bcpg.Sig +{ + /** + * packet giving signature expiration time. + */ + public class Features + : SignatureSubpacket + { + /** Identifier for the Modification Detection (packets 18 and 19) */ + public static readonly byte FEATURE_MODIFICATION_DETECTION = 0x01; + /** Identifier for the AEAD Encrypted Data Packet (packet 20) and version 5 + Symmetric-Key Encrypted Session Key Packets (packet 3) */ + public static readonly byte FEATURE_AEAD_ENCRYPTED_DATA = 0x02; + /** Identifier for the Version 5 Public-Key Packet format and corresponding new + fingerprint format */ + public static readonly byte FEATURE_VERSION_5_PUBLIC_KEY = 0x04; + + private static byte[] featureToByteArray(byte feature) + { + byte[] data = new byte[1]; + data[0] = feature; + return data; + } + + public Features( + bool critical, + bool isLongLength, + byte[] data): base(SignatureSubpacketTag.Features, critical, isLongLength, data) + { + + } + + + public Features(bool critical, byte features): this(critical, false, featureToByteArray(features)) + { + + } + + + public Features(bool critical, int features): this(critical, false, featureToByteArray((byte)features)) + { + + } + + /** + * Returns if modification detection is supported. + */ + public bool SupportsModificationDetection + { + get { return SupportsFeature(FEATURE_MODIFICATION_DETECTION); } + } + + /** + * Returns if a particular feature is supported. + */ + public bool SupportsFeature(byte feature) + { + return (data[0] & feature) != 0; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/Features.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/Features.cs.meta new file mode 100644 index 0000000..6ada646 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/Features.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9064294c48d9d664fab08527257a6942 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/IssuerKeyId.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/IssuerKeyId.cs new file mode 100644 index 0000000..627ea3e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/IssuerKeyId.cs @@ -0,0 +1,62 @@ +using System; + + + +namespace Org.BouncyCastle.Bcpg.Sig +{ + /** + * packet giving signature creation time. + */ + public class IssuerKeyId + : SignatureSubpacket + { + protected static byte[] KeyIdToBytes( + long keyId) + { + byte[] data = new byte[8]; + + data[0] = (byte)(keyId >> 56); + data[1] = (byte)(keyId >> 48); + data[2] = (byte)(keyId >> 40); + data[3] = (byte)(keyId >> 32); + data[4] = (byte)(keyId >> 24); + data[5] = (byte)(keyId >> 16); + data[6] = (byte)(keyId >> 8); + data[7] = (byte)keyId; + + return data; + } + + public IssuerKeyId( + bool critical, + bool isLongLength, + byte[] data) + : base(SignatureSubpacketTag.IssuerKeyId, critical, isLongLength, data) + { + } + + public IssuerKeyId( + bool critical, + long keyId) + : base(SignatureSubpacketTag.IssuerKeyId, critical, false, KeyIdToBytes(keyId)) + { + } + + public long KeyId + { + get + { + long keyId = ((long)(data[0] & 0xff) << 56) + | ((long)(data[1] & 0xff) << 48) + | ((long)(data[2] & 0xff) << 40) + | ((long)(data[3] & 0xff) << 32) + | ((long)(data[4] & 0xff) << 24) + | ((long)(data[5] & 0xff) << 16) + | ((long)(data[6] & 0xff) << 8) + | ((long)data[7] & 0xff); + + return keyId; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/IssuerKeyId.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/IssuerKeyId.cs.meta new file mode 100644 index 0000000..06494e4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/IssuerKeyId.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 87b4b0a40ad5c814baca0263f4a298bf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/KeyExpirationTime.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/KeyExpirationTime.cs new file mode 100644 index 0000000..dfd3e76 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/KeyExpirationTime.cs @@ -0,0 +1,55 @@ +using System; + +namespace Org.BouncyCastle.Bcpg.Sig +{ + /** + * packet giving time after creation at which the key expires. + */ + public class KeyExpirationTime + : SignatureSubpacket + { + protected static byte[] TimeToBytes( + long t) + { + byte[] data = new byte[4]; + + data[0] = (byte)(t >> 24); + data[1] = (byte)(t >> 16); + data[2] = (byte)(t >> 8); + data[3] = (byte)t; + + return data; + } + + public KeyExpirationTime( + bool critical, + bool isLongLength, + byte[] data) + : base(SignatureSubpacketTag.KeyExpireTime, critical, isLongLength, data) + { + } + + public KeyExpirationTime( + bool critical, + long seconds) + : base(SignatureSubpacketTag.KeyExpireTime, critical, false, TimeToBytes(seconds)) + { + } + + /** + * Return the number of seconds after creation time a key is valid for. + * + * @return second count for key validity. + */ + public long Time + { + get + { + long time = ((long)(data[0] & 0xff) << 24) | ((long)(data[1] & 0xff) << 16) + | ((long)(data[2] & 0xff) << 8) | ((long)data[3] & 0xff); + + return time; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/KeyExpirationTime.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/KeyExpirationTime.cs.meta new file mode 100644 index 0000000..750c13e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/KeyExpirationTime.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a1aa756203001664a93a844dbe6547d7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/KeyFlags.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/KeyFlags.cs new file mode 100644 index 0000000..5b5d85a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/KeyFlags.cs @@ -0,0 +1,75 @@ +using System; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Bcpg.Sig +{ + /** + * Packet holding the key flag values. + */ + public class KeyFlags + : SignatureSubpacket + { + public const int CertifyOther = 0x01; + public const int SignData = 0x02; + public const int EncryptComms = 0x04; + public const int EncryptStorage = 0x08; + public const int Split = 0x10; + public const int Authentication = 0x20; + public const int Shared = 0x80; + + private static byte[] IntToByteArray( + int v) + { + byte[] tmp = new byte[4]; + int size = 0; + + for (int i = 0; i != 4; i++) + { + tmp[i] = (byte)(v >> (i * 8)); + if (tmp[i] != 0) + { + size = i; + } + } + + byte[] data = new byte[size + 1]; + Array.Copy(tmp, 0, data, 0, data.Length); + return data; + } + + public KeyFlags( + bool critical, + bool isLongLength, + byte[] data) + : base(SignatureSubpacketTag.KeyFlags, critical, isLongLength, data) + { + } + + public KeyFlags( + bool critical, + int flags) + : base(SignatureSubpacketTag.KeyFlags, critical, false, IntToByteArray(flags)) + { + } + + /// + /// Return the flag values contained in the first 4 octets (note: at the moment + /// the standard only uses the first one). + /// + public int Flags + { + get + { + int flags = 0; + + for (int i = 0; i != data.Length; i++) + { + flags |= (data[i] & 0xff) << (i * 8); + } + + return flags; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/KeyFlags.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/KeyFlags.cs.meta new file mode 100644 index 0000000..0e0855b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/KeyFlags.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 26c3036a9750f5945aa47d5b300b6158 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/NotationData.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/NotationData.cs new file mode 100644 index 0000000..9ac6f89 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/NotationData.cs @@ -0,0 +1,113 @@ +using System; +using System.IO; +using System.Text; + +namespace Org.BouncyCastle.Bcpg.Sig +{ + /** + * Class provided a NotationData object according to + * RFC2440, Chapter 5.2.3.15. Notation Data + */ + public class NotationData + : SignatureSubpacket + { + public const int HeaderFlagLength = 4; + public const int HeaderNameLength = 2; + public const int HeaderValueLength = 2; + + public NotationData( + bool critical, + bool isLongLength, + byte[] data) + : base(SignatureSubpacketTag.NotationData, critical, isLongLength, data) + { + } + + public NotationData( + bool critical, + bool humanReadable, + string notationName, + string notationValue) + : base(SignatureSubpacketTag.NotationData, critical, false, + CreateData(humanReadable, notationName, notationValue)) + { + } + + private static byte[] CreateData( + bool humanReadable, + string notationName, + string notationValue) + { + MemoryStream os = new MemoryStream(); + + // (4 octets of flags, 2 octets of name length (M), + // 2 octets of value length (N), + // M octets of name data, + // N octets of value data) + + // flags + os.WriteByte(humanReadable ? (byte)0x80 : (byte)0x00); + os.WriteByte(0x0); + os.WriteByte(0x0); + os.WriteByte(0x0); + + byte[] nameData, valueData = null; + int nameLength, valueLength; + + nameData = Encoding.UTF8.GetBytes(notationName); + nameLength = System.Math.Min(nameData.Length, 0xFF); + + valueData = Encoding.UTF8.GetBytes(notationValue); + valueLength = System.Math.Min(valueData.Length, 0xFF); + + // name length + os.WriteByte((byte)(nameLength >> 8)); + os.WriteByte((byte)(nameLength >> 0)); + + // value length + os.WriteByte((byte)(valueLength >> 8)); + os.WriteByte((byte)(valueLength >> 0)); + + // name + os.Write(nameData, 0, nameLength); + + // value + os.Write(valueData, 0, valueLength); + + return os.ToArray(); + } + + public bool IsHumanReadable + { + get { return data[0] == (byte)0x80; } + } + + public string GetNotationName() + { + int nameLength = ((data[HeaderFlagLength] << 8) + (data[HeaderFlagLength + 1] << 0)); + int namePos = HeaderFlagLength + HeaderNameLength + HeaderValueLength; + + return Encoding.UTF8.GetString(data, namePos, nameLength); + } + + public string GetNotationValue() + { + int nameLength = ((data[HeaderFlagLength] << 8) + (data[HeaderFlagLength + 1] << 0)); + int valueLength = ((data[HeaderFlagLength + HeaderNameLength] << 8) + (data[HeaderFlagLength + HeaderNameLength + 1] << 0)); + int valuePos = HeaderFlagLength + HeaderNameLength + HeaderValueLength + nameLength; + + return Encoding.UTF8.GetString(data, valuePos, valueLength); + } + + public byte[] GetNotationValueBytes() + { + int nameLength = ((data[HeaderFlagLength] << 8) + (data[HeaderFlagLength + 1] << 0)); + int valueLength = ((data[HeaderFlagLength + HeaderNameLength] << 8) + (data[HeaderFlagLength + HeaderNameLength + 1] << 0)); + int valuePos = HeaderFlagLength + HeaderNameLength + HeaderValueLength + nameLength; + + byte[] bytes = new byte[valueLength]; + Array.Copy(data, valuePos, bytes, 0, valueLength); + return bytes; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/NotationData.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/NotationData.cs.meta new file mode 100644 index 0000000..c929ecf --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/NotationData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fdac6977e7a02024892ca5f8d149621a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/PreferredAlgorithms.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/PreferredAlgorithms.cs new file mode 100644 index 0000000..9514bed --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/PreferredAlgorithms.cs @@ -0,0 +1,53 @@ +using System; + +namespace Org.BouncyCastle.Bcpg.Sig +{ + /** + * packet giving signature creation time. + */ + public class PreferredAlgorithms + : SignatureSubpacket + { + private static byte[] IntToByteArray( + int[] v) + { + byte[] data = new byte[v.Length]; + + for (int i = 0; i != v.Length; i++) + { + data[i] = (byte)v[i]; + } + + return data; + } + + public PreferredAlgorithms( + SignatureSubpacketTag type, + bool critical, + bool isLongLength, + byte[] data) + : base(type, critical, isLongLength, data) + { + } + + public PreferredAlgorithms( + SignatureSubpacketTag type, + bool critical, + int[] preferences) + : base(type, critical, false, IntToByteArray(preferences)) + { + } + + public int[] GetPreferences() + { + int[] v = new int[data.Length]; + + for (int i = 0; i != v.Length; i++) + { + v[i] = data[i] & 0xff; + } + + return v; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/PreferredAlgorithms.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/PreferredAlgorithms.cs.meta new file mode 100644 index 0000000..ec38783 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/PreferredAlgorithms.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2936fa7de517ff3489ef49c0e76b94ea +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/PrimaryUserId.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/PrimaryUserId.cs new file mode 100644 index 0000000..1f16f40 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/PrimaryUserId.cs @@ -0,0 +1,47 @@ +using System; + +namespace Org.BouncyCastle.Bcpg.Sig +{ + /** + * packet giving whether or not the signature is signed using the primary user ID for the key. + */ + public class PrimaryUserId + : SignatureSubpacket + { + private static byte[] BooleanToByteArray( + bool val) + { + byte[] data = new byte[1]; + + if (val) + { + data[0] = 1; + return data; + } + else + { + return data; + } + } + + public PrimaryUserId( + bool critical, + bool isLongLength, + byte[] data) + : base(SignatureSubpacketTag.PrimaryUserId, critical, isLongLength, data) + { + } + + public PrimaryUserId( + bool critical, + bool isPrimaryUserId) + : base(SignatureSubpacketTag.PrimaryUserId, critical, false, BooleanToByteArray(isPrimaryUserId)) + { + } + + public bool IsPrimaryUserId() + { + return data[0] != 0; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/PrimaryUserId.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/PrimaryUserId.cs.meta new file mode 100644 index 0000000..107af54 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/PrimaryUserId.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e7bbea2a260d6e94aafa7640fa7a1806 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/Revocable.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/Revocable.cs new file mode 100644 index 0000000..7aa9139 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/Revocable.cs @@ -0,0 +1,47 @@ +using System; + +namespace Org.BouncyCastle.Bcpg.Sig +{ + /** + * packet giving whether or not is revocable. + */ + public class Revocable + : SignatureSubpacket + { + private static byte[] BooleanToByteArray( + bool value) + { + byte[] data = new byte[1]; + + if (value) + { + data[0] = 1; + return data; + } + else + { + return data; + } + } + + public Revocable( + bool critical, + bool isLongLength, + byte[] data) + : base(SignatureSubpacketTag.Revocable, critical, isLongLength, data) + { + } + + public Revocable( + bool critical, + bool isRevocable) + : base(SignatureSubpacketTag.Revocable, critical, false, BooleanToByteArray(isRevocable)) + { + } + + public bool IsRevocable() + { + return data[0] != 0; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/Revocable.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/Revocable.cs.meta new file mode 100644 index 0000000..27ea58b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/Revocable.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 10d9be2cac3b2334ab4b8926659276b9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/RevocationKey.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/RevocationKey.cs new file mode 100644 index 0000000..11467d2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/RevocationKey.cs @@ -0,0 +1,63 @@ +using System; +using System.Text; + +namespace Org.BouncyCastle.Bcpg +{ + /// + /// Represents revocation key OpenPGP signature sub packet. + /// + public class RevocationKey + : SignatureSubpacket + { + // 1 octet of class, + // 1 octet of public-key algorithm ID, + // 20 octets of fingerprint + public RevocationKey( + bool isCritical, + bool isLongLength, + byte[] data) + : base(SignatureSubpacketTag.RevocationKey, isCritical, isLongLength, data) + { + } + + public RevocationKey( + bool isCritical, + RevocationKeyTag signatureClass, + PublicKeyAlgorithmTag keyAlgorithm, + byte[] fingerprint) + : base(SignatureSubpacketTag.RevocationKey, isCritical, false, + CreateData(signatureClass, keyAlgorithm, fingerprint)) + { + } + + private static byte[] CreateData( + RevocationKeyTag signatureClass, + PublicKeyAlgorithmTag keyAlgorithm, + byte[] fingerprint) + { + byte[] data = new byte[2 + fingerprint.Length]; + data[0] = (byte)signatureClass; + data[1] = (byte)keyAlgorithm; + Array.Copy(fingerprint, 0, data, 2, fingerprint.Length); + return data; + } + + public virtual RevocationKeyTag SignatureClass + { + get { return (RevocationKeyTag)this.GetData()[0]; } + } + + public virtual PublicKeyAlgorithmTag Algorithm + { + get { return (PublicKeyAlgorithmTag)this.GetData()[1]; } + } + + public virtual byte[] GetFingerprint() + { + byte[] data = this.GetData(); + byte[] fingerprint = new byte[data.Length - 2]; + Array.Copy(data, 2, fingerprint, 0, fingerprint.Length); + return fingerprint; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/RevocationKey.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/RevocationKey.cs.meta new file mode 100644 index 0000000..cf5a8a5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/RevocationKey.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9baa23cb94e7d8547b3ed72725b0badc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/RevocationKeyTags.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/RevocationKeyTags.cs new file mode 100644 index 0000000..d76d1dc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/RevocationKeyTags.cs @@ -0,0 +1,9 @@ +namespace Org.BouncyCastle.Bcpg +{ + public enum RevocationKeyTag + : byte + { + ClassDefault = 0x80, + ClassSensitive = 0x40 + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/RevocationKeyTags.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/RevocationKeyTags.cs.meta new file mode 100644 index 0000000..ea2ab50 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/RevocationKeyTags.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c8dc6d6124471f34585bd4c954436aef +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/RevocationReason.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/RevocationReason.cs new file mode 100644 index 0000000..42afd5f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/RevocationReason.cs @@ -0,0 +1,59 @@ +using System; +using System.Text; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Bcpg +{ + /// + /// Represents revocation reason OpenPGP signature sub packet. + /// + public class RevocationReason + : SignatureSubpacket + { + public RevocationReason(bool isCritical, bool isLongLength, byte[] data) + : base(SignatureSubpacketTag.RevocationReason, isCritical, isLongLength, data) + { + } + + public RevocationReason( + bool isCritical, + RevocationReasonTag reason, + string description) + : base(SignatureSubpacketTag.RevocationReason, isCritical, false, CreateData(reason, description)) + { + } + + private static byte[] CreateData( + RevocationReasonTag reason, + string description) + { + byte[] descriptionBytes = Strings.ToUtf8ByteArray(description); + byte[] data = new byte[1 + descriptionBytes.Length]; + + data[0] = (byte)reason; + Array.Copy(descriptionBytes, 0, data, 1, descriptionBytes.Length); + + return data; + } + + public virtual RevocationReasonTag GetRevocationReason() + { + return (RevocationReasonTag)GetData()[0]; + } + + public virtual string GetRevocationDescription() + { + byte[] data = GetData(); + if (data.Length == 1) + { + return string.Empty; + } + + byte[] description = new byte[data.Length - 1]; + Array.Copy(data, 1, description, 0, description.Length); + + return Strings.FromUtf8ByteArray(description); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/RevocationReason.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/RevocationReason.cs.meta new file mode 100644 index 0000000..b5d2007 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/RevocationReason.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 43eae953add32c44b88ac1734506c6d2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/RevocationReasonTags.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/RevocationReasonTags.cs new file mode 100644 index 0000000..524a58c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/RevocationReasonTags.cs @@ -0,0 +1,14 @@ +namespace Org.BouncyCastle.Bcpg +{ + public enum RevocationReasonTag + : byte + { + NoReason = 0, // No reason specified (key revocations or cert revocations) + KeySuperseded = 1, // Key is superseded (key revocations) + KeyCompromised = 2, // Key material has been compromised (key revocations) + KeyRetired = 3, // Key is retired and no longer used (key revocations) + UserNoLongerValid = 32, // User ID information is no longer valid (cert revocations) + + // 100-110 - Private Use + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/RevocationReasonTags.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/RevocationReasonTags.cs.meta new file mode 100644 index 0000000..c155359 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/RevocationReasonTags.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ec9ff7b5ed3dc6f458f5fceee4ce367f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/SignatureCreationTime.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/SignatureCreationTime.cs new file mode 100644 index 0000000..d172e5d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/SignatureCreationTime.cs @@ -0,0 +1,51 @@ +using System; + +using Org.BouncyCastle.Utilities.Date; + +namespace Org.BouncyCastle.Bcpg.Sig +{ + /** + * packet giving signature creation time. + */ + public class SignatureCreationTime + : SignatureSubpacket + { + protected static byte[] TimeToBytes( + DateTime time) + { + long t = DateTimeUtilities.DateTimeToUnixMs(time) / 1000L; + byte[] data = new byte[4]; + data[0] = (byte)(t >> 24); + data[1] = (byte)(t >> 16); + data[2] = (byte)(t >> 8); + data[3] = (byte)t; + return data; + } + + public SignatureCreationTime( + bool critical, + bool isLongLength, + byte[] data) + : base(SignatureSubpacketTag.CreationTime, critical, isLongLength, data) + { + } + + public SignatureCreationTime( + bool critical, + DateTime date) + : base(SignatureSubpacketTag.CreationTime, critical, false, TimeToBytes(date)) + { + } + + public DateTime GetTime() + { + long time = (long)( + ((uint)data[0] << 24) + | ((uint)data[1] << 16) + | ((uint)data[2] << 8) + | ((uint)data[3]) + ); + return DateTimeUtilities.UnixMsToDateTime(time * 1000L); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/SignatureCreationTime.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/SignatureCreationTime.cs.meta new file mode 100644 index 0000000..6385cee --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/SignatureCreationTime.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 05448759c4d5d63419a3e9093ec40609 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/SignatureExpirationTime.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/SignatureExpirationTime.cs new file mode 100644 index 0000000..24f0a9f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/SignatureExpirationTime.cs @@ -0,0 +1,51 @@ +using System; + +namespace Org.BouncyCastle.Bcpg.Sig +{ + /** + * packet giving signature expiration time. + */ + public class SignatureExpirationTime + : SignatureSubpacket + { + protected static byte[] TimeToBytes( + long t) + { + byte[] data = new byte[4]; + data[0] = (byte)(t >> 24); + data[1] = (byte)(t >> 16); + data[2] = (byte)(t >> 8); + data[3] = (byte)t; + return data; + } + + public SignatureExpirationTime( + bool critical, + bool isLongLength, + byte[] data) + : base(SignatureSubpacketTag.ExpireTime, critical, isLongLength, data) + { + } + + public SignatureExpirationTime( + bool critical, + long seconds) + : base(SignatureSubpacketTag.ExpireTime, critical, false, TimeToBytes(seconds)) + { + } + + /** + * return time in seconds before signature expires after creation time. + */ + public long Time + { + get + { + long time = ((long)(data[0] & 0xff) << 24) | ((long)(data[1] & 0xff) << 16) + | ((long)(data[2] & 0xff) << 8) | ((long)data[3] & 0xff); + + return time; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/SignatureExpirationTime.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/SignatureExpirationTime.cs.meta new file mode 100644 index 0000000..b8275c2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/SignatureExpirationTime.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d757fef04fafd224dbd01582183a3498 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/SignerUserId.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/SignerUserId.cs new file mode 100644 index 0000000..8ab62ed --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/SignerUserId.cs @@ -0,0 +1,53 @@ +using System; + + + +namespace Org.BouncyCastle.Bcpg.Sig +{ + /** + * packet giving the User ID of the signer. + */ + public class SignerUserId + : SignatureSubpacket + { + private static byte[] UserIdToBytes( + string id) + { + byte[] idData = new byte[id.Length]; + + for (int i = 0; i != id.Length; i++) + { + idData[i] = (byte)id[i]; + } + + return idData; + } + + public SignerUserId( + bool critical, + bool isLongLength, + byte[] data) + : base(SignatureSubpacketTag.SignerUserId, critical, isLongLength, data) + { + } + + public SignerUserId( + bool critical, + string userId) + : base(SignatureSubpacketTag.SignerUserId, critical, false, UserIdToBytes(userId)) + { + } + + public string GetId() + { + char[] chars = new char[data.Length]; + + for (int i = 0; i != chars.Length; i++) + { + chars[i] = (char)(data[i] & 0xff); + } + + return new string(chars); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/SignerUserId.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/SignerUserId.cs.meta new file mode 100644 index 0000000..6bd104e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/SignerUserId.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 712320e3faee22b438810361e41b3d92 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/TrustSignature.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/TrustSignature.cs new file mode 100644 index 0000000..9145882 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/TrustSignature.cs @@ -0,0 +1,44 @@ +using System; + +namespace Org.BouncyCastle.Bcpg.Sig +{ + /** + * packet giving trust. + */ + public class TrustSignature + : SignatureSubpacket + { + private static byte[] IntToByteArray( + int v1, + int v2) + { + return new byte[]{ (byte)v1, (byte)v2 }; + } + + public TrustSignature( + bool critical, + bool isLongLength, + byte[] data) + : base(SignatureSubpacketTag.TrustSig, critical, isLongLength, data) + { + } + + public TrustSignature( + bool critical, + int depth, + int trustAmount) + : base(SignatureSubpacketTag.TrustSig, critical, false, IntToByteArray(depth, trustAmount)) + { + } + + public int Depth + { + get { return data[0] & 0xff; } + } + + public int TrustAmount + { + get { return data[1] & 0xff; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/TrustSignature.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/TrustSignature.cs.meta new file mode 100644 index 0000000..371b4b3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/bcpg/sig/TrustSignature.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b48d0cb3da1337542a7ee7dd29d1a84a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp.meta new file mode 100644 index 0000000..f27831f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 6e84455d2467c9647a9dcf08f1767d2b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/CertificateConfirmationContent.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/CertificateConfirmationContent.cs new file mode 100644 index 0000000..ad46ca0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/CertificateConfirmationContent.cs @@ -0,0 +1,42 @@ +using System; + +using Org.BouncyCastle.Asn1.Cmp; +using Org.BouncyCastle.Cms; + +namespace Org.BouncyCastle.Cmp +{ + public class CertificateConfirmationContent + { + private readonly DefaultDigestAlgorithmIdentifierFinder digestAlgFinder; + private readonly CertConfirmContent content; + + public CertificateConfirmationContent(CertConfirmContent content) + { + this.content = content; + } + + public CertificateConfirmationContent(CertConfirmContent content, + DefaultDigestAlgorithmIdentifierFinder digestAlgFinder) + { + this.content = content; + this.digestAlgFinder = digestAlgFinder; + } + + public CertConfirmContent ToAsn1Structure() + { + return content; + } + + public CertificateStatus[] GetStatusMessages() + { + CertStatus[] statusArray = content.ToCertStatusArray(); + CertificateStatus[] ret = new CertificateStatus[statusArray.Length]; + for (int i = 0; i != ret.Length; i++) + { + ret[i] = new CertificateStatus(digestAlgFinder, statusArray[i]); + } + + return ret; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/CertificateConfirmationContent.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/CertificateConfirmationContent.cs.meta new file mode 100644 index 0000000..349366e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/CertificateConfirmationContent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4956a89f6f8f8d54a82eda93c65dfb57 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/CertificateConfirmationContentBuilder.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/CertificateConfirmationContentBuilder.cs new file mode 100644 index 0000000..611fa44 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/CertificateConfirmationContentBuilder.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cmp; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Cms; +using Org.BouncyCastle.Crypto.IO; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.Cmp +{ + public class CertificateConfirmationContentBuilder + { + private static readonly DefaultSignatureAlgorithmIdentifierFinder sigAlgFinder = new DefaultSignatureAlgorithmIdentifierFinder(); + + private readonly DefaultDigestAlgorithmIdentifierFinder digestAlgFinder; + private readonly IList acceptedCerts = Platform.CreateArrayList(); + private readonly IList acceptedReqIds = Platform.CreateArrayList(); + + public CertificateConfirmationContentBuilder() + : this(new DefaultDigestAlgorithmIdentifierFinder()) + { + } + + public CertificateConfirmationContentBuilder(DefaultDigestAlgorithmIdentifierFinder digestAlgFinder) + { + this.digestAlgFinder = digestAlgFinder; + } + + public CertificateConfirmationContentBuilder AddAcceptedCertificate(X509Certificate certHolder, + BigInteger certReqId) + { + acceptedCerts.Add(certHolder); + acceptedReqIds.Add(certReqId); + return this; + } + + public CertificateConfirmationContent Build() + { + Asn1EncodableVector v = new Asn1EncodableVector(); + for (int i = 0; i != acceptedCerts.Count; i++) + { + X509Certificate cert = (X509Certificate)acceptedCerts[i]; + BigInteger reqId = (BigInteger)acceptedReqIds[i]; + + + AlgorithmIdentifier algorithmIdentifier = sigAlgFinder.Find(cert.SigAlgName); + + AlgorithmIdentifier digAlg = digestAlgFinder.find(algorithmIdentifier); + if (null == digAlg) + throw new CmpException("cannot find algorithm for digest from signature"); + + byte[] digest = DigestUtilities.CalculateDigest(digAlg.Algorithm, cert.GetEncoded()); + + v.Add(new CertStatus(digest, reqId)); + } + + return new CertificateConfirmationContent(CertConfirmContent.GetInstance(new DerSequence(v)), + digestAlgFinder); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/CertificateConfirmationContentBuilder.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/CertificateConfirmationContentBuilder.cs.meta new file mode 100644 index 0000000..f593cb9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/CertificateConfirmationContentBuilder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c709ea07221e10546adf2f7fa480e93a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/CertificateStatus.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/CertificateStatus.cs new file mode 100644 index 0000000..0f1d9af --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/CertificateStatus.cs @@ -0,0 +1,48 @@ +using System; + +using Org.BouncyCastle.Asn1.Cmp; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Cms; +using Org.BouncyCastle.Crypto.IO; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.Cmp +{ + public class CertificateStatus + { + private static readonly DefaultSignatureAlgorithmIdentifierFinder sigAlgFinder = new DefaultSignatureAlgorithmIdentifierFinder(); + + private readonly DefaultDigestAlgorithmIdentifierFinder digestAlgFinder; + private readonly CertStatus certStatus; + + public CertificateStatus(DefaultDigestAlgorithmIdentifierFinder digestAlgFinder, CertStatus certStatus) + { + this.digestAlgFinder = digestAlgFinder; + this.certStatus = certStatus; + } + + public PkiStatusInfo PkiStatusInfo + { + get { return certStatus.StatusInfo; } + } + + public BigInteger CertRequestId + { + get { return certStatus.CertReqID.Value; } + } + + public bool IsVerified(X509Certificate cert) + { + AlgorithmIdentifier digAlg = digestAlgFinder.find(sigAlgFinder.Find(cert.SigAlgName)); + if (null == digAlg) + throw new CmpException("cannot find algorithm for digest from signature " + cert.SigAlgName); + + byte[] digest = DigestUtilities.CalculateDigest(digAlg.Algorithm, cert.GetEncoded()); + + return Arrays.ConstantTimeAreEqual(certStatus.CertHash.GetOctets(), digest); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/CertificateStatus.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/CertificateStatus.cs.meta new file mode 100644 index 0000000..a6fd264 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/CertificateStatus.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 87baead16b6c4654eaf3b6efda05fc63 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/CmpException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/CmpException.cs new file mode 100644 index 0000000..6594e8f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/CmpException.cs @@ -0,0 +1,22 @@ +using System; + +namespace Org.BouncyCastle.Cmp +{ + public class CmpException + : Exception + { + public CmpException() + { + } + + public CmpException(string message) + : base(message) + { + } + + public CmpException(string message, Exception innerException) + : base(message, innerException) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/CmpException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/CmpException.cs.meta new file mode 100644 index 0000000..44a86ba --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/CmpException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cb190c0537821d74a88bc96d7981d2ef +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/GeneralPkiMessage.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/GeneralPkiMessage.cs new file mode 100644 index 0000000..9b12ee7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/GeneralPkiMessage.cs @@ -0,0 +1,59 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cmp; + +namespace Org.BouncyCastle.Cmp +{ + public class GeneralPkiMessage + { + private readonly PkiMessage pkiMessage; + + private static PkiMessage ParseBytes(byte[] encoding) + { + return PkiMessage.GetInstance(Asn1Object.FromByteArray(encoding)); + } + + /// + /// Wrap a PKIMessage ASN.1 structure. + /// + /// PKI message. + public GeneralPkiMessage(PkiMessage pkiMessage) + { + this.pkiMessage = pkiMessage; + } + + /// + /// Create a PKIMessage from the passed in bytes. + /// + /// BER/DER encoding of the PKIMessage + public GeneralPkiMessage(byte[] encoding) + : this(ParseBytes(encoding)) + { + } + + public PkiHeader Header + { + get { return pkiMessage.Header; } + } + + public PkiBody Body + { + get { return pkiMessage.Body; } + } + + /// + /// Return true if this message has protection bits on it. A return value of true + /// indicates the message can be used to construct a ProtectedPKIMessage. + /// + public bool HasProtection + { + get { return pkiMessage.Protection != null; } + } + + public PkiMessage ToAsn1Structure() + { + return pkiMessage; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/GeneralPkiMessage.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/GeneralPkiMessage.cs.meta new file mode 100644 index 0000000..5a257e2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/GeneralPkiMessage.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 764f51b241d194845b2791ab0fb432a5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/ProtectedPkiMessage.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/ProtectedPkiMessage.cs new file mode 100644 index 0000000..770fe54 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/ProtectedPkiMessage.cs @@ -0,0 +1,149 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cmp; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crmf; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.Cmp +{ + /// + /// Wrapper for a PKIMessage with protection attached to it. + /// + public class ProtectedPkiMessage + { + private readonly PkiMessage pkiMessage; + + /// + /// Wrap a general message. + /// + /// If the general message does not have protection. + /// The General message + public ProtectedPkiMessage(GeneralPkiMessage pkiMessage) + { + if (!pkiMessage.HasProtection) + throw new ArgumentException("pki message not protected"); + + this.pkiMessage = pkiMessage.ToAsn1Structure(); + } + + /// + /// Wrap a PKI message. + /// + /// If the PKI message does not have protection. + /// The PKI message + public ProtectedPkiMessage(PkiMessage pkiMessage) + { + if (null == pkiMessage.Header.ProtectionAlg) + throw new ArgumentException("pki message not protected"); + + this.pkiMessage = pkiMessage; + } + + /// + /// Message header + /// + public PkiHeader Header + { + get { return pkiMessage.Header; } + } + + /// + /// Message Body + /// + public PkiBody Body + { + get { return pkiMessage.Body; } + } + + /// + /// Return the underlying ASN.1 structure contained in this object. + /// + /// PKI Message structure + public PkiMessage ToAsn1Message() + { + return pkiMessage; + } + + /// + /// Determine whether the message is protected by a password based MAC. Use verify(PKMACBuilder, char[]) + /// to verify the message if this method returns true. + /// + /// true if protection MAC PBE based, false otherwise. + public bool HasPasswordBasedMacProtected + { + get { return Header.ProtectionAlg.Algorithm.Equals(CmpObjectIdentifiers.passwordBasedMac); } + } + + /// + /// Return the extra certificates associated with this message. + /// + /// an array of extra certificates, zero length if none present. + public X509Certificate[] GetCertificates() + { + CmpCertificate[] certs = pkiMessage.GetExtraCerts(); + if (null == certs) + return new X509Certificate[0]; + + X509Certificate[] res = new X509Certificate[certs.Length]; + for (int t = 0; t < certs.Length; t++) + { + res[t] = new X509Certificate(X509CertificateStructure.GetInstance(certs[t].GetEncoded())); + } + + return res; + } + + /// + /// Verify a message with a public key based signature attached. + /// + /// a factory of signature verifiers. + /// true if the provider is able to create a verifier that validates the signature, false otherwise. + public bool Verify(IVerifierFactory verifierFactory) + { + IStreamCalculator streamCalculator = verifierFactory.CreateCalculator(); + + IVerifier result = (IVerifier)Process(streamCalculator); + + return result.IsVerified(pkiMessage.Protection.GetBytes()); + } + + private object Process(IStreamCalculator streamCalculator) + { + Asn1EncodableVector avec = new Asn1EncodableVector(); + avec.Add(pkiMessage.Header); + avec.Add(pkiMessage.Body); + byte[] enc = new DerSequence(avec).GetDerEncoded(); + + streamCalculator.Stream.Write(enc, 0, enc.Length); + streamCalculator.Stream.Flush(); + Platform.Dispose(streamCalculator.Stream); + + return streamCalculator.GetResult(); + } + + /// + /// Verify a message with password based MAC protection. + /// + /// MAC builder that can be used to construct the appropriate MacCalculator + /// the MAC password + /// true if the passed in password and MAC builder verify the message, false otherwise. + /// if algorithm not MAC based, or an exception is thrown verifying the MAC. + public bool Verify(PKMacBuilder pkMacBuilder, char[] password) + { + if (!CmpObjectIdentifiers.passwordBasedMac.Equals(pkiMessage.Header.ProtectionAlg.Algorithm)) + throw new InvalidOperationException("protection algorithm is not mac based"); + + PbmParameter parameter = PbmParameter.GetInstance(pkiMessage.Header.ProtectionAlg.Parameters); + + pkMacBuilder.SetParameters(parameter); + + IBlockResult result = (IBlockResult)Process(pkMacBuilder.Build(password).CreateCalculator()); + + return Arrays.ConstantTimeAreEqual(result.Collect(), this.pkiMessage.Protection.GetBytes()); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/ProtectedPkiMessage.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/ProtectedPkiMessage.cs.meta new file mode 100644 index 0000000..3b59c12 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/ProtectedPkiMessage.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e7ea8382cd2748a4e9409a2d8dd619e7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/ProtectedPkiMessageBuilder.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/ProtectedPkiMessageBuilder.cs new file mode 100644 index 0000000..5939e92 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/ProtectedPkiMessageBuilder.cs @@ -0,0 +1,178 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cmp; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Operators; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.Cmp +{ + public class ProtectedPkiMessageBuilder + { + private PkiHeaderBuilder hdrBuilBuilder; + private PkiBody body; + private IList generalInfos = Platform.CreateArrayList(); + private IList extraCerts = Platform.CreateArrayList(); + + public ProtectedPkiMessageBuilder(GeneralName sender, GeneralName recipient) + : this(PkiHeader.CMP_2000, sender, recipient) + { + } + + public ProtectedPkiMessageBuilder(int pvno, GeneralName sender, GeneralName recipient) + { + hdrBuilBuilder = new PkiHeaderBuilder(pvno, sender, recipient); + } + + public ProtectedPkiMessageBuilder SetTransactionId(byte[] tid) + { + hdrBuilBuilder.SetTransactionID(tid); + return this; + } + + public ProtectedPkiMessageBuilder SetFreeText(PkiFreeText freeText) + { + hdrBuilBuilder.SetFreeText(freeText); + return this; + } + + public ProtectedPkiMessageBuilder AddGeneralInfo(InfoTypeAndValue genInfo) + { + generalInfos.Add(genInfo); + return this; + } + + public ProtectedPkiMessageBuilder SetMessageTime(DerGeneralizedTime generalizedTime) + { + hdrBuilBuilder.SetMessageTime(generalizedTime); + return this; + } + + public ProtectedPkiMessageBuilder SetRecipKID(byte[] id) + { + hdrBuilBuilder.SetRecipKID(id); + return this; + } + + public ProtectedPkiMessageBuilder SetRecipNonce(byte[] nonce) + { + hdrBuilBuilder.SetRecipNonce(nonce); + return this; + } + + public ProtectedPkiMessageBuilder SetSenderKID(byte[] id) + { + hdrBuilBuilder.SetSenderKID(id); + return this; + } + + public ProtectedPkiMessageBuilder SetSenderNonce(byte[] nonce) + { + hdrBuilBuilder.SetSenderNonce(nonce); + return this; + } + + public ProtectedPkiMessageBuilder SetBody(PkiBody body) + { + this.body = body; + return this; + } + + public ProtectedPkiMessageBuilder AddCmpCertificate(X509Certificate certificate) + { + extraCerts.Add(certificate); + return this; + } + + public ProtectedPkiMessage Build(ISignatureFactory signatureFactory) + { + if (null == body) + throw new InvalidOperationException("body must be set before building"); + + IStreamCalculator calculator = signatureFactory.CreateCalculator(); + + if (!(signatureFactory.AlgorithmDetails is AlgorithmIdentifier)) + { + throw new ArgumentException("AlgorithmDetails is not AlgorithmIdentifier"); + } + + FinalizeHeader((AlgorithmIdentifier)signatureFactory.AlgorithmDetails); + PkiHeader header = hdrBuilBuilder.Build(); + DerBitString protection = new DerBitString(CalculateSignature(calculator, header, body)); + return FinalizeMessage(header, protection); + } + + public ProtectedPkiMessage Build(IMacFactory factory) + { + if (null == body) + throw new InvalidOperationException("body must be set before building"); + + IStreamCalculator calculator = factory.CreateCalculator(); + FinalizeHeader((AlgorithmIdentifier)factory.AlgorithmDetails); + PkiHeader header = hdrBuilBuilder.Build(); + DerBitString protection = new DerBitString(CalculateSignature(calculator, header, body)); + return FinalizeMessage(header, protection); + } + + private void FinalizeHeader(AlgorithmIdentifier algorithmIdentifier) + { + hdrBuilBuilder.SetProtectionAlg(algorithmIdentifier); + if (generalInfos.Count > 0) + { + InfoTypeAndValue[] genInfos = new InfoTypeAndValue[generalInfos.Count]; + for (int t = 0; t < genInfos.Length; t++) + { + genInfos[t] = (InfoTypeAndValue)generalInfos[t]; + } + + hdrBuilBuilder.SetGeneralInfo(genInfos); + } + } + + private ProtectedPkiMessage FinalizeMessage(PkiHeader header, DerBitString protection) + { + if (extraCerts.Count > 0) + { + CmpCertificate[] cmpCertificates = new CmpCertificate[extraCerts.Count]; + for (int i = 0; i < cmpCertificates.Length; i++) + { + byte[] cert = ((X509Certificate)extraCerts[i]).GetEncoded(); + cmpCertificates[i] = CmpCertificate.GetInstance((Asn1Sequence.FromByteArray(cert))); + } + + return new ProtectedPkiMessage(new PkiMessage(header, body, protection, cmpCertificates)); + } + + return new ProtectedPkiMessage(new PkiMessage(header, body, protection)); + } + + private byte[] CalculateSignature(IStreamCalculator signer, PkiHeader header, PkiBody body) + { + Asn1EncodableVector avec = new Asn1EncodableVector(); + avec.Add(header); + avec.Add(body); + byte[] encoded = new DerSequence(avec).GetEncoded(); + signer.Stream.Write(encoded, 0, encoded.Length); + object result = signer.GetResult(); + + if (result is DefaultSignatureResult) + { + return ((DefaultSignatureResult)result).Collect(); + } + else if (result is IBlockResult) + { + return ((IBlockResult)result).Collect(); + } + else if (result is byte[]) + { + return (byte[])result; + } + + throw new InvalidOperationException("result is not byte[] or DefaultSignatureResult"); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/ProtectedPkiMessageBuilder.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/ProtectedPkiMessageBuilder.cs.meta new file mode 100644 index 0000000..50423f7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/ProtectedPkiMessageBuilder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c0276185cec96d54e9b5965653ebe5de +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/RevocationDetails.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/RevocationDetails.cs new file mode 100644 index 0000000..2d3f9a5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/RevocationDetails.cs @@ -0,0 +1,38 @@ +using System; + +using Org.BouncyCastle.Asn1.Cmp; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Cmp +{ + public class RevocationDetails + { + private readonly RevDetails revDetails; + + public RevocationDetails(RevDetails revDetails) + { + this.revDetails = revDetails; + } + + public X509Name Subject + { + get { return revDetails.CertDetails.Subject; } + } + + public X509Name Issuer + { + get { return revDetails.CertDetails.Issuer; } + } + + public BigInteger SerialNumber + { + get { return revDetails.CertDetails.SerialNumber.Value; } + } + + public RevDetails ToASN1Structure() + { + return revDetails; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/RevocationDetails.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/RevocationDetails.cs.meta new file mode 100644 index 0000000..fd4363c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/RevocationDetails.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1108c0803cf03c847b6427c702cddd25 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/RevocationDetailsBuilder.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/RevocationDetailsBuilder.cs new file mode 100644 index 0000000..b3be012 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/RevocationDetailsBuilder.cs @@ -0,0 +1,60 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cmp; +using Org.BouncyCastle.Asn1.Crmf; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Cmp +{ + public class RevocationDetailsBuilder + { + private readonly CertTemplateBuilder _templateBuilder = new CertTemplateBuilder(); + + public RevocationDetailsBuilder SetPublicKey(SubjectPublicKeyInfo publicKey) + { + if (publicKey != null) + { + _templateBuilder.SetPublicKey(publicKey); + } + + return this; + } + + public RevocationDetailsBuilder SetIssuer(X509Name issuer) + { + if (issuer != null) + { + _templateBuilder.SetIssuer(issuer); + } + + return this; + } + + public RevocationDetailsBuilder SetSerialNumber(BigInteger serialNumber) + { + if (serialNumber != null) + { + _templateBuilder.SetSerialNumber(new DerInteger(serialNumber)); + } + + return this; + } + + public RevocationDetailsBuilder SetSubject(X509Name subject) + { + if (subject != null) + { + _templateBuilder.SetSubject(subject); + } + + return this; + } + + public RevocationDetails Build() + { + return new RevocationDetails(new RevDetails(_templateBuilder.Build())); + } + } +} \ No newline at end of file diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/RevocationDetailsBuilder.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/RevocationDetailsBuilder.cs.meta new file mode 100644 index 0000000..3cc27f8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cmp/RevocationDetailsBuilder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ba29a44e55db7bd48a44ce7523012d08 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms.meta new file mode 100644 index 0000000..4f97414 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4383c6b8a7e34074bafed5f894b57a00 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/BaseDigestCalculator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/BaseDigestCalculator.cs new file mode 100644 index 0000000..3dcbca7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/BaseDigestCalculator.cs @@ -0,0 +1,23 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Cms +{ + internal class BaseDigestCalculator + : IDigestCalculator + { + private readonly byte[] digest; + + internal BaseDigestCalculator( + byte[] digest) + { + this.digest = digest; + } + + public byte[] GetDigest() + { + return Arrays.Clone(digest); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/BaseDigestCalculator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/BaseDigestCalculator.cs.meta new file mode 100644 index 0000000..107151a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/BaseDigestCalculator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7db27259db31e1540bcb6be17a6979d4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAttributeTableGenerationException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAttributeTableGenerationException.cs new file mode 100644 index 0000000..87dad99 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAttributeTableGenerationException.cs @@ -0,0 +1,28 @@ +using System; + +namespace Org.BouncyCastle.Cms +{ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE) + [Serializable] +#endif + public class CmsAttributeTableGenerationException + : CmsException + { + public CmsAttributeTableGenerationException() + { + } + + public CmsAttributeTableGenerationException( + string name) + : base(name) + { + } + + public CmsAttributeTableGenerationException( + string name, + Exception e) + : base(name, e) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAttributeTableGenerationException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAttributeTableGenerationException.cs.meta new file mode 100644 index 0000000..a86db6a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAttributeTableGenerationException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a61b1cf2b4913104a8533b8286f09ec9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAttributeTableGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAttributeTableGenerator.cs new file mode 100644 index 0000000..92c9a29 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAttributeTableGenerator.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1.Cms; + +namespace Org.BouncyCastle.Cms +{ + /// + /// The 'Signature' parameter is only available when generating unsigned attributes. + /// + public enum CmsAttributeTableParameter + { +// const string ContentType = "contentType"; +// const string Digest = "digest"; +// const string Signature = "encryptedDigest"; +// const string DigestAlgorithmIdentifier = "digestAlgID"; + + ContentType, Digest, Signature, DigestAlgorithmIdentifier + } + + public interface CmsAttributeTableGenerator + { + AttributeTable GetAttributes(IDictionary parameters); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAttributeTableGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAttributeTableGenerator.cs.meta new file mode 100644 index 0000000..d84747a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAttributeTableGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d8643692e8548c041823c2af8714e8a7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAuthEnvelopedData.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAuthEnvelopedData.cs new file mode 100644 index 0000000..d35e946 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAuthEnvelopedData.cs @@ -0,0 +1,112 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Cms +{ + /** + * containing class for an CMS AuthEnveloped Data object + */ + internal class CmsAuthEnvelopedData + { + internal RecipientInformationStore recipientInfoStore; + internal ContentInfo contentInfo; + + private OriginatorInfo originator; + private AlgorithmIdentifier authEncAlg; + private Asn1Set authAttrs; + private byte[] mac; + private Asn1Set unauthAttrs; + + public CmsAuthEnvelopedData( + byte[] authEnvData) + : this(CmsUtilities.ReadContentInfo(authEnvData)) + { + } + + public CmsAuthEnvelopedData( + Stream authEnvData) + : this(CmsUtilities.ReadContentInfo(authEnvData)) + { + } + + public CmsAuthEnvelopedData( + ContentInfo contentInfo) + { + this.contentInfo = contentInfo; + + AuthEnvelopedData authEnvData = AuthEnvelopedData.GetInstance(contentInfo.Content); + + this.originator = authEnvData.OriginatorInfo; + + // + // read the recipients + // + Asn1Set recipientInfos = authEnvData.RecipientInfos; + + // + // read the auth-encrypted content info + // + EncryptedContentInfo authEncInfo = authEnvData.AuthEncryptedContentInfo; + this.authEncAlg = authEncInfo.ContentEncryptionAlgorithm; + CmsSecureReadable secureReadable = new AuthEnvelopedSecureReadable(this); + + // + // build the RecipientInformationStore + // + this.recipientInfoStore = CmsEnvelopedHelper.BuildRecipientInformationStore( + recipientInfos, secureReadable); + + // FIXME These need to be passed to the AEAD cipher as AAD (Additional Authenticated Data) + this.authAttrs = authEnvData.AuthAttrs; + this.mac = authEnvData.Mac.GetOctets(); + this.unauthAttrs = authEnvData.UnauthAttrs; + } + + private class AuthEnvelopedSecureReadable : CmsSecureReadable + { + private readonly CmsAuthEnvelopedData parent; + + internal AuthEnvelopedSecureReadable(CmsAuthEnvelopedData parent) + { + this.parent = parent; + } + + public AlgorithmIdentifier Algorithm + { + get { return parent.authEncAlg; } + } + + public object CryptoObject + { + get { return null; } + } + + public CmsReadable GetReadable(KeyParameter key) + { + // TODO Create AEAD cipher instance to decrypt and calculate tag ( MAC) + throw new CmsException("AuthEnveloped data decryption not yet implemented"); + +// RFC 5084 ASN.1 Module +// -- Parameters for AlgorithmIdentifier +// +// CCMParameters ::= SEQUENCE { +// aes-nonce OCTET STRING (SIZE(7..13)), +// aes-ICVlen AES-CCM-ICVlen DEFAULT 12 } +// +// AES-CCM-ICVlen ::= INTEGER (4 | 6 | 8 | 10 | 12 | 14 | 16) +// +// GCMParameters ::= SEQUENCE { +// aes-nonce OCTET STRING, -- recommended size is 12 octets +// aes-ICVlen AES-GCM-ICVlen DEFAULT 12 } +// +// AES-GCM-ICVlen ::= INTEGER (12 | 13 | 14 | 15 | 16) + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAuthEnvelopedData.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAuthEnvelopedData.cs.meta new file mode 100644 index 0000000..351364f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAuthEnvelopedData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 57e2efdb170957145a72d2448877d4fa +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAuthEnvelopedGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAuthEnvelopedGenerator.cs new file mode 100644 index 0000000..4273cff --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAuthEnvelopedGenerator.cs @@ -0,0 +1,16 @@ +using System; + +using Org.BouncyCastle.Asn1.Nist; + +namespace Org.BouncyCastle.Cms +{ + internal class CmsAuthEnvelopedGenerator + { + public static readonly string Aes128Ccm = NistObjectIdentifiers.IdAes128Ccm.Id; + public static readonly string Aes192Ccm = NistObjectIdentifiers.IdAes192Ccm.Id; + public static readonly string Aes256Ccm = NistObjectIdentifiers.IdAes256Ccm.Id; + public static readonly string Aes128Gcm = NistObjectIdentifiers.IdAes128Gcm.Id; + public static readonly string Aes192Gcm = NistObjectIdentifiers.IdAes192Gcm.Id; + public static readonly string Aes256Gcm = NistObjectIdentifiers.IdAes256Gcm.Id; + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAuthEnvelopedGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAuthEnvelopedGenerator.cs.meta new file mode 100644 index 0000000..466cae9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAuthEnvelopedGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0434e8befd4c3fd4092b89597059e8cd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAuthenticatedData.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAuthenticatedData.cs new file mode 100644 index 0000000..33b4cc2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAuthenticatedData.cs @@ -0,0 +1,137 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Cms +{ + /** + * containing class for an CMS Authenticated Data object + */ + public class CmsAuthenticatedData + { + internal RecipientInformationStore recipientInfoStore; + internal ContentInfo contentInfo; + + private AlgorithmIdentifier macAlg; + private Asn1Set authAttrs; + private Asn1Set unauthAttrs; + private byte[] mac; + + public CmsAuthenticatedData( + byte[] authData) + : this(CmsUtilities.ReadContentInfo(authData)) + { + } + + public CmsAuthenticatedData( + Stream authData) + : this(CmsUtilities.ReadContentInfo(authData)) + { + } + + public CmsAuthenticatedData( + ContentInfo contentInfo) + { + this.contentInfo = contentInfo; + + AuthenticatedData authData = AuthenticatedData.GetInstance(contentInfo.Content); + + // + // read the recipients + // + Asn1Set recipientInfos = authData.RecipientInfos; + + this.macAlg = authData.MacAlgorithm; + + // + // read the authenticated content info + // + ContentInfo encInfo = authData.EncapsulatedContentInfo; + CmsReadable readable = new CmsProcessableByteArray( + Asn1OctetString.GetInstance(encInfo.Content).GetOctets()); + CmsSecureReadable secureReadable = new CmsEnvelopedHelper.CmsAuthenticatedSecureReadable( + this.macAlg, readable); + + // + // build the RecipientInformationStore + // + this.recipientInfoStore = CmsEnvelopedHelper.BuildRecipientInformationStore( + recipientInfos, secureReadable); + + this.authAttrs = authData.AuthAttrs; + this.mac = authData.Mac.GetOctets(); + this.unauthAttrs = authData.UnauthAttrs; + } + + public byte[] GetMac() + { + return Arrays.Clone(mac); + } + + public AlgorithmIdentifier MacAlgorithmID + { + get { return macAlg; } + } + + /** + * return the object identifier for the content MAC algorithm. + */ + public string MacAlgOid + { + get { return macAlg.Algorithm.Id; } + } + + /** + * return a store of the intended recipients for this message + */ + public RecipientInformationStore GetRecipientInfos() + { + return recipientInfoStore; + } + + /** + * return the ContentInfo + */ + public ContentInfo ContentInfo + { + get { return contentInfo; } + } + + /** + * return a table of the digested attributes indexed by + * the OID of the attribute. + */ + public Asn1.Cms.AttributeTable GetAuthAttrs() + { + if (authAttrs == null) + return null; + + return new Asn1.Cms.AttributeTable(authAttrs); + } + + /** + * return a table of the undigested attributes indexed by + * the OID of the attribute. + */ + public Asn1.Cms.AttributeTable GetUnauthAttrs() + { + if (unauthAttrs == null) + return null; + + return new Asn1.Cms.AttributeTable(unauthAttrs); + } + + /** + * return the ASN.1 encoded representation of this object. + */ + public byte[] GetEncoded() + { + return contentInfo.GetEncoded(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAuthenticatedData.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAuthenticatedData.cs.meta new file mode 100644 index 0000000..b3dcbca --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAuthenticatedData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8848aefce4026c9438e7f337e297f1d6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAuthenticatedDataGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAuthenticatedDataGenerator.cs new file mode 100644 index 0000000..addd14c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAuthenticatedDataGenerator.cs @@ -0,0 +1,156 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.IO; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Cms +{ + /** + * General class for generating a CMS authenticated-data message. + * + * A simple example of usage. + * + *
+	 *      CMSAuthenticatedDataGenerator  fact = new CMSAuthenticatedDataGenerator();
+	 *
+	 *      fact.addKeyTransRecipient(cert);
+	 *
+	 *      CMSAuthenticatedData         data = fact.generate(content, algorithm, "BC");
+	 * 
+ */ + public class CmsAuthenticatedDataGenerator + : CmsAuthenticatedGenerator + { + /** + * base constructor + */ + public CmsAuthenticatedDataGenerator() + { + } + + /** + * constructor allowing specific source of randomness + * @param rand instance of SecureRandom to use + */ + public CmsAuthenticatedDataGenerator( + SecureRandom rand) + : base(rand) + { + } + + /** + * generate an enveloped object that contains an CMS Enveloped Data + * object using the given provider and the passed in key generator. + */ + private CmsAuthenticatedData Generate( + CmsProcessable content, + string macOid, + CipherKeyGenerator keyGen) + { + AlgorithmIdentifier macAlgId; + KeyParameter encKey; + Asn1OctetString encContent; + Asn1OctetString macResult; + + try + { + // FIXME Will this work for macs? + byte[] encKeyBytes = keyGen.GenerateKey(); + encKey = ParameterUtilities.CreateKeyParameter(macOid, encKeyBytes); + + Asn1Encodable asn1Params = GenerateAsn1Parameters(macOid, encKeyBytes); + + ICipherParameters cipherParameters; + macAlgId = GetAlgorithmIdentifier( + macOid, encKey, asn1Params, out cipherParameters); + + IMac mac = MacUtilities.GetMac(macOid); + // TODO Confirm no ParametersWithRandom needed + // FIXME Only passing key at the moment +// mac.Init(cipherParameters); + mac.Init(encKey); + + MemoryStream bOut = new MemoryStream(); + Stream mOut = new TeeOutputStream(bOut, new MacSink(mac)); + + content.Write(mOut); + + Platform.Dispose(mOut); + + encContent = new BerOctetString(bOut.ToArray()); + + byte[] macOctets = MacUtilities.DoFinal(mac); + macResult = new DerOctetString(macOctets); + } + catch (SecurityUtilityException e) + { + throw new CmsException("couldn't create cipher.", e); + } + catch (InvalidKeyException e) + { + throw new CmsException("key invalid in message.", e); + } + catch (IOException e) + { + throw new CmsException("exception decoding algorithm parameters.", e); + } + + Asn1EncodableVector recipientInfos = new Asn1EncodableVector(); + + foreach (RecipientInfoGenerator rig in recipientInfoGenerators) + { + try + { + recipientInfos.Add(rig.Generate(encKey, rand)); + } + catch (InvalidKeyException e) + { + throw new CmsException("key inappropriate for algorithm.", e); + } + catch (GeneralSecurityException e) + { + throw new CmsException("error making encrypted content.", e); + } + } + + ContentInfo eci = new ContentInfo(CmsObjectIdentifiers.Data, encContent); + + ContentInfo contentInfo = new ContentInfo( + CmsObjectIdentifiers.AuthenticatedData, + new AuthenticatedData(null, new DerSet(recipientInfos), macAlgId, null, eci, null, macResult, null)); + + return new CmsAuthenticatedData(contentInfo); + } + + /** + * generate an authenticated object that contains an CMS Authenticated Data object + */ + public CmsAuthenticatedData Generate( + CmsProcessable content, + string encryptionOid) + { + try + { + // FIXME Will this work for macs? + CipherKeyGenerator keyGen = GeneratorUtilities.GetKeyGenerator(encryptionOid); + + keyGen.Init(new KeyGenerationParameters(rand, keyGen.DefaultStrength)); + + return Generate(content, encryptionOid, keyGen); + } + catch (SecurityUtilityException e) + { + throw new CmsException("can't find key generation algorithm.", e); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAuthenticatedDataGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAuthenticatedDataGenerator.cs.meta new file mode 100644 index 0000000..dffa0a4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAuthenticatedDataGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bfe833dc4089cfa4b907d20d9ed78df7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAuthenticatedDataParser.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAuthenticatedDataParser.cs new file mode 100644 index 0000000..7defafc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAuthenticatedDataParser.cs @@ -0,0 +1,214 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Cms +{ + /** + * Parsing class for an CMS Authenticated Data object from an input stream. + *

+ * Note: that because we are in a streaming mode only one recipient can be tried and it is important + * that the methods on the parser are called in the appropriate order. + *

+ *

+ * Example of use - assuming the first recipient matches the private key we have. + *

+	*      CMSAuthenticatedDataParser     ad = new CMSAuthenticatedDataParser(inputStream);
+	*
+	*      RecipientInformationStore  recipients = ad.getRecipientInfos();
+	*
+	*      Collection  c = recipients.getRecipients();
+	*      Iterator    it = c.iterator();
+	*
+	*      if (it.hasNext())
+	*      {
+	*          RecipientInformation   recipient = (RecipientInformation)it.next();
+	*
+	*          CMSTypedStream recData = recipient.getContentStream(privateKey, "BC");
+	*
+	*          processDataStream(recData.getContentStream());
+	*
+	*          if (!Arrays.equals(ad.getMac(), recipient.getMac())
+	*          {
+	*              System.err.println("Data corrupted!!!!");
+	*          }
+	*      }
+	*  
+ * Note: this class does not introduce buffering - if you are processing large files you should create + * the parser with: + *
+	*          CMSAuthenticatedDataParser     ep = new CMSAuthenticatedDataParser(new BufferedInputStream(inputStream, bufSize));
+	*  
+ * where bufSize is a suitably large buffer size. + *

+ */ + public class CmsAuthenticatedDataParser + : CmsContentInfoParser + { + internal RecipientInformationStore _recipientInfoStore; + internal AuthenticatedDataParser authData; + + private AlgorithmIdentifier macAlg; + private byte[] mac; + private Asn1.Cms.AttributeTable authAttrs; + private Asn1.Cms.AttributeTable unauthAttrs; + + private bool authAttrNotRead; + private bool unauthAttrNotRead; + + public CmsAuthenticatedDataParser( + byte[] envelopedData) + : this(new MemoryStream(envelopedData, false)) + { + } + + public CmsAuthenticatedDataParser( + Stream envelopedData) + : base(envelopedData) + { + this.authAttrNotRead = true; + this.authData = new AuthenticatedDataParser( + (Asn1SequenceParser)contentInfo.GetContent(Asn1Tags.Sequence)); + + // TODO Validate version? + //DerInteger version = this.authData.getVersion(); + + // + // read the recipients + // + Asn1Set recipientInfos = Asn1Set.GetInstance(authData.GetRecipientInfos().ToAsn1Object()); + + this.macAlg = authData.GetMacAlgorithm(); + + // + // read the authenticated content info + // + ContentInfoParser data = authData.GetEnapsulatedContentInfo(); + CmsReadable readable = new CmsProcessableInputStream( + ((Asn1OctetStringParser)data.GetContent(Asn1Tags.OctetString)).GetOctetStream()); + CmsSecureReadable secureReadable = new CmsEnvelopedHelper.CmsAuthenticatedSecureReadable( + this.macAlg, readable); + + // + // build the RecipientInformationStore + // + this._recipientInfoStore = CmsEnvelopedHelper.BuildRecipientInformationStore( + recipientInfos, secureReadable); + } + + public AlgorithmIdentifier MacAlgorithmID + { + get { return macAlg; } + } + + /** + * return the object identifier for the mac algorithm. + */ + public string MacAlgOid + { + get { return macAlg.Algorithm.Id; } + } + + + /** + * return the ASN.1 encoded encryption algorithm parameters, or null if + * there aren't any. + */ + public Asn1Object MacAlgParams + { + get + { + Asn1Encodable ae = macAlg.Parameters; + + return ae == null ? null : ae.ToAsn1Object(); + } + } + + /** + * return a store of the intended recipients for this message + */ + public RecipientInformationStore GetRecipientInfos() + { + return _recipientInfoStore; + } + + public byte[] GetMac() + { + if (mac == null) + { + GetAuthAttrs(); + mac = authData.GetMac().GetOctets(); + } + return Arrays.Clone(mac); + } + + /** + * return a table of the unauthenticated attributes indexed by + * the OID of the attribute. + * @exception java.io.IOException + */ + public Asn1.Cms.AttributeTable GetAuthAttrs() + { + if (authAttrs == null && authAttrNotRead) + { + Asn1SetParser s = authData.GetAuthAttrs(); + + authAttrNotRead = false; + + if (s != null) + { + Asn1EncodableVector v = new Asn1EncodableVector(); + + IAsn1Convertible o; + while ((o = s.ReadObject()) != null) + { + Asn1SequenceParser seq = (Asn1SequenceParser)o; + + v.Add(seq.ToAsn1Object()); + } + + authAttrs = new Asn1.Cms.AttributeTable(new DerSet(v)); + } + } + + return authAttrs; + } + + /** + * return a table of the unauthenticated attributes indexed by + * the OID of the attribute. + * @exception java.io.IOException + */ + public Asn1.Cms.AttributeTable GetUnauthAttrs() + { + if (unauthAttrs == null && unauthAttrNotRead) + { + Asn1SetParser s = authData.GetUnauthAttrs(); + + unauthAttrNotRead = false; + + if (s != null) + { + Asn1EncodableVector v = new Asn1EncodableVector(); + + IAsn1Convertible o; + while ((o = s.ReadObject()) != null) + { + Asn1SequenceParser seq = (Asn1SequenceParser)o; + + v.Add(seq.ToAsn1Object()); + } + + unauthAttrs = new Asn1.Cms.AttributeTable(new DerSet(v)); + } + } + + return unauthAttrs; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAuthenticatedDataParser.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAuthenticatedDataParser.cs.meta new file mode 100644 index 0000000..0540aaa --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAuthenticatedDataParser.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d4745845dddeec04bb83944d62493df6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAuthenticatedDataStreamGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAuthenticatedDataStreamGenerator.cs new file mode 100644 index 0000000..b77758d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAuthenticatedDataStreamGenerator.cs @@ -0,0 +1,297 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.IO; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Cms +{ + /** + * General class for generating a CMS authenticated-data message stream. + *

+ * A simple example of usage. + *

+	*      CMSAuthenticatedDataStreamGenerator edGen = new CMSAuthenticatedDataStreamGenerator();
+	*
+	*      edGen.addKeyTransRecipient(cert);
+	*
+	*      ByteArrayOutputStream  bOut = new ByteArrayOutputStream();
+	*
+	*      OutputStream out = edGen.open(
+	*                              bOut, CMSAuthenticatedDataGenerator.AES128_CBC, "BC");*
+	*      out.write(data);
+	*
+	*      out.close();
+	* 
+ *

+ */ + public class CmsAuthenticatedDataStreamGenerator + : CmsAuthenticatedGenerator + { + // TODO Add support +// private object _originatorInfo = null; +// private object _unprotectedAttributes = null; + private int _bufferSize; + private bool _berEncodeRecipientSet; + + /** + * base constructor + */ + public CmsAuthenticatedDataStreamGenerator() + { + } + + /** + * constructor allowing specific source of randomness + * @param rand instance of SecureRandom to use + */ + public CmsAuthenticatedDataStreamGenerator( + SecureRandom rand) + : base(rand) + { + } + + /** + * Set the underlying string size for encapsulated data + * + * @param bufferSize length of octet strings to buffer the data. + */ + public void SetBufferSize( + int bufferSize) + { + _bufferSize = bufferSize; + } + + /** + * Use a BER Set to store the recipient information + */ + public void SetBerEncodeRecipients( + bool berEncodeRecipientSet) + { + _berEncodeRecipientSet = berEncodeRecipientSet; + } + + /** + * generate an enveloped object that contains an CMS Enveloped Data + * object using the given provider and the passed in key generator. + * @throws java.io.IOException + */ + private Stream Open( + Stream outStr, + string macOid, + CipherKeyGenerator keyGen) + { + // FIXME Will this work for macs? + byte[] encKeyBytes = keyGen.GenerateKey(); + KeyParameter encKey = ParameterUtilities.CreateKeyParameter(macOid, encKeyBytes); + + Asn1Encodable asn1Params = GenerateAsn1Parameters(macOid, encKeyBytes); + + ICipherParameters cipherParameters; + AlgorithmIdentifier macAlgId = GetAlgorithmIdentifier( + macOid, encKey, asn1Params, out cipherParameters); + + Asn1EncodableVector recipientInfos = new Asn1EncodableVector(); + + foreach (RecipientInfoGenerator rig in recipientInfoGenerators) + { + try + { + recipientInfos.Add(rig.Generate(encKey, rand)); + } + catch (InvalidKeyException e) + { + throw new CmsException("key inappropriate for algorithm.", e); + } + catch (GeneralSecurityException e) + { + throw new CmsException("error making encrypted content.", e); + } + } + + // FIXME Only passing key at the moment +// return Open(outStr, macAlgId, cipherParameters, recipientInfos); + return Open(outStr, macAlgId, encKey, recipientInfos); + } + + protected Stream Open( + Stream outStr, + AlgorithmIdentifier macAlgId, + ICipherParameters cipherParameters, + Asn1EncodableVector recipientInfos) + { + try + { + // + // ContentInfo + // + BerSequenceGenerator cGen = new BerSequenceGenerator(outStr); + + cGen.AddObject(CmsObjectIdentifiers.AuthenticatedData); + + // + // Authenticated Data + // + BerSequenceGenerator authGen = new BerSequenceGenerator( + cGen.GetRawOutputStream(), 0, true); + + authGen.AddObject(new DerInteger(AuthenticatedData.CalculateVersion(null))); + + Stream authRaw = authGen.GetRawOutputStream(); + Asn1Generator recipGen = _berEncodeRecipientSet + ? (Asn1Generator) new BerSetGenerator(authRaw) + : new DerSetGenerator(authRaw); + + foreach (Asn1Encodable ae in recipientInfos) + { + recipGen.AddObject(ae); + } + + recipGen.Close(); + + authGen.AddObject(macAlgId); + + BerSequenceGenerator eiGen = new BerSequenceGenerator(authRaw); + eiGen.AddObject(CmsObjectIdentifiers.Data); + + Stream octetOutputStream = CmsUtilities.CreateBerOctetOutputStream( + eiGen.GetRawOutputStream(), 0, true, _bufferSize); + + IMac mac = MacUtilities.GetMac(macAlgId.Algorithm); + // TODO Confirm no ParametersWithRandom needed + mac.Init(cipherParameters); + Stream mOut = new TeeOutputStream(octetOutputStream, new MacSink(mac)); + + return new CmsAuthenticatedDataOutputStream(mOut, mac, cGen, authGen, eiGen); + } + catch (SecurityUtilityException e) + { + throw new CmsException("couldn't create cipher.", e); + } + catch (InvalidKeyException e) + { + throw new CmsException("key invalid in message.", e); + } + catch (IOException e) + { + throw new CmsException("exception decoding algorithm parameters.", e); + } + } + + /** + * generate an enveloped object that contains an CMS Enveloped Data object + */ + public Stream Open( + Stream outStr, + string encryptionOid) + { + CipherKeyGenerator keyGen = GeneratorUtilities.GetKeyGenerator(encryptionOid); + + keyGen.Init(new KeyGenerationParameters(rand, keyGen.DefaultStrength)); + + return Open(outStr, encryptionOid, keyGen); + } + + /** + * generate an enveloped object that contains an CMS Enveloped Data object + */ + public Stream Open( + Stream outStr, + string encryptionOid, + int keySize) + { + CipherKeyGenerator keyGen = GeneratorUtilities.GetKeyGenerator(encryptionOid); + + keyGen.Init(new KeyGenerationParameters(rand, keySize)); + + return Open(outStr, encryptionOid, keyGen); + } + + private class CmsAuthenticatedDataOutputStream + : BaseOutputStream + { + private readonly Stream macStream; + private readonly IMac mac; + private readonly BerSequenceGenerator cGen; + private readonly BerSequenceGenerator authGen; + private readonly BerSequenceGenerator eiGen; + + public CmsAuthenticatedDataOutputStream( + Stream macStream, + IMac mac, + BerSequenceGenerator cGen, + BerSequenceGenerator authGen, + BerSequenceGenerator eiGen) + { + this.macStream = macStream; + this.mac = mac; + this.cGen = cGen; + this.authGen = authGen; + this.eiGen = eiGen; + } + + public override void WriteByte( + byte b) + { + macStream.WriteByte(b); + } + + public override void Write( + byte[] bytes, + int off, + int len) + { + macStream.Write(bytes, off, len); + } + +#if PORTABLE + protected override void Dispose(bool disposing) + { + if (disposing) + { + Platform.Dispose(macStream); + + // TODO Parent context(s) should really be be closed explicitly + + eiGen.Close(); + + // [TODO] auth attributes go here + byte[] macOctets = MacUtilities.DoFinal(mac); + authGen.AddObject(new DerOctetString(macOctets)); + // [TODO] unauth attributes go here + + authGen.Close(); + cGen.Close(); + } + base.Dispose(disposing); + } +#else + public override void Close() + { + Platform.Dispose(macStream); + + // TODO Parent context(s) should really be be closed explicitly + + eiGen.Close(); + + // [TODO] auth attributes go here + byte[] macOctets = MacUtilities.DoFinal(mac); + authGen.AddObject(new DerOctetString(macOctets)); + // [TODO] unauth attributes go here + + authGen.Close(); + cGen.Close(); + base.Close(); + } +#endif + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAuthenticatedDataStreamGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAuthenticatedDataStreamGenerator.cs.meta new file mode 100644 index 0000000..a3be402 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAuthenticatedDataStreamGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8f5ba3a20017eae4aad596ee32122043 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAuthenticatedGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAuthenticatedGenerator.cs new file mode 100644 index 0000000..8824d19 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAuthenticatedGenerator.cs @@ -0,0 +1,35 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities.Date; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Cms +{ + public class CmsAuthenticatedGenerator + : CmsEnvelopedGenerator + { + /** + * base constructor + */ + public CmsAuthenticatedGenerator() + { + } + + /** + * constructor allowing specific source of randomness + * + * @param rand instance of SecureRandom to use + */ + public CmsAuthenticatedGenerator( + SecureRandom rand) + : base(rand) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAuthenticatedGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAuthenticatedGenerator.cs.meta new file mode 100644 index 0000000..d4c29eb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSAuthenticatedGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 302bff75d7d504d4399ac744865c7c74 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSCompressedData.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSCompressedData.cs new file mode 100644 index 0000000..21651f0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSCompressedData.cs @@ -0,0 +1,108 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Zlib; + +namespace Org.BouncyCastle.Cms +{ + /** + * containing class for an CMS Compressed Data object + */ + public class CmsCompressedData + { + internal ContentInfo contentInfo; + + public CmsCompressedData( + byte[] compressedData) + : this(CmsUtilities.ReadContentInfo(compressedData)) + { + } + + public CmsCompressedData( + Stream compressedDataStream) + : this(CmsUtilities.ReadContentInfo(compressedDataStream)) + { + } + + public CmsCompressedData( + ContentInfo contentInfo) + { + this.contentInfo = contentInfo; + } + + /** + * Return the uncompressed content. + * + * @return the uncompressed content + * @throws CmsException if there is an exception uncompressing the data. + */ + public byte[] GetContent() + { + CompressedData comData = CompressedData.GetInstance(contentInfo.Content); + ContentInfo content = comData.EncapContentInfo; + + Asn1OctetString bytes = (Asn1OctetString) content.Content; + ZInputStream zIn = new ZInputStream(bytes.GetOctetStream()); + + try + { + return CmsUtilities.StreamToByteArray(zIn); + } + catch (IOException e) + { + throw new CmsException("exception reading compressed stream.", e); + } + finally + { + Platform.Dispose(zIn); + } + } + + /** + * Return the uncompressed content, throwing an exception if the data size + * is greater than the passed in limit. If the content is exceeded getCause() + * on the CMSException will contain a StreamOverflowException + * + * @param limit maximum number of bytes to read + * @return the content read + * @throws CMSException if there is an exception uncompressing the data. + */ + public byte[] GetContent(int limit) + { + CompressedData comData = CompressedData.GetInstance(contentInfo.Content); + ContentInfo content = comData.EncapContentInfo; + + Asn1OctetString bytes = (Asn1OctetString)content.Content; + + ZInputStream zIn = new ZInputStream(new MemoryStream(bytes.GetOctets(), false)); + + try + { + return CmsUtilities.StreamToByteArray(zIn, limit); + } + catch (IOException e) + { + throw new CmsException("exception reading compressed stream.", e); + } + } + + /** + * return the ContentInfo + */ + public ContentInfo ContentInfo + { + get { return contentInfo; } + } + + /** + * return the ASN.1 encoded representation of this object. + */ + public byte[] GetEncoded() + { + return contentInfo.GetEncoded(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSCompressedData.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSCompressedData.cs.meta new file mode 100644 index 0000000..fe16b8b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSCompressedData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7c4f8132a7caf7a499fc8facca0914da +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSCompressedDataGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSCompressedDataGenerator.cs new file mode 100644 index 0000000..d51de10 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSCompressedDataGenerator.cs @@ -0,0 +1,67 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Zlib; + +namespace Org.BouncyCastle.Cms +{ + /** + * General class for generating a compressed CMS message. + *

+ * A simple example of usage.

+ *

+ *

+    *      CMSCompressedDataGenerator fact = new CMSCompressedDataGenerator();
+    *      CMSCompressedData data = fact.Generate(content, algorithm);
+    * 
+ *

+ */ + public class CmsCompressedDataGenerator + { + public const string ZLib = "1.2.840.113549.1.9.16.3.8"; + + public CmsCompressedDataGenerator() + { + } + + /** + * Generate an object that contains an CMS Compressed Data + */ + public CmsCompressedData Generate( + CmsProcessable content, + string compressionOid) + { + AlgorithmIdentifier comAlgId; + Asn1OctetString comOcts; + + try + { + MemoryStream bOut = new MemoryStream(); + ZOutputStream zOut = new ZOutputStream(bOut, JZlib.Z_DEFAULT_COMPRESSION); + + content.Write(zOut); + + Platform.Dispose(zOut); + + comAlgId = new AlgorithmIdentifier(new DerObjectIdentifier(compressionOid)); + comOcts = new BerOctetString(bOut.ToArray()); + } + catch (IOException e) + { + throw new CmsException("exception encoding data.", e); + } + + ContentInfo comContent = new ContentInfo(CmsObjectIdentifiers.Data, comOcts); + ContentInfo contentInfo = new ContentInfo( + CmsObjectIdentifiers.CompressedData, + new CompressedData(comAlgId, comContent)); + + return new CmsCompressedData(contentInfo); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSCompressedDataGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSCompressedDataGenerator.cs.meta new file mode 100644 index 0000000..a8092b0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSCompressedDataGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 52e5df7b4a4d0b140b286b5c31004268 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSCompressedDataParser.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSCompressedDataParser.cs new file mode 100644 index 0000000..93dfa12 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSCompressedDataParser.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Utilities.Zlib; + +namespace Org.BouncyCastle.Cms +{ + /** + * Class for reading a CMS Compressed Data stream. + *
+    *     CMSCompressedDataParser cp = new CMSCompressedDataParser(inputStream);
+    *
+    *     process(cp.GetContent().GetContentStream());
+    * 
+ * Note: this class does not introduce buffering - if you are processing large files you should create + * the parser with: + *
+    *      CMSCompressedDataParser     ep = new CMSCompressedDataParser(new BufferedInputStream(inputStream, bufSize));
+    *  
+ * where bufSize is a suitably large buffer size. + */ + public class CmsCompressedDataParser + : CmsContentInfoParser + { + public CmsCompressedDataParser( + byte[] compressedData) + : this(new MemoryStream(compressedData, false)) + { + } + + public CmsCompressedDataParser( + Stream compressedData) + : base(compressedData) + { + } + + public CmsTypedStream GetContent() + { + try + { + CompressedDataParser comData = new CompressedDataParser((Asn1SequenceParser)this.contentInfo.GetContent(Asn1Tags.Sequence)); + ContentInfoParser content = comData.GetEncapContentInfo(); + + Asn1OctetStringParser bytes = (Asn1OctetStringParser)content.GetContent(Asn1Tags.OctetString); + + return new CmsTypedStream(content.ContentType.ToString(), new ZInputStream(bytes.GetOctetStream())); + } + catch (IOException e) + { + throw new CmsException("IOException reading compressed content.", e); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSCompressedDataParser.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSCompressedDataParser.cs.meta new file mode 100644 index 0000000..361be16 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSCompressedDataParser.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 953923aa808590b49bc5beecfae75709 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSCompressedDataStreamGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSCompressedDataStreamGenerator.cs new file mode 100644 index 0000000..0cb1bb6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSCompressedDataStreamGenerator.cs @@ -0,0 +1,158 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; +using Org.BouncyCastle.Utilities.Zlib; + +namespace Org.BouncyCastle.Cms +{ + /** + * General class for generating a compressed CMS message stream. + *

+ * A simple example of usage. + *

+ *
+	*      CMSCompressedDataStreamGenerator gen = new CMSCompressedDataStreamGenerator();
+	*
+	*      Stream cOut = gen.Open(outputStream, CMSCompressedDataStreamGenerator.ZLIB);
+	*
+	*      cOut.Write(data);
+	*
+	*      cOut.Close();
+	* 
+ */ + public class CmsCompressedDataStreamGenerator + { + public const string ZLib = "1.2.840.113549.1.9.16.3.8"; + + private int _bufferSize; + + /** + * base constructor + */ + public CmsCompressedDataStreamGenerator() + { + } + + /** + * Set the underlying string size for encapsulated data + * + * @param bufferSize length of octet strings to buffer the data. + */ + public void SetBufferSize( + int bufferSize) + { + _bufferSize = bufferSize; + } + + public Stream Open( + Stream outStream, + string compressionOID) + { + return Open(outStream, CmsObjectIdentifiers.Data.Id, compressionOID); + } + + public Stream Open( + Stream outStream, + string contentOID, + string compressionOID) + { + BerSequenceGenerator sGen = new BerSequenceGenerator(outStream); + + sGen.AddObject(CmsObjectIdentifiers.CompressedData); + + // + // Compressed Data + // + BerSequenceGenerator cGen = new BerSequenceGenerator( + sGen.GetRawOutputStream(), 0, true); + + // CMSVersion + cGen.AddObject(new DerInteger(0)); + + // CompressionAlgorithmIdentifier + cGen.AddObject(new AlgorithmIdentifier(new DerObjectIdentifier(ZLib))); + + // + // Encapsulated ContentInfo + // + BerSequenceGenerator eiGen = new BerSequenceGenerator(cGen.GetRawOutputStream()); + + eiGen.AddObject(new DerObjectIdentifier(contentOID)); + + Stream octetStream = CmsUtilities.CreateBerOctetOutputStream( + eiGen.GetRawOutputStream(), 0, true, _bufferSize); + + return new CmsCompressedOutputStream( + new ZOutputStream(octetStream, JZlib.Z_DEFAULT_COMPRESSION), sGen, cGen, eiGen); + } + + private class CmsCompressedOutputStream + : BaseOutputStream + { + private ZOutputStream _out; + private BerSequenceGenerator _sGen; + private BerSequenceGenerator _cGen; + private BerSequenceGenerator _eiGen; + + internal CmsCompressedOutputStream( + ZOutputStream outStream, + BerSequenceGenerator sGen, + BerSequenceGenerator cGen, + BerSequenceGenerator eiGen) + { + _out = outStream; + _sGen = sGen; + _cGen = cGen; + _eiGen = eiGen; + } + + public override void WriteByte( + byte b) + { + _out.WriteByte(b); + } + + public override void Write( + byte[] bytes, + int off, + int len) + { + _out.Write(bytes, off, len); + } + +#if PORTABLE + protected override void Dispose(bool disposing) + { + if (disposing) + { + Platform.Dispose(_out); + + // TODO Parent context(s) should really be be closed explicitly + + _eiGen.Close(); + _cGen.Close(); + _sGen.Close(); + } + base.Dispose(disposing); + } +#else + public override void Close() + { + Platform.Dispose(_out); + + // TODO Parent context(s) should really be be closed explicitly + + _eiGen.Close(); + _cGen.Close(); + _sGen.Close(); + base.Close(); + } +#endif + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSCompressedDataStreamGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSCompressedDataStreamGenerator.cs.meta new file mode 100644 index 0000000..d7b7a5d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSCompressedDataStreamGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8d41fceddd9f2d14398f60d5f906ec76 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSContentInfoParser.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSContentInfoParser.cs new file mode 100644 index 0000000..a7b43f2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSContentInfoParser.cs @@ -0,0 +1,48 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Cms +{ + public class CmsContentInfoParser + { + protected ContentInfoParser contentInfo; + protected Stream data; + + protected CmsContentInfoParser( + Stream data) + { + if (data == null) + throw new ArgumentNullException("data"); + + this.data = data; + + try + { + Asn1StreamParser inStream = new Asn1StreamParser(data); + + this.contentInfo = new ContentInfoParser((Asn1SequenceParser)inStream.ReadObject()); + } + catch (IOException e) + { + throw new CmsException("IOException reading content.", e); + } + catch (InvalidCastException e) + { + throw new CmsException("Unexpected object reading content.", e); + } + } + + /** + * Close the underlying data stream. + * @throws IOException if the close fails. + */ + public void Close() + { + Platform.Dispose(this.data); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSContentInfoParser.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSContentInfoParser.cs.meta new file mode 100644 index 0000000..0374899 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSContentInfoParser.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4a94b865b821295488c01b7ce9ae2ff2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSEnvelopedData.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSEnvelopedData.cs new file mode 100644 index 0000000..223d0ca --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSEnvelopedData.cs @@ -0,0 +1,115 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Cms +{ + /** + * containing class for an CMS Enveloped Data object + */ + public class CmsEnvelopedData + { + internal RecipientInformationStore recipientInfoStore; + internal ContentInfo contentInfo; + + private AlgorithmIdentifier encAlg; + private Asn1Set unprotectedAttributes; + + public CmsEnvelopedData( + byte[] envelopedData) + : this(CmsUtilities.ReadContentInfo(envelopedData)) + { + } + + public CmsEnvelopedData( + Stream envelopedData) + : this(CmsUtilities.ReadContentInfo(envelopedData)) + { + } + + public CmsEnvelopedData( + ContentInfo contentInfo) + { + this.contentInfo = contentInfo; + + EnvelopedData envData = EnvelopedData.GetInstance(contentInfo.Content); + + // + // read the recipients + // + Asn1Set recipientInfos = envData.RecipientInfos; + + // + // read the encrypted content info + // + EncryptedContentInfo encInfo = envData.EncryptedContentInfo; + this.encAlg = encInfo.ContentEncryptionAlgorithm; + CmsReadable readable = new CmsProcessableByteArray(encInfo.EncryptedContent.GetOctets()); + CmsSecureReadable secureReadable = new CmsEnvelopedHelper.CmsEnvelopedSecureReadable( + this.encAlg, readable); + + // + // build the RecipientInformationStore + // + this.recipientInfoStore = CmsEnvelopedHelper.BuildRecipientInformationStore( + recipientInfos, secureReadable); + + this.unprotectedAttributes = envData.UnprotectedAttrs; + } + + public AlgorithmIdentifier EncryptionAlgorithmID + { + get { return encAlg; } + } + + /** + * return the object identifier for the content encryption algorithm. + */ + public string EncryptionAlgOid + { + get { return encAlg.Algorithm.Id; } + } + + /** + * return a store of the intended recipients for this message + */ + public RecipientInformationStore GetRecipientInfos() + { + return recipientInfoStore; + } + + /** + * return the ContentInfo + */ + public ContentInfo ContentInfo + { + get { return contentInfo; } + } + + /** + * return a table of the unprotected attributes indexed by + * the OID of the attribute. + */ + public Asn1.Cms.AttributeTable GetUnprotectedAttributes() + { + if (unprotectedAttributes == null) + return null; + + return new Asn1.Cms.AttributeTable(unprotectedAttributes); + } + + /** + * return the ASN.1 encoded representation of this object. + */ + public byte[] GetEncoded() + { + return contentInfo.GetEncoded(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSEnvelopedData.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSEnvelopedData.cs.meta new file mode 100644 index 0000000..673c739 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSEnvelopedData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ef410c0776df2804a9fa5fd61bb4f3ba +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSEnvelopedDataGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSEnvelopedDataGenerator.cs new file mode 100644 index 0000000..c844ca6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSEnvelopedDataGenerator.cs @@ -0,0 +1,247 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Oiw; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.IO; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Date; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.Cms +{ + /// + /// General class for generating a CMS enveloped-data message. + /// + /// A simple example of usage. + /// + ///
+    ///      CmsEnvelopedDataGenerator  fact = new CmsEnvelopedDataGenerator();
+    ///
+    ///      fact.AddKeyTransRecipient(cert);
+    ///
+    ///      CmsEnvelopedData         data = fact.Generate(content, algorithm);
+    /// 
+ ///
+ public class CmsEnvelopedDataGenerator + : CmsEnvelopedGenerator + { + public CmsEnvelopedDataGenerator() + { + } + + /// Constructor allowing specific source of randomness + /// Instance of SecureRandom to use. + public CmsEnvelopedDataGenerator( + SecureRandom rand) + : base(rand) + { + } + + /// + /// Generate an enveloped object that contains a CMS Enveloped Data + /// object using the passed in key generator. + /// + private CmsEnvelopedData Generate( + CmsProcessable content, + string encryptionOid, + CipherKeyGenerator keyGen) + { + AlgorithmIdentifier encAlgId = null; + KeyParameter encKey; + Asn1OctetString encContent; + + try + { + byte[] encKeyBytes = keyGen.GenerateKey(); + encKey = ParameterUtilities.CreateKeyParameter(encryptionOid, encKeyBytes); + + Asn1Encodable asn1Params = GenerateAsn1Parameters(encryptionOid, encKeyBytes); + + ICipherParameters cipherParameters; + encAlgId = GetAlgorithmIdentifier( + encryptionOid, encKey, asn1Params, out cipherParameters); + + IBufferedCipher cipher = CipherUtilities.GetCipher(encryptionOid); + cipher.Init(true, new ParametersWithRandom(cipherParameters, rand)); + + MemoryStream bOut = new MemoryStream(); + CipherStream cOut = new CipherStream(bOut, null, cipher); + + content.Write(cOut); + + Platform.Dispose(cOut); + + encContent = new BerOctetString(bOut.ToArray()); + } + catch (SecurityUtilityException e) + { + throw new CmsException("couldn't create cipher.", e); + } + catch (InvalidKeyException e) + { + throw new CmsException("key invalid in message.", e); + } + catch (IOException e) + { + throw new CmsException("exception decoding algorithm parameters.", e); + } + + + Asn1EncodableVector recipientInfos = new Asn1EncodableVector(); + + foreach (RecipientInfoGenerator rig in recipientInfoGenerators) + { + try + { + recipientInfos.Add(rig.Generate(encKey, rand)); + } + catch (InvalidKeyException e) + { + throw new CmsException("key inappropriate for algorithm.", e); + } + catch (GeneralSecurityException e) + { + throw new CmsException("error making encrypted content.", e); + } + } + + EncryptedContentInfo eci = new EncryptedContentInfo( + CmsObjectIdentifiers.Data, + encAlgId, + encContent); + + Asn1Set unprotectedAttrSet = null; + if (unprotectedAttributeGenerator != null) + { + Asn1.Cms.AttributeTable attrTable = unprotectedAttributeGenerator.GetAttributes(Platform.CreateHashtable()); + + unprotectedAttrSet = new BerSet(attrTable.ToAsn1EncodableVector()); + } + + ContentInfo contentInfo = new ContentInfo( + CmsObjectIdentifiers.EnvelopedData, + new EnvelopedData(null, new DerSet(recipientInfos), eci, unprotectedAttrSet)); + + return new CmsEnvelopedData(contentInfo); + } + + /// Generate an enveloped object that contains an CMS Enveloped Data object. + public CmsEnvelopedData Generate( + CmsProcessable content, + string encryptionOid) + { + try + { + CipherKeyGenerator keyGen = GeneratorUtilities.GetKeyGenerator(encryptionOid); + + keyGen.Init(new KeyGenerationParameters(rand, keyGen.DefaultStrength)); + + return Generate(content, encryptionOid, keyGen); + } + catch (SecurityUtilityException e) + { + throw new CmsException("can't find key generation algorithm.", e); + } + } + + + public CmsEnvelopedData Generate(CmsProcessable content, ICipherBuilderWithKey cipherBuilder) + { + //AlgorithmIdentifier encAlgId = null; + KeyParameter encKey; + Asn1OctetString encContent; + + try + { + encKey = (KeyParameter) cipherBuilder.Key; + + MemoryStream collector = new MemoryStream(); + Stream bOut = cipherBuilder.BuildCipher(collector).Stream; + content.Write(bOut); + Platform.Dispose(bOut); + encContent = new BerOctetString(collector.ToArray()); + } + catch (SecurityUtilityException e) + { + throw new CmsException("couldn't create cipher.", e); + } + catch (InvalidKeyException e) + { + throw new CmsException("key invalid in message.", e); + } + catch (IOException e) + { + throw new CmsException("exception decoding algorithm parameters.", e); + } + + + Asn1EncodableVector recipientInfos = new Asn1EncodableVector(); + + foreach (RecipientInfoGenerator rig in recipientInfoGenerators) + { + try + { + recipientInfos.Add(rig.Generate(encKey, rand)); + } + catch (InvalidKeyException e) + { + throw new CmsException("key inappropriate for algorithm.", e); + } + catch (GeneralSecurityException e) + { + throw new CmsException("error making encrypted content.", e); + } + } + + EncryptedContentInfo eci = new EncryptedContentInfo( + CmsObjectIdentifiers.Data, + (AlgorithmIdentifier) cipherBuilder.AlgorithmDetails, + encContent); + + Asn1Set unprotectedAttrSet = null; + if (unprotectedAttributeGenerator != null) + { + Asn1.Cms.AttributeTable attrTable = unprotectedAttributeGenerator.GetAttributes(Platform.CreateHashtable()); + + unprotectedAttrSet = new BerSet(attrTable.ToAsn1EncodableVector()); + } + + ContentInfo contentInfo = new ContentInfo( + CmsObjectIdentifiers.EnvelopedData, + new EnvelopedData(null, new DerSet(recipientInfos), eci, unprotectedAttrSet)); + + return new CmsEnvelopedData(contentInfo); + } + + /// Generate an enveloped object that contains an CMS Enveloped Data object. + public CmsEnvelopedData Generate( + CmsProcessable content, + string encryptionOid, + int keySize) + { + try + { + CipherKeyGenerator keyGen = GeneratorUtilities.GetKeyGenerator(encryptionOid); + + keyGen.Init(new KeyGenerationParameters(rand, keySize)); + + return Generate(content, encryptionOid, keyGen); + } + catch (SecurityUtilityException e) + { + throw new CmsException("can't find key generation algorithm.", e); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSEnvelopedDataGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSEnvelopedDataGenerator.cs.meta new file mode 100644 index 0000000..e0ce92d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSEnvelopedDataGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f21a80d552c7ae24faeae09c6788cc3a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSEnvelopedDataParser.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSEnvelopedDataParser.cs new file mode 100644 index 0000000..d5dfaf5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSEnvelopedDataParser.cs @@ -0,0 +1,161 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; + +namespace Org.BouncyCastle.Cms +{ + /** + * Parsing class for an CMS Enveloped Data object from an input stream. + *

+ * Note: that because we are in a streaming mode only one recipient can be tried and it is important + * that the methods on the parser are called in the appropriate order. + *

+ *

+ * Example of use - assuming the first recipient matches the private key we have. + *

+	*      CmsEnvelopedDataParser     ep = new CmsEnvelopedDataParser(inputStream);
+	*
+	*      RecipientInformationStore  recipients = ep.GetRecipientInfos();
+	*
+	*      Collection  c = recipients.getRecipients();
+	*      Iterator    it = c.iterator();
+	*
+	*      if (it.hasNext())
+	*      {
+	*          RecipientInformation   recipient = (RecipientInformation)it.next();
+	*
+	*          CMSTypedStream recData = recipient.getContentStream(privateKey);
+	*
+	*          processDataStream(recData.getContentStream());
+	*      }
+	*  
+ * Note: this class does not introduce buffering - if you are processing large files you should create + * the parser with: + *
+	*          CmsEnvelopedDataParser     ep = new CmsEnvelopedDataParser(new BufferedInputStream(inputStream, bufSize));
+	*  
+ * where bufSize is a suitably large buffer size. + *

+ */ + public class CmsEnvelopedDataParser + : CmsContentInfoParser + { + internal RecipientInformationStore recipientInfoStore; + internal EnvelopedDataParser envelopedData; + + private AlgorithmIdentifier _encAlg; + private Asn1.Cms.AttributeTable _unprotectedAttributes; + private bool _attrNotRead; + + public CmsEnvelopedDataParser( + byte[] envelopedData) + : this(new MemoryStream(envelopedData, false)) + { + } + + public CmsEnvelopedDataParser( + Stream envelopedData) + : base(envelopedData) + { + this._attrNotRead = true; + this.envelopedData = new EnvelopedDataParser( + (Asn1SequenceParser)this.contentInfo.GetContent(Asn1Tags.Sequence)); + + // TODO Validate version? + //DerInteger version = this.envelopedData.Version; + + // + // read the recipients + // + Asn1Set recipientInfos = Asn1Set.GetInstance(this.envelopedData.GetRecipientInfos().ToAsn1Object()); + + // + // read the encrypted content info + // + EncryptedContentInfoParser encInfo = this.envelopedData.GetEncryptedContentInfo(); + this._encAlg = encInfo.ContentEncryptionAlgorithm; + CmsReadable readable = new CmsProcessableInputStream( + ((Asn1OctetStringParser)encInfo.GetEncryptedContent(Asn1Tags.OctetString)).GetOctetStream()); + CmsSecureReadable secureReadable = new CmsEnvelopedHelper.CmsEnvelopedSecureReadable( + this._encAlg, readable); + + // + // build the RecipientInformationStore + // + this.recipientInfoStore = CmsEnvelopedHelper.BuildRecipientInformationStore( + recipientInfos, secureReadable); + } + + public AlgorithmIdentifier EncryptionAlgorithmID + { + get { return _encAlg; } + } + + /** + * return the object identifier for the content encryption algorithm. + */ + public string EncryptionAlgOid + { + get { return _encAlg.Algorithm.Id; } + } + + /** + * return the ASN.1 encoded encryption algorithm parameters, or null if + * there aren't any. + */ + public Asn1Object EncryptionAlgParams + { + get + { + Asn1Encodable ae = _encAlg.Parameters; + + return ae == null ? null : ae.ToAsn1Object(); + } + } + + /** + * return a store of the intended recipients for this message + */ + public RecipientInformationStore GetRecipientInfos() + { + return this.recipientInfoStore; + } + + /** + * return a table of the unprotected attributes indexed by + * the OID of the attribute. + * @throws IOException + */ + public Asn1.Cms.AttributeTable GetUnprotectedAttributes() + { + if (_unprotectedAttributes == null && _attrNotRead) + { + Asn1SetParser asn1Set = this.envelopedData.GetUnprotectedAttrs(); + + _attrNotRead = false; + + if (asn1Set != null) + { + Asn1EncodableVector v = new Asn1EncodableVector(); + IAsn1Convertible o; + + while ((o = asn1Set.ReadObject()) != null) + { + Asn1SequenceParser seq = (Asn1SequenceParser)o; + + v.Add(seq.ToAsn1Object()); + } + + _unprotectedAttributes = new Asn1.Cms.AttributeTable(new DerSet(v)); + } + } + + return _unprotectedAttributes; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSEnvelopedDataParser.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSEnvelopedDataParser.cs.meta new file mode 100644 index 0000000..2fc6be6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSEnvelopedDataParser.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e86fdda46e7c4884486e5eedcbab4bce +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSEnvelopedDataStreamGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSEnvelopedDataStreamGenerator.cs new file mode 100644 index 0000000..e0822aa --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSEnvelopedDataStreamGenerator.cs @@ -0,0 +1,308 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.IO; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Security.Certificates; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.Cms +{ + /** + * General class for generating a CMS enveloped-data message stream. + *

+ * A simple example of usage. + *

+	*      CmsEnvelopedDataStreamGenerator edGen = new CmsEnvelopedDataStreamGenerator();
+	*
+	*      edGen.AddKeyTransRecipient(cert);
+	*
+	*      MemoryStream  bOut = new MemoryStream();
+	*
+	*      Stream out = edGen.Open(
+	*                              bOut, CMSEnvelopedDataGenerator.AES128_CBC);*
+	*      out.Write(data);
+	*
+	*      out.Close();
+	* 
+ *

+ */ + public class CmsEnvelopedDataStreamGenerator + : CmsEnvelopedGenerator + { + private object _originatorInfo = null; + private object _unprotectedAttributes = null; + private int _bufferSize; + private bool _berEncodeRecipientSet; + + public CmsEnvelopedDataStreamGenerator() + { + } + + /// Constructor allowing specific source of randomness + /// Instance of SecureRandom to use. + public CmsEnvelopedDataStreamGenerator( + SecureRandom rand) + : base(rand) + { + } + + /// Set the underlying string size for encapsulated data. + /// Length of octet strings to buffer the data. + public void SetBufferSize( + int bufferSize) + { + _bufferSize = bufferSize; + } + + /// Use a BER Set to store the recipient information. + public void SetBerEncodeRecipients( + bool berEncodeRecipientSet) + { + _berEncodeRecipientSet = berEncodeRecipientSet; + } + + private DerInteger Version + { + get + { + int version = (_originatorInfo != null || _unprotectedAttributes != null) + ? 2 + : 0; + + return new DerInteger(version); + } + } + + /// + /// Generate an enveloped object that contains an CMS Enveloped Data + /// object using the passed in key generator. + /// + private Stream Open( + Stream outStream, + string encryptionOid, + CipherKeyGenerator keyGen) + { + byte[] encKeyBytes = keyGen.GenerateKey(); + KeyParameter encKey = ParameterUtilities.CreateKeyParameter(encryptionOid, encKeyBytes); + + Asn1Encodable asn1Params = GenerateAsn1Parameters(encryptionOid, encKeyBytes); + + ICipherParameters cipherParameters; + AlgorithmIdentifier encAlgID = GetAlgorithmIdentifier( + encryptionOid, encKey, asn1Params, out cipherParameters); + + Asn1EncodableVector recipientInfos = new Asn1EncodableVector(); + + foreach (RecipientInfoGenerator rig in recipientInfoGenerators) + { + try + { + recipientInfos.Add(rig.Generate(encKey, rand)); + } + catch (InvalidKeyException e) + { + throw new CmsException("key inappropriate for algorithm.", e); + } + catch (GeneralSecurityException e) + { + throw new CmsException("error making encrypted content.", e); + } + } + + return Open(outStream, encAlgID, cipherParameters, recipientInfos); + } + + private Stream Open( + Stream outStream, + AlgorithmIdentifier encAlgID, + ICipherParameters cipherParameters, + Asn1EncodableVector recipientInfos) + { + try + { + // + // ContentInfo + // + BerSequenceGenerator cGen = new BerSequenceGenerator(outStream); + + cGen.AddObject(CmsObjectIdentifiers.EnvelopedData); + + // + // Encrypted Data + // + BerSequenceGenerator envGen = new BerSequenceGenerator( + cGen.GetRawOutputStream(), 0, true); + + envGen.AddObject(this.Version); + + Stream envRaw = envGen.GetRawOutputStream(); + Asn1Generator recipGen = _berEncodeRecipientSet + ? (Asn1Generator) new BerSetGenerator(envRaw) + : new DerSetGenerator(envRaw); + + foreach (Asn1Encodable ae in recipientInfos) + { + recipGen.AddObject(ae); + } + + recipGen.Close(); + + BerSequenceGenerator eiGen = new BerSequenceGenerator(envRaw); + eiGen.AddObject(CmsObjectIdentifiers.Data); + eiGen.AddObject(encAlgID); + + Stream octetOutputStream = CmsUtilities.CreateBerOctetOutputStream( + eiGen.GetRawOutputStream(), 0, false, _bufferSize); + + IBufferedCipher cipher = CipherUtilities.GetCipher(encAlgID.Algorithm); + cipher.Init(true, new ParametersWithRandom(cipherParameters, rand)); + CipherStream cOut = new CipherStream(octetOutputStream, null, cipher); + + return new CmsEnvelopedDataOutputStream(this, cOut, cGen, envGen, eiGen); + } + catch (SecurityUtilityException e) + { + throw new CmsException("couldn't create cipher.", e); + } + catch (InvalidKeyException e) + { + throw new CmsException("key invalid in message.", e); + } + catch (IOException e) + { + throw new CmsException("exception decoding algorithm parameters.", e); + } + } + + /** + * generate an enveloped object that contains an CMS Enveloped Data object + * @throws IOException + */ + public Stream Open( + Stream outStream, + string encryptionOid) + { + CipherKeyGenerator keyGen = GeneratorUtilities.GetKeyGenerator(encryptionOid); + + keyGen.Init(new KeyGenerationParameters(rand, keyGen.DefaultStrength)); + + return Open(outStream, encryptionOid, keyGen); + } + + /** + * generate an enveloped object that contains an CMS Enveloped Data object + * @throws IOException + */ + public Stream Open( + Stream outStream, + string encryptionOid, + int keySize) + { + CipherKeyGenerator keyGen = GeneratorUtilities.GetKeyGenerator(encryptionOid); + + keyGen.Init(new KeyGenerationParameters(rand, keySize)); + + return Open(outStream, encryptionOid, keyGen); + } + + private class CmsEnvelopedDataOutputStream + : BaseOutputStream + { + private readonly CmsEnvelopedGenerator _outer; + + private readonly CipherStream _out; + private readonly BerSequenceGenerator _cGen; + private readonly BerSequenceGenerator _envGen; + private readonly BerSequenceGenerator _eiGen; + + public CmsEnvelopedDataOutputStream( + CmsEnvelopedGenerator outer, + CipherStream outStream, + BerSequenceGenerator cGen, + BerSequenceGenerator envGen, + BerSequenceGenerator eiGen) + { + _outer = outer; + _out = outStream; + _cGen = cGen; + _envGen = envGen; + _eiGen = eiGen; + } + + public override void WriteByte( + byte b) + { + _out.WriteByte(b); + } + + public override void Write( + byte[] bytes, + int off, + int len) + { + _out.Write(bytes, off, len); + } + +#if PORTABLE + protected override void Dispose(bool disposing) + { + if (disposing) + { + Platform.Dispose(_out); + + // TODO Parent context(s) should really be closed explicitly + + _eiGen.Close(); + + if (_outer.unprotectedAttributeGenerator != null) + { + Asn1.Cms.AttributeTable attrTable = _outer.unprotectedAttributeGenerator.GetAttributes(Platform.CreateHashtable()); + + Asn1Set unprotectedAttrs = new BerSet(attrTable.ToAsn1EncodableVector()); + + _envGen.AddObject(new DerTaggedObject(false, 1, unprotectedAttrs)); + } + + _envGen.Close(); + _cGen.Close(); + } + base.Dispose(disposing); + } +#else + public override void Close() + { + Platform.Dispose(_out); + + // TODO Parent context(s) should really be closed explicitly + + _eiGen.Close(); + + if (_outer.unprotectedAttributeGenerator != null) + { + Asn1.Cms.AttributeTable attrTable = _outer.unprotectedAttributeGenerator.GetAttributes(Platform.CreateHashtable()); + + Asn1Set unprotectedAttrs = new BerSet(attrTable.ToAsn1EncodableVector()); + + _envGen.AddObject(new DerTaggedObject(false, 1, unprotectedAttrs)); + } + + _envGen.Close(); + _cGen.Close(); + base.Close(); + } +#endif + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSEnvelopedDataStreamGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSEnvelopedDataStreamGenerator.cs.meta new file mode 100644 index 0000000..8773bdb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSEnvelopedDataStreamGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bd5942a984a5dc1449b3e6237932d241 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSEnvelopedGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSEnvelopedGenerator.cs new file mode 100644 index 0000000..d7d3e4b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSEnvelopedGenerator.cs @@ -0,0 +1,338 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Asn1.Kisa; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Ntt; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Operators; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.Cms +{ + /** + * General class for generating a CMS enveloped-data message. + * + * A simple example of usage. + * + *
+	*      CMSEnvelopedDataGenerator  fact = new CMSEnvelopedDataGenerator();
+	*
+	*      fact.addKeyTransRecipient(cert);
+	*
+	*      CMSEnvelopedData         data = fact.generate(content, algorithm, "BC");
+	* 
+ */ + public class CmsEnvelopedGenerator + { + // Note: These tables are complementary: If rc2Table[i]==j, then rc2Ekb[j]==i + internal static readonly short[] rc2Table = + { + 0xbd, 0x56, 0xea, 0xf2, 0xa2, 0xf1, 0xac, 0x2a, 0xb0, 0x93, 0xd1, 0x9c, 0x1b, 0x33, 0xfd, 0xd0, + 0x30, 0x04, 0xb6, 0xdc, 0x7d, 0xdf, 0x32, 0x4b, 0xf7, 0xcb, 0x45, 0x9b, 0x31, 0xbb, 0x21, 0x5a, + 0x41, 0x9f, 0xe1, 0xd9, 0x4a, 0x4d, 0x9e, 0xda, 0xa0, 0x68, 0x2c, 0xc3, 0x27, 0x5f, 0x80, 0x36, + 0x3e, 0xee, 0xfb, 0x95, 0x1a, 0xfe, 0xce, 0xa8, 0x34, 0xa9, 0x13, 0xf0, 0xa6, 0x3f, 0xd8, 0x0c, + 0x78, 0x24, 0xaf, 0x23, 0x52, 0xc1, 0x67, 0x17, 0xf5, 0x66, 0x90, 0xe7, 0xe8, 0x07, 0xb8, 0x60, + 0x48, 0xe6, 0x1e, 0x53, 0xf3, 0x92, 0xa4, 0x72, 0x8c, 0x08, 0x15, 0x6e, 0x86, 0x00, 0x84, 0xfa, + 0xf4, 0x7f, 0x8a, 0x42, 0x19, 0xf6, 0xdb, 0xcd, 0x14, 0x8d, 0x50, 0x12, 0xba, 0x3c, 0x06, 0x4e, + 0xec, 0xb3, 0x35, 0x11, 0xa1, 0x88, 0x8e, 0x2b, 0x94, 0x99, 0xb7, 0x71, 0x74, 0xd3, 0xe4, 0xbf, + 0x3a, 0xde, 0x96, 0x0e, 0xbc, 0x0a, 0xed, 0x77, 0xfc, 0x37, 0x6b, 0x03, 0x79, 0x89, 0x62, 0xc6, + 0xd7, 0xc0, 0xd2, 0x7c, 0x6a, 0x8b, 0x22, 0xa3, 0x5b, 0x05, 0x5d, 0x02, 0x75, 0xd5, 0x61, 0xe3, + 0x18, 0x8f, 0x55, 0x51, 0xad, 0x1f, 0x0b, 0x5e, 0x85, 0xe5, 0xc2, 0x57, 0x63, 0xca, 0x3d, 0x6c, + 0xb4, 0xc5, 0xcc, 0x70, 0xb2, 0x91, 0x59, 0x0d, 0x47, 0x20, 0xc8, 0x4f, 0x58, 0xe0, 0x01, 0xe2, + 0x16, 0x38, 0xc4, 0x6f, 0x3b, 0x0f, 0x65, 0x46, 0xbe, 0x7e, 0x2d, 0x7b, 0x82, 0xf9, 0x40, 0xb5, + 0x1d, 0x73, 0xf8, 0xeb, 0x26, 0xc7, 0x87, 0x97, 0x25, 0x54, 0xb1, 0x28, 0xaa, 0x98, 0x9d, 0xa5, + 0x64, 0x6d, 0x7a, 0xd4, 0x10, 0x81, 0x44, 0xef, 0x49, 0xd6, 0xae, 0x2e, 0xdd, 0x76, 0x5c, 0x2f, + 0xa7, 0x1c, 0xc9, 0x09, 0x69, 0x9a, 0x83, 0xcf, 0x29, 0x39, 0xb9, 0xe9, 0x4c, 0xff, 0x43, 0xab + }; + +// internal static readonly short[] rc2Ekb = +// { +// 0x5d, 0xbe, 0x9b, 0x8b, 0x11, 0x99, 0x6e, 0x4d, 0x59, 0xf3, 0x85, 0xa6, 0x3f, 0xb7, 0x83, 0xc5, +// 0xe4, 0x73, 0x6b, 0x3a, 0x68, 0x5a, 0xc0, 0x47, 0xa0, 0x64, 0x34, 0x0c, 0xf1, 0xd0, 0x52, 0xa5, +// 0xb9, 0x1e, 0x96, 0x43, 0x41, 0xd8, 0xd4, 0x2c, 0xdb, 0xf8, 0x07, 0x77, 0x2a, 0xca, 0xeb, 0xef, +// 0x10, 0x1c, 0x16, 0x0d, 0x38, 0x72, 0x2f, 0x89, 0xc1, 0xf9, 0x80, 0xc4, 0x6d, 0xae, 0x30, 0x3d, +// 0xce, 0x20, 0x63, 0xfe, 0xe6, 0x1a, 0xc7, 0xb8, 0x50, 0xe8, 0x24, 0x17, 0xfc, 0x25, 0x6f, 0xbb, +// 0x6a, 0xa3, 0x44, 0x53, 0xd9, 0xa2, 0x01, 0xab, 0xbc, 0xb6, 0x1f, 0x98, 0xee, 0x9a, 0xa7, 0x2d, +// 0x4f, 0x9e, 0x8e, 0xac, 0xe0, 0xc6, 0x49, 0x46, 0x29, 0xf4, 0x94, 0x8a, 0xaf, 0xe1, 0x5b, 0xc3, +// 0xb3, 0x7b, 0x57, 0xd1, 0x7c, 0x9c, 0xed, 0x87, 0x40, 0x8c, 0xe2, 0xcb, 0x93, 0x14, 0xc9, 0x61, +// 0x2e, 0xe5, 0xcc, 0xf6, 0x5e, 0xa8, 0x5c, 0xd6, 0x75, 0x8d, 0x62, 0x95, 0x58, 0x69, 0x76, 0xa1, +// 0x4a, 0xb5, 0x55, 0x09, 0x78, 0x33, 0x82, 0xd7, 0xdd, 0x79, 0xf5, 0x1b, 0x0b, 0xde, 0x26, 0x21, +// 0x28, 0x74, 0x04, 0x97, 0x56, 0xdf, 0x3c, 0xf0, 0x37, 0x39, 0xdc, 0xff, 0x06, 0xa4, 0xea, 0x42, +// 0x08, 0xda, 0xb4, 0x71, 0xb0, 0xcf, 0x12, 0x7a, 0x4e, 0xfa, 0x6c, 0x1d, 0x84, 0x00, 0xc8, 0x7f, +// 0x91, 0x45, 0xaa, 0x2b, 0xc2, 0xb1, 0x8f, 0xd5, 0xba, 0xf2, 0xad, 0x19, 0xb2, 0x67, 0x36, 0xf7, +// 0x0f, 0x0a, 0x92, 0x7d, 0xe3, 0x9d, 0xe9, 0x90, 0x3e, 0x23, 0x27, 0x66, 0x13, 0xec, 0x81, 0x15, +// 0xbd, 0x22, 0xbf, 0x9f, 0x7e, 0xa9, 0x51, 0x4b, 0x4c, 0xfb, 0x02, 0xd3, 0x70, 0x86, 0x31, 0xe7, +// 0x3b, 0x05, 0x03, 0x54, 0x60, 0x48, 0x65, 0x18, 0xd2, 0xcd, 0x5f, 0x32, 0x88, 0x0e, 0x35, 0xfd +// }; + + + // TODO Create named constants for all of these + public static readonly string DesEde3Cbc = PkcsObjectIdentifiers.DesEde3Cbc.Id; + public static readonly string RC2Cbc = PkcsObjectIdentifiers.RC2Cbc.Id; + public const string IdeaCbc = "1.3.6.1.4.1.188.7.1.1.2"; + public const string Cast5Cbc = "1.2.840.113533.7.66.10"; + public static readonly string Aes128Cbc = NistObjectIdentifiers.IdAes128Cbc.Id; + public static readonly string Aes192Cbc = NistObjectIdentifiers.IdAes192Cbc.Id; + public static readonly string Aes256Cbc = NistObjectIdentifiers.IdAes256Cbc.Id; + public static readonly string Camellia128Cbc = NttObjectIdentifiers.IdCamellia128Cbc.Id; + public static readonly string Camellia192Cbc = NttObjectIdentifiers.IdCamellia192Cbc.Id; + public static readonly string Camellia256Cbc = NttObjectIdentifiers.IdCamellia256Cbc.Id; + public static readonly string SeedCbc = KisaObjectIdentifiers.IdSeedCbc.Id; + + public static readonly string DesEde3Wrap = PkcsObjectIdentifiers.IdAlgCms3DesWrap.Id; + public static readonly string Aes128Wrap = NistObjectIdentifiers.IdAes128Wrap.Id; + public static readonly string Aes192Wrap = NistObjectIdentifiers.IdAes192Wrap.Id; + public static readonly string Aes256Wrap = NistObjectIdentifiers.IdAes256Wrap.Id; + public static readonly string Camellia128Wrap = NttObjectIdentifiers.IdCamellia128Wrap.Id; + public static readonly string Camellia192Wrap = NttObjectIdentifiers.IdCamellia192Wrap.Id; + public static readonly string Camellia256Wrap = NttObjectIdentifiers.IdCamellia256Wrap.Id; + public static readonly string SeedWrap = KisaObjectIdentifiers.IdNpkiAppCmsSeedWrap.Id; + + public static readonly string ECDHSha1Kdf = X9ObjectIdentifiers.DHSinglePassStdDHSha1KdfScheme.Id; + public static readonly string ECMqvSha1Kdf = X9ObjectIdentifiers.MqvSinglePassSha1KdfScheme.Id; + + internal readonly IList recipientInfoGenerators = Platform.CreateArrayList(); + internal readonly SecureRandom rand; + + internal CmsAttributeTableGenerator unprotectedAttributeGenerator = null; + + public CmsEnvelopedGenerator() + : this(new SecureRandom()) + { + } + + /// Constructor allowing specific source of randomness + /// Instance of SecureRandom to use. + public CmsEnvelopedGenerator( + SecureRandom rand) + { + this.rand = rand; + } + + public CmsAttributeTableGenerator UnprotectedAttributeGenerator + { + get { return this.unprotectedAttributeGenerator; } + set { this.unprotectedAttributeGenerator = value; } + } + + /** + * add a recipient. + * + * @param cert recipient's public key certificate + * @exception ArgumentException if there is a problem with the certificate + */ + public void AddKeyTransRecipient( + X509Certificate cert) + { + TbsCertificateStructure recipientTbsCert = CmsUtilities.GetTbsCertificateStructure(cert); + SubjectPublicKeyInfo info = recipientTbsCert.SubjectPublicKeyInfo; + this.AddRecipientInfoGenerator(new KeyTransRecipientInfoGenerator(cert, new Asn1KeyWrapper(info.AlgorithmID.Algorithm, info.AlgorithmID.Parameters, cert))); + } + + /** + * add a recipient + * + * @param key the public key used by the recipient + * @param subKeyId the identifier for the recipient's public key + * @exception ArgumentException if there is a problem with the key + */ + public void AddKeyTransRecipient( + AsymmetricKeyParameter pubKey, + byte[] subKeyId) + { + SubjectPublicKeyInfo info = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(pubKey); + this.AddRecipientInfoGenerator(new KeyTransRecipientInfoGenerator(subKeyId, new Asn1KeyWrapper(info.AlgorithmID.Algorithm, info.AlgorithmID.Parameters, pubKey))); + } + + /** + * add a KEK recipient. + * @param key the secret key to use for wrapping + * @param keyIdentifier the byte string that identifies the key + */ + public void AddKekRecipient( + string keyAlgorithm, // TODO Remove need for this parameter + KeyParameter key, + byte[] keyIdentifier) + { + AddKekRecipient(keyAlgorithm, key, new KekIdentifier(keyIdentifier, null, null)); + } + + /** + * add a KEK recipient. + * @param key the secret key to use for wrapping + * @param keyIdentifier the byte string that identifies the key + */ + public void AddKekRecipient( + string keyAlgorithm, // TODO Remove need for this parameter + KeyParameter key, + KekIdentifier kekIdentifier) + { + KekRecipientInfoGenerator kekrig = new KekRecipientInfoGenerator(); + kekrig.KekIdentifier = kekIdentifier; + kekrig.KeyEncryptionKeyOID = keyAlgorithm; + kekrig.KeyEncryptionKey = key; + + recipientInfoGenerators.Add(kekrig); + } + + public void AddPasswordRecipient( + CmsPbeKey pbeKey, + string kekAlgorithmOid) + { + Pbkdf2Params p = new Pbkdf2Params(pbeKey.Salt, pbeKey.IterationCount); + + PasswordRecipientInfoGenerator prig = new PasswordRecipientInfoGenerator(); + prig.KeyDerivationAlgorithm = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdPbkdf2, p); + prig.KeyEncryptionKeyOID = kekAlgorithmOid; + prig.KeyEncryptionKey = pbeKey.GetEncoded(kekAlgorithmOid); + + recipientInfoGenerators.Add(prig); + } + + /** + * Add a key agreement based recipient. + * + * @param agreementAlgorithm key agreement algorithm to use. + * @param senderPrivateKey private key to initialise sender side of agreement with. + * @param senderPublicKey sender public key to include with message. + * @param recipientCert recipient's public key certificate. + * @param cekWrapAlgorithm OID for key wrapping algorithm to use. + * @exception SecurityUtilityException if the algorithm requested cannot be found + * @exception InvalidKeyException if the keys are inappropriate for the algorithm specified + */ + public void AddKeyAgreementRecipient( + string agreementAlgorithm, + AsymmetricKeyParameter senderPrivateKey, + AsymmetricKeyParameter senderPublicKey, + X509Certificate recipientCert, + string cekWrapAlgorithm) + { + IList recipientCerts = Platform.CreateArrayList(1); + recipientCerts.Add(recipientCert); + + AddKeyAgreementRecipients(agreementAlgorithm, senderPrivateKey, senderPublicKey, + recipientCerts, cekWrapAlgorithm); + } + + /** + * Add multiple key agreement based recipients (sharing a single KeyAgreeRecipientInfo structure). + * + * @param agreementAlgorithm key agreement algorithm to use. + * @param senderPrivateKey private key to initialise sender side of agreement with. + * @param senderPublicKey sender public key to include with message. + * @param recipientCerts recipients' public key certificates. + * @param cekWrapAlgorithm OID for key wrapping algorithm to use. + * @exception SecurityUtilityException if the algorithm requested cannot be found + * @exception InvalidKeyException if the keys are inappropriate for the algorithm specified + */ + public void AddKeyAgreementRecipients( + string agreementAlgorithm, + AsymmetricKeyParameter senderPrivateKey, + AsymmetricKeyParameter senderPublicKey, + ICollection recipientCerts, + string cekWrapAlgorithm) + { + if (!senderPrivateKey.IsPrivate) + throw new ArgumentException("Expected private key", "senderPrivateKey"); + if (senderPublicKey.IsPrivate) + throw new ArgumentException("Expected public key", "senderPublicKey"); + + /* TODO + * "a recipient X.509 version 3 certificate that contains a key usage extension MUST + * assert the keyAgreement bit." + */ + + KeyAgreeRecipientInfoGenerator karig = new KeyAgreeRecipientInfoGenerator(); + karig.KeyAgreementOID = new DerObjectIdentifier(agreementAlgorithm); + karig.KeyEncryptionOID = new DerObjectIdentifier(cekWrapAlgorithm); + karig.RecipientCerts = recipientCerts; + karig.SenderKeyPair = new AsymmetricCipherKeyPair(senderPublicKey, senderPrivateKey); + + recipientInfoGenerators.Add(karig); + } + + /// + /// Add a generator to produce the recipient info required. + /// + /// a generator of a recipient info object. + public void AddRecipientInfoGenerator(RecipientInfoGenerator recipientInfoGenerator) + { + recipientInfoGenerators.Add(recipientInfoGenerator); + } + + + protected internal virtual AlgorithmIdentifier GetAlgorithmIdentifier( + string encryptionOid, + KeyParameter encKey, + Asn1Encodable asn1Params, + out ICipherParameters cipherParameters) + { + Asn1Object asn1Object; + if (asn1Params != null) + { + asn1Object = asn1Params.ToAsn1Object(); + cipherParameters = ParameterUtilities.GetCipherParameters( + encryptionOid, encKey, asn1Object); + } + else + { + asn1Object = DerNull.Instance; + cipherParameters = encKey; + } + + return new AlgorithmIdentifier( + new DerObjectIdentifier(encryptionOid), + asn1Object); + } + + protected internal virtual Asn1Encodable GenerateAsn1Parameters( + string encryptionOid, + byte[] encKeyBytes) + { + Asn1Encodable asn1Params = null; + + try + { + if (encryptionOid.Equals(RC2Cbc)) + { + byte[] iv = new byte[8]; + rand.NextBytes(iv); + + // TODO Is this detailed repeat of Java version really necessary? + int effKeyBits = encKeyBytes.Length * 8; + int parameterVersion; + + if (effKeyBits < 256) + { + parameterVersion = rc2Table[effKeyBits]; + } + else + { + parameterVersion = effKeyBits; + } + + asn1Params = new RC2CbcParameter(parameterVersion, iv); + } + else + { + asn1Params = ParameterUtilities.GenerateParameters(encryptionOid, rand); + } + } + catch (SecurityUtilityException) + { + // No problem... no parameters generated + } + + return asn1Params; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSEnvelopedGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSEnvelopedGenerator.cs.meta new file mode 100644 index 0000000..643249c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSEnvelopedGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e36f5b55af9828b43b51e417a1645da9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSEnvelopedHelper.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSEnvelopedHelper.cs new file mode 100644 index 0000000..930ffcb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSEnvelopedHelper.cs @@ -0,0 +1,311 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.IO; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Cms +{ + class CmsEnvelopedHelper + { + internal static readonly CmsEnvelopedHelper Instance = new CmsEnvelopedHelper(); + + private static readonly IDictionary KeySizes = Platform.CreateHashtable(); + private static readonly IDictionary BaseCipherNames = Platform.CreateHashtable(); + + static CmsEnvelopedHelper() + { + KeySizes.Add(CmsEnvelopedGenerator.DesEde3Cbc, 192); + KeySizes.Add(CmsEnvelopedGenerator.Aes128Cbc, 128); + KeySizes.Add(CmsEnvelopedGenerator.Aes192Cbc, 192); + KeySizes.Add(CmsEnvelopedGenerator.Aes256Cbc, 256); + + BaseCipherNames.Add(CmsEnvelopedGenerator.DesEde3Cbc, "DESEDE"); + BaseCipherNames.Add(CmsEnvelopedGenerator.Aes128Cbc, "AES"); + BaseCipherNames.Add(CmsEnvelopedGenerator.Aes192Cbc, "AES"); + BaseCipherNames.Add(CmsEnvelopedGenerator.Aes256Cbc, "AES"); + } + + private string GetAsymmetricEncryptionAlgName( + string encryptionAlgOid) + { + if (Asn1.Pkcs.PkcsObjectIdentifiers.RsaEncryption.Id.Equals(encryptionAlgOid)) + { + return "RSA/ECB/PKCS1Padding"; + } + + return encryptionAlgOid; + } + + internal IBufferedCipher CreateAsymmetricCipher( + string encryptionOid) + { + string asymName = GetAsymmetricEncryptionAlgName(encryptionOid); + if (!asymName.Equals(encryptionOid)) + { + try + { + return CipherUtilities.GetCipher(asymName); + } + catch (SecurityUtilityException) + { + // Ignore + } + } + return CipherUtilities.GetCipher(encryptionOid); + } + + internal IWrapper CreateWrapper( + string encryptionOid) + { + try + { + return WrapperUtilities.GetWrapper(encryptionOid); + } + catch (SecurityUtilityException) + { + return WrapperUtilities.GetWrapper(GetAsymmetricEncryptionAlgName(encryptionOid)); + } + } + + internal string GetRfc3211WrapperName( + string oid) + { + if (oid == null) + throw new ArgumentNullException("oid"); + + string alg = (string) BaseCipherNames[oid]; + + if (alg == null) + throw new ArgumentException("no name for " + oid, "oid"); + + return alg + "RFC3211Wrap"; + } + + internal int GetKeySize( + string oid) + { + if (!KeySizes.Contains(oid)) + { + throw new ArgumentException("no keysize for " + oid, "oid"); + } + + return (int) KeySizes[oid]; + } + + internal static RecipientInformationStore BuildRecipientInformationStore( + Asn1Set recipientInfos, CmsSecureReadable secureReadable) + { + IList infos = Platform.CreateArrayList(); + for (int i = 0; i != recipientInfos.Count; i++) + { + RecipientInfo info = RecipientInfo.GetInstance(recipientInfos[i]); + + ReadRecipientInfo(infos, info, secureReadable); + } + return new RecipientInformationStore(infos); + } + + private static void ReadRecipientInfo( + IList infos, RecipientInfo info, CmsSecureReadable secureReadable) + { + Asn1Encodable recipInfo = info.Info; + if (recipInfo is KeyTransRecipientInfo) + { + infos.Add(new KeyTransRecipientInformation((KeyTransRecipientInfo)recipInfo, secureReadable)); + } + else if (recipInfo is KekRecipientInfo) + { + infos.Add(new KekRecipientInformation((KekRecipientInfo)recipInfo, secureReadable)); + } + else if (recipInfo is KeyAgreeRecipientInfo) + { + KeyAgreeRecipientInformation.ReadRecipientInfo(infos, (KeyAgreeRecipientInfo)recipInfo, secureReadable); + } + else if (recipInfo is PasswordRecipientInfo) + { + infos.Add(new PasswordRecipientInformation((PasswordRecipientInfo)recipInfo, secureReadable)); + } + } + + internal class CmsAuthenticatedSecureReadable : CmsSecureReadable + { + private AlgorithmIdentifier algorithm; + private IMac mac; + private CmsReadable readable; + + internal CmsAuthenticatedSecureReadable(AlgorithmIdentifier algorithm, CmsReadable readable) + { + this.algorithm = algorithm; + this.readable = readable; + } + + public AlgorithmIdentifier Algorithm + { + get { return this.algorithm; } + } + + public object CryptoObject + { + get { return this.mac; } + } + + public CmsReadable GetReadable(KeyParameter sKey) + { + string macAlg = this.algorithm.Algorithm.Id; +// Asn1Object sParams = this.algorithm.Parameters.ToAsn1Object(); + + try + { + this.mac = MacUtilities.GetMac(macAlg); + + // FIXME Support for MAC algorithm parameters similar to cipher parameters +// ASN1Object sParams = (ASN1Object)macAlg.getParameters(); +// +// if (sParams != null && !(sParams instanceof ASN1Null)) +// { +// AlgorithmParameters params = CMSEnvelopedHelper.INSTANCE.createAlgorithmParameters(macAlg.getObjectId().getId(), provider); +// +// params.init(sParams.getEncoded(), "ASN.1"); +// +// mac.init(sKey, params.getParameterSpec(IvParameterSpec.class)); +// } +// else + { + mac.Init(sKey); + } + +// Asn1Object asn1Params = asn1Enc == null ? null : asn1Enc.ToAsn1Object(); +// +// ICipherParameters cipherParameters = sKey; +// +// if (asn1Params != null && !(asn1Params is Asn1Null)) +// { +// cipherParameters = ParameterUtilities.GetCipherParameters( +// macAlg.Algorithm, cipherParameters, asn1Params); +// } +// else +// { +// string alg = macAlg.Algorithm.Id; +// if (alg.Equals(CmsEnvelopedDataGenerator.DesEde3Cbc) +// || alg.Equals(CmsEnvelopedDataGenerator.IdeaCbc) +// || alg.Equals(CmsEnvelopedDataGenerator.Cast5Cbc)) +// { +// cipherParameters = new ParametersWithIV(cipherParameters, new byte[8]); +// } +// } +// +// mac.Init(cipherParameters); + } + catch (SecurityUtilityException e) + { + throw new CmsException("couldn't create cipher.", e); + } + catch (InvalidKeyException e) + { + throw new CmsException("key invalid in message.", e); + } + catch (IOException e) + { + throw new CmsException("error decoding algorithm parameters.", e); + } + + try + { + return new CmsProcessableInputStream( + new TeeInputStream( + readable.GetInputStream(), + new MacSink(this.mac))); + } + catch (IOException e) + { + throw new CmsException("error reading content.", e); + } + } + } + + internal class CmsEnvelopedSecureReadable : CmsSecureReadable + { + private AlgorithmIdentifier algorithm; + private IBufferedCipher cipher; + private CmsReadable readable; + + internal CmsEnvelopedSecureReadable(AlgorithmIdentifier algorithm, CmsReadable readable) + { + this.algorithm = algorithm; + this.readable = readable; + } + + public AlgorithmIdentifier Algorithm + { + get { return this.algorithm; } + } + + public object CryptoObject + { + get { return this.cipher; } + } + + public CmsReadable GetReadable(KeyParameter sKey) + { + try + { + this.cipher = CipherUtilities.GetCipher(this.algorithm.Algorithm); + + Asn1Encodable asn1Enc = this.algorithm.Parameters; + Asn1Object asn1Params = asn1Enc == null ? null : asn1Enc.ToAsn1Object(); + + ICipherParameters cipherParameters = sKey; + + if (asn1Params != null && !(asn1Params is Asn1Null)) + { + cipherParameters = ParameterUtilities.GetCipherParameters( + this.algorithm.Algorithm, cipherParameters, asn1Params); + } + else + { + string alg = this.algorithm.Algorithm.Id; + if (alg.Equals(CmsEnvelopedDataGenerator.DesEde3Cbc) + || alg.Equals(CmsEnvelopedDataGenerator.IdeaCbc) + || alg.Equals(CmsEnvelopedDataGenerator.Cast5Cbc)) + { + cipherParameters = new ParametersWithIV(cipherParameters, new byte[8]); + } + } + + cipher.Init(false, cipherParameters); + } + catch (SecurityUtilityException e) + { + throw new CmsException("couldn't create cipher.", e); + } + catch (InvalidKeyException e) + { + throw new CmsException("key invalid in message.", e); + } + catch (IOException e) + { + throw new CmsException("error decoding algorithm parameters.", e); + } + + try + { + return new CmsProcessableInputStream( + new CipherStream(readable.GetInputStream(), cipher, null)); + } + catch (IOException e) + { + throw new CmsException("error reading content.", e); + } + } + } + } +} \ No newline at end of file diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSEnvelopedHelper.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSEnvelopedHelper.cs.meta new file mode 100644 index 0000000..c2be191 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSEnvelopedHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ad53ee82daf533b4ca0ff2b673e768e7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSException.cs new file mode 100644 index 0000000..29fe0a6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSException.cs @@ -0,0 +1,28 @@ +using System; + +namespace Org.BouncyCastle.Cms +{ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE) + [Serializable] +#endif + public class CmsException + : Exception + { + public CmsException() + { + } + + public CmsException( + string msg) + : base(msg) + { + } + + public CmsException( + string msg, + Exception e) + : base(msg, e) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSException.cs.meta new file mode 100644 index 0000000..671fed8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3e32c6807ee17544bb26e815b73f4e71 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSPBEKey.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSPBEKey.cs new file mode 100644 index 0000000..e03307e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSPBEKey.cs @@ -0,0 +1,109 @@ +using System; + +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +//import javax.crypto.interfaces.PBEKey; + +namespace Org.BouncyCastle.Cms +{ + public abstract class CmsPbeKey + // TODO Create an equivalent interface somewhere? + // : PBEKey + : ICipherParameters + { + internal readonly char[] password; + internal readonly byte[] salt; + internal readonly int iterationCount; + + [Obsolete("Use version taking 'char[]' instead")] + public CmsPbeKey( + string password, + byte[] salt, + int iterationCount) + : this(password.ToCharArray(), salt, iterationCount) + { + } + + [Obsolete("Use version taking 'char[]' instead")] + public CmsPbeKey( + string password, + AlgorithmIdentifier keyDerivationAlgorithm) + : this(password.ToCharArray(), keyDerivationAlgorithm) + { + } + + public CmsPbeKey( + char[] password, + byte[] salt, + int iterationCount) + { + this.password = (char[])password.Clone(); + this.salt = Arrays.Clone(salt); + this.iterationCount = iterationCount; + } + + public CmsPbeKey( + char[] password, + AlgorithmIdentifier keyDerivationAlgorithm) + { + if (!keyDerivationAlgorithm.Algorithm.Equals(PkcsObjectIdentifiers.IdPbkdf2)) + throw new ArgumentException("Unsupported key derivation algorithm: " + + keyDerivationAlgorithm.Algorithm); + + Pbkdf2Params kdfParams = Pbkdf2Params.GetInstance( + keyDerivationAlgorithm.Parameters.ToAsn1Object()); + + this.password = (char[])password.Clone(); + this.salt = kdfParams.GetSalt(); + this.iterationCount = kdfParams.IterationCount.IntValue; + } + + ~CmsPbeKey() + { + Array.Clear(this.password, 0, this.password.Length); + } + + [Obsolete("Will be removed")] + public string Password + { + get { return new string(password); } + } + + public byte[] Salt + { + get { return Arrays.Clone(salt); } + } + + [Obsolete("Use 'Salt' property instead")] + public byte[] GetSalt() + { + return Salt; + } + + public int IterationCount + { + get { return iterationCount; } + } + + public string Algorithm + { + get { return "PKCS5S2"; } + } + + public string Format + { + get { return "RAW"; } + } + + public byte[] GetEncoded() + { + return null; + } + + internal abstract KeyParameter GetEncoded(string algorithmOid); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSPBEKey.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSPBEKey.cs.meta new file mode 100644 index 0000000..59349e3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSPBEKey.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bd186000d3723994aa80f4f91ad491bf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSProcessable.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSProcessable.cs new file mode 100644 index 0000000..41018d1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSProcessable.cs @@ -0,0 +1,19 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Cms +{ + public interface CmsProcessable + { + /// + /// Generic routine to copy out the data we want processed. + /// + /// + /// This routine may be called multiple times. + /// + void Write(Stream outStream); + + [Obsolete] + object GetContent(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSProcessable.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSProcessable.cs.meta new file mode 100644 index 0000000..6502f8d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSProcessable.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 972a0156fc2b9be47afdf652dfe3073a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSProcessableByteArray.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSProcessableByteArray.cs new file mode 100644 index 0000000..b09935d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSProcessableByteArray.cs @@ -0,0 +1,51 @@ +using System; +using System.IO; +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cms; + +namespace Org.BouncyCastle.Cms +{ + /** + * a holding class for a byte array of data to be processed. + */ + public class CmsProcessableByteArray + : CmsProcessable, CmsReadable + { + private readonly DerObjectIdentifier type; + private readonly byte[] bytes; + + public CmsProcessableByteArray(byte[] bytes) + { + type = CmsObjectIdentifiers.Data; + this.bytes = bytes; + } + + public CmsProcessableByteArray(DerObjectIdentifier type, byte[] bytes) + { + this.bytes = bytes; + this.type = type; + } + + public DerObjectIdentifier Type + { + get { return type; } + } + + public virtual Stream GetInputStream() + { + return new MemoryStream(bytes, false); + } + + public virtual void Write(Stream zOut) + { + zOut.Write(bytes, 0, bytes.Length); + } + + /// A clone of the byte array + [Obsolete] + public virtual object GetContent() + { + return bytes.Clone(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSProcessableByteArray.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSProcessableByteArray.cs.meta new file mode 100644 index 0000000..086abcb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSProcessableByteArray.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b4bbb61addb21f94ea9afe454b881214 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSProcessableFile.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSProcessableFile.cs new file mode 100644 index 0000000..c7fbba6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSProcessableFile.cs @@ -0,0 +1,52 @@ +#if !PORTABLE || NETSTANDARD1_3 +using System; +using System.IO; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Cms +{ + /** + * a holding class for a file of data to be processed. + */ + public class CmsProcessableFile + : CmsProcessable, CmsReadable + { + private const int DefaultBufSize = 32 * 1024; + + private readonly FileInfo _file; + private readonly int _bufSize; + + public CmsProcessableFile(FileInfo file) + : this(file, DefaultBufSize) + { + } + + public CmsProcessableFile(FileInfo file, int bufSize) + { + _file = file; + _bufSize = bufSize; + } + + public virtual Stream GetInputStream() + { + return new FileStream(_file.FullName, FileMode.Open, FileAccess.Read, FileShare.Read, _bufSize); + } + + public virtual void Write(Stream zOut) + { + Stream inStr = _file.OpenRead(); + Streams.PipeAll(inStr, zOut, _bufSize); + Platform.Dispose(inStr); + } + + /// The file handle + [Obsolete] + public virtual object GetContent() + { + return _file; + } + } +} +#endif diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSProcessableFile.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSProcessableFile.cs.meta new file mode 100644 index 0000000..0dcadc6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSProcessableFile.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 767cbde8ef0456f4d8343ddbbd3c0213 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSProcessableInputStream.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSProcessableInputStream.cs new file mode 100644 index 0000000..b2abd6f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSProcessableInputStream.cs @@ -0,0 +1,53 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Cms +{ + public class CmsProcessableInputStream + : CmsProcessable, CmsReadable + { + private readonly Stream input; + + private bool used = false; + + public CmsProcessableInputStream(Stream input) + { + this.input = input; + } + + public virtual Stream GetInputStream() + { + CheckSingleUsage(); + + return input; + } + + public virtual void Write(Stream output) + { + CheckSingleUsage(); + + Streams.PipeAll(input, output); + Platform.Dispose(input); + } + + [Obsolete] + public virtual object GetContent() + { + return GetInputStream(); + } + + protected virtual void CheckSingleUsage() + { + lock (this) + { + if (used) + throw new InvalidOperationException("CmsProcessableInputStream can only be used once"); + + used = true; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSProcessableInputStream.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSProcessableInputStream.cs.meta new file mode 100644 index 0000000..9672784 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSProcessableInputStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a9b63eae780baf74b988cc8998ff1008 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSReadable.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSReadable.cs new file mode 100644 index 0000000..ad83ba0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSReadable.cs @@ -0,0 +1,10 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Cms +{ + public interface CmsReadable + { + Stream GetInputStream(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSReadable.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSReadable.cs.meta new file mode 100644 index 0000000..b4b45cb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSReadable.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6500b4888e7662344bf86d0a1ab0318d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSSecureReadable.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSSecureReadable.cs new file mode 100644 index 0000000..5ceac24 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSSecureReadable.cs @@ -0,0 +1,14 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Cms +{ + internal interface CmsSecureReadable + { + AlgorithmIdentifier Algorithm { get; } + object CryptoObject { get; } + CmsReadable GetReadable(KeyParameter key); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSSecureReadable.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSSecureReadable.cs.meta new file mode 100644 index 0000000..bb416b9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSSecureReadable.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8eabf6c451c0e73419621ad14ce227b7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSSignedData.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSSignedData.cs new file mode 100644 index 0000000..6028de7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSSignedData.cs @@ -0,0 +1,440 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Security.Certificates; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.X509; +using Org.BouncyCastle.X509.Store; + +namespace Org.BouncyCastle.Cms +{ + /** + * general class for handling a pkcs7-signature message. + * + * A simple example of usage - note, in the example below the validity of + * the certificate isn't verified, just the fact that one of the certs + * matches the given signer... + * + *
+	*  IX509Store              certs = s.GetCertificates();
+	*  SignerInformationStore  signers = s.GetSignerInfos();
+	*
+	*  foreach (SignerInformation signer in signers.GetSigners())
+	*  {
+	*      ArrayList       certList = new ArrayList(certs.GetMatches(signer.SignerID));
+	*      X509Certificate cert = (X509Certificate) certList[0];
+	*
+	*      if (signer.Verify(cert.GetPublicKey()))
+	*      {
+	*          verified++;
+	*      }
+	*  }
+	* 
+ */ + public class CmsSignedData + { + private static readonly CmsSignedHelper Helper = CmsSignedHelper.Instance; + + private readonly CmsProcessable signedContent; + private SignedData signedData; + private ContentInfo contentInfo; + private SignerInformationStore signerInfoStore; + private IX509Store attrCertStore; + private IX509Store certificateStore; + private IX509Store crlStore; + private IDictionary hashes; + + private CmsSignedData( + CmsSignedData c) + { + this.signedData = c.signedData; + this.contentInfo = c.contentInfo; + this.signedContent = c.signedContent; + this.signerInfoStore = c.signerInfoStore; + } + + public CmsSignedData( + byte[] sigBlock) + : this(CmsUtilities.ReadContentInfo(new MemoryStream(sigBlock, false))) + { + } + + public CmsSignedData( + CmsProcessable signedContent, + byte[] sigBlock) + : this(signedContent, CmsUtilities.ReadContentInfo(new MemoryStream(sigBlock, false))) + { + } + + /** + * Content with detached signature, digests precomputed + * + * @param hashes a map of precomputed digests for content indexed by name of hash. + * @param sigBlock the signature object. + */ + public CmsSignedData( + IDictionary hashes, + byte[] sigBlock) + : this(hashes, CmsUtilities.ReadContentInfo(sigBlock)) + { + } + + /** + * base constructor - content with detached signature. + * + * @param signedContent the content that was signed. + * @param sigData the signature object. + */ + public CmsSignedData( + CmsProcessable signedContent, + Stream sigData) + : this(signedContent, CmsUtilities.ReadContentInfo(sigData)) + { + } + + /** + * base constructor - with encapsulated content + */ + public CmsSignedData( + Stream sigData) + : this(CmsUtilities.ReadContentInfo(sigData)) + { + } + + public CmsSignedData( + CmsProcessable signedContent, + ContentInfo sigData) + { + this.signedContent = signedContent; + this.contentInfo = sigData; + this.signedData = SignedData.GetInstance(contentInfo.Content); + } + + public CmsSignedData( + IDictionary hashes, + ContentInfo sigData) + { + this.hashes = hashes; + this.contentInfo = sigData; + this.signedData = SignedData.GetInstance(contentInfo.Content); + } + + public CmsSignedData( + ContentInfo sigData) + { + this.contentInfo = sigData; + this.signedData = SignedData.GetInstance(contentInfo.Content); + + // + // this can happen if the signed message is sent simply to send a + // certificate chain. + // + if (signedData.EncapContentInfo.Content != null) + { + this.signedContent = new CmsProcessableByteArray( + ((Asn1OctetString)(signedData.EncapContentInfo.Content)).GetOctets()); + } +// else +// { +// this.signedContent = null; +// } + } + + /// Return the version number for this object. + public int Version + { + get { return signedData.Version.IntValueExact; } + } + + internal IX509Store GetCertificates() + { + return Helper.GetCertificates(signedData.Certificates); + } + + /** + * return the collection of signers that are associated with the + * signatures for the message. + */ + public SignerInformationStore GetSignerInfos() + { + if (signerInfoStore == null) + { + IList signerInfos = Platform.CreateArrayList(); + Asn1Set s = signedData.SignerInfos; + + foreach (object obj in s) + { + SignerInfo info = SignerInfo.GetInstance(obj); + DerObjectIdentifier contentType = signedData.EncapContentInfo.ContentType; + + if (hashes == null) + { + signerInfos.Add(new SignerInformation(info, contentType, signedContent, null)); + } + else + { + byte[] hash = (byte[])hashes[info.DigestAlgorithm.Algorithm.Id]; + + signerInfos.Add(new SignerInformation(info, contentType, null, new BaseDigestCalculator(hash))); + } + } + + signerInfoStore = new SignerInformationStore(signerInfos); + } + + return signerInfoStore; + } + + /** + * return a X509Store containing the attribute certificates, if any, contained + * in this message. + * + * @param type type of store to create + * @return a store of attribute certificates + * @exception NoSuchStoreException if the store type isn't available. + * @exception CmsException if a general exception prevents creation of the X509Store + */ + public IX509Store GetAttributeCertificates( + string type) + { + if (attrCertStore == null) + { + attrCertStore = Helper.CreateAttributeStore(type, signedData.Certificates); + } + + return attrCertStore; + } + + /** + * return a X509Store containing the public key certificates, if any, contained + * in this message. + * + * @param type type of store to create + * @return a store of public key certificates + * @exception NoSuchStoreException if the store type isn't available. + * @exception CmsException if a general exception prevents creation of the X509Store + */ + public IX509Store GetCertificates( + string type) + { + if (certificateStore == null) + { + certificateStore = Helper.CreateCertificateStore(type, signedData.Certificates); + } + + return certificateStore; + } + + /** + * return a X509Store containing CRLs, if any, contained + * in this message. + * + * @param type type of store to create + * @return a store of CRLs + * @exception NoSuchStoreException if the store type isn't available. + * @exception CmsException if a general exception prevents creation of the X509Store + */ + public IX509Store GetCrls( + string type) + { + if (crlStore == null) + { + crlStore = Helper.CreateCrlStore(type, signedData.CRLs); + } + + return crlStore; + } + + [Obsolete("Use 'SignedContentType' property instead.")] + public string SignedContentTypeOid + { + get { return signedData.EncapContentInfo.ContentType.Id; } + } + + /// + /// Return the DerObjectIdentifier associated with the encapsulated + /// content info structure carried in the signed data. + /// + public DerObjectIdentifier SignedContentType + { + get { return signedData.EncapContentInfo.ContentType; } + } + + public CmsProcessable SignedContent + { + get { return signedContent; } + } + + /** + * return the ContentInfo + */ + public ContentInfo ContentInfo + { + get { return contentInfo; } + } + + /** + * return the ASN.1 encoded representation of this object. + */ + public byte[] GetEncoded() + { + return contentInfo.GetEncoded(); + } + + /** + * return the ASN.1 encoded representation of this object using the specified encoding. + * + * @param encoding the ASN.1 encoding format to use ("BER" or "DER"). + */ + public byte[] GetEncoded(string encoding) + { + return contentInfo.GetEncoded(encoding); + } + + /** + * Replace the signerinformation store associated with this + * CmsSignedData object with the new one passed in. You would + * probably only want to do this if you wanted to change the unsigned + * attributes associated with a signer, or perhaps delete one. + * + * @param signedData the signed data object to be used as a base. + * @param signerInformationStore the new signer information store to use. + * @return a new signed data object. + */ + public static CmsSignedData ReplaceSigners( + CmsSignedData signedData, + SignerInformationStore signerInformationStore) + { + // + // copy + // + CmsSignedData cms = new CmsSignedData(signedData); + + // + // replace the store + // + cms.signerInfoStore = signerInformationStore; + + // + // replace the signers in the SignedData object + // + Asn1EncodableVector digestAlgs = new Asn1EncodableVector(); + Asn1EncodableVector vec = new Asn1EncodableVector(); + + foreach (SignerInformation signer in signerInformationStore.GetSigners()) + { + digestAlgs.Add(Helper.FixAlgID(signer.DigestAlgorithmID)); + vec.Add(signer.ToSignerInfo()); + } + + Asn1Set digests = new DerSet(digestAlgs); + Asn1Set signers = new DerSet(vec); + Asn1Sequence sD = (Asn1Sequence)signedData.signedData.ToAsn1Object(); + + // + // signers are the last item in the sequence. + // + vec = new Asn1EncodableVector( + sD[0], // version + digests); + + for (int i = 2; i != sD.Count - 1; i++) + { + vec.Add(sD[i]); + } + + vec.Add(signers); + + cms.signedData = SignedData.GetInstance(new BerSequence(vec)); + + // + // replace the contentInfo with the new one + // + cms.contentInfo = new ContentInfo(cms.contentInfo.ContentType, cms.signedData); + + return cms; + } + + /** + * Replace the certificate and CRL information associated with this + * CmsSignedData object with the new one passed in. + * + * @param signedData the signed data object to be used as a base. + * @param x509Certs the new certificates to be used. + * @param x509Crls the new CRLs to be used. + * @return a new signed data object. + * @exception CmsException if there is an error processing the stores + */ + public static CmsSignedData ReplaceCertificatesAndCrls( + CmsSignedData signedData, + IX509Store x509Certs, + IX509Store x509Crls, + IX509Store x509AttrCerts) + { + if (x509AttrCerts != null) + throw Platform.CreateNotImplementedException("Currently can't replace attribute certificates"); + + // + // copy + // + CmsSignedData cms = new CmsSignedData(signedData); + + // + // replace the certs and crls in the SignedData object + // + Asn1Set certs = null; + try + { + Asn1Set asn1Set = CmsUtilities.CreateBerSetFromList( + CmsUtilities.GetCertificatesFromStore(x509Certs)); + + if (asn1Set.Count != 0) + { + certs = asn1Set; + } + } + catch (X509StoreException e) + { + throw new CmsException("error getting certificates from store", e); + } + + Asn1Set crls = null; + try + { + Asn1Set asn1Set = CmsUtilities.CreateBerSetFromList( + CmsUtilities.GetCrlsFromStore(x509Crls)); + + if (asn1Set.Count != 0) + { + crls = asn1Set; + } + } + catch (X509StoreException e) + { + throw new CmsException("error getting CRLs from store", e); + } + + // + // replace the CMS structure. + // + SignedData old = signedData.signedData; + cms.signedData = new SignedData( + old.DigestAlgorithms, + old.EncapContentInfo, + certs, + crls, + old.SignerInfos); + + // + // replace the contentInfo with the new one + // + cms.contentInfo = new ContentInfo(cms.contentInfo.ContentType, cms.signedData); + + return cms; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSSignedData.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSSignedData.cs.meta new file mode 100644 index 0000000..b512e64 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSSignedData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4a1b0e4969250ba4e9590e093668ad41 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSSignedDataGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSSignedDataGenerator.cs new file mode 100644 index 0000000..f2d54ba --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSSignedDataGenerator.cs @@ -0,0 +1,590 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.IO; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Security.Certificates; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.X509; +using Org.BouncyCastle.Crypto.Operators; + +namespace Org.BouncyCastle.Cms +{ + /** + * general class for generating a pkcs7-signature message. + *

+ * A simple example of usage. + * + *

+     *      IX509Store certs...
+     *      IX509Store crls...
+     *      CmsSignedDataGenerator gen = new CmsSignedDataGenerator();
+     *
+     *      gen.AddSigner(privKey, cert, CmsSignedGenerator.DigestSha1);
+     *      gen.AddCertificates(certs);
+     *      gen.AddCrls(crls);
+     *
+     *      CmsSignedData data = gen.Generate(content);
+     * 
+ *

+ */ + public class CmsSignedDataGenerator + : CmsSignedGenerator + { + private static readonly CmsSignedHelper Helper = CmsSignedHelper.Instance; + + private readonly IList signerInfs = Platform.CreateArrayList(); + + private class SignerInf + { + private readonly CmsSignedGenerator outer; + + private readonly ISignatureFactory sigCalc; + private readonly SignerIdentifier signerIdentifier; + private readonly string digestOID; + private readonly string encOID; + private readonly CmsAttributeTableGenerator sAttr; + private readonly CmsAttributeTableGenerator unsAttr; + private readonly Asn1.Cms.AttributeTable baseSignedTable; + + internal SignerInf( + CmsSignedGenerator outer, + AsymmetricKeyParameter key, + SignerIdentifier signerIdentifier, + string digestOID, + string encOID, + CmsAttributeTableGenerator sAttr, + CmsAttributeTableGenerator unsAttr, + Asn1.Cms.AttributeTable baseSignedTable) + { + string digestName = Helper.GetDigestAlgName(digestOID); + + string signatureName = digestName + "with" + Helper.GetEncryptionAlgName(encOID); + + this.outer = outer; + this.sigCalc = new Asn1SignatureFactory(signatureName, key); + this.signerIdentifier = signerIdentifier; + this.digestOID = digestOID; + this.encOID = encOID; + this.sAttr = sAttr; + this.unsAttr = unsAttr; + this.baseSignedTable = baseSignedTable; + } + + internal SignerInf( + CmsSignedGenerator outer, + ISignatureFactory sigCalc, + SignerIdentifier signerIdentifier, + CmsAttributeTableGenerator sAttr, + CmsAttributeTableGenerator unsAttr, + Asn1.Cms.AttributeTable baseSignedTable) + { + this.outer = outer; + this.sigCalc = sigCalc; + this.signerIdentifier = signerIdentifier; + this.digestOID = new DefaultDigestAlgorithmIdentifierFinder().find((AlgorithmIdentifier)sigCalc.AlgorithmDetails).Algorithm.Id; + this.encOID = ((AlgorithmIdentifier)sigCalc.AlgorithmDetails).Algorithm.Id; + this.sAttr = sAttr; + this.unsAttr = unsAttr; + this.baseSignedTable = baseSignedTable; + } + + internal AlgorithmIdentifier DigestAlgorithmID + { + get { return new AlgorithmIdentifier(new DerObjectIdentifier(digestOID), DerNull.Instance); } + } + + internal CmsAttributeTableGenerator SignedAttributes + { + get { return sAttr; } + } + + internal CmsAttributeTableGenerator UnsignedAttributes + { + get { return unsAttr; } + } + + internal SignerInfo ToSignerInfo( + DerObjectIdentifier contentType, + CmsProcessable content, + SecureRandom random) + { + AlgorithmIdentifier digAlgId = DigestAlgorithmID; + string digestName = Helper.GetDigestAlgName(digestOID); + + string signatureName = digestName + "with" + Helper.GetEncryptionAlgName(encOID); + + byte[] hash; + if (outer._digests.Contains(digestOID)) + { + hash = (byte[])outer._digests[digestOID]; + } + else + { + IDigest dig = Helper.GetDigestInstance(digestName); + if (content != null) + { + content.Write(new DigestSink(dig)); + } + hash = DigestUtilities.DoFinal(dig); + outer._digests.Add(digestOID, hash.Clone()); + } + + IStreamCalculator calculator = sigCalc.CreateCalculator(); + +#if NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE + Stream sigStr = calculator.Stream; +#else + Stream sigStr = new BufferedStream(calculator.Stream); +#endif + + Asn1Set signedAttr = null; + if (sAttr != null) + { + IDictionary parameters = outer.GetBaseParameters(contentType, digAlgId, hash); + +// Asn1.Cms.AttributeTable signed = sAttr.GetAttributes(Collections.unmodifiableMap(parameters)); + Asn1.Cms.AttributeTable signed = sAttr.GetAttributes(parameters); + + if (contentType == null) //counter signature + { + if (signed != null && signed[CmsAttributes.ContentType] != null) + { + IDictionary tmpSigned = signed.ToDictionary(); + tmpSigned.Remove(CmsAttributes.ContentType); + signed = new Asn1.Cms.AttributeTable(tmpSigned); + } + } + + // TODO Validate proposed signed attributes + + signedAttr = outer.GetAttributeSet(signed); + + // sig must be composed from the DER encoding. + signedAttr.EncodeTo(sigStr, Asn1Encodable.Der); + } + else if (content != null) + { + // TODO Use raw signature of the hash value instead + content.Write(sigStr); + } + + Platform.Dispose(sigStr); + byte[] sigBytes = ((IBlockResult)calculator.GetResult()).Collect(); + + Asn1Set unsignedAttr = null; + if (unsAttr != null) + { + IDictionary baseParameters = outer.GetBaseParameters(contentType, digAlgId, hash); + baseParameters[CmsAttributeTableParameter.Signature] = sigBytes.Clone(); + +// Asn1.Cms.AttributeTable unsigned = unsAttr.GetAttributes(Collections.unmodifiableMap(baseParameters)); + Asn1.Cms.AttributeTable unsigned = unsAttr.GetAttributes(baseParameters); + + // TODO Validate proposed unsigned attributes + + unsignedAttr = outer.GetAttributeSet(unsigned); + } + + // TODO[RSAPSS] Need the ability to specify non-default parameters + Asn1Encodable sigX509Parameters = SignerUtilities.GetDefaultX509Parameters(signatureName); + AlgorithmIdentifier encAlgId = Helper.GetEncAlgorithmIdentifier( + new DerObjectIdentifier(encOID), sigX509Parameters); + + return new SignerInfo(signerIdentifier, digAlgId, + signedAttr, encAlgId, new DerOctetString(sigBytes), unsignedAttr); + } + } + + public CmsSignedDataGenerator() + { + } + + /// Constructor allowing specific source of randomness + /// Instance of SecureRandom to use. + public CmsSignedDataGenerator( + SecureRandom rand) + : base(rand) + { + } + + /** + * add a signer - no attributes other than the default ones will be + * provided here. + * + * @param key signing key to use + * @param cert certificate containing corresponding public key + * @param digestOID digest algorithm OID + */ + public void AddSigner( + AsymmetricKeyParameter privateKey, + X509Certificate cert, + string digestOID) + { + AddSigner(privateKey, cert, Helper.GetEncOid(privateKey, digestOID), digestOID); + } + + /** + * add a signer, specifying the digest encryption algorithm to use - no attributes other than the default ones will be + * provided here. + * + * @param key signing key to use + * @param cert certificate containing corresponding public key + * @param encryptionOID digest encryption algorithm OID + * @param digestOID digest algorithm OID + */ + public void AddSigner( + AsymmetricKeyParameter privateKey, + X509Certificate cert, + string encryptionOID, + string digestOID) + { + doAddSigner(privateKey, GetSignerIdentifier(cert), encryptionOID, digestOID, + new DefaultSignedAttributeTableGenerator(), null, null); + } + + /** + * add a signer - no attributes other than the default ones will be + * provided here. + */ + public void AddSigner( + AsymmetricKeyParameter privateKey, + byte[] subjectKeyID, + string digestOID) + { + AddSigner(privateKey, subjectKeyID, Helper.GetEncOid(privateKey, digestOID), digestOID); + } + + /** + * add a signer, specifying the digest encryption algorithm to use - no attributes other than the default ones will be + * provided here. + */ + public void AddSigner( + AsymmetricKeyParameter privateKey, + byte[] subjectKeyID, + string encryptionOID, + string digestOID) + { + doAddSigner(privateKey, GetSignerIdentifier(subjectKeyID), encryptionOID, digestOID, + new DefaultSignedAttributeTableGenerator(), null, null); + } + + /** + * add a signer with extra signed/unsigned attributes. + * + * @param key signing key to use + * @param cert certificate containing corresponding public key + * @param digestOID digest algorithm OID + * @param signedAttr table of attributes to be included in signature + * @param unsignedAttr table of attributes to be included as unsigned + */ + public void AddSigner( + AsymmetricKeyParameter privateKey, + X509Certificate cert, + string digestOID, + Asn1.Cms.AttributeTable signedAttr, + Asn1.Cms.AttributeTable unsignedAttr) + { + AddSigner(privateKey, cert, Helper.GetEncOid(privateKey, digestOID), digestOID, + signedAttr, unsignedAttr); + } + + /** + * add a signer, specifying the digest encryption algorithm, with extra signed/unsigned attributes. + * + * @param key signing key to use + * @param cert certificate containing corresponding public key + * @param encryptionOID digest encryption algorithm OID + * @param digestOID digest algorithm OID + * @param signedAttr table of attributes to be included in signature + * @param unsignedAttr table of attributes to be included as unsigned + */ + public void AddSigner( + AsymmetricKeyParameter privateKey, + X509Certificate cert, + string encryptionOID, + string digestOID, + Asn1.Cms.AttributeTable signedAttr, + Asn1.Cms.AttributeTable unsignedAttr) + { + doAddSigner(privateKey, GetSignerIdentifier(cert), encryptionOID, digestOID, + new DefaultSignedAttributeTableGenerator(signedAttr), + new SimpleAttributeTableGenerator(unsignedAttr), + signedAttr); + } + + /** + * add a signer with extra signed/unsigned attributes. + * + * @param key signing key to use + * @param subjectKeyID subjectKeyID of corresponding public key + * @param digestOID digest algorithm OID + * @param signedAttr table of attributes to be included in signature + * @param unsignedAttr table of attributes to be included as unsigned + */ + public void AddSigner( + AsymmetricKeyParameter privateKey, + byte[] subjectKeyID, + string digestOID, + Asn1.Cms.AttributeTable signedAttr, + Asn1.Cms.AttributeTable unsignedAttr) + { + AddSigner(privateKey, subjectKeyID, Helper.GetEncOid(privateKey, digestOID), digestOID, + signedAttr, unsignedAttr); + } + + /** + * add a signer, specifying the digest encryption algorithm, with extra signed/unsigned attributes. + * + * @param key signing key to use + * @param subjectKeyID subjectKeyID of corresponding public key + * @param encryptionOID digest encryption algorithm OID + * @param digestOID digest algorithm OID + * @param signedAttr table of attributes to be included in signature + * @param unsignedAttr table of attributes to be included as unsigned + */ + public void AddSigner( + AsymmetricKeyParameter privateKey, + byte[] subjectKeyID, + string encryptionOID, + string digestOID, + Asn1.Cms.AttributeTable signedAttr, + Asn1.Cms.AttributeTable unsignedAttr) + { + doAddSigner(privateKey, GetSignerIdentifier(subjectKeyID), encryptionOID, digestOID, + new DefaultSignedAttributeTableGenerator(signedAttr), + new SimpleAttributeTableGenerator(unsignedAttr), + signedAttr); + } + + /** + * add a signer with extra signed/unsigned attributes based on generators. + */ + public void AddSigner( + AsymmetricKeyParameter privateKey, + X509Certificate cert, + string digestOID, + CmsAttributeTableGenerator signedAttrGen, + CmsAttributeTableGenerator unsignedAttrGen) + { + AddSigner(privateKey, cert, Helper.GetEncOid(privateKey, digestOID), digestOID, + signedAttrGen, unsignedAttrGen); + } + + /** + * add a signer, specifying the digest encryption algorithm, with extra signed/unsigned attributes based on generators. + */ + public void AddSigner( + AsymmetricKeyParameter privateKey, + X509Certificate cert, + string encryptionOID, + string digestOID, + CmsAttributeTableGenerator signedAttrGen, + CmsAttributeTableGenerator unsignedAttrGen) + { + doAddSigner(privateKey, GetSignerIdentifier(cert), encryptionOID, digestOID, signedAttrGen, + unsignedAttrGen, null); + } + + /** + * add a signer with extra signed/unsigned attributes based on generators. + */ + public void AddSigner( + AsymmetricKeyParameter privateKey, + byte[] subjectKeyID, + string digestOID, + CmsAttributeTableGenerator signedAttrGen, + CmsAttributeTableGenerator unsignedAttrGen) + { + AddSigner(privateKey, subjectKeyID, Helper.GetEncOid(privateKey, digestOID), digestOID, + signedAttrGen, unsignedAttrGen); + } + + /** + * add a signer, including digest encryption algorithm, with extra signed/unsigned attributes based on generators. + */ + public void AddSigner( + AsymmetricKeyParameter privateKey, + byte[] subjectKeyID, + string encryptionOID, + string digestOID, + CmsAttributeTableGenerator signedAttrGen, + CmsAttributeTableGenerator unsignedAttrGen) + { + doAddSigner(privateKey, GetSignerIdentifier(subjectKeyID), encryptionOID, digestOID, + signedAttrGen, unsignedAttrGen, null); + } + + public void AddSignerInfoGenerator(SignerInfoGenerator signerInfoGenerator) + { + signerInfs.Add(new SignerInf(this, signerInfoGenerator.contentSigner, signerInfoGenerator.sigId, + signerInfoGenerator.signedGen, signerInfoGenerator.unsignedGen, null)); + } + + private void doAddSigner( + AsymmetricKeyParameter privateKey, + SignerIdentifier signerIdentifier, + string encryptionOID, + string digestOID, + CmsAttributeTableGenerator signedAttrGen, + CmsAttributeTableGenerator unsignedAttrGen, + Asn1.Cms.AttributeTable baseSignedTable) + { + signerInfs.Add(new SignerInf(this, privateKey, signerIdentifier, digestOID, encryptionOID, + signedAttrGen, unsignedAttrGen, baseSignedTable)); + } + + /** + * generate a signed object that for a CMS Signed Data object + */ + public CmsSignedData Generate( + CmsProcessable content) + { + return Generate(content, false); + } + + /** + * generate a signed object that for a CMS Signed Data + * object - if encapsulate is true a copy + * of the message will be included in the signature. The content type + * is set according to the OID represented by the string signedContentType. + */ + public CmsSignedData Generate( + string signedContentType, + // FIXME Avoid accessing more than once to support CmsProcessableInputStream + CmsProcessable content, + bool encapsulate) + { + Asn1EncodableVector digestAlgs = new Asn1EncodableVector(); + Asn1EncodableVector signerInfos = new Asn1EncodableVector(); + + _digests.Clear(); // clear the current preserved digest state + + // + // add the precalculated SignerInfo objects. + // + foreach (SignerInformation signer in _signers) + { + digestAlgs.Add(Helper.FixAlgID(signer.DigestAlgorithmID)); + + // TODO Verify the content type and calculated digest match the precalculated SignerInfo + signerInfos.Add(signer.ToSignerInfo()); + } + + // + // add the SignerInfo objects + // + bool isCounterSignature = (signedContentType == null); + + DerObjectIdentifier contentTypeOid = isCounterSignature + ? null + : new DerObjectIdentifier(signedContentType); + + foreach (SignerInf signer in signerInfs) + { + try + { + digestAlgs.Add(signer.DigestAlgorithmID); + signerInfos.Add(signer.ToSignerInfo(contentTypeOid, content, rand)); + } + catch (IOException e) + { + throw new CmsException("encoding error.", e); + } + catch (InvalidKeyException e) + { + throw new CmsException("key inappropriate for signature.", e); + } + catch (SignatureException e) + { + throw new CmsException("error creating signature.", e); + } + catch (CertificateEncodingException e) + { + throw new CmsException("error creating sid.", e); + } + } + + Asn1Set certificates = null; + + if (_certs.Count != 0) + { + certificates = UseDerForCerts + ? CmsUtilities.CreateDerSetFromList(_certs) + : CmsUtilities.CreateBerSetFromList(_certs); + } + + Asn1Set certrevlist = null; + + if (_crls.Count != 0) + { + certrevlist = UseDerForCrls + ? CmsUtilities.CreateDerSetFromList(_crls) + : CmsUtilities.CreateBerSetFromList(_crls); + } + + Asn1OctetString octs = null; + if (encapsulate) + { + MemoryStream bOut = new MemoryStream(); + if (content != null) + { + try + { + content.Write(bOut); + } + catch (IOException e) + { + throw new CmsException("encapsulation error.", e); + } + } + octs = new BerOctetString(bOut.ToArray()); + } + + ContentInfo encInfo = new ContentInfo(contentTypeOid, octs); + + SignedData sd = new SignedData( + new DerSet(digestAlgs), + encInfo, + certificates, + certrevlist, + new DerSet(signerInfos)); + + ContentInfo contentInfo = new ContentInfo(CmsObjectIdentifiers.SignedData, sd); + + return new CmsSignedData(content, contentInfo); + } + + /** + * generate a signed object that for a CMS Signed Data + * object - if encapsulate is true a copy + * of the message will be included in the signature with the + * default content type "data". + */ + public CmsSignedData Generate( + CmsProcessable content, + bool encapsulate) + { + return this.Generate(Data, content, encapsulate); + } + + /** + * generate a set of one or more SignerInformation objects representing counter signatures on + * the passed in SignerInformation object. + * + * @param signer the signer to be countersigned + * @param sigProvider the provider to be used for counter signing. + * @return a store containing the signers. + */ + public SignerInformationStore GenerateCounterSigners( + SignerInformation signer) + { + return this.Generate(null, new CmsProcessableByteArray(signer.GetSignature()), false).GetSignerInfos(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSSignedDataGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSSignedDataGenerator.cs.meta new file mode 100644 index 0000000..dc9f64c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSSignedDataGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e388b3033b805cc41b1934d0a68536e0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSSignedDataParser.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSSignedDataParser.cs new file mode 100644 index 0000000..c25f0aa --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSSignedDataParser.cs @@ -0,0 +1,450 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.IO; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Security.Certificates; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; +using Org.BouncyCastle.Utilities.IO; +using Org.BouncyCastle.X509; +using Org.BouncyCastle.X509.Store; + +namespace Org.BouncyCastle.Cms +{ + /** + * Parsing class for an CMS Signed Data object from an input stream. + *

+ * Note: that because we are in a streaming mode only one signer can be tried and it is important + * that the methods on the parser are called in the appropriate order. + *

+ *

+ * A simple example of usage for an encapsulated signature. + *

+ *

+ * Two notes: first, in the example below the validity of + * the certificate isn't verified, just the fact that one of the certs + * matches the given signer, and, second, because we are in a streaming + * mode the order of the operations is important. + *

+ *
+	*      CmsSignedDataParser     sp = new CmsSignedDataParser(encapSigData);
+	*
+	*      sp.GetSignedContent().Drain();
+	*
+	*      IX509Store              certs = sp.GetCertificates();
+	*      SignerInformationStore  signers = sp.GetSignerInfos();
+	*
+	*      foreach (SignerInformation signer in signers.GetSigners())
+	*      {
+	*          ArrayList       certList = new ArrayList(certs.GetMatches(signer.SignerID));
+	*          X509Certificate cert = (X509Certificate) certList[0];
+	*
+	*          Console.WriteLine("verify returns: " + signer.Verify(cert));
+	*      }
+	* 
+ * Note also: this class does not introduce buffering - if you are processing large files you should create + * the parser with: + *
+	*          CmsSignedDataParser     ep = new CmsSignedDataParser(new BufferedInputStream(encapSigData, bufSize));
+	*  
+ * where bufSize is a suitably large buffer size. + */ + public class CmsSignedDataParser + : CmsContentInfoParser + { + private static readonly CmsSignedHelper Helper = CmsSignedHelper.Instance; + + private SignedDataParser _signedData; + private DerObjectIdentifier _signedContentType; + private CmsTypedStream _signedContent; + private IDictionary _digests; + private ISet _digestOids; + + private SignerInformationStore _signerInfoStore; + private Asn1Set _certSet, _crlSet; + private bool _isCertCrlParsed; + private IX509Store _attributeStore; + private IX509Store _certificateStore; + private IX509Store _crlStore; + + public CmsSignedDataParser( + byte[] sigBlock) + : this(new MemoryStream(sigBlock, false)) + { + } + + public CmsSignedDataParser( + CmsTypedStream signedContent, + byte[] sigBlock) + : this(signedContent, new MemoryStream(sigBlock, false)) + { + } + + /** + * base constructor - with encapsulated content + */ + public CmsSignedDataParser( + Stream sigData) + : this(null, sigData) + { + } + + /** + * base constructor + * + * @param signedContent the content that was signed. + * @param sigData the signature object. + */ + public CmsSignedDataParser( + CmsTypedStream signedContent, + Stream sigData) + : base(sigData) + { + try + { + this._signedContent = signedContent; + this._signedData = SignedDataParser.GetInstance(this.contentInfo.GetContent(Asn1Tags.Sequence)); + this._digests = Platform.CreateHashtable(); + this._digestOids = new HashSet(); + + Asn1SetParser digAlgs = _signedData.GetDigestAlgorithms(); + IAsn1Convertible o; + + while ((o = digAlgs.ReadObject()) != null) + { + AlgorithmIdentifier id = AlgorithmIdentifier.GetInstance(o.ToAsn1Object()); + + try + { + string digestOid = id.Algorithm.Id; + string digestName = Helper.GetDigestAlgName(digestOid); + + if (!this._digests.Contains(digestName)) + { + this._digests[digestName] = Helper.GetDigestInstance(digestName); + this._digestOids.Add(digestOid); + } + } + catch (SecurityUtilityException) + { + // TODO Should do something other than ignore it + } + } + + // + // If the message is simply a certificate chain message GetContent() may return null. + // + ContentInfoParser cont = _signedData.GetEncapContentInfo(); + Asn1OctetStringParser octs = (Asn1OctetStringParser) + cont.GetContent(Asn1Tags.OctetString); + + if (octs != null) + { + CmsTypedStream ctStr = new CmsTypedStream( + cont.ContentType.Id, octs.GetOctetStream()); + + if (_signedContent == null) + { + this._signedContent = ctStr; + } + else + { + // + // content passed in, need to read past empty encapsulated content info object if present + // + ctStr.Drain(); + } + } + + _signedContentType = _signedContent == null + ? cont.ContentType + : new DerObjectIdentifier(_signedContent.ContentType); + } + catch (IOException e) + { + throw new CmsException("io exception: " + e.Message, e); + } + } + + /** + * Return the version number for the SignedData object + * + * @return the version number + */ + public int Version + { + get { return _signedData.Version.IntValueExact; } + } + + public ISet DigestOids + { + get { return new HashSet(_digestOids); } + } + + /** + * return the collection of signers that are associated with the + * signatures for the message. + * @throws CmsException + */ + public SignerInformationStore GetSignerInfos() + { + if (_signerInfoStore == null) + { + PopulateCertCrlSets(); + + IList signerInfos = Platform.CreateArrayList(); + IDictionary hashes = Platform.CreateHashtable(); + + foreach (object digestKey in _digests.Keys) + { + hashes[digestKey] = DigestUtilities.DoFinal( + (IDigest)_digests[digestKey]); + } + + try + { + Asn1SetParser s = _signedData.GetSignerInfos(); + IAsn1Convertible o; + + while ((o = s.ReadObject()) != null) + { + SignerInfo info = SignerInfo.GetInstance(o.ToAsn1Object()); + string digestName = Helper.GetDigestAlgName( + info.DigestAlgorithm.Algorithm.Id); + + byte[] hash = (byte[]) hashes[digestName]; + + signerInfos.Add(new SignerInformation(info, _signedContentType, null, new BaseDigestCalculator(hash))); + } + } + catch (IOException e) + { + throw new CmsException("io exception: " + e.Message, e); + } + + _signerInfoStore = new SignerInformationStore(signerInfos); + } + + return _signerInfoStore; + } + + /** + * return a X509Store containing the attribute certificates, if any, contained + * in this message. + * + * @param type type of store to create + * @return a store of attribute certificates + * @exception org.bouncycastle.x509.NoSuchStoreException if the store type isn't available. + * @exception CmsException if a general exception prevents creation of the X509Store + */ + public IX509Store GetAttributeCertificates( + string type) + { + if (_attributeStore == null) + { + PopulateCertCrlSets(); + + _attributeStore = Helper.CreateAttributeStore(type, _certSet); + } + + return _attributeStore; + } + + /** + * return a X509Store containing the public key certificates, if any, contained + * in this message. + * + * @param type type of store to create + * @return a store of public key certificates + * @exception NoSuchStoreException if the store type isn't available. + * @exception CmsException if a general exception prevents creation of the X509Store + */ + public IX509Store GetCertificates( + string type) + { + if (_certificateStore == null) + { + PopulateCertCrlSets(); + + _certificateStore = Helper.CreateCertificateStore(type, _certSet); + } + + return _certificateStore; + } + + /** + * return a X509Store containing CRLs, if any, contained + * in this message. + * + * @param type type of store to create + * @return a store of CRLs + * @exception NoSuchStoreException if the store type isn't available. + * @exception CmsException if a general exception prevents creation of the X509Store + */ + public IX509Store GetCrls( + string type) + { + if (_crlStore == null) + { + PopulateCertCrlSets(); + + _crlStore = Helper.CreateCrlStore(type, _crlSet); + } + + return _crlStore; + } + + private void PopulateCertCrlSets() + { + if (_isCertCrlParsed) + return; + + _isCertCrlParsed = true; + + try + { + // care! Streaming - Must process the GetCertificates() result before calling GetCrls() + _certSet = GetAsn1Set(_signedData.GetCertificates()); + _crlSet = GetAsn1Set(_signedData.GetCrls()); + } + catch (IOException e) + { + throw new CmsException("problem parsing cert/crl sets", e); + } + } + + /// + /// Return the DerObjectIdentifier associated with the encapsulated + /// content info structure carried in the signed data. + /// + public DerObjectIdentifier SignedContentType + { + get { return _signedContentType; } + } + + public CmsTypedStream GetSignedContent() + { + if (_signedContent == null) + { + return null; + } + + Stream digStream = _signedContent.ContentStream; + + foreach (IDigest digest in _digests.Values) + { + digStream = new DigestStream(digStream, digest, null); + } + + return new CmsTypedStream(_signedContent.ContentType, digStream); + } + + /** + * Replace the signerinformation store associated with the passed + * in message contained in the stream original with the new one passed in. + * You would probably only want to do this if you wanted to change the unsigned + * attributes associated with a signer, or perhaps delete one. + *

+ * The output stream is returned unclosed. + *

+ * @param original the signed data stream to be used as a base. + * @param signerInformationStore the new signer information store to use. + * @param out the stream to Write the new signed data object to. + * @return out. + */ + public static Stream ReplaceSigners( + Stream original, + SignerInformationStore signerInformationStore, + Stream outStr) + { + // NB: SecureRandom would be ignored since using existing signatures only + CmsSignedDataStreamGenerator gen = new CmsSignedDataStreamGenerator(); + CmsSignedDataParser parser = new CmsSignedDataParser(original); + +// gen.AddDigests(parser.DigestOids); + gen.AddSigners(signerInformationStore); + + CmsTypedStream signedContent = parser.GetSignedContent(); + bool encapsulate = (signedContent != null); + Stream contentOut = gen.Open(outStr, parser.SignedContentType.Id, encapsulate); + if (encapsulate) + { + Streams.PipeAll(signedContent.ContentStream, contentOut); + } + + gen.AddAttributeCertificates(parser.GetAttributeCertificates("Collection")); + gen.AddCertificates(parser.GetCertificates("Collection")); + gen.AddCrls(parser.GetCrls("Collection")); + +// gen.AddSigners(parser.GetSignerInfos()); + + Platform.Dispose(contentOut); + + return outStr; + } + + /** + * Replace the certificate and CRL information associated with this + * CMSSignedData object with the new one passed in. + *

+ * The output stream is returned unclosed. + *

+ * @param original the signed data stream to be used as a base. + * @param certsAndCrls the new certificates and CRLs to be used. + * @param out the stream to Write the new signed data object to. + * @return out. + * @exception CmsException if there is an error processing the CertStore + */ + public static Stream ReplaceCertificatesAndCrls( + Stream original, + IX509Store x509Certs, + IX509Store x509Crls, + IX509Store x509AttrCerts, + Stream outStr) + { + // NB: SecureRandom would be ignored since using existing signatures only + CmsSignedDataStreamGenerator gen = new CmsSignedDataStreamGenerator(); + CmsSignedDataParser parser = new CmsSignedDataParser(original); + + gen.AddDigests(parser.DigestOids); + + CmsTypedStream signedContent = parser.GetSignedContent(); + bool encapsulate = (signedContent != null); + Stream contentOut = gen.Open(outStr, parser.SignedContentType.Id, encapsulate); + if (encapsulate) + { + Streams.PipeAll(signedContent.ContentStream, contentOut); + } + +// gen.AddAttributeCertificates(parser.GetAttributeCertificates("Collection")); +// gen.AddCertificates(parser.GetCertificates("Collection")); +// gen.AddCrls(parser.GetCrls("Collection")); + if (x509AttrCerts != null) + gen.AddAttributeCertificates(x509AttrCerts); + if (x509Certs != null) + gen.AddCertificates(x509Certs); + if (x509Crls != null) + gen.AddCrls(x509Crls); + + gen.AddSigners(parser.GetSignerInfos()); + + Platform.Dispose(contentOut); + + return outStr; + } + + private static Asn1Set GetAsn1Set( + Asn1SetParser asn1SetParser) + { + return asn1SetParser == null + ? null + : Asn1Set.GetInstance(asn1SetParser.ToAsn1Object()); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSSignedDataParser.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSSignedDataParser.cs.meta new file mode 100644 index 0000000..7743ec2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSSignedDataParser.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: eeb1be0b114e96943b8c41494b2195b2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSSignedDataStreamGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSSignedDataStreamGenerator.cs new file mode 100644 index 0000000..e32f95d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSSignedDataStreamGenerator.cs @@ -0,0 +1,933 @@ +using System; +using System.Collections; +using System.Diagnostics; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.IO; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Security.Certificates; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; +using Org.BouncyCastle.Utilities.IO; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.Cms +{ + /** + * General class for generating a pkcs7-signature message stream. + *

+ * A simple example of usage. + *

+ *
+    *      IX509Store                   certs...
+    *      CmsSignedDataStreamGenerator gen = new CmsSignedDataStreamGenerator();
+    *
+    *      gen.AddSigner(privateKey, cert, CmsSignedDataStreamGenerator.DIGEST_SHA1);
+    *
+    *      gen.AddCertificates(certs);
+    *
+    *      Stream sigOut = gen.Open(bOut);
+    *
+    *      sigOut.Write(Encoding.UTF8.GetBytes("Hello World!"));
+    *
+    *      sigOut.Close();
+    * 
+ */ + public class CmsSignedDataStreamGenerator + : CmsSignedGenerator + { + private static readonly CmsSignedHelper Helper = CmsSignedHelper.Instance; + + private readonly IList _signerInfs = Platform.CreateArrayList(); + private readonly ISet _messageDigestOids = new HashSet(); + private readonly IDictionary _messageDigests = Platform.CreateHashtable(); + private readonly IDictionary _messageHashes = Platform.CreateHashtable(); + private bool _messageDigestsLocked; + private int _bufferSize; + + private class DigestAndSignerInfoGeneratorHolder + { + internal readonly ISignerInfoGenerator signerInf; + internal readonly string digestOID; + + internal DigestAndSignerInfoGeneratorHolder(ISignerInfoGenerator signerInf, String digestOID) + { + this.signerInf = signerInf; + this.digestOID = digestOID; + } + + internal AlgorithmIdentifier DigestAlgorithm + { + get { return new AlgorithmIdentifier(new DerObjectIdentifier(this.digestOID), DerNull.Instance); } + } + } + + private class SignerInfoGeneratorImpl : ISignerInfoGenerator + { + private readonly CmsSignedDataStreamGenerator outer; + + private readonly SignerIdentifier _signerIdentifier; + private readonly string _digestOID; + private readonly string _encOID; + private readonly CmsAttributeTableGenerator _sAttr; + private readonly CmsAttributeTableGenerator _unsAttr; + private readonly string _encName; + private readonly ISigner _sig; + + internal SignerInfoGeneratorImpl( + CmsSignedDataStreamGenerator outer, + AsymmetricKeyParameter key, + SignerIdentifier signerIdentifier, + string digestOID, + string encOID, + CmsAttributeTableGenerator sAttr, + CmsAttributeTableGenerator unsAttr) + { + this.outer = outer; + + _signerIdentifier = signerIdentifier; + _digestOID = digestOID; + _encOID = encOID; + _sAttr = sAttr; + _unsAttr = unsAttr; + _encName = Helper.GetEncryptionAlgName(_encOID); + + string digestName = Helper.GetDigestAlgName(_digestOID); + string signatureName = digestName + "with" + _encName; + + if (_sAttr != null) + { + _sig = Helper.GetSignatureInstance(signatureName); + } + else + { + // Note: Need to use raw signatures here since we have already calculated the digest + if (_encName.Equals("RSA")) + { + _sig = Helper.GetSignatureInstance("RSA"); + } + else if (_encName.Equals("DSA")) + { + _sig = Helper.GetSignatureInstance("NONEwithDSA"); + } + // TODO Add support for raw PSS +// else if (_encName.equals("RSAandMGF1")) +// { +// _sig = CMSSignedHelper.INSTANCE.getSignatureInstance("NONEWITHRSAPSS", _sigProvider); +// try +// { +// // Init the params this way to avoid having a 'raw' version of each PSS algorithm +// Signature sig2 = CMSSignedHelper.INSTANCE.getSignatureInstance(signatureName, _sigProvider); +// PSSParameterSpec spec = (PSSParameterSpec)sig2.getParameters().getParameterSpec(PSSParameterSpec.class); +// _sig.setParameter(spec); +// } +// catch (Exception e) +// { +// throw new SignatureException("algorithm: " + _encName + " could not be configured."); +// } +// } + else + { + throw new SignatureException("algorithm: " + _encName + " not supported in base signatures."); + } + } + + _sig.Init(true, new ParametersWithRandom(key, outer.rand)); + } + + public SignerInfo Generate(DerObjectIdentifier contentType, AlgorithmIdentifier digestAlgorithm, + byte[] calculatedDigest) + { + try + { + string digestName = Helper.GetDigestAlgName(_digestOID); + string signatureName = digestName + "with" + _encName; + +// AlgorithmIdentifier digAlgId = DigestAlgorithmID; +// +// byte[] hash = (byte[])outer._messageHashes[Helper.GetDigestAlgName(this._digestOID)]; +// outer._digests[_digestOID] = hash.Clone(); + + byte[] bytesToSign = calculatedDigest; + + /* RFC 3852 5.4 + * The result of the message digest calculation process depends on + * whether the signedAttrs field is present. When the field is absent, + * the result is just the message digest of the content as described + * + * above. When the field is present, however, the result is the message + * digest of the complete DER encoding of the SignedAttrs value + * contained in the signedAttrs field. + */ + Asn1Set signedAttr = null; + if (_sAttr != null) + { + IDictionary parameters = outer.GetBaseParameters(contentType, digestAlgorithm, calculatedDigest); + +// Asn1.Cms.AttributeTable signed = _sAttr.GetAttributes(Collections.unmodifiableMap(parameters)); + Asn1.Cms.AttributeTable signed = _sAttr.GetAttributes(parameters); + + if (contentType == null) //counter signature + { + if (signed != null && signed[CmsAttributes.ContentType] != null) + { + IDictionary tmpSigned = signed.ToDictionary(); + tmpSigned.Remove(CmsAttributes.ContentType); + signed = new Asn1.Cms.AttributeTable(tmpSigned); + } + } + + signedAttr = outer.GetAttributeSet(signed); + + // sig must be composed from the DER encoding. + bytesToSign = signedAttr.GetEncoded(Asn1Encodable.Der); + } + else + { + // Note: Need to use raw signatures here since we have already calculated the digest + if (_encName.Equals("RSA")) + { + DigestInfo dInfo = new DigestInfo(digestAlgorithm, calculatedDigest); + bytesToSign = dInfo.GetEncoded(Asn1Encodable.Der); + } + } + + _sig.BlockUpdate(bytesToSign, 0, bytesToSign.Length); + byte[] sigBytes = _sig.GenerateSignature(); + + Asn1Set unsignedAttr = null; + if (_unsAttr != null) + { + IDictionary parameters = outer.GetBaseParameters( + contentType, digestAlgorithm, calculatedDigest); + parameters[CmsAttributeTableParameter.Signature] = sigBytes.Clone(); + +// Asn1.Cms.AttributeTable unsigned = _unsAttr.getAttributes(Collections.unmodifiableMap(parameters)); + Asn1.Cms.AttributeTable unsigned = _unsAttr.GetAttributes(parameters); + + unsignedAttr = outer.GetAttributeSet(unsigned); + } + + // TODO[RSAPSS] Need the ability to specify non-default parameters + Asn1Encodable sigX509Parameters = SignerUtilities.GetDefaultX509Parameters(signatureName); + AlgorithmIdentifier digestEncryptionAlgorithm = Helper.GetEncAlgorithmIdentifier( + new DerObjectIdentifier(_encOID), sigX509Parameters); + + return new SignerInfo(_signerIdentifier, digestAlgorithm, + signedAttr, digestEncryptionAlgorithm, new DerOctetString(sigBytes), unsignedAttr); + } + catch (IOException e) + { + throw new CmsStreamException("encoding error.", e); + } + catch (SignatureException e) + { + throw new CmsStreamException("error creating signature.", e); + } + } + } + + public CmsSignedDataStreamGenerator() + { + } + + /// Constructor allowing specific source of randomness + /// Instance of SecureRandom to use. + public CmsSignedDataStreamGenerator( + SecureRandom rand) + : base(rand) + { + } + + /** + * Set the underlying string size for encapsulated data + * + * @param bufferSize length of octet strings to buffer the data. + */ + public void SetBufferSize( + int bufferSize) + { + _bufferSize = bufferSize; + } + + public void AddDigests( + params string[] digestOids) + { + AddDigests((IEnumerable) digestOids); + } + + public void AddDigests( + IEnumerable digestOids) + { + foreach (string digestOid in digestOids) + { + ConfigureDigest(digestOid); + } + } + + /** + * add a signer - no attributes other than the default ones will be + * provided here. + * @throws NoSuchAlgorithmException + * @throws InvalidKeyException + */ + public void AddSigner( + AsymmetricKeyParameter privateKey, + X509Certificate cert, + string digestOid) + { + AddSigner(privateKey, cert, digestOid, + new DefaultSignedAttributeTableGenerator(), null); + } + + /** + * add a signer, specifying the digest encryption algorithm - no attributes other than the default ones will be + * provided here. + * @throws NoSuchProviderException + * @throws NoSuchAlgorithmException + * @throws InvalidKeyException + */ + public void AddSigner( + AsymmetricKeyParameter privateKey, + X509Certificate cert, + string encryptionOid, + string digestOid) + { + AddSigner(privateKey, cert, encryptionOid, digestOid, + new DefaultSignedAttributeTableGenerator(), + (CmsAttributeTableGenerator)null); + } + + /** + * add a signer with extra signed/unsigned attributes. + * @throws NoSuchAlgorithmException + * @throws InvalidKeyException + */ + public void AddSigner( + AsymmetricKeyParameter privateKey, + X509Certificate cert, + string digestOid, + Asn1.Cms.AttributeTable signedAttr, + Asn1.Cms.AttributeTable unsignedAttr) + { + AddSigner(privateKey, cert, digestOid, + new DefaultSignedAttributeTableGenerator(signedAttr), + new SimpleAttributeTableGenerator(unsignedAttr)); + } + + /** + * add a signer with extra signed/unsigned attributes - specifying digest + * encryption algorithm. + * @throws NoSuchProviderException + * @throws NoSuchAlgorithmException + * @throws InvalidKeyException + */ + public void AddSigner( + AsymmetricKeyParameter privateKey, + X509Certificate cert, + string encryptionOid, + string digestOid, + Asn1.Cms.AttributeTable signedAttr, + Asn1.Cms.AttributeTable unsignedAttr) + { + AddSigner(privateKey, cert, encryptionOid, digestOid, + new DefaultSignedAttributeTableGenerator(signedAttr), + new SimpleAttributeTableGenerator(unsignedAttr)); + } + + public void AddSigner( + AsymmetricKeyParameter privateKey, + X509Certificate cert, + string digestOid, + CmsAttributeTableGenerator signedAttrGenerator, + CmsAttributeTableGenerator unsignedAttrGenerator) + { + AddSigner(privateKey, cert, Helper.GetEncOid(privateKey, digestOid), digestOid, + signedAttrGenerator, unsignedAttrGenerator); + } + + public void AddSigner( + AsymmetricKeyParameter privateKey, + X509Certificate cert, + string encryptionOid, + string digestOid, + CmsAttributeTableGenerator signedAttrGenerator, + CmsAttributeTableGenerator unsignedAttrGenerator) + { + DoAddSigner(privateKey, GetSignerIdentifier(cert), encryptionOid, digestOid, + signedAttrGenerator, unsignedAttrGenerator); + } + + /** + * add a signer - no attributes other than the default ones will be + * provided here. + * @throws NoSuchAlgorithmException + * @throws InvalidKeyException + */ + public void AddSigner( + AsymmetricKeyParameter privateKey, + byte[] subjectKeyID, + string digestOid) + { + AddSigner(privateKey, subjectKeyID, digestOid, new DefaultSignedAttributeTableGenerator(), + (CmsAttributeTableGenerator)null); + } + + /** + * add a signer - no attributes other than the default ones will be + * provided here. + * @throws NoSuchProviderException + * @throws NoSuchAlgorithmException + * @throws InvalidKeyException + */ + public void AddSigner( + AsymmetricKeyParameter privateKey, + byte[] subjectKeyID, + string encryptionOid, + string digestOid) + { + AddSigner(privateKey, subjectKeyID, encryptionOid, digestOid, + new DefaultSignedAttributeTableGenerator(), + (CmsAttributeTableGenerator)null); + } + + /** + * add a signer with extra signed/unsigned attributes. + * @throws NoSuchAlgorithmException + * @throws InvalidKeyException + */ + public void AddSigner( + AsymmetricKeyParameter privateKey, + byte[] subjectKeyID, + string digestOid, + Asn1.Cms.AttributeTable signedAttr, + Asn1.Cms.AttributeTable unsignedAttr) + { + AddSigner(privateKey, subjectKeyID, digestOid, + new DefaultSignedAttributeTableGenerator(signedAttr), + new SimpleAttributeTableGenerator(unsignedAttr)); + } + + public void AddSigner( + AsymmetricKeyParameter privateKey, + byte[] subjectKeyID, + string digestOid, + CmsAttributeTableGenerator signedAttrGenerator, + CmsAttributeTableGenerator unsignedAttrGenerator) + { + AddSigner(privateKey, subjectKeyID, Helper.GetEncOid(privateKey, digestOid), + digestOid, signedAttrGenerator, unsignedAttrGenerator); + } + + public void AddSigner( + AsymmetricKeyParameter privateKey, + byte[] subjectKeyID, + string encryptionOid, + string digestOid, + CmsAttributeTableGenerator signedAttrGenerator, + CmsAttributeTableGenerator unsignedAttrGenerator) + { + DoAddSigner(privateKey, GetSignerIdentifier(subjectKeyID), encryptionOid, digestOid, + signedAttrGenerator, unsignedAttrGenerator); + } + + private void DoAddSigner( + AsymmetricKeyParameter privateKey, + SignerIdentifier signerIdentifier, + string encryptionOid, + string digestOid, + CmsAttributeTableGenerator signedAttrGenerator, + CmsAttributeTableGenerator unsignedAttrGenerator) + { + ConfigureDigest(digestOid); + + SignerInfoGeneratorImpl signerInf = new SignerInfoGeneratorImpl(this, privateKey, + signerIdentifier, digestOid, encryptionOid, signedAttrGenerator, unsignedAttrGenerator); + + _signerInfs.Add(new DigestAndSignerInfoGeneratorHolder(signerInf, digestOid)); + } + + internal override void AddSignerCallback( + SignerInformation si) + { + // FIXME If there were parameters in si.DigestAlgorithmID.Parameters, they are lost + // NB: Would need to call FixAlgID on the DigestAlgorithmID + + // For precalculated signers, just need to register the algorithm, not configure a digest + RegisterDigestOid(si.DigestAlgorithmID.Algorithm.Id); + } + + /** + * generate a signed object that for a CMS Signed Data object + */ + public Stream Open( + Stream outStream) + { + return Open(outStream, false); + } + + /** + * generate a signed object that for a CMS Signed Data + * object - if encapsulate is true a copy + * of the message will be included in the signature with the + * default content type "data". + */ + public Stream Open( + Stream outStream, + bool encapsulate) + { + return Open(outStream, Data, encapsulate); + } + + /** + * generate a signed object that for a CMS Signed Data + * object using the given provider - if encapsulate is true a copy + * of the message will be included in the signature with the + * default content type "data". If dataOutputStream is non null the data + * being signed will be written to the stream as it is processed. + * @param out stream the CMS object is to be written to. + * @param encapsulate true if data should be encapsulated. + * @param dataOutputStream output stream to copy the data being signed to. + */ + public Stream Open( + Stream outStream, + bool encapsulate, + Stream dataOutputStream) + { + return Open(outStream, Data, encapsulate, dataOutputStream); + } + + /** + * generate a signed object that for a CMS Signed Data + * object - if encapsulate is true a copy + * of the message will be included in the signature. The content type + * is set according to the OID represented by the string signedContentType. + */ + public Stream Open( + Stream outStream, + string signedContentType, + bool encapsulate) + { + return Open(outStream, signedContentType, encapsulate, null); + } + + /** + * generate a signed object that for a CMS Signed Data + * object using the given provider - if encapsulate is true a copy + * of the message will be included in the signature. The content type + * is set according to the OID represented by the string signedContentType. + * @param out stream the CMS object is to be written to. + * @param signedContentType OID for data to be signed. + * @param encapsulate true if data should be encapsulated. + * @param dataOutputStream output stream to copy the data being signed to. + */ + public Stream Open( + Stream outStream, + string signedContentType, + bool encapsulate, + Stream dataOutputStream) + { + if (outStream == null) + throw new ArgumentNullException("outStream"); + if (!outStream.CanWrite) + throw new ArgumentException("Expected writeable stream", "outStream"); + if (dataOutputStream != null && !dataOutputStream.CanWrite) + throw new ArgumentException("Expected writeable stream", "dataOutputStream"); + + _messageDigestsLocked = true; + + // + // ContentInfo + // + BerSequenceGenerator sGen = new BerSequenceGenerator(outStream); + + sGen.AddObject(CmsObjectIdentifiers.SignedData); + + // + // Signed Data + // + BerSequenceGenerator sigGen = new BerSequenceGenerator( + sGen.GetRawOutputStream(), 0, true); + + bool isCounterSignature = (signedContentType == null); + + DerObjectIdentifier contentTypeOid = isCounterSignature + ? null + : new DerObjectIdentifier(signedContentType); + + sigGen.AddObject(CalculateVersion(contentTypeOid)); + + Asn1EncodableVector digestAlgs = new Asn1EncodableVector(); + + foreach (string digestOid in _messageDigestOids) + { + digestAlgs.Add( + new AlgorithmIdentifier(new DerObjectIdentifier(digestOid), DerNull.Instance)); + } + + { + byte[] tmp = new DerSet(digestAlgs).GetEncoded(); + sigGen.GetRawOutputStream().Write(tmp, 0, tmp.Length); + } + + BerSequenceGenerator eiGen = new BerSequenceGenerator(sigGen.GetRawOutputStream()); + eiGen.AddObject(contentTypeOid); + + // If encapsulating, add the data as an octet string in the sequence + Stream encapStream = encapsulate + ? CmsUtilities.CreateBerOctetOutputStream(eiGen.GetRawOutputStream(), 0, true, _bufferSize) + : null; + + // Also send the data to 'dataOutputStream' if necessary + Stream teeStream = GetSafeTeeOutputStream(dataOutputStream, encapStream); + + // Let all the digests see the data as it is written + Stream digStream = AttachDigestsToOutputStream(_messageDigests.Values, teeStream); + + return new CmsSignedDataOutputStream(this, digStream, signedContentType, sGen, sigGen, eiGen); + } + + private void RegisterDigestOid( + string digestOid) + { + if (_messageDigestsLocked) + { + if (!_messageDigestOids.Contains(digestOid)) + throw new InvalidOperationException("Cannot register new digest OIDs after the data stream is opened"); + } + else + { + _messageDigestOids.Add(digestOid); + } + } + + private void ConfigureDigest( + string digestOid) + { + RegisterDigestOid(digestOid); + + string digestName = Helper.GetDigestAlgName(digestOid); + IDigest dig = (IDigest)_messageDigests[digestName]; + if (dig == null) + { + if (_messageDigestsLocked) + throw new InvalidOperationException("Cannot configure new digests after the data stream is opened"); + + dig = Helper.GetDigestInstance(digestName); + _messageDigests[digestName] = dig; + } + } + + // TODO Make public? + internal void Generate( + Stream outStream, + string eContentType, + bool encapsulate, + Stream dataOutputStream, + CmsProcessable content) + { + Stream signedOut = Open(outStream, eContentType, encapsulate, dataOutputStream); + if (content != null) + { + content.Write(signedOut); + } + Platform.Dispose(signedOut); + } + + // RFC3852, section 5.1: + // IF ((certificates is present) AND + // (any certificates with a type of other are present)) OR + // ((crls is present) AND + // (any crls with a type of other are present)) + // THEN version MUST be 5 + // ELSE + // IF (certificates is present) AND + // (any version 2 attribute certificates are present) + // THEN version MUST be 4 + // ELSE + // IF ((certificates is present) AND + // (any version 1 attribute certificates are present)) OR + // (any SignerInfo structures are version 3) OR + // (encapContentInfo eContentType is other than id-data) + // THEN version MUST be 3 + // ELSE version MUST be 1 + // + private DerInteger CalculateVersion( + DerObjectIdentifier contentOid) + { + bool otherCert = false; + bool otherCrl = false; + bool attrCertV1Found = false; + bool attrCertV2Found = false; + + if (_certs != null) + { + foreach (object obj in _certs) + { + if (obj is Asn1TaggedObject) + { + Asn1TaggedObject tagged = (Asn1TaggedObject) obj; + + if (tagged.TagNo == 1) + { + attrCertV1Found = true; + } + else if (tagged.TagNo == 2) + { + attrCertV2Found = true; + } + else if (tagged.TagNo == 3) + { + otherCert = true; + break; + } + } + } + } + + if (otherCert) + { + return new DerInteger(5); + } + + if (_crls != null) + { + foreach (object obj in _crls) + { + if (obj is Asn1TaggedObject) + { + otherCrl = true; + break; + } + } + } + + if (otherCrl) + { + return new DerInteger(5); + } + + if (attrCertV2Found) + { + return new DerInteger(4); + } + + if (attrCertV1Found || !CmsObjectIdentifiers.Data.Equals(contentOid) || CheckForVersion3(_signers)) + { + return new DerInteger(3); + } + + return new DerInteger(1); + } + + private bool CheckForVersion3( + IList signerInfos) + { + foreach (SignerInformation si in signerInfos) + { + SignerInfo s = SignerInfo.GetInstance(si.ToSignerInfo()); + + if (s.Version.IntValueExact == 3) + { + return true; + } + } + + return false; + } + + private static Stream AttachDigestsToOutputStream(ICollection digests, Stream s) + { + Stream result = s; + foreach (IDigest digest in digests) + { + result = GetSafeTeeOutputStream(result, new DigestSink(digest)); + } + return result; + } + + private static Stream GetSafeOutputStream(Stream s) + { + if (s == null) + return new NullOutputStream(); + return s; + } + + private static Stream GetSafeTeeOutputStream(Stream s1, Stream s2) + { + if (s1 == null) + return GetSafeOutputStream(s2); + if (s2 == null) + return GetSafeOutputStream(s1); + return new TeeOutputStream(s1, s2); + } + + private class CmsSignedDataOutputStream + : BaseOutputStream + { + private readonly CmsSignedDataStreamGenerator outer; + + private Stream _out; + private DerObjectIdentifier _contentOID; + private BerSequenceGenerator _sGen; + private BerSequenceGenerator _sigGen; + private BerSequenceGenerator _eiGen; + + public CmsSignedDataOutputStream( + CmsSignedDataStreamGenerator outer, + Stream outStream, + string contentOID, + BerSequenceGenerator sGen, + BerSequenceGenerator sigGen, + BerSequenceGenerator eiGen) + { + this.outer = outer; + + _out = outStream; + _contentOID = new DerObjectIdentifier(contentOID); + _sGen = sGen; + _sigGen = sigGen; + _eiGen = eiGen; + } + + public override void WriteByte( + byte b) + { + _out.WriteByte(b); + } + + public override void Write( + byte[] bytes, + int off, + int len) + { + _out.Write(bytes, off, len); + } + +#if PORTABLE + protected override void Dispose(bool disposing) + { + if (disposing) + { + DoClose(); + } + base.Dispose(disposing); + } +#else + public override void Close() + { + DoClose(); + base.Close(); + } +#endif + + private void DoClose() + { + Platform.Dispose(_out); + + // TODO Parent context(s) should really be be closed explicitly + + _eiGen.Close(); + + outer._digests.Clear(); // clear the current preserved digest state + + if (outer._certs.Count > 0) + { + Asn1Set certs = outer.UseDerForCerts + ? CmsUtilities.CreateDerSetFromList(outer._certs) + : CmsUtilities.CreateBerSetFromList(outer._certs); + + WriteToGenerator(_sigGen, new BerTaggedObject(false, 0, certs)); + } + + if (outer._crls.Count > 0) + { + Asn1Set crls = outer.UseDerForCrls + ? CmsUtilities.CreateDerSetFromList(outer._crls) + : CmsUtilities.CreateBerSetFromList(outer._crls); + + WriteToGenerator(_sigGen, new BerTaggedObject(false, 1, crls)); + } + + // + // Calculate the digest hashes + // + foreach (DictionaryEntry de in outer._messageDigests) + { + outer._messageHashes.Add(de.Key, DigestUtilities.DoFinal((IDigest)de.Value)); + } + + // TODO If the digest OIDs for precalculated signers weren't mixed in with + // the others, we could fill in outer._digests here, instead of SignerInfoGenerator.Generate + + // + // collect all the SignerInfo objects + // + Asn1EncodableVector signerInfos = new Asn1EncodableVector(); + + // + // add the generated SignerInfo objects + // + { + foreach (DigestAndSignerInfoGeneratorHolder holder in outer._signerInfs) + { + AlgorithmIdentifier digestAlgorithm = holder.DigestAlgorithm; + + byte[] calculatedDigest = (byte[])outer._messageHashes[ + Helper.GetDigestAlgName(holder.digestOID)]; + outer._digests[holder.digestOID] = calculatedDigest.Clone(); + + signerInfos.Add(holder.signerInf.Generate(_contentOID, digestAlgorithm, calculatedDigest)); + } + } + + // + // add the precalculated SignerInfo objects. + // + { + foreach (SignerInformation signer in outer._signers) + { + // TODO Verify the content type and calculated digest match the precalculated SignerInfo +// if (!signer.ContentType.Equals(_contentOID)) +// { +// // TODO The precalculated content type did not match - error? +// } +// +// byte[] calculatedDigest = (byte[])outer._digests[signer.DigestAlgOid]; +// if (calculatedDigest == null) +// { +// // TODO We can't confirm this digest because we didn't calculate it - error? +// } +// else +// { +// if (!Arrays.AreEqual(signer.GetContentDigest(), calculatedDigest)) +// { +// // TODO The precalculated digest did not match - error? +// } +// } + + signerInfos.Add(signer.ToSignerInfo()); + } + } + + WriteToGenerator(_sigGen, new DerSet(signerInfos)); + + _sigGen.Close(); + _sGen.Close(); + } + + private static void WriteToGenerator( + Asn1Generator ag, + Asn1Encodable ae) + { + byte[] encoded = ae.GetEncoded(); + ag.GetRawOutputStream().Write(encoded, 0, encoded.Length); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSSignedDataStreamGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSSignedDataStreamGenerator.cs.meta new file mode 100644 index 0000000..a4b9786 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSSignedDataStreamGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7363f364014c19a4bbd5ce273501504c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSSignedGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSSignedGenerator.cs new file mode 100644 index 0000000..95d5ba6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSSignedGenerator.cs @@ -0,0 +1,654 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.BC; +using Org.BouncyCastle.Asn1.Bsi; +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Asn1.Eac; +using Org.BouncyCastle.Asn1.GM; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Oiw; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.Rosstandart; +using Org.BouncyCastle.Asn1.TeleTrust; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; +using Org.BouncyCastle.X509; +using Org.BouncyCastle.X509.Store; + +namespace Org.BouncyCastle.Cms +{ + public class DefaultSignatureAlgorithmIdentifierFinder + { + private static readonly IDictionary algorithms = Platform.CreateHashtable(); + private static readonly ISet noParams = new HashSet(); + private static readonly IDictionary _params = Platform.CreateHashtable(); + private static readonly ISet pkcs15RsaEncryption = new HashSet(); + private static readonly IDictionary digestOids = Platform.CreateHashtable(); + + private static readonly IDictionary digestBuilders = Platform.CreateHashtable(); + + private static readonly DerObjectIdentifier ENCRYPTION_RSA = PkcsObjectIdentifiers.RsaEncryption; + private static readonly DerObjectIdentifier ENCRYPTION_DSA = X9ObjectIdentifiers.IdDsaWithSha1; + private static readonly DerObjectIdentifier ENCRYPTION_ECDSA = X9ObjectIdentifiers.ECDsaWithSha1; + private static readonly DerObjectIdentifier ENCRYPTION_RSA_PSS = PkcsObjectIdentifiers.IdRsassaPss; + private static readonly DerObjectIdentifier ENCRYPTION_GOST3410 = CryptoProObjectIdentifiers.GostR3410x94; + private static readonly DerObjectIdentifier ENCRYPTION_ECGOST3410 = CryptoProObjectIdentifiers.GostR3410x2001; + private static readonly DerObjectIdentifier ENCRYPTION_ECGOST3410_2012_256 = RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256; + private static readonly DerObjectIdentifier ENCRYPTION_ECGOST3410_2012_512 = RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512; + + static DefaultSignatureAlgorithmIdentifierFinder() + { + algorithms["MD2WITHRSAENCRYPTION"] = PkcsObjectIdentifiers.MD2WithRsaEncryption; + algorithms["MD2WITHRSA"] = PkcsObjectIdentifiers.MD2WithRsaEncryption; + algorithms["MD5WITHRSAENCRYPTION"] = PkcsObjectIdentifiers.MD5WithRsaEncryption; + algorithms["MD5WITHRSA"] = PkcsObjectIdentifiers.MD5WithRsaEncryption; + algorithms["SHA1WITHRSAENCRYPTION"] = PkcsObjectIdentifiers.Sha1WithRsaEncryption; + algorithms["SHA-1WITHRSAENCRYPTION"] = PkcsObjectIdentifiers.Sha1WithRsaEncryption; + algorithms["SHA1WITHRSA"] = PkcsObjectIdentifiers.Sha1WithRsaEncryption; + algorithms["SHA-1WITHRSA"] = PkcsObjectIdentifiers.Sha1WithRsaEncryption; + algorithms["SHA224WITHRSAENCRYPTION"] = PkcsObjectIdentifiers.Sha224WithRsaEncryption; + algorithms["SHA-224WITHRSAENCRYPTION"] = PkcsObjectIdentifiers.Sha224WithRsaEncryption; + algorithms["SHA224WITHRSA"] = PkcsObjectIdentifiers.Sha224WithRsaEncryption; + algorithms["SHA-224WITHRSA"] = PkcsObjectIdentifiers.Sha224WithRsaEncryption; + algorithms["SHA256WITHRSAENCRYPTION"] = PkcsObjectIdentifiers.Sha256WithRsaEncryption; + algorithms["SHA-256WITHRSAENCRYPTION"] = PkcsObjectIdentifiers.Sha256WithRsaEncryption; + algorithms["SHA256WITHRSA"] = PkcsObjectIdentifiers.Sha256WithRsaEncryption; + algorithms["SHA-256WITHRSA"] = PkcsObjectIdentifiers.Sha256WithRsaEncryption; + algorithms["SHA384WITHRSAENCRYPTION"] = PkcsObjectIdentifiers.Sha384WithRsaEncryption; + algorithms["SHA-384WITHRSAENCRYPTION"] = PkcsObjectIdentifiers.Sha384WithRsaEncryption; + algorithms["SHA384WITHRSA"] = PkcsObjectIdentifiers.Sha384WithRsaEncryption; + algorithms["SHA-384WITHRSA"] = PkcsObjectIdentifiers.Sha384WithRsaEncryption; + algorithms["SHA512WITHRSAENCRYPTION"] = PkcsObjectIdentifiers.Sha512WithRsaEncryption; + algorithms["SHA-512WITHRSAENCRYPTION"] = PkcsObjectIdentifiers.Sha512WithRsaEncryption; + algorithms["SHA512WITHRSA"] = PkcsObjectIdentifiers.Sha512WithRsaEncryption; + algorithms["SHA-512WITHRSA"] = PkcsObjectIdentifiers.Sha512WithRsaEncryption; + algorithms["SHA512(224)WITHRSAENCRYPTION"] = PkcsObjectIdentifiers.Sha512_224WithRSAEncryption; + algorithms["SHA-512(224)WITHRSAENCRYPTION"] = PkcsObjectIdentifiers.Sha512_224WithRSAEncryption; + algorithms["SHA512(224)WITHRSA"] = PkcsObjectIdentifiers.Sha512_224WithRSAEncryption; + algorithms["SHA-512(224)WITHRSA"] = PkcsObjectIdentifiers.Sha512_224WithRSAEncryption; + algorithms["SHA512(256)WITHRSAENCRYPTION"] = PkcsObjectIdentifiers.Sha512_256WithRSAEncryption; + algorithms["SHA-512(256)WITHRSAENCRYPTION"] = PkcsObjectIdentifiers.Sha512_256WithRSAEncryption; + algorithms["SHA512(256)WITHRSA"] = PkcsObjectIdentifiers.Sha512_256WithRSAEncryption; + algorithms["SHA-512(256)WITHRSA"] = PkcsObjectIdentifiers.Sha512_256WithRSAEncryption; + algorithms["SHA1WITHRSAANDMGF1"] = PkcsObjectIdentifiers.IdRsassaPss; + algorithms["SHA224WITHRSAANDMGF1"] = PkcsObjectIdentifiers.IdRsassaPss; + algorithms["SHA256WITHRSAANDMGF1"] = PkcsObjectIdentifiers.IdRsassaPss; + algorithms["SHA384WITHRSAANDMGF1"] = PkcsObjectIdentifiers.IdRsassaPss; + algorithms["SHA512WITHRSAANDMGF1"] = PkcsObjectIdentifiers.IdRsassaPss; + algorithms["SHA3-224WITHRSAANDMGF1"] = PkcsObjectIdentifiers.IdRsassaPss; + algorithms["SHA3-256WITHRSAANDMGF1"] = PkcsObjectIdentifiers.IdRsassaPss; + algorithms["SHA3-384WITHRSAANDMGF1"] = PkcsObjectIdentifiers.IdRsassaPss; + algorithms["SHA3-512WITHRSAANDMGF1"] = PkcsObjectIdentifiers.IdRsassaPss; + algorithms["RIPEMD160WITHRSAENCRYPTION"] = TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160; + algorithms["RIPEMD160WITHRSA"] = TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160; + algorithms["RIPEMD128WITHRSAENCRYPTION"] = TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128; + algorithms["RIPEMD128WITHRSA"] = TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128; + algorithms["RIPEMD256WITHRSAENCRYPTION"] = TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256; + algorithms["RIPEMD256WITHRSA"] = TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256; + algorithms["SHA1WITHDSA"] = X9ObjectIdentifiers.IdDsaWithSha1; + algorithms["SHA-1WITHDSA"] = X9ObjectIdentifiers.IdDsaWithSha1; + algorithms["DSAWITHSHA1"] = X9ObjectIdentifiers.IdDsaWithSha1; + algorithms["SHA224WITHDSA"] = NistObjectIdentifiers.DsaWithSha224; + algorithms["SHA256WITHDSA"] = NistObjectIdentifiers.DsaWithSha256; + algorithms["SHA384WITHDSA"] = NistObjectIdentifiers.DsaWithSha384; + algorithms["SHA512WITHDSA"] = NistObjectIdentifiers.DsaWithSha512; + algorithms["SHA3-224WITHDSA"] = NistObjectIdentifiers.IdDsaWithSha3_224; + algorithms["SHA3-256WITHDSA"] = NistObjectIdentifiers.IdDsaWithSha3_256; + algorithms["SHA3-384WITHDSA"] = NistObjectIdentifiers.IdDsaWithSha3_384; + algorithms["SHA3-512WITHDSA"] = NistObjectIdentifiers.IdDsaWithSha3_512; + algorithms["SHA3-224WITHECDSA"] = NistObjectIdentifiers.IdEcdsaWithSha3_224; + algorithms["SHA3-256WITHECDSA"] = NistObjectIdentifiers.IdEcdsaWithSha3_256; + algorithms["SHA3-384WITHECDSA"] = NistObjectIdentifiers.IdEcdsaWithSha3_384; + algorithms["SHA3-512WITHECDSA"] = NistObjectIdentifiers.IdEcdsaWithSha3_512; + algorithms["SHA3-224WITHRSA"] = NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_224; + algorithms["SHA3-256WITHRSA"] = NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_256; + algorithms["SHA3-384WITHRSA"] = NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_384; + algorithms["SHA3-512WITHRSA"] = NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_512; + algorithms["SHA3-224WITHRSAENCRYPTION"] = NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_224; + algorithms["SHA3-256WITHRSAENCRYPTION"] = NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_256; + algorithms["SHA3-384WITHRSAENCRYPTION"] = NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_384; + algorithms["SHA3-512WITHRSAENCRYPTION"] = NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_512; + algorithms["SHA1WITHECDSA"] = X9ObjectIdentifiers.ECDsaWithSha1; + algorithms["ECDSAWITHSHA1"] = X9ObjectIdentifiers.ECDsaWithSha1; + algorithms["SHA224WITHECDSA"] = X9ObjectIdentifiers.ECDsaWithSha224; + algorithms["SHA256WITHECDSA"] = X9ObjectIdentifiers.ECDsaWithSha256; + algorithms["SHA384WITHECDSA"] = X9ObjectIdentifiers.ECDsaWithSha384; + algorithms["SHA512WITHECDSA"] = X9ObjectIdentifiers.ECDsaWithSha512; + + + algorithms["GOST3411WITHGOST3410"] = CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94; + algorithms["GOST3411WITHGOST3410-94"] = CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94; + algorithms["GOST3411WITHECGOST3410"] = CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001; + algorithms["GOST3411WITHECGOST3410-2001"] = CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001; + algorithms["GOST3411WITHGOST3410-2001"] = CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001; + algorithms["GOST3411WITHECGOST3410-2012-256"] = RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_256; + algorithms["GOST3411WITHECGOST3410-2012-512"] = RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512; + algorithms["GOST3411WITHGOST3410-2012-256"] = RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_256; + algorithms["GOST3411WITHGOST3410-2012-512"] = RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512; + algorithms["GOST3411-2012-256WITHECGOST3410-2012-256"] = RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_256; + algorithms["GOST3411-2012-512WITHECGOST3410-2012-512"] = RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512; + algorithms["GOST3411-2012-256WITHGOST3410-2012-256"] = RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_256; + algorithms["GOST3411-2012-512WITHGOST3410-2012-512"] = RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512; + algorithms["SHA1WITHPLAIN-ECDSA"] = BsiObjectIdentifiers.ecdsa_plain_SHA1; + algorithms["SHA224WITHPLAIN-ECDSA"] = BsiObjectIdentifiers.ecdsa_plain_SHA224; + algorithms["SHA256WITHPLAIN-ECDSA"] = BsiObjectIdentifiers.ecdsa_plain_SHA256; + algorithms["SHA384WITHPLAIN-ECDSA"] = BsiObjectIdentifiers.ecdsa_plain_SHA384; + algorithms["SHA512WITHPLAIN-ECDSA"] = BsiObjectIdentifiers.ecdsa_plain_SHA512; + algorithms["RIPEMD160WITHPLAIN-ECDSA"] = BsiObjectIdentifiers.ecdsa_plain_RIPEMD160; + algorithms["SHA1WITHCVC-ECDSA"] = EacObjectIdentifiers.id_TA_ECDSA_SHA_1; + algorithms["SHA224WITHCVC-ECDSA"] = EacObjectIdentifiers.id_TA_ECDSA_SHA_224; + algorithms["SHA256WITHCVC-ECDSA"] = EacObjectIdentifiers.id_TA_ECDSA_SHA_256; + algorithms["SHA384WITHCVC-ECDSA"] = EacObjectIdentifiers.id_TA_ECDSA_SHA_384; + algorithms["SHA512WITHCVC-ECDSA"] = EacObjectIdentifiers.id_TA_ECDSA_SHA_512; + algorithms["SHA3-512WITHSPHINCS256"] = BCObjectIdentifiers.sphincs256_with_SHA3_512; + algorithms["SHA512WITHSPHINCS256"] = BCObjectIdentifiers.sphincs256_with_SHA512; + + algorithms["SHA256WITHSM2"] = GMObjectIdentifiers.sm2sign_with_sha256; + algorithms["SM3WITHSM2"] = GMObjectIdentifiers.sm2sign_with_sm3; + + algorithms["SHA256WITHXMSS"] = BCObjectIdentifiers.xmss_with_SHA256; + algorithms["SHA512WITHXMSS"] = BCObjectIdentifiers.xmss_with_SHA512; + algorithms["SHAKE128WITHXMSS"] = BCObjectIdentifiers.xmss_with_SHAKE128; + algorithms["SHAKE256WITHXMSS"] = BCObjectIdentifiers.xmss_with_SHAKE256; + + algorithms["SHA256WITHXMSSMT"] = BCObjectIdentifiers.xmss_mt_with_SHA256; + algorithms["SHA512WITHXMSSMT"] = BCObjectIdentifiers.xmss_mt_with_SHA512; + algorithms["SHAKE128WITHXMSSMT"] = BCObjectIdentifiers.xmss_mt_with_SHAKE128; + algorithms["SHAKE256WITHXMSSMT"] = BCObjectIdentifiers.xmss_mt_with_SHAKE256; + + + // + // According to RFC 3279, the ASN.1 encoding SHALL (id-dsa-with-sha1) or MUST (ecdsa-with-SHA*) omit the parameters field. + // The parameters field SHALL be NULL for RSA based signature algorithms. + // + noParams.Add((object)X9ObjectIdentifiers.ECDsaWithSha1); + noParams.Add((object)X9ObjectIdentifiers.ECDsaWithSha224); + noParams.Add((object)X9ObjectIdentifiers.ECDsaWithSha256); + noParams.Add((object)X9ObjectIdentifiers.ECDsaWithSha384); + noParams.Add((object)X9ObjectIdentifiers.ECDsaWithSha512); + noParams.Add((object)X9ObjectIdentifiers.IdDsaWithSha1); + noParams.Add((object)NistObjectIdentifiers.DsaWithSha224); + noParams.Add((object)NistObjectIdentifiers.DsaWithSha256); + noParams.Add((object)NistObjectIdentifiers.DsaWithSha384); + noParams.Add((object)NistObjectIdentifiers.DsaWithSha512); + noParams.Add((object)NistObjectIdentifiers.IdDsaWithSha3_224); + noParams.Add((object)NistObjectIdentifiers.IdDsaWithSha3_256); + noParams.Add((object)NistObjectIdentifiers.IdDsaWithSha3_384); + noParams.Add((object)NistObjectIdentifiers.IdDsaWithSha3_512); + noParams.Add((object)NistObjectIdentifiers.IdEcdsaWithSha3_224); + noParams.Add((object)NistObjectIdentifiers.IdEcdsaWithSha3_256); + noParams.Add((object)NistObjectIdentifiers.IdEcdsaWithSha3_384); + noParams.Add((object)NistObjectIdentifiers.IdEcdsaWithSha3_512); + + + // + // RFC 4491 + // + noParams.Add((object)CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94); + noParams.Add((object)CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001); + noParams.Add((object)RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_256); + noParams.Add((object)RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512); + + // + // SPHINCS-256 + // + noParams.Add((object)BCObjectIdentifiers.sphincs256_with_SHA512); + noParams.Add((object)BCObjectIdentifiers.sphincs256_with_SHA3_512); + + // + // XMSS + // + noParams.Add((object)BCObjectIdentifiers.xmss_with_SHA256); + noParams.Add((object)BCObjectIdentifiers.xmss_with_SHA512); + noParams.Add((object)BCObjectIdentifiers.xmss_with_SHAKE128); + noParams.Add((object)BCObjectIdentifiers.xmss_with_SHAKE256); + noParams.Add((object)BCObjectIdentifiers.xmss_mt_with_SHA256); + noParams.Add((object)BCObjectIdentifiers.xmss_mt_with_SHA512); + noParams.Add((object)BCObjectIdentifiers.xmss_mt_with_SHAKE128); + noParams.Add((object)BCObjectIdentifiers.xmss_mt_with_SHAKE256); + + // + // SM2 + // + noParams.Add((object)GMObjectIdentifiers.sm2sign_with_sha256); + noParams.Add((object)GMObjectIdentifiers.sm2sign_with_sm3); + + // + // PKCS 1.5 encrypted algorithms + // + pkcs15RsaEncryption.Add((object)PkcsObjectIdentifiers.Sha1WithRsaEncryption); + pkcs15RsaEncryption.Add((object)PkcsObjectIdentifiers.Sha224WithRsaEncryption); + pkcs15RsaEncryption.Add((object)PkcsObjectIdentifiers.Sha256WithRsaEncryption); + pkcs15RsaEncryption.Add((object)PkcsObjectIdentifiers.Sha384WithRsaEncryption); + pkcs15RsaEncryption.Add((object)PkcsObjectIdentifiers.Sha512WithRsaEncryption); + pkcs15RsaEncryption.Add((object)PkcsObjectIdentifiers.Sha512_224WithRSAEncryption); + pkcs15RsaEncryption.Add((object)PkcsObjectIdentifiers.Sha512_256WithRSAEncryption); + pkcs15RsaEncryption.Add((object)TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128); + pkcs15RsaEncryption.Add((object)TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160); + pkcs15RsaEncryption.Add((object)TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256); + pkcs15RsaEncryption.Add((object)NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_224); + pkcs15RsaEncryption.Add((object)NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_256); + pkcs15RsaEncryption.Add((object)NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_384); + pkcs15RsaEncryption.Add((object)NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_512); + + // + // explicit params + // + AlgorithmIdentifier sha1AlgId = new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1, DerNull.Instance); + _params["SHA1WITHRSAANDMGF1"] = CreatePssParams(sha1AlgId, 20); + + AlgorithmIdentifier sha224AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha224, DerNull.Instance); + _params["SHA224WITHRSAANDMGF1"] = CreatePssParams(sha224AlgId, 28); + + AlgorithmIdentifier sha256AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha256, DerNull.Instance); + _params["SHA256WITHRSAANDMGF1"] = CreatePssParams(sha256AlgId, 32); + + AlgorithmIdentifier sha384AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha384, DerNull.Instance); + _params["SHA384WITHRSAANDMGF1"] = CreatePssParams(sha384AlgId, 48); + + AlgorithmIdentifier sha512AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha512, DerNull.Instance); + _params["SHA512WITHRSAANDMGF1"] = CreatePssParams(sha512AlgId, 64); + + AlgorithmIdentifier sha3_224AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha3_224, DerNull.Instance); + _params["SHA3-224WITHRSAANDMGF1"] = CreatePssParams(sha3_224AlgId, 28); + + AlgorithmIdentifier sha3_256AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha3_256, DerNull.Instance); + _params["SHA3-256WITHRSAANDMGF1"] = CreatePssParams(sha3_256AlgId, 32); + + AlgorithmIdentifier sha3_384AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha3_384, DerNull.Instance); + _params["SHA3-384WITHRSAANDMGF1"] = CreatePssParams(sha3_384AlgId, 48); + + AlgorithmIdentifier sha3_512AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha3_512, DerNull.Instance); + _params["SHA3-512WITHRSAANDMGF1"] = CreatePssParams(sha3_512AlgId, 64); + + // + // digests + // + digestOids[PkcsObjectIdentifiers.Sha224WithRsaEncryption] = NistObjectIdentifiers.IdSha224; + digestOids[PkcsObjectIdentifiers.Sha256WithRsaEncryption] = NistObjectIdentifiers.IdSha256; + digestOids[PkcsObjectIdentifiers.Sha384WithRsaEncryption] = NistObjectIdentifiers.IdSha384; + digestOids[PkcsObjectIdentifiers.Sha512WithRsaEncryption] = NistObjectIdentifiers.IdSha512; + digestOids[PkcsObjectIdentifiers.Sha512_224WithRSAEncryption] = NistObjectIdentifiers.IdSha512_224; + digestOids[PkcsObjectIdentifiers.Sha512_256WithRSAEncryption] = NistObjectIdentifiers.IdSha512_256; + digestOids[NistObjectIdentifiers.DsaWithSha224] = NistObjectIdentifiers.IdSha224; + digestOids[NistObjectIdentifiers.DsaWithSha256] = NistObjectIdentifiers.IdSha256; + digestOids[NistObjectIdentifiers.DsaWithSha384] = NistObjectIdentifiers.IdSha384; + digestOids[NistObjectIdentifiers.DsaWithSha512] = NistObjectIdentifiers.IdSha512; + digestOids[NistObjectIdentifiers.IdDsaWithSha3_224] = NistObjectIdentifiers.IdSha3_224; + digestOids[NistObjectIdentifiers.IdDsaWithSha3_256] = NistObjectIdentifiers.IdSha3_256; + digestOids[NistObjectIdentifiers.IdDsaWithSha3_384] = NistObjectIdentifiers.IdSha3_384; + digestOids[NistObjectIdentifiers.IdDsaWithSha3_512] = NistObjectIdentifiers.IdSha3_512; + digestOids[NistObjectIdentifiers.IdEcdsaWithSha3_224] = NistObjectIdentifiers.IdSha3_224; + digestOids[NistObjectIdentifiers.IdEcdsaWithSha3_256] = NistObjectIdentifiers.IdSha3_256; + digestOids[NistObjectIdentifiers.IdEcdsaWithSha3_384] = NistObjectIdentifiers.IdSha3_384; + digestOids[NistObjectIdentifiers.IdEcdsaWithSha3_512] = NistObjectIdentifiers.IdSha3_512; + digestOids[NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_224] = NistObjectIdentifiers.IdSha3_224; + digestOids[NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_256] = NistObjectIdentifiers.IdSha3_256; + digestOids[NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_384] = NistObjectIdentifiers.IdSha3_384; + digestOids[NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_512] = NistObjectIdentifiers.IdSha3_512; + + digestOids[PkcsObjectIdentifiers.MD2WithRsaEncryption] = PkcsObjectIdentifiers.MD2; + digestOids[PkcsObjectIdentifiers.MD4WithRsaEncryption] = PkcsObjectIdentifiers.MD4; + digestOids[PkcsObjectIdentifiers.MD5WithRsaEncryption] = PkcsObjectIdentifiers.MD5; + digestOids[PkcsObjectIdentifiers.Sha1WithRsaEncryption] = OiwObjectIdentifiers.IdSha1; + digestOids[TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128] = TeleTrusTObjectIdentifiers.RipeMD128; + digestOids[TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160] = TeleTrusTObjectIdentifiers.RipeMD160; + digestOids[TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256] = TeleTrusTObjectIdentifiers.RipeMD256; + digestOids[CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94] = CryptoProObjectIdentifiers.GostR3411; + digestOids[CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001] = CryptoProObjectIdentifiers.GostR3411; + digestOids[RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_256] = RosstandartObjectIdentifiers.id_tc26_gost_3411_12_256; + digestOids[RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512] = RosstandartObjectIdentifiers.id_tc26_gost_3411_12_512; + + digestOids[GMObjectIdentifiers.sm2sign_with_sha256] = NistObjectIdentifiers.IdSha256; + digestOids[GMObjectIdentifiers.sm2sign_with_sm3] = GMObjectIdentifiers.sm3; + } + + private static AlgorithmIdentifier Generate(string signatureAlgorithm) + { + AlgorithmIdentifier sigAlgId; + AlgorithmIdentifier encAlgId; + AlgorithmIdentifier digAlgId; + + string algorithmName = Strings.ToUpperCase(signatureAlgorithm); + DerObjectIdentifier sigOID = (DerObjectIdentifier)algorithms[algorithmName]; + if (sigOID == null) + { + throw new ArgumentException("Unknown signature type requested: " + algorithmName); + } + + if (noParams.Contains(sigOID)) + { + sigAlgId = new AlgorithmIdentifier(sigOID); + } + else if (_params.Contains(algorithmName)) + { + sigAlgId = new AlgorithmIdentifier(sigOID, (Asn1Encodable)_params[algorithmName]); + } + else + { + sigAlgId = new AlgorithmIdentifier(sigOID, DerNull.Instance); + } + + if (pkcs15RsaEncryption.Contains(sigOID)) + { + encAlgId = new AlgorithmIdentifier(PkcsObjectIdentifiers.RsaEncryption, DerNull.Instance); + } + else + { + encAlgId = sigAlgId; + } + + if (sigAlgId.Algorithm.Equals(PkcsObjectIdentifiers.IdRsassaPss)) + { + digAlgId = ((RsassaPssParameters)sigAlgId.Parameters).HashAlgorithm; + } + else + { + digAlgId = new AlgorithmIdentifier((DerObjectIdentifier)digestOids[sigOID], DerNull.Instance); + } + + return sigAlgId; + } + + private static RsassaPssParameters CreatePssParams(AlgorithmIdentifier hashAlgId, int saltSize) + { + return new RsassaPssParameters( + hashAlgId, + new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, hashAlgId), + new DerInteger(saltSize), + new DerInteger(1)); + } + + public AlgorithmIdentifier Find(string sigAlgName) + { + return Generate(sigAlgName); + } + } + + public class DefaultDigestAlgorithmIdentifierFinder + { + private static readonly IDictionary digestOids = Platform.CreateHashtable(); + private static readonly IDictionary digestNameToOids = Platform.CreateHashtable(); + + static DefaultDigestAlgorithmIdentifierFinder() + { + // + // digests + // + digestOids.Add(OiwObjectIdentifiers.MD4WithRsaEncryption, PkcsObjectIdentifiers.MD4); + digestOids.Add(OiwObjectIdentifiers.MD4WithRsa, PkcsObjectIdentifiers.MD4); + digestOids.Add(OiwObjectIdentifiers.MD5WithRsa, PkcsObjectIdentifiers.MD5); + digestOids.Add(OiwObjectIdentifiers.Sha1WithRsa, OiwObjectIdentifiers.IdSha1); + digestOids.Add(OiwObjectIdentifiers.DsaWithSha1, OiwObjectIdentifiers.IdSha1); + + digestOids.Add(PkcsObjectIdentifiers.Sha224WithRsaEncryption, NistObjectIdentifiers.IdSha224); + digestOids.Add(PkcsObjectIdentifiers.Sha256WithRsaEncryption, NistObjectIdentifiers.IdSha256); + digestOids.Add(PkcsObjectIdentifiers.Sha384WithRsaEncryption, NistObjectIdentifiers.IdSha384); + digestOids.Add(PkcsObjectIdentifiers.Sha512WithRsaEncryption, NistObjectIdentifiers.IdSha512); + digestOids.Add(PkcsObjectIdentifiers.Sha512_224WithRSAEncryption, NistObjectIdentifiers.IdSha512_224); + digestOids.Add(PkcsObjectIdentifiers.Sha512_256WithRSAEncryption, NistObjectIdentifiers.IdSha512_256); + + digestOids.Add(NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_224, NistObjectIdentifiers.IdSha3_224); + digestOids.Add(NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_256, NistObjectIdentifiers.IdSha3_256); + digestOids.Add(NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_384, NistObjectIdentifiers.IdSha3_384); + digestOids.Add(NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_512, NistObjectIdentifiers.IdSha3_512); + + digestOids.Add(PkcsObjectIdentifiers.MD2WithRsaEncryption, PkcsObjectIdentifiers.MD2); + digestOids.Add(PkcsObjectIdentifiers.MD4WithRsaEncryption, PkcsObjectIdentifiers.MD4); + digestOids.Add(PkcsObjectIdentifiers.MD5WithRsaEncryption, PkcsObjectIdentifiers.MD5); + digestOids.Add(PkcsObjectIdentifiers.Sha1WithRsaEncryption, OiwObjectIdentifiers.IdSha1); + + digestOids.Add(X9ObjectIdentifiers.ECDsaWithSha1, OiwObjectIdentifiers.IdSha1); + digestOids.Add(X9ObjectIdentifiers.ECDsaWithSha224, NistObjectIdentifiers.IdSha224); + digestOids.Add(X9ObjectIdentifiers.ECDsaWithSha256, NistObjectIdentifiers.IdSha256); + digestOids.Add(X9ObjectIdentifiers.ECDsaWithSha384, NistObjectIdentifiers.IdSha384); + digestOids.Add(X9ObjectIdentifiers.ECDsaWithSha512, NistObjectIdentifiers.IdSha512); + digestOids.Add(X9ObjectIdentifiers.IdDsaWithSha1, OiwObjectIdentifiers.IdSha1); + + digestOids.Add(NistObjectIdentifiers.DsaWithSha224, NistObjectIdentifiers.IdSha224); + digestOids.Add(NistObjectIdentifiers.DsaWithSha256, NistObjectIdentifiers.IdSha256); + digestOids.Add(NistObjectIdentifiers.DsaWithSha384, NistObjectIdentifiers.IdSha384); + digestOids.Add(NistObjectIdentifiers.DsaWithSha512, NistObjectIdentifiers.IdSha512); + + digestOids.Add(TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128, TeleTrusTObjectIdentifiers.RipeMD128); + digestOids.Add(TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160, TeleTrusTObjectIdentifiers.RipeMD160); + digestOids.Add(TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256, TeleTrusTObjectIdentifiers.RipeMD256); + + digestOids.Add(CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94, CryptoProObjectIdentifiers.GostR3411); + digestOids.Add(CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001, CryptoProObjectIdentifiers.GostR3411); + + digestNameToOids.Add("SHA-1", OiwObjectIdentifiers.IdSha1); + digestNameToOids.Add("SHA-224", NistObjectIdentifiers.IdSha224); + digestNameToOids.Add("SHA-256", NistObjectIdentifiers.IdSha256); + digestNameToOids.Add("SHA-384", NistObjectIdentifiers.IdSha384); + digestNameToOids.Add("SHA-512", NistObjectIdentifiers.IdSha512); + digestNameToOids.Add("SHA-512/224", NistObjectIdentifiers.IdSha512_224); + digestNameToOids.Add("SHA-512(224)", NistObjectIdentifiers.IdSha512_224); + digestNameToOids.Add("SHA-512/256", NistObjectIdentifiers.IdSha512_256); + digestNameToOids.Add("SHA-512(256)", NistObjectIdentifiers.IdSha512_256); + + digestNameToOids.Add("SHA1", OiwObjectIdentifiers.IdSha1); + digestNameToOids.Add("SHA224", NistObjectIdentifiers.IdSha224); + digestNameToOids.Add("SHA256", NistObjectIdentifiers.IdSha256); + digestNameToOids.Add("SHA384", NistObjectIdentifiers.IdSha384); + digestNameToOids.Add("SHA512", NistObjectIdentifiers.IdSha512); + digestNameToOids.Add("SHA512/224", NistObjectIdentifiers.IdSha512_224); + digestNameToOids.Add("SHA512(224)", NistObjectIdentifiers.IdSha512_224); + digestNameToOids.Add("SHA512/256", NistObjectIdentifiers.IdSha512_256); + digestNameToOids.Add("SHA512(256)", NistObjectIdentifiers.IdSha512_256); + + digestNameToOids.Add("SHA3-224", NistObjectIdentifiers.IdSha3_224); + digestNameToOids.Add("SHA3-256", NistObjectIdentifiers.IdSha3_256); + digestNameToOids.Add("SHA3-384", NistObjectIdentifiers.IdSha3_384); + digestNameToOids.Add("SHA3-512", NistObjectIdentifiers.IdSha3_512); + + digestNameToOids.Add("SHAKE-128", NistObjectIdentifiers.IdShake128); + digestNameToOids.Add("SHAKE-256", NistObjectIdentifiers.IdShake256); + + digestNameToOids.Add("GOST3411", CryptoProObjectIdentifiers.GostR3411); + + digestNameToOids.Add("MD2", PkcsObjectIdentifiers.MD2); + digestNameToOids.Add("MD4", PkcsObjectIdentifiers.MD4); + digestNameToOids.Add("MD5", PkcsObjectIdentifiers.MD5); + + digestNameToOids.Add("RIPEMD128", TeleTrusTObjectIdentifiers.RipeMD128); + digestNameToOids.Add("RIPEMD160", TeleTrusTObjectIdentifiers.RipeMD160); + digestNameToOids.Add("RIPEMD256", TeleTrusTObjectIdentifiers.RipeMD256); + } + + public AlgorithmIdentifier find(AlgorithmIdentifier sigAlgId) + { + AlgorithmIdentifier digAlgId; + + if (sigAlgId.Algorithm.Equals(PkcsObjectIdentifiers.IdRsassaPss)) + { + digAlgId = RsassaPssParameters.GetInstance(sigAlgId.Parameters).HashAlgorithm; + } + else + { + digAlgId = new AlgorithmIdentifier((DerObjectIdentifier)digestOids[sigAlgId.Algorithm], DerNull.Instance); + } + + return digAlgId; + } + + public AlgorithmIdentifier find(string digAlgName) + { + return new AlgorithmIdentifier((DerObjectIdentifier)digestNameToOids[digAlgName], DerNull.Instance); + } + } + + public class CmsSignedGenerator + { + /** + * Default type for the signed data. + */ + public static readonly string Data = CmsObjectIdentifiers.Data.Id; + + public static readonly string DigestSha1 = OiwObjectIdentifiers.IdSha1.Id; + public static readonly string DigestSha224 = NistObjectIdentifiers.IdSha224.Id; + public static readonly string DigestSha256 = NistObjectIdentifiers.IdSha256.Id; + public static readonly string DigestSha384 = NistObjectIdentifiers.IdSha384.Id; + public static readonly string DigestSha512 = NistObjectIdentifiers.IdSha512.Id; + public static readonly string DigestSha512_224 = NistObjectIdentifiers.IdSha512_224.Id; + public static readonly string DigestSha512_256 = NistObjectIdentifiers.IdSha512_256.Id; + public static readonly string DigestMD5 = PkcsObjectIdentifiers.MD5.Id; + public static readonly string DigestGost3411 = CryptoProObjectIdentifiers.GostR3411.Id; + public static readonly string DigestRipeMD128 = TeleTrusTObjectIdentifiers.RipeMD128.Id; + public static readonly string DigestRipeMD160 = TeleTrusTObjectIdentifiers.RipeMD160.Id; + public static readonly string DigestRipeMD256 = TeleTrusTObjectIdentifiers.RipeMD256.Id; + + public static readonly string EncryptionRsa = PkcsObjectIdentifiers.RsaEncryption.Id; + public static readonly string EncryptionDsa = X9ObjectIdentifiers.IdDsaWithSha1.Id; + public static readonly string EncryptionECDsa = X9ObjectIdentifiers.ECDsaWithSha1.Id; + public static readonly string EncryptionRsaPss = PkcsObjectIdentifiers.IdRsassaPss.Id; + public static readonly string EncryptionGost3410 = CryptoProObjectIdentifiers.GostR3410x94.Id; + public static readonly string EncryptionECGost3410 = CryptoProObjectIdentifiers.GostR3410x2001.Id; + + internal IList _certs = Platform.CreateArrayList(); + internal IList _crls = Platform.CreateArrayList(); + internal IList _signers = Platform.CreateArrayList(); + internal IDictionary _digests = Platform.CreateHashtable(); + internal bool _useDerForCerts = false; + internal bool _useDerForCrls = false; + + protected readonly SecureRandom rand; + + protected CmsSignedGenerator() + : this(new SecureRandom()) + { + } + + /// Constructor allowing specific source of randomness + /// Instance of SecureRandom to use. + protected CmsSignedGenerator( + SecureRandom rand) + { + this.rand = rand; + } + + internal protected virtual IDictionary GetBaseParameters( + DerObjectIdentifier contentType, + AlgorithmIdentifier digAlgId, + byte[] hash) + { + IDictionary param = Platform.CreateHashtable(); + + if (contentType != null) + { + param[CmsAttributeTableParameter.ContentType] = contentType; + } + + param[CmsAttributeTableParameter.DigestAlgorithmIdentifier] = digAlgId; + param[CmsAttributeTableParameter.Digest] = hash.Clone(); + + return param; + } + + internal protected virtual Asn1Set GetAttributeSet( + Asn1.Cms.AttributeTable attr) + { + return attr == null + ? null + : new DerSet(attr.ToAsn1EncodableVector()); + } + + public void AddCertificates( + IX509Store certStore) + { + CollectionUtilities.AddRange(_certs, CmsUtilities.GetCertificatesFromStore(certStore)); + } + + public void AddCrls( + IX509Store crlStore) + { + CollectionUtilities.AddRange(_crls, CmsUtilities.GetCrlsFromStore(crlStore)); + } + + /** + * Add the attribute certificates contained in the passed in store to the + * generator. + * + * @param store a store of Version 2 attribute certificates + * @throws CmsException if an error occurse processing the store. + */ + public void AddAttributeCertificates( + IX509Store store) + { + try + { + foreach (IX509AttributeCertificate attrCert in store.GetMatches(null)) + { + _certs.Add(new DerTaggedObject(false, 2, + AttributeCertificate.GetInstance(Asn1Object.FromByteArray(attrCert.GetEncoded())))); + } + } + catch (Exception e) + { + throw new CmsException("error processing attribute certs", e); + } + } + + /** + * Add a store of precalculated signers to the generator. + * + * @param signerStore store of signers + */ + public void AddSigners( + SignerInformationStore signerStore) + { + foreach (SignerInformation o in signerStore.GetSigners()) + { + _signers.Add(o); + AddSignerCallback(o); + } + } + + /** + * Return a map of oids and byte arrays representing the digests calculated on the content during + * the last generate. + * + * @return a map of oids (as string objects) and byte[] representing digests. + */ + public IDictionary GetGeneratedDigests() + { + return Platform.CreateHashtable(_digests); + } + + public bool UseDerForCerts + { + get { return _useDerForCerts; } + set { this._useDerForCerts = value; } + } + + public bool UseDerForCrls + { + get { return _useDerForCrls; } + set { this._useDerForCrls = value; } + } + + internal virtual void AddSignerCallback( + SignerInformation si) + { + } + + internal static SignerIdentifier GetSignerIdentifier(X509Certificate cert) + { + return new SignerIdentifier(CmsUtilities.GetIssuerAndSerialNumber(cert)); + } + + internal static SignerIdentifier GetSignerIdentifier(byte[] subjectKeyIdentifier) + { + return new SignerIdentifier(new DerOctetString(subjectKeyIdentifier)); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSSignedGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSSignedGenerator.cs.meta new file mode 100644 index 0000000..4adb32a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSSignedGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 431fef26242142c4b88205bc3330e9b7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSSignedHelper.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSSignedHelper.cs new file mode 100644 index 0000000..6d17200 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSSignedHelper.cs @@ -0,0 +1,454 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Asn1.Eac; +using Org.BouncyCastle.Asn1.Iana; +using Org.BouncyCastle.Asn1.Misc; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Oiw; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.TeleTrust; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Security.Certificates; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.X509; +using Org.BouncyCastle.X509.Store; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities.Collections; +using Org.BouncyCastle.Crypto.Tls; + +namespace Org.BouncyCastle.Cms +{ + internal class CmsSignedHelper + { + internal static readonly CmsSignedHelper Instance = new CmsSignedHelper(); + + private static readonly string EncryptionECDsaWithSha1 = X9ObjectIdentifiers.ECDsaWithSha1.Id; + private static readonly string EncryptionECDsaWithSha224 = X9ObjectIdentifiers.ECDsaWithSha224.Id; + private static readonly string EncryptionECDsaWithSha256 = X9ObjectIdentifiers.ECDsaWithSha256.Id; + private static readonly string EncryptionECDsaWithSha384 = X9ObjectIdentifiers.ECDsaWithSha384.Id; + private static readonly string EncryptionECDsaWithSha512 = X9ObjectIdentifiers.ECDsaWithSha512.Id; + + private static readonly IDictionary encryptionAlgs = Platform.CreateHashtable(); + private static readonly IDictionary digestAlgs = Platform.CreateHashtable(); + private static readonly IDictionary digestAliases = Platform.CreateHashtable(); + + private static readonly ISet noParams = new HashSet(); + private static readonly IDictionary ecAlgorithms = Platform.CreateHashtable(); + + private static void AddEntries(DerObjectIdentifier oid, string digest, string encryption) + { + string alias = oid.Id; + digestAlgs.Add(alias, digest); + encryptionAlgs.Add(alias, encryption); + } + + static CmsSignedHelper() + { + AddEntries(NistObjectIdentifiers.DsaWithSha224, "SHA224", "DSA"); + AddEntries(NistObjectIdentifiers.DsaWithSha256, "SHA256", "DSA"); + AddEntries(NistObjectIdentifiers.DsaWithSha384, "SHA384", "DSA"); + AddEntries(NistObjectIdentifiers.DsaWithSha512, "SHA512", "DSA"); + AddEntries(OiwObjectIdentifiers.DsaWithSha1, "SHA1", "DSA"); + AddEntries(OiwObjectIdentifiers.MD4WithRsa, "MD4", "RSA"); + AddEntries(OiwObjectIdentifiers.MD4WithRsaEncryption, "MD4", "RSA"); + AddEntries(OiwObjectIdentifiers.MD5WithRsa, "MD5", "RSA"); + AddEntries(OiwObjectIdentifiers.Sha1WithRsa, "SHA1", "RSA"); + AddEntries(PkcsObjectIdentifiers.MD2WithRsaEncryption, "MD2", "RSA"); + AddEntries(PkcsObjectIdentifiers.MD4WithRsaEncryption, "MD4", "RSA"); + AddEntries(PkcsObjectIdentifiers.MD5WithRsaEncryption, "MD5", "RSA"); + AddEntries(PkcsObjectIdentifiers.Sha1WithRsaEncryption, "SHA1", "RSA"); + AddEntries(PkcsObjectIdentifiers.Sha224WithRsaEncryption, "SHA224", "RSA"); + AddEntries(PkcsObjectIdentifiers.Sha256WithRsaEncryption, "SHA256", "RSA"); + AddEntries(PkcsObjectIdentifiers.Sha384WithRsaEncryption, "SHA384", "RSA"); + AddEntries(PkcsObjectIdentifiers.Sha512WithRsaEncryption, "SHA512", "RSA"); + AddEntries(PkcsObjectIdentifiers.Sha512_224WithRSAEncryption, "SHA512(224)", "RSA"); + AddEntries(PkcsObjectIdentifiers.Sha512_256WithRSAEncryption, "SHA512(256)", "RSA"); + AddEntries(NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_224, "SHA3-224", "RSA"); + AddEntries(NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_256, "SHA3-256", "RSA"); + AddEntries(NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_384, "SHA3-384", "RSA"); + AddEntries(NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_512, "SHA3-512", "RSA"); + AddEntries(X9ObjectIdentifiers.ECDsaWithSha1, "SHA1", "ECDSA"); + AddEntries(X9ObjectIdentifiers.ECDsaWithSha224, "SHA224", "ECDSA"); + AddEntries(X9ObjectIdentifiers.ECDsaWithSha256, "SHA256", "ECDSA"); + AddEntries(X9ObjectIdentifiers.ECDsaWithSha384, "SHA384", "ECDSA"); + AddEntries(X9ObjectIdentifiers.ECDsaWithSha512, "SHA512", "ECDSA"); + AddEntries(X9ObjectIdentifiers.IdDsaWithSha1, "SHA1", "DSA"); + AddEntries(EacObjectIdentifiers.id_TA_ECDSA_SHA_1, "SHA1", "ECDSA"); + AddEntries(EacObjectIdentifiers.id_TA_ECDSA_SHA_224, "SHA224", "ECDSA"); + AddEntries(EacObjectIdentifiers.id_TA_ECDSA_SHA_256, "SHA256", "ECDSA"); + AddEntries(EacObjectIdentifiers.id_TA_ECDSA_SHA_384, "SHA384", "ECDSA"); + AddEntries(EacObjectIdentifiers.id_TA_ECDSA_SHA_512, "SHA512", "ECDSA"); + AddEntries(EacObjectIdentifiers.id_TA_RSA_v1_5_SHA_1, "SHA1", "RSA"); + AddEntries(EacObjectIdentifiers.id_TA_RSA_v1_5_SHA_256, "SHA256", "RSA"); + AddEntries(EacObjectIdentifiers.id_TA_RSA_PSS_SHA_1, "SHA1", "RSAandMGF1"); + AddEntries(EacObjectIdentifiers.id_TA_RSA_PSS_SHA_256, "SHA256", "RSAandMGF1"); + + encryptionAlgs.Add(X9ObjectIdentifiers.IdDsa.Id, "DSA"); + encryptionAlgs.Add(PkcsObjectIdentifiers.RsaEncryption.Id, "RSA"); + encryptionAlgs.Add(TeleTrusTObjectIdentifiers.TeleTrusTRsaSignatureAlgorithm.Id, "RSA"); + encryptionAlgs.Add(X509ObjectIdentifiers.IdEARsa.Id, "RSA"); + encryptionAlgs.Add(CmsSignedGenerator.EncryptionRsaPss, "RSAandMGF1"); + encryptionAlgs.Add(CryptoProObjectIdentifiers.GostR3410x94.Id, "GOST3410"); + encryptionAlgs.Add(CryptoProObjectIdentifiers.GostR3410x2001.Id, "ECGOST3410"); + encryptionAlgs.Add("1.3.6.1.4.1.5849.1.6.2", "ECGOST3410"); + encryptionAlgs.Add("1.3.6.1.4.1.5849.1.1.5", "GOST3410"); + + digestAlgs.Add(PkcsObjectIdentifiers.MD2.Id, "MD2"); + digestAlgs.Add(PkcsObjectIdentifiers.MD4.Id, "MD4"); + digestAlgs.Add(PkcsObjectIdentifiers.MD5.Id, "MD5"); + digestAlgs.Add(OiwObjectIdentifiers.IdSha1.Id, "SHA1"); + digestAlgs.Add(NistObjectIdentifiers.IdSha224.Id, "SHA224"); + digestAlgs.Add(NistObjectIdentifiers.IdSha256.Id, "SHA256"); + digestAlgs.Add(NistObjectIdentifiers.IdSha384.Id, "SHA384"); + digestAlgs.Add(NistObjectIdentifiers.IdSha512.Id, "SHA512"); + digestAlgs.Add(NistObjectIdentifiers.IdSha512_224.Id, "SHA512(224)"); + digestAlgs.Add(NistObjectIdentifiers.IdSha512_256.Id, "SHA512(256)"); + digestAlgs.Add(NistObjectIdentifiers.IdSha3_224.Id, "SHA3-224"); + digestAlgs.Add(NistObjectIdentifiers.IdSha3_256.Id, "SHA3-256"); + digestAlgs.Add(NistObjectIdentifiers.IdSha3_384.Id, "SHA3-384"); + digestAlgs.Add(NistObjectIdentifiers.IdSha3_512.Id, "SHA3-512"); + digestAlgs.Add(TeleTrusTObjectIdentifiers.RipeMD128.Id, "RIPEMD128"); + digestAlgs.Add(TeleTrusTObjectIdentifiers.RipeMD160.Id, "RIPEMD160"); + digestAlgs.Add(TeleTrusTObjectIdentifiers.RipeMD256.Id, "RIPEMD256"); + digestAlgs.Add(CryptoProObjectIdentifiers.GostR3411.Id, "GOST3411"); + digestAlgs.Add("1.3.6.1.4.1.5849.1.2.1", "GOST3411"); + + digestAliases.Add("SHA1", new string[] { "SHA-1" }); + digestAliases.Add("SHA224", new string[] { "SHA-224" }); + digestAliases.Add("SHA256", new string[] { "SHA-256" }); + digestAliases.Add("SHA384", new string[] { "SHA-384" }); + digestAliases.Add("SHA512", new string[] { "SHA-512" }); + + noParams.Add(CmsSignedGenerator.EncryptionDsa); + // noParams.Add(EncryptionECDsa); + noParams.Add(EncryptionECDsaWithSha1); + noParams.Add(EncryptionECDsaWithSha224); + noParams.Add(EncryptionECDsaWithSha256); + noParams.Add(EncryptionECDsaWithSha384); + noParams.Add(EncryptionECDsaWithSha512); + + ecAlgorithms.Add(CmsSignedGenerator.DigestSha1, EncryptionECDsaWithSha1); + ecAlgorithms.Add(CmsSignedGenerator.DigestSha224, EncryptionECDsaWithSha224); + ecAlgorithms.Add(CmsSignedGenerator.DigestSha256, EncryptionECDsaWithSha256); + ecAlgorithms.Add(CmsSignedGenerator.DigestSha384, EncryptionECDsaWithSha384); + ecAlgorithms.Add(CmsSignedGenerator.DigestSha512, EncryptionECDsaWithSha512); + } + + + + /** + * Return the digest algorithm using one of the standard JCA string + * representations rather than the algorithm identifier (if possible). + */ + internal string GetDigestAlgName( + string digestAlgOid) + { + string algName = (string)digestAlgs[digestAlgOid]; + + if (algName != null) + { + return algName; + } + + return digestAlgOid; + } + + internal AlgorithmIdentifier GetEncAlgorithmIdentifier( + DerObjectIdentifier encOid, + Asn1Encodable sigX509Parameters) + { + if (noParams.Contains(encOid.Id)) + { + return new AlgorithmIdentifier(encOid); + } + + return new AlgorithmIdentifier(encOid, sigX509Parameters); + } + + internal string[] GetDigestAliases( + string algName) + { + string[] aliases = (string[]) digestAliases[algName]; + + return aliases == null ? new string[0] : (string[]) aliases.Clone(); + } + + /** + * Return the digest encryption algorithm using one of the standard + * JCA string representations rather than the algorithm identifier (if + * possible). + */ + internal string GetEncryptionAlgName( + string encryptionAlgOid) + { + string algName = (string) encryptionAlgs[encryptionAlgOid]; + + if (algName != null) + { + return algName; + } + + return encryptionAlgOid; + } + + internal IDigest GetDigestInstance( + string algorithm) + { + try + { + return DigestUtilities.GetDigest(algorithm); + } + catch (SecurityUtilityException e) + { + // This is probably superfluous on C#, since no provider infrastructure, + // assuming DigestUtilities already knows all the aliases + foreach (string alias in GetDigestAliases(algorithm)) + { + try { return DigestUtilities.GetDigest(alias); } + catch (SecurityUtilityException) {} + } + throw e; + } + } + + internal ISigner GetSignatureInstance( + string algorithm) + { + return SignerUtilities.GetSigner(algorithm); + } + + internal IX509Store CreateAttributeStore( + string type, + Asn1Set certSet) + { + IList certs = Platform.CreateArrayList(); + + if (certSet != null) + { + foreach (Asn1Encodable ae in certSet) + { + try + { + Asn1Object obj = ae.ToAsn1Object(); + + if (obj is Asn1TaggedObject) + { + Asn1TaggedObject tagged = (Asn1TaggedObject)obj; + + if (tagged.TagNo == 2) + { + certs.Add( + new X509V2AttributeCertificate( + Asn1Sequence.GetInstance(tagged, false).GetEncoded())); + } + } + } + catch (Exception ex) + { + throw new CmsException("can't re-encode attribute certificate!", ex); + } + } + } + + try + { + return X509StoreFactory.Create( + "AttributeCertificate/" + type, + new X509CollectionStoreParameters(certs)); + } + catch (ArgumentException e) + { + throw new CmsException("can't setup the X509Store", e); + } + } + + internal IX509Store CreateCertificateStore( + string type, + Asn1Set certSet) + { + IList certs = Platform.CreateArrayList(); + + if (certSet != null) + { + AddCertsFromSet(certs, certSet); + } + + try + { + return X509StoreFactory.Create( + "Certificate/" + type, + new X509CollectionStoreParameters(certs)); + } + catch (ArgumentException e) + { + throw new CmsException("can't setup the X509Store", e); + } + } + + internal IX509Store CreateCrlStore( + string type, + Asn1Set crlSet) + { + IList crls = Platform.CreateArrayList(); + + if (crlSet != null) + { + AddCrlsFromSet(crls, crlSet); + } + + try + { + return X509StoreFactory.Create( + "CRL/" + type, + new X509CollectionStoreParameters(crls)); + } + catch (ArgumentException e) + { + throw new CmsException("can't setup the X509Store", e); + } + } + + private void AddCertsFromSet( + IList certs, + Asn1Set certSet) + { + X509CertificateParser cf = new X509CertificateParser(); + + foreach (Asn1Encodable ae in certSet) + { + try + { + Asn1Object obj = ae.ToAsn1Object(); + + if (obj is Asn1Sequence) + { + // TODO Build certificate directly from sequence? + certs.Add(cf.ReadCertificate(obj.GetEncoded())); + } + } + catch (Exception ex) + { + throw new CmsException("can't re-encode certificate!", ex); + } + } + } + + private void AddCrlsFromSet( + IList crls, + Asn1Set crlSet) + { + X509CrlParser cf = new X509CrlParser(); + + foreach (Asn1Encodable ae in crlSet) + { + try + { + // TODO Build CRL directly from ae.ToAsn1Object()? + crls.Add(cf.ReadCrl(ae.GetEncoded())); + } + catch (Exception ex) + { + throw new CmsException("can't re-encode CRL!", ex); + } + } + } + + internal AlgorithmIdentifier FixAlgID( + AlgorithmIdentifier algId) + { + if (algId.Parameters == null) + return new AlgorithmIdentifier(algId.Algorithm, DerNull.Instance); + + return algId; + } + + internal string GetEncOid( + AsymmetricKeyParameter key, + string digestOID) + { + string encOID = null; + + if (key is RsaKeyParameters) + { + if (!((RsaKeyParameters)key).IsPrivate) + throw new ArgumentException("Expected RSA private key"); + + encOID = CmsSignedGenerator.EncryptionRsa; + } + else if (key is DsaPrivateKeyParameters) + { + if (digestOID.Equals(CmsSignedGenerator.DigestSha1)) + { + encOID = CmsSignedGenerator.EncryptionDsa; + } + else if (digestOID.Equals(CmsSignedGenerator.DigestSha224)) + { + encOID = NistObjectIdentifiers.DsaWithSha224.Id; + } + else if (digestOID.Equals(CmsSignedGenerator.DigestSha256)) + { + encOID = NistObjectIdentifiers.DsaWithSha256.Id; + } + else if (digestOID.Equals(CmsSignedGenerator.DigestSha384)) + { + encOID = NistObjectIdentifiers.DsaWithSha384.Id; + } + else if (digestOID.Equals(CmsSignedGenerator.DigestSha512)) + { + encOID = NistObjectIdentifiers.DsaWithSha512.Id; + } + else + { + throw new ArgumentException("can't mix DSA with anything but SHA1/SHA2"); + } + } + else if (key is ECPrivateKeyParameters) + { + ECPrivateKeyParameters ecPrivKey = (ECPrivateKeyParameters)key; + string algName = ecPrivKey.AlgorithmName; + + if (algName == "ECGOST3410") + { + encOID = CmsSignedGenerator.EncryptionECGost3410; + } + else + { + // TODO Should we insist on algName being one of "EC" or "ECDSA", as Java does? + encOID = (string)ecAlgorithms[digestOID]; + + if (encOID == null) + throw new ArgumentException("can't mix ECDSA with anything but SHA family digests"); + } + } + else if (key is Gost3410PrivateKeyParameters) + { + encOID = CmsSignedGenerator.EncryptionGost3410; + } + else + { + throw new ArgumentException("Unknown algorithm in CmsSignedGenerator.GetEncOid"); + } + + return encOID; + } + + public IX509Store GetCertificates(Asn1Set certificates) + { + IList certList = Platform.CreateArrayList(); + if (certificates != null) + { + foreach (Asn1Encodable enc in certificates) + { + certList.Add(X509CertificateStructure.GetInstance(enc)); + } + } + return new X509CollectionStore(certList); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSSignedHelper.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSSignedHelper.cs.meta new file mode 100644 index 0000000..2702268 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSSignedHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8eb98d8892301974d8a6cf3ed377cd92 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSStreamException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSStreamException.cs new file mode 100644 index 0000000..68a8be0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSStreamException.cs @@ -0,0 +1,29 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Cms +{ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE) + [Serializable] +#endif + public class CmsStreamException + : IOException + { + public CmsStreamException() + { + } + + public CmsStreamException( + string name) + : base(name) + { + } + + public CmsStreamException( + string name, + Exception e) + : base(name, e) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSStreamException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSStreamException.cs.meta new file mode 100644 index 0000000..0a3c9db --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSStreamException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 959da05a999c2124798745a5729a4dcf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSTypedStream.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSTypedStream.cs new file mode 100644 index 0000000..6815837 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSTypedStream.cs @@ -0,0 +1,72 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Cms +{ + public class CmsTypedStream + { + private const int BufferSize = 32 * 1024; + + private readonly string _oid; + private readonly Stream _in; + + public CmsTypedStream( + Stream inStream) + : this(PkcsObjectIdentifiers.Data.Id, inStream, BufferSize) + { + } + + public CmsTypedStream( + string oid, + Stream inStream) + : this(oid, inStream, BufferSize) + { + } + + public CmsTypedStream( + string oid, + Stream inStream, + int bufSize) + { + _oid = oid; +#if NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE + _in = new FullReaderStream(inStream); +#else + _in = new FullReaderStream(new BufferedStream(inStream, bufSize)); +#endif + } + + public string ContentType + { + get { return _oid; } + } + + public Stream ContentStream + { + get { return _in; } + } + + public void Drain() + { + Streams.Drain(_in); + Platform.Dispose(_in); + } + + private class FullReaderStream : FilterStream + { + internal FullReaderStream(Stream input) + : base(input) + { + } + + public override int Read(byte[] buf, int off, int len) + { + return Streams.ReadFully(base.s, buf, off, len); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSTypedStream.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSTypedStream.cs.meta new file mode 100644 index 0000000..bfab263 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSTypedStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b72aa2fa386be034e922c7effa0383e1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSUtils.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSUtils.cs new file mode 100644 index 0000000..95d7106 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSUtils.cs @@ -0,0 +1,186 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Security.Certificates; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; +using Org.BouncyCastle.X509; +using Org.BouncyCastle.X509.Store; + +namespace Org.BouncyCastle.Cms +{ + internal class CmsUtilities + { + // TODO Is there a .NET equivalent to this? +// private static readonly Runtime RUNTIME = Runtime.getRuntime(); + + internal static int MaximumMemory + { + get + { + // TODO Is there a .NET equivalent to this? + long maxMem = int.MaxValue;//RUNTIME.maxMemory(); + + if (maxMem > int.MaxValue) + { + return int.MaxValue; + } + + return (int)maxMem; + } + } + + internal static ContentInfo ReadContentInfo( + byte[] input) + { + // enforce limit checking as from a byte array + return ReadContentInfo(new Asn1InputStream(input)); + } + + internal static ContentInfo ReadContentInfo( + Stream input) + { + // enforce some limit checking + return ReadContentInfo(new Asn1InputStream(input, MaximumMemory)); + } + + private static ContentInfo ReadContentInfo( + Asn1InputStream aIn) + { + try + { + return ContentInfo.GetInstance(aIn.ReadObject()); + } + catch (IOException e) + { + throw new CmsException("IOException reading content.", e); + } + catch (InvalidCastException e) + { + throw new CmsException("Malformed content.", e); + } + catch (ArgumentException e) + { + throw new CmsException("Malformed content.", e); + } + } + + public static byte[] StreamToByteArray( + Stream inStream) + { + return Streams.ReadAll(inStream); + } + + public static byte[] StreamToByteArray( + Stream inStream, + int limit) + { + return Streams.ReadAllLimited(inStream, limit); + } + + public static IList GetCertificatesFromStore( + IX509Store certStore) + { + try + { + IList certs = Platform.CreateArrayList(); + + if (certStore != null) + { + foreach (X509Certificate c in certStore.GetMatches(null)) + { + certs.Add( + X509CertificateStructure.GetInstance( + Asn1Object.FromByteArray(c.GetEncoded()))); + } + } + + return certs; + } + catch (CertificateEncodingException e) + { + throw new CmsException("error encoding certs", e); + } + catch (Exception e) + { + throw new CmsException("error processing certs", e); + } + } + + public static IList GetCrlsFromStore( + IX509Store crlStore) + { + try + { + IList crls = Platform.CreateArrayList(); + + if (crlStore != null) + { + foreach (X509Crl c in crlStore.GetMatches(null)) + { + crls.Add( + CertificateList.GetInstance( + Asn1Object.FromByteArray(c.GetEncoded()))); + } + } + + return crls; + } + catch (CrlException e) + { + throw new CmsException("error encoding crls", e); + } + catch (Exception e) + { + throw new CmsException("error processing crls", e); + } + } + + public static Asn1Set CreateBerSetFromList( + IList berObjects) + { + Asn1EncodableVector v = new Asn1EncodableVector(); + + foreach (Asn1Encodable ae in berObjects) + { + v.Add(ae); + } + + return new BerSet(v); + } + + public static Asn1Set CreateDerSetFromList( + IList derObjects) + { + Asn1EncodableVector v = new Asn1EncodableVector(); + + foreach (Asn1Encodable ae in derObjects) + { + v.Add(ae); + } + + return new DerSet(v); + } + + internal static Stream CreateBerOctetOutputStream(Stream s, int tagNo, bool isExplicit, int bufferSize) + { + BerOctetStringGenerator octGen = new BerOctetStringGenerator(s, tagNo, isExplicit); + return octGen.GetOctetOutputStream(bufferSize); + } + + internal static TbsCertificateStructure GetTbsCertificateStructure(X509Certificate cert) + { + return TbsCertificateStructure.GetInstance(Asn1Object.FromByteArray(cert.GetTbsCertificate())); + } + + internal static IssuerAndSerialNumber GetIssuerAndSerialNumber(X509Certificate cert) + { + TbsCertificateStructure tbsCert = GetTbsCertificateStructure(cert); + return new IssuerAndSerialNumber(tbsCert.Issuer, tbsCert.SerialNumber.Value); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSUtils.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSUtils.cs.meta new file mode 100644 index 0000000..4231519 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CMSUtils.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 38a21ef4135d60f488b575d98fb0536c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CounterSignatureDigestCalculator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CounterSignatureDigestCalculator.cs new file mode 100644 index 0000000..6f8bf65 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CounterSignatureDigestCalculator.cs @@ -0,0 +1,28 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Cms +{ + internal class CounterSignatureDigestCalculator + : IDigestCalculator + { + private readonly string alg; + private readonly byte[] data; + + internal CounterSignatureDigestCalculator( + string alg, + byte[] data) + { + this.alg = alg; + this.data = data; + } + + public byte[] GetDigest() + { + IDigest digest = CmsSignedHelper.Instance.GetDigestInstance(alg); + return DigestUtilities.DoFinal(digest, data); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CounterSignatureDigestCalculator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CounterSignatureDigestCalculator.cs.meta new file mode 100644 index 0000000..704829b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/CounterSignatureDigestCalculator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8f32bf0f5b420a74db69e43864c5d71d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/DefaultAuthenticatedAttributeTableGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/DefaultAuthenticatedAttributeTableGenerator.cs new file mode 100644 index 0000000..d49b1d9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/DefaultAuthenticatedAttributeTableGenerator.cs @@ -0,0 +1,90 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Cms +{ + /** + * Default authenticated attributes generator. + */ + public class DefaultAuthenticatedAttributeTableGenerator + : CmsAttributeTableGenerator + { + private readonly IDictionary table; + + /** + * Initialise to use all defaults + */ + public DefaultAuthenticatedAttributeTableGenerator() + { + table = Platform.CreateHashtable(); + } + + /** + * Initialise with some extra attributes or overrides. + * + * @param attributeTable initial attribute table to use. + */ + public DefaultAuthenticatedAttributeTableGenerator( + AttributeTable attributeTable) + { + if (attributeTable != null) + { + table = attributeTable.ToDictionary(); + } + else + { + table = Platform.CreateHashtable(); + } + } + + /** + * Create a standard attribute table from the passed in parameters - this will + * normally include contentType and messageDigest. If the constructor + * using an AttributeTable was used, entries in it for contentType and + * messageDigest will override the generated ones. + * + * @param parameters source parameters for table generation. + * + * @return a filled in IDictionary of attributes. + */ + protected virtual IDictionary CreateStandardAttributeTable( + IDictionary parameters) + { + IDictionary std = Platform.CreateHashtable(table); + + if (!std.Contains(CmsAttributes.ContentType)) + { + DerObjectIdentifier contentType = (DerObjectIdentifier) + parameters[CmsAttributeTableParameter.ContentType]; + Asn1.Cms.Attribute attr = new Asn1.Cms.Attribute(CmsAttributes.ContentType, + new DerSet(contentType)); + std[attr.AttrType] = attr; + } + + if (!std.Contains(CmsAttributes.MessageDigest)) + { + byte[] messageDigest = (byte[])parameters[CmsAttributeTableParameter.Digest]; + Asn1.Cms.Attribute attr = new Asn1.Cms.Attribute(CmsAttributes.MessageDigest, + new DerSet(new DerOctetString(messageDigest))); + std[attr.AttrType] = attr; + } + + return std; + } + + /** + * @param parameters source parameters + * @return the populated attribute table + */ + public virtual AttributeTable GetAttributes( + IDictionary parameters) + { + IDictionary table = CreateStandardAttributeTable(parameters); + return new AttributeTable(table); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/DefaultAuthenticatedAttributeTableGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/DefaultAuthenticatedAttributeTableGenerator.cs.meta new file mode 100644 index 0000000..0609e68 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/DefaultAuthenticatedAttributeTableGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c2b09fb0ceb36d942bd341e664a3378d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/DefaultSignedAttributeTableGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/DefaultSignedAttributeTableGenerator.cs new file mode 100644 index 0000000..925a98a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/DefaultSignedAttributeTableGenerator.cs @@ -0,0 +1,124 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Cms +{ + /** + * Default signed attributes generator. + */ + public class DefaultSignedAttributeTableGenerator + : CmsAttributeTableGenerator + { + private readonly IDictionary table; + + /** + * Initialise to use all defaults + */ + public DefaultSignedAttributeTableGenerator() + { + table = Platform.CreateHashtable(); + } + + /** + * Initialise with some extra attributes or overrides. + * + * @param attributeTable initial attribute table to use. + */ + public DefaultSignedAttributeTableGenerator( + AttributeTable attributeTable) + { + if (attributeTable != null) + { + table = attributeTable.ToDictionary(); + } + else + { + table = Platform.CreateHashtable(); + } + } + +#if SILVERLIGHT || PORTABLE + /** + * Create a standard attribute table from the passed in parameters - this will + * normally include contentType, signingTime, and messageDigest. If the constructor + * using an AttributeTable was used, entries in it for contentType, signingTime, and + * messageDigest will override the generated ones. + * + * @param parameters source parameters for table generation. + * + * @return a filled in Hashtable of attributes. + */ + protected virtual IDictionary createStandardAttributeTable( + IDictionary parameters) + { + IDictionary std = Platform.CreateHashtable(table); + DoCreateStandardAttributeTable(parameters, std); + return std; + } +#else + /** + * Create a standard attribute table from the passed in parameters - this will + * normally include contentType, signingTime, and messageDigest. If the constructor + * using an AttributeTable was used, entries in it for contentType, signingTime, and + * messageDigest will override the generated ones. + * + * @param parameters source parameters for table generation. + * + * @return a filled in Hashtable of attributes. + */ + protected virtual Hashtable createStandardAttributeTable( + IDictionary parameters) + { + Hashtable std = new Hashtable(table); + DoCreateStandardAttributeTable(parameters, std); + return std; + } +#endif + + private void DoCreateStandardAttributeTable(IDictionary parameters, IDictionary std) + { + // contentType will be absent if we're trying to generate a counter signature. + if (parameters.Contains(CmsAttributeTableParameter.ContentType)) + { + if (!std.Contains(CmsAttributes.ContentType)) + { + DerObjectIdentifier contentType = (DerObjectIdentifier) + parameters[CmsAttributeTableParameter.ContentType]; + Asn1.Cms.Attribute attr = new Asn1.Cms.Attribute(CmsAttributes.ContentType, + new DerSet(contentType)); + std[attr.AttrType] = attr; + } + } + + if (!std.Contains(CmsAttributes.SigningTime)) + { + Asn1.Cms.Attribute attr = new Asn1.Cms.Attribute(CmsAttributes.SigningTime, + new DerSet(new Time(DateTime.UtcNow))); + std[attr.AttrType] = attr; + } + + if (!std.Contains(CmsAttributes.MessageDigest)) + { + byte[] messageDigest = (byte[])parameters[CmsAttributeTableParameter.Digest]; + Asn1.Cms.Attribute attr = new Asn1.Cms.Attribute(CmsAttributes.MessageDigest, + new DerSet(new DerOctetString(messageDigest))); + std[attr.AttrType] = attr; + } + } + + /** + * @param parameters source parameters + * @return the populated attribute table + */ + public virtual AttributeTable GetAttributes( + IDictionary parameters) + { + IDictionary table = createStandardAttributeTable(parameters); + return new AttributeTable(table); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/DefaultSignedAttributeTableGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/DefaultSignedAttributeTableGenerator.cs.meta new file mode 100644 index 0000000..33d010e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/DefaultSignedAttributeTableGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8a62b82be5aef36429639127c02e85b7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/EnvelopedDataHelper.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/EnvelopedDataHelper.cs new file mode 100644 index 0000000..6d1c7bb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/EnvelopedDataHelper.cs @@ -0,0 +1,95 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Oiw; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Operators; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Cms +{ + internal class EnvelopedDataHelper + { + private static readonly IDictionary BaseCipherNames = Platform.CreateHashtable(); + private static readonly IDictionary MacAlgNames = Platform.CreateHashtable(); + //private static readonly IDictionary PrfDigests = Platform.CreateHashtable(); + + static EnvelopedDataHelper() + { + //PrfDigests.Add(PkcsObjectIdentifiers.IdHmacWithSha1, "SHA-1"); + //PrfDigests.Add(PkcsObjectIdentifiers.IdHmacWithSha224, "SHA-224"); + //PrfDigests.Add(PkcsObjectIdentifiers.IdHmacWithSha256, "SHA-256"); + //PrfDigests.Add(PkcsObjectIdentifiers.IdHmacWithSha384, "SHA-384"); + //PrfDigests.Add(PkcsObjectIdentifiers.IdHmacWithSha512, "SHA-512"); + + BaseCipherNames.Add(PkcsObjectIdentifiers.DesEde3Cbc, "DESEDE"); + BaseCipherNames.Add(NistObjectIdentifiers.IdAes128Cbc, "AES"); + BaseCipherNames.Add(NistObjectIdentifiers.IdAes192Cbc, "AES"); + BaseCipherNames.Add(NistObjectIdentifiers.IdAes256Cbc, "AES"); + + MacAlgNames.Add(PkcsObjectIdentifiers.DesEde3Cbc, "DESEDEMac"); + MacAlgNames.Add(NistObjectIdentifiers.IdAes128Cbc, "AESMac"); + MacAlgNames.Add(NistObjectIdentifiers.IdAes192Cbc, "AESMac"); + MacAlgNames.Add(NistObjectIdentifiers.IdAes256Cbc, "AESMac"); + MacAlgNames.Add(PkcsObjectIdentifiers.RC2Cbc, "RC2Mac"); + } + + //internal static IDigest GetPrf(AlgorithmIdentifier algID) + //{ + // string digestName = (string)PrfDigests[algID]; + + // return DigestUtilities.GetDigest(digestName); + //} + + //internal static IWrapper CreateRfc3211Wrapper(DerObjectIdentifier algorithm) + //{ + // if (NistObjectIdentifiers.IdAes128Cbc.Equals(algorithm) + // || NistObjectIdentifiers.IdAes192Cbc.Equals(algorithm) + // || NistObjectIdentifiers.IdAes256Cbc.Equals(algorithm)) + // { + // return new Rfc3211WrapEngine(new AesEngine()); + // } + // else if (PkcsObjectIdentifiers.DesEde3Cbc.Equals(algorithm)) + // { + // return new Rfc3211WrapEngine(new DesEdeEngine()); + // } + // else if (OiwObjectIdentifiers.DesCbc.Equals(algorithm)) + // { + // return new Rfc3211WrapEngine(new DesEngine()); + // } + // else if (PkcsObjectIdentifiers.RC2Cbc.Equals(algorithm)) + // { + // return new Rfc3211WrapEngine(new RC2Engine()); + // } + // else + // { + // throw new CmsException("cannot recognise wrapper: " + algorithm); + // } + //} + + public static object CreateContentCipher(bool forEncryption, ICipherParameters encKey, + AlgorithmIdentifier encryptionAlgID) + { + return CipherFactory.CreateContentCipher(forEncryption, encKey, encryptionAlgID); + } + + public AlgorithmIdentifier GenerateEncryptionAlgID(DerObjectIdentifier encryptionOID, KeyParameter encKey, SecureRandom random) + { + return AlgorithmIdentifierFactory.GenerateEncryptionAlgID(encryptionOID, encKey.GetKey().Length * 8, random); + } + + public CipherKeyGenerator CreateKeyGenerator(DerObjectIdentifier algorithm, SecureRandom random) + { + return CipherKeyGeneratorFactory.CreateKeyGenerator(algorithm, random); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/EnvelopedDataHelper.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/EnvelopedDataHelper.cs.meta new file mode 100644 index 0000000..7e60db7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/EnvelopedDataHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6c6a112214057a84682c2e2e395eb7b1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/IDigestCalculator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/IDigestCalculator.cs new file mode 100644 index 0000000..3661e40 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/IDigestCalculator.cs @@ -0,0 +1,9 @@ +using System; + +namespace Org.BouncyCastle.Cms +{ + internal interface IDigestCalculator + { + byte[] GetDigest(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/IDigestCalculator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/IDigestCalculator.cs.meta new file mode 100644 index 0000000..a979fd8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/IDigestCalculator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d0e008a34d233c74a8093c8951f2315b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/KEKRecipientInfoGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/KEKRecipientInfoGenerator.cs new file mode 100644 index 0000000..6f34fec --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/KEKRecipientInfoGenerator.cs @@ -0,0 +1,138 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Asn1.Kisa; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Ntt; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Cms +{ + internal class KekRecipientInfoGenerator : RecipientInfoGenerator + { + private static readonly CmsEnvelopedHelper Helper = CmsEnvelopedHelper.Instance; + + private KeyParameter keyEncryptionKey; + // TODO Can get this from keyEncryptionKey? + private string keyEncryptionKeyOID; + private KekIdentifier kekIdentifier; + + // Derived + private AlgorithmIdentifier keyEncryptionAlgorithm; + + internal KekRecipientInfoGenerator() + { + } + + internal KekIdentifier KekIdentifier + { + set { this.kekIdentifier = value; } + } + + internal KeyParameter KeyEncryptionKey + { + set + { + this.keyEncryptionKey = value; + this.keyEncryptionAlgorithm = DetermineKeyEncAlg(keyEncryptionKeyOID, keyEncryptionKey); + } + } + + internal string KeyEncryptionKeyOID + { + set { this.keyEncryptionKeyOID = value; } + } + + public RecipientInfo Generate(KeyParameter contentEncryptionKey, SecureRandom random) + { + byte[] keyBytes = contentEncryptionKey.GetKey(); + + IWrapper keyWrapper = Helper.CreateWrapper(keyEncryptionAlgorithm.Algorithm.Id); + keyWrapper.Init(true, new ParametersWithRandom(keyEncryptionKey, random)); + Asn1OctetString encryptedKey = new DerOctetString( + keyWrapper.Wrap(keyBytes, 0, keyBytes.Length)); + + return new RecipientInfo(new KekRecipientInfo(kekIdentifier, keyEncryptionAlgorithm, encryptedKey)); + } + + private static AlgorithmIdentifier DetermineKeyEncAlg( + string algorithm, KeyParameter key) + { + if (Platform.StartsWith(algorithm, "DES")) + { + return new AlgorithmIdentifier( + PkcsObjectIdentifiers.IdAlgCms3DesWrap, + DerNull.Instance); + } + else if (Platform.StartsWith(algorithm, "RC2")) + { + return new AlgorithmIdentifier( + PkcsObjectIdentifiers.IdAlgCmsRC2Wrap, + new DerInteger(58)); + } + else if (Platform.StartsWith(algorithm, "AES")) + { + int length = key.GetKey().Length * 8; + DerObjectIdentifier wrapOid; + + if (length == 128) + { + wrapOid = NistObjectIdentifiers.IdAes128Wrap; + } + else if (length == 192) + { + wrapOid = NistObjectIdentifiers.IdAes192Wrap; + } + else if (length == 256) + { + wrapOid = NistObjectIdentifiers.IdAes256Wrap; + } + else + { + throw new ArgumentException("illegal keysize in AES"); + } + + return new AlgorithmIdentifier(wrapOid); // parameters absent + } + else if (Platform.StartsWith(algorithm, "SEED")) + { + // parameters absent + return new AlgorithmIdentifier(KisaObjectIdentifiers.IdNpkiAppCmsSeedWrap); + } + else if (Platform.StartsWith(algorithm, "CAMELLIA")) + { + int length = key.GetKey().Length * 8; + DerObjectIdentifier wrapOid; + + if (length == 128) + { + wrapOid = NttObjectIdentifiers.IdCamellia128Wrap; + } + else if (length == 192) + { + wrapOid = NttObjectIdentifiers.IdCamellia192Wrap; + } + else if (length == 256) + { + wrapOid = NttObjectIdentifiers.IdCamellia256Wrap; + } + else + { + throw new ArgumentException("illegal keysize in Camellia"); + } + + return new AlgorithmIdentifier(wrapOid); // parameters must be absent + } + else + { + throw new ArgumentException("unknown algorithm"); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/KEKRecipientInfoGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/KEKRecipientInfoGenerator.cs.meta new file mode 100644 index 0000000..4dfedd9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/KEKRecipientInfoGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e69fad2908d9398419a5fa4c07f73fcc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/KEKRecipientInformation.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/KEKRecipientInformation.cs new file mode 100644 index 0000000..871dc76 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/KEKRecipientInformation.cs @@ -0,0 +1,62 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Cms +{ + /** + * the RecipientInfo class for a recipient who has been sent a message + * encrypted using a secret key known to the other side. + */ + public class KekRecipientInformation + : RecipientInformation + { + private KekRecipientInfo info; + + internal KekRecipientInformation( + KekRecipientInfo info, + CmsSecureReadable secureReadable) + : base(info.KeyEncryptionAlgorithm, secureReadable) + { + this.info = info; + this.rid = new RecipientID(); + + KekIdentifier kekId = info.KekID; + + rid.KeyIdentifier = kekId.KeyIdentifier.GetOctets(); + } + + /** + * decrypt the content and return an input stream. + */ + public override CmsTypedStream GetContentStream( + ICipherParameters key) + { + try + { + byte[] encryptedKey = info.EncryptedKey.GetOctets(); + IWrapper keyWrapper = WrapperUtilities.GetWrapper(keyEncAlg.Algorithm.Id); + + keyWrapper.Init(false, key); + + KeyParameter sKey = ParameterUtilities.CreateKeyParameter( + GetContentAlgorithmName(), keyWrapper.Unwrap(encryptedKey, 0, encryptedKey.Length)); + + return GetContentFromSessionKey(sKey); + } + catch (SecurityUtilityException e) + { + throw new CmsException("couldn't create cipher.", e); + } + catch (InvalidKeyException e) + { + throw new CmsException("key invalid in message.", e); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/KEKRecipientInformation.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/KEKRecipientInformation.cs.meta new file mode 100644 index 0000000..ff69dba --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/KEKRecipientInformation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b8efef6a1701c14438d1522b33370202 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/KeyAgreeRecipientInfoGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/KeyAgreeRecipientInfoGenerator.cs new file mode 100644 index 0000000..6bd2cea --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/KeyAgreeRecipientInfoGenerator.cs @@ -0,0 +1,171 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Asn1.Cms.Ecc; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.Cms +{ + internal class KeyAgreeRecipientInfoGenerator : RecipientInfoGenerator + { + private static readonly CmsEnvelopedHelper Helper = CmsEnvelopedHelper.Instance; + + private DerObjectIdentifier keyAgreementOID; + private DerObjectIdentifier keyEncryptionOID; + private IList recipientCerts; + private AsymmetricCipherKeyPair senderKeyPair; + + internal KeyAgreeRecipientInfoGenerator() + { + } + + internal DerObjectIdentifier KeyAgreementOID + { + set { this.keyAgreementOID = value; } + } + + internal DerObjectIdentifier KeyEncryptionOID + { + set { this.keyEncryptionOID = value; } + } + + internal ICollection RecipientCerts + { + set { this.recipientCerts = Platform.CreateArrayList(value); } + } + + internal AsymmetricCipherKeyPair SenderKeyPair + { + set { this.senderKeyPair = value; } + } + + public RecipientInfo Generate(KeyParameter contentEncryptionKey, SecureRandom random) + { + byte[] keyBytes = contentEncryptionKey.GetKey(); + + AsymmetricKeyParameter senderPublicKey = senderKeyPair.Public; + ICipherParameters senderPrivateParams = senderKeyPair.Private; + + + OriginatorIdentifierOrKey originator; + try + { + originator = new OriginatorIdentifierOrKey( + CreateOriginatorPublicKey(senderPublicKey)); + } + catch (IOException e) + { + throw new InvalidKeyException("cannot extract originator public key: " + e); + } + + + Asn1OctetString ukm = null; + if (keyAgreementOID.Id.Equals(CmsEnvelopedGenerator.ECMqvSha1Kdf)) + { + try + { + IAsymmetricCipherKeyPairGenerator ephemKPG = + GeneratorUtilities.GetKeyPairGenerator(keyAgreementOID); + ephemKPG.Init( + ((ECPublicKeyParameters)senderPublicKey).CreateKeyGenerationParameters(random)); + + AsymmetricCipherKeyPair ephemKP = ephemKPG.GenerateKeyPair(); + + ukm = new DerOctetString( + new MQVuserKeyingMaterial( + CreateOriginatorPublicKey(ephemKP.Public), null)); + + senderPrivateParams = new MqvPrivateParameters( + (ECPrivateKeyParameters)senderPrivateParams, + (ECPrivateKeyParameters)ephemKP.Private, + (ECPublicKeyParameters)ephemKP.Public); + } + catch (IOException e) + { + throw new InvalidKeyException("cannot extract MQV ephemeral public key: " + e); + } + catch (SecurityUtilityException e) + { + throw new InvalidKeyException("cannot determine MQV ephemeral key pair parameters from public key: " + e); + } + } + + + DerSequence paramSeq = new DerSequence( + keyEncryptionOID, + DerNull.Instance); + AlgorithmIdentifier keyEncAlg = new AlgorithmIdentifier(keyAgreementOID, paramSeq); + + + Asn1EncodableVector recipientEncryptedKeys = new Asn1EncodableVector(); + foreach (X509Certificate recipientCert in recipientCerts) + { + TbsCertificateStructure tbsCert; + try + { + tbsCert = TbsCertificateStructure.GetInstance( + Asn1Object.FromByteArray(recipientCert.GetTbsCertificate())); + } + catch (Exception) + { + throw new ArgumentException("can't extract TBS structure from certificate"); + } + + // TODO Should there be a SubjectKeyIdentifier-based alternative? + IssuerAndSerialNumber issuerSerial = new IssuerAndSerialNumber( + tbsCert.Issuer, tbsCert.SerialNumber.Value); + KeyAgreeRecipientIdentifier karid = new KeyAgreeRecipientIdentifier(issuerSerial); + + ICipherParameters recipientPublicParams = recipientCert.GetPublicKey(); + if (keyAgreementOID.Id.Equals(CmsEnvelopedGenerator.ECMqvSha1Kdf)) + { + recipientPublicParams = new MqvPublicParameters( + (ECPublicKeyParameters)recipientPublicParams, + (ECPublicKeyParameters)recipientPublicParams); + } + + // Use key agreement to choose a wrap key for this recipient + IBasicAgreement keyAgreement = AgreementUtilities.GetBasicAgreementWithKdf( + keyAgreementOID, keyEncryptionOID.Id); + keyAgreement.Init(new ParametersWithRandom(senderPrivateParams, random)); + BigInteger agreedValue = keyAgreement.CalculateAgreement(recipientPublicParams); + + int keyEncryptionKeySize = GeneratorUtilities.GetDefaultKeySize(keyEncryptionOID) / 8; + byte[] keyEncryptionKeyBytes = X9IntegerConverter.IntegerToBytes(agreedValue, keyEncryptionKeySize); + KeyParameter keyEncryptionKey = ParameterUtilities.CreateKeyParameter( + keyEncryptionOID, keyEncryptionKeyBytes); + + // Wrap the content encryption key with the agreement key + IWrapper keyWrapper = Helper.CreateWrapper(keyEncryptionOID.Id); + keyWrapper.Init(true, new ParametersWithRandom(keyEncryptionKey, random)); + byte[] encryptedKeyBytes = keyWrapper.Wrap(keyBytes, 0, keyBytes.Length); + + Asn1OctetString encryptedKey = new DerOctetString(encryptedKeyBytes); + + recipientEncryptedKeys.Add(new RecipientEncryptedKey(karid, encryptedKey)); + } + + return new RecipientInfo(new KeyAgreeRecipientInfo(originator, ukm, keyEncAlg, + new DerSequence(recipientEncryptedKeys))); + } + + private static OriginatorPublicKey CreateOriginatorPublicKey( + AsymmetricKeyParameter publicKey) + { + SubjectPublicKeyInfo spki = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(publicKey); + return new OriginatorPublicKey( + new AlgorithmIdentifier(spki.AlgorithmID.Algorithm, DerNull.Instance), + spki.PublicKeyData.GetBytes()); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/KeyAgreeRecipientInfoGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/KeyAgreeRecipientInfoGenerator.cs.meta new file mode 100644 index 0000000..89c6e61 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/KeyAgreeRecipientInfoGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 59d1c24297075ee4998a2c1cf68737f1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/KeyAgreeRecipientInformation.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/KeyAgreeRecipientInformation.cs new file mode 100644 index 0000000..73e57a7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/KeyAgreeRecipientInformation.cs @@ -0,0 +1,226 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Asn1.Cms.Ecc; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.Utilities; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Pkcs; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.Cms +{ + /** + * the RecipientInfo class for a recipient who has been sent a message + * encrypted using key agreement. + */ + public class KeyAgreeRecipientInformation + : RecipientInformation + { + private KeyAgreeRecipientInfo info; + private Asn1OctetString encryptedKey; + + internal static void ReadRecipientInfo(IList infos, KeyAgreeRecipientInfo info, + CmsSecureReadable secureReadable) + { + try + { + foreach (Asn1Encodable rek in info.RecipientEncryptedKeys) + { + RecipientEncryptedKey id = RecipientEncryptedKey.GetInstance(rek.ToAsn1Object()); + + RecipientID rid = new RecipientID(); + + Asn1.Cms.KeyAgreeRecipientIdentifier karid = id.Identifier; + + Asn1.Cms.IssuerAndSerialNumber iAndSN = karid.IssuerAndSerialNumber; + if (iAndSN != null) + { + rid.Issuer = iAndSN.Name; + rid.SerialNumber = iAndSN.SerialNumber.Value; + } + else + { + Asn1.Cms.RecipientKeyIdentifier rKeyID = karid.RKeyID; + + // Note: 'date' and 'other' fields of RecipientKeyIdentifier appear to be only informational + + rid.SubjectKeyIdentifier = rKeyID.SubjectKeyIdentifier.GetOctets(); + } + + infos.Add(new KeyAgreeRecipientInformation(info, rid, id.EncryptedKey, + secureReadable)); + } + } + catch (IOException e) + { + throw new ArgumentException("invalid rid in KeyAgreeRecipientInformation", e); + } + } + + internal KeyAgreeRecipientInformation( + KeyAgreeRecipientInfo info, + RecipientID rid, + Asn1OctetString encryptedKey, + CmsSecureReadable secureReadable) + : base(info.KeyEncryptionAlgorithm, secureReadable) + { + this.info = info; + this.rid = rid; + this.encryptedKey = encryptedKey; + } + + private AsymmetricKeyParameter GetSenderPublicKey( + AsymmetricKeyParameter receiverPrivateKey, + OriginatorIdentifierOrKey originator) + { + OriginatorPublicKey opk = originator.OriginatorPublicKey; + if (opk != null) + { + return GetPublicKeyFromOriginatorPublicKey(receiverPrivateKey, opk); + } + + OriginatorID origID = new OriginatorID(); + + Asn1.Cms.IssuerAndSerialNumber iAndSN = originator.IssuerAndSerialNumber; + if (iAndSN != null) + { + origID.Issuer = iAndSN.Name; + origID.SerialNumber = iAndSN.SerialNumber.Value; + } + else + { + SubjectKeyIdentifier ski = originator.SubjectKeyIdentifier; + + origID.SubjectKeyIdentifier = ski.GetKeyIdentifier(); + } + + return GetPublicKeyFromOriginatorID(origID); + } + + private AsymmetricKeyParameter GetPublicKeyFromOriginatorPublicKey( + AsymmetricKeyParameter receiverPrivateKey, + OriginatorPublicKey originatorPublicKey) + { + PrivateKeyInfo privInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(receiverPrivateKey); + SubjectPublicKeyInfo pubInfo = new SubjectPublicKeyInfo( + privInfo.PrivateKeyAlgorithm, + originatorPublicKey.PublicKey.GetBytes()); + return PublicKeyFactory.CreateKey(pubInfo); + } + + private AsymmetricKeyParameter GetPublicKeyFromOriginatorID( + OriginatorID origID) + { + // TODO Support all alternatives for OriginatorIdentifierOrKey + // see RFC 3852 6.2.2 + throw new CmsException("No support for 'originator' as IssuerAndSerialNumber or SubjectKeyIdentifier"); + } + + private KeyParameter CalculateAgreedWrapKey( + string wrapAlg, + AsymmetricKeyParameter senderPublicKey, + AsymmetricKeyParameter receiverPrivateKey) + { + DerObjectIdentifier agreeAlgID = keyEncAlg.Algorithm; + + ICipherParameters senderPublicParams = senderPublicKey; + ICipherParameters receiverPrivateParams = receiverPrivateKey; + + if (agreeAlgID.Id.Equals(CmsEnvelopedGenerator.ECMqvSha1Kdf)) + { + byte[] ukmEncoding = info.UserKeyingMaterial.GetOctets(); + MQVuserKeyingMaterial ukm = MQVuserKeyingMaterial.GetInstance( + Asn1Object.FromByteArray(ukmEncoding)); + + AsymmetricKeyParameter ephemeralKey = GetPublicKeyFromOriginatorPublicKey( + receiverPrivateKey, ukm.EphemeralPublicKey); + + senderPublicParams = new MqvPublicParameters( + (ECPublicKeyParameters)senderPublicParams, + (ECPublicKeyParameters)ephemeralKey); + receiverPrivateParams = new MqvPrivateParameters( + (ECPrivateKeyParameters)receiverPrivateParams, + (ECPrivateKeyParameters)receiverPrivateParams); + } + + IBasicAgreement agreement = AgreementUtilities.GetBasicAgreementWithKdf( + agreeAlgID, wrapAlg); + agreement.Init(receiverPrivateParams); + BigInteger agreedValue = agreement.CalculateAgreement(senderPublicParams); + + int wrapKeySize = GeneratorUtilities.GetDefaultKeySize(wrapAlg) / 8; + byte[] wrapKeyBytes = X9IntegerConverter.IntegerToBytes(agreedValue, wrapKeySize); + return ParameterUtilities.CreateKeyParameter(wrapAlg, wrapKeyBytes); + } + + private KeyParameter UnwrapSessionKey( + string wrapAlg, + KeyParameter agreedKey) + { + byte[] encKeyOctets = encryptedKey.GetOctets(); + + IWrapper keyCipher = WrapperUtilities.GetWrapper(wrapAlg); + keyCipher.Init(false, agreedKey); + byte[] sKeyBytes = keyCipher.Unwrap(encKeyOctets, 0, encKeyOctets.Length); + return ParameterUtilities.CreateKeyParameter(GetContentAlgorithmName(), sKeyBytes); + } + + internal KeyParameter GetSessionKey( + AsymmetricKeyParameter receiverPrivateKey) + { + try + { + string wrapAlg = DerObjectIdentifier.GetInstance( + Asn1Sequence.GetInstance(keyEncAlg.Parameters)[0]).Id; + + AsymmetricKeyParameter senderPublicKey = GetSenderPublicKey( + receiverPrivateKey, info.Originator); + + KeyParameter agreedWrapKey = CalculateAgreedWrapKey(wrapAlg, + senderPublicKey, receiverPrivateKey); + + return UnwrapSessionKey(wrapAlg, agreedWrapKey); + } + catch (SecurityUtilityException e) + { + throw new CmsException("couldn't create cipher.", e); + } + catch (InvalidKeyException e) + { + throw new CmsException("key invalid in message.", e); + } + catch (Exception e) + { + throw new CmsException("originator key invalid.", e); + } + } + + /** + * decrypt the content and return an input stream. + */ + public override CmsTypedStream GetContentStream( + ICipherParameters key) + { + if (!(key is AsymmetricKeyParameter)) + throw new ArgumentException("KeyAgreement requires asymmetric key", "key"); + + AsymmetricKeyParameter receiverPrivateKey = (AsymmetricKeyParameter) key; + + if (!receiverPrivateKey.IsPrivate) + throw new ArgumentException("Expected private key", "key"); + + KeyParameter sKey = GetSessionKey(receiverPrivateKey); + + return GetContentFromSessionKey(sKey); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/KeyAgreeRecipientInformation.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/KeyAgreeRecipientInformation.cs.meta new file mode 100644 index 0000000..3438063 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/KeyAgreeRecipientInformation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f621db8d7fe54924aa5fda9f3ce6ead4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/KeyTransRecipientInfoGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/KeyTransRecipientInfoGenerator.cs new file mode 100644 index 0000000..60020be --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/KeyTransRecipientInfoGenerator.cs @@ -0,0 +1,83 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.Cms +{ + public class KeyTransRecipientInfoGenerator : RecipientInfoGenerator + { + private static readonly CmsEnvelopedHelper Helper = CmsEnvelopedHelper.Instance; + + private Asn1OctetString subjectKeyIdentifier; + private IKeyWrapper keyWrapper; + + // Derived fields + private SubjectPublicKeyInfo info; + private IssuerAndSerialNumber issuerAndSerialNumber; + private SecureRandom random; + + + public KeyTransRecipientInfoGenerator(X509Certificate recipCert, IKeyWrapper keyWrapper) + : this(new Asn1.Cms.IssuerAndSerialNumber(recipCert.IssuerDN, new DerInteger(recipCert.SerialNumber)), keyWrapper) + { + } + + public KeyTransRecipientInfoGenerator(IssuerAndSerialNumber issuerAndSerial, IKeyWrapper keyWrapper) + { + this.issuerAndSerialNumber = issuerAndSerial; + this.keyWrapper = keyWrapper; + } + + public KeyTransRecipientInfoGenerator(byte[] subjectKeyID, IKeyWrapper keyWrapper) + { + this.subjectKeyIdentifier = new DerOctetString(subjectKeyIdentifier); + this.keyWrapper = keyWrapper; + } + + public RecipientInfo Generate(KeyParameter contentEncryptionKey, SecureRandom random) + { + AlgorithmIdentifier keyEncryptionAlgorithm = this.AlgorithmDetails; + + this.random = random; + + byte[] encryptedKeyBytes = GenerateWrappedKey(contentEncryptionKey); + + RecipientIdentifier recipId; + if (issuerAndSerialNumber != null) + { + recipId = new RecipientIdentifier(issuerAndSerialNumber); + } + else + { + recipId = new RecipientIdentifier(subjectKeyIdentifier); + } + + return new RecipientInfo(new KeyTransRecipientInfo(recipId, keyEncryptionAlgorithm, + new DerOctetString(encryptedKeyBytes))); + } + + protected virtual AlgorithmIdentifier AlgorithmDetails + { + get + { + if (this.keyWrapper != null) + { + return (AlgorithmIdentifier)keyWrapper.AlgorithmDetails; + } + return info.AlgorithmID; + } + } + + protected virtual byte[] GenerateWrappedKey(KeyParameter contentEncryptionKey) + { + return keyWrapper.Wrap(contentEncryptionKey.GetKey()).Collect(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/KeyTransRecipientInfoGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/KeyTransRecipientInfoGenerator.cs.meta new file mode 100644 index 0000000..4b51f3e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/KeyTransRecipientInfoGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 313d62dd5b217fd4a97792edf5a1e6b7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/KeyTransRecipientInformation.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/KeyTransRecipientInformation.cs new file mode 100644 index 0000000..2a40fed --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/KeyTransRecipientInformation.cs @@ -0,0 +1,132 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cms; +using Asn1Pkcs = Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.X509; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Crypto.Operators; + +namespace Org.BouncyCastle.Cms +{ + /** + * the KeyTransRecipientInformation class for a recipient who has been sent a secret + * key encrypted using their public key that needs to be used to + * extract the message. + */ + public class KeyTransRecipientInformation + : RecipientInformation + { + private KeyTransRecipientInfo info; + + internal KeyTransRecipientInformation( + KeyTransRecipientInfo info, + CmsSecureReadable secureReadable) + : base(info.KeyEncryptionAlgorithm, secureReadable) + { + this.info = info; + this.rid = new RecipientID(); + + RecipientIdentifier r = info.RecipientIdentifier; + + try + { + if (r.IsTagged) + { + Asn1OctetString octs = Asn1OctetString.GetInstance(r.ID); + + rid.SubjectKeyIdentifier = octs.GetOctets(); + } + else + { + Asn1.Cms.IssuerAndSerialNumber iAnds = Asn1.Cms.IssuerAndSerialNumber.GetInstance(r.ID); + + rid.Issuer = iAnds.Name; + rid.SerialNumber = iAnds.SerialNumber.Value; + } + } + catch (IOException) + { + throw new ArgumentException("invalid rid in KeyTransRecipientInformation"); + } + } + + private string GetExchangeEncryptionAlgorithmName( + AlgorithmIdentifier algo) + { + DerObjectIdentifier oid = algo.Algorithm; + + if (Asn1Pkcs.PkcsObjectIdentifiers.RsaEncryption.Equals(oid)) + { + return "RSA//PKCS1Padding"; + } else if (Asn1Pkcs.PkcsObjectIdentifiers.IdRsaesOaep.Equals(oid)) + { + Asn1Pkcs.RsaesOaepParameters rsaParams = Asn1Pkcs.RsaesOaepParameters.GetInstance(algo.Parameters); + return "RSA//OAEPWITH"+DigestUtilities.GetAlgorithmName(rsaParams.HashAlgorithm.Algorithm)+"ANDMGF1Padding"; + } + + return oid.Id; + } + + internal KeyParameter UnwrapKey(ICipherParameters key) + { + byte[] encryptedKey = info.EncryptedKey.GetOctets(); + + + try + { + if (keyEncAlg.Algorithm.Equals(PkcsObjectIdentifiers.IdRsaesOaep)) + { + IKeyUnwrapper keyWrapper = new Asn1KeyUnwrapper(keyEncAlg.Algorithm, keyEncAlg.Parameters, key); + + return ParameterUtilities.CreateKeyParameter( + GetContentAlgorithmName(), keyWrapper.Unwrap(encryptedKey, 0, encryptedKey.Length).Collect()); + } + else + { + string keyExchangeAlgorithm = GetExchangeEncryptionAlgorithmName(keyEncAlg); + IWrapper keyWrapper = WrapperUtilities.GetWrapper(keyExchangeAlgorithm); + keyWrapper.Init(false, key); + + // FIXME Support for MAC algorithm parameters similar to cipher parameters + return ParameterUtilities.CreateKeyParameter( + GetContentAlgorithmName(), keyWrapper.Unwrap(encryptedKey, 0, encryptedKey.Length)); + } + } + catch (SecurityUtilityException e) + { + throw new CmsException("couldn't create cipher.", e); + } + catch (InvalidKeyException e) + { + throw new CmsException("key invalid in message.", e); + } +// catch (IllegalBlockSizeException e) + catch (DataLengthException e) + { + throw new CmsException("illegal blocksize in message.", e); + } +// catch (BadPaddingException e) + catch (InvalidCipherTextException e) + { + throw new CmsException("bad padding in message.", e); + } + } + + /** + * decrypt the content and return it as a byte array. + */ + public override CmsTypedStream GetContentStream( + ICipherParameters key) + { + KeyParameter sKey = UnwrapKey(key); + + return GetContentFromSessionKey(sKey); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/KeyTransRecipientInformation.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/KeyTransRecipientInformation.cs.meta new file mode 100644 index 0000000..af3fae1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/KeyTransRecipientInformation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0085d03e51e8b3d4d827fd48d94612d6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/OriginatorId.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/OriginatorId.cs new file mode 100644 index 0000000..5a3b737 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/OriginatorId.cs @@ -0,0 +1,51 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.X509.Store; + +namespace Org.BouncyCastle.Cms +{ + /** + * a basic index for an originator. + */ + public class OriginatorID + : X509CertStoreSelector + { + public override int GetHashCode() + { + int code = Arrays.GetHashCode(this.SubjectKeyIdentifier); + + BigInteger serialNumber = this.SerialNumber; + if (serialNumber != null) + { + code ^= serialNumber.GetHashCode(); + } + + X509Name issuer = this.Issuer; + if (issuer != null) + { + code ^= issuer.GetHashCode(); + } + + return code; + } + + public override bool Equals( + object obj) + { + if (obj == this) + return false; + + OriginatorID id = obj as OriginatorID; + + if (id == null) + return false; + + return Arrays.AreEqual(SubjectKeyIdentifier, id.SubjectKeyIdentifier) + && Platform.Equals(SerialNumber, id.SerialNumber) + && IssuersMatch(Issuer, id.Issuer); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/OriginatorId.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/OriginatorId.cs.meta new file mode 100644 index 0000000..13a3ab4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/OriginatorId.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e5529b63db2f9b54088ecb6994f87f63 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/OriginatorInfoGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/OriginatorInfoGenerator.cs new file mode 100644 index 0000000..6bf1087 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/OriginatorInfoGenerator.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.X509; +using Org.BouncyCastle.X509.Store; + +namespace Org.BouncyCastle.Cms +{ + public class OriginatorInfoGenerator + { + private readonly IList origCerts; + private readonly IList origCrls; + + public OriginatorInfoGenerator(X509Certificate origCert) + { + this.origCerts = Platform.CreateArrayList(1); + this.origCrls = null; + origCerts.Add(origCert.CertificateStructure); + } + + public OriginatorInfoGenerator(IX509Store origCerts) + : this(origCerts, null) + { + } + + public OriginatorInfoGenerator(IX509Store origCerts, IX509Store origCrls) + { + this.origCerts = CmsUtilities.GetCertificatesFromStore(origCerts); + this.origCrls = origCrls == null ? null : CmsUtilities.GetCrlsFromStore(origCrls); + } + + public virtual OriginatorInfo Generate() + { + Asn1Set certSet = CmsUtilities.CreateDerSetFromList(origCerts); + Asn1Set crlSet = origCrls == null ? null : CmsUtilities.CreateDerSetFromList(origCrls); + return new OriginatorInfo(certSet, crlSet); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/OriginatorInfoGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/OriginatorInfoGenerator.cs.meta new file mode 100644 index 0000000..1bc2a3b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/OriginatorInfoGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dbfcb8dc70cd350499d9940fd35c4cc3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/OriginatorInformation.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/OriginatorInformation.cs new file mode 100644 index 0000000..618add6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/OriginatorInformation.cs @@ -0,0 +1,96 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.X509; +using Org.BouncyCastle.X509.Store; + +namespace Org.BouncyCastle.Cms +{ + public class OriginatorInformation + { + private readonly OriginatorInfo originatorInfo; + + internal OriginatorInformation(OriginatorInfo originatorInfo) + { + this.originatorInfo = originatorInfo; + } + + /** + * Return the certificates stored in the underlying OriginatorInfo object. + * + * @return a Store of X509CertificateHolder objects. + */ + public virtual IX509Store GetCertificates() + { + Asn1Set certSet = originatorInfo.Certificates; + + if (certSet != null) + { + IList certList = Platform.CreateArrayList(certSet.Count); + + foreach (Asn1Encodable enc in certSet) + { + Asn1Object obj = enc.ToAsn1Object(); + if (obj is Asn1Sequence) + { + certList.Add(new X509Certificate(X509CertificateStructure.GetInstance(obj))); + } + } + + return X509StoreFactory.Create( + "Certificate/Collection", + new X509CollectionStoreParameters(certList)); + } + + return X509StoreFactory.Create( + "Certificate/Collection", + new X509CollectionStoreParameters(Platform.CreateArrayList())); + } + + /** + * Return the CRLs stored in the underlying OriginatorInfo object. + * + * @return a Store of X509CRLHolder objects. + */ + public virtual IX509Store GetCrls() + { + Asn1Set crlSet = originatorInfo.Certificates; + + if (crlSet != null) + { + IList crlList = Platform.CreateArrayList(crlSet.Count); + + foreach (Asn1Encodable enc in crlSet) + { + Asn1Object obj = enc.ToAsn1Object(); + if (obj is Asn1Sequence) + { + crlList.Add(new X509Crl(CertificateList.GetInstance(obj))); + } + } + + return X509StoreFactory.Create( + "CRL/Collection", + new X509CollectionStoreParameters(crlList)); + } + + return X509StoreFactory.Create( + "CRL/Collection", + new X509CollectionStoreParameters(Platform.CreateArrayList())); + } + + /** + * Return the underlying ASN.1 object defining this SignerInformation object. + * + * @return a OriginatorInfo. + */ + public virtual OriginatorInfo ToAsn1Structure() + { + return originatorInfo; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/OriginatorInformation.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/OriginatorInformation.cs.meta new file mode 100644 index 0000000..efd4b4e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/OriginatorInformation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0ee9449b628f73d4aa0908ea2d9400d9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/PKCS5Scheme2PBEKey.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/PKCS5Scheme2PBEKey.cs new file mode 100644 index 0000000..08b8518 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/PKCS5Scheme2PBEKey.cs @@ -0,0 +1,64 @@ +using System; + +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Cms +{ + /// + /// PKCS5 scheme-2 - password converted to bytes assuming ASCII. + /// + public class Pkcs5Scheme2PbeKey + : CmsPbeKey + { + [Obsolete("Use version taking 'char[]' instead")] + public Pkcs5Scheme2PbeKey( + string password, + byte[] salt, + int iterationCount) + : this(password.ToCharArray(), salt, iterationCount) + { + } + + [Obsolete("Use version taking 'char[]' instead")] + public Pkcs5Scheme2PbeKey( + string password, + AlgorithmIdentifier keyDerivationAlgorithm) + : this(password.ToCharArray(), keyDerivationAlgorithm) + { + } + + public Pkcs5Scheme2PbeKey( + char[] password, + byte[] salt, + int iterationCount) + : base(password, salt, iterationCount) + { + } + + public Pkcs5Scheme2PbeKey( + char[] password, + AlgorithmIdentifier keyDerivationAlgorithm) + : base(password, keyDerivationAlgorithm) + { + } + + internal override KeyParameter GetEncoded( + string algorithmOid) + { + Pkcs5S2ParametersGenerator gen = new Pkcs5S2ParametersGenerator(); + + gen.Init( + PbeParametersGenerator.Pkcs5PasswordToBytes(password), + salt, + iterationCount); + + return (KeyParameter) gen.GenerateDerivedParameters( + algorithmOid, + CmsEnvelopedHelper.Instance.GetKeySize(algorithmOid)); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/PKCS5Scheme2PBEKey.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/PKCS5Scheme2PBEKey.cs.meta new file mode 100644 index 0000000..23ba56f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/PKCS5Scheme2PBEKey.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0ca647a1968e6c448a80f99a161fea76 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/PKCS5Scheme2UTF8PBEKey.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/PKCS5Scheme2UTF8PBEKey.cs new file mode 100644 index 0000000..7aecc29 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/PKCS5Scheme2UTF8PBEKey.cs @@ -0,0 +1,64 @@ +using System; + +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Cms +{ + /** + * PKCS5 scheme-2 - password converted to bytes using UTF-8. + */ + public class Pkcs5Scheme2Utf8PbeKey + : CmsPbeKey + { + [Obsolete("Use version taking 'char[]' instead")] + public Pkcs5Scheme2Utf8PbeKey( + string password, + byte[] salt, + int iterationCount) + : this(password.ToCharArray(), salt, iterationCount) + { + } + + [Obsolete("Use version taking 'char[]' instead")] + public Pkcs5Scheme2Utf8PbeKey( + string password, + AlgorithmIdentifier keyDerivationAlgorithm) + : this(password.ToCharArray(), keyDerivationAlgorithm) + { + } + + public Pkcs5Scheme2Utf8PbeKey( + char[] password, + byte[] salt, + int iterationCount) + : base(password, salt, iterationCount) + { + } + + public Pkcs5Scheme2Utf8PbeKey( + char[] password, + AlgorithmIdentifier keyDerivationAlgorithm) + : base(password, keyDerivationAlgorithm) + { + } + + internal override KeyParameter GetEncoded( + string algorithmOid) + { + Pkcs5S2ParametersGenerator gen = new Pkcs5S2ParametersGenerator(); + + gen.Init( + PbeParametersGenerator.Pkcs5PasswordToUtf8Bytes(password), + salt, + iterationCount); + + return (KeyParameter) gen.GenerateDerivedParameters( + algorithmOid, + CmsEnvelopedHelper.Instance.GetKeySize(algorithmOid)); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/PKCS5Scheme2UTF8PBEKey.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/PKCS5Scheme2UTF8PBEKey.cs.meta new file mode 100644 index 0000000..0534915 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/PKCS5Scheme2UTF8PBEKey.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7e58946a3ee3eb84787618367470970e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/PasswordRecipientInfoGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/PasswordRecipientInfoGenerator.cs new file mode 100644 index 0000000..9916edf --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/PasswordRecipientInfoGenerator.cs @@ -0,0 +1,70 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Cms +{ + internal class PasswordRecipientInfoGenerator : RecipientInfoGenerator + { + private static readonly CmsEnvelopedHelper Helper = CmsEnvelopedHelper.Instance; + + private AlgorithmIdentifier keyDerivationAlgorithm; + private KeyParameter keyEncryptionKey; + // TODO Can get this from keyEncryptionKey? + private string keyEncryptionKeyOID; + + internal PasswordRecipientInfoGenerator() + { + } + + internal AlgorithmIdentifier KeyDerivationAlgorithm + { + set { this.keyDerivationAlgorithm = value; } + } + + internal KeyParameter KeyEncryptionKey + { + set { this.keyEncryptionKey = value; } + } + + internal string KeyEncryptionKeyOID + { + set { this.keyEncryptionKeyOID = value; } + } + + public RecipientInfo Generate(KeyParameter contentEncryptionKey, SecureRandom random) + { + byte[] keyBytes = contentEncryptionKey.GetKey(); + + string rfc3211WrapperName = Helper.GetRfc3211WrapperName(keyEncryptionKeyOID); + IWrapper keyWrapper = Helper.CreateWrapper(rfc3211WrapperName); + + // Note: In Java build, the IV is automatically generated in JCE layer + int ivLength = Platform.StartsWith(rfc3211WrapperName, "DESEDE") ? 8 : 16; + byte[] iv = new byte[ivLength]; + random.NextBytes(iv); + + ICipherParameters parameters = new ParametersWithIV(keyEncryptionKey, iv); + keyWrapper.Init(true, new ParametersWithRandom(parameters, random)); + Asn1OctetString encryptedKey = new DerOctetString( + keyWrapper.Wrap(keyBytes, 0, keyBytes.Length)); + + DerSequence seq = new DerSequence( + new DerObjectIdentifier(keyEncryptionKeyOID), + new DerOctetString(iv)); + + AlgorithmIdentifier keyEncryptionAlgorithm = new AlgorithmIdentifier( + PkcsObjectIdentifiers.IdAlgPwriKek, seq); + + return new RecipientInfo(new PasswordRecipientInfo( + keyDerivationAlgorithm, keyEncryptionAlgorithm, encryptedKey)); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/PasswordRecipientInfoGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/PasswordRecipientInfoGenerator.cs.meta new file mode 100644 index 0000000..4c263d7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/PasswordRecipientInfoGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8bf0519447ec96b419a63596c3a957e1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/PasswordRecipientInformation.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/PasswordRecipientInformation.cs new file mode 100644 index 0000000..f629cab --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/PasswordRecipientInformation.cs @@ -0,0 +1,79 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Cms +{ + /** + * the RecipientInfo class for a recipient who has been sent a message + * encrypted using a password. + */ + public class PasswordRecipientInformation + : RecipientInformation + { + private readonly PasswordRecipientInfo info; + + internal PasswordRecipientInformation( + PasswordRecipientInfo info, + CmsSecureReadable secureReadable) + : base(info.KeyEncryptionAlgorithm, secureReadable) + { + this.info = info; + this.rid = new RecipientID(); + } + + /** + * return the object identifier for the key derivation algorithm, or null + * if there is none present. + * + * @return OID for key derivation algorithm, if present. + */ + public virtual AlgorithmIdentifier KeyDerivationAlgorithm + { + get { return info.KeyDerivationAlgorithm; } + } + + /** + * decrypt the content and return an input stream. + */ + public override CmsTypedStream GetContentStream( + ICipherParameters key) + { + try + { + AlgorithmIdentifier kekAlg = AlgorithmIdentifier.GetInstance(info.KeyEncryptionAlgorithm); + Asn1Sequence kekAlgParams = (Asn1Sequence)kekAlg.Parameters; + byte[] encryptedKey = info.EncryptedKey.GetOctets(); + string kekAlgName = DerObjectIdentifier.GetInstance(kekAlgParams[0]).Id; + string cName = CmsEnvelopedHelper.Instance.GetRfc3211WrapperName(kekAlgName); + IWrapper keyWrapper = WrapperUtilities.GetWrapper(cName); + + byte[] iv = Asn1OctetString.GetInstance(kekAlgParams[1]).GetOctets(); + + ICipherParameters parameters = ((CmsPbeKey)key).GetEncoded(kekAlgName); + parameters = new ParametersWithIV(parameters, iv); + + keyWrapper.Init(false, parameters); + + KeyParameter sKey = ParameterUtilities.CreateKeyParameter( + GetContentAlgorithmName(), keyWrapper.Unwrap(encryptedKey, 0, encryptedKey.Length)); + + return GetContentFromSessionKey(sKey); + } + catch (SecurityUtilityException e) + { + throw new CmsException("couldn't create cipher.", e); + } + catch (InvalidKeyException e) + { + throw new CmsException("key invalid in message.", e); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/PasswordRecipientInformation.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/PasswordRecipientInformation.cs.meta new file mode 100644 index 0000000..0e3f650 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/PasswordRecipientInformation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6eea337def3af8847a662077cd7fb87c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/RecipientId.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/RecipientId.cs new file mode 100644 index 0000000..9b6eb09 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/RecipientId.cs @@ -0,0 +1,58 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.X509.Store; + +namespace Org.BouncyCastle.Cms +{ + public class RecipientID + : X509CertStoreSelector + { + private byte[] keyIdentifier; + + public byte[] KeyIdentifier + { + get { return Arrays.Clone(keyIdentifier); } + set { keyIdentifier = Arrays.Clone(value); } + } + + public override int GetHashCode() + { + int code = Arrays.GetHashCode(keyIdentifier) + ^ Arrays.GetHashCode(this.SubjectKeyIdentifier); + + BigInteger serialNumber = this.SerialNumber; + if (serialNumber != null) + { + code ^= serialNumber.GetHashCode(); + } + + X509Name issuer = this.Issuer; + if (issuer != null) + { + code ^= issuer.GetHashCode(); + } + + return code; + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + RecipientID id = obj as RecipientID; + + if (id == null) + return false; + + return Arrays.AreEqual(keyIdentifier, id.keyIdentifier) + && Arrays.AreEqual(SubjectKeyIdentifier, id.SubjectKeyIdentifier) + && Platform.Equals(SerialNumber, id.SerialNumber) + && IssuersMatch(Issuer, id.Issuer); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/RecipientId.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/RecipientId.cs.meta new file mode 100644 index 0000000..0e56977 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/RecipientId.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d8febbdd3333db4448d03b4302adfd77 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/RecipientInfoGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/RecipientInfoGenerator.cs new file mode 100644 index 0000000..75f5dcc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/RecipientInfoGenerator.cs @@ -0,0 +1,26 @@ +using System; + +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Cms +{ + public interface RecipientInfoGenerator + { + /// + /// Generate a RecipientInfo object for the given key. + /// + /// + /// A + /// + /// + /// A + /// + /// + /// A + /// + /// + RecipientInfo Generate(KeyParameter contentEncryptionKey, SecureRandom random); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/RecipientInfoGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/RecipientInfoGenerator.cs.meta new file mode 100644 index 0000000..450921a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/RecipientInfoGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4e3485e13e2db9e4093a0f8a4783c798 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/RecipientInformation.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/RecipientInformation.cs new file mode 100644 index 0000000..272b841 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/RecipientInformation.cs @@ -0,0 +1,126 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.IO; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Cms +{ + public abstract class RecipientInformation + { + internal RecipientID rid = new RecipientID(); + internal AlgorithmIdentifier keyEncAlg; + internal CmsSecureReadable secureReadable; + + private byte[] resultMac; + + internal RecipientInformation( + AlgorithmIdentifier keyEncAlg, + CmsSecureReadable secureReadable) + { + this.keyEncAlg = keyEncAlg; + this.secureReadable = secureReadable; + } + + internal string GetContentAlgorithmName() + { + AlgorithmIdentifier algorithm = secureReadable.Algorithm; +// return CmsEnvelopedHelper.Instance.GetSymmetricCipherName(algorithm.Algorithm.Id); + return algorithm.Algorithm.Id; + } + + public RecipientID RecipientID + { + get { return rid; } + } + + public AlgorithmIdentifier KeyEncryptionAlgorithmID + { + get { return keyEncAlg; } + } + + /** + * return the object identifier for the key encryption algorithm. + * + * @return OID for key encryption algorithm. + */ + public string KeyEncryptionAlgOid + { + get { return keyEncAlg.Algorithm.Id; } + } + + /** + * return the ASN.1 encoded key encryption algorithm parameters, or null if + * there aren't any. + * + * @return ASN.1 encoding of key encryption algorithm parameters. + */ + public Asn1Object KeyEncryptionAlgParams + { + get + { + Asn1Encodable ae = keyEncAlg.Parameters; + + return ae == null ? null : ae.ToAsn1Object(); + } + } + + internal CmsTypedStream GetContentFromSessionKey( + KeyParameter sKey) + { + CmsReadable readable = secureReadable.GetReadable(sKey); + + try + { + return new CmsTypedStream(readable.GetInputStream()); + } + catch (IOException e) + { + throw new CmsException("error getting .", e); + } + } + + public byte[] GetContent( + ICipherParameters key) + { + try + { + return CmsUtilities.StreamToByteArray(GetContentStream(key).ContentStream); + } + catch (IOException e) + { + throw new Exception("unable to parse internal stream: " + e); + } + } + + /** + * Return the MAC calculated for the content stream. Note: this call is only meaningful once all + * the content has been read. + * + * @return byte array containing the mac. + */ + public byte[] GetMac() + { + if (resultMac == null) + { + object cryptoObject = secureReadable.CryptoObject; + if (cryptoObject is IMac) + { + resultMac = MacUtilities.DoFinal((IMac)cryptoObject); + } + } + + return Arrays.Clone(resultMac); + } + + public abstract CmsTypedStream GetContentStream(ICipherParameters key); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/RecipientInformation.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/RecipientInformation.cs.meta new file mode 100644 index 0000000..7a39ad2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/RecipientInformation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2f9dc9e8a5d6df448b7e2ee719c15eff +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/RecipientInformationStore.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/RecipientInformationStore.cs new file mode 100644 index 0000000..33b472f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/RecipientInformationStore.cs @@ -0,0 +1,86 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Cms +{ + public class RecipientInformationStore + { + private readonly IList all; //ArrayList[RecipientInformation] + private readonly IDictionary table = Platform.CreateHashtable(); // Hashtable[RecipientID, ArrayList[RecipientInformation]] + + public RecipientInformationStore( + ICollection recipientInfos) + { + foreach (RecipientInformation recipientInformation in recipientInfos) + { + RecipientID rid = recipientInformation.RecipientID; + IList list = (IList)table[rid]; + + if (list == null) + { + table[rid] = list = Platform.CreateArrayList(1); + } + + list.Add(recipientInformation); + } + + this.all = Platform.CreateArrayList(recipientInfos); + } + + public RecipientInformation this[RecipientID selector] + { + get { return GetFirstRecipient(selector); } + } + + /** + * Return the first RecipientInformation object that matches the + * passed in selector. Null if there are no matches. + * + * @param selector to identify a recipient + * @return a single RecipientInformation object. Null if none matches. + */ + public RecipientInformation GetFirstRecipient( + RecipientID selector) + { + IList list = (IList) table[selector]; + + return list == null ? null : (RecipientInformation) list[0]; + } + + /** + * Return the number of recipients in the collection. + * + * @return number of recipients identified. + */ + public int Count + { + get { return all.Count; } + } + + /** + * Return all recipients in the collection + * + * @return a collection of recipients. + */ + public ICollection GetRecipients() + { + return Platform.CreateArrayList(all); + } + + /** + * Return possible empty collection with recipients matching the passed in RecipientID + * + * @param selector a recipient id to select against. + * @return a collection of RecipientInformation objects. + */ + public ICollection GetRecipients( + RecipientID selector) + { + IList list = (IList)table[selector]; + + return list == null ? Platform.CreateArrayList() : Platform.CreateArrayList(list); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/RecipientInformationStore.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/RecipientInformationStore.cs.meta new file mode 100644 index 0000000..682f079 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/RecipientInformationStore.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5a06aedfb9f72dd4884e78bce30f7fdc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/SignerId.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/SignerId.cs new file mode 100644 index 0000000..baac936 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/SignerId.cs @@ -0,0 +1,51 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.X509.Store; + +namespace Org.BouncyCastle.Cms +{ + /** + * a basic index for a signer. + */ + public class SignerID + : X509CertStoreSelector + { + public override int GetHashCode() + { + int code = Arrays.GetHashCode(this.SubjectKeyIdentifier); + + BigInteger serialNumber = this.SerialNumber; + if (serialNumber != null) + { + code ^= serialNumber.GetHashCode(); + } + + X509Name issuer = this.Issuer; + if (issuer != null) + { + code ^= issuer.GetHashCode(); + } + + return code; + } + + public override bool Equals( + object obj) + { + if (obj == this) + return false; + + SignerID id = obj as SignerID; + + if (id == null) + return false; + + return Arrays.AreEqual(SubjectKeyIdentifier, id.SubjectKeyIdentifier) + && Platform.Equals(SerialNumber, id.SerialNumber) + && IssuersMatch(Issuer, id.Issuer); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/SignerId.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/SignerId.cs.meta new file mode 100644 index 0000000..8d2111d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/SignerId.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4ea55bb40e99d0047b691e0cf06c852f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/SignerInfoGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/SignerInfoGenerator.cs new file mode 100644 index 0000000..786749c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/SignerInfoGenerator.cs @@ -0,0 +1,177 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.Cms +{ + internal interface ISignerInfoGenerator + { + SignerInfo Generate(DerObjectIdentifier contentType, AlgorithmIdentifier digestAlgorithm, + byte[] calculatedDigest); + } + + public class SignerInfoGenerator + { + internal X509Certificate certificate; + internal ISignatureFactory contentSigner; + internal SignerIdentifier sigId; + internal CmsAttributeTableGenerator signedGen; + internal CmsAttributeTableGenerator unsignedGen; + private bool isDirectSignature; + + internal SignerInfoGenerator(SignerIdentifier sigId, ISignatureFactory signerFactory): this(sigId, signerFactory, false) + { + + } + + internal SignerInfoGenerator(SignerIdentifier sigId, ISignatureFactory signerFactory, bool isDirectSignature) + { + this.sigId = sigId; + this.contentSigner = signerFactory; + this.isDirectSignature = isDirectSignature; + if (this.isDirectSignature) + { + this.signedGen = null; + this.unsignedGen = null; + } + else + { + this.signedGen = new DefaultSignedAttributeTableGenerator(); + this.unsignedGen = null; + } + } + + internal SignerInfoGenerator(SignerIdentifier sigId, ISignatureFactory contentSigner, CmsAttributeTableGenerator signedGen, CmsAttributeTableGenerator unsignedGen) + { + this.sigId = sigId; + this.contentSigner = contentSigner; + this.signedGen = signedGen; + this.unsignedGen = unsignedGen; + this.isDirectSignature = false; + } + + internal void setAssociatedCertificate(X509Certificate certificate) + { + this.certificate = certificate; + } + + public SignerInfoGeneratorBuilder NewBuilder() + { + SignerInfoGeneratorBuilder builder = new SignerInfoGeneratorBuilder(); + builder.WithSignedAttributeGenerator(signedGen); + builder.WithUnsignedAttributeGenerator(unsignedGen); + builder.SetDirectSignature(isDirectSignature); + return builder; + } + + } + + public class SignerInfoGeneratorBuilder + { + private bool directSignature; + private CmsAttributeTableGenerator signedGen; + private CmsAttributeTableGenerator unsignedGen; + + public SignerInfoGeneratorBuilder() + { + } + + + /** + * If the passed in flag is true, the signer signature will be based on the data, not + * a collection of signed attributes, and no signed attributes will be included. + * + * @return the builder object + */ + public SignerInfoGeneratorBuilder SetDirectSignature(bool hasNoSignedAttributes) + { + this.directSignature = hasNoSignedAttributes; + + return this; + } + + /** + * Provide a custom signed attribute generator. + * + * @param signedGen a generator of signed attributes. + * @return the builder object + */ + public SignerInfoGeneratorBuilder WithSignedAttributeGenerator(CmsAttributeTableGenerator signedGen) + { + this.signedGen = signedGen; + + return this; + } + + /** + * Provide a generator of unsigned attributes. + * + * @param unsignedGen a generator for signed attributes. + * @return the builder object + */ + public SignerInfoGeneratorBuilder WithUnsignedAttributeGenerator(CmsAttributeTableGenerator unsignedGen) + { + this.unsignedGen = unsignedGen; + + return this; + } + + /** + * Build a generator with the passed in X.509 certificate issuer and serial number as the signerIdentifier. + * + * @param contentSigner operator for generating the final signature in the SignerInfo with. + * @param certificate X.509 certificate related to the contentSigner. + * @return a SignerInfoGenerator + * @throws OperatorCreationException if the generator cannot be built. + */ + public SignerInfoGenerator Build(ISignatureFactory contentSigner, X509Certificate certificate) + { + SignerIdentifier sigId = new SignerIdentifier(new IssuerAndSerialNumber(certificate.IssuerDN, new DerInteger(certificate.SerialNumber))); + + SignerInfoGenerator sigInfoGen = CreateGenerator(contentSigner, sigId); + + sigInfoGen.setAssociatedCertificate(certificate); + + return sigInfoGen; + } + + /** + * Build a generator with the passed in subjectKeyIdentifier as the signerIdentifier. If used you should + * try to follow the calculation described in RFC 5280 section 4.2.1.2. + * + * @param signerFactory operator factory for generating the final signature in the SignerInfo with. + * @param subjectKeyIdentifier key identifier to identify the public key for verifying the signature. + * @return a SignerInfoGenerator + */ + public SignerInfoGenerator Build(ISignatureFactory signerFactory, byte[] subjectKeyIdentifier) + { + SignerIdentifier sigId = new SignerIdentifier(new DerOctetString(subjectKeyIdentifier)); + + return CreateGenerator(signerFactory, sigId); + } + + private SignerInfoGenerator CreateGenerator(ISignatureFactory contentSigner, SignerIdentifier sigId) + { + if (directSignature) + { + return new SignerInfoGenerator(sigId, contentSigner, true); + } + + if (signedGen != null || unsignedGen != null) + { + if (signedGen == null) + { + signedGen = new DefaultSignedAttributeTableGenerator(); + } + + return new SignerInfoGenerator(sigId, contentSigner, signedGen, unsignedGen); + } + + return new SignerInfoGenerator(sigId, contentSigner); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/SignerInfoGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/SignerInfoGenerator.cs.meta new file mode 100644 index 0000000..064154e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/SignerInfoGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6a0dd643691d3fc4bbc4b33a5895b153 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/SignerInformation.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/SignerInformation.cs new file mode 100644 index 0000000..3ab1c09 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/SignerInformation.cs @@ -0,0 +1,815 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.IO; +using Org.BouncyCastle.Crypto.Signers; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.Cms +{ + /** + * an expanded SignerInfo block from a CMS Signed message + */ + public class SignerInformation + { + private static readonly CmsSignedHelper Helper = CmsSignedHelper.Instance; + + private SignerID sid; + + private CmsProcessable content; + private byte[] signature; + private DerObjectIdentifier contentType; + private byte[] calculatedDigest; + private byte[] resultDigest; + + // Derived + private Asn1.Cms.AttributeTable signedAttributeTable; + private Asn1.Cms.AttributeTable unsignedAttributeTable; + private readonly bool isCounterSignature; + + protected SignerInfo info; + protected AlgorithmIdentifier digestAlgorithm; + protected AlgorithmIdentifier encryptionAlgorithm; + protected readonly Asn1Set signedAttributeSet; + protected readonly Asn1Set unsignedAttributeSet; + + internal SignerInformation( + SignerInfo info, + DerObjectIdentifier contentType, + CmsProcessable content, + IDigestCalculator digestCalculator) + { + this.info = info; + this.sid = new SignerID(); + this.contentType = contentType; + this.isCounterSignature = contentType == null; + + try + { + SignerIdentifier s = info.SignerID; + + if (s.IsTagged) + { + Asn1OctetString octs = Asn1OctetString.GetInstance(s.ID); + + sid.SubjectKeyIdentifier = octs.GetEncoded(); + } + else + { + Asn1.Cms.IssuerAndSerialNumber iAnds = + Asn1.Cms.IssuerAndSerialNumber.GetInstance(s.ID); + + sid.Issuer = iAnds.Name; + sid.SerialNumber = iAnds.SerialNumber.Value; + } + } + catch (IOException) + { + throw new ArgumentException("invalid sid in SignerInfo"); + } + + this.digestAlgorithm = info.DigestAlgorithm; + this.signedAttributeSet = info.AuthenticatedAttributes; + this.unsignedAttributeSet = info.UnauthenticatedAttributes; + this.encryptionAlgorithm = info.DigestEncryptionAlgorithm; + this.signature = (byte[])info.EncryptedDigest.GetOctets().Clone(); + + this.content = content; + this.calculatedDigest = (digestCalculator != null) ? digestCalculator.GetDigest() : null; + } + + /** + * Protected constructor. In some cases clients have their own idea about how to encode + * the signed attributes and calculate the signature. This constructor is to allow developers + * to deal with that by extending off the class and overriding e.g. SignedAttributes property. + * + * @param baseInfo the SignerInformation to base this one on. + */ + protected SignerInformation(SignerInformation baseInfo) + { + this.info = baseInfo.info; + this.content = baseInfo.content; + this.contentType = baseInfo.contentType; + this.isCounterSignature = baseInfo.IsCounterSignature; + this.sid = baseInfo.sid; + this.digestAlgorithm = info.DigestAlgorithm; + this.signedAttributeSet = info.AuthenticatedAttributes; + this.unsignedAttributeSet = info.UnauthenticatedAttributes; + this.encryptionAlgorithm = info.DigestEncryptionAlgorithm; + this.signature = (byte[])info.EncryptedDigest.GetOctets().Clone(); + + this.calculatedDigest = baseInfo.calculatedDigest; + this.signedAttributeTable = baseInfo.signedAttributeTable; + this.unsignedAttributeTable = baseInfo.unsignedAttributeTable; + } + + public bool IsCounterSignature + { + get { return isCounterSignature; } + } + + public DerObjectIdentifier ContentType + { + get { return contentType; } + } + + public SignerID SignerID + { + get { return sid; } + } + + /** + * return the version number for this objects underlying SignerInfo structure. + */ + public int Version + { + get { return info.Version.IntValueExact; } + } + + public AlgorithmIdentifier DigestAlgorithmID + { + get { return digestAlgorithm; } + } + + /** + * return the object identifier for the signature. + */ + public string DigestAlgOid + { + get { return digestAlgorithm.Algorithm.Id; } + } + + /** + * return the signature parameters, or null if there aren't any. + */ + public Asn1Object DigestAlgParams + { + get + { + Asn1Encodable ae = digestAlgorithm.Parameters; + + return ae == null ? null : ae.ToAsn1Object(); + } + } + + /** + * return the content digest that was calculated during verification. + */ + public byte[] GetContentDigest() + { + if (resultDigest == null) + { + throw new InvalidOperationException("method can only be called after verify."); + } + + return (byte[])resultDigest.Clone(); + } + + public AlgorithmIdentifier EncryptionAlgorithmID + { + get { return encryptionAlgorithm; } + } + + /** + * return the object identifier for the signature. + */ + public string EncryptionAlgOid + { + get { return encryptionAlgorithm.Algorithm.Id; } + } + + /** + * return the signature/encryption algorithm parameters, or null if + * there aren't any. + */ + public Asn1Object EncryptionAlgParams + { + get + { + Asn1Encodable ae = encryptionAlgorithm.Parameters; + + return ae == null ? null : ae.ToAsn1Object(); + } + } + + /** + * return a table of the signed attributes - indexed by + * the OID of the attribute. + */ + public Asn1.Cms.AttributeTable SignedAttributes + { + get + { + if (signedAttributeSet != null && signedAttributeTable == null) + { + signedAttributeTable = new Asn1.Cms.AttributeTable(signedAttributeSet); + } + return signedAttributeTable; + } + } + + /** + * return a table of the unsigned attributes indexed by + * the OID of the attribute. + */ + public Asn1.Cms.AttributeTable UnsignedAttributes + { + get + { + if (unsignedAttributeSet != null && unsignedAttributeTable == null) + { + unsignedAttributeTable = new Asn1.Cms.AttributeTable(unsignedAttributeSet); + } + return unsignedAttributeTable; + } + } + + /** + * return the encoded signature + */ + public byte[] GetSignature() + { + return (byte[]) signature.Clone(); + } + + /** + * Return a SignerInformationStore containing the counter signatures attached to this + * signer. If no counter signatures are present an empty store is returned. + */ + public SignerInformationStore GetCounterSignatures() + { + // TODO There are several checks implied by the RFC3852 comments that are missing + + /* + The countersignature attribute MUST be an unsigned attribute; it MUST + NOT be a signed attribute, an authenticated attribute, an + unauthenticated attribute, or an unprotected attribute. + */ + Asn1.Cms.AttributeTable unsignedAttributeTable = UnsignedAttributes; + if (unsignedAttributeTable == null) + { + return new SignerInformationStore(Platform.CreateArrayList(0)); + } + + IList counterSignatures = Platform.CreateArrayList(); + + /* + The UnsignedAttributes syntax is defined as a SET OF Attributes. The + UnsignedAttributes in a signerInfo may include multiple instances of + the countersignature attribute. + */ + Asn1EncodableVector allCSAttrs = unsignedAttributeTable.GetAll(CmsAttributes.CounterSignature); + + foreach (Asn1.Cms.Attribute counterSignatureAttribute in allCSAttrs) + { + /* + A countersignature attribute can have multiple attribute values. The + syntax is defined as a SET OF AttributeValue, and there MUST be one + or more instances of AttributeValue present. + */ + Asn1Set values = counterSignatureAttribute.AttrValues; + if (values.Count < 1) + { + // TODO Throw an appropriate exception? + } + + foreach (Asn1Encodable asn1Obj in values) + { + /* + Countersignature values have the same meaning as SignerInfo values + for ordinary signatures, except that: + + 1. The signedAttributes field MUST NOT contain a content-type + attribute; there is no content type for countersignatures. + + 2. The signedAttributes field MUST contain a message-digest + attribute if it contains any other attributes. + + 3. The input to the message-digesting process is the contents + octets of the DER encoding of the signatureValue field of the + SignerInfo value with which the attribute is associated. + */ + SignerInfo si = SignerInfo.GetInstance(asn1Obj.ToAsn1Object()); + + string digestName = CmsSignedHelper.Instance.GetDigestAlgName(si.DigestAlgorithm.Algorithm.Id); + + counterSignatures.Add(new SignerInformation(si, null, null, new CounterSignatureDigestCalculator(digestName, GetSignature()))); + } + } + + return new SignerInformationStore(counterSignatures); + } + + /** + * return the DER encoding of the signed attributes. + * @throws IOException if an encoding error occurs. + */ + public virtual byte[] GetEncodedSignedAttributes() + { + return signedAttributeSet == null + ? null + : signedAttributeSet.GetEncoded(Asn1Encodable.Der); + } + + private bool DoVerify( + AsymmetricKeyParameter key) + { + DerObjectIdentifier sigAlgOid = this.encryptionAlgorithm.Algorithm; + Asn1Encodable sigParams = this.encryptionAlgorithm.Parameters; + string digestName = Helper.GetDigestAlgName(this.EncryptionAlgOid); + + if (digestName.Equals(sigAlgOid.Id)) + { + digestName = Helper.GetDigestAlgName(this.DigestAlgOid); + } + + IDigest digest = Helper.GetDigestInstance(digestName); + ISigner sig; + + if (sigAlgOid.Equals(Asn1.Pkcs.PkcsObjectIdentifiers.IdRsassaPss)) + { + // RFC 4056 2.2 + // When the id-RSASSA-PSS algorithm identifier is used for a signature, + // the AlgorithmIdentifier parameters field MUST contain RSASSA-PSS-params. + if (sigParams == null) + throw new CmsException("RSASSA-PSS signature must specify algorithm parameters"); + + try + { + // TODO Provide abstract configuration mechanism + // (via alternate SignerUtilities.GetSigner method taking ASN.1 params) + + Asn1.Pkcs.RsassaPssParameters pss = Asn1.Pkcs.RsassaPssParameters.GetInstance( + sigParams.ToAsn1Object()); + + if (!pss.HashAlgorithm.Algorithm.Equals(this.digestAlgorithm.Algorithm)) + throw new CmsException("RSASSA-PSS signature parameters specified incorrect hash algorithm"); + if (!pss.MaskGenAlgorithm.Algorithm.Equals(Asn1.Pkcs.PkcsObjectIdentifiers.IdMgf1)) + throw new CmsException("RSASSA-PSS signature parameters specified unknown MGF"); + + IDigest pssDigest = DigestUtilities.GetDigest(pss.HashAlgorithm.Algorithm); + int saltLength = pss.SaltLength.IntValueExact; + + // RFC 4055 3.1 + // The value MUST be 1, which represents the trailer field with hexadecimal value 0xBC + if (!Asn1.Pkcs.RsassaPssParameters.DefaultTrailerField.Equals(pss.TrailerField)) + throw new CmsException("RSASSA-PSS signature parameters must have trailerField of 1"); + + IAsymmetricBlockCipher rsa = new RsaBlindedEngine(); + + if (signedAttributeSet == null && calculatedDigest != null) + { + sig = PssSigner.CreateRawSigner(rsa, pssDigest, pssDigest, saltLength, PssSigner.TrailerImplicit); + } + else + { + sig = new PssSigner(rsa, pssDigest, saltLength); + } + } + catch (Exception e) + { + throw new CmsException("failed to set RSASSA-PSS signature parameters", e); + } + } + else + { + // TODO Probably too strong a check at the moment + // if (sigParams != null) + // throw new CmsException("unrecognised signature parameters provided"); + + string signatureName = digestName + "with" + Helper.GetEncryptionAlgName(this.EncryptionAlgOid); + + sig = Helper.GetSignatureInstance(signatureName); + + //sig = Helper.GetSignatureInstance(this.EncryptionAlgOid); + //sig = SignerUtilities.GetSigner(sigAlgOid); + } + + try + { + if (calculatedDigest != null) + { + resultDigest = calculatedDigest; + } + else + { + if (content != null) + { + content.Write(new DigestSink(digest)); + } + else if (signedAttributeSet == null) + { + // TODO Get rid of this exception and just treat content==null as empty not missing? + throw new CmsException("data not encapsulated in signature - use detached constructor."); + } + + resultDigest = DigestUtilities.DoFinal(digest); + } + } + catch (IOException e) + { + throw new CmsException("can't process mime object to create signature.", e); + } + + // RFC 3852 11.1 Check the content-type attribute is correct + { + Asn1Object validContentType = GetSingleValuedSignedAttribute( + CmsAttributes.ContentType, "content-type"); + if (validContentType == null) + { + if (!isCounterSignature && signedAttributeSet != null) + throw new CmsException("The content-type attribute type MUST be present whenever signed attributes are present in signed-data"); + } + else + { + if (isCounterSignature) + throw new CmsException("[For counter signatures,] the signedAttributes field MUST NOT contain a content-type attribute"); + + if (!(validContentType is DerObjectIdentifier)) + throw new CmsException("content-type attribute value not of ASN.1 type 'OBJECT IDENTIFIER'"); + + DerObjectIdentifier signedContentType = (DerObjectIdentifier)validContentType; + + if (!signedContentType.Equals(contentType)) + throw new CmsException("content-type attribute value does not match eContentType"); + } + } + + // RFC 3852 11.2 Check the message-digest attribute is correct + { + Asn1Object validMessageDigest = GetSingleValuedSignedAttribute( + CmsAttributes.MessageDigest, "message-digest"); + if (validMessageDigest == null) + { + if (signedAttributeSet != null) + throw new CmsException("the message-digest signed attribute type MUST be present when there are any signed attributes present"); + } + else + { + if (!(validMessageDigest is Asn1OctetString)) + { + throw new CmsException("message-digest attribute value not of ASN.1 type 'OCTET STRING'"); + } + + Asn1OctetString signedMessageDigest = (Asn1OctetString)validMessageDigest; + + if (!Arrays.AreEqual(resultDigest, signedMessageDigest.GetOctets())) + throw new CmsException("message-digest attribute value does not match calculated value"); + } + } + + // RFC 3852 11.4 Validate countersignature attribute(s) + { + Asn1.Cms.AttributeTable signedAttrTable = this.SignedAttributes; + if (signedAttrTable != null + && signedAttrTable.GetAll(CmsAttributes.CounterSignature).Count > 0) + { + throw new CmsException("A countersignature attribute MUST NOT be a signed attribute"); + } + + Asn1.Cms.AttributeTable unsignedAttrTable = this.UnsignedAttributes; + if (unsignedAttrTable != null) + { + foreach (Asn1.Cms.Attribute csAttr in unsignedAttrTable.GetAll(CmsAttributes.CounterSignature)) + { + if (csAttr.AttrValues.Count < 1) + throw new CmsException("A countersignature attribute MUST contain at least one AttributeValue"); + + // Note: We don't recursively validate the countersignature value + } + } + } + + try + { + sig.Init(false, key); + + if (signedAttributeSet == null) + { + if (calculatedDigest != null) + { + if (sig is PssSigner) + { + sig.BlockUpdate(resultDigest, 0, resultDigest.Length); + } + else + { + // need to decrypt signature and check message bytes + return VerifyDigest(resultDigest, key, this.GetSignature()); + } + } + else if (content != null) + { + try + { + // TODO Use raw signature of the hash value instead + content.Write(new SignerSink(sig)); + } + catch (SignatureException e) + { + throw new CmsStreamException("signature problem: " + e); + } + } + } + else + { + byte[] tmp = this.GetEncodedSignedAttributes(); + sig.BlockUpdate(tmp, 0, tmp.Length); + } + + return sig.VerifySignature(this.GetSignature()); + } + catch (InvalidKeyException e) + { + throw new CmsException("key not appropriate to signature in message.", e); + } + catch (IOException e) + { + throw new CmsException("can't process mime object to create signature.", e); + } + catch (SignatureException e) + { + throw new CmsException("invalid signature format in message: " + e.Message, e); + } + } + + private bool IsNull( + Asn1Encodable o) + { + return (o is Asn1Null) || (o == null); + } + + private DigestInfo DerDecode( + byte[] encoding) + { + if (encoding[0] != (int)(Asn1Tags.Constructed | Asn1Tags.Sequence)) + { + throw new IOException("not a digest info object"); + } + + DigestInfo digInfo = DigestInfo.GetInstance(Asn1Object.FromByteArray(encoding)); + + // length check to avoid Bleichenbacher vulnerability + + if (digInfo.GetEncoded().Length != encoding.Length) + { + throw new CmsException("malformed RSA signature"); + } + + return digInfo; + } + + private bool VerifyDigest( + byte[] digest, + AsymmetricKeyParameter key, + byte[] signature) + { + string algorithm = Helper.GetEncryptionAlgName(this.EncryptionAlgOid); + + try + { + if (algorithm.Equals("RSA")) + { + IBufferedCipher c = CmsEnvelopedHelper.Instance.CreateAsymmetricCipher("RSA/ECB/PKCS1Padding"); + + c.Init(false, key); + + byte[] decrypt = c.DoFinal(signature); + + DigestInfo digInfo = DerDecode(decrypt); + + if (!digInfo.AlgorithmID.Algorithm.Equals(digestAlgorithm.Algorithm)) + { + return false; + } + + if (!IsNull(digInfo.AlgorithmID.Parameters)) + { + return false; + } + + byte[] sigHash = digInfo.GetDigest(); + + return Arrays.ConstantTimeAreEqual(digest, sigHash); + } + else if (algorithm.Equals("DSA")) + { + ISigner sig = SignerUtilities.GetSigner("NONEwithDSA"); + + sig.Init(false, key); + + sig.BlockUpdate(digest, 0, digest.Length); + + return sig.VerifySignature(signature); + } + else + { + throw new CmsException("algorithm: " + algorithm + " not supported in base signatures."); + } + } + catch (SecurityUtilityException e) + { + throw e; + } + catch (GeneralSecurityException e) + { + throw new CmsException("Exception processing signature: " + e, e); + } + catch (IOException e) + { + throw new CmsException("Exception decoding signature: " + e, e); + } + } + + /** + * verify that the given public key successfully handles and confirms the + * signature associated with this signer. + */ + public bool Verify( + AsymmetricKeyParameter pubKey) + { + if (pubKey.IsPrivate) + throw new ArgumentException("Expected public key", "pubKey"); + + // Optional, but still need to validate if present + GetSigningTime(); + + return DoVerify(pubKey); + } + + /** + * verify that the given certificate successfully handles and confirms + * the signature associated with this signer and, if a signingTime + * attribute is available, that the certificate was valid at the time the + * signature was generated. + */ + public bool Verify( + X509Certificate cert) + { + Asn1.Cms.Time signingTime = GetSigningTime(); + if (signingTime != null) + { + cert.CheckValidity(signingTime.Date); + } + + return DoVerify(cert.GetPublicKey()); + } + + /** + * Return the base ASN.1 CMS structure that this object contains. + * + * @return an object containing a CMS SignerInfo structure. + */ + public SignerInfo ToSignerInfo() + { + return info; + } + + private Asn1Object GetSingleValuedSignedAttribute( + DerObjectIdentifier attrOID, string printableName) + { + + Asn1.Cms.AttributeTable unsignedAttrTable = this.UnsignedAttributes; + if (unsignedAttrTable != null + && unsignedAttrTable.GetAll(attrOID).Count > 0) + { + throw new CmsException("The " + printableName + + " attribute MUST NOT be an unsigned attribute"); + } + + Asn1.Cms.AttributeTable signedAttrTable = this.SignedAttributes; + if (signedAttrTable == null) + { + return null; + } + + Asn1EncodableVector v = signedAttrTable.GetAll(attrOID); + switch (v.Count) + { + case 0: + return null; + case 1: + Asn1.Cms.Attribute t = (Asn1.Cms.Attribute) v[0]; + Asn1Set attrValues = t.AttrValues; + + if (attrValues.Count != 1) + throw new CmsException("A " + printableName + + " attribute MUST have a single attribute value"); + + return attrValues[0].ToAsn1Object(); + default: + throw new CmsException("The SignedAttributes in a signerInfo MUST NOT include multiple instances of the " + + printableName + " attribute"); + } + } + + private Asn1.Cms.Time GetSigningTime() + { + Asn1Object validSigningTime = GetSingleValuedSignedAttribute( + CmsAttributes.SigningTime, "signing-time"); + + if (validSigningTime == null) + return null; + + try + { + return Asn1.Cms.Time.GetInstance(validSigningTime); + } + catch (ArgumentException) + { + throw new CmsException("signing-time attribute value not a valid 'Time' structure"); + } + } + + /** + * Return a signer information object with the passed in unsigned + * attributes replacing the ones that are current associated with + * the object passed in. + * + * @param signerInformation the signerInfo to be used as the basis. + * @param unsignedAttributes the unsigned attributes to add. + * @return a copy of the original SignerInformationObject with the changed attributes. + */ + public static SignerInformation ReplaceUnsignedAttributes( + SignerInformation signerInformation, + Asn1.Cms.AttributeTable unsignedAttributes) + { + SignerInfo sInfo = signerInformation.info; + Asn1Set unsignedAttr = null; + + if (unsignedAttributes != null) + { + unsignedAttr = new DerSet(unsignedAttributes.ToAsn1EncodableVector()); + } + + return new SignerInformation( + new SignerInfo( + sInfo.SignerID, + sInfo.DigestAlgorithm, + sInfo.AuthenticatedAttributes, + sInfo.DigestEncryptionAlgorithm, + sInfo.EncryptedDigest, + unsignedAttr), + signerInformation.contentType, + signerInformation.content, + null); + } + + /** + * Return a signer information object with passed in SignerInformationStore representing counter + * signatures attached as an unsigned attribute. + * + * @param signerInformation the signerInfo to be used as the basis. + * @param counterSigners signer info objects carrying counter signature. + * @return a copy of the original SignerInformationObject with the changed attributes. + */ + public static SignerInformation AddCounterSigners( + SignerInformation signerInformation, + SignerInformationStore counterSigners) + { + // TODO Perform checks from RFC 3852 11.4 + + SignerInfo sInfo = signerInformation.info; + Asn1.Cms.AttributeTable unsignedAttr = signerInformation.UnsignedAttributes; + Asn1EncodableVector v; + + if (unsignedAttr != null) + { + v = unsignedAttr.ToAsn1EncodableVector(); + } + else + { + v = new Asn1EncodableVector(); + } + + Asn1EncodableVector sigs = new Asn1EncodableVector(); + + foreach (SignerInformation sigInf in counterSigners.GetSigners()) + { + sigs.Add(sigInf.ToSignerInfo()); + } + + v.Add(new Asn1.Cms.Attribute(CmsAttributes.CounterSignature, new DerSet(sigs))); + + return new SignerInformation( + new SignerInfo( + sInfo.SignerID, + sInfo.DigestAlgorithm, + sInfo.AuthenticatedAttributes, + sInfo.DigestEncryptionAlgorithm, + sInfo.EncryptedDigest, + new DerSet(v)), + signerInformation.contentType, + signerInformation.content, + null); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/SignerInformation.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/SignerInformation.cs.meta new file mode 100644 index 0000000..d3a519e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/SignerInformation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: eb39b55011abf7c4a88a9cb9e5d210bf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/SignerInformationStore.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/SignerInformationStore.cs new file mode 100644 index 0000000..2794086 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/SignerInformationStore.cs @@ -0,0 +1,95 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Cms +{ + public class SignerInformationStore + { + private readonly IList all; //ArrayList[SignerInformation] + private readonly IDictionary table = Platform.CreateHashtable(); // Hashtable[SignerID, ArrayList[SignerInformation]] + + /** + * Create a store containing a single SignerInformation object. + * + * @param signerInfo the signer information to contain. + */ + public SignerInformationStore( + SignerInformation signerInfo) + { + this.all = Platform.CreateArrayList(1); + this.all.Add(signerInfo); + + SignerID sid = signerInfo.SignerID; + + table[sid] = all; + } + + /** + * Create a store containing a collection of SignerInformation objects. + * + * @param signerInfos a collection signer information objects to contain. + */ + public SignerInformationStore( + ICollection signerInfos) + { + foreach (SignerInformation signer in signerInfos) + { + SignerID sid = signer.SignerID; + IList list = (IList)table[sid]; + + if (list == null) + { + table[sid] = list = Platform.CreateArrayList(1); + } + + list.Add(signer); + } + + this.all = Platform.CreateArrayList(signerInfos); + } + + /** + * Return the first SignerInformation object that matches the + * passed in selector. Null if there are no matches. + * + * @param selector to identify a signer + * @return a single SignerInformation object. Null if none matches. + */ + public SignerInformation GetFirstSigner( + SignerID selector) + { + IList list = (IList) table[selector]; + + return list == null ? null : (SignerInformation) list[0]; + } + + /// The number of signers in the collection. + public int Count + { + get { return all.Count; } + } + + /// An ICollection of all signers in the collection + public ICollection GetSigners() + { + return Platform.CreateArrayList(all); + } + + /** + * Return possible empty collection with signers matching the passed in SignerID + * + * @param selector a signer id to select against. + * @return a collection of SignerInformation objects. + */ + public ICollection GetSigners( + SignerID selector) + { + IList list = (IList) table[selector]; + + return list == null ? Platform.CreateArrayList() : Platform.CreateArrayList(list); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/SignerInformationStore.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/SignerInformationStore.cs.meta new file mode 100644 index 0000000..5576008 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/SignerInformationStore.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6f34403bdae4e3b4ba0f80bf6a86584d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/SimpleAttributeTableGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/SimpleAttributeTableGenerator.cs new file mode 100644 index 0000000..b3df21c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/SimpleAttributeTableGenerator.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1.Cms; + +namespace Org.BouncyCastle.Cms +{ + /** + * Basic generator that just returns a preconstructed attribute table + */ + public class SimpleAttributeTableGenerator + : CmsAttributeTableGenerator + { + private readonly AttributeTable attributes; + + public SimpleAttributeTableGenerator( + AttributeTable attributes) + { + this.attributes = attributes; + } + + public virtual AttributeTable GetAttributes( + IDictionary parameters) + { + return attributes; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/SimpleAttributeTableGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/SimpleAttributeTableGenerator.cs.meta new file mode 100644 index 0000000..b9303c7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/cms/SimpleAttributeTableGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4d1bcca09190da24c8c69563e2f1f20d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf.meta new file mode 100644 index 0000000..18453bd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5d7d677df150fbb4983e209136510f86 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/AuthenticatorControl.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/AuthenticatorControl.cs new file mode 100644 index 0000000..fc546ed --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/AuthenticatorControl.cs @@ -0,0 +1,52 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Crmf; + +namespace Org.BouncyCastle.Crmf +{ + /// + /// Carrier for an authenticator control. + /// + public class AuthenticatorControl + : IControl + { + private static readonly DerObjectIdentifier type = CrmfObjectIdentifiers.id_regCtrl_authenticator; + + private readonly DerUtf8String token; + + /// + /// Basic constructor - build from a UTF-8 string representing the token. + /// + /// UTF-8 string representing the token. + public AuthenticatorControl(DerUtf8String token) + { + this.token = token; + } + + /// + /// Basic constructor - build from a string representing the token. + /// + /// string representing the token. + public AuthenticatorControl(string token) + { + this.token = new DerUtf8String(token); + } + + /// + /// Return the type of this control. + /// + public DerObjectIdentifier Type + { + get { return type; } + } + + /// + /// Return the token associated with this control (a UTF8String). + /// + public Asn1Encodable Value + { + get { return token; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/AuthenticatorControl.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/AuthenticatorControl.cs.meta new file mode 100644 index 0000000..d5bee96 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/AuthenticatorControl.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f6e0fe47196975e43900d20ae6d04f9b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/CertificateRequestMessage.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/CertificateRequestMessage.cs new file mode 100644 index 0000000..c733eec --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/CertificateRequestMessage.cs @@ -0,0 +1,229 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Crmf; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Operators; + +namespace Org.BouncyCastle.Crmf +{ + public class CertificateRequestMessage + { + public static readonly int popRaVerified = Org.BouncyCastle.Asn1.Crmf.ProofOfPossession.TYPE_RA_VERIFIED; + public static readonly int popSigningKey = Org.BouncyCastle.Asn1.Crmf.ProofOfPossession.TYPE_SIGNING_KEY; + public static readonly int popKeyEncipherment = Org.BouncyCastle.Asn1.Crmf.ProofOfPossession.TYPE_KEY_ENCIPHERMENT; + public static readonly int popKeyAgreement = Org.BouncyCastle.Asn1.Crmf.ProofOfPossession.TYPE_KEY_AGREEMENT; + + private readonly CertReqMsg certReqMsg; + private readonly Controls controls; + + private static CertReqMsg ParseBytes(byte[] encoding) + { + return CertReqMsg.GetInstance(encoding); + } + + /// + /// Create a CertificateRequestMessage from the passed in bytes. + /// + /// BER/DER encoding of the CertReqMsg structure. + public CertificateRequestMessage(byte[] encoded) + : this(CertReqMsg.GetInstance(encoded)) + { + } + + public CertificateRequestMessage(CertReqMsg certReqMsg) + { + this.certReqMsg = certReqMsg; + this.controls = certReqMsg.CertReq.Controls; + } + + /// + /// Return the underlying ASN.1 object defining this CertificateRequestMessage object. + /// + /// A CertReqMsg + public CertReqMsg ToAsn1Structure() + { + return certReqMsg; + } + + /// + /// Return the certificate template contained in this message. + /// + /// a CertTemplate structure. + public CertTemplate GetCertTemplate() + { + return this.certReqMsg.CertReq.CertTemplate; + } + + /// + /// Return whether or not this request has control values associated with it. + /// + /// true if there are control values present, false otherwise. + public bool HasControls + { + get { return controls != null; } + } + + /// + /// Return whether or not this request has a specific type of control value. + /// + /// the type OID for the control value we are checking for. + /// true if a control value of type is present, false otherwise. + public bool HasControl(DerObjectIdentifier objectIdentifier) + { + return FindControl(objectIdentifier) != null; + } + + /// + /// Return a control value of the specified type. + /// + /// the type OID for the control value we are checking for. + /// the control value if present, null otherwise. + public IControl GetControl(DerObjectIdentifier type) + { + AttributeTypeAndValue found = FindControl(type); + if (found != null) + { + if (found.Type.Equals(CrmfObjectIdentifiers.id_regCtrl_pkiArchiveOptions)) + { + return new PkiArchiveControl(PkiArchiveOptions.GetInstance(found.Value)); + } + + if (found.Type.Equals(CrmfObjectIdentifiers.id_regCtrl_regToken)) + { + return new RegTokenControl(DerUtf8String.GetInstance(found.Value)); + } + + if (found.Type.Equals(CrmfObjectIdentifiers.id_regCtrl_authenticator)) + { + return new AuthenticatorControl(DerUtf8String.GetInstance(found.Value)); + } + } + return null; + } + + public AttributeTypeAndValue FindControl(DerObjectIdentifier type) + { + if (controls == null) + { + return null; + } + + AttributeTypeAndValue[] tAndV = controls.ToAttributeTypeAndValueArray(); + AttributeTypeAndValue found = null; + + for (int i = 0; i < tAndV.Length; i++) + { + if (tAndV[i].Type.Equals(type)) + { + found = tAndV[i]; + break; + } + } + + return found; + } + + /// + /// Return whether or not this request message has a proof-of-possession field in it. + /// + /// true if proof-of-possession is present, false otherwise. + public bool HasProofOfPossession + { + get { return certReqMsg.Popo != null; } + } + + /// + /// Return the type of the proof-of-possession this request message provides. + /// + /// one of: popRaVerified, popSigningKey, popKeyEncipherment, popKeyAgreement + public int ProofOfPossession + { + get { return certReqMsg.Popo.Type; } + } + + /// + /// Return whether or not the proof-of-possession (POP) is of the type popSigningKey and + /// it has a public key MAC associated with it. + /// + /// true if POP is popSigningKey and a PKMAC is present, false otherwise. + public bool HasSigningKeyProofOfPossessionWithPkMac + { + get + { + ProofOfPossession pop = certReqMsg.Popo; + + if (pop.Type == popSigningKey) + { + PopoSigningKey popoSign = PopoSigningKey.GetInstance(pop.Object); + + return popoSign.PoposkInput.PublicKeyMac != null; + } + + return false; + } + } + + /// + /// Return whether or not a signing key proof-of-possession (POP) is valid. + /// + /// a provider that can produce content verifiers for the signature contained in this POP. + /// true if the POP is valid, false otherwise. + /// if there is a problem in verification or content verifier creation. + /// if POP not appropriate. + public bool IsValidSigningKeyPop(IVerifierFactoryProvider verifierProvider) + { + ProofOfPossession pop = certReqMsg.Popo; + if (pop.Type == popSigningKey) + { + PopoSigningKey popoSign = PopoSigningKey.GetInstance(pop.Object); + if (popoSign.PoposkInput != null && popoSign.PoposkInput.PublicKeyMac != null) + { + throw new InvalidOperationException("verification requires password check"); + } + return verifySignature(verifierProvider, popoSign); + } + + throw new InvalidOperationException("not Signing Key type of proof of possession"); + } + + private bool verifySignature(IVerifierFactoryProvider verifierFactoryProvider, PopoSigningKey signKey) + { + IVerifierFactory verifer; + IStreamCalculator calculator; + try + { + verifer = verifierFactoryProvider.CreateVerifierFactory(signKey.AlgorithmIdentifier); + calculator = verifer.CreateCalculator(); + } + catch (Exception ex) + { + throw new CrmfException("unable to create verifier: " + ex.Message, ex); + } + + if (signKey.PoposkInput != null) + { + byte[] b = signKey.GetDerEncoded(); + calculator.Stream.Write(b, 0, b.Length); + } + else + { + byte[] b = certReqMsg.CertReq.GetDerEncoded(); + calculator.Stream.Write(b, 0, b.Length); + } + + DefaultVerifierResult result = (DefaultVerifierResult)calculator.GetResult(); + + return result.IsVerified(signKey.Signature.GetBytes()); + } + + /// + /// Return the ASN.1 encoding of the certReqMsg we wrap. + /// + /// a byte array containing the binary encoding of the certReqMsg. + public byte[] GetEncoded() + { + return certReqMsg.GetEncoded(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/CertificateRequestMessage.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/CertificateRequestMessage.cs.meta new file mode 100644 index 0000000..cf57af2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/CertificateRequestMessage.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9dc66389295a5cd43838b608eb1f4357 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/CertificateRequestMessageBuilder.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/CertificateRequestMessageBuilder.cs new file mode 100644 index 0000000..88d1d87 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/CertificateRequestMessageBuilder.cs @@ -0,0 +1,263 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Crmf; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Operators; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crmf +{ + public class CertificateRequestMessageBuilder + { + private readonly BigInteger _certReqId; + private X509ExtensionsGenerator _extGenerator; + private CertTemplateBuilder _templateBuilder; + private IList _controls = Platform.CreateArrayList(); + private ISignatureFactory _popSigner; + private PKMacBuilder _pkMacBuilder; + private char[] _password; + private GeneralName _sender; + private int _popoType = ProofOfPossession.TYPE_KEY_ENCIPHERMENT; + private PopoPrivKey _popoPrivKey; + private Asn1Null _popRaVerified; + private PKMacValue _agreeMac; + + public CertificateRequestMessageBuilder(BigInteger certReqId) + { + this._certReqId = certReqId; + this._extGenerator = new X509ExtensionsGenerator(); + this._templateBuilder = new CertTemplateBuilder(); + } + + public CertificateRequestMessageBuilder SetPublicKey(SubjectPublicKeyInfo publicKeyInfo) + { + if (publicKeyInfo != null) + { + _templateBuilder.SetPublicKey(publicKeyInfo); + } + + return this; + } + + public CertificateRequestMessageBuilder SetIssuer(X509Name issuer) + { + if (issuer != null) + { + _templateBuilder.SetIssuer(issuer); + } + + return this; + } + + public CertificateRequestMessageBuilder SetSubject(X509Name subject) + { + if (subject != null) + { + _templateBuilder.SetSubject(subject); + } + + return this; + } + + public CertificateRequestMessageBuilder SetSerialNumber(BigInteger serialNumber) + { + if (serialNumber != null) + { + _templateBuilder.SetSerialNumber(new DerInteger(serialNumber)); + } + + return this; + } + + public CertificateRequestMessageBuilder SetValidity(Time notBefore, Time notAfter) + { + _templateBuilder.SetValidity(new OptionalValidity(notBefore, notAfter)); + return this; + } + + public CertificateRequestMessageBuilder AddExtension(DerObjectIdentifier oid, bool critical, + Asn1Encodable value) + { + _extGenerator.AddExtension(oid, critical, value); + return this; + } + + public CertificateRequestMessageBuilder AddExtension(DerObjectIdentifier oid, bool critical, + byte[] value) + { + _extGenerator.AddExtension(oid, critical, value); + return this; + } + + public CertificateRequestMessageBuilder AddControl(IControl control) + { + _controls.Add(control); + return this; + } + + public CertificateRequestMessageBuilder SetProofOfPossessionSignKeySigner(ISignatureFactory popoSignatureFactory) + { + if (_popoPrivKey != null || _popRaVerified != null || _agreeMac != null) + { + throw new InvalidOperationException("only one proof of possession is allowed."); + } + + this._popSigner = popoSignatureFactory; + + return this; + } + + public CertificateRequestMessageBuilder SetProofOfPossessionSubsequentMessage(SubsequentMessage msg) + { + if (_popoPrivKey != null || _popRaVerified != null || _agreeMac != null) + { + throw new InvalidOperationException("only one proof of possession is allowed."); + } + + this._popoType = ProofOfPossession.TYPE_KEY_ENCIPHERMENT; + this._popoPrivKey = new PopoPrivKey(msg); + + return this; + } + + + public CertificateRequestMessageBuilder SetProofOfPossessionSubsequentMessage(int type, SubsequentMessage msg) + { + if (_popoPrivKey != null || _popRaVerified != null || _agreeMac != null) + { + throw new InvalidOperationException("only one proof of possession is allowed."); + } + + if (type != ProofOfPossession.TYPE_KEY_ENCIPHERMENT && type != ProofOfPossession.TYPE_KEY_AGREEMENT) + { + throw new ArgumentException("type must be ProofOfPossession.TYPE_KEY_ENCIPHERMENT || ProofOfPossession.TYPE_KEY_AGREEMENT"); + } + + this._popoType = type; + this._popoPrivKey = new PopoPrivKey(msg); + return this; + } + + public CertificateRequestMessageBuilder SetProofOfPossessionAgreeMac(PKMacValue macValue) + { + if (_popSigner != null || _popRaVerified != null || _popoPrivKey != null) + { + throw new InvalidOperationException("only one proof of possession allowed"); + } + + this._agreeMac = macValue; + return this; + } + + public CertificateRequestMessageBuilder SetProofOfPossessionRaVerified() + { + if (_popSigner != null || _popoPrivKey != null) + { + throw new InvalidOperationException("only one proof of possession allowed"); + } + + this._popRaVerified = DerNull.Instance; + + return this; + } + + public CertificateRequestMessageBuilder SetAuthInfoPKMAC(PKMacBuilder pkmacFactory, char[] password) + { + this._pkMacBuilder = pkmacFactory; + this._password = password; + + return this; + } + + public CertificateRequestMessageBuilder SetAuthInfoSender(X509Name sender) + { + return SetAuthInfoSender(new GeneralName(sender)); + } + + public CertificateRequestMessageBuilder SetAuthInfoSender(GeneralName sender) + { + this._sender = sender; + return this; + } + + public CertificateRequestMessage Build() + { + Asn1EncodableVector v = new Asn1EncodableVector(new DerInteger(this._certReqId)); + + if (!this._extGenerator.IsEmpty) + { + this._templateBuilder.SetExtensions(_extGenerator.Generate()); + } + + v.Add(_templateBuilder.Build()); + + if (_controls.Count > 0) + { + Asn1EncodableVector controlV = new Asn1EncodableVector(); + + foreach (object item in _controls) + { + IControl control = (IControl)item; + controlV.Add(new AttributeTypeAndValue(control.Type, control.Value)); + } + + v.Add(new DerSequence(controlV)); + } + + CertRequest request = CertRequest.GetInstance(new DerSequence(v)); + + v = new Asn1EncodableVector(request); + + if (_popSigner != null) + { + CertTemplate template = request.CertTemplate; + + if (template.Subject == null || template.PublicKey == null) + { + SubjectPublicKeyInfo pubKeyInfo = request.CertTemplate.PublicKey; + + ProofOfPossessionSigningKeyBuilder builder = new ProofOfPossessionSigningKeyBuilder(pubKeyInfo); + + if (_sender != null) + { + builder.SetSender(_sender); + } + else + { + //PKMACValueGenerator pkmacGenerator = new PKMACValueGenerator(_pkmacBuilder); + + builder.SetPublicKeyMac(_pkMacBuilder, _password); + } + + v.Add(new ProofOfPossession(builder.Build(_popSigner))); + } + else + { + ProofOfPossessionSigningKeyBuilder builder = new ProofOfPossessionSigningKeyBuilder(request); + + v.Add(new ProofOfPossession(builder.Build(_popSigner))); + } + } + else if (_popoPrivKey != null) + { + v.Add(new ProofOfPossession(_popoType, _popoPrivKey)); + } + else if (_agreeMac != null) + { + v.Add(new ProofOfPossession(ProofOfPossession.TYPE_KEY_AGREEMENT, + PopoPrivKey.GetInstance(new DerTaggedObject(false, PopoPrivKey.agreeMAC, _agreeMac), true))); + + } + else if (_popRaVerified != null) + { + v.Add(new ProofOfPossession()); + } + + return new CertificateRequestMessage(CertReqMsg.GetInstance(new DerSequence(v))); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/CertificateRequestMessageBuilder.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/CertificateRequestMessageBuilder.cs.meta new file mode 100644 index 0000000..3ec8a4a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/CertificateRequestMessageBuilder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8f3bc56466165734dbf777e39618d507 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/CrmfException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/CrmfException.cs new file mode 100644 index 0000000..5ae13a0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/CrmfException.cs @@ -0,0 +1,22 @@ +using System; + +namespace Org.BouncyCastle.Crmf +{ + public class CrmfException + : Exception + { + public CrmfException() + { + } + + public CrmfException(string message) + : base(message) + { + } + + public CrmfException(string message, Exception innerException) + : base(message, innerException) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/CrmfException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/CrmfException.cs.meta new file mode 100644 index 0000000..93d2bdf --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/CrmfException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9547b3d117c521f4a98345476cf862b0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/DefaultPKMacPrimitivesProvider.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/DefaultPKMacPrimitivesProvider.cs new file mode 100644 index 0000000..01e196e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/DefaultPKMacPrimitivesProvider.cs @@ -0,0 +1,22 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crmf +{ + public class DefaultPKMacPrimitivesProvider + : IPKMacPrimitivesProvider + { + public IDigest CreateDigest(AlgorithmIdentifier digestAlg) + { + return DigestUtilities.GetDigest(digestAlg.Algorithm); + } + + public IMac CreateMac(AlgorithmIdentifier macAlg) + { + return MacUtilities.GetMac(macAlg.Algorithm); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/DefaultPKMacPrimitivesProvider.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/DefaultPKMacPrimitivesProvider.cs.meta new file mode 100644 index 0000000..d118444 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/DefaultPKMacPrimitivesProvider.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b421853ef05276d4fbfc318ac0c6bbb5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/EncryptedValueBuilder.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/EncryptedValueBuilder.cs new file mode 100644 index 0000000..d958969 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/EncryptedValueBuilder.cs @@ -0,0 +1,161 @@ +using System; +using System.Collections; +using System.IO; +using System.Text; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Crmf; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Pkcs; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.Crmf +{ + public class EncryptedValueBuilder + { + private readonly IKeyWrapper wrapper; + private readonly ICipherBuilderWithKey encryptor; + private readonly IEncryptedValuePadder padder; + + /// + /// Create a builder that makes EncryptedValue structures. + /// + /// wrapper a wrapper for key used to encrypt the actual data contained in the EncryptedValue. + /// encryptor an output encryptor to encrypt the actual data contained in the EncryptedValue. + /// + public EncryptedValueBuilder(IKeyWrapper wrapper, ICipherBuilderWithKey encryptor) + : this(wrapper, encryptor, null) + { + } + + /// + /// Create a builder that makes EncryptedValue structures with fixed length blocks padded using the passed in padder. + /// + /// a wrapper for key used to encrypt the actual data contained in the EncryptedValue. + /// encryptor an output encryptor to encrypt the actual data contained in the EncryptedValue. + /// padder a padder to ensure that the EncryptedValue created will always be a constant length. + /// + public EncryptedValueBuilder(IKeyWrapper wrapper, ICipherBuilderWithKey encryptor, IEncryptedValuePadder padder) + { + this.wrapper = wrapper; + this.encryptor = encryptor; + this.padder = padder; + } + + /// + /// Build an EncryptedValue structure containing the passed in pass phrase. + /// + /// a revocation pass phrase. + ///an EncryptedValue containing the encrypted pass phrase. + /// + public EncryptedValue Build(char[] revocationPassphrase) + { + return EncryptData(PadData(Strings.ToUtf8ByteArray(revocationPassphrase))); + } + + /// + /// Build an EncryptedValue structure containing the certificate contained in + /// the passed in holder. + /// + /// a holder containing a certificate. + /// an EncryptedValue containing the encrypted certificate. + /// on a failure to encrypt the data, or wrap the symmetric key for this value. + /// + public EncryptedValue Build(X509Certificate holder) + { + try + { + return EncryptData(PadData(holder.GetEncoded())); + } + catch (IOException e) + { + throw new CrmfException("cannot encode certificate: " + e.Message, e); + } + } + + /// + /// Build an EncryptedValue structure containing the private key contained in + /// the passed info structure. + /// + /// a PKCS#8 private key info structure. + /// an EncryptedValue containing an EncryptedPrivateKeyInfo structure. + /// on a failure to encrypt the data, or wrap the symmetric key for this value. + /// + public EncryptedValue Build(PrivateKeyInfo privateKeyInfo) + { + Pkcs8EncryptedPrivateKeyInfoBuilder encInfoBldr = new Pkcs8EncryptedPrivateKeyInfoBuilder(privateKeyInfo); + + AlgorithmIdentifier intendedAlg = privateKeyInfo.PrivateKeyAlgorithm; + AlgorithmIdentifier symmAlg = (AlgorithmIdentifier)encryptor.AlgorithmDetails; + DerBitString encSymmKey; + + try + { + Pkcs8EncryptedPrivateKeyInfo encInfo = encInfoBldr.Build(encryptor); + + encSymmKey = new DerBitString(wrapper.Wrap(((KeyParameter)encryptor.Key).GetKey()).Collect()); + + AlgorithmIdentifier keyAlg = (AlgorithmIdentifier)wrapper.AlgorithmDetails; + Asn1OctetString valueHint = null; + + return new EncryptedValue(intendedAlg, symmAlg, encSymmKey, keyAlg, valueHint, new DerBitString(encInfo.GetEncryptedData())); + } + catch (Exception e) + { + throw new CrmfException("cannot wrap key: " + e.Message, e); + } + } + + private EncryptedValue EncryptData(byte[] data) + { + MemoryOutputStream bOut = new MemoryOutputStream(); + Stream eOut = encryptor.BuildCipher(bOut).Stream; + + try + { + eOut.Write(data, 0, data.Length); + Platform.Dispose(eOut); + } + catch (IOException e) + { + throw new CrmfException("cannot process data: " + e.Message, e); + } + + AlgorithmIdentifier intendedAlg = null; + AlgorithmIdentifier symmAlg = (AlgorithmIdentifier)encryptor.AlgorithmDetails; + + DerBitString encSymmKey; + try + { + encSymmKey = new DerBitString(wrapper.Wrap(((KeyParameter)encryptor.Key).GetKey()).Collect()); + } + catch (Exception e) + { + throw new CrmfException("cannot wrap key: " + e.Message, e); + } + + AlgorithmIdentifier keyAlg = (AlgorithmIdentifier)wrapper.AlgorithmDetails; + Asn1OctetString valueHint = null; + DerBitString encValue = new DerBitString(bOut.ToArray()); + + return new EncryptedValue(intendedAlg, symmAlg, encSymmKey, keyAlg, valueHint, encValue); + } + + private byte[] PadData(byte[] data) + { + if (padder != null) + { + return padder.GetPaddedData(data); + } + + return data; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/EncryptedValueBuilder.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/EncryptedValueBuilder.cs.meta new file mode 100644 index 0000000..8a58254 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/EncryptedValueBuilder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 38384f60f1061bf4c88720bc40984f7d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/IControl.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/IControl.cs new file mode 100644 index 0000000..9a29ac1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/IControl.cs @@ -0,0 +1,22 @@ +using System; + +using Org.BouncyCastle.Asn1; + +namespace Org.BouncyCastle.Crmf +{ + /// + /// Generic interface for a CertificateRequestMessage control value. + /// + public interface IControl + { + /// + /// Return the type of this control. + /// + DerObjectIdentifier Type { get; } + + /// + /// Return the value contained in this control object. + /// + Asn1Encodable Value { get; } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/IControl.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/IControl.cs.meta new file mode 100644 index 0000000..54e3777 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/IControl.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 306f6c7c99200b046b4e88657332743a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/IEncryptedValuePadder.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/IEncryptedValuePadder.cs new file mode 100644 index 0000000..b898614 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/IEncryptedValuePadder.cs @@ -0,0 +1,27 @@ +using System; + +namespace Org.BouncyCastle.Crmf +{ + /// + /// An encrypted value padder is used to make sure that prior to a value been + /// encrypted the data is padded to a standard length. + /// + public interface IEncryptedValuePadder + { + /// + /// Return a byte array of padded data. + /// + /// the data to be padded. + /// a padded byte array containing data. + /// + byte[] GetPaddedData(byte[] data); + + /// + /// Return a byte array of with padding removed. + /// + /// the data to be padded. + /// an array containing the original unpadded data. + /// + byte[] GetUnpaddedData(byte[] paddedData); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/IEncryptedValuePadder.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/IEncryptedValuePadder.cs.meta new file mode 100644 index 0000000..f1fc2da --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/IEncryptedValuePadder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bf8267cb76f4bc84582239aa1ccdcd81 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/IPKMacPrimitivesProvider.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/IPKMacPrimitivesProvider.cs new file mode 100644 index 0000000..08f6a62 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/IPKMacPrimitivesProvider.cs @@ -0,0 +1,14 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; + +namespace Org.BouncyCastle.Crmf +{ + public interface IPKMacPrimitivesProvider + { + IDigest CreateDigest(AlgorithmIdentifier digestAlg); + + IMac CreateMac(AlgorithmIdentifier macAlg); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/IPKMacPrimitivesProvider.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/IPKMacPrimitivesProvider.cs.meta new file mode 100644 index 0000000..9650501 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/IPKMacPrimitivesProvider.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a6a0a355f803f7448b457ce8ea0fee4e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/PKMacBuilder.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/PKMacBuilder.cs new file mode 100644 index 0000000..156936e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/PKMacBuilder.cs @@ -0,0 +1,280 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cmp; +using Org.BouncyCastle.Asn1.Iana; +using Org.BouncyCastle.Asn1.Oiw; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.IO; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crmf +{ + internal class PKMacStreamCalculator + : IStreamCalculator + { + private readonly MacSink _stream; + + public PKMacStreamCalculator(IMac mac) + { + _stream = new MacSink(mac); + } + + public Stream Stream + { + get { return _stream; } + } + + public object GetResult() + { + return new DefaultPKMacResult(_stream.Mac); + } + } + + internal class PKMacFactory + : IMacFactory + { + protected readonly PbmParameter parameters; + private readonly byte[] key; + + public PKMacFactory(byte[] key, PbmParameter parameters) + { + this.key = Arrays.Clone(key); + this.parameters = parameters; + } + + public virtual object AlgorithmDetails + { + get { return new AlgorithmIdentifier(CmpObjectIdentifiers.passwordBasedMac, parameters); } + } + + public virtual IStreamCalculator CreateCalculator() + { + IMac mac = MacUtilities.GetMac(parameters.Mac.Algorithm); + mac.Init(new KeyParameter(key)); + return new PKMacStreamCalculator(mac); + } + } + + internal class DefaultPKMacResult + : IBlockResult + { + private readonly IMac mac; + + public DefaultPKMacResult(IMac mac) + { + this.mac = mac; + } + + public byte[] Collect() + { + byte[] res = new byte[mac.GetMacSize()]; + mac.DoFinal(res, 0); + return res; + } + + public int Collect(byte[] sig, int sigOff) + { + byte[] signature = Collect(); + signature.CopyTo(sig, sigOff); + return signature.Length; + } + } + + public class PKMacBuilder + { + private AlgorithmIdentifier owf; + private AlgorithmIdentifier mac; + private IPKMacPrimitivesProvider provider; + private SecureRandom random; + private PbmParameter parameters; + private int iterationCount; + private int saltLength = 20; + private int maxIterations; + + /// + /// Default, IterationCount = 1000, OIW=IdSha1, Mac=HmacSHA1 + /// + public PKMacBuilder() : + this(new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1), 1000, new AlgorithmIdentifier(IanaObjectIdentifiers.HmacSha1, DerNull.Instance), new DefaultPKMacPrimitivesProvider()) + { + } + + /// + /// Defaults with IPKMacPrimitivesProvider + /// + /// + public PKMacBuilder(IPKMacPrimitivesProvider provider) : + this(new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1), 1000, new AlgorithmIdentifier(IanaObjectIdentifiers.HmacSha1, DerNull.Instance), provider) + { + } + + /// + /// Create. + /// + /// The Mac provider + /// Digest Algorithm Id + /// Mac Algorithm Id + public PKMacBuilder(IPKMacPrimitivesProvider provider, AlgorithmIdentifier digestAlgorithmIdentifier, AlgorithmIdentifier macAlgorithmIdentifier) : + this(digestAlgorithmIdentifier, 1000, macAlgorithmIdentifier, provider) + { + } + + /// + /// Create a PKMAC builder enforcing a ceiling on the maximum iteration count. + /// + /// supporting calculator + /// max allowable value for iteration count. + public PKMacBuilder(IPKMacPrimitivesProvider provider, int maxIterations) + { + this.provider = provider; + this.maxIterations = maxIterations; + } + + private PKMacBuilder(AlgorithmIdentifier digestAlgorithmIdentifier, int iterationCount, AlgorithmIdentifier macAlgorithmIdentifier, IPKMacPrimitivesProvider provider) + { + this.iterationCount = iterationCount; + this.mac = macAlgorithmIdentifier; + this.owf = digestAlgorithmIdentifier; + this.provider = provider; + } + + /** + * Set the salt length in octets. + * + * @param saltLength length in octets of the salt to be generated. + * @return the generator + */ + public PKMacBuilder SetSaltLength(int saltLength) + { + if (saltLength < 8) + throw new ArgumentException("salt length must be at least 8 bytes"); + + this.saltLength = saltLength; + + return this; + } + + /// + /// Set the iteration count. + /// + /// the iteration count. + /// this + /// if iteration count is less than 100 + public PKMacBuilder SetIterationCount(int iterationCount) + { + if (iterationCount < 100) + throw new ArgumentException("iteration count must be at least 100"); + + CheckIterationCountCeiling(iterationCount); + + this.iterationCount = iterationCount; + + return this; + } + + /// + /// Set PbmParameters + /// + /// The parameters. + /// this + public PKMacBuilder SetParameters(PbmParameter parameters) + { + CheckIterationCountCeiling(parameters.IterationCount.IntValueExact); + + this.parameters = parameters; + + return this; + } + + /// + /// The Secure random + /// + /// The random. + /// this + public PKMacBuilder SetSecureRandom(SecureRandom random) + { + this.random = random; + + return this; + } + + /// + /// Build an IMacFactory. + /// + /// The password. + /// IMacFactory + public IMacFactory Build(char[] password) + { + if (parameters != null) + return GenCalculator(parameters, password); + + byte[] salt = new byte[saltLength]; + + if (random == null) + { + this.random = new SecureRandom(); + } + + random.NextBytes(salt); + + return GenCalculator(new PbmParameter(salt, owf, iterationCount, mac), password); + } + + private void CheckIterationCountCeiling(int iterationCount) + { + if (maxIterations > 0 && iterationCount > maxIterations) + throw new ArgumentException("iteration count exceeds limit (" + iterationCount + " > " + maxIterations + ")"); + } + + private IMacFactory GenCalculator(PbmParameter parameters, char[] password) + { + // From RFC 4211 + // + // 1. Generate a random salt value S + // + // 2. Append the salt to the pw. K = pw || salt. + // + // 3. Hash the value of K. K = HASH(K) + // + // 4. Iter = Iter - 1. If Iter is greater than zero. Goto step 3. + // + // 5. Compute an HMAC as documented in [HMAC]. + // + // MAC = HASH( K XOR opad, HASH( K XOR ipad, data) ) + // + // Where opad and ipad are defined in [HMAC]. + byte[] pw = Strings.ToUtf8ByteArray(password); + byte[] salt = parameters.Salt.GetOctets(); + byte[] K = new byte[pw.Length + salt.Length]; + + Array.Copy(pw, 0, K, 0, pw.Length); + Array.Copy(salt, 0, K, pw.Length, salt.Length); + + IDigest digest = provider.CreateDigest(parameters.Owf); + + int iter = parameters.IterationCount.IntValueExact; + + digest.BlockUpdate(K, 0, K.Length); + + K = new byte[digest.GetDigestSize()]; + + digest.DoFinal(K, 0); + + while (--iter > 0) + { + digest.BlockUpdate(K, 0, K.Length); + + digest.DoFinal(K, 0); + } + + byte[] key = K; + + return new PKMacFactory(key, parameters); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/PKMacBuilder.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/PKMacBuilder.cs.meta new file mode 100644 index 0000000..6ceabbb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/PKMacBuilder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: af880e89041ffe5468329e991001df22 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/PkiArchiveControl.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/PkiArchiveControl.cs new file mode 100644 index 0000000..251b8db --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/PkiArchiveControl.cs @@ -0,0 +1,94 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Asn1.Crmf; +using Org.BouncyCastle.Cms; + +namespace Org.BouncyCastle.Crmf +{ + public class PkiArchiveControl + : IControl + { + public static readonly int encryptedPrivKey = PkiArchiveOptions.encryptedPrivKey; + public static readonly int keyGenParameters = PkiArchiveOptions.keyGenParameters; + public static readonly int archiveRemGenPrivKey = PkiArchiveOptions.archiveRemGenPrivKey; + + private static readonly DerObjectIdentifier type = CrmfObjectIdentifiers.id_regCtrl_pkiArchiveOptions; + + private readonly PkiArchiveOptions pkiArchiveOptions; + + /// + /// Basic constructor - build from an PKIArchiveOptions structure. + /// + /// the ASN.1 structure that will underlie this control. + public PkiArchiveControl(PkiArchiveOptions pkiArchiveOptions) + { + this.pkiArchiveOptions = pkiArchiveOptions; + } + + /// + /// Return the type of this control. + /// + /// CRMFObjectIdentifiers.id_regCtrl_pkiArchiveOptions + public DerObjectIdentifier Type + { + + get { return type; } + } + + /// + /// Return the underlying ASN.1 object. + /// + /// a PKIArchiveOptions structure. + public Asn1Encodable Value + { + get { return pkiArchiveOptions; } + } + + /// + /// Return the archive control type, one of: encryptedPrivKey,keyGenParameters,or archiveRemGenPrivKey. + /// + /// the archive control type. + public int ArchiveType + { + get { return pkiArchiveOptions.Type; } + } + + /// + /// Return whether this control contains enveloped data. + /// + /// true if the control contains enveloped data, false otherwise. + public bool EnvelopedData + { + get + { + EncryptedKey encKey = EncryptedKey.GetInstance(pkiArchiveOptions.Value); + return !encKey.IsEncryptedValue; + } + } + + /// + /// Return the enveloped data structure contained in this control. + /// + /// a CMSEnvelopedData object. + public CmsEnvelopedData GetEnvelopedData() + { + try + { + EncryptedKey encKey = EncryptedKey.GetInstance(pkiArchiveOptions.Value); + EnvelopedData data = Org.BouncyCastle.Asn1.Cms.EnvelopedData.GetInstance(encKey.Value); + + return new CmsEnvelopedData(new ContentInfo(CmsObjectIdentifiers.EnvelopedData, data)); + } + catch (CmsException e) + { + throw new CrmfException("CMS parsing error: " + e.Message, e); + } + catch (Exception e) + { + throw new CrmfException("CRMF parsing error: " + e.Message, e); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/PkiArchiveControl.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/PkiArchiveControl.cs.meta new file mode 100644 index 0000000..916626a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/PkiArchiveControl.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 232b0e7960460754d8efe0177dc7c974 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/PkiArchiveControlBuilder.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/PkiArchiveControlBuilder.cs new file mode 100644 index 0000000..d79f3b5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/PkiArchiveControlBuilder.cs @@ -0,0 +1,59 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Asn1.Crmf; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Cms; +using Org.BouncyCastle.Crypto; + +namespace Org.BouncyCastle.Crmf +{ + public class PkiArchiveControlBuilder + { + private CmsEnvelopedDataGenerator envGen; + private CmsProcessableByteArray keyContent; + + /// + ///Basic constructor - specify the contents of the PKIArchiveControl structure. + /// + /// the private key to be archived. + /// the general name to be associated with the private key. + /// + public PkiArchiveControlBuilder(PrivateKeyInfo privateKeyInfo, GeneralName generalName) + { + EncKeyWithID encKeyWithID = new EncKeyWithID(privateKeyInfo, generalName); + + try + { + this.keyContent = new CmsProcessableByteArray(CrmfObjectIdentifiers.id_ct_encKeyWithID, encKeyWithID.GetEncoded()); + } + catch (IOException e) + { + throw new InvalidOperationException("unable to encode key and general name info", e); + } + + this.envGen = new CmsEnvelopedDataGenerator(); + } + + ///Add a recipient generator to this control. + /// recipient generator created for a specific recipient. + ///this builder object. + public PkiArchiveControlBuilder AddRecipientGenerator(RecipientInfoGenerator recipientGen) + { + envGen.AddRecipientInfoGenerator(recipientGen); + return this; + } + + /// Build the PKIArchiveControl using the passed in encryptor to encrypt its contents. + /// a suitable content encryptor. + /// a PKIArchiveControl object. + public PkiArchiveControl Build(ICipherBuilderWithKey contentEncryptor) + { + CmsEnvelopedData envContent = envGen.Generate(keyContent, contentEncryptor); + EnvelopedData envD = EnvelopedData.GetInstance(envContent.ContentInfo.Content); + return new PkiArchiveControl(new PkiArchiveOptions(new EncryptedKey(envD))); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/PkiArchiveControlBuilder.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/PkiArchiveControlBuilder.cs.meta new file mode 100644 index 0000000..21c0a9a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/PkiArchiveControlBuilder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: af4f79454ee7d9646a3c31382f92c0aa +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/ProofOfPossessionSigningKeyBuilder.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/ProofOfPossessionSigningKeyBuilder.cs new file mode 100644 index 0000000..b7a3ae0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/ProofOfPossessionSigningKeyBuilder.cs @@ -0,0 +1,89 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Crmf; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Operators; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crmf +{ + public class ProofOfPossessionSigningKeyBuilder + { + private CertRequest _certRequest; + private SubjectPublicKeyInfo _pubKeyInfo; + private GeneralName _name; + private PKMacValue _publicKeyMAC; + + public ProofOfPossessionSigningKeyBuilder(CertRequest certRequest) + { + this._certRequest = certRequest; + } + + public ProofOfPossessionSigningKeyBuilder(SubjectPublicKeyInfo pubKeyInfo) + { + this._pubKeyInfo = pubKeyInfo; + } + + public ProofOfPossessionSigningKeyBuilder SetSender(GeneralName name) + { + this._name = name; + + return this; + } + + public ProofOfPossessionSigningKeyBuilder SetPublicKeyMac(PKMacBuilder generator, char[] password) + { + IMacFactory fact = generator.Build(password); + + IStreamCalculator calc = fact.CreateCalculator(); + byte[] d = _pubKeyInfo.GetDerEncoded(); + calc.Stream.Write(d, 0, d.Length); + calc.Stream.Flush(); + Platform.Dispose(calc.Stream); + + this._publicKeyMAC = new PKMacValue( + (AlgorithmIdentifier)fact.AlgorithmDetails, + new DerBitString(((IBlockResult)calc.GetResult()).Collect())); + + return this; + } + + public PopoSigningKey Build(ISignatureFactory signer) + { + if (_name != null && _publicKeyMAC != null) + { + throw new InvalidOperationException("name and publicKeyMAC cannot both be set."); + } + + PopoSigningKeyInput popo; + byte[] b; + IStreamCalculator calc = signer.CreateCalculator(); + if (_certRequest != null) + { + popo = null; + b = _certRequest.GetDerEncoded(); + calc.Stream.Write(b, 0, b.Length); + + } + else if (_name != null) + { + popo = new PopoSigningKeyInput(_name, _pubKeyInfo); + b = popo.GetDerEncoded(); + calc.Stream.Write(b, 0, b.Length); + } + else + { + popo = new PopoSigningKeyInput(_publicKeyMAC, _pubKeyInfo); + b = popo.GetDerEncoded(); + calc.Stream.Write(b, 0, b.Length); + } + + calc.Stream.Flush(); + Platform.Dispose(calc.Stream); + DefaultSignatureResult res = (DefaultSignatureResult)calc.GetResult(); + return new PopoSigningKey(popo, (AlgorithmIdentifier)signer.AlgorithmDetails, new DerBitString(res.Collect())); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/ProofOfPossessionSigningKeyBuilder.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/ProofOfPossessionSigningKeyBuilder.cs.meta new file mode 100644 index 0000000..bce1223 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/ProofOfPossessionSigningKeyBuilder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1ed04c79a7a2f9441b11309ecc810ab2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/RegTokenControl.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/RegTokenControl.cs new file mode 100644 index 0000000..4348409 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/RegTokenControl.cs @@ -0,0 +1,51 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Crmf; + +namespace Org.BouncyCastle.Crmf +{ + public class RegTokenControl + : IControl + { + private static readonly DerObjectIdentifier type = CrmfObjectIdentifiers.id_regCtrl_regToken; + + private readonly DerUtf8String token; + + /// + /// Basic constructor - build from a UTF-8 string representing the token. + /// + /// UTF-8 string representing the token. + public RegTokenControl(DerUtf8String token) + { + this.token = token; + } + + /// + /// Basic constructor - build from a string representing the token. + /// + /// string representing the token. + public RegTokenControl(string token) + { + this.token = new DerUtf8String(token); + } + + /// + /// Return the type of this control. + /// + /// CRMFObjectIdentifiers.id_regCtrl_regToken + public DerObjectIdentifier Type + { + get { return type; } + } + + /// + /// Return the token associated with this control (a UTF8String). + /// + /// a UTF8String. + public Asn1Encodable Value + { + get { return token; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/RegTokenControl.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/RegTokenControl.cs.meta new file mode 100644 index 0000000..17d3c37 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crmf/RegTokenControl.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3a4cf28c55806604faf4cf2f3ce35c53 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto.csproj.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto.csproj.meta new file mode 100644 index 0000000..9821f46 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto.csproj.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 10e63942411f885448334599a38b10a7 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto.meta new file mode 100644 index 0000000..59e5cc3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 8bcc6b02972cbf248803140f8c3ce746 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/AsymmetricCipherKeyPair.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/AsymmetricCipherKeyPair.cs new file mode 100644 index 0000000..b00a3dc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/AsymmetricCipherKeyPair.cs @@ -0,0 +1,52 @@ +using System; + +namespace Org.BouncyCastle.Crypto +{ + /** + * a holding class for public/private parameter pairs. + */ + public class AsymmetricCipherKeyPair + { + private readonly AsymmetricKeyParameter publicParameter; + private readonly AsymmetricKeyParameter privateParameter; + + /** + * basic constructor. + * + * @param publicParam a public key parameters object. + * @param privateParam the corresponding private key parameters. + */ + public AsymmetricCipherKeyPair( + AsymmetricKeyParameter publicParameter, + AsymmetricKeyParameter privateParameter) + { + if (publicParameter.IsPrivate) + throw new ArgumentException("Expected a public key", "publicParameter"); + if (!privateParameter.IsPrivate) + throw new ArgumentException("Expected a private key", "privateParameter"); + + this.publicParameter = publicParameter; + this.privateParameter = privateParameter; + } + + /** + * return the public key parameters. + * + * @return the public key parameters. + */ + public AsymmetricKeyParameter Public + { + get { return publicParameter; } + } + + /** + * return the private key parameters. + * + * @return the private key parameters. + */ + public AsymmetricKeyParameter Private + { + get { return privateParameter; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/AsymmetricCipherKeyPair.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/AsymmetricCipherKeyPair.cs.meta new file mode 100644 index 0000000..d5232ee --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/AsymmetricCipherKeyPair.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1adc56a5dc38d2a448c655fa5ad842ad +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/AsymmetricKeyParameter.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/AsymmetricKeyParameter.cs new file mode 100644 index 0000000..7502ee3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/AsymmetricKeyParameter.cs @@ -0,0 +1,47 @@ +using System; + +using Org.BouncyCastle.Crypto; + +namespace Org.BouncyCastle.Crypto +{ + public abstract class AsymmetricKeyParameter + : ICipherParameters + { + private readonly bool privateKey; + + protected AsymmetricKeyParameter( + bool privateKey) + { + this.privateKey = privateKey; + } + + public bool IsPrivate + { + get { return privateKey; } + } + + public override bool Equals( + object obj) + { + AsymmetricKeyParameter other = obj as AsymmetricKeyParameter; + + if (other == null) + { + return false; + } + + return Equals(other); + } + + protected bool Equals( + AsymmetricKeyParameter other) + { + return privateKey == other.privateKey; + } + + public override int GetHashCode() + { + return privateKey.GetHashCode(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/AsymmetricKeyParameter.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/AsymmetricKeyParameter.cs.meta new file mode 100644 index 0000000..3023295 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/AsymmetricKeyParameter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 33fad237214781a4294ff3d0518929ba +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/BufferedAeadBlockCipher.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/BufferedAeadBlockCipher.cs new file mode 100644 index 0000000..7ba4109 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/BufferedAeadBlockCipher.cs @@ -0,0 +1,247 @@ +using System; + +using Org.BouncyCastle.Crypto.Modes; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto +{ + /** + * The AEAD block ciphers already handle buffering internally, so this class + * just takes care of implementing IBufferedCipher methods. + */ + public class BufferedAeadBlockCipher + : BufferedCipherBase + { + private readonly IAeadBlockCipher cipher; + + public BufferedAeadBlockCipher( + IAeadBlockCipher cipher) + { + if (cipher == null) + throw new ArgumentNullException("cipher"); + + this.cipher = cipher; + } + + public override string AlgorithmName + { + get { return cipher.AlgorithmName; } + } + + /** + * initialise the cipher. + * + * @param forEncryption if true the cipher is initialised for + * encryption, if false for decryption. + * @param param the key and other data required by the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public override void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (parameters is ParametersWithRandom) + { + parameters = ((ParametersWithRandom) parameters).Parameters; + } + + cipher.Init(forEncryption, parameters); + } + + /** + * return the blocksize for the underlying cipher. + * + * @return the blocksize for the underlying cipher. + */ + public override int GetBlockSize() + { + return cipher.GetBlockSize(); + } + + /** + * return the size of the output buffer required for an update + * an input of len bytes. + * + * @param len the length of the input. + * @return the space required to accommodate a call to update + * with len bytes of input. + */ + public override int GetUpdateOutputSize( + int length) + { + return cipher.GetUpdateOutputSize(length); + } + + /** + * return the size of the output buffer required for an update plus a + * doFinal with an input of len bytes. + * + * @param len the length of the input. + * @return the space required to accommodate a call to update and doFinal + * with len bytes of input. + */ + public override int GetOutputSize( + int length) + { + return cipher.GetOutputSize(length); + } + + /** + * process a single byte, producing an output block if necessary. + * + * @param in the input byte. + * @param out the space for any output that might be produced. + * @param outOff the offset from which the output will be copied. + * @return the number of output bytes copied to out. + * @exception DataLengthException if there isn't enough space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + */ + public override int ProcessByte( + byte input, + byte[] output, + int outOff) + { + return cipher.ProcessByte(input, output, outOff); + } + + public override byte[] ProcessByte( + byte input) + { + int outLength = GetUpdateOutputSize(1); + + byte[] outBytes = outLength > 0 ? new byte[outLength] : null; + + int pos = ProcessByte(input, outBytes, 0); + + if (outLength > 0 && pos < outLength) + { + byte[] tmp = new byte[pos]; + Array.Copy(outBytes, 0, tmp, 0, pos); + outBytes = tmp; + } + + return outBytes; + } + + public override byte[] ProcessBytes( + byte[] input, + int inOff, + int length) + { + if (input == null) + throw new ArgumentNullException("input"); + if (length < 1) + return null; + + int outLength = GetUpdateOutputSize(length); + + byte[] outBytes = outLength > 0 ? new byte[outLength] : null; + + int pos = ProcessBytes(input, inOff, length, outBytes, 0); + + if (outLength > 0 && pos < outLength) + { + byte[] tmp = new byte[pos]; + Array.Copy(outBytes, 0, tmp, 0, pos); + outBytes = tmp; + } + + return outBytes; + } + + /** + * process an array of bytes, producing output if necessary. + * + * @param in the input byte array. + * @param inOff the offset at which the input data starts. + * @param len the number of bytes to be copied out of the input array. + * @param out the space for any output that might be produced. + * @param outOff the offset from which the output will be copied. + * @return the number of output bytes copied to out. + * @exception DataLengthException if there isn't enough space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + */ + public override int ProcessBytes( + byte[] input, + int inOff, + int length, + byte[] output, + int outOff) + { + return cipher.ProcessBytes(input, inOff, length, output, outOff); + } + + public override byte[] DoFinal() + { + byte[] outBytes = new byte[GetOutputSize(0)]; + + int pos = DoFinal(outBytes, 0); + + if (pos < outBytes.Length) + { + byte[] tmp = new byte[pos]; + Array.Copy(outBytes, 0, tmp, 0, pos); + outBytes = tmp; + } + + return outBytes; + } + + public override byte[] DoFinal( + byte[] input, + int inOff, + int inLen) + { + if (input == null) + throw new ArgumentNullException("input"); + + byte[] outBytes = new byte[GetOutputSize(inLen)]; + + int pos = (inLen > 0) + ? ProcessBytes(input, inOff, inLen, outBytes, 0) + : 0; + + pos += DoFinal(outBytes, pos); + + if (pos < outBytes.Length) + { + byte[] tmp = new byte[pos]; + Array.Copy(outBytes, 0, tmp, 0, pos); + outBytes = tmp; + } + + return outBytes; + } + + /** + * Process the last block in the buffer. + * + * @param out the array the block currently being held is copied into. + * @param outOff the offset at which the copying starts. + * @return the number of output bytes copied to out. + * @exception DataLengthException if there is insufficient space in out for + * the output, or the input is not block size aligned and should be. + * @exception InvalidOperationException if the underlying cipher is not + * initialised. + * @exception InvalidCipherTextException if padding is expected and not found. + * @exception DataLengthException if the input is not block size + * aligned. + */ + public override int DoFinal( + byte[] output, + int outOff) + { + return cipher.DoFinal(output, outOff); + } + + /** + * Reset the buffer and cipher. After resetting the object is in the same + * state as it was after the last init (if there was one). + */ + public override void Reset() + { + cipher.Reset(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/BufferedAeadBlockCipher.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/BufferedAeadBlockCipher.cs.meta new file mode 100644 index 0000000..f2d3b0e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/BufferedAeadBlockCipher.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 06d6ae62469226e448a59dcb2724d740 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/BufferedAeadCipher.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/BufferedAeadCipher.cs new file mode 100644 index 0000000..c689c1e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/BufferedAeadCipher.cs @@ -0,0 +1,246 @@ +using System; + +using Org.BouncyCastle.Crypto.Modes; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto +{ + /** + * The AEAD ciphers already handle buffering internally, so this class + * just takes care of implementing IBufferedCipher methods. + */ + public class BufferedAeadCipher + : BufferedCipherBase + { + private readonly IAeadCipher cipher; + + public BufferedAeadCipher(IAeadCipher cipher) + { + if (cipher == null) + throw new ArgumentNullException("cipher"); + + this.cipher = cipher; + } + + public override string AlgorithmName + { + get { return cipher.AlgorithmName; } + } + + /** + * initialise the cipher. + * + * @param forEncryption if true the cipher is initialised for + * encryption, if false for decryption. + * @param param the key and other data required by the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public override void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (parameters is ParametersWithRandom) + { + parameters = ((ParametersWithRandom)parameters).Parameters; + } + + cipher.Init(forEncryption, parameters); + } + + /** + * return the blocksize for the underlying cipher. + * + * @return the blocksize for the underlying cipher. + */ + public override int GetBlockSize() + { + return 0; + } + + /** + * return the size of the output buffer required for an update + * an input of len bytes. + * + * @param len the length of the input. + * @return the space required to accommodate a call to update + * with len bytes of input. + */ + public override int GetUpdateOutputSize( + int length) + { + return cipher.GetUpdateOutputSize(length); + } + + /** + * return the size of the output buffer required for an update plus a + * doFinal with an input of len bytes. + * + * @param len the length of the input. + * @return the space required to accommodate a call to update and doFinal + * with len bytes of input. + */ + public override int GetOutputSize( + int length) + { + return cipher.GetOutputSize(length); + } + + /** + * process a single byte, producing an output block if necessary. + * + * @param in the input byte. + * @param out the space for any output that might be produced. + * @param outOff the offset from which the output will be copied. + * @return the number of output bytes copied to out. + * @exception DataLengthException if there isn't enough space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + */ + public override int ProcessByte( + byte input, + byte[] output, + int outOff) + { + return cipher.ProcessByte(input, output, outOff); + } + + public override byte[] ProcessByte( + byte input) + { + int outLength = GetUpdateOutputSize(1); + + byte[] outBytes = outLength > 0 ? new byte[outLength] : null; + + int pos = ProcessByte(input, outBytes, 0); + + if (outLength > 0 && pos < outLength) + { + byte[] tmp = new byte[pos]; + Array.Copy(outBytes, 0, tmp, 0, pos); + outBytes = tmp; + } + + return outBytes; + } + + public override byte[] ProcessBytes( + byte[] input, + int inOff, + int length) + { + if (input == null) + throw new ArgumentNullException("input"); + if (length < 1) + return null; + + int outLength = GetUpdateOutputSize(length); + + byte[] outBytes = outLength > 0 ? new byte[outLength] : null; + + int pos = ProcessBytes(input, inOff, length, outBytes, 0); + + if (outLength > 0 && pos < outLength) + { + byte[] tmp = new byte[pos]; + Array.Copy(outBytes, 0, tmp, 0, pos); + outBytes = tmp; + } + + return outBytes; + } + + /** + * process an array of bytes, producing output if necessary. + * + * @param in the input byte array. + * @param inOff the offset at which the input data starts. + * @param len the number of bytes to be copied out of the input array. + * @param out the space for any output that might be produced. + * @param outOff the offset from which the output will be copied. + * @return the number of output bytes copied to out. + * @exception DataLengthException if there isn't enough space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + */ + public override int ProcessBytes( + byte[] input, + int inOff, + int length, + byte[] output, + int outOff) + { + return cipher.ProcessBytes(input, inOff, length, output, outOff); + } + + public override byte[] DoFinal() + { + byte[] outBytes = new byte[GetOutputSize(0)]; + + int pos = DoFinal(outBytes, 0); + + if (pos < outBytes.Length) + { + byte[] tmp = new byte[pos]; + Array.Copy(outBytes, 0, tmp, 0, pos); + outBytes = tmp; + } + + return outBytes; + } + + public override byte[] DoFinal( + byte[] input, + int inOff, + int inLen) + { + if (input == null) + throw new ArgumentNullException("input"); + + byte[] outBytes = new byte[GetOutputSize(inLen)]; + + int pos = (inLen > 0) + ? ProcessBytes(input, inOff, inLen, outBytes, 0) + : 0; + + pos += DoFinal(outBytes, pos); + + if (pos < outBytes.Length) + { + byte[] tmp = new byte[pos]; + Array.Copy(outBytes, 0, tmp, 0, pos); + outBytes = tmp; + } + + return outBytes; + } + + /** + * Process the last block in the buffer. + * + * @param out the array the block currently being held is copied into. + * @param outOff the offset at which the copying starts. + * @return the number of output bytes copied to out. + * @exception DataLengthException if there is insufficient space in out for + * the output, or the input is not block size aligned and should be. + * @exception InvalidOperationException if the underlying cipher is not + * initialised. + * @exception InvalidCipherTextException if padding is expected and not found. + * @exception DataLengthException if the input is not block size + * aligned. + */ + public override int DoFinal( + byte[] output, + int outOff) + { + return cipher.DoFinal(output, outOff); + } + + /** + * Reset the buffer and cipher. After resetting the object is in the same + * state as it was after the last init (if there was one). + */ + public override void Reset() + { + cipher.Reset(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/BufferedAeadCipher.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/BufferedAeadCipher.cs.meta new file mode 100644 index 0000000..32442ff --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/BufferedAeadCipher.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 55a51fed0a0d7844c8a3f8ce4ba900a3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/BufferedAsymmetricBlockCipher.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/BufferedAsymmetricBlockCipher.cs new file mode 100644 index 0000000..09ec59f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/BufferedAsymmetricBlockCipher.cs @@ -0,0 +1,152 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Crypto.Engines; + +namespace Org.BouncyCastle.Crypto +{ + /** + * a buffer wrapper for an asymmetric block cipher, allowing input + * to be accumulated in a piecemeal fashion until final processing. + */ + public class BufferedAsymmetricBlockCipher + : BufferedCipherBase + { + private readonly IAsymmetricBlockCipher cipher; + + private byte[] buffer; + private int bufOff; + + /** + * base constructor. + * + * @param cipher the cipher this buffering object wraps. + */ + public BufferedAsymmetricBlockCipher( + IAsymmetricBlockCipher cipher) + { + this.cipher = cipher; + } + + /** + * return the amount of data sitting in the buffer. + * + * @return the amount of data sitting in the buffer. + */ + internal int GetBufferPosition() + { + return bufOff; + } + + public override string AlgorithmName + { + get { return cipher.AlgorithmName; } + } + + public override int GetBlockSize() + { + return cipher.GetInputBlockSize(); + } + + public override int GetOutputSize( + int length) + { + return cipher.GetOutputBlockSize(); + } + + public override int GetUpdateOutputSize( + int length) + { + return 0; + } + + /** + * initialise the buffer and the underlying cipher. + * + * @param forEncryption if true the cipher is initialised for + * encryption, if false for decryption. + * @param param the key and other data required by the cipher. + */ + public override void Init( + bool forEncryption, + ICipherParameters parameters) + { + Reset(); + + cipher.Init(forEncryption, parameters); + + // + // we allow for an extra byte where people are using their own padding + // mechanisms on a raw cipher. + // + this.buffer = new byte[cipher.GetInputBlockSize() + (forEncryption ? 1 : 0)]; + this.bufOff = 0; + } + + public override byte[] ProcessByte( + byte input) + { + if (bufOff >= buffer.Length) + throw new DataLengthException("attempt to process message to long for cipher"); + + buffer[bufOff++] = input; + return null; + } + + public override byte[] ProcessBytes( + byte[] input, + int inOff, + int length) + { + if (length < 1) + return null; + + if (input == null) + throw new ArgumentNullException("input"); + if (bufOff + length > buffer.Length) + throw new DataLengthException("attempt to process message to long for cipher"); + + Array.Copy(input, inOff, buffer, bufOff, length); + bufOff += length; + return null; + } + + /** + * process the contents of the buffer using the underlying + * cipher. + * + * @return the result of the encryption/decryption process on the + * buffer. + * @exception InvalidCipherTextException if we are given a garbage block. + */ + public override byte[] DoFinal() + { + byte[] outBytes = bufOff > 0 + ? cipher.ProcessBlock(buffer, 0, bufOff) + : EmptyBuffer; + + Reset(); + + return outBytes; + } + + public override byte[] DoFinal( + byte[] input, + int inOff, + int length) + { + ProcessBytes(input, inOff, length); + return DoFinal(); + } + + /// Reset the buffer + public override void Reset() + { + if (buffer != null) + { + Array.Clear(buffer, 0, buffer.Length); + bufOff = 0; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/BufferedAsymmetricBlockCipher.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/BufferedAsymmetricBlockCipher.cs.meta new file mode 100644 index 0000000..ccc28f1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/BufferedAsymmetricBlockCipher.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 687e617f5896dcf448116b8a27d2e538 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/BufferedBlockCipher.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/BufferedBlockCipher.cs new file mode 100644 index 0000000..c87d2da --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/BufferedBlockCipher.cs @@ -0,0 +1,367 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto +{ + /** + * A wrapper class that allows block ciphers to be used to process data in + * a piecemeal fashion. The BufferedBlockCipher outputs a block only when the + * buffer is full and more data is being added, or on a doFinal. + *

+ * Note: in the case where the underlying cipher is either a CFB cipher or an + * OFB one the last block may not be a multiple of the block size. + *

+ */ + public class BufferedBlockCipher + : BufferedCipherBase + { + internal byte[] buf; + internal int bufOff; + internal bool forEncryption; + internal IBlockCipher cipher; + + /** + * constructor for subclasses + */ + protected BufferedBlockCipher() + { + } + + /** + * Create a buffered block cipher without padding. + * + * @param cipher the underlying block cipher this buffering object wraps. + * false otherwise. + */ + public BufferedBlockCipher( + IBlockCipher cipher) + { + if (cipher == null) + throw new ArgumentNullException("cipher"); + + this.cipher = cipher; + buf = new byte[cipher.GetBlockSize()]; + bufOff = 0; + } + + public override string AlgorithmName + { + get { return cipher.AlgorithmName; } + } + + /** + * initialise the cipher. + * + * @param forEncryption if true the cipher is initialised for + * encryption, if false for decryption. + * @param param the key and other data required by the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + // Note: This doubles as the Init in the event that this cipher is being used as an IWrapper + public override void Init( + bool forEncryption, + ICipherParameters parameters) + { + this.forEncryption = forEncryption; + + ParametersWithRandom pwr = parameters as ParametersWithRandom; + if (pwr != null) + parameters = pwr.Parameters; + + Reset(); + + cipher.Init(forEncryption, parameters); + } + + /** + * return the blocksize for the underlying cipher. + * + * @return the blocksize for the underlying cipher. + */ + public override int GetBlockSize() + { + return cipher.GetBlockSize(); + } + + /** + * return the size of the output buffer required for an update + * an input of len bytes. + * + * @param len the length of the input. + * @return the space required to accommodate a call to update + * with len bytes of input. + */ + public override int GetUpdateOutputSize( + int length) + { + int total = length + bufOff; + int leftOver = total % buf.Length; + return total - leftOver; + } + + /** + * return the size of the output buffer required for an update plus a + * doFinal with an input of len bytes. + * + * @param len the length of the input. + * @return the space required to accommodate a call to update and doFinal + * with len bytes of input. + */ + public override int GetOutputSize( + int length) + { + // Note: Can assume IsPartialBlockOkay is true for purposes of this calculation + return length + bufOff; + } + + /** + * process a single byte, producing an output block if necessary. + * + * @param in the input byte. + * @param out the space for any output that might be produced. + * @param outOff the offset from which the output will be copied. + * @return the number of output bytes copied to out. + * @exception DataLengthException if there isn't enough space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + */ + public override int ProcessByte( + byte input, + byte[] output, + int outOff) + { + buf[bufOff++] = input; + + if (bufOff == buf.Length) + { + if ((outOff + buf.Length) > output.Length) + throw new DataLengthException("output buffer too short"); + + bufOff = 0; + return cipher.ProcessBlock(buf, 0, output, outOff); + } + + return 0; + } + + public override byte[] ProcessByte( + byte input) + { + int outLength = GetUpdateOutputSize(1); + + byte[] outBytes = outLength > 0 ? new byte[outLength] : null; + + int pos = ProcessByte(input, outBytes, 0); + + if (outLength > 0 && pos < outLength) + { + byte[] tmp = new byte[pos]; + Array.Copy(outBytes, 0, tmp, 0, pos); + outBytes = tmp; + } + + return outBytes; + } + + public override byte[] ProcessBytes( + byte[] input, + int inOff, + int length) + { + if (input == null) + throw new ArgumentNullException("input"); + if (length < 1) + return null; + + int outLength = GetUpdateOutputSize(length); + + byte[] outBytes = outLength > 0 ? new byte[outLength] : null; + + int pos = ProcessBytes(input, inOff, length, outBytes, 0); + + if (outLength > 0 && pos < outLength) + { + byte[] tmp = new byte[pos]; + Array.Copy(outBytes, 0, tmp, 0, pos); + outBytes = tmp; + } + + return outBytes; + } + + /** + * process an array of bytes, producing output if necessary. + * + * @param in the input byte array. + * @param inOff the offset at which the input data starts. + * @param len the number of bytes to be copied out of the input array. + * @param out the space for any output that might be produced. + * @param outOff the offset from which the output will be copied. + * @return the number of output bytes copied to out. + * @exception DataLengthException if there isn't enough space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + */ + public override int ProcessBytes( + byte[] input, + int inOff, + int length, + byte[] output, + int outOff) + { + if (length < 1) + { + if (length < 0) + throw new ArgumentException("Can't have a negative input length!"); + + return 0; + } + + int blockSize = GetBlockSize(); + int outLength = GetUpdateOutputSize(length); + + if (outLength > 0) + { + Check.OutputLength(output, outOff, outLength, "output buffer too short"); + } + + int resultLen = 0; + int gapLen = buf.Length - bufOff; + if (length > gapLen) + { + Array.Copy(input, inOff, buf, bufOff, gapLen); + resultLen += cipher.ProcessBlock(buf, 0, output, outOff); + bufOff = 0; + length -= gapLen; + inOff += gapLen; + while (length > buf.Length) + { + resultLen += cipher.ProcessBlock(input, inOff, output, outOff + resultLen); + length -= blockSize; + inOff += blockSize; + } + } + Array.Copy(input, inOff, buf, bufOff, length); + bufOff += length; + if (bufOff == buf.Length) + { + resultLen += cipher.ProcessBlock(buf, 0, output, outOff + resultLen); + bufOff = 0; + } + return resultLen; + } + + public override byte[] DoFinal() + { + byte[] outBytes = EmptyBuffer; + + int length = GetOutputSize(0); + if (length > 0) + { + outBytes = new byte[length]; + + int pos = DoFinal(outBytes, 0); + if (pos < outBytes.Length) + { + byte[] tmp = new byte[pos]; + Array.Copy(outBytes, 0, tmp, 0, pos); + outBytes = tmp; + } + } + else + { + Reset(); + } + + return outBytes; + } + + public override byte[] DoFinal( + byte[] input, + int inOff, + int inLen) + { + if (input == null) + throw new ArgumentNullException("input"); + + int length = GetOutputSize(inLen); + + byte[] outBytes = EmptyBuffer; + + if (length > 0) + { + outBytes = new byte[length]; + + int pos = (inLen > 0) + ? ProcessBytes(input, inOff, inLen, outBytes, 0) + : 0; + + pos += DoFinal(outBytes, pos); + + if (pos < outBytes.Length) + { + byte[] tmp = new byte[pos]; + Array.Copy(outBytes, 0, tmp, 0, pos); + outBytes = tmp; + } + } + else + { + Reset(); + } + + return outBytes; + } + + /** + * Process the last block in the buffer. + * + * @param out the array the block currently being held is copied into. + * @param outOff the offset at which the copying starts. + * @return the number of output bytes copied to out. + * @exception DataLengthException if there is insufficient space in out for + * the output, or the input is not block size aligned and should be. + * @exception InvalidOperationException if the underlying cipher is not + * initialised. + * @exception InvalidCipherTextException if padding is expected and not found. + * @exception DataLengthException if the input is not block size + * aligned. + */ + public override int DoFinal( + byte[] output, + int outOff) + { + try + { + if (bufOff != 0) + { + Check.DataLength(!cipher.IsPartialBlockOkay, "data not block size aligned"); + Check.OutputLength(output, outOff, bufOff, "output buffer too short for DoFinal()"); + + // NB: Can't copy directly, or we may write too much output + cipher.ProcessBlock(buf, 0, buf, 0); + Array.Copy(buf, 0, output, outOff, bufOff); + } + + return bufOff; + } + finally + { + Reset(); + } + } + + /** + * Reset the buffer and cipher. After resetting the object is in the same + * state as it was after the last init (if there was one). + */ + public override void Reset() + { + Array.Clear(buf, 0, buf.Length); + bufOff = 0; + + cipher.Reset(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/BufferedBlockCipher.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/BufferedBlockCipher.cs.meta new file mode 100644 index 0000000..ab286bc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/BufferedBlockCipher.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2c33029733198e94f884c0efecf09c28 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/BufferedCipherBase.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/BufferedCipherBase.cs new file mode 100644 index 0000000..9d86102 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/BufferedCipherBase.cs @@ -0,0 +1,113 @@ +using System; + +namespace Org.BouncyCastle.Crypto +{ + public abstract class BufferedCipherBase + : IBufferedCipher + { + protected static readonly byte[] EmptyBuffer = new byte[0]; + + public abstract string AlgorithmName { get; } + + public abstract void Init(bool forEncryption, ICipherParameters parameters); + + public abstract int GetBlockSize(); + + public abstract int GetOutputSize(int inputLen); + public abstract int GetUpdateOutputSize(int inputLen); + + public abstract byte[] ProcessByte(byte input); + + public virtual int ProcessByte( + byte input, + byte[] output, + int outOff) + { + byte[] outBytes = ProcessByte(input); + if (outBytes == null) + return 0; + if (outOff + outBytes.Length > output.Length) + throw new DataLengthException("output buffer too short"); + outBytes.CopyTo(output, outOff); + return outBytes.Length; + } + + public virtual byte[] ProcessBytes( + byte[] input) + { + return ProcessBytes(input, 0, input.Length); + } + + public abstract byte[] ProcessBytes(byte[] input, int inOff, int length); + + public virtual int ProcessBytes( + byte[] input, + byte[] output, + int outOff) + { + return ProcessBytes(input, 0, input.Length, output, outOff); + } + + public virtual int ProcessBytes( + byte[] input, + int inOff, + int length, + byte[] output, + int outOff) + { + byte[] outBytes = ProcessBytes(input, inOff, length); + if (outBytes == null) + return 0; + if (outOff + outBytes.Length > output.Length) + throw new DataLengthException("output buffer too short"); + outBytes.CopyTo(output, outOff); + return outBytes.Length; + } + + public abstract byte[] DoFinal(); + + public virtual byte[] DoFinal( + byte[] input) + { + return DoFinal(input, 0, input.Length); + } + + public abstract byte[] DoFinal( + byte[] input, + int inOff, + int length); + + public virtual int DoFinal( + byte[] output, + int outOff) + { + byte[] outBytes = DoFinal(); + if (outOff + outBytes.Length > output.Length) + throw new DataLengthException("output buffer too short"); + outBytes.CopyTo(output, outOff); + return outBytes.Length; + } + + public virtual int DoFinal( + byte[] input, + byte[] output, + int outOff) + { + return DoFinal(input, 0, input.Length, output, outOff); + } + + public virtual int DoFinal( + byte[] input, + int inOff, + int length, + byte[] output, + int outOff) + { + int len = ProcessBytes(input, inOff, length, output, outOff); + len += DoFinal(output, outOff + len); + return len; + } + + public abstract void Reset(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/BufferedCipherBase.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/BufferedCipherBase.cs.meta new file mode 100644 index 0000000..5daf02b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/BufferedCipherBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: acfc96fa09985b2488cf31a1a8337019 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/BufferedIesCipher.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/BufferedIesCipher.cs new file mode 100644 index 0000000..6dab4ae --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/BufferedIesCipher.cs @@ -0,0 +1,113 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto +{ + public class BufferedIesCipher + : BufferedCipherBase + { + private readonly IesEngine engine; + private bool forEncryption; + private MemoryStream buffer = new MemoryStream(); + + public BufferedIesCipher( + IesEngine engine) + { + if (engine == null) + throw new ArgumentNullException("engine"); + + this.engine = engine; + } + + public override string AlgorithmName + { + // TODO Create IESEngine.AlgorithmName + get { return "IES"; } + } + + public override void Init( + bool forEncryption, + ICipherParameters parameters) + { + this.forEncryption = forEncryption; + + // TODO + throw Platform.CreateNotImplementedException("IES"); + } + + public override int GetBlockSize() + { + return 0; + } + + public override int GetOutputSize( + int inputLen) + { + if (engine == null) + throw new InvalidOperationException("cipher not initialised"); + + int baseLen = inputLen + (int) buffer.Length; + return forEncryption + ? baseLen + 20 + : baseLen - 20; + } + + public override int GetUpdateOutputSize( + int inputLen) + { + return 0; + } + + public override byte[] ProcessByte( + byte input) + { + buffer.WriteByte(input); + return null; + } + + public override byte[] ProcessBytes( + byte[] input, + int inOff, + int length) + { + if (input == null) + throw new ArgumentNullException("input"); + if (inOff < 0) + throw new ArgumentException("inOff"); + if (length < 0) + throw new ArgumentException("length"); + if (inOff + length > input.Length) + throw new ArgumentException("invalid offset/length specified for input array"); + + buffer.Write(input, inOff, length); + return null; + } + + public override byte[] DoFinal() + { + byte[] buf = buffer.ToArray(); + + Reset(); + + return engine.ProcessBlock(buf, 0, buf.Length); + } + + public override byte[] DoFinal( + byte[] input, + int inOff, + int length) + { + ProcessBytes(input, inOff, length); + return DoFinal(); + } + + public override void Reset() + { + buffer.SetLength(0); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/BufferedIesCipher.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/BufferedIesCipher.cs.meta new file mode 100644 index 0000000..e339687 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/BufferedIesCipher.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f171ae8b22d29ea449a783cf7bb6bc8c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/BufferedStreamCipher.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/BufferedStreamCipher.cs new file mode 100644 index 0000000..2d4987b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/BufferedStreamCipher.cs @@ -0,0 +1,131 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto +{ + public class BufferedStreamCipher + : BufferedCipherBase + { + private readonly IStreamCipher cipher; + + public BufferedStreamCipher( + IStreamCipher cipher) + { + if (cipher == null) + throw new ArgumentNullException("cipher"); + + this.cipher = cipher; + } + + public override string AlgorithmName + { + get { return cipher.AlgorithmName; } + } + + public override void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (parameters is ParametersWithRandom) + { + parameters = ((ParametersWithRandom) parameters).Parameters; + } + + cipher.Init(forEncryption, parameters); + } + + public override int GetBlockSize() + { + return 0; + } + + public override int GetOutputSize( + int inputLen) + { + return inputLen; + } + + public override int GetUpdateOutputSize( + int inputLen) + { + return inputLen; + } + + public override byte[] ProcessByte( + byte input) + { + return new byte[]{ cipher.ReturnByte(input) }; + } + + public override int ProcessByte( + byte input, + byte[] output, + int outOff) + { + if (outOff >= output.Length) + throw new DataLengthException("output buffer too short"); + + output[outOff] = cipher.ReturnByte(input); + return 1; + } + + public override byte[] ProcessBytes( + byte[] input, + int inOff, + int length) + { + if (length < 1) + return null; + + byte[] output = new byte[length]; + cipher.ProcessBytes(input, inOff, length, output, 0); + return output; + } + + public override int ProcessBytes( + byte[] input, + int inOff, + int length, + byte[] output, + int outOff) + { + if (length < 1) + return 0; + + if (length > 0) + { + cipher.ProcessBytes(input, inOff, length, output, outOff); + } + + return length; + } + + public override byte[] DoFinal() + { + Reset(); + + return EmptyBuffer; + } + + public override byte[] DoFinal( + byte[] input, + int inOff, + int length) + { + if (length < 1) + return EmptyBuffer; + + byte[] output = ProcessBytes(input, inOff, length); + + Reset(); + + return output; + } + + public override void Reset() + { + cipher.Reset(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/BufferedStreamCipher.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/BufferedStreamCipher.cs.meta new file mode 100644 index 0000000..f102d61 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/BufferedStreamCipher.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5b8c2e73e67117b49bfb6ec193934884 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/Check.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/Check.cs new file mode 100644 index 0000000..aacda14 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/Check.cs @@ -0,0 +1,25 @@ +using System; + +namespace Org.BouncyCastle.Crypto +{ + internal class Check + { + internal static void DataLength(bool condition, string msg) + { + if (condition) + throw new DataLengthException(msg); + } + + internal static void DataLength(byte[] buf, int off, int len, string msg) + { + if (off > (buf.Length - len)) + throw new DataLengthException(msg); + } + + internal static void OutputLength(byte[] buf, int off, int len, string msg) + { + if (off > (buf.Length - len)) + throw new OutputLengthException(msg); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/Check.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/Check.cs.meta new file mode 100644 index 0000000..0f5058d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/Check.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4448c116dc4335640b2b0abe6f20d6e3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/CipherKeyGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/CipherKeyGenerator.cs new file mode 100644 index 0000000..d8d9b29 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/CipherKeyGenerator.cs @@ -0,0 +1,83 @@ +using System; + +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto +{ + /** + * The base class for symmetric, or secret, cipher key generators. + */ + public class CipherKeyGenerator + { + protected internal SecureRandom random; + protected internal int strength; + private bool uninitialised = true; + private int defaultStrength; + + public CipherKeyGenerator() + { + } + + internal CipherKeyGenerator( + int defaultStrength) + { + if (defaultStrength < 1) + throw new ArgumentException("strength must be a positive value", "defaultStrength"); + + this.defaultStrength = defaultStrength; + } + + public int DefaultStrength + { + get { return defaultStrength; } + } + + /** + * initialise the key generator. + * + * @param param the parameters to be used for key generation + */ + public void Init( + KeyGenerationParameters parameters) + { + if (parameters == null) + throw new ArgumentNullException("parameters"); + + this.uninitialised = false; + + engineInit(parameters); + } + + protected virtual void engineInit( + KeyGenerationParameters parameters) + { + this.random = parameters.Random; + this.strength = (parameters.Strength + 7) / 8; + } + + /** + * Generate a secret key. + * + * @return a byte array containing the key value. + */ + public byte[] GenerateKey() + { + if (uninitialised) + { + if (defaultStrength < 1) + throw new InvalidOperationException("Generator has not been initialised"); + + uninitialised = false; + + engineInit(new KeyGenerationParameters(new SecureRandom(), defaultStrength)); + } + + return engineGenerateKey(); + } + + protected virtual byte[] engineGenerateKey() + { + return SecureRandom.GetNextBytes(random, strength); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/CipherKeyGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/CipherKeyGenerator.cs.meta new file mode 100644 index 0000000..003c7c3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/CipherKeyGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b6dbd82037c2b594d974736b42bbaa47 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/CryptoException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/CryptoException.cs new file mode 100644 index 0000000..73d450b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/CryptoException.cs @@ -0,0 +1,28 @@ +using System; + +namespace Org.BouncyCastle.Crypto +{ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE) + [Serializable] +#endif + public class CryptoException + : Exception + { + public CryptoException() + { + } + + public CryptoException( + string message) + : base(message) + { + } + + public CryptoException( + string message, + Exception exception) + : base(message, exception) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/CryptoException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/CryptoException.cs.meta new file mode 100644 index 0000000..2ddfbe5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/CryptoException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 07401d7edbae7974bab0ae2c3f9550cd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/DataLengthException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/DataLengthException.cs new file mode 100644 index 0000000..447ff2a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/DataLengthException.cs @@ -0,0 +1,42 @@ +using System; + +namespace Org.BouncyCastle.Crypto +{ + /** + * this exception is thrown if a buffer that is meant to have output + * copied into it turns out to be too short, or if we've been given + * insufficient input. In general this exception will Get thrown rather + * than an ArrayOutOfBounds exception. + */ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE) + [Serializable] +#endif + public class DataLengthException + : CryptoException + { + /** + * base constructor. + */ + public DataLengthException() + { + } + + /** + * create a DataLengthException with the given message. + * + * @param message the message to be carried with the exception. + */ + public DataLengthException( + string message) + : base(message) + { + } + + public DataLengthException( + string message, + Exception exception) + : base(message, exception) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/DataLengthException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/DataLengthException.cs.meta new file mode 100644 index 0000000..5746b0c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/DataLengthException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c80b5e5db74f5de4e9c483b686a9c9cf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IAlphabetMapper.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IAlphabetMapper.cs new file mode 100644 index 0000000..af63caa --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IAlphabetMapper.cs @@ -0,0 +1,32 @@ +using System; + +namespace Org.BouncyCastle.Crypto +{ +/** + * Base interface for mapping from an alphabet to a set of indexes + * suitable for use with FPE. + */ +public interface IAlphabetMapper +{ + /// + /// Return the number of characters in the alphabet. + /// + /// the radix for the alphabet. + int Radix { get; } + + /// + /// Return the passed in char[] as a byte array of indexes (indexes + /// can be more than 1 byte) + /// + /// an index array. + /// characters to be mapped. + byte[] ConvertToIndexes(char[] input); + + /// + /// Return a char[] for this alphabet based on the indexes passed. + /// + /// an array of char corresponding to the index values. + /// input array of indexes. + char[] ConvertToChars(byte[] input); +} +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IAlphabetMapper.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IAlphabetMapper.cs.meta new file mode 100644 index 0000000..8e21e88 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IAlphabetMapper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 446171df707cbb049a85e6a78b78bc0d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IAsymmetricBlockCipher.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IAsymmetricBlockCipher.cs new file mode 100644 index 0000000..455cfaa --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IAsymmetricBlockCipher.cs @@ -0,0 +1,30 @@ +using System; + +namespace Org.BouncyCastle.Crypto +{ + /// Base interface for a public/private key block cipher. + public interface IAsymmetricBlockCipher + { + /// The name of the algorithm this cipher implements. + string AlgorithmName { get; } + + /// Initialise the cipher. + /// Initialise for encryption if true, for decryption if false. + /// The key or other data required by the cipher. + void Init(bool forEncryption, ICipherParameters parameters); + + /// The maximum size, in bytes, an input block may be. + int GetInputBlockSize(); + + /// The maximum size, in bytes, an output block will be. + int GetOutputBlockSize(); + + /// Process a block. + /// The input buffer. + /// The offset into inBuf that the input block begins. + /// The length of the input block. + /// Input decrypts improperly. + /// Input is too large for the cipher. + byte[] ProcessBlock(byte[] inBuf, int inOff, int inLen); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IAsymmetricBlockCipher.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IAsymmetricBlockCipher.cs.meta new file mode 100644 index 0000000..964e65d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IAsymmetricBlockCipher.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5b87d012a1d0f4649a67322115a1a4dd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IAsymmetricCipherKeyPairGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IAsymmetricCipherKeyPairGenerator.cs new file mode 100644 index 0000000..9ec5dfa --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IAsymmetricCipherKeyPairGenerator.cs @@ -0,0 +1,24 @@ +using System; + +namespace Org.BouncyCastle.Crypto +{ + /** + * interface that a public/private key pair generator should conform to. + */ + public interface IAsymmetricCipherKeyPairGenerator + { + /** + * intialise the key pair generator. + * + * @param the parameters the key pair is to be initialised with. + */ + void Init(KeyGenerationParameters parameters); + + /** + * return an AsymmetricCipherKeyPair containing the Generated keys. + * + * @return an AsymmetricCipherKeyPair containing the Generated keys. + */ + AsymmetricCipherKeyPair GenerateKeyPair(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IAsymmetricCipherKeyPairGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IAsymmetricCipherKeyPairGenerator.cs.meta new file mode 100644 index 0000000..8ef4882 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IAsymmetricCipherKeyPairGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 82c0b6888748f4741a3f50054ca21fcf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IBasicAgreement.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IBasicAgreement.cs new file mode 100644 index 0000000..7dfc618 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IBasicAgreement.cs @@ -0,0 +1,29 @@ +using System; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto +{ + /** + * The basic interface that basic Diffie-Hellman implementations + * conforms to. + */ + public interface IBasicAgreement + { + /** + * initialise the agreement engine. + */ + void Init(ICipherParameters parameters); + + /** + * return the field size for the agreement algorithm in bytes. + */ + int GetFieldSize(); + + /** + * given a public key from a given party calculate the next + * message in the agreement sequence. + */ + BigInteger CalculateAgreement(ICipherParameters pubKey); + } + +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IBasicAgreement.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IBasicAgreement.cs.meta new file mode 100644 index 0000000..51b119b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IBasicAgreement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b62d1074c194c84439c2e9edbf6a4bf0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IBlockCipher.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IBlockCipher.cs new file mode 100644 index 0000000..a3ad6d6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IBlockCipher.cs @@ -0,0 +1,36 @@ +using System; + +namespace Org.BouncyCastle.Crypto +{ + /// Base interface for a symmetric key block cipher. + public interface IBlockCipher + { + /// The name of the algorithm this cipher implements. + string AlgorithmName { get; } + + /// Initialise the cipher. + /// Initialise for encryption if true, for decryption if false. + /// The key or other data required by the cipher. + void Init(bool forEncryption, ICipherParameters parameters); + + /// The block size for this cipher, in bytes. + int GetBlockSize(); + + /// Indicates whether this cipher can handle partial blocks. + bool IsPartialBlockOkay { get; } + + /// Process a block. + /// The input buffer. + /// The offset into inBuf that the input block begins. + /// The output buffer. + /// The offset into outBuf to write the output block. + /// If input block is wrong size, or outBuf too small. + /// The number of bytes processed and produced. + int ProcessBlock(byte[] inBuf, int inOff, byte[] outBuf, int outOff); + + /// + /// Reset the cipher to the same state as it was after the last init (if there was one). + /// + void Reset(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IBlockCipher.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IBlockCipher.cs.meta new file mode 100644 index 0000000..3bb386d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IBlockCipher.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5c21425501b0e5143b7cfe787cd92a91 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IBlockResult.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IBlockResult.cs new file mode 100644 index 0000000..0f054fe --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IBlockResult.cs @@ -0,0 +1,24 @@ + +namespace Org.BouncyCastle.Crypto +{ + /// + /// Operators that reduce their input to a single block return an object + /// of this type. + /// + public interface IBlockResult + { + /// + /// Return the final result of the operation. + /// + /// A block of bytes, representing the result of an operation. + byte[] Collect(); + + /// + /// Store the final result of the operation by copying it into the destination array. + /// + /// The number of bytes copied into destination. + /// The byte array to copy the result into. + /// The offset into destination to start copying the result at. + int Collect(byte[] destination, int offset); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IBlockResult.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IBlockResult.cs.meta new file mode 100644 index 0000000..ca0f8fb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IBlockResult.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1b99069ebcbe6314fbef7c437c55f58f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IBufferedCipher.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IBufferedCipher.cs new file mode 100644 index 0000000..69dec95 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IBufferedCipher.cs @@ -0,0 +1,44 @@ +using System; + +namespace Org.BouncyCastle.Crypto +{ + /// Block cipher engines are expected to conform to this interface. + public interface IBufferedCipher + { + /// The name of the algorithm this cipher implements. + string AlgorithmName { get; } + + /// Initialise the cipher. + /// If true the cipher is initialised for encryption, + /// if false for decryption. + /// The key and other data required by the cipher. + void Init(bool forEncryption, ICipherParameters parameters); + + int GetBlockSize(); + + int GetOutputSize(int inputLen); + + int GetUpdateOutputSize(int inputLen); + + byte[] ProcessByte(byte input); + int ProcessByte(byte input, byte[] output, int outOff); + + byte[] ProcessBytes(byte[] input); + byte[] ProcessBytes(byte[] input, int inOff, int length); + int ProcessBytes(byte[] input, byte[] output, int outOff); + int ProcessBytes(byte[] input, int inOff, int length, byte[] output, int outOff); + + byte[] DoFinal(); + byte[] DoFinal(byte[] input); + byte[] DoFinal(byte[] input, int inOff, int length); + int DoFinal(byte[] output, int outOff); + int DoFinal(byte[] input, byte[] output, int outOff); + int DoFinal(byte[] input, int inOff, int length, byte[] output, int outOff); + + /// + /// Reset the cipher. After resetting the cipher is in the same state + /// as it was after the last init (if there was one). + /// + void Reset(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IBufferedCipher.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IBufferedCipher.cs.meta new file mode 100644 index 0000000..305eb59 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IBufferedCipher.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2ca580b3b706a194899d63d4ca134d21 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ICipher.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ICipher.cs new file mode 100644 index 0000000..3768ee0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ICipher.cs @@ -0,0 +1,41 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto +{ + /// + /// Base interface for a ciphers that do not require data to be block aligned. + /// + /// Note: In cases where the underlying algorithm is block based, these ciphers may add or remove padding as needed. + /// + /// + public interface ICipher + { + /// + /// Return the size of the output buffer required for a Write() plus a + /// close() with the write() being passed inputLen bytes. + /// + /// The returned size may be dependent on the initialisation of this cipher + /// and may not be accurate once subsequent input data is processed as the cipher may + /// add, add or remove padding, as it sees fit. + /// + /// + /// The space required to accommodate a call to processBytes and doFinal with inputLen bytes of input. + /// The length of the expected input. + int GetMaxOutputSize(int inputLen); + + /// + /// Return the size of the output buffer required for a write() with the write() being + /// passed inputLen bytes and just updating the cipher output. + /// + /// The space required to accommodate a call to processBytes with inputLen bytes of input. + /// The length of the expected input. + int GetUpdateOutputSize(int inputLen); + + /// + /// Gets the stream for reading/writing data processed/to be processed. + /// + /// The stream associated with this cipher. + Stream Stream { get; } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ICipher.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ICipher.cs.meta new file mode 100644 index 0000000..fbf3237 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ICipher.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5a173c9ca4da3d54c93de6aad7f4a0a6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ICipherBuilder.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ICipherBuilder.cs new file mode 100644 index 0000000..9b0e2b3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ICipherBuilder.cs @@ -0,0 +1,30 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto +{ + /// + /// Base interface for cipher builders. + /// + public interface ICipherBuilder + { + /// + /// Return the algorithm and parameter details associated with any cipher built. + /// + object AlgorithmDetails { get; } + + /// + /// Return the maximum output size that a given input will produce. + /// + /// the length of the expected input. + /// The maximum possible output size that can produced for the expected input length. + int GetMaxOutputSize(int inputLen); + + /// + /// Build a cipher that operates on the passed in stream. + /// + /// The stream to write/read any encrypted/decrypted data. + /// A cipher based around the given stream. + ICipher BuildCipher(Stream stream); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ICipherBuilder.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ICipherBuilder.cs.meta new file mode 100644 index 0000000..137deec --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ICipherBuilder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c40139066763f164a9f001abfe02c58e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ICipherBuilderWithKey.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ICipherBuilderWithKey.cs new file mode 100644 index 0000000..8e79a5e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ICipherBuilderWithKey.cs @@ -0,0 +1,16 @@ +using System; + +namespace Org.BouncyCastle.Crypto +{ + /// + /// A cipher builder that can also return the key it was initialized with. + /// + public interface ICipherBuilderWithKey + : ICipherBuilder + { + /// + /// Return the key we were initialized with. + /// + ICipherParameters Key { get; } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ICipherBuilderWithKey.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ICipherBuilderWithKey.cs.meta new file mode 100644 index 0000000..9551286 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ICipherBuilderWithKey.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f863c489c1d725d44a7e7273f46c3fd7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ICipherParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ICipherParameters.cs new file mode 100644 index 0000000..fff0941 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ICipherParameters.cs @@ -0,0 +1,11 @@ +using System; + +namespace Org.BouncyCastle.Crypto +{ + /** + * all parameter classes implement this. + */ + public interface ICipherParameters + { + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ICipherParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ICipherParameters.cs.meta new file mode 100644 index 0000000..9df134d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ICipherParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7463c128e8b47174cb00388bf1077384 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IDSA.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IDSA.cs new file mode 100644 index 0000000..7d1fd51 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IDSA.cs @@ -0,0 +1,41 @@ +using System; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto +{ + /** + * interface for classes implementing the Digital Signature Algorithm + */ + public interface IDsa + { + string AlgorithmName { get; } + + /** + * initialise the signer for signature generation or signature + * verification. + * + * @param forSigning true if we are generating a signature, false + * otherwise. + * @param param key parameters for signature generation. + */ + void Init(bool forSigning, ICipherParameters parameters); + + /** + * sign the passed in message (usually the output of a hash function). + * + * @param message the message to be signed. + * @return two big integers representing the r and s values respectively. + */ + BigInteger[] GenerateSignature(byte[] message); + + /** + * verify the message message against the signature values r and s. + * + * @param message the message that was supposed to have been signed. + * @param r the r signature value. + * @param s the s signature value. + */ + bool VerifySignature(byte[] message, BigInteger r, BigInteger s); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IDSA.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IDSA.cs.meta new file mode 100644 index 0000000..cdfba12 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IDSA.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0ec79256fe03ad347a207bb83cddb9cb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IDecryptorBuilderProvider.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IDecryptorBuilderProvider.cs new file mode 100644 index 0000000..42ef2be --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IDecryptorBuilderProvider.cs @@ -0,0 +1,17 @@ +using System; + +namespace Org.BouncyCastle.Crypto +{ + /// + /// Interface describing a provider of cipher builders for creating decrypting ciphers. + /// + public interface IDecryptorBuilderProvider + { + /// + /// Return a cipher builder for creating decrypting ciphers. + /// + /// The algorithm details/parameters to use to create the final cipher. + /// A new cipher builder. + ICipherBuilder CreateDecryptorBuilder(object algorithmDetails); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IDecryptorBuilderProvider.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IDecryptorBuilderProvider.cs.meta new file mode 100644 index 0000000..9d540de --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IDecryptorBuilderProvider.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 54274f849101dcf4e94e9217f20b1fea +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IDerivationFunction.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IDerivationFunction.cs new file mode 100644 index 0000000..7f289f7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IDerivationFunction.cs @@ -0,0 +1,24 @@ +using System; + +namespace Org.BouncyCastle.Crypto +{ + /** + * base interface for general purpose byte derivation functions. + */ + public interface IDerivationFunction + { + void Init(IDerivationParameters parameters); + + /** + * return the message digest used as the basis for the function + */ + IDigest Digest + { + get; + } + + int GenerateBytes(byte[] output, int outOff, int length); + //throws DataLengthException, ArgumentException; + } + +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IDerivationFunction.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IDerivationFunction.cs.meta new file mode 100644 index 0000000..dec9148 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IDerivationFunction.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 195564955c3a3354b9d9d4c53baf8bf7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IDerivationParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IDerivationParameters.cs new file mode 100644 index 0000000..f1c8485 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IDerivationParameters.cs @@ -0,0 +1,11 @@ +using System; + +namespace Org.BouncyCastle.Crypto +{ + /** + * Parameters for key/byte stream derivation classes + */ + public interface IDerivationParameters + { + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IDerivationParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IDerivationParameters.cs.meta new file mode 100644 index 0000000..0b524da --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IDerivationParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0b1d6874ddf96624e9d94b27b79b43d2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IDigest.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IDigest.cs new file mode 100644 index 0000000..6769dcc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IDigest.cs @@ -0,0 +1,61 @@ +using System; + +namespace Org.BouncyCastle.Crypto +{ + /** + * interface that a message digest conforms to. + */ + public interface IDigest + { + /** + * return the algorithm name + * + * @return the algorithm name + */ + string AlgorithmName { get; } + + /** + * return the size, in bytes, of the digest produced by this message digest. + * + * @return the size, in bytes, of the digest produced by this message digest. + */ + int GetDigestSize(); + + /** + * return the size, in bytes, of the internal buffer used by this digest. + * + * @return the size, in bytes, of the internal buffer used by this digest. + */ + int GetByteLength(); + + /** + * update the message digest with a single byte. + * + * @param inByte the input byte to be entered. + */ + void Update(byte input); + + /** + * update the message digest with a block of bytes. + * + * @param input the byte array containing the data. + * @param inOff the offset into the byte array where the data starts. + * @param len the length of the data. + */ + void BlockUpdate(byte[] input, int inOff, int length); + + /** + * Close the digest, producing the final digest value. The doFinal + * call leaves the digest reset. + * + * @param output the array the digest is to be copied into. + * @param outOff the offset into the out array the digest is to start at. + */ + int DoFinal(byte[] output, int outOff); + + /** + * reset the digest back to it's initial state. + */ + void Reset(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IDigest.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IDigest.cs.meta new file mode 100644 index 0000000..7745da7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IDigest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a2b3c1f81ded6fa46ad563c7e2502815 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IDigestFactory.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IDigestFactory.cs new file mode 100644 index 0000000..eedac14 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IDigestFactory.cs @@ -0,0 +1,25 @@ +using System; + +namespace Org.BouncyCastle.Crypto +{ + /// + /// Base interface for operator factories that create stream-based digest calculators. + /// + public interface IDigestFactory + { + /// The algorithm details object for calculators made by this factory. + object AlgorithmDetails { get ; } + + /// Return the size of the digest associated with this factory. + /// The length of the digest produced by this calculators from this factory in bytes. + int DigestLength { get; } + + /// + /// Create a stream calculator for the digest associated with this factory. The stream + /// calculator is used for the actual operation of entering the data to be digested + /// and producing the digest block. + /// + /// A calculator producing an IBlockResult with the final digest in it. + IStreamCalculator CreateCalculator(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IDigestFactory.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IDigestFactory.cs.meta new file mode 100644 index 0000000..8ae4ba6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IDigestFactory.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f18ef02769c587c4b8be156a82357614 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IDsaExt.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IDsaExt.cs new file mode 100644 index 0000000..15b5578 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IDsaExt.cs @@ -0,0 +1,17 @@ +using System; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto +{ + /// + /// An "extended" interface for classes implementing DSA-style algorithms, that provides access + /// to the group order. + /// + public interface IDsaExt + : IDsa + { + /// The order of the group that the r, s values in signatures belong to. + BigInteger Order { get; } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IDsaExt.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IDsaExt.cs.meta new file mode 100644 index 0000000..d7e6d2c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IDsaExt.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ec41a625105ce3849a0485d73bd3a01c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IEntropySource.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IEntropySource.cs new file mode 100644 index 0000000..62e3bc7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IEntropySource.cs @@ -0,0 +1,29 @@ +using System; + +namespace Org.BouncyCastle.Crypto +{ + /// + /// Base interface describing an entropy source for a DRBG. + /// + public interface IEntropySource + { + /// + /// Return whether or not this entropy source is regarded as prediction resistant. + /// + /// true if this instance is prediction resistant; otherwise, false. + bool IsPredictionResistant { get; } + + /// + /// Return a byte array of entropy. + /// + /// The entropy bytes. + byte[] GetEntropy(); + + /// + /// Return the number of bits of entropy this source can produce. + /// + /// The size, in bits, of the return value of getEntropy. + int EntropySize { get; } + } +} + diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IEntropySource.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IEntropySource.cs.meta new file mode 100644 index 0000000..2c74d1d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IEntropySource.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c1e55d2fdaa9d4c459d4f96b01208f2a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IEntropySourceProvider.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IEntropySourceProvider.cs new file mode 100644 index 0000000..7564141 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IEntropySourceProvider.cs @@ -0,0 +1,17 @@ +using System; + +namespace Org.BouncyCastle.Crypto +{ + /// + /// Base interface describing a provider of entropy sources. + /// + public interface IEntropySourceProvider + { + /// + /// Return an entropy source providing a block of entropy. + /// + /// The size of the block of entropy required. + /// An entropy source providing bitsRequired blocks of entropy. + IEntropySource Get(int bitsRequired); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IEntropySourceProvider.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IEntropySourceProvider.cs.meta new file mode 100644 index 0000000..0481b3a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IEntropySourceProvider.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9588ae885e294a34f9a3d5983f942cf2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IKeyUnwrapper.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IKeyUnwrapper.cs new file mode 100644 index 0000000..18d5a8d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IKeyUnwrapper.cs @@ -0,0 +1,24 @@ +using System; + +namespace Org.BouncyCastle.Crypto +{ + /// + /// Base interface for a key unwrapper. + /// + public interface IKeyUnwrapper + { + /// + /// The parameter set used to configure this key unwrapper. + /// + object AlgorithmDetails { get; } + + /// + /// Unwrap the passed in data. + /// + /// The array containing the data to be unwrapped. + /// The offset into cipherText at which the unwrapped data starts. + /// The length of the data to be unwrapped. + /// an IBlockResult containing the unwrapped key data. + IBlockResult Unwrap(byte[] cipherText, int offset, int length); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IKeyUnwrapper.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IKeyUnwrapper.cs.meta new file mode 100644 index 0000000..8ef53f9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IKeyUnwrapper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8100fe5112f478d449f338df88f7db41 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IKeyWrapper.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IKeyWrapper.cs new file mode 100644 index 0000000..27f3384 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IKeyWrapper.cs @@ -0,0 +1,22 @@ +using System; + +namespace Org.BouncyCastle.Crypto +{ + /// + /// Base interface for a key wrapper. + /// + public interface IKeyWrapper + { + /// + /// The parameter set used to configure this key wrapper. + /// + object AlgorithmDetails { get; } + + /// + /// Wrap the passed in key data. + /// + /// The key data to be wrapped. + /// an IBlockResult containing the wrapped key data. + IBlockResult Wrap(byte[] keyData); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IKeyWrapper.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IKeyWrapper.cs.meta new file mode 100644 index 0000000..787ccc4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IKeyWrapper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 899ff94f95fe3ba46bec163b93c21e85 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IMac.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IMac.cs new file mode 100644 index 0000000..03a86e8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IMac.cs @@ -0,0 +1,69 @@ +using System; + +namespace Org.BouncyCastle.Crypto +{ + /** + * The base interface for implementations of message authentication codes (MACs). + */ + public interface IMac + { + /** + * Initialise the MAC. + * + * @param param the key and other data required by the MAC. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + void Init(ICipherParameters parameters); + + /** + * Return the name of the algorithm the MAC implements. + * + * @return the name of the algorithm the MAC implements. + */ + string AlgorithmName { get; } + + /** + * Return the block size for this MAC (in bytes). + * + * @return the block size for this MAC in bytes. + */ + int GetMacSize(); + + /** + * add a single byte to the mac for processing. + * + * @param in the byte to be processed. + * @exception InvalidOperationException if the MAC is not initialised. + */ + void Update(byte input); + + /** + * @param in the array containing the input. + * @param inOff the index in the array the data begins at. + * @param len the length of the input starting at inOff. + * @exception InvalidOperationException if the MAC is not initialised. + * @exception DataLengthException if there isn't enough data in in. + */ + void BlockUpdate(byte[] input, int inOff, int len); + + /** + * Compute the final stage of the MAC writing the output to the out + * parameter. + *

+ * doFinal leaves the MAC in the same state it was after the last init. + *

+ * @param out the array the MAC is to be output to. + * @param outOff the offset into the out buffer the output is to start at. + * @exception DataLengthException if there isn't enough space in out. + * @exception InvalidOperationException if the MAC is not initialised. + */ + int DoFinal(byte[] output, int outOff); + + /** + * Reset the MAC. At the end of resetting the MAC should be in the + * in the same state it was after the last init (if there was one). + */ + void Reset(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IMac.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IMac.cs.meta new file mode 100644 index 0000000..0e0733e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IMac.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1c7d7a1773c3b2c46bcc37a29388969f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IMacDerivationFunction.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IMacDerivationFunction.cs new file mode 100644 index 0000000..7297cd8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IMacDerivationFunction.cs @@ -0,0 +1,7 @@ +namespace Org.BouncyCastle.Crypto +{ + public interface IMacDerivationFunction:IDerivationFunction + { + IMac GetMac(); + } +} \ No newline at end of file diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IMacDerivationFunction.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IMacDerivationFunction.cs.meta new file mode 100644 index 0000000..89f07c8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IMacDerivationFunction.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2ab73a101c0e3fe4493f100fbedfd2cd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IMacFactory.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IMacFactory.cs new file mode 100644 index 0000000..9180ef1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IMacFactory.cs @@ -0,0 +1,18 @@ +using System; + +namespace Org.BouncyCastle.Crypto +{ + public interface IMacFactory + { + /// The algorithm details object for this calculator. + object AlgorithmDetails { get; } + + /// + /// Create a stream calculator for this signature calculator. The stream + /// calculator is used for the actual operation of entering the data to be signed + /// and producing the signature block. + /// + /// A calculator producing an IBlockResult with a signature in it. + IStreamCalculator CreateCalculator(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IMacFactory.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IMacFactory.cs.meta new file mode 100644 index 0000000..c163dd0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IMacFactory.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 15601c9d6c986f644a404fbdb20691f6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IRawAgreement.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IRawAgreement.cs new file mode 100644 index 0000000..63e6648 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IRawAgreement.cs @@ -0,0 +1,13 @@ +using System; + +namespace Org.BouncyCastle.Crypto +{ + public interface IRawAgreement + { + void Init(ICipherParameters parameters); + + int AgreementSize { get; } + + void CalculateAgreement(ICipherParameters publicKey, byte[] buf, int off); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IRawAgreement.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IRawAgreement.cs.meta new file mode 100644 index 0000000..ccdaebd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IRawAgreement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 813f263f43471fd42b0be5edfe1eedd5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IRsa.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IRsa.cs new file mode 100644 index 0000000..f7bcc9e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IRsa.cs @@ -0,0 +1,16 @@ +using System; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto +{ + public interface IRsa + { + void Init(bool forEncryption, ICipherParameters parameters); + int GetInputBlockSize(); + int GetOutputBlockSize(); + BigInteger ConvertInput(byte[] buf, int off, int len); + BigInteger ProcessBlock(BigInteger input); + byte[] ConvertOutput(BigInteger result); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IRsa.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IRsa.cs.meta new file mode 100644 index 0000000..34f30e9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IRsa.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5e23be80ba9241841a3682b32b6d9354 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ISignatureFactory.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ISignatureFactory.cs new file mode 100644 index 0000000..cbca7d1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ISignatureFactory.cs @@ -0,0 +1,23 @@ +using System; + +namespace Org.BouncyCastle.Crypto +{ + /// + /// Base interface for operators that serve as stream-based signature calculators. + /// + public interface ISignatureFactory + { + /// The algorithm details object for this calculator. + Object AlgorithmDetails { get ; } + + /// + /// Create a stream calculator for this signature calculator. The stream + /// calculator is used for the actual operation of entering the data to be signed + /// and producing the signature block. + /// + /// A calculator producing an IBlockResult with a signature in it. + IStreamCalculator CreateCalculator(); + } +} + + diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ISignatureFactory.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ISignatureFactory.cs.meta new file mode 100644 index 0000000..2f71b0b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ISignatureFactory.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4394f80936ff9384583834fb1b124456 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ISigner.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ISigner.cs new file mode 100644 index 0000000..e03bbf4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ISigner.cs @@ -0,0 +1,50 @@ + +using System; +using System.Text; + +namespace Org.BouncyCastle.Crypto +{ + public interface ISigner + { + /** + * Return the name of the algorithm the signer implements. + * + * @return the name of the algorithm the signer implements. + */ + string AlgorithmName { get; } + + /** + * Initialise the signer for signing or verification. + * + * @param forSigning true if for signing, false otherwise + * @param param necessary parameters. + */ + void Init(bool forSigning, ICipherParameters parameters); + + /** + * update the internal digest with the byte b + */ + void Update(byte input); + + /** + * update the internal digest with the byte array in + */ + void BlockUpdate(byte[] input, int inOff, int length); + + /** + * Generate a signature for the message we've been loaded with using + * the key we were initialised with. + */ + byte[] GenerateSignature(); + /** + * return true if the internal state represents the signature described + * in the passed in array. + */ + bool VerifySignature(byte[] signature); + + /** + * reset the internal state + */ + void Reset(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ISigner.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ISigner.cs.meta new file mode 100644 index 0000000..4de1b5f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ISigner.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e13422ba27b44944488a1eb78c3ec1ef +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ISignerWithRecovery.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ISignerWithRecovery.cs new file mode 100644 index 0000000..024f5ce --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ISignerWithRecovery.cs @@ -0,0 +1,37 @@ +using System; +using System.Text; + +namespace Org.BouncyCastle.Crypto +{ + /** + * Signer with message recovery. + */ + public interface ISignerWithRecovery + : ISigner + { + /** + * Returns true if the signer has recovered the full message as + * part of signature verification. + * + * @return true if full message recovered. + */ + bool HasFullMessage(); + + /** + * Returns a reference to what message was recovered (if any). + * + * @return full/partial message, null if nothing. + */ + byte[] GetRecoveredMessage(); + + /** + * Perform an update with the recovered message before adding any other data. This must + * be the first update method called, and calling it will result in the signer assuming + * that further calls to update will include message content past what is recoverable. + * + * @param signature the signature that we are in the process of verifying. + * @throws IllegalStateException + */ + void UpdateWithRecoveredMessage(byte[] signature); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ISignerWithRecovery.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ISignerWithRecovery.cs.meta new file mode 100644 index 0000000..83ead1b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ISignerWithRecovery.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fd7cb685945ff3c4aa3241ade7a9b96d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IStreamCalculator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IStreamCalculator.cs new file mode 100644 index 0000000..19a5428 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IStreamCalculator.cs @@ -0,0 +1,23 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto +{ + /// + /// Base interface for cryptographic operations such as Hashes, MACs, and Signatures which reduce a stream of data + /// to a single value. + /// + public interface IStreamCalculator + { + /// Return a "sink" stream which only exists to update the implementing object. + /// A stream to write to in order to update the implementing object. + Stream Stream { get; } + + /// + /// Return the result of processing the stream. This value is only available once the stream + /// has been closed. + /// + /// The result of processing the stream. + Object GetResult(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IStreamCalculator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IStreamCalculator.cs.meta new file mode 100644 index 0000000..f04946e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IStreamCalculator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 06ba3a127d090e84b8b5129c5f87ea0a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IStreamCipher.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IStreamCipher.cs new file mode 100644 index 0000000..8e575a7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IStreamCipher.cs @@ -0,0 +1,45 @@ +using System; + +namespace Org.BouncyCastle.Crypto +{ + /// The interface stream ciphers conform to. + public interface IStreamCipher + { + /// The name of the algorithm this cipher implements. + string AlgorithmName { get; } + + /// Initialise the cipher. + /// If true the cipher is initialised for encryption, + /// if false for decryption. + /// The key and other data required by the cipher. + /// + /// If the parameters argument is inappropriate. + /// + void Init(bool forEncryption, ICipherParameters parameters); + + /// encrypt/decrypt a single byte returning the result. + /// the byte to be processed. + /// the result of processing the input byte. + byte ReturnByte(byte input); + + /// + /// Process a block of bytes from input putting the result into output. + /// + /// The input byte array. + /// + /// The offset into input where the data to be processed starts. + /// + /// The number of bytes to be processed. + /// The output buffer the processed bytes go into. + /// + /// The offset into output the processed data starts at. + /// + /// If the output buffer is too small. + void ProcessBytes(byte[] input, int inOff, int length, byte[] output, int outOff); + + /// + /// Reset the cipher to the same state as it was after the last init (if there was one). + /// + void Reset(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IStreamCipher.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IStreamCipher.cs.meta new file mode 100644 index 0000000..c836039 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IStreamCipher.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 95742030e9192e04ca0576f993f8a6fd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IVerifier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IVerifier.cs new file mode 100644 index 0000000..560cabf --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IVerifier.cs @@ -0,0 +1,25 @@ +namespace Org.BouncyCastle.Crypto +{ + /// + /// Operators that reduce their input to the validation of a signature produce this type. + /// + public interface IVerifier + { + /// + /// Return true if the passed in data matches what is expected by the verification result. + /// + /// The bytes representing the signature. + /// true if the signature verifies, false otherwise. + bool IsVerified(byte[] data); + + /// + /// Return true if the length bytes from off in the source array match the signature + /// expected by the verification result. + /// + /// Byte array containing the signature. + /// The offset into the source array where the signature starts. + /// The number of bytes in source making up the signature. + /// true if the signature verifies, false otherwise. + bool IsVerified(byte[] source, int off, int length); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IVerifier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IVerifier.cs.meta new file mode 100644 index 0000000..871e71a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IVerifier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7e0b863b384aa914f8b6834c0dc4603f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IVerifierFactory.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IVerifierFactory.cs new file mode 100644 index 0000000..9502b14 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IVerifierFactory.cs @@ -0,0 +1,21 @@ +using System; + +namespace Org.BouncyCastle.Crypto +{ + /// + /// Base interface for operators that serve as stream-based signature verifiers. + /// + public interface IVerifierFactory + { + /// The algorithm details object for this verifier. + Object AlgorithmDetails { get ; } + + /// + /// Create a stream calculator for this verifier. The stream + /// calculator is used for the actual operation of entering the data to be verified + /// and producing a result which can be used to verify the original signature. + /// + /// A calculator producing an IVerifier which can verify the signature. + IStreamCalculator CreateCalculator(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IVerifierFactory.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IVerifierFactory.cs.meta new file mode 100644 index 0000000..0ab164e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IVerifierFactory.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1d781554662e90a409cb051128bbc190 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IVerifierFactoryProvider.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IVerifierFactoryProvider.cs new file mode 100644 index 0000000..9cfcbb2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IVerifierFactoryProvider.cs @@ -0,0 +1,18 @@ +using System; + +namespace Org.BouncyCastle.Crypto +{ + /// + /// Base interface for a provider to support the dynamic creation of signature verifiers. + /// + public interface IVerifierFactoryProvider + { + /// + /// Return a signature verfier for signature algorithm described in the passed in algorithm details object. + /// + /// The details of the signature algorithm verification is required for. + /// A new signature verifier. + IVerifierFactory CreateVerifierFactory (Object algorithmDetails); + } +} + diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IVerifierFactoryProvider.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IVerifierFactoryProvider.cs.meta new file mode 100644 index 0000000..b31f6e9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IVerifierFactoryProvider.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 38b96bde0844c414b8f14b8b569e56cc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IWrapper.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IWrapper.cs new file mode 100644 index 0000000..58202b3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IWrapper.cs @@ -0,0 +1,18 @@ +using System; + +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto +{ + public interface IWrapper + { + /// The name of the algorithm this cipher implements. + string AlgorithmName { get; } + + void Init(bool forWrapping, ICipherParameters parameters); + + byte[] Wrap(byte[] input, int inOff, int length); + + byte[] Unwrap(byte[] input, int inOff, int length); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IWrapper.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IWrapper.cs.meta new file mode 100644 index 0000000..2dd6753 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IWrapper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 08e0769d2a051ba409fd86832f4c682b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IXof.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IXof.cs new file mode 100644 index 0000000..f76304d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IXof.cs @@ -0,0 +1,31 @@ +using System; + +namespace Org.BouncyCastle.Crypto +{ + /// + /// With FIPS PUB 202 a new kind of message digest was announced which supported extendable output, or variable digest sizes. + /// This interface provides the extra method required to support variable output on a digest implementation. + /// + public interface IXof + : IDigest + { + /// + /// Output the results of the final calculation for this digest to outLen number of bytes. + /// + /// output array to write the output bytes to. + /// offset to start writing the bytes at. + /// the number of output bytes requested. + /// the number of bytes written + int DoFinal(byte[] output, int outOff, int outLen); + + /// + /// Start outputting the results of the final calculation for this digest. Unlike DoFinal, this method + /// will continue producing output until the Xof is explicitly reset, or signals otherwise. + /// + /// output array to write the output bytes to. + /// offset to start writing the bytes at. + /// the number of output bytes requested. + /// the number of bytes written + int DoOutput(byte[] output, int outOff, int outLen); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IXof.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IXof.cs.meta new file mode 100644 index 0000000..0aa1a0b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/IXof.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3332f41b6ab4afc41a54919a785a20bf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/InvalidCipherTextException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/InvalidCipherTextException.cs new file mode 100644 index 0000000..0fe540d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/InvalidCipherTextException.cs @@ -0,0 +1,40 @@ +using System; + +namespace Org.BouncyCastle.Crypto +{ + /** + * this exception is thrown whenever we find something we don't expect in a + * message. + */ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE) + [Serializable] +#endif + public class InvalidCipherTextException + : CryptoException + { + /** + * base constructor. + */ + public InvalidCipherTextException() + { + } + + /** + * create a InvalidCipherTextException with the given message. + * + * @param message the message to be carried with the exception. + */ + public InvalidCipherTextException( + string message) + : base(message) + { + } + + public InvalidCipherTextException( + string message, + Exception exception) + : base(message, exception) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/InvalidCipherTextException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/InvalidCipherTextException.cs.meta new file mode 100644 index 0000000..a6e6a15 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/InvalidCipherTextException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9da48350f6c7eb94c9f97becfb2a2346 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/KeyGenerationParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/KeyGenerationParameters.cs new file mode 100644 index 0000000..0cb6b07 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/KeyGenerationParameters.cs @@ -0,0 +1,55 @@ +using System; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto +{ + /** + * The base class for parameters to key generators. + */ + public class KeyGenerationParameters + { + private SecureRandom random; + private int strength; + + /** + * initialise the generator with a source of randomness + * and a strength (in bits). + * + * @param random the random byte source. + * @param strength the size, in bits, of the keys we want to produce. + */ + public KeyGenerationParameters( + SecureRandom random, + int strength) + { + if (random == null) + throw new ArgumentNullException("random"); + if (strength < 1) + throw new ArgumentException("strength must be a positive value", "strength"); + + this.random = random; + this.strength = strength; + } + + /** + * return the random source associated with this + * generator. + * + * @return the generators random source. + */ + public SecureRandom Random + { + get { return random; } + } + + /** + * return the bit strength for keys produced by this generator, + * + * @return the strength of the keys this generator produces (in bits). + */ + public int Strength + { + get { return strength; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/KeyGenerationParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/KeyGenerationParameters.cs.meta new file mode 100644 index 0000000..cec807b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/KeyGenerationParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1058744e76c9de344acba1a3ddb430f2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/MaxBytesExceededException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/MaxBytesExceededException.cs new file mode 100644 index 0000000..8992c45 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/MaxBytesExceededException.cs @@ -0,0 +1,32 @@ +using System; + +namespace Org.BouncyCastle.Crypto +{ + /// + /// This exception is thrown whenever a cipher requires a change of key, iv + /// or similar after x amount of bytes enciphered + /// +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE) + [Serializable] +#endif + public class MaxBytesExceededException + : CryptoException + { + public MaxBytesExceededException() + { + } + + public MaxBytesExceededException( + string message) + : base(message) + { + } + + public MaxBytesExceededException( + string message, + Exception e) + : base(message, e) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/MaxBytesExceededException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/MaxBytesExceededException.cs.meta new file mode 100644 index 0000000..904e747 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/MaxBytesExceededException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f840b9bd72939de4d933709491a60ace +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/OutputLengthException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/OutputLengthException.cs new file mode 100644 index 0000000..437589f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/OutputLengthException.cs @@ -0,0 +1,28 @@ +using System; + +namespace Org.BouncyCastle.Crypto +{ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE) + [Serializable] +#endif + public class OutputLengthException + : DataLengthException + { + public OutputLengthException() + { + } + + public OutputLengthException( + string message) + : base(message) + { + } + + public OutputLengthException( + string message, + Exception exception) + : base(message, exception) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/OutputLengthException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/OutputLengthException.cs.meta new file mode 100644 index 0000000..ff7b519 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/OutputLengthException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fff43b549f65bc44f96c81a89773f9b8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/PbeParametersGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/PbeParametersGenerator.cs new file mode 100644 index 0000000..97d23df --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/PbeParametersGenerator.cs @@ -0,0 +1,202 @@ +using System; +using System.Text; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto +{ + /** + * super class for all Password Based Encyrption (Pbe) parameter generator classes. + */ + public abstract class PbeParametersGenerator + { + protected byte[] mPassword; + protected byte[] mSalt; + protected int mIterationCount; + + /** + * base constructor. + */ + protected PbeParametersGenerator() + { + } + + /** + * initialise the Pbe generator. + * + * @param password the password converted into bytes (see below). + * @param salt the salt to be mixed with the password. + * @param iterationCount the number of iterations the "mixing" function + * is to be applied for. + */ + public virtual void Init( + byte[] password, + byte[] salt, + int iterationCount) + { + if (password == null) + throw new ArgumentNullException("password"); + if (salt == null) + throw new ArgumentNullException("salt"); + + this.mPassword = Arrays.Clone(password); + this.mSalt = Arrays.Clone(salt); + this.mIterationCount = iterationCount; + } + + public virtual byte[] Password + { + get { return Arrays.Clone(mPassword); } + } + + /** + * return the password byte array. + * + * @return the password byte array. + */ + [Obsolete("Use 'Password' property")] + public byte[] GetPassword() + { + return Password; + } + + public virtual byte[] Salt + { + get { return Arrays.Clone(mSalt); } + } + + /** + * return the salt byte array. + * + * @return the salt byte array. + */ + [Obsolete("Use 'Salt' property")] + public byte[] GetSalt() + { + return Salt; + } + + /** + * return the iteration count. + * + * @return the iteration count. + */ + public virtual int IterationCount + { + get { return mIterationCount; } + } + + /** + * Generate derived parameters for a key of length keySize. + * + * @param keySize the length, in bits, of the key required. + * @return a parameters object representing a key. + */ + [Obsolete("Use version with 'algorithm' parameter")] + public abstract ICipherParameters GenerateDerivedParameters(int keySize); + public abstract ICipherParameters GenerateDerivedParameters(string algorithm, int keySize); + + /** + * Generate derived parameters for a key of length keySize, and + * an initialisation vector (IV) of length ivSize. + * + * @param keySize the length, in bits, of the key required. + * @param ivSize the length, in bits, of the iv required. + * @return a parameters object representing a key and an IV. + */ + [Obsolete("Use version with 'algorithm' parameter")] + public abstract ICipherParameters GenerateDerivedParameters(int keySize, int ivSize); + public abstract ICipherParameters GenerateDerivedParameters(string algorithm, int keySize, int ivSize); + + /** + * Generate derived parameters for a key of length keySize, specifically + * for use with a MAC. + * + * @param keySize the length, in bits, of the key required. + * @return a parameters object representing a key. + */ + public abstract ICipherParameters GenerateDerivedMacParameters(int keySize); + + /** + * converts a password to a byte array according to the scheme in + * Pkcs5 (ascii, no padding) + * + * @param password a character array representing the password. + * @return a byte array representing the password. + */ + public static byte[] Pkcs5PasswordToBytes( + char[] password) + { + if (password == null) + return new byte[0]; + + return Strings.ToByteArray(password); + } + + [Obsolete("Use version taking 'char[]' instead")] + public static byte[] Pkcs5PasswordToBytes( + string password) + { + if (password == null) + return new byte[0]; + + return Strings.ToByteArray(password); + } + + /** + * converts a password to a byte array according to the scheme in + * PKCS5 (UTF-8, no padding) + * + * @param password a character array representing the password. + * @return a byte array representing the password. + */ + public static byte[] Pkcs5PasswordToUtf8Bytes( + char[] password) + { + if (password == null) + return new byte[0]; + + return Encoding.UTF8.GetBytes(password); + } + + [Obsolete("Use version taking 'char[]' instead")] + public static byte[] Pkcs5PasswordToUtf8Bytes( + string password) + { + if (password == null) + return new byte[0]; + + return Encoding.UTF8.GetBytes(password); + } + + /** + * converts a password to a byte array according to the scheme in + * Pkcs12 (unicode, big endian, 2 zero pad bytes at the end). + * + * @param password a character array representing the password. + * @return a byte array representing the password. + */ + public static byte[] Pkcs12PasswordToBytes( + char[] password) + { + return Pkcs12PasswordToBytes(password, false); + } + + public static byte[] Pkcs12PasswordToBytes( + char[] password, + bool wrongPkcs12Zero) + { + if (password == null || password.Length < 1) + { + return new byte[wrongPkcs12Zero ? 2 : 0]; + } + + // +1 for extra 2 pad bytes. + byte[] bytes = new byte[(password.Length + 1) * 2]; + + Encoding.BigEndianUnicode.GetBytes(password, 0, password.Length, bytes, 0); + + return bytes; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/PbeParametersGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/PbeParametersGenerator.cs.meta new file mode 100644 index 0000000..7718e6b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/PbeParametersGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 76678b6e0cedacb479e31f1c57e39fa4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/Security.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/Security.cs new file mode 100644 index 0000000..f6f6924 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/Security.cs @@ -0,0 +1,76 @@ +using System; +using System.Text; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Modes; +using Org.BouncyCastle.Crypto.Paddings; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities.Encoders; + +namespace crypto +{ + public class Security + { + // USAGE + //var key = Security.GenerateText(32); + //var iv = Security.GenerateText(16); + //var encrypted = Security.Encrypt("MY SECRET", key, iv); + //var decrypted = Security.Decrypt(encrypted, key, iv); + + /// + /// Return a salted hash based on PBKDF2 for the UTF-8 encoding of the argument text. + /// + /// Provided key text + /// Base64 encoded string representing the salt + /// + public static string ComputeHash(string text, string salt) + { + byte[] data = Encoding.UTF8.GetBytes(text); + Sha512Digest sha = new Sha512Digest(); + Pkcs5S2ParametersGenerator gen = new Pkcs5S2ParametersGenerator(sha); + + gen.Init(data, Base64.Decode(salt), 2048); + + return Base64.ToBase64String(((KeyParameter)gen.GenerateDerivedParameters(sha.GetDigestSize() * 8)).GetKey()); + } + + public static string Decrypt(string cipherText, string key, string iv) + { + IBufferedCipher cipher = CreateCipher(false, key, iv); + byte[] textAsBytes = cipher.DoFinal(Base64.Decode(cipherText)); + + return Encoding.UTF8.GetString(textAsBytes, 0, textAsBytes.Length); + } + + public static string Encrypt(string plainText, string key, string iv) + { + IBufferedCipher cipher = CreateCipher(true, key, iv); + + return Base64.ToBase64String(cipher.DoFinal(Encoding.UTF8.GetBytes(plainText))); + } + + public static string GenerateText(int size) + { + byte[] textAsBytes = new byte[size]; + SecureRandom secureRandom = SecureRandom.GetInstance("SHA256PRNG", true); + + secureRandom.NextBytes(textAsBytes); + return Base64.ToBase64String(textAsBytes); + } + + private static IBufferedCipher CreateCipher(bool isEncryption, string key, string iv) + { + IBufferedCipher cipher = new PaddedBufferedBlockCipher(new CbcBlockCipher(new RijndaelEngine()), new ISO10126d2Padding()); + KeyParameter keyParam = new KeyParameter(Base64.Decode(key)); + ICipherParameters cipherParams = (null == iv || iv.Length < 1) + ? (ICipherParameters)keyParam + : new ParametersWithIV(keyParam, Base64.Decode(iv)); + cipher.Init(isEncryption, cipherParams); + return cipher; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/Security.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/Security.cs.meta new file mode 100644 index 0000000..6bf2122 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/Security.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: aa9287951a89efd45ba88a0bbc538226 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/SimpleBlockResult.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/SimpleBlockResult.cs new file mode 100644 index 0000000..6cacda6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/SimpleBlockResult.cs @@ -0,0 +1,53 @@ +using System; + +namespace Org.BouncyCastle.Crypto +{ + /// + /// A simple block result object which just carries a byte array. + /// + public class SimpleBlockResult + : IBlockResult + { + private readonly byte[] result; + + /// + /// Base constructor - a wrapper for the passed in byte array. + /// + /// The byte array to be wrapped. + public SimpleBlockResult(byte[] result) + { + this.result = result; + } + + /// + /// Return the number of bytes in the result + /// + /// The length of the result in bytes. + public int Length + { + get { return result.Length; } + } + + /// + /// Return the final result of the operation. + /// + /// A block of bytes, representing the result of an operation. + public byte[] Collect() + { + return result; + } + + /// + /// Store the final result of the operation by copying it into the destination array. + /// + /// The number of bytes copied into destination. + /// The byte array to copy the result into. + /// The offset into destination to start copying the result at. + public int Collect(byte[] destination, int offset) + { + Array.Copy(result, 0, destination, offset, result.Length); + + return result.Length; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/SimpleBlockResult.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/SimpleBlockResult.cs.meta new file mode 100644 index 0000000..30cdae6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/SimpleBlockResult.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0e9a13b50308fb94caeaa8709fcfb683 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/StreamBlockCipher.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/StreamBlockCipher.cs new file mode 100644 index 0000000..ef2a8b6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/StreamBlockCipher.cs @@ -0,0 +1,109 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto +{ + /** + * a wrapper for block ciphers with a single byte block size, so that they + * can be treated like stream ciphers. + */ + public class StreamBlockCipher + : IStreamCipher + { + private readonly IBlockCipher cipher; + private readonly byte[] oneByte = new byte[1]; + + /** + * basic constructor. + * + * @param cipher the block cipher to be wrapped. + * @exception ArgumentException if the cipher has a block size other than + * one. + */ + public StreamBlockCipher( + IBlockCipher cipher) + { + if (cipher == null) + throw new ArgumentNullException("cipher"); + if (cipher.GetBlockSize() != 1) + throw new ArgumentException("block cipher block size != 1.", "cipher"); + + this.cipher = cipher; + } + + /** + * initialise the underlying cipher. + * + * @param forEncryption true if we are setting up for encryption, false otherwise. + * @param param the necessary parameters for the underlying cipher to be initialised. + */ + public void Init( + bool forEncryption, + ICipherParameters parameters) + { + cipher.Init(forEncryption, parameters); + } + + /** + * return the name of the algorithm we are wrapping. + * + * @return the name of the algorithm we are wrapping. + */ + public string AlgorithmName + { + get { return cipher.AlgorithmName; } + } + + /** + * encrypt/decrypt a single byte returning the result. + * + * @param in the byte to be processed. + * @return the result of processing the input byte. + */ + public byte ReturnByte( + byte input) + { + oneByte[0] = input; + + cipher.ProcessBlock(oneByte, 0, oneByte, 0); + + return oneByte[0]; + } + + /** + * process a block of bytes from in putting the result into out. + * + * @param in the input byte array. + * @param inOff the offset into the in array where the data to be processed starts. + * @param len the number of bytes to be processed. + * @param out the output buffer the processed bytes go into. + * @param outOff the offset into the output byte array the processed data stars at. + * @exception DataLengthException if the output buffer is too small. + */ + public void ProcessBytes( + byte[] input, + int inOff, + int length, + byte[] output, + int outOff) + { + if (outOff + length > output.Length) + throw new DataLengthException("output buffer too small in ProcessBytes()"); + + for (int i = 0; i != length; i++) + { + cipher.ProcessBlock(input, inOff + i, output, outOff + i); + } + } + + /** + * reset the underlying cipher. This leaves it in the same state + * it was at after the last init (if there was one). + */ + public void Reset() + { + cipher.Reset(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/StreamBlockCipher.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/StreamBlockCipher.cs.meta new file mode 100644 index 0000000..e51c9ca --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/StreamBlockCipher.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c777c69ef94082d499141211aa6fa677 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement.meta new file mode 100644 index 0000000..5858f5d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 6167ded586c51214b964a970d2a4298a +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/DHAgreement.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/DHAgreement.cs new file mode 100644 index 0000000..e988c0d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/DHAgreement.cs @@ -0,0 +1,99 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Agreement +{ + /** + * a Diffie-Hellman key exchange engine. + *

+ * note: This uses MTI/A0 key agreement in order to make the key agreement + * secure against passive attacks. If you're doing Diffie-Hellman and both + * parties have long term public keys you should look at using this. For + * further information have a look at RFC 2631.

+ *

+ * It's possible to extend this to more than two parties as well, for the moment + * that is left as an exercise for the reader.

+ */ + public class DHAgreement + { + private DHPrivateKeyParameters key; + private DHParameters dhParams; + private BigInteger privateValue; + private SecureRandom random; + + public void Init( + ICipherParameters parameters) + { + AsymmetricKeyParameter kParam; + if (parameters is ParametersWithRandom) + { + ParametersWithRandom rParam = (ParametersWithRandom)parameters; + + this.random = rParam.Random; + kParam = (AsymmetricKeyParameter)rParam.Parameters; + } + else + { + this.random = new SecureRandom(); + kParam = (AsymmetricKeyParameter)parameters; + } + + if (!(kParam is DHPrivateKeyParameters)) + { + throw new ArgumentException("DHEngine expects DHPrivateKeyParameters"); + } + + this.key = (DHPrivateKeyParameters)kParam; + this.dhParams = key.Parameters; + } + + /** + * calculate our initial message. + */ + public BigInteger CalculateMessage() + { + DHKeyPairGenerator dhGen = new DHKeyPairGenerator(); + dhGen.Init(new DHKeyGenerationParameters(random, dhParams)); + AsymmetricCipherKeyPair dhPair = dhGen.GenerateKeyPair(); + + this.privateValue = ((DHPrivateKeyParameters)dhPair.Private).X; + + return ((DHPublicKeyParameters)dhPair.Public).Y; + } + + /** + * given a message from a given party and the corresponding public key + * calculate the next message in the agreement sequence. In this case + * this will represent the shared secret. + */ + public BigInteger CalculateAgreement( + DHPublicKeyParameters pub, + BigInteger message) + { + if (pub == null) + throw new ArgumentNullException("pub"); + if (message == null) + throw new ArgumentNullException("message"); + + if (!pub.Parameters.Equals(dhParams)) + throw new ArgumentException("Diffie-Hellman public key has wrong parameters."); + + BigInteger p = dhParams.P; + + BigInteger peerY = pub.Y; + if (peerY == null || peerY.CompareTo(BigInteger.One) <= 0 || peerY.CompareTo(p.Subtract(BigInteger.One)) >= 0) + throw new ArgumentException("Diffie-Hellman public key is weak"); + + BigInteger result = peerY.ModPow(privateValue, p); + if (result.Equals(BigInteger.One)) + throw new InvalidOperationException("Shared key can't be 1"); + + return message.ModPow(key.X, p).Multiply(result).Mod(p); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/DHAgreement.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/DHAgreement.cs.meta new file mode 100644 index 0000000..a94e0d7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/DHAgreement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 48949323999f1dc479f0c42bde40dec9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/DHBasicAgreement.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/DHBasicAgreement.cs new file mode 100644 index 0000000..6c3fe65 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/DHBasicAgreement.cs @@ -0,0 +1,72 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Agreement +{ + /** + * a Diffie-Hellman key agreement class. + *

+ * note: This is only the basic algorithm, it doesn't take advantage of + * long term public keys if they are available. See the DHAgreement class + * for a "better" implementation.

+ */ + public class DHBasicAgreement + : IBasicAgreement + { + private DHPrivateKeyParameters key; + private DHParameters dhParams; + + public virtual void Init( + ICipherParameters parameters) + { + if (parameters is ParametersWithRandom) + { + parameters = ((ParametersWithRandom) parameters).Parameters; + } + + if (!(parameters is DHPrivateKeyParameters)) + { + throw new ArgumentException("DHEngine expects DHPrivateKeyParameters"); + } + + this.key = (DHPrivateKeyParameters) parameters; + this.dhParams = key.Parameters; + } + + public virtual int GetFieldSize() + { + return (key.Parameters.P.BitLength + 7) / 8; + } + + /** + * given a short term public key from a given party calculate the next + * message in the agreement sequence. + */ + public virtual BigInteger CalculateAgreement( + ICipherParameters pubKey) + { + if (this.key == null) + throw new InvalidOperationException("Agreement algorithm not initialised"); + + DHPublicKeyParameters pub = (DHPublicKeyParameters)pubKey; + + if (!pub.Parameters.Equals(dhParams)) + throw new ArgumentException("Diffie-Hellman public key has wrong parameters."); + + BigInteger p = dhParams.P; + + BigInteger peerY = pub.Y; + if (peerY == null || peerY.CompareTo(BigInteger.One) <= 0 || peerY.CompareTo(p.Subtract(BigInteger.One)) >= 0) + throw new ArgumentException("Diffie-Hellman public key is weak"); + + BigInteger result = peerY.ModPow(key.X, p); + if (result.Equals(BigInteger.One)) + throw new InvalidOperationException("Shared key can't be 1"); + + return result; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/DHBasicAgreement.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/DHBasicAgreement.cs.meta new file mode 100644 index 0000000..5360f2d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/DHBasicAgreement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 837ad000448541340a4243941dd4537d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/DHStandardGroups.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/DHStandardGroups.cs new file mode 100644 index 0000000..e334489 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/DHStandardGroups.cs @@ -0,0 +1,249 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Crypto.Agreement +{ + /// Standard Diffie-Hellman groups from various IETF specifications. + public class DHStandardGroups + { + private static readonly BigInteger Two = BigInteger.ValueOf(2); + + private static BigInteger FromHex(string hex) + { + return new BigInteger(1, Hex.DecodeStrict(hex)); + } + + private static DHParameters FromPG(string hexP, string hexG) + { + return new DHParameters(FromHex(hexP), FromHex(hexG)); + } + + private static DHParameters SafePrimeGen2(string hexP) + { + return SafePrimeGen2(hexP, 0); + } + + private static DHParameters SafePrimeGen2(string hexP, int l) + { + // NOTE: A group using a safe prime (i.e. q = (p-1)/2), and generator g = 2 + BigInteger p = FromHex(hexP); + return new DHParameters(p, Two, p.ShiftRight(1), l); + } + + /* + * RFC 2409 + */ + private static readonly string rfc2409_768_p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + + "E485B576625E7EC6F44C42E9A63A3620FFFFFFFFFFFFFFFF"; + public static readonly DHParameters rfc2409_768 = SafePrimeGen2(rfc2409_768_p); + + private static readonly string rfc2409_1024_p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381" + + "FFFFFFFFFFFFFFFF"; + public static readonly DHParameters rfc2409_1024 = SafePrimeGen2(rfc2409_1024_p); + + /* + * RFC 3526 + */ + private static readonly string rfc3526_1536_p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" + + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" + "83655D23DCA3AD961C62F356208552BB9ED529077096966D" + + "670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF"; + private static readonly int rfc3526_1536_l = 200; // RFC3526/RFC7919 + public static readonly DHParameters rfc3526_1536 = SafePrimeGen2(rfc3526_1536_p, rfc3526_1536_l); + + private static readonly string rfc3526_2048_p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" + + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" + "83655D23DCA3AD961C62F356208552BB9ED529077096966D" + + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" + + "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" + "15728E5A8AACAA68FFFFFFFFFFFFFFFF"; + private static readonly int rfc3526_2048_l = System.Math.Max(225, 112 * 2); // MAX(RFC3526/RFC7919,FIPS) + public static readonly DHParameters rfc3526_2048 = SafePrimeGen2(rfc3526_2048_p, rfc3526_2048_l); + + private static readonly string rfc3526_3072_p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" + + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" + "83655D23DCA3AD961C62F356208552BB9ED529077096966D" + + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" + + "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" + "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" + + "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" + "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" + + "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" + + "43DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF"; + private static readonly int rfc3526_3072_l = System.Math.Max(275, 128 * 2); // MAX(RFC3526/RFC7919,FIPS) + public static readonly DHParameters rfc3526_3072 = SafePrimeGen2(rfc3526_3072_p, rfc3526_3072_l); + + private static readonly string rfc3526_4096_p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" + + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" + "83655D23DCA3AD961C62F356208552BB9ED529077096966D" + + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" + + "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" + "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" + + "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" + "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" + + "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" + + "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7" + "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA" + + "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6" + "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED" + + "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9" + "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199" + + "FFFFFFFFFFFFFFFF"; + private static readonly int rfc3526_4096_l = System.Math.Max(325, 152 * 2); // MAX(RFC3526/RFC7919,FIPS) + public static readonly DHParameters rfc3526_4096 = SafePrimeGen2(rfc3526_4096_p, rfc3526_4096_l); + + private static readonly string rfc3526_6144_p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E08" + + "8A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B" + + "302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9" + + "A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE6" + + "49286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8" + + "FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D" + + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C" + + "180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718" + + "3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D" + + "04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7D" + + "B3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D226" + + "1AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200C" + + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFC" + + "E0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B26" + + "99C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB" + + "04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2" + + "233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127" + + "D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492" + + "36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BDF8FF9406" + + "AD9E530EE5DB382F413001AEB06A53ED9027D831179727B0865A8918" + + "DA3EDBEBCF9B14ED44CE6CBACED4BB1BDB7F1447E6CC254B33205151" + + "2BD7AF426FB8F401378CD2BF5983CA01C64B92ECF032EA15D1721D03" + + "F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E59E7C97F" + + "BEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA" + + "CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58B" + + "B7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632" + + "387FE8D76E3C0468043E8F663F4860EE12BF2D5B0B7474D6E694F91E" + + "6DCC4024FFFFFFFFFFFFFFFF"; + private static readonly int rfc3526_6144_l = System.Math.Max(375, 176 * 2); // MAX(RFC3526/RFC7919,FIPS) + public static readonly DHParameters rfc3526_6144 = SafePrimeGen2(rfc3526_6144_p, rfc3526_6144_l); + + private static readonly string rfc3526_8192_p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" + + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" + "83655D23DCA3AD961C62F356208552BB9ED529077096966D" + + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" + + "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" + "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" + + "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" + "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" + + "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" + + "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7" + "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA" + + "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6" + "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED" + + "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9" + "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492" + + "36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BD" + "F8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831" + + "179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B" + "DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF" + + "5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6" + "D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F3" + + "23A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA" + "CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE328" + + "06A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55C" + "DA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE" + + "12BF2D5B0B7474D6E694F91E6DBE115974A3926F12FEE5E4" + "38777CB6A932DF8CD8BEC4D073B931BA3BC832B68D9DD300" + + "741FA7BF8AFC47ED2576F6936BA424663AAB639C5AE4F568" + "3423B4742BF1C978238F16CBE39D652DE3FDB8BEFC848AD9" + + "22222E04A4037C0713EB57A81A23F0C73473FC646CEA306B" + "4BCBC8862F8385DDFA9D4B7FA2C087E879683303ED5BDD3A" + + "062B3CF5B3A278A66D2A13F83F44F82DDF310EE074AB6A36" + "4597E899A0255DC164F31CC50846851DF9AB48195DED7EA1" + + "B1D510BD7EE74D73FAF36BC31ECFA268359046F4EB879F92" + "4009438B481C6CD7889A002ED5EE382BC9190DA6FC026E47" + + "9558E4475677E9AA9E3050E2765694DFC81F56E880B96E71" + "60C980DD98EDD3DFFFFFFFFFFFFFFFFF"; + private static readonly int rfc3526_8192_l = System.Math.Max(400, 200 * 2); // MAX(RFC3526/RFC7919,FIPS) + public static readonly DHParameters rfc3526_8192 = SafePrimeGen2(rfc3526_8192_p, rfc3526_8192_l); + + /* + * RFC 4306 + */ + public static readonly DHParameters rfc4306_768 = rfc2409_768; + public static readonly DHParameters rfc4306_1024 = rfc2409_1024; + + /* + * RFC 5996 + */ + public static readonly DHParameters rfc5996_768 = rfc4306_768; + public static readonly DHParameters rfc5996_1024 = rfc4306_1024; + + /* + * RFC 7919 + */ + private static readonly string rfc7919_ffdhe2048_p = "FFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1" + + "D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF9" + "7D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD6561" + + "2433F51F5F066ED0856365553DED1AF3B557135E7F57C935" + "984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE735" + + "30ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FB" + "B96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB19" + + "0B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F61" + "9172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD73" + + "3BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA" + "886B423861285C97FFFFFFFFFFFFFFFF"; + private static readonly int rfc7919_ffdhe2048_l = System.Math.Max(225, 112 * 2); // MAX(RFC7919,FIPS) + public static readonly DHParameters rfc7919_ffdhe2048 = SafePrimeGen2(rfc7919_ffdhe2048_p, rfc7919_ffdhe2048_l); + + private static readonly string rfc7919_ffdhe3072_p = "FFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1" + + "D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF9" + "7D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD6561" + + "2433F51F5F066ED0856365553DED1AF3B557135E7F57C935" + "984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE735" + + "30ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FB" + "B96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB19" + + "0B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F61" + "9172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD73" + + "3BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA" + "886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C0238" + + "61B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91C" + "AEFE130985139270B4130C93BC437944F4FD4452E2D74DD3" + + "64F2E21E71F54BFF5CAE82AB9C9DF69EE86D2BC522363A0D" + "ABC521979B0DEADA1DBF9A42D5C4484E0ABCD06BFA53DDEF" + + "3C1B20EE3FD59D7C25E41D2B66C62E37FFFFFFFFFFFFFFFF"; + private static readonly int rfc7919_ffdhe3072_l = System.Math.Max(275, 128 * 2); // MAX(RFC7919,FIPS) + public static readonly DHParameters rfc7919_ffdhe3072 = SafePrimeGen2(rfc7919_ffdhe3072_p, rfc7919_ffdhe3072_l); + + private static readonly string rfc7919_ffdhe4096_p = "FFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1" + + "D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF9" + "7D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD6561" + + "2433F51F5F066ED0856365553DED1AF3B557135E7F57C935" + "984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE735" + + "30ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FB" + "B96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB19" + + "0B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F61" + "9172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD73" + + "3BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA" + "886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C0238" + + "61B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91C" + "AEFE130985139270B4130C93BC437944F4FD4452E2D74DD3" + + "64F2E21E71F54BFF5CAE82AB9C9DF69EE86D2BC522363A0D" + "ABC521979B0DEADA1DBF9A42D5C4484E0ABCD06BFA53DDEF" + + "3C1B20EE3FD59D7C25E41D2B669E1EF16E6F52C3164DF4FB" + "7930E9E4E58857B6AC7D5F42D69F6D187763CF1D55034004" + + "87F55BA57E31CC7A7135C886EFB4318AED6A1E012D9E6832" + "A907600A918130C46DC778F971AD0038092999A333CB8B7A" + + "1A1DB93D7140003C2A4ECEA9F98D0ACC0A8291CDCEC97DCF" + "8EC9B55A7F88A46B4DB5A851F44182E1C68A007E5E655F6A" + + "FFFFFFFFFFFFFFFF"; + private static readonly int rfc7919_ffdhe4096_l = System.Math.Max(325, 152 * 2); // MAX(RFC7919,FIPS) + public static readonly DHParameters rfc7919_ffdhe4096 = SafePrimeGen2(rfc7919_ffdhe4096_p, rfc7919_ffdhe4096_l); + + private static readonly string rfc7919_ffdhe6144_p = "FFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1" + + "D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF9" + "7D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD6561" + + "2433F51F5F066ED0856365553DED1AF3B557135E7F57C935" + "984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE735" + + "30ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FB" + "B96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB19" + + "0B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F61" + "9172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD73" + + "3BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA" + "886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C0238" + + "61B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91C" + "AEFE130985139270B4130C93BC437944F4FD4452E2D74DD3" + + "64F2E21E71F54BFF5CAE82AB9C9DF69EE86D2BC522363A0D" + "ABC521979B0DEADA1DBF9A42D5C4484E0ABCD06BFA53DDEF" + + "3C1B20EE3FD59D7C25E41D2B669E1EF16E6F52C3164DF4FB" + "7930E9E4E58857B6AC7D5F42D69F6D187763CF1D55034004" + + "87F55BA57E31CC7A7135C886EFB4318AED6A1E012D9E6832" + "A907600A918130C46DC778F971AD0038092999A333CB8B7A" + + "1A1DB93D7140003C2A4ECEA9F98D0ACC0A8291CDCEC97DCF" + "8EC9B55A7F88A46B4DB5A851F44182E1C68A007E5E0DD902" + + "0BFD64B645036C7A4E677D2C38532A3A23BA4442CAF53EA6" + "3BB454329B7624C8917BDD64B1C0FD4CB38E8C334C701C3A" + + "CDAD0657FCCFEC719B1F5C3E4E46041F388147FB4CFDB477" + "A52471F7A9A96910B855322EDB6340D8A00EF092350511E3" + + "0ABEC1FFF9E3A26E7FB29F8C183023C3587E38DA0077D9B4" + "763E4E4B94B2BBC194C6651E77CAF992EEAAC0232A281BF6" + + "B3A739C1226116820AE8DB5847A67CBEF9C9091B462D538C" + "D72B03746AE77F5E62292C311562A846505DC82DB854338A" + + "E49F5235C95B91178CCF2DD5CACEF403EC9D1810C6272B04" + "5B3B71F9DC6B80D63FDD4A8E9ADB1E6962A69526D43161C1" + + "A41D570D7938DAD4A40E329CD0E40E65FFFFFFFFFFFFFFFF"; + private static readonly int rfc7919_ffdhe6144_l = System.Math.Max(375, 176 * 2); // MAX(RFC7919,FIPS) + public static readonly DHParameters rfc7919_ffdhe6144 = SafePrimeGen2(rfc7919_ffdhe6144_p, rfc7919_ffdhe6144_l); + + private static readonly string rfc7919_ffdhe8192_p = "FFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1" + + "D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF9" + "7D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD6561" + + "2433F51F5F066ED0856365553DED1AF3B557135E7F57C935" + "984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE735" + + "30ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FB" + "B96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB19" + + "0B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F61" + "9172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD73" + + "3BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA" + "886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C0238" + + "61B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91C" + "AEFE130985139270B4130C93BC437944F4FD4452E2D74DD3" + + "64F2E21E71F54BFF5CAE82AB9C9DF69EE86D2BC522363A0D" + "ABC521979B0DEADA1DBF9A42D5C4484E0ABCD06BFA53DDEF" + + "3C1B20EE3FD59D7C25E41D2B669E1EF16E6F52C3164DF4FB" + "7930E9E4E58857B6AC7D5F42D69F6D187763CF1D55034004" + + "87F55BA57E31CC7A7135C886EFB4318AED6A1E012D9E6832" + "A907600A918130C46DC778F971AD0038092999A333CB8B7A" + + "1A1DB93D7140003C2A4ECEA9F98D0ACC0A8291CDCEC97DCF" + "8EC9B55A7F88A46B4DB5A851F44182E1C68A007E5E0DD902" + + "0BFD64B645036C7A4E677D2C38532A3A23BA4442CAF53EA6" + "3BB454329B7624C8917BDD64B1C0FD4CB38E8C334C701C3A" + + "CDAD0657FCCFEC719B1F5C3E4E46041F388147FB4CFDB477" + "A52471F7A9A96910B855322EDB6340D8A00EF092350511E3" + + "0ABEC1FFF9E3A26E7FB29F8C183023C3587E38DA0077D9B4" + "763E4E4B94B2BBC194C6651E77CAF992EEAAC0232A281BF6" + + "B3A739C1226116820AE8DB5847A67CBEF9C9091B462D538C" + "D72B03746AE77F5E62292C311562A846505DC82DB854338A" + + "E49F5235C95B91178CCF2DD5CACEF403EC9D1810C6272B04" + "5B3B71F9DC6B80D63FDD4A8E9ADB1E6962A69526D43161C1" + + "A41D570D7938DAD4A40E329CCFF46AAA36AD004CF600C838" + "1E425A31D951AE64FDB23FCEC9509D43687FEB69EDD1CC5E" + + "0B8CC3BDF64B10EF86B63142A3AB8829555B2F747C932665" + "CB2C0F1CC01BD70229388839D2AF05E454504AC78B758282" + + "2846C0BA35C35F5C59160CC046FD8251541FC68C9C86B022" + "BB7099876A460E7451A8A93109703FEE1C217E6C3826E52C" + + "51AA691E0E423CFC99E9E31650C1217B624816CDAD9A95F9" + "D5B8019488D9C0A0A1FE3075A577E23183F81D4A3F2FA457" + + "1EFC8CE0BA8A4FE8B6855DFE72B0A66EDED2FBABFBE58A30" + "FAFABE1C5D71A87E2F741EF8C1FE86FEA6BBFDE530677F0D" + + "97D11D49F7A8443D0822E506A9F4614E011E2A94838FF88C" + "D68C8BB7C5C6424CFFFFFFFFFFFFFFFF"; + private static readonly int rfc7919_ffdhe8192_l = System.Math.Max(400, 200 * 2); // MAX(RFC7919,FIPS) + public static readonly DHParameters rfc7919_ffdhe8192 = SafePrimeGen2(rfc7919_ffdhe8192_p, rfc7919_ffdhe8192_l); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/DHStandardGroups.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/DHStandardGroups.cs.meta new file mode 100644 index 0000000..0430230 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/DHStandardGroups.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a990aa3daa9393b4892b377b682efae3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/ECDHBasicAgreement.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/ECDHBasicAgreement.cs new file mode 100644 index 0000000..1358db0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/ECDHBasicAgreement.cs @@ -0,0 +1,74 @@ +using System; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Agreement +{ + /** + * P1363 7.2.1 ECSVDP-DH + * + * ECSVDP-DH is Elliptic Curve Secret Value Derivation Primitive, + * Diffie-Hellman version. It is based on the work of [DH76], [Mil86], + * and [Kob87]. This primitive derives a shared secret value from one + * party's private key and another party's public key, where both have + * the same set of EC domain parameters. If two parties correctly + * execute this primitive, they will produce the same output. This + * primitive can be invoked by a scheme to derive a shared secret key; + * specifically, it may be used with the schemes ECKAS-DH1 and + * DL/ECKAS-DH2. It assumes that the input keys are valid (see also + * Section 7.2.2). + */ + public class ECDHBasicAgreement + : IBasicAgreement + { + protected internal ECPrivateKeyParameters privKey; + + public virtual void Init( + ICipherParameters parameters) + { + if (parameters is ParametersWithRandom) + { + parameters = ((ParametersWithRandom)parameters).Parameters; + } + + this.privKey = (ECPrivateKeyParameters)parameters; + } + + public virtual int GetFieldSize() + { + return (privKey.Parameters.Curve.FieldSize + 7) / 8; + } + + public virtual BigInteger CalculateAgreement( + ICipherParameters pubKey) + { + ECPublicKeyParameters pub = (ECPublicKeyParameters)pubKey; + ECDomainParameters dp = privKey.Parameters; + if (!dp.Equals(pub.Parameters)) + throw new InvalidOperationException("ECDH public key has wrong domain parameters"); + + BigInteger d = privKey.D; + + // Always perform calculations on the exact curve specified by our private key's parameters + ECPoint Q = ECAlgorithms.CleanPoint(dp.Curve, pub.Q); + if (Q.IsInfinity) + throw new InvalidOperationException("Infinity is not a valid public key for ECDH"); + + BigInteger h = dp.H; + if (!h.Equals(BigInteger.One)) + { + d = dp.HInv.Multiply(d).Mod(dp.N); + Q = ECAlgorithms.ReferenceMultiply(Q, h); + } + + ECPoint P = Q.Multiply(d).Normalize(); + if (P.IsInfinity) + throw new InvalidOperationException("Infinity is not a valid agreement value for ECDH"); + + return P.AffineXCoord.ToBigInteger(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/ECDHBasicAgreement.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/ECDHBasicAgreement.cs.meta new file mode 100644 index 0000000..873e82f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/ECDHBasicAgreement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f0b313738d9d04b448e8802281fe8810 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/ECDHCBasicAgreement.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/ECDHCBasicAgreement.cs new file mode 100644 index 0000000..f0b5d1e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/ECDHCBasicAgreement.cs @@ -0,0 +1,72 @@ +using System; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Agreement +{ + /** + * P1363 7.2.2 ECSVDP-DHC + * + * ECSVDP-DHC is Elliptic Curve Secret Value Derivation Primitive, + * Diffie-Hellman version with cofactor multiplication. It is based on + * the work of [DH76], [Mil86], [Kob87], [LMQ98] and [Kal98a]. This + * primitive derives a shared secret value from one party's private key + * and another party's public key, where both have the same set of EC + * domain parameters. If two parties correctly execute this primitive, + * they will produce the same output. This primitive can be invoked by a + * scheme to derive a shared secret key; specifically, it may be used + * with the schemes ECKAS-DH1 and DL/ECKAS-DH2. It does not assume the + * validity of the input public key (see also Section 7.2.1). + *

+ * Note: As stated P1363 compatibility mode with ECDH can be preset, and + * in this case the implementation doesn't have a ECDH compatibility mode + * (if you want that just use ECDHBasicAgreement and note they both implement + * BasicAgreement!).

+ */ + public class ECDHCBasicAgreement + : IBasicAgreement + { + private ECPrivateKeyParameters privKey; + + public virtual void Init( + ICipherParameters parameters) + { + if (parameters is ParametersWithRandom) + { + parameters = ((ParametersWithRandom) parameters).Parameters; + } + + this.privKey = (ECPrivateKeyParameters)parameters; + } + + public virtual int GetFieldSize() + { + return (privKey.Parameters.Curve.FieldSize + 7) / 8; + } + + public virtual BigInteger CalculateAgreement( + ICipherParameters pubKey) + { + ECPublicKeyParameters pub = (ECPublicKeyParameters)pubKey; + ECDomainParameters dp = privKey.Parameters; + if (!dp.Equals(pub.Parameters)) + throw new InvalidOperationException("ECDHC public key has wrong domain parameters"); + + BigInteger hd = dp.H.Multiply(privKey.D).Mod(dp.N); + + // Always perform calculations on the exact curve specified by our private key's parameters + ECPoint pubPoint = ECAlgorithms.CleanPoint(dp.Curve, pub.Q); + if (pubPoint.IsInfinity) + throw new InvalidOperationException("Infinity is not a valid public key for ECDHC"); + + ECPoint P = pubPoint.Multiply(hd).Normalize(); + if (P.IsInfinity) + throw new InvalidOperationException("Infinity is not a valid agreement value for ECDHC"); + + return P.AffineXCoord.ToBigInteger(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/ECDHCBasicAgreement.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/ECDHCBasicAgreement.cs.meta new file mode 100644 index 0000000..953c89d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/ECDHCBasicAgreement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: db616075286d6374c96c6d642eba1e49 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/ECDHWithKdfBasicAgreement.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/ECDHWithKdfBasicAgreement.cs new file mode 100644 index 0000000..1de80d1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/ECDHWithKdfBasicAgreement.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Crypto.Agreement.Kdf; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Agreement +{ + public class ECDHWithKdfBasicAgreement + : ECDHBasicAgreement + { + private readonly string algorithm; + private readonly IDerivationFunction kdf; + + public ECDHWithKdfBasicAgreement( + string algorithm, + IDerivationFunction kdf) + { + if (algorithm == null) + throw new ArgumentNullException("algorithm"); + if (kdf == null) + throw new ArgumentNullException("kdf"); + + this.algorithm = algorithm; + this.kdf = kdf; + } + + public override BigInteger CalculateAgreement( + ICipherParameters pubKey) + { + // Note that the ec.KeyAgreement class in JCE only uses kdf in one + // of the engineGenerateSecret methods. + + BigInteger result = base.CalculateAgreement(pubKey); + + int keySize = GeneratorUtilities.GetDefaultKeySize(algorithm); + + DHKdfParameters dhKdfParams = new DHKdfParameters( + new DerObjectIdentifier(algorithm), + keySize, + BigIntToBytes(result)); + + kdf.Init(dhKdfParams); + + byte[] keyBytes = new byte[keySize / 8]; + kdf.GenerateBytes(keyBytes, 0, keyBytes.Length); + + return new BigInteger(1, keyBytes); + } + + private byte[] BigIntToBytes(BigInteger r) + { + int byteLength = X9IntegerConverter.GetByteLength(privKey.Parameters.Curve); + return X9IntegerConverter.IntegerToBytes(r, byteLength); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/ECDHWithKdfBasicAgreement.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/ECDHWithKdfBasicAgreement.cs.meta new file mode 100644 index 0000000..13a2fe3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/ECDHWithKdfBasicAgreement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7d60bcaef0243bc4581b2deeafb7c555 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/ECMqvBasicAgreement.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/ECMqvBasicAgreement.cs new file mode 100644 index 0000000..b71f5a7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/ECMqvBasicAgreement.cs @@ -0,0 +1,86 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; + +namespace Org.BouncyCastle.Crypto.Agreement +{ + public class ECMqvBasicAgreement + : IBasicAgreement + { + protected internal MqvPrivateParameters privParams; + + public virtual void Init( + ICipherParameters parameters) + { + if (parameters is ParametersWithRandom) + { + parameters = ((ParametersWithRandom)parameters).Parameters; + } + + this.privParams = (MqvPrivateParameters)parameters; + } + + public virtual int GetFieldSize() + { + return (privParams.StaticPrivateKey.Parameters.Curve.FieldSize + 7) / 8; + } + + public virtual BigInteger CalculateAgreement( + ICipherParameters pubKey) + { + MqvPublicParameters pubParams = (MqvPublicParameters)pubKey; + + ECPrivateKeyParameters staticPrivateKey = privParams.StaticPrivateKey; + ECDomainParameters parameters = staticPrivateKey.Parameters; + + if (!parameters.Equals(pubParams.StaticPublicKey.Parameters)) + throw new InvalidOperationException("ECMQV public key components have wrong domain parameters"); + + ECPoint agreement = CalculateMqvAgreement(parameters, staticPrivateKey, + privParams.EphemeralPrivateKey, privParams.EphemeralPublicKey, + pubParams.StaticPublicKey, pubParams.EphemeralPublicKey).Normalize(); + + if (agreement.IsInfinity) + throw new InvalidOperationException("Infinity is not a valid agreement value for MQV"); + + return agreement.AffineXCoord.ToBigInteger(); + } + + // The ECMQV Primitive as described in SEC-1, 3.4 + private static ECPoint CalculateMqvAgreement( + ECDomainParameters parameters, + ECPrivateKeyParameters d1U, + ECPrivateKeyParameters d2U, + ECPublicKeyParameters Q2U, + ECPublicKeyParameters Q1V, + ECPublicKeyParameters Q2V) + { + BigInteger n = parameters.N; + int e = (n.BitLength + 1) / 2; + BigInteger powE = BigInteger.One.ShiftLeft(e); + + ECCurve curve = parameters.Curve; + + ECPoint q2u = ECAlgorithms.CleanPoint(curve, Q2U.Q); + ECPoint q1v = ECAlgorithms.CleanPoint(curve, Q1V.Q); + ECPoint q2v = ECAlgorithms.CleanPoint(curve, Q2V.Q); + + BigInteger x = q2u.AffineXCoord.ToBigInteger(); + BigInteger xBar = x.Mod(powE); + BigInteger Q2UBar = xBar.SetBit(e); + BigInteger s = d1U.D.Multiply(Q2UBar).Add(d2U.D).Mod(n); + + BigInteger xPrime = q2v.AffineXCoord.ToBigInteger(); + BigInteger xPrimeBar = xPrime.Mod(powE); + BigInteger Q2VBar = xPrimeBar.SetBit(e); + + BigInteger hs = parameters.H.Multiply(s).Mod(n); + + return ECAlgorithms.SumOfTwoMultiplies( + q1v, Q2VBar.Multiply(hs).Mod(n), q2v, hs); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/ECMqvBasicAgreement.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/ECMqvBasicAgreement.cs.meta new file mode 100644 index 0000000..08d2897 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/ECMqvBasicAgreement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dbe549e4d325845459dde89c0dda36de +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/ECMqvWithKdfBasicAgreement.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/ECMqvWithKdfBasicAgreement.cs new file mode 100644 index 0000000..7d79fc4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/ECMqvWithKdfBasicAgreement.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Crypto.Agreement.Kdf; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Agreement +{ + public class ECMqvWithKdfBasicAgreement + : ECMqvBasicAgreement + { + private readonly string algorithm; + private readonly IDerivationFunction kdf; + + public ECMqvWithKdfBasicAgreement( + string algorithm, + IDerivationFunction kdf) + { + if (algorithm == null) + throw new ArgumentNullException("algorithm"); + if (kdf == null) + throw new ArgumentNullException("kdf"); + + this.algorithm = algorithm; + this.kdf = kdf; + } + + public override BigInteger CalculateAgreement( + ICipherParameters pubKey) + { + // Note that the ec.KeyAgreement class in JCE only uses kdf in one + // of the engineGenerateSecret methods. + + BigInteger result = base.CalculateAgreement(pubKey); + + int keySize = GeneratorUtilities.GetDefaultKeySize(algorithm); + + DHKdfParameters dhKdfParams = new DHKdfParameters( + new DerObjectIdentifier(algorithm), + keySize, + BigIntToBytes(result)); + + kdf.Init(dhKdfParams); + + byte[] keyBytes = new byte[keySize / 8]; + kdf.GenerateBytes(keyBytes, 0, keyBytes.Length); + + return new BigInteger(1, keyBytes); + } + + private byte[] BigIntToBytes(BigInteger r) + { + int byteLength = X9IntegerConverter.GetByteLength(privParams.StaticPrivateKey.Parameters.Curve); + return X9IntegerConverter.IntegerToBytes(r, byteLength); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/ECMqvWithKdfBasicAgreement.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/ECMqvWithKdfBasicAgreement.cs.meta new file mode 100644 index 0000000..374c7d7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/ECMqvWithKdfBasicAgreement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c491731dd81eab849aa7de272d578e9f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/SM2KeyExchange.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/SM2KeyExchange.cs new file mode 100644 index 0000000..986d984 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/SM2KeyExchange.cs @@ -0,0 +1,274 @@ +using System; + +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Agreement +{ + /// + /// SM2 Key Exchange protocol - based on https://tools.ietf.org/html/draft-shen-sm2-ecdsa-02 + /// + public class SM2KeyExchange + { + private readonly IDigest mDigest; + + private byte[] mUserID; + private ECPrivateKeyParameters mStaticKey; + private ECPoint mStaticPubPoint; + private ECPoint mEphemeralPubPoint; + private ECDomainParameters mECParams; + private int mW; + private ECPrivateKeyParameters mEphemeralKey; + private bool mInitiator; + + public SM2KeyExchange() + : this(new SM3Digest()) + { + } + + public SM2KeyExchange(IDigest digest) + { + this.mDigest = digest; + } + + public virtual void Init(ICipherParameters privParam) + { + SM2KeyExchangePrivateParameters baseParam; + + if (privParam is ParametersWithID) + { + baseParam = (SM2KeyExchangePrivateParameters)((ParametersWithID)privParam).Parameters; + mUserID = ((ParametersWithID)privParam).GetID(); + } + else + { + baseParam = (SM2KeyExchangePrivateParameters)privParam; + mUserID = new byte[0]; + } + + mInitiator = baseParam.IsInitiator; + mStaticKey = baseParam.StaticPrivateKey; + mEphemeralKey = baseParam.EphemeralPrivateKey; + mECParams = mStaticKey.Parameters; + mStaticPubPoint = baseParam.StaticPublicPoint; + mEphemeralPubPoint = baseParam.EphemeralPublicPoint; + mW = mECParams.Curve.FieldSize / 2 - 1; + } + + public virtual byte[] CalculateKey(int kLen, ICipherParameters pubParam) + { + SM2KeyExchangePublicParameters otherPub; + byte[] otherUserID; + + if (pubParam is ParametersWithID) + { + otherPub = (SM2KeyExchangePublicParameters)((ParametersWithID)pubParam).Parameters; + otherUserID = ((ParametersWithID)pubParam).GetID(); + } + else + { + otherPub = (SM2KeyExchangePublicParameters)pubParam; + otherUserID = new byte[0]; + } + + byte[] za = GetZ(mDigest, mUserID, mStaticPubPoint); + byte[] zb = GetZ(mDigest, otherUserID, otherPub.StaticPublicKey.Q); + + ECPoint U = CalculateU(otherPub); + + byte[] rv; + if (mInitiator) + { + rv = Kdf(U, za, zb, kLen); + } + else + { + rv = Kdf(U, zb, za, kLen); + } + + return rv; + } + + public virtual byte[][] CalculateKeyWithConfirmation(int kLen, byte[] confirmationTag, ICipherParameters pubParam) + { + SM2KeyExchangePublicParameters otherPub; + byte[] otherUserID; + + if (pubParam is ParametersWithID) + { + otherPub = (SM2KeyExchangePublicParameters)((ParametersWithID)pubParam).Parameters; + otherUserID = ((ParametersWithID)pubParam).GetID(); + } + else + { + otherPub = (SM2KeyExchangePublicParameters)pubParam; + otherUserID = new byte[0]; + } + + if (mInitiator && confirmationTag == null) + throw new ArgumentException("if initiating, confirmationTag must be set"); + + byte[] za = GetZ(mDigest, mUserID, mStaticPubPoint); + byte[] zb = GetZ(mDigest, otherUserID, otherPub.StaticPublicKey.Q); + + ECPoint U = CalculateU(otherPub); + + byte[] rv; + if (mInitiator) + { + rv = Kdf(U, za, zb, kLen); + + byte[] inner = CalculateInnerHash(mDigest, U, za, zb, mEphemeralPubPoint, otherPub.EphemeralPublicKey.Q); + + byte[] s1 = S1(mDigest, U, inner); + + if (!Arrays.ConstantTimeAreEqual(s1, confirmationTag)) + throw new InvalidOperationException("confirmation tag mismatch"); + + return new byte[][] { rv, S2(mDigest, U, inner)}; + } + else + { + rv = Kdf(U, zb, za, kLen); + + byte[] inner = CalculateInnerHash(mDigest, U, zb, za, otherPub.EphemeralPublicKey.Q, mEphemeralPubPoint); + + return new byte[][] { rv, S1(mDigest, U, inner), S2(mDigest, U, inner) }; + } + } + + protected virtual ECPoint CalculateU(SM2KeyExchangePublicParameters otherPub) + { + ECDomainParameters dp = mStaticKey.Parameters; + + ECPoint p1 = ECAlgorithms.CleanPoint(dp.Curve, otherPub.StaticPublicKey.Q); + ECPoint p2 = ECAlgorithms.CleanPoint(dp.Curve, otherPub.EphemeralPublicKey.Q); + + BigInteger x1 = Reduce(mEphemeralPubPoint.AffineXCoord.ToBigInteger()); + BigInteger x2 = Reduce(p2.AffineXCoord.ToBigInteger()); + BigInteger tA = mStaticKey.D.Add(x1.Multiply(mEphemeralKey.D)); + BigInteger k1 = mECParams.H.Multiply(tA).Mod(mECParams.N); + BigInteger k2 = k1.Multiply(x2).Mod(mECParams.N); + + return ECAlgorithms.SumOfTwoMultiplies(p1, k1, p2, k2).Normalize(); + } + + protected virtual byte[] Kdf(ECPoint u, byte[] za, byte[] zb, int klen) + { + int digestSize = mDigest.GetDigestSize(); + byte[] buf = new byte[System.Math.Max(4, digestSize)]; + byte[] rv = new byte[(klen + 7) / 8]; + int off = 0; + + IMemoable memo = mDigest as IMemoable; + IMemoable copy = null; + + if (memo != null) + { + AddFieldElement(mDigest, u.AffineXCoord); + AddFieldElement(mDigest, u.AffineYCoord); + mDigest.BlockUpdate(za, 0, za.Length); + mDigest.BlockUpdate(zb, 0, zb.Length); + copy = memo.Copy(); + } + + uint ct = 0; + + while (off < rv.Length) + { + if (memo != null) + { + memo.Reset(copy); + } + else + { + AddFieldElement(mDigest, u.AffineXCoord); + AddFieldElement(mDigest, u.AffineYCoord); + mDigest.BlockUpdate(za, 0, za.Length); + mDigest.BlockUpdate(zb, 0, zb.Length); + } + + Pack.UInt32_To_BE(++ct, buf, 0); + mDigest.BlockUpdate(buf, 0, 4); + mDigest.DoFinal(buf, 0); + + int copyLen = System.Math.Min(digestSize, rv.Length - off); + Array.Copy(buf, 0, rv, off, copyLen); + off += copyLen; + } + + return rv; + } + + //x1~=2^w+(x1 AND (2^w-1)) + private BigInteger Reduce(BigInteger x) + { + return x.And(BigInteger.One.ShiftLeft(mW).Subtract(BigInteger.One)).SetBit(mW); + } + + private byte[] S1(IDigest digest, ECPoint u, byte[] inner) + { + digest.Update((byte)0x02); + AddFieldElement(digest, u.AffineYCoord); + digest.BlockUpdate(inner, 0, inner.Length); + + return DigestUtilities.DoFinal(digest); + } + + private byte[] CalculateInnerHash(IDigest digest, ECPoint u, byte[] za, byte[] zb, ECPoint p1, ECPoint p2) + { + AddFieldElement(digest, u.AffineXCoord); + digest.BlockUpdate(za, 0, za.Length); + digest.BlockUpdate(zb, 0, zb.Length); + AddFieldElement(digest, p1.AffineXCoord); + AddFieldElement(digest, p1.AffineYCoord); + AddFieldElement(digest, p2.AffineXCoord); + AddFieldElement(digest, p2.AffineYCoord); + + return DigestUtilities.DoFinal(digest); + } + + private byte[] S2(IDigest digest, ECPoint u, byte[] inner) + { + digest.Update((byte)0x03); + AddFieldElement(digest, u.AffineYCoord); + digest.BlockUpdate(inner, 0, inner.Length); + + return DigestUtilities.DoFinal(digest); + } + + private byte[] GetZ(IDigest digest, byte[] userID, ECPoint pubPoint) + { + AddUserID(digest, userID); + + AddFieldElement(digest, mECParams.Curve.A); + AddFieldElement(digest, mECParams.Curve.B); + AddFieldElement(digest, mECParams.G.AffineXCoord); + AddFieldElement(digest, mECParams.G.AffineYCoord); + AddFieldElement(digest, pubPoint.AffineXCoord); + AddFieldElement(digest, pubPoint.AffineYCoord); + + return DigestUtilities.DoFinal(digest); + } + + private void AddUserID(IDigest digest, byte[] userID) + { + uint len = (uint)(userID.Length * 8); + + digest.Update((byte)(len >> 8)); + digest.Update((byte)len); + digest.BlockUpdate(userID, 0, userID.Length); + } + + private void AddFieldElement(IDigest digest, ECFieldElement v) + { + byte[] p = v.GetEncoded(); + digest.BlockUpdate(p, 0, p.Length); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/SM2KeyExchange.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/SM2KeyExchange.cs.meta new file mode 100644 index 0000000..6ea4438 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/SM2KeyExchange.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e4f94ff996f0ca947a9f80f9ce9e828c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/X25519Agreement.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/X25519Agreement.cs new file mode 100644 index 0000000..7e5890c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/X25519Agreement.cs @@ -0,0 +1,27 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Agreement +{ + public sealed class X25519Agreement + : IRawAgreement + { + private X25519PrivateKeyParameters privateKey; + + public void Init(ICipherParameters parameters) + { + this.privateKey = (X25519PrivateKeyParameters)parameters; + } + + public int AgreementSize + { + get { return X25519PrivateKeyParameters.SecretSize; } + } + + public void CalculateAgreement(ICipherParameters publicKey, byte[] buf, int off) + { + privateKey.GenerateSecret((X25519PublicKeyParameters)publicKey, buf, off); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/X25519Agreement.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/X25519Agreement.cs.meta new file mode 100644 index 0000000..1348db7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/X25519Agreement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b0b17f6daff7f0348b0d00c175c9078b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/X448Agreement.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/X448Agreement.cs new file mode 100644 index 0000000..26f608c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/X448Agreement.cs @@ -0,0 +1,27 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Agreement +{ + public sealed class X448Agreement + : IRawAgreement + { + private X448PrivateKeyParameters privateKey; + + public void Init(ICipherParameters parameters) + { + this.privateKey = (X448PrivateKeyParameters)parameters; + } + + public int AgreementSize + { + get { return X448PrivateKeyParameters.SecretSize; } + } + + public void CalculateAgreement(ICipherParameters publicKey, byte[] buf, int off) + { + privateKey.GenerateSecret((X448PublicKeyParameters)publicKey, buf, off); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/X448Agreement.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/X448Agreement.cs.meta new file mode 100644 index 0000000..7616072 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/X448Agreement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a7b98135f0d1250478c9cab0418d97c0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/jpake.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/jpake.meta new file mode 100644 index 0000000..66927e9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/jpake.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: eddb1afe4600b7344b2e33b75a9dccfd +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/jpake/JPakeParticipant.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/jpake/JPakeParticipant.cs new file mode 100644 index 0000000..7942848 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/jpake/JPakeParticipant.cs @@ -0,0 +1,456 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Agreement.JPake +{ + /// + /// A participant in a Password Authenticated Key Exchange by Juggling (J-PAKE) exchange. + /// + /// The J-PAKE exchange is defined by Feng Hao and Peter Ryan in the paper + /// + /// "Password Authenticated Key Exchange by Juggling, 2008." + /// + /// The J-PAKE protocol is symmetric. + /// There is no notion of a client or server, but rather just two participants. + /// An instance of JPakeParticipant represents one participant, and + /// is the primary interface for executing the exchange. + /// + /// To execute an exchange, construct a JPakeParticipant on each end, + /// and call the following 7 methods + /// (once and only once, in the given order, for each participant, sending messages between them as described): + /// + /// CreateRound1PayloadToSend() - and send the payload to the other participant + /// ValidateRound1PayloadReceived(JPakeRound1Payload) - use the payload received from the other participant + /// CreateRound2PayloadToSend() - and send the payload to the other participant + /// ValidateRound2PayloadReceived(JPakeRound2Payload) - use the payload received from the other participant + /// CalculateKeyingMaterial() + /// CreateRound3PayloadToSend(BigInteger) - and send the payload to the other participant + /// ValidateRound3PayloadReceived(JPakeRound3Payload, BigInteger) - use the payload received from the other participant + /// + /// Each side should derive a session key from the keying material returned by CalculateKeyingMaterial(). + /// The caller is responsible for deriving the session key using a secure key derivation function (KDF). + /// + /// Round 3 is an optional key confirmation process. + /// If you do not execute round 3, then there is no assurance that both participants are using the same key. + /// (i.e. if the participants used different passwords, then their session keys will differ.) + /// + /// If the round 3 validation succeeds, then the keys are guaranteed to be the same on both sides. + /// + /// The symmetric design can easily support the asymmetric cases when one party initiates the communication. + /// e.g. Sometimes the round1 payload and round2 payload may be sent in one pass. + /// Also, in some cases, the key confirmation payload can be sent together with the round2 payload. + /// These are the trivial techniques to optimize the communication. + /// + /// The key confirmation process is implemented as specified in + /// NIST SP 800-56A Revision 1, + /// Section 8.2 Unilateral Key Confirmation for Key Agreement Schemes. + /// + /// This class is stateful and NOT threadsafe. + /// Each instance should only be used for ONE complete J-PAKE exchange + /// (i.e. a new JPakeParticipant should be constructed for each new J-PAKE exchange). + /// + public class JPakeParticipant + { + // Possible internal states. Used for state checking. + public static readonly int STATE_INITIALIZED = 0; + public static readonly int STATE_ROUND_1_CREATED = 10; + public static readonly int STATE_ROUND_1_VALIDATED = 20; + public static readonly int STATE_ROUND_2_CREATED = 30; + public static readonly int STATE_ROUND_2_VALIDATED = 40; + public static readonly int STATE_KEY_CALCULATED = 50; + public static readonly int STATE_ROUND_3_CREATED = 60; + public static readonly int STATE_ROUND_3_VALIDATED = 70; + + // Unique identifier of this participant. + // The two participants in the exchange must NOT share the same id. + private string participantId; + + // Shared secret. This only contains the secret between construction + // and the call to CalculateKeyingMaterial(). + // + // i.e. When CalculateKeyingMaterial() is called, this buffer overwritten with 0's, + // and the field is set to null. + private char[] password; + + // Digest to use during calculations. + private IDigest digest; + + // Source of secure random data. + private readonly SecureRandom random; + + private readonly BigInteger p; + private readonly BigInteger q; + private readonly BigInteger g; + + // The participantId of the other participant in this exchange. + private string partnerParticipantId; + + // Alice's x1 or Bob's x3. + private BigInteger x1; + // Alice's x2 or Bob's x4. + private BigInteger x2; + // Alice's g^x1 or Bob's g^x3. + private BigInteger gx1; + // Alice's g^x2 or Bob's g^x4. + private BigInteger gx2; + // Alice's g^x3 or Bob's g^x1. + private BigInteger gx3; + // Alice's g^x4 or Bob's g^x2. + private BigInteger gx4; + // Alice's B or Bob's A. + private BigInteger b; + + // The current state. + // See the STATE_* constants for possible values. + private int state; + + /// + /// Convenience constructor for a new JPakeParticipant that uses + /// the JPakePrimeOrderGroups#NIST_3072 prime order group, + /// a SHA-256 digest, and a default SecureRandom implementation. + /// + /// After construction, the State state will be STATE_INITIALIZED. + /// + /// Throws NullReferenceException if any argument is null. Throws + /// ArgumentException if password is empty. + /// + /// Unique identifier of this participant. + /// The two participants in the exchange must NOT share the same id. + /// Shared secret. + /// A defensive copy of this array is made (and cleared once CalculateKeyingMaterial() is called). + /// Caller should clear the input password as soon as possible. + public JPakeParticipant(string participantId, char[] password) + : this(participantId, password, JPakePrimeOrderGroups.NIST_3072) { } + + /// + /// Convenience constructor for a new JPakeParticipant that uses + /// a SHA-256 digest, and a default SecureRandom implementation. + /// + /// After construction, the State state will be STATE_INITIALIZED. + /// + /// Throws NullReferenceException if any argument is null. Throws + /// ArgumentException if password is empty. + /// + /// Unique identifier of this participant. + /// The two participants in the exchange must NOT share the same id. + /// Shared secret. + /// A defensive copy of this array is made (and cleared once CalculateKeyingMaterial() is called). + /// Caller should clear the input password as soon as possible. + /// Prime order group. See JPakePrimeOrderGroups for standard groups. + public JPakeParticipant(string participantId, char[] password, JPakePrimeOrderGroup group) + : this(participantId, password, group, new Sha256Digest(), new SecureRandom()) { } + + + /// + /// Constructor for a new JPakeParticipant. + /// + /// After construction, the State state will be STATE_INITIALIZED. + /// + /// Throws NullReferenceException if any argument is null. Throws + /// ArgumentException if password is empty. + /// + /// Unique identifier of this participant. + /// The two participants in the exchange must NOT share the same id. + /// Shared secret. + /// A defensive copy of this array is made (and cleared once CalculateKeyingMaterial() is called). + /// Caller should clear the input password as soon as possible. + /// Prime order group. See JPakePrimeOrderGroups for standard groups. + /// Digest to use during zero knowledge proofs and key confirmation + /// (SHA-256 or stronger preferred). + /// Source of secure random data for x1 and x2, and for the zero knowledge proofs. + public JPakeParticipant(string participantId, char[] password, JPakePrimeOrderGroup group, IDigest digest, SecureRandom random) + { + JPakeUtilities.ValidateNotNull(participantId, "participantId"); + JPakeUtilities.ValidateNotNull(password, "password"); + JPakeUtilities.ValidateNotNull(group, "p"); + JPakeUtilities.ValidateNotNull(digest, "digest"); + JPakeUtilities.ValidateNotNull(random, "random"); + + if (password.Length == 0) + { + throw new ArgumentException("Password must not be empty."); + } + + this.participantId = participantId; + + // Create a defensive copy so as to fully encapsulate the password. + // + // This array will contain the password for the lifetime of this + // participant BEFORE CalculateKeyingMaterial() is called. + // + // i.e. When CalculateKeyingMaterial() is called, the array will be cleared + // in order to remove the password from memory. + // + // The caller is responsible for clearing the original password array + // given as input to this constructor. + this.password = new char[password.Length]; + Array.Copy(password, this.password, password.Length); + + this.p = group.P; + this.q = group.Q; + this.g = group.G; + + this.digest = digest; + this.random = random; + + this.state = STATE_INITIALIZED; + } + + /// + /// Gets the current state of this participant. + /// See the STATE_* constants for possible values. + /// + public virtual int State + { + get { return state; } + } + + + /// + /// Creates and returns the payload to send to the other participant during round 1. + /// + /// After execution, the State state} will be STATE_ROUND_1_CREATED}. + /// + public virtual JPakeRound1Payload CreateRound1PayloadToSend() + { + if (this.state >= STATE_ROUND_1_CREATED) + throw new InvalidOperationException("Round 1 payload already created for " + this.participantId); + + this.x1 = JPakeUtilities.GenerateX1(q, random); + this.x2 = JPakeUtilities.GenerateX2(q, random); + + this.gx1 = JPakeUtilities.CalculateGx(p, g, x1); + this.gx2 = JPakeUtilities.CalculateGx(p, g, x2); + BigInteger[] knowledgeProofForX1 = JPakeUtilities.CalculateZeroKnowledgeProof(p, q, g, gx1, x1, participantId, digest, random); + BigInteger[] knowledgeProofForX2 = JPakeUtilities.CalculateZeroKnowledgeProof(p, q, g, gx2, x2, participantId, digest, random); + + this.state = STATE_ROUND_1_CREATED; + + return new JPakeRound1Payload(participantId, gx1, gx2, knowledgeProofForX1, knowledgeProofForX2); + } + + /// + /// Validates the payload received from the other participant during round 1. + /// + /// Must be called prior to CreateRound2PayloadToSend(). + /// + /// After execution, the State state will be STATE_ROUND_1_VALIDATED. + /// + /// Throws CryptoException if validation fails. Throws InvalidOperationException + /// if called multiple times. + /// + public virtual void ValidateRound1PayloadReceived(JPakeRound1Payload round1PayloadReceived) + { + if (this.state >= STATE_ROUND_1_VALIDATED) + throw new InvalidOperationException("Validation already attempted for round 1 payload for " + this.participantId); + + this.partnerParticipantId = round1PayloadReceived.ParticipantId; + this.gx3 = round1PayloadReceived.Gx1; + this.gx4 = round1PayloadReceived.Gx2; + + BigInteger[] knowledgeProofForX3 = round1PayloadReceived.KnowledgeProofForX1; + BigInteger[] knowledgeProofForX4 = round1PayloadReceived.KnowledgeProofForX2; + + JPakeUtilities.ValidateParticipantIdsDiffer(participantId, round1PayloadReceived.ParticipantId); + JPakeUtilities.ValidateGx4(gx4); + JPakeUtilities.ValidateZeroKnowledgeProof(p, q, g, gx3, knowledgeProofForX3, round1PayloadReceived.ParticipantId, digest); + JPakeUtilities.ValidateZeroKnowledgeProof(p, q, g, gx4, knowledgeProofForX4, round1PayloadReceived.ParticipantId, digest); + this.state = STATE_ROUND_1_VALIDATED; + } + + /// + /// Creates and returns the payload to send to the other participant during round 2. + /// + /// ValidateRound1PayloadReceived(JPakeRound1Payload) must be called prior to this method. + /// + /// After execution, the State state will be STATE_ROUND_2_CREATED. + /// + /// Throws InvalidOperationException if called prior to ValidateRound1PayloadReceived(JPakeRound1Payload), or multiple times + /// + public virtual JPakeRound2Payload CreateRound2PayloadToSend() + { + if (this.state >= STATE_ROUND_2_CREATED) + throw new InvalidOperationException("Round 2 payload already created for " + this.participantId); + if (this.state < STATE_ROUND_1_VALIDATED) + throw new InvalidOperationException("Round 1 payload must be validated prior to creating round 2 payload for " + this.participantId); + + BigInteger gA = JPakeUtilities.CalculateGA(p, gx1, gx3, gx4); + BigInteger s = JPakeUtilities.CalculateS(password); + BigInteger x2s = JPakeUtilities.CalculateX2s(q, x2, s); + BigInteger A = JPakeUtilities.CalculateA(p, q, gA, x2s); + BigInteger[] knowledgeProofForX2s = JPakeUtilities.CalculateZeroKnowledgeProof(p, q, gA, A, x2s, participantId, digest, random); + + this.state = STATE_ROUND_2_CREATED; + + return new JPakeRound2Payload(participantId, A, knowledgeProofForX2s); + } + + /// + /// Validates the payload received from the other participant during round 2. + /// Note that this DOES NOT detect a non-common password. + /// The only indication of a non-common password is through derivation + /// of different keys (which can be detected explicitly by executing round 3 and round 4) + /// + /// Must be called prior to CalculateKeyingMaterial(). + /// + /// After execution, the State state will be STATE_ROUND_2_VALIDATED. + /// + /// Throws CryptoException if validation fails. Throws + /// InvalidOperationException if called prior to ValidateRound1PayloadReceived(JPakeRound1Payload), or multiple times + /// + public virtual void ValidateRound2PayloadReceived(JPakeRound2Payload round2PayloadReceived) + { + if (this.state >= STATE_ROUND_2_VALIDATED) + throw new InvalidOperationException("Validation already attempted for round 2 payload for " + this.participantId); + if (this.state < STATE_ROUND_1_VALIDATED) + throw new InvalidOperationException("Round 1 payload must be validated prior to validation round 2 payload for " + this.participantId); + + BigInteger gB = JPakeUtilities.CalculateGA(p, gx3, gx1, gx2); + this.b = round2PayloadReceived.A; + BigInteger[] knowledgeProofForX4s = round2PayloadReceived.KnowledgeProofForX2s; + + JPakeUtilities.ValidateParticipantIdsDiffer(participantId, round2PayloadReceived.ParticipantId); + JPakeUtilities.ValidateParticipantIdsEqual(this.partnerParticipantId, round2PayloadReceived.ParticipantId); + JPakeUtilities.ValidateGa(gB); + JPakeUtilities.ValidateZeroKnowledgeProof(p, q, gB, b, knowledgeProofForX4s, round2PayloadReceived.ParticipantId, digest); + + this.state = STATE_ROUND_2_VALIDATED; + } + + /// + /// Calculates and returns the key material. + /// A session key must be derived from this key material using a secure key derivation function (KDF). + /// The KDF used to derive the key is handled externally (i.e. not by JPakeParticipant). + /// + /// The keying material will be identical for each participant if and only if + /// each participant's password is the same. i.e. If the participants do not + /// share the same password, then each participant will derive a different key. + /// Therefore, if you immediately start using a key derived from + /// the keying material, then you must handle detection of incorrect keys. + /// If you want to handle this detection explicitly, you can optionally perform + /// rounds 3 and 4. See JPakeParticipant for details on how to execute + /// rounds 3 and 4. + /// + /// The keying material will be in the range [0, p-1]. + /// + /// ValidateRound2PayloadReceived(JPakeRound2Payload) must be called prior to this method. + /// + /// As a side effect, the internal password array is cleared, since it is no longer needed. + /// + /// After execution, the State state will be STATE_KEY_CALCULATED. + /// + /// Throws InvalidOperationException if called prior to ValidateRound2PayloadReceived(JPakeRound2Payload), + /// or if called multiple times. + /// + public virtual BigInteger CalculateKeyingMaterial() + { + if (this.state >= STATE_KEY_CALCULATED) + throw new InvalidOperationException("Key already calculated for " + participantId); + if (this.state < STATE_ROUND_2_VALIDATED) + throw new InvalidOperationException("Round 2 payload must be validated prior to creating key for " + participantId); + + BigInteger s = JPakeUtilities.CalculateS(password); + + // Clear the password array from memory, since we don't need it anymore. + // Also set the field to null as a flag to indicate that the key has already been calculated. + Array.Clear(password, 0, password.Length); + this.password = null; + + BigInteger keyingMaterial = JPakeUtilities.CalculateKeyingMaterial(p, q, gx4, x2, s, b); + + // Clear the ephemeral private key fields as well. + // Note that we're relying on the garbage collector to do its job to clean these up. + // The old objects will hang around in memory until the garbage collector destroys them. + // + // If the ephemeral private keys x1 and x2 are leaked, + // the attacker might be able to brute-force the password. + this.x1 = null; + this.x2 = null; + this.b = null; + + // Do not clear gx* yet, since those are needed by round 3. + + this.state = STATE_KEY_CALCULATED; + + return keyingMaterial; + } + + /// + /// Creates and returns the payload to send to the other participant during round 3. + /// + /// See JPakeParticipant for more details on round 3. + /// + /// After execution, the State state} will be STATE_ROUND_3_CREATED. + /// Throws InvalidOperationException if called prior to CalculateKeyingMaterial, or multiple + /// times. + /// + /// The keying material as returned from CalculateKeyingMaterial(). + public virtual JPakeRound3Payload CreateRound3PayloadToSend(BigInteger keyingMaterial) + { + if (this.state >= STATE_ROUND_3_CREATED) + throw new InvalidOperationException("Round 3 payload already created for " + this.participantId); + if (this.state < STATE_KEY_CALCULATED) + throw new InvalidOperationException("Keying material must be calculated prior to creating round 3 payload for " + this.participantId); + + BigInteger macTag = JPakeUtilities.CalculateMacTag( + this.participantId, + this.partnerParticipantId, + this.gx1, + this.gx2, + this.gx3, + this.gx4, + keyingMaterial, + this.digest); + + this.state = STATE_ROUND_3_CREATED; + + return new JPakeRound3Payload(participantId, macTag); + } + + /// + /// Validates the payload received from the other participant during round 3. + /// + /// See JPakeParticipant for more details on round 3. + /// + /// After execution, the State state will be STATE_ROUND_3_VALIDATED. + /// + /// Throws CryptoException if validation fails. Throws InvalidOperationException if called prior to + /// CalculateKeyingMaterial or multiple times + /// + /// The round 3 payload received from the other participant. + /// The keying material as returned from CalculateKeyingMaterial(). + public virtual void ValidateRound3PayloadReceived(JPakeRound3Payload round3PayloadReceived, BigInteger keyingMaterial) + { + if (this.state >= STATE_ROUND_3_VALIDATED) + throw new InvalidOperationException("Validation already attempted for round 3 payload for " + this.participantId); + if (this.state < STATE_KEY_CALCULATED) + throw new InvalidOperationException("Keying material must be calculated prior to validating round 3 payload for " + this.participantId); + + JPakeUtilities.ValidateParticipantIdsDiffer(participantId, round3PayloadReceived.ParticipantId); + JPakeUtilities.ValidateParticipantIdsEqual(this.partnerParticipantId, round3PayloadReceived.ParticipantId); + + JPakeUtilities.ValidateMacTag( + this.participantId, + this.partnerParticipantId, + this.gx1, + this.gx2, + this.gx3, + this.gx4, + keyingMaterial, + this.digest, + round3PayloadReceived.MacTag); + + // Clear the rest of the fields. + this.gx1 = null; + this.gx2 = null; + this.gx3 = null; + this.gx4 = null; + + this.state = STATE_ROUND_3_VALIDATED; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/jpake/JPakeParticipant.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/jpake/JPakeParticipant.cs.meta new file mode 100644 index 0000000..e044459 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/jpake/JPakeParticipant.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2bfb923d5c0971e409486ee916c10036 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/jpake/JPakePrimeOrderGroup.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/jpake/JPakePrimeOrderGroup.cs new file mode 100644 index 0000000..08ffe1a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/jpake/JPakePrimeOrderGroup.cs @@ -0,0 +1,103 @@ +using System; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Agreement.JPake +{ + /// + /// A pre-computed prime order group for use during a J-PAKE exchange. + /// + /// Typically a Schnorr group is used. In general, J-PAKE can use any prime order group + /// that is suitable for public key cryptography, including elliptic curve cryptography. + /// + /// See JPakePrimeOrderGroups for convenient standard groups. + /// + /// NIST publishes + /// many groups that can be used for the desired level of security. + /// + public class JPakePrimeOrderGroup + { + private readonly BigInteger p; + private readonly BigInteger q; + private readonly BigInteger g; + + /// + /// Constructs a new JPakePrimeOrderGroup. + /// + /// In general, you should use one of the pre-approved groups from + /// JPakePrimeOrderGroups, rather than manually constructing one. + /// + /// The following basic checks are performed: + /// + /// p-1 must be evenly divisible by q + /// g must be in [2, p-1] + /// g^q mod p must equal 1 + /// p must be prime (within reasonably certainty) + /// q must be prime (within reasonably certainty) + /// + /// The prime checks are performed using BigInteger#isProbablePrime(int), + /// and are therefore subject to the same probability guarantees. + /// + /// These checks prevent trivial mistakes. + /// However, due to the small uncertainties if p and q are not prime, + /// advanced attacks are not prevented. + /// Use it at your own risk. + /// + /// Throws NullReferenceException if any argument is null. Throws + /// InvalidOperationException is any of the above validations fail. + /// + public JPakePrimeOrderGroup(BigInteger p, BigInteger q, BigInteger g) + : this(p, q, g, false) + { + // Don't skip the checks on user-specified groups. + } + + /// + /// Constructor used by the pre-approved groups in JPakePrimeOrderGroups. + /// These pre-approved groups can avoid the expensive checks. + /// User-specified groups should not use this constructor. + /// + public JPakePrimeOrderGroup(BigInteger p, BigInteger q, BigInteger g, bool skipChecks) + { + JPakeUtilities.ValidateNotNull(p, "p"); + JPakeUtilities.ValidateNotNull(q, "q"); + JPakeUtilities.ValidateNotNull(g, "g"); + + if (!skipChecks) + { + if (!p.Subtract(JPakeUtilities.One).Mod(q).Equals(JPakeUtilities.Zero)) + throw new ArgumentException("p-1 must be evenly divisible by q"); + if (g.CompareTo(BigInteger.Two) == -1 || g.CompareTo(p.Subtract(JPakeUtilities.One)) == 1) + throw new ArgumentException("g must be in [2, p-1]"); + if (!g.ModPow(q, p).Equals(JPakeUtilities.One)) + throw new ArgumentException("g^q mod p must equal 1"); + + // Note these checks do not guarantee that p and q are prime. + // We just have reasonable certainty that they are prime. + if (!p.IsProbablePrime(20)) + throw new ArgumentException("p must be prime"); + if (!q.IsProbablePrime(20)) + throw new ArgumentException("q must be prime"); + } + + this.p = p; + this.q = q; + this.g = g; + } + + public virtual BigInteger P + { + get { return p; } + } + + public virtual BigInteger Q + { + get { return q; } + } + + public virtual BigInteger G + { + get { return g; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/jpake/JPakePrimeOrderGroup.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/jpake/JPakePrimeOrderGroup.cs.meta new file mode 100644 index 0000000..e65d7bf --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/jpake/JPakePrimeOrderGroup.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4e3e01820830d944494fc7cad4d144bb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/jpake/JPakePrimeOrderGroups.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/jpake/JPakePrimeOrderGroups.cs new file mode 100644 index 0000000..192cd2b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/jpake/JPakePrimeOrderGroups.cs @@ -0,0 +1,108 @@ +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Agreement.JPake +{ + /// + /// Standard pre-computed prime order groups for use by J-PAKE. + /// (J-PAKE can use pre-computed prime order groups, same as DSA and Diffie-Hellman.) + ///

+ /// This class contains some convenient constants for use as input for + /// constructing {@link JPAKEParticipant}s. + ///

+ /// The prime order groups below are taken from Sun's JDK JavaDoc (docs/guide/security/CryptoSpec.html#AppB), + /// and from the prime order groups + /// published by NIST. + ///

+ public class JPakePrimeOrderGroups + { + /// + /// From Sun's JDK JavaDoc (docs/guide/security/CryptoSpec.html#AppB) + /// 1024-bit p, 160-bit q and 1024-bit g for 80-bit security. + /// + public static readonly JPakePrimeOrderGroup SUN_JCE_1024 = new JPakePrimeOrderGroup( + // p + new BigInteger( + "fd7f53811d75122952df4a9c2eece4e7f611b7523cef4400c31e3f80b6512669" + + "455d402251fb593d8d58fabfc5f5ba30f6cb9b556cd7813b801d346ff26660b7" + + "6b9950a5a49f9fe8047b1022c24fbba9d7feb7c61bf83b57e7c6a8a6150f04fb" + + "83f6d3c51ec3023554135a169132f675f3ae2b61d72aeff22203199dd14801c7", 16), + // q + new BigInteger("9760508f15230bccb292b982a2eb840bf0581cf5", 16), + // g + new BigInteger( + "f7e1a085d69b3ddecbbcab5c36b857b97994afbbfa3aea82f9574c0b3d078267" + + "5159578ebad4594fe67107108180b449167123e84c281613b7cf09328cc8a6e1" + + "3c167a8b547c8d28e0a3ae1e2bb3a675916ea37f0bfa213562f1fb627a01243b" + + "cca4f1bea8519089a883dfe15ae59f06928b665e807b552564014c3bfecf492a", 16), + true + ); + + /// + /// From NIST. + /// 2048-bit p, 224-bit q and 2048-bit g for 112-bit security. + /// + public static readonly JPakePrimeOrderGroup NIST_2048 = new JPakePrimeOrderGroup( + // p + new BigInteger( + "C196BA05AC29E1F9C3C72D56DFFC6154A033F1477AC88EC37F09BE6C5BB95F51" + + "C296DD20D1A28A067CCC4D4316A4BD1DCA55ED1066D438C35AEBAABF57E7DAE4" + + "28782A95ECA1C143DB701FD48533A3C18F0FE23557EA7AE619ECACC7E0B51652" + + "A8776D02A425567DED36EABD90CA33A1E8D988F0BBB92D02D1D20290113BB562" + + "CE1FC856EEB7CDD92D33EEA6F410859B179E7E789A8F75F645FAE2E136D252BF" + + "FAFF89528945C1ABE705A38DBC2D364AADE99BE0D0AAD82E5320121496DC65B3" + + "930E38047294FF877831A16D5228418DE8AB275D7D75651CEFED65F78AFC3EA7" + + "FE4D79B35F62A0402A1117599ADAC7B269A59F353CF450E6982D3B1702D9CA83", 16), + // q + new BigInteger("90EAF4D1AF0708B1B612FF35E0A2997EB9E9D263C9CE659528945C0D", 16), + // g + new BigInteger( + "A59A749A11242C58C894E9E5A91804E8FA0AC64B56288F8D47D51B1EDC4D6544" + + "4FECA0111D78F35FC9FDD4CB1F1B79A3BA9CBEE83A3F811012503C8117F98E50" + + "48B089E387AF6949BF8784EBD9EF45876F2E6A5A495BE64B6E770409494B7FEE" + + "1DBB1E4B2BC2A53D4F893D418B7159592E4FFFDF6969E91D770DAEBD0B5CB14C" + + "00AD68EC7DC1E5745EA55C706C4A1C5C88964E34D09DEB753AD418C1AD0F4FDF" + + "D049A955E5D78491C0B7A2F1575A008CCD727AB376DB6E695515B05BD412F5B8" + + "C2F4C77EE10DA48ABD53F5DD498927EE7B692BBBCDA2FB23A516C5B4533D7398" + + "0B2A3B60E384ED200AE21B40D273651AD6060C13D97FD69AA13C5611A51B9085", 16), + true + ); + + /// + /// From NIST. + /// 3072-bit p, 256-bit q and 3072-bit g for 128-bit security. + /// + public static readonly JPakePrimeOrderGroup NIST_3072 = new JPakePrimeOrderGroup( + // p + new BigInteger( + "90066455B5CFC38F9CAA4A48B4281F292C260FEEF01FD61037E56258A7795A1C" + + "7AD46076982CE6BB956936C6AB4DCFE05E6784586940CA544B9B2140E1EB523F" + + "009D20A7E7880E4E5BFA690F1B9004A27811CD9904AF70420EEFD6EA11EF7DA1" + + "29F58835FF56B89FAA637BC9AC2EFAAB903402229F491D8D3485261CD068699B" + + "6BA58A1DDBBEF6DB51E8FE34E8A78E542D7BA351C21EA8D8F1D29F5D5D159394" + + "87E27F4416B0CA632C59EFD1B1EB66511A5A0FBF615B766C5862D0BD8A3FE7A0" + + "E0DA0FB2FE1FCB19E8F9996A8EA0FCCDE538175238FC8B0EE6F29AF7F642773E" + + "BE8CD5402415A01451A840476B2FCEB0E388D30D4B376C37FE401C2A2C2F941D" + + "AD179C540C1C8CE030D460C4D983BE9AB0B20F69144C1AE13F9383EA1C08504F" + + "B0BF321503EFE43488310DD8DC77EC5B8349B8BFE97C2C560EA878DE87C11E3D" + + "597F1FEA742D73EEC7F37BE43949EF1A0D15C3F3E3FC0A8335617055AC91328E" + + "C22B50FC15B941D3D1624CD88BC25F3E941FDDC6200689581BFEC416B4B2CB73", 16), + // q + new BigInteger("CFA0478A54717B08CE64805B76E5B14249A77A4838469DF7F7DC987EFCCFB11D", 16), + // g + new BigInteger( + "5E5CBA992E0A680D885EB903AEA78E4A45A469103D448EDE3B7ACCC54D521E37" + + "F84A4BDD5B06B0970CC2D2BBB715F7B82846F9A0C393914C792E6A923E2117AB" + + "805276A975AADB5261D91673EA9AAFFEECBFA6183DFCB5D3B7332AA19275AFA1" + + "F8EC0B60FB6F66CC23AE4870791D5982AAD1AA9485FD8F4A60126FEB2CF05DB8" + + "A7F0F09B3397F3937F2E90B9E5B9C9B6EFEF642BC48351C46FB171B9BFA9EF17" + + "A961CE96C7E7A7CC3D3D03DFAD1078BA21DA425198F07D2481622BCE45969D9C" + + "4D6063D72AB7A0F08B2F49A7CC6AF335E08C4720E31476B67299E231F8BD90B3" + + "9AC3AE3BE0C6B6CACEF8289A2E2873D58E51E029CAFBD55E6841489AB66B5B4B" + + "9BA6E2F784660896AFF387D92844CCB8B69475496DE19DA2E58259B090489AC8" + + "E62363CDF82CFD8EF2A427ABCD65750B506F56DDE3B988567A88126B914D7828" + + "E2B63A6D7ED0747EC59E0E0A23CE7D8A74C1D2C2A7AFB6A29799620F00E11C33" + + "787F7DED3B30E1A22D09F1FBDA1ABBBFBF25CAE05A13F812E34563F99410E73B", 16), + true + ); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/jpake/JPakePrimeOrderGroups.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/jpake/JPakePrimeOrderGroups.cs.meta new file mode 100644 index 0000000..190afd6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/jpake/JPakePrimeOrderGroups.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c028e933fba3f5f489dbb80f45d8723b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/jpake/JPakeRound1Payload.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/jpake/JPakeRound1Payload.cs new file mode 100644 index 0000000..9e4ab7a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/jpake/JPakeRound1Payload.cs @@ -0,0 +1,101 @@ +using System; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Agreement.JPake +{ + /// + /// The payload sent/received during the first round of a J-PAKE exchange. + /// + /// Each JPAKEParticipant creates and sends an instance of this payload to + /// the other. The payload to send should be created via + /// JPAKEParticipant.CreateRound1PayloadToSend(). + /// + /// Each participant must also validate the payload received from the other. + /// The received payload should be validated via + /// JPAKEParticipant.ValidateRound1PayloadReceived(JPakeRound1Payload). + /// + public class JPakeRound1Payload + { + /// + /// The id of the JPAKEParticipant who created/sent this payload. + /// + private readonly string participantId; + + /// + /// The value of g^x1 + /// + private readonly BigInteger gx1; + + /// + /// The value of g^x2 + /// + private readonly BigInteger gx2; + + /// + /// The zero knowledge proof for x1. + /// + /// This is a two element array, containing {g^v, r} for x1. + /// + private readonly BigInteger[] knowledgeProofForX1; + + /// + /// The zero knowledge proof for x2. + /// + /// This is a two element array, containing {g^v, r} for x2. + /// + private readonly BigInteger[] knowledgeProofForX2; + + public JPakeRound1Payload(string participantId, BigInteger gx1, BigInteger gx2, BigInteger[] knowledgeProofForX1, BigInteger[] knowledgeProofForX2) + { + JPakeUtilities.ValidateNotNull(participantId, "participantId"); + JPakeUtilities.ValidateNotNull(gx1, "gx1"); + JPakeUtilities.ValidateNotNull(gx2, "gx2"); + JPakeUtilities.ValidateNotNull(knowledgeProofForX1, "knowledgeProofForX1"); + JPakeUtilities.ValidateNotNull(knowledgeProofForX2, "knowledgeProofForX2"); + + this.participantId = participantId; + this.gx1 = gx1; + this.gx2 = gx2; + this.knowledgeProofForX1 = new BigInteger[knowledgeProofForX1.Length]; + Array.Copy(knowledgeProofForX1, this.knowledgeProofForX1, knowledgeProofForX1.Length); + this.knowledgeProofForX2 = new BigInteger[knowledgeProofForX2.Length]; + Array.Copy(knowledgeProofForX2, this.knowledgeProofForX2, knowledgeProofForX2.Length); + } + + public virtual string ParticipantId + { + get { return participantId; } + } + + public virtual BigInteger Gx1 + { + get { return gx1; } + } + + public virtual BigInteger Gx2 + { + get { return gx2; } + } + + public virtual BigInteger[] KnowledgeProofForX1 + { + get + { + BigInteger[] kp = new BigInteger[knowledgeProofForX1.Length]; + Array.Copy(knowledgeProofForX1, kp, knowledgeProofForX1.Length); + return kp; + } + } + + public virtual BigInteger[] KnowledgeProofForX2 + { + get + { + BigInteger[] kp = new BigInteger[knowledgeProofForX2.Length]; + Array.Copy(knowledgeProofForX2, kp, knowledgeProofForX2.Length); + return kp; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/jpake/JPakeRound1Payload.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/jpake/JPakeRound1Payload.cs.meta new file mode 100644 index 0000000..a726de1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/jpake/JPakeRound1Payload.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bdef4bc0234ca8f4c82e3ba65776d5df +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/jpake/JPakeRound2Payload.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/jpake/JPakeRound2Payload.cs new file mode 100644 index 0000000..47962cb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/jpake/JPakeRound2Payload.cs @@ -0,0 +1,72 @@ +using System; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Agreement.JPake +{ + /// + /// The payload sent/received during the second round of a J-PAKE exchange. + /// + /// Each JPAKEParticipant creates and sends an instance + /// of this payload to the other JPAKEParticipant. + /// The payload to send should be created via + /// JPAKEParticipant#createRound2PayloadToSend() + /// + /// Each JPAKEParticipant must also validate the payload + /// received from the other JPAKEParticipant. + /// The received payload should be validated via + /// JPAKEParticipant#validateRound2PayloadReceived(JPakeRound2Payload) + /// + public class JPakeRound2Payload + { + /// + /// The id of the JPAKEParticipant who created/sent this payload. + /// + private readonly string participantId; + + /// + /// The value of A, as computed during round 2. + /// + private readonly BigInteger a; + + /// + /// The zero knowledge proof for x2 * s. + /// + /// This is a two element array, containing {g^v, r} for x2 * s. + /// + private readonly BigInteger[] knowledgeProofForX2s; + + public JPakeRound2Payload(string participantId, BigInteger a, BigInteger[] knowledgeProofForX2s) + { + JPakeUtilities.ValidateNotNull(participantId, "participantId"); + JPakeUtilities.ValidateNotNull(a, "a"); + JPakeUtilities.ValidateNotNull(knowledgeProofForX2s, "knowledgeProofForX2s"); + + this.participantId = participantId; + this.a = a; + this.knowledgeProofForX2s = new BigInteger[knowledgeProofForX2s.Length]; + knowledgeProofForX2s.CopyTo(this.knowledgeProofForX2s, 0); + } + + public virtual string ParticipantId + { + get { return participantId; } + } + + public virtual BigInteger A + { + get { return a; } + } + + public virtual BigInteger[] KnowledgeProofForX2s + { + get + { + BigInteger[] kp = new BigInteger[knowledgeProofForX2s.Length]; + Array.Copy(knowledgeProofForX2s, kp, knowledgeProofForX2s.Length); + return kp; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/jpake/JPakeRound2Payload.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/jpake/JPakeRound2Payload.cs.meta new file mode 100644 index 0000000..b1047ef --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/jpake/JPakeRound2Payload.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f83ae8cf6bbdba24299629acc6fbf19e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/jpake/JPakeRound3Payload.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/jpake/JPakeRound3Payload.cs new file mode 100644 index 0000000..767702f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/jpake/JPakeRound3Payload.cs @@ -0,0 +1,51 @@ +using System; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Agreement.JPake +{ + /// + /// The payload sent/received during the optional third round of a J-PAKE exchange, + /// which is for explicit key confirmation. + /// + /// Each JPAKEParticipant creates and sends an instance + /// of this payload to the other JPAKEParticipant. + /// The payload to send should be created via + /// JPAKEParticipant#createRound3PayloadToSend(BigInteger) + /// + /// Eeach JPAKEParticipant must also validate the payload + /// received from the other JPAKEParticipant. + /// The received payload should be validated via + /// JPAKEParticipant#validateRound3PayloadReceived(JPakeRound3Payload, BigInteger) + /// + public class JPakeRound3Payload + { + /// + /// The id of the {@link JPAKEParticipant} who created/sent this payload. + /// + private readonly string participantId; + + /// + /// The value of MacTag, as computed by round 3. + /// + /// See JPAKEUtil#calculateMacTag(string, string, BigInteger, BigInteger, BigInteger, BigInteger, BigInteger, org.bouncycastle.crypto.Digest) + /// + private readonly BigInteger macTag; + + public JPakeRound3Payload(string participantId, BigInteger magTag) + { + this.participantId = participantId; + this.macTag = magTag; + } + + public virtual string ParticipantId + { + get { return participantId; } + } + + public virtual BigInteger MacTag + { + get { return macTag; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/jpake/JPakeRound3Payload.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/jpake/JPakeRound3Payload.cs.meta new file mode 100644 index 0000000..69e15a2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/jpake/JPakeRound3Payload.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e96c527908fb8224ea08ec93da14dfd5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/jpake/JPakeUtilities.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/jpake/JPakeUtilities.cs new file mode 100644 index 0000000..b23518a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/jpake/JPakeUtilities.cs @@ -0,0 +1,390 @@ +using System; +using System.Text; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Macs; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Agreement.JPake +{ + /// + /// Primitives needed for a J-PAKE exchange. + /// + /// The recommended way to perform a J-PAKE exchange is by using + /// two JPAKEParticipants. Internally, those participants + /// call these primitive operations in JPakeUtilities. + /// + /// The primitives, however, can be used without a JPAKEParticipant if needed. + /// + public abstract class JPakeUtilities + { + public static readonly BigInteger Zero = BigInteger.Zero; + public static readonly BigInteger One = BigInteger.One; + + /// + /// Return a value that can be used as x1 or x3 during round 1. + /// The returned value is a random value in the range [0, q-1]. + /// + public static BigInteger GenerateX1(BigInteger q, SecureRandom random) + { + BigInteger min = Zero; + BigInteger max = q.Subtract(One); + return BigIntegers.CreateRandomInRange(min, max, random); + } + + /// + /// Return a value that can be used as x2 or x4 during round 1. + /// The returned value is a random value in the range [1, q-1]. + /// + public static BigInteger GenerateX2(BigInteger q, SecureRandom random) + { + BigInteger min = One; + BigInteger max = q.Subtract(One); + return BigIntegers.CreateRandomInRange(min, max, random); + } + + /// + /// Converts the given password to a BigInteger + /// for use in arithmetic calculations. + /// + public static BigInteger CalculateS(char[] password) + { + return new BigInteger(Encoding.UTF8.GetBytes(password)); + } + + /// + /// Calculate g^x mod p as done in round 1. + /// + public static BigInteger CalculateGx(BigInteger p, BigInteger g, BigInteger x) + { + return g.ModPow(x, p); + } + + /// + /// Calculate ga as done in round 2. + /// + public static BigInteger CalculateGA(BigInteger p, BigInteger gx1, BigInteger gx3, BigInteger gx4) + { + // ga = g^(x1+x3+x4) = g^x1 * g^x3 * g^x4 + return gx1.Multiply(gx3).Multiply(gx4).Mod(p); + } + + /// + /// Calculate x2 * s as done in round 2. + /// + public static BigInteger CalculateX2s(BigInteger q, BigInteger x2, BigInteger s) + { + return x2.Multiply(s).Mod(q); + } + + /// + /// Calculate A as done in round 2. + /// + public static BigInteger CalculateA(BigInteger p, BigInteger q, BigInteger gA, BigInteger x2s) + { + // A = ga^(x*s) + return gA.ModPow(x2s, p); + } + + /// + /// Calculate a zero knowledge proof of x using Schnorr's signature. + /// The returned array has two elements {g^v, r = v-x*h} for x. + /// + public static BigInteger[] CalculateZeroKnowledgeProof(BigInteger p, BigInteger q, BigInteger g, + BigInteger gx, BigInteger x, string participantId, IDigest digest, SecureRandom random) + { + /* Generate a random v, and compute g^v */ + BigInteger vMin = Zero; + BigInteger vMax = q.Subtract(One); + BigInteger v = BigIntegers.CreateRandomInRange(vMin, vMax, random); + + BigInteger gv = g.ModPow(v, p); + BigInteger h = CalculateHashForZeroKnowledgeProof(g, gv, gx, participantId, digest); // h + + return new BigInteger[] + { + gv, + v.Subtract(x.Multiply(h)).Mod(q) // r = v-x*h + }; + } + + private static BigInteger CalculateHashForZeroKnowledgeProof(BigInteger g, BigInteger gr, BigInteger gx, + string participantId, IDigest digest) + { + digest.Reset(); + + UpdateDigestIncludingSize(digest, g); + + UpdateDigestIncludingSize(digest, gr); + + UpdateDigestIncludingSize(digest, gx); + + UpdateDigestIncludingSize(digest, participantId); + + byte[] output = DigestUtilities.DoFinal(digest); + + return new BigInteger(output); + } + + /// + /// Validates that g^x4 is not 1. + /// throws CryptoException if g^x4 is 1 + /// + public static void ValidateGx4(BigInteger gx4) + { + if (gx4.Equals(One)) + throw new CryptoException("g^x validation failed. g^x should not be 1."); + } + + /// + /// Validates that ga is not 1. + /// + /// As described by Feng Hao... + /// Alice could simply check ga != 1 to ensure it is a generator. + /// In fact, as we will explain in Section 3, (x1 + x3 + x4 ) is random over Zq even in the face of active attacks. + /// Hence, the probability for ga = 1 is extremely small - on the order of 2^160 for 160-bit q. + /// + /// throws CryptoException if ga is 1 + /// + public static void ValidateGa(BigInteger ga) + { + if (ga.Equals(One)) + throw new CryptoException("ga is equal to 1. It should not be. The chances of this happening are on the order of 2^160 for a 160-bit q. Try again."); + } + + /// + /// Validates the zero knowledge proof (generated by + /// calculateZeroKnowledgeProof(BigInteger, BigInteger, BigInteger, BigInteger, BigInteger, string, Digest, SecureRandom) + /// is correct. + /// + /// throws CryptoException if the zero knowledge proof is not correct + /// + public static void ValidateZeroKnowledgeProof(BigInteger p, BigInteger q, BigInteger g, + BigInteger gx, BigInteger[] zeroKnowledgeProof, string participantId, IDigest digest) + { + /* sig={g^v,r} */ + BigInteger gv = zeroKnowledgeProof[0]; + BigInteger r = zeroKnowledgeProof[1]; + + BigInteger h = CalculateHashForZeroKnowledgeProof(g, gv, gx, participantId, digest); + if (!(gx.CompareTo(Zero) == 1 && // g^x > 0 + gx.CompareTo(p) == -1 && // g^x < p + gx.ModPow(q, p).CompareTo(One) == 0 && // g^x^q mod q = 1 + /* + * Below, I took a straightforward way to compute g^r * g^x^h, + * which needs 2 exp. Using a simultaneous computation technique + * would only need 1 exp. + */ + g.ModPow(r, p).Multiply(gx.ModPow(h, p)).Mod(p).CompareTo(gv) == 0)) // g^v=g^r * g^x^h + { + throw new CryptoException("Zero-knowledge proof validation failed"); + } + } + + /// + /// Calculates the keying material, which can be done after round 2 has completed. + /// A session key must be derived from this key material using a secure key derivation function (KDF). + /// The KDF used to derive the key is handled externally (i.e. not by JPAKEParticipant). + /// + /// KeyingMaterial = (B/g^{x2*x4*s})^x2 + /// + public static BigInteger CalculateKeyingMaterial(BigInteger p, BigInteger q, + BigInteger gx4, BigInteger x2, BigInteger s, BigInteger B) + { + return gx4.ModPow(x2.Multiply(s).Negate().Mod(q), p).Multiply(B).ModPow(x2, p); + } + + /// + /// Validates that the given participant ids are not equal. + /// (For the J-PAKE exchange, each participant must use a unique id.) + /// + /// Throws CryptoException if the participantId strings are equal. + /// + public static void ValidateParticipantIdsDiffer(string participantId1, string participantId2) + { + if (participantId1.Equals(participantId2)) + { + throw new CryptoException( + "Both participants are using the same participantId (" + + participantId1 + + "). This is not allowed. " + + "Each participant must use a unique participantId."); + } + } + + /// + /// Validates that the given participant ids are equal. + /// This is used to ensure that the payloads received from + /// each round all come from the same participant. + /// + public static void ValidateParticipantIdsEqual(string expectedParticipantId, string actualParticipantId) + { + if (!expectedParticipantId.Equals(actualParticipantId)) + { + throw new CryptoException( + "Received payload from incorrect partner (" + + actualParticipantId + + "). Expected to receive payload from " + + expectedParticipantId + + "."); + } + } + + /// + /// Validates that the given object is not null. + /// throws NullReferenceException if the object is null. + /// + /// object in question + /// name of the object (to be used in exception message) + public static void ValidateNotNull(object obj, string description) + { + if (obj == null) + throw new ArgumentNullException(description); + } + + /// + /// Calculates the MacTag (to be used for key confirmation), as defined by + /// NIST SP 800-56A Revision 1, + /// Section 8.2 Unilateral Key Confirmation for Key Agreement Schemes. + /// + /// MacTag = HMAC(MacKey, MacLen, MacData) + /// MacKey = H(K || "JPAKE_KC") + /// MacData = "KC_1_U" || participantId || partnerParticipantId || gx1 || gx2 || gx3 || gx4 + /// + /// Note that both participants use "KC_1_U" because the sender of the round 3 message + /// is always the initiator for key confirmation. + /// + /// HMAC = {@link HMac} used with the given {@link Digest} + /// H = The given {@link Digest} + /// MacLen = length of MacTag + /// + public static BigInteger CalculateMacTag(string participantId, string partnerParticipantId, + BigInteger gx1, BigInteger gx2, BigInteger gx3, BigInteger gx4, BigInteger keyingMaterial, IDigest digest) + { + byte[] macKey = CalculateMacKey(keyingMaterial, digest); + + HMac mac = new HMac(digest); + mac.Init(new KeyParameter(macKey)); + Arrays.Fill(macKey, (byte)0); + + /* + * MacData = "KC_1_U" || participantId_Alice || participantId_Bob || gx1 || gx2 || gx3 || gx4. + */ + UpdateMac(mac, "KC_1_U"); + UpdateMac(mac, participantId); + UpdateMac(mac, partnerParticipantId); + UpdateMac(mac, gx1); + UpdateMac(mac, gx2); + UpdateMac(mac, gx3); + UpdateMac(mac, gx4); + + byte[] macOutput = MacUtilities.DoFinal(mac); + + return new BigInteger(macOutput); + } + + /// + /// Calculates the MacKey (i.e. the key to use when calculating the MagTag for key confirmation). + /// + /// MacKey = H(K || "JPAKE_KC") + /// + private static byte[] CalculateMacKey(BigInteger keyingMaterial, IDigest digest) + { + digest.Reset(); + + UpdateDigest(digest, keyingMaterial); + /* + * This constant is used to ensure that the macKey is NOT the same as the derived key. + */ + UpdateDigest(digest, "JPAKE_KC"); + + return DigestUtilities.DoFinal(digest); + } + + /// + /// Validates the MacTag received from the partner participant. + /// + /// throws CryptoException if the participantId strings are equal. + /// + public static void ValidateMacTag(string participantId, string partnerParticipantId, + BigInteger gx1, BigInteger gx2, BigInteger gx3, BigInteger gx4, + BigInteger keyingMaterial, IDigest digest, BigInteger partnerMacTag) + { + /* + * Calculate the expected MacTag using the parameters as the partner + * would have used when the partner called calculateMacTag. + * + * i.e. basically all the parameters are reversed. + * participantId <-> partnerParticipantId + * x1 <-> x3 + * x2 <-> x4 + */ + BigInteger expectedMacTag = CalculateMacTag(partnerParticipantId, participantId, gx3, gx4, gx1, gx2, keyingMaterial, digest); + + if (!expectedMacTag.Equals(partnerMacTag)) + { + throw new CryptoException( + "Partner MacTag validation failed. " + + "Therefore, the password, MAC, or digest algorithm of each participant does not match."); + } + } + + private static void UpdateDigest(IDigest digest, BigInteger bigInteger) + { + UpdateDigest(digest, BigIntegers.AsUnsignedByteArray(bigInteger)); + } + + private static void UpdateDigest(IDigest digest, string str) + { + UpdateDigest(digest, Encoding.UTF8.GetBytes(str)); + } + + private static void UpdateDigest(IDigest digest, byte[] bytes) + { + digest.BlockUpdate(bytes, 0, bytes.Length); + Arrays.Fill(bytes, (byte)0); + } + + private static void UpdateDigestIncludingSize(IDigest digest, BigInteger bigInteger) + { + UpdateDigestIncludingSize(digest, BigIntegers.AsUnsignedByteArray(bigInteger)); + } + + private static void UpdateDigestIncludingSize(IDigest digest, string str) + { + UpdateDigestIncludingSize(digest, Encoding.UTF8.GetBytes(str)); + } + + private static void UpdateDigestIncludingSize(IDigest digest, byte[] bytes) + { + digest.BlockUpdate(IntToByteArray(bytes.Length), 0, 4); + digest.BlockUpdate(bytes, 0, bytes.Length); + Arrays.Fill(bytes, (byte)0); + } + + private static void UpdateMac(IMac mac, BigInteger bigInteger) + { + UpdateMac(mac, BigIntegers.AsUnsignedByteArray(bigInteger)); + } + + private static void UpdateMac(IMac mac, string str) + { + UpdateMac(mac, Encoding.UTF8.GetBytes(str)); + } + + private static void UpdateMac(IMac mac, byte[] bytes) + { + mac.BlockUpdate(bytes, 0, bytes.Length); + Arrays.Fill(bytes, (byte)0); + } + + private static byte[] IntToByteArray(int value) + { + return Pack.UInt32_To_BE((uint)value); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/jpake/JPakeUtilities.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/jpake/JPakeUtilities.cs.meta new file mode 100644 index 0000000..7c319f2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/jpake/JPakeUtilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 487ee773bceec1e4795c909c3c96eb7a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/kdf.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/kdf.meta new file mode 100644 index 0000000..0183e6e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/kdf.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 34f11599e09ade944aae74086523dd80 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/kdf/ConcatenationKdfGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/kdf/ConcatenationKdfGenerator.cs new file mode 100644 index 0000000..d88f4df --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/kdf/ConcatenationKdfGenerator.cs @@ -0,0 +1,100 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; + +namespace Org.BouncyCastle.Crypto.Agreement.Kdf +{ + /** + * Generator for Concatenation Key Derivation Function defined in NIST SP 800-56A, Sect 5.8.1 + */ + public class ConcatenationKdfGenerator + : IDerivationFunction + { + private readonly IDigest mDigest; + + private byte[] mShared; + private byte[] mOtherInfo; + private int mHLen; + + /** + * @param digest the digest to be used as the source of generated bytes + */ + public ConcatenationKdfGenerator(IDigest digest) + { + this.mDigest = digest; + this.mHLen = digest.GetDigestSize(); + } + + public virtual void Init(IDerivationParameters param) + { + if (!(param is KdfParameters)) + throw new ArgumentException("KDF parameters required for ConcatenationKdfGenerator"); + + KdfParameters p = (KdfParameters)param; + + mShared = p.GetSharedSecret(); + mOtherInfo = p.GetIV(); + } + + /** + * return the underlying digest. + */ + public virtual IDigest Digest + { + get { return mDigest; } + } + + /** + * fill len bytes of the output buffer with bytes generated from + * the derivation function. + * + * @throws DataLengthException if the out buffer is too small. + */ + public virtual int GenerateBytes(byte[] outBytes, int outOff, int len) + { + if ((outBytes.Length - len) < outOff) + throw new DataLengthException("output buffer too small"); + + byte[] hashBuf = new byte[mHLen]; + byte[] C = new byte[4]; + uint counter = 1; + int outputLen = 0; + + mDigest.Reset(); + + if (len > mHLen) + { + do + { + Pack.UInt32_To_BE(counter, C); + + mDigest.BlockUpdate(C, 0, C.Length); + mDigest.BlockUpdate(mShared, 0, mShared.Length); + mDigest.BlockUpdate(mOtherInfo, 0, mOtherInfo.Length); + + mDigest.DoFinal(hashBuf, 0); + + Array.Copy(hashBuf, 0, outBytes, outOff + outputLen, mHLen); + outputLen += mHLen; + } + while ((counter++) < (len / mHLen)); + } + + if (outputLen < len) + { + Pack.UInt32_To_BE(counter, C); + + mDigest.BlockUpdate(C, 0, C.Length); + mDigest.BlockUpdate(mShared, 0, mShared.Length); + mDigest.BlockUpdate(mOtherInfo, 0, mOtherInfo.Length); + + mDigest.DoFinal(hashBuf, 0); + + Array.Copy(hashBuf, 0, outBytes, outOff + outputLen, len - outputLen); + } + + return len; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/kdf/ConcatenationKdfGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/kdf/ConcatenationKdfGenerator.cs.meta new file mode 100644 index 0000000..cb16af2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/kdf/ConcatenationKdfGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b445ca0b801f363468c9edcdffb03e18 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/kdf/DHKdfParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/kdf/DHKdfParameters.cs new file mode 100644 index 0000000..f6c9e60 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/kdf/DHKdfParameters.cs @@ -0,0 +1,57 @@ +using System; + +using Org.BouncyCastle.Asn1; + +namespace Org.BouncyCastle.Crypto.Agreement.Kdf +{ + public class DHKdfParameters + : IDerivationParameters + { + private readonly DerObjectIdentifier algorithm; + private readonly int keySize; + private readonly byte[] z; + private readonly byte[] extraInfo; + + public DHKdfParameters( + DerObjectIdentifier algorithm, + int keySize, + byte[] z) + : this(algorithm, keySize, z, null) + { + } + + public DHKdfParameters( + DerObjectIdentifier algorithm, + int keySize, + byte[] z, + byte[] extraInfo) + { + this.algorithm = algorithm; + this.keySize = keySize; + this.z = z; // TODO Clone? + this.extraInfo = extraInfo; + } + + public DerObjectIdentifier Algorithm + { + get { return algorithm; } + } + + public int KeySize + { + get { return keySize; } + } + + public byte[] GetZ() + { + // TODO Clone? + return z; + } + + public byte[] GetExtraInfo() + { + // TODO Clone? + return extraInfo; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/kdf/DHKdfParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/kdf/DHKdfParameters.cs.meta new file mode 100644 index 0000000..b8f3955 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/kdf/DHKdfParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3b209fe7b8b788240a9ec93111138d7e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/kdf/DHKekGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/kdf/DHKekGenerator.cs new file mode 100644 index 0000000..259e21e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/kdf/DHKekGenerator.cs @@ -0,0 +1,112 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Crypto.Utilities; + +namespace Org.BouncyCastle.Crypto.Agreement.Kdf +{ + /** + * RFC 2631 Diffie-hellman KEK derivation function. + */ + public class DHKekGenerator + : IDerivationFunction + { + private readonly IDigest digest; + + private DerObjectIdentifier algorithm; + private int keySize; + private byte[] z; + private byte[] partyAInfo; + + public DHKekGenerator(IDigest digest) + { + this.digest = digest; + } + + public virtual void Init(IDerivationParameters param) + { + DHKdfParameters parameters = (DHKdfParameters)param; + + this.algorithm = parameters.Algorithm; + this.keySize = parameters.KeySize; + this.z = parameters.GetZ(); // TODO Clone? + this.partyAInfo = parameters.GetExtraInfo(); // TODO Clone? + } + + public virtual IDigest Digest + { + get { return digest; } + } + + public virtual int GenerateBytes(byte[] outBytes, int outOff, int len) + { + if ((outBytes.Length - len) < outOff) + { + throw new DataLengthException("output buffer too small"); + } + + long oBytes = len; + int outLen = digest.GetDigestSize(); + + // + // this is at odds with the standard implementation, the + // maximum value should be hBits * (2^32 - 1) where hBits + // is the digest output size in bits. We can't have an + // array with a long index at the moment... + // + if (oBytes > ((2L << 32) - 1)) + { + throw new ArgumentException("Output length too large"); + } + + int cThreshold = (int)((oBytes + outLen - 1) / outLen); + + byte[] dig = new byte[digest.GetDigestSize()]; + + uint counter = 1; + + for (int i = 0; i < cThreshold; i++) + { + digest.BlockUpdate(z, 0, z.Length); + + // KeySpecificInfo + DerSequence keyInfo = new DerSequence( + algorithm, + new DerOctetString(Pack.UInt32_To_BE(counter))); + + // OtherInfo + Asn1EncodableVector v1 = new Asn1EncodableVector(keyInfo); + + if (partyAInfo != null) + { + v1.Add(new DerTaggedObject(true, 0, new DerOctetString(partyAInfo))); + } + + v1.Add(new DerTaggedObject(true, 2, new DerOctetString(Pack.UInt32_To_BE((uint)keySize)))); + + byte[] other = new DerSequence(v1).GetDerEncoded(); + + digest.BlockUpdate(other, 0, other.Length); + + digest.DoFinal(dig, 0); + + if (len > outLen) + { + Array.Copy(dig, 0, outBytes, outOff, outLen); + outOff += outLen; + len -= outLen; + } + else + { + Array.Copy(dig, 0, outBytes, outOff, len); + } + + counter++; + } + + digest.Reset(); + + return (int)oBytes; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/kdf/DHKekGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/kdf/DHKekGenerator.cs.meta new file mode 100644 index 0000000..0732e9a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/kdf/DHKekGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0b559bd03b980b942bc7655d6bcd3953 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/kdf/ECDHKekGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/kdf/ECDHKekGenerator.cs new file mode 100644 index 0000000..7446457 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/kdf/ECDHKekGenerator.cs @@ -0,0 +1,55 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; + +namespace Org.BouncyCastle.Crypto.Agreement.Kdf +{ + /** + * X9.63 based key derivation function for ECDH CMS. + */ + public class ECDHKekGenerator + : IDerivationFunction + { + private readonly IDerivationFunction kdf; + + private DerObjectIdentifier algorithm; + private int keySize; + private byte[] z; + + public ECDHKekGenerator(IDigest digest) + { + this.kdf = new Kdf2BytesGenerator(digest); + } + + public virtual void Init(IDerivationParameters param) + { + DHKdfParameters parameters = (DHKdfParameters)param; + + this.algorithm = parameters.Algorithm; + this.keySize = parameters.KeySize; + this.z = parameters.GetZ(); // TODO Clone? + } + + public virtual IDigest Digest + { + get { return kdf.Digest; } + } + + public virtual int GenerateBytes(byte[] outBytes, int outOff, int len) + { + // TODO Create an ASN.1 class for this (RFC3278) + // ECC-CMS-SharedInfo + DerSequence s = new DerSequence( + new AlgorithmIdentifier(algorithm, DerNull.Instance), + new DerTaggedObject(true, 2, new DerOctetString(Pack.UInt32_To_BE((uint)keySize)))); + + kdf.Init(new KdfParameters(z, s.GetDerEncoded())); + + return kdf.GenerateBytes(outBytes, outOff, len); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/kdf/ECDHKekGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/kdf/ECDHKekGenerator.cs.meta new file mode 100644 index 0000000..a000211 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/kdf/ECDHKekGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c62beee36d043e746bb5719637546a90 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/srp.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/srp.meta new file mode 100644 index 0000000..eb98abc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/srp.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: df703713a4369e84093e7c0939aa5ed7 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/srp/SRP6Client.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/srp/SRP6Client.cs new file mode 100644 index 0000000..f075d7a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/srp/SRP6Client.cs @@ -0,0 +1,164 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Agreement.Srp +{ + /** + * Implements the client side SRP-6a protocol. Note that this class is stateful, and therefore NOT threadsafe. + * This implementation of SRP is based on the optimized message sequence put forth by Thomas Wu in the paper + * "SRP-6: Improvements and Refinements to the Secure Remote Password Protocol, 2002" + */ + public class Srp6Client + { + protected BigInteger N; + protected BigInteger g; + + protected BigInteger privA; + protected BigInteger pubA; + + protected BigInteger B; + + protected BigInteger x; + protected BigInteger u; + protected BigInteger S; + + protected BigInteger M1; + protected BigInteger M2; + protected BigInteger Key; + + protected IDigest digest; + protected SecureRandom random; + + public Srp6Client() + { + } + + /** + * Initialises the client to begin new authentication attempt + * @param N The safe prime associated with the client's verifier + * @param g The group parameter associated with the client's verifier + * @param digest The digest algorithm associated with the client's verifier + * @param random For key generation + */ + public virtual void Init(BigInteger N, BigInteger g, IDigest digest, SecureRandom random) + { + this.N = N; + this.g = g; + this.digest = digest; + this.random = random; + } + + public virtual void Init(Srp6GroupParameters group, IDigest digest, SecureRandom random) + { + Init(group.N, group.G, digest, random); + } + + /** + * Generates client's credentials given the client's salt, identity and password + * @param salt The salt used in the client's verifier. + * @param identity The user's identity (eg. username) + * @param password The user's password + * @return Client's public value to send to server + */ + public virtual BigInteger GenerateClientCredentials(byte[] salt, byte[] identity, byte[] password) + { + this.x = Srp6Utilities.CalculateX(digest, N, salt, identity, password); + this.privA = SelectPrivateValue(); + this.pubA = g.ModPow(privA, N); + + return pubA; + } + + /** + * Generates client's verification message given the server's credentials + * @param serverB The server's credentials + * @return Client's verification message for the server + * @throws CryptoException If server's credentials are invalid + */ + public virtual BigInteger CalculateSecret(BigInteger serverB) + { + this.B = Srp6Utilities.ValidatePublicValue(N, serverB); + this.u = Srp6Utilities.CalculateU(digest, N, pubA, B); + this.S = CalculateS(); + + return S; + } + + protected virtual BigInteger SelectPrivateValue() + { + return Srp6Utilities.GeneratePrivateValue(digest, N, g, random); + } + + private BigInteger CalculateS() + { + BigInteger k = Srp6Utilities.CalculateK(digest, N, g); + BigInteger exp = u.Multiply(x).Add(privA); + BigInteger tmp = g.ModPow(x, N).Multiply(k).Mod(N); + return B.Subtract(tmp).Mod(N).ModPow(exp, N); + } + + /** + * Computes the client evidence message M1 using the previously received values. + * To be called after calculating the secret S. + * @return M1: the client side generated evidence message + * @throws CryptoException + */ + public virtual BigInteger CalculateClientEvidenceMessage() + { + // Verify pre-requirements + if (this.pubA == null || this.B == null || this.S == null) + { + throw new CryptoException("Impossible to compute M1: " + + "some data are missing from the previous operations (A,B,S)"); + } + // compute the client evidence message 'M1' + this.M1 = Srp6Utilities.CalculateM1(digest, N, pubA, B, S); + return M1; + } + + /** Authenticates the server evidence message M2 received and saves it only if correct. + * @param M2: the server side generated evidence message + * @return A boolean indicating if the server message M2 was the expected one. + * @throws CryptoException + */ + public virtual bool VerifyServerEvidenceMessage(BigInteger serverM2) + { + // Verify pre-requirements + if (this.pubA == null || this.M1 == null || this.S == null) + { + throw new CryptoException("Impossible to compute and verify M2: " + + "some data are missing from the previous operations (A,M1,S)"); + } + + // Compute the own server evidence message 'M2' + BigInteger computedM2 = Srp6Utilities.CalculateM2(digest, N, pubA, M1, S); + if (computedM2.Equals(serverM2)) + { + this.M2 = serverM2; + return true; + } + return false; + } + + /** + * Computes the final session key as a result of the SRP successful mutual authentication + * To be called after verifying the server evidence message M2. + * @return Key: the mutually authenticated symmetric session key + * @throws CryptoException + */ + public virtual BigInteger CalculateSessionKey() + { + // Verify pre-requirements (here we enforce a previous calculation of M1 and M2) + if (this.S == null || this.M1 == null || this.M2 == null) + { + throw new CryptoException("Impossible to compute Key: " + + "some data are missing from the previous operations (S,M1,M2)"); + } + this.Key = Srp6Utilities.CalculateKey(digest, N, S); + return Key; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/srp/SRP6Client.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/srp/SRP6Client.cs.meta new file mode 100644 index 0000000..e13fc60 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/srp/SRP6Client.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d69887c889ec2404bada5eb04289d81e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/srp/SRP6Server.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/srp/SRP6Server.cs new file mode 100644 index 0000000..fd0c9f1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/srp/SRP6Server.cs @@ -0,0 +1,163 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Agreement.Srp +{ + /** + * Implements the server side SRP-6a protocol. Note that this class is stateful, and therefore NOT threadsafe. + * This implementation of SRP is based on the optimized message sequence put forth by Thomas Wu in the paper + * "SRP-6: Improvements and Refinements to the Secure Remote Password Protocol, 2002" + */ + public class Srp6Server + { + protected BigInteger N; + protected BigInteger g; + protected BigInteger v; + + protected SecureRandom random; + protected IDigest digest; + + protected BigInteger A; + + protected BigInteger privB; + protected BigInteger pubB; + + protected BigInteger u; + protected BigInteger S; + protected BigInteger M1; + protected BigInteger M2; + protected BigInteger Key; + + public Srp6Server() + { + } + + /** + * Initialises the server to accept a new client authentication attempt + * @param N The safe prime associated with the client's verifier + * @param g The group parameter associated with the client's verifier + * @param v The client's verifier + * @param digest The digest algorithm associated with the client's verifier + * @param random For key generation + */ + public virtual void Init(BigInteger N, BigInteger g, BigInteger v, IDigest digest, SecureRandom random) + { + this.N = N; + this.g = g; + this.v = v; + + this.random = random; + this.digest = digest; + } + + public virtual void Init(Srp6GroupParameters group, BigInteger v, IDigest digest, SecureRandom random) + { + Init(group.N, group.G, v, digest, random); + } + + /** + * Generates the server's credentials that are to be sent to the client. + * @return The server's public value to the client + */ + public virtual BigInteger GenerateServerCredentials() + { + BigInteger k = Srp6Utilities.CalculateK(digest, N, g); + this.privB = SelectPrivateValue(); + this.pubB = k.Multiply(v).Mod(N).Add(g.ModPow(privB, N)).Mod(N); + + return pubB; + } + + /** + * Processes the client's credentials. If valid the shared secret is generated and returned. + * @param clientA The client's credentials + * @return A shared secret BigInteger + * @throws CryptoException If client's credentials are invalid + */ + public virtual BigInteger CalculateSecret(BigInteger clientA) + { + this.A = Srp6Utilities.ValidatePublicValue(N, clientA); + this.u = Srp6Utilities.CalculateU(digest, N, A, pubB); + this.S = CalculateS(); + + return S; + } + + protected virtual BigInteger SelectPrivateValue() + { + return Srp6Utilities.GeneratePrivateValue(digest, N, g, random); + } + + private BigInteger CalculateS() + { + return v.ModPow(u, N).Multiply(A).Mod(N).ModPow(privB, N); + } + + /** + * Authenticates the received client evidence message M1 and saves it only if correct. + * To be called after calculating the secret S. + * @param M1: the client side generated evidence message + * @return A boolean indicating if the client message M1 was the expected one. + * @throws CryptoException + */ + public virtual bool VerifyClientEvidenceMessage(BigInteger clientM1) + { + // Verify pre-requirements + if (this.A == null || this.pubB == null || this.S == null) + { + throw new CryptoException("Impossible to compute and verify M1: " + + "some data are missing from the previous operations (A,B,S)"); + } + + // Compute the own client evidence message 'M1' + BigInteger computedM1 = Srp6Utilities.CalculateM1(digest, N, A, pubB, S); + if (computedM1.Equals(clientM1)) + { + this.M1 = clientM1; + return true; + } + return false; + } + + /** + * Computes the server evidence message M2 using the previously verified values. + * To be called after successfully verifying the client evidence message M1. + * @return M2: the server side generated evidence message + * @throws CryptoException + */ + public virtual BigInteger CalculateServerEvidenceMessage() + { + // Verify pre-requirements + if (this.A == null || this.M1 == null || this.S == null) + { + throw new CryptoException("Impossible to compute M2: " + + "some data are missing from the previous operations (A,M1,S)"); + } + + // Compute the server evidence message 'M2' + this.M2 = Srp6Utilities.CalculateM2(digest, N, A, M1, S); + return M2; + } + + /** + * Computes the final session key as a result of the SRP successful mutual authentication + * To be called after calculating the server evidence message M2. + * @return Key: the mutual authenticated symmetric session key + * @throws CryptoException + */ + public virtual BigInteger CalculateSessionKey() + { + // Verify pre-requirements + if (this.S == null || this.M1 == null || this.M2 == null) + { + throw new CryptoException("Impossible to compute Key: " + + "some data are missing from the previous operations (S,M1,M2)"); + } + this.Key = Srp6Utilities.CalculateKey(digest, N, S); + return Key; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/srp/SRP6Server.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/srp/SRP6Server.cs.meta new file mode 100644 index 0000000..d3ccadd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/srp/SRP6Server.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ec8d003ef20196e43811c81512d98e6c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/srp/SRP6StandardGroups.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/srp/SRP6StandardGroups.cs new file mode 100644 index 0000000..464777d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/srp/SRP6StandardGroups.cs @@ -0,0 +1,159 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Crypto.Agreement.Srp +{ + public class Srp6StandardGroups + { + private static BigInteger FromHex(string hex) + { + return new BigInteger(1, Hex.DecodeStrict(hex)); + } + + private static Srp6GroupParameters FromNG(string hexN, string hexG) + { + return new Srp6GroupParameters(FromHex(hexN), FromHex(hexG)); + } + + /* + * RFC 5054 + */ + private const string rfc5054_1024_N = "EEAF0AB9ADB38DD69C33F80AFA8FC5E86072618775FF3C0B9EA2314C" + + "9C256576D674DF7496EA81D3383B4813D692C6E0E0D5D8E250B98BE4" + + "8E495C1D6089DAD15DC7D7B46154D6B6CE8EF4AD69B15D4982559B29" + + "7BCF1885C529F566660E57EC68EDBC3C05726CC02FD4CBF4976EAA9A" + "FD5138FE8376435B9FC61D2FC0EB06E3"; + private const string rfc5054_1024_g = "02"; + public static readonly Srp6GroupParameters rfc5054_1024 = FromNG(rfc5054_1024_N, rfc5054_1024_g); + + private const string rfc5054_1536_N = "9DEF3CAFB939277AB1F12A8617A47BBBDBA51DF499AC4C80BEEEA961" + + "4B19CC4D5F4F5F556E27CBDE51C6A94BE4607A291558903BA0D0F843" + + "80B655BB9A22E8DCDF028A7CEC67F0D08134B1C8B97989149B609E0B" + + "E3BAB63D47548381DBC5B1FC764E3F4B53DD9DA1158BFD3E2B9C8CF5" + + "6EDF019539349627DB2FD53D24B7C48665772E437D6C7F8CE442734A" + + "F7CCB7AE837C264AE3A9BEB87F8A2FE9B8B5292E5A021FFF5E91479E" + + "8CE7A28C2442C6F315180F93499A234DCF76E3FED135F9BB"; + private const string rfc5054_1536_g = "02"; + public static readonly Srp6GroupParameters rfc5054_1536 = FromNG(rfc5054_1536_N, rfc5054_1536_g); + + private const string rfc5054_2048_N = "AC6BDB41324A9A9BF166DE5E1389582FAF72B6651987EE07FC319294" + + "3DB56050A37329CBB4A099ED8193E0757767A13DD52312AB4B03310D" + + "CD7F48A9DA04FD50E8083969EDB767B0CF6095179A163AB3661A05FB" + + "D5FAAAE82918A9962F0B93B855F97993EC975EEAA80D740ADBF4FF74" + + "7359D041D5C33EA71D281E446B14773BCA97B43A23FB801676BD207A" + + "436C6481F1D2B9078717461A5B9D32E688F87748544523B524B0D57D" + + "5EA77A2775D2ECFA032CFBDBF52FB3786160279004E57AE6AF874E73" + + "03CE53299CCC041C7BC308D82A5698F3A8D0C38271AE35F8E9DBFBB6" + + "94B5C803D89F7AE435DE236D525F54759B65E372FCD68EF20FA7111F" + "9E4AFF73"; + private const string rfc5054_2048_g = "02"; + public static readonly Srp6GroupParameters rfc5054_2048 = FromNG(rfc5054_2048_N, rfc5054_2048_g); + + private const string rfc5054_3072_N = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E08" + + "8A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B" + + "302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9" + + "A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE6" + + "49286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8" + + "FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D" + + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C" + + "180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718" + + "3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D" + + "04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7D" + + "B3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D226" + + "1AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200C" + + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFC" + "E0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF"; + private const string rfc5054_3072_g = "05"; + public static readonly Srp6GroupParameters rfc5054_3072 = FromNG(rfc5054_3072_N, rfc5054_3072_g); + + private const string rfc5054_4096_N = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E08" + + "8A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B" + + "302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9" + + "A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE6" + + "49286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8" + + "FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D" + + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C" + + "180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718" + + "3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D" + + "04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7D" + + "B3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D226" + + "1AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200C" + + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFC" + + "E0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B26" + + "99C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB" + + "04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2" + + "233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127" + + "D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199" + "FFFFFFFFFFFFFFFF"; + private const string rfc5054_4096_g = "05"; + public static readonly Srp6GroupParameters rfc5054_4096 = FromNG(rfc5054_4096_N, rfc5054_4096_g); + + private const string rfc5054_6144_N = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E08" + + "8A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B" + + "302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9" + + "A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE6" + + "49286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8" + + "FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D" + + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C" + + "180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718" + + "3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D" + + "04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7D" + + "B3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D226" + + "1AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200C" + + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFC" + + "E0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B26" + + "99C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB" + + "04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2" + + "233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127" + + "D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492" + + "36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BDF8FF9406" + + "AD9E530EE5DB382F413001AEB06A53ED9027D831179727B0865A8918" + + "DA3EDBEBCF9B14ED44CE6CBACED4BB1BDB7F1447E6CC254B33205151" + + "2BD7AF426FB8F401378CD2BF5983CA01C64B92ECF032EA15D1721D03" + + "F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E59E7C97F" + + "BEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA" + + "CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58B" + + "B7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632" + + "387FE8D76E3C0468043E8F663F4860EE12BF2D5B0B7474D6E694F91E" + "6DCC4024FFFFFFFFFFFFFFFF"; + private const string rfc5054_6144_g = "05"; + public static readonly Srp6GroupParameters rfc5054_6144 = FromNG(rfc5054_6144_N, rfc5054_6144_g); + + private const string rfc5054_8192_N = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E08" + + "8A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B" + + "302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9" + + "A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE6" + + "49286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8" + + "FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D" + + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C" + + "180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718" + + "3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D" + + "04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7D" + + "B3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D226" + + "1AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200C" + + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFC" + + "E0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B26" + + "99C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB" + + "04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2" + + "233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127" + + "D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492" + + "36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BDF8FF9406" + + "AD9E530EE5DB382F413001AEB06A53ED9027D831179727B0865A8918" + + "DA3EDBEBCF9B14ED44CE6CBACED4BB1BDB7F1447E6CC254B33205151" + + "2BD7AF426FB8F401378CD2BF5983CA01C64B92ECF032EA15D1721D03" + + "F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E59E7C97F" + + "BEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA" + + "CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58B" + + "B7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632" + + "387FE8D76E3C0468043E8F663F4860EE12BF2D5B0B7474D6E694F91E" + + "6DBE115974A3926F12FEE5E438777CB6A932DF8CD8BEC4D073B931BA" + + "3BC832B68D9DD300741FA7BF8AFC47ED2576F6936BA424663AAB639C" + + "5AE4F5683423B4742BF1C978238F16CBE39D652DE3FDB8BEFC848AD9" + + "22222E04A4037C0713EB57A81A23F0C73473FC646CEA306B4BCBC886" + + "2F8385DDFA9D4B7FA2C087E879683303ED5BDD3A062B3CF5B3A278A6" + + "6D2A13F83F44F82DDF310EE074AB6A364597E899A0255DC164F31CC5" + + "0846851DF9AB48195DED7EA1B1D510BD7EE74D73FAF36BC31ECFA268" + + "359046F4EB879F924009438B481C6CD7889A002ED5EE382BC9190DA6" + + "FC026E479558E4475677E9AA9E3050E2765694DFC81F56E880B96E71" + "60C980DD98EDD3DFFFFFFFFFFFFFFFFF"; + private const string rfc5054_8192_g = "13"; + public static readonly Srp6GroupParameters rfc5054_8192 = FromNG(rfc5054_8192_N, rfc5054_8192_g); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/srp/SRP6StandardGroups.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/srp/SRP6StandardGroups.cs.meta new file mode 100644 index 0000000..95a785b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/srp/SRP6StandardGroups.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e0a981aceefa2d044afe49df0720e244 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/srp/SRP6Utilities.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/srp/SRP6Utilities.cs new file mode 100644 index 0000000..ef6d8f2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/srp/SRP6Utilities.cs @@ -0,0 +1,153 @@ +using System; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Agreement.Srp +{ + public class Srp6Utilities + { + public static BigInteger CalculateK(IDigest digest, BigInteger N, BigInteger g) + { + return HashPaddedPair(digest, N, N, g); + } + + public static BigInteger CalculateU(IDigest digest, BigInteger N, BigInteger A, BigInteger B) + { + return HashPaddedPair(digest, N, A, B); + } + + public static BigInteger CalculateX(IDigest digest, BigInteger N, byte[] salt, byte[] identity, byte[] password) + { + byte[] output = new byte[digest.GetDigestSize()]; + + digest.BlockUpdate(identity, 0, identity.Length); + digest.Update((byte)':'); + digest.BlockUpdate(password, 0, password.Length); + digest.DoFinal(output, 0); + + digest.BlockUpdate(salt, 0, salt.Length); + digest.BlockUpdate(output, 0, output.Length); + digest.DoFinal(output, 0); + + return new BigInteger(1, output); + } + + public static BigInteger GeneratePrivateValue(IDigest digest, BigInteger N, BigInteger g, SecureRandom random) + { + int minBits = System.Math.Min(256, N.BitLength / 2); + BigInteger min = BigInteger.One.ShiftLeft(minBits - 1); + BigInteger max = N.Subtract(BigInteger.One); + + return BigIntegers.CreateRandomInRange(min, max, random); + } + + public static BigInteger ValidatePublicValue(BigInteger N, BigInteger val) + { + val = val.Mod(N); + + // Check that val % N != 0 + if (val.Equals(BigInteger.Zero)) + throw new CryptoException("Invalid public value: 0"); + + return val; + } + + /** + * Computes the client evidence message (M1) according to the standard routine: + * M1 = H( A | B | S ) + * @param digest The Digest used as the hashing function H + * @param N Modulus used to get the pad length + * @param A The public client value + * @param B The public server value + * @param S The secret calculated by both sides + * @return M1 The calculated client evidence message + */ + public static BigInteger CalculateM1(IDigest digest, BigInteger N, BigInteger A, BigInteger B, BigInteger S) + { + BigInteger M1 = HashPaddedTriplet(digest, N, A, B, S); + return M1; + } + + /** + * Computes the server evidence message (M2) according to the standard routine: + * M2 = H( A | M1 | S ) + * @param digest The Digest used as the hashing function H + * @param N Modulus used to get the pad length + * @param A The public client value + * @param M1 The client evidence message + * @param S The secret calculated by both sides + * @return M2 The calculated server evidence message + */ + public static BigInteger CalculateM2(IDigest digest, BigInteger N, BigInteger A, BigInteger M1, BigInteger S) + { + BigInteger M2 = HashPaddedTriplet(digest, N, A, M1, S); + return M2; + } + + /** + * Computes the final Key according to the standard routine: Key = H(S) + * @param digest The Digest used as the hashing function H + * @param N Modulus used to get the pad length + * @param S The secret calculated by both sides + * @return + */ + public static BigInteger CalculateKey(IDigest digest, BigInteger N, BigInteger S) + { + int padLength = (N.BitLength + 7) / 8; + byte[] _S = GetPadded(S, padLength); + digest.BlockUpdate(_S, 0, _S.Length); + + byte[] output = new byte[digest.GetDigestSize()]; + digest.DoFinal(output, 0); + return new BigInteger(1, output); + } + + private static BigInteger HashPaddedTriplet(IDigest digest, BigInteger N, BigInteger n1, BigInteger n2, BigInteger n3) + { + int padLength = (N.BitLength + 7) / 8; + + byte[] n1_bytes = GetPadded(n1, padLength); + byte[] n2_bytes = GetPadded(n2, padLength); + byte[] n3_bytes = GetPadded(n3, padLength); + + digest.BlockUpdate(n1_bytes, 0, n1_bytes.Length); + digest.BlockUpdate(n2_bytes, 0, n2_bytes.Length); + digest.BlockUpdate(n3_bytes, 0, n3_bytes.Length); + + byte[] output = new byte[digest.GetDigestSize()]; + digest.DoFinal(output, 0); + + return new BigInteger(1, output); + } + + private static BigInteger HashPaddedPair(IDigest digest, BigInteger N, BigInteger n1, BigInteger n2) + { + int padLength = (N.BitLength + 7) / 8; + + byte[] n1_bytes = GetPadded(n1, padLength); + byte[] n2_bytes = GetPadded(n2, padLength); + + digest.BlockUpdate(n1_bytes, 0, n1_bytes.Length); + digest.BlockUpdate(n2_bytes, 0, n2_bytes.Length); + + byte[] output = new byte[digest.GetDigestSize()]; + digest.DoFinal(output, 0); + + return new BigInteger(1, output); + } + + private static byte[] GetPadded(BigInteger n, int length) + { + byte[] bs = BigIntegers.AsUnsignedByteArray(n); + if (bs.Length < length) + { + byte[] tmp = new byte[length]; + Array.Copy(bs, 0, tmp, length - bs.Length, bs.Length); + bs = tmp; + } + return bs; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/srp/SRP6Utilities.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/srp/SRP6Utilities.cs.meta new file mode 100644 index 0000000..c79b3bf --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/srp/SRP6Utilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e69f090dfddb4214bac0f7641116b06a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/srp/SRP6VerifierGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/srp/SRP6VerifierGenerator.cs new file mode 100644 index 0000000..9569735 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/srp/SRP6VerifierGenerator.cs @@ -0,0 +1,55 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Agreement.Srp +{ + /** + * Generates new SRP verifier for user + */ + public class Srp6VerifierGenerator + { + protected BigInteger N; + protected BigInteger g; + protected IDigest digest; + + public Srp6VerifierGenerator() + { + } + + /** + * Initialises generator to create new verifiers + * @param N The safe prime to use (see DHParametersGenerator) + * @param g The group parameter to use (see DHParametersGenerator) + * @param digest The digest to use. The same digest type will need to be used later for the actual authentication + * attempt. Also note that the final session key size is dependent on the chosen digest. + */ + public virtual void Init(BigInteger N, BigInteger g, IDigest digest) + { + this.N = N; + this.g = g; + this.digest = digest; + } + + public virtual void Init(Srp6GroupParameters group, IDigest digest) + { + Init(group.N, group.G, digest); + } + + /** + * Creates a new SRP verifier + * @param salt The salt to use, generally should be large and random + * @param identity The user's identifying information (eg. username) + * @param password The user's password + * @return A new verifier for use in future SRP authentication + */ + public virtual BigInteger GenerateVerifier(byte[] salt, byte[] identity, byte[] password) + { + BigInteger x = Srp6Utilities.CalculateX(digest, N, salt, identity, password); + + return g.ModPow(x, N); + } + } +} + diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/srp/SRP6VerifierGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/srp/SRP6VerifierGenerator.cs.meta new file mode 100644 index 0000000..7abf98e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/agreement/srp/SRP6VerifierGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1c6aba8b70909fa42936c854ec2c9ed6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests.meta new file mode 100644 index 0000000..e367f67 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ef24ec21ded3f3f46b49214a43357acc +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/Blake2bDigest.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/Blake2bDigest.cs new file mode 100644 index 0000000..770e35c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/Blake2bDigest.cs @@ -0,0 +1,531 @@ +using System; + +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /* The BLAKE2 cryptographic hash function was designed by Jean- + Philippe Aumasson, Samuel Neves, Zooko Wilcox-O'Hearn, and Christian + Winnerlein. + + Reference Implementation and Description can be found at: https://blake2.net/ + Internet Draft: https://tools.ietf.org/html/draft-saarinen-blake2-02 + + This implementation does not support the Tree Hashing Mode. + + For unkeyed hashing, developers adapting BLAKE2 to ASN.1 - based + message formats SHOULD use the OID tree at x = 1.3.6.1.4.1.1722.12.2. + + Algorithm | Target | Collision | Hash | Hash ASN.1 | + Identifier | Arch | Security | nn | OID Suffix | + ---------------+--------+-----------+------+------------+ + id-blake2b160 | 64-bit | 2**80 | 20 | x.1.20 | + id-blake2b256 | 64-bit | 2**128 | 32 | x.1.32 | + id-blake2b384 | 64-bit | 2**192 | 48 | x.1.48 | + id-blake2b512 | 64-bit | 2**256 | 64 | x.1.64 | + ---------------+--------+-----------+------+------------+ + */ + + /** + * Implementation of the cryptographic hash function Blakbe2b. + *

+ * Blake2b offers a built-in keying mechanism to be used directly + * for authentication ("Prefix-MAC") rather than a HMAC construction. + *

+ * Blake2b offers a built-in support for a salt for randomized hashing + * and a personal string for defining a unique hash function for each application. + *

+ * BLAKE2b is optimized for 64-bit platforms and produces digests of any size + * between 1 and 64 bytes. + */ + public class Blake2bDigest + : IDigest + { + // Blake2b Initialization Vector: + private static readonly ulong[] blake2b_IV = + // Produced from the square root of primes 2, 3, 5, 7, 11, 13, 17, 19. + // The same as SHA-512 IV. + { + 0x6a09e667f3bcc908UL, 0xbb67ae8584caa73bUL, 0x3c6ef372fe94f82bUL, + 0xa54ff53a5f1d36f1UL, 0x510e527fade682d1UL, 0x9b05688c2b3e6c1fUL, + 0x1f83d9abfb41bd6bUL, 0x5be0cd19137e2179UL + }; + + // Message word permutations: + private static readonly byte[,] blake2b_sigma = + { + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, + { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }, + { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 }, + { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 }, + { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 }, + { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 }, + { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 }, + { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 }, + { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 }, + { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, + { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } + }; + + private const int ROUNDS = 12; // to use for Catenas H' + private const int BLOCK_LENGTH_BYTES = 128;// bytes + + // General parameters: + private int digestLength = 64; // 1- 64 bytes + private int keyLength = 0; // 0 - 64 bytes for keyed hashing for MAC + private byte[] salt = null;// new byte[16]; + private byte[] personalization = null;// new byte[16]; + + // the key + private byte[] key = null; + + // Tree hashing parameters: + // Because this class does not implement the Tree Hashing Mode, + // these parameters can be treated as constants (see init() function) + /* + * private int fanout = 1; // 0-255 private int depth = 1; // 1 - 255 + * private int leafLength= 0; private long nodeOffset = 0L; private int + * nodeDepth = 0; private int innerHashLength = 0; + */ + + // whenever this buffer overflows, it will be processed + // in the Compress() function. + // For performance issues, long messages will not use this buffer. + private byte[] buffer = null;// new byte[BLOCK_LENGTH_BYTES]; + // Position of last inserted byte: + private int bufferPos = 0;// a value from 0 up to 128 + + private ulong[] internalState = new ulong[16]; // In the Blake2b paper it is + // called: v + private ulong[] chainValue = null; // state vector, in the Blake2b paper it + // is called: h + + private ulong t0 = 0UL; // holds last significant bits, counter (counts bytes) + private ulong t1 = 0UL; // counter: Length up to 2^128 are supported + private ulong f0 = 0UL; // finalization flag, for last block: ~0L + + // For Tree Hashing Mode, not used here: + // private long f1 = 0L; // finalization flag, for last node: ~0L + + public Blake2bDigest() + : this(512) + { + } + + public Blake2bDigest(Blake2bDigest digest) + { + this.bufferPos = digest.bufferPos; + this.buffer = Arrays.Clone(digest.buffer); + this.keyLength = digest.keyLength; + this.key = Arrays.Clone(digest.key); + this.digestLength = digest.digestLength; + this.chainValue = Arrays.Clone(digest.chainValue); + this.personalization = Arrays.Clone(digest.personalization); + this.salt = Arrays.Clone(digest.salt); + this.t0 = digest.t0; + this.t1 = digest.t1; + this.f0 = digest.f0; + } + + /** + * Basic sized constructor - size in bits. + * + * @param digestSize size of the digest in bits + */ + public Blake2bDigest(int digestSize) + { + if (digestSize < 8 || digestSize > 512 || digestSize % 8 != 0) + throw new ArgumentException("BLAKE2b digest bit length must be a multiple of 8 and not greater than 512"); + + buffer = new byte[BLOCK_LENGTH_BYTES]; + keyLength = 0; + this.digestLength = digestSize / 8; + Init(); + } + + /** + * Blake2b for authentication ("Prefix-MAC mode"). + * After calling the doFinal() method, the key will + * remain to be used for further computations of + * this instance. + * The key can be overwritten using the clearKey() method. + * + * @param key A key up to 64 bytes or null + */ + public Blake2bDigest(byte[] key) + { + buffer = new byte[BLOCK_LENGTH_BYTES]; + if (key != null) + { + this.key = new byte[key.Length]; + Array.Copy(key, 0, this.key, 0, key.Length); + + if (key.Length > 64) + throw new ArgumentException("Keys > 64 are not supported"); + + keyLength = key.Length; + Array.Copy(key, 0, buffer, 0, key.Length); + bufferPos = BLOCK_LENGTH_BYTES; // zero padding + } + digestLength = 64; + Init(); + } + + /** + * Blake2b with key, required digest length (in bytes), salt and personalization. + * After calling the doFinal() method, the key, the salt and the personal string + * will remain and might be used for further computations with this instance. + * The key can be overwritten using the clearKey() method, the salt (pepper) + * can be overwritten using the clearSalt() method. + * + * @param key A key up to 64 bytes or null + * @param digestLength from 1 up to 64 bytes + * @param salt 16 bytes or null + * @param personalization 16 bytes or null + */ + public Blake2bDigest(byte[] key, int digestLength, byte[] salt, byte[] personalization) + { + if (digestLength < 1 || digestLength > 64) + throw new ArgumentException("Invalid digest length (required: 1 - 64)"); + + this.digestLength = digestLength; + this.buffer = new byte[BLOCK_LENGTH_BYTES]; + + if (salt != null) + { + if (salt.Length != 16) + throw new ArgumentException("salt length must be exactly 16 bytes"); + + this.salt = new byte[16]; + Array.Copy(salt, 0, this.salt, 0, salt.Length); + } + if (personalization != null) + { + if (personalization.Length != 16) + throw new ArgumentException("personalization length must be exactly 16 bytes"); + + this.personalization = new byte[16]; + Array.Copy(personalization, 0, this.personalization, 0, personalization.Length); + } + if (key != null) + { + if (key.Length > 64) + throw new ArgumentException("Keys > 64 are not supported"); + + this.key = new byte[key.Length]; + Array.Copy(key, 0, this.key, 0, key.Length); + + keyLength = key.Length; + Array.Copy(key, 0, buffer, 0, key.Length); + bufferPos = BLOCK_LENGTH_BYTES; // zero padding + } + Init(); + } + + // initialize chainValue + private void Init() + { + if (chainValue == null) + { + chainValue = new ulong[8]; + + chainValue[0] = blake2b_IV[0] ^ (ulong)(digestLength | (keyLength << 8) | 0x1010000); + + // 0x1010000 = ((fanout << 16) | (depth << 24) | (leafLength << + // 32)); + // with fanout = 1; depth = 0; leafLength = 0; + chainValue[1] = blake2b_IV[1];// ^ nodeOffset; with nodeOffset = 0; + chainValue[2] = blake2b_IV[2];// ^ ( nodeDepth | (innerHashLength << 8) ); + // with nodeDepth = 0; innerHashLength = 0; + + chainValue[3] = blake2b_IV[3]; + + chainValue[4] = blake2b_IV[4]; + chainValue[5] = blake2b_IV[5]; + if (salt != null) + { + chainValue[4] ^= Pack.LE_To_UInt64(salt, 0); + chainValue[5] ^= Pack.LE_To_UInt64(salt, 8); + } + + chainValue[6] = blake2b_IV[6]; + chainValue[7] = blake2b_IV[7]; + if (personalization != null) + { + chainValue[6] ^= Pack.LE_To_UInt64(personalization, 0); + chainValue[7] ^= Pack.LE_To_UInt64(personalization, 8); + } + } + } + + private void InitializeInternalState() + { + // initialize v: + Array.Copy(chainValue, 0, internalState, 0, chainValue.Length); + Array.Copy(blake2b_IV, 0, internalState, chainValue.Length, 4); + internalState[12] = t0 ^ blake2b_IV[4]; + internalState[13] = t1 ^ blake2b_IV[5]; + internalState[14] = f0 ^ blake2b_IV[6]; + internalState[15] = blake2b_IV[7];// ^ f1 with f1 = 0 + } + + /** + * update the message digest with a single byte. + * + * @param b the input byte to be entered. + */ + public virtual void Update(byte b) + { + int remainingLength = 0; // left bytes of buffer + + // process the buffer if full else add to buffer: + remainingLength = BLOCK_LENGTH_BYTES - bufferPos; + if (remainingLength == 0) + { // full buffer + t0 += BLOCK_LENGTH_BYTES; + if (t0 == 0) + { // if message > 2^64 + t1++; + } + Compress(buffer, 0); + Array.Clear(buffer, 0, buffer.Length);// clear buffer + buffer[0] = b; + bufferPos = 1; + } + else + { + buffer[bufferPos] = b; + bufferPos++; + return; + } + } + + /** + * update the message digest with a block of bytes. + * + * @param message the byte array containing the data. + * @param offset the offset into the byte array where the data starts. + * @param len the length of the data. + */ + public virtual void BlockUpdate(byte[] message, int offset, int len) + { + if (message == null || len == 0) + return; + + int remainingLength = 0; // left bytes of buffer + + if (bufferPos != 0) + { // commenced, incomplete buffer + + // complete the buffer: + remainingLength = BLOCK_LENGTH_BYTES - bufferPos; + if (remainingLength < len) + { // full buffer + at least 1 byte + Array.Copy(message, offset, buffer, bufferPos, + remainingLength); + t0 += BLOCK_LENGTH_BYTES; + if (t0 == 0) + { // if message > 2^64 + t1++; + } + Compress(buffer, 0); + bufferPos = 0; + Array.Clear(buffer, 0, buffer.Length);// clear buffer + } + else + { + Array.Copy(message, offset, buffer, bufferPos, len); + bufferPos += len; + return; + } + } + + // process blocks except last block (also if last block is full) + int messagePos; + int blockWiseLastPos = offset + len - BLOCK_LENGTH_BYTES; + for (messagePos = offset + remainingLength; messagePos < blockWiseLastPos; messagePos += BLOCK_LENGTH_BYTES) + { // block wise 128 bytes + // without buffer: + t0 += BLOCK_LENGTH_BYTES; + if (t0 == 0) + { + t1++; + } + Compress(message, messagePos); + } + + // fill the buffer with left bytes, this might be a full block + Array.Copy(message, messagePos, buffer, 0, offset + len + - messagePos); + bufferPos += offset + len - messagePos; + } + + /** + * close the digest, producing the final digest value. The doFinal + * call leaves the digest reset. + * Key, salt and personal string remain. + * + * @param out the array the digest is to be copied into. + * @param outOffset the offset into the out array the digest is to start at. + */ + public virtual int DoFinal(byte[] output, int outOffset) + { + f0 = 0xFFFFFFFFFFFFFFFFUL; + t0 += (ulong)bufferPos; + if (bufferPos > 0 && t0 == 0) + { + t1++; + } + Compress(buffer, 0); + Array.Clear(buffer, 0, buffer.Length);// Holds eventually the key if input is null + Array.Clear(internalState, 0, internalState.Length); + + for (int i = 0; i < chainValue.Length && (i * 8 < digestLength); i++) + { + byte[] bytes = Pack.UInt64_To_LE(chainValue[i]); + + if (i * 8 < digestLength - 8) + { + Array.Copy(bytes, 0, output, outOffset + i * 8, 8); + } + else + { + Array.Copy(bytes, 0, output, outOffset + i * 8, digestLength - (i * 8)); + } + } + + Array.Clear(chainValue, 0, chainValue.Length); + + Reset(); + + return digestLength; + } + + /** + * Reset the digest back to it's initial state. + * The key, the salt and the personal string will + * remain for further computations. + */ + public virtual void Reset() + { + bufferPos = 0; + f0 = 0L; + t0 = 0L; + t1 = 0L; + chainValue = null; + Array.Clear(buffer, 0, buffer.Length); + if (key != null) + { + Array.Copy(key, 0, buffer, 0, key.Length); + bufferPos = BLOCK_LENGTH_BYTES; // zero padding + } + Init(); + } + + private void Compress(byte[] message, int messagePos) + { + InitializeInternalState(); + + ulong[] m = new ulong[16]; + for (int j = 0; j < 16; j++) + { + m[j] = Pack.LE_To_UInt64(message, messagePos + j * 8); + } + + for (int round = 0; round < ROUNDS; round++) + { + // G apply to columns of internalState:m[blake2b_sigma[round][2 * blockPos]] /+1 + G(m[blake2b_sigma[round,0]], m[blake2b_sigma[round,1]], 0, 4, 8, 12); + G(m[blake2b_sigma[round,2]], m[blake2b_sigma[round,3]], 1, 5, 9, 13); + G(m[blake2b_sigma[round,4]], m[blake2b_sigma[round,5]], 2, 6, 10, 14); + G(m[blake2b_sigma[round,6]], m[blake2b_sigma[round,7]], 3, 7, 11, 15); + // G apply to diagonals of internalState: + G(m[blake2b_sigma[round,8]], m[blake2b_sigma[round,9]], 0, 5, 10, 15); + G(m[blake2b_sigma[round,10]], m[blake2b_sigma[round,11]], 1, 6, 11, 12); + G(m[blake2b_sigma[round,12]], m[blake2b_sigma[round,13]], 2, 7, 8, 13); + G(m[blake2b_sigma[round,14]], m[blake2b_sigma[round,15]], 3, 4, 9, 14); + } + + // update chain values: + for (int offset = 0; offset < chainValue.Length; offset++) + { + chainValue[offset] = chainValue[offset] ^ internalState[offset] ^ internalState[offset + 8]; + } + } + + private void G(ulong m1, ulong m2, int posA, int posB, int posC, int posD) + { + internalState[posA] = internalState[posA] + internalState[posB] + m1; + internalState[posD] = Rotr64(internalState[posD] ^ internalState[posA], 32); + internalState[posC] = internalState[posC] + internalState[posD]; + internalState[posB] = Rotr64(internalState[posB] ^ internalState[posC], 24); // replaces 25 of BLAKE + internalState[posA] = internalState[posA] + internalState[posB] + m2; + internalState[posD] = Rotr64(internalState[posD] ^ internalState[posA], 16); + internalState[posC] = internalState[posC] + internalState[posD]; + internalState[posB] = Rotr64(internalState[posB] ^ internalState[posC], 63); // replaces 11 of BLAKE + } + + private static ulong Rotr64(ulong x, int rot) + { + return x >> rot | x << -rot; + } + + /** + * return the algorithm name + * + * @return the algorithm name + */ + public virtual string AlgorithmName + { + get { return "BLAKE2b"; } + } + + /** + * return the size, in bytes, of the digest produced by this message digest. + * + * @return the size, in bytes, of the digest produced by this message digest. + */ + public virtual int GetDigestSize() + { + return digestLength; + } + + /** + * Return the size in bytes of the internal buffer the digest applies it's compression + * function to. + * + * @return byte length of the digests internal buffer. + */ + public virtual int GetByteLength() + { + return BLOCK_LENGTH_BYTES; + } + + /** + * Overwrite the key + * if it is no longer used (zeroization) + */ + public virtual void ClearKey() + { + if (key != null) + { + Array.Clear(key, 0, key.Length); + Array.Clear(buffer, 0, buffer.Length); + } + } + + /** + * Overwrite the salt (pepper) if it + * is secret and no longer used (zeroization) + */ + public virtual void ClearSalt() + { + if (salt != null) + { + Array.Clear(salt, 0, salt.Length); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/Blake2bDigest.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/Blake2bDigest.cs.meta new file mode 100644 index 0000000..c6b4cc2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/Blake2bDigest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2d3b08040c4ebfe48a0cde61f918c39c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/Blake2sDigest.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/Blake2sDigest.cs new file mode 100644 index 0000000..432b0f4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/Blake2sDigest.cs @@ -0,0 +1,551 @@ +using System; + +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /* + The BLAKE2 cryptographic hash function was designed by Jean- + Philippe Aumasson, Samuel Neves, Zooko Wilcox-O'Hearn, and Christian + Winnerlein. + + Reference Implementation and Description can be found at: https://blake2.net/ + RFC: https://tools.ietf.org/html/rfc7693 + + This implementation does not support the Tree Hashing Mode. + + For unkeyed hashing, developers adapting BLAKE2 to ASN.1 - based + message formats SHOULD use the OID tree at x = 1.3.6.1.4.1.1722.12.2. + + Algorithm | Target | Collision | Hash | Hash ASN.1 | + Identifier | Arch | Security | nn | OID Suffix | + ---------------+--------+-----------+------+------------+ + id-blake2s128 | 32-bit | 2**64 | 16 | x.2.4 | + id-blake2s160 | 32-bit | 2**80 | 20 | x.2.5 | + id-blake2s224 | 32-bit | 2**112 | 28 | x.2.7 | + id-blake2s256 | 32-bit | 2**128 | 32 | x.2.8 | + ---------------+--------+-----------+------+------------+ + */ + + /** + * Implementation of the cryptographic hash function BLAKE2s. + *

+ * BLAKE2s offers a built-in keying mechanism to be used directly + * for authentication ("Prefix-MAC") rather than a HMAC construction. + *

+ * BLAKE2s offers a built-in support for a salt for randomized hashing + * and a personal string for defining a unique hash function for each application. + *

+ * BLAKE2s is optimized for 32-bit platforms and produces digests of any size + * between 1 and 32 bytes. + */ + public class Blake2sDigest + : IDigest + { + /** + * BLAKE2s Initialization Vector + **/ + private static readonly uint[] blake2s_IV = + // Produced from the square root of primes 2, 3, 5, 7, 11, 13, 17, 19. + // The same as SHA-256 IV. + { + 0x6a09e667, 0xbb67ae85, 0x3c6ef372, + 0xa54ff53a, 0x510e527f, 0x9b05688c, + 0x1f83d9ab, 0x5be0cd19 + }; + + /** + * Message word permutations + **/ + private static readonly byte[,] blake2s_sigma = + { + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, + { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }, + { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 }, + { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 }, + { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 }, + { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 }, + { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 }, + { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 }, + { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 }, + { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 } + }; + + private const int ROUNDS = 10; // to use for Catenas H' + private const int BLOCK_LENGTH_BYTES = 64;// bytes + + // General parameters: + private int digestLength = 32; // 1- 32 bytes + private int keyLength = 0; // 0 - 32 bytes for keyed hashing for MAC + private byte[] salt = null; + private byte[] personalization = null; + private byte[] key = null; + + // Tree hashing parameters: + // Because this class does not implement the Tree Hashing Mode, + // these parameters can be treated as constants (see Init() function) + /* + * private int fanout = 1; // 0-255 + * private int depth = 1; // 1 - 255 + * private int leafLength= 0; + * private long nodeOffset = 0L; + * private int nodeDepth = 0; + * private int innerHashLength = 0; + */ + + /** + * Whenever this buffer overflows, it will be processed in the Compress() + * function. For performance issues, long messages will not use this buffer. + */ + private byte[] buffer = null; + /** + * Position of last inserted byte + **/ + private int bufferPos = 0;// a value from 0 up to BLOCK_LENGTH_BYTES + + /** + * Internal state, in the BLAKE2 paper it is called v + **/ + private uint[] internalState = new uint[16]; + /** + * State vector, in the BLAKE2 paper it is called h + **/ + private uint[] chainValue = null; + + // counter (counts bytes): Length up to 2^64 are supported + /** + * holds least significant bits of counter + **/ + private uint t0 = 0; + /** + * holds most significant bits of counter + **/ + private uint t1 = 0; + /** + * finalization flag, for last block: ~0 + **/ + private uint f0 = 0; + + // For Tree Hashing Mode, not used here: + // private long f1 = 0L; // finalization flag, for last node: ~0L + + /** + * BLAKE2s-256 for hashing. + */ + public Blake2sDigest() + : this(256) + { + } + + public Blake2sDigest(Blake2sDigest digest) + { + this.bufferPos = digest.bufferPos; + this.buffer = Arrays.Clone(digest.buffer); + this.keyLength = digest.keyLength; + this.key = Arrays.Clone(digest.key); + this.digestLength = digest.digestLength; + this.chainValue = Arrays.Clone(digest.chainValue); + this.personalization = Arrays.Clone(digest.personalization); + } + + /** + * BLAKE2s for hashing. + * + * @param digestBits the desired digest length in bits. Must be a multiple of 8 and less than 256. + */ + public Blake2sDigest(int digestBits) + { + if (digestBits < 8 || digestBits > 256 || digestBits % 8 != 0) + throw new ArgumentException("BLAKE2s digest bit length must be a multiple of 8 and not greater than 256"); + + buffer = new byte[BLOCK_LENGTH_BYTES]; + keyLength = 0; + digestLength = digestBits / 8; + Init(); + } + + /** + * BLAKE2s for authentication ("Prefix-MAC mode"). + *

+ * After calling the doFinal() method, the key will remain to be used for + * further computations of this instance. The key can be overwritten using + * the clearKey() method. + * + * @param key a key up to 32 bytes or null + */ + public Blake2sDigest(byte[] key) + { + buffer = new byte[BLOCK_LENGTH_BYTES]; + if (key != null) + { + if (key.Length > 32) + throw new ArgumentException("Keys > 32 are not supported"); + + this.key = new byte[key.Length]; + Array.Copy(key, 0, this.key, 0, key.Length); + + keyLength = key.Length; + Array.Copy(key, 0, buffer, 0, key.Length); + bufferPos = BLOCK_LENGTH_BYTES; // zero padding + } + digestLength = 32; + Init(); + } + + /** + * BLAKE2s with key, required digest length, salt and personalization. + *

+ * After calling the doFinal() method, the key, the salt and the personal + * string will remain and might be used for further computations with this + * instance. The key can be overwritten using the clearKey() method, the + * salt (pepper) can be overwritten using the clearSalt() method. + * + * @param key a key up to 32 bytes or null + * @param digestBytes from 1 up to 32 bytes + * @param salt 8 bytes or null + * @param personalization 8 bytes or null + */ + public Blake2sDigest(byte[] key, int digestBytes, byte[] salt, + byte[] personalization) + { + if (digestBytes < 1 || digestBytes > 32) + throw new ArgumentException("Invalid digest length (required: 1 - 32)"); + + this.digestLength = digestBytes; + this.buffer = new byte[BLOCK_LENGTH_BYTES]; + + if (salt != null) + { + if (salt.Length != 8) + throw new ArgumentException("Salt length must be exactly 8 bytes"); + + this.salt = new byte[8]; + Array.Copy(salt, 0, this.salt, 0, salt.Length); + } + if (personalization != null) + { + if (personalization.Length != 8) + throw new ArgumentException("Personalization length must be exactly 8 bytes"); + + this.personalization = new byte[8]; + Array.Copy(personalization, 0, this.personalization, 0, personalization.Length); + } + if (key != null) + { + if (key.Length > 32) + throw new ArgumentException("Keys > 32 bytes are not supported"); + + this.key = new byte[key.Length]; + Array.Copy(key, 0, this.key, 0, key.Length); + + keyLength = key.Length; + Array.Copy(key, 0, buffer, 0, key.Length); + bufferPos = BLOCK_LENGTH_BYTES; // zero padding + } + Init(); + } + + // initialize chainValue + private void Init() + { + if (chainValue == null) + { + chainValue = new uint[8]; + + chainValue[0] = blake2s_IV[0] ^ (uint)(digestLength | (keyLength << 8) | 0x1010000); + // 0x1010000 = ((fanout << 16) | (depth << 24)); + // with fanout = 1; depth = 0; + chainValue[1] = blake2s_IV[1];// ^ leafLength; with leafLength = 0; + chainValue[2] = blake2s_IV[2];// ^ nodeOffset; with nodeOffset = 0; + chainValue[3] = blake2s_IV[3];// ^ ( (nodeOffset << 32) | (nodeDepth << 16) | (innerHashLength << 24) ); + // with nodeDepth = 0; innerHashLength = 0; + + chainValue[4] = blake2s_IV[4]; + chainValue[5] = blake2s_IV[5]; + if (salt != null) + { + chainValue[4] ^= Pack.LE_To_UInt32(salt, 0); + chainValue[5] ^= Pack.LE_To_UInt32(salt, 4); + } + + chainValue[6] = blake2s_IV[6]; + chainValue[7] = blake2s_IV[7]; + if (personalization != null) + { + chainValue[6] ^= Pack.LE_To_UInt32(personalization, 0); + chainValue[7] ^= Pack.LE_To_UInt32(personalization, 4); + } + } + } + + private void InitializeInternalState() + { + // initialize v: + Array.Copy(chainValue, 0, internalState, 0, chainValue.Length); + Array.Copy(blake2s_IV, 0, internalState, chainValue.Length, 4); + internalState[12] = t0 ^ blake2s_IV[4]; + internalState[13] = t1 ^ blake2s_IV[5]; + internalState[14] = f0 ^ blake2s_IV[6]; + internalState[15] = blake2s_IV[7];// ^ f1 with f1 = 0 + } + + /** + * Update the message digest with a single byte. + * + * @param b the input byte to be entered. + */ + public virtual void Update(byte b) + { + int remainingLength; // left bytes of buffer + + // process the buffer if full else add to buffer: + remainingLength = BLOCK_LENGTH_BYTES - bufferPos; + if (remainingLength == 0) + { // full buffer + t0 += BLOCK_LENGTH_BYTES; + if (t0 == 0) + { // if message > 2^32 + t1++; + } + Compress(buffer, 0); + Array.Clear(buffer, 0, buffer.Length);// clear buffer + buffer[0] = b; + bufferPos = 1; + } + else + { + buffer[bufferPos] = b; + bufferPos++; + } + } + + /** + * Update the message digest with a block of bytes. + * + * @param message the byte array containing the data. + * @param offset the offset into the byte array where the data starts. + * @param len the length of the data. + */ + public virtual void BlockUpdate(byte[] message, int offset, int len) + { + if (message == null || len == 0) + return; + + int remainingLength = 0; // left bytes of buffer + + if (bufferPos != 0) + { // commenced, incomplete buffer + + // complete the buffer: + remainingLength = BLOCK_LENGTH_BYTES - bufferPos; + if (remainingLength < len) + { // full buffer + at least 1 byte + Array.Copy(message, offset, buffer, bufferPos, remainingLength); + t0 += BLOCK_LENGTH_BYTES; + if (t0 == 0) + { // if message > 2^32 + t1++; + } + Compress(buffer, 0); + bufferPos = 0; + Array.Clear(buffer, 0, buffer.Length);// clear buffer + } + else + { + Array.Copy(message, offset, buffer, bufferPos, len); + bufferPos += len; + return; + } + } + + // process blocks except last block (also if last block is full) + int messagePos; + int blockWiseLastPos = offset + len - BLOCK_LENGTH_BYTES; + for (messagePos = offset + remainingLength; + messagePos < blockWiseLastPos; + messagePos += BLOCK_LENGTH_BYTES) + { // block wise 64 bytes + // without buffer: + t0 += BLOCK_LENGTH_BYTES; + if (t0 == 0) + { + t1++; + } + Compress(message, messagePos); + } + + // fill the buffer with left bytes, this might be a full block + Array.Copy(message, messagePos, buffer, 0, offset + len + - messagePos); + bufferPos += offset + len - messagePos; + } + + /** + * Close the digest, producing the final digest value. The doFinal() call + * leaves the digest reset. Key, salt and personal string remain. + * + * @param out the array the digest is to be copied into. + * @param outOffset the offset into the out array the digest is to start at. + */ + public virtual int DoFinal(byte[] output, int outOffset) + { + f0 = 0xFFFFFFFFU; + t0 += (uint)bufferPos; + // bufferPos may be < 64, so (t0 == 0) does not work + // for 2^32 < message length > 2^32 - 63 + if ((t0 < 0) && (bufferPos > -t0)) + { + t1++; + } + Compress(buffer, 0); + Array.Clear(buffer, 0, buffer.Length);// Holds eventually the key if input is null + Array.Clear(internalState, 0, internalState.Length); + + for (int i = 0; i < chainValue.Length && (i * 4 < digestLength); i++) + { + byte[] bytes = Pack.UInt32_To_LE(chainValue[i]); + + if (i * 4 < digestLength - 4) + { + Array.Copy(bytes, 0, output, outOffset + i * 4, 4); + } + else + { + Array.Copy(bytes, 0, output, outOffset + i * 4, digestLength - (i * 4)); + } + } + + Array.Clear(chainValue, 0, chainValue.Length); + + Reset(); + + return digestLength; + } + + /** + * Reset the digest back to its initial state. The key, the salt and the + * personal string will remain for further computations. + */ + public virtual void Reset() + { + bufferPos = 0; + f0 = 0; + t0 = 0; + t1 = 0; + chainValue = null; + Array.Clear(buffer, 0, buffer.Length); + if (key != null) + { + Array.Copy(key, 0, buffer, 0, key.Length); + bufferPos = BLOCK_LENGTH_BYTES; // zero padding + } + Init(); + } + + private void Compress(byte[] message, int messagePos) + { + InitializeInternalState(); + + uint[] m = new uint[16]; + for (int j = 0; j < 16; j++) + { + m[j] = Pack.LE_To_UInt32(message, messagePos + j * 4); + } + + for (int round = 0; round < ROUNDS; round++) + { + + // G apply to columns of internalState:m[blake2s_sigma[round][2 * + // blockPos]] /+1 + G(m[blake2s_sigma[round,0]], m[blake2s_sigma[round,1]], 0, 4, 8, 12); + G(m[blake2s_sigma[round,2]], m[blake2s_sigma[round,3]], 1, 5, 9, 13); + G(m[blake2s_sigma[round,4]], m[blake2s_sigma[round,5]], 2, 6, 10, 14); + G(m[blake2s_sigma[round,6]], m[blake2s_sigma[round,7]], 3, 7, 11, 15); + // G apply to diagonals of internalState: + G(m[blake2s_sigma[round,8]], m[blake2s_sigma[round,9]], 0, 5, 10, 15); + G(m[blake2s_sigma[round,10]], m[blake2s_sigma[round,11]], 1, 6, 11, 12); + G(m[blake2s_sigma[round,12]], m[blake2s_sigma[round,13]], 2, 7, 8, 13); + G(m[blake2s_sigma[round,14]], m[blake2s_sigma[round,15]], 3, 4, 9, 14); + } + + // update chain values: + for (int offset = 0; offset < chainValue.Length; offset++) + { + chainValue[offset] = chainValue[offset] ^ internalState[offset] ^ internalState[offset + 8]; + } + } + + private void G(uint m1, uint m2, int posA, int posB, int posC, int posD) + { + internalState[posA] = internalState[posA] + internalState[posB] + m1; + internalState[posD] = rotr32(internalState[posD] ^ internalState[posA], 16); + internalState[posC] = internalState[posC] + internalState[posD]; + internalState[posB] = rotr32(internalState[posB] ^ internalState[posC], 12); + internalState[posA] = internalState[posA] + internalState[posB] + m2; + internalState[posD] = rotr32(internalState[posD] ^ internalState[posA], 8); + internalState[posC] = internalState[posC] + internalState[posD]; + internalState[posB] = rotr32(internalState[posB] ^ internalState[posC], 7); + } + + private uint rotr32(uint x, int rot) + { + return x >> rot | x << -rot; + } + + /** + * Return the algorithm name. + * + * @return the algorithm name + */ + public virtual string AlgorithmName + { + get { return "BLAKE2s"; } + } + + /** + * Return the size in bytes of the digest produced by this message digest. + * + * @return the size in bytes of the digest produced by this message digest. + */ + public virtual int GetDigestSize() + { + return digestLength; + } + + /** + * Return the size in bytes of the internal buffer the digest applies its + * compression function to. + * + * @return byte length of the digest's internal buffer. + */ + public virtual int GetByteLength() + { + return BLOCK_LENGTH_BYTES; + } + + /** + * Overwrite the key if it is no longer used (zeroization). + */ + public virtual void ClearKey() + { + if (key != null) + { + Array.Clear(key, 0, key.Length); + Array.Clear(buffer, 0, buffer.Length); + } + } + + /** + * Overwrite the salt (pepper) if it is secret and no longer used + * (zeroization). + */ + public virtual void ClearSalt() + { + if (salt != null) + { + Array.Clear(salt, 0, salt.Length); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/Blake2sDigest.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/Blake2sDigest.cs.meta new file mode 100644 index 0000000..213f4bc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/Blake2sDigest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c93795237787c644c945161f02897738 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/CSHAKEDigest.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/CSHAKEDigest.cs new file mode 100644 index 0000000..c3b0b70 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/CSHAKEDigest.cs @@ -0,0 +1,108 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + ///

+ /// Customizable SHAKE function. + /// + public class CShakeDigest + : ShakeDigest + { + private static readonly byte[] padding = new byte[100]; + + private static byte[] EncodeString(byte[] str) + { + if (Arrays.IsNullOrEmpty(str)) + { + return XofUtilities.LeftEncode(0L); + } + + return Arrays.Concatenate(XofUtilities.LeftEncode(str.Length * 8L), str); + } + + private readonly byte[] diff; + + /// + /// Base constructor + /// + /// bit length of the underlying SHAKE function, 128 or 256. + /// the function name string, note this is reserved for use by NIST. Avoid using it if not required. + /// the customization string - available for local use. + public CShakeDigest(int bitLength, byte[] N, byte[] S) + : base(bitLength) + { + if ((N == null || N.Length == 0) && (S == null || S.Length == 0)) + { + diff = null; + } + else + { + diff = Arrays.ConcatenateAll(XofUtilities.LeftEncode(rate / 8), EncodeString(N), EncodeString(S)); + DiffPadAndAbsorb(); + } + } + + public CShakeDigest(CShakeDigest source) + : base(source) + { + this.diff = Arrays.Clone(source.diff); + } + + // bytepad in SP 800-185 + private void DiffPadAndAbsorb() + { + int blockSize = rate / 8; + Absorb(diff, 0, diff.Length); + + int delta = diff.Length % blockSize; + + // only add padding if needed + if (delta != 0) + { + int required = blockSize - delta; + + while (required > padding.Length) + { + Absorb(padding, 0, padding.Length); + required -= padding.Length; + } + + Absorb(padding, 0, required); + } + } + + public override string AlgorithmName + { + get { return "CSHAKE" + fixedOutputLength; } + } + + public override int DoOutput(byte[] output, int outOff, int outLen) + { + if (diff == null) + { + return base.DoOutput(output, outOff, outLen); + } + + if (!squeezing) + { + AbsorbBits(0x00, 2); + } + + Squeeze(output, outOff, ((long)outLen) << 3); + + return outLen; + } + + public override void Reset() + { + base.Reset(); + + if (diff != null) + { + DiffPadAndAbsorb(); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/CSHAKEDigest.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/CSHAKEDigest.cs.meta new file mode 100644 index 0000000..b57c510 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/CSHAKEDigest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9a5063b56a2a1e24c9339902ec666f55 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/DSTU7564Digest.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/DSTU7564Digest.cs new file mode 100644 index 0000000..b2d9079 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/DSTU7564Digest.cs @@ -0,0 +1,530 @@ +using System; + +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /** + * implementation of Ukrainian DSTU 7564 hash function + */ + public class Dstu7564Digest + : IDigest, IMemoable + { + private const int NB_512 = 8; //Number of 8-byte words in state for <=256-bit hash code. + private const int NB_1024 = 16; //Number of 8-byte words in state for <=512-bit hash code. + + private const int NR_512 = 10; //Number of rounds for 512-bit state. + private const int NR_1024 = 14; //Number of rounds for 1024-bit state. + + private int hashSize; + private int blockSize; + + private int columns; + private int rounds; + + private ulong[] state; + private ulong[] tempState1; + private ulong[] tempState2; + + // TODO Guard against 'inputBlocks' overflow (2^64 blocks) + private ulong inputBlocks; + private int bufOff; + private byte[] buf; + + public Dstu7564Digest(Dstu7564Digest digest) + { + CopyIn(digest); + } + + private void CopyIn(Dstu7564Digest digest) + { + this.hashSize = digest.hashSize; + this.blockSize = digest.blockSize; + + this.rounds = digest.rounds; + if (columns > 0 && columns == digest.columns) + { + Array.Copy(digest.state, 0, state, 0, columns); + Array.Copy(digest.buf, 0, buf, 0, blockSize); + } + else + { + this.columns = digest.columns; + this.state = Arrays.Clone(digest.state); + this.tempState1 = new ulong[columns]; + this.tempState2 = new ulong[columns]; + this.buf = Arrays.Clone(digest.buf); + } + + this.inputBlocks = digest.inputBlocks; + this.bufOff = digest.bufOff; + } + + public Dstu7564Digest(int hashSizeBits) + { + if (hashSizeBits == 256 || hashSizeBits == 384 || hashSizeBits == 512) + { + this.hashSize = hashSizeBits / 8; + } + else + { + throw new ArgumentException("Hash size is not recommended. Use 256/384/512 instead"); + } + + if (hashSizeBits > 256) + { + this.columns = NB_1024; + this.rounds = NR_1024; + } + else + { + this.columns = NB_512; + this.rounds = NR_512; + } + + this.blockSize = columns << 3; + + this.state = new ulong[columns]; + this.state[0] = (ulong)blockSize; + + this.tempState1 = new ulong[columns]; + this.tempState2 = new ulong[columns]; + + this.buf = new byte[blockSize]; + } + + public virtual string AlgorithmName + { + get { return "DSTU7564"; } + } + + public virtual int GetDigestSize() + { + return hashSize; + } + + public virtual int GetByteLength() + { + return blockSize; + } + + public virtual void Update(byte input) + { + buf[bufOff++] = input; + if (bufOff == blockSize) + { + ProcessBlock(buf, 0); + bufOff = 0; + ++inputBlocks; + } + } + + public virtual void BlockUpdate(byte[] input, int inOff, int length) + { + while (bufOff != 0 && length > 0) + { + Update(input[inOff++]); + --length; + } + + if (length > 0) + { + while (length >= blockSize) + { + ProcessBlock(input, inOff); + inOff += blockSize; + length -= blockSize; + ++inputBlocks; + } + + while (length > 0) + { + Update(input[inOff++]); + --length; + } + } + } + + public virtual int DoFinal(byte[] output, int outOff) + { + // Apply padding: terminator byte and 96-bit length field + { + int inputBytes = bufOff; + buf[bufOff++] = (byte)0x80; + + int lenPos = blockSize - 12; + if (bufOff > lenPos) + { + while (bufOff < blockSize) + { + buf[bufOff++] = 0; + } + bufOff = 0; + ProcessBlock(buf, 0); + } + + while (bufOff < lenPos) + { + buf[bufOff++] = 0; + } + + ulong c = ((inputBlocks & 0xFFFFFFFFUL) * (ulong)blockSize + (uint)inputBytes) << 3; + Pack.UInt32_To_LE((uint)c, buf, bufOff); + bufOff += 4; + c >>= 32; + c += ((inputBlocks >> 32) * (ulong)blockSize) << 3; + Pack.UInt64_To_LE(c, buf, bufOff); + // bufOff += 8; + ProcessBlock(buf, 0); + } + + { + Array.Copy(state, 0, tempState1, 0, columns); + + P(tempState1); + + for (int col = 0; col < columns; ++col) + { + state[col] ^= tempState1[col]; + } + } + + int neededColumns = hashSize / 8; + for (int col = columns - neededColumns; col < columns; ++col) + { + Pack.UInt64_To_LE(state[col], output, outOff); + outOff += 8; + } + + Reset(); + + return hashSize; + } + + public virtual void Reset() + { + Array.Clear(state, 0, state.Length); + state[0] = (ulong)blockSize; + + inputBlocks = 0; + bufOff = 0; + } + + protected virtual void ProcessBlock(byte[] input, int inOff) + { + int pos = inOff; + for (int col = 0; col < columns; ++col) + { + ulong word = Pack.LE_To_UInt64(input, pos); + pos += 8; + + tempState1[col] = state[col] ^ word; + tempState2[col] = word; + } + + P(tempState1); + Q(tempState2); + + for (int col = 0; col < columns; ++col) + { + state[col] ^= tempState1[col] ^ tempState2[col]; + } + } + + private void P(ulong[] s) + { + for (int round = 0; round < rounds; ++round) + { + ulong rc = (ulong)round; + + /* AddRoundConstants */ + for (int col = 0; col < columns; ++col) + { + s[col] ^= rc; + rc += 0x10L; + } + + ShiftRows(s); + SubBytes(s); + MixColumns(s); + } + } + + private void Q(ulong[] s) + { + for (int round = 0; round < rounds; ++round) + { + /* AddRoundConstantsQ */ + ulong rc = ((ulong)(((columns - 1) << 4) ^ round) << 56) | 0x00F0F0F0F0F0F0F3UL; + + for (int col = 0; col < columns; ++col) + { + s[col] += rc; + rc -= 0x1000000000000000L; + } + + ShiftRows(s); + SubBytes(s); + MixColumns(s); + } + } + + private static ulong MixColumn(ulong c) + { + //// Calculate column multiplied by powers of 'x' + //ulong x0 = c; + //ulong x1 = ((x0 & 0x7F7F7F7F7F7F7F7FUL) << 1) ^ (((x0 & 0x8080808080808080UL) >> 7) * 0x1DUL); + //ulong x2 = ((x1 & 0x7F7F7F7F7F7F7F7FUL) << 1) ^ (((x1 & 0x8080808080808080UL) >> 7) * 0x1DUL); + //ulong x3 = ((x2 & 0x7F7F7F7F7F7F7F7FUL) << 1) ^ (((x2 & 0x8080808080808080UL) >> 7) * 0x1DUL); + + //// Calculate products with circulant matrix from (0x01, 0x01, 0x05, 0x01, 0x08, 0x06, 0x07, 0x04) + //ulong m0 = x0; + //ulong m1 = x0; + //ulong m2 = x0 ^ x2; + //ulong m3 = x0; + //ulong m4 = x3; + //ulong m5 = x1 ^ x2; + //ulong m6 = x0 ^ x1 ^ x2; + //ulong m7 = x2; + + //// Assemble the rotated products + //return m0 + // ^ Rotate(8, m1) + // ^ Rotate(16, m2) + // ^ Rotate(24, m3) + // ^ Rotate(32, m4) + // ^ Rotate(40, m5) + // ^ Rotate(48, m6) + // ^ Rotate(56, m7); + + // Multiply elements by 'x' + ulong x1 = ((c & 0x7F7F7F7F7F7F7F7FUL) << 1) ^ (((c & 0x8080808080808080UL) >> 7) * 0x1DUL); + ulong u, v; + + u = Rotate(8, c) ^ c; + u ^= Rotate(16, u); + u ^= Rotate(48, c); + + v = u ^ c ^ x1; + + // Multiply elements by 'x^2' + v = ((v & 0x3F3F3F3F3F3F3F3FUL) << 2) ^ (((v & 0x8080808080808080UL) >> 6) * 0x1DUL) ^ (((v & 0x4040404040404040UL) >> 6) * 0x1DUL); + + return u ^ Rotate(32, v) ^ Rotate(40, x1) ^ Rotate(48, x1); + } + + private void MixColumns(ulong[] s) + { + for (int col = 0; col < columns; ++col) + { + s[col] = MixColumn(s[col]); + } + } + + private static ulong Rotate(int n, ulong x) + { + return (x >> n) | (x << -n); + } + + private void ShiftRows(ulong[] s) + { + switch (columns) + { + case NB_512: + { + ulong c0 = s[0], c1 = s[1], c2 = s[2], c3 = s[3]; + ulong c4 = s[4], c5 = s[5], c6 = s[6], c7 = s[7]; + ulong d; + + d = (c0 ^ c4) & 0xFFFFFFFF00000000UL; c0 ^= d; c4 ^= d; + d = (c1 ^ c5) & 0x00FFFFFFFF000000UL; c1 ^= d; c5 ^= d; + d = (c2 ^ c6) & 0x0000FFFFFFFF0000UL; c2 ^= d; c6 ^= d; + d = (c3 ^ c7) & 0x000000FFFFFFFF00UL; c3 ^= d; c7 ^= d; + + d = (c0 ^ c2) & 0xFFFF0000FFFF0000UL; c0 ^= d; c2 ^= d; + d = (c1 ^ c3) & 0x00FFFF0000FFFF00UL; c1 ^= d; c3 ^= d; + d = (c4 ^ c6) & 0xFFFF0000FFFF0000UL; c4 ^= d; c6 ^= d; + d = (c5 ^ c7) & 0x00FFFF0000FFFF00UL; c5 ^= d; c7 ^= d; + + d = (c0 ^ c1) & 0xFF00FF00FF00FF00UL; c0 ^= d; c1 ^= d; + d = (c2 ^ c3) & 0xFF00FF00FF00FF00UL; c2 ^= d; c3 ^= d; + d = (c4 ^ c5) & 0xFF00FF00FF00FF00UL; c4 ^= d; c5 ^= d; + d = (c6 ^ c7) & 0xFF00FF00FF00FF00UL; c6 ^= d; c7 ^= d; + + s[0] = c0; s[1] = c1; s[2] = c2; s[3] = c3; + s[4] = c4; s[5] = c5; s[6] = c6; s[7] = c7; + break; + } + case NB_1024: + { + ulong c00 = s[0], c01 = s[1], c02 = s[2], c03 = s[3]; + ulong c04 = s[4], c05 = s[5], c06 = s[6], c07 = s[7]; + ulong c08 = s[8], c09 = s[9], c10 = s[10], c11 = s[11]; + ulong c12 = s[12], c13 = s[13], c14 = s[14], c15 = s[15]; + ulong d; + + // NOTE: Row 7 is shifted by 11 + + d = (c00 ^ c08) & 0xFF00000000000000UL; c00 ^= d; c08 ^= d; + d = (c01 ^ c09) & 0xFF00000000000000UL; c01 ^= d; c09 ^= d; + d = (c02 ^ c10) & 0xFFFF000000000000UL; c02 ^= d; c10 ^= d; + d = (c03 ^ c11) & 0xFFFFFF0000000000UL; c03 ^= d; c11 ^= d; + d = (c04 ^ c12) & 0xFFFFFFFF00000000UL; c04 ^= d; c12 ^= d; + d = (c05 ^ c13) & 0x00FFFFFFFF000000UL; c05 ^= d; c13 ^= d; + d = (c06 ^ c14) & 0x00FFFFFFFFFF0000UL; c06 ^= d; c14 ^= d; + d = (c07 ^ c15) & 0x00FFFFFFFFFFFF00UL; c07 ^= d; c15 ^= d; + + d = (c00 ^ c04) & 0x00FFFFFF00000000UL; c00 ^= d; c04 ^= d; + d = (c01 ^ c05) & 0xFFFFFFFFFF000000UL; c01 ^= d; c05 ^= d; + d = (c02 ^ c06) & 0xFF00FFFFFFFF0000UL; c02 ^= d; c06 ^= d; + d = (c03 ^ c07) & 0xFF0000FFFFFFFF00UL; c03 ^= d; c07 ^= d; + d = (c08 ^ c12) & 0x00FFFFFF00000000UL; c08 ^= d; c12 ^= d; + d = (c09 ^ c13) & 0xFFFFFFFFFF000000UL; c09 ^= d; c13 ^= d; + d = (c10 ^ c14) & 0xFF00FFFFFFFF0000UL; c10 ^= d; c14 ^= d; + d = (c11 ^ c15) & 0xFF0000FFFFFFFF00UL; c11 ^= d; c15 ^= d; + + d = (c00 ^ c02) & 0xFFFF0000FFFF0000UL; c00 ^= d; c02 ^= d; + d = (c01 ^ c03) & 0x00FFFF0000FFFF00UL; c01 ^= d; c03 ^= d; + d = (c04 ^ c06) & 0xFFFF0000FFFF0000UL; c04 ^= d; c06 ^= d; + d = (c05 ^ c07) & 0x00FFFF0000FFFF00UL; c05 ^= d; c07 ^= d; + d = (c08 ^ c10) & 0xFFFF0000FFFF0000UL; c08 ^= d; c10 ^= d; + d = (c09 ^ c11) & 0x00FFFF0000FFFF00UL; c09 ^= d; c11 ^= d; + d = (c12 ^ c14) & 0xFFFF0000FFFF0000UL; c12 ^= d; c14 ^= d; + d = (c13 ^ c15) & 0x00FFFF0000FFFF00UL; c13 ^= d; c15 ^= d; + + d = (c00 ^ c01) & 0xFF00FF00FF00FF00UL; c00 ^= d; c01 ^= d; + d = (c02 ^ c03) & 0xFF00FF00FF00FF00UL; c02 ^= d; c03 ^= d; + d = (c04 ^ c05) & 0xFF00FF00FF00FF00UL; c04 ^= d; c05 ^= d; + d = (c06 ^ c07) & 0xFF00FF00FF00FF00UL; c06 ^= d; c07 ^= d; + d = (c08 ^ c09) & 0xFF00FF00FF00FF00UL; c08 ^= d; c09 ^= d; + d = (c10 ^ c11) & 0xFF00FF00FF00FF00UL; c10 ^= d; c11 ^= d; + d = (c12 ^ c13) & 0xFF00FF00FF00FF00UL; c12 ^= d; c13 ^= d; + d = (c14 ^ c15) & 0xFF00FF00FF00FF00UL; c14 ^= d; c15 ^= d; + + s[0] = c00; s[1] = c01; s[2] = c02; s[3] = c03; + s[4] = c04; s[5] = c05; s[6] = c06; s[7] = c07; + s[8] = c08; s[9] = c09; s[10] = c10; s[11] = c11; + s[12] = c12; s[13] = c13; s[14] = c14; s[15] = c15; + break; + } + default: + { + throw new InvalidOperationException("unsupported state size: only 512/1024 are allowed"); + } + } + } + + private void SubBytes(ulong[] s) + { + for (int i = 0; i < columns; ++i) + { + ulong u = s[i]; + uint lo = (uint)u, hi = (uint)(u >> 32); + byte t0 = S0[lo & 0xFF]; + byte t1 = S1[(lo >> 8) & 0xFF]; + byte t2 = S2[(lo >> 16) & 0xFF]; + byte t3 = S3[lo >> 24]; + lo = (uint)t0 | ((uint)t1 << 8) | ((uint)t2 << 16) | ((uint)t3 << 24); + byte t4 = S0[hi & 0xFF]; + byte t5 = S1[(hi >> 8) & 0xFF]; + byte t6 = S2[(hi >> 16) & 0xFF]; + byte t7 = S3[hi >> 24]; + hi = (uint)t4 | ((uint)t5 << 8) | ((uint)t6 << 16) | ((uint)t7 << 24); + s[i] = (ulong)lo | ((ulong)hi << 32); + } + } + + private static readonly byte[] S0 = new byte[] { + 0xa8, 0x43, 0x5f, 0x06, 0x6b, 0x75, 0x6c, 0x59, 0x71, 0xdf, 0x87, 0x95, 0x17, 0xf0, 0xd8, 0x09, + 0x6d, 0xf3, 0x1d, 0xcb, 0xc9, 0x4d, 0x2c, 0xaf, 0x79, 0xe0, 0x97, 0xfd, 0x6f, 0x4b, 0x45, 0x39, + 0x3e, 0xdd, 0xa3, 0x4f, 0xb4, 0xb6, 0x9a, 0x0e, 0x1f, 0xbf, 0x15, 0xe1, 0x49, 0xd2, 0x93, 0xc6, + 0x92, 0x72, 0x9e, 0x61, 0xd1, 0x63, 0xfa, 0xee, 0xf4, 0x19, 0xd5, 0xad, 0x58, 0xa4, 0xbb, 0xa1, + 0xdc, 0xf2, 0x83, 0x37, 0x42, 0xe4, 0x7a, 0x32, 0x9c, 0xcc, 0xab, 0x4a, 0x8f, 0x6e, 0x04, 0x27, + 0x2e, 0xe7, 0xe2, 0x5a, 0x96, 0x16, 0x23, 0x2b, 0xc2, 0x65, 0x66, 0x0f, 0xbc, 0xa9, 0x47, 0x41, + 0x34, 0x48, 0xfc, 0xb7, 0x6a, 0x88, 0xa5, 0x53, 0x86, 0xf9, 0x5b, 0xdb, 0x38, 0x7b, 0xc3, 0x1e, + 0x22, 0x33, 0x24, 0x28, 0x36, 0xc7, 0xb2, 0x3b, 0x8e, 0x77, 0xba, 0xf5, 0x14, 0x9f, 0x08, 0x55, + 0x9b, 0x4c, 0xfe, 0x60, 0x5c, 0xda, 0x18, 0x46, 0xcd, 0x7d, 0x21, 0xb0, 0x3f, 0x1b, 0x89, 0xff, + 0xeb, 0x84, 0x69, 0x3a, 0x9d, 0xd7, 0xd3, 0x70, 0x67, 0x40, 0xb5, 0xde, 0x5d, 0x30, 0x91, 0xb1, + 0x78, 0x11, 0x01, 0xe5, 0x00, 0x68, 0x98, 0xa0, 0xc5, 0x02, 0xa6, 0x74, 0x2d, 0x0b, 0xa2, 0x76, + 0xb3, 0xbe, 0xce, 0xbd, 0xae, 0xe9, 0x8a, 0x31, 0x1c, 0xec, 0xf1, 0x99, 0x94, 0xaa, 0xf6, 0x26, + 0x2f, 0xef, 0xe8, 0x8c, 0x35, 0x03, 0xd4, 0x7f, 0xfb, 0x05, 0xc1, 0x5e, 0x90, 0x20, 0x3d, 0x82, + 0xf7, 0xea, 0x0a, 0x0d, 0x7e, 0xf8, 0x50, 0x1a, 0xc4, 0x07, 0x57, 0xb8, 0x3c, 0x62, 0xe3, 0xc8, + 0xac, 0x52, 0x64, 0x10, 0xd0, 0xd9, 0x13, 0x0c, 0x12, 0x29, 0x51, 0xb9, 0xcf, 0xd6, 0x73, 0x8d, + 0x81, 0x54, 0xc0, 0xed, 0x4e, 0x44, 0xa7, 0x2a, 0x85, 0x25, 0xe6, 0xca, 0x7c, 0x8b, 0x56, 0x80 + }; + + private static readonly byte[] S1 = new byte[] { + 0xce, 0xbb, 0xeb, 0x92, 0xea, 0xcb, 0x13, 0xc1, 0xe9, 0x3a, 0xd6, 0xb2, 0xd2, 0x90, 0x17, 0xf8, + 0x42, 0x15, 0x56, 0xb4, 0x65, 0x1c, 0x88, 0x43, 0xc5, 0x5c, 0x36, 0xba, 0xf5, 0x57, 0x67, 0x8d, + 0x31, 0xf6, 0x64, 0x58, 0x9e, 0xf4, 0x22, 0xaa, 0x75, 0x0f, 0x02, 0xb1, 0xdf, 0x6d, 0x73, 0x4d, + 0x7c, 0x26, 0x2e, 0xf7, 0x08, 0x5d, 0x44, 0x3e, 0x9f, 0x14, 0xc8, 0xae, 0x54, 0x10, 0xd8, 0xbc, + 0x1a, 0x6b, 0x69, 0xf3, 0xbd, 0x33, 0xab, 0xfa, 0xd1, 0x9b, 0x68, 0x4e, 0x16, 0x95, 0x91, 0xee, + 0x4c, 0x63, 0x8e, 0x5b, 0xcc, 0x3c, 0x19, 0xa1, 0x81, 0x49, 0x7b, 0xd9, 0x6f, 0x37, 0x60, 0xca, + 0xe7, 0x2b, 0x48, 0xfd, 0x96, 0x45, 0xfc, 0x41, 0x12, 0x0d, 0x79, 0xe5, 0x89, 0x8c, 0xe3, 0x20, + 0x30, 0xdc, 0xb7, 0x6c, 0x4a, 0xb5, 0x3f, 0x97, 0xd4, 0x62, 0x2d, 0x06, 0xa4, 0xa5, 0x83, 0x5f, + 0x2a, 0xda, 0xc9, 0x00, 0x7e, 0xa2, 0x55, 0xbf, 0x11, 0xd5, 0x9c, 0xcf, 0x0e, 0x0a, 0x3d, 0x51, + 0x7d, 0x93, 0x1b, 0xfe, 0xc4, 0x47, 0x09, 0x86, 0x0b, 0x8f, 0x9d, 0x6a, 0x07, 0xb9, 0xb0, 0x98, + 0x18, 0x32, 0x71, 0x4b, 0xef, 0x3b, 0x70, 0xa0, 0xe4, 0x40, 0xff, 0xc3, 0xa9, 0xe6, 0x78, 0xf9, + 0x8b, 0x46, 0x80, 0x1e, 0x38, 0xe1, 0xb8, 0xa8, 0xe0, 0x0c, 0x23, 0x76, 0x1d, 0x25, 0x24, 0x05, + 0xf1, 0x6e, 0x94, 0x28, 0x9a, 0x84, 0xe8, 0xa3, 0x4f, 0x77, 0xd3, 0x85, 0xe2, 0x52, 0xf2, 0x82, + 0x50, 0x7a, 0x2f, 0x74, 0x53, 0xb3, 0x61, 0xaf, 0x39, 0x35, 0xde, 0xcd, 0x1f, 0x99, 0xac, 0xad, + 0x72, 0x2c, 0xdd, 0xd0, 0x87, 0xbe, 0x5e, 0xa6, 0xec, 0x04, 0xc6, 0x03, 0x34, 0xfb, 0xdb, 0x59, + 0xb6, 0xc2, 0x01, 0xf0, 0x5a, 0xed, 0xa7, 0x66, 0x21, 0x7f, 0x8a, 0x27, 0xc7, 0xc0, 0x29, 0xd7 + }; + + private static readonly byte[] S2 = new byte[] { + 0x93, 0xd9, 0x9a, 0xb5, 0x98, 0x22, 0x45, 0xfc, 0xba, 0x6a, 0xdf, 0x02, 0x9f, 0xdc, 0x51, 0x59, + 0x4a, 0x17, 0x2b, 0xc2, 0x94, 0xf4, 0xbb, 0xa3, 0x62, 0xe4, 0x71, 0xd4, 0xcd, 0x70, 0x16, 0xe1, + 0x49, 0x3c, 0xc0, 0xd8, 0x5c, 0x9b, 0xad, 0x85, 0x53, 0xa1, 0x7a, 0xc8, 0x2d, 0xe0, 0xd1, 0x72, + 0xa6, 0x2c, 0xc4, 0xe3, 0x76, 0x78, 0xb7, 0xb4, 0x09, 0x3b, 0x0e, 0x41, 0x4c, 0xde, 0xb2, 0x90, + 0x25, 0xa5, 0xd7, 0x03, 0x11, 0x00, 0xc3, 0x2e, 0x92, 0xef, 0x4e, 0x12, 0x9d, 0x7d, 0xcb, 0x35, + 0x10, 0xd5, 0x4f, 0x9e, 0x4d, 0xa9, 0x55, 0xc6, 0xd0, 0x7b, 0x18, 0x97, 0xd3, 0x36, 0xe6, 0x48, + 0x56, 0x81, 0x8f, 0x77, 0xcc, 0x9c, 0xb9, 0xe2, 0xac, 0xb8, 0x2f, 0x15, 0xa4, 0x7c, 0xda, 0x38, + 0x1e, 0x0b, 0x05, 0xd6, 0x14, 0x6e, 0x6c, 0x7e, 0x66, 0xfd, 0xb1, 0xe5, 0x60, 0xaf, 0x5e, 0x33, + 0x87, 0xc9, 0xf0, 0x5d, 0x6d, 0x3f, 0x88, 0x8d, 0xc7, 0xf7, 0x1d, 0xe9, 0xec, 0xed, 0x80, 0x29, + 0x27, 0xcf, 0x99, 0xa8, 0x50, 0x0f, 0x37, 0x24, 0x28, 0x30, 0x95, 0xd2, 0x3e, 0x5b, 0x40, 0x83, + 0xb3, 0x69, 0x57, 0x1f, 0x07, 0x1c, 0x8a, 0xbc, 0x20, 0xeb, 0xce, 0x8e, 0xab, 0xee, 0x31, 0xa2, + 0x73, 0xf9, 0xca, 0x3a, 0x1a, 0xfb, 0x0d, 0xc1, 0xfe, 0xfa, 0xf2, 0x6f, 0xbd, 0x96, 0xdd, 0x43, + 0x52, 0xb6, 0x08, 0xf3, 0xae, 0xbe, 0x19, 0x89, 0x32, 0x26, 0xb0, 0xea, 0x4b, 0x64, 0x84, 0x82, + 0x6b, 0xf5, 0x79, 0xbf, 0x01, 0x5f, 0x75, 0x63, 0x1b, 0x23, 0x3d, 0x68, 0x2a, 0x65, 0xe8, 0x91, + 0xf6, 0xff, 0x13, 0x58, 0xf1, 0x47, 0x0a, 0x7f, 0xc5, 0xa7, 0xe7, 0x61, 0x5a, 0x06, 0x46, 0x44, + 0x42, 0x04, 0xa0, 0xdb, 0x39, 0x86, 0x54, 0xaa, 0x8c, 0x34, 0x21, 0x8b, 0xf8, 0x0c, 0x74, 0x67 + }; + + private static readonly byte[] S3 = new byte[] { + 0x68, 0x8d, 0xca, 0x4d, 0x73, 0x4b, 0x4e, 0x2a, 0xd4, 0x52, 0x26, 0xb3, 0x54, 0x1e, 0x19, 0x1f, + 0x22, 0x03, 0x46, 0x3d, 0x2d, 0x4a, 0x53, 0x83, 0x13, 0x8a, 0xb7, 0xd5, 0x25, 0x79, 0xf5, 0xbd, + 0x58, 0x2f, 0x0d, 0x02, 0xed, 0x51, 0x9e, 0x11, 0xf2, 0x3e, 0x55, 0x5e, 0xd1, 0x16, 0x3c, 0x66, + 0x70, 0x5d, 0xf3, 0x45, 0x40, 0xcc, 0xe8, 0x94, 0x56, 0x08, 0xce, 0x1a, 0x3a, 0xd2, 0xe1, 0xdf, + 0xb5, 0x38, 0x6e, 0x0e, 0xe5, 0xf4, 0xf9, 0x86, 0xe9, 0x4f, 0xd6, 0x85, 0x23, 0xcf, 0x32, 0x99, + 0x31, 0x14, 0xae, 0xee, 0xc8, 0x48, 0xd3, 0x30, 0xa1, 0x92, 0x41, 0xb1, 0x18, 0xc4, 0x2c, 0x71, + 0x72, 0x44, 0x15, 0xfd, 0x37, 0xbe, 0x5f, 0xaa, 0x9b, 0x88, 0xd8, 0xab, 0x89, 0x9c, 0xfa, 0x60, + 0xea, 0xbc, 0x62, 0x0c, 0x24, 0xa6, 0xa8, 0xec, 0x67, 0x20, 0xdb, 0x7c, 0x28, 0xdd, 0xac, 0x5b, + 0x34, 0x7e, 0x10, 0xf1, 0x7b, 0x8f, 0x63, 0xa0, 0x05, 0x9a, 0x43, 0x77, 0x21, 0xbf, 0x27, 0x09, + 0xc3, 0x9f, 0xb6, 0xd7, 0x29, 0xc2, 0xeb, 0xc0, 0xa4, 0x8b, 0x8c, 0x1d, 0xfb, 0xff, 0xc1, 0xb2, + 0x97, 0x2e, 0xf8, 0x65, 0xf6, 0x75, 0x07, 0x04, 0x49, 0x33, 0xe4, 0xd9, 0xb9, 0xd0, 0x42, 0xc7, + 0x6c, 0x90, 0x00, 0x8e, 0x6f, 0x50, 0x01, 0xc5, 0xda, 0x47, 0x3f, 0xcd, 0x69, 0xa2, 0xe2, 0x7a, + 0xa7, 0xc6, 0x93, 0x0f, 0x0a, 0x06, 0xe6, 0x2b, 0x96, 0xa3, 0x1c, 0xaf, 0x6a, 0x12, 0x84, 0x39, + 0xe7, 0xb0, 0x82, 0xf7, 0xfe, 0x9d, 0x87, 0x5c, 0x81, 0x35, 0xde, 0xb4, 0xa5, 0xfc, 0x80, 0xef, + 0xcb, 0xbb, 0x6b, 0x76, 0xba, 0x5a, 0x7d, 0x78, 0x0b, 0x95, 0xe3, 0xad, 0x74, 0x98, 0x3b, 0x36, + 0x64, 0x6d, 0xdc, 0xf0, 0x59, 0xa9, 0x4c, 0x17, 0x7f, 0x91, 0xb8, 0xc9, 0x57, 0x1b, 0xe0, 0x61 + }; + + public virtual IMemoable Copy() + { + return new Dstu7564Digest(this); + } + + public virtual void Reset(IMemoable other) + { + Dstu7564Digest d = (Dstu7564Digest)other; + + CopyIn(d); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/DSTU7564Digest.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/DSTU7564Digest.cs.meta new file mode 100644 index 0000000..eb9bfa3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/DSTU7564Digest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f4131721402daa8468c56870f0f22e9f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/GOST3411Digest.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/GOST3411Digest.cs new file mode 100644 index 0000000..218adf6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/GOST3411Digest.cs @@ -0,0 +1,356 @@ +using System; + +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /** + * implementation of GOST R 34.11-94 + */ + public class Gost3411Digest + : IDigest, IMemoable + { + private const int DIGEST_LENGTH = 32; + + private byte[] H = new byte[32], L = new byte[32], + M = new byte[32], Sum = new byte[32]; + private byte[][] C = MakeC(); + + private byte[] xBuf = new byte[32]; + private int xBufOff; + private ulong byteCount; + + private readonly IBlockCipher cipher = new Gost28147Engine(); + private byte[] sBox; + + private static byte[][] MakeC() + { + byte[][] c = new byte[4][]; + for (int i = 0; i < 4; ++i) + { + c[i] = new byte[32]; + } + return c; + } + + /** + * Standard constructor + */ + public Gost3411Digest() + { + sBox = Gost28147Engine.GetSBox("D-A"); + cipher.Init(true, new ParametersWithSBox(null, sBox)); + + Reset(); + } + + /** + * Constructor to allow use of a particular sbox with GOST28147 + * @see GOST28147Engine#getSBox(String) + */ + public Gost3411Digest(byte[] sBoxParam) + { + sBox = Arrays.Clone(sBoxParam); + cipher.Init(true, new ParametersWithSBox(null, sBox)); + + Reset(); + } + + /** + * Copy constructor. This will copy the state of the provided + * message digest. + */ + public Gost3411Digest(Gost3411Digest t) + { + Reset(t); + } + + public string AlgorithmName + { + get { return "Gost3411"; } + } + + public int GetDigestSize() + { + return DIGEST_LENGTH; + } + + public void Update( + byte input) + { + xBuf[xBufOff++] = input; + if (xBufOff == xBuf.Length) + { + sumByteArray(xBuf); // calc sum M + processBlock(xBuf, 0); + xBufOff = 0; + } + byteCount++; + } + + public void BlockUpdate( + byte[] input, + int inOff, + int length) + { + while ((xBufOff != 0) && (length > 0)) + { + Update(input[inOff]); + inOff++; + length--; + } + + while (length > xBuf.Length) + { + Array.Copy(input, inOff, xBuf, 0, xBuf.Length); + + sumByteArray(xBuf); // calc sum M + processBlock(xBuf, 0); + inOff += xBuf.Length; + length -= xBuf.Length; + byteCount += (uint)xBuf.Length; + } + + // load in the remainder. + while (length > 0) + { + Update(input[inOff]); + inOff++; + length--; + } + } + + // (i + 1 + 4(k - 1)) = 8i + k i = 0-3, k = 1-8 + private byte[] K = new byte[32]; + + private byte[] P(byte[] input) + { + int fourK = 0; + for(int k = 0; k < 8; k++) + { + K[fourK++] = input[k]; + K[fourK++] = input[8 + k]; + K[fourK++] = input[16 + k]; + K[fourK++] = input[24 + k]; + } + + return K; + } + + //A (x) = (x0 ^ x1) || x3 || x2 || x1 + byte[] a = new byte[8]; + private byte[] A(byte[] input) + { + for(int j=0; j<8; j++) + { + a[j]=(byte)(input[j] ^ input[j+8]); + } + + Array.Copy(input, 8, input, 0, 24); + Array.Copy(a, 0, input, 24, 8); + + return input; + } + + //Encrypt function, ECB mode + private void E(byte[] key, byte[] s, int sOff, byte[] input, int inOff) + { + cipher.Init(true, new KeyParameter(key)); + + cipher.ProcessBlock(input, inOff, s, sOff); + } + + // (in:) n16||..||n1 ==> (out:) n1^n2^n3^n4^n13^n16||n16||..||n2 + internal short[] wS = new short[16], w_S = new short[16]; + + private void fw(byte[] input) + { + cpyBytesToShort(input, wS); + w_S[15] = (short)(wS[0] ^ wS[1] ^ wS[2] ^ wS[3] ^ wS[12] ^ wS[15]); + Array.Copy(wS, 1, w_S, 0, 15); + cpyShortToBytes(w_S, input); + } + + // block processing + internal byte[] S = new byte[32], U = new byte[32], V = new byte[32], W = new byte[32]; + + private void processBlock(byte[] input, int inOff) + { + Array.Copy(input, inOff, M, 0, 32); + + //key step 1 + + // H = h3 || h2 || h1 || h0 + // S = s3 || s2 || s1 || s0 + H.CopyTo(U, 0); + M.CopyTo(V, 0); + for (int j=0; j<32; j++) + { + W[j] = (byte)(U[j]^V[j]); + } + // Encrypt gost28147-ECB + E(P(W), S, 0, H, 0); // s0 = EK0 [h0] + + //keys step 2,3,4 + for (int i=1; i<4; i++) + { + byte[] tmpA = A(U); + for (int j=0; j<32; j++) + { + U[j] = (byte)(tmpA[j] ^ C[i][j]); + } + V = A(A(V)); + for (int j=0; j<32; j++) + { + W[j] = (byte)(U[j]^V[j]); + } + // Encrypt gost28147-ECB + E(P(W), S, i * 8, H, i * 8); // si = EKi [hi] + } + + // x(M, H) = y61(H^y(M^y12(S))) + for(int n = 0; n < 12; n++) + { + fw(S); + } + for(int n = 0; n < 32; n++) + { + S[n] = (byte)(S[n] ^ M[n]); + } + + fw(S); + + for(int n = 0; n < 32; n++) + { + S[n] = (byte)(H[n] ^ S[n]); + } + for(int n = 0; n < 61; n++) + { + fw(S); + } + Array.Copy(S, 0, H, 0, H.Length); + } + + private void finish() + { + ulong bitCount = byteCount * 8; + Pack.UInt64_To_LE(bitCount, L); + + while (xBufOff != 0) + { + Update((byte)0); + } + + processBlock(L, 0); + processBlock(Sum, 0); + } + + public int DoFinal( + byte[] output, + int outOff) + { + finish(); + + H.CopyTo(output, outOff); + + Reset(); + + return DIGEST_LENGTH; + } + + /** + * reset the chaining variables to the IV values. + */ + private static readonly byte[] C2 = { + 0x00,(byte)0xFF,0x00,(byte)0xFF,0x00,(byte)0xFF,0x00,(byte)0xFF, + (byte)0xFF,0x00,(byte)0xFF,0x00,(byte)0xFF,0x00,(byte)0xFF,0x00, + 0x00,(byte)0xFF,(byte)0xFF,0x00,(byte)0xFF,0x00,0x00,(byte)0xFF, + (byte)0xFF,0x00,0x00,0x00,(byte)0xFF,(byte)0xFF,0x00,(byte)0xFF + }; + + public void Reset() + { + byteCount = 0; + xBufOff = 0; + + Array.Clear(H, 0, H.Length); + Array.Clear(L, 0, L.Length); + Array.Clear(M, 0, M.Length); + Array.Clear(C[1], 0, C[1].Length); // real index C = +1 because index array with 0. + Array.Clear(C[3], 0, C[3].Length); + Array.Clear(Sum, 0, Sum.Length); + Array.Clear(xBuf, 0, xBuf.Length); + + C2.CopyTo(C[2], 0); + } + + // 256 bitsblock modul -> (Sum + a mod (2^256)) + private void sumByteArray( + byte[] input) + { + int carry = 0; + + for (int i = 0; i != Sum.Length; i++) + { + int sum = (Sum[i] & 0xff) + (input[i] & 0xff) + carry; + + Sum[i] = (byte)sum; + + carry = sum >> 8; + } + } + + private static void cpyBytesToShort(byte[] S, short[] wS) + { + for(int i = 0; i < S.Length / 2; i++) + { + wS[i] = (short)(((S[i*2+1]<<8)&0xFF00)|(S[i*2]&0xFF)); + } + } + + private static void cpyShortToBytes(short[] wS, byte[] S) + { + for(int i=0; i> 8); + S[i*2] = (byte)wS[i]; + } + } + + public int GetByteLength() + { + return 32; + } + + public IMemoable Copy() + { + return new Gost3411Digest(this); + } + + public void Reset(IMemoable other) + { + Gost3411Digest t = (Gost3411Digest)other; + + this.sBox = t.sBox; + cipher.Init(true, new ParametersWithSBox(null, sBox)); + + Reset(); + + Array.Copy(t.H, 0, this.H, 0, t.H.Length); + Array.Copy(t.L, 0, this.L, 0, t.L.Length); + Array.Copy(t.M, 0, this.M, 0, t.M.Length); + Array.Copy(t.Sum, 0, this.Sum, 0, t.Sum.Length); + Array.Copy(t.C[1], 0, this.C[1], 0, t.C[1].Length); + Array.Copy(t.C[2], 0, this.C[2], 0, t.C[2].Length); + Array.Copy(t.C[3], 0, this.C[3], 0, t.C[3].Length); + Array.Copy(t.xBuf, 0, this.xBuf, 0, t.xBuf.Length); + + this.xBufOff = t.xBufOff; + this.byteCount = t.byteCount; + } + } + +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/GOST3411Digest.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/GOST3411Digest.cs.meta new file mode 100644 index 0000000..a294c79 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/GOST3411Digest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a80283035cfd1c746a8a21498dc85046 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/GOST3411_2012Digest.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/GOST3411_2012Digest.cs new file mode 100644 index 0000000..68cb6c0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/GOST3411_2012Digest.cs @@ -0,0 +1,1036 @@ +using System; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + public abstract class Gost3411_2012Digest:IDigest,IMemoable + { + private readonly byte[] IV = new byte[64]; + private readonly byte[] N = new byte[64]; + private readonly byte[] Sigma = new byte[64]; + private readonly byte[] Ki = new byte[64]; + private readonly byte[] m = new byte[64]; + private readonly byte[] h = new byte[64]; + + // Temporary buffers + private readonly byte[] tmp = new byte[64]; + private readonly byte[] block = new byte[64]; + + private int bOff = 64; + + protected Gost3411_2012Digest(byte[] IV) + { + System.Array.Copy(IV,this.IV,64); + System.Array.Copy(IV, h, 64); + } + + public abstract string AlgorithmName { get; } + + public abstract IMemoable Copy(); + + public virtual int DoFinal(byte[] output, int outOff) + { + int lenM = 64 - bOff; + + // At this point it is certain that lenM is smaller than 64 + for (int i = 0; i != 64 - lenM; i++) + { + m[i] = 0; + } + + m[63 - lenM] = 1; + + if (bOff != 64) + { + System.Array.Copy(block, bOff, m, 64 - lenM, lenM); + } + + g_N(h, N, m); + addMod512(N, lenM * 8); + addMod512(Sigma, m); + g_N(h, Zero, N); + g_N(h, Zero, Sigma); + + reverse(h, tmp); + + Array.Copy(tmp, 0, output, outOff, 64); + + Reset(); + return 64; + } + + public int GetByteLength() + { + return 64; + } + + public abstract int GetDigestSize(); + + + public void Reset() + { + bOff = 64; + Arrays.Fill(N, (byte)0); + Arrays.Fill(Sigma, (byte)0); + System.Array.Copy(IV, 0, h, 0, 64); + Arrays.Fill(block, (byte)0); + } + + public void Reset(IMemoable other) + { + Gost3411_2012Digest o = (Gost3411_2012Digest)other; + + System.Array.Copy(o.IV, 0, this.IV, 0, 64); + System.Array.Copy(o.N, 0, this.N, 0, 64); + System.Array.Copy(o.Sigma, 0, this.Sigma, 0, 64); + System.Array.Copy(o.Ki, 0, this.Ki, 0, 64); + System.Array.Copy(o.m, 0, this.m, 0, 64); + System.Array.Copy(o.h, 0, this.h, 0, 64); + + System.Array.Copy(o.block, 0, this.block, 0, 64); + this.bOff = o.bOff; + } + + public void Update(byte input) + { + block[--bOff] = input; + if (bOff == 0) + { + g_N(h, N, block); + addMod512(N, 512); + addMod512(Sigma, block); + bOff = 64; + } + } + + + public void BlockUpdate(byte[] input, int inOff, int len) + { + while (bOff != 64 && len > 0) + { + Update(input[inOff++]); + len--; + } + while (len >= 64) + { + System.Array.Copy(input, inOff, tmp, 0, 64); + reverse(tmp, block); + g_N(h, N, block); + addMod512(N, 512); + addMod512(Sigma, block); + + len -= 64; + inOff += 64; + } + while (len > 0) + { + Update(input[inOff++]); + len--; + } + } + + + + + private void F(byte[] V) + { + ulong[] res = new ulong[8]; + ulong r; + + r = 0; + r ^= T[0][(V[56] & 0xFF)]; + r ^= T[1][(V[48] & 0xFF)]; + r ^= T[2][(V[40] & 0xFF)]; + r ^= T[3][(V[32] & 0xFF)]; + r ^= T[4][(V[24] & 0xFF)]; + r ^= T[5][(V[16] & 0xFF)]; + r ^= T[6][(V[8] & 0xFF)]; + r ^= T[7][(V[0] & 0xFF)]; + res[0] = r; + + r = 0; + r ^= T[0][(V[57] & 0xFF)]; + r ^= T[1][(V[49] & 0xFF)]; + r ^= T[2][(V[41] & 0xFF)]; + r ^= T[3][(V[33] & 0xFF)]; + r ^= T[4][(V[25] & 0xFF)]; + r ^= T[5][(V[17] & 0xFF)]; + r ^= T[6][(V[9] & 0xFF)]; + r ^= T[7][(V[1] & 0xFF)]; + res[1] = r; + + r = 0; + r ^= T[0][(V[58] & 0xFF)]; + r ^= T[1][(V[50] & 0xFF)]; + r ^= T[2][(V[42] & 0xFF)]; + r ^= T[3][(V[34] & 0xFF)]; + r ^= T[4][(V[26] & 0xFF)]; + r ^= T[5][(V[18] & 0xFF)]; + r ^= T[6][(V[10] & 0xFF)]; + r ^= T[7][(V[2] & 0xFF)]; + res[2] = r; + + r = 0; + r ^= T[0][(V[59] & 0xFF)]; + r ^= T[1][(V[51] & 0xFF)]; + r ^= T[2][(V[43] & 0xFF)]; + r ^= T[3][(V[35] & 0xFF)]; + r ^= T[4][(V[27] & 0xFF)]; + r ^= T[5][(V[19] & 0xFF)]; + r ^= T[6][(V[11] & 0xFF)]; + r ^= T[7][(V[3] & 0xFF)]; + res[3] = r; + + r = 0; + r ^= T[0][(V[60] & 0xFF)]; + r ^= T[1][(V[52] & 0xFF)]; + r ^= T[2][(V[44] & 0xFF)]; + r ^= T[3][(V[36] & 0xFF)]; + r ^= T[4][(V[28] & 0xFF)]; + r ^= T[5][(V[20] & 0xFF)]; + r ^= T[6][(V[12] & 0xFF)]; + r ^= T[7][(V[4] & 0xFF)]; + res[4] = r; + + r = 0; + r ^= T[0][(V[61] & 0xFF)]; + r ^= T[1][(V[53] & 0xFF)]; + r ^= T[2][(V[45] & 0xFF)]; + r ^= T[3][(V[37] & 0xFF)]; + r ^= T[4][(V[29] & 0xFF)]; + r ^= T[5][(V[21] & 0xFF)]; + r ^= T[6][(V[13] & 0xFF)]; + r ^= T[7][(V[5] & 0xFF)]; + res[5] = r; + + r = 0; + r ^= T[0][(V[62] & 0xFF)]; + r ^= T[1][(V[54] & 0xFF)]; + r ^= T[2][(V[46] & 0xFF)]; + r ^= T[3][(V[38] & 0xFF)]; + r ^= T[4][(V[30] & 0xFF)]; + r ^= T[5][(V[22] & 0xFF)]; + r ^= T[6][(V[14] & 0xFF)]; + r ^= T[7][(V[6] & 0xFF)]; + res[6] = r; + + r = 0; + r ^= T[0][(V[63] & 0xFF)]; + r ^= T[1][(V[55] & 0xFF)]; + r ^= T[2][(V[47] & 0xFF)]; + r ^= T[3][(V[39] & 0xFF)]; + r ^= T[4][(V[31] & 0xFF)]; + r ^= T[5][(V[23] & 0xFF)]; + r ^= T[6][(V[15] & 0xFF)]; + r ^= T[7][(V[7] & 0xFF)]; + res[7] = r; + + r = res[0]; + V[7] = (byte)(r >> 56); + V[6] = (byte)(r >> 48); + V[5] = (byte)(r >> 40); + V[4] = (byte)(r >> 32); + V[3] = (byte)(r >> 24); + V[2] = (byte)(r >> 16); + V[1] = (byte)(r >> 8); + V[0] = (byte)(r); + + r = res[1]; + V[15] = (byte)(r >> 56); + V[14] = (byte)(r >> 48); + V[13] = (byte)(r >> 40); + V[12] = (byte)(r >> 32); + V[11] = (byte)(r >> 24); + V[10] = (byte)(r >> 16); + V[9] = (byte)(r >> 8); + V[8] = (byte)(r); + + r = res[2]; + V[23] = (byte)(r >> 56); + V[22] = (byte)(r >> 48); + V[21] = (byte)(r >> 40); + V[20] = (byte)(r >> 32); + V[19] = (byte)(r >> 24); + V[18] = (byte)(r >> 16); + V[17] = (byte)(r >> 8); + V[16] = (byte)(r); + + r = res[3]; + V[31] = (byte)(r >> 56); + V[30] = (byte)(r >> 48); + V[29] = (byte)(r >> 40); + V[28] = (byte)(r >> 32); + V[27] = (byte)(r >> 24); + V[26] = (byte)(r >> 16); + V[25] = (byte)(r >> 8); + V[24] = (byte)(r); + + r = res[4]; + V[39] = (byte)(r >> 56); + V[38] = (byte)(r >> 48); + V[37] = (byte)(r >> 40); + V[36] = (byte)(r >> 32); + V[35] = (byte)(r >> 24); + V[34] = (byte)(r >> 16); + V[33] = (byte)(r >> 8); + V[32] = (byte)(r); + + r = res[5]; + V[47] = (byte)(r >> 56); + V[46] = (byte)(r >> 48); + V[45] = (byte)(r >> 40); + V[44] = (byte)(r >> 32); + V[43] = (byte)(r >> 24); + V[42] = (byte)(r >> 16); + V[41] = (byte)(r >> 8); + V[40] = (byte)(r); + + r = res[6]; + V[55] = (byte)(r >> 56); + V[54] = (byte)(r >> 48); + V[53] = (byte)(r >> 40); + V[52] = (byte)(r >> 32); + V[51] = (byte)(r >> 24); + V[50] = (byte)(r >> 16); + V[49] = (byte)(r >> 8); + V[48] = (byte)(r); + + r = res[7]; + V[63] = (byte)(r >> 56); + V[62] = (byte)(r >> 48); + V[61] = (byte)(r >> 40); + V[60] = (byte)(r >> 32); + V[59] = (byte)(r >> 24); + V[58] = (byte)(r >> 16); + V[57] = (byte)(r >> 8); + V[56] = (byte)(r); + } + + private void xor512(byte[] A, byte[] B) + { + for (int i = 0; i < 64; ++i) + { + A[i] ^= B[i]; + } + } + + private void E(byte[] K, byte[] m) + { + System.Array.Copy(K, 0, Ki, 0, 64); + xor512(K, m); + F(K); + for (int i = 0; i < 11; ++i) + { + xor512(Ki, C[i]); + F(Ki); + xor512(K, Ki); + F(K); + } + xor512(Ki, C[11]); + F(Ki); + xor512(K, Ki); + } + + private void g_N(byte[] h, byte[] N, byte[] m) + { + System.Array.Copy(h, 0, tmp, 0, 64); + + xor512(h, N); + F(h); + + E(h, m); + xor512(h, tmp); + xor512(h, m); + } + + private void addMod512(byte[] A, int num) + { + int c; + c = (A[63] & 0xFF) + (num & 0xFF); + A[63] = (byte)c; + + c = (A[62] & 0xFF) + ((num >> 8) & 0xFF) + (c >> 8); + A[62] = (byte)c; + + for (int i = 61; (i >= 0) && (c > 0); --i) + { + c = (A[i] & 0xFF) + (c >> 8); + A[i] = (byte)c; + } + } + + private void addMod512(byte[] A, byte[] B) + { + for (int c = 0, i = 63; i >= 0; --i) + { + c = (A[i] & 0xFF) + (B[i] & 0xFF) + (c >> 8); + A[i] = (byte)c; + } + } + + private void reverse(byte[] src, byte[] dst) + { + int len = src.Length; + for (int i = 0; i < len; i++) + { + dst[len - 1 - i] = src[i]; + } + } + + private static readonly byte[][] C = new byte[][]{ new byte[]{ + (byte)0xb1, (byte)0x08, (byte)0x5b, (byte)0xda, (byte)0x1e, (byte)0xca, (byte)0xda, (byte)0xe9, + (byte)0xeb, (byte)0xcb, (byte)0x2f, (byte)0x81, (byte)0xc0, (byte)0x65, (byte)0x7c, (byte)0x1f, + (byte)0x2f, (byte)0x6a, (byte)0x76, (byte)0x43, (byte)0x2e, (byte)0x45, (byte)0xd0, (byte)0x16, + (byte)0x71, (byte)0x4e, (byte)0xb8, (byte)0x8d, (byte)0x75, (byte)0x85, (byte)0xc4, (byte)0xfc, + (byte)0x4b, (byte)0x7c, (byte)0xe0, (byte)0x91, (byte)0x92, (byte)0x67, (byte)0x69, (byte)0x01, + (byte)0xa2, (byte)0x42, (byte)0x2a, (byte)0x08, (byte)0xa4, (byte)0x60, (byte)0xd3, (byte)0x15, + (byte)0x05, (byte)0x76, (byte)0x74, (byte)0x36, (byte)0xcc, (byte)0x74, (byte)0x4d, (byte)0x23, + (byte)0xdd, (byte)0x80, (byte)0x65, (byte)0x59, (byte)0xf2, (byte)0xa6, (byte)0x45, (byte)0x07}, + + new byte[]{ + (byte)0x6f, (byte)0xa3, (byte)0xb5, (byte)0x8a, (byte)0xa9, (byte)0x9d, (byte)0x2f, (byte)0x1a, + (byte)0x4f, (byte)0xe3, (byte)0x9d, (byte)0x46, (byte)0x0f, (byte)0x70, (byte)0xb5, (byte)0xd7, + (byte)0xf3, (byte)0xfe, (byte)0xea, (byte)0x72, (byte)0x0a, (byte)0x23, (byte)0x2b, (byte)0x98, + (byte)0x61, (byte)0xd5, (byte)0x5e, (byte)0x0f, (byte)0x16, (byte)0xb5, (byte)0x01, (byte)0x31, + (byte)0x9a, (byte)0xb5, (byte)0x17, (byte)0x6b, (byte)0x12, (byte)0xd6, (byte)0x99, (byte)0x58, + (byte)0x5c, (byte)0xb5, (byte)0x61, (byte)0xc2, (byte)0xdb, (byte)0x0a, (byte)0xa7, (byte)0xca, + (byte)0x55, (byte)0xdd, (byte)0xa2, (byte)0x1b, (byte)0xd7, (byte)0xcb, (byte)0xcd, (byte)0x56, + (byte)0xe6, (byte)0x79, (byte)0x04, (byte)0x70, (byte)0x21, (byte)0xb1, (byte)0x9b, (byte)0xb7}, + new byte[]{ + (byte)0xf5, (byte)0x74, (byte)0xdc, (byte)0xac, (byte)0x2b, (byte)0xce, (byte)0x2f, (byte)0xc7, + (byte)0x0a, (byte)0x39, (byte)0xfc, (byte)0x28, (byte)0x6a, (byte)0x3d, (byte)0x84, (byte)0x35, + (byte)0x06, (byte)0xf1, (byte)0x5e, (byte)0x5f, (byte)0x52, (byte)0x9c, (byte)0x1f, (byte)0x8b, + (byte)0xf2, (byte)0xea, (byte)0x75, (byte)0x14, (byte)0xb1, (byte)0x29, (byte)0x7b, (byte)0x7b, + (byte)0xd3, (byte)0xe2, (byte)0x0f, (byte)0xe4, (byte)0x90, (byte)0x35, (byte)0x9e, (byte)0xb1, + (byte)0xc1, (byte)0xc9, (byte)0x3a, (byte)0x37, (byte)0x60, (byte)0x62, (byte)0xdb, (byte)0x09, + (byte)0xc2, (byte)0xb6, (byte)0xf4, (byte)0x43, (byte)0x86, (byte)0x7a, (byte)0xdb, (byte)0x31, + (byte)0x99, (byte)0x1e, (byte)0x96, (byte)0xf5, (byte)0x0a, (byte)0xba, (byte)0x0a, (byte)0xb2}, + new byte[]{ + (byte)0xef, (byte)0x1f, (byte)0xdf, (byte)0xb3, (byte)0xe8, (byte)0x15, (byte)0x66, (byte)0xd2, + (byte)0xf9, (byte)0x48, (byte)0xe1, (byte)0xa0, (byte)0x5d, (byte)0x71, (byte)0xe4, (byte)0xdd, + (byte)0x48, (byte)0x8e, (byte)0x85, (byte)0x7e, (byte)0x33, (byte)0x5c, (byte)0x3c, (byte)0x7d, + (byte)0x9d, (byte)0x72, (byte)0x1c, (byte)0xad, (byte)0x68, (byte)0x5e, (byte)0x35, (byte)0x3f, + (byte)0xa9, (byte)0xd7, (byte)0x2c, (byte)0x82, (byte)0xed, (byte)0x03, (byte)0xd6, (byte)0x75, + (byte)0xd8, (byte)0xb7, (byte)0x13, (byte)0x33, (byte)0x93, (byte)0x52, (byte)0x03, (byte)0xbe, + (byte)0x34, (byte)0x53, (byte)0xea, (byte)0xa1, (byte)0x93, (byte)0xe8, (byte)0x37, (byte)0xf1, + (byte)0x22, (byte)0x0c, (byte)0xbe, (byte)0xbc, (byte)0x84, (byte)0xe3, (byte)0xd1, (byte)0x2e}, + new byte[] { + (byte)0x4b, (byte)0xea, (byte)0x6b, (byte)0xac, (byte)0xad, (byte)0x47, (byte)0x47, (byte)0x99, + (byte)0x9a, (byte)0x3f, (byte)0x41, (byte)0x0c, (byte)0x6c, (byte)0xa9, (byte)0x23, (byte)0x63, + (byte)0x7f, (byte)0x15, (byte)0x1c, (byte)0x1f, (byte)0x16, (byte)0x86, (byte)0x10, (byte)0x4a, + (byte)0x35, (byte)0x9e, (byte)0x35, (byte)0xd7, (byte)0x80, (byte)0x0f, (byte)0xff, (byte)0xbd, + (byte)0xbf, (byte)0xcd, (byte)0x17, (byte)0x47, (byte)0x25, (byte)0x3a, (byte)0xf5, (byte)0xa3, + (byte)0xdf, (byte)0xff, (byte)0x00, (byte)0xb7, (byte)0x23, (byte)0x27, (byte)0x1a, (byte)0x16, + (byte)0x7a, (byte)0x56, (byte)0xa2, (byte)0x7e, (byte)0xa9, (byte)0xea, (byte)0x63, (byte)0xf5, + (byte)0x60, (byte)0x17, (byte)0x58, (byte)0xfd, (byte)0x7c, (byte)0x6c, (byte)0xfe, (byte)0x57}, + new byte[]{ + (byte)0xae, (byte)0x4f, (byte)0xae, (byte)0xae, (byte)0x1d, (byte)0x3a, (byte)0xd3, (byte)0xd9, + (byte)0x6f, (byte)0xa4, (byte)0xc3, (byte)0x3b, (byte)0x7a, (byte)0x30, (byte)0x39, (byte)0xc0, + (byte)0x2d, (byte)0x66, (byte)0xc4, (byte)0xf9, (byte)0x51, (byte)0x42, (byte)0xa4, (byte)0x6c, + (byte)0x18, (byte)0x7f, (byte)0x9a, (byte)0xb4, (byte)0x9a, (byte)0xf0, (byte)0x8e, (byte)0xc6, + (byte)0xcf, (byte)0xfa, (byte)0xa6, (byte)0xb7, (byte)0x1c, (byte)0x9a, (byte)0xb7, (byte)0xb4, + (byte)0x0a, (byte)0xf2, (byte)0x1f, (byte)0x66, (byte)0xc2, (byte)0xbe, (byte)0xc6, (byte)0xb6, + (byte)0xbf, (byte)0x71, (byte)0xc5, (byte)0x72, (byte)0x36, (byte)0x90, (byte)0x4f, (byte)0x35, + (byte)0xfa, (byte)0x68, (byte)0x40, (byte)0x7a, (byte)0x46, (byte)0x64, (byte)0x7d, (byte)0x6e}, + new byte[] { + (byte)0xf4, (byte)0xc7, (byte)0x0e, (byte)0x16, (byte)0xee, (byte)0xaa, (byte)0xc5, (byte)0xec, + (byte)0x51, (byte)0xac, (byte)0x86, (byte)0xfe, (byte)0xbf, (byte)0x24, (byte)0x09, (byte)0x54, + (byte)0x39, (byte)0x9e, (byte)0xc6, (byte)0xc7, (byte)0xe6, (byte)0xbf, (byte)0x87, (byte)0xc9, + (byte)0xd3, (byte)0x47, (byte)0x3e, (byte)0x33, (byte)0x19, (byte)0x7a, (byte)0x93, (byte)0xc9, + (byte)0x09, (byte)0x92, (byte)0xab, (byte)0xc5, (byte)0x2d, (byte)0x82, (byte)0x2c, (byte)0x37, + (byte)0x06, (byte)0x47, (byte)0x69, (byte)0x83, (byte)0x28, (byte)0x4a, (byte)0x05, (byte)0x04, + (byte)0x35, (byte)0x17, (byte)0x45, (byte)0x4c, (byte)0xa2, (byte)0x3c, (byte)0x4a, (byte)0xf3, + (byte)0x88, (byte)0x86, (byte)0x56, (byte)0x4d, (byte)0x3a, (byte)0x14, (byte)0xd4, (byte)0x93}, + new byte[] { + (byte)0x9b, (byte)0x1f, (byte)0x5b, (byte)0x42, (byte)0x4d, (byte)0x93, (byte)0xc9, (byte)0xa7, + (byte)0x03, (byte)0xe7, (byte)0xaa, (byte)0x02, (byte)0x0c, (byte)0x6e, (byte)0x41, (byte)0x41, + (byte)0x4e, (byte)0xb7, (byte)0xf8, (byte)0x71, (byte)0x9c, (byte)0x36, (byte)0xde, (byte)0x1e, + (byte)0x89, (byte)0xb4, (byte)0x44, (byte)0x3b, (byte)0x4d, (byte)0xdb, (byte)0xc4, (byte)0x9a, + (byte)0xf4, (byte)0x89, (byte)0x2b, (byte)0xcb, (byte)0x92, (byte)0x9b, (byte)0x06, (byte)0x90, + (byte)0x69, (byte)0xd1, (byte)0x8d, (byte)0x2b, (byte)0xd1, (byte)0xa5, (byte)0xc4, (byte)0x2f, + (byte)0x36, (byte)0xac, (byte)0xc2, (byte)0x35, (byte)0x59, (byte)0x51, (byte)0xa8, (byte)0xd9, + (byte)0xa4, (byte)0x7f, (byte)0x0d, (byte)0xd4, (byte)0xbf, (byte)0x02, (byte)0xe7, (byte)0x1e}, + new byte[]{ + (byte)0x37, (byte)0x8f, (byte)0x5a, (byte)0x54, (byte)0x16, (byte)0x31, (byte)0x22, (byte)0x9b, + (byte)0x94, (byte)0x4c, (byte)0x9a, (byte)0xd8, (byte)0xec, (byte)0x16, (byte)0x5f, (byte)0xde, + (byte)0x3a, (byte)0x7d, (byte)0x3a, (byte)0x1b, (byte)0x25, (byte)0x89, (byte)0x42, (byte)0x24, + (byte)0x3c, (byte)0xd9, (byte)0x55, (byte)0xb7, (byte)0xe0, (byte)0x0d, (byte)0x09, (byte)0x84, + (byte)0x80, (byte)0x0a, (byte)0x44, (byte)0x0b, (byte)0xdb, (byte)0xb2, (byte)0xce, (byte)0xb1, + (byte)0x7b, (byte)0x2b, (byte)0x8a, (byte)0x9a, (byte)0xa6, (byte)0x07, (byte)0x9c, (byte)0x54, + (byte)0x0e, (byte)0x38, (byte)0xdc, (byte)0x92, (byte)0xcb, (byte)0x1f, (byte)0x2a, (byte)0x60, + (byte)0x72, (byte)0x61, (byte)0x44, (byte)0x51, (byte)0x83, (byte)0x23, (byte)0x5a, (byte)0xdb}, + new byte[] { + (byte)0xab, (byte)0xbe, (byte)0xde, (byte)0xa6, (byte)0x80, (byte)0x05, (byte)0x6f, (byte)0x52, + (byte)0x38, (byte)0x2a, (byte)0xe5, (byte)0x48, (byte)0xb2, (byte)0xe4, (byte)0xf3, (byte)0xf3, + (byte)0x89, (byte)0x41, (byte)0xe7, (byte)0x1c, (byte)0xff, (byte)0x8a, (byte)0x78, (byte)0xdb, + (byte)0x1f, (byte)0xff, (byte)0xe1, (byte)0x8a, (byte)0x1b, (byte)0x33, (byte)0x61, (byte)0x03, + (byte)0x9f, (byte)0xe7, (byte)0x67, (byte)0x02, (byte)0xaf, (byte)0x69, (byte)0x33, (byte)0x4b, + (byte)0x7a, (byte)0x1e, (byte)0x6c, (byte)0x30, (byte)0x3b, (byte)0x76, (byte)0x52, (byte)0xf4, + (byte)0x36, (byte)0x98, (byte)0xfa, (byte)0xd1, (byte)0x15, (byte)0x3b, (byte)0xb6, (byte)0xc3, + (byte)0x74, (byte)0xb4, (byte)0xc7, (byte)0xfb, (byte)0x98, (byte)0x45, (byte)0x9c, (byte)0xed}, + new byte[] { + (byte)0x7b, (byte)0xcd, (byte)0x9e, (byte)0xd0, (byte)0xef, (byte)0xc8, (byte)0x89, (byte)0xfb, + (byte)0x30, (byte)0x02, (byte)0xc6, (byte)0xcd, (byte)0x63, (byte)0x5a, (byte)0xfe, (byte)0x94, + (byte)0xd8, (byte)0xfa, (byte)0x6b, (byte)0xbb, (byte)0xeb, (byte)0xab, (byte)0x07, (byte)0x61, + (byte)0x20, (byte)0x01, (byte)0x80, (byte)0x21, (byte)0x14, (byte)0x84, (byte)0x66, (byte)0x79, + (byte)0x8a, (byte)0x1d, (byte)0x71, (byte)0xef, (byte)0xea, (byte)0x48, (byte)0xb9, (byte)0xca, + (byte)0xef, (byte)0xba, (byte)0xcd, (byte)0x1d, (byte)0x7d, (byte)0x47, (byte)0x6e, (byte)0x98, + (byte)0xde, (byte)0xa2, (byte)0x59, (byte)0x4a, (byte)0xc0, (byte)0x6f, (byte)0xd8, (byte)0x5d, + (byte)0x6b, (byte)0xca, (byte)0xa4, (byte)0xcd, (byte)0x81, (byte)0xf3, (byte)0x2d, (byte)0x1b}, + new byte[] { + (byte)0x37, (byte)0x8e, (byte)0xe7, (byte)0x67, (byte)0xf1, (byte)0x16, (byte)0x31, (byte)0xba, + (byte)0xd2, (byte)0x13, (byte)0x80, (byte)0xb0, (byte)0x04, (byte)0x49, (byte)0xb1, (byte)0x7a, + (byte)0xcd, (byte)0xa4, (byte)0x3c, (byte)0x32, (byte)0xbc, (byte)0xdf, (byte)0x1d, (byte)0x77, + (byte)0xf8, (byte)0x20, (byte)0x12, (byte)0xd4, (byte)0x30, (byte)0x21, (byte)0x9f, (byte)0x9b, + (byte)0x5d, (byte)0x80, (byte)0xef, (byte)0x9d, (byte)0x18, (byte)0x91, (byte)0xcc, (byte)0x86, + (byte)0xe7, (byte)0x1d, (byte)0xa4, (byte)0xaa, (byte)0x88, (byte)0xe1, (byte)0x28, (byte)0x52, + (byte)0xfa, (byte)0xf4, (byte)0x17, (byte)0xd5, (byte)0xd9, (byte)0xb2, (byte)0x1b, (byte)0x99, + (byte)0x48, (byte)0xbc, (byte)0x92, (byte)0x4a, (byte)0xf1, (byte)0x1b, (byte)0xd7, (byte)0x20} + }; + + private static readonly byte[] Zero = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + private readonly static ulong[][] T = { + new ulong[] { + 0xE6F87E5C5B711FD0L, 0x258377800924FA16L, 0xC849E07E852EA4A8L, 0x5B4686A18F06C16AL, + 0x0B32E9A2D77B416EL, 0xABDA37A467815C66L, 0xF61796A81A686676L, 0xF5DC0B706391954BL, + 0x4862F38DB7E64BF1L, 0xFF5C629A68BD85C5L, 0xCB827DA6FCD75795L, 0x66D36DAF69B9F089L, + 0x356C9F74483D83B0L, 0x7CBCECB1238C99A1L, 0x36A702AC31C4708DL, 0x9EB6A8D02FBCDFD6L, + 0x8B19FA51E5B3AE37L, 0x9CCFB5408A127D0BL, 0xBC0C78B508208F5AL, 0xE533E3842288ECEDL, + 0xCEC2C7D377C15FD2L, 0xEC7817B6505D0F5EL, 0xB94CC2C08336871DL, 0x8C205DB4CB0B04ADL, + 0x763C855B28A0892FL, 0x588D1B79F6FF3257L, 0x3FECF69E4311933EL, 0x0FC0D39F803A18C9L, + 0xEE010A26F5F3AD83L, 0x10EFE8F4411979A6L, 0x5DCDA10C7DE93A10L, 0x4A1BEE1D1248E92CL, + 0x53BFF2DB21847339L, 0xB4F50CCFA6A23D09L, 0x5FB4BC9CD84798CDL, 0xE88A2D8B071C56F9L, + 0x7F7771695A756A9CL, 0xC5F02E71A0BA1EBCL, 0xA663F9AB4215E672L, 0x2EB19E22DE5FBB78L, + 0x0DB9CE0F2594BA14L, 0x82520E6397664D84L, 0x2F031E6A0208EA98L, 0x5C7F2144A1BE6BF0L, + 0x7A37CB1CD16362DBL, 0x83E08E2B4B311C64L, 0xCF70479BAB960E32L, 0x856BA986B9DEE71EL, + 0xB5478C877AF56CE9L, 0xB8FE42885F61D6FDL, 0x1BDD0156966238C8L, 0x622157923EF8A92EL, + 0xFC97FF42114476F8L, 0x9D7D350856452CEBL, 0x4C90C9B0E0A71256L, 0x2308502DFBCB016CL, + 0x2D7A03FAA7A64845L, 0xF46E8B38BFC6C4ABL, 0xBDBEF8FDD477DEBAL, 0x3AAC4CEBC8079B79L, + 0xF09CB105E8879D0CL, 0x27FA6A10AC8A58CBL, 0x8960E7C1401D0CEAL, 0x1A6F811E4A356928L, + 0x90C4FB0773D196FFL, 0x43501A2F609D0A9FL, 0xF7A516E0C63F3796L, 0x1CE4A6B3B8DA9252L, + 0x1324752C38E08A9BL, 0xA5A864733BEC154FL, 0x2BF124575549B33FL, 0xD766DB15440DC5C7L, + 0xA7D179E39E42B792L, 0xDADF151A61997FD3L, 0x86A0345EC0271423L, 0x38D5517B6DA939A4L, + 0x6518F077104003B4L, 0x02791D90A5AEA2DDL, 0x88D267899C4A5D0AL, 0x930F66DF0A2865C2L, + 0x4EE9D4204509B08BL, 0x325538916685292AL, 0x412907BFC533A842L, 0xB27E2B62544DC673L, + 0x6C5304456295E007L, 0x5AF406E95351908AL, 0x1F2F3B6BC123616FL, 0xC37B09DC5255E5C6L, + 0x3967D133B1FE6844L, 0x298839C7F0E711E2L, 0x409B87F71964F9A2L, 0xE938ADC3DB4B0719L, + 0x0C0B4E47F9C3EBF4L, 0x5534D576D36B8843L, 0x4610A05AEB8B02D8L, 0x20C3CDF58232F251L, + 0x6DE1840DBEC2B1E7L, 0xA0E8DE06B0FA1D08L, 0x7B854B540D34333BL, 0x42E29A67BCCA5B7FL, + 0xD8A6088AC437DD0EL, 0xC63BB3A9D943ED81L, 0x21714DBD5E65A3B1L, 0x6761EDE7B5EEA169L, + 0x2431F7C8D573ABF6L, 0xD51FC685E1A3671AL, 0x5E063CD40410C92DL, 0x283AB98F2CB04002L, + 0x8FEBC06CB2F2F790L, 0x17D64F116FA1D33CL, 0xE07359F1A99EE4AAL, 0x784ED68C74CDC006L, + 0x6E2A19D5C73B42DAL, 0x8712B4161C7045C3L, 0x371582E4ED93216DL, 0xACE390414939F6FCL, + 0x7EC5F12186223B7CL, 0xC0B094042BAC16FBL, 0xF9D745379A527EBFL, 0x737C3F2EA3B68168L, + 0x33E7B8D9BAD278CAL, 0xA9A32A34C22FFEBBL, 0xE48163CCFEDFBD0DL, 0x8E5940246EA5A670L, + 0x51C6EF4B842AD1E4L, 0x22BAD065279C508CL, 0xD91488C218608CEEL, 0x319EA5491F7CDA17L, + 0xD394E128134C9C60L, 0x094BF43272D5E3B3L, 0x9BF612A5A4AAD791L, 0xCCBBDA43D26FFD0FL, + 0x34DE1F3C946AD250L, 0x4F5B5468995EE16BL, 0xDF9FAF6FEA8F7794L, 0x2648EA5870DD092BL, + 0xBFC7E56D71D97C67L, 0xDDE6B2FF4F21D549L, 0x3C276B463AE86003L, 0x91767B4FAF86C71FL, + 0x68A13E7835D4B9A0L, 0xB68C115F030C9FD4L, 0x141DD2C916582001L, 0x983D8F7DDD5324ACL, + 0x64AA703FCC175254L, 0xC2C989948E02B426L, 0x3E5E76D69F46C2DEL, 0x50746F03587D8004L, + 0x45DB3D829272F1E5L, 0x60584A029B560BF3L, 0xFBAE58A73FFCDC62L, 0xA15A5E4E6CAD4CE8L, + 0x4BA96E55CE1FB8CCL, 0x08F9747AAE82B253L, 0xC102144CF7FB471BL, 0x9F042898F3EB8E36L, + 0x068B27ADF2EFFB7AL, 0xEDCA97FE8C0A5EBEL, 0x778E0513F4F7D8CFL, 0x302C2501C32B8BF7L, + 0x8D92DDFC175C554DL, 0xF865C57F46052F5FL, 0xEAF3301BA2B2F424L, 0xAA68B7ECBBD60D86L, + 0x998F0F350104754CL, 0x0000000000000000L, 0xF12E314D34D0CCECL, 0x710522BE061823B5L, + 0xAF280D9930C005C1L, 0x97FD5CE25D693C65L, 0x19A41CC633CC9A15L, 0x95844172F8C79EB8L, + 0xDC5432B7937684A9L, 0x9436C13A2490CF58L, 0x802B13F332C8EF59L, 0xC442AE397CED4F5CL, + 0xFA1CD8EFE3AB8D82L, 0xF2E5AC954D293FD1L, 0x6AD823E8907A1B7DL, 0x4D2249F83CF043B6L, + 0x03CB9DD879F9F33DL, 0xDE2D2F2736D82674L, 0x2A43A41F891EE2DFL, 0x6F98999D1B6C133AL, + 0xD4AD46CD3DF436FAL, 0xBB35DF50269825C0L, 0x964FDCAA813E6D85L, 0xEB41B0537EE5A5C4L, + 0x0540BA758B160847L, 0xA41AE43BE7BB44AFL, 0xE3B8C429D0671797L, 0x819993BBEE9FBEB9L, + 0xAE9A8DD1EC975421L, 0xF3572CDD917E6E31L, 0x6393D7DAE2AFF8CEL, 0x47A2201237DC5338L, + 0xA32343DEC903EE35L, 0x79FC56C4A89A91E6L, 0x01B28048DC5751E0L, 0x1296F564E4B7DB7BL, + 0x75F7188351597A12L, 0xDB6D9552BDCE2E33L, 0x1E9DBB231D74308FL, 0x520D7293FDD322D9L, + 0xE20A44610C304677L, 0xFEEEE2D2B4EAD425L, 0xCA30FDEE20800675L, 0x61EACA4A47015A13L, + 0xE74AFE1487264E30L, 0x2CC883B27BF119A5L, 0x1664CF59B3F682DCL, 0xA811AA7C1E78AF5BL, + 0x1D5626FB648DC3B2L, 0xB73E9117DF5BCE34L, 0xD05F7CF06AB56F5DL, 0xFD257F0ACD132718L, + 0x574DC8E676C52A9EL, 0x0739A7E52EB8AA9AL, 0x5486553E0F3CD9A3L, 0x56FF48AEAA927B7EL, + 0xBE756525AD8E2D87L, 0x7D0E6CF9FFDBC841L, 0x3B1ECCA31450CA99L, 0x6913BE30E983E840L, + 0xAD511009956EA71CL, 0xB1B5B6BA2DB4354EL, 0x4469BDCA4E25A005L, 0x15AF5281CA0F71E1L, + 0x744598CB8D0E2BF2L, 0x593F9B312AA863B7L, 0xEFB38A6E29A4FC63L, 0x6B6AA3A04C2D4A9DL, + 0x3D95EB0EE6BF31E3L, 0xA291C3961554BFD5L, 0x18169C8EEF9BCBF5L, 0x115D68BC9D4E2846L, + 0xBA875F18FACF7420L, 0xD1EDFCB8B6E23EBDL, 0xB00736F2F1E364AEL, 0x84D929CE6589B6FEL, + 0x70B7A2F6DA4F7255L, 0x0E7253D75C6D4929L, 0x04F23A3D574159A7L, 0x0A8069EA0B2C108EL, + 0x49D073C56BB11A11L, 0x8AAB7A1939E4FFD7L, 0xCD095A0B0E38ACEFL, 0xC9FB60365979F548L, + 0x92BDE697D67F3422L, 0xC78933E10514BC61L, 0xE1C1D9B975C9B54AL, 0xD2266160CF1BCD80L, + 0x9A4492ED78FD8671L, 0xB3CCAB2A881A9793L, 0x72CEBF667FE1D088L, 0xD6D45B5D985A9427L + }, + new ulong[]{ + 0xC811A8058C3F55DEL, 0x65F5B43196B50619L, 0xF74F96B1D6706E43L, 0x859D1E8BCB43D336L, + 0x5AAB8A85CCFA3D84L, 0xF9C7BF99C295FCFDL, 0xA21FD5A1DE4B630FL, 0xCDB3EF763B8B456DL, + 0x803F59F87CF7C385L, 0xB27C73BE5F31913CL, 0x98E3AC6633B04821L, 0xBF61674C26B8F818L, + 0x0FFBC995C4C130C8L, 0xAAA0862010761A98L, 0x6057F342210116AAL, 0xF63C760C0654CC35L, + 0x2DDB45CC667D9042L, 0xBCF45A964BD40382L, 0x68E8A0C3EF3C6F3DL, 0xA7BD92D269FF73BCL, + 0x290AE20201ED2287L, 0xB7DE34CDE885818FL, 0xD901EEA7DD61059BL, 0xD6FA273219A03553L, + 0xD56F1AE874CCCEC9L, 0xEA31245C2E83F554L, 0x7034555DA07BE499L, 0xCE26D2AC56E7BEF7L, + 0xFD161857A5054E38L, 0x6A0E7DA4527436D1L, 0x5BD86A381CDE9FF2L, 0xCAF7756231770C32L, + 0xB09AAED9E279C8D0L, 0x5DEF1091C60674DBL, 0x111046A2515E5045L, 0x23536CE4729802FCL, + 0xC50CBCF7F5B63CFAL, 0x73A16887CD171F03L, 0x7D2941AFD9F28DBDL, 0x3F5E3EB45A4F3B9DL, + 0x84EEFE361B677140L, 0x3DB8E3D3E7076271L, 0x1A3A28F9F20FD248L, 0x7EBC7C75B49E7627L, + 0x74E5F293C7EB565CL, 0x18DCF59E4F478BA4L, 0x0C6EF44FA9ADCB52L, 0xC699812D98DAC760L, + 0x788B06DC6E469D0EL, 0xFC65F8EA7521EC4EL, 0x30A5F7219E8E0B55L, 0x2BEC3F65BCA57B6BL, + 0xDDD04969BAF1B75EL, 0x99904CDBE394EA57L, 0x14B201D1E6EA40F6L, 0xBBB0C08241284ADDL, + 0x50F20463BF8F1DFFL, 0xE8D7F93B93CBACB8L, 0x4D8CB68E477C86E8L, 0xC1DD1B3992268E3FL, + 0x7C5AA11209D62FCBL, 0x2F3D98ABDB35C9AEL, 0x671369562BFD5FF5L, 0x15C1E16C36CEE280L, + 0x1D7EB2EDF8F39B17L, 0xDA94D37DB00DFE01L, 0x877BC3EC760B8ADAL, 0xCB8495DFE153AE44L, + 0x05A24773B7B410B3L, 0x12857B783C32ABDFL, 0x8EB770D06812513BL, 0x536739B9D2E3E665L, + 0x584D57E271B26468L, 0xD789C78FC9849725L, 0xA935BBFA7D1AE102L, 0x8B1537A3DFA64188L, + 0xD0CD5D9BC378DE7AL, 0x4AC82C9A4D80CFB7L, 0x42777F1B83BDB620L, 0x72D2883A1D33BD75L, + 0x5E7A2D4BAB6A8F41L, 0xF4DAAB6BBB1C95D9L, 0x905CFFE7FD8D31B6L, 0x83AA6422119B381FL, + 0xC0AEFB8442022C49L, 0xA0F908C663033AE3L, 0xA428AF0804938826L, 0xADE41C341A8A53C7L, + 0xAE7121EE77E6A85DL, 0xC47F5C4A25929E8CL, 0xB538E9AA55CDD863L, 0x06377AA9DAD8EB29L, + 0xA18AE87BB3279895L, 0x6EDFDA6A35E48414L, 0x6B7D9D19825094A7L, 0xD41CFA55A4E86CBFL, + 0xE5CAEDC9EA42C59CL, 0xA36C351C0E6FC179L, 0x5181E4DE6FABBF89L, 0xFFF0C530184D17D4L, + 0x9D41EB1584045892L, 0x1C0D525028D73961L, 0xF178EC180CA8856AL, 0x9A0571018EF811CDL, + 0x4091A27C3EF5EFCCL, 0x19AF15239F6329D2L, 0x347450EFF91EB990L, 0xE11B4A078DD27759L, + 0xB9561DE5FC601331L, 0x912F1F5A2DA993C0L, 0x1654DCB65BA2191AL, 0x3E2DDE098A6B99EBL, + 0x8A66D71E0F82E3FEL, 0x8C51ADB7D55A08D7L, 0x4533E50F8941FF7FL, 0x02E6DD67BD4859ECL, + 0xE068AABA5DF6D52FL, 0xC24826E3FF4A75A5L, 0x6C39070D88ACDDF8L, 0x6486548C4691A46FL, + 0xD1BEBD26135C7C0CL, 0xB30F93038F15334AL, 0x82D9849FC1BF9A69L, 0x9C320BA85420FAE4L, + 0xFA528243AFF90767L, 0x9ED4D6CFE968A308L, 0xB825FD582C44B147L, 0x9B7691BC5EDCB3BBL, + 0xC7EA619048FE6516L, 0x1063A61F817AF233L, 0x47D538683409A693L, 0x63C2CE984C6DED30L, + 0x2A9FDFD86C81D91DL, 0x7B1E3B06032A6694L, 0x666089EBFBD9FD83L, 0x0A598EE67375207BL, + 0x07449A140AFC495FL, 0x2CA8A571B6593234L, 0x1F986F8A45BBC2FBL, 0x381AA4A050B372C2L, + 0x5423A3ADD81FAF3AL, 0x17273C0B8B86BB6CL, 0xFE83258DC869B5A2L, 0x287902BFD1C980F1L, + 0xF5A94BD66B3837AFL, 0x88800A79B2CABA12L, 0x55504310083B0D4CL, 0xDF36940E07B9EEB2L, + 0x04D1A7CE6790B2C5L, 0x612413FFF125B4DCL, 0x26F12B97C52C124FL, 0x86082351A62F28ACL, + 0xEF93632F9937E5E7L, 0x3507B052293A1BE6L, 0xE72C30AE570A9C70L, 0xD3586041AE1425E0L, + 0xDE4574B3D79D4CC4L, 0x92BA228040C5685AL, 0xF00B0CA5DC8C271CL, 0xBE1287F1F69C5A6EL, + 0xF39E317FB1E0DC86L, 0x495D114020EC342DL, 0x699B407E3F18CD4BL, 0xDCA3A9D46AD51528L, + 0x0D1D14F279896924L, 0x0000000000000000L, 0x593EB75FA196C61EL, 0x2E4E78160B116BD8L, + 0x6D4AE7B058887F8EL, 0xE65FD013872E3E06L, 0x7A6DDBBBD30EC4E2L, 0xAC97FC89CAAEF1B1L, + 0x09CCB33C1E19DBE1L, 0x89F3EAC462EE1864L, 0x7770CF49AA87ADC6L, 0x56C57ECA6557F6D6L, + 0x03953DDA6D6CFB9AL, 0x36928D884456E07CL, 0x1EEB8F37959F608DL, 0x31D6179C4EAAA923L, + 0x6FAC3AD7E5C02662L, 0x43049FA653991456L, 0xABD3669DC052B8EEL, 0xAF02C153A7C20A2BL, + 0x3CCB036E3723C007L, 0x93C9C23D90E1CA2CL, 0xC33BC65E2F6ED7D3L, 0x4CFF56339758249EL, + 0xB1E94E64325D6AA6L, 0x37E16D359472420AL, 0x79F8E661BE623F78L, 0x5214D90402C74413L, + 0x482EF1FDF0C8965BL, 0x13F69BC5EC1609A9L, 0x0E88292814E592BEL, 0x4E198B542A107D72L, + 0xCCC00FCBEBAFE71BL, 0x1B49C844222B703EL, 0x2564164DA840E9D5L, 0x20C6513E1FF4F966L, + 0xBAC3203F910CE8ABL, 0xF2EDD1C261C47EF0L, 0x814CB945ACD361F3L, 0x95FEB8944A392105L, + 0x5C9CF02C1622D6ADL, 0x971865F3F77178E9L, 0xBD87BA2B9BF0A1F4L, 0x444005B259655D09L, + 0xED75BE48247FBC0BL, 0x7596122E17CFF42AL, 0xB44B091785E97A15L, 0x966B854E2755DA9FL, + 0xEEE0839249134791L, 0x32432A4623C652B9L, 0xA8465B47AD3E4374L, 0xF8B45F2412B15E8BL, + 0x2417F6F078644BA3L, 0xFB2162FE7FDDA511L, 0x4BBBCC279DA46DC1L, 0x0173E0BDD024A276L, + 0x22208C59A2BCA08AL, 0x8FC4906DB836F34DL, 0xE4B90D743A6667EAL, 0x7147B5E0705F46EFL, + 0x2782CB2A1508B039L, 0xEC065EF5F45B1E7DL, 0x21B5B183CFD05B10L, 0xDBE733C060295C77L, + 0x9FA73672394C017EL, 0xCF55321186C31C81L, 0xD8720E1A0D45A7EDL, 0x3B8F997A3DDF8958L, + 0x3AFC79C7EDFB2B2EL, 0xE9A4198643EF0ECEL, 0x5F09CDF67B4E2D37L, 0x4F6A6BE9FA34DF04L, + 0xB6ADD47038A123F9L, 0x8D224D0A057EAAA1L, 0xC96248B85C1BF7A8L, 0xE3FD9760309A2EB5L, + 0x0B2A6E5BA351820DL, 0xEB42C4E1FEA75722L, 0x948D58299A1D8373L, 0x7FCF9CC864BAD451L, + 0xA55B4FB5D4B72A50L, 0x08BF5381CE3D7997L, 0x46A6D8D5E42D04E5L, 0xD22B80FC7E308796L, + 0x57B69E77B57354A0L, 0x3969441D8097D0B4L, 0x3330CAFBF3E2F0CFL, 0xE28E77DDE0BE8CC3L, + 0x62B12E259C494F46L, 0xA6CE726FB9DBD1CAL, 0x41E242C1EED14DBAL, 0x76032FF47AA30FB0L + }, + new ulong[]{ + 0x45B268A93ACDE4CCL, 0xAF7F0BE884549D08L, 0x048354B3C1468263L, 0x925435C2C80EFED2L, + 0xEE4E37F27FDFFBA7L, 0x167A33920C60F14DL, 0xFB123B52EA03E584L, 0x4A0CAB53FDBB9007L, + 0x9DEAF6380F788A19L, 0xCB48EC558F0CB32AL, 0xB59DC4B2D6FEF7E0L, 0xDCDBCA22F4F3ECB6L, + 0x11DF5813549A9C40L, 0xE33FDEDF568ACED3L, 0xA0C1C8124322E9C3L, 0x07A56B8158FA6D0DL, + 0x77279579B1E1F3DDL, 0xD9B18B74422AC004L, 0xB8EC2D9FFFABC294L, 0xF4ACF8A82D75914FL, + 0x7BBF69B1EF2B6878L, 0xC4F62FAF487AC7E1L, 0x76CE809CC67E5D0CL, 0x6711D88F92E4C14CL, + 0x627B99D9243DEDFEL, 0x234AA5C3DFB68B51L, 0x909B1F15262DBF6DL, 0x4F66EA054B62BCB5L, + 0x1AE2CF5A52AA6AE8L, 0xBEA053FBD0CE0148L, 0xED6808C0E66314C9L, 0x43FE16CD15A82710L, + 0xCD049231A06970F6L, 0xE7BC8A6C97CC4CB0L, 0x337CE835FCB3B9C0L, 0x65DEF2587CC780F3L, + 0x52214EDE4132BB50L, 0x95F15E4390F493DFL, 0x870839625DD2E0F1L, 0x41313C1AFB8B66AFL, + 0x91720AF051B211BCL, 0x477D427ED4EEA573L, 0x2E3B4CEEF6E3BE25L, 0x82627834EB0BCC43L, + 0x9C03E3DD78E724C8L, 0x2877328AD9867DF9L, 0x14B51945E243B0F2L, 0x574B0F88F7EB97E2L, + 0x88B6FA989AA4943AL, 0x19C4F068CB168586L, 0x50EE6409AF11FAEFL, 0x7DF317D5C04EABA4L, + 0x7A567C5498B4C6A9L, 0xB6BBFB804F42188EL, 0x3CC22BCF3BC5CD0BL, 0xD04336EAAA397713L, + 0xF02FAC1BEC33132CL, 0x2506DBA7F0D3488DL, 0xD7E65D6BF2C31A1EL, 0x5EB9B2161FF820F5L, + 0x842E0650C46E0F9FL, 0x716BEB1D9E843001L, 0xA933758CAB315ED4L, 0x3FE414FDA2792265L, + 0x27C9F1701EF00932L, 0x73A4C1CA70A771BEL, 0x94184BA6E76B3D0EL, 0x40D829FF8C14C87EL, + 0x0FBEC3FAC77674CBL, 0x3616A9634A6A9572L, 0x8F139119C25EF937L, 0xF545ED4D5AEA3F9EL, + 0xE802499650BA387BL, 0x6437E7BD0B582E22L, 0xE6559F89E053E261L, 0x80AD52E305288DFCL, + 0x6DC55A23E34B9935L, 0xDE14E0F51AD0AD09L, 0xC6390578A659865EL, 0x96D7617109487CB1L, + 0xE2D6CB3A21156002L, 0x01E915E5779FAED1L, 0xADB0213F6A77DCB7L, 0x9880B76EB9A1A6ABL, + 0x5D9F8D248644CF9BL, 0xFD5E4536C5662658L, 0xF1C6B9FE9BACBDFDL, 0xEACD6341BE9979C4L, + 0xEFA7221708405576L, 0x510771ECD88E543EL, 0xC2BA51CB671F043DL, 0x0AD482AC71AF5879L, + 0xFE787A045CDAC936L, 0xB238AF338E049AEDL, 0xBD866CC94972EE26L, 0x615DA6EBBD810290L, + 0x3295FDD08B2C1711L, 0xF834046073BF0AEAL, 0xF3099329758FFC42L, 0x1CAEB13E7DCFA934L, + 0xBA2307481188832BL, 0x24EFCE42874CE65CL, 0x0E57D61FB0E9DA1AL, 0xB3D1BAD6F99B343CL, + 0xC0757B1C893C4582L, 0x2B510DB8403A9297L, 0x5C7698C1F1DB614AL, 0x3E0D0118D5E68CB4L, + 0xD60F488E855CB4CFL, 0xAE961E0DF3CB33D9L, 0x3A8E55AB14A00ED7L, 0x42170328623789C1L, + 0x838B6DD19C946292L, 0x895FEF7DED3B3AEBL, 0xCFCBB8E64E4A3149L, 0x064C7E642F65C3DCL, + 0x3D2B3E2A4C5A63DAL, 0x5BD3F340A9210C47L, 0xB474D157A1615931L, 0xAC5934DA1DE87266L, + 0x6EE365117AF7765BL, 0xC86ED36716B05C44L, 0x9BA6885C201D49C5L, 0xB905387A88346C45L, + 0x131072C4BAB9DDFFL, 0xBF49461EA751AF99L, 0xD52977BC1CE05BA1L, 0xB0F785E46027DB52L, + 0x546D30BA6E57788CL, 0x305AD707650F56AEL, 0xC987C682612FF295L, 0xA5AB8944F5FBC571L, + 0x7ED528E759F244CAL, 0x8DDCBBCE2C7DB888L, 0xAA154ABE328DB1BAL, 0x1E619BE993ECE88BL, + 0x09F2BD9EE813B717L, 0x7401AA4B285D1CB3L, 0x21858F143195CAEEL, 0x48C381841398D1B8L, + 0xFCB750D3B2F98889L, 0x39A86A998D1CE1B9L, 0x1F888E0CE473465AL, 0x7899568376978716L, + 0x02CF2AD7EE2341BFL, 0x85C713B5B3F1A14EL, 0xFF916FE12B4567E7L, 0x7C1A0230B7D10575L, + 0x0C98FCC85ECA9BA5L, 0xA3E7F720DA9E06ADL, 0x6A6031A2BBB1F438L, 0x973E74947ED7D260L, + 0x2CF4663918C0FF9AL, 0x5F50A7F368678E24L, 0x34D983B4A449D4CDL, 0x68AF1B755592B587L, + 0x7F3C3D022E6DEA1BL, 0xABFC5F5B45121F6BL, 0x0D71E92D29553574L, 0xDFFDF5106D4F03D8L, + 0x081BA87B9F8C19C6L, 0xDB7EA1A3AC0981BBL, 0xBBCA12AD66172DFAL, 0x79704366010829C7L, + 0x179326777BFF5F9CL, 0x0000000000000000L, 0xEB2476A4C906D715L, 0x724DD42F0738DF6FL, + 0xB752EE6538DDB65FL, 0x37FFBC863DF53BA3L, 0x8EFA84FCB5C157E6L, 0xE9EB5C73272596AAL, + 0x1B0BDABF2535C439L, 0x86E12C872A4D4E20L, 0x9969A28BCE3E087AL, 0xFAFB2EB79D9C4B55L, + 0x056A4156B6D92CB2L, 0x5A3AE6A5DEBEA296L, 0x22A3B026A8292580L, 0x53C85B3B36AD1581L, + 0xB11E900117B87583L, 0xC51F3A4A3FE56930L, 0xE019E1EDCF3621BDL, 0xEC811D2591FCBA18L, + 0x445B7D4C4D524A1DL, 0xA8DA6069DCAEF005L, 0x58F5CC72309DE329L, 0xD4C062596B7FF570L, + 0xCE22AD0339D59F98L, 0x591CD99747024DF8L, 0x8B90C5AA03187B54L, 0xF663D27FC356D0F0L, + 0xD8589E9135B56ED5L, 0x35309651D3D67A1CL, 0x12F96721CD26732EL, 0xD28C1C3D441A36ACL, + 0x492A946164077F69L, 0x2D1D73DC6F5F514BL, 0x6F0A70F40D68D88AL, 0x60B4B30ECA1EAC41L, + 0xD36509D83385987DL, 0x0B3D97490630F6A8L, 0x9ECCC90A96C46577L, 0xA20EE2C5AD01A87CL, + 0xE49AB55E0E70A3DEL, 0xA4429CA182646BA0L, 0xDA97B446DB962F6AL, 0xCCED87D4D7F6DE27L, + 0x2AB8185D37A53C46L, 0x9F25DCEFE15BCBA6L, 0xC19C6EF9FEA3EB53L, 0xA764A3931BD884CEL, + 0x2FD2590B817C10F4L, 0x56A21A6D80743933L, 0xE573A0BB79EF0D0FL, 0x155C0CA095DC1E23L, + 0x6C2C4FC694D437E4L, 0x10364DF623053291L, 0xDD32DFC7836C4267L, 0x03263F3299BCEF6EL, + 0x66F8CD6AE57B6F9DL, 0x8C35AE2B5BE21659L, 0x31B3C2E21290F87FL, 0x93BD2027BF915003L, + 0x69460E90220D1B56L, 0x299E276FAE19D328L, 0x63928C3C53A2432FL, 0x7082FEF8E91B9ED0L, + 0xBC6F792C3EED40F7L, 0x4C40D537D2DE53DBL, 0x75E8BFAE5FC2B262L, 0x4DA9C0D2A541FD0AL, + 0x4E8FFFE03CFD1264L, 0x2620E495696FA7E3L, 0xE1F0F408B8A98F6CL, 0xD1AA230FDDA6D9C2L, + 0xC7D0109DD1C6288FL, 0x8A79D04F7487D585L, 0x4694579BA3710BA2L, 0x38417F7CFA834F68L, + 0x1D47A4DB0A5007E5L, 0x206C9AF1460A643FL, 0xA128DDF734BD4712L, 0x8144470672B7232DL, + 0xF2E086CC02105293L, 0x182DE58DBC892B57L, 0xCAA1F9B0F8931DFBL, 0x6B892447CC2E5AE9L, + 0xF9DD11850420A43BL, 0x4BE5BEB68A243ED6L, 0x5584255F19C8D65DL, 0x3B67404E633FA006L, + 0xA68DB6766C472A1FL, 0xF78AC79AB4C97E21L, 0xC353442E1080AAECL, 0x9A4F9DB95782E714L + }, + new ulong[] { + 0x05BA7BC82C9B3220L, 0x31A54665F8B65E4FL, 0xB1B651F77547F4D4L, 0x8BFA0D857BA46682L, + 0x85A96C5AA16A98BBL, 0x990FAEF908EB79C9L, 0xA15E37A247F4A62DL, 0x76857DCD5D27741EL, + 0xF8C50B800A1820BCL, 0xBE65DCB201F7A2B4L, 0x666D1B986F9426E7L, 0x4CC921BF53C4E648L, + 0x95410A0F93D9CA42L, 0x20CDCCAA647BA4EFL, 0x429A4060890A1871L, 0x0C4EA4F69B32B38BL, + 0xCCDA362DDE354CD3L, 0x96DC23BC7C5B2FA9L, 0xC309BB68AA851AB3L, 0xD26131A73648E013L, + 0x021DC52941FC4DB2L, 0xCD5ADAB7704BE48AL, 0xA77965D984ED71E6L, 0x32386FD61734BBA4L, + 0xE82D6DD538AB7245L, 0x5C2147EA6177B4B1L, 0x5DA1AB70CF091CE8L, 0xAC907FCE72B8BDFFL, + 0x57C85DFD972278A8L, 0xA4E44C6A6B6F940DL, 0x3851995B4F1FDFE4L, 0x62578CCAED71BC9EL, + 0xD9882BB0C01D2C0AL, 0x917B9D5D113C503BL, 0xA2C31E11A87643C6L, 0xE463C923A399C1CEL, + 0xF71686C57EA876DCL, 0x87B4A973E096D509L, 0xAF0D567D9D3A5814L, 0xB40C2A3F59DCC6F4L, + 0x3602F88495D121DDL, 0xD3E1DD3D9836484AL, 0xF945E71AA46688E5L, 0x7518547EB2A591F5L, + 0x9366587450C01D89L, 0x9EA81018658C065BL, 0x4F54080CBC4603A3L, 0x2D0384C65137BF3DL, + 0xDC325078EC861E2AL, 0xEA30A8FC79573FF7L, 0x214D2030CA050CB6L, 0x65F0322B8016C30CL, + 0x69BE96DD1B247087L, 0xDB95EE9981E161B8L, 0xD1FC1814D9CA05F8L, 0x820ED2BBCC0DE729L, + 0x63D76050430F14C7L, 0x3BCCB0E8A09D3A0FL, 0x8E40764D573F54A2L, 0x39D175C1E16177BDL, + 0x12F5A37C734F1F4BL, 0xAB37C12F1FDFC26DL, 0x5648B167395CD0F1L, 0x6C04ED1537BF42A7L, + 0xED97161D14304065L, 0x7D6C67DAAB72B807L, 0xEC17FA87BA4EE83CL, 0xDFAF79CB0304FBC1L, + 0x733F060571BC463EL, 0x78D61C1287E98A27L, 0xD07CF48E77B4ADA1L, 0xB9C262536C90DD26L, + 0xE2449B5860801605L, 0x8FC09AD7F941FCFBL, 0xFAD8CEA94BE46D0EL, 0xA343F28B0608EB9FL, + 0x9B126BD04917347BL, 0x9A92874AE7699C22L, 0x1B017C42C4E69EE0L, 0x3A4C5C720EE39256L, + 0x4B6E9F5E3EA399DAL, 0x6BA353F45AD83D35L, 0xE7FEE0904C1B2425L, 0x22D009832587E95DL, + 0x842980C00F1430E2L, 0xC6B3C0A0861E2893L, 0x087433A419D729F2L, 0x341F3DADD42D6C6FL, + 0xEE0A3FAEFBB2A58EL, 0x4AEE73C490DD3183L, 0xAAB72DB5B1A16A34L, 0xA92A04065E238FDFL, + 0x7B4B35A1686B6FCCL, 0x6A23BF6EF4A6956CL, 0x191CB96B851AD352L, 0x55D598D4D6DE351AL, + 0xC9604DE5F2AE7EF3L, 0x1CA6C2A3A981E172L, 0xDE2F9551AD7A5398L, 0x3025AAFF56C8F616L, + 0x15521D9D1E2860D9L, 0x506FE31CFA45073AL, 0x189C55F12B647B0BL, 0x0180EC9AAE7EA859L, + 0x7CEC8B40050C105EL, 0x2350E5198BF94104L, 0xEF8AD33455CC0DD7L, 0x07A7BEE16D677F92L, + 0xE5E325B90DE76997L, 0x5A061591A26E637AL, 0xB611EF1618208B46L, 0x09F4DF3EB7A981ABL, + 0x1EBB078AE87DACC0L, 0xB791038CB65E231FL, 0x0FD38D4574B05660L, 0x67EDF702C1EA8EBEL, + 0xBA5F4BE0831238CDL, 0xE3C477C2CEFEBE5CL, 0x0DCE486C354C1BD2L, 0x8C5DB36416C31910L, + 0x26EA9ED1A7627324L, 0x039D29B3EF82E5EBL, 0x9F28FC82CBF2AE02L, 0xA8AAE89CF05D2786L, + 0x431AACFA2774B028L, 0xCF471F9E31B7A938L, 0x581BD0B8E3922EC8L, 0xBC78199B400BEF06L, + 0x90FB71C7BF42F862L, 0x1F3BEB1046030499L, 0x683E7A47B55AD8DEL, 0x988F4263A695D190L, + 0xD808C72A6E638453L, 0x0627527BC319D7CBL, 0xEBB04466D72997AEL, 0xE67E0C0AE2658C7CL, + 0x14D2F107B056C880L, 0x7122C32C30400B8CL, 0x8A7AE11FD5DACEDBL, 0xA0DEDB38E98A0E74L, + 0xAD109354DCC615A6L, 0x0BE91A17F655CC19L, 0x8DDD5FFEB8BDB149L, 0xBFE53028AF890AEDL, + 0xD65BA6F5B4AD7A6AL, 0x7956F0882997227EL, 0x10E8665532B352F9L, 0x0E5361DFDACEFE39L, + 0xCEC7F3049FC90161L, 0xFF62B561677F5F2EL, 0x975CCF26D22587F0L, 0x51EF0F86543BAF63L, + 0x2F1E41EF10CBF28FL, 0x52722635BBB94A88L, 0xAE8DBAE73344F04DL, 0x410769D36688FD9AL, + 0xB3AB94DE34BBB966L, 0x801317928DF1AA9BL, 0xA564A0F0C5113C54L, 0xF131D4BEBDB1A117L, + 0x7F71A2F3EA8EF5B5L, 0x40878549C8F655C3L, 0x7EF14E6944F05DECL, 0xD44663DCF55137D8L, + 0xF2ACFD0D523344FCL, 0x0000000000000000L, 0x5FBC6E598EF5515AL, 0x16CF342EF1AA8532L, + 0xB036BD6DDB395C8DL, 0x13754FE6DD31B712L, 0xBBDFA77A2D6C9094L, 0x89E7C8AC3A582B30L, + 0x3C6B0E09CDFA459DL, 0xC4AE0589C7E26521L, 0x49735A777F5FD468L, 0xCAFD64561D2C9B18L, + 0xDA1502032F9FC9E1L, 0x8867243694268369L, 0x3782141E3BAF8984L, 0x9CB5D53124704BE9L, + 0xD7DB4A6F1AD3D233L, 0xA6F989432A93D9BFL, 0x9D3539AB8A0EE3B0L, 0x53F2CAAF15C7E2D1L, + 0x6E19283C76430F15L, 0x3DEBE2936384EDC4L, 0x5E3C82C3208BF903L, 0x33B8834CB94A13FDL, + 0x6470DEB12E686B55L, 0x359FD1377A53C436L, 0x61CAA57902F35975L, 0x043A975282E59A79L, + 0xFD7F70482683129CL, 0xC52EE913699CCD78L, 0x28B9FF0E7DAC8D1DL, 0x5455744E78A09D43L, + 0xCB7D88CCB3523341L, 0x44BD121B4A13CFBAL, 0x4D49CD25FDBA4E11L, 0x3E76CB208C06082FL, + 0x3FF627BA2278A076L, 0xC28957F204FBB2EAL, 0x453DFE81E46D67E3L, 0x94C1E6953DA7621BL, + 0x2C83685CFF491764L, 0xF32C1197FC4DECA5L, 0x2B24D6BD922E68F6L, 0xB22B78449AC5113FL, + 0x48F3B6EDD1217C31L, 0x2E9EAD75BEB55AD6L, 0x174FD8B45FD42D6BL, 0x4ED4E4961238ABFAL, + 0x92E6B4EEFEBEB5D0L, 0x46A0D7320BEF8208L, 0x47203BA8A5912A51L, 0x24F75BF8E69E3E96L, + 0xF0B1382413CF094EL, 0xFEE259FBC901F777L, 0x276A724B091CDB7DL, 0xBDF8F501EE75475FL, + 0x599B3C224DEC8691L, 0x6D84018F99C1EAFEL, 0x7498B8E41CDB39ACL, 0xE0595E71217C5BB7L, + 0x2AA43A273C50C0AFL, 0xF50B43EC3F543B6EL, 0x838E3E2162734F70L, 0xC09492DB4507FF58L, + 0x72BFEA9FDFC2EE67L, 0x11688ACF9CCDFAA0L, 0x1A8190D86A9836B9L, 0x7ACBD93BC615C795L, + 0xC7332C3A286080CAL, 0x863445E94EE87D50L, 0xF6966A5FD0D6DE85L, 0xE9AD814F96D5DA1CL, + 0x70A22FB69E3EA3D5L, 0x0A69F68D582B6440L, 0xB8428EC9C2EE757FL, 0x604A49E3AC8DF12CL, + 0x5B86F90B0C10CB23L, 0xE1D9B2EB8F02F3EEL, 0x29391394D3D22544L, 0xC8E0A17F5CD0D6AAL, + 0xB58CC6A5F7A26EADL, 0x8193FB08238F02C2L, 0xD5C68F465B2F9F81L, 0xFCFF9CD288FDBAC5L, + 0x77059157F359DC47L, 0x1D262E3907FF492BL, 0xFB582233E59AC557L, 0xDDB2BCE242F8B673L, + 0x2577B76248E096CFL, 0x6F99C4A6D83DA74CL, 0xC1147E41EB795701L, 0xF48BAF76912A9337L + }, + new ulong[] { + 0x3EF29D249B2C0A19L, 0xE9E16322B6F8622FL, 0x5536994047757F7AL, 0x9F4D56D5A47B0B33L, + 0x822567466AA1174CL, 0xB8F5057DEB082FB2L, 0xCC48C10BF4475F53L, 0x373088D4275DEC3AL, + 0x968F4325180AED10L, 0x173D232CF7016151L, 0xAE4ED09F946FCC13L, 0xFD4B4741C4539873L, + 0x1B5B3F0DD9933765L, 0x2FFCB0967B644052L, 0xE02376D20A89840CL, 0xA3AE3A70329B18D7L, + 0x419CBD2335DE8526L, 0xFAFEBF115B7C3199L, 0x0397074F85AA9B0DL, 0xC58AD4FB4836B970L, + 0xBEC60BE3FC4104A8L, 0x1EFF36DC4B708772L, 0x131FDC33ED8453B6L, 0x0844E33E341764D3L, + 0x0FF11B6EAB38CD39L, 0x64351F0A7761B85AL, 0x3B5694F509CFBA0EL, 0x30857084B87245D0L, + 0x47AFB3BD2297AE3CL, 0xF2BA5C2F6F6B554AL, 0x74BDC4761F4F70E1L, 0xCFDFC64471EDC45EL, + 0xE610784C1DC0AF16L, 0x7ACA29D63C113F28L, 0x2DED411776A859AFL, 0xAC5F211E99A3D5EEL, + 0xD484F949A87EF33BL, 0x3CE36CA596E013E4L, 0xD120F0983A9D432CL, 0x6BC40464DC597563L, + 0x69D5F5E5D1956C9EL, 0x9AE95F043698BB24L, 0xC9ECC8DA66A4EF44L, 0xD69508C8A5B2EAC6L, + 0xC40C2235C0503B80L, 0x38C193BA8C652103L, 0x1CEEC75D46BC9E8FL, 0xD331011937515AD1L, + 0xD8E2E56886ECA50FL, 0xB137108D5779C991L, 0x709F3B6905CA4206L, 0x4FEB50831680CAEFL, + 0xEC456AF3241BD238L, 0x58D673AFE181ABBEL, 0x242F54E7CAD9BF8CL, 0x0211F1810DCC19FDL, + 0x90BC4DBB0F43C60AL, 0x9518446A9DA0761DL, 0xA1BFCBF13F57012AL, 0x2BDE4F8961E172B5L, + 0x27B853A84F732481L, 0xB0B1E643DF1F4B61L, 0x18CC38425C39AC68L, 0xD2B7F7D7BF37D821L, + 0x3103864A3014C720L, 0x14AA246372ABFA5CL, 0x6E600DB54EBAC574L, 0x394765740403A3F3L, + 0x09C215F0BC71E623L, 0x2A58B947E987F045L, 0x7B4CDF18B477BDD8L, 0x9709B5EB906C6FE0L, + 0x73083C268060D90BL, 0xFEDC400E41F9037EL, 0x284948C6E44BE9B8L, 0x728ECAE808065BFBL, + 0x06330E9E17492B1AL, 0x5950856169E7294EL, 0xBAE4F4FCE6C4364FL, 0xCA7BCF95E30E7449L, + 0x7D7FD186A33E96C2L, 0x52836110D85AD690L, 0x4DFAA1021B4CD312L, 0x913ABB75872544FAL, + 0xDD46ECB9140F1518L, 0x3D659A6B1E869114L, 0xC23F2CABD719109AL, 0xD713FE062DD46836L, + 0xD0A60656B2FBC1DCL, 0x221C5A79DD909496L, 0xEFD26DBCA1B14935L, 0x0E77EDA0235E4FC9L, + 0xCBFD395B6B68F6B9L, 0x0DE0EAEFA6F4D4C4L, 0x0422FF1F1A8532E7L, 0xF969B85EDED6AA94L, + 0x7F6E2007AEF28F3FL, 0x3AD0623B81A938FEL, 0x6624EE8B7AADA1A7L, 0xB682E8DDC856607BL, + 0xA78CC56F281E2A30L, 0xC79B257A45FAA08DL, 0x5B4174E0642B30B3L, 0x5F638BFF7EAE0254L, + 0x4BC9AF9C0C05F808L, 0xCE59308AF98B46AEL, 0x8FC58DA9CC55C388L, 0x803496C7676D0EB1L, + 0xF33CAAE1E70DD7BAL, 0xBB6202326EA2B4BFL, 0xD5020F87201871CBL, 0x9D5CA754A9B712CEL, + 0x841669D87DE83C56L, 0x8A6184785EB6739FL, 0x420BBA6CB0741E2BL, 0xF12D5B60EAC1CE47L, + 0x76AC35F71283691CL, 0x2C6BB7D9FECEDB5FL, 0xFCCDB18F4C351A83L, 0x1F79C012C3160582L, + 0xF0ABADAE62A74CB7L, 0xE1A5801C82EF06FCL, 0x67A21845F2CB2357L, 0x5114665F5DF04D9DL, + 0xBF40FD2D74278658L, 0xA0393D3FB73183DAL, 0x05A409D192E3B017L, 0xA9FB28CF0B4065F9L, + 0x25A9A22942BF3D7CL, 0xDB75E22703463E02L, 0xB326E10C5AB5D06CL, 0xE7968E8295A62DE6L, + 0xB973F3B3636EAD42L, 0xDF571D3819C30CE5L, 0xEE549B7229D7CBC5L, 0x12992AFD65E2D146L, + 0xF8EF4E9056B02864L, 0xB7041E134030E28BL, 0xC02EDD2ADAD50967L, 0x932B4AF48AE95D07L, + 0x6FE6FB7BC6DC4784L, 0x239AACB755F61666L, 0x401A4BEDBDB807D6L, 0x485EA8D389AF6305L, + 0xA41BC220ADB4B13DL, 0x753B32B89729F211L, 0x997E584BB3322029L, 0x1D683193CEDA1C7FL, + 0xFF5AB6C0C99F818EL, 0x16BBD5E27F67E3A1L, 0xA59D34EE25D233CDL, 0x98F8AE853B54A2D9L, + 0x6DF70AFACB105E79L, 0x795D2E99B9BBA425L, 0x8E437B6744334178L, 0x0186F6CE886682F0L, + 0xEBF092A3BB347BD2L, 0xBCD7FA62F18D1D55L, 0xADD9D7D011C5571EL, 0x0BD3E471B1BDFFDEL, + 0xAA6C2F808EEAFEF4L, 0x5EE57D31F6C880A4L, 0xF50FA47FF044FCA0L, 0x1ADDC9C351F5B595L, + 0xEA76646D3352F922L, 0x0000000000000000L, 0x85909F16F58EBEA6L, 0x46294573AAF12CCCL, + 0x0A5512BF39DB7D2EL, 0x78DBD85731DD26D5L, 0x29CFBE086C2D6B48L, 0x218B5D36583A0F9BL, + 0x152CD2ADFACD78ACL, 0x83A39188E2C795BCL, 0xC3B9DA655F7F926AL, 0x9ECBA01B2C1D89C3L, + 0x07B5F8509F2FA9EAL, 0x7EE8D6C926940DCFL, 0x36B67E1AAF3B6ECAL, 0x86079859702425ABL, + 0xFB7849DFD31AB369L, 0x4C7C57CC932A51E2L, 0xD96413A60E8A27FFL, 0x263EA566C715A671L, + 0x6C71FC344376DC89L, 0x4A4F595284637AF8L, 0xDAF314E98B20BCF2L, 0x572768C14AB96687L, + 0x1088DB7C682EC8BBL, 0x887075F9537A6A62L, 0x2E7A4658F302C2A2L, 0x619116DBE582084DL, + 0xA87DDE018326E709L, 0xDCC01A779C6997E8L, 0xEDC39C3DAC7D50C8L, 0xA60A33A1A078A8C0L, + 0xC1A82BE452B38B97L, 0x3F746BEA134A88E9L, 0xA228CCBEBAFD9A27L, 0xABEAD94E068C7C04L, + 0xF48952B178227E50L, 0x5CF48CB0FB049959L, 0x6017E0156DE48ABDL, 0x4438B4F2A73D3531L, + 0x8C528AE649FF5885L, 0xB515EF924DFCFB76L, 0x0C661C212E925634L, 0xB493195CC59A7986L, + 0x9CDA519A21D1903EL, 0x32948105B5BE5C2DL, 0x194ACE8CD45F2E98L, 0x438D4CA238129CDBL, + 0x9B6FA9CABEFE39D4L, 0x81B26009EF0B8C41L, 0xDED1EBF691A58E15L, 0x4E6DA64D9EE6481FL, + 0x54B06F8ECF13FD8AL, 0x49D85E1D01C9E1F5L, 0xAFC826511C094EE3L, 0xF698A33075EE67ADL, + 0x5AC7822EEC4DB243L, 0x8DD47C28C199DA75L, 0x89F68337DB1CE892L, 0xCDCE37C57C21DDA3L, + 0x530597DE503C5460L, 0x6A42F2AA543FF793L, 0x5D727A7E73621BA9L, 0xE232875307459DF1L, + 0x56A19E0FC2DFE477L, 0xC61DD3B4CD9C227DL, 0xE5877F03986A341BL, 0x949EB2A415C6F4EDL, + 0x6206119460289340L, 0x6380E75AE84E11B0L, 0x8BE772B6D6D0F16FL, 0x50929091D596CF6DL, + 0xE86795EC3E9EE0DFL, 0x7CF927482B581432L, 0xC86A3E14EEC26DB4L, 0x7119CDA78DACC0F6L, + 0xE40189CD100CB6EBL, 0x92ADBC3A028FDFF7L, 0xB2A017C2D2D3529CL, 0x200DABF8D05C8D6BL, + 0x34A78F9BA2F77737L, 0xE3B4719D8F231F01L, 0x45BE423C2F5BB7C1L, 0xF71E55FEFD88E55DL, + 0x6853032B59F3EE6EL, 0x65B3E9C4FF073AAAL, 0x772AC3399AE5EBECL, 0x87816E97F842A75BL, + 0x110E2DB2E0484A4BL, 0x331277CB3DD8DEDDL, 0xBD510CAC79EB9FA5L, 0x352179552A91F5C7L + }, + new ulong[] { + 0x8AB0A96846E06A6DL, 0x43C7E80B4BF0B33AL, 0x08C9B3546B161EE5L, 0x39F1C235EBA990BEL, + 0xC1BEF2376606C7B2L, 0x2C209233614569AAL, 0xEB01523B6FC3289AL, 0x946953AB935ACEDDL, + 0x272838F63E13340EL, 0x8B0455ECA12BA052L, 0x77A1B2C4978FF8A2L, 0xA55122CA13E54086L, + 0x2276135862D3F1CDL, 0xDB8DDFDE08B76CFEL, 0x5D1E12C89E4A178AL, 0x0E56816B03969867L, + 0xEE5F79953303ED59L, 0xAFED748BAB78D71DL, 0x6D929F2DF93E53EEL, 0xF5D8A8F8BA798C2AL, + 0xF619B1698E39CF6BL, 0x95DDAF2F749104E2L, 0xEC2A9C80E0886427L, 0xCE5C8FD8825B95EAL, + 0xC4E0D9993AC60271L, 0x4699C3A5173076F9L, 0x3D1B151F50A29F42L, 0x9ED505EA2BC75946L, + 0x34665ACFDC7F4B98L, 0x61B1FB53292342F7L, 0xC721C0080E864130L, 0x8693CD1696FD7B74L, + 0x872731927136B14BL, 0xD3446C8A63A1721BL, 0x669A35E8A6680E4AL, 0xCAB658F239509A16L, + 0xA4E5DE4EF42E8AB9L, 0x37A7435EE83F08D9L, 0x134E6239E26C7F96L, 0x82791A3C2DF67488L, + 0x3F6EF00A8329163CL, 0x8E5A7E42FDEB6591L, 0x5CAAEE4C7981DDB5L, 0x19F234785AF1E80DL, + 0x255DDDE3ED98BD70L, 0x50898A32A99CCCACL, 0x28CA4519DA4E6656L, 0xAE59880F4CB31D22L, + 0x0D9798FA37D6DB26L, 0x32F968F0B4FFCD1AL, 0xA00F09644F258545L, 0xFA3AD5175E24DE72L, + 0xF46C547C5DB24615L, 0x713E80FBFF0F7E20L, 0x7843CF2B73D2AAFAL, 0xBD17EA36AEDF62B4L, + 0xFD111BACD16F92CFL, 0x4ABAA7DBC72D67E0L, 0xB3416B5DAD49FAD3L, 0xBCA316B24914A88BL, + 0x15D150068AECF914L, 0xE27C1DEBE31EFC40L, 0x4FE48C759BEDA223L, 0x7EDCFD141B522C78L, + 0x4E5070F17C26681CL, 0xE696CAC15815F3BCL, 0x35D2A64B3BB481A7L, 0x800CFF29FE7DFDF6L, + 0x1ED9FAC3D5BAA4B0L, 0x6C2663A91EF599D1L, 0x03C1199134404341L, 0xF7AD4DED69F20554L, + 0xCD9D9649B61BD6ABL, 0xC8C3BDE7EADB1368L, 0xD131899FB02AFB65L, 0x1D18E352E1FAE7F1L, + 0xDA39235AEF7CA6C1L, 0xA1BBF5E0A8EE4F7AL, 0x91377805CF9A0B1EL, 0x3138716180BF8E5BL, + 0xD9F83ACBDB3CE580L, 0x0275E515D38B897EL, 0x472D3F21F0FBBCC6L, 0x2D946EB7868EA395L, + 0xBA3C248D21942E09L, 0xE7223645BFDE3983L, 0xFF64FEB902E41BB1L, 0xC97741630D10D957L, + 0xC3CB1722B58D4ECCL, 0xA27AEC719CAE0C3BL, 0x99FECB51A48C15FBL, 0x1465AC826D27332BL, + 0xE1BD047AD75EBF01L, 0x79F733AF941960C5L, 0x672EC96C41A3C475L, 0xC27FEBA6524684F3L, + 0x64EFD0FD75E38734L, 0xED9E60040743AE18L, 0xFB8E2993B9EF144DL, 0x38453EB10C625A81L, + 0x6978480742355C12L, 0x48CF42CE14A6EE9EL, 0x1CAC1FD606312DCEL, 0x7B82D6BA4792E9BBL, + 0x9D141C7B1F871A07L, 0x5616B80DC11C4A2EL, 0xB849C198F21FA777L, 0x7CA91801C8D9A506L, + 0xB1348E487EC273ADL, 0x41B20D1E987B3A44L, 0x7460AB55A3CFBBE3L, 0x84E628034576F20AL, + 0x1B87D16D897A6173L, 0x0FE27DEFE45D5258L, 0x83CDE6B8CA3DBEB7L, 0x0C23647ED01D1119L, + 0x7A362A3EA0592384L, 0xB61F40F3F1893F10L, 0x75D457D1440471DCL, 0x4558DA34237035B8L, + 0xDCA6116587FC2043L, 0x8D9B67D3C9AB26D0L, 0x2B0B5C88EE0E2517L, 0x6FE77A382AB5DA90L, + 0x269CC472D9D8FE31L, 0x63C41E46FAA8CB89L, 0xB7ABBC771642F52FL, 0x7D1DE4852F126F39L, + 0xA8C6BA3024339BA0L, 0x600507D7CEE888C8L, 0x8FEE82C61A20AFAEL, 0x57A2448926D78011L, + 0xFCA5E72836A458F0L, 0x072BCEBB8F4B4CBDL, 0x497BBE4AF36D24A1L, 0x3CAFE99BB769557DL, + 0x12FA9EBD05A7B5A9L, 0xE8C04BAA5B836BDBL, 0x4273148FAC3B7905L, 0x908384812851C121L, + 0xE557D3506C55B0FDL, 0x72FF996ACB4F3D61L, 0x3EDA0C8E64E2DC03L, 0xF0868356E6B949E9L, + 0x04EAD72ABB0B0FFCL, 0x17A4B5135967706AL, 0xE3C8E16F04D5367FL, 0xF84F30028DAF570CL, + 0x1846C8FCBD3A2232L, 0x5B8120F7F6CA9108L, 0xD46FA231ECEA3EA6L, 0x334D947453340725L, + 0x58403966C28AD249L, 0xBED6F3A79A9F21F5L, 0x68CCB483A5FE962DL, 0xD085751B57E1315AL, + 0xFED0023DE52FD18EL, 0x4B0E5B5F20E6ADDFL, 0x1A332DE96EB1AB4CL, 0xA3CE10F57B65C604L, + 0x108F7BA8D62C3CD7L, 0xAB07A3A11073D8E1L, 0x6B0DAD1291BED56CL, 0xF2F366433532C097L, + 0x2E557726B2CEE0D4L, 0x0000000000000000L, 0xCB02A476DE9B5029L, 0xE4E32FD48B9E7AC2L, + 0x734B65EE2C84F75EL, 0x6E5386BCCD7E10AFL, 0x01B4FC84E7CBCA3FL, 0xCFE8735C65905FD5L, + 0x3613BFDA0FF4C2E6L, 0x113B872C31E7F6E8L, 0x2FE18BA255052AEBL, 0xE974B72EBC48A1E4L, + 0x0ABC5641B89D979BL, 0xB46AA5E62202B66EL, 0x44EC26B0C4BBFF87L, 0xA6903B5B27A503C7L, + 0x7F680190FC99E647L, 0x97A84A3AA71A8D9CL, 0xDD12EDE16037EA7CL, 0xC554251DDD0DC84EL, + 0x88C54C7D956BE313L, 0x4D91696048662B5DL, 0xB08072CC9909B992L, 0xB5DE5962C5C97C51L, + 0x81B803AD19B637C9L, 0xB2F597D94A8230ECL, 0x0B08AAC55F565DA4L, 0xF1327FD2017283D6L, + 0xAD98919E78F35E63L, 0x6AB9519676751F53L, 0x24E921670A53774FL, 0xB9FD3D1C15D46D48L, + 0x92F66194FBDA485FL, 0x5A35DC7311015B37L, 0xDED3F4705477A93DL, 0xC00A0EB381CD0D8DL, + 0xBB88D809C65FE436L, 0x16104997BEACBA55L, 0x21B70AC95693B28CL, 0x59F4C5E225411876L, + 0xD5DB5EB50B21F499L, 0x55D7A19CF55C096FL, 0xA97246B4C3F8519FL, 0x8552D487A2BD3835L, + 0x54635D181297C350L, 0x23C2EFDC85183BF2L, 0x9F61F96ECC0C9379L, 0x534893A39DDC8FEDL, + 0x5EDF0B59AA0A54CBL, 0xAC2C6D1A9F38945CL, 0xD7AEBBA0D8AA7DE7L, 0x2ABFA00C09C5EF28L, + 0xD84CC64F3CF72FBFL, 0x2003F64DB15878B3L, 0xA724C7DFC06EC9F8L, 0x069F323F68808682L, + 0xCC296ACD51D01C94L, 0x055E2BAE5CC0C5C3L, 0x6270E2C21D6301B6L, 0x3B842720382219C0L, + 0xD2F0900E846AB824L, 0x52FC6F277A1745D2L, 0xC6953C8CE94D8B0FL, 0xE009F8FE3095753EL, + 0x655B2C7992284D0BL, 0x984A37D54347DFC4L, 0xEAB5AEBF8808E2A5L, 0x9A3FD2C090CC56BAL, + 0x9CA0E0FFF84CD038L, 0x4C2595E4AFADE162L, 0xDF6708F4B3BC6302L, 0xBF620F237D54EBCAL, + 0x93429D101C118260L, 0x097D4FD08CDDD4DAL, 0x8C2F9B572E60ECEFL, 0x708A7C7F18C4B41FL, + 0x3A30DBA4DFE9D3FFL, 0x4006F19A7FB0F07BL, 0x5F6BF7DD4DC19EF4L, 0x1F6D064732716E8FL, + 0xF9FBCC866A649D33L, 0x308C8DE567744464L, 0x8971B0F972A0292CL, 0xD61A47243F61B7D8L, + 0xEFEB8511D4C82766L, 0x961CB6BE40D147A3L, 0xAAB35F25F7B812DEL, 0x76154E407044329DL, + 0x513D76B64E570693L, 0xF3479AC7D2F90AA8L, 0x9B8B2E4477079C85L, 0x297EB99D3D85AC69L + }, + new ulong[] { + 0x7E37E62DFC7D40C3L, 0x776F25A4EE939E5BL, 0xE045C850DD8FB5ADL, 0x86ED5BA711FF1952L, + 0xE91D0BD9CF616B35L, 0x37E0AB256E408FFBL, 0x9607F6C031025A7AL, 0x0B02F5E116D23C9DL, + 0xF3D8486BFB50650CL, 0x621CFF27C40875F5L, 0x7D40CB71FA5FD34AL, 0x6DAA6616DAA29062L, + 0x9F5F354923EC84E2L, 0xEC847C3DC507C3B3L, 0x025A3668043CE205L, 0xA8BF9E6C4DAC0B19L, + 0xFA808BE2E9BEBB94L, 0xB5B99C5277C74FA3L, 0x78D9BC95F0397BCCL, 0xE332E50CDBAD2624L, + 0xC74FCE129332797EL, 0x1729ECEB2EA709ABL, 0xC2D6B9F69954D1F8L, 0x5D898CBFBAB8551AL, + 0x859A76FB17DD8ADBL, 0x1BE85886362F7FB5L, 0xF6413F8FF136CD8AL, 0xD3110FA5BBB7E35CL, + 0x0A2FEED514CC4D11L, 0xE83010EDCD7F1AB9L, 0xA1E75DE55F42D581L, 0xEEDE4A55C13B21B6L, + 0xF2F5535FF94E1480L, 0x0CC1B46D1888761EL, 0xBCE15FDB6529913BL, 0x2D25E8975A7181C2L, + 0x71817F1CE2D7A554L, 0x2E52C5CB5C53124BL, 0xF9F7A6BEEF9C281DL, 0x9E722E7D21F2F56EL, + 0xCE170D9B81DCA7E6L, 0x0E9B82051CB4941BL, 0x1E712F623C49D733L, 0x21E45CFA42F9F7DCL, + 0xCB8E7A7F8BBA0F60L, 0x8E98831A010FB646L, 0x474CCF0D8E895B23L, 0xA99285584FB27A95L, + 0x8CC2B57205335443L, 0x42D5B8E984EFF3A5L, 0x012D1B34021E718CL, 0x57A6626AAE74180BL, + 0xFF19FC06E3D81312L, 0x35BA9D4D6A7C6DFEL, 0xC9D44C178F86ED65L, 0x506523E6A02E5288L, + 0x03772D5C06229389L, 0x8B01F4FE0B691EC0L, 0xF8DABD8AED825991L, 0x4C4E3AEC985B67BEL, + 0xB10DF0827FBF96A9L, 0x6A69279AD4F8DAE1L, 0xE78689DCD3D5FF2EL, 0x812E1A2B1FA553D1L, + 0xFBAD90D6EBA0CA18L, 0x1AC543B234310E39L, 0x1604F7DF2CB97827L, 0xA6241C6951189F02L, + 0x753513CCEAAF7C5EL, 0x64F2A59FC84C4EFAL, 0x247D2B1E489F5F5AL, 0xDB64D718AB474C48L, + 0x79F4A7A1F2270A40L, 0x1573DA832A9BEBAEL, 0x3497867968621C72L, 0x514838D2A2302304L, + 0xF0AF6537FD72F685L, 0x1D06023E3A6B44BAL, 0x678588C3CE6EDD73L, 0x66A893F7CC70ACFFL, + 0xD4D24E29B5EDA9DFL, 0x3856321470EA6A6CL, 0x07C3418C0E5A4A83L, 0x2BCBB22F5635BACDL, + 0x04B46CD00878D90AL, 0x06EE5AB80C443B0FL, 0x3B211F4876C8F9E5L, 0x0958C38912EEDE98L, + 0xD14B39CDBF8B0159L, 0x397B292072F41BE0L, 0x87C0409313E168DEL, 0xAD26E98847CAA39FL, + 0x4E140C849C6785BBL, 0xD5FF551DB7F3D853L, 0xA0CA46D15D5CA40DL, 0xCD6020C787FE346FL, + 0x84B76DCF15C3FB57L, 0xDEFDA0FCA121E4CEL, 0x4B8D7B6096012D3DL, 0x9AC642AD298A2C64L, + 0x0875D8BD10F0AF14L, 0xB357C6EA7B8374ACL, 0x4D6321D89A451632L, 0xEDA96709C719B23FL, + 0xF76C24BBF328BC06L, 0xC662D526912C08F2L, 0x3CE25EC47892B366L, 0xB978283F6F4F39BDL, + 0xC08C8F9E9D6833FDL, 0x4F3917B09E79F437L, 0x593DE06FB2C08C10L, 0xD6887841B1D14BDAL, + 0x19B26EEE32139DB0L, 0xB494876675D93E2FL, 0x825937771987C058L, 0x90E9AC783D466175L, + 0xF1827E03FF6C8709L, 0x945DC0A8353EB87FL, 0x4516F9658AB5B926L, 0x3F9573987EB020EFL, + 0xB855330B6D514831L, 0x2AE6A91B542BCB41L, 0x6331E413C6160479L, 0x408F8E8180D311A0L, + 0xEFF35161C325503AL, 0xD06622F9BD9570D5L, 0x8876D9A20D4B8D49L, 0xA5533135573A0C8BL, + 0xE168D364DF91C421L, 0xF41B09E7F50A2F8FL, 0x12B09B0F24C1A12DL, 0xDA49CC2CA9593DC4L, + 0x1F5C34563E57A6BFL, 0x54D14F36A8568B82L, 0xAF7CDFE043F6419AL, 0xEA6A2685C943F8BCL, + 0xE5DCBFB4D7E91D2BL, 0xB27ADDDE799D0520L, 0x6B443CAED6E6AB6DL, 0x7BAE91C9F61BE845L, + 0x3EB868AC7CAE5163L, 0x11C7B65322E332A4L, 0xD23C1491B9A992D0L, 0x8FB5982E0311C7CAL, + 0x70AC6428E0C9D4D8L, 0x895BC2960F55FCC5L, 0x76423E90EC8DEFD7L, 0x6FF0507EDE9E7267L, + 0x3DCF45F07A8CC2EAL, 0x4AA06054941F5CB1L, 0x5810FB5BB0DEFD9CL, 0x5EFEA1E3BC9AC693L, + 0x6EDD4B4ADC8003EBL, 0x741808F8E8B10DD2L, 0x145EC1B728859A22L, 0x28BC9F7350172944L, + 0x270A06424EBDCCD3L, 0x972AEDF4331C2BF6L, 0x059977E40A66A886L, 0x2550302A4A812ED6L, + 0xDD8A8DA0A7037747L, 0xC515F87A970E9B7BL, 0x3023EAA9601AC578L, 0xB7E3AA3A73FBADA6L, + 0x0FB699311EAAE597L, 0x0000000000000000L, 0x310EF19D6204B4F4L, 0x229371A644DB6455L, + 0x0DECAF591A960792L, 0x5CA4978BB8A62496L, 0x1C2B190A38753536L, 0x41A295B582CD602CL, + 0x3279DCC16426277DL, 0xC1A194AA9F764271L, 0x139D803B26DFD0A1L, 0xAE51C4D441E83016L, + 0xD813FA44AD65DFC1L, 0xAC0BF2BC45D4D213L, 0x23BE6A9246C515D9L, 0x49D74D08923DCF38L, + 0x9D05032127D066E7L, 0x2F7FDEFF5E4D63C7L, 0xA47E2A0155247D07L, 0x99B16FF12FA8BFEDL, + 0x4661D4398C972AAFL, 0xDFD0BBC8A33F9542L, 0xDCA79694A51D06CBL, 0xB020EBB67DA1E725L, + 0xBA0F0563696DAA34L, 0xE4F1A480D5F76CA7L, 0xC438E34E9510EAF7L, 0x939E81243B64F2FCL, + 0x8DEFAE46072D25CFL, 0x2C08F3A3586FF04EL, 0xD7A56375B3CF3A56L, 0x20C947CE40E78650L, + 0x43F8A3DD86F18229L, 0x568B795EAC6A6987L, 0x8003011F1DBB225DL, 0xF53612D3F7145E03L, + 0x189F75DA300DEC3CL, 0x9570DB9C3720C9F3L, 0xBB221E576B73DBB8L, 0x72F65240E4F536DDL, + 0x443BE25188ABC8AAL, 0xE21FFE38D9B357A8L, 0xFD43CA6EE7E4F117L, 0xCAA3614B89A47EECL, + 0xFE34E732E1C6629EL, 0x83742C431B99B1D4L, 0xCF3A16AF83C2D66AL, 0xAAE5A8044990E91CL, + 0x26271D764CA3BD5FL, 0x91C4B74C3F5810F9L, 0x7C6DD045F841A2C6L, 0x7F1AFD19FE63314FL, + 0xC8F957238D989CE9L, 0xA709075D5306EE8EL, 0x55FC5402AA48FA0EL, 0x48FA563C9023BEB4L, + 0x65DFBEABCA523F76L, 0x6C877D22D8BCE1EEL, 0xCC4D3BF385E045E3L, 0xBEBB69B36115733EL, + 0x10EAAD6720FD4328L, 0xB6CEB10E71E5DC2AL, 0xBDCC44EF6737E0B7L, 0x523F158EA412B08DL, + 0x989C74C52DB6CE61L, 0x9BEB59992B945DE8L, 0x8A2CEFCA09776F4CL, 0xA3BD6B8D5B7E3784L, + 0xEB473DB1CB5D8930L, 0xC3FBA2C29B4AA074L, 0x9C28181525CE176BL, 0x683311F2D0C438E4L, + 0x5FD3BAD7BE84B71FL, 0xFC6ED15AE5FA809BL, 0x36CDB0116C5EFE77L, 0x29918447520958C8L, + 0xA29070B959604608L, 0x53120EBAA60CC101L, 0x3A0C047C74D68869L, 0x691E0AC6D2DA4968L, + 0x73DB4974E6EB4751L, 0x7A838AFDF40599C9L, 0x5A4ACD33B4E21F99L, 0x6046C94FC03497F0L, + 0xE6AB92E8D1CB8EA2L, 0x3354C7F5663856F1L, 0xD93EE170AF7BAE4DL, 0x616BD27BC22AE67CL, + 0x92B39A10397A8370L, 0xABC8B3304B8E9890L, 0xBF967287630B02B2L, 0x5B67D607B6FC6E15L + }, + new ulong[] { + 0xD031C397CE553FE6L, 0x16BA5B01B006B525L, 0xA89BADE6296E70C8L, 0x6A1F525D77D3435BL, + 0x6E103570573DFA0BL, 0x660EFB2A17FC95ABL, 0x76327A9E97634BF6L, 0x4BAD9D6462458BF5L, + 0xF1830CAEDBC3F748L, 0xC5C8F542669131FFL, 0x95044A1CDC48B0CBL, 0x892962DF3CF8B866L, + 0xB0B9E208E930C135L, 0xA14FB3F0611A767CL, 0x8D2605F21C160136L, 0xD6B71922FECC549EL, + 0x37089438A5907D8BL, 0x0B5DA38E5803D49CL, 0x5A5BCC9CEA6F3CBCL, 0xEDAE246D3B73FFE5L, + 0xD2B87E0FDE22EDCEL, 0x5E54ABB1CA8185ECL, 0x1DE7F88FE80561B9L, 0xAD5E1A870135A08CL, + 0x2F2ADBD665CECC76L, 0x5780B5A782F58358L, 0x3EDC8A2EEDE47B3FL, 0xC9D95C3506BEE70FL, + 0x83BE111D6C4E05EEL, 0xA603B90959367410L, 0x103C81B4809FDE5DL, 0x2C69B6027D0C774AL, + 0x399080D7D5C87953L, 0x09D41E16487406B4L, 0xCDD63B1826505E5FL, 0xF99DC2F49B0298E8L, + 0x9CD0540A943CB67FL, 0xBCA84B7F891F17C5L, 0x723D1DB3B78DF2A6L, 0x78AA6E71E73B4F2EL, + 0x1433E699A071670DL, 0x84F21BE454620782L, 0x98DF3327B4D20F2FL, 0xF049DCE2D3769E5CL, + 0xDB6C60199656EB7AL, 0x648746B2078B4783L, 0x32CD23598DCBADCFL, 0x1EA4955BF0C7DA85L, + 0xE9A143401B9D46B5L, 0xFD92A5D9BBEC21B8L, 0xC8138C790E0B8E1BL, 0x2EE00B9A6D7BA562L, + 0xF85712B893B7F1FCL, 0xEB28FED80BEA949DL, 0x564A65EB8A40EA4CL, 0x6C9988E8474A2823L, + 0x4535898B121D8F2DL, 0xABD8C03231ACCBF4L, 0xBA2E91CAB9867CBDL, 0x7960BE3DEF8E263AL, + 0x0C11A977602FD6F0L, 0xCB50E1AD16C93527L, 0xEAE22E94035FFD89L, 0x2866D12F5DE2CE1AL, + 0xFF1B1841AB9BF390L, 0x9F9339DE8CFE0D43L, 0x964727C8C48A0BF7L, 0x524502C6AAAE531CL, + 0x9B9C5EF3AC10B413L, 0x4FA2FA4942AB32A5L, 0x3F165A62E551122BL, 0xC74148DA76E6E3D7L, + 0x924840E5E464B2A7L, 0xD372AE43D69784DAL, 0x233B72A105E11A86L, 0xA48A04914941A638L, + 0xB4B68525C9DE7865L, 0xDDEABAACA6CF8002L, 0x0A9773C250B6BD88L, 0xC284FFBB5EBD3393L, + 0x8BA0DF472C8F6A4EL, 0x2AEF6CB74D951C32L, 0x427983722A318D41L, 0x73F7CDFFBF389BB2L, + 0x074C0AF9382C026CL, 0x8A6A0F0B243A035AL, 0x6FDAE53C5F88931FL, 0xC68B98967E538AC3L, + 0x44FF59C71AA8E639L, 0xE2FCE0CE439E9229L, 0xA20CDE2479D8CD40L, 0x19E89FA2C8EBD8E9L, + 0xF446BBCFF398270CL, 0x43B3533E2284E455L, 0xD82F0DCD8E945046L, 0x51066F12B26CE820L, + 0xE73957AF6BC5426DL, 0x081ECE5A40C16FA0L, 0x3B193D4FC5BFAB7BL, 0x7FE66488DF174D42L, + 0x0E9814EF705804D8L, 0x8137AC857C39D7C6L, 0xB1733244E185A821L, 0x695C3F896F11F867L, + 0xF6CF0657E3EFF524L, 0x1AABF276D02963D5L, 0x2DA3664E75B91E5EL, 0x0289BD981077D228L, + 0x90C1FD7DF413608FL, 0x3C5537B6FD93A917L, 0xAA12107E3919A2E0L, 0x0686DAB530996B78L, + 0xDAA6B0559EE3826EL, 0xC34E2FF756085A87L, 0x6D5358A44FFF4137L, 0xFC587595B35948ACL, + 0x7CA5095CC7D5F67EL, 0xFB147F6C8B754AC0L, 0xBFEB26AB91DDACF9L, 0x6896EFC567A49173L, + 0xCA9A31E11E7C5C33L, 0xBBE44186B13315A9L, 0x0DDB793B689ABFE4L, 0x70B4A02BA7FA208EL, + 0xE47A3A7B7307F951L, 0x8CECD5BE14A36822L, 0xEEED49B923B144D9L, 0x17708B4DB8B3DC31L, + 0x6088219F2765FED3L, 0xB3FA8FDCF1F27A09L, 0x910B2D31FCA6099BL, 0x0F52C4A378ED6DCCL, + 0x50CCBF5EBAD98134L, 0x6BD582117F662A4FL, 0x94CE9A50D4FDD9DFL, 0x2B25BCFB45207526L, + 0x67C42B661F49FCBFL, 0x492420FC723259DDL, 0x03436DD418C2BB3CL, 0x1F6E4517F872B391L, + 0xA08563BC69AF1F68L, 0xD43EA4BAEEBB86B6L, 0x01CAD04C08B56914L, 0xAC94CACB0980C998L, + 0x54C3D8739A373864L, 0x26FEC5C02DBACAC2L, 0xDEA9D778BE0D3B3EL, 0x040F672D20EEB950L, + 0xE5B0EA377BB29045L, 0xF30AB136CBB42560L, 0x62019C0737122CFBL, 0xE86B930C13282FA1L, + 0xCC1CEB542EE5374BL, 0x538FD28AA21B3A08L, 0x1B61223AD89C0AC1L, 0x36C24474AD25149FL, + 0x7A23D3E9F74C9D06L, 0xBE21F6E79968C5EDL, 0xCF5F868036278C77L, 0xF705D61BEB5A9C30L, + 0x4D2B47D152DCE08DL, 0x5F9E7BFDC234ECF8L, 0x247778583DCD18EAL, 0x867BA67C4415D5AAL, + 0x4CE1979D5A698999L, 0x0000000000000000L, 0xEC64F42133C696F1L, 0xB57C5569C16B1171L, + 0xC1C7926F467F88AFL, 0x654D96FE0F3E2E97L, 0x15F936D5A8C40E19L, 0xB8A72C52A9F1AE95L, + 0xA9517DAA21DB19DCL, 0x58D27104FA18EE94L, 0x5918A148F2AD8780L, 0x5CDD1629DAF657C4L, + 0x8274C15164FB6CFAL, 0xD1FB13DBC6E056F2L, 0x7D6FD910CF609F6AL, 0xB63F38BDD9A9AA4DL, + 0x3D9FE7FAF526C003L, 0x74BBC706871499DEL, 0xDF630734B6B8522AL, 0x3AD3ED03CD0AC26FL, + 0xFADEAF2083C023D4L, 0xC00D42234ECAE1BBL, 0x8538CBA85CD76E96L, 0xC402250E6E2458EBL, + 0x47BC3413026A5D05L, 0xAFD7A71F114272A4L, 0x978DF784CC3F62E3L, 0xB96DFC1EA144C781L, + 0x21B2CF391596C8AEL, 0x318E4E8D950916F3L, 0xCE9556CC3E92E563L, 0x385A509BDD7D1047L, + 0x358129A0B5E7AFA3L, 0xE6F387E363702B79L, 0xE0755D5653E94001L, 0x7BE903A5FFF9F412L, + 0x12B53C2C90E80C75L, 0x3307F315857EC4DBL, 0x8FAFB86A0C61D31EL, 0xD9E5DD8186213952L, + 0x77F8AAD29FD622E2L, 0x25BDA814357871FEL, 0x7571174A8FA1F0CAL, 0x137FEC60985D6561L, + 0x30449EC19DBC7FE7L, 0xA540D4DD41F4CF2CL, 0xDC206AE0AE7AE916L, 0x5B911CD0E2DA55A8L, + 0xB2305F90F947131DL, 0x344BF9ECBD52C6B7L, 0x5D17C665D2433ED0L, 0x18224FEEC05EB1FDL, + 0x9E59E992844B6457L, 0x9A568EBFA4A5DD07L, 0xA3C60E68716DA454L, 0x7E2CB4C4D7A22456L, + 0x87B176304CA0BCBEL, 0x413AEEA632F3367DL, 0x9915E36BBC67663BL, 0x40F03EEA3A465F69L, + 0x1C2D28C3E0B008ADL, 0x4E682A054A1E5BB1L, 0x05C5B761285BD044L, 0xE1BF8D1A5B5C2915L, + 0xF2C0617AC3014C74L, 0xB7F5E8F1D11CC359L, 0x63CB4C4B3FA745EFL, 0x9D1A84469C89DF6BL, + 0xE33630824B2BFB3DL, 0xD5F474F6E60EEFA2L, 0xF58C6B83FB2D4E18L, 0x4676E45F0ADF3411L, + 0x20781F751D23A1BAL, 0xBD629B3381AA7ED1L, 0xAE1D775319F71BB0L, 0xFED1C80DA32E9A84L, + 0x5509083F92825170L, 0x29AC01635557A70EL, 0xA7C9694551831D04L, 0x8E65682604D4BA0AL, + 0x11F651F8882AB749L, 0xD77DC96EF6793D8AL, 0xEF2799F52B042DCDL, 0x48EEF0B07A8730C9L, + 0x22F1A2ED0D547392L, 0x6142F1D32FD097C7L, 0x4A674D286AF0E2E1L, 0x80FD7CC9748CBED2L, + 0x717E7067AF4F499AL, 0x938290A9ECD1DBB3L, 0x88E3B293344DD172L, 0x2734158C250FA3D6L + } + }; + + + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/GOST3411_2012Digest.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/GOST3411_2012Digest.cs.meta new file mode 100644 index 0000000..75004f9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/GOST3411_2012Digest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a8883ee20b0638049bf7ddfd70db2d11 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/GOST3411_2012_256Digest.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/GOST3411_2012_256Digest.cs new file mode 100644 index 0000000..77cf6c5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/GOST3411_2012_256Digest.cs @@ -0,0 +1,54 @@ +using System; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + public class Gost3411_2012_256Digest : Gost3411_2012Digest + { + private readonly static byte[] IV = { + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 + }; + + public override string AlgorithmName + { + get { return "GOST3411-2012-256"; } + } + + public Gost3411_2012_256Digest() : base(IV) + { + + } + + public Gost3411_2012_256Digest(Gost3411_2012_256Digest other) : base(IV) + { + Reset(other); + } + + public override int GetDigestSize() + { + return 32; + } + + public override int DoFinal(byte[] output, int outOff) + { + byte[] result = new byte[64]; + base.DoFinal(result, 0); + + Array.Copy(result, 32, output, outOff, 32); + + return 32; + } + + public override IMemoable Copy() + { + return new Gost3411_2012_256Digest(this); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/GOST3411_2012_256Digest.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/GOST3411_2012_256Digest.cs.meta new file mode 100644 index 0000000..617e715 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/GOST3411_2012_256Digest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1c7dcfdc25fde7347af11027369b1d4d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/GOST3411_2012_512Digest.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/GOST3411_2012_512Digest.cs new file mode 100644 index 0000000..2b77e36 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/GOST3411_2012_512Digest.cs @@ -0,0 +1,43 @@ +using System; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + public class Gost3411_2012_512Digest:Gost3411_2012Digest + { + private readonly static byte[] IV = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + public override string AlgorithmName + { + get { return "GOST3411-2012-512"; } + } + + public Gost3411_2012_512Digest():base(IV) + { + } + + public Gost3411_2012_512Digest(Gost3411_2012_512Digest other) : base(IV) + { + Reset(other); + } + + public override int GetDigestSize() + { + return 64; + } + + public override IMemoable Copy() + { + return new Gost3411_2012_512Digest(this); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/GOST3411_2012_512Digest.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/GOST3411_2012_512Digest.cs.meta new file mode 100644 index 0000000..f0d68e9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/GOST3411_2012_512Digest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c0632db5c462dd444ae14fadb344471c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/GeneralDigest.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/GeneralDigest.cs new file mode 100644 index 0000000..d40ad28 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/GeneralDigest.cs @@ -0,0 +1,133 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /** + * base implementation of MD4 family style digest as outlined in + * "Handbook of Applied Cryptography", pages 344 - 347. + */ + public abstract class GeneralDigest + : IDigest, IMemoable + { + private const int BYTE_LENGTH = 64; + + private byte[] xBuf; + private int xBufOff; + + private long byteCount; + + internal GeneralDigest() + { + xBuf = new byte[4]; + } + + internal GeneralDigest(GeneralDigest t) + { + xBuf = new byte[t.xBuf.Length]; + CopyIn(t); + } + + protected void CopyIn(GeneralDigest t) + { + Array.Copy(t.xBuf, 0, xBuf, 0, t.xBuf.Length); + + xBufOff = t.xBufOff; + byteCount = t.byteCount; + } + + public void Update(byte input) + { + xBuf[xBufOff++] = input; + + if (xBufOff == xBuf.Length) + { + ProcessWord(xBuf, 0); + xBufOff = 0; + } + + byteCount++; + } + + public void BlockUpdate( + byte[] input, + int inOff, + int length) + { + length = System.Math.Max(0, length); + + // + // fill the current word + // + int i = 0; + if (xBufOff != 0) + { + while (i < length) + { + xBuf[xBufOff++] = input[inOff + i++]; + if (xBufOff == 4) + { + ProcessWord(xBuf, 0); + xBufOff = 0; + break; + } + } + } + + // + // process whole words. + // + int limit = ((length - i) & ~3) + i; + for (; i < limit; i += 4) + { + ProcessWord(input, inOff + i); + } + + // + // load in the remainder. + // + while (i < length) + { + xBuf[xBufOff++] = input[inOff + i++]; + } + + byteCount += length; + } + + public void Finish() + { + long bitLength = (byteCount << 3); + + // + // add the pad bytes. + // + Update((byte)128); + + while (xBufOff != 0) Update((byte)0); + ProcessLength(bitLength); + ProcessBlock(); + } + + public virtual void Reset() + { + byteCount = 0; + xBufOff = 0; + Array.Clear(xBuf, 0, xBuf.Length); + } + + public int GetByteLength() + { + return BYTE_LENGTH; + } + + internal abstract void ProcessWord(byte[] input, int inOff); + internal abstract void ProcessLength(long bitLength); + internal abstract void ProcessBlock(); + public abstract string AlgorithmName { get; } + public abstract int GetDigestSize(); + public abstract int DoFinal(byte[] output, int outOff); + public abstract IMemoable Copy(); + public abstract void Reset(IMemoable t); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/GeneralDigest.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/GeneralDigest.cs.meta new file mode 100644 index 0000000..1a08553 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/GeneralDigest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fbd668437b29c024c9d4d6d7b84461c2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/KeccakDigest.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/KeccakDigest.cs new file mode 100644 index 0000000..2da2e09 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/KeccakDigest.cs @@ -0,0 +1,414 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /// + /// Implementation of Keccak based on following KeccakNISTInterface.c from http://keccak.noekeon.org/ + /// + /// + /// Following the naming conventions used in the C source code to enable easy review of the implementation. + /// + public class KeccakDigest + : IDigest, IMemoable + { + private static readonly ulong[] KeccakRoundConstants = new ulong[]{ + 0x0000000000000001UL, 0x0000000000008082UL, 0x800000000000808aUL, 0x8000000080008000UL, + 0x000000000000808bUL, 0x0000000080000001UL, 0x8000000080008081UL, 0x8000000000008009UL, + 0x000000000000008aUL, 0x0000000000000088UL, 0x0000000080008009UL, 0x000000008000000aUL, + 0x000000008000808bUL, 0x800000000000008bUL, 0x8000000000008089UL, 0x8000000000008003UL, + 0x8000000000008002UL, 0x8000000000000080UL, 0x000000000000800aUL, 0x800000008000000aUL, + 0x8000000080008081UL, 0x8000000000008080UL, 0x0000000080000001UL, 0x8000000080008008UL + }; + + private ulong[] state = new ulong[25]; + protected byte[] dataQueue = new byte[192]; + protected int rate; + protected int bitsInQueue; + protected internal int fixedOutputLength; + protected bool squeezing; + + public KeccakDigest() + : this(288) + { + } + + public KeccakDigest(int bitLength) + { + Init(bitLength); + } + + public KeccakDigest(KeccakDigest source) + { + CopyIn(source); + } + + private void CopyIn(KeccakDigest source) + { + Array.Copy(source.state, 0, this.state, 0, source.state.Length); + Array.Copy(source.dataQueue, 0, this.dataQueue, 0, source.dataQueue.Length); + this.rate = source.rate; + this.bitsInQueue = source.bitsInQueue; + this.fixedOutputLength = source.fixedOutputLength; + this.squeezing = source.squeezing; + } + + public virtual string AlgorithmName + { + get { return "Keccak-" + fixedOutputLength; } + } + + public virtual int GetDigestSize() + { + return fixedOutputLength >> 3; + } + + public virtual void Update(byte input) + { + Absorb(input); + } + + public virtual void BlockUpdate(byte[] input, int inOff, int len) + { + Absorb(input, inOff, len); + } + + public virtual int DoFinal(byte[] output, int outOff) + { + Squeeze(output, outOff, fixedOutputLength); + + Reset(); + + return GetDigestSize(); + } + + /* + * TODO Possible API change to support partial-byte suffixes. + */ + protected virtual int DoFinal(byte[] output, int outOff, byte partialByte, int partialBits) + { + if (partialBits > 0) + { + AbsorbBits(partialByte, partialBits); + } + + Squeeze(output, outOff, fixedOutputLength); + + Reset(); + + return GetDigestSize(); + } + + public virtual void Reset() + { + Init(fixedOutputLength); + } + + /** + * Return the size of block that the compression function is applied to in bytes. + * + * @return internal byte length of a block. + */ + public virtual int GetByteLength() + { + return rate >> 3; + } + + private void Init(int bitLength) + { + switch (bitLength) + { + case 128: + case 224: + case 256: + case 288: + case 384: + case 512: + InitSponge(1600 - (bitLength << 1)); + break; + default: + throw new ArgumentException("must be one of 128, 224, 256, 288, 384, or 512.", "bitLength"); + } + } + + private void InitSponge(int rate) + { + if (rate <= 0 || rate >= 1600 || (rate & 63) != 0) + throw new InvalidOperationException("invalid rate value"); + + this.rate = rate; + Array.Clear(state, 0, state.Length); + Arrays.Fill(this.dataQueue, (byte)0); + this.bitsInQueue = 0; + this.squeezing = false; + this.fixedOutputLength = (1600 - rate) >> 1; + } + + protected void Absorb(byte data) + { + if ((bitsInQueue & 7) != 0) + throw new InvalidOperationException("attempt to absorb with odd length queue"); + if (squeezing) + throw new InvalidOperationException("attempt to absorb while squeezing"); + + dataQueue[bitsInQueue >> 3] = data; + if ((bitsInQueue += 8) == rate) + { + KeccakAbsorb(dataQueue, 0); + bitsInQueue = 0; + } + } + + protected void Absorb(byte[] data, int off, int len) + { + if ((bitsInQueue & 7) != 0) + throw new InvalidOperationException("attempt to absorb with odd length queue"); + if (squeezing) + throw new InvalidOperationException("attempt to absorb while squeezing"); + + int bytesInQueue = bitsInQueue >> 3; + int rateBytes = rate >> 3; + + int available = rateBytes - bytesInQueue; + if (len < available) + { + Array.Copy(data, off, dataQueue, bytesInQueue, len); + this.bitsInQueue += len << 3; + return; + } + + int count = 0; + if (bytesInQueue > 0) + { + Array.Copy(data, off, dataQueue, bytesInQueue, available); + count += available; + KeccakAbsorb(dataQueue, 0); + } + + int remaining; + while ((remaining = (len - count)) >= rateBytes) + { + KeccakAbsorb(data, off + count); + count += rateBytes; + } + + Array.Copy(data, off + count, dataQueue, 0, remaining); + this.bitsInQueue = remaining << 3; + } + + protected void AbsorbBits(int data, int bits) + { + if (bits < 1 || bits > 7) + throw new ArgumentException("must be in the range 1 to 7", "bits"); + if ((bitsInQueue & 7) != 0) + throw new InvalidOperationException("attempt to absorb with odd length queue"); + if (squeezing) + throw new InvalidOperationException("attempt to absorb while squeezing"); + + int mask = (1 << bits) - 1; + dataQueue[bitsInQueue >> 3] = (byte)(data & mask); + + // NOTE: After this, bitsInQueue is no longer a multiple of 8, so no more absorbs will work + bitsInQueue += bits; + } + + private void PadAndSwitchToSqueezingPhase() + { + Debug.Assert(bitsInQueue < rate); + + dataQueue[bitsInQueue >> 3] |= (byte)(1 << (bitsInQueue & 7)); + + if (++bitsInQueue == rate) + { + KeccakAbsorb(dataQueue, 0); + } + else + { + int full = bitsInQueue >> 6, partial = bitsInQueue & 63; + int off = 0; + for (int i = 0; i < full; ++i) + { + state[i] ^= Pack.LE_To_UInt64(dataQueue, off); + off += 8; + } + if (partial > 0) + { + ulong mask = (1UL << partial) - 1UL; + state[full] ^= Pack.LE_To_UInt64(dataQueue, off) & mask; + } + } + + state[(rate - 1) >> 6] ^= (1UL << 63); + + bitsInQueue = 0; + squeezing = true; + } + + protected void Squeeze(byte[] output, int offset, long outputLength) + { + if (!squeezing) + { + PadAndSwitchToSqueezingPhase(); + } + if ((outputLength & 7L) != 0L) + throw new InvalidOperationException("outputLength not a multiple of 8"); + + long i = 0; + while (i < outputLength) + { + if (bitsInQueue == 0) + { + KeccakExtract(); + } + int partialBlock = (int)System.Math.Min((long)bitsInQueue, outputLength - i); + Array.Copy(dataQueue, (rate - bitsInQueue) >> 3, output, offset + (int)(i >> 3), partialBlock >> 3); + bitsInQueue -= partialBlock; + i += partialBlock; + } + } + + private void KeccakAbsorb(byte[] data, int off) + { + int count = rate >> 6; + for (int i = 0; i < count; ++i) + { + state[i] ^= Pack.LE_To_UInt64(data, off); + off += 8; + } + + KeccakPermutation(); + } + + private void KeccakExtract() + { + KeccakPermutation(); + + Pack.UInt64_To_LE(state, 0, rate >> 6, dataQueue, 0); + + this.bitsInQueue = rate; + } + + private void KeccakPermutation() + { + ulong[] A = state; + + ulong a00 = A[ 0], a01 = A[ 1], a02 = A[ 2], a03 = A[ 3], a04 = A[ 4]; + ulong a05 = A[ 5], a06 = A[ 6], a07 = A[ 7], a08 = A[ 8], a09 = A[ 9]; + ulong a10 = A[10], a11 = A[11], a12 = A[12], a13 = A[13], a14 = A[14]; + ulong a15 = A[15], a16 = A[16], a17 = A[17], a18 = A[18], a19 = A[19]; + ulong a20 = A[20], a21 = A[21], a22 = A[22], a23 = A[23], a24 = A[24]; + + for (int i = 0; i < 24; i++) + { + // theta + ulong c0 = a00 ^ a05 ^ a10 ^ a15 ^ a20; + ulong c1 = a01 ^ a06 ^ a11 ^ a16 ^ a21; + ulong c2 = a02 ^ a07 ^ a12 ^ a17 ^ a22; + ulong c3 = a03 ^ a08 ^ a13 ^ a18 ^ a23; + ulong c4 = a04 ^ a09 ^ a14 ^ a19 ^ a24; + + ulong d1 = (c1 << 1 | c1 >> -1) ^ c4; + ulong d2 = (c2 << 1 | c2 >> -1) ^ c0; + ulong d3 = (c3 << 1 | c3 >> -1) ^ c1; + ulong d4 = (c4 << 1 | c4 >> -1) ^ c2; + ulong d0 = (c0 << 1 | c0 >> -1) ^ c3; + + a00 ^= d1; a05 ^= d1; a10 ^= d1; a15 ^= d1; a20 ^= d1; + a01 ^= d2; a06 ^= d2; a11 ^= d2; a16 ^= d2; a21 ^= d2; + a02 ^= d3; a07 ^= d3; a12 ^= d3; a17 ^= d3; a22 ^= d3; + a03 ^= d4; a08 ^= d4; a13 ^= d4; a18 ^= d4; a23 ^= d4; + a04 ^= d0; a09 ^= d0; a14 ^= d0; a19 ^= d0; a24 ^= d0; + + // rho/pi + c1 = a01 << 1 | a01 >> 63; + a01 = a06 << 44 | a06 >> 20; + a06 = a09 << 20 | a09 >> 44; + a09 = a22 << 61 | a22 >> 3; + a22 = a14 << 39 | a14 >> 25; + a14 = a20 << 18 | a20 >> 46; + a20 = a02 << 62 | a02 >> 2; + a02 = a12 << 43 | a12 >> 21; + a12 = a13 << 25 | a13 >> 39; + a13 = a19 << 8 | a19 >> 56; + a19 = a23 << 56 | a23 >> 8; + a23 = a15 << 41 | a15 >> 23; + a15 = a04 << 27 | a04 >> 37; + a04 = a24 << 14 | a24 >> 50; + a24 = a21 << 2 | a21 >> 62; + a21 = a08 << 55 | a08 >> 9; + a08 = a16 << 45 | a16 >> 19; + a16 = a05 << 36 | a05 >> 28; + a05 = a03 << 28 | a03 >> 36; + a03 = a18 << 21 | a18 >> 43; + a18 = a17 << 15 | a17 >> 49; + a17 = a11 << 10 | a11 >> 54; + a11 = a07 << 6 | a07 >> 58; + a07 = a10 << 3 | a10 >> 61; + a10 = c1; + + // chi + c0 = a00 ^ (~a01 & a02); + c1 = a01 ^ (~a02 & a03); + a02 ^= ~a03 & a04; + a03 ^= ~a04 & a00; + a04 ^= ~a00 & a01; + a00 = c0; + a01 = c1; + + c0 = a05 ^ (~a06 & a07); + c1 = a06 ^ (~a07 & a08); + a07 ^= ~a08 & a09; + a08 ^= ~a09 & a05; + a09 ^= ~a05 & a06; + a05 = c0; + a06 = c1; + + c0 = a10 ^ (~a11 & a12); + c1 = a11 ^ (~a12 & a13); + a12 ^= ~a13 & a14; + a13 ^= ~a14 & a10; + a14 ^= ~a10 & a11; + a10 = c0; + a11 = c1; + + c0 = a15 ^ (~a16 & a17); + c1 = a16 ^ (~a17 & a18); + a17 ^= ~a18 & a19; + a18 ^= ~a19 & a15; + a19 ^= ~a15 & a16; + a15 = c0; + a16 = c1; + + c0 = a20 ^ (~a21 & a22); + c1 = a21 ^ (~a22 & a23); + a22 ^= ~a23 & a24; + a23 ^= ~a24 & a20; + a24 ^= ~a20 & a21; + a20 = c0; + a21 = c1; + + // iota + a00 ^= KeccakRoundConstants[i]; + } + + A[ 0] = a00; A[ 1] = a01; A[ 2] = a02; A[ 3] = a03; A[ 4] = a04; + A[ 5] = a05; A[ 6] = a06; A[ 7] = a07; A[ 8] = a08; A[ 9] = a09; + A[10] = a10; A[11] = a11; A[12] = a12; A[13] = a13; A[14] = a14; + A[15] = a15; A[16] = a16; A[17] = a17; A[18] = a18; A[19] = a19; + A[20] = a20; A[21] = a21; A[22] = a22; A[23] = a23; A[24] = a24; + } + + public virtual IMemoable Copy() + { + return new KeccakDigest(this); + } + + public virtual void Reset(IMemoable other) + { + CopyIn((KeccakDigest)other); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/KeccakDigest.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/KeccakDigest.cs.meta new file mode 100644 index 0000000..e740ca9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/KeccakDigest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9d48e484a1622c44abea716e921690f7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/LongDigest.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/LongDigest.cs new file mode 100644 index 0000000..9ee9bcd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/LongDigest.cs @@ -0,0 +1,355 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /** + * Base class for SHA-384 and SHA-512. + */ + public abstract class LongDigest + : IDigest, IMemoable + { + private int MyByteLength = 128; + + private byte[] xBuf; + private int xBufOff; + + private long byteCount1; + private long byteCount2; + + internal ulong H1, H2, H3, H4, H5, H6, H7, H8; + + private ulong[] W = new ulong[80]; + private int wOff; + + /** + * Constructor for variable length word + */ + internal LongDigest() + { + xBuf = new byte[8]; + + Reset(); + } + + /** + * Copy constructor. We are using copy constructors in place + * of the object.Clone() interface as this interface is not + * supported by J2ME. + */ + internal LongDigest( + LongDigest t) + { + xBuf = new byte[t.xBuf.Length]; + + CopyIn(t); + } + + protected void CopyIn(LongDigest t) + { + Array.Copy(t.xBuf, 0, xBuf, 0, t.xBuf.Length); + + xBufOff = t.xBufOff; + byteCount1 = t.byteCount1; + byteCount2 = t.byteCount2; + + H1 = t.H1; + H2 = t.H2; + H3 = t.H3; + H4 = t.H4; + H5 = t.H5; + H6 = t.H6; + H7 = t.H7; + H8 = t.H8; + + Array.Copy(t.W, 0, W, 0, t.W.Length); + wOff = t.wOff; + } + + public void Update( + byte input) + { + xBuf[xBufOff++] = input; + + if (xBufOff == xBuf.Length) + { + ProcessWord(xBuf, 0); + xBufOff = 0; + } + + byteCount1++; + } + + public void BlockUpdate( + byte[] input, + int inOff, + int length) + { + // + // fill the current word + // + while ((xBufOff != 0) && (length > 0)) + { + Update(input[inOff]); + + inOff++; + length--; + } + + // + // process whole words. + // + while (length > xBuf.Length) + { + ProcessWord(input, inOff); + + inOff += xBuf.Length; + length -= xBuf.Length; + byteCount1 += xBuf.Length; + } + + // + // load in the remainder. + // + while (length > 0) + { + Update(input[inOff]); + + inOff++; + length--; + } + } + + public void Finish() + { + AdjustByteCounts(); + + long lowBitLength = byteCount1 << 3; + long hiBitLength = byteCount2; + + // + // add the pad bytes. + // + Update((byte)128); + + while (xBufOff != 0) + { + Update((byte)0); + } + + ProcessLength(lowBitLength, hiBitLength); + + ProcessBlock(); + } + + public virtual void Reset() + { + byteCount1 = 0; + byteCount2 = 0; + + xBufOff = 0; + for ( int i = 0; i < xBuf.Length; i++ ) + { + xBuf[i] = 0; + } + + wOff = 0; + Array.Clear(W, 0, W.Length); + } + + internal void ProcessWord( + byte[] input, + int inOff) + { + W[wOff] = Pack.BE_To_UInt64(input, inOff); + + if (++wOff == 16) + { + ProcessBlock(); + } + } + + /** + * adjust the byte counts so that byteCount2 represents the + * upper long (less 3 bits) word of the byte count. + */ + private void AdjustByteCounts() + { + if (byteCount1 > 0x1fffffffffffffffL) + { + byteCount2 += (long) ((ulong) byteCount1 >> 61); + byteCount1 &= 0x1fffffffffffffffL; + } + } + + internal void ProcessLength( + long lowW, + long hiW) + { + if (wOff > 14) + { + ProcessBlock(); + } + + W[14] = (ulong)hiW; + W[15] = (ulong)lowW; + } + + internal void ProcessBlock() + { + AdjustByteCounts(); + + // + // expand 16 word block into 80 word blocks. + // + for (int ti = 16; ti <= 79; ++ti) + { + W[ti] = Sigma1(W[ti - 2]) + W[ti - 7] + Sigma0(W[ti - 15]) + W[ti - 16]; + } + + // + // set up working variables. + // + ulong a = H1; + ulong b = H2; + ulong c = H3; + ulong d = H4; + ulong e = H5; + ulong f = H6; + ulong g = H7; + ulong h = H8; + + int t = 0; + for(int i = 0; i < 10; i ++) + { + // t = 8 * i + h += Sum1(e) + Ch(e, f, g) + K[t] + W[t++]; + d += h; + h += Sum0(a) + Maj(a, b, c); + + // t = 8 * i + 1 + g += Sum1(d) + Ch(d, e, f) + K[t] + W[t++]; + c += g; + g += Sum0(h) + Maj(h, a, b); + + // t = 8 * i + 2 + f += Sum1(c) + Ch(c, d, e) + K[t] + W[t++]; + b += f; + f += Sum0(g) + Maj(g, h, a); + + // t = 8 * i + 3 + e += Sum1(b) + Ch(b, c, d) + K[t] + W[t++]; + a += e; + e += Sum0(f) + Maj(f, g, h); + + // t = 8 * i + 4 + d += Sum1(a) + Ch(a, b, c) + K[t] + W[t++]; + h += d; + d += Sum0(e) + Maj(e, f, g); + + // t = 8 * i + 5 + c += Sum1(h) + Ch(h, a, b) + K[t] + W[t++]; + g += c; + c += Sum0(d) + Maj(d, e, f); + + // t = 8 * i + 6 + b += Sum1(g) + Ch(g, h, a) + K[t] + W[t++]; + f += b; + b += Sum0(c) + Maj(c, d, e); + + // t = 8 * i + 7 + a += Sum1(f) + Ch(f, g, h) + K[t] + W[t++]; + e += a; + a += Sum0(b) + Maj(b, c, d); + } + + H1 += a; + H2 += b; + H3 += c; + H4 += d; + H5 += e; + H6 += f; + H7 += g; + H8 += h; + + // + // reset the offset and clean out the word buffer. + // + wOff = 0; + Array.Clear(W, 0, 16); + } + + /* SHA-384 and SHA-512 functions (as for SHA-256 but for longs) */ + private static ulong Ch(ulong x, ulong y, ulong z) + { + return (x & y) ^ (~x & z); + } + + private static ulong Maj(ulong x, ulong y, ulong z) + { + return (x & y) ^ (x & z) ^ (y & z); + } + + private static ulong Sum0(ulong x) + { + return ((x << 36) | (x >> 28)) ^ ((x << 30) | (x >> 34)) ^ ((x << 25) | (x >> 39)); + } + + private static ulong Sum1(ulong x) + { + return ((x << 50) | (x >> 14)) ^ ((x << 46) | (x >> 18)) ^ ((x << 23) | (x >> 41)); + } + + private static ulong Sigma0(ulong x) + { + return ((x << 63) | (x >> 1)) ^ ((x << 56) | (x >> 8)) ^ (x >> 7); + } + + private static ulong Sigma1(ulong x) + { + return ((x << 45) | (x >> 19)) ^ ((x << 3) | (x >> 61)) ^ (x >> 6); + } + + /* SHA-384 and SHA-512 Constants + * (represent the first 64 bits of the fractional parts of the + * cube roots of the first sixty-four prime numbers) + */ + internal static readonly ulong[] K = + { + 0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc, + 0x3956c25bf348b538, 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118, + 0xd807aa98a3030242, 0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2, + 0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235, 0xc19bf174cf692694, + 0xe49b69c19ef14ad2, 0xefbe4786384f25e3, 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65, + 0x2de92c6f592b0275, 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5, + 0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f, 0xbf597fc7beef0ee4, + 0xc6e00bf33da88fc2, 0xd5a79147930aa725, 0x06ca6351e003826f, 0x142929670a0e6e70, + 0x27b70a8546d22ffc, 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df, + 0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, 0x92722c851482353b, + 0xa2bfe8a14cf10364, 0xa81a664bbc423001, 0xc24b8b70d0f89791, 0xc76c51a30654be30, + 0xd192e819d6ef5218, 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8, + 0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8, + 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, 0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3, + 0x748f82ee5defb2fc, 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec, + 0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, 0xc67178f2e372532b, + 0xca273eceea26619c, 0xd186b8c721c0c207, 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, + 0x06f067aa72176fba, 0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b, + 0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c, + 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, 0x5fcb6fab3ad6faec, 0x6c44198c4a475817 + }; + + public int GetByteLength() + { + return MyByteLength; + } + + public abstract string AlgorithmName { get; } + public abstract int GetDigestSize(); + public abstract int DoFinal(byte[] output, int outOff); + public abstract IMemoable Copy(); + public abstract void Reset(IMemoable t); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/LongDigest.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/LongDigest.cs.meta new file mode 100644 index 0000000..abffdc5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/LongDigest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 95c87a44e0da6204e8947f7c36e0fade +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/MD2Digest.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/MD2Digest.cs new file mode 100644 index 0000000..6d90f3f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/MD2Digest.cs @@ -0,0 +1,269 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + + /** + * implementation of MD2 + * as outlined in RFC1319 by B.Kaliski from RSA Laboratories April 1992 + */ + public class MD2Digest + : IDigest, IMemoable + { + private const int DigestLength = 16; + private const int BYTE_LENGTH = 16; + + /* X buffer */ + private byte[] X = new byte[48]; + private int xOff; + + /* M buffer */ + + private byte[] M = new byte[16]; + private int mOff; + + /* check sum */ + + private byte[] C = new byte[16]; + private int COff; + + public MD2Digest() + { + Reset(); + } + + public MD2Digest(MD2Digest t) + { + CopyIn(t); + } + + private void CopyIn(MD2Digest t) + { + Array.Copy(t.X, 0, X, 0, t.X.Length); + xOff = t.xOff; + Array.Copy(t.M, 0, M, 0, t.M.Length); + mOff = t.mOff; + Array.Copy(t.C, 0, C, 0, t.C.Length); + COff = t.COff; + } + + /** + * return the algorithm name + * + * @return the algorithm name + */ + public string AlgorithmName + { + get { return "MD2"; } + } + + public int GetDigestSize() + { + return DigestLength; + } + + public int GetByteLength() + { + return BYTE_LENGTH; + } + + /** + * Close the digest, producing the final digest value. The doFinal + * call leaves the digest reset. + * + * @param out the array the digest is to be copied into. + * @param outOff the offset into the out array the digest is to start at. + */ + public int DoFinal(byte[] output, int outOff) + { + // add padding + byte paddingByte = (byte)(M.Length - mOff); + for (int i=mOff;i 0)) + { + Update(input[inOff]); + inOff++; + length--; + } + + // + // process whole words. + // + while (length > 16) + { + Array.Copy(input,inOff,M,0,16); + ProcessChecksum(M); + ProcessBlock(M); + length -= 16; + inOff += 16; + } + + // + // load in the remainder. + // + while (length > 0) + { + Update(input[inOff]); + inOff++; + length--; + } + } + + internal void ProcessChecksum(byte[] m) + { + int L = C[15]; + for (int i=0;i<16;i++) + { + C[i] ^= S[(m[i] ^ L) & 0xff]; + L = C[i]; + } + } + internal void ProcessBlock(byte[] m) + { + for (int i=0;i<16;i++) + { + X[i+16] = m[i]; + X[i+32] = (byte)(m[i] ^ X[i]); + } + // encrypt block + int t = 0; + + for (int j=0;j<18;j++) + { + for (int k=0;k<48;k++) + { + t = X[k] ^= S[t]; + t = t & 0xff; + } + t = (t + j)%256; + } + } + + + + // 256-byte random permutation constructed from the digits of PI + private static readonly byte[] S = { + (byte)41,(byte)46,(byte)67,(byte)201,(byte)162,(byte)216,(byte)124, + (byte)1,(byte)61,(byte)54,(byte)84,(byte)161,(byte)236,(byte)240, + (byte)6,(byte)19,(byte)98,(byte)167,(byte)5,(byte)243,(byte)192, + (byte)199,(byte)115,(byte)140,(byte)152,(byte)147,(byte)43,(byte)217, + (byte)188,(byte)76,(byte)130,(byte)202,(byte)30,(byte)155,(byte)87, + (byte)60,(byte)253,(byte)212,(byte)224,(byte)22,(byte)103,(byte)66, + (byte)111,(byte)24,(byte)138,(byte)23,(byte)229,(byte)18,(byte)190, + (byte)78,(byte)196,(byte)214,(byte)218,(byte)158,(byte)222,(byte)73, + (byte)160,(byte)251,(byte)245,(byte)142,(byte)187,(byte)47,(byte)238, + (byte)122,(byte)169,(byte)104,(byte)121,(byte)145,(byte)21,(byte)178, + (byte)7,(byte)63,(byte)148,(byte)194,(byte)16,(byte)137,(byte)11, + (byte)34,(byte)95,(byte)33,(byte)128,(byte)127,(byte)93,(byte)154, + (byte)90,(byte)144,(byte)50,(byte)39,(byte)53,(byte)62,(byte)204, + (byte)231,(byte)191,(byte)247,(byte)151,(byte)3,(byte)255,(byte)25, + (byte)48,(byte)179,(byte)72,(byte)165,(byte)181,(byte)209,(byte)215, + (byte)94,(byte)146,(byte)42,(byte)172,(byte)86,(byte)170,(byte)198, + (byte)79,(byte)184,(byte)56,(byte)210,(byte)150,(byte)164,(byte)125, + (byte)182,(byte)118,(byte)252,(byte)107,(byte)226,(byte)156,(byte)116, + (byte)4,(byte)241,(byte)69,(byte)157,(byte)112,(byte)89,(byte)100, + (byte)113,(byte)135,(byte)32,(byte)134,(byte)91,(byte)207,(byte)101, + (byte)230,(byte)45,(byte)168,(byte)2,(byte)27,(byte)96,(byte)37, + (byte)173,(byte)174,(byte)176,(byte)185,(byte)246,(byte)28,(byte)70, + (byte)97,(byte)105,(byte)52,(byte)64,(byte)126,(byte)15,(byte)85, + (byte)71,(byte)163,(byte)35,(byte)221,(byte)81,(byte)175,(byte)58, + (byte)195,(byte)92,(byte)249,(byte)206,(byte)186,(byte)197,(byte)234, + (byte)38,(byte)44,(byte)83,(byte)13,(byte)110,(byte)133,(byte)40, + (byte)132, 9,(byte)211,(byte)223,(byte)205,(byte)244,(byte)65, + (byte)129,(byte)77,(byte)82,(byte)106,(byte)220,(byte)55,(byte)200, + (byte)108,(byte)193,(byte)171,(byte)250,(byte)36,(byte)225,(byte)123, + (byte)8,(byte)12,(byte)189,(byte)177,(byte)74,(byte)120,(byte)136, + (byte)149,(byte)139,(byte)227,(byte)99,(byte)232,(byte)109,(byte)233, + (byte)203,(byte)213,(byte)254,(byte)59,(byte)0,(byte)29,(byte)57, + (byte)242,(byte)239,(byte)183,(byte)14,(byte)102,(byte)88,(byte)208, + (byte)228,(byte)166,(byte)119,(byte)114,(byte)248,(byte)235,(byte)117, + (byte)75,(byte)10,(byte)49,(byte)68,(byte)80,(byte)180,(byte)143, + (byte)237,(byte)31,(byte)26,(byte)219,(byte)153,(byte)141,(byte)51, + (byte)159,(byte)17,(byte)131,(byte)20 + }; + + public IMemoable Copy() + { + return new MD2Digest(this); + } + + public void Reset(IMemoable other) + { + MD2Digest d = (MD2Digest)other; + + CopyIn(d); + } + + } + +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/MD2Digest.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/MD2Digest.cs.meta new file mode 100644 index 0000000..97e0ca5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/MD2Digest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e3c08e2c81a30e044815b2f54e88af10 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/MD4Digest.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/MD4Digest.cs new file mode 100644 index 0000000..8743f7d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/MD4Digest.cs @@ -0,0 +1,292 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /** + * implementation of MD4 as RFC 1320 by R. Rivest, MIT Laboratory for + * Computer Science and RSA Data Security, Inc. + *

+ * NOTE: This algorithm is only included for backwards compatibility + * with legacy applications, it's not secure, don't use it for anything new!

+ */ + public class MD4Digest + : GeneralDigest + { + private const int DigestLength = 16; + + private int H1, H2, H3, H4; // IV's + + private int[] X = new int[16]; + private int xOff; + + /** + * Standard constructor + */ + public MD4Digest() + { + Reset(); + } + + /** + * Copy constructor. This will copy the state of the provided + * message digest. + */ + public MD4Digest(MD4Digest t) : base(t) + { + CopyIn(t); + } + + private void CopyIn(MD4Digest t) + { + base.CopyIn(t); + H1 = t.H1; + H2 = t.H2; + H3 = t.H3; + H4 = t.H4; + + Array.Copy(t.X, 0, X, 0, t.X.Length); + xOff = t.xOff; + } + + public override string AlgorithmName + { + get { return "MD4"; } + } + + public override int GetDigestSize() + { + return DigestLength; + } + + internal override void ProcessWord( + byte[] input, + int inOff) + { + X[xOff++] = (input[inOff] & 0xff) | ((input[inOff + 1] & 0xff) << 8) + | ((input[inOff + 2] & 0xff) << 16) | ((input[inOff + 3] & 0xff) << 24); + + if (xOff == 16) + { + ProcessBlock(); + } + } + + internal override void ProcessLength( + long bitLength) + { + if (xOff > 14) + { + ProcessBlock(); + } + + X[14] = (int)(bitLength & 0xffffffff); + X[15] = (int)((ulong) bitLength >> 32); + } + + private void UnpackWord( + int word, + byte[] outBytes, + int outOff) + { + outBytes[outOff] = (byte)word; + outBytes[outOff + 1] = (byte)((uint) word >> 8); + outBytes[outOff + 2] = (byte)((uint) word >> 16); + outBytes[outOff + 3] = (byte)((uint) word >> 24); + } + + public override int DoFinal( + byte[] output, + int outOff) + { + Finish(); + + UnpackWord(H1, output, outOff); + UnpackWord(H2, output, outOff + 4); + UnpackWord(H3, output, outOff + 8); + UnpackWord(H4, output, outOff + 12); + + Reset(); + + return DigestLength; + } + + /** + * reset the chaining variables to the IV values. + */ + public override void Reset() + { + base.Reset(); + + H1 = unchecked((int) 0x67452301); + H2 = unchecked((int) 0xefcdab89); + H3 = unchecked((int) 0x98badcfe); + H4 = unchecked((int) 0x10325476); + + xOff = 0; + + for (int i = 0; i != X.Length; i++) + { + X[i] = 0; + } + } + + // + // round 1 left rotates + // + private const int S11 = 3; + private const int S12 = 7; + private const int S13 = 11; + private const int S14 = 19; + + // + // round 2 left rotates + // + private const int S21 = 3; + private const int S22 = 5; + private const int S23 = 9; + private const int S24 = 13; + + // + // round 3 left rotates + // + private const int S31 = 3; + private const int S32 = 9; + private const int S33 = 11; + private const int S34 = 15; + + /* + * rotate int x left n bits. + */ + private int RotateLeft( + int x, + int n) + { + return (x << n) | (int) ((uint) x >> (32 - n)); + } + + /* + * F, G, H and I are the basic MD4 functions. + */ + private int F( + int u, + int v, + int w) + { + return (u & v) | (~u & w); + } + + private int G( + int u, + int v, + int w) + { + return (u & v) | (u & w) | (v & w); + } + + private int H( + int u, + int v, + int w) + { + return u ^ v ^ w; + } + + internal override void ProcessBlock() + { + int a = H1; + int b = H2; + int c = H3; + int d = H4; + + // + // Round 1 - F cycle, 16 times. + // + a = RotateLeft((a + F(b, c, d) + X[ 0]), S11); + d = RotateLeft((d + F(a, b, c) + X[ 1]), S12); + c = RotateLeft((c + F(d, a, b) + X[ 2]), S13); + b = RotateLeft((b + F(c, d, a) + X[ 3]), S14); + a = RotateLeft((a + F(b, c, d) + X[ 4]), S11); + d = RotateLeft((d + F(a, b, c) + X[ 5]), S12); + c = RotateLeft((c + F(d, a, b) + X[ 6]), S13); + b = RotateLeft((b + F(c, d, a) + X[ 7]), S14); + a = RotateLeft((a + F(b, c, d) + X[ 8]), S11); + d = RotateLeft((d + F(a, b, c) + X[ 9]), S12); + c = RotateLeft((c + F(d, a, b) + X[10]), S13); + b = RotateLeft((b + F(c, d, a) + X[11]), S14); + a = RotateLeft((a + F(b, c, d) + X[12]), S11); + d = RotateLeft((d + F(a, b, c) + X[13]), S12); + c = RotateLeft((c + F(d, a, b) + X[14]), S13); + b = RotateLeft((b + F(c, d, a) + X[15]), S14); + + // + // Round 2 - G cycle, 16 times. + // + a = RotateLeft((a + G(b, c, d) + X[ 0] + 0x5a827999), S21); + d = RotateLeft((d + G(a, b, c) + X[ 4] + 0x5a827999), S22); + c = RotateLeft((c + G(d, a, b) + X[ 8] + 0x5a827999), S23); + b = RotateLeft((b + G(c, d, a) + X[12] + 0x5a827999), S24); + a = RotateLeft((a + G(b, c, d) + X[ 1] + 0x5a827999), S21); + d = RotateLeft((d + G(a, b, c) + X[ 5] + 0x5a827999), S22); + c = RotateLeft((c + G(d, a, b) + X[ 9] + 0x5a827999), S23); + b = RotateLeft((b + G(c, d, a) + X[13] + 0x5a827999), S24); + a = RotateLeft((a + G(b, c, d) + X[ 2] + 0x5a827999), S21); + d = RotateLeft((d + G(a, b, c) + X[ 6] + 0x5a827999), S22); + c = RotateLeft((c + G(d, a, b) + X[10] + 0x5a827999), S23); + b = RotateLeft((b + G(c, d, a) + X[14] + 0x5a827999), S24); + a = RotateLeft((a + G(b, c, d) + X[ 3] + 0x5a827999), S21); + d = RotateLeft((d + G(a, b, c) + X[ 7] + 0x5a827999), S22); + c = RotateLeft((c + G(d, a, b) + X[11] + 0x5a827999), S23); + b = RotateLeft((b + G(c, d, a) + X[15] + 0x5a827999), S24); + + // + // Round 3 - H cycle, 16 times. + // + a = RotateLeft((a + H(b, c, d) + X[ 0] + 0x6ed9eba1), S31); + d = RotateLeft((d + H(a, b, c) + X[ 8] + 0x6ed9eba1), S32); + c = RotateLeft((c + H(d, a, b) + X[ 4] + 0x6ed9eba1), S33); + b = RotateLeft((b + H(c, d, a) + X[12] + 0x6ed9eba1), S34); + a = RotateLeft((a + H(b, c, d) + X[ 2] + 0x6ed9eba1), S31); + d = RotateLeft((d + H(a, b, c) + X[10] + 0x6ed9eba1), S32); + c = RotateLeft((c + H(d, a, b) + X[ 6] + 0x6ed9eba1), S33); + b = RotateLeft((b + H(c, d, a) + X[14] + 0x6ed9eba1), S34); + a = RotateLeft((a + H(b, c, d) + X[ 1] + 0x6ed9eba1), S31); + d = RotateLeft((d + H(a, b, c) + X[ 9] + 0x6ed9eba1), S32); + c = RotateLeft((c + H(d, a, b) + X[ 5] + 0x6ed9eba1), S33); + b = RotateLeft((b + H(c, d, a) + X[13] + 0x6ed9eba1), S34); + a = RotateLeft((a + H(b, c, d) + X[ 3] + 0x6ed9eba1), S31); + d = RotateLeft((d + H(a, b, c) + X[11] + 0x6ed9eba1), S32); + c = RotateLeft((c + H(d, a, b) + X[ 7] + 0x6ed9eba1), S33); + b = RotateLeft((b + H(c, d, a) + X[15] + 0x6ed9eba1), S34); + + H1 += a; + H2 += b; + H3 += c; + H4 += d; + + // + // reset the offset and clean out the word buffer. + // + xOff = 0; + for (int i = 0; i != X.Length; i++) + { + X[i] = 0; + } + } + + public override IMemoable Copy() + { + return new MD4Digest(this); + } + + public override void Reset(IMemoable other) + { + MD4Digest d = (MD4Digest)other; + + CopyIn(d); + } + + } + +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/MD4Digest.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/MD4Digest.cs.meta new file mode 100644 index 0000000..8f497a5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/MD4Digest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9c02cda0e53df9d41b3778f248079486 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/MD5Digest.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/MD5Digest.cs new file mode 100644 index 0000000..c60ac92 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/MD5Digest.cs @@ -0,0 +1,313 @@ +using System; + +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /** + * implementation of MD5 as outlined in "Handbook of Applied Cryptography", pages 346 - 347. + */ + public class MD5Digest + : GeneralDigest + { + private const int DigestLength = 16; + + private uint H1, H2, H3, H4; // IV's + + private uint[] X = new uint[16]; + private int xOff; + + public MD5Digest() + { + Reset(); + } + + /** + * Copy constructor. This will copy the state of the provided + * message digest. + */ + public MD5Digest(MD5Digest t) + : base(t) + { + CopyIn(t); + } + + private void CopyIn(MD5Digest t) + { + base.CopyIn(t); + H1 = t.H1; + H2 = t.H2; + H3 = t.H3; + H4 = t.H4; + + Array.Copy(t.X, 0, X, 0, t.X.Length); + xOff = t.xOff; + } + + public override string AlgorithmName + { + get { return "MD5"; } + } + + public override int GetDigestSize() + { + return DigestLength; + } + + internal override void ProcessWord( + byte[] input, + int inOff) + { + X[xOff] = Pack.LE_To_UInt32(input, inOff); + + if (++xOff == 16) + { + ProcessBlock(); + } + } + + internal override void ProcessLength( + long bitLength) + { + if (xOff > 14) + { + if (xOff == 15) + X[15] = 0; + + ProcessBlock(); + } + + for (int i = xOff; i < 14; ++i) + { + X[i] = 0; + } + + X[14] = (uint)((ulong)bitLength); + X[15] = (uint)((ulong)bitLength >> 32); + } + + public override int DoFinal( + byte[] output, + int outOff) + { + Finish(); + + Pack.UInt32_To_LE(H1, output, outOff); + Pack.UInt32_To_LE(H2, output, outOff + 4); + Pack.UInt32_To_LE(H3, output, outOff + 8); + Pack.UInt32_To_LE(H4, output, outOff + 12); + + Reset(); + + return DigestLength; + } + + /** + * reset the chaining variables to the IV values. + */ + public override void Reset() + { + base.Reset(); + + H1 = 0x67452301; + H2 = 0xefcdab89; + H3 = 0x98badcfe; + H4 = 0x10325476; + + xOff = 0; + + for (int i = 0; i != X.Length; i++) + { + X[i] = 0; + } + } + + // + // round 1 left rotates + // + private static readonly int S11 = 7; + private static readonly int S12 = 12; + private static readonly int S13 = 17; + private static readonly int S14 = 22; + + // + // round 2 left rotates + // + private static readonly int S21 = 5; + private static readonly int S22 = 9; + private static readonly int S23 = 14; + private static readonly int S24 = 20; + + // + // round 3 left rotates + // + private static readonly int S31 = 4; + private static readonly int S32 = 11; + private static readonly int S33 = 16; + private static readonly int S34 = 23; + + // + // round 4 left rotates + // + private static readonly int S41 = 6; + private static readonly int S42 = 10; + private static readonly int S43 = 15; + private static readonly int S44 = 21; + + /* + * rotate int x left n bits. + */ + private static uint RotateLeft( + uint x, + int n) + { + return (x << n) | (x >> (32 - n)); + } + + /* + * F, G, H and I are the basic MD5 functions. + */ + private static uint F( + uint u, + uint v, + uint w) + { + return (u & v) | (~u & w); + } + + private static uint G( + uint u, + uint v, + uint w) + { + return (u & w) | (v & ~w); + } + + private static uint H( + uint u, + uint v, + uint w) + { + return u ^ v ^ w; + } + + private static uint K( + uint u, + uint v, + uint w) + { + return v ^ (u | ~w); + } + + internal override void ProcessBlock() + { + uint a = H1; + uint b = H2; + uint c = H3; + uint d = H4; + + // + // Round 1 - F cycle, 16 times. + // + a = RotateLeft((a + F(b, c, d) + X[0] + 0xd76aa478), S11) + b; + d = RotateLeft((d + F(a, b, c) + X[1] + 0xe8c7b756), S12) + a; + c = RotateLeft((c + F(d, a, b) + X[2] + 0x242070db), S13) + d; + b = RotateLeft((b + F(c, d, a) + X[3] + 0xc1bdceee), S14) + c; + a = RotateLeft((a + F(b, c, d) + X[4] + 0xf57c0faf), S11) + b; + d = RotateLeft((d + F(a, b, c) + X[5] + 0x4787c62a), S12) + a; + c = RotateLeft((c + F(d, a, b) + X[6] + 0xa8304613), S13) + d; + b = RotateLeft((b + F(c, d, a) + X[7] + 0xfd469501), S14) + c; + a = RotateLeft((a + F(b, c, d) + X[8] + 0x698098d8), S11) + b; + d = RotateLeft((d + F(a, b, c) + X[9] + 0x8b44f7af), S12) + a; + c = RotateLeft((c + F(d, a, b) + X[10] + 0xffff5bb1), S13) + d; + b = RotateLeft((b + F(c, d, a) + X[11] + 0x895cd7be), S14) + c; + a = RotateLeft((a + F(b, c, d) + X[12] + 0x6b901122), S11) + b; + d = RotateLeft((d + F(a, b, c) + X[13] + 0xfd987193), S12) + a; + c = RotateLeft((c + F(d, a, b) + X[14] + 0xa679438e), S13) + d; + b = RotateLeft((b + F(c, d, a) + X[15] + 0x49b40821), S14) + c; + + // + // Round 2 - G cycle, 16 times. + // + a = RotateLeft((a + G(b, c, d) + X[1] + 0xf61e2562), S21) + b; + d = RotateLeft((d + G(a, b, c) + X[6] + 0xc040b340), S22) + a; + c = RotateLeft((c + G(d, a, b) + X[11] + 0x265e5a51), S23) + d; + b = RotateLeft((b + G(c, d, a) + X[0] + 0xe9b6c7aa), S24) + c; + a = RotateLeft((a + G(b, c, d) + X[5] + 0xd62f105d), S21) + b; + d = RotateLeft((d + G(a, b, c) + X[10] + 0x02441453), S22) + a; + c = RotateLeft((c + G(d, a, b) + X[15] + 0xd8a1e681), S23) + d; + b = RotateLeft((b + G(c, d, a) + X[4] + 0xe7d3fbc8), S24) + c; + a = RotateLeft((a + G(b, c, d) + X[9] + 0x21e1cde6), S21) + b; + d = RotateLeft((d + G(a, b, c) + X[14] + 0xc33707d6), S22) + a; + c = RotateLeft((c + G(d, a, b) + X[3] + 0xf4d50d87), S23) + d; + b = RotateLeft((b + G(c, d, a) + X[8] + 0x455a14ed), S24) + c; + a = RotateLeft((a + G(b, c, d) + X[13] + 0xa9e3e905), S21) + b; + d = RotateLeft((d + G(a, b, c) + X[2] + 0xfcefa3f8), S22) + a; + c = RotateLeft((c + G(d, a, b) + X[7] + 0x676f02d9), S23) + d; + b = RotateLeft((b + G(c, d, a) + X[12] + 0x8d2a4c8a), S24) + c; + + // + // Round 3 - H cycle, 16 times. + // + a = RotateLeft((a + H(b, c, d) + X[5] + 0xfffa3942), S31) + b; + d = RotateLeft((d + H(a, b, c) + X[8] + 0x8771f681), S32) + a; + c = RotateLeft((c + H(d, a, b) + X[11] + 0x6d9d6122), S33) + d; + b = RotateLeft((b + H(c, d, a) + X[14] + 0xfde5380c), S34) + c; + a = RotateLeft((a + H(b, c, d) + X[1] + 0xa4beea44), S31) + b; + d = RotateLeft((d + H(a, b, c) + X[4] + 0x4bdecfa9), S32) + a; + c = RotateLeft((c + H(d, a, b) + X[7] + 0xf6bb4b60), S33) + d; + b = RotateLeft((b + H(c, d, a) + X[10] + 0xbebfbc70), S34) + c; + a = RotateLeft((a + H(b, c, d) + X[13] + 0x289b7ec6), S31) + b; + d = RotateLeft((d + H(a, b, c) + X[0] + 0xeaa127fa), S32) + a; + c = RotateLeft((c + H(d, a, b) + X[3] + 0xd4ef3085), S33) + d; + b = RotateLeft((b + H(c, d, a) + X[6] + 0x04881d05), S34) + c; + a = RotateLeft((a + H(b, c, d) + X[9] + 0xd9d4d039), S31) + b; + d = RotateLeft((d + H(a, b, c) + X[12] + 0xe6db99e5), S32) + a; + c = RotateLeft((c + H(d, a, b) + X[15] + 0x1fa27cf8), S33) + d; + b = RotateLeft((b + H(c, d, a) + X[2] + 0xc4ac5665), S34) + c; + + // + // Round 4 - K cycle, 16 times. + // + a = RotateLeft((a + K(b, c, d) + X[0] + 0xf4292244), S41) + b; + d = RotateLeft((d + K(a, b, c) + X[7] + 0x432aff97), S42) + a; + c = RotateLeft((c + K(d, a, b) + X[14] + 0xab9423a7), S43) + d; + b = RotateLeft((b + K(c, d, a) + X[5] + 0xfc93a039), S44) + c; + a = RotateLeft((a + K(b, c, d) + X[12] + 0x655b59c3), S41) + b; + d = RotateLeft((d + K(a, b, c) + X[3] + 0x8f0ccc92), S42) + a; + c = RotateLeft((c + K(d, a, b) + X[10] + 0xffeff47d), S43) + d; + b = RotateLeft((b + K(c, d, a) + X[1] + 0x85845dd1), S44) + c; + a = RotateLeft((a + K(b, c, d) + X[8] + 0x6fa87e4f), S41) + b; + d = RotateLeft((d + K(a, b, c) + X[15] + 0xfe2ce6e0), S42) + a; + c = RotateLeft((c + K(d, a, b) + X[6] + 0xa3014314), S43) + d; + b = RotateLeft((b + K(c, d, a) + X[13] + 0x4e0811a1), S44) + c; + a = RotateLeft((a + K(b, c, d) + X[4] + 0xf7537e82), S41) + b; + d = RotateLeft((d + K(a, b, c) + X[11] + 0xbd3af235), S42) + a; + c = RotateLeft((c + K(d, a, b) + X[2] + 0x2ad7d2bb), S43) + d; + b = RotateLeft((b + K(c, d, a) + X[9] + 0xeb86d391), S44) + c; + + H1 += a; + H2 += b; + H3 += c; + H4 += d; + + xOff = 0; + } + + public override IMemoable Copy() + { + return new MD5Digest(this); + } + + public override void Reset(IMemoable other) + { + MD5Digest d = (MD5Digest)other; + + CopyIn(d); + } + + } + +} + diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/MD5Digest.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/MD5Digest.cs.meta new file mode 100644 index 0000000..fcc5c93 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/MD5Digest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b14c11eee1fbee847bde673bcaae9cd3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/NonMemoableDigest.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/NonMemoableDigest.cs new file mode 100644 index 0000000..02c49b8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/NonMemoableDigest.cs @@ -0,0 +1,62 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /** + * Wrapper removes exposure to the IMemoable interface on an IDigest implementation. + */ + public class NonMemoableDigest + : IDigest + { + protected readonly IDigest mBaseDigest; + + /** + * Base constructor. + * + * @param baseDigest underlying digest to use. + * @exception IllegalArgumentException if baseDigest is null + */ + public NonMemoableDigest(IDigest baseDigest) + { + if (baseDigest == null) + throw new ArgumentNullException("baseDigest"); + + this.mBaseDigest = baseDigest; + } + + public virtual string AlgorithmName + { + get { return mBaseDigest.AlgorithmName; } + } + + public virtual int GetDigestSize() + { + return mBaseDigest.GetDigestSize(); + } + + public virtual void Update(byte input) + { + mBaseDigest.Update(input); + } + + public virtual void BlockUpdate(byte[] input, int inOff, int len) + { + mBaseDigest.BlockUpdate(input, inOff, len); + } + + public virtual int DoFinal(byte[] output, int outOff) + { + return mBaseDigest.DoFinal(output, outOff); + } + + public virtual void Reset() + { + mBaseDigest.Reset(); + } + + public virtual int GetByteLength() + { + return mBaseDigest.GetByteLength(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/NonMemoableDigest.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/NonMemoableDigest.cs.meta new file mode 100644 index 0000000..2cf5cc1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/NonMemoableDigest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7f4b18d22ca038d40ae41c4cec23f225 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/NullDigest.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/NullDigest.cs new file mode 100644 index 0000000..76b69af --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/NullDigest.cs @@ -0,0 +1,55 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Crypto.Digests +{ + public class NullDigest : IDigest + { + private readonly MemoryStream bOut = new MemoryStream(); + + public string AlgorithmName + { + get { return "NULL"; } + } + + public int GetByteLength() + { + // TODO Is this okay? + return 0; + } + + public int GetDigestSize() + { + return (int)bOut.Length; + } + + public void Update(byte b) + { + bOut.WriteByte(b); + } + + public void BlockUpdate(byte[] inBytes, int inOff, int len) + { + bOut.Write(inBytes, inOff, len); + } + + public int DoFinal(byte[] outBytes, int outOff) + { + try + { + return Streams.WriteBufTo(bOut, outBytes, outOff); + } + finally + { + Reset(); + } + } + + public void Reset() + { + bOut.SetLength(0); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/NullDigest.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/NullDigest.cs.meta new file mode 100644 index 0000000..c21db5c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/NullDigest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ce4a34a3586d48f4986ab9b61c8695a0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/ParallelHash.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/ParallelHash.cs new file mode 100644 index 0000000..7d9be76 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/ParallelHash.cs @@ -0,0 +1,210 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /// + /// ParallelHash - a hash designed to support the efficient hashing of very long strings, by taking advantage, + /// of the parallelism available in modern processors with an optional XOF mode. + /// + /// From NIST Special Publication 800-185 - SHA-3 Derived Functions:cSHAKE, KMAC, TupleHash and ParallelHash + /// + /// + public class ParallelHash + : IXof, IDigest + { + private static readonly byte[] N_PARALLEL_HASH = Strings.ToByteArray("ParallelHash"); + + private readonly CShakeDigest cshake; + private readonly CShakeDigest compressor; + private readonly int bitLength; + private readonly int outputLength; + private readonly int B; + private readonly byte[] buffer; + private readonly byte[] compressorBuffer; + + private bool firstOutput; + private int nCount; + private int bufOff; + + /** + * Base constructor. + * + * @param bitLength bit length of the underlying SHAKE function, 128 or 256. + * @param S the customization string - available for local use. + * @param B the blocksize (in bytes) for hashing. + */ + public ParallelHash(int bitLength, byte[] S, int B) + : this(bitLength, S, B, bitLength * 2) + { + + } + + public ParallelHash(int bitLength, byte[] S, int B, int outputSize) + { + this.cshake = new CShakeDigest(bitLength, N_PARALLEL_HASH, S); + this.compressor = new CShakeDigest(bitLength, new byte[0], new byte[0]); + this.bitLength = bitLength; + this.B = B; + this.outputLength = (outputSize + 7) / 8; + this.buffer = new byte[B]; + this.compressorBuffer = new byte[bitLength * 2 / 8]; + + Reset(); + } + + public ParallelHash(ParallelHash source) + { + this.cshake = new CShakeDigest(source.cshake); + this.compressor = new CShakeDigest(source.compressor); + this.bitLength = source.bitLength; + this.B = source.B; + this.outputLength = source.outputLength; + this.buffer = Arrays.Clone(source.buffer); + this.compressorBuffer = Arrays.Clone(source.compressorBuffer); + } + + public virtual string AlgorithmName + { + get { return "ParallelHash" + cshake.AlgorithmName.Substring(6); } + } + + public virtual int GetByteLength() + { + return cshake.GetByteLength(); + } + + public virtual int GetDigestSize() + { + return outputLength; + } + + public virtual void Update(byte b) + { + buffer[bufOff++] = b; + if (bufOff == buffer.Length) + { + compress(); + } + } + + public virtual void BlockUpdate(byte[] inBuf, int inOff, int len) + { + len = System.Math.Max(0, len); + + // + // fill the current word + // + int i = 0; + if (bufOff != 0) + { + while (i < len && bufOff != buffer.Length) + { + buffer[bufOff++] = inBuf[inOff + i++]; + } + + if (bufOff == buffer.Length) + { + compress(); + } + } + + if (i < len) + { + while (len - i > B) + { + compress(inBuf, inOff + i, B); + i += B; + } + } + + while (i < len) + { + Update(inBuf[inOff + i++]); + } + } + + private void compress() + { + compress(buffer, 0, bufOff); + bufOff = 0; + } + + private void compress(byte[] buf, int offSet, int len) + { + compressor.BlockUpdate(buf, offSet, len); + compressor.DoFinal(compressorBuffer, 0, compressorBuffer.Length); + + cshake.BlockUpdate(compressorBuffer, 0, compressorBuffer.Length); + + nCount++; + } + + private void wrapUp(int outputSize) + { + if (bufOff != 0) + { + compress(); + } + byte[] nOut = XofUtilities.RightEncode(nCount); + byte[] encOut = XofUtilities.RightEncode(outputSize * 8); + + cshake.BlockUpdate(nOut, 0, nOut.Length); + cshake.BlockUpdate(encOut, 0, encOut.Length); + + firstOutput = false; + } + + public virtual int DoFinal(byte[] outBuf, int outOff) + { + if (firstOutput) + { + wrapUp(outputLength); + } + + int rv = cshake.DoFinal(outBuf, outOff, GetDigestSize()); + + Reset(); + + return rv; + } + + public virtual int DoFinal(byte[] outBuf, int outOff, int outLen) + { + if (firstOutput) + { + wrapUp(outputLength); + } + + int rv = cshake.DoFinal(outBuf, outOff, outLen); + + Reset(); + + return rv; + } + + public virtual int DoOutput(byte[] outBuf, int outOff, int outLen) + { + if (firstOutput) + { + wrapUp(0); + } + + return cshake.DoOutput(outBuf, outOff, outLen); + } + + public virtual void Reset() + { + cshake.Reset(); + Arrays.Clear(buffer); + + byte[] hdr = XofUtilities.LeftEncode(B); + cshake.BlockUpdate(hdr, 0, hdr.Length); + + nCount = 0; + bufOff = 0; + firstOutput = true; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/ParallelHash.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/ParallelHash.cs.meta new file mode 100644 index 0000000..6a09609 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/ParallelHash.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c70c9234da37b2b4e82196de9d14ca25 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/RipeMD128Digest.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/RipeMD128Digest.cs new file mode 100644 index 0000000..e8a0331 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/RipeMD128Digest.cs @@ -0,0 +1,484 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /** + * implementation of RipeMD128 + */ + public class RipeMD128Digest + : GeneralDigest + { + private const int DigestLength = 16; + + private int H0, H1, H2, H3; // IV's + + private int[] X = new int[16]; + private int xOff; + + /** + * Standard constructor + */ + public RipeMD128Digest() + { + Reset(); + } + + /** + * Copy constructor. This will copy the state of the provided + * message digest. + */ + public RipeMD128Digest(RipeMD128Digest t) : base(t) + { + CopyIn(t); + } + + private void CopyIn(RipeMD128Digest t) + { + base.CopyIn(t); + + H0 = t.H0; + H1 = t.H1; + H2 = t.H2; + H3 = t.H3; + + Array.Copy(t.X, 0, X, 0, t.X.Length); + xOff = t.xOff; + } + + public override string AlgorithmName + { + get { return "RIPEMD128"; } + } + + public override int GetDigestSize() + { + return DigestLength; + } + + internal override void ProcessWord( + byte[] input, + int inOff) + { + X[xOff++] = (input[inOff] & 0xff) | ((input[inOff + 1] & 0xff) << 8) + | ((input[inOff + 2] & 0xff) << 16) | ((input[inOff + 3] & 0xff) << 24); + + if (xOff == 16) + { + ProcessBlock(); + } + } + + internal override void ProcessLength( + long bitLength) + { + if (xOff > 14) + { + ProcessBlock(); + } + + X[14] = (int)(bitLength & 0xffffffff); + X[15] = (int)((ulong) bitLength >> 32); + } + + private void UnpackWord( + int word, + byte[] outBytes, + int outOff) + { + outBytes[outOff] = (byte)word; + outBytes[outOff + 1] = (byte)((uint) word >> 8); + outBytes[outOff + 2] = (byte)((uint) word >> 16); + outBytes[outOff + 3] = (byte)((uint) word >> 24); + } + + public override int DoFinal( + byte[] output, + int outOff) + { + Finish(); + + UnpackWord(H0, output, outOff); + UnpackWord(H1, output, outOff + 4); + UnpackWord(H2, output, outOff + 8); + UnpackWord(H3, output, outOff + 12); + + Reset(); + + return DigestLength; + } + + /** + * reset the chaining variables to the IV values. + */ + public override void Reset() + { + base.Reset(); + + H0 = unchecked((int) 0x67452301); + H1 = unchecked((int) 0xefcdab89); + H2 = unchecked((int) 0x98badcfe); + H3 = unchecked((int) 0x10325476); + + xOff = 0; + + for (int i = 0; i != X.Length; i++) + { + X[i] = 0; + } + } + + /* + * rotate int x left n bits. + */ + private int RL( + int x, + int n) + { + return (x << n) | (int) ((uint) x >> (32 - n)); + } + + /* + * f1,f2,f3,f4 are the basic RipeMD128 functions. + */ + + /* + * F + */ + private int F1( + int x, + int y, + int z) + { + return x ^ y ^ z; + } + + /* + * G + */ + private int F2( + int x, + int y, + int z) + { + return (x & y) | (~x & z); + } + + /* + * H + */ + private int F3( + int x, + int y, + int z) + { + return (x | ~y) ^ z; + } + + /* + * I + */ + private int F4( + int x, + int y, + int z) + { + return (x & z) | (y & ~z); + } + + private int F1( + int a, + int b, + int c, + int d, + int x, + int s) + { + return RL(a + F1(b, c, d) + x, s); + } + + private int F2( + int a, + int b, + int c, + int d, + int x, + int s) + { + return RL(a + F2(b, c, d) + x + unchecked((int) 0x5a827999), s); + } + + private int F3( + int a, + int b, + int c, + int d, + int x, + int s) + { + return RL(a + F3(b, c, d) + x + unchecked((int) 0x6ed9eba1), s); + } + + private int F4( + int a, + int b, + int c, + int d, + int x, + int s) + { + return RL(a + F4(b, c, d) + x + unchecked((int) 0x8f1bbcdc), s); + } + + private int FF1( + int a, + int b, + int c, + int d, + int x, + int s) + { + return RL(a + F1(b, c, d) + x, s); + } + + private int FF2( + int a, + int b, + int c, + int d, + int x, + int s) + { + return RL(a + F2(b, c, d) + x + unchecked((int) 0x6d703ef3), s); + } + + private int FF3( + int a, + int b, + int c, + int d, + int x, + int s) + { + return RL(a + F3(b, c, d) + x + unchecked((int) 0x5c4dd124), s); + } + + private int FF4( + int a, + int b, + int c, + int d, + int x, + int s) + { + return RL(a + F4(b, c, d) + x + unchecked((int) 0x50a28be6), s); + } + + internal override void ProcessBlock() + { + int a, aa; + int b, bb; + int c, cc; + int d, dd; + + a = aa = H0; + b = bb = H1; + c = cc = H2; + d = dd = H3; + + // + // Round 1 + // + a = F1(a, b, c, d, X[ 0], 11); + d = F1(d, a, b, c, X[ 1], 14); + c = F1(c, d, a, b, X[ 2], 15); + b = F1(b, c, d, a, X[ 3], 12); + a = F1(a, b, c, d, X[ 4], 5); + d = F1(d, a, b, c, X[ 5], 8); + c = F1(c, d, a, b, X[ 6], 7); + b = F1(b, c, d, a, X[ 7], 9); + a = F1(a, b, c, d, X[ 8], 11); + d = F1(d, a, b, c, X[ 9], 13); + c = F1(c, d, a, b, X[10], 14); + b = F1(b, c, d, a, X[11], 15); + a = F1(a, b, c, d, X[12], 6); + d = F1(d, a, b, c, X[13], 7); + c = F1(c, d, a, b, X[14], 9); + b = F1(b, c, d, a, X[15], 8); + + // + // Round 2 + // + a = F2(a, b, c, d, X[ 7], 7); + d = F2(d, a, b, c, X[ 4], 6); + c = F2(c, d, a, b, X[13], 8); + b = F2(b, c, d, a, X[ 1], 13); + a = F2(a, b, c, d, X[10], 11); + d = F2(d, a, b, c, X[ 6], 9); + c = F2(c, d, a, b, X[15], 7); + b = F2(b, c, d, a, X[ 3], 15); + a = F2(a, b, c, d, X[12], 7); + d = F2(d, a, b, c, X[ 0], 12); + c = F2(c, d, a, b, X[ 9], 15); + b = F2(b, c, d, a, X[ 5], 9); + a = F2(a, b, c, d, X[ 2], 11); + d = F2(d, a, b, c, X[14], 7); + c = F2(c, d, a, b, X[11], 13); + b = F2(b, c, d, a, X[ 8], 12); + + // + // Round 3 + // + a = F3(a, b, c, d, X[ 3], 11); + d = F3(d, a, b, c, X[10], 13); + c = F3(c, d, a, b, X[14], 6); + b = F3(b, c, d, a, X[ 4], 7); + a = F3(a, b, c, d, X[ 9], 14); + d = F3(d, a, b, c, X[15], 9); + c = F3(c, d, a, b, X[ 8], 13); + b = F3(b, c, d, a, X[ 1], 15); + a = F3(a, b, c, d, X[ 2], 14); + d = F3(d, a, b, c, X[ 7], 8); + c = F3(c, d, a, b, X[ 0], 13); + b = F3(b, c, d, a, X[ 6], 6); + a = F3(a, b, c, d, X[13], 5); + d = F3(d, a, b, c, X[11], 12); + c = F3(c, d, a, b, X[ 5], 7); + b = F3(b, c, d, a, X[12], 5); + + // + // Round 4 + // + a = F4(a, b, c, d, X[ 1], 11); + d = F4(d, a, b, c, X[ 9], 12); + c = F4(c, d, a, b, X[11], 14); + b = F4(b, c, d, a, X[10], 15); + a = F4(a, b, c, d, X[ 0], 14); + d = F4(d, a, b, c, X[ 8], 15); + c = F4(c, d, a, b, X[12], 9); + b = F4(b, c, d, a, X[ 4], 8); + a = F4(a, b, c, d, X[13], 9); + d = F4(d, a, b, c, X[ 3], 14); + c = F4(c, d, a, b, X[ 7], 5); + b = F4(b, c, d, a, X[15], 6); + a = F4(a, b, c, d, X[14], 8); + d = F4(d, a, b, c, X[ 5], 6); + c = F4(c, d, a, b, X[ 6], 5); + b = F4(b, c, d, a, X[ 2], 12); + + // + // Parallel round 1 + // + aa = FF4(aa, bb, cc, dd, X[ 5], 8); + dd = FF4(dd, aa, bb, cc, X[14], 9); + cc = FF4(cc, dd, aa, bb, X[ 7], 9); + bb = FF4(bb, cc, dd, aa, X[ 0], 11); + aa = FF4(aa, bb, cc, dd, X[ 9], 13); + dd = FF4(dd, aa, bb, cc, X[ 2], 15); + cc = FF4(cc, dd, aa, bb, X[11], 15); + bb = FF4(bb, cc, dd, aa, X[ 4], 5); + aa = FF4(aa, bb, cc, dd, X[13], 7); + dd = FF4(dd, aa, bb, cc, X[ 6], 7); + cc = FF4(cc, dd, aa, bb, X[15], 8); + bb = FF4(bb, cc, dd, aa, X[ 8], 11); + aa = FF4(aa, bb, cc, dd, X[ 1], 14); + dd = FF4(dd, aa, bb, cc, X[10], 14); + cc = FF4(cc, dd, aa, bb, X[ 3], 12); + bb = FF4(bb, cc, dd, aa, X[12], 6); + + // + // Parallel round 2 + // + aa = FF3(aa, bb, cc, dd, X[ 6], 9); + dd = FF3(dd, aa, bb, cc, X[11], 13); + cc = FF3(cc, dd, aa, bb, X[ 3], 15); + bb = FF3(bb, cc, dd, aa, X[ 7], 7); + aa = FF3(aa, bb, cc, dd, X[ 0], 12); + dd = FF3(dd, aa, bb, cc, X[13], 8); + cc = FF3(cc, dd, aa, bb, X[ 5], 9); + bb = FF3(bb, cc, dd, aa, X[10], 11); + aa = FF3(aa, bb, cc, dd, X[14], 7); + dd = FF3(dd, aa, bb, cc, X[15], 7); + cc = FF3(cc, dd, aa, bb, X[ 8], 12); + bb = FF3(bb, cc, dd, aa, X[12], 7); + aa = FF3(aa, bb, cc, dd, X[ 4], 6); + dd = FF3(dd, aa, bb, cc, X[ 9], 15); + cc = FF3(cc, dd, aa, bb, X[ 1], 13); + bb = FF3(bb, cc, dd, aa, X[ 2], 11); + + // + // Parallel round 3 + // + aa = FF2(aa, bb, cc, dd, X[15], 9); + dd = FF2(dd, aa, bb, cc, X[ 5], 7); + cc = FF2(cc, dd, aa, bb, X[ 1], 15); + bb = FF2(bb, cc, dd, aa, X[ 3], 11); + aa = FF2(aa, bb, cc, dd, X[ 7], 8); + dd = FF2(dd, aa, bb, cc, X[14], 6); + cc = FF2(cc, dd, aa, bb, X[ 6], 6); + bb = FF2(bb, cc, dd, aa, X[ 9], 14); + aa = FF2(aa, bb, cc, dd, X[11], 12); + dd = FF2(dd, aa, bb, cc, X[ 8], 13); + cc = FF2(cc, dd, aa, bb, X[12], 5); + bb = FF2(bb, cc, dd, aa, X[ 2], 14); + aa = FF2(aa, bb, cc, dd, X[10], 13); + dd = FF2(dd, aa, bb, cc, X[ 0], 13); + cc = FF2(cc, dd, aa, bb, X[ 4], 7); + bb = FF2(bb, cc, dd, aa, X[13], 5); + + // + // Parallel round 4 + // + aa = FF1(aa, bb, cc, dd, X[ 8], 15); + dd = FF1(dd, aa, bb, cc, X[ 6], 5); + cc = FF1(cc, dd, aa, bb, X[ 4], 8); + bb = FF1(bb, cc, dd, aa, X[ 1], 11); + aa = FF1(aa, bb, cc, dd, X[ 3], 14); + dd = FF1(dd, aa, bb, cc, X[11], 14); + cc = FF1(cc, dd, aa, bb, X[15], 6); + bb = FF1(bb, cc, dd, aa, X[ 0], 14); + aa = FF1(aa, bb, cc, dd, X[ 5], 6); + dd = FF1(dd, aa, bb, cc, X[12], 9); + cc = FF1(cc, dd, aa, bb, X[ 2], 12); + bb = FF1(bb, cc, dd, aa, X[13], 9); + aa = FF1(aa, bb, cc, dd, X[ 9], 12); + dd = FF1(dd, aa, bb, cc, X[ 7], 5); + cc = FF1(cc, dd, aa, bb, X[10], 15); + bb = FF1(bb, cc, dd, aa, X[14], 8); + + dd += c + H1; // final result for H0 + + // + // combine the results + // + H1 = H2 + d + aa; + H2 = H3 + a + bb; + H3 = H0 + b + cc; + H0 = dd; + + // + // reset the offset and clean out the word buffer. + // + xOff = 0; + for (int i = 0; i != X.Length; i++) + { + X[i] = 0; + } + } + + public override IMemoable Copy() + { + return new RipeMD128Digest(this); + } + + public override void Reset(IMemoable other) + { + RipeMD128Digest d = (RipeMD128Digest)other; + + CopyIn(d); + } + + } + +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/RipeMD128Digest.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/RipeMD128Digest.cs.meta new file mode 100644 index 0000000..bbcbda6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/RipeMD128Digest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9f8f81e96f438f449911106154674696 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/RipeMD160Digest.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/RipeMD160Digest.cs new file mode 100644 index 0000000..af4aa44 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/RipeMD160Digest.cs @@ -0,0 +1,445 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /** + * implementation of RipeMD see, + * http://www.esat.kuleuven.ac.be/~bosselae/ripemd160.html + */ + public class RipeMD160Digest + : GeneralDigest + { + private const int DigestLength = 20; + + private int H0, H1, H2, H3, H4; // IV's + + private int[] X = new int[16]; + private int xOff; + + /** + * Standard constructor + */ + public RipeMD160Digest() + { + Reset(); + } + + /** + * Copy constructor. This will copy the state of the provided + * message digest. + */ + public RipeMD160Digest(RipeMD160Digest t) : base(t) + { + CopyIn(t); + } + + private void CopyIn(RipeMD160Digest t) + { + base.CopyIn(t); + + H0 = t.H0; + H1 = t.H1; + H2 = t.H2; + H3 = t.H3; + H4 = t.H4; + + Array.Copy(t.X, 0, X, 0, t.X.Length); + xOff = t.xOff; + } + + public override string AlgorithmName + { + get { return "RIPEMD160"; } + } + + public override int GetDigestSize() + { + return DigestLength; + } + + internal override void ProcessWord( + byte[] input, + int inOff) + { + X[xOff++] = (input[inOff] & 0xff) | ((input[inOff + 1] & 0xff) << 8) + | ((input[inOff + 2] & 0xff) << 16) | ((input[inOff + 3] & 0xff) << 24); + + if (xOff == 16) + { + ProcessBlock(); + } + } + + internal override void ProcessLength( + long bitLength) + { + if (xOff > 14) + { + ProcessBlock(); + } + + X[14] = (int)(bitLength & 0xffffffff); + X[15] = (int)((ulong) bitLength >> 32); + } + + private void UnpackWord( + int word, + byte[] outBytes, + int outOff) + { + outBytes[outOff] = (byte)word; + outBytes[outOff + 1] = (byte)((uint) word >> 8); + outBytes[outOff + 2] = (byte)((uint) word >> 16); + outBytes[outOff + 3] = (byte)((uint) word >> 24); + } + + public override int DoFinal( + byte[] output, + int outOff) + { + Finish(); + + UnpackWord(H0, output, outOff); + UnpackWord(H1, output, outOff + 4); + UnpackWord(H2, output, outOff + 8); + UnpackWord(H3, output, outOff + 12); + UnpackWord(H4, output, outOff + 16); + + Reset(); + + return DigestLength; + } + + /** + * reset the chaining variables to the IV values. + */ + public override void Reset() + { + base.Reset(); + + H0 = unchecked((int) 0x67452301); + H1 = unchecked((int) 0xefcdab89); + H2 = unchecked((int) 0x98badcfe); + H3 = unchecked((int) 0x10325476); + H4 = unchecked((int) 0xc3d2e1f0); + + xOff = 0; + + for (int i = 0; i != X.Length; i++) + { + X[i] = 0; + } + } + + /* + * rotate int x left n bits. + */ + private int RL( + int x, + int n) + { + return (x << n) | (int) ((uint) x >> (32 - n)); + } + + /* + * f1,f2,f3,f4,f5 are the basic RipeMD160 functions. + */ + + /* + * rounds 0-15 + */ + private int F1( + int x, + int y, + int z) + { + return x ^ y ^ z; + } + + /* + * rounds 16-31 + */ + private int F2( + int x, + int y, + int z) + { + return (x & y) | (~x & z); + } + + /* + * rounds 32-47 + */ + private int F3( + int x, + int y, + int z) + { + return (x | ~y) ^ z; + } + + /* + * rounds 48-63 + */ + private int F4( + int x, + int y, + int z) + { + return (x & z) | (y & ~z); + } + + /* + * rounds 64-79 + */ + private int F5( + int x, + int y, + int z) + { + return x ^ (y | ~z); + } + + internal override void ProcessBlock() + { + int a, aa; + int b, bb; + int c, cc; + int d, dd; + int e, ee; + + a = aa = H0; + b = bb = H1; + c = cc = H2; + d = dd = H3; + e = ee = H4; + + // + // Rounds 1 - 16 + // + // left + a = RL(a + F1(b,c,d) + X[ 0], 11) + e; c = RL(c, 10); + e = RL(e + F1(a,b,c) + X[ 1], 14) + d; b = RL(b, 10); + d = RL(d + F1(e,a,b) + X[ 2], 15) + c; a = RL(a, 10); + c = RL(c + F1(d,e,a) + X[ 3], 12) + b; e = RL(e, 10); + b = RL(b + F1(c,d,e) + X[ 4], 5) + a; d = RL(d, 10); + a = RL(a + F1(b,c,d) + X[ 5], 8) + e; c = RL(c, 10); + e = RL(e + F1(a,b,c) + X[ 6], 7) + d; b = RL(b, 10); + d = RL(d + F1(e,a,b) + X[ 7], 9) + c; a = RL(a, 10); + c = RL(c + F1(d,e,a) + X[ 8], 11) + b; e = RL(e, 10); + b = RL(b + F1(c,d,e) + X[ 9], 13) + a; d = RL(d, 10); + a = RL(a + F1(b,c,d) + X[10], 14) + e; c = RL(c, 10); + e = RL(e + F1(a,b,c) + X[11], 15) + d; b = RL(b, 10); + d = RL(d + F1(e,a,b) + X[12], 6) + c; a = RL(a, 10); + c = RL(c + F1(d,e,a) + X[13], 7) + b; e = RL(e, 10); + b = RL(b + F1(c,d,e) + X[14], 9) + a; d = RL(d, 10); + a = RL(a + F1(b,c,d) + X[15], 8) + e; c = RL(c, 10); + + // right + aa = RL(aa + F5(bb,cc,dd) + X[ 5] + unchecked((int) 0x50a28be6), 8) + ee; cc = RL(cc, 10); + ee = RL(ee + F5(aa,bb,cc) + X[14] + unchecked((int) 0x50a28be6), 9) + dd; bb = RL(bb, 10); + dd = RL(dd + F5(ee,aa,bb) + X[ 7] + unchecked((int) 0x50a28be6), 9) + cc; aa = RL(aa, 10); + cc = RL(cc + F5(dd,ee,aa) + X[ 0] + unchecked((int) 0x50a28be6), 11) + bb; ee = RL(ee, 10); + bb = RL(bb + F5(cc,dd,ee) + X[ 9] + unchecked((int) 0x50a28be6), 13) + aa; dd = RL(dd, 10); + aa = RL(aa + F5(bb,cc,dd) + X[ 2] + unchecked((int) 0x50a28be6), 15) + ee; cc = RL(cc, 10); + ee = RL(ee + F5(aa,bb,cc) + X[11] + unchecked((int) 0x50a28be6), 15) + dd; bb = RL(bb, 10); + dd = RL(dd + F5(ee,aa,bb) + X[ 4] + unchecked((int) 0x50a28be6), 5) + cc; aa = RL(aa, 10); + cc = RL(cc + F5(dd,ee,aa) + X[13] + unchecked((int) 0x50a28be6), 7) + bb; ee = RL(ee, 10); + bb = RL(bb + F5(cc,dd,ee) + X[ 6] + unchecked((int) 0x50a28be6), 7) + aa; dd = RL(dd, 10); + aa = RL(aa + F5(bb,cc,dd) + X[15] + unchecked((int) 0x50a28be6), 8) + ee; cc = RL(cc, 10); + ee = RL(ee + F5(aa,bb,cc) + X[ 8] + unchecked((int) 0x50a28be6), 11) + dd; bb = RL(bb, 10); + dd = RL(dd + F5(ee,aa,bb) + X[ 1] + unchecked((int) 0x50a28be6), 14) + cc; aa = RL(aa, 10); + cc = RL(cc + F5(dd,ee,aa) + X[10] + unchecked((int) 0x50a28be6), 14) + bb; ee = RL(ee, 10); + bb = RL(bb + F5(cc,dd,ee) + X[ 3] + unchecked((int) 0x50a28be6), 12) + aa; dd = RL(dd, 10); + aa = RL(aa + F5(bb,cc,dd) + X[12] + unchecked((int) 0x50a28be6), 6) + ee; cc = RL(cc, 10); + + // + // Rounds 16-31 + // + // left + e = RL(e + F2(a,b,c) + X[ 7] + unchecked((int) 0x5a827999), 7) + d; b = RL(b, 10); + d = RL(d + F2(e,a,b) + X[ 4] + unchecked((int) 0x5a827999), 6) + c; a = RL(a, 10); + c = RL(c + F2(d,e,a) + X[13] + unchecked((int) 0x5a827999), 8) + b; e = RL(e, 10); + b = RL(b + F2(c,d,e) + X[ 1] + unchecked((int) 0x5a827999), 13) + a; d = RL(d, 10); + a = RL(a + F2(b,c,d) + X[10] + unchecked((int) 0x5a827999), 11) + e; c = RL(c, 10); + e = RL(e + F2(a,b,c) + X[ 6] + unchecked((int) 0x5a827999), 9) + d; b = RL(b, 10); + d = RL(d + F2(e,a,b) + X[15] + unchecked((int) 0x5a827999), 7) + c; a = RL(a, 10); + c = RL(c + F2(d,e,a) + X[ 3] + unchecked((int) 0x5a827999), 15) + b; e = RL(e, 10); + b = RL(b + F2(c,d,e) + X[12] + unchecked((int) 0x5a827999), 7) + a; d = RL(d, 10); + a = RL(a + F2(b,c,d) + X[ 0] + unchecked((int) 0x5a827999), 12) + e; c = RL(c, 10); + e = RL(e + F2(a,b,c) + X[ 9] + unchecked((int) 0x5a827999), 15) + d; b = RL(b, 10); + d = RL(d + F2(e,a,b) + X[ 5] + unchecked((int) 0x5a827999), 9) + c; a = RL(a, 10); + c = RL(c + F2(d,e,a) + X[ 2] + unchecked((int) 0x5a827999), 11) + b; e = RL(e, 10); + b = RL(b + F2(c,d,e) + X[14] + unchecked((int) 0x5a827999), 7) + a; d = RL(d, 10); + a = RL(a + F2(b,c,d) + X[11] + unchecked((int) 0x5a827999), 13) + e; c = RL(c, 10); + e = RL(e + F2(a,b,c) + X[ 8] + unchecked((int) 0x5a827999), 12) + d; b = RL(b, 10); + + // right + ee = RL(ee + F4(aa,bb,cc) + X[ 6] + unchecked((int) 0x5c4dd124), 9) + dd; bb = RL(bb, 10); + dd = RL(dd + F4(ee,aa,bb) + X[11] + unchecked((int) 0x5c4dd124), 13) + cc; aa = RL(aa, 10); + cc = RL(cc + F4(dd,ee,aa) + X[ 3] + unchecked((int) 0x5c4dd124), 15) + bb; ee = RL(ee, 10); + bb = RL(bb + F4(cc,dd,ee) + X[ 7] + unchecked((int) 0x5c4dd124), 7) + aa; dd = RL(dd, 10); + aa = RL(aa + F4(bb,cc,dd) + X[ 0] + unchecked((int) 0x5c4dd124), 12) + ee; cc = RL(cc, 10); + ee = RL(ee + F4(aa,bb,cc) + X[13] + unchecked((int) 0x5c4dd124), 8) + dd; bb = RL(bb, 10); + dd = RL(dd + F4(ee,aa,bb) + X[ 5] + unchecked((int) 0x5c4dd124), 9) + cc; aa = RL(aa, 10); + cc = RL(cc + F4(dd,ee,aa) + X[10] + unchecked((int) 0x5c4dd124), 11) + bb; ee = RL(ee, 10); + bb = RL(bb + F4(cc,dd,ee) + X[14] + unchecked((int) 0x5c4dd124), 7) + aa; dd = RL(dd, 10); + aa = RL(aa + F4(bb,cc,dd) + X[15] + unchecked((int) 0x5c4dd124), 7) + ee; cc = RL(cc, 10); + ee = RL(ee + F4(aa,bb,cc) + X[ 8] + unchecked((int) 0x5c4dd124), 12) + dd; bb = RL(bb, 10); + dd = RL(dd + F4(ee,aa,bb) + X[12] + unchecked((int) 0x5c4dd124), 7) + cc; aa = RL(aa, 10); + cc = RL(cc + F4(dd,ee,aa) + X[ 4] + unchecked((int) 0x5c4dd124), 6) + bb; ee = RL(ee, 10); + bb = RL(bb + F4(cc,dd,ee) + X[ 9] + unchecked((int) 0x5c4dd124), 15) + aa; dd = RL(dd, 10); + aa = RL(aa + F4(bb,cc,dd) + X[ 1] + unchecked((int) 0x5c4dd124), 13) + ee; cc = RL(cc, 10); + ee = RL(ee + F4(aa,bb,cc) + X[ 2] + unchecked((int) 0x5c4dd124), 11) + dd; bb = RL(bb, 10); + + // + // Rounds 32-47 + // + // left + d = RL(d + F3(e,a,b) + X[ 3] + unchecked((int) 0x6ed9eba1), 11) + c; a = RL(a, 10); + c = RL(c + F3(d,e,a) + X[10] + unchecked((int) 0x6ed9eba1), 13) + b; e = RL(e, 10); + b = RL(b + F3(c,d,e) + X[14] + unchecked((int) 0x6ed9eba1), 6) + a; d = RL(d, 10); + a = RL(a + F3(b,c,d) + X[ 4] + unchecked((int) 0x6ed9eba1), 7) + e; c = RL(c, 10); + e = RL(e + F3(a,b,c) + X[ 9] + unchecked((int) 0x6ed9eba1), 14) + d; b = RL(b, 10); + d = RL(d + F3(e,a,b) + X[15] + unchecked((int) 0x6ed9eba1), 9) + c; a = RL(a, 10); + c = RL(c + F3(d,e,a) + X[ 8] + unchecked((int) 0x6ed9eba1), 13) + b; e = RL(e, 10); + b = RL(b + F3(c,d,e) + X[ 1] + unchecked((int) 0x6ed9eba1), 15) + a; d = RL(d, 10); + a = RL(a + F3(b,c,d) + X[ 2] + unchecked((int) 0x6ed9eba1), 14) + e; c = RL(c, 10); + e = RL(e + F3(a,b,c) + X[ 7] + unchecked((int) 0x6ed9eba1), 8) + d; b = RL(b, 10); + d = RL(d + F3(e,a,b) + X[ 0] + unchecked((int) 0x6ed9eba1), 13) + c; a = RL(a, 10); + c = RL(c + F3(d,e,a) + X[ 6] + unchecked((int) 0x6ed9eba1), 6) + b; e = RL(e, 10); + b = RL(b + F3(c,d,e) + X[13] + unchecked((int) 0x6ed9eba1), 5) + a; d = RL(d, 10); + a = RL(a + F3(b,c,d) + X[11] + unchecked((int) 0x6ed9eba1), 12) + e; c = RL(c, 10); + e = RL(e + F3(a,b,c) + X[ 5] + unchecked((int) 0x6ed9eba1), 7) + d; b = RL(b, 10); + d = RL(d + F3(e,a,b) + X[12] + unchecked((int) 0x6ed9eba1), 5) + c; a = RL(a, 10); + + // right + dd = RL(dd + F3(ee,aa,bb) + X[15] + unchecked((int) 0x6d703ef3), 9) + cc; aa = RL(aa, 10); + cc = RL(cc + F3(dd,ee,aa) + X[ 5] + unchecked((int) 0x6d703ef3), 7) + bb; ee = RL(ee, 10); + bb = RL(bb + F3(cc,dd,ee) + X[ 1] + unchecked((int) 0x6d703ef3), 15) + aa; dd = RL(dd, 10); + aa = RL(aa + F3(bb,cc,dd) + X[ 3] + unchecked((int) 0x6d703ef3), 11) + ee; cc = RL(cc, 10); + ee = RL(ee + F3(aa,bb,cc) + X[ 7] + unchecked((int) 0x6d703ef3), 8) + dd; bb = RL(bb, 10); + dd = RL(dd + F3(ee,aa,bb) + X[14] + unchecked((int) 0x6d703ef3), 6) + cc; aa = RL(aa, 10); + cc = RL(cc + F3(dd,ee,aa) + X[ 6] + unchecked((int) 0x6d703ef3), 6) + bb; ee = RL(ee, 10); + bb = RL(bb + F3(cc,dd,ee) + X[ 9] + unchecked((int) 0x6d703ef3), 14) + aa; dd = RL(dd, 10); + aa = RL(aa + F3(bb,cc,dd) + X[11] + unchecked((int) 0x6d703ef3), 12) + ee; cc = RL(cc, 10); + ee = RL(ee + F3(aa,bb,cc) + X[ 8] + unchecked((int) 0x6d703ef3), 13) + dd; bb = RL(bb, 10); + dd = RL(dd + F3(ee,aa,bb) + X[12] + unchecked((int) 0x6d703ef3), 5) + cc; aa = RL(aa, 10); + cc = RL(cc + F3(dd,ee,aa) + X[ 2] + unchecked((int) 0x6d703ef3), 14) + bb; ee = RL(ee, 10); + bb = RL(bb + F3(cc,dd,ee) + X[10] + unchecked((int) 0x6d703ef3), 13) + aa; dd = RL(dd, 10); + aa = RL(aa + F3(bb,cc,dd) + X[ 0] + unchecked((int) 0x6d703ef3), 13) + ee; cc = RL(cc, 10); + ee = RL(ee + F3(aa,bb,cc) + X[ 4] + unchecked((int) 0x6d703ef3), 7) + dd; bb = RL(bb, 10); + dd = RL(dd + F3(ee,aa,bb) + X[13] + unchecked((int) 0x6d703ef3), 5) + cc; aa = RL(aa, 10); + + // + // Rounds 48-63 + // + // left + c = RL(c + F4(d,e,a) + X[ 1] + unchecked((int) 0x8f1bbcdc), 11) + b; e = RL(e, 10); + b = RL(b + F4(c,d,e) + X[ 9] + unchecked((int) 0x8f1bbcdc), 12) + a; d = RL(d, 10); + a = RL(a + F4(b,c,d) + X[11] + unchecked((int) 0x8f1bbcdc), 14) + e; c = RL(c, 10); + e = RL(e + F4(a,b,c) + X[10] + unchecked((int) 0x8f1bbcdc), 15) + d; b = RL(b, 10); + d = RL(d + F4(e,a,b) + X[ 0] + unchecked((int) 0x8f1bbcdc), 14) + c; a = RL(a, 10); + c = RL(c + F4(d,e,a) + X[ 8] + unchecked((int) 0x8f1bbcdc), 15) + b; e = RL(e, 10); + b = RL(b + F4(c,d,e) + X[12] + unchecked((int) 0x8f1bbcdc), 9) + a; d = RL(d, 10); + a = RL(a + F4(b,c,d) + X[ 4] + unchecked((int) 0x8f1bbcdc), 8) + e; c = RL(c, 10); + e = RL(e + F4(a,b,c) + X[13] + unchecked((int) 0x8f1bbcdc), 9) + d; b = RL(b, 10); + d = RL(d + F4(e,a,b) + X[ 3] + unchecked((int) 0x8f1bbcdc), 14) + c; a = RL(a, 10); + c = RL(c + F4(d,e,a) + X[ 7] + unchecked((int) 0x8f1bbcdc), 5) + b; e = RL(e, 10); + b = RL(b + F4(c,d,e) + X[15] + unchecked((int) 0x8f1bbcdc), 6) + a; d = RL(d, 10); + a = RL(a + F4(b,c,d) + X[14] + unchecked((int) 0x8f1bbcdc), 8) + e; c = RL(c, 10); + e = RL(e + F4(a,b,c) + X[ 5] + unchecked((int) 0x8f1bbcdc), 6) + d; b = RL(b, 10); + d = RL(d + F4(e,a,b) + X[ 6] + unchecked((int) 0x8f1bbcdc), 5) + c; a = RL(a, 10); + c = RL(c + F4(d,e,a) + X[ 2] + unchecked((int) 0x8f1bbcdc), 12) + b; e = RL(e, 10); + + // right + cc = RL(cc + F2(dd,ee,aa) + X[ 8] + unchecked((int) 0x7a6d76e9), 15) + bb; ee = RL(ee, 10); + bb = RL(bb + F2(cc,dd,ee) + X[ 6] + unchecked((int) 0x7a6d76e9), 5) + aa; dd = RL(dd, 10); + aa = RL(aa + F2(bb,cc,dd) + X[ 4] + unchecked((int) 0x7a6d76e9), 8) + ee; cc = RL(cc, 10); + ee = RL(ee + F2(aa,bb,cc) + X[ 1] + unchecked((int) 0x7a6d76e9), 11) + dd; bb = RL(bb, 10); + dd = RL(dd + F2(ee,aa,bb) + X[ 3] + unchecked((int) 0x7a6d76e9), 14) + cc; aa = RL(aa, 10); + cc = RL(cc + F2(dd,ee,aa) + X[11] + unchecked((int) 0x7a6d76e9), 14) + bb; ee = RL(ee, 10); + bb = RL(bb + F2(cc,dd,ee) + X[15] + unchecked((int) 0x7a6d76e9), 6) + aa; dd = RL(dd, 10); + aa = RL(aa + F2(bb,cc,dd) + X[ 0] + unchecked((int) 0x7a6d76e9), 14) + ee; cc = RL(cc, 10); + ee = RL(ee + F2(aa,bb,cc) + X[ 5] + unchecked((int) 0x7a6d76e9), 6) + dd; bb = RL(bb, 10); + dd = RL(dd + F2(ee,aa,bb) + X[12] + unchecked((int) 0x7a6d76e9), 9) + cc; aa = RL(aa, 10); + cc = RL(cc + F2(dd,ee,aa) + X[ 2] + unchecked((int) 0x7a6d76e9), 12) + bb; ee = RL(ee, 10); + bb = RL(bb + F2(cc,dd,ee) + X[13] + unchecked((int) 0x7a6d76e9), 9) + aa; dd = RL(dd, 10); + aa = RL(aa + F2(bb,cc,dd) + X[ 9] + unchecked((int) 0x7a6d76e9), 12) + ee; cc = RL(cc, 10); + ee = RL(ee + F2(aa,bb,cc) + X[ 7] + unchecked((int) 0x7a6d76e9), 5) + dd; bb = RL(bb, 10); + dd = RL(dd + F2(ee,aa,bb) + X[10] + unchecked((int) 0x7a6d76e9), 15) + cc; aa = RL(aa, 10); + cc = RL(cc + F2(dd,ee,aa) + X[14] + unchecked((int) 0x7a6d76e9), 8) + bb; ee = RL(ee, 10); + + // + // Rounds 64-79 + // + // left + b = RL(b + F5(c,d,e) + X[ 4] + unchecked((int) 0xa953fd4e), 9) + a; d = RL(d, 10); + a = RL(a + F5(b,c,d) + X[ 0] + unchecked((int) 0xa953fd4e), 15) + e; c = RL(c, 10); + e = RL(e + F5(a,b,c) + X[ 5] + unchecked((int) 0xa953fd4e), 5) + d; b = RL(b, 10); + d = RL(d + F5(e,a,b) + X[ 9] + unchecked((int) 0xa953fd4e), 11) + c; a = RL(a, 10); + c = RL(c + F5(d,e,a) + X[ 7] + unchecked((int) 0xa953fd4e), 6) + b; e = RL(e, 10); + b = RL(b + F5(c,d,e) + X[12] + unchecked((int) 0xa953fd4e), 8) + a; d = RL(d, 10); + a = RL(a + F5(b,c,d) + X[ 2] + unchecked((int) 0xa953fd4e), 13) + e; c = RL(c, 10); + e = RL(e + F5(a,b,c) + X[10] + unchecked((int) 0xa953fd4e), 12) + d; b = RL(b, 10); + d = RL(d + F5(e,a,b) + X[14] + unchecked((int) 0xa953fd4e), 5) + c; a = RL(a, 10); + c = RL(c + F5(d,e,a) + X[ 1] + unchecked((int) 0xa953fd4e), 12) + b; e = RL(e, 10); + b = RL(b + F5(c,d,e) + X[ 3] + unchecked((int) 0xa953fd4e), 13) + a; d = RL(d, 10); + a = RL(a + F5(b,c,d) + X[ 8] + unchecked((int) 0xa953fd4e), 14) + e; c = RL(c, 10); + e = RL(e + F5(a,b,c) + X[11] + unchecked((int) 0xa953fd4e), 11) + d; b = RL(b, 10); + d = RL(d + F5(e,a,b) + X[ 6] + unchecked((int) 0xa953fd4e), 8) + c; a = RL(a, 10); + c = RL(c + F5(d,e,a) + X[15] + unchecked((int) 0xa953fd4e), 5) + b; e = RL(e, 10); + b = RL(b + F5(c,d,e) + X[13] + unchecked((int) 0xa953fd4e), 6) + a; d = RL(d, 10); + + // right + bb = RL(bb + F1(cc,dd,ee) + X[12], 8) + aa; dd = RL(dd, 10); + aa = RL(aa + F1(bb,cc,dd) + X[15], 5) + ee; cc = RL(cc, 10); + ee = RL(ee + F1(aa,bb,cc) + X[10], 12) + dd; bb = RL(bb, 10); + dd = RL(dd + F1(ee,aa,bb) + X[ 4], 9) + cc; aa = RL(aa, 10); + cc = RL(cc + F1(dd,ee,aa) + X[ 1], 12) + bb; ee = RL(ee, 10); + bb = RL(bb + F1(cc,dd,ee) + X[ 5], 5) + aa; dd = RL(dd, 10); + aa = RL(aa + F1(bb,cc,dd) + X[ 8], 14) + ee; cc = RL(cc, 10); + ee = RL(ee + F1(aa,bb,cc) + X[ 7], 6) + dd; bb = RL(bb, 10); + dd = RL(dd + F1(ee,aa,bb) + X[ 6], 8) + cc; aa = RL(aa, 10); + cc = RL(cc + F1(dd,ee,aa) + X[ 2], 13) + bb; ee = RL(ee, 10); + bb = RL(bb + F1(cc,dd,ee) + X[13], 6) + aa; dd = RL(dd, 10); + aa = RL(aa + F1(bb,cc,dd) + X[14], 5) + ee; cc = RL(cc, 10); + ee = RL(ee + F1(aa,bb,cc) + X[ 0], 15) + dd; bb = RL(bb, 10); + dd = RL(dd + F1(ee,aa,bb) + X[ 3], 13) + cc; aa = RL(aa, 10); + cc = RL(cc + F1(dd,ee,aa) + X[ 9], 11) + bb; ee = RL(ee, 10); + bb = RL(bb + F1(cc,dd,ee) + X[11], 11) + aa; dd = RL(dd, 10); + + dd += c + H1; + H1 = H2 + d + ee; + H2 = H3 + e + aa; + H3 = H4 + a + bb; + H4 = H0 + b + cc; + H0 = dd; + + // + // reset the offset and clean out the word buffer. + // + xOff = 0; + for (int i = 0; i != X.Length; i++) + { + X[i] = 0; + } + } + + public override IMemoable Copy() + { + return new RipeMD160Digest(this); + } + + public override void Reset(IMemoable other) + { + RipeMD160Digest d = (RipeMD160Digest)other; + + CopyIn(d); + } + + } + +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/RipeMD160Digest.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/RipeMD160Digest.cs.meta new file mode 100644 index 0000000..4272d9d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/RipeMD160Digest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f266d6b5f259a784cb3980abfce33021 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/RipeMD256Digest.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/RipeMD256Digest.cs new file mode 100644 index 0000000..3062757 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/RipeMD256Digest.cs @@ -0,0 +1,430 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /// + ///

Implementation of RipeMD256.

+ ///

Note: this algorithm offers the same level of security as RipeMD128.

+ ///
+ public class RipeMD256Digest + : GeneralDigest + { + public override string AlgorithmName + { + get { return "RIPEMD256"; } + } + + public override int GetDigestSize() + { + return DigestLength; + } + + private const int DigestLength = 32; + + private int H0, H1, H2, H3, H4, H5, H6, H7; // IV's + + private int[] X = new int[16]; + private int xOff; + + /// Standard constructor + public RipeMD256Digest() + { + Reset(); + } + + /// Copy constructor. This will copy the state of the provided + /// message digest. + /// + public RipeMD256Digest(RipeMD256Digest t):base(t) + { + CopyIn(t); + } + + private void CopyIn(RipeMD256Digest t) + { + base.CopyIn(t); + + H0 = t.H0; + H1 = t.H1; + H2 = t.H2; + H3 = t.H3; + H4 = t.H4; + H5 = t.H5; + H6 = t.H6; + H7 = t.H7; + + Array.Copy(t.X, 0, X, 0, t.X.Length); + xOff = t.xOff; + } + + internal override void ProcessWord( + byte[] input, + int inOff) + { + X[xOff++] = (input[inOff] & 0xff) | ((input[inOff + 1] & 0xff) << 8) + | ((input[inOff + 2] & 0xff) << 16) | ((input[inOff + 3] & 0xff) << 24); + + if (xOff == 16) + { + ProcessBlock(); + } + } + + internal override void ProcessLength( + long bitLength) + { + if (xOff > 14) + { + ProcessBlock(); + } + + X[14] = (int)(bitLength & 0xffffffff); + X[15] = (int)((ulong)bitLength >> 32); + } + + private void UnpackWord( + int word, + byte[] outBytes, + int outOff) + { + outBytes[outOff] = (byte)(uint)word; + outBytes[outOff + 1] = (byte)((uint)word >> 8); + outBytes[outOff + 2] = (byte)((uint)word >> 16); + outBytes[outOff + 3] = (byte)((uint)word >> 24); + } + + public override int DoFinal(byte[] output, int outOff) + { + Finish(); + + UnpackWord(H0, output, outOff); + UnpackWord(H1, output, outOff + 4); + UnpackWord(H2, output, outOff + 8); + UnpackWord(H3, output, outOff + 12); + UnpackWord(H4, output, outOff + 16); + UnpackWord(H5, output, outOff + 20); + UnpackWord(H6, output, outOff + 24); + UnpackWord(H7, output, outOff + 28); + + Reset(); + + return DigestLength; + } + + /// reset the chaining variables to the IV values. + public override void Reset() + { + base.Reset(); + + H0 = unchecked((int)0x67452301); + H1 = unchecked((int)0xefcdab89); + H2 = unchecked((int)0x98badcfe); + H3 = unchecked((int)0x10325476); + H4 = unchecked((int)0x76543210); + H5 = unchecked((int)0xFEDCBA98); + H6 = unchecked((int)0x89ABCDEF); + H7 = unchecked((int)0x01234567); + + xOff = 0; + + for (int i = 0; i != X.Length; i++) + { + X[i] = 0; + } + } + + /* + * rotate int x left n bits. + */ + private int RL( + int x, + int n) + { + return (x << n) | (int)((uint)x >> (32 - n)); + } + + /* + * f1,f2,f3,f4 are the basic RipeMD128 functions. + */ + + /* + * F + */ + private int F1(int x, int y, int z) + { + return x ^ y ^ z; + } + + /* + * G + */ + private int F2(int x, int y, int z) + { + return (x & y) | (~ x & z); + } + + /* + * H + */ + private int F3(int x, int y, int z) + { + return (x | ~ y) ^ z; + } + + /* + * I + */ + private int F4(int x, int y, int z) + { + return (x & z) | (y & ~ z); + } + + private int F1(int a, int b, int c, int d, int x, int s) + { + return RL(a + F1(b, c, d) + x, s); + } + + private int F2(int a, int b, int c, int d, int x, int s) + { + return RL(a + F2(b, c, d) + x + unchecked((int)0x5a827999), s); + } + + private int F3(int a, int b, int c, int d, int x, int s) + { + return RL(a + F3(b, c, d) + x + unchecked((int)0x6ed9eba1), s); + } + + private int F4(int a, int b, int c, int d, int x, int s) + { + return RL(a + F4(b, c, d) + x + unchecked((int)0x8f1bbcdc), s); + } + + private int FF1(int a, int b, int c, int d, int x, int s) + { + return RL(a + F1(b, c, d) + x, s); + } + + private int FF2(int a, int b, int c, int d, int x, int s) + { + return RL(a + F2(b, c, d) + x + unchecked((int)0x6d703ef3), s); + } + + private int FF3(int a, int b, int c, int d, int x, int s) + { + return RL(a + F3(b, c, d) + x + unchecked((int)0x5c4dd124), s); + } + + private int FF4(int a, int b, int c, int d, int x, int s) + { + return RL(a + F4(b, c, d) + x + unchecked((int)0x50a28be6), s); + } + + internal override void ProcessBlock() + { + int a, aa; + int b, bb; + int c, cc; + int d, dd; + int t; + + a = H0; + b = H1; + c = H2; + d = H3; + aa = H4; + bb = H5; + cc = H6; + dd = H7; + + // + // Round 1 + // + + a = F1(a, b, c, d, X[0], 11); + d = F1(d, a, b, c, X[1], 14); + c = F1(c, d, a, b, X[2], 15); + b = F1(b, c, d, a, X[3], 12); + a = F1(a, b, c, d, X[4], 5); + d = F1(d, a, b, c, X[5], 8); + c = F1(c, d, a, b, X[6], 7); + b = F1(b, c, d, a, X[7], 9); + a = F1(a, b, c, d, X[8], 11); + d = F1(d, a, b, c, X[9], 13); + c = F1(c, d, a, b, X[10], 14); + b = F1(b, c, d, a, X[11], 15); + a = F1(a, b, c, d, X[12], 6); + d = F1(d, a, b, c, X[13], 7); + c = F1(c, d, a, b, X[14], 9); + b = F1(b, c, d, a, X[15], 8); + + aa = FF4(aa, bb, cc, dd, X[5], 8); + dd = FF4(dd, aa, bb, cc, X[14], 9); + cc = FF4(cc, dd, aa, bb, X[7], 9); + bb = FF4(bb, cc, dd, aa, X[0], 11); + aa = FF4(aa, bb, cc, dd, X[9], 13); + dd = FF4(dd, aa, bb, cc, X[2], 15); + cc = FF4(cc, dd, aa, bb, X[11], 15); + bb = FF4(bb, cc, dd, aa, X[4], 5); + aa = FF4(aa, bb, cc, dd, X[13], 7); + dd = FF4(dd, aa, bb, cc, X[6], 7); + cc = FF4(cc, dd, aa, bb, X[15], 8); + bb = FF4(bb, cc, dd, aa, X[8], 11); + aa = FF4(aa, bb, cc, dd, X[1], 14); + dd = FF4(dd, aa, bb, cc, X[10], 14); + cc = FF4(cc, dd, aa, bb, X[3], 12); + bb = FF4(bb, cc, dd, aa, X[12], 6); + + t = a; a = aa; aa = t; + + // + // Round 2 + // + a = F2(a, b, c, d, X[7], 7); + d = F2(d, a, b, c, X[4], 6); + c = F2(c, d, a, b, X[13], 8); + b = F2(b, c, d, a, X[1], 13); + a = F2(a, b, c, d, X[10], 11); + d = F2(d, a, b, c, X[6], 9); + c = F2(c, d, a, b, X[15], 7); + b = F2(b, c, d, a, X[3], 15); + a = F2(a, b, c, d, X[12], 7); + d = F2(d, a, b, c, X[0], 12); + c = F2(c, d, a, b, X[9], 15); + b = F2(b, c, d, a, X[5], 9); + a = F2(a, b, c, d, X[2], 11); + d = F2(d, a, b, c, X[14], 7); + c = F2(c, d, a, b, X[11], 13); + b = F2(b, c, d, a, X[8], 12); + + aa = FF3(aa, bb, cc, dd, X[6], 9); + dd = FF3(dd, aa, bb, cc, X[11], 13); + cc = FF3(cc, dd, aa, bb, X[3], 15); + bb = FF3(bb, cc, dd, aa, X[7], 7); + aa = FF3(aa, bb, cc, dd, X[0], 12); + dd = FF3(dd, aa, bb, cc, X[13], 8); + cc = FF3(cc, dd, aa, bb, X[5], 9); + bb = FF3(bb, cc, dd, aa, X[10], 11); + aa = FF3(aa, bb, cc, dd, X[14], 7); + dd = FF3(dd, aa, bb, cc, X[15], 7); + cc = FF3(cc, dd, aa, bb, X[8], 12); + bb = FF3(bb, cc, dd, aa, X[12], 7); + aa = FF3(aa, bb, cc, dd, X[4], 6); + dd = FF3(dd, aa, bb, cc, X[9], 15); + cc = FF3(cc, dd, aa, bb, X[1], 13); + bb = FF3(bb, cc, dd, aa, X[2], 11); + + t = b; b = bb; bb = t; + + // + // Round 3 + // + a = F3(a, b, c, d, X[3], 11); + d = F3(d, a, b, c, X[10], 13); + c = F3(c, d, a, b, X[14], 6); + b = F3(b, c, d, a, X[4], 7); + a = F3(a, b, c, d, X[9], 14); + d = F3(d, a, b, c, X[15], 9); + c = F3(c, d, a, b, X[8], 13); + b = F3(b, c, d, a, X[1], 15); + a = F3(a, b, c, d, X[2], 14); + d = F3(d, a, b, c, X[7], 8); + c = F3(c, d, a, b, X[0], 13); + b = F3(b, c, d, a, X[6], 6); + a = F3(a, b, c, d, X[13], 5); + d = F3(d, a, b, c, X[11], 12); + c = F3(c, d, a, b, X[5], 7); + b = F3(b, c, d, a, X[12], 5); + + aa = FF2(aa, bb, cc, dd, X[15], 9); + dd = FF2(dd, aa, bb, cc, X[5], 7); + cc = FF2(cc, dd, aa, bb, X[1], 15); + bb = FF2(bb, cc, dd, aa, X[3], 11); + aa = FF2(aa, bb, cc, dd, X[7], 8); + dd = FF2(dd, aa, bb, cc, X[14], 6); + cc = FF2(cc, dd, aa, bb, X[6], 6); + bb = FF2(bb, cc, dd, aa, X[9], 14); + aa = FF2(aa, bb, cc, dd, X[11], 12); + dd = FF2(dd, aa, bb, cc, X[8], 13); + cc = FF2(cc, dd, aa, bb, X[12], 5); + bb = FF2(bb, cc, dd, aa, X[2], 14); + aa = FF2(aa, bb, cc, dd, X[10], 13); + dd = FF2(dd, aa, bb, cc, X[0], 13); + cc = FF2(cc, dd, aa, bb, X[4], 7); + bb = FF2(bb, cc, dd, aa, X[13], 5); + + t = c; c = cc; cc = t; + + // + // Round 4 + // + a = F4(a, b, c, d, X[1], 11); + d = F4(d, a, b, c, X[9], 12); + c = F4(c, d, a, b, X[11], 14); + b = F4(b, c, d, a, X[10], 15); + a = F4(a, b, c, d, X[0], 14); + d = F4(d, a, b, c, X[8], 15); + c = F4(c, d, a, b, X[12], 9); + b = F4(b, c, d, a, X[4], 8); + a = F4(a, b, c, d, X[13], 9); + d = F4(d, a, b, c, X[3], 14); + c = F4(c, d, a, b, X[7], 5); + b = F4(b, c, d, a, X[15], 6); + a = F4(a, b, c, d, X[14], 8); + d = F4(d, a, b, c, X[5], 6); + c = F4(c, d, a, b, X[6], 5); + b = F4(b, c, d, a, X[2], 12); + + aa = FF1(aa, bb, cc, dd, X[8], 15); + dd = FF1(dd, aa, bb, cc, X[6], 5); + cc = FF1(cc, dd, aa, bb, X[4], 8); + bb = FF1(bb, cc, dd, aa, X[1], 11); + aa = FF1(aa, bb, cc, dd, X[3], 14); + dd = FF1(dd, aa, bb, cc, X[11], 14); + cc = FF1(cc, dd, aa, bb, X[15], 6); + bb = FF1(bb, cc, dd, aa, X[0], 14); + aa = FF1(aa, bb, cc, dd, X[5], 6); + dd = FF1(dd, aa, bb, cc, X[12], 9); + cc = FF1(cc, dd, aa, bb, X[2], 12); + bb = FF1(bb, cc, dd, aa, X[13], 9); + aa = FF1(aa, bb, cc, dd, X[9], 12); + dd = FF1(dd, aa, bb, cc, X[7], 5); + cc = FF1(cc, dd, aa, bb, X[10], 15); + bb = FF1(bb, cc, dd, aa, X[14], 8); + + t = d; d = dd; dd = t; + + H0 += a; + H1 += b; + H2 += c; + H3 += d; + H4 += aa; + H5 += bb; + H6 += cc; + H7 += dd; + + // + // reset the offset and clean out the word buffer. + // + xOff = 0; + for (int i = 0; i != X.Length; i++) + { + X[i] = 0; + } + } + + public override IMemoable Copy() + { + return new RipeMD256Digest(this); + } + + public override void Reset(IMemoable other) + { + RipeMD256Digest d = (RipeMD256Digest)other; + + CopyIn(d); + } + + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/RipeMD256Digest.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/RipeMD256Digest.cs.meta new file mode 100644 index 0000000..96d16c2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/RipeMD256Digest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f02d6f779ed0bba45a4c9006536b3cd4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/RipeMD320Digest.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/RipeMD320Digest.cs new file mode 100644 index 0000000..767d74d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/RipeMD320Digest.cs @@ -0,0 +1,459 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /// + ///

Implementation of RipeMD 320.

+ ///

Note: this algorithm offers the same level of security as RipeMD160.

+ ///
+ public class RipeMD320Digest + : GeneralDigest + { + public override string AlgorithmName + { + get { return "RIPEMD320"; } + } + + public override int GetDigestSize() + { + return DigestLength; + } + + private const int DigestLength = 40; + + private int H0, H1, H2, H3, H4, H5, H6, H7, H8, H9; // IV's + + private int[] X = new int[16]; + private int xOff; + + /// Standard constructor + public RipeMD320Digest() + { + Reset(); + } + + /// Copy constructor. This will copy the state of the provided + /// message digest. + /// + public RipeMD320Digest(RipeMD320Digest t) + : base(t) + { + CopyIn(t); + } + + private void CopyIn(RipeMD320Digest t) + { + base.CopyIn(t); + + H0 = t.H0; + H1 = t.H1; + H2 = t.H2; + H3 = t.H3; + H4 = t.H4; + H5 = t.H5; + H6 = t.H6; + H7 = t.H7; + H8 = t.H8; + H9 = t.H9; + + Array.Copy(t.X, 0, X, 0, t.X.Length); + xOff = t.xOff; + } + + internal override void ProcessWord( + byte[] input, + int inOff) + { + X[xOff++] = (input[inOff] & 0xff) | ((input[inOff + 1] & 0xff) << 8) + | ((input[inOff + 2] & 0xff) << 16) | ((input[inOff + 3] & 0xff) << 24); + + if (xOff == 16) + { + ProcessBlock(); + } + } + + internal override void ProcessLength( + long bitLength) + { + if (xOff > 14) + { + ProcessBlock(); + } + + X[14] = (int)(bitLength & 0xffffffff); + X[15] = (int)((ulong)bitLength >> 32); + } + + private void UnpackWord( + int word, + byte[] outBytes, + int outOff) + { + outBytes[outOff] = (byte)word; + outBytes[outOff + 1] = (byte)((uint)word >> 8); + outBytes[outOff + 2] = (byte)((uint)word >> 16); + outBytes[outOff + 3] = (byte)((uint)word >> 24); + } + + public override int DoFinal(byte[] output, int outOff) + { + Finish(); + + UnpackWord(H0, output, outOff); + UnpackWord(H1, output, outOff + 4); + UnpackWord(H2, output, outOff + 8); + UnpackWord(H3, output, outOff + 12); + UnpackWord(H4, output, outOff + 16); + UnpackWord(H5, output, outOff + 20); + UnpackWord(H6, output, outOff + 24); + UnpackWord(H7, output, outOff + 28); + UnpackWord(H8, output, outOff + 32); + UnpackWord(H9, output, outOff + 36); + + Reset(); + + return DigestLength; + } + + /// reset the chaining variables to the IV values. + public override void Reset() + { + base.Reset(); + + H0 = unchecked((int) 0x67452301); + H1 = unchecked((int) 0xefcdab89); + H2 = unchecked((int) 0x98badcfe); + H3 = unchecked((int) 0x10325476); + H4 = unchecked((int) 0xc3d2e1f0); + H5 = unchecked((int) 0x76543210); + H6 = unchecked((int) 0xFEDCBA98); + H7 = unchecked((int) 0x89ABCDEF); + H8 = unchecked((int) 0x01234567); + H9 = unchecked((int) 0x3C2D1E0F); + + xOff = 0; + + for (int i = 0; i != X.Length; i++) + { + X[i] = 0; + } + } + + /* + * rotate int x left n bits. + */ + private int RL( + int x, + int n) + { + return (x << n) | (int)(((uint)x) >> (32 - n)); + } + + /* + * f1,f2,f3,f4,f5 are the basic RipeMD160 functions. + */ + + /* + * rounds 0-15 + */ + private int F1(int x, int y, int z) + { + return x ^ y ^ z; + } + + /* + * rounds 16-31 + */ + private int F2(int x, int y, int z) + { + return (x & y) | (~ x & z); + } + + /* + * rounds 32-47 + */ + private int F3(int x, int y, int z) + { + return (x | ~ y) ^ z; + } + + /* + * rounds 48-63 + */ + private int F4(int x, int y, int z) + { + return (x & z) | (y & ~ z); + } + + /* + * rounds 64-79 + */ + private int F5(int x, int y, int z) + { + return x ^ (y | ~z); + } + + internal override void ProcessBlock() + { + int a, aa; + int b, bb; + int c, cc; + int d, dd; + int e, ee; + int t; + + a = H0; + b = H1; + c = H2; + d = H3; + e = H4; + aa = H5; + bb = H6; + cc = H7; + dd = H8; + ee = H9; + + // + // Rounds 1 - 16 + // + // left + a = RL(a + F1(b, c, d) + X[0], 11) + e; c = RL(c, 10); + e = RL(e + F1(a, b, c) + X[1], 14) + d; b = RL(b, 10); + d = RL(d + F1(e, a, b) + X[2], 15) + c; a = RL(a, 10); + c = RL(c + F1(d, e, a) + X[3], 12) + b; e = RL(e, 10); + b = RL(b + F1(c, d, e) + X[4], 5) + a; d = RL(d, 10); + a = RL(a + F1(b, c, d) + X[5], 8) + e; c = RL(c, 10); + e = RL(e + F1(a, b, c) + X[6], 7) + d; b = RL(b, 10); + d = RL(d + F1(e, a, b) + X[7], 9) + c; a = RL(a, 10); + c = RL(c + F1(d, e, a) + X[8], 11) + b; e = RL(e, 10); + b = RL(b + F1(c, d, e) + X[9], 13) + a; d = RL(d, 10); + a = RL(a + F1(b, c, d) + X[10], 14) + e; c = RL(c, 10); + e = RL(e + F1(a, b, c) + X[11], 15) + d; b = RL(b, 10); + d = RL(d + F1(e, a, b) + X[12], 6) + c; a = RL(a, 10); + c = RL(c + F1(d, e, a) + X[13], 7) + b; e = RL(e, 10); + b = RL(b + F1(c, d, e) + X[14], 9) + a; d = RL(d, 10); + a = RL(a + F1(b, c, d) + X[15], 8) + e; c = RL(c, 10); + + // right + aa = RL(aa + F5(bb, cc, dd) + X[5] + unchecked((int)0x50a28be6), 8) + ee; cc = RL(cc, 10); + ee = RL(ee + F5(aa, bb, cc) + X[14] + unchecked((int)0x50a28be6), 9) + dd; bb = RL(bb, 10); + dd = RL(dd + F5(ee, aa, bb) + X[7] + unchecked((int)0x50a28be6), 9) + cc; aa = RL(aa, 10); + cc = RL(cc + F5(dd, ee, aa) + X[0] + unchecked((int)0x50a28be6), 11) + bb; ee = RL(ee, 10); + bb = RL(bb + F5(cc, dd, ee) + X[9] + unchecked((int)0x50a28be6), 13) + aa; dd = RL(dd, 10); + aa = RL(aa + F5(bb, cc, dd) + X[2] + unchecked((int)0x50a28be6), 15) + ee; cc = RL(cc, 10); + ee = RL(ee + F5(aa, bb, cc) + X[11] + unchecked((int)0x50a28be6), 15) + dd; bb = RL(bb, 10); + dd = RL(dd + F5(ee, aa, bb) + X[4] + unchecked((int)0x50a28be6), 5) + cc; aa = RL(aa, 10); + cc = RL(cc + F5(dd, ee, aa) + X[13] + unchecked((int)0x50a28be6), 7) + bb; ee = RL(ee, 10); + bb = RL(bb + F5(cc, dd, ee) + X[6] + unchecked((int)0x50a28be6), 7) + aa; dd = RL(dd, 10); + aa = RL(aa + F5(bb, cc, dd) + X[15] + unchecked((int)0x50a28be6), 8) + ee; cc = RL(cc, 10); + ee = RL(ee + F5(aa, bb, cc) + X[8] + unchecked((int)0x50a28be6), 11) + dd; bb = RL(bb, 10); + dd = RL(dd + F5(ee, aa, bb) + X[1] + unchecked((int)0x50a28be6), 14) + cc; aa = RL(aa, 10); + cc = RL(cc + F5(dd, ee, aa) + X[10] + unchecked((int)0x50a28be6), 14) + bb; ee = RL(ee, 10); + bb = RL(bb + F5(cc, dd, ee) + X[3] + unchecked((int)0x50a28be6), 12) + aa; dd = RL(dd, 10); + aa = RL(aa + F5(bb, cc, dd) + X[12] + unchecked((int)0x50a28be6), 6) + ee; cc = RL(cc, 10); + + t = a; a = aa; aa = t; + // + // Rounds 16-31 + // + // left + e = RL(e + F2(a, b, c) + X[7] + unchecked((int)0x5a827999), 7) + d; b = RL(b, 10); + d = RL(d + F2(e, a, b) + X[4] + unchecked((int)0x5a827999), 6) + c; a = RL(a, 10); + c = RL(c + F2(d, e, a) + X[13] + unchecked((int)0x5a827999), 8) + b; e = RL(e, 10); + b = RL(b + F2(c, d, e) + X[1] + unchecked((int)0x5a827999), 13) + a; d = RL(d, 10); + a = RL(a + F2(b, c, d) + X[10] + unchecked((int)0x5a827999), 11) + e; c = RL(c, 10); + e = RL(e + F2(a, b, c) + X[6] + unchecked((int)0x5a827999), 9) + d; b = RL(b, 10); + d = RL(d + F2(e, a, b) + X[15] + unchecked((int)0x5a827999), 7) + c; a = RL(a, 10); + c = RL(c + F2(d, e, a) + X[3] + unchecked((int)0x5a827999), 15) + b; e = RL(e, 10); + b = RL(b + F2(c, d, e) + X[12] + unchecked((int)0x5a827999), 7) + a; d = RL(d, 10); + a = RL(a + F2(b, c, d) + X[0] + unchecked((int)0x5a827999), 12) + e; c = RL(c, 10); + e = RL(e + F2(a, b, c) + X[9] + unchecked((int)0x5a827999), 15) + d; b = RL(b, 10); + d = RL(d + F2(e, a, b) + X[5] + unchecked((int)0x5a827999), 9) + c; a = RL(a, 10); + c = RL(c + F2(d, e, a) + X[2] + unchecked((int)0x5a827999), 11) + b; e = RL(e, 10); + b = RL(b + F2(c, d, e) + X[14] + unchecked((int)0x5a827999), 7) + a; d = RL(d, 10); + a = RL(a + F2(b, c, d) + X[11] + unchecked((int)0x5a827999), 13) + e; c = RL(c, 10); + e = RL(e + F2(a, b, c) + X[8] + unchecked((int)0x5a827999), 12) + d; b = RL(b, 10); + + // right + ee = RL(ee + F4(aa, bb, cc) + X[6] + unchecked((int)0x5c4dd124), 9) + dd; bb = RL(bb, 10); + dd = RL(dd + F4(ee, aa, bb) + X[11] + unchecked((int)0x5c4dd124), 13) + cc; aa = RL(aa, 10); + cc = RL(cc + F4(dd, ee, aa) + X[3] + unchecked((int)0x5c4dd124), 15) + bb; ee = RL(ee, 10); + bb = RL(bb + F4(cc, dd, ee) + X[7] + unchecked((int)0x5c4dd124), 7) + aa; dd = RL(dd, 10); + aa = RL(aa + F4(bb, cc, dd) + X[0] + unchecked((int)0x5c4dd124), 12) + ee; cc = RL(cc, 10); + ee = RL(ee + F4(aa, bb, cc) + X[13] + unchecked((int)0x5c4dd124), 8) + dd; bb = RL(bb, 10); + dd = RL(dd + F4(ee, aa, bb) + X[5] + unchecked((int)0x5c4dd124), 9) + cc; aa = RL(aa, 10); + cc = RL(cc + F4(dd, ee, aa) + X[10] + unchecked((int)0x5c4dd124), 11) + bb; ee = RL(ee, 10); + bb = RL(bb + F4(cc, dd, ee) + X[14] + unchecked((int)0x5c4dd124), 7) + aa; dd = RL(dd, 10); + aa = RL(aa + F4(bb, cc, dd) + X[15] + unchecked((int)0x5c4dd124), 7) + ee; cc = RL(cc, 10); + ee = RL(ee + F4(aa, bb, cc) + X[8] + unchecked((int)0x5c4dd124), 12) + dd; bb = RL(bb, 10); + dd = RL(dd + F4(ee, aa, bb) + X[12] + unchecked((int)0x5c4dd124), 7) + cc; aa = RL(aa, 10); + cc = RL(cc + F4(dd, ee, aa) + X[4] + unchecked((int)0x5c4dd124), 6) + bb; ee = RL(ee, 10); + bb = RL(bb + F4(cc, dd, ee) + X[9] + unchecked((int)0x5c4dd124), 15) + aa; dd = RL(dd, 10); + aa = RL(aa + F4(bb, cc, dd) + X[1] + unchecked((int)0x5c4dd124), 13) + ee; cc = RL(cc, 10); + ee = RL(ee + F4(aa, bb, cc) + X[2] + unchecked((int)0x5c4dd124), 11) + dd; bb = RL(bb, 10); + + t = b; b = bb; bb = t; + + // + // Rounds 32-47 + // + // left + d = RL(d + F3(e, a, b) + X[3] + unchecked((int)0x6ed9eba1), 11) + c; a = RL(a, 10); + c = RL(c + F3(d, e, a) + X[10] + unchecked((int)0x6ed9eba1), 13) + b; e = RL(e, 10); + b = RL(b + F3(c, d, e) + X[14] + unchecked((int)0x6ed9eba1), 6) + a; d = RL(d, 10); + a = RL(a + F3(b, c, d) + X[4] + unchecked((int)0x6ed9eba1), 7) + e; c = RL(c, 10); + e = RL(e + F3(a, b, c) + X[9] + unchecked((int)0x6ed9eba1), 14) + d; b = RL(b, 10); + d = RL(d + F3(e, a, b) + X[15] + unchecked((int)0x6ed9eba1), 9) + c; a = RL(a, 10); + c = RL(c + F3(d, e, a) + X[8] + unchecked((int)0x6ed9eba1), 13) + b; e = RL(e, 10); + b = RL(b + F3(c, d, e) + X[1] + unchecked((int)0x6ed9eba1), 15) + a; d = RL(d, 10); + a = RL(a + F3(b, c, d) + X[2] + unchecked((int)0x6ed9eba1), 14) + e; c = RL(c, 10); + e = RL(e + F3(a, b, c) + X[7] + unchecked((int)0x6ed9eba1), 8) + d; b = RL(b, 10); + d = RL(d + F3(e, a, b) + X[0] + unchecked((int)0x6ed9eba1), 13) + c; a = RL(a, 10); + c = RL(c + F3(d, e, a) + X[6] + unchecked((int)0x6ed9eba1), 6) + b; e = RL(e, 10); + b = RL(b + F3(c, d, e) + X[13] + unchecked((int)0x6ed9eba1), 5) + a; d = RL(d, 10); + a = RL(a + F3(b, c, d) + X[11] + unchecked((int)0x6ed9eba1), 12) + e; c = RL(c, 10); + e = RL(e + F3(a, b, c) + X[5] + unchecked((int)0x6ed9eba1), 7) + d; b = RL(b, 10); + d = RL(d + F3(e, a, b) + X[12] + unchecked((int)0x6ed9eba1), 5) + c; a = RL(a, 10); + + // right + dd = RL(dd + F3(ee, aa, bb) + X[15] + unchecked((int)0x6d703ef3), 9) + cc; aa = RL(aa, 10); + cc = RL(cc + F3(dd, ee, aa) + X[5] + unchecked((int)0x6d703ef3), 7) + bb; ee = RL(ee, 10); + bb = RL(bb + F3(cc, dd, ee) + X[1] + unchecked((int)0x6d703ef3), 15) + aa; dd = RL(dd, 10); + aa = RL(aa + F3(bb, cc, dd) + X[3] + unchecked((int)0x6d703ef3), 11) + ee; cc = RL(cc, 10); + ee = RL(ee + F3(aa, bb, cc) + X[7] + unchecked((int)0x6d703ef3), 8) + dd; bb = RL(bb, 10); + dd = RL(dd + F3(ee, aa, bb) + X[14] + unchecked((int)0x6d703ef3), 6) + cc; aa = RL(aa, 10); + cc = RL(cc + F3(dd, ee, aa) + X[6] + unchecked((int)0x6d703ef3), 6) + bb; ee = RL(ee, 10); + bb = RL(bb + F3(cc, dd, ee) + X[9] + unchecked((int)0x6d703ef3), 14) + aa; dd = RL(dd, 10); + aa = RL(aa + F3(bb, cc, dd) + X[11] + unchecked((int)0x6d703ef3), 12) + ee; cc = RL(cc, 10); + ee = RL(ee + F3(aa, bb, cc) + X[8] + unchecked((int)0x6d703ef3), 13) + dd; bb = RL(bb, 10); + dd = RL(dd + F3(ee, aa, bb) + X[12] + unchecked((int)0x6d703ef3), 5) + cc; aa = RL(aa, 10); + cc = RL(cc + F3(dd, ee, aa) + X[2] + unchecked((int)0x6d703ef3), 14) + bb; ee = RL(ee, 10); + bb = RL(bb + F3(cc, dd, ee) + X[10] + unchecked((int)0x6d703ef3), 13) + aa; dd = RL(dd, 10); + aa = RL(aa + F3(bb, cc, dd) + X[0] + unchecked((int)0x6d703ef3), 13) + ee; cc = RL(cc, 10); + ee = RL(ee + F3(aa, bb, cc) + X[4] + unchecked((int)0x6d703ef3), 7) + dd; bb = RL(bb, 10); + dd = RL(dd + F3(ee, aa, bb) + X[13] + unchecked((int)0x6d703ef3), 5) + cc; aa = RL(aa, 10); + + t = c; c = cc; cc = t; + + // + // Rounds 48-63 + // + // left + c = RL(c + F4(d, e, a) + X[1] + unchecked((int)0x8f1bbcdc), 11) + b; e = RL(e, 10); + b = RL(b + F4(c, d, e) + X[9] + unchecked((int)0x8f1bbcdc), 12) + a; d = RL(d, 10); + a = RL(a + F4(b, c, d) + X[11] + unchecked((int)0x8f1bbcdc), 14) + e; c = RL(c, 10); + e = RL(e + F4(a, b, c) + X[10] + unchecked((int)0x8f1bbcdc), 15) + d; b = RL(b, 10); + d = RL(d + F4(e, a, b) + X[0] + unchecked((int)0x8f1bbcdc), 14) + c; a = RL(a, 10); + c = RL(c + F4(d, e, a) + X[8] + unchecked((int)0x8f1bbcdc), 15) + b; e = RL(e, 10); + b = RL(b + F4(c, d, e) + X[12] + unchecked((int)0x8f1bbcdc), 9) + a; d = RL(d, 10); + a = RL(a + F4(b, c, d) + X[4] + unchecked((int)0x8f1bbcdc), 8) + e; c = RL(c, 10); + e = RL(e + F4(a, b, c) + X[13] + unchecked((int)0x8f1bbcdc), 9) + d; b = RL(b, 10); + d = RL(d + F4(e, a, b) + X[3] + unchecked((int)0x8f1bbcdc), 14) + c; a = RL(a, 10); + c = RL(c + F4(d, e, a) + X[7] + unchecked((int)0x8f1bbcdc), 5) + b; e = RL(e, 10); + b = RL(b + F4(c, d, e) + X[15] + unchecked((int)0x8f1bbcdc), 6) + a; d = RL(d, 10); + a = RL(a + F4(b, c, d) + X[14] + unchecked((int)0x8f1bbcdc), 8) + e; c = RL(c, 10); + e = RL(e + F4(a, b, c) + X[5] + unchecked((int)0x8f1bbcdc), 6) + d; b = RL(b, 10); + d = RL(d + F4(e, a, b) + X[6] + unchecked((int)0x8f1bbcdc), 5) + c; a = RL(a, 10); + c = RL(c + F4(d, e, a) + X[2] + unchecked((int)0x8f1bbcdc), 12) + b; e = RL(e, 10); + + // right + cc = RL(cc + F2(dd, ee, aa) + X[8] + unchecked((int)0x7a6d76e9), 15) + bb; ee = RL(ee, 10); + bb = RL(bb + F2(cc, dd, ee) + X[6] + unchecked((int)0x7a6d76e9), 5) + aa; dd = RL(dd, 10); + aa = RL(aa + F2(bb, cc, dd) + X[4] + unchecked((int)0x7a6d76e9), 8) + ee; cc = RL(cc, 10); + ee = RL(ee + F2(aa, bb, cc) + X[1] + unchecked((int)0x7a6d76e9), 11) + dd; bb = RL(bb, 10); + dd = RL(dd + F2(ee, aa, bb) + X[3] + unchecked((int)0x7a6d76e9), 14) + cc; aa = RL(aa, 10); + cc = RL(cc + F2(dd, ee, aa) + X[11] + unchecked((int)0x7a6d76e9), 14) + bb; ee = RL(ee, 10); + bb = RL(bb + F2(cc, dd, ee) + X[15] + unchecked((int)0x7a6d76e9), 6) + aa; dd = RL(dd, 10); + aa = RL(aa + F2(bb, cc, dd) + X[0] + unchecked((int)0x7a6d76e9), 14) + ee; cc = RL(cc, 10); + ee = RL(ee + F2(aa, bb, cc) + X[5] + unchecked((int)0x7a6d76e9), 6) + dd; bb = RL(bb, 10); + dd = RL(dd + F2(ee, aa, bb) + X[12] + unchecked((int)0x7a6d76e9), 9) + cc; aa = RL(aa, 10); + cc = RL(cc + F2(dd, ee, aa) + X[2] + unchecked((int)0x7a6d76e9), 12) + bb; ee = RL(ee, 10); + bb = RL(bb + F2(cc, dd, ee) + X[13] + unchecked((int)0x7a6d76e9), 9) + aa; dd = RL(dd, 10); + aa = RL(aa + F2(bb, cc, dd) + X[9] + unchecked((int)0x7a6d76e9), 12) + ee; cc = RL(cc, 10); + ee = RL(ee + F2(aa, bb, cc) + X[7] + unchecked((int)0x7a6d76e9), 5) + dd; bb = RL(bb, 10); + dd = RL(dd + F2(ee, aa, bb) + X[10] + unchecked((int)0x7a6d76e9), 15) + cc; aa = RL(aa, 10); + cc = RL(cc + F2(dd, ee, aa) + X[14] + unchecked((int)0x7a6d76e9), 8) + bb; ee = RL(ee, 10); + + t = d; d = dd; dd = t; + + // + // Rounds 64-79 + // + // left + b = RL(b + F5(c, d, e) + X[4] + unchecked((int)0xa953fd4e), 9) + a; d = RL(d, 10); + a = RL(a + F5(b, c, d) + X[0] + unchecked((int)0xa953fd4e), 15) + e; c = RL(c, 10); + e = RL(e + F5(a, b, c) + X[5] + unchecked((int)0xa953fd4e), 5) + d; b = RL(b, 10); + d = RL(d + F5(e, a, b) + X[9] + unchecked((int)0xa953fd4e), 11) + c; a = RL(a, 10); + c = RL(c + F5(d, e, a) + X[7] + unchecked((int)0xa953fd4e), 6) + b; e = RL(e, 10); + b = RL(b + F5(c, d, e) + X[12] + unchecked((int)0xa953fd4e), 8) + a; d = RL(d, 10); + a = RL(a + F5(b, c, d) + X[2] + unchecked((int)0xa953fd4e), 13) + e; c = RL(c, 10); + e = RL(e + F5(a, b, c) + X[10] + unchecked((int)0xa953fd4e), 12) + d; b = RL(b, 10); + d = RL(d + F5(e, a, b) + X[14] + unchecked((int)0xa953fd4e), 5) + c; a = RL(a, 10); + c = RL(c + F5(d, e, a) + X[1] + unchecked((int)0xa953fd4e), 12) + b; e = RL(e, 10); + b = RL(b + F5(c, d, e) + X[3] + unchecked((int)0xa953fd4e), 13) + a; d = RL(d, 10); + a = RL(a + F5(b, c, d) + X[8] + unchecked((int)0xa953fd4e), 14) + e; c = RL(c, 10); + e = RL(e + F5(a, b, c) + X[11] + unchecked((int)0xa953fd4e), 11) + d; b = RL(b, 10); + d = RL(d + F5(e, a, b) + X[6] + unchecked((int)0xa953fd4e), 8) + c; a = RL(a, 10); + c = RL(c + F5(d, e, a) + X[15] + unchecked((int)0xa953fd4e), 5) + b; e = RL(e, 10); + b = RL(b + F5(c, d, e) + X[13] + unchecked((int)0xa953fd4e), 6) + a; d = RL(d, 10); + + // right + bb = RL(bb + F1(cc, dd, ee) + X[12], 8) + aa; dd = RL(dd, 10); + aa = RL(aa + F1(bb, cc, dd) + X[15], 5) + ee; cc = RL(cc, 10); + ee = RL(ee + F1(aa, bb, cc) + X[10], 12) + dd; bb = RL(bb, 10); + dd = RL(dd + F1(ee, aa, bb) + X[4], 9) + cc; aa = RL(aa, 10); + cc = RL(cc + F1(dd, ee, aa) + X[1], 12) + bb; ee = RL(ee, 10); + bb = RL(bb + F1(cc, dd, ee) + X[5], 5) + aa; dd = RL(dd, 10); + aa = RL(aa + F1(bb, cc, dd) + X[8], 14) + ee; cc = RL(cc, 10); + ee = RL(ee + F1(aa, bb, cc) + X[7], 6) + dd; bb = RL(bb, 10); + dd = RL(dd + F1(ee, aa, bb) + X[6], 8) + cc; aa = RL(aa, 10); + cc = RL(cc + F1(dd, ee, aa) + X[2], 13) + bb; ee = RL(ee, 10); + bb = RL(bb + F1(cc, dd, ee) + X[13], 6) + aa; dd = RL(dd, 10); + aa = RL(aa + F1(bb, cc, dd) + X[14], 5) + ee; cc = RL(cc, 10); + ee = RL(ee + F1(aa, bb, cc) + X[0], 15) + dd; bb = RL(bb, 10); + dd = RL(dd + F1(ee, aa, bb) + X[3], 13) + cc; aa = RL(aa, 10); + cc = RL(cc + F1(dd, ee, aa) + X[9], 11) + bb; ee = RL(ee, 10); + bb = RL(bb + F1(cc, dd, ee) + X[11], 11) + aa; dd = RL(dd, 10); + + // + // do (e, ee) swap as part of assignment. + // + + H0 += a; + H1 += b; + H2 += c; + H3 += d; + H4 += ee; + H5 += aa; + H6 += bb; + H7 += cc; + H8 += dd; + H9 += e; + + // + // reset the offset and clean out the word buffer. + // + xOff = 0; + for (int i = 0; i != X.Length; i++) + { + X[i] = 0; + } + } + + public override IMemoable Copy() + { + return new RipeMD320Digest(this); + } + + public override void Reset(IMemoable other) + { + RipeMD320Digest d = (RipeMD320Digest)other; + + CopyIn(d); + } + + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/RipeMD320Digest.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/RipeMD320Digest.cs.meta new file mode 100644 index 0000000..844560b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/RipeMD320Digest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a96b215be81f34f498ecad83a02f5766 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/SHA3Digest.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/SHA3Digest.cs new file mode 100644 index 0000000..3dc63a6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/SHA3Digest.cs @@ -0,0 +1,85 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /// + /// Implementation of SHA-3 based on following KeccakNISTInterface.c from http://keccak.noekeon.org/ + /// + /// + /// Following the naming conventions used in the C source code to enable easy review of the implementation. + /// + public class Sha3Digest + : KeccakDigest + { + private static int CheckBitLength(int bitLength) + { + switch (bitLength) + { + case 224: + case 256: + case 384: + case 512: + return bitLength; + default: + throw new ArgumentException(bitLength + " not supported for SHA-3", "bitLength"); + } + } + + public Sha3Digest() + : this(256) + { + } + + public Sha3Digest(int bitLength) + : base(CheckBitLength(bitLength)) + { + } + + public Sha3Digest(Sha3Digest source) + : base(source) + { + } + + public override string AlgorithmName + { + get { return "SHA3-" + fixedOutputLength; } + } + + public override int DoFinal(byte[] output, int outOff) + { + AbsorbBits(0x02, 2); + + return base.DoFinal(output, outOff); + } + + /* + * TODO Possible API change to support partial-byte suffixes. + */ + protected override int DoFinal(byte[] output, int outOff, byte partialByte, int partialBits) + { + if (partialBits < 0 || partialBits > 7) + throw new ArgumentException("must be in the range [0,7]", "partialBits"); + + int finalInput = (partialByte & ((1 << partialBits) - 1)) | (0x02 << partialBits); + Debug.Assert(finalInput >= 0); + int finalBits = partialBits + 2; + + if (finalBits >= 8) + { + Absorb((byte)finalInput); + finalBits -= 8; + finalInput >>= 8; + } + + return base.DoFinal(output, outOff, (byte)finalInput, finalBits); + } + + public override IMemoable Copy() + { + return new Sha3Digest(this); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/SHA3Digest.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/SHA3Digest.cs.meta new file mode 100644 index 0000000..a9cb87d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/SHA3Digest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 017826f2ed695ce468bb511b56c60a2d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/SM3Digest.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/SM3Digest.cs new file mode 100644 index 0000000..449d7c1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/SM3Digest.cs @@ -0,0 +1,320 @@ +using System; + +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + + /// + /// Implementation of Chinese SM3 digest as described at + /// http://tools.ietf.org/html/draft-shen-sm3-hash-00 + /// and at .... ( Chinese PDF ) + /// + /// + /// The specification says "process a bit stream", + /// but this is written to process bytes in blocks of 4, + /// meaning this will process 32-bit word groups. + /// But so do also most other digest specifications, + /// including the SHA-256 which was a origin for + /// this specification. + /// + public class SM3Digest + : GeneralDigest + { + private const int DIGEST_LENGTH = 32; // bytes + private const int BLOCK_SIZE = 64 / 4; // of 32 bit ints (16 ints) + + private uint[] V = new uint[DIGEST_LENGTH / 4]; // in 32 bit ints (8 ints) + private uint[] inwords = new uint[BLOCK_SIZE]; + private int xOff; + + // Work-bufs used within processBlock() + private uint[] W = new uint[68]; + + // Round constant T for processBlock() which is 32 bit integer rolled left up to (63 MOD 32) bit positions. + private static readonly uint[] T = new uint[64]; + + static SM3Digest() + { + for (int i = 0; i < 16; ++i) + { + uint t = 0x79CC4519; + T[i] = (t << i) | (t >> (32 - i)); + } + for (int i = 16; i < 64; ++i) + { + int n = i % 32; + uint t = 0x7A879D8A; + T[i] = (t << n) | (t >> (32 - n)); + } + } + + + /// + /// Standard constructor + /// + public SM3Digest() + { + Reset(); + } + + /// + /// Copy constructor. This will copy the state of the provided + /// message digest. + /// + public SM3Digest(SM3Digest t) + : base(t) + { + CopyIn(t); + } + + private void CopyIn(SM3Digest t) + { + Array.Copy(t.V, 0, this.V, 0, this.V.Length); + Array.Copy(t.inwords, 0, this.inwords, 0, this.inwords.Length); + xOff = t.xOff; + } + + public override string AlgorithmName + { + get { return "SM3"; } + } + + public override int GetDigestSize() + { + return DIGEST_LENGTH; + } + + public override IMemoable Copy() + { + return new SM3Digest(this); + } + + public override void Reset(IMemoable other) + { + SM3Digest d = (SM3Digest)other; + + base.CopyIn(d); + CopyIn(d); + } + + /// + /// reset the chaining variables + /// + public override void Reset() + { + base.Reset(); + + this.V[0] = 0x7380166F; + this.V[1] = 0x4914B2B9; + this.V[2] = 0x172442D7; + this.V[3] = 0xDA8A0600; + this.V[4] = 0xA96F30BC; + this.V[5] = 0x163138AA; + this.V[6] = 0xE38DEE4D; + this.V[7] = 0xB0FB0E4E; + + this.xOff = 0; + } + + + public override int DoFinal(byte[] output, int outOff) + { + Finish(); + + Pack.UInt32_To_BE(V, output, outOff); + + Reset(); + + return DIGEST_LENGTH; + } + + + internal override void ProcessWord(byte[] input, + int inOff) + { + uint n = Pack.BE_To_UInt32(input, inOff); + this.inwords[this.xOff] = n; + ++this.xOff; + + if (this.xOff >= 16) + { + ProcessBlock(); + } + } + + internal override void ProcessLength(long bitLength) + { + if (this.xOff > (BLOCK_SIZE - 2)) + { + // xOff == 15 --> can't fit the 64 bit length field at tail.. + this.inwords[this.xOff] = 0; // fill with zero + ++this.xOff; + + ProcessBlock(); + } + // Fill with zero words, until reach 2nd to last slot + while (this.xOff < (BLOCK_SIZE - 2)) + { + this.inwords[this.xOff] = 0; + ++this.xOff; + } + + // Store input data length in BITS + this.inwords[this.xOff++] = (uint)(bitLength >> 32); + this.inwords[this.xOff++] = (uint)(bitLength); + } + + /* + + 3.4.2. Constants + + + Tj = 79cc4519 when 0 < = j < = 15 + Tj = 7a879d8a when 16 < = j < = 63 + + 3.4.3. Boolean function + + + FFj(X;Y;Z) = X XOR Y XOR Z when 0 < = j < = 15 + = (X AND Y) OR (X AND Z) OR (Y AND Z) when 16 < = j < = 63 + + GGj(X;Y;Z) = X XOR Y XOR Z when 0 < = j < = 15 + = (X AND Y) OR (NOT X AND Z) when 16 < = j < = 63 + + The X, Y, Z in the fomular are words!GBP + + 3.4.4. Permutation function + + + P0(X) = X XOR (X <<< 9) XOR (X <<< 17) ## ROLL, not SHIFT + P1(X) = X XOR (X <<< 15) XOR (X <<< 23) ## ROLL, not SHIFT + + The X in the fomular are a word. + + ---------- + + Each ROLL converted to Java expression: + + ROLL 9 : ((x << 9) | (x >> (32-9)))) + ROLL 17 : ((x << 17) | (x >> (32-17))) + ROLL 15 : ((x << 15) | (x >> (32-15))) + ROLL 23 : ((x << 23) | (x >> (32-23))) + + */ + + private uint P0(uint x) + { + uint r9 = ((x << 9) | (x >> (32 - 9))); + uint r17 = ((x << 17) | (x >> (32 - 17))); + return (x ^ r9 ^ r17); + } + + private uint P1(uint x) + { + uint r15 = ((x << 15) | (x >> (32 - 15))); + uint r23 = ((x << 23) | (x >> (32 - 23))); + return (x ^ r15 ^ r23); + } + + private uint FF0(uint x, uint y, uint z) + { + return (x ^ y ^ z); + } + + private uint FF1(uint x, uint y, uint z) + { + return ((x & y) | (x & z) | (y & z)); + } + + private uint GG0(uint x, uint y, uint z) + { + return (x ^ y ^ z); + } + + private uint GG1(uint x, uint y, uint z) + { + return ((x & y) | ((~x) & z)); + } + + + internal override void ProcessBlock() + { + for (int j = 0; j < 16; ++j) + { + this.W[j] = this.inwords[j]; + } + for (int j = 16; j < 68; ++j) + { + uint wj3 = this.W[j - 3]; + uint r15 = ((wj3 << 15) | (wj3 >> (32 - 15))); + uint wj13 = this.W[j - 13]; + uint r7 = ((wj13 << 7) | (wj13 >> (32 - 7))); + this.W[j] = P1(this.W[j - 16] ^ this.W[j - 9] ^ r15) ^ r7 ^ this.W[j - 6]; + } + + uint A = this.V[0]; + uint B = this.V[1]; + uint C = this.V[2]; + uint D = this.V[3]; + uint E = this.V[4]; + uint F = this.V[5]; + uint G = this.V[6]; + uint H = this.V[7]; + + + for (int j = 0; j < 16; ++j) + { + uint a12 = ((A << 12) | (A >> (32 - 12))); + uint s1_ = a12 + E + T[j]; + uint SS1 = ((s1_ << 7) | (s1_ >> (32 - 7))); + uint SS2 = SS1 ^ a12; + uint Wj = W[j]; + uint W1j = Wj ^ W[j + 4]; + uint TT1 = FF0(A, B, C) + D + SS2 + W1j; + uint TT2 = GG0(E, F, G) + H + SS1 + Wj; + D = C; + C = ((B << 9) | (B >> (32 - 9))); + B = A; + A = TT1; + H = G; + G = ((F << 19) | (F >> (32 - 19))); + F = E; + E = P0(TT2); + } + + // Different FF,GG functions on rounds 16..63 + for (int j = 16; j < 64; ++j) + { + uint a12 = ((A << 12) | (A >> (32 - 12))); + uint s1_ = a12 + E + T[j]; + uint SS1 = ((s1_ << 7) | (s1_ >> (32 - 7))); + uint SS2 = SS1 ^ a12; + uint Wj = W[j]; + uint W1j = Wj ^ W[j + 4]; + uint TT1 = FF1(A, B, C) + D + SS2 + W1j; + uint TT2 = GG1(E, F, G) + H + SS1 + Wj; + D = C; + C = ((B << 9) | (B >> (32 - 9))); + B = A; + A = TT1; + H = G; + G = ((F << 19) | (F >> (32 - 19))); + F = E; + E = P0(TT2); + } + + this.V[0] ^= A; + this.V[1] ^= B; + this.V[2] ^= C; + this.V[3] ^= D; + this.V[4] ^= E; + this.V[5] ^= F; + this.V[6] ^= G; + this.V[7] ^= H; + + this.xOff = 0; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/SM3Digest.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/SM3Digest.cs.meta new file mode 100644 index 0000000..76dda4f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/SM3Digest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fefdb833d43c87842902fa900b0a095d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/Sha1Digest.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/Sha1Digest.cs new file mode 100644 index 0000000..60ec651 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/Sha1Digest.cs @@ -0,0 +1,284 @@ +using System; + +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + + /** + * implementation of SHA-1 as outlined in "Handbook of Applied Cryptography", pages 346 - 349. + * + * It is interesting to ponder why the, apart from the extra IV, the other difference here from MD5 + * is the "endianness" of the word processing! + */ + public class Sha1Digest + : GeneralDigest + { + private const int DigestLength = 20; + + private uint H1, H2, H3, H4, H5; + + private uint[] X = new uint[80]; + private int xOff; + + public Sha1Digest() + { + Reset(); + } + + /** + * Copy constructor. This will copy the state of the provided + * message digest. + */ + public Sha1Digest(Sha1Digest t) + : base(t) + { + CopyIn(t); + } + + private void CopyIn(Sha1Digest t) + { + base.CopyIn(t); + + H1 = t.H1; + H2 = t.H2; + H3 = t.H3; + H4 = t.H4; + H5 = t.H5; + + Array.Copy(t.X, 0, X, 0, t.X.Length); + xOff = t.xOff; + } + + public override string AlgorithmName + { + get { return "SHA-1"; } + } + + public override int GetDigestSize() + { + return DigestLength; + } + + internal override void ProcessWord( + byte[] input, + int inOff) + { + X[xOff] = Pack.BE_To_UInt32(input, inOff); + + if (++xOff == 16) + { + ProcessBlock(); + } + } + + internal override void ProcessLength(long bitLength) + { + if (xOff > 14) + { + ProcessBlock(); + } + + X[14] = (uint)((ulong)bitLength >> 32); + X[15] = (uint)((ulong)bitLength); + } + + public override int DoFinal( + byte[] output, + int outOff) + { + Finish(); + + Pack.UInt32_To_BE(H1, output, outOff); + Pack.UInt32_To_BE(H2, output, outOff + 4); + Pack.UInt32_To_BE(H3, output, outOff + 8); + Pack.UInt32_To_BE(H4, output, outOff + 12); + Pack.UInt32_To_BE(H5, output, outOff + 16); + + Reset(); + + return DigestLength; + } + + /** + * reset the chaining variables + */ + public override void Reset() + { + base.Reset(); + + H1 = 0x67452301; + H2 = 0xefcdab89; + H3 = 0x98badcfe; + H4 = 0x10325476; + H5 = 0xc3d2e1f0; + + xOff = 0; + Array.Clear(X, 0, X.Length); + } + + // + // Additive constants + // + private const uint Y1 = 0x5a827999; + private const uint Y2 = 0x6ed9eba1; + private const uint Y3 = 0x8f1bbcdc; + private const uint Y4 = 0xca62c1d6; + + private static uint F(uint u, uint v, uint w) + { + return (u & v) | (~u & w); + } + + private static uint H(uint u, uint v, uint w) + { + return u ^ v ^ w; + } + + private static uint G(uint u, uint v, uint w) + { + return (u & v) | (u & w) | (v & w); + } + + internal override void ProcessBlock() + { + // + // expand 16 word block into 80 word block. + // + for (int i = 16; i < 80; i++) + { + uint t = X[i - 3] ^ X[i - 8] ^ X[i - 14] ^ X[i - 16]; + X[i] = t << 1 | t >> 31; + } + + // + // set up working variables. + // + uint A = H1; + uint B = H2; + uint C = H3; + uint D = H4; + uint E = H5; + + // + // round 1 + // + int idx = 0; + + for (int j = 0; j < 4; j++) + { + // E = rotateLeft(A, 5) + F(B, C, D) + E + X[idx++] + Y1 + // B = rotateLeft(B, 30) + E += (A << 5 | (A >> 27)) + F(B, C, D) + X[idx++] + Y1; + B = B << 30 | (B >> 2); + + D += (E << 5 | (E >> 27)) + F(A, B, C) + X[idx++] + Y1; + A = A << 30 | (A >> 2); + + C += (D << 5 | (D >> 27)) + F(E, A, B) + X[idx++] + Y1; + E = E << 30 | (E >> 2); + + B += (C << 5 | (C >> 27)) + F(D, E, A) + X[idx++] + Y1; + D = D << 30 | (D >> 2); + + A += (B << 5 | (B >> 27)) + F(C, D, E) + X[idx++] + Y1; + C = C << 30 | (C >> 2); + } + + // + // round 2 + // + for (int j = 0; j < 4; j++) + { + // E = rotateLeft(A, 5) + H(B, C, D) + E + X[idx++] + Y2 + // B = rotateLeft(B, 30) + E += (A << 5 | (A >> 27)) + H(B, C, D) + X[idx++] + Y2; + B = B << 30 | (B >> 2); + + D += (E << 5 | (E >> 27)) + H(A, B, C) + X[idx++] + Y2; + A = A << 30 | (A >> 2); + + C += (D << 5 | (D >> 27)) + H(E, A, B) + X[idx++] + Y2; + E = E << 30 | (E >> 2); + + B += (C << 5 | (C >> 27)) + H(D, E, A) + X[idx++] + Y2; + D = D << 30 | (D >> 2); + + A += (B << 5 | (B >> 27)) + H(C, D, E) + X[idx++] + Y2; + C = C << 30 | (C >> 2); + } + + // + // round 3 + // + for (int j = 0; j < 4; j++) + { + // E = rotateLeft(A, 5) + G(B, C, D) + E + X[idx++] + Y3 + // B = rotateLeft(B, 30) + E += (A << 5 | (A >> 27)) + G(B, C, D) + X[idx++] + Y3; + B = B << 30 | (B >> 2); + + D += (E << 5 | (E >> 27)) + G(A, B, C) + X[idx++] + Y3; + A = A << 30 | (A >> 2); + + C += (D << 5 | (D >> 27)) + G(E, A, B) + X[idx++] + Y3; + E = E << 30 | (E >> 2); + + B += (C << 5 | (C >> 27)) + G(D, E, A) + X[idx++] + Y3; + D = D << 30 | (D >> 2); + + A += (B << 5 | (B >> 27)) + G(C, D, E) + X[idx++] + Y3; + C = C << 30 | (C >> 2); + } + + // + // round 4 + // + for (int j = 0; j < 4; j++) + { + // E = rotateLeft(A, 5) + H(B, C, D) + E + X[idx++] + Y4 + // B = rotateLeft(B, 30) + E += (A << 5 | (A >> 27)) + H(B, C, D) + X[idx++] + Y4; + B = B << 30 | (B >> 2); + + D += (E << 5 | (E >> 27)) + H(A, B, C) + X[idx++] + Y4; + A = A << 30 | (A >> 2); + + C += (D << 5 | (D >> 27)) + H(E, A, B) + X[idx++] + Y4; + E = E << 30 | (E >> 2); + + B += (C << 5 | (C >> 27)) + H(D, E, A) + X[idx++] + Y4; + D = D << 30 | (D >> 2); + + A += (B << 5 | (B >> 27)) + H(C, D, E) + X[idx++] + Y4; + C = C << 30 | (C >> 2); + } + + H1 += A; + H2 += B; + H3 += C; + H4 += D; + H5 += E; + + // + // reset start of the buffer. + // + xOff = 0; + Array.Clear(X, 0, 16); + } + + public override IMemoable Copy() + { + return new Sha1Digest(this); + } + + public override void Reset(IMemoable other) + { + Sha1Digest d = (Sha1Digest)other; + + CopyIn(d); + } + + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/Sha1Digest.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/Sha1Digest.cs.meta new file mode 100644 index 0000000..a03c8da --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/Sha1Digest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4f021159b5fb1454c880948b6c239ab9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/Sha224Digest.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/Sha224Digest.cs new file mode 100644 index 0000000..b4e8537 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/Sha224Digest.cs @@ -0,0 +1,289 @@ +using System; + +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /** + * SHA-224 as described in RFC 3874 + *
+     *         block  word  digest
+     * SHA-1   512    32    160
+     * SHA-224 512    32    224
+     * SHA-256 512    32    256
+     * SHA-384 1024   64    384
+     * SHA-512 1024   64    512
+     * 
+ */ + public class Sha224Digest + : GeneralDigest + { + private const int DigestLength = 28; + + private uint H1, H2, H3, H4, H5, H6, H7, H8; + + private uint[] X = new uint[64]; + private int xOff; + + /** + * Standard constructor + */ + public Sha224Digest() + { + Reset(); + } + + /** + * Copy constructor. This will copy the state of the provided + * message digest. + */ + public Sha224Digest( + Sha224Digest t) + : base(t) + { + CopyIn(t); + } + + private void CopyIn(Sha224Digest t) + { + base.CopyIn(t); + + H1 = t.H1; + H2 = t.H2; + H3 = t.H3; + H4 = t.H4; + H5 = t.H5; + H6 = t.H6; + H7 = t.H7; + H8 = t.H8; + + Array.Copy(t.X, 0, X, 0, t.X.Length); + xOff = t.xOff; + } + + public override string AlgorithmName + { + get { return "SHA-224"; } + } + + public override int GetDigestSize() + { + return DigestLength; + } + + internal override void ProcessWord( + byte[] input, + int inOff) + { + X[xOff] = Pack.BE_To_UInt32(input, inOff); + + if (++xOff == 16) + { + ProcessBlock(); + } + } + + internal override void ProcessLength( + long bitLength) + { + if (xOff > 14) + { + ProcessBlock(); + } + + X[14] = (uint)((ulong)bitLength >> 32); + X[15] = (uint)((ulong)bitLength); + } + + public override int DoFinal( + byte[] output, + int outOff) + { + Finish(); + + Pack.UInt32_To_BE(H1, output, outOff); + Pack.UInt32_To_BE(H2, output, outOff + 4); + Pack.UInt32_To_BE(H3, output, outOff + 8); + Pack.UInt32_To_BE(H4, output, outOff + 12); + Pack.UInt32_To_BE(H5, output, outOff + 16); + Pack.UInt32_To_BE(H6, output, outOff + 20); + Pack.UInt32_To_BE(H7, output, outOff + 24); + + Reset(); + + return DigestLength; + } + + /** + * reset the chaining variables + */ + public override void Reset() + { + base.Reset(); + + /* SHA-224 initial hash value + */ + H1 = 0xc1059ed8; + H2 = 0x367cd507; + H3 = 0x3070dd17; + H4 = 0xf70e5939; + H5 = 0xffc00b31; + H6 = 0x68581511; + H7 = 0x64f98fa7; + H8 = 0xbefa4fa4; + + xOff = 0; + Array.Clear(X, 0, X.Length); + } + + internal override void ProcessBlock() + { + // + // expand 16 word block into 64 word blocks. + // + for (int ti = 16; ti <= 63; ti++) + { + X[ti] = Theta1(X[ti - 2]) + X[ti - 7] + Theta0(X[ti - 15]) + X[ti - 16]; + } + + // + // set up working variables. + // + uint a = H1; + uint b = H2; + uint c = H3; + uint d = H4; + uint e = H5; + uint f = H6; + uint g = H7; + uint h = H8; + + int t = 0; + for(int i = 0; i < 8; i ++) + { + // t = 8 * i + h += Sum1(e) + Ch(e, f, g) + K[t] + X[t]; + d += h; + h += Sum0(a) + Maj(a, b, c); + ++t; + + // t = 8 * i + 1 + g += Sum1(d) + Ch(d, e, f) + K[t] + X[t]; + c += g; + g += Sum0(h) + Maj(h, a, b); + ++t; + + // t = 8 * i + 2 + f += Sum1(c) + Ch(c, d, e) + K[t] + X[t]; + b += f; + f += Sum0(g) + Maj(g, h, a); + ++t; + + // t = 8 * i + 3 + e += Sum1(b) + Ch(b, c, d) + K[t] + X[t]; + a += e; + e += Sum0(f) + Maj(f, g, h); + ++t; + + // t = 8 * i + 4 + d += Sum1(a) + Ch(a, b, c) + K[t] + X[t]; + h += d; + d += Sum0(e) + Maj(e, f, g); + ++t; + + // t = 8 * i + 5 + c += Sum1(h) + Ch(h, a, b) + K[t] + X[t]; + g += c; + c += Sum0(d) + Maj(d, e, f); + ++t; + + // t = 8 * i + 6 + b += Sum1(g) + Ch(g, h, a) + K[t] + X[t]; + f += b; + b += Sum0(c) + Maj(c, d, e); + ++t; + + // t = 8 * i + 7 + a += Sum1(f) + Ch(f, g, h) + K[t] + X[t]; + e += a; + a += Sum0(b) + Maj(b, c, d); + ++t; + } + + H1 += a; + H2 += b; + H3 += c; + H4 += d; + H5 += e; + H6 += f; + H7 += g; + H8 += h; + + // + // reset the offset and clean out the word buffer. + // + xOff = 0; + Array.Clear(X, 0, 16); + } + + /* SHA-224 functions */ + private static uint Ch(uint x, uint y, uint z) + { + return (x & y) ^ (~x & z); + } + + private static uint Maj(uint x, uint y, uint z) + { + return (x & y) ^ (x & z) ^ (y & z); + } + + private static uint Sum0(uint x) + { + return ((x >> 2) | (x << 30)) ^ ((x >> 13) | (x << 19)) ^ ((x >> 22) | (x << 10)); + } + + private static uint Sum1(uint x) + { + return ((x >> 6) | (x << 26)) ^ ((x >> 11) | (x << 21)) ^ ((x >> 25) | (x << 7)); + } + + private static uint Theta0(uint x) + { + return ((x >> 7) | (x << 25)) ^ ((x >> 18) | (x << 14)) ^ (x >> 3); + } + + private static uint Theta1(uint x) + { + return ((x >> 17) | (x << 15)) ^ ((x >> 19) | (x << 13)) ^ (x >> 10); + } + + /* SHA-224 Constants + * (represent the first 32 bits of the fractional parts of the + * cube roots of the first sixty-four prime numbers) + */ + internal static readonly uint[] K = { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 + }; + + public override IMemoable Copy() + { + return new Sha224Digest(this); + } + + public override void Reset(IMemoable other) + { + Sha224Digest d = (Sha224Digest)other; + + CopyIn(d); + } + + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/Sha224Digest.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/Sha224Digest.cs.meta new file mode 100644 index 0000000..968c503 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/Sha224Digest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5d95eb67017f0f64584c6feea920beba +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/Sha256Digest.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/Sha256Digest.cs new file mode 100644 index 0000000..63d5b8b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/Sha256Digest.cs @@ -0,0 +1,318 @@ +using System; + +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /** + * Draft FIPS 180-2 implementation of SHA-256. Note: As this is + * based on a draft this implementation is subject to change. + * + *
+    *         block  word  digest
+    * SHA-1   512    32    160
+    * SHA-256 512    32    256
+    * SHA-384 1024   64    384
+    * SHA-512 1024   64    512
+    * 
+ */ + public class Sha256Digest + : GeneralDigest + { + private const int DigestLength = 32; + + private uint H1, H2, H3, H4, H5, H6, H7, H8; + private uint[] X = new uint[64]; + private int xOff; + + public Sha256Digest() + { + initHs(); + } + + /** + * Copy constructor. This will copy the state of the provided + * message digest. + */ + public Sha256Digest(Sha256Digest t) : base(t) + { + CopyIn(t); + } + + private void CopyIn(Sha256Digest t) + { + base.CopyIn(t); + + H1 = t.H1; + H2 = t.H2; + H3 = t.H3; + H4 = t.H4; + H5 = t.H5; + H6 = t.H6; + H7 = t.H7; + H8 = t.H8; + + Array.Copy(t.X, 0, X, 0, t.X.Length); + xOff = t.xOff; + } + + public override string AlgorithmName + { + get { return "SHA-256"; } + } + + public override int GetDigestSize() + { + return DigestLength; + } + + internal override void ProcessWord( + byte[] input, + int inOff) + { + X[xOff] = Pack.BE_To_UInt32(input, inOff); + + if (++xOff == 16) + { + ProcessBlock(); + } + } + + internal override void ProcessLength( + long bitLength) + { + if (xOff > 14) + { + ProcessBlock(); + } + + X[14] = (uint)((ulong)bitLength >> 32); + X[15] = (uint)((ulong)bitLength); + } + + public override int DoFinal( + byte[] output, + int outOff) + { + Finish(); + + Pack.UInt32_To_BE((uint)H1, output, outOff); + Pack.UInt32_To_BE((uint)H2, output, outOff + 4); + Pack.UInt32_To_BE((uint)H3, output, outOff + 8); + Pack.UInt32_To_BE((uint)H4, output, outOff + 12); + Pack.UInt32_To_BE((uint)H5, output, outOff + 16); + Pack.UInt32_To_BE((uint)H6, output, outOff + 20); + Pack.UInt32_To_BE((uint)H7, output, outOff + 24); + Pack.UInt32_To_BE((uint)H8, output, outOff + 28); + + Reset(); + + return DigestLength; + } + + /** + * reset the chaining variables + */ + public override void Reset() + { + base.Reset(); + + initHs(); + + xOff = 0; + Array.Clear(X, 0, X.Length); + } + + private void initHs() + { + /* SHA-256 initial hash value + * The first 32 bits of the fractional parts of the square roots + * of the first eight prime numbers + */ + H1 = 0x6a09e667; + H2 = 0xbb67ae85; + H3 = 0x3c6ef372; + H4 = 0xa54ff53a; + H5 = 0x510e527f; + H6 = 0x9b05688c; + H7 = 0x1f83d9ab; + H8 = 0x5be0cd19; + } + + internal override void ProcessBlock() + { + // + // expand 16 word block into 64 word blocks. + // + for (int ti = 16; ti <= 63; ti++) + { + X[ti] = Theta1(X[ti - 2]) + X[ti - 7] + Theta0(X[ti - 15]) + X[ti - 16]; + } + + // + // set up working variables. + // + uint a = H1; + uint b = H2; + uint c = H3; + uint d = H4; + uint e = H5; + uint f = H6; + uint g = H7; + uint h = H8; + + int t = 0; + for(int i = 0; i < 8; ++i) + { + // t = 8 * i + h += Sum1Ch(e, f, g) + K[t] + X[t]; + d += h; + h += Sum0Maj(a, b, c); + ++t; + + // t = 8 * i + 1 + g += Sum1Ch(d, e, f) + K[t] + X[t]; + c += g; + g += Sum0Maj(h, a, b); + ++t; + + // t = 8 * i + 2 + f += Sum1Ch(c, d, e) + K[t] + X[t]; + b += f; + f += Sum0Maj(g, h, a); + ++t; + + // t = 8 * i + 3 + e += Sum1Ch(b, c, d) + K[t] + X[t]; + a += e; + e += Sum0Maj(f, g, h); + ++t; + + // t = 8 * i + 4 + d += Sum1Ch(a, b, c) + K[t] + X[t]; + h += d; + d += Sum0Maj(e, f, g); + ++t; + + // t = 8 * i + 5 + c += Sum1Ch(h, a, b) + K[t] + X[t]; + g += c; + c += Sum0Maj(d, e, f); + ++t; + + // t = 8 * i + 6 + b += Sum1Ch(g, h, a) + K[t] + X[t]; + f += b; + b += Sum0Maj(c, d, e); + ++t; + + // t = 8 * i + 7 + a += Sum1Ch(f, g, h) + K[t] + X[t]; + e += a; + a += Sum0Maj(b, c, d); + ++t; + } + + H1 += a; + H2 += b; + H3 += c; + H4 += d; + H5 += e; + H6 += f; + H7 += g; + H8 += h; + + // + // reset the offset and clean out the word buffer. + // + xOff = 0; + Array.Clear(X, 0, 16); + } + + private static uint Sum1Ch(uint x, uint y, uint z) + { +// return Sum1(x) + Ch(x, y, z); + return (((x >> 6) | (x << 26)) ^ ((x >> 11) | (x << 21)) ^ ((x >> 25) | (x << 7))) + //+ ((x & y) ^ ((~x) & z)); + + (z ^ (x & (y ^ z))); + } + + private static uint Sum0Maj(uint x, uint y, uint z) + { +// return Sum0(x) + Maj(x, y, z); + return (((x >> 2) | (x << 30)) ^ ((x >> 13) | (x << 19)) ^ ((x >> 22) | (x << 10))) + //+ ((x & y) ^ (x & z) ^ (y & z)); + + ((x & y) | (z & (x ^ y))); + } + +// /* SHA-256 functions */ +// private static uint Ch(uint x, uint y, uint z) +// { +// return (x & y) ^ ((~x) & z); +// //return z ^ (x & (y ^ z)); +// } +// +// private static uint Maj(uint x, uint y, uint z) +// { +// //return (x & y) ^ (x & z) ^ (y & z); +// return (x & y) | (z & (x ^ y)); +// } +// +// private static uint Sum0(uint x) +// { +// return ((x >> 2) | (x << 30)) ^ ((x >> 13) | (x << 19)) ^ ((x >> 22) | (x << 10)); +// } +// +// private static uint Sum1(uint x) +// { +// return ((x >> 6) | (x << 26)) ^ ((x >> 11) | (x << 21)) ^ ((x >> 25) | (x << 7)); +// } + + private static uint Theta0(uint x) + { + return ((x >> 7) | (x << 25)) ^ ((x >> 18) | (x << 14)) ^ (x >> 3); + } + + private static uint Theta1(uint x) + { + return ((x >> 17) | (x << 15)) ^ ((x >> 19) | (x << 13)) ^ (x >> 10); + } + + /* SHA-256 Constants + * (represent the first 32 bits of the fractional parts of the + * cube roots of the first sixty-four prime numbers) + */ + private static readonly uint[] K = { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, + 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, + 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, + 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, + 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, + 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 + }; + + public override IMemoable Copy() + { + return new Sha256Digest(this); + } + + public override void Reset(IMemoable other) + { + Sha256Digest d = (Sha256Digest)other; + + CopyIn(d); + } + + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/Sha256Digest.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/Sha256Digest.cs.meta new file mode 100644 index 0000000..1bac4bc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/Sha256Digest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4414c243bb5c82940a0da3c40f9202b0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/Sha384Digest.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/Sha384Digest.cs new file mode 100644 index 0000000..e6c9a9a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/Sha384Digest.cs @@ -0,0 +1,101 @@ +using System; + +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /** + * Draft FIPS 180-2 implementation of SHA-384. Note: As this is + * based on a draft this implementation is subject to change. + * + *
+     *         block  word  digest
+     * SHA-1   512    32    160
+     * SHA-256 512    32    256
+     * SHA-384 1024   64    384
+     * SHA-512 1024   64    512
+     * 
+ */ + public class Sha384Digest + : LongDigest + { + private const int DigestLength = 48; + + public Sha384Digest() + { + } + + /** + * Copy constructor. This will copy the state of the provided + * message digest. + */ + public Sha384Digest( + Sha384Digest t) + : base(t) + { + } + + public override string AlgorithmName + { + get { return "SHA-384"; } + } + + public override int GetDigestSize() + { + return DigestLength; + } + + public override int DoFinal( + byte[] output, + int outOff) + { + Finish(); + + Pack.UInt64_To_BE(H1, output, outOff); + Pack.UInt64_To_BE(H2, output, outOff + 8); + Pack.UInt64_To_BE(H3, output, outOff + 16); + Pack.UInt64_To_BE(H4, output, outOff + 24); + Pack.UInt64_To_BE(H5, output, outOff + 32); + Pack.UInt64_To_BE(H6, output, outOff + 40); + + Reset(); + + return DigestLength; + } + + /** + * reset the chaining variables + */ + public override void Reset() + { + base.Reset(); + + /* SHA-384 initial hash value + * The first 64 bits of the fractional parts of the square roots + * of the 9th through 16th prime numbers + */ + H1 = 0xcbbb9d5dc1059ed8; + H2 = 0x629a292a367cd507; + H3 = 0x9159015a3070dd17; + H4 = 0x152fecd8f70e5939; + H5 = 0x67332667ffc00b31; + H6 = 0x8eb44a8768581511; + H7 = 0xdb0c2e0d64f98fa7; + H8 = 0x47b5481dbefa4fa4; + } + + public override IMemoable Copy() + { + return new Sha384Digest(this); + } + + public override void Reset(IMemoable other) + { + Sha384Digest d = (Sha384Digest)other; + + CopyIn(d); + } + + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/Sha384Digest.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/Sha384Digest.cs.meta new file mode 100644 index 0000000..d91fa9e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/Sha384Digest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 443b8261a61dd2d4e95ce56544aeb7ae +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/Sha512Digest.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/Sha512Digest.cs new file mode 100644 index 0000000..2a0964f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/Sha512Digest.cs @@ -0,0 +1,104 @@ +using System; + +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /** + * Draft FIPS 180-2 implementation of SHA-512. Note: As this is + * based on a draft this implementation is subject to change. + * + *
+     *         block  word  digest
+     * SHA-1   512    32    160
+     * SHA-256 512    32    256
+     * SHA-384 1024   64    384
+     * SHA-512 1024   64    512
+     * 
+ */ + public class Sha512Digest + : LongDigest + { + private const int DigestLength = 64; + + public Sha512Digest() + { + } + + /** + * Copy constructor. This will copy the state of the provided + * message digest. + */ + public Sha512Digest( + Sha512Digest t) + : base(t) + { + } + + public override string AlgorithmName + { + get { return "SHA-512"; } + } + + public override int GetDigestSize() + { + return DigestLength; + } + + public override int DoFinal( + byte[] output, + int outOff) + { + Finish(); + + Pack.UInt64_To_BE(H1, output, outOff); + Pack.UInt64_To_BE(H2, output, outOff + 8); + Pack.UInt64_To_BE(H3, output, outOff + 16); + Pack.UInt64_To_BE(H4, output, outOff + 24); + Pack.UInt64_To_BE(H5, output, outOff + 32); + Pack.UInt64_To_BE(H6, output, outOff + 40); + Pack.UInt64_To_BE(H7, output, outOff + 48); + Pack.UInt64_To_BE(H8, output, outOff + 56); + + Reset(); + + return DigestLength; + + } + + /** + * reset the chaining variables + */ + public override void Reset() + { + base.Reset(); + + /* SHA-512 initial hash value + * The first 64 bits of the fractional parts of the square roots + * of the first eight prime numbers + */ + H1 = 0x6a09e667f3bcc908; + H2 = 0xbb67ae8584caa73b; + H3 = 0x3c6ef372fe94f82b; + H4 = 0xa54ff53a5f1d36f1; + H5 = 0x510e527fade682d1; + H6 = 0x9b05688c2b3e6c1f; + H7 = 0x1f83d9abfb41bd6b; + H8 = 0x5be0cd19137e2179; + } + + public override IMemoable Copy() + { + return new Sha512Digest(this); + } + + public override void Reset(IMemoable other) + { + Sha512Digest d = (Sha512Digest)other; + + CopyIn(d); + } + + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/Sha512Digest.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/Sha512Digest.cs.meta new file mode 100644 index 0000000..e4dc53f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/Sha512Digest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b2285db00be034c4cb41a9e61f4edf4a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/Sha512tDigest.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/Sha512tDigest.cs new file mode 100644 index 0000000..2caefa7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/Sha512tDigest.cs @@ -0,0 +1,200 @@ +using System; + +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /** + * FIPS 180-4 implementation of SHA-512/t + */ + public class Sha512tDigest + : LongDigest + { + private const ulong A5 = 0xa5a5a5a5a5a5a5a5UL; + + private readonly int digestLength; + + private ulong H1t, H2t, H3t, H4t, H5t, H6t, H7t, H8t; + + /** + * Standard constructor + */ + public Sha512tDigest(int bitLength) + { + if (bitLength >= 512) + throw new ArgumentException("cannot be >= 512", "bitLength"); + if (bitLength % 8 != 0) + throw new ArgumentException("needs to be a multiple of 8", "bitLength"); + if (bitLength == 384) + throw new ArgumentException("cannot be 384 use SHA384 instead", "bitLength"); + + this.digestLength = bitLength / 8; + + tIvGenerate(digestLength * 8); + + Reset(); + } + + /** + * Copy constructor. This will copy the state of the provided + * message digest. + */ + public Sha512tDigest(Sha512tDigest t) + : base(t) + { + this.digestLength = t.digestLength; + + Reset(t); + } + + public override string AlgorithmName + { + get { return "SHA-512/" + (digestLength * 8); } + } + + public override int GetDigestSize() + { + return digestLength; + } + + public override int DoFinal(byte[] output, int outOff) + { + Finish(); + + UInt64_To_BE(H1, output, outOff, digestLength); + UInt64_To_BE(H2, output, outOff + 8, digestLength - 8); + UInt64_To_BE(H3, output, outOff + 16, digestLength - 16); + UInt64_To_BE(H4, output, outOff + 24, digestLength - 24); + UInt64_To_BE(H5, output, outOff + 32, digestLength - 32); + UInt64_To_BE(H6, output, outOff + 40, digestLength - 40); + UInt64_To_BE(H7, output, outOff + 48, digestLength - 48); + UInt64_To_BE(H8, output, outOff + 56, digestLength - 56); + + Reset(); + + return digestLength; + } + + /** + * reset the chaining variables + */ + public override void Reset() + { + base.Reset(); + + /* + * initial hash values use the iv generation algorithm for t. + */ + H1 = H1t; + H2 = H2t; + H3 = H3t; + H4 = H4t; + H5 = H5t; + H6 = H6t; + H7 = H7t; + H8 = H8t; + } + + private void tIvGenerate(int bitLength) + { + H1 = 0x6a09e667f3bcc908UL ^ A5; + H2 = 0xbb67ae8584caa73bUL ^ A5; + H3 = 0x3c6ef372fe94f82bUL ^ A5; + H4 = 0xa54ff53a5f1d36f1UL ^ A5; + H5 = 0x510e527fade682d1UL ^ A5; + H6 = 0x9b05688c2b3e6c1fUL ^ A5; + H7 = 0x1f83d9abfb41bd6bUL ^ A5; + H8 = 0x5be0cd19137e2179UL ^ A5; + + Update(0x53); + Update(0x48); + Update(0x41); + Update(0x2D); + Update(0x35); + Update(0x31); + Update(0x32); + Update(0x2F); + + if (bitLength > 100) + { + Update((byte)(bitLength / 100 + 0x30)); + bitLength = bitLength % 100; + Update((byte)(bitLength / 10 + 0x30)); + bitLength = bitLength % 10; + Update((byte)(bitLength + 0x30)); + } + else if (bitLength > 10) + { + Update((byte)(bitLength / 10 + 0x30)); + bitLength = bitLength % 10; + Update((byte)(bitLength + 0x30)); + } + else + { + Update((byte)(bitLength + 0x30)); + } + + Finish(); + + H1t = H1; + H2t = H2; + H3t = H3; + H4t = H4; + H5t = H5; + H6t = H6; + H7t = H7; + H8t = H8; + } + + private static void UInt64_To_BE(ulong n, byte[] bs, int off, int max) + { + if (max > 0) + { + UInt32_To_BE((uint)(n >> 32), bs, off, max); + + if (max > 4) + { + UInt32_To_BE((uint)n, bs, off + 4, max - 4); + } + } + } + + private static void UInt32_To_BE(uint n, byte[] bs, int off, int max) + { + int num = System.Math.Min(4, max); + while (--num >= 0) + { + int shift = 8 * (3 - num); + bs[off + num] = (byte)(n >> shift); + } + } + + public override IMemoable Copy() + { + return new Sha512tDigest(this); + } + + public override void Reset(IMemoable other) + { + Sha512tDigest t = (Sha512tDigest)other; + + if (this.digestLength != t.digestLength) + { + throw new MemoableResetException("digestLength inappropriate in other"); + } + + base.CopyIn(t); + + this.H1t = t.H1t; + this.H2t = t.H2t; + this.H3t = t.H3t; + this.H4t = t.H4t; + this.H5t = t.H5t; + this.H6t = t.H6t; + this.H7t = t.H7t; + this.H8t = t.H8t; + } + + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/Sha512tDigest.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/Sha512tDigest.cs.meta new file mode 100644 index 0000000..555580c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/Sha512tDigest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ec2249b9429409d468627f6fdbf916e1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/ShakeDigest.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/ShakeDigest.cs new file mode 100644 index 0000000..8d7a7d6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/ShakeDigest.cs @@ -0,0 +1,124 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /// + /// Implementation of SHAKE based on following KeccakNISTInterface.c from http://keccak.noekeon.org/ + /// + /// + /// Following the naming conventions used in the C source code to enable easy review of the implementation. + /// + public class ShakeDigest + : KeccakDigest, IXof + { + private static int CheckBitLength(int bitLength) + { + switch (bitLength) + { + case 128: + case 256: + return bitLength; + default: + throw new ArgumentException(bitLength + " not supported for SHAKE", "bitLength"); + } + } + + public ShakeDigest() + : this(128) + { + } + + public ShakeDigest(int bitLength) + : base(CheckBitLength(bitLength)) + { + } + + public ShakeDigest(ShakeDigest source) + : base(source) + { + } + + public override string AlgorithmName + { + get { return "SHAKE" + fixedOutputLength; } + } + + public override int GetDigestSize() + { + return fixedOutputLength >> 2; + } + + public override int DoFinal(byte[] output, int outOff) + { + return DoFinal(output, outOff, GetDigestSize()); + } + + public virtual int DoFinal(byte[] output, int outOff, int outLen) + { + int length = DoOutput(output, outOff, outLen); + + Reset(); + + return length; + } + + public virtual int DoOutput(byte[] output, int outOff, int outLen) + { + if (!squeezing) + { + AbsorbBits(0x0F, 4); + } + + Squeeze(output, outOff, (long)outLen << 3); + + return outLen; + } + + /* + * TODO Possible API change to support partial-byte suffixes. + */ + protected override int DoFinal(byte[] output, int outOff, byte partialByte, int partialBits) + { + return DoFinal(output, outOff, GetDigestSize(), partialByte, partialBits); + } + + /* + * TODO Possible API change to support partial-byte suffixes. + */ + protected virtual int DoFinal(byte[] output, int outOff, int outLen, byte partialByte, int partialBits) + { + if (partialBits < 0 || partialBits > 7) + throw new ArgumentException("must be in the range [0,7]", "partialBits"); + + int finalInput = (partialByte & ((1 << partialBits) - 1)) | (0x0F << partialBits); + Debug.Assert(finalInput >= 0); + int finalBits = partialBits + 4; + + if (finalBits >= 8) + { + Absorb((byte)finalInput); + finalBits -= 8; + finalInput >>= 8; + } + + if (finalBits > 0) + { + AbsorbBits(finalInput, finalBits); + } + + Squeeze(output, outOff, (long)outLen << 3); + + Reset(); + + return outLen; + } + + public override IMemoable Copy() + { + return new ShakeDigest(this); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/ShakeDigest.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/ShakeDigest.cs.meta new file mode 100644 index 0000000..26b6cf7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/ShakeDigest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e26479186e9b53c4794a86b0b47a0c8f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/ShortenedDigest.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/ShortenedDigest.cs new file mode 100644 index 0000000..9e4d99e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/ShortenedDigest.cs @@ -0,0 +1,82 @@ +using System; +using Org.BouncyCastle.Crypto; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /** + * Wrapper class that reduces the output length of a particular digest to + * only the first n bytes of the digest function. + */ + public class ShortenedDigest + : IDigest + { + private IDigest baseDigest; + private int length; + + /** + * Base constructor. + * + * @param baseDigest underlying digest to use. + * @param length length in bytes of the output of doFinal. + * @exception ArgumentException if baseDigest is null, or length is greater than baseDigest.GetDigestSize(). + */ + public ShortenedDigest( + IDigest baseDigest, + int length) + { + if (baseDigest == null) + { + throw new ArgumentNullException("baseDigest"); + } + + if (length > baseDigest.GetDigestSize()) + { + throw new ArgumentException("baseDigest output not large enough to support length"); + } + + this.baseDigest = baseDigest; + this.length = length; + } + + public string AlgorithmName + { + get { return baseDigest.AlgorithmName + "(" + length * 8 + ")"; } + } + + public int GetDigestSize() + { + return length; + } + + public void Update(byte input) + { + baseDigest.Update(input); + } + + public void BlockUpdate(byte[] input, int inOff, int length) + { + baseDigest.BlockUpdate(input, inOff, length); + } + + public int DoFinal(byte[] output, int outOff) + { + byte[] tmp = new byte[baseDigest.GetDigestSize()]; + + baseDigest.DoFinal(tmp, 0); + + Array.Copy(tmp, 0, output, outOff, length); + + return length; + } + + public void Reset() + { + baseDigest.Reset(); + } + + public int GetByteLength() + { + return baseDigest.GetByteLength(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/ShortenedDigest.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/ShortenedDigest.cs.meta new file mode 100644 index 0000000..f036a82 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/ShortenedDigest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e5aa5d4d299e2e345abb92ffaf7d5a24 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/SkeinDigest.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/SkeinDigest.cs new file mode 100644 index 0000000..f826ce5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/SkeinDigest.cs @@ -0,0 +1,117 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + + /// + /// Implementation of the Skein parameterised hash function in 256, 512 and 1024 bit block sizes, + /// based on the Threefish tweakable block cipher. + /// + /// + /// This is the 1.3 version of Skein defined in the Skein hash function submission to the NIST SHA-3 + /// competition in October 2010. + ///

+ /// Skein was designed by Niels Ferguson - Stefan Lucks - Bruce Schneier - Doug Whiting - Mihir + /// Bellare - Tadayoshi Kohno - Jon Callas - Jesse Walker. + /// + /// + /// + public class SkeinDigest + : IDigest, IMemoable + { + ///

+ /// 256 bit block size - Skein-256 + /// + public const int SKEIN_256 = SkeinEngine.SKEIN_256; + /// + /// 512 bit block size - Skein-512 + /// + public const int SKEIN_512 = SkeinEngine.SKEIN_512; + /// + /// 1024 bit block size - Skein-1024 + /// + public const int SKEIN_1024 = SkeinEngine.SKEIN_1024; + + private readonly SkeinEngine engine; + + /// + /// Constructs a Skein digest with an internal state size and output size. + /// + /// the internal state size in bits - one of or + /// . + /// the output/digest size to produce in bits, which must be an integral number of + /// bytes. + public SkeinDigest(int stateSizeBits, int digestSizeBits) + { + this.engine = new SkeinEngine(stateSizeBits, digestSizeBits); + Init(null); + } + + public SkeinDigest(SkeinDigest digest) + { + this.engine = new SkeinEngine(digest.engine); + } + + public void Reset(IMemoable other) + { + SkeinDigest d = (SkeinDigest)other; + engine.Reset(d.engine); + } + + public IMemoable Copy() + { + return new SkeinDigest(this); + } + + public String AlgorithmName + { + get { return "Skein-" + (engine.BlockSize * 8) + "-" + (engine.OutputSize * 8); } + } + + public int GetDigestSize() + { + return engine.OutputSize; + } + + public int GetByteLength() + { + return engine.BlockSize; + } + + /// + /// Optionally initialises the Skein digest with the provided parameters. + /// + /// See for details on the parameterisation of the Skein hash function. + /// the parameters to apply to this engine, or null to use no parameters. + public void Init(SkeinParameters parameters) + { + engine.Init(parameters); + } + + public void Reset() + { + engine.Reset(); + } + + public void Update(byte inByte) + { + engine.Update(inByte); + } + + public void BlockUpdate(byte[] inBytes, int inOff, int len) + { + engine.Update(inBytes, inOff, len); + } + + public int DoFinal(byte[] outBytes, int outOff) + { + return engine.DoFinal(outBytes, outOff); + } + + } +} \ No newline at end of file diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/SkeinDigest.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/SkeinDigest.cs.meta new file mode 100644 index 0000000..9dd732b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/SkeinDigest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c6dd8ac7d2319a24bbc5f8e8ecc008c8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/SkeinEngine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/SkeinEngine.cs new file mode 100644 index 0000000..cfedfad --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/SkeinEngine.cs @@ -0,0 +1,804 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + + /// + /// Implementation of the Skein family of parameterised hash functions in 256, 512 and 1024 bit block + /// sizes, based on the Threefish tweakable block cipher. + /// + /// + /// This is the 1.3 version of Skein defined in the Skein hash function submission to the NIST SHA-3 + /// competition in October 2010. + ///

+ /// Skein was designed by Niels Ferguson - Stefan Lucks - Bruce Schneier - Doug Whiting - Mihir + /// Bellare - Tadayoshi Kohno - Jon Callas - Jesse Walker. + ///

+ /// This implementation is the basis for and , implementing the + /// parameter based configuration system that allows Skein to be adapted to multiple applications.
+ /// Initialising the engine with allows standard and arbitrary parameters to + /// be applied during the Skein hash function. + ///

+ /// Implemented: + ///

    + ///
  • 256, 512 and 1024 bit internal states.
  • + ///
  • Full 96 bit input length.
  • + ///
  • Parameters defined in the Skein specification, and arbitrary other pre and post message + /// parameters.
  • + ///
  • Arbitrary output size in 1 byte intervals.
  • + ///
+ ///

+ /// Not implemented: + ///

    + ///
  • Sub-byte length input (bit padding).
  • + ///
  • Tree hashing.
  • + ///
+ ///
+ /// + public class SkeinEngine + : IMemoable + { + /// + /// 256 bit block size - Skein-256 + /// + public const int SKEIN_256 = ThreefishEngine.BLOCKSIZE_256; + /// + /// 512 bit block size - Skein-512 + /// + public const int SKEIN_512 = ThreefishEngine.BLOCKSIZE_512; + /// + /// 1024 bit block size - Skein-1024 + /// + public const int SKEIN_1024 = ThreefishEngine.BLOCKSIZE_1024; + + // Minimal at present, but more complex when tree hashing is implemented + private class Configuration + { + private byte[] bytes = new byte[32]; + + public Configuration(long outputSizeBits) + { + // 0..3 = ASCII SHA3 + bytes[0] = (byte)'S'; + bytes[1] = (byte)'H'; + bytes[2] = (byte)'A'; + bytes[3] = (byte)'3'; + + // 4..5 = version number in LSB order + bytes[4] = 1; + bytes[5] = 0; + + // 8..15 = output length + ThreefishEngine.WordToBytes((ulong)outputSizeBits, bytes, 8); + } + + public byte[] Bytes + { + get { return bytes; } + } + + } + + public class Parameter + { + private int type; + private byte[] value; + + public Parameter(int type, byte[] value) + { + this.type = type; + this.value = value; + } + + public int Type + { + get { return type; } + } + + public byte[] Value + { + get { return value; } + } + + } + + /** + * The parameter type for the Skein key. + */ + private const int PARAM_TYPE_KEY = 0; + + /** + * The parameter type for the Skein configuration block. + */ + private const int PARAM_TYPE_CONFIG = 4; + + /** + * The parameter type for the message. + */ + private const int PARAM_TYPE_MESSAGE = 48; + + /** + * The parameter type for the output transformation. + */ + private const int PARAM_TYPE_OUTPUT = 63; + + /** + * Precalculated UBI(CFG) states for common state/output combinations without key or other + * pre-message params. + */ + private static readonly IDictionary INITIAL_STATES = Platform.CreateHashtable(); + + static SkeinEngine() + { + // From Appendix C of the Skein 1.3 NIST submission + InitialState(SKEIN_256, 128, new ulong[]{ + 0xe1111906964d7260UL, + 0x883daaa77c8d811cUL, + 0x10080df491960f7aUL, + 0xccf7dde5b45bc1c2UL}); + + InitialState(SKEIN_256, 160, new ulong[]{ + 0x1420231472825e98UL, + 0x2ac4e9a25a77e590UL, + 0xd47a58568838d63eUL, + 0x2dd2e4968586ab7dUL}); + + InitialState(SKEIN_256, 224, new ulong[]{ + 0xc6098a8c9ae5ea0bUL, + 0x876d568608c5191cUL, + 0x99cb88d7d7f53884UL, + 0x384bddb1aeddb5deUL}); + + InitialState(SKEIN_256, 256, new ulong[]{ + 0xfc9da860d048b449UL, + 0x2fca66479fa7d833UL, + 0xb33bc3896656840fUL, + 0x6a54e920fde8da69UL}); + + InitialState(SKEIN_512, 128, new ulong[]{ + 0xa8bc7bf36fbf9f52UL, + 0x1e9872cebd1af0aaUL, + 0x309b1790b32190d3UL, + 0xbcfbb8543f94805cUL, + 0x0da61bcd6e31b11bUL, + 0x1a18ebead46a32e3UL, + 0xa2cc5b18ce84aa82UL, + 0x6982ab289d46982dUL}); + + InitialState(SKEIN_512, 160, new ulong[]{ + 0x28b81a2ae013bd91UL, + 0xc2f11668b5bdf78fUL, + 0x1760d8f3f6a56f12UL, + 0x4fb747588239904fUL, + 0x21ede07f7eaf5056UL, + 0xd908922e63ed70b8UL, + 0xb8ec76ffeccb52faUL, + 0x01a47bb8a3f27a6eUL}); + + InitialState(SKEIN_512, 224, new ulong[]{ + 0xccd0616248677224UL, + 0xcba65cf3a92339efUL, + 0x8ccd69d652ff4b64UL, + 0x398aed7b3ab890b4UL, + 0x0f59d1b1457d2bd0UL, + 0x6776fe6575d4eb3dUL, + 0x99fbc70e997413e9UL, + 0x9e2cfccfe1c41ef7UL}); + + InitialState(SKEIN_512, 384, new ulong[]{ + 0xa3f6c6bf3a75ef5fUL, + 0xb0fef9ccfd84faa4UL, + 0x9d77dd663d770cfeUL, + 0xd798cbf3b468fddaUL, + 0x1bc4a6668a0e4465UL, + 0x7ed7d434e5807407UL, + 0x548fc1acd4ec44d6UL, + 0x266e17546aa18ff8UL}); + + InitialState(SKEIN_512, 512, new ulong[]{ + 0x4903adff749c51ceUL, + 0x0d95de399746df03UL, + 0x8fd1934127c79bceUL, + 0x9a255629ff352cb1UL, + 0x5db62599df6ca7b0UL, + 0xeabe394ca9d5c3f4UL, + 0x991112c71a75b523UL, + 0xae18a40b660fcc33UL}); + } + + private static void InitialState(int blockSize, int outputSize, ulong[] state) + { + INITIAL_STATES.Add(VariantIdentifier(blockSize / 8, outputSize / 8), state); + } + + private static int VariantIdentifier(int blockSizeBytes, int outputSizeBytes) + { + return (outputSizeBytes << 16) | blockSizeBytes; + } + + private class UbiTweak + { + /** + * Point at which position might overflow long, so switch to add with carry logic + */ + private const ulong LOW_RANGE = UInt64.MaxValue - UInt32.MaxValue; + + /** + * Bit 127 = final + */ + private const ulong T1_FINAL = 1UL << 63; + + /** + * Bit 126 = first + */ + private const ulong T1_FIRST = 1UL << 62; + + /** + * UBI uses a 128 bit tweak + */ + private ulong[] tweak = new ulong[2]; + + /** + * Whether 64 bit position exceeded + */ + private bool extendedPosition; + + public UbiTweak() + { + Reset(); + } + + public void Reset(UbiTweak tweak) + { + this.tweak = Arrays.Clone(tweak.tweak, this.tweak); + this.extendedPosition = tweak.extendedPosition; + } + + public void Reset() + { + tweak[0] = 0; + tweak[1] = 0; + extendedPosition = false; + First = true; + } + + public uint Type + { + get + { + return (uint)((tweak[1] >> 56) & 0x3FUL); + } + + set + { + // Bits 120..125 = type + tweak[1] = (tweak[1] & 0xFFFFFFC000000000UL) | ((value & 0x3FUL) << 56); + } + } + + public bool First + { + get + { + return ((tweak[1] & T1_FIRST) != 0); + } + set + { + if (value) + { + tweak[1] |= T1_FIRST; + } + else + { + tweak[1] &= ~T1_FIRST; + } + } + } + + public bool Final + { + get + { + return ((tweak[1] & T1_FINAL) != 0); + } + set + { + if (value) + { + tweak[1] |= T1_FINAL; + } + else + { + tweak[1] &= ~T1_FINAL; + } + } + } + + /** + * Advances the position in the tweak by the specified value. + */ + public void AdvancePosition(int advance) + { + // Bits 0..95 = position + if (extendedPosition) + { + ulong[] parts = new ulong[3]; + parts[0] = tweak[0] & 0xFFFFFFFFUL; + parts[1] = (tweak[0] >> 32) & 0xFFFFFFFFUL; + parts[2] = tweak[1] & 0xFFFFFFFFUL; + + ulong carry = (ulong)advance; + for (int i = 0; i < parts.Length; i++) + { + carry += parts[i]; + parts[i] = carry; + carry >>= 32; + } + tweak[0] = ((parts[1] & 0xFFFFFFFFUL) << 32) | (parts[0] & 0xFFFFFFFFUL); + tweak[1] = (tweak[1] & 0xFFFFFFFF00000000UL) | (parts[2] & 0xFFFFFFFFUL); + } + else + { + ulong position = tweak[0]; + position += (uint)advance; + tweak[0] = position; + if (position > LOW_RANGE) + { + extendedPosition = true; + } + } + } + + public ulong[] GetWords() + { + return tweak; + } + + public override string ToString() + { + return Type + " first: " + First + ", final: " + Final; + } + + } + + /** + * The Unique Block Iteration chaining mode. + */ + // TODO: This might be better as methods... + private class UBI + { + private readonly UbiTweak tweak = new UbiTweak(); + + private readonly SkeinEngine engine; + + /** + * Buffer for the current block of message data + */ + private byte[] currentBlock; + + /** + * Offset into the current message block + */ + private int currentOffset; + + /** + * Buffer for message words for feedback into encrypted block + */ + private ulong[] message; + + public UBI(SkeinEngine engine, int blockSize) + { + this.engine = engine; + currentBlock = new byte[blockSize]; + message = new ulong[currentBlock.Length / 8]; + } + + public void Reset(UBI ubi) + { + currentBlock = Arrays.Clone(ubi.currentBlock, currentBlock); + currentOffset = ubi.currentOffset; + message = Arrays.Clone(ubi.message, this.message); + tweak.Reset(ubi.tweak); + } + + public void Reset(int type) + { + tweak.Reset(); + tweak.Type = (uint)type; + currentOffset = 0; + } + + public void Update(byte[] value, int offset, int len, ulong[] output) + { + /* + * Buffer complete blocks for the underlying Threefish cipher, only flushing when there + * are subsequent bytes (last block must be processed in doFinal() with final=true set). + */ + int copied = 0; + while (len > copied) + { + if (currentOffset == currentBlock.Length) + { + ProcessBlock(output); + tweak.First = false; + currentOffset = 0; + } + + int toCopy = System.Math.Min((len - copied), currentBlock.Length - currentOffset); + Array.Copy(value, offset + copied, currentBlock, currentOffset, toCopy); + copied += toCopy; + currentOffset += toCopy; + tweak.AdvancePosition(toCopy); + } + } + + private void ProcessBlock(ulong[] output) + { + engine.threefish.Init(true, engine.chain, tweak.GetWords()); + for (int i = 0; i < message.Length; i++) + { + message[i] = ThreefishEngine.BytesToWord(currentBlock, i * 8); + } + + engine.threefish.ProcessBlock(message, output); + + for (int i = 0; i < output.Length; i++) + { + output[i] ^= message[i]; + } + } + + public void DoFinal(ulong[] output) + { + // Pad remainder of current block with zeroes + for (int i = currentOffset; i < currentBlock.Length; i++) + { + currentBlock[i] = 0; + } + + tweak.Final = true; + ProcessBlock(output); + } + + } + + /** + * Underlying Threefish tweakable block cipher + */ + private readonly ThreefishEngine threefish; + + /** + * Size of the digest output, in bytes + */ + private readonly int outputSizeBytes; + + /** + * The current chaining/state value + */ + private ulong[] chain; + + /** + * The initial state value + */ + private ulong[] initialState; + + /** + * The (optional) key parameter + */ + private byte[] key; + + /** + * Parameters to apply prior to the message + */ + private Parameter[] preMessageParameters; + + /** + * Parameters to apply after the message, but prior to output + */ + private Parameter[] postMessageParameters; + + /** + * The current UBI operation + */ + private readonly UBI ubi; + + /** + * Buffer for single byte update method + */ + private readonly byte[] singleByte = new byte[1]; + + /// + /// Constructs a Skein digest with an internal state size and output size. + /// + /// the internal state size in bits - one of or + /// . + /// the output/digest size to produce in bits, which must be an integral number of + /// bytes. + public SkeinEngine(int blockSizeBits, int outputSizeBits) + { + if (outputSizeBits % 8 != 0) + { + throw new ArgumentException("Output size must be a multiple of 8 bits. :" + outputSizeBits); + } + // TODO: Prevent digest sizes > block size? + this.outputSizeBytes = outputSizeBits / 8; + + this.threefish = new ThreefishEngine(blockSizeBits); + this.ubi = new UBI(this,threefish.GetBlockSize()); + } + + /// + /// Creates a SkeinEngine as an exact copy of an existing instance. + /// + public SkeinEngine(SkeinEngine engine) + : this(engine.BlockSize * 8, engine.OutputSize * 8) + { + CopyIn(engine); + } + + private void CopyIn(SkeinEngine engine) + { + this.ubi.Reset(engine.ubi); + this.chain = Arrays.Clone(engine.chain, this.chain); + this.initialState = Arrays.Clone(engine.initialState, this.initialState); + this.key = Arrays.Clone(engine.key, this.key); + this.preMessageParameters = Clone(engine.preMessageParameters, this.preMessageParameters); + this.postMessageParameters = Clone(engine.postMessageParameters, this.postMessageParameters); + } + + private static Parameter[] Clone(Parameter[] data, Parameter[] existing) + { + if (data == null) + { + return null; + } + if ((existing == null) || (existing.Length != data.Length)) + { + existing = new Parameter[data.Length]; + } + Array.Copy(data, 0, existing, 0, existing.Length); + return existing; + } + + public IMemoable Copy() + { + return new SkeinEngine(this); + } + + public void Reset(IMemoable other) + { + SkeinEngine s = (SkeinEngine)other; + if ((BlockSize != s.BlockSize) || (outputSizeBytes != s.outputSizeBytes)) + { + throw new MemoableResetException("Incompatible parameters in provided SkeinEngine."); + } + CopyIn(s); + } + + public int OutputSize + { + get { return outputSizeBytes; } + } + + public int BlockSize + { + get { return threefish.GetBlockSize (); } + } + + /// + /// Initialises the Skein engine with the provided parameters. See for + /// details on the parameterisation of the Skein hash function. + /// + /// the parameters to apply to this engine, or null to use no parameters. + public void Init(SkeinParameters parameters) + { + this.chain = null; + this.key = null; + this.preMessageParameters = null; + this.postMessageParameters = null; + + if (parameters != null) + { + byte[] key = parameters.GetKey(); + if (key.Length < 16) + { + throw new ArgumentException("Skein key must be at least 128 bits."); + } + InitParams(parameters.GetParameters()); + } + CreateInitialState(); + + // Initialise message block + UbiInit(PARAM_TYPE_MESSAGE); + } + + private void InitParams(IDictionary parameters) + { + IEnumerator keys = parameters.Keys.GetEnumerator(); + IList pre = Platform.CreateArrayList(); + IList post = Platform.CreateArrayList(); + + while (keys.MoveNext()) + { + int type = (int)keys.Current; + byte[] value = (byte[])parameters[type]; + + if (type == PARAM_TYPE_KEY) + { + this.key = value; + } + else if (type < PARAM_TYPE_MESSAGE) + { + pre.Add(new Parameter(type, value)); + } + else + { + post.Add(new Parameter(type, value)); + } + } + preMessageParameters = new Parameter[pre.Count]; + pre.CopyTo(preMessageParameters, 0); + Array.Sort(preMessageParameters); + + postMessageParameters = new Parameter[post.Count]; + post.CopyTo(postMessageParameters, 0); + Array.Sort(postMessageParameters); + } + + /** + * Calculate the initial (pre message block) chaining state. + */ + private void CreateInitialState() + { + ulong[] precalc = (ulong[])INITIAL_STATES[VariantIdentifier(BlockSize, OutputSize)]; + if ((key == null) && (precalc != null)) + { + // Precalculated UBI(CFG) + chain = Arrays.Clone(precalc); + } + else + { + // Blank initial state + chain = new ulong[BlockSize / 8]; + + // Process key block + if (key != null) + { + UbiComplete(SkeinParameters.PARAM_TYPE_KEY, key); + } + + // Process configuration block + UbiComplete(PARAM_TYPE_CONFIG, new Configuration(outputSizeBytes * 8).Bytes); + } + + // Process additional pre-message parameters + if (preMessageParameters != null) + { + for (int i = 0; i < preMessageParameters.Length; i++) + { + Parameter param = preMessageParameters[i]; + UbiComplete(param.Type, param.Value); + } + } + initialState = Arrays.Clone(chain); + } + + /// + /// Reset the engine to the initial state (with the key and any pre-message parameters , ready to + /// accept message input. + /// + public void Reset() + { + Array.Copy(initialState, 0, chain, 0, chain.Length); + + UbiInit(PARAM_TYPE_MESSAGE); + } + + private void UbiComplete(int type, byte[] value) + { + UbiInit(type); + this.ubi.Update(value, 0, value.Length, chain); + UbiFinal(); + } + + private void UbiInit(int type) + { + this.ubi.Reset(type); + } + + private void UbiFinal() + { + ubi.DoFinal(chain); + } + + private void CheckInitialised() + { + if (this.ubi == null) + { + throw new ArgumentException("Skein engine is not initialised."); + } + } + + public void Update(byte inByte) + { + singleByte[0] = inByte; + Update(singleByte, 0, 1); + } + + public void Update(byte[] inBytes, int inOff, int len) + { + CheckInitialised(); + ubi.Update(inBytes, inOff, len, chain); + } + + public int DoFinal(byte[] outBytes, int outOff) + { + CheckInitialised(); + if (outBytes.Length < (outOff + outputSizeBytes)) + { + throw new DataLengthException("Output buffer is too short to hold output"); + } + + // Finalise message block + UbiFinal(); + + // Process additional post-message parameters + if (postMessageParameters != null) + { + for (int i = 0; i < postMessageParameters.Length; i++) + { + Parameter param = postMessageParameters[i]; + UbiComplete(param.Type, param.Value); + } + } + + // Perform the output transform + int blockSize = BlockSize; + int blocksRequired = ((outputSizeBytes + blockSize - 1) / blockSize); + for (int i = 0; i < blocksRequired; i++) + { + int toWrite = System.Math.Min(blockSize, outputSizeBytes - (i * blockSize)); + Output((ulong)i, outBytes, outOff + (i * blockSize), toWrite); + } + + Reset(); + + return outputSizeBytes; + } + + private void Output(ulong outputSequence, byte[] outBytes, int outOff, int outputBytes) + { + byte[] currentBytes = new byte[8]; + ThreefishEngine.WordToBytes(outputSequence, currentBytes, 0); + + // Output is a sequence of UBI invocations all of which use and preserve the pre-output + // state + ulong[] outputWords = new ulong[chain.Length]; + UbiInit(PARAM_TYPE_OUTPUT); + this.ubi.Update(currentBytes, 0, currentBytes.Length, outputWords); + ubi.DoFinal(outputWords); + + int wordsRequired = ((outputBytes + 8 - 1) / 8); + for (int i = 0; i < wordsRequired; i++) + { + int toWrite = System.Math.Min(8, outputBytes - (i * 8)); + if (toWrite == 8) + { + ThreefishEngine.WordToBytes(outputWords[i], outBytes, outOff + (i * 8)); + } + else + { + ThreefishEngine.WordToBytes(outputWords[i], currentBytes, 0); + Array.Copy(currentBytes, 0, outBytes, outOff + (i * 8), toWrite); + } + } + } + + } +} + diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/SkeinEngine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/SkeinEngine.cs.meta new file mode 100644 index 0000000..4b854cb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/SkeinEngine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 61c5194302debc74189a01c1f4208df7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/TigerDigest.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/TigerDigest.cs new file mode 100644 index 0000000..059232d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/TigerDigest.cs @@ -0,0 +1,883 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /** + * implementation of Tiger based on: + * + * http://www.cs.technion.ac.il/~biham/Reports/Tiger + */ + public class TigerDigest + : IDigest, IMemoable + { + private const int MyByteLength = 64; + + /* + * S-Boxes. + */ + private static readonly long[] t1 = { + unchecked((long) 0x02AAB17CF7E90C5EL) /* 0 */, unchecked((long) 0xAC424B03E243A8ECL) /* 1 */, + unchecked((long) 0x72CD5BE30DD5FCD3L) /* 2 */, unchecked((long) 0x6D019B93F6F97F3AL) /* 3 */, + unchecked((long) 0xCD9978FFD21F9193L) /* 4 */, unchecked((long) 0x7573A1C9708029E2L) /* 5 */, + unchecked((long) 0xB164326B922A83C3L) /* 6 */, unchecked((long) 0x46883EEE04915870L) /* 7 */, + unchecked((long) 0xEAACE3057103ECE6L) /* 8 */, unchecked((long) 0xC54169B808A3535CL) /* 9 */, + unchecked((long) 0x4CE754918DDEC47CL) /* 10 */, unchecked((long) 0x0AA2F4DFDC0DF40CL) /* 11 */, + unchecked((long) 0x10B76F18A74DBEFAL) /* 12 */, unchecked((long) 0xC6CCB6235AD1AB6AL) /* 13 */, + unchecked((long) 0x13726121572FE2FFL) /* 14 */, unchecked((long) 0x1A488C6F199D921EL) /* 15 */, + unchecked((long) 0x4BC9F9F4DA0007CAL) /* 16 */, unchecked((long) 0x26F5E6F6E85241C7L) /* 17 */, + unchecked((long) 0x859079DBEA5947B6L) /* 18 */, unchecked((long) 0x4F1885C5C99E8C92L) /* 19 */, + unchecked((long) 0xD78E761EA96F864BL) /* 20 */, unchecked((long) 0x8E36428C52B5C17DL) /* 21 */, + unchecked((long) 0x69CF6827373063C1L) /* 22 */, unchecked((long) 0xB607C93D9BB4C56EL) /* 23 */, + unchecked((long) 0x7D820E760E76B5EAL) /* 24 */, unchecked((long) 0x645C9CC6F07FDC42L) /* 25 */, + unchecked((long) 0xBF38A078243342E0L) /* 26 */, unchecked((long) 0x5F6B343C9D2E7D04L) /* 27 */, + unchecked((long) 0xF2C28AEB600B0EC6L) /* 28 */, unchecked((long) 0x6C0ED85F7254BCACL) /* 29 */, + unchecked((long) 0x71592281A4DB4FE5L) /* 30 */, unchecked((long) 0x1967FA69CE0FED9FL) /* 31 */, + unchecked((long) 0xFD5293F8B96545DBL) /* 32 */, unchecked((long) 0xC879E9D7F2A7600BL) /* 33 */, + unchecked((long) 0x860248920193194EL) /* 34 */, unchecked((long) 0xA4F9533B2D9CC0B3L) /* 35 */, + unchecked((long) 0x9053836C15957613L) /* 36 */, unchecked((long) 0xDB6DCF8AFC357BF1L) /* 37 */, + unchecked((long) 0x18BEEA7A7A370F57L) /* 38 */, unchecked((long) 0x037117CA50B99066L) /* 39 */, + unchecked((long) 0x6AB30A9774424A35L) /* 40 */, unchecked((long) 0xF4E92F02E325249BL) /* 41 */, + unchecked((long) 0x7739DB07061CCAE1L) /* 42 */, unchecked((long) 0xD8F3B49CECA42A05L) /* 43 */, + unchecked((long) 0xBD56BE3F51382F73L) /* 44 */, unchecked((long) 0x45FAED5843B0BB28L) /* 45 */, + unchecked((long) 0x1C813D5C11BF1F83L) /* 46 */, unchecked((long) 0x8AF0E4B6D75FA169L) /* 47 */, + unchecked((long) 0x33EE18A487AD9999L) /* 48 */, unchecked((long) 0x3C26E8EAB1C94410L) /* 49 */, + unchecked((long) 0xB510102BC0A822F9L) /* 50 */, unchecked((long) 0x141EEF310CE6123BL) /* 51 */, + unchecked((long) 0xFC65B90059DDB154L) /* 52 */, unchecked((long) 0xE0158640C5E0E607L) /* 53 */, + unchecked((long) 0x884E079826C3A3CFL) /* 54 */, unchecked((long) 0x930D0D9523C535FDL) /* 55 */, + unchecked((long) 0x35638D754E9A2B00L) /* 56 */, unchecked((long) 0x4085FCCF40469DD5L) /* 57 */, + unchecked((long) 0xC4B17AD28BE23A4CL) /* 58 */, unchecked((long) 0xCAB2F0FC6A3E6A2EL) /* 59 */, + unchecked((long) 0x2860971A6B943FCDL) /* 60 */, unchecked((long) 0x3DDE6EE212E30446L) /* 61 */, + unchecked((long) 0x6222F32AE01765AEL) /* 62 */, unchecked((long) 0x5D550BB5478308FEL) /* 63 */, + unchecked((long) 0xA9EFA98DA0EDA22AL) /* 64 */, unchecked((long) 0xC351A71686C40DA7L) /* 65 */, + unchecked((long) 0x1105586D9C867C84L) /* 66 */, unchecked((long) 0xDCFFEE85FDA22853L) /* 67 */, + unchecked((long) 0xCCFBD0262C5EEF76L) /* 68 */, unchecked((long) 0xBAF294CB8990D201L) /* 69 */, + unchecked((long) 0xE69464F52AFAD975L) /* 70 */, unchecked((long) 0x94B013AFDF133E14L) /* 71 */, + unchecked((long) 0x06A7D1A32823C958L) /* 72 */, unchecked((long) 0x6F95FE5130F61119L) /* 73 */, + unchecked((long) 0xD92AB34E462C06C0L) /* 74 */, unchecked((long) 0xED7BDE33887C71D2L) /* 75 */, + unchecked((long) 0x79746D6E6518393EL) /* 76 */, unchecked((long) 0x5BA419385D713329L) /* 77 */, + unchecked((long) 0x7C1BA6B948A97564L) /* 78 */, unchecked((long) 0x31987C197BFDAC67L) /* 79 */, + unchecked((long) 0xDE6C23C44B053D02L) /* 80 */, unchecked((long) 0x581C49FED002D64DL) /* 81 */, + unchecked((long) 0xDD474D6338261571L) /* 82 */, unchecked((long) 0xAA4546C3E473D062L) /* 83 */, + unchecked((long) 0x928FCE349455F860L) /* 84 */, unchecked((long) 0x48161BBACAAB94D9L) /* 85 */, + unchecked((long) 0x63912430770E6F68L) /* 86 */, unchecked((long) 0x6EC8A5E602C6641CL) /* 87 */, + unchecked((long) 0x87282515337DDD2BL) /* 88 */, unchecked((long) 0x2CDA6B42034B701BL) /* 89 */, + unchecked((long) 0xB03D37C181CB096DL) /* 90 */, unchecked((long) 0xE108438266C71C6FL) /* 91 */, + unchecked((long) 0x2B3180C7EB51B255L) /* 92 */, unchecked((long) 0xDF92B82F96C08BBCL) /* 93 */, + unchecked((long) 0x5C68C8C0A632F3BAL) /* 94 */, unchecked((long) 0x5504CC861C3D0556L) /* 95 */, + unchecked((long) 0xABBFA4E55FB26B8FL) /* 96 */, unchecked((long) 0x41848B0AB3BACEB4L) /* 97 */, + unchecked((long) 0xB334A273AA445D32L) /* 98 */, unchecked((long) 0xBCA696F0A85AD881L) /* 99 */, + unchecked((long) 0x24F6EC65B528D56CL) /* 100 */, unchecked((long) 0x0CE1512E90F4524AL) /* 101 */, + unchecked((long) 0x4E9DD79D5506D35AL) /* 102 */, unchecked((long) 0x258905FAC6CE9779L) /* 103 */, + unchecked((long) 0x2019295B3E109B33L) /* 104 */, unchecked((long) 0xF8A9478B73A054CCL) /* 105 */, + unchecked((long) 0x2924F2F934417EB0L) /* 106 */, unchecked((long) 0x3993357D536D1BC4L) /* 107 */, + unchecked((long) 0x38A81AC21DB6FF8BL) /* 108 */, unchecked((long) 0x47C4FBF17D6016BFL) /* 109 */, + unchecked((long) 0x1E0FAADD7667E3F5L) /* 110 */, unchecked((long) 0x7ABCFF62938BEB96L) /* 111 */, + unchecked((long) 0xA78DAD948FC179C9L) /* 112 */, unchecked((long) 0x8F1F98B72911E50DL) /* 113 */, + unchecked((long) 0x61E48EAE27121A91L) /* 114 */, unchecked((long) 0x4D62F7AD31859808L) /* 115 */, + unchecked((long) 0xECEBA345EF5CEAEBL) /* 116 */, unchecked((long) 0xF5CEB25EBC9684CEL) /* 117 */, + unchecked((long) 0xF633E20CB7F76221L) /* 118 */, unchecked((long) 0xA32CDF06AB8293E4L) /* 119 */, + unchecked((long) 0x985A202CA5EE2CA4L) /* 120 */, unchecked((long) 0xCF0B8447CC8A8FB1L) /* 121 */, + unchecked((long) 0x9F765244979859A3L) /* 122 */, unchecked((long) 0xA8D516B1A1240017L) /* 123 */, + unchecked((long) 0x0BD7BA3EBB5DC726L) /* 124 */, unchecked((long) 0xE54BCA55B86ADB39L) /* 125 */, + unchecked((long) 0x1D7A3AFD6C478063L) /* 126 */, unchecked((long) 0x519EC608E7669EDDL) /* 127 */, + unchecked((long) 0x0E5715A2D149AA23L) /* 128 */, unchecked((long) 0x177D4571848FF194L) /* 129 */, + unchecked((long) 0xEEB55F3241014C22L) /* 130 */, unchecked((long) 0x0F5E5CA13A6E2EC2L) /* 131 */, + unchecked((long) 0x8029927B75F5C361L) /* 132 */, unchecked((long) 0xAD139FABC3D6E436L) /* 133 */, + unchecked((long) 0x0D5DF1A94CCF402FL) /* 134 */, unchecked((long) 0x3E8BD948BEA5DFC8L) /* 135 */, + unchecked((long) 0xA5A0D357BD3FF77EL) /* 136 */, unchecked((long) 0xA2D12E251F74F645L) /* 137 */, + unchecked((long) 0x66FD9E525E81A082L) /* 138 */, unchecked((long) 0x2E0C90CE7F687A49L) /* 139 */, + unchecked((long) 0xC2E8BCBEBA973BC5L) /* 140 */, unchecked((long) 0x000001BCE509745FL) /* 141 */, + unchecked((long) 0x423777BBE6DAB3D6L) /* 142 */, unchecked((long) 0xD1661C7EAEF06EB5L) /* 143 */, + unchecked((long) 0xA1781F354DAACFD8L) /* 144 */, unchecked((long) 0x2D11284A2B16AFFCL) /* 145 */, + unchecked((long) 0xF1FC4F67FA891D1FL) /* 146 */, unchecked((long) 0x73ECC25DCB920ADAL) /* 147 */, + unchecked((long) 0xAE610C22C2A12651L) /* 148 */, unchecked((long) 0x96E0A810D356B78AL) /* 149 */, + unchecked((long) 0x5A9A381F2FE7870FL) /* 150 */, unchecked((long) 0xD5AD62EDE94E5530L) /* 151 */, + unchecked((long) 0xD225E5E8368D1427L) /* 152 */, unchecked((long) 0x65977B70C7AF4631L) /* 153 */, + unchecked((long) 0x99F889B2DE39D74FL) /* 154 */, unchecked((long) 0x233F30BF54E1D143L) /* 155 */, + unchecked((long) 0x9A9675D3D9A63C97L) /* 156 */, unchecked((long) 0x5470554FF334F9A8L) /* 157 */, + unchecked((long) 0x166ACB744A4F5688L) /* 158 */, unchecked((long) 0x70C74CAAB2E4AEADL) /* 159 */, + unchecked((long) 0xF0D091646F294D12L) /* 160 */, unchecked((long) 0x57B82A89684031D1L) /* 161 */, + unchecked((long) 0xEFD95A5A61BE0B6BL) /* 162 */, unchecked((long) 0x2FBD12E969F2F29AL) /* 163 */, + unchecked((long) 0x9BD37013FEFF9FE8L) /* 164 */, unchecked((long) 0x3F9B0404D6085A06L) /* 165 */, + unchecked((long) 0x4940C1F3166CFE15L) /* 166 */, unchecked((long) 0x09542C4DCDF3DEFBL) /* 167 */, + unchecked((long) 0xB4C5218385CD5CE3L) /* 168 */, unchecked((long) 0xC935B7DC4462A641L) /* 169 */, + unchecked((long) 0x3417F8A68ED3B63FL) /* 170 */, unchecked((long) 0xB80959295B215B40L) /* 171 */, + unchecked((long) 0xF99CDAEF3B8C8572L) /* 172 */, unchecked((long) 0x018C0614F8FCB95DL) /* 173 */, + unchecked((long) 0x1B14ACCD1A3ACDF3L) /* 174 */, unchecked((long) 0x84D471F200BB732DL) /* 175 */, + unchecked((long) 0xC1A3110E95E8DA16L) /* 176 */, unchecked((long) 0x430A7220BF1A82B8L) /* 177 */, + unchecked((long) 0xB77E090D39DF210EL) /* 178 */, unchecked((long) 0x5EF4BD9F3CD05E9DL) /* 179 */, + unchecked((long) 0x9D4FF6DA7E57A444L) /* 180 */, unchecked((long) 0xDA1D60E183D4A5F8L) /* 181 */, + unchecked((long) 0xB287C38417998E47L) /* 182 */, unchecked((long) 0xFE3EDC121BB31886L) /* 183 */, + unchecked((long) 0xC7FE3CCC980CCBEFL) /* 184 */, unchecked((long) 0xE46FB590189BFD03L) /* 185 */, + unchecked((long) 0x3732FD469A4C57DCL) /* 186 */, unchecked((long) 0x7EF700A07CF1AD65L) /* 187 */, + unchecked((long) 0x59C64468A31D8859L) /* 188 */, unchecked((long) 0x762FB0B4D45B61F6L) /* 189 */, + unchecked((long) 0x155BAED099047718L) /* 190 */, unchecked((long) 0x68755E4C3D50BAA6L) /* 191 */, + unchecked((long) 0xE9214E7F22D8B4DFL) /* 192 */, unchecked((long) 0x2ADDBF532EAC95F4L) /* 193 */, + unchecked((long) 0x32AE3909B4BD0109L) /* 194 */, unchecked((long) 0x834DF537B08E3450L) /* 195 */, + unchecked((long) 0xFA209DA84220728DL) /* 196 */, unchecked((long) 0x9E691D9B9EFE23F7L) /* 197 */, + unchecked((long) 0x0446D288C4AE8D7FL) /* 198 */, unchecked((long) 0x7B4CC524E169785BL) /* 199 */, + unchecked((long) 0x21D87F0135CA1385L) /* 200 */, unchecked((long) 0xCEBB400F137B8AA5L) /* 201 */, + unchecked((long) 0x272E2B66580796BEL) /* 202 */, unchecked((long) 0x3612264125C2B0DEL) /* 203 */, + unchecked((long) 0x057702BDAD1EFBB2L) /* 204 */, unchecked((long) 0xD4BABB8EACF84BE9L) /* 205 */, + unchecked((long) 0x91583139641BC67BL) /* 206 */, unchecked((long) 0x8BDC2DE08036E024L) /* 207 */, + unchecked((long) 0x603C8156F49F68EDL) /* 208 */, unchecked((long) 0xF7D236F7DBEF5111L) /* 209 */, + unchecked((long) 0x9727C4598AD21E80L) /* 210 */, unchecked((long) 0xA08A0896670A5FD7L) /* 211 */, + unchecked((long) 0xCB4A8F4309EBA9CBL) /* 212 */, unchecked((long) 0x81AF564B0F7036A1L) /* 213 */, + unchecked((long) 0xC0B99AA778199ABDL) /* 214 */, unchecked((long) 0x959F1EC83FC8E952L) /* 215 */, + unchecked((long) 0x8C505077794A81B9L) /* 216 */, unchecked((long) 0x3ACAAF8F056338F0L) /* 217 */, + unchecked((long) 0x07B43F50627A6778L) /* 218 */, unchecked((long) 0x4A44AB49F5ECCC77L) /* 219 */, + unchecked((long) 0x3BC3D6E4B679EE98L) /* 220 */, unchecked((long) 0x9CC0D4D1CF14108CL) /* 221 */, + unchecked((long) 0x4406C00B206BC8A0L) /* 222 */, unchecked((long) 0x82A18854C8D72D89L) /* 223 */, + unchecked((long) 0x67E366B35C3C432CL) /* 224 */, unchecked((long) 0xB923DD61102B37F2L) /* 225 */, + unchecked((long) 0x56AB2779D884271DL) /* 226 */, unchecked((long) 0xBE83E1B0FF1525AFL) /* 227 */, + unchecked((long) 0xFB7C65D4217E49A9L) /* 228 */, unchecked((long) 0x6BDBE0E76D48E7D4L) /* 229 */, + unchecked((long) 0x08DF828745D9179EL) /* 230 */, unchecked((long) 0x22EA6A9ADD53BD34L) /* 231 */, + unchecked((long) 0xE36E141C5622200AL) /* 232 */, unchecked((long) 0x7F805D1B8CB750EEL) /* 233 */, + unchecked((long) 0xAFE5C7A59F58E837L) /* 234 */, unchecked((long) 0xE27F996A4FB1C23CL) /* 235 */, + unchecked((long) 0xD3867DFB0775F0D0L) /* 236 */, unchecked((long) 0xD0E673DE6E88891AL) /* 237 */, + unchecked((long) 0x123AEB9EAFB86C25L) /* 238 */, unchecked((long) 0x30F1D5D5C145B895L) /* 239 */, + unchecked((long) 0xBB434A2DEE7269E7L) /* 240 */, unchecked((long) 0x78CB67ECF931FA38L) /* 241 */, + unchecked((long) 0xF33B0372323BBF9CL) /* 242 */, unchecked((long) 0x52D66336FB279C74L) /* 243 */, + unchecked((long) 0x505F33AC0AFB4EAAL) /* 244 */, unchecked((long) 0xE8A5CD99A2CCE187L) /* 245 */, + unchecked((long) 0x534974801E2D30BBL) /* 246 */, unchecked((long) 0x8D2D5711D5876D90L) /* 247 */, + unchecked((long) 0x1F1A412891BC038EL) /* 248 */, unchecked((long) 0xD6E2E71D82E56648L) /* 249 */, + unchecked((long) 0x74036C3A497732B7L) /* 250 */, unchecked((long) 0x89B67ED96361F5ABL) /* 251 */, + unchecked((long) 0xFFED95D8F1EA02A2L) /* 252 */, unchecked((long) 0xE72B3BD61464D43DL) /* 253 */, + unchecked((long) 0xA6300F170BDC4820L) /* 254 */, unchecked((long) 0xEBC18760ED78A77AL) /* 255 */, + }; + + private static readonly long[] t2 = { + unchecked((long) 0xE6A6BE5A05A12138L) /* 256 */, unchecked((long) 0xB5A122A5B4F87C98L) /* 257 */, + unchecked((long) 0x563C6089140B6990L) /* 258 */, unchecked((long) 0x4C46CB2E391F5DD5L) /* 259 */, + unchecked((long) 0xD932ADDBC9B79434L) /* 260 */, unchecked((long) 0x08EA70E42015AFF5L) /* 261 */, + unchecked((long) 0xD765A6673E478CF1L) /* 262 */, unchecked((long) 0xC4FB757EAB278D99L) /* 263 */, + unchecked((long) 0xDF11C6862D6E0692L) /* 264 */, unchecked((long) 0xDDEB84F10D7F3B16L) /* 265 */, + unchecked((long) 0x6F2EF604A665EA04L) /* 266 */, unchecked((long) 0x4A8E0F0FF0E0DFB3L) /* 267 */, + unchecked((long) 0xA5EDEEF83DBCBA51L) /* 268 */, unchecked((long) 0xFC4F0A2A0EA4371EL) /* 269 */, + unchecked((long) 0xE83E1DA85CB38429L) /* 270 */, unchecked((long) 0xDC8FF882BA1B1CE2L) /* 271 */, + unchecked((long) 0xCD45505E8353E80DL) /* 272 */, unchecked((long) 0x18D19A00D4DB0717L) /* 273 */, + unchecked((long) 0x34A0CFEDA5F38101L) /* 274 */, unchecked((long) 0x0BE77E518887CAF2L) /* 275 */, + unchecked((long) 0x1E341438B3C45136L) /* 276 */, unchecked((long) 0xE05797F49089CCF9L) /* 277 */, + unchecked((long) 0xFFD23F9DF2591D14L) /* 278 */, unchecked((long) 0x543DDA228595C5CDL) /* 279 */, + unchecked((long) 0x661F81FD99052A33L) /* 280 */, unchecked((long) 0x8736E641DB0F7B76L) /* 281 */, + unchecked((long) 0x15227725418E5307L) /* 282 */, unchecked((long) 0xE25F7F46162EB2FAL) /* 283 */, + unchecked((long) 0x48A8B2126C13D9FEL) /* 284 */, unchecked((long) 0xAFDC541792E76EEAL) /* 285 */, + unchecked((long) 0x03D912BFC6D1898FL) /* 286 */, unchecked((long) 0x31B1AAFA1B83F51BL) /* 287 */, + unchecked((long) 0xF1AC2796E42AB7D9L) /* 288 */, unchecked((long) 0x40A3A7D7FCD2EBACL) /* 289 */, + unchecked((long) 0x1056136D0AFBBCC5L) /* 290 */, unchecked((long) 0x7889E1DD9A6D0C85L) /* 291 */, + unchecked((long) 0xD33525782A7974AAL) /* 292 */, unchecked((long) 0xA7E25D09078AC09BL) /* 293 */, + unchecked((long) 0xBD4138B3EAC6EDD0L) /* 294 */, unchecked((long) 0x920ABFBE71EB9E70L) /* 295 */, + unchecked((long) 0xA2A5D0F54FC2625CL) /* 296 */, unchecked((long) 0xC054E36B0B1290A3L) /* 297 */, + unchecked((long) 0xF6DD59FF62FE932BL) /* 298 */, unchecked((long) 0x3537354511A8AC7DL) /* 299 */, + unchecked((long) 0xCA845E9172FADCD4L) /* 300 */, unchecked((long) 0x84F82B60329D20DCL) /* 301 */, + unchecked((long) 0x79C62CE1CD672F18L) /* 302 */, unchecked((long) 0x8B09A2ADD124642CL) /* 303 */, + unchecked((long) 0xD0C1E96A19D9E726L) /* 304 */, unchecked((long) 0x5A786A9B4BA9500CL) /* 305 */, + unchecked((long) 0x0E020336634C43F3L) /* 306 */, unchecked((long) 0xC17B474AEB66D822L) /* 307 */, + unchecked((long) 0x6A731AE3EC9BAAC2L) /* 308 */, unchecked((long) 0x8226667AE0840258L) /* 309 */, + unchecked((long) 0x67D4567691CAECA5L) /* 310 */, unchecked((long) 0x1D94155C4875ADB5L) /* 311 */, + unchecked((long) 0x6D00FD985B813FDFL) /* 312 */, unchecked((long) 0x51286EFCB774CD06L) /* 313 */, + unchecked((long) 0x5E8834471FA744AFL) /* 314 */, unchecked((long) 0xF72CA0AEE761AE2EL) /* 315 */, + unchecked((long) 0xBE40E4CDAEE8E09AL) /* 316 */, unchecked((long) 0xE9970BBB5118F665L) /* 317 */, + unchecked((long) 0x726E4BEB33DF1964L) /* 318 */, unchecked((long) 0x703B000729199762L) /* 319 */, + unchecked((long) 0x4631D816F5EF30A7L) /* 320 */, unchecked((long) 0xB880B5B51504A6BEL) /* 321 */, + unchecked((long) 0x641793C37ED84B6CL) /* 322 */, unchecked((long) 0x7B21ED77F6E97D96L) /* 323 */, + unchecked((long) 0x776306312EF96B73L) /* 324 */, unchecked((long) 0xAE528948E86FF3F4L) /* 325 */, + unchecked((long) 0x53DBD7F286A3F8F8L) /* 326 */, unchecked((long) 0x16CADCE74CFC1063L) /* 327 */, + unchecked((long) 0x005C19BDFA52C6DDL) /* 328 */, unchecked((long) 0x68868F5D64D46AD3L) /* 329 */, + unchecked((long) 0x3A9D512CCF1E186AL) /* 330 */, unchecked((long) 0x367E62C2385660AEL) /* 331 */, + unchecked((long) 0xE359E7EA77DCB1D7L) /* 332 */, unchecked((long) 0x526C0773749ABE6EL) /* 333 */, + unchecked((long) 0x735AE5F9D09F734BL) /* 334 */, unchecked((long) 0x493FC7CC8A558BA8L) /* 335 */, + unchecked((long) 0xB0B9C1533041AB45L) /* 336 */, unchecked((long) 0x321958BA470A59BDL) /* 337 */, + unchecked((long) 0x852DB00B5F46C393L) /* 338 */, unchecked((long) 0x91209B2BD336B0E5L) /* 339 */, + unchecked((long) 0x6E604F7D659EF19FL) /* 340 */, unchecked((long) 0xB99A8AE2782CCB24L) /* 341 */, + unchecked((long) 0xCCF52AB6C814C4C7L) /* 342 */, unchecked((long) 0x4727D9AFBE11727BL) /* 343 */, + unchecked((long) 0x7E950D0C0121B34DL) /* 344 */, unchecked((long) 0x756F435670AD471FL) /* 345 */, + unchecked((long) 0xF5ADD442615A6849L) /* 346 */, unchecked((long) 0x4E87E09980B9957AL) /* 347 */, + unchecked((long) 0x2ACFA1DF50AEE355L) /* 348 */, unchecked((long) 0xD898263AFD2FD556L) /* 349 */, + unchecked((long) 0xC8F4924DD80C8FD6L) /* 350 */, unchecked((long) 0xCF99CA3D754A173AL) /* 351 */, + unchecked((long) 0xFE477BACAF91BF3CL) /* 352 */, unchecked((long) 0xED5371F6D690C12DL) /* 353 */, + unchecked((long) 0x831A5C285E687094L) /* 354 */, unchecked((long) 0xC5D3C90A3708A0A4L) /* 355 */, + unchecked((long) 0x0F7F903717D06580L) /* 356 */, unchecked((long) 0x19F9BB13B8FDF27FL) /* 357 */, + unchecked((long) 0xB1BD6F1B4D502843L) /* 358 */, unchecked((long) 0x1C761BA38FFF4012L) /* 359 */, + unchecked((long) 0x0D1530C4E2E21F3BL) /* 360 */, unchecked((long) 0x8943CE69A7372C8AL) /* 361 */, + unchecked((long) 0xE5184E11FEB5CE66L) /* 362 */, unchecked((long) 0x618BDB80BD736621L) /* 363 */, + unchecked((long) 0x7D29BAD68B574D0BL) /* 364 */, unchecked((long) 0x81BB613E25E6FE5BL) /* 365 */, + unchecked((long) 0x071C9C10BC07913FL) /* 366 */, unchecked((long) 0xC7BEEB7909AC2D97L) /* 367 */, + unchecked((long) 0xC3E58D353BC5D757L) /* 368 */, unchecked((long) 0xEB017892F38F61E8L) /* 369 */, + unchecked((long) 0xD4EFFB9C9B1CC21AL) /* 370 */, unchecked((long) 0x99727D26F494F7ABL) /* 371 */, + unchecked((long) 0xA3E063A2956B3E03L) /* 372 */, unchecked((long) 0x9D4A8B9A4AA09C30L) /* 373 */, + unchecked((long) 0x3F6AB7D500090FB4L) /* 374 */, unchecked((long) 0x9CC0F2A057268AC0L) /* 375 */, + unchecked((long) 0x3DEE9D2DEDBF42D1L) /* 376 */, unchecked((long) 0x330F49C87960A972L) /* 377 */, + unchecked((long) 0xC6B2720287421B41L) /* 378 */, unchecked((long) 0x0AC59EC07C00369CL) /* 379 */, + unchecked((long) 0xEF4EAC49CB353425L) /* 380 */, unchecked((long) 0xF450244EEF0129D8L) /* 381 */, + unchecked((long) 0x8ACC46E5CAF4DEB6L) /* 382 */, unchecked((long) 0x2FFEAB63989263F7L) /* 383 */, + unchecked((long) 0x8F7CB9FE5D7A4578L) /* 384 */, unchecked((long) 0x5BD8F7644E634635L) /* 385 */, + unchecked((long) 0x427A7315BF2DC900L) /* 386 */, unchecked((long) 0x17D0C4AA2125261CL) /* 387 */, + unchecked((long) 0x3992486C93518E50L) /* 388 */, unchecked((long) 0xB4CBFEE0A2D7D4C3L) /* 389 */, + unchecked((long) 0x7C75D6202C5DDD8DL) /* 390 */, unchecked((long) 0xDBC295D8E35B6C61L) /* 391 */, + unchecked((long) 0x60B369D302032B19L) /* 392 */, unchecked((long) 0xCE42685FDCE44132L) /* 393 */, + unchecked((long) 0x06F3DDB9DDF65610L) /* 394 */, unchecked((long) 0x8EA4D21DB5E148F0L) /* 395 */, + unchecked((long) 0x20B0FCE62FCD496FL) /* 396 */, unchecked((long) 0x2C1B912358B0EE31L) /* 397 */, + unchecked((long) 0xB28317B818F5A308L) /* 398 */, unchecked((long) 0xA89C1E189CA6D2CFL) /* 399 */, + unchecked((long) 0x0C6B18576AAADBC8L) /* 400 */, unchecked((long) 0xB65DEAA91299FAE3L) /* 401 */, + unchecked((long) 0xFB2B794B7F1027E7L) /* 402 */, unchecked((long) 0x04E4317F443B5BEBL) /* 403 */, + unchecked((long) 0x4B852D325939D0A6L) /* 404 */, unchecked((long) 0xD5AE6BEEFB207FFCL) /* 405 */, + unchecked((long) 0x309682B281C7D374L) /* 406 */, unchecked((long) 0xBAE309A194C3B475L) /* 407 */, + unchecked((long) 0x8CC3F97B13B49F05L) /* 408 */, unchecked((long) 0x98A9422FF8293967L) /* 409 */, + unchecked((long) 0x244B16B01076FF7CL) /* 410 */, unchecked((long) 0xF8BF571C663D67EEL) /* 411 */, + unchecked((long) 0x1F0D6758EEE30DA1L) /* 412 */, unchecked((long) 0xC9B611D97ADEB9B7L) /* 413 */, + unchecked((long) 0xB7AFD5887B6C57A2L) /* 414 */, unchecked((long) 0x6290AE846B984FE1L) /* 415 */, + unchecked((long) 0x94DF4CDEACC1A5FDL) /* 416 */, unchecked((long) 0x058A5BD1C5483AFFL) /* 417 */, + unchecked((long) 0x63166CC142BA3C37L) /* 418 */, unchecked((long) 0x8DB8526EB2F76F40L) /* 419 */, + unchecked((long) 0xE10880036F0D6D4EL) /* 420 */, unchecked((long) 0x9E0523C9971D311DL) /* 421 */, + unchecked((long) 0x45EC2824CC7CD691L) /* 422 */, unchecked((long) 0x575B8359E62382C9L) /* 423 */, + unchecked((long) 0xFA9E400DC4889995L) /* 424 */, unchecked((long) 0xD1823ECB45721568L) /* 425 */, + unchecked((long) 0xDAFD983B8206082FL) /* 426 */, unchecked((long) 0xAA7D29082386A8CBL) /* 427 */, + unchecked((long) 0x269FCD4403B87588L) /* 428 */, unchecked((long) 0x1B91F5F728BDD1E0L) /* 429 */, + unchecked((long) 0xE4669F39040201F6L) /* 430 */, unchecked((long) 0x7A1D7C218CF04ADEL) /* 431 */, + unchecked((long) 0x65623C29D79CE5CEL) /* 432 */, unchecked((long) 0x2368449096C00BB1L) /* 433 */, + unchecked((long) 0xAB9BF1879DA503BAL) /* 434 */, unchecked((long) 0xBC23ECB1A458058EL) /* 435 */, + unchecked((long) 0x9A58DF01BB401ECCL) /* 436 */, unchecked((long) 0xA070E868A85F143DL) /* 437 */, + unchecked((long) 0x4FF188307DF2239EL) /* 438 */, unchecked((long) 0x14D565B41A641183L) /* 439 */, + unchecked((long) 0xEE13337452701602L) /* 440 */, unchecked((long) 0x950E3DCF3F285E09L) /* 441 */, + unchecked((long) 0x59930254B9C80953L) /* 442 */, unchecked((long) 0x3BF299408930DA6DL) /* 443 */, + unchecked((long) 0xA955943F53691387L) /* 444 */, unchecked((long) 0xA15EDECAA9CB8784L) /* 445 */, + unchecked((long) 0x29142127352BE9A0L) /* 446 */, unchecked((long) 0x76F0371FFF4E7AFBL) /* 447 */, + unchecked((long) 0x0239F450274F2228L) /* 448 */, unchecked((long) 0xBB073AF01D5E868BL) /* 449 */, + unchecked((long) 0xBFC80571C10E96C1L) /* 450 */, unchecked((long) 0xD267088568222E23L) /* 451 */, + unchecked((long) 0x9671A3D48E80B5B0L) /* 452 */, unchecked((long) 0x55B5D38AE193BB81L) /* 453 */, + unchecked((long) 0x693AE2D0A18B04B8L) /* 454 */, unchecked((long) 0x5C48B4ECADD5335FL) /* 455 */, + unchecked((long) 0xFD743B194916A1CAL) /* 456 */, unchecked((long) 0x2577018134BE98C4L) /* 457 */, + unchecked((long) 0xE77987E83C54A4ADL) /* 458 */, unchecked((long) 0x28E11014DA33E1B9L) /* 459 */, + unchecked((long) 0x270CC59E226AA213L) /* 460 */, unchecked((long) 0x71495F756D1A5F60L) /* 461 */, + unchecked((long) 0x9BE853FB60AFEF77L) /* 462 */, unchecked((long) 0xADC786A7F7443DBFL) /* 463 */, + unchecked((long) 0x0904456173B29A82L) /* 464 */, unchecked((long) 0x58BC7A66C232BD5EL) /* 465 */, + unchecked((long) 0xF306558C673AC8B2L) /* 466 */, unchecked((long) 0x41F639C6B6C9772AL) /* 467 */, + unchecked((long) 0x216DEFE99FDA35DAL) /* 468 */, unchecked((long) 0x11640CC71C7BE615L) /* 469 */, + unchecked((long) 0x93C43694565C5527L) /* 470 */, unchecked((long) 0xEA038E6246777839L) /* 471 */, + unchecked((long) 0xF9ABF3CE5A3E2469L) /* 472 */, unchecked((long) 0x741E768D0FD312D2L) /* 473 */, + unchecked((long) 0x0144B883CED652C6L) /* 474 */, unchecked((long) 0xC20B5A5BA33F8552L) /* 475 */, + unchecked((long) 0x1AE69633C3435A9DL) /* 476 */, unchecked((long) 0x97A28CA4088CFDECL) /* 477 */, + unchecked((long) 0x8824A43C1E96F420L) /* 478 */, unchecked((long) 0x37612FA66EEEA746L) /* 479 */, + unchecked((long) 0x6B4CB165F9CF0E5AL) /* 480 */, unchecked((long) 0x43AA1C06A0ABFB4AL) /* 481 */, + unchecked((long) 0x7F4DC26FF162796BL) /* 482 */, unchecked((long) 0x6CBACC8E54ED9B0FL) /* 483 */, + unchecked((long) 0xA6B7FFEFD2BB253EL) /* 484 */, unchecked((long) 0x2E25BC95B0A29D4FL) /* 485 */, + unchecked((long) 0x86D6A58BDEF1388CL) /* 486 */, unchecked((long) 0xDED74AC576B6F054L) /* 487 */, + unchecked((long) 0x8030BDBC2B45805DL) /* 488 */, unchecked((long) 0x3C81AF70E94D9289L) /* 489 */, + unchecked((long) 0x3EFF6DDA9E3100DBL) /* 490 */, unchecked((long) 0xB38DC39FDFCC8847L) /* 491 */, + unchecked((long) 0x123885528D17B87EL) /* 492 */, unchecked((long) 0xF2DA0ED240B1B642L) /* 493 */, + unchecked((long) 0x44CEFADCD54BF9A9L) /* 494 */, unchecked((long) 0x1312200E433C7EE6L) /* 495 */, + unchecked((long) 0x9FFCC84F3A78C748L) /* 496 */, unchecked((long) 0xF0CD1F72248576BBL) /* 497 */, + unchecked((long) 0xEC6974053638CFE4L) /* 498 */, unchecked((long) 0x2BA7B67C0CEC4E4CL) /* 499 */, + unchecked((long) 0xAC2F4DF3E5CE32EDL) /* 500 */, unchecked((long) 0xCB33D14326EA4C11L) /* 501 */, + unchecked((long) 0xA4E9044CC77E58BCL) /* 502 */, unchecked((long) 0x5F513293D934FCEFL) /* 503 */, + unchecked((long) 0x5DC9645506E55444L) /* 504 */, unchecked((long) 0x50DE418F317DE40AL) /* 505 */, + unchecked((long) 0x388CB31A69DDE259L) /* 506 */, unchecked((long) 0x2DB4A83455820A86L) /* 507 */, + unchecked((long) 0x9010A91E84711AE9L) /* 508 */, unchecked((long) 0x4DF7F0B7B1498371L) /* 509 */, + unchecked((long) 0xD62A2EABC0977179L) /* 510 */, unchecked((long) 0x22FAC097AA8D5C0EL) /* 511 */, + }; + + private static readonly long[] t3 = { + unchecked((long) 0xF49FCC2FF1DAF39BL) /* 512 */, unchecked((long) 0x487FD5C66FF29281L) /* 513 */, + unchecked((long) 0xE8A30667FCDCA83FL) /* 514 */, unchecked((long) 0x2C9B4BE3D2FCCE63L) /* 515 */, + unchecked((long) 0xDA3FF74B93FBBBC2L) /* 516 */, unchecked((long) 0x2FA165D2FE70BA66L) /* 517 */, + unchecked((long) 0xA103E279970E93D4L) /* 518 */, unchecked((long) 0xBECDEC77B0E45E71L) /* 519 */, + unchecked((long) 0xCFB41E723985E497L) /* 520 */, unchecked((long) 0xB70AAA025EF75017L) /* 521 */, + unchecked((long) 0xD42309F03840B8E0L) /* 522 */, unchecked((long) 0x8EFC1AD035898579L) /* 523 */, + unchecked((long) 0x96C6920BE2B2ABC5L) /* 524 */, unchecked((long) 0x66AF4163375A9172L) /* 525 */, + unchecked((long) 0x2174ABDCCA7127FBL) /* 526 */, unchecked((long) 0xB33CCEA64A72FF41L) /* 527 */, + unchecked((long) 0xF04A4933083066A5L) /* 528 */, unchecked((long) 0x8D970ACDD7289AF5L) /* 529 */, + unchecked((long) 0x8F96E8E031C8C25EL) /* 530 */, unchecked((long) 0xF3FEC02276875D47L) /* 531 */, + unchecked((long) 0xEC7BF310056190DDL) /* 532 */, unchecked((long) 0xF5ADB0AEBB0F1491L) /* 533 */, + unchecked((long) 0x9B50F8850FD58892L) /* 534 */, unchecked((long) 0x4975488358B74DE8L) /* 535 */, + unchecked((long) 0xA3354FF691531C61L) /* 536 */, unchecked((long) 0x0702BBE481D2C6EEL) /* 537 */, + unchecked((long) 0x89FB24057DEDED98L) /* 538 */, unchecked((long) 0xAC3075138596E902L) /* 539 */, + unchecked((long) 0x1D2D3580172772EDL) /* 540 */, unchecked((long) 0xEB738FC28E6BC30DL) /* 541 */, + unchecked((long) 0x5854EF8F63044326L) /* 542 */, unchecked((long) 0x9E5C52325ADD3BBEL) /* 543 */, + unchecked((long) 0x90AA53CF325C4623L) /* 544 */, unchecked((long) 0xC1D24D51349DD067L) /* 545 */, + unchecked((long) 0x2051CFEEA69EA624L) /* 546 */, unchecked((long) 0x13220F0A862E7E4FL) /* 547 */, + unchecked((long) 0xCE39399404E04864L) /* 548 */, unchecked((long) 0xD9C42CA47086FCB7L) /* 549 */, + unchecked((long) 0x685AD2238A03E7CCL) /* 550 */, unchecked((long) 0x066484B2AB2FF1DBL) /* 551 */, + unchecked((long) 0xFE9D5D70EFBF79ECL) /* 552 */, unchecked((long) 0x5B13B9DD9C481854L) /* 553 */, + unchecked((long) 0x15F0D475ED1509ADL) /* 554 */, unchecked((long) 0x0BEBCD060EC79851L) /* 555 */, + unchecked((long) 0xD58C6791183AB7F8L) /* 556 */, unchecked((long) 0xD1187C5052F3EEE4L) /* 557 */, + unchecked((long) 0xC95D1192E54E82FFL) /* 558 */, unchecked((long) 0x86EEA14CB9AC6CA2L) /* 559 */, + unchecked((long) 0x3485BEB153677D5DL) /* 560 */, unchecked((long) 0xDD191D781F8C492AL) /* 561 */, + unchecked((long) 0xF60866BAA784EBF9L) /* 562 */, unchecked((long) 0x518F643BA2D08C74L) /* 563 */, + unchecked((long) 0x8852E956E1087C22L) /* 564 */, unchecked((long) 0xA768CB8DC410AE8DL) /* 565 */, + unchecked((long) 0x38047726BFEC8E1AL) /* 566 */, unchecked((long) 0xA67738B4CD3B45AAL) /* 567 */, + unchecked((long) 0xAD16691CEC0DDE19L) /* 568 */, unchecked((long) 0xC6D4319380462E07L) /* 569 */, + unchecked((long) 0xC5A5876D0BA61938L) /* 570 */, unchecked((long) 0x16B9FA1FA58FD840L) /* 571 */, + unchecked((long) 0x188AB1173CA74F18L) /* 572 */, unchecked((long) 0xABDA2F98C99C021FL) /* 573 */, + unchecked((long) 0x3E0580AB134AE816L) /* 574 */, unchecked((long) 0x5F3B05B773645ABBL) /* 575 */, + unchecked((long) 0x2501A2BE5575F2F6L) /* 576 */, unchecked((long) 0x1B2F74004E7E8BA9L) /* 577 */, + unchecked((long) 0x1CD7580371E8D953L) /* 578 */, unchecked((long) 0x7F6ED89562764E30L) /* 579 */, + unchecked((long) 0xB15926FF596F003DL) /* 580 */, unchecked((long) 0x9F65293DA8C5D6B9L) /* 581 */, + unchecked((long) 0x6ECEF04DD690F84CL) /* 582 */, unchecked((long) 0x4782275FFF33AF88L) /* 583 */, + unchecked((long) 0xE41433083F820801L) /* 584 */, unchecked((long) 0xFD0DFE409A1AF9B5L) /* 585 */, + unchecked((long) 0x4325A3342CDB396BL) /* 586 */, unchecked((long) 0x8AE77E62B301B252L) /* 587 */, + unchecked((long) 0xC36F9E9F6655615AL) /* 588 */, unchecked((long) 0x85455A2D92D32C09L) /* 589 */, + unchecked((long) 0xF2C7DEA949477485L) /* 590 */, unchecked((long) 0x63CFB4C133A39EBAL) /* 591 */, + unchecked((long) 0x83B040CC6EBC5462L) /* 592 */, unchecked((long) 0x3B9454C8FDB326B0L) /* 593 */, + unchecked((long) 0x56F56A9E87FFD78CL) /* 594 */, unchecked((long) 0x2DC2940D99F42BC6L) /* 595 */, + unchecked((long) 0x98F7DF096B096E2DL) /* 596 */, unchecked((long) 0x19A6E01E3AD852BFL) /* 597 */, + unchecked((long) 0x42A99CCBDBD4B40BL) /* 598 */, unchecked((long) 0xA59998AF45E9C559L) /* 599 */, + unchecked((long) 0x366295E807D93186L) /* 600 */, unchecked((long) 0x6B48181BFAA1F773L) /* 601 */, + unchecked((long) 0x1FEC57E2157A0A1DL) /* 602 */, unchecked((long) 0x4667446AF6201AD5L) /* 603 */, + unchecked((long) 0xE615EBCACFB0F075L) /* 604 */, unchecked((long) 0xB8F31F4F68290778L) /* 605 */, + unchecked((long) 0x22713ED6CE22D11EL) /* 606 */, unchecked((long) 0x3057C1A72EC3C93BL) /* 607 */, + unchecked((long) 0xCB46ACC37C3F1F2FL) /* 608 */, unchecked((long) 0xDBB893FD02AAF50EL) /* 609 */, + unchecked((long) 0x331FD92E600B9FCFL) /* 610 */, unchecked((long) 0xA498F96148EA3AD6L) /* 611 */, + unchecked((long) 0xA8D8426E8B6A83EAL) /* 612 */, unchecked((long) 0xA089B274B7735CDCL) /* 613 */, + unchecked((long) 0x87F6B3731E524A11L) /* 614 */, unchecked((long) 0x118808E5CBC96749L) /* 615 */, + unchecked((long) 0x9906E4C7B19BD394L) /* 616 */, unchecked((long) 0xAFED7F7E9B24A20CL) /* 617 */, + unchecked((long) 0x6509EADEEB3644A7L) /* 618 */, unchecked((long) 0x6C1EF1D3E8EF0EDEL) /* 619 */, + unchecked((long) 0xB9C97D43E9798FB4L) /* 620 */, unchecked((long) 0xA2F2D784740C28A3L) /* 621 */, + unchecked((long) 0x7B8496476197566FL) /* 622 */, unchecked((long) 0x7A5BE3E6B65F069DL) /* 623 */, + unchecked((long) 0xF96330ED78BE6F10L) /* 624 */, unchecked((long) 0xEEE60DE77A076A15L) /* 625 */, + unchecked((long) 0x2B4BEE4AA08B9BD0L) /* 626 */, unchecked((long) 0x6A56A63EC7B8894EL) /* 627 */, + unchecked((long) 0x02121359BA34FEF4L) /* 628 */, unchecked((long) 0x4CBF99F8283703FCL) /* 629 */, + unchecked((long) 0x398071350CAF30C8L) /* 630 */, unchecked((long) 0xD0A77A89F017687AL) /* 631 */, + unchecked((long) 0xF1C1A9EB9E423569L) /* 632 */, unchecked((long) 0x8C7976282DEE8199L) /* 633 */, + unchecked((long) 0x5D1737A5DD1F7ABDL) /* 634 */, unchecked((long) 0x4F53433C09A9FA80L) /* 635 */, + unchecked((long) 0xFA8B0C53DF7CA1D9L) /* 636 */, unchecked((long) 0x3FD9DCBC886CCB77L) /* 637 */, + unchecked((long) 0xC040917CA91B4720L) /* 638 */, unchecked((long) 0x7DD00142F9D1DCDFL) /* 639 */, + unchecked((long) 0x8476FC1D4F387B58L) /* 640 */, unchecked((long) 0x23F8E7C5F3316503L) /* 641 */, + unchecked((long) 0x032A2244E7E37339L) /* 642 */, unchecked((long) 0x5C87A5D750F5A74BL) /* 643 */, + unchecked((long) 0x082B4CC43698992EL) /* 644 */, unchecked((long) 0xDF917BECB858F63CL) /* 645 */, + unchecked((long) 0x3270B8FC5BF86DDAL) /* 646 */, unchecked((long) 0x10AE72BB29B5DD76L) /* 647 */, + unchecked((long) 0x576AC94E7700362BL) /* 648 */, unchecked((long) 0x1AD112DAC61EFB8FL) /* 649 */, + unchecked((long) 0x691BC30EC5FAA427L) /* 650 */, unchecked((long) 0xFF246311CC327143L) /* 651 */, + unchecked((long) 0x3142368E30E53206L) /* 652 */, unchecked((long) 0x71380E31E02CA396L) /* 653 */, + unchecked((long) 0x958D5C960AAD76F1L) /* 654 */, unchecked((long) 0xF8D6F430C16DA536L) /* 655 */, + unchecked((long) 0xC8FFD13F1BE7E1D2L) /* 656 */, unchecked((long) 0x7578AE66004DDBE1L) /* 657 */, + unchecked((long) 0x05833F01067BE646L) /* 658 */, unchecked((long) 0xBB34B5AD3BFE586DL) /* 659 */, + unchecked((long) 0x095F34C9A12B97F0L) /* 660 */, unchecked((long) 0x247AB64525D60CA8L) /* 661 */, + unchecked((long) 0xDCDBC6F3017477D1L) /* 662 */, unchecked((long) 0x4A2E14D4DECAD24DL) /* 663 */, + unchecked((long) 0xBDB5E6D9BE0A1EEBL) /* 664 */, unchecked((long) 0x2A7E70F7794301ABL) /* 665 */, + unchecked((long) 0xDEF42D8A270540FDL) /* 666 */, unchecked((long) 0x01078EC0A34C22C1L) /* 667 */, + unchecked((long) 0xE5DE511AF4C16387L) /* 668 */, unchecked((long) 0x7EBB3A52BD9A330AL) /* 669 */, + unchecked((long) 0x77697857AA7D6435L) /* 670 */, unchecked((long) 0x004E831603AE4C32L) /* 671 */, + unchecked((long) 0xE7A21020AD78E312L) /* 672 */, unchecked((long) 0x9D41A70C6AB420F2L) /* 673 */, + unchecked((long) 0x28E06C18EA1141E6L) /* 674 */, unchecked((long) 0xD2B28CBD984F6B28L) /* 675 */, + unchecked((long) 0x26B75F6C446E9D83L) /* 676 */, unchecked((long) 0xBA47568C4D418D7FL) /* 677 */, + unchecked((long) 0xD80BADBFE6183D8EL) /* 678 */, unchecked((long) 0x0E206D7F5F166044L) /* 679 */, + unchecked((long) 0xE258A43911CBCA3EL) /* 680 */, unchecked((long) 0x723A1746B21DC0BCL) /* 681 */, + unchecked((long) 0xC7CAA854F5D7CDD3L) /* 682 */, unchecked((long) 0x7CAC32883D261D9CL) /* 683 */, + unchecked((long) 0x7690C26423BA942CL) /* 684 */, unchecked((long) 0x17E55524478042B8L) /* 685 */, + unchecked((long) 0xE0BE477656A2389FL) /* 686 */, unchecked((long) 0x4D289B5E67AB2DA0L) /* 687 */, + unchecked((long) 0x44862B9C8FBBFD31L) /* 688 */, unchecked((long) 0xB47CC8049D141365L) /* 689 */, + unchecked((long) 0x822C1B362B91C793L) /* 690 */, unchecked((long) 0x4EB14655FB13DFD8L) /* 691 */, + unchecked((long) 0x1ECBBA0714E2A97BL) /* 692 */, unchecked((long) 0x6143459D5CDE5F14L) /* 693 */, + unchecked((long) 0x53A8FBF1D5F0AC89L) /* 694 */, unchecked((long) 0x97EA04D81C5E5B00L) /* 695 */, + unchecked((long) 0x622181A8D4FDB3F3L) /* 696 */, unchecked((long) 0xE9BCD341572A1208L) /* 697 */, + unchecked((long) 0x1411258643CCE58AL) /* 698 */, unchecked((long) 0x9144C5FEA4C6E0A4L) /* 699 */, + unchecked((long) 0x0D33D06565CF620FL) /* 700 */, unchecked((long) 0x54A48D489F219CA1L) /* 701 */, + unchecked((long) 0xC43E5EAC6D63C821L) /* 702 */, unchecked((long) 0xA9728B3A72770DAFL) /* 703 */, + unchecked((long) 0xD7934E7B20DF87EFL) /* 704 */, unchecked((long) 0xE35503B61A3E86E5L) /* 705 */, + unchecked((long) 0xCAE321FBC819D504L) /* 706 */, unchecked((long) 0x129A50B3AC60BFA6L) /* 707 */, + unchecked((long) 0xCD5E68EA7E9FB6C3L) /* 708 */, unchecked((long) 0xB01C90199483B1C7L) /* 709 */, + unchecked((long) 0x3DE93CD5C295376CL) /* 710 */, unchecked((long) 0xAED52EDF2AB9AD13L) /* 711 */, + unchecked((long) 0x2E60F512C0A07884L) /* 712 */, unchecked((long) 0xBC3D86A3E36210C9L) /* 713 */, + unchecked((long) 0x35269D9B163951CEL) /* 714 */, unchecked((long) 0x0C7D6E2AD0CDB5FAL) /* 715 */, + unchecked((long) 0x59E86297D87F5733L) /* 716 */, unchecked((long) 0x298EF221898DB0E7L) /* 717 */, + unchecked((long) 0x55000029D1A5AA7EL) /* 718 */, unchecked((long) 0x8BC08AE1B5061B45L) /* 719 */, + unchecked((long) 0xC2C31C2B6C92703AL) /* 720 */, unchecked((long) 0x94CC596BAF25EF42L) /* 721 */, + unchecked((long) 0x0A1D73DB22540456L) /* 722 */, unchecked((long) 0x04B6A0F9D9C4179AL) /* 723 */, + unchecked((long) 0xEFFDAFA2AE3D3C60L) /* 724 */, unchecked((long) 0xF7C8075BB49496C4L) /* 725 */, + unchecked((long) 0x9CC5C7141D1CD4E3L) /* 726 */, unchecked((long) 0x78BD1638218E5534L) /* 727 */, + unchecked((long) 0xB2F11568F850246AL) /* 728 */, unchecked((long) 0xEDFABCFA9502BC29L) /* 729 */, + unchecked((long) 0x796CE5F2DA23051BL) /* 730 */, unchecked((long) 0xAAE128B0DC93537CL) /* 731 */, + unchecked((long) 0x3A493DA0EE4B29AEL) /* 732 */, unchecked((long) 0xB5DF6B2C416895D7L) /* 733 */, + unchecked((long) 0xFCABBD25122D7F37L) /* 734 */, unchecked((long) 0x70810B58105DC4B1L) /* 735 */, + unchecked((long) 0xE10FDD37F7882A90L) /* 736 */, unchecked((long) 0x524DCAB5518A3F5CL) /* 737 */, + unchecked((long) 0x3C9E85878451255BL) /* 738 */, unchecked((long) 0x4029828119BD34E2L) /* 739 */, + unchecked((long) 0x74A05B6F5D3CECCBL) /* 740 */, unchecked((long) 0xB610021542E13ECAL) /* 741 */, + unchecked((long) 0x0FF979D12F59E2ACL) /* 742 */, unchecked((long) 0x6037DA27E4F9CC50L) /* 743 */, + unchecked((long) 0x5E92975A0DF1847DL) /* 744 */, unchecked((long) 0xD66DE190D3E623FEL) /* 745 */, + unchecked((long) 0x5032D6B87B568048L) /* 746 */, unchecked((long) 0x9A36B7CE8235216EL) /* 747 */, + unchecked((long) 0x80272A7A24F64B4AL) /* 748 */, unchecked((long) 0x93EFED8B8C6916F7L) /* 749 */, + unchecked((long) 0x37DDBFF44CCE1555L) /* 750 */, unchecked((long) 0x4B95DB5D4B99BD25L) /* 751 */, + unchecked((long) 0x92D3FDA169812FC0L) /* 752 */, unchecked((long) 0xFB1A4A9A90660BB6L) /* 753 */, + unchecked((long) 0x730C196946A4B9B2L) /* 754 */, unchecked((long) 0x81E289AA7F49DA68L) /* 755 */, + unchecked((long) 0x64669A0F83B1A05FL) /* 756 */, unchecked((long) 0x27B3FF7D9644F48BL) /* 757 */, + unchecked((long) 0xCC6B615C8DB675B3L) /* 758 */, unchecked((long) 0x674F20B9BCEBBE95L) /* 759 */, + unchecked((long) 0x6F31238275655982L) /* 760 */, unchecked((long) 0x5AE488713E45CF05L) /* 761 */, + unchecked((long) 0xBF619F9954C21157L) /* 762 */, unchecked((long) 0xEABAC46040A8EAE9L) /* 763 */, + unchecked((long) 0x454C6FE9F2C0C1CDL) /* 764 */, unchecked((long) 0x419CF6496412691CL) /* 765 */, + unchecked((long) 0xD3DC3BEF265B0F70L) /* 766 */, unchecked((long) 0x6D0E60F5C3578A9EL) /* 767 */, + }; + + private static readonly long[] t4 = { + unchecked((long) 0x5B0E608526323C55L) /* 768 */, unchecked((long) 0x1A46C1A9FA1B59F5L) /* 769 */, + unchecked((long) 0xA9E245A17C4C8FFAL) /* 770 */, unchecked((long) 0x65CA5159DB2955D7L) /* 771 */, + unchecked((long) 0x05DB0A76CE35AFC2L) /* 772 */, unchecked((long) 0x81EAC77EA9113D45L) /* 773 */, + unchecked((long) 0x528EF88AB6AC0A0DL) /* 774 */, unchecked((long) 0xA09EA253597BE3FFL) /* 775 */, + unchecked((long) 0x430DDFB3AC48CD56L) /* 776 */, unchecked((long) 0xC4B3A67AF45CE46FL) /* 777 */, + unchecked((long) 0x4ECECFD8FBE2D05EL) /* 778 */, unchecked((long) 0x3EF56F10B39935F0L) /* 779 */, + unchecked((long) 0x0B22D6829CD619C6L) /* 780 */, unchecked((long) 0x17FD460A74DF2069L) /* 781 */, + unchecked((long) 0x6CF8CC8E8510ED40L) /* 782 */, unchecked((long) 0xD6C824BF3A6ECAA7L) /* 783 */, + unchecked((long) 0x61243D581A817049L) /* 784 */, unchecked((long) 0x048BACB6BBC163A2L) /* 785 */, + unchecked((long) 0xD9A38AC27D44CC32L) /* 786 */, unchecked((long) 0x7FDDFF5BAAF410ABL) /* 787 */, + unchecked((long) 0xAD6D495AA804824BL) /* 788 */, unchecked((long) 0xE1A6A74F2D8C9F94L) /* 789 */, + unchecked((long) 0xD4F7851235DEE8E3L) /* 790 */, unchecked((long) 0xFD4B7F886540D893L) /* 791 */, + unchecked((long) 0x247C20042AA4BFDAL) /* 792 */, unchecked((long) 0x096EA1C517D1327CL) /* 793 */, + unchecked((long) 0xD56966B4361A6685L) /* 794 */, unchecked((long) 0x277DA5C31221057DL) /* 795 */, + unchecked((long) 0x94D59893A43ACFF7L) /* 796 */, unchecked((long) 0x64F0C51CCDC02281L) /* 797 */, + unchecked((long) 0x3D33BCC4FF6189DBL) /* 798 */, unchecked((long) 0xE005CB184CE66AF1L) /* 799 */, + unchecked((long) 0xFF5CCD1D1DB99BEAL) /* 800 */, unchecked((long) 0xB0B854A7FE42980FL) /* 801 */, + unchecked((long) 0x7BD46A6A718D4B9FL) /* 802 */, unchecked((long) 0xD10FA8CC22A5FD8CL) /* 803 */, + unchecked((long) 0xD31484952BE4BD31L) /* 804 */, unchecked((long) 0xC7FA975FCB243847L) /* 805 */, + unchecked((long) 0x4886ED1E5846C407L) /* 806 */, unchecked((long) 0x28CDDB791EB70B04L) /* 807 */, + unchecked((long) 0xC2B00BE2F573417FL) /* 808 */, unchecked((long) 0x5C9590452180F877L) /* 809 */, + unchecked((long) 0x7A6BDDFFF370EB00L) /* 810 */, unchecked((long) 0xCE509E38D6D9D6A4L) /* 811 */, + unchecked((long) 0xEBEB0F00647FA702L) /* 812 */, unchecked((long) 0x1DCC06CF76606F06L) /* 813 */, + unchecked((long) 0xE4D9F28BA286FF0AL) /* 814 */, unchecked((long) 0xD85A305DC918C262L) /* 815 */, + unchecked((long) 0x475B1D8732225F54L) /* 816 */, unchecked((long) 0x2D4FB51668CCB5FEL) /* 817 */, + unchecked((long) 0xA679B9D9D72BBA20L) /* 818 */, unchecked((long) 0x53841C0D912D43A5L) /* 819 */, + unchecked((long) 0x3B7EAA48BF12A4E8L) /* 820 */, unchecked((long) 0x781E0E47F22F1DDFL) /* 821 */, + unchecked((long) 0xEFF20CE60AB50973L) /* 822 */, unchecked((long) 0x20D261D19DFFB742L) /* 823 */, + unchecked((long) 0x16A12B03062A2E39L) /* 824 */, unchecked((long) 0x1960EB2239650495L) /* 825 */, + unchecked((long) 0x251C16FED50EB8B8L) /* 826 */, unchecked((long) 0x9AC0C330F826016EL) /* 827 */, + unchecked((long) 0xED152665953E7671L) /* 828 */, unchecked((long) 0x02D63194A6369570L) /* 829 */, + unchecked((long) 0x5074F08394B1C987L) /* 830 */, unchecked((long) 0x70BA598C90B25CE1L) /* 831 */, + unchecked((long) 0x794A15810B9742F6L) /* 832 */, unchecked((long) 0x0D5925E9FCAF8C6CL) /* 833 */, + unchecked((long) 0x3067716CD868744EL) /* 834 */, unchecked((long) 0x910AB077E8D7731BL) /* 835 */, + unchecked((long) 0x6A61BBDB5AC42F61L) /* 836 */, unchecked((long) 0x93513EFBF0851567L) /* 837 */, + unchecked((long) 0xF494724B9E83E9D5L) /* 838 */, unchecked((long) 0xE887E1985C09648DL) /* 839 */, + unchecked((long) 0x34B1D3C675370CFDL) /* 840 */, unchecked((long) 0xDC35E433BC0D255DL) /* 841 */, + unchecked((long) 0xD0AAB84234131BE0L) /* 842 */, unchecked((long) 0x08042A50B48B7EAFL) /* 843 */, + unchecked((long) 0x9997C4EE44A3AB35L) /* 844 */, unchecked((long) 0x829A7B49201799D0L) /* 845 */, + unchecked((long) 0x263B8307B7C54441L) /* 846 */, unchecked((long) 0x752F95F4FD6A6CA6L) /* 847 */, + unchecked((long) 0x927217402C08C6E5L) /* 848 */, unchecked((long) 0x2A8AB754A795D9EEL) /* 849 */, + unchecked((long) 0xA442F7552F72943DL) /* 850 */, unchecked((long) 0x2C31334E19781208L) /* 851 */, + unchecked((long) 0x4FA98D7CEAEE6291L) /* 852 */, unchecked((long) 0x55C3862F665DB309L) /* 853 */, + unchecked((long) 0xBD0610175D53B1F3L) /* 854 */, unchecked((long) 0x46FE6CB840413F27L) /* 855 */, + unchecked((long) 0x3FE03792DF0CFA59L) /* 856 */, unchecked((long) 0xCFE700372EB85E8FL) /* 857 */, + unchecked((long) 0xA7BE29E7ADBCE118L) /* 858 */, unchecked((long) 0xE544EE5CDE8431DDL) /* 859 */, + unchecked((long) 0x8A781B1B41F1873EL) /* 860 */, unchecked((long) 0xA5C94C78A0D2F0E7L) /* 861 */, + unchecked((long) 0x39412E2877B60728L) /* 862 */, unchecked((long) 0xA1265EF3AFC9A62CL) /* 863 */, + unchecked((long) 0xBCC2770C6A2506C5L) /* 864 */, unchecked((long) 0x3AB66DD5DCE1CE12L) /* 865 */, + unchecked((long) 0xE65499D04A675B37L) /* 866 */, unchecked((long) 0x7D8F523481BFD216L) /* 867 */, + unchecked((long) 0x0F6F64FCEC15F389L) /* 868 */, unchecked((long) 0x74EFBE618B5B13C8L) /* 869 */, + unchecked((long) 0xACDC82B714273E1DL) /* 870 */, unchecked((long) 0xDD40BFE003199D17L) /* 871 */, + unchecked((long) 0x37E99257E7E061F8L) /* 872 */, unchecked((long) 0xFA52626904775AAAL) /* 873 */, + unchecked((long) 0x8BBBF63A463D56F9L) /* 874 */, unchecked((long) 0xF0013F1543A26E64L) /* 875 */, + unchecked((long) 0xA8307E9F879EC898L) /* 876 */, unchecked((long) 0xCC4C27A4150177CCL) /* 877 */, + unchecked((long) 0x1B432F2CCA1D3348L) /* 878 */, unchecked((long) 0xDE1D1F8F9F6FA013L) /* 879 */, + unchecked((long) 0x606602A047A7DDD6L) /* 880 */, unchecked((long) 0xD237AB64CC1CB2C7L) /* 881 */, + unchecked((long) 0x9B938E7225FCD1D3L) /* 882 */, unchecked((long) 0xEC4E03708E0FF476L) /* 883 */, + unchecked((long) 0xFEB2FBDA3D03C12DL) /* 884 */, unchecked((long) 0xAE0BCED2EE43889AL) /* 885 */, + unchecked((long) 0x22CB8923EBFB4F43L) /* 886 */, unchecked((long) 0x69360D013CF7396DL) /* 887 */, + unchecked((long) 0x855E3602D2D4E022L) /* 888 */, unchecked((long) 0x073805BAD01F784CL) /* 889 */, + unchecked((long) 0x33E17A133852F546L) /* 890 */, unchecked((long) 0xDF4874058AC7B638L) /* 891 */, + unchecked((long) 0xBA92B29C678AA14AL) /* 892 */, unchecked((long) 0x0CE89FC76CFAADCDL) /* 893 */, + unchecked((long) 0x5F9D4E0908339E34L) /* 894 */, unchecked((long) 0xF1AFE9291F5923B9L) /* 895 */, + unchecked((long) 0x6E3480F60F4A265FL) /* 896 */, unchecked((long) 0xEEBF3A2AB29B841CL) /* 897 */, + unchecked((long) 0xE21938A88F91B4ADL) /* 898 */, unchecked((long) 0x57DFEFF845C6D3C3L) /* 899 */, + unchecked((long) 0x2F006B0BF62CAAF2L) /* 900 */, unchecked((long) 0x62F479EF6F75EE78L) /* 901 */, + unchecked((long) 0x11A55AD41C8916A9L) /* 902 */, unchecked((long) 0xF229D29084FED453L) /* 903 */, + unchecked((long) 0x42F1C27B16B000E6L) /* 904 */, unchecked((long) 0x2B1F76749823C074L) /* 905 */, + unchecked((long) 0x4B76ECA3C2745360L) /* 906 */, unchecked((long) 0x8C98F463B91691BDL) /* 907 */, + unchecked((long) 0x14BCC93CF1ADE66AL) /* 908 */, unchecked((long) 0x8885213E6D458397L) /* 909 */, + unchecked((long) 0x8E177DF0274D4711L) /* 910 */, unchecked((long) 0xB49B73B5503F2951L) /* 911 */, + unchecked((long) 0x10168168C3F96B6BL) /* 912 */, unchecked((long) 0x0E3D963B63CAB0AEL) /* 913 */, + unchecked((long) 0x8DFC4B5655A1DB14L) /* 914 */, unchecked((long) 0xF789F1356E14DE5CL) /* 915 */, + unchecked((long) 0x683E68AF4E51DAC1L) /* 916 */, unchecked((long) 0xC9A84F9D8D4B0FD9L) /* 917 */, + unchecked((long) 0x3691E03F52A0F9D1L) /* 918 */, unchecked((long) 0x5ED86E46E1878E80L) /* 919 */, + unchecked((long) 0x3C711A0E99D07150L) /* 920 */, unchecked((long) 0x5A0865B20C4E9310L) /* 921 */, + unchecked((long) 0x56FBFC1FE4F0682EL) /* 922 */, unchecked((long) 0xEA8D5DE3105EDF9BL) /* 923 */, + unchecked((long) 0x71ABFDB12379187AL) /* 924 */, unchecked((long) 0x2EB99DE1BEE77B9CL) /* 925 */, + unchecked((long) 0x21ECC0EA33CF4523L) /* 926 */, unchecked((long) 0x59A4D7521805C7A1L) /* 927 */, + unchecked((long) 0x3896F5EB56AE7C72L) /* 928 */, unchecked((long) 0xAA638F3DB18F75DCL) /* 929 */, + unchecked((long) 0x9F39358DABE9808EL) /* 930 */, unchecked((long) 0xB7DEFA91C00B72ACL) /* 931 */, + unchecked((long) 0x6B5541FD62492D92L) /* 932 */, unchecked((long) 0x6DC6DEE8F92E4D5BL) /* 933 */, + unchecked((long) 0x353F57ABC4BEEA7EL) /* 934 */, unchecked((long) 0x735769D6DA5690CEL) /* 935 */, + unchecked((long) 0x0A234AA642391484L) /* 936 */, unchecked((long) 0xF6F9508028F80D9DL) /* 937 */, + unchecked((long) 0xB8E319A27AB3F215L) /* 938 */, unchecked((long) 0x31AD9C1151341A4DL) /* 939 */, + unchecked((long) 0x773C22A57BEF5805L) /* 940 */, unchecked((long) 0x45C7561A07968633L) /* 941 */, + unchecked((long) 0xF913DA9E249DBE36L) /* 942 */, unchecked((long) 0xDA652D9B78A64C68L) /* 943 */, + unchecked((long) 0x4C27A97F3BC334EFL) /* 944 */, unchecked((long) 0x76621220E66B17F4L) /* 945 */, + unchecked((long) 0x967743899ACD7D0BL) /* 946 */, unchecked((long) 0xF3EE5BCAE0ED6782L) /* 947 */, + unchecked((long) 0x409F753600C879FCL) /* 948 */, unchecked((long) 0x06D09A39B5926DB6L) /* 949 */, + unchecked((long) 0x6F83AEB0317AC588L) /* 950 */, unchecked((long) 0x01E6CA4A86381F21L) /* 951 */, + unchecked((long) 0x66FF3462D19F3025L) /* 952 */, unchecked((long) 0x72207C24DDFD3BFBL) /* 953 */, + unchecked((long) 0x4AF6B6D3E2ECE2EBL) /* 954 */, unchecked((long) 0x9C994DBEC7EA08DEL) /* 955 */, + unchecked((long) 0x49ACE597B09A8BC4L) /* 956 */, unchecked((long) 0xB38C4766CF0797BAL) /* 957 */, + unchecked((long) 0x131B9373C57C2A75L) /* 958 */, unchecked((long) 0xB1822CCE61931E58L) /* 959 */, + unchecked((long) 0x9D7555B909BA1C0CL) /* 960 */, unchecked((long) 0x127FAFDD937D11D2L) /* 961 */, + unchecked((long) 0x29DA3BADC66D92E4L) /* 962 */, unchecked((long) 0xA2C1D57154C2ECBCL) /* 963 */, + unchecked((long) 0x58C5134D82F6FE24L) /* 964 */, unchecked((long) 0x1C3AE3515B62274FL) /* 965 */, + unchecked((long) 0xE907C82E01CB8126L) /* 966 */, unchecked((long) 0xF8ED091913E37FCBL) /* 967 */, + unchecked((long) 0x3249D8F9C80046C9L) /* 968 */, unchecked((long) 0x80CF9BEDE388FB63L) /* 969 */, + unchecked((long) 0x1881539A116CF19EL) /* 970 */, unchecked((long) 0x5103F3F76BD52457L) /* 971 */, + unchecked((long) 0x15B7E6F5AE47F7A8L) /* 972 */, unchecked((long) 0xDBD7C6DED47E9CCFL) /* 973 */, + unchecked((long) 0x44E55C410228BB1AL) /* 974 */, unchecked((long) 0xB647D4255EDB4E99L) /* 975 */, + unchecked((long) 0x5D11882BB8AAFC30L) /* 976 */, unchecked((long) 0xF5098BBB29D3212AL) /* 977 */, + unchecked((long) 0x8FB5EA14E90296B3L) /* 978 */, unchecked((long) 0x677B942157DD025AL) /* 979 */, + unchecked((long) 0xFB58E7C0A390ACB5L) /* 980 */, unchecked((long) 0x89D3674C83BD4A01L) /* 981 */, + unchecked((long) 0x9E2DA4DF4BF3B93BL) /* 982 */, unchecked((long) 0xFCC41E328CAB4829L) /* 983 */, + unchecked((long) 0x03F38C96BA582C52L) /* 984 */, unchecked((long) 0xCAD1BDBD7FD85DB2L) /* 985 */, + unchecked((long) 0xBBB442C16082AE83L) /* 986 */, unchecked((long) 0xB95FE86BA5DA9AB0L) /* 987 */, + unchecked((long) 0xB22E04673771A93FL) /* 988 */, unchecked((long) 0x845358C9493152D8L) /* 989 */, + unchecked((long) 0xBE2A488697B4541EL) /* 990 */, unchecked((long) 0x95A2DC2DD38E6966L) /* 991 */, + unchecked((long) 0xC02C11AC923C852BL) /* 992 */, unchecked((long) 0x2388B1990DF2A87BL) /* 993 */, + unchecked((long) 0x7C8008FA1B4F37BEL) /* 994 */, unchecked((long) 0x1F70D0C84D54E503L) /* 995 */, + unchecked((long) 0x5490ADEC7ECE57D4L) /* 996 */, unchecked((long) 0x002B3C27D9063A3AL) /* 997 */, + unchecked((long) 0x7EAEA3848030A2BFL) /* 998 */, unchecked((long) 0xC602326DED2003C0L) /* 999 */, + unchecked((long) 0x83A7287D69A94086L) /* 1000 */, unchecked((long) 0xC57A5FCB30F57A8AL) /* 1001 */, + unchecked((long) 0xB56844E479EBE779L) /* 1002 */, unchecked((long) 0xA373B40F05DCBCE9L) /* 1003 */, + unchecked((long) 0xD71A786E88570EE2L) /* 1004 */, unchecked((long) 0x879CBACDBDE8F6A0L) /* 1005 */, + unchecked((long) 0x976AD1BCC164A32FL) /* 1006 */, unchecked((long) 0xAB21E25E9666D78BL) /* 1007 */, + unchecked((long) 0x901063AAE5E5C33CL) /* 1008 */, unchecked((long) 0x9818B34448698D90L) /* 1009 */, + unchecked((long) 0xE36487AE3E1E8ABBL) /* 1010 */, unchecked((long) 0xAFBDF931893BDCB4L) /* 1011 */, + unchecked((long) 0x6345A0DC5FBBD519L) /* 1012 */, unchecked((long) 0x8628FE269B9465CAL) /* 1013 */, + unchecked((long) 0x1E5D01603F9C51ECL) /* 1014 */, unchecked((long) 0x4DE44006A15049B7L) /* 1015 */, + unchecked((long) 0xBF6C70E5F776CBB1L) /* 1016 */, unchecked((long) 0x411218F2EF552BEDL) /* 1017 */, + unchecked((long) 0xCB0C0708705A36A3L) /* 1018 */, unchecked((long) 0xE74D14754F986044L) /* 1019 */, + unchecked((long) 0xCD56D9430EA8280EL) /* 1020 */, unchecked((long) 0xC12591D7535F5065L) /* 1021 */, + unchecked((long) 0xC83223F1720AEF96L) /* 1022 */, unchecked((long) 0xC3A0396F7363A51FL) /* 1023 */ + }; + + private const int DigestLength = 24; + + // + // registers + // + private long a, b, c; + private long byteCount; + + // + // buffers + // + private byte[] Buffer = new byte[8]; + private int bOff; + + private long[] x = new long[8]; + private int xOff; + + /** + * Standard constructor + */ + public TigerDigest() + { + Reset(); + } + + /** + * Copy constructor. This will copy the state of the provided + * message digest. + */ + public TigerDigest(TigerDigest t) + { + Reset(t); + } + + public string AlgorithmName + { + get { return "Tiger"; } + } + + public int GetDigestSize() + { + return DigestLength; + } + + public int GetByteLength() + { + return MyByteLength; + } + + private void ProcessWord( + byte[] b, + int off) + { + x[xOff++] = ((long)(b[off + 7] & 0xff) << 56) + | ((long)(b[off + 6] & 0xff) << 48) + | ((long)(b[off + 5] & 0xff) << 40) + | ((long)(b[off + 4] & 0xff) << 32) + | ((long)(b[off + 3] & 0xff) << 24) + | ((long)(b[off + 2] & 0xff) << 16) + | ((long)(b[off + 1] & 0xff) << 8) + | ((uint)(b[off + 0] & 0xff)); + + if (xOff == x.Length) + { + ProcessBlock(); + } + + bOff = 0; + } + + public void Update( + byte input) + { + Buffer[bOff++] = input; + + if (bOff == Buffer.Length) + { + ProcessWord(Buffer, 0); + } + + byteCount++; + } + + public void BlockUpdate( + byte[] input, + int inOff, + int length) + { + // + // fill the current word + // + while ((bOff != 0) && (length > 0)) + { + Update(input[inOff]); + + inOff++; + length--; + } + + // + // process whole words. + // + while (length > 8) + { + ProcessWord(input, inOff); + + inOff += 8; + length -= 8; + byteCount += 8; + } + + // + // load in the remainder. + // + while (length > 0) + { + Update(input[inOff]); + + inOff++; + length--; + } + } + + private void RoundABC( + long x, + long mul) + { + c ^= x ; + a -= t1[(int)c & 0xff] ^ t2[(int)(c >> 16) & 0xff] + ^ t3[(int)(c >> 32) & 0xff] ^ t4[(int)(c >> 48) & 0xff]; + b += t4[(int)(c >> 8) & 0xff] ^ t3[(int)(c >> 24) & 0xff] + ^ t2[(int)(c >> 40) & 0xff] ^ t1[(int)(c >> 56) & 0xff]; + b *= mul; + } + + private void RoundBCA( + long x, + long mul) + { + a ^= x ; + b -= t1[(int)a & 0xff] ^ t2[(int)(a >> 16) & 0xff] + ^ t3[(int)(a >> 32) & 0xff] ^ t4[(int)(a >> 48) & 0xff]; + c += t4[(int)(a >> 8) & 0xff] ^ t3[(int)(a >> 24) & 0xff] + ^ t2[(int)(a >> 40) & 0xff] ^ t1[(int)(a >> 56) & 0xff]; + c *= mul; + } + + private void RoundCAB( + long x, + long mul) + { + b ^= x ; + c -= t1[(int)b & 0xff] ^ t2[(int)(b >> 16) & 0xff] + ^ t3[(int)(b >> 32) & 0xff] ^ t4[(int)(b >> 48) & 0xff]; + a += t4[(int)(b >> 8) & 0xff] ^ t3[(int)(b >> 24) & 0xff] + ^ t2[(int)(b >> 40) & 0xff] ^ t1[(int)(b >> 56) & 0xff]; + a *= mul; + } + + private void KeySchedule() + { + x[0] -= x[7] ^ unchecked ((long) 0xA5A5A5A5A5A5A5A5L); + x[1] ^= x[0]; + x[2] += x[1]; + x[3] -= x[2] ^ ((~x[1]) << 19); + x[4] ^= x[3]; + x[5] += x[4]; + x[6] -= x[5] ^ (long) ((ulong) (~x[4]) >> 23); + x[7] ^= x[6]; + x[0] += x[7]; + x[1] -= x[0] ^ ((~x[7]) << 19); + x[2] ^= x[1]; + x[3] += x[2]; + x[4] -= x[3] ^ (long) ((ulong) (~x[2]) >> 23); + x[5] ^= x[4]; + x[6] += x[5]; + x[7] -= x[6] ^ 0x0123456789ABCDEFL; + } + + private void ProcessBlock() + { + // + // save abc + // + long aa = a; + long bb = b; + long cc = c; + + // + // rounds and schedule + // + RoundABC(x[0], 5); + RoundBCA(x[1], 5); + RoundCAB(x[2], 5); + RoundABC(x[3], 5); + RoundBCA(x[4], 5); + RoundCAB(x[5], 5); + RoundABC(x[6], 5); + RoundBCA(x[7], 5); + + KeySchedule(); + + RoundCAB(x[0], 7); + RoundABC(x[1], 7); + RoundBCA(x[2], 7); + RoundCAB(x[3], 7); + RoundABC(x[4], 7); + RoundBCA(x[5], 7); + RoundCAB(x[6], 7); + RoundABC(x[7], 7); + + KeySchedule(); + + RoundBCA(x[0], 9); + RoundCAB(x[1], 9); + RoundABC(x[2], 9); + RoundBCA(x[3], 9); + RoundCAB(x[4], 9); + RoundABC(x[5], 9); + RoundBCA(x[6], 9); + RoundCAB(x[7], 9); + + // + // feed forward + // + a ^= aa; + b -= bb; + c += cc; + + // + // clear the x buffer + // + xOff = 0; + for (int i = 0; i != x.Length; i++) + { + x[i] = 0; + } + } + + private void UnpackWord( + long r, + byte[] output, + int outOff) + { + output[outOff + 7] = (byte)(r >> 56); + output[outOff + 6] = (byte)(r >> 48); + output[outOff + 5] = (byte)(r >> 40); + output[outOff + 4] = (byte)(r >> 32); + output[outOff + 3] = (byte)(r >> 24); + output[outOff + 2] = (byte)(r >> 16); + output[outOff + 1] = (byte)(r >> 8); + output[outOff] = (byte)r; + } + + private void ProcessLength( + long bitLength) + { + x[7] = bitLength; + } + + private void Finish() + { + long bitLength = (byteCount << 3); + + Update((byte)0x01); + + while (bOff != 0) + { + Update((byte)0); + } + + ProcessLength(bitLength); + + ProcessBlock(); + } + + public int DoFinal( + byte[] output, + int outOff) + { + Finish(); + + UnpackWord(a, output, outOff); + UnpackWord(b, output, outOff + 8); + UnpackWord(c, output, outOff + 16); + + Reset(); + + return DigestLength; + } + + /** + * reset the chaining variables + */ + public void Reset() + { + a = unchecked((long) 0x0123456789ABCDEFL); + b = unchecked((long) 0xFEDCBA9876543210L); + c = unchecked((long) 0xF096A5B4C3B2E187L); + + xOff = 0; + for (int i = 0; i != x.Length; i++) + { + x[i] = 0; + } + + bOff = 0; + for (int i = 0; i != Buffer.Length; i++) + { + Buffer[i] = 0; + } + + byteCount = 0; + } + + public IMemoable Copy() + { + return new TigerDigest(this); + } + + public void Reset(IMemoable other) + { + TigerDigest t = (TigerDigest)other; + + a = t.a; + b = t.b; + c = t.c; + + Array.Copy(t.x, 0, x, 0, t.x.Length); + xOff = t.xOff; + + Array.Copy(t.Buffer, 0, Buffer, 0, t.Buffer.Length); + bOff = t.bOff; + + byteCount = t.byteCount; + } + + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/TigerDigest.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/TigerDigest.cs.meta new file mode 100644 index 0000000..0b76c95 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/TigerDigest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 81fba5707db0e0546806ff328aca0367 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/TupleHash.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/TupleHash.cs new file mode 100644 index 0000000..98c2d2a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/TupleHash.cs @@ -0,0 +1,134 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /// + /// TupleHash - a hash designed to simply hash a tuple of input strings, any or all of which may be empty strings, + /// in an unambiguous way with an optional XOF mode. + /// + /// From NIST Special Publication 800-185 - SHA-3 Derived Functions:cSHAKE, KMAC, TupleHash and ParallelHash + /// + /// + public class TupleHash + : IXof, IDigest + { + private static readonly byte[] N_TUPLE_HASH = Strings.ToByteArray("TupleHash"); + + private readonly CShakeDigest cshake; + private readonly int bitLength; + private readonly int outputLength; + + private bool firstOutput; + + /** + * Base constructor. + * + * @param bitLength bit length of the underlying SHAKE function, 128 or 256. + * @param S the customization string - available for local use. + */ + public TupleHash(int bitLength, byte[] S) + : this(bitLength, S, bitLength * 2) + { + + } + + public TupleHash(int bitLength, byte[] S, int outputSize) + { + this.cshake = new CShakeDigest(bitLength, N_TUPLE_HASH, S); + this.bitLength = bitLength; + this.outputLength = (outputSize + 7) / 8; + + Reset(); + } + + public TupleHash(TupleHash original) + { + this.cshake = new CShakeDigest(original.cshake); + this.bitLength = cshake.fixedOutputLength; + this.outputLength = bitLength * 2 / 8; + this.firstOutput = original.firstOutput; + } + + public virtual string AlgorithmName + { + get { return "TupleHash" + cshake.AlgorithmName.Substring(6); } + } + + public virtual int GetByteLength() + { + return cshake.GetByteLength(); + } + + public virtual int GetDigestSize() + { + return outputLength; + } + + public virtual void Update(byte b) + { + byte[] bytes = XofUtilities.Encode(b); + cshake.BlockUpdate(bytes, 0, bytes.Length); + } + + public virtual void BlockUpdate(byte[] inBuf, int inOff, int len) + { + byte[] bytes = XofUtilities.Encode(inBuf, inOff, len); + cshake.BlockUpdate(bytes, 0, bytes.Length); + } + + private void wrapUp(int outputSize) + { + byte[] encOut = XofUtilities.RightEncode(outputSize * 8); + + cshake.BlockUpdate(encOut, 0, encOut.Length); + + firstOutput = false; + } + + public virtual int DoFinal(byte[] outBuf, int outOff) + { + if (firstOutput) + { + wrapUp(GetDigestSize()); + } + + int rv = cshake.DoFinal(outBuf, outOff, GetDigestSize()); + + Reset(); + + return rv; + } + + public virtual int DoFinal(byte[] outBuf, int outOff, int outLen) + { + if (firstOutput) + { + wrapUp(GetDigestSize()); + } + + int rv = cshake.DoFinal(outBuf, outOff, outLen); + + Reset(); + + return rv; + } + + public virtual int DoOutput(byte[] outBuf, int outOff, int outLen) + { + if (firstOutput) + { + wrapUp(0); + } + + return cshake.DoOutput(outBuf, outOff, outLen); + } + + public virtual void Reset() + { + cshake.Reset(); + firstOutput = true; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/TupleHash.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/TupleHash.cs.meta new file mode 100644 index 0000000..5b04188 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/TupleHash.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4600c7f4d7b6b0b46b23aae85327a355 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/WhirlpoolDigest.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/WhirlpoolDigest.cs new file mode 100644 index 0000000..55b7120 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/WhirlpoolDigest.cs @@ -0,0 +1,413 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + /** + * Implementation of WhirlpoolDigest, based on Java source published by Barreto + * and Rijmen. + * + */ + public sealed class WhirlpoolDigest + : IDigest, IMemoable + { + private const int BYTE_LENGTH = 64; + + private const int DIGEST_LENGTH_BYTES = 512 / 8; + private const int ROUNDS = 10; + private const int REDUCTION_POLYNOMIAL = 0x011d; // 2^8 + 2^4 + 2^3 + 2 + 1; + + private static readonly int[] SBOX = + { + 0x18, 0x23, 0xc6, 0xe8, 0x87, 0xb8, 0x01, 0x4f, 0x36, 0xa6, 0xd2, 0xf5, 0x79, 0x6f, 0x91, 0x52, + 0x60, 0xbc, 0x9b, 0x8e, 0xa3, 0x0c, 0x7b, 0x35, 0x1d, 0xe0, 0xd7, 0xc2, 0x2e, 0x4b, 0xfe, 0x57, + 0x15, 0x77, 0x37, 0xe5, 0x9f, 0xf0, 0x4a, 0xda, 0x58, 0xc9, 0x29, 0x0a, 0xb1, 0xa0, 0x6b, 0x85, + 0xbd, 0x5d, 0x10, 0xf4, 0xcb, 0x3e, 0x05, 0x67, 0xe4, 0x27, 0x41, 0x8b, 0xa7, 0x7d, 0x95, 0xd8, + 0xfb, 0xee, 0x7c, 0x66, 0xdd, 0x17, 0x47, 0x9e, 0xca, 0x2d, 0xbf, 0x07, 0xad, 0x5a, 0x83, 0x33, + 0x63, 0x02, 0xaa, 0x71, 0xc8, 0x19, 0x49, 0xd9, 0xf2, 0xe3, 0x5b, 0x88, 0x9a, 0x26, 0x32, 0xb0, + 0xe9, 0x0f, 0xd5, 0x80, 0xbe, 0xcd, 0x34, 0x48, 0xff, 0x7a, 0x90, 0x5f, 0x20, 0x68, 0x1a, 0xae, + 0xb4, 0x54, 0x93, 0x22, 0x64, 0xf1, 0x73, 0x12, 0x40, 0x08, 0xc3, 0xec, 0xdb, 0xa1, 0x8d, 0x3d, + 0x97, 0x00, 0xcf, 0x2b, 0x76, 0x82, 0xd6, 0x1b, 0xb5, 0xaf, 0x6a, 0x50, 0x45, 0xf3, 0x30, 0xef, + 0x3f, 0x55, 0xa2, 0xea, 0x65, 0xba, 0x2f, 0xc0, 0xde, 0x1c, 0xfd, 0x4d, 0x92, 0x75, 0x06, 0x8a, + 0xb2, 0xe6, 0x0e, 0x1f, 0x62, 0xd4, 0xa8, 0x96, 0xf9, 0xc5, 0x25, 0x59, 0x84, 0x72, 0x39, 0x4c, + 0x5e, 0x78, 0x38, 0x8c, 0xd1, 0xa5, 0xe2, 0x61, 0xb3, 0x21, 0x9c, 0x1e, 0x43, 0xc7, 0xfc, 0x04, + 0x51, 0x99, 0x6d, 0x0d, 0xfa, 0xdf, 0x7e, 0x24, 0x3b, 0xab, 0xce, 0x11, 0x8f, 0x4e, 0xb7, 0xeb, + 0x3c, 0x81, 0x94, 0xf7, 0xb9, 0x13, 0x2c, 0xd3, 0xe7, 0x6e, 0xc4, 0x03, 0x56, 0x44, 0x7f, 0xa9, + 0x2a, 0xbb, 0xc1, 0x53, 0xdc, 0x0b, 0x9d, 0x6c, 0x31, 0x74, 0xf6, 0x46, 0xac, 0x89, 0x14, 0xe1, + 0x16, 0x3a, 0x69, 0x09, 0x70, 0xb6, 0xd0, 0xed, 0xcc, 0x42, 0x98, 0xa4, 0x28, 0x5c, 0xf8, 0x86 + }; + + private static readonly long[] C0 = new long[256]; + private static readonly long[] C1 = new long[256]; + private static readonly long[] C2 = new long[256]; + private static readonly long[] C3 = new long[256]; + private static readonly long[] C4 = new long[256]; + private static readonly long[] C5 = new long[256]; + private static readonly long[] C6 = new long[256]; + private static readonly long[] C7 = new long[256]; + + private readonly long[] _rc = new long[ROUNDS + 1]; + + /* + * increment() can be implemented in this way using 2 arrays or + * by having some temporary variables that are used to set the + * value provided by EIGHT[i] and carry within the loop. + * + * not having done any timing, this seems likely to be faster + * at the slight expense of 32*(sizeof short) bytes + */ + private static readonly short[] EIGHT = new short[BITCOUNT_ARRAY_SIZE]; + + static WhirlpoolDigest() + { + EIGHT[BITCOUNT_ARRAY_SIZE - 1] = 8; + + for (int i = 0; i < 256; i++) + { + int v1 = SBOX[i]; + int v2 = maskWithReductionPolynomial(v1 << 1); + int v4 = maskWithReductionPolynomial(v2 << 1); + int v5 = v4 ^ v1; + int v8 = maskWithReductionPolynomial(v4 << 1); + int v9 = v8 ^ v1; + + C0[i] = packIntoLong(v1, v1, v4, v1, v8, v5, v2, v9); + C1[i] = packIntoLong(v9, v1, v1, v4, v1, v8, v5, v2); + C2[i] = packIntoLong(v2, v9, v1, v1, v4, v1, v8, v5); + C3[i] = packIntoLong(v5, v2, v9, v1, v1, v4, v1, v8); + C4[i] = packIntoLong(v8, v5, v2, v9, v1, v1, v4, v1); + C5[i] = packIntoLong(v1, v8, v5, v2, v9, v1, v1, v4); + C6[i] = packIntoLong(v4, v1, v8, v5, v2, v9, v1, v1); + C7[i] = packIntoLong(v1, v4, v1, v8, v5, v2, v9, v1); + } + } + + public WhirlpoolDigest() + { + _rc[0] = 0L; + for (int r = 1; r <= ROUNDS; r++) + { + int i = 8 * (r - 1); + _rc[r] = (long)((ulong)C0[i] & 0xff00000000000000L) ^ + (C1[i + 1] & (long) 0x00ff000000000000L) ^ + (C2[i + 2] & (long) 0x0000ff0000000000L) ^ + (C3[i + 3] & (long) 0x000000ff00000000L) ^ + (C4[i + 4] & (long) 0x00000000ff000000L) ^ + (C5[i + 5] & (long) 0x0000000000ff0000L) ^ + (C6[i + 6] & (long) 0x000000000000ff00L) ^ + (C7[i + 7] & (long) 0x00000000000000ffL); + } + } + + private static long packIntoLong(int b7, int b6, int b5, int b4, int b3, int b2, int b1, int b0) + { + return + ((long)b7 << 56) ^ + ((long)b6 << 48) ^ + ((long)b5 << 40) ^ + ((long)b4 << 32) ^ + ((long)b3 << 24) ^ + ((long)b2 << 16) ^ + ((long)b1 << 8) ^ + b0; + } + + /* + * int's are used to prevent sign extension. The values that are really being used are + * actually just 0..255 + */ + private static int maskWithReductionPolynomial(int input) + { + int rv = input; + if (rv >= 0x100L) // high bit set + { + rv ^= REDUCTION_POLYNOMIAL; // reduced by the polynomial + } + return rv; + } + + // --------------------------------------------------------------------------------------// + + // -- buffer information -- + private const int BITCOUNT_ARRAY_SIZE = 32; + private byte[] _buffer = new byte[64]; + private int _bufferPos; + private short[] _bitCount = new short[BITCOUNT_ARRAY_SIZE]; + + // -- internal hash state -- + private long[] _hash = new long[8]; + private long[] _K = new long[8]; // the round key + private long[] _L = new long[8]; + private long[] _block = new long[8]; // mu (buffer) + private long[] _state = new long[8]; // the current "cipher" state + + + + /** + * Copy constructor. This will copy the state of the provided message + * digest. + */ + public WhirlpoolDigest(WhirlpoolDigest originalDigest) + { + Reset(originalDigest); + } + + public string AlgorithmName + { + get { return "Whirlpool"; } + } + + public int GetDigestSize() + { + return DIGEST_LENGTH_BYTES; + } + + public int DoFinal(byte[] output, int outOff) + { + // sets output[outOff] .. output[outOff+DIGEST_LENGTH_BYTES] + finish(); + + for (int i = 0; i < 8; i++) + { + convertLongToByteArray(_hash[i], output, outOff + (i * 8)); + } + + Reset(); + + return GetDigestSize(); + } + + /** + * Reset the chaining variables + */ + public void Reset() + { + // set variables to null, blank, whatever + _bufferPos = 0; + Array.Clear(_bitCount, 0, _bitCount.Length); + Array.Clear(_buffer, 0, _buffer.Length); + Array.Clear(_hash, 0, _hash.Length); + Array.Clear(_K, 0, _K.Length); + Array.Clear(_L, 0, _L.Length); + Array.Clear(_block, 0, _block.Length); + Array.Clear(_state, 0, _state.Length); + } + + // this takes a buffer of information and fills the block + private void processFilledBuffer() + { + // copies into the block... + for (int i = 0; i < _state.Length; i++) + { + _block[i] = bytesToLongFromBuffer(_buffer, i * 8); + } + processBlock(); + _bufferPos = 0; + Array.Clear(_buffer, 0, _buffer.Length); + } + + private static long bytesToLongFromBuffer(byte[] buffer, int startPos) + { + long rv = (((buffer[startPos + 0] & 0xffL) << 56) | + ((buffer[startPos + 1] & 0xffL) << 48) | + ((buffer[startPos + 2] & 0xffL) << 40) | + ((buffer[startPos + 3] & 0xffL) << 32) | + ((buffer[startPos + 4] & 0xffL) << 24) | + ((buffer[startPos + 5] & 0xffL) << 16) | + ((buffer[startPos + 6] & 0xffL) << 8) | + ((buffer[startPos + 7]) & 0xffL)); + + return rv; + } + + private static void convertLongToByteArray(long inputLong, byte[] outputArray, int offSet) + { + for (int i = 0; i < 8; i++) + { + outputArray[offSet + i] = (byte)((inputLong >> (56 - (i * 8))) & 0xff); + } + } + + private void processBlock() + { + // buffer contents have been transferred to the _block[] array via + // processFilledBuffer + + // compute and apply K^0 + for (int i = 0; i < 8; i++) + { + _state[i] = _block[i] ^ (_K[i] = _hash[i]); + } + + // iterate over the rounds + for (int round = 1; round <= ROUNDS; round++) + { + for (int i = 0; i < 8; i++) + { + _L[i] = 0; + _L[i] ^= C0[(int)(_K[(i - 0) & 7] >> 56) & 0xff]; + _L[i] ^= C1[(int)(_K[(i - 1) & 7] >> 48) & 0xff]; + _L[i] ^= C2[(int)(_K[(i - 2) & 7] >> 40) & 0xff]; + _L[i] ^= C3[(int)(_K[(i - 3) & 7] >> 32) & 0xff]; + _L[i] ^= C4[(int)(_K[(i - 4) & 7] >> 24) & 0xff]; + _L[i] ^= C5[(int)(_K[(i - 5) & 7] >> 16) & 0xff]; + _L[i] ^= C6[(int)(_K[(i - 6) & 7] >> 8) & 0xff]; + _L[i] ^= C7[(int)(_K[(i - 7) & 7]) & 0xff]; + } + + Array.Copy(_L, 0, _K, 0, _K.Length); + + _K[0] ^= _rc[round]; + + // apply the round transformation + for (int i = 0; i < 8; i++) + { + _L[i] = _K[i]; + + _L[i] ^= C0[(int)(_state[(i - 0) & 7] >> 56) & 0xff]; + _L[i] ^= C1[(int)(_state[(i - 1) & 7] >> 48) & 0xff]; + _L[i] ^= C2[(int)(_state[(i - 2) & 7] >> 40) & 0xff]; + _L[i] ^= C3[(int)(_state[(i - 3) & 7] >> 32) & 0xff]; + _L[i] ^= C4[(int)(_state[(i - 4) & 7] >> 24) & 0xff]; + _L[i] ^= C5[(int)(_state[(i - 5) & 7] >> 16) & 0xff]; + _L[i] ^= C6[(int)(_state[(i - 6) & 7] >> 8) & 0xff]; + _L[i] ^= C7[(int)(_state[(i - 7) & 7]) & 0xff]; + } + + // save the current state + Array.Copy(_L, 0, _state, 0, _state.Length); + } + + // apply Miuaguchi-Preneel compression + for (int i = 0; i < 8; i++) + { + _hash[i] ^= _state[i] ^ _block[i]; + } + + } + + public void Update(byte input) + { + _buffer[_bufferPos] = input; + + //Console.WriteLine("adding to buffer = "+_buffer[_bufferPos]); + + ++_bufferPos; + + if (_bufferPos == _buffer.Length) + { + processFilledBuffer(); + } + + increment(); + } + + private void increment() + { + int carry = 0; + for (int i = _bitCount.Length - 1; i >= 0; i--) + { + int sum = (_bitCount[i] & 0xff) + EIGHT[i] + carry; + + carry = sum >> 8; + _bitCount[i] = (short)(sum & 0xff); + } + } + + public void BlockUpdate(byte[] input, int inOff, int length) + { + while (length > 0) + { + Update(input[inOff]); + ++inOff; + --length; + } + + } + + private void finish() + { + /* + * this makes a copy of the current bit length. at the expense of an + * object creation of 32 bytes rather than providing a _stopCounting + * boolean which was the alternative I could think of. + */ + byte[] bitLength = copyBitLength(); + + _buffer[_bufferPos++] |= 0x80; + + if (_bufferPos == _buffer.Length) + { + processFilledBuffer(); + } + + /* + * Final block contains + * [ ... data .... ][0][0][0][ length ] + * + * if [ length ] cannot fit. Need to create a new block. + */ + if (_bufferPos > 32) + { + while (_bufferPos != 0) + { + Update((byte)0); + } + } + + while (_bufferPos <= 32) + { + Update((byte)0); + } + + // copy the length information to the final 32 bytes of the + // 64 byte block.... + Array.Copy(bitLength, 0, _buffer, 32, bitLength.Length); + + processFilledBuffer(); + } + + private byte[] copyBitLength() + { + byte[] rv = new byte[BITCOUNT_ARRAY_SIZE]; + for (int i = 0; i < rv.Length; i++) + { + rv[i] = (byte)(_bitCount[i] & 0xff); + } + return rv; + } + + public int GetByteLength() + { + return BYTE_LENGTH; + } + + public IMemoable Copy() + { + return new WhirlpoolDigest(this); + } + + public void Reset(IMemoable other) + { + WhirlpoolDigest originalDigest = (WhirlpoolDigest)other; + + Array.Copy(originalDigest._rc, 0, _rc, 0, _rc.Length); + + Array.Copy(originalDigest._buffer, 0, _buffer, 0, _buffer.Length); + + this._bufferPos = originalDigest._bufferPos; + Array.Copy(originalDigest._bitCount, 0, _bitCount, 0, _bitCount.Length); + + // -- internal hash state -- + Array.Copy(originalDigest._hash, 0, _hash, 0, _hash.Length); + Array.Copy(originalDigest._K, 0, _K, 0, _K.Length); + Array.Copy(originalDigest._L, 0, _L, 0, _L.Length); + Array.Copy(originalDigest._block, 0, _block, 0, _block.Length); + Array.Copy(originalDigest._state, 0, _state, 0, _state.Length); + } + + + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/WhirlpoolDigest.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/WhirlpoolDigest.cs.meta new file mode 100644 index 0000000..2782b14 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/WhirlpoolDigest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 060ed70e4a8da6a4c8624a1d5d790e4a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/XofUtils.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/XofUtils.cs new file mode 100644 index 0000000..a4d6622 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/XofUtils.cs @@ -0,0 +1,67 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Digests +{ + internal class XofUtilities + { + internal static byte[] LeftEncode(long strLen) + { + byte n = 1; + + long v = strLen; + while ((v >>= 8) != 0) + { + n++; + } + + byte[] b = new byte[n + 1]; + + b[0] = n; + + for (int i = 1; i <= n; i++) + { + b[i] = (byte)(strLen >> (8 * (n - i))); + } + + return b; + } + + internal static byte[] RightEncode(long strLen) + { + byte n = 1; + + long v = strLen; + while ((v >>= 8) != 0) + { + n++; + } + + byte[] b = new byte[n + 1]; + + b[n] = n; + + for (int i = 0; i < n; i++) + { + b[i] = (byte)(strLen >> (8 * (n - i - 1))); + } + + return b; + } + + internal static byte[] Encode(byte X) + { + return Arrays.Concatenate(LeftEncode(8), new byte[] { X }); + } + + internal static byte[] Encode(byte[] inBuf, int inOff, int len) + { + if (inBuf.Length == len) + { + return Arrays.Concatenate(LeftEncode(len * 8), inBuf); + } + return Arrays.Concatenate(LeftEncode(len * 8), Arrays.CopyOfRange(inBuf, inOff, inOff + len)); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/XofUtils.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/XofUtils.cs.meta new file mode 100644 index 0000000..87d9cc4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/digests/XofUtils.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8478f0ee13e07ee458cbe32c8bce9f28 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ec.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ec.meta new file mode 100644 index 0000000..4bd53df --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ec.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 671e37514adf4de488f94e874d3b5cfa +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ec/CustomNamedCurves.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ec/CustomNamedCurves.cs new file mode 100644 index 0000000..0eee66a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ec/CustomNamedCurves.cs @@ -0,0 +1,896 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.GM; +using Org.BouncyCastle.Asn1.Sec; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Math.EC.Custom.Djb; +using Org.BouncyCastle.Math.EC.Custom.GM; +using Org.BouncyCastle.Math.EC.Custom.Sec; +using Org.BouncyCastle.Math.EC.Endo; +using Org.BouncyCastle.Math.EC.Multiplier; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Crypto.EC +{ + public sealed class CustomNamedCurves + { + private CustomNamedCurves() + { + } + + private static X9ECPoint ConfigureBasepoint(ECCurve curve, string encoding) + { + X9ECPoint G = new X9ECPoint(curve, Hex.DecodeStrict(encoding)); + WNafUtilities.ConfigureBasepoint(G.Point); + return G; + } + + private static ECCurve ConfigureCurve(ECCurve curve) + { + return curve; + } + + private static ECCurve ConfigureCurveGlv(ECCurve c, GlvTypeBParameters p) + { + return c.Configure().SetEndomorphism(new GlvTypeBEndomorphism(c, p)).Create(); + } + + /* + * curve25519 + */ + internal class Curve25519Holder + : X9ECParametersHolder + { + private Curve25519Holder() { } + + internal static readonly X9ECParametersHolder Instance = new Curve25519Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = null; + ECCurve curve = ConfigureCurve(new Curve25519()); + + /* + * NOTE: Curve25519 was specified in Montgomery form. Rewriting in Weierstrass form + * involves substitution of variables, so the base-point x coordinate is 9 + (486662 / 3). + * + * The Curve25519 paper doesn't say which of the two possible y values the base + * point has. The choice here is guided by language in the Ed25519 paper. + * + * (The other possible y value is 5F51E65E475F794B1FE122D388B72EB36DC2B28192839E4DD6163A5D81312C14) + */ + X9ECPoint G = ConfigureBasepoint(curve, + "042AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD245A20AE19A1B8A086B4E01EDD2C7748D14C923D4D7E6D7C61B229E9C5A27ECED3D9"); + + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + } + + /* + * secp128r1 + */ + internal class SecP128R1Holder + : X9ECParametersHolder + { + private SecP128R1Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecP128R1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = Hex.DecodeStrict("000E0D4D696E6768756151750CC03A4473D03679"); + ECCurve curve = ConfigureCurve(new SecP128R1Curve()); + X9ECPoint G = ConfigureBasepoint(curve, + "04161FF7528B899B2D0C28607CA52C5B86CF5AC8395BAFEB13C02DA292DDED7A83"); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + }; + + /* + * secp160k1 + */ + internal class SecP160K1Holder + : X9ECParametersHolder + { + private SecP160K1Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecP160K1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = null; + GlvTypeBParameters glv = new GlvTypeBParameters( + new BigInteger("9ba48cba5ebcb9b6bd33b92830b2a2e0e192f10a", 16), + new BigInteger("c39c6c3b3a36d7701b9c71a1f5804ae5d0003f4", 16), + new ScalarSplitParameters( + new BigInteger[]{ + new BigInteger("9162fbe73984472a0a9e", 16), + new BigInteger("-96341f1138933bc2f505", 16) }, + new BigInteger[]{ + new BigInteger("127971af8721782ecffa3", 16), + new BigInteger("9162fbe73984472a0a9e", 16) }, + new BigInteger("9162fbe73984472a0a9d0590", 16), + new BigInteger("96341f1138933bc2f503fd44", 16), + 176)); + ECCurve curve = ConfigureCurveGlv(new SecP160K1Curve(), glv); + X9ECPoint G = ConfigureBasepoint(curve, + "043B4C382CE37AA192A4019E763036F4F5DD4D7EBB938CF935318FDCED6BC28286531733C3F03C4FEE"); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + }; + + /* + * secp160r1 + */ + internal class SecP160R1Holder + : X9ECParametersHolder + { + private SecP160R1Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecP160R1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = Hex.DecodeStrict("1053CDE42C14D696E67687561517533BF3F83345"); + ECCurve curve = ConfigureCurve(new SecP160R1Curve()); + X9ECPoint G = ConfigureBasepoint(curve, + "044A96B5688EF573284664698968C38BB913CBFC8223A628553168947D59DCC912042351377AC5FB32"); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + }; + + /* + * secp160r2 + */ + internal class SecP160R2Holder + : X9ECParametersHolder + { + private SecP160R2Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecP160R2Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = Hex.DecodeStrict("B99B99B099B323E02709A4D696E6768756151751"); + ECCurve curve = ConfigureCurve(new SecP160R2Curve()); + X9ECPoint G = ConfigureBasepoint(curve, + "0452DCB034293A117E1F4FF11B30F7199D3144CE6DFEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E"); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + }; + + /* + * secp192k1 + */ + internal class SecP192K1Holder + : X9ECParametersHolder + { + private SecP192K1Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecP192K1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = null; + GlvTypeBParameters glv = new GlvTypeBParameters( + new BigInteger("bb85691939b869c1d087f601554b96b80cb4f55b35f433c2", 16), + new BigInteger("3d84f26c12238d7b4f3d516613c1759033b1a5800175d0b1", 16), + new ScalarSplitParameters( + new BigInteger[]{ + new BigInteger("71169be7330b3038edb025f1", 16), + new BigInteger("-b3fb3400dec5c4adceb8655c", 16) }, + new BigInteger[]{ + new BigInteger("12511cfe811d0f4e6bc688b4d", 16), + new BigInteger("71169be7330b3038edb025f1", 16) }, + new BigInteger("71169be7330b3038edb025f1d0f9", 16), + new BigInteger("b3fb3400dec5c4adceb8655d4c94", 16), + 208)); + ECCurve curve = ConfigureCurveGlv(new SecP192K1Curve(), glv); + X9ECPoint G = ConfigureBasepoint(curve, + "04DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D"); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + } + + /* + * secp192r1 + */ + internal class SecP192R1Holder + : X9ECParametersHolder + { + private SecP192R1Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecP192R1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = Hex.DecodeStrict("3045AE6FC8422F64ED579528D38120EAE12196D5"); + ECCurve curve = ConfigureCurve(new SecP192R1Curve()); + X9ECPoint G = ConfigureBasepoint(curve, + "04188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF101207192B95FFC8DA78631011ED6B24CDD573F977A11E794811"); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + } + + /* + * secp224k1 + */ + internal class SecP224K1Holder + : X9ECParametersHolder + { + private SecP224K1Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecP224K1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = null; + GlvTypeBParameters glv = new GlvTypeBParameters( + new BigInteger("fe0e87005b4e83761908c5131d552a850b3f58b749c37cf5b84d6768", 16), + new BigInteger("60dcd2104c4cbc0be6eeefc2bdd610739ec34e317f9b33046c9e4788", 16), + new ScalarSplitParameters( + new BigInteger[]{ + new BigInteger("6b8cf07d4ca75c88957d9d670591", 16), + new BigInteger("-b8adf1378a6eb73409fa6c9c637d", 16) }, + new BigInteger[]{ + new BigInteger("1243ae1b4d71613bc9f780a03690e", 16), + new BigInteger("6b8cf07d4ca75c88957d9d670591", 16) }, + new BigInteger("6b8cf07d4ca75c88957d9d67059037a4", 16), + new BigInteger("b8adf1378a6eb73409fa6c9c637ba7f5", 16), + 240)); + ECCurve curve = ConfigureCurveGlv(new SecP224K1Curve(), glv); + X9ECPoint G = ConfigureBasepoint(curve, + "04A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5"); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + } + + /* + * secp224r1 + */ + internal class SecP224R1Holder + : X9ECParametersHolder + { + private SecP224R1Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecP224R1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = Hex.DecodeStrict("BD71344799D5C7FCDC45B59FA3B9AB8F6A948BC5"); + ECCurve curve = ConfigureCurve(new SecP224R1Curve()); + X9ECPoint G = ConfigureBasepoint(curve, + "04B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34"); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + } + + /* + * secp256k1 + */ + internal class SecP256K1Holder + : X9ECParametersHolder + { + private SecP256K1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new SecP256K1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = null; + GlvTypeBParameters glv = new GlvTypeBParameters( + new BigInteger("7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee", 16), + new BigInteger("5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72", 16), + new ScalarSplitParameters( + new BigInteger[]{ + new BigInteger("3086d221a7d46bcde86c90e49284eb15", 16), + new BigInteger("-e4437ed6010e88286f547fa90abfe4c3", 16) }, + new BigInteger[]{ + new BigInteger("114ca50f7a8e2f3f657c1108d9d44cfd8", 16), + new BigInteger("3086d221a7d46bcde86c90e49284eb15", 16) }, + new BigInteger("3086d221a7d46bcde86c90e49284eb153dab", 16), + new BigInteger("e4437ed6010e88286f547fa90abfe4c42212", 16), + 272)); + ECCurve curve = ConfigureCurveGlv(new SecP256K1Curve(), glv); + X9ECPoint G = ConfigureBasepoint(curve, + "0479BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8"); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + } + + /* + * secp256r1 + */ + internal class SecP256R1Holder + : X9ECParametersHolder + { + private SecP256R1Holder() {} + + internal static readonly X9ECParametersHolder Instance = new SecP256R1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = Hex.DecodeStrict("C49D360886E704936A6678E1139D26B7819F7E90"); + ECCurve curve = ConfigureCurve(new SecP256R1Curve()); + X9ECPoint G = ConfigureBasepoint(curve, + "046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5"); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + } + + /* + * secp384r1 + */ + internal class SecP384R1Holder + : X9ECParametersHolder + { + private SecP384R1Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecP384R1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = Hex.DecodeStrict("A335926AA319A27A1D00896A6773A4827ACDAC73"); + ECCurve curve = ConfigureCurve(new SecP384R1Curve()); + X9ECPoint G = ConfigureBasepoint(curve, "04" + + "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7" + + "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F"); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + } + + /* + * secp521r1 + */ + internal class SecP521R1Holder + : X9ECParametersHolder + { + private SecP521R1Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecP521R1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = Hex.DecodeStrict("D09E8800291CB85396CC6717393284AAA0DA64BA"); + ECCurve curve = ConfigureCurve(new SecP521R1Curve()); + X9ECPoint G = ConfigureBasepoint(curve, "04" + + "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66" + + "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650"); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + } + + /* + * sect113r1 + */ + internal class SecT113R1Holder + : X9ECParametersHolder + { + private SecT113R1Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecT113R1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = Hex.DecodeStrict("10E723AB14D696E6768756151756FEBF8FCB49A9"); + ECCurve curve = ConfigureCurve(new SecT113R1Curve()); + X9ECPoint G = ConfigureBasepoint(curve, + "04009D73616F35F4AB1407D73562C10F00A52830277958EE84D1315ED31886"); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + }; + + /* + * sect113r2 + */ + internal class SecT113R2Holder + : X9ECParametersHolder + { + private SecT113R2Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecT113R2Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = Hex.DecodeStrict("10C0FB15760860DEF1EEF4D696E676875615175D"); + ECCurve curve = ConfigureCurve(new SecT113R2Curve()); + X9ECPoint G = ConfigureBasepoint(curve, + "0401A57A6A7B26CA5EF52FCDB816479700B3ADC94ED1FE674C06E695BABA1D"); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + }; + + /* + * sect131r1 + */ + internal class SecT131R1Holder + : X9ECParametersHolder + { + private SecT131R1Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecT131R1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = Hex.DecodeStrict("4D696E676875615175985BD3ADBADA21B43A97E2"); + ECCurve curve = ConfigureCurve(new SecT131R1Curve()); + X9ECPoint G = ConfigureBasepoint(curve, + "040081BAF91FDF9833C40F9C181343638399078C6E7EA38C001F73C8134B1B4EF9E150"); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + }; + + /* + * sect131r2 + */ + internal class SecT131R2Holder + : X9ECParametersHolder + { + private SecT131R2Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecT131R2Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = Hex.DecodeStrict("985BD3ADBAD4D696E676875615175A21B43A97E3"); + ECCurve curve = ConfigureCurve(new SecT131R2Curve()); + X9ECPoint G = ConfigureBasepoint(curve, + "040356DCD8F2F95031AD652D23951BB366A80648F06D867940A5366D9E265DE9EB240F"); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + }; + + /* + * sect163k1 + */ + internal class SecT163K1Holder + : X9ECParametersHolder + { + private SecT163K1Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecT163K1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = null; + ECCurve curve = ConfigureCurve(new SecT163K1Curve()); + X9ECPoint G = ConfigureBasepoint(curve, + "0402FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE80289070FB05D38FF58321F2E800536D538CCDAA3D9"); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + }; + + /* + * sect163r1 + */ + internal class SecT163R1Holder + : X9ECParametersHolder + { + private SecT163R1Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecT163R1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = Hex.DecodeStrict("24B7B137C8A14D696E6768756151756FD0DA2E5C"); + ECCurve curve = ConfigureCurve(new SecT163R1Curve()); + X9ECPoint G = ConfigureBasepoint(curve, + "040369979697AB43897789566789567F787A7876A65400435EDB42EFAFB2989D51FEFCE3C80988F41FF883"); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + }; + + /* + * sect163r2 + */ + internal class SecT163R2Holder + : X9ECParametersHolder + { + private SecT163R2Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecT163R2Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = Hex.DecodeStrict("85E25BFE5C86226CDB12016F7553F9D0E693A268"); + ECCurve curve = ConfigureCurve(new SecT163R2Curve()); + X9ECPoint G = ConfigureBasepoint(curve, + "0403F0EBA16286A2D57EA0991168D4994637E8343E3600D51FBC6C71A0094FA2CDD545B11C5C0C797324F1"); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + }; + + /* + * sect193r1 + */ + internal class SecT193R1Holder + : X9ECParametersHolder + { + private SecT193R1Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecT193R1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = Hex.DecodeStrict("103FAEC74D696E676875615175777FC5B191EF30"); + ECCurve curve = ConfigureCurve(new SecT193R1Curve()); + X9ECPoint G = ConfigureBasepoint(curve, + "0401F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E10025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05"); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + }; + + /* + * sect193r2 + */ + internal class SecT193R2Holder + : X9ECParametersHolder + { + private SecT193R2Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecT193R2Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = Hex.DecodeStrict("10B7B4D696E676875615175137C8A16FD0DA2211"); + ECCurve curve = ConfigureCurve(new SecT193R2Curve()); + X9ECPoint G = ConfigureBasepoint(curve, + "0400D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C"); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + }; + + /* + * sect233k1 + */ + internal class SecT233K1Holder + : X9ECParametersHolder + { + private SecT233K1Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecT233K1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = null; + ECCurve curve = ConfigureCurve(new SecT233K1Curve()); + X9ECPoint G = ConfigureBasepoint(curve, + "04017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD612601DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3"); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + }; + + /* + * sect233r1 + */ + internal class SecT233R1Holder + : X9ECParametersHolder + { + private SecT233R1Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecT233R1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = Hex.DecodeStrict("74D59FF07F6B413D0EA14B344B20A2DB049B50C3"); + ECCurve curve = ConfigureCurve(new SecT233R1Curve()); + X9ECPoint G = ConfigureBasepoint(curve, + "0400FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052"); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + }; + + /* + * sect239k1 + */ + internal class SecT239K1Holder + : X9ECParametersHolder + { + private SecT239K1Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecT239K1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = null; + ECCurve curve = ConfigureCurve(new SecT239K1Curve()); + X9ECPoint G = ConfigureBasepoint(curve, + "0429A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA"); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + }; + + /* + * sect283k1 + */ + internal class SecT283K1Holder + : X9ECParametersHolder + { + private SecT283K1Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecT283K1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = null; + ECCurve curve = ConfigureCurve(new SecT283K1Curve()); + X9ECPoint G = ConfigureBasepoint(curve, "04" + + "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836" + + "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259"); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + }; + + /* + * sect283r1 + */ + internal class SecT283R1Holder + : X9ECParametersHolder + { + private SecT283R1Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecT283R1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = Hex.DecodeStrict("77E2B07370EB0F832A6DD5B62DFC88CD06BB84BE"); + ECCurve curve = ConfigureCurve(new SecT283R1Curve()); + X9ECPoint G = ConfigureBasepoint(curve, "04" + + "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053" + + "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4"); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + }; + + /* + * sect409k1 + */ + internal class SecT409K1Holder + : X9ECParametersHolder + { + private SecT409K1Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecT409K1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = null; + ECCurve curve = ConfigureCurve(new SecT409K1Curve()); + X9ECPoint G = ConfigureBasepoint(curve, "04" + + "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746" + + "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B"); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + }; + + /* + * sect409r1 + */ + internal class SecT409R1Holder + : X9ECParametersHolder + { + private SecT409R1Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecT409R1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = Hex.DecodeStrict("4099B5A457F9D69F79213D094C4BCD4D4262210B"); + ECCurve curve = ConfigureCurve(new SecT409R1Curve()); + X9ECPoint G = ConfigureBasepoint(curve, "04" + + "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7" + + "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706"); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + }; + + /* + * sect571k1 + */ + internal class SecT571K1Holder + : X9ECParametersHolder + { + private SecT571K1Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecT571K1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = null; + ECCurve curve = ConfigureCurve(new SecT571K1Curve()); + X9ECPoint G = ConfigureBasepoint(curve, "04" + + "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972" + + "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3"); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + }; + + /* + * sect571r1 + */ + internal class SecT571R1Holder + : X9ECParametersHolder + { + private SecT571R1Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SecT571R1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = Hex.DecodeStrict("2AA058F73A0E33AB486B0F610410C53A7F132310"); + ECCurve curve = ConfigureCurve(new SecT571R1Curve()); + X9ECPoint G = ConfigureBasepoint(curve, "04" + + "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19" + + "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B"); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + }; + + /* + * sm2p256v1 + */ + internal class SM2P256V1Holder + : X9ECParametersHolder + { + private SM2P256V1Holder() { } + + internal static readonly X9ECParametersHolder Instance = new SM2P256V1Holder(); + + protected override X9ECParameters CreateParameters() + { + byte[] S = null; + ECCurve curve = ConfigureCurve(new SM2P256V1Curve()); + X9ECPoint G = ConfigureBasepoint(curve, + "0432C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0"); + return new X9ECParameters(curve, G, curve.Order, curve.Cofactor, S); + } + } + + + private static readonly IDictionary nameToCurve = Platform.CreateHashtable(); + private static readonly IDictionary nameToOid = Platform.CreateHashtable(); + private static readonly IDictionary oidToCurve = Platform.CreateHashtable(); + private static readonly IDictionary oidToName = Platform.CreateHashtable(); + private static readonly IList names = Platform.CreateArrayList(); + + private static void DefineCurve(string name, X9ECParametersHolder holder) + { + names.Add(name); + name = Platform.ToUpperInvariant(name); + nameToCurve.Add(name, holder); + } + + private static void DefineCurveWithOid(string name, DerObjectIdentifier oid, X9ECParametersHolder holder) + { + names.Add(name); + oidToName.Add(oid, name); + oidToCurve.Add(oid, holder); + name = Platform.ToUpperInvariant(name); + nameToOid.Add(name, oid); + nameToCurve.Add(name, holder); + } + + private static void DefineCurveAlias(string name, DerObjectIdentifier oid) + { + object curve = oidToCurve[oid]; + if (curve == null) + throw new InvalidOperationException(); + + name = Platform.ToUpperInvariant(name); + nameToOid.Add(name, oid); + nameToCurve.Add(name, curve); + } + + static CustomNamedCurves() + { + DefineCurve("curve25519", Curve25519Holder.Instance); + + //DefineCurveWithOid("secp112r1", SecObjectIdentifiers.SecP112r1, SecP112R1Holder.Instance); + //DefineCurveWithOid("secp112r2", SecObjectIdentifiers.SecP112r2, SecP112R2Holder.Instance); + DefineCurveWithOid("secp128r1", SecObjectIdentifiers.SecP128r1, SecP128R1Holder.Instance); + //DefineCurveWithOid("secp128r2", SecObjectIdentifiers.SecP128r2, SecP128R2Holder.Instance); + DefineCurveWithOid("secp160k1", SecObjectIdentifiers.SecP160k1, SecP160K1Holder.Instance); + DefineCurveWithOid("secp160r1", SecObjectIdentifiers.SecP160r1, SecP160R1Holder.Instance); + DefineCurveWithOid("secp160r2", SecObjectIdentifiers.SecP160r2, SecP160R2Holder.Instance); + DefineCurveWithOid("secp192k1", SecObjectIdentifiers.SecP192k1, SecP192K1Holder.Instance); + DefineCurveWithOid("secp192r1", SecObjectIdentifiers.SecP192r1, SecP192R1Holder.Instance); + DefineCurveWithOid("secp224k1", SecObjectIdentifiers.SecP224k1, SecP224K1Holder.Instance); + DefineCurveWithOid("secp224r1", SecObjectIdentifiers.SecP224r1, SecP224R1Holder.Instance); + DefineCurveWithOid("secp256k1", SecObjectIdentifiers.SecP256k1, SecP256K1Holder.Instance); + DefineCurveWithOid("secp256r1", SecObjectIdentifiers.SecP256r1, SecP256R1Holder.Instance); + DefineCurveWithOid("secp384r1", SecObjectIdentifiers.SecP384r1, SecP384R1Holder.Instance); + DefineCurveWithOid("secp521r1", SecObjectIdentifiers.SecP521r1, SecP521R1Holder.Instance); + + DefineCurveWithOid("sect113r1", SecObjectIdentifiers.SecT113r1, SecT113R1Holder.Instance); + DefineCurveWithOid("sect113r2", SecObjectIdentifiers.SecT113r2, SecT113R2Holder.Instance); + DefineCurveWithOid("sect131r1", SecObjectIdentifiers.SecT131r1, SecT131R1Holder.Instance); + DefineCurveWithOid("sect131r2", SecObjectIdentifiers.SecT131r2, SecT131R2Holder.Instance); + DefineCurveWithOid("sect163k1", SecObjectIdentifiers.SecT163k1, SecT163K1Holder.Instance); + DefineCurveWithOid("sect163r1", SecObjectIdentifiers.SecT163r1, SecT163R1Holder.Instance); + DefineCurveWithOid("sect163r2", SecObjectIdentifiers.SecT163r2, SecT163R2Holder.Instance); + DefineCurveWithOid("sect193r1", SecObjectIdentifiers.SecT193r1, SecT193R1Holder.Instance); + DefineCurveWithOid("sect193r2", SecObjectIdentifiers.SecT193r2, SecT193R2Holder.Instance); + DefineCurveWithOid("sect233k1", SecObjectIdentifiers.SecT233k1, SecT233K1Holder.Instance); + DefineCurveWithOid("sect233r1", SecObjectIdentifiers.SecT233r1, SecT233R1Holder.Instance); + DefineCurveWithOid("sect239k1", SecObjectIdentifiers.SecT239k1, SecT239K1Holder.Instance); + DefineCurveWithOid("sect283k1", SecObjectIdentifiers.SecT283k1, SecT283K1Holder.Instance); + DefineCurveWithOid("sect283r1", SecObjectIdentifiers.SecT283r1, SecT283R1Holder.Instance); + DefineCurveWithOid("sect409k1", SecObjectIdentifiers.SecT409k1, SecT409K1Holder.Instance); + DefineCurveWithOid("sect409r1", SecObjectIdentifiers.SecT409r1, SecT409R1Holder.Instance); + DefineCurveWithOid("sect571k1", SecObjectIdentifiers.SecT571k1, SecT571K1Holder.Instance); + DefineCurveWithOid("sect571r1", SecObjectIdentifiers.SecT571r1, SecT571R1Holder.Instance); + + DefineCurveWithOid("sm2p256v1", GMObjectIdentifiers.sm2p256v1, SM2P256V1Holder.Instance); + + DefineCurveAlias("B-163", SecObjectIdentifiers.SecT163r2); + DefineCurveAlias("B-233", SecObjectIdentifiers.SecT233r1); + DefineCurveAlias("B-283", SecObjectIdentifiers.SecT283r1); + DefineCurveAlias("B-409", SecObjectIdentifiers.SecT409r1); + DefineCurveAlias("B-571", SecObjectIdentifiers.SecT571r1); + + DefineCurveAlias("K-163", SecObjectIdentifiers.SecT163k1); + DefineCurveAlias("K-233", SecObjectIdentifiers.SecT233k1); + DefineCurveAlias("K-283", SecObjectIdentifiers.SecT283k1); + DefineCurveAlias("K-409", SecObjectIdentifiers.SecT409k1); + DefineCurveAlias("K-571", SecObjectIdentifiers.SecT571k1); + + DefineCurveAlias("P-192", SecObjectIdentifiers.SecP192r1); + DefineCurveAlias("P-224", SecObjectIdentifiers.SecP224r1); + DefineCurveAlias("P-256", SecObjectIdentifiers.SecP256r1); + DefineCurveAlias("P-384", SecObjectIdentifiers.SecP384r1); + DefineCurveAlias("P-521", SecObjectIdentifiers.SecP521r1); + } + + public static X9ECParameters GetByName(string name) + { + X9ECParametersHolder holder = (X9ECParametersHolder)nameToCurve[Platform.ToUpperInvariant(name)]; + return holder == null ? null : holder.Parameters; + } + + /** + * return the X9ECParameters object for the named curve represented by + * the passed in object identifier. Null if the curve isn't present. + * + * @param oid an object identifier representing a named curve, if present. + */ + public static X9ECParameters GetByOid(DerObjectIdentifier oid) + { + X9ECParametersHolder holder = (X9ECParametersHolder)oidToCurve[oid]; + return holder == null ? null : holder.Parameters; + } + + /** + * return the object identifier signified by the passed in name. Null + * if there is no object identifier associated with name. + * + * @return the object identifier associated with name, if present. + */ + public static DerObjectIdentifier GetOid(string name) + { + return (DerObjectIdentifier)nameToOid[Platform.ToUpperInvariant(name)]; + } + + /** + * return the named curve name represented by the given object identifier. + */ + public static string GetName(DerObjectIdentifier oid) + { + return (string)oidToName[oid]; + } + + /** + * returns an enumeration containing the name strings for curves + * contained in this structure. + */ + public static IEnumerable Names + { + get { return new EnumerableProxy(names); } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ec/CustomNamedCurves.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ec/CustomNamedCurves.cs.meta new file mode 100644 index 0000000..530ec6c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/ec/CustomNamedCurves.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b19692f7fa6e3b94fa89ab27eac96d85 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/encodings.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/encodings.meta new file mode 100644 index 0000000..480dfd4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/encodings.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 6817d97d5c7a8214981fd7a77de866e2 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/encodings/ISO9796d1Encoding.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/encodings/ISO9796d1Encoding.cs new file mode 100644 index 0000000..30e9883 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/encodings/ISO9796d1Encoding.cs @@ -0,0 +1,273 @@ +using System; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Encodings +{ + /** + * ISO 9796-1 padding. Note in the light of recent results you should + * only use this with RSA (rather than the "simpler" Rabin keys) and you + * should never use it with anything other than a hash (ie. even if the + * message is small don't sign the message, sign it's hash) or some "random" + * value. See your favorite search engine for details. + */ + public class ISO9796d1Encoding + : IAsymmetricBlockCipher + { + private static readonly BigInteger Sixteen = BigInteger.ValueOf(16); + private static readonly BigInteger Six = BigInteger.ValueOf(6); + + private static readonly byte[] shadows = { 0xe, 0x3, 0x5, 0x8, 0x9, 0x4, 0x2, 0xf, + 0x0, 0xd, 0xb, 0x6, 0x7, 0xa, 0xc, 0x1 }; + private static readonly byte[] inverse = { 0x8, 0xf, 0x6, 0x1, 0x5, 0x2, 0xb, 0xc, + 0x3, 0x4, 0xd, 0xa, 0xe, 0x9, 0x0, 0x7 }; + + private readonly IAsymmetricBlockCipher engine; + private bool forEncryption; + private int bitSize; + private int padBits = 0; + private BigInteger modulus; + + public ISO9796d1Encoding( + IAsymmetricBlockCipher cipher) + { + this.engine = cipher; + } + + public string AlgorithmName + { + get { return engine.AlgorithmName + "/ISO9796-1Padding"; } + } + + public IAsymmetricBlockCipher GetUnderlyingCipher() + { + return engine; + } + + public void Init( + bool forEncryption, + ICipherParameters parameters) + { + RsaKeyParameters kParam; + if (parameters is ParametersWithRandom) + { + ParametersWithRandom rParam = (ParametersWithRandom)parameters; + kParam = (RsaKeyParameters)rParam.Parameters; + } + else + { + kParam = (RsaKeyParameters)parameters; + } + + engine.Init(forEncryption, parameters); + + modulus = kParam.Modulus; + bitSize = modulus.BitLength; + + this.forEncryption = forEncryption; + } + + /** + * return the input block size. The largest message we can process + * is (key_size_in_bits + 3)/16, which in our world comes to + * key_size_in_bytes / 2. + */ + public int GetInputBlockSize() + { + int baseBlockSize = engine.GetInputBlockSize(); + + if (forEncryption) + { + return (baseBlockSize + 1) / 2; + } + else + { + return baseBlockSize; + } + } + + /** + * return the maximum possible size for the output. + */ + public int GetOutputBlockSize() + { + int baseBlockSize = engine.GetOutputBlockSize(); + + if (forEncryption) + { + return baseBlockSize; + } + else + { + return (baseBlockSize + 1) / 2; + } + } + + /** + * set the number of bits in the next message to be treated as + * pad bits. + */ + public void SetPadBits( + int padBits) + { + if (padBits > 7) + { + throw new ArgumentException("padBits > 7"); + } + + this.padBits = padBits; + } + + /** + * retrieve the number of pad bits in the last decoded message. + */ + public int GetPadBits() + { + return padBits; + } + + public byte[] ProcessBlock( + byte[] input, + int inOff, + int length) + { + if (forEncryption) + { + return EncodeBlock(input, inOff, length); + } + else + { + return DecodeBlock(input, inOff, length); + } + } + + private byte[] EncodeBlock( + byte[] input, + int inOff, + int inLen) + { + byte[] block = new byte[(bitSize + 7) / 8]; + int r = padBits + 1; + int z = inLen; + int t = (bitSize + 13) / 16; + + for (int i = 0; i < t; i += z) + { + if (i > t - z) + { + Array.Copy(input, inOff + inLen - (t - i), + block, block.Length - t, t - i); + } + else + { + Array.Copy(input, inOff, block, block.Length - (i + z), z); + } + } + + for (int i = block.Length - 2 * t; i != block.Length; i += 2) + { + byte val = block[block.Length - t + i / 2]; + + block[i] = (byte)((shadows[(uint) (val & 0xff) >> 4] << 4) + | shadows[val & 0x0f]); + block[i + 1] = val; + } + + block[block.Length - 2 * z] ^= (byte) r; + block[block.Length - 1] = (byte)((block[block.Length - 1] << 4) | 0x06); + + int maxBit = (8 - (bitSize - 1) % 8); + int offSet = 0; + + if (maxBit != 8) + { + block[0] &= (byte) ((ushort) 0xff >> maxBit); + block[0] |= (byte) ((ushort) 0x80 >> maxBit); + } + else + { + block[0] = 0x00; + block[1] |= 0x80; + offSet = 1; + } + + return engine.ProcessBlock(block, offSet, block.Length - offSet); + } + + /** + * @exception InvalidCipherTextException if the decrypted block is not a valid ISO 9796 bit string + */ + private byte[] DecodeBlock( + byte[] input, + int inOff, + int inLen) + { + byte[] block = engine.ProcessBlock(input, inOff, inLen); + int r = 1; + int t = (bitSize + 13) / 16; + + BigInteger iS = new BigInteger(1, block); + BigInteger iR; + if (iS.Mod(Sixteen).Equals(Six)) + { + iR = iS; + } + else + { + iR = modulus.Subtract(iS); + + if (!iR.Mod(Sixteen).Equals(Six)) + throw new InvalidCipherTextException("resulting integer iS or (modulus - iS) is not congruent to 6 mod 16"); + } + + block = iR.ToByteArrayUnsigned(); + + if ((block[block.Length - 1] & 0x0f) != 0x6) + throw new InvalidCipherTextException("invalid forcing byte in block"); + + block[block.Length - 1] = + (byte)(((ushort)(block[block.Length - 1] & 0xff) >> 4) + | ((inverse[(block[block.Length - 2] & 0xff) >> 4]) << 4)); + + block[0] = (byte)((shadows[(uint) (block[1] & 0xff) >> 4] << 4) + | shadows[block[1] & 0x0f]); + + bool boundaryFound = false; + int boundary = 0; + + for (int i = block.Length - 1; i >= block.Length - 2 * t; i -= 2) + { + int val = ((shadows[(uint) (block[i] & 0xff) >> 4] << 4) + | shadows[block[i] & 0x0f]); + + if (((block[i - 1] ^ val) & 0xff) != 0) + { + if (!boundaryFound) + { + boundaryFound = true; + r = (block[i - 1] ^ val) & 0xff; + boundary = i - 1; + } + else + { + throw new InvalidCipherTextException("invalid tsums in block"); + } + } + } + + block[boundary] = 0; + + byte[] nblock = new byte[(block.Length - boundary) / 2]; + + for (int i = 0; i < nblock.Length; i++) + { + nblock[i] = block[2 * i + boundary + 1]; + } + + padBits = r - 1; + + return nblock; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/encodings/ISO9796d1Encoding.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/encodings/ISO9796d1Encoding.cs.meta new file mode 100644 index 0000000..8f8899c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/encodings/ISO9796d1Encoding.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cdbae7a795bcc5f42bb9999bf593f365 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/encodings/OaepEncoding.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/encodings/OaepEncoding.cs new file mode 100644 index 0000000..295a43a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/encodings/OaepEncoding.cs @@ -0,0 +1,361 @@ +using System; + +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Encodings +{ + /** + * Optimal Asymmetric Encryption Padding (OAEP) - see PKCS 1 V 2. + */ + public class OaepEncoding + : IAsymmetricBlockCipher + { + private byte[] defHash; + private IDigest mgf1Hash; + + private IAsymmetricBlockCipher engine; + private SecureRandom random; + private bool forEncryption; + + public OaepEncoding( + IAsymmetricBlockCipher cipher) + : this(cipher, new Sha1Digest(), null) + { + } + + public OaepEncoding( + IAsymmetricBlockCipher cipher, + IDigest hash) + : this(cipher, hash, null) + { + } + + public OaepEncoding( + IAsymmetricBlockCipher cipher, + IDigest hash, + byte[] encodingParams) + : this(cipher, hash, hash, encodingParams) + { + } + + public OaepEncoding( + IAsymmetricBlockCipher cipher, + IDigest hash, + IDigest mgf1Hash, + byte[] encodingParams) + { + this.engine = cipher; + this.mgf1Hash = mgf1Hash; + this.defHash = new byte[hash.GetDigestSize()]; + + hash.Reset(); + + if (encodingParams != null) + { + hash.BlockUpdate(encodingParams, 0, encodingParams.Length); + } + + hash.DoFinal(defHash, 0); + } + + public IAsymmetricBlockCipher GetUnderlyingCipher() + { + return engine; + } + + public string AlgorithmName + { + get { return engine.AlgorithmName + "/OAEPPadding"; } + } + + public void Init( + bool forEncryption, + ICipherParameters param) + { + if (param is ParametersWithRandom) + { + ParametersWithRandom rParam = (ParametersWithRandom)param; + this.random = rParam.Random; + } + else + { + this.random = new SecureRandom(); + } + + engine.Init(forEncryption, param); + + this.forEncryption = forEncryption; + } + + public int GetInputBlockSize() + { + int baseBlockSize = engine.GetInputBlockSize(); + + if (forEncryption) + { + return baseBlockSize - 1 - 2 * defHash.Length; + } + else + { + return baseBlockSize; + } + } + + public int GetOutputBlockSize() + { + int baseBlockSize = engine.GetOutputBlockSize(); + + if (forEncryption) + { + return baseBlockSize; + } + else + { + return baseBlockSize - 1 - 2 * defHash.Length; + } + } + + public byte[] ProcessBlock( + byte[] inBytes, + int inOff, + int inLen) + { + if (forEncryption) + { + return EncodeBlock(inBytes, inOff, inLen); + } + else + { + return DecodeBlock(inBytes, inOff, inLen); + } + } + + private byte[] EncodeBlock( + byte[] inBytes, + int inOff, + int inLen) + { + Check.DataLength(inLen > GetInputBlockSize(), "input data too long"); + + byte[] block = new byte[GetInputBlockSize() + 1 + 2 * defHash.Length]; + + // + // copy in the message + // + Array.Copy(inBytes, inOff, block, block.Length - inLen, inLen); + + // + // add sentinel + // + block[block.Length - inLen - 1] = 0x01; + + // + // as the block is already zeroed - there's no need to add PS (the >= 0 pad of 0) + // + + // + // add the hash of the encoding params. + // + Array.Copy(defHash, 0, block, defHash.Length, defHash.Length); + + // + // generate the seed. + // + byte[] seed = SecureRandom.GetNextBytes(random, defHash.Length); + + // + // mask the message block. + // + byte[] mask = MaskGeneratorFunction(seed, 0, seed.Length, block.Length - defHash.Length); + + for (int i = defHash.Length; i != block.Length; i++) + { + block[i] ^= mask[i - defHash.Length]; + } + + // + // add in the seed + // + Array.Copy(seed, 0, block, 0, defHash.Length); + + // + // mask the seed. + // + mask = MaskGeneratorFunction( + block, defHash.Length, block.Length - defHash.Length, defHash.Length); + + for (int i = 0; i != defHash.Length; i++) + { + block[i] ^= mask[i]; + } + + return engine.ProcessBlock(block, 0, block.Length); + } + + /** + * @exception InvalidCipherTextException if the decrypted block turns out to + * be badly formatted. + */ + private byte[] DecodeBlock( + byte[] inBytes, + int inOff, + int inLen) + { + byte[] data = engine.ProcessBlock(inBytes, inOff, inLen); + byte[] block = new byte[engine.GetOutputBlockSize()]; + + // + // as we may have zeros in our leading bytes for the block we produced + // on encryption, we need to make sure our decrypted block comes back + // the same size. + // + bool wrongData = (block.Length < (2 * defHash.Length) + 1); + + if (data.Length <= block.Length) + { + Array.Copy(data, 0, block, block.Length - data.Length, data.Length); + } + else + { + Array.Copy(data, 0, block, 0, block.Length); + wrongData = true; + } + + // + // unmask the seed. + // + byte[] mask = MaskGeneratorFunction( + block, defHash.Length, block.Length - defHash.Length, defHash.Length); + + for (int i = 0; i != defHash.Length; i++) + { + block[i] ^= mask[i]; + } + + // + // unmask the message block. + // + mask = MaskGeneratorFunction(block, 0, defHash.Length, block.Length - defHash.Length); + + for (int i = defHash.Length; i != block.Length; i++) + { + block[i] ^= mask[i - defHash.Length]; + } + + // + // check the hash of the encoding params. + // long check to try to avoid this been a source of a timing attack. + // + bool defHashWrong = false; + + for (int i = 0; i != defHash.Length; i++) + { + if (defHash[i] != block[defHash.Length + i]) + { + defHashWrong = true; + } + } + + // + // find the data block + // + int start = block.Length; + + for (int index = 2 * defHash.Length; index != block.Length; index++) + { + if (block[index] != 0 & start == block.Length) + { + start = index; + } + } + + bool dataStartWrong = (start > (block.Length - 1) | block[start] != 1); + + start++; + + if (defHashWrong | wrongData | dataStartWrong) + { + Arrays.Fill(block, 0); + throw new InvalidCipherTextException("data wrong"); + } + + // + // extract the data block + // + byte[] output = new byte[block.Length - start]; + + Array.Copy(block, start, output, 0, output.Length); + Array.Clear(block, 0, block.Length); + + return output; + } + + private byte[] MaskGeneratorFunction( + byte[] Z, + int zOff, + int zLen, + int length) + { + if (mgf1Hash is IXof) + { + byte[] mask = new byte[length]; + mgf1Hash.BlockUpdate(Z, zOff, zLen); + ((IXof)mgf1Hash).DoFinal(mask, 0, mask.Length); + + return mask; + } + else + { + return MaskGeneratorFunction1(Z, zOff, zLen, length); + } + } + + /** + * mask generator function, as described in PKCS1v2. + */ + private byte[] MaskGeneratorFunction1( + byte[] Z, + int zOff, + int zLen, + int length) + { + byte[] mask = new byte[length]; + byte[] hashBuf = new byte[mgf1Hash.GetDigestSize()]; + byte[] C = new byte[4]; + int counter = 0; + + mgf1Hash.Reset(); + + while (counter < (length / hashBuf.Length)) + { + Pack.UInt32_To_BE((uint)counter, C); + + mgf1Hash.BlockUpdate(Z, zOff, zLen); + mgf1Hash.BlockUpdate(C, 0, C.Length); + mgf1Hash.DoFinal(hashBuf, 0); + + Array.Copy(hashBuf, 0, mask, counter * hashBuf.Length, hashBuf.Length); + + counter++; + } + + if ((counter * hashBuf.Length) < length) + { + Pack.UInt32_To_BE((uint)counter, C); + + mgf1Hash.BlockUpdate(Z, zOff, zLen); + mgf1Hash.BlockUpdate(C, 0, C.Length); + mgf1Hash.DoFinal(hashBuf, 0); + + Array.Copy(hashBuf, 0, mask, counter * hashBuf.Length, mask.Length - (counter * hashBuf.Length)); + } + + return mask; + } + } +} + diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/encodings/OaepEncoding.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/encodings/OaepEncoding.cs.meta new file mode 100644 index 0000000..35142d4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/encodings/OaepEncoding.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cc08ac5ec79684344a8661a0977ae9d9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/encodings/Pkcs1Encoding.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/encodings/Pkcs1Encoding.cs new file mode 100644 index 0000000..53c046a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/encodings/Pkcs1Encoding.cs @@ -0,0 +1,384 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Encodings +{ + /** + * this does your basic Pkcs 1 v1.5 padding - whether or not you should be using this + * depends on your application - see Pkcs1 Version 2 for details. + */ + public class Pkcs1Encoding + : IAsymmetricBlockCipher + { + /** + * some providers fail to include the leading zero in PKCS1 encoded blocks. If you need to + * work with one of these set the system property Org.BouncyCastle.Pkcs1.Strict to false. + */ + public const string StrictLengthEnabledProperty = "Org.BouncyCastle.Pkcs1.Strict"; + + private const int HeaderLength = 10; + + /** + * The same effect can be achieved by setting the static property directly + *

+ * The static property is checked during construction of the encoding object, it is set to + * true by default. + *

+ */ + public static bool StrictLengthEnabled + { + get { return strictLengthEnabled[0]; } + set { strictLengthEnabled[0] = value; } + } + + private static readonly bool[] strictLengthEnabled; + + static Pkcs1Encoding() + { + string strictProperty = Platform.GetEnvironmentVariable(StrictLengthEnabledProperty); + + strictLengthEnabled = new bool[]{ strictProperty == null || Platform.EqualsIgnoreCase("true", strictProperty) }; + } + + + private SecureRandom random; + private IAsymmetricBlockCipher engine; + private bool forEncryption; + private bool forPrivateKey; + private bool useStrictLength; + private int pLen = -1; + private byte[] fallback = null; + private byte[] blockBuffer = null; + + /** + * Basic constructor. + * + * @param cipher + */ + public Pkcs1Encoding( + IAsymmetricBlockCipher cipher) + { + this.engine = cipher; + this.useStrictLength = StrictLengthEnabled; + } + + /** + * Constructor for decryption with a fixed plaintext length. + * + * @param cipher The cipher to use for cryptographic operation. + * @param pLen Length of the expected plaintext. + */ + public Pkcs1Encoding(IAsymmetricBlockCipher cipher, int pLen) + { + this.engine = cipher; + this.useStrictLength = StrictLengthEnabled; + this.pLen = pLen; + } + + /** + * Constructor for decryption with a fixed plaintext length and a fallback + * value that is returned, if the padding is incorrect. + * + * @param cipher + * The cipher to use for cryptographic operation. + * @param fallback + * The fallback value, we don't to a arraycopy here. + */ + public Pkcs1Encoding(IAsymmetricBlockCipher cipher, byte[] fallback) + { + this.engine = cipher; + this.useStrictLength = StrictLengthEnabled; + this.fallback = fallback; + this.pLen = fallback.Length; + } + + public IAsymmetricBlockCipher GetUnderlyingCipher() + { + return engine; + } + + public string AlgorithmName + { + get { return engine.AlgorithmName + "/PKCS1Padding"; } + } + + public void Init(bool forEncryption, ICipherParameters parameters) + { + AsymmetricKeyParameter kParam; + if (parameters is ParametersWithRandom) + { + ParametersWithRandom rParam = (ParametersWithRandom)parameters; + + this.random = rParam.Random; + kParam = (AsymmetricKeyParameter)rParam.Parameters; + } + else + { + this.random = new SecureRandom(); + kParam = (AsymmetricKeyParameter)parameters; + } + + engine.Init(forEncryption, parameters); + + this.forPrivateKey = kParam.IsPrivate; + this.forEncryption = forEncryption; + this.blockBuffer = new byte[engine.GetOutputBlockSize()]; + + if (pLen > 0 && fallback == null && random == null) + throw new ArgumentException("encoder requires random"); + } + + public int GetInputBlockSize() + { + int baseBlockSize = engine.GetInputBlockSize(); + + return forEncryption + ? baseBlockSize - HeaderLength + : baseBlockSize; + } + + public int GetOutputBlockSize() + { + int baseBlockSize = engine.GetOutputBlockSize(); + + return forEncryption + ? baseBlockSize + : baseBlockSize - HeaderLength; + } + + public byte[] ProcessBlock( + byte[] input, + int inOff, + int length) + { + return forEncryption + ? EncodeBlock(input, inOff, length) + : DecodeBlock(input, inOff, length); + } + + private byte[] EncodeBlock( + byte[] input, + int inOff, + int inLen) + { + if (inLen > GetInputBlockSize()) + throw new ArgumentException("input data too large", "inLen"); + + byte[] block = new byte[engine.GetInputBlockSize()]; + + if (forPrivateKey) + { + block[0] = 0x01; // type code 1 + + for (int i = 1; i != block.Length - inLen - 1; i++) + { + block[i] = (byte)0xFF; + } + } + else + { + random.NextBytes(block); // random fill + + block[0] = 0x02; // type code 2 + + // + // a zero byte marks the end of the padding, so all + // the pad bytes must be non-zero. + // + for (int i = 1; i != block.Length - inLen - 1; i++) + { + while (block[i] == 0) + { + block[i] = (byte)random.NextInt(); + } + } + } + + block[block.Length - inLen - 1] = 0x00; // mark the end of the padding + Array.Copy(input, inOff, block, block.Length - inLen, inLen); + + return engine.ProcessBlock(block, 0, block.Length); + } + + /** + * Checks if the argument is a correctly PKCS#1.5 encoded Plaintext + * for encryption. + * + * @param encoded The Plaintext. + * @param pLen Expected length of the plaintext. + * @return Either 0, if the encoding is correct, or -1, if it is incorrect. + */ + private static int CheckPkcs1Encoding(byte[] encoded, int pLen) + { + int correct = 0; + /* + * Check if the first two bytes are 0 2 + */ + correct |= (encoded[0] ^ 2); + + /* + * Now the padding check, check for no 0 byte in the padding + */ + int plen = encoded.Length - ( + pLen /* Length of the PMS */ + + 1 /* Final 0-byte before PMS */ + ); + + for (int i = 1; i < plen; i++) + { + int tmp = encoded[i]; + tmp |= tmp >> 1; + tmp |= tmp >> 2; + tmp |= tmp >> 4; + correct |= (tmp & 1) - 1; + } + + /* + * Make sure the padding ends with a 0 byte. + */ + correct |= encoded[encoded.Length - (pLen + 1)]; + + /* + * Return 0 or 1, depending on the result. + */ + correct |= correct >> 1; + correct |= correct >> 2; + correct |= correct >> 4; + return ~((correct & 1) - 1); + } + + /** + * Decode PKCS#1.5 encoding, and return a random value if the padding is not correct. + * + * @param in The encrypted block. + * @param inOff Offset in the encrypted block. + * @param inLen Length of the encrypted block. + * @param pLen Length of the desired output. + * @return The plaintext without padding, or a random value if the padding was incorrect. + * @throws InvalidCipherTextException + */ + private byte[] DecodeBlockOrRandom(byte[] input, int inOff, int inLen) + { + if (!forPrivateKey) + throw new InvalidCipherTextException("sorry, this method is only for decryption, not for signing"); + + byte[] block = engine.ProcessBlock(input, inOff, inLen); + byte[] random; + if (this.fallback == null) + { + random = new byte[this.pLen]; + this.random.NextBytes(random); + } + else + { + random = fallback; + } + + byte[] data = (useStrictLength & (block.Length != engine.GetOutputBlockSize())) ? blockBuffer : block; + + /* + * Check the padding. + */ + int correct = CheckPkcs1Encoding(data, this.pLen); + + /* + * Now, to a constant time constant memory copy of the decrypted value + * or the random value, depending on the validity of the padding. + */ + byte[] result = new byte[this.pLen]; + for (int i = 0; i < this.pLen; i++) + { + result[i] = (byte)((data[i + (data.Length - pLen)] & (~correct)) | (random[i] & correct)); + } + + Arrays.Fill(data, 0); + + return result; + } + + /** + * @exception InvalidCipherTextException if the decrypted block is not in Pkcs1 format. + */ + private byte[] DecodeBlock( + byte[] input, + int inOff, + int inLen) + { + /* + * If the length of the expected plaintext is known, we use a constant-time decryption. + * If the decryption fails, we return a random value. + */ + if (this.pLen != -1) + { + return this.DecodeBlockOrRandom(input, inOff, inLen); + } + + byte[] block = engine.ProcessBlock(input, inOff, inLen); + bool incorrectLength = (useStrictLength & (block.Length != engine.GetOutputBlockSize())); + + byte[] data; + if (block.Length < GetOutputBlockSize()) + { + data = blockBuffer; + } + else + { + data = block; + } + + byte expectedType = (byte)(forPrivateKey ? 2 : 1); + byte type = data[0]; + + bool badType = (type != expectedType); + + // + // find and extract the message block. + // + int start = FindStart(type, data); + + start++; // data should start at the next byte + + if (badType | (start < HeaderLength)) + { + Arrays.Fill(data, 0); + throw new InvalidCipherTextException("block incorrect"); + } + + // if we get this far, it's likely to be a genuine encoding error + if (incorrectLength) + { + Arrays.Fill(data, 0); + throw new InvalidCipherTextException("block incorrect size"); + } + + byte[] result = new byte[data.Length - start]; + + Array.Copy(data, start, result, 0, result.Length); + + return result; + } + + private int FindStart(byte type, byte[] block) + { + int start = -1; + bool padErr = false; + + for (int i = 1; i != block.Length; i++) + { + byte pad = block[i]; + + if (pad == 0 & start < 0) + { + start = i; + } + padErr |= ((type == 1) & (start < 0) & (pad != (byte)0xff)); + } + + return padErr ? -1 : start; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/encodings/Pkcs1Encoding.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/encodings/Pkcs1Encoding.cs.meta new file mode 100644 index 0000000..42b2e44 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/encodings/Pkcs1Encoding.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4416ae3fdee78174db627984281575f7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines.meta new file mode 100644 index 0000000..fc2429b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 2b1c9d7205c64bd479603612f2cc061f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/AesEngine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/AesEngine.cs new file mode 100644 index 0000000..10c7209 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/AesEngine.cs @@ -0,0 +1,601 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * an implementation of the AES (Rijndael), from FIPS-197. + *

+ * For further details see: http://csrc.nist.gov/encryption/aes/. + * + * This implementation is based on optimizations from Dr. Brian Gladman's paper and C code at + * http://fp.gladman.plus.com/cryptography_technology/rijndael/ + * + * There are three levels of tradeoff of speed vs memory + * Because java has no preprocessor, they are written as three separate classes from which to choose + * + * The fastest uses 8Kbytes of static tables to precompute round calculations, 4 256 word tables for encryption + * and 4 for decryption. + * + * The middle performance version uses only one 256 word table for each, for a total of 2Kbytes, + * adding 12 rotate operations per round to compute the values contained in the other tables from + * the contents of the first. + * + * The slowest version uses no static tables at all and computes the values in each round. + *

+ *

+ * This file contains the middle performance version with 2Kbytes of static tables for round precomputation. + *

+ */ + public class AesEngine + : IBlockCipher + { + // The S box + private static readonly byte[] S = + { + 99, 124, 119, 123, 242, 107, 111, 197, + 48, 1, 103, 43, 254, 215, 171, 118, + 202, 130, 201, 125, 250, 89, 71, 240, + 173, 212, 162, 175, 156, 164, 114, 192, + 183, 253, 147, 38, 54, 63, 247, 204, + 52, 165, 229, 241, 113, 216, 49, 21, + 4, 199, 35, 195, 24, 150, 5, 154, + 7, 18, 128, 226, 235, 39, 178, 117, + 9, 131, 44, 26, 27, 110, 90, 160, + 82, 59, 214, 179, 41, 227, 47, 132, + 83, 209, 0, 237, 32, 252, 177, 91, + 106, 203, 190, 57, 74, 76, 88, 207, + 208, 239, 170, 251, 67, 77, 51, 133, + 69, 249, 2, 127, 80, 60, 159, 168, + 81, 163, 64, 143, 146, 157, 56, 245, + 188, 182, 218, 33, 16, 255, 243, 210, + 205, 12, 19, 236, 95, 151, 68, 23, + 196, 167, 126, 61, 100, 93, 25, 115, + 96, 129, 79, 220, 34, 42, 144, 136, + 70, 238, 184, 20, 222, 94, 11, 219, + 224, 50, 58, 10, 73, 6, 36, 92, + 194, 211, 172, 98, 145, 149, 228, 121, + 231, 200, 55, 109, 141, 213, 78, 169, + 108, 86, 244, 234, 101, 122, 174, 8, + 186, 120, 37, 46, 28, 166, 180, 198, + 232, 221, 116, 31, 75, 189, 139, 138, + 112, 62, 181, 102, 72, 3, 246, 14, + 97, 53, 87, 185, 134, 193, 29, 158, + 225, 248, 152, 17, 105, 217, 142, 148, + 155, 30, 135, 233, 206, 85, 40, 223, + 140, 161, 137, 13, 191, 230, 66, 104, + 65, 153, 45, 15, 176, 84, 187, 22, + }; + + // The inverse S-box + private static readonly byte[] Si = + { + 82, 9, 106, 213, 48, 54, 165, 56, + 191, 64, 163, 158, 129, 243, 215, 251, + 124, 227, 57, 130, 155, 47, 255, 135, + 52, 142, 67, 68, 196, 222, 233, 203, + 84, 123, 148, 50, 166, 194, 35, 61, + 238, 76, 149, 11, 66, 250, 195, 78, + 8, 46, 161, 102, 40, 217, 36, 178, + 118, 91, 162, 73, 109, 139, 209, 37, + 114, 248, 246, 100, 134, 104, 152, 22, + 212, 164, 92, 204, 93, 101, 182, 146, + 108, 112, 72, 80, 253, 237, 185, 218, + 94, 21, 70, 87, 167, 141, 157, 132, + 144, 216, 171, 0, 140, 188, 211, 10, + 247, 228, 88, 5, 184, 179, 69, 6, + 208, 44, 30, 143, 202, 63, 15, 2, + 193, 175, 189, 3, 1, 19, 138, 107, + 58, 145, 17, 65, 79, 103, 220, 234, + 151, 242, 207, 206, 240, 180, 230, 115, + 150, 172, 116, 34, 231, 173, 53, 133, + 226, 249, 55, 232, 28, 117, 223, 110, + 71, 241, 26, 113, 29, 41, 197, 137, + 111, 183, 98, 14, 170, 24, 190, 27, + 252, 86, 62, 75, 198, 210, 121, 32, + 154, 219, 192, 254, 120, 205, 90, 244, + 31, 221, 168, 51, 136, 7, 199, 49, + 177, 18, 16, 89, 39, 128, 236, 95, + 96, 81, 127, 169, 25, 181, 74, 13, + 45, 229, 122, 159, 147, 201, 156, 239, + 160, 224, 59, 77, 174, 42, 245, 176, + 200, 235, 187, 60, 131, 83, 153, 97, + 23, 43, 4, 126, 186, 119, 214, 38, + 225, 105, 20, 99, 85, 33, 12, 125, + }; + + // vector used in calculating key schedule (powers of x in GF(256)) + private static readonly byte[] rcon = + { + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, + 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91 + }; + + // precomputation tables of calculations for rounds + private static readonly uint[] T0 = + { + 0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6, 0x0df2f2ff, + 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591, 0x50303060, 0x03010102, + 0xa96767ce, 0x7d2b2b56, 0x19fefee7, 0x62d7d7b5, 0xe6abab4d, + 0x9a7676ec, 0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa, + 0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb, 0xecadad41, + 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45, 0xbf9c9c23, 0xf7a4a453, + 0x967272e4, 0x5bc0c09b, 0xc2b7b775, 0x1cfdfde1, 0xae93933d, + 0x6a26264c, 0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83, + 0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x08f1f1f9, 0x937171e2, + 0x73d8d8ab, 0x53313162, 0x3f15152a, 0x0c040408, 0x52c7c795, + 0x65232346, 0x5ec3c39d, 0x28181830, 0xa1969637, 0x0f05050a, + 0xb59a9a2f, 0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df, + 0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea, 0x1b090912, + 0x9e83831d, 0x742c2c58, 0x2e1a1a34, 0x2d1b1b36, 0xb26e6edc, + 0xee5a5ab4, 0xfba0a05b, 0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, + 0xceb3b37d, 0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413, + 0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1, 0x60202040, + 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6, 0xbe6a6ad4, 0x46cbcb8d, + 0xd9bebe67, 0x4b393972, 0xde4a4a94, 0xd44c4c98, 0xe85858b0, + 0x4acfcf85, 0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed, + 0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511, 0xcf45458a, + 0x10f9f9e9, 0x06020204, 0x817f7ffe, 0xf05050a0, 0x443c3c78, + 0xba9f9f25, 0xe3a8a84b, 0xf35151a2, 0xfea3a35d, 0xc0404080, + 0x8a8f8f05, 0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1, + 0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142, 0x30101020, + 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf, 0x4ccdcd81, 0x140c0c18, + 0x35131326, 0x2fececc3, 0xe15f5fbe, 0xa2979735, 0xcc444488, + 0x3917172e, 0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a, + 0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6, 0xa06060c0, + 0x98818119, 0xd14f4f9e, 0x7fdcdca3, 0x66222244, 0x7e2a2a54, + 0xab90903b, 0x8388880b, 0xca46468c, 0x29eeeec7, 0xd3b8b86b, + 0x3c141428, 0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad, + 0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14, 0xdb494992, + 0x0a06060c, 0x6c242448, 0xe45c5cb8, 0x5dc2c29f, 0x6ed3d3bd, + 0xefacac43, 0xa66262c4, 0xa8919139, 0xa4959531, 0x37e4e4d3, + 0x8b7979f2, 0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda, + 0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949, 0xb46c6cd8, + 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf, 0xaf6565ca, 0x8e7a7af4, + 0xe9aeae47, 0x18080810, 0xd5baba6f, 0x887878f0, 0x6f25254a, + 0x722e2e5c, 0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697, + 0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e, 0xdd4b4b96, + 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f, 0x907070e0, 0x423e3e7c, + 0xc4b5b571, 0xaa6666cc, 0xd8484890, 0x05030306, 0x01f6f6f7, + 0x120e0e1c, 0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969, + 0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27, 0x38e1e1d9, + 0x13f8f8eb, 0xb398982b, 0x33111122, 0xbb6969d2, 0x70d9d9a9, + 0x898e8e07, 0xa7949433, 0xb69b9b2d, 0x221e1e3c, 0x92878715, + 0x20e9e9c9, 0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5, + 0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a, 0xdabfbf65, + 0x31e6e6d7, 0xc6424284, 0xb86868d0, 0xc3414182, 0xb0999929, + 0x772d2d5a, 0x110f0f1e, 0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, + 0x3a16162c + }; + + private static readonly uint[] Tinv0 = + { + 0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a, 0xcb6bab3b, + 0xf1459d1f, 0xab58faac, 0x9303e34b, 0x55fa3020, 0xf66d76ad, + 0x9176cc88, 0x254c02f5, 0xfcd7e54f, 0xd7cb2ac5, 0x80443526, + 0x8fa362b5, 0x495ab1de, 0x671bba25, 0x980eea45, 0xe1c0fe5d, + 0x02752fc3, 0x12f04c81, 0xa397468d, 0xc6f9d36b, 0xe75f8f03, + 0x959c9215, 0xeb7a6dbf, 0xda595295, 0x2d83bed4, 0xd3217458, + 0x2969e049, 0x44c8c98e, 0x6a89c275, 0x78798ef4, 0x6b3e5899, + 0xdd71b927, 0xb64fe1be, 0x17ad88f0, 0x66ac20c9, 0xb43ace7d, + 0x184adf63, 0x82311ae5, 0x60335197, 0x457f5362, 0xe07764b1, + 0x84ae6bbb, 0x1ca081fe, 0x942b08f9, 0x58684870, 0x19fd458f, + 0x876cde94, 0xb7f87b52, 0x23d373ab, 0xe2024b72, 0x578f1fe3, + 0x2aab5566, 0x0728ebb2, 0x03c2b52f, 0x9a7bc586, 0xa50837d3, + 0xf2872830, 0xb2a5bf23, 0xba6a0302, 0x5c8216ed, 0x2b1ccf8a, + 0x92b479a7, 0xf0f207f3, 0xa1e2694e, 0xcdf4da65, 0xd5be0506, + 0x1f6234d1, 0x8afea6c4, 0x9d532e34, 0xa055f3a2, 0x32e18a05, + 0x75ebf6a4, 0x39ec830b, 0xaaef6040, 0x069f715e, 0x51106ebd, + 0xf98a213e, 0x3d06dd96, 0xae053edd, 0x46bde64d, 0xb58d5491, + 0x055dc471, 0x6fd40604, 0xff155060, 0x24fb9819, 0x97e9bdd6, + 0xcc434089, 0x779ed967, 0xbd42e8b0, 0x888b8907, 0x385b19e7, + 0xdbeec879, 0x470a7ca1, 0xe90f427c, 0xc91e84f8, 0x00000000, + 0x83868009, 0x48ed2b32, 0xac70111e, 0x4e725a6c, 0xfbff0efd, + 0x5638850f, 0x1ed5ae3d, 0x27392d36, 0x64d90f0a, 0x21a65c68, + 0xd1545b9b, 0x3a2e3624, 0xb1670a0c, 0x0fe75793, 0xd296eeb4, + 0x9e919b1b, 0x4fc5c080, 0xa220dc61, 0x694b775a, 0x161a121c, + 0x0aba93e2, 0xe52aa0c0, 0x43e0223c, 0x1d171b12, 0x0b0d090e, + 0xadc78bf2, 0xb9a8b62d, 0xc8a91e14, 0x8519f157, 0x4c0775af, + 0xbbdd99ee, 0xfd607fa3, 0x9f2601f7, 0xbcf5725c, 0xc53b6644, + 0x347efb5b, 0x7629438b, 0xdcc623cb, 0x68fcedb6, 0x63f1e4b8, + 0xcadc31d7, 0x10856342, 0x40229713, 0x2011c684, 0x7d244a85, + 0xf83dbbd2, 0x1132f9ae, 0x6da129c7, 0x4b2f9e1d, 0xf330b2dc, + 0xec52860d, 0xd0e3c177, 0x6c16b32b, 0x99b970a9, 0xfa489411, + 0x2264e947, 0xc48cfca8, 0x1a3ff0a0, 0xd82c7d56, 0xef903322, + 0xc74e4987, 0xc1d138d9, 0xfea2ca8c, 0x360bd498, 0xcf81f5a6, + 0x28de7aa5, 0x268eb7da, 0xa4bfad3f, 0xe49d3a2c, 0x0d927850, + 0x9bcc5f6a, 0x62467e54, 0xc2138df6, 0xe8b8d890, 0x5ef7392e, + 0xf5afc382, 0xbe805d9f, 0x7c93d069, 0xa92dd56f, 0xb31225cf, + 0x3b99acc8, 0xa77d1810, 0x6e639ce8, 0x7bbb3bdb, 0x097826cd, + 0xf418596e, 0x01b79aec, 0xa89a4f83, 0x656e95e6, 0x7ee6ffaa, + 0x08cfbc21, 0xe6e815ef, 0xd99be7ba, 0xce366f4a, 0xd4099fea, + 0xd67cb029, 0xafb2a431, 0x31233f2a, 0x3094a5c6, 0xc066a235, + 0x37bc4e74, 0xa6ca82fc, 0xb0d090e0, 0x15d8a733, 0x4a9804f1, + 0xf7daec41, 0x0e50cd7f, 0x2ff69117, 0x8dd64d76, 0x4db0ef43, + 0x544daacc, 0xdf0496e4, 0xe3b5d19e, 0x1b886a4c, 0xb81f2cc1, + 0x7f516546, 0x04ea5e9d, 0x5d358c01, 0x737487fa, 0x2e410bfb, + 0x5a1d67b3, 0x52d2db92, 0x335610e9, 0x1347d66d, 0x8c61d79a, + 0x7a0ca137, 0x8e14f859, 0x893c13eb, 0xee27a9ce, 0x35c961b7, + 0xede51ce1, 0x3cb1477a, 0x59dfd29c, 0x3f73f255, 0x79ce1418, + 0xbf37c773, 0xeacdf753, 0x5baafd5f, 0x146f3ddf, 0x86db4478, + 0x81f3afca, 0x3ec468b9, 0x2c342438, 0x5f40a3c2, 0x72c31d16, + 0x0c25e2bc, 0x8b493c28, 0x41950dff, 0x7101a839, 0xdeb30c08, + 0x9ce4b4d8, 0x90c15664, 0x6184cb7b, 0x70b632d5, 0x745c6c48, + 0x4257b8d0 + }; + + private static uint Shift(uint r, int shift) + { + return (r >> shift) | (r << (32 - shift)); + } + + /* multiply four bytes in GF(2^8) by 'x' {02} in parallel */ + + private const uint m1 = 0x80808080; + private const uint m2 = 0x7f7f7f7f; + private const uint m3 = 0x0000001b; + private const uint m4 = 0xC0C0C0C0; + private const uint m5 = 0x3f3f3f3f; + + private static uint FFmulX(uint x) + { + return ((x & m2) << 1) ^ (((x & m1) >> 7) * m3); + } + + private static uint FFmulX2(uint x) + { + uint t0 = (x & m5) << 2; + uint t1 = (x & m4); + t1 ^= (t1 >> 1); + return t0 ^ (t1 >> 2) ^ (t1 >> 5); + } + + /* + The following defines provide alternative definitions of FFmulX that might + give improved performance if a fast 32-bit multiply is not available. + + private int FFmulX(int x) { int u = x & m1; u |= (u >> 1); return ((x & m2) << 1) ^ ((u >>> 3) | (u >>> 6)); } + private static final int m4 = 0x1b1b1b1b; + private int FFmulX(int x) { int u = x & m1; return ((x & m2) << 1) ^ ((u - (u >>> 7)) & m4); } + + */ + + private static uint Inv_Mcol(uint x) + { + uint t0, t1; + t0 = x; + t1 = t0 ^ Shift(t0, 8); + t0 ^= FFmulX(t1); + t1 ^= FFmulX2(t0); + t0 ^= t1 ^ Shift(t1, 16); + return t0; + } + + private static uint SubWord(uint x) + { + return (uint)S[x&255] + | (((uint)S[(x>>8)&255]) << 8) + | (((uint)S[(x>>16)&255]) << 16) + | (((uint)S[(x>>24)&255]) << 24); + } + + /** + * Calculate the necessary round keys + * The number of calculations depends on key size and block size + * AES specified a fixed block size of 128 bits and key sizes 128/192/256 bits + * This code is written assuming those are the only possible values + */ + private uint[][] GenerateWorkingKey(byte[] key, bool forEncryption) + { + int keyLen = key.Length; + if (keyLen < 16 || keyLen > 32 || (keyLen & 7) != 0) + throw new ArgumentException("Key length not 128/192/256 bits."); + + int KC = keyLen >> 2; + this.ROUNDS = KC + 6; // This is not always true for the generalized Rijndael that allows larger block sizes + + uint[][] W = new uint[ROUNDS + 1][]; // 4 words in a block + for (int i = 0; i <= ROUNDS; ++i) + { + W[i] = new uint[4]; + } + + switch (KC) + { + case 4: + { + uint t0 = Pack.LE_To_UInt32(key, 0); W[0][0] = t0; + uint t1 = Pack.LE_To_UInt32(key, 4); W[0][1] = t1; + uint t2 = Pack.LE_To_UInt32(key, 8); W[0][2] = t2; + uint t3 = Pack.LE_To_UInt32(key, 12); W[0][3] = t3; + + for (int i = 1; i <= 10; ++i) + { + uint u = SubWord(Shift(t3, 8)) ^ rcon[i - 1]; + t0 ^= u; W[i][0] = t0; + t1 ^= t0; W[i][1] = t1; + t2 ^= t1; W[i][2] = t2; + t3 ^= t2; W[i][3] = t3; + } + + break; + } + case 6: + { + uint t0 = Pack.LE_To_UInt32(key, 0); W[0][0] = t0; + uint t1 = Pack.LE_To_UInt32(key, 4); W[0][1] = t1; + uint t2 = Pack.LE_To_UInt32(key, 8); W[0][2] = t2; + uint t3 = Pack.LE_To_UInt32(key, 12); W[0][3] = t3; + uint t4 = Pack.LE_To_UInt32(key, 16); W[1][0] = t4; + uint t5 = Pack.LE_To_UInt32(key, 20); W[1][1] = t5; + + uint rcon = 1; + uint u = SubWord(Shift(t5, 8)) ^ rcon; rcon <<= 1; + t0 ^= u; W[1][2] = t0; + t1 ^= t0; W[1][3] = t1; + t2 ^= t1; W[2][0] = t2; + t3 ^= t2; W[2][1] = t3; + t4 ^= t3; W[2][2] = t4; + t5 ^= t4; W[2][3] = t5; + + for (int i = 3; i < 12; i += 3) + { + u = SubWord(Shift(t5, 8)) ^ rcon; rcon <<= 1; + t0 ^= u; W[i ][0] = t0; + t1 ^= t0; W[i ][1] = t1; + t2 ^= t1; W[i ][2] = t2; + t3 ^= t2; W[i ][3] = t3; + t4 ^= t3; W[i + 1][0] = t4; + t5 ^= t4; W[i + 1][1] = t5; + u = SubWord(Shift(t5, 8)) ^ rcon; rcon <<= 1; + t0 ^= u; W[i + 1][2] = t0; + t1 ^= t0; W[i + 1][3] = t1; + t2 ^= t1; W[i + 2][0] = t2; + t3 ^= t2; W[i + 2][1] = t3; + t4 ^= t3; W[i + 2][2] = t4; + t5 ^= t4; W[i + 2][3] = t5; + } + + u = SubWord(Shift(t5, 8)) ^ rcon; + t0 ^= u; W[12][0] = t0; + t1 ^= t0; W[12][1] = t1; + t2 ^= t1; W[12][2] = t2; + t3 ^= t2; W[12][3] = t3; + + break; + } + case 8: + { + uint t0 = Pack.LE_To_UInt32(key, 0); W[0][0] = t0; + uint t1 = Pack.LE_To_UInt32(key, 4); W[0][1] = t1; + uint t2 = Pack.LE_To_UInt32(key, 8); W[0][2] = t2; + uint t3 = Pack.LE_To_UInt32(key, 12); W[0][3] = t3; + uint t4 = Pack.LE_To_UInt32(key, 16); W[1][0] = t4; + uint t5 = Pack.LE_To_UInt32(key, 20); W[1][1] = t5; + uint t6 = Pack.LE_To_UInt32(key, 24); W[1][2] = t6; + uint t7 = Pack.LE_To_UInt32(key, 28); W[1][3] = t7; + + uint u, rcon = 1; + + for (int i = 2; i < 14; i += 2) + { + u = SubWord(Shift(t7, 8)) ^ rcon; rcon <<= 1; + t0 ^= u; W[i ][0] = t0; + t1 ^= t0; W[i ][1] = t1; + t2 ^= t1; W[i ][2] = t2; + t3 ^= t2; W[i ][3] = t3; + u = SubWord(t3); + t4 ^= u; W[i + 1][0] = t4; + t5 ^= t4; W[i + 1][1] = t5; + t6 ^= t5; W[i + 1][2] = t6; + t7 ^= t6; W[i + 1][3] = t7; + } + + u = SubWord(Shift(t7, 8)) ^ rcon; + t0 ^= u; W[14][0] = t0; + t1 ^= t0; W[14][1] = t1; + t2 ^= t1; W[14][2] = t2; + t3 ^= t2; W[14][3] = t3; + + break; + } + default: + { + throw new InvalidOperationException("Should never get here"); + } + } + + if (!forEncryption) + { + for (int j = 1; j < ROUNDS; j++) + { + uint[] w = W[j]; + for (int i = 0; i < 4; i++) + { + w[i] = Inv_Mcol(w[i]); + } + } + } + + return W; + } + + private int ROUNDS; + private uint[][] WorkingKey; + private bool forEncryption; + + private byte[] s; + + private const int BLOCK_SIZE = 16; + + /** + * default constructor - 128 bit block size. + */ + public AesEngine() + { + } + + /** + * initialise an AES cipher. + * + * @param forEncryption whether or not we are for encryption. + * @param parameters the parameters required to set up the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + KeyParameter keyParameter = parameters as KeyParameter; + + if (keyParameter == null) + throw new ArgumentException("invalid parameter passed to AES init - " + + Platform.GetTypeName(parameters)); + + WorkingKey = GenerateWorkingKey(keyParameter.GetKey(), forEncryption); + + this.forEncryption = forEncryption; + this.s = Arrays.Clone(forEncryption ? S : Si); + } + + public virtual string AlgorithmName + { + get { return "AES"; } + } + + public virtual bool IsPartialBlockOkay + { + get { return false; } + } + + public virtual int GetBlockSize() + { + return BLOCK_SIZE; + } + + public virtual int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff) + { + if (WorkingKey == null) + throw new InvalidOperationException("AES engine not initialised"); + + Check.DataLength(input, inOff, 16, "input buffer too short"); + Check.OutputLength(output, outOff, 16, "output buffer too short"); + + if (forEncryption) + { + EncryptBlock(input, inOff, output, outOff, WorkingKey); + } + else + { + DecryptBlock(input, inOff, output, outOff, WorkingKey); + } + + return BLOCK_SIZE; + } + + public virtual void Reset() + { + } + + private void EncryptBlock(byte[] input, int inOff, byte[] output, int outOff, uint[][] KW) + { + uint C0 = Pack.LE_To_UInt32(input, inOff + 0); + uint C1 = Pack.LE_To_UInt32(input, inOff + 4); + uint C2 = Pack.LE_To_UInt32(input, inOff + 8); + uint C3 = Pack.LE_To_UInt32(input, inOff + 12); + + uint[] kw = KW[0]; + uint t0 = C0 ^ kw[0]; + uint t1 = C1 ^ kw[1]; + uint t2 = C2 ^ kw[2]; + + uint r0, r1, r2, r3 = C3 ^ kw[3]; + int r = 1; + while (r < ROUNDS - 1) + { + kw = KW[r++]; + r0 = T0[t0 & 255] ^ Shift(T0[(t1 >> 8) & 255], 24) ^ Shift(T0[(t2 >> 16) & 255], 16) ^ Shift(T0[(r3 >> 24) & 255], 8) ^ kw[0]; + r1 = T0[t1 & 255] ^ Shift(T0[(t2 >> 8) & 255], 24) ^ Shift(T0[(r3 >> 16) & 255], 16) ^ Shift(T0[(t0 >> 24) & 255], 8) ^ kw[1]; + r2 = T0[t2 & 255] ^ Shift(T0[(r3 >> 8) & 255], 24) ^ Shift(T0[(t0 >> 16) & 255], 16) ^ Shift(T0[(t1 >> 24) & 255], 8) ^ kw[2]; + r3 = T0[r3 & 255] ^ Shift(T0[(t0 >> 8) & 255], 24) ^ Shift(T0[(t1 >> 16) & 255], 16) ^ Shift(T0[(t2 >> 24) & 255], 8) ^ kw[3]; + kw = KW[r++]; + t0 = T0[r0 & 255] ^ Shift(T0[(r1 >> 8) & 255], 24) ^ Shift(T0[(r2 >> 16) & 255], 16) ^ Shift(T0[(r3 >> 24) & 255], 8) ^ kw[0]; + t1 = T0[r1 & 255] ^ Shift(T0[(r2 >> 8) & 255], 24) ^ Shift(T0[(r3 >> 16) & 255], 16) ^ Shift(T0[(r0 >> 24) & 255], 8) ^ kw[1]; + t2 = T0[r2 & 255] ^ Shift(T0[(r3 >> 8) & 255], 24) ^ Shift(T0[(r0 >> 16) & 255], 16) ^ Shift(T0[(r1 >> 24) & 255], 8) ^ kw[2]; + r3 = T0[r3 & 255] ^ Shift(T0[(r0 >> 8) & 255], 24) ^ Shift(T0[(r1 >> 16) & 255], 16) ^ Shift(T0[(r2 >> 24) & 255], 8) ^ kw[3]; + } + + kw = KW[r++]; + r0 = T0[t0 & 255] ^ Shift(T0[(t1 >> 8) & 255], 24) ^ Shift(T0[(t2 >> 16) & 255], 16) ^ Shift(T0[(r3 >> 24) & 255], 8) ^ kw[0]; + r1 = T0[t1 & 255] ^ Shift(T0[(t2 >> 8) & 255], 24) ^ Shift(T0[(r3 >> 16) & 255], 16) ^ Shift(T0[(t0 >> 24) & 255], 8) ^ kw[1]; + r2 = T0[t2 & 255] ^ Shift(T0[(r3 >> 8) & 255], 24) ^ Shift(T0[(t0 >> 16) & 255], 16) ^ Shift(T0[(t1 >> 24) & 255], 8) ^ kw[2]; + r3 = T0[r3 & 255] ^ Shift(T0[(t0 >> 8) & 255], 24) ^ Shift(T0[(t1 >> 16) & 255], 16) ^ Shift(T0[(t2 >> 24) & 255], 8) ^ kw[3]; + + // the final round's table is a simple function of S so we don't use a whole other four tables for it + + kw = KW[r]; + C0 = (uint)S[r0 & 255] ^ (((uint)S[(r1 >> 8) & 255]) << 8) ^ (((uint)s[(r2 >> 16) & 255]) << 16) ^ (((uint)s[(r3 >> 24) & 255]) << 24) ^ kw[0]; + C1 = (uint)s[r1 & 255] ^ (((uint)S[(r2 >> 8) & 255]) << 8) ^ (((uint)S[(r3 >> 16) & 255]) << 16) ^ (((uint)s[(r0 >> 24) & 255]) << 24) ^ kw[1]; + C2 = (uint)s[r2 & 255] ^ (((uint)S[(r3 >> 8) & 255]) << 8) ^ (((uint)S[(r0 >> 16) & 255]) << 16) ^ (((uint)S[(r1 >> 24) & 255]) << 24) ^ kw[2]; + C3 = (uint)s[r3 & 255] ^ (((uint)s[(r0 >> 8) & 255]) << 8) ^ (((uint)s[(r1 >> 16) & 255]) << 16) ^ (((uint)S[(r2 >> 24) & 255]) << 24) ^ kw[3]; + + Pack.UInt32_To_LE(C0, output, outOff + 0); + Pack.UInt32_To_LE(C1, output, outOff + 4); + Pack.UInt32_To_LE(C2, output, outOff + 8); + Pack.UInt32_To_LE(C3, output, outOff + 12); + } + + private void DecryptBlock(byte[] input, int inOff, byte[] output, int outOff, uint[][] KW) + { + uint C0 = Pack.LE_To_UInt32(input, inOff + 0); + uint C1 = Pack.LE_To_UInt32(input, inOff + 4); + uint C2 = Pack.LE_To_UInt32(input, inOff + 8); + uint C3 = Pack.LE_To_UInt32(input, inOff + 12); + + uint[] kw = KW[ROUNDS]; + uint t0 = C0 ^ kw[0]; + uint t1 = C1 ^ kw[1]; + uint t2 = C2 ^ kw[2]; + + uint r0, r1, r2, r3 = C3 ^ kw[3]; + int r = ROUNDS - 1; + while (r > 1) + { + kw = KW[r--]; + r0 = Tinv0[t0 & 255] ^ Shift(Tinv0[(r3 >> 8) & 255], 24) ^ Shift(Tinv0[(t2 >> 16) & 255], 16) ^ Shift(Tinv0[(t1 >> 24) & 255], 8) ^ kw[0]; + r1 = Tinv0[t1 & 255] ^ Shift(Tinv0[(t0 >> 8) & 255], 24) ^ Shift(Tinv0[(r3 >> 16) & 255], 16) ^ Shift(Tinv0[(t2 >> 24) & 255], 8) ^ kw[1]; + r2 = Tinv0[t2 & 255] ^ Shift(Tinv0[(t1 >> 8) & 255], 24) ^ Shift(Tinv0[(t0 >> 16) & 255], 16) ^ Shift(Tinv0[(r3 >> 24) & 255], 8) ^ kw[2]; + r3 = Tinv0[r3 & 255] ^ Shift(Tinv0[(t2 >> 8) & 255], 24) ^ Shift(Tinv0[(t1 >> 16) & 255], 16) ^ Shift(Tinv0[(t0 >> 24) & 255], 8) ^ kw[3]; + kw = KW[r--]; + t0 = Tinv0[r0 & 255] ^ Shift(Tinv0[(r3 >> 8) & 255], 24) ^ Shift(Tinv0[(r2 >> 16) & 255], 16) ^ Shift(Tinv0[(r1 >> 24) & 255], 8) ^ kw[0]; + t1 = Tinv0[r1 & 255] ^ Shift(Tinv0[(r0 >> 8) & 255], 24) ^ Shift(Tinv0[(r3 >> 16) & 255], 16) ^ Shift(Tinv0[(r2 >> 24) & 255], 8) ^ kw[1]; + t2 = Tinv0[r2 & 255] ^ Shift(Tinv0[(r1 >> 8) & 255], 24) ^ Shift(Tinv0[(r0 >> 16) & 255], 16) ^ Shift(Tinv0[(r3 >> 24) & 255], 8) ^ kw[2]; + r3 = Tinv0[r3 & 255] ^ Shift(Tinv0[(r2 >> 8) & 255], 24) ^ Shift(Tinv0[(r1 >> 16) & 255], 16) ^ Shift(Tinv0[(r0 >> 24) & 255], 8) ^ kw[3]; + } + + kw = KW[1]; + r0 = Tinv0[t0 & 255] ^ Shift(Tinv0[(r3 >> 8) & 255], 24) ^ Shift(Tinv0[(t2 >> 16) & 255], 16) ^ Shift(Tinv0[(t1 >> 24) & 255], 8) ^ kw[0]; + r1 = Tinv0[t1 & 255] ^ Shift(Tinv0[(t0 >> 8) & 255], 24) ^ Shift(Tinv0[(r3 >> 16) & 255], 16) ^ Shift(Tinv0[(t2 >> 24) & 255], 8) ^ kw[1]; + r2 = Tinv0[t2 & 255] ^ Shift(Tinv0[(t1 >> 8) & 255], 24) ^ Shift(Tinv0[(t0 >> 16) & 255], 16) ^ Shift(Tinv0[(r3 >> 24) & 255], 8) ^ kw[2]; + r3 = Tinv0[r3 & 255] ^ Shift(Tinv0[(t2 >> 8) & 255], 24) ^ Shift(Tinv0[(t1 >> 16) & 255], 16) ^ Shift(Tinv0[(t0 >> 24) & 255], 8) ^ kw[3]; + + // the final round's table is a simple function of Si so we don't use a whole other four tables for it + + kw = KW[0]; + C0 = (uint)Si[r0 & 255] ^ (((uint)s[(r3 >> 8) & 255]) << 8) ^ (((uint)s[(r2 >> 16) & 255]) << 16) ^ (((uint)Si[(r1 >> 24) & 255]) << 24) ^ kw[0]; + C1 = (uint)s[r1 & 255] ^ (((uint)s[(r0 >> 8) & 255]) << 8) ^ (((uint)Si[(r3 >> 16) & 255]) << 16) ^ (((uint)s[(r2 >> 24) & 255]) << 24) ^ kw[1]; + C2 = (uint)s[r2 & 255] ^ (((uint)Si[(r1 >> 8) & 255]) << 8) ^ (((uint)Si[(r0 >> 16) & 255]) << 16) ^ (((uint)s[(r3 >> 24) & 255]) << 24) ^ kw[2]; + C3 = (uint)Si[r3 & 255] ^ (((uint)s[(r2 >> 8) & 255]) << 8) ^ (((uint)s[(r1 >> 16) & 255]) << 16) ^ (((uint)s[(r0 >> 24) & 255]) << 24) ^ kw[3]; + + Pack.UInt32_To_LE(C0, output, outOff + 0); + Pack.UInt32_To_LE(C1, output, outOff + 4); + Pack.UInt32_To_LE(C2, output, outOff + 8); + Pack.UInt32_To_LE(C3, output, outOff + 12); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/AesEngine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/AesEngine.cs.meta new file mode 100644 index 0000000..8288583 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/AesEngine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4de640522e7844e4ab32af32d23e323b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/AesFastEngine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/AesFastEngine.cs new file mode 100644 index 0000000..32e1795 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/AesFastEngine.cs @@ -0,0 +1,939 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * an implementation of the AES (Rijndael)), from FIPS-197. + *

+ * For further details see: http://csrc.nist.gov/encryption/aes/. + * + * This implementation is based on optimizations from Dr. Brian Gladman's paper and C code at + * http://fp.gladman.plus.com/cryptography_technology/rijndael/ + * + * There are three levels of tradeoff of speed vs memory + * Because java has no preprocessor), they are written as three separate classes from which to choose + * + * The fastest uses 8Kbytes of static tables to precompute round calculations), 4 256 word tables for encryption + * and 4 for decryption. + * + * The middle performance version uses only one 256 word table for each), for a total of 2Kbytes), + * adding 12 rotate operations per round to compute the values contained in the other tables from + * the contents of the first + * + * The slowest version uses no static tables at all and computes the values in each round + *

+ *

+ * This file contains the fast version with 8Kbytes of static tables for round precomputation + *

+ */ + /// + /// Unfortunately this class has a few side channel issues. + /// In an environment where encryption/decryption may be closely observed it should not be used. + /// + [Obsolete("Use AesEngine instead")] + public class AesFastEngine + : IBlockCipher + { + // The S box + private static readonly byte[] S = + { + 99, 124, 119, 123, 242, 107, 111, 197, + 48, 1, 103, 43, 254, 215, 171, 118, + 202, 130, 201, 125, 250, 89, 71, 240, + 173, 212, 162, 175, 156, 164, 114, 192, + 183, 253, 147, 38, 54, 63, 247, 204, + 52, 165, 229, 241, 113, 216, 49, 21, + 4, 199, 35, 195, 24, 150, 5, 154, + 7, 18, 128, 226, 235, 39, 178, 117, + 9, 131, 44, 26, 27, 110, 90, 160, + 82, 59, 214, 179, 41, 227, 47, 132, + 83, 209, 0, 237, 32, 252, 177, 91, + 106, 203, 190, 57, 74, 76, 88, 207, + 208, 239, 170, 251, 67, 77, 51, 133, + 69, 249, 2, 127, 80, 60, 159, 168, + 81, 163, 64, 143, 146, 157, 56, 245, + 188, 182, 218, 33, 16, 255, 243, 210, + 205, 12, 19, 236, 95, 151, 68, 23, + 196, 167, 126, 61, 100, 93, 25, 115, + 96, 129, 79, 220, 34, 42, 144, 136, + 70, 238, 184, 20, 222, 94, 11, 219, + 224, 50, 58, 10, 73, 6, 36, 92, + 194, 211, 172, 98, 145, 149, 228, 121, + 231, 200, 55, 109, 141, 213, 78, 169, + 108, 86, 244, 234, 101, 122, 174, 8, + 186, 120, 37, 46, 28, 166, 180, 198, + 232, 221, 116, 31, 75, 189, 139, 138, + 112, 62, 181, 102, 72, 3, 246, 14, + 97, 53, 87, 185, 134, 193, 29, 158, + 225, 248, 152, 17, 105, 217, 142, 148, + 155, 30, 135, 233, 206, 85, 40, 223, + 140, 161, 137, 13, 191, 230, 66, 104, + 65, 153, 45, 15, 176, 84, 187, 22, + }; + + // The inverse S-box + private static readonly byte[] Si = + { + 82, 9, 106, 213, 48, 54, 165, 56, + 191, 64, 163, 158, 129, 243, 215, 251, + 124, 227, 57, 130, 155, 47, 255, 135, + 52, 142, 67, 68, 196, 222, 233, 203, + 84, 123, 148, 50, 166, 194, 35, 61, + 238, 76, 149, 11, 66, 250, 195, 78, + 8, 46, 161, 102, 40, 217, 36, 178, + 118, 91, 162, 73, 109, 139, 209, 37, + 114, 248, 246, 100, 134, 104, 152, 22, + 212, 164, 92, 204, 93, 101, 182, 146, + 108, 112, 72, 80, 253, 237, 185, 218, + 94, 21, 70, 87, 167, 141, 157, 132, + 144, 216, 171, 0, 140, 188, 211, 10, + 247, 228, 88, 5, 184, 179, 69, 6, + 208, 44, 30, 143, 202, 63, 15, 2, + 193, 175, 189, 3, 1, 19, 138, 107, + 58, 145, 17, 65, 79, 103, 220, 234, + 151, 242, 207, 206, 240, 180, 230, 115, + 150, 172, 116, 34, 231, 173, 53, 133, + 226, 249, 55, 232, 28, 117, 223, 110, + 71, 241, 26, 113, 29, 41, 197, 137, + 111, 183, 98, 14, 170, 24, 190, 27, + 252, 86, 62, 75, 198, 210, 121, 32, + 154, 219, 192, 254, 120, 205, 90, 244, + 31, 221, 168, 51, 136, 7, 199, 49, + 177, 18, 16, 89, 39, 128, 236, 95, + 96, 81, 127, 169, 25, 181, 74, 13, + 45, 229, 122, 159, 147, 201, 156, 239, + 160, 224, 59, 77, 174, 42, 245, 176, + 200, 235, 187, 60, 131, 83, 153, 97, + 23, 43, 4, 126, 186, 119, 214, 38, + 225, 105, 20, 99, 85, 33, 12, 125, + }; + + // vector used in calculating key schedule (powers of x in GF(256)) + private static readonly byte[] rcon = + { + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, + 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91 + }; + + // precomputation tables of calculations for rounds + private static readonly uint[] T0 = + { + 0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6, 0x0df2f2ff, + 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591, 0x50303060, 0x03010102, + 0xa96767ce, 0x7d2b2b56, 0x19fefee7, 0x62d7d7b5, 0xe6abab4d, + 0x9a7676ec, 0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa, + 0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb, 0xecadad41, + 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45, 0xbf9c9c23, 0xf7a4a453, + 0x967272e4, 0x5bc0c09b, 0xc2b7b775, 0x1cfdfde1, 0xae93933d, + 0x6a26264c, 0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83, + 0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x08f1f1f9, 0x937171e2, + 0x73d8d8ab, 0x53313162, 0x3f15152a, 0x0c040408, 0x52c7c795, + 0x65232346, 0x5ec3c39d, 0x28181830, 0xa1969637, 0x0f05050a, + 0xb59a9a2f, 0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df, + 0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea, 0x1b090912, + 0x9e83831d, 0x742c2c58, 0x2e1a1a34, 0x2d1b1b36, 0xb26e6edc, + 0xee5a5ab4, 0xfba0a05b, 0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, + 0xceb3b37d, 0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413, + 0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1, 0x60202040, + 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6, 0xbe6a6ad4, 0x46cbcb8d, + 0xd9bebe67, 0x4b393972, 0xde4a4a94, 0xd44c4c98, 0xe85858b0, + 0x4acfcf85, 0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed, + 0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511, 0xcf45458a, + 0x10f9f9e9, 0x06020204, 0x817f7ffe, 0xf05050a0, 0x443c3c78, + 0xba9f9f25, 0xe3a8a84b, 0xf35151a2, 0xfea3a35d, 0xc0404080, + 0x8a8f8f05, 0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1, + 0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142, 0x30101020, + 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf, 0x4ccdcd81, 0x140c0c18, + 0x35131326, 0x2fececc3, 0xe15f5fbe, 0xa2979735, 0xcc444488, + 0x3917172e, 0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a, + 0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6, 0xa06060c0, + 0x98818119, 0xd14f4f9e, 0x7fdcdca3, 0x66222244, 0x7e2a2a54, + 0xab90903b, 0x8388880b, 0xca46468c, 0x29eeeec7, 0xd3b8b86b, + 0x3c141428, 0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad, + 0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14, 0xdb494992, + 0x0a06060c, 0x6c242448, 0xe45c5cb8, 0x5dc2c29f, 0x6ed3d3bd, + 0xefacac43, 0xa66262c4, 0xa8919139, 0xa4959531, 0x37e4e4d3, + 0x8b7979f2, 0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda, + 0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949, 0xb46c6cd8, + 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf, 0xaf6565ca, 0x8e7a7af4, + 0xe9aeae47, 0x18080810, 0xd5baba6f, 0x887878f0, 0x6f25254a, + 0x722e2e5c, 0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697, + 0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e, 0xdd4b4b96, + 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f, 0x907070e0, 0x423e3e7c, + 0xc4b5b571, 0xaa6666cc, 0xd8484890, 0x05030306, 0x01f6f6f7, + 0x120e0e1c, 0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969, + 0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27, 0x38e1e1d9, + 0x13f8f8eb, 0xb398982b, 0x33111122, 0xbb6969d2, 0x70d9d9a9, + 0x898e8e07, 0xa7949433, 0xb69b9b2d, 0x221e1e3c, 0x92878715, + 0x20e9e9c9, 0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5, + 0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a, 0xdabfbf65, + 0x31e6e6d7, 0xc6424284, 0xb86868d0, 0xc3414182, 0xb0999929, + 0x772d2d5a, 0x110f0f1e, 0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, + 0x3a16162c + }; + + private static readonly uint[] T1 = + { + 0x6363c6a5, 0x7c7cf884, 0x7777ee99, 0x7b7bf68d, 0xf2f2ff0d, + 0x6b6bd6bd, 0x6f6fdeb1, 0xc5c59154, 0x30306050, 0x01010203, + 0x6767cea9, 0x2b2b567d, 0xfefee719, 0xd7d7b562, 0xabab4de6, + 0x7676ec9a, 0xcaca8f45, 0x82821f9d, 0xc9c98940, 0x7d7dfa87, + 0xfafaef15, 0x5959b2eb, 0x47478ec9, 0xf0f0fb0b, 0xadad41ec, + 0xd4d4b367, 0xa2a25ffd, 0xafaf45ea, 0x9c9c23bf, 0xa4a453f7, + 0x7272e496, 0xc0c09b5b, 0xb7b775c2, 0xfdfde11c, 0x93933dae, + 0x26264c6a, 0x36366c5a, 0x3f3f7e41, 0xf7f7f502, 0xcccc834f, + 0x3434685c, 0xa5a551f4, 0xe5e5d134, 0xf1f1f908, 0x7171e293, + 0xd8d8ab73, 0x31316253, 0x15152a3f, 0x0404080c, 0xc7c79552, + 0x23234665, 0xc3c39d5e, 0x18183028, 0x969637a1, 0x05050a0f, + 0x9a9a2fb5, 0x07070e09, 0x12122436, 0x80801b9b, 0xe2e2df3d, + 0xebebcd26, 0x27274e69, 0xb2b27fcd, 0x7575ea9f, 0x0909121b, + 0x83831d9e, 0x2c2c5874, 0x1a1a342e, 0x1b1b362d, 0x6e6edcb2, + 0x5a5ab4ee, 0xa0a05bfb, 0x5252a4f6, 0x3b3b764d, 0xd6d6b761, + 0xb3b37dce, 0x2929527b, 0xe3e3dd3e, 0x2f2f5e71, 0x84841397, + 0x5353a6f5, 0xd1d1b968, 0x00000000, 0xededc12c, 0x20204060, + 0xfcfce31f, 0xb1b179c8, 0x5b5bb6ed, 0x6a6ad4be, 0xcbcb8d46, + 0xbebe67d9, 0x3939724b, 0x4a4a94de, 0x4c4c98d4, 0x5858b0e8, + 0xcfcf854a, 0xd0d0bb6b, 0xefefc52a, 0xaaaa4fe5, 0xfbfbed16, + 0x434386c5, 0x4d4d9ad7, 0x33336655, 0x85851194, 0x45458acf, + 0xf9f9e910, 0x02020406, 0x7f7ffe81, 0x5050a0f0, 0x3c3c7844, + 0x9f9f25ba, 0xa8a84be3, 0x5151a2f3, 0xa3a35dfe, 0x404080c0, + 0x8f8f058a, 0x92923fad, 0x9d9d21bc, 0x38387048, 0xf5f5f104, + 0xbcbc63df, 0xb6b677c1, 0xdadaaf75, 0x21214263, 0x10102030, + 0xffffe51a, 0xf3f3fd0e, 0xd2d2bf6d, 0xcdcd814c, 0x0c0c1814, + 0x13132635, 0xececc32f, 0x5f5fbee1, 0x979735a2, 0x444488cc, + 0x17172e39, 0xc4c49357, 0xa7a755f2, 0x7e7efc82, 0x3d3d7a47, + 0x6464c8ac, 0x5d5dbae7, 0x1919322b, 0x7373e695, 0x6060c0a0, + 0x81811998, 0x4f4f9ed1, 0xdcdca37f, 0x22224466, 0x2a2a547e, + 0x90903bab, 0x88880b83, 0x46468cca, 0xeeeec729, 0xb8b86bd3, + 0x1414283c, 0xdedea779, 0x5e5ebce2, 0x0b0b161d, 0xdbdbad76, + 0xe0e0db3b, 0x32326456, 0x3a3a744e, 0x0a0a141e, 0x494992db, + 0x06060c0a, 0x2424486c, 0x5c5cb8e4, 0xc2c29f5d, 0xd3d3bd6e, + 0xacac43ef, 0x6262c4a6, 0x919139a8, 0x959531a4, 0xe4e4d337, + 0x7979f28b, 0xe7e7d532, 0xc8c88b43, 0x37376e59, 0x6d6ddab7, + 0x8d8d018c, 0xd5d5b164, 0x4e4e9cd2, 0xa9a949e0, 0x6c6cd8b4, + 0x5656acfa, 0xf4f4f307, 0xeaeacf25, 0x6565caaf, 0x7a7af48e, + 0xaeae47e9, 0x08081018, 0xbaba6fd5, 0x7878f088, 0x25254a6f, + 0x2e2e5c72, 0x1c1c3824, 0xa6a657f1, 0xb4b473c7, 0xc6c69751, + 0xe8e8cb23, 0xdddda17c, 0x7474e89c, 0x1f1f3e21, 0x4b4b96dd, + 0xbdbd61dc, 0x8b8b0d86, 0x8a8a0f85, 0x7070e090, 0x3e3e7c42, + 0xb5b571c4, 0x6666ccaa, 0x484890d8, 0x03030605, 0xf6f6f701, + 0x0e0e1c12, 0x6161c2a3, 0x35356a5f, 0x5757aef9, 0xb9b969d0, + 0x86861791, 0xc1c19958, 0x1d1d3a27, 0x9e9e27b9, 0xe1e1d938, + 0xf8f8eb13, 0x98982bb3, 0x11112233, 0x6969d2bb, 0xd9d9a970, + 0x8e8e0789, 0x949433a7, 0x9b9b2db6, 0x1e1e3c22, 0x87871592, + 0xe9e9c920, 0xcece8749, 0x5555aaff, 0x28285078, 0xdfdfa57a, + 0x8c8c038f, 0xa1a159f8, 0x89890980, 0x0d0d1a17, 0xbfbf65da, + 0xe6e6d731, 0x424284c6, 0x6868d0b8, 0x414182c3, 0x999929b0, + 0x2d2d5a77, 0x0f0f1e11, 0xb0b07bcb, 0x5454a8fc, 0xbbbb6dd6, + 0x16162c3a + }; + + private static readonly uint[] T2 = + { + 0x63c6a563, 0x7cf8847c, 0x77ee9977, 0x7bf68d7b, 0xf2ff0df2, + 0x6bd6bd6b, 0x6fdeb16f, 0xc59154c5, 0x30605030, 0x01020301, + 0x67cea967, 0x2b567d2b, 0xfee719fe, 0xd7b562d7, 0xab4de6ab, + 0x76ec9a76, 0xca8f45ca, 0x821f9d82, 0xc98940c9, 0x7dfa877d, + 0xfaef15fa, 0x59b2eb59, 0x478ec947, 0xf0fb0bf0, 0xad41ecad, + 0xd4b367d4, 0xa25ffda2, 0xaf45eaaf, 0x9c23bf9c, 0xa453f7a4, + 0x72e49672, 0xc09b5bc0, 0xb775c2b7, 0xfde11cfd, 0x933dae93, + 0x264c6a26, 0x366c5a36, 0x3f7e413f, 0xf7f502f7, 0xcc834fcc, + 0x34685c34, 0xa551f4a5, 0xe5d134e5, 0xf1f908f1, 0x71e29371, + 0xd8ab73d8, 0x31625331, 0x152a3f15, 0x04080c04, 0xc79552c7, + 0x23466523, 0xc39d5ec3, 0x18302818, 0x9637a196, 0x050a0f05, + 0x9a2fb59a, 0x070e0907, 0x12243612, 0x801b9b80, 0xe2df3de2, + 0xebcd26eb, 0x274e6927, 0xb27fcdb2, 0x75ea9f75, 0x09121b09, + 0x831d9e83, 0x2c58742c, 0x1a342e1a, 0x1b362d1b, 0x6edcb26e, + 0x5ab4ee5a, 0xa05bfba0, 0x52a4f652, 0x3b764d3b, 0xd6b761d6, + 0xb37dceb3, 0x29527b29, 0xe3dd3ee3, 0x2f5e712f, 0x84139784, + 0x53a6f553, 0xd1b968d1, 0x00000000, 0xedc12ced, 0x20406020, + 0xfce31ffc, 0xb179c8b1, 0x5bb6ed5b, 0x6ad4be6a, 0xcb8d46cb, + 0xbe67d9be, 0x39724b39, 0x4a94de4a, 0x4c98d44c, 0x58b0e858, + 0xcf854acf, 0xd0bb6bd0, 0xefc52aef, 0xaa4fe5aa, 0xfbed16fb, + 0x4386c543, 0x4d9ad74d, 0x33665533, 0x85119485, 0x458acf45, + 0xf9e910f9, 0x02040602, 0x7ffe817f, 0x50a0f050, 0x3c78443c, + 0x9f25ba9f, 0xa84be3a8, 0x51a2f351, 0xa35dfea3, 0x4080c040, + 0x8f058a8f, 0x923fad92, 0x9d21bc9d, 0x38704838, 0xf5f104f5, + 0xbc63dfbc, 0xb677c1b6, 0xdaaf75da, 0x21426321, 0x10203010, + 0xffe51aff, 0xf3fd0ef3, 0xd2bf6dd2, 0xcd814ccd, 0x0c18140c, + 0x13263513, 0xecc32fec, 0x5fbee15f, 0x9735a297, 0x4488cc44, + 0x172e3917, 0xc49357c4, 0xa755f2a7, 0x7efc827e, 0x3d7a473d, + 0x64c8ac64, 0x5dbae75d, 0x19322b19, 0x73e69573, 0x60c0a060, + 0x81199881, 0x4f9ed14f, 0xdca37fdc, 0x22446622, 0x2a547e2a, + 0x903bab90, 0x880b8388, 0x468cca46, 0xeec729ee, 0xb86bd3b8, + 0x14283c14, 0xdea779de, 0x5ebce25e, 0x0b161d0b, 0xdbad76db, + 0xe0db3be0, 0x32645632, 0x3a744e3a, 0x0a141e0a, 0x4992db49, + 0x060c0a06, 0x24486c24, 0x5cb8e45c, 0xc29f5dc2, 0xd3bd6ed3, + 0xac43efac, 0x62c4a662, 0x9139a891, 0x9531a495, 0xe4d337e4, + 0x79f28b79, 0xe7d532e7, 0xc88b43c8, 0x376e5937, 0x6ddab76d, + 0x8d018c8d, 0xd5b164d5, 0x4e9cd24e, 0xa949e0a9, 0x6cd8b46c, + 0x56acfa56, 0xf4f307f4, 0xeacf25ea, 0x65caaf65, 0x7af48e7a, + 0xae47e9ae, 0x08101808, 0xba6fd5ba, 0x78f08878, 0x254a6f25, + 0x2e5c722e, 0x1c38241c, 0xa657f1a6, 0xb473c7b4, 0xc69751c6, + 0xe8cb23e8, 0xdda17cdd, 0x74e89c74, 0x1f3e211f, 0x4b96dd4b, + 0xbd61dcbd, 0x8b0d868b, 0x8a0f858a, 0x70e09070, 0x3e7c423e, + 0xb571c4b5, 0x66ccaa66, 0x4890d848, 0x03060503, 0xf6f701f6, + 0x0e1c120e, 0x61c2a361, 0x356a5f35, 0x57aef957, 0xb969d0b9, + 0x86179186, 0xc19958c1, 0x1d3a271d, 0x9e27b99e, 0xe1d938e1, + 0xf8eb13f8, 0x982bb398, 0x11223311, 0x69d2bb69, 0xd9a970d9, + 0x8e07898e, 0x9433a794, 0x9b2db69b, 0x1e3c221e, 0x87159287, + 0xe9c920e9, 0xce8749ce, 0x55aaff55, 0x28507828, 0xdfa57adf, + 0x8c038f8c, 0xa159f8a1, 0x89098089, 0x0d1a170d, 0xbf65dabf, + 0xe6d731e6, 0x4284c642, 0x68d0b868, 0x4182c341, 0x9929b099, + 0x2d5a772d, 0x0f1e110f, 0xb07bcbb0, 0x54a8fc54, 0xbb6dd6bb, + 0x162c3a16 + }; + + private static readonly uint[] T3 = + { + 0xc6a56363, 0xf8847c7c, 0xee997777, 0xf68d7b7b, 0xff0df2f2, + 0xd6bd6b6b, 0xdeb16f6f, 0x9154c5c5, 0x60503030, 0x02030101, + 0xcea96767, 0x567d2b2b, 0xe719fefe, 0xb562d7d7, 0x4de6abab, + 0xec9a7676, 0x8f45caca, 0x1f9d8282, 0x8940c9c9, 0xfa877d7d, + 0xef15fafa, 0xb2eb5959, 0x8ec94747, 0xfb0bf0f0, 0x41ecadad, + 0xb367d4d4, 0x5ffda2a2, 0x45eaafaf, 0x23bf9c9c, 0x53f7a4a4, + 0xe4967272, 0x9b5bc0c0, 0x75c2b7b7, 0xe11cfdfd, 0x3dae9393, + 0x4c6a2626, 0x6c5a3636, 0x7e413f3f, 0xf502f7f7, 0x834fcccc, + 0x685c3434, 0x51f4a5a5, 0xd134e5e5, 0xf908f1f1, 0xe2937171, + 0xab73d8d8, 0x62533131, 0x2a3f1515, 0x080c0404, 0x9552c7c7, + 0x46652323, 0x9d5ec3c3, 0x30281818, 0x37a19696, 0x0a0f0505, + 0x2fb59a9a, 0x0e090707, 0x24361212, 0x1b9b8080, 0xdf3de2e2, + 0xcd26ebeb, 0x4e692727, 0x7fcdb2b2, 0xea9f7575, 0x121b0909, + 0x1d9e8383, 0x58742c2c, 0x342e1a1a, 0x362d1b1b, 0xdcb26e6e, + 0xb4ee5a5a, 0x5bfba0a0, 0xa4f65252, 0x764d3b3b, 0xb761d6d6, + 0x7dceb3b3, 0x527b2929, 0xdd3ee3e3, 0x5e712f2f, 0x13978484, + 0xa6f55353, 0xb968d1d1, 0x00000000, 0xc12ceded, 0x40602020, + 0xe31ffcfc, 0x79c8b1b1, 0xb6ed5b5b, 0xd4be6a6a, 0x8d46cbcb, + 0x67d9bebe, 0x724b3939, 0x94de4a4a, 0x98d44c4c, 0xb0e85858, + 0x854acfcf, 0xbb6bd0d0, 0xc52aefef, 0x4fe5aaaa, 0xed16fbfb, + 0x86c54343, 0x9ad74d4d, 0x66553333, 0x11948585, 0x8acf4545, + 0xe910f9f9, 0x04060202, 0xfe817f7f, 0xa0f05050, 0x78443c3c, + 0x25ba9f9f, 0x4be3a8a8, 0xa2f35151, 0x5dfea3a3, 0x80c04040, + 0x058a8f8f, 0x3fad9292, 0x21bc9d9d, 0x70483838, 0xf104f5f5, + 0x63dfbcbc, 0x77c1b6b6, 0xaf75dada, 0x42632121, 0x20301010, + 0xe51affff, 0xfd0ef3f3, 0xbf6dd2d2, 0x814ccdcd, 0x18140c0c, + 0x26351313, 0xc32fecec, 0xbee15f5f, 0x35a29797, 0x88cc4444, + 0x2e391717, 0x9357c4c4, 0x55f2a7a7, 0xfc827e7e, 0x7a473d3d, + 0xc8ac6464, 0xbae75d5d, 0x322b1919, 0xe6957373, 0xc0a06060, + 0x19988181, 0x9ed14f4f, 0xa37fdcdc, 0x44662222, 0x547e2a2a, + 0x3bab9090, 0x0b838888, 0x8cca4646, 0xc729eeee, 0x6bd3b8b8, + 0x283c1414, 0xa779dede, 0xbce25e5e, 0x161d0b0b, 0xad76dbdb, + 0xdb3be0e0, 0x64563232, 0x744e3a3a, 0x141e0a0a, 0x92db4949, + 0x0c0a0606, 0x486c2424, 0xb8e45c5c, 0x9f5dc2c2, 0xbd6ed3d3, + 0x43efacac, 0xc4a66262, 0x39a89191, 0x31a49595, 0xd337e4e4, + 0xf28b7979, 0xd532e7e7, 0x8b43c8c8, 0x6e593737, 0xdab76d6d, + 0x018c8d8d, 0xb164d5d5, 0x9cd24e4e, 0x49e0a9a9, 0xd8b46c6c, + 0xacfa5656, 0xf307f4f4, 0xcf25eaea, 0xcaaf6565, 0xf48e7a7a, + 0x47e9aeae, 0x10180808, 0x6fd5baba, 0xf0887878, 0x4a6f2525, + 0x5c722e2e, 0x38241c1c, 0x57f1a6a6, 0x73c7b4b4, 0x9751c6c6, + 0xcb23e8e8, 0xa17cdddd, 0xe89c7474, 0x3e211f1f, 0x96dd4b4b, + 0x61dcbdbd, 0x0d868b8b, 0x0f858a8a, 0xe0907070, 0x7c423e3e, + 0x71c4b5b5, 0xccaa6666, 0x90d84848, 0x06050303, 0xf701f6f6, + 0x1c120e0e, 0xc2a36161, 0x6a5f3535, 0xaef95757, 0x69d0b9b9, + 0x17918686, 0x9958c1c1, 0x3a271d1d, 0x27b99e9e, 0xd938e1e1, + 0xeb13f8f8, 0x2bb39898, 0x22331111, 0xd2bb6969, 0xa970d9d9, + 0x07898e8e, 0x33a79494, 0x2db69b9b, 0x3c221e1e, 0x15928787, + 0xc920e9e9, 0x8749cece, 0xaaff5555, 0x50782828, 0xa57adfdf, + 0x038f8c8c, 0x59f8a1a1, 0x09808989, 0x1a170d0d, 0x65dabfbf, + 0xd731e6e6, 0x84c64242, 0xd0b86868, 0x82c34141, 0x29b09999, + 0x5a772d2d, 0x1e110f0f, 0x7bcbb0b0, 0xa8fc5454, 0x6dd6bbbb, + 0x2c3a1616 + }; + + private static readonly uint[] Tinv0 = + { + 0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a, 0xcb6bab3b, + 0xf1459d1f, 0xab58faac, 0x9303e34b, 0x55fa3020, 0xf66d76ad, + 0x9176cc88, 0x254c02f5, 0xfcd7e54f, 0xd7cb2ac5, 0x80443526, + 0x8fa362b5, 0x495ab1de, 0x671bba25, 0x980eea45, 0xe1c0fe5d, + 0x02752fc3, 0x12f04c81, 0xa397468d, 0xc6f9d36b, 0xe75f8f03, + 0x959c9215, 0xeb7a6dbf, 0xda595295, 0x2d83bed4, 0xd3217458, + 0x2969e049, 0x44c8c98e, 0x6a89c275, 0x78798ef4, 0x6b3e5899, + 0xdd71b927, 0xb64fe1be, 0x17ad88f0, 0x66ac20c9, 0xb43ace7d, + 0x184adf63, 0x82311ae5, 0x60335197, 0x457f5362, 0xe07764b1, + 0x84ae6bbb, 0x1ca081fe, 0x942b08f9, 0x58684870, 0x19fd458f, + 0x876cde94, 0xb7f87b52, 0x23d373ab, 0xe2024b72, 0x578f1fe3, + 0x2aab5566, 0x0728ebb2, 0x03c2b52f, 0x9a7bc586, 0xa50837d3, + 0xf2872830, 0xb2a5bf23, 0xba6a0302, 0x5c8216ed, 0x2b1ccf8a, + 0x92b479a7, 0xf0f207f3, 0xa1e2694e, 0xcdf4da65, 0xd5be0506, + 0x1f6234d1, 0x8afea6c4, 0x9d532e34, 0xa055f3a2, 0x32e18a05, + 0x75ebf6a4, 0x39ec830b, 0xaaef6040, 0x069f715e, 0x51106ebd, + 0xf98a213e, 0x3d06dd96, 0xae053edd, 0x46bde64d, 0xb58d5491, + 0x055dc471, 0x6fd40604, 0xff155060, 0x24fb9819, 0x97e9bdd6, + 0xcc434089, 0x779ed967, 0xbd42e8b0, 0x888b8907, 0x385b19e7, + 0xdbeec879, 0x470a7ca1, 0xe90f427c, 0xc91e84f8, 0x00000000, + 0x83868009, 0x48ed2b32, 0xac70111e, 0x4e725a6c, 0xfbff0efd, + 0x5638850f, 0x1ed5ae3d, 0x27392d36, 0x64d90f0a, 0x21a65c68, + 0xd1545b9b, 0x3a2e3624, 0xb1670a0c, 0x0fe75793, 0xd296eeb4, + 0x9e919b1b, 0x4fc5c080, 0xa220dc61, 0x694b775a, 0x161a121c, + 0x0aba93e2, 0xe52aa0c0, 0x43e0223c, 0x1d171b12, 0x0b0d090e, + 0xadc78bf2, 0xb9a8b62d, 0xc8a91e14, 0x8519f157, 0x4c0775af, + 0xbbdd99ee, 0xfd607fa3, 0x9f2601f7, 0xbcf5725c, 0xc53b6644, + 0x347efb5b, 0x7629438b, 0xdcc623cb, 0x68fcedb6, 0x63f1e4b8, + 0xcadc31d7, 0x10856342, 0x40229713, 0x2011c684, 0x7d244a85, + 0xf83dbbd2, 0x1132f9ae, 0x6da129c7, 0x4b2f9e1d, 0xf330b2dc, + 0xec52860d, 0xd0e3c177, 0x6c16b32b, 0x99b970a9, 0xfa489411, + 0x2264e947, 0xc48cfca8, 0x1a3ff0a0, 0xd82c7d56, 0xef903322, + 0xc74e4987, 0xc1d138d9, 0xfea2ca8c, 0x360bd498, 0xcf81f5a6, + 0x28de7aa5, 0x268eb7da, 0xa4bfad3f, 0xe49d3a2c, 0x0d927850, + 0x9bcc5f6a, 0x62467e54, 0xc2138df6, 0xe8b8d890, 0x5ef7392e, + 0xf5afc382, 0xbe805d9f, 0x7c93d069, 0xa92dd56f, 0xb31225cf, + 0x3b99acc8, 0xa77d1810, 0x6e639ce8, 0x7bbb3bdb, 0x097826cd, + 0xf418596e, 0x01b79aec, 0xa89a4f83, 0x656e95e6, 0x7ee6ffaa, + 0x08cfbc21, 0xe6e815ef, 0xd99be7ba, 0xce366f4a, 0xd4099fea, + 0xd67cb029, 0xafb2a431, 0x31233f2a, 0x3094a5c6, 0xc066a235, + 0x37bc4e74, 0xa6ca82fc, 0xb0d090e0, 0x15d8a733, 0x4a9804f1, + 0xf7daec41, 0x0e50cd7f, 0x2ff69117, 0x8dd64d76, 0x4db0ef43, + 0x544daacc, 0xdf0496e4, 0xe3b5d19e, 0x1b886a4c, 0xb81f2cc1, + 0x7f516546, 0x04ea5e9d, 0x5d358c01, 0x737487fa, 0x2e410bfb, + 0x5a1d67b3, 0x52d2db92, 0x335610e9, 0x1347d66d, 0x8c61d79a, + 0x7a0ca137, 0x8e14f859, 0x893c13eb, 0xee27a9ce, 0x35c961b7, + 0xede51ce1, 0x3cb1477a, 0x59dfd29c, 0x3f73f255, 0x79ce1418, + 0xbf37c773, 0xeacdf753, 0x5baafd5f, 0x146f3ddf, 0x86db4478, + 0x81f3afca, 0x3ec468b9, 0x2c342438, 0x5f40a3c2, 0x72c31d16, + 0x0c25e2bc, 0x8b493c28, 0x41950dff, 0x7101a839, 0xdeb30c08, + 0x9ce4b4d8, 0x90c15664, 0x6184cb7b, 0x70b632d5, 0x745c6c48, + 0x4257b8d0 + }; + + private static readonly uint[] Tinv1 = + { + 0xa7f45150, 0x65417e53, 0xa4171ac3, 0x5e273a96, 0x6bab3bcb, + 0x459d1ff1, 0x58faacab, 0x03e34b93, 0xfa302055, 0x6d76adf6, + 0x76cc8891, 0x4c02f525, 0xd7e54ffc, 0xcb2ac5d7, 0x44352680, + 0xa362b58f, 0x5ab1de49, 0x1bba2567, 0x0eea4598, 0xc0fe5de1, + 0x752fc302, 0xf04c8112, 0x97468da3, 0xf9d36bc6, 0x5f8f03e7, + 0x9c921595, 0x7a6dbfeb, 0x595295da, 0x83bed42d, 0x217458d3, + 0x69e04929, 0xc8c98e44, 0x89c2756a, 0x798ef478, 0x3e58996b, + 0x71b927dd, 0x4fe1beb6, 0xad88f017, 0xac20c966, 0x3ace7db4, + 0x4adf6318, 0x311ae582, 0x33519760, 0x7f536245, 0x7764b1e0, + 0xae6bbb84, 0xa081fe1c, 0x2b08f994, 0x68487058, 0xfd458f19, + 0x6cde9487, 0xf87b52b7, 0xd373ab23, 0x024b72e2, 0x8f1fe357, + 0xab55662a, 0x28ebb207, 0xc2b52f03, 0x7bc5869a, 0x0837d3a5, + 0x872830f2, 0xa5bf23b2, 0x6a0302ba, 0x8216ed5c, 0x1ccf8a2b, + 0xb479a792, 0xf207f3f0, 0xe2694ea1, 0xf4da65cd, 0xbe0506d5, + 0x6234d11f, 0xfea6c48a, 0x532e349d, 0x55f3a2a0, 0xe18a0532, + 0xebf6a475, 0xec830b39, 0xef6040aa, 0x9f715e06, 0x106ebd51, + 0x8a213ef9, 0x06dd963d, 0x053eddae, 0xbde64d46, 0x8d5491b5, + 0x5dc47105, 0xd406046f, 0x155060ff, 0xfb981924, 0xe9bdd697, + 0x434089cc, 0x9ed96777, 0x42e8b0bd, 0x8b890788, 0x5b19e738, + 0xeec879db, 0x0a7ca147, 0x0f427ce9, 0x1e84f8c9, 0x00000000, + 0x86800983, 0xed2b3248, 0x70111eac, 0x725a6c4e, 0xff0efdfb, + 0x38850f56, 0xd5ae3d1e, 0x392d3627, 0xd90f0a64, 0xa65c6821, + 0x545b9bd1, 0x2e36243a, 0x670a0cb1, 0xe757930f, 0x96eeb4d2, + 0x919b1b9e, 0xc5c0804f, 0x20dc61a2, 0x4b775a69, 0x1a121c16, + 0xba93e20a, 0x2aa0c0e5, 0xe0223c43, 0x171b121d, 0x0d090e0b, + 0xc78bf2ad, 0xa8b62db9, 0xa91e14c8, 0x19f15785, 0x0775af4c, + 0xdd99eebb, 0x607fa3fd, 0x2601f79f, 0xf5725cbc, 0x3b6644c5, + 0x7efb5b34, 0x29438b76, 0xc623cbdc, 0xfcedb668, 0xf1e4b863, + 0xdc31d7ca, 0x85634210, 0x22971340, 0x11c68420, 0x244a857d, + 0x3dbbd2f8, 0x32f9ae11, 0xa129c76d, 0x2f9e1d4b, 0x30b2dcf3, + 0x52860dec, 0xe3c177d0, 0x16b32b6c, 0xb970a999, 0x489411fa, + 0x64e94722, 0x8cfca8c4, 0x3ff0a01a, 0x2c7d56d8, 0x903322ef, + 0x4e4987c7, 0xd138d9c1, 0xa2ca8cfe, 0x0bd49836, 0x81f5a6cf, + 0xde7aa528, 0x8eb7da26, 0xbfad3fa4, 0x9d3a2ce4, 0x9278500d, + 0xcc5f6a9b, 0x467e5462, 0x138df6c2, 0xb8d890e8, 0xf7392e5e, + 0xafc382f5, 0x805d9fbe, 0x93d0697c, 0x2dd56fa9, 0x1225cfb3, + 0x99acc83b, 0x7d1810a7, 0x639ce86e, 0xbb3bdb7b, 0x7826cd09, + 0x18596ef4, 0xb79aec01, 0x9a4f83a8, 0x6e95e665, 0xe6ffaa7e, + 0xcfbc2108, 0xe815efe6, 0x9be7bad9, 0x366f4ace, 0x099fead4, + 0x7cb029d6, 0xb2a431af, 0x233f2a31, 0x94a5c630, 0x66a235c0, + 0xbc4e7437, 0xca82fca6, 0xd090e0b0, 0xd8a73315, 0x9804f14a, + 0xdaec41f7, 0x50cd7f0e, 0xf691172f, 0xd64d768d, 0xb0ef434d, + 0x4daacc54, 0x0496e4df, 0xb5d19ee3, 0x886a4c1b, 0x1f2cc1b8, + 0x5165467f, 0xea5e9d04, 0x358c015d, 0x7487fa73, 0x410bfb2e, + 0x1d67b35a, 0xd2db9252, 0x5610e933, 0x47d66d13, 0x61d79a8c, + 0x0ca1377a, 0x14f8598e, 0x3c13eb89, 0x27a9ceee, 0xc961b735, + 0xe51ce1ed, 0xb1477a3c, 0xdfd29c59, 0x73f2553f, 0xce141879, + 0x37c773bf, 0xcdf753ea, 0xaafd5f5b, 0x6f3ddf14, 0xdb447886, + 0xf3afca81, 0xc468b93e, 0x3424382c, 0x40a3c25f, 0xc31d1672, + 0x25e2bc0c, 0x493c288b, 0x950dff41, 0x01a83971, 0xb30c08de, + 0xe4b4d89c, 0xc1566490, 0x84cb7b61, 0xb632d570, 0x5c6c4874, + 0x57b8d042 + }; + + private static readonly uint[] Tinv2 = + { + 0xf45150a7, 0x417e5365, 0x171ac3a4, 0x273a965e, 0xab3bcb6b, + 0x9d1ff145, 0xfaacab58, 0xe34b9303, 0x302055fa, 0x76adf66d, + 0xcc889176, 0x02f5254c, 0xe54ffcd7, 0x2ac5d7cb, 0x35268044, + 0x62b58fa3, 0xb1de495a, 0xba25671b, 0xea45980e, 0xfe5de1c0, + 0x2fc30275, 0x4c8112f0, 0x468da397, 0xd36bc6f9, 0x8f03e75f, + 0x9215959c, 0x6dbfeb7a, 0x5295da59, 0xbed42d83, 0x7458d321, + 0xe0492969, 0xc98e44c8, 0xc2756a89, 0x8ef47879, 0x58996b3e, + 0xb927dd71, 0xe1beb64f, 0x88f017ad, 0x20c966ac, 0xce7db43a, + 0xdf63184a, 0x1ae58231, 0x51976033, 0x5362457f, 0x64b1e077, + 0x6bbb84ae, 0x81fe1ca0, 0x08f9942b, 0x48705868, 0x458f19fd, + 0xde94876c, 0x7b52b7f8, 0x73ab23d3, 0x4b72e202, 0x1fe3578f, + 0x55662aab, 0xebb20728, 0xb52f03c2, 0xc5869a7b, 0x37d3a508, + 0x2830f287, 0xbf23b2a5, 0x0302ba6a, 0x16ed5c82, 0xcf8a2b1c, + 0x79a792b4, 0x07f3f0f2, 0x694ea1e2, 0xda65cdf4, 0x0506d5be, + 0x34d11f62, 0xa6c48afe, 0x2e349d53, 0xf3a2a055, 0x8a0532e1, + 0xf6a475eb, 0x830b39ec, 0x6040aaef, 0x715e069f, 0x6ebd5110, + 0x213ef98a, 0xdd963d06, 0x3eddae05, 0xe64d46bd, 0x5491b58d, + 0xc471055d, 0x06046fd4, 0x5060ff15, 0x981924fb, 0xbdd697e9, + 0x4089cc43, 0xd967779e, 0xe8b0bd42, 0x8907888b, 0x19e7385b, + 0xc879dbee, 0x7ca1470a, 0x427ce90f, 0x84f8c91e, 0x00000000, + 0x80098386, 0x2b3248ed, 0x111eac70, 0x5a6c4e72, 0x0efdfbff, + 0x850f5638, 0xae3d1ed5, 0x2d362739, 0x0f0a64d9, 0x5c6821a6, + 0x5b9bd154, 0x36243a2e, 0x0a0cb167, 0x57930fe7, 0xeeb4d296, + 0x9b1b9e91, 0xc0804fc5, 0xdc61a220, 0x775a694b, 0x121c161a, + 0x93e20aba, 0xa0c0e52a, 0x223c43e0, 0x1b121d17, 0x090e0b0d, + 0x8bf2adc7, 0xb62db9a8, 0x1e14c8a9, 0xf1578519, 0x75af4c07, + 0x99eebbdd, 0x7fa3fd60, 0x01f79f26, 0x725cbcf5, 0x6644c53b, + 0xfb5b347e, 0x438b7629, 0x23cbdcc6, 0xedb668fc, 0xe4b863f1, + 0x31d7cadc, 0x63421085, 0x97134022, 0xc6842011, 0x4a857d24, + 0xbbd2f83d, 0xf9ae1132, 0x29c76da1, 0x9e1d4b2f, 0xb2dcf330, + 0x860dec52, 0xc177d0e3, 0xb32b6c16, 0x70a999b9, 0x9411fa48, + 0xe9472264, 0xfca8c48c, 0xf0a01a3f, 0x7d56d82c, 0x3322ef90, + 0x4987c74e, 0x38d9c1d1, 0xca8cfea2, 0xd498360b, 0xf5a6cf81, + 0x7aa528de, 0xb7da268e, 0xad3fa4bf, 0x3a2ce49d, 0x78500d92, + 0x5f6a9bcc, 0x7e546246, 0x8df6c213, 0xd890e8b8, 0x392e5ef7, + 0xc382f5af, 0x5d9fbe80, 0xd0697c93, 0xd56fa92d, 0x25cfb312, + 0xacc83b99, 0x1810a77d, 0x9ce86e63, 0x3bdb7bbb, 0x26cd0978, + 0x596ef418, 0x9aec01b7, 0x4f83a89a, 0x95e6656e, 0xffaa7ee6, + 0xbc2108cf, 0x15efe6e8, 0xe7bad99b, 0x6f4ace36, 0x9fead409, + 0xb029d67c, 0xa431afb2, 0x3f2a3123, 0xa5c63094, 0xa235c066, + 0x4e7437bc, 0x82fca6ca, 0x90e0b0d0, 0xa73315d8, 0x04f14a98, + 0xec41f7da, 0xcd7f0e50, 0x91172ff6, 0x4d768dd6, 0xef434db0, + 0xaacc544d, 0x96e4df04, 0xd19ee3b5, 0x6a4c1b88, 0x2cc1b81f, + 0x65467f51, 0x5e9d04ea, 0x8c015d35, 0x87fa7374, 0x0bfb2e41, + 0x67b35a1d, 0xdb9252d2, 0x10e93356, 0xd66d1347, 0xd79a8c61, + 0xa1377a0c, 0xf8598e14, 0x13eb893c, 0xa9ceee27, 0x61b735c9, + 0x1ce1ede5, 0x477a3cb1, 0xd29c59df, 0xf2553f73, 0x141879ce, + 0xc773bf37, 0xf753eacd, 0xfd5f5baa, 0x3ddf146f, 0x447886db, + 0xafca81f3, 0x68b93ec4, 0x24382c34, 0xa3c25f40, 0x1d1672c3, + 0xe2bc0c25, 0x3c288b49, 0x0dff4195, 0xa8397101, 0x0c08deb3, + 0xb4d89ce4, 0x566490c1, 0xcb7b6184, 0x32d570b6, 0x6c48745c, + 0xb8d04257 + }; + + private static readonly uint[] Tinv3 = + { + 0x5150a7f4, 0x7e536541, 0x1ac3a417, 0x3a965e27, 0x3bcb6bab, + 0x1ff1459d, 0xacab58fa, 0x4b9303e3, 0x2055fa30, 0xadf66d76, + 0x889176cc, 0xf5254c02, 0x4ffcd7e5, 0xc5d7cb2a, 0x26804435, + 0xb58fa362, 0xde495ab1, 0x25671bba, 0x45980eea, 0x5de1c0fe, + 0xc302752f, 0x8112f04c, 0x8da39746, 0x6bc6f9d3, 0x03e75f8f, + 0x15959c92, 0xbfeb7a6d, 0x95da5952, 0xd42d83be, 0x58d32174, + 0x492969e0, 0x8e44c8c9, 0x756a89c2, 0xf478798e, 0x996b3e58, + 0x27dd71b9, 0xbeb64fe1, 0xf017ad88, 0xc966ac20, 0x7db43ace, + 0x63184adf, 0xe582311a, 0x97603351, 0x62457f53, 0xb1e07764, + 0xbb84ae6b, 0xfe1ca081, 0xf9942b08, 0x70586848, 0x8f19fd45, + 0x94876cde, 0x52b7f87b, 0xab23d373, 0x72e2024b, 0xe3578f1f, + 0x662aab55, 0xb20728eb, 0x2f03c2b5, 0x869a7bc5, 0xd3a50837, + 0x30f28728, 0x23b2a5bf, 0x02ba6a03, 0xed5c8216, 0x8a2b1ccf, + 0xa792b479, 0xf3f0f207, 0x4ea1e269, 0x65cdf4da, 0x06d5be05, + 0xd11f6234, 0xc48afea6, 0x349d532e, 0xa2a055f3, 0x0532e18a, + 0xa475ebf6, 0x0b39ec83, 0x40aaef60, 0x5e069f71, 0xbd51106e, + 0x3ef98a21, 0x963d06dd, 0xddae053e, 0x4d46bde6, 0x91b58d54, + 0x71055dc4, 0x046fd406, 0x60ff1550, 0x1924fb98, 0xd697e9bd, + 0x89cc4340, 0x67779ed9, 0xb0bd42e8, 0x07888b89, 0xe7385b19, + 0x79dbeec8, 0xa1470a7c, 0x7ce90f42, 0xf8c91e84, 0x00000000, + 0x09838680, 0x3248ed2b, 0x1eac7011, 0x6c4e725a, 0xfdfbff0e, + 0x0f563885, 0x3d1ed5ae, 0x3627392d, 0x0a64d90f, 0x6821a65c, + 0x9bd1545b, 0x243a2e36, 0x0cb1670a, 0x930fe757, 0xb4d296ee, + 0x1b9e919b, 0x804fc5c0, 0x61a220dc, 0x5a694b77, 0x1c161a12, + 0xe20aba93, 0xc0e52aa0, 0x3c43e022, 0x121d171b, 0x0e0b0d09, + 0xf2adc78b, 0x2db9a8b6, 0x14c8a91e, 0x578519f1, 0xaf4c0775, + 0xeebbdd99, 0xa3fd607f, 0xf79f2601, 0x5cbcf572, 0x44c53b66, + 0x5b347efb, 0x8b762943, 0xcbdcc623, 0xb668fced, 0xb863f1e4, + 0xd7cadc31, 0x42108563, 0x13402297, 0x842011c6, 0x857d244a, + 0xd2f83dbb, 0xae1132f9, 0xc76da129, 0x1d4b2f9e, 0xdcf330b2, + 0x0dec5286, 0x77d0e3c1, 0x2b6c16b3, 0xa999b970, 0x11fa4894, + 0x472264e9, 0xa8c48cfc, 0xa01a3ff0, 0x56d82c7d, 0x22ef9033, + 0x87c74e49, 0xd9c1d138, 0x8cfea2ca, 0x98360bd4, 0xa6cf81f5, + 0xa528de7a, 0xda268eb7, 0x3fa4bfad, 0x2ce49d3a, 0x500d9278, + 0x6a9bcc5f, 0x5462467e, 0xf6c2138d, 0x90e8b8d8, 0x2e5ef739, + 0x82f5afc3, 0x9fbe805d, 0x697c93d0, 0x6fa92dd5, 0xcfb31225, + 0xc83b99ac, 0x10a77d18, 0xe86e639c, 0xdb7bbb3b, 0xcd097826, + 0x6ef41859, 0xec01b79a, 0x83a89a4f, 0xe6656e95, 0xaa7ee6ff, + 0x2108cfbc, 0xefe6e815, 0xbad99be7, 0x4ace366f, 0xead4099f, + 0x29d67cb0, 0x31afb2a4, 0x2a31233f, 0xc63094a5, 0x35c066a2, + 0x7437bc4e, 0xfca6ca82, 0xe0b0d090, 0x3315d8a7, 0xf14a9804, + 0x41f7daec, 0x7f0e50cd, 0x172ff691, 0x768dd64d, 0x434db0ef, + 0xcc544daa, 0xe4df0496, 0x9ee3b5d1, 0x4c1b886a, 0xc1b81f2c, + 0x467f5165, 0x9d04ea5e, 0x015d358c, 0xfa737487, 0xfb2e410b, + 0xb35a1d67, 0x9252d2db, 0xe9335610, 0x6d1347d6, 0x9a8c61d7, + 0x377a0ca1, 0x598e14f8, 0xeb893c13, 0xceee27a9, 0xb735c961, + 0xe1ede51c, 0x7a3cb147, 0x9c59dfd2, 0x553f73f2, 0x1879ce14, + 0x73bf37c7, 0x53eacdf7, 0x5f5baafd, 0xdf146f3d, 0x7886db44, + 0xca81f3af, 0xb93ec468, 0x382c3424, 0xc25f40a3, 0x1672c31d, + 0xbc0c25e2, 0x288b493c, 0xff41950d, 0x397101a8, 0x08deb30c, + 0xd89ce4b4, 0x6490c156, 0x7b6184cb, 0xd570b632, 0x48745c6c, + 0xd04257b8 + }; + + private static uint Shift(uint r, int shift) + { + return (r >> shift) | (r << (32 - shift)); + } + + /* multiply four bytes in GF(2^8) by 'x' {02} in parallel */ + + private const uint m1 = 0x80808080; + private const uint m2 = 0x7f7f7f7f; + private const uint m3 = 0x0000001b; + private const uint m4 = 0xC0C0C0C0; + private const uint m5 = 0x3f3f3f3f; + + private static uint FFmulX(uint x) + { + return ((x & m2) << 1) ^ (((x & m1) >> 7) * m3); + } + + private static uint FFmulX2(uint x) + { + uint t0 = (x & m5) << 2; + uint t1 = (x & m4); + t1 ^= (t1 >> 1); + return t0 ^ (t1 >> 2) ^ (t1 >> 5); + } + + /* + The following defines provide alternative definitions of FFmulX that might + give improved performance if a fast 32-bit multiply is not available. + + private int FFmulX(int x) { int u = x & m1; u |= (u >> 1); return ((x & m2) << 1) ^ ((u >>> 3) | (u >>> 6)); } + private static final int m4 = 0x1b1b1b1b; + private int FFmulX(int x) { int u = x & m1; return ((x & m2) << 1) ^ ((u - (u >>> 7)) & m4); } + + */ + + private static uint Inv_Mcol(uint x) + { + uint t0, t1; + t0 = x; + t1 = t0 ^ Shift(t0, 8); + t0 ^= FFmulX(t1); + t1 ^= FFmulX2(t0); + t0 ^= t1 ^ Shift(t1, 16); + return t0; + } + + private static uint SubWord(uint x) + { + return (uint)S[x&255] + | (((uint)S[(x>>8)&255]) << 8) + | (((uint)S[(x>>16)&255]) << 16) + | (((uint)S[(x>>24)&255]) << 24); + } + + /** + * Calculate the necessary round keys + * The number of calculations depends on key size and block size + * AES specified a fixed block size of 128 bits and key sizes 128/192/256 bits + * This code is written assuming those are the only possible values + */ + private uint[][] GenerateWorkingKey(byte[] key, bool forEncryption) + { + int keyLen = key.Length; + if (keyLen < 16 || keyLen > 32 || (keyLen & 7) != 0) + throw new ArgumentException("Key length not 128/192/256 bits."); + + int KC = keyLen >> 2; + this.ROUNDS = KC + 6; // This is not always true for the generalized Rijndael that allows larger block sizes + + uint[][] W = new uint[ROUNDS + 1][]; // 4 words in a block + for (int i = 0; i <= ROUNDS; ++i) + { + W[i] = new uint[4]; + } + + switch (KC) + { + case 4: + { + uint t0 = Pack.LE_To_UInt32(key, 0); W[0][0] = t0; + uint t1 = Pack.LE_To_UInt32(key, 4); W[0][1] = t1; + uint t2 = Pack.LE_To_UInt32(key, 8); W[0][2] = t2; + uint t3 = Pack.LE_To_UInt32(key, 12); W[0][3] = t3; + + for (int i = 1; i <= 10; ++i) + { + uint u = SubWord(Shift(t3, 8)) ^ rcon[i - 1]; + t0 ^= u; W[i][0] = t0; + t1 ^= t0; W[i][1] = t1; + t2 ^= t1; W[i][2] = t2; + t3 ^= t2; W[i][3] = t3; + } + + break; + } + case 6: + { + uint t0 = Pack.LE_To_UInt32(key, 0); W[0][0] = t0; + uint t1 = Pack.LE_To_UInt32(key, 4); W[0][1] = t1; + uint t2 = Pack.LE_To_UInt32(key, 8); W[0][2] = t2; + uint t3 = Pack.LE_To_UInt32(key, 12); W[0][3] = t3; + uint t4 = Pack.LE_To_UInt32(key, 16); W[1][0] = t4; + uint t5 = Pack.LE_To_UInt32(key, 20); W[1][1] = t5; + + uint rcon = 1; + uint u = SubWord(Shift(t5, 8)) ^ rcon; rcon <<= 1; + t0 ^= u; W[1][2] = t0; + t1 ^= t0; W[1][3] = t1; + t2 ^= t1; W[2][0] = t2; + t3 ^= t2; W[2][1] = t3; + t4 ^= t3; W[2][2] = t4; + t5 ^= t4; W[2][3] = t5; + + for (int i = 3; i < 12; i += 3) + { + u = SubWord(Shift(t5, 8)) ^ rcon; rcon <<= 1; + t0 ^= u; W[i ][0] = t0; + t1 ^= t0; W[i ][1] = t1; + t2 ^= t1; W[i ][2] = t2; + t3 ^= t2; W[i ][3] = t3; + t4 ^= t3; W[i + 1][0] = t4; + t5 ^= t4; W[i + 1][1] = t5; + u = SubWord(Shift(t5, 8)) ^ rcon; rcon <<= 1; + t0 ^= u; W[i + 1][2] = t0; + t1 ^= t0; W[i + 1][3] = t1; + t2 ^= t1; W[i + 2][0] = t2; + t3 ^= t2; W[i + 2][1] = t3; + t4 ^= t3; W[i + 2][2] = t4; + t5 ^= t4; W[i + 2][3] = t5; + } + + u = SubWord(Shift(t5, 8)) ^ rcon; + t0 ^= u; W[12][0] = t0; + t1 ^= t0; W[12][1] = t1; + t2 ^= t1; W[12][2] = t2; + t3 ^= t2; W[12][3] = t3; + + break; + } + case 8: + { + uint t0 = Pack.LE_To_UInt32(key, 0); W[0][0] = t0; + uint t1 = Pack.LE_To_UInt32(key, 4); W[0][1] = t1; + uint t2 = Pack.LE_To_UInt32(key, 8); W[0][2] = t2; + uint t3 = Pack.LE_To_UInt32(key, 12); W[0][3] = t3; + uint t4 = Pack.LE_To_UInt32(key, 16); W[1][0] = t4; + uint t5 = Pack.LE_To_UInt32(key, 20); W[1][1] = t5; + uint t6 = Pack.LE_To_UInt32(key, 24); W[1][2] = t6; + uint t7 = Pack.LE_To_UInt32(key, 28); W[1][3] = t7; + + uint u, rcon = 1; + + for (int i = 2; i < 14; i += 2) + { + u = SubWord(Shift(t7, 8)) ^ rcon; rcon <<= 1; + t0 ^= u; W[i ][0] = t0; + t1 ^= t0; W[i ][1] = t1; + t2 ^= t1; W[i ][2] = t2; + t3 ^= t2; W[i ][3] = t3; + u = SubWord(t3); + t4 ^= u; W[i + 1][0] = t4; + t5 ^= t4; W[i + 1][1] = t5; + t6 ^= t5; W[i + 1][2] = t6; + t7 ^= t6; W[i + 1][3] = t7; + } + + u = SubWord(Shift(t7, 8)) ^ rcon; + t0 ^= u; W[14][0] = t0; + t1 ^= t0; W[14][1] = t1; + t2 ^= t1; W[14][2] = t2; + t3 ^= t2; W[14][3] = t3; + + break; + } + default: + { + throw new InvalidOperationException("Should never get here"); + } + } + + if (!forEncryption) + { + for (int j = 1; j < ROUNDS; j++) + { + uint[] w = W[j]; + for (int i = 0; i < 4; i++) + { + w[i] = Inv_Mcol(w[i]); + } + } + } + + return W; + } + + private int ROUNDS; + private uint[][] WorkingKey; + private bool forEncryption; + + private const int BLOCK_SIZE = 16; + + /** + * default constructor - 128 bit block size. + */ + public AesFastEngine() + { + } + + /** + * initialise an AES cipher. + * + * @param forEncryption whether or not we are for encryption. + * @param parameters the parameters required to set up the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + KeyParameter keyParameter = parameters as KeyParameter; + + if (keyParameter == null) + throw new ArgumentException("invalid parameter passed to AES init - " + + Platform.GetTypeName(parameters)); + + WorkingKey = GenerateWorkingKey(keyParameter.GetKey(), forEncryption); + + this.forEncryption = forEncryption; + } + + public virtual string AlgorithmName + { + get { return "AES"; } + } + + public virtual bool IsPartialBlockOkay + { + get { return false; } + } + + public virtual int GetBlockSize() + { + return BLOCK_SIZE; + } + + public virtual int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff) + { + if (WorkingKey == null) + throw new InvalidOperationException("AES engine not initialised"); + + Check.DataLength(input, inOff, 16, "input buffer too short"); + Check.OutputLength(output, outOff, 16, "output buffer too short"); + + if (forEncryption) + { + EncryptBlock(input, inOff, output, outOff, WorkingKey); + } + else + { + DecryptBlock(input, inOff, output, outOff, WorkingKey); + } + + return BLOCK_SIZE; + } + + public virtual void Reset() + { + } + + private void EncryptBlock(byte[] input, int inOff, byte[] output, int outOff, uint[][] KW) + { + uint C0 = Pack.LE_To_UInt32(input, inOff + 0); + uint C1 = Pack.LE_To_UInt32(input, inOff + 4); + uint C2 = Pack.LE_To_UInt32(input, inOff + 8); + uint C3 = Pack.LE_To_UInt32(input, inOff + 12); + + uint[] kw = KW[0]; + uint t0 = C0 ^ kw[0]; + uint t1 = C1 ^ kw[1]; + uint t2 = C2 ^ kw[2]; + + uint r0, r1, r2, r3 = C3 ^ kw[3]; + int r = 1; + while (r < ROUNDS - 1) + { + kw = KW[r++]; + r0 = T0[t0 & 255] ^ T1[(t1 >> 8) & 255] ^ T2[(t2 >> 16) & 255] ^ T3[r3 >> 24] ^ kw[0]; + r1 = T0[t1 & 255] ^ T1[(t2 >> 8) & 255] ^ T2[(r3 >> 16) & 255] ^ T3[t0 >> 24] ^ kw[1]; + r2 = T0[t2 & 255] ^ T1[(r3 >> 8) & 255] ^ T2[(t0 >> 16) & 255] ^ T3[t1 >> 24] ^ kw[2]; + r3 = T0[r3 & 255] ^ T1[(t0 >> 8) & 255] ^ T2[(t1 >> 16) & 255] ^ T3[t2 >> 24] ^ kw[3]; + kw = KW[r++]; + t0 = T0[r0 & 255] ^ T1[(r1 >> 8) & 255] ^ T2[(r2 >> 16) & 255] ^ T3[r3 >> 24] ^ kw[0]; + t1 = T0[r1 & 255] ^ T1[(r2 >> 8) & 255] ^ T2[(r3 >> 16) & 255] ^ T3[r0 >> 24] ^ kw[1]; + t2 = T0[r2 & 255] ^ T1[(r3 >> 8) & 255] ^ T2[(r0 >> 16) & 255] ^ T3[r1 >> 24] ^ kw[2]; + r3 = T0[r3 & 255] ^ T1[(r0 >> 8) & 255] ^ T2[(r1 >> 16) & 255] ^ T3[r2 >> 24] ^ kw[3]; + } + + kw = KW[r++]; + r0 = T0[t0 & 255] ^ T1[(t1 >> 8) & 255] ^ T2[(t2 >> 16) & 255] ^ T3[r3 >> 24] ^ kw[0]; + r1 = T0[t1 & 255] ^ T1[(t2 >> 8) & 255] ^ T2[(r3 >> 16) & 255] ^ T3[t0 >> 24] ^ kw[1]; + r2 = T0[t2 & 255] ^ T1[(r3 >> 8) & 255] ^ T2[(t0 >> 16) & 255] ^ T3[t1 >> 24] ^ kw[2]; + r3 = T0[r3 & 255] ^ T1[(t0 >> 8) & 255] ^ T2[(t1 >> 16) & 255] ^ T3[t2 >> 24] ^ kw[3]; + + // the final round's table is a simple function of S so we don't use a whole other four tables for it + + kw = KW[r]; + C0 = (uint)S[r0 & 255] ^ (((uint)S[(r1 >> 8) & 255]) << 8) ^ (((uint)S[(r2 >> 16) & 255]) << 16) ^ (((uint)S[r3 >> 24]) << 24) ^ kw[0]; + C1 = (uint)S[r1 & 255] ^ (((uint)S[(r2 >> 8) & 255]) << 8) ^ (((uint)S[(r3 >> 16) & 255]) << 16) ^ (((uint)S[r0 >> 24]) << 24) ^ kw[1]; + C2 = (uint)S[r2 & 255] ^ (((uint)S[(r3 >> 8) & 255]) << 8) ^ (((uint)S[(r0 >> 16) & 255]) << 16) ^ (((uint)S[r1 >> 24]) << 24) ^ kw[2]; + C3 = (uint)S[r3 & 255] ^ (((uint)S[(r0 >> 8) & 255]) << 8) ^ (((uint)S[(r1 >> 16) & 255]) << 16) ^ (((uint)S[r2 >> 24]) << 24) ^ kw[3]; + + Pack.UInt32_To_LE(C0, output, outOff + 0); + Pack.UInt32_To_LE(C1, output, outOff + 4); + Pack.UInt32_To_LE(C2, output, outOff + 8); + Pack.UInt32_To_LE(C3, output, outOff + 12); + } + + private void DecryptBlock(byte[] input, int inOff, byte[] output, int outOff, uint[][] KW) + { + uint C0 = Pack.LE_To_UInt32(input, inOff + 0); + uint C1 = Pack.LE_To_UInt32(input, inOff + 4); + uint C2 = Pack.LE_To_UInt32(input, inOff + 8); + uint C3 = Pack.LE_To_UInt32(input, inOff + 12); + + uint[] kw = KW[ROUNDS]; + uint t0 = C0 ^ kw[0]; + uint t1 = C1 ^ kw[1]; + uint t2 = C2 ^ kw[2]; + + uint r0, r1, r2, r3 = C3 ^ kw[3]; + int r = ROUNDS - 1; + while (r > 1) + { + kw = KW[r--]; + r0 = Tinv0[t0 & 255] ^ Tinv1[(r3 >> 8) & 255] ^ Tinv2[(t2 >> 16) & 255] ^ Tinv3[t1 >> 24] ^ kw[0]; + r1 = Tinv0[t1 & 255] ^ Tinv1[(t0 >> 8) & 255] ^ Tinv2[(r3 >> 16) & 255] ^ Tinv3[t2 >> 24] ^ kw[1]; + r2 = Tinv0[t2 & 255] ^ Tinv1[(t1 >> 8) & 255] ^ Tinv2[(t0 >> 16) & 255] ^ Tinv3[r3 >> 24] ^ kw[2]; + r3 = Tinv0[r3 & 255] ^ Tinv1[(t2 >> 8) & 255] ^ Tinv2[(t1 >> 16) & 255] ^ Tinv3[t0 >> 24] ^ kw[3]; + kw = KW[r--]; + t0 = Tinv0[r0 & 255] ^ Tinv1[(r3 >> 8) & 255] ^ Tinv2[(r2 >> 16) & 255] ^ Tinv3[r1 >> 24] ^ kw[0]; + t1 = Tinv0[r1 & 255] ^ Tinv1[(r0 >> 8) & 255] ^ Tinv2[(r3 >> 16) & 255] ^ Tinv3[r2 >> 24] ^ kw[1]; + t2 = Tinv0[r2 & 255] ^ Tinv1[(r1 >> 8) & 255] ^ Tinv2[(r0 >> 16) & 255] ^ Tinv3[r3 >> 24] ^ kw[2]; + r3 = Tinv0[r3 & 255] ^ Tinv1[(r2 >> 8) & 255] ^ Tinv2[(r1 >> 16) & 255] ^ Tinv3[r0 >> 24] ^ kw[3]; + } + + kw = KW[1]; + r0 = Tinv0[t0 & 255] ^ Tinv1[(r3 >> 8) & 255] ^ Tinv2[(t2 >> 16) & 255] ^ Tinv3[t1 >> 24] ^ kw[0]; + r1 = Tinv0[t1 & 255] ^ Tinv1[(t0 >> 8) & 255] ^ Tinv2[(r3 >> 16) & 255] ^ Tinv3[t2 >> 24] ^ kw[1]; + r2 = Tinv0[t2 & 255] ^ Tinv1[(t1 >> 8) & 255] ^ Tinv2[(t0 >> 16) & 255] ^ Tinv3[r3 >> 24] ^ kw[2]; + r3 = Tinv0[r3 & 255] ^ Tinv1[(t2 >> 8) & 255] ^ Tinv2[(t1 >> 16) & 255] ^ Tinv3[t0 >> 24] ^ kw[3]; + + // the final round's table is a simple function of Si so we don't use a whole other four tables for it + + kw = KW[0]; + C0 = (uint)Si[r0 & 255] ^ (((uint)Si[(r3 >> 8) & 255]) << 8) ^ (((uint)Si[(r2 >> 16) & 255]) << 16) ^ (((uint)Si[r1 >> 24]) << 24) ^ kw[0]; + C1 = (uint)Si[r1 & 255] ^ (((uint)Si[(r0 >> 8) & 255]) << 8) ^ (((uint)Si[(r3 >> 16) & 255]) << 16) ^ (((uint)Si[r2 >> 24]) << 24) ^ kw[1]; + C2 = (uint)Si[r2 & 255] ^ (((uint)Si[(r1 >> 8) & 255]) << 8) ^ (((uint)Si[(r0 >> 16) & 255]) << 16) ^ (((uint)Si[r3 >> 24]) << 24) ^ kw[2]; + C3 = (uint)Si[r3 & 255] ^ (((uint)Si[(r2 >> 8) & 255]) << 8) ^ (((uint)Si[(r1 >> 16) & 255]) << 16) ^ (((uint)Si[r0 >> 24]) << 24) ^ kw[3]; + + Pack.UInt32_To_LE(C0, output, outOff + 0); + Pack.UInt32_To_LE(C1, output, outOff + 4); + Pack.UInt32_To_LE(C2, output, outOff + 8); + Pack.UInt32_To_LE(C3, output, outOff + 12); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/AesFastEngine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/AesFastEngine.cs.meta new file mode 100644 index 0000000..b43e1c7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/AesFastEngine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3d691b94e66ead24096eda959cb5169c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/AesLightEngine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/AesLightEngine.cs new file mode 100644 index 0000000..8d5a98a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/AesLightEngine.cs @@ -0,0 +1,495 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * an implementation of the AES (Rijndael), from FIPS-197. + *

+ * For further details see: http://csrc.nist.gov/encryption/aes/. + * + * This implementation is based on optimizations from Dr. Brian Gladman's paper and C code at + * http://fp.gladman.plus.com/cryptography_technology/rijndael/ + * + * There are three levels of tradeoff of speed vs memory + * Because java has no preprocessor, they are written as three separate classes from which to choose + * + * The fastest uses 8Kbytes of static tables to precompute round calculations, 4 256 word tables for encryption + * and 4 for decryption. + * + * The middle performance version uses only one 256 word table for each, for a total of 2Kbytes, + * adding 12 rotate operations per round to compute the values contained in the other tables from + * the contents of the first + * + * The slowest version uses no static tables at all and computes the values + * in each round. + *

+ *

+ * This file contains the slowest performance version with no static tables + * for round precomputation, but it has the smallest foot print. + *

+ */ + public class AesLightEngine + : IBlockCipher + { + // The S box + private static readonly byte[] S = + { + 99, 124, 119, 123, 242, 107, 111, 197, + 48, 1, 103, 43, 254, 215, 171, 118, + 202, 130, 201, 125, 250, 89, 71, 240, + 173, 212, 162, 175, 156, 164, 114, 192, + 183, 253, 147, 38, 54, 63, 247, 204, + 52, 165, 229, 241, 113, 216, 49, 21, + 4, 199, 35, 195, 24, 150, 5, 154, + 7, 18, 128, 226, 235, 39, 178, 117, + 9, 131, 44, 26, 27, 110, 90, 160, + 82, 59, 214, 179, 41, 227, 47, 132, + 83, 209, 0, 237, 32, 252, 177, 91, + 106, 203, 190, 57, 74, 76, 88, 207, + 208, 239, 170, 251, 67, 77, 51, 133, + 69, 249, 2, 127, 80, 60, 159, 168, + 81, 163, 64, 143, 146, 157, 56, 245, + 188, 182, 218, 33, 16, 255, 243, 210, + 205, 12, 19, 236, 95, 151, 68, 23, + 196, 167, 126, 61, 100, 93, 25, 115, + 96, 129, 79, 220, 34, 42, 144, 136, + 70, 238, 184, 20, 222, 94, 11, 219, + 224, 50, 58, 10, 73, 6, 36, 92, + 194, 211, 172, 98, 145, 149, 228, 121, + 231, 200, 55, 109, 141, 213, 78, 169, + 108, 86, 244, 234, 101, 122, 174, 8, + 186, 120, 37, 46, 28, 166, 180, 198, + 232, 221, 116, 31, 75, 189, 139, 138, + 112, 62, 181, 102, 72, 3, 246, 14, + 97, 53, 87, 185, 134, 193, 29, 158, + 225, 248, 152, 17, 105, 217, 142, 148, + 155, 30, 135, 233, 206, 85, 40, 223, + 140, 161, 137, 13, 191, 230, 66, 104, + 65, 153, 45, 15, 176, 84, 187, 22, + }; + + // The inverse S-box + private static readonly byte[] Si = + { + 82, 9, 106, 213, 48, 54, 165, 56, + 191, 64, 163, 158, 129, 243, 215, 251, + 124, 227, 57, 130, 155, 47, 255, 135, + 52, 142, 67, 68, 196, 222, 233, 203, + 84, 123, 148, 50, 166, 194, 35, 61, + 238, 76, 149, 11, 66, 250, 195, 78, + 8, 46, 161, 102, 40, 217, 36, 178, + 118, 91, 162, 73, 109, 139, 209, 37, + 114, 248, 246, 100, 134, 104, 152, 22, + 212, 164, 92, 204, 93, 101, 182, 146, + 108, 112, 72, 80, 253, 237, 185, 218, + 94, 21, 70, 87, 167, 141, 157, 132, + 144, 216, 171, 0, 140, 188, 211, 10, + 247, 228, 88, 5, 184, 179, 69, 6, + 208, 44, 30, 143, 202, 63, 15, 2, + 193, 175, 189, 3, 1, 19, 138, 107, + 58, 145, 17, 65, 79, 103, 220, 234, + 151, 242, 207, 206, 240, 180, 230, 115, + 150, 172, 116, 34, 231, 173, 53, 133, + 226, 249, 55, 232, 28, 117, 223, 110, + 71, 241, 26, 113, 29, 41, 197, 137, + 111, 183, 98, 14, 170, 24, 190, 27, + 252, 86, 62, 75, 198, 210, 121, 32, + 154, 219, 192, 254, 120, 205, 90, 244, + 31, 221, 168, 51, 136, 7, 199, 49, + 177, 18, 16, 89, 39, 128, 236, 95, + 96, 81, 127, 169, 25, 181, 74, 13, + 45, 229, 122, 159, 147, 201, 156, 239, + 160, 224, 59, 77, 174, 42, 245, 176, + 200, 235, 187, 60, 131, 83, 153, 97, + 23, 43, 4, 126, 186, 119, 214, 38, + 225, 105, 20, 99, 85, 33, 12, 125, + }; + + // vector used in calculating key schedule (powers of x in GF(256)) + private static readonly byte[] rcon = + { + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, + 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91 + }; + + private static uint Shift(uint r, int shift) + { + return (r >> shift) | (r << (32 - shift)); + } + + /* multiply four bytes in GF(2^8) by 'x' {02} in parallel */ + + private const uint m1 = 0x80808080; + private const uint m2 = 0x7f7f7f7f; + private const uint m3 = 0x0000001b; + private const uint m4 = 0xC0C0C0C0; + private const uint m5 = 0x3f3f3f3f; + + private static uint FFmulX(uint x) + { + return ((x & m2) << 1) ^ (((x & m1) >> 7) * m3); + } + + private static uint FFmulX2(uint x) + { + uint t0 = (x & m5) << 2; + uint t1 = (x & m4); + t1 ^= (t1 >> 1); + return t0 ^ (t1 >> 2) ^ (t1 >> 5); + } + + /* + The following defines provide alternative definitions of FFmulX that might + give improved performance if a fast 32-bit multiply is not available. + + private int FFmulX(int x) { int u = x & m1; u |= (u >> 1); return ((x & m2) << 1) ^ ((u >>> 3) | (u >>> 6)); } + private static final int m4 = 0x1b1b1b1b; + private int FFmulX(int x) { int u = x & m1; return ((x & m2) << 1) ^ ((u - (u >>> 7)) & m4); } + + */ + + private static uint Mcol(uint x) + { + uint t0, t1; + t0 = Shift(x, 8); + t1 = x ^ t0; + return Shift(t1, 16) ^ t0 ^ FFmulX(t1); + } + + private static uint Inv_Mcol(uint x) + { + uint t0, t1; + t0 = x; + t1 = t0 ^ Shift(t0, 8); + t0 ^= FFmulX(t1); + t1 ^= FFmulX2(t0); + t0 ^= t1 ^ Shift(t1, 16); + return t0; + } + + private static uint SubWord(uint x) + { + return (uint)S[x&255] + | (((uint)S[(x>>8)&255]) << 8) + | (((uint)S[(x>>16)&255]) << 16) + | (((uint)S[(x>>24)&255]) << 24); + } + + /** + * Calculate the necessary round keys + * The number of calculations depends on key size and block size + * AES specified a fixed block size of 128 bits and key sizes 128/192/256 bits + * This code is written assuming those are the only possible values + */ + private uint[][] GenerateWorkingKey(byte[] key, bool forEncryption) + { + int keyLen = key.Length; + if (keyLen < 16 || keyLen > 32 || (keyLen & 7) != 0) + throw new ArgumentException("Key length not 128/192/256 bits."); + + int KC = keyLen >> 2; + this.ROUNDS = KC + 6; // This is not always true for the generalized Rijndael that allows larger block sizes + + uint[][] W = new uint[ROUNDS + 1][]; // 4 words in a block + for (int i = 0; i <= ROUNDS; ++i) + { + W[i] = new uint[4]; + } + + switch (KC) + { + case 4: + { + uint t0 = Pack.LE_To_UInt32(key, 0); W[0][0] = t0; + uint t1 = Pack.LE_To_UInt32(key, 4); W[0][1] = t1; + uint t2 = Pack.LE_To_UInt32(key, 8); W[0][2] = t2; + uint t3 = Pack.LE_To_UInt32(key, 12); W[0][3] = t3; + + for (int i = 1; i <= 10; ++i) + { + uint u = SubWord(Shift(t3, 8)) ^ rcon[i - 1]; + t0 ^= u; W[i][0] = t0; + t1 ^= t0; W[i][1] = t1; + t2 ^= t1; W[i][2] = t2; + t3 ^= t2; W[i][3] = t3; + } + + break; + } + case 6: + { + uint t0 = Pack.LE_To_UInt32(key, 0); W[0][0] = t0; + uint t1 = Pack.LE_To_UInt32(key, 4); W[0][1] = t1; + uint t2 = Pack.LE_To_UInt32(key, 8); W[0][2] = t2; + uint t3 = Pack.LE_To_UInt32(key, 12); W[0][3] = t3; + uint t4 = Pack.LE_To_UInt32(key, 16); W[1][0] = t4; + uint t5 = Pack.LE_To_UInt32(key, 20); W[1][1] = t5; + + uint rcon = 1; + uint u = SubWord(Shift(t5, 8)) ^ rcon; rcon <<= 1; + t0 ^= u; W[1][2] = t0; + t1 ^= t0; W[1][3] = t1; + t2 ^= t1; W[2][0] = t2; + t3 ^= t2; W[2][1] = t3; + t4 ^= t3; W[2][2] = t4; + t5 ^= t4; W[2][3] = t5; + + for (int i = 3; i < 12; i += 3) + { + u = SubWord(Shift(t5, 8)) ^ rcon; rcon <<= 1; + t0 ^= u; W[i ][0] = t0; + t1 ^= t0; W[i ][1] = t1; + t2 ^= t1; W[i ][2] = t2; + t3 ^= t2; W[i ][3] = t3; + t4 ^= t3; W[i + 1][0] = t4; + t5 ^= t4; W[i + 1][1] = t5; + u = SubWord(Shift(t5, 8)) ^ rcon; rcon <<= 1; + t0 ^= u; W[i + 1][2] = t0; + t1 ^= t0; W[i + 1][3] = t1; + t2 ^= t1; W[i + 2][0] = t2; + t3 ^= t2; W[i + 2][1] = t3; + t4 ^= t3; W[i + 2][2] = t4; + t5 ^= t4; W[i + 2][3] = t5; + } + + u = SubWord(Shift(t5, 8)) ^ rcon; + t0 ^= u; W[12][0] = t0; + t1 ^= t0; W[12][1] = t1; + t2 ^= t1; W[12][2] = t2; + t3 ^= t2; W[12][3] = t3; + + break; + } + case 8: + { + uint t0 = Pack.LE_To_UInt32(key, 0); W[0][0] = t0; + uint t1 = Pack.LE_To_UInt32(key, 4); W[0][1] = t1; + uint t2 = Pack.LE_To_UInt32(key, 8); W[0][2] = t2; + uint t3 = Pack.LE_To_UInt32(key, 12); W[0][3] = t3; + uint t4 = Pack.LE_To_UInt32(key, 16); W[1][0] = t4; + uint t5 = Pack.LE_To_UInt32(key, 20); W[1][1] = t5; + uint t6 = Pack.LE_To_UInt32(key, 24); W[1][2] = t6; + uint t7 = Pack.LE_To_UInt32(key, 28); W[1][3] = t7; + + uint u, rcon = 1; + + for (int i = 2; i < 14; i += 2) + { + u = SubWord(Shift(t7, 8)) ^ rcon; rcon <<= 1; + t0 ^= u; W[i ][0] = t0; + t1 ^= t0; W[i ][1] = t1; + t2 ^= t1; W[i ][2] = t2; + t3 ^= t2; W[i ][3] = t3; + u = SubWord(t3); + t4 ^= u; W[i + 1][0] = t4; + t5 ^= t4; W[i + 1][1] = t5; + t6 ^= t5; W[i + 1][2] = t6; + t7 ^= t6; W[i + 1][3] = t7; + } + + u = SubWord(Shift(t7, 8)) ^ rcon; + t0 ^= u; W[14][0] = t0; + t1 ^= t0; W[14][1] = t1; + t2 ^= t1; W[14][2] = t2; + t3 ^= t2; W[14][3] = t3; + + break; + } + default: + { + throw new InvalidOperationException("Should never get here"); + } + } + + if (!forEncryption) + { + for (int j = 1; j < ROUNDS; j++) + { + uint[] w = W[j]; + for (int i = 0; i < 4; i++) + { + w[i] = Inv_Mcol(w[i]); + } + } + } + + return W; + } + + private int ROUNDS; + private uint[][] WorkingKey; + private bool forEncryption; + + private const int BLOCK_SIZE = 16; + + /** + * default constructor - 128 bit block size. + */ + public AesLightEngine() + { + } + + /** + * initialise an AES cipher. + * + * @param forEncryption whether or not we are for encryption. + * @param parameters the parameters required to set up the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + KeyParameter keyParameter = parameters as KeyParameter; + + if (keyParameter == null) + throw new ArgumentException("invalid parameter passed to AES init - " + + Platform.GetTypeName(parameters)); + + WorkingKey = GenerateWorkingKey(keyParameter.GetKey(), forEncryption); + + this.forEncryption = forEncryption; + } + + public virtual string AlgorithmName + { + get { return "AES"; } + } + + public virtual bool IsPartialBlockOkay + { + get { return false; } + } + + public virtual int GetBlockSize() + { + return BLOCK_SIZE; + } + + public virtual int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff) + { + if (WorkingKey == null) + throw new InvalidOperationException("AES engine not initialised"); + + Check.DataLength(input, inOff, 16, "input buffer too short"); + Check.OutputLength(output, outOff, 16, "output buffer too short"); + + if (forEncryption) + { + EncryptBlock(input, inOff, output, outOff, WorkingKey); + } + else + { + DecryptBlock(input, inOff, output, outOff, WorkingKey); + } + + return BLOCK_SIZE; + } + + public virtual void Reset() + { + } + + private void EncryptBlock(byte[] input, int inOff, byte[] output, int outOff, uint[][] KW) + { + uint C0 = Pack.LE_To_UInt32(input, inOff + 0); + uint C1 = Pack.LE_To_UInt32(input, inOff + 4); + uint C2 = Pack.LE_To_UInt32(input, inOff + 8); + uint C3 = Pack.LE_To_UInt32(input, inOff + 12); + + uint[] kw = KW[0]; + uint t0 = C0 ^ kw[0]; + uint t1 = C1 ^ kw[1]; + uint t2 = C2 ^ kw[2]; + + uint r0, r1, r2, r3 = C3 ^ kw[3]; + int r = 1; + while (r < ROUNDS - 1) + { + kw = KW[r++]; + r0 = Mcol((uint)S[t0 & 255] ^ (((uint)S[(t1 >> 8) & 255]) << 8) ^ (((uint)S[(t2 >> 16) & 255]) << 16) ^ (((uint)S[(r3 >> 24) & 255]) << 24)) ^ kw[0]; + r1 = Mcol((uint)S[t1 & 255] ^ (((uint)S[(t2 >> 8) & 255]) << 8) ^ (((uint)S[(r3 >> 16) & 255]) << 16) ^ (((uint)S[(t0 >> 24) & 255]) << 24)) ^ kw[1]; + r2 = Mcol((uint)S[t2 & 255] ^ (((uint)S[(r3 >> 8) & 255]) << 8) ^ (((uint)S[(t0 >> 16) & 255]) << 16) ^ (((uint)S[(t1 >> 24) & 255]) << 24)) ^ kw[2]; + r3 = Mcol((uint)S[r3 & 255] ^ (((uint)S[(t0 >> 8) & 255]) << 8) ^ (((uint)S[(t1 >> 16) & 255]) << 16) ^ (((uint)S[(t2 >> 24) & 255]) << 24)) ^ kw[3]; + kw = KW[r++]; + t0 = Mcol((uint)S[r0 & 255] ^ (((uint)S[(r1 >> 8) & 255]) << 8) ^ (((uint)S[(r2 >> 16) & 255]) << 16) ^ (((uint)S[(r3 >> 24) & 255]) << 24)) ^ kw[0]; + t1 = Mcol((uint)S[r1 & 255] ^ (((uint)S[(r2 >> 8) & 255]) << 8) ^ (((uint)S[(r3 >> 16) & 255]) << 16) ^ (((uint)S[(r0 >> 24) & 255]) << 24)) ^ kw[1]; + t2 = Mcol((uint)S[r2 & 255] ^ (((uint)S[(r3 >> 8) & 255]) << 8) ^ (((uint)S[(r0 >> 16) & 255]) << 16) ^ (((uint)S[(r1 >> 24) & 255]) << 24)) ^ kw[2]; + r3 = Mcol((uint)S[r3 & 255] ^ (((uint)S[(r0 >> 8) & 255]) << 8) ^ (((uint)S[(r1 >> 16) & 255]) << 16) ^ (((uint)S[(r2 >> 24) & 255]) << 24)) ^ kw[3]; + } + + kw = KW[r++]; + r0 = Mcol((uint)S[t0 & 255] ^ (((uint)S[(t1 >> 8) & 255]) << 8) ^ (((uint)S[(t2 >> 16) & 255]) << 16) ^ (((uint)S[(r3 >> 24) & 255]) << 24)) ^ kw[0]; + r1 = Mcol((uint)S[t1 & 255] ^ (((uint)S[(t2 >> 8) & 255]) << 8) ^ (((uint)S[(r3 >> 16) & 255]) << 16) ^ (((uint)S[(t0 >> 24) & 255]) << 24)) ^ kw[1]; + r2 = Mcol((uint)S[t2 & 255] ^ (((uint)S[(r3 >> 8) & 255]) << 8) ^ (((uint)S[(t0 >> 16) & 255]) << 16) ^ (((uint)S[(t1 >> 24) & 255]) << 24)) ^ kw[2]; + r3 = Mcol((uint)S[r3 & 255] ^ (((uint)S[(t0 >> 8) & 255]) << 8) ^ (((uint)S[(t1 >> 16) & 255]) << 16) ^ (((uint)S[(t2 >> 24) & 255]) << 24)) ^ kw[3]; + + // the final round is a simple function of S + + kw = KW[r]; + C0 = (uint)S[r0 & 255] ^ (((uint)S[(r1 >> 8) & 255]) << 8) ^ (((uint)S[(r2 >> 16) & 255]) << 16) ^ (((uint)S[(r3 >> 24) & 255]) << 24) ^ kw[0]; + C1 = (uint)S[r1 & 255] ^ (((uint)S[(r2 >> 8) & 255]) << 8) ^ (((uint)S[(r3 >> 16) & 255]) << 16) ^ (((uint)S[(r0 >> 24) & 255]) << 24) ^ kw[1]; + C2 = (uint)S[r2 & 255] ^ (((uint)S[(r3 >> 8) & 255]) << 8) ^ (((uint)S[(r0 >> 16) & 255]) << 16) ^ (((uint)S[(r1 >> 24) & 255]) << 24) ^ kw[2]; + C3 = (uint)S[r3 & 255] ^ (((uint)S[(r0 >> 8) & 255]) << 8) ^ (((uint)S[(r1 >> 16) & 255]) << 16) ^ (((uint)S[(r2 >> 24) & 255]) << 24) ^ kw[3]; + + Pack.UInt32_To_LE(C0, output, outOff + 0); + Pack.UInt32_To_LE(C1, output, outOff + 4); + Pack.UInt32_To_LE(C2, output, outOff + 8); + Pack.UInt32_To_LE(C3, output, outOff + 12); + } + + private void DecryptBlock(byte[] input, int inOff, byte[] output, int outOff, uint[][] KW) + { + uint C0 = Pack.LE_To_UInt32(input, inOff + 0); + uint C1 = Pack.LE_To_UInt32(input, inOff + 4); + uint C2 = Pack.LE_To_UInt32(input, inOff + 8); + uint C3 = Pack.LE_To_UInt32(input, inOff + 12); + + uint[] kw = KW[ROUNDS]; + uint t0 = C0 ^ kw[0]; + uint t1 = C1 ^ kw[1]; + uint t2 = C2 ^ kw[2]; + + uint r0, r1, r2, r3 = C3 ^ kw[3]; + int r = ROUNDS - 1; + while (r > 1) + { + kw = KW[r--]; + r0 = Inv_Mcol((uint)Si[t0 & 255] ^ (((uint)Si[(r3 >> 8) & 255]) << 8) ^ (((uint)Si[(t2 >> 16) & 255]) << 16) ^ ((uint)Si[(t1 >> 24) & 255] << 24)) ^ kw[0]; + r1 = Inv_Mcol((uint)Si[t1 & 255] ^ (((uint)Si[(t0 >> 8) & 255]) << 8) ^ (((uint)Si[(r3 >> 16) & 255]) << 16) ^ ((uint)Si[(t2 >> 24) & 255] << 24)) ^ kw[1]; + r2 = Inv_Mcol((uint)Si[t2 & 255] ^ (((uint)Si[(t1 >> 8) & 255]) << 8) ^ (((uint)Si[(t0 >> 16) & 255]) << 16) ^ ((uint)Si[(r3 >> 24) & 255] << 24)) ^ kw[2]; + r3 = Inv_Mcol((uint)Si[r3 & 255] ^ (((uint)Si[(t2 >> 8) & 255]) << 8) ^ (((uint)Si[(t1 >> 16) & 255]) << 16) ^ ((uint)Si[(t0 >> 24) & 255] << 24)) ^ kw[3]; + kw = KW[r--]; + t0 = Inv_Mcol((uint)Si[r0 & 255] ^ (((uint)Si[(r3 >> 8) & 255]) << 8) ^ (((uint)Si[(r2 >> 16) & 255]) << 16) ^ ((uint)Si[(r1 >> 24) & 255] << 24)) ^ kw[0]; + t1 = Inv_Mcol((uint)Si[r1 & 255] ^ (((uint)Si[(r0 >> 8) & 255]) << 8) ^ (((uint)Si[(r3 >> 16) & 255]) << 16) ^ ((uint)Si[(r2 >> 24) & 255] << 24)) ^ kw[1]; + t2 = Inv_Mcol((uint)Si[r2 & 255] ^ (((uint)Si[(r1 >> 8) & 255]) << 8) ^ (((uint)Si[(r0 >> 16) & 255]) << 16) ^ ((uint)Si[(r3 >> 24) & 255] << 24)) ^ kw[2]; + r3 = Inv_Mcol((uint)Si[r3 & 255] ^ (((uint)Si[(r2 >> 8) & 255]) << 8) ^ (((uint)Si[(r1 >> 16) & 255]) << 16) ^ ((uint)Si[(r0 >> 24) & 255] << 24)) ^ kw[3]; + } + + kw = KW[1]; + r0 = Inv_Mcol((uint)Si[t0 & 255] ^ (((uint)Si[(r3 >> 8) & 255]) << 8) ^ (((uint)Si[(t2 >> 16) & 255]) << 16) ^ ((uint)Si[(t1 >> 24) & 255] << 24)) ^ kw[0]; + r1 = Inv_Mcol((uint)Si[t1 & 255] ^ (((uint)Si[(t0 >> 8) & 255]) << 8) ^ (((uint)Si[(r3 >> 16) & 255]) << 16) ^ ((uint)Si[(t2 >> 24) & 255] << 24)) ^ kw[1]; + r2 = Inv_Mcol((uint)Si[t2 & 255] ^ (((uint)Si[(t1 >> 8) & 255]) << 8) ^ (((uint)Si[(t0 >> 16) & 255]) << 16) ^ ((uint)Si[(r3 >> 24) & 255] << 24)) ^ kw[2]; + r3 = Inv_Mcol((uint)Si[r3 & 255] ^ (((uint)Si[(t2 >> 8) & 255]) << 8) ^ (((uint)Si[(t1 >> 16) & 255]) << 16) ^ ((uint)Si[(t0 >> 24) & 255] << 24)) ^ kw[3]; + + // the final round's table is a simple function of Si + + kw = KW[0]; + C0 = (uint)Si[r0 & 255] ^ (((uint)Si[(r3 >> 8) & 255]) << 8) ^ (((uint)Si[(r2 >> 16) & 255]) << 16) ^ (((uint)Si[(r1 >> 24) & 255]) << 24) ^ kw[0]; + C1 = (uint)Si[r1 & 255] ^ (((uint)Si[(r0 >> 8) & 255]) << 8) ^ (((uint)Si[(r3 >> 16) & 255]) << 16) ^ (((uint)Si[(r2 >> 24) & 255]) << 24) ^ kw[1]; + C2 = (uint)Si[r2 & 255] ^ (((uint)Si[(r1 >> 8) & 255]) << 8) ^ (((uint)Si[(r0 >> 16) & 255]) << 16) ^ (((uint)Si[(r3 >> 24) & 255]) << 24) ^ kw[2]; + C3 = (uint)Si[r3 & 255] ^ (((uint)Si[(r2 >> 8) & 255]) << 8) ^ (((uint)Si[(r1 >> 16) & 255]) << 16) ^ (((uint)Si[(r0 >> 24) & 255]) << 24) ^ kw[3]; + + Pack.UInt32_To_LE(C0, output, outOff + 0); + Pack.UInt32_To_LE(C1, output, outOff + 4); + Pack.UInt32_To_LE(C2, output, outOff + 8); + Pack.UInt32_To_LE(C3, output, outOff + 12); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/AesLightEngine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/AesLightEngine.cs.meta new file mode 100644 index 0000000..0b4ab70 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/AesLightEngine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: eb2749a473e5f9046a118c92c3a0b6b0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/AesWrapEngine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/AesWrapEngine.cs new file mode 100644 index 0000000..1ce0154 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/AesWrapEngine.cs @@ -0,0 +1,16 @@ +namespace Org.BouncyCastle.Crypto.Engines +{ + /// + /// An implementation of the AES Key Wrapper from the NIST Key Wrap Specification. + ///

+ /// For further details see: http://csrc.nist.gov/encryption/kms/key-wrap.pdf. + /// + public class AesWrapEngine + : Rfc3394WrapEngine + { + public AesWrapEngine() + : base(new AesEngine()) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/AesWrapEngine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/AesWrapEngine.cs.meta new file mode 100644 index 0000000..2d74052 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/AesWrapEngine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2e8b988fa599e324f96df603c8a5c69b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/AriaEngine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/AriaEngine.cs new file mode 100644 index 0000000..2f94dc0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/AriaEngine.cs @@ -0,0 +1,421 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * RFC 5794. + * + * ARIA is a 128-bit block cipher with 128-, 192-, and 256-bit keys. + */ + public class AriaEngine + : IBlockCipher + { + private static readonly byte[][] C = { Hex.DecodeStrict("517cc1b727220a94fe13abe8fa9a6ee0"), + Hex.DecodeStrict("6db14acc9e21c820ff28b1d5ef5de2b0"), Hex.DecodeStrict("db92371d2126e9700324977504e8c90e") }; + + private static readonly byte[] SB1_sbox = { (byte)0x63, (byte)0x7c, (byte)0x77, (byte)0x7b, (byte)0xf2, (byte)0x6b, + (byte)0x6f, (byte)0xc5, (byte)0x30, (byte)0x01, (byte)0x67, (byte)0x2b, (byte)0xfe, (byte)0xd7, (byte)0xab, + (byte)0x76, (byte)0xca, (byte)0x82, (byte)0xc9, (byte)0x7d, (byte)0xfa, (byte)0x59, (byte)0x47, (byte)0xf0, + (byte)0xad, (byte)0xd4, (byte)0xa2, (byte)0xaf, (byte)0x9c, (byte)0xa4, (byte)0x72, (byte)0xc0, (byte)0xb7, + (byte)0xfd, (byte)0x93, (byte)0x26, (byte)0x36, (byte)0x3f, (byte)0xf7, (byte)0xcc, (byte)0x34, (byte)0xa5, + (byte)0xe5, (byte)0xf1, (byte)0x71, (byte)0xd8, (byte)0x31, (byte)0x15, (byte)0x04, (byte)0xc7, (byte)0x23, + (byte)0xc3, (byte)0x18, (byte)0x96, (byte)0x05, (byte)0x9a, (byte)0x07, (byte)0x12, (byte)0x80, (byte)0xe2, + (byte)0xeb, (byte)0x27, (byte)0xb2, (byte)0x75, (byte)0x09, (byte)0x83, (byte)0x2c, (byte)0x1a, (byte)0x1b, + (byte)0x6e, (byte)0x5a, (byte)0xa0, (byte)0x52, (byte)0x3b, (byte)0xd6, (byte)0xb3, (byte)0x29, (byte)0xe3, + (byte)0x2f, (byte)0x84, (byte)0x53, (byte)0xd1, (byte)0x00, (byte)0xed, (byte)0x20, (byte)0xfc, (byte)0xb1, + (byte)0x5b, (byte)0x6a, (byte)0xcb, (byte)0xbe, (byte)0x39, (byte)0x4a, (byte)0x4c, (byte)0x58, (byte)0xcf, + (byte)0xd0, (byte)0xef, (byte)0xaa, (byte)0xfb, (byte)0x43, (byte)0x4d, (byte)0x33, (byte)0x85, (byte)0x45, + (byte)0xf9, (byte)0x02, (byte)0x7f, (byte)0x50, (byte)0x3c, (byte)0x9f, (byte)0xa8, (byte)0x51, (byte)0xa3, + (byte)0x40, (byte)0x8f, (byte)0x92, (byte)0x9d, (byte)0x38, (byte)0xf5, (byte)0xbc, (byte)0xb6, (byte)0xda, + (byte)0x21, (byte)0x10, (byte)0xff, (byte)0xf3, (byte)0xd2, (byte)0xcd, (byte)0x0c, (byte)0x13, (byte)0xec, + (byte)0x5f, (byte)0x97, (byte)0x44, (byte)0x17, (byte)0xc4, (byte)0xa7, (byte)0x7e, (byte)0x3d, (byte)0x64, + (byte)0x5d, (byte)0x19, (byte)0x73, (byte)0x60, (byte)0x81, (byte)0x4f, (byte)0xdc, (byte)0x22, (byte)0x2a, + (byte)0x90, (byte)0x88, (byte)0x46, (byte)0xee, (byte)0xb8, (byte)0x14, (byte)0xde, (byte)0x5e, (byte)0x0b, + (byte)0xdb, (byte)0xe0, (byte)0x32, (byte)0x3a, (byte)0x0a, (byte)0x49, (byte)0x06, (byte)0x24, (byte)0x5c, + (byte)0xc2, (byte)0xd3, (byte)0xac, (byte)0x62, (byte)0x91, (byte)0x95, (byte)0xe4, (byte)0x79, (byte)0xe7, + (byte)0xc8, (byte)0x37, (byte)0x6d, (byte)0x8d, (byte)0xd5, (byte)0x4e, (byte)0xa9, (byte)0x6c, (byte)0x56, + (byte)0xf4, (byte)0xea, (byte)0x65, (byte)0x7a, (byte)0xae, (byte)0x08, (byte)0xba, (byte)0x78, (byte)0x25, + (byte)0x2e, (byte)0x1c, (byte)0xa6, (byte)0xb4, (byte)0xc6, (byte)0xe8, (byte)0xdd, (byte)0x74, (byte)0x1f, + (byte)0x4b, (byte)0xbd, (byte)0x8b, (byte)0x8a, (byte)0x70, (byte)0x3e, (byte)0xb5, (byte)0x66, (byte)0x48, + (byte)0x03, (byte)0xf6, (byte)0x0e, (byte)0x61, (byte)0x35, (byte)0x57, (byte)0xb9, (byte)0x86, (byte)0xc1, + (byte)0x1d, (byte)0x9e, (byte)0xe1, (byte)0xf8, (byte)0x98, (byte)0x11, (byte)0x69, (byte)0xd9, (byte)0x8e, + (byte)0x94, (byte)0x9b, (byte)0x1e, (byte)0x87, (byte)0xe9, (byte)0xce, (byte)0x55, (byte)0x28, (byte)0xdf, + (byte)0x8c, (byte)0xa1, (byte)0x89, (byte)0x0d, (byte)0xbf, (byte)0xe6, (byte)0x42, (byte)0x68, (byte)0x41, + (byte)0x99, (byte)0x2d, (byte)0x0f, (byte)0xb0, (byte)0x54, (byte)0xbb, (byte)0x16 }; + + private static readonly byte[] SB2_sbox = { (byte)0xe2, (byte)0x4e, (byte)0x54, (byte)0xfc, (byte)0x94, (byte)0xc2, + (byte)0x4a, (byte)0xcc, (byte)0x62, (byte)0x0d, (byte)0x6a, (byte)0x46, (byte)0x3c, (byte)0x4d, (byte)0x8b, + (byte)0xd1, (byte)0x5e, (byte)0xfa, (byte)0x64, (byte)0xcb, (byte)0xb4, (byte)0x97, (byte)0xbe, (byte)0x2b, + (byte)0xbc, (byte)0x77, (byte)0x2e, (byte)0x03, (byte)0xd3, (byte)0x19, (byte)0x59, (byte)0xc1, (byte)0x1d, + (byte)0x06, (byte)0x41, (byte)0x6b, (byte)0x55, (byte)0xf0, (byte)0x99, (byte)0x69, (byte)0xea, (byte)0x9c, + (byte)0x18, (byte)0xae, (byte)0x63, (byte)0xdf, (byte)0xe7, (byte)0xbb, (byte)0x00, (byte)0x73, (byte)0x66, + (byte)0xfb, (byte)0x96, (byte)0x4c, (byte)0x85, (byte)0xe4, (byte)0x3a, (byte)0x09, (byte)0x45, (byte)0xaa, + (byte)0x0f, (byte)0xee, (byte)0x10, (byte)0xeb, (byte)0x2d, (byte)0x7f, (byte)0xf4, (byte)0x29, (byte)0xac, + (byte)0xcf, (byte)0xad, (byte)0x91, (byte)0x8d, (byte)0x78, (byte)0xc8, (byte)0x95, (byte)0xf9, (byte)0x2f, + (byte)0xce, (byte)0xcd, (byte)0x08, (byte)0x7a, (byte)0x88, (byte)0x38, (byte)0x5c, (byte)0x83, (byte)0x2a, + (byte)0x28, (byte)0x47, (byte)0xdb, (byte)0xb8, (byte)0xc7, (byte)0x93, (byte)0xa4, (byte)0x12, (byte)0x53, + (byte)0xff, (byte)0x87, (byte)0x0e, (byte)0x31, (byte)0x36, (byte)0x21, (byte)0x58, (byte)0x48, (byte)0x01, + (byte)0x8e, (byte)0x37, (byte)0x74, (byte)0x32, (byte)0xca, (byte)0xe9, (byte)0xb1, (byte)0xb7, (byte)0xab, + (byte)0x0c, (byte)0xd7, (byte)0xc4, (byte)0x56, (byte)0x42, (byte)0x26, (byte)0x07, (byte)0x98, (byte)0x60, + (byte)0xd9, (byte)0xb6, (byte)0xb9, (byte)0x11, (byte)0x40, (byte)0xec, (byte)0x20, (byte)0x8c, (byte)0xbd, + (byte)0xa0, (byte)0xc9, (byte)0x84, (byte)0x04, (byte)0x49, (byte)0x23, (byte)0xf1, (byte)0x4f, (byte)0x50, + (byte)0x1f, (byte)0x13, (byte)0xdc, (byte)0xd8, (byte)0xc0, (byte)0x9e, (byte)0x57, (byte)0xe3, (byte)0xc3, + (byte)0x7b, (byte)0x65, (byte)0x3b, (byte)0x02, (byte)0x8f, (byte)0x3e, (byte)0xe8, (byte)0x25, (byte)0x92, + (byte)0xe5, (byte)0x15, (byte)0xdd, (byte)0xfd, (byte)0x17, (byte)0xa9, (byte)0xbf, (byte)0xd4, (byte)0x9a, + (byte)0x7e, (byte)0xc5, (byte)0x39, (byte)0x67, (byte)0xfe, (byte)0x76, (byte)0x9d, (byte)0x43, (byte)0xa7, + (byte)0xe1, (byte)0xd0, (byte)0xf5, (byte)0x68, (byte)0xf2, (byte)0x1b, (byte)0x34, (byte)0x70, (byte)0x05, + (byte)0xa3, (byte)0x8a, (byte)0xd5, (byte)0x79, (byte)0x86, (byte)0xa8, (byte)0x30, (byte)0xc6, (byte)0x51, + (byte)0x4b, (byte)0x1e, (byte)0xa6, (byte)0x27, (byte)0xf6, (byte)0x35, (byte)0xd2, (byte)0x6e, (byte)0x24, + (byte)0x16, (byte)0x82, (byte)0x5f, (byte)0xda, (byte)0xe6, (byte)0x75, (byte)0xa2, (byte)0xef, (byte)0x2c, + (byte)0xb2, (byte)0x1c, (byte)0x9f, (byte)0x5d, (byte)0x6f, (byte)0x80, (byte)0x0a, (byte)0x72, (byte)0x44, + (byte)0x9b, (byte)0x6c, (byte)0x90, (byte)0x0b, (byte)0x5b, (byte)0x33, (byte)0x7d, (byte)0x5a, (byte)0x52, + (byte)0xf3, (byte)0x61, (byte)0xa1, (byte)0xf7, (byte)0xb0, (byte)0xd6, (byte)0x3f, (byte)0x7c, (byte)0x6d, + (byte)0xed, (byte)0x14, (byte)0xe0, (byte)0xa5, (byte)0x3d, (byte)0x22, (byte)0xb3, (byte)0xf8, (byte)0x89, + (byte)0xde, (byte)0x71, (byte)0x1a, (byte)0xaf, (byte)0xba, (byte)0xb5, (byte)0x81 }; + + private static readonly byte[] SB3_sbox = { (byte)0x52, (byte)0x09, (byte)0x6a, (byte)0xd5, (byte)0x30, (byte)0x36, + (byte)0xa5, (byte)0x38, (byte)0xbf, (byte)0x40, (byte)0xa3, (byte)0x9e, (byte)0x81, (byte)0xf3, (byte)0xd7, + (byte)0xfb, (byte)0x7c, (byte)0xe3, (byte)0x39, (byte)0x82, (byte)0x9b, (byte)0x2f, (byte)0xff, (byte)0x87, + (byte)0x34, (byte)0x8e, (byte)0x43, (byte)0x44, (byte)0xc4, (byte)0xde, (byte)0xe9, (byte)0xcb, (byte)0x54, + (byte)0x7b, (byte)0x94, (byte)0x32, (byte)0xa6, (byte)0xc2, (byte)0x23, (byte)0x3d, (byte)0xee, (byte)0x4c, + (byte)0x95, (byte)0x0b, (byte)0x42, (byte)0xfa, (byte)0xc3, (byte)0x4e, (byte)0x08, (byte)0x2e, (byte)0xa1, + (byte)0x66, (byte)0x28, (byte)0xd9, (byte)0x24, (byte)0xb2, (byte)0x76, (byte)0x5b, (byte)0xa2, (byte)0x49, + (byte)0x6d, (byte)0x8b, (byte)0xd1, (byte)0x25, (byte)0x72, (byte)0xf8, (byte)0xf6, (byte)0x64, (byte)0x86, + (byte)0x68, (byte)0x98, (byte)0x16, (byte)0xd4, (byte)0xa4, (byte)0x5c, (byte)0xcc, (byte)0x5d, (byte)0x65, + (byte)0xb6, (byte)0x92, (byte)0x6c, (byte)0x70, (byte)0x48, (byte)0x50, (byte)0xfd, (byte)0xed, (byte)0xb9, + (byte)0xda, (byte)0x5e, (byte)0x15, (byte)0x46, (byte)0x57, (byte)0xa7, (byte)0x8d, (byte)0x9d, (byte)0x84, + (byte)0x90, (byte)0xd8, (byte)0xab, (byte)0x00, (byte)0x8c, (byte)0xbc, (byte)0xd3, (byte)0x0a, (byte)0xf7, + (byte)0xe4, (byte)0x58, (byte)0x05, (byte)0xb8, (byte)0xb3, (byte)0x45, (byte)0x06, (byte)0xd0, (byte)0x2c, + (byte)0x1e, (byte)0x8f, (byte)0xca, (byte)0x3f, (byte)0x0f, (byte)0x02, (byte)0xc1, (byte)0xaf, (byte)0xbd, + (byte)0x03, (byte)0x01, (byte)0x13, (byte)0x8a, (byte)0x6b, (byte)0x3a, (byte)0x91, (byte)0x11, (byte)0x41, + (byte)0x4f, (byte)0x67, (byte)0xdc, (byte)0xea, (byte)0x97, (byte)0xf2, (byte)0xcf, (byte)0xce, (byte)0xf0, + (byte)0xb4, (byte)0xe6, (byte)0x73, (byte)0x96, (byte)0xac, (byte)0x74, (byte)0x22, (byte)0xe7, (byte)0xad, + (byte)0x35, (byte)0x85, (byte)0xe2, (byte)0xf9, (byte)0x37, (byte)0xe8, (byte)0x1c, (byte)0x75, (byte)0xdf, + (byte)0x6e, (byte)0x47, (byte)0xf1, (byte)0x1a, (byte)0x71, (byte)0x1d, (byte)0x29, (byte)0xc5, (byte)0x89, + (byte)0x6f, (byte)0xb7, (byte)0x62, (byte)0x0e, (byte)0xaa, (byte)0x18, (byte)0xbe, (byte)0x1b, (byte)0xfc, + (byte)0x56, (byte)0x3e, (byte)0x4b, (byte)0xc6, (byte)0xd2, (byte)0x79, (byte)0x20, (byte)0x9a, (byte)0xdb, + (byte)0xc0, (byte)0xfe, (byte)0x78, (byte)0xcd, (byte)0x5a, (byte)0xf4, (byte)0x1f, (byte)0xdd, (byte)0xa8, + (byte)0x33, (byte)0x88, (byte)0x07, (byte)0xc7, (byte)0x31, (byte)0xb1, (byte)0x12, (byte)0x10, (byte)0x59, + (byte)0x27, (byte)0x80, (byte)0xec, (byte)0x5f, (byte)0x60, (byte)0x51, (byte)0x7f, (byte)0xa9, (byte)0x19, + (byte)0xb5, (byte)0x4a, (byte)0x0d, (byte)0x2d, (byte)0xe5, (byte)0x7a, (byte)0x9f, (byte)0x93, (byte)0xc9, + (byte)0x9c, (byte)0xef, (byte)0xa0, (byte)0xe0, (byte)0x3b, (byte)0x4d, (byte)0xae, (byte)0x2a, (byte)0xf5, + (byte)0xb0, (byte)0xc8, (byte)0xeb, (byte)0xbb, (byte)0x3c, (byte)0x83, (byte)0x53, (byte)0x99, (byte)0x61, + (byte)0x17, (byte)0x2b, (byte)0x04, (byte)0x7e, (byte)0xba, (byte)0x77, (byte)0xd6, (byte)0x26, (byte)0xe1, + (byte)0x69, (byte)0x14, (byte)0x63, (byte)0x55, (byte)0x21, (byte)0x0c, (byte)0x7d }; + + private static readonly byte[] SB4_sbox = { (byte)0x30, (byte)0x68, (byte)0x99, (byte)0x1b, (byte)0x87, (byte)0xb9, + (byte)0x21, (byte)0x78, (byte)0x50, (byte)0x39, (byte)0xdb, (byte)0xe1, (byte)0x72, (byte)0x9, (byte)0x62, + (byte)0x3c, (byte)0x3e, (byte)0x7e, (byte)0x5e, (byte)0x8e, (byte)0xf1, (byte)0xa0, (byte)0xcc, (byte)0xa3, + (byte)0x2a, (byte)0x1d, (byte)0xfb, (byte)0xb6, (byte)0xd6, (byte)0x20, (byte)0xc4, (byte)0x8d, (byte)0x81, + (byte)0x65, (byte)0xf5, (byte)0x89, (byte)0xcb, (byte)0x9d, (byte)0x77, (byte)0xc6, (byte)0x57, (byte)0x43, + (byte)0x56, (byte)0x17, (byte)0xd4, (byte)0x40, (byte)0x1a, (byte)0x4d, (byte)0xc0, (byte)0x63, (byte)0x6c, + (byte)0xe3, (byte)0xb7, (byte)0xc8, (byte)0x64, (byte)0x6a, (byte)0x53, (byte)0xaa, (byte)0x38, (byte)0x98, + (byte)0x0c, (byte)0xf4, (byte)0x9b, (byte)0xed, (byte)0x7f, (byte)0x22, (byte)0x76, (byte)0xaf, (byte)0xdd, + (byte)0x3a, (byte)0x0b, (byte)0x58, (byte)0x67, (byte)0x88, (byte)0x06, (byte)0xc3, (byte)0x35, (byte)0x0d, + (byte)0x01, (byte)0x8b, (byte)0x8c, (byte)0xc2, (byte)0xe6, (byte)0x5f, (byte)0x02, (byte)0x24, (byte)0x75, + (byte)0x93, (byte)0x66, (byte)0x1e, (byte)0xe5, (byte)0xe2, (byte)0x54, (byte)0xd8, (byte)0x10, (byte)0xce, + (byte)0x7a, (byte)0xe8, (byte)0x08, (byte)0x2c, (byte)0x12, (byte)0x97, (byte)0x32, (byte)0xab, (byte)0xb4, + (byte)0x27, (byte)0x0a, (byte)0x23, (byte)0xdf, (byte)0xef, (byte)0xca, (byte)0xd9, (byte)0xb8, (byte)0xfa, + (byte)0xdc, (byte)0x31, (byte)0x6b, (byte)0xd1, (byte)0xad, (byte)0x19, (byte)0x49, (byte)0xbd, (byte)0x51, + (byte)0x96, (byte)0xee, (byte)0xe4, (byte)0xa8, (byte)0x41, (byte)0xda, (byte)0xff, (byte)0xcd, (byte)0x55, + (byte)0x86, (byte)0x36, (byte)0xbe, (byte)0x61, (byte)0x52, (byte)0xf8, (byte)0xbb, (byte)0x0e, (byte)0x82, + (byte)0x48, (byte)0x69, (byte)0x9a, (byte)0xe0, (byte)0x47, (byte)0x9e, (byte)0x5c, (byte)0x04, (byte)0x4b, + (byte)0x34, (byte)0x15, (byte)0x79, (byte)0x26, (byte)0xa7, (byte)0xde, (byte)0x29, (byte)0xae, (byte)0x92, + (byte)0xd7, (byte)0x84, (byte)0xe9, (byte)0xd2, (byte)0xba, (byte)0x5d, (byte)0xf3, (byte)0xc5, (byte)0xb0, + (byte)0xbf, (byte)0xa4, (byte)0x3b, (byte)0x71, (byte)0x44, (byte)0x46, (byte)0x2b, (byte)0xfc, (byte)0xeb, + (byte)0x6f, (byte)0xd5, (byte)0xf6, (byte)0x14, (byte)0xfe, (byte)0x7c, (byte)0x70, (byte)0x5a, (byte)0x7d, + (byte)0xfd, (byte)0x2f, (byte)0x18, (byte)0x83, (byte)0x16, (byte)0xa5, (byte)0x91, (byte)0x1f, (byte)0x05, + (byte)0x95, (byte)0x74, (byte)0xa9, (byte)0xc1, (byte)0x5b, (byte)0x4a, (byte)0x85, (byte)0x6d, (byte)0x13, + (byte)0x07, (byte)0x4f, (byte)0x4e, (byte)0x45, (byte)0xb2, (byte)0x0f, (byte)0xc9, (byte)0x1c, (byte)0xa6, + (byte)0xbc, (byte)0xec, (byte)0x73, (byte)0x90, (byte)0x7b, (byte)0xcf, (byte)0x59, (byte)0x8f, (byte)0xa1, + (byte)0xf9, (byte)0x2d, (byte)0xf2, (byte)0xb1, (byte)0x00, (byte)0x94, (byte)0x37, (byte)0x9f, (byte)0xd0, + (byte)0x2e, (byte)0x9c, (byte)0x6e, (byte)0x28, (byte)0x3f, (byte)0x80, (byte)0xf0, (byte)0x3d, (byte)0xd3, + (byte)0x25, (byte)0x8a, (byte)0xb5, (byte)0xe7, (byte)0x42, (byte)0xb3, (byte)0xc7, (byte)0xea, (byte)0xf7, + (byte)0x4c, (byte)0x11, (byte)0x33, (byte)0x03, (byte)0xa2, (byte)0xac, (byte)0x60 }; + + protected const int BlockSize = 16; + + private byte[][] m_roundKeys; + + public virtual void Init(bool forEncryption, ICipherParameters parameters) + { + KeyParameter keyParameter = parameters as KeyParameter; + + if (keyParameter == null) + throw new ArgumentException("invalid parameter passed to ARIA init - " + + Platform.GetTypeName(parameters)); + + this.m_roundKeys = KeySchedule(forEncryption, keyParameter.GetKey()); + } + + public virtual string AlgorithmName + { + get { return "ARIA"; } + } + + public virtual bool IsPartialBlockOkay + { + get { return false; } + } + + public virtual int GetBlockSize() + { + return BlockSize; + } + + public virtual int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff) + { + if (m_roundKeys == null) + throw new InvalidOperationException("ARIA engine not initialised"); + + Check.DataLength(input, inOff, BlockSize, "input buffer too short"); + Check.OutputLength(output, outOff, BlockSize, "output buffer too short"); + + byte[] z = new byte[BlockSize]; + Array.Copy(input, inOff, z, 0, BlockSize); + + int i = 0, rounds = m_roundKeys.Length - 3; + while (i < rounds) + { + FO(z, m_roundKeys[i++]); + FE(z, m_roundKeys[i++]); + } + + FO(z, m_roundKeys[i++]); + Xor(z, m_roundKeys[i++]); + SL2(z); + Xor(z, m_roundKeys[i]); + + Array.Copy(z, 0, output, outOff, BlockSize); + + return BlockSize; + } + + public virtual void Reset() + { + // Empty + } + + protected static void A(byte[] z) + { + byte x0 = z[0], x1 = z[1], x2 = z[2], x3 = z[3], x4 = z[4], x5 = z[5], x6 = z[6], x7 = z[7], x8 = z[8], + x9 = z[9], x10 = z[10], x11 = z[11], x12 = z[12], x13 = z[13], x14 = z[14], x15 = z[15]; + + z[0] = (byte)(x3 ^ x4 ^ x6 ^ x8 ^ x9 ^ x13 ^ x14); + z[1] = (byte)(x2 ^ x5 ^ x7 ^ x8 ^ x9 ^ x12 ^ x15); + z[2] = (byte)(x1 ^ x4 ^ x6 ^ x10 ^ x11 ^ x12 ^ x15); + z[3] = (byte)(x0 ^ x5 ^ x7 ^ x10 ^ x11 ^ x13 ^ x14); + z[4] = (byte)(x0 ^ x2 ^ x5 ^ x8 ^ x11 ^ x14 ^ x15); + z[5] = (byte)(x1 ^ x3 ^ x4 ^ x9 ^ x10 ^ x14 ^ x15); + z[6] = (byte)(x0 ^ x2 ^ x7 ^ x9 ^ x10 ^ x12 ^ x13); + z[7] = (byte)(x1 ^ x3 ^ x6 ^ x8 ^ x11 ^ x12 ^ x13); + z[8] = (byte)(x0 ^ x1 ^ x4 ^ x7 ^ x10 ^ x13 ^ x15); + z[9] = (byte)(x0 ^ x1 ^ x5 ^ x6 ^ x11 ^ x12 ^ x14); + z[10] = (byte)(x2 ^ x3 ^ x5 ^ x6 ^ x8 ^ x13 ^ x15); + z[11] = (byte)(x2 ^ x3 ^ x4 ^ x7 ^ x9 ^ x12 ^ x14); + z[12] = (byte)(x1 ^ x2 ^ x6 ^ x7 ^ x9 ^ x11 ^ x12); + z[13] = (byte)(x0 ^ x3 ^ x6 ^ x7 ^ x8 ^ x10 ^ x13); + z[14] = (byte)(x0 ^ x3 ^ x4 ^ x5 ^ x9 ^ x11 ^ x14); + z[15] = (byte)(x1 ^ x2 ^ x4 ^ x5 ^ x8 ^ x10 ^ x15); + } + + protected static void FE(byte[] D, byte[] RK) + { + Xor(D, RK); + SL2(D); + A(D); + } + + protected static void FO(byte[] D, byte[] RK) + { + Xor(D, RK); + SL1(D); + A(D); + } + + protected static byte[][] KeySchedule(bool forEncryption, byte[] K) + { + int keyLen = K.Length; + if (keyLen < 16 || keyLen > 32 || (keyLen & 7) != 0) + throw new ArgumentException("Key length not 128/192/256 bits."); + + int keyLenIdx = (keyLen >> 3) - 2; + + byte[] CK1 = C[keyLenIdx]; + byte[] CK2 = C[(keyLenIdx + 1) % 3]; + byte[] CK3 = C[(keyLenIdx + 2) % 3]; + + byte[] KL = new byte[16], KR = new byte[16]; + Array.Copy(K, 0, KL, 0, 16); + Array.Copy(K, 16, KR, 0, keyLen - 16); + + byte[] W0 = new byte[16]; + byte[] W1 = new byte[16]; + byte[] W2 = new byte[16]; + byte[] W3 = new byte[16]; + + Array.Copy(KL, 0, W0, 0, 16); + + Array.Copy(W0, 0, W1, 0, 16); + FO(W1, CK1); + Xor(W1, KR); + + Array.Copy(W1, 0, W2, 0, 16); + FE(W2, CK2); + Xor(W2, W0); + + Array.Copy(W2, 0, W3, 0, 16); + FO(W3, CK3); + Xor(W3, W1); + + int numRounds = 12 + (keyLenIdx * 2); + byte[][] rks = new byte[numRounds + 1][]; + + rks[0] = KeyScheduleRound(W0, W1, 19); + rks[1] = KeyScheduleRound(W1, W2, 19); + rks[2] = KeyScheduleRound(W2, W3, 19); + rks[3] = KeyScheduleRound(W3, W0, 19); + + rks[4] = KeyScheduleRound(W0, W1, 31); + rks[5] = KeyScheduleRound(W1, W2, 31); + rks[6] = KeyScheduleRound(W2, W3, 31); + rks[7] = KeyScheduleRound(W3, W0, 31); + + rks[8] = KeyScheduleRound(W0, W1, 67); + rks[9] = KeyScheduleRound(W1, W2, 67); + rks[10] = KeyScheduleRound(W2, W3, 67); + rks[11] = KeyScheduleRound(W3, W0, 67); + + rks[12] = KeyScheduleRound(W0, W1, 97); + if (numRounds > 12) + { + rks[13] = KeyScheduleRound(W1, W2, 97); + rks[14] = KeyScheduleRound(W2, W3, 97); + if (numRounds > 14) + { + rks[15] = KeyScheduleRound(W3, W0, 97); + + rks[16] = KeyScheduleRound(W0, W1, 109); + } + } + + if (!forEncryption) + { + ReverseKeys(rks); + + for (int i = 1; i < numRounds; ++i) + { + A(rks[i]); + } + } + + return rks; + } + + protected static byte[] KeyScheduleRound(byte[] w, byte[] wr, int n) + { + byte[] rk = new byte[16]; + + int off = n >> 3, right = n & 7, left = 8 - right; + + int hi = wr[15 - off] & 0xFF; + + for (int to = 0; to < 16; ++to) + { + int lo = wr[(to - off) & 0xF] & 0xFF; + + int b = (hi << left) | (lo >> right); + b ^= (w[to] & 0xFF); + + rk[to] = (byte)b; + + hi = lo; + } + + return rk; + } + + protected static void ReverseKeys(byte[][] keys) + { + int length = keys.Length, limit = length / 2, last = length - 1; + for (int i = 0; i < limit; ++i) + { + byte[] t = keys[i]; + keys[i] = keys[last - i]; + keys[last - i] = t; + } + } + + protected static byte SB1(byte x) + { + return SB1_sbox[x & 0xFF]; + } + + protected static byte SB2(byte x) + { + return SB2_sbox[x & 0xFF]; + } + + protected static byte SB3(byte x) + { + return SB3_sbox[x & 0xFF]; + } + + protected static byte SB4(byte x) + { + return SB4_sbox[x & 0xFF]; + } + + protected static void SL1(byte[] z) + { + z[0] = SB1(z[0]); + z[1] = SB2(z[1]); + z[2] = SB3(z[2]); + z[3] = SB4(z[3]); + z[4] = SB1(z[4]); + z[5] = SB2(z[5]); + z[6] = SB3(z[6]); + z[7] = SB4(z[7]); + z[8] = SB1(z[8]); + z[9] = SB2(z[9]); + z[10] = SB3(z[10]); + z[11] = SB4(z[11]); + z[12] = SB1(z[12]); + z[13] = SB2(z[13]); + z[14] = SB3(z[14]); + z[15] = SB4(z[15]); + } + + protected static void SL2(byte[] z) + { + z[0] = SB3(z[0]); + z[1] = SB4(z[1]); + z[2] = SB1(z[2]); + z[3] = SB2(z[3]); + z[4] = SB3(z[4]); + z[5] = SB4(z[5]); + z[6] = SB1(z[6]); + z[7] = SB2(z[7]); + z[8] = SB3(z[8]); + z[9] = SB4(z[9]); + z[10] = SB1(z[10]); + z[11] = SB2(z[11]); + z[12] = SB3(z[12]); + z[13] = SB4(z[13]); + z[14] = SB1(z[14]); + z[15] = SB2(z[15]); + } + + protected static void Xor(byte[] z, byte[] x) + { + for (int i = 0; i < 16; ++i) + { + z[i] ^= x[i]; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/AriaEngine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/AriaEngine.cs.meta new file mode 100644 index 0000000..d29bd75 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/AriaEngine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1485489dd3006da4abcd0e92c3d137ab +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/BlowfishEngine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/BlowfishEngine.cs new file mode 100644 index 0000000..1b3dd97 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/BlowfishEngine.cs @@ -0,0 +1,558 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * A class that provides Blowfish key encryption operations, + * such as encoding data and generating keys. + * All the algorithms herein are from Applied Cryptography + * and implement a simplified cryptography interface. + */ + public sealed class BlowfishEngine + : IBlockCipher + { + private readonly static uint[] KP = + { + 0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344, + 0xA4093822, 0x299F31D0, 0x082EFA98, 0xEC4E6C89, + 0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C, + 0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917, + 0x9216D5D9, 0x8979FB1B + }, + KS0 = + { + 0xD1310BA6, 0x98DFB5AC, 0x2FFD72DB, 0xD01ADFB7, + 0xB8E1AFED, 0x6A267E96, 0xBA7C9045, 0xF12C7F99, + 0x24A19947, 0xB3916CF7, 0x0801F2E2, 0x858EFC16, + 0x636920D8, 0x71574E69, 0xA458FEA3, 0xF4933D7E, + 0x0D95748F, 0x728EB658, 0x718BCD58, 0x82154AEE, + 0x7B54A41D, 0xC25A59B5, 0x9C30D539, 0x2AF26013, + 0xC5D1B023, 0x286085F0, 0xCA417918, 0xB8DB38EF, + 0x8E79DCB0, 0x603A180E, 0x6C9E0E8B, 0xB01E8A3E, + 0xD71577C1, 0xBD314B27, 0x78AF2FDA, 0x55605C60, + 0xE65525F3, 0xAA55AB94, 0x57489862, 0x63E81440, + 0x55CA396A, 0x2AAB10B6, 0xB4CC5C34, 0x1141E8CE, + 0xA15486AF, 0x7C72E993, 0xB3EE1411, 0x636FBC2A, + 0x2BA9C55D, 0x741831F6, 0xCE5C3E16, 0x9B87931E, + 0xAFD6BA33, 0x6C24CF5C, 0x7A325381, 0x28958677, + 0x3B8F4898, 0x6B4BB9AF, 0xC4BFE81B, 0x66282193, + 0x61D809CC, 0xFB21A991, 0x487CAC60, 0x5DEC8032, + 0xEF845D5D, 0xE98575B1, 0xDC262302, 0xEB651B88, + 0x23893E81, 0xD396ACC5, 0x0F6D6FF3, 0x83F44239, + 0x2E0B4482, 0xA4842004, 0x69C8F04A, 0x9E1F9B5E, + 0x21C66842, 0xF6E96C9A, 0x670C9C61, 0xABD388F0, + 0x6A51A0D2, 0xD8542F68, 0x960FA728, 0xAB5133A3, + 0x6EEF0B6C, 0x137A3BE4, 0xBA3BF050, 0x7EFB2A98, + 0xA1F1651D, 0x39AF0176, 0x66CA593E, 0x82430E88, + 0x8CEE8619, 0x456F9FB4, 0x7D84A5C3, 0x3B8B5EBE, + 0xE06F75D8, 0x85C12073, 0x401A449F, 0x56C16AA6, + 0x4ED3AA62, 0x363F7706, 0x1BFEDF72, 0x429B023D, + 0x37D0D724, 0xD00A1248, 0xDB0FEAD3, 0x49F1C09B, + 0x075372C9, 0x80991B7B, 0x25D479D8, 0xF6E8DEF7, + 0xE3FE501A, 0xB6794C3B, 0x976CE0BD, 0x04C006BA, + 0xC1A94FB6, 0x409F60C4, 0x5E5C9EC2, 0x196A2463, + 0x68FB6FAF, 0x3E6C53B5, 0x1339B2EB, 0x3B52EC6F, + 0x6DFC511F, 0x9B30952C, 0xCC814544, 0xAF5EBD09, + 0xBEE3D004, 0xDE334AFD, 0x660F2807, 0x192E4BB3, + 0xC0CBA857, 0x45C8740F, 0xD20B5F39, 0xB9D3FBDB, + 0x5579C0BD, 0x1A60320A, 0xD6A100C6, 0x402C7279, + 0x679F25FE, 0xFB1FA3CC, 0x8EA5E9F8, 0xDB3222F8, + 0x3C7516DF, 0xFD616B15, 0x2F501EC8, 0xAD0552AB, + 0x323DB5FA, 0xFD238760, 0x53317B48, 0x3E00DF82, + 0x9E5C57BB, 0xCA6F8CA0, 0x1A87562E, 0xDF1769DB, + 0xD542A8F6, 0x287EFFC3, 0xAC6732C6, 0x8C4F5573, + 0x695B27B0, 0xBBCA58C8, 0xE1FFA35D, 0xB8F011A0, + 0x10FA3D98, 0xFD2183B8, 0x4AFCB56C, 0x2DD1D35B, + 0x9A53E479, 0xB6F84565, 0xD28E49BC, 0x4BFB9790, + 0xE1DDF2DA, 0xA4CB7E33, 0x62FB1341, 0xCEE4C6E8, + 0xEF20CADA, 0x36774C01, 0xD07E9EFE, 0x2BF11FB4, + 0x95DBDA4D, 0xAE909198, 0xEAAD8E71, 0x6B93D5A0, + 0xD08ED1D0, 0xAFC725E0, 0x8E3C5B2F, 0x8E7594B7, + 0x8FF6E2FB, 0xF2122B64, 0x8888B812, 0x900DF01C, + 0x4FAD5EA0, 0x688FC31C, 0xD1CFF191, 0xB3A8C1AD, + 0x2F2F2218, 0xBE0E1777, 0xEA752DFE, 0x8B021FA1, + 0xE5A0CC0F, 0xB56F74E8, 0x18ACF3D6, 0xCE89E299, + 0xB4A84FE0, 0xFD13E0B7, 0x7CC43B81, 0xD2ADA8D9, + 0x165FA266, 0x80957705, 0x93CC7314, 0x211A1477, + 0xE6AD2065, 0x77B5FA86, 0xC75442F5, 0xFB9D35CF, + 0xEBCDAF0C, 0x7B3E89A0, 0xD6411BD3, 0xAE1E7E49, + 0x00250E2D, 0x2071B35E, 0x226800BB, 0x57B8E0AF, + 0x2464369B, 0xF009B91E, 0x5563911D, 0x59DFA6AA, + 0x78C14389, 0xD95A537F, 0x207D5BA2, 0x02E5B9C5, + 0x83260376, 0x6295CFA9, 0x11C81968, 0x4E734A41, + 0xB3472DCA, 0x7B14A94A, 0x1B510052, 0x9A532915, + 0xD60F573F, 0xBC9BC6E4, 0x2B60A476, 0x81E67400, + 0x08BA6FB5, 0x571BE91F, 0xF296EC6B, 0x2A0DD915, + 0xB6636521, 0xE7B9F9B6, 0xFF34052E, 0xC5855664, + 0x53B02D5D, 0xA99F8FA1, 0x08BA4799, 0x6E85076A + }, + KS1 = + { + 0x4B7A70E9, 0xB5B32944, 0xDB75092E, 0xC4192623, + 0xAD6EA6B0, 0x49A7DF7D, 0x9CEE60B8, 0x8FEDB266, + 0xECAA8C71, 0x699A17FF, 0x5664526C, 0xC2B19EE1, + 0x193602A5, 0x75094C29, 0xA0591340, 0xE4183A3E, + 0x3F54989A, 0x5B429D65, 0x6B8FE4D6, 0x99F73FD6, + 0xA1D29C07, 0xEFE830F5, 0x4D2D38E6, 0xF0255DC1, + 0x4CDD2086, 0x8470EB26, 0x6382E9C6, 0x021ECC5E, + 0x09686B3F, 0x3EBAEFC9, 0x3C971814, 0x6B6A70A1, + 0x687F3584, 0x52A0E286, 0xB79C5305, 0xAA500737, + 0x3E07841C, 0x7FDEAE5C, 0x8E7D44EC, 0x5716F2B8, + 0xB03ADA37, 0xF0500C0D, 0xF01C1F04, 0x0200B3FF, + 0xAE0CF51A, 0x3CB574B2, 0x25837A58, 0xDC0921BD, + 0xD19113F9, 0x7CA92FF6, 0x94324773, 0x22F54701, + 0x3AE5E581, 0x37C2DADC, 0xC8B57634, 0x9AF3DDA7, + 0xA9446146, 0x0FD0030E, 0xECC8C73E, 0xA4751E41, + 0xE238CD99, 0x3BEA0E2F, 0x3280BBA1, 0x183EB331, + 0x4E548B38, 0x4F6DB908, 0x6F420D03, 0xF60A04BF, + 0x2CB81290, 0x24977C79, 0x5679B072, 0xBCAF89AF, + 0xDE9A771F, 0xD9930810, 0xB38BAE12, 0xDCCF3F2E, + 0x5512721F, 0x2E6B7124, 0x501ADDE6, 0x9F84CD87, + 0x7A584718, 0x7408DA17, 0xBC9F9ABC, 0xE94B7D8C, + 0xEC7AEC3A, 0xDB851DFA, 0x63094366, 0xC464C3D2, + 0xEF1C1847, 0x3215D908, 0xDD433B37, 0x24C2BA16, + 0x12A14D43, 0x2A65C451, 0x50940002, 0x133AE4DD, + 0x71DFF89E, 0x10314E55, 0x81AC77D6, 0x5F11199B, + 0x043556F1, 0xD7A3C76B, 0x3C11183B, 0x5924A509, + 0xF28FE6ED, 0x97F1FBFA, 0x9EBABF2C, 0x1E153C6E, + 0x86E34570, 0xEAE96FB1, 0x860E5E0A, 0x5A3E2AB3, + 0x771FE71C, 0x4E3D06FA, 0x2965DCB9, 0x99E71D0F, + 0x803E89D6, 0x5266C825, 0x2E4CC978, 0x9C10B36A, + 0xC6150EBA, 0x94E2EA78, 0xA5FC3C53, 0x1E0A2DF4, + 0xF2F74EA7, 0x361D2B3D, 0x1939260F, 0x19C27960, + 0x5223A708, 0xF71312B6, 0xEBADFE6E, 0xEAC31F66, + 0xE3BC4595, 0xA67BC883, 0xB17F37D1, 0x018CFF28, + 0xC332DDEF, 0xBE6C5AA5, 0x65582185, 0x68AB9802, + 0xEECEA50F, 0xDB2F953B, 0x2AEF7DAD, 0x5B6E2F84, + 0x1521B628, 0x29076170, 0xECDD4775, 0x619F1510, + 0x13CCA830, 0xEB61BD96, 0x0334FE1E, 0xAA0363CF, + 0xB5735C90, 0x4C70A239, 0xD59E9E0B, 0xCBAADE14, + 0xEECC86BC, 0x60622CA7, 0x9CAB5CAB, 0xB2F3846E, + 0x648B1EAF, 0x19BDF0CA, 0xA02369B9, 0x655ABB50, + 0x40685A32, 0x3C2AB4B3, 0x319EE9D5, 0xC021B8F7, + 0x9B540B19, 0x875FA099, 0x95F7997E, 0x623D7DA8, + 0xF837889A, 0x97E32D77, 0x11ED935F, 0x16681281, + 0x0E358829, 0xC7E61FD6, 0x96DEDFA1, 0x7858BA99, + 0x57F584A5, 0x1B227263, 0x9B83C3FF, 0x1AC24696, + 0xCDB30AEB, 0x532E3054, 0x8FD948E4, 0x6DBC3128, + 0x58EBF2EF, 0x34C6FFEA, 0xFE28ED61, 0xEE7C3C73, + 0x5D4A14D9, 0xE864B7E3, 0x42105D14, 0x203E13E0, + 0x45EEE2B6, 0xA3AAABEA, 0xDB6C4F15, 0xFACB4FD0, + 0xC742F442, 0xEF6ABBB5, 0x654F3B1D, 0x41CD2105, + 0xD81E799E, 0x86854DC7, 0xE44B476A, 0x3D816250, + 0xCF62A1F2, 0x5B8D2646, 0xFC8883A0, 0xC1C7B6A3, + 0x7F1524C3, 0x69CB7492, 0x47848A0B, 0x5692B285, + 0x095BBF00, 0xAD19489D, 0x1462B174, 0x23820E00, + 0x58428D2A, 0x0C55F5EA, 0x1DADF43E, 0x233F7061, + 0x3372F092, 0x8D937E41, 0xD65FECF1, 0x6C223BDB, + 0x7CDE3759, 0xCBEE7460, 0x4085F2A7, 0xCE77326E, + 0xA6078084, 0x19F8509E, 0xE8EFD855, 0x61D99735, + 0xA969A7AA, 0xC50C06C2, 0x5A04ABFC, 0x800BCADC, + 0x9E447A2E, 0xC3453484, 0xFDD56705, 0x0E1E9EC9, + 0xDB73DBD3, 0x105588CD, 0x675FDA79, 0xE3674340, + 0xC5C43465, 0x713E38D8, 0x3D28F89E, 0xF16DFF20, + 0x153E21E7, 0x8FB03D4A, 0xE6E39F2B, 0xDB83ADF7 + }, + KS2 = + { + 0xE93D5A68, 0x948140F7, 0xF64C261C, 0x94692934, + 0x411520F7, 0x7602D4F7, 0xBCF46B2E, 0xD4A20068, + 0xD4082471, 0x3320F46A, 0x43B7D4B7, 0x500061AF, + 0x1E39F62E, 0x97244546, 0x14214F74, 0xBF8B8840, + 0x4D95FC1D, 0x96B591AF, 0x70F4DDD3, 0x66A02F45, + 0xBFBC09EC, 0x03BD9785, 0x7FAC6DD0, 0x31CB8504, + 0x96EB27B3, 0x55FD3941, 0xDA2547E6, 0xABCA0A9A, + 0x28507825, 0x530429F4, 0x0A2C86DA, 0xE9B66DFB, + 0x68DC1462, 0xD7486900, 0x680EC0A4, 0x27A18DEE, + 0x4F3FFEA2, 0xE887AD8C, 0xB58CE006, 0x7AF4D6B6, + 0xAACE1E7C, 0xD3375FEC, 0xCE78A399, 0x406B2A42, + 0x20FE9E35, 0xD9F385B9, 0xEE39D7AB, 0x3B124E8B, + 0x1DC9FAF7, 0x4B6D1856, 0x26A36631, 0xEAE397B2, + 0x3A6EFA74, 0xDD5B4332, 0x6841E7F7, 0xCA7820FB, + 0xFB0AF54E, 0xD8FEB397, 0x454056AC, 0xBA489527, + 0x55533A3A, 0x20838D87, 0xFE6BA9B7, 0xD096954B, + 0x55A867BC, 0xA1159A58, 0xCCA92963, 0x99E1DB33, + 0xA62A4A56, 0x3F3125F9, 0x5EF47E1C, 0x9029317C, + 0xFDF8E802, 0x04272F70, 0x80BB155C, 0x05282CE3, + 0x95C11548, 0xE4C66D22, 0x48C1133F, 0xC70F86DC, + 0x07F9C9EE, 0x41041F0F, 0x404779A4, 0x5D886E17, + 0x325F51EB, 0xD59BC0D1, 0xF2BCC18F, 0x41113564, + 0x257B7834, 0x602A9C60, 0xDFF8E8A3, 0x1F636C1B, + 0x0E12B4C2, 0x02E1329E, 0xAF664FD1, 0xCAD18115, + 0x6B2395E0, 0x333E92E1, 0x3B240B62, 0xEEBEB922, + 0x85B2A20E, 0xE6BA0D99, 0xDE720C8C, 0x2DA2F728, + 0xD0127845, 0x95B794FD, 0x647D0862, 0xE7CCF5F0, + 0x5449A36F, 0x877D48FA, 0xC39DFD27, 0xF33E8D1E, + 0x0A476341, 0x992EFF74, 0x3A6F6EAB, 0xF4F8FD37, + 0xA812DC60, 0xA1EBDDF8, 0x991BE14C, 0xDB6E6B0D, + 0xC67B5510, 0x6D672C37, 0x2765D43B, 0xDCD0E804, + 0xF1290DC7, 0xCC00FFA3, 0xB5390F92, 0x690FED0B, + 0x667B9FFB, 0xCEDB7D9C, 0xA091CF0B, 0xD9155EA3, + 0xBB132F88, 0x515BAD24, 0x7B9479BF, 0x763BD6EB, + 0x37392EB3, 0xCC115979, 0x8026E297, 0xF42E312D, + 0x6842ADA7, 0xC66A2B3B, 0x12754CCC, 0x782EF11C, + 0x6A124237, 0xB79251E7, 0x06A1BBE6, 0x4BFB6350, + 0x1A6B1018, 0x11CAEDFA, 0x3D25BDD8, 0xE2E1C3C9, + 0x44421659, 0x0A121386, 0xD90CEC6E, 0xD5ABEA2A, + 0x64AF674E, 0xDA86A85F, 0xBEBFE988, 0x64E4C3FE, + 0x9DBC8057, 0xF0F7C086, 0x60787BF8, 0x6003604D, + 0xD1FD8346, 0xF6381FB0, 0x7745AE04, 0xD736FCCC, + 0x83426B33, 0xF01EAB71, 0xB0804187, 0x3C005E5F, + 0x77A057BE, 0xBDE8AE24, 0x55464299, 0xBF582E61, + 0x4E58F48F, 0xF2DDFDA2, 0xF474EF38, 0x8789BDC2, + 0x5366F9C3, 0xC8B38E74, 0xB475F255, 0x46FCD9B9, + 0x7AEB2661, 0x8B1DDF84, 0x846A0E79, 0x915F95E2, + 0x466E598E, 0x20B45770, 0x8CD55591, 0xC902DE4C, + 0xB90BACE1, 0xBB8205D0, 0x11A86248, 0x7574A99E, + 0xB77F19B6, 0xE0A9DC09, 0x662D09A1, 0xC4324633, + 0xE85A1F02, 0x09F0BE8C, 0x4A99A025, 0x1D6EFE10, + 0x1AB93D1D, 0x0BA5A4DF, 0xA186F20F, 0x2868F169, + 0xDCB7DA83, 0x573906FE, 0xA1E2CE9B, 0x4FCD7F52, + 0x50115E01, 0xA70683FA, 0xA002B5C4, 0x0DE6D027, + 0x9AF88C27, 0x773F8641, 0xC3604C06, 0x61A806B5, + 0xF0177A28, 0xC0F586E0, 0x006058AA, 0x30DC7D62, + 0x11E69ED7, 0x2338EA63, 0x53C2DD94, 0xC2C21634, + 0xBBCBEE56, 0x90BCB6DE, 0xEBFC7DA1, 0xCE591D76, + 0x6F05E409, 0x4B7C0188, 0x39720A3D, 0x7C927C24, + 0x86E3725F, 0x724D9DB9, 0x1AC15BB4, 0xD39EB8FC, + 0xED545578, 0x08FCA5B5, 0xD83D7CD3, 0x4DAD0FC4, + 0x1E50EF5E, 0xB161E6F8, 0xA28514D9, 0x6C51133C, + 0x6FD5C7E7, 0x56E14EC4, 0x362ABFCE, 0xDDC6C837, + 0xD79A3234, 0x92638212, 0x670EFA8E, 0x406000E0 + }, + KS3 = + { + 0x3A39CE37, 0xD3FAF5CF, 0xABC27737, 0x5AC52D1B, + 0x5CB0679E, 0x4FA33742, 0xD3822740, 0x99BC9BBE, + 0xD5118E9D, 0xBF0F7315, 0xD62D1C7E, 0xC700C47B, + 0xB78C1B6B, 0x21A19045, 0xB26EB1BE, 0x6A366EB4, + 0x5748AB2F, 0xBC946E79, 0xC6A376D2, 0x6549C2C8, + 0x530FF8EE, 0x468DDE7D, 0xD5730A1D, 0x4CD04DC6, + 0x2939BBDB, 0xA9BA4650, 0xAC9526E8, 0xBE5EE304, + 0xA1FAD5F0, 0x6A2D519A, 0x63EF8CE2, 0x9A86EE22, + 0xC089C2B8, 0x43242EF6, 0xA51E03AA, 0x9CF2D0A4, + 0x83C061BA, 0x9BE96A4D, 0x8FE51550, 0xBA645BD6, + 0x2826A2F9, 0xA73A3AE1, 0x4BA99586, 0xEF5562E9, + 0xC72FEFD3, 0xF752F7DA, 0x3F046F69, 0x77FA0A59, + 0x80E4A915, 0x87B08601, 0x9B09E6AD, 0x3B3EE593, + 0xE990FD5A, 0x9E34D797, 0x2CF0B7D9, 0x022B8B51, + 0x96D5AC3A, 0x017DA67D, 0xD1CF3ED6, 0x7C7D2D28, + 0x1F9F25CF, 0xADF2B89B, 0x5AD6B472, 0x5A88F54C, + 0xE029AC71, 0xE019A5E6, 0x47B0ACFD, 0xED93FA9B, + 0xE8D3C48D, 0x283B57CC, 0xF8D56629, 0x79132E28, + 0x785F0191, 0xED756055, 0xF7960E44, 0xE3D35E8C, + 0x15056DD4, 0x88F46DBA, 0x03A16125, 0x0564F0BD, + 0xC3EB9E15, 0x3C9057A2, 0x97271AEC, 0xA93A072A, + 0x1B3F6D9B, 0x1E6321F5, 0xF59C66FB, 0x26DCF319, + 0x7533D928, 0xB155FDF5, 0x03563482, 0x8ABA3CBB, + 0x28517711, 0xC20AD9F8, 0xABCC5167, 0xCCAD925F, + 0x4DE81751, 0x3830DC8E, 0x379D5862, 0x9320F991, + 0xEA7A90C2, 0xFB3E7BCE, 0x5121CE64, 0x774FBE32, + 0xA8B6E37E, 0xC3293D46, 0x48DE5369, 0x6413E680, + 0xA2AE0810, 0xDD6DB224, 0x69852DFD, 0x09072166, + 0xB39A460A, 0x6445C0DD, 0x586CDECF, 0x1C20C8AE, + 0x5BBEF7DD, 0x1B588D40, 0xCCD2017F, 0x6BB4E3BB, + 0xDDA26A7E, 0x3A59FF45, 0x3E350A44, 0xBCB4CDD5, + 0x72EACEA8, 0xFA6484BB, 0x8D6612AE, 0xBF3C6F47, + 0xD29BE463, 0x542F5D9E, 0xAEC2771B, 0xF64E6370, + 0x740E0D8D, 0xE75B1357, 0xF8721671, 0xAF537D5D, + 0x4040CB08, 0x4EB4E2CC, 0x34D2466A, 0x0115AF84, + 0xE1B00428, 0x95983A1D, 0x06B89FB4, 0xCE6EA048, + 0x6F3F3B82, 0x3520AB82, 0x011A1D4B, 0x277227F8, + 0x611560B1, 0xE7933FDC, 0xBB3A792B, 0x344525BD, + 0xA08839E1, 0x51CE794B, 0x2F32C9B7, 0xA01FBAC9, + 0xE01CC87E, 0xBCC7D1F6, 0xCF0111C3, 0xA1E8AAC7, + 0x1A908749, 0xD44FBD9A, 0xD0DADECB, 0xD50ADA38, + 0x0339C32A, 0xC6913667, 0x8DF9317C, 0xE0B12B4F, + 0xF79E59B7, 0x43F5BB3A, 0xF2D519FF, 0x27D9459C, + 0xBF97222C, 0x15E6FC2A, 0x0F91FC71, 0x9B941525, + 0xFAE59361, 0xCEB69CEB, 0xC2A86459, 0x12BAA8D1, + 0xB6C1075E, 0xE3056A0C, 0x10D25065, 0xCB03A442, + 0xE0EC6E0E, 0x1698DB3B, 0x4C98A0BE, 0x3278E964, + 0x9F1F9532, 0xE0D392DF, 0xD3A0342B, 0x8971F21E, + 0x1B0A7441, 0x4BA3348C, 0xC5BE7120, 0xC37632D8, + 0xDF359F8D, 0x9B992F2E, 0xE60B6F47, 0x0FE3F11D, + 0xE54CDA54, 0x1EDAD891, 0xCE6279CF, 0xCD3E7E6F, + 0x1618B166, 0xFD2C1D05, 0x848FD2C5, 0xF6FB2299, + 0xF523F357, 0xA6327623, 0x93A83531, 0x56CCCD02, + 0xACF08162, 0x5A75EBB5, 0x6E163697, 0x88D273CC, + 0xDE966292, 0x81B949D0, 0x4C50901B, 0x71C65614, + 0xE6C6C7BD, 0x327A140A, 0x45E1D006, 0xC3F27B9A, + 0xC9AA53FD, 0x62A80F00, 0xBB25BFE2, 0x35BDD2F6, + 0x71126905, 0xB2040222, 0xB6CBCF7C, 0xCD769C2B, + 0x53113EC0, 0x1640E3D3, 0x38ABBD60, 0x2547ADF0, + 0xBA38209C, 0xF746CE76, 0x77AFA1C5, 0x20756060, + 0x85CBFE4E, 0x8AE88DD8, 0x7AAAF9B0, 0x4CF9AA7E, + 0x1948C25C, 0x02FB8A8C, 0x01C36AE4, 0xD6EBE1F9, + 0x90D4F869, 0xA65CDEA0, 0x3F09252D, 0xC208E69F, + 0xB74E6132, 0xCE77E25B, 0x578FDFE3, 0x3AC372E6 + }; + + //==================================== + // Useful constants + //==================================== + + private static readonly int ROUNDS = 16; + private const int BLOCK_SIZE = 8; // bytes = 64 bits + private static readonly int SBOX_SK = 256; + private static readonly int P_SZ = ROUNDS+2; + + private readonly uint[] S0, S1, S2, S3; // the s-boxes + private readonly uint[] P; // the p-array + + private bool encrypting; + + private byte[] workingKey; + + public BlowfishEngine() + { + S0 = new uint[SBOX_SK]; + S1 = new uint[SBOX_SK]; + S2 = new uint[SBOX_SK]; + S3 = new uint[SBOX_SK]; + P = new uint[P_SZ]; + } + + /** + * initialise a Blowfish cipher. + * + * @param forEncryption whether or not we are for encryption. + * @param parameters the parameters required to set up the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (!(parameters is KeyParameter)) + throw new ArgumentException("invalid parameter passed to Blowfish init - " + Platform.GetTypeName(parameters)); + + this.encrypting = forEncryption; + this.workingKey = ((KeyParameter)parameters).GetKey(); + SetKey(this.workingKey); + } + + public string AlgorithmName + { + get { return "Blowfish"; } + } + + public bool IsPartialBlockOkay + { + get { return false; } + } + + public int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + if (workingKey == null) + throw new InvalidOperationException("Blowfish not initialised"); + + Check.DataLength(input, inOff, BLOCK_SIZE, "input buffer too short"); + Check.OutputLength(output, outOff, BLOCK_SIZE, "output buffer too short"); + + if (encrypting) + { + EncryptBlock(input, inOff, output, outOff); + } + else + { + DecryptBlock(input, inOff, output, outOff); + } + + return BLOCK_SIZE; + } + + public void Reset() + { + } + + public int GetBlockSize() + { + return BLOCK_SIZE; + } + + //================================== + // Private Implementation + //================================== + + private uint F(uint x) + { + return (((S0[x >> 24] + S1[(x >> 16) & 0xff]) ^ S2[(x >> 8) & 0xff]) + S3[x & 0xff]); + } + + /** + * apply the encryption cycle to each value pair in the table. + */ + private void ProcessTable( + uint xl, + uint xr, + uint[] table) + { + int size = table.Length; + + for (int s = 0; s < size; s += 2) + { + xl ^= P[0]; + + for (int i = 1; i < ROUNDS; i += 2) + { + xr ^= F(xl) ^ P[i]; + xl ^= F(xr) ^ P[i + 1]; + } + + xr ^= P[ROUNDS + 1]; + + table[s] = xr; + table[s + 1] = xl; + + xr = xl; // end of cycle swap + xl = table[s]; + } + } + + private void SetKey(byte[] key) + { + if (key.Length < 4 || key.Length > 56) + { + throw new ArgumentException("key length must be in range 32 to 448 bits"); + } + + /* + * - comments are from _Applied Crypto_, Schneier, p338 + * please be careful comparing the two, AC numbers the + * arrays from 1, the enclosed code from 0. + * + * (1) + * Initialise the S-boxes and the P-array, with a fixed string + * This string contains the hexadecimal digits of pi (3.141...) + */ + Array.Copy(KS0, 0, S0, 0, SBOX_SK); + Array.Copy(KS1, 0, S1, 0, SBOX_SK); + Array.Copy(KS2, 0, S2, 0, SBOX_SK); + Array.Copy(KS3, 0, S3, 0, SBOX_SK); + + Array.Copy(KP, 0, P, 0, P_SZ); + + /* + * (2) + * Now, XOR P[0] with the first 32 bits of the key, XOR P[1] with the + * second 32-bits of the key, and so on for all bits of the key + * (up to P[17]). Repeatedly cycle through the key bits until the + * entire P-array has been XOR-ed with the key bits + */ + int keyLength = key.Length; + int keyIndex = 0; + + for (int i=0; i < P_SZ; i++) + { + // Get the 32 bits of the key, in 4 * 8 bit chunks + uint data = 0x0000000; + for (int j=0; j < 4; j++) + { + // create a 32 bit block + data = (data << 8) | (uint)key[keyIndex++]; + + // wrap when we get to the end of the key + if (keyIndex >= keyLength) + { + keyIndex = 0; + } + } + // XOR the newly created 32 bit chunk onto the P-array + P[i] ^= data; + } + + /* + * (3) + * Encrypt the all-zero string with the Blowfish algorithm, using + * the subkeys described in (1) and (2) + * + * (4) + * Replace P1 and P2 with the output of step (3) + * + * (5) + * Encrypt the output of step(3) using the Blowfish algorithm, + * with the modified subkeys. + * + * (6) + * Replace P3 and P4 with the output of step (5) + * + * (7) + * Continue the process, replacing all elements of the P-array + * and then all four S-boxes in order, with the output of the + * continuously changing Blowfish algorithm + */ + + ProcessTable(0, 0, P); + ProcessTable(P[P_SZ - 2], P[P_SZ - 1], S0); + ProcessTable(S0[SBOX_SK - 2], S0[SBOX_SK - 1], S1); + ProcessTable(S1[SBOX_SK - 2], S1[SBOX_SK - 1], S2); + ProcessTable(S2[SBOX_SK - 2], S2[SBOX_SK - 1], S3); + } + + /** + * Encrypt the given input starting at the given offset and place + * the result in the provided buffer starting at the given offset. + * The input will be an exact multiple of our blocksize. + */ + private void EncryptBlock( + byte[] src, + int srcIndex, + byte[] dst, + int dstIndex) + { + uint xl = Pack.BE_To_UInt32(src, srcIndex); + uint xr = Pack.BE_To_UInt32(src, srcIndex+4); + + xl ^= P[0]; + + for (int i = 1; i < ROUNDS; i += 2) + { + xr ^= F(xl) ^ P[i]; + xl ^= F(xr) ^ P[i + 1]; + } + + xr ^= P[ROUNDS + 1]; + + Pack.UInt32_To_BE(xr, dst, dstIndex); + Pack.UInt32_To_BE(xl, dst, dstIndex + 4); + } + + /** + * Decrypt the given input starting at the given offset and place + * the result in the provided buffer starting at the given offset. + * The input will be an exact multiple of our blocksize. + */ + private void DecryptBlock( + byte[] src, + int srcIndex, + byte[] dst, + int dstIndex) + { + uint xl = Pack.BE_To_UInt32(src, srcIndex); + uint xr = Pack.BE_To_UInt32(src, srcIndex + 4); + + xl ^= P[ROUNDS + 1]; + + for (int i = ROUNDS; i > 0 ; i -= 2) + { + xr ^= F(xl) ^ P[i]; + xl ^= F(xr) ^ P[i - 1]; + } + + xr ^= P[0]; + + Pack.UInt32_To_BE(xr, dst, dstIndex); + Pack.UInt32_To_BE(xl, dst, dstIndex + 4); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/BlowfishEngine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/BlowfishEngine.cs.meta new file mode 100644 index 0000000..52bbf57 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/BlowfishEngine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5fd3488982f616b429c211cb81d1e380 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/CamelliaEngine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/CamelliaEngine.cs new file mode 100644 index 0000000..71bd1b0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/CamelliaEngine.cs @@ -0,0 +1,668 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * Camellia - based on RFC 3713. + */ + public class CamelliaEngine + : IBlockCipher + { + private bool initialised = false; + private bool _keyIs128; + + private const int BLOCK_SIZE = 16; + + private uint[] subkey = new uint[24 * 4]; + private uint[] kw = new uint[4 * 2]; // for whitening + private uint[] ke = new uint[6 * 2]; // for FL and FL^(-1) + private uint[] state = new uint[4]; // for encryption and decryption + + private static readonly uint[] SIGMA = new uint[]{ + 0xa09e667f, 0x3bcc908b, + 0xb67ae858, 0x4caa73b2, + 0xc6ef372f, 0xe94f82be, + 0x54ff53a5, 0xf1d36f1c, + 0x10e527fa, 0xde682d1d, + 0xb05688c2, 0xb3e6c1fd + }; + + /* + * + * S-box data + * + */ + private static readonly uint[] SBOX1_1110 = new uint[]{ + 0x70707000, 0x82828200, 0x2c2c2c00, 0xececec00, 0xb3b3b300, 0x27272700, + 0xc0c0c000, 0xe5e5e500, 0xe4e4e400, 0x85858500, 0x57575700, 0x35353500, + 0xeaeaea00, 0x0c0c0c00, 0xaeaeae00, 0x41414100, 0x23232300, 0xefefef00, + 0x6b6b6b00, 0x93939300, 0x45454500, 0x19191900, 0xa5a5a500, 0x21212100, + 0xededed00, 0x0e0e0e00, 0x4f4f4f00, 0x4e4e4e00, 0x1d1d1d00, 0x65656500, + 0x92929200, 0xbdbdbd00, 0x86868600, 0xb8b8b800, 0xafafaf00, 0x8f8f8f00, + 0x7c7c7c00, 0xebebeb00, 0x1f1f1f00, 0xcecece00, 0x3e3e3e00, 0x30303000, + 0xdcdcdc00, 0x5f5f5f00, 0x5e5e5e00, 0xc5c5c500, 0x0b0b0b00, 0x1a1a1a00, + 0xa6a6a600, 0xe1e1e100, 0x39393900, 0xcacaca00, 0xd5d5d500, 0x47474700, + 0x5d5d5d00, 0x3d3d3d00, 0xd9d9d900, 0x01010100, 0x5a5a5a00, 0xd6d6d600, + 0x51515100, 0x56565600, 0x6c6c6c00, 0x4d4d4d00, 0x8b8b8b00, 0x0d0d0d00, + 0x9a9a9a00, 0x66666600, 0xfbfbfb00, 0xcccccc00, 0xb0b0b000, 0x2d2d2d00, + 0x74747400, 0x12121200, 0x2b2b2b00, 0x20202000, 0xf0f0f000, 0xb1b1b100, + 0x84848400, 0x99999900, 0xdfdfdf00, 0x4c4c4c00, 0xcbcbcb00, 0xc2c2c200, + 0x34343400, 0x7e7e7e00, 0x76767600, 0x05050500, 0x6d6d6d00, 0xb7b7b700, + 0xa9a9a900, 0x31313100, 0xd1d1d100, 0x17171700, 0x04040400, 0xd7d7d700, + 0x14141400, 0x58585800, 0x3a3a3a00, 0x61616100, 0xdedede00, 0x1b1b1b00, + 0x11111100, 0x1c1c1c00, 0x32323200, 0x0f0f0f00, 0x9c9c9c00, 0x16161600, + 0x53535300, 0x18181800, 0xf2f2f200, 0x22222200, 0xfefefe00, 0x44444400, + 0xcfcfcf00, 0xb2b2b200, 0xc3c3c300, 0xb5b5b500, 0x7a7a7a00, 0x91919100, + 0x24242400, 0x08080800, 0xe8e8e800, 0xa8a8a800, 0x60606000, 0xfcfcfc00, + 0x69696900, 0x50505000, 0xaaaaaa00, 0xd0d0d000, 0xa0a0a000, 0x7d7d7d00, + 0xa1a1a100, 0x89898900, 0x62626200, 0x97979700, 0x54545400, 0x5b5b5b00, + 0x1e1e1e00, 0x95959500, 0xe0e0e000, 0xffffff00, 0x64646400, 0xd2d2d200, + 0x10101000, 0xc4c4c400, 0x00000000, 0x48484800, 0xa3a3a300, 0xf7f7f700, + 0x75757500, 0xdbdbdb00, 0x8a8a8a00, 0x03030300, 0xe6e6e600, 0xdadada00, + 0x09090900, 0x3f3f3f00, 0xdddddd00, 0x94949400, 0x87878700, 0x5c5c5c00, + 0x83838300, 0x02020200, 0xcdcdcd00, 0x4a4a4a00, 0x90909000, 0x33333300, + 0x73737300, 0x67676700, 0xf6f6f600, 0xf3f3f300, 0x9d9d9d00, 0x7f7f7f00, + 0xbfbfbf00, 0xe2e2e200, 0x52525200, 0x9b9b9b00, 0xd8d8d800, 0x26262600, + 0xc8c8c800, 0x37373700, 0xc6c6c600, 0x3b3b3b00, 0x81818100, 0x96969600, + 0x6f6f6f00, 0x4b4b4b00, 0x13131300, 0xbebebe00, 0x63636300, 0x2e2e2e00, + 0xe9e9e900, 0x79797900, 0xa7a7a700, 0x8c8c8c00, 0x9f9f9f00, 0x6e6e6e00, + 0xbcbcbc00, 0x8e8e8e00, 0x29292900, 0xf5f5f500, 0xf9f9f900, 0xb6b6b600, + 0x2f2f2f00, 0xfdfdfd00, 0xb4b4b400, 0x59595900, 0x78787800, 0x98989800, + 0x06060600, 0x6a6a6a00, 0xe7e7e700, 0x46464600, 0x71717100, 0xbababa00, + 0xd4d4d400, 0x25252500, 0xababab00, 0x42424200, 0x88888800, 0xa2a2a200, + 0x8d8d8d00, 0xfafafa00, 0x72727200, 0x07070700, 0xb9b9b900, 0x55555500, + 0xf8f8f800, 0xeeeeee00, 0xacacac00, 0x0a0a0a00, 0x36363600, 0x49494900, + 0x2a2a2a00, 0x68686800, 0x3c3c3c00, 0x38383800, 0xf1f1f100, 0xa4a4a400, + 0x40404000, 0x28282800, 0xd3d3d300, 0x7b7b7b00, 0xbbbbbb00, 0xc9c9c900, + 0x43434300, 0xc1c1c100, 0x15151500, 0xe3e3e300, 0xadadad00, 0xf4f4f400, + 0x77777700, 0xc7c7c700, 0x80808000, 0x9e9e9e00 + }; + + private static readonly uint[] SBOX4_4404 = new uint[]{ + 0x70700070, 0x2c2c002c, 0xb3b300b3, 0xc0c000c0, 0xe4e400e4, 0x57570057, + 0xeaea00ea, 0xaeae00ae, 0x23230023, 0x6b6b006b, 0x45450045, 0xa5a500a5, + 0xeded00ed, 0x4f4f004f, 0x1d1d001d, 0x92920092, 0x86860086, 0xafaf00af, + 0x7c7c007c, 0x1f1f001f, 0x3e3e003e, 0xdcdc00dc, 0x5e5e005e, 0x0b0b000b, + 0xa6a600a6, 0x39390039, 0xd5d500d5, 0x5d5d005d, 0xd9d900d9, 0x5a5a005a, + 0x51510051, 0x6c6c006c, 0x8b8b008b, 0x9a9a009a, 0xfbfb00fb, 0xb0b000b0, + 0x74740074, 0x2b2b002b, 0xf0f000f0, 0x84840084, 0xdfdf00df, 0xcbcb00cb, + 0x34340034, 0x76760076, 0x6d6d006d, 0xa9a900a9, 0xd1d100d1, 0x04040004, + 0x14140014, 0x3a3a003a, 0xdede00de, 0x11110011, 0x32320032, 0x9c9c009c, + 0x53530053, 0xf2f200f2, 0xfefe00fe, 0xcfcf00cf, 0xc3c300c3, 0x7a7a007a, + 0x24240024, 0xe8e800e8, 0x60600060, 0x69690069, 0xaaaa00aa, 0xa0a000a0, + 0xa1a100a1, 0x62620062, 0x54540054, 0x1e1e001e, 0xe0e000e0, 0x64640064, + 0x10100010, 0x00000000, 0xa3a300a3, 0x75750075, 0x8a8a008a, 0xe6e600e6, + 0x09090009, 0xdddd00dd, 0x87870087, 0x83830083, 0xcdcd00cd, 0x90900090, + 0x73730073, 0xf6f600f6, 0x9d9d009d, 0xbfbf00bf, 0x52520052, 0xd8d800d8, + 0xc8c800c8, 0xc6c600c6, 0x81810081, 0x6f6f006f, 0x13130013, 0x63630063, + 0xe9e900e9, 0xa7a700a7, 0x9f9f009f, 0xbcbc00bc, 0x29290029, 0xf9f900f9, + 0x2f2f002f, 0xb4b400b4, 0x78780078, 0x06060006, 0xe7e700e7, 0x71710071, + 0xd4d400d4, 0xabab00ab, 0x88880088, 0x8d8d008d, 0x72720072, 0xb9b900b9, + 0xf8f800f8, 0xacac00ac, 0x36360036, 0x2a2a002a, 0x3c3c003c, 0xf1f100f1, + 0x40400040, 0xd3d300d3, 0xbbbb00bb, 0x43430043, 0x15150015, 0xadad00ad, + 0x77770077, 0x80800080, 0x82820082, 0xecec00ec, 0x27270027, 0xe5e500e5, + 0x85850085, 0x35350035, 0x0c0c000c, 0x41410041, 0xefef00ef, 0x93930093, + 0x19190019, 0x21210021, 0x0e0e000e, 0x4e4e004e, 0x65650065, 0xbdbd00bd, + 0xb8b800b8, 0x8f8f008f, 0xebeb00eb, 0xcece00ce, 0x30300030, 0x5f5f005f, + 0xc5c500c5, 0x1a1a001a, 0xe1e100e1, 0xcaca00ca, 0x47470047, 0x3d3d003d, + 0x01010001, 0xd6d600d6, 0x56560056, 0x4d4d004d, 0x0d0d000d, 0x66660066, + 0xcccc00cc, 0x2d2d002d, 0x12120012, 0x20200020, 0xb1b100b1, 0x99990099, + 0x4c4c004c, 0xc2c200c2, 0x7e7e007e, 0x05050005, 0xb7b700b7, 0x31310031, + 0x17170017, 0xd7d700d7, 0x58580058, 0x61610061, 0x1b1b001b, 0x1c1c001c, + 0x0f0f000f, 0x16160016, 0x18180018, 0x22220022, 0x44440044, 0xb2b200b2, + 0xb5b500b5, 0x91910091, 0x08080008, 0xa8a800a8, 0xfcfc00fc, 0x50500050, + 0xd0d000d0, 0x7d7d007d, 0x89890089, 0x97970097, 0x5b5b005b, 0x95950095, + 0xffff00ff, 0xd2d200d2, 0xc4c400c4, 0x48480048, 0xf7f700f7, 0xdbdb00db, + 0x03030003, 0xdada00da, 0x3f3f003f, 0x94940094, 0x5c5c005c, 0x02020002, + 0x4a4a004a, 0x33330033, 0x67670067, 0xf3f300f3, 0x7f7f007f, 0xe2e200e2, + 0x9b9b009b, 0x26260026, 0x37370037, 0x3b3b003b, 0x96960096, 0x4b4b004b, + 0xbebe00be, 0x2e2e002e, 0x79790079, 0x8c8c008c, 0x6e6e006e, 0x8e8e008e, + 0xf5f500f5, 0xb6b600b6, 0xfdfd00fd, 0x59590059, 0x98980098, 0x6a6a006a, + 0x46460046, 0xbaba00ba, 0x25250025, 0x42420042, 0xa2a200a2, 0xfafa00fa, + 0x07070007, 0x55550055, 0xeeee00ee, 0x0a0a000a, 0x49490049, 0x68680068, + 0x38380038, 0xa4a400a4, 0x28280028, 0x7b7b007b, 0xc9c900c9, 0xc1c100c1, + 0xe3e300e3, 0xf4f400f4, 0xc7c700c7, 0x9e9e009e + }; + + private static readonly uint[] SBOX2_0222 = new uint[]{ + 0x00e0e0e0, 0x00050505, 0x00585858, 0x00d9d9d9, 0x00676767, 0x004e4e4e, + 0x00818181, 0x00cbcbcb, 0x00c9c9c9, 0x000b0b0b, 0x00aeaeae, 0x006a6a6a, + 0x00d5d5d5, 0x00181818, 0x005d5d5d, 0x00828282, 0x00464646, 0x00dfdfdf, + 0x00d6d6d6, 0x00272727, 0x008a8a8a, 0x00323232, 0x004b4b4b, 0x00424242, + 0x00dbdbdb, 0x001c1c1c, 0x009e9e9e, 0x009c9c9c, 0x003a3a3a, 0x00cacaca, + 0x00252525, 0x007b7b7b, 0x000d0d0d, 0x00717171, 0x005f5f5f, 0x001f1f1f, + 0x00f8f8f8, 0x00d7d7d7, 0x003e3e3e, 0x009d9d9d, 0x007c7c7c, 0x00606060, + 0x00b9b9b9, 0x00bebebe, 0x00bcbcbc, 0x008b8b8b, 0x00161616, 0x00343434, + 0x004d4d4d, 0x00c3c3c3, 0x00727272, 0x00959595, 0x00ababab, 0x008e8e8e, + 0x00bababa, 0x007a7a7a, 0x00b3b3b3, 0x00020202, 0x00b4b4b4, 0x00adadad, + 0x00a2a2a2, 0x00acacac, 0x00d8d8d8, 0x009a9a9a, 0x00171717, 0x001a1a1a, + 0x00353535, 0x00cccccc, 0x00f7f7f7, 0x00999999, 0x00616161, 0x005a5a5a, + 0x00e8e8e8, 0x00242424, 0x00565656, 0x00404040, 0x00e1e1e1, 0x00636363, + 0x00090909, 0x00333333, 0x00bfbfbf, 0x00989898, 0x00979797, 0x00858585, + 0x00686868, 0x00fcfcfc, 0x00ececec, 0x000a0a0a, 0x00dadada, 0x006f6f6f, + 0x00535353, 0x00626262, 0x00a3a3a3, 0x002e2e2e, 0x00080808, 0x00afafaf, + 0x00282828, 0x00b0b0b0, 0x00747474, 0x00c2c2c2, 0x00bdbdbd, 0x00363636, + 0x00222222, 0x00383838, 0x00646464, 0x001e1e1e, 0x00393939, 0x002c2c2c, + 0x00a6a6a6, 0x00303030, 0x00e5e5e5, 0x00444444, 0x00fdfdfd, 0x00888888, + 0x009f9f9f, 0x00656565, 0x00878787, 0x006b6b6b, 0x00f4f4f4, 0x00232323, + 0x00484848, 0x00101010, 0x00d1d1d1, 0x00515151, 0x00c0c0c0, 0x00f9f9f9, + 0x00d2d2d2, 0x00a0a0a0, 0x00555555, 0x00a1a1a1, 0x00414141, 0x00fafafa, + 0x00434343, 0x00131313, 0x00c4c4c4, 0x002f2f2f, 0x00a8a8a8, 0x00b6b6b6, + 0x003c3c3c, 0x002b2b2b, 0x00c1c1c1, 0x00ffffff, 0x00c8c8c8, 0x00a5a5a5, + 0x00202020, 0x00898989, 0x00000000, 0x00909090, 0x00474747, 0x00efefef, + 0x00eaeaea, 0x00b7b7b7, 0x00151515, 0x00060606, 0x00cdcdcd, 0x00b5b5b5, + 0x00121212, 0x007e7e7e, 0x00bbbbbb, 0x00292929, 0x000f0f0f, 0x00b8b8b8, + 0x00070707, 0x00040404, 0x009b9b9b, 0x00949494, 0x00212121, 0x00666666, + 0x00e6e6e6, 0x00cecece, 0x00ededed, 0x00e7e7e7, 0x003b3b3b, 0x00fefefe, + 0x007f7f7f, 0x00c5c5c5, 0x00a4a4a4, 0x00373737, 0x00b1b1b1, 0x004c4c4c, + 0x00919191, 0x006e6e6e, 0x008d8d8d, 0x00767676, 0x00030303, 0x002d2d2d, + 0x00dedede, 0x00969696, 0x00262626, 0x007d7d7d, 0x00c6c6c6, 0x005c5c5c, + 0x00d3d3d3, 0x00f2f2f2, 0x004f4f4f, 0x00191919, 0x003f3f3f, 0x00dcdcdc, + 0x00797979, 0x001d1d1d, 0x00525252, 0x00ebebeb, 0x00f3f3f3, 0x006d6d6d, + 0x005e5e5e, 0x00fbfbfb, 0x00696969, 0x00b2b2b2, 0x00f0f0f0, 0x00313131, + 0x000c0c0c, 0x00d4d4d4, 0x00cfcfcf, 0x008c8c8c, 0x00e2e2e2, 0x00757575, + 0x00a9a9a9, 0x004a4a4a, 0x00575757, 0x00848484, 0x00111111, 0x00454545, + 0x001b1b1b, 0x00f5f5f5, 0x00e4e4e4, 0x000e0e0e, 0x00737373, 0x00aaaaaa, + 0x00f1f1f1, 0x00dddddd, 0x00595959, 0x00141414, 0x006c6c6c, 0x00929292, + 0x00545454, 0x00d0d0d0, 0x00787878, 0x00707070, 0x00e3e3e3, 0x00494949, + 0x00808080, 0x00505050, 0x00a7a7a7, 0x00f6f6f6, 0x00777777, 0x00939393, + 0x00868686, 0x00838383, 0x002a2a2a, 0x00c7c7c7, 0x005b5b5b, 0x00e9e9e9, + 0x00eeeeee, 0x008f8f8f, 0x00010101, 0x003d3d3d + }; + + private static readonly uint[] SBOX3_3033 = new uint[]{ + 0x38003838, 0x41004141, 0x16001616, 0x76007676, 0xd900d9d9, 0x93009393, + 0x60006060, 0xf200f2f2, 0x72007272, 0xc200c2c2, 0xab00abab, 0x9a009a9a, + 0x75007575, 0x06000606, 0x57005757, 0xa000a0a0, 0x91009191, 0xf700f7f7, + 0xb500b5b5, 0xc900c9c9, 0xa200a2a2, 0x8c008c8c, 0xd200d2d2, 0x90009090, + 0xf600f6f6, 0x07000707, 0xa700a7a7, 0x27002727, 0x8e008e8e, 0xb200b2b2, + 0x49004949, 0xde00dede, 0x43004343, 0x5c005c5c, 0xd700d7d7, 0xc700c7c7, + 0x3e003e3e, 0xf500f5f5, 0x8f008f8f, 0x67006767, 0x1f001f1f, 0x18001818, + 0x6e006e6e, 0xaf00afaf, 0x2f002f2f, 0xe200e2e2, 0x85008585, 0x0d000d0d, + 0x53005353, 0xf000f0f0, 0x9c009c9c, 0x65006565, 0xea00eaea, 0xa300a3a3, + 0xae00aeae, 0x9e009e9e, 0xec00ecec, 0x80008080, 0x2d002d2d, 0x6b006b6b, + 0xa800a8a8, 0x2b002b2b, 0x36003636, 0xa600a6a6, 0xc500c5c5, 0x86008686, + 0x4d004d4d, 0x33003333, 0xfd00fdfd, 0x66006666, 0x58005858, 0x96009696, + 0x3a003a3a, 0x09000909, 0x95009595, 0x10001010, 0x78007878, 0xd800d8d8, + 0x42004242, 0xcc00cccc, 0xef00efef, 0x26002626, 0xe500e5e5, 0x61006161, + 0x1a001a1a, 0x3f003f3f, 0x3b003b3b, 0x82008282, 0xb600b6b6, 0xdb00dbdb, + 0xd400d4d4, 0x98009898, 0xe800e8e8, 0x8b008b8b, 0x02000202, 0xeb00ebeb, + 0x0a000a0a, 0x2c002c2c, 0x1d001d1d, 0xb000b0b0, 0x6f006f6f, 0x8d008d8d, + 0x88008888, 0x0e000e0e, 0x19001919, 0x87008787, 0x4e004e4e, 0x0b000b0b, + 0xa900a9a9, 0x0c000c0c, 0x79007979, 0x11001111, 0x7f007f7f, 0x22002222, + 0xe700e7e7, 0x59005959, 0xe100e1e1, 0xda00dada, 0x3d003d3d, 0xc800c8c8, + 0x12001212, 0x04000404, 0x74007474, 0x54005454, 0x30003030, 0x7e007e7e, + 0xb400b4b4, 0x28002828, 0x55005555, 0x68006868, 0x50005050, 0xbe00bebe, + 0xd000d0d0, 0xc400c4c4, 0x31003131, 0xcb00cbcb, 0x2a002a2a, 0xad00adad, + 0x0f000f0f, 0xca00caca, 0x70007070, 0xff00ffff, 0x32003232, 0x69006969, + 0x08000808, 0x62006262, 0x00000000, 0x24002424, 0xd100d1d1, 0xfb00fbfb, + 0xba00baba, 0xed00eded, 0x45004545, 0x81008181, 0x73007373, 0x6d006d6d, + 0x84008484, 0x9f009f9f, 0xee00eeee, 0x4a004a4a, 0xc300c3c3, 0x2e002e2e, + 0xc100c1c1, 0x01000101, 0xe600e6e6, 0x25002525, 0x48004848, 0x99009999, + 0xb900b9b9, 0xb300b3b3, 0x7b007b7b, 0xf900f9f9, 0xce00cece, 0xbf00bfbf, + 0xdf00dfdf, 0x71007171, 0x29002929, 0xcd00cdcd, 0x6c006c6c, 0x13001313, + 0x64006464, 0x9b009b9b, 0x63006363, 0x9d009d9d, 0xc000c0c0, 0x4b004b4b, + 0xb700b7b7, 0xa500a5a5, 0x89008989, 0x5f005f5f, 0xb100b1b1, 0x17001717, + 0xf400f4f4, 0xbc00bcbc, 0xd300d3d3, 0x46004646, 0xcf00cfcf, 0x37003737, + 0x5e005e5e, 0x47004747, 0x94009494, 0xfa00fafa, 0xfc00fcfc, 0x5b005b5b, + 0x97009797, 0xfe00fefe, 0x5a005a5a, 0xac00acac, 0x3c003c3c, 0x4c004c4c, + 0x03000303, 0x35003535, 0xf300f3f3, 0x23002323, 0xb800b8b8, 0x5d005d5d, + 0x6a006a6a, 0x92009292, 0xd500d5d5, 0x21002121, 0x44004444, 0x51005151, + 0xc600c6c6, 0x7d007d7d, 0x39003939, 0x83008383, 0xdc00dcdc, 0xaa00aaaa, + 0x7c007c7c, 0x77007777, 0x56005656, 0x05000505, 0x1b001b1b, 0xa400a4a4, + 0x15001515, 0x34003434, 0x1e001e1e, 0x1c001c1c, 0xf800f8f8, 0x52005252, + 0x20002020, 0x14001414, 0xe900e9e9, 0xbd00bdbd, 0xdd00dddd, 0xe400e4e4, + 0xa100a1a1, 0xe000e0e0, 0x8a008a8a, 0xf100f1f1, 0xd600d6d6, 0x7a007a7a, + 0xbb00bbbb, 0xe300e3e3, 0x40004040, 0x4f004f4f + }; + + private static uint rightRotate(uint x, int s) + { + return ((x >> s) + (x << (32 - s))); + } + + private static uint leftRotate(uint x, int s) + { + return (x << s) + (x >> (32 - s)); + } + + private static void roldq(int rot, uint[] ki, int ioff, uint[] ko, int ooff) + { + ko[0 + ooff] = (ki[0 + ioff] << rot) | (ki[1 + ioff] >> (32 - rot)); + ko[1 + ooff] = (ki[1 + ioff] << rot) | (ki[2 + ioff] >> (32 - rot)); + ko[2 + ooff] = (ki[2 + ioff] << rot) | (ki[3 + ioff] >> (32 - rot)); + ko[3 + ooff] = (ki[3 + ioff] << rot) | (ki[0 + ioff] >> (32 - rot)); + ki[0 + ioff] = ko[0 + ooff]; + ki[1 + ioff] = ko[1 + ooff]; + ki[2 + ioff] = ko[2 + ooff]; + ki[3 + ioff] = ko[3 + ooff]; + } + + private static void decroldq(int rot, uint[] ki, int ioff, uint[] ko, int ooff) + { + ko[2 + ooff] = (ki[0 + ioff] << rot) | (ki[1 + ioff] >> (32 - rot)); + ko[3 + ooff] = (ki[1 + ioff] << rot) | (ki[2 + ioff] >> (32 - rot)); + ko[0 + ooff] = (ki[2 + ioff] << rot) | (ki[3 + ioff] >> (32 - rot)); + ko[1 + ooff] = (ki[3 + ioff] << rot) | (ki[0 + ioff] >> (32 - rot)); + ki[0 + ioff] = ko[2 + ooff]; + ki[1 + ioff] = ko[3 + ooff]; + ki[2 + ioff] = ko[0 + ooff]; + ki[3 + ioff] = ko[1 + ooff]; + } + + private static void roldqo32(int rot, uint[] ki, int ioff, uint[] ko, int ooff) + { + ko[0 + ooff] = (ki[1 + ioff] << (rot - 32)) | (ki[2 + ioff] >> (64 - rot)); + ko[1 + ooff] = (ki[2 + ioff] << (rot - 32)) | (ki[3 + ioff] >> (64 - rot)); + ko[2 + ooff] = (ki[3 + ioff] << (rot - 32)) | (ki[0 + ioff] >> (64 - rot)); + ko[3 + ooff] = (ki[0 + ioff] << (rot - 32)) | (ki[1 + ioff] >> (64 - rot)); + ki[0 + ioff] = ko[0 + ooff]; + ki[1 + ioff] = ko[1 + ooff]; + ki[2 + ioff] = ko[2 + ooff]; + ki[3 + ioff] = ko[3 + ooff]; + } + + private static void decroldqo32(int rot, uint[] ki, int ioff, uint[] ko, int ooff) + { + ko[2 + ooff] = (ki[1 + ioff] << (rot - 32)) | (ki[2 + ioff] >> (64 - rot)); + ko[3 + ooff] = (ki[2 + ioff] << (rot - 32)) | (ki[3 + ioff] >> (64 - rot)); + ko[0 + ooff] = (ki[3 + ioff] << (rot - 32)) | (ki[0 + ioff] >> (64 - rot)); + ko[1 + ooff] = (ki[0 + ioff] << (rot - 32)) | (ki[1 + ioff] >> (64 - rot)); + ki[0 + ioff] = ko[2 + ooff]; + ki[1 + ioff] = ko[3 + ooff]; + ki[2 + ioff] = ko[0 + ooff]; + ki[3 + ioff] = ko[1 + ooff]; + } + + private static uint bytes2uint(byte[] src, int offset) + { + uint word = 0; + for (int i = 0; i < 4; i++) + { + word = (word << 8) + (uint)src[i + offset]; + } + return word; + } + + private static void uint2bytes(uint word, byte[] dst, int offset) + { + for (int i = 0; i < 4; i++) + { + dst[(3 - i) + offset] = (byte)word; + word >>= 8; + } + } + + private static void camelliaF2(uint[] s, uint[] skey, int keyoff) + { + uint t1, t2, u, v; + + t1 = s[0] ^ skey[0 + keyoff]; + u = SBOX4_4404[(byte)t1]; + u ^= SBOX3_3033[(byte)(t1 >> 8)]; + u ^= SBOX2_0222[(byte)(t1 >> 16)]; + u ^= SBOX1_1110[(byte)(t1 >> 24)]; + t2 = s[1] ^ skey[1 + keyoff]; + v = SBOX1_1110[(byte)t2]; + v ^= SBOX4_4404[(byte)(t2 >> 8)]; + v ^= SBOX3_3033[(byte)(t2 >> 16)]; + v ^= SBOX2_0222[(byte)(t2 >> 24)]; + + s[2] ^= u ^ v; + s[3] ^= u ^ v ^ rightRotate(u, 8); + + t1 = s[2] ^ skey[2 + keyoff]; + u = SBOX4_4404[(byte)t1]; + u ^= SBOX3_3033[(byte)(t1 >> 8)]; + u ^= SBOX2_0222[(byte)(t1 >> 16)]; + u ^= SBOX1_1110[(byte)(t1 >> 24)]; + t2 = s[3] ^ skey[3 + keyoff]; + v = SBOX1_1110[(byte)t2]; + v ^= SBOX4_4404[(byte)(t2 >> 8)]; + v ^= SBOX3_3033[(byte)(t2 >> 16)]; + v ^= SBOX2_0222[(byte)(t2 >> 24)]; + + s[0] ^= u ^ v; + s[1] ^= u ^ v ^ rightRotate(u, 8); + } + + private static void camelliaFLs(uint[] s, uint[] fkey, int keyoff) + { + + s[1] ^= leftRotate(s[0] & fkey[0 + keyoff], 1); + s[0] ^= fkey[1 + keyoff] | s[1]; + + s[2] ^= fkey[3 + keyoff] | s[3]; + s[3] ^= leftRotate(fkey[2 + keyoff] & s[2], 1); + } + + private void setKey(bool forEncryption, byte[] key) + { + uint[] k = new uint[8]; + uint[] ka = new uint[4]; + uint[] kb = new uint[4]; + uint[] t = new uint[4]; + + switch (key.Length) + { + case 16: + _keyIs128 = true; + k[0] = bytes2uint(key, 0); + k[1] = bytes2uint(key, 4); + k[2] = bytes2uint(key, 8); + k[3] = bytes2uint(key, 12); + k[4] = k[5] = k[6] = k[7] = 0; + break; + case 24: + k[0] = bytes2uint(key, 0); + k[1] = bytes2uint(key, 4); + k[2] = bytes2uint(key, 8); + k[3] = bytes2uint(key, 12); + k[4] = bytes2uint(key, 16); + k[5] = bytes2uint(key, 20); + k[6] = ~k[4]; + k[7] = ~k[5]; + _keyIs128 = false; + break; + case 32: + k[0] = bytes2uint(key, 0); + k[1] = bytes2uint(key, 4); + k[2] = bytes2uint(key, 8); + k[3] = bytes2uint(key, 12); + k[4] = bytes2uint(key, 16); + k[5] = bytes2uint(key, 20); + k[6] = bytes2uint(key, 24); + k[7] = bytes2uint(key, 28); + _keyIs128 = false; + break; + default: + throw new ArgumentException("key sizes are only 16/24/32 bytes."); + } + + for (int i = 0; i < 4; i++) + { + ka[i] = k[i] ^ k[i + 4]; + } + /* compute KA */ + camelliaF2(ka, SIGMA, 0); + for (int i = 0; i < 4; i++) + { + ka[i] ^= k[i]; + } + camelliaF2(ka, SIGMA, 4); + + if (_keyIs128) + { + if (forEncryption) + { + /* KL dependant keys */ + kw[0] = k[0]; + kw[1] = k[1]; + kw[2] = k[2]; + kw[3] = k[3]; + roldq(15, k, 0, subkey, 4); + roldq(30, k, 0, subkey, 12); + roldq(15, k, 0, t, 0); + subkey[18] = t[2]; + subkey[19] = t[3]; + roldq(17, k, 0, ke, 4); + roldq(17, k, 0, subkey, 24); + roldq(17, k, 0, subkey, 32); + /* KA dependant keys */ + subkey[0] = ka[0]; + subkey[1] = ka[1]; + subkey[2] = ka[2]; + subkey[3] = ka[3]; + roldq(15, ka, 0, subkey, 8); + roldq(15, ka, 0, ke, 0); + roldq(15, ka, 0, t, 0); + subkey[16] = t[0]; + subkey[17] = t[1]; + roldq(15, ka, 0, subkey, 20); + roldqo32(34, ka, 0, subkey, 28); + roldq(17, ka, 0, kw, 4); + + } + else + { // decryption + /* KL dependant keys */ + kw[4] = k[0]; + kw[5] = k[1]; + kw[6] = k[2]; + kw[7] = k[3]; + decroldq(15, k, 0, subkey, 28); + decroldq(30, k, 0, subkey, 20); + decroldq(15, k, 0, t, 0); + subkey[16] = t[0]; + subkey[17] = t[1]; + decroldq(17, k, 0, ke, 0); + decroldq(17, k, 0, subkey, 8); + decroldq(17, k, 0, subkey, 0); + /* KA dependant keys */ + subkey[34] = ka[0]; + subkey[35] = ka[1]; + subkey[32] = ka[2]; + subkey[33] = ka[3]; + decroldq(15, ka, 0, subkey, 24); + decroldq(15, ka, 0, ke, 4); + decroldq(15, ka, 0, t, 0); + subkey[18] = t[2]; + subkey[19] = t[3]; + decroldq(15, ka, 0, subkey, 12); + decroldqo32(34, ka, 0, subkey, 4); + roldq(17, ka, 0, kw, 0); + } + } + else + { // 192bit or 256bit + /* compute KB */ + for (int i = 0; i < 4; i++) + { + kb[i] = ka[i] ^ k[i + 4]; + } + camelliaF2(kb, SIGMA, 8); + + if (forEncryption) + { + /* KL dependant keys */ + kw[0] = k[0]; + kw[1] = k[1]; + kw[2] = k[2]; + kw[3] = k[3]; + roldqo32(45, k, 0, subkey, 16); + roldq(15, k, 0, ke, 4); + roldq(17, k, 0, subkey, 32); + roldqo32(34, k, 0, subkey, 44); + /* KR dependant keys */ + roldq(15, k, 4, subkey, 4); + roldq(15, k, 4, ke, 0); + roldq(30, k, 4, subkey, 24); + roldqo32(34, k, 4, subkey, 36); + /* KA dependant keys */ + roldq(15, ka, 0, subkey, 8); + roldq(30, ka, 0, subkey, 20); + /* 32bit rotation */ + ke[8] = ka[1]; + ke[9] = ka[2]; + ke[10] = ka[3]; + ke[11] = ka[0]; + roldqo32(49, ka, 0, subkey, 40); + + /* KB dependant keys */ + subkey[0] = kb[0]; + subkey[1] = kb[1]; + subkey[2] = kb[2]; + subkey[3] = kb[3]; + roldq(30, kb, 0, subkey, 12); + roldq(30, kb, 0, subkey, 28); + roldqo32(51, kb, 0, kw, 4); + + } + else + { // decryption + /* KL dependant keys */ + kw[4] = k[0]; + kw[5] = k[1]; + kw[6] = k[2]; + kw[7] = k[3]; + decroldqo32(45, k, 0, subkey, 28); + decroldq(15, k, 0, ke, 4); + decroldq(17, k, 0, subkey, 12); + decroldqo32(34, k, 0, subkey, 0); + /* KR dependant keys */ + decroldq(15, k, 4, subkey, 40); + decroldq(15, k, 4, ke, 8); + decroldq(30, k, 4, subkey, 20); + decroldqo32(34, k, 4, subkey, 8); + /* KA dependant keys */ + decroldq(15, ka, 0, subkey, 36); + decroldq(30, ka, 0, subkey, 24); + /* 32bit rotation */ + ke[2] = ka[1]; + ke[3] = ka[2]; + ke[0] = ka[3]; + ke[1] = ka[0]; + decroldqo32(49, ka, 0, subkey, 4); + + /* KB dependant keys */ + subkey[46] = kb[0]; + subkey[47] = kb[1]; + subkey[44] = kb[2]; + subkey[45] = kb[3]; + decroldq(30, kb, 0, subkey, 32); + decroldq(30, kb, 0, subkey, 16); + roldqo32(51, kb, 0, kw, 0); + } + } + } + + private int processBlock128(byte[] input, int inOff, byte[] output, int outOff) + { + for (int i = 0; i < 4; i++) + { + state[i] = bytes2uint(input, inOff + (i * 4)); + state[i] ^= kw[i]; + } + + camelliaF2(state, subkey, 0); + camelliaF2(state, subkey, 4); + camelliaF2(state, subkey, 8); + camelliaFLs(state, ke, 0); + camelliaF2(state, subkey, 12); + camelliaF2(state, subkey, 16); + camelliaF2(state, subkey, 20); + camelliaFLs(state, ke, 4); + camelliaF2(state, subkey, 24); + camelliaF2(state, subkey, 28); + camelliaF2(state, subkey, 32); + + state[2] ^= kw[4]; + state[3] ^= kw[5]; + state[0] ^= kw[6]; + state[1] ^= kw[7]; + + uint2bytes(state[2], output, outOff); + uint2bytes(state[3], output, outOff + 4); + uint2bytes(state[0], output, outOff + 8); + uint2bytes(state[1], output, outOff + 12); + + return BLOCK_SIZE; + } + + private int processBlock192or256(byte[] input, int inOff, byte[] output, int outOff) + { + for (int i = 0; i < 4; i++) + { + state[i] = bytes2uint(input, inOff + (i * 4)); + state[i] ^= kw[i]; + } + + camelliaF2(state, subkey, 0); + camelliaF2(state, subkey, 4); + camelliaF2(state, subkey, 8); + camelliaFLs(state, ke, 0); + camelliaF2(state, subkey, 12); + camelliaF2(state, subkey, 16); + camelliaF2(state, subkey, 20); + camelliaFLs(state, ke, 4); + camelliaF2(state, subkey, 24); + camelliaF2(state, subkey, 28); + camelliaF2(state, subkey, 32); + camelliaFLs(state, ke, 8); + camelliaF2(state, subkey, 36); + camelliaF2(state, subkey, 40); + camelliaF2(state, subkey, 44); + + state[2] ^= kw[4]; + state[3] ^= kw[5]; + state[0] ^= kw[6]; + state[1] ^= kw[7]; + + uint2bytes(state[2], output, outOff); + uint2bytes(state[3], output, outOff + 4); + uint2bytes(state[0], output, outOff + 8); + uint2bytes(state[1], output, outOff + 12); + return BLOCK_SIZE; + } + + public CamelliaEngine() + { + } + + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (!(parameters is KeyParameter)) + throw new ArgumentException("only simple KeyParameter expected."); + + setKey(forEncryption, ((KeyParameter)parameters).GetKey()); + + initialised = true; + } + + public virtual string AlgorithmName + { + get { return "Camellia"; } + } + + public virtual bool IsPartialBlockOkay + { + get { return false; } + } + + public virtual int GetBlockSize() + { + return BLOCK_SIZE; + } + + public virtual int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + if (!initialised) + throw new InvalidOperationException("Camellia engine not initialised"); + + Check.DataLength(input, inOff, BLOCK_SIZE, "input buffer too short"); + Check.OutputLength(output, outOff, BLOCK_SIZE, "output buffer too short"); + + if (_keyIs128) + { + return processBlock128(input, inOff, output, outOff); + } + else + { + return processBlock192or256(input, inOff, output, outOff); + } + } + + public virtual void Reset() + { + // nothing + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/CamelliaEngine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/CamelliaEngine.cs.meta new file mode 100644 index 0000000..df2b1e7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/CamelliaEngine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 299d687d87b8f2e4bbb7775cc466b066 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/CamelliaLightEngine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/CamelliaLightEngine.cs new file mode 100644 index 0000000..a132227 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/CamelliaLightEngine.cs @@ -0,0 +1,580 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * Camellia - based on RFC 3713, smaller implementation, about half the size of CamelliaEngine. + */ + public class CamelliaLightEngine + : IBlockCipher + { + private const int BLOCK_SIZE = 16; +// private const int MASK8 = 0xff; + private bool initialised; + private bool _keyis128; + + private uint[] subkey = new uint[24 * 4]; + private uint[] kw = new uint[4 * 2]; // for whitening + private uint[] ke = new uint[6 * 2]; // for FL and FL^(-1) + private uint[] state = new uint[4]; // for encryption and decryption + + private static readonly uint[] SIGMA = { + 0xa09e667f, 0x3bcc908b, + 0xb67ae858, 0x4caa73b2, + 0xc6ef372f, 0xe94f82be, + 0x54ff53a5, 0xf1d36f1c, + 0x10e527fa, 0xde682d1d, + 0xb05688c2, 0xb3e6c1fd + }; + + /* + * + * S-box data + * + */ + private static readonly byte[] SBOX1 = { + (byte)112, (byte)130, (byte)44, (byte)236, + (byte)179, (byte)39, (byte)192, (byte)229, + (byte)228, (byte)133, (byte)87, (byte)53, + (byte)234, (byte)12, (byte)174, (byte)65, + (byte)35, (byte)239, (byte)107, (byte)147, + (byte)69, (byte)25, (byte)165, (byte)33, + (byte)237, (byte)14, (byte)79, (byte)78, + (byte)29, (byte)101, (byte)146, (byte)189, + (byte)134, (byte)184, (byte)175, (byte)143, + (byte)124, (byte)235, (byte)31, (byte)206, + (byte)62, (byte)48, (byte)220, (byte)95, + (byte)94, (byte)197, (byte)11, (byte)26, + (byte)166, (byte)225, (byte)57, (byte)202, + (byte)213, (byte)71, (byte)93, (byte)61, + (byte)217, (byte)1, (byte)90, (byte)214, + (byte)81, (byte)86, (byte)108, (byte)77, + (byte)139, (byte)13, (byte)154, (byte)102, + (byte)251, (byte)204, (byte)176, (byte)45, + (byte)116, (byte)18, (byte)43, (byte)32, + (byte)240, (byte)177, (byte)132, (byte)153, + (byte)223, (byte)76, (byte)203, (byte)194, + (byte)52, (byte)126, (byte)118, (byte)5, + (byte)109, (byte)183, (byte)169, (byte)49, + (byte)209, (byte)23, (byte)4, (byte)215, + (byte)20, (byte)88, (byte)58, (byte)97, + (byte)222, (byte)27, (byte)17, (byte)28, + (byte)50, (byte)15, (byte)156, (byte)22, + (byte)83, (byte)24, (byte)242, (byte)34, + (byte)254, (byte)68, (byte)207, (byte)178, + (byte)195, (byte)181, (byte)122, (byte)145, + (byte)36, (byte)8, (byte)232, (byte)168, + (byte)96, (byte)252, (byte)105, (byte)80, + (byte)170, (byte)208, (byte)160, (byte)125, + (byte)161, (byte)137, (byte)98, (byte)151, + (byte)84, (byte)91, (byte)30, (byte)149, + (byte)224, (byte)255, (byte)100, (byte)210, + (byte)16, (byte)196, (byte)0, (byte)72, + (byte)163, (byte)247, (byte)117, (byte)219, + (byte)138, (byte)3, (byte)230, (byte)218, + (byte)9, (byte)63, (byte)221, (byte)148, + (byte)135, (byte)92, (byte)131, (byte)2, + (byte)205, (byte)74, (byte)144, (byte)51, + (byte)115, (byte)103, (byte)246, (byte)243, + (byte)157, (byte)127, (byte)191, (byte)226, + (byte)82, (byte)155, (byte)216, (byte)38, + (byte)200, (byte)55, (byte)198, (byte)59, + (byte)129, (byte)150, (byte)111, (byte)75, + (byte)19, (byte)190, (byte)99, (byte)46, + (byte)233, (byte)121, (byte)167, (byte)140, + (byte)159, (byte)110, (byte)188, (byte)142, + (byte)41, (byte)245, (byte)249, (byte)182, + (byte)47, (byte)253, (byte)180, (byte)89, + (byte)120, (byte)152, (byte)6, (byte)106, + (byte)231, (byte)70, (byte)113, (byte)186, + (byte)212, (byte)37, (byte)171, (byte)66, + (byte)136, (byte)162, (byte)141, (byte)250, + (byte)114, (byte)7, (byte)185, (byte)85, + (byte)248, (byte)238, (byte)172, (byte)10, + (byte)54, (byte)73, (byte)42, (byte)104, + (byte)60, (byte)56, (byte)241, (byte)164, + (byte)64, (byte)40, (byte)211, (byte)123, + (byte)187, (byte)201, (byte)67, (byte)193, + (byte)21, (byte)227, (byte)173, (byte)244, + (byte)119, (byte)199, (byte)128, (byte)158 + }; + + private static uint rightRotate(uint x, int s) + { + return ((x >> s) + (x << (32 - s))); + } + + private static uint leftRotate(uint x, int s) + { + return (x << s) + (x >> (32 - s)); + } + + private static void roldq(int rot, uint[] ki, int ioff, uint[] ko, int ooff) + { + ko[0 + ooff] = (ki[0 + ioff] << rot) | (ki[1 + ioff] >> (32 - rot)); + ko[1 + ooff] = (ki[1 + ioff] << rot) | (ki[2 + ioff] >> (32 - rot)); + ko[2 + ooff] = (ki[2 + ioff] << rot) | (ki[3 + ioff] >> (32 - rot)); + ko[3 + ooff] = (ki[3 + ioff] << rot) | (ki[0 + ioff] >> (32 - rot)); + ki[0 + ioff] = ko[0 + ooff]; + ki[1 + ioff] = ko[1 + ooff]; + ki[2 + ioff] = ko[2 + ooff]; + ki[3 + ioff] = ko[3 + ooff]; + } + + private static void decroldq(int rot, uint[] ki, int ioff, uint[] ko, int ooff) + { + ko[2 + ooff] = (ki[0 + ioff] << rot) | (ki[1 + ioff] >> (32 - rot)); + ko[3 + ooff] = (ki[1 + ioff] << rot) | (ki[2 + ioff] >> (32 - rot)); + ko[0 + ooff] = (ki[2 + ioff] << rot) | (ki[3 + ioff] >> (32 - rot)); + ko[1 + ooff] = (ki[3 + ioff] << rot) | (ki[0 + ioff] >> (32 - rot)); + ki[0 + ioff] = ko[2 + ooff]; + ki[1 + ioff] = ko[3 + ooff]; + ki[2 + ioff] = ko[0 + ooff]; + ki[3 + ioff] = ko[1 + ooff]; + } + + private static void roldqo32(int rot, uint[] ki, int ioff, uint[] ko, int ooff) + { + ko[0 + ooff] = (ki[1 + ioff] << (rot - 32)) | (ki[2 + ioff] >> (64 - rot)); + ko[1 + ooff] = (ki[2 + ioff] << (rot - 32)) | (ki[3 + ioff] >> (64 - rot)); + ko[2 + ooff] = (ki[3 + ioff] << (rot - 32)) | (ki[0 + ioff] >> (64 - rot)); + ko[3 + ooff] = (ki[0 + ioff] << (rot - 32)) | (ki[1 + ioff] >> (64 - rot)); + ki[0 + ioff] = ko[0 + ooff]; + ki[1 + ioff] = ko[1 + ooff]; + ki[2 + ioff] = ko[2 + ooff]; + ki[3 + ioff] = ko[3 + ooff]; + } + + private static void decroldqo32(int rot, uint[] ki, int ioff, uint[] ko, int ooff) + { + ko[2 + ooff] = (ki[1 + ioff] << (rot - 32)) | (ki[2 + ioff] >> (64 - rot)); + ko[3 + ooff] = (ki[2 + ioff] << (rot - 32)) | (ki[3 + ioff] >> (64 - rot)); + ko[0 + ooff] = (ki[3 + ioff] << (rot - 32)) | (ki[0 + ioff] >> (64 - rot)); + ko[1 + ooff] = (ki[0 + ioff] << (rot - 32)) | (ki[1 + ioff] >> (64 - rot)); + ki[0 + ioff] = ko[2 + ooff]; + ki[1 + ioff] = ko[3 + ooff]; + ki[2 + ioff] = ko[0 + ooff]; + ki[3 + ioff] = ko[1 + ooff]; + } + + private static uint bytes2uint(byte[] src, int offset) + { + uint word = 0; + for (int i = 0; i < 4; i++) + { + word = (word << 8) + (uint)src[i + offset]; + } + return word; + } + + private static void uint2bytes(uint word, byte[] dst, int offset) + { + for (int i = 0; i < 4; i++) + { + dst[(3 - i) + offset] = (byte)word; + word >>= 8; + } + } + + private byte lRot8(byte v, int rot) + { + return (byte)(((uint)v << rot) | ((uint)v >> (8 - rot))); + } + + private uint sbox2(int x) + { + return (uint)lRot8(SBOX1[x], 1); + } + + private uint sbox3(int x) + { + return (uint)lRot8(SBOX1[x], 7); + } + + private uint sbox4(int x) + { + return (uint)SBOX1[lRot8((byte)x, 1)]; + } + + private void camelliaF2(uint[] s, uint[] skey, int keyoff) + { + uint t1, t2, u, v; + + t1 = s[0] ^ skey[0 + keyoff]; + u = sbox4((byte)t1); + u |= (sbox3((byte)(t1 >> 8)) << 8); + u |= (sbox2((byte)(t1 >> 16)) << 16); + u |= ((uint)(SBOX1[(byte)(t1 >> 24)]) << 24); + + t2 = s[1] ^ skey[1 + keyoff]; + v = (uint)SBOX1[(byte)t2]; + v |= (sbox4((byte)(t2 >> 8)) << 8); + v |= (sbox3((byte)(t2 >> 16)) << 16); + v |= (sbox2((byte)(t2 >> 24)) << 24); + + v = leftRotate(v, 8); + u ^= v; + v = leftRotate(v, 8) ^ u; + u = rightRotate(u, 8) ^ v; + s[2] ^= leftRotate(v, 16) ^ u; + s[3] ^= leftRotate(u, 8); + + t1 = s[2] ^ skey[2 + keyoff]; + u = sbox4((byte)t1); + u |= sbox3((byte)(t1 >> 8)) << 8; + u |= sbox2((byte)(t1 >> 16)) << 16; + u |= ((uint)SBOX1[(byte)(t1 >> 24)]) << 24; + + t2 = s[3] ^ skey[3 + keyoff]; + v = (uint)SBOX1[(byte)t2]; + v |= sbox4((byte)(t2 >> 8)) << 8; + v |= sbox3((byte)(t2 >> 16)) << 16; + v |= sbox2((byte)(t2 >> 24)) << 24; + + v = leftRotate(v, 8); + u ^= v; + v = leftRotate(v, 8) ^ u; + u = rightRotate(u, 8) ^ v; + s[0] ^= leftRotate(v, 16) ^ u; + s[1] ^= leftRotate(u, 8); + } + + private void camelliaFLs(uint[] s, uint[] fkey, int keyoff) + { + s[1] ^= leftRotate(s[0] & fkey[0 + keyoff], 1); + s[0] ^= fkey[1 + keyoff] | s[1]; + + s[2] ^= fkey[3 + keyoff] | s[3]; + s[3] ^= leftRotate(fkey[2 + keyoff] & s[2], 1); + } + + private void setKey(bool forEncryption, byte[] key) + { + uint[] k = new uint[8]; + uint[] ka = new uint[4]; + uint[] kb = new uint[4]; + uint[] t = new uint[4]; + + switch (key.Length) + { + case 16: + _keyis128 = true; + k[0] = bytes2uint(key, 0); + k[1] = bytes2uint(key, 4); + k[2] = bytes2uint(key, 8); + k[3] = bytes2uint(key, 12); + k[4] = k[5] = k[6] = k[7] = 0; + break; + case 24: + k[0] = bytes2uint(key, 0); + k[1] = bytes2uint(key, 4); + k[2] = bytes2uint(key, 8); + k[3] = bytes2uint(key, 12); + k[4] = bytes2uint(key, 16); + k[5] = bytes2uint(key, 20); + k[6] = ~k[4]; + k[7] = ~k[5]; + _keyis128 = false; + break; + case 32: + k[0] = bytes2uint(key, 0); + k[1] = bytes2uint(key, 4); + k[2] = bytes2uint(key, 8); + k[3] = bytes2uint(key, 12); + k[4] = bytes2uint(key, 16); + k[5] = bytes2uint(key, 20); + k[6] = bytes2uint(key, 24); + k[7] = bytes2uint(key, 28); + _keyis128 = false; + break; + default: + throw new ArgumentException("key sizes are only 16/24/32 bytes."); + } + + for (int i = 0; i < 4; i++) + { + ka[i] = k[i] ^ k[i + 4]; + } + /* compute KA */ + camelliaF2(ka, SIGMA, 0); + for (int i = 0; i < 4; i++) + { + ka[i] ^= k[i]; + } + camelliaF2(ka, SIGMA, 4); + + if (_keyis128) + { + if (forEncryption) + { + /* KL dependant keys */ + kw[0] = k[0]; + kw[1] = k[1]; + kw[2] = k[2]; + kw[3] = k[3]; + roldq(15, k, 0, subkey, 4); + roldq(30, k, 0, subkey, 12); + roldq(15, k, 0, t, 0); + subkey[18] = t[2]; + subkey[19] = t[3]; + roldq(17, k, 0, ke, 4); + roldq(17, k, 0, subkey, 24); + roldq(17, k, 0, subkey, 32); + /* KA dependant keys */ + subkey[0] = ka[0]; + subkey[1] = ka[1]; + subkey[2] = ka[2]; + subkey[3] = ka[3]; + roldq(15, ka, 0, subkey, 8); + roldq(15, ka, 0, ke, 0); + roldq(15, ka, 0, t, 0); + subkey[16] = t[0]; + subkey[17] = t[1]; + roldq(15, ka, 0, subkey, 20); + roldqo32(34, ka, 0, subkey, 28); + roldq(17, ka, 0, kw, 4); + + } + else + { // decryption + /* KL dependant keys */ + kw[4] = k[0]; + kw[5] = k[1]; + kw[6] = k[2]; + kw[7] = k[3]; + decroldq(15, k, 0, subkey, 28); + decroldq(30, k, 0, subkey, 20); + decroldq(15, k, 0, t, 0); + subkey[16] = t[0]; + subkey[17] = t[1]; + decroldq(17, k, 0, ke, 0); + decroldq(17, k, 0, subkey, 8); + decroldq(17, k, 0, subkey, 0); + /* KA dependant keys */ + subkey[34] = ka[0]; + subkey[35] = ka[1]; + subkey[32] = ka[2]; + subkey[33] = ka[3]; + decroldq(15, ka, 0, subkey, 24); + decroldq(15, ka, 0, ke, 4); + decroldq(15, ka, 0, t, 0); + subkey[18] = t[2]; + subkey[19] = t[3]; + decroldq(15, ka, 0, subkey, 12); + decroldqo32(34, ka, 0, subkey, 4); + roldq(17, ka, 0, kw, 0); + } + } + else + { // 192bit or 256bit + /* compute KB */ + for (int i = 0; i < 4; i++) + { + kb[i] = ka[i] ^ k[i + 4]; + } + camelliaF2(kb, SIGMA, 8); + + if (forEncryption) + { + /* KL dependant keys */ + kw[0] = k[0]; + kw[1] = k[1]; + kw[2] = k[2]; + kw[3] = k[3]; + roldqo32(45, k, 0, subkey, 16); + roldq(15, k, 0, ke, 4); + roldq(17, k, 0, subkey, 32); + roldqo32(34, k, 0, subkey, 44); + /* KR dependant keys */ + roldq(15, k, 4, subkey, 4); + roldq(15, k, 4, ke, 0); + roldq(30, k, 4, subkey, 24); + roldqo32(34, k, 4, subkey, 36); + /* KA dependant keys */ + roldq(15, ka, 0, subkey, 8); + roldq(30, ka, 0, subkey, 20); + /* 32bit rotation */ + ke[8] = ka[1]; + ke[9] = ka[2]; + ke[10] = ka[3]; + ke[11] = ka[0]; + roldqo32(49, ka, 0, subkey, 40); + + /* KB dependant keys */ + subkey[0] = kb[0]; + subkey[1] = kb[1]; + subkey[2] = kb[2]; + subkey[3] = kb[3]; + roldq(30, kb, 0, subkey, 12); + roldq(30, kb, 0, subkey, 28); + roldqo32(51, kb, 0, kw, 4); + + } + else + { // decryption + /* KL dependant keys */ + kw[4] = k[0]; + kw[5] = k[1]; + kw[6] = k[2]; + kw[7] = k[3]; + decroldqo32(45, k, 0, subkey, 28); + decroldq(15, k, 0, ke, 4); + decroldq(17, k, 0, subkey, 12); + decroldqo32(34, k, 0, subkey, 0); + /* KR dependant keys */ + decroldq(15, k, 4, subkey, 40); + decroldq(15, k, 4, ke, 8); + decroldq(30, k, 4, subkey, 20); + decroldqo32(34, k, 4, subkey, 8); + /* KA dependant keys */ + decroldq(15, ka, 0, subkey, 36); + decroldq(30, ka, 0, subkey, 24); + /* 32bit rotation */ + ke[2] = ka[1]; + ke[3] = ka[2]; + ke[0] = ka[3]; + ke[1] = ka[0]; + decroldqo32(49, ka, 0, subkey, 4); + + /* KB dependant keys */ + subkey[46] = kb[0]; + subkey[47] = kb[1]; + subkey[44] = kb[2]; + subkey[45] = kb[3]; + decroldq(30, kb, 0, subkey, 32); + decroldq(30, kb, 0, subkey, 16); + roldqo32(51, kb, 0, kw, 0); + } + } + } + + private int processBlock128(byte[] input, int inOff, byte[] output, int outOff) + { + for (int i = 0; i < 4; i++) + { + state[i] = bytes2uint(input, inOff + (i * 4)); + state[i] ^= kw[i]; + } + + camelliaF2(state, subkey, 0); + camelliaF2(state, subkey, 4); + camelliaF2(state, subkey, 8); + camelliaFLs(state, ke, 0); + camelliaF2(state, subkey, 12); + camelliaF2(state, subkey, 16); + camelliaF2(state, subkey, 20); + camelliaFLs(state, ke, 4); + camelliaF2(state, subkey, 24); + camelliaF2(state, subkey, 28); + camelliaF2(state, subkey, 32); + + state[2] ^= kw[4]; + state[3] ^= kw[5]; + state[0] ^= kw[6]; + state[1] ^= kw[7]; + + uint2bytes(state[2], output, outOff); + uint2bytes(state[3], output, outOff + 4); + uint2bytes(state[0], output, outOff + 8); + uint2bytes(state[1], output, outOff + 12); + + return BLOCK_SIZE; + } + + private int processBlock192or256(byte[] input, int inOff, byte[] output, int outOff) + { + for (int i = 0; i < 4; i++) + { + state[i] = bytes2uint(input, inOff + (i * 4)); + state[i] ^= kw[i]; + } + + camelliaF2(state, subkey, 0); + camelliaF2(state, subkey, 4); + camelliaF2(state, subkey, 8); + camelliaFLs(state, ke, 0); + camelliaF2(state, subkey, 12); + camelliaF2(state, subkey, 16); + camelliaF2(state, subkey, 20); + camelliaFLs(state, ke, 4); + camelliaF2(state, subkey, 24); + camelliaF2(state, subkey, 28); + camelliaF2(state, subkey, 32); + camelliaFLs(state, ke, 8); + camelliaF2(state, subkey, 36); + camelliaF2(state, subkey, 40); + camelliaF2(state, subkey, 44); + + state[2] ^= kw[4]; + state[3] ^= kw[5]; + state[0] ^= kw[6]; + state[1] ^= kw[7]; + + uint2bytes(state[2], output, outOff); + uint2bytes(state[3], output, outOff + 4); + uint2bytes(state[0], output, outOff + 8); + uint2bytes(state[1], output, outOff + 12); + return BLOCK_SIZE; + } + + public CamelliaLightEngine() + { + initialised = false; + } + + public virtual string AlgorithmName + { + get { return "Camellia"; } + } + + public virtual bool IsPartialBlockOkay + { + get { return false; } + } + + public virtual int GetBlockSize() + { + return BLOCK_SIZE; + } + + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (!(parameters is KeyParameter)) + throw new ArgumentException("only simple KeyParameter expected."); + + setKey(forEncryption, ((KeyParameter)parameters).GetKey()); + + initialised = true; + } + + public virtual int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + if (!initialised) + throw new InvalidOperationException("Camellia engine not initialised"); + + Check.DataLength(input, inOff, BLOCK_SIZE, "input buffer too short"); + Check.OutputLength(output, outOff, BLOCK_SIZE, "output buffer too short"); + + if (_keyis128) + { + return processBlock128(input, inOff, output, outOff); + } + else + { + return processBlock192or256(input, inOff, output, outOff); + } + } + + public virtual void Reset() + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/CamelliaLightEngine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/CamelliaLightEngine.cs.meta new file mode 100644 index 0000000..2d41fce --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/CamelliaLightEngine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0915cdf529a856c42ba65180ccdedf3e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/CamelliaWrapEngine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/CamelliaWrapEngine.cs new file mode 100644 index 0000000..49dc833 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/CamelliaWrapEngine.cs @@ -0,0 +1,16 @@ +namespace Org.BouncyCastle.Crypto.Engines +{ + /// + /// An implementation of the Camellia key wrapper based on RFC 3657/RFC 3394. + ///

+ /// For further details see: http://www.ietf.org/rfc/rfc3657.txt. + /// + public class CamelliaWrapEngine + : Rfc3394WrapEngine + { + public CamelliaWrapEngine() + : base(new CamelliaEngine()) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/CamelliaWrapEngine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/CamelliaWrapEngine.cs.meta new file mode 100644 index 0000000..29ef720 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/CamelliaWrapEngine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c0a0e6299a7fd1c46b7932d01d3babfa +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/Cast5Engine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/Cast5Engine.cs new file mode 100644 index 0000000..398f6d4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/Cast5Engine.cs @@ -0,0 +1,802 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * A class that provides CAST key encryption operations, + * such as encoding data and generating keys. + * + * All the algorithms herein are from the Internet RFC's + * + * RFC2144 - Cast5 (64bit block, 40-128bit key) + * RFC2612 - CAST6 (128bit block, 128-256bit key) + * + * and implement a simplified cryptography interface. + */ + public class Cast5Engine + : IBlockCipher + { + private static readonly uint[] S1 = + { + 0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f, 0x9c004dd3, 0x6003e540, 0xcf9fc949, + 0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675, 0x6e63a0e0, 0x15c361d2, 0xc2e7661d, 0x22d4ff8e, + 0x28683b6f, 0xc07fd059, 0xff2379c8, 0x775f50e2, 0x43c340d3, 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d, + 0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f, 0x2abe32e1, 0xaa54166b, 0x22568e3a, 0xa2d341d0, + 0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de, 0x97943fac, 0x4a97c1d8, 0x527644b7, 0xb5f437a7, + 0xb82cbaef, 0xd751d159, 0x6ff7f0ed, 0x5a097a1f, 0x827b68d0, 0x90ecf52e, 0x22b0c054, 0xbc8e5935, + 0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d, 0xb7332290, 0xe93b159f, 0xb48ee411, 0x4bff345d, + 0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165, 0xd5b1caad, 0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50, + 0x882240f2, 0x0c6e4f38, 0xa4e4bfd7, 0x4f5ba272, 0x564c1d2f, 0xc59c5319, 0xb949e354, 0xb04669fe, + 0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d, 0x57538ad5, 0x6a390493, 0xe63d37e0, 0x2a54f6b3, + 0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a, 0x29f9d4d5, 0xf61b1891, 0xbb72275e, 0xaa508167, + 0x38901091, 0xc6b505eb, 0x84c7cb8c, 0x2ad75a0f, 0x874a1427, 0xa2d1936b, 0x2ad286af, 0xaa56d291, + 0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9, 0x6c00b32d, 0x73e2bb14, 0xa0bebc3c, 0x54623779, + 0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6, 0x04ee002e, 0x89fe78e6, 0x3fab0950, 0x325ff6c2, + 0x81383f05, 0x6963c5c8, 0x76cb5ad6, 0xd49974c9, 0xca180dcf, 0x380782d5, 0xc7fa5cf6, 0x8ac31511, + 0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e, 0x31366241, 0x051ef495, 0xaa573b04, 0x4a805d8d, + 0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e, 0x75c6372b, 0x50afd341, 0xa7c13275, 0x915a0bf5, + 0x6b54bfab, 0x2b0b1426, 0xab4cc9d7, 0x449ccd82, 0xf7fbf265, 0xab85c5f3, 0x1b55db94, 0xaad4e324, + 0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac, 0xeadf55b3, 0xd5bd9e98, 0xe31231b2, 0x2ad5ad6c, + 0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f, 0xaa786bf6, 0x22513f1e, 0xaa51a79b, 0x2ad344cc, + 0x7b5a41f0, 0xd37cfbad, 0x1b069505, 0x41ece491, 0xb4c332e6, 0x032268d4, 0xc9600acc, 0xce387e6d, + 0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de, 0xe01063da, 0x4736f464, 0x5ad328d8, 0xb347cc96, + 0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a, 0xe11f0abc, 0xbfc5fe4a, 0xa70aec10, 0xac39570a, + 0x3f04442f, 0x6188b153, 0xe0397a2e, 0x5727cb79, 0x9ceb418f, 0x1cacd68d, 0x2ad37c96, 0x0175cb9d, + 0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779, 0x4744ead4, 0xb11c3274, 0xdd24cb9e, 0x7e1c54bd, + 0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755, 0xd47c27af, 0x51c85f4d, 0x56907596, 0xa5bb15e6, + 0x580304f0, 0xca042cf1, 0x011a37ea, 0x8dbfaadb, 0x35ba3e4a, 0x3526ffa0, 0xc37b4d09, 0xbc306ed9, + 0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0, 0x7c63b2cf, 0x700b45e1, 0xd5ea50f1, 0x85a92872, + 0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79, 0x42e04198, 0x0cd0ede7, 0x26470db8, 0xf881814c, + 0x474d6ad7, 0x7c0c5e5c, 0xd1231959, 0x381b7298, 0xf5d2f4db, 0xab838653, 0x6e2f1e23, 0x83719c9e, + 0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, 0x962bda1c, 0xe1e696ff, 0xb141ab08, 0x7cca89b9, + 0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d, 0x427b169c, 0x5ac9f049, 0xdd8f0f00, 0x5c8165bf + }, + S2 = + { + 0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a, 0xeec5207a, 0x55889c94, 0x72fc0651, + 0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba, 0x99c430ef, 0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3, + 0xa0b52f7b, 0x59e83605, 0xee15b094, 0xe9ffd909, 0xdc440086, 0xef944459, 0xba83ccb3, 0xe0c3cdfb, + 0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, 0x01420ddb, 0xe4e7ef5b, 0x25a1ff41, 0xe180f806, + 0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4, 0x98de8b7f, 0x77e83f4e, 0x79929269, 0x24fa9f7b, + 0xe113c85b, 0xacc40083, 0xd7503525, 0xf7ea615f, 0x62143154, 0x0d554b63, 0x5d681121, 0xc866c359, + 0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21, 0x071f6181, 0x39f7627f, 0x361e3084, 0xe4eb573b, + 0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d, 0x2701f50c, 0x99847ab4, 0xa0e3df79, 0xba6cf38c, + 0x10843094, 0x2537a95e, 0xf46f6ffe, 0xa1ff3b1f, 0x208cfb6a, 0x8f458c74, 0xd9e0a227, 0x4ec73a34, + 0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d, 0x8a45388c, 0x1d804366, 0x721d9bfd, 0xa58684bb, + 0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4, 0xce280ae1, 0x27e19ba5, 0xd5a6c252, 0xe49754bd, + 0xc5d655dd, 0xeb667064, 0x77840b4d, 0xa1b6a801, 0x84db26a9, 0xe0b56714, 0x21f043b7, 0xe5d05860, + 0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755, 0xb5625dbf, 0x68561be6, 0x83ca6b94, 0x2d6ed23b, + 0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709, 0x33b4a34c, 0x397bc8d6, 0x5ee22b95, 0x5f0e5304, + 0x81ed6f61, 0x20e74364, 0xb45e1378, 0xde18639b, 0x881ca122, 0xb96726d1, 0x8049a7e8, 0x22b7da7b, + 0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, 0x488cb402, 0x1ba4fe5b, 0xa4b09f6b, 0x1ca815cf, + 0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9, 0x0beeff53, 0xe3214517, 0xb4542835, 0x9f63293c, + 0xee41e729, 0x6e1d2d7c, 0x50045286, 0x1e6685f3, 0xf33401c6, 0x30a22c95, 0x31a70850, 0x60930f13, + 0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9, 0xcdff33a6, 0xa02b1741, 0x7cbad9a2, 0x2180036f, + 0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab, 0x80342676, 0x25a75e7b, 0xe4e6d1fc, 0x20c710e6, + 0xcdf0b680, 0x17844d3b, 0x31eef84d, 0x7e0824e4, 0x2ccb49eb, 0x846a3bae, 0x8ff77888, 0xee5d60f6, + 0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43, 0xb3faec54, 0x157fd7fa, 0xef8579cc, 0xd152de58, + 0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8, 0x99319ad5, 0xc242fa0f, 0xa7e3ebb0, 0xc68e4906, + 0xb8da230c, 0x80823028, 0xdcdef3c8, 0xd35fb171, 0x088a1bc8, 0xbec0c560, 0x61a3c9e8, 0xbca8f54d, + 0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89, 0x8b1c34bc, 0x301e16e6, 0x273be979, 0xb0ffeaa6, + 0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b, 0x43daf65a, 0xf7e19798, 0x7619b72f, 0x8f1c9ba4, + 0xdc8637a0, 0x16a7d3b1, 0x9fc393b7, 0xa7136eeb, 0xc6bcc63e, 0x1a513742, 0xef6828bc, 0x520365d6, + 0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e, 0xdb92f2fb, 0x5eea29cb, 0x145892f5, 0x91584f7f, + 0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea, 0x833860d4, 0x0d23e0f9, 0x6c387e8a, 0x0ae6d249, + 0xb284600c, 0xd835731d, 0xdcb1c647, 0xac4c56ea, 0x3ebd81b3, 0x230eabb0, 0x6438bc87, 0xf0b5b1fa, + 0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, 0x649da589, 0xa345415e, 0x5c038323, 0x3e5d3bb9, + 0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef, 0x7160a539, 0x73bfbe70, 0x83877605, 0x4523ecf1 + }, + S3 = + { + 0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff, 0x369fe44b, 0x8c1fc644, 0xaececa90, + 0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae, 0x920e8806, 0xf0ad0548, 0xe13c8d83, 0x927010d5, + 0x11107d9f, 0x07647db9, 0xb2e3e4d4, 0x3d4f285e, 0xb9afa820, 0xfade82e0, 0xa067268b, 0x8272792e, + 0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc, 0x21fffcee, 0x825b1bfd, 0x9255c5ed, 0x1257a240, + 0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e, 0x3373f7bf, 0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5, + 0xa8c01db7, 0x579fc264, 0x67094f31, 0xf2bd3f5f, 0x40fff7c1, 0x1fb78dfc, 0x8e6bd2c1, 0x437be59b, + 0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99, 0xa197c81c, 0x4a012d6e, 0xc5884a28, 0xccc36f71, + 0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f, 0x2f7fe850, 0xd7c07f7e, 0x02507fbf, 0x5afb9a04, + 0xa747d2d0, 0x1651192e, 0xaf70bf3e, 0x58c31380, 0x5f98302e, 0x727cc3c4, 0x0a0fb402, 0x0f7fef82, + 0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8, 0x8427f4a0, 0x1eac5790, 0x796fb449, 0x8252dc15, + 0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504, 0xfa5d7403, 0xe83ec305, 0x4f91751a, 0x925669c2, + 0x23efe941, 0xa903f12e, 0x60270df2, 0x0276e4b6, 0x94fd6574, 0x927985b2, 0x8276dbcb, 0x02778176, + 0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e, 0x842f7d83, 0x340ce5c8, 0x96bbb682, 0x93b4b148, + 0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d, 0x224d1e20, 0x8437aa88, 0x7d29dc96, 0x2756d3dc, + 0x8b907cee, 0xb51fd240, 0xe7c07ce3, 0xe566b4a1, 0xc3e9615e, 0x3cf8209d, 0x6094d1e3, 0xcd9ca341, + 0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, 0xf76cedd9, 0xbda8229c, 0x127dadaa, 0x438a074e, + 0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15, 0x97b03cff, 0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51, + 0x68cc7bfb, 0xd90f2788, 0x12490181, 0x5de5ffd4, 0xdd7ef86a, 0x76a2e214, 0xb9a40368, 0x925d958f, + 0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b, 0x6d498623, 0x193cbcfa, 0x27627545, 0x825cf47a, + 0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392, 0x10428db7, 0x8272a972, 0x9270c4a8, 0x127de50b, + 0x285ba1c8, 0x3c62f44f, 0x35c0eaa5, 0xe805d231, 0x428929fb, 0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b, + 0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889, 0x694bcc11, 0x236a5cae, 0x12deca4d, 0x2c3f8cc5, + 0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67, 0x494a488c, 0xb9b6a80c, 0x5c8f82bc, 0x89d36b45, + 0x3a609437, 0xec00c9a9, 0x44715253, 0x0a874b49, 0xd773bc40, 0x7c34671c, 0x02717ef6, 0x4feb5536, + 0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d, 0x07478cd1, 0x006e1888, 0xa2e53f55, 0xb9e6d4bc, + 0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d, 0x72f87b33, 0xabcc4f33, 0x7688c55d, 0x7b00a6b0, + 0x947b0001, 0x570075d2, 0xf9bb88f8, 0x8942019e, 0x4264a5ff, 0x856302e0, 0x72dbd92b, 0xee971b69, + 0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767, 0xcf1febd2, 0x61efc8c2, 0xf1ac2571, 0xcc8239c2, + 0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce, 0xf90a5c38, 0x0ff0443d, 0x606e6dc6, 0x60543a49, + 0x5727c148, 0x2be98a1d, 0x8ab41738, 0x20e1be24, 0xaf96da0f, 0x68458425, 0x99833be5, 0x600d457d, + 0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31, 0x9c305a00, 0x52bce688, 0x1b03588a, + 0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, 0xdfef4636, 0xa133c501, 0xe9d3531c, 0xee353783 + }, + S4 = + { + 0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb, 0x64ad8c57, 0x85510443, 0xfa020ed1, + 0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120, 0xfd059d43, 0x6497b7b1, 0xf3641f63, 0x241e4adf, + 0x28147f5f, 0x4fa2b8cd, 0xc9430040, 0x0cc32220, 0xfdd30b30, 0xc0a5374f, 0x1d2d00d9, 0x24147b15, + 0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe, 0x1a05645f, 0x0c13fefe, 0x081b08ca, 0x05170121, + 0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701, 0xd2b8ee5f, 0x06df4261, 0xbb9e9b8a, 0x7293ea25, + 0xce84ffdf, 0xf5718801, 0x3dd64b04, 0xa26f263b, 0x7ed48400, 0x547eebe6, 0x446d4ca0, 0x6cf3d6f5, + 0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93, 0xd3772061, 0x11b638e1, 0x72500e03, 0xf80eb2bb, + 0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746, 0xc9335400, 0x6920318f, 0x081dbb99, 0xffc304a5, + 0x4d351805, 0x7f3d5ce3, 0xa6c866c6, 0x5d5bcca9, 0xdaec6fea, 0x9f926f91, 0x9f46222f, 0x3991467d, + 0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb, 0x022083b8, 0x3fb6180c, 0x18f8931e, 0x281658e6, + 0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c, 0xf32d0a25, 0x79098b02, 0xe4eabb81, 0x28123b23, + 0x69dead38, 0x1574ca16, 0xdf871b62, 0x211c40b7, 0xa51a9ef9, 0x0014377b, 0x041e8ac8, 0x09114003, + 0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340, 0x557be8de, 0x00eae4a7, 0x0ce5c2ec, 0x4db4bba6, + 0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327, 0x99afc8b0, 0x56c8c391, 0x6b65811c, 0x5e146119, + 0x6e85cb75, 0xbe07c002, 0xc2325577, 0x893ff4ec, 0x5bbfc92d, 0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24, + 0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, 0xaac9548a, 0xeca1d7c7, 0x041afa32, 0x1d16625a, + 0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031, 0x36cc6fdb, 0xc70b8b46, 0xd9e66a48, 0x56e55a79, + 0x026a4ceb, 0x52437eff, 0x2f8f76b4, 0x0df980a5, 0x8674cde3, 0xedda04eb, 0x17a9be04, 0x2c18f4df, + 0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c, 0x1741a254, 0xe5b6a035, 0x213d42f6, 0x2c1c7c26, + 0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69, 0xd8167fa2, 0x0418f2c8, 0x001a96a6, 0x0d1526ab, + 0x63315c21, 0x5e0a72ec, 0x49bafefd, 0x187908d9, 0x8d0dbd86, 0x311170a7, 0x3e9b640c, 0xcc3e10d7, + 0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff, 0x71eae2a1, 0x1f9af36e, 0xcfcbd12f, 0xc1de8417, + 0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3, 0xb1c52fca, 0xb4be31cd, 0xd8782806, 0x12a3a4e2, + 0x6f7de532, 0x58fd7eb6, 0xd01ee900, 0x24adffc2, 0xf4990fc5, 0x9711aac5, 0x001d7b95, 0x82e5e7d2, + 0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff, 0x29908415, 0x7fbb977f, 0xaf9eb3db, 0x29c9ed2a, + 0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091, 0xd49e2ce7, 0x0ce454a9, 0xd60acd86, 0x015f1919, + 0x77079103, 0xdea03af6, 0x78a8565e, 0xdee356df, 0x21f05cbe, 0x8b75e387, 0xb3c50651, 0xb8a5c3ef, + 0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf, 0xafe67afb, 0xf470c4b2, 0xf3e0eb5b, 0xd6cc9876, + 0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367, 0xa99144f8, 0x296b299e, 0x492fc295, 0x9266beab, + 0xb5676e69, 0x9bd3ddda, 0xdf7e052f, 0xdb25701c, 0x1b5e51ee, 0xf65324e6, 0x6afce36c, 0x0316cc04, + 0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, 0x41823979, 0x932bcdf6, 0xb657c34d, 0x4edfd282, + 0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e, 0x13ecf0b0, 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2 + }, + S5 = + { + 0x7ec90c04, 0x2c6e74b9, 0x9b0e66df, 0xa6337911, 0xb86a7fff, 0x1dd358f5, 0x44dd9d44, 0x1731167f, + 0x08fbf1fa, 0xe7f511cc, 0xd2051b00, 0x735aba00, 0x2ab722d8, 0x386381cb, 0xacf6243a, 0x69befd7a, + 0xe6a2e77f, 0xf0c720cd, 0xc4494816, 0xccf5c180, 0x38851640, 0x15b0a848, 0xe68b18cb, 0x4caadeff, + 0x5f480a01, 0x0412b2aa, 0x259814fc, 0x41d0efe2, 0x4e40b48d, 0x248eb6fb, 0x8dba1cfe, 0x41a99b02, + 0x1a550a04, 0xba8f65cb, 0x7251f4e7, 0x95a51725, 0xc106ecd7, 0x97a5980a, 0xc539b9aa, 0x4d79fe6a, + 0xf2f3f763, 0x68af8040, 0xed0c9e56, 0x11b4958b, 0xe1eb5a88, 0x8709e6b0, 0xd7e07156, 0x4e29fea7, + 0x6366e52d, 0x02d1c000, 0xc4ac8e05, 0x9377f571, 0x0c05372a, 0x578535f2, 0x2261be02, 0xd642a0c9, + 0xdf13a280, 0x74b55bd2, 0x682199c0, 0xd421e5ec, 0x53fb3ce8, 0xc8adedb3, 0x28a87fc9, 0x3d959981, + 0x5c1ff900, 0xfe38d399, 0x0c4eff0b, 0x062407ea, 0xaa2f4fb1, 0x4fb96976, 0x90c79505, 0xb0a8a774, + 0xef55a1ff, 0xe59ca2c2, 0xa6b62d27, 0xe66a4263, 0xdf65001f, 0x0ec50966, 0xdfdd55bc, 0x29de0655, + 0x911e739a, 0x17af8975, 0x32c7911c, 0x89f89468, 0x0d01e980, 0x524755f4, 0x03b63cc9, 0x0cc844b2, + 0xbcf3f0aa, 0x87ac36e9, 0xe53a7426, 0x01b3d82b, 0x1a9e7449, 0x64ee2d7e, 0xcddbb1da, 0x01c94910, + 0xb868bf80, 0x0d26f3fd, 0x9342ede7, 0x04a5c284, 0x636737b6, 0x50f5b616, 0xf24766e3, 0x8eca36c1, + 0x136e05db, 0xfef18391, 0xfb887a37, 0xd6e7f7d4, 0xc7fb7dc9, 0x3063fcdf, 0xb6f589de, 0xec2941da, + 0x26e46695, 0xb7566419, 0xf654efc5, 0xd08d58b7, 0x48925401, 0xc1bacb7f, 0xe5ff550f, 0xb6083049, + 0x5bb5d0e8, 0x87d72e5a, 0xab6a6ee1, 0x223a66ce, 0xc62bf3cd, 0x9e0885f9, 0x68cb3e47, 0x086c010f, + 0xa21de820, 0xd18b69de, 0xf3f65777, 0xfa02c3f6, 0x407edac3, 0xcbb3d550, 0x1793084d, 0xb0d70eba, + 0x0ab378d5, 0xd951fb0c, 0xded7da56, 0x4124bbe4, 0x94ca0b56, 0x0f5755d1, 0xe0e1e56e, 0x6184b5be, + 0x580a249f, 0x94f74bc0, 0xe327888e, 0x9f7b5561, 0xc3dc0280, 0x05687715, 0x646c6bd7, 0x44904db3, + 0x66b4f0a3, 0xc0f1648a, 0x697ed5af, 0x49e92ff6, 0x309e374f, 0x2cb6356a, 0x85808573, 0x4991f840, + 0x76f0ae02, 0x083be84d, 0x28421c9a, 0x44489406, 0x736e4cb8, 0xc1092910, 0x8bc95fc6, 0x7d869cf4, + 0x134f616f, 0x2e77118d, 0xb31b2be1, 0xaa90b472, 0x3ca5d717, 0x7d161bba, 0x9cad9010, 0xaf462ba2, + 0x9fe459d2, 0x45d34559, 0xd9f2da13, 0xdbc65487, 0xf3e4f94e, 0x176d486f, 0x097c13ea, 0x631da5c7, + 0x445f7382, 0x175683f4, 0xcdc66a97, 0x70be0288, 0xb3cdcf72, 0x6e5dd2f3, 0x20936079, 0x459b80a5, + 0xbe60e2db, 0xa9c23101, 0xeba5315c, 0x224e42f2, 0x1c5c1572, 0xf6721b2c, 0x1ad2fff3, 0x8c25404e, + 0x324ed72f, 0x4067b7fd, 0x0523138e, 0x5ca3bc78, 0xdc0fd66e, 0x75922283, 0x784d6b17, 0x58ebb16e, + 0x44094f85, 0x3f481d87, 0xfcfeae7b, 0x77b5ff76, 0x8c2302bf, 0xaaf47556, 0x5f46b02a, 0x2b092801, + 0x3d38f5f7, 0x0ca81f36, 0x52af4a8a, 0x66d5e7c0, 0xdf3b0874, 0x95055110, 0x1b5ad7a8, 0xf61ed5ad, + 0x6cf6e479, 0x20758184, 0xd0cefa65, 0x88f7be58, 0x4a046826, 0x0ff6f8f3, 0xa09c7f70, 0x5346aba0, + 0x5ce96c28, 0xe176eda3, 0x6bac307f, 0x376829d2, 0x85360fa9, 0x17e3fe2a, 0x24b79767, 0xf5a96b20, + 0xd6cd2595, 0x68ff1ebf, 0x7555442c, 0xf19f06be, 0xf9e0659a, 0xeeb9491d, 0x34010718, 0xbb30cab8, + 0xe822fe15, 0x88570983, 0x750e6249, 0xda627e55, 0x5e76ffa8, 0xb1534546, 0x6d47de08, 0xefe9e7d4 + }, + S6 = + { + 0xf6fa8f9d, 0x2cac6ce1, 0x4ca34867, 0xe2337f7c, 0x95db08e7, 0x016843b4, 0xeced5cbc, 0x325553ac, + 0xbf9f0960, 0xdfa1e2ed, 0x83f0579d, 0x63ed86b9, 0x1ab6a6b8, 0xde5ebe39, 0xf38ff732, 0x8989b138, + 0x33f14961, 0xc01937bd, 0xf506c6da, 0xe4625e7e, 0xa308ea99, 0x4e23e33c, 0x79cbd7cc, 0x48a14367, + 0xa3149619, 0xfec94bd5, 0xa114174a, 0xeaa01866, 0xa084db2d, 0x09a8486f, 0xa888614a, 0x2900af98, + 0x01665991, 0xe1992863, 0xc8f30c60, 0x2e78ef3c, 0xd0d51932, 0xcf0fec14, 0xf7ca07d2, 0xd0a82072, + 0xfd41197e, 0x9305a6b0, 0xe86be3da, 0x74bed3cd, 0x372da53c, 0x4c7f4448, 0xdab5d440, 0x6dba0ec3, + 0x083919a7, 0x9fbaeed9, 0x49dbcfb0, 0x4e670c53, 0x5c3d9c01, 0x64bdb941, 0x2c0e636a, 0xba7dd9cd, + 0xea6f7388, 0xe70bc762, 0x35f29adb, 0x5c4cdd8d, 0xf0d48d8c, 0xb88153e2, 0x08a19866, 0x1ae2eac8, + 0x284caf89, 0xaa928223, 0x9334be53, 0x3b3a21bf, 0x16434be3, 0x9aea3906, 0xefe8c36e, 0xf890cdd9, + 0x80226dae, 0xc340a4a3, 0xdf7e9c09, 0xa694a807, 0x5b7c5ecc, 0x221db3a6, 0x9a69a02f, 0x68818a54, + 0xceb2296f, 0x53c0843a, 0xfe893655, 0x25bfe68a, 0xb4628abc, 0xcf222ebf, 0x25ac6f48, 0xa9a99387, + 0x53bddb65, 0xe76ffbe7, 0xe967fd78, 0x0ba93563, 0x8e342bc1, 0xe8a11be9, 0x4980740d, 0xc8087dfc, + 0x8de4bf99, 0xa11101a0, 0x7fd37975, 0xda5a26c0, 0xe81f994f, 0x9528cd89, 0xfd339fed, 0xb87834bf, + 0x5f04456d, 0x22258698, 0xc9c4c83b, 0x2dc156be, 0x4f628daa, 0x57f55ec5, 0xe2220abe, 0xd2916ebf, + 0x4ec75b95, 0x24f2c3c0, 0x42d15d99, 0xcd0d7fa0, 0x7b6e27ff, 0xa8dc8af0, 0x7345c106, 0xf41e232f, + 0x35162386, 0xe6ea8926, 0x3333b094, 0x157ec6f2, 0x372b74af, 0x692573e4, 0xe9a9d848, 0xf3160289, + 0x3a62ef1d, 0xa787e238, 0xf3a5f676, 0x74364853, 0x20951063, 0x4576698d, 0xb6fad407, 0x592af950, + 0x36f73523, 0x4cfb6e87, 0x7da4cec0, 0x6c152daa, 0xcb0396a8, 0xc50dfe5d, 0xfcd707ab, 0x0921c42f, + 0x89dff0bb, 0x5fe2be78, 0x448f4f33, 0x754613c9, 0x2b05d08d, 0x48b9d585, 0xdc049441, 0xc8098f9b, + 0x7dede786, 0xc39a3373, 0x42410005, 0x6a091751, 0x0ef3c8a6, 0x890072d6, 0x28207682, 0xa9a9f7be, + 0xbf32679d, 0xd45b5b75, 0xb353fd00, 0xcbb0e358, 0x830f220a, 0x1f8fb214, 0xd372cf08, 0xcc3c4a13, + 0x8cf63166, 0x061c87be, 0x88c98f88, 0x6062e397, 0x47cf8e7a, 0xb6c85283, 0x3cc2acfb, 0x3fc06976, + 0x4e8f0252, 0x64d8314d, 0xda3870e3, 0x1e665459, 0xc10908f0, 0x513021a5, 0x6c5b68b7, 0x822f8aa0, + 0x3007cd3e, 0x74719eef, 0xdc872681, 0x073340d4, 0x7e432fd9, 0x0c5ec241, 0x8809286c, 0xf592d891, + 0x08a930f6, 0x957ef305, 0xb7fbffbd, 0xc266e96f, 0x6fe4ac98, 0xb173ecc0, 0xbc60b42a, 0x953498da, + 0xfba1ae12, 0x2d4bd736, 0x0f25faab, 0xa4f3fceb, 0xe2969123, 0x257f0c3d, 0x9348af49, 0x361400bc, + 0xe8816f4a, 0x3814f200, 0xa3f94043, 0x9c7a54c2, 0xbc704f57, 0xda41e7f9, 0xc25ad33a, 0x54f4a084, + 0xb17f5505, 0x59357cbe, 0xedbd15c8, 0x7f97c5ab, 0xba5ac7b5, 0xb6f6deaf, 0x3a479c3a, 0x5302da25, + 0x653d7e6a, 0x54268d49, 0x51a477ea, 0x5017d55b, 0xd7d25d88, 0x44136c76, 0x0404a8c8, 0xb8e5a121, + 0xb81a928a, 0x60ed5869, 0x97c55b96, 0xeaec991b, 0x29935913, 0x01fdb7f1, 0x088e8dfa, 0x9ab6f6f5, + 0x3b4cbf9f, 0x4a5de3ab, 0xe6051d35, 0xa0e1d855, 0xd36b4cf1, 0xf544edeb, 0xb0e93524, 0xbebb8fbd, + 0xa2d762cf, 0x49c92f54, 0x38b5f331, 0x7128a454, 0x48392905, 0xa65b1db8, 0x851c97bd, 0xd675cf2f + }, + S7 = + { + 0x85e04019, 0x332bf567, 0x662dbfff, 0xcfc65693, 0x2a8d7f6f, 0xab9bc912, 0xde6008a1, 0x2028da1f, + 0x0227bce7, 0x4d642916, 0x18fac300, 0x50f18b82, 0x2cb2cb11, 0xb232e75c, 0x4b3695f2, 0xb28707de, + 0xa05fbcf6, 0xcd4181e9, 0xe150210c, 0xe24ef1bd, 0xb168c381, 0xfde4e789, 0x5c79b0d8, 0x1e8bfd43, + 0x4d495001, 0x38be4341, 0x913cee1d, 0x92a79c3f, 0x089766be, 0xbaeeadf4, 0x1286becf, 0xb6eacb19, + 0x2660c200, 0x7565bde4, 0x64241f7a, 0x8248dca9, 0xc3b3ad66, 0x28136086, 0x0bd8dfa8, 0x356d1cf2, + 0x107789be, 0xb3b2e9ce, 0x0502aa8f, 0x0bc0351e, 0x166bf52a, 0xeb12ff82, 0xe3486911, 0xd34d7516, + 0x4e7b3aff, 0x5f43671b, 0x9cf6e037, 0x4981ac83, 0x334266ce, 0x8c9341b7, 0xd0d854c0, 0xcb3a6c88, + 0x47bc2829, 0x4725ba37, 0xa66ad22b, 0x7ad61f1e, 0x0c5cbafa, 0x4437f107, 0xb6e79962, 0x42d2d816, + 0x0a961288, 0xe1a5c06e, 0x13749e67, 0x72fc081a, 0xb1d139f7, 0xf9583745, 0xcf19df58, 0xbec3f756, + 0xc06eba30, 0x07211b24, 0x45c28829, 0xc95e317f, 0xbc8ec511, 0x38bc46e9, 0xc6e6fa14, 0xbae8584a, + 0xad4ebc46, 0x468f508b, 0x7829435f, 0xf124183b, 0x821dba9f, 0xaff60ff4, 0xea2c4e6d, 0x16e39264, + 0x92544a8b, 0x009b4fc3, 0xaba68ced, 0x9ac96f78, 0x06a5b79a, 0xb2856e6e, 0x1aec3ca9, 0xbe838688, + 0x0e0804e9, 0x55f1be56, 0xe7e5363b, 0xb3a1f25d, 0xf7debb85, 0x61fe033c, 0x16746233, 0x3c034c28, + 0xda6d0c74, 0x79aac56c, 0x3ce4e1ad, 0x51f0c802, 0x98f8f35a, 0x1626a49f, 0xeed82b29, 0x1d382fe3, + 0x0c4fb99a, 0xbb325778, 0x3ec6d97b, 0x6e77a6a9, 0xcb658b5c, 0xd45230c7, 0x2bd1408b, 0x60c03eb7, + 0xb9068d78, 0xa33754f4, 0xf430c87d, 0xc8a71302, 0xb96d8c32, 0xebd4e7be, 0xbe8b9d2d, 0x7979fb06, + 0xe7225308, 0x8b75cf77, 0x11ef8da4, 0xe083c858, 0x8d6b786f, 0x5a6317a6, 0xfa5cf7a0, 0x5dda0033, + 0xf28ebfb0, 0xf5b9c310, 0xa0eac280, 0x08b9767a, 0xa3d9d2b0, 0x79d34217, 0x021a718d, 0x9ac6336a, + 0x2711fd60, 0x438050e3, 0x069908a8, 0x3d7fedc4, 0x826d2bef, 0x4eeb8476, 0x488dcf25, 0x36c9d566, + 0x28e74e41, 0xc2610aca, 0x3d49a9cf, 0xbae3b9df, 0xb65f8de6, 0x92aeaf64, 0x3ac7d5e6, 0x9ea80509, + 0xf22b017d, 0xa4173f70, 0xdd1e16c3, 0x15e0d7f9, 0x50b1b887, 0x2b9f4fd5, 0x625aba82, 0x6a017962, + 0x2ec01b9c, 0x15488aa9, 0xd716e740, 0x40055a2c, 0x93d29a22, 0xe32dbf9a, 0x058745b9, 0x3453dc1e, + 0xd699296e, 0x496cff6f, 0x1c9f4986, 0xdfe2ed07, 0xb87242d1, 0x19de7eae, 0x053e561a, 0x15ad6f8c, + 0x66626c1c, 0x7154c24c, 0xea082b2a, 0x93eb2939, 0x17dcb0f0, 0x58d4f2ae, 0x9ea294fb, 0x52cf564c, + 0x9883fe66, 0x2ec40581, 0x763953c3, 0x01d6692e, 0xd3a0c108, 0xa1e7160e, 0xe4f2dfa6, 0x693ed285, + 0x74904698, 0x4c2b0edd, 0x4f757656, 0x5d393378, 0xa132234f, 0x3d321c5d, 0xc3f5e194, 0x4b269301, + 0xc79f022f, 0x3c997e7e, 0x5e4f9504, 0x3ffafbbd, 0x76f7ad0e, 0x296693f4, 0x3d1fce6f, 0xc61e45be, + 0xd3b5ab34, 0xf72bf9b7, 0x1b0434c0, 0x4e72b567, 0x5592a33d, 0xb5229301, 0xcfd2a87f, 0x60aeb767, + 0x1814386b, 0x30bcc33d, 0x38a0c07d, 0xfd1606f2, 0xc363519b, 0x589dd390, 0x5479f8e6, 0x1cb8d647, + 0x97fd61a9, 0xea7759f4, 0x2d57539d, 0x569a58cf, 0xe84e63ad, 0x462e1b78, 0x6580f87e, 0xf3817914, + 0x91da55f4, 0x40a230f3, 0xd1988f35, 0xb6e318d2, 0x3ffa50bc, 0x3d40f021, 0xc3c0bdae, 0x4958c24c, + 0x518f36b2, 0x84b1d370, 0x0fedce83, 0x878ddada, 0xf2a279c7, 0x94e01be8, 0x90716f4b, 0x954b8aa3 + }, + S8 = + { + 0xe216300d, 0xbbddfffc, 0xa7ebdabd, 0x35648095, 0x7789f8b7, 0xe6c1121b, 0x0e241600, 0x052ce8b5, + 0x11a9cfb0, 0xe5952f11, 0xece7990a, 0x9386d174, 0x2a42931c, 0x76e38111, 0xb12def3a, 0x37ddddfc, + 0xde9adeb1, 0x0a0cc32c, 0xbe197029, 0x84a00940, 0xbb243a0f, 0xb4d137cf, 0xb44e79f0, 0x049eedfd, + 0x0b15a15d, 0x480d3168, 0x8bbbde5a, 0x669ded42, 0xc7ece831, 0x3f8f95e7, 0x72df191b, 0x7580330d, + 0x94074251, 0x5c7dcdfa, 0xabbe6d63, 0xaa402164, 0xb301d40a, 0x02e7d1ca, 0x53571dae, 0x7a3182a2, + 0x12a8ddec, 0xfdaa335d, 0x176f43e8, 0x71fb46d4, 0x38129022, 0xce949ad4, 0xb84769ad, 0x965bd862, + 0x82f3d055, 0x66fb9767, 0x15b80b4e, 0x1d5b47a0, 0x4cfde06f, 0xc28ec4b8, 0x57e8726e, 0x647a78fc, + 0x99865d44, 0x608bd593, 0x6c200e03, 0x39dc5ff6, 0x5d0b00a3, 0xae63aff2, 0x7e8bd632, 0x70108c0c, + 0xbbd35049, 0x2998df04, 0x980cf42a, 0x9b6df491, 0x9e7edd53, 0x06918548, 0x58cb7e07, 0x3b74ef2e, + 0x522fffb1, 0xd24708cc, 0x1c7e27cd, 0xa4eb215b, 0x3cf1d2e2, 0x19b47a38, 0x424f7618, 0x35856039, + 0x9d17dee7, 0x27eb35e6, 0xc9aff67b, 0x36baf5b8, 0x09c467cd, 0xc18910b1, 0xe11dbf7b, 0x06cd1af8, + 0x7170c608, 0x2d5e3354, 0xd4de495a, 0x64c6d006, 0xbcc0c62c, 0x3dd00db3, 0x708f8f34, 0x77d51b42, + 0x264f620f, 0x24b8d2bf, 0x15c1b79e, 0x46a52564, 0xf8d7e54e, 0x3e378160, 0x7895cda5, 0x859c15a5, + 0xe6459788, 0xc37bc75f, 0xdb07ba0c, 0x0676a3ab, 0x7f229b1e, 0x31842e7b, 0x24259fd7, 0xf8bef472, + 0x835ffcb8, 0x6df4c1f2, 0x96f5b195, 0xfd0af0fc, 0xb0fe134c, 0xe2506d3d, 0x4f9b12ea, 0xf215f225, + 0xa223736f, 0x9fb4c428, 0x25d04979, 0x34c713f8, 0xc4618187, 0xea7a6e98, 0x7cd16efc, 0x1436876c, + 0xf1544107, 0xbedeee14, 0x56e9af27, 0xa04aa441, 0x3cf7c899, 0x92ecbae6, 0xdd67016d, 0x151682eb, + 0xa842eedf, 0xfdba60b4, 0xf1907b75, 0x20e3030f, 0x24d8c29e, 0xe139673b, 0xefa63fb8, 0x71873054, + 0xb6f2cf3b, 0x9f326442, 0xcb15a4cc, 0xb01a4504, 0xf1e47d8d, 0x844a1be5, 0xbae7dfdc, 0x42cbda70, + 0xcd7dae0a, 0x57e85b7a, 0xd53f5af6, 0x20cf4d8c, 0xcea4d428, 0x79d130a4, 0x3486ebfb, 0x33d3cddc, + 0x77853b53, 0x37effcb5, 0xc5068778, 0xe580b3e6, 0x4e68b8f4, 0xc5c8b37e, 0x0d809ea2, 0x398feb7c, + 0x132a4f94, 0x43b7950e, 0x2fee7d1c, 0x223613bd, 0xdd06caa2, 0x37df932b, 0xc4248289, 0xacf3ebc3, + 0x5715f6b7, 0xef3478dd, 0xf267616f, 0xc148cbe4, 0x9052815e, 0x5e410fab, 0xb48a2465, 0x2eda7fa4, + 0xe87b40e4, 0xe98ea084, 0x5889e9e1, 0xefd390fc, 0xdd07d35b, 0xdb485694, 0x38d7e5b2, 0x57720101, + 0x730edebc, 0x5b643113, 0x94917e4f, 0x503c2fba, 0x646f1282, 0x7523d24a, 0xe0779695, 0xf9c17a8f, + 0x7a5b2121, 0xd187b896, 0x29263a4d, 0xba510cdf, 0x81f47c9f, 0xad1163ed, 0xea7b5965, 0x1a00726e, + 0x11403092, 0x00da6d77, 0x4a0cdd61, 0xad1f4603, 0x605bdfb0, 0x9eedc364, 0x22ebe6a8, 0xcee7d28a, + 0xa0e736a0, 0x5564a6b9, 0x10853209, 0xc7eb8f37, 0x2de705ca, 0x8951570f, 0xdf09822b, 0xbd691a6c, + 0xaa12e4f2, 0x87451c0f, 0xe0f6a27a, 0x3ada4819, 0x4cf1764f, 0x0d771c2b, 0x67cdb156, 0x350d8384, + 0x5938fa0f, 0x42399ef3, 0x36997b07, 0x0e84093d, 0x4aa93e61, 0x8360d87b, 0x1fa98b0c, 0x1149382c, + 0xe97625a5, 0x0614d1b7, 0x0e25244b, 0x0c768347, 0x589e8d82, 0x0d2059d1, 0xa466bb1e, 0xf8da0a82, + 0x04f19130, 0xba6e4ec0, 0x99265164, 0x1ee7230d, 0x50b2ad80, 0xeaee6801, 0x8db2a283, 0xea8bf59e + }; + + //==================================== + // Useful constants + //==================================== + + internal static readonly int MAX_ROUNDS = 16; + internal static readonly int RED_ROUNDS = 12; + + private const int BLOCK_SIZE = 8; // bytes = 64 bits + + private int[] _Kr = new int[17]; // the rotating round key + private uint[] _Km = new uint[17]; // the masking round key + + private bool _encrypting; + + private byte[] _workingKey; + private int _rounds = MAX_ROUNDS; + + public Cast5Engine() + { + } + + /** + * initialise a CAST cipher. + * + * @param forEncryption whether or not we are for encryption. + * @param parameters the parameters required to set up the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (!(parameters is KeyParameter)) + throw new ArgumentException("Invalid parameter passed to "+ AlgorithmName +" init - " + Platform.GetTypeName(parameters)); + + _encrypting = forEncryption; + _workingKey = ((KeyParameter)parameters).GetKey(); + SetKey(_workingKey); + } + + public virtual string AlgorithmName + { + get { return "CAST5"; } + } + + public virtual bool IsPartialBlockOkay + { + get { return false; } + } + + public virtual int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + int blockSize = GetBlockSize(); + if (_workingKey == null) + throw new InvalidOperationException(AlgorithmName + " not initialised"); + + Check.DataLength(input, inOff, blockSize, "input buffer too short"); + Check.OutputLength(output, outOff, blockSize, "output buffer too short"); + + if (_encrypting) + { + return EncryptBlock(input, inOff, output, outOff); + } + else + { + return DecryptBlock(input, inOff, output, outOff); + } + } + + public virtual void Reset() + { + } + + public virtual int GetBlockSize() + { + return BLOCK_SIZE; + } + + //================================== + // Private Implementation + //================================== + + /* + * Creates the subkeys using the same nomenclature + * as described in RFC2144. + * + * See section 2.4 + */ + internal virtual void SetKey(byte[] key) + { + /* + * Determine the key size here, if required + * + * if keysize <= 80bits, use 12 rounds instead of 16 + * if keysize < 128bits, pad with 0 + * + * Typical key sizes => 40, 64, 80, 128 + */ + + if (key.Length < 11) + { + _rounds = RED_ROUNDS; + } + + int [] z = new int[16]; + int [] x = new int[16]; + + uint z03, z47, z8B, zCF; + uint x03, x47, x8B, xCF; + + /* copy the key into x */ + for (int i=0; i< key.Length; i++) + { + x[i] = (int)(key[i] & 0xff); + } + + /* + * This will look different because the selection of + * bytes from the input key I've already chosen the + * correct int. + */ + x03 = IntsTo32bits(x, 0x0); + x47 = IntsTo32bits(x, 0x4); + x8B = IntsTo32bits(x, 0x8); + xCF = IntsTo32bits(x, 0xC); + + z03 = x03 ^S5[x[0xD]] ^S6[x[0xF]] ^S7[x[0xC]] ^S8[x[0xE]] ^S7[x[0x8]]; + + Bits32ToInts(z03, z, 0x0); + z47 = x8B ^S5[z[0x0]] ^S6[z[0x2]] ^S7[z[0x1]] ^S8[z[0x3]] ^S8[x[0xA]]; + Bits32ToInts(z47, z, 0x4); + z8B = xCF ^S5[z[0x7]] ^S6[z[0x6]] ^S7[z[0x5]] ^S8[z[0x4]] ^S5[x[0x9]]; + Bits32ToInts(z8B, z, 0x8); + zCF = x47 ^S5[z[0xA]] ^S6[z[0x9]] ^S7[z[0xB]] ^S8[z[0x8]] ^S6[x[0xB]]; + Bits32ToInts(zCF, z, 0xC); + _Km[ 1]= S5[z[0x8]] ^ S6[z[0x9]] ^ S7[z[0x7]] ^ S8[z[0x6]] ^ S5[z[0x2]]; + _Km[ 2]= S5[z[0xA]] ^ S6[z[0xB]] ^ S7[z[0x5]] ^ S8[z[0x4]] ^ S6[z[0x6]]; + _Km[ 3]= S5[z[0xC]] ^ S6[z[0xD]] ^ S7[z[0x3]] ^ S8[z[0x2]] ^ S7[z[0x9]]; + _Km[ 4]= S5[z[0xE]] ^ S6[z[0xF]] ^ S7[z[0x1]] ^ S8[z[0x0]] ^ S8[z[0xC]]; + + z03 = IntsTo32bits(z, 0x0); + z47 = IntsTo32bits(z, 0x4); + z8B = IntsTo32bits(z, 0x8); + zCF = IntsTo32bits(z, 0xC); + x03 = z8B ^S5[z[0x5]] ^S6[z[0x7]] ^S7[z[0x4]] ^S8[z[0x6]] ^S7[z[0x0]]; + Bits32ToInts(x03, x, 0x0); + x47 = z03 ^S5[x[0x0]] ^S6[x[0x2]] ^S7[x[0x1]] ^S8[x[0x3]] ^S8[z[0x2]]; + Bits32ToInts(x47, x, 0x4); + x8B = z47 ^S5[x[0x7]] ^S6[x[0x6]] ^S7[x[0x5]] ^S8[x[0x4]] ^S5[z[0x1]]; + Bits32ToInts(x8B, x, 0x8); + xCF = zCF ^S5[x[0xA]] ^S6[x[0x9]] ^S7[x[0xB]] ^S8[x[0x8]] ^S6[z[0x3]]; + Bits32ToInts(xCF, x, 0xC); + _Km[ 5]= S5[x[0x3]] ^ S6[x[0x2]] ^ S7[x[0xC]] ^ S8[x[0xD]] ^ S5[x[0x8]]; + _Km[ 6]= S5[x[0x1]] ^ S6[x[0x0]] ^ S7[x[0xE]] ^ S8[x[0xF]] ^ S6[x[0xD]]; + _Km[ 7]= S5[x[0x7]] ^ S6[x[0x6]] ^ S7[x[0x8]] ^ S8[x[0x9]] ^ S7[x[0x3]]; + _Km[ 8]= S5[x[0x5]] ^ S6[x[0x4]] ^ S7[x[0xA]] ^ S8[x[0xB]] ^ S8[x[0x7]]; + + x03 = IntsTo32bits(x, 0x0); + x47 = IntsTo32bits(x, 0x4); + x8B = IntsTo32bits(x, 0x8); + xCF = IntsTo32bits(x, 0xC); + z03 = x03 ^S5[x[0xD]] ^S6[x[0xF]] ^S7[x[0xC]] ^S8[x[0xE]] ^S7[x[0x8]]; + Bits32ToInts(z03, z, 0x0); + z47 = x8B ^S5[z[0x0]] ^S6[z[0x2]] ^S7[z[0x1]] ^S8[z[0x3]] ^S8[x[0xA]]; + Bits32ToInts(z47, z, 0x4); + z8B = xCF ^S5[z[0x7]] ^S6[z[0x6]] ^S7[z[0x5]] ^S8[z[0x4]] ^S5[x[0x9]]; + Bits32ToInts(z8B, z, 0x8); + zCF = x47 ^S5[z[0xA]] ^S6[z[0x9]] ^S7[z[0xB]] ^S8[z[0x8]] ^S6[x[0xB]]; + Bits32ToInts(zCF, z, 0xC); + _Km[ 9]= S5[z[0x3]] ^ S6[z[0x2]] ^ S7[z[0xC]] ^ S8[z[0xD]] ^ S5[z[0x9]]; + _Km[10]= S5[z[0x1]] ^ S6[z[0x0]] ^ S7[z[0xE]] ^ S8[z[0xF]] ^ S6[z[0xc]]; + _Km[11]= S5[z[0x7]] ^ S6[z[0x6]] ^ S7[z[0x8]] ^ S8[z[0x9]] ^ S7[z[0x2]]; + _Km[12]= S5[z[0x5]] ^ S6[z[0x4]] ^ S7[z[0xA]] ^ S8[z[0xB]] ^ S8[z[0x6]]; + + z03 = IntsTo32bits(z, 0x0); + z47 = IntsTo32bits(z, 0x4); + z8B = IntsTo32bits(z, 0x8); + zCF = IntsTo32bits(z, 0xC); + x03 = z8B ^S5[z[0x5]] ^S6[z[0x7]] ^S7[z[0x4]] ^S8[z[0x6]] ^S7[z[0x0]]; + Bits32ToInts(x03, x, 0x0); + x47 = z03 ^S5[x[0x0]] ^S6[x[0x2]] ^S7[x[0x1]] ^S8[x[0x3]] ^S8[z[0x2]]; + Bits32ToInts(x47, x, 0x4); + x8B = z47 ^S5[x[0x7]] ^S6[x[0x6]] ^S7[x[0x5]] ^S8[x[0x4]] ^S5[z[0x1]]; + Bits32ToInts(x8B, x, 0x8); + xCF = zCF ^S5[x[0xA]] ^S6[x[0x9]] ^S7[x[0xB]] ^S8[x[0x8]] ^S6[z[0x3]]; + Bits32ToInts(xCF, x, 0xC); + _Km[13]= S5[x[0x8]] ^ S6[x[0x9]] ^ S7[x[0x7]] ^ S8[x[0x6]] ^ S5[x[0x3]]; + _Km[14]= S5[x[0xA]] ^ S6[x[0xB]] ^ S7[x[0x5]] ^ S8[x[0x4]] ^ S6[x[0x7]]; + _Km[15]= S5[x[0xC]] ^ S6[x[0xD]] ^ S7[x[0x3]] ^ S8[x[0x2]] ^ S7[x[0x8]]; + _Km[16]= S5[x[0xE]] ^ S6[x[0xF]] ^ S7[x[0x1]] ^ S8[x[0x0]] ^ S8[x[0xD]]; + + x03 = IntsTo32bits(x, 0x0); + x47 = IntsTo32bits(x, 0x4); + x8B = IntsTo32bits(x, 0x8); + xCF = IntsTo32bits(x, 0xC); + z03 = x03 ^S5[x[0xD]] ^S6[x[0xF]] ^S7[x[0xC]] ^S8[x[0xE]] ^S7[x[0x8]]; + Bits32ToInts(z03, z, 0x0); + z47 = x8B ^S5[z[0x0]] ^S6[z[0x2]] ^S7[z[0x1]] ^S8[z[0x3]] ^S8[x[0xA]]; + Bits32ToInts(z47, z, 0x4); + z8B = xCF ^S5[z[0x7]] ^S6[z[0x6]] ^S7[z[0x5]] ^S8[z[0x4]] ^S5[x[0x9]]; + Bits32ToInts(z8B, z, 0x8); + zCF = x47 ^S5[z[0xA]] ^S6[z[0x9]] ^S7[z[0xB]] ^S8[z[0x8]] ^S6[x[0xB]]; + Bits32ToInts(zCF, z, 0xC); + _Kr[ 1]=(int)((S5[z[0x8]]^S6[z[0x9]]^S7[z[0x7]]^S8[z[0x6]] ^ S5[z[0x2]])&0x1f); + _Kr[ 2]=(int)((S5[z[0xA]]^S6[z[0xB]]^S7[z[0x5]]^S8[z[0x4]] ^ S6[z[0x6]])&0x1f); + _Kr[ 3]=(int)((S5[z[0xC]]^S6[z[0xD]]^S7[z[0x3]]^S8[z[0x2]] ^ S7[z[0x9]])&0x1f); + _Kr[ 4]=(int)((S5[z[0xE]]^S6[z[0xF]]^S7[z[0x1]]^S8[z[0x0]] ^ S8[z[0xC]])&0x1f); + + z03 = IntsTo32bits(z, 0x0); + z47 = IntsTo32bits(z, 0x4); + z8B = IntsTo32bits(z, 0x8); + zCF = IntsTo32bits(z, 0xC); + x03 = z8B ^S5[z[0x5]] ^S6[z[0x7]] ^S7[z[0x4]] ^S8[z[0x6]] ^S7[z[0x0]]; + Bits32ToInts(x03, x, 0x0); + x47 = z03 ^S5[x[0x0]] ^S6[x[0x2]] ^S7[x[0x1]] ^S8[x[0x3]] ^S8[z[0x2]]; + Bits32ToInts(x47, x, 0x4); + x8B = z47 ^S5[x[0x7]] ^S6[x[0x6]] ^S7[x[0x5]] ^S8[x[0x4]] ^S5[z[0x1]]; + Bits32ToInts(x8B, x, 0x8); + xCF = zCF ^S5[x[0xA]] ^S6[x[0x9]] ^S7[x[0xB]] ^S8[x[0x8]] ^S6[z[0x3]]; + Bits32ToInts(xCF, x, 0xC); + _Kr[ 5]=(int)((S5[x[0x3]]^S6[x[0x2]]^S7[x[0xC]]^S8[x[0xD]]^S5[x[0x8]])&0x1f); + _Kr[ 6]=(int)((S5[x[0x1]]^S6[x[0x0]]^S7[x[0xE]]^S8[x[0xF]]^S6[x[0xD]])&0x1f); + _Kr[ 7]=(int)((S5[x[0x7]]^S6[x[0x6]]^S7[x[0x8]]^S8[x[0x9]]^S7[x[0x3]])&0x1f); + _Kr[ 8]=(int)((S5[x[0x5]]^S6[x[0x4]]^S7[x[0xA]]^S8[x[0xB]]^S8[x[0x7]])&0x1f); + + x03 = IntsTo32bits(x, 0x0); + x47 = IntsTo32bits(x, 0x4); + x8B = IntsTo32bits(x, 0x8); + xCF = IntsTo32bits(x, 0xC); + z03 = x03 ^S5[x[0xD]] ^S6[x[0xF]] ^S7[x[0xC]] ^S8[x[0xE]] ^S7[x[0x8]]; + Bits32ToInts(z03, z, 0x0); + z47 = x8B ^S5[z[0x0]] ^S6[z[0x2]] ^S7[z[0x1]] ^S8[z[0x3]] ^S8[x[0xA]]; + Bits32ToInts(z47, z, 0x4); + z8B = xCF ^S5[z[0x7]] ^S6[z[0x6]] ^S7[z[0x5]] ^S8[z[0x4]] ^S5[x[0x9]]; + Bits32ToInts(z8B, z, 0x8); + zCF = x47 ^S5[z[0xA]] ^S6[z[0x9]] ^S7[z[0xB]] ^S8[z[0x8]] ^S6[x[0xB]]; + Bits32ToInts(zCF, z, 0xC); + _Kr[ 9]=(int)((S5[z[0x3]]^S6[z[0x2]]^S7[z[0xC]]^S8[z[0xD]]^S5[z[0x9]])&0x1f); + _Kr[10]=(int)((S5[z[0x1]]^S6[z[0x0]]^S7[z[0xE]]^S8[z[0xF]]^S6[z[0xc]])&0x1f); + _Kr[11]=(int)((S5[z[0x7]]^S6[z[0x6]]^S7[z[0x8]]^S8[z[0x9]]^S7[z[0x2]])&0x1f); + _Kr[12]=(int)((S5[z[0x5]]^S6[z[0x4]]^S7[z[0xA]]^S8[z[0xB]]^S8[z[0x6]])&0x1f); + + z03 = IntsTo32bits(z, 0x0); + z47 = IntsTo32bits(z, 0x4); + z8B = IntsTo32bits(z, 0x8); + zCF = IntsTo32bits(z, 0xC); + x03 = z8B ^S5[z[0x5]] ^S6[z[0x7]] ^S7[z[0x4]] ^S8[z[0x6]] ^S7[z[0x0]]; + Bits32ToInts(x03, x, 0x0); + x47 = z03 ^S5[x[0x0]] ^S6[x[0x2]] ^S7[x[0x1]] ^S8[x[0x3]] ^S8[z[0x2]]; + Bits32ToInts(x47, x, 0x4); + x8B = z47 ^S5[x[0x7]] ^S6[x[0x6]] ^S7[x[0x5]] ^S8[x[0x4]] ^S5[z[0x1]]; + Bits32ToInts(x8B, x, 0x8); + xCF = zCF ^S5[x[0xA]] ^S6[x[0x9]] ^S7[x[0xB]] ^S8[x[0x8]] ^S6[z[0x3]]; + Bits32ToInts(xCF, x, 0xC); + _Kr[13]=(int)((S5[x[0x8]]^S6[x[0x9]]^S7[x[0x7]]^S8[x[0x6]]^S5[x[0x3]])&0x1f); + _Kr[14]=(int)((S5[x[0xA]]^S6[x[0xB]]^S7[x[0x5]]^S8[x[0x4]]^S6[x[0x7]])&0x1f); + _Kr[15]=(int)((S5[x[0xC]]^S6[x[0xD]]^S7[x[0x3]]^S8[x[0x2]]^S7[x[0x8]])&0x1f); + _Kr[16]=(int)((S5[x[0xE]]^S6[x[0xF]]^S7[x[0x1]]^S8[x[0x0]]^S8[x[0xD]])&0x1f); + } + + /** + * Encrypt the given input starting at the given offset and place + * the result in the provided buffer starting at the given offset. + * + * @param src The plaintext buffer + * @param srcIndex An offset into src + * @param dst The ciphertext buffer + * @param dstIndex An offset into dst + */ + internal virtual int EncryptBlock( + byte[] src, + int srcIndex, + byte[] dst, + int dstIndex) + { + // process the input block + // batch the units up into a 32 bit chunk and go for it + // the array is in bytes, the increment is 8x8 bits = 64 + + uint L0 = Pack.BE_To_UInt32(src, srcIndex); + uint R0 = Pack.BE_To_UInt32(src, srcIndex + 4); + + uint[] result = new uint[2]; + CAST_Encipher(L0, R0, result); + + // now stuff them into the destination block + Pack.UInt32_To_BE(result[0], dst, dstIndex); + Pack.UInt32_To_BE(result[1], dst, dstIndex + 4); + + return BLOCK_SIZE; + } + + /** + * Decrypt the given input starting at the given offset and place + * the result in the provided buffer starting at the given offset. + * + * @param src The plaintext buffer + * @param srcIndex An offset into src + * @param dst The ciphertext buffer + * @param dstIndex An offset into dst + */ + internal virtual int DecryptBlock( + byte[] src, + int srcIndex, + byte[] dst, + int dstIndex) + { + // process the input block + // batch the units up into a 32 bit chunk and go for it + // the array is in bytes, the increment is 8x8 bits = 64 + uint L16 = Pack.BE_To_UInt32(src, srcIndex); + uint R16 = Pack.BE_To_UInt32(src, srcIndex + 4); + + uint[] result = new uint[2]; + CAST_Decipher(L16, R16, result); + + // now stuff them into the destination block + Pack.UInt32_To_BE(result[0], dst, dstIndex); + Pack.UInt32_To_BE(result[1], dst, dstIndex + 4); + + return BLOCK_SIZE; + } + + /** + * The first of the three processing functions for the + * encryption and decryption. + * + * @param D the input to be processed + * @param Kmi the mask to be used from Km[n] + * @param Kri the rotation value to be used + * + */ + internal static uint F1(uint D, uint Kmi, int Kri) + { + uint I = Kmi + D; + I = I << Kri | (I >> (32-Kri)); + return ((S1[(I>>24)&0xff]^S2[(I>>16)&0xff])-S3[(I>>8)&0xff])+S4[I&0xff]; + } + + /** + * The second of the three processing functions for the + * encryption and decryption. + * + * @param D the input to be processed + * @param Kmi the mask to be used from Km[n] + * @param Kri the rotation value to be used + * + */ + internal static uint F2(uint D, uint Kmi, int Kri) + { + uint I = Kmi ^ D; + I = I << Kri | (I >> (32-Kri)); + return ((S1[(I>>24)&0xff]-S2[(I>>16)&0xff])+S3[(I>>8)&0xff])^S4[I&0xff]; + } + + /** + * The third of the three processing functions for the + * encryption and decryption. + * + * @param D the input to be processed + * @param Kmi the mask to be used from Km[n] + * @param Kri the rotation value to be used + * + */ + internal static uint F3(uint D, uint Kmi, int Kri) + { + uint I = Kmi - D; + I = I << Kri | (I >> (32-Kri)); + return ((S1[(I>>24)&0xff]+S2[(I>>16)&0xff])^S3[(I>>8)&0xff])-S4[I&0xff]; + } + + /** + * Does the 16 rounds to encrypt the block. + * + * @param L0 the LH-32bits of the plaintext block + * @param R0 the RH-32bits of the plaintext block + */ + internal void CAST_Encipher(uint L0, uint R0, uint[] result) + { + uint Lp = L0; // the previous value, equiv to L[i-1] + uint Rp = R0; // equivalent to R[i-1] + + /* + * numbering consistent with paper to make + * checking and validating easier + */ + uint Li = L0, Ri = R0; + + for (int i = 1; i<=_rounds ; i++) + { + Lp = Li; + Rp = Ri; + + Li = Rp; + switch (i) + { + case 1: + case 4: + case 7: + case 10: + case 13: + case 16: + Ri = Lp ^ F1(Rp, _Km[i], _Kr[i]); + break; + case 2: + case 5: + case 8: + case 11: + case 14: + Ri = Lp ^ F2(Rp, _Km[i], _Kr[i]); + break; + case 3: + case 6: + case 9: + case 12: + case 15: + Ri = Lp ^ F3(Rp, _Km[i], _Kr[i]); + break; + } + } + + result[0] = Ri; + result[1] = Li; + + return; + } + + internal void CAST_Decipher(uint L16, uint R16, uint[] result) + { + uint Lp = L16; // the previous value, equiv to L[i-1] + uint Rp = R16; // equivalent to R[i-1] + + /* + * numbering consistent with paper to make + * checking and validating easier + */ + uint Li = L16, Ri = R16; + + for (int i = _rounds; i > 0; i--) + { + Lp = Li; + Rp = Ri; + + Li = Rp; + switch (i) + { + case 1: + case 4: + case 7: + case 10: + case 13: + case 16: + Ri = Lp ^ F1(Rp, _Km[i], _Kr[i]); + break; + case 2: + case 5: + case 8: + case 11: + case 14: + Ri = Lp ^ F2(Rp, _Km[i], _Kr[i]); + break; + case 3: + case 6: + case 9: + case 12: + case 15: + Ri = Lp ^ F3(Rp, _Km[i], _Kr[i]); + break; + } + } + + result[0] = Ri; + result[1] = Li; + + return; + } + + internal static void Bits32ToInts(uint inData, int[] b, int offset) + { + b[offset + 3] = (int) (inData & 0xff); + b[offset + 2] = (int) ((inData >> 8) & 0xff); + b[offset + 1] = (int) ((inData >> 16) & 0xff); + b[offset] = (int) ((inData >> 24) & 0xff); + } + + internal static uint IntsTo32bits(int[] b, int i) + { + return (uint)(((b[i] & 0xff) << 24) | + ((b[i+1] & 0xff) << 16) | + ((b[i+2] & 0xff) << 8) | + ((b[i+3] & 0xff))); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/Cast5Engine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/Cast5Engine.cs.meta new file mode 100644 index 0000000..8a9581e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/Cast5Engine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 70e228ec99e890748adb1ed3315f97e0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/Cast6Engine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/Cast6Engine.cs new file mode 100644 index 0000000..c5c419b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/Cast6Engine.cs @@ -0,0 +1,279 @@ +using System; + +using Org.BouncyCastle.Crypto.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * A class that provides CAST6 key encryption operations, + * such as encoding data and generating keys. + * + * All the algorithms herein are from the Internet RFC + * + * RFC2612 - CAST6 (128bit block, 128-256bit key) + * + * and implement a simplified cryptography interface. + */ + public sealed class Cast6Engine + : Cast5Engine + { + //==================================== + // Useful constants + //==================================== + private const int ROUNDS = 12; + private const int BLOCK_SIZE = 16; // bytes = 128 bits + + /* + * Put the round and mask keys into an array. + * Kr0[i] => _Kr[i*4 + 0] + */ + private int []_Kr = new int[ROUNDS*4]; // the rotating round key(s) + private uint []_Km = new uint[ROUNDS*4]; // the masking round key(s) + + /* + * Key setup + */ + private int []_Tr = new int[24 * 8]; + private uint []_Tm = new uint[24 * 8]; + private uint[] _workingKey = new uint[8]; + + public Cast6Engine() + { + } + + public override string AlgorithmName + { + get { return "CAST6"; } + } + + public override void Reset() + { + } + + public override int GetBlockSize() + { + return BLOCK_SIZE; + } + + //================================== + // Private Implementation + //================================== + /* + * Creates the subkeys using the same nomenclature + * as described in RFC2612. + * + * See section 2.4 + */ + internal override void SetKey( + byte[] key) + { + uint Cm = 0x5a827999; + uint Mm = 0x6ed9eba1; + int Cr = 19; + int Mr = 17; + /* + * Determine the key size here, if required + * + * if keysize < 256 bytes, pad with 0 + * + * Typical key sizes => 128, 160, 192, 224, 256 + */ + for (int i=0; i< 24; i++) + { + for (int j=0; j< 8; j++) + { + _Tm[i*8 + j] = Cm; + Cm += Mm; //mod 2^32; + _Tr[i*8 + j] = Cr; + Cr = (Cr + Mr) & 0x1f; // mod 32 + } + } + + byte[] tmpKey = new byte[64]; + key.CopyTo(tmpKey, 0); + + // now create ABCDEFGH + for (int i = 0; i < 8; i++) + { + _workingKey[i] = Pack.BE_To_UInt32(tmpKey, i*4); + } + + // Generate the key schedule + for (int i = 0; i < 12; i++) + { + // KAPPA <- W2i(KAPPA) + int i2 = i*2 *8; + _workingKey[6] ^= F1(_workingKey[7], _Tm[i2], _Tr[i2]); + _workingKey[5] ^= F2(_workingKey[6], _Tm[i2+1], _Tr[i2+1]); + _workingKey[4] ^= F3(_workingKey[5], _Tm[i2+2], _Tr[i2+2]); + _workingKey[3] ^= F1(_workingKey[4], _Tm[i2+3], _Tr[i2+3]); + _workingKey[2] ^= F2(_workingKey[3], _Tm[i2+4], _Tr[i2+4]); + _workingKey[1] ^= F3(_workingKey[2], _Tm[i2+5], _Tr[i2+5]); + _workingKey[0] ^= F1(_workingKey[1], _Tm[i2+6], _Tr[i2+6]); + _workingKey[7] ^= F2(_workingKey[0], _Tm[i2+7], _Tr[i2+7]); + // KAPPA <- W2i+1(KAPPA) + i2 = (i*2 + 1)*8; + _workingKey[6] ^= F1(_workingKey[7], _Tm[i2], _Tr[i2]); + _workingKey[5] ^= F2(_workingKey[6], _Tm[i2+1], _Tr[i2+1]); + _workingKey[4] ^= F3(_workingKey[5], _Tm[i2+2], _Tr[i2+2]); + _workingKey[3] ^= F1(_workingKey[4], _Tm[i2+3], _Tr[i2+3]); + _workingKey[2] ^= F2(_workingKey[3], _Tm[i2+4], _Tr[i2+4]); + _workingKey[1] ^= F3(_workingKey[2], _Tm[i2+5], _Tr[i2+5]); + _workingKey[0] ^= F1(_workingKey[1], _Tm[i2+6], _Tr[i2+6]); + _workingKey[7] ^= F2(_workingKey[0], _Tm[i2+7], _Tr[i2+7]); + // Kr_(i) <- KAPPA + _Kr[i*4] = (int)(_workingKey[0] & 0x1f); + _Kr[i*4 + 1] = (int)(_workingKey[2] & 0x1f); + _Kr[i*4 + 2] = (int)(_workingKey[4] & 0x1f); + _Kr[i*4 + 3] = (int)(_workingKey[6] & 0x1f); + // Km_(i) <- KAPPA + _Km[i*4] = _workingKey[7]; + _Km[i*4 + 1] = _workingKey[5]; + _Km[i*4 + 2] = _workingKey[3]; + _Km[i*4 + 3] = _workingKey[1]; + } + } + + /** + * Encrypt the given input starting at the given offset and place + * the result in the provided buffer starting at the given offset. + * + * @param src The plaintext buffer + * @param srcIndex An offset into src + * @param dst The ciphertext buffer + * @param dstIndex An offset into dst + */ + internal override int EncryptBlock( + byte[] src, + int srcIndex, + byte[] dst, + int dstIndex) + { + // process the input block + // batch the units up into 4x32 bit chunks and go for it + uint A = Pack.BE_To_UInt32(src, srcIndex); + uint B = Pack.BE_To_UInt32(src, srcIndex + 4); + uint C = Pack.BE_To_UInt32(src, srcIndex + 8); + uint D = Pack.BE_To_UInt32(src, srcIndex + 12); + uint[] result = new uint[4]; + CAST_Encipher(A, B, C, D, result); + // now stuff them into the destination block + Pack.UInt32_To_BE(result[0], dst, dstIndex); + Pack.UInt32_To_BE(result[1], dst, dstIndex + 4); + Pack.UInt32_To_BE(result[2], dst, dstIndex + 8); + Pack.UInt32_To_BE(result[3], dst, dstIndex + 12); + return BLOCK_SIZE; + } + + /** + * Decrypt the given input starting at the given offset and place + * the result in the provided buffer starting at the given offset. + * + * @param src The plaintext buffer + * @param srcIndex An offset into src + * @param dst The ciphertext buffer + * @param dstIndex An offset into dst + */ + internal override int DecryptBlock( + byte[] src, + int srcIndex, + byte[] dst, + int dstIndex) + { + // process the input block + // batch the units up into 4x32 bit chunks and go for it + uint A = Pack.BE_To_UInt32(src, srcIndex); + uint B = Pack.BE_To_UInt32(src, srcIndex + 4); + uint C = Pack.BE_To_UInt32(src, srcIndex + 8); + uint D = Pack.BE_To_UInt32(src, srcIndex + 12); + uint[] result = new uint[4]; + CAST_Decipher(A, B, C, D, result); + // now stuff them into the destination block + Pack.UInt32_To_BE(result[0], dst, dstIndex); + Pack.UInt32_To_BE(result[1], dst, dstIndex + 4); + Pack.UInt32_To_BE(result[2], dst, dstIndex + 8); + Pack.UInt32_To_BE(result[3], dst, dstIndex + 12); + return BLOCK_SIZE; + } + + /** + * Does the 12 quad rounds rounds to encrypt the block. + * + * @param A the 00-31 bits of the plaintext block + * @param B the 32-63 bits of the plaintext block + * @param C the 64-95 bits of the plaintext block + * @param D the 96-127 bits of the plaintext block + * @param result the resulting ciphertext + */ + private void CAST_Encipher( + uint A, + uint B, + uint C, + uint D, + uint[] result) + { + for (int i = 0; i < 6; i++) + { + int x = i*4; + // BETA <- Qi(BETA) + C ^= F1(D, _Km[x], _Kr[x]); + B ^= F2(C, _Km[x + 1], _Kr[x + 1]); + A ^= F3(B, _Km[x + 2], _Kr[x + 2]); + D ^= F1(A, _Km[x + 3], _Kr[x + 3]); + } + for (int i = 6; i < 12; i++) + { + int x = i*4; + // BETA <- QBARi(BETA) + D ^= F1(A, _Km[x + 3], _Kr[x + 3]); + A ^= F3(B, _Km[x + 2], _Kr[x + 2]); + B ^= F2(C, _Km[x + 1], _Kr[x + 1]); + C ^= F1(D, _Km[x], _Kr[x]); + } + result[0] = A; + result[1] = B; + result[2] = C; + result[3] = D; + } + + /** + * Does the 12 quad rounds rounds to decrypt the block. + * + * @param A the 00-31 bits of the ciphertext block + * @param B the 32-63 bits of the ciphertext block + * @param C the 64-95 bits of the ciphertext block + * @param D the 96-127 bits of the ciphertext block + * @param result the resulting plaintext + */ + private void CAST_Decipher( + uint A, + uint B, + uint C, + uint D, + uint[] result) + { + for (int i = 0; i < 6; i++) + { + int x = (11-i)*4; + // BETA <- Qi(BETA) + C ^= F1(D, _Km[x], _Kr[x]); + B ^= F2(C, _Km[x + 1], _Kr[x + 1]); + A ^= F3(B, _Km[x + 2], _Kr[x + 2]); + D ^= F1(A, _Km[x + 3], _Kr[x + 3]); + } + for (int i=6; i<12; i++) + { + int x = (11-i)*4; + // BETA <- QBARi(BETA) + D ^= F1(A, _Km[x + 3], _Kr[x + 3]); + A ^= F3(B, _Km[x + 2], _Kr[x + 2]); + B ^= F2(C, _Km[x + 1], _Kr[x + 1]); + C ^= F1(D, _Km[x], _Kr[x]); + } + result[0] = A; + result[1] = B; + result[2] = C; + result[3] = D; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/Cast6Engine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/Cast6Engine.cs.meta new file mode 100644 index 0000000..d68d73a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/Cast6Engine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2f41a3fe7d70c5846b210173c0679a22 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/ChaCha7539Engine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/ChaCha7539Engine.cs new file mode 100644 index 0000000..206416a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/ChaCha7539Engine.cs @@ -0,0 +1,66 @@ +using System; + +using Org.BouncyCastle.Crypto.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + ///

+ /// Implementation of Daniel J. Bernstein's ChaCha stream cipher. + /// + public class ChaCha7539Engine + : Salsa20Engine + { + /// + /// Creates a 20 rounds ChaCha engine. + /// + public ChaCha7539Engine() + : base() + { + } + + public override string AlgorithmName + { + get { return "ChaCha7539"; } + } + + protected override int NonceSize + { + get { return 12; } + } + + protected override void AdvanceCounter() + { + if (++engineState[12] == 0) + throw new InvalidOperationException("attempt to increase counter past 2^32."); + } + + protected override void ResetCounter() + { + engineState[12] = 0; + } + + protected override void SetKey(byte[] keyBytes, byte[] ivBytes) + { + if (keyBytes != null) + { + if (keyBytes.Length != 32) + throw new ArgumentException(AlgorithmName + " requires 256 bit key"); + + PackTauOrSigma(keyBytes.Length, engineState, 0); + + // Key + Pack.LE_To_UInt32(keyBytes, 0, engineState, 4, 8); + } + + // IV + Pack.LE_To_UInt32(ivBytes, 0, engineState, 13, 3); + } + + protected override void GenerateKeyStream(byte[] output) + { + ChaChaEngine.ChachaCore(rounds, engineState, x); + Pack.UInt32_To_LE(x, output, 0); + } + } +} + diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/ChaCha7539Engine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/ChaCha7539Engine.cs.meta new file mode 100644 index 0000000..d013af4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/ChaCha7539Engine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f16de5a9ef1ae364e9bc99735c96404b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/ChaChaEngine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/ChaChaEngine.cs new file mode 100644 index 0000000..a97c04e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/ChaChaEngine.cs @@ -0,0 +1,158 @@ +using System; + +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /// + /// Implementation of Daniel J. Bernstein's ChaCha stream cipher. + /// + public class ChaChaEngine + : Salsa20Engine + { + /// + /// Creates a 20 rounds ChaCha engine. + /// + public ChaChaEngine() + { + } + + /// + /// Creates a ChaCha engine with a specific number of rounds. + /// + /// the number of rounds (must be an even number). + public ChaChaEngine(int rounds) + : base(rounds) + { + } + + public override string AlgorithmName + { + get { return "ChaCha" + rounds; } + } + + protected override void AdvanceCounter() + { + if (++engineState[12] == 0) + { + ++engineState[13]; + } + } + + protected override void ResetCounter() + { + engineState[12] = engineState[13] = 0; + } + + protected override void SetKey(byte[] keyBytes, byte[] ivBytes) + { + if (keyBytes != null) + { + if ((keyBytes.Length != 16) && (keyBytes.Length != 32)) + throw new ArgumentException(AlgorithmName + " requires 128 bit or 256 bit key"); + + PackTauOrSigma(keyBytes.Length, engineState, 0); + + // Key + Pack.LE_To_UInt32(keyBytes, 0, engineState, 4, 4); + Pack.LE_To_UInt32(keyBytes, keyBytes.Length - 16, engineState, 8, 4); + } + + // IV + Pack.LE_To_UInt32(ivBytes, 0, engineState, 14, 2); + } + + protected override void GenerateKeyStream(byte[] output) + { + ChachaCore(rounds, engineState, x); + Pack.UInt32_To_LE(x, output, 0); + } + + /// + /// ChaCha function. + /// + /// The number of ChaCha rounds to execute + /// The input words. + /// The ChaCha state to modify. + internal static void ChachaCore(int rounds, uint[] input, uint[] x) + { + if (input.Length != 16) + throw new ArgumentException(); + if (x.Length != 16) + throw new ArgumentException(); + if (rounds % 2 != 0) + throw new ArgumentException("Number of rounds must be even"); + + uint x00 = input[ 0]; + uint x01 = input[ 1]; + uint x02 = input[ 2]; + uint x03 = input[ 3]; + uint x04 = input[ 4]; + uint x05 = input[ 5]; + uint x06 = input[ 6]; + uint x07 = input[ 7]; + uint x08 = input[ 8]; + uint x09 = input[ 9]; + uint x10 = input[10]; + uint x11 = input[11]; + uint x12 = input[12]; + uint x13 = input[13]; + uint x14 = input[14]; + uint x15 = input[15]; + + for (int i = rounds; i > 0; i -= 2) + { + x00 += x04; x12 = Integers.RotateLeft(x12 ^ x00, 16); + x08 += x12; x04 = Integers.RotateLeft(x04 ^ x08, 12); + x00 += x04; x12 = Integers.RotateLeft(x12 ^ x00, 8); + x08 += x12; x04 = Integers.RotateLeft(x04 ^ x08, 7); + x01 += x05; x13 = Integers.RotateLeft(x13 ^ x01, 16); + x09 += x13; x05 = Integers.RotateLeft(x05 ^ x09, 12); + x01 += x05; x13 = Integers.RotateLeft(x13 ^ x01, 8); + x09 += x13; x05 = Integers.RotateLeft(x05 ^ x09, 7); + x02 += x06; x14 = Integers.RotateLeft(x14 ^ x02, 16); + x10 += x14; x06 = Integers.RotateLeft(x06 ^ x10, 12); + x02 += x06; x14 = Integers.RotateLeft(x14 ^ x02, 8); + x10 += x14; x06 = Integers.RotateLeft(x06 ^ x10, 7); + x03 += x07; x15 = Integers.RotateLeft(x15 ^ x03, 16); + x11 += x15; x07 = Integers.RotateLeft(x07 ^ x11, 12); + x03 += x07; x15 = Integers.RotateLeft(x15 ^ x03, 8); + x11 += x15; x07 = Integers.RotateLeft(x07 ^ x11, 7); + x00 += x05; x15 = Integers.RotateLeft(x15 ^ x00, 16); + x10 += x15; x05 = Integers.RotateLeft(x05 ^ x10, 12); + x00 += x05; x15 = Integers.RotateLeft(x15 ^ x00, 8); + x10 += x15; x05 = Integers.RotateLeft(x05 ^ x10, 7); + x01 += x06; x12 = Integers.RotateLeft(x12 ^ x01, 16); + x11 += x12; x06 = Integers.RotateLeft(x06 ^ x11, 12); + x01 += x06; x12 = Integers.RotateLeft(x12 ^ x01, 8); + x11 += x12; x06 = Integers.RotateLeft(x06 ^ x11, 7); + x02 += x07; x13 = Integers.RotateLeft(x13 ^ x02, 16); + x08 += x13; x07 = Integers.RotateLeft(x07 ^ x08, 12); + x02 += x07; x13 = Integers.RotateLeft(x13 ^ x02, 8); + x08 += x13; x07 = Integers.RotateLeft(x07 ^ x08, 7); + x03 += x04; x14 = Integers.RotateLeft(x14 ^ x03, 16); + x09 += x14; x04 = Integers.RotateLeft(x04 ^ x09, 12); + x03 += x04; x14 = Integers.RotateLeft(x14 ^ x03, 8); + x09 += x14; x04 = Integers.RotateLeft(x04 ^ x09, 7); + } + + x[ 0] = x00 + input[ 0]; + x[ 1] = x01 + input[ 1]; + x[ 2] = x02 + input[ 2]; + x[ 3] = x03 + input[ 3]; + x[ 4] = x04 + input[ 4]; + x[ 5] = x05 + input[ 5]; + x[ 6] = x06 + input[ 6]; + x[ 7] = x07 + input[ 7]; + x[ 8] = x08 + input[ 8]; + x[ 9] = x09 + input[ 9]; + x[10] = x10 + input[10]; + x[11] = x11 + input[11]; + x[12] = x12 + input[12]; + x[13] = x13 + input[13]; + x[14] = x14 + input[14]; + x[15] = x15 + input[15]; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/ChaChaEngine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/ChaChaEngine.cs.meta new file mode 100644 index 0000000..b2b1e5d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/ChaChaEngine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c52a109c995b1c240a2128292dde4226 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/DesEdeEngine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/DesEdeEngine.cs new file mode 100644 index 0000000..2fac24a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/DesEdeEngine.cs @@ -0,0 +1,100 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /// A class that provides a basic DESede (or Triple DES) engine. + public class DesEdeEngine + : DesEngine + { + private int[] workingKey1, workingKey2, workingKey3; + private bool forEncryption; + + /** + * initialise a DESede cipher. + * + * @param forEncryption whether or not we are for encryption. + * @param parameters the parameters required to set up the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public override void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (!(parameters is KeyParameter)) + throw new ArgumentException("invalid parameter passed to DESede init - " + Platform.GetTypeName(parameters)); + + byte[] keyMaster = ((KeyParameter)parameters).GetKey(); + if (keyMaster.Length != 24 && keyMaster.Length != 16) + throw new ArgumentException("key size must be 16 or 24 bytes."); + + this.forEncryption = forEncryption; + + byte[] key1 = new byte[8]; + Array.Copy(keyMaster, 0, key1, 0, key1.Length); + workingKey1 = GenerateWorkingKey(forEncryption, key1); + + byte[] key2 = new byte[8]; + Array.Copy(keyMaster, 8, key2, 0, key2.Length); + workingKey2 = GenerateWorkingKey(!forEncryption, key2); + + if (keyMaster.Length == 24) + { + byte[] key3 = new byte[8]; + Array.Copy(keyMaster, 16, key3, 0, key3.Length); + workingKey3 = GenerateWorkingKey(forEncryption, key3); + } + else // 16 byte key + { + workingKey3 = workingKey1; + } + } + + public override string AlgorithmName + { + get { return "DESede"; } + } + + public override int GetBlockSize() + { + return BLOCK_SIZE; + } + + public override int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + if (workingKey1 == null) + throw new InvalidOperationException("DESede engine not initialised"); + + Check.DataLength(input, inOff, BLOCK_SIZE, "input buffer too short"); + Check.OutputLength(output, outOff, BLOCK_SIZE, "output buffer too short"); + + byte[] temp = new byte[BLOCK_SIZE]; + + if (forEncryption) + { + DesFunc(workingKey1, input, inOff, temp, 0); + DesFunc(workingKey2, temp, 0, temp, 0); + DesFunc(workingKey3, temp, 0, output, outOff); + } + else + { + DesFunc(workingKey3, input, inOff, temp, 0); + DesFunc(workingKey2, temp, 0, temp, 0); + DesFunc(workingKey1, temp, 0, output, outOff); + } + + return BLOCK_SIZE; + } + + public override void Reset() + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/DesEdeEngine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/DesEdeEngine.cs.meta new file mode 100644 index 0000000..b5e4993 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/DesEdeEngine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 88673e7f8cde9494e9cd84d320f908b8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/DesEdeWrapEngine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/DesEdeWrapEngine.cs new file mode 100644 index 0000000..43100a9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/DesEdeWrapEngine.cs @@ -0,0 +1,322 @@ +using System; + +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Modes; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * Wrap keys according to + * + * draft-ietf-smime-key-wrap-01.txt. + *

+ * Note: + *

    + *
  • this is based on a draft, and as such is subject to change - don't use this class for anything requiring long term storage.
  • + *
  • if you are using this to wrap triple-des keys you need to set the + * parity bits on the key and, if it's a two-key triple-des key, pad it + * yourself.
  • + *
+ *

+ */ + public class DesEdeWrapEngine + : IWrapper + { + /** Field engine */ + private CbcBlockCipher engine; + /** Field param */ + private KeyParameter param; + /** Field paramPlusIV */ + private ParametersWithIV paramPlusIV; + /** Field iv */ + private byte[] iv; + /** Field forWrapping */ + private bool forWrapping; + /** Field IV2 */ + private static readonly byte[] IV2 = { (byte) 0x4a, (byte) 0xdd, (byte) 0xa2, + (byte) 0x2c, (byte) 0x79, (byte) 0xe8, + (byte) 0x21, (byte) 0x05 }; + + // + // checksum digest + // + private readonly IDigest sha1 = new Sha1Digest(); + private readonly byte[] digest = new byte[20]; + + /** + * Method init + * + * @param forWrapping + * @param param + */ + public virtual void Init( + bool forWrapping, + ICipherParameters parameters) + { + this.forWrapping = forWrapping; + this.engine = new CbcBlockCipher(new DesEdeEngine()); + + SecureRandom sr; + if (parameters is ParametersWithRandom) + { + ParametersWithRandom pr = (ParametersWithRandom) parameters; + parameters = pr.Parameters; + sr = pr.Random; + } + else + { + sr = new SecureRandom(); + } + + if (parameters is KeyParameter) + { + this.param = (KeyParameter) parameters; + if (this.forWrapping) + { + // Hm, we have no IV but we want to wrap ?!? + // well, then we have to create our own IV. + this.iv = new byte[8]; + sr.NextBytes(iv); + + this.paramPlusIV = new ParametersWithIV(this.param, this.iv); + } + } + else if (parameters is ParametersWithIV) + { + if (!forWrapping) + throw new ArgumentException("You should not supply an IV for unwrapping"); + + this.paramPlusIV = (ParametersWithIV) parameters; + this.iv = this.paramPlusIV.GetIV(); + this.param = (KeyParameter) this.paramPlusIV.Parameters; + + if (this.iv.Length != 8) + throw new ArgumentException("IV is not 8 octets", "parameters"); + } + } + + /** + * Method GetAlgorithmName + * + * @return + */ + public virtual string AlgorithmName + { + get { return "DESede"; } + } + + /** + * Method wrap + * + * @param in + * @param inOff + * @param inLen + * @return + */ + public virtual byte[] Wrap( + byte[] input, + int inOff, + int length) + { + if (!forWrapping) + { + throw new InvalidOperationException("Not initialized for wrapping"); + } + + byte[] keyToBeWrapped = new byte[length]; + Array.Copy(input, inOff, keyToBeWrapped, 0, length); + + // Compute the CMS Key Checksum, (section 5.6.1), call this CKS. + byte[] CKS = CalculateCmsKeyChecksum(keyToBeWrapped); + + // Let WKCKS = WK || CKS where || is concatenation. + byte[] WKCKS = new byte[keyToBeWrapped.Length + CKS.Length]; + Array.Copy(keyToBeWrapped, 0, WKCKS, 0, keyToBeWrapped.Length); + Array.Copy(CKS, 0, WKCKS, keyToBeWrapped.Length, CKS.Length); + + // Encrypt WKCKS in CBC mode using KEK as the key and IV as the + // initialization vector. Call the results TEMP1. + + int blockSize = engine.GetBlockSize(); + + if (WKCKS.Length % blockSize != 0) + throw new InvalidOperationException("Not multiple of block length"); + + engine.Init(true, paramPlusIV); + + byte [] TEMP1 = new byte[WKCKS.Length]; + + for (int currentBytePos = 0; currentBytePos != WKCKS.Length; currentBytePos += blockSize) + { + engine.ProcessBlock(WKCKS, currentBytePos, TEMP1, currentBytePos); + } + + // Let TEMP2 = IV || TEMP1. + byte[] TEMP2 = new byte[this.iv.Length + TEMP1.Length]; + Array.Copy(this.iv, 0, TEMP2, 0, this.iv.Length); + Array.Copy(TEMP1, 0, TEMP2, this.iv.Length, TEMP1.Length); + + // Reverse the order of the octets in TEMP2 and call the result TEMP3. + byte[] TEMP3 = reverse(TEMP2); + + // Encrypt TEMP3 in CBC mode using the KEK and an initialization vector + // of 0x 4a dd a2 2c 79 e8 21 05. The resulting cipher text is the desired + // result. It is 40 octets long if a 168 bit key is being wrapped. + ParametersWithIV param2 = new ParametersWithIV(this.param, IV2); + this.engine.Init(true, param2); + + for (int currentBytePos = 0; currentBytePos != TEMP3.Length; currentBytePos += blockSize) + { + engine.ProcessBlock(TEMP3, currentBytePos, TEMP3, currentBytePos); + } + + return TEMP3; + } + + /** + * Method unwrap + * + * @param in + * @param inOff + * @param inLen + * @return + * @throws InvalidCipherTextException + */ + public virtual byte[] Unwrap( + byte[] input, + int inOff, + int length) + { + if (forWrapping) + { + throw new InvalidOperationException("Not set for unwrapping"); + } + if (input == null) + { + throw new InvalidCipherTextException("Null pointer as ciphertext"); + } + + int blockSize = engine.GetBlockSize(); + + if (length % blockSize != 0) + { + throw new InvalidCipherTextException("Ciphertext not multiple of " + blockSize); + } + + /* + // Check if the length of the cipher text is reasonable given the key + // type. It must be 40 bytes for a 168 bit key and either 32, 40, or + // 48 bytes for a 128, 192, or 256 bit key. If the length is not supported + // or inconsistent with the algorithm for which the key is intended, + // return error. + // + // we do not accept 168 bit keys. it has to be 192 bit. + int lengthA = (estimatedKeyLengthInBit / 8) + 16; + int lengthB = estimatedKeyLengthInBit % 8; + if ((lengthA != keyToBeUnwrapped.Length) || (lengthB != 0)) { + throw new XMLSecurityException("empty"); + } + */ + + // Decrypt the cipher text with TRIPLedeS in CBC mode using the KEK + // and an initialization vector (IV) of 0x4adda22c79e82105. Call the output TEMP3. + ParametersWithIV param2 = new ParametersWithIV(this.param, IV2); + this.engine.Init(false, param2); + + byte [] TEMP3 = new byte[length]; + + for (int currentBytePos = 0; currentBytePos != TEMP3.Length; currentBytePos += blockSize) + { + engine.ProcessBlock(input, inOff + currentBytePos, TEMP3, currentBytePos); + } + + // Reverse the order of the octets in TEMP3 and call the result TEMP2. + byte[] TEMP2 = reverse(TEMP3); + + // Decompose TEMP2 into IV, the first 8 octets, and TEMP1, the remaining octets. + this.iv = new byte[8]; + byte[] TEMP1 = new byte[TEMP2.Length - 8]; + Array.Copy(TEMP2, 0, this.iv, 0, 8); + Array.Copy(TEMP2, 8, TEMP1, 0, TEMP2.Length - 8); + + // Decrypt TEMP1 using TRIPLedeS in CBC mode using the KEK and the IV + // found in the previous step. Call the result WKCKS. + this.paramPlusIV = new ParametersWithIV(this.param, this.iv); + this.engine.Init(false, this.paramPlusIV); + + byte[] WKCKS = new byte[TEMP1.Length]; + + for (int currentBytePos = 0; currentBytePos != WKCKS.Length; currentBytePos += blockSize) + { + engine.ProcessBlock(TEMP1, currentBytePos, WKCKS, currentBytePos); + } + + // Decompose WKCKS. CKS is the last 8 octets and WK, the wrapped key, are + // those octets before the CKS. + byte[] result = new byte[WKCKS.Length - 8]; + byte[] CKStoBeVerified = new byte[8]; + Array.Copy(WKCKS, 0, result, 0, WKCKS.Length - 8); + Array.Copy(WKCKS, WKCKS.Length - 8, CKStoBeVerified, 0, 8); + + // Calculate a CMS Key Checksum, (section 5.6.1), over the WK and compare + // with the CKS extracted in the above step. If they are not equal, return error. + if (!CheckCmsKeyChecksum(result, CKStoBeVerified)) { + throw new InvalidCipherTextException( + "Checksum inside ciphertext is corrupted"); + } + + // WK is the wrapped key, now extracted for use in data decryption. + return result; + } + + /** + * Some key wrap algorithms make use of the Key Checksum defined + * in CMS [CMS-Algorithms]. This is used to provide an integrity + * check value for the key being wrapped. The algorithm is + * + * - Compute the 20 octet SHA-1 hash on the key being wrapped. + * - Use the first 8 octets of this hash as the checksum value. + * + * @param key + * @return + * @throws Exception + * @see http://www.w3.org/TR/xmlenc-core/#sec-CMSKeyChecksum + */ + private byte[] CalculateCmsKeyChecksum( + byte[] key) + { + sha1.BlockUpdate(key, 0, key.Length); + sha1.DoFinal(digest, 0); + + byte[] result = new byte[8]; + Array.Copy(digest, 0, result, 0, 8); + return result; + } + + /** + * @param key + * @param checksum + * @return + * @see http://www.w3.org/TR/xmlenc-core/#sec-CMSKeyChecksum + */ + private bool CheckCmsKeyChecksum( + byte[] key, + byte[] checksum) + { + return Arrays.ConstantTimeAreEqual(CalculateCmsKeyChecksum(key), checksum); + } + + private static byte[] reverse(byte[] bs) + { + byte[] result = new byte[bs.Length]; + for (int i = 0; i < bs.Length; i++) + { + result[i] = bs[bs.Length - (i + 1)]; + } + return result; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/DesEdeWrapEngine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/DesEdeWrapEngine.cs.meta new file mode 100644 index 0000000..a900e19 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/DesEdeWrapEngine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: de09fddd5558cc841a0ea977f9135e9d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/DesEngine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/DesEngine.cs new file mode 100644 index 0000000..cfd5068 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/DesEngine.cs @@ -0,0 +1,475 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /// A class that provides a basic DES engine. + public class DesEngine + : IBlockCipher + { + internal const int BLOCK_SIZE = 8; + + private int[] workingKey; + + public virtual int[] GetWorkingKey() + { + return workingKey; + } + + /** + * initialise a DES cipher. + * + * @param forEncryption whether or not we are for encryption. + * @param parameters the parameters required to set up the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (!(parameters is KeyParameter)) + throw new ArgumentException("invalid parameter passed to DES init - " + Platform.GetTypeName(parameters)); + + workingKey = GenerateWorkingKey(forEncryption, ((KeyParameter)parameters).GetKey()); + } + + public virtual string AlgorithmName + { + get { return "DES"; } + } + + public virtual bool IsPartialBlockOkay + { + get { return false; } + } + + public virtual int GetBlockSize() + { + return BLOCK_SIZE; + } + + public virtual int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + if (workingKey == null) + throw new InvalidOperationException("DES engine not initialised"); + + Check.DataLength(input, inOff, BLOCK_SIZE, "input buffer too short"); + Check.OutputLength(output, outOff, BLOCK_SIZE, "output buffer too short"); + + DesFunc(workingKey, input, inOff, output, outOff); + + return BLOCK_SIZE; + } + + public virtual void Reset() + { + } + + /** + * what follows is mainly taken from "Applied Cryptography", by + * Bruce Schneier, however it also bears great resemblance to Richard + * Outerbridge's D3DES... + */ + +// private static readonly short[] Df_Key = +// { +// 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef, +// 0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10, +// 0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67 +// }; + + private static readonly short[] bytebit = + { + 128, 64, 32, 16, 8, 4, 2, 1 + }; + + private static readonly int[] bigbyte = + { + 0x800000, 0x400000, 0x200000, 0x100000, + 0x80000, 0x40000, 0x20000, 0x10000, + 0x8000, 0x4000, 0x2000, 0x1000, + 0x800, 0x400, 0x200, 0x100, + 0x80, 0x40, 0x20, 0x10, + 0x8, 0x4, 0x2, 0x1 + }; + + /* + * Use the key schedule specified in the Standard (ANSI X3.92-1981). + */ + private static readonly byte[] pc1 = + { + 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, + 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, + 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, + 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 + }; + + private static readonly byte[] totrot = + { + 1, 2, 4, 6, 8, 10, 12, 14, + 15, 17, 19, 21, 23, 25, 27, 28 + }; + + private static readonly byte[] pc2 = + { + 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, + 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, + 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, + 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 + }; + + private static readonly uint[] SP1 = + { + 0x01010400, 0x00000000, 0x00010000, 0x01010404, + 0x01010004, 0x00010404, 0x00000004, 0x00010000, + 0x00000400, 0x01010400, 0x01010404, 0x00000400, + 0x01000404, 0x01010004, 0x01000000, 0x00000004, + 0x00000404, 0x01000400, 0x01000400, 0x00010400, + 0x00010400, 0x01010000, 0x01010000, 0x01000404, + 0x00010004, 0x01000004, 0x01000004, 0x00010004, + 0x00000000, 0x00000404, 0x00010404, 0x01000000, + 0x00010000, 0x01010404, 0x00000004, 0x01010000, + 0x01010400, 0x01000000, 0x01000000, 0x00000400, + 0x01010004, 0x00010000, 0x00010400, 0x01000004, + 0x00000400, 0x00000004, 0x01000404, 0x00010404, + 0x01010404, 0x00010004, 0x01010000, 0x01000404, + 0x01000004, 0x00000404, 0x00010404, 0x01010400, + 0x00000404, 0x01000400, 0x01000400, 0x00000000, + 0x00010004, 0x00010400, 0x00000000, 0x01010004 + }; + + private static readonly uint[] SP2 = + { + 0x80108020, 0x80008000, 0x00008000, 0x00108020, + 0x00100000, 0x00000020, 0x80100020, 0x80008020, + 0x80000020, 0x80108020, 0x80108000, 0x80000000, + 0x80008000, 0x00100000, 0x00000020, 0x80100020, + 0x00108000, 0x00100020, 0x80008020, 0x00000000, + 0x80000000, 0x00008000, 0x00108020, 0x80100000, + 0x00100020, 0x80000020, 0x00000000, 0x00108000, + 0x00008020, 0x80108000, 0x80100000, 0x00008020, + 0x00000000, 0x00108020, 0x80100020, 0x00100000, + 0x80008020, 0x80100000, 0x80108000, 0x00008000, + 0x80100000, 0x80008000, 0x00000020, 0x80108020, + 0x00108020, 0x00000020, 0x00008000, 0x80000000, + 0x00008020, 0x80108000, 0x00100000, 0x80000020, + 0x00100020, 0x80008020, 0x80000020, 0x00100020, + 0x00108000, 0x00000000, 0x80008000, 0x00008020, + 0x80000000, 0x80100020, 0x80108020, 0x00108000 + }; + + private static readonly uint[] SP3 = + { + 0x00000208, 0x08020200, 0x00000000, 0x08020008, + 0x08000200, 0x00000000, 0x00020208, 0x08000200, + 0x00020008, 0x08000008, 0x08000008, 0x00020000, + 0x08020208, 0x00020008, 0x08020000, 0x00000208, + 0x08000000, 0x00000008, 0x08020200, 0x00000200, + 0x00020200, 0x08020000, 0x08020008, 0x00020208, + 0x08000208, 0x00020200, 0x00020000, 0x08000208, + 0x00000008, 0x08020208, 0x00000200, 0x08000000, + 0x08020200, 0x08000000, 0x00020008, 0x00000208, + 0x00020000, 0x08020200, 0x08000200, 0x00000000, + 0x00000200, 0x00020008, 0x08020208, 0x08000200, + 0x08000008, 0x00000200, 0x00000000, 0x08020008, + 0x08000208, 0x00020000, 0x08000000, 0x08020208, + 0x00000008, 0x00020208, 0x00020200, 0x08000008, + 0x08020000, 0x08000208, 0x00000208, 0x08020000, + 0x00020208, 0x00000008, 0x08020008, 0x00020200 + }; + + private static readonly uint[] SP4 = + { + 0x00802001, 0x00002081, 0x00002081, 0x00000080, + 0x00802080, 0x00800081, 0x00800001, 0x00002001, + 0x00000000, 0x00802000, 0x00802000, 0x00802081, + 0x00000081, 0x00000000, 0x00800080, 0x00800001, + 0x00000001, 0x00002000, 0x00800000, 0x00802001, + 0x00000080, 0x00800000, 0x00002001, 0x00002080, + 0x00800081, 0x00000001, 0x00002080, 0x00800080, + 0x00002000, 0x00802080, 0x00802081, 0x00000081, + 0x00800080, 0x00800001, 0x00802000, 0x00802081, + 0x00000081, 0x00000000, 0x00000000, 0x00802000, + 0x00002080, 0x00800080, 0x00800081, 0x00000001, + 0x00802001, 0x00002081, 0x00002081, 0x00000080, + 0x00802081, 0x00000081, 0x00000001, 0x00002000, + 0x00800001, 0x00002001, 0x00802080, 0x00800081, + 0x00002001, 0x00002080, 0x00800000, 0x00802001, + 0x00000080, 0x00800000, 0x00002000, 0x00802080 + }; + + private static readonly uint[] SP5 = + { + 0x00000100, 0x02080100, 0x02080000, 0x42000100, + 0x00080000, 0x00000100, 0x40000000, 0x02080000, + 0x40080100, 0x00080000, 0x02000100, 0x40080100, + 0x42000100, 0x42080000, 0x00080100, 0x40000000, + 0x02000000, 0x40080000, 0x40080000, 0x00000000, + 0x40000100, 0x42080100, 0x42080100, 0x02000100, + 0x42080000, 0x40000100, 0x00000000, 0x42000000, + 0x02080100, 0x02000000, 0x42000000, 0x00080100, + 0x00080000, 0x42000100, 0x00000100, 0x02000000, + 0x40000000, 0x02080000, 0x42000100, 0x40080100, + 0x02000100, 0x40000000, 0x42080000, 0x02080100, + 0x40080100, 0x00000100, 0x02000000, 0x42080000, + 0x42080100, 0x00080100, 0x42000000, 0x42080100, + 0x02080000, 0x00000000, 0x40080000, 0x42000000, + 0x00080100, 0x02000100, 0x40000100, 0x00080000, + 0x00000000, 0x40080000, 0x02080100, 0x40000100 + }; + + private static readonly uint[] SP6 = + { + 0x20000010, 0x20400000, 0x00004000, 0x20404010, + 0x20400000, 0x00000010, 0x20404010, 0x00400000, + 0x20004000, 0x00404010, 0x00400000, 0x20000010, + 0x00400010, 0x20004000, 0x20000000, 0x00004010, + 0x00000000, 0x00400010, 0x20004010, 0x00004000, + 0x00404000, 0x20004010, 0x00000010, 0x20400010, + 0x20400010, 0x00000000, 0x00404010, 0x20404000, + 0x00004010, 0x00404000, 0x20404000, 0x20000000, + 0x20004000, 0x00000010, 0x20400010, 0x00404000, + 0x20404010, 0x00400000, 0x00004010, 0x20000010, + 0x00400000, 0x20004000, 0x20000000, 0x00004010, + 0x20000010, 0x20404010, 0x00404000, 0x20400000, + 0x00404010, 0x20404000, 0x00000000, 0x20400010, + 0x00000010, 0x00004000, 0x20400000, 0x00404010, + 0x00004000, 0x00400010, 0x20004010, 0x00000000, + 0x20404000, 0x20000000, 0x00400010, 0x20004010 + }; + + private static readonly uint[] SP7 = + { + 0x00200000, 0x04200002, 0x04000802, 0x00000000, + 0x00000800, 0x04000802, 0x00200802, 0x04200800, + 0x04200802, 0x00200000, 0x00000000, 0x04000002, + 0x00000002, 0x04000000, 0x04200002, 0x00000802, + 0x04000800, 0x00200802, 0x00200002, 0x04000800, + 0x04000002, 0x04200000, 0x04200800, 0x00200002, + 0x04200000, 0x00000800, 0x00000802, 0x04200802, + 0x00200800, 0x00000002, 0x04000000, 0x00200800, + 0x04000000, 0x00200800, 0x00200000, 0x04000802, + 0x04000802, 0x04200002, 0x04200002, 0x00000002, + 0x00200002, 0x04000000, 0x04000800, 0x00200000, + 0x04200800, 0x00000802, 0x00200802, 0x04200800, + 0x00000802, 0x04000002, 0x04200802, 0x04200000, + 0x00200800, 0x00000000, 0x00000002, 0x04200802, + 0x00000000, 0x00200802, 0x04200000, 0x00000800, + 0x04000002, 0x04000800, 0x00000800, 0x00200002 + }; + + private static readonly uint[] SP8 = + { + 0x10001040, 0x00001000, 0x00040000, 0x10041040, + 0x10000000, 0x10001040, 0x00000040, 0x10000000, + 0x00040040, 0x10040000, 0x10041040, 0x00041000, + 0x10041000, 0x00041040, 0x00001000, 0x00000040, + 0x10040000, 0x10000040, 0x10001000, 0x00001040, + 0x00041000, 0x00040040, 0x10040040, 0x10041000, + 0x00001040, 0x00000000, 0x00000000, 0x10040040, + 0x10000040, 0x10001000, 0x00041040, 0x00040000, + 0x00041040, 0x00040000, 0x10041000, 0x00001000, + 0x00000040, 0x10040040, 0x00001000, 0x00041040, + 0x10001000, 0x00000040, 0x10000040, 0x10040000, + 0x10040040, 0x10000000, 0x00040000, 0x10001040, + 0x00000000, 0x10041040, 0x00040040, 0x10000040, + 0x10040000, 0x10001000, 0x10001040, 0x00000000, + 0x10041040, 0x00041000, 0x00041000, 0x00001040, + 0x00001040, 0x00040040, 0x10000000, 0x10041000 + }; + + /** + * Generate an integer based working key based on our secret key + * and what we processing we are planning to do. + * + * Acknowledgements for this routine go to James Gillogly and Phil Karn. + * (whoever, and wherever they are!). + */ + protected static int[] GenerateWorkingKey( + bool encrypting, + byte[] key) + { + int[] newKey = new int[32]; + bool[] pc1m = new bool[56]; + bool[] pcr = new bool[56]; + + for (int j = 0; j < 56; j++ ) + { + int l = pc1[j]; + + pc1m[j] = ((key[(uint) l >> 3] & bytebit[l & 07]) != 0); + } + + for (int i = 0; i < 16; i++) + { + int l, m, n; + + if (encrypting) + { + m = i << 1; + } + else + { + m = (15 - i) << 1; + } + + n = m + 1; + newKey[m] = newKey[n] = 0; + + for (int j = 0; j < 28; j++) + { + l = j + totrot[i]; + if ( l < 28 ) + { + pcr[j] = pc1m[l]; + } + else + { + pcr[j] = pc1m[l - 28]; + } + } + + for (int j = 28; j < 56; j++) + { + l = j + totrot[i]; + if (l < 56 ) + { + pcr[j] = pc1m[l]; + } + else + { + pcr[j] = pc1m[l - 28]; + } + } + + for (int j = 0; j < 24; j++) + { + if (pcr[pc2[j]]) + { + newKey[m] |= bigbyte[j]; + } + + if (pcr[pc2[j + 24]]) + { + newKey[n] |= bigbyte[j]; + } + } + } + + // + // store the processed key + // + for (int i = 0; i != 32; i += 2) + { + int i1, i2; + + i1 = newKey[i]; + i2 = newKey[i + 1]; + + newKey[i] = (int) ( (uint) ((i1 & 0x00fc0000) << 6) | + (uint) ((i1 & 0x00000fc0) << 10) | + ((uint) (i2 & 0x00fc0000) >> 10) | + ((uint) (i2 & 0x00000fc0) >> 6)); + + newKey[i + 1] = (int) ( (uint) ((i1 & 0x0003f000) << 12) | + (uint) ((i1 & 0x0000003f) << 16) | + ((uint) (i2 & 0x0003f000) >> 4) | + (uint) (i2 & 0x0000003f)); + } + + return newKey; + } + + /** + * the DES engine. + */ + internal static void DesFunc( + int[] wKey, + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + uint left = Pack.BE_To_UInt32(input, inOff); + uint right = Pack.BE_To_UInt32(input, inOff + 4); + uint work; + + work = ((left >> 4) ^ right) & 0x0f0f0f0f; + right ^= work; + left ^= (work << 4); + work = ((left >> 16) ^ right) & 0x0000ffff; + right ^= work; + left ^= (work << 16); + work = ((right >> 2) ^ left) & 0x33333333; + left ^= work; + right ^= (work << 2); + work = ((right >> 8) ^ left) & 0x00ff00ff; + left ^= work; + right ^= (work << 8); + right = (right << 1) | (right >> 31); + work = (left ^ right) & 0xaaaaaaaa; + left ^= work; + right ^= work; + left = (left << 1) | (left >> 31); + + for (int round = 0; round < 8; round++) + { + uint fval; + + work = (right << 28) | (right >> 4); + work ^= (uint)wKey[round * 4 + 0]; + fval = SP7[work & 0x3f]; + fval |= SP5[(work >> 8) & 0x3f]; + fval |= SP3[(work >> 16) & 0x3f]; + fval |= SP1[(work >> 24) & 0x3f]; + work = right ^ (uint)wKey[round * 4 + 1]; + fval |= SP8[ work & 0x3f]; + fval |= SP6[(work >> 8) & 0x3f]; + fval |= SP4[(work >> 16) & 0x3f]; + fval |= SP2[(work >> 24) & 0x3f]; + left ^= fval; + work = (left << 28) | (left >> 4); + work ^= (uint)wKey[round * 4 + 2]; + fval = SP7[ work & 0x3f]; + fval |= SP5[(work >> 8) & 0x3f]; + fval |= SP3[(work >> 16) & 0x3f]; + fval |= SP1[(work >> 24) & 0x3f]; + work = left ^ (uint)wKey[round * 4 + 3]; + fval |= SP8[ work & 0x3f]; + fval |= SP6[(work >> 8) & 0x3f]; + fval |= SP4[(work >> 16) & 0x3f]; + fval |= SP2[(work >> 24) & 0x3f]; + right ^= fval; + } + + right = (right << 31) | (right >> 1); + work = (left ^ right) & 0xaaaaaaaa; + left ^= work; + right ^= work; + left = (left << 31) | (left >> 1); + work = ((left >> 8) ^ right) & 0x00ff00ff; + right ^= work; + left ^= (work << 8); + work = ((left >> 2) ^ right) & 0x33333333; + right ^= work; + left ^= (work << 2); + work = ((right >> 16) ^ left) & 0x0000ffff; + left ^= work; + right ^= (work << 16); + work = ((right >> 4) ^ left) & 0x0f0f0f0f; + left ^= work; + right ^= (work << 4); + + Pack.UInt32_To_BE(right, outBytes, outOff); + Pack.UInt32_To_BE(left, outBytes, outOff + 4); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/DesEngine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/DesEngine.cs.meta new file mode 100644 index 0000000..47c3ed8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/DesEngine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: baeacd982acf9b84a86aef46671b42d1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/Dstu7624Engine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/Dstu7624Engine.cs new file mode 100644 index 0000000..4242d3a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/Dstu7624Engine.cs @@ -0,0 +1,1084 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * implementation of DSTU 7624 (Kalyna) + */ + public class Dstu7624Engine + : IBlockCipher + { + private ulong[] internalState; + private ulong[] workingKey; + private ulong[][] roundKeys; + + /* Number of 64-bit words in block */ + private int wordsInBlock; + + /* Number of 64-bit words in key */ + private int wordsInKey; + + /* Number of encryption rounds depending on key length */ + private const int ROUNDS_128 = 10; + private const int ROUNDS_256 = 14; + private const int ROUNDS_512 = 18; + + private int roundsAmount; + + private bool forEncryption; + + public Dstu7624Engine(int blockSizeBits) + { + /* DSTU7624 supports 128 | 256 | 512 key/block sizes */ + if (blockSizeBits != 128 && blockSizeBits != 256 && blockSizeBits != 512) + { + throw new ArgumentException("unsupported block length: only 128/256/512 are allowed"); + } + + wordsInBlock = blockSizeBits / 64; + internalState = new ulong[wordsInBlock]; + } + + #region INITIALIZATION + + public virtual void Init(bool forEncryption, ICipherParameters parameters) + { + if (!(parameters is KeyParameter)) + throw new ArgumentException("Invalid parameter passed to Dstu7624Engine Init"); + + this.forEncryption = forEncryption; + + byte[] keyBytes = ((KeyParameter)parameters).GetKey(); + int keyBitLength = keyBytes.Length << 3; + int blockBitLength = wordsInBlock << 6; + + if (keyBitLength != 128 && keyBitLength != 256 && keyBitLength != 512) + { + throw new ArgumentException("unsupported key length: only 128/256/512 are allowed"); + } + + /* Limitations on key lengths depending on block lengths. See table 6.1 in standard */ + if (keyBitLength != blockBitLength && keyBitLength != (2 * blockBitLength)) + { + throw new ArgumentException("Unsupported key length"); + } + + switch (keyBitLength) + { + case 128: + roundsAmount = ROUNDS_128; + break; + case 256: + roundsAmount = ROUNDS_256; + break; + case 512: + roundsAmount = ROUNDS_512; + break; + } + + wordsInKey = keyBitLength / 64; + + /* +1 round key as defined in standard */ + roundKeys = new ulong[roundsAmount + 1][]; + for (int roundKeyIndex = 0; roundKeyIndex < roundKeys.Length; roundKeyIndex++) + { + roundKeys[roundKeyIndex] = new ulong[wordsInBlock]; + } + + workingKey = new ulong[wordsInKey]; + + if (keyBytes.Length != wordsInKey * 8) + { + throw new ArgumentException("Invalid key parameter passed to Dstu7624Engine Init"); + } + + /* Unpack encryption key bytes to words */ + Pack.LE_To_UInt64(keyBytes, 0, workingKey); + + ulong[] tempKeys = new ulong[wordsInBlock]; + + /* KSA in DSTU7624 is strengthened to mitigate known weaknesses in AES KSA (eprint.iacr.org/2012/260.pdf) */ + WorkingKeyExpandKT(workingKey, tempKeys); + WorkingKeyExpandEven(workingKey, tempKeys); + WorkingKeyExpandOdd(); + } + + private void WorkingKeyExpandKT(ulong[] workingKey, ulong[] tempKeys) + { + ulong[] k0 = new ulong[wordsInBlock]; + ulong[] k1 = new ulong[wordsInBlock]; + + internalState = new ulong[wordsInBlock]; + internalState[0] += (ulong)(wordsInBlock + wordsInKey + 1); + + if (wordsInBlock == wordsInKey) + { + Array.Copy(workingKey, 0, k0, 0, k0.Length); + Array.Copy(workingKey, 0, k1, 0, k1.Length); + } + else + { + Array.Copy(workingKey, 0, k0, 0, wordsInBlock); + Array.Copy(workingKey, wordsInBlock, k1, 0, wordsInBlock); + } + + + for (int wordIndex = 0; wordIndex < internalState.Length; wordIndex++) + { + internalState[wordIndex] += k0[wordIndex]; + } + + EncryptionRound(); + + for (int wordIndex = 0; wordIndex < internalState.Length; wordIndex++) + { + internalState[wordIndex] ^= k1[wordIndex]; + } + + EncryptionRound(); + + for (int wordIndex = 0; wordIndex < internalState.Length; wordIndex++) + { + internalState[wordIndex] += k0[wordIndex]; + } + + EncryptionRound(); + + Array.Copy(internalState, 0, tempKeys, 0, wordsInBlock); + } + + private void WorkingKeyExpandEven(ulong[] workingKey, ulong[] tempKey) + { + ulong[] initialData = new ulong[wordsInKey]; + ulong[] tempRoundKey = new ulong[wordsInBlock]; + + int round = 0; + + Array.Copy(workingKey, 0, initialData, 0, wordsInKey); + + ulong tmv = 0x0001000100010001UL; + + while (true) + { + for (int wordIndex = 0; wordIndex < wordsInBlock; wordIndex++) + { + tempRoundKey[wordIndex] = tempKey[wordIndex] + tmv; + } + + for (int wordIndex = 0; wordIndex < wordsInBlock; wordIndex++) + { + internalState[wordIndex] = initialData[wordIndex] + tempRoundKey[wordIndex]; + } + + EncryptionRound(); + + for (int wordIndex = 0; wordIndex < wordsInBlock; wordIndex++) + { + internalState[wordIndex] ^= tempRoundKey[wordIndex]; + } + + EncryptionRound(); + + for (int wordIndex = 0; wordIndex < wordsInBlock; wordIndex++) + { + internalState[wordIndex] += tempRoundKey[wordIndex]; + } + + Array.Copy(internalState, 0, roundKeys[round], 0, wordsInBlock); + + if (roundsAmount == round) + { + break; + } + + if (wordsInKey != wordsInBlock) + { + round += 2; + tmv <<= 1; + + for (int wordIndex = 0; wordIndex < wordsInBlock; wordIndex++) + { + tempRoundKey[wordIndex] = tempKey[wordIndex] + tmv; + } + + for (int wordIndex = 0; wordIndex < wordsInBlock; wordIndex++) + { + internalState[wordIndex] = initialData[wordsInBlock + wordIndex] + tempRoundKey[wordIndex]; + } + + EncryptionRound(); + + for (int wordIndex = 0; wordIndex < wordsInBlock; wordIndex++) + { + internalState[wordIndex] ^= tempRoundKey[wordIndex]; + } + + EncryptionRound(); + + for (int wordIndex = 0; wordIndex < wordsInBlock; wordIndex++) + { + internalState[wordIndex] += tempRoundKey[wordIndex]; + } + + Array.Copy(internalState, 0, roundKeys[round], 0, wordsInBlock); + + if (roundsAmount == round) + { + break; + } + } + + round += 2; + tmv <<= 1; + + ulong temp = initialData[0]; + for (int i = 1; i < initialData.Length; ++i) + { + initialData[i - 1] = initialData[i]; + } + initialData[initialData.Length - 1] = temp; + } + } + + private void WorkingKeyExpandOdd() + { + for (int roundIndex = 1; roundIndex < roundsAmount; roundIndex += 2) + { + RotateLeft(roundKeys[roundIndex - 1], roundKeys[roundIndex]); + } + } + + #endregion + + public virtual int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff) + { + if (workingKey == null) + throw new InvalidOperationException("Dstu7624Engine not initialised"); + + Check.DataLength(input, inOff, GetBlockSize(), "input buffer too short"); + Check.OutputLength(output, outOff, GetBlockSize(), "output buffer too short"); + + if (forEncryption) + { + /* Encrypt */ + switch (wordsInBlock) + { + case 2: + { + EncryptBlock_128(input, inOff, output, outOff); + break; + } + default: + { + Pack.LE_To_UInt64(input, inOff, internalState); + AddRoundKey(0); + for (int round = 0;;) + { + EncryptionRound(); + + if (++round == roundsAmount) + { + break; + } + + XorRoundKey(round); + } + AddRoundKey(roundsAmount); + Pack.UInt64_To_LE(internalState, output, outOff); + break; + } + } + } + else + { + /* Decrypt */ + switch (wordsInBlock) + { + case 2: + { + DecryptBlock_128(input, inOff, output, outOff); + break; + } + default: + { + Pack.LE_To_UInt64(input, inOff, internalState); + SubRoundKey(roundsAmount); + for (int round = roundsAmount;;) + { + DecryptionRound(); + + if (--round == 0) + { + break; + } + + XorRoundKey(round); + } + SubRoundKey(0); + Pack.UInt64_To_LE(internalState, output, outOff); + break; + } + } + } + + return GetBlockSize(); + } + + private void EncryptionRound() + { + SubBytes(); + ShiftRows(); + MixColumns(); + } + + private void DecryptionRound() + { + MixColumnsInv(); + InvShiftRows(); + InvSubBytes(); + } + + private void DecryptBlock_128(byte[] input, int inOff, byte[] output, int outOff) + { + ulong c0 = Pack.LE_To_UInt64(input, inOff); + ulong c1 = Pack.LE_To_UInt64(input, inOff + 8); + + ulong[] roundKey = roundKeys[roundsAmount]; + c0 -= roundKey[0]; + c1 -= roundKey[1]; + + for (int round = roundsAmount;;) + { + c0 = MixColumnInv(c0); + c1 = MixColumnInv(c1); + + uint lo0 = (uint)c0, hi0 = (uint)(c0 >> 32); + uint lo1 = (uint)c1, hi1 = (uint)(c1 >> 32); + + { + byte t0 = T0[lo0 & 0xFF]; + byte t1 = T1[(lo0 >> 8) & 0xFF]; + byte t2 = T2[(lo0 >> 16) & 0xFF]; + byte t3 = T3[lo0 >> 24]; + lo0 = (uint)t0 | ((uint)t1 << 8) | ((uint)t2 << 16) | ((uint)t3 << 24); + byte t4 = T0[hi1 & 0xFF]; + byte t5 = T1[(hi1 >> 8) & 0xFF]; + byte t6 = T2[(hi1 >> 16) & 0xFF]; + byte t7 = T3[hi1 >> 24]; + hi1 = (uint)t4 | ((uint)t5 << 8) | ((uint)t6 << 16) | ((uint)t7 << 24); + c0 = (ulong)lo0 | ((ulong)hi1 << 32); + } + + { + byte t0 = T0[lo1 & 0xFF]; + byte t1 = T1[(lo1 >> 8) & 0xFF]; + byte t2 = T2[(lo1 >> 16) & 0xFF]; + byte t3 = T3[lo1 >> 24]; + lo1 = (uint)t0 | ((uint)t1 << 8) | ((uint)t2 << 16) | ((uint)t3 << 24); + byte t4 = T0[hi0 & 0xFF]; + byte t5 = T1[(hi0 >> 8) & 0xFF]; + byte t6 = T2[(hi0 >> 16) & 0xFF]; + byte t7 = T3[hi0 >> 24]; + hi0 = (uint)t4 | ((uint)t5 << 8) | ((uint)t6 << 16) | ((uint)t7 << 24); + c1 = (ulong)lo1 | ((ulong)hi0 << 32); + } + + if (--round == 0) + { + break; + } + + roundKey = roundKeys[round]; + c0 ^= roundKey[0]; + c1 ^= roundKey[1]; + } + + roundKey = roundKeys[0]; + c0 -= roundKey[0]; + c1 -= roundKey[1]; + + Pack.UInt64_To_LE(c0, output, outOff); + Pack.UInt64_To_LE(c1, output, outOff + 8); + } + + private void EncryptBlock_128(byte[] input, int inOff, byte[] output, int outOff) + { + ulong c0 = Pack.LE_To_UInt64(input, inOff); + ulong c1 = Pack.LE_To_UInt64(input, inOff + 8); + + ulong[] roundKey = roundKeys[0]; + c0 += roundKey[0]; + c1 += roundKey[1]; + + for (int round = 0;;) + { + uint lo0 = (uint)c0, hi0 = (uint)(c0 >> 32); + uint lo1 = (uint)c1, hi1 = (uint)(c1 >> 32); + + { + byte t0 = S0[lo0 & 0xFF]; + byte t1 = S1[(lo0 >> 8) & 0xFF]; + byte t2 = S2[(lo0 >> 16) & 0xFF]; + byte t3 = S3[lo0 >> 24]; + lo0 = (uint)t0 | ((uint)t1 << 8) | ((uint)t2 << 16) | ((uint)t3 << 24); + byte t4 = S0[hi1 & 0xFF]; + byte t5 = S1[(hi1 >> 8) & 0xFF]; + byte t6 = S2[(hi1 >> 16) & 0xFF]; + byte t7 = S3[hi1 >> 24]; + hi1 = (uint)t4 | ((uint)t5 << 8) | ((uint)t6 << 16) | ((uint)t7 << 24); + c0 = (ulong)lo0 | ((ulong)hi1 << 32); + } + + { + byte t0 = S0[lo1 & 0xFF]; + byte t1 = S1[(lo1 >> 8) & 0xFF]; + byte t2 = S2[(lo1 >> 16) & 0xFF]; + byte t3 = S3[lo1 >> 24]; + lo1 = (uint)t0 | ((uint)t1 << 8) | ((uint)t2 << 16) | ((uint)t3 << 24); + byte t4 = S0[hi0 & 0xFF]; + byte t5 = S1[(hi0 >> 8) & 0xFF]; + byte t6 = S2[(hi0 >> 16) & 0xFF]; + byte t7 = S3[hi0 >> 24]; + hi0 = (uint)t4 | ((uint)t5 << 8) | ((uint)t6 << 16) | ((uint)t7 << 24); + c1 = (ulong)lo1 | ((ulong)hi0 << 32); + } + + c0 = MixColumn(c0); + c1 = MixColumn(c1); + + if (++round == roundsAmount) + { + break; + } + + roundKey = roundKeys[round]; + c0 ^= roundKey[0]; + c1 ^= roundKey[1]; + } + + roundKey = roundKeys[roundsAmount]; + c0 += roundKey[0]; + c1 += roundKey[1]; + + Pack.UInt64_To_LE(c0, output, outOff); + Pack.UInt64_To_LE(c1, output, outOff + 8); + } + + private void SubBytes() + { + for (int i = 0; i < wordsInBlock; i++) + { + ulong u = internalState[i]; + uint lo = (uint)u, hi = (uint)(u >> 32); + byte t0 = S0[lo & 0xFF]; + byte t1 = S1[(lo >> 8) & 0xFF]; + byte t2 = S2[(lo >> 16) & 0xFF]; + byte t3 = S3[lo >> 24]; + lo = (uint)t0 | ((uint)t1 << 8) | ((uint)t2 << 16) | ((uint)t3 << 24); + byte t4 = S0[hi & 0xFF]; + byte t5 = S1[(hi >> 8) & 0xFF]; + byte t6 = S2[(hi >> 16) & 0xFF]; + byte t7 = S3[hi >> 24]; + hi = (uint)t4 | ((uint)t5 << 8) | ((uint)t6 << 16) | ((uint)t7 << 24); + internalState[i] = (ulong)lo | ((ulong)hi << 32); + } + } + + private void InvSubBytes() + { + for (int i = 0; i < wordsInBlock; i++) + { + ulong u = internalState[i]; + uint lo = (uint)u, hi = (uint)(u >> 32); + byte t0 = T0[lo & 0xFF]; + byte t1 = T1[(lo >> 8) & 0xFF]; + byte t2 = T2[(lo >> 16) & 0xFF]; + byte t3 = T3[lo >> 24]; + lo = (uint)t0 | ((uint)t1 << 8) | ((uint)t2 << 16) | ((uint)t3 << 24); + byte t4 = T0[hi & 0xFF]; + byte t5 = T1[(hi >> 8) & 0xFF]; + byte t6 = T2[(hi >> 16) & 0xFF]; + byte t7 = T3[hi >> 24]; + hi = (uint)t4 | ((uint)t5 << 8) | ((uint)t6 << 16) | ((uint)t7 << 24); + internalState[i] = (ulong)lo | ((ulong)hi << 32); + } + } + + private void ShiftRows() + { + switch (wordsInBlock) + { + case 2: + { + ulong c0 = internalState[0], c1 = internalState[1]; + ulong d; + + d = (c0 ^ c1) & 0xFFFFFFFF00000000UL; c0 ^= d; c1 ^= d; + + internalState[0] = c0; + internalState[1] = c1; + break; + } + case 4: + { + ulong c0 = internalState[0], c1 = internalState[1], c2 = internalState[2], c3 = internalState[3]; + ulong d; + + d = (c0 ^ c2) & 0xFFFFFFFF00000000UL; c0 ^= d; c2 ^= d; + d = (c1 ^ c3) & 0x0000FFFFFFFF0000UL; c1 ^= d; c3 ^= d; + + d = (c0 ^ c1) & 0xFFFF0000FFFF0000UL; c0 ^= d; c1 ^= d; + d = (c2 ^ c3) & 0xFFFF0000FFFF0000UL; c2 ^= d; c3 ^= d; + + internalState[0] = c0; + internalState[1] = c1; + internalState[2] = c2; + internalState[3] = c3; + break; + } + case 8: + { + ulong c0 = internalState[0], c1 = internalState[1], c2 = internalState[2], c3 = internalState[3]; + ulong c4 = internalState[4], c5 = internalState[5], c6 = internalState[6], c7 = internalState[7]; + ulong d; + + d = (c0 ^ c4) & 0xFFFFFFFF00000000UL; c0 ^= d; c4 ^= d; + d = (c1 ^ c5) & 0x00FFFFFFFF000000UL; c1 ^= d; c5 ^= d; + d = (c2 ^ c6) & 0x0000FFFFFFFF0000UL; c2 ^= d; c6 ^= d; + d = (c3 ^ c7) & 0x000000FFFFFFFF00UL; c3 ^= d; c7 ^= d; + + d = (c0 ^ c2) & 0xFFFF0000FFFF0000UL; c0 ^= d; c2 ^= d; + d = (c1 ^ c3) & 0x00FFFF0000FFFF00UL; c1 ^= d; c3 ^= d; + d = (c4 ^ c6) & 0xFFFF0000FFFF0000UL; c4 ^= d; c6 ^= d; + d = (c5 ^ c7) & 0x00FFFF0000FFFF00UL; c5 ^= d; c7 ^= d; + + d = (c0 ^ c1) & 0xFF00FF00FF00FF00UL; c0 ^= d; c1 ^= d; + d = (c2 ^ c3) & 0xFF00FF00FF00FF00UL; c2 ^= d; c3 ^= d; + d = (c4 ^ c5) & 0xFF00FF00FF00FF00UL; c4 ^= d; c5 ^= d; + d = (c6 ^ c7) & 0xFF00FF00FF00FF00UL; c6 ^= d; c7 ^= d; + + internalState[0] = c0; + internalState[1] = c1; + internalState[2] = c2; + internalState[3] = c3; + internalState[4] = c4; + internalState[5] = c5; + internalState[6] = c6; + internalState[7] = c7; + break; + } + default: + { + throw new InvalidOperationException("unsupported block length: only 128/256/512 are allowed"); + } + } + } + + private void InvShiftRows() + { + switch (wordsInBlock) + { + case 2: + { + ulong c0 = internalState[0], c1 = internalState[1]; + ulong d; + + d = (c0 ^ c1) & 0xFFFFFFFF00000000UL; c0 ^= d; c1 ^= d; + + internalState[0] = c0; + internalState[1] = c1; + break; + } + case 4: + { + ulong c0 = internalState[0], c1 = internalState[1], c2 = internalState[2], c3 = internalState[3]; + ulong d; + + d = (c0 ^ c1) & 0xFFFF0000FFFF0000UL; c0 ^= d; c1 ^= d; + d = (c2 ^ c3) & 0xFFFF0000FFFF0000UL; c2 ^= d; c3 ^= d; + + d = (c0 ^ c2) & 0xFFFFFFFF00000000UL; c0 ^= d; c2 ^= d; + d = (c1 ^ c3) & 0x0000FFFFFFFF0000UL; c1 ^= d; c3 ^= d; + + internalState[0] = c0; + internalState[1] = c1; + internalState[2] = c2; + internalState[3] = c3; + break; + } + case 8: + { + ulong c0 = internalState[0], c1 = internalState[1], c2 = internalState[2], c3 = internalState[3]; + ulong c4 = internalState[4], c5 = internalState[5], c6 = internalState[6], c7 = internalState[7]; + ulong d; + + d = (c0 ^ c1) & 0xFF00FF00FF00FF00UL; c0 ^= d; c1 ^= d; + d = (c2 ^ c3) & 0xFF00FF00FF00FF00UL; c2 ^= d; c3 ^= d; + d = (c4 ^ c5) & 0xFF00FF00FF00FF00UL; c4 ^= d; c5 ^= d; + d = (c6 ^ c7) & 0xFF00FF00FF00FF00UL; c6 ^= d; c7 ^= d; + + d = (c0 ^ c2) & 0xFFFF0000FFFF0000UL; c0 ^= d; c2 ^= d; + d = (c1 ^ c3) & 0x00FFFF0000FFFF00UL; c1 ^= d; c3 ^= d; + d = (c4 ^ c6) & 0xFFFF0000FFFF0000UL; c4 ^= d; c6 ^= d; + d = (c5 ^ c7) & 0x00FFFF0000FFFF00UL; c5 ^= d; c7 ^= d; + + d = (c0 ^ c4) & 0xFFFFFFFF00000000UL; c0 ^= d; c4 ^= d; + d = (c1 ^ c5) & 0x00FFFFFFFF000000UL; c1 ^= d; c5 ^= d; + d = (c2 ^ c6) & 0x0000FFFFFFFF0000UL; c2 ^= d; c6 ^= d; + d = (c3 ^ c7) & 0x000000FFFFFFFF00UL; c3 ^= d; c7 ^= d; + + internalState[0] = c0; + internalState[1] = c1; + internalState[2] = c2; + internalState[3] = c3; + internalState[4] = c4; + internalState[5] = c5; + internalState[6] = c6; + internalState[7] = c7; + break; + } + default: + { + throw new InvalidOperationException("unsupported block length: only 128/256/512 are allowed"); + } + } + } + + private void AddRoundKey(int round) + { + ulong[] roundKey = roundKeys[round]; + for (int i = 0; i < wordsInBlock; ++i) + { + internalState[i] += roundKey[i]; + } + } + + private void SubRoundKey(int round) + { + ulong[] roundKey = roundKeys[round]; + for (int i = 0; i < wordsInBlock; ++i) + { + internalState[i] -= roundKey[i]; + } + } + + private void XorRoundKey(int round) + { + ulong[] roundKey = roundKeys[round]; + for (int i = 0; i < wordsInBlock; i++) + { + internalState[i] ^= roundKey[i]; + } + } + + private static ulong MixColumn(ulong c) + { + //// Calculate column multiplied by powers of 'x' + //ulong x0 = c; + //ulong x1 = MulX(x0); + //ulong x2 = MulX(x1); + //ulong x3 = MulX(x2); + + //// Calculate products with circulant matrix from (0x01, 0x01, 0x05, 0x01, 0x08, 0x06, 0x07, 0x04) + //ulong m0 = x0; + //ulong m1 = x0; + //ulong m2 = x0 ^ x2; + //ulong m3 = x0; + //ulong m4 = x3; + //ulong m5 = x1 ^ x2; + //ulong m6 = x0 ^ x1 ^ x2; + //ulong m7 = x2; + + //// Assemble the rotated products + //return m0 + // ^ Rotate(8, m1) + // ^ Rotate(16, m2) + // ^ Rotate(24, m3) + // ^ Rotate(32, m4) + // ^ Rotate(40, m5) + // ^ Rotate(48, m6) + // ^ Rotate(56, m7); + + ulong x1 = MulX(c); + ulong u, v; + + u = Rotate(8, c) ^ c; + u ^= Rotate(16, u); + u ^= Rotate(48, c); + + v = MulX2(u ^ c ^ x1); + + return u ^ Rotate(32, v) ^ Rotate(40, x1) ^ Rotate(48, x1); + } + + private void MixColumns() + { + for (int col = 0; col < wordsInBlock; ++col) + { + internalState[col] = MixColumn(internalState[col]); + } + } + + private static ulong MixColumnInv(ulong c) + { +/* + // Calculate column multiplied by powers of 'x' + ulong x0 = c; + ulong x1 = MulX(x0); + ulong x2 = MulX(x1); + ulong x3 = MulX(x2); + ulong x4 = MulX(x3); + ulong x5 = MulX(x4); + ulong x6 = MulX(x5); + ulong x7 = MulX(x6); + + // Calculate products with circulant matrix from (0xAD,0x95,0x76,0xA8,0x2F,0x49,0xD7,0xCA) + //long m0 = x0 ^ x2 ^ x3 ^ x5 ^ x7; + //long m1 = x0 ^ x2 ^ x4 ^ x7; + //long m2 = x1 ^ x2 ^ x4 ^ x5 ^ x6; + //long m3 = x3 ^ x5 ^ x7; + //long m4 = x0 ^ x1 ^ x2 ^ x3 ^ x5; + //long m5 = x0 ^ x3 ^ x6; + //long m6 = x0 ^ x1 ^ x2 ^ x4 ^ x6 ^ x7; + //long m7 = x1 ^ x3 ^ x6 ^ x7; + + ulong m5 = x0 ^ x3 ^ x6; + x0 ^= x2; + ulong m3 = x3 ^ x5 ^ x7; + ulong m0 = m3 ^ x0; + ulong m6 = x0 ^ x4; + ulong m1 = m6 ^ x7; + x5 ^= x1; + x7 ^= x1 ^ x6; + ulong m2 = x2 ^ x4 ^ x5 ^ x6; + ulong m4 = x0 ^ x3 ^ x5; + m6 ^= x7; + ulong m7 = x3 ^ x7; + + // Assemble the rotated products + return m0 + ^ Rotate(8, m1) + ^ Rotate(16, m2) + ^ Rotate(24, m3) + ^ Rotate(32, m4) + ^ Rotate(40, m5) + ^ Rotate(48, m6) + ^ Rotate(56, m7); +*/ + + ulong u0 = c; + u0 ^= Rotate( 8, u0); + u0 ^= Rotate(32, u0); + u0 ^= Rotate(48, c); + + ulong t = u0 ^ c; + + ulong c48 = Rotate(48, c); + ulong c56 = Rotate(56, c); + + ulong u7 = t ^ c56; + ulong u6 = Rotate(56, t); + u6 ^= MulX(u7); + ulong u5 = Rotate(16, t) ^ c; + u5 ^= Rotate(40, MulX(u6) ^ c); + ulong u4 = t ^ c48; + u4 ^= MulX(u5); + ulong u3 = Rotate(16, u0); + u3 ^= MulX(u4); + ulong u2 = t ^ Rotate(24, c) ^ c48 ^ c56; + u2 ^= MulX(u3); + ulong u1 = Rotate(32, t) ^ c ^ c56; + u1 ^= MulX(u2); + u0 ^= MulX(Rotate(40, u1)); + + return u0; + } + + private void MixColumnsInv() + { + for (int col = 0; col < wordsInBlock; ++col) + { + internalState[col] = MixColumnInv(internalState[col]); + } + } + + private static ulong MulX(ulong n) + { + return ((n & 0x7F7F7F7F7F7F7F7FUL) << 1) ^ (((n & 0x8080808080808080UL) >> 7) * 0x1DUL); + } + + private static ulong MulX2(ulong n) + { + return ((n & 0x3F3F3F3F3F3F3F3FUL) << 2) ^ (((n & 0x8080808080808080UL) >> 6) * 0x1DUL) ^ (((n & 0x4040404040404040UL) >> 6) * 0x1DUL); + } + + //private static ulong MulX4(ulong n) + //{ + // ulong u = n & 0xF0F0F0F0F0F0F0F0UL; + // return ((n & 0x0F0F0F0F0F0F0F0FUL) << 4) ^ u ^ (u >> 1) ^ (u >> 2) ^ (u >> 4); + //} + + /* + * Pair-wise modular multiplication of 8 byte-pairs. + * + * REDUCTION_POLYNOMIAL is x^8 + x^4 + x^3 + x^2 + 1 + */ + //private static ulong MultiplyGFx8(ulong u, ulong v, int vMaxDegree) + //{ + // ulong r = u & ((v & 0x0101010101010101UL) * 0xFFUL); + // for (int i = 1; i <= vMaxDegree; ++i) + // { + // u = ((u & 0x7F7F7F7F7F7F7F7FUL) << 1) ^ (((u >> 7) & 0x0101010101010101UL) * 0x1DUL); + // v >>= 1; + + // r ^= u & ((v & 0x0101010101010101UL) * 0xFFUL); + // } + + // return r; + //} + + //private static ulong MultiplyMds(ulong u) + //{ + // ulong r = 0, s = 0, t = (u >> 8); + // r ^= u & 0x0000001F00000000UL; r <<= 1; + // s ^= t & 0x00000000E0000000UL; s <<= 1; + // r ^= u & 0x3F3F3F00003F0000UL; r <<= 1; + // s ^= t & 0x00C0C0C00000C000UL; s <<= 1; + // r ^= u & 0x007F7F0000000000UL; r <<= 1; + // s ^= t & 0x0000808000000000UL; s <<= 1; + // r ^= u & 0x00FF0000FFFFFFFFUL; + // r ^= s ^ (s << 2) ^ (s << 3) ^ (s << 4); + // return r; + //} + + private static ulong Rotate(int n, ulong x) + { + return (x >> n) | (x << -n); + } + + private void RotateLeft(ulong[] x, ulong[] z) + { + switch (wordsInBlock) + { + case 2: + { + ulong x0 = x[0], x1 = x[1]; + z[0] = (x0 >> 56) | (x1 << 8); + z[1] = (x1 >> 56) | (x0 << 8); + break; + } + case 4: + { + ulong x0 = x[0], x1 = x[1], x2 = x[2], x3 = x[3]; + z[0] = (x1 >> 24) | (x2 << 40); + z[1] = (x2 >> 24) | (x3 << 40); + z[2] = (x3 >> 24) | (x0 << 40); + z[3] = (x0 >> 24) | (x1 << 40); + break; + } + case 8: + { + ulong x0 = x[0], x1 = x[1], x2 = x[2], x3 = x[3]; + ulong x4 = x[4], x5 = x[5], x6 = x[6], x7 = x[7]; + z[0] = (x2 >> 24) | (x3 << 40); + z[1] = (x3 >> 24) | (x4 << 40); + z[2] = (x4 >> 24) | (x5 << 40); + z[3] = (x5 >> 24) | (x6 << 40); + z[4] = (x6 >> 24) | (x7 << 40); + z[5] = (x7 >> 24) | (x0 << 40); + z[6] = (x0 >> 24) | (x1 << 40); + z[7] = (x1 >> 24) | (x2 << 40); + break; + } + default: + { + throw new InvalidOperationException("unsupported block length: only 128/256/512 are allowed"); + } + } + } + + #region TABLES AND S-BOXES + + private const ulong mdsMatrix = 0x0407060801050101UL; + private const ulong mdsInvMatrix = 0xCAD7492FA87695ADUL; + + private static readonly byte[] S0 = new byte[]{ + 0xa8, 0x43, 0x5f, 0x06, 0x6b, 0x75, 0x6c, 0x59, 0x71, 0xdf, 0x87, 0x95, 0x17, 0xf0, 0xd8, 0x09, + 0x6d, 0xf3, 0x1d, 0xcb, 0xc9, 0x4d, 0x2c, 0xaf, 0x79, 0xe0, 0x97, 0xfd, 0x6f, 0x4b, 0x45, 0x39, + 0x3e, 0xdd, 0xa3, 0x4f, 0xb4, 0xb6, 0x9a, 0x0e, 0x1f, 0xbf, 0x15, 0xe1, 0x49, 0xd2, 0x93, 0xc6, + 0x92, 0x72, 0x9e, 0x61, 0xd1, 0x63, 0xfa, 0xee, 0xf4, 0x19, 0xd5, 0xad, 0x58, 0xa4, 0xbb, 0xa1, + 0xdc, 0xf2, 0x83, 0x37, 0x42, 0xe4, 0x7a, 0x32, 0x9c, 0xcc, 0xab, 0x4a, 0x8f, 0x6e, 0x04, 0x27, + 0x2e, 0xe7, 0xe2, 0x5a, 0x96, 0x16, 0x23, 0x2b, 0xc2, 0x65, 0x66, 0x0f, 0xbc, 0xa9, 0x47, 0x41, + 0x34, 0x48, 0xfc, 0xb7, 0x6a, 0x88, 0xa5, 0x53, 0x86, 0xf9, 0x5b, 0xdb, 0x38, 0x7b, 0xc3, 0x1e, + 0x22, 0x33, 0x24, 0x28, 0x36, 0xc7, 0xb2, 0x3b, 0x8e, 0x77, 0xba, 0xf5, 0x14, 0x9f, 0x08, 0x55, + 0x9b, 0x4c, 0xfe, 0x60, 0x5c, 0xda, 0x18, 0x46, 0xcd, 0x7d, 0x21, 0xb0, 0x3f, 0x1b, 0x89, 0xff, + 0xeb, 0x84, 0x69, 0x3a, 0x9d, 0xd7, 0xd3, 0x70, 0x67, 0x40, 0xb5, 0xde, 0x5d, 0x30, 0x91, 0xb1, + 0x78, 0x11, 0x01, 0xe5, 0x00, 0x68, 0x98, 0xa0, 0xc5, 0x02, 0xa6, 0x74, 0x2d, 0x0b, 0xa2, 0x76, + 0xb3, 0xbe, 0xce, 0xbd, 0xae, 0xe9, 0x8a, 0x31, 0x1c, 0xec, 0xf1, 0x99, 0x94, 0xaa, 0xf6, 0x26, + 0x2f, 0xef, 0xe8, 0x8c, 0x35, 0x03, 0xd4, 0x7f, 0xfb, 0x05, 0xc1, 0x5e, 0x90, 0x20, 0x3d, 0x82, + 0xf7, 0xea, 0x0a, 0x0d, 0x7e, 0xf8, 0x50, 0x1a, 0xc4, 0x07, 0x57, 0xb8, 0x3c, 0x62, 0xe3, 0xc8, + 0xac, 0x52, 0x64, 0x10, 0xd0, 0xd9, 0x13, 0x0c, 0x12, 0x29, 0x51, 0xb9, 0xcf, 0xd6, 0x73, 0x8d, + 0x81, 0x54, 0xc0, 0xed, 0x4e, 0x44, 0xa7, 0x2a, 0x85, 0x25, 0xe6, 0xca, 0x7c, 0x8b, 0x56, 0x80 + }; + + private static readonly byte[] S1 = new byte[]{ + 0xce, 0xbb, 0xeb, 0x92, 0xea, 0xcb, 0x13, 0xc1, 0xe9, 0x3a, 0xd6, 0xb2, 0xd2, 0x90, 0x17, 0xf8, + 0x42, 0x15, 0x56, 0xb4, 0x65, 0x1c, 0x88, 0x43, 0xc5, 0x5c, 0x36, 0xba, 0xf5, 0x57, 0x67, 0x8d, + 0x31, 0xf6, 0x64, 0x58, 0x9e, 0xf4, 0x22, 0xaa, 0x75, 0x0f, 0x02, 0xb1, 0xdf, 0x6d, 0x73, 0x4d, + 0x7c, 0x26, 0x2e, 0xf7, 0x08, 0x5d, 0x44, 0x3e, 0x9f, 0x14, 0xc8, 0xae, 0x54, 0x10, 0xd8, 0xbc, + 0x1a, 0x6b, 0x69, 0xf3, 0xbd, 0x33, 0xab, 0xfa, 0xd1, 0x9b, 0x68, 0x4e, 0x16, 0x95, 0x91, 0xee, + 0x4c, 0x63, 0x8e, 0x5b, 0xcc, 0x3c, 0x19, 0xa1, 0x81, 0x49, 0x7b, 0xd9, 0x6f, 0x37, 0x60, 0xca, + 0xe7, 0x2b, 0x48, 0xfd, 0x96, 0x45, 0xfc, 0x41, 0x12, 0x0d, 0x79, 0xe5, 0x89, 0x8c, 0xe3, 0x20, + 0x30, 0xdc, 0xb7, 0x6c, 0x4a, 0xb5, 0x3f, 0x97, 0xd4, 0x62, 0x2d, 0x06, 0xa4, 0xa5, 0x83, 0x5f, + 0x2a, 0xda, 0xc9, 0x00, 0x7e, 0xa2, 0x55, 0xbf, 0x11, 0xd5, 0x9c, 0xcf, 0x0e, 0x0a, 0x3d, 0x51, + 0x7d, 0x93, 0x1b, 0xfe, 0xc4, 0x47, 0x09, 0x86, 0x0b, 0x8f, 0x9d, 0x6a, 0x07, 0xb9, 0xb0, 0x98, + 0x18, 0x32, 0x71, 0x4b, 0xef, 0x3b, 0x70, 0xa0, 0xe4, 0x40, 0xff, 0xc3, 0xa9, 0xe6, 0x78, 0xf9, + 0x8b, 0x46, 0x80, 0x1e, 0x38, 0xe1, 0xb8, 0xa8, 0xe0, 0x0c, 0x23, 0x76, 0x1d, 0x25, 0x24, 0x05, + 0xf1, 0x6e, 0x94, 0x28, 0x9a, 0x84, 0xe8, 0xa3, 0x4f, 0x77, 0xd3, 0x85, 0xe2, 0x52, 0xf2, 0x82, + 0x50, 0x7a, 0x2f, 0x74, 0x53, 0xb3, 0x61, 0xaf, 0x39, 0x35, 0xde, 0xcd, 0x1f, 0x99, 0xac, 0xad, + 0x72, 0x2c, 0xdd, 0xd0, 0x87, 0xbe, 0x5e, 0xa6, 0xec, 0x04, 0xc6, 0x03, 0x34, 0xfb, 0xdb, 0x59, + 0xb6, 0xc2, 0x01, 0xf0, 0x5a, 0xed, 0xa7, 0x66, 0x21, 0x7f, 0x8a, 0x27, 0xc7, 0xc0, 0x29, 0xd7 + }; + + private static readonly byte[] S2 = new byte[]{ + 0x93, 0xd9, 0x9a, 0xb5, 0x98, 0x22, 0x45, 0xfc, 0xba, 0x6a, 0xdf, 0x02, 0x9f, 0xdc, 0x51, 0x59, + 0x4a, 0x17, 0x2b, 0xc2, 0x94, 0xf4, 0xbb, 0xa3, 0x62, 0xe4, 0x71, 0xd4, 0xcd, 0x70, 0x16, 0xe1, + 0x49, 0x3c, 0xc0, 0xd8, 0x5c, 0x9b, 0xad, 0x85, 0x53, 0xa1, 0x7a, 0xc8, 0x2d, 0xe0, 0xd1, 0x72, + 0xa6, 0x2c, 0xc4, 0xe3, 0x76, 0x78, 0xb7, 0xb4, 0x09, 0x3b, 0x0e, 0x41, 0x4c, 0xde, 0xb2, 0x90, + 0x25, 0xa5, 0xd7, 0x03, 0x11, 0x00, 0xc3, 0x2e, 0x92, 0xef, 0x4e, 0x12, 0x9d, 0x7d, 0xcb, 0x35, + 0x10, 0xd5, 0x4f, 0x9e, 0x4d, 0xa9, 0x55, 0xc6, 0xd0, 0x7b, 0x18, 0x97, 0xd3, 0x36, 0xe6, 0x48, + 0x56, 0x81, 0x8f, 0x77, 0xcc, 0x9c, 0xb9, 0xe2, 0xac, 0xb8, 0x2f, 0x15, 0xa4, 0x7c, 0xda, 0x38, + 0x1e, 0x0b, 0x05, 0xd6, 0x14, 0x6e, 0x6c, 0x7e, 0x66, 0xfd, 0xb1, 0xe5, 0x60, 0xaf, 0x5e, 0x33, + 0x87, 0xc9, 0xf0, 0x5d, 0x6d, 0x3f, 0x88, 0x8d, 0xc7, 0xf7, 0x1d, 0xe9, 0xec, 0xed, 0x80, 0x29, + 0x27, 0xcf, 0x99, 0xa8, 0x50, 0x0f, 0x37, 0x24, 0x28, 0x30, 0x95, 0xd2, 0x3e, 0x5b, 0x40, 0x83, + 0xb3, 0x69, 0x57, 0x1f, 0x07, 0x1c, 0x8a, 0xbc, 0x20, 0xeb, 0xce, 0x8e, 0xab, 0xee, 0x31, 0xa2, + 0x73, 0xf9, 0xca, 0x3a, 0x1a, 0xfb, 0x0d, 0xc1, 0xfe, 0xfa, 0xf2, 0x6f, 0xbd, 0x96, 0xdd, 0x43, + 0x52, 0xb6, 0x08, 0xf3, 0xae, 0xbe, 0x19, 0x89, 0x32, 0x26, 0xb0, 0xea, 0x4b, 0x64, 0x84, 0x82, + 0x6b, 0xf5, 0x79, 0xbf, 0x01, 0x5f, 0x75, 0x63, 0x1b, 0x23, 0x3d, 0x68, 0x2a, 0x65, 0xe8, 0x91, + 0xf6, 0xff, 0x13, 0x58, 0xf1, 0x47, 0x0a, 0x7f, 0xc5, 0xa7, 0xe7, 0x61, 0x5a, 0x06, 0x46, 0x44, + 0x42, 0x04, 0xa0, 0xdb, 0x39, 0x86, 0x54, 0xaa, 0x8c, 0x34, 0x21, 0x8b, 0xf8, 0x0c, 0x74, 0x67 + }; + + private static readonly byte[] S3 = new byte[]{ + 0x68, 0x8d, 0xca, 0x4d, 0x73, 0x4b, 0x4e, 0x2a, 0xd4, 0x52, 0x26, 0xb3, 0x54, 0x1e, 0x19, 0x1f, + 0x22, 0x03, 0x46, 0x3d, 0x2d, 0x4a, 0x53, 0x83, 0x13, 0x8a, 0xb7, 0xd5, 0x25, 0x79, 0xf5, 0xbd, + 0x58, 0x2f, 0x0d, 0x02, 0xed, 0x51, 0x9e, 0x11, 0xf2, 0x3e, 0x55, 0x5e, 0xd1, 0x16, 0x3c, 0x66, + 0x70, 0x5d, 0xf3, 0x45, 0x40, 0xcc, 0xe8, 0x94, 0x56, 0x08, 0xce, 0x1a, 0x3a, 0xd2, 0xe1, 0xdf, + 0xb5, 0x38, 0x6e, 0x0e, 0xe5, 0xf4, 0xf9, 0x86, 0xe9, 0x4f, 0xd6, 0x85, 0x23, 0xcf, 0x32, 0x99, + 0x31, 0x14, 0xae, 0xee, 0xc8, 0x48, 0xd3, 0x30, 0xa1, 0x92, 0x41, 0xb1, 0x18, 0xc4, 0x2c, 0x71, + 0x72, 0x44, 0x15, 0xfd, 0x37, 0xbe, 0x5f, 0xaa, 0x9b, 0x88, 0xd8, 0xab, 0x89, 0x9c, 0xfa, 0x60, + 0xea, 0xbc, 0x62, 0x0c, 0x24, 0xa6, 0xa8, 0xec, 0x67, 0x20, 0xdb, 0x7c, 0x28, 0xdd, 0xac, 0x5b, + 0x34, 0x7e, 0x10, 0xf1, 0x7b, 0x8f, 0x63, 0xa0, 0x05, 0x9a, 0x43, 0x77, 0x21, 0xbf, 0x27, 0x09, + 0xc3, 0x9f, 0xb6, 0xd7, 0x29, 0xc2, 0xeb, 0xc0, 0xa4, 0x8b, 0x8c, 0x1d, 0xfb, 0xff, 0xc1, 0xb2, + 0x97, 0x2e, 0xf8, 0x65, 0xf6, 0x75, 0x07, 0x04, 0x49, 0x33, 0xe4, 0xd9, 0xb9, 0xd0, 0x42, 0xc7, + 0x6c, 0x90, 0x00, 0x8e, 0x6f, 0x50, 0x01, 0xc5, 0xda, 0x47, 0x3f, 0xcd, 0x69, 0xa2, 0xe2, 0x7a, + 0xa7, 0xc6, 0x93, 0x0f, 0x0a, 0x06, 0xe6, 0x2b, 0x96, 0xa3, 0x1c, 0xaf, 0x6a, 0x12, 0x84, 0x39, + 0xe7, 0xb0, 0x82, 0xf7, 0xfe, 0x9d, 0x87, 0x5c, 0x81, 0x35, 0xde, 0xb4, 0xa5, 0xfc, 0x80, 0xef, + 0xcb, 0xbb, 0x6b, 0x76, 0xba, 0x5a, 0x7d, 0x78, 0x0b, 0x95, 0xe3, 0xad, 0x74, 0x98, 0x3b, 0x36, + 0x64, 0x6d, 0xdc, 0xf0, 0x59, 0xa9, 0x4c, 0x17, 0x7f, 0x91, 0xb8, 0xc9, 0x57, 0x1b, 0xe0, 0x61 + }; + + private static readonly byte[] T0 = new byte[]{ + 0xa4, 0xa2, 0xa9, 0xc5, 0x4e, 0xc9, 0x03, 0xd9, 0x7e, 0x0f, 0xd2, 0xad, 0xe7, 0xd3, 0x27, 0x5b, + 0xe3, 0xa1, 0xe8, 0xe6, 0x7c, 0x2a, 0x55, 0x0c, 0x86, 0x39, 0xd7, 0x8d, 0xb8, 0x12, 0x6f, 0x28, + 0xcd, 0x8a, 0x70, 0x56, 0x72, 0xf9, 0xbf, 0x4f, 0x73, 0xe9, 0xf7, 0x57, 0x16, 0xac, 0x50, 0xc0, + 0x9d, 0xb7, 0x47, 0x71, 0x60, 0xc4, 0x74, 0x43, 0x6c, 0x1f, 0x93, 0x77, 0xdc, 0xce, 0x20, 0x8c, + 0x99, 0x5f, 0x44, 0x01, 0xf5, 0x1e, 0x87, 0x5e, 0x61, 0x2c, 0x4b, 0x1d, 0x81, 0x15, 0xf4, 0x23, + 0xd6, 0xea, 0xe1, 0x67, 0xf1, 0x7f, 0xfe, 0xda, 0x3c, 0x07, 0x53, 0x6a, 0x84, 0x9c, 0xcb, 0x02, + 0x83, 0x33, 0xdd, 0x35, 0xe2, 0x59, 0x5a, 0x98, 0xa5, 0x92, 0x64, 0x04, 0x06, 0x10, 0x4d, 0x1c, + 0x97, 0x08, 0x31, 0xee, 0xab, 0x05, 0xaf, 0x79, 0xa0, 0x18, 0x46, 0x6d, 0xfc, 0x89, 0xd4, 0xc7, + 0xff, 0xf0, 0xcf, 0x42, 0x91, 0xf8, 0x68, 0x0a, 0x65, 0x8e, 0xb6, 0xfd, 0xc3, 0xef, 0x78, 0x4c, + 0xcc, 0x9e, 0x30, 0x2e, 0xbc, 0x0b, 0x54, 0x1a, 0xa6, 0xbb, 0x26, 0x80, 0x48, 0x94, 0x32, 0x7d, + 0xa7, 0x3f, 0xae, 0x22, 0x3d, 0x66, 0xaa, 0xf6, 0x00, 0x5d, 0xbd, 0x4a, 0xe0, 0x3b, 0xb4, 0x17, + 0x8b, 0x9f, 0x76, 0xb0, 0x24, 0x9a, 0x25, 0x63, 0xdb, 0xeb, 0x7a, 0x3e, 0x5c, 0xb3, 0xb1, 0x29, + 0xf2, 0xca, 0x58, 0x6e, 0xd8, 0xa8, 0x2f, 0x75, 0xdf, 0x14, 0xfb, 0x13, 0x49, 0x88, 0xb2, 0xec, + 0xe4, 0x34, 0x2d, 0x96, 0xc6, 0x3a, 0xed, 0x95, 0x0e, 0xe5, 0x85, 0x6b, 0x40, 0x21, 0x9b, 0x09, + 0x19, 0x2b, 0x52, 0xde, 0x45, 0xa3, 0xfa, 0x51, 0xc2, 0xb5, 0xd1, 0x90, 0xb9, 0xf3, 0x37, 0xc1, + 0x0d, 0xba, 0x41, 0x11, 0x38, 0x7b, 0xbe, 0xd0, 0xd5, 0x69, 0x36, 0xc8, 0x62, 0x1b, 0x82, 0x8f + }; + + private static readonly byte[] T1 = new byte[]{ + 0x83, 0xf2, 0x2a, 0xeb, 0xe9, 0xbf, 0x7b, 0x9c, 0x34, 0x96, 0x8d, 0x98, 0xb9, 0x69, 0x8c, 0x29, + 0x3d, 0x88, 0x68, 0x06, 0x39, 0x11, 0x4c, 0x0e, 0xa0, 0x56, 0x40, 0x92, 0x15, 0xbc, 0xb3, 0xdc, + 0x6f, 0xf8, 0x26, 0xba, 0xbe, 0xbd, 0x31, 0xfb, 0xc3, 0xfe, 0x80, 0x61, 0xe1, 0x7a, 0x32, 0xd2, + 0x70, 0x20, 0xa1, 0x45, 0xec, 0xd9, 0x1a, 0x5d, 0xb4, 0xd8, 0x09, 0xa5, 0x55, 0x8e, 0x37, 0x76, + 0xa9, 0x67, 0x10, 0x17, 0x36, 0x65, 0xb1, 0x95, 0x62, 0x59, 0x74, 0xa3, 0x50, 0x2f, 0x4b, 0xc8, + 0xd0, 0x8f, 0xcd, 0xd4, 0x3c, 0x86, 0x12, 0x1d, 0x23, 0xef, 0xf4, 0x53, 0x19, 0x35, 0xe6, 0x7f, + 0x5e, 0xd6, 0x79, 0x51, 0x22, 0x14, 0xf7, 0x1e, 0x4a, 0x42, 0x9b, 0x41, 0x73, 0x2d, 0xc1, 0x5c, + 0xa6, 0xa2, 0xe0, 0x2e, 0xd3, 0x28, 0xbb, 0xc9, 0xae, 0x6a, 0xd1, 0x5a, 0x30, 0x90, 0x84, 0xf9, + 0xb2, 0x58, 0xcf, 0x7e, 0xc5, 0xcb, 0x97, 0xe4, 0x16, 0x6c, 0xfa, 0xb0, 0x6d, 0x1f, 0x52, 0x99, + 0x0d, 0x4e, 0x03, 0x91, 0xc2, 0x4d, 0x64, 0x77, 0x9f, 0xdd, 0xc4, 0x49, 0x8a, 0x9a, 0x24, 0x38, + 0xa7, 0x57, 0x85, 0xc7, 0x7c, 0x7d, 0xe7, 0xf6, 0xb7, 0xac, 0x27, 0x46, 0xde, 0xdf, 0x3b, 0xd7, + 0x9e, 0x2b, 0x0b, 0xd5, 0x13, 0x75, 0xf0, 0x72, 0xb6, 0x9d, 0x1b, 0x01, 0x3f, 0x44, 0xe5, 0x87, + 0xfd, 0x07, 0xf1, 0xab, 0x94, 0x18, 0xea, 0xfc, 0x3a, 0x82, 0x5f, 0x05, 0x54, 0xdb, 0x00, 0x8b, + 0xe3, 0x48, 0x0c, 0xca, 0x78, 0x89, 0x0a, 0xff, 0x3e, 0x5b, 0x81, 0xee, 0x71, 0xe2, 0xda, 0x2c, + 0xb8, 0xb5, 0xcc, 0x6e, 0xa8, 0x6b, 0xad, 0x60, 0xc6, 0x08, 0x04, 0x02, 0xe8, 0xf5, 0x4f, 0xa4, + 0xf3, 0xc0, 0xce, 0x43, 0x25, 0x1c, 0x21, 0x33, 0x0f, 0xaf, 0x47, 0xed, 0x66, 0x63, 0x93, 0xaa + }; + + private static readonly byte[] T2 = new byte[]{ + 0x45, 0xd4, 0x0b, 0x43, 0xf1, 0x72, 0xed, 0xa4, 0xc2, 0x38, 0xe6, 0x71, 0xfd, 0xb6, 0x3a, 0x95, + 0x50, 0x44, 0x4b, 0xe2, 0x74, 0x6b, 0x1e, 0x11, 0x5a, 0xc6, 0xb4, 0xd8, 0xa5, 0x8a, 0x70, 0xa3, + 0xa8, 0xfa, 0x05, 0xd9, 0x97, 0x40, 0xc9, 0x90, 0x98, 0x8f, 0xdc, 0x12, 0x31, 0x2c, 0x47, 0x6a, + 0x99, 0xae, 0xc8, 0x7f, 0xf9, 0x4f, 0x5d, 0x96, 0x6f, 0xf4, 0xb3, 0x39, 0x21, 0xda, 0x9c, 0x85, + 0x9e, 0x3b, 0xf0, 0xbf, 0xef, 0x06, 0xee, 0xe5, 0x5f, 0x20, 0x10, 0xcc, 0x3c, 0x54, 0x4a, 0x52, + 0x94, 0x0e, 0xc0, 0x28, 0xf6, 0x56, 0x60, 0xa2, 0xe3, 0x0f, 0xec, 0x9d, 0x24, 0x83, 0x7e, 0xd5, + 0x7c, 0xeb, 0x18, 0xd7, 0xcd, 0xdd, 0x78, 0xff, 0xdb, 0xa1, 0x09, 0xd0, 0x76, 0x84, 0x75, 0xbb, + 0x1d, 0x1a, 0x2f, 0xb0, 0xfe, 0xd6, 0x34, 0x63, 0x35, 0xd2, 0x2a, 0x59, 0x6d, 0x4d, 0x77, 0xe7, + 0x8e, 0x61, 0xcf, 0x9f, 0xce, 0x27, 0xf5, 0x80, 0x86, 0xc7, 0xa6, 0xfb, 0xf8, 0x87, 0xab, 0x62, + 0x3f, 0xdf, 0x48, 0x00, 0x14, 0x9a, 0xbd, 0x5b, 0x04, 0x92, 0x02, 0x25, 0x65, 0x4c, 0x53, 0x0c, + 0xf2, 0x29, 0xaf, 0x17, 0x6c, 0x41, 0x30, 0xe9, 0x93, 0x55, 0xf7, 0xac, 0x68, 0x26, 0xc4, 0x7d, + 0xca, 0x7a, 0x3e, 0xa0, 0x37, 0x03, 0xc1, 0x36, 0x69, 0x66, 0x08, 0x16, 0xa7, 0xbc, 0xc5, 0xd3, + 0x22, 0xb7, 0x13, 0x46, 0x32, 0xe8, 0x57, 0x88, 0x2b, 0x81, 0xb2, 0x4e, 0x64, 0x1c, 0xaa, 0x91, + 0x58, 0x2e, 0x9b, 0x5c, 0x1b, 0x51, 0x73, 0x42, 0x23, 0x01, 0x6e, 0xf3, 0x0d, 0xbe, 0x3d, 0x0a, + 0x2d, 0x1f, 0x67, 0x33, 0x19, 0x7b, 0x5e, 0xea, 0xde, 0x8b, 0xcb, 0xa9, 0x8c, 0x8d, 0xad, 0x49, + 0x82, 0xe4, 0xba, 0xc3, 0x15, 0xd1, 0xe0, 0x89, 0xfc, 0xb1, 0xb9, 0xb5, 0x07, 0x79, 0xb8, 0xe1 + }; + + private static readonly byte[] T3 = new byte[]{ + 0xb2, 0xb6, 0x23, 0x11, 0xa7, 0x88, 0xc5, 0xa6, 0x39, 0x8f, 0xc4, 0xe8, 0x73, 0x22, 0x43, 0xc3, + 0x82, 0x27, 0xcd, 0x18, 0x51, 0x62, 0x2d, 0xf7, 0x5c, 0x0e, 0x3b, 0xfd, 0xca, 0x9b, 0x0d, 0x0f, + 0x79, 0x8c, 0x10, 0x4c, 0x74, 0x1c, 0x0a, 0x8e, 0x7c, 0x94, 0x07, 0xc7, 0x5e, 0x14, 0xa1, 0x21, + 0x57, 0x50, 0x4e, 0xa9, 0x80, 0xd9, 0xef, 0x64, 0x41, 0xcf, 0x3c, 0xee, 0x2e, 0x13, 0x29, 0xba, + 0x34, 0x5a, 0xae, 0x8a, 0x61, 0x33, 0x12, 0xb9, 0x55, 0xa8, 0x15, 0x05, 0xf6, 0x03, 0x06, 0x49, + 0xb5, 0x25, 0x09, 0x16, 0x0c, 0x2a, 0x38, 0xfc, 0x20, 0xf4, 0xe5, 0x7f, 0xd7, 0x31, 0x2b, 0x66, + 0x6f, 0xff, 0x72, 0x86, 0xf0, 0xa3, 0x2f, 0x78, 0x00, 0xbc, 0xcc, 0xe2, 0xb0, 0xf1, 0x42, 0xb4, + 0x30, 0x5f, 0x60, 0x04, 0xec, 0xa5, 0xe3, 0x8b, 0xe7, 0x1d, 0xbf, 0x84, 0x7b, 0xe6, 0x81, 0xf8, + 0xde, 0xd8, 0xd2, 0x17, 0xce, 0x4b, 0x47, 0xd6, 0x69, 0x6c, 0x19, 0x99, 0x9a, 0x01, 0xb3, 0x85, + 0xb1, 0xf9, 0x59, 0xc2, 0x37, 0xe9, 0xc8, 0xa0, 0xed, 0x4f, 0x89, 0x68, 0x6d, 0xd5, 0x26, 0x91, + 0x87, 0x58, 0xbd, 0xc9, 0x98, 0xdc, 0x75, 0xc0, 0x76, 0xf5, 0x67, 0x6b, 0x7e, 0xeb, 0x52, 0xcb, + 0xd1, 0x5b, 0x9f, 0x0b, 0xdb, 0x40, 0x92, 0x1a, 0xfa, 0xac, 0xe4, 0xe1, 0x71, 0x1f, 0x65, 0x8d, + 0x97, 0x9e, 0x95, 0x90, 0x5d, 0xb7, 0xc1, 0xaf, 0x54, 0xfb, 0x02, 0xe0, 0x35, 0xbb, 0x3a, 0x4d, + 0xad, 0x2c, 0x3d, 0x56, 0x08, 0x1b, 0x4a, 0x93, 0x6a, 0xab, 0xb8, 0x7a, 0xf2, 0x7d, 0xda, 0x3f, + 0xfe, 0x3e, 0xbe, 0xea, 0xaa, 0x44, 0xc6, 0xd0, 0x36, 0x48, 0x70, 0x96, 0x77, 0x24, 0x53, 0xdf, + 0xf3, 0x83, 0x28, 0x32, 0x45, 0x1e, 0xa4, 0xd3, 0xa2, 0x46, 0x6e, 0x9c, 0xdd, 0x63, 0xd4, 0x9d + }; + + #endregion + + public virtual string AlgorithmName + { + get { return "DSTU7624"; } + } + + public virtual int GetBlockSize() + { + return wordsInBlock << 3; + } + + public virtual bool IsPartialBlockOkay + { + get { return false; } + } + + public virtual void Reset() + { + Array.Clear(internalState, 0, internalState.Length); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/Dstu7624Engine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/Dstu7624Engine.cs.meta new file mode 100644 index 0000000..874269a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/Dstu7624Engine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ee7bcbf2f98ee61428d4d6d5b7ff4d1e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/Dstu7624WrapEngine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/Dstu7624WrapEngine.cs new file mode 100644 index 0000000..9cb9824 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/Dstu7624WrapEngine.cs @@ -0,0 +1,216 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + public class Dstu7624WrapEngine + : IWrapper + { + private KeyParameter param; + private Dstu7624Engine engine; + private bool forWrapping; + private int blockSize; + + public Dstu7624WrapEngine(int blockSizeBits) + { + engine = new Dstu7624Engine(blockSizeBits); + param = null; + + blockSize = blockSizeBits / 8; + } + + public string AlgorithmName + { + get { return "Dstu7624WrapEngine"; } + } + + public void Init(bool forWrapping, ICipherParameters parameters) + { + this.forWrapping = forWrapping; + + if (parameters is KeyParameter) + { + this.param = (KeyParameter)parameters; + + engine.Init(forWrapping, param); + } + else + { + throw new ArgumentException("Bad parameters passed to Dstu7624WrapEngine"); + } + } + + public byte[] Wrap(byte[] input, int inOff, int length) + { + if (!forWrapping) + throw new InvalidOperationException("Not set for wrapping"); + + if (length % blockSize != 0) + throw new ArgumentException("Padding not supported"); + + int n = 2 * (1 + length / blockSize); + int V = (n - 1) * 6; + + byte[] buffer = new byte[length + blockSize]; + Array.Copy(input, inOff, buffer, 0, length); + //Console.WriteLine(Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(buffer)); + + byte[] B = new byte[blockSize / 2]; + Array.Copy(buffer, 0, B, 0, blockSize / 2); + //Console.WriteLine("B0: "+ Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(B)); + + IList bTemp = Platform.CreateArrayList(); + int bHalfBlocksLen = buffer.Length - blockSize / 2; + int bufOff = blockSize / 2; + while (bHalfBlocksLen != 0) + { + byte[] temp = new byte[blockSize / 2]; + Array.Copy(buffer, bufOff, temp, 0, blockSize / 2); + //Console.WriteLine(Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(buffer)); + //Console.WriteLine(buffer.Length); + //Console.WriteLine("b: " + Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(temp)); + + bTemp.Add(temp); + + bHalfBlocksLen -= blockSize / 2; + bufOff += blockSize / 2; + } + + for (int j = 0; j < V; j++) + { + Array.Copy(B, 0, buffer, 0, blockSize / 2); + Array.Copy((byte[])bTemp[0], 0, buffer, blockSize / 2, blockSize / 2); + + engine.ProcessBlock(buffer, 0, buffer, 0); + + byte[] intArray = Pack.UInt32_To_LE((uint)(j + 1)); + for (int byteNum = 0; byteNum < intArray.Length; byteNum++) + { + buffer[byteNum + blockSize / 2] ^= intArray[byteNum]; + } + + Array.Copy(buffer, blockSize / 2, B, 0, blockSize / 2); + + for (int i = 2; i < n; i++) + { + Array.Copy((byte[])bTemp[i - 1], 0, (byte[])bTemp[i - 2], 0, blockSize / 2); + } + + Array.Copy(buffer, 0, (byte[])bTemp[n - 2], 0, blockSize / 2); + + //Console.WriteLine("B" + j.ToString() + ": " + Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(B)); + //Console.WriteLine("b: " + Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(bTemp[0])); + //Console.WriteLine("b: " + Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(bTemp[1])); + //Console.WriteLine("b: " + Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(bTemp[2])); + + //Console.WriteLine(Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(buffer)); + } + + Array.Copy(B, 0, buffer, 0, blockSize / 2); + bufOff = blockSize / 2; + + for (int i = 0; i < n - 1; i++) + { + Array.Copy((byte[])bTemp[i], 0, buffer, bufOff, blockSize / 2); + bufOff += blockSize / 2; + } + + return buffer; + } + + public byte[] Unwrap(byte[] input, int inOff, int length) + { + if (forWrapping) + throw new InvalidOperationException("not set for unwrapping"); + + if (length % blockSize != 0) + throw new ArgumentException("Padding not supported"); + + int n = 2 * length / blockSize; + int V = (n - 1) * 6; + + byte[] buffer = new byte[length]; + Array.Copy(input, inOff, buffer, 0, length); + + byte[] B = new byte[blockSize / 2]; + Array.Copy(buffer, 0, B, 0, blockSize / 2); + //Console.WriteLine("B18: " + Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(B)); + + IList bTemp = Platform.CreateArrayList(); + + int bHalfBlocksLen = buffer.Length - blockSize / 2; + int bufOff = blockSize / 2; + while (bHalfBlocksLen != 0) + { + byte[] temp = new byte[blockSize / 2]; + Array.Copy(buffer, bufOff, temp, 0, blockSize / 2); + //Console.WriteLine(Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(buffer)); + //Console.WriteLine(buffer.Length); + //Console.WriteLine("b: " + Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(temp)); + + bTemp.Add(temp); + + bHalfBlocksLen -= blockSize / 2; + bufOff += blockSize / 2; + } + + for (int j = 0; j < V; j++) + { + Array.Copy((byte[])bTemp[n - 2], 0, buffer, 0, blockSize / 2); + Array.Copy(B, 0, buffer, blockSize / 2, blockSize / 2); + + byte[] intArray = Pack.UInt32_To_LE((uint)(V - j)); + for (int byteNum = 0; byteNum < intArray.Length; byteNum++) + { + buffer[byteNum + blockSize / 2] ^= intArray[byteNum]; + } + + //Console.WriteLine(Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(buffer)); + + engine.ProcessBlock(buffer, 0, buffer, 0); + + //Console.WriteLine(Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(buffer)); + + Array.Copy(buffer, 0, B, 0, blockSize / 2); + + for (int i = 2; i < n; i++) + { + Array.Copy((byte[])bTemp[n - i - 1], 0, (byte[])bTemp[n - i], 0, blockSize / 2); + } + + Array.Copy(buffer, blockSize / 2, (byte[])bTemp[0], 0, blockSize / 2); + + //Console.WriteLine("B" + (V - j - 1).ToString() + ": " + Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(B)); + //Console.WriteLine("b: " + Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(bTemp[0])); + //Console.WriteLine("b: " + Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(bTemp[1])); + //Console.WriteLine("b: " + Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(bTemp[2])); + + //Console.WriteLine(Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(buffer)); + } + + Array.Copy(B, 0, buffer, 0, blockSize / 2); + bufOff = blockSize / 2; + + for (int i = 0; i < n - 1; i++) + { + Array.Copy((byte[])bTemp[i], 0, buffer, bufOff, blockSize / 2); + bufOff += blockSize / 2; + } + + byte diff = 0; + for (int i = buffer.Length - blockSize; i < buffer.Length; ++i) + { + diff |= buffer[i]; + } + + if (diff != 0) + throw new InvalidCipherTextException("checksum failed"); + + return Arrays.CopyOfRange(buffer, 0, buffer.Length - blockSize); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/Dstu7624WrapEngine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/Dstu7624WrapEngine.cs.meta new file mode 100644 index 0000000..f94ac5d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/Dstu7624WrapEngine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 70f87f04b5cc7544f9d84180dce8de85 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/ElGamalEngine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/ElGamalEngine.cs new file mode 100644 index 0000000..197d7bc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/ElGamalEngine.cs @@ -0,0 +1,178 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * this does your basic ElGamal algorithm. + */ + public class ElGamalEngine + : IAsymmetricBlockCipher + { + private ElGamalKeyParameters key; + private SecureRandom random; + private bool forEncryption; + private int bitSize; + + public virtual string AlgorithmName + { + get { return "ElGamal"; } + } + + /** + * initialise the ElGamal engine. + * + * @param forEncryption true if we are encrypting, false otherwise. + * @param param the necessary ElGamal key parameters. + */ + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (parameters is ParametersWithRandom) + { + ParametersWithRandom p = (ParametersWithRandom) parameters; + + this.key = (ElGamalKeyParameters) p.Parameters; + this.random = p.Random; + } + else + { + this.key = (ElGamalKeyParameters) parameters; + this.random = new SecureRandom(); + } + + this.forEncryption = forEncryption; + this.bitSize = key.Parameters.P.BitLength; + + if (forEncryption) + { + if (!(key is ElGamalPublicKeyParameters)) + { + throw new ArgumentException("ElGamalPublicKeyParameters are required for encryption."); + } + } + else + { + if (!(key is ElGamalPrivateKeyParameters)) + { + throw new ArgumentException("ElGamalPrivateKeyParameters are required for decryption."); + } + } + } + + /** + * Return the maximum size for an input block to this engine. + * For ElGamal this is always one byte less than the size of P on + * encryption, and twice the length as the size of P on decryption. + * + * @return maximum size for an input block. + */ + public virtual int GetInputBlockSize() + { + if (forEncryption) + { + return (bitSize - 1) / 8; + } + + return 2 * ((bitSize + 7) / 8); + } + + /** + * Return the maximum size for an output block to this engine. + * For ElGamal this is always one byte less than the size of P on + * decryption, and twice the length as the size of P on encryption. + * + * @return maximum size for an output block. + */ + public virtual int GetOutputBlockSize() + { + if (forEncryption) + { + return 2 * ((bitSize + 7) / 8); + } + + return (bitSize - 1) / 8; + } + + /** + * Process a single block using the basic ElGamal algorithm. + * + * @param in the input array. + * @param inOff the offset into the input buffer where the data starts. + * @param length the length of the data to be processed. + * @return the result of the ElGamal process. + * @exception DataLengthException the input block is too large. + */ + public virtual byte[] ProcessBlock( + byte[] input, + int inOff, + int length) + { + if (key == null) + throw new InvalidOperationException("ElGamal engine not initialised"); + + int maxLength = forEncryption + ? (bitSize - 1 + 7) / 8 + : GetInputBlockSize(); + + if (length > maxLength) + throw new DataLengthException("input too large for ElGamal cipher.\n"); + + BigInteger p = key.Parameters.P; + + byte[] output; + if (key is ElGamalPrivateKeyParameters) // decryption + { + int halfLength = length / 2; + BigInteger gamma = new BigInteger(1, input, inOff, halfLength); + BigInteger phi = new BigInteger(1, input, inOff + halfLength, halfLength); + + ElGamalPrivateKeyParameters priv = (ElGamalPrivateKeyParameters) key; + + // a shortcut, which generally relies on p being prime amongst other things. + // if a problem with this shows up, check the p and g values! + BigInteger m = gamma.ModPow(p.Subtract(BigInteger.One).Subtract(priv.X), p).Multiply(phi).Mod(p); + + output = m.ToByteArrayUnsigned(); + } + else // encryption + { + BigInteger tmp = new BigInteger(1, input, inOff, length); + + if (tmp.BitLength >= p.BitLength) + throw new DataLengthException("input too large for ElGamal cipher.\n"); + + + ElGamalPublicKeyParameters pub = (ElGamalPublicKeyParameters) key; + + BigInteger pSub2 = p.Subtract(BigInteger.Two); + + // TODO In theory, a series of 'k', 'g.ModPow(k, p)' and 'y.ModPow(k, p)' can be pre-calculated + BigInteger k; + do + { + k = new BigInteger(p.BitLength, random); + } + while (k.SignValue == 0 || k.CompareTo(pSub2) > 0); + + BigInteger g = key.Parameters.G; + BigInteger gamma = g.ModPow(k, p); + BigInteger phi = tmp.Multiply(pub.Y.ModPow(k, p)).Mod(p); + + output = new byte[this.GetOutputBlockSize()]; + + // TODO Add methods to allow writing BigInteger to existing byte array? + byte[] out1 = gamma.ToByteArrayUnsigned(); + byte[] out2 = phi.ToByteArrayUnsigned(); + out1.CopyTo(output, output.Length / 2 - out1.Length); + out2.CopyTo(output, output.Length - out2.Length); + } + + return output; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/ElGamalEngine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/ElGamalEngine.cs.meta new file mode 100644 index 0000000..31e7586 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/ElGamalEngine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: decaf5c68e6bd8845976d736c31e6f84 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/GOST28147Engine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/GOST28147Engine.cs new file mode 100644 index 0000000..acf0be2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/GOST28147Engine.cs @@ -0,0 +1,382 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * implementation of GOST 28147-89 + */ + public class Gost28147Engine + : IBlockCipher + { + private const int BlockSize = 8; + private int[] workingKey = null; + private bool forEncryption; + + private byte[] S = Sbox_Default; + + // these are the S-boxes given in Applied Cryptography 2nd Ed., p. 333 + // This is default S-box! + private static readonly byte[] Sbox_Default = { + 0x4,0xA,0x9,0x2,0xD,0x8,0x0,0xE,0x6,0xB,0x1,0xC,0x7,0xF,0x5,0x3, + 0xE,0xB,0x4,0xC,0x6,0xD,0xF,0xA,0x2,0x3,0x8,0x1,0x0,0x7,0x5,0x9, + 0x5,0x8,0x1,0xD,0xA,0x3,0x4,0x2,0xE,0xF,0xC,0x7,0x6,0x0,0x9,0xB, + 0x7,0xD,0xA,0x1,0x0,0x8,0x9,0xF,0xE,0x4,0x6,0xC,0xB,0x2,0x5,0x3, + 0x6,0xC,0x7,0x1,0x5,0xF,0xD,0x8,0x4,0xA,0x9,0xE,0x0,0x3,0xB,0x2, + 0x4,0xB,0xA,0x0,0x7,0x2,0x1,0xD,0x3,0x6,0x8,0x5,0x9,0xC,0xF,0xE, + 0xD,0xB,0x4,0x1,0x3,0xF,0x5,0x9,0x0,0xA,0xE,0x7,0x6,0x8,0x2,0xC, + 0x1,0xF,0xD,0x0,0x5,0x7,0xA,0x4,0x9,0x2,0x3,0xE,0x6,0xB,0x8,0xC + }; + + /* + * class content S-box parameters for encrypting + * getting from, see: http://tools.ietf.org/id/draft-popov-cryptopro-cpalgs-01.txt + * http://tools.ietf.org/id/draft-popov-cryptopro-cpalgs-02.txt + */ + private static readonly byte[] ESbox_Test = { + 0x4,0x2,0xF,0x5,0x9,0x1,0x0,0x8,0xE,0x3,0xB,0xC,0xD,0x7,0xA,0x6, + 0xC,0x9,0xF,0xE,0x8,0x1,0x3,0xA,0x2,0x7,0x4,0xD,0x6,0x0,0xB,0x5, + 0xD,0x8,0xE,0xC,0x7,0x3,0x9,0xA,0x1,0x5,0x2,0x4,0x6,0xF,0x0,0xB, + 0xE,0x9,0xB,0x2,0x5,0xF,0x7,0x1,0x0,0xD,0xC,0x6,0xA,0x4,0x3,0x8, + 0x3,0xE,0x5,0x9,0x6,0x8,0x0,0xD,0xA,0xB,0x7,0xC,0x2,0x1,0xF,0x4, + 0x8,0xF,0x6,0xB,0x1,0x9,0xC,0x5,0xD,0x3,0x7,0xA,0x0,0xE,0x2,0x4, + 0x9,0xB,0xC,0x0,0x3,0x6,0x7,0x5,0x4,0x8,0xE,0xF,0x1,0xA,0x2,0xD, + 0xC,0x6,0x5,0x2,0xB,0x0,0x9,0xD,0x3,0xE,0x7,0xA,0xF,0x4,0x1,0x8 + }; + + private static readonly byte[] ESbox_A = { + 0x9,0x6,0x3,0x2,0x8,0xB,0x1,0x7,0xA,0x4,0xE,0xF,0xC,0x0,0xD,0x5, + 0x3,0x7,0xE,0x9,0x8,0xA,0xF,0x0,0x5,0x2,0x6,0xC,0xB,0x4,0xD,0x1, + 0xE,0x4,0x6,0x2,0xB,0x3,0xD,0x8,0xC,0xF,0x5,0xA,0x0,0x7,0x1,0x9, + 0xE,0x7,0xA,0xC,0xD,0x1,0x3,0x9,0x0,0x2,0xB,0x4,0xF,0x8,0x5,0x6, + 0xB,0x5,0x1,0x9,0x8,0xD,0xF,0x0,0xE,0x4,0x2,0x3,0xC,0x7,0xA,0x6, + 0x3,0xA,0xD,0xC,0x1,0x2,0x0,0xB,0x7,0x5,0x9,0x4,0x8,0xF,0xE,0x6, + 0x1,0xD,0x2,0x9,0x7,0xA,0x6,0x0,0x8,0xC,0x4,0x5,0xF,0x3,0xB,0xE, + 0xB,0xA,0xF,0x5,0x0,0xC,0xE,0x8,0x6,0x2,0x3,0x9,0x1,0x7,0xD,0x4 + }; + + private static readonly byte[] ESbox_B = { + 0x8,0x4,0xB,0x1,0x3,0x5,0x0,0x9,0x2,0xE,0xA,0xC,0xD,0x6,0x7,0xF, + 0x0,0x1,0x2,0xA,0x4,0xD,0x5,0xC,0x9,0x7,0x3,0xF,0xB,0x8,0x6,0xE, + 0xE,0xC,0x0,0xA,0x9,0x2,0xD,0xB,0x7,0x5,0x8,0xF,0x3,0x6,0x1,0x4, + 0x7,0x5,0x0,0xD,0xB,0x6,0x1,0x2,0x3,0xA,0xC,0xF,0x4,0xE,0x9,0x8, + 0x2,0x7,0xC,0xF,0x9,0x5,0xA,0xB,0x1,0x4,0x0,0xD,0x6,0x8,0xE,0x3, + 0x8,0x3,0x2,0x6,0x4,0xD,0xE,0xB,0xC,0x1,0x7,0xF,0xA,0x0,0x9,0x5, + 0x5,0x2,0xA,0xB,0x9,0x1,0xC,0x3,0x7,0x4,0xD,0x0,0x6,0xF,0x8,0xE, + 0x0,0x4,0xB,0xE,0x8,0x3,0x7,0x1,0xA,0x2,0x9,0x6,0xF,0xD,0x5,0xC + }; + + private static readonly byte[] ESbox_C = { + 0x1,0xB,0xC,0x2,0x9,0xD,0x0,0xF,0x4,0x5,0x8,0xE,0xA,0x7,0x6,0x3, + 0x0,0x1,0x7,0xD,0xB,0x4,0x5,0x2,0x8,0xE,0xF,0xC,0x9,0xA,0x6,0x3, + 0x8,0x2,0x5,0x0,0x4,0x9,0xF,0xA,0x3,0x7,0xC,0xD,0x6,0xE,0x1,0xB, + 0x3,0x6,0x0,0x1,0x5,0xD,0xA,0x8,0xB,0x2,0x9,0x7,0xE,0xF,0xC,0x4, + 0x8,0xD,0xB,0x0,0x4,0x5,0x1,0x2,0x9,0x3,0xC,0xE,0x6,0xF,0xA,0x7, + 0xC,0x9,0xB,0x1,0x8,0xE,0x2,0x4,0x7,0x3,0x6,0x5,0xA,0x0,0xF,0xD, + 0xA,0x9,0x6,0x8,0xD,0xE,0x2,0x0,0xF,0x3,0x5,0xB,0x4,0x1,0xC,0x7, + 0x7,0x4,0x0,0x5,0xA,0x2,0xF,0xE,0xC,0x6,0x1,0xB,0xD,0x9,0x3,0x8 + }; + + private static readonly byte[] ESbox_D = { + 0xF,0xC,0x2,0xA,0x6,0x4,0x5,0x0,0x7,0x9,0xE,0xD,0x1,0xB,0x8,0x3, + 0xB,0x6,0x3,0x4,0xC,0xF,0xE,0x2,0x7,0xD,0x8,0x0,0x5,0xA,0x9,0x1, + 0x1,0xC,0xB,0x0,0xF,0xE,0x6,0x5,0xA,0xD,0x4,0x8,0x9,0x3,0x7,0x2, + 0x1,0x5,0xE,0xC,0xA,0x7,0x0,0xD,0x6,0x2,0xB,0x4,0x9,0x3,0xF,0x8, + 0x0,0xC,0x8,0x9,0xD,0x2,0xA,0xB,0x7,0x3,0x6,0x5,0x4,0xE,0xF,0x1, + 0x8,0x0,0xF,0x3,0x2,0x5,0xE,0xB,0x1,0xA,0x4,0x7,0xC,0x9,0xD,0x6, + 0x3,0x0,0x6,0xF,0x1,0xE,0x9,0x2,0xD,0x8,0xC,0x4,0xB,0xA,0x5,0x7, + 0x1,0xA,0x6,0x8,0xF,0xB,0x0,0x4,0xC,0x3,0x5,0x9,0x7,0xD,0x2,0xE + }; + + //S-box for digest + private static readonly byte[] DSbox_Test = { + 0x4,0xA,0x9,0x2,0xD,0x8,0x0,0xE,0x6,0xB,0x1,0xC,0x7,0xF,0x5,0x3, + 0xE,0xB,0x4,0xC,0x6,0xD,0xF,0xA,0x2,0x3,0x8,0x1,0x0,0x7,0x5,0x9, + 0x5,0x8,0x1,0xD,0xA,0x3,0x4,0x2,0xE,0xF,0xC,0x7,0x6,0x0,0x9,0xB, + 0x7,0xD,0xA,0x1,0x0,0x8,0x9,0xF,0xE,0x4,0x6,0xC,0xB,0x2,0x5,0x3, + 0x6,0xC,0x7,0x1,0x5,0xF,0xD,0x8,0x4,0xA,0x9,0xE,0x0,0x3,0xB,0x2, + 0x4,0xB,0xA,0x0,0x7,0x2,0x1,0xD,0x3,0x6,0x8,0x5,0x9,0xC,0xF,0xE, + 0xD,0xB,0x4,0x1,0x3,0xF,0x5,0x9,0x0,0xA,0xE,0x7,0x6,0x8,0x2,0xC, + 0x1,0xF,0xD,0x0,0x5,0x7,0xA,0x4,0x9,0x2,0x3,0xE,0x6,0xB,0x8,0xC + }; + + private static readonly byte[] DSbox_A = { + 0xA,0x4,0x5,0x6,0x8,0x1,0x3,0x7,0xD,0xC,0xE,0x0,0x9,0x2,0xB,0xF, + 0x5,0xF,0x4,0x0,0x2,0xD,0xB,0x9,0x1,0x7,0x6,0x3,0xC,0xE,0xA,0x8, + 0x7,0xF,0xC,0xE,0x9,0x4,0x1,0x0,0x3,0xB,0x5,0x2,0x6,0xA,0x8,0xD, + 0x4,0xA,0x7,0xC,0x0,0xF,0x2,0x8,0xE,0x1,0x6,0x5,0xD,0xB,0x9,0x3, + 0x7,0x6,0x4,0xB,0x9,0xC,0x2,0xA,0x1,0x8,0x0,0xE,0xF,0xD,0x3,0x5, + 0x7,0x6,0x2,0x4,0xD,0x9,0xF,0x0,0xA,0x1,0x5,0xB,0x8,0xE,0xC,0x3, + 0xD,0xE,0x4,0x1,0x7,0x0,0x5,0xA,0x3,0xC,0x8,0xF,0x6,0x2,0x9,0xB, + 0x1,0x3,0xA,0x9,0x5,0xB,0x4,0xF,0x8,0x6,0x7,0xE,0xD,0x0,0x2,0xC + }; + + // + // pre-defined sbox table + // + private static readonly IDictionary sBoxes = Platform.CreateHashtable(); + + static Gost28147Engine() + { + AddSBox("Default", Sbox_Default); + AddSBox("E-TEST", ESbox_Test); + AddSBox("E-A", ESbox_A); + AddSBox("E-B", ESbox_B); + AddSBox("E-C", ESbox_C); + AddSBox("E-D", ESbox_D); + AddSBox("D-TEST", DSbox_Test); + AddSBox("D-A", DSbox_A); + } + + private static void AddSBox(string sBoxName, byte[] sBox) + { + sBoxes.Add(Platform.ToUpperInvariant(sBoxName), sBox); + } + + /** + * standard constructor. + */ + public Gost28147Engine() + { + } + + /** + * initialise an Gost28147 cipher. + * + * @param forEncryption whether or not we are for encryption. + * @param parameters the parameters required to set up the cipher. + * @exception ArgumentException if the parameters argument is inappropriate. + */ + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (parameters is ParametersWithSBox) + { + ParametersWithSBox param = (ParametersWithSBox)parameters; + + // + // Set the S-Box + // + byte[] sBox = param.GetSBox(); + if (sBox.Length != Sbox_Default.Length) + throw new ArgumentException("invalid S-box passed to GOST28147 init"); + + this.S = Arrays.Clone(sBox); + + // + // set key if there is one + // + if (param.Parameters != null) + { + workingKey = generateWorkingKey(forEncryption, + ((KeyParameter)param.Parameters).GetKey()); + } + } + else if (parameters is KeyParameter) + { + workingKey = generateWorkingKey(forEncryption, + ((KeyParameter)parameters).GetKey()); + } + else if (parameters != null) + { + throw new ArgumentException("invalid parameter passed to Gost28147 init - " + + Platform.GetTypeName(parameters)); + } + } + + public virtual string AlgorithmName + { + get { return "Gost28147"; } + } + + public virtual bool IsPartialBlockOkay + { + get { return false; } + } + + public virtual int GetBlockSize() + { + return BlockSize; + } + + public virtual int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + if (workingKey == null) + throw new InvalidOperationException("Gost28147 engine not initialised"); + + Check.DataLength(input, inOff, BlockSize, "input buffer too short"); + Check.OutputLength(output, outOff, BlockSize, "output buffer too short"); + + Gost28147Func(workingKey, input, inOff, output, outOff); + + return BlockSize; + } + + public virtual void Reset() + { + } + + private int[] generateWorkingKey( + bool forEncryption, + byte[] userKey) + { + this.forEncryption = forEncryption; + + if (userKey.Length != 32) + { + throw new ArgumentException("Key length invalid. Key needs to be 32 byte - 256 bit!!!"); + } + + int[] key = new int[8]; + for(int i=0; i!=8; i++) + { + key[i] = bytesToint(userKey,i*4); + } + + return key; + } + + private int Gost28147_mainStep(int n1, int key) + { + int cm = (key + n1); // CM1 + + // S-box replacing + + int om = S[ 0 + ((cm >> (0 * 4)) & 0xF)] << (0 * 4); + om += S[ 16 + ((cm >> (1 * 4)) & 0xF)] << (1 * 4); + om += S[ 32 + ((cm >> (2 * 4)) & 0xF)] << (2 * 4); + om += S[ 48 + ((cm >> (3 * 4)) & 0xF)] << (3 * 4); + om += S[ 64 + ((cm >> (4 * 4)) & 0xF)] << (4 * 4); + om += S[ 80 + ((cm >> (5 * 4)) & 0xF)] << (5 * 4); + om += S[ 96 + ((cm >> (6 * 4)) & 0xF)] << (6 * 4); + om += S[112 + ((cm >> (7 * 4)) & 0xF)] << (7 * 4); + +// return om << 11 | om >>> (32-11); // 11-leftshift + int omLeft = om << 11; + int omRight = (int)(((uint) om) >> (32 - 11)); // Note: Casts required to get unsigned bit rotation + + return omLeft | omRight; + } + + private void Gost28147Func( + int[] workingKey, + byte[] inBytes, + int inOff, + byte[] outBytes, + int outOff) + { + int N1, N2, tmp; //tmp -> for saving N1 + N1 = bytesToint(inBytes, inOff); + N2 = bytesToint(inBytes, inOff + 4); + + if (this.forEncryption) + { + for(int k = 0; k < 3; k++) // 1-24 steps + { + for(int j = 0; j < 8; j++) + { + tmp = N1; + int step = Gost28147_mainStep(N1, workingKey[j]); + N1 = N2 ^ step; // CM2 + N2 = tmp; + } + } + for(int j = 7; j > 0; j--) // 25-31 steps + { + tmp = N1; + N1 = N2 ^ Gost28147_mainStep(N1, workingKey[j]); // CM2 + N2 = tmp; + } + } + else //decrypt + { + for(int j = 0; j < 8; j++) // 1-8 steps + { + tmp = N1; + N1 = N2 ^ Gost28147_mainStep(N1, workingKey[j]); // CM2 + N2 = tmp; + } + for(int k = 0; k < 3; k++) //9-31 steps + { + for(int j = 7; j >= 0; j--) + { + if ((k == 2) && (j==0)) + { + break; // break 32 step + } + tmp = N1; + N1 = N2 ^ Gost28147_mainStep(N1, workingKey[j]); // CM2 + N2 = tmp; + } + } + } + + N2 = N2 ^ Gost28147_mainStep(N1, workingKey[0]); // 32 step (N1=N1) + + intTobytes(N1, outBytes, outOff); + intTobytes(N2, outBytes, outOff + 4); + } + + //array of bytes to type int + private static int bytesToint( + byte[] inBytes, + int inOff) + { + return (int)((inBytes[inOff + 3] << 24) & 0xff000000) + ((inBytes[inOff + 2] << 16) & 0xff0000) + + ((inBytes[inOff + 1] << 8) & 0xff00) + (inBytes[inOff] & 0xff); + } + + //int to array of bytes + private static void intTobytes( + int num, + byte[] outBytes, + int outOff) + { + outBytes[outOff + 3] = (byte)(num >> 24); + outBytes[outOff + 2] = (byte)(num >> 16); + outBytes[outOff + 1] = (byte)(num >> 8); + outBytes[outOff] = (byte)num; + } + + /** + * Return the S-Box associated with SBoxName + * @param sBoxName name of the S-Box + * @return byte array representing the S-Box + */ + public static byte[] GetSBox( + string sBoxName) + { + byte[] sBox = (byte[])sBoxes[Platform.ToUpperInvariant(sBoxName)]; + + if (sBox == null) + { + throw new ArgumentException("Unknown S-Box - possible types: " + + "\"Default\", \"E-Test\", \"E-A\", \"E-B\", \"E-C\", \"E-D\", \"D-Test\", \"D-A\"."); + } + + return Arrays.Clone(sBox); + } + + public static string GetSBoxName(byte[] sBox) + { + foreach (string name in sBoxes.Keys) + { + byte[] sb = (byte[])sBoxes[name]; + if (Arrays.AreEqual(sb, sBox)) + { + return name; + } + } + + throw new ArgumentException("SBOX provided did not map to a known one"); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/GOST28147Engine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/GOST28147Engine.cs.meta new file mode 100644 index 0000000..70a7ae1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/GOST28147Engine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: befb2b0f66759cd4ab94ae6ae7134b00 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/HC128Engine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/HC128Engine.cs new file mode 100644 index 0000000..b83eb70 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/HC128Engine.cs @@ -0,0 +1,235 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * HC-128 is a software-efficient stream cipher created by Hongjun Wu. It + * generates keystream from a 128-bit secret key and a 128-bit initialization + * vector. + *

+ * http://www.ecrypt.eu.org/stream/p3ciphers/hc/hc128_p3.pdf + *

+ * It is a third phase candidate in the eStream contest, and is patent-free. + * No attacks are known as of today (April 2007). See + * + * http://www.ecrypt.eu.org/stream/hcp3.html + *

+ */ + public class HC128Engine + : IStreamCipher + { + private uint[] p = new uint[512]; + private uint[] q = new uint[512]; + private uint cnt = 0; + + private static uint F1(uint x) + { + return RotateRight(x, 7) ^ RotateRight(x, 18) ^ (x >> 3); + } + + private static uint F2(uint x) + { + return RotateRight(x, 17) ^ RotateRight(x, 19) ^ (x >> 10); + } + + private uint G1(uint x, uint y, uint z) + { + return (RotateRight(x, 10) ^ RotateRight(z, 23)) + RotateRight(y, 8); + } + + private uint G2(uint x, uint y, uint z) + { + return (RotateLeft(x, 10) ^ RotateLeft(z, 23)) + RotateLeft(y, 8); + } + + private static uint RotateLeft(uint x, int bits) + { + return (x << bits) | (x >> -bits); + } + + private static uint RotateRight(uint x, int bits) + { + return (x >> bits) | (x << -bits); + } + + private uint H1(uint x) + { + return q[x & 0xFF] + q[((x >> 16) & 0xFF) + 256]; + } + + private uint H2(uint x) + { + return p[x & 0xFF] + p[((x >> 16) & 0xFF) + 256]; + } + + private static uint Mod1024(uint x) + { + return x & 0x3FF; + } + + private static uint Mod512(uint x) + { + return x & 0x1FF; + } + + private static uint Dim(uint x, uint y) + { + return Mod512(x - y); + } + + private uint Step() + { + uint j = Mod512(cnt); + uint ret; + if (cnt < 512) + { + p[j] += G1(p[Dim(j, 3)], p[Dim(j, 10)], p[Dim(j, 511)]); + ret = H1(p[Dim(j, 12)]) ^ p[j]; + } + else + { + q[j] += G2(q[Dim(j, 3)], q[Dim(j, 10)], q[Dim(j, 511)]); + ret = H2(q[Dim(j, 12)]) ^ q[j]; + } + cnt = Mod1024(cnt + 1); + return ret; + } + + private byte[] key, iv; + private bool initialised; + + private void Init() + { + if (key.Length != 16) + throw new ArgumentException("The key must be 128 bits long"); + + idx = 0; + cnt = 0; + + uint[] w = new uint[1280]; + + for (int i = 0; i < 16; i++) + { + w[i >> 2] |= ((uint)key[i] << (8 * (i & 0x3))); + } + Array.Copy(w, 0, w, 4, 4); + + for (int i = 0; i < iv.Length && i < 16; i++) + { + w[(i >> 2) + 8] |= ((uint)iv[i] << (8 * (i & 0x3))); + } + Array.Copy(w, 8, w, 12, 4); + + for (uint i = 16; i < 1280; i++) + { + w[i] = F2(w[i - 2]) + w[i - 7] + F1(w[i - 15]) + w[i - 16] + i; + } + + Array.Copy(w, 256, p, 0, 512); + Array.Copy(w, 768, q, 0, 512); + + for (int i = 0; i < 512; i++) + { + p[i] = Step(); + } + for (int i = 0; i < 512; i++) + { + q[i] = Step(); + } + + cnt = 0; + } + + public virtual string AlgorithmName + { + get { return "HC-128"; } + } + + /** + * Initialise a HC-128 cipher. + * + * @param forEncryption whether or not we are for encryption. Irrelevant, as + * encryption and decryption are the same. + * @param params the parameters required to set up the cipher. + * @throws ArgumentException if the params argument is + * inappropriate (ie. the key is not 128 bit long). + */ + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + ICipherParameters keyParam = parameters; + + if (parameters is ParametersWithIV) + { + iv = ((ParametersWithIV)parameters).GetIV(); + keyParam = ((ParametersWithIV)parameters).Parameters; + } + else + { + iv = new byte[0]; + } + + if (keyParam is KeyParameter) + { + key = ((KeyParameter)keyParam).GetKey(); + Init(); + } + else + { + throw new ArgumentException( + "Invalid parameter passed to HC128 init - " + Platform.GetTypeName(parameters), + "parameters"); + } + + initialised = true; + } + + private byte[] buf = new byte[4]; + private int idx = 0; + + private byte GetByte() + { + if (idx == 0) + { + Pack.UInt32_To_LE(Step(), buf); + } + byte ret = buf[idx]; + idx = idx + 1 & 0x3; + return ret; + } + + public virtual void ProcessBytes( + byte[] input, + int inOff, + int len, + byte[] output, + int outOff) + { + if (!initialised) + throw new InvalidOperationException(AlgorithmName + " not initialised"); + + Check.DataLength(input, inOff, len, "input buffer too short"); + Check.OutputLength(output, outOff, len, "output buffer too short"); + + for (int i = 0; i < len; i++) + { + output[outOff + i] = (byte)(input[inOff + i] ^ GetByte()); + } + } + + public virtual void Reset() + { + Init(); + } + + public virtual byte ReturnByte(byte input) + { + return (byte)(input ^ GetByte()); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/HC128Engine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/HC128Engine.cs.meta new file mode 100644 index 0000000..ea0b9e7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/HC128Engine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cf0b8081a45e1ba49bdad419c5af0ed1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/HC256Engine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/HC256Engine.cs new file mode 100644 index 0000000..d8d83a6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/HC256Engine.cs @@ -0,0 +1,224 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * HC-256 is a software-efficient stream cipher created by Hongjun Wu. It + * generates keystream from a 256-bit secret key and a 256-bit initialization + * vector. + *

+ * http://www.ecrypt.eu.org/stream/p3ciphers/hc/hc256_p3.pdf + *

+ * Its brother, HC-128, is a third phase candidate in the eStream contest. + * The algorithm is patent-free. No attacks are known as of today (April 2007). + * See + * + * http://www.ecrypt.eu.org/stream/hcp3.html + *

+ */ + public class HC256Engine + : IStreamCipher + { + private uint[] p = new uint[1024]; + private uint[] q = new uint[1024]; + private uint cnt = 0; + + private uint Step() + { + uint j = cnt & 0x3FF; + uint ret; + if (cnt < 1024) + { + uint x = p[(j - 3 & 0x3FF)]; + uint y = p[(j - 1023 & 0x3FF)]; + p[j] += p[(j - 10 & 0x3FF)] + + (RotateRight(x, 10) ^ RotateRight(y, 23)) + + q[((x ^ y) & 0x3FF)]; + + x = p[(j - 12 & 0x3FF)]; + ret = (q[x & 0xFF] + q[((x >> 8) & 0xFF) + 256] + + q[((x >> 16) & 0xFF) + 512] + q[((x >> 24) & 0xFF) + 768]) + ^ p[j]; + } + else + { + uint x = q[(j - 3 & 0x3FF)]; + uint y = q[(j - 1023 & 0x3FF)]; + q[j] += q[(j - 10 & 0x3FF)] + + (RotateRight(x, 10) ^ RotateRight(y, 23)) + + p[((x ^ y) & 0x3FF)]; + + x = q[(j - 12 & 0x3FF)]; + ret = (p[x & 0xFF] + p[((x >> 8) & 0xFF) + 256] + + p[((x >> 16) & 0xFF) + 512] + p[((x >> 24) & 0xFF) + 768]) + ^ q[j]; + } + cnt = cnt + 1 & 0x7FF; + return ret; + } + + private byte[] key, iv; + private bool initialised; + + private void Init() + { + if (key.Length != 32 && key.Length != 16) + throw new ArgumentException("The key must be 128/256 bits long"); + + if (iv.Length < 16) + throw new ArgumentException("The IV must be at least 128 bits long"); + + if (key.Length != 32) + { + byte[] k = new byte[32]; + + Array.Copy(key, 0, k, 0, key.Length); + Array.Copy(key, 0, k, 16, key.Length); + + key = k; + } + + if (iv.Length < 32) + { + byte[] newIV = new byte[32]; + + Array.Copy(iv, 0, newIV, 0, iv.Length); + Array.Copy(iv, 0, newIV, iv.Length, newIV.Length - iv.Length); + + iv = newIV; + } + + idx = 0; + cnt = 0; + + uint[] w = new uint[2560]; + + for (int i = 0; i < 32; i++) + { + w[i >> 2] |= ((uint)key[i] << (8 * (i & 0x3))); + } + + for (int i = 0; i < 32; i++) + { + w[(i >> 2) + 8] |= ((uint)iv[i] << (8 * (i & 0x3))); + } + + for (uint i = 16; i < 2560; i++) + { + uint x = w[i - 2]; + uint y = w[i - 15]; + w[i] = (RotateRight(x, 17) ^ RotateRight(x, 19) ^ (x >> 10)) + + w[i - 7] + + (RotateRight(y, 7) ^ RotateRight(y, 18) ^ (y >> 3)) + + w[i - 16] + i; + } + + Array.Copy(w, 512, p, 0, 1024); + Array.Copy(w, 1536, q, 0, 1024); + + for (int i = 0; i < 4096; i++) + { + Step(); + } + + cnt = 0; + } + + public virtual string AlgorithmName + { + get { return "HC-256"; } + } + + /** + * Initialise a HC-256 cipher. + * + * @param forEncryption whether or not we are for encryption. Irrelevant, as + * encryption and decryption are the same. + * @param params the parameters required to set up the cipher. + * @throws ArgumentException if the params argument is + * inappropriate (ie. the key is not 256 bit long). + */ + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + ICipherParameters keyParam = parameters; + + if (parameters is ParametersWithIV) + { + iv = ((ParametersWithIV)parameters).GetIV(); + keyParam = ((ParametersWithIV)parameters).Parameters; + } + else + { + iv = new byte[0]; + } + + if (keyParam is KeyParameter) + { + key = ((KeyParameter)keyParam).GetKey(); + Init(); + } + else + { + throw new ArgumentException( + "Invalid parameter passed to HC256 init - " + Platform.GetTypeName(parameters), + "parameters"); + } + + initialised = true; + } + + private byte[] buf = new byte[4]; + private int idx = 0; + + private byte GetByte() + { + if (idx == 0) + { + Pack.UInt32_To_LE(Step(), buf); + } + byte ret = buf[idx]; + idx = idx + 1 & 0x3; + return ret; + } + + public virtual void ProcessBytes( + byte[] input, + int inOff, + int len, + byte[] output, + int outOff) + { + if (!initialised) + throw new InvalidOperationException(AlgorithmName + " not initialised"); + + Check.DataLength(input, inOff, len, "input buffer too short"); + Check.OutputLength(output, outOff, len, "output buffer too short"); + + for (int i = 0; i < len; i++) + { + output[outOff + i] = (byte)(input[inOff + i] ^ GetByte()); + } + } + + public virtual void Reset() + { + Init(); + } + + public virtual byte ReturnByte(byte input) + { + return (byte)(input ^ GetByte()); + } + + private static uint RotateRight(uint x, int bits) + { + return (x >> bits) | (x << -bits); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/HC256Engine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/HC256Engine.cs.meta new file mode 100644 index 0000000..5b9cfb4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/HC256Engine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 20311bf4c51987d4c9524cc8dd098fb2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/ISAACEngine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/ISAACEngine.cs new file mode 100644 index 0000000..b94ee6e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/ISAACEngine.cs @@ -0,0 +1,212 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * Implementation of Bob Jenkin's ISAAC (Indirection Shift Accumulate Add and Count). + * see: http://www.burtleburtle.net/bob/rand/isaacafa.html + */ + public class IsaacEngine + : IStreamCipher + { + // Constants + private static readonly int sizeL = 8, + stateArraySize = sizeL<<5; // 256 + + // Cipher's internal state + private uint[] engineState = null, // mm + results = null; // randrsl + private uint a = 0, b = 0, c = 0; + + // Engine state + private int index = 0; + private byte[] keyStream = new byte[stateArraySize<<2], // results expanded into bytes + workingKey = null; + private bool initialised = false; + + /** + * initialise an ISAAC cipher. + * + * @param forEncryption whether or not we are for encryption. + * @param params the parameters required to set up the cipher. + * @exception ArgumentException if the params argument is + * inappropriate. + */ + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (!(parameters is KeyParameter)) + throw new ArgumentException( + "invalid parameter passed to ISAAC Init - " + Platform.GetTypeName(parameters), + "parameters"); + + /* + * ISAAC encryption and decryption is completely + * symmetrical, so the 'forEncryption' is + * irrelevant. + */ + KeyParameter p = (KeyParameter) parameters; + setKey(p.GetKey()); + } + + public virtual byte ReturnByte( + byte input) + { + if (index == 0) + { + isaac(); + keyStream = Pack.UInt32_To_BE(results); + } + + byte output = (byte)(keyStream[index]^input); + index = (index + 1) & 1023; + + return output; + } + + public virtual void ProcessBytes( + byte[] input, + int inOff, + int len, + byte[] output, + int outOff) + { + if (!initialised) + throw new InvalidOperationException(AlgorithmName + " not initialised"); + + Check.DataLength(input, inOff, len, "input buffer too short"); + Check.OutputLength(output, outOff, len, "output buffer too short"); + + for (int i = 0; i < len; i++) + { + if (index == 0) + { + isaac(); + keyStream = Pack.UInt32_To_BE(results); + } + output[i+outOff] = (byte)(keyStream[index]^input[i+inOff]); + index = (index + 1) & 1023; + } + } + + public virtual string AlgorithmName + { + get { return "ISAAC"; } + } + + public virtual void Reset() + { + setKey(workingKey); + } + + // Private implementation + private void setKey( + byte[] keyBytes) + { + workingKey = keyBytes; + + if (engineState == null) + { + engineState = new uint[stateArraySize]; + } + + if (results == null) + { + results = new uint[stateArraySize]; + } + + int i, j, k; + + // Reset state + for (i = 0; i < stateArraySize; i++) + { + engineState[i] = results[i] = 0; + } + a = b = c = 0; + + // Reset index counter for output + index = 0; + + // Convert the key bytes to ints and put them into results[] for initialization + byte[] t = new byte[keyBytes.Length + (keyBytes.Length & 3)]; + Array.Copy(keyBytes, 0, t, 0, keyBytes.Length); + for (i = 0; i < t.Length; i+=4) + { + results[i >> 2] = Pack.LE_To_UInt32(t, i); + } + + // It has begun? + uint[] abcdefgh = new uint[sizeL]; + + for (i = 0; i < sizeL; i++) + { + abcdefgh[i] = 0x9e3779b9; // Phi (golden ratio) + } + + for (i = 0; i < 4; i++) + { + mix(abcdefgh); + } + + for (i = 0; i < 2; i++) + { + for (j = 0; j < stateArraySize; j+=sizeL) + { + for (k = 0; k < sizeL; k++) + { + abcdefgh[k] += (i<1) ? results[j+k] : engineState[j+k]; + } + + mix(abcdefgh); + + for (k = 0; k < sizeL; k++) + { + engineState[j+k] = abcdefgh[k]; + } + } + } + + isaac(); + + initialised = true; + } + + private void isaac() + { + uint x, y; + + b += ++c; + for (int i = 0; i < stateArraySize; i++) + { + x = engineState[i]; + switch (i & 3) + { + case 0: a ^= (a << 13); break; + case 1: a ^= (a >> 6); break; + case 2: a ^= (a << 2); break; + case 3: a ^= (a >> 16); break; + } + a += engineState[(i+128) & 0xFF]; + engineState[i] = y = engineState[(int)((uint)x >> 2) & 0xFF] + a + b; + results[i] = b = engineState[(int)((uint)y >> 10) & 0xFF] + x; + } + } + + private void mix(uint[] x) + { + x[0]^=x[1]<< 11; x[3]+=x[0]; x[1]+=x[2]; + x[1]^=x[2]>> 2; x[4]+=x[1]; x[2]+=x[3]; + x[2]^=x[3]<< 8; x[5]+=x[2]; x[3]+=x[4]; + x[3]^=x[4]>> 16; x[6]+=x[3]; x[4]+=x[5]; + x[4]^=x[5]<< 10; x[7]+=x[4]; x[5]+=x[6]; + x[5]^=x[6]>> 4; x[0]+=x[5]; x[6]+=x[7]; + x[6]^=x[7]<< 8; x[1]+=x[6]; x[7]+=x[0]; + x[7]^=x[0]>> 9; x[2]+=x[7]; x[0]+=x[1]; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/ISAACEngine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/ISAACEngine.cs.meta new file mode 100644 index 0000000..7c4b26c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/ISAACEngine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 83978ed600fa0ba41a8f8f374142184b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/IdeaEngine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/IdeaEngine.cs new file mode 100644 index 0000000..6c03791 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/IdeaEngine.cs @@ -0,0 +1,322 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * A class that provides a basic International Data Encryption Algorithm (IDEA) engine. + *

+ * This implementation is based on the "HOWTO: INTERNATIONAL DATA ENCRYPTION ALGORITHM" + * implementation summary by Fauzan Mirza (F.U.Mirza@sheffield.ac.uk). (barring 1 typo at the + * end of the MulInv function!). + *

+ *

+ * It can be found at ftp://ftp.funet.fi/pub/crypt/cryptography/symmetric/idea/ + *

+ *

+ * Note: This algorithm was patented in the USA, Japan and Europe. These patents expired in 2011/2012. + *

+ */ + public class IdeaEngine + : IBlockCipher + { + private const int BLOCK_SIZE = 8; + private int[] workingKey; + /** + * standard constructor. + */ + public IdeaEngine() + { + } + /** + * initialise an IDEA cipher. + * + * @param forEncryption whether or not we are for encryption. + * @param parameters the parameters required to set up the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (!(parameters is KeyParameter)) + throw new ArgumentException("invalid parameter passed to IDEA init - " + Platform.GetTypeName(parameters)); + + workingKey = GenerateWorkingKey(forEncryption, + ((KeyParameter)parameters).GetKey()); + } + + public virtual string AlgorithmName + { + get { return "IDEA"; } + } + + public virtual bool IsPartialBlockOkay + { + get { return false; } + } + + public virtual int GetBlockSize() + { + return BLOCK_SIZE; + } + + public virtual int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + if (workingKey == null) + throw new InvalidOperationException("IDEA engine not initialised"); + + Check.DataLength(input, inOff, BLOCK_SIZE, "input buffer too short"); + Check.OutputLength(output, outOff, BLOCK_SIZE, "output buffer too short"); + + IdeaFunc(workingKey, input, inOff, output, outOff); + return BLOCK_SIZE; + } + public virtual void Reset() + { + } + private static readonly int MASK = 0xffff; + private static readonly int BASE = 0x10001; + private int BytesToWord( + byte[] input, + int inOff) + { + return ((input[inOff] << 8) & 0xff00) + (input[inOff + 1] & 0xff); + } + private void WordToBytes( + int word, + byte[] outBytes, + int outOff) + { + outBytes[outOff] = (byte)((uint) word >> 8); + outBytes[outOff + 1] = (byte)word; + } + /** + * return x = x * y where the multiplication is done modulo + * 65537 (0x10001) (as defined in the IDEA specification) and + * a zero input is taken to be 65536 (0x10000). + * + * @param x the x value + * @param y the y value + * @return x = x * y + */ + private int Mul( + int x, + int y) + { + if (x == 0) + { + x = (BASE - y); + } + else if (y == 0) + { + x = (BASE - x); + } + else + { + int p = x * y; + y = p & MASK; + x = (int) ((uint) p >> 16); + x = y - x + ((y < x) ? 1 : 0); + } + return x & MASK; + } + private void IdeaFunc( + int[] workingKey, + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + int x0, x1, x2, x3, t0, t1; + int keyOff = 0; + x0 = BytesToWord(input, inOff); + x1 = BytesToWord(input, inOff + 2); + x2 = BytesToWord(input, inOff + 4); + x3 = BytesToWord(input, inOff + 6); + for (int round = 0; round < 8; round++) + { + x0 = Mul(x0, workingKey[keyOff++]); + x1 += workingKey[keyOff++]; + x1 &= MASK; + x2 += workingKey[keyOff++]; + x2 &= MASK; + x3 = Mul(x3, workingKey[keyOff++]); + t0 = x1; + t1 = x2; + x2 ^= x0; + x1 ^= x3; + x2 = Mul(x2, workingKey[keyOff++]); + x1 += x2; + x1 &= MASK; + x1 = Mul(x1, workingKey[keyOff++]); + x2 += x1; + x2 &= MASK; + x0 ^= x1; + x3 ^= x2; + x1 ^= t1; + x2 ^= t0; + } + WordToBytes(Mul(x0, workingKey[keyOff++]), outBytes, outOff); + WordToBytes(x2 + workingKey[keyOff++], outBytes, outOff + 2); /* NB: Order */ + WordToBytes(x1 + workingKey[keyOff++], outBytes, outOff + 4); + WordToBytes(Mul(x3, workingKey[keyOff]), outBytes, outOff + 6); + } + /** + * The following function is used to expand the user key to the encryption + * subkey. The first 16 bytes are the user key, and the rest of the subkey + * is calculated by rotating the previous 16 bytes by 25 bits to the left, + * and so on until the subkey is completed. + */ + private int[] ExpandKey( + byte[] uKey) + { + int[] key = new int[52]; + if (uKey.Length < 16) + { + byte[] tmp = new byte[16]; + Array.Copy(uKey, 0, tmp, tmp.Length - uKey.Length, uKey.Length); + uKey = tmp; + } + for (int i = 0; i < 8; i++) + { + key[i] = BytesToWord(uKey, i * 2); + } + for (int i = 8; i < 52; i++) + { + if ((i & 7) < 6) + { + key[i] = ((key[i - 7] & 127) << 9 | key[i - 6] >> 7) & MASK; + } + else if ((i & 7) == 6) + { + key[i] = ((key[i - 7] & 127) << 9 | key[i - 14] >> 7) & MASK; + } + else + { + key[i] = ((key[i - 15] & 127) << 9 | key[i - 14] >> 7) & MASK; + } + } + return key; + } + /** + * This function computes multiplicative inverse using Euclid's Greatest + * Common Divisor algorithm. Zero and one are self inverse. + *

+ * i.e. x * MulInv(x) == 1 (modulo BASE) + *

+ */ + private int MulInv( + int x) + { + int t0, t1, q, y; + + if (x < 2) + { + return x; + } + t0 = 1; + t1 = BASE / x; + y = BASE % x; + while (y != 1) + { + q = x / y; + x = x % y; + t0 = (t0 + (t1 * q)) & MASK; + if (x == 1) + { + return t0; + } + q = y / x; + y = y % x; + t1 = (t1 + (t0 * q)) & MASK; + } + return (1 - t1) & MASK; + } + /** + * Return the additive inverse of x. + *

+ * i.e. x + AddInv(x) == 0 + *

+ */ + int AddInv( + int x) + { + return (0 - x) & MASK; + } + + /** + * The function to invert the encryption subkey to the decryption subkey. + * It also involves the multiplicative inverse and the additive inverse functions. + */ + private int[] InvertKey( + int[] inKey) + { + int t1, t2, t3, t4; + int p = 52; /* We work backwards */ + int[] key = new int[52]; + int inOff = 0; + + t1 = MulInv(inKey[inOff++]); + t2 = AddInv(inKey[inOff++]); + t3 = AddInv(inKey[inOff++]); + t4 = MulInv(inKey[inOff++]); + key[--p] = t4; + key[--p] = t3; + key[--p] = t2; + key[--p] = t1; + + for (int round = 1; round < 8; round++) + { + t1 = inKey[inOff++]; + t2 = inKey[inOff++]; + key[--p] = t2; + key[--p] = t1; + + t1 = MulInv(inKey[inOff++]); + t2 = AddInv(inKey[inOff++]); + t3 = AddInv(inKey[inOff++]); + t4 = MulInv(inKey[inOff++]); + key[--p] = t4; + key[--p] = t2; /* NB: Order */ + key[--p] = t3; + key[--p] = t1; + } + t1 = inKey[inOff++]; + t2 = inKey[inOff++]; + key[--p] = t2; + key[--p] = t1; + + t1 = MulInv(inKey[inOff++]); + t2 = AddInv(inKey[inOff++]); + t3 = AddInv(inKey[inOff++]); + t4 = MulInv(inKey[inOff]); + key[--p] = t4; + key[--p] = t3; + key[--p] = t2; + key[--p] = t1; + return key; + } + + private int[] GenerateWorkingKey( + bool forEncryption, + byte[] userKey) + { + if (forEncryption) + { + return ExpandKey(userKey); + } + else + { + return InvertKey(ExpandKey(userKey)); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/IdeaEngine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/IdeaEngine.cs.meta new file mode 100644 index 0000000..8ccca9e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/IdeaEngine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 03a25df1a86823f428e4281869cb374f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/IesEngine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/IesEngine.cs new file mode 100644 index 0000000..307cc7a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/IesEngine.cs @@ -0,0 +1,243 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * support class for constructing intergrated encryption ciphers + * for doing basic message exchanges on top of key agreement ciphers + */ + public class IesEngine + { + private readonly IBasicAgreement agree; + private readonly IDerivationFunction kdf; + private readonly IMac mac; + private readonly BufferedBlockCipher cipher; + private readonly byte[] macBuf; + + private bool forEncryption; + private ICipherParameters privParam, pubParam; + private IesParameters param; + + /** + * set up for use with stream mode, where the key derivation function + * is used to provide a stream of bytes to xor with the message. + * + * @param agree the key agreement used as the basis for the encryption + * @param kdf the key derivation function used for byte generation + * @param mac the message authentication code generator for the message + */ + public IesEngine( + IBasicAgreement agree, + IDerivationFunction kdf, + IMac mac) + { + this.agree = agree; + this.kdf = kdf; + this.mac = mac; + this.macBuf = new byte[mac.GetMacSize()]; +// this.cipher = null; + } + + /** + * set up for use in conjunction with a block cipher to handle the + * message. + * + * @param agree the key agreement used as the basis for the encryption + * @param kdf the key derivation function used for byte generation + * @param mac the message authentication code generator for the message + * @param cipher the cipher to used for encrypting the message + */ + public IesEngine( + IBasicAgreement agree, + IDerivationFunction kdf, + IMac mac, + BufferedBlockCipher cipher) + { + this.agree = agree; + this.kdf = kdf; + this.mac = mac; + this.macBuf = new byte[mac.GetMacSize()]; + this.cipher = cipher; + } + + /** + * Initialise the encryptor. + * + * @param forEncryption whether or not this is encryption/decryption. + * @param privParam our private key parameters + * @param pubParam the recipient's/sender's public key parameters + * @param param encoding and derivation parameters. + */ + public virtual void Init( + bool forEncryption, + ICipherParameters privParameters, + ICipherParameters pubParameters, + ICipherParameters iesParameters) + { + this.forEncryption = forEncryption; + this.privParam = privParameters; + this.pubParam = pubParameters; + this.param = (IesParameters)iesParameters; + } + + private byte[] DecryptBlock( + byte[] in_enc, + int inOff, + int inLen, + byte[] z) + { + byte[] M = null; + KeyParameter macKey = null; + KdfParameters kParam = new KdfParameters(z, param.GetDerivationV()); + int macKeySize = param.MacKeySize; + + kdf.Init(kParam); + + // Ensure that the length of the input is greater than the MAC in bytes + if (inLen < mac.GetMacSize()) + throw new InvalidCipherTextException("Length of input must be greater than the MAC"); + + inLen -= mac.GetMacSize(); + + if (cipher == null) // stream mode + { + byte[] Buffer = GenerateKdfBytes(kParam, inLen + (macKeySize / 8)); + + M = new byte[inLen]; + + for (int i = 0; i != inLen; i++) + { + M[i] = (byte)(in_enc[inOff + i] ^ Buffer[i]); + } + + macKey = new KeyParameter(Buffer, inLen, (macKeySize / 8)); + } + else + { + int cipherKeySize = ((IesWithCipherParameters)param).CipherKeySize; + byte[] Buffer = GenerateKdfBytes(kParam, (cipherKeySize / 8) + (macKeySize / 8)); + + cipher.Init(false, new KeyParameter(Buffer, 0, (cipherKeySize / 8))); + + M = cipher.DoFinal(in_enc, inOff, inLen); + + macKey = new KeyParameter(Buffer, (cipherKeySize / 8), (macKeySize / 8)); + } + + byte[] macIV = param.GetEncodingV(); + + mac.Init(macKey); + mac.BlockUpdate(in_enc, inOff, inLen); + mac.BlockUpdate(macIV, 0, macIV.Length); + mac.DoFinal(macBuf, 0); + + inOff += inLen; + + byte[] T1 = Arrays.CopyOfRange(in_enc, inOff, inOff + macBuf.Length); + + if (!Arrays.ConstantTimeAreEqual(T1, macBuf)) + throw (new InvalidCipherTextException("Invalid MAC.")); + + return M; + } + + private byte[] EncryptBlock( + byte[] input, + int inOff, + int inLen, + byte[] z) + { + byte[] C = null; + KeyParameter macKey = null; + KdfParameters kParam = new KdfParameters(z, param.GetDerivationV()); + int c_text_length = 0; + int macKeySize = param.MacKeySize; + + if (cipher == null) // stream mode + { + byte[] Buffer = GenerateKdfBytes(kParam, inLen + (macKeySize / 8)); + + C = new byte[inLen + mac.GetMacSize()]; + c_text_length = inLen; + + for (int i = 0; i != inLen; i++) + { + C[i] = (byte)(input[inOff + i] ^ Buffer[i]); + } + + macKey = new KeyParameter(Buffer, inLen, (macKeySize / 8)); + } + else + { + int cipherKeySize = ((IesWithCipherParameters)param).CipherKeySize; + byte[] Buffer = GenerateKdfBytes(kParam, (cipherKeySize / 8) + (macKeySize / 8)); + + cipher.Init(true, new KeyParameter(Buffer, 0, (cipherKeySize / 8))); + + c_text_length = cipher.GetOutputSize(inLen); + byte[] tmp = new byte[c_text_length]; + + int len = cipher.ProcessBytes(input, inOff, inLen, tmp, 0); + len += cipher.DoFinal(tmp, len); + + C = new byte[len + mac.GetMacSize()]; + c_text_length = len; + + Array.Copy(tmp, 0, C, 0, len); + + macKey = new KeyParameter(Buffer, (cipherKeySize / 8), (macKeySize / 8)); + } + + byte[] macIV = param.GetEncodingV(); + + mac.Init(macKey); + mac.BlockUpdate(C, 0, c_text_length); + mac.BlockUpdate(macIV, 0, macIV.Length); + // + // return the message and it's MAC + // + mac.DoFinal(C, c_text_length); + return C; + } + + private byte[] GenerateKdfBytes( + KdfParameters kParam, + int length) + { + byte[] buf = new byte[length]; + + kdf.Init(kParam); + + kdf.GenerateBytes(buf, 0, buf.Length); + + return buf; + } + + public virtual byte[] ProcessBlock( + byte[] input, + int inOff, + int inLen) + { + agree.Init(privParam); + + BigInteger z = agree.CalculateAgreement(pubParam); + + byte[] zBytes = BigIntegers.AsUnsignedByteArray(agree.GetFieldSize(), z); + + try + { + return forEncryption + ? EncryptBlock(input, inOff, inLen, zBytes) + : DecryptBlock(input, inOff, inLen, zBytes); + } + finally + { + Array.Clear(zBytes, 0, zBytes.Length); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/IesEngine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/IesEngine.cs.meta new file mode 100644 index 0000000..bf244f5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/IesEngine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 53e5a96d5e07d9443a7562d56d013808 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/NaccacheSternEngine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/NaccacheSternEngine.cs new file mode 100644 index 0000000..fe2d78d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/NaccacheSternEngine.cs @@ -0,0 +1,358 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * NaccacheStern Engine. For details on this cipher, please see + * http://www.gemplus.com/smart/rd/publications/pdf/NS98pkcs.pdf + */ + public class NaccacheSternEngine + : IAsymmetricBlockCipher + { + private bool forEncryption; + + private NaccacheSternKeyParameters key; + + private IList[] lookup = null; + + public string AlgorithmName + { + get { return "NaccacheStern"; } + } + + /** + * Initializes this algorithm. Must be called before all other Functions. + * + * @see org.bouncycastle.crypto.AsymmetricBlockCipher#init(bool, + * org.bouncycastle.crypto.CipherParameters) + */ + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + this.forEncryption = forEncryption; + + if (parameters is ParametersWithRandom) + { + parameters = ((ParametersWithRandom) parameters).Parameters; + } + + key = (NaccacheSternKeyParameters)parameters; + + // construct lookup table for faster decryption if necessary + if (!this.forEncryption) + { + NaccacheSternPrivateKeyParameters priv = (NaccacheSternPrivateKeyParameters)key; + IList primes = priv.SmallPrimesList; + lookup = new IList[primes.Count]; + for (int i = 0; i < primes.Count; i++) + { + BigInteger actualPrime = (BigInteger) primes[i]; + int actualPrimeValue = actualPrime.IntValue; + + lookup[i] = Platform.CreateArrayList(actualPrimeValue); + lookup[i].Add(BigInteger.One); + + BigInteger accJ = BigInteger.Zero; + + for (int j = 1; j < actualPrimeValue; j++) + { +// BigInteger bigJ = BigInteger.ValueOf(j); +// accJ = priv.PhiN.Multiply(bigJ); + accJ = accJ.Add(priv.PhiN); + BigInteger comp = accJ.Divide(actualPrime); + lookup[i].Add(priv.G.ModPow(comp, priv.Modulus)); + } + } + } + } + + [Obsolete("Remove: no longer used")] + public virtual bool Debug + { + set {} + } + + /** + * Returns the input block size of this algorithm. + * + * @see org.bouncycastle.crypto.AsymmetricBlockCipher#GetInputBlockSize() + */ + public virtual int GetInputBlockSize() + { + if (forEncryption) + { + // We can only encrypt values up to lowerSigmaBound + return (key.LowerSigmaBound + 7) / 8 - 1; + } + else + { + // We pad to modulus-size bytes for easier decryption. +// return key.Modulus.ToByteArray().Length; + return key.Modulus.BitLength / 8 + 1; + } + } + + /** + * Returns the output block size of this algorithm. + * + * @see org.bouncycastle.crypto.AsymmetricBlockCipher#GetOutputBlockSize() + */ + public virtual int GetOutputBlockSize() + { + if (forEncryption) + { + // encrypted Data is always padded up to modulus size +// return key.Modulus.ToByteArray().Length; + return key.Modulus.BitLength / 8 + 1; + } + else + { + // decrypted Data has upper limit lowerSigmaBound + return (key.LowerSigmaBound + 7) / 8 - 1; + } + } + + /** + * Process a single Block using the Naccache-Stern algorithm. + * + * @see org.bouncycastle.crypto.AsymmetricBlockCipher#ProcessBlock(byte[], + * int, int) + */ + public virtual byte[] ProcessBlock( + byte[] inBytes, + int inOff, + int length) + { + if (key == null) + throw new InvalidOperationException("NaccacheStern engine not initialised"); + if (length > (GetInputBlockSize() + 1)) + throw new DataLengthException("input too large for Naccache-Stern cipher.\n"); + + if (!forEncryption) + { + // At decryption make sure that we receive padded data blocks + if (length < GetInputBlockSize()) + { + throw new InvalidCipherTextException("BlockLength does not match modulus for Naccache-Stern cipher.\n"); + } + } + + // transform input into BigInteger + BigInteger input = new BigInteger(1, inBytes, inOff, length); + + byte[] output; + if (forEncryption) + { + output = Encrypt(input); + } + else + { + IList plain = Platform.CreateArrayList(); + NaccacheSternPrivateKeyParameters priv = (NaccacheSternPrivateKeyParameters)key; + IList primes = priv.SmallPrimesList; + // Get Chinese Remainders of CipherText + for (int i = 0; i < primes.Count; i++) + { + BigInteger exp = input.ModPow(priv.PhiN.Divide((BigInteger)primes[i]), priv.Modulus); + IList al = lookup[i]; + if (lookup[i].Count != ((BigInteger)primes[i]).IntValue) + { + throw new InvalidCipherTextException("Error in lookup Array for " + + ((BigInteger)primes[i]).IntValue + + ": Size mismatch. Expected ArrayList with length " + + ((BigInteger)primes[i]).IntValue + " but found ArrayList of length " + + lookup[i].Count); + } + int lookedup = al.IndexOf(exp); + + if (lookedup == -1) + { + throw new InvalidCipherTextException("Lookup failed"); + } + plain.Add(BigInteger.ValueOf(lookedup)); + } + BigInteger test = chineseRemainder(plain, primes); + + // Should not be used as an oracle, so reencrypt output to see + // if it corresponds to input + + // this breaks probabilisic encryption, so disable it. Anyway, we do + // use the first n primes for key generation, so it is pretty easy + // to guess them. But as stated in the paper, this is not a security + // breach. So we can just work with the correct sigma. + + // if ((key.G.ModPow(test, key.Modulus)).Equals(input)) { + // output = test.ToByteArray(); + // } else { + // output = null; + // } + + output = test.ToByteArray(); + } + + return output; + } + + /** + * Encrypts a BigInteger aka Plaintext with the public key. + * + * @param plain + * The BigInteger to encrypt + * @return The byte[] representation of the encrypted BigInteger (i.e. + * crypted.toByteArray()) + */ + public virtual byte[] Encrypt( + BigInteger plain) + { + // Always return modulus size values 0-padded at the beginning + // 0-padding at the beginning is correctly parsed by BigInteger :) +// byte[] output = key.Modulus.ToByteArray(); +// Array.Clear(output, 0, output.Length); + byte[] output = new byte[key.Modulus.BitLength / 8 + 1]; + + byte[] tmp = key.G.ModPow(plain, key.Modulus).ToByteArray(); + Array.Copy(tmp, 0, output, output.Length - tmp.Length, tmp.Length); + return output; + } + + /** + * Adds the contents of two encrypted blocks mod sigma + * + * @param block1 + * the first encrypted block + * @param block2 + * the second encrypted block + * @return encrypt((block1 + block2) mod sigma) + * @throws InvalidCipherTextException + */ + public virtual byte[] AddCryptedBlocks( + byte[] block1, + byte[] block2) + { + // check for correct blocksize + if (forEncryption) + { + if ((block1.Length > GetOutputBlockSize()) + || (block2.Length > GetOutputBlockSize())) + { + throw new InvalidCipherTextException( + "BlockLength too large for simple addition.\n"); + } + } + else + { + if ((block1.Length > GetInputBlockSize()) + || (block2.Length > GetInputBlockSize())) + { + throw new InvalidCipherTextException( + "BlockLength too large for simple addition.\n"); + } + } + + // calculate resulting block + BigInteger m1Crypt = new BigInteger(1, block1); + BigInteger m2Crypt = new BigInteger(1, block2); + BigInteger m1m2Crypt = m1Crypt.Multiply(m2Crypt); + m1m2Crypt = m1m2Crypt.Mod(key.Modulus); + + //byte[] output = key.Modulus.ToByteArray(); + //Array.Clear(output, 0, output.Length); + byte[] output = new byte[key.Modulus.BitLength / 8 + 1]; + + byte[] m1m2CryptBytes = m1m2Crypt.ToByteArray(); + Array.Copy(m1m2CryptBytes, 0, output, + output.Length - m1m2CryptBytes.Length, m1m2CryptBytes.Length); + + return output; + } + + /** + * Convenience Method for data exchange with the cipher. + * + * Determines blocksize and splits data to blocksize. + * + * @param data the data to be processed + * @return the data after it went through the NaccacheSternEngine. + * @throws InvalidCipherTextException + */ + public virtual byte[] ProcessData( + byte[] data) + { + if (data.Length > GetInputBlockSize()) + { + int inBlocksize = GetInputBlockSize(); + int outBlocksize = GetOutputBlockSize(); + int datapos = 0; + int retpos = 0; + byte[] retval = new byte[(data.Length / inBlocksize + 1) * outBlocksize]; + while (datapos < data.Length) + { + byte[] tmp; + if (datapos + inBlocksize < data.Length) + { + tmp = ProcessBlock(data, datapos, inBlocksize); + datapos += inBlocksize; + } + else + { + tmp = ProcessBlock(data, datapos, data.Length - datapos); + datapos += data.Length - datapos; + } + if (tmp != null) + { + tmp.CopyTo(retval, retpos); + retpos += tmp.Length; + } + else + { + throw new InvalidCipherTextException("cipher returned null"); + } + } + byte[] ret = new byte[retpos]; + Array.Copy(retval, 0, ret, 0, retpos); + return ret; + } + else + { + return ProcessBlock(data, 0, data.Length); + } + } + + /** + * Computes the integer x that is expressed through the given primes and the + * congruences with the chinese remainder theorem (CRT). + * + * @param congruences + * the congruences c_i + * @param primes + * the primes p_i + * @return an integer x for that x % p_i == c_i + */ + private static BigInteger chineseRemainder(IList congruences, IList primes) + { + BigInteger retval = BigInteger.Zero; + BigInteger all = BigInteger.One; + for (int i = 0; i < primes.Count; i++) + { + all = all.Multiply((BigInteger)primes[i]); + } + for (int i = 0; i < primes.Count; i++) + { + BigInteger a = (BigInteger)primes[i]; + BigInteger b = all.Divide(a); + BigInteger b2 = b.ModInverse(a); + BigInteger tmp = b.Multiply(b2); + tmp = tmp.Multiply((BigInteger)congruences[i]); + retval = retval.Add(tmp); + } + + return retval.Mod(all); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/NaccacheSternEngine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/NaccacheSternEngine.cs.meta new file mode 100644 index 0000000..a6536b8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/NaccacheSternEngine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 16ffe6e454c962541b0a77e6003d169d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/NoekeonEngine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/NoekeonEngine.cs new file mode 100644 index 0000000..838a403 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/NoekeonEngine.cs @@ -0,0 +1,258 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * A Noekeon engine, using direct-key mode. + */ + public class NoekeonEngine + : IBlockCipher + { + // Block and key size, as well as the amount of rounds. + private const int Size = 16; + + private static readonly byte[] RoundConstants = { 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, + 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4 }; + + private readonly uint[] k = new uint[4]; + + private bool _initialised, _forEncryption; + + /** + * Create an instance of the Noekeon encryption algorithm + * and set some defaults + */ + public NoekeonEngine() + { + _initialised = false; + } + + public virtual string AlgorithmName + { + get { return "Noekeon"; } + } + + public virtual bool IsPartialBlockOkay + { + get { return false; } + } + + public virtual int GetBlockSize() + { + return Size; + } + + /** + * initialise + * + * @param forEncryption whether or not we are for encryption. + * @param params the parameters required to set up the cipher. + * @exception ArgumentException if the params argument is + * inappropriate. + */ + public virtual void Init(bool forEncryption, ICipherParameters parameters) + { + if (!(parameters is KeyParameter)) + throw new ArgumentException("Invalid parameters passed to Noekeon init - " + + Platform.GetTypeName(parameters), "parameters"); + + KeyParameter p = (KeyParameter) parameters; + byte[] key = p.GetKey(); + if (key.Length != 16) + throw new ArgumentException("Key length not 128 bits."); + + Pack.BE_To_UInt32(key, 0, k, 0, 4); + + if (!forEncryption) + { + // theta(k, new uint[]{ 0x00, 0x00, 0x00, 0x00 }); + { + uint a0 = k[0], a1 = k[1], a2 = k[2], a3 = k[3]; + + uint t02 = a0 ^ a2; + t02 ^= Integers.RotateLeft(t02, 8) ^ Integers.RotateLeft(t02, 24); + + uint t13 = a1 ^ a3; + t13 ^= Integers.RotateLeft(t13, 8) ^ Integers.RotateLeft(t13, 24); + + a0 ^= t13; + a1 ^= t02; + a2 ^= t13; + a3 ^= t02; + + k[0] = a0; k[1] = a1; k[2] = a2; k[3] = a3; + } + } + + this._forEncryption = forEncryption; + this._initialised = true; + } + + public virtual int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + if (!_initialised) + throw new InvalidOperationException(AlgorithmName + " not initialised"); + + Check.DataLength(input, inOff, Size, "input buffer too short"); + Check.OutputLength(output, outOff, Size, "output buffer too short"); + + return _forEncryption + ? EncryptBlock(input, inOff, output, outOff) + : DecryptBlock(input, inOff, output, outOff); + } + + public virtual void Reset() + { + } + + private int EncryptBlock(byte[] input, int inOff, byte[] output, int outOff) + { + uint a0 = Pack.BE_To_UInt32(input, inOff); + uint a1 = Pack.BE_To_UInt32(input, inOff + 4); + uint a2 = Pack.BE_To_UInt32(input, inOff + 8); + uint a3 = Pack.BE_To_UInt32(input, inOff + 12); + + uint k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3]; + + int round = 0; + for (;;) + { + a0 ^= RoundConstants[round]; + + // theta(a, k); + { + uint t02 = a0 ^ a2; + t02 ^= Integers.RotateLeft(t02, 8) ^ Integers.RotateLeft(t02, 24); + + a0 ^= k0; + a1 ^= k1; + a2 ^= k2; + a3 ^= k3; + + uint t13 = a1 ^ a3; + t13 ^= Integers.RotateLeft(t13, 8) ^ Integers.RotateLeft(t13, 24); + + a0 ^= t13; + a1 ^= t02; + a2 ^= t13; + a3 ^= t02; + } + + if (++round > Size) + break; + + // pi1(a); + { + a1 = Integers.RotateLeft(a1, 1); + a2 = Integers.RotateLeft(a2, 5); + a3 = Integers.RotateLeft(a3, 2); + } + + // gamma(a); + { + uint t = a3; + a1 ^= a3 | a2; + a3 = a0 ^ (a2 & ~a1); + + a2 = t ^ ~a1 ^ a2 ^ a3; + + a1 ^= a3 | a2; + a0 = t ^ (a2 & a1); + } + + // pi2(a); + { + a1 = Integers.RotateLeft(a1, 31); + a2 = Integers.RotateLeft(a2, 27); + a3 = Integers.RotateLeft(a3, 30); + } + } + + Pack.UInt32_To_BE(a0, output, outOff); + Pack.UInt32_To_BE(a1, output, outOff + 4); + Pack.UInt32_To_BE(a2, output, outOff + 8); + Pack.UInt32_To_BE(a3, output, outOff + 12); + + return Size; + } + + private int DecryptBlock(byte[] input, int inOff, byte[] output, int outOff) + { + uint a0 = Pack.BE_To_UInt32(input, inOff); + uint a1 = Pack.BE_To_UInt32(input, inOff + 4); + uint a2 = Pack.BE_To_UInt32(input, inOff + 8); + uint a3 = Pack.BE_To_UInt32(input, inOff + 12); + + uint k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3]; + + int round = Size; + for (;;) + { + // theta(a, k); + { + uint t02 = a0 ^ a2; + t02 ^= Integers.RotateLeft(t02, 8) ^ Integers.RotateLeft(t02, 24); + + a0 ^= k0; + a1 ^= k1; + a2 ^= k2; + a3 ^= k3; + + uint t13 = a1 ^ a3; + t13 ^= Integers.RotateLeft(t13, 8) ^ Integers.RotateLeft(t13, 24); + + a0 ^= t13; + a1 ^= t02; + a2 ^= t13; + a3 ^= t02; + } + + a0 ^= RoundConstants[round]; + + if (--round < 0) + break; + + // pi1(a); + { + a1 = Integers.RotateLeft(a1, 1); + a2 = Integers.RotateLeft(a2, 5); + a3 = Integers.RotateLeft(a3, 2); + } + + // gamma(a); + { + uint t = a3; + a1 ^= a3 | a2; + a3 = a0 ^ (a2 & ~a1); + + a2 = t ^ ~a1 ^ a2 ^ a3; + + a1 ^= a3 | a2; + a0 = t ^ (a2 & a1); + } + + // pi2(a); + { + a1 = Integers.RotateLeft(a1, 31); + a2 = Integers.RotateLeft(a2, 27); + a3 = Integers.RotateLeft(a3, 30); + } + } + + Pack.UInt32_To_BE(a0, output, outOff); + Pack.UInt32_To_BE(a1, output, outOff + 4); + Pack.UInt32_To_BE(a2, output, outOff + 8); + Pack.UInt32_To_BE(a3, output, outOff + 12); + + return Size; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/NoekeonEngine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/NoekeonEngine.cs.meta new file mode 100644 index 0000000..4b60995 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/NoekeonEngine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 56aa0376b5ad63741ad06d44db774916 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/NullEngine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/NullEngine.cs new file mode 100644 index 0000000..f883b7c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/NullEngine.cs @@ -0,0 +1,69 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * The no-op engine that just copies bytes through, irrespective of whether encrypting and decrypting. + * Provided for the sake of completeness. + */ + public class NullEngine + : IBlockCipher + { + private bool initialised; + private const int BlockSize = 1; + + public NullEngine() + { + } + + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + // we don't mind any parameters that may come in + initialised = true; + } + + public virtual string AlgorithmName + { + get { return "Null"; } + } + + public virtual bool IsPartialBlockOkay + { + get { return true; } + } + + public virtual int GetBlockSize() + { + return BlockSize; + } + + public virtual int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + if (!initialised) + throw new InvalidOperationException("Null engine not initialised"); + + Check.DataLength(input, inOff, BlockSize, "input buffer too short"); + Check.OutputLength(output, outOff, BlockSize, "output buffer too short"); + + for (int i = 0; i < BlockSize; ++i) + { + output[outOff + i] = input[inOff + i]; + } + + return BlockSize; + } + + public virtual void Reset() + { + // nothing needs to be done + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/NullEngine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/NullEngine.cs.meta new file mode 100644 index 0000000..a24d45a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/NullEngine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3197d04f92bfe89489128581709624ca +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RC2Engine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RC2Engine.cs new file mode 100644 index 0000000..4aca189 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RC2Engine.cs @@ -0,0 +1,311 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * an implementation of RC2 as described in RFC 2268 + * "A Description of the RC2(r) Encryption Algorithm" R. Rivest. + */ + public class RC2Engine + : IBlockCipher + { + // + // the values we use for key expansion (based on the digits of PI) + // + private static readonly byte[] piTable = + { + (byte)0xd9, (byte)0x78, (byte)0xf9, (byte)0xc4, (byte)0x19, (byte)0xdd, (byte)0xb5, (byte)0xed, + (byte)0x28, (byte)0xe9, (byte)0xfd, (byte)0x79, (byte)0x4a, (byte)0xa0, (byte)0xd8, (byte)0x9d, + (byte)0xc6, (byte)0x7e, (byte)0x37, (byte)0x83, (byte)0x2b, (byte)0x76, (byte)0x53, (byte)0x8e, + (byte)0x62, (byte)0x4c, (byte)0x64, (byte)0x88, (byte)0x44, (byte)0x8b, (byte)0xfb, (byte)0xa2, + (byte)0x17, (byte)0x9a, (byte)0x59, (byte)0xf5, (byte)0x87, (byte)0xb3, (byte)0x4f, (byte)0x13, + (byte)0x61, (byte)0x45, (byte)0x6d, (byte)0x8d, (byte)0x9, (byte)0x81, (byte)0x7d, (byte)0x32, + (byte)0xbd, (byte)0x8f, (byte)0x40, (byte)0xeb, (byte)0x86, (byte)0xb7, (byte)0x7b, (byte)0xb, + (byte)0xf0, (byte)0x95, (byte)0x21, (byte)0x22, (byte)0x5c, (byte)0x6b, (byte)0x4e, (byte)0x82, + (byte)0x54, (byte)0xd6, (byte)0x65, (byte)0x93, (byte)0xce, (byte)0x60, (byte)0xb2, (byte)0x1c, + (byte)0x73, (byte)0x56, (byte)0xc0, (byte)0x14, (byte)0xa7, (byte)0x8c, (byte)0xf1, (byte)0xdc, + (byte)0x12, (byte)0x75, (byte)0xca, (byte)0x1f, (byte)0x3b, (byte)0xbe, (byte)0xe4, (byte)0xd1, + (byte)0x42, (byte)0x3d, (byte)0xd4, (byte)0x30, (byte)0xa3, (byte)0x3c, (byte)0xb6, (byte)0x26, + (byte)0x6f, (byte)0xbf, (byte)0xe, (byte)0xda, (byte)0x46, (byte)0x69, (byte)0x7, (byte)0x57, + (byte)0x27, (byte)0xf2, (byte)0x1d, (byte)0x9b, (byte)0xbc, (byte)0x94, (byte)0x43, (byte)0x3, + (byte)0xf8, (byte)0x11, (byte)0xc7, (byte)0xf6, (byte)0x90, (byte)0xef, (byte)0x3e, (byte)0xe7, + (byte)0x6, (byte)0xc3, (byte)0xd5, (byte)0x2f, (byte)0xc8, (byte)0x66, (byte)0x1e, (byte)0xd7, + (byte)0x8, (byte)0xe8, (byte)0xea, (byte)0xde, (byte)0x80, (byte)0x52, (byte)0xee, (byte)0xf7, + (byte)0x84, (byte)0xaa, (byte)0x72, (byte)0xac, (byte)0x35, (byte)0x4d, (byte)0x6a, (byte)0x2a, + (byte)0x96, (byte)0x1a, (byte)0xd2, (byte)0x71, (byte)0x5a, (byte)0x15, (byte)0x49, (byte)0x74, + (byte)0x4b, (byte)0x9f, (byte)0xd0, (byte)0x5e, (byte)0x4, (byte)0x18, (byte)0xa4, (byte)0xec, + (byte)0xc2, (byte)0xe0, (byte)0x41, (byte)0x6e, (byte)0xf, (byte)0x51, (byte)0xcb, (byte)0xcc, + (byte)0x24, (byte)0x91, (byte)0xaf, (byte)0x50, (byte)0xa1, (byte)0xf4, (byte)0x70, (byte)0x39, + (byte)0x99, (byte)0x7c, (byte)0x3a, (byte)0x85, (byte)0x23, (byte)0xb8, (byte)0xb4, (byte)0x7a, + (byte)0xfc, (byte)0x2, (byte)0x36, (byte)0x5b, (byte)0x25, (byte)0x55, (byte)0x97, (byte)0x31, + (byte)0x2d, (byte)0x5d, (byte)0xfa, (byte)0x98, (byte)0xe3, (byte)0x8a, (byte)0x92, (byte)0xae, + (byte)0x5, (byte)0xdf, (byte)0x29, (byte)0x10, (byte)0x67, (byte)0x6c, (byte)0xba, (byte)0xc9, + (byte)0xd3, (byte)0x0, (byte)0xe6, (byte)0xcf, (byte)0xe1, (byte)0x9e, (byte)0xa8, (byte)0x2c, + (byte)0x63, (byte)0x16, (byte)0x1, (byte)0x3f, (byte)0x58, (byte)0xe2, (byte)0x89, (byte)0xa9, + (byte)0xd, (byte)0x38, (byte)0x34, (byte)0x1b, (byte)0xab, (byte)0x33, (byte)0xff, (byte)0xb0, + (byte)0xbb, (byte)0x48, (byte)0xc, (byte)0x5f, (byte)0xb9, (byte)0xb1, (byte)0xcd, (byte)0x2e, + (byte)0xc5, (byte)0xf3, (byte)0xdb, (byte)0x47, (byte)0xe5, (byte)0xa5, (byte)0x9c, (byte)0x77, + (byte)0xa, (byte)0xa6, (byte)0x20, (byte)0x68, (byte)0xfe, (byte)0x7f, (byte)0xc1, (byte)0xad + }; + + private const int BLOCK_SIZE = 8; + + private int[] workingKey; + private bool encrypting; + + private int[] GenerateWorkingKey( + byte[] key, + int bits) + { + int x; + int[] xKey = new int[128]; + + for (int i = 0; i != key.Length; i++) + { + xKey[i] = key[i] & 0xff; + } + + // Phase 1: Expand input key to 128 bytes + int len = key.Length; + + if (len < 128) + { + int index = 0; + + x = xKey[len - 1]; + + do + { + x = piTable[(x + xKey[index++]) & 255] & 0xff; + xKey[len++] = x; + } + while (len < 128); + } + + // Phase 2 - reduce effective key size to "bits" + len = (bits + 7) >> 3; + x = piTable[xKey[128 - len] & (255 >> (7 & -bits))] & 0xff; + xKey[128 - len] = x; + + for (int i = 128 - len - 1; i >= 0; i--) + { + x = piTable[x ^ xKey[i + len]] & 0xff; + xKey[i] = x; + } + + // Phase 3 - copy to newKey in little-endian order + int[] newKey = new int[64]; + + for (int i = 0; i != newKey.Length; i++) + { + newKey[i] = (xKey[2 * i] + (xKey[2 * i + 1] << 8)); + } + + return newKey; + } + + /** + * initialise a RC2 cipher. + * + * @param forEncryption whether or not we are for encryption. + * @param parameters the parameters required to set up the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + this.encrypting = forEncryption; + + if (parameters is RC2Parameters) + { + RC2Parameters param = (RC2Parameters) parameters; + + workingKey = GenerateWorkingKey(param.GetKey(), param.EffectiveKeyBits); + } + else if (parameters is KeyParameter) + { + KeyParameter param = (KeyParameter) parameters; + byte[] key = param.GetKey(); + + workingKey = GenerateWorkingKey(key, key.Length * 8); + } + else + { + throw new ArgumentException("invalid parameter passed to RC2 init - " + Platform.GetTypeName(parameters)); + } + } + + public virtual void Reset() + { + } + + public virtual string AlgorithmName + { + get { return "RC2"; } + } + + public virtual bool IsPartialBlockOkay + { + get { return false; } + } + + public virtual int GetBlockSize() + { + return BLOCK_SIZE; + } + + public virtual int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + if (workingKey == null) + throw new InvalidOperationException("RC2 engine not initialised"); + + Check.DataLength(input, inOff, BLOCK_SIZE, "input buffer too short"); + Check.OutputLength(output, outOff, BLOCK_SIZE, "output buffer too short"); + + if (encrypting) + { + EncryptBlock(input, inOff, output, outOff); + } + else + { + DecryptBlock(input, inOff, output, outOff); + } + + return BLOCK_SIZE; + } + + /** + * return the result rotating the 16 bit number in x left by y + */ + private int RotateWordLeft( + int x, + int y) + { + x &= 0xffff; + return (x << y) | (x >> (16 - y)); + } + + private void EncryptBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + int x76, x54, x32, x10; + + x76 = ((input[inOff + 7] & 0xff) << 8) + (input[inOff + 6] & 0xff); + x54 = ((input[inOff + 5] & 0xff) << 8) + (input[inOff + 4] & 0xff); + x32 = ((input[inOff + 3] & 0xff) << 8) + (input[inOff + 2] & 0xff); + x10 = ((input[inOff + 1] & 0xff) << 8) + (input[inOff + 0] & 0xff); + + for (int i = 0; i <= 16; i += 4) + { + x10 = RotateWordLeft(x10 + (x32 & ~x76) + (x54 & x76) + workingKey[i ], 1); + x32 = RotateWordLeft(x32 + (x54 & ~x10) + (x76 & x10) + workingKey[i+1], 2); + x54 = RotateWordLeft(x54 + (x76 & ~x32) + (x10 & x32) + workingKey[i+2], 3); + x76 = RotateWordLeft(x76 + (x10 & ~x54) + (x32 & x54) + workingKey[i+3], 5); + } + + x10 += workingKey[x76 & 63]; + x32 += workingKey[x10 & 63]; + x54 += workingKey[x32 & 63]; + x76 += workingKey[x54 & 63]; + + for (int i = 20; i <= 40; i += 4) + { + x10 = RotateWordLeft(x10 + (x32 & ~x76) + (x54 & x76) + workingKey[i ], 1); + x32 = RotateWordLeft(x32 + (x54 & ~x10) + (x76 & x10) + workingKey[i+1], 2); + x54 = RotateWordLeft(x54 + (x76 & ~x32) + (x10 & x32) + workingKey[i+2], 3); + x76 = RotateWordLeft(x76 + (x10 & ~x54) + (x32 & x54) + workingKey[i+3], 5); + } + + x10 += workingKey[x76 & 63]; + x32 += workingKey[x10 & 63]; + x54 += workingKey[x32 & 63]; + x76 += workingKey[x54 & 63]; + + for (int i = 44; i < 64; i += 4) + { + x10 = RotateWordLeft(x10 + (x32 & ~x76) + (x54 & x76) + workingKey[i ], 1); + x32 = RotateWordLeft(x32 + (x54 & ~x10) + (x76 & x10) + workingKey[i+1], 2); + x54 = RotateWordLeft(x54 + (x76 & ~x32) + (x10 & x32) + workingKey[i+2], 3); + x76 = RotateWordLeft(x76 + (x10 & ~x54) + (x32 & x54) + workingKey[i+3], 5); + } + + outBytes[outOff + 0] = (byte)x10; + outBytes[outOff + 1] = (byte)(x10 >> 8); + outBytes[outOff + 2] = (byte)x32; + outBytes[outOff + 3] = (byte)(x32 >> 8); + outBytes[outOff + 4] = (byte)x54; + outBytes[outOff + 5] = (byte)(x54 >> 8); + outBytes[outOff + 6] = (byte)x76; + outBytes[outOff + 7] = (byte)(x76 >> 8); + } + + private void DecryptBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + int x76, x54, x32, x10; + + x76 = ((input[inOff + 7] & 0xff) << 8) + (input[inOff + 6] & 0xff); + x54 = ((input[inOff + 5] & 0xff) << 8) + (input[inOff + 4] & 0xff); + x32 = ((input[inOff + 3] & 0xff) << 8) + (input[inOff + 2] & 0xff); + x10 = ((input[inOff + 1] & 0xff) << 8) + (input[inOff + 0] & 0xff); + + for (int i = 60; i >= 44; i -= 4) + { + x76 = RotateWordLeft(x76, 11) - ((x10 & ~x54) + (x32 & x54) + workingKey[i+3]); + x54 = RotateWordLeft(x54, 13) - ((x76 & ~x32) + (x10 & x32) + workingKey[i+2]); + x32 = RotateWordLeft(x32, 14) - ((x54 & ~x10) + (x76 & x10) + workingKey[i+1]); + x10 = RotateWordLeft(x10, 15) - ((x32 & ~x76) + (x54 & x76) + workingKey[i ]); + } + + x76 -= workingKey[x54 & 63]; + x54 -= workingKey[x32 & 63]; + x32 -= workingKey[x10 & 63]; + x10 -= workingKey[x76 & 63]; + + for (int i = 40; i >= 20; i -= 4) + { + x76 = RotateWordLeft(x76, 11) - ((x10 & ~x54) + (x32 & x54) + workingKey[i+3]); + x54 = RotateWordLeft(x54, 13) - ((x76 & ~x32) + (x10 & x32) + workingKey[i+2]); + x32 = RotateWordLeft(x32, 14) - ((x54 & ~x10) + (x76 & x10) + workingKey[i+1]); + x10 = RotateWordLeft(x10, 15) - ((x32 & ~x76) + (x54 & x76) + workingKey[i ]); + } + + x76 -= workingKey[x54 & 63]; + x54 -= workingKey[x32 & 63]; + x32 -= workingKey[x10 & 63]; + x10 -= workingKey[x76 & 63]; + + for (int i = 16; i >= 0; i -= 4) + { + x76 = RotateWordLeft(x76, 11) - ((x10 & ~x54) + (x32 & x54) + workingKey[i+3]); + x54 = RotateWordLeft(x54, 13) - ((x76 & ~x32) + (x10 & x32) + workingKey[i+2]); + x32 = RotateWordLeft(x32, 14) - ((x54 & ~x10) + (x76 & x10) + workingKey[i+1]); + x10 = RotateWordLeft(x10, 15) - ((x32 & ~x76) + (x54 & x76) + workingKey[i ]); + } + + outBytes[outOff + 0] = (byte)x10; + outBytes[outOff + 1] = (byte)(x10 >> 8); + outBytes[outOff + 2] = (byte)x32; + outBytes[outOff + 3] = (byte)(x32 >> 8); + outBytes[outOff + 4] = (byte)x54; + outBytes[outOff + 5] = (byte)(x54 >> 8); + outBytes[outOff + 6] = (byte)x76; + outBytes[outOff + 7] = (byte)(x76 >> 8); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RC2Engine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RC2Engine.cs.meta new file mode 100644 index 0000000..f35aef1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RC2Engine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 217021d681f433c4fbde88f5484d73e5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RC2WrapEngine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RC2WrapEngine.cs new file mode 100644 index 0000000..5742aa8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RC2WrapEngine.cs @@ -0,0 +1,370 @@ +using System; + +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Modes; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * Wrap keys according to RFC 3217 - RC2 mechanism + */ + public class RC2WrapEngine + : IWrapper + { + /** Field engine */ + private CbcBlockCipher engine; + + /** Field param */ + private ICipherParameters parameters; + + /** Field paramPlusIV */ + private ParametersWithIV paramPlusIV; + + /** Field iv */ + private byte[] iv; + + /** Field forWrapping */ + private bool forWrapping; + + private SecureRandom sr; + + /** Field IV2 */ + private static readonly byte[] IV2 = + { + (byte) 0x4a, (byte) 0xdd, (byte) 0xa2, + (byte) 0x2c, (byte) 0x79, (byte) 0xe8, + (byte) 0x21, (byte) 0x05 + }; + + // + // checksum digest + // + IDigest sha1 = new Sha1Digest(); + byte[] digest = new byte[20]; + + /** + * Method init + * + * @param forWrapping + * @param param + */ + public virtual void Init( + bool forWrapping, + ICipherParameters parameters) + { + this.forWrapping = forWrapping; + this.engine = new CbcBlockCipher(new RC2Engine()); + + if (parameters is ParametersWithRandom) + { + ParametersWithRandom pWithR = (ParametersWithRandom)parameters; + sr = pWithR.Random; + parameters = pWithR.Parameters; + } + else + { + sr = new SecureRandom(); + } + + if (parameters is ParametersWithIV) + { + if (!forWrapping) + throw new ArgumentException("You should not supply an IV for unwrapping"); + + this.paramPlusIV = (ParametersWithIV)parameters; + this.iv = this.paramPlusIV.GetIV(); + this.parameters = this.paramPlusIV.Parameters; + + if (this.iv.Length != 8) + throw new ArgumentException("IV is not 8 octets"); + } + else + { + this.parameters = parameters; + + if (this.forWrapping) + { + // Hm, we have no IV but we want to wrap ?!? + // well, then we have to create our own IV. + this.iv = new byte[8]; + sr.NextBytes(iv); + this.paramPlusIV = new ParametersWithIV(this.parameters, this.iv); + } + } + } + + /** + * Method GetAlgorithmName + * + * @return + */ + public virtual string AlgorithmName + { + get { return "RC2"; } + } + + /** + * Method wrap + * + * @param in + * @param inOff + * @param inLen + * @return + */ + public virtual byte[] Wrap( + byte[] input, + int inOff, + int length) + { + if (!forWrapping) + { + throw new InvalidOperationException("Not initialized for wrapping"); + } + + int len = length + 1; + if ((len % 8) != 0) + { + len += 8 - (len % 8); + } + + byte [] keyToBeWrapped = new byte[len]; + + keyToBeWrapped[0] = (byte)length; + Array.Copy(input, inOff, keyToBeWrapped, 1, length); + + byte[] pad = new byte[keyToBeWrapped.Length - length - 1]; + + if (pad.Length > 0) + { + sr.NextBytes(pad); + Array.Copy(pad, 0, keyToBeWrapped, length + 1, pad.Length); + } + + // Compute the CMS Key Checksum, (section 5.6.1), call this CKS. + byte[] CKS = CalculateCmsKeyChecksum(keyToBeWrapped); + + // Let WKCKS = WK || CKS where || is concatenation. + byte[] WKCKS = new byte[keyToBeWrapped.Length + CKS.Length]; + + Array.Copy(keyToBeWrapped, 0, WKCKS, 0, keyToBeWrapped.Length); + Array.Copy(CKS, 0, WKCKS, keyToBeWrapped.Length, CKS.Length); + + // Encrypt WKCKS in CBC mode using KEK as the key and IV as the + // initialization vector. Call the results TEMP1. + byte [] TEMP1 = new byte[WKCKS.Length]; + + Array.Copy(WKCKS, 0, TEMP1, 0, WKCKS.Length); + + int noOfBlocks = WKCKS.Length / engine.GetBlockSize(); + int extraBytes = WKCKS.Length % engine.GetBlockSize(); + + if (extraBytes != 0) + { + throw new InvalidOperationException("Not multiple of block length"); + } + + engine.Init(true, paramPlusIV); + + for (int i = 0; i < noOfBlocks; i++) + { + int currentBytePos = i * engine.GetBlockSize(); + + engine.ProcessBlock(TEMP1, currentBytePos, TEMP1, currentBytePos); + } + + // Left TEMP2 = IV || TEMP1. + byte[] TEMP2 = new byte[this.iv.Length + TEMP1.Length]; + + Array.Copy(this.iv, 0, TEMP2, 0, this.iv.Length); + Array.Copy(TEMP1, 0, TEMP2, this.iv.Length, TEMP1.Length); + + // Reverse the order of the octets in TEMP2 and call the result TEMP3. + byte[] TEMP3 = new byte[TEMP2.Length]; + + for (int i = 0; i < TEMP2.Length; i++) + { + TEMP3[i] = TEMP2[TEMP2.Length - (i + 1)]; + } + + // Encrypt TEMP3 in CBC mode using the KEK and an initialization vector + // of 0x 4a dd a2 2c 79 e8 21 05. The resulting cipher text is the desired + // result. It is 40 octets long if a 168 bit key is being wrapped. + ParametersWithIV param2 = new ParametersWithIV(this.parameters, IV2); + + this.engine.Init(true, param2); + + for (int i = 0; i < noOfBlocks + 1; i++) + { + int currentBytePos = i * engine.GetBlockSize(); + + engine.ProcessBlock(TEMP3, currentBytePos, TEMP3, currentBytePos); + } + + return TEMP3; + } + + /** + * Method unwrap + * + * @param in + * @param inOff + * @param inLen + * @return + * @throws InvalidCipherTextException + */ + public virtual byte[] Unwrap( + byte[] input, + int inOff, + int length) + { + if (forWrapping) + { + throw new InvalidOperationException("Not set for unwrapping"); + } + + if (input == null) + { + throw new InvalidCipherTextException("Null pointer as ciphertext"); + } + + if (length % engine.GetBlockSize() != 0) + { + throw new InvalidCipherTextException("Ciphertext not multiple of " + + engine.GetBlockSize()); + } + + /* + // Check if the length of the cipher text is reasonable given the key + // type. It must be 40 bytes for a 168 bit key and either 32, 40, or + // 48 bytes for a 128, 192, or 256 bit key. If the length is not supported + // or inconsistent with the algorithm for which the key is intended, + // return error. + // + // we do not accept 168 bit keys. it has to be 192 bit. + int lengthA = (estimatedKeyLengthInBit / 8) + 16; + int lengthB = estimatedKeyLengthInBit % 8; + + if ((lengthA != keyToBeUnwrapped.Length) || (lengthB != 0)) { + throw new XMLSecurityException("empty"); + } + */ + + // Decrypt the cipher text with TRIPLedeS in CBC mode using the KEK + // and an initialization vector (IV) of 0x4adda22c79e82105. Call the output TEMP3. + ParametersWithIV param2 = new ParametersWithIV(this.parameters, IV2); + + this.engine.Init(false, param2); + + byte [] TEMP3 = new byte[length]; + + Array.Copy(input, inOff, TEMP3, 0, length); + + for (int i = 0; i < (TEMP3.Length / engine.GetBlockSize()); i++) + { + int currentBytePos = i * engine.GetBlockSize(); + + engine.ProcessBlock(TEMP3, currentBytePos, TEMP3, currentBytePos); + } + + // Reverse the order of the octets in TEMP3 and call the result TEMP2. + byte[] TEMP2 = new byte[TEMP3.Length]; + + for (int i = 0; i < TEMP3.Length; i++) + { + TEMP2[i] = TEMP3[TEMP3.Length - (i + 1)]; + } + + // Decompose TEMP2 into IV, the first 8 octets, and TEMP1, the remaining octets. + this.iv = new byte[8]; + + byte[] TEMP1 = new byte[TEMP2.Length - 8]; + + Array.Copy(TEMP2, 0, this.iv, 0, 8); + Array.Copy(TEMP2, 8, TEMP1, 0, TEMP2.Length - 8); + + // Decrypt TEMP1 using TRIPLedeS in CBC mode using the KEK and the IV + // found in the previous step. Call the result WKCKS. + this.paramPlusIV = new ParametersWithIV(this.parameters, this.iv); + + this.engine.Init(false, this.paramPlusIV); + + byte[] LCEKPADICV = new byte[TEMP1.Length]; + + Array.Copy(TEMP1, 0, LCEKPADICV, 0, TEMP1.Length); + + for (int i = 0; i < (LCEKPADICV.Length / engine.GetBlockSize()); i++) + { + int currentBytePos = i * engine.GetBlockSize(); + + engine.ProcessBlock(LCEKPADICV, currentBytePos, LCEKPADICV, currentBytePos); + } + + // Decompose LCEKPADICV. CKS is the last 8 octets and WK, the wrapped key, are + // those octets before the CKS. + byte[] result = new byte[LCEKPADICV.Length - 8]; + byte[] CKStoBeVerified = new byte[8]; + + Array.Copy(LCEKPADICV, 0, result, 0, LCEKPADICV.Length - 8); + Array.Copy(LCEKPADICV, LCEKPADICV.Length - 8, CKStoBeVerified, 0, 8); + + // Calculate a CMS Key Checksum, (section 5.6.1), over the WK and compare + // with the CKS extracted in the above step. If they are not equal, return error. + if (!CheckCmsKeyChecksum(result, CKStoBeVerified)) + { + throw new InvalidCipherTextException( + "Checksum inside ciphertext is corrupted"); + } + + if ((result.Length - ((result[0] & 0xff) + 1)) > 7) + { + throw new InvalidCipherTextException( + "too many pad bytes (" + (result.Length - ((result[0] & 0xff) + 1)) + ")"); + } + + // CEK is the wrapped key, now extracted for use in data decryption. + byte[] CEK = new byte[result[0]]; + Array.Copy(result, 1, CEK, 0, CEK.Length); + return CEK; + } + + /** + * Some key wrap algorithms make use of the Key Checksum defined + * in CMS [CMS-Algorithms]. This is used to provide an integrity + * check value for the key being wrapped. The algorithm is + * + * - Compute the 20 octet SHA-1 hash on the key being wrapped. + * - Use the first 8 octets of this hash as the checksum value. + * + * @param key + * @return + * @throws Exception + * @see http://www.w3.org/TR/xmlenc-core/#sec-CMSKeyChecksum + */ + private byte[] CalculateCmsKeyChecksum( + byte[] key) + { + sha1.BlockUpdate(key, 0, key.Length); + sha1.DoFinal(digest, 0); + + byte[] result = new byte[8]; + Array.Copy(digest, 0, result, 0, 8); + return result; + } + + /** + * @param key + * @param checksum + * @return + * @see http://www.w3.org/TR/xmlenc-core/#sec-CMSKeyChecksum + */ + private bool CheckCmsKeyChecksum( + byte[] key, + byte[] checksum) + { + return Arrays.ConstantTimeAreEqual(CalculateCmsKeyChecksum(key), checksum); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RC2WrapEngine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RC2WrapEngine.cs.meta new file mode 100644 index 0000000..d79fc6f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RC2WrapEngine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 49389399ef4e67e49bb17f08b2359cf2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RC4Engine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RC4Engine.cs new file mode 100644 index 0000000..a515bb0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RC4Engine.cs @@ -0,0 +1,139 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + public class RC4Engine + : IStreamCipher + { + private readonly static int STATE_LENGTH = 256; + + /* + * variables to hold the state of the RC4 engine + * during encryption and decryption + */ + + private byte[] engineState; + private int x; + private int y; + private byte[] workingKey; + + /** + * initialise a RC4 cipher. + * + * @param forEncryption whether or not we are for encryption. + * @param parameters the parameters required to set up the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (parameters is KeyParameter) + { + /* + * RC4 encryption and decryption is completely + * symmetrical, so the 'forEncryption' is + * irrelevant. + */ + workingKey = ((KeyParameter)parameters).GetKey(); + SetKey(workingKey); + + return; + } + + throw new ArgumentException("invalid parameter passed to RC4 init - " + Platform.GetTypeName(parameters)); + } + + public virtual string AlgorithmName + { + get { return "RC4"; } + } + + public virtual byte ReturnByte( + byte input) + { + x = (x + 1) & 0xff; + y = (engineState[x] + y) & 0xff; + + // swap + byte tmp = engineState[x]; + engineState[x] = engineState[y]; + engineState[y] = tmp; + + // xor + return (byte)(input ^ engineState[(engineState[x] + engineState[y]) & 0xff]); + } + + public virtual void ProcessBytes( + byte[] input, + int inOff, + int length, + byte[] output, + int outOff) + { + Check.DataLength(input, inOff, length, "input buffer too short"); + Check.OutputLength(output, outOff, length, "output buffer too short"); + + for (int i = 0; i < length ; i++) + { + x = (x + 1) & 0xff; + y = (engineState[x] + y) & 0xff; + + // swap + byte tmp = engineState[x]; + engineState[x] = engineState[y]; + engineState[y] = tmp; + + // xor + output[i+outOff] = (byte)(input[i + inOff] + ^ engineState[(engineState[x] + engineState[y]) & 0xff]); + } + } + + public virtual void Reset() + { + SetKey(workingKey); + } + + // Private implementation + + private void SetKey( + byte[] keyBytes) + { + workingKey = keyBytes; + + // System.out.println("the key length is ; "+ workingKey.Length); + + x = 0; + y = 0; + + if (engineState == null) + { + engineState = new byte[STATE_LENGTH]; + } + + // reset the state of the engine + for (int i=0; i < STATE_LENGTH; i++) + { + engineState[i] = (byte)i; + } + + int i1 = 0; + int i2 = 0; + + for (int i=0; i < STATE_LENGTH; i++) + { + i2 = ((keyBytes[i1] & 0xff) + engineState[i] + i2) & 0xff; + // do the byte-swap inline + byte tmp = engineState[i]; + engineState[i] = engineState[i2]; + engineState[i2] = tmp; + i1 = (i1+1) % keyBytes.Length; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RC4Engine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RC4Engine.cs.meta new file mode 100644 index 0000000..859b568 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RC4Engine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4cc7562224054234ca64693f7a3b4f7a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RC532Engine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RC532Engine.cs new file mode 100644 index 0000000..d1c29e6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RC532Engine.cs @@ -0,0 +1,294 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * The specification for RC5 came from the RC5 Encryption Algorithm + * publication in RSA CryptoBytes, Spring of 1995. + * http://www.rsasecurity.com/rsalabs/cryptobytes. + *

+ * This implementation has a word size of 32 bits.

+ */ + public class RC532Engine + : IBlockCipher + { + /* + * the number of rounds to perform + */ + private int _noRounds; + + /* + * the expanded key array of size 2*(rounds + 1) + */ + private int [] _S; + + /* + * our "magic constants" for 32 32 + * + * Pw = Odd((e-2) * 2^wordsize) + * Qw = Odd((o-2) * 2^wordsize) + * + * where e is the base of natural logarithms (2.718281828...) + * and o is the golden ratio (1.61803398...) + */ + private static readonly int P32 = unchecked((int) 0xb7e15163); + private static readonly int Q32 = unchecked((int) 0x9e3779b9); + + private bool forEncryption; + + /** + * Create an instance of the RC5 encryption algorithm + * and set some defaults + */ + public RC532Engine() + { + _noRounds = 12; // the default +// _S = null; + } + + public virtual string AlgorithmName + { + get { return "RC5-32"; } + } + + public virtual bool IsPartialBlockOkay + { + get { return false; } + } + + public virtual int GetBlockSize() + { + return 2 * 4; + } + + /** + * initialise a RC5-32 cipher. + * + * @param forEncryption whether or not we are for encryption. + * @param parameters the parameters required to set up the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (typeof(RC5Parameters).IsInstanceOfType(parameters)) + { + RC5Parameters p = (RC5Parameters)parameters; + + _noRounds = p.Rounds; + + SetKey(p.GetKey()); + } + else if (typeof(KeyParameter).IsInstanceOfType(parameters)) + { + KeyParameter p = (KeyParameter)parameters; + + SetKey(p.GetKey()); + } + else + { + throw new ArgumentException("invalid parameter passed to RC532 init - " + Platform.GetTypeName(parameters)); + } + + this.forEncryption = forEncryption; + } + + public virtual int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + return (forEncryption) + ? EncryptBlock(input, inOff, output, outOff) + : DecryptBlock(input, inOff, output, outOff); + } + + public virtual void Reset() + { + } + + /** + * Re-key the cipher. + * + * @param key the key to be used + */ + private void SetKey( + byte[] key) + { + // + // KEY EXPANSION: + // + // There are 3 phases to the key expansion. + // + // Phase 1: + // Copy the secret key K[0...b-1] into an array L[0..c-1] of + // c = ceil(b/u), where u = 32/8 in little-endian order. + // In other words, we fill up L using u consecutive key bytes + // of K. Any unfilled byte positions in L are zeroed. In the + // case that b = c = 0, set c = 1 and L[0] = 0. + // + int[] L = new int[(key.Length + (4 - 1)) / 4]; + + for (int i = 0; i != key.Length; i++) + { + L[i / 4] += (key[i] & 0xff) << (8 * (i % 4)); + } + + // + // Phase 2: + // Initialize S to a particular fixed pseudo-random bit pattern + // using an arithmetic progression modulo 2^wordsize determined + // by the magic numbers, Pw & Qw. + // + _S = new int[2*(_noRounds + 1)]; + + _S[0] = P32; + for (int i=1; i < _S.Length; i++) + { + _S[i] = (_S[i-1] + Q32); + } + + // + // Phase 3: + // Mix in the user's secret key in 3 passes over the arrays S & L. + // The max of the arrays sizes is used as the loop control + // + int iter; + + if (L.Length > _S.Length) + { + iter = 3 * L.Length; + } + else + { + iter = 3 * _S.Length; + } + + int A = 0, B = 0; + int ii = 0, jj = 0; + + for (int k = 0; k < iter; k++) + { + A = _S[ii] = RotateLeft(_S[ii] + A + B, 3); + B = L[jj] = RotateLeft( L[jj] + A + B, A+B); + ii = (ii+1) % _S.Length; + jj = (jj+1) % L.Length; + } + } + + /** + * Encrypt the given block starting at the given offset and place + * the result in the provided buffer starting at the given offset. + * + * @param in in byte buffer containing data to encrypt + * @param inOff offset into src buffer + * @param out out buffer where encrypted data is written + * @param outOff offset into out buffer + */ + private int EncryptBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + int A = BytesToWord(input, inOff) + _S[0]; + int B = BytesToWord(input, inOff + 4) + _S[1]; + + for (int i = 1; i <= _noRounds; i++) + { + A = RotateLeft(A ^ B, B) + _S[2*i]; + B = RotateLeft(B ^ A, A) + _S[2*i+1]; + } + + WordToBytes(A, outBytes, outOff); + WordToBytes(B, outBytes, outOff + 4); + + return 2 * 4; + } + + private int DecryptBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + int A = BytesToWord(input, inOff); + int B = BytesToWord(input, inOff + 4); + + for (int i = _noRounds; i >= 1; i--) + { + B = RotateRight(B - _S[2*i+1], A) ^ A; + A = RotateRight(A - _S[2*i], B) ^ B; + } + + WordToBytes(A - _S[0], outBytes, outOff); + WordToBytes(B - _S[1], outBytes, outOff + 4); + + return 2 * 4; + } + + + ////////////////////////////////////////////////////////////// + // + // PRIVATE Helper Methods + // + ////////////////////////////////////////////////////////////// + + /** + * Perform a left "spin" of the word. The rotation of the given + * word x is rotated left by y bits. + * Only the lg(32) low-order bits of y + * are used to determine the rotation amount. Here it is + * assumed that the wordsize used is a power of 2. + * + * @param x word to rotate + * @param y number of bits to rotate % 32 + */ + private int RotateLeft(int x, int y) { + return ((int) ( (uint) (x << (y & (32-1))) | + ((uint) x >> (32 - (y & (32-1)))) ) + ); + } + + /** + * Perform a right "spin" of the word. The rotation of the given + * word x is rotated left by y bits. + * Only the lg(32) low-order bits of y + * are used to determine the rotation amount. Here it is + * assumed that the wordsize used is a power of 2. + * + * @param x word to rotate + * @param y number of bits to rotate % 32 + */ + private int RotateRight(int x, int y) { + return ((int) ( ((uint) x >> (y & (32-1))) | + (uint) (x << (32 - (y & (32-1)))) ) + ); + } + + private int BytesToWord( + byte[] src, + int srcOff) + { + return (src[srcOff] & 0xff) | ((src[srcOff + 1] & 0xff) << 8) + | ((src[srcOff + 2] & 0xff) << 16) | ((src[srcOff + 3] & 0xff) << 24); + } + + private void WordToBytes( + int word, + byte[] dst, + int dstOff) + { + dst[dstOff] = (byte)word; + dst[dstOff + 1] = (byte)(word >> 8); + dst[dstOff + 2] = (byte)(word >> 16); + dst[dstOff + 3] = (byte)(word >> 24); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RC532Engine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RC532Engine.cs.meta new file mode 100644 index 0000000..b3fa00f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RC532Engine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a43358df0ccbd6e42b77f431540dfd1e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RC564Engine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RC564Engine.cs new file mode 100644 index 0000000..097fd60 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RC564Engine.cs @@ -0,0 +1,295 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * The specification for RC5 came from the RC5 Encryption Algorithm + * publication in RSA CryptoBytes, Spring of 1995. + * http://www.rsasecurity.com/rsalabs/cryptobytes. + *

+ * This implementation is set to work with a 64 bit word size.

+ */ + public class RC564Engine + : IBlockCipher + { + private static readonly int wordSize = 64; + private static readonly int bytesPerWord = wordSize / 8; + + /* + * the number of rounds to perform + */ + private int _noRounds; + + /* + * the expanded key array of size 2*(rounds + 1) + */ + private long [] _S; + + /* + * our "magic constants" for wordSize 62 + * + * Pw = Odd((e-2) * 2^wordsize) + * Qw = Odd((o-2) * 2^wordsize) + * + * where e is the base of natural logarithms (2.718281828...) + * and o is the golden ratio (1.61803398...) + */ + private static readonly long P64 = unchecked( (long) 0xb7e151628aed2a6bL); + private static readonly long Q64 = unchecked( (long) 0x9e3779b97f4a7c15L); + + private bool forEncryption; + + /** + * Create an instance of the RC5 encryption algorithm + * and set some defaults + */ + public RC564Engine() + { + _noRounds = 12; +// _S = null; + } + + public virtual string AlgorithmName + { + get { return "RC5-64"; } + } + + public virtual bool IsPartialBlockOkay + { + get { return false; } + } + + public virtual int GetBlockSize() + { + return 2 * bytesPerWord; + } + + /** + * initialise a RC5-64 cipher. + * + * @param forEncryption whether or not we are for encryption. + * @param parameters the parameters required to set up the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (!(typeof(RC5Parameters).IsInstanceOfType(parameters))) + { + throw new ArgumentException("invalid parameter passed to RC564 init - " + Platform.GetTypeName(parameters)); + } + + RC5Parameters p = (RC5Parameters)parameters; + + this.forEncryption = forEncryption; + + _noRounds = p.Rounds; + + SetKey(p.GetKey()); + } + + public virtual int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + return (forEncryption) ? EncryptBlock(input, inOff, output, outOff) + : DecryptBlock(input, inOff, output, outOff); + } + + public virtual void Reset() + { + } + + /** + * Re-key the cipher. + * + * @param key the key to be used + */ + private void SetKey( + byte[] key) + { + // + // KEY EXPANSION: + // + // There are 3 phases to the key expansion. + // + // Phase 1: + // Copy the secret key K[0...b-1] into an array L[0..c-1] of + // c = ceil(b/u), where u = wordSize/8 in little-endian order. + // In other words, we fill up L using u consecutive key bytes + // of K. Any unfilled byte positions in L are zeroed. In the + // case that b = c = 0, set c = 1 and L[0] = 0. + // + long[] L = new long[(key.Length + (bytesPerWord - 1)) / bytesPerWord]; + + for (int i = 0; i != key.Length; i++) + { + L[i / bytesPerWord] += (long)(key[i] & 0xff) << (8 * (i % bytesPerWord)); + } + + // + // Phase 2: + // Initialize S to a particular fixed pseudo-random bit pattern + // using an arithmetic progression modulo 2^wordsize determined + // by the magic numbers, Pw & Qw. + // + _S = new long[2*(_noRounds + 1)]; + + _S[0] = P64; + for (int i=1; i < _S.Length; i++) + { + _S[i] = (_S[i-1] + Q64); + } + + // + // Phase 3: + // Mix in the user's secret key in 3 passes over the arrays S & L. + // The max of the arrays sizes is used as the loop control + // + int iter; + + if (L.Length > _S.Length) + { + iter = 3 * L.Length; + } + else + { + iter = 3 * _S.Length; + } + + long A = 0, B = 0; + int ii = 0, jj = 0; + + for (int k = 0; k < iter; k++) + { + A = _S[ii] = RotateLeft(_S[ii] + A + B, 3); + B = L[jj] = RotateLeft( L[jj] + A + B, A+B); + ii = (ii+1) % _S.Length; + jj = (jj+1) % L.Length; + } + } + + /** + * Encrypt the given block starting at the given offset and place + * the result in the provided buffer starting at the given offset. + * + * @param in in byte buffer containing data to encrypt + * @param inOff offset into src buffer + * @param out out buffer where encrypted data is written + * @param outOff offset into out buffer + */ + private int EncryptBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + long A = BytesToWord(input, inOff) + _S[0]; + long B = BytesToWord(input, inOff + bytesPerWord) + _S[1]; + + for (int i = 1; i <= _noRounds; i++) + { + A = RotateLeft(A ^ B, B) + _S[2*i]; + B = RotateLeft(B ^ A, A) + _S[2*i+1]; + } + + WordToBytes(A, outBytes, outOff); + WordToBytes(B, outBytes, outOff + bytesPerWord); + + return 2 * bytesPerWord; + } + + private int DecryptBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + long A = BytesToWord(input, inOff); + long B = BytesToWord(input, inOff + bytesPerWord); + + for (int i = _noRounds; i >= 1; i--) + { + B = RotateRight(B - _S[2*i+1], A) ^ A; + A = RotateRight(A - _S[2*i], B) ^ B; + } + + WordToBytes(A - _S[0], outBytes, outOff); + WordToBytes(B - _S[1], outBytes, outOff + bytesPerWord); + + return 2 * bytesPerWord; + } + + + ////////////////////////////////////////////////////////////// + // + // PRIVATE Helper Methods + // + ////////////////////////////////////////////////////////////// + + /** + * Perform a left "spin" of the word. The rotation of the given + * word x is rotated left by y bits. + * Only the lg(wordSize) low-order bits of y + * are used to determine the rotation amount. Here it is + * assumed that the wordsize used is a power of 2. + * + * @param x word to rotate + * @param y number of bits to rotate % wordSize + */ + private long RotateLeft(long x, long y) { + return ((long) ( (ulong) (x << (int) (y & (wordSize-1))) | + ((ulong) x >> (int) (wordSize - (y & (wordSize-1))))) + ); + } + + /** + * Perform a right "spin" of the word. The rotation of the given + * word x is rotated left by y bits. + * Only the lg(wordSize) low-order bits of y + * are used to determine the rotation amount. Here it is + * assumed that the wordsize used is a power of 2. + * + * @param x word to rotate + * @param y number of bits to rotate % wordSize + */ + private long RotateRight(long x, long y) { + return ((long) ( ((ulong) x >> (int) (y & (wordSize-1))) | + (ulong) (x << (int) (wordSize - (y & (wordSize-1))))) + ); + } + + private long BytesToWord( + byte[] src, + int srcOff) + { + long word = 0; + + for (int i = bytesPerWord - 1; i >= 0; i--) + { + word = (word << 8) + (src[i + srcOff] & 0xff); + } + + return word; + } + + private void WordToBytes( + long word, + byte[] dst, + int dstOff) + { + for (int i = 0; i < bytesPerWord; i++) + { + dst[i + dstOff] = (byte)word; + word = (long) ((ulong) word >> 8); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RC564Engine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RC564Engine.cs.meta new file mode 100644 index 0000000..030973b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RC564Engine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ecfe9400ade05a640a2a4e1e95cb6722 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RC6Engine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RC6Engine.cs new file mode 100644 index 0000000..9aeb1e7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RC6Engine.cs @@ -0,0 +1,361 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * An RC6 engine. + */ + public class RC6Engine + : IBlockCipher + { + private static readonly int wordSize = 32; + private static readonly int bytesPerWord = wordSize / 8; + + /* + * the number of rounds to perform + */ + private static readonly int _noRounds = 20; + + /* + * the expanded key array of size 2*(rounds + 1) + */ + private int [] _S; + + /* + * our "magic constants" for wordSize 32 + * + * Pw = Odd((e-2) * 2^wordsize) + * Qw = Odd((o-2) * 2^wordsize) + * + * where e is the base of natural logarithms (2.718281828...) + * and o is the golden ratio (1.61803398...) + */ + private static readonly int P32 = unchecked((int) 0xb7e15163); + private static readonly int Q32 = unchecked((int) 0x9e3779b9); + + private static readonly int LGW = 5; // log2(32) + + private bool forEncryption; + + /** + * Create an instance of the RC6 encryption algorithm + * and set some defaults + */ + public RC6Engine() + { +// _S = null; + } + + public virtual string AlgorithmName + { + get { return "RC6"; } + } + + public virtual bool IsPartialBlockOkay + { + get { return false; } + } + + public virtual int GetBlockSize() + { + return 4 * bytesPerWord; + } + + /** + * initialise a RC5-32 cipher. + * + * @param forEncryption whether or not we are for encryption. + * @param parameters the parameters required to set up the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (!(parameters is KeyParameter)) + throw new ArgumentException("invalid parameter passed to RC6 init - " + Platform.GetTypeName(parameters)); + + this.forEncryption = forEncryption; + + KeyParameter p = (KeyParameter)parameters; + SetKey(p.GetKey()); + } + + public virtual int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + int blockSize = GetBlockSize(); + if (_S == null) + throw new InvalidOperationException("RC6 engine not initialised"); + + Check.DataLength(input, inOff, blockSize, "input buffer too short"); + Check.OutputLength(output, outOff, blockSize, "output buffer too short"); + + return (forEncryption) + ? EncryptBlock(input, inOff, output, outOff) + : DecryptBlock(input, inOff, output, outOff); + } + + public virtual void Reset() + { + } + + /** + * Re-key the cipher. + * + * @param inKey the key to be used + */ + private void SetKey( + byte[] key) + { + // + // KEY EXPANSION: + // + // There are 3 phases to the key expansion. + // + // Phase 1: + // Copy the secret key K[0...b-1] into an array L[0..c-1] of + // c = ceil(b/u), where u = wordSize/8 in little-endian order. + // In other words, we fill up L using u consecutive key bytes + // of K. Any unfilled byte positions in L are zeroed. In the + // case that b = c = 0, set c = 1 and L[0] = 0. + // + // compute number of dwords + int c = (key.Length + (bytesPerWord - 1)) / bytesPerWord; + if (c == 0) + { + c = 1; + } + int[] L = new int[(key.Length + bytesPerWord - 1) / bytesPerWord]; + + // load all key bytes into array of key dwords + for (int i = key.Length - 1; i >= 0; i--) + { + L[i / bytesPerWord] = (L[i / bytesPerWord] << 8) + (key[i] & 0xff); + } + + // + // Phase 2: + // Key schedule is placed in a array of 2+2*ROUNDS+2 = 44 dwords. + // Initialize S to a particular fixed pseudo-random bit pattern + // using an arithmetic progression modulo 2^wordsize determined + // by the magic numbers, Pw & Qw. + // + _S = new int[2+2*_noRounds+2]; + + _S[0] = P32; + for (int i=1; i < _S.Length; i++) + { + _S[i] = (_S[i-1] + Q32); + } + + // + // Phase 3: + // Mix in the user's secret key in 3 passes over the arrays S & L. + // The max of the arrays sizes is used as the loop control + // + int iter; + + if (L.Length > _S.Length) + { + iter = 3 * L.Length; + } + else + { + iter = 3 * _S.Length; + } + + int A = 0; + int B = 0; + int ii = 0, jj = 0; + + for (int k = 0; k < iter; k++) + { + A = _S[ii] = RotateLeft(_S[ii] + A + B, 3); + B = L[jj] = RotateLeft( L[jj] + A + B, A+B); + ii = (ii+1) % _S.Length; + jj = (jj+1) % L.Length; + } + } + + private int EncryptBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + // load A,B,C and D registers from in. + int A = BytesToWord(input, inOff); + int B = BytesToWord(input, inOff + bytesPerWord); + int C = BytesToWord(input, inOff + bytesPerWord*2); + int D = BytesToWord(input, inOff + bytesPerWord*3); + + // Do pseudo-round #0: pre-whitening of B and D + B += _S[0]; + D += _S[1]; + + // perform round #1,#2 ... #ROUNDS of encryption + for (int i = 1; i <= _noRounds; i++) + { + int t = 0,u = 0; + + t = B*(2*B+1); + t = RotateLeft(t,5); + + u = D*(2*D+1); + u = RotateLeft(u,5); + + A ^= t; + A = RotateLeft(A,u); + A += _S[2*i]; + + C ^= u; + C = RotateLeft(C,t); + C += _S[2*i+1]; + + int temp = A; + A = B; + B = C; + C = D; + D = temp; + } + // do pseudo-round #(ROUNDS+1) : post-whitening of A and C + A += _S[2*_noRounds+2]; + C += _S[2*_noRounds+3]; + + // store A, B, C and D registers to out + WordToBytes(A, outBytes, outOff); + WordToBytes(B, outBytes, outOff + bytesPerWord); + WordToBytes(C, outBytes, outOff + bytesPerWord*2); + WordToBytes(D, outBytes, outOff + bytesPerWord*3); + + return 4 * bytesPerWord; + } + + private int DecryptBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + // load A,B,C and D registers from out. + int A = BytesToWord(input, inOff); + int B = BytesToWord(input, inOff + bytesPerWord); + int C = BytesToWord(input, inOff + bytesPerWord*2); + int D = BytesToWord(input, inOff + bytesPerWord*3); + + // Undo pseudo-round #(ROUNDS+1) : post whitening of A and C + C -= _S[2*_noRounds+3]; + A -= _S[2*_noRounds+2]; + + // Undo round #ROUNDS, .., #2,#1 of encryption + for (int i = _noRounds; i >= 1; i--) + { + int t=0,u = 0; + + int temp = D; + D = C; + C = B; + B = A; + A = temp; + + t = B*(2*B+1); + t = RotateLeft(t, LGW); + + u = D*(2*D+1); + u = RotateLeft(u, LGW); + + C -= _S[2*i+1]; + C = RotateRight(C,t); + C ^= u; + + A -= _S[2*i]; + A = RotateRight(A,u); + A ^= t; + + } + // Undo pseudo-round #0: pre-whitening of B and D + D -= _S[1]; + B -= _S[0]; + + WordToBytes(A, outBytes, outOff); + WordToBytes(B, outBytes, outOff + bytesPerWord); + WordToBytes(C, outBytes, outOff + bytesPerWord*2); + WordToBytes(D, outBytes, outOff + bytesPerWord*3); + + return 4 * bytesPerWord; + } + + + ////////////////////////////////////////////////////////////// + // + // PRIVATE Helper Methods + // + ////////////////////////////////////////////////////////////// + + /** + * Perform a left "spin" of the word. The rotation of the given + * word x is rotated left by y bits. + * Only the lg(wordSize) low-order bits of y + * are used to determine the rotation amount. Here it is + * assumed that the wordsize used is a power of 2. + * + * @param x word to rotate + * @param y number of bits to rotate % wordSize + */ + private int RotateLeft(int x, int y) + { + return ((int)((uint)(x << (y & (wordSize-1))) + | ((uint) x >> (wordSize - (y & (wordSize-1)))))); + } + + /** + * Perform a right "spin" of the word. The rotation of the given + * word x is rotated left by y bits. + * Only the lg(wordSize) low-order bits of y + * are used to determine the rotation amount. Here it is + * assumed that the wordsize used is a power of 2. + * + * @param x word to rotate + * @param y number of bits to rotate % wordSize + */ + private int RotateRight(int x, int y) + { + return ((int)(((uint) x >> (y & (wordSize-1))) + | (uint)(x << (wordSize - (y & (wordSize-1)))))); + } + + private int BytesToWord( + byte[] src, + int srcOff) + { + int word = 0; + + for (int i = bytesPerWord - 1; i >= 0; i--) + { + word = (word << 8) + (src[i + srcOff] & 0xff); + } + + return word; + } + + private void WordToBytes( + int word, + byte[] dst, + int dstOff) + { + for (int i = 0; i < bytesPerWord; i++) + { + dst[i + dstOff] = (byte)word; + word = (int) ((uint) word >> 8); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RC6Engine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RC6Engine.cs.meta new file mode 100644 index 0000000..e80a388 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RC6Engine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4fe87d338dbeb084c846980143860169 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RFC3211WrapEngine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RFC3211WrapEngine.cs new file mode 100644 index 0000000..8648014 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RFC3211WrapEngine.cs @@ -0,0 +1,179 @@ +using System; + +using Org.BouncyCastle.Crypto.Modes; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * an implementation of the RFC 3211 Key Wrap + * Specification. + */ + public class Rfc3211WrapEngine + : IWrapper + { + private CbcBlockCipher engine; + private ParametersWithIV param; + private bool forWrapping; + private SecureRandom rand; + + public Rfc3211WrapEngine( + IBlockCipher engine) + { + this.engine = new CbcBlockCipher(engine); + } + + public virtual void Init( + bool forWrapping, + ICipherParameters param) + { + this.forWrapping = forWrapping; + + if (param is ParametersWithRandom) + { + ParametersWithRandom p = (ParametersWithRandom)param; + + this.rand = p.Random; + this.param = p.Parameters as ParametersWithIV; + } + else + { + if (forWrapping) + { + rand = new SecureRandom(); + } + + this.param = param as ParametersWithIV; + } + + if (null == this.param) + throw new ArgumentException("RFC3211Wrap requires an IV", "param"); + } + + public virtual string AlgorithmName + { + get { return engine.GetUnderlyingCipher().AlgorithmName + "/RFC3211Wrap"; } + } + + public virtual byte[] Wrap( + byte[] inBytes, + int inOff, + int inLen) + { + if (!forWrapping) + throw new InvalidOperationException("not set for wrapping"); + if (inLen > 255 || inLen < 0) + throw new ArgumentException("input must be from 0 to 255 bytes", "inLen"); + + engine.Init(true, param); + + int blockSize = engine.GetBlockSize(); + byte[] cekBlock; + + if (inLen + 4 < blockSize * 2) + { + cekBlock = new byte[blockSize * 2]; + } + else + { + cekBlock = new byte[(inLen + 4) % blockSize == 0 ? inLen + 4 : ((inLen + 4) / blockSize + 1) * blockSize]; + } + + cekBlock[0] = (byte)inLen; + + Array.Copy(inBytes, inOff, cekBlock, 4, inLen); + + rand.NextBytes(cekBlock, inLen + 4, cekBlock.Length - inLen - 4); + + cekBlock[1] = (byte)~cekBlock[4]; + cekBlock[2] = (byte)~cekBlock[4 + 1]; + cekBlock[3] = (byte)~cekBlock[4 + 2]; + + for (int i = 0; i < cekBlock.Length; i += blockSize) + { + engine.ProcessBlock(cekBlock, i, cekBlock, i); + } + + for (int i = 0; i < cekBlock.Length; i += blockSize) + { + engine.ProcessBlock(cekBlock, i, cekBlock, i); + } + + return cekBlock; + } + + public virtual byte[] Unwrap( + byte[] inBytes, + int inOff, + int inLen) + { + if (forWrapping) + { + throw new InvalidOperationException("not set for unwrapping"); + } + + int blockSize = engine.GetBlockSize(); + + if (inLen < 2 * blockSize) + { + throw new InvalidCipherTextException("input too short"); + } + + byte[] cekBlock = new byte[inLen]; + byte[] iv = new byte[blockSize]; + + Array.Copy(inBytes, inOff, cekBlock, 0, inLen); + Array.Copy(inBytes, inOff, iv, 0, iv.Length); + + engine.Init(false, new ParametersWithIV(param.Parameters, iv)); + + for (int i = blockSize; i < cekBlock.Length; i += blockSize) + { + engine.ProcessBlock(cekBlock, i, cekBlock, i); + } + + Array.Copy(cekBlock, cekBlock.Length - iv.Length, iv, 0, iv.Length); + + engine.Init(false, new ParametersWithIV(param.Parameters, iv)); + + engine.ProcessBlock(cekBlock, 0, cekBlock, 0); + + engine.Init(false, param); + + for (int i = 0; i < cekBlock.Length; i += blockSize) + { + engine.ProcessBlock(cekBlock, i, cekBlock, i); + } + + bool invalidLength = (int)cekBlock[0] > (cekBlock.Length - 4); + + byte[] key; + if (invalidLength) + { + key = new byte[cekBlock.Length - 4]; + } + else + { + key = new byte[cekBlock[0]]; + } + + Array.Copy(cekBlock, 4, key, 0, key.Length); + + // Note: Using constant time comparison + int nonEqual = 0; + for (int i = 0; i != 3; i++) + { + byte check = (byte)~cekBlock[1 + i]; + nonEqual |= (check ^ cekBlock[4 + i]); + } + + Array.Clear(cekBlock, 0, cekBlock.Length); + + if (nonEqual != 0 | invalidLength) + throw new InvalidCipherTextException("wrapped key corrupted"); + + return key; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RFC3211WrapEngine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RFC3211WrapEngine.cs.meta new file mode 100644 index 0000000..e0aee44 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RFC3211WrapEngine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 775ef0057b07b964a9a9fe0961d771b0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RFC3394WrapEngine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RFC3394WrapEngine.cs new file mode 100644 index 0000000..4bb0e21 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RFC3394WrapEngine.cs @@ -0,0 +1,178 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /// + /// An implementation of the AES Key Wrapper from the NIST Key Wrap + /// Specification as described in RFC 3394. + ///

+ /// For further details see: http://www.ietf.org/rfc/rfc3394.txt + /// and http://csrc.nist.gov/encryption/kms/key-wrap.pdf. + /// + public class Rfc3394WrapEngine + : IWrapper + { + private readonly IBlockCipher engine; + + private KeyParameter param; + private bool forWrapping; + + private byte[] iv = + { + 0xa6, 0xa6, 0xa6, 0xa6, + 0xa6, 0xa6, 0xa6, 0xa6 + }; + + public Rfc3394WrapEngine( + IBlockCipher engine) + { + this.engine = engine; + } + + public virtual void Init( + bool forWrapping, + ICipherParameters parameters) + { + this.forWrapping = forWrapping; + + if (parameters is ParametersWithRandom) + { + parameters = ((ParametersWithRandom) parameters).Parameters; + } + + if (parameters is KeyParameter) + { + this.param = (KeyParameter) parameters; + } + else if (parameters is ParametersWithIV) + { + ParametersWithIV pIV = (ParametersWithIV) parameters; + byte[] iv = pIV.GetIV(); + + if (iv.Length != 8) + throw new ArgumentException("IV length not equal to 8", "parameters"); + + this.iv = iv; + this.param = (KeyParameter) pIV.Parameters; + } + else + { + // TODO Throw an exception for bad parameters? + } + } + + public virtual string AlgorithmName + { + get { return engine.AlgorithmName; } + } + + public virtual byte[] Wrap( + byte[] input, + int inOff, + int inLen) + { + if (!forWrapping) + { + throw new InvalidOperationException("not set for wrapping"); + } + + int n = inLen / 8; + + if ((n * 8) != inLen) + { + throw new DataLengthException("wrap data must be a multiple of 8 bytes"); + } + + byte[] block = new byte[inLen + iv.Length]; + byte[] buf = new byte[8 + iv.Length]; + + Array.Copy(iv, 0, block, 0, iv.Length); + Array.Copy(input, inOff, block, iv.Length, inLen); + + engine.Init(true, param); + + for (int j = 0; j != 6; j++) + { + for (int i = 1; i <= n; i++) + { + Array.Copy(block, 0, buf, 0, iv.Length); + Array.Copy(block, 8 * i, buf, iv.Length, 8); + engine.ProcessBlock(buf, 0, buf, 0); + + int t = n * j + i; + for (int k = 1; t != 0; k++) + { + byte v = (byte)t; + + buf[iv.Length - k] ^= v; + t = (int) ((uint)t >> 8); + } + + Array.Copy(buf, 0, block, 0, 8); + Array.Copy(buf, 8, block, 8 * i, 8); + } + } + + return block; + } + + public virtual byte[] Unwrap( + byte[] input, + int inOff, + int inLen) + { + if (forWrapping) + { + throw new InvalidOperationException("not set for unwrapping"); + } + + int n = inLen / 8; + + if ((n * 8) != inLen) + { + throw new InvalidCipherTextException("unwrap data must be a multiple of 8 bytes"); + } + + byte[] block = new byte[inLen - iv.Length]; + byte[] a = new byte[iv.Length]; + byte[] buf = new byte[8 + iv.Length]; + + Array.Copy(input, inOff, a, 0, iv.Length); + Array.Copy(input, inOff + iv.Length, block, 0, inLen - iv.Length); + + engine.Init(false, param); + + n = n - 1; + + for (int j = 5; j >= 0; j--) + { + for (int i = n; i >= 1; i--) + { + Array.Copy(a, 0, buf, 0, iv.Length); + Array.Copy(block, 8 * (i - 1), buf, iv.Length, 8); + + int t = n * j + i; + for (int k = 1; t != 0; k++) + { + byte v = (byte)t; + + buf[iv.Length - k] ^= v; + t = (int) ((uint)t >> 8); + } + + engine.ProcessBlock(buf, 0, buf, 0); + Array.Copy(buf, 0, a, 0, 8); + Array.Copy(buf, 8, block, 8 * (i - 1), 8); + } + } + + if (!Arrays.ConstantTimeAreEqual(a, iv)) + throw new InvalidCipherTextException("checksum failed"); + + return block; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RFC3394WrapEngine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RFC3394WrapEngine.cs.meta new file mode 100644 index 0000000..b83333c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RFC3394WrapEngine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4d8902626ce1f68468d4e2e47acb4352 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RSABlindedEngine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RSABlindedEngine.cs new file mode 100644 index 0000000..637bf3c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RSABlindedEngine.cs @@ -0,0 +1,155 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * this does your basic RSA algorithm with blinding + */ + public class RsaBlindedEngine + : IAsymmetricBlockCipher + { + private readonly IRsa core; + + private RsaKeyParameters key; + private SecureRandom random; + + public RsaBlindedEngine() + : this(new RsaCoreEngine()) + { + } + + public RsaBlindedEngine(IRsa rsa) + { + this.core = rsa; + } + + public virtual string AlgorithmName + { + get { return "RSA"; } + } + + /** + * initialise the RSA engine. + * + * @param forEncryption true if we are encrypting, false otherwise. + * @param param the necessary RSA key parameters. + */ + public virtual void Init( + bool forEncryption, + ICipherParameters param) + { + core.Init(forEncryption, param); + + if (param is ParametersWithRandom) + { + ParametersWithRandom rParam = (ParametersWithRandom)param; + + this.key = (RsaKeyParameters)rParam.Parameters; + + if (key is RsaPrivateCrtKeyParameters) + { + this.random = rParam.Random; + } + else + { + this.random = null; + } + } + else + { + this.key = (RsaKeyParameters)param; + + if (key is RsaPrivateCrtKeyParameters) + { + this.random = new SecureRandom(); + } + else + { + this.random = null; + } + } + } + + /** + * Return the maximum size for an input block to this engine. + * For RSA this is always one byte less than the key size on + * encryption, and the same length as the key size on decryption. + * + * @return maximum size for an input block. + */ + public virtual int GetInputBlockSize() + { + return core.GetInputBlockSize(); + } + + /** + * Return the maximum size for an output block to this engine. + * For RSA this is always one byte less than the key size on + * decryption, and the same length as the key size on encryption. + * + * @return maximum size for an output block. + */ + public virtual int GetOutputBlockSize() + { + return core.GetOutputBlockSize(); + } + + /** + * Process a single block using the basic RSA algorithm. + * + * @param inBuf the input array. + * @param inOff the offset into the input buffer where the data starts. + * @param inLen the length of the data to be processed. + * @return the result of the RSA process. + * @exception DataLengthException the input block is too large. + */ + public virtual byte[] ProcessBlock( + byte[] inBuf, + int inOff, + int inLen) + { + if (key == null) + throw new InvalidOperationException("RSA engine not initialised"); + + BigInteger input = core.ConvertInput(inBuf, inOff, inLen); + + BigInteger result; + if (key is RsaPrivateCrtKeyParameters) + { + RsaPrivateCrtKeyParameters k = (RsaPrivateCrtKeyParameters)key; + BigInteger e = k.PublicExponent; + if (e != null) // can't do blinding without a public exponent + { + BigInteger m = k.Modulus; + BigInteger r = BigIntegers.CreateRandomInRange( + BigInteger.One, m.Subtract(BigInteger.One), random); + + BigInteger blindedInput = r.ModPow(e, m).Multiply(input).Mod(m); + BigInteger blindedResult = core.ProcessBlock(blindedInput); + + BigInteger rInv = BigIntegers.ModOddInverse(m, r); + result = blindedResult.Multiply(rInv).Mod(m); + + // defence against Arjen Lenstra’s CRT attack + if (!input.Equals(result.ModPow(e, m))) + throw new InvalidOperationException("RSA engine faulty decryption/signing detected"); + } + else + { + result = core.ProcessBlock(input); + } + } + else + { + result = core.ProcessBlock(input); + } + + return core.ConvertOutput(result); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RSABlindedEngine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RSABlindedEngine.cs.meta new file mode 100644 index 0000000..afeb94b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RSABlindedEngine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a7456372f02481941a17be1e45a9ce5c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RSABlindingEngine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RSABlindingEngine.cs new file mode 100644 index 0000000..11bb8d9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RSABlindingEngine.cs @@ -0,0 +1,150 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * This does your basic RSA Chaum's blinding and unblinding as outlined in + * "Handbook of Applied Cryptography", page 475. You need to use this if you are + * trying to get another party to generate signatures without them being aware + * of the message they are signing. + */ + public class RsaBlindingEngine + : IAsymmetricBlockCipher + { + private readonly IRsa core; + + private RsaKeyParameters key; + private BigInteger blindingFactor; + + private bool forEncryption; + + public RsaBlindingEngine() + : this(new RsaCoreEngine()) + { + } + + public RsaBlindingEngine(IRsa rsa) + { + this.core = rsa; + } + + public virtual string AlgorithmName + { + get { return "RSA"; } + } + + /** + * Initialise the blinding engine. + * + * @param forEncryption true if we are encrypting (blinding), false otherwise. + * @param param the necessary RSA key parameters. + */ + public virtual void Init( + bool forEncryption, + ICipherParameters param) + { + RsaBlindingParameters p; + + if (param is ParametersWithRandom) + { + ParametersWithRandom rParam = (ParametersWithRandom)param; + + p = (RsaBlindingParameters)rParam.Parameters; + } + else + { + p = (RsaBlindingParameters)param; + } + + core.Init(forEncryption, p.PublicKey); + + this.forEncryption = forEncryption; + this.key = p.PublicKey; + this.blindingFactor = p.BlindingFactor; + } + + /** + * Return the maximum size for an input block to this engine. + * For RSA this is always one byte less than the key size on + * encryption, and the same length as the key size on decryption. + * + * @return maximum size for an input block. + */ + public virtual int GetInputBlockSize() + { + return core.GetInputBlockSize(); + } + + /** + * Return the maximum size for an output block to this engine. + * For RSA this is always one byte less than the key size on + * decryption, and the same length as the key size on encryption. + * + * @return maximum size for an output block. + */ + public virtual int GetOutputBlockSize() + { + return core.GetOutputBlockSize(); + } + + /** + * Process a single block using the RSA blinding algorithm. + * + * @param in the input array. + * @param inOff the offset into the input buffer where the data starts. + * @param inLen the length of the data to be processed. + * @return the result of the RSA process. + * @throws DataLengthException the input block is too large. + */ + public virtual byte[] ProcessBlock( + byte[] inBuf, + int inOff, + int inLen) + { + BigInteger msg = core.ConvertInput(inBuf, inOff, inLen); + + if (forEncryption) + { + msg = BlindMessage(msg); + } + else + { + msg = UnblindMessage(msg); + } + + return core.ConvertOutput(msg); + } + + /* + * Blind message with the blind factor. + */ + private BigInteger BlindMessage( + BigInteger msg) + { + BigInteger blindMsg = blindingFactor; + blindMsg = msg.Multiply(blindMsg.ModPow(key.Exponent, key.Modulus)); + blindMsg = blindMsg.Mod(key.Modulus); + + return blindMsg; + } + + /* + * Unblind the message blinded with the blind factor. + */ + private BigInteger UnblindMessage( + BigInteger blindedMsg) + { + BigInteger m = key.Modulus; + BigInteger msg = blindedMsg; + BigInteger blindFactorInverse = BigIntegers.ModOddInverse(m, blindingFactor); + msg = msg.Multiply(blindFactorInverse); + msg = msg.Mod(m); + + return msg; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RSABlindingEngine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RSABlindingEngine.cs.meta new file mode 100644 index 0000000..84bb7d8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RSABlindingEngine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 34db85430984aa44092550e75ebae948 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RSACoreEngine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RSACoreEngine.cs new file mode 100644 index 0000000..5f6e98e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RSACoreEngine.cs @@ -0,0 +1,173 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * this does your basic RSA algorithm. + */ + public class RsaCoreEngine + : IRsa + { + private RsaKeyParameters key; + private bool forEncryption; + private int bitSize; + + private void CheckInitialised() + { + if (key == null) + throw new InvalidOperationException("RSA engine not initialised"); + } + + /** + * initialise the RSA engine. + * + * @param forEncryption true if we are encrypting, false otherwise. + * @param param the necessary RSA key parameters. + */ + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (parameters is ParametersWithRandom) + { + parameters = ((ParametersWithRandom) parameters).Parameters; + } + + if (!(parameters is RsaKeyParameters)) + throw new InvalidKeyException("Not an RSA key"); + + this.key = (RsaKeyParameters) parameters; + this.forEncryption = forEncryption; + this.bitSize = key.Modulus.BitLength; + } + + /** + * Return the maximum size for an input block to this engine. + * For RSA this is always one byte less than the key size on + * encryption, and the same length as the key size on decryption. + * + * @return maximum size for an input block. + */ + public virtual int GetInputBlockSize() + { + CheckInitialised(); + + if (forEncryption) + { + return (bitSize - 1) / 8; + } + + return (bitSize + 7) / 8; + } + + /** + * Return the maximum size for an output block to this engine. + * For RSA this is always one byte less than the key size on + * decryption, and the same length as the key size on encryption. + * + * @return maximum size for an output block. + */ + public virtual int GetOutputBlockSize() + { + CheckInitialised(); + + if (forEncryption) + { + return (bitSize + 7) / 8; + } + + return (bitSize - 1) / 8; + } + + public virtual BigInteger ConvertInput( + byte[] inBuf, + int inOff, + int inLen) + { + CheckInitialised(); + + int maxLength = (bitSize + 7) / 8; + + if (inLen > maxLength) + throw new DataLengthException("input too large for RSA cipher."); + + BigInteger input = new BigInteger(1, inBuf, inOff, inLen); + + if (input.CompareTo(key.Modulus) >= 0) + throw new DataLengthException("input too large for RSA cipher."); + + return input; + } + + public virtual byte[] ConvertOutput( + BigInteger result) + { + CheckInitialised(); + + byte[] output = result.ToByteArrayUnsigned(); + + if (forEncryption) + { + int outSize = GetOutputBlockSize(); + + // TODO To avoid this, create version of BigInteger.ToByteArray that + // writes to an existing array + if (output.Length < outSize) // have ended up with less bytes than normal, lengthen + { + byte[] tmp = new byte[outSize]; + output.CopyTo(tmp, tmp.Length - output.Length); + output = tmp; + } + } + + return output; + } + + public virtual BigInteger ProcessBlock( + BigInteger input) + { + CheckInitialised(); + + if (key is RsaPrivateCrtKeyParameters) + { + // + // we have the extra factors, use the Chinese Remainder Theorem - the author + // wishes to express his thanks to Dirk Bonekaemper at rtsffm.com for + // advice regarding the expression of this. + // + RsaPrivateCrtKeyParameters crtKey = (RsaPrivateCrtKeyParameters)key; + + BigInteger p = crtKey.P; + BigInteger q = crtKey.Q; + BigInteger dP = crtKey.DP; + BigInteger dQ = crtKey.DQ; + BigInteger qInv = crtKey.QInv; + + BigInteger mP, mQ, h, m; + + // mP = ((input Mod p) ^ dP)) Mod p + mP = (input.Remainder(p)).ModPow(dP, p); + + // mQ = ((input Mod q) ^ dQ)) Mod q + mQ = (input.Remainder(q)).ModPow(dQ, q); + + // h = qInv * (mP - mQ) Mod p + h = mP.Subtract(mQ); + h = h.Multiply(qInv); + h = h.Mod(p); // Mod (in Java) returns the positive residual + + // m = h * q + mQ + m = h.Multiply(q); + m = m.Add(mQ); + + return m; + } + + return input.ModPow(key.Exponent, key.Modulus); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RSACoreEngine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RSACoreEngine.cs.meta new file mode 100644 index 0000000..ea04610 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RSACoreEngine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 90280f9e8dabeac4e88378be56e925c2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RijndaelEngine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RijndaelEngine.cs new file mode 100644 index 0000000..7025cb5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RijndaelEngine.cs @@ -0,0 +1,738 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * an implementation of Rijndael, based on the documentation and reference implementation + * by Paulo Barreto, Vincent Rijmen, for v2.0 August '99. + *

+ * Note: this implementation is based on information prior to readonly NIST publication. + *

+ */ + public class RijndaelEngine + : IBlockCipher + { + private static readonly int MAXROUNDS = 14; + + private static readonly int MAXKC = (256/4); + + private static readonly byte[] Logtable = + { + 0, 0, 25, 1, 50, 2, 26, 198, + 75, 199, 27, 104, 51, 238, 223, 3, + 100, 4, 224, 14, 52, 141, 129, 239, + 76, 113, 8, 200, 248, 105, 28, 193, + 125, 194, 29, 181, 249, 185, 39, 106, + 77, 228, 166, 114, 154, 201, 9, 120, + 101, 47, 138, 5, 33, 15, 225, 36, + 18, 240, 130, 69, 53, 147, 218, 142, + 150, 143, 219, 189, 54, 208, 206, 148, + 19, 92, 210, 241, 64, 70, 131, 56, + 102, 221, 253, 48, 191, 6, 139, 98, + 179, 37, 226, 152, 34, 136, 145, 16, + 126, 110, 72, 195, 163, 182, 30, 66, + 58, 107, 40, 84, 250, 133, 61, 186, + 43, 121, 10, 21, 155, 159, 94, 202, + 78, 212, 172, 229, 243, 115, 167, 87, + 175, 88, 168, 80, 244, 234, 214, 116, + 79, 174, 233, 213, 231, 230, 173, 232, + 44, 215, 117, 122, 235, 22, 11, 245, + 89, 203, 95, 176, 156, 169, 81, 160, + 127, 12, 246, 111, 23, 196, 73, 236, + 216, 67, 31, 45, 164, 118, 123, 183, + 204, 187, 62, 90, 251, 96, 177, 134, + 59, 82, 161, 108, 170, 85, 41, 157, + 151, 178, 135, 144, 97, 190, 220, 252, + 188, 149, 207, 205, 55, 63, 91, 209, + 83, 57, 132, 60, 65, 162, 109, 71, + 20, 42, 158, 93, 86, 242, 211, 171, + 68, 17, 146, 217, 35, 32, 46, 137, + 180, 124, 184, 38, 119, 153, 227, 165, + 103, 74, 237, 222, 197, 49, 254, 24, + 13, 99, 140, 128, 192, 247, 112, 7 + }; + + private static readonly byte[] Alogtable = + { + 0, 3, 5, 15, 17, 51, 85, 255, 26, 46, 114, 150, 161, 248, 19, 53, + 95, 225, 56, 72, 216, 115, 149, 164, 247, 2, 6, 10, 30, 34, 102, 170, + 229, 52, 92, 228, 55, 89, 235, 38, 106, 190, 217, 112, 144, 171, 230, 49, + 83, 245, 4, 12, 20, 60, 68, 204, 79, 209, 104, 184, 211, 110, 178, 205, + 76, 212, 103, 169, 224, 59, 77, 215, 98, 166, 241, 8, 24, 40, 120, 136, + 131, 158, 185, 208, 107, 189, 220, 127, 129, 152, 179, 206, 73, 219, 118, 154, + 181, 196, 87, 249, 16, 48, 80, 240, 11, 29, 39, 105, 187, 214, 97, 163, + 254, 25, 43, 125, 135, 146, 173, 236, 47, 113, 147, 174, 233, 32, 96, 160, + 251, 22, 58, 78, 210, 109, 183, 194, 93, 231, 50, 86, 250, 21, 63, 65, + 195, 94, 226, 61, 71, 201, 64, 192, 91, 237, 44, 116, 156, 191, 218, 117, + 159, 186, 213, 100, 172, 239, 42, 126, 130, 157, 188, 223, 122, 142, 137, 128, + 155, 182, 193, 88, 232, 35, 101, 175, 234, 37, 111, 177, 200, 67, 197, 84, + 252, 31, 33, 99, 165, 244, 7, 9, 27, 45, 119, 153, 176, 203, 70, 202, + 69, 207, 74, 222, 121, 139, 134, 145, 168, 227, 62, 66, 198, 81, 243, 14, + 18, 54, 90, 238, 41, 123, 141, 140, 143, 138, 133, 148, 167, 242, 13, 23, + 57, 75, 221, 124, 132, 151, 162, 253, 28, 36, 108, 180, 199, 82, 246, 1, + 3, 5, 15, 17, 51, 85, 255, 26, 46, 114, 150, 161, 248, 19, 53, + 95, 225, 56, 72, 216, 115, 149, 164, 247, 2, 6, 10, 30, 34, 102, 170, + 229, 52, 92, 228, 55, 89, 235, 38, 106, 190, 217, 112, 144, 171, 230, 49, + 83, 245, 4, 12, 20, 60, 68, 204, 79, 209, 104, 184, 211, 110, 178, 205, + 76, 212, 103, 169, 224, 59, 77, 215, 98, 166, 241, 8, 24, 40, 120, 136, + 131, 158, 185, 208, 107, 189, 220, 127, 129, 152, 179, 206, 73, 219, 118, 154, + 181, 196, 87, 249, 16, 48, 80, 240, 11, 29, 39, 105, 187, 214, 97, 163, + 254, 25, 43, 125, 135, 146, 173, 236, 47, 113, 147, 174, 233, 32, 96, 160, + 251, 22, 58, 78, 210, 109, 183, 194, 93, 231, 50, 86, 250, 21, 63, 65, + 195, 94, 226, 61, 71, 201, 64, 192, 91, 237, 44, 116, 156, 191, 218, 117, + 159, 186, 213, 100, 172, 239, 42, 126, 130, 157, 188, 223, 122, 142, 137, 128, + 155, 182, 193, 88, 232, 35, 101, 175, 234, 37, 111, 177, 200, 67, 197, 84, + 252, 31, 33, 99, 165, 244, 7, 9, 27, 45, 119, 153, 176, 203, 70, 202, + 69, 207, 74, 222, 121, 139, 134, 145, 168, 227, 62, 66, 198, 81, 243, 14, + 18, 54, 90, 238, 41, 123, 141, 140, 143, 138, 133, 148, 167, 242, 13, 23, + 57, 75, 221, 124, 132, 151, 162, 253, 28, 36, 108, 180, 199, 82, 246, 1, + }; + + private static readonly byte[] S = + { + 99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, 118, + 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, 114, 192, + 183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, 216, 49, 21, + 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, 235, 39, 178, 117, + 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, 179, 41, 227, 47, 132, + 83, 209, 0, 237, 32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207, + 208, 239, 170, 251, 67, 77, 51, 133, 69, 249, 2, 127, 80, 60, 159, 168, + 81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255, 243, 210, + 205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61, 100, 93, 25, 115, + 96, 129, 79, 220, 34, 42, 144, 136, 70, 238, 184, 20, 222, 94, 11, 219, + 224, 50, 58, 10, 73, 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121, + 231, 200, 55, 109, 141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, + 186, 120, 37, 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, + 112, 62, 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158, + 225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223, + 140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, 22, + }; + + private static readonly byte[] Si = + { + 82, 9, 106, 213, 48, 54, 165, 56, 191, 64, 163, 158, 129, 243, 215, 251, + 124, 227, 57, 130, 155, 47, 255, 135, 52, 142, 67, 68, 196, 222, 233, 203, + 84, 123, 148, 50, 166, 194, 35, 61, 238, 76, 149, 11, 66, 250, 195, 78, + 8, 46, 161, 102, 40, 217, 36, 178, 118, 91, 162, 73, 109, 139, 209, 37, + 114, 248, 246, 100, 134, 104, 152, 22, 212, 164, 92, 204, 93, 101, 182, 146, + 108, 112, 72, 80, 253, 237, 185, 218, 94, 21, 70, 87, 167, 141, 157, 132, + 144, 216, 171, 0, 140, 188, 211, 10, 247, 228, 88, 5, 184, 179, 69, 6, + 208, 44, 30, 143, 202, 63, 15, 2, 193, 175, 189, 3, 1, 19, 138, 107, + 58, 145, 17, 65, 79, 103, 220, 234, 151, 242, 207, 206, 240, 180, 230, 115, + 150, 172, 116, 34, 231, 173, 53, 133, 226, 249, 55, 232, 28, 117, 223, 110, + 71, 241, 26, 113, 29, 41, 197, 137, 111, 183, 98, 14, 170, 24, 190, 27, + 252, 86, 62, 75, 198, 210, 121, 32, 154, 219, 192, 254, 120, 205, 90, 244, + 31, 221, 168, 51, 136, 7, 199, 49, 177, 18, 16, 89, 39, 128, 236, 95, + 96, 81, 127, 169, 25, 181, 74, 13, 45, 229, 122, 159, 147, 201, 156, 239, + 160, 224, 59, 77, 174, 42, 245, 176, 200, 235, 187, 60, 131, 83, 153, 97, + 23, 43, 4, 126, 186, 119, 214, 38, 225, 105, 20, 99, 85, 33, 12, 125, + }; + + private static readonly byte[] rcon = + { + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, + 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91 + }; + + static readonly byte[][] shifts0 = new byte [][] + { + new byte[]{ 0, 8, 16, 24 }, + new byte[]{ 0, 8, 16, 24 }, + new byte[]{ 0, 8, 16, 24 }, + new byte[]{ 0, 8, 16, 32 }, + new byte[]{ 0, 8, 24, 32 } + }; + + static readonly byte[][] shifts1 = + { + new byte[]{ 0, 24, 16, 8 }, + new byte[]{ 0, 32, 24, 16 }, + new byte[]{ 0, 40, 32, 24 }, + new byte[]{ 0, 48, 40, 24 }, + new byte[]{ 0, 56, 40, 32 } + }; + + /** + * multiply two elements of GF(2^m) + * needed for MixColumn and InvMixColumn + */ + private byte Mul0x2( + int b) + { + if (b != 0) + { + return Alogtable[25 + (Logtable[b] & 0xff)]; + } + else + { + return 0; + } + } + + private byte Mul0x3( + int b) + { + if (b != 0) + { + return Alogtable[1 + (Logtable[b] & 0xff)]; + } + else + { + return 0; + } + } + + private byte Mul0x9( + int b) + { + if (b >= 0) + { + return Alogtable[199 + b]; + } + else + { + return 0; + } + } + + private byte Mul0xb( + int b) + { + if (b >= 0) + { + return Alogtable[104 + b]; + } + else + { + return 0; + } + } + + private byte Mul0xd( + int b) + { + if (b >= 0) + { + return Alogtable[238 + b]; + } + else + { + return 0; + } + } + + private byte Mul0xe( + int b) + { + if (b >= 0) + { + return Alogtable[223 + b]; + } + else + { + return 0; + } + } + + /** + * xor corresponding text input and round key input bytes + */ + private void KeyAddition( + long[] rk) + { + A0 ^= rk[0]; + A1 ^= rk[1]; + A2 ^= rk[2]; + A3 ^= rk[3]; + } + + private long Shift( + long r, + int shift) + { + //return (((long)((ulong) r >> shift) | (r << (BC - shift)))) & BC_MASK; + + ulong temp = (ulong) r >> shift; + + // NB: This corrects for Mono Bug #79087 (fixed in 1.1.17) + if (shift > 31) + { + temp &= 0xFFFFFFFFUL; + } + + return ((long) temp | (r << (BC - shift))) & BC_MASK; + } + + /** + * Row 0 remains unchanged + * The other three rows are shifted a variable amount + */ + private void ShiftRow( + byte[] shiftsSC) + { + A1 = Shift(A1, shiftsSC[1]); + A2 = Shift(A2, shiftsSC[2]); + A3 = Shift(A3, shiftsSC[3]); + } + + private long ApplyS( + long r, + byte[] box) + { + long res = 0; + + for (int j = 0; j < BC; j += 8) + { + res |= (long)(box[(int)((r >> j) & 0xff)] & 0xff) << j; + } + + return res; + } + + /** + * Replace every byte of the input by the byte at that place + * in the nonlinear S-box + */ + private void Substitution( + byte[] box) + { + A0 = ApplyS(A0, box); + A1 = ApplyS(A1, box); + A2 = ApplyS(A2, box); + A3 = ApplyS(A3, box); + } + + /** + * Mix the bytes of every column in a linear way + */ + private void MixColumn() + { + long r0, r1, r2, r3; + + r0 = r1 = r2 = r3 = 0; + + for (int j = 0; j < BC; j += 8) + { + int a0 = (int)((A0 >> j) & 0xff); + int a1 = (int)((A1 >> j) & 0xff); + int a2 = (int)((A2 >> j) & 0xff); + int a3 = (int)((A3 >> j) & 0xff); + + r0 |= (long)((Mul0x2(a0) ^ Mul0x3(a1) ^ a2 ^ a3) & 0xff) << j; + + r1 |= (long)((Mul0x2(a1) ^ Mul0x3(a2) ^ a3 ^ a0) & 0xff) << j; + + r2 |= (long)((Mul0x2(a2) ^ Mul0x3(a3) ^ a0 ^ a1) & 0xff) << j; + + r3 |= (long)((Mul0x2(a3) ^ Mul0x3(a0) ^ a1 ^ a2) & 0xff) << j; + } + + A0 = r0; + A1 = r1; + A2 = r2; + A3 = r3; + } + + /** + * Mix the bytes of every column in a linear way + * This is the opposite operation of Mixcolumn + */ + private void InvMixColumn() + { + long r0, r1, r2, r3; + + r0 = r1 = r2 = r3 = 0; + for (int j = 0; j < BC; j += 8) + { + int a0 = (int)((A0 >> j) & 0xff); + int a1 = (int)((A1 >> j) & 0xff); + int a2 = (int)((A2 >> j) & 0xff); + int a3 = (int)((A3 >> j) & 0xff); + + // + // pre-lookup the log table + // + a0 = (a0 != 0) ? (Logtable[a0 & 0xff] & 0xff) : -1; + a1 = (a1 != 0) ? (Logtable[a1 & 0xff] & 0xff) : -1; + a2 = (a2 != 0) ? (Logtable[a2 & 0xff] & 0xff) : -1; + a3 = (a3 != 0) ? (Logtable[a3 & 0xff] & 0xff) : -1; + + r0 |= (long)((Mul0xe(a0) ^ Mul0xb(a1) ^ Mul0xd(a2) ^ Mul0x9(a3)) & 0xff) << j; + + r1 |= (long)((Mul0xe(a1) ^ Mul0xb(a2) ^ Mul0xd(a3) ^ Mul0x9(a0)) & 0xff) << j; + + r2 |= (long)((Mul0xe(a2) ^ Mul0xb(a3) ^ Mul0xd(a0) ^ Mul0x9(a1)) & 0xff) << j; + + r3 |= (long)((Mul0xe(a3) ^ Mul0xb(a0) ^ Mul0xd(a1) ^ Mul0x9(a2)) & 0xff) << j; + } + + A0 = r0; + A1 = r1; + A2 = r2; + A3 = r3; + } + + /** + * Calculate the necessary round keys + * The number of calculations depends on keyBits and blockBits + */ + private long[][] GenerateWorkingKey( + byte[] key) + { + int KC; + int t, rconpointer = 0; + int keyBits = key.Length * 8; + byte[,] tk = new byte[4,MAXKC]; + //long[,] W = new long[MAXROUNDS+1,4]; + long[][] W = new long[MAXROUNDS+1][]; + + for (int i = 0; i < MAXROUNDS+1; i++) W[i] = new long[4]; + + switch (keyBits) + { + case 128: + KC = 4; + break; + case 160: + KC = 5; + break; + case 192: + KC = 6; + break; + case 224: + KC = 7; + break; + case 256: + KC = 8; + break; + default : + throw new ArgumentException("Key length not 128/160/192/224/256 bits."); + } + + if (keyBits >= blockBits) + { + ROUNDS = KC + 6; + } + else + { + ROUNDS = (BC / 8) + 6; + } + + // + // copy the key into the processing area + // + int index = 0; + + for (int i = 0; i < key.Length; i++) + { + tk[i % 4,i / 4] = key[index++]; + } + + t = 0; + + // + // copy values into round key array + // + for (int j = 0; (j < KC) && (t < (ROUNDS+1)*(BC / 8)); j++, t++) + { + for (int i = 0; i < 4; i++) + { + W[t / (BC / 8)][i] |= (long)(tk[i,j] & 0xff) << ((t * 8) % BC); + } + } + + // + // while not enough round key material calculated + // calculate new values + // + while (t < (ROUNDS+1)*(BC/8)) + { + for (int i = 0; i < 4; i++) + { + tk[i,0] ^= S[tk[(i+1)%4,KC-1] & 0xff]; + } + tk[0,0] ^= (byte) rcon[rconpointer++]; + + if (KC <= 6) + { + for (int j = 1; j < KC; j++) + { + for (int i = 0; i < 4; i++) + { + tk[i,j] ^= tk[i,j-1]; + } + } + } + else + { + for (int j = 1; j < 4; j++) + { + for (int i = 0; i < 4; i++) + { + tk[i,j] ^= tk[i,j-1]; + } + } + for (int i = 0; i < 4; i++) + { + tk[i,4] ^= S[tk[i,3] & 0xff]; + } + for (int j = 5; j < KC; j++) + { + for (int i = 0; i < 4; i++) + { + tk[i,j] ^= tk[i,j-1]; + } + } + } + + // + // copy values into round key array + // + for (int j = 0; (j < KC) && (t < (ROUNDS+1)*(BC/8)); j++, t++) + { + for (int i = 0; i < 4; i++) + { + W[t / (BC/8)][i] |= (long)(tk[i,j] & 0xff) << ((t * 8) % (BC)); + } + } + } + return W; + } + + private int BC; + private long BC_MASK; + private int ROUNDS; + private int blockBits; + private long[][] workingKey; + private long A0, A1, A2, A3; + private bool forEncryption; + private byte[] shifts0SC; + private byte[] shifts1SC; + + /** + * default constructor - 128 bit block size. + */ + public RijndaelEngine() : this(128) {} + + /** + * basic constructor - set the cipher up for a given blocksize + * + * @param blocksize the blocksize in bits, must be 128, 192, or 256. + */ + public RijndaelEngine( + int blockBits) + { + switch (blockBits) + { + case 128: + BC = 32; + BC_MASK = 0xffffffffL; + shifts0SC = shifts0[0]; + shifts1SC = shifts1[0]; + break; + case 160: + BC = 40; + BC_MASK = 0xffffffffffL; + shifts0SC = shifts0[1]; + shifts1SC = shifts1[1]; + break; + case 192: + BC = 48; + BC_MASK = 0xffffffffffffL; + shifts0SC = shifts0[2]; + shifts1SC = shifts1[2]; + break; + case 224: + BC = 56; + BC_MASK = 0xffffffffffffffL; + shifts0SC = shifts0[3]; + shifts1SC = shifts1[3]; + break; + case 256: + BC = 64; + BC_MASK = unchecked( (long)0xffffffffffffffffL); + shifts0SC = shifts0[4]; + shifts1SC = shifts1[4]; + break; + default: + throw new ArgumentException("unknown blocksize to Rijndael"); + } + + this.blockBits = blockBits; + } + + /** + * initialise a Rijndael cipher. + * + * @param forEncryption whether or not we are for encryption. + * @param parameters the parameters required to set up the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (typeof(KeyParameter).IsInstanceOfType(parameters)) + { + workingKey = GenerateWorkingKey(((KeyParameter)parameters).GetKey()); + this.forEncryption = forEncryption; + return; + } + + throw new ArgumentException("invalid parameter passed to Rijndael init - " + Platform.GetTypeName(parameters)); + } + + public virtual string AlgorithmName + { + get { return "Rijndael"; } + } + + public virtual bool IsPartialBlockOkay + { + get { return false; } + } + + public virtual int GetBlockSize() + { + return BC / 2; + } + + public virtual int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + if (workingKey == null) + throw new InvalidOperationException("Rijndael engine not initialised"); + + Check.DataLength(input, inOff, (BC / 2), "input buffer too short"); + Check.OutputLength(output, outOff, (BC / 2), "output buffer too short"); + + UnPackBlock(input, inOff); + + if (forEncryption) + { + EncryptBlock(workingKey); + } + else + { + DecryptBlock(workingKey); + } + + PackBlock(output, outOff); + + return BC / 2; + } + + public virtual void Reset() + { + } + + private void UnPackBlock( + byte[] bytes, + int off) + { + int index = off; + + A0 = (long)(bytes[index++] & 0xff); + A1 = (long)(bytes[index++] & 0xff); + A2 = (long)(bytes[index++] & 0xff); + A3 = (long)(bytes[index++] & 0xff); + + for (int j = 8; j != BC; j += 8) + { + A0 |= (long)(bytes[index++] & 0xff) << j; + A1 |= (long)(bytes[index++] & 0xff) << j; + A2 |= (long)(bytes[index++] & 0xff) << j; + A3 |= (long)(bytes[index++] & 0xff) << j; + } + } + + private void PackBlock( + byte[] bytes, + int off) + { + int index = off; + + for (int j = 0; j != BC; j += 8) + { + bytes[index++] = (byte)(A0 >> j); + bytes[index++] = (byte)(A1 >> j); + bytes[index++] = (byte)(A2 >> j); + bytes[index++] = (byte)(A3 >> j); + } + } + + private void EncryptBlock( + long[][] rk) + { + int r; + + // + // begin with a key addition + // + KeyAddition(rk[0]); + + // + // ROUNDS-1 ordinary rounds + // + for (r = 1; r < ROUNDS; r++) + { + Substitution(S); + ShiftRow(shifts0SC); + MixColumn(); + KeyAddition(rk[r]); + } + + // + // Last round is special: there is no MixColumn + // + Substitution(S); + ShiftRow(shifts0SC); + KeyAddition(rk[ROUNDS]); + } + + private void DecryptBlock( + long[][] rk) + { + int r; + + // To decrypt: apply the inverse operations of the encrypt routine, + // in opposite order + // + // (KeyAddition is an involution: it 's equal to its inverse) + // (the inverse of Substitution with table S is Substitution with the inverse table of S) + // (the inverse of Shiftrow is Shiftrow over a suitable distance) + // + + // First the special round: + // without InvMixColumn + // with extra KeyAddition + // + KeyAddition(rk[ROUNDS]); + Substitution(Si); + ShiftRow(shifts1SC); + + // + // ROUNDS-1 ordinary rounds + // + for (r = ROUNDS-1; r > 0; r--) + { + KeyAddition(rk[r]); + InvMixColumn(); + Substitution(Si); + ShiftRow(shifts1SC); + } + + // + // End with the extra key addition + // + KeyAddition(rk[0]); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RijndaelEngine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RijndaelEngine.cs.meta new file mode 100644 index 0000000..9e2ad08 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RijndaelEngine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 671be4bd78954b24ca42a1f65e3ea55f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RsaEngine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RsaEngine.cs new file mode 100644 index 0000000..95bfb23 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RsaEngine.cs @@ -0,0 +1,86 @@ +using System; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * this does your basic RSA algorithm. + */ + public class RsaEngine + : IAsymmetricBlockCipher + { + private readonly IRsa core; + + public RsaEngine() + : this(new RsaCoreEngine()) + { + } + + public RsaEngine(IRsa rsa) + { + this.core = rsa; + } + + public virtual string AlgorithmName + { + get { return "RSA"; } + } + + /** + * initialise the RSA engine. + * + * @param forEncryption true if we are encrypting, false otherwise. + * @param param the necessary RSA key parameters. + */ + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + core.Init(forEncryption, parameters); + } + + /** + * Return the maximum size for an input block to this engine. + * For RSA this is always one byte less than the key size on + * encryption, and the same length as the key size on decryption. + * + * @return maximum size for an input block. + */ + public virtual int GetInputBlockSize() + { + return core.GetInputBlockSize(); + } + + /** + * Return the maximum size for an output block to this engine. + * For RSA this is always one byte less than the key size on + * decryption, and the same length as the key size on encryption. + * + * @return maximum size for an output block. + */ + public virtual int GetOutputBlockSize() + { + return core.GetOutputBlockSize(); + } + + /** + * Process a single block using the basic RSA algorithm. + * + * @param inBuf the input array. + * @param inOff the offset into the input buffer where the data starts. + * @param inLen the length of the data to be processed. + * @return the result of the RSA process. + * @exception DataLengthException the input block is too large. + */ + public virtual byte[] ProcessBlock( + byte[] inBuf, + int inOff, + int inLen) + { + BigInteger input = core.ConvertInput(inBuf, inOff, inLen); + BigInteger output = core.ProcessBlock(input); + return core.ConvertOutput(output); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RsaEngine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RsaEngine.cs.meta new file mode 100644 index 0000000..f7f70be --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/RsaEngine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4fc96b472bef149468fdb8693ce7f117 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/SEEDEngine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/SEEDEngine.cs new file mode 100644 index 0000000..f615b84 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/SEEDEngine.cs @@ -0,0 +1,360 @@ +using System; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * Implementation of the SEED algorithm as described in RFC 4009 + */ + public class SeedEngine + : IBlockCipher + { + private const int BlockSize = 16; + + private static readonly uint[] SS0 = + { + 0x2989a1a8, 0x05858184, 0x16c6d2d4, 0x13c3d3d0, 0x14445054, 0x1d0d111c, 0x2c8ca0ac, 0x25052124, + 0x1d4d515c, 0x03434340, 0x18081018, 0x1e0e121c, 0x11415150, 0x3cccf0fc, 0x0acac2c8, 0x23436360, + 0x28082028, 0x04444044, 0x20002020, 0x1d8d919c, 0x20c0e0e0, 0x22c2e2e0, 0x08c8c0c8, 0x17071314, + 0x2585a1a4, 0x0f8f838c, 0x03030300, 0x3b4b7378, 0x3b8bb3b8, 0x13031310, 0x12c2d2d0, 0x2ecee2ec, + 0x30407070, 0x0c8c808c, 0x3f0f333c, 0x2888a0a8, 0x32023230, 0x1dcdd1dc, 0x36c6f2f4, 0x34447074, + 0x2ccce0ec, 0x15859194, 0x0b0b0308, 0x17475354, 0x1c4c505c, 0x1b4b5358, 0x3d8db1bc, 0x01010100, + 0x24042024, 0x1c0c101c, 0x33437370, 0x18889098, 0x10001010, 0x0cccc0cc, 0x32c2f2f0, 0x19c9d1d8, + 0x2c0c202c, 0x27c7e3e4, 0x32427270, 0x03838380, 0x1b8b9398, 0x11c1d1d0, 0x06868284, 0x09c9c1c8, + 0x20406060, 0x10405050, 0x2383a3a0, 0x2bcbe3e8, 0x0d0d010c, 0x3686b2b4, 0x1e8e929c, 0x0f4f434c, + 0x3787b3b4, 0x1a4a5258, 0x06c6c2c4, 0x38487078, 0x2686a2a4, 0x12021210, 0x2f8fa3ac, 0x15c5d1d4, + 0x21416160, 0x03c3c3c0, 0x3484b0b4, 0x01414140, 0x12425250, 0x3d4d717c, 0x0d8d818c, 0x08080008, + 0x1f0f131c, 0x19899198, 0x00000000, 0x19091118, 0x04040004, 0x13435350, 0x37c7f3f4, 0x21c1e1e0, + 0x3dcdf1fc, 0x36467274, 0x2f0f232c, 0x27072324, 0x3080b0b0, 0x0b8b8388, 0x0e0e020c, 0x2b8ba3a8, + 0x2282a2a0, 0x2e4e626c, 0x13839390, 0x0d4d414c, 0x29496168, 0x3c4c707c, 0x09090108, 0x0a0a0208, + 0x3f8fb3bc, 0x2fcfe3ec, 0x33c3f3f0, 0x05c5c1c4, 0x07878384, 0x14041014, 0x3ecef2fc, 0x24446064, + 0x1eced2dc, 0x2e0e222c, 0x0b4b4348, 0x1a0a1218, 0x06060204, 0x21012120, 0x2b4b6368, 0x26466264, + 0x02020200, 0x35c5f1f4, 0x12829290, 0x0a8a8288, 0x0c0c000c, 0x3383b3b0, 0x3e4e727c, 0x10c0d0d0, + 0x3a4a7278, 0x07474344, 0x16869294, 0x25c5e1e4, 0x26062224, 0x00808080, 0x2d8da1ac, 0x1fcfd3dc, + 0x2181a1a0, 0x30003030, 0x37073334, 0x2e8ea2ac, 0x36063234, 0x15051114, 0x22022220, 0x38083038, + 0x34c4f0f4, 0x2787a3a4, 0x05454144, 0x0c4c404c, 0x01818180, 0x29c9e1e8, 0x04848084, 0x17879394, + 0x35053134, 0x0bcbc3c8, 0x0ecec2cc, 0x3c0c303c, 0x31417170, 0x11011110, 0x07c7c3c4, 0x09898188, + 0x35457174, 0x3bcbf3f8, 0x1acad2d8, 0x38c8f0f8, 0x14849094, 0x19495158, 0x02828280, 0x04c4c0c4, + 0x3fcff3fc, 0x09494148, 0x39093138, 0x27476364, 0x00c0c0c0, 0x0fcfc3cc, 0x17c7d3d4, 0x3888b0b8, + 0x0f0f030c, 0x0e8e828c, 0x02424240, 0x23032320, 0x11819190, 0x2c4c606c, 0x1bcbd3d8, 0x2484a0a4, + 0x34043034, 0x31c1f1f0, 0x08484048, 0x02c2c2c0, 0x2f4f636c, 0x3d0d313c, 0x2d0d212c, 0x00404040, + 0x3e8eb2bc, 0x3e0e323c, 0x3c8cb0bc, 0x01c1c1c0, 0x2a8aa2a8, 0x3a8ab2b8, 0x0e4e424c, 0x15455154, + 0x3b0b3338, 0x1cccd0dc, 0x28486068, 0x3f4f737c, 0x1c8c909c, 0x18c8d0d8, 0x0a4a4248, 0x16465254, + 0x37477374, 0x2080a0a0, 0x2dcde1ec, 0x06464244, 0x3585b1b4, 0x2b0b2328, 0x25456164, 0x3acaf2f8, + 0x23c3e3e0, 0x3989b1b8, 0x3181b1b0, 0x1f8f939c, 0x1e4e525c, 0x39c9f1f8, 0x26c6e2e4, 0x3282b2b0, + 0x31013130, 0x2acae2e8, 0x2d4d616c, 0x1f4f535c, 0x24c4e0e4, 0x30c0f0f0, 0x0dcdc1cc, 0x08888088, + 0x16061214, 0x3a0a3238, 0x18485058, 0x14c4d0d4, 0x22426260, 0x29092128, 0x07070304, 0x33033330, + 0x28c8e0e8, 0x1b0b1318, 0x05050104, 0x39497178, 0x10809090, 0x2a4a6268, 0x2a0a2228, 0x1a8a9298 + }; + + private static readonly uint[] SS1 = + { + 0x38380830, 0xe828c8e0, 0x2c2d0d21, 0xa42686a2, 0xcc0fcfc3, 0xdc1eced2, 0xb03383b3, 0xb83888b0, + 0xac2f8fa3, 0x60204060, 0x54154551, 0xc407c7c3, 0x44044440, 0x6c2f4f63, 0x682b4b63, 0x581b4b53, + 0xc003c3c3, 0x60224262, 0x30330333, 0xb43585b1, 0x28290921, 0xa02080a0, 0xe022c2e2, 0xa42787a3, + 0xd013c3d3, 0x90118191, 0x10110111, 0x04060602, 0x1c1c0c10, 0xbc3c8cb0, 0x34360632, 0x480b4b43, + 0xec2fcfe3, 0x88088880, 0x6c2c4c60, 0xa82888a0, 0x14170713, 0xc404c4c0, 0x14160612, 0xf434c4f0, + 0xc002c2c2, 0x44054541, 0xe021c1e1, 0xd416c6d2, 0x3c3f0f33, 0x3c3d0d31, 0x8c0e8e82, 0x98188890, + 0x28280820, 0x4c0e4e42, 0xf436c6f2, 0x3c3e0e32, 0xa42585a1, 0xf839c9f1, 0x0c0d0d01, 0xdc1fcfd3, + 0xd818c8d0, 0x282b0b23, 0x64264662, 0x783a4a72, 0x24270723, 0x2c2f0f23, 0xf031c1f1, 0x70324272, + 0x40024242, 0xd414c4d0, 0x40014141, 0xc000c0c0, 0x70334373, 0x64274763, 0xac2c8ca0, 0x880b8b83, + 0xf437c7f3, 0xac2d8da1, 0x80008080, 0x1c1f0f13, 0xc80acac2, 0x2c2c0c20, 0xa82a8aa2, 0x34340430, + 0xd012c2d2, 0x080b0b03, 0xec2ecee2, 0xe829c9e1, 0x5c1d4d51, 0x94148490, 0x18180810, 0xf838c8f0, + 0x54174753, 0xac2e8ea2, 0x08080800, 0xc405c5c1, 0x10130313, 0xcc0dcdc1, 0x84068682, 0xb83989b1, + 0xfc3fcff3, 0x7c3d4d71, 0xc001c1c1, 0x30310131, 0xf435c5f1, 0x880a8a82, 0x682a4a62, 0xb03181b1, + 0xd011c1d1, 0x20200020, 0xd417c7d3, 0x00020202, 0x20220222, 0x04040400, 0x68284860, 0x70314171, + 0x04070703, 0xd81bcbd3, 0x9c1d8d91, 0x98198991, 0x60214161, 0xbc3e8eb2, 0xe426c6e2, 0x58194951, + 0xdc1dcdd1, 0x50114151, 0x90108090, 0xdc1cccd0, 0x981a8a92, 0xa02383a3, 0xa82b8ba3, 0xd010c0d0, + 0x80018181, 0x0c0f0f03, 0x44074743, 0x181a0a12, 0xe023c3e3, 0xec2ccce0, 0x8c0d8d81, 0xbc3f8fb3, + 0x94168692, 0x783b4b73, 0x5c1c4c50, 0xa02282a2, 0xa02181a1, 0x60234363, 0x20230323, 0x4c0d4d41, + 0xc808c8c0, 0x9c1e8e92, 0x9c1c8c90, 0x383a0a32, 0x0c0c0c00, 0x2c2e0e22, 0xb83a8ab2, 0x6c2e4e62, + 0x9c1f8f93, 0x581a4a52, 0xf032c2f2, 0x90128292, 0xf033c3f3, 0x48094941, 0x78384870, 0xcc0cccc0, + 0x14150511, 0xf83bcbf3, 0x70304070, 0x74354571, 0x7c3f4f73, 0x34350531, 0x10100010, 0x00030303, + 0x64244460, 0x6c2d4d61, 0xc406c6c2, 0x74344470, 0xd415c5d1, 0xb43484b0, 0xe82acae2, 0x08090901, + 0x74364672, 0x18190911, 0xfc3ecef2, 0x40004040, 0x10120212, 0xe020c0e0, 0xbc3d8db1, 0x04050501, + 0xf83acaf2, 0x00010101, 0xf030c0f0, 0x282a0a22, 0x5c1e4e52, 0xa82989a1, 0x54164652, 0x40034343, + 0x84058581, 0x14140410, 0x88098981, 0x981b8b93, 0xb03080b0, 0xe425c5e1, 0x48084840, 0x78394971, + 0x94178793, 0xfc3cccf0, 0x1c1e0e12, 0x80028282, 0x20210121, 0x8c0c8c80, 0x181b0b13, 0x5c1f4f53, + 0x74374773, 0x54144450, 0xb03282b2, 0x1c1d0d11, 0x24250521, 0x4c0f4f43, 0x00000000, 0x44064642, + 0xec2dcde1, 0x58184850, 0x50124252, 0xe82bcbe3, 0x7c3e4e72, 0xd81acad2, 0xc809c9c1, 0xfc3dcdf1, + 0x30300030, 0x94158591, 0x64254561, 0x3c3c0c30, 0xb43686b2, 0xe424c4e0, 0xb83b8bb3, 0x7c3c4c70, + 0x0c0e0e02, 0x50104050, 0x38390931, 0x24260622, 0x30320232, 0x84048480, 0x68294961, 0x90138393, + 0x34370733, 0xe427c7e3, 0x24240420, 0xa42484a0, 0xc80bcbc3, 0x50134353, 0x080a0a02, 0x84078783, + 0xd819c9d1, 0x4c0c4c40, 0x80038383, 0x8c0f8f83, 0xcc0ecec2, 0x383b0b33, 0x480a4a42, 0xb43787b3 + }; + + private static readonly uint[] SS2 = + { + + 0xa1a82989, 0x81840585, 0xd2d416c6, 0xd3d013c3, 0x50541444, 0x111c1d0d, 0xa0ac2c8c, 0x21242505, + 0x515c1d4d, 0x43400343, 0x10181808, 0x121c1e0e, 0x51501141, 0xf0fc3ccc, 0xc2c80aca, 0x63602343, + 0x20282808, 0x40440444, 0x20202000, 0x919c1d8d, 0xe0e020c0, 0xe2e022c2, 0xc0c808c8, 0x13141707, + 0xa1a42585, 0x838c0f8f, 0x03000303, 0x73783b4b, 0xb3b83b8b, 0x13101303, 0xd2d012c2, 0xe2ec2ece, + 0x70703040, 0x808c0c8c, 0x333c3f0f, 0xa0a82888, 0x32303202, 0xd1dc1dcd, 0xf2f436c6, 0x70743444, + 0xe0ec2ccc, 0x91941585, 0x03080b0b, 0x53541747, 0x505c1c4c, 0x53581b4b, 0xb1bc3d8d, 0x01000101, + 0x20242404, 0x101c1c0c, 0x73703343, 0x90981888, 0x10101000, 0xc0cc0ccc, 0xf2f032c2, 0xd1d819c9, + 0x202c2c0c, 0xe3e427c7, 0x72703242, 0x83800383, 0x93981b8b, 0xd1d011c1, 0x82840686, 0xc1c809c9, + 0x60602040, 0x50501040, 0xa3a02383, 0xe3e82bcb, 0x010c0d0d, 0xb2b43686, 0x929c1e8e, 0x434c0f4f, + 0xb3b43787, 0x52581a4a, 0xc2c406c6, 0x70783848, 0xa2a42686, 0x12101202, 0xa3ac2f8f, 0xd1d415c5, + 0x61602141, 0xc3c003c3, 0xb0b43484, 0x41400141, 0x52501242, 0x717c3d4d, 0x818c0d8d, 0x00080808, + 0x131c1f0f, 0x91981989, 0x00000000, 0x11181909, 0x00040404, 0x53501343, 0xf3f437c7, 0xe1e021c1, + 0xf1fc3dcd, 0x72743646, 0x232c2f0f, 0x23242707, 0xb0b03080, 0x83880b8b, 0x020c0e0e, 0xa3a82b8b, + 0xa2a02282, 0x626c2e4e, 0x93901383, 0x414c0d4d, 0x61682949, 0x707c3c4c, 0x01080909, 0x02080a0a, + 0xb3bc3f8f, 0xe3ec2fcf, 0xf3f033c3, 0xc1c405c5, 0x83840787, 0x10141404, 0xf2fc3ece, 0x60642444, + 0xd2dc1ece, 0x222c2e0e, 0x43480b4b, 0x12181a0a, 0x02040606, 0x21202101, 0x63682b4b, 0x62642646, + 0x02000202, 0xf1f435c5, 0x92901282, 0x82880a8a, 0x000c0c0c, 0xb3b03383, 0x727c3e4e, 0xd0d010c0, + 0x72783a4a, 0x43440747, 0x92941686, 0xe1e425c5, 0x22242606, 0x80800080, 0xa1ac2d8d, 0xd3dc1fcf, + 0xa1a02181, 0x30303000, 0x33343707, 0xa2ac2e8e, 0x32343606, 0x11141505, 0x22202202, 0x30383808, + 0xf0f434c4, 0xa3a42787, 0x41440545, 0x404c0c4c, 0x81800181, 0xe1e829c9, 0x80840484, 0x93941787, + 0x31343505, 0xc3c80bcb, 0xc2cc0ece, 0x303c3c0c, 0x71703141, 0x11101101, 0xc3c407c7, 0x81880989, + 0x71743545, 0xf3f83bcb, 0xd2d81aca, 0xf0f838c8, 0x90941484, 0x51581949, 0x82800282, 0xc0c404c4, + 0xf3fc3fcf, 0x41480949, 0x31383909, 0x63642747, 0xc0c000c0, 0xc3cc0fcf, 0xd3d417c7, 0xb0b83888, + 0x030c0f0f, 0x828c0e8e, 0x42400242, 0x23202303, 0x91901181, 0x606c2c4c, 0xd3d81bcb, 0xa0a42484, + 0x30343404, 0xf1f031c1, 0x40480848, 0xc2c002c2, 0x636c2f4f, 0x313c3d0d, 0x212c2d0d, 0x40400040, + 0xb2bc3e8e, 0x323c3e0e, 0xb0bc3c8c, 0xc1c001c1, 0xa2a82a8a, 0xb2b83a8a, 0x424c0e4e, 0x51541545, + 0x33383b0b, 0xd0dc1ccc, 0x60682848, 0x737c3f4f, 0x909c1c8c, 0xd0d818c8, 0x42480a4a, 0x52541646, + 0x73743747, 0xa0a02080, 0xe1ec2dcd, 0x42440646, 0xb1b43585, 0x23282b0b, 0x61642545, 0xf2f83aca, + 0xe3e023c3, 0xb1b83989, 0xb1b03181, 0x939c1f8f, 0x525c1e4e, 0xf1f839c9, 0xe2e426c6, 0xb2b03282, + 0x31303101, 0xe2e82aca, 0x616c2d4d, 0x535c1f4f, 0xe0e424c4, 0xf0f030c0, 0xc1cc0dcd, 0x80880888, + 0x12141606, 0x32383a0a, 0x50581848, 0xd0d414c4, 0x62602242, 0x21282909, 0x03040707, 0x33303303, + 0xe0e828c8, 0x13181b0b, 0x01040505, 0x71783949, 0x90901080, 0x62682a4a, 0x22282a0a, 0x92981a8a + }; + + private static readonly uint[] SS3 = + { + + 0x08303838, 0xc8e0e828, 0x0d212c2d, 0x86a2a426, 0xcfc3cc0f, 0xced2dc1e, 0x83b3b033, 0x88b0b838, + 0x8fa3ac2f, 0x40606020, 0x45515415, 0xc7c3c407, 0x44404404, 0x4f636c2f, 0x4b63682b, 0x4b53581b, + 0xc3c3c003, 0x42626022, 0x03333033, 0x85b1b435, 0x09212829, 0x80a0a020, 0xc2e2e022, 0x87a3a427, + 0xc3d3d013, 0x81919011, 0x01111011, 0x06020406, 0x0c101c1c, 0x8cb0bc3c, 0x06323436, 0x4b43480b, + 0xcfe3ec2f, 0x88808808, 0x4c606c2c, 0x88a0a828, 0x07131417, 0xc4c0c404, 0x06121416, 0xc4f0f434, + 0xc2c2c002, 0x45414405, 0xc1e1e021, 0xc6d2d416, 0x0f333c3f, 0x0d313c3d, 0x8e828c0e, 0x88909818, + 0x08202828, 0x4e424c0e, 0xc6f2f436, 0x0e323c3e, 0x85a1a425, 0xc9f1f839, 0x0d010c0d, 0xcfd3dc1f, + 0xc8d0d818, 0x0b23282b, 0x46626426, 0x4a72783a, 0x07232427, 0x0f232c2f, 0xc1f1f031, 0x42727032, + 0x42424002, 0xc4d0d414, 0x41414001, 0xc0c0c000, 0x43737033, 0x47636427, 0x8ca0ac2c, 0x8b83880b, + 0xc7f3f437, 0x8da1ac2d, 0x80808000, 0x0f131c1f, 0xcac2c80a, 0x0c202c2c, 0x8aa2a82a, 0x04303434, + 0xc2d2d012, 0x0b03080b, 0xcee2ec2e, 0xc9e1e829, 0x4d515c1d, 0x84909414, 0x08101818, 0xc8f0f838, + 0x47535417, 0x8ea2ac2e, 0x08000808, 0xc5c1c405, 0x03131013, 0xcdc1cc0d, 0x86828406, 0x89b1b839, + 0xcff3fc3f, 0x4d717c3d, 0xc1c1c001, 0x01313031, 0xc5f1f435, 0x8a82880a, 0x4a62682a, 0x81b1b031, + 0xc1d1d011, 0x00202020, 0xc7d3d417, 0x02020002, 0x02222022, 0x04000404, 0x48606828, 0x41717031, + 0x07030407, 0xcbd3d81b, 0x8d919c1d, 0x89919819, 0x41616021, 0x8eb2bc3e, 0xc6e2e426, 0x49515819, + 0xcdd1dc1d, 0x41515011, 0x80909010, 0xccd0dc1c, 0x8a92981a, 0x83a3a023, 0x8ba3a82b, 0xc0d0d010, + 0x81818001, 0x0f030c0f, 0x47434407, 0x0a12181a, 0xc3e3e023, 0xcce0ec2c, 0x8d818c0d, 0x8fb3bc3f, + 0x86929416, 0x4b73783b, 0x4c505c1c, 0x82a2a022, 0x81a1a021, 0x43636023, 0x03232023, 0x4d414c0d, + 0xc8c0c808, 0x8e929c1e, 0x8c909c1c, 0x0a32383a, 0x0c000c0c, 0x0e222c2e, 0x8ab2b83a, 0x4e626c2e, + 0x8f939c1f, 0x4a52581a, 0xc2f2f032, 0x82929012, 0xc3f3f033, 0x49414809, 0x48707838, 0xccc0cc0c, + 0x05111415, 0xcbf3f83b, 0x40707030, 0x45717435, 0x4f737c3f, 0x05313435, 0x00101010, 0x03030003, + 0x44606424, 0x4d616c2d, 0xc6c2c406, 0x44707434, 0xc5d1d415, 0x84b0b434, 0xcae2e82a, 0x09010809, + 0x46727436, 0x09111819, 0xcef2fc3e, 0x40404000, 0x02121012, 0xc0e0e020, 0x8db1bc3d, 0x05010405, + 0xcaf2f83a, 0x01010001, 0xc0f0f030, 0x0a22282a, 0x4e525c1e, 0x89a1a829, 0x46525416, 0x43434003, + 0x85818405, 0x04101414, 0x89818809, 0x8b93981b, 0x80b0b030, 0xc5e1e425, 0x48404808, 0x49717839, + 0x87939417, 0xccf0fc3c, 0x0e121c1e, 0x82828002, 0x01212021, 0x8c808c0c, 0x0b13181b, 0x4f535c1f, + 0x47737437, 0x44505414, 0x82b2b032, 0x0d111c1d, 0x05212425, 0x4f434c0f, 0x00000000, 0x46424406, + 0xcde1ec2d, 0x48505818, 0x42525012, 0xcbe3e82b, 0x4e727c3e, 0xcad2d81a, 0xc9c1c809, 0xcdf1fc3d, + 0x00303030, 0x85919415, 0x45616425, 0x0c303c3c, 0x86b2b436, 0xc4e0e424, 0x8bb3b83b, 0x4c707c3c, + 0x0e020c0e, 0x40505010, 0x09313839, 0x06222426, 0x02323032, 0x84808404, 0x49616829, 0x83939013, + 0x07333437, 0xc7e3e427, 0x04202424, 0x84a0a424, 0xcbc3c80b, 0x43535013, 0x0a02080a, 0x87838407, + 0xc9d1d819, 0x4c404c0c, 0x83838003, 0x8f838c0f, 0xcec2cc0e, 0x0b33383b, 0x4a42480a, 0x87b3b437 + }; + + private static readonly uint[] KC = + { + 0x9e3779b9, 0x3c6ef373, 0x78dde6e6, 0xf1bbcdcc, + 0xe3779b99, 0xc6ef3733, 0x8dde6e67, 0x1bbcdccf, + 0x3779b99e, 0x6ef3733c, 0xdde6e678, 0xbbcdccf1, + 0x779b99e3, 0xef3733c6, 0xde6e678d, 0xbcdccf1b + }; + + private int[] wKey; + private bool forEncryption; + + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + this.forEncryption = forEncryption; + wKey = createWorkingKey(((KeyParameter)parameters).GetKey()); + } + + public virtual string AlgorithmName + { + get { return "SEED"; } + } + + public virtual bool IsPartialBlockOkay + { + get { return false; } + } + + public virtual int GetBlockSize() + { + return BlockSize; + } + + public virtual int ProcessBlock( + byte[] inBuf, + int inOff, + byte[] outBuf, + int outOff) + { + if (wKey == null) + throw new InvalidOperationException("SEED engine not initialised"); + + Check.DataLength(inBuf, inOff, BlockSize, "input buffer too short"); + Check.OutputLength(outBuf, outOff, BlockSize, "output buffer too short"); + + long l = bytesToLong(inBuf, inOff + 0); + long r = bytesToLong(inBuf, inOff + 8); + + if (forEncryption) + { + for (int i = 0; i < 16; i++) + { + long nl = r; + + r = l ^ F(wKey[2 * i], wKey[(2 * i) + 1], r); + l = nl; + } + } + else + { + for (int i = 15; i >= 0; i--) + { + long nl = r; + + r = l ^ F(wKey[2 * i], wKey[(2 * i) + 1], r); + l = nl; + } + } + + longToBytes(outBuf, outOff + 0, r); + longToBytes(outBuf, outOff + 8, l); + + return BlockSize; + } + + public virtual void Reset() + { + } + + private int[] createWorkingKey( + byte[] inKey) + { + int[] key = new int[32]; + long lower = bytesToLong(inKey, 0); + long upper = bytesToLong(inKey, 8); + + int key0 = extractW0(lower); + int key1 = extractW1(lower); + int key2 = extractW0(upper); + int key3 = extractW1(upper); + + for (int i = 0; i < 16; i++) + { + key[2 * i] = G(key0 + key2 - (int)KC[i]); + key[2 * i + 1] = G(key1 - key3 + (int)KC[i]); + + if (i % 2 == 0) + { + lower = rotateRight8(lower); + key0 = extractW0(lower); + key1 = extractW1(lower); + } + else + { + upper = rotateLeft8(upper); + key2 = extractW0(upper); + key3 = extractW1(upper); + } + } + + return key; + } + + private int extractW1( + long lVal) + { + return (int)lVal; + } + + private int extractW0( + long lVal) + { + return (int)(lVal >> 32); + } + + private long rotateLeft8( + long x) + { + return (x << 8) | ((long)((ulong) x >> 56)); + } + + private long rotateRight8( + long x) + { + return ((long)((ulong) x >> 8)) | (x << 56); + } + + private long bytesToLong( + byte[] src, + int srcOff) + { + long word = 0; + + for (int i = 0; i <= 7; i++) + { + word = (word << 8) + (src[i + srcOff] & 0xff); + } + + return word; + } + + private void longToBytes( + byte[] dest, + int destOff, + long value) + { + for (int i = 0; i < 8; i++) + { + dest[i + destOff] = (byte)(value >> ((7 - i) * 8)); + } + } + + private int G( + int x) + { + return (int)(SS0[x & 0xff] ^ SS1[(x >> 8) & 0xff] ^ SS2[(x >> 16) & 0xff] ^ SS3[(x >> 24) & 0xff]); + } + + private long F( + int ki0, + int ki1, + long r) + { + int r0 = (int)(r >> 32); + int r1 = (int)r; + int rd1 = phaseCalc2(r0, ki0, r1, ki1); + int rd0 = rd1 + phaseCalc1(r0, ki0, r1, ki1); + + return ((long)rd0 << 32) | (rd1 & 0xffffffffL); + } + + private int phaseCalc1( + int r0, + int ki0, + int r1, + int ki1) + { + return G(G((r0 ^ ki0) ^ (r1 ^ ki1)) + (r0 ^ ki0)); + } + + private int phaseCalc2( + int r0, + int ki0, + int r1, + int ki1) + { + return G(phaseCalc1(r0, ki0, r1, ki1) + G((r0 ^ ki0) ^ (r1 ^ ki1))); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/SEEDEngine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/SEEDEngine.cs.meta new file mode 100644 index 0000000..8a6ab79 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/SEEDEngine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a28e8c8464021ee4ba7813122beadb6d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/SEEDWrapEngine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/SEEDWrapEngine.cs new file mode 100644 index 0000000..6b71f94 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/SEEDWrapEngine.cs @@ -0,0 +1,16 @@ +namespace Org.BouncyCastle.Crypto.Engines +{ + /// + /// An implementation of the SEED key wrapper based on RFC 4010/RFC 3394. + ///

+ /// For further details see: http://www.ietf.org/rfc/rfc4010.txt. + /// + public class SeedWrapEngine + : Rfc3394WrapEngine + { + public SeedWrapEngine() + : base(new SeedEngine()) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/SEEDWrapEngine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/SEEDWrapEngine.cs.meta new file mode 100644 index 0000000..e769ec6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/SEEDWrapEngine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c2206043224747140ad58c401bbf3591 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/SM2Engine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/SM2Engine.cs new file mode 100644 index 0000000..ab7e9cd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/SM2Engine.cs @@ -0,0 +1,238 @@ +using System; + +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Math.EC.Multiplier; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + ///

+ /// SM2 public key encryption engine - based on https://tools.ietf.org/html/draft-shen-sm2-ecdsa-02. + /// + public class SM2Engine + { + private readonly IDigest mDigest; + + private bool mForEncryption; + private ECKeyParameters mECKey; + private ECDomainParameters mECParams; + private int mCurveLength; + private SecureRandom mRandom; + + public SM2Engine() + : this(new SM3Digest()) + { + } + + public SM2Engine(IDigest digest) + { + this.mDigest = digest; + } + + public virtual void Init(bool forEncryption, ICipherParameters param) + { + this.mForEncryption = forEncryption; + + if (forEncryption) + { + ParametersWithRandom rParam = (ParametersWithRandom)param; + + mECKey = (ECKeyParameters)rParam.Parameters; + mECParams = mECKey.Parameters; + + ECPoint s = ((ECPublicKeyParameters)mECKey).Q.Multiply(mECParams.H); + if (s.IsInfinity) + throw new ArgumentException("invalid key: [h]Q at infinity"); + + mRandom = rParam.Random; + } + else + { + mECKey = (ECKeyParameters)param; + mECParams = mECKey.Parameters; + } + + mCurveLength = (mECParams.Curve.FieldSize + 7) / 8; + } + + public virtual byte[] ProcessBlock(byte[] input, int inOff, int inLen) + { + if (mForEncryption) + { + return Encrypt(input, inOff, inLen); + } + else + { + return Decrypt(input, inOff, inLen); + } + } + + protected virtual ECMultiplier CreateBasePointMultiplier() + { + return new FixedPointCombMultiplier(); + } + + private byte[] Encrypt(byte[] input, int inOff, int inLen) + { + byte[] c2 = new byte[inLen]; + + Array.Copy(input, inOff, c2, 0, c2.Length); + + ECMultiplier multiplier = CreateBasePointMultiplier(); + + byte[] c1; + ECPoint kPB; + do + { + BigInteger k = NextK(); + + ECPoint c1P = multiplier.Multiply(mECParams.G, k).Normalize(); + + c1 = c1P.GetEncoded(false); + + kPB = ((ECPublicKeyParameters)mECKey).Q.Multiply(k).Normalize(); + + Kdf(mDigest, kPB, c2); + } + while (NotEncrypted(c2, input, inOff)); + + AddFieldElement(mDigest, kPB.AffineXCoord); + mDigest.BlockUpdate(input, inOff, inLen); + AddFieldElement(mDigest, kPB.AffineYCoord); + + byte[] c3 = DigestUtilities.DoFinal(mDigest); + + return Arrays.ConcatenateAll(c1, c2, c3); + } + + private byte[] Decrypt(byte[] input, int inOff, int inLen) + { + byte[] c1 = new byte[mCurveLength * 2 + 1]; + + Array.Copy(input, inOff, c1, 0, c1.Length); + + ECPoint c1P = mECParams.Curve.DecodePoint(c1); + + ECPoint s = c1P.Multiply(mECParams.H); + if (s.IsInfinity) + throw new InvalidCipherTextException("[h]C1 at infinity"); + + c1P = c1P.Multiply(((ECPrivateKeyParameters)mECKey).D).Normalize(); + + byte[] c2 = new byte[inLen - c1.Length - mDigest.GetDigestSize()]; + + Array.Copy(input, inOff + c1.Length, c2, 0, c2.Length); + + Kdf(mDigest, c1P, c2); + + AddFieldElement(mDigest, c1P.AffineXCoord); + mDigest.BlockUpdate(c2, 0, c2.Length); + AddFieldElement(mDigest, c1P.AffineYCoord); + + byte[] c3 = DigestUtilities.DoFinal(mDigest); + + int check = 0; + for (int i = 0; i != c3.Length; i++) + { + check |= c3[i] ^ input[inOff + c1.Length + c2.Length + i]; + } + + Arrays.Fill(c1, 0); + Arrays.Fill(c3, 0); + + if (check != 0) + { + Arrays.Fill(c2, 0); + throw new InvalidCipherTextException("invalid cipher text"); + } + + return c2; + } + + private bool NotEncrypted(byte[] encData, byte[] input, int inOff) + { + for (int i = 0; i != encData.Length; i++) + { + if (encData[i] != input[inOff + i]) + { + return false; + } + } + + return true; + } + + private void Kdf(IDigest digest, ECPoint c1, byte[] encData) + { + int digestSize = digest.GetDigestSize(); + byte[] buf = new byte[System.Math.Max(4, digestSize)]; + int off = 0; + + IMemoable memo = digest as IMemoable; + IMemoable copy = null; + + if (memo != null) + { + AddFieldElement(digest, c1.AffineXCoord); + AddFieldElement(digest, c1.AffineYCoord); + copy = memo.Copy(); + } + + uint ct = 0; + + while (off < encData.Length) + { + if (memo != null) + { + memo.Reset(copy); + } + else + { + AddFieldElement(digest, c1.AffineXCoord); + AddFieldElement(digest, c1.AffineYCoord); + } + + Pack.UInt32_To_BE(++ct, buf, 0); + digest.BlockUpdate(buf, 0, 4); + digest.DoFinal(buf, 0); + + int xorLen = System.Math.Min(digestSize, encData.Length - off); + Xor(encData, buf, off, xorLen); + off += xorLen; + } + } + + private void Xor(byte[] data, byte[] kdfOut, int dOff, int dRemaining) + { + for (int i = 0; i != dRemaining; i++) + { + data[dOff + i] ^= kdfOut[i]; + } + } + + private BigInteger NextK() + { + int qBitLength = mECParams.N.BitLength; + + BigInteger k; + do + { + k = new BigInteger(qBitLength, mRandom); + } + while (k.SignValue == 0 || k.CompareTo(mECParams.N) >= 0); + + return k; + } + + private void AddFieldElement(IDigest digest, ECFieldElement v) + { + byte[] p = v.GetEncoded(); + digest.BlockUpdate(p, 0, p.Length); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/SM2Engine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/SM2Engine.cs.meta new file mode 100644 index 0000000..4926994 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/SM2Engine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 135c9fb3405be884ea3045eb1cc3b8ce +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/SM4Engine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/SM4Engine.cs new file mode 100644 index 0000000..7477b07 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/SM4Engine.cs @@ -0,0 +1,189 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /// SM4 Block Cipher - SM4 is a 128 bit block cipher with a 128 bit key. + /// + /// The implementation here is based on the document http://eprint.iacr.org/2008/329.pdf + /// by Whitfield Diffie and George Ledin, which is a translation of Prof. LU Shu-wang's original standard. + /// + public class SM4Engine + : IBlockCipher + { + private const int BlockSize = 16; + + private static readonly byte[] Sbox = + { + 0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7, 0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05, + 0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3, 0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99, + 0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a, 0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62, + 0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95, 0x80, 0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6, + 0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba, 0x83, 0x59, 0x3c, 0x19, 0xe6, 0x85, 0x4f, 0xa8, + 0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b, 0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d, 0x35, + 0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2, 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87, + 0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52, 0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e, + 0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5, 0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1, + 0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55, 0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3, + 0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60, 0xc0, 0x29, 0x23, 0xab, 0x0d, 0x53, 0x4e, 0x6f, + 0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f, 0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51, + 0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f, 0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8, + 0x0a, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd, 0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0, + 0x89, 0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e, 0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84, + 0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20, 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48 + }; + + private static readonly uint[] CK = + { + 0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269, + 0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9, + 0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249, + 0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9, + 0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229, + 0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299, + 0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209, + 0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279 + }; + + private static readonly uint[] FK = + { + 0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc + }; + + private uint[] rk; + + // non-linear substitution tau. + private static uint tau(uint A) + { + uint b0 = Sbox[A >> 24]; + uint b1 = Sbox[(A >> 16) & 0xFF]; + uint b2 = Sbox[(A >> 8) & 0xFF]; + uint b3 = Sbox[A & 0xFF]; + + return (b0 << 24) | (b1 << 16) | (b2 << 8) | b3; + } + + private static uint L_ap(uint B) + { + return B ^ Integers.RotateLeft(B, 13) ^ Integers.RotateLeft(B, 23); + } + + private uint T_ap(uint Z) + { + return L_ap(tau(Z)); + } + + // Key expansion + private void ExpandKey(bool forEncryption, byte[] key) + { + uint K0 = Pack.BE_To_UInt32(key, 0) ^ FK[0]; + uint K1 = Pack.BE_To_UInt32(key, 4) ^ FK[1]; + uint K2 = Pack.BE_To_UInt32(key, 8) ^ FK[2]; + uint K3 = Pack.BE_To_UInt32(key, 12) ^ FK[3]; + + if (forEncryption) + { + rk[0] = K0 ^ T_ap(K1 ^ K2 ^ K3 ^ CK[0]); + rk[1] = K1 ^ T_ap(K2 ^ K3 ^ rk[0] ^ CK[1]); + rk[2] = K2 ^ T_ap(K3 ^ rk[0] ^ rk[1] ^ CK[2]); + rk[3] = K3 ^ T_ap(rk[0] ^ rk[1] ^ rk[2] ^ CK[3]); + for (int i = 4; i < 32; ++i) + { + rk[i] = rk[i - 4] ^ T_ap(rk[i - 3] ^ rk[i - 2] ^ rk[i - 1] ^ CK[i]); + } + } + else + { + rk[31] = K0 ^ T_ap(K1 ^ K2 ^ K3 ^ CK[0]); + rk[30] = K1 ^ T_ap(K2 ^ K3 ^ rk[31] ^ CK[1]); + rk[29] = K2 ^ T_ap(K3 ^ rk[31] ^ rk[30] ^ CK[2]); + rk[28] = K3 ^ T_ap(rk[31] ^ rk[30] ^ rk[29] ^ CK[3]); + for (int i = 27; i >= 0; --i) + { + rk[i] = rk[i + 4] ^ T_ap(rk[i + 3] ^ rk[i + 2] ^ rk[i + 1] ^ CK[31 - i]); + } + } + } + + // Linear substitution L + private static uint L(uint B) + { + return B ^ Integers.RotateLeft(B, 2) ^ Integers.RotateLeft(B, 10) ^ Integers.RotateLeft(B, 18) ^ Integers.RotateLeft(B, 24); + } + + // Mixer-substitution T + private static uint T(uint Z) + { + return L(tau(Z)); + } + + public virtual void Init(bool forEncryption, ICipherParameters parameters) + { + KeyParameter keyParameter = parameters as KeyParameter; + if (null == keyParameter) + throw new ArgumentException("invalid parameter passed to SM4 init - " + Platform.GetTypeName(parameters), "parameters"); + + byte[] key = keyParameter.GetKey(); + if (key.Length != 16) + throw new ArgumentException("SM4 requires a 128 bit key", "parameters"); + + if (null == rk) + { + rk = new uint[32]; + } + + ExpandKey(forEncryption, key); + } + + public virtual string AlgorithmName + { + get { return "SM4"; } + } + + public virtual bool IsPartialBlockOkay + { + get { return false; } + } + + public virtual int GetBlockSize() + { + return BlockSize; + } + + public virtual int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff) + { + if (null == rk) + throw new InvalidOperationException("SM4 not initialised"); + + Check.DataLength(input, inOff, BlockSize, "input buffer too short"); + Check.OutputLength(output, outOff, BlockSize, "output buffer too short"); + + uint X0 = Pack.BE_To_UInt32(input, inOff); + uint X1 = Pack.BE_To_UInt32(input, inOff + 4); + uint X2 = Pack.BE_To_UInt32(input, inOff + 8); + uint X3 = Pack.BE_To_UInt32(input, inOff + 12); + + for (int i = 0; i < 32; i += 4) + { + X0 ^= T(X1 ^ X2 ^ X3 ^ rk[i ]); // F0 + X1 ^= T(X2 ^ X3 ^ X0 ^ rk[i + 1]); // F1 + X2 ^= T(X3 ^ X0 ^ X1 ^ rk[i + 2]); // F2 + X3 ^= T(X0 ^ X1 ^ X2 ^ rk[i + 3]); // F3 + } + + Pack.UInt32_To_BE(X3, output, outOff); + Pack.UInt32_To_BE(X2, output, outOff + 4); + Pack.UInt32_To_BE(X1, output, outOff + 8); + Pack.UInt32_To_BE(X0, output, outOff + 12); + + return BlockSize; + } + + public virtual void Reset() + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/SM4Engine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/SM4Engine.cs.meta new file mode 100644 index 0000000..25a3b6e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/SM4Engine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b16f4028018b0df4ebbf78a5773bd601 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/Salsa20Engine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/Salsa20Engine.cs new file mode 100644 index 0000000..056fc09 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/Salsa20Engine.cs @@ -0,0 +1,349 @@ +using System; +using System.Text; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /// + /// Implementation of Daniel J. Bernstein's Salsa20 stream cipher, Snuffle 2005 + /// + public class Salsa20Engine + : IStreamCipher + { + public static readonly int DEFAULT_ROUNDS = 20; + + /** Constants */ + private const int StateSize = 16; // 16, 32 bit ints = 64 bytes + + private readonly static uint[] TAU_SIGMA = Pack.LE_To_UInt32(Strings.ToAsciiByteArray("expand 16-byte k" + "expand 32-byte k"), 0, 8); + + internal void PackTauOrSigma(int keyLength, uint[] state, int stateOffset) + { + int tsOff = (keyLength - 16) / 4; + state[stateOffset] = TAU_SIGMA[tsOff]; + state[stateOffset + 1] = TAU_SIGMA[tsOff + 1]; + state[stateOffset + 2] = TAU_SIGMA[tsOff + 2]; + state[stateOffset + 3] = TAU_SIGMA[tsOff + 3]; + } + + [Obsolete] + protected readonly static byte[] + sigma = Strings.ToAsciiByteArray("expand 32-byte k"), + tau = Strings.ToAsciiByteArray("expand 16-byte k"); + + protected int rounds; + + /* + * variables to hold the state of the engine + * during encryption and decryption + */ + private int index = 0; + internal uint[] engineState = new uint[StateSize]; // state + internal uint[] x = new uint[StateSize]; // internal buffer + private byte[] keyStream = new byte[StateSize * 4]; // expanded state, 64 bytes + private bool initialised = false; + + /* + * internal counter + */ + private uint cW0, cW1, cW2; + + /// + /// Creates a 20 round Salsa20 engine. + /// + public Salsa20Engine() + : this(DEFAULT_ROUNDS) + { + } + + /// + /// Creates a Salsa20 engine with a specific number of rounds. + /// + /// the number of rounds (must be an even number). + public Salsa20Engine(int rounds) + { + if (rounds <= 0 || (rounds & 1) != 0) + { + throw new ArgumentException("'rounds' must be a positive, even number"); + } + + this.rounds = rounds; + } + + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + /* + * Salsa20 encryption and decryption is completely + * symmetrical, so the 'forEncryption' is + * irrelevant. (Like 90% of stream ciphers) + */ + + ParametersWithIV ivParams = parameters as ParametersWithIV; + if (ivParams == null) + throw new ArgumentException(AlgorithmName + " Init requires an IV", "parameters"); + + byte[] iv = ivParams.GetIV(); + if (iv == null || iv.Length != NonceSize) + throw new ArgumentException(AlgorithmName + " requires exactly " + NonceSize + " bytes of IV"); + + ICipherParameters keyParam = ivParams.Parameters; + if (keyParam == null) + { + if (!initialised) + throw new InvalidOperationException(AlgorithmName + " KeyParameter can not be null for first initialisation"); + + SetKey(null, iv); + } + else if (keyParam is KeyParameter) + { + SetKey(((KeyParameter)keyParam).GetKey(), iv); + } + else + { + throw new ArgumentException(AlgorithmName + " Init parameters must contain a KeyParameter (or null for re-init)"); + } + + Reset(); + initialised = true; + } + + protected virtual int NonceSize + { + get { return 8; } + } + + public virtual string AlgorithmName + { + get + { + string name = "Salsa20"; + if (rounds != DEFAULT_ROUNDS) + { + name += "/" + rounds; + } + return name; + } + } + + public virtual byte ReturnByte( + byte input) + { + if (LimitExceeded()) + { + throw new MaxBytesExceededException("2^70 byte limit per IV; Change IV"); + } + + if (index == 0) + { + GenerateKeyStream(keyStream); + AdvanceCounter(); + } + + byte output = (byte)(keyStream[index] ^ input); + index = (index + 1) & 63; + + return output; + } + + protected virtual void AdvanceCounter() + { + if (++engineState[8] == 0) + { + ++engineState[9]; + } + } + + public virtual void ProcessBytes( + byte[] inBytes, + int inOff, + int len, + byte[] outBytes, + int outOff) + { + if (!initialised) + throw new InvalidOperationException(AlgorithmName + " not initialised"); + + Check.DataLength(inBytes, inOff, len, "input buffer too short"); + Check.OutputLength(outBytes, outOff, len, "output buffer too short"); + + if (LimitExceeded((uint)len)) + throw new MaxBytesExceededException("2^70 byte limit per IV would be exceeded; Change IV"); + + for (int i = 0; i < len; i++) + { + if (index == 0) + { + GenerateKeyStream(keyStream); + AdvanceCounter(); + } + outBytes[i+outOff] = (byte)(keyStream[index]^inBytes[i+inOff]); + index = (index + 1) & 63; + } + } + + public virtual void Reset() + { + index = 0; + ResetLimitCounter(); + ResetCounter(); + } + + protected virtual void ResetCounter() + { + engineState[8] = engineState[9] = 0; + } + + protected virtual void SetKey(byte[] keyBytes, byte[] ivBytes) + { + if (keyBytes != null) + { + if ((keyBytes.Length != 16) && (keyBytes.Length != 32)) + throw new ArgumentException(AlgorithmName + " requires 128 bit or 256 bit key"); + + int tsOff = (keyBytes.Length - 16) / 4; + engineState[0] = TAU_SIGMA[tsOff]; + engineState[5] = TAU_SIGMA[tsOff + 1]; + engineState[10] = TAU_SIGMA[tsOff + 2]; + engineState[15] = TAU_SIGMA[tsOff + 3]; + + // Key + Pack.LE_To_UInt32(keyBytes, 0, engineState, 1, 4); + Pack.LE_To_UInt32(keyBytes, keyBytes.Length - 16, engineState, 11, 4); + } + + // IV + Pack.LE_To_UInt32(ivBytes, 0, engineState, 6, 2); + } + + protected virtual void GenerateKeyStream(byte[] output) + { + SalsaCore(rounds, engineState, x); + Pack.UInt32_To_LE(x, output, 0); + } + + internal static void SalsaCore(int rounds, uint[] input, uint[] x) + { + if (input.Length != 16) + throw new ArgumentException(); + if (x.Length != 16) + throw new ArgumentException(); + if (rounds % 2 != 0) + throw new ArgumentException("Number of rounds must be even"); + + uint x00 = input[ 0]; + uint x01 = input[ 1]; + uint x02 = input[ 2]; + uint x03 = input[ 3]; + uint x04 = input[ 4]; + uint x05 = input[ 5]; + uint x06 = input[ 6]; + uint x07 = input[ 7]; + uint x08 = input[ 8]; + uint x09 = input[ 9]; + uint x10 = input[10]; + uint x11 = input[11]; + uint x12 = input[12]; + uint x13 = input[13]; + uint x14 = input[14]; + uint x15 = input[15]; + + for (int i = rounds; i > 0; i -= 2) + { + x04 ^= Integers.RotateLeft((x00+x12), 7); + x08 ^= Integers.RotateLeft((x04+x00), 9); + x12 ^= Integers.RotateLeft((x08+x04),13); + x00 ^= Integers.RotateLeft((x12+x08),18); + x09 ^= Integers.RotateLeft((x05+x01), 7); + x13 ^= Integers.RotateLeft((x09+x05), 9); + x01 ^= Integers.RotateLeft((x13+x09),13); + x05 ^= Integers.RotateLeft((x01+x13),18); + x14 ^= Integers.RotateLeft((x10+x06), 7); + x02 ^= Integers.RotateLeft((x14+x10), 9); + x06 ^= Integers.RotateLeft((x02+x14),13); + x10 ^= Integers.RotateLeft((x06+x02),18); + x03 ^= Integers.RotateLeft((x15+x11), 7); + x07 ^= Integers.RotateLeft((x03+x15), 9); + x11 ^= Integers.RotateLeft((x07+x03),13); + x15 ^= Integers.RotateLeft((x11+x07),18); + + x01 ^= Integers.RotateLeft((x00+x03), 7); + x02 ^= Integers.RotateLeft((x01+x00), 9); + x03 ^= Integers.RotateLeft((x02+x01),13); + x00 ^= Integers.RotateLeft((x03+x02),18); + x06 ^= Integers.RotateLeft((x05+x04), 7); + x07 ^= Integers.RotateLeft((x06+x05), 9); + x04 ^= Integers.RotateLeft((x07+x06),13); + x05 ^= Integers.RotateLeft((x04+x07),18); + x11 ^= Integers.RotateLeft((x10+x09), 7); + x08 ^= Integers.RotateLeft((x11+x10), 9); + x09 ^= Integers.RotateLeft((x08+x11),13); + x10 ^= Integers.RotateLeft((x09+x08),18); + x12 ^= Integers.RotateLeft((x15+x14), 7); + x13 ^= Integers.RotateLeft((x12+x15), 9); + x14 ^= Integers.RotateLeft((x13+x12),13); + x15 ^= Integers.RotateLeft((x14+x13),18); + } + + x[ 0] = x00 + input[ 0]; + x[ 1] = x01 + input[ 1]; + x[ 2] = x02 + input[ 2]; + x[ 3] = x03 + input[ 3]; + x[ 4] = x04 + input[ 4]; + x[ 5] = x05 + input[ 5]; + x[ 6] = x06 + input[ 6]; + x[ 7] = x07 + input[ 7]; + x[ 8] = x08 + input[ 8]; + x[ 9] = x09 + input[ 9]; + x[10] = x10 + input[10]; + x[11] = x11 + input[11]; + x[12] = x12 + input[12]; + x[13] = x13 + input[13]; + x[14] = x14 + input[14]; + x[15] = x15 + input[15]; + } + + private void ResetLimitCounter() + { + cW0 = 0; + cW1 = 0; + cW2 = 0; + } + + private bool LimitExceeded() + { + if (++cW0 == 0) + { + if (++cW1 == 0) + { + return (++cW2 & 0x20) != 0; // 2^(32 + 32 + 6) + } + } + + return false; + } + + /* + * this relies on the fact len will always be positive. + */ + private bool LimitExceeded( + uint len) + { + uint old = cW0; + cW0 += len; + if (cW0 < old) + { + if (++cW1 == 0) + { + return (++cW2 & 0x20) != 0; // 2^(32 + 32 + 6) + } + } + + return false; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/Salsa20Engine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/Salsa20Engine.cs.meta new file mode 100644 index 0000000..3ba4662 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/Salsa20Engine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5a7c2b8882a1bd14785bcaa3d2e89aef +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/SerpentEngine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/SerpentEngine.cs new file mode 100644 index 0000000..76799f0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/SerpentEngine.cs @@ -0,0 +1,292 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * Serpent is a 128-bit 32-round block cipher with variable key lengths, + * including 128, 192 and 256 bit keys conjectured to be at least as + * secure as three-key triple-DES. + *

+ * Serpent was designed by Ross Anderson, Eli Biham and Lars Knudsen as a + * candidate algorithm for the NIST AES Quest. + *

+ *

+ * For full details see The Serpent home page + *

+ */ + public sealed class SerpentEngine + : SerpentEngineBase + { + /** + * Expand a user-supplied key material into a session key. + * + * @param key The user-key bytes (multiples of 4) to use. + * @exception ArgumentException + */ + protected override int[] MakeWorkingKey(byte[] key) + { + // + // pad key to 256 bits + // + int[] kPad = new int[16]; + int off = 0; + int length = 0; + + for (off = 0; (off + 4) < key.Length; off += 4) + { + kPad[length++] = (int)Pack.LE_To_UInt32(key, off); + } + + if (off % 4 == 0) + { + kPad[length++] = (int)Pack.LE_To_UInt32(key, off); + if (length < 8) + { + kPad[length] = 1; + } + } + else + { + throw new ArgumentException("key must be a multiple of 4 bytes"); + } + + // + // expand the padded key up to 33 x 128 bits of key material + // + int amount = (ROUNDS + 1) * 4; + int[] w = new int[amount]; + + // + // compute w0 to w7 from w-8 to w-1 + // + for (int i = 8; i < 16; i++) + { + kPad[i] = RotateLeft(kPad[i - 8] ^ kPad[i - 5] ^ kPad[i - 3] ^ kPad[i - 1] ^ PHI ^ (i - 8), 11); + } + + Array.Copy(kPad, 8, w, 0, 8); + + // + // compute w8 to w136 + // + for (int i = 8; i < amount; i++) + { + w[i] = RotateLeft(w[i - 8] ^ w[i - 5] ^ w[i - 3] ^ w[i - 1] ^ PHI ^ i, 11); + } + + // + // create the working keys by processing w with the Sbox and IP + // + Sb3(w[0], w[1], w[2], w[3]); + w[0] = X0; w[1] = X1; w[2] = X2; w[3] = X3; + Sb2(w[4], w[5], w[6], w[7]); + w[4] = X0; w[5] = X1; w[6] = X2; w[7] = X3; + Sb1(w[8], w[9], w[10], w[11]); + w[8] = X0; w[9] = X1; w[10] = X2; w[11] = X3; + Sb0(w[12], w[13], w[14], w[15]); + w[12] = X0; w[13] = X1; w[14] = X2; w[15] = X3; + Sb7(w[16], w[17], w[18], w[19]); + w[16] = X0; w[17] = X1; w[18] = X2; w[19] = X3; + Sb6(w[20], w[21], w[22], w[23]); + w[20] = X0; w[21] = X1; w[22] = X2; w[23] = X3; + Sb5(w[24], w[25], w[26], w[27]); + w[24] = X0; w[25] = X1; w[26] = X2; w[27] = X3; + Sb4(w[28], w[29], w[30], w[31]); + w[28] = X0; w[29] = X1; w[30] = X2; w[31] = X3; + Sb3(w[32], w[33], w[34], w[35]); + w[32] = X0; w[33] = X1; w[34] = X2; w[35] = X3; + Sb2(w[36], w[37], w[38], w[39]); + w[36] = X0; w[37] = X1; w[38] = X2; w[39] = X3; + Sb1(w[40], w[41], w[42], w[43]); + w[40] = X0; w[41] = X1; w[42] = X2; w[43] = X3; + Sb0(w[44], w[45], w[46], w[47]); + w[44] = X0; w[45] = X1; w[46] = X2; w[47] = X3; + Sb7(w[48], w[49], w[50], w[51]); + w[48] = X0; w[49] = X1; w[50] = X2; w[51] = X3; + Sb6(w[52], w[53], w[54], w[55]); + w[52] = X0; w[53] = X1; w[54] = X2; w[55] = X3; + Sb5(w[56], w[57], w[58], w[59]); + w[56] = X0; w[57] = X1; w[58] = X2; w[59] = X3; + Sb4(w[60], w[61], w[62], w[63]); + w[60] = X0; w[61] = X1; w[62] = X2; w[63] = X3; + Sb3(w[64], w[65], w[66], w[67]); + w[64] = X0; w[65] = X1; w[66] = X2; w[67] = X3; + Sb2(w[68], w[69], w[70], w[71]); + w[68] = X0; w[69] = X1; w[70] = X2; w[71] = X3; + Sb1(w[72], w[73], w[74], w[75]); + w[72] = X0; w[73] = X1; w[74] = X2; w[75] = X3; + Sb0(w[76], w[77], w[78], w[79]); + w[76] = X0; w[77] = X1; w[78] = X2; w[79] = X3; + Sb7(w[80], w[81], w[82], w[83]); + w[80] = X0; w[81] = X1; w[82] = X2; w[83] = X3; + Sb6(w[84], w[85], w[86], w[87]); + w[84] = X0; w[85] = X1; w[86] = X2; w[87] = X3; + Sb5(w[88], w[89], w[90], w[91]); + w[88] = X0; w[89] = X1; w[90] = X2; w[91] = X3; + Sb4(w[92], w[93], w[94], w[95]); + w[92] = X0; w[93] = X1; w[94] = X2; w[95] = X3; + Sb3(w[96], w[97], w[98], w[99]); + w[96] = X0; w[97] = X1; w[98] = X2; w[99] = X3; + Sb2(w[100], w[101], w[102], w[103]); + w[100] = X0; w[101] = X1; w[102] = X2; w[103] = X3; + Sb1(w[104], w[105], w[106], w[107]); + w[104] = X0; w[105] = X1; w[106] = X2; w[107] = X3; + Sb0(w[108], w[109], w[110], w[111]); + w[108] = X0; w[109] = X1; w[110] = X2; w[111] = X3; + Sb7(w[112], w[113], w[114], w[115]); + w[112] = X0; w[113] = X1; w[114] = X2; w[115] = X3; + Sb6(w[116], w[117], w[118], w[119]); + w[116] = X0; w[117] = X1; w[118] = X2; w[119] = X3; + Sb5(w[120], w[121], w[122], w[123]); + w[120] = X0; w[121] = X1; w[122] = X2; w[123] = X3; + Sb4(w[124], w[125], w[126], w[127]); + w[124] = X0; w[125] = X1; w[126] = X2; w[127] = X3; + Sb3(w[128], w[129], w[130], w[131]); + w[128] = X0; w[129] = X1; w[130] = X2; w[131] = X3; + + return w; + } + + /** + * Encrypt one block of plaintext. + * + * @param input the array containing the input data. + * @param inOff offset into the in array the data starts at. + * @param output the array the output data will be copied into. + * @param outOff the offset into the out array the output will start at. + */ + protected override void EncryptBlock(byte[] input, int inOff, byte[] output, int outOff) + { + X0 = (int)Pack.LE_To_UInt32(input, inOff); + X1 = (int)Pack.LE_To_UInt32(input, inOff + 4); + X2 = (int)Pack.LE_To_UInt32(input, inOff + 8); + X3 = (int)Pack.LE_To_UInt32(input, inOff + 12); + + Sb0(wKey[0] ^ X0, wKey[1] ^ X1, wKey[2] ^ X2, wKey[3] ^ X3); LT(); + Sb1(wKey[4] ^ X0, wKey[5] ^ X1, wKey[6] ^ X2, wKey[7] ^ X3); LT(); + Sb2(wKey[8] ^ X0, wKey[9] ^ X1, wKey[10] ^ X2, wKey[11] ^ X3); LT(); + Sb3(wKey[12] ^ X0, wKey[13] ^ X1, wKey[14] ^ X2, wKey[15] ^ X3); LT(); + Sb4(wKey[16] ^ X0, wKey[17] ^ X1, wKey[18] ^ X2, wKey[19] ^ X3); LT(); + Sb5(wKey[20] ^ X0, wKey[21] ^ X1, wKey[22] ^ X2, wKey[23] ^ X3); LT(); + Sb6(wKey[24] ^ X0, wKey[25] ^ X1, wKey[26] ^ X2, wKey[27] ^ X3); LT(); + Sb7(wKey[28] ^ X0, wKey[29] ^ X1, wKey[30] ^ X2, wKey[31] ^ X3); LT(); + Sb0(wKey[32] ^ X0, wKey[33] ^ X1, wKey[34] ^ X2, wKey[35] ^ X3); LT(); + Sb1(wKey[36] ^ X0, wKey[37] ^ X1, wKey[38] ^ X2, wKey[39] ^ X3); LT(); + Sb2(wKey[40] ^ X0, wKey[41] ^ X1, wKey[42] ^ X2, wKey[43] ^ X3); LT(); + Sb3(wKey[44] ^ X0, wKey[45] ^ X1, wKey[46] ^ X2, wKey[47] ^ X3); LT(); + Sb4(wKey[48] ^ X0, wKey[49] ^ X1, wKey[50] ^ X2, wKey[51] ^ X3); LT(); + Sb5(wKey[52] ^ X0, wKey[53] ^ X1, wKey[54] ^ X2, wKey[55] ^ X3); LT(); + Sb6(wKey[56] ^ X0, wKey[57] ^ X1, wKey[58] ^ X2, wKey[59] ^ X3); LT(); + Sb7(wKey[60] ^ X0, wKey[61] ^ X1, wKey[62] ^ X2, wKey[63] ^ X3); LT(); + Sb0(wKey[64] ^ X0, wKey[65] ^ X1, wKey[66] ^ X2, wKey[67] ^ X3); LT(); + Sb1(wKey[68] ^ X0, wKey[69] ^ X1, wKey[70] ^ X2, wKey[71] ^ X3); LT(); + Sb2(wKey[72] ^ X0, wKey[73] ^ X1, wKey[74] ^ X2, wKey[75] ^ X3); LT(); + Sb3(wKey[76] ^ X0, wKey[77] ^ X1, wKey[78] ^ X2, wKey[79] ^ X3); LT(); + Sb4(wKey[80] ^ X0, wKey[81] ^ X1, wKey[82] ^ X2, wKey[83] ^ X3); LT(); + Sb5(wKey[84] ^ X0, wKey[85] ^ X1, wKey[86] ^ X2, wKey[87] ^ X3); LT(); + Sb6(wKey[88] ^ X0, wKey[89] ^ X1, wKey[90] ^ X2, wKey[91] ^ X3); LT(); + Sb7(wKey[92] ^ X0, wKey[93] ^ X1, wKey[94] ^ X2, wKey[95] ^ X3); LT(); + Sb0(wKey[96] ^ X0, wKey[97] ^ X1, wKey[98] ^ X2, wKey[99] ^ X3); LT(); + Sb1(wKey[100] ^ X0, wKey[101] ^ X1, wKey[102] ^ X2, wKey[103] ^ X3); LT(); + Sb2(wKey[104] ^ X0, wKey[105] ^ X1, wKey[106] ^ X2, wKey[107] ^ X3); LT(); + Sb3(wKey[108] ^ X0, wKey[109] ^ X1, wKey[110] ^ X2, wKey[111] ^ X3); LT(); + Sb4(wKey[112] ^ X0, wKey[113] ^ X1, wKey[114] ^ X2, wKey[115] ^ X3); LT(); + Sb5(wKey[116] ^ X0, wKey[117] ^ X1, wKey[118] ^ X2, wKey[119] ^ X3); LT(); + Sb6(wKey[120] ^ X0, wKey[121] ^ X1, wKey[122] ^ X2, wKey[123] ^ X3); LT(); + Sb7(wKey[124] ^ X0, wKey[125] ^ X1, wKey[126] ^ X2, wKey[127] ^ X3); + + Pack.UInt32_To_LE((uint)(wKey[128] ^ X0), output, outOff); + Pack.UInt32_To_LE((uint)(wKey[129] ^ X1), output, outOff + 4); + Pack.UInt32_To_LE((uint)(wKey[130] ^ X2), output, outOff + 8); + Pack.UInt32_To_LE((uint)(wKey[131] ^ X3), output, outOff + 12); + } + + /** + * Decrypt one block of ciphertext. + * + * @param input the array containing the input data. + * @param inOff offset into the in array the data starts at. + * @param output the array the output data will be copied into. + * @param outOff the offset into the out array the output will start at. + */ + protected override void DecryptBlock(byte[] input, int inOff, byte[] output, int outOff) + { + X0 = wKey[128] ^ (int)Pack.LE_To_UInt32(input, inOff); + X1 = wKey[129] ^ (int)Pack.LE_To_UInt32(input, inOff + 4); + X2 = wKey[130] ^ (int)Pack.LE_To_UInt32(input, inOff + 8); + X3 = wKey[131] ^ (int)Pack.LE_To_UInt32(input, inOff + 12); + + Ib7(X0, X1, X2, X3); + X0 ^= wKey[124]; X1 ^= wKey[125]; X2 ^= wKey[126]; X3 ^= wKey[127]; + InverseLT(); Ib6(X0, X1, X2, X3); + X0 ^= wKey[120]; X1 ^= wKey[121]; X2 ^= wKey[122]; X3 ^= wKey[123]; + InverseLT(); Ib5(X0, X1, X2, X3); + X0 ^= wKey[116]; X1 ^= wKey[117]; X2 ^= wKey[118]; X3 ^= wKey[119]; + InverseLT(); Ib4(X0, X1, X2, X3); + X0 ^= wKey[112]; X1 ^= wKey[113]; X2 ^= wKey[114]; X3 ^= wKey[115]; + InverseLT(); Ib3(X0, X1, X2, X3); + X0 ^= wKey[108]; X1 ^= wKey[109]; X2 ^= wKey[110]; X3 ^= wKey[111]; + InverseLT(); Ib2(X0, X1, X2, X3); + X0 ^= wKey[104]; X1 ^= wKey[105]; X2 ^= wKey[106]; X3 ^= wKey[107]; + InverseLT(); Ib1(X0, X1, X2, X3); + X0 ^= wKey[100]; X1 ^= wKey[101]; X2 ^= wKey[102]; X3 ^= wKey[103]; + InverseLT(); Ib0(X0, X1, X2, X3); + X0 ^= wKey[96]; X1 ^= wKey[97]; X2 ^= wKey[98]; X3 ^= wKey[99]; + InverseLT(); Ib7(X0, X1, X2, X3); + X0 ^= wKey[92]; X1 ^= wKey[93]; X2 ^= wKey[94]; X3 ^= wKey[95]; + InverseLT(); Ib6(X0, X1, X2, X3); + X0 ^= wKey[88]; X1 ^= wKey[89]; X2 ^= wKey[90]; X3 ^= wKey[91]; + InverseLT(); Ib5(X0, X1, X2, X3); + X0 ^= wKey[84]; X1 ^= wKey[85]; X2 ^= wKey[86]; X3 ^= wKey[87]; + InverseLT(); Ib4(X0, X1, X2, X3); + X0 ^= wKey[80]; X1 ^= wKey[81]; X2 ^= wKey[82]; X3 ^= wKey[83]; + InverseLT(); Ib3(X0, X1, X2, X3); + X0 ^= wKey[76]; X1 ^= wKey[77]; X2 ^= wKey[78]; X3 ^= wKey[79]; + InverseLT(); Ib2(X0, X1, X2, X3); + X0 ^= wKey[72]; X1 ^= wKey[73]; X2 ^= wKey[74]; X3 ^= wKey[75]; + InverseLT(); Ib1(X0, X1, X2, X3); + X0 ^= wKey[68]; X1 ^= wKey[69]; X2 ^= wKey[70]; X3 ^= wKey[71]; + InverseLT(); Ib0(X0, X1, X2, X3); + X0 ^= wKey[64]; X1 ^= wKey[65]; X2 ^= wKey[66]; X3 ^= wKey[67]; + InverseLT(); Ib7(X0, X1, X2, X3); + X0 ^= wKey[60]; X1 ^= wKey[61]; X2 ^= wKey[62]; X3 ^= wKey[63]; + InverseLT(); Ib6(X0, X1, X2, X3); + X0 ^= wKey[56]; X1 ^= wKey[57]; X2 ^= wKey[58]; X3 ^= wKey[59]; + InverseLT(); Ib5(X0, X1, X2, X3); + X0 ^= wKey[52]; X1 ^= wKey[53]; X2 ^= wKey[54]; X3 ^= wKey[55]; + InverseLT(); Ib4(X0, X1, X2, X3); + X0 ^= wKey[48]; X1 ^= wKey[49]; X2 ^= wKey[50]; X3 ^= wKey[51]; + InverseLT(); Ib3(X0, X1, X2, X3); + X0 ^= wKey[44]; X1 ^= wKey[45]; X2 ^= wKey[46]; X3 ^= wKey[47]; + InverseLT(); Ib2(X0, X1, X2, X3); + X0 ^= wKey[40]; X1 ^= wKey[41]; X2 ^= wKey[42]; X3 ^= wKey[43]; + InverseLT(); Ib1(X0, X1, X2, X3); + X0 ^= wKey[36]; X1 ^= wKey[37]; X2 ^= wKey[38]; X3 ^= wKey[39]; + InverseLT(); Ib0(X0, X1, X2, X3); + X0 ^= wKey[32]; X1 ^= wKey[33]; X2 ^= wKey[34]; X3 ^= wKey[35]; + InverseLT(); Ib7(X0, X1, X2, X3); + X0 ^= wKey[28]; X1 ^= wKey[29]; X2 ^= wKey[30]; X3 ^= wKey[31]; + InverseLT(); Ib6(X0, X1, X2, X3); + X0 ^= wKey[24]; X1 ^= wKey[25]; X2 ^= wKey[26]; X3 ^= wKey[27]; + InverseLT(); Ib5(X0, X1, X2, X3); + X0 ^= wKey[20]; X1 ^= wKey[21]; X2 ^= wKey[22]; X3 ^= wKey[23]; + InverseLT(); Ib4(X0, X1, X2, X3); + X0 ^= wKey[16]; X1 ^= wKey[17]; X2 ^= wKey[18]; X3 ^= wKey[19]; + InverseLT(); Ib3(X0, X1, X2, X3); + X0 ^= wKey[12]; X1 ^= wKey[13]; X2 ^= wKey[14]; X3 ^= wKey[15]; + InverseLT(); Ib2(X0, X1, X2, X3); + X0 ^= wKey[8]; X1 ^= wKey[9]; X2 ^= wKey[10]; X3 ^= wKey[11]; + InverseLT(); Ib1(X0, X1, X2, X3); + X0 ^= wKey[4]; X1 ^= wKey[5]; X2 ^= wKey[6]; X3 ^= wKey[7]; + InverseLT(); Ib0(X0, X1, X2, X3); + + Pack.UInt32_To_LE((uint)(X0 ^ wKey[0]), output, outOff); + Pack.UInt32_To_LE((uint)(X1 ^ wKey[1]), output, outOff + 4); + Pack.UInt32_To_LE((uint)(X2 ^ wKey[2]), output, outOff + 8); + Pack.UInt32_To_LE((uint)(X3 ^ wKey[3]), output, outOff + 12); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/SerpentEngine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/SerpentEngine.cs.meta new file mode 100644 index 0000000..cf38eda --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/SerpentEngine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d30d71545a3398a4282f7c43ba7e70ce +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/SerpentEngineBase.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/SerpentEngineBase.cs new file mode 100644 index 0000000..9de5522 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/SerpentEngineBase.cs @@ -0,0 +1,469 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + public abstract class SerpentEngineBase + : IBlockCipher + { + protected static readonly int BlockSize = 16; + + internal const int ROUNDS = 32; + internal const int PHI = unchecked((int)0x9E3779B9); // (sqrt(5) - 1) * 2**31 + + protected bool encrypting; + protected int[] wKey; + + protected int X0, X1, X2, X3; // registers + + protected SerpentEngineBase() + { + } + + /** + * initialise a Serpent cipher. + * + * @param encrypting whether or not we are for encryption. + * @param params the parameters required to set up the cipher. + * @throws IllegalArgumentException if the params argument is + * inappropriate. + */ + public virtual void Init(bool encrypting, ICipherParameters parameters) + { + if (!(parameters is KeyParameter)) + throw new ArgumentException("invalid parameter passed to " + AlgorithmName + " init - " + Platform.GetTypeName(parameters)); + + this.encrypting = encrypting; + this.wKey = MakeWorkingKey(((KeyParameter)parameters).GetKey()); + } + + public virtual string AlgorithmName + { + get { return "Serpent"; } + } + + public virtual bool IsPartialBlockOkay + { + get { return false; } + } + + public virtual int GetBlockSize() + { + return BlockSize; + } + + /** + * Process one block of input from the array in and write it to + * the out array. + * + * @param in the array containing the input data. + * @param inOff offset into the in array the data starts at. + * @param out the array the output data will be copied into. + * @param outOff the offset into the out array the output will start at. + * @return the number of bytes processed and produced. + * @throws DataLengthException if there isn't enough data in in, or + * space in out. + * @throws IllegalStateException if the cipher isn't initialised. + */ + public int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff) + { + if (wKey == null) + throw new InvalidOperationException(AlgorithmName + " not initialised"); + + Check.DataLength(input, inOff, BlockSize, "input buffer too short"); + Check.OutputLength(output, outOff, BlockSize, "output buffer too short"); + + if (encrypting) + { + EncryptBlock(input, inOff, output, outOff); + } + else + { + DecryptBlock(input, inOff, output, outOff); + } + + return BlockSize; + } + + public virtual void Reset() + { + } + + protected static int RotateLeft(int x, int bits) + { + return ((x << bits) | (int) ((uint)x >> (32 - bits))); + } + + private static int RotateRight(int x, int bits) + { + return ( (int)((uint)x >> bits) | (x << (32 - bits))); + } + + /* + * The sboxes below are based on the work of Brian Gladman and + * Sam Simpson, whose original notice appears below. + *

+ * For further details see: + * http://fp.gladman.plus.com/cryptography_technology/serpent/ + *

+ */ + + /* Partially optimised Serpent S Box boolean functions derived */ + /* using a recursive descent analyser but without a full search */ + /* of all subtrees. This set of S boxes is the result of work */ + /* by Sam Simpson and Brian Gladman using the spare time on a */ + /* cluster of high capacity servers to search for S boxes with */ + /* this customised search engine. There are now an average of */ + /* 15.375 terms per S box. */ + /* */ + /* Copyright: Dr B. R Gladman (gladman@seven77.demon.co.uk) */ + /* and Sam Simpson (s.simpson@mia.co.uk) */ + /* 17th December 1998 */ + /* */ + /* We hereby give permission for information in this file to be */ + /* used freely subject only to acknowledgement of its origin. */ + + /* + * S0 - { 3, 8,15, 1,10, 6, 5,11,14,13, 4, 2, 7, 0, 9,12 } - 15 terms. + */ + protected void Sb0(int a, int b, int c, int d) + { + int t1 = a ^ d; + int t3 = c ^ t1; + int t4 = b ^ t3; + X3 = (a & d) ^ t4; + int t7 = a ^ (b & t1); + X2 = t4 ^ (c | t7); + int t12 = X3 & (t3 ^ t7); + X1 = (~t3) ^ t12; + X0 = t12 ^ (~t7); + } + + /** + * InvSO - {13, 3,11, 0,10, 6, 5,12, 1,14, 4, 7,15, 9, 8, 2 } - 15 terms. + */ + protected void Ib0(int a, int b, int c, int d) + { + int t1 = ~a; + int t2 = a ^ b; + int t4 = d ^ (t1 | t2); + int t5 = c ^ t4; + X2 = t2 ^ t5; + int t8 = t1 ^ (d & t2); + X1 = t4 ^ (X2 & t8); + X3 = (a & t4) ^ (t5 | X1); + X0 = X3 ^ (t5 ^ t8); + } + + /** + * S1 - {15,12, 2, 7, 9, 0, 5,10, 1,11,14, 8, 6,13, 3, 4 } - 14 terms. + */ + protected void Sb1(int a, int b, int c, int d) + { + int t2 = b ^ (~a); + int t5 = c ^ (a | t2); + X2 = d ^ t5; + int t7 = b ^ (d | t2); + int t8 = t2 ^ X2; + X3 = t8 ^ (t5 & t7); + int t11 = t5 ^ t7; + X1 = X3 ^ t11; + X0 = t5 ^ (t8 & t11); + } + + /** + * InvS1 - { 5, 8, 2,14,15, 6,12, 3,11, 4, 7, 9, 1,13,10, 0 } - 14 steps. + */ + protected void Ib1(int a, int b, int c, int d) + { + int t1 = b ^ d; + int t3 = a ^ (b & t1); + int t4 = t1 ^ t3; + X3 = c ^ t4; + int t7 = b ^ (t1 & t3); + int t8 = X3 | t7; + X1 = t3 ^ t8; + int t10 = ~X1; + int t11 = X3 ^ t7; + X0 = t10 ^ t11; + X2 = t4 ^ (t10 | t11); + } + + /** + * S2 - { 8, 6, 7, 9, 3,12,10,15,13, 1,14, 4, 0,11, 5, 2 } - 16 terms. + */ + protected void Sb2(int a, int b, int c, int d) + { + int t1 = ~a; + int t2 = b ^ d; + int t3 = c & t1; + X0 = t2 ^ t3; + int t5 = c ^ t1; + int t6 = c ^ X0; + int t7 = b & t6; + X3 = t5 ^ t7; + X2 = a ^ ((d | t7) & (X0 | t5)); + X1 = (t2 ^ X3) ^ (X2 ^ (d | t1)); + } + + /** + * InvS2 - {12, 9,15, 4,11,14, 1, 2, 0, 3, 6,13, 5, 8,10, 7 } - 16 steps. + */ + protected void Ib2(int a, int b, int c, int d) + { + int t1 = b ^ d; + int t2 = ~t1; + int t3 = a ^ c; + int t4 = c ^ t1; + int t5 = b & t4; + X0 = t3 ^ t5; + int t7 = a | t2; + int t8 = d ^ t7; + int t9 = t3 | t8; + X3 = t1 ^ t9; + int t11 = ~t4; + int t12 = X0 | X3; + X1 = t11 ^ t12; + X2 = (d & t11) ^ (t3 ^ t12); + } + + /** + * S3 - { 0,15,11, 8,12, 9, 6, 3,13, 1, 2, 4,10, 7, 5,14 } - 16 terms. + */ + protected void Sb3(int a, int b, int c, int d) + { + int t1 = a ^ b; + int t2 = a & c; + int t3 = a | d; + int t4 = c ^ d; + int t5 = t1 & t3; + int t6 = t2 | t5; + X2 = t4 ^ t6; + int t8 = b ^ t3; + int t9 = t6 ^ t8; + int t10 = t4 & t9; + X0 = t1 ^ t10; + int t12 = X2 & X0; + X1 = t9 ^ t12; + X3 = (b | d) ^ (t4 ^ t12); + } + + /** + * InvS3 - { 0, 9,10, 7,11,14, 6,13, 3, 5,12, 2, 4, 8,15, 1 } - 15 terms + */ + protected void Ib3(int a, int b, int c, int d) + { + int t1 = a | b; + int t2 = b ^ c; + int t3 = b & t2; + int t4 = a ^ t3; + int t5 = c ^ t4; + int t6 = d | t4; + X0 = t2 ^ t6; + int t8 = t2 | t6; + int t9 = d ^ t8; + X2 = t5 ^ t9; + int t11 = t1 ^ t9; + int t12 = X0 & t11; + X3 = t4 ^ t12; + X1 = X3 ^ (X0 ^ t11); + } + + /** + * S4 - { 1,15, 8, 3,12, 0,11, 6, 2, 5, 4,10, 9,14, 7,13 } - 15 terms. + */ + protected void Sb4(int a, int b, int c, int d) + { + int t1 = a ^ d; + int t2 = d & t1; + int t3 = c ^ t2; + int t4 = b | t3; + X3 = t1 ^ t4; + int t6 = ~b; + int t7 = t1 | t6; + X0 = t3 ^ t7; + int t9 = a & X0; + int t10 = t1 ^ t6; + int t11 = t4 & t10; + X2 = t9 ^ t11; + X1 = (a ^ t3) ^ (t10 & X2); + } + + /** + * InvS4 - { 5, 0, 8, 3,10, 9, 7,14, 2,12,11, 6, 4,15,13, 1 } - 15 terms. + */ + protected void Ib4(int a, int b, int c, int d) + { + int t1 = c | d; + int t2 = a & t1; + int t3 = b ^ t2; + int t4 = a & t3; + int t5 = c ^ t4; + X1 = d ^ t5; + int t7 = ~a; + int t8 = t5 & X1; + X3 = t3 ^ t8; + int t10 = X1 | t7; + int t11 = d ^ t10; + X0 = X3 ^ t11; + X2 = (t3 & t11) ^ (X1 ^ t7); + } + + /** + * S5 - {15, 5, 2,11, 4,10, 9,12, 0, 3,14, 8,13, 6, 7, 1 } - 16 terms. + */ + protected void Sb5(int a, int b, int c, int d) + { + int t1 = ~a; + int t2 = a ^ b; + int t3 = a ^ d; + int t4 = c ^ t1; + int t5 = t2 | t3; + X0 = t4 ^ t5; + int t7 = d & X0; + int t8 = t2 ^ X0; + X1 = t7 ^ t8; + int t10 = t1 | X0; + int t11 = t2 | t7; + int t12 = t3 ^ t10; + X2 = t11 ^ t12; + X3 = (b ^ t7) ^ (X1 & t12); + } + + /** + * InvS5 - { 8,15, 2, 9, 4, 1,13,14,11, 6, 5, 3, 7,12,10, 0 } - 16 terms. + */ + protected void Ib5(int a, int b, int c, int d) + { + int t1 = ~c; + int t2 = b & t1; + int t3 = d ^ t2; + int t4 = a & t3; + int t5 = b ^ t1; + X3 = t4 ^ t5; + int t7 = b | X3; + int t8 = a & t7; + X1 = t3 ^ t8; + int t10 = a | d; + int t11 = t1 ^ t7; + X0 = t10 ^ t11; + X2 = (b & t10) ^ (t4 | (a ^ c)); + } + + /** + * S6 - { 7, 2,12, 5, 8, 4, 6,11,14, 9, 1,15,13, 3,10, 0 } - 15 terms. + */ + protected void Sb6(int a, int b, int c, int d) + { + int t1 = ~a; + int t2 = a ^ d; + int t3 = b ^ t2; + int t4 = t1 | t2; + int t5 = c ^ t4; + X1 = b ^ t5; + int t7 = t2 | X1; + int t8 = d ^ t7; + int t9 = t5 & t8; + X2 = t3 ^ t9; + int t11 = t5 ^ t8; + X0 = X2 ^ t11; + X3 = (~t5) ^ (t3 & t11); + } + + /** + * InvS6 - {15,10, 1,13, 5, 3, 6, 0, 4, 9,14, 7, 2,12, 8,11 } - 15 terms. + */ + protected void Ib6(int a, int b, int c, int d) + { + int t1 = ~a; + int t2 = a ^ b; + int t3 = c ^ t2; + int t4 = c | t1; + int t5 = d ^ t4; + X1 = t3 ^ t5; + int t7 = t3 & t5; + int t8 = t2 ^ t7; + int t9 = b | t8; + X3 = t5 ^ t9; + int t11 = b | X3; + X0 = t8 ^ t11; + X2 = (d & t1) ^ (t3 ^ t11); + } + + /** + * S7 - { 1,13,15, 0,14, 8, 2,11, 7, 4,12,10, 9, 3, 5, 6 } - 16 terms. + */ + protected void Sb7(int a, int b, int c, int d) + { + int t1 = b ^ c; + int t2 = c & t1; + int t3 = d ^ t2; + int t4 = a ^ t3; + int t5 = d | t1; + int t6 = t4 & t5; + X1 = b ^ t6; + int t8 = t3 | X1; + int t9 = a & t4; + X3 = t1 ^ t9; + int t11 = t4 ^ t8; + int t12 = X3 & t11; + X2 = t3 ^ t12; + X0 = (~t11) ^ (X3 & X2); + } + + /** + * InvS7 - { 3, 0, 6,13, 9,14,15, 8, 5,12,11, 7,10, 1, 4, 2 } - 17 terms. + */ + protected void Ib7(int a, int b, int c, int d) + { + int t3 = c | (a & b); + int t4 = d & (a | b); + X3 = t3 ^ t4; + int t6 = ~d; + int t7 = b ^ t4; + int t9 = t7 | (X3 ^ t6); + X1 = a ^ t9; + X0 = (c ^ t7) ^ (d | X1); + X2 = (t3 ^ X1) ^ (X0 ^ (a & X3)); + } + + /** + * Apply the linear transformation to the register set. + */ + protected void LT() + { + int x0 = RotateLeft(X0, 13); + int x2 = RotateLeft(X2, 3); + int x1 = X1 ^ x0 ^ x2; + int x3 = X3 ^ x2 ^ x0 << 3; + + X1 = RotateLeft(x1, 1); + X3 = RotateLeft(x3, 7); + X0 = RotateLeft(x0 ^ X1 ^ X3, 5); + X2 = RotateLeft(x2 ^ X3 ^ (X1 << 7), 22); + } + + /** + * Apply the inverse of the linear transformation to the register set. + */ + protected void InverseLT() + { + int x2 = RotateRight(X2, 22) ^ X3 ^ (X1 << 7); + int x0 = RotateRight(X0, 5) ^ X1 ^ X3; + int x3 = RotateRight(X3, 7); + int x1 = RotateRight(X1, 1); + X3 = x3 ^ x2 ^ x0 << 3; + X1 = x1 ^ x0 ^ x2; + X2 = RotateRight(x2, 3); + X0 = RotateRight(x0, 13); + } + + protected abstract int[] MakeWorkingKey(byte[] key); + + protected abstract void EncryptBlock(byte[] input, int inOff, byte[] output, int outOff); + + protected abstract void DecryptBlock(byte[] input, int inOff, byte[] output, int outOff); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/SerpentEngineBase.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/SerpentEngineBase.cs.meta new file mode 100644 index 0000000..78a8865 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/SerpentEngineBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9fa09510d413aaa4ebaeee85bcd35e83 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/SkipjackEngine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/SkipjackEngine.cs new file mode 100644 index 0000000..c90646c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/SkipjackEngine.cs @@ -0,0 +1,254 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * a class that provides a basic SKIPJACK engine. + */ + public class SkipjackEngine + : IBlockCipher + { + const int BLOCK_SIZE = 8; + + static readonly short [] ftable = + { + 0xa3, 0xd7, 0x09, 0x83, 0xf8, 0x48, 0xf6, 0xf4, 0xb3, 0x21, 0x15, 0x78, 0x99, 0xb1, 0xaf, 0xf9, + 0xe7, 0x2d, 0x4d, 0x8a, 0xce, 0x4c, 0xca, 0x2e, 0x52, 0x95, 0xd9, 0x1e, 0x4e, 0x38, 0x44, 0x28, + 0x0a, 0xdf, 0x02, 0xa0, 0x17, 0xf1, 0x60, 0x68, 0x12, 0xb7, 0x7a, 0xc3, 0xe9, 0xfa, 0x3d, 0x53, + 0x96, 0x84, 0x6b, 0xba, 0xf2, 0x63, 0x9a, 0x19, 0x7c, 0xae, 0xe5, 0xf5, 0xf7, 0x16, 0x6a, 0xa2, + 0x39, 0xb6, 0x7b, 0x0f, 0xc1, 0x93, 0x81, 0x1b, 0xee, 0xb4, 0x1a, 0xea, 0xd0, 0x91, 0x2f, 0xb8, + 0x55, 0xb9, 0xda, 0x85, 0x3f, 0x41, 0xbf, 0xe0, 0x5a, 0x58, 0x80, 0x5f, 0x66, 0x0b, 0xd8, 0x90, + 0x35, 0xd5, 0xc0, 0xa7, 0x33, 0x06, 0x65, 0x69, 0x45, 0x00, 0x94, 0x56, 0x6d, 0x98, 0x9b, 0x76, + 0x97, 0xfc, 0xb2, 0xc2, 0xb0, 0xfe, 0xdb, 0x20, 0xe1, 0xeb, 0xd6, 0xe4, 0xdd, 0x47, 0x4a, 0x1d, + 0x42, 0xed, 0x9e, 0x6e, 0x49, 0x3c, 0xcd, 0x43, 0x27, 0xd2, 0x07, 0xd4, 0xde, 0xc7, 0x67, 0x18, + 0x89, 0xcb, 0x30, 0x1f, 0x8d, 0xc6, 0x8f, 0xaa, 0xc8, 0x74, 0xdc, 0xc9, 0x5d, 0x5c, 0x31, 0xa4, + 0x70, 0x88, 0x61, 0x2c, 0x9f, 0x0d, 0x2b, 0x87, 0x50, 0x82, 0x54, 0x64, 0x26, 0x7d, 0x03, 0x40, + 0x34, 0x4b, 0x1c, 0x73, 0xd1, 0xc4, 0xfd, 0x3b, 0xcc, 0xfb, 0x7f, 0xab, 0xe6, 0x3e, 0x5b, 0xa5, + 0xad, 0x04, 0x23, 0x9c, 0x14, 0x51, 0x22, 0xf0, 0x29, 0x79, 0x71, 0x7e, 0xff, 0x8c, 0x0e, 0xe2, + 0x0c, 0xef, 0xbc, 0x72, 0x75, 0x6f, 0x37, 0xa1, 0xec, 0xd3, 0x8e, 0x62, 0x8b, 0x86, 0x10, 0xe8, + 0x08, 0x77, 0x11, 0xbe, 0x92, 0x4f, 0x24, 0xc5, 0x32, 0x36, 0x9d, 0xcf, 0xf3, 0xa6, 0xbb, 0xac, + 0x5e, 0x6c, 0xa9, 0x13, 0x57, 0x25, 0xb5, 0xe3, 0xbd, 0xa8, 0x3a, 0x01, 0x05, 0x59, 0x2a, 0x46 + }; + + private int[] key0, key1, key2, key3; + private bool encrypting; + + /** + * initialise a SKIPJACK cipher. + * + * @param forEncryption whether or not we are for encryption. + * @param parameters the parameters required to set up the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (!(parameters is KeyParameter)) + throw new ArgumentException("invalid parameter passed to SKIPJACK init - " + Platform.GetTypeName(parameters)); + + byte[] keyBytes = ((KeyParameter)parameters).GetKey(); + + this.encrypting = forEncryption; + this.key0 = new int[32]; + this.key1 = new int[32]; + this.key2 = new int[32]; + this.key3 = new int[32]; + + // + // expand the key to 128 bytes in 4 parts (saving us a modulo, multiply + // and an addition). + // + for (int i = 0; i < 32; i ++) + { + key0[i] = keyBytes[(i * 4) % 10] & 0xff; + key1[i] = keyBytes[(i * 4 + 1) % 10] & 0xff; + key2[i] = keyBytes[(i * 4 + 2) % 10] & 0xff; + key3[i] = keyBytes[(i * 4 + 3) % 10] & 0xff; + } + } + + public virtual string AlgorithmName + { + get { return "SKIPJACK"; } + } + + public virtual bool IsPartialBlockOkay + { + get { return false; } + } + + public virtual int GetBlockSize() + { + return BLOCK_SIZE; + } + + public virtual int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + if (key1 == null) + throw new InvalidOperationException("SKIPJACK engine not initialised"); + + Check.DataLength(input, inOff, BLOCK_SIZE, "input buffer too short"); + Check.OutputLength(output, outOff, BLOCK_SIZE, "output buffer too short"); + + if (encrypting) + { + EncryptBlock(input, inOff, output, outOff); + } + else + { + DecryptBlock(input, inOff, output, outOff); + } + + return BLOCK_SIZE; + } + + public virtual void Reset() + { + } + + /** + * The G permutation + */ + private int G( + int k, + int w) + { + int g1, g2, g3, g4, g5, g6; + + g1 = (w >> 8) & 0xff; + g2 = w & 0xff; + + g3 = ftable[g2 ^ key0[k]] ^ g1; + g4 = ftable[g3 ^ key1[k]] ^ g2; + g5 = ftable[g4 ^ key2[k]] ^ g3; + g6 = ftable[g5 ^ key3[k]] ^ g4; + + return ((g5 << 8) + g6); + } + + public virtual int EncryptBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + int w1 = (input[inOff + 0] << 8) + (input[inOff + 1] & 0xff); + int w2 = (input[inOff + 2] << 8) + (input[inOff + 3] & 0xff); + int w3 = (input[inOff + 4] << 8) + (input[inOff + 5] & 0xff); + int w4 = (input[inOff + 6] << 8) + (input[inOff + 7] & 0xff); + + int k = 0; + + for (int t = 0; t < 2; t++) + { + for(int i = 0; i < 8; i++) + { + int tmp = w4; + w4 = w3; + w3 = w2; + w2 = G(k, w1); + w1 = w2 ^ tmp ^ (k + 1); + k++; + } + + for(int i = 0; i < 8; i++) + { + int tmp = w4; + w4 = w3; + w3 = w1 ^ w2 ^ (k + 1); + w2 = G(k, w1); + w1 = tmp; + k++; + } + } + + outBytes[outOff + 0] = (byte)((w1 >> 8)); + outBytes[outOff + 1] = (byte)(w1); + outBytes[outOff + 2] = (byte)((w2 >> 8)); + outBytes[outOff + 3] = (byte)(w2); + outBytes[outOff + 4] = (byte)((w3 >> 8)); + outBytes[outOff + 5] = (byte)(w3); + outBytes[outOff + 6] = (byte)((w4 >> 8)); + outBytes[outOff + 7] = (byte)(w4); + + return BLOCK_SIZE; + } + + /** + * the inverse of the G permutation. + */ + private int H( + int k, + int w) + { + int h1, h2, h3, h4, h5, h6; + + h1 = w & 0xff; + h2 = (w >> 8) & 0xff; + + h3 = ftable[h2 ^ key3[k]] ^ h1; + h4 = ftable[h3 ^ key2[k]] ^ h2; + h5 = ftable[h4 ^ key1[k]] ^ h3; + h6 = ftable[h5 ^ key0[k]] ^ h4; + + return ((h6 << 8) + h5); + } + + public virtual int DecryptBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + int w2 = (input[inOff + 0] << 8) + (input[inOff + 1] & 0xff); + int w1 = (input[inOff + 2] << 8) + (input[inOff + 3] & 0xff); + int w4 = (input[inOff + 4] << 8) + (input[inOff + 5] & 0xff); + int w3 = (input[inOff + 6] << 8) + (input[inOff + 7] & 0xff); + + int k = 31; + + for (int t = 0; t < 2; t++) + { + for(int i = 0; i < 8; i++) + { + int tmp = w4; + w4 = w3; + w3 = w2; + w2 = H(k, w1); + w1 = w2 ^ tmp ^ (k + 1); + k--; + } + + for(int i = 0; i < 8; i++) + { + int tmp = w4; + w4 = w3; + w3 = w1 ^ w2 ^ (k + 1); + w2 = H(k, w1); + w1 = tmp; + k--; + } + } + + outBytes[outOff + 0] = (byte)((w2 >> 8)); + outBytes[outOff + 1] = (byte)(w2); + outBytes[outOff + 2] = (byte)((w1 >> 8)); + outBytes[outOff + 3] = (byte)(w1); + outBytes[outOff + 4] = (byte)((w4 >> 8)); + outBytes[outOff + 5] = (byte)(w4); + outBytes[outOff + 6] = (byte)((w3 >> 8)); + outBytes[outOff + 7] = (byte)(w3); + + return BLOCK_SIZE; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/SkipjackEngine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/SkipjackEngine.cs.meta new file mode 100644 index 0000000..79d51dc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/SkipjackEngine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 689973374cb74a749b2dfc2f95074a43 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/TEAEngine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/TEAEngine.cs new file mode 100644 index 0000000..7b70014 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/TEAEngine.cs @@ -0,0 +1,166 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * An TEA engine. + */ + public class TeaEngine + : IBlockCipher + { + private const int + rounds = 32, + block_size = 8; +// key_size = 16, + + private const uint + delta = 0x9E3779B9, + d_sum = 0xC6EF3720; // sum on decrypt + + /* + * the expanded key array of 4 subkeys + */ + private uint _a, _b, _c, _d; + private bool _initialised; + private bool _forEncryption; + + /** + * Create an instance of the TEA encryption algorithm + * and set some defaults + */ + public TeaEngine() + { + _initialised = false; + } + + public virtual string AlgorithmName + { + get { return "TEA"; } + } + + public virtual bool IsPartialBlockOkay + { + get { return false; } + } + + public virtual int GetBlockSize() + { + return block_size; + } + + /** + * initialise + * + * @param forEncryption whether or not we are for encryption. + * @param params the parameters required to set up the cipher. + * @exception ArgumentException if the params argument is + * inappropriate. + */ + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (!(parameters is KeyParameter)) + { + throw new ArgumentException("invalid parameter passed to TEA init - " + + Platform.GetTypeName(parameters)); + } + + _forEncryption = forEncryption; + _initialised = true; + + KeyParameter p = (KeyParameter) parameters; + + setKey(p.GetKey()); + } + + public virtual int ProcessBlock( + byte[] inBytes, + int inOff, + byte[] outBytes, + int outOff) + { + if (!_initialised) + throw new InvalidOperationException(AlgorithmName + " not initialised"); + + Check.DataLength(inBytes, inOff, block_size, "input buffer too short"); + Check.OutputLength(outBytes, outOff, block_size, "output buffer too short"); + + return _forEncryption + ? encryptBlock(inBytes, inOff, outBytes, outOff) + : decryptBlock(inBytes, inOff, outBytes, outOff); + } + + public virtual void Reset() + { + } + + /** + * Re-key the cipher. + * + * @param key the key to be used + */ + private void setKey( + byte[] key) + { + _a = Pack.BE_To_UInt32(key, 0); + _b = Pack.BE_To_UInt32(key, 4); + _c = Pack.BE_To_UInt32(key, 8); + _d = Pack.BE_To_UInt32(key, 12); + } + + private int encryptBlock( + byte[] inBytes, + int inOff, + byte[] outBytes, + int outOff) + { + // Pack bytes into integers + uint v0 = Pack.BE_To_UInt32(inBytes, inOff); + uint v1 = Pack.BE_To_UInt32(inBytes, inOff + 4); + + uint sum = 0; + + for (int i = 0; i != rounds; i++) + { + sum += delta; + v0 += ((v1 << 4) + _a) ^ (v1 + sum) ^ ((v1 >> 5) + _b); + v1 += ((v0 << 4) + _c) ^ (v0 + sum) ^ ((v0 >> 5) + _d); + } + + Pack.UInt32_To_BE(v0, outBytes, outOff); + Pack.UInt32_To_BE(v1, outBytes, outOff + 4); + + return block_size; + } + + private int decryptBlock( + byte[] inBytes, + int inOff, + byte[] outBytes, + int outOff) + { + // Pack bytes into integers + uint v0 = Pack.BE_To_UInt32(inBytes, inOff); + uint v1 = Pack.BE_To_UInt32(inBytes, inOff + 4); + + uint sum = d_sum; + + for (int i = 0; i != rounds; i++) + { + v1 -= ((v0 << 4) + _c) ^ (v0 + sum) ^ ((v0 >> 5) + _d); + v0 -= ((v1 << 4) + _a) ^ (v1 + sum) ^ ((v1 >> 5) + _b); + sum -= delta; + } + + Pack.UInt32_To_BE(v0, outBytes, outOff); + Pack.UInt32_To_BE(v1, outBytes, outOff + 4); + + return block_size; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/TEAEngine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/TEAEngine.cs.meta new file mode 100644 index 0000000..0f31e4c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/TEAEngine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 15e160981dd6cdc43990e292acaab7f7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/ThreefishEngine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/ThreefishEngine.cs new file mode 100644 index 0000000..eade3cc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/ThreefishEngine.cs @@ -0,0 +1,1491 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /// + /// Implementation of the Threefish tweakable large block cipher in 256, 512 and 1024 bit block + /// sizes. + /// + /// + /// This is the 1.3 version of Threefish defined in the Skein hash function submission to the NIST + /// SHA-3 competition in October 2010. + ///

+ /// Threefish was designed by Niels Ferguson - Stefan Lucks - Bruce Schneier - Doug Whiting - Mihir + /// Bellare - Tadayoshi Kohno - Jon Callas - Jesse Walker. + ///

+ /// This implementation inlines all round functions, unrolls 8 rounds, and uses 1.2k of static tables + /// to speed up key schedule injection.
+ /// 2 x block size state is retained by each cipher instance. + /// + public class ThreefishEngine + : IBlockCipher + { + ///

+ /// 256 bit block size - Threefish-256 + /// + public const int BLOCKSIZE_256 = 256; + /// + /// 512 bit block size - Threefish-512 + /// + public const int BLOCKSIZE_512 = 512; + /// + /// 1024 bit block size - Threefish-1024 + /// + public const int BLOCKSIZE_1024 = 1024; + + /** + * Size of the tweak in bytes (always 128 bit/16 bytes) + */ + private const int TWEAK_SIZE_BYTES = 16; + private const int TWEAK_SIZE_WORDS = TWEAK_SIZE_BYTES / 8; + + /** + * Rounds in Threefish-256 + */ + private const int ROUNDS_256 = 72; + /** + * Rounds in Threefish-512 + */ + private const int ROUNDS_512 = 72; + /** + * Rounds in Threefish-1024 + */ + private const int ROUNDS_1024 = 80; + + /** + * Max rounds of any of the variants + */ + private const int MAX_ROUNDS = ROUNDS_1024; + + /** + * Key schedule parity constant + */ + private const ulong C_240 = 0x1BD11BDAA9FC1A22L; + + /* Pre-calculated modulo arithmetic tables for key schedule lookups */ + private static readonly int[] MOD9 = new int[MAX_ROUNDS]; + private static readonly int[] MOD17 = new int[MOD9.Length]; + private static readonly int[] MOD5 = new int[MOD9.Length]; + private static readonly int[] MOD3 = new int[MOD9.Length]; + + static ThreefishEngine() + { + for (int i = 0; i < MOD9.Length; i++) + { + MOD17[i] = i % 17; + MOD9[i] = i % 9; + MOD5[i] = i % 5; + MOD3[i] = i % 3; + } + } + + /** + * Block size in bytes + */ + private readonly int blocksizeBytes; + + /** + * Block size in 64 bit words + */ + private readonly int blocksizeWords; + + /** + * Buffer for byte oriented processBytes to call internal word API + */ + private readonly ulong[] currentBlock; + + /** + * Tweak bytes (2 byte t1,t2, calculated t3 and repeat of t1,t2 for modulo free lookup + */ + private readonly ulong[] t = new ulong[5]; + + /** + * Key schedule words + */ + private readonly ulong[] kw; + + /** + * The internal cipher implementation (varies by blocksize) + */ + private readonly ThreefishCipher cipher; + + private bool forEncryption; + + /// + /// Constructs a new Threefish cipher, with a specified block size. + /// + /// the block size in bits, one of , , + /// . + public ThreefishEngine(int blocksizeBits) + { + this.blocksizeBytes = (blocksizeBits / 8); + this.blocksizeWords = (this.blocksizeBytes / 8); + this.currentBlock = new ulong[blocksizeWords]; + + /* + * Provide room for original key words, extended key word and repeat of key words for modulo + * free lookup of key schedule words. + */ + this.kw = new ulong[2 * blocksizeWords + 1]; + + switch (blocksizeBits) + { + case BLOCKSIZE_256: + cipher = new Threefish256Cipher(kw, t); + break; + case BLOCKSIZE_512: + cipher = new Threefish512Cipher(kw, t); + break; + case BLOCKSIZE_1024: + cipher = new Threefish1024Cipher(kw, t); + break; + default: + throw new ArgumentException( + "Invalid blocksize - Threefish is defined with block size of 256, 512, or 1024 bits"); + } + } + + /// + /// Initialise the engine. + /// + /// Initialise for encryption if true, for decryption if false. + /// an instance of or (to + /// use a 0 tweak) + public virtual void Init(bool forEncryption, ICipherParameters parameters) + { + byte[] keyBytes; + byte[] tweakBytes; + + if (parameters is TweakableBlockCipherParameters) + { + TweakableBlockCipherParameters tParams = (TweakableBlockCipherParameters)parameters; + keyBytes = tParams.Key.GetKey(); + tweakBytes = tParams.Tweak; + } + else if (parameters is KeyParameter) + { + keyBytes = ((KeyParameter)parameters).GetKey(); + tweakBytes = null; + } + else + { + throw new ArgumentException("Invalid parameter passed to Threefish init - " + + Platform.GetTypeName(parameters)); + } + + ulong[] keyWords = null; + ulong[] tweakWords = null; + + if (keyBytes != null) + { + if (keyBytes.Length != this.blocksizeBytes) + { + throw new ArgumentException("Threefish key must be same size as block (" + blocksizeBytes + + " bytes)"); + } + keyWords = new ulong[blocksizeWords]; + for (int i = 0; i < keyWords.Length; i++) + { + keyWords[i] = BytesToWord(keyBytes, i * 8); + } + } + if (tweakBytes != null) + { + if (tweakBytes.Length != TWEAK_SIZE_BYTES) + { + throw new ArgumentException("Threefish tweak must be " + TWEAK_SIZE_BYTES + " bytes"); + } + tweakWords = new ulong[]{BytesToWord(tweakBytes, 0), BytesToWord(tweakBytes, 8)}; + } + Init(forEncryption, keyWords, tweakWords); + } + + /// + /// Initialise the engine, specifying the key and tweak directly. + /// + /// the cipher mode. + /// the words of the key, or null to use the current key. + /// the 2 word (128 bit) tweak, or null to use the current tweak. + internal void Init(bool forEncryption, ulong[] key, ulong[] tweak) + { + this.forEncryption = forEncryption; + if (key != null) + { + SetKey(key); + } + if (tweak != null) + { + SetTweak(tweak); + } + } + + private void SetKey(ulong[] key) + { + if (key.Length != this.blocksizeWords) + { + throw new ArgumentException("Threefish key must be same size as block (" + blocksizeWords + + " words)"); + } + + /* + * Full subkey schedule is deferred to execution to avoid per cipher overhead (10k for 512, + * 20k for 1024). + * + * Key and tweak word sequences are repeated, and static MOD17/MOD9/MOD5/MOD3 calculations + * used, to avoid expensive mod computations during cipher operation. + */ + + ulong knw = C_240; + for (int i = 0; i < blocksizeWords; i++) + { + kw[i] = key[i]; + knw = knw ^ kw[i]; + } + kw[blocksizeWords] = knw; + Array.Copy(kw, 0, kw, blocksizeWords + 1, blocksizeWords); + } + + private void SetTweak(ulong[] tweak) + { + if (tweak.Length != TWEAK_SIZE_WORDS) + { + throw new ArgumentException("Tweak must be " + TWEAK_SIZE_WORDS + " words."); + } + + /* + * Tweak schedule partially repeated to avoid mod computations during cipher operation + */ + t[0] = tweak[0]; + t[1] = tweak[1]; + t[2] = t[0] ^ t[1]; + t[3] = t[0]; + t[4] = t[1]; + } + + public virtual string AlgorithmName + { + get { return "Threefish-" + (blocksizeBytes * 8); } + } + + public virtual bool IsPartialBlockOkay + { + get { return false; } + } + + public virtual int GetBlockSize() + { + return blocksizeBytes; + } + + public virtual void Reset() + { + } + + public virtual int ProcessBlock(byte[] inBytes, int inOff, byte[] outBytes, int outOff) + { + if ((outOff + blocksizeBytes) > outBytes.Length) + { + throw new DataLengthException("Output buffer too short"); + } + + if ((inOff + blocksizeBytes) > inBytes.Length) + { + throw new DataLengthException("Input buffer too short"); + } + + for (int i = 0; i < blocksizeBytes; i += 8) + { + currentBlock[i >> 3] = BytesToWord(inBytes, inOff + i); + } + ProcessBlock(this.currentBlock, this.currentBlock); + for (int i = 0; i < blocksizeBytes; i += 8) + { + WordToBytes(this.currentBlock[i >> 3], outBytes, outOff + i); + } + + return blocksizeBytes; + } + + /// + /// Process a block of data represented as 64 bit words. + /// + /// the number of 8 byte words processed (which will be the same as the block size). + /// a block sized buffer of words to process. + /// a block sized buffer of words to receive the output of the operation. + /// if either the input or output is not block sized + /// if this engine is not initialised + internal int ProcessBlock(ulong[] inWords, ulong[] outWords) + { + if (kw[blocksizeWords] == 0) + { + throw new InvalidOperationException("Threefish engine not initialised"); + } + + if (inWords.Length != blocksizeWords) + { + throw new DataLengthException("Input buffer too short"); + } + if (outWords.Length != blocksizeWords) + { + throw new DataLengthException("Output buffer too short"); + } + + if (forEncryption) + { + cipher.EncryptBlock(inWords, outWords); + } + else + { + cipher.DecryptBlock(inWords, outWords); + } + + return blocksizeWords; + } + + /// + /// Read a single 64 bit word from input in LSB first order. + /// + internal static ulong BytesToWord(byte[] bytes, int off) + { + if ((off + 8) > bytes.Length) + { + // Help the JIT avoid index checks + throw new ArgumentException(); + } + + ulong word = 0; + int index = off; + + word = (bytes[index++] & 0xffUL); + word |= (bytes[index++] & 0xffUL) << 8; + word |= (bytes[index++] & 0xffUL) << 16; + word |= (bytes[index++] & 0xffUL) << 24; + word |= (bytes[index++] & 0xffUL) << 32; + word |= (bytes[index++] & 0xffUL) << 40; + word |= (bytes[index++] & 0xffUL) << 48; + word |= (bytes[index++] & 0xffUL) << 56; + + return word; + } + + /// + /// Write a 64 bit word to output in LSB first order. + /// + internal static void WordToBytes(ulong word, byte[] bytes, int off) + { + if ((off + 8) > bytes.Length) + { + // Help the JIT avoid index checks + throw new ArgumentException(); + } + int index = off; + + bytes[index++] = (byte)word; + bytes[index++] = (byte)(word >> 8); + bytes[index++] = (byte)(word >> 16); + bytes[index++] = (byte)(word >> 24); + bytes[index++] = (byte)(word >> 32); + bytes[index++] = (byte)(word >> 40); + bytes[index++] = (byte)(word >> 48); + bytes[index++] = (byte)(word >> 56); + } + + /** + * Rotate left + xor part of the mix operation. + */ + private static ulong RotlXor(ulong x, int n, ulong xor) + { + return ((x << n) | (x >> (64 - n))) ^ xor; + } + + /** + * Rotate xor + rotate right part of the unmix operation. + */ + private static ulong XorRotr(ulong x, int n, ulong xor) + { + ulong xored = x ^ xor; + return (xored >> n) | (xored << (64 - n)); + } + + private abstract class ThreefishCipher + { + /** + * The extended + repeated tweak words + */ + protected readonly ulong[] t; + /** + * The extended + repeated key words + */ + protected readonly ulong[] kw; + + protected ThreefishCipher(ulong[] kw, ulong[] t) + { + this.kw = kw; + this.t = t; + } + + internal abstract void EncryptBlock(ulong[] block, ulong[] outWords); + + internal abstract void DecryptBlock(ulong[] block, ulong[] outWords); + + } + + private sealed class Threefish256Cipher + : ThreefishCipher + { + /** + * Mix rotation constants defined in Skein 1.3 specification + */ + private const int ROTATION_0_0 = 14, ROTATION_0_1 = 16; + private const int ROTATION_1_0 = 52, ROTATION_1_1 = 57; + private const int ROTATION_2_0 = 23, ROTATION_2_1 = 40; + private const int ROTATION_3_0 = 5, ROTATION_3_1 = 37; + + private const int ROTATION_4_0 = 25, ROTATION_4_1 = 33; + private const int ROTATION_5_0 = 46, ROTATION_5_1 = 12; + private const int ROTATION_6_0 = 58, ROTATION_6_1 = 22; + private const int ROTATION_7_0 = 32, ROTATION_7_1 = 32; + + public Threefish256Cipher(ulong[] kw, ulong[] t) + : base(kw, t) + { + } + + internal override void EncryptBlock(ulong[] block, ulong[] outWords) + { + ulong[] kw = this.kw; + ulong[] t = this.t; + int[] mod5 = MOD5; + int[] mod3 = MOD3; + + /* Help the JIT avoid index bounds checks */ + if (kw.Length != 9) + { + throw new ArgumentException(); + } + if (t.Length != 5) + { + throw new ArgumentException(); + } + + /* + * Read 4 words of plaintext data, not using arrays for cipher state + */ + ulong b0 = block[0]; + ulong b1 = block[1]; + ulong b2 = block[2]; + ulong b3 = block[3]; + + /* + * First subkey injection. + */ + b0 += kw[0]; + b1 += kw[1] + t[0]; + b2 += kw[2] + t[1]; + b3 += kw[3]; + + /* + * Rounds loop, unrolled to 8 rounds per iteration. + * + * Unrolling to multiples of 4 avoids the mod 4 check for key injection, and allows + * inlining of the permutations, which cycle every of 2 rounds (avoiding array + * index/lookup). + * + * Unrolling to multiples of 8 avoids the mod 8 rotation constant lookup, and allows + * inlining constant rotation values (avoiding array index/lookup). + */ + + for (int d = 1; d < (ROUNDS_256 / 4); d += 2) + { + int dm5 = mod5[d]; + int dm3 = mod3[d]; + + /* + * 4 rounds of mix and permute. + * + * Permute schedule has a 2 round cycle, so permutes are inlined in the mix + * operations in each 4 round block. + */ + b1 = RotlXor(b1, ROTATION_0_0, b0 += b1); + b3 = RotlXor(b3, ROTATION_0_1, b2 += b3); + + b3 = RotlXor(b3, ROTATION_1_0, b0 += b3); + b1 = RotlXor(b1, ROTATION_1_1, b2 += b1); + + b1 = RotlXor(b1, ROTATION_2_0, b0 += b1); + b3 = RotlXor(b3, ROTATION_2_1, b2 += b3); + + b3 = RotlXor(b3, ROTATION_3_0, b0 += b3); + b1 = RotlXor(b1, ROTATION_3_1, b2 += b1); + + /* + * Subkey injection for first 4 rounds. + */ + b0 += kw[dm5]; + b1 += kw[dm5 + 1] + t[dm3]; + b2 += kw[dm5 + 2] + t[dm3 + 1]; + b3 += kw[dm5 + 3] + (uint)d; + + /* + * 4 more rounds of mix/permute + */ + b1 = RotlXor(b1, ROTATION_4_0, b0 += b1); + b3 = RotlXor(b3, ROTATION_4_1, b2 += b3); + + b3 = RotlXor(b3, ROTATION_5_0, b0 += b3); + b1 = RotlXor(b1, ROTATION_5_1, b2 += b1); + + b1 = RotlXor(b1, ROTATION_6_0, b0 += b1); + b3 = RotlXor(b3, ROTATION_6_1, b2 += b3); + + b3 = RotlXor(b3, ROTATION_7_0, b0 += b3); + b1 = RotlXor(b1, ROTATION_7_1, b2 += b1); + + /* + * Subkey injection for next 4 rounds. + */ + b0 += kw[dm5 + 1]; + b1 += kw[dm5 + 2] + t[dm3 + 1]; + b2 += kw[dm5 + 3] + t[dm3 + 2]; + b3 += kw[dm5 + 4] + (uint)d + 1; + } + + /* + * Output cipher state. + */ + outWords[0] = b0; + outWords[1] = b1; + outWords[2] = b2; + outWords[3] = b3; + } + + internal override void DecryptBlock(ulong[] block, ulong[] state) + { + ulong[] kw = this.kw; + ulong[] t = this.t; + int[] mod5 = MOD5; + int[] mod3 = MOD3; + + /* Help the JIT avoid index bounds checks */ + if (kw.Length != 9) + { + throw new ArgumentException(); + } + if (t.Length != 5) + { + throw new ArgumentException(); + } + + ulong b0 = block[0]; + ulong b1 = block[1]; + ulong b2 = block[2]; + ulong b3 = block[3]; + + for (int d = (ROUNDS_256 / 4) - 1; d >= 1; d -= 2) + { + int dm5 = mod5[d]; + int dm3 = mod3[d]; + + /* Reverse key injection for second 4 rounds */ + b0 -= kw[dm5 + 1]; + b1 -= kw[dm5 + 2] + t[dm3 + 1]; + b2 -= kw[dm5 + 3] + t[dm3 + 2]; + b3 -= kw[dm5 + 4] + (uint)d + 1; + + /* Reverse second 4 mix/permute rounds */ + + b3 = XorRotr(b3, ROTATION_7_0, b0); + b0 -= b3; + b1 = XorRotr(b1, ROTATION_7_1, b2); + b2 -= b1; + + b1 = XorRotr(b1, ROTATION_6_0, b0); + b0 -= b1; + b3 = XorRotr(b3, ROTATION_6_1, b2); + b2 -= b3; + + b3 = XorRotr(b3, ROTATION_5_0, b0); + b0 -= b3; + b1 = XorRotr(b1, ROTATION_5_1, b2); + b2 -= b1; + + b1 = XorRotr(b1, ROTATION_4_0, b0); + b0 -= b1; + b3 = XorRotr(b3, ROTATION_4_1, b2); + b2 -= b3; + + /* Reverse key injection for first 4 rounds */ + b0 -= kw[dm5]; + b1 -= kw[dm5 + 1] + t[dm3]; + b2 -= kw[dm5 + 2] + t[dm3 + 1]; + b3 -= kw[dm5 + 3] + (uint)d; + + /* Reverse first 4 mix/permute rounds */ + b3 = XorRotr(b3, ROTATION_3_0, b0); + b0 -= b3; + b1 = XorRotr(b1, ROTATION_3_1, b2); + b2 -= b1; + + b1 = XorRotr(b1, ROTATION_2_0, b0); + b0 -= b1; + b3 = XorRotr(b3, ROTATION_2_1, b2); + b2 -= b3; + + b3 = XorRotr(b3, ROTATION_1_0, b0); + b0 -= b3; + b1 = XorRotr(b1, ROTATION_1_1, b2); + b2 -= b1; + + b1 = XorRotr(b1, ROTATION_0_0, b0); + b0 -= b1; + b3 = XorRotr(b3, ROTATION_0_1, b2); + b2 -= b3; + } + + /* + * First subkey uninjection. + */ + b0 -= kw[0]; + b1 -= kw[1] + t[0]; + b2 -= kw[2] + t[1]; + b3 -= kw[3]; + + /* + * Output cipher state. + */ + state[0] = b0; + state[1] = b1; + state[2] = b2; + state[3] = b3; + } + + } + + private sealed class Threefish512Cipher + : ThreefishCipher + { + /** + * Mix rotation constants defined in Skein 1.3 specification + */ + private const int ROTATION_0_0 = 46, ROTATION_0_1 = 36, ROTATION_0_2 = 19, ROTATION_0_3 = 37; + private const int ROTATION_1_0 = 33, ROTATION_1_1 = 27, ROTATION_1_2 = 14, ROTATION_1_3 = 42; + private const int ROTATION_2_0 = 17, ROTATION_2_1 = 49, ROTATION_2_2 = 36, ROTATION_2_3 = 39; + private const int ROTATION_3_0 = 44, ROTATION_3_1 = 9, ROTATION_3_2 = 54, ROTATION_3_3 = 56; + + private const int ROTATION_4_0 = 39, ROTATION_4_1 = 30, ROTATION_4_2 = 34, ROTATION_4_3 = 24; + private const int ROTATION_5_0 = 13, ROTATION_5_1 = 50, ROTATION_5_2 = 10, ROTATION_5_3 = 17; + private const int ROTATION_6_0 = 25, ROTATION_6_1 = 29, ROTATION_6_2 = 39, ROTATION_6_3 = 43; + private const int ROTATION_7_0 = 8, ROTATION_7_1 = 35, ROTATION_7_2 = 56, ROTATION_7_3 = 22; + + internal Threefish512Cipher(ulong[] kw, ulong[] t) + : base(kw, t) + { + } + + internal override void EncryptBlock(ulong[] block, ulong[] outWords) + { + ulong[] kw = this.kw; + ulong[] t = this.t; + int[] mod9 = MOD9; + int[] mod3 = MOD3; + + /* Help the JIT avoid index bounds checks */ + if (kw.Length != 17) + { + throw new ArgumentException(); + } + if (t.Length != 5) + { + throw new ArgumentException(); + } + + /* + * Read 8 words of plaintext data, not using arrays for cipher state + */ + ulong b0 = block[0]; + ulong b1 = block[1]; + ulong b2 = block[2]; + ulong b3 = block[3]; + ulong b4 = block[4]; + ulong b5 = block[5]; + ulong b6 = block[6]; + ulong b7 = block[7]; + + /* + * First subkey injection. + */ + b0 += kw[0]; + b1 += kw[1]; + b2 += kw[2]; + b3 += kw[3]; + b4 += kw[4]; + b5 += kw[5] + t[0]; + b6 += kw[6] + t[1]; + b7 += kw[7]; + + /* + * Rounds loop, unrolled to 8 rounds per iteration. + * + * Unrolling to multiples of 4 avoids the mod 4 check for key injection, and allows + * inlining of the permutations, which cycle every of 4 rounds (avoiding array + * index/lookup). + * + * Unrolling to multiples of 8 avoids the mod 8 rotation constant lookup, and allows + * inlining constant rotation values (avoiding array index/lookup). + */ + + for (int d = 1; d < (ROUNDS_512 / 4); d += 2) + { + int dm9 = mod9[d]; + int dm3 = mod3[d]; + + /* + * 4 rounds of mix and permute. + * + * Permute schedule has a 4 round cycle, so permutes are inlined in the mix + * operations in each 4 round block. + */ + b1 = RotlXor(b1, ROTATION_0_0, b0 += b1); + b3 = RotlXor(b3, ROTATION_0_1, b2 += b3); + b5 = RotlXor(b5, ROTATION_0_2, b4 += b5); + b7 = RotlXor(b7, ROTATION_0_3, b6 += b7); + + b1 = RotlXor(b1, ROTATION_1_0, b2 += b1); + b7 = RotlXor(b7, ROTATION_1_1, b4 += b7); + b5 = RotlXor(b5, ROTATION_1_2, b6 += b5); + b3 = RotlXor(b3, ROTATION_1_3, b0 += b3); + + b1 = RotlXor(b1, ROTATION_2_0, b4 += b1); + b3 = RotlXor(b3, ROTATION_2_1, b6 += b3); + b5 = RotlXor(b5, ROTATION_2_2, b0 += b5); + b7 = RotlXor(b7, ROTATION_2_3, b2 += b7); + + b1 = RotlXor(b1, ROTATION_3_0, b6 += b1); + b7 = RotlXor(b7, ROTATION_3_1, b0 += b7); + b5 = RotlXor(b5, ROTATION_3_2, b2 += b5); + b3 = RotlXor(b3, ROTATION_3_3, b4 += b3); + + /* + * Subkey injection for first 4 rounds. + */ + b0 += kw[dm9]; + b1 += kw[dm9 + 1]; + b2 += kw[dm9 + 2]; + b3 += kw[dm9 + 3]; + b4 += kw[dm9 + 4]; + b5 += kw[dm9 + 5] + t[dm3]; + b6 += kw[dm9 + 6] + t[dm3 + 1]; + b7 += kw[dm9 + 7] + (uint)d; + + /* + * 4 more rounds of mix/permute + */ + b1 = RotlXor(b1, ROTATION_4_0, b0 += b1); + b3 = RotlXor(b3, ROTATION_4_1, b2 += b3); + b5 = RotlXor(b5, ROTATION_4_2, b4 += b5); + b7 = RotlXor(b7, ROTATION_4_3, b6 += b7); + + b1 = RotlXor(b1, ROTATION_5_0, b2 += b1); + b7 = RotlXor(b7, ROTATION_5_1, b4 += b7); + b5 = RotlXor(b5, ROTATION_5_2, b6 += b5); + b3 = RotlXor(b3, ROTATION_5_3, b0 += b3); + + b1 = RotlXor(b1, ROTATION_6_0, b4 += b1); + b3 = RotlXor(b3, ROTATION_6_1, b6 += b3); + b5 = RotlXor(b5, ROTATION_6_2, b0 += b5); + b7 = RotlXor(b7, ROTATION_6_3, b2 += b7); + + b1 = RotlXor(b1, ROTATION_7_0, b6 += b1); + b7 = RotlXor(b7, ROTATION_7_1, b0 += b7); + b5 = RotlXor(b5, ROTATION_7_2, b2 += b5); + b3 = RotlXor(b3, ROTATION_7_3, b4 += b3); + + /* + * Subkey injection for next 4 rounds. + */ + b0 += kw[dm9 + 1]; + b1 += kw[dm9 + 2]; + b2 += kw[dm9 + 3]; + b3 += kw[dm9 + 4]; + b4 += kw[dm9 + 5]; + b5 += kw[dm9 + 6] + t[dm3 + 1]; + b6 += kw[dm9 + 7] + t[dm3 + 2]; + b7 += kw[dm9 + 8] + (uint)d + 1; + } + + /* + * Output cipher state. + */ + outWords[0] = b0; + outWords[1] = b1; + outWords[2] = b2; + outWords[3] = b3; + outWords[4] = b4; + outWords[5] = b5; + outWords[6] = b6; + outWords[7] = b7; + } + + internal override void DecryptBlock(ulong[] block, ulong[] state) + { + ulong[] kw = this.kw; + ulong[] t = this.t; + int[] mod9 = MOD9; + int[] mod3 = MOD3; + + /* Help the JIT avoid index bounds checks */ + if (kw.Length != 17) + { + throw new ArgumentException(); + } + if (t.Length != 5) + { + throw new ArgumentException(); + } + + ulong b0 = block[0]; + ulong b1 = block[1]; + ulong b2 = block[2]; + ulong b3 = block[3]; + ulong b4 = block[4]; + ulong b5 = block[5]; + ulong b6 = block[6]; + ulong b7 = block[7]; + + for (int d = (ROUNDS_512 / 4) - 1; d >= 1; d -= 2) + { + int dm9 = mod9[d]; + int dm3 = mod3[d]; + + /* Reverse key injection for second 4 rounds */ + b0 -= kw[dm9 + 1]; + b1 -= kw[dm9 + 2]; + b2 -= kw[dm9 + 3]; + b3 -= kw[dm9 + 4]; + b4 -= kw[dm9 + 5]; + b5 -= kw[dm9 + 6] + t[dm3 + 1]; + b6 -= kw[dm9 + 7] + t[dm3 + 2]; + b7 -= kw[dm9 + 8] + (uint)d + 1; + + /* Reverse second 4 mix/permute rounds */ + + b1 = XorRotr(b1, ROTATION_7_0, b6); + b6 -= b1; + b7 = XorRotr(b7, ROTATION_7_1, b0); + b0 -= b7; + b5 = XorRotr(b5, ROTATION_7_2, b2); + b2 -= b5; + b3 = XorRotr(b3, ROTATION_7_3, b4); + b4 -= b3; + + b1 = XorRotr(b1, ROTATION_6_0, b4); + b4 -= b1; + b3 = XorRotr(b3, ROTATION_6_1, b6); + b6 -= b3; + b5 = XorRotr(b5, ROTATION_6_2, b0); + b0 -= b5; + b7 = XorRotr(b7, ROTATION_6_3, b2); + b2 -= b7; + + b1 = XorRotr(b1, ROTATION_5_0, b2); + b2 -= b1; + b7 = XorRotr(b7, ROTATION_5_1, b4); + b4 -= b7; + b5 = XorRotr(b5, ROTATION_5_2, b6); + b6 -= b5; + b3 = XorRotr(b3, ROTATION_5_3, b0); + b0 -= b3; + + b1 = XorRotr(b1, ROTATION_4_0, b0); + b0 -= b1; + b3 = XorRotr(b3, ROTATION_4_1, b2); + b2 -= b3; + b5 = XorRotr(b5, ROTATION_4_2, b4); + b4 -= b5; + b7 = XorRotr(b7, ROTATION_4_3, b6); + b6 -= b7; + + /* Reverse key injection for first 4 rounds */ + b0 -= kw[dm9]; + b1 -= kw[dm9 + 1]; + b2 -= kw[dm9 + 2]; + b3 -= kw[dm9 + 3]; + b4 -= kw[dm9 + 4]; + b5 -= kw[dm9 + 5] + t[dm3]; + b6 -= kw[dm9 + 6] + t[dm3 + 1]; + b7 -= kw[dm9 + 7] + (uint)d; + + /* Reverse first 4 mix/permute rounds */ + b1 = XorRotr(b1, ROTATION_3_0, b6); + b6 -= b1; + b7 = XorRotr(b7, ROTATION_3_1, b0); + b0 -= b7; + b5 = XorRotr(b5, ROTATION_3_2, b2); + b2 -= b5; + b3 = XorRotr(b3, ROTATION_3_3, b4); + b4 -= b3; + + b1 = XorRotr(b1, ROTATION_2_0, b4); + b4 -= b1; + b3 = XorRotr(b3, ROTATION_2_1, b6); + b6 -= b3; + b5 = XorRotr(b5, ROTATION_2_2, b0); + b0 -= b5; + b7 = XorRotr(b7, ROTATION_2_3, b2); + b2 -= b7; + + b1 = XorRotr(b1, ROTATION_1_0, b2); + b2 -= b1; + b7 = XorRotr(b7, ROTATION_1_1, b4); + b4 -= b7; + b5 = XorRotr(b5, ROTATION_1_2, b6); + b6 -= b5; + b3 = XorRotr(b3, ROTATION_1_3, b0); + b0 -= b3; + + b1 = XorRotr(b1, ROTATION_0_0, b0); + b0 -= b1; + b3 = XorRotr(b3, ROTATION_0_1, b2); + b2 -= b3; + b5 = XorRotr(b5, ROTATION_0_2, b4); + b4 -= b5; + b7 = XorRotr(b7, ROTATION_0_3, b6); + b6 -= b7; + } + + /* + * First subkey uninjection. + */ + b0 -= kw[0]; + b1 -= kw[1]; + b2 -= kw[2]; + b3 -= kw[3]; + b4 -= kw[4]; + b5 -= kw[5] + t[0]; + b6 -= kw[6] + t[1]; + b7 -= kw[7]; + + /* + * Output cipher state. + */ + state[0] = b0; + state[1] = b1; + state[2] = b2; + state[3] = b3; + state[4] = b4; + state[5] = b5; + state[6] = b6; + state[7] = b7; + } + } + + private sealed class Threefish1024Cipher + : ThreefishCipher + { + /** + * Mix rotation constants defined in Skein 1.3 specification + */ + private const int ROTATION_0_0 = 24, ROTATION_0_1 = 13, ROTATION_0_2 = 8, ROTATION_0_3 = 47; + private const int ROTATION_0_4 = 8, ROTATION_0_5 = 17, ROTATION_0_6 = 22, ROTATION_0_7 = 37; + private const int ROTATION_1_0 = 38, ROTATION_1_1 = 19, ROTATION_1_2 = 10, ROTATION_1_3 = 55; + private const int ROTATION_1_4 = 49, ROTATION_1_5 = 18, ROTATION_1_6 = 23, ROTATION_1_7 = 52; + private const int ROTATION_2_0 = 33, ROTATION_2_1 = 4, ROTATION_2_2 = 51, ROTATION_2_3 = 13; + private const int ROTATION_2_4 = 34, ROTATION_2_5 = 41, ROTATION_2_6 = 59, ROTATION_2_7 = 17; + private const int ROTATION_3_0 = 5, ROTATION_3_1 = 20, ROTATION_3_2 = 48, ROTATION_3_3 = 41; + private const int ROTATION_3_4 = 47, ROTATION_3_5 = 28, ROTATION_3_6 = 16, ROTATION_3_7 = 25; + + private const int ROTATION_4_0 = 41, ROTATION_4_1 = 9, ROTATION_4_2 = 37, ROTATION_4_3 = 31; + private const int ROTATION_4_4 = 12, ROTATION_4_5 = 47, ROTATION_4_6 = 44, ROTATION_4_7 = 30; + private const int ROTATION_5_0 = 16, ROTATION_5_1 = 34, ROTATION_5_2 = 56, ROTATION_5_3 = 51; + private const int ROTATION_5_4 = 4, ROTATION_5_5 = 53, ROTATION_5_6 = 42, ROTATION_5_7 = 41; + private const int ROTATION_6_0 = 31, ROTATION_6_1 = 44, ROTATION_6_2 = 47, ROTATION_6_3 = 46; + private const int ROTATION_6_4 = 19, ROTATION_6_5 = 42, ROTATION_6_6 = 44, ROTATION_6_7 = 25; + private const int ROTATION_7_0 = 9, ROTATION_7_1 = 48, ROTATION_7_2 = 35, ROTATION_7_3 = 52; + private const int ROTATION_7_4 = 23, ROTATION_7_5 = 31, ROTATION_7_6 = 37, ROTATION_7_7 = 20; + + public Threefish1024Cipher(ulong[] kw, ulong[] t) + : base(kw, t) + { + } + + internal override void EncryptBlock(ulong[] block, ulong[] outWords) + { + ulong[] kw = this.kw; + ulong[] t = this.t; + int[] mod17 = MOD17; + int[] mod3 = MOD3; + + /* Help the JIT avoid index bounds checks */ + if (kw.Length != 33) + { + throw new ArgumentException(); + } + if (t.Length != 5) + { + throw new ArgumentException(); + } + + /* + * Read 16 words of plaintext data, not using arrays for cipher state + */ + ulong b0 = block[0]; + ulong b1 = block[1]; + ulong b2 = block[2]; + ulong b3 = block[3]; + ulong b4 = block[4]; + ulong b5 = block[5]; + ulong b6 = block[6]; + ulong b7 = block[7]; + ulong b8 = block[8]; + ulong b9 = block[9]; + ulong b10 = block[10]; + ulong b11 = block[11]; + ulong b12 = block[12]; + ulong b13 = block[13]; + ulong b14 = block[14]; + ulong b15 = block[15]; + + /* + * First subkey injection. + */ + b0 += kw[0]; + b1 += kw[1]; + b2 += kw[2]; + b3 += kw[3]; + b4 += kw[4]; + b5 += kw[5]; + b6 += kw[6]; + b7 += kw[7]; + b8 += kw[8]; + b9 += kw[9]; + b10 += kw[10]; + b11 += kw[11]; + b12 += kw[12]; + b13 += kw[13] + t[0]; + b14 += kw[14] + t[1]; + b15 += kw[15]; + + /* + * Rounds loop, unrolled to 8 rounds per iteration. + * + * Unrolling to multiples of 4 avoids the mod 4 check for key injection, and allows + * inlining of the permutations, which cycle every of 4 rounds (avoiding array + * index/lookup). + * + * Unrolling to multiples of 8 avoids the mod 8 rotation constant lookup, and allows + * inlining constant rotation values (avoiding array index/lookup). + */ + + for (int d = 1; d < (ROUNDS_1024 / 4); d += 2) + { + int dm17 = mod17[d]; + int dm3 = mod3[d]; + + /* + * 4 rounds of mix and permute. + * + * Permute schedule has a 4 round cycle, so permutes are inlined in the mix + * operations in each 4 round block. + */ + b1 = RotlXor(b1, ROTATION_0_0, b0 += b1); + b3 = RotlXor(b3, ROTATION_0_1, b2 += b3); + b5 = RotlXor(b5, ROTATION_0_2, b4 += b5); + b7 = RotlXor(b7, ROTATION_0_3, b6 += b7); + b9 = RotlXor(b9, ROTATION_0_4, b8 += b9); + b11 = RotlXor(b11, ROTATION_0_5, b10 += b11); + b13 = RotlXor(b13, ROTATION_0_6, b12 += b13); + b15 = RotlXor(b15, ROTATION_0_7, b14 += b15); + + b9 = RotlXor(b9, ROTATION_1_0, b0 += b9); + b13 = RotlXor(b13, ROTATION_1_1, b2 += b13); + b11 = RotlXor(b11, ROTATION_1_2, b6 += b11); + b15 = RotlXor(b15, ROTATION_1_3, b4 += b15); + b7 = RotlXor(b7, ROTATION_1_4, b10 += b7); + b3 = RotlXor(b3, ROTATION_1_5, b12 += b3); + b5 = RotlXor(b5, ROTATION_1_6, b14 += b5); + b1 = RotlXor(b1, ROTATION_1_7, b8 += b1); + + b7 = RotlXor(b7, ROTATION_2_0, b0 += b7); + b5 = RotlXor(b5, ROTATION_2_1, b2 += b5); + b3 = RotlXor(b3, ROTATION_2_2, b4 += b3); + b1 = RotlXor(b1, ROTATION_2_3, b6 += b1); + b15 = RotlXor(b15, ROTATION_2_4, b12 += b15); + b13 = RotlXor(b13, ROTATION_2_5, b14 += b13); + b11 = RotlXor(b11, ROTATION_2_6, b8 += b11); + b9 = RotlXor(b9, ROTATION_2_7, b10 += b9); + + b15 = RotlXor(b15, ROTATION_3_0, b0 += b15); + b11 = RotlXor(b11, ROTATION_3_1, b2 += b11); + b13 = RotlXor(b13, ROTATION_3_2, b6 += b13); + b9 = RotlXor(b9, ROTATION_3_3, b4 += b9); + b1 = RotlXor(b1, ROTATION_3_4, b14 += b1); + b5 = RotlXor(b5, ROTATION_3_5, b8 += b5); + b3 = RotlXor(b3, ROTATION_3_6, b10 += b3); + b7 = RotlXor(b7, ROTATION_3_7, b12 += b7); + + /* + * Subkey injection for first 4 rounds. + */ + b0 += kw[dm17]; + b1 += kw[dm17 + 1]; + b2 += kw[dm17 + 2]; + b3 += kw[dm17 + 3]; + b4 += kw[dm17 + 4]; + b5 += kw[dm17 + 5]; + b6 += kw[dm17 + 6]; + b7 += kw[dm17 + 7]; + b8 += kw[dm17 + 8]; + b9 += kw[dm17 + 9]; + b10 += kw[dm17 + 10]; + b11 += kw[dm17 + 11]; + b12 += kw[dm17 + 12]; + b13 += kw[dm17 + 13] + t[dm3]; + b14 += kw[dm17 + 14] + t[dm3 + 1]; + b15 += kw[dm17 + 15] + (uint)d; + + /* + * 4 more rounds of mix/permute + */ + b1 = RotlXor(b1, ROTATION_4_0, b0 += b1); + b3 = RotlXor(b3, ROTATION_4_1, b2 += b3); + b5 = RotlXor(b5, ROTATION_4_2, b4 += b5); + b7 = RotlXor(b7, ROTATION_4_3, b6 += b7); + b9 = RotlXor(b9, ROTATION_4_4, b8 += b9); + b11 = RotlXor(b11, ROTATION_4_5, b10 += b11); + b13 = RotlXor(b13, ROTATION_4_6, b12 += b13); + b15 = RotlXor(b15, ROTATION_4_7, b14 += b15); + + b9 = RotlXor(b9, ROTATION_5_0, b0 += b9); + b13 = RotlXor(b13, ROTATION_5_1, b2 += b13); + b11 = RotlXor(b11, ROTATION_5_2, b6 += b11); + b15 = RotlXor(b15, ROTATION_5_3, b4 += b15); + b7 = RotlXor(b7, ROTATION_5_4, b10 += b7); + b3 = RotlXor(b3, ROTATION_5_5, b12 += b3); + b5 = RotlXor(b5, ROTATION_5_6, b14 += b5); + b1 = RotlXor(b1, ROTATION_5_7, b8 += b1); + + b7 = RotlXor(b7, ROTATION_6_0, b0 += b7); + b5 = RotlXor(b5, ROTATION_6_1, b2 += b5); + b3 = RotlXor(b3, ROTATION_6_2, b4 += b3); + b1 = RotlXor(b1, ROTATION_6_3, b6 += b1); + b15 = RotlXor(b15, ROTATION_6_4, b12 += b15); + b13 = RotlXor(b13, ROTATION_6_5, b14 += b13); + b11 = RotlXor(b11, ROTATION_6_6, b8 += b11); + b9 = RotlXor(b9, ROTATION_6_7, b10 += b9); + + b15 = RotlXor(b15, ROTATION_7_0, b0 += b15); + b11 = RotlXor(b11, ROTATION_7_1, b2 += b11); + b13 = RotlXor(b13, ROTATION_7_2, b6 += b13); + b9 = RotlXor(b9, ROTATION_7_3, b4 += b9); + b1 = RotlXor(b1, ROTATION_7_4, b14 += b1); + b5 = RotlXor(b5, ROTATION_7_5, b8 += b5); + b3 = RotlXor(b3, ROTATION_7_6, b10 += b3); + b7 = RotlXor(b7, ROTATION_7_7, b12 += b7); + + /* + * Subkey injection for next 4 rounds. + */ + b0 += kw[dm17 + 1]; + b1 += kw[dm17 + 2]; + b2 += kw[dm17 + 3]; + b3 += kw[dm17 + 4]; + b4 += kw[dm17 + 5]; + b5 += kw[dm17 + 6]; + b6 += kw[dm17 + 7]; + b7 += kw[dm17 + 8]; + b8 += kw[dm17 + 9]; + b9 += kw[dm17 + 10]; + b10 += kw[dm17 + 11]; + b11 += kw[dm17 + 12]; + b12 += kw[dm17 + 13]; + b13 += kw[dm17 + 14] + t[dm3 + 1]; + b14 += kw[dm17 + 15] + t[dm3 + 2]; + b15 += kw[dm17 + 16] + (uint)d + 1; + + } + + /* + * Output cipher state. + */ + outWords[0] = b0; + outWords[1] = b1; + outWords[2] = b2; + outWords[3] = b3; + outWords[4] = b4; + outWords[5] = b5; + outWords[6] = b6; + outWords[7] = b7; + outWords[8] = b8; + outWords[9] = b9; + outWords[10] = b10; + outWords[11] = b11; + outWords[12] = b12; + outWords[13] = b13; + outWords[14] = b14; + outWords[15] = b15; + } + + internal override void DecryptBlock(ulong[] block, ulong[] state) + { + ulong[] kw = this.kw; + ulong[] t = this.t; + int[] mod17 = MOD17; + int[] mod3 = MOD3; + + /* Help the JIT avoid index bounds checks */ + if (kw.Length != 33) + { + throw new ArgumentException(); + } + if (t.Length != 5) + { + throw new ArgumentException(); + } + + ulong b0 = block[0]; + ulong b1 = block[1]; + ulong b2 = block[2]; + ulong b3 = block[3]; + ulong b4 = block[4]; + ulong b5 = block[5]; + ulong b6 = block[6]; + ulong b7 = block[7]; + ulong b8 = block[8]; + ulong b9 = block[9]; + ulong b10 = block[10]; + ulong b11 = block[11]; + ulong b12 = block[12]; + ulong b13 = block[13]; + ulong b14 = block[14]; + ulong b15 = block[15]; + + for (int d = (ROUNDS_1024 / 4) - 1; d >= 1; d -= 2) + { + int dm17 = mod17[d]; + int dm3 = mod3[d]; + + /* Reverse key injection for second 4 rounds */ + b0 -= kw[dm17 + 1]; + b1 -= kw[dm17 + 2]; + b2 -= kw[dm17 + 3]; + b3 -= kw[dm17 + 4]; + b4 -= kw[dm17 + 5]; + b5 -= kw[dm17 + 6]; + b6 -= kw[dm17 + 7]; + b7 -= kw[dm17 + 8]; + b8 -= kw[dm17 + 9]; + b9 -= kw[dm17 + 10]; + b10 -= kw[dm17 + 11]; + b11 -= kw[dm17 + 12]; + b12 -= kw[dm17 + 13]; + b13 -= kw[dm17 + 14] + t[dm3 + 1]; + b14 -= kw[dm17 + 15] + t[dm3 + 2]; + b15 -= kw[dm17 + 16] + (uint)d + 1; + + /* Reverse second 4 mix/permute rounds */ + b15 = XorRotr(b15, ROTATION_7_0, b0); + b0 -= b15; + b11 = XorRotr(b11, ROTATION_7_1, b2); + b2 -= b11; + b13 = XorRotr(b13, ROTATION_7_2, b6); + b6 -= b13; + b9 = XorRotr(b9, ROTATION_7_3, b4); + b4 -= b9; + b1 = XorRotr(b1, ROTATION_7_4, b14); + b14 -= b1; + b5 = XorRotr(b5, ROTATION_7_5, b8); + b8 -= b5; + b3 = XorRotr(b3, ROTATION_7_6, b10); + b10 -= b3; + b7 = XorRotr(b7, ROTATION_7_7, b12); + b12 -= b7; + + b7 = XorRotr(b7, ROTATION_6_0, b0); + b0 -= b7; + b5 = XorRotr(b5, ROTATION_6_1, b2); + b2 -= b5; + b3 = XorRotr(b3, ROTATION_6_2, b4); + b4 -= b3; + b1 = XorRotr(b1, ROTATION_6_3, b6); + b6 -= b1; + b15 = XorRotr(b15, ROTATION_6_4, b12); + b12 -= b15; + b13 = XorRotr(b13, ROTATION_6_5, b14); + b14 -= b13; + b11 = XorRotr(b11, ROTATION_6_6, b8); + b8 -= b11; + b9 = XorRotr(b9, ROTATION_6_7, b10); + b10 -= b9; + + b9 = XorRotr(b9, ROTATION_5_0, b0); + b0 -= b9; + b13 = XorRotr(b13, ROTATION_5_1, b2); + b2 -= b13; + b11 = XorRotr(b11, ROTATION_5_2, b6); + b6 -= b11; + b15 = XorRotr(b15, ROTATION_5_3, b4); + b4 -= b15; + b7 = XorRotr(b7, ROTATION_5_4, b10); + b10 -= b7; + b3 = XorRotr(b3, ROTATION_5_5, b12); + b12 -= b3; + b5 = XorRotr(b5, ROTATION_5_6, b14); + b14 -= b5; + b1 = XorRotr(b1, ROTATION_5_7, b8); + b8 -= b1; + + b1 = XorRotr(b1, ROTATION_4_0, b0); + b0 -= b1; + b3 = XorRotr(b3, ROTATION_4_1, b2); + b2 -= b3; + b5 = XorRotr(b5, ROTATION_4_2, b4); + b4 -= b5; + b7 = XorRotr(b7, ROTATION_4_3, b6); + b6 -= b7; + b9 = XorRotr(b9, ROTATION_4_4, b8); + b8 -= b9; + b11 = XorRotr(b11, ROTATION_4_5, b10); + b10 -= b11; + b13 = XorRotr(b13, ROTATION_4_6, b12); + b12 -= b13; + b15 = XorRotr(b15, ROTATION_4_7, b14); + b14 -= b15; + + /* Reverse key injection for first 4 rounds */ + b0 -= kw[dm17]; + b1 -= kw[dm17 + 1]; + b2 -= kw[dm17 + 2]; + b3 -= kw[dm17 + 3]; + b4 -= kw[dm17 + 4]; + b5 -= kw[dm17 + 5]; + b6 -= kw[dm17 + 6]; + b7 -= kw[dm17 + 7]; + b8 -= kw[dm17 + 8]; + b9 -= kw[dm17 + 9]; + b10 -= kw[dm17 + 10]; + b11 -= kw[dm17 + 11]; + b12 -= kw[dm17 + 12]; + b13 -= kw[dm17 + 13] + t[dm3]; + b14 -= kw[dm17 + 14] + t[dm3 + 1]; + b15 -= kw[dm17 + 15] + (uint)d; + + /* Reverse first 4 mix/permute rounds */ + b15 = XorRotr(b15, ROTATION_3_0, b0); + b0 -= b15; + b11 = XorRotr(b11, ROTATION_3_1, b2); + b2 -= b11; + b13 = XorRotr(b13, ROTATION_3_2, b6); + b6 -= b13; + b9 = XorRotr(b9, ROTATION_3_3, b4); + b4 -= b9; + b1 = XorRotr(b1, ROTATION_3_4, b14); + b14 -= b1; + b5 = XorRotr(b5, ROTATION_3_5, b8); + b8 -= b5; + b3 = XorRotr(b3, ROTATION_3_6, b10); + b10 -= b3; + b7 = XorRotr(b7, ROTATION_3_7, b12); + b12 -= b7; + + b7 = XorRotr(b7, ROTATION_2_0, b0); + b0 -= b7; + b5 = XorRotr(b5, ROTATION_2_1, b2); + b2 -= b5; + b3 = XorRotr(b3, ROTATION_2_2, b4); + b4 -= b3; + b1 = XorRotr(b1, ROTATION_2_3, b6); + b6 -= b1; + b15 = XorRotr(b15, ROTATION_2_4, b12); + b12 -= b15; + b13 = XorRotr(b13, ROTATION_2_5, b14); + b14 -= b13; + b11 = XorRotr(b11, ROTATION_2_6, b8); + b8 -= b11; + b9 = XorRotr(b9, ROTATION_2_7, b10); + b10 -= b9; + + b9 = XorRotr(b9, ROTATION_1_0, b0); + b0 -= b9; + b13 = XorRotr(b13, ROTATION_1_1, b2); + b2 -= b13; + b11 = XorRotr(b11, ROTATION_1_2, b6); + b6 -= b11; + b15 = XorRotr(b15, ROTATION_1_3, b4); + b4 -= b15; + b7 = XorRotr(b7, ROTATION_1_4, b10); + b10 -= b7; + b3 = XorRotr(b3, ROTATION_1_5, b12); + b12 -= b3; + b5 = XorRotr(b5, ROTATION_1_6, b14); + b14 -= b5; + b1 = XorRotr(b1, ROTATION_1_7, b8); + b8 -= b1; + + b1 = XorRotr(b1, ROTATION_0_0, b0); + b0 -= b1; + b3 = XorRotr(b3, ROTATION_0_1, b2); + b2 -= b3; + b5 = XorRotr(b5, ROTATION_0_2, b4); + b4 -= b5; + b7 = XorRotr(b7, ROTATION_0_3, b6); + b6 -= b7; + b9 = XorRotr(b9, ROTATION_0_4, b8); + b8 -= b9; + b11 = XorRotr(b11, ROTATION_0_5, b10); + b10 -= b11; + b13 = XorRotr(b13, ROTATION_0_6, b12); + b12 -= b13; + b15 = XorRotr(b15, ROTATION_0_7, b14); + b14 -= b15; + } + + /* + * First subkey uninjection. + */ + b0 -= kw[0]; + b1 -= kw[1]; + b2 -= kw[2]; + b3 -= kw[3]; + b4 -= kw[4]; + b5 -= kw[5]; + b6 -= kw[6]; + b7 -= kw[7]; + b8 -= kw[8]; + b9 -= kw[9]; + b10 -= kw[10]; + b11 -= kw[11]; + b12 -= kw[12]; + b13 -= kw[13] + t[0]; + b14 -= kw[14] + t[1]; + b15 -= kw[15]; + + /* + * Output cipher state. + */ + state[0] = b0; + state[1] = b1; + state[2] = b2; + state[3] = b3; + state[4] = b4; + state[5] = b5; + state[6] = b6; + state[7] = b7; + state[8] = b8; + state[9] = b9; + state[10] = b10; + state[11] = b11; + state[12] = b12; + state[13] = b13; + state[14] = b14; + state[15] = b15; + } + + } + + } +} \ No newline at end of file diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/ThreefishEngine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/ThreefishEngine.cs.meta new file mode 100644 index 0000000..d71f43a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/ThreefishEngine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5eb35ed0a6d53d14d9636fb2bd3704ba +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/TnepresEngine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/TnepresEngine.cs new file mode 100644 index 0000000..ce687d1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/TnepresEngine.cs @@ -0,0 +1,299 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * Tnepres is a 128-bit 32-round block cipher with variable key lengths, + * including 128, 192 and 256 bit keys conjectured to be at least as + * secure as three-key triple-DES. + *

+ * Tnepres is based on Serpent which was designed by Ross Anderson, Eli Biham and Lars Knudsen as a + * candidate algorithm for the NIST AES Quest. Unfortunately there was an endianness issue + * with test vectors in the AES submission and the resulting confusion lead to the Tnepres cipher + * as well, which is a byte swapped version of Serpent. + *

+ *

+ * For full details see The Serpent home page + *

+ */ + public sealed class TnepresEngine + : SerpentEngineBase + { + public override string AlgorithmName + { + get { return "Tnepres"; } + } + + /** + * Expand a user-supplied key material into a session key. + * + * @param key The user-key bytes (multiples of 4) to use. + * @exception ArgumentException + */ + protected override int[] MakeWorkingKey(byte[] key) + { + // + // pad key to 256 bits + // + int[] kPad = new int[16]; + int off = 0; + int length = 0; + + for (off = key.Length - 4; off > 0; off -= 4) + { + kPad[length++] = (int)Pack.BE_To_UInt32(key, off); + } + + if (off == 0) + { + kPad[length++] = (int)Pack.BE_To_UInt32(key, 0); + if (length < 8) + { + kPad[length] = 1; + } + } + else + { + throw new ArgumentException("key must be a multiple of 4 bytes"); + } + + // + // expand the padded key up to 33 x 128 bits of key material + // + int amount = (ROUNDS + 1) * 4; + int[] w = new int[amount]; + + // + // compute w0 to w7 from w-8 to w-1 + // + for (int i = 8; i < 16; i++) + { + kPad[i] = RotateLeft(kPad[i - 8] ^ kPad[i - 5] ^ kPad[i - 3] ^ kPad[i - 1] ^ PHI ^ (i - 8), 11); + } + + Array.Copy(kPad, 8, w, 0, 8); + + // + // compute w8 to w136 + // + for (int i = 8; i < amount; i++) + { + w[i] = RotateLeft(w[i - 8] ^ w[i - 5] ^ w[i - 3] ^ w[i - 1] ^ PHI ^ i, 11); + } + + // + // create the working keys by processing w with the Sbox and IP + // + Sb3(w[0], w[1], w[2], w[3]); + w[0] = X0; w[1] = X1; w[2] = X2; w[3] = X3; + Sb2(w[4], w[5], w[6], w[7]); + w[4] = X0; w[5] = X1; w[6] = X2; w[7] = X3; + Sb1(w[8], w[9], w[10], w[11]); + w[8] = X0; w[9] = X1; w[10] = X2; w[11] = X3; + Sb0(w[12], w[13], w[14], w[15]); + w[12] = X0; w[13] = X1; w[14] = X2; w[15] = X3; + Sb7(w[16], w[17], w[18], w[19]); + w[16] = X0; w[17] = X1; w[18] = X2; w[19] = X3; + Sb6(w[20], w[21], w[22], w[23]); + w[20] = X0; w[21] = X1; w[22] = X2; w[23] = X3; + Sb5(w[24], w[25], w[26], w[27]); + w[24] = X0; w[25] = X1; w[26] = X2; w[27] = X3; + Sb4(w[28], w[29], w[30], w[31]); + w[28] = X0; w[29] = X1; w[30] = X2; w[31] = X3; + Sb3(w[32], w[33], w[34], w[35]); + w[32] = X0; w[33] = X1; w[34] = X2; w[35] = X3; + Sb2(w[36], w[37], w[38], w[39]); + w[36] = X0; w[37] = X1; w[38] = X2; w[39] = X3; + Sb1(w[40], w[41], w[42], w[43]); + w[40] = X0; w[41] = X1; w[42] = X2; w[43] = X3; + Sb0(w[44], w[45], w[46], w[47]); + w[44] = X0; w[45] = X1; w[46] = X2; w[47] = X3; + Sb7(w[48], w[49], w[50], w[51]); + w[48] = X0; w[49] = X1; w[50] = X2; w[51] = X3; + Sb6(w[52], w[53], w[54], w[55]); + w[52] = X0; w[53] = X1; w[54] = X2; w[55] = X3; + Sb5(w[56], w[57], w[58], w[59]); + w[56] = X0; w[57] = X1; w[58] = X2; w[59] = X3; + Sb4(w[60], w[61], w[62], w[63]); + w[60] = X0; w[61] = X1; w[62] = X2; w[63] = X3; + Sb3(w[64], w[65], w[66], w[67]); + w[64] = X0; w[65] = X1; w[66] = X2; w[67] = X3; + Sb2(w[68], w[69], w[70], w[71]); + w[68] = X0; w[69] = X1; w[70] = X2; w[71] = X3; + Sb1(w[72], w[73], w[74], w[75]); + w[72] = X0; w[73] = X1; w[74] = X2; w[75] = X3; + Sb0(w[76], w[77], w[78], w[79]); + w[76] = X0; w[77] = X1; w[78] = X2; w[79] = X3; + Sb7(w[80], w[81], w[82], w[83]); + w[80] = X0; w[81] = X1; w[82] = X2; w[83] = X3; + Sb6(w[84], w[85], w[86], w[87]); + w[84] = X0; w[85] = X1; w[86] = X2; w[87] = X3; + Sb5(w[88], w[89], w[90], w[91]); + w[88] = X0; w[89] = X1; w[90] = X2; w[91] = X3; + Sb4(w[92], w[93], w[94], w[95]); + w[92] = X0; w[93] = X1; w[94] = X2; w[95] = X3; + Sb3(w[96], w[97], w[98], w[99]); + w[96] = X0; w[97] = X1; w[98] = X2; w[99] = X3; + Sb2(w[100], w[101], w[102], w[103]); + w[100] = X0; w[101] = X1; w[102] = X2; w[103] = X3; + Sb1(w[104], w[105], w[106], w[107]); + w[104] = X0; w[105] = X1; w[106] = X2; w[107] = X3; + Sb0(w[108], w[109], w[110], w[111]); + w[108] = X0; w[109] = X1; w[110] = X2; w[111] = X3; + Sb7(w[112], w[113], w[114], w[115]); + w[112] = X0; w[113] = X1; w[114] = X2; w[115] = X3; + Sb6(w[116], w[117], w[118], w[119]); + w[116] = X0; w[117] = X1; w[118] = X2; w[119] = X3; + Sb5(w[120], w[121], w[122], w[123]); + w[120] = X0; w[121] = X1; w[122] = X2; w[123] = X3; + Sb4(w[124], w[125], w[126], w[127]); + w[124] = X0; w[125] = X1; w[126] = X2; w[127] = X3; + Sb3(w[128], w[129], w[130], w[131]); + w[128] = X0; w[129] = X1; w[130] = X2; w[131] = X3; + + return w; + } + + /** + * Encrypt one block of plaintext. + * + * @param input the array containing the input data. + * @param inOff offset into the in array the data starts at. + * @param output the array the output data will be copied into. + * @param outOff the offset into the out array the output will start at. + */ + protected override void EncryptBlock(byte[] input, int inOff, byte[] output, int outOff) + { + X3 = (int)Pack.BE_To_UInt32(input, inOff); + X2 = (int)Pack.BE_To_UInt32(input, inOff + 4); + X1 = (int)Pack.BE_To_UInt32(input, inOff + 8); + X0 = (int)Pack.BE_To_UInt32(input, inOff + 12); + + Sb0(wKey[0] ^ X0, wKey[1] ^ X1, wKey[2] ^ X2, wKey[3] ^ X3); LT(); + Sb1(wKey[4] ^ X0, wKey[5] ^ X1, wKey[6] ^ X2, wKey[7] ^ X3); LT(); + Sb2(wKey[8] ^ X0, wKey[9] ^ X1, wKey[10] ^ X2, wKey[11] ^ X3); LT(); + Sb3(wKey[12] ^ X0, wKey[13] ^ X1, wKey[14] ^ X2, wKey[15] ^ X3); LT(); + Sb4(wKey[16] ^ X0, wKey[17] ^ X1, wKey[18] ^ X2, wKey[19] ^ X3); LT(); + Sb5(wKey[20] ^ X0, wKey[21] ^ X1, wKey[22] ^ X2, wKey[23] ^ X3); LT(); + Sb6(wKey[24] ^ X0, wKey[25] ^ X1, wKey[26] ^ X2, wKey[27] ^ X3); LT(); + Sb7(wKey[28] ^ X0, wKey[29] ^ X1, wKey[30] ^ X2, wKey[31] ^ X3); LT(); + Sb0(wKey[32] ^ X0, wKey[33] ^ X1, wKey[34] ^ X2, wKey[35] ^ X3); LT(); + Sb1(wKey[36] ^ X0, wKey[37] ^ X1, wKey[38] ^ X2, wKey[39] ^ X3); LT(); + Sb2(wKey[40] ^ X0, wKey[41] ^ X1, wKey[42] ^ X2, wKey[43] ^ X3); LT(); + Sb3(wKey[44] ^ X0, wKey[45] ^ X1, wKey[46] ^ X2, wKey[47] ^ X3); LT(); + Sb4(wKey[48] ^ X0, wKey[49] ^ X1, wKey[50] ^ X2, wKey[51] ^ X3); LT(); + Sb5(wKey[52] ^ X0, wKey[53] ^ X1, wKey[54] ^ X2, wKey[55] ^ X3); LT(); + Sb6(wKey[56] ^ X0, wKey[57] ^ X1, wKey[58] ^ X2, wKey[59] ^ X3); LT(); + Sb7(wKey[60] ^ X0, wKey[61] ^ X1, wKey[62] ^ X2, wKey[63] ^ X3); LT(); + Sb0(wKey[64] ^ X0, wKey[65] ^ X1, wKey[66] ^ X2, wKey[67] ^ X3); LT(); + Sb1(wKey[68] ^ X0, wKey[69] ^ X1, wKey[70] ^ X2, wKey[71] ^ X3); LT(); + Sb2(wKey[72] ^ X0, wKey[73] ^ X1, wKey[74] ^ X2, wKey[75] ^ X3); LT(); + Sb3(wKey[76] ^ X0, wKey[77] ^ X1, wKey[78] ^ X2, wKey[79] ^ X3); LT(); + Sb4(wKey[80] ^ X0, wKey[81] ^ X1, wKey[82] ^ X2, wKey[83] ^ X3); LT(); + Sb5(wKey[84] ^ X0, wKey[85] ^ X1, wKey[86] ^ X2, wKey[87] ^ X3); LT(); + Sb6(wKey[88] ^ X0, wKey[89] ^ X1, wKey[90] ^ X2, wKey[91] ^ X3); LT(); + Sb7(wKey[92] ^ X0, wKey[93] ^ X1, wKey[94] ^ X2, wKey[95] ^ X3); LT(); + Sb0(wKey[96] ^ X0, wKey[97] ^ X1, wKey[98] ^ X2, wKey[99] ^ X3); LT(); + Sb1(wKey[100] ^ X0, wKey[101] ^ X1, wKey[102] ^ X2, wKey[103] ^ X3); LT(); + Sb2(wKey[104] ^ X0, wKey[105] ^ X1, wKey[106] ^ X2, wKey[107] ^ X3); LT(); + Sb3(wKey[108] ^ X0, wKey[109] ^ X1, wKey[110] ^ X2, wKey[111] ^ X3); LT(); + Sb4(wKey[112] ^ X0, wKey[113] ^ X1, wKey[114] ^ X2, wKey[115] ^ X3); LT(); + Sb5(wKey[116] ^ X0, wKey[117] ^ X1, wKey[118] ^ X2, wKey[119] ^ X3); LT(); + Sb6(wKey[120] ^ X0, wKey[121] ^ X1, wKey[122] ^ X2, wKey[123] ^ X3); LT(); + Sb7(wKey[124] ^ X0, wKey[125] ^ X1, wKey[126] ^ X2, wKey[127] ^ X3); + + Pack.UInt32_To_BE((uint)(wKey[131] ^ X3), output, outOff); + Pack.UInt32_To_BE((uint)(wKey[130] ^ X2), output, outOff + 4); + Pack.UInt32_To_BE((uint)(wKey[129] ^ X1), output, outOff + 8); + Pack.UInt32_To_BE((uint)(wKey[128] ^ X0), output, outOff + 12); + } + + /** + * Decrypt one block of ciphertext. + * + * @param input the array containing the input data. + * @param inOff offset into the in array the data starts at. + * @param output the array the output data will be copied into. + * @param outOff the offset into the out array the output will start at. + */ + protected override void DecryptBlock(byte[] input, int inOff, byte[] output, int outOff) + { + X3 = wKey[131] ^ (int)Pack.BE_To_UInt32(input, inOff); + X2 = wKey[130] ^ (int)Pack.BE_To_UInt32(input, inOff + 4); + X1 = wKey[129] ^ (int)Pack.BE_To_UInt32(input, inOff + 8); + X0 = wKey[128] ^ (int)Pack.BE_To_UInt32(input, inOff + 12); + + Ib7(X0, X1, X2, X3); + X0 ^= wKey[124]; X1 ^= wKey[125]; X2 ^= wKey[126]; X3 ^= wKey[127]; + InverseLT(); Ib6(X0, X1, X2, X3); + X0 ^= wKey[120]; X1 ^= wKey[121]; X2 ^= wKey[122]; X3 ^= wKey[123]; + InverseLT(); Ib5(X0, X1, X2, X3); + X0 ^= wKey[116]; X1 ^= wKey[117]; X2 ^= wKey[118]; X3 ^= wKey[119]; + InverseLT(); Ib4(X0, X1, X2, X3); + X0 ^= wKey[112]; X1 ^= wKey[113]; X2 ^= wKey[114]; X3 ^= wKey[115]; + InverseLT(); Ib3(X0, X1, X2, X3); + X0 ^= wKey[108]; X1 ^= wKey[109]; X2 ^= wKey[110]; X3 ^= wKey[111]; + InverseLT(); Ib2(X0, X1, X2, X3); + X0 ^= wKey[104]; X1 ^= wKey[105]; X2 ^= wKey[106]; X3 ^= wKey[107]; + InverseLT(); Ib1(X0, X1, X2, X3); + X0 ^= wKey[100]; X1 ^= wKey[101]; X2 ^= wKey[102]; X3 ^= wKey[103]; + InverseLT(); Ib0(X0, X1, X2, X3); + X0 ^= wKey[96]; X1 ^= wKey[97]; X2 ^= wKey[98]; X3 ^= wKey[99]; + InverseLT(); Ib7(X0, X1, X2, X3); + X0 ^= wKey[92]; X1 ^= wKey[93]; X2 ^= wKey[94]; X3 ^= wKey[95]; + InverseLT(); Ib6(X0, X1, X2, X3); + X0 ^= wKey[88]; X1 ^= wKey[89]; X2 ^= wKey[90]; X3 ^= wKey[91]; + InverseLT(); Ib5(X0, X1, X2, X3); + X0 ^= wKey[84]; X1 ^= wKey[85]; X2 ^= wKey[86]; X3 ^= wKey[87]; + InverseLT(); Ib4(X0, X1, X2, X3); + X0 ^= wKey[80]; X1 ^= wKey[81]; X2 ^= wKey[82]; X3 ^= wKey[83]; + InverseLT(); Ib3(X0, X1, X2, X3); + X0 ^= wKey[76]; X1 ^= wKey[77]; X2 ^= wKey[78]; X3 ^= wKey[79]; + InverseLT(); Ib2(X0, X1, X2, X3); + X0 ^= wKey[72]; X1 ^= wKey[73]; X2 ^= wKey[74]; X3 ^= wKey[75]; + InverseLT(); Ib1(X0, X1, X2, X3); + X0 ^= wKey[68]; X1 ^= wKey[69]; X2 ^= wKey[70]; X3 ^= wKey[71]; + InverseLT(); Ib0(X0, X1, X2, X3); + X0 ^= wKey[64]; X1 ^= wKey[65]; X2 ^= wKey[66]; X3 ^= wKey[67]; + InverseLT(); Ib7(X0, X1, X2, X3); + X0 ^= wKey[60]; X1 ^= wKey[61]; X2 ^= wKey[62]; X3 ^= wKey[63]; + InverseLT(); Ib6(X0, X1, X2, X3); + X0 ^= wKey[56]; X1 ^= wKey[57]; X2 ^= wKey[58]; X3 ^= wKey[59]; + InverseLT(); Ib5(X0, X1, X2, X3); + X0 ^= wKey[52]; X1 ^= wKey[53]; X2 ^= wKey[54]; X3 ^= wKey[55]; + InverseLT(); Ib4(X0, X1, X2, X3); + X0 ^= wKey[48]; X1 ^= wKey[49]; X2 ^= wKey[50]; X3 ^= wKey[51]; + InverseLT(); Ib3(X0, X1, X2, X3); + X0 ^= wKey[44]; X1 ^= wKey[45]; X2 ^= wKey[46]; X3 ^= wKey[47]; + InverseLT(); Ib2(X0, X1, X2, X3); + X0 ^= wKey[40]; X1 ^= wKey[41]; X2 ^= wKey[42]; X3 ^= wKey[43]; + InverseLT(); Ib1(X0, X1, X2, X3); + X0 ^= wKey[36]; X1 ^= wKey[37]; X2 ^= wKey[38]; X3 ^= wKey[39]; + InverseLT(); Ib0(X0, X1, X2, X3); + X0 ^= wKey[32]; X1 ^= wKey[33]; X2 ^= wKey[34]; X3 ^= wKey[35]; + InverseLT(); Ib7(X0, X1, X2, X3); + X0 ^= wKey[28]; X1 ^= wKey[29]; X2 ^= wKey[30]; X3 ^= wKey[31]; + InverseLT(); Ib6(X0, X1, X2, X3); + X0 ^= wKey[24]; X1 ^= wKey[25]; X2 ^= wKey[26]; X3 ^= wKey[27]; + InverseLT(); Ib5(X0, X1, X2, X3); + X0 ^= wKey[20]; X1 ^= wKey[21]; X2 ^= wKey[22]; X3 ^= wKey[23]; + InverseLT(); Ib4(X0, X1, X2, X3); + X0 ^= wKey[16]; X1 ^= wKey[17]; X2 ^= wKey[18]; X3 ^= wKey[19]; + InverseLT(); Ib3(X0, X1, X2, X3); + X0 ^= wKey[12]; X1 ^= wKey[13]; X2 ^= wKey[14]; X3 ^= wKey[15]; + InverseLT(); Ib2(X0, X1, X2, X3); + X0 ^= wKey[8]; X1 ^= wKey[9]; X2 ^= wKey[10]; X3 ^= wKey[11]; + InverseLT(); Ib1(X0, X1, X2, X3); + X0 ^= wKey[4]; X1 ^= wKey[5]; X2 ^= wKey[6]; X3 ^= wKey[7]; + InverseLT(); Ib0(X0, X1, X2, X3); + + Pack.UInt32_To_BE((uint)(X3 ^ wKey[3]), output, outOff); + Pack.UInt32_To_BE((uint)(X2 ^ wKey[2]), output, outOff + 4); + Pack.UInt32_To_BE((uint)(X1 ^ wKey[1]), output, outOff + 8); + Pack.UInt32_To_BE((uint)(X0 ^ wKey[0]), output, outOff + 12); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/TnepresEngine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/TnepresEngine.cs.meta new file mode 100644 index 0000000..ce7607f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/TnepresEngine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 39449ad868cc5fb49a095fa58e651368 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/TwofishEngine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/TwofishEngine.cs new file mode 100644 index 0000000..0758451 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/TwofishEngine.cs @@ -0,0 +1,659 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * A class that provides Twofish encryption operations. + * + * This Java implementation is based on the Java reference + * implementation provided by Bruce Schneier and developed + * by Raif S. Naffah. + */ + public sealed class TwofishEngine + : IBlockCipher + { + private static readonly byte[,] P = { + { // p0 + (byte) 0xA9, (byte) 0x67, (byte) 0xB3, (byte) 0xE8, + (byte) 0x04, (byte) 0xFD, (byte) 0xA3, (byte) 0x76, + (byte) 0x9A, (byte) 0x92, (byte) 0x80, (byte) 0x78, + (byte) 0xE4, (byte) 0xDD, (byte) 0xD1, (byte) 0x38, + (byte) 0x0D, (byte) 0xC6, (byte) 0x35, (byte) 0x98, + (byte) 0x18, (byte) 0xF7, (byte) 0xEC, (byte) 0x6C, + (byte) 0x43, (byte) 0x75, (byte) 0x37, (byte) 0x26, + (byte) 0xFA, (byte) 0x13, (byte) 0x94, (byte) 0x48, + (byte) 0xF2, (byte) 0xD0, (byte) 0x8B, (byte) 0x30, + (byte) 0x84, (byte) 0x54, (byte) 0xDF, (byte) 0x23, + (byte) 0x19, (byte) 0x5B, (byte) 0x3D, (byte) 0x59, + (byte) 0xF3, (byte) 0xAE, (byte) 0xA2, (byte) 0x82, + (byte) 0x63, (byte) 0x01, (byte) 0x83, (byte) 0x2E, + (byte) 0xD9, (byte) 0x51, (byte) 0x9B, (byte) 0x7C, + (byte) 0xA6, (byte) 0xEB, (byte) 0xA5, (byte) 0xBE, + (byte) 0x16, (byte) 0x0C, (byte) 0xE3, (byte) 0x61, + (byte) 0xC0, (byte) 0x8C, (byte) 0x3A, (byte) 0xF5, + (byte) 0x73, (byte) 0x2C, (byte) 0x25, (byte) 0x0B, + (byte) 0xBB, (byte) 0x4E, (byte) 0x89, (byte) 0x6B, + (byte) 0x53, (byte) 0x6A, (byte) 0xB4, (byte) 0xF1, + (byte) 0xE1, (byte) 0xE6, (byte) 0xBD, (byte) 0x45, + (byte) 0xE2, (byte) 0xF4, (byte) 0xB6, (byte) 0x66, + (byte) 0xCC, (byte) 0x95, (byte) 0x03, (byte) 0x56, + (byte) 0xD4, (byte) 0x1C, (byte) 0x1E, (byte) 0xD7, + (byte) 0xFB, (byte) 0xC3, (byte) 0x8E, (byte) 0xB5, + (byte) 0xE9, (byte) 0xCF, (byte) 0xBF, (byte) 0xBA, + (byte) 0xEA, (byte) 0x77, (byte) 0x39, (byte) 0xAF, + (byte) 0x33, (byte) 0xC9, (byte) 0x62, (byte) 0x71, + (byte) 0x81, (byte) 0x79, (byte) 0x09, (byte) 0xAD, + (byte) 0x24, (byte) 0xCD, (byte) 0xF9, (byte) 0xD8, + (byte) 0xE5, (byte) 0xC5, (byte) 0xB9, (byte) 0x4D, + (byte) 0x44, (byte) 0x08, (byte) 0x86, (byte) 0xE7, + (byte) 0xA1, (byte) 0x1D, (byte) 0xAA, (byte) 0xED, + (byte) 0x06, (byte) 0x70, (byte) 0xB2, (byte) 0xD2, + (byte) 0x41, (byte) 0x7B, (byte) 0xA0, (byte) 0x11, + (byte) 0x31, (byte) 0xC2, (byte) 0x27, (byte) 0x90, + (byte) 0x20, (byte) 0xF6, (byte) 0x60, (byte) 0xFF, + (byte) 0x96, (byte) 0x5C, (byte) 0xB1, (byte) 0xAB, + (byte) 0x9E, (byte) 0x9C, (byte) 0x52, (byte) 0x1B, + (byte) 0x5F, (byte) 0x93, (byte) 0x0A, (byte) 0xEF, + (byte) 0x91, (byte) 0x85, (byte) 0x49, (byte) 0xEE, + (byte) 0x2D, (byte) 0x4F, (byte) 0x8F, (byte) 0x3B, + (byte) 0x47, (byte) 0x87, (byte) 0x6D, (byte) 0x46, + (byte) 0xD6, (byte) 0x3E, (byte) 0x69, (byte) 0x64, + (byte) 0x2A, (byte) 0xCE, (byte) 0xCB, (byte) 0x2F, + (byte) 0xFC, (byte) 0x97, (byte) 0x05, (byte) 0x7A, + (byte) 0xAC, (byte) 0x7F, (byte) 0xD5, (byte) 0x1A, + (byte) 0x4B, (byte) 0x0E, (byte) 0xA7, (byte) 0x5A, + (byte) 0x28, (byte) 0x14, (byte) 0x3F, (byte) 0x29, + (byte) 0x88, (byte) 0x3C, (byte) 0x4C, (byte) 0x02, + (byte) 0xB8, (byte) 0xDA, (byte) 0xB0, (byte) 0x17, + (byte) 0x55, (byte) 0x1F, (byte) 0x8A, (byte) 0x7D, + (byte) 0x57, (byte) 0xC7, (byte) 0x8D, (byte) 0x74, + (byte) 0xB7, (byte) 0xC4, (byte) 0x9F, (byte) 0x72, + (byte) 0x7E, (byte) 0x15, (byte) 0x22, (byte) 0x12, + (byte) 0x58, (byte) 0x07, (byte) 0x99, (byte) 0x34, + (byte) 0x6E, (byte) 0x50, (byte) 0xDE, (byte) 0x68, + (byte) 0x65, (byte) 0xBC, (byte) 0xDB, (byte) 0xF8, + (byte) 0xC8, (byte) 0xA8, (byte) 0x2B, (byte) 0x40, + (byte) 0xDC, (byte) 0xFE, (byte) 0x32, (byte) 0xA4, + (byte) 0xCA, (byte) 0x10, (byte) 0x21, (byte) 0xF0, + (byte) 0xD3, (byte) 0x5D, (byte) 0x0F, (byte) 0x00, + (byte) 0x6F, (byte) 0x9D, (byte) 0x36, (byte) 0x42, + (byte) 0x4A, (byte) 0x5E, (byte) 0xC1, (byte) 0xE0 }, + { // p1 + (byte) 0x75, (byte) 0xF3, (byte) 0xC6, (byte) 0xF4, + (byte) 0xDB, (byte) 0x7B, (byte) 0xFB, (byte) 0xC8, + (byte) 0x4A, (byte) 0xD3, (byte) 0xE6, (byte) 0x6B, + (byte) 0x45, (byte) 0x7D, (byte) 0xE8, (byte) 0x4B, + (byte) 0xD6, (byte) 0x32, (byte) 0xD8, (byte) 0xFD, + (byte) 0x37, (byte) 0x71, (byte) 0xF1, (byte) 0xE1, + (byte) 0x30, (byte) 0x0F, (byte) 0xF8, (byte) 0x1B, + (byte) 0x87, (byte) 0xFA, (byte) 0x06, (byte) 0x3F, + (byte) 0x5E, (byte) 0xBA, (byte) 0xAE, (byte) 0x5B, + (byte) 0x8A, (byte) 0x00, (byte) 0xBC, (byte) 0x9D, + (byte) 0x6D, (byte) 0xC1, (byte) 0xB1, (byte) 0x0E, + (byte) 0x80, (byte) 0x5D, (byte) 0xD2, (byte) 0xD5, + (byte) 0xA0, (byte) 0x84, (byte) 0x07, (byte) 0x14, + (byte) 0xB5, (byte) 0x90, (byte) 0x2C, (byte) 0xA3, + (byte) 0xB2, (byte) 0x73, (byte) 0x4C, (byte) 0x54, + (byte) 0x92, (byte) 0x74, (byte) 0x36, (byte) 0x51, + (byte) 0x38, (byte) 0xB0, (byte) 0xBD, (byte) 0x5A, + (byte) 0xFC, (byte) 0x60, (byte) 0x62, (byte) 0x96, + (byte) 0x6C, (byte) 0x42, (byte) 0xF7, (byte) 0x10, + (byte) 0x7C, (byte) 0x28, (byte) 0x27, (byte) 0x8C, + (byte) 0x13, (byte) 0x95, (byte) 0x9C, (byte) 0xC7, + (byte) 0x24, (byte) 0x46, (byte) 0x3B, (byte) 0x70, + (byte) 0xCA, (byte) 0xE3, (byte) 0x85, (byte) 0xCB, + (byte) 0x11, (byte) 0xD0, (byte) 0x93, (byte) 0xB8, + (byte) 0xA6, (byte) 0x83, (byte) 0x20, (byte) 0xFF, + (byte) 0x9F, (byte) 0x77, (byte) 0xC3, (byte) 0xCC, + (byte) 0x03, (byte) 0x6F, (byte) 0x08, (byte) 0xBF, + (byte) 0x40, (byte) 0xE7, (byte) 0x2B, (byte) 0xE2, + (byte) 0x79, (byte) 0x0C, (byte) 0xAA, (byte) 0x82, + (byte) 0x41, (byte) 0x3A, (byte) 0xEA, (byte) 0xB9, + (byte) 0xE4, (byte) 0x9A, (byte) 0xA4, (byte) 0x97, + (byte) 0x7E, (byte) 0xDA, (byte) 0x7A, (byte) 0x17, + (byte) 0x66, (byte) 0x94, (byte) 0xA1, (byte) 0x1D, + (byte) 0x3D, (byte) 0xF0, (byte) 0xDE, (byte) 0xB3, + (byte) 0x0B, (byte) 0x72, (byte) 0xA7, (byte) 0x1C, + (byte) 0xEF, (byte) 0xD1, (byte) 0x53, (byte) 0x3E, + (byte) 0x8F, (byte) 0x33, (byte) 0x26, (byte) 0x5F, + (byte) 0xEC, (byte) 0x76, (byte) 0x2A, (byte) 0x49, + (byte) 0x81, (byte) 0x88, (byte) 0xEE, (byte) 0x21, + (byte) 0xC4, (byte) 0x1A, (byte) 0xEB, (byte) 0xD9, + (byte) 0xC5, (byte) 0x39, (byte) 0x99, (byte) 0xCD, + (byte) 0xAD, (byte) 0x31, (byte) 0x8B, (byte) 0x01, + (byte) 0x18, (byte) 0x23, (byte) 0xDD, (byte) 0x1F, + (byte) 0x4E, (byte) 0x2D, (byte) 0xF9, (byte) 0x48, + (byte) 0x4F, (byte) 0xF2, (byte) 0x65, (byte) 0x8E, + (byte) 0x78, (byte) 0x5C, (byte) 0x58, (byte) 0x19, + (byte) 0x8D, (byte) 0xE5, (byte) 0x98, (byte) 0x57, + (byte) 0x67, (byte) 0x7F, (byte) 0x05, (byte) 0x64, + (byte) 0xAF, (byte) 0x63, (byte) 0xB6, (byte) 0xFE, + (byte) 0xF5, (byte) 0xB7, (byte) 0x3C, (byte) 0xA5, + (byte) 0xCE, (byte) 0xE9, (byte) 0x68, (byte) 0x44, + (byte) 0xE0, (byte) 0x4D, (byte) 0x43, (byte) 0x69, + (byte) 0x29, (byte) 0x2E, (byte) 0xAC, (byte) 0x15, + (byte) 0x59, (byte) 0xA8, (byte) 0x0A, (byte) 0x9E, + (byte) 0x6E, (byte) 0x47, (byte) 0xDF, (byte) 0x34, + (byte) 0x35, (byte) 0x6A, (byte) 0xCF, (byte) 0xDC, + (byte) 0x22, (byte) 0xC9, (byte) 0xC0, (byte) 0x9B, + (byte) 0x89, (byte) 0xD4, (byte) 0xED, (byte) 0xAB, + (byte) 0x12, (byte) 0xA2, (byte) 0x0D, (byte) 0x52, + (byte) 0xBB, (byte) 0x02, (byte) 0x2F, (byte) 0xA9, + (byte) 0xD7, (byte) 0x61, (byte) 0x1E, (byte) 0xB4, + (byte) 0x50, (byte) 0x04, (byte) 0xF6, (byte) 0xC2, + (byte) 0x16, (byte) 0x25, (byte) 0x86, (byte) 0x56, + (byte) 0x55, (byte) 0x09, (byte) 0xBE, (byte) 0x91 } + }; + + /** + * Define the fixed p0/p1 permutations used in keyed S-box lookup. + * By changing the following constant definitions, the S-boxes will + * automatically Get changed in the Twofish engine. + */ + private const int P_00 = 1; + private const int P_01 = 0; + private const int P_02 = 0; + private const int P_03 = P_01 ^ 1; + private const int P_04 = 1; + + private const int P_10 = 0; + private const int P_11 = 0; + private const int P_12 = 1; + private const int P_13 = P_11 ^ 1; + private const int P_14 = 0; + + private const int P_20 = 1; + private const int P_21 = 1; + private const int P_22 = 0; + private const int P_23 = P_21 ^ 1; + private const int P_24 = 0; + + private const int P_30 = 0; + private const int P_31 = 1; + private const int P_32 = 1; + private const int P_33 = P_31 ^ 1; + private const int P_34 = 1; + + /* Primitive polynomial for GF(256) */ + private const int GF256_FDBK = 0x169; + private const int GF256_FDBK_2 = GF256_FDBK / 2; + private const int GF256_FDBK_4 = GF256_FDBK / 4; + + private const int RS_GF_FDBK = 0x14D; // field generator + + //==================================== + // Useful constants + //==================================== + + private const int ROUNDS = 16; + private const int MAX_ROUNDS = 16; // bytes = 128 bits + private const int BLOCK_SIZE = 16; // bytes = 128 bits + private const int MAX_KEY_BITS = 256; + + private const int INPUT_WHITEN=0; + private const int OUTPUT_WHITEN=INPUT_WHITEN+BLOCK_SIZE/4; // 4 + private const int ROUND_SUBKEYS=OUTPUT_WHITEN+BLOCK_SIZE/4;// 8 + + private const int TOTAL_SUBKEYS=ROUND_SUBKEYS+2*MAX_ROUNDS;// 40 + + private const int SK_STEP = 0x02020202; + private const int SK_BUMP = 0x01010101; + private const int SK_ROTL = 9; + + private bool encrypting; + + private int[] gMDS0 = new int[MAX_KEY_BITS]; + private int[] gMDS1 = new int[MAX_KEY_BITS]; + private int[] gMDS2 = new int[MAX_KEY_BITS]; + private int[] gMDS3 = new int[MAX_KEY_BITS]; + + /** + * gSubKeys[] and gSBox[] are eventually used in the + * encryption and decryption methods. + */ + private int[] gSubKeys; + private int[] gSBox; + + private int k64Cnt; + + private byte[] workingKey; + + public TwofishEngine() + { + // calculate the MDS matrix + int[] m1 = new int[2]; + int[] mX = new int[2]; + int[] mY = new int[2]; + int j; + + for (int i=0; i< MAX_KEY_BITS ; i++) + { + j = P[0,i] & 0xff; + m1[0] = j; + mX[0] = Mx_X(j) & 0xff; + mY[0] = Mx_Y(j) & 0xff; + + j = P[1,i] & 0xff; + m1[1] = j; + mX[1] = Mx_X(j) & 0xff; + mY[1] = Mx_Y(j) & 0xff; + + gMDS0[i] = m1[P_00] | mX[P_00] << 8 | + mY[P_00] << 16 | mY[P_00] << 24; + + gMDS1[i] = mY[P_10] | mY[P_10] << 8 | + mX[P_10] << 16 | m1[P_10] << 24; + + gMDS2[i] = mX[P_20] | mY[P_20] << 8 | + m1[P_20] << 16 | mY[P_20] << 24; + + gMDS3[i] = mX[P_30] | m1[P_30] << 8 | + mY[P_30] << 16 | mX[P_30] << 24; + } + } + + /** + * initialise a Twofish cipher. + * + * @param forEncryption whether or not we are for encryption. + * @param parameters the parameters required to set up the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (!(parameters is KeyParameter)) + throw new ArgumentException("invalid parameter passed to Twofish init - " + Platform.GetTypeName(parameters)); + + this.encrypting = forEncryption; + this.workingKey = ((KeyParameter)parameters).GetKey(); + + int keyBits = this.workingKey.Length * 8; + switch (keyBits) + { + case 128: + case 192: + case 256: + break; + default: + throw new ArgumentException("Key length not 128/192/256 bits."); + } + + this.k64Cnt = this.workingKey.Length / 8; + SetKey(this.workingKey); + } + + public string AlgorithmName + { + get { return "Twofish"; } + } + + public bool IsPartialBlockOkay + { + get { return false; } + } + + public int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + if (workingKey == null) + throw new InvalidOperationException("Twofish not initialised"); + + Check.DataLength(input, inOff, BLOCK_SIZE, "input buffer too short"); + Check.OutputLength(output, outOff, BLOCK_SIZE, "output buffer too short"); + + if (encrypting) + { + EncryptBlock(input, inOff, output, outOff); + } + else + { + DecryptBlock(input, inOff, output, outOff); + } + + return BLOCK_SIZE; + } + + public void Reset() + { + if (this.workingKey != null) + { + SetKey(this.workingKey); + } + } + + public int GetBlockSize() + { + return BLOCK_SIZE; + } + + //================================== + // Private Implementation + //================================== + + private void SetKey(byte[] key) + { + int[] k32e = new int[MAX_KEY_BITS/64]; // 4 + int[] k32o = new int[MAX_KEY_BITS/64]; // 4 + + int[] sBoxKeys = new int[MAX_KEY_BITS/64]; // 4 + gSubKeys = new int[TOTAL_SUBKEYS]; + + /* + * k64Cnt is the number of 8 byte blocks (64 chunks) that are in the input key. + * The input key is 16, 24 or 32 bytes, so the range for k64Cnt is 2..4 + */ + for (int i = 0; i < k64Cnt; i++) + { + int p = i * 8; + + k32e[i] = (int)Pack.LE_To_UInt32(key, p); + k32o[i] = (int)Pack.LE_To_UInt32(key, p + 4); + + sBoxKeys[k64Cnt-1-i] = RS_MDS_Encode(k32e[i], k32o[i]); + } + + int q,A,B; + for (int i=0; i < TOTAL_SUBKEYS / 2 ; i++) + { + q = i*SK_STEP; + A = F32(q, k32e); + B = F32(q+SK_BUMP, k32o); + B = Integers.RotateLeft(B, 8); + A += B; + gSubKeys[i*2] = A; + A += B; + gSubKeys[i*2 + 1] = Integers.RotateLeft(A, SK_ROTL); + } + + /* + * fully expand the table for speed + */ + int k0 = sBoxKeys[0]; + int k1 = sBoxKeys[1]; + int k2 = sBoxKeys[2]; + int k3 = sBoxKeys[3]; + int b0, b1, b2, b3; + gSBox = new int[4*MAX_KEY_BITS]; + for (int i=0; i + *
+        * G(x) = x^4 + (a+1/a)x^3 + ax^2 + (a+1/a)x + 1
+        * 
+ * where a = primitive root of field generator 0x14D + *

+ */ + private int RS_rem(int x) + { + int b = (int) (((uint)x >> 24) & 0xff); + int g2 = ((b << 1) ^ + ((b & 0x80) != 0 ? RS_GF_FDBK : 0)) & 0xff; + int g3 = ( (int)((uint)b >> 1) ^ + ((b & 0x01) != 0 ? (int)((uint)RS_GF_FDBK >> 1) : 0)) ^ g2 ; + return ((x << 8) ^ (g3 << 24) ^ (g2 << 16) ^ (g3 << 8) ^ b); + } + + private int LFSR1(int x) + { + return (x >> 1) ^ + (((x & 0x01) != 0) ? GF256_FDBK_2 : 0); + } + + private int LFSR2(int x) + { + return (x >> 2) ^ + (((x & 0x02) != 0) ? GF256_FDBK_2 : 0) ^ + (((x & 0x01) != 0) ? GF256_FDBK_4 : 0); + } + + private int Mx_X(int x) + { + return x ^ LFSR2(x); + } // 5B + + private int Mx_Y(int x) + { + return x ^ LFSR1(x) ^ LFSR2(x); + } // EF + + private int M_b0(int x) + { + return x & 0xff; + } + + private int M_b1(int x) + { + return (int)((uint)x >> 8) & 0xff; + } + + private int M_b2(int x) + { + return (int)((uint)x >> 16) & 0xff; + } + + private int M_b3(int x) + { + return (int)((uint)x >> 24) & 0xff; + } + + private int Fe32_0(int x) + { + return gSBox[ 0x000 + 2*(x & 0xff) ] ^ + gSBox[ 0x001 + 2*((int)((uint)x >> 8) & 0xff) ] ^ + gSBox[ 0x200 + 2*((int)((uint)x >> 16) & 0xff) ] ^ + gSBox[ 0x201 + 2*((int)((uint)x >> 24) & 0xff) ]; + } + + private int Fe32_3(int x) + { + return gSBox[ 0x000 + 2*((int)((uint)x >> 24) & 0xff) ] ^ + gSBox[ 0x001 + 2*(x & 0xff) ] ^ + gSBox[ 0x200 + 2*((int)((uint)x >> 8) & 0xff) ] ^ + gSBox[ 0x201 + 2*((int)((uint)x >> 16) & 0xff) ]; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/TwofishEngine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/TwofishEngine.cs.meta new file mode 100644 index 0000000..6e6d1f8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/TwofishEngine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cc5827b37a2cecc4fb7b29ed0bfba117 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/VMPCEngine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/VMPCEngine.cs new file mode 100644 index 0000000..852901e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/VMPCEngine.cs @@ -0,0 +1,133 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Engines +{ + public class VmpcEngine + : IStreamCipher + { + /* + * variables to hold the state of the VMPC engine during encryption and + * decryption + */ + protected byte n = 0; + protected byte[] P = null; + protected byte s = 0; + + protected byte[] workingIV; + protected byte[] workingKey; + + public virtual string AlgorithmName + { + get { return "VMPC"; } + } + + /** + * initialise a VMPC cipher. + * + * @param forEncryption + * whether or not we are for encryption. + * @param params + * the parameters required to set up the cipher. + * @exception ArgumentException + * if the params argument is inappropriate. + */ + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (!(parameters is ParametersWithIV)) + throw new ArgumentException("VMPC Init parameters must include an IV"); + + ParametersWithIV ivParams = (ParametersWithIV) parameters; + + if (!(ivParams.Parameters is KeyParameter)) + throw new ArgumentException("VMPC Init parameters must include a key"); + + KeyParameter key = (KeyParameter)ivParams.Parameters; + + this.workingIV = ivParams.GetIV(); + + if (workingIV == null || workingIV.Length < 1 || workingIV.Length > 768) + throw new ArgumentException("VMPC requires 1 to 768 bytes of IV"); + + this.workingKey = key.GetKey(); + + InitKey(this.workingKey, this.workingIV); + } + + protected virtual void InitKey( + byte[] keyBytes, + byte[] ivBytes) + { + s = 0; + P = new byte[256]; + for (int i = 0; i < 256; i++) + { + P[i] = (byte) i; + } + + for (int m = 0; m < 768; m++) + { + s = P[(s + P[m & 0xff] + keyBytes[m % keyBytes.Length]) & 0xff]; + byte temp = P[m & 0xff]; + P[m & 0xff] = P[s & 0xff]; + P[s & 0xff] = temp; + } + for (int m = 0; m < 768; m++) + { + s = P[(s + P[m & 0xff] + ivBytes[m % ivBytes.Length]) & 0xff]; + byte temp = P[m & 0xff]; + P[m & 0xff] = P[s & 0xff]; + P[s & 0xff] = temp; + } + n = 0; + } + + public virtual void ProcessBytes( + byte[] input, + int inOff, + int len, + byte[] output, + int outOff) + { + Check.DataLength(input, inOff, len, "input buffer too short"); + Check.OutputLength(output, outOff, len, "output buffer too short"); + + for (int i = 0; i < len; i++) + { + s = P[(s + P[n & 0xff]) & 0xff]; + byte z = P[(P[(P[s & 0xff]) & 0xff] + 1) & 0xff]; + // encryption + byte temp = P[n & 0xff]; + P[n & 0xff] = P[s & 0xff]; + P[s & 0xff] = temp; + n = (byte) ((n + 1) & 0xff); + + // xor + output[i + outOff] = (byte) (input[i + inOff] ^ z); + } + } + + public virtual void Reset() + { + InitKey(this.workingKey, this.workingIV); + } + + public virtual byte ReturnByte( + byte input) + { + s = P[(s + P[n & 0xff]) & 0xff]; + byte z = P[(P[(P[s & 0xff]) & 0xff] + 1) & 0xff]; + // encryption + byte temp = P[n & 0xff]; + P[n & 0xff] = P[s & 0xff]; + P[s & 0xff] = temp; + n = (byte) ((n + 1) & 0xff); + + // xor + return (byte) (input ^ z); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/VMPCEngine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/VMPCEngine.cs.meta new file mode 100644 index 0000000..fa07a87 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/VMPCEngine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e6328a51ef0a0c14db1c7a2c48d35e64 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/VMPCKSA3Engine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/VMPCKSA3Engine.cs new file mode 100644 index 0000000..95b6813 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/VMPCKSA3Engine.cs @@ -0,0 +1,51 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Engines +{ + public class VmpcKsa3Engine + : VmpcEngine + { + public override string AlgorithmName + { + get { return "VMPC-KSA3"; } + } + + protected override void InitKey( + byte[] keyBytes, + byte[] ivBytes) + { + s = 0; + P = new byte[256]; + for (int i = 0; i < 256; i++) + { + P[i] = (byte) i; + } + + for (int m = 0; m < 768; m++) + { + s = P[(s + P[m & 0xff] + keyBytes[m % keyBytes.Length]) & 0xff]; + byte temp = P[m & 0xff]; + P[m & 0xff] = P[s & 0xff]; + P[s & 0xff] = temp; + } + + for (int m = 0; m < 768; m++) + { + s = P[(s + P[m & 0xff] + ivBytes[m % ivBytes.Length]) & 0xff]; + byte temp = P[m & 0xff]; + P[m & 0xff] = P[s & 0xff]; + P[s & 0xff] = temp; + } + + for (int m = 0; m < 768; m++) + { + s = P[(s + P[m & 0xff] + keyBytes[m % keyBytes.Length]) & 0xff]; + byte temp = P[m & 0xff]; + P[m & 0xff] = P[s & 0xff]; + P[s & 0xff] = temp; + } + + n = 0; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/VMPCKSA3Engine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/VMPCKSA3Engine.cs.meta new file mode 100644 index 0000000..d477afc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/VMPCKSA3Engine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d53b07fdde3f7cd488d4c178a0de7303 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/XSalsa20Engine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/XSalsa20Engine.cs new file mode 100644 index 0000000..50c51a8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/XSalsa20Engine.cs @@ -0,0 +1,64 @@ +using System; + +using Org.BouncyCastle.Crypto.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /// + /// Implementation of Daniel J. Bernstein's XSalsa20 stream cipher - Salsa20 with an extended nonce. + /// + /// + /// XSalsa20 requires a 256 bit key, and a 192 bit nonce. + /// + public class XSalsa20Engine + : Salsa20Engine + { + public override string AlgorithmName + { + get { return "XSalsa20"; } + } + + protected override int NonceSize + { + get { return 24; } + } + + /// + /// XSalsa20 key generation: process 256 bit input key and 128 bits of the input nonce + /// using a core Salsa20 function without input addition to produce 256 bit working key + /// and use that with the remaining 64 bits of nonce to initialize a standard Salsa20 engine state. + /// + protected override void SetKey(byte[] keyBytes, byte[] ivBytes) + { + if (keyBytes == null) + throw new ArgumentException(AlgorithmName + " doesn't support re-init with null key"); + + if (keyBytes.Length != 32) + throw new ArgumentException(AlgorithmName + " requires a 256 bit key"); + + // Set key for HSalsa20 + base.SetKey(keyBytes, ivBytes); + + // Pack next 64 bits of IV into engine state instead of counter + Pack.LE_To_UInt32(ivBytes, 8, engineState, 8, 2); + + // Process engine state to generate Salsa20 key + uint[] hsalsa20Out = new uint[engineState.Length]; + SalsaCore(20, engineState, hsalsa20Out); + + // Set new key, removing addition in last round of salsaCore + engineState[1] = hsalsa20Out[0] - engineState[0]; + engineState[2] = hsalsa20Out[5] - engineState[5]; + engineState[3] = hsalsa20Out[10] - engineState[10]; + engineState[4] = hsalsa20Out[15] - engineState[15]; + + engineState[11] = hsalsa20Out[6] - engineState[6]; + engineState[12] = hsalsa20Out[7] - engineState[7]; + engineState[13] = hsalsa20Out[8] - engineState[8]; + engineState[14] = hsalsa20Out[9] - engineState[9]; + + // Last 64 bits of input IV + Pack.LE_To_UInt32(ivBytes, 16, engineState, 6, 2); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/XSalsa20Engine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/XSalsa20Engine.cs.meta new file mode 100644 index 0000000..1350e43 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/XSalsa20Engine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5fe2e67f7ef78ef42a0bbda83d549427 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/XTEAEngine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/XTEAEngine.cs new file mode 100644 index 0000000..5fcfa4a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/XTEAEngine.cs @@ -0,0 +1,166 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Engines +{ + /** + * An XTEA engine. + */ + public class XteaEngine + : IBlockCipher + { + private const int + rounds = 32, + block_size = 8, +// key_size = 16, + delta = unchecked((int) 0x9E3779B9); + + /* + * the expanded key array of 4 subkeys + */ + private uint[] _S = new uint[4], + _sum0 = new uint[32], + _sum1 = new uint[32]; + private bool _initialised, _forEncryption; + + /** + * Create an instance of the TEA encryption algorithm + * and set some defaults + */ + public XteaEngine() + { + _initialised = false; + } + + public virtual string AlgorithmName + { + get { return "XTEA"; } + } + + public virtual bool IsPartialBlockOkay + { + get { return false; } + } + + public virtual int GetBlockSize() + { + return block_size; + } + + /** + * initialise + * + * @param forEncryption whether or not we are for encryption. + * @param params the parameters required to set up the cipher. + * @exception ArgumentException if the params argument is + * inappropriate. + */ + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (!(parameters is KeyParameter)) + { + throw new ArgumentException("invalid parameter passed to TEA init - " + + Platform.GetTypeName(parameters)); + } + + _forEncryption = forEncryption; + _initialised = true; + + KeyParameter p = (KeyParameter) parameters; + + setKey(p.GetKey()); + } + + public virtual int ProcessBlock( + byte[] inBytes, + int inOff, + byte[] outBytes, + int outOff) + { + if (!_initialised) + throw new InvalidOperationException(AlgorithmName + " not initialised"); + + Check.DataLength(inBytes, inOff, block_size, "input buffer too short"); + Check.OutputLength(outBytes, outOff, block_size, "output buffer too short"); + + return _forEncryption + ? encryptBlock(inBytes, inOff, outBytes, outOff) + : decryptBlock(inBytes, inOff, outBytes, outOff); + } + + public virtual void Reset() + { + } + + /** + * Re-key the cipher. + * + * @param key the key to be used + */ + private void setKey( + byte[] key) + { + int i, j; + for (i = j = 0; i < 4; i++,j+=4) + { + _S[i] = Pack.BE_To_UInt32(key, j); + } + + for (i = j = 0; i < rounds; i++) + { + _sum0[i] = ((uint)j + _S[j & 3]); + j += delta; + _sum1[i] = ((uint)j + _S[j >> 11 & 3]); + } + } + + private int encryptBlock( + byte[] inBytes, + int inOff, + byte[] outBytes, + int outOff) + { + // Pack bytes into integers + uint v0 = Pack.BE_To_UInt32(inBytes, inOff); + uint v1 = Pack.BE_To_UInt32(inBytes, inOff + 4); + + for (int i = 0; i < rounds; i++) + { + v0 += ((v1 << 4 ^ v1 >> 5) + v1) ^ _sum0[i]; + v1 += ((v0 << 4 ^ v0 >> 5) + v0) ^ _sum1[i]; + } + + Pack.UInt32_To_BE(v0, outBytes, outOff); + Pack.UInt32_To_BE(v1, outBytes, outOff + 4); + + return block_size; + } + + private int decryptBlock( + byte[] inBytes, + int inOff, + byte[] outBytes, + int outOff) + { + // Pack bytes into integers + uint v0 = Pack.BE_To_UInt32(inBytes, inOff); + uint v1 = Pack.BE_To_UInt32(inBytes, inOff + 4); + + for (int i = rounds-1; i >= 0; i--) + { + v1 -= ((v0 << 4 ^ v0 >> 5) + v0) ^ _sum1[i]; + v0 -= ((v1 << 4 ^ v1 >> 5) + v1) ^ _sum0[i]; + } + + Pack.UInt32_To_BE(v0, outBytes, outOff); + Pack.UInt32_To_BE(v1, outBytes, outOff + 4); + + return block_size; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/XTEAEngine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/XTEAEngine.cs.meta new file mode 100644 index 0000000..83a506e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/engines/XTEAEngine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c434b7957cd6abe4c8868c4254603a11 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/fpe.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/fpe.meta new file mode 100644 index 0000000..7bd2665 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/fpe.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c48a93bef30c29040904d71c136781a3 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/fpe/FpeEngine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/fpe/FpeEngine.cs new file mode 100644 index 0000000..5545b7d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/fpe/FpeEngine.cs @@ -0,0 +1,73 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Fpe +{ + /// Base class for format-preserving encryption. + public abstract class FpeEngine + { + protected readonly IBlockCipher baseCipher; + + protected bool forEncryption; + protected FpeParameters fpeParameters; + + protected FpeEngine(IBlockCipher baseCipher) + { + this.baseCipher = baseCipher; + } + + /// + /// Process length bytes from inBuf, writing the output to outBuf. + /// + /// number of bytes output. + /// input data. + /// offset in input data to start at. + /// number of bytes to process. + /// destination buffer. + /// offset to start writing at in destination buffer. + public virtual int ProcessBlock(byte[] inBuf, int inOff, int length, byte[] outBuf, int outOff) + { + if (fpeParameters == null) + throw new InvalidOperationException("FPE engine not initialized"); + if (length < 0) + throw new ArgumentException("cannot be negative", "length"); + if (inBuf == null) + throw new ArgumentNullException("inBuf"); + if (outBuf == null) + throw new ArgumentNullException("outBuf"); + + Check.DataLength(inBuf, inOff, length, "input buffer too short"); + Check.OutputLength(outBuf, outOff, length, "output buffer too short"); + + if (forEncryption) + { + return EncryptBlock(inBuf, inOff, length, outBuf, outOff); + } + else + { + return DecryptBlock(inBuf, inOff, length, outBuf, outOff); + } + } + + protected static bool IsOverrideSet(string propName) + { + string propValue = Platform.GetEnvironmentVariable(propName); + + return propValue != null && Platform.EqualsIgnoreCase("true", propValue); + } + + /// + /// Initialize the FPE engine for encryption/decryption. + /// + /// number of bytes output. + /// true if initialising for encryption, false otherwise. + /// the key and other parameters to use to set the engine up. + public abstract void Init(bool forEncryption, ICipherParameters parameters); + + protected abstract int EncryptBlock(byte[] inBuf, int inOff, int length, byte[] outBuf, int outOff); + + protected abstract int DecryptBlock(byte[] inBuf, int inOff, int length, byte[] outBuf, int outOff); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/fpe/FpeEngine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/fpe/FpeEngine.cs.meta new file mode 100644 index 0000000..fa2445a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/fpe/FpeEngine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2c7f4eb8dac303a4ba2d713d5e70d768 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/fpe/FpeFf1Engine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/fpe/FpeFf1Engine.cs new file mode 100644 index 0000000..acd31b6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/fpe/FpeFf1Engine.cs @@ -0,0 +1,83 @@ +using System; + +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; + +namespace Org.BouncyCastle.Crypto.Fpe +{ + public class FpeFf1Engine + : FpeEngine + { + public FpeFf1Engine() + : this(new AesEngine()) + { + } + + public FpeFf1Engine(IBlockCipher baseCipher) + : base(baseCipher) + { + if (IsOverrideSet(SP80038G.FPE_DISABLED) || + IsOverrideSet(SP80038G.FF1_DISABLED)) + { + throw new InvalidOperationException("FF1 encryption disabled"); + } + } + + public override void Init(bool forEncryption, ICipherParameters parameters) + { + this.forEncryption = forEncryption; + this.fpeParameters = (FpeParameters)parameters; + + baseCipher.Init(!fpeParameters.UseInverseFunction, fpeParameters.Key); + } + + protected override int EncryptBlock(byte[] inBuf, int inOff, int length, byte[] outBuf, int outOff) + { + byte[] enc; + + if (fpeParameters.Radix > 256) + { + if ((length & 1) != 0) + throw new ArgumentException("input must be an even number of bytes for a wide radix"); + + ushort[] u16In = Pack.BE_To_UInt16(inBuf, inOff, length); + ushort[] u16Out = SP80038G.EncryptFF1w(baseCipher, fpeParameters.Radix, fpeParameters.GetTweak(), + u16In, 0, u16In.Length); + enc = Pack.UInt16_To_BE(u16Out, 0, u16Out.Length); + } + else + { + enc = SP80038G.EncryptFF1(baseCipher, fpeParameters.Radix, fpeParameters.GetTweak(), inBuf, inOff, length); + } + + Array.Copy(enc, 0, outBuf, outOff, length); + + return length; + } + + protected override int DecryptBlock(byte[] inBuf, int inOff, int length, byte[] outBuf, int outOff) + { + byte[] dec; + + if (fpeParameters.Radix > 256) + { + if ((length & 1) != 0) + throw new ArgumentException("input must be an even number of bytes for a wide radix"); + + ushort[] u16In = Pack.BE_To_UInt16(inBuf, inOff, length); + ushort[] u16Out = SP80038G.DecryptFF1w(baseCipher, fpeParameters.Radix, fpeParameters.GetTweak(), + u16In, 0, u16In.Length); + dec = Pack.UInt16_To_BE(u16Out, 0, u16Out.Length); + } + else + { + dec = SP80038G.DecryptFF1(baseCipher, fpeParameters.Radix, fpeParameters.GetTweak(), inBuf, inOff, length); + } + + Array.Copy(dec, 0, outBuf, outOff, length); + + return length; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/fpe/FpeFf1Engine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/fpe/FpeFf1Engine.cs.meta new file mode 100644 index 0000000..581e7b9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/fpe/FpeFf1Engine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dd604be3b4cba4848be2e53c7dd95257 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/fpe/FpeFf3_1Engine.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/fpe/FpeFf3_1Engine.cs new file mode 100644 index 0000000..aa238e4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/fpe/FpeFf3_1Engine.cs @@ -0,0 +1,86 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Fpe +{ + public class FpeFf3_1Engine + : FpeEngine + { + public FpeFf3_1Engine() + : this(new AesEngine()) + { + } + + public FpeFf3_1Engine(IBlockCipher baseCipher) + : base(baseCipher) + { + if (IsOverrideSet(SP80038G.FPE_DISABLED)) + { + throw new InvalidOperationException("FPE disabled"); + } + } + + public override void Init(bool forEncryption, ICipherParameters parameters) + { + this.forEncryption = forEncryption; + this.fpeParameters = (FpeParameters)parameters; + + baseCipher.Init(!fpeParameters.UseInverseFunction, new KeyParameter(Arrays.Reverse(fpeParameters.Key.GetKey()))); + + if (fpeParameters.GetTweak().Length != 7) + throw new ArgumentException("tweak should be 56 bits"); + } + + protected override int EncryptBlock(byte[] inBuf, int inOff, int length, byte[] outBuf, int outOff) + { + byte[] enc; + + if (fpeParameters.Radix > 256) + { + if ((length & 1) != 0) + throw new ArgumentException("input must be an even number of bytes for a wide radix"); + + ushort[] u16In = Pack.BE_To_UInt16(inBuf, inOff, length); + ushort[] u16Out = SP80038G.EncryptFF3_1w(baseCipher, fpeParameters.Radix, fpeParameters.GetTweak(), + u16In, 0, u16In.Length); + enc = Pack.UInt16_To_BE(u16Out, 0, u16Out.Length); + } + else + { + enc = SP80038G.EncryptFF3_1(baseCipher, fpeParameters.Radix, fpeParameters.GetTweak(), inBuf, inOff, length); + } + + Array.Copy(enc, 0, outBuf, outOff, length); + + return length; + } + + protected override int DecryptBlock(byte[] inBuf, int inOff, int length, byte[] outBuf, int outOff) + { + byte[] dec; + + if (fpeParameters.Radix > 256) + { + if ((length & 1) != 0) + throw new ArgumentException("input must be an even number of bytes for a wide radix"); + + ushort[] u16In = Pack.BE_To_UInt16(inBuf, inOff, length); + ushort[] u16Out = SP80038G.DecryptFF3_1w(baseCipher, fpeParameters.Radix, fpeParameters.GetTweak(), + u16In, 0, u16In.Length); + dec = Pack.UInt16_To_BE(u16Out, 0, u16Out.Length); + } + else + { + dec = SP80038G.DecryptFF3_1(baseCipher, fpeParameters.Radix, fpeParameters.GetTweak(), inBuf, inOff, length); + } + + Array.Copy(dec, 0, outBuf, outOff, length); + + return length; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/fpe/FpeFf3_1Engine.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/fpe/FpeFf3_1Engine.cs.meta new file mode 100644 index 0000000..e5497f1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/fpe/FpeFf3_1Engine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d93167b6f40b5114bb28dd3c8e33919d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/fpe/SP80038G.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/fpe/SP80038G.cs new file mode 100644 index 0000000..53efc14 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/fpe/SP80038G.cs @@ -0,0 +1,694 @@ +using System; + +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Fpe +{ + /* + * SP800-38G Format-Preserving Encryption + * + * TODOs + * - Initialize the cipher internally or externally? + * 1. Algs 7-10 don't appear to require forward vs. inverse transform, although sample data is forward. + * 2. Algs 9-10 specify reversal of the cipher key! + * - Separate construction/initialization stage for "prerequisites" + */ + internal class SP80038G + { + internal static readonly string FPE_DISABLED = "Org.BouncyCastle.Fpe.Disable"; + internal static readonly string FF1_DISABLED = "Org.BouncyCastle.Fpe.Disable_Ff1"; + + protected static readonly int BLOCK_SIZE = 16; + protected static readonly double LOG2 = System.Math.Log(2.0); + protected static readonly double TWO_TO_96 = System.Math.Pow(2, 96); + + public static byte[] DecryptFF1(IBlockCipher cipher, int radix, byte[] tweak, byte[] buf, int off, int len) + { + checkArgs(cipher, true, radix, buf, off, len); + + // Algorithm 8 + int n = len; + int u = n / 2, v = n - u; + + ushort[] A = toShort(buf, off, u); + ushort[] B = toShort(buf, off + u, v); + + ushort[] rv = decFF1(cipher, radix, tweak, n, u, v, A, B); + + return toByte(rv); + } + + public static ushort[] DecryptFF1w(IBlockCipher cipher, int radix, byte[] tweak, ushort[] buf, int off, int len) + { + checkArgs(cipher, true, radix, buf, off, len); + + // Algorithm 8 + int n = len; + int u = n / 2, v = n - u; + + ushort[] A = new ushort[u]; + ushort[] B = new ushort[v]; + + Array.Copy(buf, off, A, 0, u); + Array.Copy(buf, off + u, B, 0, v); + + return decFF1(cipher, radix, tweak, n, u, v, A, B); + } + + private static ushort[] decFF1(IBlockCipher cipher, int radix, byte[] T, int n, int u, int v, ushort[] A, ushort[] B) + { + int t = T.Length; + int b = ((int)Ceil(System.Math.Log((double)radix) * (double)v / LOG2) + 7) / 8; + int d = (((b + 3) / 4) * 4) + 4; + + byte[] P = calculateP_FF1(radix, (byte)u, n, t); + + BigInteger bigRadix = BigInteger.ValueOf(radix); + BigInteger[] modUV = calculateModUV(bigRadix, u, v); + + int m = u; + + for (int i = 9; i >= 0; --i) + { + // i. - iv. + BigInteger y = calculateY_FF1(cipher, bigRadix, T, b, d, i, P, A); + + // v. + m = n - m; + BigInteger modulus = modUV[i & 1]; + + // vi. + BigInteger c = num(bigRadix, B).Subtract(y).Mod(modulus); + + // vii. - ix. + ushort[] C = B; + B = A; + A = C; + str(bigRadix, c, m, C, 0); + } + + return Arrays.Concatenate(A, B); + } + + public static byte[] DecryptFF3(IBlockCipher cipher, int radix, byte[] tweak64, byte[] buf, int off, int len) + { + checkArgs(cipher, false, radix, buf, off, len); + + if (tweak64.Length != 8) + { + throw new ArgumentException(); + } + + return implDecryptFF3(cipher, radix, tweak64, buf, off, len); + } + + public static byte[] DecryptFF3_1(IBlockCipher cipher, int radix, byte[] tweak56, byte[] buf, int off, int len) + { + checkArgs(cipher, false, radix, buf, off, len); + + if (tweak56.Length != 7) + { + throw new ArgumentException("tweak should be 56 bits"); + } + + byte[] tweak64 = calculateTweak64_FF3_1(tweak56); + + return implDecryptFF3(cipher, radix, tweak64, buf, off, len); + } + + public static ushort[] DecryptFF3_1w(IBlockCipher cipher, int radix, byte[] tweak56, ushort[] buf, int off, int len) + { + checkArgs(cipher, false, radix, buf, off, len); + + if (tweak56.Length != 7) + { + throw new ArgumentException("tweak should be 56 bits"); + } + + byte[] tweak64 = calculateTweak64_FF3_1(tweak56); + + return implDecryptFF3w(cipher, radix, tweak64, buf, off, len); + } + + public static byte[] EncryptFF1(IBlockCipher cipher, int radix, byte[] tweak, byte[] buf, int off, int len) + { + checkArgs(cipher, true, radix, buf, off, len); + + // Algorithm 7 + int n = len; + int u = n / 2, v = n - u; + + ushort[] A = toShort(buf, off, u); + ushort[] B = toShort(buf, off + u, v); + + return toByte(encFF1(cipher, radix, tweak, n, u, v, A, B)); + } + + public static ushort[] EncryptFF1w(IBlockCipher cipher, int radix, byte[] tweak, ushort[] buf, int off, int len) + { + checkArgs(cipher, true, radix, buf, off, len); + + // Algorithm 7 + int n = len; + int u = n / 2, v = n - u; + + ushort[] A = new ushort[u]; + ushort[] B = new ushort[v]; + + Array.Copy(buf, off, A, 0, u); + Array.Copy(buf, off + u, B, 0, v); + + return encFF1(cipher, radix, tweak, n, u, v, A, B); + } + + private static ushort[] encFF1(IBlockCipher cipher, int radix, byte[] T, int n, int u, int v, ushort[] A, ushort[] B) + { + int t = T.Length; + + int b = ((int)Ceil(System.Math.Log((double)radix) * (double)v / LOG2) + 7) / 8; + int d = (((b + 3) / 4) * 4) + 4; + + byte[] P = calculateP_FF1(radix, (byte)u, n, t); + + BigInteger bigRadix = BigInteger.ValueOf(radix); + BigInteger[] modUV = calculateModUV(bigRadix, u, v); + + int m = v; + + for (int i = 0; i < 10; ++i) + { + // i. - iv. + BigInteger y = calculateY_FF1(cipher, bigRadix, T, b, d, i, P, B); + + // v. + m = n - m; + BigInteger modulus = modUV[i & 1]; + + // vi. + BigInteger c = num(bigRadix, A).Add(y).Mod(modulus); + + // vii. - ix. + ushort[] C = A; + A = B; + B = C; + str(bigRadix, c, m, C, 0); + } + + return Arrays.Concatenate(A, B); + } + + public static byte[] EncryptFF3(IBlockCipher cipher, int radix, byte[] tweak64, byte[] buf, int off, int len) + { + checkArgs(cipher, false, radix, buf, off, len); + + if (tweak64.Length != 8) + { + throw new ArgumentException(); + } + + return implEncryptFF3(cipher, radix, tweak64, buf, off, len); + } + + public static ushort[] EncryptFF3w(IBlockCipher cipher, int radix, byte[] tweak64, ushort[] buf, int off, int len) + { + checkArgs(cipher, false, radix, buf, off, len); + + if (tweak64.Length != 8) + { + throw new ArgumentException(); + } + + return implEncryptFF3w(cipher, radix, tweak64, buf, off, len); + } + + public static ushort[] EncryptFF3_1w(IBlockCipher cipher, int radix, byte[] tweak56, ushort[] buf, int off, int len) + { + checkArgs(cipher, false, radix, buf, off, len); + + if (tweak56.Length != 7) + { + throw new ArgumentException("tweak should be 56 bits"); + } + byte[] tweak64 = calculateTweak64_FF3_1(tweak56); + + return EncryptFF3w(cipher, radix, tweak64, buf, off, len); + } + + public static byte[] EncryptFF3_1(IBlockCipher cipher, int radix, byte[] tweak56, byte[] buf, int off, int len) + { + checkArgs(cipher, false, radix, buf, off, len); + + if (tweak56.Length != 7) + { + throw new ArgumentException("tweak should be 56 bits"); + } + + byte[] tweak64 = calculateTweak64_FF3_1(tweak56); + + return EncryptFF3(cipher, radix, tweak64, buf, off, len); + } + + protected static BigInteger[] calculateModUV(BigInteger bigRadix, int u, int v) + { + BigInteger[] modUV = new BigInteger[2]; + modUV[0] = bigRadix.Pow(u); + modUV[1] = modUV[0]; + if (v != u) + { + modUV[1] = modUV[1].Multiply(bigRadix); + } + return modUV; + } + + protected static byte[] calculateP_FF1(int radix, byte uLow, int n, int t) + { + byte[] P = new byte[BLOCK_SIZE]; + P[0] = 1; + P[1] = 2; + P[2] = 1; + + // Radix + P[3] = 0; + P[4] = (byte)(radix >> 8); + P[5] = (byte)radix; + + P[6] = 10; + P[7] = uLow; + Pack.UInt32_To_BE((uint)n, P, 8); + Pack.UInt32_To_BE((uint)t, P, 12); + return P; + } + + protected static byte[] calculateTweak64_FF3_1(byte[] tweak56) + { + byte[] tweak64 = new byte[8]; + tweak64[0] = tweak56[0]; + tweak64[1] = tweak56[1]; + tweak64[2] = tweak56[2]; + tweak64[3] = (byte)(tweak56[3] & 0xF0); + tweak64[4] = tweak56[4]; + tweak64[5] = tweak56[5]; + tweak64[6] = tweak56[6]; + tweak64[7] = (byte)(tweak56[3] << 4); + + return tweak64; + } + + protected static BigInteger calculateY_FF1(IBlockCipher cipher, BigInteger bigRadix, byte[] T, int b, int d, int round, byte[] P, ushort[] AB) + { + int t = T.Length; + + // i. + BigInteger numAB = num(bigRadix, AB); + byte[] bytesAB = BigIntegers.AsUnsignedByteArray(numAB); + + int zeroes = -(t + b + 1) & 15; + byte[] Q = new byte[t + zeroes + 1 + b]; + Array.Copy(T, 0, Q, 0, t); + Q[t + zeroes] = (byte)round; + Array.Copy(bytesAB, 0, Q, Q.Length - bytesAB.Length, bytesAB.Length); + + // ii. + byte[] R = prf(cipher, Arrays.Concatenate(P, Q)); + + // iii. + byte[] sBlocks = R; + if (d > BLOCK_SIZE) + { + int sBlocksLen = (d + BLOCK_SIZE - 1) / BLOCK_SIZE; + sBlocks = new byte[sBlocksLen * BLOCK_SIZE]; + Array.Copy(R, 0, sBlocks, 0, BLOCK_SIZE); + + byte[] uint32 = new byte[4]; + for (uint j = 1; j < sBlocksLen; ++j) + { + int sOff = (int)(j * BLOCK_SIZE); + Array.Copy(R, 0, sBlocks, sOff, BLOCK_SIZE); + Pack.UInt32_To_BE(j, uint32, 0); + xor(uint32, 0, sBlocks, sOff + BLOCK_SIZE - 4, 4); + cipher.ProcessBlock(sBlocks, sOff, sBlocks, sOff); + } + } + + // iv. + return num(sBlocks, 0, d); + } + + protected static BigInteger calculateY_FF3(IBlockCipher cipher, BigInteger bigRadix, byte[] T, int wOff, uint round, ushort[] AB) + { + // ii. + byte[] P = new byte[BLOCK_SIZE]; + Pack.UInt32_To_BE(round, P, 0); + xor(T, wOff, P, 0, 4); + BigInteger numAB = num(bigRadix, AB); + + byte[] bytesAB = BigIntegers.AsUnsignedByteArray(numAB); + + if ((P.Length - bytesAB.Length) < 4) // to be sure... + { + throw new InvalidOperationException("input out of range"); + } + Array.Copy(bytesAB, 0, P, P.Length - bytesAB.Length, bytesAB.Length); + + // iii. + rev(P); + cipher.ProcessBlock(P, 0, P, 0); + rev(P); + byte[] S = P; + + // iv. + return num(S, 0, S.Length); + } + + protected static void checkArgs(IBlockCipher cipher, bool isFF1, int radix, ushort[] buf, int off, int len) + { + checkCipher(cipher); + if (radix < 2 || radix > (1 << 16)) + { + throw new ArgumentException(); + } + checkData(isFF1, radix, buf, off, len); + } + + protected static void checkArgs(IBlockCipher cipher, bool isFF1, int radix, byte[] buf, int off, int len) + { + checkCipher(cipher); + if (radix < 2 || radix > (1 << 8)) + { + throw new ArgumentException(); + } + checkData(isFF1, radix, buf, off, len); + } + + protected static void checkCipher(IBlockCipher cipher) + { + if (BLOCK_SIZE != cipher.GetBlockSize()) + { + throw new ArgumentException(); + } + } + + protected static void checkData(bool isFF1, int radix, ushort[] buf, int off, int len) + { + checkLength(isFF1, radix, len); + for (int i = 0; i < len; ++i) + { + int b = buf[off + i] & 0xFFFF; + if (b >= radix) + { + throw new ArgumentException("input data outside of radix"); + } + } + } + + protected static void checkData(bool isFF1, int radix, byte[] buf, int off, int len) + { + checkLength(isFF1, radix, len); + for (int i = 0; i < len; ++i) + { + int b = buf[off + i] & 0xFF; + if (b >= radix) + { + throw new ArgumentException("input data outside of radix"); + } + } + } + + private static void checkLength(bool isFF1, int radix, int len) + { + if (len < 2 || System.Math.Pow(radix, len) < 1000000) + { + throw new ArgumentException("input too short"); + } + if (!isFF1) + { + int maxLen = 2 * (int)(System.Math.Floor(System.Math.Log(TWO_TO_96) / System.Math.Log(radix))); + if (len > maxLen) + { + throw new ArgumentException("maximum input length is " + maxLen); + } + } + } + + protected static byte[] implDecryptFF3(IBlockCipher cipher, int radix, byte[] tweak64, byte[] buf, int off, int len) + { + // Algorithm 10 + byte[] T = tweak64; + int n = len; + int v = n / 2, u = n - v; + + ushort[] A = toShort(buf, off, u); + ushort[] B = toShort(buf, off + u, v); + + ushort[] rv = decFF3_1(cipher, radix, T, n, v, u, A, B); + + return toByte(rv); + } + + protected static ushort[] implDecryptFF3w(IBlockCipher cipher, int radix, byte[] tweak64, ushort[] buf, int off, int len) + { + // Algorithm 10 + byte[] T = tweak64; + int n = len; + int v = n / 2, u = n - v; + + ushort[] A = new ushort[u]; + ushort[] B = new ushort[v]; + + Array.Copy(buf, off, A, 0, u); + Array.Copy(buf, off + u, B, 0, v); + + return decFF3_1(cipher, radix, T, n, v, u, A, B); + } + + private static ushort[] decFF3_1(IBlockCipher cipher, int radix, byte[] T, int n, int v, int u, ushort[] A, ushort[] B) + { + BigInteger bigRadix = BigInteger.ValueOf(radix); + BigInteger[] modVU = calculateModUV(bigRadix, v, u); + + int m = u; + + // Note we keep A, B in reverse order throughout + rev(A); + rev(B); + + for (int i = 7; i >= 0; --i) + { + // i. + m = n - m; + BigInteger modulus = modVU[1 - (i & 1)]; + int wOff = 4 - ((i & 1) * 4); + + // ii. - iv. + BigInteger y = calculateY_FF3(cipher, bigRadix, T, wOff, (uint)i, A); + + // v. + BigInteger c = num(bigRadix, B).Subtract(y).Mod(modulus); + + // vi. - viii. + ushort[] C = B; + B = A; + A = C; + str(bigRadix, c, m, C, 0); + } + + rev(A); + rev(B); + + return Arrays.Concatenate(A, B); + } + + protected static byte[] implEncryptFF3(IBlockCipher cipher, int radix, byte[] tweak64, byte[] buf, int off, int len) + { + // Algorithm 9 + byte[] T = tweak64; + int n = len; + int v = n / 2, u = n - v; + + ushort[] A = toShort(buf, off, u); + ushort[] B = toShort(buf, off + u, v); + + ushort[] rv = encFF3_1(cipher, radix, T, n, v, u, A, B); + + return toByte(rv); + } + + protected static ushort[] implEncryptFF3w(IBlockCipher cipher, int radix, byte[] tweak64, ushort[] buf, int off, int len) + { + // Algorithm 9 + byte[] T = tweak64; + int n = len; + int v = n / 2, u = n - v; + + ushort[] A = new ushort[u]; + ushort[] B = new ushort[v]; + + Array.Copy(buf, off, A, 0, u); + Array.Copy(buf, off + u, B, 0, v); + + return encFF3_1(cipher, radix, T, n, v, u, A, B); + } + + private static ushort[] encFF3_1(IBlockCipher cipher, int radix, byte[] t, int n, int v, int u, ushort[] a, ushort[] b) + { + BigInteger bigRadix = BigInteger.ValueOf(radix); + BigInteger[] modVU = calculateModUV(bigRadix, v, u); + + int m = v; + + // Note we keep A, B in reverse order throughout + rev(a); + rev(b); + + for (uint i = 0; i < 8; ++i) + { + // i. + m = n - m; + BigInteger modulus = modVU[1 - (i & 1)]; + int wOff = 4 - (int)((i & 1) * 4); + + // ii. - iv. + BigInteger y = calculateY_FF3(cipher, bigRadix, t, wOff, i, b); + + // v. + BigInteger c = num(bigRadix, a).Add(y).Mod(modulus); + + // vi. - viii. + ushort[] C = a; + a = b; + b = C; + str(bigRadix, c, m, C, 0); + } + + rev(a); + rev(b); + + return Arrays.Concatenate(a, b); + } + + protected static BigInteger num(byte[] buf, int off, int len) + { + return new BigInteger(1, Arrays.CopyOfRange(buf, off, off + len)); + } + + protected static BigInteger num(BigInteger R, ushort[] x) + { + BigInteger result = BigInteger.Zero; + for (int i = 0; i < x.Length; ++i) + { + result = result.Multiply(R).Add(BigInteger.ValueOf(x[i] & 0xFFFF)); + } + return result; + } + + protected static byte[] prf(IBlockCipher c, byte[] x) + { + if ((x.Length % BLOCK_SIZE) != 0) + { + throw new ArgumentException(); + } + + int m = x.Length / BLOCK_SIZE; + byte[] y = new byte[BLOCK_SIZE]; + + for (int i = 0; i < m; ++i) + { + xor(x, i * BLOCK_SIZE, y, 0, BLOCK_SIZE); + c.ProcessBlock(y, 0, y, 0); + } + + return y; + } + + // protected static void rev(byte[] x, int xOff, byte[] y, int yOff, int len) + // { + // for (int i = 1; i <= len; ++i) + // { + // y[yOff + len - i] = x[xOff + i - 1]; + // } + // } + + protected static void rev(byte[] x) + { + int half = x.Length / 2, end = x.Length - 1; + for (int i = 0; i < half; ++i) + { + byte tmp = x[i]; + x[i] = x[end - i]; + x[end - i] = tmp; + } + } + + protected static void rev(ushort[] x) + { + int half = x.Length / 2, end = x.Length - 1; + for (int i = 0; i < half; ++i) + { + ushort tmp = x[i]; + x[i] = x[end - i]; + x[end - i] = tmp; + } + } + + protected static void str(BigInteger R, BigInteger x, int m, ushort[] output, int off) + { + if (x.SignValue < 0) + { + throw new ArgumentException(); + } + for (int i = 1; i <= m; ++i) + { + BigInteger[] qr = x.DivideAndRemainder(R); + output[off + m - i] = (ushort)qr[1].IntValue; + x = qr[0]; + } + if (x.SignValue != 0) + { + throw new ArgumentException(); + } + } + + protected static void xor(byte[] x, int xOff, byte[] y, int yOff, int len) + { + for (int i = 0; i < len; ++i) + { + y[yOff + i] ^= x[xOff + i]; + } + } + + private static byte[] toByte(ushort[] buf) + { + byte[] s = new byte[buf.Length]; + + for (int i = 0; i != s.Length; i++) + { + s[i] = (byte)buf[i]; + } + + return s; + } + + private static ushort[] toShort(byte[] buf, int off, int len) + { + ushort[] s = new ushort[len]; + + for (int i = 0; i != s.Length; i++) + { + s[i] = (ushort)(buf[off + i] & 0xFF); + } + + return s; + } + + private static int Ceil(double v) + { + int rv = (int)v; + if ((double)rv < v) + return rv + 1; + + return rv; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/fpe/SP80038G.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/fpe/SP80038G.cs.meta new file mode 100644 index 0000000..2ec20d4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/fpe/SP80038G.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 71a9a43ed933f27438fed3a1a0c27bd9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators.meta new file mode 100644 index 0000000..36e5243 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 8ed2513f4de9be14d8959123fa0356e0 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/BCrypt.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/BCrypt.cs new file mode 100644 index 0000000..6e9611a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/BCrypt.cs @@ -0,0 +1,628 @@ +using System; + +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Generators +{ + /** + * Core of password hashing scheme Bcrypt, + * designed by Niels Provos and David Mazières, + * corresponds to the C reference implementation. + *

+ * This implementation does not correspondent to the 1999 published paper + * "A Future-Adaptable Password Scheme" of Niels Provos and David Mazières, + * see: https://www.usenix.org/legacy/events/usenix99/provos/provos_html/node1.html. + * In contrast to the paper, the order of key setup and salt setup is reversed: + * state <- ExpandKey(state, 0, key) + * state %lt;- ExpandKey(state, 0, salt) + * This corresponds to the OpenBSD reference implementation of Bcrypt. + *

+ * Note: + * There is no successful cryptanalysis (status 2015), but + * the amount of memory and the band width of Bcrypt + * may be insufficient to effectively prevent attacks + * with custom hardware like FPGAs, ASICs + *

+ * This implementation uses some parts of Bouncy Castle's BlowfishEngine. + *

+ */ + public sealed class BCrypt + { + // magic String "OrpheanBeholderScryDoubt" is used as clear text for encryption + private static readonly uint[] MAGIC_STRING = + { + 0x4F727068, 0x65616E42, 0x65686F6C, + 0x64657253, 0x63727944, 0x6F756274 + }; + + internal const int MAGIC_STRING_LENGTH = 6; + + private static readonly uint[] + KP = { + 0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344, + 0xA4093822, 0x299F31D0, 0x082EFA98, 0xEC4E6C89, + 0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C, + 0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917, + 0x9216D5D9, 0x8979FB1B + }, + + KS0 = { + 0xD1310BA6, 0x98DFB5AC, 0x2FFD72DB, 0xD01ADFB7, + 0xB8E1AFED, 0x6A267E96, 0xBA7C9045, 0xF12C7F99, + 0x24A19947, 0xB3916CF7, 0x0801F2E2, 0x858EFC16, + 0x636920D8, 0x71574E69, 0xA458FEA3, 0xF4933D7E, + 0x0D95748F, 0x728EB658, 0x718BCD58, 0x82154AEE, + 0x7B54A41D, 0xC25A59B5, 0x9C30D539, 0x2AF26013, + 0xC5D1B023, 0x286085F0, 0xCA417918, 0xB8DB38EF, + 0x8E79DCB0, 0x603A180E, 0x6C9E0E8B, 0xB01E8A3E, + 0xD71577C1, 0xBD314B27, 0x78AF2FDA, 0x55605C60, + 0xE65525F3, 0xAA55AB94, 0x57489862, 0x63E81440, + 0x55CA396A, 0x2AAB10B6, 0xB4CC5C34, 0x1141E8CE, + 0xA15486AF, 0x7C72E993, 0xB3EE1411, 0x636FBC2A, + 0x2BA9C55D, 0x741831F6, 0xCE5C3E16, 0x9B87931E, + 0xAFD6BA33, 0x6C24CF5C, 0x7A325381, 0x28958677, + 0x3B8F4898, 0x6B4BB9AF, 0xC4BFE81B, 0x66282193, + 0x61D809CC, 0xFB21A991, 0x487CAC60, 0x5DEC8032, + 0xEF845D5D, 0xE98575B1, 0xDC262302, 0xEB651B88, + 0x23893E81, 0xD396ACC5, 0x0F6D6FF3, 0x83F44239, + 0x2E0B4482, 0xA4842004, 0x69C8F04A, 0x9E1F9B5E, + 0x21C66842, 0xF6E96C9A, 0x670C9C61, 0xABD388F0, + 0x6A51A0D2, 0xD8542F68, 0x960FA728, 0xAB5133A3, + 0x6EEF0B6C, 0x137A3BE4, 0xBA3BF050, 0x7EFB2A98, + 0xA1F1651D, 0x39AF0176, 0x66CA593E, 0x82430E88, + 0x8CEE8619, 0x456F9FB4, 0x7D84A5C3, 0x3B8B5EBE, + 0xE06F75D8, 0x85C12073, 0x401A449F, 0x56C16AA6, + 0x4ED3AA62, 0x363F7706, 0x1BFEDF72, 0x429B023D, + 0x37D0D724, 0xD00A1248, 0xDB0FEAD3, 0x49F1C09B, + 0x075372C9, 0x80991B7B, 0x25D479D8, 0xF6E8DEF7, + 0xE3FE501A, 0xB6794C3B, 0x976CE0BD, 0x04C006BA, + 0xC1A94FB6, 0x409F60C4, 0x5E5C9EC2, 0x196A2463, + 0x68FB6FAF, 0x3E6C53B5, 0x1339B2EB, 0x3B52EC6F, + 0x6DFC511F, 0x9B30952C, 0xCC814544, 0xAF5EBD09, + 0xBEE3D004, 0xDE334AFD, 0x660F2807, 0x192E4BB3, + 0xC0CBA857, 0x45C8740F, 0xD20B5F39, 0xB9D3FBDB, + 0x5579C0BD, 0x1A60320A, 0xD6A100C6, 0x402C7279, + 0x679F25FE, 0xFB1FA3CC, 0x8EA5E9F8, 0xDB3222F8, + 0x3C7516DF, 0xFD616B15, 0x2F501EC8, 0xAD0552AB, + 0x323DB5FA, 0xFD238760, 0x53317B48, 0x3E00DF82, + 0x9E5C57BB, 0xCA6F8CA0, 0x1A87562E, 0xDF1769DB, + 0xD542A8F6, 0x287EFFC3, 0xAC6732C6, 0x8C4F5573, + 0x695B27B0, 0xBBCA58C8, 0xE1FFA35D, 0xB8F011A0, + 0x10FA3D98, 0xFD2183B8, 0x4AFCB56C, 0x2DD1D35B, + 0x9A53E479, 0xB6F84565, 0xD28E49BC, 0x4BFB9790, + 0xE1DDF2DA, 0xA4CB7E33, 0x62FB1341, 0xCEE4C6E8, + 0xEF20CADA, 0x36774C01, 0xD07E9EFE, 0x2BF11FB4, + 0x95DBDA4D, 0xAE909198, 0xEAAD8E71, 0x6B93D5A0, + 0xD08ED1D0, 0xAFC725E0, 0x8E3C5B2F, 0x8E7594B7, + 0x8FF6E2FB, 0xF2122B64, 0x8888B812, 0x900DF01C, + 0x4FAD5EA0, 0x688FC31C, 0xD1CFF191, 0xB3A8C1AD, + 0x2F2F2218, 0xBE0E1777, 0xEA752DFE, 0x8B021FA1, + 0xE5A0CC0F, 0xB56F74E8, 0x18ACF3D6, 0xCE89E299, + 0xB4A84FE0, 0xFD13E0B7, 0x7CC43B81, 0xD2ADA8D9, + 0x165FA266, 0x80957705, 0x93CC7314, 0x211A1477, + 0xE6AD2065, 0x77B5FA86, 0xC75442F5, 0xFB9D35CF, + 0xEBCDAF0C, 0x7B3E89A0, 0xD6411BD3, 0xAE1E7E49, + 0x00250E2D, 0x2071B35E, 0x226800BB, 0x57B8E0AF, + 0x2464369B, 0xF009B91E, 0x5563911D, 0x59DFA6AA, + 0x78C14389, 0xD95A537F, 0x207D5BA2, 0x02E5B9C5, + 0x83260376, 0x6295CFA9, 0x11C81968, 0x4E734A41, + 0xB3472DCA, 0x7B14A94A, 0x1B510052, 0x9A532915, + 0xD60F573F, 0xBC9BC6E4, 0x2B60A476, 0x81E67400, + 0x08BA6FB5, 0x571BE91F, 0xF296EC6B, 0x2A0DD915, + 0xB6636521, 0xE7B9F9B6, 0xFF34052E, 0xC5855664, + 0x53B02D5D, 0xA99F8FA1, 0x08BA4799, 0x6E85076A + }, + + KS1 = { + 0x4B7A70E9, 0xB5B32944, 0xDB75092E, 0xC4192623, + 0xAD6EA6B0, 0x49A7DF7D, 0x9CEE60B8, 0x8FEDB266, + 0xECAA8C71, 0x699A17FF, 0x5664526C, 0xC2B19EE1, + 0x193602A5, 0x75094C29, 0xA0591340, 0xE4183A3E, + 0x3F54989A, 0x5B429D65, 0x6B8FE4D6, 0x99F73FD6, + 0xA1D29C07, 0xEFE830F5, 0x4D2D38E6, 0xF0255DC1, + 0x4CDD2086, 0x8470EB26, 0x6382E9C6, 0x021ECC5E, + 0x09686B3F, 0x3EBAEFC9, 0x3C971814, 0x6B6A70A1, + 0x687F3584, 0x52A0E286, 0xB79C5305, 0xAA500737, + 0x3E07841C, 0x7FDEAE5C, 0x8E7D44EC, 0x5716F2B8, + 0xB03ADA37, 0xF0500C0D, 0xF01C1F04, 0x0200B3FF, + 0xAE0CF51A, 0x3CB574B2, 0x25837A58, 0xDC0921BD, + 0xD19113F9, 0x7CA92FF6, 0x94324773, 0x22F54701, + 0x3AE5E581, 0x37C2DADC, 0xC8B57634, 0x9AF3DDA7, + 0xA9446146, 0x0FD0030E, 0xECC8C73E, 0xA4751E41, + 0xE238CD99, 0x3BEA0E2F, 0x3280BBA1, 0x183EB331, + 0x4E548B38, 0x4F6DB908, 0x6F420D03, 0xF60A04BF, + 0x2CB81290, 0x24977C79, 0x5679B072, 0xBCAF89AF, + 0xDE9A771F, 0xD9930810, 0xB38BAE12, 0xDCCF3F2E, + 0x5512721F, 0x2E6B7124, 0x501ADDE6, 0x9F84CD87, + 0x7A584718, 0x7408DA17, 0xBC9F9ABC, 0xE94B7D8C, + 0xEC7AEC3A, 0xDB851DFA, 0x63094366, 0xC464C3D2, + 0xEF1C1847, 0x3215D908, 0xDD433B37, 0x24C2BA16, + 0x12A14D43, 0x2A65C451, 0x50940002, 0x133AE4DD, + 0x71DFF89E, 0x10314E55, 0x81AC77D6, 0x5F11199B, + 0x043556F1, 0xD7A3C76B, 0x3C11183B, 0x5924A509, + 0xF28FE6ED, 0x97F1FBFA, 0x9EBABF2C, 0x1E153C6E, + 0x86E34570, 0xEAE96FB1, 0x860E5E0A, 0x5A3E2AB3, + 0x771FE71C, 0x4E3D06FA, 0x2965DCB9, 0x99E71D0F, + 0x803E89D6, 0x5266C825, 0x2E4CC978, 0x9C10B36A, + 0xC6150EBA, 0x94E2EA78, 0xA5FC3C53, 0x1E0A2DF4, + 0xF2F74EA7, 0x361D2B3D, 0x1939260F, 0x19C27960, + 0x5223A708, 0xF71312B6, 0xEBADFE6E, 0xEAC31F66, + 0xE3BC4595, 0xA67BC883, 0xB17F37D1, 0x018CFF28, + 0xC332DDEF, 0xBE6C5AA5, 0x65582185, 0x68AB9802, + 0xEECEA50F, 0xDB2F953B, 0x2AEF7DAD, 0x5B6E2F84, + 0x1521B628, 0x29076170, 0xECDD4775, 0x619F1510, + 0x13CCA830, 0xEB61BD96, 0x0334FE1E, 0xAA0363CF, + 0xB5735C90, 0x4C70A239, 0xD59E9E0B, 0xCBAADE14, + 0xEECC86BC, 0x60622CA7, 0x9CAB5CAB, 0xB2F3846E, + 0x648B1EAF, 0x19BDF0CA, 0xA02369B9, 0x655ABB50, + 0x40685A32, 0x3C2AB4B3, 0x319EE9D5, 0xC021B8F7, + 0x9B540B19, 0x875FA099, 0x95F7997E, 0x623D7DA8, + 0xF837889A, 0x97E32D77, 0x11ED935F, 0x16681281, + 0x0E358829, 0xC7E61FD6, 0x96DEDFA1, 0x7858BA99, + 0x57F584A5, 0x1B227263, 0x9B83C3FF, 0x1AC24696, + 0xCDB30AEB, 0x532E3054, 0x8FD948E4, 0x6DBC3128, + 0x58EBF2EF, 0x34C6FFEA, 0xFE28ED61, 0xEE7C3C73, + 0x5D4A14D9, 0xE864B7E3, 0x42105D14, 0x203E13E0, + 0x45EEE2B6, 0xA3AAABEA, 0xDB6C4F15, 0xFACB4FD0, + 0xC742F442, 0xEF6ABBB5, 0x654F3B1D, 0x41CD2105, + 0xD81E799E, 0x86854DC7, 0xE44B476A, 0x3D816250, + 0xCF62A1F2, 0x5B8D2646, 0xFC8883A0, 0xC1C7B6A3, + 0x7F1524C3, 0x69CB7492, 0x47848A0B, 0x5692B285, + 0x095BBF00, 0xAD19489D, 0x1462B174, 0x23820E00, + 0x58428D2A, 0x0C55F5EA, 0x1DADF43E, 0x233F7061, + 0x3372F092, 0x8D937E41, 0xD65FECF1, 0x6C223BDB, + 0x7CDE3759, 0xCBEE7460, 0x4085F2A7, 0xCE77326E, + 0xA6078084, 0x19F8509E, 0xE8EFD855, 0x61D99735, + 0xA969A7AA, 0xC50C06C2, 0x5A04ABFC, 0x800BCADC, + 0x9E447A2E, 0xC3453484, 0xFDD56705, 0x0E1E9EC9, + 0xDB73DBD3, 0x105588CD, 0x675FDA79, 0xE3674340, + 0xC5C43465, 0x713E38D8, 0x3D28F89E, 0xF16DFF20, + 0x153E21E7, 0x8FB03D4A, 0xE6E39F2B, 0xDB83ADF7 + }, + + KS2 = { + 0xE93D5A68, 0x948140F7, 0xF64C261C, 0x94692934, + 0x411520F7, 0x7602D4F7, 0xBCF46B2E, 0xD4A20068, + 0xD4082471, 0x3320F46A, 0x43B7D4B7, 0x500061AF, + 0x1E39F62E, 0x97244546, 0x14214F74, 0xBF8B8840, + 0x4D95FC1D, 0x96B591AF, 0x70F4DDD3, 0x66A02F45, + 0xBFBC09EC, 0x03BD9785, 0x7FAC6DD0, 0x31CB8504, + 0x96EB27B3, 0x55FD3941, 0xDA2547E6, 0xABCA0A9A, + 0x28507825, 0x530429F4, 0x0A2C86DA, 0xE9B66DFB, + 0x68DC1462, 0xD7486900, 0x680EC0A4, 0x27A18DEE, + 0x4F3FFEA2, 0xE887AD8C, 0xB58CE006, 0x7AF4D6B6, + 0xAACE1E7C, 0xD3375FEC, 0xCE78A399, 0x406B2A42, + 0x20FE9E35, 0xD9F385B9, 0xEE39D7AB, 0x3B124E8B, + 0x1DC9FAF7, 0x4B6D1856, 0x26A36631, 0xEAE397B2, + 0x3A6EFA74, 0xDD5B4332, 0x6841E7F7, 0xCA7820FB, + 0xFB0AF54E, 0xD8FEB397, 0x454056AC, 0xBA489527, + 0x55533A3A, 0x20838D87, 0xFE6BA9B7, 0xD096954B, + 0x55A867BC, 0xA1159A58, 0xCCA92963, 0x99E1DB33, + 0xA62A4A56, 0x3F3125F9, 0x5EF47E1C, 0x9029317C, + 0xFDF8E802, 0x04272F70, 0x80BB155C, 0x05282CE3, + 0x95C11548, 0xE4C66D22, 0x48C1133F, 0xC70F86DC, + 0x07F9C9EE, 0x41041F0F, 0x404779A4, 0x5D886E17, + 0x325F51EB, 0xD59BC0D1, 0xF2BCC18F, 0x41113564, + 0x257B7834, 0x602A9C60, 0xDFF8E8A3, 0x1F636C1B, + 0x0E12B4C2, 0x02E1329E, 0xAF664FD1, 0xCAD18115, + 0x6B2395E0, 0x333E92E1, 0x3B240B62, 0xEEBEB922, + 0x85B2A20E, 0xE6BA0D99, 0xDE720C8C, 0x2DA2F728, + 0xD0127845, 0x95B794FD, 0x647D0862, 0xE7CCF5F0, + 0x5449A36F, 0x877D48FA, 0xC39DFD27, 0xF33E8D1E, + 0x0A476341, 0x992EFF74, 0x3A6F6EAB, 0xF4F8FD37, + 0xA812DC60, 0xA1EBDDF8, 0x991BE14C, 0xDB6E6B0D, + 0xC67B5510, 0x6D672C37, 0x2765D43B, 0xDCD0E804, + 0xF1290DC7, 0xCC00FFA3, 0xB5390F92, 0x690FED0B, + 0x667B9FFB, 0xCEDB7D9C, 0xA091CF0B, 0xD9155EA3, + 0xBB132F88, 0x515BAD24, 0x7B9479BF, 0x763BD6EB, + 0x37392EB3, 0xCC115979, 0x8026E297, 0xF42E312D, + 0x6842ADA7, 0xC66A2B3B, 0x12754CCC, 0x782EF11C, + 0x6A124237, 0xB79251E7, 0x06A1BBE6, 0x4BFB6350, + 0x1A6B1018, 0x11CAEDFA, 0x3D25BDD8, 0xE2E1C3C9, + 0x44421659, 0x0A121386, 0xD90CEC6E, 0xD5ABEA2A, + 0x64AF674E, 0xDA86A85F, 0xBEBFE988, 0x64E4C3FE, + 0x9DBC8057, 0xF0F7C086, 0x60787BF8, 0x6003604D, + 0xD1FD8346, 0xF6381FB0, 0x7745AE04, 0xD736FCCC, + 0x83426B33, 0xF01EAB71, 0xB0804187, 0x3C005E5F, + 0x77A057BE, 0xBDE8AE24, 0x55464299, 0xBF582E61, + 0x4E58F48F, 0xF2DDFDA2, 0xF474EF38, 0x8789BDC2, + 0x5366F9C3, 0xC8B38E74, 0xB475F255, 0x46FCD9B9, + 0x7AEB2661, 0x8B1DDF84, 0x846A0E79, 0x915F95E2, + 0x466E598E, 0x20B45770, 0x8CD55591, 0xC902DE4C, + 0xB90BACE1, 0xBB8205D0, 0x11A86248, 0x7574A99E, + 0xB77F19B6, 0xE0A9DC09, 0x662D09A1, 0xC4324633, + 0xE85A1F02, 0x09F0BE8C, 0x4A99A025, 0x1D6EFE10, + 0x1AB93D1D, 0x0BA5A4DF, 0xA186F20F, 0x2868F169, + 0xDCB7DA83, 0x573906FE, 0xA1E2CE9B, 0x4FCD7F52, + 0x50115E01, 0xA70683FA, 0xA002B5C4, 0x0DE6D027, + 0x9AF88C27, 0x773F8641, 0xC3604C06, 0x61A806B5, + 0xF0177A28, 0xC0F586E0, 0x006058AA, 0x30DC7D62, + 0x11E69ED7, 0x2338EA63, 0x53C2DD94, 0xC2C21634, + 0xBBCBEE56, 0x90BCB6DE, 0xEBFC7DA1, 0xCE591D76, + 0x6F05E409, 0x4B7C0188, 0x39720A3D, 0x7C927C24, + 0x86E3725F, 0x724D9DB9, 0x1AC15BB4, 0xD39EB8FC, + 0xED545578, 0x08FCA5B5, 0xD83D7CD3, 0x4DAD0FC4, + 0x1E50EF5E, 0xB161E6F8, 0xA28514D9, 0x6C51133C, + 0x6FD5C7E7, 0x56E14EC4, 0x362ABFCE, 0xDDC6C837, + 0xD79A3234, 0x92638212, 0x670EFA8E, 0x406000E0 + }, + + KS3 = { + 0x3A39CE37, 0xD3FAF5CF, 0xABC27737, 0x5AC52D1B, + 0x5CB0679E, 0x4FA33742, 0xD3822740, 0x99BC9BBE, + 0xD5118E9D, 0xBF0F7315, 0xD62D1C7E, 0xC700C47B, + 0xB78C1B6B, 0x21A19045, 0xB26EB1BE, 0x6A366EB4, + 0x5748AB2F, 0xBC946E79, 0xC6A376D2, 0x6549C2C8, + 0x530FF8EE, 0x468DDE7D, 0xD5730A1D, 0x4CD04DC6, + 0x2939BBDB, 0xA9BA4650, 0xAC9526E8, 0xBE5EE304, + 0xA1FAD5F0, 0x6A2D519A, 0x63EF8CE2, 0x9A86EE22, + 0xC089C2B8, 0x43242EF6, 0xA51E03AA, 0x9CF2D0A4, + 0x83C061BA, 0x9BE96A4D, 0x8FE51550, 0xBA645BD6, + 0x2826A2F9, 0xA73A3AE1, 0x4BA99586, 0xEF5562E9, + 0xC72FEFD3, 0xF752F7DA, 0x3F046F69, 0x77FA0A59, + 0x80E4A915, 0x87B08601, 0x9B09E6AD, 0x3B3EE593, + 0xE990FD5A, 0x9E34D797, 0x2CF0B7D9, 0x022B8B51, + 0x96D5AC3A, 0x017DA67D, 0xD1CF3ED6, 0x7C7D2D28, + 0x1F9F25CF, 0xADF2B89B, 0x5AD6B472, 0x5A88F54C, + 0xE029AC71, 0xE019A5E6, 0x47B0ACFD, 0xED93FA9B, + 0xE8D3C48D, 0x283B57CC, 0xF8D56629, 0x79132E28, + 0x785F0191, 0xED756055, 0xF7960E44, 0xE3D35E8C, + 0x15056DD4, 0x88F46DBA, 0x03A16125, 0x0564F0BD, + 0xC3EB9E15, 0x3C9057A2, 0x97271AEC, 0xA93A072A, + 0x1B3F6D9B, 0x1E6321F5, 0xF59C66FB, 0x26DCF319, + 0x7533D928, 0xB155FDF5, 0x03563482, 0x8ABA3CBB, + 0x28517711, 0xC20AD9F8, 0xABCC5167, 0xCCAD925F, + 0x4DE81751, 0x3830DC8E, 0x379D5862, 0x9320F991, + 0xEA7A90C2, 0xFB3E7BCE, 0x5121CE64, 0x774FBE32, + 0xA8B6E37E, 0xC3293D46, 0x48DE5369, 0x6413E680, + 0xA2AE0810, 0xDD6DB224, 0x69852DFD, 0x09072166, + 0xB39A460A, 0x6445C0DD, 0x586CDECF, 0x1C20C8AE, + 0x5BBEF7DD, 0x1B588D40, 0xCCD2017F, 0x6BB4E3BB, + 0xDDA26A7E, 0x3A59FF45, 0x3E350A44, 0xBCB4CDD5, + 0x72EACEA8, 0xFA6484BB, 0x8D6612AE, 0xBF3C6F47, + 0xD29BE463, 0x542F5D9E, 0xAEC2771B, 0xF64E6370, + 0x740E0D8D, 0xE75B1357, 0xF8721671, 0xAF537D5D, + 0x4040CB08, 0x4EB4E2CC, 0x34D2466A, 0x0115AF84, + 0xE1B00428, 0x95983A1D, 0x06B89FB4, 0xCE6EA048, + 0x6F3F3B82, 0x3520AB82, 0x011A1D4B, 0x277227F8, + 0x611560B1, 0xE7933FDC, 0xBB3A792B, 0x344525BD, + 0xA08839E1, 0x51CE794B, 0x2F32C9B7, 0xA01FBAC9, + 0xE01CC87E, 0xBCC7D1F6, 0xCF0111C3, 0xA1E8AAC7, + 0x1A908749, 0xD44FBD9A, 0xD0DADECB, 0xD50ADA38, + 0x0339C32A, 0xC6913667, 0x8DF9317C, 0xE0B12B4F, + 0xF79E59B7, 0x43F5BB3A, 0xF2D519FF, 0x27D9459C, + 0xBF97222C, 0x15E6FC2A, 0x0F91FC71, 0x9B941525, + 0xFAE59361, 0xCEB69CEB, 0xC2A86459, 0x12BAA8D1, + 0xB6C1075E, 0xE3056A0C, 0x10D25065, 0xCB03A442, + 0xE0EC6E0E, 0x1698DB3B, 0x4C98A0BE, 0x3278E964, + 0x9F1F9532, 0xE0D392DF, 0xD3A0342B, 0x8971F21E, + 0x1B0A7441, 0x4BA3348C, 0xC5BE7120, 0xC37632D8, + 0xDF359F8D, 0x9B992F2E, 0xE60B6F47, 0x0FE3F11D, + 0xE54CDA54, 0x1EDAD891, 0xCE6279CF, 0xCD3E7E6F, + 0x1618B166, 0xFD2C1D05, 0x848FD2C5, 0xF6FB2299, + 0xF523F357, 0xA6327623, 0x93A83531, 0x56CCCD02, + 0xACF08162, 0x5A75EBB5, 0x6E163697, 0x88D273CC, + 0xDE966292, 0x81B949D0, 0x4C50901B, 0x71C65614, + 0xE6C6C7BD, 0x327A140A, 0x45E1D006, 0xC3F27B9A, + 0xC9AA53FD, 0x62A80F00, 0xBB25BFE2, 0x35BDD2F6, + 0x71126905, 0xB2040222, 0xB6CBCF7C, 0xCD769C2B, + 0x53113EC0, 0x1640E3D3, 0x38ABBD60, 0x2547ADF0, + 0xBA38209C, 0xF746CE76, 0x77AFA1C5, 0x20756060, + 0x85CBFE4E, 0x8AE88DD8, 0x7AAAF9B0, 0x4CF9AA7E, + 0x1948C25C, 0x02FB8A8C, 0x01C36AE4, 0xD6EBE1F9, + 0x90D4F869, 0xA65CDEA0, 0x3F09252D, 0xC208E69F, + 0xB74E6132, 0xCE77E25B, 0x578FDFE3, 0x3AC372E6 + }; + + //==================================== + // Useful constants + //==================================== + + private const int ROUNDS = 16; + private const int SBOX_SK = 256; + private const int SBOX_SK2 = SBOX_SK * 2; + private const int SBOX_SK3 = SBOX_SK * 3; + private const int P_SZ = ROUNDS + 2; + + private readonly uint[] S; // the s-boxes + private readonly uint[] P; // the p-array + + private BCrypt() + { + S = new uint[SBOX_SK * 4]; + P = new uint[P_SZ]; + } + + //================================== + // Private Implementation + //================================== + + private uint F(uint x) + { + return (((S[(x >> 24)] + S[SBOX_SK + ((x >> 16) & 0xff)]) + ^ S[SBOX_SK2 + ((x >> 8) & 0xff)]) + S[SBOX_SK3 + (x & 0xff)]); + } + + /* + * apply the encryption cycle to each value pair in the table. + */ + private void ProcessTable(uint xl, uint xr, uint[] table) + { + int size = table.Length; + + for (int s = 0; s < size; s += 2) + { + xl ^= P[0]; + + for (int i = 1; i < ROUNDS; i += 2) + { + xr ^= F(xl) ^ P[i]; + xl ^= F(xr) ^ P[i + 1]; + } + + xr ^= P[ROUNDS + 1]; + + table[s] = xr; + table[s + 1] = xl; + + xr = xl; // end of cycle swap + xl = table[s]; + } + } + + /* + * Initialize the S-boxes and the P-array, with a fixed string + * This string contains the hexadecimal digits of pi (3.141...) + */ + private void InitState() + { + Array.Copy(KS0, 0, S, 0, SBOX_SK); + Array.Copy(KS1, 0, S, SBOX_SK, SBOX_SK); + Array.Copy(KS2, 0, S, SBOX_SK2, SBOX_SK); + Array.Copy(KS3, 0, S, SBOX_SK3, SBOX_SK); + + Array.Copy(KP, 0, P, 0, P_SZ); + } + + /* + * XOR P with key cyclic. + * This is the first part of ExpandKey function + */ + private void CyclicXorKey(byte[] key) + { + int keyLength = key.Length; + int keyIndex = 0; + + for (int i = 0; i < P_SZ; i++) + { + // get the 32 bits of the key, in 4 * 8 bit chunks + uint data = 0x0000000; + for (int j = 0; j < 4; j++) + { + // create a 32 bit block + data = (data << 8) | key[keyIndex]; + + // wrap when we get to the end of the key + if (++keyIndex >= keyLength) + { + keyIndex = 0; + } + } + // XOR the newly created 32 bit chunk onto the P-array + P[i] ^= data; + } + } + + + /* + * encrypt magic String 64 times in ECB + */ + private byte[] EncryptMagicString() + { + uint[] text = { + MAGIC_STRING[0], MAGIC_STRING[1], + MAGIC_STRING[2], MAGIC_STRING[3], + MAGIC_STRING[4], MAGIC_STRING[5] + }; + for (int i = 0; i < 64; i++) + { + for (int j = 0; j < MAGIC_STRING_LENGTH; j += 2) + { + uint left = text[j]; + uint right = text[j + 1]; + + left ^= P[0]; + for (int k = 1; k < ROUNDS; k += 2) + { + right ^= F(left) ^ P[k]; + left ^= F(right) ^ P[k + 1]; + } + right ^= P[ROUNDS + 1]; + // swap values: + text[j] = right; + text[j + 1] = left; + } + } + byte[] result = new byte[24]; // holds 192 bit key + Pack.UInt32_To_BE(text, result, 0); + Array.Clear(text, 0, text.Length); + Array.Clear(P, 0, P.Length); + Array.Clear(S, 0, S.Length); + + return result; + } + + /* + * This is a part of Eksblowfish function + * + * @param table: sub-keys or working key + * @param salt32Bit: a 16 byte salt as two 32 bit words + * @param iv1: value from last proceeded table + * @param iv2: value from last proceeded table + */ + private void ProcessTableWithSalt(uint[] table, uint[] salt32Bit, uint iv1, uint iv2) + { + uint xl = iv1 ^ salt32Bit[0]; + uint xr = iv2 ^ salt32Bit[1]; + + uint yl; + uint yr; + int size = table.Length; + + for (int s = 0; s < size; s += 4) + { + xl ^= P[0]; + for (int i = 1; i < ROUNDS; i += 2) + { + xr ^= F(xl) ^ P[i]; + xl ^= F(xr) ^ P[i + 1]; + } + xr ^= P[ROUNDS + 1]; + + table[s] = xr; + table[s + 1] = xl; + + yl = salt32Bit[2] ^ xr; + yr = salt32Bit[3] ^ xl; + + if (s + 2 >= size) // P holds 18 values + { + break; + } + + yl ^= P[0]; + for (int i = 1; i < ROUNDS; i += 2) + { + yr ^= F(yl) ^ P[i]; + yl ^= F(yr) ^ P[i + 1]; + } + yr ^= P[ROUNDS + 1]; + + table[s + 2] = yr; + table[s + 3] = yl; + + xl = salt32Bit[0] ^ yr; + xr = salt32Bit[1] ^ yl; + } + } + + /** + * Derives a raw 192 bit Bcrypt key + * + * @param cost the cost factor, treated as an exponent of 2 + * @param salt a 16 byte salt + * @param psw the password + * @return a 192 bit key + */ + private byte[] DeriveRawKey(int cost, byte[] salt, byte[] psw) + { + if (salt.Length != 16) + throw new DataLengthException("Invalid salt size: 16 bytes expected."); + if (cost < 4 || cost > 31) + throw new ArgumentException("Illegal cost factor: 4 - 31 expected.", "cost"); + + if (psw.Length == 0) + { + psw = new byte[4]; + } + + // state <- InitState() + InitState(); + + uint[] salt32Bit = new uint[4]; // holds 16 byte salt + Pack.BE_To_UInt32(salt, 0, salt32Bit); + + uint[] salt32Bit2 = new uint[salt.Length]; // swapped values + salt32Bit2[0] = salt32Bit[2]; + salt32Bit2[1] = salt32Bit[3]; + salt32Bit2[2] = salt32Bit[0]; + salt32Bit2[3] = salt32Bit[1]; + + // ExpandKey( state, salt, key): + CyclicXorKey(psw); + ProcessTableWithSalt(P, salt32Bit, 0, 0); + Array.Clear(salt32Bit, 0, salt32Bit.Length); + ProcessTableWithSalt(S, salt32Bit2, P[P.Length - 2], P[P.Length - 1]); + Array.Clear(salt32Bit2, 0, salt32Bit2.Length); + + int rounds = 1 << cost; + for (int i = 0; i != rounds; i++) // rounds may be negative if cost is 31 + { + // state <- ExpandKey(state, 0, key); + CyclicXorKey(psw); + ProcessTable(0, 0, P); + ProcessTable(P[P_SZ - 2], P[P_SZ - 1], S); + + // state <- ExpandKey(state, 0, salt); + CyclicXorKey(salt); + ProcessTable(0, 0, P); + ProcessTable(P[P_SZ - 2], P[P_SZ - 1], S); + } + + // encrypt magicString 64 times + return EncryptMagicString(); + } + + /** + * Size of the salt parameter in bytes + */ + internal const int SALT_SIZE_BYTES = 16; + + /** + * Minimum value of cost parameter, equal to log2(bytes of salt) + */ + internal const int MIN_COST = 4; + + /** + * Maximum value of cost parameter (31 == 2,147,483,648) + */ + internal const int MAX_COST = 31; + + /** + * Maximum size of password == max (unrestricted) size of Blowfish key + */ + // Blowfish spec limits keys to 448bit/56 bytes to ensure all bits of key affect all ciphertext + // bits, but technically algorithm handles 72 byte keys and most implementations support this. + internal const int MAX_PASSWORD_BYTES = 72; + + /** + * Converts a character password to bytes incorporating the required trailing zero byte. + * + * @param password the password to be encoded. + * @return a byte representation of the password in UTF8 + trailing zero. + */ + public static byte[] PasswordToByteArray(char[] password) + { + return Arrays.Append(Strings.ToUtf8ByteArray(password), 0); + } + + /** + * Calculates the bcrypt hash of a password. + *

+ * This implements the raw bcrypt function as defined in the bcrypt specification, not + * the crypt encoded version implemented in OpenBSD. + *

+ * @param password the password bytes (up to 72 bytes) to use for this invocation. + * @param salt the 128 bit salt to use for this invocation. + * @param cost the bcrypt cost parameter. The cost of the bcrypt function grows as + * 2^cost. Legal values are 4..31 inclusive. + * @return the output of the raw bcrypt operation: a 192 bit (24 byte) hash. + */ + public static byte[] Generate(byte[] password, byte[] salt, int cost) + { + if (password == null) + throw new ArgumentNullException("password"); + if (password.Length > MAX_PASSWORD_BYTES) + throw new ArgumentException("BCrypt password must be <= 72 bytes", "password"); + if (salt == null) + throw new ArgumentNullException("salt"); + if (salt.Length != SALT_SIZE_BYTES) + throw new ArgumentException("BCrypt salt must be 128 bits", "salt"); + if (cost < MIN_COST || cost > MAX_COST) + throw new ArgumentException("BCrypt cost must be from 4..31", "cost"); + + return new BCrypt().DeriveRawKey(cost, salt, password); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/BCrypt.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/BCrypt.cs.meta new file mode 100644 index 0000000..1b64faa --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/BCrypt.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e238961b7b74de348a97a90691be141c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/BaseKdfBytesGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/BaseKdfBytesGenerator.cs new file mode 100644 index 0000000..bca4207 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/BaseKdfBytesGenerator.cs @@ -0,0 +1,132 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; + +namespace Org.BouncyCastle.Crypto.Generators +{ + /** + * Basic KDF generator for derived keys and ivs as defined by IEEE P1363a/ISO 18033 + *
+ * This implementation is based on ISO 18033/P1363a. + */ + public class BaseKdfBytesGenerator + : IDerivationFunction + { + private int counterStart; + private IDigest digest; + private byte[] shared; + private byte[] iv; + + /** + * Construct a KDF Parameters generator. + * + * @param counterStart value of counter. + * @param digest the digest to be used as the source of derived keys. + */ + public BaseKdfBytesGenerator(int counterStart, IDigest digest) + { + this.counterStart = counterStart; + this.digest = digest; + } + + public virtual void Init(IDerivationParameters parameters) + { + if (parameters is KdfParameters) + { + KdfParameters p = (KdfParameters)parameters; + + shared = p.GetSharedSecret(); + iv = p.GetIV(); + } + else if (parameters is Iso18033KdfParameters) + { + Iso18033KdfParameters p = (Iso18033KdfParameters)parameters; + + shared = p.GetSeed(); + iv = null; + } + else + { + throw new ArgumentException("KDF parameters required for KDF Generator"); + } + } + + /** + * return the underlying digest. + */ + public virtual IDigest Digest + { + get { return digest; } + } + + /** + * fill len bytes of the output buffer with bytes generated from + * the derivation function. + * + * @throws ArgumentException if the size of the request will cause an overflow. + * @throws DataLengthException if the out buffer is too small. + */ + public virtual int GenerateBytes(byte[] output, int outOff, int length) + { + if ((output.Length - length) < outOff) + throw new DataLengthException("output buffer too small"); + + long oBytes = length; + int outLen = digest.GetDigestSize(); + + // + // this is at odds with the standard implementation, the + // maximum value should be hBits * (2^32 - 1) where hBits + // is the digest output size in bits. We can't have an + // array with a long index at the moment... + // + if (oBytes > ((2L << 32) - 1)) + throw new ArgumentException("Output length too large"); + + int cThreshold = (int)((oBytes + outLen - 1) / outLen); + + byte[] dig = new byte[digest.GetDigestSize()]; + + byte[] C = new byte[4]; + Pack.UInt32_To_BE((uint)counterStart, C, 0); + + uint counterBase = (uint)(counterStart & ~0xFF); + + for (int i = 0; i < cThreshold; i++) + { + digest.BlockUpdate(shared, 0, shared.Length); + digest.BlockUpdate(C, 0, 4); + + if (iv != null) + { + digest.BlockUpdate(iv, 0, iv.Length); + } + + digest.DoFinal(dig, 0); + + if (length > outLen) + { + Array.Copy(dig, 0, output, outOff, outLen); + outOff += outLen; + length -= outLen; + } + else + { + Array.Copy(dig, 0, output, outOff, length); + } + + if (++C[3] == 0) + { + counterBase += 0x100; + Pack.UInt32_To_BE(counterBase, C, 0); + } + } + + digest.Reset(); + + return (int)oBytes; + } + } +} \ No newline at end of file diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/BaseKdfBytesGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/BaseKdfBytesGenerator.cs.meta new file mode 100644 index 0000000..11491b1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/BaseKdfBytesGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b5a601f0b1701c54b912f0ff9ef54898 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DHBasicKeyPairGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DHBasicKeyPairGenerator.cs new file mode 100644 index 0000000..51b3af6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DHBasicKeyPairGenerator.cs @@ -0,0 +1,38 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Generators +{ + /** + * a basic Diffie-Hellman key pair generator. + * + * This generates keys consistent for use with the basic algorithm for + * Diffie-Hellman. + */ + public class DHBasicKeyPairGenerator + : IAsymmetricCipherKeyPairGenerator + { + private DHKeyGenerationParameters param; + + public virtual void Init( + KeyGenerationParameters parameters) + { + this.param = (DHKeyGenerationParameters)parameters; + } + + public virtual AsymmetricCipherKeyPair GenerateKeyPair() + { + DHKeyGeneratorHelper helper = DHKeyGeneratorHelper.Instance; + DHParameters dhp = param.Parameters; + + BigInteger x = helper.CalculatePrivate(dhp, param.Random); + BigInteger y = helper.CalculatePublic(dhp, x); + + return new AsymmetricCipherKeyPair( + new DHPublicKeyParameters(y, dhp), + new DHPrivateKeyParameters(x, dhp)); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DHBasicKeyPairGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DHBasicKeyPairGenerator.cs.meta new file mode 100644 index 0000000..b790637 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DHBasicKeyPairGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ed530b1624cc2ae4f9ae9c84a5f83cab +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DHKeyGeneratorHelper.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DHKeyGeneratorHelper.cs new file mode 100644 index 0000000..68aba64 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DHKeyGeneratorHelper.cs @@ -0,0 +1,72 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC.Multiplier; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Generators +{ + class DHKeyGeneratorHelper + { + internal static readonly DHKeyGeneratorHelper Instance = new DHKeyGeneratorHelper(); + + private DHKeyGeneratorHelper() + { + } + + internal BigInteger CalculatePrivate( + DHParameters dhParams, + SecureRandom random) + { + int limit = dhParams.L; + + if (limit != 0) + { + int minWeight = limit >> 2; + for (;;) + { + BigInteger x = new BigInteger(limit, random).SetBit(limit - 1); + if (WNafUtilities.GetNafWeight(x) >= minWeight) + { + return x; + } + } + } + + BigInteger min = BigInteger.Two; + int m = dhParams.M; + if (m != 0) + { + min = BigInteger.One.ShiftLeft(m - 1); + } + + BigInteger q = dhParams.Q; + if (q == null) + { + q = dhParams.P; + } + BigInteger max = q.Subtract(BigInteger.Two); + + { + int minWeight = max.BitLength >> 2; + for (;;) + { + BigInteger x = BigIntegers.CreateRandomInRange(min, max, random); + if (WNafUtilities.GetNafWeight(x) >= minWeight) + { + return x; + } + } + } + } + + internal BigInteger CalculatePublic( + DHParameters dhParams, + BigInteger x) + { + return dhParams.G.ModPow(x, dhParams.P); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DHKeyGeneratorHelper.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DHKeyGeneratorHelper.cs.meta new file mode 100644 index 0000000..228a6fd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DHKeyGeneratorHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8757873a0ba8edd428e89dba0f8778e6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DHKeyPairGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DHKeyPairGenerator.cs new file mode 100644 index 0000000..3bf58ba --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DHKeyPairGenerator.cs @@ -0,0 +1,38 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Generators +{ + /** + * a Diffie-Hellman key pair generator. + * + * This generates keys consistent for use in the MTI/A0 key agreement protocol + * as described in "Handbook of Applied Cryptography", Pages 516-519. + */ + public class DHKeyPairGenerator + : IAsymmetricCipherKeyPairGenerator + { + private DHKeyGenerationParameters param; + + public virtual void Init( + KeyGenerationParameters parameters) + { + this.param = (DHKeyGenerationParameters)parameters; + } + + public virtual AsymmetricCipherKeyPair GenerateKeyPair() + { + DHKeyGeneratorHelper helper = DHKeyGeneratorHelper.Instance; + DHParameters dhp = param.Parameters; + + BigInteger x = helper.CalculatePrivate(dhp, param.Random); + BigInteger y = helper.CalculatePublic(dhp, x); + + return new AsymmetricCipherKeyPair( + new DHPublicKeyParameters(y, dhp), + new DHPrivateKeyParameters(x, dhp)); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DHKeyPairGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DHKeyPairGenerator.cs.meta new file mode 100644 index 0000000..f4b824f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DHKeyPairGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9e3bcda939d83fa4482f639c3ee192f7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DHParametersGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DHParametersGenerator.cs new file mode 100644 index 0000000..e752c84 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DHParametersGenerator.cs @@ -0,0 +1,45 @@ +using System; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Generators +{ + public class DHParametersGenerator + { + private int size; + private int certainty; + private SecureRandom random; + + public virtual void Init( + int size, + int certainty, + SecureRandom random) + { + this.size = size; + this.certainty = certainty; + this.random = random; + } + + /** + * which Generates the p and g values from the given parameters, + * returning the DHParameters object. + *

+ * Note: can take a while...

+ */ + public virtual DHParameters GenerateParameters() + { + // + // find a safe prime p where p = 2*q + 1, where p and q are prime. + // + BigInteger[] safePrimes = DHParametersHelper.GenerateSafePrimes(size, certainty, random); + + BigInteger p = safePrimes[0]; + BigInteger q = safePrimes[1]; + BigInteger g = DHParametersHelper.SelectGenerator(p, q, random); + + return new DHParameters(p, g, q, BigInteger.Two, null); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DHParametersGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DHParametersGenerator.cs.meta new file mode 100644 index 0000000..bb49985 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DHParametersGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 79388942d85f9624fa5ce433e182b280 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DHParametersHelper.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DHParametersHelper.cs new file mode 100644 index 0000000..3856904 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DHParametersHelper.cs @@ -0,0 +1,156 @@ +using System; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC.Multiplier; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Generators +{ + internal class DHParametersHelper + { + private static readonly BigInteger Six = BigInteger.ValueOf(6); + + private static readonly int[][] primeLists = BigInteger.primeLists; + private static readonly int[] primeProducts = BigInteger.primeProducts; + private static readonly BigInteger[] BigPrimeProducts = ConstructBigPrimeProducts(primeProducts); + + private static BigInteger[] ConstructBigPrimeProducts(int[] primeProducts) + { + BigInteger[] bpp = new BigInteger[primeProducts.Length]; + for (int i = 0; i < bpp.Length; ++i) + { + bpp[i] = BigInteger.ValueOf(primeProducts[i]); + } + return bpp; + } + + /* + * Finds a pair of prime BigInteger's {p, q: p = 2q + 1} + * + * (see: Handbook of Applied Cryptography 4.86) + */ + internal static BigInteger[] GenerateSafePrimes(int size, int certainty, SecureRandom random) + { + BigInteger p, q; + int qLength = size - 1; + int minWeight = size >> 2; + + if (size <= 32) + { + for (;;) + { + q = new BigInteger(qLength, 2, random); + + p = q.ShiftLeft(1).Add(BigInteger.One); + + if (!p.IsProbablePrime(certainty, true)) + continue; + + if (certainty > 2 && !q.IsProbablePrime(certainty, true)) + continue; + + break; + } + } + else + { + // Note: Modified from Java version for speed + for (;;) + { + q = new BigInteger(qLength, 0, random); + + retry: + for (int i = 0; i < primeLists.Length; ++i) + { + int test = q.Remainder(BigPrimeProducts[i]).IntValue; + + if (i == 0) + { + int rem3 = test % 3; + if (rem3 != 2) + { + int diff = 2 * rem3 + 2; + q = q.Add(BigInteger.ValueOf(diff)); + test = (test + diff) % primeProducts[i]; + } + } + + int[] primeList = primeLists[i]; + for (int j = 0; j < primeList.Length; ++j) + { + int prime = primeList[j]; + int qRem = test % prime; + if (qRem == 0 || qRem == (prime >> 1)) + { + q = q.Add(Six); + goto retry; + } + } + } + + if (q.BitLength != qLength) + continue; + + if (!q.RabinMillerTest(2, random, true)) + continue; + + p = q.ShiftLeft(1).Add(BigInteger.One); + + if (!p.RabinMillerTest(certainty, random, true)) + continue; + + if (certainty > 2 && !q.RabinMillerTest(certainty - 2, random, true)) + continue; + + /* + * Require a minimum weight of the NAF representation, since low-weight primes may be + * weak against a version of the number-field-sieve for the discrete-logarithm-problem. + * + * See "The number field sieve for integers of low weight", Oliver Schirokauer. + */ + if (WNafUtilities.GetNafWeight(p) < minWeight) + continue; + + break; + } + } + + return new BigInteger[] { p, q }; + } + + /* + * Select a high order element of the multiplicative group Zp* + * + * p and q must be s.t. p = 2*q + 1, where p and q are prime (see generateSafePrimes) + */ + internal static BigInteger SelectGenerator(BigInteger p, BigInteger q, SecureRandom random) + { + BigInteger pMinusTwo = p.Subtract(BigInteger.Two); + BigInteger g; + + /* + * (see: Handbook of Applied Cryptography 4.80) + */ +// do +// { +// g = BigIntegers.CreateRandomInRange(BigInteger.Two, pMinusTwo, random); +// } +// while (g.ModPow(BigInteger.Two, p).Equals(BigInteger.One) +// || g.ModPow(q, p).Equals(BigInteger.One)); + + /* + * RFC 2631 2.2.1.2 (and see: Handbook of Applied Cryptography 4.81) + */ + do + { + BigInteger h = BigIntegers.CreateRandomInRange(BigInteger.Two, pMinusTwo, random); + + g = h.ModPow(BigInteger.Two, p); + } + while (g.Equals(BigInteger.One)); + + return g; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DHParametersHelper.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DHParametersHelper.cs.meta new file mode 100644 index 0000000..4ee6156 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DHParametersHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d915facd8d963c041a8b7941965d7cfd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DesEdeKeyGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DesEdeKeyGenerator.cs new file mode 100644 index 0000000..904cc71 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DesEdeKeyGenerator.cs @@ -0,0 +1,67 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Generators +{ + public class DesEdeKeyGenerator + : DesKeyGenerator + { + public DesEdeKeyGenerator() + { + } + + internal DesEdeKeyGenerator( + int defaultStrength) + : base(defaultStrength) + { + } + + /** + * initialise the key generator - if strength is set to zero + * the key Generated will be 192 bits in size, otherwise + * strength can be 128 or 192 (or 112 or 168 if you don't count + * parity bits), depending on whether you wish to do 2-key or 3-key + * triple DES. + * + * @param param the parameters to be used for key generation + */ + protected override void engineInit( + KeyGenerationParameters parameters) + { + this.random = parameters.Random; + this.strength = (parameters.Strength + 7) / 8; + + if (strength == 0 || strength == (168 / 8)) + { + strength = DesEdeParameters.DesEdeKeyLength; + } + else if (strength == (112 / 8)) + { + strength = 2 * DesEdeParameters.DesKeyLength; + } + else if (strength != DesEdeParameters.DesEdeKeyLength + && strength != (2 * DesEdeParameters.DesKeyLength)) + { + throw new ArgumentException("DESede key must be " + + (DesEdeParameters.DesEdeKeyLength * 8) + " or " + + (2 * 8 * DesEdeParameters.DesKeyLength) + + " bits long."); + } + } + + protected override byte[] engineGenerateKey() + { + byte[] newKey = new byte[strength]; + + do + { + random.NextBytes(newKey); + DesEdeParameters.SetOddParity(newKey); + } + while (DesEdeParameters.IsWeakKey(newKey, 0, newKey.Length) || !DesEdeParameters.IsRealEdeKey(newKey, 0)); + + return newKey; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DesEdeKeyGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DesEdeKeyGenerator.cs.meta new file mode 100644 index 0000000..2147254 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DesEdeKeyGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: db411dd3561ee534babd0023028ae5c0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DesKeyGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DesKeyGenerator.cs new file mode 100644 index 0000000..4c2051d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DesKeyGenerator.cs @@ -0,0 +1,57 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Generators +{ + public class DesKeyGenerator + : CipherKeyGenerator + { + public DesKeyGenerator() + { + } + + internal DesKeyGenerator( + int defaultStrength) + : base(defaultStrength) + { + } + + /** + * initialise the key generator - if strength is set to zero + * the key generated will be 64 bits in size, otherwise + * strength can be 64 or 56 bits (if you don't count the parity bits). + * + * @param param the parameters to be used for key generation + */ + protected override void engineInit( + KeyGenerationParameters parameters) + { + base.engineInit(parameters); + + if (strength == 0 || strength == (56 / 8)) + { + strength = DesParameters.DesKeyLength; + } + else if (strength != DesParameters.DesKeyLength) + { + throw new ArgumentException( + "DES key must be " + (DesParameters.DesKeyLength * 8) + " bits long."); + } + } + + protected override byte[] engineGenerateKey() + { + byte[] newKey = new byte[DesParameters.DesKeyLength]; + + do + { + random.NextBytes(newKey); + DesParameters.SetOddParity(newKey); + } + while (DesParameters.IsWeakKey(newKey, 0)); + + return newKey; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DesKeyGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DesKeyGenerator.cs.meta new file mode 100644 index 0000000..cb6d668 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DesKeyGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: eaf17d376d1841848a5d1ca94a3123d4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DsaKeyPairGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DsaKeyPairGenerator.cs new file mode 100644 index 0000000..1c9ce5a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DsaKeyPairGenerator.cs @@ -0,0 +1,72 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC.Multiplier; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Generators +{ + /** + * a DSA key pair generator. + * + * This Generates DSA keys in line with the method described + * in FIPS 186-3 B.1 FFC Key Pair Generation. + */ + public class DsaKeyPairGenerator + : IAsymmetricCipherKeyPairGenerator + { + private static readonly BigInteger One = BigInteger.One; + + private DsaKeyGenerationParameters param; + + public void Init( + KeyGenerationParameters parameters) + { + if (parameters == null) + throw new ArgumentNullException("parameters"); + + // Note: If we start accepting instances of KeyGenerationParameters, + // must apply constraint checking on strength (see DsaParametersGenerator.Init) + + this.param = (DsaKeyGenerationParameters) parameters; + } + + public AsymmetricCipherKeyPair GenerateKeyPair() + { + DsaParameters dsaParams = param.Parameters; + + BigInteger x = GeneratePrivateKey(dsaParams.Q, param.Random); + BigInteger y = CalculatePublicKey(dsaParams.P, dsaParams.G, x); + + return new AsymmetricCipherKeyPair( + new DsaPublicKeyParameters(y, dsaParams), + new DsaPrivateKeyParameters(x, dsaParams)); + } + + private static BigInteger GeneratePrivateKey(BigInteger q, SecureRandom random) + { + // B.1.2 Key Pair Generation by Testing Candidates + int minWeight = q.BitLength >> 2; + for (;;) + { + // TODO Prefer this method? (change test cases that used fixed random) + // B.1.1 Key Pair Generation Using Extra Random Bits + //BigInteger x = new BigInteger(q.BitLength + 64, random).Mod(q.Subtract(One)).Add(One); + + BigInteger x = BigIntegers.CreateRandomInRange(One, q.Subtract(One), random); + if (WNafUtilities.GetNafWeight(x) >= minWeight) + { + return x; + } + } + } + + private static BigInteger CalculatePublicKey(BigInteger p, BigInteger g, BigInteger x) + { + return g.ModPow(x, p); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DsaKeyPairGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DsaKeyPairGenerator.cs.meta new file mode 100644 index 0000000..8b01087 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DsaKeyPairGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6ba7afb5e7b49e648aa7f84f1e3da9e3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DsaParametersGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DsaParametersGenerator.cs new file mode 100644 index 0000000..97c20d1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DsaParametersGenerator.cs @@ -0,0 +1,355 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Crypto.Generators +{ + /** + * Generate suitable parameters for DSA, in line with FIPS 186-2, or FIPS 186-3. + */ + public class DsaParametersGenerator + { + private IDigest digest; + private int L, N; + private int certainty; + private SecureRandom random; + private bool use186_3; + private int usageIndex; + + public DsaParametersGenerator() + : this(new Sha1Digest()) + { + } + + public DsaParametersGenerator(IDigest digest) + { + this.digest = digest; + } + + /// Initialise the generator + /// This form can only be used for older DSA (pre-DSA2) parameters + /// the size of keys in bits (from 512 up to 1024, and a multiple of 64) + /// measure of robustness of primes (at least 80 for FIPS 186-2 compliance) + /// the source of randomness to use + public virtual void Init( + int size, + int certainty, + SecureRandom random) + { + if (!IsValidDsaStrength(size)) + throw new ArgumentException("size must be from 512 - 1024 and a multiple of 64", "size"); + + this.use186_3 = false; + this.L = size; + this.N = GetDefaultN(size); + this.certainty = certainty; + this.random = random; + } + + /// Initialise the generator for DSA 2 + /// You must use this Init method if you need to generate parameters for DSA 2 keys + /// An instance of DsaParameterGenerationParameters used to configure this generator + public virtual void Init(DsaParameterGenerationParameters parameters) + { + // TODO Should we enforce the minimum 'certainty' values as per C.3 Table C.1? + this.use186_3 = true; + this.L = parameters.L; + this.N = parameters.N; + this.certainty = parameters.Certainty; + this.random = parameters.Random; + this.usageIndex = parameters.UsageIndex; + + if ((L < 1024 || L > 3072) || L % 1024 != 0) + throw new ArgumentException("Values must be between 1024 and 3072 and a multiple of 1024", "L"); + if (L == 1024 && N != 160) + throw new ArgumentException("N must be 160 for L = 1024"); + if (L == 2048 && (N != 224 && N != 256)) + throw new ArgumentException("N must be 224 or 256 for L = 2048"); + if (L == 3072 && N != 256) + throw new ArgumentException("N must be 256 for L = 3072"); + + if (digest.GetDigestSize() * 8 < N) + throw new InvalidOperationException("Digest output size too small for value of N"); + } + + /// Generates a set of DsaParameters + /// Can take a while... + public virtual DsaParameters GenerateParameters() + { + return use186_3 + ? GenerateParameters_FIPS186_3() + : GenerateParameters_FIPS186_2(); + } + + protected virtual DsaParameters GenerateParameters_FIPS186_2() + { + byte[] seed = new byte[20]; + byte[] part1 = new byte[20]; + byte[] part2 = new byte[20]; + byte[] u = new byte[20]; + int n = (L - 1) / 160; + byte[] w = new byte[L / 8]; + + if (!(digest is Sha1Digest)) + throw new InvalidOperationException("can only use SHA-1 for generating FIPS 186-2 parameters"); + + for (;;) + { + random.NextBytes(seed); + + Hash(digest, seed, part1); + Array.Copy(seed, 0, part2, 0, seed.Length); + Inc(part2); + Hash(digest, part2, part2); + + for (int i = 0; i != u.Length; i++) + { + u[i] = (byte)(part1[i] ^ part2[i]); + } + + u[0] |= (byte)0x80; + u[19] |= (byte)0x01; + + BigInteger q = new BigInteger(1, u); + + if (!q.IsProbablePrime(certainty)) + continue; + + byte[] offset = Arrays.Clone(seed); + Inc(offset); + + for (int counter = 0; counter < 4096; ++counter) + { + for (int k = 0; k < n; k++) + { + Inc(offset); + Hash(digest, offset, part1); + Array.Copy(part1, 0, w, w.Length - (k + 1) * part1.Length, part1.Length); + } + + Inc(offset); + Hash(digest, offset, part1); + Array.Copy(part1, part1.Length - ((w.Length - (n) * part1.Length)), w, 0, w.Length - n * part1.Length); + + w[0] |= (byte)0x80; + + BigInteger x = new BigInteger(1, w); + + BigInteger c = x.Mod(q.ShiftLeft(1)); + + BigInteger p = x.Subtract(c.Subtract(BigInteger.One)); + + if (p.BitLength != L) + continue; + + if (p.IsProbablePrime(certainty)) + { + BigInteger g = CalculateGenerator_FIPS186_2(p, q, random); + + return new DsaParameters(p, q, g, new DsaValidationParameters(seed, counter)); + } + } + } + } + + protected virtual BigInteger CalculateGenerator_FIPS186_2(BigInteger p, BigInteger q, SecureRandom r) + { + BigInteger e = p.Subtract(BigInteger.One).Divide(q); + BigInteger pSub2 = p.Subtract(BigInteger.Two); + + for (;;) + { + BigInteger h = BigIntegers.CreateRandomInRange(BigInteger.Two, pSub2, r); + BigInteger g = h.ModPow(e, p); + + if (g.BitLength > 1) + return g; + } + } + + /** + * generate suitable parameters for DSA, in line with + * FIPS 186-3 A.1 Generation of the FFC Primes p and q. + */ + protected virtual DsaParameters GenerateParameters_FIPS186_3() + { +// A.1.1.2 Generation of the Probable Primes p and q Using an Approved Hash Function + IDigest d = digest; + int outlen = d.GetDigestSize() * 8; + +// 1. Check that the (L, N) pair is in the list of acceptable (L, N pairs) (see Section 4.2). If +// the pair is not in the list, then return INVALID. + // Note: checked at initialisation + +// 2. If (seedlen < N), then return INVALID. + // FIXME This should be configurable (must be >= N) + int seedlen = N; + byte[] seed = new byte[seedlen / 8]; + +// 3. n = ceiling(L ℠outlen) – 1. + int n = (L - 1) / outlen; + +// 4. b = L – 1 – (n ∗ outlen). + int b = (L - 1) % outlen; + + byte[] output = new byte[d.GetDigestSize()]; + for (;;) + { +// 5. Get an arbitrary sequence of seedlen bits as the domain_parameter_seed. + random.NextBytes(seed); + +// 6. U = Hash (domain_parameter_seed) mod 2^(N–1). + Hash(d, seed, output); + BigInteger U = new BigInteger(1, output).Mod(BigInteger.One.ShiftLeft(N - 1)); + +// 7. q = 2^(N–1) + U + 1 – ( U mod 2). + BigInteger q = U.SetBit(0).SetBit(N - 1); + +// 8. Test whether or not q is prime as specified in Appendix C.3. + // TODO Review C.3 for primality checking + if (!q.IsProbablePrime(certainty)) + { +// 9. If q is not a prime, then go to step 5. + continue; + } + +// 10. offset = 1. + // Note: 'offset' value managed incrementally + byte[] offset = Arrays.Clone(seed); + +// 11. For counter = 0 to (4L – 1) do + int counterLimit = 4 * L; + for (int counter = 0; counter < counterLimit; ++counter) + { +// 11.1 For j = 0 to n do +// Vj = Hash ((domain_parameter_seed + offset + j) mod 2^seedlen). +// 11.2 W = V0 + (V1 ∗ 2^outlen) + ... + (V^(n–1) ∗ 2^((n–1) ∗ outlen)) + ((Vn mod 2^b) ∗ 2^(n ∗ outlen)). + // TODO Assemble w as a byte array + BigInteger W = BigInteger.Zero; + for (int j = 0, exp = 0; j <= n; ++j, exp += outlen) + { + Inc(offset); + Hash(d, offset, output); + + BigInteger Vj = new BigInteger(1, output); + if (j == n) + { + Vj = Vj.Mod(BigInteger.One.ShiftLeft(b)); + } + + W = W.Add(Vj.ShiftLeft(exp)); + } + +// 11.3 X = W + 2^(L–1). Comment: 0 ≤ W < 2L–1; hence, 2L–1 ≤ X < 2L. + BigInteger X = W.Add(BigInteger.One.ShiftLeft(L - 1)); + +// 11.4 c = X mod 2q. + BigInteger c = X.Mod(q.ShiftLeft(1)); + +// 11.5 p = X - (c - 1). Comment: p ≡ 1 (mod 2q). + BigInteger p = X.Subtract(c.Subtract(BigInteger.One)); + + // 11.6 If (p < 2^(L - 1)), then go to step 11.9 + if (p.BitLength != L) + continue; + +// 11.7 Test whether or not p is prime as specified in Appendix C.3. + // TODO Review C.3 for primality checking + if (p.IsProbablePrime(certainty)) + { +// 11.8 If p is determined to be prime, then return VALID and the values of p, q and +// (optionally) the values of domain_parameter_seed and counter. + // TODO Make configurable (8-bit unsigned)? + + if (usageIndex >= 0) + { + BigInteger g = CalculateGenerator_FIPS186_3_Verifiable(d, p, q, seed, usageIndex); + if (g != null) + return new DsaParameters(p, q, g, new DsaValidationParameters(seed, counter, usageIndex)); + } + + { + BigInteger g = CalculateGenerator_FIPS186_3_Unverifiable(p, q, random); + + return new DsaParameters(p, q, g, new DsaValidationParameters(seed, counter)); + } + } + +// 11.9 offset = offset + n + 1. Comment: Increment offset; then, as part of +// the loop in step 11, increment counter; if +// counter < 4L, repeat steps 11.1 through 11.8. + // Note: 'offset' value already incremented in inner loop + } +// 12. Go to step 5. + } + } + + protected virtual BigInteger CalculateGenerator_FIPS186_3_Unverifiable(BigInteger p, BigInteger q, + SecureRandom r) + { + return CalculateGenerator_FIPS186_2(p, q, r); + } + + protected virtual BigInteger CalculateGenerator_FIPS186_3_Verifiable(IDigest d, BigInteger p, BigInteger q, + byte[] seed, int index) + { + // A.2.3 Verifiable Canonical Generation of the Generator g + BigInteger e = p.Subtract(BigInteger.One).Divide(q); + byte[] ggen = Hex.DecodeStrict("6767656E"); + + // 7. U = domain_parameter_seed || "ggen" || index || count. + byte[] U = new byte[seed.Length + ggen.Length + 1 + 2]; + Array.Copy(seed, 0, U, 0, seed.Length); + Array.Copy(ggen, 0, U, seed.Length, ggen.Length); + U[U.Length - 3] = (byte)index; + + byte[] w = new byte[d.GetDigestSize()]; + for (int count = 1; count < (1 << 16); ++count) + { + Inc(U); + Hash(d, U, w); + BigInteger W = new BigInteger(1, w); + BigInteger g = W.ModPow(e, p); + + if (g.CompareTo(BigInteger.Two) >= 0) + return g; + } + + return null; + } + + private static bool IsValidDsaStrength( + int strength) + { + return strength >= 512 && strength <= 1024 && strength % 64 == 0; + } + + protected static void Hash(IDigest d, byte[] input, byte[] output) + { + d.BlockUpdate(input, 0, input.Length); + d.DoFinal(output, 0); + } + + private static int GetDefaultN(int L) + { + return L > 1024 ? 256 : 160; + } + + protected static void Inc(byte[] buf) + { + for (int i = buf.Length - 1; i >= 0; --i) + { + byte b = (byte)(buf[i] + 1); + buf[i] = b; + + if (b != 0) + break; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DsaParametersGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DsaParametersGenerator.cs.meta new file mode 100644 index 0000000..45e6530 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/DsaParametersGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 10e192b1d3178ac4fbb2ee6933914b75 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/ECKeyPairGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/ECKeyPairGenerator.cs new file mode 100644 index 0000000..6a710c6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/ECKeyPairGenerator.cs @@ -0,0 +1,162 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Sec; +using Org.BouncyCastle.Asn1.TeleTrust; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.EC; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Math.EC.Multiplier; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Generators +{ + public class ECKeyPairGenerator + : IAsymmetricCipherKeyPairGenerator + { + private readonly string algorithm; + + private ECDomainParameters parameters; + private DerObjectIdentifier publicKeyParamSet; + private SecureRandom random; + + public ECKeyPairGenerator() + : this("EC") + { + } + + public ECKeyPairGenerator( + string algorithm) + { + if (algorithm == null) + throw new ArgumentNullException("algorithm"); + + this.algorithm = ECKeyParameters.VerifyAlgorithmName(algorithm); + } + + public void Init( + KeyGenerationParameters parameters) + { + if (parameters is ECKeyGenerationParameters) + { + ECKeyGenerationParameters ecP = (ECKeyGenerationParameters) parameters; + + this.publicKeyParamSet = ecP.PublicKeyParamSet; + this.parameters = ecP.DomainParameters; + } + else + { + DerObjectIdentifier oid; + switch (parameters.Strength) + { + case 192: + oid = X9ObjectIdentifiers.Prime192v1; + break; + case 224: + oid = SecObjectIdentifiers.SecP224r1; + break; + case 239: + oid = X9ObjectIdentifiers.Prime239v1; + break; + case 256: + oid = X9ObjectIdentifiers.Prime256v1; + break; + case 384: + oid = SecObjectIdentifiers.SecP384r1; + break; + case 521: + oid = SecObjectIdentifiers.SecP521r1; + break; + default: + throw new InvalidParameterException("unknown key size."); + } + + X9ECParameters ecps = FindECCurveByOid(oid); + + this.publicKeyParamSet = oid; + this.parameters = new ECDomainParameters( + ecps.Curve, ecps.G, ecps.N, ecps.H, ecps.GetSeed()); + } + + this.random = parameters.Random; + + if (this.random == null) + { + this.random = new SecureRandom(); + } + } + + /** + * Given the domain parameters this routine generates an EC key + * pair in accordance with X9.62 section 5.2.1 pages 26, 27. + */ + public AsymmetricCipherKeyPair GenerateKeyPair() + { + BigInteger n = parameters.N; + BigInteger d; + int minWeight = n.BitLength >> 2; + + for (;;) + { + d = new BigInteger(n.BitLength, random); + + if (d.CompareTo(BigInteger.One) < 0 || d.CompareTo(n) >= 0) + continue; + + if (WNafUtilities.GetNafWeight(d) < minWeight) + continue; + + break; + } + + ECPoint q = CreateBasePointMultiplier().Multiply(parameters.G, d); + + if (publicKeyParamSet != null) + { + return new AsymmetricCipherKeyPair( + new ECPublicKeyParameters(algorithm, q, publicKeyParamSet), + new ECPrivateKeyParameters(algorithm, d, publicKeyParamSet)); + } + + return new AsymmetricCipherKeyPair( + new ECPublicKeyParameters(algorithm, q, parameters), + new ECPrivateKeyParameters(algorithm, d, parameters)); + } + + protected virtual ECMultiplier CreateBasePointMultiplier() + { + return new FixedPointCombMultiplier(); + } + + internal static X9ECParameters FindECCurveByOid(DerObjectIdentifier oid) + { + // TODO ECGost3410NamedCurves support (returns ECDomainParameters though) + + X9ECParameters ecP = CustomNamedCurves.GetByOid(oid); + if (ecP == null) + { + ecP = ECNamedCurveTable.GetByOid(oid); + } + return ecP; + } + + internal static ECPublicKeyParameters GetCorrespondingPublicKey( + ECPrivateKeyParameters privKey) + { + ECDomainParameters ec = privKey.Parameters; + ECPoint q = new FixedPointCombMultiplier().Multiply(ec.G, privKey.D); + + if (privKey.PublicKeyParamSet != null) + { + return new ECPublicKeyParameters(privKey.AlgorithmName, q, privKey.PublicKeyParamSet); + } + + return new ECPublicKeyParameters(privKey.AlgorithmName, q, ec); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/ECKeyPairGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/ECKeyPairGenerator.cs.meta new file mode 100644 index 0000000..afebd75 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/ECKeyPairGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: db095333a9a6db74480fe87fe59bf484 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Ed25519KeyPairGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Ed25519KeyPairGenerator.cs new file mode 100644 index 0000000..266d111 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Ed25519KeyPairGenerator.cs @@ -0,0 +1,25 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Generators +{ + public class Ed25519KeyPairGenerator + : IAsymmetricCipherKeyPairGenerator + { + private SecureRandom random; + + public virtual void Init(KeyGenerationParameters parameters) + { + this.random = parameters.Random; + } + + public virtual AsymmetricCipherKeyPair GenerateKeyPair() + { + Ed25519PrivateKeyParameters privateKey = new Ed25519PrivateKeyParameters(random); + Ed25519PublicKeyParameters publicKey = privateKey.GeneratePublicKey(); + return new AsymmetricCipherKeyPair(publicKey, privateKey); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Ed25519KeyPairGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Ed25519KeyPairGenerator.cs.meta new file mode 100644 index 0000000..7ef91fe --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Ed25519KeyPairGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bd92905a34bb8e94b8729865b6d31929 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Ed448KeyPairGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Ed448KeyPairGenerator.cs new file mode 100644 index 0000000..50aee63 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Ed448KeyPairGenerator.cs @@ -0,0 +1,25 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Generators +{ + public class Ed448KeyPairGenerator + : IAsymmetricCipherKeyPairGenerator + { + private SecureRandom random; + + public virtual void Init(KeyGenerationParameters parameters) + { + this.random = parameters.Random; + } + + public virtual AsymmetricCipherKeyPair GenerateKeyPair() + { + Ed448PrivateKeyParameters privateKey = new Ed448PrivateKeyParameters(random); + Ed448PublicKeyParameters publicKey = privateKey.GeneratePublicKey(); + return new AsymmetricCipherKeyPair(publicKey, privateKey); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Ed448KeyPairGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Ed448KeyPairGenerator.cs.meta new file mode 100644 index 0000000..758fbab --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Ed448KeyPairGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b8c872e3bd8b5534d9b98f15cf00a251 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/ElGamalKeyPairGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/ElGamalKeyPairGenerator.cs new file mode 100644 index 0000000..227e7fe --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/ElGamalKeyPairGenerator.cs @@ -0,0 +1,40 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Generators +{ + /** + * a ElGamal key pair generator. + *

+ * This Generates keys consistent for use with ElGamal as described in + * page 164 of "Handbook of Applied Cryptography".

+ */ + public class ElGamalKeyPairGenerator + : IAsymmetricCipherKeyPairGenerator + { + private ElGamalKeyGenerationParameters param; + + public void Init( + KeyGenerationParameters parameters) + { + this.param = (ElGamalKeyGenerationParameters) parameters; + } + + public AsymmetricCipherKeyPair GenerateKeyPair() + { + DHKeyGeneratorHelper helper = DHKeyGeneratorHelper.Instance; + ElGamalParameters egp = param.Parameters; + DHParameters dhp = new DHParameters(egp.P, egp.G, null, 0, egp.L); + + BigInteger x = helper.CalculatePrivate(dhp, param.Random); + BigInteger y = helper.CalculatePublic(dhp, x); + + return new AsymmetricCipherKeyPair( + new ElGamalPublicKeyParameters(y, egp), + new ElGamalPrivateKeyParameters(x, egp)); + } + } + +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/ElGamalKeyPairGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/ElGamalKeyPairGenerator.cs.meta new file mode 100644 index 0000000..41d9bf4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/ElGamalKeyPairGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b7f246120038f374eb679026696663db +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/ElGamalParametersGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/ElGamalParametersGenerator.cs new file mode 100644 index 0000000..8443bb0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/ElGamalParametersGenerator.cs @@ -0,0 +1,46 @@ +using System; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Generators +{ + public class ElGamalParametersGenerator + { + private int size; + private int certainty; + private SecureRandom random; + + public void Init( + int size, + int certainty, + SecureRandom random) + { + this.size = size; + this.certainty = certainty; + this.random = random; + } + + /** + * which Generates the p and g values from the given parameters, + * returning the ElGamalParameters object. + *

+ * Note: can take a while... + *

+ */ + public ElGamalParameters GenerateParameters() + { + // + // find a safe prime p where p = 2*q + 1, where p and q are prime. + // + BigInteger[] safePrimes = DHParametersHelper.GenerateSafePrimes(size, certainty, random); + + BigInteger p = safePrimes[0]; + BigInteger q = safePrimes[1]; + BigInteger g = DHParametersHelper.SelectGenerator(p, q, random); + + return new ElGamalParameters(p, g); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/ElGamalParametersGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/ElGamalParametersGenerator.cs.meta new file mode 100644 index 0000000..d58421d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/ElGamalParametersGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7b48f76077bc0f948a52ed3ccd854396 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/GOST3410KeyPairGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/GOST3410KeyPairGenerator.cs new file mode 100644 index 0000000..520820b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/GOST3410KeyPairGenerator.cs @@ -0,0 +1,82 @@ +using System; + +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC.Multiplier; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Generators +{ + /** + * a GOST3410 key pair generator. + * This generates GOST3410 keys in line with the method described + * in GOST R 34.10-94. + */ + public class Gost3410KeyPairGenerator + : IAsymmetricCipherKeyPairGenerator + { + private Gost3410KeyGenerationParameters param; + + public void Init( + KeyGenerationParameters parameters) + { + if (parameters is Gost3410KeyGenerationParameters) + { + this.param = (Gost3410KeyGenerationParameters) parameters; + } + else + { + Gost3410KeyGenerationParameters kgp = new Gost3410KeyGenerationParameters( + parameters.Random, + CryptoProObjectIdentifiers.GostR3410x94CryptoProA); + + if (parameters.Strength != kgp.Parameters.P.BitLength - 1) + { + // TODO Should we complain? + } + + this.param = kgp; + } + } + + public AsymmetricCipherKeyPair GenerateKeyPair() + { + SecureRandom random = param.Random; + Gost3410Parameters gost3410Params = param.Parameters; + + BigInteger q = gost3410Params.Q, x; + + int minWeight = 64; + for (;;) + { + x = new BigInteger(256, random); + + if (x.SignValue < 1 || x.CompareTo(q) >= 0) + continue; + + if (WNafUtilities.GetNafWeight(x) < minWeight) + continue; + + break; + } + + BigInteger p = gost3410Params.P; + BigInteger a = gost3410Params.A; + + // calculate the public key. + BigInteger y = a.ModPow(x, p); + + if (param.PublicKeyParamSet != null) + { + return new AsymmetricCipherKeyPair( + new Gost3410PublicKeyParameters(y, param.PublicKeyParamSet), + new Gost3410PrivateKeyParameters(x, param.PublicKeyParamSet)); + } + + return new AsymmetricCipherKeyPair( + new Gost3410PublicKeyParameters(y, gost3410Params), + new Gost3410PrivateKeyParameters(x, gost3410Params)); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/GOST3410KeyPairGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/GOST3410KeyPairGenerator.cs.meta new file mode 100644 index 0000000..e8d806e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/GOST3410KeyPairGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 948604f3ba47d224bbce1cd4638207ac +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/GOST3410ParametersGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/GOST3410ParametersGenerator.cs new file mode 100644 index 0000000..52a9f5a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/GOST3410ParametersGenerator.cs @@ -0,0 +1,530 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Generators +{ + /** + * generate suitable parameters for GOST3410. + */ + public class Gost3410ParametersGenerator + { + private int size; + private int typeproc; + private SecureRandom init_random; + + /** + * initialise the key generator. + * + * @param size size of the key + * @param typeProcedure type procedure A,B = 1; A',B' - else + * @param random random byte source. + */ + public void Init( + int size, + int typeProcedure, + SecureRandom random) + { + this.size = size; + this.typeproc = typeProcedure; + this.init_random = random; + } + + //Procedure A + private int procedure_A(int x0, int c, BigInteger[] pq, int size) + { + //Verify and perform condition: 065536) + { + x0 = init_random.NextInt()/32768; + } + + while((c<0 || c>65536) || (c/2==0)) + { + c = init_random.NextInt()/32768 + 1; + } + + BigInteger C = BigInteger.ValueOf(c); + BigInteger constA16 = BigInteger.ValueOf(19381); + + //step1 + BigInteger[] y = new BigInteger[1]; // begin length = 1 + y[0] = BigInteger.ValueOf(x0); + + //step 2 + int[] t = new int[1]; // t - orders; begin length = 1 + t[0] = size; + int s = 0; + for (int i=0; t[i]>=17; i++) + { + // extension array t + int[] tmp_t = new int[t.Length + 1]; /////////////// + Array.Copy(t,0,tmp_t,0,t.Length); // extension + t = new int[tmp_t.Length]; // array t + Array.Copy(tmp_t, 0, t, 0, tmp_t.Length); /////////////// + + t[i+1] = t[i]/2; + s = i+1; + } + + //step3 + BigInteger[] p = new BigInteger[s+1]; + p[s] = new BigInteger("8003",16); //set min prime number length 16 bit + + int m = s-1; //step4 + + for (int i=0; i t[m]) + { + goto step6; //step 12 + } + + p[m] = NByLastP.Add(BigInteger.One); + + //step13 + if (BigInteger.Two.ModPow(NByLastP, p[m]).CompareTo(BigInteger.One) == 0 + && BigInteger.Two.ModPow(N, p[m]).CompareTo(BigInteger.One) != 0) + { + break; + } + + N = N.Add(BigInteger.Two); + } + + if (--m < 0) + { + pq[0] = p[0]; + pq[1] = p[1]; + return y[0].IntValue; //return for procedure B step 2 + } + + break; //step 14 + } + } + return y[0].IntValue; + } + + //Procedure A' + private long procedure_Aa(long x0, long c, BigInteger[] pq, int size) + { + //Verify and perform condition: 04294967296L) + { + x0 = init_random.NextInt()*2; + } + + while((c<0 || c>4294967296L) || (c/2==0)) + { + c = init_random.NextInt()*2+1; + } + + BigInteger C = BigInteger.ValueOf(c); + BigInteger constA32 = BigInteger.ValueOf(97781173); + + //step1 + BigInteger[] y = new BigInteger[1]; // begin length = 1 + y[0] = BigInteger.ValueOf(x0); + + //step 2 + int[] t = new int[1]; // t - orders; begin length = 1 + t[0] = size; + int s = 0; + for (int i=0; t[i]>=33; i++) + { + // extension array t + int[] tmp_t = new int[t.Length + 1]; /////////////// + Array.Copy(t,0,tmp_t,0,t.Length); // extension + t = new int[tmp_t.Length]; // array t + Array.Copy(tmp_t, 0, t, 0, tmp_t.Length); /////////////// + + t[i+1] = t[i]/2; + s = i+1; + } + + //step3 + BigInteger[] p = new BigInteger[s+1]; + p[s] = new BigInteger("8000000B",16); //set min prime number length 32 bit + + int m = s-1; //step4 + + for (int i=0; i t[m]) + { + goto step6; //step 12 + } + + p[m] = NByLastP.Add(BigInteger.One); + + //step13 + if (BigInteger.Two.ModPow(NByLastP, p[m]).CompareTo(BigInteger.One) == 0 + && BigInteger.Two.ModPow(N, p[m]).CompareTo(BigInteger.One) != 0) + { + break; + } + + N = N.Add(BigInteger.Two); + } + + if (--m < 0) + { + pq[0] = p[0]; + pq[1] = p[1]; + return y[0].LongValue; //return for procedure B' step 2 + } + + break; //step 14 + } + } + return y[0].LongValue; + } + + //Procedure B + private void procedure_B(int x0, int c, BigInteger[] pq) + { + //Verify and perform condition: 065536) + { + x0 = init_random.NextInt()/32768; + } + + while((c<0 || c>65536) || (c/2==0)) + { + c = init_random.NextInt()/32768 + 1; + } + + BigInteger [] qp = new BigInteger[2]; + BigInteger q = null, Q = null, p = null; + BigInteger C = BigInteger.ValueOf(c); + BigInteger constA16 = BigInteger.ValueOf(19381); + + //step1 + x0 = procedure_A(x0, c, qp, 256); + q = qp[0]; + + //step2 + x0 = procedure_A(x0, c, qp, 512); + Q = qp[0]; + + BigInteger[] y = new BigInteger[65]; + y[0] = BigInteger.ValueOf(x0); + + const int tp = 1024; + + BigInteger qQ = q.Multiply(Q); + +step3: + for(;;) + { + //step 3 + for (int j=0; j<64; j++) + { + y[j+1] = (y[j].Multiply(constA16).Add(C)).Mod(BigInteger.Two.Pow(16)); + } + + //step 4 + BigInteger Y = BigInteger.Zero; + + for (int j=0; j<64; j++) + { + Y = Y.Add(y[j].ShiftLeft(16*j)); + } + + y[0] = y[64]; //step 5 + + //step 6 + BigInteger N = BigInteger.One.ShiftLeft(tp-1).Divide(qQ).Add( + Y.ShiftLeft(tp-1).Divide(qQ.ShiftLeft(1024))); + + if (N.TestBit(0)) + { + N = N.Add(BigInteger.One); + } + + //step 7 + + for(;;) + { + //step 11 + BigInteger qQN = qQ.Multiply(N); + + if (qQN.BitLength > tp) + { + goto step3; //step 9 + } + + p = qQN.Add(BigInteger.One); + + //step10 + if (BigInteger.Two.ModPow(qQN, p).CompareTo(BigInteger.One) == 0 + && BigInteger.Two.ModPow(q.Multiply(N), p).CompareTo(BigInteger.One) != 0) + { + pq[0] = p; + pq[1] = q; + return; + } + + N = N.Add(BigInteger.Two); + } + } + } + + //Procedure B' + private void procedure_Bb(long x0, long c, BigInteger[] pq) + { + //Verify and perform condition: 04294967296L) + { + x0 = init_random.NextInt()*2; + } + + while((c<0 || c>4294967296L) || (c/2==0)) + { + c = init_random.NextInt()*2+1; + } + + BigInteger [] qp = new BigInteger[2]; + BigInteger q = null, Q = null, p = null; + BigInteger C = BigInteger.ValueOf(c); + BigInteger constA32 = BigInteger.ValueOf(97781173); + + //step1 + x0 = procedure_Aa(x0, c, qp, 256); + q = qp[0]; + + //step2 + x0 = procedure_Aa(x0, c, qp, 512); + Q = qp[0]; + + BigInteger[] y = new BigInteger[33]; + y[0] = BigInteger.ValueOf(x0); + + const int tp = 1024; + + BigInteger qQ = q.Multiply(Q); + +step3: + for(;;) + { + //step 3 + for (int j=0; j<32; j++) + { + y[j+1] = (y[j].Multiply(constA32).Add(C)).Mod(BigInteger.Two.Pow(32)); + } + + //step 4 + BigInteger Y = BigInteger.Zero; + for (int j=0; j<32; j++) + { + Y = Y.Add(y[j].ShiftLeft(32*j)); + } + + y[0] = y[32]; //step 5 + + //step 6 + BigInteger N = BigInteger.One.ShiftLeft(tp-1).Divide(qQ).Add( + Y.ShiftLeft(tp-1).Divide(qQ.ShiftLeft(1024))); + + if (N.TestBit(0)) + { + N = N.Add(BigInteger.One); + } + + //step 7 + + for(;;) + { + //step 11 + BigInteger qQN = qQ.Multiply(N); + + if (qQN.BitLength > tp) + { + goto step3; //step 9 + } + + p = qQN.Add(BigInteger.One); + + //step10 + if (BigInteger.Two.ModPow(qQN, p).CompareTo(BigInteger.One) == 0 + && BigInteger.Two.ModPow(q.Multiply(N), p).CompareTo(BigInteger.One) != 0) + { + pq[0] = p; + pq[1] = q; + return; + } + + N = N.Add(BigInteger.Two); + } + } + } + + + /** + * Procedure C + * procedure generates the a value from the given p,q, + * returning the a value. + */ + private BigInteger procedure_C(BigInteger p, BigInteger q) + { + BigInteger pSub1 = p.Subtract(BigInteger.One); + BigInteger pSub1Divq = pSub1.Divide(q); + + for(;;) + { + BigInteger d = new BigInteger(p.BitLength, init_random); + + // 1 < d < p-1 + if (d.CompareTo(BigInteger.One) > 0 && d.CompareTo(pSub1) < 0) + { + BigInteger a = d.ModPow(pSub1Divq, p); + + if (a.CompareTo(BigInteger.One) != 0) + { + return a; + } + } + } + } + + /** + * which generates the p , q and a values from the given parameters, + * returning the Gost3410Parameters object. + */ + public Gost3410Parameters GenerateParameters() + { + BigInteger [] pq = new BigInteger[2]; + BigInteger q = null, p = null, a = null; + + int x0, c; + long x0L, cL; + + if (typeproc==1) + { + x0 = init_random.NextInt(); + c = init_random.NextInt(); + + switch(size) + { + case 512: + procedure_A(x0, c, pq, 512); + break; + case 1024: + procedure_B(x0, c, pq); + break; + default: + throw new ArgumentException("Ooops! key size 512 or 1024 bit."); + } + p = pq[0]; q = pq[1]; + a = procedure_C(p, q); + //System.out.println("p:"+p.toString(16)+"\n"+"q:"+q.toString(16)+"\n"+"a:"+a.toString(16)); + //System.out.println("p:"+p+"\n"+"q:"+q+"\n"+"a:"+a); + return new Gost3410Parameters(p, q, a, new Gost3410ValidationParameters(x0, c)); + } + else + { + x0L = init_random.NextLong(); + cL = init_random.NextLong(); + + switch(size) + { + case 512: + procedure_Aa(x0L, cL, pq, 512); + break; + case 1024: + procedure_Bb(x0L, cL, pq); + break; + default: + throw new InvalidOperationException("Ooops! key size 512 or 1024 bit."); + } + p = pq[0]; q = pq[1]; + a = procedure_C(p, q); + //System.out.println("p:"+p.toString(16)+"\n"+"q:"+q.toString(16)+"\n"+"a:"+a.toString(16)); + //System.out.println("p:"+p+"\n"+"q:"+q+"\n"+"a:"+a); + return new Gost3410Parameters(p, q, a, new Gost3410ValidationParameters(x0L, cL)); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/GOST3410ParametersGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/GOST3410ParametersGenerator.cs.meta new file mode 100644 index 0000000..fc5f5fd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/GOST3410ParametersGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2e6f52e94b7ebf5448af4739023ae7a7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/HKdfBytesGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/HKdfBytesGenerator.cs new file mode 100644 index 0000000..6f36a6f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/HKdfBytesGenerator.cs @@ -0,0 +1,152 @@ +using System; + +using Org.BouncyCastle.Crypto.Macs; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Generators +{ + /** + * HMAC-based Extract-and-Expand Key Derivation Function (HKDF) implemented + * according to IETF RFC 5869, May 2010 as specified by H. Krawczyk, IBM + * Research & P. Eronen, Nokia. It uses a HMac internally to compute de OKM + * (output keying material) and is likely to have better security properties + * than KDF's based on just a hash function. + */ + public class HkdfBytesGenerator + : IDerivationFunction + { + private HMac hMacHash; + private int hashLen; + + private byte[] info; + private byte[] currentT; + + private int generatedBytes; + + /** + * Creates a HKDFBytesGenerator based on the given hash function. + * + * @param hash the digest to be used as the source of generatedBytes bytes + */ + public HkdfBytesGenerator(IDigest hash) + { + this.hMacHash = new HMac(hash); + this.hashLen = hash.GetDigestSize(); + } + + public virtual void Init(IDerivationParameters parameters) + { + if (!(parameters is HkdfParameters)) + throw new ArgumentException("HKDF parameters required for HkdfBytesGenerator", "parameters"); + + HkdfParameters hkdfParameters = (HkdfParameters)parameters; + if (hkdfParameters.SkipExtract) + { + // use IKM directly as PRK + hMacHash.Init(new KeyParameter(hkdfParameters.GetIkm())); + } + else + { + hMacHash.Init(Extract(hkdfParameters.GetSalt(), hkdfParameters.GetIkm())); + } + + info = hkdfParameters.GetInfo(); + + generatedBytes = 0; + currentT = new byte[hashLen]; + } + + /** + * Performs the extract part of the key derivation function. + * + * @param salt the salt to use + * @param ikm the input keying material + * @return the PRK as KeyParameter + */ + private KeyParameter Extract(byte[] salt, byte[] ikm) + { + if (salt == null) + { + // TODO check if hashLen is indeed same as HMAC size + hMacHash.Init(new KeyParameter(new byte[hashLen])); + } + else + { + hMacHash.Init(new KeyParameter(salt)); + } + + hMacHash.BlockUpdate(ikm, 0, ikm.Length); + + byte[] prk = new byte[hashLen]; + hMacHash.DoFinal(prk, 0); + return new KeyParameter(prk); + } + + /** + * Performs the expand part of the key derivation function, using currentT + * as input and output buffer. + * + * @throws DataLengthException if the total number of bytes generated is larger than the one + * specified by RFC 5869 (255 * HashLen) + */ + private void ExpandNext() + { + int n = generatedBytes / hashLen + 1; + if (n >= 256) + { + throw new DataLengthException( + "HKDF cannot generate more than 255 blocks of HashLen size"); + } + // special case for T(0): T(0) is empty, so no update + if (generatedBytes != 0) + { + hMacHash.BlockUpdate(currentT, 0, hashLen); + } + hMacHash.BlockUpdate(info, 0, info.Length); + hMacHash.Update((byte)n); + hMacHash.DoFinal(currentT, 0); + } + + public virtual IDigest Digest + { + get { return hMacHash.GetUnderlyingDigest(); } + } + + public virtual int GenerateBytes(byte[] output, int outOff, int len) + { + if (generatedBytes + len > 255 * hashLen) + { + throw new DataLengthException( + "HKDF may only be used for 255 * HashLen bytes of output"); + } + + if (generatedBytes % hashLen == 0) + { + ExpandNext(); + } + + // copy what is left in the currentT (1..hash + int toGenerate = len; + int posInT = generatedBytes % hashLen; + int leftInT = hashLen - generatedBytes % hashLen; + int toCopy = System.Math.Min(leftInT, toGenerate); + Array.Copy(currentT, posInT, output, outOff, toCopy); + generatedBytes += toCopy; + toGenerate -= toCopy; + outOff += toCopy; + + while (toGenerate > 0) + { + ExpandNext(); + toCopy = System.Math.Min(hashLen, toGenerate); + Array.Copy(currentT, 0, output, outOff, toCopy); + generatedBytes += toCopy; + toGenerate -= toCopy; + outOff += toCopy; + } + + return len; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/HKdfBytesGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/HKdfBytesGenerator.cs.meta new file mode 100644 index 0000000..56cec37 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/HKdfBytesGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 618cf7b08b2525b40811d660d288fb63 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/KDFCounterBytesGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/KDFCounterBytesGenerator.cs new file mode 100644 index 0000000..9c2b2fd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/KDFCounterBytesGenerator.cs @@ -0,0 +1,154 @@ +using System; + +using Org.BouncyCastle.Crypto.Macs; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Generators +{ + public class KdfCounterBytesGenerator : IMacDerivationFunction + { + + private static readonly BigInteger IntegerMax = BigInteger.ValueOf(0x7fffffff); + private static readonly BigInteger Two = BigInteger.Two; + + + private readonly IMac prf; + private readonly int h; + + private byte[] fixedInputDataCtrPrefix; + private byte[] fixedInputData_afterCtr; + private int maxSizeExcl; + // ios is i defined as an octet string (the binary representation) + private byte[] ios; + + // operational + private int generatedBytes; + // k is used as buffer for all K(i) values + private byte[] k; + + public KdfCounterBytesGenerator(IMac prf) + { + this.prf = prf; + this.h = prf.GetMacSize(); + this.k = new byte[h]; + } + + public void Init(IDerivationParameters param) + { + KdfCounterParameters kdfParams = param as KdfCounterParameters; + if (kdfParams == null) + { + throw new ArgumentException("Wrong type of arguments given"); + } + + + + // --- init mac based PRF --- + + this.prf.Init(new KeyParameter(kdfParams.Ki)); + + // --- set arguments --- + + this.fixedInputDataCtrPrefix = kdfParams.FixedInputDataCounterPrefix; + this.fixedInputData_afterCtr = kdfParams.FixedInputDataCounterSuffix; + + int r = kdfParams.R; + this.ios = new byte[r / 8]; + + BigInteger maxSize = Two.Pow(r).Multiply(BigInteger.ValueOf(h)); + this.maxSizeExcl = maxSize.CompareTo(IntegerMax) == 1 ? + Int32.MaxValue : maxSize.IntValue; + + // --- set operational state --- + + generatedBytes = 0; + } + + + public IMac GetMac() + { + return prf; + } + + public IDigest Digest + { + get { return prf is HMac ? ((HMac)prf).GetUnderlyingDigest() : null; } + } + + public int GenerateBytes(byte[] output, int outOff, int length) + { + int generatedBytesAfter = generatedBytes + length; + if (generatedBytesAfter < 0 || generatedBytesAfter >= maxSizeExcl) + { + throw new DataLengthException( + "Current KDFCTR may only be used for " + maxSizeExcl + " bytes"); + } + + if (generatedBytes % h == 0) + { + generateNext(); + } + + // copy what is left in the currentT (1..hash + int toGenerate = length; + int posInK = generatedBytes % h; + int leftInK = h - generatedBytes % h; + int toCopy = System.Math.Min(leftInK, toGenerate); + Array.Copy(k, posInK, output, outOff, toCopy); + generatedBytes += toCopy; + toGenerate -= toCopy; + outOff += toCopy; + + while (toGenerate > 0) + { + generateNext(); + toCopy = System.Math.Min(h, toGenerate); + Array.Copy(k, 0, output, outOff, toCopy); + generatedBytes += toCopy; + toGenerate -= toCopy; + outOff += toCopy; + } + + return length; + + } + + private void generateNext() + { + + int i = generatedBytes / h + 1; + + // encode i into counter buffer + switch (ios.Length) + { + case 4: + ios[0] = (byte)(i >> 24); + goto case 3; + // fall through + case 3: + ios[ios.Length - 3] = (byte)(i >> 16); + // fall through + goto case 2; + case 2: + ios[ios.Length - 2] = (byte)(i >> 8); + // fall through + goto case 1; + case 1: + ios[ios.Length - 1] = (byte)i; + break; + default: + throw new InvalidOperationException("Unsupported size of counter i"); + } + + + + // special case for K(0): K(0) is empty, so no update + prf.BlockUpdate(fixedInputDataCtrPrefix, 0, fixedInputDataCtrPrefix.Length); + prf.BlockUpdate(ios, 0, ios.Length); + prf.BlockUpdate(fixedInputData_afterCtr, 0, fixedInputData_afterCtr.Length); + prf.DoFinal(k, 0); + } + } +} \ No newline at end of file diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/KDFCounterBytesGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/KDFCounterBytesGenerator.cs.meta new file mode 100644 index 0000000..732071d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/KDFCounterBytesGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9bd16dfbede3cb14c984a9480a194900 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/KDFDoublePipelineIterationBytesGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/KDFDoublePipelineIterationBytesGenerator.cs new file mode 100644 index 0000000..9010ae2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/KDFDoublePipelineIterationBytesGenerator.cs @@ -0,0 +1,182 @@ +using System; + +using Org.BouncyCastle.Crypto.Macs; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Generators +{ + public class KdfDoublePipelineIterationBytesGenerator : IMacDerivationFunction + { + private static readonly BigInteger IntegerMax = BigInteger.ValueOf(0x7fffffff); + private static readonly BigInteger Two = BigInteger.Two; + + // fields set by the constructor + private readonly IMac prf; + private readonly int h; + + // fields set by init + private byte[] fixedInputData; + private int maxSizeExcl; + // ios is i defined as an octet string (the binary representation) + private byte[] ios; + private bool useCounter; + + // operational + private int generatedBytes; + // k is used as buffer for all K(i) values + private byte[] a; + private byte[] k; + + + public KdfDoublePipelineIterationBytesGenerator(IMac prf) + { + this.prf = prf; + this.h = prf.GetMacSize(); + this.a = new byte[h]; + this.k = new byte[h]; + } + + + public void Init(IDerivationParameters parameters) + { + KdfDoublePipelineIterationParameters dpiParams = parameters as KdfDoublePipelineIterationParameters; + if (dpiParams == null) + { + throw new ArgumentException("Wrong type of arguments given"); + } + + + + // --- init mac based PRF --- + + this.prf.Init(new KeyParameter(dpiParams.Ki)); + + // --- set arguments --- + + this.fixedInputData = dpiParams.FixedInputData; + + int r = dpiParams.R; + this.ios = new byte[r / 8]; + + if (dpiParams.UseCounter) + { + // this is more conservative than the spec + BigInteger maxSize = Two.Pow(r).Multiply(BigInteger.ValueOf(h)); + this.maxSizeExcl = maxSize.CompareTo(IntegerMax) == 1 ? + Int32.MaxValue : maxSize.IntValue; + } + else + { + this.maxSizeExcl = IntegerMax.IntValue; + } + + this.useCounter = dpiParams.UseCounter; + + // --- set operational state --- + + generatedBytes = 0; + } + + + + + private void generateNext() + { + + if (generatedBytes == 0) + { + // --- step 4 --- + prf.BlockUpdate(fixedInputData, 0, fixedInputData.Length); + prf.DoFinal(a, 0); + } + else + { + // --- step 5a --- + prf.BlockUpdate(a, 0, a.Length); + prf.DoFinal(a, 0); + } + + // --- step 5b --- + prf.BlockUpdate(a, 0, a.Length); + + if (useCounter) + { + int i = generatedBytes / h + 1; + + // encode i into counter buffer + switch (ios.Length) + { + case 4: + ios[0] = (byte)(i >> 24); + // fall through + goto case 3; + case 3: + ios[ios.Length - 3] = (byte)(i >> 16); + // fall through + goto case 2; + case 2: + ios[ios.Length - 2] = (byte)(i >> 8); + // fall through + goto case 1; + case 1: + ios[ios.Length - 1] = (byte)i; + break; + default: + throw new InvalidOperationException("Unsupported size of counter i"); + } + prf.BlockUpdate(ios, 0, ios.Length); + } + + prf.BlockUpdate(fixedInputData, 0, fixedInputData.Length); + prf.DoFinal(k, 0); + } + + public IDigest Digest + { + get { return prf is HMac ? ((HMac)prf).GetUnderlyingDigest() : null; } + } + + public int GenerateBytes(byte[] output, int outOff, int length) + { + int generatedBytesAfter = generatedBytes + length; + if (generatedBytesAfter < 0 || generatedBytesAfter >= maxSizeExcl) + { + throw new DataLengthException( + "Current KDFCTR may only be used for " + maxSizeExcl + " bytes"); + } + + if (generatedBytes % h == 0) + { + generateNext(); + } + + // copy what is left in the currentT (1..hash + int toGenerate = length; + int posInK = generatedBytes % h; + int leftInK = h - generatedBytes % h; + int toCopy = System.Math.Min(leftInK, toGenerate); + Array.Copy(k, posInK, output, outOff, toCopy); + generatedBytes += toCopy; + toGenerate -= toCopy; + outOff += toCopy; + + while (toGenerate > 0) + { + generateNext(); + toCopy = System.Math.Min(h, toGenerate); + Array.Copy(k, 0, output, outOff, toCopy); + generatedBytes += toCopy; + toGenerate -= toCopy; + outOff += toCopy; + } + + return length; + } + + public IMac GetMac() + { + return prf; + } + } +} \ No newline at end of file diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/KDFDoublePipelineIterationBytesGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/KDFDoublePipelineIterationBytesGenerator.cs.meta new file mode 100644 index 0000000..d322870 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/KDFDoublePipelineIterationBytesGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 54c41f64d4c9f25439b67987f9dae4b2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/KDFFeedbackBytesGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/KDFFeedbackBytesGenerator.cs new file mode 100644 index 0000000..19ce0ea --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/KDFFeedbackBytesGenerator.cs @@ -0,0 +1,177 @@ +using System; + +using Org.BouncyCastle.Crypto.Macs; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Generators +{ + public class KdfFeedbackBytesGenerator : IMacDerivationFunction + { + private static readonly BigInteger IntegerMax = BigInteger.ValueOf(0x7fffffff); + private static readonly BigInteger Two = BigInteger.Two; + + // please refer to the standard for the meaning of the variable names + // all field lengths are in bytes, not in bits as specified by the standard + + // fields set by the constructor + private readonly IMac prf; + private readonly int h; + + // fields set by init + private byte[] fixedInputData; + private int maxSizeExcl; + // ios is i defined as an octet string (the binary representation) + private byte[] ios; + private byte[] iv; + private bool useCounter; + + // operational + private int generatedBytes; + // k is used as buffer for all K(i) values + private byte[] k; + + public KdfFeedbackBytesGenerator(IMac prf) + { + this.prf = prf; + this.h = prf.GetMacSize(); + this.k = new byte[h]; + } + + + public void Init(IDerivationParameters parameters) + { + KdfFeedbackParameters feedbackParams = parameters as KdfFeedbackParameters; + if (feedbackParams == null) + { + throw new ArgumentException("Wrong type of arguments given"); + } + + + // --- init mac based PRF --- + + this.prf.Init(new KeyParameter(feedbackParams.Ki)); + + // --- set arguments --- + + this.fixedInputData = feedbackParams.FixedInputData; + + int r = feedbackParams.R; + this.ios = new byte[r / 8]; + + if (feedbackParams.UseCounter) + { + // this is more conservative than the spec + BigInteger maxSize = Two.Pow(r).Multiply(BigInteger.ValueOf(h)); + this.maxSizeExcl = maxSize.CompareTo(IntegerMax) == 1 ? + Int32.MaxValue : maxSize.IntValue; + } + else + { + this.maxSizeExcl = Int32.MaxValue; + } + + this.iv = feedbackParams.Iv; + this.useCounter = feedbackParams.UseCounter; + + // --- set operational state --- + + generatedBytes = 0; + } + + public IDigest Digest + { + get { return prf is HMac ? ((HMac)prf).GetUnderlyingDigest() : null; } + } + + public int GenerateBytes(byte[] output, int outOff, int length) + { + int generatedBytesAfter = generatedBytes + length; + if (generatedBytesAfter < 0 || generatedBytesAfter >= maxSizeExcl) + { + throw new DataLengthException( + "Current KDFCTR may only be used for " + maxSizeExcl + " bytes"); + } + + if (generatedBytes % h == 0) + { + generateNext(); + } + + // copy what is left in the currentT (1..hash + int toGenerate = length; + int posInK = generatedBytes % h; + int leftInK = h - generatedBytes % h; + + + int toCopy = System.Math.Min(leftInK, toGenerate); + Array.Copy(k, posInK, output, outOff, toCopy); + + generatedBytes += toCopy; + toGenerate -= toCopy; + outOff += toCopy; + + while (toGenerate > 0) + { + generateNext(); + toCopy = System.Math.Min(h, toGenerate); + Array.Copy(k, 0, output, outOff, toCopy); + generatedBytes += toCopy; + toGenerate -= toCopy; + outOff += toCopy; + } + + return length; + } + + private void generateNext() + { + + // TODO enable IV + if (generatedBytes == 0) + { + prf.BlockUpdate(iv, 0, iv.Length); + } + else + { + prf.BlockUpdate(k, 0, k.Length); + } + + if (useCounter) + { + int i = generatedBytes / h + 1; + + // encode i into counter buffer + switch (ios.Length) + { + case 4: + ios[0] = (byte)(i >> 24); + goto case 3; + // fall through + case 3: + ios[ios.Length - 3] = (byte)(i >> 16); + // fall through + goto case 2; + case 2: + ios[ios.Length - 2] = (byte)(i >> 8); + // fall through + goto case 1; + case 1: + ios[ios.Length - 1] = (byte)i; + break; + default: + throw new InvalidOperationException("Unsupported size of counter i"); + } + prf.BlockUpdate(ios, 0, ios.Length); + } + + prf.BlockUpdate(fixedInputData, 0, fixedInputData.Length); + prf.DoFinal(k, 0); + } + + public IMac GetMac() + { + return prf; + } + } +} \ No newline at end of file diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/KDFFeedbackBytesGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/KDFFeedbackBytesGenerator.cs.meta new file mode 100644 index 0000000..42dbe0c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/KDFFeedbackBytesGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2e2661ffc73cf9e488ae60502f2c045b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Kdf1BytesGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Kdf1BytesGenerator.cs new file mode 100644 index 0000000..0ddf6c1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Kdf1BytesGenerator.cs @@ -0,0 +1,26 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Generators +{ + /** + * KFD2 generator for derived keys and ivs as defined by IEEE P1363a/ISO 18033 + *
+ * This implementation is based on IEEE P1363/ISO 18033. + */ + public class Kdf1BytesGenerator + : BaseKdfBytesGenerator + { + /** + * Construct a KDF1 byte generator. + * + * @param digest the digest to be used as the source of derived keys. + */ + public Kdf1BytesGenerator(IDigest digest) + : base(0, digest) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Kdf1BytesGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Kdf1BytesGenerator.cs.meta new file mode 100644 index 0000000..58720ac --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Kdf1BytesGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 92d89db7d508d4a4dbc71850dccb5106 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Kdf2BytesGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Kdf2BytesGenerator.cs new file mode 100644 index 0000000..8a68219 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Kdf2BytesGenerator.cs @@ -0,0 +1,27 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Generators +{ + /** + * KDF2 generator for derived keys and ivs as defined by IEEE P1363a/ISO 18033 + *
+ * This implementation is based on IEEE P1363/ISO 18033. + */ + public class Kdf2BytesGenerator + : BaseKdfBytesGenerator + { + /** + * Construct a KDF2 bytes generator. Generates key material + * according to IEEE P1363 or ISO 18033 depending on the initialisation. + * + * @param digest the digest to be used as the source of derived keys. + */ + public Kdf2BytesGenerator(IDigest digest) + : base(1, digest) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Kdf2BytesGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Kdf2BytesGenerator.cs.meta new file mode 100644 index 0000000..d5a5cc8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Kdf2BytesGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9a145f8255bb32342b28280674ebdc1c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Mgf1BytesGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Mgf1BytesGenerator.cs new file mode 100644 index 0000000..23a3aca --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Mgf1BytesGenerator.cs @@ -0,0 +1,117 @@ +using System; +//using Org.BouncyCastle.Math; +//using Org.BouncyCastle.Security; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Generators +{ + /** + * Generator for MGF1 as defined in Pkcs 1v2 + */ + public class Mgf1BytesGenerator : IDerivationFunction + { + private IDigest digest; + private byte[] seed; + private int hLen; + + /** + * @param digest the digest to be used as the source of Generated bytes + */ + public Mgf1BytesGenerator( + IDigest digest) + { + this.digest = digest; + this.hLen = digest.GetDigestSize(); + } + + public void Init( + IDerivationParameters parameters) + { + if (!(typeof(MgfParameters).IsInstanceOfType(parameters))) + { + throw new ArgumentException("MGF parameters required for MGF1Generator"); + } + + MgfParameters p = (MgfParameters)parameters; + + seed = p.GetSeed(); + } + + /** + * return the underlying digest. + */ + public IDigest Digest + { + get + { + return digest; + } + } + + /** + * int to octet string. + */ + private void ItoOSP( + int i, + byte[] sp) + { + sp[0] = (byte)((uint) i >> 24); + sp[1] = (byte)((uint) i >> 16); + sp[2] = (byte)((uint) i >> 8); + sp[3] = (byte)((uint) i >> 0); + } + + /** + * fill len bytes of the output buffer with bytes Generated from + * the derivation function. + * + * @throws DataLengthException if the out buffer is too small. + */ + public int GenerateBytes( + byte[] output, + int outOff, + int length) + { + if ((output.Length - length) < outOff) + { + throw new DataLengthException("output buffer too small"); + } + + byte[] hashBuf = new byte[hLen]; + byte[] C = new byte[4]; + int counter = 0; + + digest.Reset(); + + if (length > hLen) + { + do + { + ItoOSP(counter, C); + + digest.BlockUpdate(seed, 0, seed.Length); + digest.BlockUpdate(C, 0, C.Length); + digest.DoFinal(hashBuf, 0); + + Array.Copy(hashBuf, 0, output, outOff + counter * hLen, hLen); + } + while (++counter < (length / hLen)); + } + + if ((counter * hLen) < length) + { + ItoOSP(counter, C); + + digest.BlockUpdate(seed, 0, seed.Length); + digest.BlockUpdate(C, 0, C.Length); + digest.DoFinal(hashBuf, 0); + + Array.Copy(hashBuf, 0, output, outOff + counter * hLen, length - (counter * hLen)); + } + + return length; + } + } + +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Mgf1BytesGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Mgf1BytesGenerator.cs.meta new file mode 100644 index 0000000..6779588 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Mgf1BytesGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1dc94d2b7c95faa458188616c7b05403 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/NaccacheSternKeyPairGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/NaccacheSternKeyPairGenerator.cs new file mode 100644 index 0000000..d681068 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/NaccacheSternKeyPairGenerator.cs @@ -0,0 +1,268 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Crypto.Generators +{ + /** + * Key generation parameters for NaccacheStern cipher. For details on this cipher, please see + * + * http://www.gemplus.com/smart/rd/publications/pdf/NS98pkcs.pdf + */ + public class NaccacheSternKeyPairGenerator + : IAsymmetricCipherKeyPairGenerator + { + private static readonly int[] smallPrimes = + { + 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, + 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, + 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, + 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, + 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, + 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, + 541, 547, 557 + }; + + private NaccacheSternKeyGenerationParameters param; + + /* + * (non-Javadoc) + * + * @see org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator#init(org.bouncycastle.crypto.KeyGenerationParameters) + */ + public void Init(KeyGenerationParameters parameters) + { + this.param = (NaccacheSternKeyGenerationParameters)parameters; + } + + /* + * (non-Javadoc) + * + * @see org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator#generateKeyPair() + */ + public AsymmetricCipherKeyPair GenerateKeyPair() + { + int strength = param.Strength; + SecureRandom rand = param.Random; + int certainty = param.Certainty; + + IList smallPrimes = findFirstPrimes(param.CountSmallPrimes); + + smallPrimes = permuteList(smallPrimes, rand); + + BigInteger u = BigInteger.One; + BigInteger v = BigInteger.One; + + for (int i = 0; i < smallPrimes.Count / 2; i++) + { + u = u.Multiply((BigInteger)smallPrimes[i]); + } + for (int i = smallPrimes.Count / 2; i < smallPrimes.Count; i++) + { + v = v.Multiply((BigInteger)smallPrimes[i]); + } + + BigInteger sigma = u.Multiply(v); + + // n = (2 a u _p + 1 ) ( 2 b v _q + 1) + // -> |n| = strength + // |2| = 1 in bits + // -> |a| * |b| = |n| - |u| - |v| - |_p| - |_q| - |2| -|2| + // remainingStrength = strength - sigma.bitLength() - _p.bitLength() - + // _q.bitLength() - 1 -1 + int remainingStrength = strength - sigma.BitLength - 48; + BigInteger a = generatePrime(remainingStrength / 2 + 1, certainty, rand); + BigInteger b = generatePrime(remainingStrength / 2 + 1, certainty, rand); + + BigInteger _p; + BigInteger _q; + BigInteger p; + BigInteger q; + + long tries = 0; + + BigInteger _2au = a.Multiply(u).ShiftLeft(1); + BigInteger _2bv = b.Multiply(v).ShiftLeft(1); + + for (;;) + { + tries++; + + _p = generatePrime(24, certainty, rand); + + p = _p.Multiply(_2au).Add(BigInteger.One); + + if (!p.IsProbablePrime(certainty, true)) + continue; + + for (;;) + { + _q = generatePrime(24, certainty, rand); + + if (_p.Equals(_q)) + continue; + + q = _q.Multiply(_2bv).Add(BigInteger.One); + + if (q.IsProbablePrime(certainty, true)) + break; + } + + if (!sigma.Gcd(_p.Multiply(_q)).Equals(BigInteger.One)) + { + //Console.WriteLine("sigma.gcd(_p.mult(_q)) != 1!\n _p: " + _p +"\n _q: "+ _q ); + continue; + } + + if (p.Multiply(q).BitLength < strength) + { + continue; + } + break; + } + + BigInteger n = p.Multiply(q); + BigInteger phi_n = p.Subtract(BigInteger.One).Multiply(q.Subtract(BigInteger.One)); + BigInteger g; + tries = 0; + + for (;;) + { + // TODO After the first loop, just regenerate one randomly-selected gPart each time? + IList gParts = Platform.CreateArrayList(); + for (int ind = 0; ind != smallPrimes.Count; ind++) + { + BigInteger i = (BigInteger)smallPrimes[ind]; + BigInteger e = phi_n.Divide(i); + + for (;;) + { + tries++; + + g = generatePrime(strength, certainty, rand); + + if (!g.ModPow(e, n).Equals(BigInteger.One)) + { + gParts.Add(g); + break; + } + } + } + g = BigInteger.One; + for (int i = 0; i < smallPrimes.Count; i++) + { + BigInteger gPart = (BigInteger) gParts[i]; + BigInteger smallPrime = (BigInteger) smallPrimes[i]; + g = g.Multiply(gPart.ModPow(sigma.Divide(smallPrime), n)).Mod(n); + } + + // make sure that g is not divisible by p_i or q_i + bool divisible = false; + for (int i = 0; i < smallPrimes.Count; i++) + { + if (g.ModPow(phi_n.Divide((BigInteger)smallPrimes[i]), n).Equals(BigInteger.One)) + { + divisible = true; + break; + } + } + + if (divisible) + { + continue; + } + + // make sure that g has order > phi_n/4 + + //if (g.ModPow(phi_n.Divide(BigInteger.ValueOf(4)), n).Equals(BigInteger.One)) + if (g.ModPow(phi_n.ShiftRight(2), n).Equals(BigInteger.One)) + { + continue; + } + + if (g.ModPow(phi_n.Divide(_p), n).Equals(BigInteger.One)) + { + continue; + } + if (g.ModPow(phi_n.Divide(_q), n).Equals(BigInteger.One)) + { + continue; + } + if (g.ModPow(phi_n.Divide(a), n).Equals(BigInteger.One)) + { + continue; + } + if (g.ModPow(phi_n.Divide(b), n).Equals(BigInteger.One)) + { + continue; + } + break; + } + + return new AsymmetricCipherKeyPair(new NaccacheSternKeyParameters(false, g, n, sigma.BitLength), + new NaccacheSternPrivateKeyParameters(g, n, sigma.BitLength, smallPrimes, phi_n)); + } + + private static BigInteger generatePrime( + int bitLength, + int certainty, + SecureRandom rand) + { + return new BigInteger(bitLength, certainty, rand); + } + + /** + * Generates a permuted ArrayList from the original one. The original List + * is not modified + * + * @param arr + * the ArrayList to be permuted + * @param rand + * the source of Randomness for permutation + * @return a new IList with the permuted elements. + */ + private static IList permuteList( + IList arr, + SecureRandom rand) + { + // TODO Create a utility method for generating permutation of first 'n' integers + + IList retval = Platform.CreateArrayList(arr.Count); + + foreach (object element in arr) + { + int index = rand.Next(retval.Count + 1); + retval.Insert(index, element); + } + + return retval; + } + + /** + * Finds the first 'count' primes starting with 3 + * + * @param count + * the number of primes to find + * @return a vector containing the found primes as Integer + */ + private static IList findFirstPrimes( + int count) + { + IList primes = Platform.CreateArrayList(count); + + for (int i = 0; i != count; i++) + { + primes.Add(BigInteger.ValueOf(smallPrimes[i])); + } + + return primes; + } + + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/NaccacheSternKeyPairGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/NaccacheSternKeyPairGenerator.cs.meta new file mode 100644 index 0000000..18858f3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/NaccacheSternKeyPairGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 869cb3350dd2e854da187114a63f3dfc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/OpenBsdBCrypt.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/OpenBsdBCrypt.cs new file mode 100644 index 0000000..da6e2b9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/OpenBsdBCrypt.cs @@ -0,0 +1,305 @@ +using System; +using System.IO; +using System.Text; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Crypto.Generators +{ + /** + * Password hashing scheme BCrypt, + * designed by Niels Provos and David Mazières, using the + * String format and the Base64 encoding + * of the reference implementation on OpenBSD + */ + public class OpenBsdBCrypt + { + private static readonly byte[] EncodingTable = // the Bcrypts encoding table for OpenBSD + { + (byte)'.', (byte)'/', (byte)'A', (byte)'B', (byte)'C', (byte)'D', + (byte)'E', (byte)'F', (byte)'G', (byte)'H', (byte)'I', (byte)'J', + (byte)'K', (byte)'L', (byte)'M', (byte)'N', (byte)'O', (byte)'P', + (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U', (byte)'V', + (byte)'W', (byte)'X', (byte)'Y', (byte)'Z', (byte)'a', (byte)'b', + (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g', (byte)'h', + (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n', + (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', + (byte)'u', (byte)'v', (byte)'w', (byte)'x', (byte)'y', (byte)'z', + (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', + (byte)'6', (byte)'7', (byte)'8', (byte)'9' + }; + + /* + * set up the decoding table. + */ + private static readonly byte[] DecodingTable = new byte[128]; + private static readonly string DefaultVersion = "2y"; + private static readonly ISet AllowedVersions = new HashSet(); + + static OpenBsdBCrypt() + { + // Presently just the Bcrypt versions. + AllowedVersions.Add("2a"); + AllowedVersions.Add("2y"); + AllowedVersions.Add("2b"); + + for (int i = 0; i < DecodingTable.Length; i++) + { + DecodingTable[i] = (byte)0xff; + } + + for (int i = 0; i < EncodingTable.Length; i++) + { + DecodingTable[EncodingTable[i]] = (byte)i; + } + } + + public OpenBsdBCrypt() + { + } + + /** + * Creates a 60 character Bcrypt String, including + * version, cost factor, salt and hash, separated by '$' + * + * @param version the version, 2y,2b or 2a. (2a is not backwards compatible.) + * @param cost the cost factor, treated as an exponent of 2 + * @param salt a 16 byte salt + * @param password the password + * @return a 60 character Bcrypt String + */ + private static string CreateBcryptString(string version, byte[] password, byte[] salt, int cost) + { + if (!AllowedVersions.Contains(version)) + throw new ArgumentException("Version " + version + " is not accepted by this implementation.", "version"); + + StringBuilder sb = new StringBuilder(60); + sb.Append('$'); + sb.Append(version); + sb.Append('$'); + sb.Append(cost < 10 ? ("0" + cost) : cost.ToString()); + sb.Append('$'); + sb.Append(EncodeData(salt)); + + byte[] key = BCrypt.Generate(password, salt, cost); + + sb.Append(EncodeData(key)); + + return sb.ToString(); + } + + /** + * Creates a 60 character Bcrypt String, including + * version, cost factor, salt and hash, separated by '$' using version + * '2y'. + * + * @param cost the cost factor, treated as an exponent of 2 + * @param salt a 16 byte salt + * @param password the password + * @return a 60 character Bcrypt String + */ + public static string Generate(char[] password, byte[] salt, int cost) + { + return Generate(DefaultVersion, password, salt, cost); + } + + /** + * Creates a 60 character Bcrypt String, including + * version, cost factor, salt and hash, separated by '$' + * + * @param version the version, may be 2b, 2y or 2a. (2a is not backwards compatible.) + * @param cost the cost factor, treated as an exponent of 2 + * @param salt a 16 byte salt + * @param password the password + * @return a 60 character Bcrypt String + */ + public static string Generate(string version, char[] password, byte[] salt, int cost) + { + if (!AllowedVersions.Contains(version)) + throw new ArgumentException("Version " + version + " is not accepted by this implementation.", "version"); + if (password == null) + throw new ArgumentNullException("password"); + if (salt == null) + throw new ArgumentNullException("salt"); + if (salt.Length != 16) + throw new DataLengthException("16 byte salt required: " + salt.Length); + + if (cost < 4 || cost > 31) // Minimum rounds: 16, maximum 2^31 + throw new ArgumentException("Invalid cost factor.", "cost"); + + byte[] psw = Strings.ToUtf8ByteArray(password); + + // 0 termination: + + byte[] tmp = new byte[psw.Length >= 72 ? 72 : psw.Length + 1]; + int copyLen = System.Math.Min(psw.Length, tmp.Length); + Array.Copy(psw, 0, tmp, 0, copyLen); + + Array.Clear(psw, 0, psw.Length); + + string rv = CreateBcryptString(version, tmp, salt, cost); + + Array.Clear(tmp, 0, tmp.Length); + + return rv; + } + + /** + * Checks if a password corresponds to a 60 character Bcrypt String + * + * @param bcryptString a 60 character Bcrypt String, including + * version, cost factor, salt and hash, + * separated by '$' + * @param password the password as an array of chars + * @return true if the password corresponds to the + * Bcrypt String, otherwise false + */ + public static bool CheckPassword(string bcryptString, char[] password) + { + // validate bcryptString: + if (bcryptString.Length != 60) + throw new DataLengthException("Bcrypt String length: " + bcryptString.Length + ", 60 required."); + if (bcryptString[0] != '$' || bcryptString[3] != '$' || bcryptString[6] != '$') + throw new ArgumentException("Invalid Bcrypt String format.", "bcryptString"); + + string version = bcryptString.Substring(1, 2); + if (!AllowedVersions.Contains(version)) + throw new ArgumentException("Bcrypt version '" + version + "' is not supported by this implementation", "bcryptString"); + + int cost = 0; + try + { + cost = Int32.Parse(bcryptString.Substring(4, 2)); + } + catch (Exception nfe) + { +#if PORTABLE + throw new ArgumentException("Invalid cost factor: " + bcryptString.Substring(4, 2), "bcryptString"); +#else + throw new ArgumentException("Invalid cost factor: " + bcryptString.Substring(4, 2), "bcryptString", nfe); +#endif + } + if (cost < 4 || cost > 31) + throw new ArgumentException("Invalid cost factor: " + cost + ", 4 < cost < 31 expected."); + + // check password: + if (password == null) + throw new ArgumentNullException("Missing password."); + + int start = bcryptString.LastIndexOf('$') + 1, end = bcryptString.Length - 31; + byte[] salt = DecodeSaltString(bcryptString.Substring(start, end - start)); + + string newBcryptString = Generate(version, password, salt, cost); + + return bcryptString.Equals(newBcryptString); + } + + /* + * encode the input data producing a Bcrypt base 64 string. + * + * @param a byte representation of the salt or the password + * @return the Bcrypt base64 string + */ + private static string EncodeData(byte[] data) + { + if (data.Length != 24 && data.Length != 16) // 192 bit key or 128 bit salt expected + throw new DataLengthException("Invalid length: " + data.Length + ", 24 for key or 16 for salt expected"); + + bool salt = false; + if (data.Length == 16)//salt + { + salt = true; + byte[] tmp = new byte[18];// zero padding + Array.Copy(data, 0, tmp, 0, data.Length); + data = tmp; + } + else // key + { + data[data.Length - 1] = (byte)0; + } + + MemoryStream mOut = new MemoryStream(); + int len = data.Length; + + uint a1, a2, a3; + int i; + for (i = 0; i < len; i += 3) + { + a1 = data[i]; + a2 = data[i + 1]; + a3 = data[i + 2]; + + mOut.WriteByte(EncodingTable[(a1 >> 2) & 0x3f]); + mOut.WriteByte(EncodingTable[((a1 << 4) | (a2 >> 4)) & 0x3f]); + mOut.WriteByte(EncodingTable[((a2 << 2) | (a3 >> 6)) & 0x3f]); + mOut.WriteByte(EncodingTable[a3 & 0x3f]); + } + + string result = Strings.FromByteArray(mOut.ToArray()); + int resultLen = salt + ? 22 // truncate padding + : result.Length - 1; + + return result.Substring(0, resultLen); + } + + + /* + * decodes the bcrypt base 64 encoded SaltString + * + * @param a 22 character Bcrypt base 64 encoded String + * @return the 16 byte salt + * @exception DataLengthException if the length + * of parameter is not 22 + * @exception InvalidArgumentException if the parameter + * contains a value other than from Bcrypts base 64 encoding table + */ + private static byte[] DecodeSaltString(string saltString) + { + char[] saltChars = saltString.ToCharArray(); + + MemoryStream mOut = new MemoryStream(16); + byte b1, b2, b3, b4; + + if (saltChars.Length != 22)// bcrypt salt must be 22 (16 bytes) + throw new DataLengthException("Invalid base64 salt length: " + saltChars.Length + " , 22 required."); + + // check string for invalid characters: + for (int i = 0; i < saltChars.Length; i++) + { + int value = saltChars[i]; + if (value > 122 || value < 46 || (value > 57 && value < 65)) + throw new ArgumentException("Salt string contains invalid character: " + value, "saltString"); + } + + // Padding: add two '\u0000' + char[] tmp = new char[22 + 2]; + Array.Copy(saltChars, 0, tmp, 0, saltChars.Length); + saltChars = tmp; + + int len = saltChars.Length; + + for (int i = 0; i < len; i += 4) + { + b1 = DecodingTable[saltChars[i]]; + b2 = DecodingTable[saltChars[i + 1]]; + b3 = DecodingTable[saltChars[i + 2]]; + b4 = DecodingTable[saltChars[i + 3]]; + + mOut.WriteByte((byte)((b1 << 2) | (b2 >> 4))); + mOut.WriteByte((byte)((b2 << 4) | (b3 >> 2))); + mOut.WriteByte((byte)((b3 << 6) | b4)); + } + + byte[] saltBytes = mOut.ToArray(); + + // truncate: + byte[] tmpSalt = new byte[16]; + Array.Copy(saltBytes, 0, tmpSalt, 0, tmpSalt.Length); + saltBytes = tmpSalt; + + return saltBytes; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/OpenBsdBCrypt.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/OpenBsdBCrypt.cs.meta new file mode 100644 index 0000000..b781ab9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/OpenBsdBCrypt.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a880128e38df5bd4c90357267222fdc2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/OpenSSLPBEParametersGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/OpenSSLPBEParametersGenerator.cs new file mode 100644 index 0000000..1b77d34 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/OpenSSLPBEParametersGenerator.cs @@ -0,0 +1,183 @@ +using System; + +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Generators +{ + /// + /// + /// + /// Generator for PBE derived keys and ivs as usd by OpenSSL. + ///

+ /// Originally this scheme was a simple extension of PKCS 5 V2.0 Scheme 1 using MD5 with an + /// iteration count of 1. The default digest was changed to SHA-256 with OpenSSL 1.1.0. This + /// implementation still defaults to MD5, but the digest can now be set. + /// + /// + public class OpenSslPbeParametersGenerator + : PbeParametersGenerator + { + private readonly IDigest digest; + + /// + /// + /// Construct a OpenSSL Parameters generator - digest the original MD5. + /// + /// + public OpenSslPbeParametersGenerator() : this(new MD5Digest()) + { + } + + /// + /// + /// Construct a OpenSSL Parameters generator - digest as specified. + /// + /// the digest to use as the PRF. + /// + public OpenSslPbeParametersGenerator(IDigest digest) + { + this.digest = digest; + } + + public override void Init( + byte[] password, + byte[] salt, + int iterationCount) + { + // Ignore the provided iterationCount + base.Init(password, salt, 1); + } + + /** + * Initialise - note the iteration count for this algorithm is fixed at 1. + * + * @param password password to use. + * @param salt salt to use. + */ + public virtual void Init( + byte[] password, + byte[] salt) + { + base.Init(password, salt, 1); + } + + /** + * the derived key function, the ith hash of the password and the salt. + */ + private byte[] GenerateDerivedKey( + int bytesNeeded) + { + byte[] buf = new byte[digest.GetDigestSize()]; + byte[] key = new byte[bytesNeeded]; + int offset = 0; + + for (;;) + { + digest.BlockUpdate(mPassword, 0, mPassword.Length); + digest.BlockUpdate(mSalt, 0, mSalt.Length); + + digest.DoFinal(buf, 0); + + int len = (bytesNeeded > buf.Length) ? buf.Length : bytesNeeded; + Array.Copy(buf, 0, key, offset, len); + offset += len; + + // check if we need any more + bytesNeeded -= len; + if (bytesNeeded == 0) + { + break; + } + + // do another round + digest.Reset(); + digest.BlockUpdate(buf, 0, buf.Length); + } + + return key; + } + + /** + * Generate a key parameter derived from the password, salt, and iteration + * count we are currently initialised with. + * + * @param keySize the size of the key we want (in bits) + * @return a KeyParameter object. + * @exception ArgumentException if the key length larger than the base hash size. + */ + [Obsolete("Use version with 'algorithm' parameter")] + public override ICipherParameters GenerateDerivedParameters( + int keySize) + { + return GenerateDerivedMacParameters(keySize); + } + + public override ICipherParameters GenerateDerivedParameters( + string algorithm, + int keySize) + { + keySize /= 8; + + byte[] dKey = GenerateDerivedKey(keySize); + + return ParameterUtilities.CreateKeyParameter(algorithm, dKey, 0, keySize); + } + + /** + * Generate a key with initialisation vector parameter derived from + * the password, salt, and iteration count we are currently initialised + * with. + * + * @param keySize the size of the key we want (in bits) + * @param ivSize the size of the iv we want (in bits) + * @return a ParametersWithIV object. + * @exception ArgumentException if keySize + ivSize is larger than the base hash size. + */ + [Obsolete("Use version with 'algorithm' parameter")] + public override ICipherParameters GenerateDerivedParameters( + int keySize, + int ivSize) + { + keySize = keySize / 8; + ivSize = ivSize / 8; + + byte[] dKey = GenerateDerivedKey(keySize + ivSize); + + return new ParametersWithIV(new KeyParameter(dKey, 0, keySize), dKey, keySize, ivSize); + } + + public override ICipherParameters GenerateDerivedParameters( + string algorithm, + int keySize, + int ivSize) + { + keySize /= 8; + ivSize /= 8; + + byte[] dKey = GenerateDerivedKey(keySize + ivSize); + KeyParameter key = ParameterUtilities.CreateKeyParameter(algorithm, dKey, 0, keySize); + + return new ParametersWithIV(key, dKey, keySize, ivSize); + } + + /** + * Generate a key parameter for use with a MAC derived from the password, + * salt, and iteration count we are currently initialised with. + * + * @param keySize the size of the key we want (in bits) + * @return a KeyParameter object. + * @exception ArgumentException if the key length larger than the base hash size. + */ + public override ICipherParameters GenerateDerivedMacParameters( + int keySize) + { + keySize = keySize / 8; + + byte[] dKey = GenerateDerivedKey(keySize); + + return new KeyParameter(dKey, 0, keySize); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/OpenSSLPBEParametersGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/OpenSSLPBEParametersGenerator.cs.meta new file mode 100644 index 0000000..80bffc8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/OpenSSLPBEParametersGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 58f22eaf2a22fb041a4bacd188259adf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Pkcs12ParametersGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Pkcs12ParametersGenerator.cs new file mode 100644 index 0000000..85543a0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Pkcs12ParametersGenerator.cs @@ -0,0 +1,243 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Generators +{ + /** + * Generator for Pbe derived keys and ivs as defined by Pkcs 12 V1.0. + *

+ * The document this implementation is based on can be found at + * + * RSA's Pkcs12 Page + *

+ */ + public class Pkcs12ParametersGenerator + : PbeParametersGenerator + { + public const int KeyMaterial = 1; + public const int IVMaterial = 2; + public const int MacMaterial = 3; + + private readonly IDigest digest; + + private readonly int u; + private readonly int v; + + /** + * Construct a Pkcs 12 Parameters generator. + * + * @param digest the digest to be used as the source of derived keys. + * @exception ArgumentException if an unknown digest is passed in. + */ + public Pkcs12ParametersGenerator( + IDigest digest) + { + this.digest = digest; + + u = digest.GetDigestSize(); + v = digest.GetByteLength(); + } + + /** + * add a + b + 1, returning the result in a. The a value is treated + * as a BigInteger of length (b.Length * 8) bits. The result is + * modulo 2^b.Length in case of overflow. + */ + private void Adjust( + byte[] a, + int aOff, + byte[] b) + { + int x = (b[b.Length - 1] & 0xff) + (a[aOff + b.Length - 1] & 0xff) + 1; + + a[aOff + b.Length - 1] = (byte)x; + x = (int) ((uint) x >> 8); + + for (int i = b.Length - 2; i >= 0; i--) + { + x += (b[i] & 0xff) + (a[aOff + i] & 0xff); + a[aOff + i] = (byte)x; + x = (int) ((uint) x >> 8); + } + } + + /** + * generation of a derived key ala Pkcs12 V1.0. + */ + private byte[] GenerateDerivedKey( + int idByte, + int n) + { + byte[] D = new byte[v]; + byte[] dKey = new byte[n]; + + for (int i = 0; i != D.Length; i++) + { + D[i] = (byte)idByte; + } + + byte[] S; + + if ((mSalt != null) && (mSalt.Length != 0)) + { + S = new byte[v * ((mSalt.Length + v - 1) / v)]; + + for (int i = 0; i != S.Length; i++) + { + S[i] = mSalt[i % mSalt.Length]; + } + } + else + { + S = new byte[0]; + } + + byte[] P; + + if ((mPassword != null) && (mPassword.Length != 0)) + { + P = new byte[v * ((mPassword.Length + v - 1) / v)]; + + for (int i = 0; i != P.Length; i++) + { + P[i] = mPassword[i % mPassword.Length]; + } + } + else + { + P = new byte[0]; + } + + byte[] I = new byte[S.Length + P.Length]; + + Array.Copy(S, 0, I, 0, S.Length); + Array.Copy(P, 0, I, S.Length, P.Length); + + byte[] B = new byte[v]; + int c = (n + u - 1) / u; + byte[] A = new byte[u]; + + for (int i = 1; i <= c; i++) + { + digest.BlockUpdate(D, 0, D.Length); + digest.BlockUpdate(I, 0, I.Length); + digest.DoFinal(A, 0); + + for (int j = 1; j != mIterationCount; j++) + { + digest.BlockUpdate(A, 0, A.Length); + digest.DoFinal(A, 0); + } + + for (int j = 0; j != B.Length; j++) + { + B[j] = A[j % A.Length]; + } + + for (int j = 0; j != I.Length / v; j++) + { + Adjust(I, j * v, B); + } + + if (i == c) + { + Array.Copy(A, 0, dKey, (i - 1) * u, dKey.Length - ((i - 1) * u)); + } + else + { + Array.Copy(A, 0, dKey, (i - 1) * u, A.Length); + } + } + + return dKey; + } + + /** + * Generate a key parameter derived from the password, salt, and iteration + * count we are currently initialised with. + * + * @param keySize the size of the key we want (in bits) + * @return a KeyParameter object. + */ + public override ICipherParameters GenerateDerivedParameters( + int keySize) + { + keySize /= 8; + + byte[] dKey = GenerateDerivedKey(KeyMaterial, keySize); + + return new KeyParameter(dKey, 0, keySize); + } + + public override ICipherParameters GenerateDerivedParameters( + string algorithm, + int keySize) + { + keySize /= 8; + + byte[] dKey = GenerateDerivedKey(KeyMaterial, keySize); + + return ParameterUtilities.CreateKeyParameter(algorithm, dKey, 0, keySize); + } + + /** + * Generate a key with initialisation vector parameter derived from + * the password, salt, and iteration count we are currently initialised + * with. + * + * @param keySize the size of the key we want (in bits) + * @param ivSize the size of the iv we want (in bits) + * @return a ParametersWithIV object. + */ + public override ICipherParameters GenerateDerivedParameters( + int keySize, + int ivSize) + { + keySize /= 8; + ivSize /= 8; + + byte[] dKey = GenerateDerivedKey(KeyMaterial, keySize); + + byte[] iv = GenerateDerivedKey(IVMaterial, ivSize); + + return new ParametersWithIV(new KeyParameter(dKey, 0, keySize), iv, 0, ivSize); + } + + public override ICipherParameters GenerateDerivedParameters( + string algorithm, + int keySize, + int ivSize) + { + keySize /= 8; + ivSize /= 8; + + byte[] dKey = GenerateDerivedKey(KeyMaterial, keySize); + KeyParameter key = ParameterUtilities.CreateKeyParameter(algorithm, dKey, 0, keySize); + + byte[] iv = GenerateDerivedKey(IVMaterial, ivSize); + + return new ParametersWithIV(key, iv, 0, ivSize); + } + + /** + * Generate a key parameter for use with a MAC derived from the password, + * salt, and iteration count we are currently initialised with. + * + * @param keySize the size of the key we want (in bits) + * @return a KeyParameter object. + */ + public override ICipherParameters GenerateDerivedMacParameters( + int keySize) + { + keySize /= 8; + + byte[] dKey = GenerateDerivedKey(MacMaterial, keySize); + + return new KeyParameter(dKey, 0, keySize); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Pkcs12ParametersGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Pkcs12ParametersGenerator.cs.meta new file mode 100644 index 0000000..5710977 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Pkcs12ParametersGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0327861b20e96214c85ff0e0a4197975 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Pkcs5S1ParametersGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Pkcs5S1ParametersGenerator.cs new file mode 100644 index 0000000..9b39a5f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Pkcs5S1ParametersGenerator.cs @@ -0,0 +1,160 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Generators +{ + /** + * Generator for Pbe derived keys and ivs as defined by Pkcs 5 V2.0 Scheme 1. + * Note this generator is limited to the size of the hash produced by the + * digest used to drive it. + *

+ * The document this implementation is based on can be found at + * + * RSA's Pkcs5 Page + *

+ */ + public class Pkcs5S1ParametersGenerator + : PbeParametersGenerator + { + private readonly IDigest digest; + + /** + * Construct a Pkcs 5 Scheme 1 Parameters generator. + * + * @param digest the digest to be used as the source of derived keys. + */ + public Pkcs5S1ParametersGenerator( + IDigest digest) + { + this.digest = digest; + } + + /** + * the derived key function, the ith hash of the mPassword and the mSalt. + */ + private byte[] GenerateDerivedKey() + { + byte[] digestBytes = new byte[digest.GetDigestSize()]; + + digest.BlockUpdate(mPassword, 0, mPassword.Length); + digest.BlockUpdate(mSalt, 0, mSalt.Length); + + digest.DoFinal(digestBytes, 0); + for (int i = 1; i < mIterationCount; i++) + { + digest.BlockUpdate(digestBytes, 0, digestBytes.Length); + digest.DoFinal(digestBytes, 0); + } + + return digestBytes; + } + + /** + * Generate a key parameter derived from the mPassword, mSalt, and iteration + * count we are currently initialised with. + * + * @param keySize the size of the key we want (in bits) + * @return a KeyParameter object. + * @exception ArgumentException if the key length larger than the base hash size. + */ + public override ICipherParameters GenerateDerivedParameters( + int keySize) + { + return GenerateDerivedMacParameters(keySize); + } + + public override ICipherParameters GenerateDerivedParameters( + string algorithm, + int keySize) + { + keySize /= 8; + + if (keySize > digest.GetDigestSize()) + { + throw new ArgumentException( + "Can't Generate a derived key " + keySize + " bytes long."); + } + + byte[] dKey = GenerateDerivedKey(); + + return ParameterUtilities.CreateKeyParameter(algorithm, dKey, 0, keySize); + } + + /** + * Generate a key with initialisation vector parameter derived from + * the mPassword, mSalt, and iteration count we are currently initialised + * with. + * + * @param keySize the size of the key we want (in bits) + * @param ivSize the size of the iv we want (in bits) + * @return a ParametersWithIV object. + * @exception ArgumentException if keySize + ivSize is larger than the base hash size. + */ + public override ICipherParameters GenerateDerivedParameters( + int keySize, + int ivSize) + { + keySize /= 8; + ivSize /= 8; + + if ((keySize + ivSize) > digest.GetDigestSize()) + { + throw new ArgumentException( + "Can't Generate a derived key " + (keySize + ivSize) + " bytes long."); + } + + byte[] dKey = GenerateDerivedKey(); + + return new ParametersWithIV(new KeyParameter(dKey, 0, keySize), dKey, keySize, ivSize); + } + + public override ICipherParameters GenerateDerivedParameters( + string algorithm, + int keySize, + int ivSize) + { + keySize /= 8; + ivSize /= 8; + + if ((keySize + ivSize) > digest.GetDigestSize()) + { + throw new ArgumentException( + "Can't Generate a derived key " + (keySize + ivSize) + " bytes long."); + } + + byte[] dKey = GenerateDerivedKey(); + KeyParameter key = ParameterUtilities.CreateKeyParameter(algorithm, dKey, 0, keySize); + + return new ParametersWithIV(key, dKey, keySize, ivSize); + } + + /** + * Generate a key parameter for use with a MAC derived from the mPassword, + * mSalt, and iteration count we are currently initialised with. + * + * @param keySize the size of the key we want (in bits) + * @return a KeyParameter object. + * @exception ArgumentException if the key length larger than the base hash size. + */ + public override ICipherParameters GenerateDerivedMacParameters( + int keySize) + { + keySize /= 8; + + if (keySize > digest.GetDigestSize()) + { + throw new ArgumentException( + "Can't Generate a derived key " + keySize + " bytes long."); + } + + byte[] dKey = GenerateDerivedKey(); + + return new KeyParameter(dKey, 0, keySize); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Pkcs5S1ParametersGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Pkcs5S1ParametersGenerator.cs.meta new file mode 100644 index 0000000..31fc0b2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Pkcs5S1ParametersGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6d09135ff4769404bb431d27610db8c3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Pkcs5S2ParametersGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Pkcs5S2ParametersGenerator.cs new file mode 100644 index 0000000..0b0caa0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Pkcs5S2ParametersGenerator.cs @@ -0,0 +1,178 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Macs; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Generators +{ + /** + * Generator for Pbe derived keys and ivs as defined by Pkcs 5 V2.0 Scheme 2. + * This generator uses a SHA-1 HMac as the calculation function. + *

+ * The document this implementation is based on can be found at + * + * RSA's Pkcs5 Page

+ */ + public class Pkcs5S2ParametersGenerator + : PbeParametersGenerator + { + private readonly IMac hMac; + private readonly byte[] state; + + /** + * construct a Pkcs5 Scheme 2 Parameters generator. + */ + public Pkcs5S2ParametersGenerator() + : this(new Sha1Digest()) + { + } + + public Pkcs5S2ParametersGenerator(IDigest digest) + { + this.hMac = new HMac(digest); + this.state = new byte[hMac.GetMacSize()]; + } + + private void F( + byte[] S, + int c, + byte[] iBuf, + byte[] outBytes, + int outOff) + { + if (c == 0) + throw new ArgumentException("iteration count must be at least 1."); + + if (S != null) + { + hMac.BlockUpdate(S, 0, S.Length); + } + + hMac.BlockUpdate(iBuf, 0, iBuf.Length); + hMac.DoFinal(state, 0); + + Array.Copy(state, 0, outBytes, outOff, state.Length); + + for (int count = 1; count < c; ++count) + { + hMac.BlockUpdate(state, 0, state.Length); + hMac.DoFinal(state, 0); + + for (int j = 0; j < state.Length; ++j) + { + outBytes[outOff + j] ^= state[j]; + } + } + } + + private byte[] GenerateDerivedKey( + int dkLen) + { + int hLen = hMac.GetMacSize(); + int l = (dkLen + hLen - 1) / hLen; + byte[] iBuf = new byte[4]; + byte[] outBytes = new byte[l * hLen]; + int outPos = 0; + + ICipherParameters param = new KeyParameter(mPassword); + + hMac.Init(param); + + for (int i = 1; i <= l; i++) + { + // Increment the value in 'iBuf' + int pos = 3; + while (++iBuf[pos] == 0) + { + --pos; + } + + F(mSalt, mIterationCount, iBuf, outBytes, outPos); + outPos += hLen; + } + + return outBytes; + } + + /** + * Generate a key parameter derived from the password, salt, and iteration + * count we are currently initialised with. + * + * @param keySize the size of the key we want (in bits) + * @return a KeyParameter object. + */ + public override ICipherParameters GenerateDerivedParameters( + int keySize) + { + return GenerateDerivedMacParameters(keySize); + } + + public override ICipherParameters GenerateDerivedParameters( + string algorithm, + int keySize) + { + keySize /= 8; + + byte[] dKey = GenerateDerivedKey(keySize); + + return ParameterUtilities.CreateKeyParameter(algorithm, dKey, 0, keySize); + } + + /** + * Generate a key with initialisation vector parameter derived from + * the password, salt, and iteration count we are currently initialised + * with. + * + * @param keySize the size of the key we want (in bits) + * @param ivSize the size of the iv we want (in bits) + * @return a ParametersWithIV object. + */ + public override ICipherParameters GenerateDerivedParameters( + int keySize, + int ivSize) + { + keySize /= 8; + ivSize /= 8; + + byte[] dKey = GenerateDerivedKey(keySize + ivSize); + + return new ParametersWithIV(new KeyParameter(dKey, 0, keySize), dKey, keySize, ivSize); + } + + public override ICipherParameters GenerateDerivedParameters( + string algorithm, + int keySize, + int ivSize) + { + keySize /= 8; + ivSize /= 8; + + byte[] dKey = GenerateDerivedKey(keySize + ivSize); + KeyParameter key = ParameterUtilities.CreateKeyParameter(algorithm, dKey, 0, keySize); + + return new ParametersWithIV(key, dKey, keySize, ivSize); + } + + /** + * Generate a key parameter for use with a MAC derived from the password, + * salt, and iteration count we are currently initialised with. + * + * @param keySize the size of the key we want (in bits) + * @return a KeyParameter object. + */ + public override ICipherParameters GenerateDerivedMacParameters( + int keySize) + { + keySize /= 8; + + byte[] dKey = GenerateDerivedKey(keySize); + + return new KeyParameter(dKey, 0, keySize); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Pkcs5S2ParametersGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Pkcs5S2ParametersGenerator.cs.meta new file mode 100644 index 0000000..a1f1f63 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Pkcs5S2ParametersGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 526b4710e27db68419aeae24b80fe0b0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Poly1305KeyGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Poly1305KeyGenerator.cs new file mode 100644 index 0000000..cdb24bf --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Poly1305KeyGenerator.cs @@ -0,0 +1,116 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Macs; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Generators +{ + /// + /// Generates keys for the Poly1305 MAC. + /// + /// + /// Poly1305 keys are 256 bit keys consisting of a 128 bit secret key used for the underlying block + /// cipher followed by a 128 bit {@code r} value used for the polynomial portion of the Mac.
+ /// The {@code r} value has a specific format with some bits required to be cleared, resulting in an + /// effective 106 bit key.
+ /// A separately generated 256 bit key can be modified to fit the Poly1305 key format by using the + /// {@link #clamp(byte[])} method to clear the required bits. + ///
+ /// + public class Poly1305KeyGenerator + : CipherKeyGenerator + { + private const byte R_MASK_LOW_2 = (byte)0xFC; + private const byte R_MASK_HIGH_4 = (byte)0x0F; + + /// + /// Initialises the key generator. + /// + /// + /// Poly1305 keys are always 256 bits, so the key length in the provided parameters is ignored. + /// + protected override void engineInit(KeyGenerationParameters param) + { + // Poly1305 keys are always 256 bits + this.random = param.Random; + this.strength = 32; + } + + /// + /// Generates a 256 bit key in the format required for Poly1305 - e.g. + /// k[0] ... k[15], r[0] ... r[15] with the required bits in r cleared + /// as per . + /// + protected override byte[] engineGenerateKey() + { + byte[] key = base.engineGenerateKey(); + Clamp(key); + return key; + } + + /// + /// Modifies an existing 32 byte key value to comply with the requirements of the Poly1305 key by + /// clearing required bits in the r (second 16 bytes) portion of the key.
+ /// Specifically: + ///
    + ///
  • r[3], r[7], r[11], r[15] have top four bits clear (i.e., are {0, 1, . . . , 15})
  • + ///
  • r[4], r[8], r[12] have bottom two bits clear (i.e., are in {0, 4, 8, . . . , 252})
  • + ///
+ ///
+ /// a 32 byte key value k[0] ... k[15], r[0] ... r[15] + public static void Clamp(byte[] key) + { + /* + * Key is k[0] ... k[15], r[0] ... r[15] as per poly1305_aes_clamp in ref impl. + */ + if (key.Length != 32) + throw new ArgumentException("Poly1305 key must be 256 bits."); + + /* + * r[3], r[7], r[11], r[15] have top four bits clear (i.e., are {0, 1, . . . , 15}) + */ + key[3] &= R_MASK_HIGH_4; + key[7] &= R_MASK_HIGH_4; + key[11] &= R_MASK_HIGH_4; + key[15] &= R_MASK_HIGH_4; + + /* + * r[4], r[8], r[12] have bottom two bits clear (i.e., are in {0, 4, 8, . . . , 252}). + */ + key[4] &= R_MASK_LOW_2; + key[8] &= R_MASK_LOW_2; + key[12] &= R_MASK_LOW_2; + } + + /// + /// Checks a 32 byte key for compliance with the Poly1305 key requirements, e.g. + /// k[0] ... k[15], r[0] ... r[15] with the required bits in r cleared + /// as per . + /// + /// Key. + /// if the key is of the wrong length, or has invalid bits set + /// in the r portion of the key. + public static void CheckKey(byte[] key) + { + if (key.Length != 32) + throw new ArgumentException("Poly1305 key must be 256 bits."); + + CheckMask(key[3], R_MASK_HIGH_4); + CheckMask(key[7], R_MASK_HIGH_4); + CheckMask(key[11], R_MASK_HIGH_4); + CheckMask(key[15], R_MASK_HIGH_4); + + CheckMask(key[4], R_MASK_LOW_2); + CheckMask(key[8], R_MASK_LOW_2); + CheckMask(key[12], R_MASK_LOW_2); + } + + private static void CheckMask(byte b, byte mask) + { + if ((b & (~mask)) != 0) + throw new ArgumentException("Invalid format for r portion of Poly1305 key."); + } + } +} \ No newline at end of file diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Poly1305KeyGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Poly1305KeyGenerator.cs.meta new file mode 100644 index 0000000..d44a869 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/Poly1305KeyGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 63e21f1bae9796c4e85c2bced1809eac +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/RSABlindingFactorGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/RSABlindingFactorGenerator.cs new file mode 100644 index 0000000..e2f63fa --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/RSABlindingFactorGenerator.cs @@ -0,0 +1,69 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Generators +{ + /** + * Generate a random factor suitable for use with RSA blind signatures + * as outlined in Chaum's blinding and unblinding as outlined in + * "Handbook of Applied Cryptography", page 475. + */ + public class RsaBlindingFactorGenerator + { + private RsaKeyParameters key; + private SecureRandom random; + + /** + * Initialise the factor generator + * + * @param param the necessary RSA key parameters. + */ + public void Init( + ICipherParameters param) + { + if (param is ParametersWithRandom) + { + ParametersWithRandom rParam = (ParametersWithRandom)param; + + key = (RsaKeyParameters)rParam.Parameters; + random = rParam.Random; + } + else + { + key = (RsaKeyParameters)param; + random = new SecureRandom(); + } + + if (key.IsPrivate) + throw new ArgumentException("generator requires RSA public key"); + } + + /** + * Generate a suitable blind factor for the public key the generator was initialised with. + * + * @return a random blind factor + */ + public BigInteger GenerateBlindingFactor() + { + if (key == null) + throw new InvalidOperationException("generator not initialised"); + + BigInteger m = key.Modulus; + int length = m.BitLength - 1; // must be less than m.BitLength + BigInteger factor; + BigInteger gcd; + + do + { + factor = new BigInteger(length, random); + gcd = factor.Gcd(m); + } + while (factor.SignValue == 0 || factor.Equals(BigInteger.One) || !gcd.Equals(BigInteger.One)); + + return factor; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/RSABlindingFactorGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/RSABlindingFactorGenerator.cs.meta new file mode 100644 index 0000000..fa587b6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/RSABlindingFactorGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c95b8a76be90e4f4c9cf76484267db06 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/RsaKeyPairGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/RsaKeyPairGenerator.cs new file mode 100644 index 0000000..78c9eb1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/RsaKeyPairGenerator.cs @@ -0,0 +1,163 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC.Multiplier; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Generators +{ + /** + * an RSA key pair generator. + */ + public class RsaKeyPairGenerator + : IAsymmetricCipherKeyPairGenerator + { + private static readonly int[] SPECIAL_E_VALUES = new int[]{ 3, 5, 17, 257, 65537 }; + private static readonly int SPECIAL_E_HIGHEST = SPECIAL_E_VALUES[SPECIAL_E_VALUES.Length - 1]; + private static readonly int SPECIAL_E_BITS = BigInteger.ValueOf(SPECIAL_E_HIGHEST).BitLength; + + protected static readonly BigInteger One = BigInteger.One; + protected static readonly BigInteger DefaultPublicExponent = BigInteger.ValueOf(0x10001); + protected const int DefaultTests = 100; + + protected RsaKeyGenerationParameters parameters; + + public virtual void Init( + KeyGenerationParameters parameters) + { + if (parameters is RsaKeyGenerationParameters) + { + this.parameters = (RsaKeyGenerationParameters)parameters; + } + else + { + this.parameters = new RsaKeyGenerationParameters( + DefaultPublicExponent, parameters.Random, parameters.Strength, DefaultTests); + } + } + + public virtual AsymmetricCipherKeyPair GenerateKeyPair() + { + for (;;) + { + // + // p and q values should have a length of half the strength in bits + // + int strength = parameters.Strength; + int pBitlength = (strength + 1) / 2; + int qBitlength = strength - pBitlength; + int mindiffbits = strength / 3; + int minWeight = strength >> 2; + + BigInteger e = parameters.PublicExponent; + + // TODO Consider generating safe primes for p, q (see DHParametersHelper.generateSafePrimes) + // (then p-1 and q-1 will not consist of only small factors - see "Pollard's algorithm") + + BigInteger p = ChooseRandomPrime(pBitlength, e); + BigInteger q, n; + + // + // generate a modulus of the required length + // + for (;;) + { + q = ChooseRandomPrime(qBitlength, e); + + // p and q should not be too close together (or equal!) + BigInteger diff = q.Subtract(p).Abs(); + if (diff.BitLength < mindiffbits) + continue; + + // + // calculate the modulus + // + n = p.Multiply(q); + + if (n.BitLength != strength) + { + // + // if we get here our primes aren't big enough, make the largest + // of the two p and try again + // + p = p.Max(q); + continue; + } + + /* + * Require a minimum weight of the NAF representation, since low-weight composites may + * be weak against a version of the number-field-sieve for factoring. + * + * See "The number field sieve for integers of low weight", Oliver Schirokauer. + */ + if (WNafUtilities.GetNafWeight(n) < minWeight) + { + p = ChooseRandomPrime(pBitlength, e); + continue; + } + + break; + } + + if (p.CompareTo(q) < 0) + { + BigInteger tmp = p; + p = q; + q = tmp; + } + + BigInteger pSub1 = p.Subtract(One); + BigInteger qSub1 = q.Subtract(One); + //BigInteger phi = pSub1.Multiply(qSub1); + BigInteger gcd = pSub1.Gcd(qSub1); + BigInteger lcm = pSub1.Divide(gcd).Multiply(qSub1); + + // + // calculate the private exponent + // + BigInteger d = e.ModInverse(lcm); + + if (d.BitLength <= qBitlength) + continue; + + // + // calculate the CRT factors + // + BigInteger dP = d.Remainder(pSub1); + BigInteger dQ = d.Remainder(qSub1); + BigInteger qInv = BigIntegers.ModOddInverse(p, q); + + return new AsymmetricCipherKeyPair( + new RsaKeyParameters(false, n, e), + new RsaPrivateCrtKeyParameters(n, e, d, p, q, dP, dQ, qInv)); + } + } + + /// Choose a random prime value for use with RSA + /// the bit-length of the returned prime + /// the RSA public exponent + /// a prime p, with (p-1) relatively prime to e + protected virtual BigInteger ChooseRandomPrime(int bitlength, BigInteger e) + { + bool eIsKnownOddPrime = (e.BitLength <= SPECIAL_E_BITS) && Arrays.Contains(SPECIAL_E_VALUES, e.IntValue); + + for (;;) + { + BigInteger p = new BigInteger(bitlength, 1, parameters.Random); + + if (p.Mod(e).Equals(One)) + continue; + + if (!p.IsProbablePrime(parameters.Certainty, true)) + continue; + + if (!eIsKnownOddPrime && !e.Gcd(p.Subtract(One)).Equals(One)) + continue; + + return p; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/RsaKeyPairGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/RsaKeyPairGenerator.cs.meta new file mode 100644 index 0000000..e849ec7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/RsaKeyPairGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 76edd4ad9815db74d889e8133afa2372 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/SCrypt.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/SCrypt.cs new file mode 100644 index 0000000..0753820 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/SCrypt.cs @@ -0,0 +1,210 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Generators +{ + /// Implementation of the scrypt a password-based key derivation function. + /// + /// Scrypt was created by Colin Percival and is specified in + /// draft-josefsson-scrypt-kd. + /// + public class SCrypt + { + /// Generate a key using the scrypt key derivation function. + /// the bytes of the pass phrase. + /// the salt to use for this invocation. + /// CPU/Memory cost parameter. Must be larger than 1, a power of 2 and less than + /// 2^(128 * r / 8). + /// the block size, must be >= 1. + /// Parallelization parameter. Must be a positive integer less than or equal to + /// Int32.MaxValue / (128 * r * 8). + /// the length of the key to generate. + /// the generated key. + public static byte[] Generate(byte[] P, byte[] S, int N, int r, int p, int dkLen) + { + if (P == null) + throw new ArgumentNullException("Passphrase P must be provided."); + if (S == null) + throw new ArgumentNullException("Salt S must be provided."); + if (N <= 1 || !IsPowerOf2(N)) + throw new ArgumentException("Cost parameter N must be > 1 and a power of 2."); + // Only value of r that cost (as an int) could be exceeded for is 1 + if (r == 1 && N >= 65536) + throw new ArgumentException("Cost parameter N must be > 1 and < 65536."); + if (r < 1) + throw new ArgumentException("Block size r must be >= 1."); + int maxParallel = Int32.MaxValue / (128 * r * 8); + if (p < 1 || p > maxParallel) + { + throw new ArgumentException("Parallelisation parameter p must be >= 1 and <= " + maxParallel + + " (based on block size r of " + r + ")"); + } + if (dkLen < 1) + throw new ArgumentException("Generated key length dkLen must be >= 1."); + + return MFcrypt(P, S, N, r, p, dkLen); + } + + private static byte[] MFcrypt(byte[] P, byte[] S, int N, int r, int p, int dkLen) + { + int MFLenBytes = r * 128; + byte[] bytes = SingleIterationPBKDF2(P, S, p * MFLenBytes); + + uint[] B = null; + + try + { + int BLen = bytes.Length >> 2; + B = new uint[BLen]; + + Pack.LE_To_UInt32(bytes, 0, B); + + /* + * Chunk memory allocations; We choose 'd' so that there will be 2**d chunks, each not + * larger than 32KiB, except that the minimum chunk size is 2 * r * 32. + */ + int d = 0, total = N * r; + while ((N - d) > 2 && total > (1 << 10)) + { + ++d; + total >>= 1; + } + + int MFLenWords = MFLenBytes >> 2; + for (int BOff = 0; BOff < BLen; BOff += MFLenWords) + { + // TODO These can be done in parallel threads + SMix(B, BOff, N, d, r); + } + + Pack.UInt32_To_LE(B, bytes, 0); + + return SingleIterationPBKDF2(P, bytes, dkLen); + } + finally + { + ClearAll(bytes, B); + } + } + + private static byte[] SingleIterationPBKDF2(byte[] P, byte[] S, int dkLen) + { + PbeParametersGenerator pGen = new Pkcs5S2ParametersGenerator(new Sha256Digest()); + pGen.Init(P, S, 1); + KeyParameter key = (KeyParameter)pGen.GenerateDerivedMacParameters(dkLen * 8); + return key.GetKey(); + } + + private static void SMix(uint[] B, int BOff, int N, int d, int r) + { + int powN = Integers.NumberOfTrailingZeros(N); + int blocksPerChunk = N >> d; + int chunkCount = 1 << d, chunkMask = blocksPerChunk - 1, chunkPow = powN - d; + + int BCount = r * 32; + + uint[] blockX1 = new uint[16]; + uint[] blockX2 = new uint[16]; + uint[] blockY = new uint[BCount]; + + uint[] X = new uint[BCount]; + uint[][] VV = new uint[chunkCount][]; + + try + { + Array.Copy(B, BOff, X, 0, BCount); + + for (int c = 0; c < chunkCount; ++c) + { + uint[] V = new uint[blocksPerChunk * BCount]; + VV[c] = V; + + int off = 0; + for (int i = 0; i < blocksPerChunk; i += 2) + { + Array.Copy(X, 0, V, off, BCount); + off += BCount; + BlockMix(X, blockX1, blockX2, blockY, r); + Array.Copy(blockY, 0, V, off, BCount); + off += BCount; + BlockMix(blockY, blockX1, blockX2, X, r); + } + } + + uint mask = (uint)N - 1; + for (int i = 0; i < N; ++i) + { + int j = (int)(X[BCount - 16] & mask); + uint[] V = VV[j >> chunkPow]; + int VOff = (j & chunkMask) * BCount; + Array.Copy(V, VOff, blockY, 0, BCount); + Xor(blockY, X, 0, blockY); + BlockMix(blockY, blockX1, blockX2, X, r); + } + + Array.Copy(X, 0, B, BOff, BCount); + } + finally + { + ClearAll(VV); + ClearAll(X, blockX1, blockX2, blockY); + } + } + + private static void BlockMix(uint[] B, uint[] X1, uint[] X2, uint[] Y, int r) + { + Array.Copy(B, B.Length - 16, X1, 0, 16); + + int BOff = 0, YOff = 0, halfLen = B.Length >> 1; + + for (int i = 2 * r; i > 0; --i) + { + Xor(X1, B, BOff, X2); + + Salsa20Engine.SalsaCore(8, X2, X1); + Array.Copy(X1, 0, Y, YOff, 16); + + YOff = halfLen + BOff - YOff; + BOff += 16; + } + } + + private static void Xor(uint[] a, uint[] b, int bOff, uint[] output) + { + for (int i = output.Length - 1; i >= 0; --i) + { + output[i] = a[i] ^ b[bOff + i]; + } + } + + private static void Clear(Array array) + { + if (array != null) + { + Array.Clear(array, 0, array.Length); + } + } + + private static void ClearAll(params Array[] arrays) + { + foreach (Array array in arrays) + { + Clear(array); + } + } + + // note: we know X is non-zero + private static bool IsPowerOf2(int x) + { + Debug.Assert(x != 0); + + return (x & (x - 1)) == 0; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/SCrypt.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/SCrypt.cs.meta new file mode 100644 index 0000000..372bc51 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/SCrypt.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d95442b799b27924cb4f955126904626 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/X25519KeyPairGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/X25519KeyPairGenerator.cs new file mode 100644 index 0000000..9437844 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/X25519KeyPairGenerator.cs @@ -0,0 +1,25 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Generators +{ + public class X25519KeyPairGenerator + : IAsymmetricCipherKeyPairGenerator + { + private SecureRandom random; + + public virtual void Init(KeyGenerationParameters parameters) + { + this.random = parameters.Random; + } + + public virtual AsymmetricCipherKeyPair GenerateKeyPair() + { + X25519PrivateKeyParameters privateKey = new X25519PrivateKeyParameters(random); + X25519PublicKeyParameters publicKey = privateKey.GeneratePublicKey(); + return new AsymmetricCipherKeyPair(publicKey, privateKey); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/X25519KeyPairGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/X25519KeyPairGenerator.cs.meta new file mode 100644 index 0000000..33fad67 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/X25519KeyPairGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5204eaca38c0b7644b3f29c72e1809b5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/X448KeyPairGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/X448KeyPairGenerator.cs new file mode 100644 index 0000000..4a203e4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/X448KeyPairGenerator.cs @@ -0,0 +1,25 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Generators +{ + public class X448KeyPairGenerator + : IAsymmetricCipherKeyPairGenerator + { + private SecureRandom random; + + public virtual void Init(KeyGenerationParameters parameters) + { + this.random = parameters.Random; + } + + public virtual AsymmetricCipherKeyPair GenerateKeyPair() + { + X448PrivateKeyParameters privateKey = new X448PrivateKeyParameters(random); + X448PublicKeyParameters publicKey = privateKey.GeneratePublicKey(); + return new AsymmetricCipherKeyPair(publicKey, privateKey); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/X448KeyPairGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/X448KeyPairGenerator.cs.meta new file mode 100644 index 0000000..bdeb4d0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/generators/X448KeyPairGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b83a15977777aa549b5a86983d910679 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/io.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/io.meta new file mode 100644 index 0000000..def304d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/io.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f05989e45f9c0614ca10d56a93b01c66 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/io/CipherStream.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/io/CipherStream.cs new file mode 100644 index 0000000..b5e6830 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/io/CipherStream.cs @@ -0,0 +1,252 @@ +using System; +using System.Diagnostics; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.IO +{ + public class CipherStream + : Stream + { + internal Stream stream; + internal IBufferedCipher inCipher, outCipher; + private byte[] mInBuf; + private int mInPos; + private bool inStreamEnded; + + public CipherStream( + Stream stream, + IBufferedCipher readCipher, + IBufferedCipher writeCipher) + { + this.stream = stream; + + if (readCipher != null) + { + this.inCipher = readCipher; + mInBuf = null; + } + + if (writeCipher != null) + { + this.outCipher = writeCipher; + } + } + + public IBufferedCipher ReadCipher + { + get { return inCipher; } + } + + public IBufferedCipher WriteCipher + { + get { return outCipher; } + } + + public override int ReadByte() + { + if (inCipher == null) + return stream.ReadByte(); + + if (mInBuf == null || mInPos >= mInBuf.Length) + { + if (!FillInBuf()) + return -1; + } + + return mInBuf[mInPos++]; + } + + public override int Read( + byte[] buffer, + int offset, + int count) + { + if (inCipher == null) + return stream.Read(buffer, offset, count); + + int num = 0; + while (num < count) + { + if (mInBuf == null || mInPos >= mInBuf.Length) + { + if (!FillInBuf()) + break; + } + + int numToCopy = System.Math.Min(count - num, mInBuf.Length - mInPos); + Array.Copy(mInBuf, mInPos, buffer, offset + num, numToCopy); + mInPos += numToCopy; + num += numToCopy; + } + + return num; + } + + private bool FillInBuf() + { + if (inStreamEnded) + return false; + + mInPos = 0; + + do + { + mInBuf = ReadAndProcessBlock(); + } + while (!inStreamEnded && mInBuf == null); + + return mInBuf != null; + } + + private byte[] ReadAndProcessBlock() + { + int blockSize = inCipher.GetBlockSize(); + int readSize = (blockSize == 0) ? 256 : blockSize; + + byte[] block = new byte[readSize]; + int numRead = 0; + do + { + int count = stream.Read(block, numRead, block.Length - numRead); + if (count < 1) + { + inStreamEnded = true; + break; + } + numRead += count; + } + while (numRead < block.Length); + + Debug.Assert(inStreamEnded || numRead == block.Length); + + byte[] bytes = inStreamEnded + ? inCipher.DoFinal(block, 0, numRead) + : inCipher.ProcessBytes(block); + + if (bytes != null && bytes.Length == 0) + { + bytes = null; + } + + return bytes; + } + + public override void Write( + byte[] buffer, + int offset, + int count) + { + Debug.Assert(buffer != null); + Debug.Assert(0 <= offset && offset <= buffer.Length); + Debug.Assert(count >= 0); + + int end = offset + count; + + Debug.Assert(0 <= end && end <= buffer.Length); + + if (outCipher == null) + { + stream.Write(buffer, offset, count); + return; + } + + byte[] data = outCipher.ProcessBytes(buffer, offset, count); + if (data != null) + { + stream.Write(data, 0, data.Length); + } + } + + public override void WriteByte( + byte b) + { + if (outCipher == null) + { + stream.WriteByte(b); + return; + } + + byte[] data = outCipher.ProcessByte(b); + if (data != null) + { + stream.Write(data, 0, data.Length); + } + } + + public override bool CanRead + { + get { return stream.CanRead && (inCipher != null); } + } + + public override bool CanWrite + { + get { return stream.CanWrite && (outCipher != null); } + } + + public override bool CanSeek + { + get { return false; } + } + + public sealed override long Length + { + get { throw new NotSupportedException(); } + } + + public sealed override long Position + { + get { throw new NotSupportedException(); } + set { throw new NotSupportedException(); } + } + +#if PORTABLE + protected override void Dispose(bool disposing) + { + if (disposing) + { + if (outCipher != null) + { + byte[] data = outCipher.DoFinal(); + stream.Write(data, 0, data.Length); + stream.Flush(); + } + Platform.Dispose(stream); + } + base.Dispose(disposing); + } +#else + public override void Close() + { + if (outCipher != null) + { + byte[] data = outCipher.DoFinal(); + stream.Write(data, 0, data.Length); + stream.Flush(); + } + Platform.Dispose(stream); + base.Close(); + } +#endif + + public override void Flush() + { + // Note: outCipher.DoFinal is only called during Close() + stream.Flush(); + } + + public sealed override long Seek( + long offset, + SeekOrigin origin) + { + throw new NotSupportedException(); + } + + public sealed override void SetLength( + long length) + { + throw new NotSupportedException(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/io/CipherStream.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/io/CipherStream.cs.meta new file mode 100644 index 0000000..83b3fa4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/io/CipherStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fda049b52c83af446ba673a465211fdb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/io/DigestSink.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/io/DigestSink.cs new file mode 100644 index 0000000..98307e5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/io/DigestSink.cs @@ -0,0 +1,35 @@ +using System; + +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Crypto.IO +{ + public class DigestSink + : BaseOutputStream + { + private readonly IDigest mDigest; + + public DigestSink(IDigest digest) + { + this.mDigest = digest; + } + + public virtual IDigest Digest + { + get { return mDigest; } + } + + public override void WriteByte(byte b) + { + mDigest.Update(b); + } + + public override void Write(byte[] buf, int off, int len) + { + if (len > 0) + { + mDigest.BlockUpdate(buf, off, len); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/io/DigestSink.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/io/DigestSink.cs.meta new file mode 100644 index 0000000..bc01160 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/io/DigestSink.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0e16e471dd2bbca48886cf8505974a71 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/io/DigestStream.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/io/DigestStream.cs new file mode 100644 index 0000000..dce8757 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/io/DigestStream.cs @@ -0,0 +1,151 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.IO +{ + public class DigestStream + : Stream + { + protected readonly Stream stream; + protected readonly IDigest inDigest; + protected readonly IDigest outDigest; + + public DigestStream( + Stream stream, + IDigest readDigest, + IDigest writeDigest) + { + this.stream = stream; + this.inDigest = readDigest; + this.outDigest = writeDigest; + } + + public virtual IDigest ReadDigest() + { + return inDigest; + } + + public virtual IDigest WriteDigest() + { + return outDigest; + } + + public override int Read( + byte[] buffer, + int offset, + int count) + { + int n = stream.Read(buffer, offset, count); + if (inDigest != null) + { + if (n > 0) + { + inDigest.BlockUpdate(buffer, offset, n); + } + } + return n; + } + + public override int ReadByte() + { + int b = stream.ReadByte(); + if (inDigest != null) + { + if (b >= 0) + { + inDigest.Update((byte)b); + } + } + return b; + } + + public override void Write( + byte[] buffer, + int offset, + int count) + { + if (outDigest != null) + { + if (count > 0) + { + outDigest.BlockUpdate(buffer, offset, count); + } + } + stream.Write(buffer, offset, count); + } + + public override void WriteByte( + byte b) + { + if (outDigest != null) + { + outDigest.Update(b); + } + stream.WriteByte(b); + } + + public override bool CanRead + { + get { return stream.CanRead; } + } + + public override bool CanWrite + { + get { return stream.CanWrite; } + } + + public override bool CanSeek + { + get { return stream.CanSeek; } + } + + public override long Length + { + get { return stream.Length; } + } + + public override long Position + { + get { return stream.Position; } + set { stream.Position = value; } + } + +#if PORTABLE + protected override void Dispose(bool disposing) + { + if (disposing) + { + Platform.Dispose(stream); + } + base.Dispose(disposing); + } +#else + public override void Close() + { + Platform.Dispose(stream); + base.Close(); + } +#endif + + public override void Flush() + { + stream.Flush(); + } + + public override long Seek( + long offset, + SeekOrigin origin) + { + return stream.Seek(offset, origin); + } + + public override void SetLength( + long length) + { + stream.SetLength(length); + } + } +} + diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/io/DigestStream.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/io/DigestStream.cs.meta new file mode 100644 index 0000000..c23bdf3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/io/DigestStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a14b6ab080a26c34db2aecf34e6b69ef +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/io/MacSink.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/io/MacSink.cs new file mode 100644 index 0000000..c4fe716 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/io/MacSink.cs @@ -0,0 +1,35 @@ +using System; + +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Crypto.IO +{ + public class MacSink + : BaseOutputStream + { + private readonly IMac mMac; + + public MacSink(IMac mac) + { + this.mMac = mac; + } + + public virtual IMac Mac + { + get { return mMac; } + } + + public override void WriteByte(byte b) + { + mMac.Update(b); + } + + public override void Write(byte[] buf, int off, int len) + { + if (len > 0) + { + mMac.BlockUpdate(buf, off, len); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/io/MacSink.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/io/MacSink.cs.meta new file mode 100644 index 0000000..f8520ce --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/io/MacSink.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3181c7f6d7c19fe4192a56dedd2114a9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/io/MacStream.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/io/MacStream.cs new file mode 100644 index 0000000..d9b8323 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/io/MacStream.cs @@ -0,0 +1,150 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.IO +{ + public class MacStream + : Stream + { + protected readonly Stream stream; + protected readonly IMac inMac; + protected readonly IMac outMac; + + public MacStream( + Stream stream, + IMac readMac, + IMac writeMac) + { + this.stream = stream; + this.inMac = readMac; + this.outMac = writeMac; + } + + public virtual IMac ReadMac() + { + return inMac; + } + + public virtual IMac WriteMac() + { + return outMac; + } + + public override int Read( + byte[] buffer, + int offset, + int count) + { + int n = stream.Read(buffer, offset, count); + if (inMac != null) + { + if (n > 0) + { + inMac.BlockUpdate(buffer, offset, n); + } + } + return n; + } + + public override int ReadByte() + { + int b = stream.ReadByte(); + if (inMac != null) + { + if (b >= 0) + { + inMac.Update((byte)b); + } + } + return b; + } + + public override void Write( + byte[] buffer, + int offset, + int count) + { + if (outMac != null) + { + if (count > 0) + { + outMac.BlockUpdate(buffer, offset, count); + } + } + stream.Write(buffer, offset, count); + } + + public override void WriteByte(byte b) + { + if (outMac != null) + { + outMac.Update(b); + } + stream.WriteByte(b); + } + + public override bool CanRead + { + get { return stream.CanRead; } + } + + public override bool CanWrite + { + get { return stream.CanWrite; } + } + + public override bool CanSeek + { + get { return stream.CanSeek; } + } + + public override long Length + { + get { return stream.Length; } + } + + public override long Position + { + get { return stream.Position; } + set { stream.Position = value; } + } + +#if PORTABLE + protected override void Dispose(bool disposing) + { + if (disposing) + { + Platform.Dispose(stream); + } + base.Dispose(disposing); + } +#else + public override void Close() + { + Platform.Dispose(stream); + base.Close(); + } +#endif + + public override void Flush() + { + stream.Flush(); + } + + public override long Seek( + long offset, + SeekOrigin origin) + { + return stream.Seek(offset,origin); + } + + public override void SetLength( + long length) + { + stream.SetLength(length); + } + } +} + diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/io/MacStream.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/io/MacStream.cs.meta new file mode 100644 index 0000000..7e0131e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/io/MacStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6dc5607dacfe3bd48b34182b82919c88 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/io/SignerSink.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/io/SignerSink.cs new file mode 100644 index 0000000..c9bd8b9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/io/SignerSink.cs @@ -0,0 +1,35 @@ +using System; + +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Crypto.IO +{ + public class SignerSink + : BaseOutputStream + { + private readonly ISigner mSigner; + + public SignerSink(ISigner signer) + { + this.mSigner = signer; + } + + public virtual ISigner Signer + { + get { return mSigner; } + } + + public override void WriteByte(byte b) + { + mSigner.Update(b); + } + + public override void Write(byte[] buf, int off, int len) + { + if (len > 0) + { + mSigner.BlockUpdate(buf, off, len); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/io/SignerSink.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/io/SignerSink.cs.meta new file mode 100644 index 0000000..440bf51 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/io/SignerSink.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7df23fe4e2c7cd148966f257d031e0f0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/io/SignerStream.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/io/SignerStream.cs new file mode 100644 index 0000000..1e37c8d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/io/SignerStream.cs @@ -0,0 +1,151 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.IO +{ + public class SignerStream + : Stream + { + protected readonly Stream stream; + protected readonly ISigner inSigner; + protected readonly ISigner outSigner; + + public SignerStream( + Stream stream, + ISigner readSigner, + ISigner writeSigner) + { + this.stream = stream; + this.inSigner = readSigner; + this.outSigner = writeSigner; + } + + public virtual ISigner ReadSigner() + { + return inSigner; + } + + public virtual ISigner WriteSigner() + { + return outSigner; + } + + public override int Read( + byte[] buffer, + int offset, + int count) + { + int n = stream.Read(buffer, offset, count); + if (inSigner != null) + { + if (n > 0) + { + inSigner.BlockUpdate(buffer, offset, n); + } + } + return n; + } + + public override int ReadByte() + { + int b = stream.ReadByte(); + if (inSigner != null) + { + if (b >= 0) + { + inSigner.Update((byte)b); + } + } + return b; + } + + public override void Write( + byte[] buffer, + int offset, + int count) + { + if (outSigner != null) + { + if (count > 0) + { + outSigner.BlockUpdate(buffer, offset, count); + } + } + stream.Write(buffer, offset, count); + } + + public override void WriteByte( + byte b) + { + if (outSigner != null) + { + outSigner.Update(b); + } + stream.WriteByte(b); + } + + public override bool CanRead + { + get { return stream.CanRead; } + } + + public override bool CanWrite + { + get { return stream.CanWrite; } + } + + public override bool CanSeek + { + get { return stream.CanSeek; } + } + + public override long Length + { + get { return stream.Length; } + } + + public override long Position + { + get { return stream.Position; } + set { stream.Position = value; } + } + +#if PORTABLE + protected override void Dispose(bool disposing) + { + if (disposing) + { + Platform.Dispose(stream); + } + base.Dispose(disposing); + } +#else + public override void Close() + { + Platform.Dispose(stream); + base.Close(); + } +#endif + + public override void Flush() + { + stream.Flush(); + } + + public override long Seek( + long offset, + SeekOrigin origin) + { + return stream.Seek(offset, origin); + } + + public override void SetLength( + long length) + { + stream.SetLength(length); + } + } +} + diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/io/SignerStream.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/io/SignerStream.cs.meta new file mode 100644 index 0000000..bd2078d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/io/SignerStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7d5078675bac3cf49af21a4b6534e943 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs.meta new file mode 100644 index 0000000..7d415dd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 266312b2d1c889846ada6f4a3e50df6d +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/CMac.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/CMac.cs new file mode 100644 index 0000000..682c12b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/CMac.cs @@ -0,0 +1,257 @@ +using System; + +using Org.BouncyCastle.Crypto.Modes; +using Org.BouncyCastle.Crypto.Paddings; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Macs +{ + /** + * CMAC - as specified at www.nuee.nagoya-u.ac.jp/labs/tiwata/omac/omac.html + *

+ * CMAC is analogous to OMAC1 - see also en.wikipedia.org/wiki/CMAC + *

+ * CMAC is a NIST recomendation - see + * csrc.nist.gov/CryptoToolkit/modes/800-38_Series_Publications/SP800-38B.pdf + *

+ * CMAC/OMAC1 is a blockcipher-based message authentication code designed and + * analyzed by Tetsu Iwata and Kaoru Kurosawa. + *

+ * CMAC/OMAC1 is a simple variant of the CBC MAC (Cipher Block Chaining Message + * Authentication Code). OMAC stands for One-Key CBC MAC. + *

+ * It supports 128- or 64-bits block ciphers, with any key size, and returns + * a MAC with dimension less or equal to the block size of the underlying + * cipher. + *

+ */ + public class CMac + : IMac + { + private const byte CONSTANT_128 = (byte)0x87; + private const byte CONSTANT_64 = (byte)0x1b; + + private byte[] ZEROES; + + private byte[] mac; + + private byte[] buf; + private int bufOff; + private IBlockCipher cipher; + + private int macSize; + + private byte[] L, Lu, Lu2; + + /** + * create a standard MAC based on a CBC block cipher (64 or 128 bit block). + * This will produce an authentication code the length of the block size + * of the cipher. + * + * @param cipher the cipher to be used as the basis of the MAC generation. + */ + public CMac( + IBlockCipher cipher) + : this(cipher, cipher.GetBlockSize() * 8) + { + } + + /** + * create a standard MAC based on a block cipher with the size of the + * MAC been given in bits. + *

+ * Note: the size of the MAC must be at least 24 bits (FIPS Publication 81), + * or 16 bits if being used as a data authenticator (FIPS Publication 113), + * and in general should be less than the size of the block cipher as it reduces + * the chance of an exhaustive attack (see Handbook of Applied Cryptography). + * + * @param cipher the cipher to be used as the basis of the MAC generation. + * @param macSizeInBits the size of the MAC in bits, must be a multiple of 8 and @lt;= 128. + */ + public CMac( + IBlockCipher cipher, + int macSizeInBits) + { + if ((macSizeInBits % 8) != 0) + throw new ArgumentException("MAC size must be multiple of 8"); + + if (macSizeInBits > (cipher.GetBlockSize() * 8)) + { + throw new ArgumentException( + "MAC size must be less or equal to " + + (cipher.GetBlockSize() * 8)); + } + + if (cipher.GetBlockSize() != 8 && cipher.GetBlockSize() != 16) + { + throw new ArgumentException( + "Block size must be either 64 or 128 bits"); + } + + this.cipher = new CbcBlockCipher(cipher); + this.macSize = macSizeInBits / 8; + + mac = new byte[cipher.GetBlockSize()]; + + buf = new byte[cipher.GetBlockSize()]; + + ZEROES = new byte[cipher.GetBlockSize()]; + + bufOff = 0; + } + + public string AlgorithmName + { + get { return cipher.AlgorithmName; } + } + + private static int ShiftLeft(byte[] block, byte[] output) + { + int i = block.Length; + uint bit = 0; + while (--i >= 0) + { + uint b = block[i]; + output[i] = (byte)((b << 1) | bit); + bit = (b >> 7) & 1; + } + return (int)bit; + } + + private static byte[] DoubleLu(byte[] input) + { + byte[] ret = new byte[input.Length]; + int carry = ShiftLeft(input, ret); + int xor = input.Length == 16 ? CONSTANT_128 : CONSTANT_64; + + /* + * NOTE: This construction is an attempt at a constant-time implementation. + */ + ret[input.Length - 1] ^= (byte)(xor >> ((1 - carry) << 3)); + + return ret; + } + + public void Init( + ICipherParameters parameters) + { + if (parameters is KeyParameter) + { + cipher.Init(true, parameters); + + //initializes the L, Lu, Lu2 numbers + L = new byte[ZEROES.Length]; + cipher.ProcessBlock(ZEROES, 0, L, 0); + Lu = DoubleLu(L); + Lu2 = DoubleLu(Lu); + } + else if (parameters != null) + { + // CMAC mode does not permit IV to underlying CBC mode + throw new ArgumentException("CMac mode only permits key to be set.", "parameters"); + } + + Reset(); + } + + public int GetMacSize() + { + return macSize; + } + + public void Update( + byte input) + { + if (bufOff == buf.Length) + { + cipher.ProcessBlock(buf, 0, mac, 0); + bufOff = 0; + } + + buf[bufOff++] = input; + } + + public void BlockUpdate( + byte[] inBytes, + int inOff, + int len) + { + if (len < 0) + throw new ArgumentException("Can't have a negative input length!"); + + int blockSize = cipher.GetBlockSize(); + int gapLen = blockSize - bufOff; + + if (len > gapLen) + { + Array.Copy(inBytes, inOff, buf, bufOff, gapLen); + + cipher.ProcessBlock(buf, 0, mac, 0); + + bufOff = 0; + len -= gapLen; + inOff += gapLen; + + while (len > blockSize) + { + cipher.ProcessBlock(inBytes, inOff, mac, 0); + + len -= blockSize; + inOff += blockSize; + } + } + + Array.Copy(inBytes, inOff, buf, bufOff, len); + + bufOff += len; + } + + public int DoFinal( + byte[] outBytes, + int outOff) + { + int blockSize = cipher.GetBlockSize(); + + byte[] lu; + if (bufOff == blockSize) + { + lu = Lu; + } + else + { + new ISO7816d4Padding().AddPadding(buf, bufOff); + lu = Lu2; + } + + for (int i = 0; i < mac.Length; i++) + { + buf[i] ^= lu[i]; + } + + cipher.ProcessBlock(buf, 0, mac, 0); + + Array.Copy(mac, 0, outBytes, outOff, macSize); + + Reset(); + + return macSize; + } + + /** + * Reset the mac generator. + */ + public void Reset() + { + /* + * clean the buffer. + */ + Array.Clear(buf, 0, buf.Length); + bufOff = 0; + + /* + * Reset the underlying cipher. + */ + cipher.Reset(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/CMac.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/CMac.cs.meta new file mode 100644 index 0000000..f900765 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/CMac.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c9834c986e15f564f842e9058d78884e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/CbcBlockCipherMac.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/CbcBlockCipherMac.cs new file mode 100644 index 0000000..146e16a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/CbcBlockCipherMac.cs @@ -0,0 +1,209 @@ +using System; + +using Org.BouncyCastle.Crypto.Modes; +using Org.BouncyCastle.Crypto.Paddings; + +namespace Org.BouncyCastle.Crypto.Macs +{ + /** + * standard CBC Block Cipher MAC - if no padding is specified the default of + * pad of zeroes is used. + */ + public class CbcBlockCipherMac + : IMac + { + private byte[] buf; + private int bufOff; + private IBlockCipher cipher; + private IBlockCipherPadding padding; + private int macSize; + + /** + * create a standard MAC based on a CBC block cipher. This will produce an + * authentication code half the length of the block size of the cipher. + * + * @param cipher the cipher to be used as the basis of the MAC generation. + */ + public CbcBlockCipherMac( + IBlockCipher cipher) + : this(cipher, (cipher.GetBlockSize() * 8) / 2, null) + { + } + + /** + * create a standard MAC based on a CBC block cipher. This will produce an + * authentication code half the length of the block size of the cipher. + * + * @param cipher the cipher to be used as the basis of the MAC generation. + * @param padding the padding to be used to complete the last block. + */ + public CbcBlockCipherMac( + IBlockCipher cipher, + IBlockCipherPadding padding) + : this(cipher, (cipher.GetBlockSize() * 8) / 2, padding) + { + } + + /** + * create a standard MAC based on a block cipher with the size of the + * MAC been given in bits. This class uses CBC mode as the basis for the + * MAC generation. + *

+ * Note: the size of the MAC must be at least 24 bits (FIPS Publication 81), + * or 16 bits if being used as a data authenticator (FIPS Publication 113), + * and in general should be less than the size of the block cipher as it reduces + * the chance of an exhaustive attack (see Handbook of Applied Cryptography). + *

+ * @param cipher the cipher to be used as the basis of the MAC generation. + * @param macSizeInBits the size of the MAC in bits, must be a multiple of 8. + */ + public CbcBlockCipherMac( + IBlockCipher cipher, + int macSizeInBits) + : this(cipher, macSizeInBits, null) + { + } + + /** + * create a standard MAC based on a block cipher with the size of the + * MAC been given in bits. This class uses CBC mode as the basis for the + * MAC generation. + *

+ * Note: the size of the MAC must be at least 24 bits (FIPS Publication 81), + * or 16 bits if being used as a data authenticator (FIPS Publication 113), + * and in general should be less than the size of the block cipher as it reduces + * the chance of an exhaustive attack (see Handbook of Applied Cryptography). + *

+ * @param cipher the cipher to be used as the basis of the MAC generation. + * @param macSizeInBits the size of the MAC in bits, must be a multiple of 8. + * @param padding the padding to be used to complete the last block. + */ + public CbcBlockCipherMac( + IBlockCipher cipher, + int macSizeInBits, + IBlockCipherPadding padding) + { + if ((macSizeInBits % 8) != 0) + throw new ArgumentException("MAC size must be multiple of 8"); + + this.cipher = new CbcBlockCipher(cipher); + this.padding = padding; + this.macSize = macSizeInBits / 8; + + buf = new byte[cipher.GetBlockSize()]; + bufOff = 0; + } + + public string AlgorithmName + { + get { return cipher.AlgorithmName; } + } + + public void Init( + ICipherParameters parameters) + { + Reset(); + + cipher.Init(true, parameters); + } + + public int GetMacSize() + { + return macSize; + } + + public void Update( + byte input) + { + if (bufOff == buf.Length) + { + cipher.ProcessBlock(buf, 0, buf, 0); + bufOff = 0; + } + + buf[bufOff++] = input; + } + + public void BlockUpdate( + byte[] input, + int inOff, + int len) + { + if (len < 0) + throw new ArgumentException("Can't have a negative input length!"); + + int blockSize = cipher.GetBlockSize(); + int gapLen = blockSize - bufOff; + + if (len > gapLen) + { + Array.Copy(input, inOff, buf, bufOff, gapLen); + + cipher.ProcessBlock(buf, 0, buf, 0); + + bufOff = 0; + len -= gapLen; + inOff += gapLen; + + while (len > blockSize) + { + cipher.ProcessBlock(input, inOff, buf, 0); + + len -= blockSize; + inOff += blockSize; + } + } + + Array.Copy(input, inOff, buf, bufOff, len); + + bufOff += len; + } + + public int DoFinal( + byte[] output, + int outOff) + { + int blockSize = cipher.GetBlockSize(); + + if (padding == null) + { + // pad with zeroes + while (bufOff < blockSize) + { + buf[bufOff++] = 0; + } + } + else + { + if (bufOff == blockSize) + { + cipher.ProcessBlock(buf, 0, buf, 0); + bufOff = 0; + } + + padding.AddPadding(buf, bufOff); + } + + cipher.ProcessBlock(buf, 0, buf, 0); + + Array.Copy(buf, 0, output, outOff, macSize); + + Reset(); + + return macSize; + } + + /** + * Reset the mac generator. + */ + public void Reset() + { + // Clear the buffer. + Array.Clear(buf, 0, buf.Length); + bufOff = 0; + + // Reset the underlying cipher. + cipher.Reset(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/CbcBlockCipherMac.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/CbcBlockCipherMac.cs.meta new file mode 100644 index 0000000..55564af --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/CbcBlockCipherMac.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 973babc8410610246bc4c6b4f197741d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/CfbBlockCipherMac.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/CfbBlockCipherMac.cs new file mode 100644 index 0000000..364cf84 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/CfbBlockCipherMac.cs @@ -0,0 +1,368 @@ +using System; + +using Org.BouncyCastle.Crypto.Modes; +using Org.BouncyCastle.Crypto.Paddings; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Macs +{ + /** + * implements a Cipher-FeedBack (CFB) mode on top of a simple cipher. + */ + class MacCFBBlockCipher + : IBlockCipher + { + private byte[] IV; + private byte[] cfbV; + private byte[] cfbOutV; + + private readonly int blockSize; + private readonly IBlockCipher cipher; + + /** + * Basic constructor. + * + * @param cipher the block cipher to be used as the basis of the + * feedback mode. + * @param blockSize the block size in bits (note: a multiple of 8) + */ + public MacCFBBlockCipher( + IBlockCipher cipher, + int bitBlockSize) + { + this.cipher = cipher; + this.blockSize = bitBlockSize / 8; + + this.IV = new byte[cipher.GetBlockSize()]; + this.cfbV = new byte[cipher.GetBlockSize()]; + this.cfbOutV = new byte[cipher.GetBlockSize()]; + } + + /** + * Initialise the cipher and, possibly, the initialisation vector (IV). + * If an IV isn't passed as part of the parameter, the IV will be all zeros. + * An IV which is too short is handled in FIPS compliant fashion. + * + * @param param the key and other data required by the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public void Init( + bool forEncryption, + ICipherParameters parameters) + { + if (parameters is ParametersWithIV) + { + ParametersWithIV ivParam = (ParametersWithIV)parameters; + byte[] iv = ivParam.GetIV(); + + if (iv.Length < IV.Length) + { + Array.Copy(iv, 0, IV, IV.Length - iv.Length, iv.Length); + } + else + { + Array.Copy(iv, 0, IV, 0, IV.Length); + } + + parameters = ivParam.Parameters; + } + + Reset(); + + cipher.Init(true, parameters); + } + + /** + * return the algorithm name and mode. + * + * @return the name of the underlying algorithm followed by "/CFB" + * and the block size in bits. + */ + public string AlgorithmName + { + get { return cipher.AlgorithmName + "/CFB" + (blockSize * 8); } + } + + public bool IsPartialBlockOkay + { + get { return true; } + } + + /** + * return the block size we are operating at. + * + * @return the block size we are operating at (in bytes). + */ + public int GetBlockSize() + { + return blockSize; + } + + /** + * Process one block of input from the array in and write it to + * the out array. + * + * @param in the array containing the input data. + * @param inOff offset into the in array the data starts at. + * @param out the array the output data will be copied into. + * @param outOff the offset into the out array the output will start at. + * @exception DataLengthException if there isn't enough data in in, or + * space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + * @return the number of bytes processed and produced. + */ + public int ProcessBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + if ((inOff + blockSize) > input.Length) + throw new DataLengthException("input buffer too short"); + + if ((outOff + blockSize) > outBytes.Length) + throw new DataLengthException("output buffer too short"); + + cipher.ProcessBlock(cfbV, 0, cfbOutV, 0); + + // + // XOR the cfbV with the plaintext producing the cipher text + // + for (int i = 0; i < blockSize; i++) + { + outBytes[outOff + i] = (byte)(cfbOutV[i] ^ input[inOff + i]); + } + + // + // change over the input block. + // + Array.Copy(cfbV, blockSize, cfbV, 0, cfbV.Length - blockSize); + Array.Copy(outBytes, outOff, cfbV, cfbV.Length - blockSize, blockSize); + + return blockSize; + } + + /** + * reset the chaining vector back to the IV and reset the underlying + * cipher. + */ + public void Reset() + { + IV.CopyTo(cfbV, 0); + + cipher.Reset(); + } + + public void GetMacBlock( + byte[] mac) + { + cipher.ProcessBlock(cfbV, 0, mac, 0); + } + } + + public class CfbBlockCipherMac + : IMac + { + private byte[] mac; + private byte[] Buffer; + private int bufOff; + private MacCFBBlockCipher cipher; + private IBlockCipherPadding padding; + private int macSize; + + /** + * create a standard MAC based on a CFB block cipher. This will produce an + * authentication code half the length of the block size of the cipher, with + * the CFB mode set to 8 bits. + * + * @param cipher the cipher to be used as the basis of the MAC generation. + */ + public CfbBlockCipherMac( + IBlockCipher cipher) + : this(cipher, 8, (cipher.GetBlockSize() * 8) / 2, null) + { + } + + /** + * create a standard MAC based on a CFB block cipher. This will produce an + * authentication code half the length of the block size of the cipher, with + * the CFB mode set to 8 bits. + * + * @param cipher the cipher to be used as the basis of the MAC generation. + * @param padding the padding to be used. + */ + public CfbBlockCipherMac( + IBlockCipher cipher, + IBlockCipherPadding padding) + : this(cipher, 8, (cipher.GetBlockSize() * 8) / 2, padding) + { + } + + /** + * create a standard MAC based on a block cipher with the size of the + * MAC been given in bits. This class uses CFB mode as the basis for the + * MAC generation. + *

+ * Note: the size of the MAC must be at least 24 bits (FIPS Publication 81), + * or 16 bits if being used as a data authenticator (FIPS Publication 113), + * and in general should be less than the size of the block cipher as it reduces + * the chance of an exhaustive attack (see Handbook of Applied Cryptography). + *

+ * @param cipher the cipher to be used as the basis of the MAC generation. + * @param cfbBitSize the size of an output block produced by the CFB mode. + * @param macSizeInBits the size of the MAC in bits, must be a multiple of 8. + */ + public CfbBlockCipherMac( + IBlockCipher cipher, + int cfbBitSize, + int macSizeInBits) + : this(cipher, cfbBitSize, macSizeInBits, null) + { + } + + /** + * create a standard MAC based on a block cipher with the size of the + * MAC been given in bits. This class uses CFB mode as the basis for the + * MAC generation. + *

+ * Note: the size of the MAC must be at least 24 bits (FIPS Publication 81), + * or 16 bits if being used as a data authenticator (FIPS Publication 113), + * and in general should be less than the size of the block cipher as it reduces + * the chance of an exhaustive attack (see Handbook of Applied Cryptography). + *

+ * @param cipher the cipher to be used as the basis of the MAC generation. + * @param cfbBitSize the size of an output block produced by the CFB mode. + * @param macSizeInBits the size of the MAC in bits, must be a multiple of 8. + * @param padding a padding to be used. + */ + public CfbBlockCipherMac( + IBlockCipher cipher, + int cfbBitSize, + int macSizeInBits, + IBlockCipherPadding padding) + { + if ((macSizeInBits % 8) != 0) + throw new ArgumentException("MAC size must be multiple of 8"); + + mac = new byte[cipher.GetBlockSize()]; + + this.cipher = new MacCFBBlockCipher(cipher, cfbBitSize); + this.padding = padding; + this.macSize = macSizeInBits / 8; + + Buffer = new byte[this.cipher.GetBlockSize()]; + bufOff = 0; + } + + public string AlgorithmName + { + get { return cipher.AlgorithmName; } + } + + public void Init( + ICipherParameters parameters) + { + Reset(); + + cipher.Init(true, parameters); + } + + public int GetMacSize() + { + return macSize; + } + + public void Update( + byte input) + { + if (bufOff == Buffer.Length) + { + cipher.ProcessBlock(Buffer, 0, mac, 0); + bufOff = 0; + } + + Buffer[bufOff++] = input; + } + + public void BlockUpdate( + byte[] input, + int inOff, + int len) + { + if (len < 0) + throw new ArgumentException("Can't have a negative input length!"); + + int blockSize = cipher.GetBlockSize(); + int resultLen = 0; + int gapLen = blockSize - bufOff; + + if (len > gapLen) + { + Array.Copy(input, inOff, Buffer, bufOff, gapLen); + + resultLen += cipher.ProcessBlock(Buffer, 0, mac, 0); + + bufOff = 0; + len -= gapLen; + inOff += gapLen; + + while (len > blockSize) + { + resultLen += cipher.ProcessBlock(input, inOff, mac, 0); + + len -= blockSize; + inOff += blockSize; + } + } + + Array.Copy(input, inOff, Buffer, bufOff, len); + + bufOff += len; + } + + public int DoFinal( + byte[] output, + int outOff) + { + int blockSize = cipher.GetBlockSize(); + + // pad with zeroes + if (this.padding == null) + { + while (bufOff < blockSize) + { + Buffer[bufOff++] = 0; + } + } + else + { + padding.AddPadding(Buffer, bufOff); + } + + cipher.ProcessBlock(Buffer, 0, mac, 0); + + cipher.GetMacBlock(mac); + + Array.Copy(mac, 0, output, outOff, macSize); + + Reset(); + + return macSize; + } + + /** + * Reset the mac generator. + */ + public void Reset() + { + // Clear the buffer. + Array.Clear(Buffer, 0, Buffer.Length); + bufOff = 0; + + // Reset the underlying cipher. + cipher.Reset(); + } + } + +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/CfbBlockCipherMac.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/CfbBlockCipherMac.cs.meta new file mode 100644 index 0000000..26fc62e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/CfbBlockCipherMac.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b9b8fac05dca686459c77c7afe63f275 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/DSTU7564Mac.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/DSTU7564Mac.cs new file mode 100644 index 0000000..36e8641 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/DSTU7564Mac.cs @@ -0,0 +1,143 @@ +using System; + +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; + +namespace Org.BouncyCastle.Crypto.Macs +{ + /// + /// Implementation of DSTU7564 mac mode + /// + public class Dstu7564Mac + : IMac + { + private Dstu7564Digest engine; + private int macSize; + + private ulong inputLength; + + byte[] paddedKey; + byte[] invertedKey; + + public string AlgorithmName + { + get { return "DSTU7564Mac"; } + } + + public Dstu7564Mac(int macSizeBits) + { + engine = new Dstu7564Digest(macSizeBits); + macSize = macSizeBits / 8; + } + + public void Init(ICipherParameters parameters) + { + if (parameters is KeyParameter) + { + byte[] key = ((KeyParameter)parameters).GetKey(); + + invertedKey = new byte[key.Length]; + + paddedKey = PadKey(key); + + for (int byteIndex = 0; byteIndex < invertedKey.Length; byteIndex++) + { + invertedKey[byteIndex] = (byte)(key[byteIndex] ^ (byte)0xFF); + } + } + else + { + throw new ArgumentException("Bad parameter passed"); + } + + engine.BlockUpdate(paddedKey, 0, paddedKey.Length); + } + + public int GetMacSize() + { + return macSize; + } + + public void BlockUpdate(byte[] input, int inOff, int len) + { + Check.DataLength(input, inOff, len, "Input buffer too short"); + + if (paddedKey == null) + throw new InvalidOperationException(AlgorithmName + " not initialised"); + + engine.BlockUpdate(input, inOff, len); + inputLength += (ulong)len; + } + + public void Update(byte input) + { + engine.Update(input); + inputLength++; + } + + public int DoFinal(byte[] output, int outOff) + { + Check.OutputLength(output, outOff, macSize, "Output buffer too short"); + + if (paddedKey == null) + throw new InvalidOperationException(AlgorithmName + " not initialised"); + + Pad(); + + engine.BlockUpdate(invertedKey, 0, invertedKey.Length); + + inputLength = 0; + + return engine.DoFinal(output, outOff); + } + + public void Reset() + { + inputLength = 0; + engine.Reset(); + if (paddedKey != null) + { + engine.BlockUpdate(paddedKey, 0, paddedKey.Length); + } + } + + private void Pad() + { + int extra = engine.GetByteLength() - (int)(inputLength % (ulong)engine.GetByteLength()); + if (extra < 13) // terminator byte + 96 bits of length + { + extra += engine.GetByteLength(); + } + + byte[] padded = new byte[extra]; + + padded[0] = (byte)0x80; // Defined in standard; + + // Defined in standard; + Pack.UInt64_To_LE(inputLength * 8, padded, padded.Length - 12); + + engine.BlockUpdate(padded, 0, padded.Length); + } + + private byte[] PadKey(byte[] input) + { + int paddedLen = ((input.Length + engine.GetByteLength() - 1) / engine.GetByteLength()) * engine.GetByteLength(); + + int extra = engine.GetByteLength() - (int)(input.Length % engine.GetByteLength()); + if (extra < 13) // terminator byte + 96 bits of length + { + paddedLen += engine.GetByteLength(); + } + + byte[] padded = new byte[paddedLen]; + + Array.Copy(input, 0, padded, 0, input.Length); + + padded[input.Length] = (byte)0x80; // Defined in standard; + Pack.UInt32_To_LE((uint)(input.Length * 8), padded, padded.Length - 12); // Defined in standard; + + return padded; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/DSTU7564Mac.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/DSTU7564Mac.cs.meta new file mode 100644 index 0000000..928f58a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/DSTU7564Mac.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a9177fae4ada6684d9b603da0868a20f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/DSTU7624Mac.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/DSTU7624Mac.cs new file mode 100644 index 0000000..953d816 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/DSTU7624Mac.cs @@ -0,0 +1,160 @@ +using System; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Parameters; + + +namespace Org.BouncyCastle.Crypto.Macs +{ + /** + * implementation of DSTU 7624 MAC + */ + public class Dstu7624Mac : IMac + { + private int macSize; + + private Dstu7624Engine engine; + private int blockSize; + + private byte[] c, cTemp, kDelta; + private byte[] buf; + private int bufOff; + + public Dstu7624Mac(int blockSizeBits, int q) + { + engine = new Dstu7624Engine(blockSizeBits); + + blockSize = blockSizeBits / 8; + + macSize = q / 8; + + c = new byte[blockSize]; + + cTemp = new byte[blockSize]; + + kDelta = new byte[blockSize]; + buf = new byte[blockSize]; + } + + public void Init(ICipherParameters parameters) + { + if (parameters is KeyParameter) + { + engine.Init(true, (KeyParameter)parameters); + + engine.ProcessBlock(kDelta, 0, kDelta, 0); + } + else + { + throw new ArgumentException("invalid parameter passed to Dstu7624Mac init - " + + Platform.GetTypeName(parameters)); + } + } + + public string AlgorithmName + { + get { return "Dstu7624Mac"; } + } + + public int GetMacSize() + { + return macSize; + } + + public void Update(byte input) + { + if (bufOff == buf.Length) + { + processBlock(buf, 0); + bufOff = 0; + } + + buf[bufOff++] = input; + } + + public void BlockUpdate(byte[] input, int inOff, int len) + { + if (len < 0) + { + throw new ArgumentException( + "Can't have a negative input length!"); + } + + int blockSize = engine.GetBlockSize(); + int gapLen = blockSize - bufOff; + + if (len > gapLen) + { + Array.Copy(input, inOff, buf, bufOff, gapLen); + + processBlock(buf, 0); + + bufOff = 0; + len -= gapLen; + inOff += gapLen; + + while (len > blockSize) + { + processBlock(input, inOff); + + len -= blockSize; + inOff += blockSize; + } + } + + Array.Copy(input, inOff, buf, bufOff, len); + + bufOff += len; + } + + private void processBlock(byte[] input, int inOff) + { + Xor(c, 0, input, inOff, cTemp); + + engine.ProcessBlock(cTemp, 0, c, 0); + } + + private void Xor(byte[] c, int cOff, byte[] input, int inOff, byte[] xorResult) + { + for (int byteIndex = 0; byteIndex < blockSize; byteIndex++) + { + xorResult[byteIndex] = (byte)(c[byteIndex + cOff] ^ input[byteIndex + inOff]); + } + } + + public int DoFinal(byte[] output, int outOff) + { + if (bufOff % buf.Length != 0) + { + throw new DataLengthException("Input must be a multiple of blocksize"); + } + + //Last block + Xor(c, 0, buf, 0, cTemp); + Xor(cTemp, 0, kDelta, 0, c); + engine.ProcessBlock(c, 0, c, 0); + + if (macSize + outOff > output.Length) + { + throw new DataLengthException("Output buffer too short"); + } + + Array.Copy(c, 0, output, outOff, macSize); + + return macSize; + } + + public void Reset() + { + Arrays.Fill(c, (byte)0x00); + Arrays.Fill(cTemp, (byte)0x00); + Arrays.Fill(kDelta, (byte)0x00); + Arrays.Fill(buf, (byte)0x00); + engine.Reset(); + engine.ProcessBlock(kDelta, 0, kDelta, 0); + bufOff = 0; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/DSTU7624Mac.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/DSTU7624Mac.cs.meta new file mode 100644 index 0000000..a01b4e3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/DSTU7624Mac.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ee9ab22377334e54c9ebf81c5357f383 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/GMac.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/GMac.cs new file mode 100644 index 0000000..f2c3990 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/GMac.cs @@ -0,0 +1,112 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Modes; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Macs +{ + /// + /// The GMAC specialisation of Galois/Counter mode (GCM) detailed in NIST Special Publication + /// 800-38D. + /// + /// + /// GMac is an invocation of the GCM mode where no data is encrypted (i.e. all input data to the Mac + /// is processed as additional authenticated data with the underlying GCM block cipher). + /// + public class GMac + : IMac + { + private readonly GcmBlockCipher cipher; + private readonly int macSizeBits; + + /// + /// Creates a GMAC based on the operation of a block cipher in GCM mode. + /// + /// + /// This will produce an authentication code the length of the block size of the cipher. + /// + /// the cipher to be used in GCM mode to generate the MAC. + public GMac(GcmBlockCipher cipher) + : this(cipher, 128) + { + } + + /// + /// Creates a GMAC based on the operation of a 128 bit block cipher in GCM mode. + /// + /// + /// This will produce an authentication code the length of the block size of the cipher. + /// + /// the cipher to be used in GCM mode to generate the MAC. + /// the mac size to generate, in bits. Must be a multiple of 8, between 32 and 128 (inclusive). + /// Sizes less than 96 are not recommended, but are supported for specialized applications. + public GMac(GcmBlockCipher cipher, int macSizeBits) + { + this.cipher = cipher; + this.macSizeBits = macSizeBits; + } + + /// + /// Initialises the GMAC - requires a + /// providing a and a nonce. + /// + public void Init(ICipherParameters parameters) + { + if (parameters is ParametersWithIV) + { + ParametersWithIV param = (ParametersWithIV)parameters; + + byte[] iv = param.GetIV(); + KeyParameter keyParam = (KeyParameter)param.Parameters; + + // GCM is always operated in encrypt mode to calculate MAC + cipher.Init(true, new AeadParameters(keyParam, macSizeBits, iv)); + } + else + { + throw new ArgumentException("GMAC requires ParametersWithIV"); + } + } + + public string AlgorithmName + { + get { return cipher.GetUnderlyingCipher().AlgorithmName + "-GMAC"; } + } + + public int GetMacSize() + { + return macSizeBits / 8; + } + + public void Update(byte input) + { + cipher.ProcessAadByte(input); + } + + public void BlockUpdate(byte[] input, int inOff, int len) + { + cipher.ProcessAadBytes(input, inOff, len); + } + + public int DoFinal(byte[] output, int outOff) + { + try + { + return cipher.DoFinal(output, outOff); + } + catch (InvalidCipherTextException e) + { + // Impossible in encrypt mode + throw new InvalidOperationException(e.ToString()); + } + } + + public void Reset() + { + cipher.Reset(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/GMac.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/GMac.cs.meta new file mode 100644 index 0000000..9c9514e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/GMac.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fa019a75ac1d4b6429f56341790bf687 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/GOST28147Mac.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/GOST28147Mac.cs new file mode 100644 index 0000000..33c2d67 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/GOST28147Mac.cs @@ -0,0 +1,315 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Macs +{ + /** + * implementation of GOST 28147-89 MAC + */ + public class Gost28147Mac : IMac + { + private const int blockSize = 8; + private const int macSize = 4; + private int bufOff; + private byte[] buf; + private byte[] mac; + private bool firstStep = true; + private int[] workingKey; + private byte[] macIV = null; + + // + // This is default S-box - E_A. + private byte[] S = + { + 0x9,0x6,0x3,0x2,0x8,0xB,0x1,0x7,0xA,0x4,0xE,0xF,0xC,0x0,0xD,0x5, + 0x3,0x7,0xE,0x9,0x8,0xA,0xF,0x0,0x5,0x2,0x6,0xC,0xB,0x4,0xD,0x1, + 0xE,0x4,0x6,0x2,0xB,0x3,0xD,0x8,0xC,0xF,0x5,0xA,0x0,0x7,0x1,0x9, + 0xE,0x7,0xA,0xC,0xD,0x1,0x3,0x9,0x0,0x2,0xB,0x4,0xF,0x8,0x5,0x6, + 0xB,0x5,0x1,0x9,0x8,0xD,0xF,0x0,0xE,0x4,0x2,0x3,0xC,0x7,0xA,0x6, + 0x3,0xA,0xD,0xC,0x1,0x2,0x0,0xB,0x7,0x5,0x9,0x4,0x8,0xF,0xE,0x6, + 0x1,0xD,0x2,0x9,0x7,0xA,0x6,0x0,0x8,0xC,0x4,0x5,0xF,0x3,0xB,0xE, + 0xB,0xA,0xF,0x5,0x0,0xC,0xE,0x8,0x6,0x2,0x3,0x9,0x1,0x7,0xD,0x4 + }; + + public Gost28147Mac() + { + mac = new byte[blockSize]; + buf = new byte[blockSize]; + bufOff = 0; + } + + private static int[] GenerateWorkingKey( + byte[] userKey) + { + if (userKey.Length != 32) + throw new ArgumentException("Key length invalid. Key needs to be 32 byte - 256 bit!!!"); + + int[] key = new int[8]; + for(int i=0; i!=8; i++) + { + key[i] = bytesToint(userKey,i*4); + } + + return key; + } + + public void Init( + ICipherParameters parameters) + { + Reset(); + buf = new byte[blockSize]; + macIV = null; + if (parameters is ParametersWithSBox) + { + ParametersWithSBox param = (ParametersWithSBox)parameters; + + // + // Set the S-Box + // + param.GetSBox().CopyTo(this.S, 0); + + // + // set key if there is one + // + if (param.Parameters != null) + { + workingKey = GenerateWorkingKey(((KeyParameter)param.Parameters).GetKey()); + } + } + else if (parameters is KeyParameter) + { + workingKey = GenerateWorkingKey(((KeyParameter)parameters).GetKey()); + } + else if (parameters is ParametersWithIV) + { + ParametersWithIV p = (ParametersWithIV)parameters; + + workingKey = GenerateWorkingKey(((KeyParameter)p.Parameters).GetKey()); + Array.Copy(p.GetIV(), 0, mac, 0, mac.Length); + macIV = p.GetIV(); // don't skip the initial CM5Func + } + else + { + throw new ArgumentException("invalid parameter passed to Gost28147 init - " + + Platform.GetTypeName(parameters)); + } + } + + public string AlgorithmName + { + get { return "Gost28147Mac"; } + } + + public int GetMacSize() + { + return macSize; + } + + private int gost28147_mainStep(int n1, int key) + { + int cm = (key + n1); // CM1 + + // S-box replacing + + int om = S[ 0 + ((cm >> (0 * 4)) & 0xF)] << (0 * 4); + om += S[ 16 + ((cm >> (1 * 4)) & 0xF)] << (1 * 4); + om += S[ 32 + ((cm >> (2 * 4)) & 0xF)] << (2 * 4); + om += S[ 48 + ((cm >> (3 * 4)) & 0xF)] << (3 * 4); + om += S[ 64 + ((cm >> (4 * 4)) & 0xF)] << (4 * 4); + om += S[ 80 + ((cm >> (5 * 4)) & 0xF)] << (5 * 4); + om += S[ 96 + ((cm >> (6 * 4)) & 0xF)] << (6 * 4); + om += S[112 + ((cm >> (7 * 4)) & 0xF)] << (7 * 4); + +// return om << 11 | om >>> (32-11); // 11-leftshift + int omLeft = om << 11; + int omRight = (int)(((uint) om) >> (32 - 11)); // Note: Casts required to get unsigned bit rotation + + return omLeft | omRight; + } + + private void gost28147MacFunc( + int[] workingKey, + byte[] input, + int inOff, + byte[] output, + int outOff) + { + int N1, N2, tmp; //tmp -> for saving N1 + N1 = bytesToint(input, inOff); + N2 = bytesToint(input, inOff + 4); + + for (int k = 0; k < 2; k++) // 1-16 steps + { + for (int j = 0; j < 8; j++) + { + tmp = N1; + N1 = N2 ^ gost28147_mainStep(N1, workingKey[j]); // CM2 + N2 = tmp; + } + } + + intTobytes(N1, output, outOff); + intTobytes(N2, output, outOff + 4); + } + + //array of bytes to type int + private static int bytesToint( + byte[] input, + int inOff) + { + return (int)((input[inOff + 3] << 24) & 0xff000000) + ((input[inOff + 2] << 16) & 0xff0000) + + ((input[inOff + 1] << 8) & 0xff00) + (input[inOff] & 0xff); + } + + //int to array of bytes + private static void intTobytes( + int num, + byte[] output, + int outOff) + { + output[outOff + 3] = (byte)(num >> 24); + output[outOff + 2] = (byte)(num >> 16); + output[outOff + 1] = (byte)(num >> 8); + output[outOff] = (byte)num; + } + + private static byte[] CM5func( + byte[] buf, + int bufOff, + byte[] mac) + { + byte[] sum = new byte[buf.Length - bufOff]; + + Array.Copy(buf, bufOff, sum, 0, mac.Length); + + for (int i = 0; i != mac.Length; i++) + { + sum[i] = (byte)(sum[i] ^ mac[i]); + } + + return sum; + } + + public void Update( + byte input) + { + if (bufOff == buf.Length) + { + byte[] sumbuf = new byte[buf.Length]; + Array.Copy(buf, 0, sumbuf, 0, mac.Length); + + if (firstStep) + { + firstStep = false; + if (macIV != null) + { + sumbuf = CM5func(buf, 0, macIV); + } + } + else + { + sumbuf = CM5func(buf, 0, mac); + } + + gost28147MacFunc(workingKey, sumbuf, 0, mac, 0); + bufOff = 0; + } + + buf[bufOff++] = input; + } + + public void BlockUpdate( + byte[] input, + int inOff, + int len) + { + if (len < 0) + throw new ArgumentException("Can't have a negative input length!"); + + int gapLen = blockSize - bufOff; + + if (len > gapLen) + { + Array.Copy(input, inOff, buf, bufOff, gapLen); + + byte[] sumbuf = new byte[buf.Length]; + Array.Copy(buf, 0, sumbuf, 0, mac.Length); + + if (firstStep) + { + firstStep = false; + if (macIV != null) + { + sumbuf = CM5func(buf, 0, macIV); + } + } + else + { + sumbuf = CM5func(buf, 0, mac); + } + + gost28147MacFunc(workingKey, sumbuf, 0, mac, 0); + + bufOff = 0; + len -= gapLen; + inOff += gapLen; + + while (len > blockSize) + { + sumbuf = CM5func(input, inOff, mac); + gost28147MacFunc(workingKey, sumbuf, 0, mac, 0); + + len -= blockSize; + inOff += blockSize; + } + } + + Array.Copy(input, inOff, buf, bufOff, len); + + bufOff += len; + } + + public int DoFinal( + byte[] output, + int outOff) + { + //padding with zero + while (bufOff < blockSize) + { + buf[bufOff++] = 0; + } + + byte[] sumbuf = new byte[buf.Length]; + Array.Copy(buf, 0, sumbuf, 0, mac.Length); + + if (firstStep) + { + firstStep = false; + } + else + { + sumbuf = CM5func(buf, 0, mac); + } + + gost28147MacFunc(workingKey, sumbuf, 0, mac, 0); + + Array.Copy(mac, (mac.Length/2)-macSize, output, outOff, macSize); + + Reset(); + + return macSize; + } + + public void Reset() + { + // Clear the buffer. + Array.Clear(buf, 0, buf.Length); + bufOff = 0; + + firstStep = true; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/GOST28147Mac.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/GOST28147Mac.cs.meta new file mode 100644 index 0000000..75502df --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/GOST28147Mac.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 25d2322dec799c74abed25d42a581774 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/HMac.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/HMac.cs new file mode 100644 index 0000000..460f3c5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/HMac.cs @@ -0,0 +1,154 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Macs +{ + /** + * HMAC implementation based on RFC2104 + * + * H(K XOR opad, H(K XOR ipad, text)) + */ + public class HMac + : IMac + { + private const byte IPAD = (byte)0x36; + private const byte OPAD = (byte)0x5C; + + private readonly IDigest digest; + private readonly int digestSize; + private readonly int blockLength; + private IMemoable ipadState; + private IMemoable opadState; + + private readonly byte[] inputPad; + private readonly byte[] outputBuf; + + public HMac(IDigest digest) + { + this.digest = digest; + this.digestSize = digest.GetDigestSize(); + this.blockLength = digest.GetByteLength(); + this.inputPad = new byte[blockLength]; + this.outputBuf = new byte[blockLength + digestSize]; + } + + public virtual string AlgorithmName + { + get { return digest.AlgorithmName + "/HMAC"; } + } + + public virtual IDigest GetUnderlyingDigest() + { + return digest; + } + + public virtual void Init(ICipherParameters parameters) + { + digest.Reset(); + + byte[] key = ((KeyParameter)parameters).GetKey(); + int keyLength = key.Length; + + if (keyLength > blockLength) + { + digest.BlockUpdate(key, 0, keyLength); + digest.DoFinal(inputPad, 0); + + keyLength = digestSize; + } + else + { + Array.Copy(key, 0, inputPad, 0, keyLength); + } + + Array.Clear(inputPad, keyLength, blockLength - keyLength); + Array.Copy(inputPad, 0, outputBuf, 0, blockLength); + + XorPad(inputPad, blockLength, IPAD); + XorPad(outputBuf, blockLength, OPAD); + + if (digest is IMemoable) + { + opadState = ((IMemoable)digest).Copy(); + + ((IDigest)opadState).BlockUpdate(outputBuf, 0, blockLength); + } + + digest.BlockUpdate(inputPad, 0, inputPad.Length); + + if (digest is IMemoable) + { + ipadState = ((IMemoable)digest).Copy(); + } + } + + public virtual int GetMacSize() + { + return digestSize; + } + + public virtual void Update(byte input) + { + digest.Update(input); + } + + public virtual void BlockUpdate(byte[] input, int inOff, int len) + { + digest.BlockUpdate(input, inOff, len); + } + + public virtual int DoFinal(byte[] output, int outOff) + { + digest.DoFinal(outputBuf, blockLength); + + if (opadState != null) + { + ((IMemoable)digest).Reset(opadState); + digest.BlockUpdate(outputBuf, blockLength, digest.GetDigestSize()); + } + else + { + digest.BlockUpdate(outputBuf, 0, outputBuf.Length); + } + + int len = digest.DoFinal(output, outOff); + + Array.Clear(outputBuf, blockLength, digestSize); + + if (ipadState != null) + { + ((IMemoable)digest).Reset(ipadState); + } + else + { + digest.BlockUpdate(inputPad, 0, inputPad.Length); + } + + return len; + } + + /** + * Reset the mac generator. + */ + public virtual void Reset() + { + // Reset underlying digest + digest.Reset(); + + // Initialise the digest + digest.BlockUpdate(inputPad, 0, inputPad.Length); + } + + private static void XorPad(byte[] pad, int len, byte n) + { + for (int i = 0; i < len; ++i) + { + pad[i] ^= n; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/HMac.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/HMac.cs.meta new file mode 100644 index 0000000..a0c39fc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/HMac.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 831da6fa11e423c42b363602b6c7a85a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/ISO9797Alg3Mac.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/ISO9797Alg3Mac.cs new file mode 100644 index 0000000..6fee619 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/ISO9797Alg3Mac.cs @@ -0,0 +1,275 @@ +using System; + +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Modes; +using Org.BouncyCastle.Crypto.Paddings; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Macs +{ + /** + * DES based CBC Block Cipher MAC according to ISO9797, algorithm 3 (ANSI X9.19 Retail MAC) + * + * This could as well be derived from CBCBlockCipherMac, but then the property mac in the base + * class must be changed to protected + */ + public class ISO9797Alg3Mac : IMac + { + private byte[] mac; + private byte[] buf; + private int bufOff; + private IBlockCipher cipher; + private IBlockCipherPadding padding; + private int macSize; + private KeyParameter lastKey2; + private KeyParameter lastKey3; + + /** + * create a Retail-MAC based on a CBC block cipher. This will produce an + * authentication code of the length of the block size of the cipher. + * + * @param cipher the cipher to be used as the basis of the MAC generation. This must + * be DESEngine. + */ + public ISO9797Alg3Mac( + IBlockCipher cipher) + : this(cipher, cipher.GetBlockSize() * 8, null) + { + } + + /** + * create a Retail-MAC based on a CBC block cipher. This will produce an + * authentication code of the length of the block size of the cipher. + * + * @param cipher the cipher to be used as the basis of the MAC generation. + * @param padding the padding to be used to complete the last block. + */ + public ISO9797Alg3Mac( + IBlockCipher cipher, + IBlockCipherPadding padding) + : this(cipher, cipher.GetBlockSize() * 8, padding) + { + } + + /** + * create a Retail-MAC based on a block cipher with the size of the + * MAC been given in bits. This class uses single DES CBC mode as the basis for the + * MAC generation. + *

+ * Note: the size of the MAC must be at least 24 bits (FIPS Publication 81), + * or 16 bits if being used as a data authenticator (FIPS Publication 113), + * and in general should be less than the size of the block cipher as it reduces + * the chance of an exhaustive attack (see Handbook of Applied Cryptography). + *

+ * @param cipher the cipher to be used as the basis of the MAC generation. + * @param macSizeInBits the size of the MAC in bits, must be a multiple of 8. + */ + public ISO9797Alg3Mac( + IBlockCipher cipher, + int macSizeInBits) + : this(cipher, macSizeInBits, null) + { + } + + /** + * create a standard MAC based on a block cipher with the size of the + * MAC been given in bits. This class uses single DES CBC mode as the basis for the + * MAC generation. The final block is decrypted and then encrypted using the + * middle and right part of the key. + *

+ * Note: the size of the MAC must be at least 24 bits (FIPS Publication 81), + * or 16 bits if being used as a data authenticator (FIPS Publication 113), + * and in general should be less than the size of the block cipher as it reduces + * the chance of an exhaustive attack (see Handbook of Applied Cryptography). + *

+ * @param cipher the cipher to be used as the basis of the MAC generation. + * @param macSizeInBits the size of the MAC in bits, must be a multiple of 8. + * @param padding the padding to be used to complete the last block. + */ + public ISO9797Alg3Mac( + IBlockCipher cipher, + int macSizeInBits, + IBlockCipherPadding padding) + { + if ((macSizeInBits % 8) != 0) + throw new ArgumentException("MAC size must be multiple of 8"); + + if (!(cipher is DesEngine)) + throw new ArgumentException("cipher must be instance of DesEngine"); + + this.cipher = new CbcBlockCipher(cipher); + this.padding = padding; + this.macSize = macSizeInBits / 8; + + mac = new byte[cipher.GetBlockSize()]; + buf = new byte[cipher.GetBlockSize()]; + bufOff = 0; + } + + public string AlgorithmName + { + get { return "ISO9797Alg3"; } + } + + public void Init( + ICipherParameters parameters) + { + Reset(); + + if (!(parameters is KeyParameter || parameters is ParametersWithIV)) + throw new ArgumentException("parameters must be an instance of KeyParameter or ParametersWithIV"); + + // KeyParameter must contain a double or triple length DES key, + // however the underlying cipher is a single DES. The middle and + // right key are used only in the final step. + + KeyParameter kp; + if (parameters is KeyParameter) + { + kp = (KeyParameter)parameters; + } + else + { + kp = (KeyParameter)((ParametersWithIV)parameters).Parameters; + } + + KeyParameter key1; + byte[] keyvalue = kp.GetKey(); + + if (keyvalue.Length == 16) + { // Double length DES key + key1 = new KeyParameter(keyvalue, 0, 8); + this.lastKey2 = new KeyParameter(keyvalue, 8, 8); + this.lastKey3 = key1; + } + else if (keyvalue.Length == 24) + { // Triple length DES key + key1 = new KeyParameter(keyvalue, 0, 8); + this.lastKey2 = new KeyParameter(keyvalue, 8, 8); + this.lastKey3 = new KeyParameter(keyvalue, 16, 8); + } + else + { + throw new ArgumentException("Key must be either 112 or 168 bit long"); + } + + if (parameters is ParametersWithIV) + { + cipher.Init(true, new ParametersWithIV(key1, ((ParametersWithIV)parameters).GetIV())); + } + else + { + cipher.Init(true, key1); + } + } + + public int GetMacSize() + { + return macSize; + } + + public void Update( + byte input) + { + if (bufOff == buf.Length) + { + cipher.ProcessBlock(buf, 0, mac, 0); + bufOff = 0; + } + + buf[bufOff++] = input; + } + + public void BlockUpdate( + byte[] input, + int inOff, + int len) + { + if (len < 0) + throw new ArgumentException("Can't have a negative input length!"); + + int blockSize = cipher.GetBlockSize(); + int resultLen = 0; + int gapLen = blockSize - bufOff; + + if (len > gapLen) + { + Array.Copy(input, inOff, buf, bufOff, gapLen); + + resultLen += cipher.ProcessBlock(buf, 0, mac, 0); + + bufOff = 0; + len -= gapLen; + inOff += gapLen; + + while (len > blockSize) + { + resultLen += cipher.ProcessBlock(input, inOff, mac, 0); + + len -= blockSize; + inOff += blockSize; + } + } + + Array.Copy(input, inOff, buf, bufOff, len); + + bufOff += len; + } + + public int DoFinal( + byte[] output, + int outOff) + { + int blockSize = cipher.GetBlockSize(); + + if (padding == null) + { + // pad with zeroes + while (bufOff < blockSize) + { + buf[bufOff++] = 0; + } + } + else + { + if (bufOff == blockSize) + { + cipher.ProcessBlock(buf, 0, mac, 0); + bufOff = 0; + } + + padding.AddPadding(buf, bufOff); + } + + cipher.ProcessBlock(buf, 0, mac, 0); + + // Added to code from base class + DesEngine deseng = new DesEngine(); + + deseng.Init(false, this.lastKey2); + deseng.ProcessBlock(mac, 0, mac, 0); + + deseng.Init(true, this.lastKey3); + deseng.ProcessBlock(mac, 0, mac, 0); + // **** + + Array.Copy(mac, 0, output, outOff, macSize); + + Reset(); + + return macSize; + } + + /** + * Reset the mac generator. + */ + public void Reset() + { + Array.Clear(buf, 0, buf.Length); + bufOff = 0; + + // reset the underlying cipher. + cipher.Reset(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/ISO9797Alg3Mac.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/ISO9797Alg3Mac.cs.meta new file mode 100644 index 0000000..de59ecb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/ISO9797Alg3Mac.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 922be1bff548389448187c4f46b101cd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/KMac.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/KMac.cs new file mode 100644 index 0000000..05031ac --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/KMac.cs @@ -0,0 +1,173 @@ +using System; + +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Macs +{ + public class KMac + : IMac, IXof + { + private static readonly byte[] padding = new byte[100]; + + private readonly CShakeDigest cshake; + private readonly int bitLength; + private readonly int outputLength; + + private byte[] key; + private bool initialised; + private bool firstOutput; + + public KMac(int bitLength, byte[] S) + { + this.cshake = new CShakeDigest(bitLength, Strings.ToAsciiByteArray("KMAC"), S); + this.bitLength = bitLength; + this.outputLength = bitLength * 2 / 8; + } + + public string AlgorithmName + { + get { return "KMAC" + cshake.AlgorithmName.Substring(6); } + } + + public void BlockUpdate(byte[] input, int inOff, int len) + { + if (!initialised) + throw new InvalidOperationException("KMAC not initialized"); + + cshake.BlockUpdate(input, inOff, len); + } + + public int DoFinal(byte[] output, int outOff) + { + if (firstOutput) + { + if (!initialised) + throw new InvalidOperationException("KMAC not initialized"); + + byte[] encOut = XofUtilities.RightEncode(GetMacSize() * 8); + + cshake.BlockUpdate(encOut, 0, encOut.Length); + } + + int rv = cshake.DoFinal(output, outOff, GetMacSize()); + + Reset(); + + return rv; + } + + public int DoFinal(byte[] output, int outOff, int outLen) + { + if (firstOutput) + { + if (!initialised) + throw new InvalidOperationException("KMAC not initialized"); + + byte[] encOut = XofUtilities.RightEncode(outLen * 8); + + cshake.BlockUpdate(encOut, 0, encOut.Length); + } + + int rv = cshake.DoFinal(output, outOff, outLen); + + Reset(); + + return rv; + } + + public int DoOutput(byte[] output, int outOff, int outLen) + { + if (firstOutput) + { + if (!initialised) + throw new InvalidOperationException("KMAC not initialized"); + + byte[] encOut = XofUtilities.RightEncode(0); + + cshake.BlockUpdate(encOut, 0, encOut.Length); + + firstOutput = false; + } + + return cshake.DoOutput(output, outOff, outLen); + } + + public int GetByteLength() + { + return cshake.GetByteLength(); + } + + public int GetDigestSize() + { + return outputLength; + } + + public int GetMacSize() + { + return outputLength; + } + + public void Init(ICipherParameters parameters) + { + KeyParameter kParam = (KeyParameter)parameters; + this.key = Arrays.Clone(kParam.GetKey()); + this.initialised = true; + Reset(); + } + + public void Reset() + { + cshake.Reset(); + + if (key != null) + { + if (bitLength == 128) + { + bytePad(key, 168); + } + else + { + bytePad(key, 136); + } + } + + firstOutput = true; + } + + private void bytePad(byte[] X, int w) + { + byte[] bytes = XofUtilities.LeftEncode(w); + BlockUpdate(bytes, 0, bytes.Length); + byte[] encX = encode(X); + BlockUpdate(encX, 0, encX.Length); + + int required = w - ((bytes.Length + encX.Length) % w); + + if (required > 0 && required != w) + { + while (required > padding.Length) + { + BlockUpdate(padding, 0, padding.Length); + required -= padding.Length; + } + + BlockUpdate(padding, 0, required); + } + } + + private static byte[] encode(byte[] X) + { + return Arrays.Concatenate(XofUtilities.LeftEncode(X.Length * 8), X); + } + + public void Update(byte input) + { + if (!initialised) + throw new InvalidOperationException("KMAC not initialized"); + + cshake.Update(input); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/KMac.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/KMac.cs.meta new file mode 100644 index 0000000..a2d3457 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/KMac.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 021401756b1fbf846b1ca4e4571e8f10 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/Poly1305.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/Poly1305.cs new file mode 100644 index 0000000..c0a660f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/Poly1305.cs @@ -0,0 +1,293 @@ +using System; + +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; + +namespace Org.BouncyCastle.Crypto.Macs +{ + + /// + /// Poly1305 message authentication code, designed by D. J. Bernstein. + /// + /// + /// Poly1305 computes a 128-bit (16 bytes) authenticator, using a 128 bit nonce and a 256 bit key + /// consisting of a 128 bit key applied to an underlying cipher, and a 128 bit key (with 106 + /// effective key bits) used in the authenticator. + /// + /// The polynomial calculation in this implementation is adapted from the public domain poly1305-donna-unrolled C implementation + /// by Andrew M (@floodyberry). + /// + /// + public class Poly1305 + : IMac + { + private const int BlockSize = 16; + + private readonly IBlockCipher cipher; + + private readonly byte[] singleByte = new byte[1]; + + // Initialised state + + /** Polynomial key */ + private uint r0, r1, r2, r3, r4; + + /** Precomputed 5 * r[1..4] */ + private uint s1, s2, s3, s4; + + /** Encrypted nonce */ + private uint k0, k1, k2, k3; + + // Accumulating state + + /** Current block of buffered input */ + private byte[] currentBlock = new byte[BlockSize]; + + /** Current offset in input buffer */ + private int currentBlockOffset = 0; + + /** Polynomial accumulator */ + private uint h0, h1, h2, h3, h4; + + /** + * Constructs a Poly1305 MAC, where the key passed to init() will be used directly. + */ + public Poly1305() + { + this.cipher = null; + } + + /** + * Constructs a Poly1305 MAC, using a 128 bit block cipher. + */ + public Poly1305(IBlockCipher cipher) + { + if (cipher.GetBlockSize() != BlockSize) + { + throw new ArgumentException("Poly1305 requires a 128 bit block cipher."); + } + this.cipher = cipher; + } + + /// + /// Initialises the Poly1305 MAC. + /// + /// a {@link ParametersWithIV} containing a 128 bit nonce and a {@link KeyParameter} with + /// a 256 bit key complying to the {@link Poly1305KeyGenerator Poly1305 key format}. + public void Init(ICipherParameters parameters) + { + byte[] nonce = null; + + if (cipher != null) + { + if (!(parameters is ParametersWithIV)) + throw new ArgumentException("Poly1305 requires an IV when used with a block cipher.", "parameters"); + + ParametersWithIV ivParams = (ParametersWithIV)parameters; + nonce = ivParams.GetIV(); + parameters = ivParams.Parameters; + } + + if (!(parameters is KeyParameter)) + throw new ArgumentException("Poly1305 requires a key."); + + KeyParameter keyParams = (KeyParameter)parameters; + + SetKey(keyParams.GetKey(), nonce); + + Reset(); + } + + private void SetKey(byte[] key, byte[] nonce) + { + if (key.Length != 32) + throw new ArgumentException("Poly1305 key must be 256 bits."); + + if (cipher != null && (nonce == null || nonce.Length != BlockSize)) + throw new ArgumentException("Poly1305 requires a 128 bit IV."); + + // Extract r portion of key (and "clamp" the values) + uint t0 = Pack.LE_To_UInt32(key, 0); + uint t1 = Pack.LE_To_UInt32(key, 4); + uint t2 = Pack.LE_To_UInt32(key, 8); + uint t3 = Pack.LE_To_UInt32(key, 12); + + // NOTE: The masks perform the key "clamping" implicitly + r0 = t0 & 0x03FFFFFFU; + r1 = ((t0 >> 26) | (t1 << 6)) & 0x03FFFF03U; + r2 = ((t1 >> 20) | (t2 << 12)) & 0x03FFC0FFU; + r3 = ((t2 >> 14) | (t3 << 18)) & 0x03F03FFFU; + r4 = (t3 >> 8) & 0x000FFFFFU; + + // Precompute multipliers + s1 = r1 * 5; + s2 = r2 * 5; + s3 = r3 * 5; + s4 = r4 * 5; + + byte[] kBytes; + int kOff; + + if (cipher == null) + { + kBytes = key; + kOff = BlockSize; + } + else + { + // Compute encrypted nonce + kBytes = new byte[BlockSize]; + kOff = 0; + + cipher.Init(true, new KeyParameter(key, BlockSize, BlockSize)); + cipher.ProcessBlock(nonce, 0, kBytes, 0); + } + + k0 = Pack.LE_To_UInt32(kBytes, kOff + 0); + k1 = Pack.LE_To_UInt32(kBytes, kOff + 4); + k2 = Pack.LE_To_UInt32(kBytes, kOff + 8); + k3 = Pack.LE_To_UInt32(kBytes, kOff + 12); + } + + public string AlgorithmName + { + get { return cipher == null ? "Poly1305" : "Poly1305-" + cipher.AlgorithmName; } + } + + public int GetMacSize() + { + return BlockSize; + } + + public void Update(byte input) + { + singleByte[0] = input; + BlockUpdate(singleByte, 0, 1); + } + + public void BlockUpdate(byte[] input, int inOff, int len) + { + int copied = 0; + while (len > copied) + { + if (currentBlockOffset == BlockSize) + { + ProcessBlock(); + currentBlockOffset = 0; + } + + int toCopy = System.Math.Min((len - copied), BlockSize - currentBlockOffset); + Array.Copy(input, copied + inOff, currentBlock, currentBlockOffset, toCopy); + copied += toCopy; + currentBlockOffset += toCopy; + } + + } + + private void ProcessBlock() + { + if (currentBlockOffset < BlockSize) + { + currentBlock[currentBlockOffset] = 1; + for (int i = currentBlockOffset + 1; i < BlockSize; i++) + { + currentBlock[i] = 0; + } + } + + ulong t0 = Pack.LE_To_UInt32(currentBlock, 0); + ulong t1 = Pack.LE_To_UInt32(currentBlock, 4); + ulong t2 = Pack.LE_To_UInt32(currentBlock, 8); + ulong t3 = Pack.LE_To_UInt32(currentBlock, 12); + + h0 += (uint)(t0 & 0x3ffffffU); + h1 += (uint)((((t1 << 32) | t0) >> 26) & 0x3ffffff); + h2 += (uint)((((t2 << 32) | t1) >> 20) & 0x3ffffff); + h3 += (uint)((((t3 << 32) | t2) >> 14) & 0x3ffffff); + h4 += (uint)(t3 >> 8); + + if (currentBlockOffset == BlockSize) + { + h4 += (1 << 24); + } + + ulong tp0 = mul32x32_64(h0,r0) + mul32x32_64(h1,s4) + mul32x32_64(h2,s3) + mul32x32_64(h3,s2) + mul32x32_64(h4,s1); + ulong tp1 = mul32x32_64(h0,r1) + mul32x32_64(h1,r0) + mul32x32_64(h2,s4) + mul32x32_64(h3,s3) + mul32x32_64(h4,s2); + ulong tp2 = mul32x32_64(h0,r2) + mul32x32_64(h1,r1) + mul32x32_64(h2,r0) + mul32x32_64(h3,s4) + mul32x32_64(h4,s3); + ulong tp3 = mul32x32_64(h0,r3) + mul32x32_64(h1,r2) + mul32x32_64(h2,r1) + mul32x32_64(h3,r0) + mul32x32_64(h4,s4); + ulong tp4 = mul32x32_64(h0,r4) + mul32x32_64(h1,r3) + mul32x32_64(h2,r2) + mul32x32_64(h3,r1) + mul32x32_64(h4,r0); + + h0 = (uint)tp0 & 0x3ffffff; tp1 += (tp0 >> 26); + h1 = (uint)tp1 & 0x3ffffff; tp2 += (tp1 >> 26); + h2 = (uint)tp2 & 0x3ffffff; tp3 += (tp2 >> 26); + h3 = (uint)tp3 & 0x3ffffff; tp4 += (tp3 >> 26); + h4 = (uint)tp4 & 0x3ffffff; + h0 += (uint)(tp4 >> 26) * 5; + h1 += (h0 >> 26); h0 &= 0x3ffffff; + } + + public int DoFinal(byte[] output, int outOff) + { + Check.DataLength(output, outOff, BlockSize, "Output buffer is too short."); + + if (currentBlockOffset > 0) + { + // Process padded block + ProcessBlock(); + } + + h1 += (h0 >> 26); h0 &= 0x3ffffff; + h2 += (h1 >> 26); h1 &= 0x3ffffff; + h3 += (h2 >> 26); h2 &= 0x3ffffff; + h4 += (h3 >> 26); h3 &= 0x3ffffff; + h0 += (h4 >> 26) * 5; h4 &= 0x3ffffff; + h1 += (h0 >> 26); h0 &= 0x3ffffff; + + uint g0, g1, g2, g3, g4, b; + g0 = h0 + 5; b = g0 >> 26; g0 &= 0x3ffffff; + g1 = h1 + b; b = g1 >> 26; g1 &= 0x3ffffff; + g2 = h2 + b; b = g2 >> 26; g2 &= 0x3ffffff; + g3 = h3 + b; b = g3 >> 26; g3 &= 0x3ffffff; + g4 = h4 + b - (1 << 26); + + b = (g4 >> 31) - 1; + uint nb = ~b; + h0 = (h0 & nb) | (g0 & b); + h1 = (h1 & nb) | (g1 & b); + h2 = (h2 & nb) | (g2 & b); + h3 = (h3 & nb) | (g3 & b); + h4 = (h4 & nb) | (g4 & b); + + ulong f0, f1, f2, f3; + f0 = ((h0 ) | (h1 << 26)) + (ulong)k0; + f1 = ((h1 >> 6 ) | (h2 << 20)) + (ulong)k1; + f2 = ((h2 >> 12) | (h3 << 14)) + (ulong)k2; + f3 = ((h3 >> 18) | (h4 << 8 )) + (ulong)k3; + + Pack.UInt32_To_LE((uint)f0, output, outOff); + f1 += (f0 >> 32); + Pack.UInt32_To_LE((uint)f1, output, outOff + 4); + f2 += (f1 >> 32); + Pack.UInt32_To_LE((uint)f2, output, outOff + 8); + f3 += (f2 >> 32); + Pack.UInt32_To_LE((uint)f3, output, outOff + 12); + + Reset(); + return BlockSize; + } + + public void Reset() + { + currentBlockOffset = 0; + + h0 = h1 = h2 = h3 = h4 = 0; + } + + private static ulong mul32x32_64(uint i1, uint i2) + { + return ((ulong)i1) * i2; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/Poly1305.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/Poly1305.cs.meta new file mode 100644 index 0000000..724b17d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/Poly1305.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3071244dcb6e18b4ebe3ab304b0908d6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/SipHash.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/SipHash.cs new file mode 100644 index 0000000..e1a19fa --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/SipHash.cs @@ -0,0 +1,199 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; + +namespace Org.BouncyCastle.Crypto.Macs +{ + /// + /// Implementation of SipHash as specified in "SipHash: a fast short-input PRF", by Jean-Philippe + /// Aumasson and Daniel J. Bernstein (https://131002.net/siphash/siphash.pdf). + /// + /// + /// "SipHash is a family of PRFs SipHash-c-d where the integer parameters c and d are the number of + /// compression rounds and the number of finalization rounds. A compression round is identical to a + /// finalization round and this round function is called SipRound. Given a 128-bit key k and a + /// (possibly empty) byte string m, SipHash-c-d returns a 64-bit value..." + /// + public class SipHash + : IMac + { + protected readonly int c, d; + + protected long k0, k1; + protected long v0, v1, v2, v3; + + protected long m = 0; + protected int wordPos = 0; + protected int wordCount = 0; + + /// SipHash-2-4 + public SipHash() + : this(2, 4) + { + } + + /// SipHash-c-d + /// the number of compression rounds + /// the number of finalization rounds + public SipHash(int c, int d) + { + this.c = c; + this.d = d; + } + + public virtual string AlgorithmName + { + get { return "SipHash-" + c + "-" + d; } + } + + public virtual int GetMacSize() + { + return 8; + } + + public virtual void Init(ICipherParameters parameters) + { + KeyParameter keyParameter = parameters as KeyParameter; + if (keyParameter == null) + throw new ArgumentException("must be an instance of KeyParameter", "parameters"); + byte[] key = keyParameter.GetKey(); + if (key.Length != 16) + throw new ArgumentException("must be a 128-bit key", "parameters"); + + this.k0 = (long)Pack.LE_To_UInt64(key, 0); + this.k1 = (long)Pack.LE_To_UInt64(key, 8); + + Reset(); + } + + public virtual void Update(byte input) + { + m = (long)(((ulong)m >> 8) | ((ulong)input << 56)); + + if (++wordPos == 8) + { + ProcessMessageWord(); + wordPos = 0; + } + } + + public virtual void BlockUpdate(byte[] input, int offset, int length) + { + int i = 0, fullWords = length & ~7; + if (wordPos == 0) + { + for (; i < fullWords; i += 8) + { + m = (long)Pack.LE_To_UInt64(input, offset + i); + ProcessMessageWord(); + } + for (; i < length; ++i) + { + m = (long)(((ulong)m >> 8) | ((ulong)input[offset + i] << 56)); + } + wordPos = length - fullWords; + } + else + { + int bits = wordPos << 3; + for (; i < fullWords; i += 8) + { + ulong n = Pack.LE_To_UInt64(input, offset + i); + m = (long)((n << bits) | ((ulong)m >> -bits)); + ProcessMessageWord(); + m = (long)n; + } + for (; i < length; ++i) + { + m = (long)(((ulong)m >> 8) | ((ulong)input[offset + i] << 56)); + + if (++wordPos == 8) + { + ProcessMessageWord(); + wordPos = 0; + } + } + } + } + + public virtual long DoFinal() + { + // NOTE: 2 distinct shifts to avoid "64-bit shift" when wordPos == 0 + m = (long)((ulong)m >> ((7 - wordPos) << 3)); + m = (long)((ulong)m >> 8); + m = (long)((ulong)m | ((ulong)((wordCount << 3) + wordPos) << 56)); + + ProcessMessageWord(); + + v2 ^= 0xffL; + + ApplySipRounds(d); + + long result = v0 ^ v1 ^ v2 ^ v3; + + Reset(); + + return result; + } + + public virtual int DoFinal(byte[] output, int outOff) + { + long result = DoFinal(); + Pack.UInt64_To_LE((ulong)result, output, outOff); + return 8; + } + + public virtual void Reset() + { + v0 = k0 ^ 0x736f6d6570736575L; + v1 = k1 ^ 0x646f72616e646f6dL; + v2 = k0 ^ 0x6c7967656e657261L; + v3 = k1 ^ 0x7465646279746573L; + + m = 0; + wordPos = 0; + wordCount = 0; + } + + protected virtual void ProcessMessageWord() + { + ++wordCount; + v3 ^= m; + ApplySipRounds(c); + v0 ^= m; + } + + protected virtual void ApplySipRounds(int n) + { + long r0 = v0, r1 = v1, r2 = v2, r3 = v3; + + for (int r = 0; r < n; ++r) + { + r0 += r1; + r2 += r3; + r1 = RotateLeft(r1, 13); + r3 = RotateLeft(r3, 16); + r1 ^= r0; + r3 ^= r2; + r0 = RotateLeft(r0, 32); + r2 += r1; + r0 += r3; + r1 = RotateLeft(r1, 17); + r3 = RotateLeft(r3, 21); + r1 ^= r2; + r3 ^= r0; + r2 = RotateLeft(r2, 32); + } + + v0 = r0; v1 = r1; v2 = r2; v3 = r3; + } + + protected static long RotateLeft(long x, int n) + { + ulong ux = (ulong)x; + ux = (ux << n) | (ux >> -n); + return (long)ux; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/SipHash.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/SipHash.cs.meta new file mode 100644 index 0000000..a2baa0c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/SipHash.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a1b6162167e16594da28d252df8f3354 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/SkeinMac.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/SkeinMac.cs new file mode 100644 index 0000000..07eff24 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/SkeinMac.cs @@ -0,0 +1,118 @@ +using System; + +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Macs +{ + + /// + /// Implementation of the Skein parameterised MAC function in 256, 512 and 1024 bit block sizes, + /// based on the Threefish tweakable block cipher. + /// + /// + /// This is the 1.3 version of Skein defined in the Skein hash function submission to the NIST SHA-3 + /// competition in October 2010. + ///

+ /// Skein was designed by Niels Ferguson - Stefan Lucks - Bruce Schneier - Doug Whiting - Mihir + /// Bellare - Tadayoshi Kohno - Jon Callas - Jesse Walker. + /// + /// + /// + public class SkeinMac + : IMac + { + ///

+ /// 256 bit block size - Skein-256 + /// + public const int SKEIN_256 = SkeinEngine.SKEIN_256; + /// + /// 512 bit block size - Skein-512 + /// + public const int SKEIN_512 = SkeinEngine.SKEIN_512; + /// + /// 1024 bit block size - Skein-1024 + /// + public const int SKEIN_1024 = SkeinEngine.SKEIN_1024; + + private readonly SkeinEngine engine; + + /// + /// Constructs a Skein MAC with an internal state size and output size. + /// + /// the internal state size in bits - one of or + /// . + /// the output/MAC size to produce in bits, which must be an integral number of + /// bytes. + public SkeinMac(int stateSizeBits, int digestSizeBits) + { + this.engine = new SkeinEngine(stateSizeBits, digestSizeBits); + } + + public SkeinMac(SkeinMac mac) + { + this.engine = new SkeinEngine(mac.engine); + } + + public string AlgorithmName + { + get { return "Skein-MAC-" + (engine.BlockSize * 8) + "-" + (engine.OutputSize * 8); } + } + + /// + /// Optionally initialises the Skein digest with the provided parameters. + /// + /// See for details on the parameterisation of the Skein hash function. + /// the parameters to apply to this engine, or null to use no parameters. + public void Init(ICipherParameters parameters) + { + SkeinParameters skeinParameters; + if (parameters is SkeinParameters) + { + skeinParameters = (SkeinParameters)parameters; + } + else if (parameters is KeyParameter) + { + skeinParameters = new SkeinParameters.Builder().SetKey(((KeyParameter)parameters).GetKey()).Build(); + } + else + { + throw new ArgumentException("Invalid parameter passed to Skein MAC init - " + + Platform.GetTypeName(parameters)); + } + if (skeinParameters.GetKey() == null) + { + throw new ArgumentException("Skein MAC requires a key parameter."); + } + engine.Init(skeinParameters); + } + + public int GetMacSize() + { + return engine.OutputSize; + } + + public void Reset() + { + engine.Reset(); + } + + public void Update(byte inByte) + { + engine.Update(inByte); + } + + public void BlockUpdate(byte[] input, int inOff, int len) + { + engine.Update(input, inOff, len); + } + + public int DoFinal(byte[] output, int outOff) + { + return engine.DoFinal(output, outOff); + } + + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/SkeinMac.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/SkeinMac.cs.meta new file mode 100644 index 0000000..9fc57b8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/SkeinMac.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b0c814d3e4edd684ca0df922504c54ea +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/VMPCMac.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/VMPCMac.cs new file mode 100644 index 0000000..6f2da07 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/VMPCMac.cs @@ -0,0 +1,173 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Macs +{ + public class VmpcMac + : IMac + { + private byte g; + + private byte n = 0; + private byte[] P = null; + private byte s = 0; + + private byte[] T; + private byte[] workingIV; + + private byte[] workingKey; + + private byte x1, x2, x3, x4; + + public virtual int DoFinal(byte[] output, int outOff) + { + // Execute the Post-Processing Phase + for (int r = 1; r < 25; r++) + { + s = P[(s + P[n & 0xff]) & 0xff]; + + x4 = P[(x4 + x3 + r) & 0xff]; + x3 = P[(x3 + x2 + r) & 0xff]; + x2 = P[(x2 + x1 + r) & 0xff]; + x1 = P[(x1 + s + r) & 0xff]; + T[g & 0x1f] = (byte) (T[g & 0x1f] ^ x1); + T[(g + 1) & 0x1f] = (byte) (T[(g + 1) & 0x1f] ^ x2); + T[(g + 2) & 0x1f] = (byte) (T[(g + 2) & 0x1f] ^ x3); + T[(g + 3) & 0x1f] = (byte) (T[(g + 3) & 0x1f] ^ x4); + g = (byte) ((g + 4) & 0x1f); + + byte temp = P[n & 0xff]; + P[n & 0xff] = P[s & 0xff]; + P[s & 0xff] = temp; + n = (byte) ((n + 1) & 0xff); + } + + // Input T to the IV-phase of the VMPC KSA + for (int m = 0; m < 768; m++) + { + s = P[(s + P[m & 0xff] + T[m & 0x1f]) & 0xff]; + byte temp = P[m & 0xff]; + P[m & 0xff] = P[s & 0xff]; + P[s & 0xff] = temp; + } + + // Store 20 new outputs of the VMPC Stream Cipher input table M + byte[] M = new byte[20]; + for (int i = 0; i < 20; i++) + { + s = P[(s + P[i & 0xff]) & 0xff]; + M[i] = P[(P[(P[s & 0xff]) & 0xff] + 1) & 0xff]; + + byte temp = P[i & 0xff]; + P[i & 0xff] = P[s & 0xff]; + P[s & 0xff] = temp; + } + + Array.Copy(M, 0, output, outOff, M.Length); + Reset(); + + return M.Length; + } + + public virtual string AlgorithmName + { + get { return "VMPC-MAC"; } + } + + public virtual int GetMacSize() + { + return 20; + } + + public virtual void Init(ICipherParameters parameters) + { + if (!(parameters is ParametersWithIV)) + throw new ArgumentException("VMPC-MAC Init parameters must include an IV", "parameters"); + + ParametersWithIV ivParams = (ParametersWithIV) parameters; + KeyParameter key = (KeyParameter) ivParams.Parameters; + + if (!(ivParams.Parameters is KeyParameter)) + throw new ArgumentException("VMPC-MAC Init parameters must include a key", "parameters"); + + this.workingIV = ivParams.GetIV(); + + if (workingIV == null || workingIV.Length < 1 || workingIV.Length > 768) + throw new ArgumentException("VMPC-MAC requires 1 to 768 bytes of IV", "parameters"); + + this.workingKey = key.GetKey(); + + Reset(); + + } + + private void initKey(byte[] keyBytes, byte[] ivBytes) + { + s = 0; + P = new byte[256]; + for (int i = 0; i < 256; i++) + { + P[i] = (byte) i; + } + for (int m = 0; m < 768; m++) + { + s = P[(s + P[m & 0xff] + keyBytes[m % keyBytes.Length]) & 0xff]; + byte temp = P[m & 0xff]; + P[m & 0xff] = P[s & 0xff]; + P[s & 0xff] = temp; + } + for (int m = 0; m < 768; m++) + { + s = P[(s + P[m & 0xff] + ivBytes[m % ivBytes.Length]) & 0xff]; + byte temp = P[m & 0xff]; + P[m & 0xff] = P[s & 0xff]; + P[s & 0xff] = temp; + } + n = 0; + } + + public virtual void Reset() + { + initKey(this.workingKey, this.workingIV); + g = x1 = x2 = x3 = x4 = n = 0; + T = new byte[32]; + for (int i = 0; i < 32; i++) + { + T[i] = 0; + } + } + + public virtual void Update(byte input) + { + s = P[(s + P[n & 0xff]) & 0xff]; + byte c = (byte) (input ^ P[(P[(P[s & 0xff]) & 0xff] + 1) & 0xff]); + + x4 = P[(x4 + x3) & 0xff]; + x3 = P[(x3 + x2) & 0xff]; + x2 = P[(x2 + x1) & 0xff]; + x1 = P[(x1 + s + c) & 0xff]; + T[g & 0x1f] = (byte) (T[g & 0x1f] ^ x1); + T[(g + 1) & 0x1f] = (byte) (T[(g + 1) & 0x1f] ^ x2); + T[(g + 2) & 0x1f] = (byte) (T[(g + 2) & 0x1f] ^ x3); + T[(g + 3) & 0x1f] = (byte) (T[(g + 3) & 0x1f] ^ x4); + g = (byte) ((g + 4) & 0x1f); + + byte temp = P[n & 0xff]; + P[n & 0xff] = P[s & 0xff]; + P[s & 0xff] = temp; + n = (byte) ((n + 1) & 0xff); + } + + public virtual void BlockUpdate(byte[] input, int inOff, int len) + { + if ((inOff + len) > input.Length) + throw new DataLengthException("input buffer too short"); + + for (int i = 0; i < len; i++) + { + Update(input[inOff + i]); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/VMPCMac.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/VMPCMac.cs.meta new file mode 100644 index 0000000..afd47a1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/macs/VMPCMac.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0dee47e15b2a59b4c8a98d42586ccca4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes.meta new file mode 100644 index 0000000..3d026dc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 75bdde0fc938baf4595e80cbea5601b2 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/CbcBlockCipher.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/CbcBlockCipher.cs new file mode 100644 index 0000000..9345fd8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/CbcBlockCipher.cs @@ -0,0 +1,241 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Modes +{ + /** + * implements Cipher-Block-Chaining (CBC) mode on top of a simple cipher. + */ + public class CbcBlockCipher + : IBlockCipher + { + private byte[] IV, cbcV, cbcNextV; + private int blockSize; + private IBlockCipher cipher; + private bool encrypting; + + /** + * Basic constructor. + * + * @param cipher the block cipher to be used as the basis of chaining. + */ + public CbcBlockCipher( + IBlockCipher cipher) + { + this.cipher = cipher; + this.blockSize = cipher.GetBlockSize(); + + this.IV = new byte[blockSize]; + this.cbcV = new byte[blockSize]; + this.cbcNextV = new byte[blockSize]; + } + + /** + * return the underlying block cipher that we are wrapping. + * + * @return the underlying block cipher that we are wrapping. + */ + public IBlockCipher GetUnderlyingCipher() + { + return cipher; + } + + /** + * Initialise the cipher and, possibly, the initialisation vector (IV). + * If an IV isn't passed as part of the parameter, the IV will be all zeros. + * + * @param forEncryption if true the cipher is initialised for + * encryption, if false for decryption. + * @param param the key and other data required by the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public void Init( + bool forEncryption, + ICipherParameters parameters) + { + bool oldEncrypting = this.encrypting; + + this.encrypting = forEncryption; + + if (parameters is ParametersWithIV) + { + ParametersWithIV ivParam = (ParametersWithIV)parameters; + byte[] iv = ivParam.GetIV(); + + if (iv.Length != blockSize) + { + throw new ArgumentException("initialisation vector must be the same length as block size"); + } + + Array.Copy(iv, 0, IV, 0, iv.Length); + + parameters = ivParam.Parameters; + } + + Reset(); + + // if null it's an IV changed only. + if (parameters != null) + { + cipher.Init(encrypting, parameters); + } + else if (oldEncrypting != encrypting) + { + throw new ArgumentException("cannot change encrypting state without providing key."); + } + } + + /** + * return the algorithm name and mode. + * + * @return the name of the underlying algorithm followed by "/CBC". + */ + public string AlgorithmName + { + get { return cipher.AlgorithmName + "/CBC"; } + } + + public bool IsPartialBlockOkay + { + get { return false; } + } + + /** + * return the block size of the underlying cipher. + * + * @return the block size of the underlying cipher. + */ + public int GetBlockSize() + { + return cipher.GetBlockSize(); + } + + /** + * Process one block of input from the array in and write it to + * the out array. + * + * @param in the array containing the input data. + * @param inOff offset into the in array the data starts at. + * @param out the array the output data will be copied into. + * @param outOff the offset into the out array the output will start at. + * @exception DataLengthException if there isn't enough data in in, or + * space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + * @return the number of bytes processed and produced. + */ + public int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + return (encrypting) + ? EncryptBlock(input, inOff, output, outOff) + : DecryptBlock(input, inOff, output, outOff); + } + + /** + * reset the chaining vector back to the IV and reset the underlying + * cipher. + */ + public void Reset() + { + Array.Copy(IV, 0, cbcV, 0, IV.Length); + Array.Clear(cbcNextV, 0, cbcNextV.Length); + + cipher.Reset(); + } + + /** + * Do the appropriate chaining step for CBC mode encryption. + * + * @param in the array containing the data to be encrypted. + * @param inOff offset into the in array the data starts at. + * @param out the array the encrypted data will be copied into. + * @param outOff the offset into the out array the output will start at. + * @exception DataLengthException if there isn't enough data in in, or + * space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + * @return the number of bytes processed and produced. + */ + private int EncryptBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + if ((inOff + blockSize) > input.Length) + { + throw new DataLengthException("input buffer too short"); + } + + /* + * XOR the cbcV and the input, + * then encrypt the cbcV + */ + for (int i = 0; i < blockSize; i++) + { + cbcV[i] ^= input[inOff + i]; + } + + int length = cipher.ProcessBlock(cbcV, 0, outBytes, outOff); + + /* + * copy ciphertext to cbcV + */ + Array.Copy(outBytes, outOff, cbcV, 0, cbcV.Length); + + return length; + } + + /** + * Do the appropriate chaining step for CBC mode decryption. + * + * @param in the array containing the data to be decrypted. + * @param inOff offset into the in array the data starts at. + * @param out the array the decrypted data will be copied into. + * @param outOff the offset into the out array the output will start at. + * @exception DataLengthException if there isn't enough data in in, or + * space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + * @return the number of bytes processed and produced. + */ + private int DecryptBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + if ((inOff + blockSize) > input.Length) + { + throw new DataLengthException("input buffer too short"); + } + + Array.Copy(input, inOff, cbcNextV, 0, blockSize); + + int length = cipher.ProcessBlock(input, inOff, outBytes, outOff); + + /* + * XOR the cbcV and the output + */ + for (int i = 0; i < blockSize; i++) + { + outBytes[outOff + i] ^= cbcV[i]; + } + + /* + * swap the back up buffer into next position + */ + byte[] tmp; + + tmp = cbcV; + cbcV = cbcNextV; + cbcNextV = tmp; + + return length; + } + } + +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/CbcBlockCipher.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/CbcBlockCipher.cs.meta new file mode 100644 index 0000000..5154a6c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/CbcBlockCipher.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 21f29d1e851e7e14c9a7af20e150f4d6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/CcmBlockCipher.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/CcmBlockCipher.cs new file mode 100644 index 0000000..2981fdc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/CcmBlockCipher.cs @@ -0,0 +1,455 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Macs; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Modes +{ + /** + * Implements the Counter with Cipher Block Chaining mode (CCM) detailed in + * NIST Special Publication 800-38C. + *

+ * Note: this mode is a packet mode - it needs all the data up front. + *

+ */ + public class CcmBlockCipher + : IAeadBlockCipher + { + private static readonly int BlockSize = 16; + + private readonly IBlockCipher cipher; + private readonly byte[] macBlock; + private bool forEncryption; + private byte[] nonce; + private byte[] initialAssociatedText; + private int macSize; + private ICipherParameters keyParam; + private readonly MemoryStream associatedText = new MemoryStream(); + private readonly MemoryStream data = new MemoryStream(); + + /** + * Basic constructor. + * + * @param cipher the block cipher to be used. + */ + public CcmBlockCipher( + IBlockCipher cipher) + { + this.cipher = cipher; + this.macBlock = new byte[BlockSize]; + + if (cipher.GetBlockSize() != BlockSize) + throw new ArgumentException("cipher required with a block size of " + BlockSize + "."); + } + + /** + * return the underlying block cipher that we are wrapping. + * + * @return the underlying block cipher that we are wrapping. + */ + public virtual IBlockCipher GetUnderlyingCipher() + { + return cipher; + } + + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + this.forEncryption = forEncryption; + + ICipherParameters cipherParameters; + if (parameters is AeadParameters) + { + AeadParameters param = (AeadParameters) parameters; + + nonce = param.GetNonce(); + initialAssociatedText = param.GetAssociatedText(); + macSize = GetMacSize(forEncryption, param.MacSize); + cipherParameters = param.Key; + } + else if (parameters is ParametersWithIV) + { + ParametersWithIV param = (ParametersWithIV) parameters; + + nonce = param.GetIV(); + initialAssociatedText = null; + macSize = GetMacSize(forEncryption, 64); + cipherParameters = param.Parameters; + } + else + { + throw new ArgumentException("invalid parameters passed to CCM"); + } + + // NOTE: Very basic support for key re-use, but no performance gain from it + if (cipherParameters != null) + { + keyParam = cipherParameters; + } + + if (nonce == null || nonce.Length < 7 || nonce.Length > 13) + throw new ArgumentException("nonce must have length from 7 to 13 octets"); + + Reset(); + } + + public virtual string AlgorithmName + { + get { return cipher.AlgorithmName + "/CCM"; } + } + + public virtual int GetBlockSize() + { + return cipher.GetBlockSize(); + } + + public virtual void ProcessAadByte(byte input) + { + associatedText.WriteByte(input); + } + + public virtual void ProcessAadBytes(byte[] inBytes, int inOff, int len) + { + // TODO: Process AAD online + associatedText.Write(inBytes, inOff, len); + } + + public virtual int ProcessByte( + byte input, + byte[] outBytes, + int outOff) + { + data.WriteByte(input); + + return 0; + } + + public virtual int ProcessBytes( + byte[] inBytes, + int inOff, + int inLen, + byte[] outBytes, + int outOff) + { + Check.DataLength(inBytes, inOff, inLen, "Input buffer too short"); + + data.Write(inBytes, inOff, inLen); + + return 0; + } + + public virtual int DoFinal( + byte[] outBytes, + int outOff) + { +#if PORTABLE + byte[] input = data.ToArray(); + int inLen = input.Length; +#else + byte[] input = data.GetBuffer(); + int inLen = (int)data.Position; +#endif + + int len = ProcessPacket(input, 0, inLen, outBytes, outOff); + + Reset(); + + return len; + } + + public virtual void Reset() + { + cipher.Reset(); + associatedText.SetLength(0); + data.SetLength(0); + } + + /** + * Returns a byte array containing the mac calculated as part of the + * last encrypt or decrypt operation. + * + * @return the last mac calculated. + */ + public virtual byte[] GetMac() + { + return Arrays.CopyOfRange(macBlock, 0, macSize); + } + + public virtual int GetUpdateOutputSize( + int len) + { + return 0; + } + + public virtual int GetOutputSize( + int len) + { + int totalData = (int)data.Length + len; + + if (forEncryption) + { + return totalData + macSize; + } + + return totalData < macSize ? 0 : totalData - macSize; + } + + /** + * Process a packet of data for either CCM decryption or encryption. + * + * @param in data for processing. + * @param inOff offset at which data starts in the input array. + * @param inLen length of the data in the input array. + * @return a byte array containing the processed input.. + * @throws IllegalStateException if the cipher is not appropriately set up. + * @throws InvalidCipherTextException if the input data is truncated or the mac check fails. + */ + public virtual byte[] ProcessPacket(byte[] input, int inOff, int inLen) + { + byte[] output; + + if (forEncryption) + { + output = new byte[inLen + macSize]; + } + else + { + if (inLen < macSize) + throw new InvalidCipherTextException("data too short"); + + output = new byte[inLen - macSize]; + } + + ProcessPacket(input, inOff, inLen, output, 0); + + return output; + } + + /** + * Process a packet of data for either CCM decryption or encryption. + * + * @param in data for processing. + * @param inOff offset at which data starts in the input array. + * @param inLen length of the data in the input array. + * @param output output array. + * @param outOff offset into output array to start putting processed bytes. + * @return the number of bytes added to output. + * @throws IllegalStateException if the cipher is not appropriately set up. + * @throws InvalidCipherTextException if the input data is truncated or the mac check fails. + * @throws DataLengthException if output buffer too short. + */ + public virtual int ProcessPacket(byte[] input, int inOff, int inLen, byte[] output, int outOff) + { + // TODO: handle null keyParam (e.g. via RepeatedKeySpec) + // Need to keep the CTR and CBC Mac parts around and reset + if (keyParam == null) + throw new InvalidOperationException("CCM cipher unitialized."); + + int n = nonce.Length; + int q = 15 - n; + if (q < 4) + { + int limitLen = 1 << (8 * q); + if (inLen >= limitLen) + throw new InvalidOperationException("CCM packet too large for choice of q."); + } + + byte[] iv = new byte[BlockSize]; + iv[0] = (byte)((q - 1) & 0x7); + nonce.CopyTo(iv, 1); + + IBlockCipher ctrCipher = new SicBlockCipher(cipher); + ctrCipher.Init(forEncryption, new ParametersWithIV(keyParam, iv)); + + int outputLen; + int inIndex = inOff; + int outIndex = outOff; + + if (forEncryption) + { + outputLen = inLen + macSize; + Check.OutputLength(output, outOff, outputLen, "Output buffer too short."); + + CalculateMac(input, inOff, inLen, macBlock); + + byte[] encMac = new byte[BlockSize]; + ctrCipher.ProcessBlock(macBlock, 0, encMac, 0); // S0 + + while (inIndex < (inOff + inLen - BlockSize)) // S1... + { + ctrCipher.ProcessBlock(input, inIndex, output, outIndex); + outIndex += BlockSize; + inIndex += BlockSize; + } + + byte[] block = new byte[BlockSize]; + + Array.Copy(input, inIndex, block, 0, inLen + inOff - inIndex); + + ctrCipher.ProcessBlock(block, 0, block, 0); + + Array.Copy(block, 0, output, outIndex, inLen + inOff - inIndex); + + Array.Copy(encMac, 0, output, outOff + inLen, macSize); + } + else + { + if (inLen < macSize) + throw new InvalidCipherTextException("data too short"); + + outputLen = inLen - macSize; + Check.OutputLength(output, outOff, outputLen, "Output buffer too short."); + + Array.Copy(input, inOff + outputLen, macBlock, 0, macSize); + + ctrCipher.ProcessBlock(macBlock, 0, macBlock, 0); + + for (int i = macSize; i != macBlock.Length; i++) + { + macBlock[i] = 0; + } + + while (inIndex < (inOff + outputLen - BlockSize)) + { + ctrCipher.ProcessBlock(input, inIndex, output, outIndex); + outIndex += BlockSize; + inIndex += BlockSize; + } + + byte[] block = new byte[BlockSize]; + + Array.Copy(input, inIndex, block, 0, outputLen - (inIndex - inOff)); + + ctrCipher.ProcessBlock(block, 0, block, 0); + + Array.Copy(block, 0, output, outIndex, outputLen - (inIndex - inOff)); + + byte[] calculatedMacBlock = new byte[BlockSize]; + + CalculateMac(output, outOff, outputLen, calculatedMacBlock); + + if (!Arrays.ConstantTimeAreEqual(macBlock, calculatedMacBlock)) + throw new InvalidCipherTextException("mac check in CCM failed"); + } + + return outputLen; + } + + private int CalculateMac(byte[] data, int dataOff, int dataLen, byte[] macBlock) + { + IMac cMac = new CbcBlockCipherMac(cipher, macSize * 8); + + cMac.Init(keyParam); + + // + // build b0 + // + byte[] b0 = new byte[16]; + + if (HasAssociatedText()) + { + b0[0] |= 0x40; + } + + b0[0] |= (byte)((((cMac.GetMacSize() - 2) / 2) & 0x7) << 3); + + b0[0] |= (byte)(((15 - nonce.Length) - 1) & 0x7); + + Array.Copy(nonce, 0, b0, 1, nonce.Length); + + int q = dataLen; + int count = 1; + while (q > 0) + { + b0[b0.Length - count] = (byte)(q & 0xff); + q >>= 8; + count++; + } + + cMac.BlockUpdate(b0, 0, b0.Length); + + // + // process associated text + // + if (HasAssociatedText()) + { + int extra; + + int textLength = GetAssociatedTextLength(); + if (textLength < ((1 << 16) - (1 << 8))) + { + cMac.Update((byte)(textLength >> 8)); + cMac.Update((byte)textLength); + + extra = 2; + } + else // can't go any higher than 2^32 + { + cMac.Update((byte)0xff); + cMac.Update((byte)0xfe); + cMac.Update((byte)(textLength >> 24)); + cMac.Update((byte)(textLength >> 16)); + cMac.Update((byte)(textLength >> 8)); + cMac.Update((byte)textLength); + + extra = 6; + } + + if (initialAssociatedText != null) + { + cMac.BlockUpdate(initialAssociatedText, 0, initialAssociatedText.Length); + } + if (associatedText.Position > 0) + { +#if PORTABLE + byte[] input = associatedText.ToArray(); + int len = input.Length; +#else + byte[] input = associatedText.GetBuffer(); + int len = (int)associatedText.Position; +#endif + + cMac.BlockUpdate(input, 0, len); + } + + extra = (extra + textLength) % 16; + if (extra != 0) + { + for (int i = extra; i < 16; ++i) + { + cMac.Update((byte)0x00); + } + } + } + + // + // add the text + // + cMac.BlockUpdate(data, dataOff, dataLen); + + return cMac.DoFinal(macBlock, 0); + } + + private int GetMacSize(bool forEncryption, int requestedMacBits) + { + if (forEncryption && (requestedMacBits < 32 || requestedMacBits > 128 || 0 != (requestedMacBits & 15))) + throw new ArgumentException("tag length in octets must be one of {4,6,8,10,12,14,16}"); + + return requestedMacBits >> 3; + } + + private int GetAssociatedTextLength() + { + return (int)associatedText.Length + ((initialAssociatedText == null) ? 0 : initialAssociatedText.Length); + } + + private bool HasAssociatedText() + { + return GetAssociatedTextLength() > 0; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/CcmBlockCipher.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/CcmBlockCipher.cs.meta new file mode 100644 index 0000000..de1b1d5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/CcmBlockCipher.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cb7f7128afcd5f44a94255a2c8a15633 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/CfbBlockCipher.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/CfbBlockCipher.cs new file mode 100644 index 0000000..ed0be40 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/CfbBlockCipher.cs @@ -0,0 +1,227 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Modes +{ + /** + * implements a Cipher-FeedBack (CFB) mode on top of a simple cipher. + */ + public class CfbBlockCipher + : IBlockCipher + { + private byte[] IV; + private byte[] cfbV; + private byte[] cfbOutV; + private bool encrypting; + + private readonly int blockSize; + private readonly IBlockCipher cipher; + + /** + * Basic constructor. + * + * @param cipher the block cipher to be used as the basis of the + * feedback mode. + * @param blockSize the block size in bits (note: a multiple of 8) + */ + public CfbBlockCipher( + IBlockCipher cipher, + int bitBlockSize) + { + if (bitBlockSize < 8 || (bitBlockSize & 7) != 0) + throw new ArgumentException("CFB" + bitBlockSize + " not supported", "bitBlockSize"); + + this.cipher = cipher; + this.blockSize = bitBlockSize / 8; + this.IV = new byte[cipher.GetBlockSize()]; + this.cfbV = new byte[cipher.GetBlockSize()]; + this.cfbOutV = new byte[cipher.GetBlockSize()]; + } + /** + * return the underlying block cipher that we are wrapping. + * + * @return the underlying block cipher that we are wrapping. + */ + public IBlockCipher GetUnderlyingCipher() + { + return cipher; + } + /** + * Initialise the cipher and, possibly, the initialisation vector (IV). + * If an IV isn't passed as part of the parameter, the IV will be all zeros. + * An IV which is too short is handled in FIPS compliant fashion. + * + * @param forEncryption if true the cipher is initialised for + * encryption, if false for decryption. + * @param param the key and other data required by the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public void Init( + bool forEncryption, + ICipherParameters parameters) + { + this.encrypting = forEncryption; + if (parameters is ParametersWithIV) + { + ParametersWithIV ivParam = (ParametersWithIV) parameters; + byte[] iv = ivParam.GetIV(); + int diff = IV.Length - iv.Length; + Array.Copy(iv, 0, IV, diff, iv.Length); + Array.Clear(IV, 0, diff); + + parameters = ivParam.Parameters; + } + Reset(); + + // if it's null, key is to be reused. + if (parameters != null) + { + cipher.Init(true, parameters); + } + } + + /** + * return the algorithm name and mode. + * + * @return the name of the underlying algorithm followed by "/CFB" + * and the block size in bits. + */ + public string AlgorithmName + { + get { return cipher.AlgorithmName + "/CFB" + (blockSize * 8); } + } + + public bool IsPartialBlockOkay + { + get { return true; } + } + + /** + * return the block size we are operating at. + * + * @return the block size we are operating at (in bytes). + */ + public int GetBlockSize() + { + return blockSize; + } + + /** + * Process one block of input from the array in and write it to + * the out array. + * + * @param in the array containing the input data. + * @param inOff offset into the in array the data starts at. + * @param out the array the output data will be copied into. + * @param outOff the offset into the out array the output will start at. + * @exception DataLengthException if there isn't enough data in in, or + * space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + * @return the number of bytes processed and produced. + */ + public int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + return (encrypting) + ? EncryptBlock(input, inOff, output, outOff) + : DecryptBlock(input, inOff, output, outOff); + } + + /** + * Do the appropriate processing for CFB mode encryption. + * + * @param in the array containing the data to be encrypted. + * @param inOff offset into the in array the data starts at. + * @param out the array the encrypted data will be copied into. + * @param outOff the offset into the out array the output will start at. + * @exception DataLengthException if there isn't enough data in in, or + * space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + * @return the number of bytes processed and produced. + */ + public int EncryptBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + if ((inOff + blockSize) > input.Length) + { + throw new DataLengthException("input buffer too short"); + } + if ((outOff + blockSize) > outBytes.Length) + { + throw new DataLengthException("output buffer too short"); + } + cipher.ProcessBlock(cfbV, 0, cfbOutV, 0); + // + // XOR the cfbV with the plaintext producing the ciphertext + // + for (int i = 0; i < blockSize; i++) + { + outBytes[outOff + i] = (byte)(cfbOutV[i] ^ input[inOff + i]); + } + // + // change over the input block. + // + Array.Copy(cfbV, blockSize, cfbV, 0, cfbV.Length - blockSize); + Array.Copy(outBytes, outOff, cfbV, cfbV.Length - blockSize, blockSize); + return blockSize; + } + /** + * Do the appropriate processing for CFB mode decryption. + * + * @param in the array containing the data to be decrypted. + * @param inOff offset into the in array the data starts at. + * @param out the array the encrypted data will be copied into. + * @param outOff the offset into the out array the output will start at. + * @exception DataLengthException if there isn't enough data in in, or + * space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + * @return the number of bytes processed and produced. + */ + public int DecryptBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + if ((inOff + blockSize) > input.Length) + { + throw new DataLengthException("input buffer too short"); + } + if ((outOff + blockSize) > outBytes.Length) + { + throw new DataLengthException("output buffer too short"); + } + cipher.ProcessBlock(cfbV, 0, cfbOutV, 0); + // + // change over the input block. + // + Array.Copy(cfbV, blockSize, cfbV, 0, cfbV.Length - blockSize); + Array.Copy(input, inOff, cfbV, cfbV.Length - blockSize, blockSize); + // + // XOR the cfbV with the ciphertext producing the plaintext + // + for (int i = 0; i < blockSize; i++) + { + outBytes[outOff + i] = (byte)(cfbOutV[i] ^ input[inOff + i]); + } + return blockSize; + } + /** + * reset the chaining vector back to the IV and reset the underlying + * cipher. + */ + public void Reset() + { + Array.Copy(IV, 0, cfbV, 0, IV.Length); + cipher.Reset(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/CfbBlockCipher.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/CfbBlockCipher.cs.meta new file mode 100644 index 0000000..7732691 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/CfbBlockCipher.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dd1bff002f1d8834abd05c03dc4c4ad8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/ChaCha20Poly1305.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/ChaCha20Poly1305.cs new file mode 100644 index 0000000..6ca32d9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/ChaCha20Poly1305.cs @@ -0,0 +1,557 @@ +using System; + +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Macs; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Modes +{ + public class ChaCha20Poly1305 + : IAeadCipher + { + private enum State + { + Uninitialized = 0, + EncInit = 1, + EncAad = 2, + EncData = 3, + EncFinal = 4, + DecInit = 5, + DecAad = 6, + DecData = 7, + DecFinal = 8, + } + + private const int BufSize = 64; + private const int KeySize = 32; + private const int NonceSize = 12; + private const int MacSize = 16; + private static readonly byte[] Zeroes = new byte[MacSize - 1]; + + private const ulong AadLimit = ulong.MaxValue; + private const ulong DataLimit = ((1UL << 32) - 1) * 64; + + private readonly ChaCha7539Engine mChacha20; + private readonly IMac mPoly1305; + + private readonly byte[] mKey = new byte[KeySize]; + private readonly byte[] mNonce = new byte[NonceSize]; + private readonly byte[] mBuf = new byte[BufSize + MacSize]; + private readonly byte[] mMac = new byte[MacSize]; + + private byte[] mInitialAad; + + private ulong mAadCount; + private ulong mDataCount; + private State mState = State.Uninitialized; + private int mBufPos; + + public ChaCha20Poly1305() + : this(new Poly1305()) + { + } + + public ChaCha20Poly1305(IMac poly1305) + { + if (null == poly1305) + throw new ArgumentNullException("poly1305"); + if (MacSize != poly1305.GetMacSize()) + throw new ArgumentException("must be a 128-bit MAC", "poly1305"); + + this.mChacha20 = new ChaCha7539Engine(); + this.mPoly1305 = poly1305; + } + + public virtual string AlgorithmName + { + get { return "ChaCha20Poly1305"; } + } + + public virtual void Init(bool forEncryption, ICipherParameters parameters) + { + KeyParameter initKeyParam; + byte[] initNonce; + ICipherParameters chacha20Params; + + if (parameters is AeadParameters) + { + AeadParameters aeadParams = (AeadParameters)parameters; + + int macSizeBits = aeadParams.MacSize; + if ((MacSize * 8) != macSizeBits) + throw new ArgumentException("Invalid value for MAC size: " + macSizeBits); + + initKeyParam = aeadParams.Key; + initNonce = aeadParams.GetNonce(); + chacha20Params = new ParametersWithIV(initKeyParam, initNonce); + + this.mInitialAad = aeadParams.GetAssociatedText(); + } + else if (parameters is ParametersWithIV) + { + ParametersWithIV ivParams = (ParametersWithIV)parameters; + + initKeyParam = (KeyParameter)ivParams.Parameters; + initNonce = ivParams.GetIV(); + chacha20Params = ivParams; + + this.mInitialAad = null; + } + else + { + throw new ArgumentException("invalid parameters passed to ChaCha20Poly1305", "parameters"); + } + + // Validate key + if (null == initKeyParam) + { + if (State.Uninitialized == mState) + throw new ArgumentException("Key must be specified in initial init"); + } + else + { + if (KeySize != initKeyParam.GetKey().Length) + throw new ArgumentException("Key must be 256 bits"); + } + + // Validate nonce + if (null == initNonce || NonceSize != initNonce.Length) + throw new ArgumentException("Nonce must be 96 bits"); + + // Check for encryption with reused nonce + if (State.Uninitialized != mState && forEncryption && Arrays.AreEqual(mNonce, initNonce)) + { + if (null == initKeyParam || Arrays.AreEqual(mKey, initKeyParam.GetKey())) + throw new ArgumentException("cannot reuse nonce for ChaCha20Poly1305 encryption"); + } + + if (null != initKeyParam) + { + Array.Copy(initKeyParam.GetKey(), 0, mKey, 0, KeySize); + } + + Array.Copy(initNonce, 0, mNonce, 0, NonceSize); + + mChacha20.Init(true, chacha20Params); + + this.mState = forEncryption ? State.EncInit : State.DecInit; + + Reset(true, false); + } + + public virtual int GetOutputSize(int len) + { + int total = System.Math.Max(0, len) + mBufPos; + + switch (mState) + { + case State.DecInit: + case State.DecAad: + case State.DecData: + return System.Math.Max(0, total - MacSize); + case State.EncInit: + case State.EncAad: + case State.EncData: + return total + MacSize; + default: + throw new InvalidOperationException(); + } + } + + public virtual int GetUpdateOutputSize(int len) + { + int total = System.Math.Max(0, len) + mBufPos; + + switch (mState) + { + case State.DecInit: + case State.DecAad: + case State.DecData: + total = System.Math.Max(0, total - MacSize); + break; + case State.EncInit: + case State.EncAad: + case State.EncData: + break; + default: + throw new InvalidOperationException(); + } + + return total - (total % BufSize); + } + + public virtual void ProcessAadByte(byte input) + { + CheckAad(); + + this.mAadCount = IncrementCount(mAadCount, 1, AadLimit); + mPoly1305.Update(input); + } + + public virtual void ProcessAadBytes(byte[] inBytes, int inOff, int len) + { + if (null == inBytes) + throw new ArgumentNullException("inBytes"); + if (inOff < 0) + throw new ArgumentException("cannot be negative", "inOff"); + if (len < 0) + throw new ArgumentException("cannot be negative", "len"); + Check.DataLength(inBytes, inOff, len, "input buffer too short"); + + CheckAad(); + + if (len > 0) + { + this.mAadCount = IncrementCount(mAadCount, (uint)len, AadLimit); + mPoly1305.BlockUpdate(inBytes, inOff, len); + } + } + + public virtual int ProcessByte(byte input, byte[] outBytes, int outOff) + { + CheckData(); + + switch (mState) + { + case State.DecData: + { + mBuf[mBufPos] = input; + if (++mBufPos == mBuf.Length) + { + mPoly1305.BlockUpdate(mBuf, 0, BufSize); + ProcessData(mBuf, 0, BufSize, outBytes, outOff); + Array.Copy(mBuf, BufSize, mBuf, 0, MacSize); + this.mBufPos = MacSize; + return BufSize; + } + + return 0; + } + case State.EncData: + { + mBuf[mBufPos] = input; + if (++mBufPos == BufSize) + { + ProcessData(mBuf, 0, BufSize, outBytes, outOff); + mPoly1305.BlockUpdate(outBytes, outOff, BufSize); + this.mBufPos = 0; + return BufSize; + } + + return 0; + } + default: + throw new InvalidOperationException(); + } + } + + public virtual int ProcessBytes(byte[] inBytes, int inOff, int len, byte[] outBytes, int outOff) + { + if (null == inBytes) + throw new ArgumentNullException("inBytes"); + /* + * Following bc-java, we allow null when no output is expected (e.g. based on a + * GetUpdateOutputSize call). + */ + if (null == outBytes) + { + //throw new ArgumentNullException("outBytes"); + } + if (inOff < 0) + throw new ArgumentException("cannot be negative", "inOff"); + if (len < 0) + throw new ArgumentException("cannot be negative", "len"); + Check.DataLength(inBytes, inOff, len, "input buffer too short"); + if (outOff < 0) + throw new ArgumentException("cannot be negative", "outOff"); + + CheckData(); + + int resultLen = 0; + + switch (mState) + { + case State.DecData: + { + for (int i = 0; i < len; ++i) + { + mBuf[mBufPos] = inBytes[inOff + i]; + if (++mBufPos == mBuf.Length) + { + mPoly1305.BlockUpdate(mBuf, 0, BufSize); + ProcessData(mBuf, 0, BufSize, outBytes, outOff + resultLen); + Array.Copy(mBuf, BufSize, mBuf, 0, MacSize); + this.mBufPos = MacSize; + resultLen += BufSize; + } + } + break; + } + case State.EncData: + { + if (mBufPos != 0) + { + while (len > 0) + { + --len; + mBuf[mBufPos] = inBytes[inOff++]; + if (++mBufPos == BufSize) + { + ProcessData(mBuf, 0, BufSize, outBytes, outOff); + mPoly1305.BlockUpdate(outBytes, outOff, BufSize); + this.mBufPos = 0; + resultLen = BufSize; + break; + } + } + } + + while (len >= BufSize) + { + ProcessData(inBytes, inOff, BufSize, outBytes, outOff + resultLen); + mPoly1305.BlockUpdate(outBytes, outOff + resultLen, BufSize); + inOff += BufSize; + len -= BufSize; + resultLen += BufSize; + } + + if (len > 0) + { + Array.Copy(inBytes, inOff, mBuf, 0, len); + this.mBufPos = len; + } + break; + } + default: + throw new InvalidOperationException(); + } + + return resultLen; + } + + public virtual int DoFinal(byte[] outBytes, int outOff) + { + if (null == outBytes) + throw new ArgumentNullException("outBytes"); + if (outOff < 0) + throw new ArgumentException("cannot be negative", "outOff"); + + CheckData(); + + Array.Clear(mMac, 0, MacSize); + + int resultLen = 0; + + switch (mState) + { + case State.DecData: + { + if (mBufPos < MacSize) + throw new InvalidCipherTextException("data too short"); + + resultLen = mBufPos - MacSize; + + Check.OutputLength(outBytes, outOff, resultLen, "output buffer too short"); + + if (resultLen > 0) + { + mPoly1305.BlockUpdate(mBuf, 0, resultLen); + ProcessData(mBuf, 0, resultLen, outBytes, outOff); + } + + FinishData(State.DecFinal); + + if (!Arrays.ConstantTimeAreEqual(MacSize, mMac, 0, mBuf, resultLen)) + { + throw new InvalidCipherTextException("mac check in ChaCha20Poly1305 failed"); + } + + break; + } + case State.EncData: + { + resultLen = mBufPos + MacSize; + + Check.OutputLength(outBytes, outOff, resultLen, "output buffer too short"); + + if (mBufPos > 0) + { + ProcessData(mBuf, 0, mBufPos, outBytes, outOff); + mPoly1305.BlockUpdate(outBytes, outOff, mBufPos); + } + + FinishData(State.EncFinal); + + Array.Copy(mMac, 0, outBytes, outOff + mBufPos, MacSize); + break; + } + default: + throw new InvalidOperationException(); + } + + Reset(false, true); + + return resultLen; + } + + public virtual byte[] GetMac() + { + return Arrays.Clone(mMac); + } + + public virtual void Reset() + { + Reset(true, true); + } + + private void CheckAad() + { + switch (mState) + { + case State.DecInit: + this.mState = State.DecAad; + break; + case State.EncInit: + this.mState = State.EncAad; + break; + case State.DecAad: + case State.EncAad: + break; + case State.EncFinal: + throw new InvalidOperationException("ChaCha20Poly1305 cannot be reused for encryption"); + default: + throw new InvalidOperationException(); + } + } + + private void CheckData() + { + switch (mState) + { + case State.DecInit: + case State.DecAad: + FinishAad(State.DecData); + break; + case State.EncInit: + case State.EncAad: + FinishAad(State.EncData); + break; + case State.DecData: + case State.EncData: + break; + case State.EncFinal: + throw new InvalidOperationException("ChaCha20Poly1305 cannot be reused for encryption"); + default: + throw new InvalidOperationException(); + } + } + + private void FinishAad(State nextState) + { + PadMac(mAadCount); + + this.mState = nextState; + } + + private void FinishData(State nextState) + { + PadMac(mDataCount); + + byte[] lengths = new byte[16]; + Pack.UInt64_To_LE(mAadCount, lengths, 0); + Pack.UInt64_To_LE(mDataCount, lengths, 8); + mPoly1305.BlockUpdate(lengths, 0, 16); + + mPoly1305.DoFinal(mMac, 0); + + this.mState = nextState; + } + + private ulong IncrementCount(ulong count, uint increment, ulong limit) + { + if (count > (limit - increment)) + throw new InvalidOperationException ("Limit exceeded"); + + return count + increment; + } + + private void InitMac() + { + byte[] firstBlock = new byte[64]; + try + { + mChacha20.ProcessBytes(firstBlock, 0, 64, firstBlock, 0); + mPoly1305.Init(new KeyParameter(firstBlock, 0, 32)); + } + finally + { + Array.Clear(firstBlock, 0, 64); + } + } + + private void PadMac(ulong count) + { + int partial = (int)count & (MacSize - 1); + if (0 != partial) + { + mPoly1305.BlockUpdate(Zeroes, 0, MacSize - partial); + } + } + + private void ProcessData(byte[] inBytes, int inOff, int inLen, byte[] outBytes, int outOff) + { + Check.OutputLength(outBytes, outOff, inLen, "output buffer too short"); + + mChacha20.ProcessBytes(inBytes, inOff, inLen, outBytes, outOff); + + this.mDataCount = IncrementCount(mDataCount, (uint)inLen, DataLimit); + } + + private void Reset(bool clearMac, bool resetCipher) + { + Array.Clear(mBuf, 0, mBuf.Length); + + if (clearMac) + { + Array.Clear(mMac, 0, mMac.Length); + } + + this.mAadCount = 0UL; + this.mDataCount = 0UL; + this.mBufPos = 0; + + switch (mState) + { + case State.DecInit: + case State.EncInit: + break; + case State.DecAad: + case State.DecData: + case State.DecFinal: + this.mState = State.DecInit; + break; + case State.EncAad: + case State.EncData: + case State.EncFinal: + this.mState = State.EncFinal; + return; + default: + throw new InvalidOperationException(); + } + + if (resetCipher) + { + mChacha20.Reset(); + } + + InitMac(); + + if (null != mInitialAad) + { + ProcessAadBytes(mInitialAad, 0, mInitialAad.Length); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/ChaCha20Poly1305.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/ChaCha20Poly1305.cs.meta new file mode 100644 index 0000000..163e70b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/ChaCha20Poly1305.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 24e33d50fd426ba41a5cba58642865ec +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/CtsBlockCipher.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/CtsBlockCipher.cs new file mode 100644 index 0000000..ff37844 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/CtsBlockCipher.cs @@ -0,0 +1,253 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Modes +{ + /** + * A Cipher Text Stealing (CTS) mode cipher. CTS allows block ciphers to + * be used to produce cipher text which is the same outLength as the plain text. + */ + public class CtsBlockCipher + : BufferedBlockCipher + { + private readonly int blockSize; + + /** + * Create a buffered block cipher that uses Cipher Text Stealing + * + * @param cipher the underlying block cipher this buffering object wraps. + */ + public CtsBlockCipher( + IBlockCipher cipher) + { + // TODO Should this test for acceptable ones instead? + if (cipher is OfbBlockCipher || cipher is CfbBlockCipher) + throw new ArgumentException("CtsBlockCipher can only accept ECB, or CBC ciphers"); + + this.cipher = cipher; + + blockSize = cipher.GetBlockSize(); + + buf = new byte[blockSize * 2]; + bufOff = 0; + } + + /** + * return the size of the output buffer required for an update of 'length' bytes. + * + * @param length the outLength of the input. + * @return the space required to accommodate a call to update + * with length bytes of input. + */ + public override int GetUpdateOutputSize( + int length) + { + int total = length + bufOff; + int leftOver = total % buf.Length; + + if (leftOver == 0) + { + return total - buf.Length; + } + + return total - leftOver; + } + + /** + * return the size of the output buffer required for an update plus a + * doFinal with an input of length bytes. + * + * @param length the outLength of the input. + * @return the space required to accommodate a call to update and doFinal + * with length bytes of input. + */ + public override int GetOutputSize( + int length) + { + return length + bufOff; + } + + /** + * process a single byte, producing an output block if necessary. + * + * @param in the input byte. + * @param out the space for any output that might be produced. + * @param outOff the offset from which the output will be copied. + * @return the number of output bytes copied to out. + * @exception DataLengthException if there isn't enough space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + */ + public override int ProcessByte( + byte input, + byte[] output, + int outOff) + { + int resultLen = 0; + + if (bufOff == buf.Length) + { + resultLen = cipher.ProcessBlock(buf, 0, output, outOff); + Debug.Assert(resultLen == blockSize); + + Array.Copy(buf, blockSize, buf, 0, blockSize); + bufOff = blockSize; + } + + buf[bufOff++] = input; + + return resultLen; + } + + /** + * process an array of bytes, producing output if necessary. + * + * @param in the input byte array. + * @param inOff the offset at which the input data starts. + * @param length the number of bytes to be copied out of the input array. + * @param out the space for any output that might be produced. + * @param outOff the offset from which the output will be copied. + * @return the number of output bytes copied to out. + * @exception DataLengthException if there isn't enough space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + */ + public override int ProcessBytes( + byte[] input, + int inOff, + int length, + byte[] output, + int outOff) + { + if (length < 0) + { + throw new ArgumentException("Can't have a negative input outLength!"); + } + + int blockSize = GetBlockSize(); + int outLength = GetUpdateOutputSize(length); + + if (outLength > 0) + { + if ((outOff + outLength) > output.Length) + { + throw new DataLengthException("output buffer too short"); + } + } + + int resultLen = 0; + int gapLen = buf.Length - bufOff; + + if (length > gapLen) + { + Array.Copy(input, inOff, buf, bufOff, gapLen); + + resultLen += cipher.ProcessBlock(buf, 0, output, outOff); + Array.Copy(buf, blockSize, buf, 0, blockSize); + + bufOff = blockSize; + + length -= gapLen; + inOff += gapLen; + + while (length > blockSize) + { + Array.Copy(input, inOff, buf, bufOff, blockSize); + resultLen += cipher.ProcessBlock(buf, 0, output, outOff + resultLen); + Array.Copy(buf, blockSize, buf, 0, blockSize); + + length -= blockSize; + inOff += blockSize; + } + } + + Array.Copy(input, inOff, buf, bufOff, length); + + bufOff += length; + + return resultLen; + } + + /** + * Process the last block in the buffer. + * + * @param out the array the block currently being held is copied into. + * @param outOff the offset at which the copying starts. + * @return the number of output bytes copied to out. + * @exception DataLengthException if there is insufficient space in out for + * the output. + * @exception InvalidOperationException if the underlying cipher is not + * initialised. + * @exception InvalidCipherTextException if cipher text decrypts wrongly (in + * case the exception will never Get thrown). + */ + public override int DoFinal( + byte[] output, + int outOff) + { + if (bufOff + outOff > output.Length) + { + throw new DataLengthException("output buffer too small in doFinal"); + } + + int blockSize = cipher.GetBlockSize(); + int length = bufOff - blockSize; + byte[] block = new byte[blockSize]; + + if (forEncryption) + { + cipher.ProcessBlock(buf, 0, block, 0); + + if (bufOff < blockSize) + { + throw new DataLengthException("need at least one block of input for CTS"); + } + + for (int i = bufOff; i != buf.Length; i++) + { + buf[i] = block[i - blockSize]; + } + + for (int i = blockSize; i != bufOff; i++) + { + buf[i] ^= block[i - blockSize]; + } + + IBlockCipher c = (cipher is CbcBlockCipher) + ? ((CbcBlockCipher)cipher).GetUnderlyingCipher() + : cipher; + + c.ProcessBlock(buf, blockSize, output, outOff); + + Array.Copy(block, 0, output, outOff + blockSize, length); + } + else + { + byte[] lastBlock = new byte[blockSize]; + + IBlockCipher c = (cipher is CbcBlockCipher) + ? ((CbcBlockCipher)cipher).GetUnderlyingCipher() + : cipher; + + c.ProcessBlock(buf, 0, block, 0); + + for (int i = blockSize; i != bufOff; i++) + { + lastBlock[i - blockSize] = (byte)(block[i - blockSize] ^ buf[i]); + } + + Array.Copy(buf, blockSize, block, 0, length); + + cipher.ProcessBlock(block, 0, output, outOff); + Array.Copy(lastBlock, 0, output, outOff + blockSize, length); + } + + int offset = bufOff; + + Reset(); + + return offset; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/CtsBlockCipher.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/CtsBlockCipher.cs.meta new file mode 100644 index 0000000..9432d81 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/CtsBlockCipher.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 57689d7b4d63a4a4ab4efdc70dd37f86 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/EAXBlockCipher.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/EAXBlockCipher.cs new file mode 100644 index 0000000..624f385 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/EAXBlockCipher.cs @@ -0,0 +1,379 @@ +using System; + +using Org.BouncyCastle.Crypto.Macs; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Modes +{ + /** + * A Two-Pass Authenticated-Encryption Scheme Optimized for Simplicity and + * Efficiency - by M. Bellare, P. Rogaway, D. Wagner. + * + * http://www.cs.ucdavis.edu/~rogaway/papers/eax.pdf + * + * EAX is an AEAD scheme based on CTR and OMAC1/CMAC, that uses a single block + * cipher to encrypt and authenticate data. It's on-line (the length of a + * message isn't needed to begin processing it), has good performances, it's + * simple and provably secure (provided the underlying block cipher is secure). + * + * Of course, this implementations is NOT thread-safe. + */ + public class EaxBlockCipher + : IAeadBlockCipher + { + private enum Tag : byte { N, H, C }; + + private SicBlockCipher cipher; + + private bool forEncryption; + + private int blockSize; + + private IMac mac; + + private byte[] nonceMac; + private byte[] associatedTextMac; + private byte[] macBlock; + + private int macSize; + private byte[] bufBlock; + private int bufOff; + + private bool cipherInitialized; + private byte[] initialAssociatedText; + + /** + * Constructor that accepts an instance of a block cipher engine. + * + * @param cipher the engine to use + */ + public EaxBlockCipher( + IBlockCipher cipher) + { + blockSize = cipher.GetBlockSize(); + mac = new CMac(cipher); + macBlock = new byte[blockSize]; + associatedTextMac = new byte[mac.GetMacSize()]; + nonceMac = new byte[mac.GetMacSize()]; + this.cipher = new SicBlockCipher(cipher); + } + + public virtual string AlgorithmName + { + get { return cipher.GetUnderlyingCipher().AlgorithmName + "/EAX"; } + } + + public virtual IBlockCipher GetUnderlyingCipher() + { + return cipher; + } + + public virtual int GetBlockSize() + { + return cipher.GetBlockSize(); + } + + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + this.forEncryption = forEncryption; + + byte[] nonce; + ICipherParameters keyParam; + + if (parameters is AeadParameters) + { + AeadParameters param = (AeadParameters) parameters; + + nonce = param.GetNonce(); + initialAssociatedText = param.GetAssociatedText(); + macSize = param.MacSize / 8; + keyParam = param.Key; + } + else if (parameters is ParametersWithIV) + { + ParametersWithIV param = (ParametersWithIV) parameters; + + nonce = param.GetIV(); + initialAssociatedText = null; + macSize = mac.GetMacSize() / 2; + keyParam = param.Parameters; + } + else + { + throw new ArgumentException("invalid parameters passed to EAX"); + } + + bufBlock = new byte[forEncryption ? blockSize : (blockSize + macSize)]; + + byte[] tag = new byte[blockSize]; + + // Key reuse implemented in CBC mode of underlying CMac + mac.Init(keyParam); + + tag[blockSize - 1] = (byte)Tag.N; + mac.BlockUpdate(tag, 0, blockSize); + mac.BlockUpdate(nonce, 0, nonce.Length); + mac.DoFinal(nonceMac, 0); + + // Same BlockCipher underlies this and the mac, so reuse last key on cipher + cipher.Init(true, new ParametersWithIV(null, nonceMac)); + + Reset(); + } + + private void InitCipher() + { + if (cipherInitialized) + { + return; + } + + cipherInitialized = true; + + mac.DoFinal(associatedTextMac, 0); + + byte[] tag = new byte[blockSize]; + tag[blockSize - 1] = (byte)Tag.C; + mac.BlockUpdate(tag, 0, blockSize); + } + + private void CalculateMac() + { + byte[] outC = new byte[blockSize]; + mac.DoFinal(outC, 0); + + for (int i = 0; i < macBlock.Length; i++) + { + macBlock[i] = (byte)(nonceMac[i] ^ associatedTextMac[i] ^ outC[i]); + } + } + + public virtual void Reset() + { + Reset(true); + } + + private void Reset( + bool clearMac) + { + cipher.Reset(); // TODO Redundant since the mac will reset it? + mac.Reset(); + + bufOff = 0; + Array.Clear(bufBlock, 0, bufBlock.Length); + + if (clearMac) + { + Array.Clear(macBlock, 0, macBlock.Length); + } + + byte[] tag = new byte[blockSize]; + tag[blockSize - 1] = (byte)Tag.H; + mac.BlockUpdate(tag, 0, blockSize); + + cipherInitialized = false; + + if (initialAssociatedText != null) + { + ProcessAadBytes(initialAssociatedText, 0, initialAssociatedText.Length); + } + } + + public virtual void ProcessAadByte(byte input) + { + if (cipherInitialized) + { + throw new InvalidOperationException("AAD data cannot be added after encryption/decryption processing has begun."); + } + mac.Update(input); + } + + public virtual void ProcessAadBytes(byte[] inBytes, int inOff, int len) + { + if (cipherInitialized) + { + throw new InvalidOperationException("AAD data cannot be added after encryption/decryption processing has begun."); + } + mac.BlockUpdate(inBytes, inOff, len); + } + + public virtual int ProcessByte( + byte input, + byte[] outBytes, + int outOff) + { + InitCipher(); + + return Process(input, outBytes, outOff); + } + + public virtual int ProcessBytes( + byte[] inBytes, + int inOff, + int len, + byte[] outBytes, + int outOff) + { + InitCipher(); + + int resultLen = 0; + + for (int i = 0; i != len; i++) + { + resultLen += Process(inBytes[inOff + i], outBytes, outOff + resultLen); + } + + return resultLen; + } + + public virtual int DoFinal( + byte[] outBytes, + int outOff) + { + InitCipher(); + + int extra = bufOff; + byte[] tmp = new byte[bufBlock.Length]; + + bufOff = 0; + + if (forEncryption) + { + Check.OutputLength(outBytes, outOff, extra + macSize, "Output buffer too short"); + + cipher.ProcessBlock(bufBlock, 0, tmp, 0); + + Array.Copy(tmp, 0, outBytes, outOff, extra); + + mac.BlockUpdate(tmp, 0, extra); + + CalculateMac(); + + Array.Copy(macBlock, 0, outBytes, outOff + extra, macSize); + + Reset(false); + + return extra + macSize; + } + else + { + if (extra < macSize) + throw new InvalidCipherTextException("data too short"); + + Check.OutputLength(outBytes, outOff, extra - macSize, "Output buffer too short"); + + if (extra > macSize) + { + mac.BlockUpdate(bufBlock, 0, extra - macSize); + + cipher.ProcessBlock(bufBlock, 0, tmp, 0); + + Array.Copy(tmp, 0, outBytes, outOff, extra - macSize); + } + + CalculateMac(); + + if (!VerifyMac(bufBlock, extra - macSize)) + throw new InvalidCipherTextException("mac check in EAX failed"); + + Reset(false); + + return extra - macSize; + } + } + + public virtual byte[] GetMac() + { + byte[] mac = new byte[macSize]; + + Array.Copy(macBlock, 0, mac, 0, macSize); + + return mac; + } + + public virtual int GetUpdateOutputSize( + int len) + { + int totalData = len + bufOff; + if (!forEncryption) + { + if (totalData < macSize) + { + return 0; + } + totalData -= macSize; + } + return totalData - totalData % blockSize; + } + + public virtual int GetOutputSize( + int len) + { + int totalData = len + bufOff; + + if (forEncryption) + { + return totalData + macSize; + } + + return totalData < macSize ? 0 : totalData - macSize; + } + + private int Process( + byte b, + byte[] outBytes, + int outOff) + { + bufBlock[bufOff++] = b; + + if (bufOff == bufBlock.Length) + { + Check.OutputLength(outBytes, outOff, blockSize, "Output buffer is too short"); + + // TODO Could move the ProcessByte(s) calls to here +// InitCipher(); + + int size; + + if (forEncryption) + { + size = cipher.ProcessBlock(bufBlock, 0, outBytes, outOff); + + mac.BlockUpdate(outBytes, outOff, blockSize); + } + else + { + mac.BlockUpdate(bufBlock, 0, blockSize); + + size = cipher.ProcessBlock(bufBlock, 0, outBytes, outOff); + } + + bufOff = 0; + if (!forEncryption) + { + Array.Copy(bufBlock, blockSize, bufBlock, 0, macSize); + bufOff = macSize; + } + + return size; + } + + return 0; + } + + private bool VerifyMac(byte[] mac, int off) + { + int nonEqual = 0; + + for (int i = 0; i < macSize; i++) + { + nonEqual |= (macBlock[i] ^ mac[off + i]); + } + + return nonEqual == 0; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/EAXBlockCipher.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/EAXBlockCipher.cs.meta new file mode 100644 index 0000000..8515ded --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/EAXBlockCipher.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 834bbbcb9cb29dc4cba6f0020e8bb3a4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/GCMBlockCipher.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/GCMBlockCipher.cs new file mode 100644 index 0000000..88b413f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/GCMBlockCipher.cs @@ -0,0 +1,645 @@ +using System; + +using Org.BouncyCastle.Crypto.Macs; +using Org.BouncyCastle.Crypto.Modes.Gcm; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Modes +{ + /// + /// Implements the Galois/Counter mode (GCM) detailed in + /// NIST Special Publication 800-38D. + /// + public class GcmBlockCipher + : IAeadBlockCipher + { + private const int BlockSize = 16; + + private readonly IBlockCipher cipher; + private readonly IGcmMultiplier multiplier; + private IGcmExponentiator exp; + + // These fields are set by Init and not modified by processing + private bool forEncryption; + private bool initialised; + private int macSize; + private byte[] lastKey; + private byte[] nonce; + private byte[] initialAssociatedText; + private byte[] H; + private byte[] J0; + + // These fields are modified during processing + private byte[] bufBlock; + private byte[] macBlock; + private byte[] S, S_at, S_atPre; + private byte[] counter; + private uint blocksRemaining; + private int bufOff; + private ulong totalLength; + private byte[] atBlock; + private int atBlockPos; + private ulong atLength; + private ulong atLengthPre; + + public GcmBlockCipher( + IBlockCipher c) + : this(c, null) + { + } + + public GcmBlockCipher( + IBlockCipher c, + IGcmMultiplier m) + { + if (c.GetBlockSize() != BlockSize) + throw new ArgumentException("cipher required with a block size of " + BlockSize + "."); + + if (m == null) + { + m = new Tables4kGcmMultiplier(); + } + + this.cipher = c; + this.multiplier = m; + } + + public virtual string AlgorithmName + { + get { return cipher.AlgorithmName + "/GCM"; } + } + + public IBlockCipher GetUnderlyingCipher() + { + return cipher; + } + + public virtual int GetBlockSize() + { + return BlockSize; + } + + /// + /// MAC sizes from 32 bits to 128 bits (must be a multiple of 8) are supported. The default is 128 bits. + /// Sizes less than 96 are not recommended, but are supported for specialized applications. + /// + public virtual void Init( + bool forEncryption, + ICipherParameters parameters) + { + this.forEncryption = forEncryption; + this.macBlock = null; + this.initialised = true; + + KeyParameter keyParam; + byte[] newNonce = null; + + if (parameters is AeadParameters) + { + AeadParameters param = (AeadParameters)parameters; + + newNonce = param.GetNonce(); + initialAssociatedText = param.GetAssociatedText(); + + int macSizeBits = param.MacSize; + if (macSizeBits < 32 || macSizeBits > 128 || macSizeBits % 8 != 0) + { + throw new ArgumentException("Invalid value for MAC size: " + macSizeBits); + } + + macSize = macSizeBits / 8; + keyParam = param.Key; + } + else if (parameters is ParametersWithIV) + { + ParametersWithIV param = (ParametersWithIV)parameters; + + newNonce = param.GetIV(); + initialAssociatedText = null; + macSize = 16; + keyParam = (KeyParameter)param.Parameters; + } + else + { + throw new ArgumentException("invalid parameters passed to GCM"); + } + + int bufLength = forEncryption ? BlockSize : (BlockSize + macSize); + this.bufBlock = new byte[bufLength]; + + if (newNonce == null || newNonce.Length < 1) + { + throw new ArgumentException("IV must be at least 1 byte"); + } + + if (forEncryption) + { + if (nonce != null && Arrays.AreEqual(nonce, newNonce)) + { + if (keyParam == null) + { + throw new ArgumentException("cannot reuse nonce for GCM encryption"); + } + if (lastKey != null && Arrays.AreEqual(lastKey, keyParam.GetKey())) + { + throw new ArgumentException("cannot reuse nonce for GCM encryption"); + } + } + } + + nonce = newNonce; + if (keyParam != null) + { + lastKey = keyParam.GetKey(); + } + + // TODO Restrict macSize to 16 if nonce length not 12? + + // Cipher always used in forward mode + // if keyParam is null we're reusing the last key. + if (keyParam != null) + { + cipher.Init(true, keyParam); + + this.H = new byte[BlockSize]; + cipher.ProcessBlock(H, 0, H, 0); + + // if keyParam is null we're reusing the last key and the multiplier doesn't need re-init + multiplier.Init(H); + exp = null; + } + else if (this.H == null) + { + throw new ArgumentException("Key must be specified in initial init"); + } + + this.J0 = new byte[BlockSize]; + + if (nonce.Length == 12) + { + Array.Copy(nonce, 0, J0, 0, nonce.Length); + this.J0[BlockSize - 1] = 0x01; + } + else + { + gHASH(J0, nonce, nonce.Length); + byte[] X = new byte[BlockSize]; + Pack.UInt64_To_BE((ulong)nonce.Length * 8UL, X, 8); + gHASHBlock(J0, X); + } + + this.S = new byte[BlockSize]; + this.S_at = new byte[BlockSize]; + this.S_atPre = new byte[BlockSize]; + this.atBlock = new byte[BlockSize]; + this.atBlockPos = 0; + this.atLength = 0; + this.atLengthPre = 0; + this.counter = Arrays.Clone(J0); + this.blocksRemaining = uint.MaxValue - 1; // page 8, len(P) <= 2^39 - 256, 1 block used by tag + this.bufOff = 0; + this.totalLength = 0; + + if (initialAssociatedText != null) + { + ProcessAadBytes(initialAssociatedText, 0, initialAssociatedText.Length); + } + } + + public virtual byte[] GetMac() + { + return macBlock == null + ? new byte[macSize] + : Arrays.Clone(macBlock); + } + + public virtual int GetOutputSize( + int len) + { + int totalData = len + bufOff; + + if (forEncryption) + { + return totalData + macSize; + } + + return totalData < macSize ? 0 : totalData - macSize; + } + + public virtual int GetUpdateOutputSize( + int len) + { + int totalData = len + bufOff; + if (!forEncryption) + { + if (totalData < macSize) + { + return 0; + } + totalData -= macSize; + } + return totalData - totalData % BlockSize; + } + + public virtual void ProcessAadByte(byte input) + { + CheckStatus(); + + atBlock[atBlockPos] = input; + if (++atBlockPos == BlockSize) + { + // Hash each block as it fills + gHASHBlock(S_at, atBlock); + atBlockPos = 0; + atLength += BlockSize; + } + } + + public virtual void ProcessAadBytes(byte[] inBytes, int inOff, int len) + { + CheckStatus(); + + for (int i = 0; i < len; ++i) + { + atBlock[atBlockPos] = inBytes[inOff + i]; + if (++atBlockPos == BlockSize) + { + // Hash each block as it fills + gHASHBlock(S_at, atBlock); + atBlockPos = 0; + atLength += BlockSize; + } + } + } + + private void InitCipher() + { + if (atLength > 0) + { + Array.Copy(S_at, 0, S_atPre, 0, BlockSize); + atLengthPre = atLength; + } + + // Finish hash for partial AAD block + if (atBlockPos > 0) + { + gHASHPartial(S_atPre, atBlock, 0, atBlockPos); + atLengthPre += (uint)atBlockPos; + } + + if (atLengthPre > 0) + { + Array.Copy(S_atPre, 0, S, 0, BlockSize); + } + } + + public virtual int ProcessByte( + byte input, + byte[] output, + int outOff) + { + CheckStatus(); + + bufBlock[bufOff] = input; + if (++bufOff == bufBlock.Length) + { + ProcessBlock(bufBlock, 0, output, outOff); + if (forEncryption) + { + bufOff = 0; + } + else + { + Array.Copy(bufBlock, BlockSize, bufBlock, 0, macSize); + bufOff = macSize; + } + return BlockSize; + } + return 0; + } + + public virtual int ProcessBytes( + byte[] input, + int inOff, + int len, + byte[] output, + int outOff) + { + CheckStatus(); + + Check.DataLength(input, inOff, len, "input buffer too short"); + + int resultLen = 0; + + if (forEncryption) + { + if (bufOff != 0) + { + while (len > 0) + { + --len; + bufBlock[bufOff] = input[inOff++]; + if (++bufOff == BlockSize) + { + ProcessBlock(bufBlock, 0, output, outOff); + bufOff = 0; + resultLen += BlockSize; + break; + } + } + } + + while (len >= BlockSize) + { + ProcessBlock(input, inOff, output, outOff + resultLen); + inOff += BlockSize; + len -= BlockSize; + resultLen += BlockSize; + } + + if (len > 0) + { + Array.Copy(input, inOff, bufBlock, 0, len); + bufOff = len; + } + } + else + { + for (int i = 0; i < len; ++i) + { + bufBlock[bufOff] = input[inOff + i]; + if (++bufOff == bufBlock.Length) + { + ProcessBlock(bufBlock, 0, output, outOff + resultLen); + Array.Copy(bufBlock, BlockSize, bufBlock, 0, macSize); + bufOff = macSize; + resultLen += BlockSize; + } + } + } + + return resultLen; + } + + public int DoFinal(byte[] output, int outOff) + { + CheckStatus(); + + if (totalLength == 0) + { + InitCipher(); + } + + int extra = bufOff; + + if (forEncryption) + { + Check.OutputLength(output, outOff, extra + macSize, "Output buffer too short"); + } + else + { + if (extra < macSize) + throw new InvalidCipherTextException("data too short"); + + extra -= macSize; + + Check.OutputLength(output, outOff, extra, "Output buffer too short"); + } + + if (extra > 0) + { + ProcessPartial(bufBlock, 0, extra, output, outOff); + } + + atLength += (uint)atBlockPos; + + if (atLength > atLengthPre) + { + /* + * Some AAD was sent after the cipher started. We determine the difference b/w the hash value + * we actually used when the cipher started (S_atPre) and the final hash value calculated (S_at). + * Then we carry this difference forward by multiplying by H^c, where c is the number of (full or + * partial) cipher-text blocks produced, and adjust the current hash. + */ + + // Finish hash for partial AAD block + if (atBlockPos > 0) + { + gHASHPartial(S_at, atBlock, 0, atBlockPos); + } + + // Find the difference between the AAD hashes + if (atLengthPre > 0) + { + GcmUtilities.Xor(S_at, S_atPre); + } + + // Number of cipher-text blocks produced + long c = (long)(((totalLength * 8) + 127) >> 7); + + // Calculate the adjustment factor + byte[] H_c = new byte[16]; + if (exp == null) + { + exp = new BasicGcmExponentiator(); + exp.Init(H); + } + exp.ExponentiateX(c, H_c); + + // Carry the difference forward + GcmUtilities.Multiply(S_at, H_c); + + // Adjust the current hash + GcmUtilities.Xor(S, S_at); + } + + // Final gHASH + byte[] X = new byte[BlockSize]; + Pack.UInt64_To_BE(atLength * 8UL, X, 0); + Pack.UInt64_To_BE(totalLength * 8UL, X, 8); + + gHASHBlock(S, X); + + // T = MSBt(GCTRk(J0,S)) + byte[] tag = new byte[BlockSize]; + cipher.ProcessBlock(J0, 0, tag, 0); + GcmUtilities.Xor(tag, S); + + int resultLen = extra; + + // We place into macBlock our calculated value for T + this.macBlock = new byte[macSize]; + Array.Copy(tag, 0, macBlock, 0, macSize); + + if (forEncryption) + { + // Append T to the message + Array.Copy(macBlock, 0, output, outOff + bufOff, macSize); + resultLen += macSize; + } + else + { + // Retrieve the T value from the message and compare to calculated one + byte[] msgMac = new byte[macSize]; + Array.Copy(bufBlock, extra, msgMac, 0, macSize); + if (!Arrays.ConstantTimeAreEqual(this.macBlock, msgMac)) + throw new InvalidCipherTextException("mac check in GCM failed"); + } + + Reset(false); + + return resultLen; + } + + public virtual void Reset() + { + Reset(true); + } + + private void Reset( + bool clearMac) + { + cipher.Reset(); + + // note: we do not reset the nonce. + + S = new byte[BlockSize]; + S_at = new byte[BlockSize]; + S_atPre = new byte[BlockSize]; + atBlock = new byte[BlockSize]; + atBlockPos = 0; + atLength = 0; + atLengthPre = 0; + counter = Arrays.Clone(J0); + blocksRemaining = uint.MaxValue - 1; + bufOff = 0; + totalLength = 0; + + if (bufBlock != null) + { + Arrays.Fill(bufBlock, 0); + } + + if (clearMac) + { + macBlock = null; + } + + if (forEncryption) + { + initialised = false; + } + else + { + if (initialAssociatedText != null) + { + ProcessAadBytes(initialAssociatedText, 0, initialAssociatedText.Length); + } + } + } + + private void ProcessBlock(byte[] buf, int bufOff, byte[] output, int outOff) + { + Check.OutputLength(output, outOff, BlockSize, "Output buffer too short"); + + if (totalLength == 0) + { + InitCipher(); + } + + byte[] ctrBlock = new byte[BlockSize]; + GetNextCtrBlock(ctrBlock); + + if (forEncryption) + { + GcmUtilities.Xor(ctrBlock, buf, bufOff); + gHASHBlock(S, ctrBlock); + Array.Copy(ctrBlock, 0, output, outOff, BlockSize); + } + else + { + gHASHBlock(S, buf, bufOff); + GcmUtilities.Xor(ctrBlock, 0, buf, bufOff, output, outOff); + } + + totalLength += BlockSize; + } + + private void ProcessPartial(byte[] buf, int off, int len, byte[] output, int outOff) + { + byte[] ctrBlock = new byte[BlockSize]; + GetNextCtrBlock(ctrBlock); + + if (forEncryption) + { + GcmUtilities.Xor(buf, off, ctrBlock, 0, len); + gHASHPartial(S, buf, off, len); + } + else + { + gHASHPartial(S, buf, off, len); + GcmUtilities.Xor(buf, off, ctrBlock, 0, len); + } + + Array.Copy(buf, off, output, outOff, len); + totalLength += (uint)len; + } + + private void gHASH(byte[] Y, byte[] b, int len) + { + for (int pos = 0; pos < len; pos += BlockSize) + { + int num = System.Math.Min(len - pos, BlockSize); + gHASHPartial(Y, b, pos, num); + } + } + + private void gHASHBlock(byte[] Y, byte[] b) + { + GcmUtilities.Xor(Y, b); + multiplier.MultiplyH(Y); + } + + private void gHASHBlock(byte[] Y, byte[] b, int off) + { + GcmUtilities.Xor(Y, b, off); + multiplier.MultiplyH(Y); + } + + private void gHASHPartial(byte[] Y, byte[] b, int off, int len) + { + GcmUtilities.Xor(Y, b, off, len); + multiplier.MultiplyH(Y); + } + + private void GetNextCtrBlock(byte[] block) + { + if (blocksRemaining == 0) + throw new InvalidOperationException("Attempt to process too many blocks"); + + blocksRemaining--; + + uint c = 1; + c += counter[15]; counter[15] = (byte)c; c >>= 8; + c += counter[14]; counter[14] = (byte)c; c >>= 8; + c += counter[13]; counter[13] = (byte)c; c >>= 8; + c += counter[12]; counter[12] = (byte)c; + + cipher.ProcessBlock(counter, 0, block, 0); + } + + private void CheckStatus() + { + if (!initialised) + { + if (forEncryption) + { + throw new InvalidOperationException("GCM cipher cannot be reused for encryption"); + } + throw new InvalidOperationException("GCM cipher needs to be initialised"); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/GCMBlockCipher.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/GCMBlockCipher.cs.meta new file mode 100644 index 0000000..2f3fcef --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/GCMBlockCipher.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 69c0f019f2116a545b4c78e2756966ea +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/GOFBBlockCipher.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/GOFBBlockCipher.cs new file mode 100644 index 0000000..436b58a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/GOFBBlockCipher.cs @@ -0,0 +1,234 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Modes +{ + /** + * implements the GOST 28147 OFB counter mode (GCTR). + */ + public class GOfbBlockCipher + : IBlockCipher + { + private byte[] IV; + private byte[] ofbV; + private byte[] ofbOutV; + + private readonly int blockSize; + private readonly IBlockCipher cipher; + + bool firstStep = true; + int N3; + int N4; + const int C1 = 16843012; //00000001000000010000000100000100 + const int C2 = 16843009; //00000001000000010000000100000001 + + /** + * Basic constructor. + * + * @param cipher the block cipher to be used as the basis of the + * counter mode (must have a 64 bit block size). + */ + public GOfbBlockCipher( + IBlockCipher cipher) + { + this.cipher = cipher; + this.blockSize = cipher.GetBlockSize(); + + if (blockSize != 8) + { + throw new ArgumentException("GCTR only for 64 bit block ciphers"); + } + + this.IV = new byte[cipher.GetBlockSize()]; + this.ofbV = new byte[cipher.GetBlockSize()]; + this.ofbOutV = new byte[cipher.GetBlockSize()]; + } + + /** + * return the underlying block cipher that we are wrapping. + * + * @return the underlying block cipher that we are wrapping. + */ + public IBlockCipher GetUnderlyingCipher() + { + return cipher; + } + + /** + * Initialise the cipher and, possibly, the initialisation vector (IV). + * If an IV isn't passed as part of the parameter, the IV will be all zeros. + * An IV which is too short is handled in FIPS compliant fashion. + * + * @param encrypting if true the cipher is initialised for + * encryption, if false for decryption. + * @param parameters the key and other data required by the cipher. + * @exception ArgumentException if the parameters argument is inappropriate. + */ + public void Init( + bool forEncryption, //ignored by this CTR mode + ICipherParameters parameters) + { + firstStep = true; + N3 = 0; + N4 = 0; + + if (parameters is ParametersWithIV) + { + ParametersWithIV ivParam = (ParametersWithIV)parameters; + byte[] iv = ivParam.GetIV(); + + if (iv.Length < IV.Length) + { + // prepend the supplied IV with zeros (per FIPS PUB 81) + Array.Copy(iv, 0, IV, IV.Length - iv.Length, iv.Length); + for (int i = 0; i < IV.Length - iv.Length; i++) + { + IV[i] = 0; + } + } + else + { + Array.Copy(iv, 0, IV, 0, IV.Length); + } + + parameters = ivParam.Parameters; + } + + Reset(); + + // if it's null, key is to be reused. + if (parameters != null) + { + cipher.Init(true, parameters); + } + } + + /** + * return the algorithm name and mode. + * + * @return the name of the underlying algorithm followed by "/GCTR" + * and the block size in bits + */ + public string AlgorithmName + { + get { return cipher.AlgorithmName + "/GCTR"; } + } + + public bool IsPartialBlockOkay + { + get { return true; } + } + + /** + * return the block size we are operating at (in bytes). + * + * @return the block size we are operating at (in bytes). + */ + public int GetBlockSize() + { + return blockSize; + } + + /** + * Process one block of input from the array in and write it to + * the out array. + * + * @param in the array containing the input data. + * @param inOff offset into the in array the data starts at. + * @param out the array the output data will be copied into. + * @param outOff the offset into the out array the output will start at. + * @exception DataLengthException if there isn't enough data in in, or + * space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + * @return the number of bytes processed and produced. + */ + public int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + if ((inOff + blockSize) > input.Length) + { + throw new DataLengthException("input buffer too short"); + } + + if ((outOff + blockSize) > output.Length) + { + throw new DataLengthException("output buffer too short"); + } + + if (firstStep) + { + firstStep = false; + cipher.ProcessBlock(ofbV, 0, ofbOutV, 0); + N3 = bytesToint(ofbOutV, 0); + N4 = bytesToint(ofbOutV, 4); + } + N3 += C2; + N4 += C1; + if (N4 < C1) // addition is mod (2**32 - 1) + { + if (N4 > 0) + { + N4++; + } + } + intTobytes(N3, ofbV, 0); + intTobytes(N4, ofbV, 4); + + cipher.ProcessBlock(ofbV, 0, ofbOutV, 0); + + // + // XOR the ofbV with the plaintext producing the cipher text (and + // the next input block). + // + for (int i = 0; i < blockSize; i++) + { + output[outOff + i] = (byte)(ofbOutV[i] ^ input[inOff + i]); + } + + // + // change over the input block. + // + Array.Copy(ofbV, blockSize, ofbV, 0, ofbV.Length - blockSize); + Array.Copy(ofbOutV, 0, ofbV, ofbV.Length - blockSize, blockSize); + + return blockSize; + } + + /** + * reset the feedback vector back to the IV and reset the underlying + * cipher. + */ + public void Reset() + { + Array.Copy(IV, 0, ofbV, 0, IV.Length); + + cipher.Reset(); + } + + //array of bytes to type int + private int bytesToint( + byte[] inBytes, + int inOff) + { + return (int)((inBytes[inOff + 3] << 24) & 0xff000000) + ((inBytes[inOff + 2] << 16) & 0xff0000) + + ((inBytes[inOff + 1] << 8) & 0xff00) + (inBytes[inOff] & 0xff); + } + + //int to array of bytes + private void intTobytes( + int num, + byte[] outBytes, + int outOff) + { + outBytes[outOff + 3] = (byte)(num >> 24); + outBytes[outOff + 2] = (byte)(num >> 16); + outBytes[outOff + 1] = (byte)(num >> 8); + outBytes[outOff] = (byte)num; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/GOFBBlockCipher.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/GOFBBlockCipher.cs.meta new file mode 100644 index 0000000..b2375d3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/GOFBBlockCipher.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 16d0b52be0b752642ad2c4d9bed5cb19 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/GcmSivBlockCipher.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/GcmSivBlockCipher.cs new file mode 100644 index 0000000..9615931 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/GcmSivBlockCipher.cs @@ -0,0 +1,931 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Modes.Gcm; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Crypto.Modes +{ + /** + * GCM-SIV Mode. + *

It should be noted that the specified limit of 236 bytes is not supported. This is because all bytes are + * cached in a ByteArrayOutputStream object (which has a limit of a little less than 231 bytes), + * and are output on the DoFinal() call (which can only process a maximum of 231 bytes).

+ *

The practical limit of 231 - 24 bytes is policed, and attempts to breach the limit will be rejected

+ *

In order to properly support the higher limit, an extended form of ByteArrayOutputStream would be needed + * which would use multiple arrays to store the data. In addition, a new doOutput method would be required (similar + * to that in XOF digests), which would allow the data to be output over multiple calls. Alternatively an extended + * form of ByteArrayInputStream could be used to deliver the data.

+ */ + public class GcmSivBlockCipher + : IAeadBlockCipher + { + /// The buffer length. + private static readonly int BUFLEN = 16; + + /// The halfBuffer length. + private static readonly int HALFBUFLEN = BUFLEN >> 1; + + /// The nonce length. + private static readonly int NONCELEN = 12; + + /** + * The maximum data length (AEAD/PlainText). Due to implementation constraints this is restricted to the maximum + * array length (https://programming.guide/java/array-maximum-length.html) minus the BUFLEN to allow for the MAC + */ + private static readonly int MAX_DATALEN = Int32.MaxValue - 8 - BUFLEN; + + /** + * The top bit mask. + */ + private static readonly byte MASK = (byte)0x80; + + /** + * The addition constant. + */ + private static readonly byte ADD = (byte)0xE1; + + /** + * The initialisation flag. + */ + private static readonly int INIT = 1; + + /** + * The aeadComplete flag. + */ + private static readonly int AEAD_COMPLETE = 2; + + /** + * The cipher. + */ + private readonly IBlockCipher theCipher; + + /** + * The multiplier. + */ + private readonly IGcmMultiplier theMultiplier; + + /** + * The gHash buffer. + */ + internal readonly byte[] theGHash = new byte[BUFLEN]; + + /** + * The reverse buffer. + */ + internal readonly byte[] theReverse = new byte[BUFLEN]; + + /** + * The aeadHasher. + */ + private readonly GcmSivHasher theAEADHasher; + + /** + * The dataHasher. + */ + private readonly GcmSivHasher theDataHasher; + + /** + * The plainDataStream. + */ + private GcmSivCache thePlain; + + /** + * The encryptedDataStream (decryption only). + */ + private GcmSivCache theEncData; + + /** + * Are we encrypting? + */ + private bool forEncryption; + + /** + * The initialAEAD. + */ + private byte[] theInitialAEAD; + + /** + * The nonce. + */ + private byte[] theNonce; + + /** + * The flags. + */ + private int theFlags; + + /** + * Constructor. + */ + public GcmSivBlockCipher() + : this(new AesEngine()) + { + } + + /** + * Constructor. + * @param pCipher the underlying cipher + */ + public GcmSivBlockCipher(IBlockCipher pCipher) + : this(pCipher, new Tables4kGcmMultiplier()) + { + } + + /** + * Constructor. + * @param pCipher the underlying cipher + * @param pMultiplier the multiplier + */ + public GcmSivBlockCipher(IBlockCipher pCipher, IGcmMultiplier pMultiplier) + { + /* Ensure that the cipher is the correct size */ + if (pCipher.GetBlockSize() != BUFLEN) + throw new ArgumentException("Cipher required with a block size of " + BUFLEN + "."); + + /* Store parameters */ + theCipher = pCipher; + theMultiplier = pMultiplier; + + /* Create the hashers */ + theAEADHasher = new GcmSivHasher(this); + theDataHasher = new GcmSivHasher(this); + } + + public virtual IBlockCipher GetUnderlyingCipher() + { + return theCipher; + } + + public virtual int GetBlockSize() + { + return theCipher.GetBlockSize(); + } + + public virtual void Init(bool pEncrypt, ICipherParameters cipherParameters) + { + /* Set defaults */ + byte[] myInitialAEAD = null; + byte[] myNonce = null; + KeyParameter myKey = null; + + /* Access parameters */ + if (cipherParameters is AeadParameters) + { + AeadParameters myAEAD = (AeadParameters)cipherParameters; + myInitialAEAD = myAEAD.GetAssociatedText(); + myNonce = myAEAD.GetNonce(); + myKey = myAEAD.Key; + } + else if (cipherParameters is ParametersWithIV) + { + ParametersWithIV myParms = (ParametersWithIV)cipherParameters; + myNonce = myParms.GetIV(); + myKey = (KeyParameter)myParms.Parameters; + } + else + { + throw new ArgumentException("invalid parameters passed to GCM_SIV"); + } + + /* Check nonceSize */ + if (myNonce == null || myNonce.Length != NONCELEN) + { + throw new ArgumentException("Invalid nonce"); + } + + /* Check keysize */ + if (myKey == null) + { + throw new ArgumentException("Invalid key"); + } + + byte[] k = myKey.GetKey(); + + if (k.Length != BUFLEN + && k.Length != (BUFLEN << 1)) + { + throw new ArgumentException("Invalid key"); + } + + /* Reset details */ + forEncryption = pEncrypt; + theInitialAEAD = myInitialAEAD; + theNonce = myNonce; + + /* Initialise the keys */ + deriveKeys(myKey); + ResetStreams(); + } + + public virtual string AlgorithmName + { + get { return theCipher.AlgorithmName + "-GCM-SIV"; } + } + + /** + * check AEAD status. + * @param pLen the aeadLength + */ + private void CheckAeadStatus(int pLen) + { + /* Check we are initialised */ + if ((theFlags & INIT) == 0) + { + throw new InvalidOperationException("Cipher is not initialised"); + } + + /* Check AAD is allowed */ + if ((theFlags & AEAD_COMPLETE) != 0) + { + throw new InvalidOperationException("AEAD data cannot be processed after ordinary data"); + } + + /* Make sure that we haven't breached AEAD data limit */ + if ((long)theAEADHasher.getBytesProcessed() + Int64.MinValue > (MAX_DATALEN - pLen) + Int64.MinValue) + { + throw new InvalidOperationException("AEAD byte count exceeded"); + } + } + + /** + * check status. + * @param pLen the dataLength + */ + private void CheckStatus(int pLen) + { + /* Check we are initialised */ + if ((theFlags & INIT) == 0) + { + throw new InvalidOperationException("Cipher is not initialised"); + } + + /* Complete the AEAD section if this is the first data */ + if ((theFlags & AEAD_COMPLETE) == 0) + { + theAEADHasher.completeHash(); + theFlags |= AEAD_COMPLETE; + } + + /* Make sure that we haven't breached data limit */ + long dataLimit = MAX_DATALEN; + long currBytes = thePlain.Length; + if (!forEncryption) + { + dataLimit += BUFLEN; + currBytes = theEncData.Length; + } + if (currBytes + System.Int64.MinValue + > (dataLimit - pLen) + System.Int64.MinValue) + { + throw new InvalidOperationException("byte count exceeded"); + } + } + + public virtual void ProcessAadByte(byte pByte) + { + /* Check that we can supply AEAD */ + CheckAeadStatus(1); + + /* Process the aead */ + theAEADHasher.updateHash(pByte); + } + + public virtual void ProcessAadBytes(byte[] pData, int pOffset, int pLen) + { + /* Check that we can supply AEAD */ + CheckAeadStatus(pLen); + + /* Check input buffer */ + CheckBuffer(pData, pOffset, pLen, false); + + /* Process the aead */ + theAEADHasher.updateHash(pData, pOffset, pLen); + } + + public virtual int ProcessByte(byte pByte, byte[] pOutput, int pOutOffset) + { + /* Check that we have initialised */ + CheckStatus(1); + + /* Store the data */ + if (forEncryption) + { + thePlain.WriteByte(pByte); + theDataHasher.updateHash(pByte); + } + else + { + theEncData.WriteByte(pByte); + } + + /* No data returned */ + return 0; + } + + public virtual int ProcessBytes(byte[] pData, int pOffset, int pLen, byte[] pOutput, int pOutOffset) + { + /* Check that we have initialised */ + CheckStatus(pLen); + + /* Check input buffer */ + CheckBuffer(pData, pOffset, pLen, false); + + /* Store the data */ + if (forEncryption) + { + thePlain.Write(pData, pOffset, pLen); + theDataHasher.updateHash(pData, pOffset, pLen); + } + else + { + theEncData.Write(pData, pOffset, pLen); + } + + /* No data returned */ + return 0; + } + + public virtual int DoFinal(byte[] pOutput, int pOffset) + { + /* Check that we have initialised */ + CheckStatus(0); + + /* Check output buffer */ + CheckBuffer(pOutput, pOffset, GetOutputSize(0), true); + + /* If we are encrypting */ + if (forEncryption) + { + /* Derive the tag */ + byte[] myTag = calculateTag(); + + /* encrypt the plain text */ + int myDataLen = BUFLEN + encryptPlain(myTag, pOutput, pOffset); + + /* Add the tag to the output */ + Array.Copy(myTag, 0, pOutput, pOffset + (int)thePlain.Length, BUFLEN); + + /* Reset the streams */ + ResetStreams(); + return myDataLen; + + /* else we are decrypting */ + } + else + { + /* decrypt to plain text */ + decryptPlain(); + + /* Release plain text */ + int myDataLen = Streams.WriteBufTo(thePlain, pOutput, pOffset); + + /* Reset the streams */ + ResetStreams(); + return myDataLen; + } + } + + public virtual byte[] GetMac() + { + throw new InvalidOperationException(); + } + + public virtual int GetUpdateOutputSize(int pLen) + { + return 0; + } + + public virtual int GetOutputSize(int pLen) + { + if (forEncryption) + { + return (int)(pLen + thePlain.Length + BUFLEN); + } + int myCurr = (int)(pLen + theEncData.Length); + return myCurr > BUFLEN ? myCurr - BUFLEN : 0; + } + + public virtual void Reset() + { + ResetStreams(); + } + + /** + * Reset Streams. + */ + private void ResetStreams() + { + /* Clear the plainText buffer */ + if (thePlain != null) + { + thePlain.Position = 0L; + Streams.WriteZeroes(thePlain, thePlain.Capacity); + } + + /* Reset hashers */ + theAEADHasher.Reset(); + theDataHasher.Reset(); + + /* Recreate streams (to release memory) */ + thePlain = new GcmSivCache(); + theEncData = forEncryption ? null : new GcmSivCache(); + + /* Initialise AEAD if required */ + theFlags &= ~AEAD_COMPLETE; + Arrays.Fill(theGHash, (byte)0); + if (theInitialAEAD != null) + { + theAEADHasher.updateHash(theInitialAEAD, 0, theInitialAEAD.Length); + } + } + + /** + * Obtain buffer length (allowing for null). + * @param pBuffer the buffere + * @return the length + */ + private static int bufLength(byte[] pBuffer) + { + return pBuffer == null ? 0 : pBuffer.Length; + } + + /** + * Check buffer. + * @param pBuffer the buffer + * @param pOffset the offset + * @param pLen the length + * @param pOutput is this an output buffer? + */ + private static void CheckBuffer(byte[] pBuffer, int pOffset, int pLen, bool pOutput) + { + /* Access lengths */ + int myBufLen = bufLength(pBuffer); + int myLast = pOffset + pLen; + + /* Check for negative values and buffer overflow */ + bool badLen = pLen < 0 || pOffset < 0 || myLast < 0; + if (badLen || myLast > myBufLen) + { + throw pOutput + ? new OutputLengthException("Output buffer too short.") + : new DataLengthException("Input buffer too short."); + } + } + + /** + * encrypt data stream. + * @param pCounter the counter + * @param pTarget the target buffer + * @param pOffset the target offset + * @return the length of data encrypted + */ + private int encryptPlain(byte[] pCounter, byte[] pTarget, int pOffset) + { + /* Access buffer and length */ +#if PORTABLE + byte[] thePlainBuf = thePlain.ToArray(); + int thePlainLen = thePlainBuf.Length; +#else + byte[] thePlainBuf = thePlain.GetBuffer(); + int thePlainLen = (int)thePlain.Length; +#endif + + byte[] mySrc = thePlainBuf; + byte[] myCounter = Arrays.Clone(pCounter); + myCounter[BUFLEN - 1] |= MASK; + byte[] myMask = new byte[BUFLEN]; + long myRemaining = thePlainLen; + int myOff = 0; + + /* While we have data to process */ + while (myRemaining > 0) + { + /* Generate the next mask */ + theCipher.ProcessBlock(myCounter, 0, myMask, 0); + + /* Xor data into mask */ + int myLen = (int)System.Math.Min(BUFLEN, myRemaining); + xorBlock(myMask, mySrc, myOff, myLen); + + /* Copy encrypted data to output */ + Array.Copy(myMask, 0, pTarget, pOffset + myOff, myLen); + + /* Adjust counters */ + myRemaining -= myLen; + myOff += myLen; + incrementCounter(myCounter); + } + + /* Return the amount of data processed */ + return thePlainLen; + } + + /** + * decrypt data stream. + * @throws InvalidCipherTextException on data too short or mac check failed + */ + private void decryptPlain() + { + /* Access buffer and length */ +#if PORTABLE + byte[] theEncDataBuf = theEncData.ToArray(); + int theEncDataLen = theEncDataBuf.Length; +#else + byte[] theEncDataBuf = theEncData.GetBuffer(); + int theEncDataLen = (int)theEncData.Length; +#endif + + byte[] mySrc = theEncDataBuf; + int myRemaining = theEncDataLen - BUFLEN; + + /* Check for insufficient data */ + if (myRemaining < 0) + { + throw new InvalidCipherTextException("Data too short"); + } + + /* Access counter */ + byte[] myExpected = Arrays.CopyOfRange(mySrc, myRemaining, myRemaining + BUFLEN); + byte[] myCounter = Arrays.Clone(myExpected); + myCounter[BUFLEN - 1] |= MASK; + byte[] myMask = new byte[BUFLEN]; + int myOff = 0; + + /* While we have data to process */ + while (myRemaining > 0) + { + /* Generate the next mask */ + theCipher.ProcessBlock(myCounter, 0, myMask, 0); + + /* Xor data into mask */ + int myLen = System.Math.Min(BUFLEN, myRemaining); + xorBlock(myMask, mySrc, myOff, myLen); + + /* Write data to plain dataStream */ + thePlain.Write(myMask, 0, myLen); + theDataHasher.updateHash(myMask, 0, myLen); + + /* Adjust counters */ + myRemaining -= myLen; + myOff += myLen; + incrementCounter(myCounter); + } + + /* Derive and check the tag */ + byte[] myTag = calculateTag(); + if (!Arrays.ConstantTimeAreEqual(myTag, myExpected)) + { + Reset(); + throw new InvalidCipherTextException("mac check failed"); + } + } + + /** + * calculate tag. + * @return the calculated tag + */ + private byte[] calculateTag() + { + /* Complete the hash */ + theDataHasher.completeHash(); + byte[] myPolyVal = completePolyVal(); + + /* calculate polyVal */ + byte[] myResult = new byte[BUFLEN]; + + /* Fold in the nonce */ + for (int i = 0; i < NONCELEN; i++) + { + myPolyVal[i] ^= theNonce[i]; + } + + /* Clear top bit */ + myPolyVal[BUFLEN - 1] &= (byte)(MASK - 1); + + /* Calculate tag and return it */ + theCipher.ProcessBlock(myPolyVal, 0, myResult, 0); + return myResult; + } + + /** + * complete polyVAL. + * @return the calculated value + */ + private byte[] completePolyVal() + { + /* Build the polyVal result */ + byte[] myResult = new byte[BUFLEN]; + gHashLengths(); + fillReverse(theGHash, 0, BUFLEN, myResult); + return myResult; + } + + /** + * process lengths. + */ + private void gHashLengths() + { + /* Create reversed bigEndian buffer to keep it simple */ + byte[] myIn = new byte[BUFLEN]; + Pack.UInt64_To_BE((ulong)Bytes.NumBits * theDataHasher.getBytesProcessed(), myIn, 0); + Pack.UInt64_To_BE((ulong)Bytes.NumBits * theAEADHasher.getBytesProcessed(), myIn, Longs.NumBytes); + + /* hash value */ + gHASH(myIn); + } + + /** + * perform the next GHASH step. + * @param pNext the next value + */ + private void gHASH(byte[] pNext) + { + xorBlock(theGHash, pNext); + theMultiplier.MultiplyH(theGHash); + } + + /** + * Byte reverse a buffer. + * @param pInput the input buffer + * @param pOffset the offset + * @param pLength the length of data (<= BUFLEN) + * @param pOutput the output buffer + */ + private static void fillReverse(byte[] pInput, int pOffset, int pLength, byte[] pOutput) + { + /* Loop through the buffer */ + for (int i = 0, j = BUFLEN - 1; i < pLength; i++, j--) + { + /* Copy byte */ + pOutput[j] = pInput[pOffset + i]; + } + } + + /** + * xor a full block buffer. + * @param pLeft the left operand and result + * @param pRight the right operand + */ + private static void xorBlock(byte[] pLeft, byte[] pRight) + { + /* Loop through the bytes */ + for (int i = 0; i < BUFLEN; i++) + { + pLeft[i] ^= pRight[i]; + } + } + + /** + * xor a partial block buffer. + * @param pLeft the left operand and result + * @param pRight the right operand + * @param pOffset the offset in the right operand + * @param pLength the length of data in the right operand + */ + private static void xorBlock(byte[] pLeft, byte[] pRight, int pOffset, int pLength) + { + /* Loop through the bytes */ + for (int i = 0; i < pLength; i++) + { + pLeft[i] ^= pRight[i + pOffset]; + } + } + + /** + * increment the counter. + * @param pCounter the counter to increment + */ + private static void incrementCounter(byte[] pCounter) + { + /* Loop through the bytes incrementing counter */ + for (int i = 0; i < Integers.NumBytes; i++) + { + if (++pCounter[i] != 0) + { + break; + } + } + } + + /** + * multiply by X. + * @param pValue the value to adjust + */ + private static void mulX(byte[] pValue) + { + /* Loop through the bytes */ + byte myMask = (byte)0; + for (int i = 0; i < BUFLEN; i++) + { + byte myValue = pValue[i]; + pValue[i] = (byte)(((myValue >> 1) & ~MASK) | myMask); + myMask = (byte)((myValue & 1) == 0 ? (byte)0 : MASK); + } + + /* Xor in addition if last bit was set */ + if (myMask != 0) + { + pValue[0] ^= ADD; + } + } + + /** + * Derive Keys. + * @param pKey the keyGeneration key + */ + private void deriveKeys(KeyParameter pKey) + { + /* Create the buffers */ + byte[] myIn = new byte[BUFLEN]; + byte[] myOut = new byte[BUFLEN]; + byte[] myResult = new byte[BUFLEN]; + byte[] myEncKey = new byte[pKey.GetKey().Length]; + + /* Prepare for encryption */ + Array.Copy(theNonce, 0, myIn, BUFLEN - NONCELEN, NONCELEN); + theCipher.Init(true, pKey); + + /* Derive authentication key */ + int myOff = 0; + theCipher.ProcessBlock(myIn, 0, myOut, 0); + Array.Copy(myOut, 0, myResult, myOff, HALFBUFLEN); + myIn[0]++; + myOff += HALFBUFLEN; + theCipher.ProcessBlock(myIn, 0, myOut, 0); + Array.Copy(myOut, 0, myResult, myOff, HALFBUFLEN); + + /* Derive encryption key */ + myIn[0]++; + myOff = 0; + theCipher.ProcessBlock(myIn, 0, myOut, 0); + Array.Copy(myOut, 0, myEncKey, myOff, HALFBUFLEN); + myIn[0]++; + myOff += HALFBUFLEN; + theCipher.ProcessBlock(myIn, 0, myOut, 0); + Array.Copy(myOut, 0, myEncKey, myOff, HALFBUFLEN); + + /* If we have a 32byte key */ + if (myEncKey.Length == BUFLEN << 1) + { + /* Derive remainder of encryption key */ + myIn[0]++; + myOff += HALFBUFLEN; + theCipher.ProcessBlock(myIn, 0, myOut, 0); + Array.Copy(myOut, 0, myEncKey, myOff, HALFBUFLEN); + myIn[0]++; + myOff += HALFBUFLEN; + theCipher.ProcessBlock(myIn, 0, myOut, 0); + Array.Copy(myOut, 0, myEncKey, myOff, HALFBUFLEN); + } + + /* Initialise the Cipher */ + theCipher.Init(true, new KeyParameter(myEncKey)); + + /* Initialise the multiplier */ + fillReverse(myResult, 0, BUFLEN, myOut); + mulX(myOut); + theMultiplier.Init(myOut); + theFlags |= INIT; + } + + private class GcmSivCache + : MemoryStream + { + internal GcmSivCache() + { + } + } + + /** + * Hash Control. + */ + private class GcmSivHasher + { + /** + * Cache. + */ + private readonly byte[] theBuffer = new byte[BUFLEN]; + + /** + * Single byte cache. + */ + private readonly byte[] theByte = new byte[1]; + + /** + * Count of active bytes in cache. + */ + private int numActive; + + /** + * Count of hashed bytes. + */ + private ulong numHashed; + + private readonly GcmSivBlockCipher parent; + + internal GcmSivHasher(GcmSivBlockCipher parent) + { + this.parent = parent; + } + + /** + * Obtain the count of bytes hashed. + * @return the count + */ + internal ulong getBytesProcessed() + { + return numHashed; + } + + /** + * Reset the hasher. + */ + internal void Reset() + { + numActive = 0; + numHashed = 0; + } + + /** + * update hash. + * @param pByte the byte + */ + internal void updateHash(byte pByte) + { + theByte[0] = pByte; + updateHash(theByte, 0, 1); + } + + /** + * update hash. + * @param pBuffer the buffer + * @param pOffset the offset within the buffer + * @param pLen the length of data + */ + internal void updateHash(byte[] pBuffer, int pOffset, int pLen) + { + /* If we should process the cache */ + int mySpace = BUFLEN - numActive; + int numProcessed = 0; + int myRemaining = pLen; + if (numActive > 0 && pLen >= mySpace) + { + /* Copy data into the cache and hash it */ + Array.Copy(pBuffer, pOffset, theBuffer, numActive, mySpace); + fillReverse(theBuffer, 0, BUFLEN, parent.theReverse); + parent.gHASH(parent.theReverse); + + /* Adjust counters */ + numProcessed += mySpace; + myRemaining -= mySpace; + numActive = 0; + } + + /* While we have full blocks */ + while (myRemaining >= BUFLEN) + { + /* Access the next data */ + fillReverse(pBuffer, pOffset + numProcessed, BUFLEN, parent.theReverse); + parent.gHASH(parent.theReverse); + + /* Adjust counters */ + numProcessed += mySpace; + myRemaining -= mySpace; + } + + /* If we have remaining data */ + if (myRemaining > 0) + { + /* Copy data into the cache */ + Array.Copy(pBuffer, pOffset + numProcessed, theBuffer, numActive, myRemaining); + numActive += myRemaining; + } + + /* Adjust the number of bytes processed */ + numHashed += (ulong)pLen; + } + + /** + * complete hash. + */ + internal void completeHash() + { + /* If we have remaining data */ + if (numActive > 0) + { + /* Access the next data */ + Arrays.Fill(parent.theReverse, (byte)0); + fillReverse(theBuffer, 0, numActive, parent.theReverse); + + /* hash value */ + parent.gHASH(parent.theReverse); + } + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/GcmSivBlockCipher.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/GcmSivBlockCipher.cs.meta new file mode 100644 index 0000000..f271fc4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/GcmSivBlockCipher.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 70e25e9c54131e74c8cf95c80b0c0115 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/IAeadBlockCipher.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/IAeadBlockCipher.cs new file mode 100644 index 0000000..ebe5ef2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/IAeadBlockCipher.cs @@ -0,0 +1,15 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Modes +{ + /// An IAeadCipher based on an IBlockCipher. + public interface IAeadBlockCipher + : IAeadCipher + { + /// The block size for this cipher, in bytes. + int GetBlockSize(); + + /// The block cipher underlying this algorithm. + IBlockCipher GetUnderlyingCipher(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/IAeadBlockCipher.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/IAeadBlockCipher.cs.meta new file mode 100644 index 0000000..0476848 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/IAeadBlockCipher.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 04d4fe52ccf3b544d98dc94b2579df01 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/IAeadCipher.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/IAeadCipher.cs new file mode 100644 index 0000000..437693c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/IAeadCipher.cs @@ -0,0 +1,111 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Modes +{ + /// + /// A cipher mode that includes authenticated encryption with a streaming mode and optional + /// associated data. + /// + /// + /// Implementations of this interface may operate in a packet mode (where all input data is + /// buffered and processed during the call to DoFinal, or in a streaming mode (where output + /// data is incrementally produced with each call to ProcessByte or ProcessBytes. This is + /// important to consider during decryption: in a streaming mode, unauthenticated plaintext + /// data may be output prior to the call to DoFinal that results in an authentication failure. + /// The higher level protocol utilising this cipher must ensure the plaintext data is handled + /// appropriately until the end of data is reached and the entire ciphertext is authenticated. + /// + /// + public interface IAeadCipher + { + /// The name of the algorithm this cipher implements. + string AlgorithmName { get; } + + /// Initialise the cipher. + /// Parameter can either be an AeadParameters or a ParametersWithIV object. + /// Initialise for encryption if true, for decryption if false. + /// The key or other data required by the cipher. + void Init(bool forEncryption, ICipherParameters parameters); + + /// Add a single byte to the associated data check. + /// If the implementation supports it, this will be an online operation and will not retain the associated data. + /// The byte to be processed. + void ProcessAadByte(byte input); + + /// Add a sequence of bytes to the associated data check. + /// If the implementation supports it, this will be an online operation and will not retain the associated data. + /// The input byte array. + /// The offset into the input array where the data to be processed starts. + /// The number of bytes to be processed. + void ProcessAadBytes(byte[] inBytes, int inOff, int len); + + /** + * Encrypt/decrypt a single byte. + * + * @param input the byte to be processed. + * @param outBytes the output buffer the processed byte goes into. + * @param outOff the offset into the output byte array the processed data starts at. + * @return the number of bytes written to out. + * @exception DataLengthException if the output buffer is too small. + */ + int ProcessByte(byte input, byte[] outBytes, int outOff); + + /** + * Process a block of bytes from in putting the result into out. + * + * @param inBytes the input byte array. + * @param inOff the offset into the in array where the data to be processed starts. + * @param len the number of bytes to be processed. + * @param outBytes the output buffer the processed bytes go into. + * @param outOff the offset into the output byte array the processed data starts at. + * @return the number of bytes written to out. + * @exception DataLengthException if the output buffer is too small. + */ + int ProcessBytes(byte[] inBytes, int inOff, int len, byte[] outBytes, int outOff); + + /** + * Finish the operation either appending or verifying the MAC at the end of the data. + * + * @param outBytes space for any resulting output data. + * @param outOff offset into out to start copying the data at. + * @return number of bytes written into out. + * @throws InvalidOperationException if the cipher is in an inappropriate state. + * @throws InvalidCipherTextException if the MAC fails to match. + */ + int DoFinal(byte[] outBytes, int outOff); + + /** + * Return the value of the MAC associated with the last stream processed. + * + * @return MAC for plaintext data. + */ + byte[] GetMac(); + + /** + * Return the size of the output buffer required for a ProcessBytes + * an input of len bytes. + * + * @param len the length of the input. + * @return the space required to accommodate a call to ProcessBytes + * with len bytes of input. + */ + int GetUpdateOutputSize(int len); + + /** + * Return the size of the output buffer required for a ProcessBytes plus a + * DoFinal with an input of len bytes. + * + * @param len the length of the input. + * @return the space required to accommodate a call to ProcessBytes and DoFinal + * with len bytes of input. + */ + int GetOutputSize(int len); + + /// + /// Reset the cipher to the same state as it was after the last init (if there was one). + /// + void Reset(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/IAeadCipher.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/IAeadCipher.cs.meta new file mode 100644 index 0000000..53ab416 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/IAeadCipher.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2775766e1e85a644d94196e8517dad89 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/KCcmBlockCipher.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/KCcmBlockCipher.cs new file mode 100644 index 0000000..4f78214 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/KCcmBlockCipher.cs @@ -0,0 +1,490 @@ +using System; +using System.IO; +using System.Text; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Modes +{ + public class KCcmBlockCipher: IAeadBlockCipher + { + private static readonly int BYTES_IN_INT = 4; + private static readonly int BITS_IN_BYTE = 8; + + private static readonly int MAX_MAC_BIT_LENGTH = 512; + private static readonly int MIN_MAC_BIT_LENGTH = 64; + + private IBlockCipher engine; + + private int macSize; + private bool forEncryption; + + private byte[] initialAssociatedText; + private byte[] mac; + private byte[] macBlock; + + private byte[] nonce; + + private byte[] G1; + private byte[] buffer; + + private byte[] s; + private byte[] counter; + + private readonly MemoryStream associatedText = new MemoryStream(); + private readonly MemoryStream data = new MemoryStream(); + + /* + * + * + */ + private int Nb_ = 4; + + private void setNb(int Nb) + { + if (Nb == 4 || Nb == 6 || Nb == 8) + { + Nb_ = Nb; + } + else + { + throw new ArgumentException("Nb = 4 is recommended by DSTU7624 but can be changed to only 6 or 8 in this implementation"); + } + } + + /// + /// Base constructor. Nb value is set to 4. + /// + /// base cipher to use under CCM. + public KCcmBlockCipher(IBlockCipher engine): this(engine, 4) + { + } + + /// + /// Constructor allowing Nb configuration. + /// + /// Nb is a parameter specified in CCM mode of DSTU7624 standard. + /// This parameter specifies maximum possible length of input.It should + /// be calculated as follows: Nb = 1 / 8 * (-3 + log[2]Nmax) + 1, + /// where Nmax - length of input message in bits.For practical reasons + /// Nmax usually less than 4Gb, e.g. for Nmax = 2^32 - 1, Nb = 4. + /// + /// base cipher to use under CCM. + /// Nb value to use. + public KCcmBlockCipher(IBlockCipher engine, int Nb) + { + this.engine = engine; + this.macSize = engine.GetBlockSize(); + this.nonce = new byte[engine.GetBlockSize()]; + this.initialAssociatedText = new byte[engine.GetBlockSize()]; + this.mac = new byte[engine.GetBlockSize()]; + this.macBlock = new byte[engine.GetBlockSize()]; + this.G1 = new byte[engine.GetBlockSize()]; + this.buffer = new byte[engine.GetBlockSize()]; + this.s = new byte[engine.GetBlockSize()]; + this.counter = new byte[engine.GetBlockSize()]; + setNb(Nb); + } + + public virtual void Init(bool forEncryption, ICipherParameters parameters) + { + + ICipherParameters cipherParameters; + if (parameters is AeadParameters) + { + + AeadParameters param = (AeadParameters)parameters; + + if (param.MacSize > MAX_MAC_BIT_LENGTH || param.MacSize < MIN_MAC_BIT_LENGTH || param.MacSize % 8 != 0) + { + throw new ArgumentException("Invalid mac size specified"); + } + + nonce = param.GetNonce(); + macSize = param.MacSize / BITS_IN_BYTE; + initialAssociatedText = param.GetAssociatedText(); + cipherParameters = param.Key; + } + else if (parameters is ParametersWithIV) + { + nonce = ((ParametersWithIV)parameters).GetIV(); + macSize = engine.GetBlockSize(); // use default blockSize for MAC if it is not specified + initialAssociatedText = null; + cipherParameters = ((ParametersWithIV)parameters).Parameters; + } + else + { + throw new ArgumentException("Invalid parameters specified"); + } + + this.mac = new byte[macSize]; + this.forEncryption = forEncryption; + engine.Init(true, cipherParameters); + + counter[0] = 0x01; // defined in standard + + if (initialAssociatedText != null) + { + ProcessAadBytes(initialAssociatedText, 0, initialAssociatedText.Length); + } + } + + public virtual String AlgorithmName + { + get + { + return engine.AlgorithmName + "/KCCM"; + } + } + + public virtual int GetBlockSize() + { + return engine.GetBlockSize(); + } + + public virtual IBlockCipher GetUnderlyingCipher() + { + return engine; + } + + public virtual void ProcessAadByte(byte input) + { + associatedText.WriteByte(input); + } + + public virtual void ProcessAadBytes(byte[] input, int inOff, int len) + { + associatedText.Write(input, inOff, len); + } + + private void ProcessAAD(byte[] assocText, int assocOff, int assocLen, int dataLen) + { + if (assocLen - assocOff < engine.GetBlockSize()) + { + throw new ArgumentException("authText buffer too short"); + } + if (assocLen % engine.GetBlockSize() != 0) + { + throw new ArgumentException("padding not supported"); + } + + Array.Copy(nonce, 0, G1, 0, nonce.Length - Nb_ - 1); + + intToBytes(dataLen, buffer, 0); // for G1 + + Array.Copy(buffer, 0, G1, nonce.Length - Nb_ - 1, BYTES_IN_INT); + + G1[G1.Length - 1] = getFlag(true, macSize); + + engine.ProcessBlock(G1, 0, macBlock, 0); + + intToBytes(assocLen, buffer, 0); // for G2 + + if (assocLen <= engine.GetBlockSize() - Nb_) + { + for (int byteIndex = 0; byteIndex < assocLen; byteIndex++) + { + buffer[byteIndex + Nb_] ^= assocText[assocOff + byteIndex]; + } + + for (int byteIndex = 0; byteIndex < engine.GetBlockSize(); byteIndex++) + { + macBlock[byteIndex] ^= buffer[byteIndex]; + } + + engine.ProcessBlock(macBlock, 0, macBlock, 0); + + return; + } + + for (int byteIndex = 0; byteIndex < engine.GetBlockSize(); byteIndex++) + { + macBlock[byteIndex] ^= buffer[byteIndex]; + } + + engine.ProcessBlock(macBlock, 0, macBlock, 0); + + int authLen = assocLen; + while (authLen != 0) + { + for (int byteIndex = 0; byteIndex < engine.GetBlockSize(); byteIndex++) + { + macBlock[byteIndex] ^= assocText[byteIndex + assocOff]; + } + + engine.ProcessBlock(macBlock, 0, macBlock, 0); + + assocOff += engine.GetBlockSize(); + authLen -= engine.GetBlockSize(); + } + } + + public virtual int ProcessByte(byte input, byte[] output, int outOff) + { + data.WriteByte(input); + + return 0; + } + + public virtual int ProcessBytes(byte[] input, int inOff, int inLen, byte[] output, int outOff) + { + Check.DataLength(input, inOff, inLen, "input buffer too short"); + + data.Write(input, inOff, inLen); + + return 0; + } + + public int ProcessPacket(byte[] input, int inOff, int len, byte[] output, int outOff) + { + Check.DataLength(input, inOff, len, "input buffer too short"); + Check.OutputLength(output, outOff, len, "output buffer too short"); + + if (associatedText.Length > 0) + { +#if PORTABLE + byte[] aad = associatedText.ToArray(); + int aadLen = aad.Length; +#else + byte[] aad = associatedText.GetBuffer(); + int aadLen = (int)associatedText.Length; +#endif + + int dataLen = forEncryption ? (int)data.Length : ((int)data.Length - macSize); + + ProcessAAD(aad, 0, aadLen, dataLen); + } + + if (forEncryption) + { + Check.DataLength(len % engine.GetBlockSize() != 0, "partial blocks not supported"); + + CalculateMac(input, inOff, len); + engine.ProcessBlock(nonce, 0, s, 0); + + int totalLength = len; + while (totalLength > 0) + { + ProcessBlock(input, inOff, len, output, outOff); + totalLength -= engine.GetBlockSize(); + inOff += engine.GetBlockSize(); + outOff += engine.GetBlockSize(); + } + + for (int byteIndex = 0; byteIndex inOff) + { + for (int byteIndex = 0; byteIndex 0) + { + for (int byteIndex = 0; byteIndex < engine.GetBlockSize(); byteIndex++) + { + macBlock[byteIndex] ^= authText[authOff + byteIndex]; + } + + engine.ProcessBlock(macBlock, 0, macBlock, 0); + + totalLen -= engine.GetBlockSize(); + authOff += engine.GetBlockSize(); + } + } + + public virtual int DoFinal(byte[] output, int outOff) + { +#if PORTABLE + byte[] buf = data.ToArray(); + int bufLen = buf.Length; +#else + byte[] buf = data.GetBuffer(); + int bufLen = (int)data.Length; +#endif + + int len = ProcessPacket(buf, 0, bufLen, output, outOff); + + Reset(); + + return len; + } + + public virtual byte[] GetMac() + { + return Arrays.Clone(mac); + } + + public virtual int GetUpdateOutputSize(int len) + { + return len; + } + + public virtual int GetOutputSize(int len) + { + return len + macSize; + } + + public virtual void Reset() + { + Arrays.Fill(G1, (byte)0); + Arrays.Fill(buffer, (byte)0); + Arrays.Fill(counter, (byte)0); + Arrays.Fill(macBlock, (byte)0); + + counter[0] = 0x01; + data.SetLength(0); + associatedText.SetLength(0); + + if (initialAssociatedText != null) + { + ProcessAadBytes(initialAssociatedText, 0, initialAssociatedText.Length); + } + } + + private void intToBytes( + int num, + byte[] outBytes, + int outOff) + { + outBytes[outOff + 3] = (byte)(num >> 24); + outBytes[outOff + 2] = (byte)(num >> 16); + outBytes[outOff + 1] = (byte)(num >> 8); + outBytes[outOff] = (byte)num; + } + + private byte getFlag(bool authTextPresents, int macSize) + { + StringBuilder flagByte = new StringBuilder(); + + if (authTextPresents) + { + flagByte.Append("1"); + } + else + { + flagByte.Append("0"); + } + + + switch (macSize) + { + case 8: + flagByte.Append("010"); // binary 2 + break; + case 16: + flagByte.Append("011"); // binary 3 + break; + case 32: + flagByte.Append("100"); // binary 4 + break; + case 48: + flagByte.Append("101"); // binary 5 + break; + case 64: + flagByte.Append("110"); // binary 6 + break; + } + + String binaryNb = Convert.ToString(Nb_ - 1, 2); + while (binaryNb.Length < 4) + { + binaryNb = new StringBuilder(binaryNb).Insert(0, "0").ToString(); + } + + flagByte.Append(binaryNb); + + return (byte)Convert.ToInt32(flagByte.ToString(), 2); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/KCcmBlockCipher.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/KCcmBlockCipher.cs.meta new file mode 100644 index 0000000..56e99c9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/KCcmBlockCipher.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 992d557db09a7ae4cb27b9c1c6c7e5fd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/KCtrBlockCipher.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/KCtrBlockCipher.cs new file mode 100644 index 0000000..ff0249a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/KCtrBlockCipher.cs @@ -0,0 +1,235 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Modes +{ + /** + * Implements a Gamming or Counter (CTR) mode on top of a DSTU 7624 block cipher. + */ + public class KCtrBlockCipher : IStreamCipher, IBlockCipher + { + private byte[] IV; + private byte[] ofbV; + private byte[] ofbOutV; + private bool initialised; + + private int byteCount; + + private readonly int blockSize; + private readonly IBlockCipher cipher; + + /** + * Basic constructor. + * + * @param cipher the block cipher to be used as the basis of the + * feedback mode. + */ + public KCtrBlockCipher(IBlockCipher cipher) + { + this.cipher = cipher; + this.IV = new byte[cipher.GetBlockSize()]; + this.blockSize = cipher.GetBlockSize(); + + this.ofbV = new byte[cipher.GetBlockSize()]; + this.ofbOutV = new byte[cipher.GetBlockSize()]; + } + + /** + * return the underlying block cipher that we are wrapping. + * + * @return the underlying block cipher that we are wrapping. + */ + public IBlockCipher GetUnderlyingCipher() + { + return cipher; + } + /** + * Initialise the cipher and, possibly, the initialisation vector (IV). + * If an IV isn't passed as part of the parameter, the IV will be all zeros. + * An IV which is too short is handled in FIPS compliant fashion. + * + * @param forEncryption if true the cipher is initialised for + * encryption, if false for decryption. + * @param param the key and other data required by the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public void Init( + bool forEncryption, + ICipherParameters parameters) + { + this.initialised = true; + if (parameters is ParametersWithIV) + { + ParametersWithIV ivParam = (ParametersWithIV)parameters; + byte[] iv = ivParam.GetIV(); + int diff = IV.Length - iv.Length; + + Array.Clear(IV, 0, IV.Length); + Array.Copy(iv, 0, IV, diff, iv.Length); + + parameters = ivParam.Parameters; + } + else + { + throw new ArgumentException("Invalid parameter passed"); + } + + // if it's null, key is to be reused. + if (parameters != null) + { + cipher.Init(true, parameters); + } + + Reset(); + } + + /** + * return the algorithm name and mode. + * + * @return the name of the underlying algorithm followed by "/KCTR" + * and the block size in bits. + */ + public string AlgorithmName + { + get { return cipher.AlgorithmName + "/KCTR"; } + } + + public bool IsPartialBlockOkay + { + get { return true; } + } + + /** + * return the block size we are operating at. + * + * @return the block size we are operating at (in bytes). + */ + public int GetBlockSize() + { + return cipher.GetBlockSize(); + } + + public byte ReturnByte(byte input) + { + return CalculateByte(input); + } + + public void ProcessBytes(byte[] input, int inOff, int len, byte[] output, int outOff) + { + if (outOff + len > output.Length) + { + throw new DataLengthException("Output buffer too short"); + } + + if (inOff + len > input.Length) + { + throw new DataLengthException("Input buffer too small"); + } + + int inStart = inOff; + int inEnd = inOff + len; + int outStart = outOff; + + while (inStartRFC 7253 on The OCB + * Authenticated-Encryption Algorithm, licensed per: + * + *

License for + * Open-Source Software Implementations of OCB (Jan 9, 2013) - 'License 1'
+ * Under this license, you are authorized to make, use, and distribute open-source software + * implementations of OCB. This license terminates for you if you sue someone over their open-source + * software implementation of OCB claiming that you have a patent covering their implementation. + *

+ * This is a non-binding summary of a legal document (the link above). The parameters of the license + * are specified in the license document and that document is controlling.

+ */ + public class OcbBlockCipher + : IAeadBlockCipher + { + private const int BLOCK_SIZE = 16; + + private readonly IBlockCipher hashCipher; + private readonly IBlockCipher mainCipher; + + /* + * CONFIGURATION + */ + private bool forEncryption; + private int macSize; + private byte[] initialAssociatedText; + + /* + * KEY-DEPENDENT + */ + // NOTE: elements are lazily calculated + private IList L; + private byte[] L_Asterisk, L_Dollar; + + /* + * NONCE-DEPENDENT + */ + private byte[] KtopInput = null; + private byte[] Stretch = new byte[24]; + private byte[] OffsetMAIN_0 = new byte[16]; + + /* + * PER-ENCRYPTION/DECRYPTION + */ + private byte[] hashBlock, mainBlock; + private int hashBlockPos, mainBlockPos; + private long hashBlockCount, mainBlockCount; + private byte[] OffsetHASH; + private byte[] Sum; + private byte[] OffsetMAIN = new byte[16]; + private byte[] Checksum; + + // NOTE: The MAC value is preserved after doFinal + private byte[] macBlock; + + public OcbBlockCipher(IBlockCipher hashCipher, IBlockCipher mainCipher) + { + if (hashCipher == null) + throw new ArgumentNullException("hashCipher"); + if (hashCipher.GetBlockSize() != BLOCK_SIZE) + throw new ArgumentException("must have a block size of " + BLOCK_SIZE, "hashCipher"); + if (mainCipher == null) + throw new ArgumentNullException("mainCipher"); + if (mainCipher.GetBlockSize() != BLOCK_SIZE) + throw new ArgumentException("must have a block size of " + BLOCK_SIZE, "mainCipher"); + + if (!hashCipher.AlgorithmName.Equals(mainCipher.AlgorithmName)) + throw new ArgumentException("'hashCipher' and 'mainCipher' must be the same algorithm"); + + this.hashCipher = hashCipher; + this.mainCipher = mainCipher; + } + + public virtual IBlockCipher GetUnderlyingCipher() + { + return mainCipher; + } + + public virtual string AlgorithmName + { + get { return mainCipher.AlgorithmName + "/OCB"; } + } + + public virtual void Init(bool forEncryption, ICipherParameters parameters) + { + bool oldForEncryption = this.forEncryption; + this.forEncryption = forEncryption; + this.macBlock = null; + + KeyParameter keyParameter; + + byte[] N; + if (parameters is AeadParameters) + { + AeadParameters aeadParameters = (AeadParameters) parameters; + + N = aeadParameters.GetNonce(); + initialAssociatedText = aeadParameters.GetAssociatedText(); + + int macSizeBits = aeadParameters.MacSize; + if (macSizeBits < 64 || macSizeBits > 128 || macSizeBits % 8 != 0) + throw new ArgumentException("Invalid value for MAC size: " + macSizeBits); + + macSize = macSizeBits / 8; + keyParameter = aeadParameters.Key; + } + else if (parameters is ParametersWithIV) + { + ParametersWithIV parametersWithIV = (ParametersWithIV) parameters; + + N = parametersWithIV.GetIV(); + initialAssociatedText = null; + macSize = 16; + keyParameter = (KeyParameter) parametersWithIV.Parameters; + } + else + { + throw new ArgumentException("invalid parameters passed to OCB"); + } + + this.hashBlock = new byte[16]; + this.mainBlock = new byte[forEncryption ? BLOCK_SIZE : (BLOCK_SIZE + macSize)]; + + if (N == null) + { + N = new byte[0]; + } + + if (N.Length > 15) + { + throw new ArgumentException("IV must be no more than 15 bytes"); + } + + /* + * KEY-DEPENDENT INITIALISATION + */ + + if (keyParameter != null) + { + // hashCipher always used in forward mode + hashCipher.Init(true, keyParameter); + mainCipher.Init(forEncryption, keyParameter); + KtopInput = null; + } + else if (oldForEncryption != forEncryption) + { + throw new ArgumentException("cannot change encrypting state without providing key."); + } + + this.L_Asterisk = new byte[16]; + hashCipher.ProcessBlock(L_Asterisk, 0, L_Asterisk, 0); + + this.L_Dollar = OCB_double(L_Asterisk); + + this.L = Platform.CreateArrayList(); + this.L.Add(OCB_double(L_Dollar)); + + /* + * NONCE-DEPENDENT AND PER-ENCRYPTION/DECRYPTION INITIALISATION + */ + + int bottom = ProcessNonce(N); + + int bits = bottom % 8, bytes = bottom / 8; + if (bits == 0) + { + Array.Copy(Stretch, bytes, OffsetMAIN_0, 0, 16); + } + else + { + for (int i = 0; i < 16; ++i) + { + uint b1 = Stretch[bytes]; + uint b2 = Stretch[++bytes]; + this.OffsetMAIN_0[i] = (byte) ((b1 << bits) | (b2 >> (8 - bits))); + } + } + + this.hashBlockPos = 0; + this.mainBlockPos = 0; + + this.hashBlockCount = 0; + this.mainBlockCount = 0; + + this.OffsetHASH = new byte[16]; + this.Sum = new byte[16]; + Array.Copy(OffsetMAIN_0, 0, OffsetMAIN, 0, 16); + this.Checksum = new byte[16]; + + if (initialAssociatedText != null) + { + ProcessAadBytes(initialAssociatedText, 0, initialAssociatedText.Length); + } + } + + protected virtual int ProcessNonce(byte[] N) + { + byte[] nonce = new byte[16]; + Array.Copy(N, 0, nonce, nonce.Length - N.Length, N.Length); + nonce[0] = (byte)(macSize << 4); + nonce[15 - N.Length] |= 1; + + int bottom = nonce[15] & 0x3F; + nonce[15] &= 0xC0; + + /* + * When used with incrementing nonces, the cipher is only applied once every 64 inits. + */ + if (KtopInput == null || !Arrays.AreEqual(nonce, KtopInput)) + { + byte[] Ktop = new byte[16]; + KtopInput = nonce; + hashCipher.ProcessBlock(KtopInput, 0, Ktop, 0); + Array.Copy(Ktop, 0, Stretch, 0, 16); + for (int i = 0; i < 8; ++i) + { + Stretch[16 + i] = (byte)(Ktop[i] ^ Ktop[i + 1]); + } + } + + return bottom; + } + + public virtual int GetBlockSize() + { + return BLOCK_SIZE; + } + + public virtual byte[] GetMac() + { + return macBlock == null + ? new byte[macSize] + : Arrays.Clone(macBlock); + } + + public virtual int GetOutputSize(int len) + { + int totalData = len + mainBlockPos; + if (forEncryption) + { + return totalData + macSize; + } + return totalData < macSize ? 0 : totalData - macSize; + } + + public virtual int GetUpdateOutputSize(int len) + { + int totalData = len + mainBlockPos; + if (!forEncryption) + { + if (totalData < macSize) + { + return 0; + } + totalData -= macSize; + } + return totalData - totalData % BLOCK_SIZE; + } + + public virtual void ProcessAadByte(byte input) + { + hashBlock[hashBlockPos] = input; + if (++hashBlockPos == hashBlock.Length) + { + ProcessHashBlock(); + } + } + + public virtual void ProcessAadBytes(byte[] input, int off, int len) + { + for (int i = 0; i < len; ++i) + { + hashBlock[hashBlockPos] = input[off + i]; + if (++hashBlockPos == hashBlock.Length) + { + ProcessHashBlock(); + } + } + } + + public virtual int ProcessByte(byte input, byte[] output, int outOff) + { + mainBlock[mainBlockPos] = input; + if (++mainBlockPos == mainBlock.Length) + { + ProcessMainBlock(output, outOff); + return BLOCK_SIZE; + } + return 0; + } + + public virtual int ProcessBytes(byte[] input, int inOff, int len, byte[] output, int outOff) + { + int resultLen = 0; + + for (int i = 0; i < len; ++i) + { + mainBlock[mainBlockPos] = input[inOff + i]; + if (++mainBlockPos == mainBlock.Length) + { + ProcessMainBlock(output, outOff + resultLen); + resultLen += BLOCK_SIZE; + } + } + + return resultLen; + } + + public virtual int DoFinal(byte[] output, int outOff) + { + /* + * For decryption, get the tag from the end of the message + */ + byte[] tag = null; + if (!forEncryption) { + if (mainBlockPos < macSize) + throw new InvalidCipherTextException("data too short"); + + mainBlockPos -= macSize; + tag = new byte[macSize]; + Array.Copy(mainBlock, mainBlockPos, tag, 0, macSize); + } + + /* + * HASH: Process any final partial block; compute final hash value + */ + if (hashBlockPos > 0) + { + OCB_extend(hashBlock, hashBlockPos); + UpdateHASH(L_Asterisk); + } + + /* + * OCB-ENCRYPT/OCB-DECRYPT: Process any final partial block + */ + if (mainBlockPos > 0) + { + if (forEncryption) + { + OCB_extend(mainBlock, mainBlockPos); + Xor(Checksum, mainBlock); + } + + Xor(OffsetMAIN, L_Asterisk); + + byte[] Pad = new byte[16]; + hashCipher.ProcessBlock(OffsetMAIN, 0, Pad, 0); + + Xor(mainBlock, Pad); + + Check.OutputLength(output, outOff, mainBlockPos, "Output buffer too short"); + Array.Copy(mainBlock, 0, output, outOff, mainBlockPos); + + if (!forEncryption) + { + OCB_extend(mainBlock, mainBlockPos); + Xor(Checksum, mainBlock); + } + } + + /* + * OCB-ENCRYPT/OCB-DECRYPT: Compute raw tag + */ + Xor(Checksum, OffsetMAIN); + Xor(Checksum, L_Dollar); + hashCipher.ProcessBlock(Checksum, 0, Checksum, 0); + Xor(Checksum, Sum); + + this.macBlock = new byte[macSize]; + Array.Copy(Checksum, 0, macBlock, 0, macSize); + + /* + * Validate or append tag and reset this cipher for the next run + */ + int resultLen = mainBlockPos; + + if (forEncryption) + { + Check.OutputLength(output, outOff, resultLen + macSize, "Output buffer too short"); + + // Append tag to the message + Array.Copy(macBlock, 0, output, outOff + resultLen, macSize); + resultLen += macSize; + } + else + { + // Compare the tag from the message with the calculated one + if (!Arrays.ConstantTimeAreEqual(macBlock, tag)) + throw new InvalidCipherTextException("mac check in OCB failed"); + } + + Reset(false); + + return resultLen; + } + + public virtual void Reset() + { + Reset(true); + } + + protected virtual void Clear(byte[] bs) + { + if (bs != null) + { + Array.Clear(bs, 0, bs.Length); + } + } + + protected virtual byte[] GetLSub(int n) + { + while (n >= L.Count) + { + L.Add(OCB_double((byte[]) L[L.Count - 1])); + } + return (byte[])L[n]; + } + + protected virtual void ProcessHashBlock() + { + /* + * HASH: Process any whole blocks + */ + UpdateHASH(GetLSub(OCB_ntz(++hashBlockCount))); + hashBlockPos = 0; + } + + protected virtual void ProcessMainBlock(byte[] output, int outOff) + { + Check.DataLength(output, outOff, BLOCK_SIZE, "Output buffer too short"); + + /* + * OCB-ENCRYPT/OCB-DECRYPT: Process any whole blocks + */ + + if (forEncryption) + { + Xor(Checksum, mainBlock); + mainBlockPos = 0; + } + + Xor(OffsetMAIN, GetLSub(OCB_ntz(++mainBlockCount))); + + Xor(mainBlock, OffsetMAIN); + mainCipher.ProcessBlock(mainBlock, 0, mainBlock, 0); + Xor(mainBlock, OffsetMAIN); + + Array.Copy(mainBlock, 0, output, outOff, 16); + + if (!forEncryption) + { + Xor(Checksum, mainBlock); + Array.Copy(mainBlock, BLOCK_SIZE, mainBlock, 0, macSize); + mainBlockPos = macSize; + } + } + + protected virtual void Reset(bool clearMac) + { + hashCipher.Reset(); + mainCipher.Reset(); + + Clear(hashBlock); + Clear(mainBlock); + + hashBlockPos = 0; + mainBlockPos = 0; + + hashBlockCount = 0; + mainBlockCount = 0; + + Clear(OffsetHASH); + Clear(Sum); + Array.Copy(OffsetMAIN_0, 0, OffsetMAIN, 0, 16); + Clear(Checksum); + + if (clearMac) + { + macBlock = null; + } + + if (initialAssociatedText != null) + { + ProcessAadBytes(initialAssociatedText, 0, initialAssociatedText.Length); + } + } + + protected virtual void UpdateHASH(byte[] LSub) + { + Xor(OffsetHASH, LSub); + Xor(hashBlock, OffsetHASH); + hashCipher.ProcessBlock(hashBlock, 0, hashBlock, 0); + Xor(Sum, hashBlock); + } + + protected static byte[] OCB_double(byte[] block) + { + byte[] result = new byte[16]; + int carry = ShiftLeft(block, result); + + /* + * NOTE: This construction is an attempt at a constant-time implementation. + */ + result[15] ^= (byte)(0x87 >> ((1 - carry) << 3)); + + return result; + } + + protected static void OCB_extend(byte[] block, int pos) + { + block[pos] = (byte) 0x80; + while (++pos < 16) + { + block[pos] = 0; + } + } + + protected static int OCB_ntz(long x) + { + if (x == 0) + { + return 64; + } + + int n = 0; + ulong ux = (ulong)x; + while ((ux & 1UL) == 0UL) + { + ++n; + ux >>= 1; + } + return n; + } + + protected static int ShiftLeft(byte[] block, byte[] output) + { + int i = 16; + uint bit = 0; + while (--i >= 0) + { + uint b = block[i]; + output[i] = (byte) ((b << 1) | bit); + bit = (b >> 7) & 1; + } + return (int)bit; + } + + protected static void Xor(byte[] block, byte[] val) + { + for (int i = 15; i >= 0; --i) + { + block[i] ^= val[i]; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/OCBBlockCipher.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/OCBBlockCipher.cs.meta new file mode 100644 index 0000000..1aebd5c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/OCBBlockCipher.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0fb8bc9bd42cd894fbe731aad24ed526 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/OfbBlockCipher.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/OfbBlockCipher.cs new file mode 100644 index 0000000..a99f8c5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/OfbBlockCipher.cs @@ -0,0 +1,182 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Modes +{ + /** + * implements a Output-FeedBack (OFB) mode on top of a simple cipher. + */ + public class OfbBlockCipher + : IBlockCipher + { + private byte[] IV; + private byte[] ofbV; + private byte[] ofbOutV; + + private readonly int blockSize; + private readonly IBlockCipher cipher; + + /** + * Basic constructor. + * + * @param cipher the block cipher to be used as the basis of the + * feedback mode. + * @param blockSize the block size in bits (note: a multiple of 8) + */ + public OfbBlockCipher( + IBlockCipher cipher, + int blockSize) + { + this.cipher = cipher; + this.blockSize = blockSize / 8; + + this.IV = new byte[cipher.GetBlockSize()]; + this.ofbV = new byte[cipher.GetBlockSize()]; + this.ofbOutV = new byte[cipher.GetBlockSize()]; + } + + /** + * return the underlying block cipher that we are wrapping. + * + * @return the underlying block cipher that we are wrapping. + */ + public IBlockCipher GetUnderlyingCipher() + { + return cipher; + } + + /** + * Initialise the cipher and, possibly, the initialisation vector (IV). + * If an IV isn't passed as part of the parameter, the IV will be all zeros. + * An IV which is too short is handled in FIPS compliant fashion. + * + * @param forEncryption if true the cipher is initialised for + * encryption, if false for decryption. + * @param param the key and other data required by the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public void Init( + bool forEncryption, //ignored by this OFB mode + ICipherParameters parameters) + { + if (parameters is ParametersWithIV) + { + ParametersWithIV ivParam = (ParametersWithIV)parameters; + byte[] iv = ivParam.GetIV(); + + if (iv.Length < IV.Length) + { + // prepend the supplied IV with zeros (per FIPS PUB 81) + Array.Copy(iv, 0, IV, IV.Length - iv.Length, iv.Length); + for (int i = 0; i < IV.Length - iv.Length; i++) + { + IV[i] = 0; + } + } + else + { + Array.Copy(iv, 0, IV, 0, IV.Length); + } + + parameters = ivParam.Parameters; + } + + Reset(); + + // if it's null, key is to be reused. + if (parameters != null) + { + cipher.Init(true, parameters); + } + } + + /** + * return the algorithm name and mode. + * + * @return the name of the underlying algorithm followed by "/OFB" + * and the block size in bits + */ + public string AlgorithmName + { + get { return cipher.AlgorithmName + "/OFB" + (blockSize * 8); } + } + + public bool IsPartialBlockOkay + { + get { return true; } + } + + /** + * return the block size we are operating at (in bytes). + * + * @return the block size we are operating at (in bytes). + */ + public int GetBlockSize() + { + return blockSize; + } + + /** + * Process one block of input from the array in and write it to + * the out array. + * + * @param in the array containing the input data. + * @param inOff offset into the in array the data starts at. + * @param out the array the output data will be copied into. + * @param outOff the offset into the out array the output will start at. + * @exception DataLengthException if there isn't enough data in in, or + * space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + * @return the number of bytes processed and produced. + */ + public int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + if ((inOff + blockSize) > input.Length) + { + throw new DataLengthException("input buffer too short"); + } + + if ((outOff + blockSize) > output.Length) + { + throw new DataLengthException("output buffer too short"); + } + + cipher.ProcessBlock(ofbV, 0, ofbOutV, 0); + + // + // XOR the ofbV with the plaintext producing the cipher text (and + // the next input block). + // + for (int i = 0; i < blockSize; i++) + { + output[outOff + i] = (byte)(ofbOutV[i] ^ input[inOff + i]); + } + + // + // change over the input block. + // + Array.Copy(ofbV, blockSize, ofbV, 0, ofbV.Length - blockSize); + Array.Copy(ofbOutV, 0, ofbV, ofbV.Length - blockSize, blockSize); + + return blockSize; + } + + /** + * reset the feedback vector back to the IV and reset the underlying + * cipher. + */ + public void Reset() + { + Array.Copy(IV, 0, ofbV, 0, IV.Length); + + cipher.Reset(); + } + } + +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/OfbBlockCipher.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/OfbBlockCipher.cs.meta new file mode 100644 index 0000000..3ff2a1b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/OfbBlockCipher.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5611dcff082ff4949a96821973412f27 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/OpenPgpCfbBlockCipher.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/OpenPgpCfbBlockCipher.cs new file mode 100644 index 0000000..038ca78 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/OpenPgpCfbBlockCipher.cs @@ -0,0 +1,337 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Modes +{ + /** + * Implements OpenPGP's rather strange version of Cipher-FeedBack (CFB) mode + * on top of a simple cipher. This class assumes the IV has been prepended + * to the data stream already, and just accomodates the reset after + * (blockSize + 2) bytes have been read. + *

+ * For further info see RFC 2440. + *

+ */ + public class OpenPgpCfbBlockCipher + : IBlockCipher + { + private byte[] IV; + private byte[] FR; + private byte[] FRE; + + private readonly IBlockCipher cipher; + private readonly int blockSize; + + private int count; + private bool forEncryption; + + /** + * Basic constructor. + * + * @param cipher the block cipher to be used as the basis of the + * feedback mode. + */ + public OpenPgpCfbBlockCipher( + IBlockCipher cipher) + { + this.cipher = cipher; + + this.blockSize = cipher.GetBlockSize(); + this.IV = new byte[blockSize]; + this.FR = new byte[blockSize]; + this.FRE = new byte[blockSize]; + } + + /** + * return the underlying block cipher that we are wrapping. + * + * @return the underlying block cipher that we are wrapping. + */ + public IBlockCipher GetUnderlyingCipher() + { + return cipher; + } + + /** + * return the algorithm name and mode. + * + * @return the name of the underlying algorithm followed by "/PGPCFB" + * and the block size in bits. + */ + public string AlgorithmName + { + get { return cipher.AlgorithmName + "/OpenPGPCFB"; } + } + + public bool IsPartialBlockOkay + { + get { return true; } + } + + /** + * return the block size we are operating at. + * + * @return the block size we are operating at (in bytes). + */ + public int GetBlockSize() + { + return cipher.GetBlockSize(); + } + + /** + * Process one block of input from the array in and write it to + * the out array. + * + * @param in the array containing the input data. + * @param inOff offset into the in array the data starts at. + * @param out the array the output data will be copied into. + * @param outOff the offset into the out array the output will start at. + * @exception DataLengthException if there isn't enough data in in, or + * space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + * @return the number of bytes processed and produced. + */ + public int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + return (forEncryption) ? EncryptBlock(input, inOff, output, outOff) : DecryptBlock(input, inOff, output, outOff); + } + + /** + * reset the chaining vector back to the IV and reset the underlying + * cipher. + */ + public void Reset() + { + count = 0; + + Array.Copy(IV, 0, FR, 0, FR.Length); + + cipher.Reset(); + } + + /** + * Initialise the cipher and, possibly, the initialisation vector (IV). + * If an IV isn't passed as part of the parameter, the IV will be all zeros. + * An IV which is too short is handled in FIPS compliant fashion. + * + * @param forEncryption if true the cipher is initialised for + * encryption, if false for decryption. + * @param parameters the key and other data required by the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public void Init( + bool forEncryption, + ICipherParameters parameters) + { + this.forEncryption = forEncryption; + + if (parameters is ParametersWithIV) + { + ParametersWithIV ivParam = (ParametersWithIV)parameters; + byte[] iv = ivParam.GetIV(); + + if (iv.Length < IV.Length) + { + // prepend the supplied IV with zeros (per FIPS PUB 81) + Array.Copy(iv, 0, IV, IV.Length - iv.Length, iv.Length); + for (int i = 0; i < IV.Length - iv.Length; i++) + { + IV[i] = 0; + } + } + else + { + Array.Copy(iv, 0, IV, 0, IV.Length); + } + + parameters = ivParam.Parameters; + } + + Reset(); + + cipher.Init(true, parameters); + } + + /** + * Encrypt one byte of data according to CFB mode. + * @param data the byte to encrypt + * @param blockOff offset in the current block + * @returns the encrypted byte + */ + private byte EncryptByte(byte data, int blockOff) + { + return (byte)(FRE[blockOff] ^ data); + } + + /** + * Do the appropriate processing for CFB IV mode encryption. + * + * @param in the array containing the data to be encrypted. + * @param inOff offset into the in array the data starts at. + * @param out the array the encrypted data will be copied into. + * @param outOff the offset into the out array the output will start at. + * @exception DataLengthException if there isn't enough data in in, or + * space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + * @return the number of bytes processed and produced. + */ + private int EncryptBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + if ((inOff + blockSize) > input.Length) + { + throw new DataLengthException("input buffer too short"); + } + + if ((outOff + blockSize) > outBytes.Length) + { + throw new DataLengthException("output buffer too short"); + } + + if (count > blockSize) + { + FR[blockSize - 2] = outBytes[outOff] = EncryptByte(input[inOff], blockSize - 2); + FR[blockSize - 1] = outBytes[outOff + 1] = EncryptByte(input[inOff + 1], blockSize - 1); + + cipher.ProcessBlock(FR, 0, FRE, 0); + + for (int n = 2; n < blockSize; n++) + { + FR[n - 2] = outBytes[outOff + n] = EncryptByte(input[inOff + n], n - 2); + } + } + else if (count == 0) + { + cipher.ProcessBlock(FR, 0, FRE, 0); + + for (int n = 0; n < blockSize; n++) + { + FR[n] = outBytes[outOff + n] = EncryptByte(input[inOff + n], n); + } + + count += blockSize; + } + else if (count == blockSize) + { + cipher.ProcessBlock(FR, 0, FRE, 0); + + outBytes[outOff] = EncryptByte(input[inOff], 0); + outBytes[outOff + 1] = EncryptByte(input[inOff + 1], 1); + + // + // do reset + // + Array.Copy(FR, 2, FR, 0, blockSize - 2); + Array.Copy(outBytes, outOff, FR, blockSize - 2, 2); + + cipher.ProcessBlock(FR, 0, FRE, 0); + + for (int n = 2; n < blockSize; n++) + { + FR[n - 2] = outBytes[outOff + n] = EncryptByte(input[inOff + n], n - 2); + } + + count += blockSize; + } + + return blockSize; + } + + /** + * Do the appropriate processing for CFB IV mode decryption. + * + * @param in the array containing the data to be decrypted. + * @param inOff offset into the in array the data starts at. + * @param out the array the encrypted data will be copied into. + * @param outOff the offset into the out array the output will start at. + * @exception DataLengthException if there isn't enough data in in, or + * space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + * @return the number of bytes processed and produced. + */ + private int DecryptBlock( + byte[] input, + int inOff, + byte[] outBytes, + int outOff) + { + if ((inOff + blockSize) > input.Length) + { + throw new DataLengthException("input buffer too short"); + } + + if ((outOff + blockSize) > outBytes.Length) + { + throw new DataLengthException("output buffer too short"); + } + + if (count > blockSize) + { + byte inVal = input[inOff]; + FR[blockSize - 2] = inVal; + outBytes[outOff] = EncryptByte(inVal, blockSize - 2); + + inVal = input[inOff + 1]; + FR[blockSize - 1] = inVal; + outBytes[outOff + 1] = EncryptByte(inVal, blockSize - 1); + + cipher.ProcessBlock(FR, 0, FRE, 0); + + for (int n = 2; n < blockSize; n++) + { + inVal = input[inOff + n]; + FR[n - 2] = inVal; + outBytes[outOff + n] = EncryptByte(inVal, n - 2); + } + } + else if (count == 0) + { + cipher.ProcessBlock(FR, 0, FRE, 0); + + for (int n = 0; n < blockSize; n++) + { + FR[n] = input[inOff + n]; + outBytes[n] = EncryptByte(input[inOff + n], n); + } + + count += blockSize; + } + else if (count == blockSize) + { + cipher.ProcessBlock(FR, 0, FRE, 0); + + byte inVal1 = input[inOff]; + byte inVal2 = input[inOff + 1]; + outBytes[outOff ] = EncryptByte(inVal1, 0); + outBytes[outOff + 1] = EncryptByte(inVal2, 1); + + Array.Copy(FR, 2, FR, 0, blockSize - 2); + + FR[blockSize - 2] = inVal1; + FR[blockSize - 1] = inVal2; + + cipher.ProcessBlock(FR, 0, FRE, 0); + + for (int n = 2; n < blockSize; n++) + { + byte inVal = input[inOff + n]; + FR[n - 2] = inVal; + outBytes[outOff + n] = EncryptByte(inVal, n - 2); + } + + count += blockSize; + } + + return blockSize; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/OpenPgpCfbBlockCipher.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/OpenPgpCfbBlockCipher.cs.meta new file mode 100644 index 0000000..ecfa068 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/OpenPgpCfbBlockCipher.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 45fd2354110f6c446b2c0f92b84d357b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/SicBlockCipher.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/SicBlockCipher.cs new file mode 100644 index 0000000..0bea4a4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/SicBlockCipher.cs @@ -0,0 +1,120 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Modes +{ + /** + * Implements the Segmented Integer Counter (SIC) mode on top of a simple + * block cipher. + */ + public class SicBlockCipher + : IBlockCipher + { + private readonly IBlockCipher cipher; + private readonly int blockSize; + private readonly byte[] counter; + private readonly byte[] counterOut; + private byte[] IV; + + /** + * Basic constructor. + * + * @param c the block cipher to be used. + */ + public SicBlockCipher(IBlockCipher cipher) + { + this.cipher = cipher; + this.blockSize = cipher.GetBlockSize(); + this.counter = new byte[blockSize]; + this.counterOut = new byte[blockSize]; + this.IV = new byte[blockSize]; + } + + /** + * return the underlying block cipher that we are wrapping. + * + * @return the underlying block cipher that we are wrapping. + */ + public virtual IBlockCipher GetUnderlyingCipher() + { + return cipher; + } + + public virtual void Init( + bool forEncryption, //ignored by this CTR mode + ICipherParameters parameters) + { + ParametersWithIV ivParam = parameters as ParametersWithIV; + if (ivParam == null) + throw new ArgumentException("CTR/SIC mode requires ParametersWithIV", "parameters"); + + this.IV = Arrays.Clone(ivParam.GetIV()); + + if (blockSize < IV.Length) + throw new ArgumentException("CTR/SIC mode requires IV no greater than: " + blockSize + " bytes."); + + int maxCounterSize = System.Math.Min(8, blockSize / 2); + if (blockSize - IV.Length > maxCounterSize) + throw new ArgumentException("CTR/SIC mode requires IV of at least: " + (blockSize - maxCounterSize) + " bytes."); + + // if null it's an IV changed only. + if (ivParam.Parameters != null) + { + cipher.Init(true, ivParam.Parameters); + } + + Reset(); + } + + public virtual string AlgorithmName + { + get { return cipher.AlgorithmName + "/SIC"; } + } + + public virtual bool IsPartialBlockOkay + { + get { return true; } + } + + public virtual int GetBlockSize() + { + return cipher.GetBlockSize(); + } + + public virtual int ProcessBlock( + byte[] input, + int inOff, + byte[] output, + int outOff) + { + cipher.ProcessBlock(counter, 0, counterOut, 0); + + // + // XOR the counterOut with the plaintext producing the cipher text + // + for (int i = 0; i < counterOut.Length; i++) + { + output[outOff + i] = (byte)(counterOut[i] ^ input[inOff + i]); + } + + // Increment the counter + int j = counter.Length; + while (--j >= 0 && ++counter[j] == 0) + { + } + + return counter.Length; + } + + public virtual void Reset() + { + Arrays.Fill(counter, (byte)0); + Array.Copy(IV, 0, counter, 0, IV.Length); + cipher.Reset(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/SicBlockCipher.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/SicBlockCipher.cs.meta new file mode 100644 index 0000000..17f6c15 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/SicBlockCipher.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 65461e393efeec146a73028bd5a6c7d6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm.meta new file mode 100644 index 0000000..e6eb0d4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5038e5ae9344f47409984773eb471319 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/BasicGcmExponentiator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/BasicGcmExponentiator.cs new file mode 100644 index 0000000..e7386b8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/BasicGcmExponentiator.cs @@ -0,0 +1,40 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Modes.Gcm +{ + public class BasicGcmExponentiator + : IGcmExponentiator + { + private ulong[] x; + + public void Init(byte[] x) + { + this.x = GcmUtilities.AsUlongs(x); + } + + public void ExponentiateX(long pow, byte[] output) + { + // Initial value is little-endian 1 + ulong[] y = GcmUtilities.OneAsUlongs(); + + if (pow > 0) + { + ulong[] powX = Arrays.Clone(x); + do + { + if ((pow & 1L) != 0) + { + GcmUtilities.Multiply(y, powX); + } + GcmUtilities.Square(powX, powX); + pow >>= 1; + } + while (pow > 0); + } + + GcmUtilities.AsBytes(y, output); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/BasicGcmExponentiator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/BasicGcmExponentiator.cs.meta new file mode 100644 index 0000000..349f089 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/BasicGcmExponentiator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: af0780e84fc44be45a50bad6d1eb7490 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/BasicGcmMultiplier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/BasicGcmMultiplier.cs new file mode 100644 index 0000000..644ddb1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/BasicGcmMultiplier.cs @@ -0,0 +1,22 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Modes.Gcm +{ + public class BasicGcmMultiplier + : IGcmMultiplier + { + private ulong[] H; + + public void Init(byte[] H) + { + this.H = GcmUtilities.AsUlongs(H); + } + + public void MultiplyH(byte[] x) + { + ulong[] t = GcmUtilities.AsUlongs(x); + GcmUtilities.Multiply(t, H); + GcmUtilities.AsBytes(t, x); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/BasicGcmMultiplier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/BasicGcmMultiplier.cs.meta new file mode 100644 index 0000000..5567849 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/BasicGcmMultiplier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 952e7b9afe9b1124b883cc1a06d7e014 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/GcmUtilities.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/GcmUtilities.cs new file mode 100644 index 0000000..1dd4cd6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/GcmUtilities.cs @@ -0,0 +1,504 @@ +using System; + +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Modes.Gcm +{ + internal abstract class GcmUtilities + { + private const uint E1 = 0xe1000000; + private const ulong E1UL = (ulong)E1 << 32; + + internal static byte[] OneAsBytes() + { + byte[] tmp = new byte[16]; + tmp[0] = 0x80; + return tmp; + } + + internal static uint[] OneAsUints() + { + uint[] tmp = new uint[4]; + tmp[0] = 0x80000000; + return tmp; + } + + internal static ulong[] OneAsUlongs() + { + ulong[] tmp = new ulong[2]; + tmp[0] = 1UL << 63; + return tmp; + } + + internal static byte[] AsBytes(uint[] x) + { + return Pack.UInt32_To_BE(x); + } + + internal static void AsBytes(uint[] x, byte[] z) + { + Pack.UInt32_To_BE(x, z, 0); + } + + internal static byte[] AsBytes(ulong[] x) + { + byte[] z = new byte[16]; + Pack.UInt64_To_BE(x, z, 0); + return z; + } + + internal static void AsBytes(ulong[] x, byte[] z) + { + Pack.UInt64_To_BE(x, z, 0); + } + + internal static uint[] AsUints(byte[] bs) + { + uint[] output = new uint[4]; + Pack.BE_To_UInt32(bs, 0, output); + return output; + } + + internal static void AsUints(byte[] bs, uint[] output) + { + Pack.BE_To_UInt32(bs, 0, output); + } + + internal static ulong[] AsUlongs(byte[] x) + { + ulong[] z = new ulong[2]; + Pack.BE_To_UInt64(x, 0, z); + return z; + } + + internal static void AsUlongs(byte[] x, ulong[] z) + { + Pack.BE_To_UInt64(x, 0, z); + } + + internal static void AsUlongs(byte[] x, ulong[] z, int zOff) + { + Pack.BE_To_UInt64(x, 0, z, zOff, 2); + } + + internal static void Copy(uint[] x, uint[] z) + { + z[0] = x[0]; + z[1] = x[1]; + z[2] = x[2]; + z[3] = x[3]; + } + + internal static void Copy(ulong[] x, ulong[] z) + { + z[0] = x[0]; + z[1] = x[1]; + } + + internal static void Copy(ulong[] x, int xOff, ulong[] z, int zOff) + { + z[zOff + 0] = x[xOff + 0]; + z[zOff + 1] = x[xOff + 1]; + } + + internal static void DivideP(ulong[] x, ulong[] z) + { + ulong x0 = x[0], x1 = x[1]; + ulong m = (ulong)((long)x0 >> 63); + x0 ^= (m & E1UL); + z[0] = (x0 << 1) | (x1 >> 63); + z[1] = (x1 << 1) | (ulong)(-(long)m); + } + + internal static void DivideP(ulong[] x, int xOff, ulong[] z, int zOff) + { + ulong x0 = x[xOff + 0], x1 = x[xOff + 1]; + ulong m = (ulong)((long)x0 >> 63); + x0 ^= (m & E1UL); + z[zOff + 0] = (x0 << 1) | (x1 >> 63); + z[zOff + 1] = (x1 << 1) | (ulong)(-(long)m); + } + + internal static void Multiply(byte[] x, byte[] y) + { + ulong[] t1 = AsUlongs(x); + ulong[] t2 = AsUlongs(y); + Multiply(t1, t2); + AsBytes(t1, x); + } + + internal static void Multiply(uint[] x, uint[] y) + { + uint y0 = y[0], y1 = y[1], y2 = y[2], y3 = y[3]; + uint z0 = 0, z1 = 0, z2 = 0, z3 = 0; + + for (int i = 0; i < 4; ++i) + { + int bits = (int)x[i]; + for (int j = 0; j < 32; ++j) + { + uint m1 = (uint)(bits >> 31); bits <<= 1; + z0 ^= y0 & m1; + z1 ^= y1 & m1; + z2 ^= y2 & m1; + z3 ^= y3 & m1; + + uint m2 = (uint)((int)(y3 << 31) >> 8); + y3 = (y3 >> 1) | (y2 << 31); + y2 = (y2 >> 1) | (y1 << 31); + y1 = (y1 >> 1) | (y0 << 31); + y0 = (y0 >> 1) ^ (m2 & E1); + } + } + + x[0] = z0; + x[1] = z1; + x[2] = z2; + x[3] = z3; + } + + internal static void Multiply(ulong[] x, ulong[] y) + { + //ulong x0 = x[0], x1 = x[1]; + //ulong y0 = y[0], y1 = y[1]; + //ulong z0 = 0, z1 = 0, z2 = 0; + + //for (int j = 0; j < 64; ++j) + //{ + // ulong m0 = (ulong)((long)x0 >> 63); x0 <<= 1; + // z0 ^= y0 & m0; + // z1 ^= y1 & m0; + + // ulong m1 = (ulong)((long)x1 >> 63); x1 <<= 1; + // z1 ^= y0 & m1; + // z2 ^= y1 & m1; + + // ulong c = (ulong)((long)(y1 << 63) >> 8); + // y1 = (y1 >> 1) | (y0 << 63); + // y0 = (y0 >> 1) ^ (c & E1UL); + //} + + //z0 ^= z2 ^ (z2 >> 1) ^ (z2 >> 2) ^ (z2 >> 7); + //z1 ^= (z2 << 63) ^ (z2 << 62) ^ (z2 << 57); + + //x[0] = z0; + //x[1] = z1; + + /* + * "Three-way recursion" as described in "Batch binary Edwards", Daniel J. Bernstein. + * + * Without access to the high part of a 64x64 product x * y, we use a bit reversal to calculate it: + * rev(x) * rev(y) == rev((x * y) << 1) + */ + + ulong x0 = x[0], x1 = x[1]; + ulong y0 = y[0], y1 = y[1]; + ulong x0r = Longs.Reverse(x0), x1r = Longs.Reverse(x1); + ulong y0r = Longs.Reverse(y0), y1r = Longs.Reverse(y1); + + ulong h0 = Longs.Reverse(ImplMul64(x0r, y0r)); + ulong h1 = ImplMul64(x0, y0) << 1; + ulong h2 = Longs.Reverse(ImplMul64(x1r, y1r)); + ulong h3 = ImplMul64(x1, y1) << 1; + ulong h4 = Longs.Reverse(ImplMul64(x0r ^ x1r, y0r ^ y1r)); + ulong h5 = ImplMul64(x0 ^ x1, y0 ^ y1) << 1; + + ulong z0 = h0; + ulong z1 = h1 ^ h0 ^ h2 ^ h4; + ulong z2 = h2 ^ h1 ^ h3 ^ h5; + ulong z3 = h3; + + z1 ^= z3 ^ (z3 >> 1) ^ (z3 >> 2) ^ (z3 >> 7); +// z2 ^= (z3 << 63) ^ (z3 << 62) ^ (z3 << 57); + z2 ^= (z3 << 62) ^ (z3 << 57); + + z0 ^= z2 ^ (z2 >> 1) ^ (z2 >> 2) ^ (z2 >> 7); + z1 ^= (z2 << 63) ^ (z2 << 62) ^ (z2 << 57); + + x[0] = z0; + x[1] = z1; + } + + internal static void MultiplyP(uint[] x) + { + uint x0 = x[0], x1 = x[1], x2 = x[2], x3 = x[3]; + uint m = (uint)((int)(x3 << 31) >> 31); + x[0] = (x0 >> 1) ^ (m & E1); + x[1] = (x1 >> 1) | (x0 << 31); + x[2] = (x2 >> 1) | (x1 << 31); + x[3] = (x3 >> 1) | (x2 << 31); + } + + internal static void MultiplyP(uint[] x, uint[] z) + { + uint x0 = x[0], x1 = x[1], x2 = x[2], x3 = x[3]; + uint m = (uint)((int)(x3 << 31) >> 31); + z[0] = (x0 >> 1) ^ (m & E1); + z[1] = (x1 >> 1) | (x0 << 31); + z[2] = (x2 >> 1) | (x1 << 31); + z[3] = (x3 >> 1) | (x2 << 31); + } + + internal static void MultiplyP(ulong[] x) + { + ulong x0 = x[0], x1 = x[1]; + ulong m = (ulong)((long)(x1 << 63) >> 63); + x[0] = (x0 >> 1) ^ (m & E1UL); + x[1] = (x1 >> 1) | (x0 << 63); + } + + internal static void MultiplyP(ulong[] x, ulong[] z) + { + ulong x0 = x[0], x1 = x[1]; + ulong m = (ulong)((long)(x1 << 63) >> 63); + z[0] = (x0 >> 1) ^ (m & E1UL); + z[1] = (x1 >> 1) | (x0 << 63); + } + + internal static void MultiplyP3(ulong[] x, ulong[] z) + { + ulong x0 = x[0], x1 = x[1]; + ulong c = x1 << 61; + z[0] = (x0 >> 3) ^ c ^ (c >> 1) ^ (c >> 2) ^ (c >> 7); + z[1] = (x1 >> 3) | (x0 << 61); + } + + internal static void MultiplyP3(ulong[] x, int xOff, ulong[] z, int zOff) + { + ulong x0 = x[xOff + 0], x1 = x[xOff + 1]; + ulong c = x1 << 61; + z[zOff + 0] = (x0 >> 3) ^ c ^ (c >> 1) ^ (c >> 2) ^ (c >> 7); + z[zOff + 1] = (x1 >> 3) | (x0 << 61); + } + + internal static void MultiplyP4(ulong[] x, ulong[] z) + { + ulong x0 = x[0], x1 = x[1]; + ulong c = x1 << 60; + z[0] = (x0 >> 4) ^ c ^ (c >> 1) ^ (c >> 2) ^ (c >> 7); + z[1] = (x1 >> 4) | (x0 << 60); + } + + internal static void MultiplyP4(ulong[] x, int xOff, ulong[] z, int zOff) + { + ulong x0 = x[xOff + 0], x1 = x[xOff + 1]; + ulong c = x1 << 60; + z[zOff + 0] = (x0 >> 4) ^ c ^ (c >> 1) ^ (c >> 2) ^ (c >> 7); + z[zOff + 1] = (x1 >> 4) | (x0 << 60); + } + + internal static void MultiplyP7(ulong[] x, ulong[] z) + { + ulong x0 = x[0], x1 = x[1]; + ulong c = x1 << 57; + z[0] = (x0 >> 7) ^ c ^ (c >> 1) ^ (c >> 2) ^ (c >> 7); + z[1] = (x1 >> 7) | (x0 << 57); + } + + internal static void MultiplyP7(ulong[] x, int xOff, ulong[] z, int zOff) + { + ulong x0 = x[xOff + 0], x1 = x[xOff + 1]; + ulong c = x1 << 57; + z[zOff + 0] = (x0 >> 7) ^ c ^ (c >> 1) ^ (c >> 2) ^ (c >> 7); + z[zOff + 1] = (x1 >> 7) | (x0 << 57); + } + + internal static void MultiplyP8(uint[] x) + { + uint x0 = x[0], x1 = x[1], x2 = x[2], x3 = x[3]; + uint c = x3 << 24; + x[0] = (x0 >> 8) ^ c ^ (c >> 1) ^ (c >> 2) ^ (c >> 7); + x[1] = (x1 >> 8) | (x0 << 24); + x[2] = (x2 >> 8) | (x1 << 24); + x[3] = (x3 >> 8) | (x2 << 24); + } + + internal static void MultiplyP8(uint[] x, uint[] y) + { + uint x0 = x[0], x1 = x[1], x2 = x[2], x3 = x[3]; + uint c = x3 << 24; + y[0] = (x0 >> 8) ^ c ^ (c >> 1) ^ (c >> 2) ^ (c >> 7); + y[1] = (x1 >> 8) | (x0 << 24); + y[2] = (x2 >> 8) | (x1 << 24); + y[3] = (x3 >> 8) | (x2 << 24); + } + + internal static void MultiplyP8(ulong[] x) + { + ulong x0 = x[0], x1 = x[1]; + ulong c = x1 << 56; + x[0] = (x0 >> 8) ^ c ^ (c >> 1) ^ (c >> 2) ^ (c >> 7); + x[1] = (x1 >> 8) | (x0 << 56); + } + + internal static void MultiplyP8(ulong[] x, ulong[] y) + { + ulong x0 = x[0], x1 = x[1]; + ulong c = x1 << 56; + y[0] = (x0 >> 8) ^ c ^ (c >> 1) ^ (c >> 2) ^ (c >> 7); + y[1] = (x1 >> 8) | (x0 << 56); + } + + internal static void MultiplyP8(ulong[] x, int xOff, ulong[] y, int yOff) + { + ulong x0 = x[xOff + 0], x1 = x[xOff + 1]; + ulong c = x1 << 56; + y[yOff + 0] = (x0 >> 8) ^ c ^ (c >> 1) ^ (c >> 2) ^ (c >> 7); + y[yOff + 1] = (x1 >> 8) | (x0 << 56); + } + + internal static void Square(ulong[] x, ulong[] z) + { + ulong[] t = new ulong[4]; + Interleave.Expand64To128Rev(x[0], t, 0); + Interleave.Expand64To128Rev(x[1], t, 2); + + ulong z0 = t[0], z1 = t[1], z2 = t[2], z3 = t[3]; + + z1 ^= z3 ^ (z3 >> 1) ^ (z3 >> 2) ^ (z3 >> 7); +// z2 ^= (z3 << 63) ^ (z3 << 62) ^ (z3 << 57); + z2 ^= (z3 << 62) ^ (z3 << 57); + + z0 ^= z2 ^ (z2 >> 1) ^ (z2 >> 2) ^ (z2 >> 7); + z1 ^= (z2 << 63) ^ (z2 << 62) ^ (z2 << 57); + + z[0] = z0; + z[1] = z1; + } + + internal static void Xor(byte[] x, byte[] y) + { + int i = 0; + do + { + x[i] ^= y[i]; ++i; + x[i] ^= y[i]; ++i; + x[i] ^= y[i]; ++i; + x[i] ^= y[i]; ++i; + } + while (i < 16); + } + + internal static void Xor(byte[] x, byte[] y, int yOff) + { + int i = 0; + do + { + x[i] ^= y[yOff + i]; ++i; + x[i] ^= y[yOff + i]; ++i; + x[i] ^= y[yOff + i]; ++i; + x[i] ^= y[yOff + i]; ++i; + } + while (i < 16); + } + + internal static void Xor(byte[] x, int xOff, byte[] y, int yOff, byte[] z, int zOff) + { + int i = 0; + do + { + z[zOff + i] = (byte)(x[xOff + i] ^ y[yOff + i]); ++i; + z[zOff + i] = (byte)(x[xOff + i] ^ y[yOff + i]); ++i; + z[zOff + i] = (byte)(x[xOff + i] ^ y[yOff + i]); ++i; + z[zOff + i] = (byte)(x[xOff + i] ^ y[yOff + i]); ++i; + } + while (i < 16); + } + + internal static void Xor(byte[] x, byte[] y, int yOff, int yLen) + { + while (--yLen >= 0) + { + x[yLen] ^= y[yOff + yLen]; + } + } + + internal static void Xor(byte[] x, int xOff, byte[] y, int yOff, int len) + { + while (--len >= 0) + { + x[xOff + len] ^= y[yOff + len]; + } + } + + internal static void Xor(byte[] x, byte[] y, byte[] z) + { + int i = 0; + do + { + z[i] = (byte)(x[i] ^ y[i]); ++i; + z[i] = (byte)(x[i] ^ y[i]); ++i; + z[i] = (byte)(x[i] ^ y[i]); ++i; + z[i] = (byte)(x[i] ^ y[i]); ++i; + } + while (i < 16); + } + + internal static void Xor(uint[] x, uint[] y) + { + x[0] ^= y[0]; + x[1] ^= y[1]; + x[2] ^= y[2]; + x[3] ^= y[3]; + } + + internal static void Xor(uint[] x, uint[] y, uint[] z) + { + z[0] = x[0] ^ y[0]; + z[1] = x[1] ^ y[1]; + z[2] = x[2] ^ y[2]; + z[3] = x[3] ^ y[3]; + } + + internal static void Xor(ulong[] x, ulong[] y) + { + x[0] ^= y[0]; + x[1] ^= y[1]; + } + + internal static void Xor(ulong[] x, int xOff, ulong[] y, int yOff) + { + x[xOff + 0] ^= y[yOff + 0]; + x[xOff + 1] ^= y[yOff + 1]; + } + + internal static void Xor(ulong[] x, ulong[] y, ulong[] z) + { + z[0] = x[0] ^ y[0]; + z[1] = x[1] ^ y[1]; + } + + internal static void Xor(ulong[] x, int xOff, ulong[] y, int yOff, ulong[] z, int zOff) + { + z[zOff + 0] = x[xOff + 0] ^ y[yOff + 0]; + z[zOff + 1] = x[xOff + 1] ^ y[yOff + 1]; + } + + private static ulong ImplMul64(ulong x, ulong y) + { + ulong x0 = x & 0x1111111111111111UL; + ulong x1 = x & 0x2222222222222222UL; + ulong x2 = x & 0x4444444444444444UL; + ulong x3 = x & 0x8888888888888888UL; + + ulong y0 = y & 0x1111111111111111UL; + ulong y1 = y & 0x2222222222222222UL; + ulong y2 = y & 0x4444444444444444UL; + ulong y3 = y & 0x8888888888888888UL; + + ulong z0 = (x0 * y0) ^ (x1 * y3) ^ (x2 * y2) ^ (x3 * y1); + ulong z1 = (x0 * y1) ^ (x1 * y0) ^ (x2 * y3) ^ (x3 * y2); + ulong z2 = (x0 * y2) ^ (x1 * y1) ^ (x2 * y0) ^ (x3 * y3); + ulong z3 = (x0 * y3) ^ (x1 * y2) ^ (x2 * y1) ^ (x3 * y0); + + z0 &= 0x1111111111111111UL; + z1 &= 0x2222222222222222UL; + z2 &= 0x4444444444444444UL; + z3 &= 0x8888888888888888UL; + + return z0 | z1 | z2 | z3; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/GcmUtilities.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/GcmUtilities.cs.meta new file mode 100644 index 0000000..6d30c32 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/GcmUtilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3e0dfba6699671a4dab951c597501a43 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/IGcmExponentiator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/IGcmExponentiator.cs new file mode 100644 index 0000000..5b4ce9d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/IGcmExponentiator.cs @@ -0,0 +1,10 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Modes.Gcm +{ + public interface IGcmExponentiator + { + void Init(byte[] x); + void ExponentiateX(long pow, byte[] output); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/IGcmExponentiator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/IGcmExponentiator.cs.meta new file mode 100644 index 0000000..9ec88fe --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/IGcmExponentiator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 48f8572864fb1e841a20887f6321c441 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/IGcmMultiplier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/IGcmMultiplier.cs new file mode 100644 index 0000000..ec7b906 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/IGcmMultiplier.cs @@ -0,0 +1,10 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Modes.Gcm +{ + public interface IGcmMultiplier + { + void Init(byte[] H); + void MultiplyH(byte[] x); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/IGcmMultiplier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/IGcmMultiplier.cs.meta new file mode 100644 index 0000000..e673bea --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/IGcmMultiplier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4068377abc5a7e34c80fc08b23efa107 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/Tables1kGcmExponentiator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/Tables1kGcmExponentiator.cs new file mode 100644 index 0000000..3667241 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/Tables1kGcmExponentiator.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Modes.Gcm +{ + public class Tables1kGcmExponentiator + : IGcmExponentiator + { + // A lookup table of the power-of-two powers of 'x' + // - lookupPowX2[i] = x^(2^i) + private IList lookupPowX2; + + public void Init(byte[] x) + { + ulong[] y = GcmUtilities.AsUlongs(x); + if (lookupPowX2 != null && Arrays.AreEqual(y, (ulong[])lookupPowX2[0])) + return; + + lookupPowX2 = Platform.CreateArrayList(8); + lookupPowX2.Add(y); + } + + public void ExponentiateX(long pow, byte[] output) + { + ulong[] y = GcmUtilities.OneAsUlongs(); + int bit = 0; + while (pow > 0) + { + if ((pow & 1L) != 0) + { + EnsureAvailable(bit); + GcmUtilities.Multiply(y, (ulong[])lookupPowX2[bit]); + } + ++bit; + pow >>= 1; + } + + GcmUtilities.AsBytes(y, output); + } + + private void EnsureAvailable(int bit) + { + int count = lookupPowX2.Count; + if (count <= bit) + { + ulong[] tmp = (ulong[])lookupPowX2[count - 1]; + do + { + tmp = Arrays.Clone(tmp); + GcmUtilities.Square(tmp, tmp); + lookupPowX2.Add(tmp); + } + while (++count <= bit); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/Tables1kGcmExponentiator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/Tables1kGcmExponentiator.cs.meta new file mode 100644 index 0000000..b110f98 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/Tables1kGcmExponentiator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ae26b43759cd28948bf94fcb938379e8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/Tables4kGcmMultiplier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/Tables4kGcmMultiplier.cs new file mode 100644 index 0000000..3ed596e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/Tables4kGcmMultiplier.cs @@ -0,0 +1,70 @@ +using System; + +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Modes.Gcm +{ + public class Tables4kGcmMultiplier + : IGcmMultiplier + { + private byte[] H; + private ulong[] T; + + public void Init(byte[] H) + { + if (T == null) + { + T = new ulong[512]; + } + else if (Arrays.AreEqual(this.H, H)) + { + return; + } + + this.H = Arrays.Clone(H); + + // T[0] = 0 + + // T[1] = H.p^7 + GcmUtilities.AsUlongs(this.H, T, 2); + GcmUtilities.MultiplyP7(T, 2, T, 2); + + for (int n = 2; n < 256; n += 2) + { + // T[2.n] = T[n].p^-1 + GcmUtilities.DivideP(T, n, T, n << 1); + + // T[2.n + 1] = T[2.n] + T[1] + GcmUtilities.Xor(T, n << 1, T, 2, T, (n + 1) << 1); + } + } + + public void MultiplyH(byte[] x) + { + //ulong[] z = new ulong[2]; + //GcmUtilities.Copy(T, x[15] << 1, z, 0); + //for (int i = 14; i >= 0; --i) + //{ + // GcmUtilities.MultiplyP8(z); + // GcmUtilities.Xor(z, 0, T, x[i] << 1); + //} + //Pack.UInt64_To_BE(z, x, 0); + + int pos = x[15] << 1; + ulong z0 = T[pos + 0], z1 = T[pos + 1]; + + for (int i = 14; i >= 0; --i) + { + pos = x[i] << 1; + + ulong c = z1 << 56; + z1 = T[pos + 1] ^ ((z1 >> 8) | (z0 << 56)); + z0 = T[pos + 0] ^ (z0 >> 8) ^ c ^ (c >> 1) ^ (c >> 2) ^ (c >> 7); + } + + Pack.UInt64_To_BE(z0, x, 0); + Pack.UInt64_To_BE(z1, x, 8); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/Tables4kGcmMultiplier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/Tables4kGcmMultiplier.cs.meta new file mode 100644 index 0000000..c74f815 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/Tables4kGcmMultiplier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dada64b48462cf14895fd07f5f6f51ca +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/Tables64kGcmMultiplier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/Tables64kGcmMultiplier.cs new file mode 100644 index 0000000..0c15ff6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/Tables64kGcmMultiplier.cs @@ -0,0 +1,81 @@ +using System; + +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Modes.Gcm +{ + public class Tables64kGcmMultiplier + : IGcmMultiplier + { + private byte[] H; + private ulong[][] T; + + public void Init(byte[] H) + { + if (T == null) + { + T = new ulong[16][]; + } + else if (Arrays.AreEqual(this.H, H)) + { + return; + } + + this.H = Arrays.Clone(H); + + for (int i = 0; i < 16; ++i) + { + ulong[] t = T[i] = new ulong[512]; + + // t[0] = 0 + + if (i == 0) + { + // t[1] = H.p^7 + GcmUtilities.AsUlongs(this.H, t, 2); + GcmUtilities.MultiplyP7(t, 2, t, 2); + } + else + { + // t[1] = T[i-1][1].p^8 + GcmUtilities.MultiplyP8(T[i - 1], 2, t, 2); + } + + for (int n = 2; n < 256; n += 2) + { + // t[2.n] = t[n].p^-1 + GcmUtilities.DivideP(t, n, t, n << 1); + + // t[2.n + 1] = t[2.n] + t[1] + GcmUtilities.Xor(t, n << 1, t, 2, t, (n + 1) << 1); + } + } + } + + public void MultiplyH(byte[] x) + { + //ulong[] z = new ulong[2]; + //for (int i = 15; i >= 0; --i) + //{ + // GcmUtilities.Xor(z, 0, T[i], x[i] << 1); + //} + //Pack.UInt64_To_BE(z, x, 0); + + ulong[] t = T[15]; + int tPos = x[15] << 1; + ulong z0 = t[tPos + 0], z1 = t[tPos + 1]; + + for (int i = 14; i >= 0; --i) + { + t = T[i]; + tPos = x[i] << 1; + z0 ^= t[tPos + 0]; + z1 ^= t[tPos + 1]; + } + + Pack.UInt64_To_BE(z0, x, 0); + Pack.UInt64_To_BE(z1, x, 8); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/Tables64kGcmMultiplier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/Tables64kGcmMultiplier.cs.meta new file mode 100644 index 0000000..c3618da --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/Tables64kGcmMultiplier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d5db9f1262e2ec14db24551b423c11b3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/Tables8kGcmMultiplier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/Tables8kGcmMultiplier.cs new file mode 100644 index 0000000..81f60bb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/Tables8kGcmMultiplier.cs @@ -0,0 +1,81 @@ +using System; + +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Modes.Gcm +{ + public class Tables8kGcmMultiplier + : IGcmMultiplier + { + private byte[] H; + private ulong[][] T; + + public void Init(byte[] H) + { + if (T == null) + { + T = new ulong[32][]; + } + else if (Arrays.AreEqual(this.H, H)) + { + return; + } + + this.H = Arrays.Clone(H); + + for (int i = 0; i < 32; ++i) + { + ulong[] t = T[i] = new ulong[32]; + + // t[0] = 0 + + if (i == 0) + { + // t[1] = H.p^3 + GcmUtilities.AsUlongs(this.H, t, 2); + GcmUtilities.MultiplyP3(t, 2, t, 2); + } + else + { + // t[1] = T[i-1][1].p^4 + GcmUtilities.MultiplyP4(T[i - 1], 2, t, 2); + } + + for (int n = 2; n < 16; n += 2) + { + // t[2.n] = t[n].p^-1 + GcmUtilities.DivideP(t, n, t, n << 1); + + // t[2.n + 1] = t[2.n] + t[1] + GcmUtilities.Xor(t, n << 1, t, 2, t, (n + 1) << 1); + } + } + } + + public void MultiplyH(byte[] x) + { + //ulong[] z = new ulong[2]; + //for (int i = 15; i >= 0; --i) + //{ + // GcmUtilities.Xor(z, 0, T[i + i + 1], (x[i] & 0x0F) << 1); + // GcmUtilities.Xor(z, 0, T[i + i], (x[i] & 0xF0) >> 3); + //} + //Pack.UInt64_To_BE(z, x, 0); + + ulong z0 = 0, z1 = 0; + + for (int i = 15; i >= 0; --i) + { + ulong[] tu = T[i + i + 1], tv = T[i + i]; + int uPos = (x[i] & 0x0F) << 1, vPos = (x[i] & 0xF0) >> 3; + + z0 ^= tu[uPos + 0] ^ tv[vPos + 0]; + z1 ^= tu[uPos + 1] ^ tv[vPos + 1]; + } + + Pack.UInt64_To_BE(z0, x, 0); + Pack.UInt64_To_BE(z1, x, 8); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/Tables8kGcmMultiplier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/Tables8kGcmMultiplier.cs.meta new file mode 100644 index 0000000..2c43142 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/modes/gcm/Tables8kGcmMultiplier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8ebdaf7aee582d3488d5c4339485281b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators.meta new file mode 100644 index 0000000..ec1bcbd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: bcbfed6e56b17bb4e988fb3d86e8d38d +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/Asn1CipherBuilder.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/Asn1CipherBuilder.cs new file mode 100644 index 0000000..d584074 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/Asn1CipherBuilder.cs @@ -0,0 +1,100 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Ntt; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Cms; +using Org.BouncyCastle.Crypto.IO; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Operators +{ + public class Asn1CipherBuilderWithKey : ICipherBuilderWithKey + { + private readonly KeyParameter encKey; + private AlgorithmIdentifier algorithmIdentifier; + + public Asn1CipherBuilderWithKey(DerObjectIdentifier encryptionOID, int keySize, SecureRandom random) + { + if (random == null) + { + random = new SecureRandom(); + } + + CipherKeyGenerator keyGen = CipherKeyGeneratorFactory.CreateKeyGenerator(encryptionOID, random); + + encKey = new KeyParameter(keyGen.GenerateKey()); + algorithmIdentifier = AlgorithmIdentifierFactory.GenerateEncryptionAlgID(encryptionOID, encKey.GetKey().Length * 8, random); + } + + public object AlgorithmDetails + { + get { return algorithmIdentifier; } + } + + public int GetMaxOutputSize(int inputLen) + { + throw new NotImplementedException(); + } + + public ICipher BuildCipher(Stream stream) + { + object cipher = EnvelopedDataHelper.CreateContentCipher(true, encKey, algorithmIdentifier); + + // + // BufferedBlockCipher + // IStreamCipher + // + + if (cipher is IStreamCipher) + { + cipher = new BufferedStreamCipher((IStreamCipher)cipher); + } + + if (stream == null) + { + stream = new MemoryStream(); + } + + return new BufferedCipherWrapper((IBufferedCipher)cipher, stream); + } + + public ICipherParameters Key + { + get { return encKey; } + } + } + + public class BufferedCipherWrapper : ICipher + { + private readonly IBufferedCipher bufferedCipher; + private readonly CipherStream stream; + + public BufferedCipherWrapper(IBufferedCipher bufferedCipher, Stream source) + { + this.bufferedCipher = bufferedCipher; + stream = new CipherStream(source, bufferedCipher, bufferedCipher); + } + + public int GetMaxOutputSize(int inputLen) + { + return bufferedCipher.GetOutputSize(inputLen); + } + + public int GetUpdateOutputSize(int inputLen) + { + return bufferedCipher.GetUpdateOutputSize(inputLen); + } + + public Stream Stream + { + get { return stream; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/Asn1CipherBuilder.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/Asn1CipherBuilder.cs.meta new file mode 100644 index 0000000..f8cacdf --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/Asn1CipherBuilder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 152ee81daf5812d4793f022defc6f484 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/Asn1DigestFactory.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/Asn1DigestFactory.cs new file mode 100644 index 0000000..91fb46c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/Asn1DigestFactory.cs @@ -0,0 +1,70 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto.IO; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Operators +{ + public class Asn1DigestFactory : IDigestFactory + { + public static Asn1DigestFactory Get(DerObjectIdentifier oid) + { + return new Asn1DigestFactory(DigestUtilities.GetDigest(oid), oid); + } + + public static Asn1DigestFactory Get(String mechanism) + { + DerObjectIdentifier oid = DigestUtilities.GetObjectIdentifier(mechanism); + return new Asn1DigestFactory(DigestUtilities.GetDigest(oid), oid); + } + + private readonly IDigest mDigest; + private readonly DerObjectIdentifier mOid; + + public Asn1DigestFactory(IDigest digest, DerObjectIdentifier oid) + { + this.mDigest = digest; + this.mOid = oid; + } + + public virtual object AlgorithmDetails + { + get { return new AlgorithmIdentifier(mOid); } + } + + public virtual int DigestLength + { + get { return mDigest.GetDigestSize(); } + } + + public virtual IStreamCalculator CreateCalculator() + { + return new DfDigestStream(mDigest); + } + } + + internal class DfDigestStream : IStreamCalculator + { + private readonly DigestSink mStream; + + public DfDigestStream(IDigest digest) + { + this.mStream = new DigestSink(digest); + } + + public Stream Stream + { + get { return mStream; } + } + + public object GetResult() + { + byte[] result = new byte[mStream.Digest.GetDigestSize()]; + mStream.Digest.DoFinal(result, 0); + return new SimpleBlockResult(result); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/Asn1DigestFactory.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/Asn1DigestFactory.cs.meta new file mode 100644 index 0000000..f554d16 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/Asn1DigestFactory.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c2f2513622884864cbde81df94bcc05f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/Asn1KeyWrapper.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/Asn1KeyWrapper.cs new file mode 100644 index 0000000..a34d93d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/Asn1KeyWrapper.cs @@ -0,0 +1,318 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Oiw; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto.Encodings; +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.Crypto.Operators +{ + public class Asn1KeyWrapper + : IKeyWrapper + { + private string algorithm; + private IKeyWrapper wrapper; + + public Asn1KeyWrapper(string algorithm, X509Certificate cert) + { + this.algorithm = algorithm; + wrapper = KeyWrapperUtil.WrapperForName(algorithm, cert.GetPublicKey()); + } + + public Asn1KeyWrapper(DerObjectIdentifier algorithm, X509Certificate cert) + : this(algorithm, cert.GetPublicKey()) + { + } + + public Asn1KeyWrapper(DerObjectIdentifier algorithm, ICipherParameters key) + : this(algorithm, null, key) + { + } + + public Asn1KeyWrapper(DerObjectIdentifier algorithm, Asn1Encodable parameters, X509Certificate cert) + :this(algorithm, parameters, cert.GetPublicKey()) + { + } + + public Asn1KeyWrapper(DerObjectIdentifier algorithm, Asn1Encodable parameters, ICipherParameters key) + { + this.algorithm = algorithm.Id; + if (algorithm.Equals(PkcsObjectIdentifiers.IdRsaesOaep)) + { + RsaesOaepParameters oaepParams = RsaesOaepParameters.GetInstance(parameters); + WrapperProvider provider; + if (oaepParams.MaskGenAlgorithm.Algorithm.Equals(PkcsObjectIdentifiers.IdMgf1)) + { + AlgorithmIdentifier digAlg = AlgorithmIdentifier.GetInstance(oaepParams.MaskGenAlgorithm.Parameters); + + provider = new RsaOaepWrapperProvider(oaepParams.HashAlgorithm.Algorithm, digAlg.Algorithm); + } + else + { + provider = new RsaOaepWrapperProvider(oaepParams.HashAlgorithm.Algorithm, oaepParams.MaskGenAlgorithm.Algorithm); + } + wrapper = (IKeyWrapper)provider.CreateWrapper(true, key); + } + else if (algorithm.Equals(PkcsObjectIdentifiers.RsaEncryption)) + { + wrapper = (IKeyWrapper)new RsaPkcs1Wrapper(true, key); + } + else + { + throw new ArgumentException("unknown algorithm: " + algorithm.Id); + } + } + + public object AlgorithmDetails + { + get { return wrapper.AlgorithmDetails; } + } + + public IBlockResult Wrap(byte[] keyData) + { + return wrapper.Wrap(keyData); + } + } + + public class Asn1KeyUnwrapper + : IKeyUnwrapper + { + private string algorithm; + private IKeyUnwrapper wrapper; + + public Asn1KeyUnwrapper(string algorithm, ICipherParameters key) + { + this.algorithm = algorithm; + wrapper = KeyWrapperUtil.UnwrapperForName(algorithm, key); + } + + public Asn1KeyUnwrapper(DerObjectIdentifier algorithm, ICipherParameters key) + : this(algorithm, null, key) + { + } + + public Asn1KeyUnwrapper(DerObjectIdentifier algorithm, Asn1Encodable parameters, ICipherParameters key) + { + this.algorithm = algorithm.Id; + if (algorithm.Equals(PkcsObjectIdentifiers.IdRsaesOaep)) + { + RsaesOaepParameters oaepParams = RsaesOaepParameters.GetInstance(parameters); + WrapperProvider provider; + if (oaepParams.MaskGenAlgorithm.Algorithm.Equals(PkcsObjectIdentifiers.IdMgf1)) + { + AlgorithmIdentifier digAlg = AlgorithmIdentifier.GetInstance(oaepParams.MaskGenAlgorithm.Parameters); + + provider = new RsaOaepWrapperProvider(oaepParams.HashAlgorithm.Algorithm, digAlg.Algorithm); + } + else + { + provider = new RsaOaepWrapperProvider(oaepParams.HashAlgorithm.Algorithm, oaepParams.MaskGenAlgorithm.Algorithm); + } + wrapper = (IKeyUnwrapper)provider.CreateWrapper(false, key); + } + else if (algorithm.Equals(PkcsObjectIdentifiers.RsaEncryption)) + { + RsaesOaepParameters oaepParams = RsaesOaepParameters.GetInstance(parameters); + WrapperProvider provider; + if (oaepParams.MaskGenAlgorithm.Algorithm.Equals(PkcsObjectIdentifiers.IdMgf1)) + { + AlgorithmIdentifier digAlg = AlgorithmIdentifier.GetInstance(oaepParams.MaskGenAlgorithm.Parameters); + + provider = new RsaOaepWrapperProvider(oaepParams.HashAlgorithm.Algorithm, digAlg.Algorithm); + } + else + { + provider = new RsaOaepWrapperProvider(oaepParams.HashAlgorithm.Algorithm, oaepParams.MaskGenAlgorithm.Algorithm); + } + wrapper = (IKeyUnwrapper)new RsaPkcs1Wrapper(false, key); + } + else + { + throw new ArgumentException("unknown algorithm: " + algorithm.Id); + } + } + + public object AlgorithmDetails + { + get { return wrapper.AlgorithmDetails; } + } + + public IBlockResult Unwrap(byte[] keyData, int offSet, int length) + { + return wrapper.Unwrap(keyData, offSet, length); + } + } + + internal class KeyWrapperUtil + { + // + // Provider + // + private static readonly IDictionary providerMap = Platform.CreateHashtable(); + + static KeyWrapperUtil() + + { + providerMap.Add("RSA/ECB/PKCS1PADDING", new RsaOaepWrapperProvider(OiwObjectIdentifiers.IdSha1)); + providerMap.Add("RSA/NONE/PKCS1PADDING", new RsaOaepWrapperProvider(OiwObjectIdentifiers.IdSha1)); + providerMap.Add("RSA/NONE/OAEPWITHSHA1ANDMGF1PADDING", new RsaOaepWrapperProvider(OiwObjectIdentifiers.IdSha1)); + providerMap.Add("RSA/NONE/OAEPWITHSHA224ANDMGF1PADDING", new RsaOaepWrapperProvider(NistObjectIdentifiers.IdSha224)); + providerMap.Add("RSA/NONE/OAEPWITHSHA256ANDMGF1PADDING", new RsaOaepWrapperProvider(NistObjectIdentifiers.IdSha256)); + providerMap.Add("RSA/NONE/OAEPWITHSHA384ANDMGF1PADDING", new RsaOaepWrapperProvider(NistObjectIdentifiers.IdSha384)); + providerMap.Add("RSA/NONE/OAEPWITHSHA512ANDMGF1PADDING", new RsaOaepWrapperProvider(NistObjectIdentifiers.IdSha512)); + providerMap.Add("RSA/NONE/OAEPWITHSHA256ANDMGF1WITHSHA1PADDING", new RsaOaepWrapperProvider(NistObjectIdentifiers.IdSha256, OiwObjectIdentifiers.IdSha1)); + } + + public static IKeyWrapper WrapperForName(string algorithm, ICipherParameters parameters) + { + WrapperProvider provider = (WrapperProvider)providerMap[Strings.ToUpperCase(algorithm)]; + + if (provider == null) + throw new ArgumentException("could not resolve " + algorithm + " to a KeyWrapper"); + + return (IKeyWrapper)provider.CreateWrapper(true, parameters); + } + + public static IKeyUnwrapper UnwrapperForName(string algorithm, ICipherParameters parameters) + { + WrapperProvider provider = (WrapperProvider)providerMap[Strings.ToUpperCase(algorithm)]; + if (provider == null) + throw new ArgumentException("could not resolve " + algorithm + " to a KeyUnwrapper"); + + return (IKeyUnwrapper)provider.CreateWrapper(false, parameters); + } + } + + internal interface WrapperProvider + { + object CreateWrapper(bool forWrapping, ICipherParameters parameters); + } + + internal class RsaPkcs1Wrapper : IKeyWrapper, IKeyUnwrapper + { + private readonly AlgorithmIdentifier algId; + private readonly IAsymmetricBlockCipher engine; + + public RsaPkcs1Wrapper(bool forWrapping, ICipherParameters parameters) + { + this.algId = new AlgorithmIdentifier( + PkcsObjectIdentifiers.RsaEncryption, + DerNull.Instance); + + this.engine = new Pkcs1Encoding(new RsaBlindedEngine()); + this.engine.Init(forWrapping, parameters); + } + + public object AlgorithmDetails + { + get { return algId; } + } + + public IBlockResult Unwrap(byte[] cipherText, int offset, int length) + { + return new SimpleBlockResult(engine.ProcessBlock(cipherText, offset, length)); + } + + public IBlockResult Wrap(byte[] keyData) + { + return new SimpleBlockResult(engine.ProcessBlock(keyData, 0, keyData.Length)); + } + } + + internal class RsaPkcs1WrapperProvider + : WrapperProvider + { + internal RsaPkcs1WrapperProvider() + { + } + + object WrapperProvider.CreateWrapper(bool forWrapping, ICipherParameters parameters) + { + return new RsaPkcs1Wrapper(forWrapping, parameters); + } + } + + internal class RsaOaepWrapper : IKeyWrapper, IKeyUnwrapper + { + private readonly AlgorithmIdentifier algId; + private readonly IAsymmetricBlockCipher engine; + + public RsaOaepWrapper(bool forWrapping, ICipherParameters parameters, DerObjectIdentifier digestOid) + : this(forWrapping, parameters, digestOid, digestOid) + { + } + + public RsaOaepWrapper(bool forWrapping, ICipherParameters parameters, DerObjectIdentifier digestOid, DerObjectIdentifier mgfOid) + { + AlgorithmIdentifier digestAlgId = new AlgorithmIdentifier(digestOid, DerNull.Instance); + + if (mgfOid.Equals(NistObjectIdentifiers.IdShake128) || mgfOid.Equals(NistObjectIdentifiers.IdShake256)) + { + this.algId = new AlgorithmIdentifier( + PkcsObjectIdentifiers.IdRsaesOaep, + new RsaesOaepParameters( + digestAlgId, + new AlgorithmIdentifier(mgfOid), + RsaesOaepParameters.DefaultPSourceAlgorithm)); + } + else + { + this.algId = new AlgorithmIdentifier( + PkcsObjectIdentifiers.IdRsaesOaep, + new RsaesOaepParameters( + digestAlgId, + new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, new AlgorithmIdentifier(mgfOid, DerNull.Instance)), + RsaesOaepParameters.DefaultPSourceAlgorithm)); + } + + this.engine = new OaepEncoding(new RsaBlindedEngine(), DigestUtilities.GetDigest(digestOid), DigestUtilities.GetDigest(mgfOid), null); + this.engine.Init(forWrapping, parameters); + } + + public object AlgorithmDetails + { + get { return algId; } + } + + public IBlockResult Unwrap(byte[] cipherText, int offset, int length) + { + return new SimpleBlockResult(engine.ProcessBlock(cipherText, offset, length)); + } + + public IBlockResult Wrap(byte[] keyData) + { + return new SimpleBlockResult(engine.ProcessBlock(keyData, 0, keyData.Length)); + } + } + + internal class RsaOaepWrapperProvider + : WrapperProvider + { + private readonly DerObjectIdentifier digestOid; + private readonly DerObjectIdentifier mgfOid; + + internal RsaOaepWrapperProvider(DerObjectIdentifier digestOid) + { + this.digestOid = digestOid; + this.mgfOid = digestOid; + } + + internal RsaOaepWrapperProvider(DerObjectIdentifier digestOid, DerObjectIdentifier mgfOid) + { + this.digestOid = digestOid; + this.mgfOid = mgfOid; + } + + object WrapperProvider.CreateWrapper(bool forWrapping, ICipherParameters parameters) + { + return new RsaOaepWrapper(forWrapping, parameters, digestOid, mgfOid); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/Asn1KeyWrapper.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/Asn1KeyWrapper.cs.meta new file mode 100644 index 0000000..8e97d67 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/Asn1KeyWrapper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fb579b8996e5e8c44af19ba743535c11 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/Asn1Signature.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/Asn1Signature.cs new file mode 100644 index 0000000..965f8e7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/Asn1Signature.cs @@ -0,0 +1,423 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Oiw; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.TeleTrust; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Crypto.IO; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Signers; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Crypto.Operators +{ + internal class X509Utilities + { + private static readonly Asn1Null derNull = DerNull.Instance; + + private static readonly IDictionary algorithms = Platform.CreateHashtable(); + private static readonly IDictionary exParams = Platform.CreateHashtable(); + private static readonly ISet noParams = new HashSet(); + + static X509Utilities() + { + algorithms.Add("MD2WITHRSAENCRYPTION", PkcsObjectIdentifiers.MD2WithRsaEncryption); + algorithms.Add("MD2WITHRSA", PkcsObjectIdentifiers.MD2WithRsaEncryption); + algorithms.Add("MD5WITHRSAENCRYPTION", PkcsObjectIdentifiers.MD5WithRsaEncryption); + algorithms.Add("MD5WITHRSA", PkcsObjectIdentifiers.MD5WithRsaEncryption); + algorithms.Add("SHA1WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha1WithRsaEncryption); + algorithms.Add("SHA-1WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha1WithRsaEncryption); + algorithms.Add("SHA1WITHRSA", PkcsObjectIdentifiers.Sha1WithRsaEncryption); + algorithms.Add("SHA-1WITHRSA", PkcsObjectIdentifiers.Sha1WithRsaEncryption); + algorithms.Add("SHA224WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha224WithRsaEncryption); + algorithms.Add("SHA-224WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha224WithRsaEncryption); + algorithms.Add("SHA224WITHRSA", PkcsObjectIdentifiers.Sha224WithRsaEncryption); + algorithms.Add("SHA-224WITHRSA", PkcsObjectIdentifiers.Sha224WithRsaEncryption); + algorithms.Add("SHA256WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha256WithRsaEncryption); + algorithms.Add("SHA-256WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha256WithRsaEncryption); + algorithms.Add("SHA256WITHRSA", PkcsObjectIdentifiers.Sha256WithRsaEncryption); + algorithms.Add("SHA-256WITHRSA", PkcsObjectIdentifiers.Sha256WithRsaEncryption); + algorithms.Add("SHA384WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha384WithRsaEncryption); + algorithms.Add("SHA-384WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha384WithRsaEncryption); + algorithms.Add("SHA384WITHRSA", PkcsObjectIdentifiers.Sha384WithRsaEncryption); + algorithms.Add("SHA-384WITHRSA", PkcsObjectIdentifiers.Sha384WithRsaEncryption); + algorithms.Add("SHA512WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha512WithRsaEncryption); + algorithms.Add("SHA-512WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha512WithRsaEncryption); + algorithms.Add("SHA512WITHRSA", PkcsObjectIdentifiers.Sha512WithRsaEncryption); + algorithms.Add("SHA-512WITHRSA", PkcsObjectIdentifiers.Sha512WithRsaEncryption); + algorithms.Add("SHA512(224)WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha512_224WithRSAEncryption); + algorithms.Add("SHA-512(224)WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha512_224WithRSAEncryption); + algorithms.Add("SHA512(224)WITHRSA", PkcsObjectIdentifiers.Sha512_224WithRSAEncryption); + algorithms.Add("SHA-512(224)WITHRSA", PkcsObjectIdentifiers.Sha512_224WithRSAEncryption); + algorithms.Add("SHA512(256)WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha512_256WithRSAEncryption); + algorithms.Add("SHA-512(256)WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha512_256WithRSAEncryption); + algorithms.Add("SHA512(256)WITHRSA", PkcsObjectIdentifiers.Sha512_256WithRSAEncryption); + algorithms.Add("SHA-512(256)WITHRSA", PkcsObjectIdentifiers.Sha512_256WithRSAEncryption); + algorithms.Add("SHA3-224WITHRSAENCRYPTION", NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_224); + algorithms.Add("SHA3-256WITHRSAENCRYPTION", NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_256); + algorithms.Add("SHA3-384WITHRSAENCRYPTION", NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_384); + algorithms.Add("SHA3-512WITHRSAENCRYPTION", NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_512); + algorithms.Add("SHA3-224WITHRSA", NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_224); + algorithms.Add("SHA3-256WITHRSA", NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_256); + algorithms.Add("SHA3-384WITHRSA", NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_384); + algorithms.Add("SHA3-512WITHRSA", NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_512); + algorithms.Add("SHA1WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss); + algorithms.Add("SHA224WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss); + algorithms.Add("SHA256WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss); + algorithms.Add("SHA384WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss); + algorithms.Add("SHA512WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss); + algorithms.Add("RIPEMD160WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160); + algorithms.Add("RIPEMD160WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160); + algorithms.Add("RIPEMD128WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128); + algorithms.Add("RIPEMD128WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128); + algorithms.Add("RIPEMD256WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256); + algorithms.Add("RIPEMD256WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256); + algorithms.Add("SHA1WITHDSA", X9ObjectIdentifiers.IdDsaWithSha1); + algorithms.Add("DSAWITHSHA1", X9ObjectIdentifiers.IdDsaWithSha1); + algorithms.Add("SHA224WITHDSA", NistObjectIdentifiers.DsaWithSha224); + algorithms.Add("SHA256WITHDSA", NistObjectIdentifiers.DsaWithSha256); + algorithms.Add("SHA384WITHDSA", NistObjectIdentifiers.DsaWithSha384); + algorithms.Add("SHA512WITHDSA", NistObjectIdentifiers.DsaWithSha512); + algorithms.Add("SHA1WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha1); + algorithms.Add("ECDSAWITHSHA1", X9ObjectIdentifiers.ECDsaWithSha1); + algorithms.Add("SHA224WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha224); + algorithms.Add("SHA256WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha256); + algorithms.Add("SHA384WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha384); + algorithms.Add("SHA512WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha512); + algorithms.Add("GOST3411WITHGOST3410", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94); + algorithms.Add("GOST3411WITHGOST3410-94", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94); + algorithms.Add("GOST3411WITHECGOST3410", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001); + algorithms.Add("GOST3411WITHECGOST3410-2001", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001); + algorithms.Add("GOST3411WITHGOST3410-2001", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001); + + // + // According to RFC 3279, the ASN.1 encoding SHALL (id-dsa-with-sha1) or MUST (ecdsa-with-SHA*) omit the parameters field. + // The parameters field SHALL be NULL for RSA based signature algorithms. + // + noParams.Add(X9ObjectIdentifiers.ECDsaWithSha1); + noParams.Add(X9ObjectIdentifiers.ECDsaWithSha224); + noParams.Add(X9ObjectIdentifiers.ECDsaWithSha256); + noParams.Add(X9ObjectIdentifiers.ECDsaWithSha384); + noParams.Add(X9ObjectIdentifiers.ECDsaWithSha512); + noParams.Add(X9ObjectIdentifiers.IdDsaWithSha1); + noParams.Add(OiwObjectIdentifiers.DsaWithSha1); + noParams.Add(NistObjectIdentifiers.DsaWithSha224); + noParams.Add(NistObjectIdentifiers.DsaWithSha256); + noParams.Add(NistObjectIdentifiers.DsaWithSha384); + noParams.Add(NistObjectIdentifiers.DsaWithSha512); + + // + // RFC 4491 + // + noParams.Add(CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94); + noParams.Add(CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001); + + // + // explicit params + // + AlgorithmIdentifier sha1AlgId = new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1, DerNull.Instance); + exParams.Add("SHA1WITHRSAANDMGF1", CreatePssParams(sha1AlgId, 20)); + + AlgorithmIdentifier sha224AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha224, DerNull.Instance); + exParams.Add("SHA224WITHRSAANDMGF1", CreatePssParams(sha224AlgId, 28)); + + AlgorithmIdentifier sha256AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha256, DerNull.Instance); + exParams.Add("SHA256WITHRSAANDMGF1", CreatePssParams(sha256AlgId, 32)); + + AlgorithmIdentifier sha384AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha384, DerNull.Instance); + exParams.Add("SHA384WITHRSAANDMGF1", CreatePssParams(sha384AlgId, 48)); + + AlgorithmIdentifier sha512AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha512, DerNull.Instance); + exParams.Add("SHA512WITHRSAANDMGF1", CreatePssParams(sha512AlgId, 64)); + } + + /** + * Return the digest algorithm using one of the standard JCA string + * representations rather than the algorithm identifier (if possible). + */ + private static string GetDigestAlgName( + DerObjectIdentifier digestAlgOID) + { + if (PkcsObjectIdentifiers.MD5.Equals(digestAlgOID)) + { + return "MD5"; + } + else if (OiwObjectIdentifiers.IdSha1.Equals(digestAlgOID)) + { + return "SHA1"; + } + else if (NistObjectIdentifiers.IdSha224.Equals(digestAlgOID)) + { + return "SHA224"; + } + else if (NistObjectIdentifiers.IdSha256.Equals(digestAlgOID)) + { + return "SHA256"; + } + else if (NistObjectIdentifiers.IdSha384.Equals(digestAlgOID)) + { + return "SHA384"; + } + else if (NistObjectIdentifiers.IdSha512.Equals(digestAlgOID)) + { + return "SHA512"; + } + else if (NistObjectIdentifiers.IdSha512_224.Equals(digestAlgOID)) + { + return "SHA512(224)"; + } + else if (NistObjectIdentifiers.IdSha512_256.Equals(digestAlgOID)) + { + return "SHA512(256)"; + } + else if (TeleTrusTObjectIdentifiers.RipeMD128.Equals(digestAlgOID)) + { + return "RIPEMD128"; + } + else if (TeleTrusTObjectIdentifiers.RipeMD160.Equals(digestAlgOID)) + { + return "RIPEMD160"; + } + else if (TeleTrusTObjectIdentifiers.RipeMD256.Equals(digestAlgOID)) + { + return "RIPEMD256"; + } + else if (CryptoProObjectIdentifiers.GostR3411.Equals(digestAlgOID)) + { + return "GOST3411"; + } + else + { + return digestAlgOID.Id; + } + } + + internal static string GetSignatureName(AlgorithmIdentifier sigAlgId) + { + Asn1Encodable parameters = sigAlgId.Parameters; + + if (parameters != null && !derNull.Equals(parameters)) + { + if (sigAlgId.Algorithm.Equals(PkcsObjectIdentifiers.IdRsassaPss)) + { + RsassaPssParameters rsaParams = RsassaPssParameters.GetInstance(parameters); + + return GetDigestAlgName(rsaParams.HashAlgorithm.Algorithm) + "withRSAandMGF1"; + } + if (sigAlgId.Algorithm.Equals(X9ObjectIdentifiers.ECDsaWithSha2)) + { + Asn1Sequence ecDsaParams = Asn1Sequence.GetInstance(parameters); + + return GetDigestAlgName((DerObjectIdentifier)ecDsaParams[0]) + "withECDSA"; + } + } + + return sigAlgId.Algorithm.Id; + } + + private static RsassaPssParameters CreatePssParams( + AlgorithmIdentifier hashAlgId, + int saltSize) + { + return new RsassaPssParameters( + hashAlgId, + new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, hashAlgId), + new DerInteger(saltSize), + new DerInteger(1)); + } + + internal static DerObjectIdentifier GetAlgorithmOid( + string algorithmName) + { + algorithmName = Platform.ToUpperInvariant(algorithmName); + + if (algorithms.Contains(algorithmName)) + { + return (DerObjectIdentifier) algorithms[algorithmName]; + } + + return new DerObjectIdentifier(algorithmName); + } + + internal static AlgorithmIdentifier GetSigAlgID( + DerObjectIdentifier sigOid, + string algorithmName) + { + if (noParams.Contains(sigOid)) + { + return new AlgorithmIdentifier(sigOid); + } + + algorithmName = Platform.ToUpperInvariant(algorithmName); + + if (exParams.Contains(algorithmName)) + { + return new AlgorithmIdentifier(sigOid, (Asn1Encodable) exParams[algorithmName]); + } + + return new AlgorithmIdentifier(sigOid, DerNull.Instance); + } + + internal static IEnumerable GetAlgNames() + { + return new EnumerableProxy(algorithms.Keys); + } + } + + + + /// + /// Calculator factory class for signature generation in ASN.1 based profiles that use an AlgorithmIdentifier to preserve + /// signature algorithm details. + /// + public class Asn1SignatureFactory + : ISignatureFactory + { + private readonly AlgorithmIdentifier algID; + private readonly string algorithm; + private readonly AsymmetricKeyParameter privateKey; + private readonly SecureRandom random; + + /// + /// Base constructor. + /// + /// The name of the signature algorithm to use. + /// The private key to be used in the signing operation. + public Asn1SignatureFactory (string algorithm, AsymmetricKeyParameter privateKey) + : this(algorithm, privateKey, null) + { + } + + /// + /// Constructor which also specifies a source of randomness to be used if one is required. + /// + /// The name of the signature algorithm to use. + /// The private key to be used in the signing operation. + /// The source of randomness to be used in signature calculation. + public Asn1SignatureFactory(string algorithm, AsymmetricKeyParameter privateKey, SecureRandom random) + { + if (algorithm == null) + throw new ArgumentNullException("algorithm"); + if (privateKey == null) + throw new ArgumentNullException("privateKey"); + if (!privateKey.IsPrivate) + throw new ArgumentException("Key for signing must be private", "privateKey"); + + DerObjectIdentifier sigOid = X509Utilities.GetAlgorithmOid(algorithm); + + this.algorithm = algorithm; + this.privateKey = privateKey; + this.random = random; + this.algID = X509Utilities.GetSigAlgID(sigOid, algorithm); + } + + public Object AlgorithmDetails + { + get { return this.algID; } + } + + public IStreamCalculator CreateCalculator() + { + ISigner signer = SignerUtilities.InitSigner(algorithm, true, privateKey, random); + + return new DefaultSignatureCalculator(signer); + } + + /// + /// Allows enumeration of the signature names supported by the verifier provider. + /// + public static IEnumerable SignatureAlgNames + { + get { return X509Utilities.GetAlgNames(); } + } + } + + /// + /// Verifier class for signature verification in ASN.1 based profiles that use an AlgorithmIdentifier to preserve + /// signature algorithm details. + /// + public class Asn1VerifierFactory + : IVerifierFactory + { + private readonly AlgorithmIdentifier algID; + private readonly AsymmetricKeyParameter publicKey; + + /// + /// Base constructor. + /// + /// The name of the signature algorithm to use. + /// The public key to be used in the verification operation. + public Asn1VerifierFactory(string algorithm, AsymmetricKeyParameter publicKey) + { + if (algorithm == null) + throw new ArgumentNullException("algorithm"); + if (publicKey == null) + throw new ArgumentNullException("publicKey"); + if (publicKey.IsPrivate) + throw new ArgumentException("Key for verifying must be public", "publicKey"); + + DerObjectIdentifier sigOid = X509Utilities.GetAlgorithmOid(algorithm); + + this.publicKey = publicKey; + this.algID = X509Utilities.GetSigAlgID(sigOid, algorithm); + } + + public Asn1VerifierFactory(AlgorithmIdentifier algorithm, AsymmetricKeyParameter publicKey) + { + this.publicKey = publicKey; + this.algID = algorithm; + } + + public Object AlgorithmDetails + { + get { return this.algID; } + } + + public IStreamCalculator CreateCalculator() + { + + ISigner verifier = SignerUtilities.InitSigner(X509Utilities.GetSignatureName(algID), false, publicKey, null); + + return new DefaultVerifierCalculator(verifier); + } + } + + /// + /// Provider class which supports dynamic creation of signature verifiers. + /// + public class Asn1VerifierFactoryProvider: IVerifierFactoryProvider + { + private readonly AsymmetricKeyParameter publicKey; + + /// + /// Base constructor - specify the public key to be used in verification. + /// + /// The public key to be used in creating verifiers provided by this object. + public Asn1VerifierFactoryProvider(AsymmetricKeyParameter publicKey) + { + this.publicKey = publicKey; + } + + public IVerifierFactory CreateVerifierFactory(Object algorithmDetails) + { + return new Asn1VerifierFactory((AlgorithmIdentifier)algorithmDetails, publicKey); + } + + /// + /// Allows enumeration of the signature names supported by the verifier provider. + /// + public IEnumerable SignatureAlgNames + { + get { return X509Utilities.GetAlgNames(); } + } + } +} + diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/Asn1Signature.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/Asn1Signature.cs.meta new file mode 100644 index 0000000..1e1f843 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/Asn1Signature.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: baa623a638ce1f64a9d07e204766630e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/CmsContentEncryptorBuilder.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/CmsContentEncryptorBuilder.cs new file mode 100644 index 0000000..690e970 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/CmsContentEncryptorBuilder.cs @@ -0,0 +1,67 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Ntt; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Cms; +using Org.BouncyCastle.Crypto.IO; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Operators; + +namespace Org.BouncyCastle.Operators +{ + public class CmsContentEncryptorBuilder + { + private static readonly IDictionary KeySizes = Platform.CreateHashtable(); + + static CmsContentEncryptorBuilder() + { + KeySizes[NistObjectIdentifiers.IdAes128Cbc] = 128; + KeySizes[NistObjectIdentifiers.IdAes192Cbc] = 192; + KeySizes[NistObjectIdentifiers.IdAes256Cbc] = 256; + + KeySizes[NttObjectIdentifiers.IdCamellia128Cbc] = 128; + KeySizes[NttObjectIdentifiers.IdCamellia192Cbc] = 192; + KeySizes[NttObjectIdentifiers.IdCamellia256Cbc] = 256; + } + + private static int GetKeySize(DerObjectIdentifier oid) + { + if (KeySizes.Contains(oid)) + { + return (int)KeySizes[oid]; + } + + return -1; + } + + private readonly DerObjectIdentifier encryptionOID; + private readonly int keySize; + + private readonly EnvelopedDataHelper helper = new EnvelopedDataHelper(); + //private SecureRandom random; + + public CmsContentEncryptorBuilder(DerObjectIdentifier encryptionOID) + : this(encryptionOID, GetKeySize(encryptionOID)) + { + } + + public CmsContentEncryptorBuilder(DerObjectIdentifier encryptionOID, int keySize) + { + this.encryptionOID = encryptionOID; + this.keySize = keySize; + } + + public ICipherBuilderWithKey Build() + { + //return new Asn1CipherBuilderWithKey(encryptionOID, keySize, random); + return new Asn1CipherBuilderWithKey(encryptionOID, keySize, null); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/CmsContentEncryptorBuilder.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/CmsContentEncryptorBuilder.cs.meta new file mode 100644 index 0000000..a1dc7ee --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/CmsContentEncryptorBuilder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6c6fd0b37bada6f4292c9a7b5c3234d9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/CmsKeyTransRecipientInfoGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/CmsKeyTransRecipientInfoGenerator.cs new file mode 100644 index 0000000..0165f6a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/CmsKeyTransRecipientInfoGenerator.cs @@ -0,0 +1,30 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Cms; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.Operators +{ + /// Use KeyTransRecipientInfoGenerator + public class CmsKeyTransRecipientInfoGenerator + : KeyTransRecipientInfoGenerator + { + public CmsKeyTransRecipientInfoGenerator(X509Certificate recipCert, IKeyWrapper keyWrapper) + : base(new Asn1.Cms.IssuerAndSerialNumber(recipCert.IssuerDN, new DerInteger(recipCert.SerialNumber)), keyWrapper) + { + } + + public CmsKeyTransRecipientInfoGenerator(IssuerAndSerialNumber issuerAndSerial, IKeyWrapper keyWrapper) + : base(issuerAndSerial, keyWrapper) + { + } + + public CmsKeyTransRecipientInfoGenerator(byte[] subjectKeyID, IKeyWrapper keyWrapper) : base(subjectKeyID, keyWrapper) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/CmsKeyTransRecipientInfoGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/CmsKeyTransRecipientInfoGenerator.cs.meta new file mode 100644 index 0000000..90eb7b1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/CmsKeyTransRecipientInfoGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9c095ec5ca323264abb99893f9bfb62a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/DefaultSignatureCalculator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/DefaultSignatureCalculator.cs new file mode 100644 index 0000000..8ca1c01 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/DefaultSignatureCalculator.cs @@ -0,0 +1,28 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Crypto.IO; + +namespace Org.BouncyCastle.Crypto.Operators +{ + public class DefaultSignatureCalculator + : IStreamCalculator + { + private readonly SignerSink mSignerSink; + + public DefaultSignatureCalculator(ISigner signer) + { + this.mSignerSink = new SignerSink(signer); + } + + public Stream Stream + { + get { return mSignerSink; } + } + + public object GetResult() + { + return new DefaultSignatureResult(mSignerSink.Signer); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/DefaultSignatureCalculator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/DefaultSignatureCalculator.cs.meta new file mode 100644 index 0000000..06aa234 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/DefaultSignatureCalculator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a9e119546bdaaad42805775e95dc273c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/DefaultSignatureResult.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/DefaultSignatureResult.cs new file mode 100644 index 0000000..615f67d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/DefaultSignatureResult.cs @@ -0,0 +1,27 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Operators +{ + public class DefaultSignatureResult + : IBlockResult + { + private readonly ISigner mSigner; + + public DefaultSignatureResult(ISigner signer) + { + this.mSigner = signer; + } + + public byte[] Collect() + { + return mSigner.GenerateSignature(); + } + + public int Collect(byte[] sig, int sigOff) + { + byte[] signature = Collect(); + signature.CopyTo(sig, sigOff); + return signature.Length; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/DefaultSignatureResult.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/DefaultSignatureResult.cs.meta new file mode 100644 index 0000000..c630694 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/DefaultSignatureResult.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dc812102161f662409d91592a580c2bb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/DefaultVerifierCalculator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/DefaultVerifierCalculator.cs new file mode 100644 index 0000000..c985e81 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/DefaultVerifierCalculator.cs @@ -0,0 +1,28 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Crypto.IO; + +namespace Org.BouncyCastle.Crypto.Operators +{ + public class DefaultVerifierCalculator + : IStreamCalculator + { + private readonly SignerSink mSignerSink; + + public DefaultVerifierCalculator(ISigner signer) + { + this.mSignerSink = new SignerSink(signer); + } + + public Stream Stream + { + get { return mSignerSink; } + } + + public object GetResult() + { + return new DefaultVerifierResult(mSignerSink.Signer); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/DefaultVerifierCalculator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/DefaultVerifierCalculator.cs.meta new file mode 100644 index 0000000..19f9d33 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/DefaultVerifierCalculator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2b286d304c7e6c548a69b24b9cdf0cbf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/DefaultVerifierResult.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/DefaultVerifierResult.cs new file mode 100644 index 0000000..fb259c8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/DefaultVerifierResult.cs @@ -0,0 +1,29 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Operators +{ + public class DefaultVerifierResult + : IVerifier + { + private readonly ISigner mSigner; + + public DefaultVerifierResult(ISigner signer) + { + this.mSigner = signer; + } + + public bool IsVerified(byte[] signature) + { + return mSigner.VerifySignature(signature); + } + + public bool IsVerified(byte[] sig, int sigOff, int sigLen) + { + byte[] signature = Arrays.CopyOfRange(sig, sigOff, sigOff + sigLen); + + return IsVerified(signature); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/DefaultVerifierResult.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/DefaultVerifierResult.cs.meta new file mode 100644 index 0000000..6c90ef5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/DefaultVerifierResult.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2c23c77d7edefb7428413ce037f8af89 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/GenericKey.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/GenericKey.cs new file mode 100644 index 0000000..89512c7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/GenericKey.cs @@ -0,0 +1,40 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; + +namespace Org.BouncyCastle.Crypto.Operators +{ + public class GenericKey + { + private readonly AlgorithmIdentifier algorithmIdentifier; + private readonly object representation; + + public GenericKey(object representation) + { + this.algorithmIdentifier = null; + this.representation = representation; + } + + public GenericKey(AlgorithmIdentifier algorithmIdentifier, byte[] representation) + { + this.algorithmIdentifier = algorithmIdentifier; + this.representation = representation; + } + + public GenericKey(AlgorithmIdentifier algorithmIdentifier, object representation) + { + this.algorithmIdentifier = algorithmIdentifier; + this.representation = representation; + } + + public AlgorithmIdentifier AlgorithmIdentifier + { + get { return algorithmIdentifier; } + } + + public object Representation + { + get { return representation; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/GenericKey.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/GenericKey.cs.meta new file mode 100644 index 0000000..374cbe9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/operators/GenericKey.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 61245733a1356374dac3c7dd8a93749d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings.meta new file mode 100644 index 0000000..09f5c80 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e4840d8766f9daf4db759e6ce24413cc +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings/BlockCipherPadding.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings/BlockCipherPadding.cs new file mode 100644 index 0000000..33a5f9f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings/BlockCipherPadding.cs @@ -0,0 +1,43 @@ +using System; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Security; + + +namespace Org.BouncyCastle.Crypto.Paddings +{ + /** + * Block cipher padders are expected to conform to this interface + */ + public interface IBlockCipherPadding + { + /** + * Initialise the padder. + * + * @param param parameters, if any required. + */ + void Init(SecureRandom random); + //throws ArgumentException; + + /** + * Return the name of the algorithm the cipher implements. + * + * @return the name of the algorithm the cipher implements. + */ + string PaddingName { get; } + + /** + * add the pad bytes to the passed in block, returning the + * number of bytes added. + */ + int AddPadding(byte[] input, int inOff); + + /** + * return the number of pad bytes present in the block. + * @exception InvalidCipherTextException if the padding is badly formed + * or invalid. + */ + int PadCount(byte[] input); + //throws InvalidCipherTextException; + } + +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings/BlockCipherPadding.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings/BlockCipherPadding.cs.meta new file mode 100644 index 0000000..5868c1c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings/BlockCipherPadding.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7c3fcb0d97391244bb63795872a0cc2c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings/ISO10126d2Padding.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings/ISO10126d2Padding.cs new file mode 100644 index 0000000..e132a62 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings/ISO10126d2Padding.cs @@ -0,0 +1,76 @@ +using System; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Security; + + +namespace Org.BouncyCastle.Crypto.Paddings +{ + + /** + * A padder that adds ISO10126-2 padding to a block. + */ + public class ISO10126d2Padding: IBlockCipherPadding + { + private SecureRandom random; + + /** + * Initialise the padder. + * + * @param random a SecureRandom if available. + */ + public void Init( + SecureRandom random) + //throws ArgumentException + { + this.random = (random != null) ? random : new SecureRandom(); + } + + /** + * Return the name of the algorithm the cipher implements. + * + * @return the name of the algorithm the cipher implements. + */ + public string PaddingName + { + get { return "ISO10126-2"; } + } + + /** + * add the pad bytes to the passed in block, returning the + * number of bytes added. + */ + public int AddPadding( + byte[] input, + int inOff) + { + byte code = (byte)(input.Length - inOff); + + while (inOff < (input.Length - 1)) + { + input[inOff] = (byte)random.NextInt(); + inOff++; + } + + input[inOff] = code; + + return code; + } + + /** + * return the number of pad bytes present in the block. + */ + public int PadCount(byte[] input) + //throws InvalidCipherTextException + { + int count = input[input.Length - 1] & 0xff; + + if (count > input.Length) + { + throw new InvalidCipherTextException("pad block corrupted"); + } + + return count; + } + } + +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings/ISO10126d2Padding.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings/ISO10126d2Padding.cs.meta new file mode 100644 index 0000000..7faad0c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings/ISO10126d2Padding.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2bea2435519ff4c4ba8727b8ea53af13 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings/ISO7816d4Padding.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings/ISO7816d4Padding.cs new file mode 100644 index 0000000..016b25a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings/ISO7816d4Padding.cs @@ -0,0 +1,79 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Paddings +{ + /** + * A padder that adds the padding according to the scheme referenced in + * ISO 7814-4 - scheme 2 from ISO 9797-1. The first byte is 0x80, rest is 0x00 + */ + public class ISO7816d4Padding + : IBlockCipherPadding + { + /** + * Initialise the padder. + * + * @param random - a SecureRandom if available. + */ + public void Init( + SecureRandom random) + { + // nothing to do. + } + + /** + * Return the name of the algorithm the padder implements. + * + * @return the name of the algorithm the padder implements. + */ + public string PaddingName + { + get { return "ISO7816-4"; } + } + + /** + * add the pad bytes to the passed in block, returning the + * number of bytes added. + */ + public int AddPadding( + byte[] input, + int inOff) + { + int added = (input.Length - inOff); + + input[inOff]= (byte) 0x80; + inOff ++; + + while (inOff < input.Length) + { + input[inOff] = (byte) 0; + inOff++; + } + + return added; + } + + /** + * return the number of pad bytes present in the block. + */ + public int PadCount( + byte[] input) + { + int count = input.Length - 1; + + while (count > 0 && input[count] == 0) + { + count--; + } + + if (input[count] != (byte)0x80) + { + throw new InvalidCipherTextException("pad block corrupted"); + } + + return input.Length - count; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings/ISO7816d4Padding.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings/ISO7816d4Padding.cs.meta new file mode 100644 index 0000000..123d71e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings/ISO7816d4Padding.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6aea1e8b42a633c4a8530d8b9b3f94c8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings/PaddedBufferedBlockCipher.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings/PaddedBufferedBlockCipher.cs new file mode 100644 index 0000000..5d2f8cf --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings/PaddedBufferedBlockCipher.cs @@ -0,0 +1,285 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Paddings +{ + /** + * A wrapper class that allows block ciphers to be used to process data in + * a piecemeal fashion with padding. The PaddedBufferedBlockCipher + * outputs a block only when the buffer is full and more data is being added, + * or on a doFinal (unless the current block in the buffer is a pad block). + * The default padding mechanism used is the one outlined in Pkcs5/Pkcs7. + */ + public class PaddedBufferedBlockCipher + : BufferedBlockCipher + { + private readonly IBlockCipherPadding padding; + + /** + * Create a buffered block cipher with the desired padding. + * + * @param cipher the underlying block cipher this buffering object wraps. + * @param padding the padding type. + */ + public PaddedBufferedBlockCipher( + IBlockCipher cipher, + IBlockCipherPadding padding) + { + this.cipher = cipher; + this.padding = padding; + + buf = new byte[cipher.GetBlockSize()]; + bufOff = 0; + } + + /** + * Create a buffered block cipher Pkcs7 padding + * + * @param cipher the underlying block cipher this buffering object wraps. + */ + public PaddedBufferedBlockCipher( + IBlockCipher cipher) + : this(cipher, new Pkcs7Padding()) { } + + /** + * initialise the cipher. + * + * @param forEncryption if true the cipher is initialised for + * encryption, if false for decryption. + * @param param the key and other data required by the cipher. + * @exception ArgumentException if the parameters argument is + * inappropriate. + */ + public override void Init( + bool forEncryption, + ICipherParameters parameters) + { + this.forEncryption = forEncryption; + + SecureRandom initRandom = null; + if (parameters is ParametersWithRandom) + { + ParametersWithRandom p = (ParametersWithRandom)parameters; + initRandom = p.Random; + parameters = p.Parameters; + } + + Reset(); + padding.Init(initRandom); + cipher.Init(forEncryption, parameters); + } + + /** + * return the minimum size of the output buffer required for an update + * plus a doFinal with an input of len bytes. + * + * @param len the length of the input. + * @return the space required to accommodate a call to update and doFinal + * with len bytes of input. + */ + public override int GetOutputSize( + int length) + { + int total = length + bufOff; + int leftOver = total % buf.Length; + + if (leftOver == 0) + { + if (forEncryption) + { + return total + buf.Length; + } + + return total; + } + + return total - leftOver + buf.Length; + } + + /** + * return the size of the output buffer required for an update + * an input of len bytes. + * + * @param len the length of the input. + * @return the space required to accommodate a call to update + * with len bytes of input. + */ + public override int GetUpdateOutputSize( + int length) + { + int total = length + bufOff; + int leftOver = total % buf.Length; + + if (leftOver == 0) + { + return total - buf.Length; + } + + return total - leftOver; + } + + /** + * process a single byte, producing an output block if necessary. + * + * @param in the input byte. + * @param out the space for any output that might be produced. + * @param outOff the offset from which the output will be copied. + * @return the number of output bytes copied to out. + * @exception DataLengthException if there isn't enough space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + */ + public override int ProcessByte( + byte input, + byte[] output, + int outOff) + { + int resultLen = 0; + + if (bufOff == buf.Length) + { + resultLen = cipher.ProcessBlock(buf, 0, output, outOff); + bufOff = 0; + } + + buf[bufOff++] = input; + + return resultLen; + } + + /** + * process an array of bytes, producing output if necessary. + * + * @param in the input byte array. + * @param inOff the offset at which the input data starts. + * @param len the number of bytes to be copied out of the input array. + * @param out the space for any output that might be produced. + * @param outOff the offset from which the output will be copied. + * @return the number of output bytes copied to out. + * @exception DataLengthException if there isn't enough space in out. + * @exception InvalidOperationException if the cipher isn't initialised. + */ + public override int ProcessBytes( + byte[] input, + int inOff, + int length, + byte[] output, + int outOff) + { + if (length < 0) + { + throw new ArgumentException("Can't have a negative input length!"); + } + + int blockSize = GetBlockSize(); + int outLength = GetUpdateOutputSize(length); + + if (outLength > 0) + { + Check.OutputLength(output, outOff, outLength, "output buffer too short"); + } + + int resultLen = 0; + int gapLen = buf.Length - bufOff; + + if (length > gapLen) + { + Array.Copy(input, inOff, buf, bufOff, gapLen); + + resultLen += cipher.ProcessBlock(buf, 0, output, outOff); + + bufOff = 0; + length -= gapLen; + inOff += gapLen; + + while (length > buf.Length) + { + resultLen += cipher.ProcessBlock(input, inOff, output, outOff + resultLen); + + length -= blockSize; + inOff += blockSize; + } + } + + Array.Copy(input, inOff, buf, bufOff, length); + + bufOff += length; + + return resultLen; + } + + /** + * Process the last block in the buffer. If the buffer is currently + * full and padding needs to be added a call to doFinal will produce + * 2 * GetBlockSize() bytes. + * + * @param out the array the block currently being held is copied into. + * @param outOff the offset at which the copying starts. + * @return the number of output bytes copied to out. + * @exception DataLengthException if there is insufficient space in out for + * the output or we are decrypting and the input is not block size aligned. + * @exception InvalidOperationException if the underlying cipher is not + * initialised. + * @exception InvalidCipherTextException if padding is expected and not found. + */ + public override int DoFinal( + byte[] output, + int outOff) + { + int blockSize = cipher.GetBlockSize(); + int resultLen = 0; + + if (forEncryption) + { + if (bufOff == blockSize) + { + if ((outOff + 2 * blockSize) > output.Length) + { + Reset(); + + throw new OutputLengthException("output buffer too short"); + } + + resultLen = cipher.ProcessBlock(buf, 0, output, outOff); + bufOff = 0; + } + + padding.AddPadding(buf, bufOff); + + resultLen += cipher.ProcessBlock(buf, 0, output, outOff + resultLen); + + Reset(); + } + else + { + if (bufOff == blockSize) + { + resultLen = cipher.ProcessBlock(buf, 0, buf, 0); + bufOff = 0; + } + else + { + Reset(); + + throw new DataLengthException("last block incomplete in decryption"); + } + + try + { + resultLen -= padding.PadCount(buf); + + Array.Copy(buf, 0, output, outOff, resultLen); + } + finally + { + Reset(); + } + } + + return resultLen; + } + } + +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings/PaddedBufferedBlockCipher.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings/PaddedBufferedBlockCipher.cs.meta new file mode 100644 index 0000000..a04c401 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings/PaddedBufferedBlockCipher.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a5406774ee91cac418e83d4cd8acc3c0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings/Pkcs7Padding.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings/Pkcs7Padding.cs new file mode 100644 index 0000000..1158564 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings/Pkcs7Padding.cs @@ -0,0 +1,76 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Paddings +{ + /** + * A padder that adds Pkcs7/Pkcs5 padding to a block. + */ + public class Pkcs7Padding + : IBlockCipherPadding + { + /** + * Initialise the padder. + * + * @param random - a SecureRandom if available. + */ + public void Init( + SecureRandom random) + { + // nothing to do. + } + + /** + * Return the name of the algorithm the cipher implements. + * + * @return the name of the algorithm the cipher implements. + */ + public string PaddingName + { + get { return "PKCS7"; } + } + + /** + * add the pad bytes to the passed in block, returning the + * number of bytes added. + */ + public int AddPadding( + byte[] input, + int inOff) + { + byte code = (byte)(input.Length - inOff); + + while (inOff < input.Length) + { + input[inOff] = code; + inOff++; + } + + return code; + } + + /** + * return the number of pad bytes present in the block. + */ + public int PadCount( + byte[] input) + { + byte countAsByte = input[input.Length - 1]; + int count = countAsByte; + + if (count < 1 || count > input.Length) + throw new InvalidCipherTextException("pad block corrupted"); + + for (int i = 2; i <= count; i++) + { + if (input[input.Length - i] != countAsByte) + throw new InvalidCipherTextException("pad block corrupted"); + } + + return count; + } + } + +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings/Pkcs7Padding.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings/Pkcs7Padding.cs.meta new file mode 100644 index 0000000..1026b7d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings/Pkcs7Padding.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 05081663f8ec7c542b45fd8ba18527e2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings/TbcPadding.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings/TbcPadding.cs new file mode 100644 index 0000000..74b64e8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings/TbcPadding.cs @@ -0,0 +1,79 @@ +using System; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Paddings +{ + + /// A padder that adds Trailing-Bit-Compliment padding to a block. + ///

+ /// This padding pads the block out compliment of the last bit + /// of the plain text. + ///

+ ///
+ public class TbcPadding + : IBlockCipherPadding + { + /// Return the name of the algorithm the cipher implements. + /// the name of the algorithm the cipher implements. + /// + public string PaddingName + { + get { return "TBC"; } + } + + /// Initialise the padder. + /// - a SecureRandom if available. + /// + public virtual void Init(SecureRandom random) + { + // nothing to do. + } + + /// add the pad bytes to the passed in block, returning the + /// number of bytes added. + ///

+ /// Note: this assumes that the last block of plain text is always + /// passed to it inside in. i.e. if inOff is zero, indicating the + /// entire block is to be overwritten with padding the value of in + /// should be the same as the last block of plain text. + ///

+ ///
+ public virtual int AddPadding(byte[] input, int inOff) + { + int count = input.Length - inOff; + byte code; + + if (inOff > 0) + { + code = (byte)((input[inOff - 1] & 0x01) == 0?0xff:0x00); + } + else + { + code = (byte)((input[input.Length - 1] & 0x01) == 0?0xff:0x00); + } + + while (inOff < input.Length) + { + input[inOff] = code; + inOff++; + } + + return count; + } + + /// return the number of pad bytes present in the block. + public virtual int PadCount(byte[] input) + { + byte code = input[input.Length - 1]; + + int index = input.Length - 1; + while (index > 0 && input[index - 1] == code) + { + index--; + } + + return input.Length - index; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings/TbcPadding.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings/TbcPadding.cs.meta new file mode 100644 index 0000000..e75417d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings/TbcPadding.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ce5278b109c96b84893fa47b0487f485 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings/X923Padding.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings/X923Padding.cs new file mode 100644 index 0000000..cc1b52b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings/X923Padding.cs @@ -0,0 +1,82 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Paddings +{ + /** + * A padder that adds X9.23 padding to a block - if a SecureRandom is + * passed in random padding is assumed, otherwise padding with zeros is used. + */ + public class X923Padding + : IBlockCipherPadding + { + private SecureRandom random; + + /** + * Initialise the padder. + * + * @param random a SecureRandom if one is available. + */ + public void Init( + SecureRandom random) + { + this.random = random; + } + + /** + * Return the name of the algorithm the cipher implements. + * + * @return the name of the algorithm the cipher implements. + */ + public string PaddingName + { + get { return "X9.23"; } + } + + /** + * add the pad bytes to the passed in block, returning the + * number of bytes added. + */ + public int AddPadding( + byte[] input, + int inOff) + { + byte code = (byte)(input.Length - inOff); + + while (inOff < input.Length - 1) + { + if (random == null) + { + input[inOff] = 0; + } + else + { + input[inOff] = (byte)random.NextInt(); + } + inOff++; + } + + input[inOff] = code; + + return code; + } + + /** + * return the number of pad bytes present in the block. + */ + public int PadCount( + byte[] input) + { + int count = input[input.Length - 1] & 0xff; + + if (count > input.Length) + { + throw new InvalidCipherTextException("pad block corrupted"); + } + + return count; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings/X923Padding.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings/X923Padding.cs.meta new file mode 100644 index 0000000..2f8bf79 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings/X923Padding.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3889091bbd0c69a4f989a2b5c0340f23 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings/ZeroBytePadding.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings/ZeroBytePadding.cs new file mode 100644 index 0000000..0d55ca4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings/ZeroBytePadding.cs @@ -0,0 +1,68 @@ +using System; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Paddings +{ + + /// A padder that adds Null byte padding to a block. + public class ZeroBytePadding : IBlockCipherPadding + { + /// Return the name of the algorithm the cipher implements. + /// + /// + /// the name of the algorithm the cipher implements. + /// + public string PaddingName + { + get { return "ZeroBytePadding"; } + } + + /// Initialise the padder. + /// + /// + /// - a SecureRandom if available. + /// + public void Init(SecureRandom random) + { + // nothing to do. + } + + /// add the pad bytes to the passed in block, returning the + /// number of bytes added. + /// + public int AddPadding( + byte[] input, + int inOff) + { + int added = (input.Length - inOff); + + while (inOff < input.Length) + { + input[inOff] = (byte) 0; + inOff++; + } + + return added; + } + + /// return the number of pad bytes present in the block. + public int PadCount( + byte[] input) + { + int count = input.Length; + + while (count > 0) + { + if (input[count - 1] != 0) + { + break; + } + + count--; + } + + return input.Length - count; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings/ZeroBytePadding.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings/ZeroBytePadding.cs.meta new file mode 100644 index 0000000..de207e1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/paddings/ZeroBytePadding.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b777b323a71021c44bbd32e85fca1775 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters.meta new file mode 100644 index 0000000..3020b7f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9915ba187075e89449e50f5e005fe59b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/AEADParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/AEADParameters.cs new file mode 100644 index 0000000..825d6b7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/AEADParameters.cs @@ -0,0 +1,65 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class AeadParameters + : ICipherParameters + { + private readonly byte[] associatedText; + private readonly byte[] nonce; + private readonly KeyParameter key; + private readonly int macSize; + + /** + * Base constructor. + * + * @param key key to be used by underlying cipher + * @param macSize macSize in bits + * @param nonce nonce to be used + */ + public AeadParameters(KeyParameter key, int macSize, byte[] nonce) + : this(key, macSize, nonce, null) + { + } + + /** + * Base constructor. + * + * @param key key to be used by underlying cipher + * @param macSize macSize in bits + * @param nonce nonce to be used + * @param associatedText associated text, if any + */ + public AeadParameters( + KeyParameter key, + int macSize, + byte[] nonce, + byte[] associatedText) + { + this.key = key; + this.nonce = nonce; + this.macSize = macSize; + this.associatedText = associatedText; + } + + public virtual KeyParameter Key + { + get { return key; } + } + + public virtual int MacSize + { + get { return macSize; } + } + + public virtual byte[] GetAssociatedText() + { + return associatedText; + } + + public virtual byte[] GetNonce() + { + return nonce; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/AEADParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/AEADParameters.cs.meta new file mode 100644 index 0000000..4cac6c5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/AEADParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6a637506aeff9bf4baa1ff34141718a1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/CcmParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/CcmParameters.cs new file mode 100644 index 0000000..d445908 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/CcmParameters.cs @@ -0,0 +1,26 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + [Obsolete("Use AeadParameters")] + public class CcmParameters + : AeadParameters + { + /** + * Base constructor. + * + * @param key key to be used by underlying cipher + * @param macSize macSize in bits + * @param nonce nonce to be used + * @param associatedText associated text, if any + */ + public CcmParameters( + KeyParameter key, + int macSize, + byte[] nonce, + byte[] associatedText) + : base(key, macSize, nonce, associatedText) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/CcmParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/CcmParameters.cs.meta new file mode 100644 index 0000000..db97920 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/CcmParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a0218a28ea7999649a825b75ab1b5201 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DHKeyGenerationParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DHKeyGenerationParameters.cs new file mode 100644 index 0000000..ab3e18f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DHKeyGenerationParameters.cs @@ -0,0 +1,31 @@ +using System; + +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class DHKeyGenerationParameters + : KeyGenerationParameters + { + private readonly DHParameters parameters; + + public DHKeyGenerationParameters( + SecureRandom random, + DHParameters parameters) + : base(random, GetStrength(parameters)) + { + this.parameters = parameters; + } + + public DHParameters Parameters + { + get { return parameters; } + } + + internal static int GetStrength( + DHParameters parameters) + { + return parameters.L != 0 ? parameters.L : parameters.P.BitLength; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DHKeyGenerationParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DHKeyGenerationParameters.cs.meta new file mode 100644 index 0000000..d9aed76 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DHKeyGenerationParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 30e232630cae9de4ab6ece897d53dc32 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DHKeyParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DHKeyParameters.cs new file mode 100644 index 0000000..1a5c138 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DHKeyParameters.cs @@ -0,0 +1,76 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class DHKeyParameters + : AsymmetricKeyParameter + { + private readonly DHParameters parameters; + private readonly DerObjectIdentifier algorithmOid; + + protected DHKeyParameters( + bool isPrivate, + DHParameters parameters) + : this(isPrivate, parameters, PkcsObjectIdentifiers.DhKeyAgreement) + { + } + + protected DHKeyParameters( + bool isPrivate, + DHParameters parameters, + DerObjectIdentifier algorithmOid) + : base(isPrivate) + { + // TODO Should we allow parameters to be null? + this.parameters = parameters; + this.algorithmOid = algorithmOid; + } + + public DHParameters Parameters + { + get { return parameters; } + } + + public DerObjectIdentifier AlgorithmOid + { + get { return algorithmOid; } + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + DHKeyParameters other = obj as DHKeyParameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected bool Equals( + DHKeyParameters other) + { + return Platform.Equals(parameters, other.parameters) + && base.Equals(other); + } + + public override int GetHashCode() + { + int hc = base.GetHashCode(); + + if (parameters != null) + { + hc ^= parameters.GetHashCode(); + } + + return hc; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DHKeyParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DHKeyParameters.cs.meta new file mode 100644 index 0000000..aacba42 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DHKeyParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f3a5a0802a1a02047a8049a2621fbfc9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DHParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DHParameters.cs new file mode 100644 index 0000000..bdea124 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DHParameters.cs @@ -0,0 +1,185 @@ +using System; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class DHParameters + : ICipherParameters + { + private const int DefaultMinimumLength = 160; + + private readonly BigInteger p, g, q, j; + private readonly int m, l; + private readonly DHValidationParameters validation; + + private static int GetDefaultMParam( + int lParam) + { + if (lParam == 0) + return DefaultMinimumLength; + + return System.Math.Min(lParam, DefaultMinimumLength); + } + + public DHParameters( + BigInteger p, + BigInteger g) + : this(p, g, null, 0) + { + } + + public DHParameters( + BigInteger p, + BigInteger g, + BigInteger q) + : this(p, g, q, 0) + { + } + + public DHParameters( + BigInteger p, + BigInteger g, + BigInteger q, + int l) + : this(p, g, q, GetDefaultMParam(l), l, null, null) + { + } + + public DHParameters( + BigInteger p, + BigInteger g, + BigInteger q, + int m, + int l) + : this(p, g, q, m, l, null, null) + { + } + + public DHParameters( + BigInteger p, + BigInteger g, + BigInteger q, + BigInteger j, + DHValidationParameters validation) + : this(p, g, q, DefaultMinimumLength, 0, j, validation) + { + } + + public DHParameters( + BigInteger p, + BigInteger g, + BigInteger q, + int m, + int l, + BigInteger j, + DHValidationParameters validation) + { + if (p == null) + throw new ArgumentNullException("p"); + if (g == null) + throw new ArgumentNullException("g"); + if (!p.TestBit(0)) + throw new ArgumentException("field must be an odd prime", "p"); + if (g.CompareTo(BigInteger.Two) < 0 + || g.CompareTo(p.Subtract(BigInteger.Two)) > 0) + throw new ArgumentException("generator must in the range [2, p - 2]", "g"); + if (q != null && q.BitLength >= p.BitLength) + throw new ArgumentException("q too big to be a factor of (p-1)", "q"); + if (m >= p.BitLength) + throw new ArgumentException("m value must be < bitlength of p", "m"); + if (l != 0) + { + // TODO Check this against the Java version, which has 'l > p.BitLength' here + if (l >= p.BitLength) + throw new ArgumentException("when l value specified, it must be less than bitlength(p)", "l"); + if (l < m) + throw new ArgumentException("when l value specified, it may not be less than m value", "l"); + } + if (j != null && j.CompareTo(BigInteger.Two) < 0) + throw new ArgumentException("subgroup factor must be >= 2", "j"); + + // TODO If q, j both provided, validate p = jq + 1 ? + + this.p = p; + this.g = g; + this.q = q; + this.m = m; + this.l = l; + this.j = j; + this.validation = validation; + } + + public BigInteger P + { + get { return p; } + } + + public BigInteger G + { + get { return g; } + } + + public BigInteger Q + { + get { return q; } + } + + public BigInteger J + { + get { return j; } + } + + /// The minimum bitlength of the private value. + public int M + { + get { return m; } + } + + /// The bitlength of the private value. + public int L + { + get { return l; } + } + + public DHValidationParameters ValidationParameters + { + get { return validation; } + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + DHParameters other = obj as DHParameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected virtual bool Equals( + DHParameters other) + { + return p.Equals(other.p) + && g.Equals(other.g) + && Platform.Equals(q, other.q); + } + + public override int GetHashCode() + { + int hc = p.GetHashCode() ^ g.GetHashCode(); + + if (q != null) + { + hc ^= q.GetHashCode(); + } + + return hc; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DHParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DHParameters.cs.meta new file mode 100644 index 0000000..80ffb66 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DHParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 55601f1bcc966e94dbb91d9c3501abc9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DHPrivateKeyParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DHPrivateKeyParameters.cs new file mode 100644 index 0000000..fc724df --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DHPrivateKeyParameters.cs @@ -0,0 +1,60 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class DHPrivateKeyParameters + : DHKeyParameters + { + private readonly BigInteger x; + + public DHPrivateKeyParameters( + BigInteger x, + DHParameters parameters) + : base(true, parameters) + { + this.x = x; + } + + public DHPrivateKeyParameters( + BigInteger x, + DHParameters parameters, + DerObjectIdentifier algorithmOid) + : base(true, parameters, algorithmOid) + { + this.x = x; + } + + public BigInteger X + { + get { return x; } + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + DHPrivateKeyParameters other = obj as DHPrivateKeyParameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected bool Equals( + DHPrivateKeyParameters other) + { + return x.Equals(other.x) && base.Equals(other); + } + + public override int GetHashCode() + { + return x.GetHashCode() ^ base.GetHashCode(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DHPrivateKeyParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DHPrivateKeyParameters.cs.meta new file mode 100644 index 0000000..3a971fc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DHPrivateKeyParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1e7d55094e853a44f97fd8827c31ef57 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DHPublicKeyParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DHPublicKeyParameters.cs new file mode 100644 index 0000000..19e732b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DHPublicKeyParameters.cs @@ -0,0 +1,167 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class DHPublicKeyParameters + : DHKeyParameters + { + private static BigInteger Validate(BigInteger y, DHParameters dhParams) + { + if (y == null) + throw new ArgumentNullException("y"); + + BigInteger p = dhParams.P; + + // TLS check + if (y.CompareTo(BigInteger.Two) < 0 || y.CompareTo(p.Subtract(BigInteger.Two)) > 0) + throw new ArgumentException("invalid DH public key", "y"); + + BigInteger q = dhParams.Q; + + // We can't validate without Q. + if (q == null) + return y; + + if (p.TestBit(0) + && p.BitLength - 1 == q.BitLength + && p.ShiftRight(1).Equals(q)) + { + // Safe prime case + if (1 == Legendre(y, p)) + return y; + } + else + { + if (BigInteger.One.Equals(y.ModPow(q, p))) + return y; + } + + throw new ArgumentException("value does not appear to be in correct group", "y"); + } + + private readonly BigInteger y; + + public DHPublicKeyParameters( + BigInteger y, + DHParameters parameters) + : base(false, parameters) + { + this.y = Validate(y, parameters); + } + + public DHPublicKeyParameters( + BigInteger y, + DHParameters parameters, + DerObjectIdentifier algorithmOid) + : base(false, parameters, algorithmOid) + { + this.y = Validate(y, parameters); + } + + public virtual BigInteger Y + { + get { return y; } + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + DHPublicKeyParameters other = obj as DHPublicKeyParameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected bool Equals( + DHPublicKeyParameters other) + { + return y.Equals(other.y) && base.Equals(other); + } + + public override int GetHashCode() + { + return y.GetHashCode() ^ base.GetHashCode(); + } + + private static int Legendre(BigInteger a, BigInteger b) + { + //int r = 0, bits = b.IntValue; + + //for (;;) + //{ + // int lowestSetBit = a.GetLowestSetBit(); + // a = a.ShiftRight(lowestSetBit); + // r ^= (bits ^ (bits >> 1)) & (lowestSetBit << 1); + + // int cmp = a.CompareTo(b); + // if (cmp == 0) + // break; + + // if (cmp < 0) + // { + // BigInteger t = a; a = b; b = t; + + // int oldBits = bits; + // bits = b.IntValue; + // r ^= oldBits & bits; + // } + + // a = a.Subtract(b); + //} + + //return BigInteger.One.Equals(b) ? (1 - (r & 2)) : 0; + + int bitLength = b.BitLength; + uint[] A = Nat.FromBigInteger(bitLength, a); + uint[] B = Nat.FromBigInteger(bitLength, b); + + int r = 0; + + int len = B.Length; + for (;;) + { + while (A[0] == 0) + { + Nat.ShiftDownWord(len, A, 0); + } + + int shift = Integers.NumberOfTrailingZeros((int)A[0]); + if (shift > 0) + { + Nat.ShiftDownBits(len, A, shift, 0); + int bits = (int)B[0]; + r ^= (bits ^ (bits >> 1)) & (shift << 1); + } + + int cmp = Nat.Compare(len, A, B); + if (cmp == 0) + break; + + if (cmp < 0) + { + r ^= (int)(A[0] & B[0]); + uint[] t = A; A = B; B = t; + } + + while (A[len - 1] == 0) + { + len = len - 1; + } + + Nat.Sub(len, A, B, A); + } + + return Nat.IsOne(len, B) ? (1 - (r & 2)) : 0; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DHPublicKeyParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DHPublicKeyParameters.cs.meta new file mode 100644 index 0000000..8be98b9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DHPublicKeyParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e9385e15018d35f49928084ccefd96ca +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DHValidationParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DHValidationParameters.cs new file mode 100644 index 0000000..50c0739 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DHValidationParameters.cs @@ -0,0 +1,59 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class DHValidationParameters + { + private readonly byte[] seed; + private readonly int counter; + + public DHValidationParameters( + byte[] seed, + int counter) + { + if (seed == null) + throw new ArgumentNullException("seed"); + + this.seed = (byte[]) seed.Clone(); + this.counter = counter; + } + + public byte[] GetSeed() + { + return (byte[]) seed.Clone(); + } + + public int Counter + { + get { return counter; } + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + DHValidationParameters other = obj as DHValidationParameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected bool Equals( + DHValidationParameters other) + { + return counter == other.counter + && Arrays.AreEqual(this.seed, other.seed); + } + + public override int GetHashCode() + { + return counter.GetHashCode() ^ Arrays.GetHashCode(seed); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DHValidationParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DHValidationParameters.cs.meta new file mode 100644 index 0000000..647cf63 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DHValidationParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1f7983f8eebe6824aa5779d787b88f4c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DSAParameterGenerationParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DSAParameterGenerationParameters.cs new file mode 100644 index 0000000..7427574 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DSAParameterGenerationParameters.cs @@ -0,0 +1,74 @@ +using System; + +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class DsaParameterGenerationParameters + { + public const int DigitalSignatureUsage = 1; + public const int KeyEstablishmentUsage = 2; + + private readonly int l; + private readonly int n; + private readonly int certainty; + private readonly SecureRandom random; + private readonly int usageIndex; + + /** + * Construct without a usage index, this will do a random construction of G. + * + * @param L desired length of prime P in bits (the effective key size). + * @param N desired length of prime Q in bits. + * @param certainty certainty level for prime number generation. + * @param random the source of randomness to use. + */ + public DsaParameterGenerationParameters(int L, int N, int certainty, SecureRandom random) + : this(L, N, certainty, random, -1) + { + } + + /** + * Construct for a specific usage index - this has the effect of using verifiable canonical generation of G. + * + * @param L desired length of prime P in bits (the effective key size). + * @param N desired length of prime Q in bits. + * @param certainty certainty level for prime number generation. + * @param random the source of randomness to use. + * @param usageIndex a valid usage index. + */ + public DsaParameterGenerationParameters(int L, int N, int certainty, SecureRandom random, int usageIndex) + { + this.l = L; + this.n = N; + this.certainty = certainty; + this.random = random; + this.usageIndex = usageIndex; + } + + public virtual int L + { + get { return l; } + } + + public virtual int N + { + get { return n; } + } + + public virtual int UsageIndex + { + get { return usageIndex; } + } + + public virtual int Certainty + { + get { return certainty; } + } + + public virtual SecureRandom Random + { + get { return random; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DSAParameterGenerationParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DSAParameterGenerationParameters.cs.meta new file mode 100644 index 0000000..694b542 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DSAParameterGenerationParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6d38700ca08b96f4398accb824c6de1b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DesEdeParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DesEdeParameters.cs new file mode 100644 index 0000000..6be56fb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DesEdeParameters.cs @@ -0,0 +1,140 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class DesEdeParameters + : DesParameters + { + /* + * DES-EDE Key length in bytes. + */ + public const int DesEdeKeyLength = 24; + + private static byte[] FixKey( + byte[] key, + int keyOff, + int keyLen) + { + byte[] tmp = new byte[24]; + + switch (keyLen) + { + case 16: + Array.Copy(key, keyOff, tmp, 0, 16); + Array.Copy(key, keyOff, tmp, 16, 8); + break; + case 24: + Array.Copy(key, keyOff, tmp, 0, 24); + break; + default: + throw new ArgumentException("Bad length for DESede key: " + keyLen, "keyLen"); + } + + if (IsWeakKey(tmp)) + throw new ArgumentException("attempt to create weak DESede key"); + + return tmp; + } + + public DesEdeParameters( + byte[] key) + : base(FixKey(key, 0, key.Length)) + { + } + + public DesEdeParameters( + byte[] key, + int keyOff, + int keyLen) + : base(FixKey(key, keyOff, keyLen)) + { + } + + /** + * return true if the passed in key is a DES-EDE weak key. + * + * @param key bytes making up the key + * @param offset offset into the byte array the key starts at + * @param length number of bytes making up the key + */ + public static bool IsWeakKey( + byte[] key, + int offset, + int length) + { + for (int i = offset; i < length; i += DesKeyLength) + { + if (DesParameters.IsWeakKey(key, i)) + { + return true; + } + } + + return false; + } + + /** + * return true if the passed in key is a DES-EDE weak key. + * + * @param key bytes making up the key + * @param offset offset into the byte array the key starts at + */ + public static new bool IsWeakKey( + byte[] key, + int offset) + { + return IsWeakKey(key, offset, key.Length - offset); + } + + public static new bool IsWeakKey( + byte[] key) + { + return IsWeakKey(key, 0, key.Length); + } + + /** + * return true if the passed in key is a real 2/3 part DES-EDE key. + * + * @param key bytes making up the key + * @param offset offset into the byte array the key starts at + */ + public static bool IsRealEdeKey(byte[] key, int offset) + { + return key.Length == 16 ? IsReal2Key(key, offset) : IsReal3Key(key, offset); + } + + /** + * return true if the passed in key is a real 2 part DES-EDE key. + * + * @param key bytes making up the key + * @param offset offset into the byte array the key starts at + */ + public static bool IsReal2Key(byte[] key, int offset) + { + bool isValid = false; + for (int i = offset; i != offset + 8; i++) + { + isValid |= (key[i] != key[i + 8]); + } + return isValid; + } + + /** + * return true if the passed in key is a real 3 part DES-EDE key. + * + * @param key bytes making up the key + * @param offset offset into the byte array the key starts at + */ + public static bool IsReal3Key(byte[] key, int offset) + { + bool diff12 = false, diff13 = false, diff23 = false; + for (int i = offset; i != offset + 8; i++) + { + diff12 |= (key[i] != key[i + 8]); + diff13 |= (key[i] != key[i + 16]); + diff23 |= (key[i + 8] != key[i + 16]); + } + return diff12 && diff13 && diff23; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DesEdeParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DesEdeParameters.cs.meta new file mode 100644 index 0000000..b932006 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DesEdeParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bd4ac8e53660fd94e8b052be8eaf3515 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DesParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DesParameters.cs new file mode 100644 index 0000000..a1f67e2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DesParameters.cs @@ -0,0 +1,139 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class DesParameters + : KeyParameter + { + public DesParameters( + byte[] key) + : base(key) + { + if (IsWeakKey(key)) + throw new ArgumentException("attempt to create weak DES key"); + } + + public DesParameters( + byte[] key, + int keyOff, + int keyLen) + : base(key, keyOff, keyLen) + { + if (IsWeakKey(key, keyOff)) + throw new ArgumentException("attempt to create weak DES key"); + } + + /* + * DES Key Length in bytes. + */ + public const int DesKeyLength = 8; + + /* + * Table of weak and semi-weak keys taken from Schneier pp281 + */ + private const int N_DES_WEAK_KEYS = 16; + + private static readonly byte[] DES_weak_keys = + { + /* weak keys */ + (byte)0x01,(byte)0x01,(byte)0x01,(byte)0x01, (byte)0x01,(byte)0x01,(byte)0x01,(byte)0x01, + (byte)0x1f,(byte)0x1f,(byte)0x1f,(byte)0x1f, (byte)0x0e,(byte)0x0e,(byte)0x0e,(byte)0x0e, + (byte)0xe0,(byte)0xe0,(byte)0xe0,(byte)0xe0, (byte)0xf1,(byte)0xf1,(byte)0xf1,(byte)0xf1, + (byte)0xfe,(byte)0xfe,(byte)0xfe,(byte)0xfe, (byte)0xfe,(byte)0xfe,(byte)0xfe,(byte)0xfe, + + /* semi-weak keys */ + (byte)0x01,(byte)0xfe,(byte)0x01,(byte)0xfe, (byte)0x01,(byte)0xfe,(byte)0x01,(byte)0xfe, + (byte)0x1f,(byte)0xe0,(byte)0x1f,(byte)0xe0, (byte)0x0e,(byte)0xf1,(byte)0x0e,(byte)0xf1, + (byte)0x01,(byte)0xe0,(byte)0x01,(byte)0xe0, (byte)0x01,(byte)0xf1,(byte)0x01,(byte)0xf1, + (byte)0x1f,(byte)0xfe,(byte)0x1f,(byte)0xfe, (byte)0x0e,(byte)0xfe,(byte)0x0e,(byte)0xfe, + (byte)0x01,(byte)0x1f,(byte)0x01,(byte)0x1f, (byte)0x01,(byte)0x0e,(byte)0x01,(byte)0x0e, + (byte)0xe0,(byte)0xfe,(byte)0xe0,(byte)0xfe, (byte)0xf1,(byte)0xfe,(byte)0xf1,(byte)0xfe, + (byte)0xfe,(byte)0x01,(byte)0xfe,(byte)0x01, (byte)0xfe,(byte)0x01,(byte)0xfe,(byte)0x01, + (byte)0xe0,(byte)0x1f,(byte)0xe0,(byte)0x1f, (byte)0xf1,(byte)0x0e,(byte)0xf1,(byte)0x0e, + (byte)0xe0,(byte)0x01,(byte)0xe0,(byte)0x01, (byte)0xf1,(byte)0x01,(byte)0xf1,(byte)0x01, + (byte)0xfe,(byte)0x1f,(byte)0xfe,(byte)0x1f, (byte)0xfe,(byte)0x0e,(byte)0xfe,(byte)0x0e, + (byte)0x1f,(byte)0x01,(byte)0x1f,(byte)0x01, (byte)0x0e,(byte)0x01,(byte)0x0e,(byte)0x01, + (byte)0xfe,(byte)0xe0,(byte)0xfe,(byte)0xe0, (byte)0xfe,(byte)0xf1,(byte)0xfe,(byte)0xf1 + }; + + /** + * DES has 16 weak keys. This method will check + * if the given DES key material is weak or semi-weak. + * Key material that is too short is regarded as weak. + *

+ * See "Applied + * Cryptography" by Bruce Schneier for more information. + *

+ * @return true if the given DES key material is weak or semi-weak, + * false otherwise. + */ + public static bool IsWeakKey( + byte[] key, + int offset) + { + if (key.Length - offset < DesKeyLength) + throw new ArgumentException("key material too short."); + + //nextkey: + for (int i = 0; i < N_DES_WEAK_KEYS; i++) + { + bool unmatch = false; + for (int j = 0; j < DesKeyLength; j++) + { + if (key[j + offset] != DES_weak_keys[i * DesKeyLength + j]) + { + //continue nextkey; + unmatch = true; + break; + } + } + + if (!unmatch) + { + return true; + } + } + + return false; + } + + public static bool IsWeakKey( + byte[] key) + { + return IsWeakKey(key, 0); + } + + public static byte SetOddParity(byte b) + { + uint parity = b ^ 1U; + parity ^= (parity >> 4); + parity ^= (parity >> 2); + parity ^= (parity >> 1); + parity &= 1U; + + return (byte)(b ^ parity); + } + + /** + * DES Keys use the LSB as the odd parity bit. This can + * be used to check for corrupt keys. + * + * @param bytes the byte array to set the parity on. + */ + public static void SetOddParity(byte[] bytes) + { + for (int i = 0; i < bytes.Length; i++) + { + bytes[i] = SetOddParity(bytes[i]); + } + } + + public static void SetOddParity(byte[] bytes, int off, int len) + { + for (int i = 0; i < len; i++) + { + bytes[off + i] = SetOddParity(bytes[off + i]); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DesParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DesParameters.cs.meta new file mode 100644 index 0000000..d0ea996 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DesParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f8cce47d1141bdf439068da0bdcbd555 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DsaKeyGenerationParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DsaKeyGenerationParameters.cs new file mode 100644 index 0000000..86d6f5b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DsaKeyGenerationParameters.cs @@ -0,0 +1,26 @@ +using System; + +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class DsaKeyGenerationParameters + : KeyGenerationParameters + { + private readonly DsaParameters parameters; + + public DsaKeyGenerationParameters( + SecureRandom random, + DsaParameters parameters) + : base(random, parameters.P.BitLength - 1) + { + this.parameters = parameters; + } + + public DsaParameters Parameters + { + get { return parameters; } + } + } + +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DsaKeyGenerationParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DsaKeyGenerationParameters.cs.meta new file mode 100644 index 0000000..efff68a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DsaKeyGenerationParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2c8536dcf5d357941bb11b5233d2710d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DsaKeyParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DsaKeyParameters.cs new file mode 100644 index 0000000..5fe6d7a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DsaKeyParameters.cs @@ -0,0 +1,59 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public abstract class DsaKeyParameters + : AsymmetricKeyParameter + { + private readonly DsaParameters parameters; + + protected DsaKeyParameters( + bool isPrivate, + DsaParameters parameters) + : base(isPrivate) + { + // Note: parameters may be null + this.parameters = parameters; + } + + public DsaParameters Parameters + { + get { return parameters; } + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + DsaKeyParameters other = obj as DsaKeyParameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected bool Equals( + DsaKeyParameters other) + { + return Platform.Equals(parameters, other.parameters) + && base.Equals(other); + } + + public override int GetHashCode() + { + int hc = base.GetHashCode(); + + if (parameters != null) + { + hc ^= parameters.GetHashCode(); + } + + return hc; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DsaKeyParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DsaKeyParameters.cs.meta new file mode 100644 index 0000000..cc40063 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DsaKeyParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 293297e2035a1384aa0d4c7d2928343c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DsaParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DsaParameters.cs new file mode 100644 index 0000000..50d080e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DsaParameters.cs @@ -0,0 +1,85 @@ +using System; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class DsaParameters + : ICipherParameters + { + private readonly BigInteger p, q , g; + private readonly DsaValidationParameters validation; + + public DsaParameters( + BigInteger p, + BigInteger q, + BigInteger g) + : this(p, q, g, null) + { + } + + public DsaParameters( + BigInteger p, + BigInteger q, + BigInteger g, + DsaValidationParameters parameters) + { + if (p == null) + throw new ArgumentNullException("p"); + if (q == null) + throw new ArgumentNullException("q"); + if (g == null) + throw new ArgumentNullException("g"); + + this.p = p; + this.q = q; + this.g = g; + this.validation = parameters; + } + + public BigInteger P + { + get { return p; } + } + + public BigInteger Q + { + get { return q; } + } + + public BigInteger G + { + get { return g; } + } + + public DsaValidationParameters ValidationParameters + { + get { return validation; } + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + DsaParameters other = obj as DsaParameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected bool Equals( + DsaParameters other) + { + return p.Equals(other.p) && q.Equals(other.q) && g.Equals(other.g); + } + + public override int GetHashCode() + { + return p.GetHashCode() ^ q.GetHashCode() ^ g.GetHashCode(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DsaParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DsaParameters.cs.meta new file mode 100644 index 0000000..dd76f97 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DsaParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5442ae4439d6286418ac9d0405edaa98 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DsaPrivateKeyParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DsaPrivateKeyParameters.cs new file mode 100644 index 0000000..2abdd0e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DsaPrivateKeyParameters.cs @@ -0,0 +1,53 @@ +using System; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class DsaPrivateKeyParameters + : DsaKeyParameters + { + private readonly BigInteger x; + + public DsaPrivateKeyParameters( + BigInteger x, + DsaParameters parameters) + : base(true, parameters) + { + if (x == null) + throw new ArgumentNullException("x"); + + this.x = x; + } + + public BigInteger X + { + get { return x; } + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + DsaPrivateKeyParameters other = obj as DsaPrivateKeyParameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected bool Equals( + DsaPrivateKeyParameters other) + { + return x.Equals(other.x) && base.Equals(other); + } + + public override int GetHashCode() + { + return x.GetHashCode() ^ base.GetHashCode(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DsaPrivateKeyParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DsaPrivateKeyParameters.cs.meta new file mode 100644 index 0000000..b0f6a86 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DsaPrivateKeyParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 08c489ff86e77ff4eb594f455adedf9b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DsaPublicKeyParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DsaPublicKeyParameters.cs new file mode 100644 index 0000000..3a81bfd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DsaPublicKeyParameters.cs @@ -0,0 +1,68 @@ +using System; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class DsaPublicKeyParameters + : DsaKeyParameters + { + private static BigInteger Validate(BigInteger y, DsaParameters parameters) + { + // we can't validate without params, fortunately we can't use the key either... + if (parameters != null) + { + if (y.CompareTo(BigInteger.Two) < 0 + || y.CompareTo(parameters.P.Subtract(BigInteger.Two)) > 0 + || !y.ModPow(parameters.Q, parameters.P).Equals(BigInteger.One)) + { + throw new ArgumentException("y value does not appear to be in correct group"); + } + } + + return y; + } + + private readonly BigInteger y; + + public DsaPublicKeyParameters( + BigInteger y, + DsaParameters parameters) + : base(false, parameters) + { + if (y == null) + throw new ArgumentNullException("y"); + + this.y = Validate(y, parameters); + } + + public BigInteger Y + { + get { return y; } + } + + public override bool Equals(object obj) + { + if (obj == this) + return true; + + DsaPublicKeyParameters other = obj as DsaPublicKeyParameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected bool Equals( + DsaPublicKeyParameters other) + { + return y.Equals(other.y) && base.Equals(other); + } + + public override int GetHashCode() + { + return y.GetHashCode() ^ base.GetHashCode(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DsaPublicKeyParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DsaPublicKeyParameters.cs.meta new file mode 100644 index 0000000..c31bde4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DsaPublicKeyParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c86653e9996cd14439ac51baad2e66d3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DsaValidationParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DsaValidationParameters.cs new file mode 100644 index 0000000..c2f84c7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DsaValidationParameters.cs @@ -0,0 +1,72 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class DsaValidationParameters + { + private readonly byte[] seed; + private readonly int counter; + private readonly int usageIndex; + + public DsaValidationParameters(byte[] seed, int counter) + : this(seed, counter, -1) + { + } + + public DsaValidationParameters( + byte[] seed, + int counter, + int usageIndex) + { + if (seed == null) + throw new ArgumentNullException("seed"); + + this.seed = (byte[]) seed.Clone(); + this.counter = counter; + this.usageIndex = usageIndex; + } + + public virtual byte[] GetSeed() + { + return (byte[]) seed.Clone(); + } + + public virtual int Counter + { + get { return counter; } + } + + public virtual int UsageIndex + { + get { return usageIndex; } + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + DsaValidationParameters other = obj as DsaValidationParameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected virtual bool Equals( + DsaValidationParameters other) + { + return counter == other.counter + && Arrays.AreEqual(seed, other.seed); + } + + public override int GetHashCode() + { + return counter.GetHashCode() ^ Arrays.GetHashCode(seed); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DsaValidationParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DsaValidationParameters.cs.meta new file mode 100644 index 0000000..a27c5e2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/DsaValidationParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6f046f77b7e3be14495021baf65cfc82 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ECDomainParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ECDomainParameters.cs new file mode 100644 index 0000000..b5ca183 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ECDomainParameters.cs @@ -0,0 +1,171 @@ +using System; + +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class ECDomainParameters + { + private readonly ECCurve curve; + private readonly byte[] seed; + private readonly ECPoint g; + private readonly BigInteger n; + private readonly BigInteger h; + + private BigInteger hInv; + + public ECDomainParameters(X9ECParameters x9) + : this(x9.Curve, x9.G, x9.N, x9.H, x9.GetSeed()) + { + } + + public ECDomainParameters( + ECCurve curve, + ECPoint g, + BigInteger n) + : this(curve, g, n, BigInteger.One, null) + { + } + + public ECDomainParameters( + ECCurve curve, + ECPoint g, + BigInteger n, + BigInteger h) + : this(curve, g, n, h, null) + { + } + + public ECDomainParameters( + ECCurve curve, + ECPoint g, + BigInteger n, + BigInteger h, + byte[] seed) + { + if (curve == null) + throw new ArgumentNullException("curve"); + if (g == null) + throw new ArgumentNullException("g"); + if (n == null) + throw new ArgumentNullException("n"); + // we can't check for h == null here as h is optional in X9.62 as it is not required for ECDSA + + this.curve = curve; + this.g = ValidatePublicPoint(curve, g); + this.n = n; + this.h = h; + this.seed = Arrays.Clone(seed); + } + + public ECCurve Curve + { + get { return curve; } + } + + public ECPoint G + { + get { return g; } + } + + public BigInteger N + { + get { return n; } + } + + public BigInteger H + { + get { return h; } + } + + public BigInteger HInv + { + get + { + lock (this) + { + if (hInv == null) + { + hInv = BigIntegers.ModOddInverseVar(n, h); + } + return hInv; + } + } + } + + public byte[] GetSeed() + { + return Arrays.Clone(seed); + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + ECDomainParameters other = obj as ECDomainParameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected virtual bool Equals( + ECDomainParameters other) + { + return curve.Equals(other.curve) + && g.Equals(other.g) + && n.Equals(other.n); + } + + public override int GetHashCode() + { + //return Arrays.GetHashCode(new object[]{ curve, g, n }); + int hc = 4; + hc *= 257; + hc ^= curve.GetHashCode(); + hc *= 257; + hc ^= g.GetHashCode(); + hc *= 257; + hc ^= n.GetHashCode(); + return hc; + } + + public BigInteger ValidatePrivateScalar(BigInteger d) + { + if (null == d) + throw new ArgumentNullException("d", "Scalar cannot be null"); + + if (d.CompareTo(BigInteger.One) < 0 || (d.CompareTo(N) >= 0)) + throw new ArgumentException("Scalar is not in the interval [1, n - 1]", "d"); + + return d; + } + + public ECPoint ValidatePublicPoint(ECPoint q) + { + return ValidatePublicPoint(Curve, q); + } + + internal static ECPoint ValidatePublicPoint(ECCurve c, ECPoint q) + { + if (null == q) + throw new ArgumentNullException("q", "Point cannot be null"); + + q = ECAlgorithms.ImportPoint(c, q).Normalize(); + + if (q.IsInfinity) + throw new ArgumentException("Point at infinity", "q"); + + if (!q.IsValid()) + throw new ArgumentException("Point not on curve", "q"); + + return q; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ECDomainParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ECDomainParameters.cs.meta new file mode 100644 index 0000000..17c9fb7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ECDomainParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 894e311270ef32643b96a60c6504e6ba +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ECGOST3410Parameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ECGOST3410Parameters.cs new file mode 100644 index 0000000..6abcb16 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ECGOST3410Parameters.cs @@ -0,0 +1,53 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class ECGost3410Parameters + : ECNamedDomainParameters + { + private readonly DerObjectIdentifier _publicKeyParamSet; + private readonly DerObjectIdentifier _digestParamSet; + private readonly DerObjectIdentifier _encryptionParamSet; + + public DerObjectIdentifier PublicKeyParamSet + { + get { return _publicKeyParamSet; } + } + + public DerObjectIdentifier DigestParamSet + { + get { return _digestParamSet; } + } + + public DerObjectIdentifier EncryptionParamSet + { + get { return _encryptionParamSet; } + } + + public ECGost3410Parameters( + ECNamedDomainParameters dp, + DerObjectIdentifier publicKeyParamSet, + DerObjectIdentifier digestParamSet, + DerObjectIdentifier encryptionParamSet) + : base(dp.Name, dp.Curve, dp.G, dp.N, dp.H, dp.GetSeed()) + { + this._publicKeyParamSet = publicKeyParamSet; + this._digestParamSet = digestParamSet; + this._encryptionParamSet = encryptionParamSet; + } + + public ECGost3410Parameters(ECDomainParameters dp, DerObjectIdentifier publicKeyParamSet, + DerObjectIdentifier digestParamSet, + DerObjectIdentifier encryptionParamSet) + : base(publicKeyParamSet, dp.Curve, dp.G, dp.N, dp.H, dp.GetSeed()) + { + this._publicKeyParamSet = publicKeyParamSet; + this._digestParamSet = digestParamSet; + this._encryptionParamSet = encryptionParamSet; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ECGOST3410Parameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ECGOST3410Parameters.cs.meta new file mode 100644 index 0000000..0595a3c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ECGOST3410Parameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ea7e09cd74f77624aa5a8f814e3a2ecb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ECKeyGenerationParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ECKeyGenerationParameters.cs new file mode 100644 index 0000000..9b2b988 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ECKeyGenerationParameters.cs @@ -0,0 +1,41 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class ECKeyGenerationParameters + : KeyGenerationParameters + { + private readonly ECDomainParameters domainParams; + private readonly DerObjectIdentifier publicKeyParamSet; + + public ECKeyGenerationParameters( + ECDomainParameters domainParameters, + SecureRandom random) + : base(random, domainParameters.N.BitLength) + { + this.domainParams = domainParameters; + } + + public ECKeyGenerationParameters( + DerObjectIdentifier publicKeyParamSet, + SecureRandom random) + : this(ECKeyParameters.LookupParameters(publicKeyParamSet), random) + { + this.publicKeyParamSet = publicKeyParamSet; + } + + public ECDomainParameters DomainParameters + { + get { return domainParams; } + } + + public DerObjectIdentifier PublicKeyParamSet + { + get { return publicKeyParamSet; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ECKeyGenerationParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ECKeyGenerationParameters.cs.meta new file mode 100644 index 0000000..84e71e1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ECKeyGenerationParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bf5c4813e22b07b4c96d4b697f09bb13 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ECKeyParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ECKeyParameters.cs new file mode 100644 index 0000000..49bd4fe --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ECKeyParameters.cs @@ -0,0 +1,127 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public abstract class ECKeyParameters + : AsymmetricKeyParameter + { + private static readonly string[] algorithms = { "EC", "ECDSA", "ECDH", "ECDHC", "ECGOST3410", "ECMQV" }; + + private readonly string algorithm; + private readonly ECDomainParameters parameters; + private readonly DerObjectIdentifier publicKeyParamSet; + + protected ECKeyParameters( + string algorithm, + bool isPrivate, + ECDomainParameters parameters) + : base(isPrivate) + { + if (algorithm == null) + throw new ArgumentNullException("algorithm"); + if (parameters == null) + throw new ArgumentNullException("parameters"); + + this.algorithm = VerifyAlgorithmName(algorithm); + this.parameters = parameters; + } + + protected ECKeyParameters( + string algorithm, + bool isPrivate, + DerObjectIdentifier publicKeyParamSet) + : base(isPrivate) + { + if (algorithm == null) + throw new ArgumentNullException("algorithm"); + if (publicKeyParamSet == null) + throw new ArgumentNullException("publicKeyParamSet"); + + this.algorithm = VerifyAlgorithmName(algorithm); + this.parameters = LookupParameters(publicKeyParamSet); + this.publicKeyParamSet = publicKeyParamSet; + } + + public string AlgorithmName + { + get { return algorithm; } + } + + public ECDomainParameters Parameters + { + get { return parameters; } + } + + public DerObjectIdentifier PublicKeyParamSet + { + get { return publicKeyParamSet; } + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + ECDomainParameters other = obj as ECDomainParameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected bool Equals( + ECKeyParameters other) + { + return parameters.Equals(other.parameters) && base.Equals(other); + } + + public override int GetHashCode() + { + return parameters.GetHashCode() ^ base.GetHashCode(); + } + + internal ECKeyGenerationParameters CreateKeyGenerationParameters( + SecureRandom random) + { + if (publicKeyParamSet != null) + { + return new ECKeyGenerationParameters(publicKeyParamSet, random); + } + + return new ECKeyGenerationParameters(parameters, random); + } + + internal static string VerifyAlgorithmName(string algorithm) + { + string upper = Platform.ToUpperInvariant(algorithm); + if (Array.IndexOf(algorithms, algorithm, 0, algorithms.Length) < 0) + throw new ArgumentException("unrecognised algorithm: " + algorithm, "algorithm"); + return upper; + } + + internal static ECDomainParameters LookupParameters( + DerObjectIdentifier publicKeyParamSet) + { + if (publicKeyParamSet == null) + throw new ArgumentNullException("publicKeyParamSet"); + + X9ECParameters x9 = ECKeyPairGenerator.FindECCurveByOid(publicKeyParamSet); + + if (x9 == null) + throw new ArgumentException("OID is not a valid public key parameter set", "publicKeyParamSet"); + + return new ECDomainParameters(x9); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ECKeyParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ECKeyParameters.cs.meta new file mode 100644 index 0000000..62bd96a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ECKeyParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6628c4f0b1fef7346a8b95b4acdc2165 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ECNamedDomainParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ECNamedDomainParameters.cs new file mode 100644 index 0000000..aa20e32 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ECNamedDomainParameters.cs @@ -0,0 +1,49 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class ECNamedDomainParameters + : ECDomainParameters + { + private readonly DerObjectIdentifier name; + + public DerObjectIdentifier Name + { + get { return name; } + } + + public ECNamedDomainParameters(DerObjectIdentifier name, ECDomainParameters dp) + : this(name, dp.Curve, dp.G, dp.N, dp.H, dp.GetSeed()) + { + } + + public ECNamedDomainParameters(DerObjectIdentifier name, X9ECParameters x9) + : base(x9) + { + this.name = name; + } + + public ECNamedDomainParameters(DerObjectIdentifier name, ECCurve curve, ECPoint g, BigInteger n) + : base(curve, g, n) + { + this.name = name; + } + + public ECNamedDomainParameters(DerObjectIdentifier name, ECCurve curve, ECPoint g, BigInteger n, BigInteger h) + : base(curve, g, n, h) + { + this.name = name; + } + + public ECNamedDomainParameters(DerObjectIdentifier name, ECCurve curve, ECPoint g, BigInteger n, BigInteger h, byte[] seed) + : base(curve, g, n, h, seed) + { + this.name = name; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ECNamedDomainParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ECNamedDomainParameters.cs.meta new file mode 100644 index 0000000..13bb457 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ECNamedDomainParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7ca4883adfb3fb144a163efd8e19c47f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ECPrivateKeyParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ECPrivateKeyParameters.cs new file mode 100644 index 0000000..47e53ef --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ECPrivateKeyParameters.cs @@ -0,0 +1,78 @@ +using System; +using System.Globalization; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class ECPrivateKeyParameters + : ECKeyParameters + { + private readonly BigInteger d; + + public ECPrivateKeyParameters( + BigInteger d, + ECDomainParameters parameters) + : this("EC", d, parameters) + { + } + + [Obsolete("Use version with explicit 'algorithm' parameter")] + public ECPrivateKeyParameters( + BigInteger d, + DerObjectIdentifier publicKeyParamSet) + : base("ECGOST3410", true, publicKeyParamSet) + { + this.d = Parameters.ValidatePrivateScalar(d); + } + + public ECPrivateKeyParameters( + string algorithm, + BigInteger d, + ECDomainParameters parameters) + : base(algorithm, true, parameters) + { + this.d = Parameters.ValidatePrivateScalar(d); + } + + public ECPrivateKeyParameters( + string algorithm, + BigInteger d, + DerObjectIdentifier publicKeyParamSet) + : base(algorithm, true, publicKeyParamSet) + { + this.d = Parameters.ValidatePrivateScalar(d); + } + + public BigInteger D + { + get { return d; } + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + ECPrivateKeyParameters other = obj as ECPrivateKeyParameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected bool Equals( + ECPrivateKeyParameters other) + { + return d.Equals(other.d) && base.Equals(other); + } + + public override int GetHashCode() + { + return d.GetHashCode() ^ base.GetHashCode(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ECPrivateKeyParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ECPrivateKeyParameters.cs.meta new file mode 100644 index 0000000..d48233b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ECPrivateKeyParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 98c12bfd994a7154cb9bc5083bbaef0c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ECPublicKeyParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ECPublicKeyParameters.cs new file mode 100644 index 0000000..d43ac7e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ECPublicKeyParameters.cs @@ -0,0 +1,77 @@ +using System; +using System.Globalization; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Math.EC; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class ECPublicKeyParameters + : ECKeyParameters + { + private readonly ECPoint q; + + public ECPublicKeyParameters( + ECPoint q, + ECDomainParameters parameters) + : this("EC", q, parameters) + { + } + + [Obsolete("Use version with explicit 'algorithm' parameter")] + public ECPublicKeyParameters( + ECPoint q, + DerObjectIdentifier publicKeyParamSet) + : base("ECGOST3410", false, publicKeyParamSet) + { + this.q = ECDomainParameters.ValidatePublicPoint(Parameters.Curve, q); + } + + public ECPublicKeyParameters( + string algorithm, + ECPoint q, + ECDomainParameters parameters) + : base(algorithm, false, parameters) + { + this.q = ECDomainParameters.ValidatePublicPoint(Parameters.Curve, q); + } + + public ECPublicKeyParameters( + string algorithm, + ECPoint q, + DerObjectIdentifier publicKeyParamSet) + : base(algorithm, false, publicKeyParamSet) + { + this.q = ECDomainParameters.ValidatePublicPoint(Parameters.Curve, q); + } + + public ECPoint Q + { + get { return q; } + } + + public override bool Equals(object obj) + { + if (obj == this) + return true; + + ECPublicKeyParameters other = obj as ECPublicKeyParameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected bool Equals( + ECPublicKeyParameters other) + { + return q.Equals(other.q) && base.Equals(other); + } + + public override int GetHashCode() + { + return q.GetHashCode() ^ base.GetHashCode(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ECPublicKeyParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ECPublicKeyParameters.cs.meta new file mode 100644 index 0000000..002be57 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ECPublicKeyParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 95b1f7bc5391559468587c62ce6cdc25 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/Ed25519KeyGenerationParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/Ed25519KeyGenerationParameters.cs new file mode 100644 index 0000000..daf3856 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/Ed25519KeyGenerationParameters.cs @@ -0,0 +1,15 @@ +using System; + +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class Ed25519KeyGenerationParameters + : KeyGenerationParameters + { + public Ed25519KeyGenerationParameters(SecureRandom random) + : base(random, 256) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/Ed25519KeyGenerationParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/Ed25519KeyGenerationParameters.cs.meta new file mode 100644 index 0000000..eb06c11 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/Ed25519KeyGenerationParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9e4586c193195f143bb75387cc01ff27 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/Ed25519PrivateKeyParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/Ed25519PrivateKeyParameters.cs new file mode 100644 index 0000000..4e61a0f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/Ed25519PrivateKeyParameters.cs @@ -0,0 +1,123 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Math.EC.Rfc8032; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public sealed class Ed25519PrivateKeyParameters + : AsymmetricKeyParameter + { + public static readonly int KeySize = Ed25519.SecretKeySize; + public static readonly int SignatureSize = Ed25519.SignatureSize; + + private readonly byte[] data = new byte[KeySize]; + + private Ed25519PublicKeyParameters cachedPublicKey; + + public Ed25519PrivateKeyParameters(SecureRandom random) + : base(true) + { + Ed25519.GeneratePrivateKey(random, data); + } + + public Ed25519PrivateKeyParameters(byte[] buf) + : this(Validate(buf), 0) + { + } + + public Ed25519PrivateKeyParameters(byte[] buf, int off) + : base(true) + { + Array.Copy(buf, off, data, 0, KeySize); + } + + public Ed25519PrivateKeyParameters(Stream input) + : base(true) + { + if (KeySize != Streams.ReadFully(input, data)) + throw new EndOfStreamException("EOF encountered in middle of Ed25519 private key"); + } + + public void Encode(byte[] buf, int off) + { + Array.Copy(data, 0, buf, off, KeySize); + } + + public byte[] GetEncoded() + { + return Arrays.Clone(data); + } + + public Ed25519PublicKeyParameters GeneratePublicKey() + { + lock (data) + { + if (null == cachedPublicKey) + { + byte[] publicKey = new byte[Ed25519.PublicKeySize]; + Ed25519.GeneratePublicKey(data, 0, publicKey, 0); + cachedPublicKey = new Ed25519PublicKeyParameters(publicKey, 0); + } + + return cachedPublicKey; + } + } + + [Obsolete("Use overload that doesn't take a public key")] + public void Sign(Ed25519.Algorithm algorithm, Ed25519PublicKeyParameters publicKey, byte[] ctx, byte[] msg, int msgOff, int msgLen, + byte[] sig, int sigOff) + { + Sign(algorithm, ctx, msg, msgOff, msgLen, sig, sigOff); + } + + public void Sign(Ed25519.Algorithm algorithm, byte[] ctx, byte[] msg, int msgOff, int msgLen, + byte[] sig, int sigOff) + { + Ed25519PublicKeyParameters publicKey = GeneratePublicKey(); + + byte[] pk = new byte[Ed25519.PublicKeySize]; + publicKey.Encode(pk, 0); + + switch (algorithm) + { + case Ed25519.Algorithm.Ed25519: + { + if (null != ctx) + throw new ArgumentException("ctx"); + + Ed25519.Sign(data, 0, pk, 0, msg, msgOff, msgLen, sig, sigOff); + break; + } + case Ed25519.Algorithm.Ed25519ctx: + { + Ed25519.Sign(data, 0, pk, 0, ctx, msg, msgOff, msgLen, sig, sigOff); + break; + } + case Ed25519.Algorithm.Ed25519ph: + { + if (Ed25519.PrehashSize != msgLen) + throw new ArgumentException("msgLen"); + + Ed25519.SignPrehash(data, 0, pk, 0, ctx, msg, msgOff, sig, sigOff); + break; + } + default: + { + throw new ArgumentException("algorithm"); + } + } + } + + private static byte[] Validate(byte[] buf) + { + if (buf.Length != KeySize) + throw new ArgumentException("must have length " + KeySize, "buf"); + + return buf; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/Ed25519PrivateKeyParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/Ed25519PrivateKeyParameters.cs.meta new file mode 100644 index 0000000..83f5972 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/Ed25519PrivateKeyParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 709921408e323294cb1b59de48b0d385 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/Ed25519PublicKeyParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/Ed25519PublicKeyParameters.cs new file mode 100644 index 0000000..8a9139e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/Ed25519PublicKeyParameters.cs @@ -0,0 +1,53 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Math.EC.Rfc8032; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public sealed class Ed25519PublicKeyParameters + : AsymmetricKeyParameter + { + public static readonly int KeySize = Ed25519.PublicKeySize; + + private readonly byte[] data = new byte[KeySize]; + + public Ed25519PublicKeyParameters(byte[] buf) + : this(Validate(buf), 0) + { + } + + public Ed25519PublicKeyParameters(byte[] buf, int off) + : base(false) + { + Array.Copy(buf, off, data, 0, KeySize); + } + + public Ed25519PublicKeyParameters(Stream input) + : base(false) + { + if (KeySize != Streams.ReadFully(input, data)) + throw new EndOfStreamException("EOF encountered in middle of Ed25519 public key"); + } + + public void Encode(byte[] buf, int off) + { + Array.Copy(data, 0, buf, off, KeySize); + } + + public byte[] GetEncoded() + { + return Arrays.Clone(data); + } + + private static byte[] Validate(byte[] buf) + { + if (buf.Length != KeySize) + throw new ArgumentException("must have length " + KeySize, "buf"); + + return buf; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/Ed25519PublicKeyParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/Ed25519PublicKeyParameters.cs.meta new file mode 100644 index 0000000..1ee8b3e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/Ed25519PublicKeyParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6d20fe448292c2342a81b9c064fefb1a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/Ed448KeyGenerationParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/Ed448KeyGenerationParameters.cs new file mode 100644 index 0000000..830d15a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/Ed448KeyGenerationParameters.cs @@ -0,0 +1,15 @@ +using System; + +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class Ed448KeyGenerationParameters + : KeyGenerationParameters + { + public Ed448KeyGenerationParameters(SecureRandom random) + : base(random, 448) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/Ed448KeyGenerationParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/Ed448KeyGenerationParameters.cs.meta new file mode 100644 index 0000000..5cc3d20 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/Ed448KeyGenerationParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 06b93f577b7a07b489ecf5fec6677a8c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/Ed448PrivateKeyParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/Ed448PrivateKeyParameters.cs new file mode 100644 index 0000000..705ad8c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/Ed448PrivateKeyParameters.cs @@ -0,0 +1,115 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Math.EC.Rfc8032; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public sealed class Ed448PrivateKeyParameters + : AsymmetricKeyParameter + { + public static readonly int KeySize = Ed448.SecretKeySize; + public static readonly int SignatureSize = Ed448.SignatureSize; + + private readonly byte[] data = new byte[KeySize]; + + private Ed448PublicKeyParameters cachedPublicKey; + + public Ed448PrivateKeyParameters(SecureRandom random) + : base(true) + { + Ed448.GeneratePrivateKey(random, data); + } + + public Ed448PrivateKeyParameters(byte[] buf) + : this(Validate(buf), 0) + { + } + + public Ed448PrivateKeyParameters(byte[] buf, int off) + : base(true) + { + Array.Copy(buf, off, data, 0, KeySize); + } + + public Ed448PrivateKeyParameters(Stream input) + : base(true) + { + if (KeySize != Streams.ReadFully(input, data)) + throw new EndOfStreamException("EOF encountered in middle of Ed448 private key"); + } + + public void Encode(byte[] buf, int off) + { + Array.Copy(data, 0, buf, off, KeySize); + } + + public byte[] GetEncoded() + { + return Arrays.Clone(data); + } + + public Ed448PublicKeyParameters GeneratePublicKey() + { + lock (data) + { + if (null == cachedPublicKey) + { + byte[] publicKey = new byte[Ed448.PublicKeySize]; + Ed448.GeneratePublicKey(data, 0, publicKey, 0); + cachedPublicKey = new Ed448PublicKeyParameters(publicKey, 0); + } + + return cachedPublicKey; + } + } + + [Obsolete("Use overload that doesn't take a public key")] + public void Sign(Ed448.Algorithm algorithm, Ed448PublicKeyParameters publicKey, byte[] ctx, byte[] msg, int msgOff, int msgLen, + byte[] sig, int sigOff) + { + Sign(algorithm, ctx, msg, msgOff, msgLen, sig, sigOff); + } + + public void Sign(Ed448.Algorithm algorithm, byte[] ctx, byte[] msg, int msgOff, int msgLen, + byte[] sig, int sigOff) + { + Ed448PublicKeyParameters publicKey = GeneratePublicKey(); + + byte[] pk = new byte[Ed448.PublicKeySize]; + publicKey.Encode(pk, 0); + + switch (algorithm) + { + case Ed448.Algorithm.Ed448: + { + Ed448.Sign(data, 0, pk, 0, ctx, msg, msgOff, msgLen, sig, sigOff); + break; + } + case Ed448.Algorithm.Ed448ph: + { + if (Ed448.PrehashSize != msgLen) + throw new ArgumentException("msgLen"); + + Ed448.SignPrehash(data, 0, pk, 0, ctx, msg, msgOff, sig, sigOff); + break; + } + default: + { + throw new ArgumentException("algorithm"); + } + } + } + + private static byte[] Validate(byte[] buf) + { + if (buf.Length != KeySize) + throw new ArgumentException("must have length " + KeySize, "buf"); + + return buf; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/Ed448PrivateKeyParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/Ed448PrivateKeyParameters.cs.meta new file mode 100644 index 0000000..b55ab38 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/Ed448PrivateKeyParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1ace81806149aaf409a51668e0b38aba +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/Ed448PublicKeyParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/Ed448PublicKeyParameters.cs new file mode 100644 index 0000000..8a89be0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/Ed448PublicKeyParameters.cs @@ -0,0 +1,53 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Math.EC.Rfc8032; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public sealed class Ed448PublicKeyParameters + : AsymmetricKeyParameter + { + public static readonly int KeySize = Ed448.PublicKeySize; + + private readonly byte[] data = new byte[KeySize]; + + public Ed448PublicKeyParameters(byte[] buf) + : this(Validate(buf), 0) + { + } + + public Ed448PublicKeyParameters(byte[] buf, int off) + : base(false) + { + Array.Copy(buf, off, data, 0, KeySize); + } + + public Ed448PublicKeyParameters(Stream input) + : base(false) + { + if (KeySize != Streams.ReadFully(input, data)) + throw new EndOfStreamException("EOF encountered in middle of Ed448 public key"); + } + + public void Encode(byte[] buf, int off) + { + Array.Copy(data, 0, buf, off, KeySize); + } + + public byte[] GetEncoded() + { + return Arrays.Clone(data); + } + + private static byte[] Validate(byte[] buf) + { + if (buf.Length != KeySize) + throw new ArgumentException("must have length " + KeySize, "buf"); + + return buf; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/Ed448PublicKeyParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/Ed448PublicKeyParameters.cs.meta new file mode 100644 index 0000000..532b53a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/Ed448PublicKeyParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2e25b9a2ca578d649bd4603daed0fe2f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ElGamalKeyGenerationParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ElGamalKeyGenerationParameters.cs new file mode 100644 index 0000000..40ca70d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ElGamalKeyGenerationParameters.cs @@ -0,0 +1,31 @@ +using System; + +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class ElGamalKeyGenerationParameters + : KeyGenerationParameters + { + private readonly ElGamalParameters parameters; + + public ElGamalKeyGenerationParameters( + SecureRandom random, + ElGamalParameters parameters) + : base(random, GetStrength(parameters)) + { + this.parameters = parameters; + } + + public ElGamalParameters Parameters + { + get { return parameters; } + } + + internal static int GetStrength( + ElGamalParameters parameters) + { + return parameters.L != 0 ? parameters.L : parameters.P.BitLength; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ElGamalKeyGenerationParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ElGamalKeyGenerationParameters.cs.meta new file mode 100644 index 0000000..7cabcb8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ElGamalKeyGenerationParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1e7733252fdd68044829ad917bc892a4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ElGamalKeyParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ElGamalKeyParameters.cs new file mode 100644 index 0000000..8b6e279 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ElGamalKeyParameters.cs @@ -0,0 +1,59 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class ElGamalKeyParameters + : AsymmetricKeyParameter + { + private readonly ElGamalParameters parameters; + + protected ElGamalKeyParameters( + bool isPrivate, + ElGamalParameters parameters) + : base(isPrivate) + { + // TODO Should we allow 'parameters' to be null? + this.parameters = parameters; + } + + public ElGamalParameters Parameters + { + get { return parameters; } + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + ElGamalKeyParameters other = obj as ElGamalKeyParameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected bool Equals( + ElGamalKeyParameters other) + { + return Platform.Equals(parameters, other.parameters) + && base.Equals(other); + } + + public override int GetHashCode() + { + int hc = base.GetHashCode(); + + if (parameters != null) + { + hc ^= parameters.GetHashCode(); + } + + return hc; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ElGamalKeyParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ElGamalKeyParameters.cs.meta new file mode 100644 index 0000000..2f0bcbe --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ElGamalKeyParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1ebef6cce4a0006489fbfd24fbd588a5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ElGamalParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ElGamalParameters.cs new file mode 100644 index 0000000..ab6d3e7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ElGamalParameters.cs @@ -0,0 +1,81 @@ +using System; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class ElGamalParameters + : ICipherParameters + { + private readonly BigInteger p, g; + private readonly int l; + + public ElGamalParameters( + BigInteger p, + BigInteger g) + : this(p, g, 0) + { + } + + public ElGamalParameters( + BigInteger p, + BigInteger g, + int l) + { + if (p == null) + throw new ArgumentNullException("p"); + if (g == null) + throw new ArgumentNullException("g"); + + this.p = p; + this.g = g; + this.l = l; + } + + public BigInteger P + { + get { return p; } + } + + /** + * return the generator - g + */ + public BigInteger G + { + get { return g; } + } + + /** + * return private value limit - l + */ + public int L + { + get { return l; } + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + ElGamalParameters other = obj as ElGamalParameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected bool Equals( + ElGamalParameters other) + { + return p.Equals(other.p) && g.Equals(other.g) && l == other.l; + } + + public override int GetHashCode() + { + return p.GetHashCode() ^ g.GetHashCode() ^ l; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ElGamalParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ElGamalParameters.cs.meta new file mode 100644 index 0000000..31b190f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ElGamalParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f949d3ad3a845d541bbe73a9ffe9868c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ElGamalPrivateKeyParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ElGamalPrivateKeyParameters.cs new file mode 100644 index 0000000..6363f2b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ElGamalPrivateKeyParameters.cs @@ -0,0 +1,53 @@ +using System; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class ElGamalPrivateKeyParameters + : ElGamalKeyParameters + { + private readonly BigInteger x; + + public ElGamalPrivateKeyParameters( + BigInteger x, + ElGamalParameters parameters) + : base(true, parameters) + { + if (x == null) + throw new ArgumentNullException("x"); + + this.x = x; + } + + public BigInteger X + { + get { return x; } + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + ElGamalPrivateKeyParameters other = obj as ElGamalPrivateKeyParameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected bool Equals( + ElGamalPrivateKeyParameters other) + { + return other.x.Equals(x) && base.Equals(other); + } + + public override int GetHashCode() + { + return x.GetHashCode() ^ base.GetHashCode(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ElGamalPrivateKeyParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ElGamalPrivateKeyParameters.cs.meta new file mode 100644 index 0000000..36026fb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ElGamalPrivateKeyParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 73c7ec7d7c2733d408145a105f340b85 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ElGamalPublicKeyParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ElGamalPublicKeyParameters.cs new file mode 100644 index 0000000..25ac625 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ElGamalPublicKeyParameters.cs @@ -0,0 +1,53 @@ +using System; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class ElGamalPublicKeyParameters + : ElGamalKeyParameters + { + private readonly BigInteger y; + + public ElGamalPublicKeyParameters( + BigInteger y, + ElGamalParameters parameters) + : base(false, parameters) + { + if (y == null) + throw new ArgumentNullException("y"); + + this.y = y; + } + + public BigInteger Y + { + get { return y; } + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + ElGamalPublicKeyParameters other = obj as ElGamalPublicKeyParameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected bool Equals( + ElGamalPublicKeyParameters other) + { + return y.Equals(other.y) && base.Equals(other); + } + + public override int GetHashCode() + { + return y.GetHashCode() ^ base.GetHashCode(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ElGamalPublicKeyParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ElGamalPublicKeyParameters.cs.meta new file mode 100644 index 0000000..bec4844 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ElGamalPublicKeyParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ee072221640f0f84880125798ad88390 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/FpeParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/FpeParameters.cs new file mode 100644 index 0000000..ab88333 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/FpeParameters.cs @@ -0,0 +1,49 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Parameters +{ +public sealed class FpeParameters + : ICipherParameters +{ + private readonly KeyParameter key; + private readonly int radix; + private readonly byte[] tweak; + private readonly bool useInverse; + + public FpeParameters(KeyParameter key, int radix, byte[] tweak): this(key, radix, tweak, false) + { + + } + + public FpeParameters(KeyParameter key, int radix, byte[] tweak, bool useInverse) + { + this.key = key; + this.radix = radix; + this.tweak = Arrays.Clone(tweak); + this.useInverse = useInverse; + } + + public KeyParameter Key + { + get { return key; } + } + + public int Radix + { + get { return radix; } + } + + public bool UseInverseFunction + { + get { return useInverse; } + } + + public byte[] GetTweak() + { + return Arrays.Clone(tweak); + } +} +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/FpeParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/FpeParameters.cs.meta new file mode 100644 index 0000000..8eaa589 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/FpeParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8bb68e2463e119c4b8e0db12aaff75bf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/GOST3410KeyGenerationParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/GOST3410KeyGenerationParameters.cs new file mode 100644 index 0000000..b06a5d8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/GOST3410KeyGenerationParameters.cs @@ -0,0 +1,55 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class Gost3410KeyGenerationParameters + : KeyGenerationParameters + { + private readonly Gost3410Parameters parameters; + private readonly DerObjectIdentifier publicKeyParamSet; + + public Gost3410KeyGenerationParameters( + SecureRandom random, + Gost3410Parameters parameters) + : base(random, parameters.P.BitLength - 1) + { + this.parameters = parameters; + } + + public Gost3410KeyGenerationParameters( + SecureRandom random, + DerObjectIdentifier publicKeyParamSet) + : this(random, LookupParameters(publicKeyParamSet)) + { + this.publicKeyParamSet = publicKeyParamSet; + } + + public Gost3410Parameters Parameters + { + get { return parameters; } + } + + public DerObjectIdentifier PublicKeyParamSet + { + get { return publicKeyParamSet; } + } + + private static Gost3410Parameters LookupParameters( + DerObjectIdentifier publicKeyParamSet) + { + if (publicKeyParamSet == null) + throw new ArgumentNullException("publicKeyParamSet"); + + Gost3410ParamSetParameters p = Gost3410NamedParameters.GetByOid(publicKeyParamSet); + + if (p == null) + throw new ArgumentException("OID is not a valid CryptoPro public key parameter set", "publicKeyParamSet"); + + return new Gost3410Parameters(p.P, p.Q, p.A); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/GOST3410KeyGenerationParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/GOST3410KeyGenerationParameters.cs.meta new file mode 100644 index 0000000..8a32ff6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/GOST3410KeyGenerationParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c3139fc0a95805f488ce055878e05921 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/GOST3410KeyParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/GOST3410KeyParameters.cs new file mode 100644 index 0000000..f771c4d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/GOST3410KeyParameters.cs @@ -0,0 +1,58 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public abstract class Gost3410KeyParameters + : AsymmetricKeyParameter + { + private readonly Gost3410Parameters parameters; + private readonly DerObjectIdentifier publicKeyParamSet; + + protected Gost3410KeyParameters( + bool isPrivate, + Gost3410Parameters parameters) + : base(isPrivate) + { + this.parameters = parameters; + } + + protected Gost3410KeyParameters( + bool isPrivate, + DerObjectIdentifier publicKeyParamSet) + : base(isPrivate) + { + this.parameters = LookupParameters(publicKeyParamSet); + this.publicKeyParamSet = publicKeyParamSet; + } + + public Gost3410Parameters Parameters + { + get { return parameters; } + } + + public DerObjectIdentifier PublicKeyParamSet + { + get { return publicKeyParamSet; } + } + + // TODO Implement Equals/GetHashCode + + private static Gost3410Parameters LookupParameters( + DerObjectIdentifier publicKeyParamSet) + { + if (publicKeyParamSet == null) + throw new ArgumentNullException("publicKeyParamSet"); + + Gost3410ParamSetParameters p = Gost3410NamedParameters.GetByOid(publicKeyParamSet); + + if (p == null) + throw new ArgumentException("OID is not a valid CryptoPro public key parameter set", "publicKeyParamSet"); + + return new Gost3410Parameters(p.P, p.Q, p.A); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/GOST3410KeyParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/GOST3410KeyParameters.cs.meta new file mode 100644 index 0000000..9e1c72f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/GOST3410KeyParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a69cc72cf9e464a48b84623a2a496201 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/GOST3410Parameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/GOST3410Parameters.cs new file mode 100644 index 0000000..2ec167e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/GOST3410Parameters.cs @@ -0,0 +1,86 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class Gost3410Parameters + : ICipherParameters + { + private readonly BigInteger p, q, a; + private readonly Gost3410ValidationParameters validation; + + public Gost3410Parameters( + BigInteger p, + BigInteger q, + BigInteger a) + : this(p, q, a, null) + { + } + + public Gost3410Parameters( + BigInteger p, + BigInteger q, + BigInteger a, + Gost3410ValidationParameters validation) + { + if (p == null) + throw new ArgumentNullException("p"); + if (q == null) + throw new ArgumentNullException("q"); + if (a == null) + throw new ArgumentNullException("a"); + + this.p = p; + this.q = q; + this.a = a; + this.validation = validation; + } + + public BigInteger P + { + get { return p; } + } + + public BigInteger Q + { + get { return q; } + } + + public BigInteger A + { + get { return a; } + } + + public Gost3410ValidationParameters ValidationParameters + { + get { return validation; } + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + Gost3410Parameters other = obj as Gost3410Parameters; + + if (other == null) + return false; + + return Equals(other); + } + + protected bool Equals( + Gost3410Parameters other) + { + return p.Equals(other.p) && q.Equals(other.q) && a.Equals(other.a); + } + + public override int GetHashCode() + { + return p.GetHashCode() ^ q.GetHashCode() ^ a.GetHashCode(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/GOST3410Parameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/GOST3410Parameters.cs.meta new file mode 100644 index 0000000..e1edc12 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/GOST3410Parameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c3ac7270a5bcce842a7660efa41f4bc8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/GOST3410PrivateKeyParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/GOST3410PrivateKeyParameters.cs new file mode 100644 index 0000000..e3a613d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/GOST3410PrivateKeyParameters.cs @@ -0,0 +1,41 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class Gost3410PrivateKeyParameters + : Gost3410KeyParameters + { + private readonly BigInteger x; + + public Gost3410PrivateKeyParameters( + BigInteger x, + Gost3410Parameters parameters) + : base(true, parameters) + { + if (x.SignValue < 1 || x.BitLength > 256 || x.CompareTo(Parameters.Q) >= 0) + throw new ArgumentException("Invalid x for GOST3410 private key", "x"); + + this.x = x; + } + + public Gost3410PrivateKeyParameters( + BigInteger x, + DerObjectIdentifier publicKeyParamSet) + : base(true, publicKeyParamSet) + { + if (x.SignValue < 1 || x.BitLength > 256 || x.CompareTo(Parameters.Q) >= 0) + throw new ArgumentException("Invalid x for GOST3410 private key", "x"); + + this.x = x; + } + + public BigInteger X + { + get { return x; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/GOST3410PrivateKeyParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/GOST3410PrivateKeyParameters.cs.meta new file mode 100644 index 0000000..8f9b84c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/GOST3410PrivateKeyParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cf4784cd7d116fd46a619324261509b2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/GOST3410PublicKeyParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/GOST3410PublicKeyParameters.cs new file mode 100644 index 0000000..96b7e91 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/GOST3410PublicKeyParameters.cs @@ -0,0 +1,40 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class Gost3410PublicKeyParameters + : Gost3410KeyParameters + { + private readonly BigInteger y; + + public Gost3410PublicKeyParameters( + BigInteger y, + Gost3410Parameters parameters) + : base(false, parameters) + { + if (y.SignValue < 1 || y.CompareTo(Parameters.P) >= 0) + throw new ArgumentException("Invalid y for GOST3410 public key", "y"); + + this.y = y; + } + + public Gost3410PublicKeyParameters( + BigInteger y, + DerObjectIdentifier publicKeyParamSet) + : base(false, publicKeyParamSet) + { + if (y.SignValue < 1 || y.CompareTo(Parameters.P) >= 0) + throw new ArgumentException("Invalid y for GOST3410 public key", "y"); + + this.y = y; + } + + public BigInteger Y + { + get { return y; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/GOST3410PublicKeyParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/GOST3410PublicKeyParameters.cs.meta new file mode 100644 index 0000000..a5321e0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/GOST3410PublicKeyParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9985a30b0381ab348963be45e24e52e0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/GOST3410ValidationParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/GOST3410ValidationParameters.cs new file mode 100644 index 0000000..21e5af8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/GOST3410ValidationParameters.cs @@ -0,0 +1,51 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class Gost3410ValidationParameters + { + private int x0; + private int c; + private long x0L; + private long cL; + + public Gost3410ValidationParameters( + int x0, + int c) + { + this.x0 = x0; + this.c = c; + } + + public Gost3410ValidationParameters( + long x0L, + long cL) + { + this.x0L = x0L; + this.cL = cL; + } + + public int C { get { return c; } } + public int X0 { get { return x0; } } + public long CL { get { return cL; } } + public long X0L { get { return x0L; } } + + public override bool Equals( + object obj) + { + Gost3410ValidationParameters other = obj as Gost3410ValidationParameters; + + return other != null + && other.c == this.c + && other.x0 == this.x0 + && other.cL == this.cL + && other.x0L == this.x0L; + } + + public override int GetHashCode() + { + return c.GetHashCode() ^ x0.GetHashCode() ^ cL.GetHashCode() ^ x0L.GetHashCode(); + } + + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/GOST3410ValidationParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/GOST3410ValidationParameters.cs.meta new file mode 100644 index 0000000..4144684 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/GOST3410ValidationParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9f1ade0ec93a6d74c87ec45353052379 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/HKdfParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/HKdfParameters.cs new file mode 100644 index 0000000..6d1465e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/HKdfParameters.cs @@ -0,0 +1,119 @@ +using System; + +using Org.BouncyCastle.Crypto.Macs; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + /** + * Parameter class for the HkdfBytesGenerator class. + */ + public class HkdfParameters + : IDerivationParameters + { + private readonly byte[] ikm; + private readonly bool skipExpand; + private readonly byte[] salt; + private readonly byte[] info; + + private HkdfParameters(byte[] ikm, bool skip, byte[] salt, byte[] info) + { + if (ikm == null) + throw new ArgumentNullException("ikm"); + + this.ikm = Arrays.Clone(ikm); + this.skipExpand = skip; + + if (salt == null || salt.Length == 0) + { + this.salt = null; + } + else + { + this.salt = Arrays.Clone(salt); + } + + if (info == null) + { + this.info = new byte[0]; + } + else + { + this.info = Arrays.Clone(info); + } + } + + /** + * Generates parameters for HKDF, specifying both the optional salt and + * optional info. Step 1: Extract won't be skipped. + * + * @param ikm the input keying material or seed + * @param salt the salt to use, may be null for a salt for hashLen zeros + * @param info the info to use, may be null for an info field of zero bytes + */ + public HkdfParameters(byte[] ikm, byte[] salt, byte[] info) + : this(ikm, false, salt, info) + { + } + + /** + * Factory method that makes the HKDF skip the extract part of the key + * derivation function. + * + * @param ikm the input keying material or seed, directly used for step 2: + * Expand + * @param info the info to use, may be null for an info field of zero bytes + * @return HKDFParameters that makes the implementation skip step 1 + */ + public static HkdfParameters SkipExtractParameters(byte[] ikm, byte[] info) + { + return new HkdfParameters(ikm, true, null, info); + } + + public static HkdfParameters DefaultParameters(byte[] ikm) + { + return new HkdfParameters(ikm, false, null, null); + } + + /** + * Returns the input keying material or seed. + * + * @return the keying material + */ + public virtual byte[] GetIkm() + { + return Arrays.Clone(ikm); + } + + /** + * Returns if step 1: extract has to be skipped or not + * + * @return true for skipping, false for no skipping of step 1 + */ + public virtual bool SkipExtract + { + get { return skipExpand; } + } + + /** + * Returns the salt, or null if the salt should be generated as a byte array + * of HashLen zeros. + * + * @return the salt, or null + */ + public virtual byte[] GetSalt() + { + return Arrays.Clone(salt); + } + + /** + * Returns the info field, which may be empty (null is converted to empty). + * + * @return the info field, never null + */ + public virtual byte[] GetInfo() + { + return Arrays.Clone(info); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/HKdfParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/HKdfParameters.cs.meta new file mode 100644 index 0000000..a895e8f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/HKdfParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 430b0be963843da4aa52c2462fed9f50 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ISO18033KDFParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ISO18033KDFParameters.cs new file mode 100644 index 0000000..2d8fff8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ISO18033KDFParameters.cs @@ -0,0 +1,25 @@ +using System; +using Org.BouncyCastle.Crypto; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + /** + * parameters for Key derivation functions for ISO-18033 + */ + public class Iso18033KdfParameters + : IDerivationParameters + { + byte[] seed; + + public Iso18033KdfParameters( + byte[] seed) + { + this.seed = seed; + } + + public byte[] GetSeed() + { + return seed; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ISO18033KDFParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ISO18033KDFParameters.cs.meta new file mode 100644 index 0000000..093d7f6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ISO18033KDFParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 844e9ec29157bb84d9a9ad7322598888 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/IesParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/IesParameters.cs new file mode 100644 index 0000000..d306b2c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/IesParameters.cs @@ -0,0 +1,49 @@ +using System; +using Org.BouncyCastle.Crypto; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + /** + * parameters for using an integrated cipher in stream mode. + */ + public class IesParameters : ICipherParameters + { + private byte[] derivation; + private byte[] encoding; + private int macKeySize; + + /** + * @param derivation the derivation parameter for the KDF function. + * @param encoding the encoding parameter for the KDF function. + * @param macKeySize the size of the MAC key (in bits). + */ + public IesParameters( + byte[] derivation, + byte[] encoding, + int macKeySize) + { + this.derivation = derivation; + this.encoding = encoding; + this.macKeySize = macKeySize; + } + + public byte[] GetDerivationV() + { + return derivation; + } + + public byte[] GetEncodingV() + { + return encoding; + } + + public int MacKeySize + { + get + { + return macKeySize; + } + } + } + +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/IesParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/IesParameters.cs.meta new file mode 100644 index 0000000..e446309 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/IesParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: eb56f142f4a4b5848bdf04fac53f9996 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/IesWithCipherParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/IesWithCipherParameters.cs new file mode 100644 index 0000000..70ef55d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/IesWithCipherParameters.cs @@ -0,0 +1,33 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class IesWithCipherParameters : IesParameters + { + private int cipherKeySize; + + /** + * @param derivation the derivation parameter for the KDF function. + * @param encoding the encoding parameter for the KDF function. + * @param macKeySize the size of the MAC key (in bits). + * @param cipherKeySize the size of the associated Cipher key (in bits). + */ + public IesWithCipherParameters( + byte[] derivation, + byte[] encoding, + int macKeySize, + int cipherKeySize) : base(derivation, encoding, macKeySize) + { + this.cipherKeySize = cipherKeySize; + } + + public int CipherKeySize + { + get + { + return cipherKeySize; + } + } + } + +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/IesWithCipherParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/IesWithCipherParameters.cs.meta new file mode 100644 index 0000000..ef5e99d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/IesWithCipherParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a766adef4b3699f4a97411e207a98e71 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/KDFCounterParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/KDFCounterParameters.cs new file mode 100644 index 0000000..49d6f7d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/KDFCounterParameters.cs @@ -0,0 +1,92 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class KdfCounterParameters : IDerivationParameters + { + private byte[] ki; + private byte[] fixedInputDataCounterPrefix; + private byte[] fixedInputDataCounterSuffix; + private int r; + + /// + /// Base constructor - suffix fixed input data only. + /// + /// the KDF seed + /// fixed input data to follow counter. + /// length of the counter in bits + public KdfCounterParameters(byte[] ki, byte[] fixedInputDataCounterSuffix, int r) : this(ki, null, fixedInputDataCounterSuffix, r) + { + } + + + + /// + /// Base constructor - prefix and suffix fixed input data. + /// + /// the KDF seed + /// fixed input data to precede counter + /// fixed input data to follow counter. + /// length of the counter in bits. + public KdfCounterParameters(byte[] ki, byte[] fixedInputDataCounterPrefix, byte[] fixedInputDataCounterSuffix, int r) + { + if (ki == null) + { + throw new ArgumentException("A KDF requires Ki (a seed) as input"); + } + this.ki = Arrays.Clone(ki); + + if (fixedInputDataCounterPrefix == null) + { + this.fixedInputDataCounterPrefix = new byte[0]; + } + else + { + this.fixedInputDataCounterPrefix = Arrays.Clone(fixedInputDataCounterPrefix); + } + + if (fixedInputDataCounterSuffix == null) + { + this.fixedInputDataCounterSuffix = new byte[0]; + } + else + { + this.fixedInputDataCounterSuffix = Arrays.Clone(fixedInputDataCounterSuffix); + } + + if (r != 8 && r != 16 && r != 24 && r != 32) + { + throw new ArgumentException("Length of counter should be 8, 16, 24 or 32"); + } + this.r = r; + } + + public byte[] Ki + { + get { return ki; } + } + + public byte[] FixedInputData + { + get { return Arrays.Clone(fixedInputDataCounterSuffix); } + } + + public byte[] FixedInputDataCounterPrefix + { + get { return Arrays.Clone(fixedInputDataCounterPrefix); } + + } + + public byte[] FixedInputDataCounterSuffix + { + get { return Arrays.Clone(fixedInputDataCounterSuffix); } + } + + public int R + { + get { return r; } + } + } +} \ No newline at end of file diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/KDFCounterParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/KDFCounterParameters.cs.meta new file mode 100644 index 0000000..f57a0c0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/KDFCounterParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 64125bcbf6f6b094195c9fdf6a54c626 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/KDFDoublePipelineIterationParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/KDFDoublePipelineIterationParameters.cs new file mode 100644 index 0000000..9e2a68b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/KDFDoublePipelineIterationParameters.cs @@ -0,0 +1,77 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class KdfDoublePipelineIterationParameters : IDerivationParameters + { + // could be any valid value, using 32, don't know why + private static readonly int UNUSED_R = 32; + + private readonly byte[] ki; + private readonly bool useCounter; + private readonly int r; + private readonly byte[] fixedInputData; + + private KdfDoublePipelineIterationParameters(byte[] ki, byte[] fixedInputData, int r, bool useCounter) + { + if (ki == null) + { + throw new ArgumentException("A KDF requires Ki (a seed) as input"); + } + + this.ki = Arrays.Clone(ki); + + if (fixedInputData == null) + { + this.fixedInputData = new byte[0]; + } + else + { + this.fixedInputData = Arrays.Clone(fixedInputData); + } + + if (r != 8 && r != 16 && r != 24 && r != 32) + { + throw new ArgumentException("Length of counter should be 8, 16, 24 or 32"); + } + + this.r = r; + + this.useCounter = useCounter; + } + + public static KdfDoublePipelineIterationParameters CreateWithCounter( + byte[] ki, byte[] fixedInputData, int r) + { + return new KdfDoublePipelineIterationParameters(ki, fixedInputData, r, true); + } + + public static KdfDoublePipelineIterationParameters CreateWithoutCounter( + byte[] ki, byte[] fixedInputData) + { + return new KdfDoublePipelineIterationParameters(ki, fixedInputData, UNUSED_R, false); + } + + public byte[] Ki + { + get { return Arrays.Clone(ki); } + } + + public bool UseCounter + { + get { return useCounter; } + } + + public int R + { + get { return r; } + } + + public byte[] FixedInputData + { + get { return Arrays.Clone(fixedInputData); } + } + } +} \ No newline at end of file diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/KDFDoublePipelineIterationParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/KDFDoublePipelineIterationParameters.cs.meta new file mode 100644 index 0000000..c4317b9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/KDFDoublePipelineIterationParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 43888302b40d6d14f94f550c5797d337 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/KDFFeedbackParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/KDFFeedbackParameters.cs new file mode 100644 index 0000000..86ea232 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/KDFFeedbackParameters.cs @@ -0,0 +1,92 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class KdfFeedbackParameters : IDerivationParameters + { + // could be any valid value, using 32, don't know why + private static readonly int UNUSED_R = -1; + + private readonly byte[] ki; + private readonly byte[] iv; + private readonly bool useCounter; + private readonly int r; + private readonly byte[] fixedInputData; + + private KdfFeedbackParameters(byte[] ki, byte[] iv, byte[] fixedInputData, int r, bool useCounter) + { + if (ki == null) + { + throw new ArgumentException("A KDF requires Ki (a seed) as input"); + } + + this.ki = Arrays.Clone(ki); + + if (fixedInputData == null) + { + this.fixedInputData = new byte[0]; + } + else + { + this.fixedInputData = Arrays.Clone(fixedInputData); + } + + this.r = r; + + if (iv == null) + { + this.iv = new byte[0]; + } + else + { + this.iv = Arrays.Clone(iv); + } + + this.useCounter = useCounter; + } + + public static KdfFeedbackParameters CreateWithCounter( + byte[] ki, byte[] iv, byte[] fixedInputData, int r) + { + if (r != 8 && r != 16 && r != 24 && r != 32) + { + throw new ArgumentException("Length of counter should be 8, 16, 24 or 32"); + } + + return new KdfFeedbackParameters(ki, iv, fixedInputData, r, true); + } + + public static KdfFeedbackParameters CreateWithoutCounter( + byte[] ki, byte[] iv, byte[] fixedInputData) + { + return new KdfFeedbackParameters(ki, iv, fixedInputData, UNUSED_R, false); + } + + public byte[] Ki + { + get { return Arrays.Clone(ki); } + } + + public byte[] Iv + { + get { return Arrays.Clone(iv); } + } + + public bool UseCounter + { + get { return useCounter; } + } + + public int R + { + get { return r; } + } + + public byte[] FixedInputData + { + get { return Arrays.Clone(fixedInputData); } + } + } +} \ No newline at end of file diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/KDFFeedbackParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/KDFFeedbackParameters.cs.meta new file mode 100644 index 0000000..686fc38 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/KDFFeedbackParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 42e05e297b9747a459aac0e4256d3920 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/KdfParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/KdfParameters.cs new file mode 100644 index 0000000..bc5c905 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/KdfParameters.cs @@ -0,0 +1,33 @@ +using System; +using Org.BouncyCastle.Crypto; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + /** + * parameters for Key derivation functions for IEEE P1363a + */ + public class KdfParameters : IDerivationParameters + { + byte[] iv; + byte[] shared; + + public KdfParameters( + byte[] shared, + byte[] iv) + { + this.shared = shared; + this.iv = iv; + } + + public byte[] GetSharedSecret() + { + return shared; + } + + public byte[] GetIV() + { + return iv; + } + } + +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/KdfParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/KdfParameters.cs.meta new file mode 100644 index 0000000..44930dd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/KdfParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fef193ab720f210498128faf37cef5fb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/KeyParameter.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/KeyParameter.cs new file mode 100644 index 0000000..043adf2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/KeyParameter.cs @@ -0,0 +1,43 @@ +using System; + +using Org.BouncyCastle.Crypto; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class KeyParameter + : ICipherParameters + { + private readonly byte[] key; + + public KeyParameter( + byte[] key) + { + if (key == null) + throw new ArgumentNullException("key"); + + this.key = (byte[]) key.Clone(); + } + + public KeyParameter( + byte[] key, + int keyOff, + int keyLen) + { + if (key == null) + throw new ArgumentNullException("key"); + if (keyOff < 0 || keyOff > key.Length) + throw new ArgumentOutOfRangeException("keyOff"); + if (keyLen < 0 || keyLen > (key.Length - keyOff)) + throw new ArgumentOutOfRangeException("keyLen"); + + this.key = new byte[keyLen]; + Array.Copy(key, keyOff, this.key, 0, keyLen); + } + + public byte[] GetKey() + { + return (byte[]) key.Clone(); + } + } + +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/KeyParameter.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/KeyParameter.cs.meta new file mode 100644 index 0000000..11a20b8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/KeyParameter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: eab378f629021ed4b92052e4607f9b59 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/MgfParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/MgfParameters.cs new file mode 100644 index 0000000..11983b8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/MgfParameters.cs @@ -0,0 +1,31 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + /// Parameters for mask derivation functions. + public class MgfParameters + : IDerivationParameters + { + private readonly byte[] seed; + + public MgfParameters( + byte[] seed) + : this(seed, 0, seed.Length) + { + } + + public MgfParameters( + byte[] seed, + int off, + int len) + { + this.seed = new byte[len]; + Array.Copy(seed, off, this.seed, 0, len); + } + + public byte[] GetSeed() + { + return (byte[]) seed.Clone(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/MgfParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/MgfParameters.cs.meta new file mode 100644 index 0000000..19f9d18 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/MgfParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7d078f1427ee468459b13c1dcd5e05ea +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/MqvPrivateParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/MqvPrivateParameters.cs new file mode 100644 index 0000000..3714571 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/MqvPrivateParameters.cs @@ -0,0 +1,67 @@ +using System; + +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Math.EC.Multiplier; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class MqvPrivateParameters + : ICipherParameters + { + private readonly ECPrivateKeyParameters staticPrivateKey; + private readonly ECPrivateKeyParameters ephemeralPrivateKey; + private readonly ECPublicKeyParameters ephemeralPublicKey; + + public MqvPrivateParameters( + ECPrivateKeyParameters staticPrivateKey, + ECPrivateKeyParameters ephemeralPrivateKey) + : this(staticPrivateKey, ephemeralPrivateKey, null) + { + } + + public MqvPrivateParameters( + ECPrivateKeyParameters staticPrivateKey, + ECPrivateKeyParameters ephemeralPrivateKey, + ECPublicKeyParameters ephemeralPublicKey) + { + if (staticPrivateKey == null) + throw new ArgumentNullException("staticPrivateKey"); + if (ephemeralPrivateKey == null) + throw new ArgumentNullException("ephemeralPrivateKey"); + + ECDomainParameters parameters = staticPrivateKey.Parameters; + if (!parameters.Equals(ephemeralPrivateKey.Parameters)) + throw new ArgumentException("Static and ephemeral private keys have different domain parameters"); + + if (ephemeralPublicKey == null) + { + ECPoint q = new FixedPointCombMultiplier().Multiply(parameters.G, ephemeralPrivateKey.D); + + ephemeralPublicKey = new ECPublicKeyParameters(q, parameters); + } + else if (!parameters.Equals(ephemeralPublicKey.Parameters)) + { + throw new ArgumentException("Ephemeral public key has different domain parameters"); + } + + this.staticPrivateKey = staticPrivateKey; + this.ephemeralPrivateKey = ephemeralPrivateKey; + this.ephemeralPublicKey = ephemeralPublicKey; + } + + public virtual ECPrivateKeyParameters StaticPrivateKey + { + get { return staticPrivateKey; } + } + + public virtual ECPrivateKeyParameters EphemeralPrivateKey + { + get { return ephemeralPrivateKey; } + } + + public virtual ECPublicKeyParameters EphemeralPublicKey + { + get { return ephemeralPublicKey; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/MqvPrivateParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/MqvPrivateParameters.cs.meta new file mode 100644 index 0000000..ef61982 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/MqvPrivateParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e8e4c1393c35a6048a42f63df387a1a3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/MqvPublicParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/MqvPublicParameters.cs new file mode 100644 index 0000000..239afa3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/MqvPublicParameters.cs @@ -0,0 +1,36 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class MqvPublicParameters + : ICipherParameters + { + private readonly ECPublicKeyParameters staticPublicKey; + private readonly ECPublicKeyParameters ephemeralPublicKey; + + public MqvPublicParameters( + ECPublicKeyParameters staticPublicKey, + ECPublicKeyParameters ephemeralPublicKey) + { + if (staticPublicKey == null) + throw new ArgumentNullException("staticPublicKey"); + if (ephemeralPublicKey == null) + throw new ArgumentNullException("ephemeralPublicKey"); + if (!staticPublicKey.Parameters.Equals(ephemeralPublicKey.Parameters)) + throw new ArgumentException("Static and ephemeral public keys have different domain parameters"); + + this.staticPublicKey = staticPublicKey; + this.ephemeralPublicKey = ephemeralPublicKey; + } + + public virtual ECPublicKeyParameters StaticPublicKey + { + get { return staticPublicKey; } + } + + public virtual ECPublicKeyParameters EphemeralPublicKey + { + get { return ephemeralPublicKey; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/MqvPublicParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/MqvPublicParameters.cs.meta new file mode 100644 index 0000000..f4873aa --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/MqvPublicParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fab90af5da9a05342a58309d13d45376 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/NaccacheSternKeyGenerationParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/NaccacheSternKeyGenerationParameters.cs new file mode 100644 index 0000000..44fc906 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/NaccacheSternKeyGenerationParameters.cs @@ -0,0 +1,98 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + /** + * Parameters for NaccacheStern public private key generation. For details on + * this cipher, please see + * + * http://www.gemplus.com/smart/rd/publications/pdf/NS98pkcs.pdf + */ + public class NaccacheSternKeyGenerationParameters : KeyGenerationParameters + { + // private BigInteger publicExponent; + private readonly int certainty; + private readonly int countSmallPrimes; + + /** + * Parameters for generating a NaccacheStern KeyPair. + * + * @param random + * The source of randomness + * @param strength + * The desired strength of the Key in Bits + * @param certainty + * the probability that the generated primes are not really prime + * as integer: 2^(-certainty) is then the probability + * @param countSmallPrimes + * How many small key factors are desired + */ + public NaccacheSternKeyGenerationParameters( + SecureRandom random, + int strength, + int certainty, + int countSmallPrimes) + : base(random, strength) + { + if (countSmallPrimes % 2 == 1) + throw new ArgumentException("countSmallPrimes must be a multiple of 2"); + if (countSmallPrimes < 30) + throw new ArgumentException("countSmallPrimes must be >= 30 for security reasons"); + + this.certainty = certainty; + this.countSmallPrimes = countSmallPrimes; + } + + /** + * Parameters for a NaccacheStern KeyPair. + * + * @param random + * The source of randomness + * @param strength + * The desired strength of the Key in Bits + * @param certainty + * the probability that the generated primes are not really prime + * as integer: 2^(-certainty) is then the probability + * @param cntSmallPrimes + * How many small key factors are desired + * @param debug + * Ignored + */ + [Obsolete("Use version without 'debug' parameter")] + public NaccacheSternKeyGenerationParameters( + SecureRandom random, + int strength, + int certainty, + int countSmallPrimes, + bool debug) + : this(random, strength, certainty, countSmallPrimes) + { + } + + /** + * @return Returns the certainty. + */ + public int Certainty + { + get { return certainty; } + } + + /** + * @return Returns the countSmallPrimes. + */ + public int CountSmallPrimes + { + get { return countSmallPrimes; } + } + + [Obsolete("Remove: always false")] + public bool IsDebug + { + get { return false; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/NaccacheSternKeyGenerationParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/NaccacheSternKeyGenerationParameters.cs.meta new file mode 100644 index 0000000..717e0da --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/NaccacheSternKeyGenerationParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c1238966f8b23974b83162d0df5f786c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/NaccacheSternKeyParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/NaccacheSternKeyParameters.cs new file mode 100644 index 0000000..8be7ad8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/NaccacheSternKeyParameters.cs @@ -0,0 +1,44 @@ +using System; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + /** + * Public key parameters for NaccacheStern cipher. For details on this cipher, + * please see + * + * http://www.gemplus.com/smart/rd/publications/pdf/NS98pkcs.pdf + */ + public class NaccacheSternKeyParameters : AsymmetricKeyParameter + { + private readonly BigInteger g, n; + private readonly int lowerSigmaBound; + + /** + * @param privateKey + */ + public NaccacheSternKeyParameters(bool privateKey, BigInteger g, BigInteger n, int lowerSigmaBound) + : base(privateKey) + { + this.g = g; + this.n = n; + this.lowerSigmaBound = lowerSigmaBound; + } + + /** + * @return Returns the g. + */ + public BigInteger G { get { return g; } } + + /** + * @return Returns the lowerSigmaBound. + */ + public int LowerSigmaBound { get { return lowerSigmaBound; } } + + /** + * @return Returns the n. + */ + public BigInteger Modulus { get { return n; } } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/NaccacheSternKeyParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/NaccacheSternKeyParameters.cs.meta new file mode 100644 index 0000000..caf08bc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/NaccacheSternKeyParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: db409e5c7712ed7498d1799bb24b1584 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/NaccacheSternPrivateKeyParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/NaccacheSternPrivateKeyParameters.cs new file mode 100644 index 0000000..42a0454 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/NaccacheSternPrivateKeyParameters.cs @@ -0,0 +1,79 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + /** + * Private key parameters for NaccacheStern cipher. For details on this cipher, + * please see + * + * http://www.gemplus.com/smart/rd/publications/pdf/NS98pkcs.pdf + */ + public class NaccacheSternPrivateKeyParameters : NaccacheSternKeyParameters + { + private readonly BigInteger phiN; + private readonly IList smallPrimes; + +#if !(SILVERLIGHT || PORTABLE) + [Obsolete] + public NaccacheSternPrivateKeyParameters( + BigInteger g, + BigInteger n, + int lowerSigmaBound, + ArrayList smallPrimes, + BigInteger phiN) + : base(true, g, n, lowerSigmaBound) + { + this.smallPrimes = smallPrimes; + this.phiN = phiN; + } +#endif + + /** + * Constructs a NaccacheSternPrivateKey + * + * @param g + * the public enryption parameter g + * @param n + * the public modulus n = p*q + * @param lowerSigmaBound + * the public lower sigma bound up to which data can be encrypted + * @param smallPrimes + * the small primes, of which sigma is constructed in the right + * order + * @param phi_n + * the private modulus phi(n) = (p-1)(q-1) + */ + public NaccacheSternPrivateKeyParameters( + BigInteger g, + BigInteger n, + int lowerSigmaBound, + IList smallPrimes, + BigInteger phiN) + : base(true, g, n, lowerSigmaBound) + { + this.smallPrimes = smallPrimes; + this.phiN = phiN; + } + + public BigInteger PhiN + { + get { return phiN; } + } + +#if !(SILVERLIGHT || PORTABLE) + [Obsolete("Use 'SmallPrimesList' instead")] + public ArrayList SmallPrimes + { + get { return new ArrayList(smallPrimes); } + } +#endif + + public IList SmallPrimesList + { + get { return smallPrimes; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/NaccacheSternPrivateKeyParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/NaccacheSternPrivateKeyParameters.cs.meta new file mode 100644 index 0000000..9b8e3a2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/NaccacheSternPrivateKeyParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5d000d79a56235444a0ad827183d8bdb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ParametersWithID.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ParametersWithID.cs new file mode 100644 index 0000000..37f6870 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ParametersWithID.cs @@ -0,0 +1,36 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class ParametersWithID + : ICipherParameters + { + private readonly ICipherParameters parameters; + private readonly byte[] id; + + public ParametersWithID(ICipherParameters parameters, + byte[] id) + : this(parameters, id, 0, id.Length) + { + } + + public ParametersWithID(ICipherParameters parameters, + byte[] id, int idOff, int idLen) + { + this.parameters = parameters; + this.id = Arrays.CopyOfRange(id, idOff, idOff + idLen); + } + + public byte[] GetID() + { + return id; + } + + public ICipherParameters Parameters + { + get { return parameters; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ParametersWithID.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ParametersWithID.cs.meta new file mode 100644 index 0000000..bfbdb50 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ParametersWithID.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e7b0e2405790a864c82a5ecec7c9e825 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ParametersWithIV.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ParametersWithIV.cs new file mode 100644 index 0000000..4b2eb93 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ParametersWithIV.cs @@ -0,0 +1,40 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class ParametersWithIV + : ICipherParameters + { + private readonly ICipherParameters parameters; + private readonly byte[] iv; + + public ParametersWithIV(ICipherParameters parameters, + byte[] iv) + : this(parameters, iv, 0, iv.Length) + { + } + + public ParametersWithIV(ICipherParameters parameters, + byte[] iv, int ivOff, int ivLen) + { + // NOTE: 'parameters' may be null to imply key re-use + if (iv == null) + throw new ArgumentNullException("iv"); + + this.parameters = parameters; + this.iv = Arrays.CopyOfRange(iv, ivOff, ivOff + ivLen); + } + + public byte[] GetIV() + { + return (byte[])iv.Clone(); + } + + public ICipherParameters Parameters + { + get { return parameters; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ParametersWithIV.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ParametersWithIV.cs.meta new file mode 100644 index 0000000..b961a56 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ParametersWithIV.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c3e3c4349d8c6104686d14e8c071f1b7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ParametersWithRandom.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ParametersWithRandom.cs new file mode 100644 index 0000000..276dc26 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ParametersWithRandom.cs @@ -0,0 +1,48 @@ +using System; + +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class ParametersWithRandom + : ICipherParameters + { + private readonly ICipherParameters parameters; + private readonly SecureRandom random; + + public ParametersWithRandom( + ICipherParameters parameters, + SecureRandom random) + { + if (parameters == null) + throw new ArgumentNullException("parameters"); + if (random == null) + throw new ArgumentNullException("random"); + + this.parameters = parameters; + this.random = random; + } + + public ParametersWithRandom( + ICipherParameters parameters) + : this(parameters, new SecureRandom()) + { + } + + [Obsolete("Use Random property instead")] + public SecureRandom GetRandom() + { + return Random; + } + + public SecureRandom Random + { + get { return random; } + } + + public ICipherParameters Parameters + { + get { return parameters; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ParametersWithRandom.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ParametersWithRandom.cs.meta new file mode 100644 index 0000000..593c510 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ParametersWithRandom.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d75f7dc4796bc47478e2416196e88607 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ParametersWithSBox.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ParametersWithSBox.cs new file mode 100644 index 0000000..6473796 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ParametersWithSBox.cs @@ -0,0 +1,24 @@ +using System; + +using Org.BouncyCastle.Crypto; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class ParametersWithSBox : ICipherParameters + { + private ICipherParameters parameters; + private byte[] sBox; + + public ParametersWithSBox( + ICipherParameters parameters, + byte[] sBox) + { + this.parameters = parameters; + this.sBox = sBox; + } + + public byte[] GetSBox() { return sBox; } + + public ICipherParameters Parameters { get { return parameters; } } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ParametersWithSBox.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ParametersWithSBox.cs.meta new file mode 100644 index 0000000..4a7b786 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ParametersWithSBox.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cda7fdb250421dd4bbd886f955fdf6c6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ParametersWithSalt.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ParametersWithSalt.cs new file mode 100644 index 0000000..7f4cd6c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ParametersWithSalt.cs @@ -0,0 +1,39 @@ +using System; + +using Org.BouncyCastle.Crypto; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + + /// Cipher parameters with a fixed salt value associated with them. + public class ParametersWithSalt : ICipherParameters + { + private byte[] salt; + private ICipherParameters parameters; + + public ParametersWithSalt(ICipherParameters parameters, byte[] salt):this(parameters, salt, 0, salt.Length) + { + } + + public ParametersWithSalt(ICipherParameters parameters, byte[] salt, int saltOff, int saltLen) + { + this.salt = new byte[saltLen]; + this.parameters = parameters; + + Array.Copy(salt, saltOff, this.salt, 0, saltLen); + } + + public byte[] GetSalt() + { + return salt; + } + + public ICipherParameters Parameters + { + get + { + return parameters; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ParametersWithSalt.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ParametersWithSalt.cs.meta new file mode 100644 index 0000000..bae0d0d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/ParametersWithSalt.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f9a353c7c7a50fe4da823a58803cf5b9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/RC2Parameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/RC2Parameters.cs new file mode 100644 index 0000000..7a6d5bb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/RC2Parameters.cs @@ -0,0 +1,47 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class RC2Parameters + : KeyParameter + { + private readonly int bits; + + public RC2Parameters( + byte[] key) + : this(key, (key.Length > 128) ? 1024 : (key.Length * 8)) + { + } + + public RC2Parameters( + byte[] key, + int keyOff, + int keyLen) + : this(key, keyOff, keyLen, (keyLen > 128) ? 1024 : (keyLen * 8)) + { + } + + public RC2Parameters( + byte[] key, + int bits) + : base(key) + { + this.bits = bits; + } + + public RC2Parameters( + byte[] key, + int keyOff, + int keyLen, + int bits) + : base(key, keyOff, keyLen) + { + this.bits = bits; + } + + public int EffectiveKeyBits + { + get { return bits; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/RC2Parameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/RC2Parameters.cs.meta new file mode 100644 index 0000000..f9f329c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/RC2Parameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 80ed7bcc3e3d2a446a283872b37e92b0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/RC5Parameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/RC5Parameters.cs new file mode 100644 index 0000000..88a59e1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/RC5Parameters.cs @@ -0,0 +1,27 @@ +using System; +using Org.BouncyCastle.Crypto; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class RC5Parameters + : KeyParameter + { + private readonly int rounds; + + public RC5Parameters( + byte[] key, + int rounds) + : base(key) + { + if (key.Length > 255) + throw new ArgumentException("RC5 key length can be no greater than 255"); + + this.rounds = rounds; + } + + public int Rounds + { + get { return rounds; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/RC5Parameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/RC5Parameters.cs.meta new file mode 100644 index 0000000..be8a726 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/RC5Parameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a9fbcf9f21532444aa67b19e4ac2e771 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/RSABlindingParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/RSABlindingParameters.cs new file mode 100644 index 0000000..49c7bcc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/RSABlindingParameters.cs @@ -0,0 +1,34 @@ +using System; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class RsaBlindingParameters + : ICipherParameters + { + private readonly RsaKeyParameters publicKey; + private readonly BigInteger blindingFactor; + + public RsaBlindingParameters( + RsaKeyParameters publicKey, + BigInteger blindingFactor) + { + if (publicKey.IsPrivate) + throw new ArgumentException("RSA parameters should be for a public key"); + + this.publicKey = publicKey; + this.blindingFactor = blindingFactor; + } + + public RsaKeyParameters PublicKey + { + get { return publicKey; } + } + + public BigInteger BlindingFactor + { + get { return blindingFactor; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/RSABlindingParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/RSABlindingParameters.cs.meta new file mode 100644 index 0000000..8a889d9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/RSABlindingParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 13c4b75ce7d5e4b41920e8ec0aa7d794 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/RsaKeyGenerationParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/RsaKeyGenerationParameters.cs new file mode 100644 index 0000000..619ab65 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/RsaKeyGenerationParameters.cs @@ -0,0 +1,55 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class RsaKeyGenerationParameters + : KeyGenerationParameters + { + private readonly BigInteger publicExponent; + private readonly int certainty; + + public RsaKeyGenerationParameters( + BigInteger publicExponent, + SecureRandom random, + int strength, + int certainty) + : base(random, strength) + { + this.publicExponent = publicExponent; + this.certainty = certainty; + } + + public BigInteger PublicExponent + { + get { return publicExponent; } + } + + public int Certainty + { + get { return certainty; } + } + + public override bool Equals( + object obj) + { + RsaKeyGenerationParameters other = obj as RsaKeyGenerationParameters; + + if (other == null) + { + return false; + } + + return certainty == other.certainty + && publicExponent.Equals(other.publicExponent); + } + + public override int GetHashCode() + { + return certainty.GetHashCode() ^ publicExponent.GetHashCode(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/RsaKeyGenerationParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/RsaKeyGenerationParameters.cs.meta new file mode 100644 index 0000000..dbec57b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/RsaKeyGenerationParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2cc6437da58d49c49ad7d8086893f6bb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/RsaKeyParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/RsaKeyParameters.cs new file mode 100644 index 0000000..48ea0ab --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/RsaKeyParameters.cs @@ -0,0 +1,85 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class RsaKeyParameters + : AsymmetricKeyParameter + { + // Hexadecimal value of the product of the 131 smallest odd primes from 3 to 743 + private static readonly BigInteger SmallPrimesProduct = new BigInteger( + "8138e8a0fcf3a4e84a771d40fd305d7f4aa59306d7251de54d98af8fe95729a1f" + + "73d893fa424cd2edc8636a6c3285e022b0e3866a565ae8108eed8591cd4fe8d2" + + "ce86165a978d719ebf647f362d33fca29cd179fb42401cbaf3df0c614056f9c8" + + "f3cfd51e474afb6bc6974f78db8aba8e9e517fded658591ab7502bd41849462f", + 16); + + private static BigInteger Validate(BigInteger modulus) + { + if ((modulus.IntValue & 1) == 0) + throw new ArgumentException("RSA modulus is even", "modulus"); + if (!modulus.Gcd(SmallPrimesProduct).Equals(BigInteger.One)) + throw new ArgumentException("RSA modulus has a small prime factor"); + + // TODO: add additional primePower/Composite test - expensive!! + + return modulus; + } + + private readonly BigInteger modulus; + private readonly BigInteger exponent; + + public RsaKeyParameters( + bool isPrivate, + BigInteger modulus, + BigInteger exponent) + : base(isPrivate) + { + if (modulus == null) + throw new ArgumentNullException("modulus"); + if (exponent == null) + throw new ArgumentNullException("exponent"); + if (modulus.SignValue <= 0) + throw new ArgumentException("Not a valid RSA modulus", "modulus"); + if (exponent.SignValue <= 0) + throw new ArgumentException("Not a valid RSA exponent", "exponent"); + if (!isPrivate && (exponent.IntValue & 1) == 0) + throw new ArgumentException("RSA publicExponent is even", "exponent"); + + this.modulus = Validate(modulus); + this.exponent = exponent; + } + + public BigInteger Modulus + { + get { return modulus; } + } + + public BigInteger Exponent + { + get { return exponent; } + } + + public override bool Equals( + object obj) + { + RsaKeyParameters kp = obj as RsaKeyParameters; + + if (kp == null) + { + return false; + } + + return kp.IsPrivate == this.IsPrivate + && kp.Modulus.Equals(this.modulus) + && kp.Exponent.Equals(this.exponent); + } + + public override int GetHashCode() + { + return modulus.GetHashCode() ^ exponent.GetHashCode() ^ IsPrivate.GetHashCode(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/RsaKeyParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/RsaKeyParameters.cs.meta new file mode 100644 index 0000000..0a85e66 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/RsaKeyParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 83de5f57722500d4baca1332e8a08447 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/RsaPrivateCrtKeyParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/RsaPrivateCrtKeyParameters.cs new file mode 100644 index 0000000..557ee94 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/RsaPrivateCrtKeyParameters.cs @@ -0,0 +1,118 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Asn1.Pkcs; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class RsaPrivateCrtKeyParameters + : RsaKeyParameters + { + private readonly BigInteger e, p, q, dP, dQ, qInv; + + public RsaPrivateCrtKeyParameters( + BigInteger modulus, + BigInteger publicExponent, + BigInteger privateExponent, + BigInteger p, + BigInteger q, + BigInteger dP, + BigInteger dQ, + BigInteger qInv) + : base(true, modulus, privateExponent) + { + ValidateValue(publicExponent, "publicExponent", "exponent"); + ValidateValue(p, "p", "P value"); + ValidateValue(q, "q", "Q value"); + ValidateValue(dP, "dP", "DP value"); + ValidateValue(dQ, "dQ", "DQ value"); + ValidateValue(qInv, "qInv", "InverseQ value"); + + this.e = publicExponent; + this.p = p; + this.q = q; + this.dP = dP; + this.dQ = dQ; + this.qInv = qInv; + } + + public RsaPrivateCrtKeyParameters(RsaPrivateKeyStructure rsaPrivateKey) + : this( + rsaPrivateKey.Modulus, + rsaPrivateKey.PublicExponent, + rsaPrivateKey.PrivateExponent, + rsaPrivateKey.Prime1, + rsaPrivateKey.Prime2, + rsaPrivateKey.Exponent1, + rsaPrivateKey.Exponent2, + rsaPrivateKey.Coefficient) + { + } + + public BigInteger PublicExponent + { + get { return e; } + } + + public BigInteger P + { + get { return p; } + } + + public BigInteger Q + { + get { return q; } + } + + public BigInteger DP + { + get { return dP; } + } + + public BigInteger DQ + { + get { return dQ; } + } + + public BigInteger QInv + { + get { return qInv; } + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + RsaPrivateCrtKeyParameters kp = obj as RsaPrivateCrtKeyParameters; + + if (kp == null) + return false; + + return kp.DP.Equals(dP) + && kp.DQ.Equals(dQ) + && kp.Exponent.Equals(this.Exponent) + && kp.Modulus.Equals(this.Modulus) + && kp.P.Equals(p) + && kp.Q.Equals(q) + && kp.PublicExponent.Equals(e) + && kp.QInv.Equals(qInv); + } + + public override int GetHashCode() + { + return DP.GetHashCode() ^ DQ.GetHashCode() ^ Exponent.GetHashCode() ^ Modulus.GetHashCode() + ^ P.GetHashCode() ^ Q.GetHashCode() ^ PublicExponent.GetHashCode() ^ QInv.GetHashCode(); + } + + private static void ValidateValue(BigInteger x, string name, string desc) + { + if (x == null) + throw new ArgumentNullException(name); + if (x.SignValue <= 0) + throw new ArgumentException("Not a valid RSA " + desc, name); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/RsaPrivateCrtKeyParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/RsaPrivateCrtKeyParameters.cs.meta new file mode 100644 index 0000000..d893119 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/RsaPrivateCrtKeyParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 245c08cc58dec8840a0e451807b31133 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/SM2KeyExchangePrivateParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/SM2KeyExchangePrivateParameters.cs new file mode 100644 index 0000000..6665664 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/SM2KeyExchangePrivateParameters.cs @@ -0,0 +1,67 @@ +using System; + +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Math.EC.Multiplier; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + /// Private parameters for an SM2 key exchange. + /// The ephemeralPrivateKey is used to calculate the random point used in the algorithm. + public class SM2KeyExchangePrivateParameters + : ICipherParameters + { + private readonly bool mInitiator; + private readonly ECPrivateKeyParameters mStaticPrivateKey; + private readonly ECPoint mStaticPublicPoint; + private readonly ECPrivateKeyParameters mEphemeralPrivateKey; + private readonly ECPoint mEphemeralPublicPoint; + + public SM2KeyExchangePrivateParameters( + bool initiator, + ECPrivateKeyParameters staticPrivateKey, + ECPrivateKeyParameters ephemeralPrivateKey) + { + if (staticPrivateKey == null) + throw new ArgumentNullException("staticPrivateKey"); + if (ephemeralPrivateKey == null) + throw new ArgumentNullException("ephemeralPrivateKey"); + + ECDomainParameters parameters = staticPrivateKey.Parameters; + if (!parameters.Equals(ephemeralPrivateKey.Parameters)) + throw new ArgumentException("Static and ephemeral private keys have different domain parameters"); + + ECMultiplier m = new FixedPointCombMultiplier(); + + this.mInitiator = initiator; + this.mStaticPrivateKey = staticPrivateKey; + this.mStaticPublicPoint = m.Multiply(parameters.G, staticPrivateKey.D).Normalize(); + this.mEphemeralPrivateKey = ephemeralPrivateKey; + this.mEphemeralPublicPoint = m.Multiply(parameters.G, ephemeralPrivateKey.D).Normalize(); + } + + public virtual bool IsInitiator + { + get { return mInitiator; } + } + + public virtual ECPrivateKeyParameters StaticPrivateKey + { + get { return mStaticPrivateKey; } + } + + public virtual ECPoint StaticPublicPoint + { + get { return mStaticPublicPoint; } + } + + public virtual ECPrivateKeyParameters EphemeralPrivateKey + { + get { return mEphemeralPrivateKey; } + } + + public virtual ECPoint EphemeralPublicPoint + { + get { return mEphemeralPublicPoint; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/SM2KeyExchangePrivateParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/SM2KeyExchangePrivateParameters.cs.meta new file mode 100644 index 0000000..e07c684 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/SM2KeyExchangePrivateParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6a1e82e479155204fafea5c88aaf1abc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/SM2KeyExchangePublicParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/SM2KeyExchangePublicParameters.cs new file mode 100644 index 0000000..5c21315 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/SM2KeyExchangePublicParameters.cs @@ -0,0 +1,40 @@ +using System; + +using Org.BouncyCastle.Math.EC; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + /// Public parameters for an SM2 key exchange. + /// In this case the ephemeralPublicKey provides the random point used in the algorithm. + public class SM2KeyExchangePublicParameters + : ICipherParameters + { + private readonly ECPublicKeyParameters mStaticPublicKey; + private readonly ECPublicKeyParameters mEphemeralPublicKey; + + public SM2KeyExchangePublicParameters( + ECPublicKeyParameters staticPublicKey, + ECPublicKeyParameters ephemeralPublicKey) + { + if (staticPublicKey == null) + throw new ArgumentNullException("staticPublicKey"); + if (ephemeralPublicKey == null) + throw new ArgumentNullException("ephemeralPublicKey"); + if (!staticPublicKey.Parameters.Equals(ephemeralPublicKey.Parameters)) + throw new ArgumentException("Static and ephemeral public keys have different domain parameters"); + + this.mStaticPublicKey = staticPublicKey; + this.mEphemeralPublicKey = ephemeralPublicKey; + } + + public virtual ECPublicKeyParameters StaticPublicKey + { + get { return mStaticPublicKey; } + } + + public virtual ECPublicKeyParameters EphemeralPublicKey + { + get { return mEphemeralPublicKey; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/SM2KeyExchangePublicParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/SM2KeyExchangePublicParameters.cs.meta new file mode 100644 index 0000000..90fafc7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/SM2KeyExchangePublicParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dd84f6b7de8296e48b72df0b1436ad43 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/SkeinParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/SkeinParameters.cs new file mode 100644 index 0000000..cc57ef5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/SkeinParameters.cs @@ -0,0 +1,286 @@ +using System; +using System.Collections; +using System.Globalization; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + + /// + /// Parameters for the Skein hash function - a series of byte[] strings identified by integer tags. + /// + /// + /// Parameterised Skein can be used for: + ///
    + ///
  • MAC generation, by providing a key.
  • + ///
  • Randomised hashing, by providing a nonce.
  • + ///
  • A hash function for digital signatures, associating a + /// public key with the message digest.
  • + ///
  • A key derivation function, by providing a + /// key identifier.
  • + ///
  • Personalised hashing, by providing a + /// recommended format or + /// arbitrary personalisation string.
  • + ///
+ ///
+ /// + /// + /// + public class SkeinParameters + : ICipherParameters + { + /// + /// The parameter type for a secret key, supporting MAC or KDF functions: 0 + /// + public const int PARAM_TYPE_KEY = 0; + + /// + /// The parameter type for the Skein configuration block: 4 + /// + public const int PARAM_TYPE_CONFIG = 4; + + /// + /// The parameter type for a personalisation string: 8 + /// + public const int PARAM_TYPE_PERSONALISATION = 8; + + /// + /// The parameter type for a public key: 12 + /// + public const int PARAM_TYPE_PUBLIC_KEY = 12; + + /// + /// The parameter type for a key identifier string: 16 + /// + public const int PARAM_TYPE_KEY_IDENTIFIER = 16; + + /// + /// The parameter type for a nonce: 20 + /// + public const int PARAM_TYPE_NONCE = 20; + + /// + /// The parameter type for the message: 48 + /// + public const int PARAM_TYPE_MESSAGE = 48; + + /// + /// The parameter type for the output transformation: 63 + /// + public const int PARAM_TYPE_OUTPUT = 63; + + private IDictionary parameters; + + public SkeinParameters() + : this(Platform.CreateHashtable()) + + { + } + + private SkeinParameters(IDictionary parameters) + { + this.parameters = parameters; + } + + /// + /// Obtains a map of type (int) to value (byte[]) for the parameters tracked in this object. + /// + public IDictionary GetParameters() + { + return parameters; + } + + /// + /// Obtains the value of the key parameter, or null if not + /// set. + /// + /// The key. + public byte[] GetKey() + { + return (byte[])parameters[PARAM_TYPE_KEY]; + } + + /// + /// Obtains the value of the personalisation parameter, or + /// null if not set. + /// + public byte[] GetPersonalisation() + { + return (byte[])parameters[PARAM_TYPE_PERSONALISATION]; + } + + /// + /// Obtains the value of the public key parameter, or + /// null if not set. + /// + public byte[] GetPublicKey() + { + return (byte[])parameters[PARAM_TYPE_PUBLIC_KEY]; + } + + /// + /// Obtains the value of the key identifier parameter, or + /// null if not set. + /// + public byte[] GetKeyIdentifier() + { + return (byte[])parameters[PARAM_TYPE_KEY_IDENTIFIER]; + } + + /// + /// Obtains the value of the nonce parameter, or null if + /// not set. + /// + public byte[] GetNonce() + { + return (byte[])parameters[PARAM_TYPE_NONCE]; + } + + /// + /// A builder for . + /// + public class Builder + { + private IDictionary parameters = Platform.CreateHashtable(); + + public Builder() + { + } + + public Builder(IDictionary paramsMap) + { + IEnumerator keys = paramsMap.Keys.GetEnumerator(); + while (keys.MoveNext()) + { + int key = (int)keys.Current; + parameters.Add(key, paramsMap[key]); + } + } + + public Builder(SkeinParameters parameters) + { + IEnumerator keys = parameters.parameters.Keys.GetEnumerator(); + while (keys.MoveNext()) + { + int key = (int)keys.Current; + this.parameters.Add(key, parameters.parameters[key]); + } + } + + /// + /// Sets a parameters to apply to the Skein hash function. + /// + /// + /// Parameter types must be in the range 0,5..62, and cannot use the value 48 + /// (reserved for message body). + ///

+ /// Parameters with type < 48 are processed before + /// the message content, parameters with type > 48 + /// are processed after the message and prior to output. + /// + /// the type of the parameter, in the range 5..62. + /// the byte sequence of the parameter. + public Builder Set(int type, byte[] value) + { + if (value == null) + { + throw new ArgumentException("Parameter value must not be null."); + } + if ((type != PARAM_TYPE_KEY) + && (type <= PARAM_TYPE_CONFIG || type >= PARAM_TYPE_OUTPUT || type == PARAM_TYPE_MESSAGE)) + { + throw new ArgumentException("Parameter types must be in the range 0,5..47,49..62."); + } + if (type == PARAM_TYPE_CONFIG) + { + throw new ArgumentException("Parameter type " + PARAM_TYPE_CONFIG + + " is reserved for internal use."); + } + this.parameters.Add(type, value); + return this; + } + + ///

+ /// Sets the parameter. + /// + public Builder SetKey(byte[] key) + { + return Set(PARAM_TYPE_KEY, key); + } + + /// + /// Sets the parameter. + /// + public Builder SetPersonalisation(byte[] personalisation) + { + return Set(PARAM_TYPE_PERSONALISATION, personalisation); + } + + /// + /// Implements the recommended personalisation format for Skein defined in Section 4.11 of + /// the Skein 1.3 specification. + /// + /// + /// The format is YYYYMMDD email@address distinguisher, encoded to a byte + /// sequence using UTF-8 encoding. + /// + /// the date the personalised application of the Skein was defined. + /// the email address of the creation of the personalised application. + /// an arbitrary personalisation string distinguishing the application. + public Builder SetPersonalisation(DateTime date, string emailAddress, string distinguisher) + { + try + { + MemoryStream bout = new MemoryStream(); + StreamWriter outBytes = new StreamWriter(bout, System.Text.Encoding.UTF8); + outBytes.Write(date.ToString("YYYYMMDD", CultureInfo.InvariantCulture)); + outBytes.Write(" "); + outBytes.Write(emailAddress); + outBytes.Write(" "); + outBytes.Write(distinguisher); + Platform.Dispose(outBytes); + return Set(PARAM_TYPE_PERSONALISATION, bout.ToArray()); + } + catch (IOException e) + { + throw new InvalidOperationException("Byte I/O failed.", e); + } + } + + /// + /// Sets the parameter. + /// + public Builder SetPublicKey(byte[] publicKey) + { + return Set(PARAM_TYPE_PUBLIC_KEY, publicKey); + } + + /// + /// Sets the parameter. + /// + public Builder SetKeyIdentifier(byte[] keyIdentifier) + { + return Set(PARAM_TYPE_KEY_IDENTIFIER, keyIdentifier); + } + + /// + /// Sets the parameter. + /// + public Builder SetNonce(byte[] nonce) + { + return Set(PARAM_TYPE_NONCE, nonce); + } + + /// + /// Constructs a new instance with the parameters provided to this + /// builder. + /// + public SkeinParameters Build() + { + return new SkeinParameters(parameters); + } + } + } +} \ No newline at end of file diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/SkeinParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/SkeinParameters.cs.meta new file mode 100644 index 0000000..5c250e6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/SkeinParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 246a72330c748564c9630f47bf5831ea +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/Srp6GroupParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/Srp6GroupParameters.cs new file mode 100644 index 0000000..6762dd3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/Srp6GroupParameters.cs @@ -0,0 +1,27 @@ +using System; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public sealed class Srp6GroupParameters + { + private readonly BigInteger n, g; + + public Srp6GroupParameters(BigInteger N, BigInteger g) + { + this.n = N; + this.g = g; + } + + public BigInteger G + { + get { return g; } + } + + public BigInteger N + { + get { return n; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/Srp6GroupParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/Srp6GroupParameters.cs.meta new file mode 100644 index 0000000..e2a454b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/Srp6GroupParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 865594eec146df946b77a5bb65827fa0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/TweakableBlockCipherParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/TweakableBlockCipherParameters.cs new file mode 100644 index 0000000..f757266 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/TweakableBlockCipherParameters.cs @@ -0,0 +1,40 @@ +using System; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + + /// + /// Parameters for tweakable block ciphers. + /// + public class TweakableBlockCipherParameters + : ICipherParameters + { + private readonly byte[] tweak; + private readonly KeyParameter key; + + public TweakableBlockCipherParameters(KeyParameter key, byte[] tweak) + { + this.key = key; + this.tweak = Arrays.Clone(tweak); + } + + /// + /// Gets the key. + /// + /// the key to use, or null to use the current key. + public KeyParameter Key + { + get { return key; } + } + + /// + /// Gets the tweak value. + /// + /// The tweak to use, or null to use the current tweak. + public byte[] Tweak + { + get { return tweak; } + } + } +} \ No newline at end of file diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/TweakableBlockCipherParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/TweakableBlockCipherParameters.cs.meta new file mode 100644 index 0000000..cc64f72 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/TweakableBlockCipherParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 605422c9e74547345a48016b1a4d3568 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/X25519KeyGenerationParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/X25519KeyGenerationParameters.cs new file mode 100644 index 0000000..d0bcffa --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/X25519KeyGenerationParameters.cs @@ -0,0 +1,15 @@ +using System; + +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class X25519KeyGenerationParameters + : KeyGenerationParameters + { + public X25519KeyGenerationParameters(SecureRandom random) + : base(random, 255) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/X25519KeyGenerationParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/X25519KeyGenerationParameters.cs.meta new file mode 100644 index 0000000..97bd9f5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/X25519KeyGenerationParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fdd905d720330334d93f9592dafe3342 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/X25519PrivateKeyParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/X25519PrivateKeyParameters.cs new file mode 100644 index 0000000..63e72d3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/X25519PrivateKeyParameters.cs @@ -0,0 +1,76 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Math.EC.Rfc7748; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public sealed class X25519PrivateKeyParameters + : AsymmetricKeyParameter + { + public static readonly int KeySize = X25519.ScalarSize; + public static readonly int SecretSize = X25519.PointSize; + + private readonly byte[] data = new byte[KeySize]; + + public X25519PrivateKeyParameters(SecureRandom random) + : base(true) + { + X25519.GeneratePrivateKey(random, data); + } + + public X25519PrivateKeyParameters(byte[] buf) + : this(Validate(buf), 0) + { + } + + public X25519PrivateKeyParameters(byte[] buf, int off) + : base(true) + { + Array.Copy(buf, off, data, 0, KeySize); + } + + public X25519PrivateKeyParameters(Stream input) + : base(true) + { + if (KeySize != Streams.ReadFully(input, data)) + throw new EndOfStreamException("EOF encountered in middle of X25519 private key"); + } + + public void Encode(byte[] buf, int off) + { + Array.Copy(data, 0, buf, off, KeySize); + } + + public byte[] GetEncoded() + { + return Arrays.Clone(data); + } + + public X25519PublicKeyParameters GeneratePublicKey() + { + byte[] publicKey = new byte[X25519.PointSize]; + X25519.GeneratePublicKey(data, 0, publicKey, 0); + return new X25519PublicKeyParameters(publicKey, 0); + } + + public void GenerateSecret(X25519PublicKeyParameters publicKey, byte[] buf, int off) + { + byte[] encoded = new byte[X25519.PointSize]; + publicKey.Encode(encoded, 0); + if (!X25519.CalculateAgreement(data, 0, encoded, 0, buf, off)) + throw new InvalidOperationException("X25519 agreement failed"); + } + + private static byte[] Validate(byte[] buf) + { + if (buf.Length != KeySize) + throw new ArgumentException("must have length " + KeySize, "buf"); + + return buf; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/X25519PrivateKeyParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/X25519PrivateKeyParameters.cs.meta new file mode 100644 index 0000000..81b3f51 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/X25519PrivateKeyParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 99516d79572b0a8458e0505d79a740db +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/X25519PublicKeyParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/X25519PublicKeyParameters.cs new file mode 100644 index 0000000..c28e4de --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/X25519PublicKeyParameters.cs @@ -0,0 +1,53 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Math.EC.Rfc7748; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public sealed class X25519PublicKeyParameters + : AsymmetricKeyParameter + { + public static readonly int KeySize = X25519.PointSize; + + private readonly byte[] data = new byte[KeySize]; + + public X25519PublicKeyParameters(byte[] buf) + : this(Validate(buf), 0) + { + } + + public X25519PublicKeyParameters(byte[] buf, int off) + : base(false) + { + Array.Copy(buf, off, data, 0, KeySize); + } + + public X25519PublicKeyParameters(Stream input) + : base(false) + { + if (KeySize != Streams.ReadFully(input, data)) + throw new EndOfStreamException("EOF encountered in middle of X25519 public key"); + } + + public void Encode(byte[] buf, int off) + { + Array.Copy(data, 0, buf, off, KeySize); + } + + public byte[] GetEncoded() + { + return Arrays.Clone(data); + } + + private static byte[] Validate(byte[] buf) + { + if (buf.Length != KeySize) + throw new ArgumentException("must have length " + KeySize, "buf"); + + return buf; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/X25519PublicKeyParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/X25519PublicKeyParameters.cs.meta new file mode 100644 index 0000000..84a48db --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/X25519PublicKeyParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0f018e7c9608bb34495b56ebf0458a65 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/X448KeyGenerationParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/X448KeyGenerationParameters.cs new file mode 100644 index 0000000..a7cb558 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/X448KeyGenerationParameters.cs @@ -0,0 +1,15 @@ +using System; + +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class X448KeyGenerationParameters + : KeyGenerationParameters + { + public X448KeyGenerationParameters(SecureRandom random) + : base(random, 448) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/X448KeyGenerationParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/X448KeyGenerationParameters.cs.meta new file mode 100644 index 0000000..8758733 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/X448KeyGenerationParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b192c514c0cd44244b95c870172a47ca +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/X448PrivateKeyParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/X448PrivateKeyParameters.cs new file mode 100644 index 0000000..d10a903 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/X448PrivateKeyParameters.cs @@ -0,0 +1,76 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Math.EC.Rfc7748; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public sealed class X448PrivateKeyParameters + : AsymmetricKeyParameter + { + public static readonly int KeySize = X448.ScalarSize; + public static readonly int SecretSize = X448.PointSize; + + private readonly byte[] data = new byte[KeySize]; + + public X448PrivateKeyParameters(SecureRandom random) + : base(true) + { + X448.GeneratePrivateKey(random, data); + } + + public X448PrivateKeyParameters(byte[] buf) + : this(Validate(buf), 0) + { + } + + public X448PrivateKeyParameters(byte[] buf, int off) + : base(true) + { + Array.Copy(buf, off, data, 0, KeySize); + } + + public X448PrivateKeyParameters(Stream input) + : base(true) + { + if (KeySize != Streams.ReadFully(input, data)) + throw new EndOfStreamException("EOF encountered in middle of X448 private key"); + } + + public void Encode(byte[] buf, int off) + { + Array.Copy(data, 0, buf, off, KeySize); + } + + public byte[] GetEncoded() + { + return Arrays.Clone(data); + } + + public X448PublicKeyParameters GeneratePublicKey() + { + byte[] publicKey = new byte[X448.PointSize]; + X448.GeneratePublicKey(data, 0, publicKey, 0); + return new X448PublicKeyParameters(publicKey, 0); + } + + public void GenerateSecret(X448PublicKeyParameters publicKey, byte[] buf, int off) + { + byte[] encoded = new byte[X448.PointSize]; + publicKey.Encode(encoded, 0); + if (!X448.CalculateAgreement(data, 0, encoded, 0, buf, off)) + throw new InvalidOperationException("X448 agreement failed"); + } + + private static byte[] Validate(byte[] buf) + { + if (buf.Length != KeySize) + throw new ArgumentException("must have length " + KeySize, "buf"); + + return buf; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/X448PrivateKeyParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/X448PrivateKeyParameters.cs.meta new file mode 100644 index 0000000..911cc5a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/X448PrivateKeyParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bd7f8aca4ac7ee14b8c1d7caa10233f3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/X448PublicKeyParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/X448PublicKeyParameters.cs new file mode 100644 index 0000000..704d2f7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/X448PublicKeyParameters.cs @@ -0,0 +1,53 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Math.EC.Rfc7748; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public sealed class X448PublicKeyParameters + : AsymmetricKeyParameter + { + public static readonly int KeySize = X448.PointSize; + + private readonly byte[] data = new byte[KeySize]; + + public X448PublicKeyParameters(byte[] buf) + : this(Validate(buf), 0) + { + } + + public X448PublicKeyParameters(byte[] buf, int off) + : base(false) + { + Array.Copy(buf, off, data, 0, KeySize); + } + + public X448PublicKeyParameters(Stream input) + : base(false) + { + if (KeySize != Streams.ReadFully(input, data)) + throw new EndOfStreamException("EOF encountered in middle of X448 public key"); + } + + public void Encode(byte[] buf, int off) + { + Array.Copy(data, 0, buf, off, KeySize); + } + + public byte[] GetEncoded() + { + return Arrays.Clone(data); + } + + private static byte[] Validate(byte[] buf) + { + if (buf.Length != KeySize) + throw new ArgumentException("must have length " + KeySize, "buf"); + + return buf; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/X448PublicKeyParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/X448PublicKeyParameters.cs.meta new file mode 100644 index 0000000..e6f6abb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/parameters/X448PublicKeyParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 64e014b7429da3646b1b7860a4f0ec20 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng.meta new file mode 100644 index 0000000..9b57182 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 30d5cccf7a34fd34e9d5956757566c1d +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/BasicEntropySourceProvider.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/BasicEntropySourceProvider.cs new file mode 100644 index 0000000..31a8461 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/BasicEntropySourceProvider.cs @@ -0,0 +1,71 @@ +using System; + +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Prng +{ + /** + * An EntropySourceProvider where entropy generation is based on a SecureRandom output using SecureRandom.generateSeed(). + */ + public class BasicEntropySourceProvider + : IEntropySourceProvider + { + private readonly SecureRandom mSecureRandom; + private readonly bool mPredictionResistant; + + /** + * Create a entropy source provider based on the passed in SecureRandom. + * + * @param secureRandom the SecureRandom to base EntropySource construction on. + * @param isPredictionResistant boolean indicating if the SecureRandom is based on prediction resistant entropy or not (true if it is). + */ + public BasicEntropySourceProvider(SecureRandom secureRandom, bool isPredictionResistant) + { + mSecureRandom = secureRandom; + mPredictionResistant = isPredictionResistant; + } + + /** + * Return an entropy source that will create bitsRequired bits of entropy on + * each invocation of getEntropy(). + * + * @param bitsRequired size (in bits) of entropy to be created by the provided source. + * @return an EntropySource that generates bitsRequired bits of entropy on each call to its getEntropy() method. + */ + public IEntropySource Get(int bitsRequired) + { + return new BasicEntropySource(mSecureRandom, mPredictionResistant, bitsRequired); + } + + private class BasicEntropySource + : IEntropySource + { + private readonly SecureRandom mSecureRandom; + private readonly bool mPredictionResistant; + private readonly int mEntropySize; + + internal BasicEntropySource(SecureRandom secureRandom, bool predictionResistant, int entropySize) + { + this.mSecureRandom = secureRandom; + this.mPredictionResistant = predictionResistant; + this.mEntropySize = entropySize; + } + + bool IEntropySource.IsPredictionResistant + { + get { return mPredictionResistant; } + } + + byte[] IEntropySource.GetEntropy() + { + // TODO[FIPS] Not all SecureRandom implementations are considered valid entropy sources + return SecureRandom.GetNextBytes(mSecureRandom, (mEntropySize + 7) / 8); + } + + int IEntropySource.EntropySize + { + get { return mEntropySize; } + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/BasicEntropySourceProvider.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/BasicEntropySourceProvider.cs.meta new file mode 100644 index 0000000..9e85e62 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/BasicEntropySourceProvider.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2c4f523b0ff10364f9be4ca8ecf5f547 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/CryptoApiEntropySourceProvider.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/CryptoApiEntropySourceProvider.cs new file mode 100644 index 0000000..459d3a7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/CryptoApiEntropySourceProvider.cs @@ -0,0 +1,70 @@ +#if !(NETCF_1_0 || PORTABLE) +using System; +using System.Security.Cryptography; + +namespace Org.BouncyCastle.Crypto.Prng +{ + public class CryptoApiEntropySourceProvider + : IEntropySourceProvider + { + private readonly RandomNumberGenerator mRng; + private readonly bool mPredictionResistant; + + public CryptoApiEntropySourceProvider() + : this(RandomNumberGenerator.Create(), true) + { + } + + public CryptoApiEntropySourceProvider(RandomNumberGenerator rng, bool isPredictionResistant) + { + if (rng == null) + throw new ArgumentNullException("rng"); + + mRng = rng; + mPredictionResistant = isPredictionResistant; + } + + public IEntropySource Get(int bitsRequired) + { + return new CryptoApiEntropySource(mRng, mPredictionResistant, bitsRequired); + } + + private class CryptoApiEntropySource + : IEntropySource + { + private readonly RandomNumberGenerator mRng; + private readonly bool mPredictionResistant; + private readonly int mEntropySize; + + internal CryptoApiEntropySource(RandomNumberGenerator rng, bool predictionResistant, int entropySize) + { + this.mRng = rng; + this.mPredictionResistant = predictionResistant; + this.mEntropySize = entropySize; + } + + #region IEntropySource Members + + bool IEntropySource.IsPredictionResistant + { + get { return mPredictionResistant; } + } + + byte[] IEntropySource.GetEntropy() + { + byte[] result = new byte[(mEntropySize + 7) / 8]; + mRng.GetBytes(result); + return result; + } + + int IEntropySource.EntropySize + { + get { return mEntropySize; } + } + + #endregion + } + } +} + +#endif diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/CryptoApiEntropySourceProvider.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/CryptoApiEntropySourceProvider.cs.meta new file mode 100644 index 0000000..4f141d2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/CryptoApiEntropySourceProvider.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1df24575b7f895542b1eaf5cff4cfd25 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/CryptoApiRandomGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/CryptoApiRandomGenerator.cs new file mode 100644 index 0000000..0b65920 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/CryptoApiRandomGenerator.cs @@ -0,0 +1,66 @@ +#if !(NETCF_1_0 || PORTABLE) + +using System; +using System.Security.Cryptography; + +namespace Org.BouncyCastle.Crypto.Prng +{ + /// + /// Uses RandomNumberGenerator.Create() to get randomness generator + /// + public class CryptoApiRandomGenerator + : IRandomGenerator + { + private readonly RandomNumberGenerator rndProv; + + public CryptoApiRandomGenerator() + : this(RandomNumberGenerator.Create()) + { + } + + public CryptoApiRandomGenerator(RandomNumberGenerator rng) + { + this.rndProv = rng; + } + + #region IRandomGenerator Members + + public virtual void AddSeedMaterial(byte[] seed) + { + // We don't care about the seed + } + + public virtual void AddSeedMaterial(long seed) + { + // We don't care about the seed + } + + public virtual void NextBytes(byte[] bytes) + { + rndProv.GetBytes(bytes); + } + + public virtual void NextBytes(byte[] bytes, int start, int len) + { + if (start < 0) + throw new ArgumentException("Start offset cannot be negative", "start"); + if (bytes.Length < (start + len)) + throw new ArgumentException("Byte array too small for requested offset and length"); + + if (bytes.Length == len && start == 0) + { + NextBytes(bytes); + } + else + { + byte[] tmpBuf = new byte[len]; + NextBytes(tmpBuf); + Array.Copy(tmpBuf, 0, bytes, start, len); + } + } + + #endregion + } +} + +#endif diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/CryptoApiRandomGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/CryptoApiRandomGenerator.cs.meta new file mode 100644 index 0000000..7f95d95 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/CryptoApiRandomGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e33a657d0d44edb4196a1ba20e595780 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/DigestRandomGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/DigestRandomGenerator.cs new file mode 100644 index 0000000..024db28 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/DigestRandomGenerator.cs @@ -0,0 +1,130 @@ +using System; + +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Prng +{ + /** + * Random generation based on the digest with counter. Calling AddSeedMaterial will + * always increase the entropy of the hash. + *

+ * Internal access to the digest is synchronized so a single one of these can be shared. + *

+ */ + public class DigestRandomGenerator + : IRandomGenerator + { + private const long CYCLE_COUNT = 10; + + private long stateCounter; + private long seedCounter; + private IDigest digest; + private byte[] state; + private byte[] seed; + + public DigestRandomGenerator( + IDigest digest) + { + this.digest = digest; + + this.seed = new byte[digest.GetDigestSize()]; + this.seedCounter = 1; + + this.state = new byte[digest.GetDigestSize()]; + this.stateCounter = 1; + } + + public void AddSeedMaterial( + byte[] inSeed) + { + lock (this) + { + if (!Arrays.IsNullOrEmpty(inSeed)) + { + DigestUpdate(inSeed); + } + DigestUpdate(seed); + DigestDoFinal(seed); + } + } + + public void AddSeedMaterial( + long rSeed) + { + lock (this) + { + DigestAddCounter(rSeed); + DigestUpdate(seed); + DigestDoFinal(seed); + } + } + + public void NextBytes( + byte[] bytes) + { + NextBytes(bytes, 0, bytes.Length); + } + + public void NextBytes( + byte[] bytes, + int start, + int len) + { + lock (this) + { + int stateOff = 0; + + GenerateState(); + + int end = start + len; + for (int i = start; i < end; ++i) + { + if (stateOff == state.Length) + { + GenerateState(); + stateOff = 0; + } + bytes[i] = state[stateOff++]; + } + } + } + + private void CycleSeed() + { + DigestUpdate(seed); + DigestAddCounter(seedCounter++); + DigestDoFinal(seed); + } + + private void GenerateState() + { + DigestAddCounter(stateCounter++); + DigestUpdate(state); + DigestUpdate(seed); + DigestDoFinal(state); + + if ((stateCounter % CYCLE_COUNT) == 0) + { + CycleSeed(); + } + } + + private void DigestAddCounter(long seedVal) + { + byte[] bytes = new byte[8]; + Pack.UInt64_To_LE((ulong)seedVal, bytes); + digest.BlockUpdate(bytes, 0, bytes.Length); + } + + private void DigestUpdate(byte[] inSeed) + { + digest.BlockUpdate(inSeed, 0, inSeed.Length); + } + + private void DigestDoFinal(byte[] result) + { + digest.DoFinal(result, 0); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/DigestRandomGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/DigestRandomGenerator.cs.meta new file mode 100644 index 0000000..2a9cee2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/DigestRandomGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b775030ecd95d184a8af977eff3dbda6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/EntropyUtilities.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/EntropyUtilities.cs new file mode 100644 index 0000000..58c8703 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/EntropyUtilities.cs @@ -0,0 +1,30 @@ +using System; + +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Prng +{ + public abstract class EntropyUtilities + { + /** + * Generate numBytes worth of entropy from the passed in entropy source. + * + * @param entropySource the entropy source to request the data from. + * @param numBytes the number of bytes of entropy requested. + * @return a byte array populated with the random data. + */ + public static byte[] GenerateSeed(IEntropySource entropySource, int numBytes) + { + byte[] bytes = new byte[numBytes]; + int count = 0; + while (count < numBytes) + { + byte[] entropy = entropySource.GetEntropy(); + int toCopy = System.Math.Min(bytes.Length, numBytes - count); + Array.Copy(entropy, 0, bytes, count, toCopy); + count += toCopy; + } + return bytes; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/EntropyUtilities.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/EntropyUtilities.cs.meta new file mode 100644 index 0000000..84753c8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/EntropyUtilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 93e31bdbb8dfde94e9d580068bd61019 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/IDrbgProvider.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/IDrbgProvider.cs new file mode 100644 index 0000000..5ebf5fd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/IDrbgProvider.cs @@ -0,0 +1,11 @@ +using System; + +using Org.BouncyCastle.Crypto.Prng.Drbg; + +namespace Org.BouncyCastle.Crypto.Prng +{ + internal interface IDrbgProvider + { + ISP80090Drbg Get(IEntropySource entropySource); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/IDrbgProvider.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/IDrbgProvider.cs.meta new file mode 100644 index 0000000..27db97d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/IDrbgProvider.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 81cc8c54ed0c6d3419af977f82944004 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/IRandomGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/IRandomGenerator.cs new file mode 100644 index 0000000..8dbe406 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/IRandomGenerator.cs @@ -0,0 +1,26 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Prng +{ + /// Generic interface for objects generating random bytes. + public interface IRandomGenerator + { + /// Add more seed material to the generator. + /// A byte array to be mixed into the generator's state. + void AddSeedMaterial(byte[] seed); + + /// Add more seed material to the generator. + /// A long value to be mixed into the generator's state. + void AddSeedMaterial(long seed); + + /// Fill byte array with random values. + /// Array to be filled. + void NextBytes(byte[] bytes); + + /// Fill byte array with random values. + /// Array to receive bytes. + /// Index to start filling at. + /// Length of segment to fill. + void NextBytes(byte[] bytes, int start, int len); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/IRandomGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/IRandomGenerator.cs.meta new file mode 100644 index 0000000..7bcc4ee --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/IRandomGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0c35087c540819c40846d02f0d956e0b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/ReversedWindowGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/ReversedWindowGenerator.cs new file mode 100644 index 0000000..dd28c52 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/ReversedWindowGenerator.cs @@ -0,0 +1,98 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Prng +{ + /// + /// Takes bytes generated by an underling RandomGenerator and reverses the order in + /// each small window (of configurable size). + ///

+ /// Access to internals is synchronized so a single one of these can be shared. + ///

+ ///
+ public class ReversedWindowGenerator + : IRandomGenerator + { + private readonly IRandomGenerator generator; + + private byte[] window; + private int windowCount; + + public ReversedWindowGenerator( + IRandomGenerator generator, + int windowSize) + { + if (generator == null) + throw new ArgumentNullException("generator"); + if (windowSize < 2) + throw new ArgumentException("Window size must be at least 2", "windowSize"); + + this.generator = generator; + this.window = new byte[windowSize]; + } + + /// Add more seed material to the generator. + /// A byte array to be mixed into the generator's state. + public virtual void AddSeedMaterial( + byte[] seed) + { + lock (this) + { + windowCount = 0; + generator.AddSeedMaterial(seed); + } + } + + /// Add more seed material to the generator. + /// A long value to be mixed into the generator's state. + public virtual void AddSeedMaterial( + long seed) + { + lock (this) + { + windowCount = 0; + generator.AddSeedMaterial(seed); + } + } + + /// Fill byte array with random values. + /// Array to be filled. + public virtual void NextBytes( + byte[] bytes) + { + doNextBytes(bytes, 0, bytes.Length); + } + + /// Fill byte array with random values. + /// Array to receive bytes. + /// Index to start filling at. + /// Length of segment to fill. + public virtual void NextBytes( + byte[] bytes, + int start, + int len) + { + doNextBytes(bytes, start, len); + } + + private void doNextBytes( + byte[] bytes, + int start, + int len) + { + lock (this) + { + int done = 0; + while (done < len) + { + if (windowCount < 1) + { + generator.NextBytes(window, 0, window.Length); + windowCount = window.Length; + } + + bytes[start + done++] = window[--windowCount]; + } + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/ReversedWindowGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/ReversedWindowGenerator.cs.meta new file mode 100644 index 0000000..caef9d4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/ReversedWindowGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 97604fc0207858742baaf36aa2806255 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/SP800SecureRandom.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/SP800SecureRandom.cs new file mode 100644 index 0000000..30c838c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/SP800SecureRandom.cs @@ -0,0 +1,95 @@ +using System; + +using Org.BouncyCastle.Crypto.Prng.Drbg; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Prng +{ + public class SP800SecureRandom + : SecureRandom + { + private readonly IDrbgProvider mDrbgProvider; + private readonly bool mPredictionResistant; + private readonly SecureRandom mRandomSource; + private readonly IEntropySource mEntropySource; + + private ISP80090Drbg mDrbg; + + internal SP800SecureRandom(SecureRandom randomSource, IEntropySource entropySource, IDrbgProvider drbgProvider, bool predictionResistant) + : base((IRandomGenerator)null) + { + this.mRandomSource = randomSource; + this.mEntropySource = entropySource; + this.mDrbgProvider = drbgProvider; + this.mPredictionResistant = predictionResistant; + } + + public override void SetSeed(byte[] seed) + { + lock (this) + { + if (mRandomSource != null) + { + this.mRandomSource.SetSeed(seed); + } + } + } + + public override void SetSeed(long seed) + { + lock (this) + { + // this will happen when SecureRandom() is created + if (mRandomSource != null) + { + this.mRandomSource.SetSeed(seed); + } + } + } + + public override void NextBytes(byte[] bytes) + { + lock (this) + { + if (mDrbg == null) + { + mDrbg = mDrbgProvider.Get(mEntropySource); + } + + // check if a reseed is required... + if (mDrbg.Generate(bytes, null, mPredictionResistant) < 0) + { + mDrbg.Reseed(null); + mDrbg.Generate(bytes, null, mPredictionResistant); + } + } + } + + public override void NextBytes(byte[] buf, int off, int len) + { + byte[] bytes = new byte[len]; + NextBytes(bytes); + Array.Copy(bytes, 0, buf, off, len); + } + + public override byte[] GenerateSeed(int numBytes) + { + return EntropyUtilities.GenerateSeed(mEntropySource, numBytes); + } + + /// Force a reseed of the DRBG. + /// optional additional input + public virtual void Reseed(byte[] additionalInput) + { + lock (this) + { + if (mDrbg == null) + { + mDrbg = mDrbgProvider.Get(mEntropySource); + } + + mDrbg.Reseed(additionalInput); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/SP800SecureRandom.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/SP800SecureRandom.cs.meta new file mode 100644 index 0000000..45970df --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/SP800SecureRandom.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9d46800a04f2ee34e81a5fd3adf5f81f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/SP800SecureRandomBuilder.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/SP800SecureRandomBuilder.cs new file mode 100644 index 0000000..7199f1a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/SP800SecureRandomBuilder.cs @@ -0,0 +1,208 @@ +using System; + +using Org.BouncyCastle.Crypto.Prng.Drbg; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Prng +{ + /** + * Builder class for making SecureRandom objects based on SP 800-90A Deterministic Random Bit Generators (DRBG). + */ + public class SP800SecureRandomBuilder + { + private readonly SecureRandom mRandom; + private readonly IEntropySourceProvider mEntropySourceProvider; + + private byte[] mPersonalizationString = null; + private int mSecurityStrength = 256; + private int mEntropyBitsRequired = 256; + + /** + * Basic constructor, creates a builder using an EntropySourceProvider based on the default SecureRandom with + * predictionResistant set to false. + *

+ * Any SecureRandom created from a builder constructed like this will make use of input passed to SecureRandom.setSeed() if + * the default SecureRandom does for its generateSeed() call. + *

+ */ + public SP800SecureRandomBuilder() + : this(new SecureRandom(), false) + { + } + + /** + * Construct a builder with an EntropySourceProvider based on the passed in SecureRandom and the passed in value + * for prediction resistance. + *

+ * Any SecureRandom created from a builder constructed like this will make use of input passed to SecureRandom.setSeed() if + * the passed in SecureRandom does for its generateSeed() call. + *

+ * @param entropySource + * @param predictionResistant + */ + public SP800SecureRandomBuilder(SecureRandom entropySource, bool predictionResistant) + { + this.mRandom = entropySource; + this.mEntropySourceProvider = new BasicEntropySourceProvider(entropySource, predictionResistant); + } + + /** + * Create a builder which makes creates the SecureRandom objects from a specified entropy source provider. + *

+ * Note: If this constructor is used any calls to setSeed() in the resulting SecureRandom will be ignored. + *

+ * @param entropySourceProvider a provider of EntropySource objects. + */ + public SP800SecureRandomBuilder(IEntropySourceProvider entropySourceProvider) + { + this.mRandom = null; + this.mEntropySourceProvider = entropySourceProvider; + } + + /** + * Set the personalization string for DRBG SecureRandoms created by this builder + * @param personalizationString the personalisation string for the underlying DRBG. + * @return the current builder. + */ + public SP800SecureRandomBuilder SetPersonalizationString(byte[] personalizationString) + { + this.mPersonalizationString = personalizationString; + return this; + } + + /** + * Set the security strength required for DRBGs used in building SecureRandom objects. + * + * @param securityStrength the security strength (in bits) + * @return the current builder. + */ + public SP800SecureRandomBuilder SetSecurityStrength(int securityStrength) + { + this.mSecurityStrength = securityStrength; + return this; + } + + /** + * Set the amount of entropy bits required for seeding and reseeding DRBGs used in building SecureRandom objects. + * + * @param entropyBitsRequired the number of bits of entropy to be requested from the entropy source on each seed/reseed. + * @return the current builder. + */ + public SP800SecureRandomBuilder SetEntropyBitsRequired(int entropyBitsRequired) + { + this.mEntropyBitsRequired = entropyBitsRequired; + return this; + } + + /** + * Build a SecureRandom based on a SP 800-90A Hash DRBG. + * + * @param digest digest algorithm to use in the DRBG underneath the SecureRandom. + * @param nonce nonce value to use in DRBG construction. + * @param predictionResistant specify whether the underlying DRBG in the resulting SecureRandom should reseed on each request for bytes. + * @return a SecureRandom supported by a Hash DRBG. + */ + public SP800SecureRandom BuildHash(IDigest digest, byte[] nonce, bool predictionResistant) + { + return new SP800SecureRandom(mRandom, mEntropySourceProvider.Get(mEntropyBitsRequired), + new HashDrbgProvider(digest, nonce, mPersonalizationString, mSecurityStrength), predictionResistant); + } + + /** + * Build a SecureRandom based on a SP 800-90A CTR DRBG. + * + * @param cipher the block cipher to base the DRBG on. + * @param keySizeInBits key size in bits to be used with the block cipher. + * @param nonce nonce value to use in DRBG construction. + * @param predictionResistant specify whether the underlying DRBG in the resulting SecureRandom should reseed on each request for bytes. + * @return a SecureRandom supported by a CTR DRBG. + */ + public SP800SecureRandom BuildCtr(IBlockCipher cipher, int keySizeInBits, byte[] nonce, bool predictionResistant) + { + return new SP800SecureRandom(mRandom, mEntropySourceProvider.Get(mEntropyBitsRequired), + new CtrDrbgProvider(cipher, keySizeInBits, nonce, mPersonalizationString, mSecurityStrength), predictionResistant); + } + + /** + * Build a SecureRandom based on a SP 800-90A HMAC DRBG. + * + * @param hMac HMAC algorithm to use in the DRBG underneath the SecureRandom. + * @param nonce nonce value to use in DRBG construction. + * @param predictionResistant specify whether the underlying DRBG in the resulting SecureRandom should reseed on each request for bytes. + * @return a SecureRandom supported by a HMAC DRBG. + */ + public SP800SecureRandom BuildHMac(IMac hMac, byte[] nonce, bool predictionResistant) + { + return new SP800SecureRandom(mRandom, mEntropySourceProvider.Get(mEntropyBitsRequired), + new HMacDrbgProvider(hMac, nonce, mPersonalizationString, mSecurityStrength), predictionResistant); + } + + private class HashDrbgProvider + : IDrbgProvider + { + private readonly IDigest mDigest; + private readonly byte[] mNonce; + private readonly byte[] mPersonalizationString; + private readonly int mSecurityStrength; + + public HashDrbgProvider(IDigest digest, byte[] nonce, byte[] personalizationString, int securityStrength) + { + this.mDigest = digest; + this.mNonce = nonce; + this.mPersonalizationString = personalizationString; + this.mSecurityStrength = securityStrength; + } + + public ISP80090Drbg Get(IEntropySource entropySource) + { + return new HashSP800Drbg(mDigest, mSecurityStrength, entropySource, mPersonalizationString, mNonce); + } + } + + private class HMacDrbgProvider + : IDrbgProvider + { + private readonly IMac mHMac; + private readonly byte[] mNonce; + private readonly byte[] mPersonalizationString; + private readonly int mSecurityStrength; + + public HMacDrbgProvider(IMac hMac, byte[] nonce, byte[] personalizationString, int securityStrength) + { + this.mHMac = hMac; + this.mNonce = nonce; + this.mPersonalizationString = personalizationString; + this.mSecurityStrength = securityStrength; + } + + public ISP80090Drbg Get(IEntropySource entropySource) + { + return new HMacSP800Drbg(mHMac, mSecurityStrength, entropySource, mPersonalizationString, mNonce); + } + } + + private class CtrDrbgProvider + : IDrbgProvider + { + private readonly IBlockCipher mBlockCipher; + private readonly int mKeySizeInBits; + private readonly byte[] mNonce; + private readonly byte[] mPersonalizationString; + private readonly int mSecurityStrength; + + public CtrDrbgProvider(IBlockCipher blockCipher, int keySizeInBits, byte[] nonce, byte[] personalizationString, int securityStrength) + { + this.mBlockCipher = blockCipher; + this.mKeySizeInBits = keySizeInBits; + this.mNonce = nonce; + this.mPersonalizationString = personalizationString; + this.mSecurityStrength = securityStrength; + } + + public ISP80090Drbg Get(IEntropySource entropySource) + { + return new CtrSP800Drbg(mBlockCipher, mKeySizeInBits, mSecurityStrength, entropySource, mPersonalizationString, mNonce); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/SP800SecureRandomBuilder.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/SP800SecureRandomBuilder.cs.meta new file mode 100644 index 0000000..5940cfe --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/SP800SecureRandomBuilder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 59ab5235ed57c5e4cad94f1adf08ce3d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/ThreadedSeedGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/ThreadedSeedGenerator.cs new file mode 100644 index 0000000..f12b832 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/ThreadedSeedGenerator.cs @@ -0,0 +1,144 @@ +using System; +using System.Threading; + +#if NO_THREADS +using System.Threading.Tasks; +#endif + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Prng +{ + /** + * A thread based seed generator - one source of randomness. + *

+ * Based on an idea from Marcus Lippert. + *

+ */ + public class ThreadedSeedGenerator + { + private class SeedGenerator + { +#if NETCF_1_0 + // No volatile keyword, but all fields implicitly volatile anyway + private int counter = 0; + private bool stop = false; +#else + private volatile int counter = 0; + private volatile bool stop = false; +#endif + + private void Run(object ignored) + { + while (!this.stop) + { + this.counter++; + } + } + + public byte[] GenerateSeed( + int numBytes, + bool fast) + { +#if SILVERLIGHT || PORTABLE + return DoGenerateSeed(numBytes, fast); +#else + ThreadPriority originalPriority = Thread.CurrentThread.Priority; + try + { + Thread.CurrentThread.Priority = ThreadPriority.Normal; + return DoGenerateSeed(numBytes, fast); + } + finally + { + Thread.CurrentThread.Priority = originalPriority; + } +#endif + } + + private byte[] DoGenerateSeed( + int numBytes, + bool fast) + { + this.counter = 0; + this.stop = false; + + byte[] result = new byte[numBytes]; + int last = 0; + int end = fast ? numBytes : numBytes * 8; + +#if NO_THREADS + Task.Factory.StartNew(() => Run(null), TaskCreationOptions.None); +#else + ThreadPool.QueueUserWorkItem(new WaitCallback(Run)); +#endif + +#if PORTABLE + AutoResetEvent autoResetEvent = new AutoResetEvent(false); +#endif + + try + { + for (int i = 0; i < end; i++) + { + while (this.counter == last) + { + try + { +#if PORTABLE + autoResetEvent.WaitOne(1); +#else + Thread.Sleep(1); +#endif + } + catch (Exception) + { + // ignore + } + } + + last = this.counter; + + if (fast) + { + result[i] = (byte)last; + } + else + { + int bytepos = i / 8; + result[bytepos] = (byte)((result[bytepos] << 1) | (last & 1)); + } + } + } + finally + { +#if PORTABLE + autoResetEvent.Dispose(); +#endif + } + + this.stop = true; + + return result; + } + } + + /** + * Generate seed bytes. Set fast to false for best quality. + *

+ * If fast is set to true, the code should be round about 8 times faster when + * generating a long sequence of random bytes. 20 bytes of random values using + * the fast mode take less than half a second on a Nokia e70. If fast is set to false, + * it takes round about 2500 ms. + *

+ * @param numBytes the number of bytes to generate + * @param fast true if fast mode should be used + */ + public byte[] GenerateSeed( + int numBytes, + bool fast) + { + return new SeedGenerator().GenerateSeed(numBytes, fast); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/ThreadedSeedGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/ThreadedSeedGenerator.cs.meta new file mode 100644 index 0000000..e07de8a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/ThreadedSeedGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bb061aedfe135ea4185b0e42f2249f87 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/VMPCRandomGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/VMPCRandomGenerator.cs new file mode 100644 index 0000000..64f287d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/VMPCRandomGenerator.cs @@ -0,0 +1,114 @@ +using System; + +using Org.BouncyCastle.Crypto.Utilities; + +namespace Org.BouncyCastle.Crypto.Prng +{ + public class VmpcRandomGenerator + : IRandomGenerator + { + private byte n = 0; + + /// + /// Permutation generated by code: + /// + /// // First 1850 fractional digit of Pi number. + /// byte[] key = new BigInteger("14159265358979323846...5068006422512520511").ToByteArray(); + /// s = 0; + /// P = new byte[256]; + /// for (int i = 0; i < 256; i++) + /// { + /// P[i] = (byte) i; + /// } + /// for (int m = 0; m < 768; m++) + /// { + /// s = P[(s + P[m & 0xff] + key[m % key.length]) & 0xff]; + /// byte temp = P[m & 0xff]; + /// P[m & 0xff] = P[s & 0xff]; + /// P[s & 0xff] = temp; + /// } + /// + private byte[] P = + { + (byte) 0xbb, (byte) 0x2c, (byte) 0x62, (byte) 0x7f, (byte) 0xb5, (byte) 0xaa, (byte) 0xd4, + (byte) 0x0d, (byte) 0x81, (byte) 0xfe, (byte) 0xb2, (byte) 0x82, (byte) 0xcb, (byte) 0xa0, (byte) 0xa1, + (byte) 0x08, (byte) 0x18, (byte) 0x71, (byte) 0x56, (byte) 0xe8, (byte) 0x49, (byte) 0x02, (byte) 0x10, + (byte) 0xc4, (byte) 0xde, (byte) 0x35, (byte) 0xa5, (byte) 0xec, (byte) 0x80, (byte) 0x12, (byte) 0xb8, + (byte) 0x69, (byte) 0xda, (byte) 0x2f, (byte) 0x75, (byte) 0xcc, (byte) 0xa2, (byte) 0x09, (byte) 0x36, + (byte) 0x03, (byte) 0x61, (byte) 0x2d, (byte) 0xfd, (byte) 0xe0, (byte) 0xdd, (byte) 0x05, (byte) 0x43, + (byte) 0x90, (byte) 0xad, (byte) 0xc8, (byte) 0xe1, (byte) 0xaf, (byte) 0x57, (byte) 0x9b, (byte) 0x4c, + (byte) 0xd8, (byte) 0x51, (byte) 0xae, (byte) 0x50, (byte) 0x85, (byte) 0x3c, (byte) 0x0a, (byte) 0xe4, + (byte) 0xf3, (byte) 0x9c, (byte) 0x26, (byte) 0x23, (byte) 0x53, (byte) 0xc9, (byte) 0x83, (byte) 0x97, + (byte) 0x46, (byte) 0xb1, (byte) 0x99, (byte) 0x64, (byte) 0x31, (byte) 0x77, (byte) 0xd5, (byte) 0x1d, + (byte) 0xd6, (byte) 0x78, (byte) 0xbd, (byte) 0x5e, (byte) 0xb0, (byte) 0x8a, (byte) 0x22, (byte) 0x38, + (byte) 0xf8, (byte) 0x68, (byte) 0x2b, (byte) 0x2a, (byte) 0xc5, (byte) 0xd3, (byte) 0xf7, (byte) 0xbc, + (byte) 0x6f, (byte) 0xdf, (byte) 0x04, (byte) 0xe5, (byte) 0x95, (byte) 0x3e, (byte) 0x25, (byte) 0x86, + (byte) 0xa6, (byte) 0x0b, (byte) 0x8f, (byte) 0xf1, (byte) 0x24, (byte) 0x0e, (byte) 0xd7, (byte) 0x40, + (byte) 0xb3, (byte) 0xcf, (byte) 0x7e, (byte) 0x06, (byte) 0x15, (byte) 0x9a, (byte) 0x4d, (byte) 0x1c, + (byte) 0xa3, (byte) 0xdb, (byte) 0x32, (byte) 0x92, (byte) 0x58, (byte) 0x11, (byte) 0x27, (byte) 0xf4, + (byte) 0x59, (byte) 0xd0, (byte) 0x4e, (byte) 0x6a, (byte) 0x17, (byte) 0x5b, (byte) 0xac, (byte) 0xff, + (byte) 0x07, (byte) 0xc0, (byte) 0x65, (byte) 0x79, (byte) 0xfc, (byte) 0xc7, (byte) 0xcd, (byte) 0x76, + (byte) 0x42, (byte) 0x5d, (byte) 0xe7, (byte) 0x3a, (byte) 0x34, (byte) 0x7a, (byte) 0x30, (byte) 0x28, + (byte) 0x0f, (byte) 0x73, (byte) 0x01, (byte) 0xf9, (byte) 0xd1, (byte) 0xd2, (byte) 0x19, (byte) 0xe9, + (byte) 0x91, (byte) 0xb9, (byte) 0x5a, (byte) 0xed, (byte) 0x41, (byte) 0x6d, (byte) 0xb4, (byte) 0xc3, + (byte) 0x9e, (byte) 0xbf, (byte) 0x63, (byte) 0xfa, (byte) 0x1f, (byte) 0x33, (byte) 0x60, (byte) 0x47, + (byte) 0x89, (byte) 0xf0, (byte) 0x96, (byte) 0x1a, (byte) 0x5f, (byte) 0x93, (byte) 0x3d, (byte) 0x37, + (byte) 0x4b, (byte) 0xd9, (byte) 0xa8, (byte) 0xc1, (byte) 0x1b, (byte) 0xf6, (byte) 0x39, (byte) 0x8b, + (byte) 0xb7, (byte) 0x0c, (byte) 0x20, (byte) 0xce, (byte) 0x88, (byte) 0x6e, (byte) 0xb6, (byte) 0x74, + (byte) 0x8e, (byte) 0x8d, (byte) 0x16, (byte) 0x29, (byte) 0xf2, (byte) 0x87, (byte) 0xf5, (byte) 0xeb, + (byte) 0x70, (byte) 0xe3, (byte) 0xfb, (byte) 0x55, (byte) 0x9f, (byte) 0xc6, (byte) 0x44, (byte) 0x4a, + (byte) 0x45, (byte) 0x7d, (byte) 0xe2, (byte) 0x6b, (byte) 0x5c, (byte) 0x6c, (byte) 0x66, (byte) 0xa9, + (byte) 0x8c, (byte) 0xee, (byte) 0x84, (byte) 0x13, (byte) 0xa7, (byte) 0x1e, (byte) 0x9d, (byte) 0xdc, + (byte) 0x67, (byte) 0x48, (byte) 0xba, (byte) 0x2e, (byte) 0xe6, (byte) 0xa4, (byte) 0xab, (byte) 0x7c, + (byte) 0x94, (byte) 0x00, (byte) 0x21, (byte) 0xef, (byte) 0xea, (byte) 0xbe, (byte) 0xca, (byte) 0x72, + (byte) 0x4f, (byte) 0x52, (byte) 0x98, (byte) 0x3f, (byte) 0xc2, (byte) 0x14, (byte) 0x7b, (byte) 0x3b, + (byte) 0x54 + }; + + /// Value generated in the same way as P. + private byte s = (byte) 0xbe; + + public VmpcRandomGenerator() + { + } + + public virtual void AddSeedMaterial(byte[] seed) + { + for (int m = 0; m < seed.Length; m++) + { + s = P[(s + P[n & 0xff] + seed[m]) & 0xff]; + byte temp = P[n & 0xff]; + P[n & 0xff] = P[s & 0xff]; + P[s & 0xff] = temp; + n = (byte) ((n + 1) & 0xff); + } + } + + public virtual void AddSeedMaterial(long seed) + { + AddSeedMaterial(Pack.UInt64_To_BE((ulong)seed)); + } + + public virtual void NextBytes(byte[] bytes) + { + NextBytes(bytes, 0, bytes.Length); + } + + public virtual void NextBytes(byte[] bytes, int start, int len) + { + lock (P) + { + int end = start + len; + for (int i = start; i != end; i++) + { + s = P[(s + P[n & 0xff]) & 0xff]; + bytes[i] = P[(P[(P[s & 0xff]) & 0xff] + 1) & 0xff]; + byte temp = P[n & 0xff]; + P[n & 0xff] = P[s & 0xff]; + P[s & 0xff] = temp; + n = (byte) ((n + 1) & 0xff); + } + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/VMPCRandomGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/VMPCRandomGenerator.cs.meta new file mode 100644 index 0000000..769612e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/VMPCRandomGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 832b5c87e75375a4f9814d5810244d7e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/X931Rng.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/X931Rng.cs new file mode 100644 index 0000000..2bd8e0c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/X931Rng.cs @@ -0,0 +1,146 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Prng +{ + internal class X931Rng + { + private const long BLOCK64_RESEED_MAX = 1L << (16 - 1); + private const long BLOCK128_RESEED_MAX = 1L << (24 - 1); + private const int BLOCK64_MAX_BITS_REQUEST = 1 << (13 - 1); + private const int BLOCK128_MAX_BITS_REQUEST = 1 << (19 - 1); + + private readonly IBlockCipher mEngine; + private readonly IEntropySource mEntropySource; + + private readonly byte[] mDT; + private readonly byte[] mI; + private readonly byte[] mR; + + private byte[] mV; + + private long mReseedCounter = 1; + + /** + * + * @param engine + * @param entropySource + */ + internal X931Rng(IBlockCipher engine, byte[] dateTimeVector, IEntropySource entropySource) + { + this.mEngine = engine; + this.mEntropySource = entropySource; + + this.mDT = new byte[engine.GetBlockSize()]; + + Array.Copy(dateTimeVector, 0, mDT, 0, mDT.Length); + + this.mI = new byte[engine.GetBlockSize()]; + this.mR = new byte[engine.GetBlockSize()]; + } + + /** + * Populate a passed in array with random data. + * + * @param output output array for generated bits. + * @param predictionResistant true if a reseed should be forced, false otherwise. + * + * @return number of bits generated, -1 if a reseed required. + */ + internal int Generate(byte[] output, bool predictionResistant) + { + if (mR.Length == 8) // 64 bit block size + { + if (mReseedCounter > BLOCK64_RESEED_MAX) + return -1; + + if (IsTooLarge(output, BLOCK64_MAX_BITS_REQUEST / 8)) + throw new ArgumentException("Number of bits per request limited to " + BLOCK64_MAX_BITS_REQUEST, "output"); + } + else + { + if (mReseedCounter > BLOCK128_RESEED_MAX) + return -1; + + if (IsTooLarge(output, BLOCK128_MAX_BITS_REQUEST / 8)) + throw new ArgumentException("Number of bits per request limited to " + BLOCK128_MAX_BITS_REQUEST, "output"); + } + + if (predictionResistant || mV == null) + { + mV = mEntropySource.GetEntropy(); + if (mV.Length != mEngine.GetBlockSize()) + throw new InvalidOperationException("Insufficient entropy returned"); + } + + int m = output.Length / mR.Length; + + for (int i = 0; i < m; i++) + { + mEngine.ProcessBlock(mDT, 0, mI, 0); + Process(mR, mI, mV); + Process(mV, mR, mI); + + Array.Copy(mR, 0, output, i * mR.Length, mR.Length); + + Increment(mDT); + } + + int bytesToCopy = (output.Length - m * mR.Length); + + if (bytesToCopy > 0) + { + mEngine.ProcessBlock(mDT, 0, mI, 0); + Process(mR, mI, mV); + Process(mV, mR, mI); + + Array.Copy(mR, 0, output, m * mR.Length, bytesToCopy); + + Increment(mDT); + } + + mReseedCounter++; + + return output.Length; + } + + /** + * Reseed the RNG. + */ + internal void Reseed() + { + mV = mEntropySource.GetEntropy(); + if (mV.Length != mEngine.GetBlockSize()) + throw new InvalidOperationException("Insufficient entropy returned"); + mReseedCounter = 1; + } + + internal IEntropySource EntropySource + { + get { return mEntropySource; } + } + + private void Process(byte[] res, byte[] a, byte[] b) + { + for (int i = 0; i != res.Length; i++) + { + res[i] = (byte)(a[i] ^ b[i]); + } + + mEngine.ProcessBlock(res, 0, res, 0); + } + + private void Increment(byte[] val) + { + for (int i = val.Length - 1; i >= 0; i--) + { + if (++val[i] != 0) + break; + } + } + + private static bool IsTooLarge(byte[] bytes, int maxBytes) + { + return bytes != null && bytes.Length > maxBytes; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/X931Rng.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/X931Rng.cs.meta new file mode 100644 index 0000000..b95a3fa --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/X931Rng.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fc5e61ab265f80e40bfd0ce34e6b1f70 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/X931SecureRandom.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/X931SecureRandom.cs new file mode 100644 index 0000000..d2e4849 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/X931SecureRandom.cs @@ -0,0 +1,70 @@ +using System; + +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Prng +{ + public class X931SecureRandom + : SecureRandom + { + private readonly bool mPredictionResistant; + private readonly SecureRandom mRandomSource; + private readonly X931Rng mDrbg; + + internal X931SecureRandom(SecureRandom randomSource, X931Rng drbg, bool predictionResistant) + : base((IRandomGenerator)null) + { + this.mRandomSource = randomSource; + this.mDrbg = drbg; + this.mPredictionResistant = predictionResistant; + } + + public override void SetSeed(byte[] seed) + { + lock (this) + { + if (mRandomSource != null) + { + this.mRandomSource.SetSeed(seed); + } + } + } + + public override void SetSeed(long seed) + { + lock (this) + { + // this will happen when SecureRandom() is created + if (mRandomSource != null) + { + this.mRandomSource.SetSeed(seed); + } + } + } + + public override void NextBytes(byte[] bytes) + { + lock (this) + { + // check if a reseed is required... + if (mDrbg.Generate(bytes, mPredictionResistant) < 0) + { + mDrbg.Reseed(); + mDrbg.Generate(bytes, mPredictionResistant); + } + } + } + + public override void NextBytes(byte[] buf, int off, int len) + { + byte[] bytes = new byte[len]; + NextBytes(bytes); + Array.Copy(bytes, 0, buf, off, len); + } + + public override byte[] GenerateSeed(int numBytes) + { + return EntropyUtilities.GenerateSeed(mDrbg.EntropySource, numBytes); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/X931SecureRandom.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/X931SecureRandom.cs.meta new file mode 100644 index 0000000..c514733 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/X931SecureRandom.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 17fe5049cade2254d9ef2f1c8c96b552 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/X931SecureRandomBuilder.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/X931SecureRandomBuilder.cs new file mode 100644 index 0000000..31e9431 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/X931SecureRandomBuilder.cs @@ -0,0 +1,87 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities.Date; + +namespace Org.BouncyCastle.Crypto.Prng +{ + public class X931SecureRandomBuilder + { + private readonly SecureRandom mRandom; // JDK 1.1 complains on final. + + private IEntropySourceProvider mEntropySourceProvider; + private byte[] mDateTimeVector; + + /** + * Basic constructor, creates a builder using an EntropySourceProvider based on the default SecureRandom with + * predictionResistant set to false. + *

+ * Any SecureRandom created from a builder constructed like this will make use of input passed to SecureRandom.setSeed() if + * the default SecureRandom does for its generateSeed() call. + *

+ */ + public X931SecureRandomBuilder() + : this(new SecureRandom(), false) + { + } + + /** + * Construct a builder with an EntropySourceProvider based on the passed in SecureRandom and the passed in value + * for prediction resistance. + *

+ * Any SecureRandom created from a builder constructed like this will make use of input passed to SecureRandom.setSeed() if + * the passed in SecureRandom does for its generateSeed() call. + *

+ * @param entropySource + * @param predictionResistant + */ + public X931SecureRandomBuilder(SecureRandom entropySource, bool predictionResistant) + { + this.mRandom = entropySource; + this.mEntropySourceProvider = new BasicEntropySourceProvider(mRandom, predictionResistant); + } + + /** + * Create a builder which makes creates the SecureRandom objects from a specified entropy source provider. + *

+ * Note: If this constructor is used any calls to setSeed() in the resulting SecureRandom will be ignored. + *

+ * @param entropySourceProvider a provider of EntropySource objects. + */ + public X931SecureRandomBuilder(IEntropySourceProvider entropySourceProvider) + { + this.mRandom = null; + this.mEntropySourceProvider = entropySourceProvider; + } + + public X931SecureRandomBuilder SetDateTimeVector(byte[] dateTimeVector) + { + this.mDateTimeVector = dateTimeVector; + return this; + } + + /** + * Construct a X9.31 secure random generator using the passed in engine and key. If predictionResistant is true the + * generator will be reseeded on each request. + * + * @param engine a block cipher to use as the operator. + * @param key the block cipher key to initialise engine with. + * @param predictionResistant true if engine to be reseeded on each use, false otherwise. + * @return a SecureRandom. + */ + public X931SecureRandom Build(IBlockCipher engine, KeyParameter key, bool predictionResistant) + { + if (mDateTimeVector == null) + { + mDateTimeVector = new byte[engine.GetBlockSize()]; + Pack.UInt64_To_BE((ulong)DateTimeUtilities.CurrentUnixMs(), mDateTimeVector, 0); + } + + engine.Init(true, key); + + return new X931SecureRandom(mRandom, new X931Rng(engine, mDateTimeVector, mEntropySourceProvider.Get(engine.GetBlockSize() * 8)), predictionResistant); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/X931SecureRandomBuilder.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/X931SecureRandomBuilder.cs.meta new file mode 100644 index 0000000..ffde090 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/X931SecureRandomBuilder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1b3d63e86479ed54dbc55c361ce5759a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/drbg.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/drbg.meta new file mode 100644 index 0000000..52dddb6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/drbg.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d970ef3cb37a3a447a5c3f2c5d6d91e5 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/drbg/CtrSP800Drbg.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/drbg/CtrSP800Drbg.cs new file mode 100644 index 0000000..5715a91 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/drbg/CtrSP800Drbg.cs @@ -0,0 +1,466 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Crypto.Prng.Drbg +{ + /** + * A SP800-90A CTR DRBG. + */ + public class CtrSP800Drbg + : ISP80090Drbg + { + private static readonly long TDEA_RESEED_MAX = 1L << (32 - 1); + private static readonly long AES_RESEED_MAX = 1L << (48 - 1); + private static readonly int TDEA_MAX_BITS_REQUEST = 1 << (13 - 1); + private static readonly int AES_MAX_BITS_REQUEST = 1 << (19 - 1); + + private readonly IEntropySource mEntropySource; + private readonly IBlockCipher mEngine; + private readonly int mKeySizeInBits; + private readonly int mSeedLength; + private readonly int mSecurityStrength; + + // internal state + private byte[] mKey; + private byte[] mV; + private long mReseedCounter = 0; + private bool mIsTdea = false; + + /** + * Construct a SP800-90A CTR DRBG. + *

+ * Minimum entropy requirement is the security strength requested. + *

+ * @param engine underlying block cipher to use to support DRBG + * @param keySizeInBits size of the key to use with the block cipher. + * @param securityStrength security strength required (in bits) + * @param entropySource source of entropy to use for seeding/reseeding. + * @param personalizationString personalization string to distinguish this DRBG (may be null). + * @param nonce nonce to further distinguish this DRBG (may be null). + */ + public CtrSP800Drbg(IBlockCipher engine, int keySizeInBits, int securityStrength, IEntropySource entropySource, + byte[] personalizationString, byte[] nonce) + { + if (securityStrength > 256) + throw new ArgumentException("Requested security strength is not supported by the derivation function"); + if (GetMaxSecurityStrength(engine, keySizeInBits) < securityStrength) + throw new ArgumentException("Requested security strength is not supported by block cipher and key size"); + if (entropySource.EntropySize < securityStrength) + throw new ArgumentException("Not enough entropy for security strength required"); + + mEntropySource = entropySource; + mEngine = engine; + + mKeySizeInBits = keySizeInBits; + mSecurityStrength = securityStrength; + mSeedLength = keySizeInBits + engine.GetBlockSize() * 8; + mIsTdea = IsTdea(engine); + + byte[] entropy = GetEntropy(); // Get_entropy_input + + CTR_DRBG_Instantiate_algorithm(entropy, nonce, personalizationString); + } + + private void CTR_DRBG_Instantiate_algorithm(byte[] entropy, byte[] nonce, byte[] personalisationString) + { + byte[] seedMaterial = Arrays.ConcatenateAll(entropy, nonce, personalisationString); + byte[] seed = Block_Cipher_df(seedMaterial, mSeedLength); + + int outlen = mEngine.GetBlockSize(); + + mKey = new byte[(mKeySizeInBits + 7) / 8]; + mV = new byte[outlen]; + + // mKey & mV are modified by this call + CTR_DRBG_Update(seed, mKey, mV); + + mReseedCounter = 1; + } + + private void CTR_DRBG_Update(byte[] seed, byte[] key, byte[] v) + { + byte[] temp = new byte[seed.Length]; + byte[] outputBlock = new byte[mEngine.GetBlockSize()]; + + int i = 0; + int outLen = mEngine.GetBlockSize(); + + mEngine.Init(true, new KeyParameter(ExpandKey(key))); + while (i*outLen < seed.Length) + { + AddOneTo(v); + mEngine.ProcessBlock(v, 0, outputBlock, 0); + + int bytesToCopy = ((temp.Length - i * outLen) > outLen) + ? outLen : (temp.Length - i * outLen); + + Array.Copy(outputBlock, 0, temp, i * outLen, bytesToCopy); + ++i; + } + + XOR(temp, seed, temp, 0); + + Array.Copy(temp, 0, key, 0, key.Length); + Array.Copy(temp, key.Length, v, 0, v.Length); + } + + private void CTR_DRBG_Reseed_algorithm(byte[] additionalInput) + { + byte[] seedMaterial = Arrays.Concatenate(GetEntropy(), additionalInput); + + seedMaterial = Block_Cipher_df(seedMaterial, mSeedLength); + + CTR_DRBG_Update(seedMaterial, mKey, mV); + + mReseedCounter = 1; + } + + private void XOR(byte[] output, byte[] a, byte[] b, int bOff) + { + for (int i = 0; i < output.Length; i++) + { + output[i] = (byte)(a[i] ^ b[bOff + i]); + } + } + + private void AddOneTo(byte[] longer) + { + uint carry = 1; + int i = longer.Length; + while (--i >= 0) + { + carry += longer[i]; + longer[i] = (byte)carry; + carry >>= 8; + } + } + + private byte[] GetEntropy() + { + byte[] entropy = mEntropySource.GetEntropy(); + if (entropy.Length < (mSecurityStrength + 7) / 8) + throw new InvalidOperationException("Insufficient entropy provided by entropy source"); + return entropy; + } + + // -- Internal state migration --- + + private static readonly byte[] K_BITS = Hex.DecodeStrict("000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F"); + + // 1. If (number_of_bits_to_return > max_number_of_bits), then return an + // ERROR_FLAG. + // 2. L = len (input_string)/8. + // 3. N = number_of_bits_to_return/8. + // Comment: L is the bitstring represention of + // the integer resulting from len (input_string)/8. + // L shall be represented as a 32-bit integer. + // + // Comment : N is the bitstring represention of + // the integer resulting from + // number_of_bits_to_return/8. N shall be + // represented as a 32-bit integer. + // + // 4. S = L || N || input_string || 0x80. + // 5. While (len (S) mod outlen) + // Comment : Pad S with zeros, if necessary. + // 0, S = S || 0x00. + // + // Comment : Compute the starting value. + // 6. temp = the Null string. + // 7. i = 0. + // 8. K = Leftmost keylen bits of 0x00010203...1D1E1F. + // 9. While len (temp) < keylen + outlen, do + // + // IV = i || 0outlen - len (i). + // + // 9.1 + // + // temp = temp || BCC (K, (IV || S)). + // + // 9.2 + // + // i = i + 1. + // + // 9.3 + // + // Comment : i shall be represented as a 32-bit + // integer, i.e., len (i) = 32. + // + // Comment: The 32-bit integer represenation of + // i is padded with zeros to outlen bits. + // + // Comment: Compute the requested number of + // bits. + // + // 10. K = Leftmost keylen bits of temp. + // + // 11. X = Next outlen bits of temp. + // + // 12. temp = the Null string. + // + // 13. While len (temp) < number_of_bits_to_return, do + // + // 13.1 X = Block_Encrypt (K, X). + // + // 13.2 temp = temp || X. + // + // 14. requested_bits = Leftmost number_of_bits_to_return of temp. + // + // 15. Return SUCCESS and requested_bits. + private byte[] Block_Cipher_df(byte[] inputString, int bitLength) + { + int outLen = mEngine.GetBlockSize(); + int L = inputString.Length; // already in bytes + int N = bitLength / 8; + // 4 S = L || N || inputstring || 0x80 + int sLen = 4 + 4 + L + 1; + int blockLen = ((sLen + outLen - 1) / outLen) * outLen; + byte[] S = new byte[blockLen]; + copyIntToByteArray(S, L, 0); + copyIntToByteArray(S, N, 4); + Array.Copy(inputString, 0, S, 8, L); + S[8 + L] = (byte)0x80; + // S already padded with zeros + + byte[] temp = new byte[mKeySizeInBits / 8 + outLen]; + byte[] bccOut = new byte[outLen]; + + byte[] IV = new byte[outLen]; + + int i = 0; + byte[] K = new byte[mKeySizeInBits / 8]; + Array.Copy(K_BITS, 0, K, 0, K.Length); + + while (i*outLen*8 < mKeySizeInBits + outLen *8) + { + copyIntToByteArray(IV, i, 0); + BCC(bccOut, K, IV, S); + + int bytesToCopy = ((temp.Length - i * outLen) > outLen) + ? outLen + : (temp.Length - i * outLen); + + Array.Copy(bccOut, 0, temp, i * outLen, bytesToCopy); + ++i; + } + + byte[] X = new byte[outLen]; + Array.Copy(temp, 0, K, 0, K.Length); + Array.Copy(temp, K.Length, X, 0, X.Length); + + temp = new byte[bitLength / 2]; + + i = 0; + mEngine.Init(true, new KeyParameter(ExpandKey(K))); + + while (i * outLen < temp.Length) + { + mEngine.ProcessBlock(X, 0, X, 0); + + int bytesToCopy = ((temp.Length - i * outLen) > outLen) + ? outLen + : (temp.Length - i * outLen); + + Array.Copy(X, 0, temp, i * outLen, bytesToCopy); + i++; + } + + return temp; + } + + /* + * 1. chaining_value = 0^outlen + * . Comment: Set the first chaining value to outlen zeros. + * 2. n = len (data)/outlen. + * 3. Starting with the leftmost bits of data, split the data into n blocks of outlen bits + * each, forming block(1) to block(n). + * 4. For i = 1 to n do + * 4.1 input_block = chaining_value ^ block(i) . + * 4.2 chaining_value = Block_Encrypt (Key, input_block). + * 5. output_block = chaining_value. + * 6. Return output_block. + */ + private void BCC(byte[] bccOut, byte[] k, byte[] iV, byte[] data) + { + int outlen = mEngine.GetBlockSize(); + byte[] chainingValue = new byte[outlen]; // initial values = 0 + int n = data.Length / outlen; + + byte[] inputBlock = new byte[outlen]; + + mEngine.Init(true, new KeyParameter(ExpandKey(k))); + + mEngine.ProcessBlock(iV, 0, chainingValue, 0); + + for (int i = 0; i < n; i++) + { + XOR(inputBlock, chainingValue, data, i*outlen); + mEngine.ProcessBlock(inputBlock, 0, chainingValue, 0); + } + + Array.Copy(chainingValue, 0, bccOut, 0, bccOut.Length); + } + + private void copyIntToByteArray(byte[] buf, int value, int offSet) + { + buf[offSet + 0] = ((byte)(value >> 24)); + buf[offSet + 1] = ((byte)(value >> 16)); + buf[offSet + 2] = ((byte)(value >> 8)); + buf[offSet + 3] = ((byte)(value)); + } + + /** + * Return the block size (in bits) of the DRBG. + * + * @return the number of bits produced on each internal round of the DRBG. + */ + public int BlockSize + { + get { return mV.Length * 8; } + } + + /** + * Populate a passed in array with random data. + * + * @param output output array for generated bits. + * @param additionalInput additional input to be added to the DRBG in this step. + * @param predictionResistant true if a reseed should be forced, false otherwise. + * + * @return number of bits generated, -1 if a reseed required. + */ + public int Generate(byte[] output, byte[] additionalInput, bool predictionResistant) + { + if (mIsTdea) + { + if (mReseedCounter > TDEA_RESEED_MAX) + return -1; + + if (DrbgUtilities.IsTooLarge(output, TDEA_MAX_BITS_REQUEST / 8)) + throw new ArgumentException("Number of bits per request limited to " + TDEA_MAX_BITS_REQUEST, "output"); + } + else + { + if (mReseedCounter > AES_RESEED_MAX) + return -1; + + if (DrbgUtilities.IsTooLarge(output, AES_MAX_BITS_REQUEST / 8)) + throw new ArgumentException("Number of bits per request limited to " + AES_MAX_BITS_REQUEST, "output"); + } + + if (predictionResistant) + { + CTR_DRBG_Reseed_algorithm(additionalInput); + additionalInput = null; + } + + if (additionalInput != null) + { + additionalInput = Block_Cipher_df(additionalInput, mSeedLength); + CTR_DRBG_Update(additionalInput, mKey, mV); + } + else + { + additionalInput = new byte[mSeedLength]; + } + + byte[] tmp = new byte[mV.Length]; + + mEngine.Init(true, new KeyParameter(ExpandKey(mKey))); + + for (int i = 0; i <= output.Length / tmp.Length; i++) + { + int bytesToCopy = ((output.Length - i * tmp.Length) > tmp.Length) + ? tmp.Length + : (output.Length - i * mV.Length); + + if (bytesToCopy != 0) + { + AddOneTo(mV); + + mEngine.ProcessBlock(mV, 0, tmp, 0); + + Array.Copy(tmp, 0, output, i * tmp.Length, bytesToCopy); + } + } + + CTR_DRBG_Update(additionalInput, mKey, mV); + + mReseedCounter++; + + return output.Length * 8; + } + + /** + * Reseed the DRBG. + * + * @param additionalInput additional input to be added to the DRBG in this step. + */ + public void Reseed(byte[] additionalInput) + { + CTR_DRBG_Reseed_algorithm(additionalInput); + } + + private bool IsTdea(IBlockCipher cipher) + { + return cipher.AlgorithmName.Equals("DESede") || cipher.AlgorithmName.Equals("TDEA"); + } + + private int GetMaxSecurityStrength(IBlockCipher cipher, int keySizeInBits) + { + if (IsTdea(cipher) && keySizeInBits == 168) + { + return 112; + } + if (cipher.AlgorithmName.Equals("AES")) + { + return keySizeInBits; + } + + return -1; + } + + private byte[] ExpandKey(byte[] key) + { + if (mIsTdea) + { + // expand key to 192 bits. + byte[] tmp = new byte[24]; + + PadKey(key, 0, tmp, 0); + PadKey(key, 7, tmp, 8); + PadKey(key, 14, tmp, 16); + + return tmp; + } + else + { + return key; + } + } + + /** + * Pad out a key for TDEA, setting odd parity for each byte. + * + * @param keyMaster + * @param keyOff + * @param tmp + * @param tmpOff + */ + private void PadKey(byte[] keyMaster, int keyOff, byte[] tmp, int tmpOff) + { + tmp[tmpOff + 0] = (byte)(keyMaster[keyOff + 0] & 0xfe); + tmp[tmpOff + 1] = (byte)((keyMaster[keyOff + 0] << 7) | ((keyMaster[keyOff + 1] & 0xfc) >> 1)); + tmp[tmpOff + 2] = (byte)((keyMaster[keyOff + 1] << 6) | ((keyMaster[keyOff + 2] & 0xf8) >> 2)); + tmp[tmpOff + 3] = (byte)((keyMaster[keyOff + 2] << 5) | ((keyMaster[keyOff + 3] & 0xf0) >> 3)); + tmp[tmpOff + 4] = (byte)((keyMaster[keyOff + 3] << 4) | ((keyMaster[keyOff + 4] & 0xe0) >> 4)); + tmp[tmpOff + 5] = (byte)((keyMaster[keyOff + 4] << 3) | ((keyMaster[keyOff + 5] & 0xc0) >> 5)); + tmp[tmpOff + 6] = (byte)((keyMaster[keyOff + 5] << 2) | ((keyMaster[keyOff + 6] & 0x80) >> 6)); + tmp[tmpOff + 7] = (byte)(keyMaster[keyOff + 6] << 1); + + DesParameters.SetOddParity(tmp, tmpOff, 8); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/drbg/CtrSP800Drbg.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/drbg/CtrSP800Drbg.cs.meta new file mode 100644 index 0000000..1a40cfc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/drbg/CtrSP800Drbg.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5f53165c7246a87499f7f5bade8dee25 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/drbg/DrbgUtilities.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/drbg/DrbgUtilities.cs new file mode 100644 index 0000000..d9a1c43 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/drbg/DrbgUtilities.cs @@ -0,0 +1,103 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Prng.Drbg +{ + internal class DrbgUtilities + { + private static readonly IDictionary maxSecurityStrengths = Platform.CreateHashtable(); + + static DrbgUtilities() + { + maxSecurityStrengths.Add("SHA-1", 128); + + maxSecurityStrengths.Add("SHA-224", 192); + maxSecurityStrengths.Add("SHA-256", 256); + maxSecurityStrengths.Add("SHA-384", 256); + maxSecurityStrengths.Add("SHA-512", 256); + + maxSecurityStrengths.Add("SHA-512/224", 192); + maxSecurityStrengths.Add("SHA-512/256", 256); + } + + internal static int GetMaxSecurityStrength(IDigest d) + { + return (int)maxSecurityStrengths[d.AlgorithmName]; + } + + internal static int GetMaxSecurityStrength(IMac m) + { + string name = m.AlgorithmName; + + return (int)maxSecurityStrengths[name.Substring(0, name.IndexOf("/"))]; + } + + /** + * Used by both Dual EC and Hash. + */ + internal static byte[] HashDF(IDigest digest, byte[] seedMaterial, int seedLength) + { + // 1. temp = the Null string. + // 2. . + // 3. counter = an 8-bit binary value representing the integer "1". + // 4. For i = 1 to len do + // Comment : In step 4.1, no_of_bits_to_return + // is used as a 32-bit string. + // 4.1 temp = temp || Hash (counter || no_of_bits_to_return || + // input_string). + // 4.2 counter = counter + 1. + // 5. requested_bits = Leftmost (no_of_bits_to_return) of temp. + // 6. Return SUCCESS and requested_bits. + byte[] temp = new byte[(seedLength + 7) / 8]; + + int len = temp.Length / digest.GetDigestSize(); + int counter = 1; + + byte[] dig = new byte[digest.GetDigestSize()]; + + for (int i = 0; i <= len; i++) + { + digest.Update((byte)counter); + + digest.Update((byte)(seedLength >> 24)); + digest.Update((byte)(seedLength >> 16)); + digest.Update((byte)(seedLength >> 8)); + digest.Update((byte)seedLength); + + digest.BlockUpdate(seedMaterial, 0, seedMaterial.Length); + + digest.DoFinal(dig, 0); + + int bytesToCopy = ((temp.Length - i * dig.Length) > dig.Length) + ? dig.Length + : (temp.Length - i * dig.Length); + Array.Copy(dig, 0, temp, i * dig.Length, bytesToCopy); + + counter++; + } + + // do a left shift to get rid of excess bits. + if (seedLength % 8 != 0) + { + int shift = 8 - (seedLength % 8); + uint carry = 0; + + for (int i = 0; i != temp.Length; i++) + { + uint b = temp[i]; + temp[i] = (byte)((b >> shift) | (carry << (8 - shift))); + carry = b; + } + } + + return temp; + } + + internal static bool IsTooLarge(byte[] bytes, int maxBytes) + { + return bytes != null && bytes.Length > maxBytes; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/drbg/DrbgUtilities.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/drbg/DrbgUtilities.cs.meta new file mode 100644 index 0000000..9fdafd0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/drbg/DrbgUtilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: aa571f41f4a029e45a5f7dffb6b8a22d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/drbg/HMacSP800Drbg.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/drbg/HMacSP800Drbg.cs new file mode 100644 index 0000000..7833170 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/drbg/HMacSP800Drbg.cs @@ -0,0 +1,186 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Prng.Drbg +{ + /** + * A SP800-90A HMAC DRBG. + */ + public class HMacSP800Drbg + : ISP80090Drbg + { + private readonly static long RESEED_MAX = 1L << (48 - 1); + private readonly static int MAX_BITS_REQUEST = 1 << (19 - 1); + + private readonly byte[] mK; + private readonly byte[] mV; + private readonly IEntropySource mEntropySource; + private readonly IMac mHMac; + private readonly int mSecurityStrength; + + private long mReseedCounter; + + /** + * Construct a SP800-90A Hash DRBG. + *

+ * Minimum entropy requirement is the security strength requested. + *

+ * @param hMac Hash MAC to base the DRBG on. + * @param securityStrength security strength required (in bits) + * @param entropySource source of entropy to use for seeding/reseeding. + * @param personalizationString personalization string to distinguish this DRBG (may be null). + * @param nonce nonce to further distinguish this DRBG (may be null). + */ + public HMacSP800Drbg(IMac hMac, int securityStrength, IEntropySource entropySource, byte[] personalizationString, byte[] nonce) + { + if (securityStrength > DrbgUtilities.GetMaxSecurityStrength(hMac)) + throw new ArgumentException("Requested security strength is not supported by the derivation function"); + if (entropySource.EntropySize < securityStrength) + throw new ArgumentException("Not enough entropy for security strength required"); + + mHMac = hMac; + mSecurityStrength = securityStrength; + mEntropySource = entropySource; + + byte[] entropy = GetEntropy(); + byte[] seedMaterial = Arrays.ConcatenateAll(entropy, nonce, personalizationString); + + mK = new byte[hMac.GetMacSize()]; + mV = new byte[mK.Length]; + Arrays.Fill(mV, (byte)1); + + hmac_DRBG_Update(seedMaterial); + + mReseedCounter = 1; + } + + private void hmac_DRBG_Update(byte[] seedMaterial) + { + hmac_DRBG_Update_Func(seedMaterial, (byte)0x00); + if (seedMaterial != null) + { + hmac_DRBG_Update_Func(seedMaterial, (byte)0x01); + } + } + + private void hmac_DRBG_Update_Func(byte[] seedMaterial, byte vValue) + { + mHMac.Init(new KeyParameter(mK)); + + mHMac.BlockUpdate(mV, 0, mV.Length); + mHMac.Update(vValue); + + if (seedMaterial != null) + { + mHMac.BlockUpdate(seedMaterial, 0, seedMaterial.Length); + } + + mHMac.DoFinal(mK, 0); + + mHMac.Init(new KeyParameter(mK)); + mHMac.BlockUpdate(mV, 0, mV.Length); + + mHMac.DoFinal(mV, 0); + } + + /** + * Return the block size (in bits) of the DRBG. + * + * @return the number of bits produced on each round of the DRBG. + */ + public int BlockSize + { + get { return mV.Length * 8; } + } + + /** + * Populate a passed in array with random data. + * + * @param output output array for generated bits. + * @param additionalInput additional input to be added to the DRBG in this step. + * @param predictionResistant true if a reseed should be forced, false otherwise. + * + * @return number of bits generated, -1 if a reseed required. + */ + public int Generate(byte[] output, byte[] additionalInput, bool predictionResistant) + { + int numberOfBits = output.Length * 8; + + if (numberOfBits > MAX_BITS_REQUEST) + throw new ArgumentException("Number of bits per request limited to " + MAX_BITS_REQUEST, "output"); + + if (mReseedCounter > RESEED_MAX) + { + return -1; + } + + if (predictionResistant) + { + Reseed(additionalInput); + additionalInput = null; + } + + // 2. + if (additionalInput != null) + { + hmac_DRBG_Update(additionalInput); + } + + // 3. + byte[] rv = new byte[output.Length]; + + int m = output.Length / mV.Length; + + mHMac.Init(new KeyParameter(mK)); + + for (int i = 0; i < m; i++) + { + mHMac.BlockUpdate(mV, 0, mV.Length); + mHMac.DoFinal(mV, 0); + + Array.Copy(mV, 0, rv, i * mV.Length, mV.Length); + } + + if (m * mV.Length < rv.Length) + { + mHMac.BlockUpdate(mV, 0, mV.Length); + mHMac.DoFinal(mV, 0); + + Array.Copy(mV, 0, rv, m * mV.Length, rv.Length - (m * mV.Length)); + } + + hmac_DRBG_Update(additionalInput); + + mReseedCounter++; + + Array.Copy(rv, 0, output, 0, output.Length); + + return numberOfBits; + } + + /** + * Reseed the DRBG. + * + * @param additionalInput additional input to be added to the DRBG in this step. + */ + public void Reseed(byte[] additionalInput) + { + byte[] entropy = GetEntropy(); + byte[] seedMaterial = Arrays.Concatenate(entropy, additionalInput); + + hmac_DRBG_Update(seedMaterial); + + mReseedCounter = 1; + } + + private byte[] GetEntropy() + { + byte[] entropy = mEntropySource.GetEntropy(); + if (entropy.Length < (mSecurityStrength + 7) / 8) + throw new InvalidOperationException("Insufficient entropy provided by entropy source"); + return entropy; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/drbg/HMacSP800Drbg.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/drbg/HMacSP800Drbg.cs.meta new file mode 100644 index 0000000..9486ed5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/drbg/HMacSP800Drbg.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 694f5d46510a82f45874d6dcbf311cd1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/drbg/HashSP800Drbg.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/drbg/HashSP800Drbg.cs new file mode 100644 index 0000000..493da5a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/drbg/HashSP800Drbg.cs @@ -0,0 +1,287 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Prng.Drbg +{ + /** + * A SP800-90A Hash DRBG. + */ + public class HashSP800Drbg + : ISP80090Drbg + { + private readonly static byte[] ONE = { 0x01 }; + + private readonly static long RESEED_MAX = 1L << (48 - 1); + private readonly static int MAX_BITS_REQUEST = 1 << (19 - 1); + + private static readonly IDictionary seedlens = Platform.CreateHashtable(); + + static HashSP800Drbg() + { + seedlens.Add("SHA-1", 440); + seedlens.Add("SHA-224", 440); + seedlens.Add("SHA-256", 440); + seedlens.Add("SHA-512/256", 440); + seedlens.Add("SHA-512/224", 440); + seedlens.Add("SHA-384", 888); + seedlens.Add("SHA-512", 888); + } + + private readonly IDigest mDigest; + private readonly IEntropySource mEntropySource; + private readonly int mSecurityStrength; + private readonly int mSeedLength; + + private byte[] mV; + private byte[] mC; + private long mReseedCounter; + + /** + * Construct a SP800-90A Hash DRBG. + *

+ * Minimum entropy requirement is the security strength requested. + *

+ * @param digest source digest to use for DRB stream. + * @param securityStrength security strength required (in bits) + * @param entropySource source of entropy to use for seeding/reseeding. + * @param personalizationString personalization string to distinguish this DRBG (may be null). + * @param nonce nonce to further distinguish this DRBG (may be null). + */ + public HashSP800Drbg(IDigest digest, int securityStrength, IEntropySource entropySource, byte[] personalizationString, byte[] nonce) + { + if (securityStrength > DrbgUtilities.GetMaxSecurityStrength(digest)) + throw new ArgumentException("Requested security strength is not supported by the derivation function"); + if (entropySource.EntropySize < securityStrength) + throw new ArgumentException("Not enough entropy for security strength required"); + + mDigest = digest; + mEntropySource = entropySource; + mSecurityStrength = securityStrength; + mSeedLength = (int)seedlens[digest.AlgorithmName]; + + // 1. seed_material = entropy_input || nonce || personalization_string. + // 2. seed = Hash_df (seed_material, seedlen). + // 3. V = seed. + // 4. C = Hash_df ((0x00 || V), seedlen). Comment: Preceed V with a byte + // of zeros. + // 5. reseed_counter = 1. + // 6. Return V, C, and reseed_counter as the initial_working_state + + byte[] entropy = GetEntropy(); + byte[] seedMaterial = Arrays.ConcatenateAll(entropy, nonce, personalizationString); + byte[] seed = DrbgUtilities.HashDF(mDigest, seedMaterial, mSeedLength); + + mV = seed; + byte[] subV = new byte[mV.Length + 1]; + Array.Copy(mV, 0, subV, 1, mV.Length); + mC = DrbgUtilities.HashDF(mDigest, subV, mSeedLength); + + mReseedCounter = 1; + } + + /** + * Return the block size (in bits) of the DRBG. + * + * @return the number of bits produced on each internal round of the DRBG. + */ + public int BlockSize + { + get { return mDigest.GetDigestSize () * 8; } + } + + /** + * Populate a passed in array with random data. + * + * @param output output array for generated bits. + * @param additionalInput additional input to be added to the DRBG in this step. + * @param predictionResistant true if a reseed should be forced, false otherwise. + * + * @return number of bits generated, -1 if a reseed required. + */ + public int Generate(byte[] output, byte[] additionalInput, bool predictionResistant) + { + // 1. If reseed_counter > reseed_interval, then return an indication that a + // reseed is required. + // 2. If (additional_input != Null), then do + // 2.1 w = Hash (0x02 || V || additional_input). + // 2.2 V = (V + w) mod 2^seedlen + // . + // 3. (returned_bits) = Hashgen (requested_number_of_bits, V). + // 4. H = Hash (0x03 || V). + // 5. V = (V + H + C + reseed_counter) mod 2^seedlen + // . + // 6. reseed_counter = reseed_counter + 1. + // 7. Return SUCCESS, returned_bits, and the new values of V, C, and + // reseed_counter for the new_working_state. + int numberOfBits = output.Length * 8; + + if (numberOfBits > MAX_BITS_REQUEST) + throw new ArgumentException("Number of bits per request limited to " + MAX_BITS_REQUEST, "output"); + + if (mReseedCounter > RESEED_MAX) + return -1; + + if (predictionResistant) + { + Reseed(additionalInput); + additionalInput = null; + } + + // 2. + if (additionalInput != null) + { + byte[] newInput = new byte[1 + mV.Length + additionalInput.Length]; + newInput[0] = 0x02; + Array.Copy(mV, 0, newInput, 1, mV.Length); + // TODO: inOff / inLength + Array.Copy(additionalInput, 0, newInput, 1 + mV.Length, additionalInput.Length); + byte[] w = Hash(newInput); + + AddTo(mV, w); + } + + // 3. + byte[] rv = hashgen(mV, numberOfBits); + + // 4. + byte[] subH = new byte[mV.Length + 1]; + Array.Copy(mV, 0, subH, 1, mV.Length); + subH[0] = 0x03; + + byte[] H = Hash(subH); + + // 5. + AddTo(mV, H); + AddTo(mV, mC); + byte[] c = new byte[4]; + c[0] = (byte)(mReseedCounter >> 24); + c[1] = (byte)(mReseedCounter >> 16); + c[2] = (byte)(mReseedCounter >> 8); + c[3] = (byte)mReseedCounter; + + AddTo(mV, c); + + mReseedCounter++; + + Array.Copy(rv, 0, output, 0, output.Length); + + return numberOfBits; + } + + private byte[] GetEntropy() + { + byte[] entropy = mEntropySource.GetEntropy(); + if (entropy.Length < (mSecurityStrength + 7) / 8) + throw new InvalidOperationException("Insufficient entropy provided by entropy source"); + return entropy; + } + + // this will always add the shorter length byte array mathematically to the + // longer length byte array. + // be careful.... + private void AddTo(byte[] longer, byte[] shorter) + { + int off = longer.Length - shorter.Length; + + uint carry = 0; + int i = shorter.Length; + while (--i >= 0) + { + carry += (uint)longer[off + i] + (uint)shorter[i]; + longer[off + i] = (byte)carry; + carry >>= 8; + } + + i = off; + while (--i >= 0) + { + carry += longer[i]; + longer[i] = (byte)carry; + carry >>= 8; + } + } + + /** + * Reseed the DRBG. + * + * @param additionalInput additional input to be added to the DRBG in this step. + */ + public void Reseed(byte[] additionalInput) + { + // 1. seed_material = 0x01 || V || entropy_input || additional_input. + // + // 2. seed = Hash_df (seed_material, seedlen). + // + // 3. V = seed. + // + // 4. C = Hash_df ((0x00 || V), seedlen). + // + // 5. reseed_counter = 1. + // + // 6. Return V, C, and reseed_counter for the new_working_state. + // + // Comment: Precede with a byte of all zeros. + byte[] entropy = GetEntropy(); + byte[] seedMaterial = Arrays.ConcatenateAll(ONE, mV, entropy, additionalInput); + byte[] seed = DrbgUtilities.HashDF(mDigest, seedMaterial, mSeedLength); + + mV = seed; + byte[] subV = new byte[mV.Length + 1]; + subV[0] = 0x00; + Array.Copy(mV, 0, subV, 1, mV.Length); + mC = DrbgUtilities.HashDF(mDigest, subV, mSeedLength); + + mReseedCounter = 1; + } + + private byte[] Hash(byte[] input) + { + byte[] hash = new byte[mDigest.GetDigestSize()]; + DoHash(input, hash); + return hash; + } + + private void DoHash(byte[] input, byte[] output) + { + mDigest.BlockUpdate(input, 0, input.Length); + mDigest.DoFinal(output, 0); + } + + // 1. m = [requested_number_of_bits / outlen] + // 2. data = V. + // 3. W = the Null string. + // 4. For i = 1 to m + // 4.1 wi = Hash (data). + // 4.2 W = W || wi. + // 4.3 data = (data + 1) mod 2^seedlen + // . + // 5. returned_bits = Leftmost (requested_no_of_bits) bits of W. + private byte[] hashgen(byte[] input, int lengthInBits) + { + int digestSize = mDigest.GetDigestSize(); + int m = (lengthInBits / 8) / digestSize; + + byte[] data = new byte[input.Length]; + Array.Copy(input, 0, data, 0, input.Length); + + byte[] W = new byte[lengthInBits / 8]; + + byte[] dig = new byte[mDigest.GetDigestSize()]; + for (int i = 0; i <= m; i++) + { + DoHash(data, dig); + + int bytesToCopy = ((W.Length - i * dig.Length) > dig.Length) + ? dig.Length + : (W.Length - i * dig.Length); + Array.Copy(dig, 0, W, i * dig.Length, bytesToCopy); + + AddTo(data, ONE); + } + + return W; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/drbg/HashSP800Drbg.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/drbg/HashSP800Drbg.cs.meta new file mode 100644 index 0000000..298760e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/drbg/HashSP800Drbg.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bf93fea5c5a5f814cae055a08d157261 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/drbg/ISP80090Drbg.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/drbg/ISP80090Drbg.cs new file mode 100644 index 0000000..0e39820 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/drbg/ISP80090Drbg.cs @@ -0,0 +1,35 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Prng.Drbg +{ + /** + * Interface to SP800-90A deterministic random bit generators. + */ + public interface ISP80090Drbg + { + /** + * Return the block size of the DRBG. + * + * @return the block size (in bits) produced by each round of the DRBG. + */ + int BlockSize { get; } + + /** + * Populate a passed in array with random data. + * + * @param output output array for generated bits. + * @param additionalInput additional input to be added to the DRBG in this step. + * @param predictionResistant true if a reseed should be forced, false otherwise. + * + * @return number of bits generated, -1 if a reseed required. + */ + int Generate(byte[] output, byte[] additionalInput, bool predictionResistant); + + /** + * Reseed the DRBG. + * + * @param additionalInput additional input to be added to the DRBG in this step. + */ + void Reseed(byte[] additionalInput); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/drbg/ISP80090Drbg.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/drbg/ISP80090Drbg.cs.meta new file mode 100644 index 0000000..0fc4a9e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/prng/drbg/ISP80090Drbg.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a2f8654e6c18325438f3a40fb44a94d5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers.meta new file mode 100644 index 0000000..96f44d5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: baccd11e486307b4c8cc43b85a245ae9 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/DsaDigestSigner.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/DsaDigestSigner.cs new file mode 100644 index 0000000..15444a0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/DsaDigestSigner.cs @@ -0,0 +1,146 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Signers +{ + public class DsaDigestSigner + : ISigner + { + private readonly IDsa dsa; + private readonly IDigest digest; + private readonly IDsaEncoding encoding; + private bool forSigning; + + public DsaDigestSigner( + IDsa dsa, + IDigest digest) + { + this.dsa = dsa; + this.digest = digest; + this.encoding = StandardDsaEncoding.Instance; + } + + public DsaDigestSigner( + IDsaExt dsa, + IDigest digest, + IDsaEncoding encoding) + { + this.dsa = dsa; + this.digest = digest; + this.encoding = encoding; + } + + public virtual string AlgorithmName + { + get { return digest.AlgorithmName + "with" + dsa.AlgorithmName; } + } + + public virtual void Init( + bool forSigning, + ICipherParameters parameters) + { + this.forSigning = forSigning; + + AsymmetricKeyParameter k; + + if (parameters is ParametersWithRandom) + { + k = (AsymmetricKeyParameter)((ParametersWithRandom)parameters).Parameters; + } + else + { + k = (AsymmetricKeyParameter)parameters; + } + + if (forSigning && !k.IsPrivate) + throw new InvalidKeyException("Signing Requires Private Key."); + + if (!forSigning && k.IsPrivate) + throw new InvalidKeyException("Verification Requires Public Key."); + + Reset(); + + dsa.Init(forSigning, parameters); + } + + /** + * update the internal digest with the byte b + */ + public virtual void Update( + byte input) + { + digest.Update(input); + } + + /** + * update the internal digest with the byte array in + */ + public virtual void BlockUpdate( + byte[] input, + int inOff, + int length) + { + digest.BlockUpdate(input, inOff, length); + } + + /** + * Generate a signature for the message we've been loaded with using + * the key we were initialised with. + */ + public virtual byte[] GenerateSignature() + { + if (!forSigning) + throw new InvalidOperationException("DSADigestSigner not initialised for signature generation."); + + byte[] hash = new byte[digest.GetDigestSize()]; + digest.DoFinal(hash, 0); + + BigInteger[] sig = dsa.GenerateSignature(hash); + + try + { + return encoding.Encode(GetOrder(), sig[0], sig[1]); + } + catch (Exception) + { + throw new InvalidOperationException("unable to encode signature"); + } + } + + /// true if the internal state represents the signature described in the passed in array. + public virtual bool VerifySignature( + byte[] signature) + { + if (forSigning) + throw new InvalidOperationException("DSADigestSigner not initialised for verification"); + + byte[] hash = new byte[digest.GetDigestSize()]; + digest.DoFinal(hash, 0); + + try + { + BigInteger[] sig = encoding.Decode(GetOrder(), signature); + + return dsa.VerifySignature(hash, sig[0], sig[1]); + } + catch (Exception) + { + return false; + } + } + + /// Reset the internal state + public virtual void Reset() + { + digest.Reset(); + } + + protected virtual BigInteger GetOrder() + { + return dsa is IDsaExt ? ((IDsaExt)dsa).Order : null; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/DsaDigestSigner.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/DsaDigestSigner.cs.meta new file mode 100644 index 0000000..1c26d7f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/DsaDigestSigner.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 310d2134fcc6ed640b93ab2228271b7d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/DsaSigner.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/DsaSigner.cs new file mode 100644 index 0000000..1f5d9b9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/DsaSigner.cs @@ -0,0 +1,161 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Signers +{ + /** + * The Digital Signature Algorithm - as described in "Handbook of Applied + * Cryptography", pages 452 - 453. + */ + public class DsaSigner + : IDsaExt + { + protected readonly IDsaKCalculator kCalculator; + + protected DsaKeyParameters key = null; + protected SecureRandom random = null; + + /** + * Default configuration, random K values. + */ + public DsaSigner() + { + this.kCalculator = new RandomDsaKCalculator(); + } + + /** + * Configuration with an alternate, possibly deterministic calculator of K. + * + * @param kCalculator a K value calculator. + */ + public DsaSigner(IDsaKCalculator kCalculator) + { + this.kCalculator = kCalculator; + } + + public virtual string AlgorithmName + { + get { return "DSA"; } + } + + public virtual void Init(bool forSigning, ICipherParameters parameters) + { + SecureRandom providedRandom = null; + + if (forSigning) + { + if (parameters is ParametersWithRandom) + { + ParametersWithRandom rParam = (ParametersWithRandom)parameters; + + providedRandom = rParam.Random; + parameters = rParam.Parameters; + } + + if (!(parameters is DsaPrivateKeyParameters)) + throw new InvalidKeyException("DSA private key required for signing"); + + this.key = (DsaPrivateKeyParameters)parameters; + } + else + { + if (!(parameters is DsaPublicKeyParameters)) + throw new InvalidKeyException("DSA public key required for verification"); + + this.key = (DsaPublicKeyParameters)parameters; + } + + this.random = InitSecureRandom(forSigning && !kCalculator.IsDeterministic, providedRandom); + } + + public virtual BigInteger Order + { + get { return key.Parameters.Q; } + } + + /** + * Generate a signature for the given message using the key we were + * initialised with. For conventional DSA the message should be a SHA-1 + * hash of the message of interest. + * + * @param message the message that will be verified later. + */ + public virtual BigInteger[] GenerateSignature(byte[] message) + { + DsaParameters parameters = key.Parameters; + BigInteger q = parameters.Q; + BigInteger m = CalculateE(q, message); + BigInteger x = ((DsaPrivateKeyParameters)key).X; + + if (kCalculator.IsDeterministic) + { + kCalculator.Init(q, x, message); + } + else + { + kCalculator.Init(q, random); + } + + BigInteger k = kCalculator.NextK(); + + BigInteger r = parameters.G.ModPow(k, parameters.P).Mod(q); + + k = BigIntegers.ModOddInverse(q, k).Multiply(m.Add(x.Multiply(r))); + + BigInteger s = k.Mod(q); + + return new BigInteger[]{ r, s }; + } + + /** + * return true if the value r and s represent a DSA signature for + * the passed in message for standard DSA the message should be a + * SHA-1 hash of the real message to be verified. + */ + public virtual bool VerifySignature(byte[] message, BigInteger r, BigInteger s) + { + DsaParameters parameters = key.Parameters; + BigInteger q = parameters.Q; + BigInteger m = CalculateE(q, message); + + if (r.SignValue <= 0 || q.CompareTo(r) <= 0) + { + return false; + } + + if (s.SignValue <= 0 || q.CompareTo(s) <= 0) + { + return false; + } + + BigInteger w = BigIntegers.ModOddInverseVar(q, s); + + BigInteger u1 = m.Multiply(w).Mod(q); + BigInteger u2 = r.Multiply(w).Mod(q); + + BigInteger p = parameters.P; + u1 = parameters.G.ModPow(u1, p); + u2 = ((DsaPublicKeyParameters)key).Y.ModPow(u2, p); + + BigInteger v = u1.Multiply(u2).Mod(p).Mod(q); + + return v.Equals(r); + } + + protected virtual BigInteger CalculateE(BigInteger n, byte[] message) + { + int length = System.Math.Min(message.Length, n.BitLength / 8); + + return new BigInteger(1, message, 0, length); + } + + protected virtual SecureRandom InitSecureRandom(bool needed, SecureRandom provided) + { + return !needed ? null : (provided != null) ? provided : new SecureRandom(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/DsaSigner.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/DsaSigner.cs.meta new file mode 100644 index 0000000..3868680 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/DsaSigner.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a195b9e59a0ec5949a69816d457a3b3e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/ECDsaSigner.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/ECDsaSigner.cs new file mode 100644 index 0000000..0a265d9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/ECDsaSigner.cs @@ -0,0 +1,246 @@ +using System; + +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Math.EC.Multiplier; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Signers +{ + /** + * EC-DSA as described in X9.62 + */ + public class ECDsaSigner + : IDsaExt + { + private static readonly BigInteger Eight = BigInteger.ValueOf(8); + + protected readonly IDsaKCalculator kCalculator; + + protected ECKeyParameters key = null; + protected SecureRandom random = null; + + /** + * Default configuration, random K values. + */ + public ECDsaSigner() + { + this.kCalculator = new RandomDsaKCalculator(); + } + + /** + * Configuration with an alternate, possibly deterministic calculator of K. + * + * @param kCalculator a K value calculator. + */ + public ECDsaSigner(IDsaKCalculator kCalculator) + { + this.kCalculator = kCalculator; + } + + public virtual string AlgorithmName + { + get { return "ECDSA"; } + } + + public virtual void Init(bool forSigning, ICipherParameters parameters) + { + SecureRandom providedRandom = null; + + if (forSigning) + { + if (parameters is ParametersWithRandom) + { + ParametersWithRandom rParam = (ParametersWithRandom)parameters; + + providedRandom = rParam.Random; + parameters = rParam.Parameters; + } + + if (!(parameters is ECPrivateKeyParameters)) + throw new InvalidKeyException("EC private key required for signing"); + + this.key = (ECPrivateKeyParameters)parameters; + } + else + { + if (!(parameters is ECPublicKeyParameters)) + throw new InvalidKeyException("EC public key required for verification"); + + this.key = (ECPublicKeyParameters)parameters; + } + + this.random = InitSecureRandom(forSigning && !kCalculator.IsDeterministic, providedRandom); + } + + public virtual BigInteger Order + { + get { return key.Parameters.N; } + } + + // 5.3 pg 28 + /** + * Generate a signature for the given message using the key we were + * initialised with. For conventional DSA the message should be a SHA-1 + * hash of the message of interest. + * + * @param message the message that will be verified later. + */ + public virtual BigInteger[] GenerateSignature(byte[] message) + { + ECDomainParameters ec = key.Parameters; + BigInteger n = ec.N; + BigInteger e = CalculateE(n, message); + BigInteger d = ((ECPrivateKeyParameters)key).D; + + if (kCalculator.IsDeterministic) + { + kCalculator.Init(n, d, message); + } + else + { + kCalculator.Init(n, random); + } + + BigInteger r, s; + + ECMultiplier basePointMultiplier = CreateBasePointMultiplier(); + + // 5.3.2 + do // Generate s + { + BigInteger k; + do // Generate r + { + k = kCalculator.NextK(); + + ECPoint p = basePointMultiplier.Multiply(ec.G, k).Normalize(); + + // 5.3.3 + r = p.AffineXCoord.ToBigInteger().Mod(n); + } + while (r.SignValue == 0); + + s = BigIntegers.ModOddInverse(n, k).Multiply(e.Add(d.Multiply(r))).Mod(n); + } + while (s.SignValue == 0); + + return new BigInteger[]{ r, s }; + } + + // 5.4 pg 29 + /** + * return true if the value r and s represent a DSA signature for + * the passed in message (for standard DSA the message should be + * a SHA-1 hash of the real message to be verified). + */ + public virtual bool VerifySignature(byte[] message, BigInteger r, BigInteger s) + { + BigInteger n = key.Parameters.N; + + // r and s should both in the range [1,n-1] + if (r.SignValue < 1 || s.SignValue < 1 + || r.CompareTo(n) >= 0 || s.CompareTo(n) >= 0) + { + return false; + } + + BigInteger e = CalculateE(n, message); + BigInteger c = BigIntegers.ModOddInverseVar(n, s); + + BigInteger u1 = e.Multiply(c).Mod(n); + BigInteger u2 = r.Multiply(c).Mod(n); + + ECPoint G = key.Parameters.G; + ECPoint Q = ((ECPublicKeyParameters) key).Q; + + ECPoint point = ECAlgorithms.SumOfTwoMultiplies(G, u1, Q, u2); + + if (point.IsInfinity) + return false; + + /* + * If possible, avoid normalizing the point (to save a modular inversion in the curve field). + * + * There are ~cofactor elements of the curve field that reduce (modulo the group order) to 'r'. + * If the cofactor is known and small, we generate those possible field values and project each + * of them to the same "denominator" (depending on the particular projective coordinates in use) + * as the calculated point.X. If any of the projected values matches point.X, then we have: + * (point.X / Denominator mod p) mod n == r + * as required, and verification succeeds. + * + * Based on an original idea by Gregory Maxwell (https://github.com/gmaxwell), as implemented in + * the libsecp256k1 project (https://github.com/bitcoin/secp256k1). + */ + ECCurve curve = point.Curve; + if (curve != null) + { + BigInteger cofactor = curve.Cofactor; + if (cofactor != null && cofactor.CompareTo(Eight) <= 0) + { + ECFieldElement D = GetDenominator(curve.CoordinateSystem, point); + if (D != null && !D.IsZero) + { + ECFieldElement X = point.XCoord; + while (curve.IsValidFieldElement(r)) + { + ECFieldElement R = curve.FromBigInteger(r).Multiply(D); + if (R.Equals(X)) + { + return true; + } + r = r.Add(n); + } + return false; + } + } + } + + BigInteger v = point.Normalize().AffineXCoord.ToBigInteger().Mod(n); + return v.Equals(r); + } + + protected virtual BigInteger CalculateE(BigInteger n, byte[] message) + { + int messageBitLength = message.Length * 8; + BigInteger trunc = new BigInteger(1, message); + + if (n.BitLength < messageBitLength) + { + trunc = trunc.ShiftRight(messageBitLength - n.BitLength); + } + + return trunc; + } + + protected virtual ECMultiplier CreateBasePointMultiplier() + { + return new FixedPointCombMultiplier(); + } + + protected virtual ECFieldElement GetDenominator(int coordinateSystem, ECPoint p) + { + switch (coordinateSystem) + { + case ECCurve.COORD_HOMOGENEOUS: + case ECCurve.COORD_LAMBDA_PROJECTIVE: + case ECCurve.COORD_SKEWED: + return p.GetZCoord(0); + case ECCurve.COORD_JACOBIAN: + case ECCurve.COORD_JACOBIAN_CHUDNOVSKY: + case ECCurve.COORD_JACOBIAN_MODIFIED: + return p.GetZCoord(0).Square(); + default: + return null; + } + } + + protected virtual SecureRandom InitSecureRandom(bool needed, SecureRandom provided) + { + return !needed ? null : (provided != null) ? provided : new SecureRandom(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/ECDsaSigner.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/ECDsaSigner.cs.meta new file mode 100644 index 0000000..0ea4626 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/ECDsaSigner.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3d48815d5e1b1244487f0a535c4ba74b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/ECGOST3410Signer.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/ECGOST3410Signer.cs new file mode 100644 index 0000000..7df43f0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/ECGOST3410Signer.cs @@ -0,0 +1,171 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Math.EC.Multiplier; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Signers +{ + /** + * GOST R 34.10-2001 Signature Algorithm + */ + public class ECGost3410Signer + : IDsaExt + { + private ECKeyParameters key; + private SecureRandom random; + private bool forSigning; + + public virtual string AlgorithmName + { + get { return key.AlgorithmName; } + } + + public virtual void Init( + bool forSigning, + ICipherParameters parameters) + { + this.forSigning = forSigning; + + if (forSigning) + { + if (parameters is ParametersWithRandom) + { + ParametersWithRandom rParam = (ParametersWithRandom)parameters; + + this.random = rParam.Random; + parameters = rParam.Parameters; + } + else + { + this.random = new SecureRandom(); + } + + if (!(parameters is ECPrivateKeyParameters)) + throw new InvalidKeyException("EC private key required for signing"); + + this.key = (ECPrivateKeyParameters) parameters; + } + else + { + if (!(parameters is ECPublicKeyParameters)) + throw new InvalidKeyException("EC public key required for verification"); + + this.key = (ECPublicKeyParameters)parameters; + } + } + + public virtual BigInteger Order + { + get { return key.Parameters.N; } + } + + /** + * generate a signature for the given message using the key we were + * initialised with. For conventional GOST3410 the message should be a GOST3411 + * hash of the message of interest. + * + * @param message the message that will be verified later. + */ + public virtual BigInteger[] GenerateSignature( + byte[] message) + { + if (!forSigning) + { + throw new InvalidOperationException("not initialized for signing"); + } + + byte[] mRev = Arrays.Reverse(message); // conversion is little-endian + BigInteger e = new BigInteger(1, mRev); + + ECDomainParameters ec = key.Parameters; + BigInteger n = ec.N; + BigInteger d = ((ECPrivateKeyParameters)key).D; + + BigInteger r, s = null; + + ECMultiplier basePointMultiplier = CreateBasePointMultiplier(); + + do // generate s + { + BigInteger k; + do // generate r + { + do + { + k = new BigInteger(n.BitLength, random); + } + while (k.SignValue == 0); + + ECPoint p = basePointMultiplier.Multiply(ec.G, k).Normalize(); + + r = p.AffineXCoord.ToBigInteger().Mod(n); + } + while (r.SignValue == 0); + + s = (k.Multiply(e)).Add(d.Multiply(r)).Mod(n); + } + while (s.SignValue == 0); + + return new BigInteger[]{ r, s }; + } + + /** + * return true if the value r and s represent a GOST3410 signature for + * the passed in message (for standard GOST3410 the message should be + * a GOST3411 hash of the real message to be verified). + */ + public virtual bool VerifySignature( + byte[] message, + BigInteger r, + BigInteger s) + { + if (forSigning) + { + throw new InvalidOperationException("not initialized for verification"); + } + + byte[] mRev = Arrays.Reverse(message); // conversion is little-endian + BigInteger e = new BigInteger(1, mRev); + BigInteger n = key.Parameters.N; + + // r in the range [1,n-1] + if (r.CompareTo(BigInteger.One) < 0 || r.CompareTo(n) >= 0) + { + return false; + } + + // s in the range [1,n-1] + if (s.CompareTo(BigInteger.One) < 0 || s.CompareTo(n) >= 0) + { + return false; + } + + BigInteger v = BigIntegers.ModOddInverseVar(n, e); + + BigInteger z1 = s.Multiply(v).Mod(n); + BigInteger z2 = (n.Subtract(r)).Multiply(v).Mod(n); + + ECPoint G = key.Parameters.G; // P + ECPoint Q = ((ECPublicKeyParameters)key).Q; + + ECPoint point = ECAlgorithms.SumOfTwoMultiplies(G, z1, Q, z2).Normalize(); + + if (point.IsInfinity) + return false; + + BigInteger R = point.AffineXCoord.ToBigInteger().Mod(n); + + return R.Equals(r); + } + + protected virtual ECMultiplier CreateBasePointMultiplier() + { + return new FixedPointCombMultiplier(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/ECGOST3410Signer.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/ECGOST3410Signer.cs.meta new file mode 100644 index 0000000..8d18bd5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/ECGOST3410Signer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9f7ea84e7f50ebf4f9f7da88a6f1c2cf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/ECNRSigner.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/ECNRSigner.cs new file mode 100644 index 0000000..bc193e7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/ECNRSigner.cs @@ -0,0 +1,193 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Signers +{ + /** + * EC-NR as described in IEEE 1363-2000 + */ + public class ECNRSigner + : IDsaExt + { + private bool forSigning; + private ECKeyParameters key; + private SecureRandom random; + + public virtual string AlgorithmName + { + get { return "ECNR"; } + } + + public virtual void Init( + bool forSigning, + ICipherParameters parameters) + { + this.forSigning = forSigning; + + if (forSigning) + { + if (parameters is ParametersWithRandom) + { + ParametersWithRandom rParam = (ParametersWithRandom) parameters; + + this.random = rParam.Random; + parameters = rParam.Parameters; + } + else + { + this.random = new SecureRandom(); + } + + if (!(parameters is ECPrivateKeyParameters)) + throw new InvalidKeyException("EC private key required for signing"); + + this.key = (ECPrivateKeyParameters) parameters; + } + else + { + if (!(parameters is ECPublicKeyParameters)) + throw new InvalidKeyException("EC public key required for verification"); + + this.key = (ECPublicKeyParameters) parameters; + } + } + + public virtual BigInteger Order + { + get { return key.Parameters.N; } + } + + // Section 7.2.5 ECSP-NR, pg 34 + /** + * generate a signature for the given message using the key we were + * initialised with. Generally, the order of the curve should be at + * least as long as the hash of the message of interest, and with + * ECNR it *must* be at least as long. + * + * @param digest the digest to be signed. + * @exception DataLengthException if the digest is longer than the key allows + */ + public virtual BigInteger[] GenerateSignature( + byte[] message) + { + if (!this.forSigning) + { + // not properly initilaized... deal with it + throw new InvalidOperationException("not initialised for signing"); + } + + BigInteger n = Order; + int nBitLength = n.BitLength; + + BigInteger e = new BigInteger(1, message); + int eBitLength = e.BitLength; + + ECPrivateKeyParameters privKey = (ECPrivateKeyParameters)key; + + if (eBitLength > nBitLength) + { + throw new DataLengthException("input too large for ECNR key."); + } + + BigInteger r = null; + BigInteger s = null; + + AsymmetricCipherKeyPair tempPair; + do // generate r + { + // generate another, but very temporary, key pair using + // the same EC parameters + ECKeyPairGenerator keyGen = new ECKeyPairGenerator(); + + keyGen.Init(new ECKeyGenerationParameters(privKey.Parameters, this.random)); + + tempPair = keyGen.GenerateKeyPair(); + + // BigInteger Vx = tempPair.getPublic().getW().getAffineX(); + ECPublicKeyParameters V = (ECPublicKeyParameters) tempPair.Public; // get temp's public key + BigInteger Vx = V.Q.AffineXCoord.ToBigInteger(); // get the point's x coordinate + + r = Vx.Add(e).Mod(n); + } + while (r.SignValue == 0); + + // generate s + BigInteger x = privKey.D; // private key value + BigInteger u = ((ECPrivateKeyParameters) tempPair.Private).D; // temp's private key value + s = u.Subtract(r.Multiply(x)).Mod(n); + + return new BigInteger[]{ r, s }; + } + + // Section 7.2.6 ECVP-NR, pg 35 + /** + * return true if the value r and s represent a signature for the + * message passed in. Generally, the order of the curve should be at + * least as long as the hash of the message of interest, and with + * ECNR, it *must* be at least as long. But just in case the signer + * applied mod(n) to the longer digest, this implementation will + * apply mod(n) during verification. + * + * @param digest the digest to be verified. + * @param r the r value of the signature. + * @param s the s value of the signature. + * @exception DataLengthException if the digest is longer than the key allows + */ + public virtual bool VerifySignature( + byte[] message, + BigInteger r, + BigInteger s) + { + if (this.forSigning) + { + // not properly initilaized... deal with it + throw new InvalidOperationException("not initialised for verifying"); + } + + ECPublicKeyParameters pubKey = (ECPublicKeyParameters)key; + BigInteger n = pubKey.Parameters.N; + int nBitLength = n.BitLength; + + BigInteger e = new BigInteger(1, message); + int eBitLength = e.BitLength; + + if (eBitLength > nBitLength) + { + throw new DataLengthException("input too large for ECNR key."); + } + + // r in the range [1,n-1] + if (r.CompareTo(BigInteger.One) < 0 || r.CompareTo(n) >= 0) + { + return false; + } + + // s in the range [0,n-1] NB: ECNR spec says 0 + if (s.CompareTo(BigInteger.Zero) < 0 || s.CompareTo(n) >= 0) + { + return false; + } + + // compute P = sG + rW + + ECPoint G = pubKey.Parameters.G; + ECPoint W = pubKey.Q; + // calculate P using Bouncy math + ECPoint P = ECAlgorithms.SumOfTwoMultiplies(G, s, W, r).Normalize(); + + if (P.IsInfinity) + return false; + + BigInteger x = P.AffineXCoord.ToBigInteger(); + BigInteger t = r.Subtract(x).Mod(n); + + return t.Equals(e); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/ECNRSigner.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/ECNRSigner.cs.meta new file mode 100644 index 0000000..f490a7f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/ECNRSigner.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7bc237e3a39202642ae2efc15d0e282d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/Ed25519Signer.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/Ed25519Signer.cs new file mode 100644 index 0000000..eb3d253 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/Ed25519Signer.cs @@ -0,0 +1,138 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math.EC.Rfc8032; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Crypto.Signers +{ + public class Ed25519Signer + : ISigner + { + private readonly Buffer buffer = new Buffer(); + + private bool forSigning; + private Ed25519PrivateKeyParameters privateKey; + private Ed25519PublicKeyParameters publicKey; + + public Ed25519Signer() + { + } + + public virtual string AlgorithmName + { + get { return "Ed25519"; } + } + + public virtual void Init(bool forSigning, ICipherParameters parameters) + { + this.forSigning = forSigning; + + if (forSigning) + { + this.privateKey = (Ed25519PrivateKeyParameters)parameters; + this.publicKey = null; + } + else + { + this.privateKey = null; + this.publicKey = (Ed25519PublicKeyParameters)parameters; + } + + Reset(); + } + + public virtual void Update(byte b) + { + buffer.WriteByte(b); + } + + public virtual void BlockUpdate(byte[] buf, int off, int len) + { + buffer.Write(buf, off, len); + } + + public virtual byte[] GenerateSignature() + { + if (!forSigning || null == privateKey) + throw new InvalidOperationException("Ed25519Signer not initialised for signature generation."); + + return buffer.GenerateSignature(privateKey); + } + + public virtual bool VerifySignature(byte[] signature) + { + if (forSigning || null == publicKey) + throw new InvalidOperationException("Ed25519Signer not initialised for verification"); + + return buffer.VerifySignature(publicKey, signature); + } + + public virtual void Reset() + { + buffer.Reset(); + } + + private class Buffer : MemoryStream + { + internal byte[] GenerateSignature(Ed25519PrivateKeyParameters privateKey) + { + lock (this) + { +#if PORTABLE + byte[] buf = ToArray(); + int count = buf.Length; +#else + byte[] buf = GetBuffer(); + int count = (int)Position; +#endif + byte[] signature = new byte[Ed25519PrivateKeyParameters.SignatureSize]; + privateKey.Sign(Ed25519.Algorithm.Ed25519, null, buf, 0, count, signature, 0); + Reset(); + return signature; + } + } + + internal bool VerifySignature(Ed25519PublicKeyParameters publicKey, byte[] signature) + { + if (Ed25519.SignatureSize != signature.Length) + { + Reset(); + return false; + } + + lock (this) + { +#if PORTABLE + byte[] buf = ToArray(); + int count = buf.Length; +#else + byte[] buf = GetBuffer(); + int count = (int)Position; +#endif + byte[] pk = publicKey.GetEncoded(); + bool result = Ed25519.Verify(signature, 0, pk, 0, buf, 0, count); + Reset(); + return result; + } + } + + internal void Reset() + { + lock (this) + { + long count = Position; +#if PORTABLE + this.Position = 0L; + Streams.WriteZeroes(this, count); +#else + Array.Clear(GetBuffer(), 0, (int)count); +#endif + this.Position = 0L; + } + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/Ed25519Signer.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/Ed25519Signer.cs.meta new file mode 100644 index 0000000..836aee2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/Ed25519Signer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 092e6038228891045b1c07fca5ef204b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/Ed25519ctxSigner.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/Ed25519ctxSigner.cs new file mode 100644 index 0000000..3610e25 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/Ed25519ctxSigner.cs @@ -0,0 +1,140 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math.EC.Rfc8032; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Crypto.Signers +{ + public class Ed25519ctxSigner + : ISigner + { + private readonly Buffer buffer = new Buffer(); + private readonly byte[] context; + + private bool forSigning; + private Ed25519PrivateKeyParameters privateKey; + private Ed25519PublicKeyParameters publicKey; + + public Ed25519ctxSigner(byte[] context) + { + this.context = Arrays.Clone(context); + } + + public virtual string AlgorithmName + { + get { return "Ed25519ctx"; } + } + + public virtual void Init(bool forSigning, ICipherParameters parameters) + { + this.forSigning = forSigning; + + if (forSigning) + { + this.privateKey = (Ed25519PrivateKeyParameters)parameters; + this.publicKey = null; + } + else + { + this.privateKey = null; + this.publicKey = (Ed25519PublicKeyParameters)parameters; + } + + Reset(); + } + + public virtual void Update(byte b) + { + buffer.WriteByte(b); + } + + public virtual void BlockUpdate(byte[] buf, int off, int len) + { + buffer.Write(buf, off, len); + } + + public virtual byte[] GenerateSignature() + { + if (!forSigning || null == privateKey) + throw new InvalidOperationException("Ed25519ctxSigner not initialised for signature generation."); + + return buffer.GenerateSignature(privateKey, context); + } + + public virtual bool VerifySignature(byte[] signature) + { + if (forSigning || null == publicKey) + throw new InvalidOperationException("Ed25519ctxSigner not initialised for verification"); + + return buffer.VerifySignature(publicKey, context, signature); + } + + public virtual void Reset() + { + buffer.Reset(); + } + + private class Buffer : MemoryStream + { + internal byte[] GenerateSignature(Ed25519PrivateKeyParameters privateKey, byte[] ctx) + { + lock (this) + { +#if PORTABLE + byte[] buf = ToArray(); + int count = buf.Length; +#else + byte[] buf = GetBuffer(); + int count = (int)Position; +#endif + byte[] signature = new byte[Ed25519PrivateKeyParameters.SignatureSize]; + privateKey.Sign(Ed25519.Algorithm.Ed25519ctx, ctx, buf, 0, count, signature, 0); + Reset(); + return signature; + } + } + + internal bool VerifySignature(Ed25519PublicKeyParameters publicKey, byte[] ctx, byte[] signature) + { + if (Ed25519.SignatureSize != signature.Length) + { + Reset(); + return false; + } + + lock (this) + { +#if PORTABLE + byte[] buf = ToArray(); + int count = buf.Length; +#else + byte[] buf = GetBuffer(); + int count = (int)Position; +#endif + byte[] pk = publicKey.GetEncoded(); + bool result = Ed25519.Verify(signature, 0, pk, 0, ctx, buf, 0, count); + Reset(); + return result; + } + } + + internal void Reset() + { + lock (this) + { + long count = Position; +#if PORTABLE + this.Position = 0L; + Streams.WriteZeroes(this, count); +#else + Array.Clear(GetBuffer(), 0, (int)count); +#endif + this.Position = 0L; + } + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/Ed25519ctxSigner.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/Ed25519ctxSigner.cs.meta new file mode 100644 index 0000000..49e0ae0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/Ed25519ctxSigner.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3ebcb50cfad7e9c488f28fb1dd7c3ecc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/Ed25519phSigner.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/Ed25519phSigner.cs new file mode 100644 index 0000000..8f4afab --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/Ed25519phSigner.cs @@ -0,0 +1,91 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math.EC.Rfc8032; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Signers +{ + public class Ed25519phSigner + : ISigner + { + private readonly IDigest prehash = Ed25519.CreatePrehash(); + private readonly byte[] context; + + private bool forSigning; + private Ed25519PrivateKeyParameters privateKey; + private Ed25519PublicKeyParameters publicKey; + + public Ed25519phSigner(byte[] context) + { + this.context = Arrays.Clone(context); + } + + public virtual string AlgorithmName + { + get { return "Ed25519ph"; } + } + + public virtual void Init(bool forSigning, ICipherParameters parameters) + { + this.forSigning = forSigning; + + if (forSigning) + { + this.privateKey = (Ed25519PrivateKeyParameters)parameters; + this.publicKey = null; + } + else + { + this.privateKey = null; + this.publicKey = (Ed25519PublicKeyParameters)parameters; + } + + Reset(); + } + + public virtual void Update(byte b) + { + prehash.Update(b); + } + + public virtual void BlockUpdate(byte[] buf, int off, int len) + { + prehash.BlockUpdate(buf, off, len); + } + + public virtual byte[] GenerateSignature() + { + if (!forSigning || null == privateKey) + throw new InvalidOperationException("Ed25519phSigner not initialised for signature generation."); + + byte[] msg = new byte[Ed25519.PrehashSize]; + if (Ed25519.PrehashSize != prehash.DoFinal(msg, 0)) + throw new InvalidOperationException("Prehash digest failed"); + + byte[] signature = new byte[Ed25519PrivateKeyParameters.SignatureSize]; + privateKey.Sign(Ed25519.Algorithm.Ed25519ph, context, msg, 0, Ed25519.PrehashSize, signature, 0); + return signature; + } + + public virtual bool VerifySignature(byte[] signature) + { + if (forSigning || null == publicKey) + throw new InvalidOperationException("Ed25519phSigner not initialised for verification"); + if (Ed25519.SignatureSize != signature.Length) + { + prehash.Reset(); + return false; + } + + byte[] pk = publicKey.GetEncoded(); + return Ed25519.VerifyPrehash(signature, 0, pk, 0, context, prehash); + } + + public void Reset() + { + prehash.Reset(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/Ed25519phSigner.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/Ed25519phSigner.cs.meta new file mode 100644 index 0000000..9ca4ac2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/Ed25519phSigner.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9221dd65317d1aa40b16ba2ea95172aa +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/Ed448Signer.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/Ed448Signer.cs new file mode 100644 index 0000000..7460298 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/Ed448Signer.cs @@ -0,0 +1,140 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math.EC.Rfc8032; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Crypto.Signers +{ + public class Ed448Signer + : ISigner + { + private readonly Buffer buffer = new Buffer(); + private readonly byte[] context; + + private bool forSigning; + private Ed448PrivateKeyParameters privateKey; + private Ed448PublicKeyParameters publicKey; + + public Ed448Signer(byte[] context) + { + this.context = Arrays.Clone(context); + } + + public virtual string AlgorithmName + { + get { return "Ed448"; } + } + + public virtual void Init(bool forSigning, ICipherParameters parameters) + { + this.forSigning = forSigning; + + if (forSigning) + { + this.privateKey = (Ed448PrivateKeyParameters)parameters; + this.publicKey = null; + } + else + { + this.privateKey = null; + this.publicKey = (Ed448PublicKeyParameters)parameters; + } + + Reset(); + } + + public virtual void Update(byte b) + { + buffer.WriteByte(b); + } + + public virtual void BlockUpdate(byte[] buf, int off, int len) + { + buffer.Write(buf, off, len); + } + + public virtual byte[] GenerateSignature() + { + if (!forSigning || null == privateKey) + throw new InvalidOperationException("Ed448Signer not initialised for signature generation."); + + return buffer.GenerateSignature(privateKey, context); + } + + public virtual bool VerifySignature(byte[] signature) + { + if (forSigning || null == publicKey) + throw new InvalidOperationException("Ed448Signer not initialised for verification"); + + return buffer.VerifySignature(publicKey, context, signature); + } + + public virtual void Reset() + { + buffer.Reset(); + } + + private class Buffer : MemoryStream + { + internal byte[] GenerateSignature(Ed448PrivateKeyParameters privateKey, byte[] ctx) + { + lock (this) + { +#if PORTABLE + byte[] buf = ToArray(); + int count = buf.Length; +#else + byte[] buf = GetBuffer(); + int count = (int)Position; +#endif + byte[] signature = new byte[Ed448PrivateKeyParameters.SignatureSize]; + privateKey.Sign(Ed448.Algorithm.Ed448, ctx, buf, 0, count, signature, 0); + Reset(); + return signature; + } + } + + internal bool VerifySignature(Ed448PublicKeyParameters publicKey, byte[] ctx, byte[] signature) + { + if (Ed448.SignatureSize != signature.Length) + { + Reset(); + return false; + } + + lock (this) + { +#if PORTABLE + byte[] buf = ToArray(); + int count = buf.Length; +#else + byte[] buf = GetBuffer(); + int count = (int)Position; +#endif + byte[] pk = publicKey.GetEncoded(); + bool result = Ed448.Verify(signature, 0, pk, 0, ctx, buf, 0, count); + Reset(); + return result; + } + } + + internal void Reset() + { + lock (this) + { + long count = Position; +#if PORTABLE + this.Position = 0L; + Streams.WriteZeroes(this, count); +#else + Array.Clear(GetBuffer(), 0, (int)count); +#endif + this.Position = 0L; + } + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/Ed448Signer.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/Ed448Signer.cs.meta new file mode 100644 index 0000000..3fa125d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/Ed448Signer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1b416d78f6c1fd341a023a8b79e8f429 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/Ed448phSigner.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/Ed448phSigner.cs new file mode 100644 index 0000000..197c2f7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/Ed448phSigner.cs @@ -0,0 +1,91 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math.EC.Rfc8032; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Signers +{ + public class Ed448phSigner + : ISigner + { + private readonly IXof prehash = Ed448.CreatePrehash(); + private readonly byte[] context; + + private bool forSigning; + private Ed448PrivateKeyParameters privateKey; + private Ed448PublicKeyParameters publicKey; + + public Ed448phSigner(byte[] context) + { + this.context = Arrays.Clone(context); + } + + public virtual string AlgorithmName + { + get { return "Ed448ph"; } + } + + public virtual void Init(bool forSigning, ICipherParameters parameters) + { + this.forSigning = forSigning; + + if (forSigning) + { + this.privateKey = (Ed448PrivateKeyParameters)parameters; + this.publicKey = null; + } + else + { + this.privateKey = null; + this.publicKey = (Ed448PublicKeyParameters)parameters; + } + + Reset(); + } + + public virtual void Update(byte b) + { + prehash.Update(b); + } + + public virtual void BlockUpdate(byte[] buf, int off, int len) + { + prehash.BlockUpdate(buf, off, len); + } + + public virtual byte[] GenerateSignature() + { + if (!forSigning || null == privateKey) + throw new InvalidOperationException("Ed448phSigner not initialised for signature generation."); + + byte[] msg = new byte[Ed448.PrehashSize]; + if (Ed448.PrehashSize != prehash.DoFinal(msg, 0, Ed448.PrehashSize)) + throw new InvalidOperationException("Prehash digest failed"); + + byte[] signature = new byte[Ed448PrivateKeyParameters.SignatureSize]; + privateKey.Sign(Ed448.Algorithm.Ed448ph, context, msg, 0, Ed448.PrehashSize, signature, 0); + return signature; + } + + public virtual bool VerifySignature(byte[] signature) + { + if (forSigning || null == publicKey) + throw new InvalidOperationException("Ed448phSigner not initialised for verification"); + if (Ed448.SignatureSize != signature.Length) + { + prehash.Reset(); + return false; + } + + byte[] pk = publicKey.GetEncoded(); + return Ed448.VerifyPrehash(signature, 0, pk, 0, context, prehash); + } + + public void Reset() + { + prehash.Reset(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/Ed448phSigner.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/Ed448phSigner.cs.meta new file mode 100644 index 0000000..c67c172 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/Ed448phSigner.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2a6980ab5dff4844094f8ddfc9aef25a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/GOST3410DigestSigner.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/GOST3410DigestSigner.cs new file mode 100644 index 0000000..bff3586 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/GOST3410DigestSigner.cs @@ -0,0 +1,154 @@ +using System; +using System.Collections; +using System.IO; +using System.Text; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Crypto.Signers; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Signers +{ + public class Gost3410DigestSigner + : ISigner + { + private readonly IDigest digest; + private readonly IDsa dsaSigner; + private readonly int size; + private int halfSize; + private bool forSigning; + + + + public Gost3410DigestSigner( + IDsa signer, + IDigest digest) + { + this.dsaSigner = signer; + this.digest = digest; + + halfSize = digest.GetDigestSize(); + this.size = halfSize * 2; + + } + + public virtual string AlgorithmName + { + get { return digest.AlgorithmName + "with" + dsaSigner.AlgorithmName; } + } + + public virtual void Init( + bool forSigning, + ICipherParameters parameters) + { + this.forSigning = forSigning; + + AsymmetricKeyParameter k; + if (parameters is ParametersWithRandom) + { + k = (AsymmetricKeyParameter)((ParametersWithRandom)parameters).Parameters; + } + else + { + k = (AsymmetricKeyParameter)parameters; + } + + if (forSigning && !k.IsPrivate) + { + throw new InvalidKeyException("Signing Requires Private Key."); + } + + if (!forSigning && k.IsPrivate) + { + throw new InvalidKeyException("Verification Requires Public Key."); + } + + + Reset(); + + dsaSigner.Init(forSigning, parameters); + } + + /** + * update the internal digest with the byte b + */ + public virtual void Update( + byte input) + { + digest.Update(input); + } + + /** + * update the internal digest with the byte array in + */ + public virtual void BlockUpdate( + byte[] input, + int inOff, + int length) + { + digest.BlockUpdate(input, inOff, length); + } + + /** + * Generate a signature for the message we've been loaded with using + * the key we were initialised with. + */ + public virtual byte[] GenerateSignature() + { + if (!forSigning) + throw new InvalidOperationException("GOST3410DigestSigner not initialised for signature generation."); + + byte[] hash = new byte[digest.GetDigestSize()]; + digest.DoFinal(hash, 0); + + try + { + BigInteger[] sig = dsaSigner.GenerateSignature(hash); + byte[] sigBytes = new byte[size]; + + // TODO Add methods to allow writing BigInteger to existing byte array? + byte[] r = sig[0].ToByteArrayUnsigned(); + byte[] s = sig[1].ToByteArrayUnsigned(); + s.CopyTo(sigBytes, halfSize - s.Length); + r.CopyTo(sigBytes, size - r.Length); + return sigBytes; + } + catch (Exception e) + { + throw new SignatureException(e.Message, e); + } + } + + /// true if the internal state represents the signature described in the passed in array. + public virtual bool VerifySignature( + byte[] signature) + { + if (forSigning) + throw new InvalidOperationException("DSADigestSigner not initialised for verification"); + + byte[] hash = new byte[digest.GetDigestSize()]; + digest.DoFinal(hash, 0); + + BigInteger R, S; + try + { + R = new BigInteger(1, signature, halfSize, halfSize); + S = new BigInteger(1, signature, 0, halfSize); + } + catch (Exception e) + { + throw new SignatureException("error decoding signature bytes.", e); + } + + return dsaSigner.VerifySignature(hash, R, S); + } + + /// Reset the internal state + public virtual void Reset() + { + digest.Reset(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/GOST3410DigestSigner.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/GOST3410DigestSigner.cs.meta new file mode 100644 index 0000000..61c8ffa --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/GOST3410DigestSigner.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 77b5b8069a14c2343a2d5b692660b893 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/GOST3410Signer.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/GOST3410Signer.cs new file mode 100644 index 0000000..bcc1125 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/GOST3410Signer.cs @@ -0,0 +1,128 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Signers +{ + /** + * Gost R 34.10-94 Signature Algorithm + */ + public class Gost3410Signer + : IDsaExt + { + private Gost3410KeyParameters key; + private SecureRandom random; + + public virtual string AlgorithmName + { + get { return "GOST3410"; } + } + + public virtual void Init( + bool forSigning, + ICipherParameters parameters) + { + if (forSigning) + { + if (parameters is ParametersWithRandom) + { + ParametersWithRandom rParam = (ParametersWithRandom)parameters; + + this.random = rParam.Random; + parameters = rParam.Parameters; + } + else + { + this.random = new SecureRandom(); + } + + if (!(parameters is Gost3410PrivateKeyParameters)) + throw new InvalidKeyException("GOST3410 private key required for signing"); + + this.key = (Gost3410PrivateKeyParameters) parameters; + } + else + { + if (!(parameters is Gost3410PublicKeyParameters)) + throw new InvalidKeyException("GOST3410 public key required for signing"); + + this.key = (Gost3410PublicKeyParameters) parameters; + } + } + + public virtual BigInteger Order + { + get { return key.Parameters.Q; } + } + + /** + * generate a signature for the given message using the key we were + * initialised with. For conventional Gost3410 the message should be a Gost3411 + * hash of the message of interest. + * + * @param message the message that will be verified later. + */ + public virtual BigInteger[] GenerateSignature( + byte[] message) + { + byte[] mRev = Arrays.Reverse(message); // conversion is little-endian + BigInteger m = new BigInteger(1, mRev); + Gost3410Parameters parameters = key.Parameters; + BigInteger k; + + do + { + k = new BigInteger(parameters.Q.BitLength, random); + } + while (k.CompareTo(parameters.Q) >= 0); + + BigInteger r = parameters.A.ModPow(k, parameters.P).Mod(parameters.Q); + + BigInteger s = k.Multiply(m). + Add(((Gost3410PrivateKeyParameters)key).X.Multiply(r)). + Mod(parameters.Q); + + return new BigInteger[]{ r, s }; + } + + /** + * return true if the value r and s represent a Gost3410 signature for + * the passed in message for standard Gost3410 the message should be a + * Gost3411 hash of the real message to be verified. + */ + public virtual bool VerifySignature( + byte[] message, + BigInteger r, + BigInteger s) + { + byte[] mRev = Arrays.Reverse(message); // conversion is little-endian + BigInteger m = new BigInteger(1, mRev); + Gost3410Parameters parameters = key.Parameters; + + if (r.SignValue < 0 || parameters.Q.CompareTo(r) <= 0) + { + return false; + } + + if (s.SignValue < 0 || parameters.Q.CompareTo(s) <= 0) + { + return false; + } + + BigInteger v = m.ModPow(parameters.Q.Subtract(BigInteger.Two), parameters.Q); + + BigInteger z1 = s.Multiply(v).Mod(parameters.Q); + BigInteger z2 = (parameters.Q.Subtract(r)).Multiply(v).Mod(parameters.Q); + + z1 = parameters.A.ModPow(z1, parameters.P); + z2 = ((Gost3410PublicKeyParameters)key).Y.ModPow(z2, parameters.P); + + BigInteger u = z1.Multiply(z2).Mod(parameters.P).Mod(parameters.Q); + + return u.Equals(r); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/GOST3410Signer.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/GOST3410Signer.cs.meta new file mode 100644 index 0000000..f696e08 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/GOST3410Signer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3cd915f02393dc54fa543e2ba13b37fd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/GenericSigner.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/GenericSigner.cs new file mode 100644 index 0000000..a551217 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/GenericSigner.cs @@ -0,0 +1,130 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Signers +{ + public class GenericSigner + : ISigner + { + private readonly IAsymmetricBlockCipher engine; + private readonly IDigest digest; + private bool forSigning; + + public GenericSigner( + IAsymmetricBlockCipher engine, + IDigest digest) + { + this.engine = engine; + this.digest = digest; + } + + public virtual string AlgorithmName + { + get { return "Generic(" + engine.AlgorithmName + "/" + digest.AlgorithmName + ")"; } + } + + /** + * initialise the signer for signing or verification. + * + * @param forSigning + * true if for signing, false otherwise + * @param parameters + * necessary parameters. + */ + public virtual void Init(bool forSigning, ICipherParameters parameters) + { + this.forSigning = forSigning; + + AsymmetricKeyParameter k; + if (parameters is ParametersWithRandom) + { + k = (AsymmetricKeyParameter)((ParametersWithRandom)parameters).Parameters; + } + else + { + k = (AsymmetricKeyParameter)parameters; + } + + if (forSigning && !k.IsPrivate) + throw new InvalidKeyException("Signing requires private key."); + + if (!forSigning && k.IsPrivate) + throw new InvalidKeyException("Verification requires public key."); + + Reset(); + + engine.Init(forSigning, parameters); + } + + /** + * update the internal digest with the byte b + */ + public virtual void Update(byte input) + { + digest.Update(input); + } + + /** + * update the internal digest with the byte array in + */ + public virtual void BlockUpdate(byte[] input, int inOff, int length) + { + digest.BlockUpdate(input, inOff, length); + } + + /** + * Generate a signature for the message we've been loaded with using the key + * we were initialised with. + */ + public virtual byte[] GenerateSignature() + { + if (!forSigning) + throw new InvalidOperationException("GenericSigner not initialised for signature generation."); + + byte[] hash = new byte[digest.GetDigestSize()]; + digest.DoFinal(hash, 0); + + return engine.ProcessBlock(hash, 0, hash.Length); + } + + /** + * return true if the internal state represents the signature described in + * the passed in array. + */ + public virtual bool VerifySignature(byte[] signature) + { + if (forSigning) + throw new InvalidOperationException("GenericSigner not initialised for verification"); + + byte[] hash = new byte[digest.GetDigestSize()]; + digest.DoFinal(hash, 0); + + try + { + byte[] sig = engine.ProcessBlock(signature, 0, signature.Length); + + // Extend with leading zeroes to match the digest size, if necessary. + if (sig.Length < hash.Length) + { + byte[] tmp = new byte[hash.Length]; + Array.Copy(sig, 0, tmp, tmp.Length - sig.Length, sig.Length); + sig = tmp; + } + + return Arrays.ConstantTimeAreEqual(sig, hash); + } + catch (Exception) + { + return false; + } + } + + public virtual void Reset() + { + digest.Reset(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/GenericSigner.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/GenericSigner.cs.meta new file mode 100644 index 0000000..f98f44c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/GenericSigner.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7352d5e716ee1b3469812d97349c09d3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/HMacDsaKCalculator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/HMacDsaKCalculator.cs new file mode 100644 index 0000000..05c4ae5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/HMacDsaKCalculator.cs @@ -0,0 +1,151 @@ +using System; + +using Org.BouncyCastle.Crypto.Macs; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Signers +{ + /** + * A deterministic K calculator based on the algorithm in section 3.2 of RFC 6979. + */ + public class HMacDsaKCalculator + : IDsaKCalculator + { + private readonly HMac hMac; + private readonly byte[] K; + private readonly byte[] V; + + private BigInteger n; + + /** + * Base constructor. + * + * @param digest digest to build the HMAC on. + */ + public HMacDsaKCalculator(IDigest digest) + { + this.hMac = new HMac(digest); + this.V = new byte[hMac.GetMacSize()]; + this.K = new byte[hMac.GetMacSize()]; + } + + public virtual bool IsDeterministic + { + get { return true; } + } + + public virtual void Init(BigInteger n, SecureRandom random) + { + throw new InvalidOperationException("Operation not supported"); + } + + public void Init(BigInteger n, BigInteger d, byte[] message) + { + this.n = n; + + Arrays.Fill(V, (byte)0x01); + Arrays.Fill(K, (byte)0); + + int size = BigIntegers.GetUnsignedByteLength(n); + byte[] x = new byte[size]; + byte[] dVal = BigIntegers.AsUnsignedByteArray(d); + + Array.Copy(dVal, 0, x, x.Length - dVal.Length, dVal.Length); + + byte[] m = new byte[size]; + + BigInteger mInt = BitsToInt(message); + + if (mInt.CompareTo(n) >= 0) + { + mInt = mInt.Subtract(n); + } + + byte[] mVal = BigIntegers.AsUnsignedByteArray(mInt); + + Array.Copy(mVal, 0, m, m.Length - mVal.Length, mVal.Length); + + hMac.Init(new KeyParameter(K)); + + hMac.BlockUpdate(V, 0, V.Length); + hMac.Update((byte)0x00); + hMac.BlockUpdate(x, 0, x.Length); + hMac.BlockUpdate(m, 0, m.Length); + + hMac.DoFinal(K, 0); + + hMac.Init(new KeyParameter(K)); + + hMac.BlockUpdate(V, 0, V.Length); + + hMac.DoFinal(V, 0); + + hMac.BlockUpdate(V, 0, V.Length); + hMac.Update((byte)0x01); + hMac.BlockUpdate(x, 0, x.Length); + hMac.BlockUpdate(m, 0, m.Length); + + hMac.DoFinal(K, 0); + + hMac.Init(new KeyParameter(K)); + + hMac.BlockUpdate(V, 0, V.Length); + + hMac.DoFinal(V, 0); + } + + public virtual BigInteger NextK() + { + byte[] t = new byte[BigIntegers.GetUnsignedByteLength(n)]; + + for (;;) + { + int tOff = 0; + + while (tOff < t.Length) + { + hMac.BlockUpdate(V, 0, V.Length); + + hMac.DoFinal(V, 0); + + int len = System.Math.Min(t.Length - tOff, V.Length); + Array.Copy(V, 0, t, tOff, len); + tOff += len; + } + + BigInteger k = BitsToInt(t); + + if (k.SignValue > 0 && k.CompareTo(n) < 0) + { + return k; + } + + hMac.BlockUpdate(V, 0, V.Length); + hMac.Update((byte)0x00); + + hMac.DoFinal(K, 0); + + hMac.Init(new KeyParameter(K)); + + hMac.BlockUpdate(V, 0, V.Length); + + hMac.DoFinal(V, 0); + } + } + + private BigInteger BitsToInt(byte[] t) + { + BigInteger v = new BigInteger(1, t); + + if (t.Length * 8 > n.BitLength) + { + v = v.ShiftRight(t.Length * 8 - n.BitLength); + } + + return v; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/HMacDsaKCalculator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/HMacDsaKCalculator.cs.meta new file mode 100644 index 0000000..4d3a0ac --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/HMacDsaKCalculator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 061808bc6621c4749a5bbde15cd362bd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/IDsaEncoding.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/IDsaEncoding.cs new file mode 100644 index 0000000..cccc4f9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/IDsaEncoding.cs @@ -0,0 +1,25 @@ +using System; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Signers +{ + /// + /// An interface for different encoding formats for DSA signatures. + /// + public interface IDsaEncoding + { + /// Decode the (r, s) pair of a DSA signature. + /// The order of the group that r, s belong to. + /// An encoding of the (r, s) pair of a DSA signature. + /// The (r, s) of a DSA signature, stored in an array of exactly two elements, r followed by s. + BigInteger[] Decode(BigInteger n, byte[] encoding); + + /// Encode the (r, s) pair of a DSA signature. + /// The order of the group that r, s belong to. + /// The r value of a DSA signature. + /// The s value of a DSA signature. + /// An encoding of the DSA signature given by the provided (r, s) pair. + byte[] Encode(BigInteger n, BigInteger r, BigInteger s); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/IDsaEncoding.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/IDsaEncoding.cs.meta new file mode 100644 index 0000000..629247e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/IDsaEncoding.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 10413986e2a22d34d8224714bb2272df +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/IDsaKCalculator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/IDsaKCalculator.cs new file mode 100644 index 0000000..645186d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/IDsaKCalculator.cs @@ -0,0 +1,44 @@ +using System; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Signers +{ + /** + * Interface define calculators of K values for DSA/ECDSA. + */ + public interface IDsaKCalculator + { + /** + * Return true if this calculator is deterministic, false otherwise. + * + * @return true if deterministic, otherwise false. + */ + bool IsDeterministic { get; } + + /** + * Non-deterministic initialiser. + * + * @param n the order of the DSA group. + * @param random a source of randomness. + */ + void Init(BigInteger n, SecureRandom random); + + /** + * Deterministic initialiser. + * + * @param n the order of the DSA group. + * @param d the DSA private value. + * @param message the message being signed. + */ + void Init(BigInteger n, BigInteger d, byte[] message); + + /** + * Return the next valid value of K. + * + * @return a K value. + */ + BigInteger NextK(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/IDsaKCalculator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/IDsaKCalculator.cs.meta new file mode 100644 index 0000000..6bb6d3b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/IDsaKCalculator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b32cda7a487aa994e93456752b5866c7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/Iso9796d2PssSigner.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/Iso9796d2PssSigner.cs new file mode 100644 index 0000000..6b80370 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/Iso9796d2PssSigner.cs @@ -0,0 +1,619 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Signers +{ + /// ISO9796-2 - mechanism using a hash function with recovery (scheme 2 and 3). + ///

+ /// Note: the usual length for the salt is the length of the hash + /// function used in bytes.

+ ///
+ public class Iso9796d2PssSigner + : ISignerWithRecovery + { + /// + /// Return a reference to the recoveredMessage message. + /// + /// The full/partial recoveredMessage message. + /// + public byte[] GetRecoveredMessage() + { + return recoveredMessage; + } + + [Obsolete("Use 'IsoTrailers' instead")] + public const int TrailerImplicit = 0xBC; + [Obsolete("Use 'IsoTrailers' instead")] + public const int TrailerRipeMD160 = 0x31CC; + [Obsolete("Use 'IsoTrailers' instead")] + public const int TrailerRipeMD128 = 0x32CC; + [Obsolete("Use 'IsoTrailers' instead")] + public const int TrailerSha1 = 0x33CC; + [Obsolete("Use 'IsoTrailers' instead")] + public const int TrailerSha256 = 0x34CC; + [Obsolete("Use 'IsoTrailers' instead")] + public const int TrailerSha512 = 0x35CC; + [Obsolete("Use 'IsoTrailers' instead")] + public const int TrailerSha384 = 0x36CC; + [Obsolete("Use 'IsoTrailers' instead")] + public const int TrailerWhirlpool = 0x37CC; + + private IDigest digest; + private IAsymmetricBlockCipher cipher; + + private SecureRandom random; + private byte[] standardSalt; + + private int hLen; + private int trailer; + private int keyBits; + private byte[] block; + private byte[] mBuf; + private int messageLength; + private readonly int saltLength; + private bool fullMessage; + private byte[] recoveredMessage; + + private byte[] preSig; + private byte[] preBlock; + private int preMStart; + private int preTLength; + + /// + /// Generate a signer with either implicit or explicit trailers for ISO9796-2, scheme 2 or 3. + /// + /// base cipher to use for signature creation/verification + /// digest to use. + /// length of salt in bytes. + /// whether or not the trailer is implicit or gives the hash. + public Iso9796d2PssSigner( + IAsymmetricBlockCipher cipher, + IDigest digest, + int saltLength, + bool isImplicit) + { + this.cipher = cipher; + this.digest = digest; + this.hLen = digest.GetDigestSize(); + this.saltLength = saltLength; + + if (isImplicit) + { + trailer = IsoTrailers.TRAILER_IMPLICIT; + } + else if (IsoTrailers.NoTrailerAvailable(digest)) + { + throw new ArgumentException("no valid trailer", "digest"); + } + else + { + trailer = IsoTrailers.GetTrailer(digest); + } + } + + /// Constructor for a signer with an explicit digest trailer. + /// + /// + /// cipher to use. + /// + /// digest to sign with. + /// + /// length of salt in bytes. + /// + public Iso9796d2PssSigner( + IAsymmetricBlockCipher cipher, + IDigest digest, + int saltLength) + : this(cipher, digest, saltLength, false) + { + } + + public virtual string AlgorithmName + { + get { return digest.AlgorithmName + "with" + "ISO9796-2S2"; } + } + + /// Initialise the signer. + /// true if for signing, false if for verification. + /// parameters for signature generation/verification. If the + /// parameters are for generation they should be a ParametersWithRandom, + /// a ParametersWithSalt, or just an RsaKeyParameters object. If RsaKeyParameters + /// are passed in a SecureRandom will be created. + /// + /// if wrong parameter type or a fixed + /// salt is passed in which is the wrong length. + /// + public virtual void Init( + bool forSigning, + ICipherParameters parameters) + { + RsaKeyParameters kParam; + if (parameters is ParametersWithRandom) + { + ParametersWithRandom p = (ParametersWithRandom) parameters; + + kParam = (RsaKeyParameters) p.Parameters; + + if (forSigning) + { + random = p.Random; + } + } + else if (parameters is ParametersWithSalt) + { + if (!forSigning) + throw new ArgumentException("ParametersWithSalt only valid for signing", "parameters"); + + ParametersWithSalt p = (ParametersWithSalt) parameters; + + kParam = (RsaKeyParameters) p.Parameters; + standardSalt = p.GetSalt(); + + if (standardSalt.Length != saltLength) + throw new ArgumentException("Fixed salt is of wrong length"); + } + else + { + kParam = (RsaKeyParameters) parameters; + + if (forSigning) + { + random = new SecureRandom(); + } + } + + cipher.Init(forSigning, kParam); + + keyBits = kParam.Modulus.BitLength; + + block = new byte[(keyBits + 7) / 8]; + + if (trailer == IsoTrailers.TRAILER_IMPLICIT) + { + mBuf = new byte[block.Length - digest.GetDigestSize() - saltLength - 1 - 1]; + } + else + { + mBuf = new byte[block.Length - digest.GetDigestSize() - saltLength - 1 - 2]; + } + + Reset(); + } + + /// compare two byte arrays - constant time. + private bool IsSameAs(byte[] a, byte[] b) + { + if (messageLength != b.Length) + { + return false; + } + + bool isOkay = true; + + for (int i = 0; i != b.Length; i++) + { + if (a[i] != b[i]) + { + isOkay = false; + } + } + + return isOkay; + } + + /// clear possible sensitive data + private void ClearBlock( + byte[] block) + { + Array.Clear(block, 0, block.Length); + } + + public virtual void UpdateWithRecoveredMessage( + byte[] signature) + { + byte[] block = cipher.ProcessBlock(signature, 0, signature.Length); + + // + // adjust block size for leading zeroes if necessary + // + if (block.Length < (keyBits + 7) / 8) + { + byte[] tmp = new byte[(keyBits + 7) / 8]; + + Array.Copy(block, 0, tmp, tmp.Length - block.Length, block.Length); + ClearBlock(block); + block = tmp; + } + + int tLength; + + if (((block[block.Length - 1] & 0xFF) ^ 0xBC) == 0) + { + tLength = 1; + } + else + { + int sigTrail = ((block[block.Length - 2] & 0xFF) << 8) | (block[block.Length - 1] & 0xFF); + + if (IsoTrailers.NoTrailerAvailable(digest)) + throw new ArgumentException("unrecognised hash in signature"); + + if (sigTrail != IsoTrailers.GetTrailer(digest)) + throw new InvalidOperationException("signer initialised with wrong digest for trailer " + sigTrail); + + tLength = 2; + } + + // + // calculate H(m2) + // + byte[] m2Hash = new byte[hLen]; + digest.DoFinal(m2Hash, 0); + + // + // remove the mask + // + byte[] dbMask = MaskGeneratorFunction1(block, block.Length - hLen - tLength, hLen, block.Length - hLen - tLength); + for (int i = 0; i != dbMask.Length; i++) + { + block[i] ^= dbMask[i]; + } + + block[0] &= 0x7f; + + // + // find out how much padding we've got + // + int mStart = 0; + + while (mStart < block.Length) + { + if (block[mStart++] == 0x01) + break; + } + + if (mStart >= block.Length) + { + ClearBlock(block); + } + + fullMessage = (mStart > 1); + + recoveredMessage = new byte[dbMask.Length - mStart - saltLength]; + + Array.Copy(block, mStart, recoveredMessage, 0, recoveredMessage.Length); + recoveredMessage.CopyTo(mBuf, 0); + + preSig = signature; + preBlock = block; + preMStart = mStart; + preTLength = tLength; + } + + /// update the internal digest with the byte b + public virtual void Update( + byte input) + { + if (preSig == null && messageLength < mBuf.Length) + { + mBuf[messageLength++] = input; + } + else + { + digest.Update(input); + } + } + + /// update the internal digest with the byte array in + public virtual void BlockUpdate( + byte[] input, + int inOff, + int length) + { + if (preSig == null) + { + while (length > 0 && messageLength < mBuf.Length) + { + this.Update(input[inOff]); + inOff++; + length--; + } + } + + if (length > 0) + { + digest.BlockUpdate(input, inOff, length); + } + } + + /// reset the internal state + public virtual void Reset() + { + digest.Reset(); + messageLength = 0; + if (mBuf != null) + { + ClearBlock(mBuf); + } + if (recoveredMessage != null) + { + ClearBlock(recoveredMessage); + recoveredMessage = null; + } + fullMessage = false; + if (preSig != null) + { + preSig = null; + ClearBlock(preBlock); + preBlock = null; + } + } + + /// Generate a signature for the loaded message using the key we were + /// initialised with. + /// + public virtual byte[] GenerateSignature() + { + int digSize = digest.GetDigestSize(); + byte[] m2Hash = new byte[digSize]; + digest.DoFinal(m2Hash, 0); + + byte[] C = new byte[8]; + LtoOSP(messageLength * 8, C); + + digest.BlockUpdate(C, 0, C.Length); + digest.BlockUpdate(mBuf, 0, messageLength); + digest.BlockUpdate(m2Hash, 0, m2Hash.Length); + + byte[] salt; + if (standardSalt != null) + { + salt = standardSalt; + } + else + { + salt = new byte[saltLength]; + random.NextBytes(salt); + } + + digest.BlockUpdate(salt, 0, salt.Length); + + byte[] hash = new byte[digest.GetDigestSize()]; + digest.DoFinal(hash, 0); + + int tLength = 2; + if (trailer == IsoTrailers.TRAILER_IMPLICIT) + { + tLength = 1; + } + + int off = block.Length - messageLength - salt.Length - hLen - tLength - 1; + + block[off] = (byte) (0x01); + + Array.Copy(mBuf, 0, block, off + 1, messageLength); + Array.Copy(salt, 0, block, off + 1 + messageLength, salt.Length); + + byte[] dbMask = MaskGeneratorFunction1(hash, 0, hash.Length, block.Length - hLen - tLength); + for (int i = 0; i != dbMask.Length; i++) + { + block[i] ^= dbMask[i]; + } + + Array.Copy(hash, 0, block, block.Length - hLen - tLength, hLen); + + if (trailer == IsoTrailers.TRAILER_IMPLICIT) + { + block[block.Length - 1] = (byte)IsoTrailers.TRAILER_IMPLICIT; + } + else + { + block[block.Length - 2] = (byte) ((uint)trailer >> 8); + block[block.Length - 1] = (byte) trailer; + } + + block[0] &= (byte) (0x7f); + + byte[] b = cipher.ProcessBlock(block, 0, block.Length); + + ClearBlock(mBuf); + ClearBlock(block); + messageLength = 0; + + return b; + } + + /// return true if the signature represents a ISO9796-2 signature + /// for the passed in message. + /// + public virtual bool VerifySignature( + byte[] signature) + { + // + // calculate H(m2) + // + byte[] m2Hash = new byte[hLen]; + digest.DoFinal(m2Hash, 0); + + byte[] block; + int tLength; + int mStart = 0; + + if (preSig == null) + { + try + { + UpdateWithRecoveredMessage(signature); + } + catch (Exception) + { + return false; + } + } + else + { + if (!Arrays.AreEqual(preSig, signature)) + { + throw new InvalidOperationException("UpdateWithRecoveredMessage called on different signature"); + } + } + + block = preBlock; + mStart = preMStart; + tLength = preTLength; + + preSig = null; + preBlock = null; + + // + // check the hashes + // + byte[] C = new byte[8]; + LtoOSP(recoveredMessage.Length * 8, C); + + digest.BlockUpdate(C, 0, C.Length); + + if (recoveredMessage.Length != 0) + { + digest.BlockUpdate(recoveredMessage, 0, recoveredMessage.Length); + } + + digest.BlockUpdate(m2Hash, 0, m2Hash.Length); + + // Update for the salt + if (standardSalt != null) + { + digest.BlockUpdate(standardSalt, 0, standardSalt.Length); + } + else + { + digest.BlockUpdate(block, mStart + recoveredMessage.Length, saltLength); + } + + byte[] hash = new byte[digest.GetDigestSize()]; + digest.DoFinal(hash, 0); + + int off = block.Length - tLength - hash.Length; + + bool isOkay = true; + + for (int i = 0; i != hash.Length; i++) + { + if (hash[i] != block[off + i]) + { + isOkay = false; + } + } + + ClearBlock(block); + ClearBlock(hash); + + if (!isOkay) + { + fullMessage = false; + messageLength = 0; + ClearBlock(recoveredMessage); + return false; + } + + // + // if they've input a message check what we've recovered against + // what was input. + // + if (messageLength != 0) + { + if (!IsSameAs(mBuf, recoveredMessage)) + { + messageLength = 0; + ClearBlock(mBuf); + return false; + } + } + + messageLength = 0; + + ClearBlock(mBuf); + return true; + } + + /// + /// Return true if the full message was recoveredMessage. + /// + /// true on full message recovery, false otherwise, or if not sure. + /// + public virtual bool HasFullMessage() + { + return fullMessage; + } + + /// int to octet string. + /// int to octet string. + private void ItoOSP( + int i, + byte[] sp) + { + sp[0] = (byte)((uint)i >> 24); + sp[1] = (byte)((uint)i >> 16); + sp[2] = (byte)((uint)i >> 8); + sp[3] = (byte)((uint)i >> 0); + } + + /// long to octet string. + private void LtoOSP(long l, byte[] sp) + { + sp[0] = (byte)((ulong)l >> 56); + sp[1] = (byte)((ulong)l >> 48); + sp[2] = (byte)((ulong)l >> 40); + sp[3] = (byte)((ulong)l >> 32); + sp[4] = (byte)((ulong)l >> 24); + sp[5] = (byte)((ulong)l >> 16); + sp[6] = (byte)((ulong)l >> 8); + sp[7] = (byte)((ulong)l >> 0); + } + + /// mask generator function, as described in Pkcs1v2. + private byte[] MaskGeneratorFunction1( + byte[] Z, + int zOff, + int zLen, + int length) + { + byte[] mask = new byte[length]; + byte[] hashBuf = new byte[hLen]; + byte[] C = new byte[4]; + int counter = 0; + + digest.Reset(); + + do + { + ItoOSP(counter, C); + + digest.BlockUpdate(Z, zOff, zLen); + digest.BlockUpdate(C, 0, C.Length); + digest.DoFinal(hashBuf, 0); + + Array.Copy(hashBuf, 0, mask, counter * hLen, hLen); + } + while (++counter < (length / hLen)); + + if ((counter * hLen) < length) + { + ItoOSP(counter, C); + + digest.BlockUpdate(Z, zOff, zLen); + digest.BlockUpdate(C, 0, C.Length); + digest.DoFinal(hashBuf, 0); + + Array.Copy(hashBuf, 0, mask, counter * hLen, mask.Length - (counter * hLen)); + } + + return mask; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/Iso9796d2PssSigner.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/Iso9796d2PssSigner.cs.meta new file mode 100644 index 0000000..1715c51 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/Iso9796d2PssSigner.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a63e6d55847781b4281c7e92ac327ce5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/Iso9796d2Signer.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/Iso9796d2Signer.cs new file mode 100644 index 0000000..3039130 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/Iso9796d2Signer.cs @@ -0,0 +1,556 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Signers +{ + /// ISO9796-2 - mechanism using a hash function with recovery (scheme 1) + public class Iso9796d2Signer : ISignerWithRecovery + { + /// + /// Return a reference to the recoveredMessage message. + /// + /// The full/partial recoveredMessage message. + /// + public byte[] GetRecoveredMessage() + { + return recoveredMessage; + } + + [Obsolete("Use 'IsoTrailers' instead")] + public const int TrailerImplicit = 0xBC; + [Obsolete("Use 'IsoTrailers' instead")] + public const int TrailerRipeMD160 = 0x31CC; + [Obsolete("Use 'IsoTrailers' instead")] + public const int TrailerRipeMD128 = 0x32CC; + [Obsolete("Use 'IsoTrailers' instead")] + public const int TrailerSha1 = 0x33CC; + [Obsolete("Use 'IsoTrailers' instead")] + public const int TrailerSha256 = 0x34CC; + [Obsolete("Use 'IsoTrailers' instead")] + public const int TrailerSha512 = 0x35CC; + [Obsolete("Use 'IsoTrailers' instead")] + public const int TrailerSha384 = 0x36CC; + [Obsolete("Use 'IsoTrailers' instead")] + public const int TrailerWhirlpool = 0x37CC; + + private IDigest digest; + private IAsymmetricBlockCipher cipher; + + private int trailer; + private int keyBits; + private byte[] block; + private byte[] mBuf; + private int messageLength; + private bool fullMessage; + private byte[] recoveredMessage; + + private byte[] preSig; + private byte[] preBlock; + + /// + /// Generate a signer with either implicit or explicit trailers for ISO9796-2. + /// + /// base cipher to use for signature creation/verification + /// digest to use. + /// whether or not the trailer is implicit or gives the hash. + public Iso9796d2Signer( + IAsymmetricBlockCipher cipher, + IDigest digest, + bool isImplicit) + { + this.cipher = cipher; + this.digest = digest; + + if (isImplicit) + { + trailer = IsoTrailers.TRAILER_IMPLICIT; + } + else if (IsoTrailers.NoTrailerAvailable(digest)) + { + throw new ArgumentException("no valid trailer", "digest"); + } + else + { + trailer = IsoTrailers.GetTrailer(digest); + } + } + + /// Constructor for a signer with an explicit digest trailer. + /// + /// + /// cipher to use. + /// + /// digest to sign with. + /// + public Iso9796d2Signer(IAsymmetricBlockCipher cipher, IDigest digest) + : this(cipher, digest, false) + { + } + + public virtual string AlgorithmName + { + get { return digest.AlgorithmName + "with" + "ISO9796-2S1"; } + } + + public virtual void Init(bool forSigning, ICipherParameters parameters) + { + RsaKeyParameters kParam = (RsaKeyParameters) parameters; + + cipher.Init(forSigning, kParam); + + keyBits = kParam.Modulus.BitLength; + + block = new byte[(keyBits + 7) / 8]; + if (trailer == IsoTrailers.TRAILER_IMPLICIT) + { + mBuf = new byte[block.Length - digest.GetDigestSize() - 2]; + } + else + { + mBuf = new byte[block.Length - digest.GetDigestSize() - 3]; + } + + Reset(); + } + + /// compare two byte arrays - constant time. + private bool IsSameAs(byte[] a, byte[] b) + { + int checkLen; + if (messageLength > mBuf.Length) + { + if (mBuf.Length > b.Length) + { + return false; + } + + checkLen = mBuf.Length; + } + else + { + if (messageLength != b.Length) + { + return false; + } + + checkLen = b.Length; + } + + bool isOkay = true; + + for (int i = 0; i != checkLen; i++) + { + if (a[i] != b[i]) + { + isOkay = false; + } + } + + return isOkay; + } + + /// clear possible sensitive data + private void ClearBlock( + byte[] block) + { + Array.Clear(block, 0, block.Length); + } + + public virtual void UpdateWithRecoveredMessage( + byte[] signature) + { + byte[] block = cipher.ProcessBlock(signature, 0, signature.Length); + + if (((block[0] & 0xC0) ^ 0x40) != 0) + throw new InvalidCipherTextException("malformed signature"); + + if (((block[block.Length - 1] & 0xF) ^ 0xC) != 0) + throw new InvalidCipherTextException("malformed signature"); + + int delta = 0; + + if (((block[block.Length - 1] & 0xFF) ^ 0xBC) == 0) + { + delta = 1; + } + else + { + int sigTrail = ((block[block.Length - 2] & 0xFF) << 8) | (block[block.Length - 1] & 0xFF); + + if (IsoTrailers.NoTrailerAvailable(digest)) + throw new ArgumentException("unrecognised hash in signature"); + + if (sigTrail != IsoTrailers.GetTrailer(digest)) + throw new InvalidOperationException("signer initialised with wrong digest for trailer " + sigTrail); + + delta = 2; + } + + // + // find out how much padding we've got + // + int mStart = 0; + + for (mStart = 0; mStart != block.Length; mStart++) + { + if (((block[mStart] & 0x0f) ^ 0x0a) == 0) + break; + } + + mStart++; + + int off = block.Length - delta - digest.GetDigestSize(); + + // + // there must be at least one byte of message string + // + if ((off - mStart) <= 0) + throw new InvalidCipherTextException("malformed block"); + + // + // if we contain the whole message as well, check the hash of that. + // + if ((block[0] & 0x20) == 0) + { + fullMessage = true; + + recoveredMessage = new byte[off - mStart]; + Array.Copy(block, mStart, recoveredMessage, 0, recoveredMessage.Length); + } + else + { + fullMessage = false; + + recoveredMessage = new byte[off - mStart]; + Array.Copy(block, mStart, recoveredMessage, 0, recoveredMessage.Length); + } + + preSig = signature; + preBlock = block; + + digest.BlockUpdate(recoveredMessage, 0, recoveredMessage.Length); + messageLength = recoveredMessage.Length; + recoveredMessage.CopyTo(mBuf, 0); + } + + /// update the internal digest with the byte b + public virtual void Update( + byte input) + { + digest.Update(input); + + if (messageLength < mBuf.Length) + { + mBuf[messageLength] = input; + } + + messageLength++; + } + + /// update the internal digest with the byte array in + public virtual void BlockUpdate( + byte[] input, + int inOff, + int length) + { + while (length > 0 && messageLength < mBuf.Length) + { + //for (int i = 0; i < length && (i + messageLength) < mBuf.Length; i++) + //{ + // mBuf[messageLength + i] = input[inOff + i]; + //} + this.Update(input[inOff]); + inOff++; + length--; + } + + digest.BlockUpdate(input, inOff, length); + messageLength += length; + } + + /// reset the internal state + public virtual void Reset() + { + digest.Reset(); + messageLength = 0; + ClearBlock(mBuf); + + if (recoveredMessage != null) + { + ClearBlock(recoveredMessage); + } + + recoveredMessage = null; + fullMessage = false; + + if (preSig != null) + { + preSig = null; + ClearBlock(preBlock); + preBlock = null; + } + } + + /// Generate a signature for the loaded message using the key we were + /// initialised with. + /// + public virtual byte[] GenerateSignature() + { + int digSize = digest.GetDigestSize(); + + int t = 0; + int delta = 0; + + if (trailer == IsoTrailers.TRAILER_IMPLICIT) + { + t = 8; + delta = block.Length - digSize - 1; + digest.DoFinal(block, delta); + block[block.Length - 1] = (byte)IsoTrailers.TRAILER_IMPLICIT; + } + else + { + t = 16; + delta = block.Length - digSize - 2; + digest.DoFinal(block, delta); + block[block.Length - 2] = (byte) ((uint)trailer >> 8); + block[block.Length - 1] = (byte) trailer; + } + + byte header = 0; + int x = (digSize + messageLength) * 8 + t + 4 - keyBits; + + if (x > 0) + { + int mR = messageLength - ((x + 7) / 8); + header = (byte) (0x60); + + delta -= mR; + + Array.Copy(mBuf, 0, block, delta, mR); + } + else + { + header = (byte) (0x40); + delta -= messageLength; + + Array.Copy(mBuf, 0, block, delta, messageLength); + } + + if ((delta - 1) > 0) + { + for (int i = delta - 1; i != 0; i--) + { + block[i] = (byte) 0xbb; + } + block[delta - 1] ^= (byte) 0x01; + block[0] = (byte) 0x0b; + block[0] |= header; + } + else + { + block[0] = (byte) 0x0a; + block[0] |= header; + } + + byte[] b = cipher.ProcessBlock(block, 0, block.Length); + + messageLength = 0; + + ClearBlock(mBuf); + ClearBlock(block); + + return b; + } + + /// return true if the signature represents a ISO9796-2 signature + /// for the passed in message. + /// + public virtual bool VerifySignature(byte[] signature) + { + byte[] block; + + if (preSig == null) + { + try + { + block = cipher.ProcessBlock(signature, 0, signature.Length); + } + catch (Exception) + { + return false; + } + } + else + { + if (!Arrays.AreEqual(preSig, signature)) + throw new InvalidOperationException("updateWithRecoveredMessage called on different signature"); + + block = preBlock; + + preSig = null; + preBlock = null; + } + + if (((block[0] & 0xC0) ^ 0x40) != 0) + return ReturnFalse(block); + + if (((block[block.Length - 1] & 0xF) ^ 0xC) != 0) + return ReturnFalse(block); + + int delta = 0; + + if (((block[block.Length - 1] & 0xFF) ^ 0xBC) == 0) + { + delta = 1; + } + else + { + int sigTrail = ((block[block.Length - 2] & 0xFF) << 8) | (block[block.Length - 1] & 0xFF); + + if (IsoTrailers.NoTrailerAvailable(digest)) + throw new ArgumentException("unrecognised hash in signature"); + + if (sigTrail != IsoTrailers.GetTrailer(digest)) + throw new InvalidOperationException("signer initialised with wrong digest for trailer " + sigTrail); + + delta = 2; + } + + // + // find out how much padding we've got + // + int mStart = 0; + for (; mStart != block.Length; mStart++) + { + if (((block[mStart] & 0x0f) ^ 0x0a) == 0) + { + break; + } + } + + mStart++; + + // + // check the hashes + // + byte[] hash = new byte[digest.GetDigestSize()]; + + int off = block.Length - delta - hash.Length; + + // + // there must be at least one byte of message string + // + if ((off - mStart) <= 0) + { + return ReturnFalse(block); + } + + // + // if we contain the whole message as well, check the hash of that. + // + if ((block[0] & 0x20) == 0) + { + fullMessage = true; + + // check right number of bytes passed in. + if (messageLength > off - mStart) + { + return ReturnFalse(block); + } + + digest.Reset(); + digest.BlockUpdate(block, mStart, off - mStart); + digest.DoFinal(hash, 0); + + bool isOkay = true; + + for (int i = 0; i != hash.Length; i++) + { + block[off + i] ^= hash[i]; + if (block[off + i] != 0) + { + isOkay = false; + } + } + + if (!isOkay) + { + return ReturnFalse(block); + } + + recoveredMessage = new byte[off - mStart]; + Array.Copy(block, mStart, recoveredMessage, 0, recoveredMessage.Length); + } + else + { + fullMessage = false; + + digest.DoFinal(hash, 0); + + bool isOkay = true; + + for (int i = 0; i != hash.Length; i++) + { + block[off + i] ^= hash[i]; + if (block[off + i] != 0) + { + isOkay = false; + } + } + + if (!isOkay) + { + return ReturnFalse(block); + } + + recoveredMessage = new byte[off - mStart]; + Array.Copy(block, mStart, recoveredMessage, 0, recoveredMessage.Length); + } + + // + // if they've input a message check what we've recovered against + // what was input. + // + if (messageLength != 0) + { + if (!IsSameAs(mBuf, recoveredMessage)) + { + return ReturnFalse(block); + } + } + + ClearBlock(mBuf); + ClearBlock(block); + + messageLength = 0; + + return true; + } + + private bool ReturnFalse(byte[] block) + { + messageLength = 0; + + ClearBlock(mBuf); + ClearBlock(block); + + return false; + } + + /// + /// Return true if the full message was recoveredMessage. + /// + /// true on full message recovery, false otherwise. + /// + public virtual bool HasFullMessage() + { + return fullMessage; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/Iso9796d2Signer.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/Iso9796d2Signer.cs.meta new file mode 100644 index 0000000..b3d0806 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/Iso9796d2Signer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 040cbc9cd8560e640919f7edac148065 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/IsoTrailers.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/IsoTrailers.cs new file mode 100644 index 0000000..497ffaf --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/IsoTrailers.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Crypto.Signers +{ + public class IsoTrailers + { + public const int TRAILER_IMPLICIT = 0xBC; + public const int TRAILER_RIPEMD160 = 0x31CC; + public const int TRAILER_RIPEMD128 = 0x32CC; + public const int TRAILER_SHA1 = 0x33CC; + public const int TRAILER_SHA256 = 0x34CC; + public const int TRAILER_SHA512 = 0x35CC; + public const int TRAILER_SHA384 = 0x36CC; + public const int TRAILER_WHIRLPOOL = 0x37CC; + public const int TRAILER_SHA224 = 0x38CC; + public const int TRAILER_SHA512_224 = 0x39CC; + public const int TRAILER_SHA512_256 = 0x40CC; + + private static IDictionary CreateTrailerMap() + { + IDictionary trailers = Platform.CreateHashtable(); + + trailers.Add("RIPEMD128", TRAILER_RIPEMD128); + trailers.Add("RIPEMD160", TRAILER_RIPEMD160); + + trailers.Add("SHA-1", TRAILER_SHA1); + trailers.Add("SHA-224", TRAILER_SHA224); + trailers.Add("SHA-256", TRAILER_SHA256); + trailers.Add("SHA-384", TRAILER_SHA384); + trailers.Add("SHA-512", TRAILER_SHA512); + trailers.Add("SHA-512/224", TRAILER_SHA512_224); + trailers.Add("SHA-512/256", TRAILER_SHA512_256); + + trailers.Add("Whirlpool", TRAILER_WHIRLPOOL); + + return CollectionUtilities.ReadOnly(trailers); + } + + // IDictionary is (string -> Int32) + private static readonly IDictionary trailerMap = CreateTrailerMap(); + + public static int GetTrailer(IDigest digest) + { + return (int)trailerMap[digest.AlgorithmName]; + } + + public static bool NoTrailerAvailable(IDigest digest) + { + return !trailerMap.Contains(digest.AlgorithmName); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/IsoTrailers.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/IsoTrailers.cs.meta new file mode 100644 index 0000000..e95916a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/IsoTrailers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8bda14bf7bf685f4db850067c7998f29 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/PlainDsaEncoding.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/PlainDsaEncoding.cs new file mode 100644 index 0000000..2e1f65a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/PlainDsaEncoding.cs @@ -0,0 +1,58 @@ +using System; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Signers +{ + public class PlainDsaEncoding + : IDsaEncoding + { + public static readonly PlainDsaEncoding Instance = new PlainDsaEncoding(); + + public virtual BigInteger[] Decode(BigInteger n, byte[] encoding) + { + int valueLength = BigIntegers.GetUnsignedByteLength(n); + if (encoding.Length != valueLength * 2) + throw new ArgumentException("Encoding has incorrect length", "encoding"); + + return new BigInteger[] { + DecodeValue(n, encoding, 0, valueLength), + DecodeValue(n, encoding, valueLength, valueLength), + }; + } + + public virtual byte[] Encode(BigInteger n, BigInteger r, BigInteger s) + { + int valueLength = BigIntegers.GetUnsignedByteLength(n); + byte[] result = new byte[valueLength * 2]; + EncodeValue(n, r, result, 0, valueLength); + EncodeValue(n, s, result, valueLength, valueLength); + return result; + } + + protected virtual BigInteger CheckValue(BigInteger n, BigInteger x) + { + if (x.SignValue < 0 || x.CompareTo(n) >= 0) + throw new ArgumentException("Value out of range", "x"); + + return x; + } + + protected virtual BigInteger DecodeValue(BigInteger n, byte[] buf, int off, int len) + { + return CheckValue(n, new BigInteger(1, buf, off, len)); + } + + protected virtual void EncodeValue(BigInteger n, BigInteger x, byte[] buf, int off, int len) + { + byte[] bs = CheckValue(n, x).ToByteArrayUnsigned(); + int bsOff = System.Math.Max(0, bs.Length - len); + int bsLen = bs.Length - bsOff; + + int pos = len - bsLen; + Arrays.Fill(buf, off, off + pos, 0); + Array.Copy(bs, bsOff, buf, off + pos, bsLen); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/PlainDsaEncoding.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/PlainDsaEncoding.cs.meta new file mode 100644 index 0000000..9a9131f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/PlainDsaEncoding.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7e889852e20b0de4a9d8fce06a87a2b1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/PssSigner.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/PssSigner.cs new file mode 100644 index 0000000..66efa51 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/PssSigner.cs @@ -0,0 +1,412 @@ +using System; + +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Signers +{ + /// RSA-PSS as described in Pkcs# 1 v 2.1. + ///

+ /// Note: the usual value for the salt length is the number of + /// bytes in the hash function.

+ ///
+ public class PssSigner + : ISigner + { + public const byte TrailerImplicit = (byte)0xBC; + + private readonly IDigest contentDigest1, contentDigest2; + private readonly IDigest mgfDigest; + private readonly IAsymmetricBlockCipher cipher; + + private SecureRandom random; + + private int hLen; + private int mgfhLen; + private int sLen; + private bool sSet; + private int emBits; + private byte[] salt; + private byte[] mDash; + private byte[] block; + private byte trailer; + + public static PssSigner CreateRawSigner( + IAsymmetricBlockCipher cipher, + IDigest digest) + { + return new PssSigner(cipher, new NullDigest(), digest, digest, digest.GetDigestSize(), null, TrailerImplicit); + } + + public static PssSigner CreateRawSigner( + IAsymmetricBlockCipher cipher, + IDigest contentDigest, + IDigest mgfDigest, + int saltLen, + byte trailer) + { + return new PssSigner(cipher, new NullDigest(), contentDigest, mgfDigest, saltLen, null, trailer); + } + + public PssSigner( + IAsymmetricBlockCipher cipher, + IDigest digest) + : this(cipher, digest, digest.GetDigestSize()) + { + } + + /// Basic constructor + /// the asymmetric cipher to use. + /// the digest to use. + /// the length of the salt to use (in bytes). + public PssSigner( + IAsymmetricBlockCipher cipher, + IDigest digest, + int saltLen) + : this(cipher, digest, saltLen, TrailerImplicit) + { + } + + /// Basic constructor + /// the asymmetric cipher to use. + /// the digest to use. + /// the fixed salt to be used. + public PssSigner( + IAsymmetricBlockCipher cipher, + IDigest digest, + byte[] salt) + : this(cipher, digest, digest, digest, salt.Length, salt, TrailerImplicit) + { + } + + public PssSigner( + IAsymmetricBlockCipher cipher, + IDigest contentDigest, + IDigest mgfDigest, + int saltLen) + : this(cipher, contentDigest, mgfDigest, saltLen, TrailerImplicit) + { + } + + public PssSigner( + IAsymmetricBlockCipher cipher, + IDigest contentDigest, + IDigest mgfDigest, + byte[] salt) + : this(cipher, contentDigest, contentDigest, mgfDigest, salt.Length, salt, TrailerImplicit) + { + } + + public PssSigner( + IAsymmetricBlockCipher cipher, + IDigest digest, + int saltLen, + byte trailer) + : this(cipher, digest, digest, saltLen, trailer) + { + } + + public PssSigner( + IAsymmetricBlockCipher cipher, + IDigest contentDigest, + IDigest mgfDigest, + int saltLen, + byte trailer) + : this(cipher, contentDigest, contentDigest, mgfDigest, saltLen, null, trailer) + { + } + + private PssSigner( + IAsymmetricBlockCipher cipher, + IDigest contentDigest1, + IDigest contentDigest2, + IDigest mgfDigest, + int saltLen, + byte[] salt, + byte trailer) + { + this.cipher = cipher; + this.contentDigest1 = contentDigest1; + this.contentDigest2 = contentDigest2; + this.mgfDigest = mgfDigest; + this.hLen = contentDigest2.GetDigestSize(); + this.mgfhLen = mgfDigest.GetDigestSize(); + this.sLen = saltLen; + this.sSet = salt != null; + if (sSet) + { + this.salt = salt; + } + else + { + this.salt = new byte[saltLen]; + } + this.mDash = new byte[8 + saltLen + hLen]; + this.trailer = trailer; + } + + public virtual string AlgorithmName + { + get { return mgfDigest.AlgorithmName + "withRSAandMGF1"; } + } + + public virtual void Init( + bool forSigning, + ICipherParameters parameters) + { + if (parameters is ParametersWithRandom) + { + ParametersWithRandom p = (ParametersWithRandom) parameters; + + parameters = p.Parameters; + random = p.Random; + } + else + { + if (forSigning) + { + random = new SecureRandom(); + } + } + + cipher.Init(forSigning, parameters); + + RsaKeyParameters kParam; + if (parameters is RsaBlindingParameters) + { + kParam = ((RsaBlindingParameters) parameters).PublicKey; + } + else + { + kParam = (RsaKeyParameters) parameters; + } + + emBits = kParam.Modulus.BitLength - 1; + + if (emBits < (8 * hLen + 8 * sLen + 9)) + throw new ArgumentException("key too small for specified hash and salt lengths"); + + block = new byte[(emBits + 7) / 8]; + } + + /// clear possible sensitive data + private void ClearBlock( + byte[] block) + { + Array.Clear(block, 0, block.Length); + } + + /// update the internal digest with the byte b + public virtual void Update( + byte input) + { + contentDigest1.Update(input); + } + + /// update the internal digest with the byte array in + public virtual void BlockUpdate( + byte[] input, + int inOff, + int length) + { + contentDigest1.BlockUpdate(input, inOff, length); + } + + /// reset the internal state + public virtual void Reset() + { + contentDigest1.Reset(); + } + + /// Generate a signature for the message we've been loaded with using + /// the key we were initialised with. + /// + public virtual byte[] GenerateSignature() + { + contentDigest1.DoFinal(mDash, mDash.Length - hLen - sLen); + + if (sLen != 0) + { + if (!sSet) + { + random.NextBytes(salt); + } + salt.CopyTo(mDash, mDash.Length - sLen); + } + + byte[] h = new byte[hLen]; + + contentDigest2.BlockUpdate(mDash, 0, mDash.Length); + + contentDigest2.DoFinal(h, 0); + + block[block.Length - sLen - 1 - hLen - 1] = (byte) (0x01); + salt.CopyTo(block, block.Length - sLen - hLen - 1); + + byte[] dbMask = MaskGeneratorFunction(h, 0, h.Length, block.Length - hLen - 1); + for (int i = 0; i != dbMask.Length; i++) + { + block[i] ^= dbMask[i]; + } + + h.CopyTo(block, block.Length - hLen - 1); + + uint firstByteMask = 0xFFU >> ((block.Length * 8) - emBits); + + block[0] &= (byte)firstByteMask; + block[block.Length - 1] = trailer; + + byte[] b = cipher.ProcessBlock(block, 0, block.Length); + + ClearBlock(block); + + return b; + } + + /// return true if the internal state represents the signature described + /// in the passed in array. + /// + public virtual bool VerifySignature( + byte[] signature) + { + contentDigest1.DoFinal(mDash, mDash.Length - hLen - sLen); + + byte[] b = cipher.ProcessBlock(signature, 0, signature.Length); + Arrays.Fill(block, 0, block.Length - b.Length, 0); + b.CopyTo(block, block.Length - b.Length); + + uint firstByteMask = 0xFFU >> ((block.Length * 8) - emBits); + + if (block[0] != (byte)(block[0] & firstByteMask) + || block[block.Length - 1] != trailer) + { + ClearBlock(block); + return false; + } + + byte[] dbMask = MaskGeneratorFunction(block, block.Length - hLen - 1, hLen, block.Length - hLen - 1); + + for (int i = 0; i != dbMask.Length; i++) + { + block[i] ^= dbMask[i]; + } + + block[0] &= (byte)firstByteMask; + + for (int i = 0; i != block.Length - hLen - sLen - 2; i++) + { + if (block[i] != 0) + { + ClearBlock(block); + return false; + } + } + + if (block[block.Length - hLen - sLen - 2] != 0x01) + { + ClearBlock(block); + return false; + } + + if (sSet) + { + Array.Copy(salt, 0, mDash, mDash.Length - sLen, sLen); + } + else + { + Array.Copy(block, block.Length - sLen - hLen - 1, mDash, mDash.Length - sLen, sLen); + } + + contentDigest2.BlockUpdate(mDash, 0, mDash.Length); + contentDigest2.DoFinal(mDash, mDash.Length - hLen); + + for (int i = block.Length - hLen - 1, j = mDash.Length - hLen; j != mDash.Length; i++, j++) + { + if ((block[i] ^ mDash[j]) != 0) + { + ClearBlock(mDash); + ClearBlock(block); + return false; + } + } + + ClearBlock(mDash); + ClearBlock(block); + + return true; + } + + /// int to octet string. + private void ItoOSP( + int i, + byte[] sp) + { + sp[0] = (byte)((uint) i >> 24); + sp[1] = (byte)((uint) i >> 16); + sp[2] = (byte)((uint) i >> 8); + sp[3] = (byte)((uint) i >> 0); + } + + private byte[] MaskGeneratorFunction( + byte[] Z, + int zOff, + int zLen, + int length) + { + if (mgfDigest is IXof) + { + byte[] mask = new byte[length]; + mgfDigest.BlockUpdate(Z, zOff, zLen); + ((IXof)mgfDigest).DoFinal(mask, 0, mask.Length); + + return mask; + } + else + { + return MaskGeneratorFunction1(Z, zOff, zLen, length); + } + } + + /// mask generator function, as described in Pkcs1v2. + private byte[] MaskGeneratorFunction1( + byte[] Z, + int zOff, + int zLen, + int length) + { + byte[] mask = new byte[length]; + byte[] hashBuf = new byte[mgfhLen]; + byte[] C = new byte[4]; + int counter = 0; + + mgfDigest.Reset(); + + while (counter < (length / mgfhLen)) + { + ItoOSP(counter, C); + + mgfDigest.BlockUpdate(Z, zOff, zLen); + mgfDigest.BlockUpdate(C, 0, C.Length); + mgfDigest.DoFinal(hashBuf, 0); + + hashBuf.CopyTo(mask, counter * mgfhLen); + ++counter; + } + + if ((counter * mgfhLen) < length) + { + ItoOSP(counter, C); + + mgfDigest.BlockUpdate(Z, zOff, zLen); + mgfDigest.BlockUpdate(C, 0, C.Length); + mgfDigest.DoFinal(hashBuf, 0); + + Array.Copy(hashBuf, 0, mask, counter * mgfhLen, mask.Length - (counter * mgfhLen)); + } + + return mask; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/PssSigner.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/PssSigner.cs.meta new file mode 100644 index 0000000..f668889 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/PssSigner.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fecd26dc0696d374aa782fd1a3dac293 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/RandomDsaKCalculator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/RandomDsaKCalculator.cs new file mode 100644 index 0000000..022cc26 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/RandomDsaKCalculator.cs @@ -0,0 +1,44 @@ +using System; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Signers +{ + public class RandomDsaKCalculator + : IDsaKCalculator + { + private BigInteger q; + private SecureRandom random; + + public virtual bool IsDeterministic + { + get { return false; } + } + + public virtual void Init(BigInteger n, SecureRandom random) + { + this.q = n; + this.random = random; + } + + public virtual void Init(BigInteger n, BigInteger d, byte[] message) + { + throw new InvalidOperationException("Operation not supported"); + } + + public virtual BigInteger NextK() + { + int qBitLength = q.BitLength; + + BigInteger k; + do + { + k = new BigInteger(qBitLength, random); + } + while (k.SignValue < 1 || k.CompareTo(q) >= 0); + + return k; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/RandomDsaKCalculator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/RandomDsaKCalculator.cs.meta new file mode 100644 index 0000000..fa6107e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/RandomDsaKCalculator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9c9108a30ea43994b94990b8f7c2c419 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/RsaDigestSigner.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/RsaDigestSigner.cs new file mode 100644 index 0000000..ce6bcb2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/RsaDigestSigner.cs @@ -0,0 +1,239 @@ +using System; +using System.Collections; +using System.IO; +using System.Text; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.TeleTrust; +using Org.BouncyCastle.Asn1.Utilities; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Encodings; +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Signers; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Signers +{ + public class RsaDigestSigner + : ISigner + { + private readonly IAsymmetricBlockCipher rsaEngine; + private readonly AlgorithmIdentifier algId; + private readonly IDigest digest; + private bool forSigning; + + private static readonly IDictionary oidMap = Platform.CreateHashtable(); + + /// + /// Load oid table. + /// + static RsaDigestSigner() + { + oidMap["RIPEMD128"] = TeleTrusTObjectIdentifiers.RipeMD128; + oidMap["RIPEMD160"] = TeleTrusTObjectIdentifiers.RipeMD160; + oidMap["RIPEMD256"] = TeleTrusTObjectIdentifiers.RipeMD256; + + oidMap["SHA-1"] = X509ObjectIdentifiers.IdSha1; + oidMap["SHA-224"] = NistObjectIdentifiers.IdSha224; + oidMap["SHA-256"] = NistObjectIdentifiers.IdSha256; + oidMap["SHA-384"] = NistObjectIdentifiers.IdSha384; + oidMap["SHA-512"] = NistObjectIdentifiers.IdSha512; + oidMap["SHA-512/224"] = NistObjectIdentifiers.IdSha512_224; + oidMap["SHA-512/256"] = NistObjectIdentifiers.IdSha512_256; + oidMap["SHA3-224"] = NistObjectIdentifiers.IdSha3_224; + oidMap["SHA3-256"] = NistObjectIdentifiers.IdSha3_256; + oidMap["SHA3-384"] = NistObjectIdentifiers.IdSha3_384; + oidMap["SHA3-512"] = NistObjectIdentifiers.IdSha3_512; + + oidMap["MD2"] = PkcsObjectIdentifiers.MD2; + oidMap["MD4"] = PkcsObjectIdentifiers.MD4; + oidMap["MD5"] = PkcsObjectIdentifiers.MD5; + } + + public RsaDigestSigner(IDigest digest) + : this(digest, (DerObjectIdentifier)oidMap[digest.AlgorithmName]) + { + } + + public RsaDigestSigner(IDigest digest, DerObjectIdentifier digestOid) + : this(digest, new AlgorithmIdentifier(digestOid, DerNull.Instance)) + { + } + + public RsaDigestSigner(IDigest digest, AlgorithmIdentifier algId) + : this(new RsaCoreEngine(), digest, algId) + { + } + + public RsaDigestSigner(IRsa rsa, IDigest digest, DerObjectIdentifier digestOid) + : this(rsa, digest, new AlgorithmIdentifier(digestOid, DerNull.Instance)) + { + } + + public RsaDigestSigner(IRsa rsa, IDigest digest, AlgorithmIdentifier algId) + : this(new RsaBlindedEngine(rsa), digest, algId) + { + } + + public RsaDigestSigner(IAsymmetricBlockCipher rsaEngine, IDigest digest, AlgorithmIdentifier algId) + { + this.rsaEngine = new Pkcs1Encoding(rsaEngine); + this.digest = digest; + this.algId = algId; + } + + public virtual string AlgorithmName + { + get { return digest.AlgorithmName + "withRSA"; } + } + + /** + * Initialise the signer for signing or verification. + * + * @param forSigning true if for signing, false otherwise + * @param param necessary parameters. + */ + public virtual void Init( + bool forSigning, + ICipherParameters parameters) + { + this.forSigning = forSigning; + AsymmetricKeyParameter k; + + if (parameters is ParametersWithRandom) + { + k = (AsymmetricKeyParameter)((ParametersWithRandom)parameters).Parameters; + } + else + { + k = (AsymmetricKeyParameter)parameters; + } + + if (forSigning && !k.IsPrivate) + throw new InvalidKeyException("Signing requires private key."); + + if (!forSigning && k.IsPrivate) + throw new InvalidKeyException("Verification requires public key."); + + Reset(); + + rsaEngine.Init(forSigning, parameters); + } + + /** + * update the internal digest with the byte b + */ + public virtual void Update( + byte input) + { + digest.Update(input); + } + + /** + * update the internal digest with the byte array in + */ + public virtual void BlockUpdate( + byte[] input, + int inOff, + int length) + { + digest.BlockUpdate(input, inOff, length); + } + + /** + * Generate a signature for the message we've been loaded with using + * the key we were initialised with. + */ + public virtual byte[] GenerateSignature() + { + if (!forSigning) + throw new InvalidOperationException("RsaDigestSigner not initialised for signature generation."); + + byte[] hash = new byte[digest.GetDigestSize()]; + digest.DoFinal(hash, 0); + + byte[] data = DerEncode(hash); + return rsaEngine.ProcessBlock(data, 0, data.Length); + } + + /** + * return true if the internal state represents the signature described + * in the passed in array. + */ + public virtual bool VerifySignature( + byte[] signature) + { + if (forSigning) + throw new InvalidOperationException("RsaDigestSigner not initialised for verification"); + + byte[] hash = new byte[digest.GetDigestSize()]; + digest.DoFinal(hash, 0); + + byte[] sig; + byte[] expected; + + try + { + sig = rsaEngine.ProcessBlock(signature, 0, signature.Length); + expected = DerEncode(hash); + } + catch (Exception) + { + return false; + } + + if (sig.Length == expected.Length) + { + return Arrays.ConstantTimeAreEqual(sig, expected); + } + else if (sig.Length == expected.Length - 2) // NULL left out + { + int sigOffset = sig.Length - hash.Length - 2; + int expectedOffset = expected.Length - hash.Length - 2; + + expected[1] -= 2; // adjust lengths + expected[3] -= 2; + + int nonEqual = 0; + + for (int i = 0; i < hash.Length; i++) + { + nonEqual |= (sig[sigOffset + i] ^ expected[expectedOffset + i]); + } + + for (int i = 0; i < sigOffset; i++) + { + nonEqual |= (sig[i] ^ expected[i]); // check header less NULL + } + + return nonEqual == 0; + } + else + { + return false; + } + } + + public virtual void Reset() + { + digest.Reset(); + } + + private byte[] DerEncode(byte[] hash) + { + if (algId == null) + { + // For raw RSA, the DigestInfo must be prepared externally + return hash; + } + + DigestInfo dInfo = new DigestInfo(algId, hash); + + return dInfo.GetDerEncoded(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/RsaDigestSigner.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/RsaDigestSigner.cs.meta new file mode 100644 index 0000000..989d489 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/RsaDigestSigner.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f46e3a19a0801d244af9a999079c2948 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/SM2Signer.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/SM2Signer.cs new file mode 100644 index 0000000..c344a22 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/SM2Signer.cs @@ -0,0 +1,259 @@ +using System; + +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Math.EC.Multiplier; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Crypto.Signers +{ + /// The SM2 Digital Signature algorithm. + public class SM2Signer + : ISigner + { + private readonly IDsaKCalculator kCalculator = new RandomDsaKCalculator(); + private readonly IDigest digest; + private readonly IDsaEncoding encoding; + + private ECDomainParameters ecParams; + private ECPoint pubPoint; + private ECKeyParameters ecKey; + private byte[] z; + + public SM2Signer() + : this(StandardDsaEncoding.Instance, new SM3Digest()) + { + } + + public SM2Signer(IDigest digest) + : this(StandardDsaEncoding.Instance, digest) + { + } + + public SM2Signer(IDsaEncoding encoding) + : this(encoding, new SM3Digest()) + { + } + + public SM2Signer(IDsaEncoding encoding, IDigest digest) + { + this.encoding = encoding; + this.digest = digest; + } + + public virtual string AlgorithmName + { + get { return "SM2Sign"; } + } + + public virtual void Init(bool forSigning, ICipherParameters parameters) + { + ICipherParameters baseParam; + byte[] userID; + + if (parameters is ParametersWithID) + { + baseParam = ((ParametersWithID)parameters).Parameters; + userID = ((ParametersWithID)parameters).GetID(); + + if (userID.Length >= 8192) + throw new ArgumentException("SM2 user ID must be less than 2^16 bits long"); + } + else + { + baseParam = parameters; + // the default value, string value is "1234567812345678" + userID = Hex.DecodeStrict("31323334353637383132333435363738"); + } + + if (forSigning) + { + if (baseParam is ParametersWithRandom) + { + ParametersWithRandom rParam = (ParametersWithRandom)baseParam; + + ecKey = (ECKeyParameters)rParam.Parameters; + ecParams = ecKey.Parameters; + kCalculator.Init(ecParams.N, rParam.Random); + } + else + { + ecKey = (ECKeyParameters)baseParam; + ecParams = ecKey.Parameters; + kCalculator.Init(ecParams.N, new SecureRandom()); + } + pubPoint = CreateBasePointMultiplier().Multiply(ecParams.G, ((ECPrivateKeyParameters)ecKey).D).Normalize(); + } + else + { + ecKey = (ECKeyParameters)baseParam; + ecParams = ecKey.Parameters; + pubPoint = ((ECPublicKeyParameters)ecKey).Q; + } + + digest.Reset(); + z = GetZ(userID); + + digest.BlockUpdate(z, 0, z.Length); + } + + public virtual void Update(byte b) + { + digest.Update(b); + } + + public virtual void BlockUpdate(byte[] buf, int off, int len) + { + digest.BlockUpdate(buf, off, len); + } + + public virtual bool VerifySignature(byte[] signature) + { + try + { + BigInteger[] rs = encoding.Decode(ecParams.N, signature); + + return VerifySignature(rs[0], rs[1]); + } + catch (Exception) + { + } + + return false; + } + + public virtual void Reset() + { + if (z != null) + { + digest.Reset(); + digest.BlockUpdate(z, 0, z.Length); + } + } + + public virtual byte[] GenerateSignature() + { + byte[] eHash = DigestUtilities.DoFinal(digest); + + BigInteger n = ecParams.N; + BigInteger e = CalculateE(n, eHash); + BigInteger d = ((ECPrivateKeyParameters)ecKey).D; + + BigInteger r, s; + + ECMultiplier basePointMultiplier = CreateBasePointMultiplier(); + + // 5.2.1 Draft RFC: SM2 Public Key Algorithms + do // generate s + { + BigInteger k; + do // generate r + { + // A3 + k = kCalculator.NextK(); + + // A4 + ECPoint p = basePointMultiplier.Multiply(ecParams.G, k).Normalize(); + + // A5 + r = e.Add(p.AffineXCoord.ToBigInteger()).Mod(n); + } + while (r.SignValue == 0 || r.Add(k).Equals(n)); + + // A6 + BigInteger dPlus1ModN = BigIntegers.ModOddInverse(n, d.Add(BigIntegers.One)); + + s = k.Subtract(r.Multiply(d)).Mod(n); + s = dPlus1ModN.Multiply(s).Mod(n); + } + while (s.SignValue == 0); + + // A7 + try + { + return encoding.Encode(ecParams.N, r, s); + } + catch (Exception ex) + { + throw new CryptoException("unable to encode signature: " + ex.Message, ex); + } + } + + private bool VerifySignature(BigInteger r, BigInteger s) + { + BigInteger n = ecParams.N; + + // 5.3.1 Draft RFC: SM2 Public Key Algorithms + // B1 + if (r.CompareTo(BigInteger.One) < 0 || r.CompareTo(n) >= 0) + return false; + + // B2 + if (s.CompareTo(BigInteger.One) < 0 || s.CompareTo(n) >= 0) + return false; + + // B3 + byte[] eHash = DigestUtilities.DoFinal(digest); + + // B4 + BigInteger e = CalculateE(n, eHash); + + // B5 + BigInteger t = r.Add(s).Mod(n); + if (t.SignValue == 0) + return false; + + // B6 + ECPoint q = ((ECPublicKeyParameters)ecKey).Q; + ECPoint x1y1 = ECAlgorithms.SumOfTwoMultiplies(ecParams.G, s, q, t).Normalize(); + if (x1y1.IsInfinity) + return false; + + // B7 + return r.Equals(e.Add(x1y1.AffineXCoord.ToBigInteger()).Mod(n)); + } + + private byte[] GetZ(byte[] userID) + { + AddUserID(digest, userID); + + AddFieldElement(digest, ecParams.Curve.A); + AddFieldElement(digest, ecParams.Curve.B); + AddFieldElement(digest, ecParams.G.AffineXCoord); + AddFieldElement(digest, ecParams.G.AffineYCoord); + AddFieldElement(digest, pubPoint.AffineXCoord); + AddFieldElement(digest, pubPoint.AffineYCoord); + + return DigestUtilities.DoFinal(digest); + } + + private void AddUserID(IDigest digest, byte[] userID) + { + int len = userID.Length * 8; + digest.Update((byte)(len >> 8)); + digest.Update((byte)len); + digest.BlockUpdate(userID, 0, userID.Length); + } + + private void AddFieldElement(IDigest digest, ECFieldElement v) + { + byte[] p = v.GetEncoded(); + digest.BlockUpdate(p, 0, p.Length); + } + + protected virtual BigInteger CalculateE(BigInteger n, byte[] message) + { + // TODO Should hashes larger than the order be truncated as with ECDSA? + return new BigInteger(1, message); + } + + protected virtual ECMultiplier CreateBasePointMultiplier() + { + return new FixedPointCombMultiplier(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/SM2Signer.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/SM2Signer.cs.meta new file mode 100644 index 0000000..27baf8c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/SM2Signer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9e8e8a53994ce3147af6d3617cbcf03f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/StandardDsaEncoding.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/StandardDsaEncoding.cs new file mode 100644 index 0000000..75ac084 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/StandardDsaEncoding.cs @@ -0,0 +1,56 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Signers +{ + public class StandardDsaEncoding + : IDsaEncoding + { + public static readonly StandardDsaEncoding Instance = new StandardDsaEncoding(); + + public virtual BigInteger[] Decode(BigInteger n, byte[] encoding) + { + Asn1Sequence seq = (Asn1Sequence)Asn1Object.FromByteArray(encoding); + if (seq.Count == 2) + { + BigInteger r = DecodeValue(n, seq, 0); + BigInteger s = DecodeValue(n, seq, 1); + + byte[] expectedEncoding = Encode(n, r, s); + if (Arrays.AreEqual(expectedEncoding, encoding)) + return new BigInteger[]{ r, s }; + } + + throw new ArgumentException("Malformed signature", "encoding"); + } + + public virtual byte[] Encode(BigInteger n, BigInteger r, BigInteger s) + { + return new DerSequence( + EncodeValue(n, r), + EncodeValue(n, s) + ).GetEncoded(Asn1Encodable.Der); + } + + protected virtual BigInteger CheckValue(BigInteger n, BigInteger x) + { + if (x.SignValue < 0 || (null != n && x.CompareTo(n) >= 0)) + throw new ArgumentException("Value out of range", "x"); + + return x; + } + + protected virtual BigInteger DecodeValue(BigInteger n, Asn1Sequence s, int pos) + { + return CheckValue(n, ((DerInteger)s[pos]).Value); + } + + protected virtual DerInteger EncodeValue(BigInteger n, BigInteger x) + { + return new DerInteger(CheckValue(n, x)); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/StandardDsaEncoding.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/StandardDsaEncoding.cs.meta new file mode 100644 index 0000000..22af94b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/StandardDsaEncoding.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1f32ce039648d7a4499fc79d4de68d12 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/X931Signer.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/X931Signer.cs new file mode 100644 index 0000000..6aeff87 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/X931Signer.cs @@ -0,0 +1,226 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Signers +{ + /** + * X9.31-1998 - signing using a hash. + *

+ * The message digest hash, H, is encapsulated to form a byte string as follows + *

+ *
+     * EB = 06 || PS || 0xBA || H || TRAILER
+     * 
+ * where PS is a string of bytes all of value 0xBB of length such that |EB|=|n|, and TRAILER is the ISO/IEC 10118 part number† for the digest. The byte string, EB, is converted to an integer value, the message representative, f. + */ + public class X931Signer + : ISigner + { + [Obsolete("Use 'IsoTrailers' instead")] + public const int TRAILER_IMPLICIT = 0xBC; + [Obsolete("Use 'IsoTrailers' instead")] + public const int TRAILER_RIPEMD160 = 0x31CC; + [Obsolete("Use 'IsoTrailers' instead")] + public const int TRAILER_RIPEMD128 = 0x32CC; + [Obsolete("Use 'IsoTrailers' instead")] + public const int TRAILER_SHA1 = 0x33CC; + [Obsolete("Use 'IsoTrailers' instead")] + public const int TRAILER_SHA256 = 0x34CC; + [Obsolete("Use 'IsoTrailers' instead")] + public const int TRAILER_SHA512 = 0x35CC; + [Obsolete("Use 'IsoTrailers' instead")] + public const int TRAILER_SHA384 = 0x36CC; + [Obsolete("Use 'IsoTrailers' instead")] + public const int TRAILER_WHIRLPOOL = 0x37CC; + [Obsolete("Use 'IsoTrailers' instead")] + public const int TRAILER_SHA224 = 0x38CC; + + private IDigest digest; + private IAsymmetricBlockCipher cipher; + private RsaKeyParameters kParam; + + private int trailer; + private int keyBits; + private byte[] block; + + /** + * Generate a signer with either implicit or explicit trailers for X9.31. + * + * @param cipher base cipher to use for signature creation/verification + * @param digest digest to use. + * @param implicit whether or not the trailer is implicit or gives the hash. + */ + public X931Signer(IAsymmetricBlockCipher cipher, IDigest digest, bool isImplicit) + { + this.cipher = cipher; + this.digest = digest; + + if (isImplicit) + { + trailer = IsoTrailers.TRAILER_IMPLICIT; + } + else if (IsoTrailers.NoTrailerAvailable(digest)) + { + throw new ArgumentException("no valid trailer", "digest"); + } + else + { + trailer = IsoTrailers.GetTrailer(digest); + } + } + + public virtual string AlgorithmName + { + get { return digest.AlgorithmName + "with" + cipher.AlgorithmName + "/X9.31"; } + } + + /** + * Constructor for a signer with an explicit digest trailer. + * + * @param cipher cipher to use. + * @param digest digest to sign with. + */ + public X931Signer(IAsymmetricBlockCipher cipher, IDigest digest) + : this(cipher, digest, false) + { + } + + public virtual void Init(bool forSigning, ICipherParameters parameters) + { + kParam = (RsaKeyParameters)parameters; + + cipher.Init(forSigning, kParam); + + keyBits = kParam.Modulus.BitLength; + + block = new byte[(keyBits + 7) / 8]; + + Reset(); + } + + /// clear possible sensitive data + private void ClearBlock(byte[] block) + { + Array.Clear(block, 0, block.Length); + } + + /** + * update the internal digest with the byte b + */ + public virtual void Update(byte b) + { + digest.Update(b); + } + + /** + * update the internal digest with the byte array in + */ + public virtual void BlockUpdate(byte[] input, int off, int len) + { + digest.BlockUpdate(input, off, len); + } + + /** + * reset the internal state + */ + public virtual void Reset() + { + digest.Reset(); + } + + /** + * generate a signature for the loaded message using the key we were + * initialised with. + */ + public virtual byte[] GenerateSignature() + { + CreateSignatureBlock(); + + BigInteger t = new BigInteger(1, cipher.ProcessBlock(block, 0, block.Length)); + ClearBlock(block); + + t = t.Min(kParam.Modulus.Subtract(t)); + + int size = BigIntegers.GetUnsignedByteLength(kParam.Modulus); + return BigIntegers.AsUnsignedByteArray(size, t); + } + + private void CreateSignatureBlock() + { + int digSize = digest.GetDigestSize(); + + int delta; + if (trailer == IsoTrailers.TRAILER_IMPLICIT) + { + delta = block.Length - digSize - 1; + digest.DoFinal(block, delta); + block[block.Length - 1] = (byte)IsoTrailers.TRAILER_IMPLICIT; + } + else + { + delta = block.Length - digSize - 2; + digest.DoFinal(block, delta); + block[block.Length - 2] = (byte)(trailer >> 8); + block[block.Length - 1] = (byte)trailer; + } + + block[0] = 0x6b; + for (int i = delta - 2; i != 0; i--) + { + block[i] = (byte)0xbb; + } + block[delta - 1] = (byte)0xba; + } + + /** + * return true if the signature represents a ISO9796-2 signature + * for the passed in message. + */ + public virtual bool VerifySignature(byte[] signature) + { + try + { + block = cipher.ProcessBlock(signature, 0, signature.Length); + } + catch (Exception) + { + return false; + } + + BigInteger t = new BigInteger(1, block); + BigInteger f; + + if ((t.IntValue & 15) == 12) + { + f = t; + } + else + { + t = kParam.Modulus.Subtract(t); + if ((t.IntValue & 15) == 12) + { + f = t; + } + else + { + return false; + } + } + + CreateSignatureBlock(); + + byte[] fBlock = BigIntegers.AsUnsignedByteArray(block.Length, f); + + bool rv = Arrays.ConstantTimeAreEqual(block, fBlock); + + ClearBlock(block); + ClearBlock(fBlock); + + return rv; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/X931Signer.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/X931Signer.cs.meta new file mode 100644 index 0000000..7a6c641 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/signers/X931Signer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5afc1f2dff9d8704ead68d3516a03dc9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls.meta new file mode 100644 index 0000000..adf5eae --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f315b941c7630284dbb7a98eeaee8035 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsAgreementCredentials.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsAgreementCredentials.cs new file mode 100644 index 0000000..2d7af80 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsAgreementCredentials.cs @@ -0,0 +1,12 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class AbstractTlsAgreementCredentials + : AbstractTlsCredentials, TlsAgreementCredentials + { + /// + public abstract byte[] GenerateAgreement(AsymmetricKeyParameter peerPublicKey); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsAgreementCredentials.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsAgreementCredentials.cs.meta new file mode 100644 index 0000000..afd6ce7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsAgreementCredentials.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5421203df4ee2184ab11883fe17abe07 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsCipherFactory.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsCipherFactory.cs new file mode 100644 index 0000000..141ee65 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsCipherFactory.cs @@ -0,0 +1,15 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class AbstractTlsCipherFactory + : TlsCipherFactory + { + /// + public virtual TlsCipher CreateCipher(TlsContext context, int encryptionAlgorithm, int macAlgorithm) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsCipherFactory.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsCipherFactory.cs.meta new file mode 100644 index 0000000..183a821 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsCipherFactory.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cf628a3eb3fec5847ba7231beccbc22d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsClient.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsClient.cs new file mode 100644 index 0000000..356aab8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsClient.cs @@ -0,0 +1,266 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class AbstractTlsClient + : AbstractTlsPeer, TlsClient + { + protected TlsCipherFactory mCipherFactory; + + protected TlsClientContext mContext; + + protected IList mSupportedSignatureAlgorithms; + protected int[] mNamedCurves; + protected byte[] mClientECPointFormats, mServerECPointFormats; + + protected int mSelectedCipherSuite; + protected short mSelectedCompressionMethod; + + public AbstractTlsClient() + : this(new DefaultTlsCipherFactory()) + { + } + + public AbstractTlsClient(TlsCipherFactory cipherFactory) + { + this.mCipherFactory = cipherFactory; + } + + protected virtual bool AllowUnexpectedServerExtension(int extensionType, byte[] extensionData) + { + switch (extensionType) + { + case ExtensionType.supported_groups: + /* + * Exception added based on field reports that some servers do send this, although the + * Supported Elliptic Curves Extension is clearly intended to be client-only. If + * present, we still require that it is a valid EllipticCurveList. + */ + TlsEccUtilities.ReadSupportedEllipticCurvesExtension(extensionData); + return true; + + case ExtensionType.ec_point_formats: + /* + * Exception added based on field reports that some servers send this even when they + * didn't negotiate an ECC cipher suite. If present, we still require that it is a valid + * ECPointFormatList. + */ + TlsEccUtilities.ReadSupportedPointFormatsExtension(extensionData); + return true; + + default: + return false; + } + } + + protected virtual void CheckForUnexpectedServerExtension(IDictionary serverExtensions, int extensionType) + { + byte[] extensionData = TlsUtilities.GetExtensionData(serverExtensions, extensionType); + if (extensionData != null && !AllowUnexpectedServerExtension(extensionType, extensionData)) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + } + + public virtual void Init(TlsClientContext context) + { + this.mContext = context; + } + + public virtual TlsSession GetSessionToResume() + { + return null; + } + + public virtual ProtocolVersion ClientHelloRecordLayerVersion + { + get + { + // "{03,00}" + //return ProtocolVersion.SSLv3; + + // "the lowest version number supported by the client" + //return MinimumVersion; + + // "the value of ClientHello.client_version" + return ClientVersion; + } + } + + public virtual ProtocolVersion ClientVersion + { + get { return ProtocolVersion.TLSv12; } + } + + public virtual bool IsFallback + { + /* + * RFC 7507 4. The TLS_FALLBACK_SCSV cipher suite value is meant for use by clients that + * repeat a connection attempt with a downgraded protocol (perform a "fallback retry") in + * order to work around interoperability problems with legacy servers. + */ + get { return false; } + } + + public virtual IDictionary GetClientExtensions() + { + IDictionary clientExtensions = null; + + ProtocolVersion clientVersion = mContext.ClientVersion; + + /* + * RFC 5246 7.4.1.4.1. Note: this extension is not meaningful for TLS versions prior to 1.2. + * Clients MUST NOT offer it if they are offering prior versions. + */ + if (TlsUtilities.IsSignatureAlgorithmsExtensionAllowed(clientVersion)) + { + // TODO Provide a way for the user to specify the acceptable hash/signature algorithms. + + this.mSupportedSignatureAlgorithms = TlsUtilities.GetDefaultSupportedSignatureAlgorithms(); + + clientExtensions = TlsExtensionsUtilities.EnsureExtensionsInitialised(clientExtensions); + + TlsUtilities.AddSignatureAlgorithmsExtension(clientExtensions, mSupportedSignatureAlgorithms); + } + + if (TlsEccUtilities.ContainsEccCipherSuites(GetCipherSuites())) + { + /* + * RFC 4492 5.1. A client that proposes ECC cipher suites in its ClientHello message + * appends these extensions (along with any others), enumerating the curves it supports + * and the point formats it can parse. Clients SHOULD send both the Supported Elliptic + * Curves Extension and the Supported Point Formats Extension. + */ + /* + * TODO Could just add all the curves since we support them all, but users may not want + * to use unnecessarily large fields. Need configuration options. + */ + this.mNamedCurves = new int[]{ NamedCurve.secp256r1, NamedCurve.secp384r1 }; + this.mClientECPointFormats = new byte[]{ ECPointFormat.uncompressed, + ECPointFormat.ansiX962_compressed_prime, ECPointFormat.ansiX962_compressed_char2, }; + + clientExtensions = TlsExtensionsUtilities.EnsureExtensionsInitialised(clientExtensions); + + TlsEccUtilities.AddSupportedEllipticCurvesExtension(clientExtensions, mNamedCurves); + TlsEccUtilities.AddSupportedPointFormatsExtension(clientExtensions, mClientECPointFormats); + } + + return clientExtensions; + } + + public virtual ProtocolVersion MinimumVersion + { + get { return ProtocolVersion.TLSv10; } + } + + public virtual void NotifyServerVersion(ProtocolVersion serverVersion) + { + if (!MinimumVersion.IsEqualOrEarlierVersionOf(serverVersion)) + throw new TlsFatalAlert(AlertDescription.protocol_version); + } + + public abstract int[] GetCipherSuites(); + + public virtual byte[] GetCompressionMethods() + { + return new byte[]{ CompressionMethod.cls_null }; + } + + public virtual void NotifySessionID(byte[] sessionID) + { + // Currently ignored + } + + public virtual void NotifySelectedCipherSuite(int selectedCipherSuite) + { + this.mSelectedCipherSuite = selectedCipherSuite; + } + + public virtual void NotifySelectedCompressionMethod(byte selectedCompressionMethod) + { + this.mSelectedCompressionMethod = selectedCompressionMethod; + } + + public virtual void ProcessServerExtensions(IDictionary serverExtensions) + { + /* + * TlsProtocol implementation validates that any server extensions received correspond to + * client extensions sent. By default, we don't send any, and this method is not called. + */ + if (serverExtensions != null) + { + /* + * RFC 5246 7.4.1.4.1. Servers MUST NOT send this extension. + */ + CheckForUnexpectedServerExtension(serverExtensions, ExtensionType.signature_algorithms); + + CheckForUnexpectedServerExtension(serverExtensions, ExtensionType.supported_groups); + + if (TlsEccUtilities.IsEccCipherSuite(this.mSelectedCipherSuite)) + { + this.mServerECPointFormats = TlsEccUtilities.GetSupportedPointFormatsExtension(serverExtensions); + } + else + { + CheckForUnexpectedServerExtension(serverExtensions, ExtensionType.ec_point_formats); + } + + /* + * RFC 7685 3. The server MUST NOT echo the extension. + */ + CheckForUnexpectedServerExtension(serverExtensions, ExtensionType.padding); + } + } + + public virtual void ProcessServerSupplementalData(IList serverSupplementalData) + { + if (serverSupplementalData != null) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + public abstract TlsKeyExchange GetKeyExchange(); + + public abstract TlsAuthentication GetAuthentication(); + + public virtual IList GetClientSupplementalData() + { + return null; + } + + public override TlsCompression GetCompression() + { + switch (mSelectedCompressionMethod) + { + case CompressionMethod.cls_null: + return new TlsNullCompression(); + + case CompressionMethod.DEFLATE: + return new TlsDeflateCompression(); + + default: + /* + * Note: internal error here; the TlsProtocol implementation verifies that the + * server-selected compression method was in the list of client-offered compression + * methods, so if we now can't produce an implementation, we shouldn't have offered it! + */ + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + public override TlsCipher GetCipher() + { + int encryptionAlgorithm = TlsUtilities.GetEncryptionAlgorithm(mSelectedCipherSuite); + int macAlgorithm = TlsUtilities.GetMacAlgorithm(mSelectedCipherSuite); + + return mCipherFactory.CreateCipher(mContext, encryptionAlgorithm, macAlgorithm); + } + + public virtual void NotifyNewSessionTicket(NewSessionTicket newSessionTicket) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsClient.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsClient.cs.meta new file mode 100644 index 0000000..5bfdf3e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsClient.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5dd844e8e4a84a94e8d8f338051e36b6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsContext.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsContext.cs new file mode 100644 index 0000000..bbcdb5e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsContext.cs @@ -0,0 +1,166 @@ +using System; +using System.Threading; + +using Org.BouncyCastle.Crypto.Prng; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + internal abstract class AbstractTlsContext + : TlsContext + { + private static long counter = Times.NanoTime(); + +#if NETCF_1_0 + private static object counterLock = new object(); + private static long NextCounterValue() + { + lock (counterLock) + { + return ++counter; + } + } +#else + private static long NextCounterValue() + { + return Interlocked.Increment(ref counter); + } +#endif + + private static IRandomGenerator CreateNonceRandom(SecureRandom secureRandom, int connectionEnd) + { + byte[] additionalSeedMaterial = new byte[16]; + Pack.UInt64_To_BE((ulong)NextCounterValue(), additionalSeedMaterial, 0); + Pack.UInt64_To_BE((ulong)Times.NanoTime(), additionalSeedMaterial, 8); + additionalSeedMaterial[0] &= 0x7F; + additionalSeedMaterial[0] |= (byte)(connectionEnd << 7); + + IDigest digest = TlsUtilities.CreateHash(HashAlgorithm.sha256); + + byte[] seed = new byte[digest.GetDigestSize()]; + secureRandom.NextBytes(seed); + + IRandomGenerator nonceRandom = new DigestRandomGenerator(digest); + nonceRandom.AddSeedMaterial(additionalSeedMaterial); + nonceRandom.AddSeedMaterial(seed); + return nonceRandom; + } + + private readonly IRandomGenerator mNonceRandom; + private readonly SecureRandom mSecureRandom; + private readonly SecurityParameters mSecurityParameters; + + private ProtocolVersion mClientVersion = null; + private ProtocolVersion mServerVersion = null; + private TlsSession mSession = null; + private object mUserObject = null; + + internal AbstractTlsContext(SecureRandom secureRandom, SecurityParameters securityParameters) + { + this.mSecureRandom = secureRandom; + this.mSecurityParameters = securityParameters; + this.mNonceRandom = CreateNonceRandom(secureRandom, securityParameters.Entity); + } + + public virtual IRandomGenerator NonceRandomGenerator + { + get { return mNonceRandom; } + } + + public virtual SecureRandom SecureRandom + { + get { return mSecureRandom; } + } + + public virtual SecurityParameters SecurityParameters + { + get { return mSecurityParameters; } + } + + public abstract bool IsServer { get; } + + public virtual ProtocolVersion ClientVersion + { + get { return mClientVersion; } + } + + internal virtual void SetClientVersion(ProtocolVersion clientVersion) + { + this.mClientVersion = clientVersion; + } + + public virtual ProtocolVersion ServerVersion + { + get { return mServerVersion; } + } + + internal virtual void SetServerVersion(ProtocolVersion serverVersion) + { + this.mServerVersion = serverVersion; + } + + public virtual TlsSession ResumableSession + { + get { return mSession; } + } + + internal virtual void SetResumableSession(TlsSession session) + { + this.mSession = session; + } + + public virtual object UserObject + { + get { return mUserObject; } + set { this.mUserObject = value; } + } + + public virtual byte[] ExportKeyingMaterial(string asciiLabel, byte[] context_value, int length) + { + if (context_value != null && !TlsUtilities.IsValidUint16(context_value.Length)) + throw new ArgumentException("must have length less than 2^16 (or be null)", "context_value"); + + SecurityParameters sp = SecurityParameters; + if (!sp.IsExtendedMasterSecret) + { + /* + * RFC 7627 5.4. If a client or server chooses to continue with a full handshake without + * the extended master secret extension, [..] the client or server MUST NOT export any + * key material based on the new master secret for any subsequent application-level + * authentication. In particular, it MUST disable [RFC5705] [..]. + */ + throw new InvalidOperationException("cannot export keying material without extended_master_secret"); + } + + byte[] cr = sp.ClientRandom, sr = sp.ServerRandom; + + int seedLength = cr.Length + sr.Length; + if (context_value != null) + { + seedLength += (2 + context_value.Length); + } + + byte[] seed = new byte[seedLength]; + int seedPos = 0; + + Array.Copy(cr, 0, seed, seedPos, cr.Length); + seedPos += cr.Length; + Array.Copy(sr, 0, seed, seedPos, sr.Length); + seedPos += sr.Length; + if (context_value != null) + { + TlsUtilities.WriteUint16(context_value.Length, seed, seedPos); + seedPos += 2; + Array.Copy(context_value, 0, seed, seedPos, context_value.Length); + seedPos += context_value.Length; + } + + if (seedPos != seedLength) + throw new InvalidOperationException("error in calculation of seed for export"); + + return TlsUtilities.PRF(this, sp.MasterSecret, asciiLabel, seed, length); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsContext.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsContext.cs.meta new file mode 100644 index 0000000..a608b09 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsContext.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3d9039d043aafe848b978f8f514a5b9e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsCredentials.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsCredentials.cs new file mode 100644 index 0000000..6411b81 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsCredentials.cs @@ -0,0 +1,10 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class AbstractTlsCredentials + : TlsCredentials + { + public abstract Certificate Certificate { get; } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsCredentials.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsCredentials.cs.meta new file mode 100644 index 0000000..98993f1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsCredentials.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e4a72f64089c1424b93491ca00bb32f4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsEncryptionCredentials.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsEncryptionCredentials.cs new file mode 100644 index 0000000..05b129c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsEncryptionCredentials.cs @@ -0,0 +1,12 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class AbstractTlsEncryptionCredentials + : AbstractTlsCredentials, TlsEncryptionCredentials + { + /// + public abstract byte[] DecryptPreMasterSecret(byte[] encryptedPreMasterSecret); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsEncryptionCredentials.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsEncryptionCredentials.cs.meta new file mode 100644 index 0000000..cfdd122 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsEncryptionCredentials.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4fa7413ad8836a746925c1ce729d4d5b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsKeyExchange.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsKeyExchange.cs new file mode 100644 index 0000000..294b249 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsKeyExchange.cs @@ -0,0 +1,177 @@ +using System; +using System.Collections; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class AbstractTlsKeyExchange + : TlsKeyExchange + { + protected readonly int mKeyExchange; + protected IList mSupportedSignatureAlgorithms; + + protected TlsContext mContext; + + protected AbstractTlsKeyExchange(int keyExchange, IList supportedSignatureAlgorithms) + { + this.mKeyExchange = keyExchange; + this.mSupportedSignatureAlgorithms = supportedSignatureAlgorithms; + } + + protected virtual DigitallySigned ParseSignature(Stream input) + { + DigitallySigned signature = DigitallySigned.Parse(mContext, input); + SignatureAndHashAlgorithm signatureAlgorithm = signature.Algorithm; + if (signatureAlgorithm != null) + { + TlsUtilities.VerifySupportedSignatureAlgorithm(mSupportedSignatureAlgorithms, signatureAlgorithm); + } + return signature; + } + + public virtual void Init(TlsContext context) + { + this.mContext = context; + + ProtocolVersion clientVersion = context.ClientVersion; + + if (TlsUtilities.IsSignatureAlgorithmsExtensionAllowed(clientVersion)) + { + /* + * RFC 5246 7.4.1.4.1. If the client does not send the signature_algorithms extension, + * the server MUST do the following: + * + * - If the negotiated key exchange algorithm is one of (RSA, DHE_RSA, DH_RSA, RSA_PSK, + * ECDH_RSA, ECDHE_RSA), behave as if client had sent the value {sha1,rsa}. + * + * - If the negotiated key exchange algorithm is one of (DHE_DSS, DH_DSS), behave as if + * the client had sent the value {sha1,dsa}. + * + * - If the negotiated key exchange algorithm is one of (ECDH_ECDSA, ECDHE_ECDSA), + * behave as if the client had sent value {sha1,ecdsa}. + */ + if (this.mSupportedSignatureAlgorithms == null) + { + switch (mKeyExchange) + { + case KeyExchangeAlgorithm.DH_DSS: + case KeyExchangeAlgorithm.DHE_DSS: + case KeyExchangeAlgorithm.SRP_DSS: + { + this.mSupportedSignatureAlgorithms = TlsUtilities.GetDefaultDssSignatureAlgorithms(); + break; + } + + case KeyExchangeAlgorithm.ECDH_ECDSA: + case KeyExchangeAlgorithm.ECDHE_ECDSA: + { + this.mSupportedSignatureAlgorithms = TlsUtilities.GetDefaultECDsaSignatureAlgorithms(); + break; + } + + case KeyExchangeAlgorithm.DH_RSA: + case KeyExchangeAlgorithm.DHE_RSA: + case KeyExchangeAlgorithm.ECDH_RSA: + case KeyExchangeAlgorithm.ECDHE_RSA: + case KeyExchangeAlgorithm.RSA: + case KeyExchangeAlgorithm.RSA_PSK: + case KeyExchangeAlgorithm.SRP_RSA: + { + this.mSupportedSignatureAlgorithms = TlsUtilities.GetDefaultRsaSignatureAlgorithms(); + break; + } + + case KeyExchangeAlgorithm.DHE_PSK: + case KeyExchangeAlgorithm.ECDHE_PSK: + case KeyExchangeAlgorithm.PSK: + case KeyExchangeAlgorithm.SRP: + break; + + default: + throw new InvalidOperationException("unsupported key exchange algorithm"); + } + } + + } + else if (this.mSupportedSignatureAlgorithms != null) + { + throw new InvalidOperationException("supported_signature_algorithms not allowed for " + clientVersion); + } + } + + public abstract void SkipServerCredentials(); + + public virtual void ProcessServerCertificate(Certificate serverCertificate) + { + if (mSupportedSignatureAlgorithms == null) + { + /* + * TODO RFC 2246 7.4.2. Unless otherwise specified, the signing algorithm for the + * certificate must be the same as the algorithm for the certificate key. + */ + } + else + { + /* + * TODO RFC 5246 7.4.2. If the client provided a "signature_algorithms" extension, then + * all certificates provided by the server MUST be signed by a hash/signature algorithm + * pair that appears in that extension. + */ + } + } + + public virtual void ProcessServerCredentials(TlsCredentials serverCredentials) + { + ProcessServerCertificate(serverCredentials.Certificate); + } + + public virtual bool RequiresServerKeyExchange + { + get { return false; } + } + + public virtual byte[] GenerateServerKeyExchange() + { + if (RequiresServerKeyExchange) + throw new TlsFatalAlert(AlertDescription.internal_error); + + return null; + } + + public virtual void SkipServerKeyExchange() + { + if (RequiresServerKeyExchange) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + public virtual void ProcessServerKeyExchange(Stream input) + { + if (!RequiresServerKeyExchange) + { + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + } + + public abstract void ValidateCertificateRequest(CertificateRequest certificateRequest); + + public virtual void SkipClientCredentials() + { + } + + public abstract void ProcessClientCredentials(TlsCredentials clientCredentials); + + public virtual void ProcessClientCertificate(Certificate clientCertificate) + { + } + + public abstract void GenerateClientKeyExchange(Stream output); + + public virtual void ProcessClientKeyExchange(Stream input) + { + // Key exchange implementation MUST support client key exchange + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public abstract byte[] GeneratePremasterSecret(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsKeyExchange.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsKeyExchange.cs.meta new file mode 100644 index 0000000..c215fc1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsKeyExchange.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b8782a8fdc71ade4cb19232636b15680 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsPeer.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsPeer.cs new file mode 100644 index 0000000..e7bfc17 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsPeer.cs @@ -0,0 +1,75 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class AbstractTlsPeer + : TlsPeer + { + private volatile TlsCloseable mCloseHandle; + + /// + public virtual void Cancel() + { + TlsCloseable closeHandle = this.mCloseHandle; + if (null != closeHandle) + { + closeHandle.Close(); + } + } + + public virtual void NotifyCloseHandle(TlsCloseable closeHandle) + { + this.mCloseHandle = closeHandle; + } + + public virtual int GetHandshakeTimeoutMillis() + { + return 0; + } + + public virtual bool RequiresExtendedMasterSecret() + { + return false; + } + + public virtual bool ShouldUseGmtUnixTime() + { + /* + * draft-mathewson-no-gmtunixtime-00 2. For the reasons we discuss above, we recommend that + * TLS implementors MUST by default set the entire value the ClientHello.Random and + * ServerHello.Random fields, including gmt_unix_time, to a cryptographically random + * sequence. + */ + return false; + } + + public virtual void NotifySecureRenegotiation(bool secureRenegotiation) + { + if (!secureRenegotiation) + { + /* + * RFC 5746 3.4/3.6. In this case, some clients/servers may want to terminate the handshake instead + * of continuing; see Section 4.1/4.3 for discussion. + */ + throw new TlsFatalAlert(AlertDescription.handshake_failure); + } + } + + public abstract TlsCompression GetCompression(); + + public abstract TlsCipher GetCipher(); + + public virtual void NotifyAlertRaised(byte alertLevel, byte alertDescription, string message, Exception cause) + { + } + + public virtual void NotifyAlertReceived(byte alertLevel, byte alertDescription) + { + } + + public virtual void NotifyHandshakeComplete() + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsPeer.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsPeer.cs.meta new file mode 100644 index 0000000..2b22b47 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsPeer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4b5f84cd220a52c4282a4ad16bd99ab1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsServer.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsServer.cs new file mode 100644 index 0000000..52a79c9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsServer.cs @@ -0,0 +1,351 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class AbstractTlsServer + : AbstractTlsPeer, TlsServer + { + protected TlsCipherFactory mCipherFactory; + + protected TlsServerContext mContext; + + protected ProtocolVersion mClientVersion; + protected int[] mOfferedCipherSuites; + protected byte[] mOfferedCompressionMethods; + protected IDictionary mClientExtensions; + + protected bool mEncryptThenMacOffered; + protected short mMaxFragmentLengthOffered; + protected bool mTruncatedHMacOffered; + protected IList mSupportedSignatureAlgorithms; + protected bool mEccCipherSuitesOffered; + protected int[] mNamedCurves; + protected byte[] mClientECPointFormats, mServerECPointFormats; + + protected ProtocolVersion mServerVersion; + protected int mSelectedCipherSuite; + protected byte mSelectedCompressionMethod; + protected IDictionary mServerExtensions; + + public AbstractTlsServer() + : this(new DefaultTlsCipherFactory()) + { + } + + public AbstractTlsServer(TlsCipherFactory cipherFactory) + { + this.mCipherFactory = cipherFactory; + } + + protected virtual bool AllowEncryptThenMac + { + get { return true; } + } + + protected virtual bool AllowTruncatedHMac + { + get { return false; } + } + + protected virtual IDictionary CheckServerExtensions() + { + return this.mServerExtensions = TlsExtensionsUtilities.EnsureExtensionsInitialised(this.mServerExtensions); + } + + protected abstract int[] GetCipherSuites(); + + protected byte[] GetCompressionMethods() + { + return new byte[] { CompressionMethod.cls_null }; + } + + protected virtual ProtocolVersion MaximumVersion + { + get { return ProtocolVersion.TLSv11; } + } + + protected virtual ProtocolVersion MinimumVersion + { + get { return ProtocolVersion.TLSv10; } + } + + protected virtual bool SupportsClientEccCapabilities(int[] namedCurves, byte[] ecPointFormats) + { + // NOTE: BC supports all the current set of point formats so we don't check them here + + if (namedCurves == null) + { + /* + * RFC 4492 4. A client that proposes ECC cipher suites may choose not to include these + * extensions. In this case, the server is free to choose any one of the elliptic curves + * or point formats [...]. + */ + return TlsEccUtilities.HasAnySupportedNamedCurves(); + } + + for (int i = 0; i < namedCurves.Length; ++i) + { + int namedCurve = namedCurves[i]; + if (NamedCurve.IsValid(namedCurve) + && (!NamedCurve.RefersToASpecificNamedCurve(namedCurve) || TlsEccUtilities.IsSupportedNamedCurve(namedCurve))) + { + return true; + } + } + + return false; + } + + public virtual void Init(TlsServerContext context) + { + this.mContext = context; + } + + public virtual void NotifyClientVersion(ProtocolVersion clientVersion) + { + this.mClientVersion = clientVersion; + } + + public virtual void NotifyFallback(bool isFallback) + { + /* + * RFC 7507 3. If TLS_FALLBACK_SCSV appears in ClientHello.cipher_suites and the highest + * protocol version supported by the server is higher than the version indicated in + * ClientHello.client_version, the server MUST respond with a fatal inappropriate_fallback + * alert [..]. + */ + if (isFallback && MaximumVersion.IsLaterVersionOf(mClientVersion)) + throw new TlsFatalAlert(AlertDescription.inappropriate_fallback); + } + + public virtual void NotifyOfferedCipherSuites(int[] offeredCipherSuites) + { + this.mOfferedCipherSuites = offeredCipherSuites; + this.mEccCipherSuitesOffered = TlsEccUtilities.ContainsEccCipherSuites(this.mOfferedCipherSuites); + } + + public virtual void NotifyOfferedCompressionMethods(byte[] offeredCompressionMethods) + { + this.mOfferedCompressionMethods = offeredCompressionMethods; + } + + public virtual void ProcessClientExtensions(IDictionary clientExtensions) + { + this.mClientExtensions = clientExtensions; + + if (clientExtensions != null) + { + this.mEncryptThenMacOffered = TlsExtensionsUtilities.HasEncryptThenMacExtension(clientExtensions); + + this.mMaxFragmentLengthOffered = TlsExtensionsUtilities.GetMaxFragmentLengthExtension(clientExtensions); + if (mMaxFragmentLengthOffered >= 0 && !MaxFragmentLength.IsValid((byte)mMaxFragmentLengthOffered)) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + this.mTruncatedHMacOffered = TlsExtensionsUtilities.HasTruncatedHMacExtension(clientExtensions); + + this.mSupportedSignatureAlgorithms = TlsUtilities.GetSignatureAlgorithmsExtension(clientExtensions); + if (this.mSupportedSignatureAlgorithms != null) + { + /* + * RFC 5246 7.4.1.4.1. Note: this extension is not meaningful for TLS versions prior + * to 1.2. Clients MUST NOT offer it if they are offering prior versions. + */ + if (!TlsUtilities.IsSignatureAlgorithmsExtensionAllowed(mClientVersion)) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + this.mNamedCurves = TlsEccUtilities.GetSupportedEllipticCurvesExtension(clientExtensions); + this.mClientECPointFormats = TlsEccUtilities.GetSupportedPointFormatsExtension(clientExtensions); + } + + /* + * RFC 4429 4. The client MUST NOT include these extensions in the ClientHello message if it + * does not propose any ECC cipher suites. + * + * NOTE: This was overly strict as there may be ECC cipher suites that we don't recognize. + * Also, draft-ietf-tls-negotiated-ff-dhe will be overloading the 'elliptic_curves' + * extension to explicitly allow FFDHE (i.e. non-ECC) groups. + */ + //if (!this.mEccCipherSuitesOffered && (this.mNamedCurves != null || this.mClientECPointFormats != null)) + // throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + public virtual ProtocolVersion GetServerVersion() + { + if (MinimumVersion.IsEqualOrEarlierVersionOf(mClientVersion)) + { + ProtocolVersion maximumVersion = MaximumVersion; + if (mClientVersion.IsEqualOrEarlierVersionOf(maximumVersion)) + { + return mServerVersion = mClientVersion; + } + if (mClientVersion.IsLaterVersionOf(maximumVersion)) + { + return mServerVersion = maximumVersion; + } + } + throw new TlsFatalAlert(AlertDescription.protocol_version); + } + + public virtual int GetSelectedCipherSuite() + { + /* + * RFC 5246 7.4.3. In order to negotiate correctly, the server MUST check any candidate + * cipher suites against the "signature_algorithms" extension before selecting them. This is + * somewhat inelegant but is a compromise designed to minimize changes to the original + * cipher suite design. + */ + IList sigAlgs = TlsUtilities.GetUsableSignatureAlgorithms(this.mSupportedSignatureAlgorithms); + + /* + * RFC 4429 5.1. A server that receives a ClientHello containing one or both of these + * extensions MUST use the client's enumerated capabilities to guide its selection of an + * appropriate cipher suite. One of the proposed ECC cipher suites must be negotiated only + * if the server can successfully complete the handshake while using the curves and point + * formats supported by the client [...]. + */ + bool eccCipherSuitesEnabled = SupportsClientEccCapabilities(this.mNamedCurves, this.mClientECPointFormats); + + int[] cipherSuites = GetCipherSuites(); + for (int i = 0; i < cipherSuites.Length; ++i) + { + int cipherSuite = cipherSuites[i]; + + if (Arrays.Contains(this.mOfferedCipherSuites, cipherSuite) + && (eccCipherSuitesEnabled || !TlsEccUtilities.IsEccCipherSuite(cipherSuite)) + && TlsUtilities.IsValidCipherSuiteForVersion(cipherSuite, mServerVersion) + && TlsUtilities.IsValidCipherSuiteForSignatureAlgorithms(cipherSuite, sigAlgs)) + { + return this.mSelectedCipherSuite = cipherSuite; + } + } + throw new TlsFatalAlert(AlertDescription.handshake_failure); + } + + public virtual byte GetSelectedCompressionMethod() + { + byte[] compressionMethods = GetCompressionMethods(); + for (int i = 0; i < compressionMethods.Length; ++i) + { + if (Arrays.Contains(mOfferedCompressionMethods, compressionMethods[i])) + { + return this.mSelectedCompressionMethod = compressionMethods[i]; + } + } + throw new TlsFatalAlert(AlertDescription.handshake_failure); + } + + // IDictionary is (Int32 -> byte[]) + public virtual IDictionary GetServerExtensions() + { + if (this.mEncryptThenMacOffered && AllowEncryptThenMac) + { + /* + * RFC 7366 3. If a server receives an encrypt-then-MAC request extension from a client + * and then selects a stream or Authenticated Encryption with Associated Data (AEAD) + * ciphersuite, it MUST NOT send an encrypt-then-MAC response extension back to the + * client. + */ + if (TlsUtilities.IsBlockCipherSuite(this.mSelectedCipherSuite)) + { + TlsExtensionsUtilities.AddEncryptThenMacExtension(CheckServerExtensions()); + } + } + + if (this.mMaxFragmentLengthOffered >= 0 + && TlsUtilities.IsValidUint8(mMaxFragmentLengthOffered) + && MaxFragmentLength.IsValid((byte)mMaxFragmentLengthOffered)) + { + TlsExtensionsUtilities.AddMaxFragmentLengthExtension(CheckServerExtensions(), (byte)mMaxFragmentLengthOffered); + } + + if (this.mTruncatedHMacOffered && AllowTruncatedHMac) + { + TlsExtensionsUtilities.AddTruncatedHMacExtension(CheckServerExtensions()); + } + + if (this.mClientECPointFormats != null && TlsEccUtilities.IsEccCipherSuite(this.mSelectedCipherSuite)) + { + /* + * RFC 4492 5.2. A server that selects an ECC cipher suite in response to a ClientHello + * message including a Supported Point Formats Extension appends this extension (along + * with others) to its ServerHello message, enumerating the point formats it can parse. + */ + this.mServerECPointFormats = new byte[]{ ECPointFormat.uncompressed, + ECPointFormat.ansiX962_compressed_prime, ECPointFormat.ansiX962_compressed_char2, }; + + TlsEccUtilities.AddSupportedPointFormatsExtension(CheckServerExtensions(), mServerECPointFormats); + } + + return mServerExtensions; + } + + public virtual IList GetServerSupplementalData() + { + return null; + } + + public abstract TlsCredentials GetCredentials(); + + public virtual CertificateStatus GetCertificateStatus() + { + return null; + } + + public abstract TlsKeyExchange GetKeyExchange(); + + public virtual CertificateRequest GetCertificateRequest() + { + return null; + } + + public virtual void ProcessClientSupplementalData(IList clientSupplementalData) + { + if (clientSupplementalData != null) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + public virtual void NotifyClientCertificate(Certificate clientCertificate) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public override TlsCompression GetCompression() + { + switch (mSelectedCompressionMethod) + { + case CompressionMethod.cls_null: + return new TlsNullCompression(); + + default: + /* + * Note: internal error here; we selected the compression method, so if we now can't + * produce an implementation, we shouldn't have chosen it! + */ + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + public override TlsCipher GetCipher() + { + int encryptionAlgorithm = TlsUtilities.GetEncryptionAlgorithm(mSelectedCipherSuite); + int macAlgorithm = TlsUtilities.GetMacAlgorithm(mSelectedCipherSuite); + + return mCipherFactory.CreateCipher(mContext, encryptionAlgorithm, macAlgorithm); + } + + public virtual NewSessionTicket GetNewSessionTicket() + { + /* + * RFC 5077 3.3. If the server determines that it does not want to include a ticket after it + * has included the SessionTicket extension in the ServerHello, then it sends a zero-length + * ticket in the NewSessionTicket handshake message. + */ + return new NewSessionTicket(0L, TlsUtilities.EmptyBytes); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsServer.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsServer.cs.meta new file mode 100644 index 0000000..4a3e8b0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsServer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e0acba31fdf5c1149918d8d90267a7ce +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsSigner.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsSigner.cs new file mode 100644 index 0000000..1f4aabf --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsSigner.cs @@ -0,0 +1,50 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class AbstractTlsSigner + : TlsSigner + { + protected TlsContext mContext; + + public virtual void Init(TlsContext context) + { + this.mContext = context; + } + + public virtual byte[] GenerateRawSignature(AsymmetricKeyParameter privateKey, byte[] md5AndSha1) + { + return GenerateRawSignature(null, privateKey, md5AndSha1); + } + + public abstract byte[] GenerateRawSignature(SignatureAndHashAlgorithm algorithm, + AsymmetricKeyParameter privateKey, byte[] hash); + + public virtual bool VerifyRawSignature(byte[] sigBytes, AsymmetricKeyParameter publicKey, byte[] md5AndSha1) + { + return VerifyRawSignature(null, sigBytes, publicKey, md5AndSha1); + } + + public abstract bool VerifyRawSignature(SignatureAndHashAlgorithm algorithm, byte[] sigBytes, + AsymmetricKeyParameter publicKey, byte[] hash); + + public virtual ISigner CreateSigner(AsymmetricKeyParameter privateKey) + { + return CreateSigner(null, privateKey); + } + + public abstract ISigner CreateSigner(SignatureAndHashAlgorithm algorithm, AsymmetricKeyParameter privateKey); + + public virtual ISigner CreateVerifyer(AsymmetricKeyParameter publicKey) + { + return CreateVerifyer(null, publicKey); + } + + public abstract ISigner CreateVerifyer(SignatureAndHashAlgorithm algorithm, AsymmetricKeyParameter publicKey); + + public abstract bool IsValidPublicKey(AsymmetricKeyParameter publicKey); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsSigner.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsSigner.cs.meta new file mode 100644 index 0000000..5de4b86 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsSigner.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1b5757fcd8b3b96438316064b59676d6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsSignerCredentials.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsSignerCredentials.cs new file mode 100644 index 0000000..886c46c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsSignerCredentials.cs @@ -0,0 +1,20 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class AbstractTlsSignerCredentials + : AbstractTlsCredentials, TlsSignerCredentials + { + /// + public abstract byte[] GenerateCertificateSignature(byte[] hash); + + public virtual SignatureAndHashAlgorithm SignatureAndHashAlgorithm + { + get + { + throw new InvalidOperationException("TlsSignerCredentials implementation does not support (D)TLS 1.2+"); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsSignerCredentials.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsSignerCredentials.cs.meta new file mode 100644 index 0000000..e7697db --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AbstractTlsSignerCredentials.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 519db275ba6b17e428e8a6e4c1ac2d47 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AlertDescription.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AlertDescription.cs new file mode 100644 index 0000000..4e2464b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AlertDescription.cs @@ -0,0 +1,304 @@ +namespace Org.BouncyCastle.Crypto.Tls +{ + /// + /// RFC 5246 7.2 + /// + public abstract class AlertDescription + { + /** + * This message notifies the recipient that the sender will not send any more messages on this + * connection. Note that as of TLS 1.1, failure to properly close a connection no longer + * requires that a session not be resumed. This is a change from TLS 1.0 ("The session becomes + * unresumable if any connection is terminated without proper close_notify messages with level + * equal to warning.") to conform with widespread implementation practice. + */ + public const byte close_notify = 0; + + /** + * An inappropriate message was received. This alert is always fatal and should never be + * observed in communication between proper implementations. + */ + public const byte unexpected_message = 10; + + /** + * This alert is returned if a record is received with an incorrect MAC. This alert also MUST be + * returned if an alert is sent because a TLSCiphertext decrypted in an invalid way: either it + * wasn't an even multiple of the block length, or its padding values, when checked, weren't + * correct. This message is always fatal and should never be observed in communication between + * proper implementations (except when messages were corrupted in the network). + */ + public const byte bad_record_mac = 20; + + /** + * This alert was used in some earlier versions of TLS, and may have permitted certain attacks + * against the CBC mode [CBCATT]. It MUST NOT be sent by compliant implementations. + */ + public const byte decryption_failed = 21; + + /** + * A TLSCiphertext record was received that had a length more than 2^14+2048 bytes, or a record + * decrypted to a TLSCompressed record with more than 2^14+1024 bytes. This message is always + * fatal and should never be observed in communication between proper implementations (except + * when messages were corrupted in the network). + */ + public const byte record_overflow = 22; + + /** + * The decompression function received improper input (e.g., data that would expand to excessive + * length). This message is always fatal and should never be observed in communication between + * proper implementations. + */ + public const byte decompression_failure = 30; + + /** + * Reception of a handshake_failure alert message indicates that the sender was unable to + * negotiate an acceptable set of security parameters given the options available. This is a + * fatal error. + */ + public const byte handshake_failure = 40; + + /** + * This alert was used in SSLv3 but not any version of TLS. It MUST NOT be sent by compliant + * implementations. + */ + public const byte no_certificate = 41; + + /** + * A certificate was corrupt, contained signatures that did not verify correctly, etc. + */ + public const byte bad_certificate = 42; + + /** + * A certificate was of an unsupported type. + */ + public const byte unsupported_certificate = 43; + + /** + * A certificate was revoked by its signer. + */ + public const byte certificate_revoked = 44; + + /** + * A certificate has expired or is not currently valid. + */ + public const byte certificate_expired = 45; + + /** + * Some other (unspecified) issue arose in processing the certificate, rendering it + * unacceptable. + */ + public const byte certificate_unknown = 46; + + /** + * A field in the handshake was out of range or inconsistent with other fields. This message is + * always fatal. + */ + public const byte illegal_parameter = 47; + + /** + * A valid certificate chain or partial chain was received, but the certificate was not accepted + * because the CA certificate could not be located or couldn't be matched with a known, trusted + * CA. This message is always fatal. + */ + public const byte unknown_ca = 48; + + /** + * A valid certificate was received, but when access control was applied, the sender decided not + * to proceed with negotiation. This message is always fatal. + */ + public const byte access_denied = 49; + + /** + * A message could not be decoded because some field was out of the specified range or the + * length of the message was incorrect. This message is always fatal and should never be + * observed in communication between proper implementations (except when messages were corrupted + * in the network). + */ + public const byte decode_error = 50; + + /** + * A handshake cryptographic operation failed, including being unable to correctly verify a + * signature or validate a Finished message. This message is always fatal. + */ + public const byte decrypt_error = 51; + + /** + * This alert was used in some earlier versions of TLS. It MUST NOT be sent by compliant + * implementations. + */ + public const byte export_restriction = 60; + + /** + * The protocol version the client has attempted to negotiate is recognized but not supported. + * (For example, old protocol versions might be avoided for security reasons.) This message is + * always fatal. + */ + public const byte protocol_version = 70; + + /** + * Returned instead of handshake_failure when a negotiation has failed specifically because the + * server requires ciphers more secure than those supported by the client. This message is + * always fatal. + */ + public const byte insufficient_security = 71; + + /** + * An internal error unrelated to the peer or the correctness of the protocol (such as a memory + * allocation failure) makes it impossible to continue. This message is always fatal. + */ + public const byte internal_error = 80; + + /** + * This handshake is being canceled for some reason unrelated to a protocol failure. If the user + * cancels an operation after the handshake is complete, just closing the connection by sending + * a close_notify is more appropriate. This alert should be followed by a close_notify. This + * message is generally a warning. + */ + public const byte user_canceled = 90; + + /** + * Sent by the client in response to a hello request or by the server in response to a client + * hello after initial handshaking. Either of these would normally lead to renegotiation; when + * that is not appropriate, the recipient should respond with this alert. At that point, the + * original requester can decide whether to proceed with the connection. One case where this + * would be appropriate is where a server has spawned a process to satisfy a request; the + * process might receive security parameters (key length, authentication, etc.) at startup, and + * it might be difficult to communicate changes to these parameters after that point. This + * message is always a warning. + */ + public const byte no_renegotiation = 100; + + /** + * Sent by clients that receive an extended server hello containing an extension that they did + * not put in the corresponding client hello. This message is always fatal. + */ + public const byte unsupported_extension = 110; + + /* + * RFC 3546 + */ + + /** + * This alert is sent by servers who are unable to retrieve a certificate chain from the URL + * supplied by the client (see Section 3.3). This message MAY be fatal - for example if client + * authentication is required by the server for the handshake to continue and the server is + * unable to retrieve the certificate chain, it may send a fatal alert. + */ + public const byte certificate_unobtainable = 111; + + /** + * This alert is sent by servers that receive a server_name extension request, but do not + * recognize the server name. This message MAY be fatal. + */ + public const byte unrecognized_name = 112; + + /** + * This alert is sent by clients that receive an invalid certificate status response (see + * Section 3.6). This message is always fatal. + */ + public const byte bad_certificate_status_response = 113; + + /** + * This alert is sent by servers when a certificate hash does not match a client provided + * certificate_hash. This message is always fatal. + */ + public const byte bad_certificate_hash_value = 114; + + /* + * RFC 4279 + */ + + /** + * If the server does not recognize the PSK identity, it MAY respond with an + * "unknown_psk_identity" alert message. + */ + public const byte unknown_psk_identity = 115; + + /* + * RFC 7507 + */ + + /** + * If TLS_FALLBACK_SCSV appears in ClientHello.cipher_suites and the highest protocol version + * supported by the server is higher than the version indicated in ClientHello.client_version, + * the server MUST respond with a fatal inappropriate_fallback alert [..]. + */ + public const byte inappropriate_fallback = 86; + + public static string GetName(byte alertDescription) + { + switch (alertDescription) + { + case close_notify: + return "close_notify"; + case unexpected_message: + return "unexpected_message"; + case bad_record_mac: + return "bad_record_mac"; + case decryption_failed: + return "decryption_failed"; + case record_overflow: + return "record_overflow"; + case decompression_failure: + return "decompression_failure"; + case handshake_failure: + return "handshake_failure"; + case no_certificate: + return "no_certificate"; + case bad_certificate: + return "bad_certificate"; + case unsupported_certificate: + return "unsupported_certificate"; + case certificate_revoked: + return "certificate_revoked"; + case certificate_expired: + return "certificate_expired"; + case certificate_unknown: + return "certificate_unknown"; + case illegal_parameter: + return "illegal_parameter"; + case unknown_ca: + return "unknown_ca"; + case access_denied: + return "access_denied"; + case decode_error: + return "decode_error"; + case decrypt_error: + return "decrypt_error"; + case export_restriction: + return "export_restriction"; + case protocol_version: + return "protocol_version"; + case insufficient_security: + return "insufficient_security"; + case internal_error: + return "internal_error"; + case user_canceled: + return "user_canceled"; + case no_renegotiation: + return "no_renegotiation"; + case unsupported_extension: + return "unsupported_extension"; + case certificate_unobtainable: + return "certificate_unobtainable"; + case unrecognized_name: + return "unrecognized_name"; + case bad_certificate_status_response: + return "bad_certificate_status_response"; + case bad_certificate_hash_value: + return "bad_certificate_hash_value"; + case unknown_psk_identity: + return "unknown_psk_identity"; + case inappropriate_fallback: + return "inappropriate_fallback"; + default: + return "UNKNOWN"; + } + } + + public static string GetText(byte alertDescription) + { + return GetName(alertDescription) + "(" + alertDescription + ")"; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AlertDescription.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AlertDescription.cs.meta new file mode 100644 index 0000000..617379f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AlertDescription.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: be49fd2c243bab84f8f6543466bc4c66 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AlertLevel.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AlertLevel.cs new file mode 100644 index 0000000..9461a0b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AlertLevel.cs @@ -0,0 +1,29 @@ +namespace Org.BouncyCastle.Crypto.Tls +{ + /// + /// RFC 5246 7.2 + /// + public abstract class AlertLevel + { + public const byte warning = 1; + public const byte fatal = 2; + + public static string GetName(byte alertDescription) + { + switch (alertDescription) + { + case warning: + return "warning"; + case fatal: + return "fatal"; + default: + return "UNKNOWN"; + } + } + + public static string GetText(byte alertDescription) + { + return GetName(alertDescription) + "(" + alertDescription + ")"; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AlertLevel.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AlertLevel.cs.meta new file mode 100644 index 0000000..cf10a56 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/AlertLevel.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 69883a949eab38d468564edd1ff25e59 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/BasicTlsPskIdentity.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/BasicTlsPskIdentity.cs new file mode 100644 index 0000000..7a3bbe7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/BasicTlsPskIdentity.cs @@ -0,0 +1,43 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class BasicTlsPskIdentity + : TlsPskIdentity + { + protected byte[] mIdentity; + protected byte[] mPsk; + + public BasicTlsPskIdentity(byte[] identity, byte[] psk) + { + this.mIdentity = Arrays.Clone(identity); + this.mPsk = Arrays.Clone(psk); + } + + public BasicTlsPskIdentity(string identity, byte[] psk) + { + this.mIdentity = Strings.ToUtf8ByteArray(identity); + this.mPsk = Arrays.Clone(psk); + } + + public virtual void SkipIdentityHint() + { + } + + public virtual void NotifyIdentityHint(byte[] psk_identity_hint) + { + } + + public virtual byte[] GetPskIdentity() + { + return mIdentity; + } + + public virtual byte[] GetPsk() + { + return Arrays.Clone(mPsk); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/BasicTlsPskIdentity.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/BasicTlsPskIdentity.cs.meta new file mode 100644 index 0000000..4418a04 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/BasicTlsPskIdentity.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b5c4680d634c87d41a3f2f31c9f0a8db +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/BulkCipherAlgorithm.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/BulkCipherAlgorithm.cs new file mode 100644 index 0000000..07ff8dc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/BulkCipherAlgorithm.cs @@ -0,0 +1,25 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// RFC 2246 + /// + /// Note that the values here are implementation-specific and arbitrary. It is recommended not to + /// depend on the particular values (e.g. serialization). + /// + public abstract class BulkCipherAlgorithm + { + public const int cls_null = 0; + public const int rc4 = 1; + public const int rc2 = 2; + public const int des = 3; + public const int cls_3des = 4; + public const int des40 = 5; + + /* + * RFC 4346 + */ + public const int aes = 6; + public const int idea = 7; + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/BulkCipherAlgorithm.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/BulkCipherAlgorithm.cs.meta new file mode 100644 index 0000000..3202fd8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/BulkCipherAlgorithm.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f6af8371339d04442b6a70e4f4d6c418 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ByteQueue.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ByteQueue.cs new file mode 100644 index 0000000..b4df685 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ByteQueue.cs @@ -0,0 +1,211 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// + /// A queue for bytes. + ///

+ /// This file could be more optimized. + ///

+ ///
+ public class ByteQueue + { + /// The smallest number which can be written as 2^x which is bigger than i. + public static int NextTwoPow( + int i) + { + /* + * This code is based of a lot of code I found on the Internet + * which mostly referenced a book called "Hacking delight". + * + */ + i |= (i >> 1); + i |= (i >> 2); + i |= (i >> 4); + i |= (i >> 8); + i |= (i >> 16); + return i + 1; + } + + /** + * The initial size for our buffer. + */ + private const int DefaultCapacity = 1024; + + /** + * The buffer where we store our data. + */ + private byte[] databuf; + + /** + * How many bytes at the beginning of the buffer are skipped. + */ + private int skipped = 0; + + /** + * How many bytes in the buffer are valid data. + */ + private int available = 0; + + private bool readOnlyBuf = false; + + public ByteQueue() + : this(DefaultCapacity) + { + } + + public ByteQueue(int capacity) + { + this.databuf = capacity == 0 ? TlsUtilities.EmptyBytes : new byte[capacity]; + } + + public ByteQueue(byte[] buf, int off, int len) + { + this.databuf = buf; + this.skipped = off; + this.available = len; + this.readOnlyBuf = true; + } + + /// Add some data to our buffer. + /// A byte-array to read data from. + /// How many bytes to skip at the beginning of the array. + /// How many bytes to read from the array. + public void AddData( + byte[] data, + int offset, + int len) + { + if (readOnlyBuf) + throw new InvalidOperationException("Cannot add data to read-only buffer"); + + if ((skipped + available + len) > databuf.Length) + { + int desiredSize = ByteQueue.NextTwoPow(available + len); + if (desiredSize > databuf.Length) + { + byte[] tmp = new byte[desiredSize]; + Array.Copy(databuf, skipped, tmp, 0, available); + databuf = tmp; + } + else + { + Array.Copy(databuf, skipped, databuf, 0, available); + } + skipped = 0; + } + + Array.Copy(data, offset, databuf, skipped + available, len); + available += len; + } + + /// The number of bytes which are available in this buffer. + public int Available + { + get { return available; } + } + + /// Copy some bytes from the beginning of the data to the provided Stream. + /// The Stream to copy the bytes to. + /// How many bytes to copy. + /// If insufficient data is available. + /// If there is a problem copying the data. + public void CopyTo(Stream output, int length) + { + if (length > available) + throw new InvalidOperationException("Cannot copy " + length + " bytes, only got " + available); + + output.Write(databuf, skipped, length); + } + + /// Read data from the buffer. + /// The buffer where the read data will be copied to. + /// How many bytes to skip at the beginning of buf. + /// How many bytes to read at all. + /// How many bytes from our data to skip. + public void Read( + byte[] buf, + int offset, + int len, + int skip) + { + if ((buf.Length - offset) < len) + { + throw new ArgumentException("Buffer size of " + buf.Length + " is too small for a read of " + len + " bytes"); + } + if ((available - skip) < len) + { + throw new InvalidOperationException("Not enough data to read"); + } + Array.Copy(databuf, skipped + skip, buf, offset, len); + } + + /// Return a MemoryStream over some bytes at the beginning of the data. + /// How many bytes will be readable. + /// A MemoryStream over the data. + /// If insufficient data is available. + public MemoryStream ReadFrom(int length) + { + if (length > available) + throw new InvalidOperationException("Cannot read " + length + " bytes, only got " + available); + + int position = skipped; + + available -= length; + skipped += length; + + return new MemoryStream(databuf, position, length, false); + } + + /// Remove some bytes from our data from the beginning. + /// How many bytes to remove. + public void RemoveData( + int i) + { + if (i > available) + { + throw new InvalidOperationException("Cannot remove " + i + " bytes, only got " + available); + } + + /* + * Skip the data. + */ + available -= i; + skipped += i; + } + + public void RemoveData(byte[] buf, int off, int len, int skip) + { + Read(buf, off, len, skip); + RemoveData(skip + len); + } + + public byte[] RemoveData(int len, int skip) + { + byte[] buf = new byte[len]; + RemoveData(buf, 0, len, skip); + return buf; + } + + public void Shrink() + { + if (available == 0) + { + databuf = TlsUtilities.EmptyBytes; + skipped = 0; + } + else + { + int desiredSize = ByteQueue.NextTwoPow(available); + if (desiredSize < databuf.Length) + { + byte[] tmp = new byte[desiredSize]; + Array.Copy(databuf, skipped, tmp, 0, available); + databuf = tmp; + skipped = 0; + } + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ByteQueue.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ByteQueue.cs.meta new file mode 100644 index 0000000..876450b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ByteQueue.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 294fd638055099d44a491c55512c2c41 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ByteQueueStream.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ByteQueueStream.cs new file mode 100644 index 0000000..249e609 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ByteQueueStream.cs @@ -0,0 +1,110 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class ByteQueueStream + : Stream + { + private readonly ByteQueue buffer; + + public ByteQueueStream() + { + this.buffer = new ByteQueue(); + } + + public virtual int Available + { + get { return buffer.Available; } + } + + public override bool CanRead + { + get { return true; } + } + + public override bool CanSeek + { + get { return false; } + } + + public override bool CanWrite + { + get { return true; } + } + + public override void Flush() + { + } + + public override long Length + { + get { throw new NotSupportedException(); } + } + + public virtual int Peek(byte[] buf) + { + int bytesToRead = System.Math.Min(buffer.Available, buf.Length); + buffer.Read(buf, 0, bytesToRead, 0); + return bytesToRead; + } + + public override long Position + { + get { throw new NotSupportedException(); } + set { throw new NotSupportedException(); } + } + + public virtual int Read(byte[] buf) + { + return Read(buf, 0, buf.Length); + } + + public override int Read(byte[] buf, int off, int len) + { + int bytesToRead = System.Math.Min(buffer.Available, len); + buffer.RemoveData(buf, off, bytesToRead, 0); + return bytesToRead; + } + + public override int ReadByte() + { + if (buffer.Available == 0) + return -1; + + return buffer.RemoveData(1, 0)[0] & 0xFF; + } + + public override long Seek(long offset, SeekOrigin origin) + { + throw new NotSupportedException(); + } + + public override void SetLength(long value) + { + throw new NotSupportedException(); + } + + public virtual int Skip(int n) + { + int bytesToSkip = System.Math.Min(buffer.Available, n); + buffer.RemoveData(bytesToSkip); + return bytesToSkip; + } + + public virtual void Write(byte[] buf) + { + buffer.AddData(buf, 0, buf.Length); + } + + public override void Write(byte[] buf, int off, int len) + { + buffer.AddData(buf, off, len); + } + + public override void WriteByte(byte b) + { + buffer.AddData(new byte[]{ b }, 0, 1); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ByteQueueStream.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ByteQueueStream.cs.meta new file mode 100644 index 0000000..b7d3f73 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ByteQueueStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ef01455fe3ef0444aa6afa56f0db89bb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CertChainType.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CertChainType.cs new file mode 100644 index 0000000..cbb1834 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CertChainType.cs @@ -0,0 +1,18 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /* + * RFC 3546 3.3. + */ + public abstract class CertChainType + { + public const byte individual_certs = 0; + public const byte pkipath = 1; + + public static bool IsValid(byte certChainType) + { + return certChainType >= individual_certs && certChainType <= pkipath; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CertChainType.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CertChainType.cs.meta new file mode 100644 index 0000000..a8289fc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CertChainType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c06f53e5af895314c9e214326d0f111b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/Certificate.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/Certificate.cs new file mode 100644 index 0000000..e047999 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/Certificate.cs @@ -0,0 +1,136 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /** + * Parsing and encoding of a Certificate struct from RFC 4346. + *

+ *

+     * opaque ASN.1Cert<2^24-1>;
+     *
+     * struct {
+     *     ASN.1Cert certificate_list<0..2^24-1>;
+     * } Certificate;
+     * 
+ * + * @see Org.BouncyCastle.Asn1.X509.X509CertificateStructure + */ + public class Certificate + { + public static readonly Certificate EmptyChain = new Certificate(new X509CertificateStructure[0]); + + /** + * The certificates. + */ + protected readonly X509CertificateStructure[] mCertificateList; + + public Certificate(X509CertificateStructure[] certificateList) + { + if (certificateList == null) + throw new ArgumentNullException("certificateList"); + + this.mCertificateList = certificateList; + } + + /** + * @return an array of {@link org.bouncycastle.asn1.x509.Certificate} representing a certificate + * chain. + */ + public virtual X509CertificateStructure[] GetCertificateList() + { + return CloneCertificateList(); + } + + public virtual X509CertificateStructure GetCertificateAt(int index) + { + return mCertificateList[index]; + } + + public virtual int Length + { + get { return mCertificateList.Length; } + } + + /** + * @return true if this certificate chain contains no certificates, or + * false otherwise. + */ + public virtual bool IsEmpty + { + get { return mCertificateList.Length == 0; } + } + + /** + * Encode this {@link Certificate} to a {@link Stream}. + * + * @param output the {@link Stream} to encode to. + * @throws IOException + */ + public virtual void Encode(Stream output) + { + IList derEncodings = Platform.CreateArrayList(mCertificateList.Length); + + int totalLength = 0; + foreach (Asn1Encodable asn1Cert in mCertificateList) + { + byte[] derEncoding = asn1Cert.GetEncoded(Asn1Encodable.Der); + derEncodings.Add(derEncoding); + totalLength += derEncoding.Length + 3; + } + + TlsUtilities.CheckUint24(totalLength); + TlsUtilities.WriteUint24(totalLength, output); + + foreach (byte[] derEncoding in derEncodings) + { + TlsUtilities.WriteOpaque24(derEncoding, output); + } + } + + /** + * Parse a {@link Certificate} from a {@link Stream}. + * + * @param input the {@link Stream} to parse from. + * @return a {@link Certificate} object. + * @throws IOException + */ + public static Certificate Parse(Stream input) + { + int totalLength = TlsUtilities.ReadUint24(input); + if (totalLength == 0) + { + return EmptyChain; + } + + byte[] certListData = TlsUtilities.ReadFully(totalLength, input); + + MemoryStream buf = new MemoryStream(certListData, false); + + IList certificate_list = Platform.CreateArrayList(); + while (buf.Position < buf.Length) + { + byte[] berEncoding = TlsUtilities.ReadOpaque24(buf); + Asn1Object asn1Cert = TlsUtilities.ReadAsn1Object(berEncoding); + certificate_list.Add(X509CertificateStructure.GetInstance(asn1Cert)); + } + + X509CertificateStructure[] certificateList = new X509CertificateStructure[certificate_list.Count]; + for (int i = 0; i < certificate_list.Count; ++i) + { + certificateList[i] = (X509CertificateStructure)certificate_list[i]; + } + return new Certificate(certificateList); + } + + protected virtual X509CertificateStructure[] CloneCertificateList() + { + return (X509CertificateStructure[])mCertificateList.Clone(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/Certificate.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/Certificate.cs.meta new file mode 100644 index 0000000..6f56b4d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/Certificate.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f0d3ce6e6f791bf449492a01977d73da +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CertificateRequest.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CertificateRequest.cs new file mode 100644 index 0000000..f3dcb3b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CertificateRequest.cs @@ -0,0 +1,156 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /** + * Parsing and encoding of a CertificateRequest struct from RFC 4346. + *

+ *

+     * struct {
+     *     ClientCertificateType certificate_types<1..2^8-1>;
+     *     DistinguishedName certificate_authorities<3..2^16-1>
+     * } CertificateRequest;
+     * 
+ * + * @see ClientCertificateType + * @see X509Name + */ + public class CertificateRequest + { + protected readonly byte[] mCertificateTypes; + protected readonly IList mSupportedSignatureAlgorithms; + protected readonly IList mCertificateAuthorities; + + /** + * @param certificateTypes see {@link ClientCertificateType} for valid constants. + * @param certificateAuthorities an {@link IList} of {@link X509Name}. + */ + public CertificateRequest(byte[] certificateTypes, IList supportedSignatureAlgorithms, + IList certificateAuthorities) + { + this.mCertificateTypes = certificateTypes; + this.mSupportedSignatureAlgorithms = supportedSignatureAlgorithms; + this.mCertificateAuthorities = certificateAuthorities; + } + + /** + * @return an array of certificate types + * @see {@link ClientCertificateType} + */ + public virtual byte[] CertificateTypes + { + get { return mCertificateTypes; } + } + + /** + * @return an {@link IList} of {@link SignatureAndHashAlgorithm} (or null before TLS 1.2). + */ + public virtual IList SupportedSignatureAlgorithms + { + get { return mSupportedSignatureAlgorithms; } + } + + /** + * @return an {@link IList} of {@link X509Name} + */ + public virtual IList CertificateAuthorities + { + get { return mCertificateAuthorities; } + } + + /** + * Encode this {@link CertificateRequest} to a {@link Stream}. + * + * @param output the {@link Stream} to encode to. + * @throws IOException + */ + public virtual void Encode(Stream output) + { + if (mCertificateTypes == null || mCertificateTypes.Length == 0) + { + TlsUtilities.WriteUint8(0, output); + } + else + { + TlsUtilities.WriteUint8ArrayWithUint8Length(mCertificateTypes, output); + } + + if (mSupportedSignatureAlgorithms != null) + { + // TODO Check whether SignatureAlgorithm.anonymous is allowed here + TlsUtilities.EncodeSupportedSignatureAlgorithms(mSupportedSignatureAlgorithms, false, output); + } + + if (mCertificateAuthorities == null || mCertificateAuthorities.Count < 1) + { + TlsUtilities.WriteUint16(0, output); + } + else + { + IList derEncodings = Platform.CreateArrayList(mCertificateAuthorities.Count); + + int totalLength = 0; + foreach (Asn1Encodable certificateAuthority in mCertificateAuthorities) + { + byte[] derEncoding = certificateAuthority.GetEncoded(Asn1Encodable.Der); + derEncodings.Add(derEncoding); + totalLength += derEncoding.Length + 2; + } + + TlsUtilities.CheckUint16(totalLength); + TlsUtilities.WriteUint16(totalLength, output); + + foreach (byte[] derEncoding in derEncodings) + { + TlsUtilities.WriteOpaque16(derEncoding, output); + } + } + } + + /** + * Parse a {@link CertificateRequest} from a {@link Stream}. + * + * @param context + * the {@link TlsContext} of the current connection. + * @param input + * the {@link Stream} to parse from. + * @return a {@link CertificateRequest} object. + * @throws IOException + */ + public static CertificateRequest Parse(TlsContext context, Stream input) + { + int numTypes = TlsUtilities.ReadUint8(input); + byte[] certificateTypes = new byte[numTypes]; + for (int i = 0; i < numTypes; ++i) + { + certificateTypes[i] = TlsUtilities.ReadUint8(input); + } + + IList supportedSignatureAlgorithms = null; + if (TlsUtilities.IsTlsV12(context)) + { + // TODO Check whether SignatureAlgorithm.anonymous is allowed here + supportedSignatureAlgorithms = TlsUtilities.ParseSupportedSignatureAlgorithms(false, input); + } + + IList certificateAuthorities = Platform.CreateArrayList(); + byte[] certAuthData = TlsUtilities.ReadOpaque16(input); + MemoryStream bis = new MemoryStream(certAuthData, false); + while (bis.Position < bis.Length) + { + byte[] derEncoding = TlsUtilities.ReadOpaque16(bis); + Asn1Object asn1 = TlsUtilities.ReadDerObject(derEncoding); + // TODO Switch to X500Name when available + certificateAuthorities.Add(X509Name.GetInstance(asn1)); + } + + return new CertificateRequest(certificateTypes, supportedSignatureAlgorithms, certificateAuthorities); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CertificateRequest.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CertificateRequest.cs.meta new file mode 100644 index 0000000..484b9bc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CertificateRequest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8c422c3e48b52814688912452e0176de +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CertificateStatus.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CertificateStatus.cs new file mode 100644 index 0000000..bc41287 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CertificateStatus.cs @@ -0,0 +1,102 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Ocsp; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class CertificateStatus + { + protected readonly byte mStatusType; + protected readonly object mResponse; + + public CertificateStatus(byte statusType, object response) + { + if (!IsCorrectType(statusType, response)) + throw new ArgumentException("not an instance of the correct type", "response"); + + this.mStatusType = statusType; + this.mResponse = response; + } + + public virtual byte StatusType + { + get { return mStatusType; } + } + + public virtual object Response + { + get { return mResponse; } + } + + public virtual OcspResponse GetOcspResponse() + { + if (!IsCorrectType(CertificateStatusType.ocsp, mResponse)) + throw new InvalidOperationException("'response' is not an OcspResponse"); + + return (OcspResponse)mResponse; + } + + /** + * Encode this {@link CertificateStatus} to a {@link Stream}. + * + * @param output + * the {@link Stream} to encode to. + * @throws IOException + */ + public virtual void Encode(Stream output) + { + TlsUtilities.WriteUint8(mStatusType, output); + + switch (mStatusType) + { + case CertificateStatusType.ocsp: + byte[] derEncoding = ((OcspResponse)mResponse).GetEncoded(Asn1Encodable.Der); + TlsUtilities.WriteOpaque24(derEncoding, output); + break; + default: + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + /** + * Parse a {@link CertificateStatus} from a {@link Stream}. + * + * @param input + * the {@link Stream} to parse from. + * @return a {@link CertificateStatus} object. + * @throws IOException + */ + public static CertificateStatus Parse(Stream input) + { + byte status_type = TlsUtilities.ReadUint8(input); + object response; + + switch (status_type) + { + case CertificateStatusType.ocsp: + { + byte[] derEncoding = TlsUtilities.ReadOpaque24(input); + response = OcspResponse.GetInstance(TlsUtilities.ReadDerObject(derEncoding)); + break; + } + default: + throw new TlsFatalAlert(AlertDescription.decode_error); + } + + return new CertificateStatus(status_type, response); + } + + protected static bool IsCorrectType(byte statusType, object response) + { + switch (statusType) + { + case CertificateStatusType.ocsp: + return response is OcspResponse; + default: + throw new ArgumentException("unsupported CertificateStatusType", "statusType"); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CertificateStatus.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CertificateStatus.cs.meta new file mode 100644 index 0000000..22ad408 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CertificateStatus.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 65665d133a85fff42b6c7208cab3ccd3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CertificateStatusRequest.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CertificateStatusRequest.cs new file mode 100644 index 0000000..24ce376 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CertificateStatusRequest.cs @@ -0,0 +1,95 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class CertificateStatusRequest + { + protected readonly byte mStatusType; + protected readonly object mRequest; + + public CertificateStatusRequest(byte statusType, Object request) + { + if (!IsCorrectType(statusType, request)) + throw new ArgumentException("not an instance of the correct type", "request"); + + this.mStatusType = statusType; + this.mRequest = request; + } + + public virtual byte StatusType + { + get { return mStatusType; } + } + + public virtual object Request + { + get { return mRequest; } + } + + public virtual OcspStatusRequest GetOcspStatusRequest() + { + if (!IsCorrectType(CertificateStatusType.ocsp, mRequest)) + throw new InvalidOperationException("'request' is not an OCSPStatusRequest"); + + return (OcspStatusRequest)mRequest; + } + + /** + * Encode this {@link CertificateStatusRequest} to a {@link Stream}. + * + * @param output + * the {@link Stream} to encode to. + * @throws IOException + */ + public virtual void Encode(Stream output) + { + TlsUtilities.WriteUint8(mStatusType, output); + + switch (mStatusType) + { + case CertificateStatusType.ocsp: + ((OcspStatusRequest)mRequest).Encode(output); + break; + default: + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + /** + * Parse a {@link CertificateStatusRequest} from a {@link Stream}. + * + * @param input + * the {@link Stream} to parse from. + * @return a {@link CertificateStatusRequest} object. + * @throws IOException + */ + public static CertificateStatusRequest Parse(Stream input) + { + byte status_type = TlsUtilities.ReadUint8(input); + object result; + + switch (status_type) + { + case CertificateStatusType.ocsp: + result = OcspStatusRequest.Parse(input); + break; + default: + throw new TlsFatalAlert(AlertDescription.decode_error); + } + + return new CertificateStatusRequest(status_type, result); + } + + protected static bool IsCorrectType(byte statusType, object request) + { + switch (statusType) + { + case CertificateStatusType.ocsp: + return request is OcspStatusRequest; + default: + throw new ArgumentException("unsupported CertificateStatusType", "statusType"); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CertificateStatusRequest.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CertificateStatusRequest.cs.meta new file mode 100644 index 0000000..01f437f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CertificateStatusRequest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 44a2f1f0d24ba1e419c563aa467d22a2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CertificateStatusType.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CertificateStatusType.cs new file mode 100644 index 0000000..54b741b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CertificateStatusType.cs @@ -0,0 +1,12 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class CertificateStatusType + { + /* + * RFC 3546 3.6 + */ + public const byte ocsp = 1; + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CertificateStatusType.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CertificateStatusType.cs.meta new file mode 100644 index 0000000..efb6eb5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CertificateStatusType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f193097fa1f02b64f9ae012578b3a432 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CertificateType.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CertificateType.cs new file mode 100644 index 0000000..47ec05c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CertificateType.cs @@ -0,0 +1,18 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /** + * RFC 6091 + */ + public class CertificateType + { + public const byte X509 = 0; + public const byte OpenPGP = 1; + + /* + * RFC 7250 + */ + public const byte RawPublicKey = 2; + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CertificateType.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CertificateType.cs.meta new file mode 100644 index 0000000..03f3af6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CertificateType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: be50ba2dd06a52446bb89159519fefe5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CertificateUrl.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CertificateUrl.cs new file mode 100644 index 0000000..aff9995 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CertificateUrl.cs @@ -0,0 +1,125 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /* + * RFC 3546 3.3 + */ + public class CertificateUrl + { + protected readonly byte mType; + protected readonly IList mUrlAndHashList; + + /** + * @param type + * see {@link CertChainType} for valid constants. + * @param urlAndHashList + * a {@link IList} of {@link UrlAndHash}. + */ + public CertificateUrl(byte type, IList urlAndHashList) + { + if (!CertChainType.IsValid(type)) + throw new ArgumentException("not a valid CertChainType value", "type"); + if (urlAndHashList == null || urlAndHashList.Count < 1) + throw new ArgumentException("must have length > 0", "urlAndHashList"); + + this.mType = type; + this.mUrlAndHashList = urlAndHashList; + } + + /** + * @return {@link CertChainType} + */ + public virtual byte Type + { + get { return mType; } + } + + /** + * @return an {@link IList} of {@link UrlAndHash} + */ + public virtual IList UrlAndHashList + { + get { return mUrlAndHashList; } + } + + /** + * Encode this {@link CertificateUrl} to a {@link Stream}. + * + * @param output the {@link Stream} to encode to. + * @throws IOException + */ + public virtual void Encode(Stream output) + { + TlsUtilities.WriteUint8(this.mType, output); + + ListBuffer16 buf = new ListBuffer16(); + foreach (UrlAndHash urlAndHash in this.mUrlAndHashList) + { + urlAndHash.Encode(buf); + } + buf.EncodeTo(output); + } + + /** + * Parse a {@link CertificateUrl} from a {@link Stream}. + * + * @param context + * the {@link TlsContext} of the current connection. + * @param input + * the {@link Stream} to parse from. + * @return a {@link CertificateUrl} object. + * @throws IOException + */ + public static CertificateUrl parse(TlsContext context, Stream input) + { + byte type = TlsUtilities.ReadUint8(input); + if (!CertChainType.IsValid(type)) + throw new TlsFatalAlert(AlertDescription.decode_error); + + int totalLength = TlsUtilities.ReadUint16(input); + if (totalLength < 1) + throw new TlsFatalAlert(AlertDescription.decode_error); + + byte[] urlAndHashListData = TlsUtilities.ReadFully(totalLength, input); + + MemoryStream buf = new MemoryStream(urlAndHashListData, false); + + IList url_and_hash_list = Platform.CreateArrayList(); + while (buf.Position < buf.Length) + { + UrlAndHash url_and_hash = UrlAndHash.Parse(context, buf); + url_and_hash_list.Add(url_and_hash); + } + + return new CertificateUrl(type, url_and_hash_list); + } + + // TODO Could be more generally useful + internal class ListBuffer16 + : MemoryStream + { + internal ListBuffer16() + { + // Reserve space for length + TlsUtilities.WriteUint16(0, this); + } + + internal void EncodeTo(Stream output) + { + // Patch actual length back in + long length = Length - 2; + TlsUtilities.CheckUint16(length); + this.Position = 0; + TlsUtilities.WriteUint16((int)length, this); + Streams.WriteBufTo(this, output); + Platform.Dispose(this); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CertificateUrl.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CertificateUrl.cs.meta new file mode 100644 index 0000000..2dd4d88 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CertificateUrl.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7a0d8a011edfadc49ae7ae7a6212e310 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/Chacha20Poly1305.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/Chacha20Poly1305.cs new file mode 100644 index 0000000..8687803 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/Chacha20Poly1305.cs @@ -0,0 +1,199 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Macs; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /** + * draft-ietf-tls-chacha20-poly1305-04 + */ + public class Chacha20Poly1305 + : TlsCipher + { + private static readonly byte[] Zeroes = new byte[15]; + + protected readonly TlsContext context; + + protected readonly ChaCha7539Engine encryptCipher, decryptCipher; + protected readonly byte[] encryptIV, decryptIV; + + /// + public Chacha20Poly1305(TlsContext context) + { + if (!TlsUtilities.IsTlsV12(context)) + throw new TlsFatalAlert(AlertDescription.internal_error); + + this.context = context; + + int cipherKeySize = 32; + // TODO SecurityParameters.fixed_iv_length + int fixed_iv_length = 12; + // TODO SecurityParameters.record_iv_length = 0 + + int key_block_size = (2 * cipherKeySize) + (2 * fixed_iv_length); + + byte[] key_block = TlsUtilities.CalculateKeyBlock(context, key_block_size); + + int offset = 0; + + KeyParameter client_write_key = new KeyParameter(key_block, offset, cipherKeySize); + offset += cipherKeySize; + KeyParameter server_write_key = new KeyParameter(key_block, offset, cipherKeySize); + offset += cipherKeySize; + byte[] client_write_IV = Arrays.CopyOfRange(key_block, offset, offset + fixed_iv_length); + offset += fixed_iv_length; + byte[] server_write_IV = Arrays.CopyOfRange(key_block, offset, offset + fixed_iv_length); + offset += fixed_iv_length; + + if (offset != key_block_size) + throw new TlsFatalAlert(AlertDescription.internal_error); + + this.encryptCipher = new ChaCha7539Engine(); + this.decryptCipher = new ChaCha7539Engine(); + + KeyParameter encryptKey, decryptKey; + if (context.IsServer) + { + encryptKey = server_write_key; + decryptKey = client_write_key; + this.encryptIV = server_write_IV; + this.decryptIV = client_write_IV; + } + else + { + encryptKey = client_write_key; + decryptKey = server_write_key; + this.encryptIV = client_write_IV; + this.decryptIV = server_write_IV; + } + + this.encryptCipher.Init(true, new ParametersWithIV(encryptKey, encryptIV)); + this.decryptCipher.Init(false, new ParametersWithIV(decryptKey, decryptIV)); + } + + public virtual int GetPlaintextLimit(int ciphertextLimit) + { + return ciphertextLimit - 16; + } + + /// + public virtual byte[] EncodePlaintext(long seqNo, byte type, byte[] plaintext, int offset, int len) + { + KeyParameter macKey = InitRecord(encryptCipher, true, seqNo, encryptIV); + + byte[] output = new byte[len + 16]; + encryptCipher.ProcessBytes(plaintext, offset, len, output, 0); + + byte[] additionalData = GetAdditionalData(seqNo, type, len); + byte[] mac = CalculateRecordMac(macKey, additionalData, output, 0, len); + Array.Copy(mac, 0, output, len, mac.Length); + + return output; + } + + /// + public virtual byte[] DecodeCiphertext(long seqNo, byte type, byte[] ciphertext, int offset, int len) + { + if (GetPlaintextLimit(len) < 0) + throw new TlsFatalAlert(AlertDescription.decode_error); + + KeyParameter macKey = InitRecord(decryptCipher, false, seqNo, decryptIV); + + int plaintextLength = len - 16; + + byte[] additionalData = GetAdditionalData(seqNo, type, plaintextLength); + byte[] calculatedMac = CalculateRecordMac(macKey, additionalData, ciphertext, offset, plaintextLength); + byte[] receivedMac = Arrays.CopyOfRange(ciphertext, offset + plaintextLength, offset + len); + + if (!Arrays.ConstantTimeAreEqual(calculatedMac, receivedMac)) + throw new TlsFatalAlert(AlertDescription.bad_record_mac); + + byte[] output = new byte[plaintextLength]; + decryptCipher.ProcessBytes(ciphertext, offset, plaintextLength, output, 0); + return output; + } + + protected virtual KeyParameter InitRecord(IStreamCipher cipher, bool forEncryption, long seqNo, byte[] iv) + { + byte[] nonce = CalculateNonce(seqNo, iv); + cipher.Init(forEncryption, new ParametersWithIV(null, nonce)); + return GenerateRecordMacKey(cipher); + } + + protected virtual byte[] CalculateNonce(long seqNo, byte[] iv) + { + byte[] nonce = new byte[12]; + TlsUtilities.WriteUint64(seqNo, nonce, 4); + + for (int i = 0; i < 12; ++i) + { + nonce[i] ^= iv[i]; + } + + return nonce; + } + + protected virtual KeyParameter GenerateRecordMacKey(IStreamCipher cipher) + { + byte[] firstBlock = new byte[64]; + cipher.ProcessBytes(firstBlock, 0, firstBlock.Length, firstBlock, 0); + + KeyParameter macKey = new KeyParameter(firstBlock, 0, 32); + Arrays.Fill(firstBlock, (byte)0); + return macKey; + } + + protected virtual byte[] CalculateRecordMac(KeyParameter macKey, byte[] additionalData, byte[] buf, int off, int len) + { + IMac mac = new Poly1305(); + mac.Init(macKey); + + UpdateRecordMacText(mac, additionalData, 0, additionalData.Length); + UpdateRecordMacText(mac, buf, off, len); + UpdateRecordMacLength(mac, additionalData.Length); + UpdateRecordMacLength(mac, len); + + return MacUtilities.DoFinal(mac); + } + + protected virtual void UpdateRecordMacLength(IMac mac, int len) + { + byte[] longLen = Pack.UInt64_To_LE((ulong)len); + mac.BlockUpdate(longLen, 0, longLen.Length); + } + + protected virtual void UpdateRecordMacText(IMac mac, byte[] buf, int off, int len) + { + mac.BlockUpdate(buf, off, len); + + int partial = len % 16; + if (partial != 0) + { + mac.BlockUpdate(Zeroes, 0, 16 - partial); + } + } + + /// + protected virtual byte[] GetAdditionalData(long seqNo, byte type, int len) + { + /* + * additional_data = seq_num + TLSCompressed.type + TLSCompressed.version + + * TLSCompressed.length + */ + byte[] additional_data = new byte[13]; + TlsUtilities.WriteUint64(seqNo, additional_data, 0); + TlsUtilities.WriteUint8(type, additional_data, 8); + TlsUtilities.WriteVersion(context.ServerVersion, additional_data, 9); + TlsUtilities.WriteUint16(len, additional_data, 11); + + return additional_data; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/Chacha20Poly1305.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/Chacha20Poly1305.cs.meta new file mode 100644 index 0000000..3e90f41 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/Chacha20Poly1305.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a2a6bd557c9aa224eb5a6cbfe9255566 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ChangeCipherSpec.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ChangeCipherSpec.cs new file mode 100644 index 0000000..323de91 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ChangeCipherSpec.cs @@ -0,0 +1,9 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class ChangeCipherSpec + { + public const byte change_cipher_spec = 1; + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ChangeCipherSpec.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ChangeCipherSpec.cs.meta new file mode 100644 index 0000000..774621c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ChangeCipherSpec.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 79c1619ccb85553428bb585249fc21be +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CipherSuite.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CipherSuite.cs new file mode 100644 index 0000000..5aa5563 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CipherSuite.cs @@ -0,0 +1,361 @@ +namespace Org.BouncyCastle.Crypto.Tls +{ + /// + /// RFC 2246 A.5 + /// + public abstract class CipherSuite + { + public const int TLS_NULL_WITH_NULL_NULL = 0x0000; + public const int TLS_RSA_WITH_NULL_MD5 = 0x0001; + public const int TLS_RSA_WITH_NULL_SHA = 0x0002; + public const int TLS_RSA_EXPORT_WITH_RC4_40_MD5 = 0x0003; + public const int TLS_RSA_WITH_RC4_128_MD5 = 0x0004; + public const int TLS_RSA_WITH_RC4_128_SHA = 0x0005; + public const int TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 = 0x0006; + public const int TLS_RSA_WITH_IDEA_CBC_SHA = 0x0007; + public const int TLS_RSA_EXPORT_WITH_DES40_CBC_SHA = 0x0008; + public const int TLS_RSA_WITH_DES_CBC_SHA = 0x0009; + public const int TLS_RSA_WITH_3DES_EDE_CBC_SHA = 0x000A; + public const int TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA = 0x000B; + public const int TLS_DH_DSS_WITH_DES_CBC_SHA = 0x000C; + public const int TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA = 0x000D; + public const int TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA = 0x000E; + public const int TLS_DH_RSA_WITH_DES_CBC_SHA = 0x000F; + public const int TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA = 0x0010; + public const int TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA = 0x0011; + public const int TLS_DHE_DSS_WITH_DES_CBC_SHA = 0x0012; + public const int TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA = 0x0013; + public const int TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA = 0x0014; + public const int TLS_DHE_RSA_WITH_DES_CBC_SHA = 0x0015; + public const int TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = 0x0016; + public const int TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 = 0x0017; + public const int TLS_DH_anon_WITH_RC4_128_MD5 = 0x0018; + public const int TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA = 0x0019; + public const int TLS_DH_anon_WITH_DES_CBC_SHA = 0x001A; + public const int TLS_DH_anon_WITH_3DES_EDE_CBC_SHA = 0x001B; + + /* + * Note: The cipher suite values { 0x00, 0x1C } and { 0x00, 0x1D } are reserved to avoid + * collision with Fortezza-based cipher suites in SSL 3. + */ + + /* + * RFC 3268 + */ + public const int TLS_RSA_WITH_AES_128_CBC_SHA = 0x002F; + public const int TLS_DH_DSS_WITH_AES_128_CBC_SHA = 0x0030; + public const int TLS_DH_RSA_WITH_AES_128_CBC_SHA = 0x0031; + public const int TLS_DHE_DSS_WITH_AES_128_CBC_SHA = 0x0032; + public const int TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0x0033; + public const int TLS_DH_anon_WITH_AES_128_CBC_SHA = 0x0034; + public const int TLS_RSA_WITH_AES_256_CBC_SHA = 0x0035; + public const int TLS_DH_DSS_WITH_AES_256_CBC_SHA = 0x0036; + public const int TLS_DH_RSA_WITH_AES_256_CBC_SHA = 0x0037; + public const int TLS_DHE_DSS_WITH_AES_256_CBC_SHA = 0x0038; + public const int TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0x0039; + public const int TLS_DH_anon_WITH_AES_256_CBC_SHA = 0x003A; + + /* + * RFC 5932 + */ + public const int TLS_RSA_WITH_CAMELLIA_128_CBC_SHA = 0x0041; + public const int TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA = 0x0042; + public const int TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA = 0x0043; + public const int TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA = 0x0044; + public const int TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA = 0x0045; + public const int TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA = 0x0046; + + public const int TLS_RSA_WITH_CAMELLIA_256_CBC_SHA = 0x0084; + public const int TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA = 0x0085; + public const int TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA = 0x0086; + public const int TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA = 0x0087; + public const int TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA = 0x0088; + public const int TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA = 0x0089; + + public const int TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 0x00BA; + public const int TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256 = 0x00BB; + public const int TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 0x00BC; + public const int TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 = 0x00BD; + public const int TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 0x00BE; + public const int TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256 = 0x00BF; + + public const int TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 = 0x00C0; + public const int TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256 = 0x00C1; + public const int TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256 = 0x00C2; + public const int TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 = 0x00C3; + public const int TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 = 0x00C4; + public const int TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256 = 0x00C5; + + /* + * RFC 4162 + */ + public const int TLS_RSA_WITH_SEED_CBC_SHA = 0x0096; + public const int TLS_DH_DSS_WITH_SEED_CBC_SHA = 0x0097; + public const int TLS_DH_RSA_WITH_SEED_CBC_SHA = 0x0098; + public const int TLS_DHE_DSS_WITH_SEED_CBC_SHA = 0x0099; + public const int TLS_DHE_RSA_WITH_SEED_CBC_SHA = 0x009A; + public const int TLS_DH_anon_WITH_SEED_CBC_SHA = 0x009B; + + /* + * RFC 4279 + */ + public const int TLS_PSK_WITH_RC4_128_SHA = 0x008A; + public const int TLS_PSK_WITH_3DES_EDE_CBC_SHA = 0x008B; + public const int TLS_PSK_WITH_AES_128_CBC_SHA = 0x008C; + public const int TLS_PSK_WITH_AES_256_CBC_SHA = 0x008D; + public const int TLS_DHE_PSK_WITH_RC4_128_SHA = 0x008E; + public const int TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA = 0x008F; + public const int TLS_DHE_PSK_WITH_AES_128_CBC_SHA = 0x0090; + public const int TLS_DHE_PSK_WITH_AES_256_CBC_SHA = 0x0091; + public const int TLS_RSA_PSK_WITH_RC4_128_SHA = 0x0092; + public const int TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA = 0x0093; + public const int TLS_RSA_PSK_WITH_AES_128_CBC_SHA = 0x0094; + public const int TLS_RSA_PSK_WITH_AES_256_CBC_SHA = 0x0095; + + /* + * RFC 4492 + */ + public const int TLS_ECDH_ECDSA_WITH_NULL_SHA = 0xC001; + public const int TLS_ECDH_ECDSA_WITH_RC4_128_SHA = 0xC002; + public const int TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA = 0xC003; + public const int TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA = 0xC004; + public const int TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA = 0xC005; + public const int TLS_ECDHE_ECDSA_WITH_NULL_SHA = 0xC006; + public const int TLS_ECDHE_ECDSA_WITH_RC4_128_SHA = 0xC007; + public const int TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA = 0xC008; + public const int TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA = 0xC009; + public const int TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = 0xC00A; + public const int TLS_ECDH_RSA_WITH_NULL_SHA = 0xC00B; + public const int TLS_ECDH_RSA_WITH_RC4_128_SHA = 0xC00C; + public const int TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA = 0xC00D; + public const int TLS_ECDH_RSA_WITH_AES_128_CBC_SHA = 0xC00E; + public const int TLS_ECDH_RSA_WITH_AES_256_CBC_SHA = 0xC00F; + public const int TLS_ECDHE_RSA_WITH_NULL_SHA = 0xC010; + public const int TLS_ECDHE_RSA_WITH_RC4_128_SHA = 0xC011; + public const int TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA = 0xC012; + public const int TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = 0xC013; + public const int TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xC014; + public const int TLS_ECDH_anon_WITH_NULL_SHA = 0xC015; + public const int TLS_ECDH_anon_WITH_RC4_128_SHA = 0xC016; + public const int TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA = 0xC017; + public const int TLS_ECDH_anon_WITH_AES_128_CBC_SHA = 0xC018; + public const int TLS_ECDH_anon_WITH_AES_256_CBC_SHA = 0xC019; + + /* + * RFC 4785 + */ + public const int TLS_PSK_WITH_NULL_SHA = 0x002C; + public const int TLS_DHE_PSK_WITH_NULL_SHA = 0x002D; + public const int TLS_RSA_PSK_WITH_NULL_SHA = 0x002E; + + /* + * RFC 5054 + */ + public const int TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA = 0xC01A; + public const int TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA = 0xC01B; + public const int TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA = 0xC01C; + public const int TLS_SRP_SHA_WITH_AES_128_CBC_SHA = 0xC01D; + public const int TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA = 0xC01E; + public const int TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA = 0xC01F; + public const int TLS_SRP_SHA_WITH_AES_256_CBC_SHA = 0xC020; + public const int TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA = 0xC021; + public const int TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA = 0xC022; + + /* + * RFC 5246 + */ + public const int TLS_RSA_WITH_NULL_SHA256 = 0x003B; + public const int TLS_RSA_WITH_AES_128_CBC_SHA256 = 0x003C; + public const int TLS_RSA_WITH_AES_256_CBC_SHA256 = 0x003D; + public const int TLS_DH_DSS_WITH_AES_128_CBC_SHA256 = 0x003E; + public const int TLS_DH_RSA_WITH_AES_128_CBC_SHA256 = 0x003F; + public const int TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 = 0x0040; + public const int TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 = 0x0067; + public const int TLS_DH_DSS_WITH_AES_256_CBC_SHA256 = 0x0068; + public const int TLS_DH_RSA_WITH_AES_256_CBC_SHA256 = 0x0069; + public const int TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 = 0x006A; + public const int TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 = 0x006B; + public const int TLS_DH_anon_WITH_AES_128_CBC_SHA256 = 0x006C; + public const int TLS_DH_anon_WITH_AES_256_CBC_SHA256 = 0x006D; + + /* + * RFC 5288 + */ + public const int TLS_RSA_WITH_AES_128_GCM_SHA256 = 0x009C; + public const int TLS_RSA_WITH_AES_256_GCM_SHA384 = 0x009D; + public const int TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 = 0x009E; + public const int TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 = 0x009F; + public const int TLS_DH_RSA_WITH_AES_128_GCM_SHA256 = 0x00A0; + public const int TLS_DH_RSA_WITH_AES_256_GCM_SHA384 = 0x00A1; + public const int TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 = 0x00A2; + public const int TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 = 0x00A3; + public const int TLS_DH_DSS_WITH_AES_128_GCM_SHA256 = 0x00A4; + public const int TLS_DH_DSS_WITH_AES_256_GCM_SHA384 = 0x00A5; + public const int TLS_DH_anon_WITH_AES_128_GCM_SHA256 = 0x00A6; + public const int TLS_DH_anon_WITH_AES_256_GCM_SHA384 = 0x00A7; + + /* + * RFC 5289 + */ + public const int TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 = 0xC023; + public const int TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 = 0xC024; + public const int TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 = 0xC025; + public const int TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 = 0xC026; + public const int TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 = 0xC027; + public const int TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 = 0xC028; + public const int TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 = 0xC029; + public const int TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 = 0xC02A; + public const int TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02B; + public const int TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = 0xC02C; + public const int TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02D; + public const int TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 = 0xC02E; + public const int TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xC02F; + public const int TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = 0xC030; + public const int TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 = 0xC031; + public const int TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 = 0xC032; + + /* + * RFC 5487 + */ + public const int TLS_PSK_WITH_AES_128_GCM_SHA256 = 0x00A8; + public const int TLS_PSK_WITH_AES_256_GCM_SHA384 = 0x00A9; + public const int TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 = 0x00AA; + public const int TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 = 0x00AB; + public const int TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 = 0x00AC; + public const int TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 = 0x00AD; + public const int TLS_PSK_WITH_AES_128_CBC_SHA256 = 0x00AE; + public const int TLS_PSK_WITH_AES_256_CBC_SHA384 = 0x00AF; + public const int TLS_PSK_WITH_NULL_SHA256 = 0x00B0; + public const int TLS_PSK_WITH_NULL_SHA384 = 0x00B1; + public const int TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 = 0x00B2; + public const int TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 = 0x00B3; + public const int TLS_DHE_PSK_WITH_NULL_SHA256 = 0x00B4; + public const int TLS_DHE_PSK_WITH_NULL_SHA384 = 0x00B5; + public const int TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 = 0x00B6; + public const int TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 = 0x00B7; + public const int TLS_RSA_PSK_WITH_NULL_SHA256 = 0x00B8; + public const int TLS_RSA_PSK_WITH_NULL_SHA384 = 0x00B9; + + /* + * RFC 5489 + */ + public const int TLS_ECDHE_PSK_WITH_RC4_128_SHA = 0xC033; + public const int TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA = 0xC034; + public const int TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA = 0xC035; + public const int TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA = 0xC036; + public const int TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 = 0xC037; + public const int TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 = 0xC038; + public const int TLS_ECDHE_PSK_WITH_NULL_SHA = 0xC039; + public const int TLS_ECDHE_PSK_WITH_NULL_SHA256 = 0xC03A; + public const int TLS_ECDHE_PSK_WITH_NULL_SHA384 = 0xC03B; + + /* + * RFC 5746 + */ + public const int TLS_EMPTY_RENEGOTIATION_INFO_SCSV = 0x00FF; + + /* + * RFC 6367 + */ + public const int TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 = 0xC072; + public const int TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 = 0xC073; + public const int TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 = 0xC074; + public const int TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 = 0xC075; + public const int TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 0xC076; + public const int TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 = 0xC077; + public const int TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 0xC078; + public const int TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 = 0xC079; + + public const int TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC07A; + public const int TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC07B; + public const int TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC07C; + public const int TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC07D; + public const int TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC07E; + public const int TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC07F; + public const int TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256 = 0xC080; + public const int TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384 = 0xC081; + public const int TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256 = 0xC082; + public const int TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384 = 0xC083; + public const int TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256 = 0xC084; + public const int TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384 = 0xC085; + public const int TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC086; + public const int TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC087; + public const int TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC088; + public const int TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC089; + public const int TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC08A; + public const int TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC08B; + public const int TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC08C; + public const int TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC08D; + + public const int TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 = 0xC08E; + public const int TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 = 0xC08F; + public const int TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 = 0xC090; + public const int TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 = 0xC091; + public const int TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 = 0xC092; + public const int TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 = 0xC093; + public const int TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 = 0xC094; + public const int TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 = 0xC095; + public const int TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 = 0xC096; + public const int TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 = 0xC097; + public const int TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 = 0xC098; + public const int TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 = 0xC099; + public const int TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 = 0xC09A; + public const int TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 = 0xC09B; + + /* + * RFC 6655 + */ + public const int TLS_RSA_WITH_AES_128_CCM = 0xC09C; + public const int TLS_RSA_WITH_AES_256_CCM = 0xC09D; + public const int TLS_DHE_RSA_WITH_AES_128_CCM = 0xC09E; + public const int TLS_DHE_RSA_WITH_AES_256_CCM = 0xC09F; + public const int TLS_RSA_WITH_AES_128_CCM_8 = 0xC0A0; + public const int TLS_RSA_WITH_AES_256_CCM_8 = 0xC0A1; + public const int TLS_DHE_RSA_WITH_AES_128_CCM_8 = 0xC0A2; + public const int TLS_DHE_RSA_WITH_AES_256_CCM_8 = 0xC0A3; + public const int TLS_PSK_WITH_AES_128_CCM = 0xC0A4; + public const int TLS_PSK_WITH_AES_256_CCM = 0xC0A5; + public const int TLS_DHE_PSK_WITH_AES_128_CCM = 0xC0A6; + public const int TLS_DHE_PSK_WITH_AES_256_CCM = 0xC0A7; + public const int TLS_PSK_WITH_AES_128_CCM_8 = 0xC0A8; + public const int TLS_PSK_WITH_AES_256_CCM_8 = 0xC0A9; + public const int TLS_PSK_DHE_WITH_AES_128_CCM_8 = 0xC0AA; + public const int TLS_PSK_DHE_WITH_AES_256_CCM_8 = 0xC0AB; + + /* + * RFC 7251 + */ + public const int TLS_ECDHE_ECDSA_WITH_AES_128_CCM = 0xC0AC; + public const int TLS_ECDHE_ECDSA_WITH_AES_256_CCM = 0xC0AD; + public const int TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 = 0xC0AE; + public const int TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 = 0xC0AF; + + /* + * RFC 7507 + */ + public const int TLS_FALLBACK_SCSV = 0x5600; + + /* + * draft-ietf-tls-chacha20-poly1305-04 + */ + public const int DRAFT_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCA8; + public const int DRAFT_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCA9; + public const int DRAFT_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAA; + public const int DRAFT_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAB; + public const int DRAFT_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAC; + public const int DRAFT_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAD; + public const int DRAFT_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAE; + + public static bool IsScsv(int cipherSuite) + { + switch (cipherSuite) + { + case TLS_EMPTY_RENEGOTIATION_INFO_SCSV: + case TLS_FALLBACK_SCSV: + return true; + default: + return false; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CipherSuite.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CipherSuite.cs.meta new file mode 100644 index 0000000..4948c2c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CipherSuite.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c52384949c8ab80448870e3b0219a8f0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CipherType.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CipherType.cs new file mode 100644 index 0000000..b2ad7d8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CipherType.cs @@ -0,0 +1,20 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// RFC 2246 + /// + /// Note that the values here are implementation-specific and arbitrary. It is recommended not to + /// depend on the particular values (e.g. serialization). + /// + public abstract class CipherType + { + public const int stream = 0; + public const int block = 1; + + /* + * RFC 5246 + */ + public const int aead = 2; + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CipherType.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CipherType.cs.meta new file mode 100644 index 0000000..0cca1c4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CipherType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 48ebb122ffd11d249b2cf6f62cb05a48 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ClientAuthenticationType.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ClientAuthenticationType.cs new file mode 100644 index 0000000..dd248f3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ClientAuthenticationType.cs @@ -0,0 +1,14 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class ClientAuthenticationType + { + /* + * RFC 5077 4 + */ + public const byte anonymous = 0; + public const byte certificate_based = 1; + public const byte psk = 2; + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ClientAuthenticationType.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ClientAuthenticationType.cs.meta new file mode 100644 index 0000000..77452bb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ClientAuthenticationType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d0608f49e6d291146aa27099a6400c48 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ClientCertificateType.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ClientCertificateType.cs new file mode 100644 index 0000000..a291a46 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ClientCertificateType.cs @@ -0,0 +1,23 @@ +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class ClientCertificateType + { + /* + * RFC 4346 7.4.4 + */ + public const byte rsa_sign = 1; + public const byte dss_sign = 2; + public const byte rsa_fixed_dh = 3; + public const byte dss_fixed_dh = 4; + public const byte rsa_ephemeral_dh_RESERVED = 5; + public const byte dss_ephemeral_dh_RESERVED = 6; + public const byte fortezza_dms_RESERVED = 20; + + /* + * RFC 4492 5.5 + */ + public const byte ecdsa_sign = 64; + public const byte rsa_fixed_ecdh = 65; + public const byte ecdsa_fixed_ecdh = 66; + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ClientCertificateType.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ClientCertificateType.cs.meta new file mode 100644 index 0000000..cc66eba --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ClientCertificateType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dc046bfccf8bbf043ac6941c1a4aabcb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CombinedHash.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CombinedHash.cs new file mode 100644 index 0000000..74a52d5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CombinedHash.cs @@ -0,0 +1,133 @@ +using System; + +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /** + * A combined hash, which implements md5(m) || sha1(m). + */ + internal class CombinedHash + : TlsHandshakeHash + { + protected TlsContext mContext; + protected IDigest mMd5; + protected IDigest mSha1; + + internal CombinedHash() + { + this.mMd5 = TlsUtilities.CreateHash(HashAlgorithm.md5); + this.mSha1 = TlsUtilities.CreateHash(HashAlgorithm.sha1); + } + + internal CombinedHash(CombinedHash t) + { + this.mContext = t.mContext; + this.mMd5 = TlsUtilities.CloneHash(HashAlgorithm.md5, t.mMd5); + this.mSha1 = TlsUtilities.CloneHash(HashAlgorithm.sha1, t.mSha1); + } + + public virtual void Init(TlsContext context) + { + this.mContext = context; + } + + public virtual TlsHandshakeHash NotifyPrfDetermined() + { + return this; + } + + public virtual void TrackHashAlgorithm(byte hashAlgorithm) + { + throw new InvalidOperationException("CombinedHash only supports calculating the legacy PRF for handshake hash"); + } + + public virtual void SealHashAlgorithms() + { + } + + public virtual TlsHandshakeHash StopTracking() + { + return new CombinedHash(this); + } + + public virtual IDigest ForkPrfHash() + { + return new CombinedHash(this); + } + + public virtual byte[] GetFinalHash(byte hashAlgorithm) + { + throw new InvalidOperationException("CombinedHash doesn't support multiple hashes"); + } + + public virtual string AlgorithmName + { + get { return mMd5.AlgorithmName + " and " + mSha1.AlgorithmName; } + } + + public virtual int GetByteLength() + { + return System.Math.Max(mMd5.GetByteLength(), mSha1.GetByteLength()); + } + + public virtual int GetDigestSize() + { + return mMd5.GetDigestSize() + mSha1.GetDigestSize(); + } + + public virtual void Update(byte input) + { + mMd5.Update(input); + mSha1.Update(input); + } + + /** + * @see org.bouncycastle.crypto.Digest#update(byte[], int, int) + */ + public virtual void BlockUpdate(byte[] input, int inOff, int len) + { + mMd5.BlockUpdate(input, inOff, len); + mSha1.BlockUpdate(input, inOff, len); + } + + /** + * @see org.bouncycastle.crypto.Digest#doFinal(byte[], int) + */ + public virtual int DoFinal(byte[] output, int outOff) + { + if (mContext != null && TlsUtilities.IsSsl(mContext)) + { + Ssl3Complete(mMd5, Ssl3Mac.IPAD, Ssl3Mac.OPAD, 48); + Ssl3Complete(mSha1, Ssl3Mac.IPAD, Ssl3Mac.OPAD, 40); + } + + int i1 = mMd5.DoFinal(output, outOff); + int i2 = mSha1.DoFinal(output, outOff + i1); + return i1 + i2; + } + + /** + * @see org.bouncycastle.crypto.Digest#reset() + */ + public virtual void Reset() + { + mMd5.Reset(); + mSha1.Reset(); + } + + protected virtual void Ssl3Complete(IDigest d, byte[] ipad, byte[] opad, int padLength) + { + byte[] master_secret = mContext.SecurityParameters.masterSecret; + + d.BlockUpdate(master_secret, 0, master_secret.Length); + d.BlockUpdate(ipad, 0, padLength); + + byte[] tmp = DigestUtilities.DoFinal(d); + + d.BlockUpdate(master_secret, 0, master_secret.Length); + d.BlockUpdate(opad, 0, padLength); + d.BlockUpdate(tmp, 0, tmp.Length); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CombinedHash.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CombinedHash.cs.meta new file mode 100644 index 0000000..4236d05 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CombinedHash.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 06bfea7b8abc5af41919e94d7127fb63 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CompressionMethod.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CompressionMethod.cs new file mode 100644 index 0000000..89c1f5f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CompressionMethod.cs @@ -0,0 +1,22 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// + /// RFC 2246 6.1 + /// + public abstract class CompressionMethod + { + public const byte cls_null = 0; + + /* + * RFC 3749 2 + */ + public const byte DEFLATE = 1; + + /* + * Values from 224 decimal (0xE0) through 255 decimal (0xFF) + * inclusive are reserved for private use. + */ + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CompressionMethod.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CompressionMethod.cs.meta new file mode 100644 index 0000000..9091e0f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/CompressionMethod.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 01b5743c3e6067e41ae2da6ee12e917c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ConnectionEnd.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ConnectionEnd.cs new file mode 100644 index 0000000..afc9460 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ConnectionEnd.cs @@ -0,0 +1,15 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// RFC 2246 + /// + /// Note that the values here are implementation-specific and arbitrary. It is recommended not to + /// depend on the particular values (e.g. serialization). + /// + public abstract class ConnectionEnd + { + public const int server = 0; + public const int client = 1; + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ConnectionEnd.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ConnectionEnd.cs.meta new file mode 100644 index 0000000..8c07b1f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ConnectionEnd.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f53e8184c02041a4084ec6ab5b36c217 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ContentType.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ContentType.cs new file mode 100644 index 0000000..d6ab438 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ContentType.cs @@ -0,0 +1,14 @@ +namespace Org.BouncyCastle.Crypto.Tls +{ + /** + * RFC 2246 6.2.1 + */ + public abstract class ContentType + { + public const byte change_cipher_spec = 20; + public const byte alert = 21; + public const byte handshake = 22; + public const byte application_data = 23; + public const byte heartbeat = 24; + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ContentType.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ContentType.cs.meta new file mode 100644 index 0000000..94e5cac --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ContentType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b13657df687ae1940be32e97c3f99a79 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DatagramTransport.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DatagramTransport.cs new file mode 100644 index 0000000..42f958d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DatagramTransport.cs @@ -0,0 +1,21 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public interface DatagramTransport + : TlsCloseable + { + /// + int GetReceiveLimit(); + + /// + int GetSendLimit(); + + /// + int Receive(byte[] buf, int off, int len, int waitMillis); + + /// + void Send(byte[] buf, int off, int len); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DatagramTransport.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DatagramTransport.cs.meta new file mode 100644 index 0000000..a54e372 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DatagramTransport.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bd60ac8b282fe5e448a43125c8c44ad4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DefaultTlsAgreementCredentials.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DefaultTlsAgreementCredentials.cs new file mode 100644 index 0000000..fab9788 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DefaultTlsAgreementCredentials.cs @@ -0,0 +1,69 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Crypto.Agreement; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class DefaultTlsAgreementCredentials + : AbstractTlsAgreementCredentials + { + protected readonly Certificate mCertificate; + protected readonly AsymmetricKeyParameter mPrivateKey; + + protected readonly IBasicAgreement mBasicAgreement; + protected readonly bool mTruncateAgreement; + + public DefaultTlsAgreementCredentials(Certificate certificate, AsymmetricKeyParameter privateKey) + { + if (certificate == null) + throw new ArgumentNullException("certificate"); + if (certificate.IsEmpty) + throw new ArgumentException("cannot be empty", "certificate"); + if (privateKey == null) + throw new ArgumentNullException("privateKey"); + if (!privateKey.IsPrivate) + throw new ArgumentException("must be private", "privateKey"); + + if (privateKey is DHPrivateKeyParameters) + { + mBasicAgreement = new DHBasicAgreement(); + mTruncateAgreement = true; + } + else if (privateKey is ECPrivateKeyParameters) + { + mBasicAgreement = new ECDHBasicAgreement(); + mTruncateAgreement = false; + } + else + { + throw new ArgumentException("type not supported: " + Platform.GetTypeName(privateKey), "privateKey"); + } + + this.mCertificate = certificate; + this.mPrivateKey = privateKey; + } + + public override Certificate Certificate + { + get { return mCertificate; } + } + + /// + public override byte[] GenerateAgreement(AsymmetricKeyParameter peerPublicKey) + { + mBasicAgreement.Init(mPrivateKey); + BigInteger agreementValue = mBasicAgreement.CalculateAgreement(peerPublicKey); + + if (mTruncateAgreement) + { + return BigIntegers.AsUnsignedByteArray(agreementValue); + } + + return BigIntegers.AsUnsignedByteArray(mBasicAgreement.GetFieldSize(), agreementValue); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DefaultTlsAgreementCredentials.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DefaultTlsAgreementCredentials.cs.meta new file mode 100644 index 0000000..a48e595 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DefaultTlsAgreementCredentials.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f74e263f91c9c464096437f201d7fa65 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DefaultTlsCipherFactory.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DefaultTlsCipherFactory.cs new file mode 100644 index 0000000..af0ec12 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DefaultTlsCipherFactory.cs @@ -0,0 +1,227 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Modes; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class DefaultTlsCipherFactory + : AbstractTlsCipherFactory + { + /// + public override TlsCipher CreateCipher(TlsContext context, int encryptionAlgorithm, int macAlgorithm) + { + switch (encryptionAlgorithm) + { + case EncryptionAlgorithm.cls_3DES_EDE_CBC: + return CreateDesEdeCipher(context, macAlgorithm); + case EncryptionAlgorithm.AES_128_CBC: + return CreateAESCipher(context, 16, macAlgorithm); + case EncryptionAlgorithm.AES_128_CCM: + // NOTE: Ignores macAlgorithm + return CreateCipher_Aes_Ccm(context, 16, 16); + case EncryptionAlgorithm.AES_128_CCM_8: + // NOTE: Ignores macAlgorithm + return CreateCipher_Aes_Ccm(context, 16, 8); + case EncryptionAlgorithm.AES_128_GCM: + // NOTE: Ignores macAlgorithm + return CreateCipher_Aes_Gcm(context, 16, 16); + case EncryptionAlgorithm.AES_128_OCB_TAGLEN96: + // NOTE: Ignores macAlgorithm + return CreateCipher_Aes_Ocb(context, 16, 12); + case EncryptionAlgorithm.AES_256_CBC: + return CreateAESCipher(context, 32, macAlgorithm); + case EncryptionAlgorithm.AES_256_CCM: + // NOTE: Ignores macAlgorithm + return CreateCipher_Aes_Ccm(context, 32, 16); + case EncryptionAlgorithm.AES_256_CCM_8: + // NOTE: Ignores macAlgorithm + return CreateCipher_Aes_Ccm(context, 32, 8); + case EncryptionAlgorithm.AES_256_GCM: + // NOTE: Ignores macAlgorithm + return CreateCipher_Aes_Gcm(context, 32, 16); + case EncryptionAlgorithm.AES_256_OCB_TAGLEN96: + // NOTE: Ignores macAlgorithm + return CreateCipher_Aes_Ocb(context, 32, 12); + case EncryptionAlgorithm.CAMELLIA_128_CBC: + return CreateCamelliaCipher(context, 16, macAlgorithm); + case EncryptionAlgorithm.CAMELLIA_128_GCM: + // NOTE: Ignores macAlgorithm + return CreateCipher_Camellia_Gcm(context, 16, 16); + case EncryptionAlgorithm.CAMELLIA_256_CBC: + return CreateCamelliaCipher(context, 32, macAlgorithm); + case EncryptionAlgorithm.CAMELLIA_256_GCM: + // NOTE: Ignores macAlgorithm + return CreateCipher_Camellia_Gcm(context, 32, 16); + case EncryptionAlgorithm.CHACHA20_POLY1305: + // NOTE: Ignores macAlgorithm + return CreateChaCha20Poly1305(context); + case EncryptionAlgorithm.NULL: + return CreateNullCipher(context, macAlgorithm); + case EncryptionAlgorithm.RC4_128: + return CreateRC4Cipher(context, 16, macAlgorithm); + case EncryptionAlgorithm.SEED_CBC: + return CreateSeedCipher(context, macAlgorithm); + default: + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + /// + protected virtual TlsBlockCipher CreateAESCipher(TlsContext context, int cipherKeySize, int macAlgorithm) + { + return new TlsBlockCipher(context, CreateAesBlockCipher(), CreateAesBlockCipher(), + CreateHMacDigest(macAlgorithm), CreateHMacDigest(macAlgorithm), cipherKeySize); + } + + /// + protected virtual TlsBlockCipher CreateCamelliaCipher(TlsContext context, int cipherKeySize, int macAlgorithm) + { + return new TlsBlockCipher(context, CreateCamelliaBlockCipher(), + CreateCamelliaBlockCipher(), CreateHMacDigest(macAlgorithm), + CreateHMacDigest(macAlgorithm), cipherKeySize); + } + + /// + protected virtual TlsCipher CreateChaCha20Poly1305(TlsContext context) + { + return new Chacha20Poly1305(context); + } + + /// + protected virtual TlsAeadCipher CreateCipher_Aes_Ccm(TlsContext context, int cipherKeySize, int macSize) + { + return new TlsAeadCipher(context, CreateAeadBlockCipher_Aes_Ccm(), + CreateAeadBlockCipher_Aes_Ccm(), cipherKeySize, macSize); + } + + /// + protected virtual TlsAeadCipher CreateCipher_Aes_Gcm(TlsContext context, int cipherKeySize, int macSize) + { + return new TlsAeadCipher(context, CreateAeadBlockCipher_Aes_Gcm(), + CreateAeadBlockCipher_Aes_Gcm(), cipherKeySize, macSize); + } + + /// + protected virtual TlsAeadCipher CreateCipher_Aes_Ocb(TlsContext context, int cipherKeySize, int macSize) + { + return new TlsAeadCipher(context, CreateAeadBlockCipher_Aes_Ocb(), + CreateAeadBlockCipher_Aes_Ocb(), cipherKeySize, macSize, TlsAeadCipher.NONCE_DRAFT_CHACHA20_POLY1305); + } + + /// + protected virtual TlsAeadCipher CreateCipher_Camellia_Gcm(TlsContext context, int cipherKeySize, int macSize) + { + return new TlsAeadCipher(context, CreateAeadBlockCipher_Camellia_Gcm(), + CreateAeadBlockCipher_Camellia_Gcm(), cipherKeySize, macSize); + } + + /// + protected virtual TlsBlockCipher CreateDesEdeCipher(TlsContext context, int macAlgorithm) + { + return new TlsBlockCipher(context, CreateDesEdeBlockCipher(), CreateDesEdeBlockCipher(), + CreateHMacDigest(macAlgorithm), CreateHMacDigest(macAlgorithm), 24); + } + + /// + protected virtual TlsNullCipher CreateNullCipher(TlsContext context, int macAlgorithm) + { + return new TlsNullCipher(context, CreateHMacDigest(macAlgorithm), + CreateHMacDigest(macAlgorithm)); + } + + /// + protected virtual TlsStreamCipher CreateRC4Cipher(TlsContext context, int cipherKeySize, int macAlgorithm) + { + return new TlsStreamCipher(context, CreateRC4StreamCipher(), CreateRC4StreamCipher(), + CreateHMacDigest(macAlgorithm), CreateHMacDigest(macAlgorithm), cipherKeySize, false); + } + + /// + protected virtual TlsBlockCipher CreateSeedCipher(TlsContext context, int macAlgorithm) + { + return new TlsBlockCipher(context, CreateSeedBlockCipher(), CreateSeedBlockCipher(), + CreateHMacDigest(macAlgorithm), CreateHMacDigest(macAlgorithm), 16); + } + + protected virtual IBlockCipher CreateAesEngine() + { + return new AesEngine(); + } + + protected virtual IBlockCipher CreateCamelliaEngine() + { + return new CamelliaEngine(); + } + + protected virtual IBlockCipher CreateAesBlockCipher() + { + return new CbcBlockCipher(CreateAesEngine()); + } + + protected virtual IAeadBlockCipher CreateAeadBlockCipher_Aes_Ccm() + { + return new CcmBlockCipher(CreateAesEngine()); + } + + protected virtual IAeadBlockCipher CreateAeadBlockCipher_Aes_Gcm() + { + // TODO Consider allowing custom configuration of multiplier + return new GcmBlockCipher(CreateAesEngine()); + } + + protected virtual IAeadBlockCipher CreateAeadBlockCipher_Aes_Ocb() + { + return new OcbBlockCipher(CreateAesEngine(), CreateAesEngine()); + } + + protected virtual IAeadBlockCipher CreateAeadBlockCipher_Camellia_Gcm() + { + // TODO Consider allowing custom configuration of multiplier + return new GcmBlockCipher(CreateCamelliaEngine()); + } + + protected virtual IBlockCipher CreateCamelliaBlockCipher() + { + return new CbcBlockCipher(CreateCamelliaEngine()); + } + + protected virtual IBlockCipher CreateDesEdeBlockCipher() + { + return new CbcBlockCipher(new DesEdeEngine()); + } + + protected virtual IStreamCipher CreateRC4StreamCipher() + { + return new RC4Engine(); + } + + protected virtual IBlockCipher CreateSeedBlockCipher() + { + return new CbcBlockCipher(new SeedEngine()); + } + + /// + protected virtual IDigest CreateHMacDigest(int macAlgorithm) + { + switch (macAlgorithm) + { + case MacAlgorithm.cls_null: + return null; + case MacAlgorithm.hmac_md5: + return TlsUtilities.CreateHash(HashAlgorithm.md5); + case MacAlgorithm.hmac_sha1: + return TlsUtilities.CreateHash(HashAlgorithm.sha1); + case MacAlgorithm.hmac_sha256: + return TlsUtilities.CreateHash(HashAlgorithm.sha256); + case MacAlgorithm.hmac_sha384: + return TlsUtilities.CreateHash(HashAlgorithm.sha384); + case MacAlgorithm.hmac_sha512: + return TlsUtilities.CreateHash(HashAlgorithm.sha512); + default: + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DefaultTlsCipherFactory.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DefaultTlsCipherFactory.cs.meta new file mode 100644 index 0000000..3475f1a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DefaultTlsCipherFactory.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 714e417265cde364fb3af786a3bdf5e5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DefaultTlsClient.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DefaultTlsClient.cs new file mode 100644 index 0000000..64d2986 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DefaultTlsClient.cs @@ -0,0 +1,115 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Modes; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class DefaultTlsClient + : AbstractTlsClient + { + protected TlsDHVerifier mDHVerifier; + + public DefaultTlsClient() + : this(new DefaultTlsCipherFactory()) + { + } + + public DefaultTlsClient(TlsCipherFactory cipherFactory) + : this(cipherFactory, new DefaultTlsDHVerifier()) + { + } + + public DefaultTlsClient(TlsCipherFactory cipherFactory, TlsDHVerifier dhVerifier) + : base(cipherFactory) + { + this.mDHVerifier = dhVerifier; + } + + public override int[] GetCipherSuites() + { + return new int[] + { + CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, + CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, + CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, + CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256, + CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256, + CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, + }; + } + + public override TlsKeyExchange GetKeyExchange() + { + int keyExchangeAlgorithm = TlsUtilities.GetKeyExchangeAlgorithm(mSelectedCipherSuite); + + switch (keyExchangeAlgorithm) + { + case KeyExchangeAlgorithm.DH_anon: + case KeyExchangeAlgorithm.DH_DSS: + case KeyExchangeAlgorithm.DH_RSA: + return CreateDHKeyExchange(keyExchangeAlgorithm); + + case KeyExchangeAlgorithm.DHE_DSS: + case KeyExchangeAlgorithm.DHE_RSA: + return CreateDheKeyExchange(keyExchangeAlgorithm); + + case KeyExchangeAlgorithm.ECDH_anon: + case KeyExchangeAlgorithm.ECDH_ECDSA: + case KeyExchangeAlgorithm.ECDH_RSA: + return CreateECDHKeyExchange(keyExchangeAlgorithm); + + case KeyExchangeAlgorithm.ECDHE_ECDSA: + case KeyExchangeAlgorithm.ECDHE_RSA: + return CreateECDheKeyExchange(keyExchangeAlgorithm); + + case KeyExchangeAlgorithm.RSA: + return CreateRsaKeyExchange(); + + default: + /* + * Note: internal error here; the TlsProtocol implementation verifies that the + * server-selected cipher suite was in the list of client-offered cipher suites, so if + * we now can't produce an implementation, we shouldn't have offered it! + */ + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + protected virtual TlsKeyExchange CreateDHKeyExchange(int keyExchange) + { + return new TlsDHKeyExchange(keyExchange, mSupportedSignatureAlgorithms, mDHVerifier, null); + } + + protected virtual TlsKeyExchange CreateDheKeyExchange(int keyExchange) + { + return new TlsDheKeyExchange(keyExchange, mSupportedSignatureAlgorithms, mDHVerifier, null); + } + + protected virtual TlsKeyExchange CreateECDHKeyExchange(int keyExchange) + { + return new TlsECDHKeyExchange(keyExchange, mSupportedSignatureAlgorithms, mNamedCurves, mClientECPointFormats, + mServerECPointFormats); + } + + protected virtual TlsKeyExchange CreateECDheKeyExchange(int keyExchange) + { + return new TlsECDheKeyExchange(keyExchange, mSupportedSignatureAlgorithms, mNamedCurves, mClientECPointFormats, + mServerECPointFormats); + } + + protected virtual TlsKeyExchange CreateRsaKeyExchange() + { + return new TlsRsaKeyExchange(mSupportedSignatureAlgorithms); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DefaultTlsClient.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DefaultTlsClient.cs.meta new file mode 100644 index 0000000..b81556c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DefaultTlsClient.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dd3be16e4cbc0af4fba720ed25736848 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DefaultTlsDHVerifier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DefaultTlsDHVerifier.cs new file mode 100644 index 0000000..ae26d04 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DefaultTlsDHVerifier.cs @@ -0,0 +1,101 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Crypto.Agreement; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class DefaultTlsDHVerifier + : TlsDHVerifier + { + public static readonly int DefaultMinimumPrimeBits = 2048; + + protected static readonly IList DefaultGroups = Platform.CreateArrayList(); + + private static void AddDefaultGroup(DHParameters dhParameters) + { + DefaultGroups.Add(dhParameters); + } + + static DefaultTlsDHVerifier() + { + AddDefaultGroup(DHStandardGroups.rfc7919_ffdhe2048); + AddDefaultGroup(DHStandardGroups.rfc7919_ffdhe3072); + AddDefaultGroup(DHStandardGroups.rfc7919_ffdhe4096); + AddDefaultGroup(DHStandardGroups.rfc7919_ffdhe6144); + AddDefaultGroup(DHStandardGroups.rfc7919_ffdhe8192); + + AddDefaultGroup(DHStandardGroups.rfc3526_1536); + AddDefaultGroup(DHStandardGroups.rfc3526_2048); + AddDefaultGroup(DHStandardGroups.rfc3526_3072); + AddDefaultGroup(DHStandardGroups.rfc3526_4096); + AddDefaultGroup(DHStandardGroups.rfc3526_6144); + AddDefaultGroup(DHStandardGroups.rfc3526_8192); + } + + // IList is (DHParameters) + protected readonly IList mGroups; + protected readonly int mMinimumPrimeBits; + + /// Accept various standard DH groups with 'P' at least DefaultMinimumPrimeBits bits. + public DefaultTlsDHVerifier() + : this(DefaultMinimumPrimeBits) + { + } + + /// Accept various standard DH groups with 'P' at least the specified number of bits. + public DefaultTlsDHVerifier(int minimumPrimeBits) + : this(DefaultGroups, minimumPrimeBits) + { + } + + /// Accept a custom set of group parameters, subject to a minimum bitlength for 'P'. + /// An IList of acceptable DHParameters. + /// The minimum acceptable bitlength of the 'P' parameter. + public DefaultTlsDHVerifier(IList groups, int minimumPrimeBits) + { + this.mGroups = groups; + this.mMinimumPrimeBits = minimumPrimeBits; + } + + public virtual bool Accept(DHParameters dhParameters) + { + return CheckMinimumPrimeBits(dhParameters) && CheckGroup(dhParameters); + } + + public virtual int MinimumPrimeBits + { + get { return mMinimumPrimeBits; } + } + + protected virtual bool AreGroupsEqual(DHParameters a, DHParameters b) + { + return a == b || (AreParametersEqual(a.P, b.P) && AreParametersEqual(a.G, b.G)); + } + + protected virtual bool AreParametersEqual(BigInteger a, BigInteger b) + { + return a == b || a.Equals(b); + } + + protected virtual bool CheckGroup(DHParameters dhParameters) + { + foreach (DHParameters group in mGroups) + { + if (AreGroupsEqual(dhParameters, group)) + { + return true; + } + } + return false; + } + + protected virtual bool CheckMinimumPrimeBits(DHParameters dhParameters) + { + return dhParameters.P.BitLength >= MinimumPrimeBits; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DefaultTlsDHVerifier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DefaultTlsDHVerifier.cs.meta new file mode 100644 index 0000000..e616d13 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DefaultTlsDHVerifier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a47a61fd85271ce4e8db414a648926ee +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DefaultTlsEncryptionCredentials.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DefaultTlsEncryptionCredentials.cs new file mode 100644 index 0000000..5348ee8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DefaultTlsEncryptionCredentials.cs @@ -0,0 +1,52 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class DefaultTlsEncryptionCredentials + : AbstractTlsEncryptionCredentials + { + protected readonly TlsContext mContext; + protected readonly Certificate mCertificate; + protected readonly AsymmetricKeyParameter mPrivateKey; + + public DefaultTlsEncryptionCredentials(TlsContext context, Certificate certificate, + AsymmetricKeyParameter privateKey) + { + if (certificate == null) + throw new ArgumentNullException("certificate"); + if (certificate.IsEmpty) + throw new ArgumentException("cannot be empty", "certificate"); + if (privateKey == null) + throw new ArgumentNullException("'privateKey' cannot be null"); + if (!privateKey.IsPrivate) + throw new ArgumentException("must be private", "privateKey"); + + if (privateKey is RsaKeyParameters) + { + } + else + { + throw new ArgumentException("type not supported: " + Platform.GetTypeName(privateKey), "privateKey"); + } + + this.mContext = context; + this.mCertificate = certificate; + this.mPrivateKey = privateKey; + } + + public override Certificate Certificate + { + get { return mCertificate; } + } + + /// + public override byte[] DecryptPreMasterSecret(byte[] encryptedPreMasterSecret) + { + return TlsRsaUtilities.SafeDecryptPreMasterSecret(mContext, (RsaKeyParameters)mPrivateKey, encryptedPreMasterSecret); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DefaultTlsEncryptionCredentials.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DefaultTlsEncryptionCredentials.cs.meta new file mode 100644 index 0000000..2a6a16e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DefaultTlsEncryptionCredentials.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a800384081fb98b428e13f9b73498c49 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DefaultTlsServer.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DefaultTlsServer.cs new file mode 100644 index 0000000..90f3576 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DefaultTlsServer.cs @@ -0,0 +1,166 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Crypto.Agreement; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class DefaultTlsServer + : AbstractTlsServer + { + public DefaultTlsServer() + : base() + { + } + + public DefaultTlsServer(TlsCipherFactory cipherFactory) + : base(cipherFactory) + { + } + + protected virtual TlsSignerCredentials GetDsaSignerCredentials() + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + protected virtual TlsSignerCredentials GetECDsaSignerCredentials() + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + protected virtual TlsEncryptionCredentials GetRsaEncryptionCredentials() + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + protected virtual TlsSignerCredentials GetRsaSignerCredentials() + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + protected virtual DHParameters GetDHParameters() + { + return DHStandardGroups.rfc7919_ffdhe2048; + } + + protected override int[] GetCipherSuites() + { + return new int[] + { + CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, + CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, + CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, + CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, + CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, + CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, + CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, + CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA, + CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA, + CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384, + CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256, + CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256, + CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256, + CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA, + CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, + }; + } + + public override TlsCredentials GetCredentials() + { + int keyExchangeAlgorithm = TlsUtilities.GetKeyExchangeAlgorithm(mSelectedCipherSuite); + + switch (keyExchangeAlgorithm) + { + case KeyExchangeAlgorithm.DHE_DSS: + return GetDsaSignerCredentials(); + + case KeyExchangeAlgorithm.DH_anon: + case KeyExchangeAlgorithm.ECDH_anon: + return null; + + case KeyExchangeAlgorithm.ECDHE_ECDSA: + return GetECDsaSignerCredentials(); + + case KeyExchangeAlgorithm.DHE_RSA: + case KeyExchangeAlgorithm.ECDHE_RSA: + return GetRsaSignerCredentials(); + + case KeyExchangeAlgorithm.RSA: + return GetRsaEncryptionCredentials(); + + default: + /* Note: internal error here; selected a key exchange we don't implement! */ + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + public override TlsKeyExchange GetKeyExchange() + { + int keyExchangeAlgorithm = TlsUtilities.GetKeyExchangeAlgorithm(mSelectedCipherSuite); + + switch (keyExchangeAlgorithm) + { + case KeyExchangeAlgorithm.DH_anon: + case KeyExchangeAlgorithm.DH_DSS: + case KeyExchangeAlgorithm.DH_RSA: + return CreateDHKeyExchange(keyExchangeAlgorithm); + + case KeyExchangeAlgorithm.DHE_DSS: + case KeyExchangeAlgorithm.DHE_RSA: + return CreateDheKeyExchange(keyExchangeAlgorithm); + + case KeyExchangeAlgorithm.ECDH_anon: + case KeyExchangeAlgorithm.ECDH_ECDSA: + case KeyExchangeAlgorithm.ECDH_RSA: + return CreateECDHKeyExchange(keyExchangeAlgorithm); + + case KeyExchangeAlgorithm.ECDHE_ECDSA: + case KeyExchangeAlgorithm.ECDHE_RSA: + return CreateECDheKeyExchange(keyExchangeAlgorithm); + + case KeyExchangeAlgorithm.RSA: + return CreateRsaKeyExchange(); + + default: + /* + * Note: internal error here; the TlsProtocol implementation verifies that the + * server-selected cipher suite was in the list of client-offered cipher suites, so if + * we now can't produce an implementation, we shouldn't have offered it! + */ + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + protected virtual TlsKeyExchange CreateDHKeyExchange(int keyExchange) + { + return new TlsDHKeyExchange(keyExchange, mSupportedSignatureAlgorithms, null, GetDHParameters()); + } + + protected virtual TlsKeyExchange CreateDheKeyExchange(int keyExchange) + { + return new TlsDheKeyExchange(keyExchange, mSupportedSignatureAlgorithms, null, GetDHParameters()); + } + + protected virtual TlsKeyExchange CreateECDHKeyExchange(int keyExchange) + { + return new TlsECDHKeyExchange(keyExchange, mSupportedSignatureAlgorithms, mNamedCurves, mClientECPointFormats, + mServerECPointFormats); + } + + protected virtual TlsKeyExchange CreateECDheKeyExchange(int keyExchange) + { + return new TlsECDheKeyExchange(keyExchange, mSupportedSignatureAlgorithms, mNamedCurves, mClientECPointFormats, + mServerECPointFormats); + } + + protected virtual TlsKeyExchange CreateRsaKeyExchange() + { + return new TlsRsaKeyExchange(mSupportedSignatureAlgorithms); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DefaultTlsServer.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DefaultTlsServer.cs.meta new file mode 100644 index 0000000..8fa3313 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DefaultTlsServer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 04c003957802544409d94c181b60c428 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DefaultTlsSignerCredentials.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DefaultTlsSignerCredentials.cs new file mode 100644 index 0000000..0ff732a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DefaultTlsSignerCredentials.cs @@ -0,0 +1,93 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class DefaultTlsSignerCredentials + : AbstractTlsSignerCredentials + { + protected readonly TlsContext mContext; + protected readonly Certificate mCertificate; + protected readonly AsymmetricKeyParameter mPrivateKey; + protected readonly SignatureAndHashAlgorithm mSignatureAndHashAlgorithm; + + protected readonly TlsSigner mSigner; + + public DefaultTlsSignerCredentials(TlsContext context, Certificate certificate, AsymmetricKeyParameter privateKey) + : this(context, certificate, privateKey, null) + { + } + + public DefaultTlsSignerCredentials(TlsContext context, Certificate certificate, AsymmetricKeyParameter privateKey, + SignatureAndHashAlgorithm signatureAndHashAlgorithm) + { + if (certificate == null) + throw new ArgumentNullException("certificate"); + if (certificate.IsEmpty) + throw new ArgumentException("cannot be empty", "clientCertificate"); + if (privateKey == null) + throw new ArgumentNullException("privateKey"); + if (!privateKey.IsPrivate) + throw new ArgumentException("must be private", "privateKey"); + if (TlsUtilities.IsTlsV12(context) && signatureAndHashAlgorithm == null) + throw new ArgumentException("cannot be null for (D)TLS 1.2+", "signatureAndHashAlgorithm"); + + if (privateKey is RsaKeyParameters) + { + mSigner = new TlsRsaSigner(); + } + else if (privateKey is DsaPrivateKeyParameters) + { + mSigner = new TlsDssSigner(); + } + else if (privateKey is ECPrivateKeyParameters) + { + mSigner = new TlsECDsaSigner(); + } + else + { + throw new ArgumentException("type not supported: " + Platform.GetTypeName(privateKey), "privateKey"); + } + + this.mSigner.Init(context); + + this.mContext = context; + this.mCertificate = certificate; + this.mPrivateKey = privateKey; + this.mSignatureAndHashAlgorithm = signatureAndHashAlgorithm; + } + + public override Certificate Certificate + { + get { return mCertificate; } + } + + /// + public override byte[] GenerateCertificateSignature(byte[] hash) + { + try + { + if (TlsUtilities.IsTlsV12(mContext)) + { + return mSigner.GenerateRawSignature(mSignatureAndHashAlgorithm, mPrivateKey, hash); + } + else + { + return mSigner.GenerateRawSignature(mPrivateKey, hash); + } + } + catch (CryptoException e) + { + throw new TlsFatalAlert(AlertDescription.internal_error, e); + } + } + + public override SignatureAndHashAlgorithm SignatureAndHashAlgorithm + { + get { return mSignatureAndHashAlgorithm; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DefaultTlsSignerCredentials.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DefaultTlsSignerCredentials.cs.meta new file mode 100644 index 0000000..fade693 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DefaultTlsSignerCredentials.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ae5a42f0dcd9c4c478d4cb1b56f8708c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DefaultTlsSrpGroupVerifier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DefaultTlsSrpGroupVerifier.cs new file mode 100644 index 0000000..cc933bf --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DefaultTlsSrpGroupVerifier.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Crypto.Agreement.Srp; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class DefaultTlsSrpGroupVerifier + : TlsSrpGroupVerifier + { + protected static readonly IList DefaultGroups = Platform.CreateArrayList(); + + static DefaultTlsSrpGroupVerifier() + { + DefaultGroups.Add(Srp6StandardGroups.rfc5054_1024); + DefaultGroups.Add(Srp6StandardGroups.rfc5054_1536); + DefaultGroups.Add(Srp6StandardGroups.rfc5054_2048); + DefaultGroups.Add(Srp6StandardGroups.rfc5054_3072); + DefaultGroups.Add(Srp6StandardGroups.rfc5054_4096); + DefaultGroups.Add(Srp6StandardGroups.rfc5054_6144); + DefaultGroups.Add(Srp6StandardGroups.rfc5054_8192); + } + + // Vector is (SRP6GroupParameters) + protected readonly IList mGroups; + + /** + * Accept only the group parameters specified in RFC 5054 Appendix A. + */ + public DefaultTlsSrpGroupVerifier() + : this(DefaultGroups) + { + } + + /** + * Specify a custom set of acceptable group parameters. + * + * @param groups a {@link Vector} of acceptable {@link SRP6GroupParameters} + */ + public DefaultTlsSrpGroupVerifier(IList groups) + { + this.mGroups = groups; + } + + public virtual bool Accept(Srp6GroupParameters group) + { + foreach (Srp6GroupParameters entry in mGroups) + { + if (AreGroupsEqual(group, entry)) + { + return true; + } + } + return false; + } + + protected virtual bool AreGroupsEqual(Srp6GroupParameters a, Srp6GroupParameters b) + { + return a == b || (AreParametersEqual(a.N, b.N) && AreParametersEqual(a.G, b.G)); + } + + protected virtual bool AreParametersEqual(BigInteger a, BigInteger b) + { + return a == b || a.Equals(b); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DefaultTlsSrpGroupVerifier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DefaultTlsSrpGroupVerifier.cs.meta new file mode 100644 index 0000000..0a81c31 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DefaultTlsSrpGroupVerifier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2d2198fc359602547a36216200a163cf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DeferredHash.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DeferredHash.cs new file mode 100644 index 0000000..f402f26 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DeferredHash.cs @@ -0,0 +1,201 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /** + * Buffers input until the hash algorithm is determined. + */ + internal class DeferredHash + : TlsHandshakeHash + { + protected const int BUFFERING_HASH_LIMIT = 4; + + protected TlsContext mContext; + + private DigestInputBuffer mBuf; + private IDictionary mHashes; + private int mPrfHashAlgorithm; + + internal DeferredHash() + { + this.mBuf = new DigestInputBuffer(); + this.mHashes = Platform.CreateHashtable(); + this.mPrfHashAlgorithm = -1; + } + + private DeferredHash(byte prfHashAlgorithm, IDigest prfHash) + { + this.mBuf = null; + this.mHashes = Platform.CreateHashtable(); + this.mPrfHashAlgorithm = prfHashAlgorithm; + mHashes[prfHashAlgorithm] = prfHash; + } + + public virtual void Init(TlsContext context) + { + this.mContext = context; + } + + public virtual TlsHandshakeHash NotifyPrfDetermined() + { + int prfAlgorithm = mContext.SecurityParameters.PrfAlgorithm; + if (prfAlgorithm == PrfAlgorithm.tls_prf_legacy) + { + CombinedHash legacyHash = new CombinedHash(); + legacyHash.Init(mContext); + mBuf.UpdateDigest(legacyHash); + return legacyHash.NotifyPrfDetermined(); + } + + this.mPrfHashAlgorithm = TlsUtilities.GetHashAlgorithmForPrfAlgorithm(prfAlgorithm); + + CheckTrackingHash((byte)mPrfHashAlgorithm); + + return this; + } + + public virtual void TrackHashAlgorithm(byte hashAlgorithm) + { + if (mBuf == null) + throw new InvalidOperationException("Too late to track more hash algorithms"); + + CheckTrackingHash(hashAlgorithm); + } + + public virtual void SealHashAlgorithms() + { + CheckStopBuffering(); + } + + public virtual TlsHandshakeHash StopTracking() + { + byte prfHashAlgorithm = (byte)mPrfHashAlgorithm; + IDigest prfHash = TlsUtilities.CloneHash(prfHashAlgorithm, (IDigest)mHashes[prfHashAlgorithm]); + if (mBuf != null) + { + mBuf.UpdateDigest(prfHash); + } + DeferredHash result = new DeferredHash(prfHashAlgorithm, prfHash); + result.Init(mContext); + return result; + } + + public virtual IDigest ForkPrfHash() + { + CheckStopBuffering(); + + byte prfHashAlgorithm = (byte)mPrfHashAlgorithm; + if (mBuf != null) + { + IDigest prfHash = TlsUtilities.CreateHash(prfHashAlgorithm); + mBuf.UpdateDigest(prfHash); + return prfHash; + } + + return TlsUtilities.CloneHash(prfHashAlgorithm, (IDigest)mHashes[prfHashAlgorithm]); + } + + public virtual byte[] GetFinalHash(byte hashAlgorithm) + { + IDigest d = (IDigest)mHashes[hashAlgorithm]; + if (d == null) + throw new InvalidOperationException("HashAlgorithm." + HashAlgorithm.GetText(hashAlgorithm) + " is not being tracked"); + + d = TlsUtilities.CloneHash(hashAlgorithm, d); + if (mBuf != null) + { + mBuf.UpdateDigest(d); + } + + return DigestUtilities.DoFinal(d); + } + + public virtual string AlgorithmName + { + get { throw new InvalidOperationException("Use Fork() to get a definite IDigest"); } + } + + public virtual int GetByteLength() + { + throw new InvalidOperationException("Use Fork() to get a definite IDigest"); + } + + public virtual int GetDigestSize() + { + throw new InvalidOperationException("Use Fork() to get a definite IDigest"); + } + + public virtual void Update(byte input) + { + if (mBuf != null) + { + mBuf.WriteByte(input); + return; + } + + foreach (IDigest hash in mHashes.Values) + { + hash.Update(input); + } + } + + public virtual void BlockUpdate(byte[] input, int inOff, int len) + { + if (mBuf != null) + { + mBuf.Write(input, inOff, len); + return; + } + + foreach (IDigest hash in mHashes.Values) + { + hash.BlockUpdate(input, inOff, len); + } + } + + public virtual int DoFinal(byte[] output, int outOff) + { + throw new InvalidOperationException("Use Fork() to get a definite IDigest"); + } + + public virtual void Reset() + { + if (mBuf != null) + { + mBuf.SetLength(0); + return; + } + + foreach (IDigest hash in mHashes.Values) + { + hash.Reset(); + } + } + + protected virtual void CheckStopBuffering() + { + if (mBuf != null && mHashes.Count <= BUFFERING_HASH_LIMIT) + { + foreach (IDigest hash in mHashes.Values) + { + mBuf.UpdateDigest(hash); + } + + this.mBuf = null; + } + } + + protected virtual void CheckTrackingHash(byte hashAlgorithm) + { + if (!mHashes.Contains(hashAlgorithm)) + { + IDigest hash = TlsUtilities.CreateHash(hashAlgorithm); + mHashes[hashAlgorithm] = hash; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DeferredHash.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DeferredHash.cs.meta new file mode 100644 index 0000000..10d5284 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DeferredHash.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6edcbec155e3c724cb33ec762fd7e889 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DigestInputBuffer.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DigestInputBuffer.cs new file mode 100644 index 0000000..acc6756 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DigestInputBuffer.cs @@ -0,0 +1,17 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Crypto.IO; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + internal class DigestInputBuffer + : MemoryStream + { + internal void UpdateDigest(IDigest d) + { + Streams.WriteBufTo(this, new DigestSink(d)); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DigestInputBuffer.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DigestInputBuffer.cs.meta new file mode 100644 index 0000000..448831f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DigestInputBuffer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0aa35c10ac959f54f93a8e737a50d64a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DigitallySigned.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DigitallySigned.cs new file mode 100644 index 0000000..8b7344f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DigitallySigned.cs @@ -0,0 +1,70 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class DigitallySigned + { + protected readonly SignatureAndHashAlgorithm mAlgorithm; + protected readonly byte[] mSignature; + + public DigitallySigned(SignatureAndHashAlgorithm algorithm, byte[] signature) + { + if (signature == null) + throw new ArgumentNullException("signature"); + + this.mAlgorithm = algorithm; + this.mSignature = signature; + } + + /** + * @return a {@link SignatureAndHashAlgorithm} (or null before TLS 1.2). + */ + public virtual SignatureAndHashAlgorithm Algorithm + { + get { return mAlgorithm; } + } + + public virtual byte[] Signature + { + get { return mSignature; } + } + + /** + * Encode this {@link DigitallySigned} to a {@link Stream}. + * + * @param output + * the {@link Stream} to encode to. + * @throws IOException + */ + public virtual void Encode(Stream output) + { + if (mAlgorithm != null) + { + mAlgorithm.Encode(output); + } + TlsUtilities.WriteOpaque16(mSignature, output); + } + + /** + * Parse a {@link DigitallySigned} from a {@link Stream}. + * + * @param context + * the {@link TlsContext} of the current connection. + * @param input + * the {@link Stream} to parse from. + * @return a {@link DigitallySigned} object. + * @throws IOException + */ + public static DigitallySigned Parse(TlsContext context, Stream input) + { + SignatureAndHashAlgorithm algorithm = null; + if (TlsUtilities.IsTlsV12(context)) + { + algorithm = SignatureAndHashAlgorithm.Parse(input); + } + byte[] signature = TlsUtilities.ReadOpaque16(input); + return new DigitallySigned(algorithm, signature); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DigitallySigned.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DigitallySigned.cs.meta new file mode 100644 index 0000000..898c2ba --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DigitallySigned.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d7b71b46e8d760848b1b626543ee3dc6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsClientProtocol.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsClientProtocol.cs new file mode 100644 index 0000000..fe6381d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsClientProtocol.cs @@ -0,0 +1,864 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class DtlsClientProtocol + : DtlsProtocol + { + public DtlsClientProtocol(SecureRandom secureRandom) + : base(secureRandom) + { + } + + public virtual DtlsTransport Connect(TlsClient client, DatagramTransport transport) + { + if (client == null) + throw new ArgumentNullException("client"); + if (transport == null) + throw new ArgumentNullException("transport"); + + SecurityParameters securityParameters = new SecurityParameters(); + securityParameters.entity = ConnectionEnd.client; + + ClientHandshakeState state = new ClientHandshakeState(); + state.client = client; + state.clientContext = new TlsClientContextImpl(mSecureRandom, securityParameters); + + securityParameters.clientRandom = TlsProtocol.CreateRandomBlock(client.ShouldUseGmtUnixTime(), + state.clientContext.NonceRandomGenerator); + + client.Init(state.clientContext); + + DtlsRecordLayer recordLayer = new DtlsRecordLayer(transport, state.clientContext, client, ContentType.handshake); + client.NotifyCloseHandle(recordLayer); + + TlsSession sessionToResume = state.client.GetSessionToResume(); + if (sessionToResume != null && sessionToResume.IsResumable) + { + SessionParameters sessionParameters = sessionToResume.ExportSessionParameters(); + if (sessionParameters != null && sessionParameters.IsExtendedMasterSecret) + { + state.tlsSession = sessionToResume; + state.sessionParameters = sessionParameters; + } + } + + try + { + return ClientHandshake(state, recordLayer); + } + catch (TlsFatalAlert fatalAlert) + { + AbortClientHandshake(state, recordLayer, fatalAlert.AlertDescription); + throw fatalAlert; + } + catch (IOException e) + { + AbortClientHandshake(state, recordLayer, AlertDescription.internal_error); + throw e; + } + catch (Exception e) + { + AbortClientHandshake(state, recordLayer, AlertDescription.internal_error); + throw new TlsFatalAlert(AlertDescription.internal_error, e); + } + finally + { + securityParameters.Clear(); + } + } + + internal virtual void AbortClientHandshake(ClientHandshakeState state, DtlsRecordLayer recordLayer, byte alertDescription) + { + recordLayer.Fail(alertDescription); + InvalidateSession(state); + } + + internal virtual DtlsTransport ClientHandshake(ClientHandshakeState state, DtlsRecordLayer recordLayer) + { + SecurityParameters securityParameters = state.clientContext.SecurityParameters; + DtlsReliableHandshake handshake = new DtlsReliableHandshake(state.clientContext, recordLayer, + state.client.GetHandshakeTimeoutMillis()); + + byte[] clientHelloBody = GenerateClientHello(state, state.client); + + recordLayer.SetWriteVersion(ProtocolVersion.DTLSv10); + + handshake.SendMessage(HandshakeType.client_hello, clientHelloBody); + + DtlsReliableHandshake.Message serverMessage = handshake.ReceiveMessage(); + + while (serverMessage.Type == HandshakeType.hello_verify_request) + { + ProtocolVersion recordLayerVersion = recordLayer.ReadVersion; + ProtocolVersion client_version = state.clientContext.ClientVersion; + + /* + * RFC 6347 4.2.1 DTLS 1.2 server implementations SHOULD use DTLS version 1.0 regardless of + * the version of TLS that is expected to be negotiated. DTLS 1.2 and 1.0 clients MUST use + * the version solely to indicate packet formatting (which is the same in both DTLS 1.2 and + * 1.0) and not as part of version negotiation. + */ + if (!recordLayerVersion.IsEqualOrEarlierVersionOf(client_version)) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + recordLayer.ReadVersion = null; + + byte[] cookie = ProcessHelloVerifyRequest(state, serverMessage.Body); + byte[] patched = PatchClientHelloWithCookie(clientHelloBody, cookie); + + handshake.ResetHandshakeMessagesDigest(); + handshake.SendMessage(HandshakeType.client_hello, patched); + + serverMessage = handshake.ReceiveMessage(); + } + + if (serverMessage.Type == HandshakeType.server_hello) + { + ProtocolVersion recordLayerVersion = recordLayer.ReadVersion; + ReportServerVersion(state, recordLayerVersion); + recordLayer.SetWriteVersion(recordLayerVersion); + + ProcessServerHello(state, serverMessage.Body); + } + else + { + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + handshake.NotifyHelloComplete(); + + ApplyMaxFragmentLengthExtension(recordLayer, securityParameters.maxFragmentLength); + + if (state.resumedSession) + { + securityParameters.masterSecret = Arrays.Clone(state.sessionParameters.MasterSecret); + recordLayer.InitPendingEpoch(state.client.GetCipher()); + + // NOTE: Calculated exclusive of the actual Finished message from the server + byte[] resExpectedServerVerifyData = TlsUtilities.CalculateVerifyData(state.clientContext, ExporterLabel.server_finished, + TlsProtocol.GetCurrentPrfHash(state.clientContext, handshake.HandshakeHash, null)); + ProcessFinished(handshake.ReceiveMessageBody(HandshakeType.finished), resExpectedServerVerifyData); + + // NOTE: Calculated exclusive of the Finished message itself + byte[] resClientVerifyData = TlsUtilities.CalculateVerifyData(state.clientContext, ExporterLabel.client_finished, + TlsProtocol.GetCurrentPrfHash(state.clientContext, handshake.HandshakeHash, null)); + handshake.SendMessage(HandshakeType.finished, resClientVerifyData); + + handshake.Finish(); + + state.clientContext.SetResumableSession(state.tlsSession); + + state.client.NotifyHandshakeComplete(); + + return new DtlsTransport(recordLayer); + } + + InvalidateSession(state); + + if (state.selectedSessionID.Length > 0) + { + state.tlsSession = new TlsSessionImpl(state.selectedSessionID, null); + } + + serverMessage = handshake.ReceiveMessage(); + + if (serverMessage.Type == HandshakeType.supplemental_data) + { + ProcessServerSupplementalData(state, serverMessage.Body); + serverMessage = handshake.ReceiveMessage(); + } + else + { + state.client.ProcessServerSupplementalData(null); + } + + state.keyExchange = state.client.GetKeyExchange(); + state.keyExchange.Init(state.clientContext); + + Certificate serverCertificate = null; + + if (serverMessage.Type == HandshakeType.certificate) + { + serverCertificate = ProcessServerCertificate(state, serverMessage.Body); + serverMessage = handshake.ReceiveMessage(); + } + else + { + // Okay, Certificate is optional + state.keyExchange.SkipServerCredentials(); + } + + // TODO[RFC 3546] Check whether empty certificates is possible, allowed, or excludes CertificateStatus + if (serverCertificate == null || serverCertificate.IsEmpty) + { + state.allowCertificateStatus = false; + } + + if (serverMessage.Type == HandshakeType.certificate_status) + { + ProcessCertificateStatus(state, serverMessage.Body); + serverMessage = handshake.ReceiveMessage(); + } + else + { + // Okay, CertificateStatus is optional + } + + if (serverMessage.Type == HandshakeType.server_key_exchange) + { + ProcessServerKeyExchange(state, serverMessage.Body); + serverMessage = handshake.ReceiveMessage(); + } + else + { + // Okay, ServerKeyExchange is optional + state.keyExchange.SkipServerKeyExchange(); + } + + if (serverMessage.Type == HandshakeType.certificate_request) + { + ProcessCertificateRequest(state, serverMessage.Body); + + /* + * TODO Give the client a chance to immediately select the CertificateVerify hash + * algorithm here to avoid tracking the other hash algorithms unnecessarily? + */ + TlsUtilities.TrackHashAlgorithms(handshake.HandshakeHash, + state.certificateRequest.SupportedSignatureAlgorithms); + + serverMessage = handshake.ReceiveMessage(); + } + else + { + // Okay, CertificateRequest is optional + } + + if (serverMessage.Type == HandshakeType.server_hello_done) + { + if (serverMessage.Body.Length != 0) + { + throw new TlsFatalAlert(AlertDescription.decode_error); + } + } + else + { + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + handshake.HandshakeHash.SealHashAlgorithms(); + + IList clientSupplementalData = state.client.GetClientSupplementalData(); + if (clientSupplementalData != null) + { + byte[] supplementalDataBody = GenerateSupplementalData(clientSupplementalData); + handshake.SendMessage(HandshakeType.supplemental_data, supplementalDataBody); + } + + if (state.certificateRequest != null) + { + state.clientCredentials = state.authentication.GetClientCredentials(state.certificateRequest); + + /* + * RFC 5246 If no suitable certificate is available, the client MUST send a certificate + * message containing no certificates. + * + * NOTE: In previous RFCs, this was SHOULD instead of MUST. + */ + Certificate clientCertificate = null; + if (state.clientCredentials != null) + { + clientCertificate = state.clientCredentials.Certificate; + } + if (clientCertificate == null) + { + clientCertificate = Certificate.EmptyChain; + } + + byte[] certificateBody = GenerateCertificate(clientCertificate); + handshake.SendMessage(HandshakeType.certificate, certificateBody); + } + + if (state.clientCredentials != null) + { + state.keyExchange.ProcessClientCredentials(state.clientCredentials); + } + else + { + state.keyExchange.SkipClientCredentials(); + } + + byte[] clientKeyExchangeBody = GenerateClientKeyExchange(state); + handshake.SendMessage(HandshakeType.client_key_exchange, clientKeyExchangeBody); + + TlsHandshakeHash prepareFinishHash = handshake.PrepareToFinish(); + securityParameters.sessionHash = TlsProtocol.GetCurrentPrfHash(state.clientContext, prepareFinishHash, null); + + TlsProtocol.EstablishMasterSecret(state.clientContext, state.keyExchange); + recordLayer.InitPendingEpoch(state.client.GetCipher()); + + if (state.clientCredentials != null && state.clientCredentials is TlsSignerCredentials) + { + TlsSignerCredentials signerCredentials = (TlsSignerCredentials)state.clientCredentials; + + /* + * RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm from TLS 1.2 + */ + SignatureAndHashAlgorithm signatureAndHashAlgorithm = TlsUtilities.GetSignatureAndHashAlgorithm( + state.clientContext, signerCredentials); + + byte[] hash; + if (signatureAndHashAlgorithm == null) + { + hash = securityParameters.SessionHash; + } + else + { + hash = prepareFinishHash.GetFinalHash(signatureAndHashAlgorithm.Hash); + } + + byte[] signature = signerCredentials.GenerateCertificateSignature(hash); + DigitallySigned certificateVerify = new DigitallySigned(signatureAndHashAlgorithm, signature); + byte[] certificateVerifyBody = GenerateCertificateVerify(state, certificateVerify); + handshake.SendMessage(HandshakeType.certificate_verify, certificateVerifyBody); + } + + // NOTE: Calculated exclusive of the Finished message itself + byte[] clientVerifyData = TlsUtilities.CalculateVerifyData(state.clientContext, ExporterLabel.client_finished, + TlsProtocol.GetCurrentPrfHash(state.clientContext, handshake.HandshakeHash, null)); + handshake.SendMessage(HandshakeType.finished, clientVerifyData); + + if (state.expectSessionTicket) + { + serverMessage = handshake.ReceiveMessage(); + if (serverMessage.Type == HandshakeType.session_ticket) + { + ProcessNewSessionTicket(state, serverMessage.Body); + } + else + { + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + } + + // NOTE: Calculated exclusive of the actual Finished message from the server + byte[] expectedServerVerifyData = TlsUtilities.CalculateVerifyData(state.clientContext, ExporterLabel.server_finished, + TlsProtocol.GetCurrentPrfHash(state.clientContext, handshake.HandshakeHash, null)); + ProcessFinished(handshake.ReceiveMessageBody(HandshakeType.finished), expectedServerVerifyData); + + handshake.Finish(); + + if (state.tlsSession != null) + { + state.sessionParameters = new SessionParameters.Builder() + .SetCipherSuite(securityParameters.CipherSuite) + .SetCompressionAlgorithm(securityParameters.CompressionAlgorithm) + .SetExtendedMasterSecret(securityParameters.IsExtendedMasterSecret) + .SetMasterSecret(securityParameters.MasterSecret) + .SetPeerCertificate(serverCertificate) + .SetPskIdentity(securityParameters.PskIdentity) + .SetSrpIdentity(securityParameters.SrpIdentity) + // TODO Consider filtering extensions that aren't relevant to resumed sessions + .SetServerExtensions(state.serverExtensions) + .Build(); + + state.tlsSession = TlsUtilities.ImportSession(state.tlsSession.SessionID, state.sessionParameters); + + state.clientContext.SetResumableSession(state.tlsSession); + } + + state.client.NotifyHandshakeComplete(); + + return new DtlsTransport(recordLayer); + } + + protected virtual byte[] GenerateCertificateVerify(ClientHandshakeState state, DigitallySigned certificateVerify) + { + MemoryStream buf = new MemoryStream(); + certificateVerify.Encode(buf); + return buf.ToArray(); + } + + protected virtual byte[] GenerateClientHello(ClientHandshakeState state, TlsClient client) + { + ProtocolVersion client_version = client.ClientVersion; + if (!client_version.IsDtls) + throw new TlsFatalAlert(AlertDescription.internal_error); + + TlsClientContextImpl context = state.clientContext; + + context.SetClientVersion(client_version); + + SecurityParameters securityParameters = context.SecurityParameters; + + // Session ID + byte[] session_id = TlsUtilities.EmptyBytes; + if (state.tlsSession != null) + { + session_id = state.tlsSession.SessionID; + if (session_id == null || session_id.Length > 32) + { + session_id = TlsUtilities.EmptyBytes; + } + } + + bool fallback = client.IsFallback; + + state.offeredCipherSuites = client.GetCipherSuites(); + + if (session_id.Length > 0 && state.sessionParameters != null) + { + if (!state.sessionParameters.IsExtendedMasterSecret + || !Arrays.Contains(state.offeredCipherSuites, state.sessionParameters.CipherSuite) + || CompressionMethod.cls_null != state.sessionParameters.CompressionAlgorithm) + { + session_id = TlsUtilities.EmptyBytes; + } + } + + state.clientExtensions = TlsExtensionsUtilities.EnsureExtensionsInitialised(client.GetClientExtensions()); + + TlsExtensionsUtilities.AddExtendedMasterSecretExtension(state.clientExtensions); + + MemoryStream buf = new MemoryStream(); + + TlsUtilities.WriteVersion(client_version, buf); + + buf.Write(securityParameters.ClientRandom, 0, securityParameters.ClientRandom.Length); + + TlsUtilities.WriteOpaque8(session_id, buf); + + // Cookie + TlsUtilities.WriteOpaque8(TlsUtilities.EmptyBytes, buf); + + // Cipher Suites (and SCSV) + { + /* + * RFC 5746 3.4. The client MUST include either an empty "renegotiation_info" extension, + * or the TLS_EMPTY_RENEGOTIATION_INFO_SCSV signaling cipher suite value in the + * ClientHello. Including both is NOT RECOMMENDED. + */ + byte[] renegExtData = TlsUtilities.GetExtensionData(state.clientExtensions, ExtensionType.renegotiation_info); + bool noRenegExt = (null == renegExtData); + + bool noRenegSCSV = !Arrays.Contains(state.offeredCipherSuites, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV); + + if (noRenegExt && noRenegSCSV) + { + // TODO Consider whether to default to a client extension instead + state.offeredCipherSuites = Arrays.Append(state.offeredCipherSuites, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV); + } + + /* + * RFC 7507 4. If a client sends a ClientHello.client_version containing a lower value + * than the latest (highest-valued) version supported by the client, it SHOULD include + * the TLS_FALLBACK_SCSV cipher suite value in ClientHello.cipher_suites [..]. (The + * client SHOULD put TLS_FALLBACK_SCSV after all cipher suites that it actually intends + * to negotiate.) + */ + if (fallback && !Arrays.Contains(state.offeredCipherSuites, CipherSuite.TLS_FALLBACK_SCSV)) + { + state.offeredCipherSuites = Arrays.Append(state.offeredCipherSuites, CipherSuite.TLS_FALLBACK_SCSV); + } + + TlsUtilities.WriteUint16ArrayWithUint16Length(state.offeredCipherSuites, buf); + } + + TlsUtilities.WriteUint8ArrayWithUint8Length(new byte[]{ CompressionMethod.cls_null }, buf); + + TlsProtocol.WriteExtensions(buf, state.clientExtensions); + + return buf.ToArray(); + } + + protected virtual byte[] GenerateClientKeyExchange(ClientHandshakeState state) + { + MemoryStream buf = new MemoryStream(); + state.keyExchange.GenerateClientKeyExchange(buf); + return buf.ToArray(); + } + + protected virtual void InvalidateSession(ClientHandshakeState state) + { + if (state.sessionParameters != null) + { + state.sessionParameters.Clear(); + state.sessionParameters = null; + } + + if (state.tlsSession != null) + { + state.tlsSession.Invalidate(); + state.tlsSession = null; + } + } + + protected virtual void ProcessCertificateRequest(ClientHandshakeState state, byte[] body) + { + if (state.authentication == null) + { + /* + * RFC 2246 7.4.4. It is a fatal handshake_failure alert for an anonymous server to + * request client identification. + */ + throw new TlsFatalAlert(AlertDescription.handshake_failure); + } + + MemoryStream buf = new MemoryStream(body, false); + + state.certificateRequest = CertificateRequest.Parse(state.clientContext, buf); + + TlsProtocol.AssertEmpty(buf); + + state.keyExchange.ValidateCertificateRequest(state.certificateRequest); + } + + protected virtual void ProcessCertificateStatus(ClientHandshakeState state, byte[] body) + { + if (!state.allowCertificateStatus) + { + /* + * RFC 3546 3.6. If a server returns a "CertificateStatus" message, then the + * server MUST have included an extension of type "status_request" with empty + * "extension_data" in the extended server hello.. + */ + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + MemoryStream buf = new MemoryStream(body, false); + + state.certificateStatus = CertificateStatus.Parse(buf); + + TlsProtocol.AssertEmpty(buf); + + // TODO[RFC 3546] Figure out how to provide this to the client/authentication. + } + + protected virtual byte[] ProcessHelloVerifyRequest(ClientHandshakeState state, byte[] body) + { + MemoryStream buf = new MemoryStream(body, false); + + ProtocolVersion server_version = TlsUtilities.ReadVersion(buf); + byte[] cookie = TlsUtilities.ReadOpaque8(buf); + + TlsProtocol.AssertEmpty(buf); + + // TODO Seems this behaviour is not yet in line with OpenSSL for DTLS 1.2 + // reportServerVersion(state, server_version); + if (!server_version.IsEqualOrEarlierVersionOf(state.clientContext.ClientVersion)) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + /* + * RFC 6347 This specification increases the cookie size limit to 255 bytes for greater + * future flexibility. The limit remains 32 for previous versions of DTLS. + */ + if (!ProtocolVersion.DTLSv12.IsEqualOrEarlierVersionOf(server_version) && cookie.Length > 32) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + return cookie; + } + + protected virtual void ProcessNewSessionTicket(ClientHandshakeState state, byte[] body) + { + MemoryStream buf = new MemoryStream(body, false); + + NewSessionTicket newSessionTicket = NewSessionTicket.Parse(buf); + + TlsProtocol.AssertEmpty(buf); + + state.client.NotifyNewSessionTicket(newSessionTicket); + } + + protected virtual Certificate ProcessServerCertificate(ClientHandshakeState state, byte[] body) + { + MemoryStream buf = new MemoryStream(body, false); + + Certificate serverCertificate = Certificate.Parse(buf); + + TlsProtocol.AssertEmpty(buf); + + state.keyExchange.ProcessServerCertificate(serverCertificate); + state.authentication = state.client.GetAuthentication(); + state.authentication.NotifyServerCertificate(serverCertificate); + + return serverCertificate; + } + + protected virtual void ProcessServerHello(ClientHandshakeState state, byte[] body) + { + SecurityParameters securityParameters = state.clientContext.SecurityParameters; + + MemoryStream buf = new MemoryStream(body, false); + + { + ProtocolVersion server_version = TlsUtilities.ReadVersion(buf); + ReportServerVersion(state, server_version); + } + + securityParameters.serverRandom = TlsUtilities.ReadFully(32, buf); + + state.selectedSessionID = TlsUtilities.ReadOpaque8(buf); + if (state.selectedSessionID.Length > 32) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + state.client.NotifySessionID(state.selectedSessionID); + state.resumedSession = state.selectedSessionID.Length > 0 && state.tlsSession != null + && Arrays.AreEqual(state.selectedSessionID, state.tlsSession.SessionID); + + int selectedCipherSuite = TlsUtilities.ReadUint16(buf); + if (!Arrays.Contains(state.offeredCipherSuites, selectedCipherSuite) + || selectedCipherSuite == CipherSuite.TLS_NULL_WITH_NULL_NULL + || CipherSuite.IsScsv(selectedCipherSuite) + || !TlsUtilities.IsValidCipherSuiteForVersion(selectedCipherSuite, state.clientContext.ServerVersion)) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + ValidateSelectedCipherSuite(selectedCipherSuite, AlertDescription.illegal_parameter); + state.client.NotifySelectedCipherSuite(selectedCipherSuite); + + byte selectedCompressionMethod = TlsUtilities.ReadUint8(buf); + if (CompressionMethod.cls_null != selectedCompressionMethod) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + state.client.NotifySelectedCompressionMethod(selectedCompressionMethod); + + /* + * RFC3546 2.2 The extended server hello message format MAY be sent in place of the server + * hello message when the client has requested extended functionality via the extended + * client hello message specified in Section 2.1. ... Note that the extended server hello + * message is only sent in response to an extended client hello message. This prevents the + * possibility that the extended server hello message could "break" existing TLS 1.0 + * clients. + */ + + /* + * TODO RFC 3546 2.3 If [...] the older session is resumed, then the server MUST ignore + * extensions appearing in the client hello, and send a server hello containing no + * extensions. + */ + + // Integer -> byte[] + state.serverExtensions = TlsProtocol.ReadExtensions(buf); + + /* + * RFC 7627 4. Clients and servers SHOULD NOT accept handshakes that do not use the extended + * master secret [..]. (and see 5.2, 5.3) + */ + securityParameters.extendedMasterSecret = TlsExtensionsUtilities.HasExtendedMasterSecretExtension(state.serverExtensions); + + if (!securityParameters.IsExtendedMasterSecret + && (state.resumedSession || state.client.RequiresExtendedMasterSecret())) + { + throw new TlsFatalAlert(AlertDescription.handshake_failure); + } + + /* + * RFC 3546 2.2 Note that the extended server hello message is only sent in response to an + * extended client hello message. However, see RFC 5746 exception below. We always include + * the SCSV, so an Extended Server Hello is always allowed. + */ + if (state.serverExtensions != null) + { + foreach (int extType in state.serverExtensions.Keys) + { + /* + * RFC 5746 3.6. Note that sending a "renegotiation_info" extension in response to a + * ClientHello containing only the SCSV is an explicit exception to the prohibition + * in RFC 5246, Section 7.4.1.4, on the server sending unsolicited extensions and is + * only allowed because the client is signaling its willingness to receive the + * extension via the TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV. + */ + if (extType == ExtensionType.renegotiation_info) + continue; + + /* + * RFC 5246 7.4.1.4 An extension type MUST NOT appear in the ServerHello unless the + * same extension type appeared in the corresponding ClientHello. If a client + * receives an extension type in ServerHello that it did not request in the + * associated ClientHello, it MUST abort the handshake with an unsupported_extension + * fatal alert. + */ + if (null == TlsUtilities.GetExtensionData(state.clientExtensions, extType)) + throw new TlsFatalAlert(AlertDescription.unsupported_extension); + + /* + * RFC 3546 2.3. If [...] the older session is resumed, then the server MUST ignore + * extensions appearing in the client hello, and send a server hello containing no + * extensions[.] + */ + if (state.resumedSession) + { + // TODO[compat-gnutls] GnuTLS test server sends server extensions e.g. ec_point_formats + // TODO[compat-openssl] OpenSSL test server sends server extensions e.g. ec_point_formats + // TODO[compat-polarssl] PolarSSL test server sends server extensions e.g. ec_point_formats + //throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + } + } + + /* + * RFC 5746 3.4. Client Behavior: Initial Handshake + */ + { + /* + * When a ServerHello is received, the client MUST check if it includes the + * "renegotiation_info" extension: + */ + byte[] renegExtData = TlsUtilities.GetExtensionData(state.serverExtensions, ExtensionType.renegotiation_info); + if (renegExtData != null) + { + /* + * If the extension is present, set the secure_renegotiation flag to TRUE. The + * client MUST then verify that the length of the "renegotiated_connection" + * field is zero, and if it is not, MUST abort the handshake (by sending a fatal + * handshake_failure alert). + */ + state.secure_renegotiation = true; + + if (!Arrays.ConstantTimeAreEqual(renegExtData, TlsProtocol.CreateRenegotiationInfo(TlsUtilities.EmptyBytes))) + throw new TlsFatalAlert(AlertDescription.handshake_failure); + } + } + + // TODO[compat-gnutls] GnuTLS test server fails to send renegotiation_info extension when resuming + state.client.NotifySecureRenegotiation(state.secure_renegotiation); + + IDictionary sessionClientExtensions = state.clientExtensions, sessionServerExtensions = state.serverExtensions; + if (state.resumedSession) + { + if (selectedCipherSuite != state.sessionParameters.CipherSuite + || selectedCompressionMethod != state.sessionParameters.CompressionAlgorithm) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + sessionClientExtensions = null; + sessionServerExtensions = state.sessionParameters.ReadServerExtensions(); + } + + securityParameters.cipherSuite = selectedCipherSuite; + securityParameters.compressionAlgorithm = selectedCompressionMethod; + + if (sessionServerExtensions != null && sessionServerExtensions.Count > 0) + { + { + /* + * RFC 7366 3. If a server receives an encrypt-then-MAC request extension from a client + * and then selects a stream or Authenticated Encryption with Associated Data (AEAD) + * ciphersuite, it MUST NOT send an encrypt-then-MAC response extension back to the + * client. + */ + bool serverSentEncryptThenMAC = TlsExtensionsUtilities.HasEncryptThenMacExtension(sessionServerExtensions); + if (serverSentEncryptThenMAC && !TlsUtilities.IsBlockCipherSuite(securityParameters.CipherSuite)) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + securityParameters.encryptThenMac = serverSentEncryptThenMAC; + } + + securityParameters.maxFragmentLength = EvaluateMaxFragmentLengthExtension(state.resumedSession, + sessionClientExtensions, sessionServerExtensions, AlertDescription.illegal_parameter); + + securityParameters.truncatedHMac = TlsExtensionsUtilities.HasTruncatedHMacExtension(sessionServerExtensions); + + /* + * TODO It's surprising that there's no provision to allow a 'fresh' CertificateStatus to be + * sent in a session resumption handshake. + */ + state.allowCertificateStatus = !state.resumedSession + && TlsUtilities.HasExpectedEmptyExtensionData(sessionServerExtensions, ExtensionType.status_request, + AlertDescription.illegal_parameter); + + state.expectSessionTicket = !state.resumedSession + && TlsUtilities.HasExpectedEmptyExtensionData(sessionServerExtensions, ExtensionType.session_ticket, + AlertDescription.illegal_parameter); + } + + if (sessionClientExtensions != null) + { + state.client.ProcessServerExtensions(sessionServerExtensions); + } + + securityParameters.prfAlgorithm = TlsProtocol.GetPrfAlgorithm(state.clientContext, + securityParameters.CipherSuite); + + /* + * RFC 5246 7.4.9. Any cipher suite which does not explicitly specify verify_data_length has + * a verify_data_length equal to 12. This includes all existing cipher suites. + */ + securityParameters.verifyDataLength = 12; + } + + protected virtual void ProcessServerKeyExchange(ClientHandshakeState state, byte[] body) + { + MemoryStream buf = new MemoryStream(body, false); + + state.keyExchange.ProcessServerKeyExchange(buf); + + TlsProtocol.AssertEmpty(buf); + } + + protected virtual void ProcessServerSupplementalData(ClientHandshakeState state, byte[] body) + { + MemoryStream buf = new MemoryStream(body, false); + IList serverSupplementalData = TlsProtocol.ReadSupplementalDataMessage(buf); + state.client.ProcessServerSupplementalData(serverSupplementalData); + } + + protected virtual void ReportServerVersion(ClientHandshakeState state, ProtocolVersion server_version) + { + TlsClientContextImpl clientContext = state.clientContext; + ProtocolVersion currentServerVersion = clientContext.ServerVersion; + if (null == currentServerVersion) + { + clientContext.SetServerVersion(server_version); + state.client.NotifyServerVersion(server_version); + } + else if (!currentServerVersion.Equals(server_version)) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + } + + protected static byte[] PatchClientHelloWithCookie(byte[] clientHelloBody, byte[] cookie) + { + int sessionIDPos = 34; + int sessionIDLength = TlsUtilities.ReadUint8(clientHelloBody, sessionIDPos); + + int cookieLengthPos = sessionIDPos + 1 + sessionIDLength; + int cookiePos = cookieLengthPos + 1; + + byte[] patched = new byte[clientHelloBody.Length + cookie.Length]; + Array.Copy(clientHelloBody, 0, patched, 0, cookieLengthPos); + TlsUtilities.CheckUint8(cookie.Length); + TlsUtilities.WriteUint8((byte)cookie.Length, patched, cookieLengthPos); + Array.Copy(cookie, 0, patched, cookiePos, cookie.Length); + Array.Copy(clientHelloBody, cookiePos, patched, cookiePos + cookie.Length, clientHelloBody.Length - cookiePos); + + return patched; + } + + protected internal class ClientHandshakeState + { + internal TlsClient client = null; + internal TlsClientContextImpl clientContext = null; + internal TlsSession tlsSession = null; + internal SessionParameters sessionParameters = null; + internal SessionParameters.Builder sessionParametersBuilder = null; + internal int[] offeredCipherSuites = null; + internal IDictionary clientExtensions = null; + internal IDictionary serverExtensions = null; + internal byte[] selectedSessionID = null; + internal bool resumedSession = false; + internal bool secure_renegotiation = false; + internal bool allowCertificateStatus = false; + internal bool expectSessionTicket = false; + internal TlsKeyExchange keyExchange = null; + internal TlsAuthentication authentication = null; + internal CertificateStatus certificateStatus = null; + internal CertificateRequest certificateRequest = null; + internal TlsCredentials clientCredentials = null; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsClientProtocol.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsClientProtocol.cs.meta new file mode 100644 index 0000000..9ddfaa8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsClientProtocol.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f15772dfb7279ee4497e3866badaa749 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsEpoch.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsEpoch.cs new file mode 100644 index 0000000..af14035 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsEpoch.cs @@ -0,0 +1,56 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + internal class DtlsEpoch + { + private readonly DtlsReplayWindow mReplayWindow = new DtlsReplayWindow(); + + private readonly int mEpoch; + private readonly TlsCipher mCipher; + + private long mSequenceNumber = 0; + + internal DtlsEpoch(int epoch, TlsCipher cipher) + { + if (epoch < 0) + throw new ArgumentException("must be >= 0", "epoch"); + if (cipher == null) + throw new ArgumentNullException("cipher"); + + this.mEpoch = epoch; + this.mCipher = cipher; + } + + internal long AllocateSequenceNumber() + { + lock (this) + { + if (mSequenceNumber >= (1L << 48)) + throw new TlsFatalAlert(AlertDescription.internal_error); + + return mSequenceNumber++; + } + } + + internal TlsCipher Cipher + { + get { return mCipher; } + } + + internal int Epoch + { + get { return mEpoch; } + } + + internal DtlsReplayWindow ReplayWindow + { + get { return mReplayWindow; } + } + + internal long SequenceNumber + { + get { lock(this) return mSequenceNumber; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsEpoch.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsEpoch.cs.meta new file mode 100644 index 0000000..e66c3b1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsEpoch.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 14d11ff7511be5743a618adba4b47437 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsHandshakeRetransmit.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsHandshakeRetransmit.cs new file mode 100644 index 0000000..8bfae78 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsHandshakeRetransmit.cs @@ -0,0 +1,11 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + interface DtlsHandshakeRetransmit + { + /// + void ReceivedHandshakeRecord(int epoch, byte[] buf, int off, int len); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsHandshakeRetransmit.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsHandshakeRetransmit.cs.meta new file mode 100644 index 0000000..e6f631f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsHandshakeRetransmit.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b6b13a9b0af64b94dbfaf2a75ce4b516 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsProtocol.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsProtocol.cs new file mode 100644 index 0000000..e4ebd43 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsProtocol.cs @@ -0,0 +1,92 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class DtlsProtocol + { + protected readonly SecureRandom mSecureRandom; + + protected DtlsProtocol(SecureRandom secureRandom) + { + if (secureRandom == null) + throw new ArgumentNullException("secureRandom"); + + this.mSecureRandom = secureRandom; + } + + /// + protected virtual void ProcessFinished(byte[] body, byte[] expected_verify_data) + { + MemoryStream buf = new MemoryStream(body, false); + + byte[] verify_data = TlsUtilities.ReadFully(expected_verify_data.Length, buf); + + TlsProtocol.AssertEmpty(buf); + + if (!Arrays.ConstantTimeAreEqual(expected_verify_data, verify_data)) + throw new TlsFatalAlert(AlertDescription.handshake_failure); + } + + /// + internal static void ApplyMaxFragmentLengthExtension(DtlsRecordLayer recordLayer, short maxFragmentLength) + { + if (maxFragmentLength >= 0) + { + if (!MaxFragmentLength.IsValid((byte)maxFragmentLength)) + throw new TlsFatalAlert(AlertDescription.internal_error); + + int plainTextLimit = 1 << (8 + maxFragmentLength); + recordLayer.SetPlaintextLimit(plainTextLimit); + } + } + + /// + protected static short EvaluateMaxFragmentLengthExtension(bool resumedSession, IDictionary clientExtensions, + IDictionary serverExtensions, byte alertDescription) + { + short maxFragmentLength = TlsExtensionsUtilities.GetMaxFragmentLengthExtension(serverExtensions); + if (maxFragmentLength >= 0) + { + if (!MaxFragmentLength.IsValid((byte)maxFragmentLength) + || (!resumedSession && maxFragmentLength != TlsExtensionsUtilities + .GetMaxFragmentLengthExtension(clientExtensions))) + { + throw new TlsFatalAlert(alertDescription); + } + } + return maxFragmentLength; + } + + /// + protected static byte[] GenerateCertificate(Certificate certificate) + { + MemoryStream buf = new MemoryStream(); + certificate.Encode(buf); + return buf.ToArray(); + } + + /// + protected static byte[] GenerateSupplementalData(IList supplementalData) + { + MemoryStream buf = new MemoryStream(); + TlsProtocol.WriteSupplementalData(buf, supplementalData); + return buf.ToArray(); + } + + /// + protected static void ValidateSelectedCipherSuite(int selectedCipherSuite, byte alertDescription) + { + switch (TlsUtilities.GetEncryptionAlgorithm(selectedCipherSuite)) + { + case EncryptionAlgorithm.RC4_40: + case EncryptionAlgorithm.RC4_128: + throw new TlsFatalAlert(alertDescription); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsProtocol.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsProtocol.cs.meta new file mode 100644 index 0000000..c22e279 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsProtocol.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6e8c5495d2ebe5a44b39abed40593b6d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsReassembler.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsReassembler.cs new file mode 100644 index 0000000..11fe609 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsReassembler.cs @@ -0,0 +1,125 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + class DtlsReassembler + { + private readonly byte mMsgType; + private readonly byte[] mBody; + + private readonly IList mMissing = Platform.CreateArrayList(); + + internal DtlsReassembler(byte msg_type, int length) + { + this.mMsgType = msg_type; + this.mBody = new byte[length]; + this.mMissing.Add(new Range(0, length)); + } + + internal byte MsgType + { + get { return mMsgType; } + } + + internal byte[] GetBodyIfComplete() + { + return mMissing.Count == 0 ? mBody : null; + } + + internal void ContributeFragment(byte msg_type, int length, byte[] buf, int off, int fragment_offset, + int fragment_length) + { + int fragment_end = fragment_offset + fragment_length; + + if (this.mMsgType != msg_type || this.mBody.Length != length || fragment_end > length) + { + return; + } + + if (fragment_length == 0) + { + // NOTE: Empty messages still require an empty fragment to complete it + if (fragment_offset == 0 && mMissing.Count > 0) + { + Range firstRange = (Range)mMissing[0]; + if (firstRange.End == 0) + { + mMissing.RemoveAt(0); + } + } + return; + } + + for (int i = 0; i < mMissing.Count; ++i) + { + Range range = (Range)mMissing[i]; + if (range.Start >= fragment_end) + { + break; + } + if (range.End > fragment_offset) + { + + int copyStart = System.Math.Max(range.Start, fragment_offset); + int copyEnd = System.Math.Min(range.End, fragment_end); + int copyLength = copyEnd - copyStart; + + Array.Copy(buf, off + copyStart - fragment_offset, mBody, copyStart, + copyLength); + + if (copyStart == range.Start) + { + if (copyEnd == range.End) + { + mMissing.RemoveAt(i--); + } + else + { + range.Start = copyEnd; + } + } + else + { + if (copyEnd != range.End) + { + mMissing.Insert(++i, new Range(copyEnd, range.End)); + } + range.End = copyStart; + } + } + } + } + + internal void Reset() + { + this.mMissing.Clear(); + this.mMissing.Add(new Range(0, mBody.Length)); + } + + private class Range + { + private int mStart, mEnd; + + internal Range(int start, int end) + { + this.mStart = start; + this.mEnd = end; + } + + public int Start + { + get { return mStart; } + set { this.mStart = value; } + } + + public int End + { + get { return mEnd; } + set { this.mEnd = value; } + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsReassembler.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsReassembler.cs.meta new file mode 100644 index 0000000..5586fc1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsReassembler.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fc4a20ee7ad6f3c499e17f2569888d83 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsRecordLayer.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsRecordLayer.cs new file mode 100644 index 0000000..69870dd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsRecordLayer.cs @@ -0,0 +1,585 @@ +using System; +using System.IO; +#if !PORTABLE || DOTNET +using System.Net.Sockets; +#endif + +using Org.BouncyCastle.Utilities.Date; + +namespace Org.BouncyCastle.Crypto.Tls +{ + internal class DtlsRecordLayer + : DatagramTransport + { + private const int RECORD_HEADER_LENGTH = 13; + private const int MAX_FRAGMENT_LENGTH = 1 << 14; + private const long TCP_MSL = 1000L * 60 * 2; + private const long RETRANSMIT_TIMEOUT = TCP_MSL * 2; + + private static void SendDatagram(DatagramTransport sender, byte[] buf, int off, int len) + { + //try + //{ + // sender.Send(buf, off, len); + //} + //catch (InterruptedIOException e) + //{ + // e.bytesTransferred = 0; + // throw e; + //} + + sender.Send(buf, off, len); + } + + private readonly DatagramTransport mTransport; + private readonly TlsContext mContext; + private readonly TlsPeer mPeer; + + private readonly ByteQueue mRecordQueue = new ByteQueue(); + + private volatile bool mClosed = false; + private volatile bool mFailed = false; + private volatile ProtocolVersion mReadVersion = null, mWriteVersion = null; + private volatile bool mInHandshake; + private volatile int mPlaintextLimit; + private DtlsEpoch mCurrentEpoch, mPendingEpoch; + private DtlsEpoch mReadEpoch, mWriteEpoch; + + private DtlsHandshakeRetransmit mRetransmit = null; + private DtlsEpoch mRetransmitEpoch = null; + private Timeout mRetransmitTimeout = null; + + internal DtlsRecordLayer(DatagramTransport transport, TlsContext context, TlsPeer peer, byte contentType) + { + this.mTransport = transport; + this.mContext = context; + this.mPeer = peer; + + this.mInHandshake = true; + + this.mCurrentEpoch = new DtlsEpoch(0, new TlsNullCipher(context)); + this.mPendingEpoch = null; + this.mReadEpoch = mCurrentEpoch; + this.mWriteEpoch = mCurrentEpoch; + + SetPlaintextLimit(MAX_FRAGMENT_LENGTH); + } + + internal bool IsClosed + { + get { return mClosed; } + } + + internal virtual void SetPlaintextLimit(int plaintextLimit) + { + this.mPlaintextLimit = plaintextLimit; + } + + internal virtual int ReadEpoch + { + get { return mReadEpoch.Epoch; } + } + + internal virtual ProtocolVersion ReadVersion + { + get { return mReadVersion; } + set { this.mReadVersion = value; } + } + + internal virtual void SetWriteVersion(ProtocolVersion writeVersion) + { + this.mWriteVersion = writeVersion; + } + + internal virtual void InitPendingEpoch(TlsCipher pendingCipher) + { + if (mPendingEpoch != null) + throw new InvalidOperationException(); + + /* + * TODO "In order to ensure that any given sequence/epoch pair is unique, implementations + * MUST NOT allow the same epoch value to be reused within two times the TCP maximum segment + * lifetime." + */ + + // TODO Check for overflow + this.mPendingEpoch = new DtlsEpoch(mWriteEpoch.Epoch + 1, pendingCipher); + } + + internal virtual void HandshakeSuccessful(DtlsHandshakeRetransmit retransmit) + { + if (mReadEpoch == mCurrentEpoch || mWriteEpoch == mCurrentEpoch) + { + // TODO + throw new InvalidOperationException(); + } + + if (retransmit != null) + { + this.mRetransmit = retransmit; + this.mRetransmitEpoch = mCurrentEpoch; + this.mRetransmitTimeout = new Timeout(RETRANSMIT_TIMEOUT); + } + + this.mInHandshake = false; + this.mCurrentEpoch = mPendingEpoch; + this.mPendingEpoch = null; + } + + internal virtual void ResetWriteEpoch() + { + if (mRetransmitEpoch != null) + { + this.mWriteEpoch = mRetransmitEpoch; + } + else + { + this.mWriteEpoch = mCurrentEpoch; + } + } + + public virtual int GetReceiveLimit() + { + return System.Math.Min(this.mPlaintextLimit, + mReadEpoch.Cipher.GetPlaintextLimit(mTransport.GetReceiveLimit() - RECORD_HEADER_LENGTH)); + } + + public virtual int GetSendLimit() + { + return System.Math.Min(this.mPlaintextLimit, + mWriteEpoch.Cipher.GetPlaintextLimit(mTransport.GetSendLimit() - RECORD_HEADER_LENGTH)); + } + + public virtual int Receive(byte[] buf, int off, int len, int waitMillis) + { + long currentTimeMillis = DateTimeUtilities.CurrentUnixMs(); + + Timeout timeout = Timeout.ForWaitMillis(waitMillis, currentTimeMillis); + byte[] record = null; + + while (waitMillis >= 0) + { + if (mRetransmitTimeout != null && mRetransmitTimeout.RemainingMillis(currentTimeMillis) < 1) + { + mRetransmit = null; + mRetransmitEpoch = null; + mRetransmitTimeout = null; + } + + int receiveLimit = System.Math.Min(len, GetReceiveLimit()) + RECORD_HEADER_LENGTH; + if (record == null || record.Length < receiveLimit) + { + record = new byte[receiveLimit]; + } + + int received = ReceiveRecord(record, 0, receiveLimit, waitMillis); + int processed = ProcessRecord(received, record, buf, off); + if (processed >= 0) + { + return processed; + } + + currentTimeMillis = DateTimeUtilities.CurrentUnixMs(); + waitMillis = Timeout.GetWaitMillis(timeout, currentTimeMillis); + } + + return -1; + } + + /// + public virtual void Send(byte[] buf, int off, int len) + { + byte contentType = ContentType.application_data; + + if (this.mInHandshake || this.mWriteEpoch == this.mRetransmitEpoch) + { + contentType = ContentType.handshake; + + byte handshakeType = TlsUtilities.ReadUint8(buf, off); + if (handshakeType == HandshakeType.finished) + { + DtlsEpoch nextEpoch = null; + if (this.mInHandshake) + { + nextEpoch = mPendingEpoch; + } + else if (this.mWriteEpoch == this.mRetransmitEpoch) + { + nextEpoch = mCurrentEpoch; + } + + if (nextEpoch == null) + { + // TODO + throw new InvalidOperationException(); + } + + // Implicitly send change_cipher_spec and change to pending cipher state + + // TODO Send change_cipher_spec and finished records in single datagram? + byte[] data = new byte[]{ 1 }; + SendRecord(ContentType.change_cipher_spec, data, 0, data.Length); + + mWriteEpoch = nextEpoch; + } + } + + SendRecord(contentType, buf, off, len); + } + + public virtual void Close() + { + if (!mClosed) + { + if (mInHandshake) + { + Warn(AlertDescription.user_canceled, "User canceled handshake"); + } + CloseTransport(); + } + } + + internal virtual void Failed() + { + if (!mClosed) + { + mFailed = true; + + CloseTransport(); + } + } + + internal virtual void Fail(byte alertDescription) + { + if (!mClosed) + { + try + { + RaiseAlert(AlertLevel.fatal, alertDescription, null, null); + } + catch (Exception) + { + // Ignore + } + + mFailed = true; + + CloseTransport(); + } + } + + internal virtual void Warn(byte alertDescription, string message) + { + RaiseAlert(AlertLevel.warning, alertDescription, message, null); + } + + private void CloseTransport() + { + if (!mClosed) + { + /* + * RFC 5246 7.2.1. Unless some other fatal alert has been transmitted, each party is + * required to send a close_notify alert before closing the write side of the + * connection. The other party MUST respond with a close_notify alert of its own and + * close down the connection immediately, discarding any pending writes. + */ + + try + { + if (!mFailed) + { + Warn(AlertDescription.close_notify, null); + } + mTransport.Close(); + } + catch (Exception) + { + // Ignore + } + + mClosed = true; + } + } + + private void RaiseAlert(byte alertLevel, byte alertDescription, string message, Exception cause) + { + mPeer.NotifyAlertRaised(alertLevel, alertDescription, message, cause); + + byte[] error = new byte[2]; + error[0] = (byte)alertLevel; + error[1] = (byte)alertDescription; + + SendRecord(ContentType.alert, error, 0, 2); + } + + private int ReceiveDatagram(byte[] buf, int off, int len, int waitMillis) + { + try + { + return mTransport.Receive(buf, off, len, waitMillis); + } + catch (TlsTimeoutException) + { + return -1; + } +#if !PORTABLE || DOTNET + catch (SocketException e) + { + if (TlsUtilities.IsTimeout(e)) + return -1; + + throw e; + } +#endif + //catch (InterruptedIOException e) + //{ + // e.bytesTransferred = 0; + // throw e; + //} + } + + private int ProcessRecord(int received, byte[] record, byte[] buf, int off) + { + // NOTE: received < 0 (timeout) is covered by this first case + if (received < RECORD_HEADER_LENGTH) + { + return -1; + } + int length = TlsUtilities.ReadUint16(record, 11); + if (received != (length + RECORD_HEADER_LENGTH)) + { + return -1; + } + + byte type = TlsUtilities.ReadUint8(record, 0); + + switch (type) + { + case ContentType.alert: + case ContentType.application_data: + case ContentType.change_cipher_spec: + case ContentType.handshake: + case ContentType.heartbeat: + break; + default: + return -1; + } + + int epoch = TlsUtilities.ReadUint16(record, 3); + + DtlsEpoch recordEpoch = null; + if (epoch == mReadEpoch.Epoch) + { + recordEpoch = mReadEpoch; + } + else if (type == ContentType.handshake && mRetransmitEpoch != null + && epoch == mRetransmitEpoch.Epoch) + { + recordEpoch = mRetransmitEpoch; + } + + if (recordEpoch == null) + { + return -1; + } + + long seq = TlsUtilities.ReadUint48(record, 5); + if (recordEpoch.ReplayWindow.ShouldDiscard(seq)) + { + return -1; + } + + ProtocolVersion version = TlsUtilities.ReadVersion(record, 1); + if (!version.IsDtls) + { + return -1; + } + + if (mReadVersion != null && !mReadVersion.Equals(version)) + { + return -1; + } + + byte[] plaintext = recordEpoch.Cipher.DecodeCiphertext( + GetMacSequenceNumber(recordEpoch.Epoch, seq), type, record, RECORD_HEADER_LENGTH, + received - RECORD_HEADER_LENGTH); + + recordEpoch.ReplayWindow.ReportAuthenticated(seq); + + if (plaintext.Length > this.mPlaintextLimit) + { + return -1; + } + + if (mReadVersion == null) + { + mReadVersion = version; + } + + switch (type) + { + case ContentType.alert: + { + if (plaintext.Length == 2) + { + byte alertLevel = plaintext[0]; + byte alertDescription = plaintext[1]; + + mPeer.NotifyAlertReceived(alertLevel, alertDescription); + + if (alertLevel == AlertLevel.fatal) + { + Failed(); + throw new TlsFatalAlert(alertDescription); + } + + // TODO Can close_notify be a fatal alert? + if (alertDescription == AlertDescription.close_notify) + { + CloseTransport(); + } + } + + return -1; + } + case ContentType.application_data: + { + if (mInHandshake) + { + // TODO Consider buffering application data for new epoch that arrives + // out-of-order with the Finished message + return -1; + } + break; + } + case ContentType.change_cipher_spec: + { + // Implicitly receive change_cipher_spec and change to pending cipher state + + for (int i = 0; i < plaintext.Length; ++i) + { + byte message = TlsUtilities.ReadUint8(plaintext, i); + if (message != ChangeCipherSpec.change_cipher_spec) + { + continue; + } + + if (mPendingEpoch != null) + { + mReadEpoch = mPendingEpoch; + } + } + + return -1; + } + case ContentType.handshake: + { + if (!mInHandshake) + { + if (mRetransmit != null) + { + mRetransmit.ReceivedHandshakeRecord(epoch, plaintext, 0, plaintext.Length); + } + + // TODO Consider support for HelloRequest + return -1; + } + break; + } + case ContentType.heartbeat: + { + // TODO[RFC 6520] + return -1; + } + } + + /* + * NOTE: If we receive any non-handshake data in the new epoch implies the peer has + * received our final flight. + */ + if (!mInHandshake && mRetransmit != null) + { + this.mRetransmit = null; + this.mRetransmitEpoch = null; + this.mRetransmitTimeout = null; + } + + Array.Copy(plaintext, 0, buf, off, plaintext.Length); + return plaintext.Length; + } + + private int ReceiveRecord(byte[] buf, int off, int len, int waitMillis) + { + if (mRecordQueue.Available > 0) + { + int length = 0; + if (mRecordQueue.Available >= RECORD_HEADER_LENGTH) + { + byte[] lengthBytes = new byte[2]; + mRecordQueue.Read(lengthBytes, 0, 2, 11); + length = TlsUtilities.ReadUint16(lengthBytes, 0); + } + + int received = System.Math.Min(mRecordQueue.Available, RECORD_HEADER_LENGTH + length); + mRecordQueue.RemoveData(buf, off, received, 0); + return received; + } + + { + int received = ReceiveDatagram(buf, off, len, waitMillis); + if (received >= RECORD_HEADER_LENGTH) + { + int fragmentLength = TlsUtilities.ReadUint16(buf, off + 11); + int recordLength = RECORD_HEADER_LENGTH + fragmentLength; + if (received > recordLength) + { + mRecordQueue.AddData(buf, off + recordLength, received - recordLength); + received = recordLength; + } + } + return received; + } + } + + private void SendRecord(byte contentType, byte[] buf, int off, int len) + { + // Never send anything until a valid ClientHello has been received + if (mWriteVersion == null) + return; + + if (len > this.mPlaintextLimit) + throw new TlsFatalAlert(AlertDescription.internal_error); + + /* + * RFC 5246 6.2.1 Implementations MUST NOT send zero-length fragments of Handshake, Alert, + * or ChangeCipherSpec content types. + */ + if (len < 1 && contentType != ContentType.application_data) + throw new TlsFatalAlert(AlertDescription.internal_error); + + int recordEpoch = mWriteEpoch.Epoch; + long recordSequenceNumber = mWriteEpoch.AllocateSequenceNumber(); + + byte[] ciphertext = mWriteEpoch.Cipher.EncodePlaintext( + GetMacSequenceNumber(recordEpoch, recordSequenceNumber), contentType, buf, off, len); + + // TODO Check the ciphertext length? + + byte[] record = new byte[ciphertext.Length + RECORD_HEADER_LENGTH]; + TlsUtilities.WriteUint8(contentType, record, 0); + ProtocolVersion version = mWriteVersion; + TlsUtilities.WriteVersion(version, record, 1); + TlsUtilities.WriteUint16(recordEpoch, record, 3); + TlsUtilities.WriteUint48(recordSequenceNumber, record, 5); + TlsUtilities.WriteUint16(ciphertext.Length, record, 11); + Array.Copy(ciphertext, 0, record, RECORD_HEADER_LENGTH, ciphertext.Length); + + SendDatagram(mTransport, record, 0, record.Length); + } + + private static long GetMacSequenceNumber(int epoch, long sequence_number) + { + return ((epoch & 0xFFFFFFFFL) << 48) | sequence_number; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsRecordLayer.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsRecordLayer.cs.meta new file mode 100644 index 0000000..cb7c337 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsRecordLayer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ab03050574fe3c149a29cff0addbe0de +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsReliableHandshake.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsReliableHandshake.cs new file mode 100644 index 0000000..4fc3513 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsReliableHandshake.cs @@ -0,0 +1,449 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Date; + +namespace Org.BouncyCastle.Crypto.Tls +{ + internal class DtlsReliableHandshake + { + private const int MaxReceiveAhead = 16; + private const int MessageHeaderLength = 12; + + private const int InitialResendMillis = 1000; + private const int MaxResendMillis = 60000; + + private readonly DtlsRecordLayer mRecordLayer; + private readonly Timeout mHandshakeTimeout; + + private TlsHandshakeHash mHandshakeHash; + + private IDictionary mCurrentInboundFlight = Platform.CreateHashtable(); + private IDictionary mPreviousInboundFlight = null; + private IList mOutboundFlight = Platform.CreateArrayList(); + + private int mResendMillis = -1; + private Timeout mResendTimeout = null; + + private int mMessageSeq = 0, mNextReceiveSeq = 0; + + internal DtlsReliableHandshake(TlsContext context, DtlsRecordLayer transport, int timeoutMillis) + { + this.mRecordLayer = transport; + this.mHandshakeTimeout = Timeout.ForWaitMillis(timeoutMillis); + this.mHandshakeHash = new DeferredHash(); + this.mHandshakeHash.Init(context); + } + + internal void NotifyHelloComplete() + { + this.mHandshakeHash = mHandshakeHash.NotifyPrfDetermined(); + } + + internal TlsHandshakeHash HandshakeHash + { + get { return mHandshakeHash; } + } + + internal TlsHandshakeHash PrepareToFinish() + { + TlsHandshakeHash result = mHandshakeHash; + this.mHandshakeHash = mHandshakeHash.StopTracking(); + return result; + } + + internal void SendMessage(byte msg_type, byte[] body) + { + TlsUtilities.CheckUint24(body.Length); + + if (mResendTimeout != null) + { + CheckInboundFlight(); + + mResendMillis = -1; + mResendTimeout = null; + + mOutboundFlight.Clear(); + } + + Message message = new Message(mMessageSeq++, msg_type, body); + + mOutboundFlight.Add(message); + + WriteMessage(message); + UpdateHandshakeMessagesDigest(message); + } + + internal byte[] ReceiveMessageBody(byte msg_type) + { + Message message = ReceiveMessage(); + if (message.Type != msg_type) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + + return message.Body; + } + + internal Message ReceiveMessage() + { + long currentTimeMillis = DateTimeUtilities.CurrentUnixMs(); + + if (mResendTimeout == null) + { + mResendMillis = InitialResendMillis; + mResendTimeout = new Timeout(mResendMillis, currentTimeMillis); + + PrepareInboundFlight(Platform.CreateHashtable()); + } + + byte[] buf = null; + + for (;;) + { + if (mRecordLayer.IsClosed) + throw new TlsFatalAlert(AlertDescription.user_canceled); + + Message pending = GetPendingMessage(); + if (pending != null) + return pending; + + int handshakeMillis = Timeout.GetWaitMillis(mHandshakeTimeout, currentTimeMillis); + if (handshakeMillis < 0) + throw new TlsFatalAlert(AlertDescription.handshake_failure); + + int waitMillis = System.Math.Max(1, Timeout.GetWaitMillis(mResendTimeout, currentTimeMillis)); + if (handshakeMillis > 0) + { + waitMillis = System.Math.Min(waitMillis, handshakeMillis); + } + + int receiveLimit = mRecordLayer.GetReceiveLimit(); + if (buf == null || buf.Length < receiveLimit) + { + buf = new byte[receiveLimit]; + } + + int received = mRecordLayer.Receive(buf, 0, receiveLimit, waitMillis); + if (received < 0) + { + ResendOutboundFlight(); + } + else + { + ProcessRecord(MaxReceiveAhead, mRecordLayer.ReadEpoch, buf, 0, received); + } + + currentTimeMillis = DateTimeUtilities.CurrentUnixMs(); + } + } + + internal void Finish() + { + DtlsHandshakeRetransmit retransmit = null; + if (mResendTimeout != null) + { + CheckInboundFlight(); + } + else + { + PrepareInboundFlight(null); + + if (mPreviousInboundFlight != null) + { + /* + * RFC 6347 4.2.4. In addition, for at least twice the default MSL defined for [TCP], + * when in the FINISHED state, the node that transmits the last flight (the server in an + * ordinary handshake or the client in a resumed handshake) MUST respond to a retransmit + * of the peer's last flight with a retransmit of the last flight. + */ + retransmit = new Retransmit(this); + } + } + + mRecordLayer.HandshakeSuccessful(retransmit); + } + + internal void ResetHandshakeMessagesDigest() + { + mHandshakeHash.Reset(); + } + + private int BackOff(int timeoutMillis) + { + /* + * TODO[DTLS] implementations SHOULD back off handshake packet size during the + * retransmit backoff. + */ + return System.Math.Min(timeoutMillis * 2, MaxResendMillis); + } + + /** + * Check that there are no "extra" messages left in the current inbound flight + */ + private void CheckInboundFlight() + { + foreach (int key in mCurrentInboundFlight.Keys) + { + if (key >= mNextReceiveSeq) + { + // TODO Should this be considered an error? + } + } + } + + private Message GetPendingMessage() + { + DtlsReassembler next = (DtlsReassembler)mCurrentInboundFlight[mNextReceiveSeq]; + if (next != null) + { + byte[] body = next.GetBodyIfComplete(); + if (body != null) + { + mPreviousInboundFlight = null; + return UpdateHandshakeMessagesDigest(new Message(mNextReceiveSeq++, next.MsgType, body)); + } + } + return null; + } + + private void PrepareInboundFlight(IDictionary nextFlight) + { + ResetAll(mCurrentInboundFlight); + mPreviousInboundFlight = mCurrentInboundFlight; + mCurrentInboundFlight = nextFlight; + } + + private void ProcessRecord(int windowSize, int epoch, byte[] buf, int off, int len) + { + bool checkPreviousFlight = false; + + while (len >= MessageHeaderLength) + { + int fragment_length = TlsUtilities.ReadUint24(buf, off + 9); + int message_length = fragment_length + MessageHeaderLength; + if (len < message_length) + { + // NOTE: Truncated message - ignore it + break; + } + + int length = TlsUtilities.ReadUint24(buf, off + 1); + int fragment_offset = TlsUtilities.ReadUint24(buf, off + 6); + if (fragment_offset + fragment_length > length) + { + // NOTE: Malformed fragment - ignore it and the rest of the record + break; + } + + /* + * NOTE: This very simple epoch check will only work until we want to support + * renegotiation (and we're not likely to do that anyway). + */ + byte msg_type = TlsUtilities.ReadUint8(buf, off + 0); + int expectedEpoch = msg_type == HandshakeType.finished ? 1 : 0; + if (epoch != expectedEpoch) + { + break; + } + + int message_seq = TlsUtilities.ReadUint16(buf, off + 4); + if (message_seq >= (mNextReceiveSeq + windowSize)) + { + // NOTE: Too far ahead - ignore + } + else if (message_seq >= mNextReceiveSeq) + { + DtlsReassembler reassembler = (DtlsReassembler)mCurrentInboundFlight[message_seq]; + if (reassembler == null) + { + reassembler = new DtlsReassembler(msg_type, length); + mCurrentInboundFlight[message_seq] = reassembler; + } + + reassembler.ContributeFragment(msg_type, length, buf, off + MessageHeaderLength, fragment_offset, + fragment_length); + } + else if (mPreviousInboundFlight != null) + { + /* + * NOTE: If we receive the previous flight of incoming messages in full again, + * retransmit our last flight + */ + + DtlsReassembler reassembler = (DtlsReassembler)mPreviousInboundFlight[message_seq]; + if (reassembler != null) + { + reassembler.ContributeFragment(msg_type, length, buf, off + MessageHeaderLength, fragment_offset, + fragment_length); + checkPreviousFlight = true; + } + } + + off += message_length; + len -= message_length; + } + + if (checkPreviousFlight && CheckAll(mPreviousInboundFlight)) + { + ResendOutboundFlight(); + ResetAll(mPreviousInboundFlight); + } + } + + private void ResendOutboundFlight() + { + mRecordLayer.ResetWriteEpoch(); + for (int i = 0; i < mOutboundFlight.Count; ++i) + { + WriteMessage((Message)mOutboundFlight[i]); + } + + mResendMillis = BackOff(mResendMillis); + mResendTimeout = new Timeout(mResendMillis); + } + + private Message UpdateHandshakeMessagesDigest(Message message) + { + if (message.Type != HandshakeType.hello_request) + { + byte[] body = message.Body; + byte[] buf = new byte[MessageHeaderLength]; + TlsUtilities.WriteUint8(message.Type, buf, 0); + TlsUtilities.WriteUint24(body.Length, buf, 1); + TlsUtilities.WriteUint16(message.Seq, buf, 4); + TlsUtilities.WriteUint24(0, buf, 6); + TlsUtilities.WriteUint24(body.Length, buf, 9); + mHandshakeHash.BlockUpdate(buf, 0, buf.Length); + mHandshakeHash.BlockUpdate(body, 0, body.Length); + } + return message; + } + + private void WriteMessage(Message message) + { + int sendLimit = mRecordLayer.GetSendLimit(); + int fragmentLimit = sendLimit - MessageHeaderLength; + + // TODO Support a higher minimum fragment size? + if (fragmentLimit < 1) + { + // TODO Should we be throwing an exception here? + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + int length = message.Body.Length; + + // NOTE: Must still send a fragment if body is empty + int fragment_offset = 0; + do + { + int fragment_length = System.Math.Min(length - fragment_offset, fragmentLimit); + WriteHandshakeFragment(message, fragment_offset, fragment_length); + fragment_offset += fragment_length; + } + while (fragment_offset < length); + } + + private void WriteHandshakeFragment(Message message, int fragment_offset, int fragment_length) + { + RecordLayerBuffer fragment = new RecordLayerBuffer(MessageHeaderLength + fragment_length); + TlsUtilities.WriteUint8(message.Type, fragment); + TlsUtilities.WriteUint24(message.Body.Length, fragment); + TlsUtilities.WriteUint16(message.Seq, fragment); + TlsUtilities.WriteUint24(fragment_offset, fragment); + TlsUtilities.WriteUint24(fragment_length, fragment); + fragment.Write(message.Body, fragment_offset, fragment_length); + + fragment.SendToRecordLayer(mRecordLayer); + } + + private static bool CheckAll(IDictionary inboundFlight) + { + foreach (DtlsReassembler r in inboundFlight.Values) + { + if (r.GetBodyIfComplete() == null) + { + return false; + } + } + return true; + } + + private static void ResetAll(IDictionary inboundFlight) + { + foreach (DtlsReassembler r in inboundFlight.Values) + { + r.Reset(); + } + } + + internal class Message + { + private readonly int mMessageSeq; + private readonly byte mMsgType; + private readonly byte[] mBody; + + internal Message(int message_seq, byte msg_type, byte[] body) + { + this.mMessageSeq = message_seq; + this.mMsgType = msg_type; + this.mBody = body; + } + + public int Seq + { + get { return mMessageSeq; } + } + + public byte Type + { + get { return mMsgType; } + } + + public byte[] Body + { + get { return mBody; } + } + } + + internal class RecordLayerBuffer + : MemoryStream + { + internal RecordLayerBuffer(int size) + : base(size) + { + } + + internal void SendToRecordLayer(DtlsRecordLayer recordLayer) + { +#if PORTABLE + byte[] buf = ToArray(); + int bufLen = buf.Length; +#else + byte[] buf = GetBuffer(); + int bufLen = (int)Length; +#endif + + recordLayer.Send(buf, 0, bufLen); + Platform.Dispose(this); + } + } + + internal class Retransmit + : DtlsHandshakeRetransmit + { + private readonly DtlsReliableHandshake mOuter; + + internal Retransmit(DtlsReliableHandshake outer) + { + this.mOuter = outer; + } + + public void ReceivedHandshakeRecord(int epoch, byte[] buf, int off, int len) + { + mOuter.ProcessRecord(0, epoch, buf, off, len); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsReliableHandshake.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsReliableHandshake.cs.meta new file mode 100644 index 0000000..b9228e6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsReliableHandshake.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8b30fa6a0147ae04d9954a68c42883fa +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsReplayWindow.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsReplayWindow.cs new file mode 100644 index 0000000..ea18e80 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsReplayWindow.cs @@ -0,0 +1,85 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /** + * RFC 4347 4.1.2.5 Anti-replay + *

+ * Support fast rejection of duplicate records by maintaining a sliding receive window + */ + internal class DtlsReplayWindow + { + private const long VALID_SEQ_MASK = 0x0000FFFFFFFFFFFFL; + + private const long WINDOW_SIZE = 64L; + + private long mLatestConfirmedSeq = -1; + private long mBitmap = 0; + + /** + * Check whether a received record with the given sequence number should be rejected as a duplicate. + * + * @param seq the 48-bit DTLSPlainText.sequence_number field of a received record. + * @return true if the record should be discarded without further processing. + */ + internal bool ShouldDiscard(long seq) + { + if ((seq & VALID_SEQ_MASK) != seq) + return true; + + if (seq <= mLatestConfirmedSeq) + { + long diff = mLatestConfirmedSeq - seq; + if (diff >= WINDOW_SIZE) + return true; + if ((mBitmap & (1L << (int)diff)) != 0) + return true; + } + + return false; + } + + /** + * Report that a received record with the given sequence number passed authentication checks. + * + * @param seq the 48-bit DTLSPlainText.sequence_number field of an authenticated record. + */ + internal void ReportAuthenticated(long seq) + { + if ((seq & VALID_SEQ_MASK) != seq) + throw new ArgumentException("out of range", "seq"); + + if (seq <= mLatestConfirmedSeq) + { + long diff = mLatestConfirmedSeq - seq; + if (diff < WINDOW_SIZE) + { + mBitmap |= (1L << (int)diff); + } + } + else + { + long diff = seq - mLatestConfirmedSeq; + if (diff >= WINDOW_SIZE) + { + mBitmap = 1; + } + else + { + mBitmap <<= (int)diff; + mBitmap |= 1; + } + mLatestConfirmedSeq = seq; + } + } + + /** + * When a new epoch begins, sequence numbers begin again at 0 + */ + internal void Reset() + { + mLatestConfirmedSeq = -1; + mBitmap = 0; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsReplayWindow.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsReplayWindow.cs.meta new file mode 100644 index 0000000..06fc3cd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsReplayWindow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 94b62144b13d3734bb0dcefe0fd65eac +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsServerProtocol.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsServerProtocol.cs new file mode 100644 index 0000000..b4ed751 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsServerProtocol.cs @@ -0,0 +1,719 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class DtlsServerProtocol + : DtlsProtocol + { + protected bool mVerifyRequests = true; + + public DtlsServerProtocol(SecureRandom secureRandom) + : base(secureRandom) + { + } + + public virtual bool VerifyRequests + { + get { return mVerifyRequests; } + set { this.mVerifyRequests = value; } + } + + public virtual DtlsTransport Accept(TlsServer server, DatagramTransport transport) + { + if (server == null) + throw new ArgumentNullException("server"); + if (transport == null) + throw new ArgumentNullException("transport"); + + SecurityParameters securityParameters = new SecurityParameters(); + securityParameters.entity = ConnectionEnd.server; + + ServerHandshakeState state = new ServerHandshakeState(); + state.server = server; + state.serverContext = new TlsServerContextImpl(mSecureRandom, securityParameters); + + securityParameters.serverRandom = TlsProtocol.CreateRandomBlock(server.ShouldUseGmtUnixTime(), + state.serverContext.NonceRandomGenerator); + + server.Init(state.serverContext); + + DtlsRecordLayer recordLayer = new DtlsRecordLayer(transport, state.serverContext, server, ContentType.handshake); + server.NotifyCloseHandle(recordLayer); + + // TODO Need to handle sending of HelloVerifyRequest without entering a full connection + + try + { + return ServerHandshake(state, recordLayer); + } + catch (TlsFatalAlert fatalAlert) + { + AbortServerHandshake(state, recordLayer, fatalAlert.AlertDescription); + throw fatalAlert; + } + catch (IOException e) + { + AbortServerHandshake(state, recordLayer, AlertDescription.internal_error); + throw e; + } + catch (Exception e) + { + AbortServerHandshake(state, recordLayer, AlertDescription.internal_error); + throw new TlsFatalAlert(AlertDescription.internal_error, e); + } + finally + { + securityParameters.Clear(); + } + } + + internal virtual void AbortServerHandshake(ServerHandshakeState state, DtlsRecordLayer recordLayer, byte alertDescription) + { + recordLayer.Fail(alertDescription); + InvalidateSession(state); + } + + internal virtual DtlsTransport ServerHandshake(ServerHandshakeState state, DtlsRecordLayer recordLayer) + { + SecurityParameters securityParameters = state.serverContext.SecurityParameters; + DtlsReliableHandshake handshake = new DtlsReliableHandshake(state.serverContext, recordLayer, + state.server.GetHandshakeTimeoutMillis()); + DtlsReliableHandshake.Message clientMessage = handshake.ReceiveMessage(); + + // NOTE: DTLSRecordLayer requires any DTLS version, we don't otherwise constrain this + //ProtocolVersion recordLayerVersion = recordLayer.ReadVersion; + + if (clientMessage.Type == HandshakeType.client_hello) + { + ProcessClientHello(state, clientMessage.Body); + } + else + { + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + { + byte[] serverHelloBody = GenerateServerHello(state); + + ApplyMaxFragmentLengthExtension(recordLayer, securityParameters.maxFragmentLength); + + ProtocolVersion recordLayerVersion = state.serverContext.ServerVersion; + recordLayer.ReadVersion = recordLayerVersion; + recordLayer.SetWriteVersion(recordLayerVersion); + + handshake.SendMessage(HandshakeType.server_hello, serverHelloBody); + } + + handshake.NotifyHelloComplete(); + + IList serverSupplementalData = state.server.GetServerSupplementalData(); + if (serverSupplementalData != null) + { + byte[] supplementalDataBody = GenerateSupplementalData(serverSupplementalData); + handshake.SendMessage(HandshakeType.supplemental_data, supplementalDataBody); + } + + state.keyExchange = state.server.GetKeyExchange(); + state.keyExchange.Init(state.serverContext); + + state.serverCredentials = state.server.GetCredentials(); + + Certificate serverCertificate = null; + + if (state.serverCredentials == null) + { + state.keyExchange.SkipServerCredentials(); + } + else + { + state.keyExchange.ProcessServerCredentials(state.serverCredentials); + + serverCertificate = state.serverCredentials.Certificate; + byte[] certificateBody = GenerateCertificate(serverCertificate); + handshake.SendMessage(HandshakeType.certificate, certificateBody); + } + + // TODO[RFC 3546] Check whether empty certificates is possible, allowed, or excludes CertificateStatus + if (serverCertificate == null || serverCertificate.IsEmpty) + { + state.allowCertificateStatus = false; + } + + if (state.allowCertificateStatus) + { + CertificateStatus certificateStatus = state.server.GetCertificateStatus(); + if (certificateStatus != null) + { + byte[] certificateStatusBody = GenerateCertificateStatus(state, certificateStatus); + handshake.SendMessage(HandshakeType.certificate_status, certificateStatusBody); + } + } + + byte[] serverKeyExchange = state.keyExchange.GenerateServerKeyExchange(); + if (serverKeyExchange != null) + { + handshake.SendMessage(HandshakeType.server_key_exchange, serverKeyExchange); + } + + if (state.serverCredentials != null) + { + state.certificateRequest = state.server.GetCertificateRequest(); + if (state.certificateRequest != null) + { + if (TlsUtilities.IsTlsV12(state.serverContext) != (state.certificateRequest.SupportedSignatureAlgorithms != null)) + throw new TlsFatalAlert(AlertDescription.internal_error); + + state.keyExchange.ValidateCertificateRequest(state.certificateRequest); + + byte[] certificateRequestBody = GenerateCertificateRequest(state, state.certificateRequest); + handshake.SendMessage(HandshakeType.certificate_request, certificateRequestBody); + + TlsUtilities.TrackHashAlgorithms(handshake.HandshakeHash, + state.certificateRequest.SupportedSignatureAlgorithms); + } + } + + handshake.SendMessage(HandshakeType.server_hello_done, TlsUtilities.EmptyBytes); + + handshake.HandshakeHash.SealHashAlgorithms(); + + clientMessage = handshake.ReceiveMessage(); + + if (clientMessage.Type == HandshakeType.supplemental_data) + { + ProcessClientSupplementalData(state, clientMessage.Body); + clientMessage = handshake.ReceiveMessage(); + } + else + { + state.server.ProcessClientSupplementalData(null); + } + + if (state.certificateRequest == null) + { + state.keyExchange.SkipClientCredentials(); + } + else + { + if (clientMessage.Type == HandshakeType.certificate) + { + ProcessClientCertificate(state, clientMessage.Body); + clientMessage = handshake.ReceiveMessage(); + } + else + { + if (TlsUtilities.IsTlsV12(state.serverContext)) + { + /* + * RFC 5246 If no suitable certificate is available, the client MUST send a + * certificate message containing no certificates. + * + * NOTE: In previous RFCs, this was SHOULD instead of MUST. + */ + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + NotifyClientCertificate(state, Certificate.EmptyChain); + } + } + + if (clientMessage.Type == HandshakeType.client_key_exchange) + { + ProcessClientKeyExchange(state, clientMessage.Body); + } + else + { + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + TlsHandshakeHash prepareFinishHash = handshake.PrepareToFinish(); + securityParameters.sessionHash = TlsProtocol.GetCurrentPrfHash(state.serverContext, prepareFinishHash, null); + + TlsProtocol.EstablishMasterSecret(state.serverContext, state.keyExchange); + recordLayer.InitPendingEpoch(state.server.GetCipher()); + + /* + * RFC 5246 7.4.8 This message is only sent following a client certificate that has signing + * capability (i.e., all certificates except those containing fixed Diffie-Hellman + * parameters). + */ + if (ExpectCertificateVerifyMessage(state)) + { + byte[] certificateVerifyBody = handshake.ReceiveMessageBody(HandshakeType.certificate_verify); + ProcessCertificateVerify(state, certificateVerifyBody, prepareFinishHash); + } + + // NOTE: Calculated exclusive of the actual Finished message from the client + byte[] expectedClientVerifyData = TlsUtilities.CalculateVerifyData(state.serverContext, ExporterLabel.client_finished, + TlsProtocol.GetCurrentPrfHash(state.serverContext, handshake.HandshakeHash, null)); + ProcessFinished(handshake.ReceiveMessageBody(HandshakeType.finished), expectedClientVerifyData); + + if (state.expectSessionTicket) + { + NewSessionTicket newSessionTicket = state.server.GetNewSessionTicket(); + byte[] newSessionTicketBody = GenerateNewSessionTicket(state, newSessionTicket); + handshake.SendMessage(HandshakeType.session_ticket, newSessionTicketBody); + } + + // NOTE: Calculated exclusive of the Finished message itself + byte[] serverVerifyData = TlsUtilities.CalculateVerifyData(state.serverContext, ExporterLabel.server_finished, + TlsProtocol.GetCurrentPrfHash(state.serverContext, handshake.HandshakeHash, null)); + handshake.SendMessage(HandshakeType.finished, serverVerifyData); + + handshake.Finish(); + + //{ + // state.sessionParameters = new SessionParameters.Builder() + // .SetCipherSuite(securityParameters.CipherSuite) + // .SetCompressionAlgorithm(securityParameters.CompressionAlgorithm) + // .SetExtendedMasterSecret(securityParameters.IsExtendedMasterSecret) + // .SetMasterSecret(securityParameters.MasterSecret) + // .SetPeerCertificate(state.clientCertificate) + // .SetPskIdentity(securityParameters.PskIdentity) + // .SetSrpIdentity(securityParameters.SrpIdentity) + // // TODO Consider filtering extensions that aren't relevant to resumed sessions + // .SetServerExtensions(state.serverExtensions) + // .Build(); + + // state.tlsSession = TlsUtilities.ImportSession(state.tlsSession.SessionID, state.sessionParameters); + + // state.serverContext.SetResumableSession(state.tlsSession); + //} + + state.server.NotifyHandshakeComplete(); + + return new DtlsTransport(recordLayer); + } + + protected virtual void InvalidateSession(ServerHandshakeState state) + { + if (state.sessionParameters != null) + { + state.sessionParameters.Clear(); + state.sessionParameters = null; + } + + if (state.tlsSession != null) + { + state.tlsSession.Invalidate(); + state.tlsSession = null; + } + } + + protected virtual byte[] GenerateCertificateRequest(ServerHandshakeState state, CertificateRequest certificateRequest) + { + MemoryStream buf = new MemoryStream(); + certificateRequest.Encode(buf); + return buf.ToArray(); + } + + protected virtual byte[] GenerateCertificateStatus(ServerHandshakeState state, CertificateStatus certificateStatus) + { + MemoryStream buf = new MemoryStream(); + certificateStatus.Encode(buf); + return buf.ToArray(); + } + + protected virtual byte[] GenerateNewSessionTicket(ServerHandshakeState state, NewSessionTicket newSessionTicket) + { + MemoryStream buf = new MemoryStream(); + newSessionTicket.Encode(buf); + return buf.ToArray(); + } + + protected virtual byte[] GenerateServerHello(ServerHandshakeState state) + { + SecurityParameters securityParameters = state.serverContext.SecurityParameters; + + MemoryStream buf = new MemoryStream(); + + { + ProtocolVersion server_version = state.server.GetServerVersion(); + if (!server_version.IsEqualOrEarlierVersionOf(state.serverContext.ClientVersion)) + throw new TlsFatalAlert(AlertDescription.internal_error); + + // TODO Read RFCs for guidance on the expected record layer version number + // recordStream.setReadVersion(server_version); + // recordStream.setWriteVersion(server_version); + // recordStream.setRestrictReadVersion(true); + state.serverContext.SetServerVersion(server_version); + + TlsUtilities.WriteVersion(state.serverContext.ServerVersion, buf); + } + + buf.Write(securityParameters.ServerRandom, 0, securityParameters.ServerRandom.Length); + + /* + * The server may return an empty session_id to indicate that the session will not be cached + * and therefore cannot be resumed. + */ + TlsUtilities.WriteOpaque8(TlsUtilities.EmptyBytes, buf); + + int selectedCipherSuite = state.server.GetSelectedCipherSuite(); + if (!Arrays.Contains(state.offeredCipherSuites, selectedCipherSuite) + || selectedCipherSuite == CipherSuite.TLS_NULL_WITH_NULL_NULL + || CipherSuite.IsScsv(selectedCipherSuite) + || !TlsUtilities.IsValidCipherSuiteForVersion(selectedCipherSuite, state.serverContext.ServerVersion)) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + ValidateSelectedCipherSuite(selectedCipherSuite, AlertDescription.internal_error); + securityParameters.cipherSuite = selectedCipherSuite; + + byte selectedCompressionMethod = state.server.GetSelectedCompressionMethod(); + if (!Arrays.Contains(state.offeredCompressionMethods, selectedCompressionMethod)) + throw new TlsFatalAlert(AlertDescription.internal_error); + securityParameters.compressionAlgorithm = selectedCompressionMethod; + + TlsUtilities.WriteUint16(selectedCipherSuite, buf); + TlsUtilities.WriteUint8(selectedCompressionMethod, buf); + + state.serverExtensions = TlsExtensionsUtilities.EnsureExtensionsInitialised(state.server.GetServerExtensions()); + + /* + * RFC 5746 3.6. Server Behavior: Initial Handshake + */ + if (state.secure_renegotiation) + { + byte[] renegExtData = TlsUtilities.GetExtensionData(state.serverExtensions, ExtensionType.renegotiation_info); + bool noRenegExt = (null == renegExtData); + + if (noRenegExt) + { + /* + * Note that sending a "renegotiation_info" extension in response to a ClientHello + * containing only the SCSV is an explicit exception to the prohibition in RFC 5246, + * Section 7.4.1.4, on the server sending unsolicited extensions and is only allowed + * because the client is signaling its willingness to receive the extension via the + * TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV. + */ + + /* + * If the secure_renegotiation flag is set to TRUE, the server MUST include an empty + * "renegotiation_info" extension in the ServerHello message. + */ + state.serverExtensions[ExtensionType.renegotiation_info] = TlsProtocol.CreateRenegotiationInfo(TlsUtilities.EmptyBytes); + } + } + + if (securityParameters.IsExtendedMasterSecret) + { + TlsExtensionsUtilities.AddExtendedMasterSecretExtension(state.serverExtensions); + } + + /* + * TODO RFC 3546 2.3 If [...] the older session is resumed, then the server MUST ignore + * extensions appearing in the client hello, and send a server hello containing no + * extensions. + */ + + if (state.serverExtensions.Count > 0) + { + securityParameters.encryptThenMac = TlsExtensionsUtilities.HasEncryptThenMacExtension(state.serverExtensions); + + securityParameters.maxFragmentLength = EvaluateMaxFragmentLengthExtension(state.resumedSession, + state.clientExtensions, state.serverExtensions, AlertDescription.internal_error); + + securityParameters.truncatedHMac = TlsExtensionsUtilities.HasTruncatedHMacExtension(state.serverExtensions); + + /* + * TODO It's surprising that there's no provision to allow a 'fresh' CertificateStatus to be sent in + * a session resumption handshake. + */ + state.allowCertificateStatus = !state.resumedSession + && TlsUtilities.HasExpectedEmptyExtensionData(state.serverExtensions, ExtensionType.status_request, + AlertDescription.internal_error); + + state.expectSessionTicket = !state.resumedSession + && TlsUtilities.HasExpectedEmptyExtensionData(state.serverExtensions, ExtensionType.session_ticket, + AlertDescription.internal_error); + + TlsProtocol.WriteExtensions(buf, state.serverExtensions); + } + + securityParameters.prfAlgorithm = TlsProtocol.GetPrfAlgorithm(state.serverContext, + securityParameters.CipherSuite); + + /* + * RFC 5246 7.4.9. Any cipher suite which does not explicitly specify verify_data_length + * has a verify_data_length equal to 12. This includes all existing cipher suites. + */ + securityParameters.verifyDataLength = 12; + + return buf.ToArray(); + } + + protected virtual void NotifyClientCertificate(ServerHandshakeState state, Certificate clientCertificate) + { + if (state.certificateRequest == null) + throw new InvalidOperationException(); + + if (state.clientCertificate != null) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + + state.clientCertificate = clientCertificate; + + if (clientCertificate.IsEmpty) + { + state.keyExchange.SkipClientCredentials(); + } + else + { + + /* + * TODO RFC 5246 7.4.6. If the certificate_authorities list in the certificate request + * message was non-empty, one of the certificates in the certificate chain SHOULD be + * issued by one of the listed CAs. + */ + + state.clientCertificateType = TlsUtilities.GetClientCertificateType(clientCertificate, + state.serverCredentials.Certificate); + + state.keyExchange.ProcessClientCertificate(clientCertificate); + } + + /* + * RFC 5246 7.4.6. If the client does not send any certificates, the server MAY at its + * discretion either continue the handshake without client authentication, or respond with a + * fatal handshake_failure alert. Also, if some aspect of the certificate chain was + * unacceptable (e.g., it was not signed by a known, trusted CA), the server MAY at its + * discretion either continue the handshake (considering the client unauthenticated) or send + * a fatal alert. + */ + state.server.NotifyClientCertificate(clientCertificate); + } + + protected virtual void ProcessClientCertificate(ServerHandshakeState state, byte[] body) + { + MemoryStream buf = new MemoryStream(body, false); + + Certificate clientCertificate = Certificate.Parse(buf); + + TlsProtocol.AssertEmpty(buf); + + NotifyClientCertificate(state, clientCertificate); + } + + protected virtual void ProcessCertificateVerify(ServerHandshakeState state, byte[] body, TlsHandshakeHash prepareFinishHash) + { + if (state.certificateRequest == null) + throw new InvalidOperationException(); + + MemoryStream buf = new MemoryStream(body, false); + + TlsServerContextImpl context = state.serverContext; + DigitallySigned clientCertificateVerify = DigitallySigned.Parse(context, buf); + + TlsProtocol.AssertEmpty(buf); + + // Verify the CertificateVerify message contains a correct signature. + try + { + SignatureAndHashAlgorithm signatureAlgorithm = clientCertificateVerify.Algorithm; + + byte[] hash; + if (TlsUtilities.IsTlsV12(context)) + { + TlsUtilities.VerifySupportedSignatureAlgorithm(state.certificateRequest.SupportedSignatureAlgorithms, signatureAlgorithm); + hash = prepareFinishHash.GetFinalHash(signatureAlgorithm.Hash); + } + else + { + hash = context.SecurityParameters.SessionHash; + } + + X509CertificateStructure x509Cert = state.clientCertificate.GetCertificateAt(0); + SubjectPublicKeyInfo keyInfo = x509Cert.SubjectPublicKeyInfo; + AsymmetricKeyParameter publicKey = PublicKeyFactory.CreateKey(keyInfo); + + TlsSigner tlsSigner = TlsUtilities.CreateTlsSigner((byte)state.clientCertificateType); + tlsSigner.Init(context); + if (!tlsSigner.VerifyRawSignature(signatureAlgorithm, clientCertificateVerify.Signature, publicKey, hash)) + throw new TlsFatalAlert(AlertDescription.decrypt_error); + } + catch (TlsFatalAlert e) + { + throw e; + } + catch (Exception e) + { + throw new TlsFatalAlert(AlertDescription.decrypt_error, e); + } + } + + protected virtual void ProcessClientHello(ServerHandshakeState state, byte[] body) + { + MemoryStream buf = new MemoryStream(body, false); + + // TODO Read RFCs for guidance on the expected record layer version number + ProtocolVersion client_version = TlsUtilities.ReadVersion(buf); + if (!client_version.IsDtls) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + /* + * Read the client random + */ + byte[] client_random = TlsUtilities.ReadFully(32, buf); + + byte[] sessionID = TlsUtilities.ReadOpaque8(buf); + if (sessionID.Length > 32) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + // TODO RFC 4347 has the cookie length restricted to 32, but not in RFC 6347 + byte[] cookie = TlsUtilities.ReadOpaque8(buf); + + int cipher_suites_length = TlsUtilities.ReadUint16(buf); + if (cipher_suites_length < 2 || (cipher_suites_length & 1) != 0) + { + throw new TlsFatalAlert(AlertDescription.decode_error); + } + + /* + * NOTE: "If the session_id field is not empty (implying a session resumption request) this + * vector must include at least the cipher_suite from that session." + */ + state.offeredCipherSuites = TlsUtilities.ReadUint16Array(cipher_suites_length / 2, buf); + + int compression_methods_length = TlsUtilities.ReadUint8(buf); + if (compression_methods_length < 1) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + state.offeredCompressionMethods = TlsUtilities.ReadUint8Array(compression_methods_length, buf); + + /* + * TODO RFC 3546 2.3 If [...] the older session is resumed, then the server MUST ignore + * extensions appearing in the client hello, and send a server hello containing no + * extensions. + */ + state.clientExtensions = TlsProtocol.ReadExtensions(buf); + + TlsServerContextImpl context = state.serverContext; + SecurityParameters securityParameters = context.SecurityParameters; + + /* + * TODO[resumption] Check RFC 7627 5.4. for required behaviour + */ + + /* + * RFC 7627 4. Clients and servers SHOULD NOT accept handshakes that do not use the extended + * master secret [..]. (and see 5.2, 5.3) + */ + securityParameters.extendedMasterSecret = TlsExtensionsUtilities.HasExtendedMasterSecretExtension(state.clientExtensions); + if (!securityParameters.IsExtendedMasterSecret && state.server.RequiresExtendedMasterSecret()) + { + throw new TlsFatalAlert(AlertDescription.handshake_failure); + } + + context.SetClientVersion(client_version); + + state.server.NotifyClientVersion(client_version); + state.server.NotifyFallback(Arrays.Contains(state.offeredCipherSuites, CipherSuite.TLS_FALLBACK_SCSV)); + + securityParameters.clientRandom = client_random; + + state.server.NotifyOfferedCipherSuites(state.offeredCipherSuites); + state.server.NotifyOfferedCompressionMethods(state.offeredCompressionMethods); + + /* + * RFC 5746 3.6. Server Behavior: Initial Handshake + */ + { + /* + * RFC 5746 3.4. The client MUST include either an empty "renegotiation_info" extension, + * or the TLS_EMPTY_RENEGOTIATION_INFO_SCSV signaling cipher suite value in the + * ClientHello. Including both is NOT RECOMMENDED. + */ + + /* + * When a ClientHello is received, the server MUST check if it includes the + * TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV. If it does, set the secure_renegotiation flag + * to TRUE. + */ + if (Arrays.Contains(state.offeredCipherSuites, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV)) + { + state.secure_renegotiation = true; + } + + /* + * The server MUST check if the "renegotiation_info" extension is included in the + * ClientHello. + */ + byte[] renegExtData = TlsUtilities.GetExtensionData(state.clientExtensions, ExtensionType.renegotiation_info); + if (renegExtData != null) + { + /* + * If the extension is present, set secure_renegotiation flag to TRUE. The + * server MUST then verify that the length of the "renegotiated_connection" + * field is zero, and if it is not, MUST abort the handshake. + */ + state.secure_renegotiation = true; + + if (!Arrays.ConstantTimeAreEqual(renegExtData, TlsProtocol.CreateRenegotiationInfo(TlsUtilities.EmptyBytes))) + throw new TlsFatalAlert(AlertDescription.handshake_failure); + } + } + + state.server.NotifySecureRenegotiation(state.secure_renegotiation); + + if (state.clientExtensions != null) + { + // NOTE: Validates the padding extension data, if present + TlsExtensionsUtilities.GetPaddingExtension(state.clientExtensions); + + state.server.ProcessClientExtensions(state.clientExtensions); + } + } + + protected virtual void ProcessClientKeyExchange(ServerHandshakeState state, byte[] body) + { + MemoryStream buf = new MemoryStream(body, false); + + state.keyExchange.ProcessClientKeyExchange(buf); + + TlsProtocol.AssertEmpty(buf); + } + + protected virtual void ProcessClientSupplementalData(ServerHandshakeState state, byte[] body) + { + MemoryStream buf = new MemoryStream(body, false); + IList clientSupplementalData = TlsProtocol.ReadSupplementalDataMessage(buf); + state.server.ProcessClientSupplementalData(clientSupplementalData); + } + + protected virtual bool ExpectCertificateVerifyMessage(ServerHandshakeState state) + { + return state.clientCertificateType >= 0 && TlsUtilities.HasSigningCapability((byte)state.clientCertificateType); + } + + protected internal class ServerHandshakeState + { + internal TlsServer server = null; + internal TlsServerContextImpl serverContext = null; + internal TlsSession tlsSession = null; + internal SessionParameters sessionParameters = null; + internal SessionParameters.Builder sessionParametersBuilder = null; + internal int[] offeredCipherSuites = null; + internal byte[] offeredCompressionMethods = null; + internal IDictionary clientExtensions = null; + internal IDictionary serverExtensions = null; + internal bool resumedSession = false; + internal bool secure_renegotiation = false; + internal bool allowCertificateStatus = false; + internal bool expectSessionTicket = false; + internal TlsKeyExchange keyExchange = null; + internal TlsCredentials serverCredentials = null; + internal CertificateRequest certificateRequest = null; + internal short clientCertificateType = -1; + internal Certificate clientCertificate = null; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsServerProtocol.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsServerProtocol.cs.meta new file mode 100644 index 0000000..2ea910b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsServerProtocol.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 61683d1d0b12d654cb93b7ded6a6c562 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsTransport.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsTransport.cs new file mode 100644 index 0000000..f2f7165 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsTransport.cs @@ -0,0 +1,132 @@ +using System; +using System.IO; +#if !PORTABLE || DOTNET +using System.Net.Sockets; +#endif + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class DtlsTransport + : DatagramTransport + { + private readonly DtlsRecordLayer mRecordLayer; + + internal DtlsTransport(DtlsRecordLayer recordLayer) + { + this.mRecordLayer = recordLayer; + } + + public virtual int GetReceiveLimit() + { + return mRecordLayer.GetReceiveLimit(); + } + + public virtual int GetSendLimit() + { + return mRecordLayer.GetSendLimit(); + } + + public virtual int Receive(byte[] buf, int off, int len, int waitMillis) + { + if (null == buf) + throw new ArgumentNullException("buf"); + if (off < 0 || off >= buf.Length) + throw new ArgumentException("invalid offset: " + off, "off"); + if (len < 0 || len > buf.Length - off) + throw new ArgumentException("invalid length: " + len, "len"); + if (waitMillis < 0) + throw new ArgumentException("cannot be negative", "waitMillis"); + + try + { + return mRecordLayer.Receive(buf, off, len, waitMillis); + } + catch (TlsFatalAlert fatalAlert) + { + mRecordLayer.Fail(fatalAlert.AlertDescription); + throw fatalAlert; + } + catch (TlsTimeoutException e) + { + throw e; + } +#if !PORTABLE || DOTNET + catch (SocketException e) + { + if (TlsUtilities.IsTimeout(e)) + throw e; + + mRecordLayer.Fail(AlertDescription.internal_error); + throw new TlsFatalAlert(AlertDescription.internal_error, e); + } +#endif + //catch (InterruptedIOException e) + //{ + // throw e; + //} + catch (IOException e) + { + mRecordLayer.Fail(AlertDescription.internal_error); + throw e; + } + catch (Exception e) + { + mRecordLayer.Fail(AlertDescription.internal_error); + throw new TlsFatalAlert(AlertDescription.internal_error, e); + } + } + + public virtual void Send(byte[] buf, int off, int len) + { + if (null == buf) + throw new ArgumentNullException("buf"); + if (off < 0 || off >= buf.Length) + throw new ArgumentException("invalid offset: " + off, "off"); + if (len < 0 || len > buf.Length - off) + throw new ArgumentException("invalid length: " + len, "len"); + + try + { + mRecordLayer.Send(buf, off, len); + } + catch (TlsFatalAlert fatalAlert) + { + mRecordLayer.Fail(fatalAlert.AlertDescription); + throw fatalAlert; + } + catch (TlsTimeoutException e) + { + throw e; + } +#if !PORTABLE || DOTNET + catch (SocketException e) + { + if (TlsUtilities.IsTimeout(e)) + throw e; + + mRecordLayer.Fail(AlertDescription.internal_error); + throw new TlsFatalAlert(AlertDescription.internal_error, e); + } +#endif + //catch (InterruptedIOException e) + //{ + // throw e; + //} + catch (IOException e) + { + mRecordLayer.Fail(AlertDescription.internal_error); + throw e; + } + catch (Exception e) + { + mRecordLayer.Fail(AlertDescription.internal_error); + throw new TlsFatalAlert(AlertDescription.internal_error, e); + } + } + + public virtual void Close() + { + mRecordLayer.Close(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsTransport.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsTransport.cs.meta new file mode 100644 index 0000000..2a29076 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/DtlsTransport.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f77b79d64abd3984bad23dea3cd4ebe0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ECBasisType.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ECBasisType.cs new file mode 100644 index 0000000..5416e17 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ECBasisType.cs @@ -0,0 +1,16 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + ///

RFC 4492 5.4. (Errata ID: 2389) + public abstract class ECBasisType + { + public const byte ec_basis_trinomial = 1; + public const byte ec_basis_pentanomial = 2; + + public static bool IsValid(byte ecBasisType) + { + return ecBasisType >= ec_basis_trinomial && ecBasisType <= ec_basis_pentanomial; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ECBasisType.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ECBasisType.cs.meta new file mode 100644 index 0000000..bcfd1f7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ECBasisType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cfbfd80d4c21e4147b59b8c8bc5e605f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ECCurveType.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ECCurveType.cs new file mode 100644 index 0000000..1b352e9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ECCurveType.cs @@ -0,0 +1,29 @@ +namespace Org.BouncyCastle.Crypto.Tls +{ + /// + /// RFC 4492 5.4 + /// + public abstract class ECCurveType + { + /** + * Indicates the elliptic curve domain parameters are conveyed verbosely, and the + * underlying finite field is a prime field. + */ + public const byte explicit_prime = 1; + + /** + * Indicates the elliptic curve domain parameters are conveyed verbosely, and the + * underlying finite field is a characteristic-2 field. + */ + public const byte explicit_char2 = 2; + + /** + * Indicates that a named curve is used. This option SHOULD be used when applicable. + */ + public const byte named_curve = 3; + + /* + * Values 248 through 255 are reserved for private use. + */ + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ECCurveType.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ECCurveType.cs.meta new file mode 100644 index 0000000..e6b9c11 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ECCurveType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 704a0e2bef4e31045a29f0399aa52c2c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ECPointFormat.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ECPointFormat.cs new file mode 100644 index 0000000..21b0fdd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ECPointFormat.cs @@ -0,0 +1,16 @@ +namespace Org.BouncyCastle.Crypto.Tls +{ + /// + /// RFC 4492 5.1.2 + /// + public abstract class ECPointFormat + { + public const byte uncompressed = 0; + public const byte ansiX962_compressed_prime = 1; + public const byte ansiX962_compressed_char2 = 2; + + /* + * reserved (248..255) + */ + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ECPointFormat.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ECPointFormat.cs.meta new file mode 100644 index 0000000..a04ecc3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ECPointFormat.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c4a59a71035c6cf44a757bf81f9cccae +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/EncryptionAlgorithm.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/EncryptionAlgorithm.cs new file mode 100644 index 0000000..45eef18 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/EncryptionAlgorithm.cs @@ -0,0 +1,69 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// RFC 2246 + /// + /// Note that the values here are implementation-specific and arbitrary. It is recommended not to + /// depend on the particular values (e.g. serialization). + /// + public abstract class EncryptionAlgorithm + { + public const int NULL = 0; + public const int RC4_40 = 1; + public const int RC4_128 = 2; + public const int RC2_CBC_40 = 3; + public const int IDEA_CBC = 4; + public const int DES40_CBC = 5; + public const int DES_CBC = 6; + public const int cls_3DES_EDE_CBC = 7; + + /* + * RFC 3268 + */ + public const int AES_128_CBC = 8; + public const int AES_256_CBC = 9; + + /* + * RFC 5289 + */ + public const int AES_128_GCM = 10; + public const int AES_256_GCM = 11; + + /* + * RFC 4132 + */ + public const int CAMELLIA_128_CBC = 12; + public const int CAMELLIA_256_CBC = 13; + + /* + * RFC 4162 + */ + public const int SEED_CBC = 14; + + /* + * RFC 6655 + */ + public const int AES_128_CCM = 15; + public const int AES_128_CCM_8 = 16; + public const int AES_256_CCM = 17; + public const int AES_256_CCM_8 = 18; + + /* + * RFC 6367 + */ + public const int CAMELLIA_128_GCM = 19; + public const int CAMELLIA_256_GCM = 20; + + /* + * RFC 7905 + */ + public const int CHACHA20_POLY1305 = 21; + + /* + * draft-zauner-tls-aes-ocb-04 + */ + public const int AES_128_OCB_TAGLEN96 = 103; + public const int AES_256_OCB_TAGLEN96 = 104; + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/EncryptionAlgorithm.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/EncryptionAlgorithm.cs.meta new file mode 100644 index 0000000..d23a91a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/EncryptionAlgorithm.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 01c03ca5ae353b944aa492c4a491a65a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ExporterLabel.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ExporterLabel.cs new file mode 100644 index 0000000..12603f3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ExporterLabel.cs @@ -0,0 +1,37 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// RFC 5705 + public abstract class ExporterLabel + { + /* + * RFC 5246 + */ + public const string client_finished = "client finished"; + public const string server_finished = "server finished"; + public const string master_secret = "master secret"; + public const string key_expansion = "key expansion"; + + /* + * RFC 5216 + */ + public const string client_EAP_encryption = "client EAP encryption"; + + /* + * RFC 5281 + */ + public const string ttls_keying_material = "ttls keying material"; + public const string ttls_challenge = "ttls challenge"; + + /* + * RFC 5764 + */ + public const string dtls_srtp = "EXTRACTOR-dtls_srtp"; + + /* + * RFC 7627 + */ + public static readonly string extended_master_secret = "extended master secret"; + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ExporterLabel.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ExporterLabel.cs.meta new file mode 100644 index 0000000..502c815 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ExporterLabel.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: aaedfcd3cc553bd4eb90eaa7acbd4b58 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ExtensionType.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ExtensionType.cs new file mode 100644 index 0000000..f17210b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ExtensionType.cs @@ -0,0 +1,128 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class ExtensionType + { + /* + * RFC 2546 2.3. + */ + public const int server_name = 0; + public const int max_fragment_length = 1; + public const int client_certificate_url = 2; + public const int trusted_ca_keys = 3; + public const int truncated_hmac = 4; + public const int status_request = 5; + + /* + * RFC 4681 + */ + public const int user_mapping = 6; + + /* + * RFC 5878 + */ + public const int client_authz = 7; + public const int server_authz = 8; + + /* + * RFC RFC6091 + */ + public const int cert_type = 9; + + /* + * draft-ietf-tls-negotiated-ff-dhe-10 + */ + public const int supported_groups = 10; + + /* + * RFC 4492 5.1. + */ + [Obsolete("Use 'supported_groups' instead")] + public const int elliptic_curves = supported_groups; + public const int ec_point_formats = 11; + + /* + * RFC 5054 2.8.1. + */ + public const int srp = 12; + + /* + * RFC 5246 7.4.1.4. + */ + public const int signature_algorithms = 13; + + /* + * RFC 5764 9. + */ + public const int use_srtp = 14; + + /* + * RFC 6520 6. + */ + public const int heartbeat = 15; + + /* + * RFC 7301 + */ + public const int application_layer_protocol_negotiation = 16; + + /* + * RFC 6961 + */ + public const int status_request_v2 = 17; + + /* + * RFC 6962 + */ + public const int signed_certificate_timestamp = 18; + + /* + * RFC 7250 + */ + public const int client_certificate_type = 19; + public const int server_certificate_type = 20; + + /* + * RFC 7685 + */ + public const int padding = 21; + + /* + * RFC 7366 + */ + public const int encrypt_then_mac = 22; + + /* + * RFC 7627 + */ + public const int extended_master_secret = 23; + + /* + * draft-ietf-tokbind-negotiation-08 + */ + public static readonly int DRAFT_token_binding = 24; + + /* + * RFC 7924 + */ + public const int cached_info = 25; + + /* + * RFC 5077 7. + */ + public const int session_ticket = 35; + + /* + * draft-ietf-tls-negotiated-ff-dhe-01 + * + * WARNING: Placeholder value; the real value is TBA + */ + public static readonly int negotiated_ff_dhe_groups = 101; + + /* + * RFC 5746 3.2. + */ + public const int renegotiation_info = 0xff01; + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ExtensionType.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ExtensionType.cs.meta new file mode 100644 index 0000000..28f00ae --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ExtensionType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 01f628558a1d31141b85cca9442713e2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/FiniteFieldDheGroup.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/FiniteFieldDheGroup.cs new file mode 100644 index 0000000..4375049 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/FiniteFieldDheGroup.cs @@ -0,0 +1,21 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /* + * draft-ietf-tls-negotiated-ff-dhe-01 + */ + public abstract class FiniteFieldDheGroup + { + public const byte ffdhe2432 = 0; + public const byte ffdhe3072 = 1; + public const byte ffdhe4096 = 2; + public const byte ffdhe6144 = 3; + public const byte ffdhe8192 = 4; + + public static bool IsValid(byte group) + { + return group >= ffdhe2432 && group <= ffdhe8192; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/FiniteFieldDheGroup.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/FiniteFieldDheGroup.cs.meta new file mode 100644 index 0000000..2bcaf24 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/FiniteFieldDheGroup.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6fe6a68601493114ca37da9bb224afbb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/HandshakeType.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/HandshakeType.cs new file mode 100644 index 0000000..e63042a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/HandshakeType.cs @@ -0,0 +1,40 @@ +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class HandshakeType + { + /* + * RFC 2246 7.4 + */ + public const byte hello_request = 0; + public const byte client_hello = 1; + public const byte server_hello = 2; + public const byte certificate = 11; + public const byte server_key_exchange = 12; + public const byte certificate_request = 13; + public const byte server_hello_done = 14; + public const byte certificate_verify = 15; + public const byte client_key_exchange = 16; + public const byte finished = 20; + + /* + * RFC 3546 2.4 + */ + public const byte certificate_url = 21; + public const byte certificate_status = 22; + + /* + * (DTLS) RFC 4347 4.3.2 + */ + public const byte hello_verify_request = 3; + + /* + * RFC 4680 + */ + public const byte supplemental_data = 23; + + /* + * RFC 5077 + */ + public const byte session_ticket = 4; + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/HandshakeType.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/HandshakeType.cs.meta new file mode 100644 index 0000000..6b3c01d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/HandshakeType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 78b70f739ce7d8c4eb55a9ca0329af91 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/HashAlgorithm.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/HashAlgorithm.cs new file mode 100644 index 0000000..a6b42d4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/HashAlgorithm.cs @@ -0,0 +1,65 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// RFC 5246 7.4.1.4.1 + public abstract class HashAlgorithm + { + public const byte none = 0; + public const byte md5 = 1; + public const byte sha1 = 2; + public const byte sha224 = 3; + public const byte sha256 = 4; + public const byte sha384 = 5; + public const byte sha512 = 6; + + public static string GetName(byte hashAlgorithm) + { + switch (hashAlgorithm) + { + case none: + return "none"; + case md5: + return "md5"; + case sha1: + return "sha1"; + case sha224: + return "sha224"; + case sha256: + return "sha256"; + case sha384: + return "sha384"; + case sha512: + return "sha512"; + default: + return "UNKNOWN"; + } + } + + public static string GetText(byte hashAlgorithm) + { + return GetName(hashAlgorithm) + "(" + hashAlgorithm + ")"; + } + + public static bool IsPrivate(byte hashAlgorithm) + { + return 224 <= hashAlgorithm && hashAlgorithm <= 255; + } + + public static bool IsRecognized(byte hashAlgorithm) + { + switch (hashAlgorithm) + { + case md5: + case sha1: + case sha224: + case sha256: + case sha384: + case sha512: + return true; + default: + return false; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/HashAlgorithm.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/HashAlgorithm.cs.meta new file mode 100644 index 0000000..6f737d2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/HashAlgorithm.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 72495a19e96397345998e2c427ccffc0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/HeartbeatExtension.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/HeartbeatExtension.cs new file mode 100644 index 0000000..0498372 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/HeartbeatExtension.cs @@ -0,0 +1,52 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class HeartbeatExtension + { + protected readonly byte mMode; + + public HeartbeatExtension(byte mode) + { + if (!HeartbeatMode.IsValid(mode)) + throw new ArgumentException("not a valid HeartbeatMode value", "mode"); + + this.mMode = mode; + } + + public virtual byte Mode + { + get { return mMode; } + } + + /** + * Encode this {@link HeartbeatExtension} to a {@link Stream}. + * + * @param output + * the {@link Stream} to encode to. + * @throws IOException + */ + public virtual void Encode(Stream output) + { + TlsUtilities.WriteUint8(mMode, output); + } + + /** + * Parse a {@link HeartbeatExtension} from a {@link Stream}. + * + * @param input + * the {@link Stream} to parse from. + * @return a {@link HeartbeatExtension} object. + * @throws IOException + */ + public static HeartbeatExtension Parse(Stream input) + { + byte mode = TlsUtilities.ReadUint8(input); + if (!HeartbeatMode.IsValid(mode)) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + return new HeartbeatExtension(mode); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/HeartbeatExtension.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/HeartbeatExtension.cs.meta new file mode 100644 index 0000000..86b423a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/HeartbeatExtension.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5fba8ce5934eedb4b86dbbf37f411e65 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/HeartbeatMessage.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/HeartbeatMessage.cs new file mode 100644 index 0000000..3f22f7e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/HeartbeatMessage.cs @@ -0,0 +1,109 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class HeartbeatMessage + { + protected readonly byte mType; + protected readonly byte[] mPayload; + protected readonly int mPaddingLength; + + public HeartbeatMessage(byte type, byte[] payload, int paddingLength) + { + if (!HeartbeatMessageType.IsValid(type)) + throw new ArgumentException("not a valid HeartbeatMessageType value", "type"); + if (payload == null || payload.Length >= (1 << 16)) + throw new ArgumentException("must have length < 2^16", "payload"); + if (paddingLength < 16) + throw new ArgumentException("must be at least 16", "paddingLength"); + + this.mType = type; + this.mPayload = payload; + this.mPaddingLength = paddingLength; + } + + /** + * Encode this {@link HeartbeatMessage} to a {@link Stream}. + * + * @param output + * the {@link Stream} to encode to. + * @throws IOException + */ + public virtual void Encode(TlsContext context, Stream output) + { + TlsUtilities.WriteUint8(mType, output); + + TlsUtilities.CheckUint16(mPayload.Length); + TlsUtilities.WriteUint16(mPayload.Length, output); + output.Write(mPayload, 0, mPayload.Length); + + byte[] padding = new byte[mPaddingLength]; + context.NonceRandomGenerator.NextBytes(padding); + output.Write(padding, 0, padding.Length); + } + + /** + * Parse a {@link HeartbeatMessage} from a {@link Stream}. + * + * @param input + * the {@link Stream} to parse from. + * @return a {@link HeartbeatMessage} object. + * @throws IOException + */ + public static HeartbeatMessage Parse(Stream input) + { + byte type = TlsUtilities.ReadUint8(input); + if (!HeartbeatMessageType.IsValid(type)) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + int payload_length = TlsUtilities.ReadUint16(input); + + PayloadBuffer buf = new PayloadBuffer(); + Streams.PipeAll(input, buf); + + byte[] payload = buf.ToTruncatedByteArray(payload_length); + if (payload == null) + { + /* + * RFC 6520 4. If the payload_length of a received HeartbeatMessage is too large, the + * received HeartbeatMessage MUST be discarded silently. + */ + return null; + } + + TlsUtilities.CheckUint16(buf.Length); + int padding_length = (int)buf.Length - payload.Length; + + /* + * RFC 6520 4. The padding of a received HeartbeatMessage message MUST be ignored + */ + return new HeartbeatMessage(type, payload, padding_length); + } + + internal class PayloadBuffer + : MemoryStream + { + internal byte[] ToTruncatedByteArray(int payloadLength) + { + /* + * RFC 6520 4. The padding_length MUST be at least 16. + */ + int minimumCount = payloadLength + 16; + if (Length < minimumCount) + return null; + +#if PORTABLE + byte[] buf = ToArray(); +#else + byte[] buf = GetBuffer(); +#endif + + return Arrays.CopyOf(buf, payloadLength); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/HeartbeatMessage.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/HeartbeatMessage.cs.meta new file mode 100644 index 0000000..a8e694c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/HeartbeatMessage.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b7d828556a4be9c43a5c89b2c05864e9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/HeartbeatMessageType.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/HeartbeatMessageType.cs new file mode 100644 index 0000000..57a4b86 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/HeartbeatMessageType.cs @@ -0,0 +1,18 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /* + * RFC 6520 3. + */ + public abstract class HeartbeatMessageType + { + public const byte heartbeat_request = 1; + public const byte heartbeat_response = 2; + + public static bool IsValid(byte heartbeatMessageType) + { + return heartbeatMessageType >= heartbeat_request && heartbeatMessageType <= heartbeat_response; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/HeartbeatMessageType.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/HeartbeatMessageType.cs.meta new file mode 100644 index 0000000..f932ff9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/HeartbeatMessageType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f27ce6788f518244ea683cd28025f053 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/HeartbeatMode.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/HeartbeatMode.cs new file mode 100644 index 0000000..f1570a8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/HeartbeatMode.cs @@ -0,0 +1,18 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /* + * RFC 6520 + */ + public abstract class HeartbeatMode + { + public const byte peer_allowed_to_send = 1; + public const byte peer_not_allowed_to_send = 2; + + public static bool IsValid(byte heartbeatMode) + { + return heartbeatMode >= peer_allowed_to_send && heartbeatMode <= peer_not_allowed_to_send; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/HeartbeatMode.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/HeartbeatMode.cs.meta new file mode 100644 index 0000000..7755b19 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/HeartbeatMode.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2f495c7478bfd034ab44a324b45687b1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/KeyExchangeAlgorithm.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/KeyExchangeAlgorithm.cs new file mode 100644 index 0000000..9b1b3ba --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/KeyExchangeAlgorithm.cs @@ -0,0 +1,54 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// RFC 2246 + /// + /// Note that the values here are implementation-specific and arbitrary. It is recommended not to + /// depend on the particular values (e.g. serialization). + /// + public abstract class KeyExchangeAlgorithm + { + public const int NULL = 0; + public const int RSA = 1; + public const int RSA_EXPORT = 2; + public const int DHE_DSS = 3; + public const int DHE_DSS_EXPORT = 4; + public const int DHE_RSA = 5; + public const int DHE_RSA_EXPORT = 6; + public const int DH_DSS = 7; + public const int DH_DSS_EXPORT = 8; + public const int DH_RSA = 9; + public const int DH_RSA_EXPORT = 10; + public const int DH_anon = 11; + public const int DH_anon_EXPORT = 12; + + /* + * RFC 4279 + */ + public const int PSK = 13; + public const int DHE_PSK = 14; + public const int RSA_PSK = 15; + + /* + * RFC 4429 + */ + public const int ECDH_ECDSA = 16; + public const int ECDHE_ECDSA = 17; + public const int ECDH_RSA = 18; + public const int ECDHE_RSA = 19; + public const int ECDH_anon = 20; + + /* + * RFC 5054 + */ + public const int SRP = 21; + public const int SRP_DSS = 22; + public const int SRP_RSA = 23; + + /* + * RFC 5489 + */ + public const int ECDHE_PSK = 24; + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/KeyExchangeAlgorithm.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/KeyExchangeAlgorithm.cs.meta new file mode 100644 index 0000000..07d8942 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/KeyExchangeAlgorithm.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1f570d07eab68e54eb2881ac07e2335c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/MacAlgorithm.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/MacAlgorithm.cs new file mode 100644 index 0000000..e4aa88d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/MacAlgorithm.cs @@ -0,0 +1,25 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// RFC 2246 + /// + /// Note that the values here are implementation-specific and arbitrary. It is recommended not to + /// depend on the particular values (e.g. serialization). + /// + public abstract class MacAlgorithm + { + public const int cls_null = 0; + public const int md5 = 1; + public const int sha = 2; + + /* + * RFC 5246 + */ + public const int hmac_md5 = md5; + public const int hmac_sha1 = sha; + public const int hmac_sha256 = 3; + public const int hmac_sha384 = 4; + public const int hmac_sha512 = 5; + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/MacAlgorithm.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/MacAlgorithm.cs.meta new file mode 100644 index 0000000..a75efbc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/MacAlgorithm.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a5ce7302e6346a94c920855d381e9afc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/MaxFragmentLength.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/MaxFragmentLength.cs new file mode 100644 index 0000000..5b10b35 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/MaxFragmentLength.cs @@ -0,0 +1,20 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class MaxFragmentLength + { + /* + * RFC 3546 3.2. + */ + public const byte pow2_9 = 1; + public const byte pow2_10 = 2; + public const byte pow2_11 = 3; + public const byte pow2_12 = 4; + + public static bool IsValid(byte maxFragmentLength) + { + return maxFragmentLength >= pow2_9 && maxFragmentLength <= pow2_12; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/MaxFragmentLength.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/MaxFragmentLength.cs.meta new file mode 100644 index 0000000..2bef0db --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/MaxFragmentLength.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b59ea9bf0ecb2b04f99d044d42f5483f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/NameType.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/NameType.cs new file mode 100644 index 0000000..7821642 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/NameType.cs @@ -0,0 +1,17 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class NameType + { + /* + * RFC 3546 3.1. + */ + public const byte host_name = 0; + + public static bool IsValid(byte nameType) + { + return nameType == host_name; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/NameType.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/NameType.cs.meta new file mode 100644 index 0000000..0a72ae3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/NameType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: aa6e2766505f54a4da3f1435a7e99d66 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/NamedCurve.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/NamedCurve.cs new file mode 100644 index 0000000..b8aa0ec --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/NamedCurve.cs @@ -0,0 +1,77 @@ +using System; + +using Org.BouncyCastle.Asn1.Sec; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// + /// RFC 4492 5.1.1 + /// The named curves defined here are those specified in SEC 2 [13]. Note that many of + /// these curves are also recommended in ANSI X9.62 [7] and FIPS 186-2 [11]. Values 0xFE00 + /// through 0xFEFF are reserved for private use. Values 0xFF01 and 0xFF02 indicate that the + /// client supports arbitrary prime and characteristic-2 curves, respectively (the curve + /// parameters must be encoded explicitly in ECParameters). + /// + public abstract class NamedCurve + { + public const int sect163k1 = 1; + public const int sect163r1 = 2; + public const int sect163r2 = 3; + public const int sect193r1 = 4; + public const int sect193r2 = 5; + public const int sect233k1 = 6; + public const int sect233r1 = 7; + public const int sect239k1 = 8; + public const int sect283k1 = 9; + public const int sect283r1 = 10; + public const int sect409k1 = 11; + public const int sect409r1 = 12; + public const int sect571k1 = 13; + public const int sect571r1 = 14; + public const int secp160k1 = 15; + public const int secp160r1 = 16; + public const int secp160r2 = 17; + public const int secp192k1 = 18; + public const int secp192r1 = 19; + public const int secp224k1 = 20; + public const int secp224r1 = 21; + public const int secp256k1 = 22; + public const int secp256r1 = 23; + public const int secp384r1 = 24; + public const int secp521r1 = 25; + + /* + * RFC 7027 + */ + public const int brainpoolP256r1 = 26; + public const int brainpoolP384r1 = 27; + public const int brainpoolP512r1 = 28; + + /* + * reserved (0xFE00..0xFEFF) + */ + + public const int arbitrary_explicit_prime_curves = 0xFF01; + public const int arbitrary_explicit_char2_curves = 0xFF02; + + public static bool IsValid(int namedCurve) + { + return (namedCurve >= sect163k1 && namedCurve <= brainpoolP512r1) + || (namedCurve >= arbitrary_explicit_prime_curves && namedCurve <= arbitrary_explicit_char2_curves); + } + + public static bool RefersToASpecificNamedCurve(int namedCurve) + { + switch (namedCurve) + { + case arbitrary_explicit_prime_curves: + case arbitrary_explicit_char2_curves: + return false; + default: + return true; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/NamedCurve.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/NamedCurve.cs.meta new file mode 100644 index 0000000..c3ef8ab --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/NamedCurve.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 63fbb424c09813246be83110d1ba3c3f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/NewSessionTicket.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/NewSessionTicket.cs new file mode 100644 index 0000000..a84026b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/NewSessionTicket.cs @@ -0,0 +1,53 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class NewSessionTicket + { + protected readonly long mTicketLifetimeHint; + protected readonly byte[] mTicket; + + public NewSessionTicket(long ticketLifetimeHint, byte[] ticket) + { + this.mTicketLifetimeHint = ticketLifetimeHint; + this.mTicket = ticket; + } + + public virtual long TicketLifetimeHint + { + get { return mTicketLifetimeHint; } + } + + public virtual byte[] Ticket + { + get { return mTicket; } + } + + /** + * Encode this {@link NewSessionTicket} to a {@link Stream}. + * + * @param output the {@link Stream} to encode to. + * @throws IOException + */ + public virtual void Encode(Stream output) + { + TlsUtilities.WriteUint32(mTicketLifetimeHint, output); + TlsUtilities.WriteOpaque16(mTicket, output); + } + + /** + * Parse a {@link NewSessionTicket} from a {@link Stream}. + * + * @param input the {@link Stream} to parse from. + * @return a {@link NewSessionTicket} object. + * @throws IOException + */ + public static NewSessionTicket Parse(Stream input) + { + long ticketLifetimeHint = TlsUtilities.ReadUint32(input); + byte[] ticket = TlsUtilities.ReadOpaque16(input); + return new NewSessionTicket(ticketLifetimeHint, ticket); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/NewSessionTicket.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/NewSessionTicket.cs.meta new file mode 100644 index 0000000..6046fa3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/NewSessionTicket.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 44b65c2ba1a32a747958a22cdb86f731 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/OcspStatusRequest.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/OcspStatusRequest.cs new file mode 100644 index 0000000..d9203a3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/OcspStatusRequest.cs @@ -0,0 +1,131 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Ocsp; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /** + * RFC 3546 3.6 + */ + public class OcspStatusRequest + { + protected readonly IList mResponderIDList; + protected readonly X509Extensions mRequestExtensions; + + /** + * @param responderIDList + * an {@link IList} of {@link ResponderID}, specifying the list of trusted OCSP + * responders. An empty list has the special meaning that the responders are + * implicitly known to the server - e.g., by prior arrangement. + * @param requestExtensions + * OCSP request extensions. A null value means that there are no extensions. + */ + public OcspStatusRequest(IList responderIDList, X509Extensions requestExtensions) + { + this.mResponderIDList = responderIDList; + this.mRequestExtensions = requestExtensions; + } + + /** + * @return an {@link IList} of {@link ResponderID} + */ + public virtual IList ResponderIDList + { + get { return mResponderIDList; } + } + + /** + * @return OCSP request extensions + */ + public virtual X509Extensions RequestExtensions + { + get { return mRequestExtensions; } + } + + /** + * Encode this {@link OcspStatusRequest} to a {@link Stream}. + * + * @param output + * the {@link Stream} to encode to. + * @throws IOException + */ + public virtual void Encode(Stream output) + { + if (mResponderIDList == null || mResponderIDList.Count < 1) + { + TlsUtilities.WriteUint16(0, output); + } + else + { + MemoryStream buf = new MemoryStream(); + for (int i = 0; i < mResponderIDList.Count; ++i) + { + ResponderID responderID = (ResponderID)mResponderIDList[i]; + byte[] derEncoding = responderID.GetEncoded(Asn1Encodable.Der); + TlsUtilities.WriteOpaque16(derEncoding, buf); + } + TlsUtilities.CheckUint16(buf.Length); + TlsUtilities.WriteUint16((int)buf.Length, output); + Streams.WriteBufTo(buf, output); + } + + if (mRequestExtensions == null) + { + TlsUtilities.WriteUint16(0, output); + } + else + { + byte[] derEncoding = mRequestExtensions.GetEncoded(Asn1Encodable.Der); + TlsUtilities.CheckUint16(derEncoding.Length); + TlsUtilities.WriteUint16(derEncoding.Length, output); + output.Write(derEncoding, 0, derEncoding.Length); + } + } + + /** + * Parse a {@link OcspStatusRequest} from a {@link Stream}. + * + * @param input + * the {@link Stream} to parse from. + * @return an {@link OcspStatusRequest} object. + * @throws IOException + */ + public static OcspStatusRequest Parse(Stream input) + { + IList responderIDList = Platform.CreateArrayList(); + { + int length = TlsUtilities.ReadUint16(input); + if (length > 0) + { + byte[] data = TlsUtilities.ReadFully(length, input); + MemoryStream buf = new MemoryStream(data, false); + do + { + byte[] derEncoding = TlsUtilities.ReadOpaque16(buf); + ResponderID responderID = ResponderID.GetInstance(TlsUtilities.ReadDerObject(derEncoding)); + responderIDList.Add(responderID); + } + while (buf.Position < buf.Length); + } + } + + X509Extensions requestExtensions = null; + { + int length = TlsUtilities.ReadUint16(input); + if (length > 0) + { + byte[] derEncoding = TlsUtilities.ReadFully(length, input); + requestExtensions = X509Extensions.GetInstance(TlsUtilities.ReadDerObject(derEncoding)); + } + } + + return new OcspStatusRequest(responderIDList, requestExtensions); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/OcspStatusRequest.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/OcspStatusRequest.cs.meta new file mode 100644 index 0000000..fbc0451 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/OcspStatusRequest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 001030e8ddf5ea24ebbbe9ff3dcda4b6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/PrfAlgorithm.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/PrfAlgorithm.cs new file mode 100644 index 0000000..871241b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/PrfAlgorithm.cs @@ -0,0 +1,24 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// RFC 5246 + /// + /// Note that the values here are implementation-specific and arbitrary. It is recommended not to + /// depend on the particular values (e.g. serialization). + /// + public abstract class PrfAlgorithm + { + /* + * Placeholder to refer to the legacy TLS algorithm + */ + public const int tls_prf_legacy = 0; + + public const int tls_prf_sha256 = 1; + + /* + * Implied by RFC 5288 + */ + public const int tls_prf_sha384 = 2; + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/PrfAlgorithm.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/PrfAlgorithm.cs.meta new file mode 100644 index 0000000..e28e90f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/PrfAlgorithm.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1c9a6fce4dba5094f87331d67e03ec49 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ProtocolVersion.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ProtocolVersion.cs new file mode 100644 index 0000000..b0d5518 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ProtocolVersion.cs @@ -0,0 +1,159 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public sealed class ProtocolVersion + { + public static readonly ProtocolVersion SSLv3 = new ProtocolVersion(0x0300, "SSL 3.0"); + public static readonly ProtocolVersion TLSv10 = new ProtocolVersion(0x0301, "TLS 1.0"); + public static readonly ProtocolVersion TLSv11 = new ProtocolVersion(0x0302, "TLS 1.1"); + public static readonly ProtocolVersion TLSv12 = new ProtocolVersion(0x0303, "TLS 1.2"); + public static readonly ProtocolVersion DTLSv10 = new ProtocolVersion(0xFEFF, "DTLS 1.0"); + public static readonly ProtocolVersion DTLSv12 = new ProtocolVersion(0xFEFD, "DTLS 1.2"); + + private readonly int version; + private readonly String name; + + private ProtocolVersion(int v, String name) + { + this.version = v & 0xffff; + this.name = name; + } + + public int FullVersion + { + get { return version; } + } + + public int MajorVersion + { + get { return version >> 8; } + } + + public int MinorVersion + { + get { return version & 0xff; } + } + + public bool IsDtls + { + get { return MajorVersion == 0xFE; } + } + + public bool IsSsl + { + get { return this == SSLv3; } + } + + public bool IsTls + { + get { return MajorVersion == 0x03; } + } + + public ProtocolVersion GetEquivalentTLSVersion() + { + if (!IsDtls) + { + return this; + } + if (this == DTLSv10) + { + return TLSv11; + } + return TLSv12; + } + + public bool IsEqualOrEarlierVersionOf(ProtocolVersion version) + { + if (MajorVersion != version.MajorVersion) + { + return false; + } + int diffMinorVersion = version.MinorVersion - MinorVersion; + return IsDtls ? diffMinorVersion <= 0 : diffMinorVersion >= 0; + } + + public bool IsLaterVersionOf(ProtocolVersion version) + { + if (MajorVersion != version.MajorVersion) + { + return false; + } + int diffMinorVersion = version.MinorVersion - MinorVersion; + return IsDtls ? diffMinorVersion > 0 : diffMinorVersion < 0; + } + + public override bool Equals(object other) + { + return this == other || (other is ProtocolVersion && Equals((ProtocolVersion)other)); + } + + public bool Equals(ProtocolVersion other) + { + return other != null && this.version == other.version; + } + + public override int GetHashCode() + { + return version; + } + + /// + public static ProtocolVersion Get(int major, int minor) + { + switch (major) + { + case 0x03: + { + switch (minor) + { + case 0x00: + return SSLv3; + case 0x01: + return TLSv10; + case 0x02: + return TLSv11; + case 0x03: + return TLSv12; + } + return GetUnknownVersion(major, minor, "TLS"); + } + case 0xFE: + { + switch (minor) + { + case 0xFF: + return DTLSv10; + case 0xFE: + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + case 0xFD: + return DTLSv12; + } + return GetUnknownVersion(major, minor, "DTLS"); + } + default: + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + } + } + + public override string ToString() + { + return name; + } + + private static ProtocolVersion GetUnknownVersion(int major, int minor, string prefix) + { + TlsUtilities.CheckUint8(major); + TlsUtilities.CheckUint8(minor); + + int v = (major << 8) | minor; + String hex = Platform.ToUpperInvariant(Convert.ToString(0x10000 | v, 16).Substring(1)); + return new ProtocolVersion(v, prefix + " 0x" + hex); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ProtocolVersion.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ProtocolVersion.cs.meta new file mode 100644 index 0000000..b3563a5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ProtocolVersion.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a6ff1bb3983ab77429d944797b9544c5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/PskTlsClient.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/PskTlsClient.cs new file mode 100644 index 0000000..d5fa435 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/PskTlsClient.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class PskTlsClient + : AbstractTlsClient + { + protected TlsDHVerifier mDHVerifier; + protected TlsPskIdentity mPskIdentity; + + public PskTlsClient(TlsPskIdentity pskIdentity) + : this(new DefaultTlsCipherFactory(), pskIdentity) + { + } + + public PskTlsClient(TlsCipherFactory cipherFactory, TlsPskIdentity pskIdentity) + : this(cipherFactory, new DefaultTlsDHVerifier(), pskIdentity) + { + } + + public PskTlsClient(TlsCipherFactory cipherFactory, TlsDHVerifier dhVerifier, TlsPskIdentity pskIdentity) + : base(cipherFactory) + { + this.mDHVerifier = dhVerifier; + this.mPskIdentity = pskIdentity; + } + + public override int[] GetCipherSuites() + { + return new int[] + { + CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, + CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, + }; + } + + public override TlsKeyExchange GetKeyExchange() + { + int keyExchangeAlgorithm = TlsUtilities.GetKeyExchangeAlgorithm(mSelectedCipherSuite); + + switch (keyExchangeAlgorithm) + { + case KeyExchangeAlgorithm.DHE_PSK: + case KeyExchangeAlgorithm.ECDHE_PSK: + case KeyExchangeAlgorithm.PSK: + case KeyExchangeAlgorithm.RSA_PSK: + return CreatePskKeyExchange(keyExchangeAlgorithm); + + default: + /* + * Note: internal error here; the TlsProtocol implementation verifies that the + * server-selected cipher suite was in the list of client-offered cipher suites, so if + * we now can't produce an implementation, we shouldn't have offered it! + */ + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + public override TlsAuthentication GetAuthentication() + { + /* + * Note: This method is not called unless a server certificate is sent, which may be the + * case e.g. for RSA_PSK key exchange. + */ + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + protected virtual TlsKeyExchange CreatePskKeyExchange(int keyExchange) + { + return new TlsPskKeyExchange(keyExchange, mSupportedSignatureAlgorithms, mPskIdentity, null, mDHVerifier, null, + mNamedCurves, mClientECPointFormats, mServerECPointFormats); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/PskTlsClient.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/PskTlsClient.cs.meta new file mode 100644 index 0000000..845e31b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/PskTlsClient.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c677c75ed0704b844b8b93bd97c44928 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/PskTlsServer.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/PskTlsServer.cs new file mode 100644 index 0000000..a377842 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/PskTlsServer.cs @@ -0,0 +1,93 @@ +using System; + +using Org.BouncyCastle.Crypto.Agreement; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class PskTlsServer + : AbstractTlsServer + { + protected TlsPskIdentityManager mPskIdentityManager; + + public PskTlsServer(TlsPskIdentityManager pskIdentityManager) + : this(new DefaultTlsCipherFactory(), pskIdentityManager) + { + } + + public PskTlsServer(TlsCipherFactory cipherFactory, TlsPskIdentityManager pskIdentityManager) + : base(cipherFactory) + { + this.mPskIdentityManager = pskIdentityManager; + } + + protected virtual TlsEncryptionCredentials GetRsaEncryptionCredentials() + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + protected virtual DHParameters GetDHParameters() + { + return DHStandardGroups.rfc7919_ffdhe2048; + } + + protected override int[] GetCipherSuites() + { + return new int[] + { + CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, + CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, + CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA256, + CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA + }; + } + + public override TlsCredentials GetCredentials() + { + int keyExchangeAlgorithm = TlsUtilities.GetKeyExchangeAlgorithm(mSelectedCipherSuite); + + switch (keyExchangeAlgorithm) + { + case KeyExchangeAlgorithm.DHE_PSK: + case KeyExchangeAlgorithm.ECDHE_PSK: + case KeyExchangeAlgorithm.PSK: + return null; + + case KeyExchangeAlgorithm.RSA_PSK: + return GetRsaEncryptionCredentials(); + + default: + /* Note: internal error here; selected a key exchange we don't implement! */ + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + public override TlsKeyExchange GetKeyExchange() + { + int keyExchangeAlgorithm = TlsUtilities.GetKeyExchangeAlgorithm(mSelectedCipherSuite); + + switch (keyExchangeAlgorithm) + { + case KeyExchangeAlgorithm.DHE_PSK: + case KeyExchangeAlgorithm.ECDHE_PSK: + case KeyExchangeAlgorithm.PSK: + case KeyExchangeAlgorithm.RSA_PSK: + return CreatePskKeyExchange(keyExchangeAlgorithm); + + default: + /* + * Note: internal error here; the TlsProtocol implementation verifies that the + * server-selected cipher suite was in the list of client-offered cipher suites, so if + * we now can't produce an implementation, we shouldn't have offered it! + */ + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + protected virtual TlsKeyExchange CreatePskKeyExchange(int keyExchange) + { + return new TlsPskKeyExchange(keyExchange, mSupportedSignatureAlgorithms, null, mPskIdentityManager, + null, GetDHParameters(), mNamedCurves, mClientECPointFormats, mServerECPointFormats); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/PskTlsServer.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/PskTlsServer.cs.meta new file mode 100644 index 0000000..07bc721 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/PskTlsServer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 13bd6446251da79478bda5db515cd360 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/RecordStream.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/RecordStream.cs new file mode 100644 index 0000000..5d556ad --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/RecordStream.cs @@ -0,0 +1,412 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// An implementation of the TLS 1.0/1.1/1.2 record layer, allowing downgrade to SSLv3. + internal class RecordStream + { + private const int DEFAULT_PLAINTEXT_LIMIT = (1 << 14); + + internal const int TLS_HEADER_SIZE = 5; + internal const int TLS_HEADER_TYPE_OFFSET = 0; + internal const int TLS_HEADER_VERSION_OFFSET = 1; + internal const int TLS_HEADER_LENGTH_OFFSET = 3; + + private TlsProtocol mHandler; + private Stream mInput; + private Stream mOutput; + private TlsCompression mPendingCompression = null, mReadCompression = null, mWriteCompression = null; + private TlsCipher mPendingCipher = null, mReadCipher = null, mWriteCipher = null; + private SequenceNumber mReadSeqNo = new SequenceNumber(), mWriteSeqNo = new SequenceNumber(); + private MemoryStream mBuffer = new MemoryStream(); + + private TlsHandshakeHash mHandshakeHash = null; + private readonly BaseOutputStream mHandshakeHashUpdater; + + private ProtocolVersion mReadVersion = null, mWriteVersion = null; + private bool mRestrictReadVersion = true; + + private int mPlaintextLimit, mCompressedLimit, mCiphertextLimit; + + internal RecordStream(TlsProtocol handler, Stream input, Stream output) + { + this.mHandler = handler; + this.mInput = input; + this.mOutput = output; + this.mReadCompression = new TlsNullCompression(); + this.mWriteCompression = this.mReadCompression; + this.mHandshakeHashUpdater = new HandshakeHashUpdateStream(this); + } + + internal virtual void Init(TlsContext context) + { + this.mReadCipher = new TlsNullCipher(context); + this.mWriteCipher = this.mReadCipher; + this.mHandshakeHash = new DeferredHash(); + this.mHandshakeHash.Init(context); + + SetPlaintextLimit(DEFAULT_PLAINTEXT_LIMIT); + } + + internal virtual int GetPlaintextLimit() + { + return mPlaintextLimit; + } + + internal virtual void SetPlaintextLimit(int plaintextLimit) + { + this.mPlaintextLimit = plaintextLimit; + this.mCompressedLimit = this.mPlaintextLimit + 1024; + this.mCiphertextLimit = this.mCompressedLimit + 1024; + } + + internal virtual ProtocolVersion ReadVersion + { + get { return mReadVersion; } + set { this.mReadVersion = value; } + } + + internal virtual void SetWriteVersion(ProtocolVersion writeVersion) + { + this.mWriteVersion = writeVersion; + } + + /** + * RFC 5246 E.1. "Earlier versions of the TLS specification were not fully clear on what the + * record layer version number (TLSPlaintext.version) should contain when sending ClientHello + * (i.e., before it is known which version of the protocol will be employed). Thus, TLS servers + * compliant with this specification MUST accept any value {03,XX} as the record layer version + * number for ClientHello." + */ + internal virtual void SetRestrictReadVersion(bool enabled) + { + this.mRestrictReadVersion = enabled; + } + + internal virtual void SetPendingConnectionState(TlsCompression tlsCompression, TlsCipher tlsCipher) + { + this.mPendingCompression = tlsCompression; + this.mPendingCipher = tlsCipher; + } + + internal virtual void SentWriteCipherSpec() + { + if (mPendingCompression == null || mPendingCipher == null) + throw new TlsFatalAlert(AlertDescription.handshake_failure); + + this.mWriteCompression = this.mPendingCompression; + this.mWriteCipher = this.mPendingCipher; + this.mWriteSeqNo = new SequenceNumber(); + } + + internal virtual void ReceivedReadCipherSpec() + { + if (mPendingCompression == null || mPendingCipher == null) + throw new TlsFatalAlert(AlertDescription.handshake_failure); + + this.mReadCompression = this.mPendingCompression; + this.mReadCipher = this.mPendingCipher; + this.mReadSeqNo = new SequenceNumber(); + } + + internal virtual void FinaliseHandshake() + { + if (mReadCompression != mPendingCompression || mWriteCompression != mPendingCompression + || mReadCipher != mPendingCipher || mWriteCipher != mPendingCipher) + { + throw new TlsFatalAlert(AlertDescription.handshake_failure); + } + this.mPendingCompression = null; + this.mPendingCipher = null; + } + + internal virtual void CheckRecordHeader(byte[] recordHeader) + { + byte type = TlsUtilities.ReadUint8(recordHeader, TLS_HEADER_TYPE_OFFSET); + + /* + * RFC 5246 6. If a TLS implementation receives an unexpected record type, it MUST send an + * unexpected_message alert. + */ + CheckType(type, AlertDescription.unexpected_message); + + if (!mRestrictReadVersion) + { + int version = TlsUtilities.ReadVersionRaw(recordHeader, TLS_HEADER_VERSION_OFFSET); + if ((version & 0xffffff00) != 0x0300) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + else + { + ProtocolVersion version = TlsUtilities.ReadVersion(recordHeader, TLS_HEADER_VERSION_OFFSET); + if (mReadVersion == null) + { + // Will be set later in 'readRecord' + } + else if (!version.Equals(mReadVersion)) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + } + + int length = TlsUtilities.ReadUint16(recordHeader, TLS_HEADER_LENGTH_OFFSET); + + CheckLength(length, mCiphertextLimit, AlertDescription.record_overflow); + } + + internal virtual bool ReadRecord() + { + byte[] recordHeader = TlsUtilities.ReadAllOrNothing(TLS_HEADER_SIZE, mInput); + if (recordHeader == null) + return false; + + byte type = TlsUtilities.ReadUint8(recordHeader, TLS_HEADER_TYPE_OFFSET); + + /* + * RFC 5246 6. If a TLS implementation receives an unexpected record type, it MUST send an + * unexpected_message alert. + */ + CheckType(type, AlertDescription.unexpected_message); + + if (!mRestrictReadVersion) + { + int version = TlsUtilities.ReadVersionRaw(recordHeader, TLS_HEADER_VERSION_OFFSET); + if ((version & 0xffffff00) != 0x0300) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + else + { + ProtocolVersion version = TlsUtilities.ReadVersion(recordHeader, TLS_HEADER_VERSION_OFFSET); + if (mReadVersion == null) + { + mReadVersion = version; + } + else if (!version.Equals(mReadVersion)) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + } + + int length = TlsUtilities.ReadUint16(recordHeader, TLS_HEADER_LENGTH_OFFSET); + + CheckLength(length, mCiphertextLimit, AlertDescription.record_overflow); + + byte[] plaintext = DecodeAndVerify(type, mInput, length); + mHandler.ProcessRecord(type, plaintext, 0, plaintext.Length); + return true; + } + + internal virtual byte[] DecodeAndVerify(byte type, Stream input, int len) + { + byte[] buf = TlsUtilities.ReadFully(len, input); + + long seqNo = mReadSeqNo.NextValue(AlertDescription.unexpected_message); + byte[] decoded = mReadCipher.DecodeCiphertext(seqNo, type, buf, 0, buf.Length); + + CheckLength(decoded.Length, mCompressedLimit, AlertDescription.record_overflow); + + /* + * TODO 5246 6.2.2. Implementation note: Decompression functions are responsible for + * ensuring that messages cannot cause internal buffer overflows. + */ + Stream cOut = mReadCompression.Decompress(mBuffer); + if (cOut != mBuffer) + { + cOut.Write(decoded, 0, decoded.Length); + cOut.Flush(); + decoded = GetBufferContents(); + } + + /* + * RFC 5246 6.2.2. If the decompression function encounters a TLSCompressed.fragment that + * would decompress to a length in excess of 2^14 bytes, it should report a fatal + * decompression failure error. + */ + CheckLength(decoded.Length, mPlaintextLimit, AlertDescription.decompression_failure); + + /* + * RFC 5246 6.2.1 Implementations MUST NOT send zero-length fragments of Handshake, Alert, + * or ChangeCipherSpec content types. + */ + if (decoded.Length < 1 && type != ContentType.application_data) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + return decoded; + } + + internal virtual void WriteRecord(byte type, byte[] plaintext, int plaintextOffset, int plaintextLength) + { + // Never send anything until a valid ClientHello has been received + if (mWriteVersion == null) + return; + + /* + * RFC 5246 6. Implementations MUST NOT send record types not defined in this document + * unless negotiated by some extension. + */ + CheckType(type, AlertDescription.internal_error); + + /* + * RFC 5246 6.2.1 The length should not exceed 2^14. + */ + CheckLength(plaintextLength, mPlaintextLimit, AlertDescription.internal_error); + + /* + * RFC 5246 6.2.1 Implementations MUST NOT send zero-length fragments of Handshake, Alert, + * or ChangeCipherSpec content types. + */ + if (plaintextLength < 1 && type != ContentType.application_data) + throw new TlsFatalAlert(AlertDescription.internal_error); + + Stream cOut = mWriteCompression.Compress(mBuffer); + + long seqNo = mWriteSeqNo.NextValue(AlertDescription.internal_error); + + byte[] ciphertext; + if (cOut == mBuffer) + { + ciphertext = mWriteCipher.EncodePlaintext(seqNo, type, plaintext, plaintextOffset, plaintextLength); + } + else + { + cOut.Write(plaintext, plaintextOffset, plaintextLength); + cOut.Flush(); + byte[] compressed = GetBufferContents(); + + /* + * RFC 5246 6.2.2. Compression must be lossless and may not increase the content length + * by more than 1024 bytes. + */ + CheckLength(compressed.Length, plaintextLength + 1024, AlertDescription.internal_error); + + ciphertext = mWriteCipher.EncodePlaintext(seqNo, type, compressed, 0, compressed.Length); + } + + /* + * RFC 5246 6.2.3. The length may not exceed 2^14 + 2048. + */ + CheckLength(ciphertext.Length, mCiphertextLimit, AlertDescription.internal_error); + + byte[] record = new byte[ciphertext.Length + TLS_HEADER_SIZE]; + TlsUtilities.WriteUint8(type, record, TLS_HEADER_TYPE_OFFSET); + TlsUtilities.WriteVersion(mWriteVersion, record, TLS_HEADER_VERSION_OFFSET); + TlsUtilities.WriteUint16(ciphertext.Length, record, TLS_HEADER_LENGTH_OFFSET); + Array.Copy(ciphertext, 0, record, TLS_HEADER_SIZE, ciphertext.Length); + mOutput.Write(record, 0, record.Length); + mOutput.Flush(); + } + + internal virtual void NotifyHelloComplete() + { + this.mHandshakeHash = mHandshakeHash.NotifyPrfDetermined(); + } + + internal virtual TlsHandshakeHash HandshakeHash + { + get { return mHandshakeHash; } + } + + internal virtual Stream HandshakeHashUpdater + { + get { return mHandshakeHashUpdater; } + } + + internal virtual TlsHandshakeHash PrepareToFinish() + { + TlsHandshakeHash result = mHandshakeHash; + this.mHandshakeHash = mHandshakeHash.StopTracking(); + return result; + } + + internal virtual void SafeClose() + { + try + { + Platform.Dispose(mInput); + } + catch (IOException) + { + } + + try + { + Platform.Dispose(mOutput); + } + catch (IOException) + { + } + } + + internal virtual void Flush() + { + mOutput.Flush(); + } + + private byte[] GetBufferContents() + { + byte[] contents = mBuffer.ToArray(); + mBuffer.SetLength(0); + return contents; + } + + private static void CheckType(byte type, byte alertDescription) + { + switch (type) + { + case ContentType.application_data: + case ContentType.alert: + case ContentType.change_cipher_spec: + case ContentType.handshake: + //case ContentType.heartbeat: + break; + default: + throw new TlsFatalAlert(alertDescription); + } + } + + private static void CheckLength(int length, int limit, byte alertDescription) + { + if (length > limit) + throw new TlsFatalAlert(alertDescription); + } + + private class HandshakeHashUpdateStream + : BaseOutputStream + { + private readonly RecordStream mOuter; + public HandshakeHashUpdateStream(RecordStream mOuter) + { + this.mOuter = mOuter; + } + + public override void Write(byte[] buf, int off, int len) + { + mOuter.mHandshakeHash.BlockUpdate(buf, off, len); + } + } + + private class SequenceNumber + { + private long value = 0L; + private bool exhausted = false; + + internal long NextValue(byte alertDescription) + { + if (exhausted) + { + throw new TlsFatalAlert(alertDescription); + } + long result = value; + if (++value == 0) + { + exhausted = true; + } + return result; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/RecordStream.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/RecordStream.cs.meta new file mode 100644 index 0000000..c96e749 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/RecordStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 50fdbe0bcc5349644ba71949770b334d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SecurityParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SecurityParameters.cs new file mode 100644 index 0000000..f3ec701 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SecurityParameters.cs @@ -0,0 +1,108 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class SecurityParameters + { + internal int entity = -1; + internal int cipherSuite = -1; + internal byte compressionAlgorithm = CompressionMethod.cls_null; + internal int prfAlgorithm = -1; + internal int verifyDataLength = -1; + internal byte[] masterSecret = null; + internal byte[] clientRandom = null; + internal byte[] serverRandom = null; + internal byte[] sessionHash = null; + internal byte[] pskIdentity = null; + internal byte[] srpIdentity = null; + + // TODO Keep these internal, since it's maybe not the ideal place for them + internal short maxFragmentLength = -1; + internal bool truncatedHMac = false; + internal bool encryptThenMac = false; + internal bool extendedMasterSecret = false; + + internal virtual void Clear() + { + if (this.masterSecret != null) + { + Arrays.Fill(this.masterSecret, (byte)0); + this.masterSecret = null; + } + } + + /** + * @return {@link ConnectionEnd} + */ + public virtual int Entity + { + get { return entity; } + } + + /** + * @return {@link CipherSuite} + */ + public virtual int CipherSuite + { + get { return cipherSuite; } + } + + /** + * @return {@link CompressionMethod} + */ + public virtual byte CompressionAlgorithm + { + get { return compressionAlgorithm; } + } + + /** + * @return {@link PRFAlgorithm} + */ + public virtual int PrfAlgorithm + { + get { return prfAlgorithm; } + } + + public virtual int VerifyDataLength + { + get { return verifyDataLength; } + } + + public virtual byte[] MasterSecret + { + get { return masterSecret; } + } + + public virtual byte[] ClientRandom + { + get { return clientRandom; } + } + + public virtual byte[] ServerRandom + { + get { return serverRandom; } + } + + public virtual byte[] SessionHash + { + get { return sessionHash; } + } + + public virtual byte[] PskIdentity + { + get { return pskIdentity; } + } + + public virtual byte[] SrpIdentity + { + get { return srpIdentity; } + } + + public virtual bool IsExtendedMasterSecret + { + get { return extendedMasterSecret; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SecurityParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SecurityParameters.cs.meta new file mode 100644 index 0000000..92e5542 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SecurityParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 91c10e87e5af9ce41b8f60a112778031 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ServerName.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ServerName.cs new file mode 100644 index 0000000..45d18b7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ServerName.cs @@ -0,0 +1,105 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class ServerName + { + protected readonly byte mNameType; + protected readonly object mName; + + public ServerName(byte nameType, object name) + { + if (!IsCorrectType(nameType, name)) + throw new ArgumentException("not an instance of the correct type", "name"); + + this.mNameType = nameType; + this.mName = name; + } + + public virtual byte NameType + { + get { return mNameType; } + } + + public virtual object Name + { + get { return mName; } + } + + public virtual string GetHostName() + { + if (!IsCorrectType(Tls.NameType.host_name, mName)) + throw new InvalidOperationException("'name' is not a HostName string"); + + return (string)mName; + } + + /** + * Encode this {@link ServerName} to a {@link Stream}. + * + * @param output + * the {@link Stream} to encode to. + * @throws IOException + */ + public virtual void Encode(Stream output) + { + TlsUtilities.WriteUint8(mNameType, output); + + switch (mNameType) + { + case Tls.NameType.host_name: + byte[] asciiEncoding = Strings.ToAsciiByteArray((string)mName); + if (asciiEncoding.Length < 1) + throw new TlsFatalAlert(AlertDescription.internal_error); + TlsUtilities.WriteOpaque16(asciiEncoding, output); + break; + default: + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + /** + * Parse a {@link ServerName} from a {@link Stream}. + * + * @param input + * the {@link Stream} to parse from. + * @return a {@link ServerName} object. + * @throws IOException + */ + public static ServerName Parse(Stream input) + { + byte name_type = TlsUtilities.ReadUint8(input); + object name; + + switch (name_type) + { + case Tls.NameType.host_name: + { + byte[] asciiEncoding = TlsUtilities.ReadOpaque16(input); + if (asciiEncoding.Length < 1) + throw new TlsFatalAlert(AlertDescription.decode_error); + name = Strings.FromAsciiByteArray(asciiEncoding); + break; + } + default: + throw new TlsFatalAlert(AlertDescription.decode_error); + } + + return new ServerName(name_type, name); + } + + protected static bool IsCorrectType(byte nameType, object name) + { + switch (nameType) + { + case Tls.NameType.host_name: + return name is string; + default: + throw new ArgumentException("unsupported NameType", "nameType"); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ServerName.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ServerName.cs.meta new file mode 100644 index 0000000..7a1f49e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ServerName.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4e1ac4d161003684d80d3b70f9ba584b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ServerNameList.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ServerNameList.cs new file mode 100644 index 0000000..ed4e593 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ServerNameList.cs @@ -0,0 +1,105 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class ServerNameList + { + protected readonly IList mServerNameList; + + /** + * @param serverNameList an {@link IList} of {@link ServerName}. + */ + public ServerNameList(IList serverNameList) + { + if (serverNameList == null) + throw new ArgumentNullException("serverNameList"); + + this.mServerNameList = serverNameList; + } + + /** + * @return an {@link IList} of {@link ServerName}. + */ + public virtual IList ServerNames + { + get { return mServerNameList; } + } + + /** + * Encode this {@link ServerNameList} to a {@link Stream}. + * + * @param output + * the {@link Stream} to encode to. + * @throws IOException + */ + public virtual void Encode(Stream output) + { + MemoryStream buf = new MemoryStream(); + + byte[] nameTypesSeen = TlsUtilities.EmptyBytes; + foreach (ServerName entry in ServerNames) + { + nameTypesSeen = CheckNameType(nameTypesSeen, entry.NameType); + if (nameTypesSeen == null) + throw new TlsFatalAlert(AlertDescription.internal_error); + + entry.Encode(buf); + } + + TlsUtilities.CheckUint16(buf.Length); + TlsUtilities.WriteUint16((int)buf.Length, output); + Streams.WriteBufTo(buf, output); + } + + /** + * Parse a {@link ServerNameList} from a {@link Stream}. + * + * @param input + * the {@link Stream} to parse from. + * @return a {@link ServerNameList} object. + * @throws IOException + */ + public static ServerNameList Parse(Stream input) + { + int length = TlsUtilities.ReadUint16(input); + if (length < 1) + throw new TlsFatalAlert(AlertDescription.decode_error); + + byte[] data = TlsUtilities.ReadFully(length, input); + + MemoryStream buf = new MemoryStream(data, false); + + byte[] nameTypesSeen = TlsUtilities.EmptyBytes; + IList server_name_list = Platform.CreateArrayList(); + while (buf.Position < buf.Length) + { + ServerName entry = ServerName.Parse(buf); + + nameTypesSeen = CheckNameType(nameTypesSeen, entry.NameType); + if (nameTypesSeen == null) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + server_name_list.Add(entry); + } + + return new ServerNameList(server_name_list); + } + + private static byte[] CheckNameType(byte[] nameTypesSeen, byte nameType) + { + /* + * RFC 6066 3. The ServerNameList MUST NOT contain more than one name of the same + * name_type. + */ + if (!NameType.IsValid(nameType) || Arrays.Contains(nameTypesSeen, nameType)) + return null; + + return Arrays.Append(nameTypesSeen, nameType); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ServerNameList.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ServerNameList.cs.meta new file mode 100644 index 0000000..462497a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ServerNameList.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3b9df34882bd5b64c800752759a678c0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ServerOnlyTlsAuthentication.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ServerOnlyTlsAuthentication.cs new file mode 100644 index 0000000..4858897 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ServerOnlyTlsAuthentication.cs @@ -0,0 +1,15 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class ServerOnlyTlsAuthentication + : TlsAuthentication + { + public abstract void NotifyServerCertificate(Certificate serverCertificate); + + public TlsCredentials GetClientCredentials(CertificateRequest certificateRequest) + { + return null; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ServerOnlyTlsAuthentication.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ServerOnlyTlsAuthentication.cs.meta new file mode 100644 index 0000000..cf8688c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ServerOnlyTlsAuthentication.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 44dd95041c26f8c41aa1a523d47894b8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ServerSrpParams.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ServerSrpParams.cs new file mode 100644 index 0000000..556ac53 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ServerSrpParams.cs @@ -0,0 +1,75 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class ServerSrpParams + { + protected BigInteger m_N, m_g, m_B; + protected byte[] m_s; + + public ServerSrpParams(BigInteger N, BigInteger g, byte[] s, BigInteger B) + { + this.m_N = N; + this.m_g = g; + this.m_s = Arrays.Clone(s); + this.m_B = B; + } + + public virtual BigInteger B + { + get { return m_B; } + } + + public virtual BigInteger G + { + get { return m_g; } + } + + public virtual BigInteger N + { + get { return m_N; } + } + + public virtual byte[] S + { + get { return m_s; } + } + + /** + * Encode this {@link ServerSRPParams} to an {@link OutputStream}. + * + * @param output + * the {@link OutputStream} to encode to. + * @throws IOException + */ + public virtual void Encode(Stream output) + { + TlsSrpUtilities.WriteSrpParameter(m_N, output); + TlsSrpUtilities.WriteSrpParameter(m_g, output); + TlsUtilities.WriteOpaque8(m_s, output); + TlsSrpUtilities.WriteSrpParameter(m_B, output); + } + + /** + * Parse a {@link ServerSRPParams} from an {@link InputStream}. + * + * @param input + * the {@link InputStream} to parse from. + * @return a {@link ServerSRPParams} object. + * @throws IOException + */ + public static ServerSrpParams Parse(Stream input) + { + BigInteger N = TlsSrpUtilities.ReadSrpParameter(input); + BigInteger g = TlsSrpUtilities.ReadSrpParameter(input); + byte[] s = TlsUtilities.ReadOpaque8(input); + BigInteger B = TlsSrpUtilities.ReadSrpParameter(input); + + return new ServerSrpParams(N, g, s, B); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ServerSrpParams.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ServerSrpParams.cs.meta new file mode 100644 index 0000000..0be8d7c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/ServerSrpParams.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f154a8d23c23d8a4ca36bed084e6c726 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SessionParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SessionParameters.cs new file mode 100644 index 0000000..e827172 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SessionParameters.cs @@ -0,0 +1,180 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public sealed class SessionParameters + { + public sealed class Builder + { + private int mCipherSuite = -1; + private short mCompressionAlgorithm = -1; + private byte[] mMasterSecret = null; + private Certificate mPeerCertificate = null; + private byte[] mPskIdentity = null; + private byte[] mSrpIdentity = null; + private byte[] mEncodedServerExtensions = null; + private bool mExtendedMasterSecret = false; + + public Builder() + { + } + + public SessionParameters Build() + { + Validate(this.mCipherSuite >= 0, "cipherSuite"); + Validate(this.mCompressionAlgorithm >= 0, "compressionAlgorithm"); + Validate(this.mMasterSecret != null, "masterSecret"); + return new SessionParameters(mCipherSuite, (byte)mCompressionAlgorithm, mMasterSecret, mPeerCertificate, + mPskIdentity, mSrpIdentity, mEncodedServerExtensions, mExtendedMasterSecret); + } + + public Builder SetCipherSuite(int cipherSuite) + { + this.mCipherSuite = cipherSuite; + return this; + } + + public Builder SetCompressionAlgorithm(byte compressionAlgorithm) + { + this.mCompressionAlgorithm = compressionAlgorithm; + return this; + } + + public Builder SetExtendedMasterSecret(bool extendedMasterSecret) + { + this.mExtendedMasterSecret = extendedMasterSecret; + return this; + } + + public Builder SetMasterSecret(byte[] masterSecret) + { + this.mMasterSecret = masterSecret; + return this; + } + + public Builder SetPeerCertificate(Certificate peerCertificate) + { + this.mPeerCertificate = peerCertificate; + return this; + } + + public Builder SetPskIdentity(byte[] pskIdentity) + { + this.mPskIdentity = pskIdentity; + return this; + } + + public Builder SetSrpIdentity(byte[] srpIdentity) + { + this.mSrpIdentity = srpIdentity; + return this; + } + + public Builder SetServerExtensions(IDictionary serverExtensions) + { + if (serverExtensions == null) + { + mEncodedServerExtensions = null; + } + else + { + MemoryStream buf = new MemoryStream(); + TlsProtocol.WriteExtensions(buf, serverExtensions); + mEncodedServerExtensions = buf.ToArray(); + } + return this; + } + + private void Validate(bool condition, string parameter) + { + if (!condition) + throw new InvalidOperationException("Required session parameter '" + parameter + "' not configured"); + } + } + + private int mCipherSuite; + private byte mCompressionAlgorithm; + private byte[] mMasterSecret; + private Certificate mPeerCertificate; + private byte[] mPskIdentity; + private byte[] mSrpIdentity; + private byte[] mEncodedServerExtensions; + private bool mExtendedMasterSecret; + + private SessionParameters(int cipherSuite, byte compressionAlgorithm, byte[] masterSecret, + Certificate peerCertificate, byte[] pskIdentity, byte[] srpIdentity, byte[] encodedServerExtensions, + bool extendedMasterSecret) + { + this.mCipherSuite = cipherSuite; + this.mCompressionAlgorithm = compressionAlgorithm; + this.mMasterSecret = Arrays.Clone(masterSecret); + this.mPeerCertificate = peerCertificate; + this.mPskIdentity = Arrays.Clone(pskIdentity); + this.mSrpIdentity = Arrays.Clone(srpIdentity); + this.mEncodedServerExtensions = encodedServerExtensions; + this.mExtendedMasterSecret = extendedMasterSecret; + } + + public void Clear() + { + if (this.mMasterSecret != null) + { + Arrays.Fill(this.mMasterSecret, (byte)0); + } + } + + public SessionParameters Copy() + { + return new SessionParameters(mCipherSuite, mCompressionAlgorithm, mMasterSecret, mPeerCertificate, + mPskIdentity, mSrpIdentity, mEncodedServerExtensions, mExtendedMasterSecret); + } + + public int CipherSuite + { + get { return mCipherSuite; } + } + + public byte CompressionAlgorithm + { + get { return mCompressionAlgorithm; } + } + + public bool IsExtendedMasterSecret + { + get { return mExtendedMasterSecret; } + } + + public byte[] MasterSecret + { + get { return mMasterSecret; } + } + + public Certificate PeerCertificate + { + get { return mPeerCertificate; } + } + + public byte[] PskIdentity + { + get { return mPskIdentity; } + } + + public byte[] SrpIdentity + { + get { return mSrpIdentity; } + } + + public IDictionary ReadServerExtensions() + { + if (mEncodedServerExtensions == null) + return null; + + MemoryStream buf = new MemoryStream(mEncodedServerExtensions, false); + return TlsProtocol.ReadExtensions(buf); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SessionParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SessionParameters.cs.meta new file mode 100644 index 0000000..005c4ac --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SessionParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0e0e85a0fe55bbe479b682ec6f428716 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SignatureAlgorithm.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SignatureAlgorithm.cs new file mode 100644 index 0000000..35b9617 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SignatureAlgorithm.cs @@ -0,0 +1,15 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /** + * RFC 5246 7.4.1.4.1 (in RFC 2246, there were no specific values assigned) + */ + public abstract class SignatureAlgorithm + { + public const byte anonymous = 0; + public const byte rsa = 1; + public const byte dsa = 2; + public const byte ecdsa = 3; + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SignatureAlgorithm.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SignatureAlgorithm.cs.meta new file mode 100644 index 0000000..86a1654 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SignatureAlgorithm.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2c66a68006f5d6447bfcc7e36b36bef0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SignatureAndHashAlgorithm.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SignatureAndHashAlgorithm.cs new file mode 100644 index 0000000..f74205b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SignatureAndHashAlgorithm.cs @@ -0,0 +1,94 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /** + * RFC 5246 7.4.1.4.1 + */ + public class SignatureAndHashAlgorithm + { + protected readonly byte mHash; + protected readonly byte mSignature; + + /** + * @param hash {@link HashAlgorithm} + * @param signature {@link SignatureAlgorithm} + */ + public SignatureAndHashAlgorithm(byte hash, byte signature) + { + if (!TlsUtilities.IsValidUint8(hash)) + { + throw new ArgumentException("should be a uint8", "hash"); + } + if (!TlsUtilities.IsValidUint8(signature)) + { + throw new ArgumentException("should be a uint8", "signature"); + } + if (signature == SignatureAlgorithm.anonymous) + { + throw new ArgumentException("MUST NOT be \"anonymous\"", "signature"); + } + + this.mHash = hash; + this.mSignature = signature; + } + + /** + * @return {@link HashAlgorithm} + */ + public virtual byte Hash + { + get { return mHash; } + } + + /** + * @return {@link SignatureAlgorithm} + */ + public virtual byte Signature + { + get { return mSignature; } + } + + public override bool Equals(object obj) + { + if (!(obj is SignatureAndHashAlgorithm)) + { + return false; + } + SignatureAndHashAlgorithm other = (SignatureAndHashAlgorithm)obj; + return other.Hash == Hash && other.Signature == Signature; + } + + public override int GetHashCode() + { + return ((int)Hash << 16) | (int)Signature; + } + + /** + * Encode this {@link SignatureAndHashAlgorithm} to a {@link Stream}. + * + * @param output the {@link Stream} to encode to. + * @throws IOException + */ + public virtual void Encode(Stream output) + { + TlsUtilities.WriteUint8(Hash, output); + TlsUtilities.WriteUint8(Signature, output); + } + + /** + * Parse a {@link SignatureAndHashAlgorithm} from a {@link Stream}. + * + * @param input the {@link Stream} to parse from. + * @return a {@link SignatureAndHashAlgorithm} object. + * @throws IOException + */ + public static SignatureAndHashAlgorithm Parse(Stream input) + { + byte hash = TlsUtilities.ReadUint8(input); + byte signature = TlsUtilities.ReadUint8(input); + return new SignatureAndHashAlgorithm(hash, signature); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SignatureAndHashAlgorithm.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SignatureAndHashAlgorithm.cs.meta new file mode 100644 index 0000000..1907c65 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SignatureAndHashAlgorithm.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b8dc03bcb6a0ed14495aa4dc7836879e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SignerInputBuffer.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SignerInputBuffer.cs new file mode 100644 index 0000000..7bc6962 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SignerInputBuffer.cs @@ -0,0 +1,37 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + internal class SignerInputBuffer + : MemoryStream + { + internal void UpdateSigner(ISigner s) + { + Streams.WriteBufTo(this, new SigStream(s)); + } + + private class SigStream + : BaseOutputStream + { + private readonly ISigner s; + + internal SigStream(ISigner s) + { + this.s = s; + } + + public override void WriteByte(byte b) + { + s.Update(b); + } + + public override void Write(byte[] buf, int off, int len) + { + s.BlockUpdate(buf, off, len); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SignerInputBuffer.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SignerInputBuffer.cs.meta new file mode 100644 index 0000000..b5c22b2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SignerInputBuffer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f29b43fc5181b144eba9da85a08ffcf4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SimulatedTlsSrpIdentityManager.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SimulatedTlsSrpIdentityManager.cs new file mode 100644 index 0000000..3e9737c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SimulatedTlsSrpIdentityManager.cs @@ -0,0 +1,69 @@ +using System; + +using Org.BouncyCastle.Crypto.Agreement.Srp; +using Org.BouncyCastle.Crypto.Macs; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /** + * An implementation of {@link TlsSRPIdentityManager} that simulates the existence of "unknown" identities + * to obscure the fact that there is no verifier for them. + */ + public class SimulatedTlsSrpIdentityManager + : TlsSrpIdentityManager + { + private static readonly byte[] PREFIX_PASSWORD = Strings.ToByteArray("password"); + private static readonly byte[] PREFIX_SALT = Strings.ToByteArray("salt"); + + /** + * Create a {@link SimulatedTlsSRPIdentityManager} that implements the algorithm from RFC 5054 2.5.1.3 + * + * @param group the {@link SRP6GroupParameters} defining the group that SRP is operating in + * @param seedKey the secret "seed key" referred to in RFC 5054 2.5.1.3 + * @return an instance of {@link SimulatedTlsSRPIdentityManager} + */ + public static SimulatedTlsSrpIdentityManager GetRfc5054Default(Srp6GroupParameters group, byte[] seedKey) + { + Srp6VerifierGenerator verifierGenerator = new Srp6VerifierGenerator(); + verifierGenerator.Init(group, TlsUtilities.CreateHash(HashAlgorithm.sha1)); + + HMac mac = new HMac(TlsUtilities.CreateHash(HashAlgorithm.sha1)); + mac.Init(new KeyParameter(seedKey)); + + return new SimulatedTlsSrpIdentityManager(group, verifierGenerator, mac); + } + + protected readonly Srp6GroupParameters mGroup; + protected readonly Srp6VerifierGenerator mVerifierGenerator; + protected readonly IMac mMac; + + public SimulatedTlsSrpIdentityManager(Srp6GroupParameters group, Srp6VerifierGenerator verifierGenerator, IMac mac) + { + this.mGroup = group; + this.mVerifierGenerator = verifierGenerator; + this.mMac = mac; + } + + public virtual TlsSrpLoginParameters GetLoginParameters(byte[] identity) + { + mMac.BlockUpdate(PREFIX_SALT, 0, PREFIX_SALT.Length); + mMac.BlockUpdate(identity, 0, identity.Length); + + byte[] salt = new byte[mMac.GetMacSize()]; + mMac.DoFinal(salt, 0); + + mMac.BlockUpdate(PREFIX_PASSWORD, 0, PREFIX_PASSWORD.Length); + mMac.BlockUpdate(identity, 0, identity.Length); + + byte[] password = new byte[mMac.GetMacSize()]; + mMac.DoFinal(password, 0); + + BigInteger verifier = mVerifierGenerator.GenerateVerifier(salt, identity, password); + + return new TlsSrpLoginParameters(mGroup, verifier, salt); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SimulatedTlsSrpIdentityManager.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SimulatedTlsSrpIdentityManager.cs.meta new file mode 100644 index 0000000..6525256 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SimulatedTlsSrpIdentityManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5e8e1600974f0e0459195fd1ca7028fd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SrpTlsClient.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SrpTlsClient.cs new file mode 100644 index 0000000..df16077 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SrpTlsClient.cs @@ -0,0 +1,104 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class SrpTlsClient + : AbstractTlsClient + { + protected TlsSrpGroupVerifier mGroupVerifier; + + protected byte[] mIdentity; + protected byte[] mPassword; + + public SrpTlsClient(byte[] identity, byte[] password) + : this(new DefaultTlsCipherFactory(), new DefaultTlsSrpGroupVerifier(), identity, password) + { + } + + public SrpTlsClient(TlsCipherFactory cipherFactory, byte[] identity, byte[] password) + : this(cipherFactory, new DefaultTlsSrpGroupVerifier(), identity, password) + { + } + + public SrpTlsClient(TlsCipherFactory cipherFactory, TlsSrpGroupVerifier groupVerifier, + byte[] identity, byte[] password) + : base(cipherFactory) + { + this.mGroupVerifier = groupVerifier; + this.mIdentity = Arrays.Clone(identity); + this.mPassword = Arrays.Clone(password); + } + + protected virtual bool RequireSrpServerExtension + { + // No explicit guidance in RFC 5054; by default an (empty) extension from server is optional + get { return false; } + } + + public override int[] GetCipherSuites() + { + return new int[] + { + CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA + }; + } + + public override IDictionary GetClientExtensions() + { + IDictionary clientExtensions = TlsExtensionsUtilities.EnsureExtensionsInitialised(base.GetClientExtensions()); + TlsSrpUtilities.AddSrpExtension(clientExtensions, this.mIdentity); + return clientExtensions; + } + + public override void ProcessServerExtensions(IDictionary serverExtensions) + { + if (!TlsUtilities.HasExpectedEmptyExtensionData(serverExtensions, ExtensionType.srp, + AlertDescription.illegal_parameter)) + { + if (RequireSrpServerExtension) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + base.ProcessServerExtensions(serverExtensions); + } + + public override TlsKeyExchange GetKeyExchange() + { + int keyExchangeAlgorithm = TlsUtilities.GetKeyExchangeAlgorithm(mSelectedCipherSuite); + + switch (keyExchangeAlgorithm) + { + case KeyExchangeAlgorithm.SRP: + case KeyExchangeAlgorithm.SRP_DSS: + case KeyExchangeAlgorithm.SRP_RSA: + return CreateSrpKeyExchange(keyExchangeAlgorithm); + + default: + /* + * Note: internal error here; the TlsProtocol implementation verifies that the + * server-selected cipher suite was in the list of client-offered cipher suites, so if + * we now can't produce an implementation, we shouldn't have offered it! + */ + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + public override TlsAuthentication GetAuthentication() + { + /* + * Note: This method is not called unless a server certificate is sent, which may be the + * case e.g. for SRP_DSS or SRP_RSA key exchange. + */ + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + protected virtual TlsKeyExchange CreateSrpKeyExchange(int keyExchange) + { + return new TlsSrpKeyExchange(keyExchange, mSupportedSignatureAlgorithms, mGroupVerifier, mIdentity, mPassword); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SrpTlsClient.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SrpTlsClient.cs.meta new file mode 100644 index 0000000..a686781 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SrpTlsClient.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 183b66d5c5f60b342a4ee0f9a58048f7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SrpTlsServer.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SrpTlsServer.cs new file mode 100644 index 0000000..f978783 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SrpTlsServer.cs @@ -0,0 +1,121 @@ +using System; +using System.Collections; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class SrpTlsServer + : AbstractTlsServer + { + protected TlsSrpIdentityManager mSrpIdentityManager; + + protected byte[] mSrpIdentity = null; + protected TlsSrpLoginParameters mLoginParameters = null; + + public SrpTlsServer(TlsSrpIdentityManager srpIdentityManager) + : this(new DefaultTlsCipherFactory(), srpIdentityManager) + { + } + + public SrpTlsServer(TlsCipherFactory cipherFactory, TlsSrpIdentityManager srpIdentityManager) + : base(cipherFactory) + { + this.mSrpIdentityManager = srpIdentityManager; + } + + protected virtual TlsSignerCredentials GetDsaSignerCredentials() + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + protected virtual TlsSignerCredentials GetRsaSignerCredentials() + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + protected override int[] GetCipherSuites() + { + return new int[] + { + CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA, + CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA, + CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA, + CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA, + CipherSuite.TLS_SRP_SHA_WITH_AES_256_CBC_SHA, + CipherSuite.TLS_SRP_SHA_WITH_AES_128_CBC_SHA + }; + } + + public override void ProcessClientExtensions(IDictionary clientExtensions) + { + base.ProcessClientExtensions(clientExtensions); + + this.mSrpIdentity = TlsSrpUtilities.GetSrpExtension(clientExtensions); + } + + public override int GetSelectedCipherSuite() + { + int cipherSuite = base.GetSelectedCipherSuite(); + + if (TlsSrpUtilities.IsSrpCipherSuite(cipherSuite)) + { + if (mSrpIdentity != null) + { + this.mLoginParameters = mSrpIdentityManager.GetLoginParameters(mSrpIdentity); + } + + if (mLoginParameters == null) + throw new TlsFatalAlert(AlertDescription.unknown_psk_identity); + } + + return cipherSuite; + } + + public override TlsCredentials GetCredentials() + { + int keyExchangeAlgorithm = TlsUtilities.GetKeyExchangeAlgorithm(mSelectedCipherSuite); + + switch (keyExchangeAlgorithm) + { + case KeyExchangeAlgorithm.SRP: + return null; + + case KeyExchangeAlgorithm.SRP_DSS: + return GetDsaSignerCredentials(); + + case KeyExchangeAlgorithm.SRP_RSA: + return GetRsaSignerCredentials(); + + default: + /* Note: internal error here; selected a key exchange we don't implement! */ + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + public override TlsKeyExchange GetKeyExchange() + { + int keyExchangeAlgorithm = TlsUtilities.GetKeyExchangeAlgorithm(mSelectedCipherSuite); + + switch (keyExchangeAlgorithm) + { + case KeyExchangeAlgorithm.SRP: + case KeyExchangeAlgorithm.SRP_DSS: + case KeyExchangeAlgorithm.SRP_RSA: + return CreateSrpKeyExchange(keyExchangeAlgorithm); + + default: + /* + * Note: internal error here; the TlsProtocol implementation verifies that the + * server-selected cipher suite was in the list of client-offered cipher suites, so if + * we now can't produce an implementation, we shouldn't have offered it! + */ + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + protected virtual TlsKeyExchange CreateSrpKeyExchange(int keyExchange) + { + return new TlsSrpKeyExchange(keyExchange, mSupportedSignatureAlgorithms, mSrpIdentity, mLoginParameters); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SrpTlsServer.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SrpTlsServer.cs.meta new file mode 100644 index 0000000..aa01939 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SrpTlsServer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 096bbec128c115d4886738e81f8df5fb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SrtpProtectionProfile.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SrtpProtectionProfile.cs new file mode 100644 index 0000000..6e9091b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SrtpProtectionProfile.cs @@ -0,0 +1,21 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class SrtpProtectionProfile + { + /* + * RFC 5764 4.1.2. + */ + public const int SRTP_AES128_CM_HMAC_SHA1_80 = 0x0001; + public const int SRTP_AES128_CM_HMAC_SHA1_32 = 0x0002; + public const int SRTP_NULL_HMAC_SHA1_80 = 0x0005; + public const int SRTP_NULL_HMAC_SHA1_32 = 0x0006; + + /* + * RFC 7714 14.2. + */ + public const int SRTP_AEAD_AES_128_GCM = 0x0007; + public const int SRTP_AEAD_AES_256_GCM = 0x0008; + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SrtpProtectionProfile.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SrtpProtectionProfile.cs.meta new file mode 100644 index 0000000..92a2b2c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SrtpProtectionProfile.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4685e6038f8170d4b8c848cd8798fe95 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/Ssl3Mac.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/Ssl3Mac.cs new file mode 100644 index 0000000..8bdb342 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/Ssl3Mac.cs @@ -0,0 +1,110 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /** + * HMAC implementation based on original internet draft for HMAC (RFC 2104) + * + * The difference is that padding is concatentated versus XORed with the key + * + * H(K + opad, H(K + ipad, text)) + */ + public class Ssl3Mac + : IMac + { + private const byte IPAD_BYTE = 0x36; + private const byte OPAD_BYTE = 0x5C; + + internal static readonly byte[] IPAD = GenPad(IPAD_BYTE, 48); + internal static readonly byte[] OPAD = GenPad(OPAD_BYTE, 48); + + private readonly IDigest digest; + private readonly int padLength; + + private byte[] secret; + + /** + * Base constructor for one of the standard digest algorithms that the byteLength of + * the algorithm is know for. Behaviour is undefined for digests other than MD5 or SHA1. + * + * @param digest the digest. + */ + public Ssl3Mac(IDigest digest) + { + this.digest = digest; + + if (digest.GetDigestSize() == 20) + { + this.padLength = 40; + } + else + { + this.padLength = 48; + } + } + + public virtual string AlgorithmName + { + get { return digest.AlgorithmName + "/SSL3MAC"; } + } + + public virtual void Init(ICipherParameters parameters) + { + secret = Arrays.Clone(((KeyParameter)parameters).GetKey()); + + Reset(); + } + + public virtual int GetMacSize() + { + return digest.GetDigestSize(); + } + + public virtual void Update(byte input) + { + digest.Update(input); + } + + public virtual void BlockUpdate(byte[] input, int inOff, int len) + { + digest.BlockUpdate(input, inOff, len); + } + + public virtual int DoFinal(byte[] output, int outOff) + { + byte[] tmp = new byte[digest.GetDigestSize()]; + digest.DoFinal(tmp, 0); + + digest.BlockUpdate(secret, 0, secret.Length); + digest.BlockUpdate(OPAD, 0, padLength); + digest.BlockUpdate(tmp, 0, tmp.Length); + + int len = digest.DoFinal(output, outOff); + + Reset(); + + return len; + } + + /** + * Reset the mac generator. + */ + public virtual void Reset() + { + digest.Reset(); + digest.BlockUpdate(secret, 0, secret.Length); + digest.BlockUpdate(IPAD, 0, padLength); + } + + private static byte[] GenPad(byte b, int count) + { + byte[] padding = new byte[count]; + Arrays.Fill(padding, b); + return padding; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/Ssl3Mac.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/Ssl3Mac.cs.meta new file mode 100644 index 0000000..d7dfe86 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/Ssl3Mac.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e677359f6f95c4e41a7af1ec56d52c30 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SupplementalDataEntry.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SupplementalDataEntry.cs new file mode 100644 index 0000000..5adc4fa --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SupplementalDataEntry.cs @@ -0,0 +1,26 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class SupplementalDataEntry + { + protected readonly int mDataType; + protected readonly byte[] mData; + + public SupplementalDataEntry(int dataType, byte[] data) + { + this.mDataType = dataType; + this.mData = data; + } + + public virtual int DataType + { + get { return mDataType; } + } + + public virtual byte[] Data + { + get { return mData; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SupplementalDataEntry.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SupplementalDataEntry.cs.meta new file mode 100644 index 0000000..a3288bf --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SupplementalDataEntry.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 767dd1bb8204ef946a44ef7b721bd154 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SupplementalDataType.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SupplementalDataType.cs new file mode 100644 index 0000000..79511c5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SupplementalDataType.cs @@ -0,0 +1,13 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// RFC 4680 + public abstract class SupplementalDataType + { + /* + * RFC 4681 + */ + public const int user_mapping_data = 0; + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SupplementalDataType.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SupplementalDataType.cs.meta new file mode 100644 index 0000000..8f4cad3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/SupplementalDataType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0fd05f4499850674ab91fd5bcc5d2f0e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/Timeout.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/Timeout.cs new file mode 100644 index 0000000..924073c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/Timeout.cs @@ -0,0 +1,121 @@ +using System; + +using Org.BouncyCastle.Utilities.Date; + +namespace Org.BouncyCastle.Crypto.Tls +{ + internal class Timeout + { + private long durationMillis; + private long startMillis; + + internal Timeout(long durationMillis) + : this(durationMillis, DateTimeUtilities.CurrentUnixMs()) + { + } + + internal Timeout(long durationMillis, long currentTimeMillis) + { + this.durationMillis = System.Math.Max(0, durationMillis); + this.startMillis = System.Math.Max(0, currentTimeMillis); + } + + //internal long RemainingMillis() + //{ + // return RemainingMillis(DateTimeUtilities.CurrentUnixMs()); + //} + + internal long RemainingMillis(long currentTimeMillis) + { + lock (this) + { + // If clock jumped backwards, reset start time + if (startMillis > currentTimeMillis) + { + startMillis = currentTimeMillis; + return durationMillis; + } + + long elapsed = currentTimeMillis - startMillis; + long remaining = durationMillis - elapsed; + + // Once timeout reached, lock it in + if (remaining <= 0) + { + return durationMillis = 0L; + } + + return remaining; + } + } + + //internal static int ConstrainWaitMillis(int waitMillis, Timeout timeout) + //{ + // return ConstrainWaitMillis(waitMillis, timeout, DateTimeUtilities.CurrentUnixMs()); + //} + + internal static int ConstrainWaitMillis(int waitMillis, Timeout timeout, long currentTimeMillis) + { + if (waitMillis < 0) + return -1; + + int timeoutMillis = GetWaitMillis(timeout, currentTimeMillis); + if (timeoutMillis < 0) + return -1; + + if (waitMillis == 0) + return timeoutMillis; + + if (timeoutMillis == 0) + return waitMillis; + + return System.Math.Min(waitMillis, timeoutMillis); + } + + internal static Timeout ForWaitMillis(int waitMillis) + { + return ForWaitMillis(waitMillis, DateTimeUtilities.CurrentUnixMs()); + } + + internal static Timeout ForWaitMillis(int waitMillis, long currentTimeMillis) + { + if (waitMillis < 0) + throw new ArgumentException("cannot be negative", "waitMillis"); + + if (waitMillis > 0) + return new Timeout(waitMillis, currentTimeMillis); + + return null; + } + + //internal static int GetWaitMillis(Timeout timeout) + //{ + // return GetWaitMillis(timeout, DateTimeUtilities.CurrentUnixMs()); + //} + + internal static int GetWaitMillis(Timeout timeout, long currentTimeMillis) + { + if (null == timeout) + return 0; + + long remainingMillis = timeout.RemainingMillis(currentTimeMillis); + if (remainingMillis < 1L) + return -1; + + if (remainingMillis > int.MaxValue) + return int.MaxValue; + + return (int)remainingMillis; + } + + //internal static bool HasExpired(Timeout timeout) + //{ + // return HasExpired(timeout, DateTimeUtilities.CurrentUnixMs()); + //} + + internal static bool HasExpired(Timeout timeout, long currentTimeMillis) + { + return null != timeout && timeout.RemainingMillis(currentTimeMillis) < 1L; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/Timeout.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/Timeout.cs.meta new file mode 100644 index 0000000..9d68343 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/Timeout.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a6a9495da2760ae4eb0aeeb8cf9593f8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsAeadCipher.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsAeadCipher.cs new file mode 100644 index 0000000..9a65d5e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsAeadCipher.cs @@ -0,0 +1,252 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Crypto.Modes; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class TlsAeadCipher + : TlsCipher + { + // TODO[draft-zauner-tls-aes-ocb-04] Apply data volume limit described in section 8.4 + + public const int NONCE_RFC5288 = 1; + + /* + * draft-zauner-tls-aes-ocb-04 specifies the nonce construction from draft-ietf-tls-chacha20-poly1305-04 + */ + internal const int NONCE_DRAFT_CHACHA20_POLY1305 = 2; + + protected readonly TlsContext context; + protected readonly int macSize; + // TODO SecurityParameters.record_iv_length + protected readonly int record_iv_length; + + protected readonly IAeadBlockCipher encryptCipher; + protected readonly IAeadBlockCipher decryptCipher; + + protected readonly byte[] encryptImplicitNonce, decryptImplicitNonce; + + protected readonly int nonceMode; + + /// + public TlsAeadCipher(TlsContext context, IAeadBlockCipher clientWriteCipher, IAeadBlockCipher serverWriteCipher, + int cipherKeySize, int macSize) + : this(context, clientWriteCipher, serverWriteCipher, cipherKeySize, macSize, NONCE_RFC5288) + { + } + + /// + internal TlsAeadCipher(TlsContext context, IAeadBlockCipher clientWriteCipher, IAeadBlockCipher serverWriteCipher, + int cipherKeySize, int macSize, int nonceMode) + { + if (!TlsUtilities.IsTlsV12(context)) + throw new TlsFatalAlert(AlertDescription.internal_error); + + this.nonceMode = nonceMode; + + // TODO SecurityParameters.fixed_iv_length + int fixed_iv_length; + + switch (nonceMode) + { + case NONCE_RFC5288: + fixed_iv_length = 4; + this.record_iv_length = 8; + break; + case NONCE_DRAFT_CHACHA20_POLY1305: + fixed_iv_length = 12; + this.record_iv_length = 0; + break; + default: + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + this.context = context; + this.macSize = macSize; + + int key_block_size = (2 * cipherKeySize) + (2 * fixed_iv_length); + + byte[] key_block = TlsUtilities.CalculateKeyBlock(context, key_block_size); + + int offset = 0; + + KeyParameter client_write_key = new KeyParameter(key_block, offset, cipherKeySize); + offset += cipherKeySize; + KeyParameter server_write_key = new KeyParameter(key_block, offset, cipherKeySize); + offset += cipherKeySize; + byte[] client_write_IV = Arrays.CopyOfRange(key_block, offset, offset + fixed_iv_length); + offset += fixed_iv_length; + byte[] server_write_IV = Arrays.CopyOfRange(key_block, offset, offset + fixed_iv_length); + offset += fixed_iv_length; + + if (offset != key_block_size) + throw new TlsFatalAlert(AlertDescription.internal_error); + + KeyParameter encryptKey, decryptKey; + if (context.IsServer) + { + this.encryptCipher = serverWriteCipher; + this.decryptCipher = clientWriteCipher; + this.encryptImplicitNonce = server_write_IV; + this.decryptImplicitNonce = client_write_IV; + encryptKey = server_write_key; + decryptKey = client_write_key; + } + else + { + this.encryptCipher = clientWriteCipher; + this.decryptCipher = serverWriteCipher; + this.encryptImplicitNonce = client_write_IV; + this.decryptImplicitNonce = server_write_IV; + encryptKey = client_write_key; + decryptKey = server_write_key; + } + + // NOTE: Ensure dummy nonce is not part of the generated sequence(s) + byte[] dummyNonce = new byte[fixed_iv_length + record_iv_length]; + dummyNonce[0] = (byte)~encryptImplicitNonce[0]; + dummyNonce[1] = (byte)~decryptImplicitNonce[1]; + + this.encryptCipher.Init(true, new AeadParameters(encryptKey, 8 * macSize, dummyNonce)); + this.decryptCipher.Init(false, new AeadParameters(decryptKey, 8 * macSize, dummyNonce)); + } + + public virtual int GetPlaintextLimit(int ciphertextLimit) + { + // TODO We ought to be able to ask the decryptCipher (independently of it's current state!) + return ciphertextLimit - macSize - record_iv_length; + } + + /// + public virtual byte[] EncodePlaintext(long seqNo, byte type, byte[] plaintext, int offset, int len) + { + byte[] nonce = new byte[encryptImplicitNonce.Length + record_iv_length]; + + switch (nonceMode) + { + case NONCE_RFC5288: + Array.Copy(encryptImplicitNonce, 0, nonce, 0, encryptImplicitNonce.Length); + // RFC 5288/6655: The nonce_explicit MAY be the 64-bit sequence number. + TlsUtilities.WriteUint64(seqNo, nonce, encryptImplicitNonce.Length); + break; + case NONCE_DRAFT_CHACHA20_POLY1305: + TlsUtilities.WriteUint64(seqNo, nonce, nonce.Length - 8); + for (int i = 0; i < encryptImplicitNonce.Length; ++i) + { + nonce[i] ^= encryptImplicitNonce[i]; + } + break; + default: + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + int plaintextOffset = offset; + int plaintextLength = len; + int ciphertextLength = encryptCipher.GetOutputSize(plaintextLength); + + byte[] output = new byte[record_iv_length + ciphertextLength]; + if (record_iv_length != 0) + { + Array.Copy(nonce, nonce.Length - record_iv_length, output, 0, record_iv_length); + } + int outputPos = record_iv_length; + + byte[] additionalData = GetAdditionalData(seqNo, type, plaintextLength); + AeadParameters parameters = new AeadParameters(null, 8 * macSize, nonce, additionalData); + + try + { + encryptCipher.Init(true, parameters); + outputPos += encryptCipher.ProcessBytes(plaintext, plaintextOffset, plaintextLength, output, outputPos); + outputPos += encryptCipher.DoFinal(output, outputPos); + } + catch (Exception e) + { + throw new TlsFatalAlert(AlertDescription.internal_error, e); + } + + if (outputPos != output.Length) + { + // NOTE: Existing AEAD cipher implementations all give exact output lengths + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + return output; + } + + /// + public virtual byte[] DecodeCiphertext(long seqNo, byte type, byte[] ciphertext, int offset, int len) + { + if (GetPlaintextLimit(len) < 0) + throw new TlsFatalAlert(AlertDescription.decode_error); + + byte[] nonce = new byte[decryptImplicitNonce.Length + record_iv_length]; + + switch (nonceMode) + { + case NONCE_RFC5288: + Array.Copy(decryptImplicitNonce, 0, nonce, 0, decryptImplicitNonce.Length); + Array.Copy(ciphertext, offset, nonce, nonce.Length - record_iv_length, record_iv_length); + break; + case NONCE_DRAFT_CHACHA20_POLY1305: + TlsUtilities.WriteUint64(seqNo, nonce, nonce.Length - 8); + for (int i = 0; i < decryptImplicitNonce.Length; ++i) + { + nonce[i] ^= decryptImplicitNonce[i]; + } + break; + default: + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + int ciphertextOffset = offset + record_iv_length; + int ciphertextLength = len - record_iv_length; + int plaintextLength = decryptCipher.GetOutputSize(ciphertextLength); + + byte[] output = new byte[plaintextLength]; + int outputPos = 0; + + byte[] additionalData = GetAdditionalData(seqNo, type, plaintextLength); + AeadParameters parameters = new AeadParameters(null, 8 * macSize, nonce, additionalData); + + try + { + decryptCipher.Init(false, parameters); + outputPos += decryptCipher.ProcessBytes(ciphertext, ciphertextOffset, ciphertextLength, output, outputPos); + outputPos += decryptCipher.DoFinal(output, outputPos); + } + catch (Exception e) + { + throw new TlsFatalAlert(AlertDescription.bad_record_mac, e); + } + + if (outputPos != output.Length) + { + // NOTE: Existing AEAD cipher implementations all give exact output lengths + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + return output; + } + + /// + protected virtual byte[] GetAdditionalData(long seqNo, byte type, int len) + { + /* + * additional_data = seq_num + TLSCompressed.type + TLSCompressed.version + + * TLSCompressed.length + */ + + byte[] additional_data = new byte[13]; + TlsUtilities.WriteUint64(seqNo, additional_data, 0); + TlsUtilities.WriteUint8(type, additional_data, 8); + TlsUtilities.WriteVersion(context.ServerVersion, additional_data, 9); + TlsUtilities.WriteUint16(len, additional_data, 11); + + return additional_data; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsAeadCipher.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsAeadCipher.cs.meta new file mode 100644 index 0000000..4cc6a23 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsAeadCipher.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e84ca4eb5a1e0174b8145a64f510e940 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsAgreementCredentials.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsAgreementCredentials.cs new file mode 100644 index 0000000..7c64072 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsAgreementCredentials.cs @@ -0,0 +1,12 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public interface TlsAgreementCredentials + : TlsCredentials + { + /// + byte[] GenerateAgreement(AsymmetricKeyParameter peerPublicKey); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsAgreementCredentials.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsAgreementCredentials.cs.meta new file mode 100644 index 0000000..bcd564a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsAgreementCredentials.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b8dfa8c7d101cd54fbc33ae2d124c7c8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsAuthentication.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsAuthentication.cs new file mode 100644 index 0000000..9aea5e4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsAuthentication.cs @@ -0,0 +1,31 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public interface TlsAuthentication + { + /// + /// Called by the protocol handler to report the server certificate. + /// + /// + /// This method is responsible for certificate verification and validation + /// + /// The server received + /// + void NotifyServerCertificate(Certificate serverCertificate); + + /// + /// Return client credentials in response to server's certificate request + /// + /// + /// A containing server certificate request details + /// + /// + /// A to be used for client authentication + /// (or null for no client authentication) + /// + /// + TlsCredentials GetClientCredentials(CertificateRequest certificateRequest); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsAuthentication.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsAuthentication.cs.meta new file mode 100644 index 0000000..a5c874a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsAuthentication.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 25253f9a801ba0843acbd90adbdcf32e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsBlockCipher.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsBlockCipher.cs new file mode 100644 index 0000000..76b476a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsBlockCipher.cs @@ -0,0 +1,395 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// + /// A generic TLS 1.0-1.2 / SSLv3 block cipher. This can be used for AES or 3DES for example. + /// + public class TlsBlockCipher + : TlsCipher + { + protected readonly TlsContext context; + protected readonly byte[] randomData; + protected readonly bool useExplicitIV; + protected readonly bool encryptThenMac; + + protected readonly IBlockCipher encryptCipher; + protected readonly IBlockCipher decryptCipher; + + protected readonly TlsMac mWriteMac; + protected readonly TlsMac mReadMac; + + public virtual TlsMac WriteMac + { + get { return mWriteMac; } + } + + public virtual TlsMac ReadMac + { + get { return mReadMac; } + } + + /// + public TlsBlockCipher(TlsContext context, IBlockCipher clientWriteCipher, IBlockCipher serverWriteCipher, + IDigest clientWriteDigest, IDigest serverWriteDigest, int cipherKeySize) + { + this.context = context; + + this.randomData = new byte[256]; + context.NonceRandomGenerator.NextBytes(randomData); + + this.useExplicitIV = TlsUtilities.IsTlsV11(context); + this.encryptThenMac = context.SecurityParameters.encryptThenMac; + + int key_block_size = (2 * cipherKeySize) + clientWriteDigest.GetDigestSize() + + serverWriteDigest.GetDigestSize(); + + // From TLS 1.1 onwards, block ciphers don't need client_write_IV + if (!useExplicitIV) + { + key_block_size += clientWriteCipher.GetBlockSize() + serverWriteCipher.GetBlockSize(); + } + + byte[] key_block = TlsUtilities.CalculateKeyBlock(context, key_block_size); + + int offset = 0; + + TlsMac clientWriteMac = new TlsMac(context, clientWriteDigest, key_block, offset, + clientWriteDigest.GetDigestSize()); + offset += clientWriteDigest.GetDigestSize(); + TlsMac serverWriteMac = new TlsMac(context, serverWriteDigest, key_block, offset, + serverWriteDigest.GetDigestSize()); + offset += serverWriteDigest.GetDigestSize(); + + KeyParameter client_write_key = new KeyParameter(key_block, offset, cipherKeySize); + offset += cipherKeySize; + KeyParameter server_write_key = new KeyParameter(key_block, offset, cipherKeySize); + offset += cipherKeySize; + + byte[] client_write_IV, server_write_IV; + if (useExplicitIV) + { + client_write_IV = new byte[clientWriteCipher.GetBlockSize()]; + server_write_IV = new byte[serverWriteCipher.GetBlockSize()]; + } + else + { + client_write_IV = Arrays.CopyOfRange(key_block, offset, offset + clientWriteCipher.GetBlockSize()); + offset += clientWriteCipher.GetBlockSize(); + server_write_IV = Arrays.CopyOfRange(key_block, offset, offset + serverWriteCipher.GetBlockSize()); + offset += serverWriteCipher.GetBlockSize(); + } + + if (offset != key_block_size) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + ICipherParameters encryptParams, decryptParams; + if (context.IsServer) + { + this.mWriteMac = serverWriteMac; + this.mReadMac = clientWriteMac; + this.encryptCipher = serverWriteCipher; + this.decryptCipher = clientWriteCipher; + encryptParams = new ParametersWithIV(server_write_key, server_write_IV); + decryptParams = new ParametersWithIV(client_write_key, client_write_IV); + } + else + { + this.mWriteMac = clientWriteMac; + this.mReadMac = serverWriteMac; + this.encryptCipher = clientWriteCipher; + this.decryptCipher = serverWriteCipher; + encryptParams = new ParametersWithIV(client_write_key, client_write_IV); + decryptParams = new ParametersWithIV(server_write_key, server_write_IV); + } + + this.encryptCipher.Init(true, encryptParams); + this.decryptCipher.Init(false, decryptParams); + } + + public virtual int GetPlaintextLimit(int ciphertextLimit) + { + int blockSize = encryptCipher.GetBlockSize(); + int macSize = mWriteMac.Size; + + int plaintextLimit = ciphertextLimit; + + // An explicit IV consumes 1 block + if (useExplicitIV) + { + plaintextLimit -= blockSize; + } + + // Leave room for the MAC, and require block-alignment + if (encryptThenMac) + { + plaintextLimit -= macSize; + plaintextLimit -= plaintextLimit % blockSize; + } + else + { + plaintextLimit -= plaintextLimit % blockSize; + plaintextLimit -= macSize; + } + + // Minimum 1 byte of padding + --plaintextLimit; + + return plaintextLimit; + } + + public virtual byte[] EncodePlaintext(long seqNo, byte type, byte[] plaintext, int offset, int len) + { + int blockSize = encryptCipher.GetBlockSize(); + int macSize = mWriteMac.Size; + + ProtocolVersion version = context.ServerVersion; + + int enc_input_length = len; + if (!encryptThenMac) + { + enc_input_length += macSize; + } + + int padding_length = blockSize - 1 - (enc_input_length % blockSize); + + /* + * Don't use variable-length padding with truncated MACs. + * + * See "Tag Size Does Matter: Attacks and Proofs for the TLS Record Protocol", Paterson, + * Ristenpart, Shrimpton. + */ + if (encryptThenMac || !context.SecurityParameters.truncatedHMac) + { + // TODO[DTLS] Consider supporting in DTLS (without exceeding send limit though) + if (!version.IsDtls && !version.IsSsl) + { + // Add a random number of extra blocks worth of padding + int maxExtraPadBlocks = (255 - padding_length) / blockSize; + int actualExtraPadBlocks = ChooseExtraPadBlocks(context.SecureRandom, maxExtraPadBlocks); + padding_length += actualExtraPadBlocks * blockSize; + } + } + + int totalSize = len + macSize + padding_length + 1; + if (useExplicitIV) + { + totalSize += blockSize; + } + + byte[] outBuf = new byte[totalSize]; + int outOff = 0; + + if (useExplicitIV) + { + byte[] explicitIV = new byte[blockSize]; + context.NonceRandomGenerator.NextBytes(explicitIV); + + encryptCipher.Init(true, new ParametersWithIV(null, explicitIV)); + + Array.Copy(explicitIV, 0, outBuf, outOff, blockSize); + outOff += blockSize; + } + + int blocks_start = outOff; + + Array.Copy(plaintext, offset, outBuf, outOff, len); + outOff += len; + + if (!encryptThenMac) + { + byte[] mac = mWriteMac.CalculateMac(seqNo, type, plaintext, offset, len); + Array.Copy(mac, 0, outBuf, outOff, mac.Length); + outOff += mac.Length; + } + + for (int i = 0; i <= padding_length; i++) + { + outBuf[outOff++] = (byte)padding_length; + } + + for (int i = blocks_start; i < outOff; i += blockSize) + { + encryptCipher.ProcessBlock(outBuf, i, outBuf, i); + } + + if (encryptThenMac) + { + byte[] mac = mWriteMac.CalculateMac(seqNo, type, outBuf, 0, outOff); + Array.Copy(mac, 0, outBuf, outOff, mac.Length); + outOff += mac.Length; + } + + // assert outBuf.length == outOff; + + return outBuf; + } + + /// + public virtual byte[] DecodeCiphertext(long seqNo, byte type, byte[] ciphertext, int offset, int len) + { + int blockSize = decryptCipher.GetBlockSize(); + int macSize = mReadMac.Size; + + int minLen = blockSize; + if (encryptThenMac) + { + minLen += macSize; + } + else + { + minLen = System.Math.Max(minLen, macSize + 1); + } + + if (useExplicitIV) + { + minLen += blockSize; + } + + if (len < minLen) + throw new TlsFatalAlert(AlertDescription.decode_error); + + int blocks_length = len; + if (encryptThenMac) + { + blocks_length -= macSize; + } + + if (blocks_length % blockSize != 0) + throw new TlsFatalAlert(AlertDescription.decryption_failed); + + if (encryptThenMac) + { + int end = offset + len; + byte[] receivedMac = Arrays.CopyOfRange(ciphertext, end - macSize, end); + byte[] calculatedMac = mReadMac.CalculateMac(seqNo, type, ciphertext, offset, len - macSize); + + bool badMacEtm = !Arrays.ConstantTimeAreEqual(calculatedMac, receivedMac); + if (badMacEtm) + { + /* + * RFC 7366 3. The MAC SHALL be evaluated before any further processing such as + * decryption is performed, and if the MAC verification fails, then processing SHALL + * terminate immediately. For TLS, a fatal bad_record_mac MUST be generated [2]. For + * DTLS, the record MUST be discarded, and a fatal bad_record_mac MAY be generated + * [4]. This immediate response to a bad MAC eliminates any timing channels that may + * be available through the use of manipulated packet data. + */ + throw new TlsFatalAlert(AlertDescription.bad_record_mac); + } + } + + if (useExplicitIV) + { + decryptCipher.Init(false, new ParametersWithIV(null, ciphertext, offset, blockSize)); + + offset += blockSize; + blocks_length -= blockSize; + } + + for (int i = 0; i < blocks_length; i += blockSize) + { + decryptCipher.ProcessBlock(ciphertext, offset + i, ciphertext, offset + i); + } + + // If there's anything wrong with the padding, this will return zero + int totalPad = CheckPaddingConstantTime(ciphertext, offset, blocks_length, blockSize, encryptThenMac ? 0 : macSize); + bool badMac = (totalPad == 0); + + int dec_output_length = blocks_length - totalPad; + + if (!encryptThenMac) + { + dec_output_length -= macSize; + int macInputLen = dec_output_length; + int macOff = offset + macInputLen; + byte[] receivedMac = Arrays.CopyOfRange(ciphertext, macOff, macOff + macSize); + byte[] calculatedMac = mReadMac.CalculateMacConstantTime(seqNo, type, ciphertext, offset, macInputLen, + blocks_length - macSize, randomData); + + badMac |= !Arrays.ConstantTimeAreEqual(calculatedMac, receivedMac); + } + + if (badMac) + throw new TlsFatalAlert(AlertDescription.bad_record_mac); + + return Arrays.CopyOfRange(ciphertext, offset, offset + dec_output_length); + } + + protected virtual int CheckPaddingConstantTime(byte[] buf, int off, int len, int blockSize, int macSize) + { + int end = off + len; + byte lastByte = buf[end - 1]; + int padlen = lastByte & 0xff; + int totalPad = padlen + 1; + + int dummyIndex = 0; + byte padDiff = 0; + + if ((TlsUtilities.IsSsl(context) && totalPad > blockSize) || (macSize + totalPad > len)) + { + totalPad = 0; + } + else + { + int padPos = end - totalPad; + do + { + padDiff |= (byte)(buf[padPos++] ^ lastByte); + } + while (padPos < end); + + dummyIndex = totalPad; + + if (padDiff != 0) + { + totalPad = 0; + } + } + + // Run some extra dummy checks so the number of checks is always constant + { + byte[] dummyPad = randomData; + while (dummyIndex < 256) + { + padDiff |= (byte)(dummyPad[dummyIndex++] ^ lastByte); + } + // Ensure the above loop is not eliminated + dummyPad[0] ^= padDiff; + } + + return totalPad; + } + + protected virtual int ChooseExtraPadBlocks(SecureRandom r, int max) + { + // return r.NextInt(max + 1); + + int x = r.NextInt(); + int n = LowestBitSet(x); + return System.Math.Min(n, max); + } + + protected virtual int LowestBitSet(int x) + { + if (x == 0) + return 32; + + uint ux = (uint)x; + int n = 0; + while ((ux & 1U) == 0) + { + ++n; + ux >>= 1; + } + return n; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsBlockCipher.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsBlockCipher.cs.meta new file mode 100644 index 0000000..71909c1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsBlockCipher.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9cb605f8ac7986e498e58d4dad7d3d82 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsCipher.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsCipher.cs new file mode 100644 index 0000000..7bd8573 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsCipher.cs @@ -0,0 +1,16 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public interface TlsCipher + { + int GetPlaintextLimit(int ciphertextLimit); + + /// + byte[] EncodePlaintext(long seqNo, byte type, byte[] plaintext, int offset, int len); + + /// + byte[] DecodeCiphertext(long seqNo, byte type, byte[] ciphertext, int offset, int len); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsCipher.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsCipher.cs.meta new file mode 100644 index 0000000..6401e06 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsCipher.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a5c72efdd1d6e974ba7b5fd1ac100f4a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsCipherFactory.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsCipherFactory.cs new file mode 100644 index 0000000..4e1fe0e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsCipherFactory.cs @@ -0,0 +1,11 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public interface TlsCipherFactory + { + /// + TlsCipher CreateCipher(TlsContext context, int encryptionAlgorithm, int macAlgorithm); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsCipherFactory.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsCipherFactory.cs.meta new file mode 100644 index 0000000..c402439 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsCipherFactory.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0fc940f97f48c2743aa24e6bd2dde053 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsClient.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsClient.cs new file mode 100644 index 0000000..73f1690 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsClient.cs @@ -0,0 +1,148 @@ +using System; +using System.Collections; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public interface TlsClient + : TlsPeer + { + /// + /// Called at the start of a new TLS session, before any other methods. + /// + /// + /// A + /// + void Init(TlsClientContext context); + + /// Return the session this client wants to resume, if any. + /// Note that the peer's certificate chain for the session (if any) may need to be periodically revalidated. + /// + /// A representing the resumable session to be used for this connection, + /// or null to use a new session. + /// + TlsSession GetSessionToResume(); + + /// + /// Return the to use for the TLSPlaintext.version field prior to + /// receiving the server version. NOTE: This method is not called for DTLS. + /// + /// + /// See RFC 5246 E.1.: "TLS clients that wish to negotiate with older servers MAY send any value + /// {03,XX} as the record layer version number. Typical values would be {03,00}, the lowest + /// version number supported by the client, and the value of ClientHello.client_version. No + /// single value will guarantee interoperability with all old servers, but this is a complex + /// topic beyond the scope of this document." + /// + /// The to use. + ProtocolVersion ClientHelloRecordLayerVersion { get; } + + ProtocolVersion ClientVersion { get; } + + bool IsFallback { get; } + + /// + /// Get the list of cipher suites that this client supports. + /// + /// + /// An array of values, each specifying a supported cipher suite. + /// + int[] GetCipherSuites(); + + /// + /// Get the list of compression methods that this client supports. + /// + /// + /// An array of values, each specifying a supported compression method. + /// + byte[] GetCompressionMethods(); + + /// + /// Get the (optional) table of client extensions to be included in (extended) client hello. + /// + /// + /// A (Int32 -> byte[]). May be null. + /// + /// + IDictionary GetClientExtensions(); + + /// + void NotifyServerVersion(ProtocolVersion selectedVersion); + + /// + /// Notifies the client of the session_id sent in the ServerHello. + /// + /// An array of + void NotifySessionID(byte[] sessionID); + + /// + /// Report the cipher suite that was selected by the server. + /// + /// + /// The protocol handler validates this value against the offered cipher suites + /// + /// + /// + /// A + /// + void NotifySelectedCipherSuite(int selectedCipherSuite); + + /// + /// Report the compression method that was selected by the server. + /// + /// + /// The protocol handler validates this value against the offered compression methods + /// + /// + /// + /// A + /// + void NotifySelectedCompressionMethod(byte selectedCompressionMethod); + + /// + /// Report the extensions from an extended server hello. + /// + /// + /// Will only be called if we returned a non-null result from . + /// + /// + /// A (Int32 -> byte[]) + /// + void ProcessServerExtensions(IDictionary serverExtensions); + + /// A list of + /// + void ProcessServerSupplementalData(IList serverSupplementalData); + + /// + /// Return an implementation of to negotiate the key exchange + /// part of the protocol. + /// + /// + /// A + /// + /// + TlsKeyExchange GetKeyExchange(); + + /// + /// Return an implementation of to handle authentication + /// part of the protocol. + /// + /// + TlsAuthentication GetAuthentication(); + + /// A list of + /// + IList GetClientSupplementalData(); + + /// RFC 5077 3.3. NewSessionTicket Handshake Message + /// + /// This method will be called (only) when a NewSessionTicket handshake message is received. The + /// ticket is opaque to the client and clients MUST NOT examine the ticket under the assumption + /// that it complies with e.g. RFC 5077 4. Recommended Ticket Construction. + /// + /// The ticket + /// + void NotifyNewSessionTicket(NewSessionTicket newSessionTicket); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsClient.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsClient.cs.meta new file mode 100644 index 0000000..2de0463 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsClient.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 78dcad069b2b9384f985e79c4a6440cd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsClientContext.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsClientContext.cs new file mode 100644 index 0000000..b077d0a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsClientContext.cs @@ -0,0 +1,11 @@ +using System; + +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public interface TlsClientContext + : TlsContext + { + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsClientContext.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsClientContext.cs.meta new file mode 100644 index 0000000..898a380 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsClientContext.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d0da1c4ac70828545bf721a684a388b0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsClientContextImpl.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsClientContextImpl.cs new file mode 100644 index 0000000..674d689 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsClientContextImpl.cs @@ -0,0 +1,20 @@ +using System; + +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Tls +{ + internal class TlsClientContextImpl + : AbstractTlsContext, TlsClientContext + { + internal TlsClientContextImpl(SecureRandom secureRandom, SecurityParameters securityParameters) + : base(secureRandom, securityParameters) + { + } + + public override bool IsServer + { + get { return false; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsClientContextImpl.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsClientContextImpl.cs.meta new file mode 100644 index 0000000..de34b37 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsClientContextImpl.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 52ce16bc0705e034ca3a7f52011e6441 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsClientProtocol.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsClientProtocol.cs new file mode 100644 index 0000000..1fe5744 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsClientProtocol.cs @@ -0,0 +1,918 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class TlsClientProtocol + : TlsProtocol + { + protected TlsClient mTlsClient = null; + internal TlsClientContextImpl mTlsClientContext = null; + + protected byte[] mSelectedSessionID = null; + + protected TlsKeyExchange mKeyExchange = null; + protected TlsAuthentication mAuthentication = null; + + protected CertificateStatus mCertificateStatus = null; + protected CertificateRequest mCertificateRequest = null; + + /** + * Constructor for blocking mode. + * @param stream The bi-directional stream of data to/from the server + * @param secureRandom Random number generator for various cryptographic functions + */ + public TlsClientProtocol(Stream stream, SecureRandom secureRandom) + : base(stream, secureRandom) + { + } + + /** + * Constructor for blocking mode. + * @param input The stream of data from the server + * @param output The stream of data to the server + * @param secureRandom Random number generator for various cryptographic functions + */ + public TlsClientProtocol(Stream input, Stream output, SecureRandom secureRandom) + : base(input, output, secureRandom) + { + } + + /** + * Constructor for non-blocking mode.
+ *
+ * When data is received, use {@link #offerInput(java.nio.ByteBuffer)} to + * provide the received ciphertext, then use + * {@link #readInput(byte[], int, int)} to read the corresponding cleartext.
+ *
+ * Similarly, when data needs to be sent, use + * {@link #offerOutput(byte[], int, int)} to provide the cleartext, then use + * {@link #readOutput(byte[], int, int)} to get the corresponding + * ciphertext. + * + * @param secureRandom + * Random number generator for various cryptographic functions + */ + public TlsClientProtocol(SecureRandom secureRandom) + : base(secureRandom) + { + } + + /** + * Initiates a TLS handshake in the role of client.
+ *
+ * In blocking mode, this will not return until the handshake is complete. + * In non-blocking mode, use {@link TlsPeer#NotifyHandshakeComplete()} to + * receive a callback when the handshake is complete. + * + * @param tlsClient The {@link TlsClient} to use for the handshake. + * @throws IOException If in blocking mode and handshake was not successful. + */ + public virtual void Connect(TlsClient tlsClient) + { + if (tlsClient == null) + throw new ArgumentNullException("tlsClient"); + if (this.mTlsClient != null) + throw new InvalidOperationException("'Connect' can only be called once"); + + this.mTlsClient = tlsClient; + + this.mSecurityParameters = new SecurityParameters(); + this.mSecurityParameters.entity = ConnectionEnd.client; + + this.mTlsClientContext = new TlsClientContextImpl(mSecureRandom, mSecurityParameters); + + this.mSecurityParameters.clientRandom = CreateRandomBlock(tlsClient.ShouldUseGmtUnixTime(), + mTlsClientContext.NonceRandomGenerator); + + this.mTlsClient.Init(mTlsClientContext); + this.mRecordStream.Init(mTlsClientContext); + + tlsClient.NotifyCloseHandle(this); + + TlsSession sessionToResume = tlsClient.GetSessionToResume(); + if (sessionToResume != null && sessionToResume.IsResumable) + { + SessionParameters sessionParameters = sessionToResume.ExportSessionParameters(); + if (sessionParameters != null && sessionParameters.IsExtendedMasterSecret) + { + this.mTlsSession = sessionToResume; + this.mSessionParameters = sessionParameters; + } + } + + SendClientHelloMessage(); + this.mConnectionState = CS_CLIENT_HELLO; + + BlockForHandshake(); + } + + protected override void CleanupHandshake() + { + base.CleanupHandshake(); + + this.mSelectedSessionID = null; + this.mKeyExchange = null; + this.mAuthentication = null; + this.mCertificateStatus = null; + this.mCertificateRequest = null; + } + + protected override TlsContext Context + { + get { return mTlsClientContext; } + } + + internal override AbstractTlsContext ContextAdmin + { + get { return mTlsClientContext; } + } + + protected override TlsPeer Peer + { + get { return mTlsClient; } + } + + protected override void HandleHandshakeMessage(byte type, MemoryStream buf) + { + if (this.mResumedSession) + { + if (type != HandshakeType.finished || this.mConnectionState != CS_SERVER_HELLO) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + + ProcessFinishedMessage(buf); + this.mConnectionState = CS_SERVER_FINISHED; + + SendChangeCipherSpecMessage(); + SendFinishedMessage(); + this.mConnectionState = CS_CLIENT_FINISHED; + + CompleteHandshake(); + return; + } + + switch (type) + { + case HandshakeType.certificate: + { + switch (this.mConnectionState) + { + case CS_SERVER_HELLO: + case CS_SERVER_SUPPLEMENTAL_DATA: + { + if (this.mConnectionState == CS_SERVER_HELLO) + { + HandleSupplementalData(null); + } + + // Parse the Certificate message and Send to cipher suite + + this.mPeerCertificate = Certificate.Parse(buf); + + AssertEmpty(buf); + + // TODO[RFC 3546] Check whether empty certificates is possible, allowed, or excludes CertificateStatus + if (this.mPeerCertificate == null || this.mPeerCertificate.IsEmpty) + { + this.mAllowCertificateStatus = false; + } + + this.mKeyExchange.ProcessServerCertificate(this.mPeerCertificate); + + this.mAuthentication = mTlsClient.GetAuthentication(); + this.mAuthentication.NotifyServerCertificate(this.mPeerCertificate); + + break; + } + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + this.mConnectionState = CS_SERVER_CERTIFICATE; + break; + } + case HandshakeType.certificate_status: + { + switch (this.mConnectionState) + { + case CS_SERVER_CERTIFICATE: + { + if (!this.mAllowCertificateStatus) + { + /* + * RFC 3546 3.6. If a server returns a "CertificateStatus" message, then the + * server MUST have included an extension of type "status_request" with empty + * "extension_data" in the extended server hello.. + */ + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + this.mCertificateStatus = CertificateStatus.Parse(buf); + + AssertEmpty(buf); + + // TODO[RFC 3546] Figure out how to provide this to the client/authentication. + + this.mConnectionState = CS_CERTIFICATE_STATUS; + break; + } + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + break; + } + case HandshakeType.finished: + { + switch (this.mConnectionState) + { + case CS_CLIENT_FINISHED: + case CS_SERVER_SESSION_TICKET: + { + if (this.mConnectionState == CS_CLIENT_FINISHED && this.mExpectSessionTicket) + { + /* + * RFC 5077 3.3. This message MUST be sent if the server included a + * SessionTicket extension in the ServerHello. + */ + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + ProcessFinishedMessage(buf); + this.mConnectionState = CS_SERVER_FINISHED; + + CompleteHandshake(); + break; + } + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + break; + } + case HandshakeType.server_hello: + { + switch (this.mConnectionState) + { + case CS_CLIENT_HELLO: + { + ReceiveServerHelloMessage(buf); + this.mConnectionState = CS_SERVER_HELLO; + + this.mRecordStream.NotifyHelloComplete(); + + ApplyMaxFragmentLengthExtension(); + + if (this.mResumedSession) + { + this.mSecurityParameters.masterSecret = Arrays.Clone(this.mSessionParameters.MasterSecret); + this.mRecordStream.SetPendingConnectionState(Peer.GetCompression(), Peer.GetCipher()); + } + else + { + InvalidateSession(); + + if (this.mSelectedSessionID.Length > 0) + { + this.mTlsSession = new TlsSessionImpl(this.mSelectedSessionID, null); + } + } + + break; + } + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + break; + } + case HandshakeType.supplemental_data: + { + switch (this.mConnectionState) + { + case CS_SERVER_HELLO: + { + HandleSupplementalData(ReadSupplementalDataMessage(buf)); + break; + } + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + break; + } + case HandshakeType.server_hello_done: + { + switch (this.mConnectionState) + { + case CS_SERVER_HELLO: + case CS_SERVER_SUPPLEMENTAL_DATA: + case CS_SERVER_CERTIFICATE: + case CS_CERTIFICATE_STATUS: + case CS_SERVER_KEY_EXCHANGE: + case CS_CERTIFICATE_REQUEST: + { + if (mConnectionState < CS_SERVER_SUPPLEMENTAL_DATA) + { + HandleSupplementalData(null); + } + + if (mConnectionState < CS_SERVER_CERTIFICATE) + { + // There was no server certificate message; check it's OK + this.mKeyExchange.SkipServerCredentials(); + this.mAuthentication = null; + } + + if (mConnectionState < CS_SERVER_KEY_EXCHANGE) + { + // There was no server key exchange message; check it's OK + this.mKeyExchange.SkipServerKeyExchange(); + } + + AssertEmpty(buf); + + this.mConnectionState = CS_SERVER_HELLO_DONE; + + this.mRecordStream.HandshakeHash.SealHashAlgorithms(); + + IList clientSupplementalData = mTlsClient.GetClientSupplementalData(); + if (clientSupplementalData != null) + { + SendSupplementalDataMessage(clientSupplementalData); + } + this.mConnectionState = CS_CLIENT_SUPPLEMENTAL_DATA; + + TlsCredentials clientCreds = null; + if (mCertificateRequest == null) + { + this.mKeyExchange.SkipClientCredentials(); + } + else + { + clientCreds = this.mAuthentication.GetClientCredentials(mCertificateRequest); + + if (clientCreds == null) + { + this.mKeyExchange.SkipClientCredentials(); + + /* + * RFC 5246 If no suitable certificate is available, the client MUST Send a + * certificate message containing no certificates. + * + * NOTE: In previous RFCs, this was SHOULD instead of MUST. + */ + SendCertificateMessage(Certificate.EmptyChain); + } + else + { + this.mKeyExchange.ProcessClientCredentials(clientCreds); + + SendCertificateMessage(clientCreds.Certificate); + } + } + + this.mConnectionState = CS_CLIENT_CERTIFICATE; + + /* + * Send the client key exchange message, depending on the key exchange we are using + * in our CipherSuite. + */ + SendClientKeyExchangeMessage(); + this.mConnectionState = CS_CLIENT_KEY_EXCHANGE; + + if (TlsUtilities.IsSsl(Context)) + { + EstablishMasterSecret(Context, mKeyExchange); + } + + TlsHandshakeHash prepareFinishHash = mRecordStream.PrepareToFinish(); + this.mSecurityParameters.sessionHash = GetCurrentPrfHash(Context, prepareFinishHash, null); + + if (!TlsUtilities.IsSsl(Context)) + { + EstablishMasterSecret(Context, mKeyExchange); + } + + mRecordStream.SetPendingConnectionState(Peer.GetCompression(), Peer.GetCipher()); + + if (clientCreds != null && clientCreds is TlsSignerCredentials) + { + TlsSignerCredentials signerCredentials = (TlsSignerCredentials)clientCreds; + + /* + * RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm from TLS 1.2 + */ + SignatureAndHashAlgorithm signatureAndHashAlgorithm = TlsUtilities.GetSignatureAndHashAlgorithm( + Context, signerCredentials); + + byte[] hash; + if (signatureAndHashAlgorithm == null) + { + hash = mSecurityParameters.SessionHash; + } + else + { + hash = prepareFinishHash.GetFinalHash(signatureAndHashAlgorithm.Hash); + } + + byte[] signature = signerCredentials.GenerateCertificateSignature(hash); + DigitallySigned certificateVerify = new DigitallySigned(signatureAndHashAlgorithm, signature); + SendCertificateVerifyMessage(certificateVerify); + + this.mConnectionState = CS_CERTIFICATE_VERIFY; + } + + SendChangeCipherSpecMessage(); + SendFinishedMessage(); + break; + } + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + this.mConnectionState = CS_CLIENT_FINISHED; + break; + } + case HandshakeType.server_key_exchange: + { + switch (this.mConnectionState) + { + case CS_SERVER_HELLO: + case CS_SERVER_SUPPLEMENTAL_DATA: + case CS_SERVER_CERTIFICATE: + case CS_CERTIFICATE_STATUS: + { + if (mConnectionState < CS_SERVER_SUPPLEMENTAL_DATA) + { + HandleSupplementalData(null); + } + + if (mConnectionState < CS_SERVER_CERTIFICATE) + { + // There was no server certificate message; check it's OK + this.mKeyExchange.SkipServerCredentials(); + this.mAuthentication = null; + } + + this.mKeyExchange.ProcessServerKeyExchange(buf); + + AssertEmpty(buf); + break; + } + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + this.mConnectionState = CS_SERVER_KEY_EXCHANGE; + break; + } + case HandshakeType.certificate_request: + { + switch (this.mConnectionState) + { + case CS_SERVER_CERTIFICATE: + case CS_CERTIFICATE_STATUS: + case CS_SERVER_KEY_EXCHANGE: + { + if (this.mConnectionState != CS_SERVER_KEY_EXCHANGE) + { + // There was no server key exchange message; check it's OK + this.mKeyExchange.SkipServerKeyExchange(); + } + + if (this.mAuthentication == null) + { + /* + * RFC 2246 7.4.4. It is a fatal handshake_failure alert for an anonymous server + * to request client identification. + */ + throw new TlsFatalAlert(AlertDescription.handshake_failure); + } + + this.mCertificateRequest = CertificateRequest.Parse(Context, buf); + + AssertEmpty(buf); + + this.mKeyExchange.ValidateCertificateRequest(this.mCertificateRequest); + + /* + * TODO Give the client a chance to immediately select the CertificateVerify hash + * algorithm here to avoid tracking the other hash algorithms unnecessarily? + */ + TlsUtilities.TrackHashAlgorithms(this.mRecordStream.HandshakeHash, + this.mCertificateRequest.SupportedSignatureAlgorithms); + + break; + } + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + this.mConnectionState = CS_CERTIFICATE_REQUEST; + break; + } + case HandshakeType.session_ticket: + { + switch (this.mConnectionState) + { + case CS_CLIENT_FINISHED: + { + if (!this.mExpectSessionTicket) + { + /* + * RFC 5077 3.3. This message MUST NOT be sent if the server did not include a + * SessionTicket extension in the ServerHello. + */ + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + /* + * RFC 5077 3.4. If the client receives a session ticket from the server, then it + * discards any Session ID that was sent in the ServerHello. + */ + InvalidateSession(); + + ReceiveNewSessionTicketMessage(buf); + break; + } + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + this.mConnectionState = CS_SERVER_SESSION_TICKET; + break; + } + case HandshakeType.hello_request: + { + AssertEmpty(buf); + + /* + * RFC 2246 7.4.1.1 Hello request This message will be ignored by the client if the + * client is currently negotiating a session. This message may be ignored by the client + * if it does not wish to renegotiate a session, or the client may, if it wishes, + * respond with a no_renegotiation alert. + */ + if (this.mConnectionState == CS_END) + { + RefuseRenegotiation(); + } + break; + } + case HandshakeType.client_hello: + case HandshakeType.client_key_exchange: + case HandshakeType.certificate_verify: + case HandshakeType.hello_verify_request: + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + } + + protected virtual void HandleSupplementalData(IList serverSupplementalData) + { + this.mTlsClient.ProcessServerSupplementalData(serverSupplementalData); + this.mConnectionState = CS_SERVER_SUPPLEMENTAL_DATA; + + this.mKeyExchange = mTlsClient.GetKeyExchange(); + this.mKeyExchange.Init(Context); + } + + protected virtual void ReceiveNewSessionTicketMessage(MemoryStream buf) + { + NewSessionTicket newSessionTicket = NewSessionTicket.Parse(buf); + + AssertEmpty(buf); + + mTlsClient.NotifyNewSessionTicket(newSessionTicket); + } + + protected virtual void ReceiveServerHelloMessage(MemoryStream buf) + { + { + ProtocolVersion server_version = TlsUtilities.ReadVersion(buf); + if (server_version.IsDtls) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + // Check that this matches what the server is Sending in the record layer + if (!server_version.Equals(this.mRecordStream.ReadVersion)) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + ProtocolVersion client_version = Context.ClientVersion; + if (!server_version.IsEqualOrEarlierVersionOf(client_version)) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + this.mRecordStream.SetWriteVersion(server_version); + ContextAdmin.SetServerVersion(server_version); + this.mTlsClient.NotifyServerVersion(server_version); + } + + /* + * Read the server random + */ + this.mSecurityParameters.serverRandom = TlsUtilities.ReadFully(32, buf); + + this.mSelectedSessionID = TlsUtilities.ReadOpaque8(buf); + if (this.mSelectedSessionID.Length > 32) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + this.mTlsClient.NotifySessionID(this.mSelectedSessionID); + this.mResumedSession = this.mSelectedSessionID.Length > 0 && this.mTlsSession != null + && Arrays.AreEqual(this.mSelectedSessionID, this.mTlsSession.SessionID); + + /* + * Find out which CipherSuite the server has chosen and check that it was one of the offered + * ones, and is a valid selection for the negotiated version. + */ + int selectedCipherSuite = TlsUtilities.ReadUint16(buf); + if (!Arrays.Contains(this.mOfferedCipherSuites, selectedCipherSuite) + || selectedCipherSuite == CipherSuite.TLS_NULL_WITH_NULL_NULL + || CipherSuite.IsScsv(selectedCipherSuite) + || !TlsUtilities.IsValidCipherSuiteForVersion(selectedCipherSuite, Context.ServerVersion)) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + this.mTlsClient.NotifySelectedCipherSuite(selectedCipherSuite); + + /* + * Find out which CompressionMethod the server has chosen and check that it was one of the + * offered ones. + */ + byte selectedCompressionMethod = TlsUtilities.ReadUint8(buf); + if (!Arrays.Contains(this.mOfferedCompressionMethods, selectedCompressionMethod)) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + this.mTlsClient.NotifySelectedCompressionMethod(selectedCompressionMethod); + + /* + * RFC 3546 2.2 The extended server hello message format MAY be sent in place of the server + * hello message when the client has requested extended functionality via the extended + * client hello message specified in Section 2.1. ... Note that the extended server hello + * message is only sent in response to an extended client hello message. This prevents the + * possibility that the extended server hello message could "break" existing TLS 1.0 + * clients. + */ + this.mServerExtensions = ReadExtensions(buf); + + /* + * RFC 7627 4. Clients and servers SHOULD NOT accept handshakes that do not use the extended + * master secret [..]. (and see 5.2, 5.3) + */ + this.mSecurityParameters.extendedMasterSecret = !TlsUtilities.IsSsl(mTlsClientContext) + && TlsExtensionsUtilities.HasExtendedMasterSecretExtension(mServerExtensions); + + if (!mSecurityParameters.IsExtendedMasterSecret + && (mResumedSession || mTlsClient.RequiresExtendedMasterSecret())) + { + throw new TlsFatalAlert(AlertDescription.handshake_failure); + } + + /* + * RFC 3546 2.2 Note that the extended server hello message is only sent in response to an + * extended client hello message. + * + * However, see RFC 5746 exception below. We always include the SCSV, so an Extended Server + * Hello is always allowed. + */ + if (this.mServerExtensions != null) + { + foreach (int extType in this.mServerExtensions.Keys) + { + /* + * RFC 5746 3.6. Note that Sending a "renegotiation_info" extension in response to a + * ClientHello containing only the SCSV is an explicit exception to the prohibition + * in RFC 5246, Section 7.4.1.4, on the server Sending unsolicited extensions and is + * only allowed because the client is signaling its willingness to receive the + * extension via the TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV. + */ + if (extType == ExtensionType.renegotiation_info) + continue; + + /* + * RFC 5246 7.4.1.4 An extension type MUST NOT appear in the ServerHello unless the + * same extension type appeared in the corresponding ClientHello. If a client + * receives an extension type in ServerHello that it did not request in the + * associated ClientHello, it MUST abort the handshake with an unsupported_extension + * fatal alert. + */ + if (null == TlsUtilities.GetExtensionData(this.mClientExtensions, extType)) + throw new TlsFatalAlert(AlertDescription.unsupported_extension); + + /* + * RFC 3546 2.3. If [...] the older session is resumed, then the server MUST ignore + * extensions appearing in the client hello, and Send a server hello containing no + * extensions[.] + */ + if (this.mResumedSession) + { + // TODO[compat-gnutls] GnuTLS test server Sends server extensions e.g. ec_point_formats + // TODO[compat-openssl] OpenSSL test server Sends server extensions e.g. ec_point_formats + // TODO[compat-polarssl] PolarSSL test server Sends server extensions e.g. ec_point_formats + // throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + } + } + + /* + * RFC 5746 3.4. Client Behavior: Initial Handshake + */ + { + /* + * When a ServerHello is received, the client MUST check if it includes the + * "renegotiation_info" extension: + */ + byte[] renegExtData = TlsUtilities.GetExtensionData(this.mServerExtensions, ExtensionType.renegotiation_info); + if (renegExtData != null) + { + /* + * If the extension is present, set the secure_renegotiation flag to TRUE. The + * client MUST then verify that the length of the "renegotiated_connection" + * field is zero, and if it is not, MUST abort the handshake (by Sending a fatal + * handshake_failure alert). + */ + this.mSecureRenegotiation = true; + + if (!Arrays.ConstantTimeAreEqual(renegExtData, CreateRenegotiationInfo(TlsUtilities.EmptyBytes))) + throw new TlsFatalAlert(AlertDescription.handshake_failure); + } + } + + // TODO[compat-gnutls] GnuTLS test server fails to Send renegotiation_info extension when resuming + this.mTlsClient.NotifySecureRenegotiation(this.mSecureRenegotiation); + + IDictionary sessionClientExtensions = mClientExtensions, sessionServerExtensions = mServerExtensions; + if (this.mResumedSession) + { + if (selectedCipherSuite != this.mSessionParameters.CipherSuite + || selectedCompressionMethod != this.mSessionParameters.CompressionAlgorithm) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + sessionClientExtensions = null; + sessionServerExtensions = this.mSessionParameters.ReadServerExtensions(); + } + + this.mSecurityParameters.cipherSuite = selectedCipherSuite; + this.mSecurityParameters.compressionAlgorithm = selectedCompressionMethod; + + if (sessionServerExtensions != null && sessionServerExtensions.Count > 0) + { + { + /* + * RFC 7366 3. If a server receives an encrypt-then-MAC request extension from a client + * and then selects a stream or Authenticated Encryption with Associated Data (AEAD) + * ciphersuite, it MUST NOT send an encrypt-then-MAC response extension back to the + * client. + */ + bool serverSentEncryptThenMAC = TlsExtensionsUtilities.HasEncryptThenMacExtension(sessionServerExtensions); + if (serverSentEncryptThenMAC && !TlsUtilities.IsBlockCipherSuite(selectedCipherSuite)) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + this.mSecurityParameters.encryptThenMac = serverSentEncryptThenMAC; + } + + this.mSecurityParameters.maxFragmentLength = ProcessMaxFragmentLengthExtension(sessionClientExtensions, + sessionServerExtensions, AlertDescription.illegal_parameter); + + this.mSecurityParameters.truncatedHMac = TlsExtensionsUtilities.HasTruncatedHMacExtension(sessionServerExtensions); + + /* + * TODO It's surprising that there's no provision to allow a 'fresh' CertificateStatus to be sent in + * a session resumption handshake. + */ + this.mAllowCertificateStatus = !this.mResumedSession + && TlsUtilities.HasExpectedEmptyExtensionData(sessionServerExtensions, ExtensionType.status_request, + AlertDescription.illegal_parameter); + + this.mExpectSessionTicket = !this.mResumedSession + && TlsUtilities.HasExpectedEmptyExtensionData(sessionServerExtensions, ExtensionType.session_ticket, + AlertDescription.illegal_parameter); + } + + if (sessionClientExtensions != null) + { + this.mTlsClient.ProcessServerExtensions(sessionServerExtensions); + } + + this.mSecurityParameters.prfAlgorithm = GetPrfAlgorithm(Context, this.mSecurityParameters.CipherSuite); + + /* + * RFC 5246 7.4.9. Any cipher suite which does not explicitly specify + * verify_data_length has a verify_data_length equal to 12. This includes all + * existing cipher suites. + */ + this.mSecurityParameters.verifyDataLength = 12; + } + + protected virtual void SendCertificateVerifyMessage(DigitallySigned certificateVerify) + { + HandshakeMessage message = new HandshakeMessage(HandshakeType.certificate_verify); + + certificateVerify.Encode(message); + + message.WriteToRecordStream(this); + } + + protected virtual void SendClientHelloMessage() + { + this.mRecordStream.SetWriteVersion(this.mTlsClient.ClientHelloRecordLayerVersion); + + ProtocolVersion client_version = this.mTlsClient.ClientVersion; + if (client_version.IsDtls) + throw new TlsFatalAlert(AlertDescription.internal_error); + + ContextAdmin.SetClientVersion(client_version); + + /* + * TODO RFC 5077 3.4. When presenting a ticket, the client MAY generate and include a + * Session ID in the TLS ClientHello. + */ + byte[] session_id = TlsUtilities.EmptyBytes; + if (this.mTlsSession != null) + { + session_id = this.mTlsSession.SessionID; + if (session_id == null || session_id.Length > 32) + { + session_id = TlsUtilities.EmptyBytes; + } + } + + bool fallback = this.mTlsClient.IsFallback; + + this.mOfferedCipherSuites = this.mTlsClient.GetCipherSuites(); + + this.mOfferedCompressionMethods = this.mTlsClient.GetCompressionMethods(); + + if (session_id.Length > 0 && this.mSessionParameters != null) + { + if (!mSessionParameters.IsExtendedMasterSecret + || !Arrays.Contains(this.mOfferedCipherSuites, mSessionParameters.CipherSuite) + || !Arrays.Contains(this.mOfferedCompressionMethods, mSessionParameters.CompressionAlgorithm)) + { + session_id = TlsUtilities.EmptyBytes; + } + } + + this.mClientExtensions = TlsExtensionsUtilities.EnsureExtensionsInitialised(this.mTlsClient.GetClientExtensions()); + + if (!client_version.IsSsl) + { + TlsExtensionsUtilities.AddExtendedMasterSecretExtension(this.mClientExtensions); + } + + HandshakeMessage message = new HandshakeMessage(HandshakeType.client_hello); + + TlsUtilities.WriteVersion(client_version, message); + + message.Write(this.mSecurityParameters.ClientRandom); + + TlsUtilities.WriteOpaque8(session_id, message); + + // Cipher Suites (and SCSV) + { + /* + * RFC 5746 3.4. The client MUST include either an empty "renegotiation_info" extension, + * or the TLS_EMPTY_RENEGOTIATION_INFO_SCSV signaling cipher suite value in the + * ClientHello. Including both is NOT RECOMMENDED. + */ + byte[] renegExtData = TlsUtilities.GetExtensionData(mClientExtensions, ExtensionType.renegotiation_info); + bool noRenegExt = (null == renegExtData); + + bool noRenegScsv = !Arrays.Contains(mOfferedCipherSuites, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV); + + if (noRenegExt && noRenegScsv) + { + // TODO Consider whether to default to a client extension instead + this.mOfferedCipherSuites = Arrays.Append(mOfferedCipherSuites, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV); + } + + /* + * RFC 7507 4. If a client sends a ClientHello.client_version containing a lower value + * than the latest (highest-valued) version supported by the client, it SHOULD include + * the TLS_FALLBACK_SCSV cipher suite value in ClientHello.cipher_suites [..]. (The + * client SHOULD put TLS_FALLBACK_SCSV after all cipher suites that it actually intends + * to negotiate.) + */ + if (fallback && !Arrays.Contains(mOfferedCipherSuites, CipherSuite.TLS_FALLBACK_SCSV)) + { + this.mOfferedCipherSuites = Arrays.Append(mOfferedCipherSuites, CipherSuite.TLS_FALLBACK_SCSV); + } + + TlsUtilities.WriteUint16ArrayWithUint16Length(mOfferedCipherSuites, message); + } + + TlsUtilities.WriteUint8ArrayWithUint8Length(mOfferedCompressionMethods, message); + + WriteExtensions(message, mClientExtensions); + + message.WriteToRecordStream(this); + } + + protected virtual void SendClientKeyExchangeMessage() + { + HandshakeMessage message = new HandshakeMessage(HandshakeType.client_key_exchange); + + this.mKeyExchange.GenerateClientKeyExchange(message); + + message.WriteToRecordStream(this); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsClientProtocol.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsClientProtocol.cs.meta new file mode 100644 index 0000000..5d63742 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsClientProtocol.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 463117a394e617747b7eab44190ca835 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsCloseable.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsCloseable.cs new file mode 100644 index 0000000..01625d7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsCloseable.cs @@ -0,0 +1,11 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public interface TlsCloseable + { + /// + void Close(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsCloseable.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsCloseable.cs.meta new file mode 100644 index 0000000..d30b94f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsCloseable.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d3f1232603e297e46bee977fbf0a73c3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsCompression.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsCompression.cs new file mode 100644 index 0000000..177d64b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsCompression.cs @@ -0,0 +1,12 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public interface TlsCompression + { + Stream Compress(Stream output); + + Stream Decompress(Stream output); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsCompression.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsCompression.cs.meta new file mode 100644 index 0000000..c844542 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsCompression.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ab6aa1816b4002448bb12b9c83c8a8d8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsContext.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsContext.cs new file mode 100644 index 0000000..d066723 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsContext.cs @@ -0,0 +1,45 @@ +using System; + +using Org.BouncyCastle.Crypto.Prng; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public interface TlsContext + { + IRandomGenerator NonceRandomGenerator { get; } + + SecureRandom SecureRandom { get; } + + SecurityParameters SecurityParameters { get; } + + bool IsServer { get; } + + ProtocolVersion ClientVersion { get; } + + ProtocolVersion ServerVersion { get; } + + /** + * Used to get the resumable session, if any, used by this connection. Only available after the + * handshake has successfully completed. + * + * @return A {@link TlsSession} representing the resumable session used by this connection, or + * null if no resumable session available. + * @see TlsPeer#NotifyHandshakeComplete() + */ + TlsSession ResumableSession { get; } + + object UserObject { get; set; } + + /** + * Export keying material according to RFC 5705: "Keying Material Exporters for TLS". + * + * @param asciiLabel indicates which application will use the exported keys. + * @param context_value allows the application using the exporter to mix its own data with the TLS PRF for + * the exporter output. + * @param length the number of bytes to generate + * @return a pseudorandom bit string of 'length' bytes generated from the master_secret. + */ + byte[] ExportKeyingMaterial(string asciiLabel, byte[] context_value, int length); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsContext.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsContext.cs.meta new file mode 100644 index 0000000..2b65f9f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsContext.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cd94519e6e2cfbc459cfeabc5fe40f25 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsCredentials.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsCredentials.cs new file mode 100644 index 0000000..5c5f1c0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsCredentials.cs @@ -0,0 +1,9 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public interface TlsCredentials + { + Certificate Certificate { get; } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsCredentials.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsCredentials.cs.meta new file mode 100644 index 0000000..9937d23 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsCredentials.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 696d807de4044a54f947c5c75b310b6e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsDHKeyExchange.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsDHKeyExchange.cs new file mode 100644 index 0000000..63abe27 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsDHKeyExchange.cs @@ -0,0 +1,249 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// (D)TLS DH key exchange. + public class TlsDHKeyExchange + : AbstractTlsKeyExchange + { + protected TlsSigner mTlsSigner; + protected TlsDHVerifier mDHVerifier; + protected DHParameters mDHParameters; + + protected AsymmetricKeyParameter mServerPublicKey; + protected TlsAgreementCredentials mAgreementCredentials; + + protected DHPrivateKeyParameters mDHAgreePrivateKey; + protected DHPublicKeyParameters mDHAgreePublicKey; + + [Obsolete("Use constructor that takes a TlsDHVerifier")] + public TlsDHKeyExchange(int keyExchange, IList supportedSignatureAlgorithms, DHParameters dhParameters) + : this(keyExchange, supportedSignatureAlgorithms, new DefaultTlsDHVerifier(), dhParameters) + { + } + + public TlsDHKeyExchange(int keyExchange, IList supportedSignatureAlgorithms, TlsDHVerifier dhVerifier, DHParameters dhParameters) + : base(keyExchange, supportedSignatureAlgorithms) + { + switch (keyExchange) + { + case KeyExchangeAlgorithm.DH_anon: + case KeyExchangeAlgorithm.DH_RSA: + case KeyExchangeAlgorithm.DH_DSS: + this.mTlsSigner = null; + break; + case KeyExchangeAlgorithm.DHE_RSA: + this.mTlsSigner = new TlsRsaSigner(); + break; + case KeyExchangeAlgorithm.DHE_DSS: + this.mTlsSigner = new TlsDssSigner(); + break; + default: + throw new InvalidOperationException("unsupported key exchange algorithm"); + } + + this.mDHVerifier = dhVerifier; + this.mDHParameters = dhParameters; + } + + public override void Init(TlsContext context) + { + base.Init(context); + + if (this.mTlsSigner != null) + { + this.mTlsSigner.Init(context); + } + } + + public override void SkipServerCredentials() + { + if (mKeyExchange != KeyExchangeAlgorithm.DH_anon) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + public override void ProcessServerCertificate(Certificate serverCertificate) + { + if (mKeyExchange == KeyExchangeAlgorithm.DH_anon) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + if (serverCertificate.IsEmpty) + throw new TlsFatalAlert(AlertDescription.decode_error); + + X509CertificateStructure x509Cert = serverCertificate.GetCertificateAt(0); + + SubjectPublicKeyInfo keyInfo = x509Cert.SubjectPublicKeyInfo; + try + { + this.mServerPublicKey = PublicKeyFactory.CreateKey(keyInfo); + } + catch (Exception e) + { + throw new TlsFatalAlert(AlertDescription.unsupported_certificate, e); + } + + if (mTlsSigner == null) + { + try + { + this.mDHAgreePublicKey = (DHPublicKeyParameters)this.mServerPublicKey; + this.mDHParameters = mDHAgreePublicKey.Parameters; + } + catch (InvalidCastException e) + { + throw new TlsFatalAlert(AlertDescription.certificate_unknown, e); + } + + TlsUtilities.ValidateKeyUsage(x509Cert, KeyUsage.KeyAgreement); + } + else + { + if (!mTlsSigner.IsValidPublicKey(this.mServerPublicKey)) + { + throw new TlsFatalAlert(AlertDescription.certificate_unknown); + } + + TlsUtilities.ValidateKeyUsage(x509Cert, KeyUsage.DigitalSignature); + } + + base.ProcessServerCertificate(serverCertificate); + } + + public override bool RequiresServerKeyExchange + { + get + { + switch (mKeyExchange) + { + case KeyExchangeAlgorithm.DH_anon: + case KeyExchangeAlgorithm.DHE_DSS: + case KeyExchangeAlgorithm.DHE_RSA: + return true; + default: + return false; + } + } + } + + public override byte[] GenerateServerKeyExchange() + { + if (!RequiresServerKeyExchange) + return null; + + // DH_anon is handled here, DHE_* in a subclass + + MemoryStream buf = new MemoryStream(); + this.mDHAgreePrivateKey = TlsDHUtilities.GenerateEphemeralServerKeyExchange(mContext.SecureRandom, + this.mDHParameters, buf); + return buf.ToArray(); + } + + public override void ProcessServerKeyExchange(Stream input) + { + if (!RequiresServerKeyExchange) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + + // DH_anon is handled here, DHE_* in a subclass + + this.mDHParameters = TlsDHUtilities.ReceiveDHParameters(mDHVerifier, input); + this.mDHAgreePublicKey = new DHPublicKeyParameters(TlsDHUtilities.ReadDHParameter(input), mDHParameters); + } + + public override void ValidateCertificateRequest(CertificateRequest certificateRequest) + { + if (mKeyExchange == KeyExchangeAlgorithm.DH_anon) + throw new TlsFatalAlert(AlertDescription.handshake_failure); + + byte[] types = certificateRequest.CertificateTypes; + for (int i = 0; i < types.Length; ++i) + { + switch (types[i]) + { + case ClientCertificateType.rsa_sign: + case ClientCertificateType.dss_sign: + case ClientCertificateType.rsa_fixed_dh: + case ClientCertificateType.dss_fixed_dh: + case ClientCertificateType.ecdsa_sign: + break; + default: + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + } + } + + public override void ProcessClientCredentials(TlsCredentials clientCredentials) + { + if (mKeyExchange == KeyExchangeAlgorithm.DH_anon) + throw new TlsFatalAlert(AlertDescription.internal_error); + + if (clientCredentials is TlsAgreementCredentials) + { + // TODO Validate client cert has matching parameters (see 'areCompatibleParameters')? + + this.mAgreementCredentials = (TlsAgreementCredentials)clientCredentials; + } + else if (clientCredentials is TlsSignerCredentials) + { + // OK + } + else + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + public override void GenerateClientKeyExchange(Stream output) + { + /* + * RFC 2246 7.4.7.2 If the client certificate already contains a suitable Diffie-Hellman + * key, then Yc is implicit and does not need to be sent again. In this case, the Client Key + * Exchange message will be sent, but will be empty. + */ + if (mAgreementCredentials == null) + { + this.mDHAgreePrivateKey = TlsDHUtilities.GenerateEphemeralClientKeyExchange(mContext.SecureRandom, + mDHParameters, output); + } + } + + public override void ProcessClientCertificate(Certificate clientCertificate) + { + if (mKeyExchange == KeyExchangeAlgorithm.DH_anon) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + + // TODO Extract the public key + // TODO If the certificate is 'fixed', take the public key as dhAgreePublicKey + } + + public override void ProcessClientKeyExchange(Stream input) + { + if (mDHAgreePublicKey != null) + { + // For dss_fixed_dh and rsa_fixed_dh, the key arrived in the client certificate + return; + } + + this.mDHAgreePublicKey = new DHPublicKeyParameters(TlsDHUtilities.ReadDHParameter(input), mDHParameters); + } + + public override byte[] GeneratePremasterSecret() + { + if (mAgreementCredentials != null) + { + return mAgreementCredentials.GenerateAgreement(mDHAgreePublicKey); + } + + if (mDHAgreePrivateKey != null) + { + return TlsDHUtilities.CalculateDHBasicAgreement(mDHAgreePublicKey, mDHAgreePrivateKey); + } + + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsDHKeyExchange.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsDHKeyExchange.cs.meta new file mode 100644 index 0000000..d5c64da --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsDHKeyExchange.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 644cdb181556b8c468b47dfdc8e497cf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsDHUtilities.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsDHUtilities.cs new file mode 100644 index 0000000..fb52133 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsDHUtilities.cs @@ -0,0 +1,470 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Crypto.Agreement; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class TlsDHUtilities + { + internal static readonly BigInteger Two = BigInteger.Two; + + /* + * TODO[draft-ietf-tls-negotiated-ff-dhe-01] Move these groups to DHStandardGroups once reaches RFC + */ + private static BigInteger FromHex(String hex) + { + return new BigInteger(1, Hex.DecodeStrict(hex)); + } + + private static DHParameters FromSafeP(String hexP) + { + BigInteger p = FromHex(hexP), q = p.ShiftRight(1); + return new DHParameters(p, Two, q); + } + + private static readonly string draft_ffdhe2432_p = + "FFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1" + + "D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF9" + + "7D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD6561" + + "2433F51F5F066ED0856365553DED1AF3B557135E7F57C935" + + "984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE735" + + "30ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FB" + + "B96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB19" + + "0B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F61" + + "9172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD73" + + "3BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA" + + "886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C0238" + + "61B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91C" + + "AEFE13098533C8B3FFFFFFFFFFFFFFFF"; + internal static readonly DHParameters draft_ffdhe2432 = FromSafeP(draft_ffdhe2432_p); + + private static readonly string draft_ffdhe3072_p = + "FFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1" + + "D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF9" + + "7D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD6561" + + "2433F51F5F066ED0856365553DED1AF3B557135E7F57C935" + + "984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE735" + + "30ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FB" + + "B96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB19" + + "0B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F61" + + "9172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD73" + + "3BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA" + + "886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C0238" + + "61B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91C" + + "AEFE130985139270B4130C93BC437944F4FD4452E2D74DD3" + + "64F2E21E71F54BFF5CAE82AB9C9DF69EE86D2BC522363A0D" + + "ABC521979B0DEADA1DBF9A42D5C4484E0ABCD06BFA53DDEF" + + "3C1B20EE3FD59D7C25E41D2B66C62E37FFFFFFFFFFFFFFFF"; + internal static readonly DHParameters draft_ffdhe3072 = FromSafeP(draft_ffdhe3072_p); + + private static readonly string draft_ffdhe4096_p = + "FFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1" + + "D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF9" + + "7D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD6561" + + "2433F51F5F066ED0856365553DED1AF3B557135E7F57C935" + + "984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE735" + + "30ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FB" + + "B96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB19" + + "0B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F61" + + "9172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD73" + + "3BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA" + + "886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C0238" + + "61B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91C" + + "AEFE130985139270B4130C93BC437944F4FD4452E2D74DD3" + + "64F2E21E71F54BFF5CAE82AB9C9DF69EE86D2BC522363A0D" + + "ABC521979B0DEADA1DBF9A42D5C4484E0ABCD06BFA53DDEF" + + "3C1B20EE3FD59D7C25E41D2B669E1EF16E6F52C3164DF4FB" + + "7930E9E4E58857B6AC7D5F42D69F6D187763CF1D55034004" + + "87F55BA57E31CC7A7135C886EFB4318AED6A1E012D9E6832" + + "A907600A918130C46DC778F971AD0038092999A333CB8B7A" + + "1A1DB93D7140003C2A4ECEA9F98D0ACC0A8291CDCEC97DCF" + + "8EC9B55A7F88A46B4DB5A851F44182E1C68A007E5E655F6A" + + "FFFFFFFFFFFFFFFF"; + internal static readonly DHParameters draft_ffdhe4096 = FromSafeP(draft_ffdhe4096_p); + + private static readonly string draft_ffdhe6144_p = + "FFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1" + + "D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF9" + + "7D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD6561" + + "2433F51F5F066ED0856365553DED1AF3B557135E7F57C935" + + "984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE735" + + "30ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FB" + + "B96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB19" + + "0B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F61" + + "9172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD73" + + "3BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA" + + "886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C0238" + + "61B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91C" + + "AEFE130985139270B4130C93BC437944F4FD4452E2D74DD3" + + "64F2E21E71F54BFF5CAE82AB9C9DF69EE86D2BC522363A0D" + + "ABC521979B0DEADA1DBF9A42D5C4484E0ABCD06BFA53DDEF" + + "3C1B20EE3FD59D7C25E41D2B669E1EF16E6F52C3164DF4FB" + + "7930E9E4E58857B6AC7D5F42D69F6D187763CF1D55034004" + + "87F55BA57E31CC7A7135C886EFB4318AED6A1E012D9E6832" + + "A907600A918130C46DC778F971AD0038092999A333CB8B7A" + + "1A1DB93D7140003C2A4ECEA9F98D0ACC0A8291CDCEC97DCF" + + "8EC9B55A7F88A46B4DB5A851F44182E1C68A007E5E0DD902" + + "0BFD64B645036C7A4E677D2C38532A3A23BA4442CAF53EA6" + + "3BB454329B7624C8917BDD64B1C0FD4CB38E8C334C701C3A" + + "CDAD0657FCCFEC719B1F5C3E4E46041F388147FB4CFDB477" + + "A52471F7A9A96910B855322EDB6340D8A00EF092350511E3" + + "0ABEC1FFF9E3A26E7FB29F8C183023C3587E38DA0077D9B4" + + "763E4E4B94B2BBC194C6651E77CAF992EEAAC0232A281BF6" + + "B3A739C1226116820AE8DB5847A67CBEF9C9091B462D538C" + + "D72B03746AE77F5E62292C311562A846505DC82DB854338A" + + "E49F5235C95B91178CCF2DD5CACEF403EC9D1810C6272B04" + + "5B3B71F9DC6B80D63FDD4A8E9ADB1E6962A69526D43161C1" + + "A41D570D7938DAD4A40E329CD0E40E65FFFFFFFFFFFFFFFF"; + internal static readonly DHParameters draft_ffdhe6144 = FromSafeP(draft_ffdhe6144_p); + + private static readonly string draft_ffdhe8192_p = + "FFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1" + + "D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF9" + + "7D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD6561" + + "2433F51F5F066ED0856365553DED1AF3B557135E7F57C935" + + "984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE735" + + "30ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FB" + + "B96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB19" + + "0B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F61" + + "9172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD73" + + "3BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA" + + "886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C0238" + + "61B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91C" + + "AEFE130985139270B4130C93BC437944F4FD4452E2D74DD3" + + "64F2E21E71F54BFF5CAE82AB9C9DF69EE86D2BC522363A0D" + + "ABC521979B0DEADA1DBF9A42D5C4484E0ABCD06BFA53DDEF" + + "3C1B20EE3FD59D7C25E41D2B669E1EF16E6F52C3164DF4FB" + + "7930E9E4E58857B6AC7D5F42D69F6D187763CF1D55034004" + + "87F55BA57E31CC7A7135C886EFB4318AED6A1E012D9E6832" + + "A907600A918130C46DC778F971AD0038092999A333CB8B7A" + + "1A1DB93D7140003C2A4ECEA9F98D0ACC0A8291CDCEC97DCF" + + "8EC9B55A7F88A46B4DB5A851F44182E1C68A007E5E0DD902" + + "0BFD64B645036C7A4E677D2C38532A3A23BA4442CAF53EA6" + + "3BB454329B7624C8917BDD64B1C0FD4CB38E8C334C701C3A" + + "CDAD0657FCCFEC719B1F5C3E4E46041F388147FB4CFDB477" + + "A52471F7A9A96910B855322EDB6340D8A00EF092350511E3" + + "0ABEC1FFF9E3A26E7FB29F8C183023C3587E38DA0077D9B4" + + "763E4E4B94B2BBC194C6651E77CAF992EEAAC0232A281BF6" + + "B3A739C1226116820AE8DB5847A67CBEF9C9091B462D538C" + + "D72B03746AE77F5E62292C311562A846505DC82DB854338A" + + "E49F5235C95B91178CCF2DD5CACEF403EC9D1810C6272B04" + + "5B3B71F9DC6B80D63FDD4A8E9ADB1E6962A69526D43161C1" + + "A41D570D7938DAD4A40E329CCFF46AAA36AD004CF600C838" + + "1E425A31D951AE64FDB23FCEC9509D43687FEB69EDD1CC5E" + + "0B8CC3BDF64B10EF86B63142A3AB8829555B2F747C932665" + + "CB2C0F1CC01BD70229388839D2AF05E454504AC78B758282" + + "2846C0BA35C35F5C59160CC046FD8251541FC68C9C86B022" + + "BB7099876A460E7451A8A93109703FEE1C217E6C3826E52C" + + "51AA691E0E423CFC99E9E31650C1217B624816CDAD9A95F9" + + "D5B8019488D9C0A0A1FE3075A577E23183F81D4A3F2FA457" + + "1EFC8CE0BA8A4FE8B6855DFE72B0A66EDED2FBABFBE58A30" + + "FAFABE1C5D71A87E2F741EF8C1FE86FEA6BBFDE530677F0D" + + "97D11D49F7A8443D0822E506A9F4614E011E2A94838FF88C" + + "D68C8BB7C5C6424CFFFFFFFFFFFFFFFF"; + internal static readonly DHParameters draft_ffdhe8192 = FromSafeP(draft_ffdhe8192_p); + + + public static void AddNegotiatedDheGroupsClientExtension(IDictionary extensions, byte[] dheGroups) + { + extensions[ExtensionType.negotiated_ff_dhe_groups] = CreateNegotiatedDheGroupsClientExtension(dheGroups); + } + + public static void AddNegotiatedDheGroupsServerExtension(IDictionary extensions, byte dheGroup) + { + extensions[ExtensionType.negotiated_ff_dhe_groups] = CreateNegotiatedDheGroupsServerExtension(dheGroup); + } + + public static byte[] GetNegotiatedDheGroupsClientExtension(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.negotiated_ff_dhe_groups); + return extensionData == null ? null : ReadNegotiatedDheGroupsClientExtension(extensionData); + } + + public static short GetNegotiatedDheGroupsServerExtension(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.negotiated_ff_dhe_groups); + return extensionData == null ? (short)-1 : (short)ReadNegotiatedDheGroupsServerExtension(extensionData); + } + + public static byte[] CreateNegotiatedDheGroupsClientExtension(byte[] dheGroups) + { + if (dheGroups == null || dheGroups.Length < 1 || dheGroups.Length > 255) + throw new TlsFatalAlert(AlertDescription.internal_error); + + return TlsUtilities.EncodeUint8ArrayWithUint8Length(dheGroups); + } + + public static byte[] CreateNegotiatedDheGroupsServerExtension(byte dheGroup) + { + return TlsUtilities.EncodeUint8(dheGroup); + } + + public static byte[] ReadNegotiatedDheGroupsClientExtension(byte[] extensionData) + { + byte[] dheGroups = TlsUtilities.DecodeUint8ArrayWithUint8Length(extensionData); + if (dheGroups.Length < 1) + throw new TlsFatalAlert(AlertDescription.decode_error); + return dheGroups; + } + + public static byte ReadNegotiatedDheGroupsServerExtension(byte[] extensionData) + { + return TlsUtilities.DecodeUint8(extensionData); + } + + public static DHParameters GetParametersForDHEGroup(short dheGroup) + { + switch (dheGroup) + { + case FiniteFieldDheGroup.ffdhe2432: + return draft_ffdhe2432; + case FiniteFieldDheGroup.ffdhe3072: + return draft_ffdhe3072; + case FiniteFieldDheGroup.ffdhe4096: + return draft_ffdhe4096; + case FiniteFieldDheGroup.ffdhe6144: + return draft_ffdhe6144; + case FiniteFieldDheGroup.ffdhe8192: + return draft_ffdhe8192; + default: + return null; + } + } + + public static bool ContainsDheCipherSuites(int[] cipherSuites) + { + for (int i = 0; i < cipherSuites.Length; ++i) + { + if (IsDheCipherSuite(cipherSuites[i])) + return true; + } + return false; + } + + public static bool IsDheCipherSuite(int cipherSuite) + { + switch (cipherSuite) + { + /* + * RFC 2246 + */ + case CipherSuite.TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_DES_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_DES_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA: + + /* + * RFC 3268 + */ + case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA: + + /* + * RFC 5932 + */ + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256: + + /* + * RFC 4162 + */ + case CipherSuite.TLS_DHE_DSS_WITH_SEED_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_SEED_CBC_SHA: + + /* + * RFC 4279 + */ + case CipherSuite.TLS_DHE_PSK_WITH_RC4_128_SHA: + case CipherSuite.TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA: + + /* + * RFC 4785 + */ + case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA: + + /* + * RFC 5246 + */ + case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: + + /* + * RFC 5288 + */ + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_AES_256_GCM_SHA384: + + /* + * RFC 5487 + */ + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA384: + + /* + * RFC 6367 + */ + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384: + + /* + * RFC 6655 + */ + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM_8: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM_8: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CCM: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CCM: + case CipherSuite.TLS_PSK_DHE_WITH_AES_128_CCM_8: + case CipherSuite.TLS_PSK_DHE_WITH_AES_256_CCM_8: + + /* + * draft-ietf-tls-chacha20-poly1305-04 + */ + case CipherSuite.DRAFT_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.DRAFT_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256: + + /* + * DH_anon cipher suites are consider ephemeral DH + */ + case CipherSuite.TLS_DH_anon_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DH_anon_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DH_anon_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DH_anon_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DH_anon_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DH_anon_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DH_anon_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DH_anon_WITH_RC4_128_MD5: + case CipherSuite.TLS_DH_anon_WITH_SEED_CBC_SHA: + + return true; + + default: + return false; + } + } + + public static bool AreCompatibleParameters(DHParameters a, DHParameters b) + { + return a.P.Equals(b.P) && a.G.Equals(b.G) + && (a.Q == null || b.Q == null || a.Q.Equals(b.Q)); + } + + public static byte[] CalculateDHBasicAgreement(DHPublicKeyParameters publicKey, + DHPrivateKeyParameters privateKey) + { + DHBasicAgreement basicAgreement = new DHBasicAgreement(); + basicAgreement.Init(privateKey); + BigInteger agreementValue = basicAgreement.CalculateAgreement(publicKey); + + /* + * RFC 5246 8.1.2. Leading bytes of Z that contain all zero bits are stripped before it is + * used as the pre_master_secret. + */ + return BigIntegers.AsUnsignedByteArray(agreementValue); + } + + public static AsymmetricCipherKeyPair GenerateDHKeyPair(SecureRandom random, DHParameters dhParams) + { + DHBasicKeyPairGenerator dhGen = new DHBasicKeyPairGenerator(); + dhGen.Init(new DHKeyGenerationParameters(random, dhParams)); + return dhGen.GenerateKeyPair(); + } + + public static DHPrivateKeyParameters GenerateEphemeralClientKeyExchange(SecureRandom random, + DHParameters dhParams, Stream output) + { + AsymmetricCipherKeyPair kp = GenerateDHKeyPair(random, dhParams); + + DHPublicKeyParameters dhPublic = (DHPublicKeyParameters)kp.Public; + WriteDHParameter(dhPublic.Y, output); + + return (DHPrivateKeyParameters)kp.Private; + } + + public static DHPrivateKeyParameters GenerateEphemeralServerKeyExchange(SecureRandom random, + DHParameters dhParams, Stream output) + { + AsymmetricCipherKeyPair kp = GenerateDHKeyPair(random, dhParams); + + DHPublicKeyParameters dhPublic = (DHPublicKeyParameters)kp.Public; + WriteDHParameters(dhParams, output); + WriteDHParameter(dhPublic.Y, output); + + return (DHPrivateKeyParameters)kp.Private; + } + + public static BigInteger ReadDHParameter(Stream input) + { + return new BigInteger(1, TlsUtilities.ReadOpaque16(input)); + } + + public static DHParameters ReadDHParameters(Stream input) + { + BigInteger p = ReadDHParameter(input); + BigInteger g = ReadDHParameter(input); + + return new DHParameters(p, g); + } + + public static DHParameters ReceiveDHParameters(TlsDHVerifier dhVerifier, Stream input) + { + DHParameters dhParameters = ReadDHParameters(input); + if (!dhVerifier.Accept(dhParameters)) + throw new TlsFatalAlert(AlertDescription.insufficient_security); + + return dhParameters; + } + + public static void WriteDHParameter(BigInteger x, Stream output) + { + TlsUtilities.WriteOpaque16(BigIntegers.AsUnsignedByteArray(x), output); + } + + public static void WriteDHParameters(DHParameters dhParameters, Stream output) + { + WriteDHParameter(dhParameters.P, output); + WriteDHParameter(dhParameters.G, output); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsDHUtilities.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsDHUtilities.cs.meta new file mode 100644 index 0000000..f93e2f9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsDHUtilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ba4e89d6f8291504586f0356a2b9cc62 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsDHVerifier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsDHVerifier.cs new file mode 100644 index 0000000..867403c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsDHVerifier.cs @@ -0,0 +1,15 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// An interface for verifying that Diffie-Hellman parameters are acceptable. + public interface TlsDHVerifier + { + /// Verify that the given DHParameters are acceptable. + /// The DHParameters to verify. + /// true if (and only if) the specified parameters are acceptable. + bool Accept(DHParameters dhParameters); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsDHVerifier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsDHVerifier.cs.meta new file mode 100644 index 0000000..bf00bbe --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsDHVerifier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 35aac3e6758efee4aad9408ca516443f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsDeflateCompression.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsDeflateCompression.cs new file mode 100644 index 0000000..9e11529 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsDeflateCompression.cs @@ -0,0 +1,68 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Utilities.Zlib; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class TlsDeflateCompression : TlsCompression + { + public const int LEVEL_NONE = JZlib.Z_NO_COMPRESSION; + public const int LEVEL_FASTEST = JZlib.Z_BEST_SPEED; + public const int LEVEL_SMALLEST = JZlib.Z_BEST_COMPRESSION; + public const int LEVEL_DEFAULT = JZlib.Z_DEFAULT_COMPRESSION; + + protected readonly ZStream zIn, zOut; + + public TlsDeflateCompression() + : this(LEVEL_DEFAULT) + { + } + + public TlsDeflateCompression(int level) + { + this.zIn = new ZStream(); + this.zIn.inflateInit(); + + this.zOut = new ZStream(); + this.zOut.deflateInit(level); + } + + public virtual Stream Compress(Stream output) + { + return new DeflateOutputStream(output, zOut, true); + } + + public virtual Stream Decompress(Stream output) + { + return new DeflateOutputStream(output, zIn, false); + } + + protected class DeflateOutputStream : ZOutputStream + { + public DeflateOutputStream(Stream output, ZStream z, bool compress) + : base(output, z) + { + this.compress = compress; + + /* + * See discussion at http://www.bolet.org/~pornin/deflate-flush.html . + */ + this.FlushMode = JZlib.Z_SYNC_FLUSH; + } + + public override void Flush() + { + /* + * TODO The inflateSyncPoint doesn't appear to work the way I hoped at the moment. + * In any case, we may like to accept PARTIAL_FLUSH input, not just SYNC_FLUSH. + * It's not clear how to check this in the Inflater. + */ + //if (!this.compress && (z == null || z.istate == null || z.istate.inflateSyncPoint(z) <= 0)) + //{ + // throw new TlsFatalAlert(AlertDescription.decompression_failure); + //} + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsDeflateCompression.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsDeflateCompression.cs.meta new file mode 100644 index 0000000..24e10fa --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsDeflateCompression.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 83c7d11a4a3aab6438bbf6912637ea4c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsDheKeyExchange.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsDheKeyExchange.cs new file mode 100644 index 0000000..5007d7d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsDheKeyExchange.cs @@ -0,0 +1,97 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class TlsDheKeyExchange + : TlsDHKeyExchange + { + protected TlsSignerCredentials mServerCredentials = null; + + [Obsolete("Use constructor that takes a TlsDHVerifier")] + public TlsDheKeyExchange(int keyExchange, IList supportedSignatureAlgorithms, DHParameters dhParameters) + : this(keyExchange, supportedSignatureAlgorithms, new DefaultTlsDHVerifier(), dhParameters) + { + } + + public TlsDheKeyExchange(int keyExchange, IList supportedSignatureAlgorithms, TlsDHVerifier dhVerifier, DHParameters dhParameters) + : base(keyExchange, supportedSignatureAlgorithms, dhVerifier, dhParameters) + { + } + + public override void ProcessServerCredentials(TlsCredentials serverCredentials) + { + if (!(serverCredentials is TlsSignerCredentials)) + throw new TlsFatalAlert(AlertDescription.internal_error); + + ProcessServerCertificate(serverCredentials.Certificate); + + this.mServerCredentials = (TlsSignerCredentials)serverCredentials; + } + + public override byte[] GenerateServerKeyExchange() + { + if (this.mDHParameters == null) + throw new TlsFatalAlert(AlertDescription.internal_error); + + DigestInputBuffer buf = new DigestInputBuffer(); + + this.mDHAgreePrivateKey = TlsDHUtilities.GenerateEphemeralServerKeyExchange(mContext.SecureRandom, + this.mDHParameters, buf); + + /* + * RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm from TLS 1.2 + */ + SignatureAndHashAlgorithm signatureAndHashAlgorithm = TlsUtilities.GetSignatureAndHashAlgorithm( + mContext, mServerCredentials); + + IDigest d = TlsUtilities.CreateHash(signatureAndHashAlgorithm); + + SecurityParameters securityParameters = mContext.SecurityParameters; + d.BlockUpdate(securityParameters.clientRandom, 0, securityParameters.clientRandom.Length); + d.BlockUpdate(securityParameters.serverRandom, 0, securityParameters.serverRandom.Length); + buf.UpdateDigest(d); + + byte[] hash = DigestUtilities.DoFinal(d); + + byte[] signature = mServerCredentials.GenerateCertificateSignature(hash); + + DigitallySigned signed_params = new DigitallySigned(signatureAndHashAlgorithm, signature); + signed_params.Encode(buf); + + return buf.ToArray(); + } + + public override void ProcessServerKeyExchange(Stream input) + { + SecurityParameters securityParameters = mContext.SecurityParameters; + + SignerInputBuffer buf = new SignerInputBuffer(); + Stream teeIn = new TeeInputStream(input, buf); + + this.mDHParameters = TlsDHUtilities.ReceiveDHParameters(mDHVerifier, teeIn); + this.mDHAgreePublicKey = new DHPublicKeyParameters(TlsDHUtilities.ReadDHParameter(teeIn), mDHParameters); + + DigitallySigned signed_params = ParseSignature(input); + + ISigner signer = InitVerifyer(mTlsSigner, signed_params.Algorithm, securityParameters); + buf.UpdateSigner(signer); + if (!signer.VerifySignature(signed_params.Signature)) + throw new TlsFatalAlert(AlertDescription.decrypt_error); + } + + protected virtual ISigner InitVerifyer(TlsSigner tlsSigner, SignatureAndHashAlgorithm algorithm, + SecurityParameters securityParameters) + { + ISigner signer = tlsSigner.CreateVerifyer(algorithm, this.mServerPublicKey); + signer.BlockUpdate(securityParameters.clientRandom, 0, securityParameters.clientRandom.Length); + signer.BlockUpdate(securityParameters.serverRandom, 0, securityParameters.serverRandom.Length); + return signer; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsDheKeyExchange.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsDheKeyExchange.cs.meta new file mode 100644 index 0000000..59dac51 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsDheKeyExchange.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b73b5edd82708a243a76d31e745dc79e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsDsaSigner.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsDsaSigner.cs new file mode 100644 index 0000000..f0c1e94 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsDsaSigner.cs @@ -0,0 +1,82 @@ +using System; + +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Signers; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class TlsDsaSigner + : AbstractTlsSigner + { + public override byte[] GenerateRawSignature(SignatureAndHashAlgorithm algorithm, + AsymmetricKeyParameter privateKey, byte[] hash) + { + ISigner signer = MakeSigner(algorithm, true, true, + new ParametersWithRandom(privateKey, this.mContext.SecureRandom)); + if (algorithm == null) + { + // Note: Only use the SHA1 part of the (MD5/SHA1) hash + signer.BlockUpdate(hash, 16, 20); + } + else + { + signer.BlockUpdate(hash, 0, hash.Length); + } + return signer.GenerateSignature(); + } + + public override bool VerifyRawSignature(SignatureAndHashAlgorithm algorithm, byte[] sigBytes, + AsymmetricKeyParameter publicKey, byte[] hash) + { + ISigner signer = MakeSigner(algorithm, true, false, publicKey); + if (algorithm == null) + { + // Note: Only use the SHA1 part of the (MD5/SHA1) hash + signer.BlockUpdate(hash, 16, 20); + } + else + { + signer.BlockUpdate(hash, 0, hash.Length); + } + return signer.VerifySignature(sigBytes); + } + + public override ISigner CreateSigner(SignatureAndHashAlgorithm algorithm, AsymmetricKeyParameter privateKey) + { + return MakeSigner(algorithm, false, true, privateKey); + } + + public override ISigner CreateVerifyer(SignatureAndHashAlgorithm algorithm, AsymmetricKeyParameter publicKey) + { + return MakeSigner(algorithm, false, false, publicKey); + } + + protected virtual ICipherParameters MakeInitParameters(bool forSigning, ICipherParameters cp) + { + return cp; + } + + protected virtual ISigner MakeSigner(SignatureAndHashAlgorithm algorithm, bool raw, bool forSigning, + ICipherParameters cp) + { + if ((algorithm != null) != TlsUtilities.IsTlsV12(mContext)) + throw new InvalidOperationException(); + + if (algorithm != null && algorithm.Signature != SignatureAlgorithm) + throw new InvalidOperationException(); + + byte hashAlgorithm = algorithm == null ? HashAlgorithm.sha1 : algorithm.Hash; + IDigest d = raw ? new NullDigest() : TlsUtilities.CreateHash(hashAlgorithm); + + ISigner s = new DsaDigestSigner(CreateDsaImpl(hashAlgorithm), d); + s.Init(forSigning, MakeInitParameters(forSigning, cp)); + return s; + } + + protected abstract byte SignatureAlgorithm { get; } + + protected abstract IDsa CreateDsaImpl(byte hashAlgorithm); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsDsaSigner.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsDsaSigner.cs.meta new file mode 100644 index 0000000..d2dda8d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsDsaSigner.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1a54cd03b4334474d95fdf658486d2b3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsDssSigner.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsDssSigner.cs new file mode 100644 index 0000000..707ef38 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsDssSigner.cs @@ -0,0 +1,26 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Signers; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class TlsDssSigner + : TlsDsaSigner + { + public override bool IsValidPublicKey(AsymmetricKeyParameter publicKey) + { + return publicKey is DsaPublicKeyParameters; + } + + protected override IDsa CreateDsaImpl(byte hashAlgorithm) + { + return new DsaSigner(new HMacDsaKCalculator(TlsUtilities.CreateHash(hashAlgorithm))); + } + + protected override byte SignatureAlgorithm + { + get { return Tls.SignatureAlgorithm.dsa; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsDssSigner.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsDssSigner.cs.meta new file mode 100644 index 0000000..c9cef90 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsDssSigner.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 41c830349e086954d8b90b049a48d197 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsECDHKeyExchange.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsECDHKeyExchange.cs new file mode 100644 index 0000000..44fd94c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsECDHKeyExchange.cs @@ -0,0 +1,252 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// (D)TLS ECDH key exchange (see RFC 4492). + public class TlsECDHKeyExchange + : AbstractTlsKeyExchange + { + protected TlsSigner mTlsSigner; + protected int[] mNamedCurves; + protected byte[] mClientECPointFormats, mServerECPointFormats; + + protected AsymmetricKeyParameter mServerPublicKey; + protected TlsAgreementCredentials mAgreementCredentials; + + protected ECPrivateKeyParameters mECAgreePrivateKey; + protected ECPublicKeyParameters mECAgreePublicKey; + + public TlsECDHKeyExchange(int keyExchange, IList supportedSignatureAlgorithms, int[] namedCurves, + byte[] clientECPointFormats, byte[] serverECPointFormats) + : base(keyExchange, supportedSignatureAlgorithms) + { + switch (keyExchange) + { + case KeyExchangeAlgorithm.ECDHE_RSA: + this.mTlsSigner = new TlsRsaSigner(); + break; + case KeyExchangeAlgorithm.ECDHE_ECDSA: + this.mTlsSigner = new TlsECDsaSigner(); + break; + case KeyExchangeAlgorithm.ECDH_anon: + case KeyExchangeAlgorithm.ECDH_RSA: + case KeyExchangeAlgorithm.ECDH_ECDSA: + this.mTlsSigner = null; + break; + default: + throw new InvalidOperationException("unsupported key exchange algorithm"); + } + + this.mNamedCurves = namedCurves; + this.mClientECPointFormats = clientECPointFormats; + this.mServerECPointFormats = serverECPointFormats; + } + + public override void Init(TlsContext context) + { + base.Init(context); + + if (this.mTlsSigner != null) + { + this.mTlsSigner.Init(context); + } + } + + public override void SkipServerCredentials() + { + if (mKeyExchange != KeyExchangeAlgorithm.ECDH_anon) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + public override void ProcessServerCertificate(Certificate serverCertificate) + { + if (mKeyExchange == KeyExchangeAlgorithm.ECDH_anon) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + if (serverCertificate.IsEmpty) + throw new TlsFatalAlert(AlertDescription.decode_error); + + X509CertificateStructure x509Cert = serverCertificate.GetCertificateAt(0); + + SubjectPublicKeyInfo keyInfo = x509Cert.SubjectPublicKeyInfo; + try + { + this.mServerPublicKey = PublicKeyFactory.CreateKey(keyInfo); + } + catch (Exception e) + { + throw new TlsFatalAlert(AlertDescription.unsupported_certificate, e); + } + + if (mTlsSigner == null) + { + try + { + this.mECAgreePublicKey = TlsEccUtilities.ValidateECPublicKey((ECPublicKeyParameters) this.mServerPublicKey); + } + catch (InvalidCastException e) + { + throw new TlsFatalAlert(AlertDescription.certificate_unknown, e); + } + + TlsUtilities.ValidateKeyUsage(x509Cert, KeyUsage.KeyAgreement); + } + else + { + if (!mTlsSigner.IsValidPublicKey(this.mServerPublicKey)) + throw new TlsFatalAlert(AlertDescription.certificate_unknown); + + TlsUtilities.ValidateKeyUsage(x509Cert, KeyUsage.DigitalSignature); + } + + base.ProcessServerCertificate(serverCertificate); + } + + public override bool RequiresServerKeyExchange + { + get + { + switch (mKeyExchange) + { + case KeyExchangeAlgorithm.ECDH_anon: + case KeyExchangeAlgorithm.ECDHE_ECDSA: + case KeyExchangeAlgorithm.ECDHE_RSA: + return true; + default: + return false; + } + } + } + + public override byte[] GenerateServerKeyExchange() + { + if (!RequiresServerKeyExchange) + return null; + + // ECDH_anon is handled here, ECDHE_* in a subclass + + MemoryStream buf = new MemoryStream(); + this.mECAgreePrivateKey = TlsEccUtilities.GenerateEphemeralServerKeyExchange(mContext.SecureRandom, mNamedCurves, + mClientECPointFormats, buf); + return buf.ToArray(); + } + + public override void ProcessServerKeyExchange(Stream input) + { + if (!RequiresServerKeyExchange) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + + // ECDH_anon is handled here, ECDHE_* in a subclass + + ECDomainParameters curve_params = TlsEccUtilities.ReadECParameters(mNamedCurves, mClientECPointFormats, input); + + byte[] point = TlsUtilities.ReadOpaque8(input); + + this.mECAgreePublicKey = TlsEccUtilities.ValidateECPublicKey(TlsEccUtilities.DeserializeECPublicKey( + mClientECPointFormats, curve_params, point)); + } + + public override void ValidateCertificateRequest(CertificateRequest certificateRequest) + { + if (mKeyExchange == KeyExchangeAlgorithm.ECDH_anon) + throw new TlsFatalAlert(AlertDescription.handshake_failure); + + /* + * RFC 4492 3. [...] The ECDSA_fixed_ECDH and RSA_fixed_ECDH mechanisms are usable with + * ECDH_ECDSA and ECDH_RSA. Their use with ECDHE_ECDSA and ECDHE_RSA is prohibited because + * the use of a long-term ECDH client key would jeopardize the forward secrecy property of + * these algorithms. + */ + byte[] types = certificateRequest.CertificateTypes; + for (int i = 0; i < types.Length; ++i) + { + switch (types[i]) + { + case ClientCertificateType.rsa_sign: + case ClientCertificateType.dss_sign: + case ClientCertificateType.ecdsa_sign: + case ClientCertificateType.rsa_fixed_ecdh: + case ClientCertificateType.ecdsa_fixed_ecdh: + break; + default: + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + } + } + + public override void ProcessClientCredentials(TlsCredentials clientCredentials) + { + if (mKeyExchange == KeyExchangeAlgorithm.ECDH_anon) + throw new TlsFatalAlert(AlertDescription.internal_error); + + if (clientCredentials is TlsAgreementCredentials) + { + // TODO Validate client cert has matching parameters (see 'TlsEccUtilities.AreOnSameCurve')? + + this.mAgreementCredentials = (TlsAgreementCredentials)clientCredentials; + } + else if (clientCredentials is TlsSignerCredentials) + { + // OK + } + else + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + public override void GenerateClientKeyExchange(Stream output) + { + if (mAgreementCredentials == null) + { + this.mECAgreePrivateKey = TlsEccUtilities.GenerateEphemeralClientKeyExchange(mContext.SecureRandom, + mServerECPointFormats, mECAgreePublicKey.Parameters, output); + } + } + + public override void ProcessClientCertificate(Certificate clientCertificate) + { + if (mKeyExchange == KeyExchangeAlgorithm.ECDH_anon) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + + // TODO Extract the public key + // TODO If the certificate is 'fixed', take the public key as mECAgreeClientPublicKey + } + + public override void ProcessClientKeyExchange(Stream input) + { + if (mECAgreePublicKey != null) + { + // For ecdsa_fixed_ecdh and rsa_fixed_ecdh, the key arrived in the client certificate + return; + } + + byte[] point = TlsUtilities.ReadOpaque8(input); + + ECDomainParameters curve_params = this.mECAgreePrivateKey.Parameters; + + this.mECAgreePublicKey = TlsEccUtilities.ValidateECPublicKey(TlsEccUtilities.DeserializeECPublicKey( + mServerECPointFormats, curve_params, point)); + } + + public override byte[] GeneratePremasterSecret() + { + if (mAgreementCredentials != null) + { + return mAgreementCredentials.GenerateAgreement(mECAgreePublicKey); + } + + if (mECAgreePrivateKey != null) + { + return TlsEccUtilities.CalculateECDHBasicAgreement(mECAgreePublicKey, mECAgreePrivateKey); + } + + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsECDHKeyExchange.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsECDHKeyExchange.cs.meta new file mode 100644 index 0000000..82543fe --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsECDHKeyExchange.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0b5ae7a309448b44c8e05c6e94de02bf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsECDheKeyExchange.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsECDheKeyExchange.cs new file mode 100644 index 0000000..e0553b3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsECDheKeyExchange.cs @@ -0,0 +1,131 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// (D)TLS ECDHE key exchange (see RFC 4492). + public class TlsECDheKeyExchange + : TlsECDHKeyExchange + { + protected TlsSignerCredentials mServerCredentials = null; + + public TlsECDheKeyExchange(int keyExchange, IList supportedSignatureAlgorithms, int[] namedCurves, + byte[] clientECPointFormats, byte[] serverECPointFormats) + : base(keyExchange, supportedSignatureAlgorithms, namedCurves, clientECPointFormats, serverECPointFormats) + { + } + + public override void ProcessServerCredentials(TlsCredentials serverCredentials) + { + if (!(serverCredentials is TlsSignerCredentials)) + throw new TlsFatalAlert(AlertDescription.internal_error); + + ProcessServerCertificate(serverCredentials.Certificate); + + this.mServerCredentials = (TlsSignerCredentials)serverCredentials; + } + + public override byte[] GenerateServerKeyExchange() + { + DigestInputBuffer buf = new DigestInputBuffer(); + + this.mECAgreePrivateKey = TlsEccUtilities.GenerateEphemeralServerKeyExchange(mContext.SecureRandom, mNamedCurves, + mClientECPointFormats, buf); + + /* + * RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm from TLS 1.2 + */ + SignatureAndHashAlgorithm signatureAndHashAlgorithm = TlsUtilities.GetSignatureAndHashAlgorithm( + mContext, mServerCredentials); + + IDigest d = TlsUtilities.CreateHash(signatureAndHashAlgorithm); + + SecurityParameters securityParameters = mContext.SecurityParameters; + d.BlockUpdate(securityParameters.clientRandom, 0, securityParameters.clientRandom.Length); + d.BlockUpdate(securityParameters.serverRandom, 0, securityParameters.serverRandom.Length); + buf.UpdateDigest(d); + + byte[] hash = DigestUtilities.DoFinal(d); + + byte[] signature = mServerCredentials.GenerateCertificateSignature(hash); + + DigitallySigned signed_params = new DigitallySigned(signatureAndHashAlgorithm, signature); + signed_params.Encode(buf); + + return buf.ToArray(); + } + + public override void ProcessServerKeyExchange(Stream input) + { + SecurityParameters securityParameters = mContext.SecurityParameters; + + SignerInputBuffer buf = new SignerInputBuffer(); + Stream teeIn = new TeeInputStream(input, buf); + + ECDomainParameters curve_params = TlsEccUtilities.ReadECParameters(mNamedCurves, mClientECPointFormats, teeIn); + + byte[] point = TlsUtilities.ReadOpaque8(teeIn); + + DigitallySigned signed_params = ParseSignature(input); + + ISigner signer = InitVerifyer(mTlsSigner, signed_params.Algorithm, securityParameters); + buf.UpdateSigner(signer); + if (!signer.VerifySignature(signed_params.Signature)) + throw new TlsFatalAlert(AlertDescription.decrypt_error); + + this.mECAgreePublicKey = TlsEccUtilities.ValidateECPublicKey(TlsEccUtilities.DeserializeECPublicKey( + mClientECPointFormats, curve_params, point)); + } + + public override void ValidateCertificateRequest(CertificateRequest certificateRequest) + { + /* + * RFC 4492 3. [...] The ECDSA_fixed_ECDH and RSA_fixed_ECDH mechanisms are usable with + * ECDH_ECDSA and ECDH_RSA. Their use with ECDHE_ECDSA and ECDHE_RSA is prohibited because + * the use of a long-term ECDH client key would jeopardize the forward secrecy property of + * these algorithms. + */ + byte[] types = certificateRequest.CertificateTypes; + for (int i = 0; i < types.Length; ++i) + { + switch (types[i]) + { + case ClientCertificateType.rsa_sign: + case ClientCertificateType.dss_sign: + case ClientCertificateType.ecdsa_sign: + break; + default: + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + } + } + + public override void ProcessClientCredentials(TlsCredentials clientCredentials) + { + if (clientCredentials is TlsSignerCredentials) + { + // OK + } + else + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + protected virtual ISigner InitVerifyer(TlsSigner tlsSigner, SignatureAndHashAlgorithm algorithm, + SecurityParameters securityParameters) + { + ISigner signer = tlsSigner.CreateVerifyer(algorithm, this.mServerPublicKey); + signer.BlockUpdate(securityParameters.clientRandom, 0, securityParameters.clientRandom.Length); + signer.BlockUpdate(securityParameters.serverRandom, 0, securityParameters.serverRandom.Length); + return signer; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsECDheKeyExchange.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsECDheKeyExchange.cs.meta new file mode 100644 index 0000000..32ff8cf --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsECDheKeyExchange.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 341eff92ead16d040b126dc045b9e4de +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsECDsaSigner.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsECDsaSigner.cs new file mode 100644 index 0000000..fa9d0b7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsECDsaSigner.cs @@ -0,0 +1,26 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Signers; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class TlsECDsaSigner + : TlsDsaSigner + { + public override bool IsValidPublicKey(AsymmetricKeyParameter publicKey) + { + return publicKey is ECPublicKeyParameters; + } + + protected override IDsa CreateDsaImpl(byte hashAlgorithm) + { + return new ECDsaSigner(new HMacDsaKCalculator(TlsUtilities.CreateHash(hashAlgorithm))); + } + + protected override byte SignatureAlgorithm + { + get { return Tls.SignatureAlgorithm.ecdsa; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsECDsaSigner.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsECDsaSigner.cs.meta new file mode 100644 index 0000000..87bebf8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsECDsaSigner.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d8f28a73347aa95439fb1346080c8421 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsEccUtilities.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsEccUtilities.cs new file mode 100644 index 0000000..5ef72a7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsEccUtilities.cs @@ -0,0 +1,695 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Agreement; +using Org.BouncyCastle.Crypto.EC; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Math.Field; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class TlsEccUtilities + { + private static readonly string[] CurveNames = new string[] { "sect163k1", "sect163r1", "sect163r2", "sect193r1", + "sect193r2", "sect233k1", "sect233r1", "sect239k1", "sect283k1", "sect283r1", "sect409k1", "sect409r1", + "sect571k1", "sect571r1", "secp160k1", "secp160r1", "secp160r2", "secp192k1", "secp192r1", "secp224k1", + "secp224r1", "secp256k1", "secp256r1", "secp384r1", "secp521r1", + "brainpoolP256r1", "brainpoolP384r1", "brainpoolP512r1"}; + + public static void AddSupportedEllipticCurvesExtension(IDictionary extensions, int[] namedCurves) + { + extensions[ExtensionType.supported_groups] = CreateSupportedEllipticCurvesExtension(namedCurves); + } + + public static void AddSupportedPointFormatsExtension(IDictionary extensions, byte[] ecPointFormats) + { + extensions[ExtensionType.ec_point_formats] = CreateSupportedPointFormatsExtension(ecPointFormats); + } + + public static int[] GetSupportedEllipticCurvesExtension(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.supported_groups); + return extensionData == null ? null : ReadSupportedEllipticCurvesExtension(extensionData); + } + + public static byte[] GetSupportedPointFormatsExtension(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.ec_point_formats); + return extensionData == null ? null : ReadSupportedPointFormatsExtension(extensionData); + } + + public static byte[] CreateSupportedEllipticCurvesExtension(int[] namedCurves) + { + if (namedCurves == null || namedCurves.Length < 1) + throw new TlsFatalAlert(AlertDescription.internal_error); + + return TlsUtilities.EncodeUint16ArrayWithUint16Length(namedCurves); + } + + public static byte[] CreateSupportedPointFormatsExtension(byte[] ecPointFormats) + { + if (ecPointFormats == null || !Arrays.Contains(ecPointFormats, ECPointFormat.uncompressed)) + { + /* + * RFC 4492 5.1. If the Supported Point Formats Extension is indeed sent, it MUST + * contain the value 0 (uncompressed) as one of the items in the list of point formats. + */ + + // NOTE: We add it at the end (lowest preference) + ecPointFormats = Arrays.Append(ecPointFormats, ECPointFormat.uncompressed); + } + + return TlsUtilities.EncodeUint8ArrayWithUint8Length(ecPointFormats); + } + + public static int[] ReadSupportedEllipticCurvesExtension(byte[] extensionData) + { + if (extensionData == null) + throw new ArgumentNullException("extensionData"); + + MemoryStream buf = new MemoryStream(extensionData, false); + + int length = TlsUtilities.ReadUint16(buf); + if (length < 2 || (length & 1) != 0) + throw new TlsFatalAlert(AlertDescription.decode_error); + + int[] namedCurves = TlsUtilities.ReadUint16Array(length / 2, buf); + + TlsProtocol.AssertEmpty(buf); + + return namedCurves; + } + + public static byte[] ReadSupportedPointFormatsExtension(byte[] extensionData) + { + byte[] ecPointFormats = TlsUtilities.DecodeUint8ArrayWithUint8Length(extensionData); + if (!Arrays.Contains(ecPointFormats, ECPointFormat.uncompressed)) + { + /* + * RFC 4492 5.1. If the Supported Point Formats Extension is indeed sent, it MUST + * contain the value 0 (uncompressed) as one of the items in the list of point formats. + */ + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + return ecPointFormats; + } + + public static string GetNameOfNamedCurve(int namedCurve) + { + return IsSupportedNamedCurve(namedCurve) ? CurveNames[namedCurve - 1] : null; + } + + public static ECDomainParameters GetParametersForNamedCurve(int namedCurve) + { + string curveName = GetNameOfNamedCurve(namedCurve); + if (curveName == null) + return null; + + // Parameters are lazily created the first time a particular curve is accessed + + X9ECParameters ecP = CustomNamedCurves.GetByName(curveName); + if (ecP == null) + { + ecP = ECNamedCurveTable.GetByName(curveName); + if (ecP == null) + return null; + } + + // It's a bit inefficient to do this conversion every time + return new ECDomainParameters(ecP.Curve, ecP.G, ecP.N, ecP.H, ecP.GetSeed()); + } + + public static bool HasAnySupportedNamedCurves() + { + return CurveNames.Length > 0; + } + + public static bool ContainsEccCipherSuites(int[] cipherSuites) + { + for (int i = 0; i < cipherSuites.Length; ++i) + { + if (IsEccCipherSuite(cipherSuites[i])) + return true; + } + return false; + } + + public static bool IsEccCipherSuite(int cipherSuite) + { + switch (cipherSuite) + { + /* + * RFC 4492 + */ + case CipherSuite.TLS_ECDH_ECDSA_WITH_NULL_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_RC4_128_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_NULL_SHA: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDH_RSA_WITH_NULL_SHA: + case CipherSuite.TLS_ECDH_RSA_WITH_RC4_128_SHA: + case CipherSuite.TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDHE_RSA_WITH_NULL_SHA: + case CipherSuite.TLS_ECDHE_RSA_WITH_RC4_128_SHA: + case CipherSuite.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDH_anon_WITH_NULL_SHA: + case CipherSuite.TLS_ECDH_anon_WITH_RC4_128_SHA: + case CipherSuite.TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDH_anon_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDH_anon_WITH_AES_256_CBC_SHA: + + /* + * RFC 5289 + */ + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384: + + /* + * RFC 5489 + */ + case CipherSuite.TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA: + case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA384: + case CipherSuite.TLS_ECDHE_PSK_WITH_RC4_128_SHA: + + /* + * RFC 6367 + */ + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384: + + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384: + + case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384: + + /* + * RFC 7251 + */ + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8: + + /* + * draft-ietf-tls-chacha20-poly1305-04 + */ + case CipherSuite.DRAFT_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.DRAFT_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.DRAFT_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: + + return true; + + default: + return false; + } + } + + public static bool AreOnSameCurve(ECDomainParameters a, ECDomainParameters b) + { + return a != null && a.Equals(b); + } + + public static bool IsSupportedNamedCurve(int namedCurve) + { + return (namedCurve > 0 && namedCurve <= CurveNames.Length); + } + + public static bool IsCompressionPreferred(byte[] ecPointFormats, byte compressionFormat) + { + if (ecPointFormats == null) + return false; + + for (int i = 0; i < ecPointFormats.Length; ++i) + { + byte ecPointFormat = ecPointFormats[i]; + if (ecPointFormat == ECPointFormat.uncompressed) + return false; + if (ecPointFormat == compressionFormat) + return true; + } + return false; + } + + public static byte[] SerializeECFieldElement(int fieldSize, BigInteger x) + { + return BigIntegers.AsUnsignedByteArray((fieldSize + 7) / 8, x); + } + + public static byte[] SerializeECPoint(byte[] ecPointFormats, ECPoint point) + { + ECCurve curve = point.Curve; + + /* + * RFC 4492 5.7. ...an elliptic curve point in uncompressed or compressed format. Here, the + * format MUST conform to what the server has requested through a Supported Point Formats + * Extension if this extension was used, and MUST be uncompressed if this extension was not + * used. + */ + bool compressed = false; + if (ECAlgorithms.IsFpCurve(curve)) + { + compressed = IsCompressionPreferred(ecPointFormats, ECPointFormat.ansiX962_compressed_prime); + } + else if (ECAlgorithms.IsF2mCurve(curve)) + { + compressed = IsCompressionPreferred(ecPointFormats, ECPointFormat.ansiX962_compressed_char2); + } + return point.GetEncoded(compressed); + } + + public static byte[] SerializeECPublicKey(byte[] ecPointFormats, ECPublicKeyParameters keyParameters) + { + return SerializeECPoint(ecPointFormats, keyParameters.Q); + } + + public static BigInteger DeserializeECFieldElement(int fieldSize, byte[] encoding) + { + int requiredLength = (fieldSize + 7) / 8; + if (encoding.Length != requiredLength) + throw new TlsFatalAlert(AlertDescription.decode_error); + return new BigInteger(1, encoding); + } + + public static ECPoint DeserializeECPoint(byte[] ecPointFormats, ECCurve curve, byte[] encoding) + { + if (encoding == null || encoding.Length < 1) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + byte actualFormat; + switch (encoding[0]) + { + case 0x02: // compressed + case 0x03: // compressed + { + if (ECAlgorithms.IsF2mCurve(curve)) + { + actualFormat = ECPointFormat.ansiX962_compressed_char2; + } + else if (ECAlgorithms.IsFpCurve(curve)) + { + actualFormat = ECPointFormat.ansiX962_compressed_prime; + } + else + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + break; + } + case 0x04: // uncompressed + { + actualFormat = ECPointFormat.uncompressed; + break; + } + case 0x00: // infinity + case 0x06: // hybrid + case 0x07: // hybrid + default: + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + if (actualFormat != ECPointFormat.uncompressed + && (ecPointFormats == null || !Arrays.Contains(ecPointFormats, actualFormat))) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + return curve.DecodePoint(encoding); + } + + public static ECPublicKeyParameters DeserializeECPublicKey(byte[] ecPointFormats, ECDomainParameters curve_params, + byte[] encoding) + { + try + { + ECPoint Y = DeserializeECPoint(ecPointFormats, curve_params.Curve, encoding); + return new ECPublicKeyParameters(Y, curve_params); + } + catch (Exception e) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter, e); + } + } + + public static byte[] CalculateECDHBasicAgreement(ECPublicKeyParameters publicKey, ECPrivateKeyParameters privateKey) + { + ECDHBasicAgreement basicAgreement = new ECDHBasicAgreement(); + basicAgreement.Init(privateKey); + BigInteger agreementValue = basicAgreement.CalculateAgreement(publicKey); + + /* + * RFC 4492 5.10. Note that this octet string (Z in IEEE 1363 terminology) as output by + * FE2OSP, the Field Element to Octet String Conversion Primitive, has constant length for + * any given field; leading zeros found in this octet string MUST NOT be truncated. + */ + return BigIntegers.AsUnsignedByteArray(basicAgreement.GetFieldSize(), agreementValue); + } + + public static AsymmetricCipherKeyPair GenerateECKeyPair(SecureRandom random, ECDomainParameters ecParams) + { + ECKeyPairGenerator keyPairGenerator = new ECKeyPairGenerator(); + keyPairGenerator.Init(new ECKeyGenerationParameters(ecParams, random)); + return keyPairGenerator.GenerateKeyPair(); + } + + public static ECPrivateKeyParameters GenerateEphemeralClientKeyExchange(SecureRandom random, byte[] ecPointFormats, + ECDomainParameters ecParams, Stream output) + { + AsymmetricCipherKeyPair kp = GenerateECKeyPair(random, ecParams); + + ECPublicKeyParameters ecPublicKey = (ECPublicKeyParameters)kp.Public; + WriteECPoint(ecPointFormats, ecPublicKey.Q, output); + + return (ECPrivateKeyParameters)kp.Private; + } + + // TODO Refactor around ServerECDHParams before making this public + internal static ECPrivateKeyParameters GenerateEphemeralServerKeyExchange(SecureRandom random, int[] namedCurves, + byte[] ecPointFormats, Stream output) + { + /* First we try to find a supported named curve from the client's list. */ + int namedCurve = -1; + if (namedCurves == null) + { + // TODO Let the peer choose the default named curve + namedCurve = NamedCurve.secp256r1; + } + else + { + for (int i = 0; i < namedCurves.Length; ++i) + { + int entry = namedCurves[i]; + if (NamedCurve.IsValid(entry) && IsSupportedNamedCurve(entry)) + { + namedCurve = entry; + break; + } + } + } + + ECDomainParameters ecParams = null; + if (namedCurve >= 0) + { + ecParams = GetParametersForNamedCurve(namedCurve); + } + else + { + /* If no named curves are suitable, check if the client supports explicit curves. */ + if (Arrays.Contains(namedCurves, NamedCurve.arbitrary_explicit_prime_curves)) + { + ecParams = GetParametersForNamedCurve(NamedCurve.secp256r1); + } + else if (Arrays.Contains(namedCurves, NamedCurve.arbitrary_explicit_char2_curves)) + { + ecParams = GetParametersForNamedCurve(NamedCurve.sect283r1); + } + } + + if (ecParams == null) + { + /* + * NOTE: We shouldn't have negotiated ECDHE key exchange since we apparently can't find + * a suitable curve. + */ + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + if (namedCurve < 0) + { + WriteExplicitECParameters(ecPointFormats, ecParams, output); + } + else + { + WriteNamedECParameters(namedCurve, output); + } + + return GenerateEphemeralClientKeyExchange(random, ecPointFormats, ecParams, output); + } + + public static ECPublicKeyParameters ValidateECPublicKey(ECPublicKeyParameters key) + { + // TODO Check RFC 4492 for validation + return key; + } + + public static int ReadECExponent(int fieldSize, Stream input) + { + BigInteger K = ReadECParameter(input); + if (K.BitLength < 32) + { + int k = K.IntValue; + if (k > 0 && k < fieldSize) + { + return k; + } + } + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + public static BigInteger ReadECFieldElement(int fieldSize, Stream input) + { + return DeserializeECFieldElement(fieldSize, TlsUtilities.ReadOpaque8(input)); + } + + public static BigInteger ReadECParameter(Stream input) + { + // TODO Are leading zeroes okay here? + return new BigInteger(1, TlsUtilities.ReadOpaque8(input)); + } + + public static ECDomainParameters ReadECParameters(int[] namedCurves, byte[] ecPointFormats, Stream input) + { + try + { + byte curveType = TlsUtilities.ReadUint8(input); + + switch (curveType) + { + case ECCurveType.explicit_prime: + { + CheckNamedCurve(namedCurves, NamedCurve.arbitrary_explicit_prime_curves); + + BigInteger prime_p = ReadECParameter(input); + BigInteger a = ReadECFieldElement(prime_p.BitLength, input); + BigInteger b = ReadECFieldElement(prime_p.BitLength, input); + byte[] baseEncoding = TlsUtilities.ReadOpaque8(input); + BigInteger order = ReadECParameter(input); + BigInteger cofactor = ReadECParameter(input); + ECCurve curve = new FpCurve(prime_p, a, b, order, cofactor); + ECPoint basePoint = DeserializeECPoint(ecPointFormats, curve, baseEncoding); + return new ECDomainParameters(curve, basePoint, order, cofactor); + } + case ECCurveType.explicit_char2: + { + CheckNamedCurve(namedCurves, NamedCurve.arbitrary_explicit_char2_curves); + + int m = TlsUtilities.ReadUint16(input); + byte basis = TlsUtilities.ReadUint8(input); + if (!ECBasisType.IsValid(basis)) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + int k1 = ReadECExponent(m, input), k2 = -1, k3 = -1; + if (basis == ECBasisType.ec_basis_pentanomial) + { + k2 = ReadECExponent(m, input); + k3 = ReadECExponent(m, input); + } + + BigInteger a = ReadECFieldElement(m, input); + BigInteger b = ReadECFieldElement(m, input); + byte[] baseEncoding = TlsUtilities.ReadOpaque8(input); + BigInteger order = ReadECParameter(input); + BigInteger cofactor = ReadECParameter(input); + + ECCurve curve = (basis == ECBasisType.ec_basis_pentanomial) + ? new F2mCurve(m, k1, k2, k3, a, b, order, cofactor) + : new F2mCurve(m, k1, a, b, order, cofactor); + + ECPoint basePoint = DeserializeECPoint(ecPointFormats, curve, baseEncoding); + + return new ECDomainParameters(curve, basePoint, order, cofactor); + } + case ECCurveType.named_curve: + { + int namedCurve = TlsUtilities.ReadUint16(input); + if (!NamedCurve.RefersToASpecificNamedCurve(namedCurve)) + { + /* + * RFC 4492 5.4. All those values of NamedCurve are allowed that refer to a + * specific curve. Values of NamedCurve that indicate support for a class of + * explicitly defined curves are not allowed here [...]. + */ + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + CheckNamedCurve(namedCurves, namedCurve); + + return GetParametersForNamedCurve(namedCurve); + } + default: + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + } + catch (Exception e) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter, e); + } + } + + private static void CheckNamedCurve(int[] namedCurves, int namedCurve) + { + if (namedCurves != null && !Arrays.Contains(namedCurves, namedCurve)) + { + /* + * RFC 4492 4. [...] servers MUST NOT negotiate the use of an ECC cipher suite + * unless they can complete the handshake while respecting the choice of curves + * and compression techniques specified by the client. + */ + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + } + + public static void WriteECExponent(int k, Stream output) + { + BigInteger K = BigInteger.ValueOf(k); + WriteECParameter(K, output); + } + + public static void WriteECFieldElement(ECFieldElement x, Stream output) + { + TlsUtilities.WriteOpaque8(x.GetEncoded(), output); + } + + public static void WriteECFieldElement(int fieldSize, BigInteger x, Stream output) + { + TlsUtilities.WriteOpaque8(SerializeECFieldElement(fieldSize, x), output); + } + + public static void WriteECParameter(BigInteger x, Stream output) + { + TlsUtilities.WriteOpaque8(BigIntegers.AsUnsignedByteArray(x), output); + } + + public static void WriteExplicitECParameters(byte[] ecPointFormats, ECDomainParameters ecParameters, + Stream output) + { + ECCurve curve = ecParameters.Curve; + + if (ECAlgorithms.IsFpCurve(curve)) + { + TlsUtilities.WriteUint8(ECCurveType.explicit_prime, output); + + WriteECParameter(curve.Field.Characteristic, output); + } + else if (ECAlgorithms.IsF2mCurve(curve)) + { + IPolynomialExtensionField field = (IPolynomialExtensionField)curve.Field; + int[] exponents = field.MinimalPolynomial.GetExponentsPresent(); + + TlsUtilities.WriteUint8(ECCurveType.explicit_char2, output); + + int m = exponents[exponents.Length - 1]; + TlsUtilities.CheckUint16(m); + TlsUtilities.WriteUint16(m, output); + + if (exponents.Length == 3) + { + TlsUtilities.WriteUint8(ECBasisType.ec_basis_trinomial, output); + WriteECExponent(exponents[1], output); + } + else if (exponents.Length == 5) + { + TlsUtilities.WriteUint8(ECBasisType.ec_basis_pentanomial, output); + WriteECExponent(exponents[1], output); + WriteECExponent(exponents[2], output); + WriteECExponent(exponents[3], output); + } + else + { + throw new ArgumentException("Only trinomial and pentomial curves are supported"); + } + } + else + { + throw new ArgumentException("'ecParameters' not a known curve type"); + } + + WriteECFieldElement(curve.A, output); + WriteECFieldElement(curve.B, output); + TlsUtilities.WriteOpaque8(SerializeECPoint(ecPointFormats, ecParameters.G), output); + WriteECParameter(ecParameters.N, output); + WriteECParameter(ecParameters.H, output); + } + + public static void WriteECPoint(byte[] ecPointFormats, ECPoint point, Stream output) + { + TlsUtilities.WriteOpaque8(SerializeECPoint(ecPointFormats, point), output); + } + + public static void WriteNamedECParameters(int namedCurve, Stream output) + { + if (!NamedCurve.RefersToASpecificNamedCurve(namedCurve)) + { + /* + * RFC 4492 5.4. All those values of NamedCurve are allowed that refer to a specific + * curve. Values of NamedCurve that indicate support for a class of explicitly defined + * curves are not allowed here [...]. + */ + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + TlsUtilities.WriteUint8(ECCurveType.named_curve, output); + TlsUtilities.CheckUint16(namedCurve); + TlsUtilities.WriteUint16(namedCurve, output); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsEccUtilities.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsEccUtilities.cs.meta new file mode 100644 index 0000000..b5294cf --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsEccUtilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ca31c5b733a34994d96e7c200f02b46e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsEncryptionCredentials.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsEncryptionCredentials.cs new file mode 100644 index 0000000..52f0070 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsEncryptionCredentials.cs @@ -0,0 +1,12 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public interface TlsEncryptionCredentials + : TlsCredentials + { + /// + byte[] DecryptPreMasterSecret(byte[] encryptedPreMasterSecret); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsEncryptionCredentials.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsEncryptionCredentials.cs.meta new file mode 100644 index 0000000..322a915 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsEncryptionCredentials.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 73be41b409053e24db78e248622c8fea +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsException.cs new file mode 100644 index 0000000..18ca22a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsException.cs @@ -0,0 +1,24 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class TlsException + : IOException + { + public TlsException() + : base() + { + } + + public TlsException(string message) + : base(message) + { + } + + public TlsException(string message, Exception cause) + : base(message, cause) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsException.cs.meta new file mode 100644 index 0000000..26c7b65 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ba7a6adee8533a14fa4598953bdf6a1e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsExtensionsUtilities.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsExtensionsUtilities.cs new file mode 100644 index 0000000..4b3d9e0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsExtensionsUtilities.cs @@ -0,0 +1,368 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class TlsExtensionsUtilities + { + public static IDictionary EnsureExtensionsInitialised(IDictionary extensions) + { + return extensions == null ? Platform.CreateHashtable() : extensions; + } + + /// + public static void AddClientCertificateTypeExtensionClient(IDictionary extensions, byte[] certificateTypes) + { + extensions[ExtensionType.client_certificate_type] = CreateCertificateTypeExtensionClient(certificateTypes); + } + + /// + public static void AddClientCertificateTypeExtensionServer(IDictionary extensions, byte certificateType) + { + extensions[ExtensionType.client_certificate_type] = CreateCertificateTypeExtensionServer(certificateType); + } + + public static void AddEncryptThenMacExtension(IDictionary extensions) + { + extensions[ExtensionType.encrypt_then_mac] = CreateEncryptThenMacExtension(); + } + + public static void AddExtendedMasterSecretExtension(IDictionary extensions) + { + extensions[ExtensionType.extended_master_secret] = CreateExtendedMasterSecretExtension(); + } + + /// + public static void AddHeartbeatExtension(IDictionary extensions, HeartbeatExtension heartbeatExtension) + { + extensions[ExtensionType.heartbeat] = CreateHeartbeatExtension(heartbeatExtension); + } + + /// + public static void AddMaxFragmentLengthExtension(IDictionary extensions, byte maxFragmentLength) + { + extensions[ExtensionType.max_fragment_length] = CreateMaxFragmentLengthExtension(maxFragmentLength); + } + + /// + public static void AddPaddingExtension(IDictionary extensions, int dataLength) + { + extensions[ExtensionType.padding] = CreatePaddingExtension(dataLength); + } + + /// + public static void AddServerCertificateTypeExtensionClient(IDictionary extensions, byte[] certificateTypes) + { + extensions[ExtensionType.server_certificate_type] = CreateCertificateTypeExtensionClient(certificateTypes); + } + + /// + public static void AddServerCertificateTypeExtensionServer(IDictionary extensions, byte certificateType) + { + extensions[ExtensionType.server_certificate_type] = CreateCertificateTypeExtensionServer(certificateType); + } + + /// + public static void AddServerNameExtension(IDictionary extensions, ServerNameList serverNameList) + { + extensions[ExtensionType.server_name] = CreateServerNameExtension(serverNameList); + } + + /// + public static void AddStatusRequestExtension(IDictionary extensions, CertificateStatusRequest statusRequest) + { + extensions[ExtensionType.status_request] = CreateStatusRequestExtension(statusRequest); + } + + public static void AddTruncatedHMacExtension(IDictionary extensions) + { + extensions[ExtensionType.truncated_hmac] = CreateTruncatedHMacExtension(); + } + + /// + public static byte[] GetClientCertificateTypeExtensionClient(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.client_certificate_type); + return extensionData == null ? null : ReadCertificateTypeExtensionClient(extensionData); + } + + /// + public static short GetClientCertificateTypeExtensionServer(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.client_certificate_type); + return extensionData == null ? (short)-1 : (short)ReadCertificateTypeExtensionServer(extensionData); + } + + /// + public static HeartbeatExtension GetHeartbeatExtension(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.heartbeat); + return extensionData == null ? null : ReadHeartbeatExtension(extensionData); + } + + /// + public static short GetMaxFragmentLengthExtension(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.max_fragment_length); + return extensionData == null ? (short)-1 : (short)ReadMaxFragmentLengthExtension(extensionData); + } + + /// + public static int GetPaddingExtension(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.padding); + return extensionData == null ? -1 : ReadPaddingExtension(extensionData); + } + + /// + public static byte[] GetServerCertificateTypeExtensionClient(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.server_certificate_type); + return extensionData == null ? null : ReadCertificateTypeExtensionClient(extensionData); + } + + /// + public static short GetServerCertificateTypeExtensionServer(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.server_certificate_type); + return extensionData == null ? (short)-1 : (short)ReadCertificateTypeExtensionServer(extensionData); + } + + /// + public static ServerNameList GetServerNameExtension(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.server_name); + return extensionData == null ? null : ReadServerNameExtension(extensionData); + } + + /// + public static CertificateStatusRequest GetStatusRequestExtension(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.status_request); + return extensionData == null ? null : ReadStatusRequestExtension(extensionData); + } + + /// + public static bool HasEncryptThenMacExtension(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.encrypt_then_mac); + return extensionData == null ? false : ReadEncryptThenMacExtension(extensionData); + } + + /// + public static bool HasExtendedMasterSecretExtension(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.extended_master_secret); + return extensionData == null ? false : ReadExtendedMasterSecretExtension(extensionData); + } + + /// + public static bool HasTruncatedHMacExtension(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.truncated_hmac); + return extensionData == null ? false : ReadTruncatedHMacExtension(extensionData); + } + + /// + public static byte[] CreateCertificateTypeExtensionClient(byte[] certificateTypes) + { + if (certificateTypes == null || certificateTypes.Length < 1 || certificateTypes.Length > 255) + throw new TlsFatalAlert(AlertDescription.internal_error); + + return TlsUtilities.EncodeUint8ArrayWithUint8Length(certificateTypes); + } + + /// + public static byte[] CreateCertificateTypeExtensionServer(byte certificateType) + { + return TlsUtilities.EncodeUint8(certificateType); + } + + public static byte[] CreateEmptyExtensionData() + { + return TlsUtilities.EmptyBytes; + } + + public static byte[] CreateEncryptThenMacExtension() + { + return CreateEmptyExtensionData(); + } + + public static byte[] CreateExtendedMasterSecretExtension() + { + return CreateEmptyExtensionData(); + } + + /// + public static byte[] CreateHeartbeatExtension(HeartbeatExtension heartbeatExtension) + { + if (heartbeatExtension == null) + throw new TlsFatalAlert(AlertDescription.internal_error); + + MemoryStream buf = new MemoryStream(); + + heartbeatExtension.Encode(buf); + + return buf.ToArray(); + } + + /// + public static byte[] CreateMaxFragmentLengthExtension(byte maxFragmentLength) + { + return TlsUtilities.EncodeUint8(maxFragmentLength); + } + + /// + public static byte[] CreatePaddingExtension(int dataLength) + { + TlsUtilities.CheckUint16(dataLength); + return new byte[dataLength]; + } + + /// + public static byte[] CreateServerNameExtension(ServerNameList serverNameList) + { + if (serverNameList == null) + throw new TlsFatalAlert(AlertDescription.internal_error); + + MemoryStream buf = new MemoryStream(); + + serverNameList.Encode(buf); + + return buf.ToArray(); + } + + /// + public static byte[] CreateStatusRequestExtension(CertificateStatusRequest statusRequest) + { + if (statusRequest == null) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + MemoryStream buf = new MemoryStream(); + + statusRequest.Encode(buf); + + return buf.ToArray(); + } + + public static byte[] CreateTruncatedHMacExtension() + { + return CreateEmptyExtensionData(); + } + + /// + private static bool ReadEmptyExtensionData(byte[] extensionData) + { + if (extensionData == null) + throw new ArgumentNullException("extensionData"); + + if (extensionData.Length != 0) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + return true; + } + + /// + public static byte[] ReadCertificateTypeExtensionClient(byte[] extensionData) + { + byte[] certificateTypes = TlsUtilities.DecodeUint8ArrayWithUint8Length(extensionData); + if (certificateTypes.Length < 1) + throw new TlsFatalAlert(AlertDescription.decode_error); + return certificateTypes; + } + + /// + public static byte ReadCertificateTypeExtensionServer(byte[] extensionData) + { + return TlsUtilities.DecodeUint8(extensionData); + } + + /// + public static bool ReadEncryptThenMacExtension(byte[] extensionData) + { + return ReadEmptyExtensionData(extensionData); + } + + /// + public static bool ReadExtendedMasterSecretExtension(byte[] extensionData) + { + return ReadEmptyExtensionData(extensionData); + } + + /// + public static HeartbeatExtension ReadHeartbeatExtension(byte[] extensionData) + { + if (extensionData == null) + throw new ArgumentNullException("extensionData"); + + MemoryStream buf = new MemoryStream(extensionData, false); + + HeartbeatExtension heartbeatExtension = HeartbeatExtension.Parse(buf); + + TlsProtocol.AssertEmpty(buf); + + return heartbeatExtension; + } + + /// + public static byte ReadMaxFragmentLengthExtension(byte[] extensionData) + { + return TlsUtilities.DecodeUint8(extensionData); + } + + /// + public static int ReadPaddingExtension(byte[] extensionData) + { + if (extensionData == null) + throw new ArgumentNullException("extensionData"); + + for (int i = 0; i < extensionData.Length; ++i) + { + if (extensionData[i] != 0) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + return extensionData.Length; + } + + /// + public static ServerNameList ReadServerNameExtension(byte[] extensionData) + { + if (extensionData == null) + throw new ArgumentNullException("extensionData"); + + MemoryStream buf = new MemoryStream(extensionData, false); + + ServerNameList serverNameList = ServerNameList.Parse(buf); + + TlsProtocol.AssertEmpty(buf); + + return serverNameList; + } + + /// + public static CertificateStatusRequest ReadStatusRequestExtension(byte[] extensionData) + { + if (extensionData == null) + throw new ArgumentNullException("extensionData"); + + MemoryStream buf = new MemoryStream(extensionData, false); + + CertificateStatusRequest statusRequest = CertificateStatusRequest.Parse(buf); + + TlsProtocol.AssertEmpty(buf); + + return statusRequest; + } + + /// + public static bool ReadTruncatedHMacExtension(byte[] extensionData) + { + return ReadEmptyExtensionData(extensionData); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsExtensionsUtilities.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsExtensionsUtilities.cs.meta new file mode 100644 index 0000000..cd8d223 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsExtensionsUtilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 90eb6263acb781045a0e2f42db949940 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsFatalAlert.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsFatalAlert.cs new file mode 100644 index 0000000..6f18981 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsFatalAlert.cs @@ -0,0 +1,26 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class TlsFatalAlert + : TlsException + { + private readonly byte alertDescription; + + public TlsFatalAlert(byte alertDescription) + : this(alertDescription, null) + { + } + + public TlsFatalAlert(byte alertDescription, Exception alertCause) + : base(Tls.AlertDescription.GetText(alertDescription), alertCause) + { + this.alertDescription = alertDescription; + } + + public virtual byte AlertDescription + { + get { return alertDescription; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsFatalAlert.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsFatalAlert.cs.meta new file mode 100644 index 0000000..b253e89 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsFatalAlert.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c78f4f9abff443940ab114a3fa4857fa +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsFatalAlertReceived.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsFatalAlertReceived.cs new file mode 100644 index 0000000..044fc80 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsFatalAlertReceived.cs @@ -0,0 +1,21 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class TlsFatalAlertReceived + : TlsException + { + private readonly byte alertDescription; + + public TlsFatalAlertReceived(byte alertDescription) + : base(Tls.AlertDescription.GetText(alertDescription), null) + { + this.alertDescription = alertDescription; + } + + public virtual byte AlertDescription + { + get { return alertDescription; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsFatalAlertReceived.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsFatalAlertReceived.cs.meta new file mode 100644 index 0000000..6e63606 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsFatalAlertReceived.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cdbf19d7fe4ef5d4eb7a8c35699d59e5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsHandshakeHash.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsHandshakeHash.cs new file mode 100644 index 0000000..7118d97 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsHandshakeHash.cs @@ -0,0 +1,22 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public interface TlsHandshakeHash + : IDigest + { + void Init(TlsContext context); + + TlsHandshakeHash NotifyPrfDetermined(); + + void TrackHashAlgorithm(byte hashAlgorithm); + + void SealHashAlgorithms(); + + TlsHandshakeHash StopTracking(); + + IDigest ForkPrfHash(); + + byte[] GetFinalHash(byte hashAlgorithm); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsHandshakeHash.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsHandshakeHash.cs.meta new file mode 100644 index 0000000..4d8fb92 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsHandshakeHash.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2a2cc463b26ff624abbbb4fbae66759d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsKeyExchange.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsKeyExchange.cs new file mode 100644 index 0000000..6731f6f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsKeyExchange.cs @@ -0,0 +1,54 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// + /// A generic interface for key exchange implementations in (D)TLS. + /// + public interface TlsKeyExchange + { + void Init(TlsContext context); + + /// + void SkipServerCredentials(); + + /// + void ProcessServerCredentials(TlsCredentials serverCredentials); + + /// + void ProcessServerCertificate(Certificate serverCertificate); + + bool RequiresServerKeyExchange { get; } + + /// + byte[] GenerateServerKeyExchange(); + + /// + void SkipServerKeyExchange(); + + /// + void ProcessServerKeyExchange(Stream input); + + /// + void ValidateCertificateRequest(CertificateRequest certificateRequest); + + /// + void SkipClientCredentials(); + + /// + void ProcessClientCredentials(TlsCredentials clientCredentials); + + /// + void ProcessClientCertificate(Certificate clientCertificate); + + /// + void GenerateClientKeyExchange(Stream output); + + /// + void ProcessClientKeyExchange(Stream input); + + /// + byte[] GeneratePremasterSecret(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsKeyExchange.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsKeyExchange.cs.meta new file mode 100644 index 0000000..a056fc9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsKeyExchange.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9f053498bb3bae84e933ba579cd66f9e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsMac.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsMac.cs new file mode 100644 index 0000000..a80319a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsMac.cs @@ -0,0 +1,173 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Macs; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// + /// A generic TLS MAC implementation, acting as an HMAC based on some underlying Digest. + /// + public class TlsMac + { + protected readonly TlsContext context; + protected readonly byte[] secret; + protected readonly IMac mac; + protected readonly int digestBlockSize; + protected readonly int digestOverhead; + protected readonly int macLength; + + /** + * Generate a new instance of an TlsMac. + * + * @param context the TLS client context + * @param digest The digest to use. + * @param key A byte-array where the key for this MAC is located. + * @param keyOff The number of bytes to skip, before the key starts in the buffer. + * @param keyLen The length of the key. + */ + public TlsMac(TlsContext context, IDigest digest, byte[] key, int keyOff, int keyLen) + { + this.context = context; + + KeyParameter keyParameter = new KeyParameter(key, keyOff, keyLen); + + this.secret = Arrays.Clone(keyParameter.GetKey()); + + // TODO This should check the actual algorithm, not rely on the engine type + if (digest is LongDigest) + { + this.digestBlockSize = 128; + this.digestOverhead = 16; + } + else + { + this.digestBlockSize = 64; + this.digestOverhead = 8; + } + + if (TlsUtilities.IsSsl(context)) + { + this.mac = new Ssl3Mac(digest); + + // TODO This should check the actual algorithm, not assume based on the digest size + if (digest.GetDigestSize() == 20) + { + /* + * NOTE: When SHA-1 is used with the SSL 3.0 MAC, the secret + input pad is not + * digest block-aligned. + */ + this.digestOverhead = 4; + } + } + else + { + this.mac = new HMac(digest); + + // NOTE: The input pad for HMAC is always a full digest block + } + + this.mac.Init(keyParameter); + + this.macLength = mac.GetMacSize(); + if (context.SecurityParameters.truncatedHMac) + { + this.macLength = System.Math.Min(this.macLength, 10); + } + } + + /** + * @return the MAC write secret + */ + public virtual byte[] MacSecret + { + get { return this.secret; } + } + + /** + * @return The output length of this MAC. + */ + public virtual int Size + { + get { return macLength; } + } + + /** + * Calculate the MAC for some given data. + * + * @param type The message type of the message. + * @param message A byte-buffer containing the message. + * @param offset The number of bytes to skip, before the message starts. + * @param length The length of the message. + * @return A new byte-buffer containing the MAC value. + */ + public virtual byte[] CalculateMac(long seqNo, byte type, byte[] message, int offset, int length) + { + ProtocolVersion serverVersion = context.ServerVersion; + bool isSsl = serverVersion.IsSsl; + + byte[] macHeader = new byte[isSsl ? 11 : 13]; + TlsUtilities.WriteUint64(seqNo, macHeader, 0); + TlsUtilities.WriteUint8(type, macHeader, 8); + if (!isSsl) + { + TlsUtilities.WriteVersion(serverVersion, macHeader, 9); + } + TlsUtilities.WriteUint16(length, macHeader, macHeader.Length - 2); + + mac.BlockUpdate(macHeader, 0, macHeader.Length); + mac.BlockUpdate(message, offset, length); + + return Truncate(MacUtilities.DoFinal(mac)); + } + + public virtual byte[] CalculateMacConstantTime(long seqNo, byte type, byte[] message, int offset, int length, + int fullLength, byte[] dummyData) + { + /* + * Actual MAC only calculated on 'length' bytes... + */ + byte[] result = CalculateMac(seqNo, type, message, offset, length); + + /* + * ...but ensure a constant number of complete digest blocks are processed (as many as would + * be needed for 'fullLength' bytes of input). + */ + int headerLength = TlsUtilities.IsSsl(context) ? 11 : 13; + + // How many extra full blocks do we need to calculate? + int extra = GetDigestBlockCount(headerLength + fullLength) - GetDigestBlockCount(headerLength + length); + + while (--extra >= 0) + { + mac.BlockUpdate(dummyData, 0, digestBlockSize); + } + + // One more byte in case the implementation is "lazy" about processing blocks + mac.Update(dummyData[0]); + mac.Reset(); + + return result; + } + + protected virtual int GetDigestBlockCount(int inputLength) + { + // NOTE: This calculation assumes a minimum of 1 pad byte + return (inputLength + digestOverhead) / digestBlockSize; + } + + protected virtual byte[] Truncate(byte[] bs) + { + if (bs.Length <= macLength) + { + return bs; + } + + return Arrays.CopyOf(bs, macLength); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsMac.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsMac.cs.meta new file mode 100644 index 0000000..aadbd22 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsMac.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4f33b59c96eb08544b8415f767a3dc9a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsNoCloseNotifyException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsNoCloseNotifyException.cs new file mode 100644 index 0000000..0bafd82 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsNoCloseNotifyException.cs @@ -0,0 +1,23 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// + /// This exception will be thrown(only) when the connection is closed by the peer without sending a + /// close_notify warning alert. + /// + /// + /// If this happens, the TLS protocol cannot rule out truncation of the connection data (potentially + /// malicious). It may be possible to check for truncation via some property of a higher level protocol + /// built upon TLS, e.g.the Content-Length header for HTTPS. + /// + public class TlsNoCloseNotifyException + : EndOfStreamException + { + public TlsNoCloseNotifyException() + : base("No close_notify alert received before connection closed") + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsNoCloseNotifyException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsNoCloseNotifyException.cs.meta new file mode 100644 index 0000000..9026ef0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsNoCloseNotifyException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a7773170aec5a8a4ebc5004880c60623 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsNullCipher.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsNullCipher.cs new file mode 100644 index 0000000..f30ace2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsNullCipher.cs @@ -0,0 +1,118 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// + /// A NULL CipherSuite, with optional MAC. + /// + public class TlsNullCipher + : TlsCipher + { + protected readonly TlsContext context; + + protected readonly TlsMac writeMac; + protected readonly TlsMac readMac; + + public TlsNullCipher(TlsContext context) + { + this.context = context; + this.writeMac = null; + this.readMac = null; + } + + /// + public TlsNullCipher(TlsContext context, IDigest clientWriteDigest, IDigest serverWriteDigest) + { + if ((clientWriteDigest == null) != (serverWriteDigest == null)) + throw new TlsFatalAlert(AlertDescription.internal_error); + + this.context = context; + + TlsMac clientWriteMac = null, serverWriteMac = null; + + if (clientWriteDigest != null) + { + int key_block_size = clientWriteDigest.GetDigestSize() + + serverWriteDigest.GetDigestSize(); + byte[] key_block = TlsUtilities.CalculateKeyBlock(context, key_block_size); + + int offset = 0; + + clientWriteMac = new TlsMac(context, clientWriteDigest, key_block, offset, + clientWriteDigest.GetDigestSize()); + offset += clientWriteDigest.GetDigestSize(); + + serverWriteMac = new TlsMac(context, serverWriteDigest, key_block, offset, + serverWriteDigest.GetDigestSize()); + offset += serverWriteDigest.GetDigestSize(); + + if (offset != key_block_size) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + if (context.IsServer) + { + writeMac = serverWriteMac; + readMac = clientWriteMac; + } + else + { + writeMac = clientWriteMac; + readMac = serverWriteMac; + } + } + + public virtual int GetPlaintextLimit(int ciphertextLimit) + { + int result = ciphertextLimit; + if (writeMac != null) + { + result -= writeMac.Size; + } + return result; + } + + /// + public virtual byte[] EncodePlaintext(long seqNo, byte type, byte[] plaintext, int offset, int len) + { + if (writeMac == null) + { + return Arrays.CopyOfRange(plaintext, offset, offset + len); + } + + byte[] mac = writeMac.CalculateMac(seqNo, type, plaintext, offset, len); + byte[] ciphertext = new byte[len + mac.Length]; + Array.Copy(plaintext, offset, ciphertext, 0, len); + Array.Copy(mac, 0, ciphertext, len, mac.Length); + return ciphertext; + } + + /// + public virtual byte[] DecodeCiphertext(long seqNo, byte type, byte[] ciphertext, int offset, int len) + { + if (readMac == null) + { + return Arrays.CopyOfRange(ciphertext, offset, offset + len); + } + + int macSize = readMac.Size; + if (len < macSize) + throw new TlsFatalAlert(AlertDescription.decode_error); + + int macInputLen = len - macSize; + + byte[] receivedMac = Arrays.CopyOfRange(ciphertext, offset + macInputLen, offset + len); + byte[] computedMac = readMac.CalculateMac(seqNo, type, ciphertext, offset, macInputLen); + + if (!Arrays.ConstantTimeAreEqual(receivedMac, computedMac)) + throw new TlsFatalAlert(AlertDescription.bad_record_mac); + + return Arrays.CopyOfRange(ciphertext, offset, offset + macInputLen); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsNullCipher.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsNullCipher.cs.meta new file mode 100644 index 0000000..5d31b92 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsNullCipher.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 80f916ba8cb99f6479576d110008d752 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsNullCompression.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsNullCompression.cs new file mode 100644 index 0000000..45f8fc7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsNullCompression.cs @@ -0,0 +1,19 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class TlsNullCompression + : TlsCompression + { + public virtual Stream Compress(Stream output) + { + return output; + } + + public virtual Stream Decompress(Stream output) + { + return output; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsNullCompression.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsNullCompression.cs.meta new file mode 100644 index 0000000..3eb48a3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsNullCompression.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c5414070d3608a6469acfb49b11e808d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsPeer.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsPeer.cs new file mode 100644 index 0000000..817871b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsPeer.cs @@ -0,0 +1,91 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public interface TlsPeer + { + void NotifyCloseHandle(TlsCloseable closehandle); + + /// + void Cancel(); + + /// + /// Specify the timeout, in milliseconds, to use for the complete handshake process. + /// + /// + /// Negative values are not allowed. A timeout of zero means an infinite timeout (i.e. the + /// handshake will never time out). NOTE: Currently only respected by DTLS protocols. + /// + int GetHandshakeTimeoutMillis(); + + /// + /// This implementation supports RFC 7627 and will always negotiate the extended_master_secret + /// extension where possible. + /// + /// + /// When connecting to a peer that does not offer/accept this extension, it is recommended to + /// abort the handshake. This option is provided for interoperability with legacy peers, + /// although some TLS features will be disabled in that case (see RFC 7627 5.4). + /// + /// + /// true if the handshake should be aborted when the peer does not negotiate the + /// extended_master_secret extension, or false to support legacy interoperability. + /// + bool RequiresExtendedMasterSecret(); + + /// + /// draft-mathewson-no-gmtunixtime-00 2. "If existing users of a TLS implementation may rely on + /// gmt_unix_time containing the current time, we recommend that implementors MAY provide the + /// ability to set gmt_unix_time as an option only, off by default." + /// + /// + /// true if the current time should be used in the gmt_unix_time field of + /// Random, or false if gmt_unix_time should contain a cryptographically + /// random value. + /// + bool ShouldUseGmtUnixTime(); + + /// + /// Report whether the server supports secure renegotiation + /// + /// + /// The protocol handler automatically processes the relevant extensions + /// + /// + /// A , true if the server supports secure renegotiation + /// + /// + void NotifySecureRenegotiation(bool secureRenegotiation); + + /// + /// Return an implementation of to handle record compression. + /// + /// A + /// + TlsCompression GetCompression(); + + /// + /// Return an implementation of to use for encryption/decryption. + /// + /// A + /// + TlsCipher GetCipher(); + + /// This method will be called when an alert is raised by the protocol. + /// + /// + /// A human-readable message explaining what caused this alert. May be null. + /// The Exception that caused this alert to be raised. May be null. + void NotifyAlertRaised(byte alertLevel, byte alertDescription, string message, Exception cause); + + /// This method will be called when an alert is received from the remote peer. + /// + /// + void NotifyAlertReceived(byte alertLevel, byte alertDescription); + + /// Notifies the peer that the handshake has been successfully completed. + /// + void NotifyHandshakeComplete(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsPeer.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsPeer.cs.meta new file mode 100644 index 0000000..2fc4453 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsPeer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 85c90f92e686946419ccee87db5bfed3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsProtocol.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsProtocol.cs new file mode 100644 index 0000000..9e5d5c1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsProtocol.cs @@ -0,0 +1,1448 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Crypto.Prng; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class TlsProtocol + : TlsCloseable + { + /* + * Our Connection states + */ + protected const short CS_START = 0; + protected const short CS_CLIENT_HELLO = 1; + protected const short CS_SERVER_HELLO = 2; + protected const short CS_SERVER_SUPPLEMENTAL_DATA = 3; + protected const short CS_SERVER_CERTIFICATE = 4; + protected const short CS_CERTIFICATE_STATUS = 5; + protected const short CS_SERVER_KEY_EXCHANGE = 6; + protected const short CS_CERTIFICATE_REQUEST = 7; + protected const short CS_SERVER_HELLO_DONE = 8; + protected const short CS_CLIENT_SUPPLEMENTAL_DATA = 9; + protected const short CS_CLIENT_CERTIFICATE = 10; + protected const short CS_CLIENT_KEY_EXCHANGE = 11; + protected const short CS_CERTIFICATE_VERIFY = 12; + protected const short CS_CLIENT_FINISHED = 13; + protected const short CS_SERVER_SESSION_TICKET = 14; + protected const short CS_SERVER_FINISHED = 15; + protected const short CS_END = 16; + + /* + * Different modes to handle the known IV weakness + */ + protected const short ADS_MODE_1_Nsub1 = 0; // 1/n-1 record splitting + protected const short ADS_MODE_0_N = 1; // 0/n record splitting + protected const short ADS_MODE_0_N_FIRSTONLY = 2; // 0/n record splitting on first data fragment only + + /* + * Queues for data from some protocols. + */ + private ByteQueue mApplicationDataQueue = new ByteQueue(0); + private ByteQueue mAlertQueue = new ByteQueue(2); + private ByteQueue mHandshakeQueue = new ByteQueue(0); + // private ByteQueue mHeartbeatQueue = new ByteQueue(); + + /* + * The Record Stream we use + */ + internal RecordStream mRecordStream; + protected SecureRandom mSecureRandom; + + private TlsStream mTlsStream = null; + + private volatile bool mClosed = false; + private volatile bool mFailedWithError = false; + private volatile bool mAppDataReady = false; + private volatile bool mAppDataSplitEnabled = true; + private volatile int mAppDataSplitMode = ADS_MODE_1_Nsub1; + private byte[] mExpectedVerifyData = null; + + protected TlsSession mTlsSession = null; + protected SessionParameters mSessionParameters = null; + protected SecurityParameters mSecurityParameters = null; + protected Certificate mPeerCertificate = null; + + protected int[] mOfferedCipherSuites = null; + protected byte[] mOfferedCompressionMethods = null; + protected IDictionary mClientExtensions = null; + protected IDictionary mServerExtensions = null; + + protected short mConnectionState = CS_START; + protected bool mResumedSession = false; + protected bool mReceivedChangeCipherSpec = false; + protected bool mSecureRenegotiation = false; + protected bool mAllowCertificateStatus = false; + protected bool mExpectSessionTicket = false; + + protected bool mBlocking = true; + protected ByteQueueStream mInputBuffers = null; + protected ByteQueueStream mOutputBuffer = null; + + public TlsProtocol(Stream stream, SecureRandom secureRandom) + : this(stream, stream, secureRandom) + { + } + + public TlsProtocol(Stream input, Stream output, SecureRandom secureRandom) + { + this.mRecordStream = new RecordStream(this, input, output); + this.mSecureRandom = secureRandom; + } + + public TlsProtocol(SecureRandom secureRandom) + { + this.mBlocking = false; + this.mInputBuffers = new ByteQueueStream(); + this.mOutputBuffer = new ByteQueueStream(); + this.mRecordStream = new RecordStream(this, mInputBuffers, mOutputBuffer); + this.mSecureRandom = secureRandom; + } + + protected abstract TlsContext Context { get; } + + internal abstract AbstractTlsContext ContextAdmin { get; } + + protected abstract TlsPeer Peer { get; } + + protected virtual void HandleAlertMessage(byte alertLevel, byte alertDescription) + { + Peer.NotifyAlertReceived(alertLevel, alertDescription); + + if (alertLevel == AlertLevel.warning) + { + HandleAlertWarningMessage(alertDescription); + } + else + { + HandleFailure(); + + throw new TlsFatalAlertReceived(alertDescription); + } + } + + protected virtual void HandleAlertWarningMessage(byte alertDescription) + { + /* + * RFC 5246 7.2.1. The other party MUST respond with a close_notify alert of its own + * and close down the connection immediately, discarding any pending writes. + */ + if (alertDescription == AlertDescription.close_notify) + { + if (!mAppDataReady) + throw new TlsFatalAlert(AlertDescription.handshake_failure); + + HandleClose(false); + } + } + + protected virtual void HandleChangeCipherSpecMessage() + { + } + + protected virtual void HandleClose(bool user_canceled) + { + if (!mClosed) + { + this.mClosed = true; + + if (user_canceled && !mAppDataReady) + { + RaiseAlertWarning(AlertDescription.user_canceled, "User canceled handshake"); + } + + RaiseAlertWarning(AlertDescription.close_notify, "Connection closed"); + + mRecordStream.SafeClose(); + + if (!mAppDataReady) + { + CleanupHandshake(); + } + } + } + + protected virtual void HandleException(byte alertDescription, string message, Exception cause) + { + if (!mClosed) + { + RaiseAlertFatal(alertDescription, message, cause); + + HandleFailure(); + } + } + + protected virtual void HandleFailure() + { + this.mClosed = true; + this.mFailedWithError = true; + + /* + * RFC 2246 7.2.1. The session becomes unresumable if any connection is terminated + * without proper close_notify messages with level equal to warning. + */ + // TODO This isn't quite in the right place. Also, as of TLS 1.1 the above is obsolete. + InvalidateSession(); + + mRecordStream.SafeClose(); + + if (!mAppDataReady) + { + CleanupHandshake(); + } + } + + protected abstract void HandleHandshakeMessage(byte type, MemoryStream buf); + + protected virtual void ApplyMaxFragmentLengthExtension() + { + if (mSecurityParameters.maxFragmentLength >= 0) + { + if (!MaxFragmentLength.IsValid((byte)mSecurityParameters.maxFragmentLength)) + throw new TlsFatalAlert(AlertDescription.internal_error); + + int plainTextLimit = 1 << (8 + mSecurityParameters.maxFragmentLength); + mRecordStream.SetPlaintextLimit(plainTextLimit); + } + } + + protected virtual void CheckReceivedChangeCipherSpec(bool expected) + { + if (expected != mReceivedChangeCipherSpec) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + protected virtual void CleanupHandshake() + { + if (this.mExpectedVerifyData != null) + { + Arrays.Fill(this.mExpectedVerifyData, (byte)0); + this.mExpectedVerifyData = null; + } + + this.mSecurityParameters.Clear(); + this.mPeerCertificate = null; + + this.mOfferedCipherSuites = null; + this.mOfferedCompressionMethods = null; + this.mClientExtensions = null; + this.mServerExtensions = null; + + this.mResumedSession = false; + this.mReceivedChangeCipherSpec = false; + this.mSecureRenegotiation = false; + this.mAllowCertificateStatus = false; + this.mExpectSessionTicket = false; + } + + protected virtual void BlockForHandshake() + { + if (mBlocking) + { + while (this.mConnectionState != CS_END) + { + if (this.mClosed) + { + // NOTE: Any close during the handshake should have raised an exception. + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + SafeReadRecord(); + } + } + } + + protected virtual void CompleteHandshake() + { + try + { + this.mConnectionState = CS_END; + + this.mAlertQueue.Shrink(); + this.mHandshakeQueue.Shrink(); + + this.mRecordStream.FinaliseHandshake(); + + this.mAppDataSplitEnabled = !TlsUtilities.IsTlsV11(Context); + + /* + * If this was an initial handshake, we are now ready to send and receive application data. + */ + if (!mAppDataReady) + { + this.mAppDataReady = true; + + if (mBlocking) + { + this.mTlsStream = new TlsStream(this); + } + } + + if (this.mTlsSession != null) + { + if (this.mSessionParameters == null) + { + this.mSessionParameters = new SessionParameters.Builder() + .SetCipherSuite(this.mSecurityParameters.CipherSuite) + .SetCompressionAlgorithm(this.mSecurityParameters.CompressionAlgorithm) + .SetExtendedMasterSecret(this.mSecurityParameters.IsExtendedMasterSecret) + .SetMasterSecret(this.mSecurityParameters.MasterSecret) + .SetPeerCertificate(this.mPeerCertificate) + .SetPskIdentity(this.mSecurityParameters.PskIdentity) + .SetSrpIdentity(this.mSecurityParameters.SrpIdentity) + // TODO Consider filtering extensions that aren't relevant to resumed sessions + .SetServerExtensions(this.mServerExtensions) + .Build(); + + this.mTlsSession = new TlsSessionImpl(this.mTlsSession.SessionID, this.mSessionParameters); + } + + ContextAdmin.SetResumableSession(this.mTlsSession); + } + + Peer.NotifyHandshakeComplete(); + } + finally + { + CleanupHandshake(); + } + } + + protected internal void ProcessRecord(byte protocol, byte[] buf, int off, int len) + { + /* + * Have a look at the protocol type, and add it to the correct queue. + */ + switch (protocol) + { + case ContentType.alert: + { + mAlertQueue.AddData(buf, off, len); + ProcessAlertQueue(); + break; + } + case ContentType.application_data: + { + if (!mAppDataReady) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + + mApplicationDataQueue.AddData(buf, off, len); + ProcessApplicationDataQueue(); + break; + } + case ContentType.change_cipher_spec: + { + ProcessChangeCipherSpec(buf, off, len); + break; + } + case ContentType.handshake: + { + if (mHandshakeQueue.Available > 0) + { + mHandshakeQueue.AddData(buf, off, len); + ProcessHandshakeQueue(mHandshakeQueue); + } + else + { + ByteQueue tmpQueue = new ByteQueue(buf, off, len); + ProcessHandshakeQueue(tmpQueue); + int remaining = tmpQueue.Available; + if (remaining > 0) + { + mHandshakeQueue.AddData(buf, off + len - remaining, remaining); + } + } + break; + } + //case ContentType.heartbeat: + //{ + // if (!mAppDataReady) + // throw new TlsFatalAlert(AlertDescription.unexpected_message); + + // // TODO[RFC 6520] + // //mHeartbeatQueue.AddData(buf, offset, len); + // //ProcessHeartbeat(); + // break; + //} + default: + // Record type should already have been checked + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + private void ProcessHandshakeQueue(ByteQueue queue) + { + while (queue.Available >= 4) + { + /* + * We need the first 4 bytes, they contain type and length of the message. + */ + byte[] beginning = new byte[4]; + queue.Read(beginning, 0, 4, 0); + byte type = TlsUtilities.ReadUint8(beginning, 0); + int length = TlsUtilities.ReadUint24(beginning, 1); + int totalLength = 4 + length; + + /* + * Check if we have enough bytes in the buffer to read the full message. + */ + if (queue.Available < totalLength) + break; + + /* + * RFC 2246 7.4.9. The value handshake_messages includes all handshake messages + * starting at client hello up to, but not including, this finished message. + * [..] Note: [Also,] Hello Request messages are omitted from handshake hashes. + */ + if (HandshakeType.hello_request != type) + { + if (HandshakeType.finished == type) + { + CheckReceivedChangeCipherSpec(true); + + TlsContext ctx = Context; + if (this.mExpectedVerifyData == null + && ctx.SecurityParameters.MasterSecret != null) + { + this.mExpectedVerifyData = CreateVerifyData(!ctx.IsServer); + } + } + else + { + CheckReceivedChangeCipherSpec(mConnectionState == CS_END); + } + + queue.CopyTo(mRecordStream.HandshakeHashUpdater, totalLength); + } + + queue.RemoveData(4); + + MemoryStream buf = queue.ReadFrom(length); + + /* + * Now, parse the message. + */ + HandleHandshakeMessage(type, buf); + } + } + + private void ProcessApplicationDataQueue() + { + /* + * There is nothing we need to do here. + * + * This function could be used for callbacks when application data arrives in the future. + */ + } + + private void ProcessAlertQueue() + { + while (mAlertQueue.Available >= 2) + { + /* + * An alert is always 2 bytes. Read the alert. + */ + byte[] alert = mAlertQueue.RemoveData(2, 0); + byte alertLevel = alert[0]; + byte alertDescription = alert[1]; + + HandleAlertMessage(alertLevel, alertDescription); + } + } + + /** + * This method is called, when a change cipher spec message is received. + * + * @throws IOException If the message has an invalid content or the handshake is not in the correct + * state. + */ + private void ProcessChangeCipherSpec(byte[] buf, int off, int len) + { + for (int i = 0; i < len; ++i) + { + byte message = TlsUtilities.ReadUint8(buf, off + i); + + if (message != ChangeCipherSpec.change_cipher_spec) + throw new TlsFatalAlert(AlertDescription.decode_error); + + if (this.mReceivedChangeCipherSpec + || mAlertQueue.Available > 0 + || mHandshakeQueue.Available > 0) + { + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + mRecordStream.ReceivedReadCipherSpec(); + + this.mReceivedChangeCipherSpec = true; + + HandleChangeCipherSpecMessage(); + } + } + + protected internal virtual int ApplicationDataAvailable() + { + return mApplicationDataQueue.Available; + } + + /** + * Read data from the network. The method will return immediately, if there is still some data + * left in the buffer, or block until some application data has been read from the network. + * + * @param buf The buffer where the data will be copied to. + * @param offset The position where the data will be placed in the buffer. + * @param len The maximum number of bytes to read. + * @return The number of bytes read. + * @throws IOException If something goes wrong during reading data. + */ + protected internal virtual int ReadApplicationData(byte[] buf, int offset, int len) + { + if (len < 1) + return 0; + + while (mApplicationDataQueue.Available == 0) + { + if (this.mClosed) + { + if (this.mFailedWithError) + throw new IOException("Cannot read application data on failed TLS connection"); + + if (!mAppDataReady) + throw new InvalidOperationException("Cannot read application data until initial handshake completed."); + + return 0; + } + + SafeReadRecord(); + } + + len = System.Math.Min(len, mApplicationDataQueue.Available); + mApplicationDataQueue.RemoveData(buf, offset, len, 0); + return len; + } + + protected virtual void SafeCheckRecordHeader(byte[] recordHeader) + { + try + { + mRecordStream.CheckRecordHeader(recordHeader); + } + catch (TlsFatalAlert e) + { + HandleException(e.AlertDescription, "Failed to read record", e); + throw e; + } + catch (IOException e) + { + HandleException(AlertDescription.internal_error, "Failed to read record", e); + throw e; + } + catch (Exception e) + { + HandleException(AlertDescription.internal_error, "Failed to read record", e); + throw new TlsFatalAlert(AlertDescription.internal_error, e); + } + } + + protected virtual void SafeReadRecord() + { + try + { + if (mRecordStream.ReadRecord()) + return; + + if (!mAppDataReady) + throw new TlsFatalAlert(AlertDescription.handshake_failure); + } + catch (TlsFatalAlertReceived e) + { + // Connection failure already handled at source + throw e; + } + catch (TlsFatalAlert e) + { + HandleException(e.AlertDescription, "Failed to read record", e); + throw e; + } + catch (IOException e) + { + HandleException(AlertDescription.internal_error, "Failed to read record", e); + throw e; + } + catch (Exception e) + { + HandleException(AlertDescription.internal_error, "Failed to read record", e); + throw new TlsFatalAlert(AlertDescription.internal_error, e); + } + + HandleFailure(); + + throw new TlsNoCloseNotifyException(); + } + + protected virtual void SafeWriteRecord(byte type, byte[] buf, int offset, int len) + { + try + { + mRecordStream.WriteRecord(type, buf, offset, len); + } + catch (TlsFatalAlert e) + { + HandleException(e.AlertDescription, "Failed to write record", e); + throw e; + } + catch (IOException e) + { + HandleException(AlertDescription.internal_error, "Failed to write record", e); + throw e; + } + catch (Exception e) + { + HandleException(AlertDescription.internal_error, "Failed to write record", e); + throw new TlsFatalAlert(AlertDescription.internal_error, e); + } + } + + /** + * Send some application data to the remote system. + *

+ * The method will handle fragmentation internally. + * + * @param buf The buffer with the data. + * @param offset The position in the buffer where the data is placed. + * @param len The length of the data. + * @throws IOException If something goes wrong during sending. + */ + protected internal virtual void WriteData(byte[] buf, int offset, int len) + { + if (this.mClosed) + throw new IOException("Cannot write application data on closed/failed TLS connection"); + + while (len > 0) + { + /* + * RFC 5246 6.2.1. Zero-length fragments of Application data MAY be sent as they are + * potentially useful as a traffic analysis countermeasure. + * + * NOTE: Actually, implementations appear to have settled on 1/n-1 record splitting. + */ + + if (this.mAppDataSplitEnabled) + { + /* + * Protect against known IV attack! + * + * DO NOT REMOVE THIS CODE, EXCEPT YOU KNOW EXACTLY WHAT YOU ARE DOING HERE. + */ + switch (mAppDataSplitMode) + { + case ADS_MODE_0_N: + SafeWriteRecord(ContentType.application_data, TlsUtilities.EmptyBytes, 0, 0); + break; + case ADS_MODE_0_N_FIRSTONLY: + this.mAppDataSplitEnabled = false; + SafeWriteRecord(ContentType.application_data, TlsUtilities.EmptyBytes, 0, 0); + break; + case ADS_MODE_1_Nsub1: + default: + SafeWriteRecord(ContentType.application_data, buf, offset, 1); + ++offset; + --len; + break; + } + } + + if (len > 0) + { + // Fragment data according to the current fragment limit. + int toWrite = System.Math.Min(len, mRecordStream.GetPlaintextLimit()); + SafeWriteRecord(ContentType.application_data, buf, offset, toWrite); + offset += toWrite; + len -= toWrite; + } + } + } + + protected virtual void SetAppDataSplitMode(int appDataSplitMode) + { + if (appDataSplitMode < ADS_MODE_1_Nsub1 || appDataSplitMode > ADS_MODE_0_N_FIRSTONLY) + throw new ArgumentException("Illegal appDataSplitMode mode: " + appDataSplitMode, "appDataSplitMode"); + + this.mAppDataSplitMode = appDataSplitMode; + } + + protected virtual void WriteHandshakeMessage(byte[] buf, int off, int len) + { + if (len < 4) + throw new TlsFatalAlert(AlertDescription.internal_error); + + byte type = TlsUtilities.ReadUint8(buf, off); + if (type != HandshakeType.hello_request) + { + mRecordStream.HandshakeHashUpdater.Write(buf, off, len); + } + + int total = 0; + do + { + // Fragment data according to the current fragment limit. + int toWrite = System.Math.Min(len - total, mRecordStream.GetPlaintextLimit()); + SafeWriteRecord(ContentType.handshake, buf, off + total, toWrite); + total += toWrite; + } + while (total < len); + } + + ///

The secure bidirectional stream for this connection + /// Only allowed in blocking mode. + public virtual Stream Stream + { + get + { + if (!mBlocking) + throw new InvalidOperationException("Cannot use Stream in non-blocking mode! Use OfferInput()/OfferOutput() instead."); + return this.mTlsStream; + } + } + + /** + * Should be called in non-blocking mode when the input data reaches EOF. + */ + public virtual void CloseInput() + { + if (mBlocking) + throw new InvalidOperationException("Cannot use CloseInput() in blocking mode!"); + + if (mClosed) + return; + + if (mInputBuffers.Available > 0) + throw new EndOfStreamException(); + + if (!mAppDataReady) + throw new TlsFatalAlert(AlertDescription.handshake_failure); + + throw new TlsNoCloseNotifyException(); + } + + /** + * Equivalent to OfferInput(input, 0, input.length) + * @see TlsProtocol#OfferInput(byte[], int, int) + * @param input The input buffer to offer + * @throws IOException If an error occurs while decrypting or processing a record + */ + public virtual void OfferInput(byte[] input) + { + OfferInput(input, 0, input.Length); + } + + /** + * Offer input from an arbitrary source. Only allowed in non-blocking mode.
+ *
+ * This method will decrypt and process all records that are fully available. + * If only part of a record is available, the buffer will be retained until the + * remainder of the record is offered.
+ *
+ * If any records containing application data were processed, the decrypted data + * can be obtained using {@link #readInput(byte[], int, int)}. If any records + * containing protocol data were processed, a response may have been generated. + * You should always check to see if there is any available output after calling + * this method by calling {@link #getAvailableOutputBytes()}. + * @param input The input buffer to offer + * @param inputOff The offset within the input buffer that input begins + * @param inputLen The number of bytes of input being offered + * @throws IOException If an error occurs while decrypting or processing a record + */ + public virtual void OfferInput(byte[] input, int inputOff, int inputLen) + { + if (mBlocking) + throw new InvalidOperationException("Cannot use OfferInput() in blocking mode! Use Stream instead."); + if (mClosed) + throw new IOException("Connection is closed, cannot accept any more input"); + + mInputBuffers.Write(input, inputOff, inputLen); + + // loop while there are enough bytes to read the length of the next record + while (mInputBuffers.Available >= RecordStream.TLS_HEADER_SIZE) + { + byte[] recordHeader = new byte[RecordStream.TLS_HEADER_SIZE]; + mInputBuffers.Peek(recordHeader); + + int totalLength = TlsUtilities.ReadUint16(recordHeader, RecordStream.TLS_HEADER_LENGTH_OFFSET) + RecordStream.TLS_HEADER_SIZE; + if (mInputBuffers.Available < totalLength) + { + // not enough bytes to read a whole record + SafeCheckRecordHeader(recordHeader); + break; + } + + SafeReadRecord(); + + if (mClosed) + { + if (mConnectionState != CS_END) + { + // NOTE: Any close during the handshake should have raised an exception. + throw new TlsFatalAlert(AlertDescription.internal_error); + } + break; + } + } + } + + /** + * Gets the amount of received application data. A call to {@link #readInput(byte[], int, int)} + * is guaranteed to be able to return at least this much data.
+ *
+ * Only allowed in non-blocking mode. + * @return The number of bytes of available application data + */ + public virtual int GetAvailableInputBytes() + { + if (mBlocking) + throw new InvalidOperationException("Cannot use GetAvailableInputBytes() in blocking mode! Use ApplicationDataAvailable() instead."); + + return ApplicationDataAvailable(); + } + + /** + * Retrieves received application data. Use {@link #getAvailableInputBytes()} to check + * how much application data is currently available. This method functions similarly to + * {@link InputStream#read(byte[], int, int)}, except that it never blocks. If no data + * is available, nothing will be copied and zero will be returned.
+ *
+ * Only allowed in non-blocking mode. + * @param buffer The buffer to hold the application data + * @param offset The start offset in the buffer at which the data is written + * @param length The maximum number of bytes to read + * @return The total number of bytes copied to the buffer. May be less than the + * length specified if the length was greater than the amount of available data. + */ + public virtual int ReadInput(byte[] buffer, int offset, int length) + { + if (mBlocking) + throw new InvalidOperationException("Cannot use ReadInput() in blocking mode! Use Stream instead."); + + return ReadApplicationData(buffer, offset, System.Math.Min(length, ApplicationDataAvailable())); + } + + /** + * Offer output from an arbitrary source. Only allowed in non-blocking mode.
+ *
+ * After this method returns, the specified section of the buffer will have been + * processed. Use {@link #readOutput(byte[], int, int)} to get the bytes to + * transmit to the other peer.
+ *
+ * This method must not be called until after the handshake is complete! Attempting + * to call it before the handshake is complete will result in an exception. + * @param buffer The buffer containing application data to encrypt + * @param offset The offset at which to begin reading data + * @param length The number of bytes of data to read + * @throws IOException If an error occurs encrypting the data, or the handshake is not complete + */ + public virtual void OfferOutput(byte[] buffer, int offset, int length) + { + if (mBlocking) + throw new InvalidOperationException("Cannot use OfferOutput() in blocking mode! Use Stream instead."); + if (!mAppDataReady) + throw new IOException("Application data cannot be sent until the handshake is complete!"); + + WriteData(buffer, offset, length); + } + + /** + * Gets the amount of encrypted data available to be sent. A call to + * {@link #readOutput(byte[], int, int)} is guaranteed to be able to return at + * least this much data.
+ *
+ * Only allowed in non-blocking mode. + * @return The number of bytes of available encrypted data + */ + public virtual int GetAvailableOutputBytes() + { + if (mBlocking) + throw new InvalidOperationException("Cannot use GetAvailableOutputBytes() in blocking mode! Use Stream instead."); + + return mOutputBuffer.Available; + } + + /** + * Retrieves encrypted data to be sent. Use {@link #getAvailableOutputBytes()} to check + * how much encrypted data is currently available. This method functions similarly to + * {@link InputStream#read(byte[], int, int)}, except that it never blocks. If no data + * is available, nothing will be copied and zero will be returned.
+ *
+ * Only allowed in non-blocking mode. + * @param buffer The buffer to hold the encrypted data + * @param offset The start offset in the buffer at which the data is written + * @param length The maximum number of bytes to read + * @return The total number of bytes copied to the buffer. May be less than the + * length specified if the length was greater than the amount of available data. + */ + public virtual int ReadOutput(byte[] buffer, int offset, int length) + { + if (mBlocking) + throw new InvalidOperationException("Cannot use ReadOutput() in blocking mode! Use Stream instead."); + + return mOutputBuffer.Read(buffer, offset, length); + } + + protected virtual void InvalidateSession() + { + if (this.mSessionParameters != null) + { + this.mSessionParameters.Clear(); + this.mSessionParameters = null; + } + + if (this.mTlsSession != null) + { + this.mTlsSession.Invalidate(); + this.mTlsSession = null; + } + } + + protected virtual void ProcessFinishedMessage(MemoryStream buf) + { + if (mExpectedVerifyData == null) + throw new TlsFatalAlert(AlertDescription.internal_error); + + byte[] verify_data = TlsUtilities.ReadFully(mExpectedVerifyData.Length, buf); + + AssertEmpty(buf); + + /* + * Compare both checksums. + */ + if (!Arrays.ConstantTimeAreEqual(mExpectedVerifyData, verify_data)) + { + /* + * Wrong checksum in the finished message. + */ + throw new TlsFatalAlert(AlertDescription.decrypt_error); + } + } + + protected virtual void RaiseAlertFatal(byte alertDescription, string message, Exception cause) + { + Peer.NotifyAlertRaised(AlertLevel.fatal, alertDescription, message, cause); + + byte[] alert = new byte[]{ AlertLevel.fatal, alertDescription }; + + try + { + mRecordStream.WriteRecord(ContentType.alert, alert, 0, 2); + } + catch (Exception) + { + // We are already processing an exception, so just ignore this + } + } + + protected virtual void RaiseAlertWarning(byte alertDescription, string message) + { + Peer.NotifyAlertRaised(AlertLevel.warning, alertDescription, message, null); + + byte[] alert = new byte[]{ AlertLevel.warning, alertDescription }; + + SafeWriteRecord(ContentType.alert, alert, 0, 2); + } + + protected virtual void SendCertificateMessage(Certificate certificate) + { + if (certificate == null) + { + certificate = Certificate.EmptyChain; + } + + if (certificate.IsEmpty) + { + TlsContext context = Context; + if (!context.IsServer) + { + ProtocolVersion serverVersion = Context.ServerVersion; + if (serverVersion.IsSsl) + { + string errorMessage = serverVersion.ToString() + " client didn't provide credentials"; + RaiseAlertWarning(AlertDescription.no_certificate, errorMessage); + return; + } + } + } + + HandshakeMessage message = new HandshakeMessage(HandshakeType.certificate); + + certificate.Encode(message); + + message.WriteToRecordStream(this); + } + + protected virtual void SendChangeCipherSpecMessage() + { + byte[] message = new byte[]{ 1 }; + SafeWriteRecord(ContentType.change_cipher_spec, message, 0, message.Length); + mRecordStream.SentWriteCipherSpec(); + } + + protected virtual void SendFinishedMessage() + { + byte[] verify_data = CreateVerifyData(Context.IsServer); + + HandshakeMessage message = new HandshakeMessage(HandshakeType.finished, verify_data.Length); + + message.Write(verify_data, 0, verify_data.Length); + + message.WriteToRecordStream(this); + } + + protected virtual void SendSupplementalDataMessage(IList supplementalData) + { + HandshakeMessage message = new HandshakeMessage(HandshakeType.supplemental_data); + + WriteSupplementalData(message, supplementalData); + + message.WriteToRecordStream(this); + } + + protected virtual byte[] CreateVerifyData(bool isServer) + { + TlsContext context = Context; + string asciiLabel = isServer ? ExporterLabel.server_finished : ExporterLabel.client_finished; + byte[] sslSender = isServer ? TlsUtilities.SSL_SERVER : TlsUtilities.SSL_CLIENT; + byte[] hash = GetCurrentPrfHash(context, mRecordStream.HandshakeHash, sslSender); + return TlsUtilities.CalculateVerifyData(context, asciiLabel, hash); + } + + /** + * Closes this connection. + * + * @throws IOException If something goes wrong during closing. + */ + public virtual void Close() + { + HandleClose(true); + } + + protected internal virtual void Flush() + { + mRecordStream.Flush(); + } + + public virtual bool IsClosed + { + get { return mClosed; } + } + + protected virtual short ProcessMaxFragmentLengthExtension(IDictionary clientExtensions, IDictionary serverExtensions, + byte alertDescription) + { + short maxFragmentLength = TlsExtensionsUtilities.GetMaxFragmentLengthExtension(serverExtensions); + if (maxFragmentLength >= 0) + { + if (!MaxFragmentLength.IsValid((byte)maxFragmentLength) + || (!this.mResumedSession && maxFragmentLength != TlsExtensionsUtilities + .GetMaxFragmentLengthExtension(clientExtensions))) + { + throw new TlsFatalAlert(alertDescription); + } + } + return maxFragmentLength; + } + + protected virtual void RefuseRenegotiation() + { + /* + * RFC 5746 4.5 SSLv3 clients that refuse renegotiation SHOULD use a fatal + * handshake_failure alert. + */ + if (TlsUtilities.IsSsl(Context)) + throw new TlsFatalAlert(AlertDescription.handshake_failure); + + RaiseAlertWarning(AlertDescription.no_renegotiation, "Renegotiation not supported"); + } + + /** + * Make sure the InputStream 'buf' now empty. Fail otherwise. + * + * @param buf The InputStream to check. + * @throws IOException If 'buf' is not empty. + */ + protected internal static void AssertEmpty(MemoryStream buf) + { + if (buf.Position < buf.Length) + throw new TlsFatalAlert(AlertDescription.decode_error); + } + + protected internal static byte[] CreateRandomBlock(bool useGmtUnixTime, IRandomGenerator randomGenerator) + { + byte[] result = new byte[32]; + randomGenerator.NextBytes(result); + + if (useGmtUnixTime) + { + TlsUtilities.WriteGmtUnixTime(result, 0); + } + + return result; + } + + protected internal static byte[] CreateRenegotiationInfo(byte[] renegotiated_connection) + { + return TlsUtilities.EncodeOpaque8(renegotiated_connection); + } + + protected internal static void EstablishMasterSecret(TlsContext context, TlsKeyExchange keyExchange) + { + byte[] pre_master_secret = keyExchange.GeneratePremasterSecret(); + + try + { + context.SecurityParameters.masterSecret = TlsUtilities.CalculateMasterSecret(context, pre_master_secret); + } + finally + { + // TODO Is there a way to ensure the data is really overwritten? + /* + * RFC 2246 8.1. The pre_master_secret should be deleted from memory once the + * master_secret has been computed. + */ + if (pre_master_secret != null) + { + Arrays.Fill(pre_master_secret, (byte)0); + } + } + } + + /** + * 'sender' only relevant to SSLv3 + */ + protected internal static byte[] GetCurrentPrfHash(TlsContext context, TlsHandshakeHash handshakeHash, byte[] sslSender) + { + IDigest d = handshakeHash.ForkPrfHash(); + + if (sslSender != null && TlsUtilities.IsSsl(context)) + { + d.BlockUpdate(sslSender, 0, sslSender.Length); + } + + return DigestUtilities.DoFinal(d); + } + + protected internal static IDictionary ReadExtensions(MemoryStream input) + { + if (input.Position >= input.Length) + return null; + + byte[] extBytes = TlsUtilities.ReadOpaque16(input); + + AssertEmpty(input); + + MemoryStream buf = new MemoryStream(extBytes, false); + + // Integer -> byte[] + IDictionary extensions = Platform.CreateHashtable(); + + while (buf.Position < buf.Length) + { + int extension_type = TlsUtilities.ReadUint16(buf); + byte[] extension_data = TlsUtilities.ReadOpaque16(buf); + + /* + * RFC 3546 2.3 There MUST NOT be more than one extension of the same type. + */ + if (extensions.Contains(extension_type)) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + extensions.Add(extension_type, extension_data); + } + + return extensions; + } + + protected internal static IList ReadSupplementalDataMessage(MemoryStream input) + { + byte[] supp_data = TlsUtilities.ReadOpaque24(input); + + AssertEmpty(input); + + MemoryStream buf = new MemoryStream(supp_data, false); + + IList supplementalData = Platform.CreateArrayList(); + + while (buf.Position < buf.Length) + { + int supp_data_type = TlsUtilities.ReadUint16(buf); + byte[] data = TlsUtilities.ReadOpaque16(buf); + + supplementalData.Add(new SupplementalDataEntry(supp_data_type, data)); + } + + return supplementalData; + } + + protected internal static void WriteExtensions(Stream output, IDictionary extensions) + { + MemoryStream buf = new MemoryStream(); + + /* + * NOTE: There are reports of servers that don't accept a zero-length extension as the last + * one, so we write out any zero-length ones first as a best-effort workaround. + */ + WriteSelectedExtensions(buf, extensions, true); + WriteSelectedExtensions(buf, extensions, false); + + byte[] extBytes = buf.ToArray(); + + TlsUtilities.WriteOpaque16(extBytes, output); + } + + protected internal static void WriteSelectedExtensions(Stream output, IDictionary extensions, bool selectEmpty) + { + foreach (int extension_type in extensions.Keys) + { + byte[] extension_data = (byte[])extensions[extension_type]; + if (selectEmpty == (extension_data.Length == 0)) + { + TlsUtilities.CheckUint16(extension_type); + TlsUtilities.WriteUint16(extension_type, output); + TlsUtilities.WriteOpaque16(extension_data, output); + } + } + } + + protected internal static void WriteSupplementalData(Stream output, IList supplementalData) + { + MemoryStream buf = new MemoryStream(); + + foreach (SupplementalDataEntry entry in supplementalData) + { + int supp_data_type = entry.DataType; + TlsUtilities.CheckUint16(supp_data_type); + TlsUtilities.WriteUint16(supp_data_type, buf); + TlsUtilities.WriteOpaque16(entry.Data, buf); + } + + byte[] supp_data = buf.ToArray(); + + TlsUtilities.WriteOpaque24(supp_data, output); + } + + protected internal static int GetPrfAlgorithm(TlsContext context, int ciphersuite) + { + bool isTLSv12 = TlsUtilities.IsTlsV12(context); + + switch (ciphersuite) + { + case CipherSuite.TLS_DH_anon_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DH_anon_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DH_anon_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CCM: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CCM: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.DRAFT_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM_8: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM_8: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.DRAFT_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.DRAFT_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.DRAFT_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_PSK_DHE_WITH_AES_128_CCM_8: + case CipherSuite.TLS_PSK_DHE_WITH_AES_256_CCM_8: + case CipherSuite.TLS_PSK_WITH_AES_128_CCM: + case CipherSuite.TLS_PSK_WITH_AES_128_CCM_8: + case CipherSuite.TLS_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_PSK_WITH_AES_256_CCM: + case CipherSuite.TLS_PSK_WITH_AES_256_CCM_8: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.DRAFT_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.DRAFT_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_128_CCM: + case CipherSuite.TLS_RSA_WITH_AES_128_CCM_8: + case CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_256_CCM: + case CipherSuite.TLS_RSA_WITH_AES_256_CCM_8: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_NULL_SHA256: + { + if (isTLSv12) + { + return PrfAlgorithm.tls_prf_sha256; + } + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + case CipherSuite.TLS_DH_anon_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DH_DSS_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DH_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_DSS_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384: + { + if (isTLSv12) + { + return PrfAlgorithm.tls_prf_sha384; + } + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA384: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA384: + case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_PSK_WITH_NULL_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA384: + { + if (isTLSv12) + { + return PrfAlgorithm.tls_prf_sha384; + } + return PrfAlgorithm.tls_prf_legacy; + } + + default: + { + if (isTLSv12) + { + return PrfAlgorithm.tls_prf_sha256; + } + return PrfAlgorithm.tls_prf_legacy; + } + } + } + + internal class HandshakeMessage + : MemoryStream + { + internal HandshakeMessage(byte handshakeType) + : this(handshakeType, 60) + { + } + + internal HandshakeMessage(byte handshakeType, int length) + : base(length + 4) + { + TlsUtilities.WriteUint8(handshakeType, this); + // Reserve space for length + TlsUtilities.WriteUint24(0, this); + } + + internal void Write(byte[] data) + { + Write(data, 0, data.Length); + } + + internal void WriteToRecordStream(TlsProtocol protocol) + { + // Patch actual length back in + long length = Length - 4; + TlsUtilities.CheckUint24(length); + this.Position = 1; + TlsUtilities.WriteUint24((int)length, this); + +#if PORTABLE + byte[] buf = ToArray(); + int bufLen = buf.Length; +#else + byte[] buf = GetBuffer(); + int bufLen = (int)Length; +#endif + + protocol.WriteHandshakeMessage(buf, 0, bufLen); + Platform.Dispose(this); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsProtocol.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsProtocol.cs.meta new file mode 100644 index 0000000..be5bf25 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsProtocol.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: df524d7757621ce499db1e95b2c585fc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsProtocolHandler.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsProtocolHandler.cs new file mode 100644 index 0000000..6f22346 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsProtocolHandler.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections; +using System.IO; +using System.Text; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto.Agreement; +using Org.BouncyCastle.Crypto.Agreement.Srp; +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Encodings; +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.IO; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Prng; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Date; + +namespace Org.BouncyCastle.Crypto.Tls +{ + [Obsolete("Use 'TlsClientProtocol' instead")] + public class TlsProtocolHandler + : TlsClientProtocol + { + public TlsProtocolHandler(Stream stream, SecureRandom secureRandom) + : base(stream, stream, secureRandom) + { + } + + /// Both streams can be the same object + public TlsProtocolHandler(Stream input, Stream output, SecureRandom secureRandom) + : base(input, output, secureRandom) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsProtocolHandler.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsProtocolHandler.cs.meta new file mode 100644 index 0000000..776d00f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsProtocolHandler.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4b2e5aaacec533c44ae523892007caa6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsPskIdentity.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsPskIdentity.cs new file mode 100644 index 0000000..119064e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsPskIdentity.cs @@ -0,0 +1,15 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public interface TlsPskIdentity + { + void SkipIdentityHint(); + + void NotifyIdentityHint(byte[] psk_identity_hint); + + byte[] GetPskIdentity(); + + byte[] GetPsk(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsPskIdentity.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsPskIdentity.cs.meta new file mode 100644 index 0000000..db35a90 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsPskIdentity.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5953497f6bad89646acf75a57b17bd82 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsPskIdentityManager.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsPskIdentityManager.cs new file mode 100644 index 0000000..a72c229 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsPskIdentityManager.cs @@ -0,0 +1,11 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public interface TlsPskIdentityManager + { + byte[] GetHint(); + + byte[] GetPsk(byte[] identity); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsPskIdentityManager.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsPskIdentityManager.cs.meta new file mode 100644 index 0000000..11671bb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsPskIdentityManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f2c156a0f2568f5448e66ab8fe04dac2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsPskKeyExchange.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsPskKeyExchange.cs new file mode 100644 index 0000000..aec7af7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsPskKeyExchange.cs @@ -0,0 +1,334 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// (D)TLS PSK key exchange (RFC 4279). + public class TlsPskKeyExchange + : AbstractTlsKeyExchange + { + protected TlsPskIdentity mPskIdentity; + protected TlsPskIdentityManager mPskIdentityManager; + + protected TlsDHVerifier mDHVerifier; + protected DHParameters mDHParameters; + protected int[] mNamedCurves; + protected byte[] mClientECPointFormats, mServerECPointFormats; + + protected byte[] mPskIdentityHint = null; + protected byte[] mPsk = null; + + protected DHPrivateKeyParameters mDHAgreePrivateKey = null; + protected DHPublicKeyParameters mDHAgreePublicKey = null; + + protected ECPrivateKeyParameters mECAgreePrivateKey = null; + protected ECPublicKeyParameters mECAgreePublicKey = null; + + protected AsymmetricKeyParameter mServerPublicKey = null; + protected RsaKeyParameters mRsaServerPublicKey = null; + protected TlsEncryptionCredentials mServerCredentials = null; + protected byte[] mPremasterSecret; + + [Obsolete("Use constructor that takes a TlsDHVerifier")] + public TlsPskKeyExchange(int keyExchange, IList supportedSignatureAlgorithms, TlsPskIdentity pskIdentity, + TlsPskIdentityManager pskIdentityManager, DHParameters dhParameters, int[] namedCurves, + byte[] clientECPointFormats, byte[] serverECPointFormats) + : this(keyExchange, supportedSignatureAlgorithms, pskIdentity, pskIdentityManager, new DefaultTlsDHVerifier(), + dhParameters, namedCurves, clientECPointFormats, serverECPointFormats) + { + } + + public TlsPskKeyExchange(int keyExchange, IList supportedSignatureAlgorithms, TlsPskIdentity pskIdentity, + TlsPskIdentityManager pskIdentityManager, TlsDHVerifier dhVerifier, DHParameters dhParameters, int[] namedCurves, + byte[] clientECPointFormats, byte[] serverECPointFormats) + : base(keyExchange, supportedSignatureAlgorithms) + { + switch (keyExchange) + { + case KeyExchangeAlgorithm.DHE_PSK: + case KeyExchangeAlgorithm.ECDHE_PSK: + case KeyExchangeAlgorithm.PSK: + case KeyExchangeAlgorithm.RSA_PSK: + break; + default: + throw new InvalidOperationException("unsupported key exchange algorithm"); + } + + this.mPskIdentity = pskIdentity; + this.mPskIdentityManager = pskIdentityManager; + this.mDHVerifier = dhVerifier; + this.mDHParameters = dhParameters; + this.mNamedCurves = namedCurves; + this.mClientECPointFormats = clientECPointFormats; + this.mServerECPointFormats = serverECPointFormats; + } + + public override void SkipServerCredentials() + { + if (mKeyExchange == KeyExchangeAlgorithm.RSA_PSK) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + public override void ProcessServerCredentials(TlsCredentials serverCredentials) + { + if (!(serverCredentials is TlsEncryptionCredentials)) + throw new TlsFatalAlert(AlertDescription.internal_error); + + ProcessServerCertificate(serverCredentials.Certificate); + + this.mServerCredentials = (TlsEncryptionCredentials)serverCredentials; + } + + public override byte[] GenerateServerKeyExchange() + { + this.mPskIdentityHint = mPskIdentityManager.GetHint(); + + if (this.mPskIdentityHint == null && !RequiresServerKeyExchange) + return null; + + MemoryStream buf = new MemoryStream(); + + if (this.mPskIdentityHint == null) + { + TlsUtilities.WriteOpaque16(TlsUtilities.EmptyBytes, buf); + } + else + { + TlsUtilities.WriteOpaque16(this.mPskIdentityHint, buf); + } + + if (this.mKeyExchange == KeyExchangeAlgorithm.DHE_PSK) + { + if (this.mDHParameters == null) + throw new TlsFatalAlert(AlertDescription.internal_error); + + this.mDHAgreePrivateKey = TlsDHUtilities.GenerateEphemeralServerKeyExchange(mContext.SecureRandom, + this.mDHParameters, buf); + } + else if (this.mKeyExchange == KeyExchangeAlgorithm.ECDHE_PSK) + { + this.mECAgreePrivateKey = TlsEccUtilities.GenerateEphemeralServerKeyExchange(mContext.SecureRandom, + mNamedCurves, mClientECPointFormats, buf); + } + + return buf.ToArray(); + } + + public override void ProcessServerCertificate(Certificate serverCertificate) + { + if (mKeyExchange != KeyExchangeAlgorithm.RSA_PSK) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + if (serverCertificate.IsEmpty) + throw new TlsFatalAlert(AlertDescription.decode_error); + + X509CertificateStructure x509Cert = serverCertificate.GetCertificateAt(0); + + SubjectPublicKeyInfo keyInfo = x509Cert.SubjectPublicKeyInfo; + try + { + this.mServerPublicKey = PublicKeyFactory.CreateKey(keyInfo); + } + catch (Exception e) + { + throw new TlsFatalAlert(AlertDescription.unsupported_certificate, e); + } + + // Sanity check the PublicKeyFactory + if (this.mServerPublicKey.IsPrivate) + throw new TlsFatalAlert(AlertDescription.internal_error); + + this.mRsaServerPublicKey = ValidateRsaPublicKey((RsaKeyParameters)this.mServerPublicKey); + + TlsUtilities.ValidateKeyUsage(x509Cert, KeyUsage.KeyEncipherment); + + base.ProcessServerCertificate(serverCertificate); + } + + public override bool RequiresServerKeyExchange + { + get + { + switch (mKeyExchange) + { + case KeyExchangeAlgorithm.DHE_PSK: + case KeyExchangeAlgorithm.ECDHE_PSK: + return true; + default: + return false; + } + } + } + + public override void ProcessServerKeyExchange(Stream input) + { + this.mPskIdentityHint = TlsUtilities.ReadOpaque16(input); + + if (this.mKeyExchange == KeyExchangeAlgorithm.DHE_PSK) + { + this.mDHParameters = TlsDHUtilities.ReceiveDHParameters(mDHVerifier, input); + this.mDHAgreePublicKey = new DHPublicKeyParameters(TlsDHUtilities.ReadDHParameter(input), mDHParameters); + } + else if (this.mKeyExchange == KeyExchangeAlgorithm.ECDHE_PSK) + { + ECDomainParameters ecParams = TlsEccUtilities.ReadECParameters(mNamedCurves, mClientECPointFormats, input); + + byte[] point = TlsUtilities.ReadOpaque8(input); + + this.mECAgreePublicKey = TlsEccUtilities.ValidateECPublicKey(TlsEccUtilities.DeserializeECPublicKey( + mClientECPointFormats, ecParams, point)); + } + } + + public override void ValidateCertificateRequest(CertificateRequest certificateRequest) + { + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + public override void ProcessClientCredentials(TlsCredentials clientCredentials) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public override void GenerateClientKeyExchange(Stream output) + { + if (mPskIdentityHint == null) + { + mPskIdentity.SkipIdentityHint(); + } + else + { + mPskIdentity.NotifyIdentityHint(mPskIdentityHint); + } + + byte[] psk_identity = mPskIdentity.GetPskIdentity(); + if (psk_identity == null) + throw new TlsFatalAlert(AlertDescription.internal_error); + + this.mPsk = mPskIdentity.GetPsk(); + if (mPsk == null) + throw new TlsFatalAlert(AlertDescription.internal_error); + + TlsUtilities.WriteOpaque16(psk_identity, output); + + mContext.SecurityParameters.pskIdentity = psk_identity; + + if (this.mKeyExchange == KeyExchangeAlgorithm.DHE_PSK) + { + this.mDHAgreePrivateKey = TlsDHUtilities.GenerateEphemeralClientKeyExchange(mContext.SecureRandom, + mDHParameters, output); + } + else if (this.mKeyExchange == KeyExchangeAlgorithm.ECDHE_PSK) + { + this.mECAgreePrivateKey = TlsEccUtilities.GenerateEphemeralClientKeyExchange(mContext.SecureRandom, + mServerECPointFormats, mECAgreePublicKey.Parameters, output); + } + else if (this.mKeyExchange == KeyExchangeAlgorithm.RSA_PSK) + { + this.mPremasterSecret = TlsRsaUtilities.GenerateEncryptedPreMasterSecret(mContext, + this.mRsaServerPublicKey, output); + } + } + + public override void ProcessClientKeyExchange(Stream input) + { + byte[] psk_identity = TlsUtilities.ReadOpaque16(input); + + this.mPsk = mPskIdentityManager.GetPsk(psk_identity); + if (mPsk == null) + throw new TlsFatalAlert(AlertDescription.unknown_psk_identity); + + mContext.SecurityParameters.pskIdentity = psk_identity; + + if (this.mKeyExchange == KeyExchangeAlgorithm.DHE_PSK) + { + this.mDHAgreePublicKey = new DHPublicKeyParameters(TlsDHUtilities.ReadDHParameter(input), mDHParameters); + } + else if (this.mKeyExchange == KeyExchangeAlgorithm.ECDHE_PSK) + { + byte[] point = TlsUtilities.ReadOpaque8(input); + + ECDomainParameters curve_params = this.mECAgreePrivateKey.Parameters; + + this.mECAgreePublicKey = TlsEccUtilities.ValidateECPublicKey(TlsEccUtilities.DeserializeECPublicKey( + mServerECPointFormats, curve_params, point)); + } + else if (this.mKeyExchange == KeyExchangeAlgorithm.RSA_PSK) + { + byte[] encryptedPreMasterSecret; + if (TlsUtilities.IsSsl(mContext)) + { + // TODO Do any SSLv3 clients actually include the length? + encryptedPreMasterSecret = Streams.ReadAll(input); + } + else + { + encryptedPreMasterSecret = TlsUtilities.ReadOpaque16(input); + } + + this.mPremasterSecret = mServerCredentials.DecryptPreMasterSecret(encryptedPreMasterSecret); + } + } + + public override byte[] GeneratePremasterSecret() + { + byte[] other_secret = GenerateOtherSecret(mPsk.Length); + + MemoryStream buf = new MemoryStream(4 + other_secret.Length + mPsk.Length); + TlsUtilities.WriteOpaque16(other_secret, buf); + TlsUtilities.WriteOpaque16(mPsk, buf); + + Arrays.Fill(mPsk, (byte)0); + this.mPsk = null; + + return buf.ToArray(); + } + + protected virtual byte[] GenerateOtherSecret(int pskLength) + { + if (this.mKeyExchange == KeyExchangeAlgorithm.DHE_PSK) + { + if (mDHAgreePrivateKey != null) + { + return TlsDHUtilities.CalculateDHBasicAgreement(mDHAgreePublicKey, mDHAgreePrivateKey); + } + + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + if (this.mKeyExchange == KeyExchangeAlgorithm.ECDHE_PSK) + { + if (mECAgreePrivateKey != null) + { + return TlsEccUtilities.CalculateECDHBasicAgreement(mECAgreePublicKey, mECAgreePrivateKey); + } + + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + if (this.mKeyExchange == KeyExchangeAlgorithm.RSA_PSK) + { + return this.mPremasterSecret; + } + + return new byte[pskLength]; + } + + protected virtual RsaKeyParameters ValidateRsaPublicKey(RsaKeyParameters key) + { + // TODO What is the minimum bit length required? + // key.Modulus.BitLength; + + if (!key.Exponent.IsProbablePrime(2)) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + return key; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsPskKeyExchange.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsPskKeyExchange.cs.meta new file mode 100644 index 0000000..3673dde --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsPskKeyExchange.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a038679d5aaaf5d4f8ebe58b5bf72a46 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsRsaKeyExchange.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsRsaKeyExchange.cs new file mode 100644 index 0000000..0e7195f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsRsaKeyExchange.cs @@ -0,0 +1,140 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto.Encodings; +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// (D)TLS and SSLv3 RSA key exchange. + public class TlsRsaKeyExchange + : AbstractTlsKeyExchange + { + protected AsymmetricKeyParameter mServerPublicKey = null; + + protected RsaKeyParameters mRsaServerPublicKey = null; + + protected TlsEncryptionCredentials mServerCredentials = null; + + protected byte[] mPremasterSecret; + + public TlsRsaKeyExchange(IList supportedSignatureAlgorithms) + : base(KeyExchangeAlgorithm.RSA, supportedSignatureAlgorithms) + { + } + + public override void SkipServerCredentials() + { + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + public override void ProcessServerCredentials(TlsCredentials serverCredentials) + { + if (!(serverCredentials is TlsEncryptionCredentials)) + throw new TlsFatalAlert(AlertDescription.internal_error); + + ProcessServerCertificate(serverCredentials.Certificate); + + this.mServerCredentials = (TlsEncryptionCredentials)serverCredentials; + } + + public override void ProcessServerCertificate(Certificate serverCertificate) + { + if (serverCertificate.IsEmpty) + throw new TlsFatalAlert(AlertDescription.decode_error); + + X509CertificateStructure x509Cert = serverCertificate.GetCertificateAt(0); + + SubjectPublicKeyInfo keyInfo = x509Cert.SubjectPublicKeyInfo; + try + { + this.mServerPublicKey = PublicKeyFactory.CreateKey(keyInfo); + } + catch (Exception e) + { + throw new TlsFatalAlert(AlertDescription.unsupported_certificate, e); + } + + // Sanity check the PublicKeyFactory + if (this.mServerPublicKey.IsPrivate) + throw new TlsFatalAlert(AlertDescription.internal_error); + + this.mRsaServerPublicKey = ValidateRsaPublicKey((RsaKeyParameters)this.mServerPublicKey); + + TlsUtilities.ValidateKeyUsage(x509Cert, KeyUsage.KeyEncipherment); + + base.ProcessServerCertificate(serverCertificate); + } + + public override void ValidateCertificateRequest(CertificateRequest certificateRequest) + { + byte[] types = certificateRequest.CertificateTypes; + for (int i = 0; i < types.Length; ++i) + { + switch (types[i]) + { + case ClientCertificateType.rsa_sign: + case ClientCertificateType.dss_sign: + case ClientCertificateType.ecdsa_sign: + break; + default: + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + } + } + + public override void ProcessClientCredentials(TlsCredentials clientCredentials) + { + if (!(clientCredentials is TlsSignerCredentials)) + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public override void GenerateClientKeyExchange(Stream output) + { + this.mPremasterSecret = TlsRsaUtilities.GenerateEncryptedPreMasterSecret(mContext, mRsaServerPublicKey, output); + } + + public override void ProcessClientKeyExchange(Stream input) + { + byte[] encryptedPreMasterSecret; + if (TlsUtilities.IsSsl(mContext)) + { + // TODO Do any SSLv3 clients actually include the length? + encryptedPreMasterSecret = Streams.ReadAll(input); + } + else + { + encryptedPreMasterSecret = TlsUtilities.ReadOpaque16(input); + } + + this.mPremasterSecret = mServerCredentials.DecryptPreMasterSecret(encryptedPreMasterSecret); + } + + public override byte[] GeneratePremasterSecret() + { + if (this.mPremasterSecret == null) + throw new TlsFatalAlert(AlertDescription.internal_error); + + byte[] tmp = this.mPremasterSecret; + this.mPremasterSecret = null; + return tmp; + } + + protected virtual RsaKeyParameters ValidateRsaPublicKey(RsaKeyParameters key) + { + // TODO What is the minimum bit length required? + // key.Modulus.BitLength; + + if (!key.Exponent.IsProbablePrime(2)) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + return key; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsRsaKeyExchange.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsRsaKeyExchange.cs.meta new file mode 100644 index 0000000..49025a6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsRsaKeyExchange.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 98e89a5996880214dbc560c4f9ce040a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsRsaSigner.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsRsaSigner.cs new file mode 100644 index 0000000..1614f50 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsRsaSigner.cs @@ -0,0 +1,102 @@ +using System; + +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Encodings; +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Signers; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class TlsRsaSigner + : AbstractTlsSigner + { + public override byte[] GenerateRawSignature(SignatureAndHashAlgorithm algorithm, + AsymmetricKeyParameter privateKey, byte[] hash) + { + ISigner signer = MakeSigner(algorithm, true, true, + new ParametersWithRandom(privateKey, this.mContext.SecureRandom)); + signer.BlockUpdate(hash, 0, hash.Length); + return signer.GenerateSignature(); + } + + public override bool VerifyRawSignature(SignatureAndHashAlgorithm algorithm, byte[] sigBytes, + AsymmetricKeyParameter publicKey, byte[] hash) + { + ISigner signer = MakeSigner(algorithm, true, false, publicKey); + signer.BlockUpdate(hash, 0, hash.Length); + return signer.VerifySignature(sigBytes); + } + + public override ISigner CreateSigner(SignatureAndHashAlgorithm algorithm, AsymmetricKeyParameter privateKey) + { + return MakeSigner(algorithm, false, true, new ParametersWithRandom(privateKey, this.mContext.SecureRandom)); + } + + public override ISigner CreateVerifyer(SignatureAndHashAlgorithm algorithm, AsymmetricKeyParameter publicKey) + { + return MakeSigner(algorithm, false, false, publicKey); + } + + public override bool IsValidPublicKey(AsymmetricKeyParameter publicKey) + { + return publicKey is RsaKeyParameters && !publicKey.IsPrivate; + } + + protected virtual ISigner MakeSigner(SignatureAndHashAlgorithm algorithm, bool raw, bool forSigning, + ICipherParameters cp) + { + if ((algorithm != null) != TlsUtilities.IsTlsV12(mContext)) + throw new InvalidOperationException(); + if (algorithm != null && algorithm.Signature != SignatureAlgorithm.rsa) + throw new InvalidOperationException(); + + IDigest d; + if (raw) + { + d = new NullDigest(); + } + else if (algorithm == null) + { + d = new CombinedHash(); + } + else + { + d = TlsUtilities.CreateHash(algorithm.Hash); + } + + ISigner s; + if (algorithm != null) + { + /* + * RFC 5246 4.7. In RSA signing, the opaque vector contains the signature generated + * using the RSASSA-PKCS1-v1_5 signature scheme defined in [PKCS1]. + */ + s = new RsaDigestSigner(d, TlsUtilities.GetOidForHashAlgorithm(algorithm.Hash)); + } + else + { + /* + * RFC 5246 4.7. Note that earlier versions of TLS used a different RSA signature scheme + * that did not include a DigestInfo encoding. + */ + s = new GenericSigner(CreateRsaImpl(), d); + } + s.Init(forSigning, cp); + return s; + } + + protected virtual IAsymmetricBlockCipher CreateRsaImpl() + { + /* + * RFC 5246 7.4.7.1. Implementation note: It is now known that remote timing-based attacks + * on TLS are possible, at least when the client and server are on the same LAN. + * Accordingly, implementations that use static RSA keys MUST use RSA blinding or some other + * anti-timing technique, as described in [TIMING]. + */ + return new Pkcs1Encoding(new RsaBlindedEngine()); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsRsaSigner.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsRsaSigner.cs.meta new file mode 100644 index 0000000..6962542 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsRsaSigner.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5703bf6aa989ac245918d696bf5c7388 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsRsaUtilities.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsRsaUtilities.cs new file mode 100644 index 0000000..0e42c17 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsRsaUtilities.cs @@ -0,0 +1,132 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Crypto.Encodings; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class TlsRsaUtilities + { + /// + public static byte[] GenerateEncryptedPreMasterSecret(TlsContext context, RsaKeyParameters rsaServerPublicKey, + Stream output) + { + /* + * Choose a PremasterSecret and send it encrypted to the server + */ + byte[] premasterSecret = new byte[48]; + context.SecureRandom.NextBytes(premasterSecret); + TlsUtilities.WriteVersion(context.ClientVersion, premasterSecret, 0); + + Pkcs1Encoding encoding = new Pkcs1Encoding(new RsaBlindedEngine()); + encoding.Init(true, new ParametersWithRandom(rsaServerPublicKey, context.SecureRandom)); + + try + { + byte[] encryptedPreMasterSecret = encoding.ProcessBlock(premasterSecret, 0, premasterSecret.Length); + + if (TlsUtilities.IsSsl(context)) + { + // TODO Do any SSLv3 servers actually expect the length? + output.Write(encryptedPreMasterSecret, 0, encryptedPreMasterSecret.Length); + } + else + { + TlsUtilities.WriteOpaque16(encryptedPreMasterSecret, output); + } + } + catch (InvalidCipherTextException e) + { + /* + * This should never happen, only during decryption. + */ + throw new TlsFatalAlert(AlertDescription.internal_error, e); + } + + return premasterSecret; + } + + public static byte[] SafeDecryptPreMasterSecret(TlsContext context, RsaKeyParameters rsaServerPrivateKey, + byte[] encryptedPreMasterSecret) + { + /* + * RFC 5246 7.4.7.1. + */ + ProtocolVersion clientVersion = context.ClientVersion; + + // TODO Provide as configuration option? + bool versionNumberCheckDisabled = false; + + /* + * Generate 48 random bytes we can use as a Pre-Master-Secret, if the + * PKCS1 padding check should fail. + */ + byte[] fallback = new byte[48]; + context.SecureRandom.NextBytes(fallback); + + byte[] M = Arrays.Clone(fallback); + try + { + Pkcs1Encoding encoding = new Pkcs1Encoding(new RsaBlindedEngine(), fallback); + encoding.Init(false, + new ParametersWithRandom(rsaServerPrivateKey, context.SecureRandom)); + + M = encoding.ProcessBlock(encryptedPreMasterSecret, 0, encryptedPreMasterSecret.Length); + } + catch (Exception) + { + /* + * This should never happen since the decryption should never throw an exception + * and return a random value instead. + * + * In any case, a TLS server MUST NOT generate an alert if processing an + * RSA-encrypted premaster secret message fails, or the version number is not as + * expected. Instead, it MUST continue the handshake with a randomly generated + * premaster secret. + */ + } + + /* + * If ClientHello.client_version is TLS 1.1 or higher, server implementations MUST + * check the version number [..]. + */ + if (versionNumberCheckDisabled && clientVersion.IsEqualOrEarlierVersionOf(ProtocolVersion.TLSv10)) + { + /* + * If the version number is TLS 1.0 or earlier, server + * implementations SHOULD check the version number, but MAY have a + * configuration option to disable the check. + * + * So there is nothing to do here. + */ + } + else + { + /* + * OK, we need to compare the version number in the decrypted Pre-Master-Secret with the + * clientVersion received during the handshake. If they don't match, we replace the + * decrypted Pre-Master-Secret with a random one. + */ + int correct = (clientVersion.MajorVersion ^ (M[0] & 0xff)) + | (clientVersion.MinorVersion ^ (M[1] & 0xff)); + correct |= correct >> 1; + correct |= correct >> 2; + correct |= correct >> 4; + int mask = ~((correct & 1) - 1); + + /* + * mask will be all bits set to 0xff if the version number differed. + */ + for (int i = 0; i < 48; i++) + { + M[i] = (byte)((M[i] & (~mask)) | (fallback[i] & mask)); + } + } + return M; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsRsaUtilities.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsRsaUtilities.cs.meta new file mode 100644 index 0000000..a2ea619 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsRsaUtilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0262e9cc6882bc4488fe5f4553dd9723 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsServer.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsServer.cs new file mode 100644 index 0000000..e791f93 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsServer.cs @@ -0,0 +1,93 @@ +using System; +using System.Collections; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public interface TlsServer + : TlsPeer + { + void Init(TlsServerContext context); + + /// + void NotifyClientVersion(ProtocolVersion clientVersion); + + /// + void NotifyFallback(bool isFallback); + + /// + void NotifyOfferedCipherSuites(int[] offeredCipherSuites); + + /// + void NotifyOfferedCompressionMethods(byte[] offeredCompressionMethods); + + /// A (Int32 -> byte[]). Will never be null. + /// + void ProcessClientExtensions(IDictionary clientExtensions); + + /// + ProtocolVersion GetServerVersion(); + + /// + int GetSelectedCipherSuite(); + + /// + byte GetSelectedCompressionMethod(); + + /// + /// Get the (optional) table of server extensions to be included in (extended) server hello. + /// + /// + /// A (Int32 -> byte[]). May be null. + /// + /// + IDictionary GetServerExtensions(); + + /// + /// A (). May be null. + /// + /// + IList GetServerSupplementalData(); + + /// + TlsCredentials GetCredentials(); + + /// + /// This method will be called (only) if the server included an extension of type + /// "status_request" with empty "extension_data" in the extended server hello. See RFC 3546 + /// 3.6. Certificate Status Request. If a non-null is returned, it + /// is sent to the client as a handshake message of type "certificate_status". + /// + /// A to be sent to the client (or null for none). + /// + CertificateStatus GetCertificateStatus(); + + /// + TlsKeyExchange GetKeyExchange(); + + /// + CertificateRequest GetCertificateRequest(); + + /// () + /// + void ProcessClientSupplementalData(IList clientSupplementalData); + + /// + /// Called by the protocol handler to report the client certificate, only if GetCertificateRequest + /// returned non-null. + /// + /// Note: this method is responsible for certificate verification and validation. + /// the effective client certificate (may be an empty chain). + /// + void NotifyClientCertificate(Certificate clientCertificate); + + /// RFC 5077 3.3. NewSessionTicket Handshake Message. + /// + /// This method will be called (only) if a NewSessionTicket extension was sent by the server. See + /// RFC 5077 4. Recommended Ticket Construction for recommended format and protection. + /// + /// The ticket) + /// + NewSessionTicket GetNewSessionTicket(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsServer.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsServer.cs.meta new file mode 100644 index 0000000..d680af4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsServer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 30698ab33e9df994f988db0fd396eb8d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsServerContext.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsServerContext.cs new file mode 100644 index 0000000..4021571 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsServerContext.cs @@ -0,0 +1,11 @@ +using System; + +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public interface TlsServerContext + : TlsContext + { + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsServerContext.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsServerContext.cs.meta new file mode 100644 index 0000000..ff81680 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsServerContext.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6289cae37fdb09346bf6fe876de0ebb6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsServerContextImpl.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsServerContextImpl.cs new file mode 100644 index 0000000..d56566f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsServerContextImpl.cs @@ -0,0 +1,20 @@ +using System; + +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Tls +{ + internal class TlsServerContextImpl + : AbstractTlsContext, TlsServerContext + { + internal TlsServerContextImpl(SecureRandom secureRandom, SecurityParameters securityParameters) + : base(secureRandom, securityParameters) + { + } + + public override bool IsServer + { + get { return true; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsServerContextImpl.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsServerContextImpl.cs.meta new file mode 100644 index 0000000..a0a9a47 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsServerContextImpl.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 87fdf2891711b27438d95906e5df2700 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsServerProtocol.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsServerProtocol.cs new file mode 100644 index 0000000..85b450c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsServerProtocol.cs @@ -0,0 +1,832 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class TlsServerProtocol + : TlsProtocol + { + protected TlsServer mTlsServer = null; + internal TlsServerContextImpl mTlsServerContext = null; + + protected TlsKeyExchange mKeyExchange = null; + protected TlsCredentials mServerCredentials = null; + protected CertificateRequest mCertificateRequest = null; + + protected short mClientCertificateType = -1; + protected TlsHandshakeHash mPrepareFinishHash = null; + + /** + * Constructor for blocking mode. + * @param stream The bi-directional stream of data to/from the client + * @param output The stream of data to the client + * @param secureRandom Random number generator for various cryptographic functions + */ + public TlsServerProtocol(Stream stream, SecureRandom secureRandom) + : base(stream, secureRandom) + { + } + + /** + * Constructor for blocking mode. + * @param input The stream of data from the client + * @param output The stream of data to the client + * @param secureRandom Random number generator for various cryptographic functions + */ + public TlsServerProtocol(Stream input, Stream output, SecureRandom secureRandom) + : base(input, output, secureRandom) + { + } + + /** + * Constructor for non-blocking mode.
+ *
+ * When data is received, use {@link #offerInput(java.nio.ByteBuffer)} to + * provide the received ciphertext, then use + * {@link #readInput(byte[], int, int)} to read the corresponding cleartext.
+ *
+ * Similarly, when data needs to be sent, use + * {@link #offerOutput(byte[], int, int)} to provide the cleartext, then use + * {@link #readOutput(byte[], int, int)} to get the corresponding + * ciphertext. + * + * @param secureRandom + * Random number generator for various cryptographic functions + */ + public TlsServerProtocol(SecureRandom secureRandom) + : base(secureRandom) + { + } + + /** + * Receives a TLS handshake in the role of server.
+ *
+ * In blocking mode, this will not return until the handshake is complete. + * In non-blocking mode, use {@link TlsPeer#notifyHandshakeComplete()} to + * receive a callback when the handshake is complete. + * + * @param tlsServer + * @throws IOException If in blocking mode and handshake was not successful. + */ + public virtual void Accept(TlsServer tlsServer) + { + if (tlsServer == null) + throw new ArgumentNullException("tlsServer"); + if (this.mTlsServer != null) + throw new InvalidOperationException("'Accept' can only be called once"); + + this.mTlsServer = tlsServer; + + this.mSecurityParameters = new SecurityParameters(); + this.mSecurityParameters.entity = ConnectionEnd.server; + + this.mTlsServerContext = new TlsServerContextImpl(mSecureRandom, mSecurityParameters); + + this.mSecurityParameters.serverRandom = CreateRandomBlock(tlsServer.ShouldUseGmtUnixTime(), + mTlsServerContext.NonceRandomGenerator); + + this.mTlsServer.Init(mTlsServerContext); + this.mRecordStream.Init(mTlsServerContext); + + tlsServer.NotifyCloseHandle(this); + + this.mRecordStream.SetRestrictReadVersion(false); + + BlockForHandshake(); + } + + protected override void CleanupHandshake() + { + base.CleanupHandshake(); + + this.mKeyExchange = null; + this.mServerCredentials = null; + this.mCertificateRequest = null; + this.mPrepareFinishHash = null; + } + + protected override TlsContext Context + { + get { return mTlsServerContext; } + } + + internal override AbstractTlsContext ContextAdmin + { + get { return mTlsServerContext; } + } + + protected override TlsPeer Peer + { + get { return mTlsServer; } + } + + protected override void HandleHandshakeMessage(byte type, MemoryStream buf) + { + switch (type) + { + case HandshakeType.client_hello: + { + switch (this.mConnectionState) + { + case CS_START: + { + ReceiveClientHelloMessage(buf); + this.mConnectionState = CS_CLIENT_HELLO; + + SendServerHelloMessage(); + this.mConnectionState = CS_SERVER_HELLO; + + mRecordStream.NotifyHelloComplete(); + + IList serverSupplementalData = mTlsServer.GetServerSupplementalData(); + if (serverSupplementalData != null) + { + SendSupplementalDataMessage(serverSupplementalData); + } + this.mConnectionState = CS_SERVER_SUPPLEMENTAL_DATA; + + this.mKeyExchange = mTlsServer.GetKeyExchange(); + this.mKeyExchange.Init(Context); + + this.mServerCredentials = mTlsServer.GetCredentials(); + + Certificate serverCertificate = null; + + if (this.mServerCredentials == null) + { + this.mKeyExchange.SkipServerCredentials(); + } + else + { + this.mKeyExchange.ProcessServerCredentials(this.mServerCredentials); + + serverCertificate = this.mServerCredentials.Certificate; + SendCertificateMessage(serverCertificate); + } + this.mConnectionState = CS_SERVER_CERTIFICATE; + + // TODO[RFC 3546] Check whether empty certificates is possible, allowed, or excludes CertificateStatus + if (serverCertificate == null || serverCertificate.IsEmpty) + { + this.mAllowCertificateStatus = false; + } + + if (this.mAllowCertificateStatus) + { + CertificateStatus certificateStatus = mTlsServer.GetCertificateStatus(); + if (certificateStatus != null) + { + SendCertificateStatusMessage(certificateStatus); + } + } + + this.mConnectionState = CS_CERTIFICATE_STATUS; + + byte[] serverKeyExchange = this.mKeyExchange.GenerateServerKeyExchange(); + if (serverKeyExchange != null) + { + SendServerKeyExchangeMessage(serverKeyExchange); + } + this.mConnectionState = CS_SERVER_KEY_EXCHANGE; + + if (this.mServerCredentials != null) + { + this.mCertificateRequest = mTlsServer.GetCertificateRequest(); + if (this.mCertificateRequest != null) + { + if (TlsUtilities.IsTlsV12(Context) != (mCertificateRequest.SupportedSignatureAlgorithms != null)) + throw new TlsFatalAlert(AlertDescription.internal_error); + + this.mKeyExchange.ValidateCertificateRequest(mCertificateRequest); + + SendCertificateRequestMessage(mCertificateRequest); + + TlsUtilities.TrackHashAlgorithms(this.mRecordStream.HandshakeHash, + this.mCertificateRequest.SupportedSignatureAlgorithms); + } + } + this.mConnectionState = CS_CERTIFICATE_REQUEST; + + SendServerHelloDoneMessage(); + this.mConnectionState = CS_SERVER_HELLO_DONE; + + this.mRecordStream.HandshakeHash.SealHashAlgorithms(); + + break; + } + case CS_END: + { + RefuseRenegotiation(); + break; + } + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + break; + } + case HandshakeType.supplemental_data: + { + switch (this.mConnectionState) + { + case CS_SERVER_HELLO_DONE: + { + mTlsServer.ProcessClientSupplementalData(ReadSupplementalDataMessage(buf)); + this.mConnectionState = CS_CLIENT_SUPPLEMENTAL_DATA; + break; + } + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + break; + } + case HandshakeType.certificate: + { + switch (this.mConnectionState) + { + case CS_SERVER_HELLO_DONE: + case CS_CLIENT_SUPPLEMENTAL_DATA: + { + if (mConnectionState < CS_CLIENT_SUPPLEMENTAL_DATA) + { + mTlsServer.ProcessClientSupplementalData(null); + } + + if (this.mCertificateRequest == null) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + + ReceiveCertificateMessage(buf); + this.mConnectionState = CS_CLIENT_CERTIFICATE; + break; + } + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + break; + } + case HandshakeType.client_key_exchange: + { + switch (this.mConnectionState) + { + case CS_SERVER_HELLO_DONE: + case CS_CLIENT_SUPPLEMENTAL_DATA: + case CS_CLIENT_CERTIFICATE: + { + if (mConnectionState < CS_CLIENT_SUPPLEMENTAL_DATA) + { + mTlsServer.ProcessClientSupplementalData(null); + } + + if (mConnectionState < CS_CLIENT_CERTIFICATE) + { + if (this.mCertificateRequest == null) + { + this.mKeyExchange.SkipClientCredentials(); + } + else + { + if (TlsUtilities.IsTlsV12(Context)) + { + /* + * RFC 5246 If no suitable certificate is available, the client MUST Send a + * certificate message containing no certificates. + * + * NOTE: In previous RFCs, this was SHOULD instead of MUST. + */ + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + else if (TlsUtilities.IsSsl(Context)) + { + if (this.mPeerCertificate == null) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + else + { + NotifyClientCertificate(Certificate.EmptyChain); + } + } + } + + ReceiveClientKeyExchangeMessage(buf); + this.mConnectionState = CS_CLIENT_KEY_EXCHANGE; + break; + } + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + break; + } + case HandshakeType.certificate_verify: + { + switch (this.mConnectionState) + { + case CS_CLIENT_KEY_EXCHANGE: + { + /* + * RFC 5246 7.4.8 This message is only sent following a client certificate that has + * signing capability (i.e., all certificates except those containing fixed + * Diffie-Hellman parameters). + */ + if (!ExpectCertificateVerifyMessage()) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + + ReceiveCertificateVerifyMessage(buf); + this.mConnectionState = CS_CERTIFICATE_VERIFY; + + break; + } + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + break; + } + case HandshakeType.finished: + { + switch (this.mConnectionState) + { + case CS_CLIENT_KEY_EXCHANGE: + case CS_CERTIFICATE_VERIFY: + { + if (mConnectionState < CS_CERTIFICATE_VERIFY && ExpectCertificateVerifyMessage()) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + + ProcessFinishedMessage(buf); + this.mConnectionState = CS_CLIENT_FINISHED; + + if (this.mExpectSessionTicket) + { + SendNewSessionTicketMessage(mTlsServer.GetNewSessionTicket()); + } + this.mConnectionState = CS_SERVER_SESSION_TICKET; + + SendChangeCipherSpecMessage(); + SendFinishedMessage(); + this.mConnectionState = CS_SERVER_FINISHED; + + CompleteHandshake(); + break; + } + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + break; + } + case HandshakeType.hello_request: + case HandshakeType.hello_verify_request: + case HandshakeType.server_hello: + case HandshakeType.server_key_exchange: + case HandshakeType.certificate_request: + case HandshakeType.server_hello_done: + case HandshakeType.session_ticket: + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + } + + protected override void HandleAlertWarningMessage(byte alertDescription) + { + /* + * SSL 3.0 If the server has sent a certificate request Message, the client must send + * either the certificate message or a no_certificate alert. + */ + if (AlertDescription.no_certificate == alertDescription && null != mCertificateRequest + && TlsUtilities.IsSsl(mTlsServerContext)) + { + switch (mConnectionState) + { + case CS_SERVER_HELLO_DONE: + case CS_CLIENT_SUPPLEMENTAL_DATA: + { + if (mConnectionState < CS_CLIENT_SUPPLEMENTAL_DATA) + { + mTlsServer.ProcessClientSupplementalData(null); + } + + NotifyClientCertificate(Certificate.EmptyChain); + this.mConnectionState = CS_CLIENT_CERTIFICATE; + return; + } + } + } + + base.HandleAlertWarningMessage(alertDescription); + } + + protected virtual void NotifyClientCertificate(Certificate clientCertificate) + { + if (mCertificateRequest == null) + throw new InvalidOperationException(); + if (mPeerCertificate != null) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + + this.mPeerCertificate = clientCertificate; + + if (clientCertificate.IsEmpty) + { + this.mKeyExchange.SkipClientCredentials(); + } + else + { + + /* + * TODO RFC 5246 7.4.6. If the certificate_authorities list in the certificate request + * message was non-empty, one of the certificates in the certificate chain SHOULD be + * issued by one of the listed CAs. + */ + + this.mClientCertificateType = TlsUtilities.GetClientCertificateType(clientCertificate, + this.mServerCredentials.Certificate); + + this.mKeyExchange.ProcessClientCertificate(clientCertificate); + } + + /* + * RFC 5246 7.4.6. If the client does not Send any certificates, the server MAY at its + * discretion either continue the handshake without client authentication, or respond with a + * fatal handshake_failure alert. Also, if some aspect of the certificate chain was + * unacceptable (e.g., it was not signed by a known, trusted CA), the server MAY at its + * discretion either continue the handshake (considering the client unauthenticated) or Send + * a fatal alert. + */ + this.mTlsServer.NotifyClientCertificate(clientCertificate); + } + + protected virtual void ReceiveCertificateMessage(MemoryStream buf) + { + Certificate clientCertificate = Certificate.Parse(buf); + + AssertEmpty(buf); + + NotifyClientCertificate(clientCertificate); + } + + protected virtual void ReceiveCertificateVerifyMessage(MemoryStream buf) + { + if (mCertificateRequest == null) + throw new InvalidOperationException(); + + DigitallySigned clientCertificateVerify = DigitallySigned.Parse(Context, buf); + + AssertEmpty(buf); + + // Verify the CertificateVerify message contains a correct signature. + try + { + SignatureAndHashAlgorithm signatureAlgorithm = clientCertificateVerify.Algorithm; + + byte[] hash; + if (TlsUtilities.IsTlsV12(Context)) + { + TlsUtilities.VerifySupportedSignatureAlgorithm(mCertificateRequest.SupportedSignatureAlgorithms, signatureAlgorithm); + hash = mPrepareFinishHash.GetFinalHash(signatureAlgorithm.Hash); + } + else + { + hash = mSecurityParameters.SessionHash; + } + + X509CertificateStructure x509Cert = mPeerCertificate.GetCertificateAt(0); + SubjectPublicKeyInfo keyInfo = x509Cert.SubjectPublicKeyInfo; + AsymmetricKeyParameter publicKey = PublicKeyFactory.CreateKey(keyInfo); + + TlsSigner tlsSigner = TlsUtilities.CreateTlsSigner((byte)mClientCertificateType); + tlsSigner.Init(Context); + if (!tlsSigner.VerifyRawSignature(signatureAlgorithm, clientCertificateVerify.Signature, publicKey, hash)) + throw new TlsFatalAlert(AlertDescription.decrypt_error); + } + catch (TlsFatalAlert e) + { + throw e; + } + catch (Exception e) + { + throw new TlsFatalAlert(AlertDescription.decrypt_error, e); + } + } + + protected virtual void ReceiveClientHelloMessage(MemoryStream buf) + { + ProtocolVersion client_version = TlsUtilities.ReadVersion(buf); + mRecordStream.SetWriteVersion(client_version); + + if (client_version.IsDtls) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + byte[] client_random = TlsUtilities.ReadFully(32, buf); + + /* + * TODO RFC 5077 3.4. If a ticket is presented by the client, the server MUST NOT attempt to + * use the Session ID in the ClientHello for stateful session resumption. + */ + byte[] sessionID = TlsUtilities.ReadOpaque8(buf); + if (sessionID.Length > 32) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + /* + * TODO RFC 5246 7.4.1.2. If the session_id field is not empty (implying a session + * resumption request), this vector MUST include at least the cipher_suite from that + * session. + */ + int cipher_suites_length = TlsUtilities.ReadUint16(buf); + if (cipher_suites_length < 2 || (cipher_suites_length & 1) != 0) + throw new TlsFatalAlert(AlertDescription.decode_error); + + this.mOfferedCipherSuites = TlsUtilities.ReadUint16Array(cipher_suites_length / 2, buf); + + /* + * TODO RFC 5246 7.4.1.2. If the session_id field is not empty (implying a session + * resumption request), it MUST include the compression_method from that session. + */ + int compression_methods_length = TlsUtilities.ReadUint8(buf); + if (compression_methods_length < 1) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + this.mOfferedCompressionMethods = TlsUtilities.ReadUint8Array(compression_methods_length, buf); + + /* + * TODO RFC 3546 2.3 If [...] the older session is resumed, then the server MUST ignore + * extensions appearing in the client hello, and Send a server hello containing no + * extensions. + */ + this.mClientExtensions = ReadExtensions(buf); + + /* + * TODO[resumption] Check RFC 7627 5.4. for required behaviour + */ + + /* + * RFC 7627 4. Clients and servers SHOULD NOT accept handshakes that do not use the extended + * master secret [..]. (and see 5.2, 5.3) + */ + this.mSecurityParameters.extendedMasterSecret = TlsExtensionsUtilities.HasExtendedMasterSecretExtension(mClientExtensions); + if (!mSecurityParameters.IsExtendedMasterSecret && mTlsServer.RequiresExtendedMasterSecret()) + { + throw new TlsFatalAlert(AlertDescription.handshake_failure); + } + + ContextAdmin.SetClientVersion(client_version); + + mTlsServer.NotifyClientVersion(client_version); + mTlsServer.NotifyFallback(Arrays.Contains(mOfferedCipherSuites, CipherSuite.TLS_FALLBACK_SCSV)); + + mSecurityParameters.clientRandom = client_random; + + mTlsServer.NotifyOfferedCipherSuites(mOfferedCipherSuites); + mTlsServer.NotifyOfferedCompressionMethods(mOfferedCompressionMethods); + + /* + * RFC 5746 3.6. Server Behavior: Initial Handshake + */ + { + /* + * RFC 5746 3.4. The client MUST include either an empty "renegotiation_info" extension, + * or the TLS_EMPTY_RENEGOTIATION_INFO_SCSV signaling cipher suite value in the + * ClientHello. Including both is NOT RECOMMENDED. + */ + + /* + * When a ClientHello is received, the server MUST check if it includes the + * TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV. If it does, set the secure_renegotiation flag + * to TRUE. + */ + if (Arrays.Contains(mOfferedCipherSuites, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV)) + { + this.mSecureRenegotiation = true; + } + + /* + * The server MUST check if the "renegotiation_info" extension is included in the + * ClientHello. + */ + byte[] renegExtData = TlsUtilities.GetExtensionData(mClientExtensions, ExtensionType.renegotiation_info); + if (renegExtData != null) + { + /* + * If the extension is present, set secure_renegotiation flag to TRUE. The + * server MUST then verify that the length of the "renegotiated_connection" + * field is zero, and if it is not, MUST abort the handshake. + */ + this.mSecureRenegotiation = true; + + if (!Arrays.ConstantTimeAreEqual(renegExtData, CreateRenegotiationInfo(TlsUtilities.EmptyBytes))) + throw new TlsFatalAlert(AlertDescription.handshake_failure); + } + } + + mTlsServer.NotifySecureRenegotiation(this.mSecureRenegotiation); + + if (mClientExtensions != null) + { + // NOTE: Validates the padding extension data, if present + TlsExtensionsUtilities.GetPaddingExtension(mClientExtensions); + + mTlsServer.ProcessClientExtensions(mClientExtensions); + } + } + + protected virtual void ReceiveClientKeyExchangeMessage(MemoryStream buf) + { + mKeyExchange.ProcessClientKeyExchange(buf); + + AssertEmpty(buf); + + if (TlsUtilities.IsSsl(Context)) + { + EstablishMasterSecret(Context, mKeyExchange); + } + + this.mPrepareFinishHash = mRecordStream.PrepareToFinish(); + this.mSecurityParameters.sessionHash = GetCurrentPrfHash(Context, mPrepareFinishHash, null); + + if (!TlsUtilities.IsSsl(Context)) + { + EstablishMasterSecret(Context, mKeyExchange); + } + + mRecordStream.SetPendingConnectionState(Peer.GetCompression(), Peer.GetCipher()); + } + + protected virtual void SendCertificateRequestMessage(CertificateRequest certificateRequest) + { + HandshakeMessage message = new HandshakeMessage(HandshakeType.certificate_request); + + certificateRequest.Encode(message); + + message.WriteToRecordStream(this); + } + + protected virtual void SendCertificateStatusMessage(CertificateStatus certificateStatus) + { + HandshakeMessage message = new HandshakeMessage(HandshakeType.certificate_status); + + certificateStatus.Encode(message); + + message.WriteToRecordStream(this); + } + + protected virtual void SendNewSessionTicketMessage(NewSessionTicket newSessionTicket) + { + if (newSessionTicket == null) + throw new TlsFatalAlert(AlertDescription.internal_error); + + HandshakeMessage message = new HandshakeMessage(HandshakeType.session_ticket); + + newSessionTicket.Encode(message); + + message.WriteToRecordStream(this); + } + + protected virtual void SendServerHelloMessage() + { + HandshakeMessage message = new HandshakeMessage(HandshakeType.server_hello); + + { + ProtocolVersion server_version = mTlsServer.GetServerVersion(); + if (!server_version.IsEqualOrEarlierVersionOf(Context.ClientVersion)) + throw new TlsFatalAlert(AlertDescription.internal_error); + + mRecordStream.ReadVersion = server_version; + mRecordStream.SetWriteVersion(server_version); + mRecordStream.SetRestrictReadVersion(true); + ContextAdmin.SetServerVersion(server_version); + + TlsUtilities.WriteVersion(server_version, message); + } + + message.Write(this.mSecurityParameters.serverRandom); + + /* + * The server may return an empty session_id to indicate that the session will not be cached + * and therefore cannot be resumed. + */ + TlsUtilities.WriteOpaque8(TlsUtilities.EmptyBytes, message); + + int selectedCipherSuite = mTlsServer.GetSelectedCipherSuite(); + if (!Arrays.Contains(mOfferedCipherSuites, selectedCipherSuite) + || selectedCipherSuite == CipherSuite.TLS_NULL_WITH_NULL_NULL + || CipherSuite.IsScsv(selectedCipherSuite) + || !TlsUtilities.IsValidCipherSuiteForVersion(selectedCipherSuite, Context.ServerVersion)) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + mSecurityParameters.cipherSuite = selectedCipherSuite; + + byte selectedCompressionMethod = mTlsServer.GetSelectedCompressionMethod(); + if (!Arrays.Contains(mOfferedCompressionMethods, selectedCompressionMethod)) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + mSecurityParameters.compressionAlgorithm = selectedCompressionMethod; + + TlsUtilities.WriteUint16(selectedCipherSuite, message); + TlsUtilities.WriteUint8(selectedCompressionMethod, message); + + this.mServerExtensions = TlsExtensionsUtilities.EnsureExtensionsInitialised(mTlsServer.GetServerExtensions()); + + /* + * RFC 5746 3.6. Server Behavior: Initial Handshake + */ + if (this.mSecureRenegotiation) + { + byte[] renegExtData = TlsUtilities.GetExtensionData(this.mServerExtensions, ExtensionType.renegotiation_info); + bool noRenegExt = (null == renegExtData); + + if (noRenegExt) + { + /* + * Note that Sending a "renegotiation_info" extension in response to a ClientHello + * containing only the SCSV is an explicit exception to the prohibition in RFC 5246, + * Section 7.4.1.4, on the server Sending unsolicited extensions and is only allowed + * because the client is signaling its willingness to receive the extension via the + * TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV. + */ + + /* + * If the secure_renegotiation flag is set to TRUE, the server MUST include an empty + * "renegotiation_info" extension in the ServerHello message. + */ + this.mServerExtensions[ExtensionType.renegotiation_info] = CreateRenegotiationInfo(TlsUtilities.EmptyBytes); + } + } + + if (TlsUtilities.IsSsl(mTlsServerContext)) + { + mSecurityParameters.extendedMasterSecret = false; + } + else if (mSecurityParameters.IsExtendedMasterSecret) + { + TlsExtensionsUtilities.AddExtendedMasterSecretExtension(mServerExtensions); + } + + /* + * TODO RFC 3546 2.3 If [...] the older session is resumed, then the server MUST ignore + * extensions appearing in the client hello, and Send a server hello containing no + * extensions. + */ + + if (this.mServerExtensions.Count > 0) + { + this.mSecurityParameters.encryptThenMac = TlsExtensionsUtilities.HasEncryptThenMacExtension(mServerExtensions); + + this.mSecurityParameters.maxFragmentLength = ProcessMaxFragmentLengthExtension(mClientExtensions, + mServerExtensions, AlertDescription.internal_error); + + this.mSecurityParameters.truncatedHMac = TlsExtensionsUtilities.HasTruncatedHMacExtension(mServerExtensions); + + /* + * TODO It's surprising that there's no provision to allow a 'fresh' CertificateStatus to be sent in + * a session resumption handshake. + */ + this.mAllowCertificateStatus = !mResumedSession + && TlsUtilities.HasExpectedEmptyExtensionData(mServerExtensions, ExtensionType.status_request, + AlertDescription.internal_error); + + this.mExpectSessionTicket = !mResumedSession + && TlsUtilities.HasExpectedEmptyExtensionData(mServerExtensions, ExtensionType.session_ticket, + AlertDescription.internal_error); + + WriteExtensions(message, this.mServerExtensions); + } + + mSecurityParameters.prfAlgorithm = GetPrfAlgorithm(Context, mSecurityParameters.CipherSuite); + + /* + * RFC 5246 7.4.9. Any cipher suite which does not explicitly specify verify_data_length has + * a verify_data_length equal to 12. This includes all existing cipher suites. + */ + mSecurityParameters.verifyDataLength = 12; + + ApplyMaxFragmentLengthExtension(); + + message.WriteToRecordStream(this); + } + + protected virtual void SendServerHelloDoneMessage() + { + byte[] message = new byte[4]; + TlsUtilities.WriteUint8(HandshakeType.server_hello_done, message, 0); + TlsUtilities.WriteUint24(0, message, 1); + + WriteHandshakeMessage(message, 0, message.Length); + } + + protected virtual void SendServerKeyExchangeMessage(byte[] serverKeyExchange) + { + HandshakeMessage message = new HandshakeMessage(HandshakeType.server_key_exchange, serverKeyExchange.Length); + + message.Write(serverKeyExchange); + + message.WriteToRecordStream(this); + } + + protected virtual bool ExpectCertificateVerifyMessage() + { + return mClientCertificateType >= 0 && TlsUtilities.HasSigningCapability((byte)mClientCertificateType); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsServerProtocol.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsServerProtocol.cs.meta new file mode 100644 index 0000000..cd2bad3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsServerProtocol.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 337eb3ddaf20665439f0b10b24aa895f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSession.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSession.cs new file mode 100644 index 0000000..6c22991 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSession.cs @@ -0,0 +1,15 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public interface TlsSession + { + SessionParameters ExportSessionParameters(); + + byte[] SessionID { get; } + + void Invalidate(); + + bool IsResumable { get; } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSession.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSession.cs.meta new file mode 100644 index 0000000..9cff4d6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSession.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8dec26c84737c1742be6ee323de876dd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSessionImpl.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSessionImpl.cs new file mode 100644 index 0000000..4f0ff81 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSessionImpl.cs @@ -0,0 +1,51 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + internal class TlsSessionImpl + : TlsSession + { + internal readonly byte[] mSessionID; + internal readonly SessionParameters mSessionParameters; + internal bool mResumable; + + internal TlsSessionImpl(byte[] sessionID, SessionParameters sessionParameters) + { + if (sessionID == null) + throw new ArgumentNullException("sessionID"); + if (sessionID.Length > 32) + throw new ArgumentException("cannot be longer than 32 bytes", "sessionID"); + + this.mSessionID = Arrays.Clone(sessionID); + this.mSessionParameters = sessionParameters; + this.mResumable = sessionID.Length > 0 + && null != sessionParameters + && sessionParameters.IsExtendedMasterSecret; + } + + public virtual SessionParameters ExportSessionParameters() + { + lock (this) + { + return this.mSessionParameters == null ? null : this.mSessionParameters.Copy(); + } + } + + public virtual byte[] SessionID + { + get { lock (this) return mSessionID; } + } + + public virtual void Invalidate() + { + lock (this) this.mResumable = false; + } + + public virtual bool IsResumable + { + get { lock (this) return mResumable; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSessionImpl.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSessionImpl.cs.meta new file mode 100644 index 0000000..737fc36 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSessionImpl.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e65332e35e4f27249a487549be2485a5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSigner.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSigner.cs new file mode 100644 index 0000000..ffdd4c9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSigner.cs @@ -0,0 +1,29 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public interface TlsSigner + { + void Init(TlsContext context); + + byte[] GenerateRawSignature(AsymmetricKeyParameter privateKey, byte[] md5AndSha1); + + byte[] GenerateRawSignature(SignatureAndHashAlgorithm algorithm, + AsymmetricKeyParameter privateKey, byte[] hash); + + bool VerifyRawSignature(byte[] sigBytes, AsymmetricKeyParameter publicKey, byte[] md5AndSha1); + + bool VerifyRawSignature(SignatureAndHashAlgorithm algorithm, byte[] sigBytes, + AsymmetricKeyParameter publicKey, byte[] hash); + + ISigner CreateSigner(AsymmetricKeyParameter privateKey); + + ISigner CreateSigner(SignatureAndHashAlgorithm algorithm, AsymmetricKeyParameter privateKey); + + ISigner CreateVerifyer(AsymmetricKeyParameter publicKey); + + ISigner CreateVerifyer(SignatureAndHashAlgorithm algorithm, AsymmetricKeyParameter publicKey); + + bool IsValidPublicKey(AsymmetricKeyParameter publicKey); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSigner.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSigner.cs.meta new file mode 100644 index 0000000..0157962 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSigner.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a224593f45b85a04f930c164d9337290 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSignerCredentials.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSignerCredentials.cs new file mode 100644 index 0000000..92ed7cc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSignerCredentials.cs @@ -0,0 +1,14 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public interface TlsSignerCredentials + : TlsCredentials + { + /// + byte[] GenerateCertificateSignature(byte[] hash); + + SignatureAndHashAlgorithm SignatureAndHashAlgorithm { get; } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSignerCredentials.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSignerCredentials.cs.meta new file mode 100644 index 0000000..c835e5e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSignerCredentials.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fb735873318193644aac1ad6eea3feb1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSrpGroupVerifier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSrpGroupVerifier.cs new file mode 100644 index 0000000..185f2f5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSrpGroupVerifier.cs @@ -0,0 +1,17 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public interface TlsSrpGroupVerifier + { + /** + * Check whether the given SRP group parameters are acceptable for use. + * + * @param group the {@link SRP6GroupParameters} to check + * @return true if (and only if) the specified group parameters are acceptable + */ + bool Accept(Srp6GroupParameters group); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSrpGroupVerifier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSrpGroupVerifier.cs.meta new file mode 100644 index 0000000..0e6f80f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSrpGroupVerifier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 877bfa1b0bc95374bbcd1d55131795b3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSrpIdentityManager.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSrpIdentityManager.cs new file mode 100644 index 0000000..080a0dc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSrpIdentityManager.cs @@ -0,0 +1,21 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public interface TlsSrpIdentityManager + { + /** + * Lookup the {@link TlsSRPLoginParameters} corresponding to the specified identity. + * + * NOTE: To avoid "identity probing", unknown identities SHOULD be handled as recommended in RFC + * 5054 2.5.1.3. {@link SimulatedTlsSRPIdentityManager} is provided for this purpose. + * + * @param identity + * the SRP identity sent by the connecting client + * @return the {@link TlsSRPLoginParameters} for the specified identity, or else 'simulated' + * parameters if the identity is not recognized. A null value is also allowed, but not + * recommended. + */ + TlsSrpLoginParameters GetLoginParameters(byte[] identity); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSrpIdentityManager.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSrpIdentityManager.cs.meta new file mode 100644 index 0000000..b01f2f5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSrpIdentityManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1368ae7aa7ee33a41a82614f88a49054 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSrpKeyExchange.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSrpKeyExchange.cs new file mode 100644 index 0000000..691c881 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSrpKeyExchange.cs @@ -0,0 +1,285 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto.Agreement.Srp; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// (D)TLS SRP key exchange (RFC 5054). + public class TlsSrpKeyExchange + : AbstractTlsKeyExchange + { + protected static TlsSigner CreateSigner(int keyExchange) + { + switch (keyExchange) + { + case KeyExchangeAlgorithm.SRP: + return null; + case KeyExchangeAlgorithm.SRP_RSA: + return new TlsRsaSigner(); + case KeyExchangeAlgorithm.SRP_DSS: + return new TlsDssSigner(); + default: + throw new ArgumentException("unsupported key exchange algorithm"); + } + } + + protected TlsSigner mTlsSigner; + protected TlsSrpGroupVerifier mGroupVerifier; + protected byte[] mIdentity; + protected byte[] mPassword; + + protected AsymmetricKeyParameter mServerPublicKey = null; + + protected Srp6GroupParameters mSrpGroup = null; + protected Srp6Client mSrpClient = null; + protected Srp6Server mSrpServer = null; + protected BigInteger mSrpPeerCredentials = null; + protected BigInteger mSrpVerifier = null; + protected byte[] mSrpSalt = null; + + protected TlsSignerCredentials mServerCredentials = null; + + [Obsolete("Use constructor taking an explicit 'groupVerifier' argument")] + public TlsSrpKeyExchange(int keyExchange, IList supportedSignatureAlgorithms, byte[] identity, byte[] password) + : this(keyExchange, supportedSignatureAlgorithms, new DefaultTlsSrpGroupVerifier(), identity, password) + { + } + + public TlsSrpKeyExchange(int keyExchange, IList supportedSignatureAlgorithms, TlsSrpGroupVerifier groupVerifier, + byte[] identity, byte[] password) + : base(keyExchange, supportedSignatureAlgorithms) + { + this.mTlsSigner = CreateSigner(keyExchange); + this.mGroupVerifier = groupVerifier; + this.mIdentity = identity; + this.mPassword = password; + this.mSrpClient = new Srp6Client(); + } + + public TlsSrpKeyExchange(int keyExchange, IList supportedSignatureAlgorithms, byte[] identity, + TlsSrpLoginParameters loginParameters) + : base(keyExchange, supportedSignatureAlgorithms) + { + this.mTlsSigner = CreateSigner(keyExchange); + this.mIdentity = identity; + this.mSrpServer = new Srp6Server(); + this.mSrpGroup = loginParameters.Group; + this.mSrpVerifier = loginParameters.Verifier; + this.mSrpSalt = loginParameters.Salt; + } + + public override void Init(TlsContext context) + { + base.Init(context); + + if (this.mTlsSigner != null) + { + this.mTlsSigner.Init(context); + } + } + + public override void SkipServerCredentials() + { + if (mTlsSigner != null) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + public override void ProcessServerCertificate(Certificate serverCertificate) + { + if (mTlsSigner == null) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + if (serverCertificate.IsEmpty) + throw new TlsFatalAlert(AlertDescription.decode_error); + + X509CertificateStructure x509Cert = serverCertificate.GetCertificateAt(0); + + SubjectPublicKeyInfo keyInfo = x509Cert.SubjectPublicKeyInfo; + try + { + this.mServerPublicKey = PublicKeyFactory.CreateKey(keyInfo); + } + catch (Exception e) + { + throw new TlsFatalAlert(AlertDescription.unsupported_certificate, e); + } + + if (!mTlsSigner.IsValidPublicKey(this.mServerPublicKey)) + throw new TlsFatalAlert(AlertDescription.certificate_unknown); + + TlsUtilities.ValidateKeyUsage(x509Cert, KeyUsage.DigitalSignature); + + base.ProcessServerCertificate(serverCertificate); + } + + public override void ProcessServerCredentials(TlsCredentials serverCredentials) + { + if ((mKeyExchange == KeyExchangeAlgorithm.SRP) || !(serverCredentials is TlsSignerCredentials)) + throw new TlsFatalAlert(AlertDescription.internal_error); + + ProcessServerCertificate(serverCredentials.Certificate); + + this.mServerCredentials = (TlsSignerCredentials)serverCredentials; + } + + public override bool RequiresServerKeyExchange + { + get { return true; } + } + + public override byte[] GenerateServerKeyExchange() + { + mSrpServer.Init(mSrpGroup, mSrpVerifier, TlsUtilities.CreateHash(HashAlgorithm.sha1), mContext.SecureRandom); + BigInteger B = mSrpServer.GenerateServerCredentials(); + + ServerSrpParams srpParams = new ServerSrpParams(mSrpGroup.N, mSrpGroup.G, mSrpSalt, B); + + DigestInputBuffer buf = new DigestInputBuffer(); + + srpParams.Encode(buf); + + if (mServerCredentials != null) + { + /* + * RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm from TLS 1.2 + */ + SignatureAndHashAlgorithm signatureAndHashAlgorithm = TlsUtilities.GetSignatureAndHashAlgorithm( + mContext, mServerCredentials); + + IDigest d = TlsUtilities.CreateHash(signatureAndHashAlgorithm); + + SecurityParameters securityParameters = mContext.SecurityParameters; + d.BlockUpdate(securityParameters.clientRandom, 0, securityParameters.clientRandom.Length); + d.BlockUpdate(securityParameters.serverRandom, 0, securityParameters.serverRandom.Length); + buf.UpdateDigest(d); + + byte[] hash = new byte[d.GetDigestSize()]; + d.DoFinal(hash, 0); + + byte[] signature = mServerCredentials.GenerateCertificateSignature(hash); + + DigitallySigned signed_params = new DigitallySigned(signatureAndHashAlgorithm, signature); + signed_params.Encode(buf); + } + + return buf.ToArray(); + } + + public override void ProcessServerKeyExchange(Stream input) + { + SecurityParameters securityParameters = mContext.SecurityParameters; + + SignerInputBuffer buf = null; + Stream teeIn = input; + + if (mTlsSigner != null) + { + buf = new SignerInputBuffer(); + teeIn = new TeeInputStream(input, buf); + } + + ServerSrpParams srpParams = ServerSrpParams.Parse(teeIn); + + if (buf != null) + { + DigitallySigned signed_params = ParseSignature(input); + + ISigner signer = InitVerifyer(mTlsSigner, signed_params.Algorithm, securityParameters); + buf.UpdateSigner(signer); + if (!signer.VerifySignature(signed_params.Signature)) + throw new TlsFatalAlert(AlertDescription.decrypt_error); + } + + this.mSrpGroup = new Srp6GroupParameters(srpParams.N, srpParams.G); + + if (!mGroupVerifier.Accept(mSrpGroup)) + throw new TlsFatalAlert(AlertDescription.insufficient_security); + + this.mSrpSalt = srpParams.S; + + /* + * RFC 5054 2.5.3: The client MUST abort the handshake with an "illegal_parameter" alert if + * B % N = 0. + */ + try + { + this.mSrpPeerCredentials = Srp6Utilities.ValidatePublicValue(mSrpGroup.N, srpParams.B); + } + catch (CryptoException e) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter, e); + } + + this.mSrpClient.Init(mSrpGroup, TlsUtilities.CreateHash(HashAlgorithm.sha1), mContext.SecureRandom); + } + + public override void ValidateCertificateRequest(CertificateRequest certificateRequest) + { + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + public override void ProcessClientCredentials(TlsCredentials clientCredentials) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public override void GenerateClientKeyExchange(Stream output) + { + BigInteger A = mSrpClient.GenerateClientCredentials(mSrpSalt, mIdentity, mPassword); + TlsSrpUtilities.WriteSrpParameter(A, output); + + mContext.SecurityParameters.srpIdentity = Arrays.Clone(mIdentity); + } + + public override void ProcessClientKeyExchange(Stream input) + { + /* + * RFC 5054 2.5.4: The server MUST abort the handshake with an "illegal_parameter" alert if + * A % N = 0. + */ + try + { + this.mSrpPeerCredentials = Srp6Utilities.ValidatePublicValue(mSrpGroup.N, TlsSrpUtilities.ReadSrpParameter(input)); + } + catch (CryptoException e) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter, e); + } + + mContext.SecurityParameters.srpIdentity = Arrays.Clone(mIdentity); + } + + public override byte[] GeneratePremasterSecret() + { + try + { + BigInteger S = mSrpServer != null + ? mSrpServer.CalculateSecret(mSrpPeerCredentials) + : mSrpClient.CalculateSecret(mSrpPeerCredentials); + + // TODO Check if this needs to be a fixed size + return BigIntegers.AsUnsignedByteArray(S); + } + catch (CryptoException e) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter, e); + } + } + + protected virtual ISigner InitVerifyer(TlsSigner tlsSigner, SignatureAndHashAlgorithm algorithm, + SecurityParameters securityParameters) + { + ISigner signer = tlsSigner.CreateVerifyer(algorithm, this.mServerPublicKey); + signer.BlockUpdate(securityParameters.clientRandom, 0, securityParameters.clientRandom.Length); + signer.BlockUpdate(securityParameters.serverRandom, 0, securityParameters.serverRandom.Length); + return signer; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSrpKeyExchange.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSrpKeyExchange.cs.meta new file mode 100644 index 0000000..dcc2bd9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSrpKeyExchange.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9b29930e438a3fd418ddfbcf18baab11 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSrpLoginParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSrpLoginParameters.cs new file mode 100644 index 0000000..5ae4641 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSrpLoginParameters.cs @@ -0,0 +1,36 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class TlsSrpLoginParameters + { + protected readonly Srp6GroupParameters mGroup; + protected readonly BigInteger mVerifier; + protected readonly byte[] mSalt; + + public TlsSrpLoginParameters(Srp6GroupParameters group, BigInteger verifier, byte[] salt) + { + this.mGroup = group; + this.mVerifier = verifier; + this.mSalt = salt; + } + + public virtual Srp6GroupParameters Group + { + get { return mGroup; } + } + + public virtual byte[] Salt + { + get { return mSalt; } + } + + public virtual BigInteger Verifier + { + get { return mVerifier; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSrpLoginParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSrpLoginParameters.cs.meta new file mode 100644 index 0000000..e01f7de --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSrpLoginParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 54f79d4c77f1bc443b4b6a56af0f1f19 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSrpUtilities.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSrpUtilities.cs new file mode 100644 index 0000000..873189d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSrpUtilities.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class TlsSrpUtilities + { + public static void AddSrpExtension(IDictionary extensions, byte[] identity) + { + extensions[ExtensionType.srp] = CreateSrpExtension(identity); + } + + public static byte[] GetSrpExtension(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.srp); + return extensionData == null ? null : ReadSrpExtension(extensionData); + } + + public static byte[] CreateSrpExtension(byte[] identity) + { + if (identity == null) + throw new TlsFatalAlert(AlertDescription.internal_error); + + return TlsUtilities.EncodeOpaque8(identity); + } + + public static byte[] ReadSrpExtension(byte[] extensionData) + { + if (extensionData == null) + throw new ArgumentNullException("extensionData"); + + MemoryStream buf = new MemoryStream(extensionData, false); + byte[] identity = TlsUtilities.ReadOpaque8(buf); + + TlsProtocol.AssertEmpty(buf); + + return identity; + } + + public static BigInteger ReadSrpParameter(Stream input) + { + return new BigInteger(1, TlsUtilities.ReadOpaque16(input)); + } + + public static void WriteSrpParameter(BigInteger x, Stream output) + { + TlsUtilities.WriteOpaque16(BigIntegers.AsUnsignedByteArray(x), output); + } + + public static bool IsSrpCipherSuite(int cipherSuite) + { + switch (cipherSuite) + { + case CipherSuite.TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_WITH_AES_256_CBC_SHA: + return true; + + default: + return false; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSrpUtilities.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSrpUtilities.cs.meta new file mode 100644 index 0000000..d531d81 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSrpUtilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 88a00c9d96dbca040b5e1ffbad170126 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSrtpUtilities.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSrtpUtilities.cs new file mode 100644 index 0000000..626c0e3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSrtpUtilities.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /** + * RFC 5764 DTLS Extension to Establish Keys for SRTP. + */ + public abstract class TlsSRTPUtils + { + public static void AddUseSrtpExtension(IDictionary extensions, UseSrtpData useSRTPData) + { + extensions[ExtensionType.use_srtp] = CreateUseSrtpExtension(useSRTPData); + } + + public static UseSrtpData GetUseSrtpExtension(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.use_srtp); + return extensionData == null ? null : ReadUseSrtpExtension(extensionData); + } + + public static byte[] CreateUseSrtpExtension(UseSrtpData useSrtpData) + { + if (useSrtpData == null) + throw new ArgumentNullException("useSrtpData"); + + MemoryStream buf = new MemoryStream(); + + // SRTPProtectionProfiles + TlsUtilities.WriteUint16ArrayWithUint16Length(useSrtpData.ProtectionProfiles, buf); + + // srtp_mki + TlsUtilities.WriteOpaque8(useSrtpData.Mki, buf); + + return buf.ToArray(); + } + + public static UseSrtpData ReadUseSrtpExtension(byte[] extensionData) + { + if (extensionData == null) + throw new ArgumentNullException("extensionData"); + + MemoryStream buf = new MemoryStream(extensionData, true); + + // SRTPProtectionProfiles + int length = TlsUtilities.ReadUint16(buf); + if (length < 2 || (length & 1) != 0) + { + throw new TlsFatalAlert(AlertDescription.decode_error); + } + int[] protectionProfiles = TlsUtilities.ReadUint16Array(length / 2, buf); + + // srtp_mki + byte[] mki = TlsUtilities.ReadOpaque8(buf); + + TlsProtocol.AssertEmpty(buf); + + return new UseSrtpData(protectionProfiles, mki); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSrtpUtilities.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSrtpUtilities.cs.meta new file mode 100644 index 0000000..63dfefa --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsSrtpUtilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: df5a039064857ec468c6e5f76558e173 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsStream.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsStream.cs new file mode 100644 index 0000000..bfd80ed --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsStream.cs @@ -0,0 +1,97 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + internal class TlsStream + : Stream + { + private readonly TlsProtocol handler; + + internal TlsStream(TlsProtocol handler) + { + this.handler = handler; + } + + public override bool CanRead + { + get { return !handler.IsClosed; } + } + + public override bool CanSeek + { + get { return false; } + } + + public override bool CanWrite + { + get { return !handler.IsClosed; } + } + +#if PORTABLE + protected override void Dispose(bool disposing) + { + if (disposing) + { + handler.Close(); + } + base.Dispose(disposing); + } +#else + public override void Close() + { + handler.Close(); + base.Close(); + } +#endif + + public override void Flush() + { + handler.Flush(); + } + + public override long Length + { + get { throw new NotSupportedException(); } + } + + public override long Position + { + get { throw new NotSupportedException(); } + set { throw new NotSupportedException(); } + } + + public override int Read(byte[] buf, int off, int len) + { + return this.handler.ReadApplicationData(buf, off, len); + } + + public override int ReadByte() + { + byte[] buf = new byte[1]; + if (this.Read(buf, 0, 1) <= 0) + return -1; + return buf[0]; + } + + public override long Seek(long offset, SeekOrigin origin) + { + throw new NotSupportedException(); + } + + public override void SetLength(long value) + { + throw new NotSupportedException(); + } + + public override void Write(byte[] buf, int off, int len) + { + this.handler.WriteData(buf, off, len); + } + + public override void WriteByte(byte b) + { + this.handler.WriteData(new byte[] { b }, 0, 1); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsStream.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsStream.cs.meta new file mode 100644 index 0000000..cd4228e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ce50e00c90a348840ae050c6defc4f5c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsStreamCipher.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsStreamCipher.cs new file mode 100644 index 0000000..555442e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsStreamCipher.cs @@ -0,0 +1,152 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Tls; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class TlsStreamCipher + : TlsCipher + { + protected readonly TlsContext context; + + protected readonly IStreamCipher encryptCipher; + protected readonly IStreamCipher decryptCipher; + + protected readonly TlsMac writeMac; + protected readonly TlsMac readMac; + + protected readonly bool usesNonce; + + /// + public TlsStreamCipher(TlsContext context, IStreamCipher clientWriteCipher, + IStreamCipher serverWriteCipher, IDigest clientWriteDigest, IDigest serverWriteDigest, + int cipherKeySize, bool usesNonce) + { + bool isServer = context.IsServer; + + this.context = context; + this.usesNonce = usesNonce; + + this.encryptCipher = clientWriteCipher; + this.decryptCipher = serverWriteCipher; + + int key_block_size = (2 * cipherKeySize) + clientWriteDigest.GetDigestSize() + + serverWriteDigest.GetDigestSize(); + + byte[] key_block = TlsUtilities.CalculateKeyBlock(context, key_block_size); + + int offset = 0; + + // Init MACs + TlsMac clientWriteMac = new TlsMac(context, clientWriteDigest, key_block, offset, + clientWriteDigest.GetDigestSize()); + offset += clientWriteDigest.GetDigestSize(); + TlsMac serverWriteMac = new TlsMac(context, serverWriteDigest, key_block, offset, + serverWriteDigest.GetDigestSize()); + offset += serverWriteDigest.GetDigestSize(); + + // Build keys + KeyParameter clientWriteKey = new KeyParameter(key_block, offset, cipherKeySize); + offset += cipherKeySize; + KeyParameter serverWriteKey = new KeyParameter(key_block, offset, cipherKeySize); + offset += cipherKeySize; + + if (offset != key_block_size) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + ICipherParameters encryptParams, decryptParams; + if (isServer) + { + this.writeMac = serverWriteMac; + this.readMac = clientWriteMac; + this.encryptCipher = serverWriteCipher; + this.decryptCipher = clientWriteCipher; + encryptParams = serverWriteKey; + decryptParams = clientWriteKey; + } + else + { + this.writeMac = clientWriteMac; + this.readMac = serverWriteMac; + this.encryptCipher = clientWriteCipher; + this.decryptCipher = serverWriteCipher; + encryptParams = clientWriteKey; + decryptParams = serverWriteKey; + } + + if (usesNonce) + { + byte[] dummyNonce = new byte[8]; + encryptParams = new ParametersWithIV(encryptParams, dummyNonce); + decryptParams = new ParametersWithIV(decryptParams, dummyNonce); + } + + this.encryptCipher.Init(true, encryptParams); + this.decryptCipher.Init(false, decryptParams); + } + + public virtual int GetPlaintextLimit(int ciphertextLimit) + { + return ciphertextLimit - writeMac.Size; + } + + public virtual byte[] EncodePlaintext(long seqNo, byte type, byte[] plaintext, int offset, int len) + { + if (usesNonce) + { + UpdateIV(encryptCipher, true, seqNo); + } + + byte[] outBuf = new byte[len + writeMac.Size]; + + encryptCipher.ProcessBytes(plaintext, offset, len, outBuf, 0); + + byte[] mac = writeMac.CalculateMac(seqNo, type, plaintext, offset, len); + encryptCipher.ProcessBytes(mac, 0, mac.Length, outBuf, len); + + return outBuf; + } + + /// + public virtual byte[] DecodeCiphertext(long seqNo, byte type, byte[] ciphertext, int offset, int len) + { + if (usesNonce) + { + UpdateIV(decryptCipher, false, seqNo); + } + + int macSize = readMac.Size; + if (len < macSize) + throw new TlsFatalAlert(AlertDescription.decode_error); + + int plaintextLength = len - macSize; + + byte[] deciphered = new byte[len]; + decryptCipher.ProcessBytes(ciphertext, offset, len, deciphered, 0); + CheckMac(seqNo, type, deciphered, plaintextLength, len, deciphered, 0, plaintextLength); + return Arrays.CopyOfRange(deciphered, 0, plaintextLength); + } + + /// + protected virtual void CheckMac(long seqNo, byte type, byte[] recBuf, int recStart, int recEnd, byte[] calcBuf, int calcOff, int calcLen) + { + byte[] receivedMac = Arrays.CopyOfRange(recBuf, recStart, recEnd); + byte[] computedMac = readMac.CalculateMac(seqNo, type, calcBuf, calcOff, calcLen); + + if (!Arrays.ConstantTimeAreEqual(receivedMac, computedMac)) + throw new TlsFatalAlert(AlertDescription.bad_record_mac); + } + + protected virtual void UpdateIV(IStreamCipher cipher, bool forEncryption, long seqNo) + { + byte[] nonce = new byte[8]; + TlsUtilities.WriteUint64(seqNo, nonce, 0); + cipher.Init(forEncryption, new ParametersWithIV(null, nonce)); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsStreamCipher.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsStreamCipher.cs.meta new file mode 100644 index 0000000..6a184f9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsStreamCipher.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cb6df11736e20e543be1452a813bdf5e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsTimeoutException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsTimeoutException.cs new file mode 100644 index 0000000..71931e4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsTimeoutException.cs @@ -0,0 +1,23 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public class TlsTimeoutException + : TlsException + { + public TlsTimeoutException() + : base() + { + } + + public TlsTimeoutException(string message) + : base(message) + { + } + + public TlsTimeoutException(string message, Exception cause) + : base(message, cause) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsTimeoutException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsTimeoutException.cs.meta new file mode 100644 index 0000000..ad06df2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsTimeoutException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e61161f1b4062dd4a9f8ee4c1d44e28d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsUtilities.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsUtilities.cs new file mode 100644 index 0000000..2fb631e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsUtilities.cs @@ -0,0 +1,2362 @@ +using System; +using System.Collections; +#if !PORTABLE || DOTNET +using System.Net.Sockets; +#endif +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Macs; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Date; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// Some helper functions for MicroTLS. + public abstract class TlsUtilities + { + public static readonly byte[] EmptyBytes = new byte[0]; + public static readonly short[] EmptyShorts = new short[0]; + public static readonly int[] EmptyInts = new int[0]; + public static readonly long[] EmptyLongs = new long[0]; + + public static void CheckUint8(int i) + { + if (!IsValidUint8(i)) + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public static void CheckUint8(long i) + { + if (!IsValidUint8(i)) + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public static void CheckUint16(int i) + { + if (!IsValidUint16(i)) + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public static void CheckUint16(long i) + { + if (!IsValidUint16(i)) + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public static void CheckUint24(int i) + { + if (!IsValidUint24(i)) + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public static void CheckUint24(long i) + { + if (!IsValidUint24(i)) + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public static void CheckUint32(long i) + { + if (!IsValidUint32(i)) + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public static void CheckUint48(long i) + { + if (!IsValidUint48(i)) + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public static void CheckUint64(long i) + { + if (!IsValidUint64(i)) + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public static bool IsValidUint8(int i) + { + return (i & 0xFF) == i; + } + + public static bool IsValidUint8(long i) + { + return (i & 0xFFL) == i; + } + + public static bool IsValidUint16(int i) + { + return (i & 0xFFFF) == i; + } + + public static bool IsValidUint16(long i) + { + return (i & 0xFFFFL) == i; + } + + public static bool IsValidUint24(int i) + { + return (i & 0xFFFFFF) == i; + } + + public static bool IsValidUint24(long i) + { + return (i & 0xFFFFFFL) == i; + } + + public static bool IsValidUint32(long i) + { + return (i & 0xFFFFFFFFL) == i; + } + + public static bool IsValidUint48(long i) + { + return (i & 0xFFFFFFFFFFFFL) == i; + } + + public static bool IsValidUint64(long i) + { + return true; + } + + public static bool IsSsl(TlsContext context) + { + return context.ServerVersion.IsSsl; + } + + public static bool IsTlsV11(ProtocolVersion version) + { + return ProtocolVersion.TLSv11.IsEqualOrEarlierVersionOf(version.GetEquivalentTLSVersion()); + } + + public static bool IsTlsV11(TlsContext context) + { + return IsTlsV11(context.ServerVersion); + } + + public static bool IsTlsV12(ProtocolVersion version) + { + return ProtocolVersion.TLSv12.IsEqualOrEarlierVersionOf(version.GetEquivalentTLSVersion()); + } + + public static bool IsTlsV12(TlsContext context) + { + return IsTlsV12(context.ServerVersion); + } + + public static void WriteUint8(byte i, Stream output) + { + output.WriteByte(i); + } + + public static void WriteUint8(byte i, byte[] buf, int offset) + { + buf[offset] = i; + } + + public static void WriteUint16(int i, Stream output) + { + output.WriteByte((byte)(i >> 8)); + output.WriteByte((byte)i); + } + + public static void WriteUint16(int i, byte[] buf, int offset) + { + buf[offset] = (byte)(i >> 8); + buf[offset + 1] = (byte)i; + } + + public static void WriteUint24(int i, Stream output) + { + output.WriteByte((byte)(i >> 16)); + output.WriteByte((byte)(i >> 8)); + output.WriteByte((byte)i); + } + + public static void WriteUint24(int i, byte[] buf, int offset) + { + buf[offset] = (byte)(i >> 16); + buf[offset + 1] = (byte)(i >> 8); + buf[offset + 2] = (byte)i; + } + + public static void WriteUint32(long i, Stream output) + { + output.WriteByte((byte)(i >> 24)); + output.WriteByte((byte)(i >> 16)); + output.WriteByte((byte)(i >> 8)); + output.WriteByte((byte)i); + } + + public static void WriteUint32(long i, byte[] buf, int offset) + { + buf[offset] = (byte)(i >> 24); + buf[offset + 1] = (byte)(i >> 16); + buf[offset + 2] = (byte)(i >> 8); + buf[offset + 3] = (byte)i; + } + + public static void WriteUint48(long i, Stream output) + { + output.WriteByte((byte)(i >> 40)); + output.WriteByte((byte)(i >> 32)); + output.WriteByte((byte)(i >> 24)); + output.WriteByte((byte)(i >> 16)); + output.WriteByte((byte)(i >> 8)); + output.WriteByte((byte)i); + } + + public static void WriteUint48(long i, byte[] buf, int offset) + { + buf[offset] = (byte)(i >> 40); + buf[offset + 1] = (byte)(i >> 32); + buf[offset + 2] = (byte)(i >> 24); + buf[offset + 3] = (byte)(i >> 16); + buf[offset + 4] = (byte)(i >> 8); + buf[offset + 5] = (byte)i; + } + + public static void WriteUint64(long i, Stream output) + { + output.WriteByte((byte)(i >> 56)); + output.WriteByte((byte)(i >> 48)); + output.WriteByte((byte)(i >> 40)); + output.WriteByte((byte)(i >> 32)); + output.WriteByte((byte)(i >> 24)); + output.WriteByte((byte)(i >> 16)); + output.WriteByte((byte)(i >> 8)); + output.WriteByte((byte)i); + } + + public static void WriteUint64(long i, byte[] buf, int offset) + { + buf[offset] = (byte)(i >> 56); + buf[offset + 1] = (byte)(i >> 48); + buf[offset + 2] = (byte)(i >> 40); + buf[offset + 3] = (byte)(i >> 32); + buf[offset + 4] = (byte)(i >> 24); + buf[offset + 5] = (byte)(i >> 16); + buf[offset + 6] = (byte)(i >> 8); + buf[offset + 7] = (byte)i; + } + + public static void WriteOpaque8(byte[] buf, Stream output) + { + WriteUint8((byte)buf.Length, output); + output.Write(buf, 0, buf.Length); + } + + public static void WriteOpaque16(byte[] buf, Stream output) + { + WriteUint16(buf.Length, output); + output.Write(buf, 0, buf.Length); + } + + public static void WriteOpaque24(byte[] buf, Stream output) + { + WriteUint24(buf.Length, output); + output.Write(buf, 0, buf.Length); + } + + public static void WriteUint8Array(byte[] uints, Stream output) + { + output.Write(uints, 0, uints.Length); + } + + public static void WriteUint8Array(byte[] uints, byte[] buf, int offset) + { + for (int i = 0; i < uints.Length; ++i) + { + WriteUint8(uints[i], buf, offset); + ++offset; + } + } + + public static void WriteUint8ArrayWithUint8Length(byte[] uints, Stream output) + { + CheckUint8(uints.Length); + WriteUint8((byte)uints.Length, output); + WriteUint8Array(uints, output); + } + + public static void WriteUint8ArrayWithUint8Length(byte[] uints, byte[] buf, int offset) + { + CheckUint8(uints.Length); + WriteUint8((byte)uints.Length, buf, offset); + WriteUint8Array(uints, buf, offset + 1); + } + + public static void WriteUint16Array(int[] uints, Stream output) + { + for (int i = 0; i < uints.Length; ++i) + { + WriteUint16(uints[i], output); + } + } + + public static void WriteUint16Array(int[] uints, byte[] buf, int offset) + { + for (int i = 0; i < uints.Length; ++i) + { + WriteUint16(uints[i], buf, offset); + offset += 2; + } + } + + public static void WriteUint16ArrayWithUint16Length(int[] uints, Stream output) + { + int length = 2 * uints.Length; + CheckUint16(length); + WriteUint16(length, output); + WriteUint16Array(uints, output); + } + + public static void WriteUint16ArrayWithUint16Length(int[] uints, byte[] buf, int offset) + { + int length = 2 * uints.Length; + CheckUint16(length); + WriteUint16(length, buf, offset); + WriteUint16Array(uints, buf, offset + 2); + } + + public static byte DecodeUint8(byte[] buf) + { + if (buf == null) + throw new ArgumentNullException("buf"); + if (buf.Length != 1) + throw new TlsFatalAlert(AlertDescription.decode_error); + return ReadUint8(buf, 0); + } + + public static byte[] DecodeUint8ArrayWithUint8Length(byte[] buf) + { + if (buf == null) + throw new ArgumentNullException("buf"); + + int count = ReadUint8(buf, 0); + if (buf.Length != (count + 1)) + throw new TlsFatalAlert(AlertDescription.decode_error); + + byte[] uints = new byte[count]; + for (int i = 0; i < count; ++i) + { + uints[i] = ReadUint8(buf, i + 1); + } + return uints; + } + + public static byte[] EncodeOpaque8(byte[] buf) + { + CheckUint8(buf.Length); + return Arrays.Prepend(buf, (byte)buf.Length); + } + + public static byte[] EncodeUint8(byte val) + { + CheckUint8(val); + + byte[] extensionData = new byte[1]; + WriteUint8(val, extensionData, 0); + return extensionData; + } + + public static byte[] EncodeUint8ArrayWithUint8Length(byte[] uints) + { + byte[] result = new byte[1 + uints.Length]; + WriteUint8ArrayWithUint8Length(uints, result, 0); + return result; + } + + public static byte[] EncodeUint16ArrayWithUint16Length(int[] uints) + { + int length = 2 * uints.Length; + byte[] result = new byte[2 + length]; + WriteUint16ArrayWithUint16Length(uints, result, 0); + return result; + } + + public static byte ReadUint8(Stream input) + { + int i = input.ReadByte(); + if (i < 0) + throw new EndOfStreamException(); + return (byte)i; + } + + public static byte ReadUint8(byte[] buf, int offset) + { + return buf[offset]; + } + + public static int ReadUint16(Stream input) + { + int i1 = input.ReadByte(); + int i2 = input.ReadByte(); + if (i2 < 0) + throw new EndOfStreamException(); + return (i1 << 8) | i2; + } + + public static int ReadUint16(byte[] buf, int offset) + { + uint n = (uint)buf[offset] << 8; + n |= (uint)buf[++offset]; + return (int)n; + } + + public static int ReadUint24(Stream input) + { + int i1 = input.ReadByte(); + int i2 = input.ReadByte(); + int i3 = input.ReadByte(); + if (i3 < 0) + throw new EndOfStreamException(); + return (i1 << 16) | (i2 << 8) | i3; + } + + public static int ReadUint24(byte[] buf, int offset) + { + uint n = (uint)buf[offset] << 16; + n |= (uint)buf[++offset] << 8; + n |= (uint)buf[++offset]; + return (int)n; + } + + public static long ReadUint32(Stream input) + { + int i1 = input.ReadByte(); + int i2 = input.ReadByte(); + int i3 = input.ReadByte(); + int i4 = input.ReadByte(); + if (i4 < 0) + throw new EndOfStreamException(); + return (long)(uint)((i1 << 24) | (i2 << 16) | (i3 << 8) | i4); + } + + public static long ReadUint32(byte[] buf, int offset) + { + uint n = (uint)buf[offset] << 24; + n |= (uint)buf[++offset] << 16; + n |= (uint)buf[++offset] << 8; + n |= (uint)buf[++offset]; + return (long)n; + } + + public static long ReadUint48(Stream input) + { + int hi = ReadUint24(input); + int lo = ReadUint24(input); + return ((long)(hi & 0xffffffffL) << 24) | (long)(lo & 0xffffffffL); + } + + public static long ReadUint48(byte[] buf, int offset) + { + int hi = ReadUint24(buf, offset); + int lo = ReadUint24(buf, offset + 3); + return ((long)(hi & 0xffffffffL) << 24) | (long)(lo & 0xffffffffL); + } + + public static byte[] ReadAllOrNothing(int length, Stream input) + { + if (length < 1) + return EmptyBytes; + byte[] buf = new byte[length]; + int read = Streams.ReadFully(input, buf); + if (read == 0) + return null; + if (read != length) + throw new EndOfStreamException(); + return buf; + } + + public static byte[] ReadFully(int length, Stream input) + { + if (length < 1) + return EmptyBytes; + byte[] buf = new byte[length]; + if (length != Streams.ReadFully(input, buf)) + throw new EndOfStreamException(); + return buf; + } + + public static void ReadFully(byte[] buf, Stream input) + { + if (Streams.ReadFully(input, buf, 0, buf.Length) < buf.Length) + throw new EndOfStreamException(); + } + + public static byte[] ReadOpaque8(Stream input) + { + byte length = ReadUint8(input); + byte[] bytes = new byte[length]; + ReadFully(bytes, input); + return bytes; + } + + public static byte[] ReadOpaque16(Stream input) + { + int length = ReadUint16(input); + byte[] bytes = new byte[length]; + ReadFully(bytes, input); + return bytes; + } + + public static byte[] ReadOpaque24(Stream input) + { + int length = ReadUint24(input); + return ReadFully(length, input); + } + + public static byte[] ReadUint8Array(int count, Stream input) + { + byte[] uints = new byte[count]; + for (int i = 0; i < count; ++i) + { + uints[i] = ReadUint8(input); + } + return uints; + } + + public static int[] ReadUint16Array(int count, Stream input) + { + int[] uints = new int[count]; + for (int i = 0; i < count; ++i) + { + uints[i] = ReadUint16(input); + } + return uints; + } + + public static ProtocolVersion ReadVersion(byte[] buf, int offset) + { + return ProtocolVersion.Get(buf[offset], buf[offset + 1]); + } + + public static ProtocolVersion ReadVersion(Stream input) + { + int i1 = input.ReadByte(); + int i2 = input.ReadByte(); + if (i2 < 0) + throw new EndOfStreamException(); + return ProtocolVersion.Get(i1, i2); + } + + public static int ReadVersionRaw(byte[] buf, int offset) + { + return (buf[offset] << 8) | buf[offset + 1]; + } + + public static int ReadVersionRaw(Stream input) + { + int i1 = input.ReadByte(); + int i2 = input.ReadByte(); + if (i2 < 0) + throw new EndOfStreamException(); + return (i1 << 8) | i2; + } + + public static Asn1Object ReadAsn1Object(byte[] encoding) + { + MemoryStream input = new MemoryStream(encoding, false); + Asn1InputStream asn1 = new Asn1InputStream(input, encoding.Length); + Asn1Object result = asn1.ReadObject(); + if (null == result) + throw new TlsFatalAlert(AlertDescription.decode_error); + if (input.Position != input.Length) + throw new TlsFatalAlert(AlertDescription.decode_error); + return result; + } + + public static Asn1Object ReadDerObject(byte[] encoding) + { + /* + * NOTE: The current ASN.1 parsing code can't enforce DER-only parsing, but since DER is + * canonical, we can check it by re-encoding the result and comparing to the original. + */ + Asn1Object result = ReadAsn1Object(encoding); + byte[] check = result.GetEncoded(Asn1Encodable.Der); + if (!Arrays.AreEqual(check, encoding)) + throw new TlsFatalAlert(AlertDescription.decode_error); + return result; + } + + public static void WriteGmtUnixTime(byte[] buf, int offset) + { + int t = (int)(DateTimeUtilities.CurrentUnixMs() / 1000L); + buf[offset] = (byte)(t >> 24); + buf[offset + 1] = (byte)(t >> 16); + buf[offset + 2] = (byte)(t >> 8); + buf[offset + 3] = (byte)t; + } + + public static void WriteVersion(ProtocolVersion version, Stream output) + { + output.WriteByte((byte)version.MajorVersion); + output.WriteByte((byte)version.MinorVersion); + } + + public static void WriteVersion(ProtocolVersion version, byte[] buf, int offset) + { + buf[offset] = (byte)version.MajorVersion; + buf[offset + 1] = (byte)version.MinorVersion; + } + + public static IList GetAllSignatureAlgorithms() + { + IList v = Platform.CreateArrayList(4); + v.Add(SignatureAlgorithm.anonymous); + v.Add(SignatureAlgorithm.rsa); + v.Add(SignatureAlgorithm.dsa); + v.Add(SignatureAlgorithm.ecdsa); + return v; + } + + public static IList GetDefaultDssSignatureAlgorithms() + { + return VectorOfOne(new SignatureAndHashAlgorithm(HashAlgorithm.sha1, SignatureAlgorithm.dsa)); + } + + public static IList GetDefaultECDsaSignatureAlgorithms() + { + return VectorOfOne(new SignatureAndHashAlgorithm(HashAlgorithm.sha1, SignatureAlgorithm.ecdsa)); + } + + public static IList GetDefaultRsaSignatureAlgorithms() + { + return VectorOfOne(new SignatureAndHashAlgorithm(HashAlgorithm.sha1, SignatureAlgorithm.rsa)); + } + + public static byte[] GetExtensionData(IDictionary extensions, int extensionType) + { + return extensions == null ? null : (byte[])extensions[extensionType]; + } + + public static IList GetDefaultSupportedSignatureAlgorithms() + { + byte[] hashAlgorithms = new byte[]{ HashAlgorithm.sha1, HashAlgorithm.sha224, HashAlgorithm.sha256, + HashAlgorithm.sha384, HashAlgorithm.sha512 }; + byte[] signatureAlgorithms = new byte[]{ SignatureAlgorithm.rsa, SignatureAlgorithm.dsa, + SignatureAlgorithm.ecdsa }; + + IList result = Platform.CreateArrayList(); + for (int i = 0; i < signatureAlgorithms.Length; ++i) + { + for (int j = 0; j < hashAlgorithms.Length; ++j) + { + result.Add(new SignatureAndHashAlgorithm(hashAlgorithms[j], signatureAlgorithms[i])); + } + } + return result; + } + + public static SignatureAndHashAlgorithm GetSignatureAndHashAlgorithm(TlsContext context, + TlsSignerCredentials signerCredentials) + { + SignatureAndHashAlgorithm signatureAndHashAlgorithm = null; + if (IsTlsV12(context)) + { + signatureAndHashAlgorithm = signerCredentials.SignatureAndHashAlgorithm; + if (signatureAndHashAlgorithm == null) + throw new TlsFatalAlert(AlertDescription.internal_error); + } + return signatureAndHashAlgorithm; + } + + public static bool HasExpectedEmptyExtensionData(IDictionary extensions, int extensionType, + byte alertDescription) + { + byte[] extension_data = GetExtensionData(extensions, extensionType); + if (extension_data == null) + return false; + if (extension_data.Length != 0) + throw new TlsFatalAlert(alertDescription); + return true; + } + + public static TlsSession ImportSession(byte[] sessionID, SessionParameters sessionParameters) + { + return new TlsSessionImpl(sessionID, sessionParameters); + } + + public static bool IsSignatureAlgorithmsExtensionAllowed(ProtocolVersion clientVersion) + { + return ProtocolVersion.TLSv12.IsEqualOrEarlierVersionOf(clientVersion.GetEquivalentTLSVersion()); + } + + /** + * Add a 'signature_algorithms' extension to existing extensions. + * + * @param extensions A {@link Hashtable} to add the extension to. + * @param supportedSignatureAlgorithms {@link Vector} containing at least 1 {@link SignatureAndHashAlgorithm}. + * @throws IOException + */ + public static void AddSignatureAlgorithmsExtension(IDictionary extensions, IList supportedSignatureAlgorithms) + { + extensions[ExtensionType.signature_algorithms] = CreateSignatureAlgorithmsExtension(supportedSignatureAlgorithms); + } + + /** + * Get a 'signature_algorithms' extension from extensions. + * + * @param extensions A {@link Hashtable} to get the extension from, if it is present. + * @return A {@link Vector} containing at least 1 {@link SignatureAndHashAlgorithm}, or null. + * @throws IOException + */ + public static IList GetSignatureAlgorithmsExtension(IDictionary extensions) + { + byte[] extensionData = GetExtensionData(extensions, ExtensionType.signature_algorithms); + return extensionData == null ? null : ReadSignatureAlgorithmsExtension(extensionData); + } + + /** + * Create a 'signature_algorithms' extension value. + * + * @param supportedSignatureAlgorithms A {@link Vector} containing at least 1 {@link SignatureAndHashAlgorithm}. + * @return A byte array suitable for use as an extension value. + * @throws IOException + */ + public static byte[] CreateSignatureAlgorithmsExtension(IList supportedSignatureAlgorithms) + { + MemoryStream buf = new MemoryStream(); + + // supported_signature_algorithms + EncodeSupportedSignatureAlgorithms(supportedSignatureAlgorithms, false, buf); + + return buf.ToArray(); + } + + /** + * Read 'signature_algorithms' extension data. + * + * @param extensionData The extension data. + * @return A {@link Vector} containing at least 1 {@link SignatureAndHashAlgorithm}. + * @throws IOException + */ + public static IList ReadSignatureAlgorithmsExtension(byte[] extensionData) + { + if (extensionData == null) + throw new ArgumentNullException("extensionData"); + + MemoryStream buf = new MemoryStream(extensionData, false); + + // supported_signature_algorithms + IList supported_signature_algorithms = ParseSupportedSignatureAlgorithms(false, buf); + + TlsProtocol.AssertEmpty(buf); + + return supported_signature_algorithms; + } + + public static void EncodeSupportedSignatureAlgorithms(IList supportedSignatureAlgorithms, bool allowAnonymous, + Stream output) + { + if (supportedSignatureAlgorithms == null) + throw new ArgumentNullException("supportedSignatureAlgorithms"); + if (supportedSignatureAlgorithms.Count < 1 || supportedSignatureAlgorithms.Count >= (1 << 15)) + throw new ArgumentException("must have length from 1 to (2^15 - 1)", "supportedSignatureAlgorithms"); + + // supported_signature_algorithms + int length = 2 * supportedSignatureAlgorithms.Count; + CheckUint16(length); + WriteUint16(length, output); + + foreach (SignatureAndHashAlgorithm entry in supportedSignatureAlgorithms) + { + if (!allowAnonymous && entry.Signature == SignatureAlgorithm.anonymous) + { + /* + * RFC 5246 7.4.1.4.1 The "anonymous" value is meaningless in this context but used + * in Section 7.4.3. It MUST NOT appear in this extension. + */ + throw new ArgumentException( + "SignatureAlgorithm.anonymous MUST NOT appear in the signature_algorithms extension"); + } + entry.Encode(output); + } + } + + public static IList ParseSupportedSignatureAlgorithms(bool allowAnonymous, Stream input) + { + // supported_signature_algorithms + int length = ReadUint16(input); + if (length < 2 || (length & 1) != 0) + throw new TlsFatalAlert(AlertDescription.decode_error); + int count = length / 2; + IList supportedSignatureAlgorithms = Platform.CreateArrayList(count); + for (int i = 0; i < count; ++i) + { + SignatureAndHashAlgorithm entry = SignatureAndHashAlgorithm.Parse(input); + if (!allowAnonymous && entry.Signature == SignatureAlgorithm.anonymous) + { + /* + * RFC 5246 7.4.1.4.1 The "anonymous" value is meaningless in this context but used + * in Section 7.4.3. It MUST NOT appear in this extension. + */ + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + supportedSignatureAlgorithms.Add(entry); + } + return supportedSignatureAlgorithms; + } + + public static void VerifySupportedSignatureAlgorithm(IList supportedSignatureAlgorithms, SignatureAndHashAlgorithm signatureAlgorithm) + { + if (supportedSignatureAlgorithms == null) + throw new ArgumentNullException("supportedSignatureAlgorithms"); + if (supportedSignatureAlgorithms.Count < 1 || supportedSignatureAlgorithms.Count >= (1 << 15)) + throw new ArgumentException("must have length from 1 to (2^15 - 1)", "supportedSignatureAlgorithms"); + if (signatureAlgorithm == null) + throw new ArgumentNullException("signatureAlgorithm"); + + if (signatureAlgorithm.Signature != SignatureAlgorithm.anonymous) + { + foreach (SignatureAndHashAlgorithm entry in supportedSignatureAlgorithms) + { + if (entry.Hash == signatureAlgorithm.Hash && entry.Signature == signatureAlgorithm.Signature) + return; + } + } + + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + public static byte[] PRF(TlsContext context, byte[] secret, string asciiLabel, byte[] seed, int size) + { + ProtocolVersion version = context.ServerVersion; + + if (version.IsSsl) + throw new InvalidOperationException("No PRF available for SSLv3 session"); + + byte[] label = Strings.ToByteArray(asciiLabel); + byte[] labelSeed = Concat(label, seed); + + int prfAlgorithm = context.SecurityParameters.PrfAlgorithm; + + if (prfAlgorithm == PrfAlgorithm.tls_prf_legacy) + return PRF_legacy(secret, label, labelSeed, size); + + IDigest prfDigest = CreatePrfHash(prfAlgorithm); + byte[] buf = new byte[size]; + HMacHash(prfDigest, secret, labelSeed, buf); + return buf; + } + + public static byte[] PRF_legacy(byte[] secret, string asciiLabel, byte[] seed, int size) + { + byte[] label = Strings.ToByteArray(asciiLabel); + byte[] labelSeed = Concat(label, seed); + + return PRF_legacy(secret, label, labelSeed, size); + } + + internal static byte[] PRF_legacy(byte[] secret, byte[] label, byte[] labelSeed, int size) + { + int s_half = (secret.Length + 1) / 2; + byte[] s1 = new byte[s_half]; + byte[] s2 = new byte[s_half]; + Array.Copy(secret, 0, s1, 0, s_half); + Array.Copy(secret, secret.Length - s_half, s2, 0, s_half); + + byte[] b1 = new byte[size]; + byte[] b2 = new byte[size]; + HMacHash(CreateHash(HashAlgorithm.md5), s1, labelSeed, b1); + HMacHash(CreateHash(HashAlgorithm.sha1), s2, labelSeed, b2); + for (int i = 0; i < size; i++) + { + b1[i] ^= b2[i]; + } + return b1; + } + + internal static byte[] Concat(byte[] a, byte[] b) + { + byte[] c = new byte[a.Length + b.Length]; + Array.Copy(a, 0, c, 0, a.Length); + Array.Copy(b, 0, c, a.Length, b.Length); + return c; + } + + internal static void HMacHash(IDigest digest, byte[] secret, byte[] seed, byte[] output) + { + HMac mac = new HMac(digest); + mac.Init(new KeyParameter(secret)); + byte[] a = seed; + int size = digest.GetDigestSize(); + int iterations = (output.Length + size - 1) / size; + byte[] buf = new byte[mac.GetMacSize()]; + byte[] buf2 = new byte[mac.GetMacSize()]; + for (int i = 0; i < iterations; i++) + { + mac.BlockUpdate(a, 0, a.Length); + mac.DoFinal(buf, 0); + a = buf; + mac.BlockUpdate(a, 0, a.Length); + mac.BlockUpdate(seed, 0, seed.Length); + mac.DoFinal(buf2, 0); + Array.Copy(buf2, 0, output, (size * i), System.Math.Min(size, output.Length - (size * i))); + } + } + + internal static void ValidateKeyUsage(X509CertificateStructure c, int keyUsageBits) + { + X509Extensions exts = c.TbsCertificate.Extensions; + if (exts != null) + { + X509Extension ext = exts.GetExtension(X509Extensions.KeyUsage); + if (ext != null) + { + DerBitString ku = KeyUsage.GetInstance(ext); + int bits = ku.GetBytes()[0]; + if ((bits & keyUsageBits) != keyUsageBits) + throw new TlsFatalAlert(AlertDescription.certificate_unknown); + } + } + } + + internal static byte[] CalculateKeyBlock(TlsContext context, int size) + { + SecurityParameters securityParameters = context.SecurityParameters; + byte[] master_secret = securityParameters.MasterSecret; + byte[] seed = Concat(securityParameters.ServerRandom, securityParameters.ClientRandom); + + if (IsSsl(context)) + return CalculateKeyBlock_Ssl(master_secret, seed, size); + + return PRF(context, master_secret, ExporterLabel.key_expansion, seed, size); + } + + internal static byte[] CalculateKeyBlock_Ssl(byte[] master_secret, byte[] random, int size) + { + IDigest md5 = CreateHash(HashAlgorithm.md5); + IDigest sha1 = CreateHash(HashAlgorithm.sha1); + int md5Size = md5.GetDigestSize(); + byte[] shatmp = new byte[sha1.GetDigestSize()]; + byte[] tmp = new byte[size + md5Size]; + + int i = 0, pos = 0; + while (pos < size) + { + byte[] ssl3Const = SSL3_CONST[i]; + + sha1.BlockUpdate(ssl3Const, 0, ssl3Const.Length); + sha1.BlockUpdate(master_secret, 0, master_secret.Length); + sha1.BlockUpdate(random, 0, random.Length); + sha1.DoFinal(shatmp, 0); + + md5.BlockUpdate(master_secret, 0, master_secret.Length); + md5.BlockUpdate(shatmp, 0, shatmp.Length); + md5.DoFinal(tmp, pos); + + pos += md5Size; + ++i; + } + + return Arrays.CopyOfRange(tmp, 0, size); + } + + internal static byte[] CalculateMasterSecret(TlsContext context, byte[] pre_master_secret) + { + SecurityParameters securityParameters = context.SecurityParameters; + + byte[] seed = securityParameters.IsExtendedMasterSecret + ? securityParameters.SessionHash + : Concat(securityParameters.ClientRandom, securityParameters.ServerRandom); + + if (IsSsl(context)) + return CalculateMasterSecret_Ssl(pre_master_secret, seed); + + string asciiLabel = securityParameters.IsExtendedMasterSecret + ? ExporterLabel.extended_master_secret + : ExporterLabel.master_secret; + + return PRF(context, pre_master_secret, asciiLabel, seed, 48); + } + + internal static byte[] CalculateMasterSecret_Ssl(byte[] pre_master_secret, byte[] random) + { + IDigest md5 = CreateHash(HashAlgorithm.md5); + IDigest sha1 = CreateHash(HashAlgorithm.sha1); + int md5Size = md5.GetDigestSize(); + byte[] shatmp = new byte[sha1.GetDigestSize()]; + + byte[] rval = new byte[md5Size * 3]; + int pos = 0; + + for (int i = 0; i < 3; ++i) + { + byte[] ssl3Const = SSL3_CONST[i]; + + sha1.BlockUpdate(ssl3Const, 0, ssl3Const.Length); + sha1.BlockUpdate(pre_master_secret, 0, pre_master_secret.Length); + sha1.BlockUpdate(random, 0, random.Length); + sha1.DoFinal(shatmp, 0); + + md5.BlockUpdate(pre_master_secret, 0, pre_master_secret.Length); + md5.BlockUpdate(shatmp, 0, shatmp.Length); + md5.DoFinal(rval, pos); + + pos += md5Size; + } + + return rval; + } + + internal static byte[] CalculateVerifyData(TlsContext context, string asciiLabel, byte[] handshakeHash) + { + if (IsSsl(context)) + return handshakeHash; + + SecurityParameters securityParameters = context.SecurityParameters; + byte[] master_secret = securityParameters.MasterSecret; + int verify_data_length = securityParameters.VerifyDataLength; + + return PRF(context, master_secret, asciiLabel, handshakeHash, verify_data_length); + } + + public static IDigest CreateHash(byte hashAlgorithm) + { + switch (hashAlgorithm) + { + case HashAlgorithm.md5: + return new MD5Digest(); + case HashAlgorithm.sha1: + return new Sha1Digest(); + case HashAlgorithm.sha224: + return new Sha224Digest(); + case HashAlgorithm.sha256: + return new Sha256Digest(); + case HashAlgorithm.sha384: + return new Sha384Digest(); + case HashAlgorithm.sha512: + return new Sha512Digest(); + default: + throw new ArgumentException("unknown HashAlgorithm", "hashAlgorithm"); + } + } + + public static IDigest CreateHash(SignatureAndHashAlgorithm signatureAndHashAlgorithm) + { + return signatureAndHashAlgorithm == null + ? new CombinedHash() + : CreateHash(signatureAndHashAlgorithm.Hash); + } + + public static IDigest CloneHash(byte hashAlgorithm, IDigest hash) + { + switch (hashAlgorithm) + { + case HashAlgorithm.md5: + return new MD5Digest((MD5Digest)hash); + case HashAlgorithm.sha1: + return new Sha1Digest((Sha1Digest)hash); + case HashAlgorithm.sha224: + return new Sha224Digest((Sha224Digest)hash); + case HashAlgorithm.sha256: + return new Sha256Digest((Sha256Digest)hash); + case HashAlgorithm.sha384: + return new Sha384Digest((Sha384Digest)hash); + case HashAlgorithm.sha512: + return new Sha512Digest((Sha512Digest)hash); + default: + throw new ArgumentException("unknown HashAlgorithm", "hashAlgorithm"); + } + } + + public static IDigest CreatePrfHash(int prfAlgorithm) + { + switch (prfAlgorithm) + { + case PrfAlgorithm.tls_prf_legacy: + return new CombinedHash(); + default: + return CreateHash(GetHashAlgorithmForPrfAlgorithm(prfAlgorithm)); + } + } + + public static IDigest ClonePrfHash(int prfAlgorithm, IDigest hash) + { + switch (prfAlgorithm) + { + case PrfAlgorithm.tls_prf_legacy: + return new CombinedHash((CombinedHash)hash); + default: + return CloneHash(GetHashAlgorithmForPrfAlgorithm(prfAlgorithm), hash); + } + } + + public static byte GetHashAlgorithmForPrfAlgorithm(int prfAlgorithm) + { + switch (prfAlgorithm) + { + case PrfAlgorithm.tls_prf_legacy: + throw new ArgumentException("legacy PRF not a valid algorithm", "prfAlgorithm"); + case PrfAlgorithm.tls_prf_sha256: + return HashAlgorithm.sha256; + case PrfAlgorithm.tls_prf_sha384: + return HashAlgorithm.sha384; + default: + throw new ArgumentException("unknown PrfAlgorithm", "prfAlgorithm"); + } + } + + public static DerObjectIdentifier GetOidForHashAlgorithm(byte hashAlgorithm) + { + switch (hashAlgorithm) + { + case HashAlgorithm.md5: + return PkcsObjectIdentifiers.MD5; + case HashAlgorithm.sha1: + return X509ObjectIdentifiers.IdSha1; + case HashAlgorithm.sha224: + return NistObjectIdentifiers.IdSha224; + case HashAlgorithm.sha256: + return NistObjectIdentifiers.IdSha256; + case HashAlgorithm.sha384: + return NistObjectIdentifiers.IdSha384; + case HashAlgorithm.sha512: + return NistObjectIdentifiers.IdSha512; + default: + throw new ArgumentException("unknown HashAlgorithm", "hashAlgorithm"); + } + } + + internal static short GetClientCertificateType(Certificate clientCertificate, Certificate serverCertificate) + { + if (clientCertificate.IsEmpty) + return -1; + + X509CertificateStructure x509Cert = clientCertificate.GetCertificateAt(0); + SubjectPublicKeyInfo keyInfo = x509Cert.SubjectPublicKeyInfo; + try + { + AsymmetricKeyParameter publicKey = PublicKeyFactory.CreateKey(keyInfo); + if (publicKey.IsPrivate) + throw new TlsFatalAlert(AlertDescription.internal_error); + + /* + * TODO RFC 5246 7.4.6. The certificates MUST be signed using an acceptable hash/ + * signature algorithm pair, as described in Section 7.4.4. Note that this relaxes the + * constraints on certificate-signing algorithms found in prior versions of TLS. + */ + + /* + * RFC 5246 7.4.6. Client Certificate + */ + + /* + * RSA public key; the certificate MUST allow the key to be used for signing with the + * signature scheme and hash algorithm that will be employed in the certificate verify + * message. + */ + if (publicKey is RsaKeyParameters) + { + ValidateKeyUsage(x509Cert, KeyUsage.DigitalSignature); + return ClientCertificateType.rsa_sign; + } + + /* + * DSA public key; the certificate MUST allow the key to be used for signing with the + * hash algorithm that will be employed in the certificate verify message. + */ + if (publicKey is DsaPublicKeyParameters) + { + ValidateKeyUsage(x509Cert, KeyUsage.DigitalSignature); + return ClientCertificateType.dss_sign; + } + + /* + * ECDSA-capable public key; the certificate MUST allow the key to be used for signing + * with the hash algorithm that will be employed in the certificate verify message; the + * public key MUST use a curve and point format supported by the server. + */ + if (publicKey is ECPublicKeyParameters) + { + ValidateKeyUsage(x509Cert, KeyUsage.DigitalSignature); + // TODO Check the curve and point format + return ClientCertificateType.ecdsa_sign; + } + + // TODO Add support for ClientCertificateType.*_fixed_* + + throw new TlsFatalAlert(AlertDescription.unsupported_certificate); + } + catch (Exception e) + { + throw new TlsFatalAlert(AlertDescription.unsupported_certificate, e); + } + } + + internal static void TrackHashAlgorithms(TlsHandshakeHash handshakeHash, IList supportedSignatureAlgorithms) + { + if (supportedSignatureAlgorithms != null) + { + foreach (SignatureAndHashAlgorithm signatureAndHashAlgorithm in supportedSignatureAlgorithms) + { + byte hashAlgorithm = signatureAndHashAlgorithm.Hash; + + if (HashAlgorithm.IsRecognized(hashAlgorithm)) + { + handshakeHash.TrackHashAlgorithm(hashAlgorithm); + } + else //if (HashAlgorithm.IsPrivate(hashAlgorithm)) + { + // TODO Support values in the "Reserved for Private Use" range + } + } + } + } + + public static bool HasSigningCapability(byte clientCertificateType) + { + switch (clientCertificateType) + { + case ClientCertificateType.dss_sign: + case ClientCertificateType.ecdsa_sign: + case ClientCertificateType.rsa_sign: + return true; + default: + return false; + } + } + + public static TlsSigner CreateTlsSigner(byte clientCertificateType) + { + switch (clientCertificateType) + { + case ClientCertificateType.dss_sign: + return new TlsDssSigner(); + case ClientCertificateType.ecdsa_sign: + return new TlsECDsaSigner(); + case ClientCertificateType.rsa_sign: + return new TlsRsaSigner(); + default: + throw new ArgumentException("not a type with signing capability", "clientCertificateType"); + } + } + + internal static readonly byte[] SSL_CLIENT = {0x43, 0x4C, 0x4E, 0x54}; + internal static readonly byte[] SSL_SERVER = {0x53, 0x52, 0x56, 0x52}; + + // SSL3 magic mix constants ("A", "BB", "CCC", ...) + internal static readonly byte[][] SSL3_CONST = GenSsl3Const(); + + private static byte[][] GenSsl3Const() + { + int n = 10; + byte[][] arr = new byte[n][]; + for (int i = 0; i < n; i++) + { + byte[] b = new byte[i + 1]; + Arrays.Fill(b, (byte)('A' + i)); + arr[i] = b; + } + return arr; + } + + private static IList VectorOfOne(object obj) + { + IList v = Platform.CreateArrayList(1); + v.Add(obj); + return v; + } + + public static int GetCipherType(int ciphersuite) + { + switch (GetEncryptionAlgorithm(ciphersuite)) + { + case EncryptionAlgorithm.AES_128_CCM: + case EncryptionAlgorithm.AES_128_CCM_8: + case EncryptionAlgorithm.AES_128_GCM: + case EncryptionAlgorithm.AES_128_OCB_TAGLEN96: + case EncryptionAlgorithm.AES_256_CCM: + case EncryptionAlgorithm.AES_256_CCM_8: + case EncryptionAlgorithm.AES_256_GCM: + case EncryptionAlgorithm.AES_256_OCB_TAGLEN96: + case EncryptionAlgorithm.CAMELLIA_128_GCM: + case EncryptionAlgorithm.CAMELLIA_256_GCM: + case EncryptionAlgorithm.CHACHA20_POLY1305: + return CipherType.aead; + + case EncryptionAlgorithm.RC2_CBC_40: + case EncryptionAlgorithm.IDEA_CBC: + case EncryptionAlgorithm.DES40_CBC: + case EncryptionAlgorithm.DES_CBC: + case EncryptionAlgorithm.cls_3DES_EDE_CBC: + case EncryptionAlgorithm.AES_128_CBC: + case EncryptionAlgorithm.AES_256_CBC: + case EncryptionAlgorithm.CAMELLIA_128_CBC: + case EncryptionAlgorithm.CAMELLIA_256_CBC: + case EncryptionAlgorithm.SEED_CBC: + return CipherType.block; + + case EncryptionAlgorithm.NULL: + case EncryptionAlgorithm.RC4_40: + case EncryptionAlgorithm.RC4_128: + return CipherType.stream; + + default: + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + public static int GetEncryptionAlgorithm(int ciphersuite) + { + switch (ciphersuite) + { + case CipherSuite.TLS_DH_anon_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_PSK_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA: + return EncryptionAlgorithm.cls_3DES_EDE_CBC; + + case CipherSuite.TLS_DH_anon_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DH_anon_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_anon_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_WITH_AES_128_CBC_SHA: + return EncryptionAlgorithm.AES_128_CBC; + + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CCM: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM: + case CipherSuite.TLS_PSK_WITH_AES_128_CCM: + case CipherSuite.TLS_RSA_WITH_AES_128_CCM: + return EncryptionAlgorithm.AES_128_CCM; + + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM_8: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8: + case CipherSuite.TLS_PSK_DHE_WITH_AES_128_CCM_8: + case CipherSuite.TLS_PSK_WITH_AES_128_CCM_8: + case CipherSuite.TLS_RSA_WITH_AES_128_CCM_8: + return EncryptionAlgorithm.AES_128_CCM_8; + + case CipherSuite.TLS_DH_anon_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256: + return EncryptionAlgorithm.AES_128_GCM; + + case CipherSuite.TLS_DH_anon_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DH_anon_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_ECDH_anon_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_WITH_AES_256_CBC_SHA: + return EncryptionAlgorithm.AES_256_CBC; + + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CCM: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM: + case CipherSuite.TLS_PSK_WITH_AES_256_CCM: + case CipherSuite.TLS_RSA_WITH_AES_256_CCM: + return EncryptionAlgorithm.AES_256_CCM; + + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM_8: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8: + case CipherSuite.TLS_PSK_DHE_WITH_AES_256_CCM_8: + case CipherSuite.TLS_PSK_WITH_AES_256_CCM_8: + case CipherSuite.TLS_RSA_WITH_AES_256_CCM_8: + return EncryptionAlgorithm.AES_256_CCM_8; + + case CipherSuite.TLS_DH_anon_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DH_DSS_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DH_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DHE_DSS_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384: + return EncryptionAlgorithm.AES_256_GCM; + + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256: + return EncryptionAlgorithm.CAMELLIA_128_CBC; + + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256: + return EncryptionAlgorithm.CAMELLIA_128_GCM; + + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384: + return EncryptionAlgorithm.CAMELLIA_256_CBC; + + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384: + return EncryptionAlgorithm.CAMELLIA_256_GCM; + + case CipherSuite.DRAFT_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.DRAFT_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.DRAFT_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.DRAFT_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.DRAFT_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.DRAFT_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.DRAFT_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256: + return EncryptionAlgorithm.CHACHA20_POLY1305; + + case CipherSuite.TLS_RSA_WITH_NULL_MD5: + return EncryptionAlgorithm.NULL; + + case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA: + case CipherSuite.TLS_ECDH_anon_WITH_NULL_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_NULL_SHA: + case CipherSuite.TLS_ECDH_RSA_WITH_NULL_SHA: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_NULL_SHA: + case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA: + case CipherSuite.TLS_ECDHE_RSA_WITH_NULL_SHA: + case CipherSuite.TLS_PSK_WITH_NULL_SHA: + case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA: + case CipherSuite.TLS_RSA_WITH_NULL_SHA: + return EncryptionAlgorithm.NULL; + + case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA256: + case CipherSuite.TLS_PSK_WITH_NULL_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA256: + case CipherSuite.TLS_RSA_WITH_NULL_SHA256: + return EncryptionAlgorithm.NULL; + + case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA384: + case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA384: + case CipherSuite.TLS_PSK_WITH_NULL_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA384: + return EncryptionAlgorithm.NULL; + + case CipherSuite.TLS_DH_anon_WITH_RC4_128_MD5: + case CipherSuite.TLS_RSA_WITH_RC4_128_MD5: + return EncryptionAlgorithm.RC4_128; + + case CipherSuite.TLS_DHE_PSK_WITH_RC4_128_SHA: + case CipherSuite.TLS_ECDH_anon_WITH_RC4_128_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_RC4_128_SHA: + case CipherSuite.TLS_ECDH_RSA_WITH_RC4_128_SHA: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: + case CipherSuite.TLS_ECDHE_PSK_WITH_RC4_128_SHA: + case CipherSuite.TLS_ECDHE_RSA_WITH_RC4_128_SHA: + case CipherSuite.TLS_PSK_WITH_RC4_128_SHA: + case CipherSuite.TLS_RSA_WITH_RC4_128_SHA: + case CipherSuite.TLS_RSA_PSK_WITH_RC4_128_SHA: + return EncryptionAlgorithm.RC4_128; + + case CipherSuite.TLS_DH_anon_WITH_SEED_CBC_SHA: + case CipherSuite.TLS_DH_DSS_WITH_SEED_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_SEED_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_SEED_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_SEED_CBC_SHA: + case CipherSuite.TLS_RSA_WITH_SEED_CBC_SHA: + return EncryptionAlgorithm.SEED_CBC; + + default: + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + public static int GetKeyExchangeAlgorithm(int ciphersuite) + { + switch (ciphersuite) + { + case CipherSuite.TLS_DH_anon_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DH_anon_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DH_anon_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DH_anon_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DH_anon_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DH_anon_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DH_anon_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DH_anon_WITH_RC4_128_MD5: + case CipherSuite.TLS_DH_anon_WITH_SEED_CBC_SHA: + return KeyExchangeAlgorithm.DH_anon; + + case CipherSuite.TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DH_DSS_WITH_SEED_CBC_SHA: + return KeyExchangeAlgorithm.DH_DSS; + + case CipherSuite.TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DH_RSA_WITH_SEED_CBC_SHA: + return KeyExchangeAlgorithm.DH_RSA; + + case CipherSuite.TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_DSS_WITH_SEED_CBC_SHA: + return KeyExchangeAlgorithm.DHE_DSS; + + case CipherSuite.TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CCM: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CCM: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA: + case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_RC4_128_SHA: + case CipherSuite.TLS_PSK_DHE_WITH_AES_128_CCM_8: + case CipherSuite.TLS_PSK_DHE_WITH_AES_256_CCM_8: + return KeyExchangeAlgorithm.DHE_PSK; + + case CipherSuite.TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM_8: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM_8: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_SEED_CBC_SHA: + return KeyExchangeAlgorithm.DHE_RSA; + + case CipherSuite.TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDH_anon_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDH_anon_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDH_anon_WITH_NULL_SHA: + case CipherSuite.TLS_ECDH_anon_WITH_RC4_128_SHA: + return KeyExchangeAlgorithm.ECDH_anon; + + case CipherSuite.TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_NULL_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_RC4_128_SHA: + return KeyExchangeAlgorithm.ECDH_ECDSA; + + case CipherSuite.TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_NULL_SHA: + case CipherSuite.TLS_ECDH_RSA_WITH_RC4_128_SHA: + return KeyExchangeAlgorithm.ECDH_RSA; + + case CipherSuite.TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_NULL_SHA: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: + return KeyExchangeAlgorithm.ECDHE_ECDSA; + + case CipherSuite.TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.DRAFT_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA: + case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA384: + case CipherSuite.TLS_ECDHE_PSK_WITH_RC4_128_SHA: + return KeyExchangeAlgorithm.ECDHE_PSK; + + case CipherSuite.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_NULL_SHA: + case CipherSuite.TLS_ECDHE_RSA_WITH_RC4_128_SHA: + return KeyExchangeAlgorithm.ECDHE_RSA; + + case CipherSuite.TLS_PSK_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_PSK_WITH_AES_128_CCM: + case CipherSuite.TLS_PSK_WITH_AES_128_CCM_8: + case CipherSuite.TLS_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_PSK_WITH_AES_256_CCM: + case CipherSuite.TLS_PSK_WITH_AES_256_CCM_8: + case CipherSuite.TLS_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_PSK_WITH_NULL_SHA: + case CipherSuite.TLS_PSK_WITH_NULL_SHA256: + case CipherSuite.TLS_PSK_WITH_NULL_SHA384: + case CipherSuite.TLS_PSK_WITH_RC4_128_SHA: + return KeyExchangeAlgorithm.PSK; + + case CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_128_CCM: + case CipherSuite.TLS_RSA_WITH_AES_128_CCM_8: + case CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_256_CCM: + case CipherSuite.TLS_RSA_WITH_AES_256_CCM_8: + case CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_RSA_WITH_NULL_MD5: + case CipherSuite.TLS_RSA_WITH_NULL_SHA: + case CipherSuite.TLS_RSA_WITH_NULL_SHA256: + case CipherSuite.TLS_RSA_WITH_RC4_128_MD5: + case CipherSuite.TLS_RSA_WITH_RC4_128_SHA: + case CipherSuite.TLS_RSA_WITH_SEED_CBC_SHA: + return KeyExchangeAlgorithm.RSA; + + case CipherSuite.TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA: + case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_RC4_128_SHA: + return KeyExchangeAlgorithm.RSA_PSK; + + case CipherSuite.TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_WITH_AES_256_CBC_SHA: + return KeyExchangeAlgorithm.SRP; + + case CipherSuite.TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA: + return KeyExchangeAlgorithm.SRP_DSS; + + case CipherSuite.TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA: + return KeyExchangeAlgorithm.SRP_RSA; + + default: + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + public static int GetMacAlgorithm(int ciphersuite) + { + switch (ciphersuite) + { + case CipherSuite.TLS_DH_anon_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DH_anon_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DH_DSS_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DH_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CCM: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CCM: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM_8: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM_8: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.DRAFT_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_PSK_DHE_WITH_AES_128_CCM_8: + case CipherSuite.TLS_PSK_DHE_WITH_AES_256_CCM_8: + case CipherSuite.TLS_PSK_WITH_AES_128_CCM: + case CipherSuite.TLS_PSK_WITH_AES_128_CCM_8: + case CipherSuite.TLS_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_PSK_WITH_AES_256_CCM: + case CipherSuite.TLS_PSK_WITH_AES_256_CCM_8: + case CipherSuite.TLS_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_128_CCM: + case CipherSuite.TLS_RSA_WITH_AES_128_CCM_8: + case CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_256_CCM: + case CipherSuite.TLS_RSA_WITH_AES_256_CCM_8: + case CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384: + return MacAlgorithm.cls_null; + + case CipherSuite.TLS_DH_anon_WITH_RC4_128_MD5: + case CipherSuite.TLS_RSA_WITH_NULL_MD5: + case CipherSuite.TLS_RSA_WITH_RC4_128_MD5: + return MacAlgorithm.hmac_md5; + + case CipherSuite.TLS_DH_anon_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DH_anon_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DH_anon_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_DH_anon_WITH_SEED_CBC_SHA: + case CipherSuite.TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_DH_DSS_WITH_SEED_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_SEED_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_SEED_CBC_SHA: + case CipherSuite.TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA: + case CipherSuite.TLS_DHE_PSK_WITH_RC4_128_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_SEED_CBC_SHA: + case CipherSuite.TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDH_anon_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDH_anon_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDH_anon_WITH_NULL_SHA: + case CipherSuite.TLS_ECDH_anon_WITH_RC4_128_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_NULL_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_RC4_128_SHA: + case CipherSuite.TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDH_RSA_WITH_NULL_SHA: + case CipherSuite.TLS_ECDH_RSA_WITH_RC4_128_SHA: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_NULL_SHA: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: + case CipherSuite.TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA: + case CipherSuite.TLS_ECDHE_PSK_WITH_RC4_128_SHA: + case CipherSuite.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDHE_RSA_WITH_NULL_SHA: + case CipherSuite.TLS_ECDHE_RSA_WITH_RC4_128_SHA: + case CipherSuite.TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_PSK_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_PSK_WITH_NULL_SHA: + case CipherSuite.TLS_PSK_WITH_RC4_128_SHA: + case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA: + case CipherSuite.TLS_RSA_PSK_WITH_RC4_128_SHA: + case CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_RSA_WITH_NULL_SHA: + case CipherSuite.TLS_RSA_WITH_RC4_128_SHA: + case CipherSuite.TLS_RSA_WITH_SEED_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_WITH_AES_256_CBC_SHA: + return MacAlgorithm.hmac_sha1; + + case CipherSuite.TLS_DH_anon_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DH_anon_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_PSK_WITH_NULL_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_NULL_SHA256: + return MacAlgorithm.hmac_sha256; + + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_PSK_WITH_NULL_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA384: + return MacAlgorithm.hmac_sha384; + + default: + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + public static ProtocolVersion GetMinimumVersion(int ciphersuite) + { + switch (ciphersuite) + { + case CipherSuite.TLS_DH_anon_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DH_anon_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DH_anon_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DH_anon_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CCM: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CCM: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM_8: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM_8: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.DRAFT_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_PSK_DHE_WITH_AES_128_CCM_8: + case CipherSuite.TLS_PSK_DHE_WITH_AES_256_CCM_8: + case CipherSuite.TLS_PSK_WITH_AES_128_CCM: + case CipherSuite.TLS_PSK_WITH_AES_128_CCM_8: + case CipherSuite.TLS_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_PSK_WITH_AES_256_CCM: + case CipherSuite.TLS_PSK_WITH_AES_256_CCM_8: + case CipherSuite.TLS_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.DRAFT_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_128_CCM: + case CipherSuite.TLS_RSA_WITH_AES_128_CCM_8: + case CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_256_CCM: + case CipherSuite.TLS_RSA_WITH_AES_256_CCM_8: + case CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_RSA_WITH_NULL_SHA256: + return ProtocolVersion.TLSv12; + + default: + return ProtocolVersion.SSLv3; + } + } + + public static bool IsAeadCipherSuite(int ciphersuite) + { + return CipherType.aead == GetCipherType(ciphersuite); + } + + public static bool IsBlockCipherSuite(int ciphersuite) + { + return CipherType.block == GetCipherType(ciphersuite); + } + + public static bool IsStreamCipherSuite(int ciphersuite) + { + return CipherType.stream == GetCipherType(ciphersuite); + } + + public static bool IsValidCipherSuiteForSignatureAlgorithms(int cipherSuite, IList sigAlgs) + { + int keyExchangeAlgorithm; + try + { + keyExchangeAlgorithm = GetKeyExchangeAlgorithm(cipherSuite); + } + catch (IOException) + { + return true; + } + + switch (keyExchangeAlgorithm) + { + case KeyExchangeAlgorithm.DH_anon: + case KeyExchangeAlgorithm.DH_anon_EXPORT: + case KeyExchangeAlgorithm.ECDH_anon: + return sigAlgs.Contains(SignatureAlgorithm.anonymous); + + case KeyExchangeAlgorithm.DHE_RSA: + case KeyExchangeAlgorithm.DHE_RSA_EXPORT: + case KeyExchangeAlgorithm.ECDHE_RSA: + case KeyExchangeAlgorithm.SRP_RSA: + return sigAlgs.Contains(SignatureAlgorithm.rsa); + + case KeyExchangeAlgorithm.DHE_DSS: + case KeyExchangeAlgorithm.DHE_DSS_EXPORT: + case KeyExchangeAlgorithm.SRP_DSS: + return sigAlgs.Contains(SignatureAlgorithm.dsa); + + case KeyExchangeAlgorithm.ECDHE_ECDSA: + return sigAlgs.Contains(SignatureAlgorithm.ecdsa); + + default: + return true; + } + } + + public static bool IsValidCipherSuiteForVersion(int cipherSuite, ProtocolVersion serverVersion) + { + return GetMinimumVersion(cipherSuite).IsEqualOrEarlierVersionOf(serverVersion.GetEquivalentTLSVersion()); + } + + public static IList GetUsableSignatureAlgorithms(IList sigHashAlgs) + { + if (sigHashAlgs == null) + return GetAllSignatureAlgorithms(); + + IList v = Platform.CreateArrayList(4); + v.Add(SignatureAlgorithm.anonymous); + foreach (SignatureAndHashAlgorithm sigHashAlg in sigHashAlgs) + { + //if (sigHashAlg.Hash >= MINIMUM_HASH_STRICT) + { + byte sigAlg = sigHashAlg.Signature; + if (!v.Contains(sigAlg)) + { + v.Add(sigAlg); + } + } + } + return v; + } + +#if !PORTABLE || DOTNET + public static bool IsTimeout(SocketException e) + { +#if NET_1_1 + return 10060 == e.ErrorCode; +#else + return SocketError.TimedOut == e.SocketErrorCode; +#endif + } +#endif + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsUtilities.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsUtilities.cs.meta new file mode 100644 index 0000000..639ac54 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/TlsUtilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5c7dae00058149c4eabab3c077072aed +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/UrlAndHash.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/UrlAndHash.cs new file mode 100644 index 0000000..9ffd2cb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/UrlAndHash.cs @@ -0,0 +1,94 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /** + * RFC 6066 5. + */ + public class UrlAndHash + { + protected readonly string mUrl; + protected readonly byte[] mSha1Hash; + + public UrlAndHash(string url, byte[] sha1Hash) + { + if (url == null || url.Length < 1 || url.Length >= (1 << 16)) + throw new ArgumentException("must have length from 1 to (2^16 - 1)", "url"); + if (sha1Hash != null && sha1Hash.Length != 20) + throw new ArgumentException("must have length == 20, if present", "sha1Hash"); + + this.mUrl = url; + this.mSha1Hash = sha1Hash; + } + + public virtual string Url + { + get { return mUrl; } + } + + public virtual byte[] Sha1Hash + { + get { return mSha1Hash; } + } + + /** + * Encode this {@link UrlAndHash} to a {@link Stream}. + * + * @param output the {@link Stream} to encode to. + * @throws IOException + */ + public virtual void Encode(Stream output) + { + byte[] urlEncoding = Strings.ToByteArray(this.mUrl); + TlsUtilities.WriteOpaque16(urlEncoding, output); + + if (this.mSha1Hash == null) + { + TlsUtilities.WriteUint8(0, output); + } + else + { + TlsUtilities.WriteUint8(1, output); + output.Write(this.mSha1Hash, 0, this.mSha1Hash.Length); + } + } + + /** + * Parse a {@link UrlAndHash} from a {@link Stream}. + * + * @param context + * the {@link TlsContext} of the current connection. + * @param input + * the {@link Stream} to parse from. + * @return a {@link UrlAndHash} object. + * @throws IOException + */ + public static UrlAndHash Parse(TlsContext context, Stream input) + { + byte[] urlEncoding = TlsUtilities.ReadOpaque16(input); + if (urlEncoding.Length < 1) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + string url = Strings.FromByteArray(urlEncoding); + + byte[] sha1Hash = null; + byte padding = TlsUtilities.ReadUint8(input); + switch (padding) + { + case 0: + if (TlsUtilities.IsTlsV12(context)) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + break; + case 1: + sha1Hash = TlsUtilities.ReadFully(20, input); + break; + default: + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + return new UrlAndHash(url, sha1Hash); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/UrlAndHash.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/UrlAndHash.cs.meta new file mode 100644 index 0000000..289f656 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/UrlAndHash.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2738f5de85de3af479ead6e5e621f617 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/UseSrtpData.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/UseSrtpData.cs new file mode 100644 index 0000000..fe8f8ac --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/UseSrtpData.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections; +using System.IO; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /** + * RFC 5764 4.1.1 + */ + public class UseSrtpData + { + protected readonly int[] mProtectionProfiles; + protected readonly byte[] mMki; + + /** + * @param protectionProfiles see {@link SrtpProtectionProfile} for valid constants. + * @param mki valid lengths from 0 to 255. + */ + public UseSrtpData(int[] protectionProfiles, byte[] mki) + { + if (protectionProfiles == null || protectionProfiles.Length < 1 + || protectionProfiles.Length >= (1 << 15)) + { + throw new ArgumentException("must have length from 1 to (2^15 - 1)", "protectionProfiles"); + } + + if (mki == null) + { + mki = TlsUtilities.EmptyBytes; + } + else if (mki.Length > 255) + { + throw new ArgumentException("cannot be longer than 255 bytes", "mki"); + } + + this.mProtectionProfiles = protectionProfiles; + this.mMki = mki; + } + + /** + * @return see {@link SrtpProtectionProfile} for valid constants. + */ + public virtual int[] ProtectionProfiles + { + get { return mProtectionProfiles; } + } + + /** + * @return valid lengths from 0 to 255. + */ + public virtual byte[] Mki + { + get { return mMki; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/UseSrtpData.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/UseSrtpData.cs.meta new file mode 100644 index 0000000..88c8bf0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/UseSrtpData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ce6a1a9285195e24fafafee1c80f8aec +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/UserMappingType.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/UserMappingType.cs new file mode 100644 index 0000000..6cff517 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/UserMappingType.cs @@ -0,0 +1,13 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// RFC 4681 + public abstract class UserMappingType + { + /* + * RFC 4681 + */ + public const byte upn_domain_hint = 64; + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/UserMappingType.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/UserMappingType.cs.meta new file mode 100644 index 0000000..0ba252b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/tls/UserMappingType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c8560a8784e13a8489b5103504ec338a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/util.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/util.meta new file mode 100644 index 0000000..52aadbe --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/util.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c6da250a297223e4393e1ba6b72bcbd8 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/util/AlgorithmIdentifierFactory.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/util/AlgorithmIdentifierFactory.cs new file mode 100644 index 0000000..ad4d31e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/util/AlgorithmIdentifierFactory.cs @@ -0,0 +1,106 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Kisa; +using Org.BouncyCastle.Asn1.Misc; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Ntt; +using Org.BouncyCastle.Asn1.Oiw; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Utilities +{ + public class AlgorithmIdentifierFactory + { + public static readonly DerObjectIdentifier IDEA_CBC = new DerObjectIdentifier("1.3.6.1.4.1.188.7.1.1.2"); + public static readonly DerObjectIdentifier CAST5_CBC = new DerObjectIdentifier("1.2.840.113533.7.66.10"); + + private static readonly short[] rc2Table = { + 0xbd, 0x56, 0xea, 0xf2, 0xa2, 0xf1, 0xac, 0x2a, 0xb0, 0x93, 0xd1, 0x9c, 0x1b, 0x33, 0xfd, 0xd0, + 0x30, 0x04, 0xb6, 0xdc, 0x7d, 0xdf, 0x32, 0x4b, 0xf7, 0xcb, 0x45, 0x9b, 0x31, 0xbb, 0x21, 0x5a, + 0x41, 0x9f, 0xe1, 0xd9, 0x4a, 0x4d, 0x9e, 0xda, 0xa0, 0x68, 0x2c, 0xc3, 0x27, 0x5f, 0x80, 0x36, + 0x3e, 0xee, 0xfb, 0x95, 0x1a, 0xfe, 0xce, 0xa8, 0x34, 0xa9, 0x13, 0xf0, 0xa6, 0x3f, 0xd8, 0x0c, + 0x78, 0x24, 0xaf, 0x23, 0x52, 0xc1, 0x67, 0x17, 0xf5, 0x66, 0x90, 0xe7, 0xe8, 0x07, 0xb8, 0x60, + 0x48, 0xe6, 0x1e, 0x53, 0xf3, 0x92, 0xa4, 0x72, 0x8c, 0x08, 0x15, 0x6e, 0x86, 0x00, 0x84, 0xfa, + 0xf4, 0x7f, 0x8a, 0x42, 0x19, 0xf6, 0xdb, 0xcd, 0x14, 0x8d, 0x50, 0x12, 0xba, 0x3c, 0x06, 0x4e, + 0xec, 0xb3, 0x35, 0x11, 0xa1, 0x88, 0x8e, 0x2b, 0x94, 0x99, 0xb7, 0x71, 0x74, 0xd3, 0xe4, 0xbf, + 0x3a, 0xde, 0x96, 0x0e, 0xbc, 0x0a, 0xed, 0x77, 0xfc, 0x37, 0x6b, 0x03, 0x79, 0x89, 0x62, 0xc6, + 0xd7, 0xc0, 0xd2, 0x7c, 0x6a, 0x8b, 0x22, 0xa3, 0x5b, 0x05, 0x5d, 0x02, 0x75, 0xd5, 0x61, 0xe3, + 0x18, 0x8f, 0x55, 0x51, 0xad, 0x1f, 0x0b, 0x5e, 0x85, 0xe5, 0xc2, 0x57, 0x63, 0xca, 0x3d, 0x6c, + 0xb4, 0xc5, 0xcc, 0x70, 0xb2, 0x91, 0x59, 0x0d, 0x47, 0x20, 0xc8, 0x4f, 0x58, 0xe0, 0x01, 0xe2, + 0x16, 0x38, 0xc4, 0x6f, 0x3b, 0x0f, 0x65, 0x46, 0xbe, 0x7e, 0x2d, 0x7b, 0x82, 0xf9, 0x40, 0xb5, + 0x1d, 0x73, 0xf8, 0xeb, 0x26, 0xc7, 0x87, 0x97, 0x25, 0x54, 0xb1, 0x28, 0xaa, 0x98, 0x9d, 0xa5, + 0x64, 0x6d, 0x7a, 0xd4, 0x10, 0x81, 0x44, 0xef, 0x49, 0xd6, 0xae, 0x2e, 0xdd, 0x76, 0x5c, 0x2f, + 0xa7, 0x1c, 0xc9, 0x09, 0x69, 0x9a, 0x83, 0xcf, 0x29, 0x39, 0xb9, 0xe9, 0x4c, 0xff, 0x43, 0xab + }; + + + /** + * Create an AlgorithmIdentifier for the passed in encryption algorithm. + * + * @param encryptionOID OID for the encryption algorithm + * @param keySize key size in bits (-1 if unknown) + * @param random SecureRandom to use for parameter generation. + * @return a full AlgorithmIdentifier including parameters + * @throws IllegalArgumentException if encryptionOID cannot be matched + */ + public static AlgorithmIdentifier GenerateEncryptionAlgID(DerObjectIdentifier encryptionOID, int keySize, SecureRandom random) + + { + if (encryptionOID.Equals(NistObjectIdentifiers.IdAes128Cbc) + || encryptionOID.Equals(NistObjectIdentifiers.IdAes192Cbc) + || encryptionOID.Equals(NistObjectIdentifiers.IdAes256Cbc) + || encryptionOID.Equals(NttObjectIdentifiers.IdCamellia128Cbc) + || encryptionOID.Equals(NttObjectIdentifiers.IdCamellia192Cbc) + || encryptionOID.Equals(NttObjectIdentifiers.IdCamellia256Cbc) + || encryptionOID.Equals(KisaObjectIdentifiers.IdSeedCbc)) + { + byte[] iv = new byte[16]; + + random.NextBytes(iv); + + return new AlgorithmIdentifier(encryptionOID, new DerOctetString(iv)); + } + else if (encryptionOID.Equals(PkcsObjectIdentifiers.DesEde3Cbc) + || encryptionOID.Equals(IDEA_CBC) + || encryptionOID.Equals(OiwObjectIdentifiers.DesCbc)) + { + byte[] iv = new byte[8]; + + random.NextBytes(iv); + + return new AlgorithmIdentifier(encryptionOID, new DerOctetString(iv)); + } + else if (encryptionOID.Equals(CAST5_CBC)) + { + byte[] iv = new byte[8]; + + random.NextBytes(iv); + + Cast5CbcParameters cbcParams = new Cast5CbcParameters(iv, keySize); + + return new AlgorithmIdentifier(encryptionOID, cbcParams); + } + else if (encryptionOID.Equals(PkcsObjectIdentifiers.rc4)) + { + return new AlgorithmIdentifier(encryptionOID, DerNull.Instance); + } + else if (encryptionOID.Equals(PkcsObjectIdentifiers.RC2Cbc)) + { + byte[] iv = new byte[8]; + + random.NextBytes(iv); + + RC2CbcParameter cbcParams = new RC2CbcParameter(rc2Table[128], iv); + + return new AlgorithmIdentifier(encryptionOID, cbcParams); + } + else + { + throw new InvalidOperationException("unable to match algorithm"); + } + } + } +} \ No newline at end of file diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/util/AlgorithmIdentifierFactory.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/util/AlgorithmIdentifierFactory.cs.meta new file mode 100644 index 0000000..4141e6f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/util/AlgorithmIdentifierFactory.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9954f8ac454e76a4b87c5f258437725d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/util/BasicAlphabetMapper.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/util/BasicAlphabetMapper.cs new file mode 100644 index 0000000..b60733f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/util/BasicAlphabetMapper.cs @@ -0,0 +1,106 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Utilities +{ + /** + * A basic alphabet mapper that just creates a mapper based on the + * passed in array of characters. + */ + public class BasicAlphabetMapper + : IAlphabetMapper + { + private readonly IDictionary indexMap = Platform.CreateHashtable(); + private readonly IDictionary charMap = Platform.CreateHashtable(); + + /** + * Base constructor. + * + * @param alphabet a string of characters making up the alphabet. + */ + public BasicAlphabetMapper(string alphabet) : + this(alphabet.ToCharArray()) + { + } + + /** + * Base constructor. + * + * @param alphabet an array of characters making up the alphabet. + */ + public BasicAlphabetMapper(char[] alphabet) + { + for (int i = 0; i != alphabet.Length; i++) + { + if (indexMap.Contains(alphabet[i])) + { + throw new ArgumentException("duplicate key detected in alphabet: " + alphabet[i]); + } + indexMap.Add(alphabet[i], i); + charMap.Add(i, alphabet[i]); + } + } + + public int Radix + { + get { return indexMap.Count; } + } + + public byte[] ConvertToIndexes(char[] input) + { + byte[] outBuf; + + if (indexMap.Count <= 256) + { + outBuf = new byte[input.Length]; + for (int i = 0; i != input.Length; i++) + { + outBuf[i] = (byte)(int)indexMap[input[i]]; + } + } + else + { + outBuf = new byte[input.Length * 2]; + for (int i = 0; i != input.Length; i++) + { + int idx = (int)indexMap[input[i]]; + outBuf[i * 2] = (byte)((idx >> 8) & 0xff); + outBuf[i * 2 + 1] = (byte)(idx & 0xff); + } + } + + return outBuf; + } + + public char[] ConvertToChars(byte[] input) + { + char[] outBuf; + + if (charMap.Count <= 256) + { + outBuf = new char[input.Length]; + for (int i = 0; i != input.Length; i++) + { + outBuf[i] = (char)charMap[input[i] & 0xff]; + } + } + else + { + if ((input.Length & 0x1) != 0) + { + throw new ArgumentException("two byte radix and input string odd.Length"); + } + + outBuf = new char[input.Length / 2]; + for (int i = 0; i != input.Length; i += 2) + { + outBuf[i / 2] = (char)charMap[((input[i] << 8) & 0xff00) | (input[i + 1] & 0xff)]; + } + } + + return outBuf; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/util/BasicAlphabetMapper.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/util/BasicAlphabetMapper.cs.meta new file mode 100644 index 0000000..9e639af --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/util/BasicAlphabetMapper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7137d282bbddd7844af70074bcbade23 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/util/CipherFactory.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/util/CipherFactory.cs new file mode 100644 index 0000000..f599826 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/util/CipherFactory.cs @@ -0,0 +1,145 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Kisa; +using Org.BouncyCastle.Asn1.Misc; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Ntt; +using Org.BouncyCastle.Asn1.Oiw; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Modes; +using Org.BouncyCastle.Crypto.Paddings; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Utilities +{ + public class CipherFactory + { + private CipherFactory() + { + } + + private static readonly short[] rc2Ekb = + { + 0x5d, 0xbe, 0x9b, 0x8b, 0x11, 0x99, 0x6e, 0x4d, 0x59, 0xf3, 0x85, 0xa6, 0x3f, 0xb7, 0x83, 0xc5, + 0xe4, 0x73, 0x6b, 0x3a, 0x68, 0x5a, 0xc0, 0x47, 0xa0, 0x64, 0x34, 0x0c, 0xf1, 0xd0, 0x52, 0xa5, + 0xb9, 0x1e, 0x96, 0x43, 0x41, 0xd8, 0xd4, 0x2c, 0xdb, 0xf8, 0x07, 0x77, 0x2a, 0xca, 0xeb, 0xef, + 0x10, 0x1c, 0x16, 0x0d, 0x38, 0x72, 0x2f, 0x89, 0xc1, 0xf9, 0x80, 0xc4, 0x6d, 0xae, 0x30, 0x3d, + 0xce, 0x20, 0x63, 0xfe, 0xe6, 0x1a, 0xc7, 0xb8, 0x50, 0xe8, 0x24, 0x17, 0xfc, 0x25, 0x6f, 0xbb, + 0x6a, 0xa3, 0x44, 0x53, 0xd9, 0xa2, 0x01, 0xab, 0xbc, 0xb6, 0x1f, 0x98, 0xee, 0x9a, 0xa7, 0x2d, + 0x4f, 0x9e, 0x8e, 0xac, 0xe0, 0xc6, 0x49, 0x46, 0x29, 0xf4, 0x94, 0x8a, 0xaf, 0xe1, 0x5b, 0xc3, + 0xb3, 0x7b, 0x57, 0xd1, 0x7c, 0x9c, 0xed, 0x87, 0x40, 0x8c, 0xe2, 0xcb, 0x93, 0x14, 0xc9, 0x61, + 0x2e, 0xe5, 0xcc, 0xf6, 0x5e, 0xa8, 0x5c, 0xd6, 0x75, 0x8d, 0x62, 0x95, 0x58, 0x69, 0x76, 0xa1, + 0x4a, 0xb5, 0x55, 0x09, 0x78, 0x33, 0x82, 0xd7, 0xdd, 0x79, 0xf5, 0x1b, 0x0b, 0xde, 0x26, 0x21, + 0x28, 0x74, 0x04, 0x97, 0x56, 0xdf, 0x3c, 0xf0, 0x37, 0x39, 0xdc, 0xff, 0x06, 0xa4, 0xea, 0x42, + 0x08, 0xda, 0xb4, 0x71, 0xb0, 0xcf, 0x12, 0x7a, 0x4e, 0xfa, 0x6c, 0x1d, 0x84, 0x00, 0xc8, 0x7f, + 0x91, 0x45, 0xaa, 0x2b, 0xc2, 0xb1, 0x8f, 0xd5, 0xba, 0xf2, 0xad, 0x19, 0xb2, 0x67, 0x36, 0xf7, + 0x0f, 0x0a, 0x92, 0x7d, 0xe3, 0x9d, 0xe9, 0x90, 0x3e, 0x23, 0x27, 0x66, 0x13, 0xec, 0x81, 0x15, + 0xbd, 0x22, 0xbf, 0x9f, 0x7e, 0xa9, 0x51, 0x4b, 0x4c, 0xfb, 0x02, 0xd3, 0x70, 0x86, 0x31, 0xe7, + 0x3b, 0x05, 0x03, 0x54, 0x60, 0x48, 0x65, 0x18, 0xd2, 0xcd, 0x5f, 0x32, 0x88, 0x0e, 0x35, 0xfd + }; + + public static object CreateContentCipher(bool forEncryption, ICipherParameters encKey, + AlgorithmIdentifier encryptionAlgID) + { + DerObjectIdentifier encAlg = encryptionAlgID.Algorithm; + + if (encAlg.Equals(PkcsObjectIdentifiers.rc4)) + { + IStreamCipher cipher = new RC4Engine(); + cipher.Init(forEncryption, encKey); + return cipher; + } + else + { + BufferedBlockCipher cipher = CreateCipher(encryptionAlgID.Algorithm); + Asn1Object sParams = encryptionAlgID.Parameters.ToAsn1Object(); + + if (sParams != null && !(sParams is DerNull)) + { + if (encAlg.Equals(PkcsObjectIdentifiers.DesEde3Cbc) + || encAlg.Equals(AlgorithmIdentifierFactory.IDEA_CBC) + || encAlg.Equals(NistObjectIdentifiers.IdAes128Cbc) + || encAlg.Equals(NistObjectIdentifiers.IdAes192Cbc) + || encAlg.Equals(NistObjectIdentifiers.IdAes256Cbc) + || encAlg.Equals(NttObjectIdentifiers.IdCamellia128Cbc) + || encAlg.Equals(NttObjectIdentifiers.IdCamellia192Cbc) + || encAlg.Equals(NttObjectIdentifiers.IdCamellia256Cbc) + || encAlg.Equals(KisaObjectIdentifiers.IdSeedCbc) + || encAlg.Equals(OiwObjectIdentifiers.DesCbc)) + { + cipher.Init(forEncryption, new ParametersWithIV(encKey, + Asn1OctetString.GetInstance(sParams).GetOctets())); + } + else if (encAlg.Equals(AlgorithmIdentifierFactory.CAST5_CBC)) + { + Cast5CbcParameters cbcParams = Cast5CbcParameters.GetInstance(sParams); + + cipher.Init(forEncryption, new ParametersWithIV(encKey, cbcParams.GetIV())); + } + else if (encAlg.Equals(PkcsObjectIdentifiers.RC2Cbc)) + { + RC2CbcParameter cbcParams = RC2CbcParameter.GetInstance(sParams); + + cipher.Init(forEncryption, new ParametersWithIV(new RC2Parameters(((KeyParameter)encKey).GetKey(), rc2Ekb[cbcParams.RC2ParameterVersion.IntValue]), cbcParams.GetIV())); + } + else + { + throw new InvalidOperationException("cannot match parameters"); + } + } + else + { + if (encAlg.Equals(PkcsObjectIdentifiers.DesEde3Cbc) + || encAlg.Equals(AlgorithmIdentifierFactory.IDEA_CBC) + || encAlg.Equals(AlgorithmIdentifierFactory.CAST5_CBC)) + { + cipher.Init(forEncryption, new ParametersWithIV(encKey, new byte[8])); + } + else + { + cipher.Init(forEncryption, encKey); + } + } + + return cipher; + } + } + + private static BufferedBlockCipher CreateCipher(DerObjectIdentifier algorithm) + { + IBlockCipher cipher; + + if (NistObjectIdentifiers.IdAes128Cbc.Equals(algorithm) + || NistObjectIdentifiers.IdAes192Cbc.Equals(algorithm) + || NistObjectIdentifiers.IdAes256Cbc.Equals(algorithm)) + { + cipher = new CbcBlockCipher(new AesEngine()); + } + else if (PkcsObjectIdentifiers.DesEde3Cbc.Equals(algorithm)) + { + cipher = new CbcBlockCipher(new DesEdeEngine()); + } + else if (OiwObjectIdentifiers.DesCbc.Equals(algorithm)) + { + cipher = new CbcBlockCipher(new DesEngine()); + } + else if (PkcsObjectIdentifiers.RC2Cbc.Equals(algorithm)) + { + cipher = new CbcBlockCipher(new RC2Engine()); + } + else if (MiscObjectIdentifiers.cast5CBC.Equals(algorithm)) + { + cipher = new CbcBlockCipher(new Cast5Engine()); + } + else + { + throw new InvalidOperationException("cannot recognise cipher: " + algorithm); + } + + return new PaddedBufferedBlockCipher(cipher, new Pkcs7Padding()); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/util/CipherFactory.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/util/CipherFactory.cs.meta new file mode 100644 index 0000000..bf2b04e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/util/CipherFactory.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5207e82cd05b8244496cf5d48f750477 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/util/CipherKeyGeneratorFactory.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/util/CipherKeyGeneratorFactory.cs new file mode 100644 index 0000000..efaad13 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/util/CipherKeyGeneratorFactory.cs @@ -0,0 +1,95 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Kisa; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Ntt; +using Org.BouncyCastle.Asn1.Oiw; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Utilities +{ + public class CipherKeyGeneratorFactory + { + private CipherKeyGeneratorFactory() + { + } + + /** + * Create a key generator for the passed in Object Identifier. + * + * @param algorithm the Object Identifier indicating the algorithn the generator is for. + * @param random a source of random to initialise the generator with. + * @return an initialised CipherKeyGenerator. + * @throws IllegalArgumentException if the algorithm cannot be identified. + */ + public static CipherKeyGenerator CreateKeyGenerator(DerObjectIdentifier algorithm, SecureRandom random) + { + if (NistObjectIdentifiers.IdAes128Cbc.Equals(algorithm)) + { + return CreateCipherKeyGenerator(random, 128); + } + else if (NistObjectIdentifiers.IdAes192Cbc.Equals(algorithm)) + { + return CreateCipherKeyGenerator(random, 192); + } + else if (NistObjectIdentifiers.IdAes256Cbc.Equals(algorithm)) + { + return CreateCipherKeyGenerator(random, 256); + } + else if (PkcsObjectIdentifiers.DesEde3Cbc.Equals(algorithm)) + { + DesEdeKeyGenerator keyGen = new DesEdeKeyGenerator(); + keyGen.Init(new KeyGenerationParameters(random, 192)); + return keyGen; + } + else if (NttObjectIdentifiers.IdCamellia128Cbc.Equals(algorithm)) + { + return CreateCipherKeyGenerator(random, 128); + } + else if (NttObjectIdentifiers.IdCamellia192Cbc.Equals(algorithm)) + { + return CreateCipherKeyGenerator(random, 192); + } + else if (NttObjectIdentifiers.IdCamellia256Cbc.Equals(algorithm)) + { + return CreateCipherKeyGenerator(random, 256); + } + else if (KisaObjectIdentifiers.IdSeedCbc.Equals(algorithm)) + { + return CreateCipherKeyGenerator(random, 128); + } + else if (AlgorithmIdentifierFactory.CAST5_CBC.Equals(algorithm)) + { + return CreateCipherKeyGenerator(random, 128); + } + else if (OiwObjectIdentifiers.DesCbc.Equals(algorithm)) + { + DesKeyGenerator keyGen = new DesKeyGenerator(); + keyGen.Init(new KeyGenerationParameters(random, 64)); + return keyGen; + } + else if (PkcsObjectIdentifiers.rc4.Equals(algorithm)) + { + return CreateCipherKeyGenerator(random, 128); + } + else if (PkcsObjectIdentifiers.RC2Cbc.Equals(algorithm)) + { + return CreateCipherKeyGenerator(random, 128); + } + else + { + throw new InvalidOperationException("cannot recognise cipher: " + algorithm); + } + } + + private static CipherKeyGenerator CreateCipherKeyGenerator(SecureRandom random, int keySize) + { + CipherKeyGenerator keyGen = new CipherKeyGenerator(); + keyGen.Init(new KeyGenerationParameters(random, keySize)); + return keyGen; + } + } +} \ No newline at end of file diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/util/CipherKeyGeneratorFactory.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/util/CipherKeyGeneratorFactory.cs.meta new file mode 100644 index 0000000..000076b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/util/CipherKeyGeneratorFactory.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e9c5d0b93b5691a419ada3e3842ef9bc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/util/Pack.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/util/Pack.cs new file mode 100644 index 0000000..8ba738d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/util/Pack.cs @@ -0,0 +1,436 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Utilities +{ + internal sealed class Pack + { + private Pack() + { + } + + internal static void UInt16_To_BE(ushort n, byte[] bs) + { + bs[0] = (byte)(n >> 8); + bs[1] = (byte)(n); + } + + internal static void UInt16_To_BE(ushort n, byte[] bs, int off) + { + bs[off] = (byte)(n >> 8); + bs[off + 1] = (byte)(n); + } + + internal static void UInt16_To_BE(ushort[] ns, byte[] bs, int off) + { + for (int i = 0; i < ns.Length; ++i) + { + UInt16_To_BE(ns[i], bs, off); + off += 2; + } + } + + internal static void UInt16_To_BE(ushort[] ns, int nsOff, int nsLen, byte[] bs, int bsOff) + { + for (int i = 0; i < nsLen; ++i) + { + UInt16_To_BE(ns[nsOff + i], bs, bsOff); + bsOff += 2; + } + } + + internal static byte[] UInt16_To_BE(ushort n) + { + byte[] bs = new byte[2]; + UInt16_To_BE(n, bs, 0); + return bs; + } + + internal static byte[] UInt16_To_BE(ushort[] ns) + { + return UInt16_To_BE(ns, 0, ns.Length); + } + + internal static byte[] UInt16_To_BE(ushort[] ns, int nsOff, int nsLen) + { + byte[] bs = new byte[2 * nsLen]; + UInt16_To_BE(ns, nsOff, nsLen, bs, 0); + return bs; + } + + internal static ushort BE_To_UInt16(byte[] bs, int off) + { + uint n = (uint)bs[off] << 8 + | (uint)bs[off + 1]; + return (ushort)n; + } + + internal static void BE_To_UInt16(byte[] bs, int bsOff, ushort[] ns, int nsOff) + { + ns[nsOff] = BE_To_UInt16(bs, bsOff); + } + + internal static ushort[] BE_To_UInt16(byte[] bs) + { + return BE_To_UInt16(bs, 0, bs.Length); + } + + internal static ushort[] BE_To_UInt16(byte[] bs, int off, int len) + { + if ((len & 1) != 0) + throw new ArgumentException("must be a multiple of 2", "len"); + + ushort[] ns = new ushort[len / 2]; + for (int i = 0; i < len; i += 2) + { + BE_To_UInt16(bs, off + i, ns, i >> 1); + } + return ns; + } + + internal static void UInt32_To_BE(uint n, byte[] bs) + { + bs[0] = (byte)(n >> 24); + bs[1] = (byte)(n >> 16); + bs[2] = (byte)(n >> 8); + bs[3] = (byte)(n); + } + + internal static void UInt32_To_BE(uint n, byte[] bs, int off) + { + bs[off] = (byte)(n >> 24); + bs[off + 1] = (byte)(n >> 16); + bs[off + 2] = (byte)(n >> 8); + bs[off + 3] = (byte)(n); + } + + internal static void UInt32_To_BE(uint[] ns, byte[] bs, int off) + { + for (int i = 0; i < ns.Length; ++i) + { + UInt32_To_BE(ns[i], bs, off); + off += 4; + } + } + + internal static void UInt32_To_BE(uint[] ns, int nsOff, int nsLen, byte[] bs, int bsOff) + { + for (int i = 0; i < nsLen; ++i) + { + UInt32_To_BE(ns[nsOff + i], bs, bsOff); + bsOff += 4; + } + } + + internal static byte[] UInt32_To_BE(uint n) + { + byte[] bs = new byte[4]; + UInt32_To_BE(n, bs, 0); + return bs; + } + + internal static byte[] UInt32_To_BE(uint[] ns) + { + byte[] bs = new byte[4 * ns.Length]; + UInt32_To_BE(ns, bs, 0); + return bs; + } + + internal static uint BE_To_UInt32(byte[] bs) + { + return (uint)bs[0] << 24 + | (uint)bs[1] << 16 + | (uint)bs[2] << 8 + | (uint)bs[3]; + } + + internal static uint BE_To_UInt32(byte[] bs, int off) + { + return (uint)bs[off] << 24 + | (uint)bs[off + 1] << 16 + | (uint)bs[off + 2] << 8 + | (uint)bs[off + 3]; + } + + internal static void BE_To_UInt32(byte[] bs, int off, uint[] ns) + { + for (int i = 0; i < ns.Length; ++i) + { + ns[i] = BE_To_UInt32(bs, off); + off += 4; + } + } + + internal static void BE_To_UInt32(byte[] bs, int bsOff, uint[] ns, int nsOff, int nsLen) + { + for (int i = 0; i < nsLen; ++i) + { + ns[nsOff + i] = BE_To_UInt32(bs, bsOff); + bsOff += 4; + } + } + + internal static byte[] UInt64_To_BE(ulong n) + { + byte[] bs = new byte[8]; + UInt64_To_BE(n, bs, 0); + return bs; + } + + internal static void UInt64_To_BE(ulong n, byte[] bs) + { + UInt32_To_BE((uint)(n >> 32), bs); + UInt32_To_BE((uint)(n), bs, 4); + } + + internal static void UInt64_To_BE(ulong n, byte[] bs, int off) + { + UInt32_To_BE((uint)(n >> 32), bs, off); + UInt32_To_BE((uint)(n), bs, off + 4); + } + + internal static byte[] UInt64_To_BE(ulong[] ns) + { + byte[] bs = new byte[8 * ns.Length]; + UInt64_To_BE(ns, bs, 0); + return bs; + } + + internal static void UInt64_To_BE(ulong[] ns, byte[] bs, int off) + { + for (int i = 0; i < ns.Length; ++i) + { + UInt64_To_BE(ns[i], bs, off); + off += 8; + } + } + + internal static void UInt64_To_BE(ulong[] ns, int nsOff, int nsLen, byte[] bs, int bsOff) + { + for (int i = 0; i < nsLen; ++i) + { + UInt64_To_BE(ns[nsOff + i], bs, bsOff); + bsOff += 8; + } + } + + internal static ulong BE_To_UInt64(byte[] bs, int off) + { + uint hi = BE_To_UInt32(bs, off); + uint lo = BE_To_UInt32(bs, off + 4); + return ((ulong)hi << 32) | (ulong)lo; + } + + internal static void BE_To_UInt64(byte[] bs, int off, ulong[] ns) + { + for (int i = 0; i < ns.Length; ++i) + { + ns[i] = BE_To_UInt64(bs, off); + off += 8; + } + } + + internal static void BE_To_UInt64(byte[] bs, int bsOff, ulong[] ns, int nsOff, int nsLen) + { + for (int i = 0; i < nsLen; ++i) + { + ns[nsOff + i] = BE_To_UInt64(bs, bsOff); + bsOff += 8; + } + } + + internal static void UInt16_To_LE(ushort n, byte[] bs) + { + bs[0] = (byte)(n); + bs[1] = (byte)(n >> 8); + } + + internal static void UInt16_To_LE(ushort n, byte[] bs, int off) + { + bs[off] = (byte)(n); + bs[off + 1] = (byte)(n >> 8); + } + + internal static ushort LE_To_UInt16(byte[] bs) + { + uint n = (uint)bs[0] + | (uint)bs[1] << 8; + return (ushort)n; + } + + internal static ushort LE_To_UInt16(byte[] bs, int off) + { + uint n = (uint)bs[off] + | (uint)bs[off + 1] << 8; + return (ushort)n; + } + + internal static byte[] UInt32_To_LE(uint n) + { + byte[] bs = new byte[4]; + UInt32_To_LE(n, bs, 0); + return bs; + } + + internal static void UInt32_To_LE(uint n, byte[] bs) + { + bs[0] = (byte)(n); + bs[1] = (byte)(n >> 8); + bs[2] = (byte)(n >> 16); + bs[3] = (byte)(n >> 24); + } + + internal static void UInt32_To_LE(uint n, byte[] bs, int off) + { + bs[off] = (byte)(n); + bs[off + 1] = (byte)(n >> 8); + bs[off + 2] = (byte)(n >> 16); + bs[off + 3] = (byte)(n >> 24); + } + + internal static byte[] UInt32_To_LE(uint[] ns) + { + byte[] bs = new byte[4 * ns.Length]; + UInt32_To_LE(ns, bs, 0); + return bs; + } + + internal static void UInt32_To_LE(uint[] ns, byte[] bs, int off) + { + for (int i = 0; i < ns.Length; ++i) + { + UInt32_To_LE(ns[i], bs, off); + off += 4; + } + } + + internal static void UInt32_To_LE(uint[] ns, int nsOff, int nsLen, byte[] bs, int bsOff) + { + for (int i = 0; i < nsLen; ++i) + { + UInt32_To_LE(ns[nsOff + i], bs, bsOff); + bsOff += 4; + } + } + + internal static uint LE_To_UInt32(byte[] bs) + { + return (uint)bs[0] + | (uint)bs[1] << 8 + | (uint)bs[2] << 16 + | (uint)bs[3] << 24; + } + + internal static uint LE_To_UInt32(byte[] bs, int off) + { + return (uint)bs[off] + | (uint)bs[off + 1] << 8 + | (uint)bs[off + 2] << 16 + | (uint)bs[off + 3] << 24; + } + + internal static void LE_To_UInt32(byte[] bs, int off, uint[] ns) + { + for (int i = 0; i < ns.Length; ++i) + { + ns[i] = LE_To_UInt32(bs, off); + off += 4; + } + } + + internal static void LE_To_UInt32(byte[] bs, int bOff, uint[] ns, int nOff, int count) + { + for (int i = 0; i < count; ++i) + { + ns[nOff + i] = LE_To_UInt32(bs, bOff); + bOff += 4; + } + } + + internal static uint[] LE_To_UInt32(byte[] bs, int off, int count) + { + uint[] ns = new uint[count]; + for (int i = 0; i < ns.Length; ++i) + { + ns[i] = LE_To_UInt32(bs, off); + off += 4; + } + return ns; + } + + internal static byte[] UInt64_To_LE(ulong n) + { + byte[] bs = new byte[8]; + UInt64_To_LE(n, bs, 0); + return bs; + } + + internal static void UInt64_To_LE(ulong n, byte[] bs) + { + UInt32_To_LE((uint)(n), bs); + UInt32_To_LE((uint)(n >> 32), bs, 4); + } + + internal static void UInt64_To_LE(ulong n, byte[] bs, int off) + { + UInt32_To_LE((uint)(n), bs, off); + UInt32_To_LE((uint)(n >> 32), bs, off + 4); + } + + internal static byte[] UInt64_To_LE(ulong[] ns) + { + byte[] bs = new byte[8 * ns.Length]; + UInt64_To_LE(ns, bs, 0); + return bs; + } + + internal static void UInt64_To_LE(ulong[] ns, byte[] bs, int off) + { + for (int i = 0; i < ns.Length; ++i) + { + UInt64_To_LE(ns[i], bs, off); + off += 8; + } + } + + internal static void UInt64_To_LE(ulong[] ns, int nsOff, int nsLen, byte[] bs, int bsOff) + { + for (int i = 0; i < nsLen; ++i) + { + UInt64_To_LE(ns[nsOff + i], bs, bsOff); + bsOff += 8; + } + } + + internal static ulong LE_To_UInt64(byte[] bs) + { + uint lo = LE_To_UInt32(bs); + uint hi = LE_To_UInt32(bs, 4); + return ((ulong)hi << 32) | (ulong)lo; + } + + internal static ulong LE_To_UInt64(byte[] bs, int off) + { + uint lo = LE_To_UInt32(bs, off); + uint hi = LE_To_UInt32(bs, off + 4); + return ((ulong)hi << 32) | (ulong)lo; + } + + internal static void LE_To_UInt64(byte[] bs, int off, ulong[] ns) + { + for (int i = 0; i < ns.Length; ++i) + { + ns[i] = LE_To_UInt64(bs, off); + off += 8; + } + } + + internal static void LE_To_UInt64(byte[] bs, int bsOff, ulong[] ns, int nsOff, int nsLen) + { + for (int i = 0; i < nsLen; ++i) + { + ns[nsOff + i] = LE_To_UInt64(bs, bsOff); + bsOff += 8; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/util/Pack.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/util/Pack.cs.meta new file mode 100644 index 0000000..ee74249 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/crypto/util/Pack.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e2b450a5271aa1341928da7c9c7a0317 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math.meta new file mode 100644 index 0000000..8365a70 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b4b7c1cae6f7eda4f89b94443a7683a8 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/BigInteger.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/BigInteger.cs new file mode 100644 index 0000000..3badb6d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/BigInteger.cs @@ -0,0 +1,3624 @@ +using System; +using System.Collections; +using System.Diagnostics; +using System.Globalization; +using System.Text; + +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math +{ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE) + [Serializable] +#endif + public class BigInteger + { + // The first few odd primes + /* + 3 5 7 11 13 17 19 23 29 + 31 37 41 43 47 53 59 61 67 71 + 73 79 83 89 97 101 103 107 109 113 + 127 131 137 139 149 151 157 163 167 173 + 179 181 191 193 197 199 211 223 227 229 + 233 239 241 251 257 263 269 271 277 281 + 283 293 307 311 313 317 331 337 347 349 + 353 359 367 373 379 383 389 397 401 409 + 419 421 431 433 439 443 449 457 461 463 + 467 479 487 491 499 503 509 521 523 541 + 547 557 563 569 571 577 587 593 599 601 + 607 613 617 619 631 641 643 647 653 659 + 661 673 677 683 691 701 709 719 727 733 + 739 743 751 757 761 769 773 787 797 809 + 811 821 823 827 829 839 853 857 859 863 + 877 881 883 887 907 911 919 929 937 941 + 947 953 967 971 977 983 991 997 1009 + 1013 1019 1021 1031 1033 1039 1049 1051 + 1061 1063 1069 1087 1091 1093 1097 1103 + 1109 1117 1123 1129 1151 1153 1163 1171 + 1181 1187 1193 1201 1213 1217 1223 1229 + 1231 1237 1249 1259 1277 1279 1283 1289 + */ + + // Each list has a product < 2^31 + internal static readonly int[][] primeLists = new int[][] + { + new int[]{ 3, 5, 7, 11, 13, 17, 19, 23 }, + new int[]{ 29, 31, 37, 41, 43 }, + new int[]{ 47, 53, 59, 61, 67 }, + new int[]{ 71, 73, 79, 83 }, + new int[]{ 89, 97, 101, 103 }, + + new int[]{ 107, 109, 113, 127 }, + new int[]{ 131, 137, 139, 149 }, + new int[]{ 151, 157, 163, 167 }, + new int[]{ 173, 179, 181, 191 }, + new int[]{ 193, 197, 199, 211 }, + + new int[]{ 223, 227, 229 }, + new int[]{ 233, 239, 241 }, + new int[]{ 251, 257, 263 }, + new int[]{ 269, 271, 277 }, + new int[]{ 281, 283, 293 }, + + new int[]{ 307, 311, 313 }, + new int[]{ 317, 331, 337 }, + new int[]{ 347, 349, 353 }, + new int[]{ 359, 367, 373 }, + new int[]{ 379, 383, 389 }, + + new int[]{ 397, 401, 409 }, + new int[]{ 419, 421, 431 }, + new int[]{ 433, 439, 443 }, + new int[]{ 449, 457, 461 }, + new int[]{ 463, 467, 479 }, + + new int[]{ 487, 491, 499 }, + new int[]{ 503, 509, 521 }, + new int[]{ 523, 541, 547 }, + new int[]{ 557, 563, 569 }, + new int[]{ 571, 577, 587 }, + + new int[]{ 593, 599, 601 }, + new int[]{ 607, 613, 617 }, + new int[]{ 619, 631, 641 }, + new int[]{ 643, 647, 653 }, + new int[]{ 659, 661, 673 }, + + new int[]{ 677, 683, 691 }, + new int[]{ 701, 709, 719 }, + new int[]{ 727, 733, 739 }, + new int[]{ 743, 751, 757 }, + new int[]{ 761, 769, 773 }, + + new int[]{ 787, 797, 809 }, + new int[]{ 811, 821, 823 }, + new int[]{ 827, 829, 839 }, + new int[]{ 853, 857, 859 }, + new int[]{ 863, 877, 881 }, + + new int[]{ 883, 887, 907 }, + new int[]{ 911, 919, 929 }, + new int[]{ 937, 941, 947 }, + new int[]{ 953, 967, 971 }, + new int[]{ 977, 983, 991 }, + + new int[]{ 997, 1009, 1013 }, + new int[]{ 1019, 1021, 1031 }, + new int[]{ 1033, 1039, 1049 }, + new int[]{ 1051, 1061, 1063 }, + new int[]{ 1069, 1087, 1091 }, + + new int[]{ 1093, 1097, 1103 }, + new int[]{ 1109, 1117, 1123 }, + new int[]{ 1129, 1151, 1153 }, + new int[]{ 1163, 1171, 1181 }, + new int[]{ 1187, 1193, 1201 }, + + new int[]{ 1213, 1217, 1223 }, + new int[]{ 1229, 1231, 1237 }, + new int[]{ 1249, 1259, 1277 }, + new int[]{ 1279, 1283, 1289 }, + }; + + internal static readonly int[] primeProducts; + + private const long IMASK = 0xFFFFFFFFL; + private const ulong UIMASK = 0xFFFFFFFFUL; + + private static readonly int[] ZeroMagnitude = new int[0]; + private static readonly byte[] ZeroEncoding = new byte[0]; + + private static readonly BigInteger[] SMALL_CONSTANTS = new BigInteger[17]; + public static readonly BigInteger Zero; + public static readonly BigInteger One; + public static readonly BigInteger Two; + public static readonly BigInteger Three; + public static readonly BigInteger Four; + public static readonly BigInteger Ten; + + //private readonly static byte[] BitCountTable = + //{ + // 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, + // 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + // 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + // 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + // 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + // 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + // 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + // 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + // 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + // 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + // 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + // 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + // 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + // 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + // 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + // 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 + //}; + + private readonly static byte[] BitLengthTable = + { + 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 + }; + + // TODO Parse radix-2 64 bits at a time and radix-8 63 bits at a time + private const int chunk2 = 1, chunk8 = 1, chunk10 = 19, chunk16 = 16; + private static readonly BigInteger radix2, radix2E, radix8, radix8E, radix10, radix10E, radix16, radix16E; + + private static readonly SecureRandom RandomSource = new SecureRandom(); + + /* + * These are the threshold bit-lengths (of an exponent) where we increase the window size. + * They are calculated according to the expected savings in multiplications. + * Some squares will also be saved on average, but we offset these against the extra storage costs. + */ + private static readonly int[] ExpWindowThresholds = { 7, 25, 81, 241, 673, 1793, 4609, Int32.MaxValue }; + + private const int BitsPerByte = 8; + private const int BitsPerInt = 32; + private const int BytesPerInt = 4; + + static BigInteger() + { + Zero = new BigInteger(0, ZeroMagnitude, false); + Zero.nBits = 0; Zero.nBitLength = 0; + + SMALL_CONSTANTS[0] = Zero; + for (uint i = 1; i < SMALL_CONSTANTS.Length; ++i) + { + SMALL_CONSTANTS[i] = CreateUValueOf(i); + } + + One = SMALL_CONSTANTS[1]; + Two = SMALL_CONSTANTS[2]; + Three = SMALL_CONSTANTS[3]; + Four = SMALL_CONSTANTS[4]; + Ten = SMALL_CONSTANTS[10]; + + radix2 = ValueOf(2); + radix2E = radix2.Pow(chunk2); + + radix8 = ValueOf(8); + radix8E = radix8.Pow(chunk8); + + radix10 = ValueOf(10); + radix10E = radix10.Pow(chunk10); + + radix16 = ValueOf(16); + radix16E = radix16.Pow(chunk16); + + primeProducts = new int[primeLists.Length]; + + for (int i = 0; i < primeLists.Length; ++i) + { + int[] primeList = primeLists[i]; + int product = primeList[0]; + for (int j = 1; j < primeList.Length; ++j) + { + product *= primeList[j]; + } + primeProducts[i] = product; + } + } + + private int[] magnitude; // array of ints with [0] being the most significant + private int sign; // -1 means -ve; +1 means +ve; 0 means 0; + private int nBits = -1; // cache BitCount() value + private int nBitLength = -1; // cache BitLength() value + private int mQuote = 0; // -m^(-1) mod b, b = 2^32 (see Montgomery mult.), 0 when uninitialised + + private static int GetByteLength( + int nBits) + { + return (nBits + BitsPerByte - 1) / BitsPerByte; + } + + public static BigInteger Arbitrary(int sizeInBits) + { + return new BigInteger(sizeInBits, RandomSource); + } + + private BigInteger( + int signum, + int[] mag, + bool checkMag) + { + if (checkMag) + { + int i = 0; + while (i < mag.Length && mag[i] == 0) + { + ++i; + } + + if (i == mag.Length) + { + this.sign = 0; + this.magnitude = ZeroMagnitude; + } + else + { + this.sign = signum; + + if (i == 0) + { + this.magnitude = mag; + } + else + { + // strip leading 0 words + this.magnitude = new int[mag.Length - i]; + Array.Copy(mag, i, this.magnitude, 0, this.magnitude.Length); + } + } + } + else + { + this.sign = signum; + this.magnitude = mag; + } + } + + public BigInteger( + string value) + : this(value, 10) + { + } + + public BigInteger( + string str, + int radix) + { + if (str.Length == 0) + throw new FormatException("Zero length BigInteger"); + + NumberStyles style; + int chunk; + BigInteger r; + BigInteger rE; + + switch (radix) + { + case 2: + // Is there anyway to restrict to binary digits? + style = NumberStyles.Integer; + chunk = chunk2; + r = radix2; + rE = radix2E; + break; + case 8: + // Is there anyway to restrict to octal digits? + style = NumberStyles.Integer; + chunk = chunk8; + r = radix8; + rE = radix8E; + break; + case 10: + // This style seems to handle spaces and minus sign already (our processing redundant?) + style = NumberStyles.Integer; + chunk = chunk10; + r = radix10; + rE = radix10E; + break; + case 16: + // TODO Should this be HexNumber? + style = NumberStyles.AllowHexSpecifier; + chunk = chunk16; + r = radix16; + rE = radix16E; + break; + default: + throw new FormatException("Only bases 2, 8, 10, or 16 allowed"); + } + + + int index = 0; + sign = 1; + + if (str[0] == '-') + { + if (str.Length == 1) + throw new FormatException("Zero length BigInteger"); + + sign = -1; + index = 1; + } + + // strip leading zeros from the string str + while (index < str.Length && Int32.Parse(str[index].ToString(), style) == 0) + { + index++; + } + + if (index >= str.Length) + { + // zero value - we're done + sign = 0; + magnitude = ZeroMagnitude; + return; + } + + ////// + // could we work out the max number of ints required to store + // str.Length digits in the given base, then allocate that + // storage in one hit?, then Generate the magnitude in one hit too? + ////// + + BigInteger b = Zero; + + + int next = index + chunk; + + if (next <= str.Length) + { + do + { + string s = str.Substring(index, chunk); + ulong i = ulong.Parse(s, style); + BigInteger bi = CreateUValueOf(i); + + switch (radix) + { + case 2: + // TODO Need this because we are parsing in radix 10 above + if (i >= 2) + throw new FormatException("Bad character in radix 2 string: " + s); + + // TODO Parse 64 bits at a time + b = b.ShiftLeft(1); + break; + case 8: + // TODO Need this because we are parsing in radix 10 above + if (i >= 8) + throw new FormatException("Bad character in radix 8 string: " + s); + + // TODO Parse 63 bits at a time + b = b.ShiftLeft(3); + break; + case 16: + b = b.ShiftLeft(64); + break; + default: + b = b.Multiply(rE); + break; + } + + b = b.Add(bi); + + index = next; + next += chunk; + } + while (next <= str.Length); + } + + if (index < str.Length) + { + string s = str.Substring(index); + ulong i = ulong.Parse(s, style); + BigInteger bi = CreateUValueOf(i); + + if (b.sign > 0) + { + if (radix == 2) + { + // NB: Can't reach here since we are parsing one char at a time + Debug.Assert(false); + + // TODO Parse all bits at once +// b = b.ShiftLeft(s.Length); + } + else if (radix == 8) + { + // NB: Can't reach here since we are parsing one char at a time + Debug.Assert(false); + + // TODO Parse all bits at once +// b = b.ShiftLeft(s.Length * 3); + } + else if (radix == 16) + { + b = b.ShiftLeft(s.Length << 2); + } + else + { + b = b.Multiply(r.Pow(s.Length)); + } + + b = b.Add(bi); + } + else + { + b = bi; + } + } + + // Note: This is the previous (slower) algorithm +// while (index < value.Length) +// { +// char c = value[index]; +// string s = c.ToString(); +// int i = Int32.Parse(s, style); +// +// b = b.Multiply(r).Add(ValueOf(i)); +// index++; +// } + + magnitude = b.magnitude; + } + + public BigInteger( + byte[] bytes) + : this(bytes, 0, bytes.Length) + { + } + + public BigInteger( + byte[] bytes, + int offset, + int length) + { + if (length == 0) + throw new FormatException("Zero length BigInteger"); + + // TODO Move this processing into MakeMagnitude (provide sign argument) + if ((sbyte)bytes[offset] < 0) + { + this.sign = -1; + + int end = offset + length; + + int iBval; + // strip leading sign bytes + for (iBval = offset; iBval < end && ((sbyte)bytes[iBval] == -1); iBval++) + { + } + + if (iBval >= end) + { + this.magnitude = One.magnitude; + } + else + { + int numBytes = end - iBval; + byte[] inverse = new byte[numBytes]; + + int index = 0; + while (index < numBytes) + { + inverse[index++] = (byte)~bytes[iBval++]; + } + + Debug.Assert(iBval == end); + + while (inverse[--index] == byte.MaxValue) + { + inverse[index] = byte.MinValue; + } + + inverse[index]++; + + this.magnitude = MakeMagnitude(inverse, 0, inverse.Length); + } + } + else + { + // strip leading zero bytes and return magnitude bytes + this.magnitude = MakeMagnitude(bytes, offset, length); + this.sign = this.magnitude.Length > 0 ? 1 : 0; + } + } + + private static int[] MakeMagnitude( + byte[] bytes, + int offset, + int length) + { + int end = offset + length; + + // strip leading zeros + int firstSignificant; + for (firstSignificant = offset; firstSignificant < end + && bytes[firstSignificant] == 0; firstSignificant++) + { + } + + if (firstSignificant >= end) + { + return ZeroMagnitude; + } + + int nInts = (end - firstSignificant + 3) / BytesPerInt; + int bCount = (end - firstSignificant) % BytesPerInt; + if (bCount == 0) + { + bCount = BytesPerInt; + } + + if (nInts < 1) + { + return ZeroMagnitude; + } + + int[] mag = new int[nInts]; + + int v = 0; + int magnitudeIndex = 0; + for (int i = firstSignificant; i < end; ++i) + { + v <<= 8; + v |= bytes[i] & 0xff; + bCount--; + if (bCount <= 0) + { + mag[magnitudeIndex] = v; + magnitudeIndex++; + bCount = BytesPerInt; + v = 0; + } + } + + if (magnitudeIndex < mag.Length) + { + mag[magnitudeIndex] = v; + } + + return mag; + } + + public BigInteger( + int sign, + byte[] bytes) + : this(sign, bytes, 0, bytes.Length) + { + } + + public BigInteger( + int sign, + byte[] bytes, + int offset, + int length) + { + if (sign < -1 || sign > 1) + throw new FormatException("Invalid sign value"); + + if (sign == 0) + { + this.sign = 0; + this.magnitude = ZeroMagnitude; + } + else + { + // copy bytes + this.magnitude = MakeMagnitude(bytes, offset, length); + this.sign = this.magnitude.Length < 1 ? 0 : sign; + } + } + + public BigInteger( + int sizeInBits, + Random random) + { + if (sizeInBits < 0) + throw new ArgumentException("sizeInBits must be non-negative"); + + this.nBits = -1; + this.nBitLength = -1; + + if (sizeInBits == 0) + { + this.sign = 0; + this.magnitude = ZeroMagnitude; + return; + } + + int nBytes = GetByteLength(sizeInBits); + byte[] b = new byte[nBytes]; + random.NextBytes(b); + + // strip off any excess bits in the MSB + int xBits = BitsPerByte * nBytes - sizeInBits; + b[0] &= (byte)(255U >> xBits); + + this.magnitude = MakeMagnitude(b, 0, b.Length); + this.sign = this.magnitude.Length < 1 ? 0 : 1; + } + + public BigInteger( + int bitLength, + int certainty, + Random random) + { + if (bitLength < 2) + throw new ArithmeticException("bitLength < 2"); + + this.sign = 1; + this.nBitLength = bitLength; + + if (bitLength == 2) + { + this.magnitude = random.Next(2) == 0 + ? Two.magnitude + : Three.magnitude; + return; + } + + int nBytes = GetByteLength(bitLength); + byte[] b = new byte[nBytes]; + + int xBits = BitsPerByte * nBytes - bitLength; + byte mask = (byte)(255U >> xBits); + byte lead = (byte)(1 << (7 - xBits)); + + for (;;) + { + random.NextBytes(b); + + // strip off any excess bits in the MSB + b[0] &= mask; + + // ensure the leading bit is 1 (to meet the strength requirement) + b[0] |= lead; + + // ensure the trailing bit is 1 (i.e. must be odd) + b[nBytes - 1] |= 1; + + this.magnitude = MakeMagnitude(b, 0, b.Length); + this.nBits = -1; + this.mQuote = 0; + + if (certainty < 1) + break; + + if (CheckProbablePrime(certainty, random, true)) + break; + + for (int j = 1; j < (magnitude.Length - 1); ++j) + { + this.magnitude[j] ^= random.Next(); + + if (CheckProbablePrime(certainty, random, true)) + return; + } + } + } + + public BigInteger Abs() + { + return sign >= 0 ? this : Negate(); + } + + /** + * return a = a + b - b preserved. + */ + private static int[] AddMagnitudes( + int[] a, + int[] b) + { + int tI = a.Length - 1; + int vI = b.Length - 1; + long m = 0; + + while (vI >= 0) + { + m += ((long)(uint)a[tI] + (long)(uint)b[vI--]); + a[tI--] = (int)m; + m = (long)((ulong)m >> 32); + } + + if (m != 0) + { + while (tI >= 0 && ++a[tI--] == 0) + { + } + } + + return a; + } + + public BigInteger Add( + BigInteger value) + { + if (this.sign == 0) + return value; + + if (this.sign != value.sign) + { + if (value.sign == 0) + return this; + + if (value.sign < 0) + return Subtract(value.Negate()); + + return value.Subtract(Negate()); + } + + return AddToMagnitude(value.magnitude); + } + + private BigInteger AddToMagnitude( + int[] magToAdd) + { + int[] big, small; + if (this.magnitude.Length < magToAdd.Length) + { + big = magToAdd; + small = this.magnitude; + } + else + { + big = this.magnitude; + small = magToAdd; + } + + // Conservatively avoid over-allocation when no overflow possible + uint limit = uint.MaxValue; + if (big.Length == small.Length) + limit -= (uint) small[0]; + + bool possibleOverflow = (uint) big[0] >= limit; + + int[] bigCopy; + if (possibleOverflow) + { + bigCopy = new int[big.Length + 1]; + big.CopyTo(bigCopy, 1); + } + else + { + bigCopy = (int[]) big.Clone(); + } + + bigCopy = AddMagnitudes(bigCopy, small); + + return new BigInteger(this.sign, bigCopy, possibleOverflow); + } + + public BigInteger And( + BigInteger value) + { + if (this.sign == 0 || value.sign == 0) + { + return Zero; + } + + int[] aMag = this.sign > 0 + ? this.magnitude + : Add(One).magnitude; + + int[] bMag = value.sign > 0 + ? value.magnitude + : value.Add(One).magnitude; + + bool resultNeg = sign < 0 && value.sign < 0; + int resultLength = System.Math.Max(aMag.Length, bMag.Length); + int[] resultMag = new int[resultLength]; + + int aStart = resultMag.Length - aMag.Length; + int bStart = resultMag.Length - bMag.Length; + + for (int i = 0; i < resultMag.Length; ++i) + { + int aWord = i >= aStart ? aMag[i - aStart] : 0; + int bWord = i >= bStart ? bMag[i - bStart] : 0; + + if (this.sign < 0) + { + aWord = ~aWord; + } + + if (value.sign < 0) + { + bWord = ~bWord; + } + + resultMag[i] = aWord & bWord; + + if (resultNeg) + { + resultMag[i] = ~resultMag[i]; + } + } + + BigInteger result = new BigInteger(1, resultMag, true); + + // TODO Optimise this case + if (resultNeg) + { + result = result.Not(); + } + + return result; + } + + public BigInteger AndNot( + BigInteger val) + { + return And(val.Not()); + } + + public int BitCount + { + get + { + if (nBits == -1) + { + if (sign < 0) + { + // TODO Optimise this case + nBits = Not().BitCount; + } + else + { + int sum = 0; + for (int i = 0; i < magnitude.Length; ++i) + { + sum += BitCnt(magnitude[i]); + } + nBits = sum; + } + } + + return nBits; + } + } + + public static int BitCnt(int i) + { + uint u = (uint)i; + u = u - ((u >> 1) & 0x55555555); + u = (u & 0x33333333) + ((u >> 2) & 0x33333333); + u = (u + (u >> 4)) & 0x0f0f0f0f; + u += (u >> 8); + u += (u >> 16); + u &= 0x3f; + return (int)u; + } + + private static int CalcBitLength(int sign, int indx, int[] mag) + { + for (;;) + { + if (indx >= mag.Length) + return 0; + + if (mag[indx] != 0) + break; + + ++indx; + } + + // bit length for everything after the first int + int bitLength = 32 * ((mag.Length - indx) - 1); + + // and determine bitlength of first int + int firstMag = mag[indx]; + bitLength += BitLen(firstMag); + + // Check for negative powers of two + if (sign < 0 && ((firstMag & -firstMag) == firstMag)) + { + do + { + if (++indx >= mag.Length) + { + --bitLength; + break; + } + } + while (mag[indx] == 0); + } + + return bitLength; + } + + public int BitLength + { + get + { + if (nBitLength == -1) + { + nBitLength = sign == 0 + ? 0 + : CalcBitLength(sign, 0, magnitude); + } + + return nBitLength; + } + } + + // + // BitLen(value) is the number of bits in value. + // + internal static int BitLen(int w) + { + uint v = (uint)w; + uint t = v >> 24; + if (t != 0) + return 24 + BitLengthTable[t]; + t = v >> 16; + if (t != 0) + return 16 + BitLengthTable[t]; + t = v >> 8; + if (t != 0) + return 8 + BitLengthTable[t]; + return BitLengthTable[v]; + } + + private bool QuickPow2Check() + { + return sign > 0 && nBits == 1; + } + + public int CompareTo( + object obj) + { + return CompareTo((BigInteger)obj); + } + + /** + * unsigned comparison on two arrays - note the arrays may + * start with leading zeros. + */ + private static int CompareTo( + int xIndx, + int[] x, + int yIndx, + int[] y) + { + while (xIndx != x.Length && x[xIndx] == 0) + { + xIndx++; + } + + while (yIndx != y.Length && y[yIndx] == 0) + { + yIndx++; + } + + return CompareNoLeadingZeroes(xIndx, x, yIndx, y); + } + + private static int CompareNoLeadingZeroes( + int xIndx, + int[] x, + int yIndx, + int[] y) + { + int diff = (x.Length - y.Length) - (xIndx - yIndx); + + if (diff != 0) + { + return diff < 0 ? -1 : 1; + } + + // lengths of magnitudes the same, test the magnitude values + + while (xIndx < x.Length) + { + uint v1 = (uint)x[xIndx++]; + uint v2 = (uint)y[yIndx++]; + + if (v1 != v2) + return v1 < v2 ? -1 : 1; + } + + return 0; + } + + public int CompareTo( + BigInteger value) + { + return sign < value.sign ? -1 + : sign > value.sign ? 1 + : sign == 0 ? 0 + : sign * CompareNoLeadingZeroes(0, magnitude, 0, value.magnitude); + } + + /** + * return z = x / y - done in place (z value preserved, x contains the + * remainder) + */ + private int[] Divide( + int[] x, + int[] y) + { + int xStart = 0; + while (xStart < x.Length && x[xStart] == 0) + { + ++xStart; + } + + int yStart = 0; + while (yStart < y.Length && y[yStart] == 0) + { + ++yStart; + } + + Debug.Assert(yStart < y.Length); + + int xyCmp = CompareNoLeadingZeroes(xStart, x, yStart, y); + int[] count; + + if (xyCmp > 0) + { + int yBitLength = CalcBitLength(1, yStart, y); + int xBitLength = CalcBitLength(1, xStart, x); + int shift = xBitLength - yBitLength; + + int[] iCount; + int iCountStart = 0; + + int[] c; + int cStart = 0; + int cBitLength = yBitLength; + if (shift > 0) + { +// iCount = ShiftLeft(One.magnitude, shift); + iCount = new int[(shift >> 5) + 1]; + iCount[0] = 1 << (shift % 32); + + c = ShiftLeft(y, shift); + cBitLength += shift; + } + else + { + iCount = new int[] { 1 }; + + int len = y.Length - yStart; + c = new int[len]; + Array.Copy(y, yStart, c, 0, len); + } + + count = new int[iCount.Length]; + + for (;;) + { + if (cBitLength < xBitLength + || CompareNoLeadingZeroes(xStart, x, cStart, c) >= 0) + { + Subtract(xStart, x, cStart, c); + AddMagnitudes(count, iCount); + + while (x[xStart] == 0) + { + if (++xStart == x.Length) + return count; + } + + //xBitLength = CalcBitLength(xStart, x); + xBitLength = 32 * (x.Length - xStart - 1) + BitLen(x[xStart]); + + if (xBitLength <= yBitLength) + { + if (xBitLength < yBitLength) + return count; + + xyCmp = CompareNoLeadingZeroes(xStart, x, yStart, y); + + if (xyCmp <= 0) + break; + } + } + + shift = cBitLength - xBitLength; + + // NB: The case where c[cStart] is 1-bit is harmless + if (shift == 1) + { + uint firstC = (uint) c[cStart] >> 1; + uint firstX = (uint) x[xStart]; + if (firstC > firstX) + ++shift; + } + + if (shift < 2) + { + ShiftRightOneInPlace(cStart, c); + --cBitLength; + ShiftRightOneInPlace(iCountStart, iCount); + } + else + { + ShiftRightInPlace(cStart, c, shift); + cBitLength -= shift; + ShiftRightInPlace(iCountStart, iCount, shift); + } + + //cStart = c.Length - ((cBitLength + 31) / 32); + while (c[cStart] == 0) + { + ++cStart; + } + + while (iCount[iCountStart] == 0) + { + ++iCountStart; + } + } + } + else + { + count = new int[1]; + } + + if (xyCmp == 0) + { + AddMagnitudes(count, One.magnitude); + Array.Clear(x, xStart, x.Length - xStart); + } + + return count; + } + + public BigInteger Divide( + BigInteger val) + { + if (val.sign == 0) + throw new ArithmeticException("Division by zero error"); + + if (sign == 0) + return Zero; + + if (val.QuickPow2Check()) // val is power of two + { + BigInteger result = this.Abs().ShiftRight(val.Abs().BitLength - 1); + return val.sign == this.sign ? result : result.Negate(); + } + + int[] mag = (int[]) this.magnitude.Clone(); + + return new BigInteger(this.sign * val.sign, Divide(mag, val.magnitude), true); + } + + public BigInteger[] DivideAndRemainder( + BigInteger val) + { + if (val.sign == 0) + throw new ArithmeticException("Division by zero error"); + + BigInteger[] biggies = new BigInteger[2]; + + if (sign == 0) + { + biggies[0] = Zero; + biggies[1] = Zero; + } + else if (val.QuickPow2Check()) // val is power of two + { + int e = val.Abs().BitLength - 1; + BigInteger quotient = this.Abs().ShiftRight(e); + int[] remainder = this.LastNBits(e); + + biggies[0] = val.sign == this.sign ? quotient : quotient.Negate(); + biggies[1] = new BigInteger(this.sign, remainder, true); + } + else + { + int[] remainder = (int[]) this.magnitude.Clone(); + int[] quotient = Divide(remainder, val.magnitude); + + biggies[0] = new BigInteger(this.sign * val.sign, quotient, true); + biggies[1] = new BigInteger(this.sign, remainder, true); + } + + return biggies; + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + BigInteger biggie = obj as BigInteger; + if (biggie == null) + return false; + + return sign == biggie.sign && IsEqualMagnitude(biggie); + } + + private bool IsEqualMagnitude(BigInteger x) + { + int[] xMag = x.magnitude; + if (magnitude.Length != x.magnitude.Length) + return false; + for (int i = 0; i < magnitude.Length; i++) + { + if (magnitude[i] != x.magnitude[i]) + return false; + } + return true; + } + + public BigInteger Gcd( + BigInteger value) + { + if (value.sign == 0) + return Abs(); + + if (sign == 0) + return value.Abs(); + + BigInteger r; + BigInteger u = this; + BigInteger v = value; + + while (v.sign != 0) + { + r = u.Mod(v); + u = v; + v = r; + } + + return u; + } + + public override int GetHashCode() + { + int hc = magnitude.Length; + if (magnitude.Length > 0) + { + hc ^= magnitude[0]; + + if (magnitude.Length > 1) + { + hc ^= magnitude[magnitude.Length - 1]; + } + } + + return sign < 0 ? ~hc : hc; + } + + // TODO Make public? + private BigInteger Inc() + { + if (this.sign == 0) + return One; + + if (this.sign < 0) + return new BigInteger(-1, doSubBigLil(this.magnitude, One.magnitude), true); + + return AddToMagnitude(One.magnitude); + } + + public int IntValue + { + get + { + if (sign == 0) + return 0; + + int n = magnitude.Length; + + int v = magnitude[n - 1]; + + return sign < 0 ? -v : v; + } + } + + public int IntValueExact + { + get + { + if (BitLength > 31) + throw new ArithmeticException("BigInteger out of int range"); + + return IntValue; + } + } + + /** + * return whether or not a BigInteger is probably prime with a + * probability of 1 - (1/2)**certainty. + *

From Knuth Vol 2, pg 395.

+ */ + public bool IsProbablePrime(int certainty) + { + return IsProbablePrime(certainty, false); + } + + internal bool IsProbablePrime(int certainty, bool randomlySelected) + { + if (certainty <= 0) + return true; + + BigInteger n = Abs(); + + if (!n.TestBit(0)) + return n.Equals(Two); + + if (n.Equals(One)) + return false; + + return n.CheckProbablePrime(certainty, RandomSource, randomlySelected); + } + + private bool CheckProbablePrime(int certainty, Random random, bool randomlySelected) + { + Debug.Assert(certainty > 0); + Debug.Assert(CompareTo(Two) > 0); + Debug.Assert(TestBit(0)); + + + // Try to reduce the penalty for really small numbers + int numLists = System.Math.Min(BitLength - 1, primeLists.Length); + + for (int i = 0; i < numLists; ++i) + { + int test = Remainder(primeProducts[i]); + + int[] primeList = primeLists[i]; + for (int j = 0; j < primeList.Length; ++j) + { + int prime = primeList[j]; + int qRem = test % prime; + if (qRem == 0) + { + // We may find small numbers in the list + return BitLength < 16 && IntValue == prime; + } + } + } + + + // TODO Special case for < 10^16 (RabinMiller fixed list) +// if (BitLength < 30) +// { +// RabinMiller against 2, 3, 5, 7, 11, 13, 23 is sufficient +// } + + + // TODO Is it worth trying to create a hybrid of these two? + return RabinMillerTest(certainty, random, randomlySelected); +// return SolovayStrassenTest(certainty, random); + +// bool rbTest = RabinMillerTest(certainty, random); +// bool ssTest = SolovayStrassenTest(certainty, random); +// +// Debug.Assert(rbTest == ssTest); +// +// return rbTest; + } + + public bool RabinMillerTest(int certainty, Random random) + { + return RabinMillerTest(certainty, random, false); + } + + internal bool RabinMillerTest(int certainty, Random random, bool randomlySelected) + { + int bits = BitLength; + + Debug.Assert(certainty > 0); + Debug.Assert(bits > 2); + Debug.Assert(TestBit(0)); + + int iterations = ((certainty - 1) / 2) + 1; + if (randomlySelected) + { + int itersFor100Cert = bits >= 1024 ? 4 + : bits >= 512 ? 8 + : bits >= 256 ? 16 + : 50; + + if (certainty < 100) + { + iterations = System.Math.Min(itersFor100Cert, iterations); + } + else + { + iterations -= 50; + iterations += itersFor100Cert; + } + } + + // let n = 1 + d . 2^s + BigInteger n = this; + int s = n.GetLowestSetBitMaskFirst(-1 << 1); + Debug.Assert(s >= 1); + BigInteger r = n.ShiftRight(s); + + // NOTE: Avoid conversion to/from Montgomery form and check for R/-R as result instead + + BigInteger montRadix = One.ShiftLeft(32 * n.magnitude.Length).Remainder(n); + BigInteger minusMontRadix = n.Subtract(montRadix); + + do + { + BigInteger a; + do + { + a = new BigInteger(n.BitLength, random); + } + while (a.sign == 0 || a.CompareTo(n) >= 0 + || a.IsEqualMagnitude(montRadix) || a.IsEqualMagnitude(minusMontRadix)); + + BigInteger y = ModPowMonty(a, r, n, false); + + if (!y.Equals(montRadix)) + { + int j = 0; + while (!y.Equals(minusMontRadix)) + { + if (++j == s) + return false; + + y = ModPowMonty(y, Two, n, false); + + if (y.Equals(montRadix)) + return false; + } + } + } + while (--iterations > 0); + + return true; + } + +// private bool SolovayStrassenTest( +// int certainty, +// Random random) +// { +// Debug.Assert(certainty > 0); +// Debug.Assert(CompareTo(Two) > 0); +// Debug.Assert(TestBit(0)); +// +// BigInteger n = this; +// BigInteger nMinusOne = n.Subtract(One); +// BigInteger e = nMinusOne.ShiftRight(1); +// +// do +// { +// BigInteger a; +// do +// { +// a = new BigInteger(nBitLength, random); +// } +// // NB: Spec says 0 < x < n, but 1 is trivial +// while (a.CompareTo(One) <= 0 || a.CompareTo(n) >= 0); +// +// +// // TODO Check this is redundant given the way Jacobi() works? +//// if (!a.Gcd(n).Equals(One)) +//// return false; +// +// int x = Jacobi(a, n); +// +// if (x == 0) +// return false; +// +// BigInteger check = a.ModPow(e, n); +// +// if (x == 1 && !check.Equals(One)) +// return false; +// +// if (x == -1 && !check.Equals(nMinusOne)) +// return false; +// +// --certainty; +// } +// while (certainty > 0); +// +// return true; +// } +// +// private static int Jacobi( +// BigInteger a, +// BigInteger b) +// { +// Debug.Assert(a.sign >= 0); +// Debug.Assert(b.sign > 0); +// Debug.Assert(b.TestBit(0)); +// Debug.Assert(a.CompareTo(b) < 0); +// +// int totalS = 1; +// for (;;) +// { +// if (a.sign == 0) +// return 0; +// +// if (a.Equals(One)) +// break; +// +// int e = a.GetLowestSetBit(); +// +// int bLsw = b.magnitude[b.magnitude.Length - 1]; +// if ((e & 1) != 0 && ((bLsw & 7) == 3 || (bLsw & 7) == 5)) +// totalS = -totalS; +// +// // TODO Confirm this is faster than later a1.Equals(One) test +// if (a.BitLength == e + 1) +// break; +// BigInteger a1 = a.ShiftRight(e); +//// if (a1.Equals(One)) +//// break; +// +// int a1Lsw = a1.magnitude[a1.magnitude.Length - 1]; +// if ((bLsw & 3) == 3 && (a1Lsw & 3) == 3) +// totalS = -totalS; +// +//// a = b.Mod(a1); +// a = b.Remainder(a1); +// b = a1; +// } +// return totalS; +// } + + public long LongValue + { + get + { + if (sign == 0) + return 0; + + int n = magnitude.Length; + + long v = magnitude[n - 1] & IMASK; + if (n > 1) + { + v |= (magnitude[n - 2] & IMASK) << 32; + } + + return sign < 0 ? -v : v; + } + } + + public long LongValueExact + { + get + { + if (BitLength > 63) + throw new ArithmeticException("BigInteger out of long range"); + + return LongValue; + } + } + + public BigInteger Max( + BigInteger value) + { + return CompareTo(value) > 0 ? this : value; + } + + public BigInteger Min( + BigInteger value) + { + return CompareTo(value) < 0 ? this : value; + } + + public BigInteger Mod( + BigInteger m) + { + if (m.sign < 1) + throw new ArithmeticException("Modulus must be positive"); + + BigInteger biggie = Remainder(m); + + return (biggie.sign >= 0 ? biggie : biggie.Add(m)); + } + + public BigInteger ModInverse( + BigInteger m) + { + if (m.sign < 1) + throw new ArithmeticException("Modulus must be positive"); + + // TODO Too slow at the moment +// // "Fast Key Exchange with Elliptic Curve Systems" R.Schoeppel +// if (m.TestBit(0)) +// { +// //The Almost Inverse Algorithm +// int k = 0; +// BigInteger B = One, C = Zero, F = this, G = m, tmp; +// +// for (;;) +// { +// // While F is even, do F=F/u, C=C*u, k=k+1. +// int zeroes = F.GetLowestSetBit(); +// if (zeroes > 0) +// { +// F = F.ShiftRight(zeroes); +// C = C.ShiftLeft(zeroes); +// k += zeroes; +// } +// +// // If F = 1, then return B,k. +// if (F.Equals(One)) +// { +// BigInteger half = m.Add(One).ShiftRight(1); +// BigInteger halfK = half.ModPow(BigInteger.ValueOf(k), m); +// return B.Multiply(halfK).Mod(m); +// } +// +// if (F.CompareTo(G) < 0) +// { +// tmp = G; G = F; F = tmp; +// tmp = B; B = C; C = tmp; +// } +// +// F = F.Add(G); +// B = B.Add(C); +// } +// } + + if (m.QuickPow2Check()) + { + return ModInversePow2(m); + } + + BigInteger d = this.Remainder(m); + BigInteger x; + BigInteger gcd = ExtEuclid(d, m, out x); + + if (!gcd.Equals(One)) + throw new ArithmeticException("Numbers not relatively prime."); + + if (x.sign < 0) + { + x = x.Add(m); + } + + return x; + } + + private BigInteger ModInversePow2(BigInteger m) + { + Debug.Assert(m.SignValue > 0); + Debug.Assert(m.BitCount == 1); + + if (!TestBit(0)) + { + throw new ArithmeticException("Numbers not relatively prime."); + } + + int pow = m.BitLength - 1; + + long inv64 = ModInverse64(LongValue); + if (pow < 64) + { + inv64 &= ((1L << pow) - 1); + } + + BigInteger x = BigInteger.ValueOf(inv64); + + if (pow > 64) + { + BigInteger d = this.Remainder(m); + int bitsCorrect = 64; + + do + { + BigInteger t = x.Multiply(d).Remainder(m); + x = x.Multiply(Two.Subtract(t)).Remainder(m); + bitsCorrect <<= 1; + } + while (bitsCorrect < pow); + } + + if (x.sign < 0) + { + x = x.Add(m); + } + + return x; + } + + private static int ModInverse32(int d) + { + // Newton's method with initial estimate "correct to 4 bits" + Debug.Assert((d & 1) != 0); + int x = d + (((d + 1) & 4) << 1); // d.x == 1 mod 2**4 + Debug.Assert(((d * x) & 15) == 1); + x *= 2 - d * x; // d.x == 1 mod 2**8 + x *= 2 - d * x; // d.x == 1 mod 2**16 + x *= 2 - d * x; // d.x == 1 mod 2**32 + Debug.Assert(d * x == 1); + return x; + } + + private static long ModInverse64(long d) + { + // Newton's method with initial estimate "correct to 4 bits" + Debug.Assert((d & 1L) != 0); + long x = d + (((d + 1L) & 4L) << 1); // d.x == 1 mod 2**4 + Debug.Assert(((d * x) & 15L) == 1L); + x *= 2 - d * x; // d.x == 1 mod 2**8 + x *= 2 - d * x; // d.x == 1 mod 2**16 + x *= 2 - d * x; // d.x == 1 mod 2**32 + x *= 2 - d * x; // d.x == 1 mod 2**64 + Debug.Assert(d * x == 1L); + return x; + } + + /** + * Calculate the numbers u1, u2, and u3 such that: + * + * u1 * a + u2 * b = u3 + * + * where u3 is the greatest common divider of a and b. + * a and b using the extended Euclid algorithm (refer p. 323 + * of The Art of Computer Programming vol 2, 2nd ed). + * This also seems to have the side effect of calculating + * some form of multiplicative inverse. + * + * @param a First number to calculate gcd for + * @param b Second number to calculate gcd for + * @param u1Out the return object for the u1 value + * @return The greatest common divisor of a and b + */ + private static BigInteger ExtEuclid(BigInteger a, BigInteger b, out BigInteger u1Out) + { + BigInteger u1 = One, v1 = Zero; + BigInteger u3 = a, v3 = b; + + if (v3.sign > 0) + { + for (;;) + { + BigInteger[] q = u3.DivideAndRemainder(v3); + u3 = v3; + v3 = q[1]; + + BigInteger oldU1 = u1; + u1 = v1; + + if (v3.sign <= 0) + break; + + v1 = oldU1.Subtract(v1.Multiply(q[0])); + } + } + + u1Out = u1; + + return u3; + } + + private static void ZeroOut( + int[] x) + { + Array.Clear(x, 0, x.Length); + } + + public BigInteger ModPow(BigInteger e, BigInteger m) + { + if (m.sign < 1) + throw new ArithmeticException("Modulus must be positive"); + + if (m.Equals(One)) + return Zero; + + if (e.sign == 0) + return One; + + if (sign == 0) + return Zero; + + bool negExp = e.sign < 0; + if (negExp) + e = e.Negate(); + + BigInteger result = this.Mod(m); + if (!e.Equals(One)) + { + if ((m.magnitude[m.magnitude.Length - 1] & 1) == 0) + { + result = ModPowBarrett(result, e, m); + } + else + { + result = ModPowMonty(result, e, m, true); + } + } + + if (negExp) + result = result.ModInverse(m); + + return result; + } + + private static BigInteger ModPowBarrett(BigInteger b, BigInteger e, BigInteger m) + { + int k = m.magnitude.Length; + BigInteger mr = One.ShiftLeft((k + 1) << 5); + BigInteger yu = One.ShiftLeft(k << 6).Divide(m); + + // Sliding window from MSW to LSW + int extraBits = 0, expLength = e.BitLength; + while (expLength > ExpWindowThresholds[extraBits]) + { + ++extraBits; + } + + int numPowers = 1 << extraBits; + BigInteger[] oddPowers = new BigInteger[numPowers]; + oddPowers[0] = b; + + BigInteger b2 = ReduceBarrett(b.Square(), m, mr, yu); + + for (int i = 1; i < numPowers; ++i) + { + oddPowers[i] = ReduceBarrett(oddPowers[i - 1].Multiply(b2), m, mr, yu); + } + + int[] windowList = GetWindowList(e.magnitude, extraBits); + Debug.Assert(windowList.Length > 0); + + int window = windowList[0]; + int mult = window & 0xFF, lastZeroes = window >> 8; + + BigInteger y; + if (mult == 1) + { + y = b2; + --lastZeroes; + } + else + { + y = oddPowers[mult >> 1]; + } + + int windowPos = 1; + while ((window = windowList[windowPos++]) != -1) + { + mult = window & 0xFF; + + int bits = lastZeroes + BitLengthTable[mult]; + for (int j = 0; j < bits; ++j) + { + y = ReduceBarrett(y.Square(), m, mr, yu); + } + + y = ReduceBarrett(y.Multiply(oddPowers[mult >> 1]), m, mr, yu); + + lastZeroes = window >> 8; + } + + for (int i = 0; i < lastZeroes; ++i) + { + y = ReduceBarrett(y.Square(), m, mr, yu); + } + + return y; + } + + private static BigInteger ReduceBarrett(BigInteger x, BigInteger m, BigInteger mr, BigInteger yu) + { + int xLen = x.BitLength, mLen = m.BitLength; + if (xLen < mLen) + return x; + + if (xLen - mLen > 1) + { + int k = m.magnitude.Length; + + BigInteger q1 = x.DivideWords(k - 1); + BigInteger q2 = q1.Multiply(yu); // TODO Only need partial multiplication here + BigInteger q3 = q2.DivideWords(k + 1); + + BigInteger r1 = x.RemainderWords(k + 1); + BigInteger r2 = q3.Multiply(m); // TODO Only need partial multiplication here + BigInteger r3 = r2.RemainderWords(k + 1); + + x = r1.Subtract(r3); + if (x.sign < 0) + { + x = x.Add(mr); + } + } + + while (x.CompareTo(m) >= 0) + { + x = x.Subtract(m); + } + + return x; + } + + private static BigInteger ModPowMonty(BigInteger b, BigInteger e, BigInteger m, bool convert) + { + int n = m.magnitude.Length; + int powR = 32 * n; + bool smallMontyModulus = m.BitLength + 2 <= powR; + uint mDash = (uint)m.GetMQuote(); + + // tmp = this * R mod m + if (convert) + { + b = b.ShiftLeft(powR).Remainder(m); + } + + int[] yAccum = new int[n + 1]; + + int[] zVal = b.magnitude; + Debug.Assert(zVal.Length <= n); + if (zVal.Length < n) + { + int[] tmp = new int[n]; + zVal.CopyTo(tmp, n - zVal.Length); + zVal = tmp; + } + + // Sliding window from MSW to LSW + + int extraBits = 0; + + // Filter the common case of small RSA exponents with few bits set + if (e.magnitude.Length > 1 || e.BitCount > 2) + { + int expLength = e.BitLength; + while (expLength > ExpWindowThresholds[extraBits]) + { + ++extraBits; + } + } + + int numPowers = 1 << extraBits; + int[][] oddPowers = new int[numPowers][]; + oddPowers[0] = zVal; + + int[] zSquared = Arrays.Clone(zVal); + SquareMonty(yAccum, zSquared, m.magnitude, mDash, smallMontyModulus); + + for (int i = 1; i < numPowers; ++i) + { + oddPowers[i] = Arrays.Clone(oddPowers[i - 1]); + MultiplyMonty(yAccum, oddPowers[i], zSquared, m.magnitude, mDash, smallMontyModulus); + } + + int[] windowList = GetWindowList(e.magnitude, extraBits); + Debug.Assert(windowList.Length > 1); + + int window = windowList[0]; + int mult = window & 0xFF, lastZeroes = window >> 8; + + int[] yVal; + if (mult == 1) + { + yVal = zSquared; + --lastZeroes; + } + else + { + yVal = Arrays.Clone(oddPowers[mult >> 1]); + } + + int windowPos = 1; + while ((window = windowList[windowPos++]) != -1) + { + mult = window & 0xFF; + + int bits = lastZeroes + BitLengthTable[mult]; + for (int j = 0; j < bits; ++j) + { + SquareMonty(yAccum, yVal, m.magnitude, mDash, smallMontyModulus); + } + + MultiplyMonty(yAccum, yVal, oddPowers[mult >> 1], m.magnitude, mDash, smallMontyModulus); + + lastZeroes = window >> 8; + } + + for (int i = 0; i < lastZeroes; ++i) + { + SquareMonty(yAccum, yVal, m.magnitude, mDash, smallMontyModulus); + } + + if (convert) + { + // Return y * R^(-1) mod m + MontgomeryReduce(yVal, m.magnitude, mDash); + } + else if (smallMontyModulus && CompareTo(0, yVal, 0, m.magnitude) >= 0) + { + Subtract(0, yVal, 0, m.magnitude); + } + + return new BigInteger(1, yVal, true); + } + + private static int[] GetWindowList(int[] mag, int extraBits) + { + int v = mag[0]; + Debug.Assert(v != 0); + + int leadingBits = BitLen(v); + + int resultSize = (((mag.Length - 1) << 5) + leadingBits) / (1 + extraBits) + 2; + int[] result = new int[resultSize]; + int resultPos = 0; + + int bitPos = 33 - leadingBits; + v <<= bitPos; + + int mult = 1, multLimit = 1 << extraBits; + int zeroes = 0; + + int i = 0; + for (; ; ) + { + for (; bitPos < 32; ++bitPos) + { + if (mult < multLimit) + { + mult = (mult << 1) | (int)((uint)v >> 31); + } + else if (v < 0) + { + result[resultPos++] = CreateWindowEntry(mult, zeroes); + mult = 1; + zeroes = 0; + } + else + { + ++zeroes; + } + + v <<= 1; + } + + if (++i == mag.Length) + { + result[resultPos++] = CreateWindowEntry(mult, zeroes); + break; + } + + v = mag[i]; + bitPos = 0; + } + + result[resultPos] = -1; + return result; + } + + private static int CreateWindowEntry(int mult, int zeroes) + { + while ((mult & 1) == 0) + { + mult >>= 1; + ++zeroes; + } + + return mult | (zeroes << 8); + } + + /** + * return w with w = x * x - w is assumed to have enough space. + */ + private static int[] Square( + int[] w, + int[] x) + { + // Note: this method allows w to be only (2 * x.Length - 1) words if result will fit +// if (w.Length != 2 * x.Length) +// throw new ArgumentException("no I don't think so..."); + + ulong c; + + int wBase = w.Length - 1; + + for (int i = x.Length - 1; i > 0; --i) + { + ulong v = (uint)x[i]; + + c = v * v + (uint)w[wBase]; + w[wBase] = (int)c; + c >>= 32; + + for (int j = i - 1; j >= 0; --j) + { + ulong prod = v * (uint)x[j]; + + c += ((uint)w[--wBase] & UIMASK) + ((uint)prod << 1); + w[wBase] = (int)c; + c = (c >> 32) + (prod >> 31); + } + + c += (uint)w[--wBase]; + w[wBase] = (int)c; + + if (--wBase >= 0) + { + w[wBase] = (int)(c >> 32); + } + else + { + Debug.Assert((c >> 32) == 0); + } + + wBase += i; + } + + c = (uint)x[0]; + + c = c * c + (uint)w[wBase]; + w[wBase] = (int)c; + + if (--wBase >= 0) + { + w[wBase] += (int)(c >> 32); + } + else + { + Debug.Assert((c >> 32) == 0); + } + + return w; + } + + /** + * return x with x = y * z - x is assumed to have enough space. + */ + private static int[] Multiply(int[] x, int[] y, int[] z) + { + int i = z.Length; + + if (i < 1) + return x; + + int xBase = x.Length - y.Length; + + do + { + long a = z[--i] & IMASK; + long val = 0; + + if (a != 0) + { + for (int j = y.Length - 1; j >= 0; j--) + { + val += a * (y[j] & IMASK) + (x[xBase + j] & IMASK); + + x[xBase + j] = (int)val; + + val = (long)((ulong)val >> 32); + } + } + + --xBase; + + if (xBase >= 0) + { + x[xBase] = (int)val; + } + else + { + Debug.Assert(val == 0); + } + } + while (i > 0); + + return x; + } + + /** + * Calculate mQuote = -m^(-1) mod b with b = 2^32 (32 = word size) + */ + private int GetMQuote() + { + if (mQuote != 0) + { + return mQuote; // already calculated + } + + Debug.Assert(this.sign > 0); + + int d = -magnitude[magnitude.Length - 1]; + + Debug.Assert((d & 1) != 0); + + return mQuote = ModInverse32(d); + } + + private static void MontgomeryReduce(int[] x, int[] m, uint mDash) // mDash = -m^(-1) mod b + { + // NOTE: Not a general purpose reduction (which would allow x up to twice the bitlength of m) + Debug.Assert(x.Length == m.Length); + + int n = m.Length; + + for (int i = n - 1; i >= 0; --i) + { + uint x0 = (uint)x[n - 1]; + ulong t = x0 * mDash; + + ulong carry = t * (uint)m[n - 1] + x0; + Debug.Assert((uint)carry == 0); + carry >>= 32; + + for (int j = n - 2; j >= 0; --j) + { + carry += t * (uint)m[j] + (uint)x[j]; + x[j + 1] = (int)carry; + carry >>= 32; + } + + x[0] = (int)carry; + Debug.Assert(carry >> 32 == 0); + } + + if (CompareTo(0, x, 0, m) >= 0) + { + Subtract(0, x, 0, m); + } + } + + /** + * Montgomery multiplication: a = x * y * R^(-1) mod m + *
+ * Based algorithm 14.36 of Handbook of Applied Cryptography. + *
+ *
  • m, x, y should have length n
  • + *
  • a should have length (n + 1)
  • + *
  • b = 2^32, R = b^n
  • + *
    + * The result is put in x + *
    + * NOTE: the indices of x, y, m, a different in HAC and in Java + */ + private static void MultiplyMonty(int[] a, int[] x, int[] y, int[] m, uint mDash, bool smallMontyModulus) + // mDash = -m^(-1) mod b + { + int n = m.Length; + + if (n == 1) + { + x[0] = (int)MultiplyMontyNIsOne((uint)x[0], (uint)y[0], (uint)m[0], mDash); + return; + } + + uint y0 = (uint)y[n - 1]; + int aMax; + + { + ulong xi = (uint)x[n - 1]; + + ulong carry = xi * y0; + ulong t = (uint)carry * mDash; + + ulong prod2 = t * (uint)m[n - 1]; + carry += (uint)prod2; + Debug.Assert((uint)carry == 0); + carry = (carry >> 32) + (prod2 >> 32); + + for (int j = n - 2; j >= 0; --j) + { + ulong prod1 = xi * (uint)y[j]; + prod2 = t * (uint)m[j]; + + carry += (prod1 & UIMASK) + (uint)prod2; + a[j + 2] = (int)carry; + carry = (carry >> 32) + (prod1 >> 32) + (prod2 >> 32); + } + + a[1] = (int)carry; + aMax = (int)(carry >> 32); + } + + for (int i = n - 2; i >= 0; --i) + { + uint a0 = (uint)a[n]; + ulong xi = (uint)x[i]; + + ulong prod1 = xi * y0; + ulong carry = (prod1 & UIMASK) + a0; + ulong t = (uint)carry * mDash; + + ulong prod2 = t * (uint)m[n - 1]; + carry += (uint)prod2; + Debug.Assert((uint)carry == 0); + carry = (carry >> 32) + (prod1 >> 32) + (prod2 >> 32); + + for (int j = n - 2; j >= 0; --j) + { + prod1 = xi * (uint)y[j]; + prod2 = t * (uint)m[j]; + + carry += (prod1 & UIMASK) + (uint)prod2 + (uint)a[j + 1]; + a[j + 2] = (int)carry; + carry = (carry >> 32) + (prod1 >> 32) + (prod2 >> 32); + } + + carry += (uint)aMax; + a[1] = (int)carry; + aMax = (int)(carry >> 32); + } + + a[0] = aMax; + + if (!smallMontyModulus && CompareTo(0, a, 0, m) >= 0) + { + Subtract(0, a, 0, m); + } + + Array.Copy(a, 1, x, 0, n); + } + + private static void SquareMonty(int[] a, int[] x, int[] m, uint mDash, bool smallMontyModulus) + // mDash = -m^(-1) mod b + { + int n = m.Length; + + if (n == 1) + { + uint xVal = (uint)x[0]; + x[0] = (int)MultiplyMontyNIsOne(xVal, xVal, (uint)m[0], mDash); + return; + } + + ulong x0 = (uint)x[n - 1]; + int aMax; + + { + ulong carry = x0 * x0; + ulong t = (uint)carry * mDash; + + ulong prod2 = t * (uint)m[n - 1]; + carry += (uint)prod2; + Debug.Assert((uint)carry == 0); + carry = (carry >> 32) + (prod2 >> 32); + + for (int j = n - 2; j >= 0; --j) + { + ulong prod1 = x0 * (uint)x[j]; + prod2 = t * (uint)m[j]; + + carry += (prod2 & UIMASK) + ((uint)prod1 << 1); + a[j + 2] = (int)carry; + carry = (carry >> 32) + (prod1 >> 31) + (prod2 >> 32); + } + + a[1] = (int)carry; + aMax = (int)(carry >> 32); + } + + for (int i = n - 2; i >= 0; --i) + { + uint a0 = (uint)a[n]; + ulong t = a0 * mDash; + + ulong carry = t * (uint)m[n - 1] + a0; + Debug.Assert((uint)carry == 0); + carry >>= 32; + + for (int j = n - 2; j > i; --j) + { + carry += t * (uint)m[j] + (uint)a[j + 1]; + a[j + 2] = (int)carry; + carry >>= 32; + } + + ulong xi = (uint)x[i]; + + { + ulong prod1 = xi * xi; + ulong prod2 = t * (uint)m[i]; + + carry += (prod1 & UIMASK) + (uint)prod2 + (uint)a[i + 1]; + a[i + 2] = (int)carry; + carry = (carry >> 32) + (prod1 >> 32) + (prod2 >> 32); + } + + for (int j = i - 1; j >= 0; --j) + { + ulong prod1 = xi * (uint)x[j]; + ulong prod2 = t * (uint)m[j]; + + carry += (prod2 & UIMASK) + ((uint)prod1 << 1) + (uint)a[j + 1]; + a[j + 2] = (int)carry; + carry = (carry >> 32) + (prod1 >> 31) + (prod2 >> 32); + } + + carry += (uint)aMax; + a[1] = (int)carry; + aMax = (int)(carry >> 32); + } + + a[0] = aMax; + + if (!smallMontyModulus && CompareTo(0, a, 0, m) >= 0) + { + Subtract(0, a, 0, m); + } + + Array.Copy(a, 1, x, 0, n); + } + + private static uint MultiplyMontyNIsOne(uint x, uint y, uint m, uint mDash) + { + ulong carry = (ulong)x * y; + uint t = (uint)carry * mDash; + ulong um = m; + ulong prod2 = um * t; + carry += (uint)prod2; + Debug.Assert((uint)carry == 0); + carry = (carry >> 32) + (prod2 >> 32); + if (carry > um) + { + carry -= um; + } + Debug.Assert(carry < um); + return (uint)carry; + } + + public BigInteger Multiply( + BigInteger val) + { + if (val == this) + return Square(); + + if ((sign & val.sign) == 0) + return Zero; + + if (val.QuickPow2Check()) // val is power of two + { + BigInteger result = this.ShiftLeft(val.Abs().BitLength - 1); + return val.sign > 0 ? result : result.Negate(); + } + + if (this.QuickPow2Check()) // this is power of two + { + BigInteger result = val.ShiftLeft(this.Abs().BitLength - 1); + return this.sign > 0 ? result : result.Negate(); + } + + int resLength = magnitude.Length + val.magnitude.Length; + int[] res = new int[resLength]; + + Multiply(res, this.magnitude, val.magnitude); + + int resSign = sign ^ val.sign ^ 1; + return new BigInteger(resSign, res, true); + } + + public BigInteger Square() + { + if (sign == 0) + return Zero; + if (this.QuickPow2Check()) + return ShiftLeft(Abs().BitLength - 1); + int resLength = magnitude.Length << 1; + if ((uint)magnitude[0] >> 16 == 0) + --resLength; + int[] res = new int[resLength]; + Square(res, magnitude); + return new BigInteger(1, res, false); + } + + public BigInteger Negate() + { + if (sign == 0) + return this; + + return new BigInteger(-sign, magnitude, false); + } + + public BigInteger NextProbablePrime() + { + if (sign < 0) + throw new ArithmeticException("Cannot be called on value < 0"); + + if (CompareTo(Two) < 0) + return Two; + + BigInteger n = Inc().SetBit(0); + + while (!n.CheckProbablePrime(100, RandomSource, false)) + { + n = n.Add(Two); + } + + return n; + } + + public BigInteger Not() + { + return Inc().Negate(); + } + + public BigInteger Pow(int exp) + { + if (exp <= 0) + { + if (exp < 0) + throw new ArithmeticException("Negative exponent"); + + return One; + } + + if (sign == 0) + { + return this; + } + + if (QuickPow2Check()) + { + long powOf2 = (long)exp * (BitLength - 1); + if (powOf2 > Int32.MaxValue) + { + throw new ArithmeticException("Result too large"); + } + return One.ShiftLeft((int)powOf2); + } + + BigInteger y = One; + BigInteger z = this; + + for (;;) + { + if ((exp & 0x1) == 1) + { + y = y.Multiply(z); + } + exp >>= 1; + if (exp == 0) break; + z = z.Multiply(z); + } + + return y; + } + + public static BigInteger ProbablePrime( + int bitLength, + Random random) + { + return new BigInteger(bitLength, 100, random); + } + + private int Remainder( + int m) + { + Debug.Assert(m > 0); + + long acc = 0; + for (int pos = 0; pos < magnitude.Length; ++pos) + { + long posVal = (uint) magnitude[pos]; + acc = (acc << 32 | posVal) % m; + } + + return (int) acc; + } + + /** + * return x = x % y - done in place (y value preserved) + */ + private static int[] Remainder( + int[] x, + int[] y) + { + int xStart = 0; + while (xStart < x.Length && x[xStart] == 0) + { + ++xStart; + } + + int yStart = 0; + while (yStart < y.Length && y[yStart] == 0) + { + ++yStart; + } + + Debug.Assert(yStart < y.Length); + + int xyCmp = CompareNoLeadingZeroes(xStart, x, yStart, y); + + if (xyCmp > 0) + { + int yBitLength = CalcBitLength(1, yStart, y); + int xBitLength = CalcBitLength(1, xStart, x); + int shift = xBitLength - yBitLength; + + int[] c; + int cStart = 0; + int cBitLength = yBitLength; + if (shift > 0) + { + c = ShiftLeft(y, shift); + cBitLength += shift; + Debug.Assert(c[0] != 0); + } + else + { + int len = y.Length - yStart; + c = new int[len]; + Array.Copy(y, yStart, c, 0, len); + } + + for (;;) + { + if (cBitLength < xBitLength + || CompareNoLeadingZeroes(xStart, x, cStart, c) >= 0) + { + Subtract(xStart, x, cStart, c); + + while (x[xStart] == 0) + { + if (++xStart == x.Length) + return x; + } + + //xBitLength = CalcBitLength(xStart, x); + xBitLength = 32 * (x.Length - xStart - 1) + BitLen(x[xStart]); + + if (xBitLength <= yBitLength) + { + if (xBitLength < yBitLength) + return x; + + xyCmp = CompareNoLeadingZeroes(xStart, x, yStart, y); + + if (xyCmp <= 0) + break; + } + } + + shift = cBitLength - xBitLength; + + // NB: The case where c[cStart] is 1-bit is harmless + if (shift == 1) + { + uint firstC = (uint) c[cStart] >> 1; + uint firstX = (uint) x[xStart]; + if (firstC > firstX) + ++shift; + } + + if (shift < 2) + { + ShiftRightOneInPlace(cStart, c); + --cBitLength; + } + else + { + ShiftRightInPlace(cStart, c, shift); + cBitLength -= shift; + } + + //cStart = c.Length - ((cBitLength + 31) / 32); + while (c[cStart] == 0) + { + ++cStart; + } + } + } + + if (xyCmp == 0) + { + Array.Clear(x, xStart, x.Length - xStart); + } + + return x; + } + + public BigInteger Remainder( + BigInteger n) + { + if (n.sign == 0) + throw new ArithmeticException("Division by zero error"); + + if (this.sign == 0) + return Zero; + + // For small values, use fast remainder method + if (n.magnitude.Length == 1) + { + int val = n.magnitude[0]; + + if (val > 0) + { + if (val == 1) + return Zero; + + // TODO Make this func work on uint, and handle val == 1? + int rem = Remainder(val); + + return rem == 0 + ? Zero + : new BigInteger(sign, new int[]{ rem }, false); + } + } + + if (CompareNoLeadingZeroes(0, magnitude, 0, n.magnitude) < 0) + return this; + + int[] result; + if (n.QuickPow2Check()) // n is power of two + { + // TODO Move before small values branch above? + result = LastNBits(n.Abs().BitLength - 1); + } + else + { + result = (int[]) this.magnitude.Clone(); + result = Remainder(result, n.magnitude); + } + + return new BigInteger(sign, result, true); + } + + private int[] LastNBits( + int n) + { + if (n < 1) + return ZeroMagnitude; + + int numWords = (n + BitsPerInt - 1) / BitsPerInt; + numWords = System.Math.Min(numWords, this.magnitude.Length); + int[] result = new int[numWords]; + + Array.Copy(this.magnitude, this.magnitude.Length - numWords, result, 0, numWords); + + int excessBits = (numWords << 5) - n; + if (excessBits > 0) + { + result[0] &= (int)(UInt32.MaxValue >> excessBits); + } + + return result; + } + + private BigInteger DivideWords(int w) + { + Debug.Assert(w >= 0); + int n = magnitude.Length; + if (w >= n) + return Zero; + int[] mag = new int[n - w]; + Array.Copy(magnitude, 0, mag, 0, n - w); + return new BigInteger(sign, mag, false); + } + + private BigInteger RemainderWords(int w) + { + Debug.Assert(w >= 0); + int n = magnitude.Length; + if (w >= n) + return this; + int[] mag = new int[w]; + Array.Copy(magnitude, n - w, mag, 0, w); + return new BigInteger(sign, mag, false); + } + + /** + * do a left shift - this returns a new array. + */ + private static int[] ShiftLeft( + int[] mag, + int n) + { + int nInts = (int)((uint)n >> 5); + int nBits = n & 0x1f; + int magLen = mag.Length; + int[] newMag; + + if (nBits == 0) + { + newMag = new int[magLen + nInts]; + mag.CopyTo(newMag, 0); + } + else + { + int i = 0; + int nBits2 = 32 - nBits; + int highBits = (int)((uint)mag[0] >> nBits2); + + if (highBits != 0) + { + newMag = new int[magLen + nInts + 1]; + newMag[i++] = highBits; + } + else + { + newMag = new int[magLen + nInts]; + } + + int m = mag[0]; + for (int j = 0; j < magLen - 1; j++) + { + int next = mag[j + 1]; + + newMag[i++] = (m << nBits) | (int)((uint)next >> nBits2); + m = next; + } + + newMag[i] = mag[magLen - 1] << nBits; + } + + return newMag; + } + + private static int ShiftLeftOneInPlace(int[] x, int carry) + { + Debug.Assert(carry == 0 || carry == 1); + int pos = x.Length; + while (--pos >= 0) + { + uint val = (uint)x[pos]; + x[pos] = (int)(val << 1) | carry; + carry = (int)(val >> 31); + } + return carry; + } + + public BigInteger ShiftLeft( + int n) + { + if (sign == 0 || magnitude.Length == 0) + return Zero; + + if (n == 0) + return this; + + if (n < 0) + return ShiftRight(-n); + + BigInteger result = new BigInteger(sign, ShiftLeft(magnitude, n), true); + + if (this.nBits != -1) + { + result.nBits = sign > 0 + ? this.nBits + : this.nBits + n; + } + + if (this.nBitLength != -1) + { + result.nBitLength = this.nBitLength + n; + } + + return result; + } + + /** + * do a right shift - this does it in place. + */ + private static void ShiftRightInPlace( + int start, + int[] mag, + int n) + { + int nInts = (int)((uint)n >> 5) + start; + int nBits = n & 0x1f; + int magEnd = mag.Length - 1; + + if (nInts != start) + { + int delta = (nInts - start); + + for (int i = magEnd; i >= nInts; i--) + { + mag[i] = mag[i - delta]; + } + for (int i = nInts - 1; i >= start; i--) + { + mag[i] = 0; + } + } + + if (nBits != 0) + { + int nBits2 = 32 - nBits; + int m = mag[magEnd]; + + for (int i = magEnd; i > nInts; --i) + { + int next = mag[i - 1]; + + mag[i] = (int)((uint)m >> nBits) | (next << nBits2); + m = next; + } + + mag[nInts] = (int)((uint)mag[nInts] >> nBits); + } + } + + /** + * do a right shift by one - this does it in place. + */ + private static void ShiftRightOneInPlace( + int start, + int[] mag) + { + int i = mag.Length; + int m = mag[i - 1]; + + while (--i > start) + { + int next = mag[i - 1]; + mag[i] = ((int)((uint)m >> 1)) | (next << 31); + m = next; + } + + mag[start] = (int)((uint)mag[start] >> 1); + } + + public BigInteger ShiftRight( + int n) + { + if (n == 0) + return this; + + if (n < 0) + return ShiftLeft(-n); + + if (n >= BitLength) + return (this.sign < 0 ? One.Negate() : Zero); + +// int[] res = (int[]) this.magnitude.Clone(); +// +// ShiftRightInPlace(0, res, n); +// +// return new BigInteger(this.sign, res, true); + + int resultLength = (BitLength - n + 31) >> 5; + int[] res = new int[resultLength]; + + int numInts = n >> 5; + int numBits = n & 31; + + if (numBits == 0) + { + Array.Copy(this.magnitude, 0, res, 0, res.Length); + } + else + { + int numBits2 = 32 - numBits; + + int magPos = this.magnitude.Length - 1 - numInts; + for (int i = resultLength - 1; i >= 0; --i) + { + res[i] = (int)((uint) this.magnitude[magPos--] >> numBits); + + if (magPos >= 0) + { + res[i] |= this.magnitude[magPos] << numBits2; + } + } + } + + Debug.Assert(res[0] != 0); + + return new BigInteger(this.sign, res, false); + } + + public int SignValue + { + get { return sign; } + } + + /** + * returns x = x - y - we assume x is >= y + */ + private static int[] Subtract( + int xStart, + int[] x, + int yStart, + int[] y) + { + Debug.Assert(yStart < y.Length); + Debug.Assert(x.Length - xStart >= y.Length - yStart); + + int iT = x.Length; + int iV = y.Length; + long m; + int borrow = 0; + + do + { + m = (x[--iT] & IMASK) - (y[--iV] & IMASK) + borrow; + x[iT] = (int) m; + +// borrow = (m < 0) ? -1 : 0; + borrow = (int)(m >> 63); + } + while (iV > yStart); + + if (borrow != 0) + { + while (--x[--iT] == -1) + { + } + } + + return x; + } + + public BigInteger Subtract( + BigInteger n) + { + if (n.sign == 0) + return this; + + if (this.sign == 0) + return n.Negate(); + + if (this.sign != n.sign) + return Add(n.Negate()); + + int compare = CompareNoLeadingZeroes(0, magnitude, 0, n.magnitude); + if (compare == 0) + return Zero; + + BigInteger bigun, lilun; + if (compare < 0) + { + bigun = n; + lilun = this; + } + else + { + bigun = this; + lilun = n; + } + + return new BigInteger(this.sign * compare, doSubBigLil(bigun.magnitude, lilun.magnitude), true); + } + + private static int[] doSubBigLil( + int[] bigMag, + int[] lilMag) + { + int[] res = (int[]) bigMag.Clone(); + + return Subtract(0, res, 0, lilMag); + } + + public byte[] ToByteArray() + { + return ToByteArray(false); + } + + public byte[] ToByteArrayUnsigned() + { + return ToByteArray(true); + } + + private byte[] ToByteArray( + bool unsigned) + { + if (sign == 0) + return unsigned ? ZeroEncoding : new byte[1]; + + int nBits = (unsigned && sign > 0) + ? BitLength + : BitLength + 1; + + int nBytes = GetByteLength(nBits); + byte[] bytes = new byte[nBytes]; + + int magIndex = magnitude.Length; + int bytesIndex = bytes.Length; + + if (sign > 0) + { + while (magIndex > 1) + { + uint mag = (uint) magnitude[--magIndex]; + bytes[--bytesIndex] = (byte) mag; + bytes[--bytesIndex] = (byte)(mag >> 8); + bytes[--bytesIndex] = (byte)(mag >> 16); + bytes[--bytesIndex] = (byte)(mag >> 24); + } + + uint lastMag = (uint) magnitude[0]; + while (lastMag > byte.MaxValue) + { + bytes[--bytesIndex] = (byte) lastMag; + lastMag >>= 8; + } + + bytes[--bytesIndex] = (byte) lastMag; + } + else // sign < 0 + { + bool carry = true; + + while (magIndex > 1) + { + uint mag = ~((uint) magnitude[--magIndex]); + + if (carry) + { + carry = (++mag == uint.MinValue); + } + + bytes[--bytesIndex] = (byte) mag; + bytes[--bytesIndex] = (byte)(mag >> 8); + bytes[--bytesIndex] = (byte)(mag >> 16); + bytes[--bytesIndex] = (byte)(mag >> 24); + } + + uint lastMag = (uint) magnitude[0]; + + if (carry) + { + // Never wraps because magnitude[0] != 0 + --lastMag; + } + + while (lastMag > byte.MaxValue) + { + bytes[--bytesIndex] = (byte) ~lastMag; + lastMag >>= 8; + } + + bytes[--bytesIndex] = (byte) ~lastMag; + + if (bytesIndex > 0) + { + bytes[--bytesIndex] = byte.MaxValue; + } + } + + return bytes; + } + + public override string ToString() + { + return ToString(10); + } + + public string ToString(int radix) + { + // TODO Make this method work for other radices (ideally 2 <= radix <= 36 as in Java) + + switch (radix) + { + case 2: + case 8: + case 10: + case 16: + break; + default: + throw new FormatException("Only bases 2, 8, 10, 16 are allowed"); + } + + // NB: Can only happen to internally managed instances + if (magnitude == null) + return "null"; + + if (sign == 0) + return "0"; + + + // NOTE: This *should* be unnecessary, since the magnitude *should* never have leading zero digits + int firstNonZero = 0; + while (firstNonZero < magnitude.Length) + { + if (magnitude[firstNonZero] != 0) + { + break; + } + ++firstNonZero; + } + + if (firstNonZero == magnitude.Length) + { + return "0"; + } + + + StringBuilder sb = new StringBuilder(); + if (sign == -1) + { + sb.Append('-'); + } + + switch (radix) + { + case 2: + { + int pos = firstNonZero; + sb.Append(Convert.ToString(magnitude[pos], 2)); + while (++pos < magnitude.Length) + { + AppendZeroExtendedString(sb, Convert.ToString(magnitude[pos], 2), 32); + } + break; + } + case 8: + { + int mask = (1 << 30) - 1; + BigInteger u = this.Abs(); + int bits = u.BitLength; + IList S = Platform.CreateArrayList(); + while (bits > 30) + { + S.Add(Convert.ToString(u.IntValue & mask, 8)); + u = u.ShiftRight(30); + bits -= 30; + } + sb.Append(Convert.ToString(u.IntValue, 8)); + for (int i = S.Count - 1; i >= 0; --i) + { + AppendZeroExtendedString(sb, (string)S[i], 10); + } + break; + } + case 16: + { + int pos = firstNonZero; + sb.Append(Convert.ToString(magnitude[pos], 16)); + while (++pos < magnitude.Length) + { + AppendZeroExtendedString(sb, Convert.ToString(magnitude[pos], 16), 8); + } + break; + } + // TODO This could work for other radices if there is an alternative to Convert.ToString method + //default: + case 10: + { + BigInteger q = this.Abs(); + if (q.BitLength < 64) + { + sb.Append(Convert.ToString(q.LongValue, radix)); + break; + } + + // TODO Could cache the moduli for each radix (soft reference?) + IList moduli = Platform.CreateArrayList(); + BigInteger R = BigInteger.ValueOf(radix); + while (R.CompareTo(q) <= 0) + { + moduli.Add(R); + R = R.Square(); + } + + int scale = moduli.Count; + sb.EnsureCapacity(sb.Length + (1 << scale)); + + ToString(sb, radix, moduli, scale, q); + + break; + } + } + + return sb.ToString(); + } + + private static void ToString(StringBuilder sb, int radix, IList moduli, int scale, BigInteger pos) + { + if (pos.BitLength < 64) + { + string s = Convert.ToString(pos.LongValue, radix); + if (sb.Length > 1 || (sb.Length == 1 && sb[0] != '-')) + { + AppendZeroExtendedString(sb, s, 1 << scale); + } + else if (pos.SignValue != 0) + { + sb.Append(s); + } + return; + } + + BigInteger[] qr = pos.DivideAndRemainder((BigInteger)moduli[--scale]); + + ToString(sb, radix, moduli, scale, qr[0]); + ToString(sb, radix, moduli, scale, qr[1]); + } + + private static void AppendZeroExtendedString(StringBuilder sb, string s, int minLength) + { + for (int len = s.Length; len < minLength; ++len) + { + sb.Append('0'); + } + sb.Append(s); + } + + private static BigInteger CreateUValueOf( + ulong value) + { + int msw = (int)(value >> 32); + int lsw = (int)value; + + if (msw != 0) + return new BigInteger(1, new int[] { msw, lsw }, false); + + if (lsw != 0) + { + BigInteger n = new BigInteger(1, new int[] { lsw }, false); + // Check for a power of two + if ((lsw & -lsw) == lsw) + { + n.nBits = 1; + } + return n; + } + + return Zero; + } + + private static BigInteger CreateValueOf( + long value) + { + if (value < 0) + { + if (value == long.MinValue) + return CreateValueOf(~value).Not(); + + return CreateValueOf(-value).Negate(); + } + + return CreateUValueOf((ulong)value); + } + + public static BigInteger ValueOf( + long value) + { + if (value >= 0 && value < SMALL_CONSTANTS.Length) + { + return SMALL_CONSTANTS[value]; + } + + return CreateValueOf(value); + } + + public int GetLowestSetBit() + { + if (this.sign == 0) + return -1; + + return GetLowestSetBitMaskFirst(-1); + } + + private int GetLowestSetBitMaskFirst(int firstWordMask) + { + int w = magnitude.Length, offset = 0; + + uint word = (uint)(magnitude[--w] & firstWordMask); + Debug.Assert(magnitude[0] != 0); + + while (word == 0) + { + word = (uint)magnitude[--w]; + offset += 32; + } + + while ((word & 0xFF) == 0) + { + word >>= 8; + offset += 8; + } + + while ((word & 1) == 0) + { + word >>= 1; + ++offset; + } + + return offset; + } + + public bool TestBit( + int n) + { + if (n < 0) + throw new ArithmeticException("Bit position must not be negative"); + + if (sign < 0) + return !Not().TestBit(n); + + int wordNum = n / 32; + if (wordNum >= magnitude.Length) + return false; + + int word = magnitude[magnitude.Length - 1 - wordNum]; + return ((word >> (n % 32)) & 1) > 0; + } + + public BigInteger Or( + BigInteger value) + { + if (this.sign == 0) + return value; + + if (value.sign == 0) + return this; + + int[] aMag = this.sign > 0 + ? this.magnitude + : Add(One).magnitude; + + int[] bMag = value.sign > 0 + ? value.magnitude + : value.Add(One).magnitude; + + bool resultNeg = sign < 0 || value.sign < 0; + int resultLength = System.Math.Max(aMag.Length, bMag.Length); + int[] resultMag = new int[resultLength]; + + int aStart = resultMag.Length - aMag.Length; + int bStart = resultMag.Length - bMag.Length; + + for (int i = 0; i < resultMag.Length; ++i) + { + int aWord = i >= aStart ? aMag[i - aStart] : 0; + int bWord = i >= bStart ? bMag[i - bStart] : 0; + + if (this.sign < 0) + { + aWord = ~aWord; + } + + if (value.sign < 0) + { + bWord = ~bWord; + } + + resultMag[i] = aWord | bWord; + + if (resultNeg) + { + resultMag[i] = ~resultMag[i]; + } + } + + BigInteger result = new BigInteger(1, resultMag, true); + + // TODO Optimise this case + if (resultNeg) + { + result = result.Not(); + } + + return result; + } + + public BigInteger Xor( + BigInteger value) + { + if (this.sign == 0) + return value; + + if (value.sign == 0) + return this; + + int[] aMag = this.sign > 0 + ? this.magnitude + : Add(One).magnitude; + + int[] bMag = value.sign > 0 + ? value.magnitude + : value.Add(One).magnitude; + + // TODO Can just replace with sign != value.sign? + bool resultNeg = (sign < 0 && value.sign >= 0) || (sign >= 0 && value.sign < 0); + int resultLength = System.Math.Max(aMag.Length, bMag.Length); + int[] resultMag = new int[resultLength]; + + int aStart = resultMag.Length - aMag.Length; + int bStart = resultMag.Length - bMag.Length; + + for (int i = 0; i < resultMag.Length; ++i) + { + int aWord = i >= aStart ? aMag[i - aStart] : 0; + int bWord = i >= bStart ? bMag[i - bStart] : 0; + + if (this.sign < 0) + { + aWord = ~aWord; + } + + if (value.sign < 0) + { + bWord = ~bWord; + } + + resultMag[i] = aWord ^ bWord; + + if (resultNeg) + { + resultMag[i] = ~resultMag[i]; + } + } + + BigInteger result = new BigInteger(1, resultMag, true); + + // TODO Optimise this case + if (resultNeg) + { + result = result.Not(); + } + + return result; + } + + public BigInteger SetBit( + int n) + { + if (n < 0) + throw new ArithmeticException("Bit address less than zero"); + + if (TestBit(n)) + return this; + + // TODO Handle negative values and zero + if (sign > 0 && n < (BitLength - 1)) + return FlipExistingBit(n); + + return Or(One.ShiftLeft(n)); + } + + public BigInteger ClearBit( + int n) + { + if (n < 0) + throw new ArithmeticException("Bit address less than zero"); + + if (!TestBit(n)) + return this; + + // TODO Handle negative values + if (sign > 0 && n < (BitLength - 1)) + return FlipExistingBit(n); + + return AndNot(One.ShiftLeft(n)); + } + + public BigInteger FlipBit( + int n) + { + if (n < 0) + throw new ArithmeticException("Bit address less than zero"); + + // TODO Handle negative values and zero + if (sign > 0 && n < (BitLength - 1)) + return FlipExistingBit(n); + + return Xor(One.ShiftLeft(n)); + } + + private BigInteger FlipExistingBit( + int n) + { + Debug.Assert(sign > 0); + Debug.Assert(n >= 0); + Debug.Assert(n < BitLength - 1); + + int[] mag = (int[]) this.magnitude.Clone(); + mag[mag.Length - 1 - (n >> 5)] ^= (1 << (n & 31)); // Flip bit + //mag[mag.Length - 1 - (n / 32)] ^= (1 << (n % 32)); + return new BigInteger(this.sign, mag, false); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/BigInteger.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/BigInteger.cs.meta new file mode 100644 index 0000000..4170650 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/BigInteger.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 83475f9cecc33c941ba7506b908208b0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/Primes.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/Primes.cs new file mode 100644 index 0000000..fb279f1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/Primes.cs @@ -0,0 +1,629 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math +{ + /** + * Utility methods for generating primes and testing for primality. + */ + public abstract class Primes + { + public static readonly int SmallFactorLimit = 211; + + private static readonly BigInteger One = BigInteger.One; + private static readonly BigInteger Two = BigInteger.Two; + private static readonly BigInteger Three = BigInteger.Three; + + /** + * Used to return the output from the + * {@linkplain Primes#enhancedMRProbablePrimeTest(BigInteger, SecureRandom, int) Enhanced + * Miller-Rabin Probabilistic Primality Test} + */ + public class MROutput + { + internal static MROutput ProbablyPrime() + { + return new MROutput(false, null); + } + + internal static MROutput ProvablyCompositeWithFactor(BigInteger factor) + { + return new MROutput(true, factor); + } + + internal static MROutput ProvablyCompositeNotPrimePower() + { + return new MROutput(true, null); + } + + private readonly bool mProvablyComposite; + private readonly BigInteger mFactor; + + private MROutput(bool provablyComposite, BigInteger factor) + { + this.mProvablyComposite = provablyComposite; + this.mFactor = factor; + } + + public BigInteger Factor + { + get { return mFactor; } + } + + public bool IsProvablyComposite + { + get { return mProvablyComposite; } + } + + public bool IsNotPrimePower + { + get { return mProvablyComposite && mFactor == null; } + } + } + + /** + * Used to return the output from the {@linkplain Primes#generateSTRandomPrime(Digest, int, byte[]) Shawe-Taylor Random_Prime Routine} + */ + public class STOutput + { + private readonly BigInteger mPrime; + private readonly byte[] mPrimeSeed; + private readonly int mPrimeGenCounter; + + internal STOutput(BigInteger prime, byte[] primeSeed, int primeGenCounter) + { + this.mPrime = prime; + this.mPrimeSeed = primeSeed; + this.mPrimeGenCounter = primeGenCounter; + } + + public BigInteger Prime + { + get { return mPrime; } + } + + public byte[] PrimeSeed + { + get { return mPrimeSeed; } + } + + public int PrimeGenCounter + { + get { return mPrimeGenCounter; } + } + } + + /** + * FIPS 186-4 C.6 Shawe-Taylor Random_Prime Routine + * + * Construct a provable prime number using a hash function. + * + * @param hash + * the {@link Digest} instance to use (as "Hash()"). Cannot be null. + * @param length + * the length (in bits) of the prime to be generated. Must be at least 2. + * @param inputSeed + * the seed to be used for the generation of the requested prime. Cannot be null or + * empty. + * @return an {@link STOutput} instance containing the requested prime. + */ + public static STOutput GenerateSTRandomPrime(IDigest hash, int length, byte[] inputSeed) + { + if (hash == null) + throw new ArgumentNullException("hash"); + if (length < 2) + throw new ArgumentException("must be >= 2", "length"); + if (inputSeed == null) + throw new ArgumentNullException("inputSeed"); + if (inputSeed.Length == 0) + throw new ArgumentException("cannot be empty", "inputSeed"); + + return ImplSTRandomPrime(hash, length, Arrays.Clone(inputSeed)); + } + + /** + * FIPS 186-4 C.3.2 Enhanced Miller-Rabin Probabilistic Primality Test + * + * Run several iterations of the Miller-Rabin algorithm with randomly-chosen bases. This is an + * alternative to {@link #isMRProbablePrime(BigInteger, SecureRandom, int)} that provides more + * information about a composite candidate, which may be useful when generating or validating + * RSA moduli. + * + * @param candidate + * the {@link BigInteger} instance to test for primality. + * @param random + * the source of randomness to use to choose bases. + * @param iterations + * the number of randomly-chosen bases to perform the test for. + * @return an {@link MROutput} instance that can be further queried for details. + */ + public static MROutput EnhancedMRProbablePrimeTest(BigInteger candidate, SecureRandom random, int iterations) + { + CheckCandidate(candidate, "candidate"); + + if (random == null) + throw new ArgumentNullException("random"); + if (iterations < 1) + throw new ArgumentException("must be > 0", "iterations"); + + if (candidate.BitLength == 2) + return MROutput.ProbablyPrime(); + + if (!candidate.TestBit(0)) + return MROutput.ProvablyCompositeWithFactor(Two); + + BigInteger w = candidate; + BigInteger wSubOne = candidate.Subtract(One); + BigInteger wSubTwo = candidate.Subtract(Two); + + int a = wSubOne.GetLowestSetBit(); + BigInteger m = wSubOne.ShiftRight(a); + + for (int i = 0; i < iterations; ++i) + { + BigInteger b = BigIntegers.CreateRandomInRange(Two, wSubTwo, random); + BigInteger g = b.Gcd(w); + + if (g.CompareTo(One) > 0) + return MROutput.ProvablyCompositeWithFactor(g); + + BigInteger z = b.ModPow(m, w); + + if (z.Equals(One) || z.Equals(wSubOne)) + continue; + + bool primeToBase = false; + + BigInteger x = z; + for (int j = 1; j < a; ++j) + { + z = z.ModPow(Two, w); + + if (z.Equals(wSubOne)) + { + primeToBase = true; + break; + } + + if (z.Equals(One)) + break; + + x = z; + } + + if (!primeToBase) + { + if (!z.Equals(One)) + { + x = z; + z = z.ModPow(Two, w); + + if (!z.Equals(One)) + { + x = z; + } + } + + g = x.Subtract(One).Gcd(w); + + if (g.CompareTo(One) > 0) + return MROutput.ProvablyCompositeWithFactor(g); + + return MROutput.ProvablyCompositeNotPrimePower(); + } + } + + return MROutput.ProbablyPrime(); + } + + /** + * A fast check for small divisors, up to some implementation-specific limit. + * + * @param candidate + * the {@link BigInteger} instance to test for division by small factors. + * + * @return true if the candidate is found to have any small factors, + * false otherwise. + */ + public static bool HasAnySmallFactors(BigInteger candidate) + { + CheckCandidate(candidate, "candidate"); + + return ImplHasAnySmallFactors(candidate); + } + + /** + * FIPS 186-4 C.3.1 Miller-Rabin Probabilistic Primality Test + * + * Run several iterations of the Miller-Rabin algorithm with randomly-chosen bases. + * + * @param candidate + * the {@link BigInteger} instance to test for primality. + * @param random + * the source of randomness to use to choose bases. + * @param iterations + * the number of randomly-chosen bases to perform the test for. + * @return false if any witness to compositeness is found amongst the chosen bases + * (so candidate is definitely NOT prime), or else true + * (indicating primality with some probability dependent on the number of iterations + * that were performed). + */ + public static bool IsMRProbablePrime(BigInteger candidate, SecureRandom random, int iterations) + { + CheckCandidate(candidate, "candidate"); + + if (random == null) + throw new ArgumentException("cannot be null", "random"); + if (iterations < 1) + throw new ArgumentException("must be > 0", "iterations"); + + if (candidate.BitLength == 2) + return true; + if (!candidate.TestBit(0)) + return false; + + BigInteger w = candidate; + BigInteger wSubOne = candidate.Subtract(One); + BigInteger wSubTwo = candidate.Subtract(Two); + + int a = wSubOne.GetLowestSetBit(); + BigInteger m = wSubOne.ShiftRight(a); + + for (int i = 0; i < iterations; ++i) + { + BigInteger b = BigIntegers.CreateRandomInRange(Two, wSubTwo, random); + + if (!ImplMRProbablePrimeToBase(w, wSubOne, m, a, b)) + return false; + } + + return true; + } + + /** + * FIPS 186-4 C.3.1 Miller-Rabin Probabilistic Primality Test (to a fixed base). + * + * Run a single iteration of the Miller-Rabin algorithm against the specified base. + * + * @param candidate + * the {@link BigInteger} instance to test for primality. + * @param baseValue + * the base value to use for this iteration. + * @return false if the specified base is a witness to compositeness (so + * candidate is definitely NOT prime), or else true. + */ + public static bool IsMRProbablePrimeToBase(BigInteger candidate, BigInteger baseValue) + { + CheckCandidate(candidate, "candidate"); + CheckCandidate(baseValue, "baseValue"); + + if (baseValue.CompareTo(candidate.Subtract(One)) >= 0) + throw new ArgumentException("must be < ('candidate' - 1)", "baseValue"); + + if (candidate.BitLength == 2) + return true; + + BigInteger w = candidate; + BigInteger wSubOne = candidate.Subtract(One); + + int a = wSubOne.GetLowestSetBit(); + BigInteger m = wSubOne.ShiftRight(a); + + return ImplMRProbablePrimeToBase(w, wSubOne, m, a, baseValue); + } + + private static void CheckCandidate(BigInteger n, string name) + { + if (n == null || n.SignValue < 1 || n.BitLength < 2) + throw new ArgumentException("must be non-null and >= 2", name); + } + + private static bool ImplHasAnySmallFactors(BigInteger x) + { + /* + * Bundle trial divisors into ~32-bit moduli then use fast tests on the ~32-bit remainders. + */ + int m = 2 * 3 * 5 * 7 * 11 * 13 * 17 * 19 * 23; + int r = x.Mod(BigInteger.ValueOf(m)).IntValue; + if ((r % 2) == 0 || (r % 3) == 0 || (r % 5) == 0 || (r % 7) == 0 || (r % 11) == 0 || (r % 13) == 0 + || (r % 17) == 0 || (r % 19) == 0 || (r % 23) == 0) + { + return true; + } + + m = 29 * 31 * 37 * 41 * 43; + r = x.Mod(BigInteger.ValueOf(m)).IntValue; + if ((r % 29) == 0 || (r % 31) == 0 || (r % 37) == 0 || (r % 41) == 0 || (r % 43) == 0) + { + return true; + } + + m = 47 * 53 * 59 * 61 * 67; + r = x.Mod(BigInteger.ValueOf(m)).IntValue; + if ((r % 47) == 0 || (r % 53) == 0 || (r % 59) == 0 || (r % 61) == 0 || (r % 67) == 0) + { + return true; + } + + m = 71 * 73 * 79 * 83; + r = x.Mod(BigInteger.ValueOf(m)).IntValue; + if ((r % 71) == 0 || (r % 73) == 0 || (r % 79) == 0 || (r % 83) == 0) + { + return true; + } + + m = 89 * 97 * 101 * 103; + r = x.Mod(BigInteger.ValueOf(m)).IntValue; + if ((r % 89) == 0 || (r % 97) == 0 || (r % 101) == 0 || (r % 103) == 0) + { + return true; + } + + m = 107 * 109 * 113 * 127; + r = x.Mod(BigInteger.ValueOf(m)).IntValue; + if ((r % 107) == 0 || (r % 109) == 0 || (r % 113) == 0 || (r % 127) == 0) + { + return true; + } + + m = 131 * 137 * 139 * 149; + r = x.Mod(BigInteger.ValueOf(m)).IntValue; + if ((r % 131) == 0 || (r % 137) == 0 || (r % 139) == 0 || (r % 149) == 0) + { + return true; + } + + m = 151 * 157 * 163 * 167; + r = x.Mod(BigInteger.ValueOf(m)).IntValue; + if ((r % 151) == 0 || (r % 157) == 0 || (r % 163) == 0 || (r % 167) == 0) + { + return true; + } + + m = 173 * 179 * 181 * 191; + r = x.Mod(BigInteger.ValueOf(m)).IntValue; + if ((r % 173) == 0 || (r % 179) == 0 || (r % 181) == 0 || (r % 191) == 0) + { + return true; + } + + m = 193 * 197 * 199 * 211; + r = x.Mod(BigInteger.ValueOf(m)).IntValue; + if ((r % 193) == 0 || (r % 197) == 0 || (r % 199) == 0 || (r % 211) == 0) + { + return true; + } + + /* + * NOTE: Unit tests depend on SMALL_FACTOR_LIMIT matching the + * highest small factor tested here. + */ + return false; + } + + private static bool ImplMRProbablePrimeToBase(BigInteger w, BigInteger wSubOne, BigInteger m, int a, BigInteger b) + { + BigInteger z = b.ModPow(m, w); + + if (z.Equals(One) || z.Equals(wSubOne)) + return true; + + bool result = false; + + for (int j = 1; j < a; ++j) + { + z = z.ModPow(Two, w); + + if (z.Equals(wSubOne)) + { + result = true; + break; + } + + if (z.Equals(One)) + return false; + } + + return result; + } + + private static STOutput ImplSTRandomPrime(IDigest d, int length, byte[] primeSeed) + { + int dLen = d.GetDigestSize(); + + if (length < 33) + { + int primeGenCounter = 0; + + byte[] c0 = new byte[dLen]; + byte[] c1 = new byte[dLen]; + + for (;;) + { + Hash(d, primeSeed, c0, 0); + Inc(primeSeed, 1); + + Hash(d, primeSeed, c1, 0); + Inc(primeSeed, 1); + + uint c = Extract32(c0) ^ Extract32(c1); + c &= (uint.MaxValue >> (32 - length)); + c |= (1U << (length - 1)) | 1U; + + ++primeGenCounter; + + if (IsPrime32(c)) + { + return new STOutput(BigInteger.ValueOf((long)c), primeSeed, primeGenCounter); + } + + if (primeGenCounter > (4 * length)) + { + throw new InvalidOperationException("Too many iterations in Shawe-Taylor Random_Prime Routine"); + } + } + } + + STOutput rec = ImplSTRandomPrime(d, (length + 3)/2, primeSeed); + + { + BigInteger c0 = rec.Prime; + primeSeed = rec.PrimeSeed; + int primeGenCounter = rec.PrimeGenCounter; + + int outlen = 8 * dLen; + int iterations = (length - 1)/outlen; + + int oldCounter = primeGenCounter; + + BigInteger x = HashGen(d, primeSeed, iterations + 1); + x = x.Mod(One.ShiftLeft(length - 1)).SetBit(length - 1); + + BigInteger c0x2 = c0.ShiftLeft(1); + BigInteger tx2 = x.Subtract(One).Divide(c0x2).Add(One).ShiftLeft(1); + int dt = 0; + + BigInteger c = tx2.Multiply(c0).Add(One); + + /* + * TODO Since the candidate primes are generated by constant steps ('c0x2'), + * sieving could be used here in place of the 'HasAnySmallFactors' approach. + */ + for (;;) + { + if (c.BitLength > length) + { + tx2 = One.ShiftLeft(length - 1).Subtract(One).Divide(c0x2).Add(One).ShiftLeft(1); + c = tx2.Multiply(c0).Add(One); + } + + ++primeGenCounter; + + /* + * This is an optimization of the original algorithm, using trial division to screen out + * many non-primes quickly. + * + * NOTE: 'primeSeed' is still incremented as if we performed the full check! + */ + if (!ImplHasAnySmallFactors(c)) + { + BigInteger a = HashGen(d, primeSeed, iterations + 1); + a = a.Mod(c.Subtract(Three)).Add(Two); + + tx2 = tx2.Add(BigInteger.ValueOf(dt)); + dt = 0; + + BigInteger z = a.ModPow(tx2, c); + + if (c.Gcd(z.Subtract(One)).Equals(One) && z.ModPow(c0, c).Equals(One)) + { + return new STOutput(c, primeSeed, primeGenCounter); + } + } + else + { + Inc(primeSeed, iterations + 1); + } + + if (primeGenCounter >= ((4 * length) + oldCounter)) + { + throw new InvalidOperationException("Too many iterations in Shawe-Taylor Random_Prime Routine"); + } + + dt += 2; + c = c.Add(c0x2); + } + } + } + + private static uint Extract32(byte[] bs) + { + uint result = 0; + + int count = System.Math.Min(4, bs.Length); + for (int i = 0; i < count; ++i) + { + uint b = bs[bs.Length - (i + 1)]; + result |= (b << (8 * i)); + } + + return result; + } + + private static void Hash(IDigest d, byte[] input, byte[] output, int outPos) + { + d.BlockUpdate(input, 0, input.Length); + d.DoFinal(output, outPos); + } + + private static BigInteger HashGen(IDigest d, byte[] seed, int count) + { + int dLen = d.GetDigestSize(); + int pos = count * dLen; + byte[] buf = new byte[pos]; + for (int i = 0; i < count; ++i) + { + pos -= dLen; + Hash(d, seed, buf, pos); + Inc(seed, 1); + } + return new BigInteger(1, buf); + } + + private static void Inc(byte[] seed, int c) + { + int pos = seed.Length; + while (c > 0 && --pos >= 0) + { + c += seed[pos]; + seed[pos] = (byte)c; + c >>= 8; + } + } + + private static bool IsPrime32(uint x) + { + /* + * Use wheel factorization with 2, 3, 5 to select trial divisors. + */ + + if (x <= 5) + { + return x == 2 || x == 3 || x == 5; + } + + if ((x & 1) == 0 || (x % 3) == 0 || (x % 5) == 0) + { + return false; + } + + uint[] ds = new uint[]{ 1, 7, 11, 13, 17, 19, 23, 29 }; + uint b = 0; + for (int pos = 1; ; pos = 0) + { + /* + * Trial division by wheel-selected divisors + */ + while (pos < ds.Length) + { + uint d = b + ds[pos]; + if (x % d == 0) + { + return x < 30; + } + ++pos; + } + + b += 30; + + if ((b >> 16 != 0) || (b * b >= x)) + { + return true; + } + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/Primes.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/Primes.cs.meta new file mode 100644 index 0000000..c03707f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/Primes.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dc751f1478394474f836df7ddc2e01ee +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec.meta new file mode 100644 index 0000000..41c0259 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7d032505b592ed449b81fdf0b7119986 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/AbstractECLookupTable.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/AbstractECLookupTable.cs new file mode 100644 index 0000000..fbd272d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/AbstractECLookupTable.cs @@ -0,0 +1,16 @@ +using System; + +namespace Org.BouncyCastle.Math.EC +{ + public abstract class AbstractECLookupTable + : ECLookupTable + { + public abstract ECPoint Lookup(int index); + public abstract int Size { get; } + + public virtual ECPoint LookupVar(int index) + { + return Lookup(index); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/AbstractECLookupTable.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/AbstractECLookupTable.cs.meta new file mode 100644 index 0000000..1acaaeb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/AbstractECLookupTable.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5311a21c6a43201458224532f396738f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ECAlgorithms.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ECAlgorithms.cs new file mode 100644 index 0000000..64e68fc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ECAlgorithms.cs @@ -0,0 +1,601 @@ +using System; + +using Org.BouncyCastle.Math.EC.Endo; +using Org.BouncyCastle.Math.EC.Multiplier; +using Org.BouncyCastle.Math.Field; +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC +{ + public class ECAlgorithms + { + public static bool IsF2mCurve(ECCurve c) + { + return IsF2mField(c.Field); + } + + public static bool IsF2mField(IFiniteField field) + { + return field.Dimension > 1 && field.Characteristic.Equals(BigInteger.Two) + && field is IPolynomialExtensionField; + } + + public static bool IsFpCurve(ECCurve c) + { + return IsFpField(c.Field); + } + + public static bool IsFpField(IFiniteField field) + { + return field.Dimension == 1; + } + + public static ECPoint SumOfMultiplies(ECPoint[] ps, BigInteger[] ks) + { + if (ps == null || ks == null || ps.Length != ks.Length || ps.Length < 1) + throw new ArgumentException("point and scalar arrays should be non-null, and of equal, non-zero, length"); + + int count = ps.Length; + switch (count) + { + case 1: + return ps[0].Multiply(ks[0]); + case 2: + return SumOfTwoMultiplies(ps[0], ks[0], ps[1], ks[1]); + default: + break; + } + + ECPoint p = ps[0]; + ECCurve c = p.Curve; + + ECPoint[] imported = new ECPoint[count]; + imported[0] = p; + for (int i = 1; i < count; ++i) + { + imported[i] = ImportPoint(c, ps[i]); + } + + GlvEndomorphism glvEndomorphism = c.GetEndomorphism() as GlvEndomorphism; + if (glvEndomorphism != null) + { + return ImplCheckResult(ImplSumOfMultipliesGlv(imported, ks, glvEndomorphism)); + } + + return ImplCheckResult(ImplSumOfMultiplies(imported, ks)); + } + + public static ECPoint SumOfTwoMultiplies(ECPoint P, BigInteger a, ECPoint Q, BigInteger b) + { + ECCurve cp = P.Curve; + Q = ImportPoint(cp, Q); + + // Point multiplication for Koblitz curves (using WTNAF) beats Shamir's trick + { + AbstractF2mCurve f2mCurve = cp as AbstractF2mCurve; + if (f2mCurve != null && f2mCurve.IsKoblitz) + { + return ImplCheckResult(P.Multiply(a).Add(Q.Multiply(b))); + } + } + + GlvEndomorphism glvEndomorphism = cp.GetEndomorphism() as GlvEndomorphism; + if (glvEndomorphism != null) + { + return ImplCheckResult( + ImplSumOfMultipliesGlv(new ECPoint[] { P, Q }, new BigInteger[] { a, b }, glvEndomorphism)); + } + + return ImplCheckResult(ImplShamirsTrickWNaf(P, a, Q, b)); + } + + /* + * "Shamir's Trick", originally due to E. G. Straus + * (Addition chains of vectors. American Mathematical Monthly, + * 71(7):806-808, Aug./Sept. 1964) + * + * Input: The points P, Q, scalar k = (km?, ... , k1, k0) + * and scalar l = (lm?, ... , l1, l0). + * Output: R = k * P + l * Q. + * 1: Z <- P + Q + * 2: R <- O + * 3: for i from m-1 down to 0 do + * 4: R <- R + R {point doubling} + * 5: if (ki = 1) and (li = 0) then R <- R + P end if + * 6: if (ki = 0) and (li = 1) then R <- R + Q end if + * 7: if (ki = 1) and (li = 1) then R <- R + Z end if + * 8: end for + * 9: return R + */ + public static ECPoint ShamirsTrick(ECPoint P, BigInteger k, ECPoint Q, BigInteger l) + { + ECCurve cp = P.Curve; + Q = ImportPoint(cp, Q); + + return ImplCheckResult(ImplShamirsTrickJsf(P, k, Q, l)); + } + + public static ECPoint ImportPoint(ECCurve c, ECPoint p) + { + ECCurve cp = p.Curve; + if (!c.Equals(cp)) + throw new ArgumentException("Point must be on the same curve"); + + return c.ImportPoint(p); + } + + public static void MontgomeryTrick(ECFieldElement[] zs, int off, int len) + { + MontgomeryTrick(zs, off, len, null); + } + + public static void MontgomeryTrick(ECFieldElement[] zs, int off, int len, ECFieldElement scale) + { + /* + * Uses the "Montgomery Trick" to invert many field elements, with only a single actual + * field inversion. See e.g. the paper: + * "Fast Multi-scalar Multiplication Methods on Elliptic Curves with Precomputation Strategy Using Montgomery Trick" + * by Katsuyuki Okeya, Kouichi Sakurai. + */ + + ECFieldElement[] c = new ECFieldElement[len]; + c[0] = zs[off]; + + int i = 0; + while (++i < len) + { + c[i] = c[i - 1].Multiply(zs[off + i]); + } + + --i; + + if (scale != null) + { + c[i] = c[i].Multiply(scale); + } + + ECFieldElement u = c[i].Invert(); + + while (i > 0) + { + int j = off + i--; + ECFieldElement tmp = zs[j]; + zs[j] = c[i].Multiply(u); + u = u.Multiply(tmp); + } + + zs[off] = u; + } + + /** + * Simple shift-and-add multiplication. Serves as reference implementation to verify (possibly + * faster) implementations, and for very small scalars. CAUTION: This implementation is NOT + * constant-time in any way. It is only intended to be used for diagnostics. + * + * @param p + * The point to multiply. + * @param k + * The multiplier. + * @return The result of the point multiplication kP. + */ + public static ECPoint ReferenceMultiply(ECPoint p, BigInteger k) + { + BigInteger x = k.Abs(); + ECPoint q = p.Curve.Infinity; + int t = x.BitLength; + if (t > 0) + { + if (x.TestBit(0)) + { + q = p; + } + for (int i = 1; i < t; i++) + { + p = p.Twice(); + if (x.TestBit(i)) + { + q = q.Add(p); + } + } + } + return k.SignValue < 0 ? q.Negate() : q; + } + + public static ECPoint ValidatePoint(ECPoint p) + { + if (!p.IsValid()) + throw new InvalidOperationException("Invalid point"); + + return p; + } + + public static ECPoint CleanPoint(ECCurve c, ECPoint p) + { + ECCurve cp = p.Curve; + if (!c.Equals(cp)) + throw new ArgumentException("Point must be on the same curve", "p"); + + return c.DecodePoint(p.GetEncoded(false)); + } + + internal static ECPoint ImplCheckResult(ECPoint p) + { + if (!p.IsValidPartial()) + throw new InvalidOperationException("Invalid result"); + + return p; + } + + internal static ECPoint ImplShamirsTrickJsf(ECPoint P, BigInteger k, ECPoint Q, BigInteger l) + { + ECCurve curve = P.Curve; + ECPoint infinity = curve.Infinity; + + // TODO conjugate co-Z addition (ZADDC) can return both of these + ECPoint PaddQ = P.Add(Q); + ECPoint PsubQ = P.Subtract(Q); + + ECPoint[] points = new ECPoint[] { Q, PsubQ, P, PaddQ }; + curve.NormalizeAll(points); + + ECPoint[] table = new ECPoint[] { + points[3].Negate(), points[2].Negate(), points[1].Negate(), + points[0].Negate(), infinity, points[0], + points[1], points[2], points[3] }; + + byte[] jsf = WNafUtilities.GenerateJsf(k, l); + + ECPoint R = infinity; + + int i = jsf.Length; + while (--i >= 0) + { + int jsfi = jsf[i]; + + // NOTE: The shifting ensures the sign is extended correctly + int kDigit = ((jsfi << 24) >> 28), lDigit = ((jsfi << 28) >> 28); + + int index = 4 + (kDigit * 3) + lDigit; + R = R.TwicePlus(table[index]); + } + + return R; + } + + internal static ECPoint ImplShamirsTrickWNaf(ECPoint P, BigInteger k, + ECPoint Q, BigInteger l) + { + bool negK = k.SignValue < 0, negL = l.SignValue < 0; + + BigInteger kAbs = k.Abs(), lAbs = l.Abs(); + + int minWidthP = WNafUtilities.GetWindowSize(kAbs.BitLength, 8); + int minWidthQ = WNafUtilities.GetWindowSize(lAbs.BitLength, 8); + + WNafPreCompInfo infoP = WNafUtilities.Precompute(P, minWidthP, true); + WNafPreCompInfo infoQ = WNafUtilities.Precompute(Q, minWidthQ, true); + + // When P, Q are 'promoted' (i.e. reused several times), switch to fixed-point algorithm + { + ECCurve c = P.Curve; + int combSize = FixedPointUtilities.GetCombSize(c); + if (!negK && !negL + && k.BitLength <= combSize && l.BitLength <= combSize + && infoP.IsPromoted && infoQ.IsPromoted) + { + return ImplShamirsTrickFixedPoint(P, k, Q, l); + } + } + + int widthP = System.Math.Min(8, infoP.Width); + int widthQ = System.Math.Min(8, infoQ.Width); + + ECPoint[] preCompP = negK ? infoP.PreCompNeg : infoP.PreComp; + ECPoint[] preCompQ = negL ? infoQ.PreCompNeg : infoQ.PreComp; + ECPoint[] preCompNegP = negK ? infoP.PreComp : infoP.PreCompNeg; + ECPoint[] preCompNegQ = negL ? infoQ.PreComp : infoQ.PreCompNeg; + + byte[] wnafP = WNafUtilities.GenerateWindowNaf(widthP, kAbs); + byte[] wnafQ = WNafUtilities.GenerateWindowNaf(widthQ, lAbs); + + return ImplShamirsTrickWNaf(preCompP, preCompNegP, wnafP, preCompQ, preCompNegQ, wnafQ); + } + + internal static ECPoint ImplShamirsTrickWNaf(ECEndomorphism endomorphism, ECPoint P, BigInteger k, BigInteger l) + { + bool negK = k.SignValue < 0, negL = l.SignValue < 0; + + k = k.Abs(); + l = l.Abs(); + + int minWidth = WNafUtilities.GetWindowSize(System.Math.Max(k.BitLength, l.BitLength), 8); + + WNafPreCompInfo infoP = WNafUtilities.Precompute(P, minWidth, true); + ECPoint Q = EndoUtilities.MapPoint(endomorphism, P); + WNafPreCompInfo infoQ = WNafUtilities.PrecomputeWithPointMap(Q, endomorphism.PointMap, infoP, true); + + int widthP = System.Math.Min(8, infoP.Width); + int widthQ = System.Math.Min(8, infoQ.Width); + + ECPoint[] preCompP = negK ? infoP.PreCompNeg : infoP.PreComp; + ECPoint[] preCompQ = negL ? infoQ.PreCompNeg : infoQ.PreComp; + ECPoint[] preCompNegP = negK ? infoP.PreComp : infoP.PreCompNeg; + ECPoint[] preCompNegQ = negL ? infoQ.PreComp : infoQ.PreCompNeg; + + byte[] wnafP = WNafUtilities.GenerateWindowNaf(widthP, k); + byte[] wnafQ = WNafUtilities.GenerateWindowNaf(widthQ, l); + + return ImplShamirsTrickWNaf(preCompP, preCompNegP, wnafP, preCompQ, preCompNegQ, wnafQ); + } + + private static ECPoint ImplShamirsTrickWNaf(ECPoint[] preCompP, ECPoint[] preCompNegP, byte[] wnafP, + ECPoint[] preCompQ, ECPoint[] preCompNegQ, byte[] wnafQ) + { + int len = System.Math.Max(wnafP.Length, wnafQ.Length); + + ECCurve curve = preCompP[0].Curve; + ECPoint infinity = curve.Infinity; + + ECPoint R = infinity; + int zeroes = 0; + + for (int i = len - 1; i >= 0; --i) + { + int wiP = i < wnafP.Length ? (int)(sbyte)wnafP[i] : 0; + int wiQ = i < wnafQ.Length ? (int)(sbyte)wnafQ[i] : 0; + + if ((wiP | wiQ) == 0) + { + ++zeroes; + continue; + } + + ECPoint r = infinity; + if (wiP != 0) + { + int nP = System.Math.Abs(wiP); + ECPoint[] tableP = wiP < 0 ? preCompNegP : preCompP; + r = r.Add(tableP[nP >> 1]); + } + if (wiQ != 0) + { + int nQ = System.Math.Abs(wiQ); + ECPoint[] tableQ = wiQ < 0 ? preCompNegQ : preCompQ; + r = r.Add(tableQ[nQ >> 1]); + } + + if (zeroes > 0) + { + R = R.TimesPow2(zeroes); + zeroes = 0; + } + + R = R.TwicePlus(r); + } + + if (zeroes > 0) + { + R = R.TimesPow2(zeroes); + } + + return R; + } + + internal static ECPoint ImplSumOfMultiplies(ECPoint[] ps, BigInteger[] ks) + { + int count = ps.Length; + bool[] negs = new bool[count]; + WNafPreCompInfo[] infos = new WNafPreCompInfo[count]; + byte[][] wnafs = new byte[count][]; + + for (int i = 0; i < count; ++i) + { + BigInteger ki = ks[i]; negs[i] = ki.SignValue < 0; ki = ki.Abs(); + + int minWidth = WNafUtilities.GetWindowSize(ki.BitLength, 8); + WNafPreCompInfo info = WNafUtilities.Precompute(ps[i], minWidth, true); + + int width = System.Math.Min(8, info.Width); + + infos[i] = info; + wnafs[i] = WNafUtilities.GenerateWindowNaf(width, ki); + } + + return ImplSumOfMultiplies(negs, infos, wnafs); + } + + internal static ECPoint ImplSumOfMultipliesGlv(ECPoint[] ps, BigInteger[] ks, GlvEndomorphism glvEndomorphism) + { + BigInteger n = ps[0].Curve.Order; + + int len = ps.Length; + + BigInteger[] abs = new BigInteger[len << 1]; + for (int i = 0, j = 0; i < len; ++i) + { + BigInteger[] ab = glvEndomorphism.DecomposeScalar(ks[i].Mod(n)); + abs[j++] = ab[0]; + abs[j++] = ab[1]; + } + + if (glvEndomorphism.HasEfficientPointMap) + { + return ImplSumOfMultiplies(glvEndomorphism, ps, abs); + } + + ECPoint[] pqs = new ECPoint[len << 1]; + for (int i = 0, j = 0; i < len; ++i) + { + ECPoint p = ps[i]; + ECPoint q = EndoUtilities.MapPoint(glvEndomorphism, p); + pqs[j++] = p; + pqs[j++] = q; + } + + return ImplSumOfMultiplies(pqs, abs); + } + + internal static ECPoint ImplSumOfMultiplies(ECEndomorphism endomorphism, ECPoint[] ps, BigInteger[] ks) + { + int halfCount = ps.Length, fullCount = halfCount << 1; + + bool[] negs = new bool[fullCount]; + WNafPreCompInfo[] infos = new WNafPreCompInfo[fullCount]; + byte[][] wnafs = new byte[fullCount][]; + + ECPointMap pointMap = endomorphism.PointMap; + + for (int i = 0; i < halfCount; ++i) + { + int j0 = i << 1, j1 = j0 + 1; + + BigInteger kj0 = ks[j0]; negs[j0] = kj0.SignValue < 0; kj0 = kj0.Abs(); + BigInteger kj1 = ks[j1]; negs[j1] = kj1.SignValue < 0; kj1 = kj1.Abs(); + + int minWidth = WNafUtilities.GetWindowSize(System.Math.Max(kj0.BitLength, kj1.BitLength), 8); + + ECPoint P = ps[i]; + WNafPreCompInfo infoP = WNafUtilities.Precompute(P, minWidth, true); + ECPoint Q = EndoUtilities.MapPoint(endomorphism, P); + WNafPreCompInfo infoQ = WNafUtilities.PrecomputeWithPointMap(Q, pointMap, infoP, true); + + int widthP = System.Math.Min(8, infoP.Width); + int widthQ = System.Math.Min(8, infoQ.Width); + + infos[j0] = infoP; + infos[j1] = infoQ; + wnafs[j0] = WNafUtilities.GenerateWindowNaf(widthP, kj0); + wnafs[j1] = WNafUtilities.GenerateWindowNaf(widthQ, kj1); + } + + return ImplSumOfMultiplies(negs, infos, wnafs); + } + + private static ECPoint ImplSumOfMultiplies(bool[] negs, WNafPreCompInfo[] infos, byte[][] wnafs) + { + int len = 0, count = wnafs.Length; + for (int i = 0; i < count; ++i) + { + len = System.Math.Max(len, wnafs[i].Length); + } + + ECCurve curve = infos[0].PreComp[0].Curve; + ECPoint infinity = curve.Infinity; + + ECPoint R = infinity; + int zeroes = 0; + + for (int i = len - 1; i >= 0; --i) + { + ECPoint r = infinity; + + for (int j = 0; j < count; ++j) + { + byte[] wnaf = wnafs[j]; + int wi = i < wnaf.Length ? (int)(sbyte)wnaf[i] : 0; + if (wi != 0) + { + int n = System.Math.Abs(wi); + WNafPreCompInfo info = infos[j]; + ECPoint[] table = (wi < 0 == negs[j]) ? info.PreComp : info.PreCompNeg; + r = r.Add(table[n >> 1]); + } + } + + if (r == infinity) + { + ++zeroes; + continue; + } + + if (zeroes > 0) + { + R = R.TimesPow2(zeroes); + zeroes = 0; + } + + R = R.TwicePlus(r); + } + + if (zeroes > 0) + { + R = R.TimesPow2(zeroes); + } + + return R; + } + + private static ECPoint ImplShamirsTrickFixedPoint(ECPoint p, BigInteger k, ECPoint q, BigInteger l) + { + ECCurve c = p.Curve; + int combSize = FixedPointUtilities.GetCombSize(c); + + if (k.BitLength > combSize || l.BitLength > combSize) + { + /* + * TODO The comb works best when the scalars are less than the (possibly unknown) order. + * Still, if we want to handle larger scalars, we could allow customization of the comb + * size, or alternatively we could deal with the 'extra' bits either by running the comb + * multiple times as necessary, or by using an alternative multiplier as prelude. + */ + throw new InvalidOperationException("fixed-point comb doesn't support scalars larger than the curve order"); + } + + FixedPointPreCompInfo infoP = FixedPointUtilities.Precompute(p); + FixedPointPreCompInfo infoQ = FixedPointUtilities.Precompute(q); + + ECLookupTable lookupTableP = infoP.LookupTable; + ECLookupTable lookupTableQ = infoQ.LookupTable; + + int widthP = infoP.Width; + int widthQ = infoQ.Width; + + // TODO This shouldn't normally happen, but a better "solution" is desirable anyway + if (widthP != widthQ) + { + FixedPointCombMultiplier m = new FixedPointCombMultiplier(); + ECPoint r1 = m.Multiply(p, k); + ECPoint r2 = m.Multiply(q, l); + return r1.Add(r2); + } + + int width = widthP; + + int d = (combSize + width - 1) / width; + + ECPoint R = c.Infinity; + + int fullComb = d * width; + uint[] K = Nat.FromBigInteger(fullComb, k); + uint[] L = Nat.FromBigInteger(fullComb, l); + + int top = fullComb - 1; + for (int i = 0; i < d; ++i) + { + uint secretIndexK = 0, secretIndexL = 0; + + for (int j = top - i; j >= 0; j -= d) + { + uint secretBitK = K[j >> 5] >> (j & 0x1F); + secretIndexK ^= secretBitK >> 1; + secretIndexK <<= 1; + secretIndexK ^= secretBitK; + + uint secretBitL = L[j >> 5] >> (j & 0x1F); + secretIndexL ^= secretBitL >> 1; + secretIndexL <<= 1; + secretIndexL ^= secretBitL; + } + + ECPoint addP = lookupTableP.LookupVar((int)secretIndexK); + ECPoint addQ = lookupTableQ.LookupVar((int)secretIndexL); + + ECPoint T = addP.Add(addQ); + + R = R.TwicePlus(T); + } + + return R.Add(infoP.Offset).Add(infoQ.Offset); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ECAlgorithms.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ECAlgorithms.cs.meta new file mode 100644 index 0000000..c06408d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ECAlgorithms.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c798be5b8dc2c9a47be5981dac6c4a99 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ECCurve.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ECCurve.cs new file mode 100644 index 0000000..f011b1b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ECCurve.cs @@ -0,0 +1,1418 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Math.EC.Abc; +using Org.BouncyCastle.Math.EC.Endo; +using Org.BouncyCastle.Math.EC.Multiplier; +using Org.BouncyCastle.Math.Field; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math.EC +{ + /// Base class for an elliptic curve. + public abstract class ECCurve + { + public const int COORD_AFFINE = 0; + public const int COORD_HOMOGENEOUS = 1; + public const int COORD_JACOBIAN = 2; + public const int COORD_JACOBIAN_CHUDNOVSKY = 3; + public const int COORD_JACOBIAN_MODIFIED = 4; + public const int COORD_LAMBDA_AFFINE = 5; + public const int COORD_LAMBDA_PROJECTIVE = 6; + public const int COORD_SKEWED = 7; + + public static int[] GetAllCoordinateSystems() + { + return new int[]{ COORD_AFFINE, COORD_HOMOGENEOUS, COORD_JACOBIAN, COORD_JACOBIAN_CHUDNOVSKY, + COORD_JACOBIAN_MODIFIED, COORD_LAMBDA_AFFINE, COORD_LAMBDA_PROJECTIVE, COORD_SKEWED }; + } + + public class Config + { + protected ECCurve outer; + protected int coord; + protected ECEndomorphism endomorphism; + protected ECMultiplier multiplier; + + internal Config(ECCurve outer, int coord, ECEndomorphism endomorphism, ECMultiplier multiplier) + { + this.outer = outer; + this.coord = coord; + this.endomorphism = endomorphism; + this.multiplier = multiplier; + } + + public Config SetCoordinateSystem(int coord) + { + this.coord = coord; + return this; + } + + public Config SetEndomorphism(ECEndomorphism endomorphism) + { + this.endomorphism = endomorphism; + return this; + } + + public Config SetMultiplier(ECMultiplier multiplier) + { + this.multiplier = multiplier; + return this; + } + + public ECCurve Create() + { + if (!outer.SupportsCoordinateSystem(coord)) + { + throw new InvalidOperationException("unsupported coordinate system"); + } + + ECCurve c = outer.CloneCurve(); + if (c == outer) + { + throw new InvalidOperationException("implementation returned current curve"); + } + + c.m_coord = coord; + c.m_endomorphism = endomorphism; + c.m_multiplier = multiplier; + + return c; + } + } + + protected readonly IFiniteField m_field; + protected ECFieldElement m_a, m_b; + protected BigInteger m_order, m_cofactor; + + protected int m_coord = COORD_AFFINE; + protected ECEndomorphism m_endomorphism = null; + protected ECMultiplier m_multiplier = null; + + protected ECCurve(IFiniteField field) + { + this.m_field = field; + } + + public abstract int FieldSize { get; } + public abstract ECFieldElement FromBigInteger(BigInteger x); + public abstract bool IsValidFieldElement(BigInteger x); + + public abstract ECFieldElement RandomFieldElement(SecureRandom r); + + public abstract ECFieldElement RandomFieldElementMult(SecureRandom r); + + public virtual Config Configure() + { + return new Config(this, this.m_coord, this.m_endomorphism, this.m_multiplier); + } + + public virtual ECPoint ValidatePoint(BigInteger x, BigInteger y) + { + ECPoint p = CreatePoint(x, y); + if (!p.IsValid()) + { + throw new ArgumentException("Invalid point coordinates"); + } + return p; + } + + [Obsolete("Per-point compression property will be removed")] + public virtual ECPoint ValidatePoint(BigInteger x, BigInteger y, bool withCompression) + { + ECPoint p = CreatePoint(x, y, withCompression); + if (!p.IsValid()) + { + throw new ArgumentException("Invalid point coordinates"); + } + return p; + } + + public virtual ECPoint CreatePoint(BigInteger x, BigInteger y) + { + return CreatePoint(x, y, false); + } + + [Obsolete("Per-point compression property will be removed")] + public virtual ECPoint CreatePoint(BigInteger x, BigInteger y, bool withCompression) + { + return CreateRawPoint(FromBigInteger(x), FromBigInteger(y), withCompression); + } + + protected abstract ECCurve CloneCurve(); + + protected internal abstract ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression); + + protected internal abstract ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression); + + protected virtual ECMultiplier CreateDefaultMultiplier() + { + GlvEndomorphism glvEndomorphism = m_endomorphism as GlvEndomorphism; + if (glvEndomorphism != null) + { + return new GlvMultiplier(this, glvEndomorphism); + } + + return new WNafL2RMultiplier(); + } + + public virtual bool SupportsCoordinateSystem(int coord) + { + return coord == COORD_AFFINE; + } + + public virtual PreCompInfo GetPreCompInfo(ECPoint point, string name) + { + CheckPoint(point); + + IDictionary table; + lock (point) + { + table = point.m_preCompTable; + } + + if (null == table) + return null; + + lock (table) + { + return (PreCompInfo)table[name]; + } + } + + /** + * Compute a PreCompInfo for a point on this curve, under a given name. Used by + * ECMultipliers to save the precomputation for this ECPoint for use + * by subsequent multiplication. + * + * @param point + * The ECPoint to store precomputations for. + * @param name + * A String used to index precomputations of different types. + * @param callback + * Called to calculate the PreCompInfo. + */ + public virtual PreCompInfo Precompute(ECPoint point, string name, IPreCompCallback callback) + { + CheckPoint(point); + + IDictionary table; + lock (point) + { + table = point.m_preCompTable; + if (null == table) + { + point.m_preCompTable = table = Platform.CreateHashtable(4); + } + } + + lock (table) + { + PreCompInfo existing = (PreCompInfo)table[name]; + PreCompInfo result = callback.Precompute(existing); + + if (result != existing) + { + table[name] = result; + } + + return result; + } + } + + public virtual ECPoint ImportPoint(ECPoint p) + { + if (this == p.Curve) + { + return p; + } + if (p.IsInfinity) + { + return Infinity; + } + + // TODO Default behaviour could be improved if the two curves have the same coordinate system by copying any Z coordinates. + p = p.Normalize(); + + return CreatePoint(p.XCoord.ToBigInteger(), p.YCoord.ToBigInteger(), p.IsCompressed); + } + + /** + * Normalization ensures that any projective coordinate is 1, and therefore that the x, y + * coordinates reflect those of the equivalent point in an affine coordinate system. Where more + * than one point is to be normalized, this method will generally be more efficient than + * normalizing each point separately. + * + * @param points + * An array of points that will be updated in place with their normalized versions, + * where necessary + */ + public virtual void NormalizeAll(ECPoint[] points) + { + NormalizeAll(points, 0, points.Length, null); + } + + /** + * Normalization ensures that any projective coordinate is 1, and therefore that the x, y + * coordinates reflect those of the equivalent point in an affine coordinate system. Where more + * than one point is to be normalized, this method will generally be more efficient than + * normalizing each point separately. An (optional) z-scaling factor can be applied; effectively + * each z coordinate is scaled by this value prior to normalization (but only one + * actual multiplication is needed). + * + * @param points + * An array of points that will be updated in place with their normalized versions, + * where necessary + * @param off + * The start of the range of points to normalize + * @param len + * The length of the range of points to normalize + * @param iso + * The (optional) z-scaling factor - can be null + */ + public virtual void NormalizeAll(ECPoint[] points, int off, int len, ECFieldElement iso) + { + CheckPoints(points, off, len); + + switch (this.CoordinateSystem) + { + case ECCurve.COORD_AFFINE: + case ECCurve.COORD_LAMBDA_AFFINE: + { + if (iso != null) + throw new ArgumentException("not valid for affine coordinates", "iso"); + + return; + } + } + + /* + * Figure out which of the points actually need to be normalized + */ + ECFieldElement[] zs = new ECFieldElement[len]; + int[] indices = new int[len]; + int count = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + if (null != p && (iso != null || !p.IsNormalized())) + { + zs[count] = p.GetZCoord(0); + indices[count++] = off + i; + } + } + + if (count == 0) + { + return; + } + + ECAlgorithms.MontgomeryTrick(zs, 0, count, iso); + + for (int j = 0; j < count; ++j) + { + int index = indices[j]; + points[index] = points[index].Normalize(zs[j]); + } + } + + public abstract ECPoint Infinity { get; } + + public virtual IFiniteField Field + { + get { return m_field; } + } + + public virtual ECFieldElement A + { + get { return m_a; } + } + + public virtual ECFieldElement B + { + get { return m_b; } + } + + public virtual BigInteger Order + { + get { return m_order; } + } + + public virtual BigInteger Cofactor + { + get { return m_cofactor; } + } + + public virtual int CoordinateSystem + { + get { return m_coord; } + } + + /** + * Create a cache-safe lookup table for the specified sequence of points. All the points MUST + * belong to this ECCurve instance, and MUST already be normalized. + */ + public virtual ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + int FE_BYTES = (FieldSize + 7) / 8; + byte[] table = new byte[len * FE_BYTES * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + byte[] px = p.RawXCoord.ToBigInteger().ToByteArray(); + byte[] py = p.RawYCoord.ToBigInteger().ToByteArray(); + + int pxStart = px.Length > FE_BYTES ? 1 : 0, pxLen = px.Length - pxStart; + int pyStart = py.Length > FE_BYTES ? 1 : 0, pyLen = py.Length - pyStart; + + Array.Copy(px, pxStart, table, pos + FE_BYTES - pxLen, pxLen); pos += FE_BYTES; + Array.Copy(py, pyStart, table, pos + FE_BYTES - pyLen, pyLen); pos += FE_BYTES; + } + } + + return new DefaultLookupTable(this, table, len); + } + + protected virtual void CheckPoint(ECPoint point) + { + if (null == point || (this != point.Curve)) + throw new ArgumentException("must be non-null and on this curve", "point"); + } + + protected virtual void CheckPoints(ECPoint[] points) + { + CheckPoints(points, 0, points.Length); + } + + protected virtual void CheckPoints(ECPoint[] points, int off, int len) + { + if (points == null) + throw new ArgumentNullException("points"); + if (off < 0 || len < 0 || (off > (points.Length - len))) + throw new ArgumentException("invalid range specified", "points"); + + for (int i = 0; i < len; ++i) + { + ECPoint point = points[off + i]; + if (null != point && this != point.Curve) + throw new ArgumentException("entries must be null or on this curve", "points"); + } + } + + public virtual bool Equals(ECCurve other) + { + if (this == other) + return true; + if (null == other) + return false; + return Field.Equals(other.Field) + && A.ToBigInteger().Equals(other.A.ToBigInteger()) + && B.ToBigInteger().Equals(other.B.ToBigInteger()); + } + + public override bool Equals(object obj) + { + return Equals(obj as ECCurve); + } + + public override int GetHashCode() + { + return Field.GetHashCode() + ^ Integers.RotateLeft(A.ToBigInteger().GetHashCode(), 8) + ^ Integers.RotateLeft(B.ToBigInteger().GetHashCode(), 16); + } + + protected abstract ECPoint DecompressPoint(int yTilde, BigInteger X1); + + public virtual ECEndomorphism GetEndomorphism() + { + return m_endomorphism; + } + + /** + * Sets the default ECMultiplier, unless already set. + * + * We avoid locking for performance reasons, so there is no uniqueness guarantee. + */ + public virtual ECMultiplier GetMultiplier() + { + if (this.m_multiplier == null) + { + this.m_multiplier = CreateDefaultMultiplier(); + } + return this.m_multiplier; + } + + /** + * Decode a point on this curve from its ASN.1 encoding. The different + * encodings are taken account of, including point compression for + * Fp (X9.62 s 4.2.1 pg 17). + * @return The decoded point. + */ + public virtual ECPoint DecodePoint(byte[] encoded) + { + ECPoint p = null; + int expectedLength = (FieldSize + 7) / 8; + + byte type = encoded[0]; + switch (type) + { + case 0x00: // infinity + { + if (encoded.Length != 1) + throw new ArgumentException("Incorrect length for infinity encoding", "encoded"); + + p = Infinity; + break; + } + + case 0x02: // compressed + case 0x03: // compressed + { + if (encoded.Length != (expectedLength + 1)) + throw new ArgumentException("Incorrect length for compressed encoding", "encoded"); + + int yTilde = type & 1; + BigInteger X = new BigInteger(1, encoded, 1, expectedLength); + + p = DecompressPoint(yTilde, X); + if (!p.ImplIsValid(true, true)) + throw new ArgumentException("Invalid point"); + + break; + } + + case 0x04: // uncompressed + { + if (encoded.Length != (2 * expectedLength + 1)) + throw new ArgumentException("Incorrect length for uncompressed encoding", "encoded"); + + BigInteger X = new BigInteger(1, encoded, 1, expectedLength); + BigInteger Y = new BigInteger(1, encoded, 1 + expectedLength, expectedLength); + + p = ValidatePoint(X, Y); + break; + } + + case 0x06: // hybrid + case 0x07: // hybrid + { + if (encoded.Length != (2 * expectedLength + 1)) + throw new ArgumentException("Incorrect length for hybrid encoding", "encoded"); + + BigInteger X = new BigInteger(1, encoded, 1, expectedLength); + BigInteger Y = new BigInteger(1, encoded, 1 + expectedLength, expectedLength); + + if (Y.TestBit(0) != (type == 0x07)) + throw new ArgumentException("Inconsistent Y coordinate in hybrid encoding", "encoded"); + + p = ValidatePoint(X, Y); + break; + } + + default: + throw new FormatException("Invalid point encoding " + type); + } + + if (type != 0x00 && p.IsInfinity) + throw new ArgumentException("Invalid infinity encoding", "encoded"); + + return p; + } + + private class DefaultLookupTable + : AbstractECLookupTable + { + private readonly ECCurve m_outer; + private readonly byte[] m_table; + private readonly int m_size; + + internal DefaultLookupTable(ECCurve outer, byte[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public override int Size + { + get { return m_size; } + } + + public override ECPoint Lookup(int index) + { + int FE_BYTES = (m_outer.FieldSize + 7) / 8; + byte[] x = new byte[FE_BYTES], y = new byte[FE_BYTES]; + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + byte MASK = (byte)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < FE_BYTES; ++j) + { + x[j] ^= (byte)(m_table[pos + j] & MASK); + y[j] ^= (byte)(m_table[pos + FE_BYTES + j] & MASK); + } + + pos += (FE_BYTES * 2); + } + + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + int FE_BYTES = (m_outer.FieldSize + 7) / 8; + byte[] x = new byte[FE_BYTES], y = new byte[FE_BYTES]; + int pos = index * FE_BYTES * 2; + + for (int j = 0; j < FE_BYTES; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + FE_BYTES + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(byte[] x, byte[] y) + { + ECFieldElement X = m_outer.FromBigInteger(new BigInteger(1, x)); + ECFieldElement Y = m_outer.FromBigInteger(new BigInteger(1, y)); + return m_outer.CreateRawPoint(X, Y, false); + } + } + } + + public abstract class AbstractFpCurve + : ECCurve + { + protected AbstractFpCurve(BigInteger q) + : base(FiniteFields.GetPrimeField(q)) + { + } + + public override bool IsValidFieldElement(BigInteger x) + { + return x != null && x.SignValue >= 0 && x.CompareTo(Field.Characteristic) < 0; + } + + public override ECFieldElement RandomFieldElement(SecureRandom r) + { + /* + * NOTE: BigInteger comparisons in the rejection sampling are not constant-time, so we + * use the product of two independent elements to mitigate side-channels. + */ + BigInteger p = Field.Characteristic; + ECFieldElement fe1 = FromBigInteger(ImplRandomFieldElement(r, p)); + ECFieldElement fe2 = FromBigInteger(ImplRandomFieldElement(r, p)); + return fe1.Multiply(fe2); + } + + public override ECFieldElement RandomFieldElementMult(SecureRandom r) + { + /* + * NOTE: BigInteger comparisons in the rejection sampling are not constant-time, so we + * use the product of two independent elements to mitigate side-channels. + */ + BigInteger p = Field.Characteristic; + ECFieldElement fe1 = FromBigInteger(ImplRandomFieldElementMult(r, p)); + ECFieldElement fe2 = FromBigInteger(ImplRandomFieldElementMult(r, p)); + return fe1.Multiply(fe2); + } + + protected override ECPoint DecompressPoint(int yTilde, BigInteger X1) + { + ECFieldElement x = FromBigInteger(X1); + ECFieldElement rhs = x.Square().Add(A).Multiply(x).Add(B); + ECFieldElement y = rhs.Sqrt(); + + /* + * If y is not a square, then we haven't got a point on the curve + */ + if (y == null) + throw new ArgumentException("Invalid point compression"); + + if (y.TestBitZero() != (yTilde == 1)) + { + // Use the other root + y = y.Negate(); + } + + return CreateRawPoint(x, y, true); + } + + private static BigInteger ImplRandomFieldElement(SecureRandom r, BigInteger p) + { + BigInteger x; + do + { + x = BigIntegers.CreateRandomBigInteger(p.BitLength, r); + } + while (x.CompareTo(p) >= 0); + return x; + } + + private static BigInteger ImplRandomFieldElementMult(SecureRandom r, BigInteger p) + { + BigInteger x; + do + { + x = BigIntegers.CreateRandomBigInteger(p.BitLength, r); + } + while (x.SignValue <= 0 || x.CompareTo(p) >= 0); + return x; + } + } + + /** + * Elliptic curve over Fp + */ + public class FpCurve + : AbstractFpCurve + { + private const int FP_DEFAULT_COORDS = COORD_JACOBIAN_MODIFIED; + + protected readonly BigInteger m_q, m_r; + protected readonly FpPoint m_infinity; + + [Obsolete("Use constructor taking order/cofactor")] + public FpCurve(BigInteger q, BigInteger a, BigInteger b) + : this(q, a, b, null, null) + { + } + + public FpCurve(BigInteger q, BigInteger a, BigInteger b, BigInteger order, BigInteger cofactor) + : base(q) + { + this.m_q = q; + this.m_r = FpFieldElement.CalculateResidue(q); + this.m_infinity = new FpPoint(this, null, null, false); + + this.m_a = FromBigInteger(a); + this.m_b = FromBigInteger(b); + this.m_order = order; + this.m_cofactor = cofactor; + this.m_coord = FP_DEFAULT_COORDS; + } + + [Obsolete("Use constructor taking order/cofactor")] + protected FpCurve(BigInteger q, BigInteger r, ECFieldElement a, ECFieldElement b) + : this(q, r, a, b, null, null) + { + } + + protected FpCurve(BigInteger q, BigInteger r, ECFieldElement a, ECFieldElement b, BigInteger order, BigInteger cofactor) + : base(q) + { + this.m_q = q; + this.m_r = r; + this.m_infinity = new FpPoint(this, null, null, false); + + this.m_a = a; + this.m_b = b; + this.m_order = order; + this.m_cofactor = cofactor; + this.m_coord = FP_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new FpCurve(m_q, m_r, m_a, m_b, m_order, m_cofactor); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_AFFINE: + case COORD_HOMOGENEOUS: + case COORD_JACOBIAN: + case COORD_JACOBIAN_MODIFIED: + return true; + default: + return false; + } + } + + public virtual BigInteger Q + { + get { return m_q; } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return m_q.BitLength; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new FpFieldElement(this.m_q, this.m_r, x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new FpPoint(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new FpPoint(this, x, y, zs, withCompression); + } + + public override ECPoint ImportPoint(ECPoint p) + { + if (this != p.Curve && this.CoordinateSystem == COORD_JACOBIAN && !p.IsInfinity) + { + switch (p.Curve.CoordinateSystem) + { + case COORD_JACOBIAN: + case COORD_JACOBIAN_CHUDNOVSKY: + case COORD_JACOBIAN_MODIFIED: + return new FpPoint(this, + FromBigInteger(p.RawXCoord.ToBigInteger()), + FromBigInteger(p.RawYCoord.ToBigInteger()), + new ECFieldElement[] { FromBigInteger(p.GetZCoord(0).ToBigInteger()) }, + p.IsCompressed); + default: + break; + } + } + + return base.ImportPoint(p); + } + } + + public abstract class AbstractF2mCurve + : ECCurve + { + public static BigInteger Inverse(int m, int[] ks, BigInteger x) + { + return new LongArray(x).ModInverse(m, ks).ToBigInteger(); + } + + /** + * The auxiliary values s0 and + * s1 used for partial modular reduction for + * Koblitz curves. + */ + private BigInteger[] si = null; + + private static IFiniteField BuildField(int m, int k1, int k2, int k3) + { + if (k1 == 0) + { + throw new ArgumentException("k1 must be > 0"); + } + + if (k2 == 0) + { + if (k3 != 0) + { + throw new ArgumentException("k3 must be 0 if k2 == 0"); + } + + return FiniteFields.GetBinaryExtensionField(new int[]{ 0, k1, m }); + } + + if (k2 <= k1) + { + throw new ArgumentException("k2 must be > k1"); + } + + if (k3 <= k2) + { + throw new ArgumentException("k3 must be > k2"); + } + + return FiniteFields.GetBinaryExtensionField(new int[]{ 0, k1, k2, k3, m }); + } + + protected AbstractF2mCurve(int m, int k1, int k2, int k3) + : base(BuildField(m, k1, k2, k3)) + { + } + + [Obsolete("Per-point compression property will be removed")] + public override ECPoint CreatePoint(BigInteger x, BigInteger y, bool withCompression) + { + ECFieldElement X = FromBigInteger(x), Y = FromBigInteger(y); + + switch (this.CoordinateSystem) + { + case COORD_LAMBDA_AFFINE: + case COORD_LAMBDA_PROJECTIVE: + { + if (X.IsZero) + { + if (!Y.Square().Equals(B)) + throw new ArgumentException(); + } + else + { + // Y becomes Lambda (X + Y/X) here + Y = Y.Divide(X).Add(X); + } + break; + } + default: + { + break; + } + } + + return CreateRawPoint(X, Y, withCompression); + } + + public override bool IsValidFieldElement(BigInteger x) + { + return x != null && x.SignValue >= 0 && x.BitLength <= FieldSize; + } + + public override ECFieldElement RandomFieldElement(SecureRandom r) + { + int m = FieldSize; + return FromBigInteger(BigIntegers.CreateRandomBigInteger(m, r)); + } + + public override ECFieldElement RandomFieldElementMult(SecureRandom r) + { + /* + * NOTE: BigInteger comparisons in the rejection sampling are not constant-time, so we + * use the product of two independent elements to mitigate side-channels. + */ + int m = FieldSize; + ECFieldElement fe1 = FromBigInteger(ImplRandomFieldElementMult(r, m)); + ECFieldElement fe2 = FromBigInteger(ImplRandomFieldElementMult(r, m)); + return fe1.Multiply(fe2); + } + + protected override ECPoint DecompressPoint(int yTilde, BigInteger X1) + { + ECFieldElement xp = FromBigInteger(X1), yp = null; + if (xp.IsZero) + { + yp = B.Sqrt(); + } + else + { + ECFieldElement beta = xp.Square().Invert().Multiply(B).Add(A).Add(xp); + ECFieldElement z = SolveQuadraticEquation(beta); + + if (z != null) + { + if (z.TestBitZero() != (yTilde == 1)) + { + z = z.AddOne(); + } + + switch (this.CoordinateSystem) + { + case COORD_LAMBDA_AFFINE: + case COORD_LAMBDA_PROJECTIVE: + { + yp = z.Add(xp); + break; + } + default: + { + yp = z.Multiply(xp); + break; + } + } + } + } + + if (yp == null) + throw new ArgumentException("Invalid point compression"); + + return CreateRawPoint(xp, yp, true); + } + + /** + * Solves a quadratic equation z2 + z = beta(X9.62 + * D.1.6) The other solution is z + 1. + * + * @param beta + * The value to solve the quadratic equation for. + * @return the solution for z2 + z = beta or + * null if no solution exists. + */ + internal ECFieldElement SolveQuadraticEquation(ECFieldElement beta) + { + AbstractF2mFieldElement betaF2m = (AbstractF2mFieldElement)beta; + + bool fastTrace = betaF2m.HasFastTrace; + if (fastTrace && 0 != betaF2m.Trace()) + return null; + + int m = FieldSize; + + // For odd m, use the half-trace + if (0 != (m & 1)) + { + ECFieldElement r = betaF2m.HalfTrace(); + if (fastTrace || r.Square().Add(r).Add(beta).IsZero) + return r; + + return null; + } + + if (beta.IsZero) + return beta; + + ECFieldElement gamma, z, zeroElement = FromBigInteger(BigInteger.Zero); + + do + { + ECFieldElement t = FromBigInteger(BigInteger.Arbitrary(m)); + z = zeroElement; + ECFieldElement w = beta; + for (int i = 1; i < m; i++) + { + ECFieldElement w2 = w.Square(); + z = z.Square().Add(w2.Multiply(t)); + w = w2.Add(beta); + } + if (!w.IsZero) + { + return null; + } + gamma = z.Square().Add(z); + } + while (gamma.IsZero); + + return z; + } + + /** + * @return the auxiliary values s0 and + * s1 used for partial modular reduction for + * Koblitz curves. + */ + internal virtual BigInteger[] GetSi() + { + if (si == null) + { + lock (this) + { + if (si == null) + { + si = Tnaf.GetSi(this); + } + } + } + return si; + } + + /** + * Returns true if this is a Koblitz curve (ABC curve). + * @return true if this is a Koblitz curve (ABC curve), false otherwise + */ + public virtual bool IsKoblitz + { + get + { + return m_order != null && m_cofactor != null && m_b.IsOne && (m_a.IsZero || m_a.IsOne); + } + } + + private static BigInteger ImplRandomFieldElementMult(SecureRandom r, int m) + { + BigInteger x; + do + { + x = BigIntegers.CreateRandomBigInteger(m, r); + } + while (x.SignValue <= 0); + return x; + } + } + + /** + * Elliptic curves over F2m. The Weierstrass equation is given by + * y2 + xy = x3 + ax2 + b. + */ + public class F2mCurve + : AbstractF2mCurve + { + private const int F2M_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + + /** + * The exponent m of F2m. + */ + private readonly int m; + + /** + * TPB: The integer k where xm + + * xk + 1 represents the reduction polynomial + * f(z).
    + * PPB: The integer k1 where xm + + * xk3 + xk2 + xk1 + 1 + * represents the reduction polynomial f(z).
    + */ + private readonly int k1; + + /** + * TPB: Always set to 0
    + * PPB: The integer k2 where xm + + * xk3 + xk2 + xk1 + 1 + * represents the reduction polynomial f(z).
    + */ + private readonly int k2; + + /** + * TPB: Always set to 0
    + * PPB: The integer k3 where xm + + * xk3 + xk2 + xk1 + 1 + * represents the reduction polynomial f(z).
    + */ + private readonly int k3; + + /** + * The point at infinity on this curve. + */ + protected readonly F2mPoint m_infinity; + + /** + * Constructor for Trinomial Polynomial Basis (TPB). + * @param m The exponent m of + * F2m. + * @param k The integer k where xm + + * xk + 1 represents the reduction + * polynomial f(z). + * @param a The coefficient a in the Weierstrass equation + * for non-supersingular elliptic curves over + * F2m. + * @param b The coefficient b in the Weierstrass equation + * for non-supersingular elliptic curves over + * F2m. + */ + [Obsolete("Use constructor taking order/cofactor")] + public F2mCurve( + int m, + int k, + BigInteger a, + BigInteger b) + : this(m, k, 0, 0, a, b, null, null) + { + } + + /** + * Constructor for Trinomial Polynomial Basis (TPB). + * @param m The exponent m of + * F2m. + * @param k The integer k where xm + + * xk + 1 represents the reduction + * polynomial f(z). + * @param a The coefficient a in the Weierstrass equation + * for non-supersingular elliptic curves over + * F2m. + * @param b The coefficient b in the Weierstrass equation + * for non-supersingular elliptic curves over + * F2m. + * @param order The order of the main subgroup of the elliptic curve. + * @param cofactor The cofactor of the elliptic curve, i.e. + * #Ea(F2m) = h * n. + */ + public F2mCurve( + int m, + int k, + BigInteger a, + BigInteger b, + BigInteger order, + BigInteger cofactor) + : this(m, k, 0, 0, a, b, order, cofactor) + { + } + + /** + * Constructor for Pentanomial Polynomial Basis (PPB). + * @param m The exponent m of + * F2m. + * @param k1 The integer k1 where xm + + * xk3 + xk2 + xk1 + 1 + * represents the reduction polynomial f(z). + * @param k2 The integer k2 where xm + + * xk3 + xk2 + xk1 + 1 + * represents the reduction polynomial f(z). + * @param k3 The integer k3 where xm + + * xk3 + xk2 + xk1 + 1 + * represents the reduction polynomial f(z). + * @param a The coefficient a in the Weierstrass equation + * for non-supersingular elliptic curves over + * F2m. + * @param b The coefficient b in the Weierstrass equation + * for non-supersingular elliptic curves over + * F2m. + */ + [Obsolete("Use constructor taking order/cofactor")] + public F2mCurve( + int m, + int k1, + int k2, + int k3, + BigInteger a, + BigInteger b) + : this(m, k1, k2, k3, a, b, null, null) + { + } + + /** + * Constructor for Pentanomial Polynomial Basis (PPB). + * @param m The exponent m of + * F2m. + * @param k1 The integer k1 where xm + + * xk3 + xk2 + xk1 + 1 + * represents the reduction polynomial f(z). + * @param k2 The integer k2 where xm + + * xk3 + xk2 + xk1 + 1 + * represents the reduction polynomial f(z). + * @param k3 The integer k3 where xm + + * xk3 + xk2 + xk1 + 1 + * represents the reduction polynomial f(z). + * @param a The coefficient a in the Weierstrass equation + * for non-supersingular elliptic curves over + * F2m. + * @param b The coefficient b in the Weierstrass equation + * for non-supersingular elliptic curves over + * F2m. + * @param order The order of the main subgroup of the elliptic curve. + * @param cofactor The cofactor of the elliptic curve, i.e. + * #Ea(F2m) = h * n. + */ + public F2mCurve( + int m, + int k1, + int k2, + int k3, + BigInteger a, + BigInteger b, + BigInteger order, + BigInteger cofactor) + : base(m, k1, k2, k3) + { + this.m = m; + this.k1 = k1; + this.k2 = k2; + this.k3 = k3; + this.m_order = order; + this.m_cofactor = cofactor; + this.m_infinity = new F2mPoint(this, null, null, false); + + if (k1 == 0) + throw new ArgumentException("k1 must be > 0"); + + if (k2 == 0) + { + if (k3 != 0) + throw new ArgumentException("k3 must be 0 if k2 == 0"); + } + else + { + if (k2 <= k1) + throw new ArgumentException("k2 must be > k1"); + + if (k3 <= k2) + throw new ArgumentException("k3 must be > k2"); + } + + this.m_a = FromBigInteger(a); + this.m_b = FromBigInteger(b); + this.m_coord = F2M_DEFAULT_COORDS; + } + + protected F2mCurve(int m, int k1, int k2, int k3, ECFieldElement a, ECFieldElement b, BigInteger order, BigInteger cofactor) + : base(m, k1, k2, k3) + { + this.m = m; + this.k1 = k1; + this.k2 = k2; + this.k3 = k3; + this.m_order = order; + this.m_cofactor = cofactor; + + this.m_infinity = new F2mPoint(this, null, null, false); + this.m_a = a; + this.m_b = b; + this.m_coord = F2M_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new F2mCurve(m, k1, k2, k3, m_a, m_b, m_order, m_cofactor); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_AFFINE: + case COORD_HOMOGENEOUS: + case COORD_LAMBDA_PROJECTIVE: + return true; + default: + return false; + } + } + + protected override ECMultiplier CreateDefaultMultiplier() + { + if (IsKoblitz) + { + return new WTauNafMultiplier(); + } + + return base.CreateDefaultMultiplier(); + } + + public override int FieldSize + { + get { return m; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new F2mFieldElement(this.m, this.k1, this.k2, this.k3, x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new F2mPoint(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new F2mPoint(this, x, y, zs, withCompression); + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public int M + { + get { return m; } + } + + /** + * Return true if curve uses a Trinomial basis. + * + * @return true if curve Trinomial, false otherwise. + */ + public bool IsTrinomial() + { + return k2 == 0 && k3 == 0; + } + + public int K1 + { + get { return k1; } + } + + public int K2 + { + get { return k2; } + } + + public int K3 + { + get { return k3; } + } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + int FE_LONGS = (m + 63) / 64; + + long[] table = new long[len * FE_LONGS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + ((F2mFieldElement)p.RawXCoord).x.CopyTo(table, pos); pos += FE_LONGS; + ((F2mFieldElement)p.RawYCoord).x.CopyTo(table, pos); pos += FE_LONGS; + } + } + + return new DefaultF2mLookupTable(this, table, len); + } + + private class DefaultF2mLookupTable + : AbstractECLookupTable + { + private readonly F2mCurve m_outer; + private readonly long[] m_table; + private readonly int m_size; + + internal DefaultF2mLookupTable(F2mCurve outer, long[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public override int Size + { + get { return m_size; } + } + + public override ECPoint Lookup(int index) + { + int FE_LONGS = (m_outer.m + 63) / 64; + long[] x = new long[FE_LONGS], y = new long[FE_LONGS]; + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + long MASK =((i ^ index) - 1) >> 31; + + for (int j = 0; j < FE_LONGS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + FE_LONGS + j] & MASK; + } + + pos += (FE_LONGS * 2); + } + + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + int FE_LONGS = (m_outer.m + 63) / 64; + long[] x = new long[FE_LONGS], y = new long[FE_LONGS]; + int pos = index * FE_LONGS * 2; + + for (int j = 0; j < FE_LONGS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + FE_LONGS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(long[] x, long[] y) + { + int m = m_outer.m; + int[] ks = m_outer.IsTrinomial() ? new int[] { m_outer.k1 } : new int[] { m_outer.k1, m_outer.k2, m_outer.k3 }; + + ECFieldElement X = new F2mFieldElement(m, ks, new LongArray(x)); + ECFieldElement Y = new F2mFieldElement(m, ks, new LongArray(y)); + return m_outer.CreateRawPoint(X, Y, false); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ECCurve.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ECCurve.cs.meta new file mode 100644 index 0000000..68bac6e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ECCurve.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0499d904f779c994483ee35317b076e4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ECFieldElement.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ECFieldElement.cs new file mode 100644 index 0000000..ed530b6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ECFieldElement.cs @@ -0,0 +1,998 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math.EC +{ + public abstract class ECFieldElement + { + public abstract BigInteger ToBigInteger(); + public abstract string FieldName { get; } + public abstract int FieldSize { get; } + public abstract ECFieldElement Add(ECFieldElement b); + public abstract ECFieldElement AddOne(); + public abstract ECFieldElement Subtract(ECFieldElement b); + public abstract ECFieldElement Multiply(ECFieldElement b); + public abstract ECFieldElement Divide(ECFieldElement b); + public abstract ECFieldElement Negate(); + public abstract ECFieldElement Square(); + public abstract ECFieldElement Invert(); + public abstract ECFieldElement Sqrt(); + + public virtual int BitLength + { + get { return ToBigInteger().BitLength; } + } + + public virtual bool IsOne + { + get { return BitLength == 1; } + } + + public virtual bool IsZero + { + get { return 0 == ToBigInteger().SignValue; } + } + + public virtual ECFieldElement MultiplyMinusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) + { + return Multiply(b).Subtract(x.Multiply(y)); + } + + public virtual ECFieldElement MultiplyPlusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) + { + return Multiply(b).Add(x.Multiply(y)); + } + + public virtual ECFieldElement SquareMinusProduct(ECFieldElement x, ECFieldElement y) + { + return Square().Subtract(x.Multiply(y)); + } + + public virtual ECFieldElement SquarePlusProduct(ECFieldElement x, ECFieldElement y) + { + return Square().Add(x.Multiply(y)); + } + + public virtual ECFieldElement SquarePow(int pow) + { + ECFieldElement r = this; + for (int i = 0; i < pow; ++i) + { + r = r.Square(); + } + return r; + } + + public virtual bool TestBitZero() + { + return ToBigInteger().TestBit(0); + } + + public override bool Equals(object obj) + { + return Equals(obj as ECFieldElement); + } + + public virtual bool Equals(ECFieldElement other) + { + if (this == other) + return true; + if (null == other) + return false; + return ToBigInteger().Equals(other.ToBigInteger()); + } + + public override int GetHashCode() + { + return ToBigInteger().GetHashCode(); + } + + public override string ToString() + { + return this.ToBigInteger().ToString(16); + } + + public virtual byte[] GetEncoded() + { + return BigIntegers.AsUnsignedByteArray((FieldSize + 7) / 8, ToBigInteger()); + } + } + + public abstract class AbstractFpFieldElement + : ECFieldElement + { + } + + public class FpFieldElement + : AbstractFpFieldElement + { + private readonly BigInteger q, r, x; + + internal static BigInteger CalculateResidue(BigInteger p) + { + int bitLength = p.BitLength; + if (bitLength >= 96) + { + BigInteger firstWord = p.ShiftRight(bitLength - 64); + if (firstWord.LongValue == -1L) + { + return BigInteger.One.ShiftLeft(bitLength).Subtract(p); + } + if ((bitLength & 7) == 0) + { + return BigInteger.One.ShiftLeft(bitLength << 1).Divide(p).Negate(); + } + } + return null; + } + + [Obsolete("Use ECCurve.FromBigInteger to construct field elements")] + public FpFieldElement(BigInteger q, BigInteger x) + : this(q, CalculateResidue(q), x) + { + } + + internal FpFieldElement(BigInteger q, BigInteger r, BigInteger x) + { + if (x == null || x.SignValue < 0 || x.CompareTo(q) >= 0) + throw new ArgumentException("value invalid in Fp field element", "x"); + + this.q = q; + this.r = r; + this.x = x; + } + + public override BigInteger ToBigInteger() + { + return x; + } + + /** + * return the field name for this field. + * + * @return the string "Fp". + */ + public override string FieldName + { + get { return "Fp"; } + } + + public override int FieldSize + { + get { return q.BitLength; } + } + + public BigInteger Q + { + get { return q; } + } + + public override ECFieldElement Add( + ECFieldElement b) + { + return new FpFieldElement(q, r, ModAdd(x, b.ToBigInteger())); + } + + public override ECFieldElement AddOne() + { + BigInteger x2 = x.Add(BigInteger.One); + if (x2.CompareTo(q) == 0) + { + x2 = BigInteger.Zero; + } + return new FpFieldElement(q, r, x2); + } + + public override ECFieldElement Subtract( + ECFieldElement b) + { + return new FpFieldElement(q, r, ModSubtract(x, b.ToBigInteger())); + } + + public override ECFieldElement Multiply( + ECFieldElement b) + { + return new FpFieldElement(q, r, ModMult(x, b.ToBigInteger())); + } + + public override ECFieldElement MultiplyMinusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) + { + BigInteger ax = this.x, bx = b.ToBigInteger(), xx = x.ToBigInteger(), yx = y.ToBigInteger(); + BigInteger ab = ax.Multiply(bx); + BigInteger xy = xx.Multiply(yx); + return new FpFieldElement(q, r, ModReduce(ab.Subtract(xy))); + } + + public override ECFieldElement MultiplyPlusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) + { + BigInteger ax = this.x, bx = b.ToBigInteger(), xx = x.ToBigInteger(), yx = y.ToBigInteger(); + BigInteger ab = ax.Multiply(bx); + BigInteger xy = xx.Multiply(yx); + BigInteger sum = ab.Add(xy); + if (r != null && r.SignValue < 0 && sum.BitLength > (q.BitLength << 1)) + { + sum = sum.Subtract(q.ShiftLeft(q.BitLength)); + } + return new FpFieldElement(q, r, ModReduce(sum)); + } + + public override ECFieldElement Divide( + ECFieldElement b) + { + return new FpFieldElement(q, r, ModMult(x, ModInverse(b.ToBigInteger()))); + } + + public override ECFieldElement Negate() + { + return x.SignValue == 0 ? this : new FpFieldElement(q, r, q.Subtract(x)); + } + + public override ECFieldElement Square() + { + return new FpFieldElement(q, r, ModMult(x, x)); + } + + public override ECFieldElement SquareMinusProduct(ECFieldElement x, ECFieldElement y) + { + BigInteger ax = this.x, xx = x.ToBigInteger(), yx = y.ToBigInteger(); + BigInteger aa = ax.Multiply(ax); + BigInteger xy = xx.Multiply(yx); + return new FpFieldElement(q, r, ModReduce(aa.Subtract(xy))); + } + + public override ECFieldElement SquarePlusProduct(ECFieldElement x, ECFieldElement y) + { + BigInteger ax = this.x, xx = x.ToBigInteger(), yx = y.ToBigInteger(); + BigInteger aa = ax.Multiply(ax); + BigInteger xy = xx.Multiply(yx); + BigInteger sum = aa.Add(xy); + if (r != null && r.SignValue < 0 && sum.BitLength > (q.BitLength << 1)) + { + sum = sum.Subtract(q.ShiftLeft(q.BitLength)); + } + return new FpFieldElement(q, r, ModReduce(sum)); + } + + public override ECFieldElement Invert() + { + // TODO Modular inversion can be faster for a (Generalized) Mersenne Prime. + return new FpFieldElement(q, r, ModInverse(x)); + } + + /** + * return a sqrt root - the routine verifies that the calculation + * returns the right value - if none exists it returns null. + */ + public override ECFieldElement Sqrt() + { + if (IsZero || IsOne) + return this; + + if (!q.TestBit(0)) + throw Platform.CreateNotImplementedException("even value of q"); + + if (q.TestBit(1)) // q == 4m + 3 + { + BigInteger e = q.ShiftRight(2).Add(BigInteger.One); + return CheckSqrt(new FpFieldElement(q, r, x.ModPow(e, q))); + } + + if (q.TestBit(2)) // q == 8m + 5 + { + BigInteger t1 = x.ModPow(q.ShiftRight(3), q); + BigInteger t2 = ModMult(t1, x); + BigInteger t3 = ModMult(t2, t1); + + if (t3.Equals(BigInteger.One)) + { + return CheckSqrt(new FpFieldElement(q, r, t2)); + } + + // TODO This is constant and could be precomputed + BigInteger t4 = BigInteger.Two.ModPow(q.ShiftRight(2), q); + + BigInteger y = ModMult(t2, t4); + + return CheckSqrt(new FpFieldElement(q, r, y)); + } + + // q == 8m + 1 + + BigInteger legendreExponent = q.ShiftRight(1); + if (!(x.ModPow(legendreExponent, q).Equals(BigInteger.One))) + return null; + + BigInteger X = this.x; + BigInteger fourX = ModDouble(ModDouble(X)); ; + + BigInteger k = legendreExponent.Add(BigInteger.One), qMinusOne = q.Subtract(BigInteger.One); + + BigInteger U, V; + do + { + BigInteger P; + do + { + P = BigInteger.Arbitrary(q.BitLength); + } + while (P.CompareTo(q) >= 0 + || !ModReduce(P.Multiply(P).Subtract(fourX)).ModPow(legendreExponent, q).Equals(qMinusOne)); + + BigInteger[] result = LucasSequence(P, X, k); + U = result[0]; + V = result[1]; + + if (ModMult(V, V).Equals(fourX)) + { + return new FpFieldElement(q, r, ModHalfAbs(V)); + } + } + while (U.Equals(BigInteger.One) || U.Equals(qMinusOne)); + + return null; + } + + private ECFieldElement CheckSqrt(ECFieldElement z) + { + return z.Square().Equals(this) ? z : null; + } + + private BigInteger[] LucasSequence( + BigInteger P, + BigInteger Q, + BigInteger k) + { + // TODO Research and apply "common-multiplicand multiplication here" + + int n = k.BitLength; + int s = k.GetLowestSetBit(); + + Debug.Assert(k.TestBit(s)); + + BigInteger Uh = BigInteger.One; + BigInteger Vl = BigInteger.Two; + BigInteger Vh = P; + BigInteger Ql = BigInteger.One; + BigInteger Qh = BigInteger.One; + + for (int j = n - 1; j >= s + 1; --j) + { + Ql = ModMult(Ql, Qh); + + if (k.TestBit(j)) + { + Qh = ModMult(Ql, Q); + Uh = ModMult(Uh, Vh); + Vl = ModReduce(Vh.Multiply(Vl).Subtract(P.Multiply(Ql))); + Vh = ModReduce(Vh.Multiply(Vh).Subtract(Qh.ShiftLeft(1))); + } + else + { + Qh = Ql; + Uh = ModReduce(Uh.Multiply(Vl).Subtract(Ql)); + Vh = ModReduce(Vh.Multiply(Vl).Subtract(P.Multiply(Ql))); + Vl = ModReduce(Vl.Multiply(Vl).Subtract(Ql.ShiftLeft(1))); + } + } + + Ql = ModMult(Ql, Qh); + Qh = ModMult(Ql, Q); + Uh = ModReduce(Uh.Multiply(Vl).Subtract(Ql)); + Vl = ModReduce(Vh.Multiply(Vl).Subtract(P.Multiply(Ql))); + Ql = ModMult(Ql, Qh); + + for (int j = 1; j <= s; ++j) + { + Uh = ModMult(Uh, Vl); + Vl = ModReduce(Vl.Multiply(Vl).Subtract(Ql.ShiftLeft(1))); + Ql = ModMult(Ql, Ql); + } + + return new BigInteger[] { Uh, Vl }; + } + + protected virtual BigInteger ModAdd(BigInteger x1, BigInteger x2) + { + BigInteger x3 = x1.Add(x2); + if (x3.CompareTo(q) >= 0) + { + x3 = x3.Subtract(q); + } + return x3; + } + + protected virtual BigInteger ModDouble(BigInteger x) + { + BigInteger _2x = x.ShiftLeft(1); + if (_2x.CompareTo(q) >= 0) + { + _2x = _2x.Subtract(q); + } + return _2x; + } + + protected virtual BigInteger ModHalf(BigInteger x) + { + if (x.TestBit(0)) + { + x = q.Add(x); + } + return x.ShiftRight(1); + } + + protected virtual BigInteger ModHalfAbs(BigInteger x) + { + if (x.TestBit(0)) + { + x = q.Subtract(x); + } + return x.ShiftRight(1); + } + + protected virtual BigInteger ModInverse(BigInteger x) + { + return BigIntegers.ModOddInverse(q, x); + } + + protected virtual BigInteger ModMult(BigInteger x1, BigInteger x2) + { + return ModReduce(x1.Multiply(x2)); + } + + protected virtual BigInteger ModReduce(BigInteger x) + { + if (r == null) + { + x = x.Mod(q); + } + else + { + bool negative = x.SignValue < 0; + if (negative) + { + x = x.Abs(); + } + int qLen = q.BitLength; + if (r.SignValue > 0) + { + BigInteger qMod = BigInteger.One.ShiftLeft(qLen); + bool rIsOne = r.Equals(BigInteger.One); + while (x.BitLength > (qLen + 1)) + { + BigInteger u = x.ShiftRight(qLen); + BigInteger v = x.Remainder(qMod); + if (!rIsOne) + { + u = u.Multiply(r); + } + x = u.Add(v); + } + } + else + { + int d = ((qLen - 1) & 31) + 1; + BigInteger mu = r.Negate(); + BigInteger u = mu.Multiply(x.ShiftRight(qLen - d)); + BigInteger quot = u.ShiftRight(qLen + d); + BigInteger v = quot.Multiply(q); + BigInteger bk1 = BigInteger.One.ShiftLeft(qLen + d); + v = v.Remainder(bk1); + x = x.Remainder(bk1); + x = x.Subtract(v); + if (x.SignValue < 0) + { + x = x.Add(bk1); + } + } + while (x.CompareTo(q) >= 0) + { + x = x.Subtract(q); + } + if (negative && x.SignValue != 0) + { + x = q.Subtract(x); + } + } + return x; + } + + protected virtual BigInteger ModSubtract(BigInteger x1, BigInteger x2) + { + BigInteger x3 = x1.Subtract(x2); + if (x3.SignValue < 0) + { + x3 = x3.Add(q); + } + return x3; + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + FpFieldElement other = obj as FpFieldElement; + + if (other == null) + return false; + + return Equals(other); + } + + public virtual bool Equals( + FpFieldElement other) + { + return q.Equals(other.q) && base.Equals(other); + } + + public override int GetHashCode() + { + return q.GetHashCode() ^ base.GetHashCode(); + } + } + + public abstract class AbstractF2mFieldElement + : ECFieldElement + { + public virtual ECFieldElement HalfTrace() + { + int m = FieldSize; + if ((m & 1) == 0) + throw new InvalidOperationException("Half-trace only defined for odd m"); + + //ECFieldElement ht = this; + //for (int i = 1; i < m; i += 2) + //{ + // ht = ht.SquarePow(2).Add(this); + //} + + int n = (m + 1) >> 1; + int k = 31 - Integers.NumberOfLeadingZeros(n); + int nk = 1; + + ECFieldElement ht = this; + while (k > 0) + { + ht = ht.SquarePow(nk << 1).Add(ht); + nk = n >> --k; + if (0 != (nk & 1)) + { + ht = ht.SquarePow(2).Add(this); + } + } + + return ht; + } + + public virtual bool HasFastTrace + { + get { return false; } + } + + public virtual int Trace() + { + int m = FieldSize; + + //ECFieldElement tr = this; + //for (int i = 1; i < m; ++i) + //{ + // tr = tr.Square().Add(this); + //} + + int k = 31 - Integers.NumberOfLeadingZeros(m); + int mk = 1; + + ECFieldElement tr = this; + while (k > 0) + { + tr = tr.SquarePow(mk).Add(tr); + mk = m >> --k; + if (0 != (mk & 1)) + { + tr = tr.Square().Add(this); + } + } + + if (tr.IsZero) + return 0; + if (tr.IsOne) + return 1; + throw new InvalidOperationException("Internal error in trace calculation"); + } + } + + /** + * Class representing the Elements of the finite field + * F2m in polynomial basis (PB) + * representation. Both trinomial (Tpb) and pentanomial (Ppb) polynomial + * basis representations are supported. Gaussian normal basis (GNB) + * representation is not supported. + */ + public class F2mFieldElement + : AbstractF2mFieldElement + { + /** + * Indicates gaussian normal basis representation (GNB). Number chosen + * according to X9.62. GNB is not implemented at present. + */ + public const int Gnb = 1; + + /** + * Indicates trinomial basis representation (Tpb). Number chosen + * according to X9.62. + */ + public const int Tpb = 2; + + /** + * Indicates pentanomial basis representation (Ppb). Number chosen + * according to X9.62. + */ + public const int Ppb = 3; + + /** + * Tpb or Ppb. + */ + private int representation; + + /** + * The exponent m of F2m. + */ + private int m; + + private int[] ks; + + /** + * The LongArray holding the bits. + */ + internal LongArray x; + + /** + * Constructor for Ppb. + * @param m The exponent m of + * F2m. + * @param k1 The integer k1 where xm + + * xk3 + xk2 + xk1 + 1 + * represents the reduction polynomial f(z). + * @param k2 The integer k2 where xm + + * xk3 + xk2 + xk1 + 1 + * represents the reduction polynomial f(z). + * @param k3 The integer k3 where xm + + * xk3 + xk2 + xk1 + 1 + * represents the reduction polynomial f(z). + * @param x The BigInteger representing the value of the field element. + */ + [Obsolete("Use ECCurve.FromBigInteger to construct field elements")] + public F2mFieldElement( + int m, + int k1, + int k2, + int k3, + BigInteger x) + { + if (x == null || x.SignValue < 0 || x.BitLength > m) + throw new ArgumentException("value invalid in F2m field element", "x"); + + if ((k2 == 0) && (k3 == 0)) + { + this.representation = Tpb; + this.ks = new int[] { k1 }; + } + else + { + if (k2 >= k3) + throw new ArgumentException("k2 must be smaller than k3"); + if (k2 <= 0) + throw new ArgumentException("k2 must be larger than 0"); + + this.representation = Ppb; + this.ks = new int[] { k1, k2, k3 }; + } + + this.m = m; + this.x = new LongArray(x); + } + + /** + * Constructor for Tpb. + * @param m The exponent m of + * F2m. + * @param k The integer k where xm + + * xk + 1 represents the reduction + * polynomial f(z). + * @param x The BigInteger representing the value of the field element. + */ + [Obsolete("Use ECCurve.FromBigInteger to construct field elements")] + public F2mFieldElement( + int m, + int k, + BigInteger x) + : this(m, k, 0, 0, x) + { + // Set k1 to k, and set k2 and k3 to 0 + } + + internal F2mFieldElement(int m, int[] ks, LongArray x) + { + this.m = m; + this.representation = (ks.Length == 1) ? Tpb : Ppb; + this.ks = ks; + this.x = x; + } + + public override int BitLength + { + get { return x.Degree(); } + } + + public override bool IsOne + { + get { return x.IsOne(); } + } + + public override bool IsZero + { + get { return x.IsZero(); } + } + + public override bool TestBitZero() + { + return x.TestBitZero(); + } + + public override BigInteger ToBigInteger() + { + return x.ToBigInteger(); + } + + public override string FieldName + { + get { return "F2m"; } + } + + public override int FieldSize + { + get { return m; } + } + + /** + * Checks, if the ECFieldElements a and b + * are elements of the same field F2m + * (having the same representation). + * @param a field element. + * @param b field element to be compared. + * @throws ArgumentException if a and b + * are not elements of the same field + * F2m (having the same + * representation). + */ + public static void CheckFieldElements( + ECFieldElement a, + ECFieldElement b) + { + if (!(a is F2mFieldElement) || !(b is F2mFieldElement)) + { + throw new ArgumentException("Field elements are not " + + "both instances of F2mFieldElement"); + } + + F2mFieldElement aF2m = (F2mFieldElement)a; + F2mFieldElement bF2m = (F2mFieldElement)b; + + if (aF2m.representation != bF2m.representation) + { + // Should never occur + throw new ArgumentException("One of the F2m field elements has incorrect representation"); + } + + if ((aF2m.m != bF2m.m) || !Arrays.AreEqual(aF2m.ks, bF2m.ks)) + { + throw new ArgumentException("Field elements are not elements of the same field F2m"); + } + } + + public override ECFieldElement Add( + ECFieldElement b) + { + // No check performed here for performance reasons. Instead the + // elements involved are checked in ECPoint.F2m + // checkFieldElements(this, b); + LongArray iarrClone = this.x.Copy(); + F2mFieldElement bF2m = (F2mFieldElement)b; + iarrClone.AddShiftedByWords(bF2m.x, 0); + return new F2mFieldElement(m, ks, iarrClone); + } + + public override ECFieldElement AddOne() + { + return new F2mFieldElement(m, ks, x.AddOne()); + } + + public override ECFieldElement Subtract( + ECFieldElement b) + { + // Addition and subtraction are the same in F2m + return Add(b); + } + + public override ECFieldElement Multiply( + ECFieldElement b) + { + // Right-to-left comb multiplication in the LongArray + // Input: Binary polynomials a(z) and b(z) of degree at most m-1 + // Output: c(z) = a(z) * b(z) mod f(z) + + // No check performed here for performance reasons. Instead the + // elements involved are checked in ECPoint.F2m + // checkFieldElements(this, b); + return new F2mFieldElement(m, ks, x.ModMultiply(((F2mFieldElement)b).x, m, ks)); + } + + public override ECFieldElement MultiplyMinusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) + { + return MultiplyPlusProduct(b, x, y); + } + + public override ECFieldElement MultiplyPlusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) + { + LongArray ax = this.x, bx = ((F2mFieldElement)b).x, xx = ((F2mFieldElement)x).x, yx = ((F2mFieldElement)y).x; + + LongArray ab = ax.Multiply(bx, m, ks); + LongArray xy = xx.Multiply(yx, m, ks); + + if (ab == ax || ab == bx) + { + ab = (LongArray)ab.Copy(); + } + + ab.AddShiftedByWords(xy, 0); + ab.Reduce(m, ks); + + return new F2mFieldElement(m, ks, ab); + } + + public override ECFieldElement Divide( + ECFieldElement b) + { + // There may be more efficient implementations + ECFieldElement bInv = b.Invert(); + return Multiply(bInv); + } + + public override ECFieldElement Negate() + { + // -x == x holds for all x in F2m + return this; + } + + public override ECFieldElement Square() + { + return new F2mFieldElement(m, ks, x.ModSquare(m, ks)); + } + + public override ECFieldElement SquareMinusProduct(ECFieldElement x, ECFieldElement y) + { + return SquarePlusProduct(x, y); + } + + public override ECFieldElement SquarePlusProduct(ECFieldElement x, ECFieldElement y) + { + LongArray ax = this.x, xx = ((F2mFieldElement)x).x, yx = ((F2mFieldElement)y).x; + + LongArray aa = ax.Square(m, ks); + LongArray xy = xx.Multiply(yx, m, ks); + + if (aa == ax) + { + aa = (LongArray)aa.Copy(); + } + + aa.AddShiftedByWords(xy, 0); + aa.Reduce(m, ks); + + return new F2mFieldElement(m, ks, aa); + } + + public override ECFieldElement SquarePow(int pow) + { + return pow < 1 ? this : new F2mFieldElement(m, ks, x.ModSquareN(pow, m, ks)); + } + + public override ECFieldElement Invert() + { + return new F2mFieldElement(this.m, this.ks, this.x.ModInverse(m, ks)); + } + + public override ECFieldElement Sqrt() + { + return (x.IsZero() || x.IsOne()) ? this : SquarePow(m - 1); + } + + /** + * @return the representation of the field + * F2m, either of + * {@link F2mFieldElement.Tpb} (trinomial + * basis representation) or + * {@link F2mFieldElement.Ppb} (pentanomial + * basis representation). + */ + public int Representation + { + get { return this.representation; } + } + + /** + * @return the degree m of the reduction polynomial + * f(z). + */ + public int M + { + get { return this.m; } + } + + /** + * @return Tpb: The integer k where xm + + * xk + 1 represents the reduction polynomial + * f(z).
    + * Ppb: The integer k1 where xm + + * xk3 + xk2 + xk1 + 1 + * represents the reduction polynomial f(z).
    + */ + public int K1 + { + get { return this.ks[0]; } + } + + /** + * @return Tpb: Always returns 0
    + * Ppb: The integer k2 where xm + + * xk3 + xk2 + xk1 + 1 + * represents the reduction polynomial f(z).
    + */ + public int K2 + { + get { return this.ks.Length >= 2 ? this.ks[1] : 0; } + } + + /** + * @return Tpb: Always set to 0
    + * Ppb: The integer k3 where xm + + * xk3 + xk2 + xk1 + 1 + * represents the reduction polynomial f(z).
    + */ + public int K3 + { + get { return this.ks.Length >= 3 ? this.ks[2] : 0; } + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + F2mFieldElement other = obj as F2mFieldElement; + + if (other == null) + return false; + + return Equals(other); + } + + public virtual bool Equals( + F2mFieldElement other) + { + return ((this.m == other.m) + && (this.representation == other.representation) + && Arrays.AreEqual(this.ks, other.ks) + && (this.x.Equals(other.x))); + } + + public override int GetHashCode() + { + return x.GetHashCode() ^ m ^ Arrays.GetHashCode(ks); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ECFieldElement.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ECFieldElement.cs.meta new file mode 100644 index 0000000..bbae168 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ECFieldElement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 658064efb54a0784f9c08a3b1b7f1410 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ECLookupTable.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ECLookupTable.cs new file mode 100644 index 0000000..c14087d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ECLookupTable.cs @@ -0,0 +1,11 @@ +using System; + +namespace Org.BouncyCastle.Math.EC +{ + public interface ECLookupTable + { + int Size { get; } + ECPoint Lookup(int index); + ECPoint LookupVar(int index); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ECLookupTable.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ECLookupTable.cs.meta new file mode 100644 index 0000000..9e613f7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ECLookupTable.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0396e9f1606cb9648a9282bde0a327e4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ECPoint.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ECPoint.cs new file mode 100644 index 0000000..efec49c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ECPoint.cs @@ -0,0 +1,2178 @@ +using System; +using System.Collections; +using System.Text; + +using Org.BouncyCastle.Math.EC.Multiplier; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Math.EC +{ + /** + * base class for points on elliptic curves. + */ + public abstract class ECPoint + { + private static readonly SecureRandom Random = new SecureRandom(); + + protected static ECFieldElement[] EMPTY_ZS = new ECFieldElement[0]; + + protected static ECFieldElement[] GetInitialZCoords(ECCurve curve) + { + // Cope with null curve, most commonly used by implicitlyCa + int coord = null == curve ? ECCurve.COORD_AFFINE : curve.CoordinateSystem; + + switch (coord) + { + case ECCurve.COORD_AFFINE: + case ECCurve.COORD_LAMBDA_AFFINE: + return EMPTY_ZS; + default: + break; + } + + ECFieldElement one = curve.FromBigInteger(BigInteger.One); + + switch (coord) + { + case ECCurve.COORD_HOMOGENEOUS: + case ECCurve.COORD_JACOBIAN: + case ECCurve.COORD_LAMBDA_PROJECTIVE: + return new ECFieldElement[] { one }; + case ECCurve.COORD_JACOBIAN_CHUDNOVSKY: + return new ECFieldElement[] { one, one, one }; + case ECCurve.COORD_JACOBIAN_MODIFIED: + return new ECFieldElement[] { one, curve.A }; + default: + throw new ArgumentException("unknown coordinate system"); + } + } + + protected internal readonly ECCurve m_curve; + protected internal readonly ECFieldElement m_x, m_y; + protected internal readonly ECFieldElement[] m_zs; + protected internal readonly bool m_withCompression; + + // Dictionary is (string -> PreCompInfo) + protected internal IDictionary m_preCompTable = null; + + protected ECPoint(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : this(curve, x, y, GetInitialZCoords(curve), withCompression) + { + } + + internal ECPoint(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + this.m_curve = curve; + this.m_x = x; + this.m_y = y; + this.m_zs = zs; + this.m_withCompression = withCompression; + } + + protected abstract bool SatisfiesCurveEquation(); + + protected virtual bool SatisfiesOrder() + { + if (BigInteger.One.Equals(Curve.Cofactor)) + return true; + + BigInteger n = Curve.Order; + + // TODO Require order to be available for all curves + + return n == null || ECAlgorithms.ReferenceMultiply(this, n).IsInfinity; + } + + public ECPoint GetDetachedPoint() + { + return Normalize().Detach(); + } + + public virtual ECCurve Curve + { + get { return m_curve; } + } + + protected abstract ECPoint Detach(); + + protected virtual int CurveCoordinateSystem + { + get + { + // Cope with null curve, most commonly used by implicitlyCa + return null == m_curve ? ECCurve.COORD_AFFINE : m_curve.CoordinateSystem; + } + } + + /** + * Returns the affine x-coordinate after checking that this point is normalized. + * + * @return The affine x-coordinate of this point + * @throws IllegalStateException if the point is not normalized + */ + public virtual ECFieldElement AffineXCoord + { + get + { + CheckNormalized(); + return XCoord; + } + } + + /** + * Returns the affine y-coordinate after checking that this point is normalized + * + * @return The affine y-coordinate of this point + * @throws IllegalStateException if the point is not normalized + */ + public virtual ECFieldElement AffineYCoord + { + get + { + CheckNormalized(); + return YCoord; + } + } + + /** + * Returns the x-coordinate. + * + * Caution: depending on the curve's coordinate system, this may not be the same value as in an + * affine coordinate system; use Normalize() to get a point where the coordinates have their + * affine values, or use AffineXCoord if you expect the point to already have been normalized. + * + * @return the x-coordinate of this point + */ + public virtual ECFieldElement XCoord + { + get { return m_x; } + } + + /** + * Returns the y-coordinate. + * + * Caution: depending on the curve's coordinate system, this may not be the same value as in an + * affine coordinate system; use Normalize() to get a point where the coordinates have their + * affine values, or use AffineYCoord if you expect the point to already have been normalized. + * + * @return the y-coordinate of this point + */ + public virtual ECFieldElement YCoord + { + get { return m_y; } + } + + public virtual ECFieldElement GetZCoord(int index) + { + return (index < 0 || index >= m_zs.Length) ? null : m_zs[index]; + } + + public virtual ECFieldElement[] GetZCoords() + { + int zsLen = m_zs.Length; + if (zsLen == 0) + { + return m_zs; + } + ECFieldElement[] copy = new ECFieldElement[zsLen]; + Array.Copy(m_zs, 0, copy, 0, zsLen); + return copy; + } + + protected internal ECFieldElement RawXCoord + { + get { return m_x; } + } + + protected internal ECFieldElement RawYCoord + { + get { return m_y; } + } + + protected internal ECFieldElement[] RawZCoords + { + get { return m_zs; } + } + + protected virtual void CheckNormalized() + { + if (!IsNormalized()) + throw new InvalidOperationException("point not in normal form"); + } + + public virtual bool IsNormalized() + { + int coord = this.CurveCoordinateSystem; + + return coord == ECCurve.COORD_AFFINE + || coord == ECCurve.COORD_LAMBDA_AFFINE + || IsInfinity + || RawZCoords[0].IsOne; + } + + /** + * Normalization ensures that any projective coordinate is 1, and therefore that the x, y + * coordinates reflect those of the equivalent point in an affine coordinate system. + * + * @return a new ECPoint instance representing the same point, but with normalized coordinates + */ + public virtual ECPoint Normalize() + { + if (this.IsInfinity) + { + return this; + } + + switch (this.CurveCoordinateSystem) + { + case ECCurve.COORD_AFFINE: + case ECCurve.COORD_LAMBDA_AFFINE: + { + return this; + } + default: + { + ECFieldElement z = RawZCoords[0]; + if (z.IsOne) + return this; + + if (null == m_curve) + throw new InvalidOperationException("Detached points must be in affine coordinates"); + + /* + * Use blinding to avoid the side-channel leak identified and analyzed in the paper + * "Yet another GCD based inversion side-channel affecting ECC implementations" by Nir + * Drucker and Shay Gueron. + * + * To blind the calculation of z^-1, choose a multiplicative (i.e. non-zero) field + * element 'b' uniformly at random, then calculate the result instead as (z * b)^-1 * b. + * Any side-channel in the implementation of 'inverse' now only leaks information about + * the value (z * b), and no longer reveals information about 'z' itself. + */ + // TODO Add CryptoServicesRegistrar class and use here + //SecureRandom r = CryptoServicesRegistrar.GetSecureRandom(); + SecureRandom r = Random; + ECFieldElement b = m_curve.RandomFieldElementMult(r); + ECFieldElement zInv = z.Multiply(b).Invert().Multiply(b); + return Normalize(zInv); + } + } + } + + internal virtual ECPoint Normalize(ECFieldElement zInv) + { + switch (this.CurveCoordinateSystem) + { + case ECCurve.COORD_HOMOGENEOUS: + case ECCurve.COORD_LAMBDA_PROJECTIVE: + { + return CreateScaledPoint(zInv, zInv); + } + case ECCurve.COORD_JACOBIAN: + case ECCurve.COORD_JACOBIAN_CHUDNOVSKY: + case ECCurve.COORD_JACOBIAN_MODIFIED: + { + ECFieldElement zInv2 = zInv.Square(), zInv3 = zInv2.Multiply(zInv); + return CreateScaledPoint(zInv2, zInv3); + } + default: + { + throw new InvalidOperationException("not a projective coordinate system"); + } + } + } + + protected virtual ECPoint CreateScaledPoint(ECFieldElement sx, ECFieldElement sy) + { + return Curve.CreateRawPoint(RawXCoord.Multiply(sx), RawYCoord.Multiply(sy), IsCompressed); + } + + public bool IsInfinity + { + get { return m_x == null && m_y == null; } + } + + public bool IsCompressed + { + get { return m_withCompression; } + } + + public bool IsValid() + { + return ImplIsValid(false, true); + } + + internal bool IsValidPartial() + { + return ImplIsValid(false, false); + } + + internal bool ImplIsValid(bool decompressed, bool checkOrder) + { + if (IsInfinity) + return true; + + ValidityCallback callback = new ValidityCallback(this, decompressed, checkOrder); + ValidityPreCompInfo validity = (ValidityPreCompInfo)Curve.Precompute(this, ValidityPreCompInfo.PRECOMP_NAME, callback); + return !validity.HasFailed(); + } + + public virtual ECPoint ScaleX(ECFieldElement scale) + { + return IsInfinity + ? this + : Curve.CreateRawPoint(RawXCoord.Multiply(scale), RawYCoord, RawZCoords, IsCompressed); + } + + public virtual ECPoint ScaleXNegateY(ECFieldElement scale) + { + return IsInfinity + ? this + : Curve.CreateRawPoint(RawXCoord.Multiply(scale), RawYCoord.Negate(), RawZCoords, IsCompressed); + } + + public virtual ECPoint ScaleY(ECFieldElement scale) + { + return IsInfinity + ? this + : Curve.CreateRawPoint(RawXCoord, RawYCoord.Multiply(scale), RawZCoords, IsCompressed); + } + + public virtual ECPoint ScaleYNegateX(ECFieldElement scale) + { + return IsInfinity + ? this + : Curve.CreateRawPoint(RawXCoord.Negate(), RawYCoord.Multiply(scale), RawZCoords, IsCompressed); + } + + public override bool Equals(object obj) + { + return Equals(obj as ECPoint); + } + + public virtual bool Equals(ECPoint other) + { + if (this == other) + return true; + if (null == other) + return false; + + ECCurve c1 = this.Curve, c2 = other.Curve; + bool n1 = (null == c1), n2 = (null == c2); + bool i1 = IsInfinity, i2 = other.IsInfinity; + + if (i1 || i2) + { + return (i1 && i2) && (n1 || n2 || c1.Equals(c2)); + } + + ECPoint p1 = this, p2 = other; + if (n1 && n2) + { + // Points with null curve are in affine form, so already normalized + } + else if (n1) + { + p2 = p2.Normalize(); + } + else if (n2) + { + p1 = p1.Normalize(); + } + else if (!c1.Equals(c2)) + { + return false; + } + else + { + // TODO Consider just requiring already normalized, to avoid silent performance degradation + + ECPoint[] points = new ECPoint[] { this, c1.ImportPoint(p2) }; + + // TODO This is a little strong, really only requires coZNormalizeAll to get Zs equal + c1.NormalizeAll(points); + + p1 = points[0]; + p2 = points[1]; + } + + return p1.XCoord.Equals(p2.XCoord) && p1.YCoord.Equals(p2.YCoord); + } + + public override int GetHashCode() + { + ECCurve c = this.Curve; + int hc = (null == c) ? 0 : ~c.GetHashCode(); + + if (!this.IsInfinity) + { + // TODO Consider just requiring already normalized, to avoid silent performance degradation + + ECPoint p = Normalize(); + + hc ^= p.XCoord.GetHashCode() * 17; + hc ^= p.YCoord.GetHashCode() * 257; + } + + return hc; + } + + public override string ToString() + { + if (this.IsInfinity) + { + return "INF"; + } + + StringBuilder sb = new StringBuilder(); + sb.Append('('); + sb.Append(RawXCoord); + sb.Append(','); + sb.Append(RawYCoord); + for (int i = 0; i < m_zs.Length; ++i) + { + sb.Append(','); + sb.Append(m_zs[i]); + } + sb.Append(')'); + return sb.ToString(); + } + + public virtual byte[] GetEncoded() + { + return GetEncoded(m_withCompression); + } + + public abstract byte[] GetEncoded(bool compressed); + + protected internal abstract bool CompressionYTilde { get; } + + public abstract ECPoint Add(ECPoint b); + public abstract ECPoint Subtract(ECPoint b); + public abstract ECPoint Negate(); + + public virtual ECPoint TimesPow2(int e) + { + if (e < 0) + throw new ArgumentException("cannot be negative", "e"); + + ECPoint p = this; + while (--e >= 0) + { + p = p.Twice(); + } + return p; + } + + public abstract ECPoint Twice(); + public abstract ECPoint Multiply(BigInteger b); + + public virtual ECPoint TwicePlus(ECPoint b) + { + return Twice().Add(b); + } + + public virtual ECPoint ThreeTimes() + { + return TwicePlus(this); + } + + private class ValidityCallback + : IPreCompCallback + { + private readonly ECPoint m_outer; + private readonly bool m_decompressed, m_checkOrder; + + internal ValidityCallback(ECPoint outer, bool decompressed, bool checkOrder) + { + this.m_outer = outer; + this.m_decompressed = decompressed; + this.m_checkOrder = checkOrder; + } + + public PreCompInfo Precompute(PreCompInfo existing) + { + ValidityPreCompInfo info = existing as ValidityPreCompInfo; + if (info == null) + { + info = new ValidityPreCompInfo(); + } + + if (info.HasFailed()) + return info; + + if (!info.HasCurveEquationPassed()) + { + if (!m_decompressed && !m_outer.SatisfiesCurveEquation()) + { + info.ReportFailed(); + return info; + } + info.ReportCurveEquationPassed(); + } + if (m_checkOrder && !info.HasOrderPassed()) + { + if (!m_outer.SatisfiesOrder()) + { + info.ReportFailed(); + return info; + } + info.ReportOrderPassed(); + } + return info; + } + } + } + + public abstract class ECPointBase + : ECPoint + { + protected internal ECPointBase( + ECCurve curve, + ECFieldElement x, + ECFieldElement y, + bool withCompression) + : base(curve, x, y, withCompression) + { + } + + protected internal ECPointBase(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + /** + * return the field element encoded with point compression. (S 4.3.6) + */ + public override byte[] GetEncoded(bool compressed) + { + if (this.IsInfinity) + { + return new byte[1]; + } + + ECPoint normed = Normalize(); + + byte[] X = normed.XCoord.GetEncoded(); + + if (compressed) + { + byte[] PO = new byte[X.Length + 1]; + PO[0] = (byte)(normed.CompressionYTilde ? 0x03 : 0x02); + Array.Copy(X, 0, PO, 1, X.Length); + return PO; + } + + byte[] Y = normed.YCoord.GetEncoded(); + + { + byte[] PO = new byte[X.Length + Y.Length + 1]; + PO[0] = 0x04; + Array.Copy(X, 0, PO, 1, X.Length); + Array.Copy(Y, 0, PO, X.Length + 1, Y.Length); + return PO; + } + } + + /** + * Multiplies this ECPoint by the given number. + * @param k The multiplicator. + * @return k * this. + */ + public override ECPoint Multiply(BigInteger k) + { + return this.Curve.GetMultiplier().Multiply(this, k); + } + } + + public abstract class AbstractFpPoint + : ECPointBase + { + protected AbstractFpPoint(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + } + + protected AbstractFpPoint(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected internal override bool CompressionYTilde + { + get { return this.AffineYCoord.TestBitZero(); } + } + + protected override bool SatisfiesCurveEquation() + { + ECFieldElement X = this.RawXCoord, Y = this.RawYCoord, A = Curve.A, B = Curve.B; + ECFieldElement lhs = Y.Square(); + + switch (CurveCoordinateSystem) + { + case ECCurve.COORD_AFFINE: + break; + case ECCurve.COORD_HOMOGENEOUS: + { + ECFieldElement Z = this.RawZCoords[0]; + if (!Z.IsOne) + { + ECFieldElement Z2 = Z.Square(), Z3 = Z.Multiply(Z2); + lhs = lhs.Multiply(Z); + A = A.Multiply(Z2); + B = B.Multiply(Z3); + } + break; + } + case ECCurve.COORD_JACOBIAN: + case ECCurve.COORD_JACOBIAN_CHUDNOVSKY: + case ECCurve.COORD_JACOBIAN_MODIFIED: + { + ECFieldElement Z = this.RawZCoords[0]; + if (!Z.IsOne) + { + ECFieldElement Z2 = Z.Square(), Z4 = Z2.Square(), Z6 = Z2.Multiply(Z4); + A = A.Multiply(Z4); + B = B.Multiply(Z6); + } + break; + } + default: + throw new InvalidOperationException("unsupported coordinate system"); + } + + ECFieldElement rhs = X.Square().Add(A).Multiply(X).Add(B); + return lhs.Equals(rhs); + } + + public override ECPoint Subtract(ECPoint b) + { + if (b.IsInfinity) + return this; + + // Add -b + return Add(b.Negate()); + } + } + + /** + * Elliptic curve points over Fp + */ + public class FpPoint + : AbstractFpPoint + { + /** + * Create a point which encodes without point compression. + * + * @param curve the curve to use + * @param x affine x co-ordinate + * @param y affine y co-ordinate + */ + [Obsolete("Use ECCurve.CreatePoint to construct points")] + public FpPoint(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * Create a point that encodes with or without point compression. + * + * @param curve the curve to use + * @param x affine x co-ordinate + * @param y affine y co-ordinate + * @param withCompression if true encode with point compression + */ + [Obsolete("Per-point compression property will be removed, see GetEncoded(bool)")] + public FpPoint(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal FpPoint(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new FpPoint(null, AffineXCoord, AffineYCoord, false); + } + + public override ECFieldElement GetZCoord(int index) + { + if (index == 1 && ECCurve.COORD_JACOBIAN_MODIFIED == this.CurveCoordinateSystem) + { + return GetJacobianModifiedW(); + } + + return base.GetZCoord(index); + } + + // B.3 pg 62 + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + if (this == b) + return Twice(); + + ECCurve curve = this.Curve; + int coord = curve.CoordinateSystem; + + ECFieldElement X1 = this.RawXCoord, Y1 = this.RawYCoord; + ECFieldElement X2 = b.RawXCoord, Y2 = b.RawYCoord; + + switch (coord) + { + case ECCurve.COORD_AFFINE: + { + ECFieldElement dx = X2.Subtract(X1), dy = Y2.Subtract(Y1); + + if (dx.IsZero) + { + if (dy.IsZero) + { + // this == b, i.e. this must be doubled + return Twice(); + } + + // this == -b, i.e. the result is the point at infinity + return Curve.Infinity; + } + + ECFieldElement gamma = dy.Divide(dx); + ECFieldElement X3 = gamma.Square().Subtract(X1).Subtract(X2); + ECFieldElement Y3 = gamma.Multiply(X1.Subtract(X3)).Subtract(Y1); + + return new FpPoint(Curve, X3, Y3, IsCompressed); + } + + case ECCurve.COORD_HOMOGENEOUS: + { + ECFieldElement Z1 = this.RawZCoords[0]; + ECFieldElement Z2 = b.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + bool Z2IsOne = Z2.IsOne; + + ECFieldElement u1 = Z1IsOne ? Y2 : Y2.Multiply(Z1); + ECFieldElement u2 = Z2IsOne ? Y1 : Y1.Multiply(Z2); + ECFieldElement u = u1.Subtract(u2); + ECFieldElement v1 = Z1IsOne ? X2 : X2.Multiply(Z1); + ECFieldElement v2 = Z2IsOne ? X1 : X1.Multiply(Z2); + ECFieldElement v = v1.Subtract(v2); + + // Check if b == this or b == -this + if (v.IsZero) + { + if (u.IsZero) + { + // this == b, i.e. this must be doubled + return this.Twice(); + } + + // this == -b, i.e. the result is the point at infinity + return curve.Infinity; + } + + // TODO Optimize for when w == 1 + ECFieldElement w = Z1IsOne ? Z2 : Z2IsOne ? Z1 : Z1.Multiply(Z2); + ECFieldElement vSquared = v.Square(); + ECFieldElement vCubed = vSquared.Multiply(v); + ECFieldElement vSquaredV2 = vSquared.Multiply(v2); + ECFieldElement A = u.Square().Multiply(w).Subtract(vCubed).Subtract(Two(vSquaredV2)); + + ECFieldElement X3 = v.Multiply(A); + ECFieldElement Y3 = vSquaredV2.Subtract(A).MultiplyMinusProduct(u, u2, vCubed); + ECFieldElement Z3 = vCubed.Multiply(w); + + return new FpPoint(curve, X3, Y3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + case ECCurve.COORD_JACOBIAN: + case ECCurve.COORD_JACOBIAN_MODIFIED: + { + ECFieldElement Z1 = this.RawZCoords[0]; + ECFieldElement Z2 = b.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + + ECFieldElement X3, Y3, Z3, Z3Squared = null; + + if (!Z1IsOne && Z1.Equals(Z2)) + { + // TODO Make this available as public method coZAdd? + + ECFieldElement dx = X1.Subtract(X2), dy = Y1.Subtract(Y2); + if (dx.IsZero) + { + if (dy.IsZero) + { + return Twice(); + } + return curve.Infinity; + } + + ECFieldElement C = dx.Square(); + ECFieldElement W1 = X1.Multiply(C), W2 = X2.Multiply(C); + ECFieldElement A1 = W1.Subtract(W2).Multiply(Y1); + + X3 = dy.Square().Subtract(W1).Subtract(W2); + Y3 = W1.Subtract(X3).Multiply(dy).Subtract(A1); + Z3 = dx; + + if (Z1IsOne) + { + Z3Squared = C; + } + else + { + Z3 = Z3.Multiply(Z1); + } + } + else + { + ECFieldElement Z1Squared, U2, S2; + if (Z1IsOne) + { + Z1Squared = Z1; U2 = X2; S2 = Y2; + } + else + { + Z1Squared = Z1.Square(); + U2 = Z1Squared.Multiply(X2); + ECFieldElement Z1Cubed = Z1Squared.Multiply(Z1); + S2 = Z1Cubed.Multiply(Y2); + } + + bool Z2IsOne = Z2.IsOne; + ECFieldElement Z2Squared, U1, S1; + if (Z2IsOne) + { + Z2Squared = Z2; U1 = X1; S1 = Y1; + } + else + { + Z2Squared = Z2.Square(); + U1 = Z2Squared.Multiply(X1); + ECFieldElement Z2Cubed = Z2Squared.Multiply(Z2); + S1 = Z2Cubed.Multiply(Y1); + } + + ECFieldElement H = U1.Subtract(U2); + ECFieldElement R = S1.Subtract(S2); + + // Check if b == this or b == -this + if (H.IsZero) + { + if (R.IsZero) + { + // this == b, i.e. this must be doubled + return this.Twice(); + } + + // this == -b, i.e. the result is the point at infinity + return curve.Infinity; + } + + ECFieldElement HSquared = H.Square(); + ECFieldElement G = HSquared.Multiply(H); + ECFieldElement V = HSquared.Multiply(U1); + + X3 = R.Square().Add(G).Subtract(Two(V)); + Y3 = V.Subtract(X3).MultiplyMinusProduct(R, G, S1); + + Z3 = H; + if (!Z1IsOne) + { + Z3 = Z3.Multiply(Z1); + } + if (!Z2IsOne) + { + Z3 = Z3.Multiply(Z2); + } + + // Alternative calculation of Z3 using fast square + //X3 = four(X3); + //Y3 = eight(Y3); + //Z3 = doubleProductFromSquares(Z1, Z2, Z1Squared, Z2Squared).Multiply(H); + + if (Z3 == H) + { + Z3Squared = HSquared; + } + } + + ECFieldElement[] zs; + if (coord == ECCurve.COORD_JACOBIAN_MODIFIED) + { + // TODO If the result will only be used in a subsequent addition, we don't need W3 + ECFieldElement W3 = CalculateJacobianModifiedW(Z3, Z3Squared); + + zs = new ECFieldElement[] { Z3, W3 }; + } + else + { + zs = new ECFieldElement[] { Z3 }; + } + + return new FpPoint(curve, X3, Y3, zs, IsCompressed); + } + + default: + { + throw new InvalidOperationException("unsupported coordinate system"); + } + } + } + + // B.3 pg 62 + public override ECPoint Twice() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement Y1 = this.RawYCoord; + if (Y1.IsZero) + return curve.Infinity; + + int coord = curve.CoordinateSystem; + + ECFieldElement X1 = this.RawXCoord; + + switch (coord) + { + case ECCurve.COORD_AFFINE: + { + ECFieldElement X1Squared = X1.Square(); + ECFieldElement gamma = Three(X1Squared).Add(this.Curve.A).Divide(Two(Y1)); + ECFieldElement X3 = gamma.Square().Subtract(Two(X1)); + ECFieldElement Y3 = gamma.Multiply(X1.Subtract(X3)).Subtract(Y1); + + return new FpPoint(Curve, X3, Y3, IsCompressed); + } + + case ECCurve.COORD_HOMOGENEOUS: + { + ECFieldElement Z1 = this.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + + // TODO Optimize for small negative a4 and -3 + ECFieldElement w = curve.A; + if (!w.IsZero && !Z1IsOne) + { + w = w.Multiply(Z1.Square()); + } + w = w.Add(Three(X1.Square())); + + ECFieldElement s = Z1IsOne ? Y1 : Y1.Multiply(Z1); + ECFieldElement t = Z1IsOne ? Y1.Square() : s.Multiply(Y1); + ECFieldElement B = X1.Multiply(t); + ECFieldElement _4B = Four(B); + ECFieldElement h = w.Square().Subtract(Two(_4B)); + + ECFieldElement _2s = Two(s); + ECFieldElement X3 = h.Multiply(_2s); + ECFieldElement _2t = Two(t); + ECFieldElement Y3 = _4B.Subtract(h).Multiply(w).Subtract(Two(_2t.Square())); + ECFieldElement _4sSquared = Z1IsOne ? Two(_2t) : _2s.Square(); + ECFieldElement Z3 = Two(_4sSquared).Multiply(s); + + return new FpPoint(curve, X3, Y3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + case ECCurve.COORD_JACOBIAN: + { + ECFieldElement Z1 = this.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + + ECFieldElement Y1Squared = Y1.Square(); + ECFieldElement T = Y1Squared.Square(); + + ECFieldElement a4 = curve.A; + ECFieldElement a4Neg = a4.Negate(); + + ECFieldElement M, S; + if (a4Neg.ToBigInteger().Equals(BigInteger.ValueOf(3))) + { + ECFieldElement Z1Squared = Z1IsOne ? Z1 : Z1.Square(); + M = Three(X1.Add(Z1Squared).Multiply(X1.Subtract(Z1Squared))); + S = Four(Y1Squared.Multiply(X1)); + } + else + { + ECFieldElement X1Squared = X1.Square(); + M = Three(X1Squared); + if (Z1IsOne) + { + M = M.Add(a4); + } + else if (!a4.IsZero) + { + ECFieldElement Z1Squared = Z1IsOne ? Z1 : Z1.Square(); + ECFieldElement Z1Pow4 = Z1Squared.Square(); + if (a4Neg.BitLength < a4.BitLength) + { + M = M.Subtract(Z1Pow4.Multiply(a4Neg)); + } + else + { + M = M.Add(Z1Pow4.Multiply(a4)); + } + } + //S = two(doubleProductFromSquares(X1, Y1Squared, X1Squared, T)); + S = Four(X1.Multiply(Y1Squared)); + } + + ECFieldElement X3 = M.Square().Subtract(Two(S)); + ECFieldElement Y3 = S.Subtract(X3).Multiply(M).Subtract(Eight(T)); + + ECFieldElement Z3 = Two(Y1); + if (!Z1IsOne) + { + Z3 = Z3.Multiply(Z1); + } + + // Alternative calculation of Z3 using fast square + //ECFieldElement Z3 = doubleProductFromSquares(Y1, Z1, Y1Squared, Z1Squared); + + return new FpPoint(curve, X3, Y3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + case ECCurve.COORD_JACOBIAN_MODIFIED: + { + return TwiceJacobianModified(true); + } + + default: + { + throw new InvalidOperationException("unsupported coordinate system"); + } + } + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this == b) + return ThreeTimes(); + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECFieldElement Y1 = this.RawYCoord; + if (Y1.IsZero) + return b; + + ECCurve curve = this.Curve; + int coord = curve.CoordinateSystem; + + switch (coord) + { + case ECCurve.COORD_AFFINE: + { + ECFieldElement X1 = this.RawXCoord; + ECFieldElement X2 = b.RawXCoord, Y2 = b.RawYCoord; + + ECFieldElement dx = X2.Subtract(X1), dy = Y2.Subtract(Y1); + + if (dx.IsZero) + { + if (dy.IsZero) + { + // this == b i.e. the result is 3P + return ThreeTimes(); + } + + // this == -b, i.e. the result is P + return this; + } + + /* + * Optimized calculation of 2P + Q, as described in "Trading Inversions for + * Multiplications in Elliptic Curve Cryptography", by Ciet, Joye, Lauter, Montgomery. + */ + + ECFieldElement X = dx.Square(), Y = dy.Square(); + ECFieldElement d = X.Multiply(Two(X1).Add(X2)).Subtract(Y); + if (d.IsZero) + { + return Curve.Infinity; + } + + ECFieldElement D = d.Multiply(dx); + ECFieldElement I = D.Invert(); + ECFieldElement L1 = d.Multiply(I).Multiply(dy); + ECFieldElement L2 = Two(Y1).Multiply(X).Multiply(dx).Multiply(I).Subtract(L1); + ECFieldElement X4 = (L2.Subtract(L1)).Multiply(L1.Add(L2)).Add(X2); + ECFieldElement Y4 = (X1.Subtract(X4)).Multiply(L2).Subtract(Y1); + + return new FpPoint(Curve, X4, Y4, IsCompressed); + } + case ECCurve.COORD_JACOBIAN_MODIFIED: + { + return TwiceJacobianModified(false).Add(b); + } + default: + { + return Twice().Add(b); + } + } + } + + public override ECPoint ThreeTimes() + { + if (this.IsInfinity) + return this; + + ECFieldElement Y1 = this.RawYCoord; + if (Y1.IsZero) + return this; + + ECCurve curve = this.Curve; + int coord = curve.CoordinateSystem; + + switch (coord) + { + case ECCurve.COORD_AFFINE: + { + ECFieldElement X1 = this.RawXCoord; + + ECFieldElement _2Y1 = Two(Y1); + ECFieldElement X = _2Y1.Square(); + ECFieldElement Z = Three(X1.Square()).Add(Curve.A); + ECFieldElement Y = Z.Square(); + + ECFieldElement d = Three(X1).Multiply(X).Subtract(Y); + if (d.IsZero) + { + return Curve.Infinity; + } + + ECFieldElement D = d.Multiply(_2Y1); + ECFieldElement I = D.Invert(); + ECFieldElement L1 = d.Multiply(I).Multiply(Z); + ECFieldElement L2 = X.Square().Multiply(I).Subtract(L1); + + ECFieldElement X4 = (L2.Subtract(L1)).Multiply(L1.Add(L2)).Add(X1); + ECFieldElement Y4 = (X1.Subtract(X4)).Multiply(L2).Subtract(Y1); + return new FpPoint(Curve, X4, Y4, IsCompressed); + } + case ECCurve.COORD_JACOBIAN_MODIFIED: + { + return TwiceJacobianModified(false).Add(this); + } + default: + { + // NOTE: Be careful about recursions between TwicePlus and ThreeTimes + return Twice().Add(this); + } + } + } + + public override ECPoint TimesPow2(int e) + { + if (e < 0) + throw new ArgumentException("cannot be negative", "e"); + if (e == 0 || this.IsInfinity) + return this; + if (e == 1) + return Twice(); + + ECCurve curve = this.Curve; + + ECFieldElement Y1 = this.RawYCoord; + if (Y1.IsZero) + return curve.Infinity; + + int coord = curve.CoordinateSystem; + + ECFieldElement W1 = curve.A; + ECFieldElement X1 = this.RawXCoord; + ECFieldElement Z1 = this.RawZCoords.Length < 1 ? curve.FromBigInteger(BigInteger.One) : this.RawZCoords[0]; + + if (!Z1.IsOne) + { + switch (coord) + { + case ECCurve.COORD_HOMOGENEOUS: + ECFieldElement Z1Sq = Z1.Square(); + X1 = X1.Multiply(Z1); + Y1 = Y1.Multiply(Z1Sq); + W1 = CalculateJacobianModifiedW(Z1, Z1Sq); + break; + case ECCurve.COORD_JACOBIAN: + W1 = CalculateJacobianModifiedW(Z1, null); + break; + case ECCurve.COORD_JACOBIAN_MODIFIED: + W1 = GetJacobianModifiedW(); + break; + } + } + + for (int i = 0; i < e; ++i) + { + if (Y1.IsZero) + return curve.Infinity; + + ECFieldElement X1Squared = X1.Square(); + ECFieldElement M = Three(X1Squared); + ECFieldElement _2Y1 = Two(Y1); + ECFieldElement _2Y1Squared = _2Y1.Multiply(Y1); + ECFieldElement S = Two(X1.Multiply(_2Y1Squared)); + ECFieldElement _4T = _2Y1Squared.Square(); + ECFieldElement _8T = Two(_4T); + + if (!W1.IsZero) + { + M = M.Add(W1); + W1 = Two(_8T.Multiply(W1)); + } + + X1 = M.Square().Subtract(Two(S)); + Y1 = M.Multiply(S.Subtract(X1)).Subtract(_8T); + Z1 = Z1.IsOne ? _2Y1 : _2Y1.Multiply(Z1); + } + + switch (coord) + { + case ECCurve.COORD_AFFINE: + ECFieldElement zInv = Z1.Invert(), zInv2 = zInv.Square(), zInv3 = zInv2.Multiply(zInv); + return new FpPoint(curve, X1.Multiply(zInv2), Y1.Multiply(zInv3), IsCompressed); + case ECCurve.COORD_HOMOGENEOUS: + X1 = X1.Multiply(Z1); + Z1 = Z1.Multiply(Z1.Square()); + return new FpPoint(curve, X1, Y1, new ECFieldElement[] { Z1 }, IsCompressed); + case ECCurve.COORD_JACOBIAN: + return new FpPoint(curve, X1, Y1, new ECFieldElement[] { Z1 }, IsCompressed); + case ECCurve.COORD_JACOBIAN_MODIFIED: + return new FpPoint(curve, X1, Y1, new ECFieldElement[] { Z1, W1 }, IsCompressed); + default: + throw new InvalidOperationException("unsupported coordinate system"); + } + } + + protected virtual ECFieldElement Two(ECFieldElement x) + { + return x.Add(x); + } + + protected virtual ECFieldElement Three(ECFieldElement x) + { + return Two(x).Add(x); + } + + protected virtual ECFieldElement Four(ECFieldElement x) + { + return Two(Two(x)); + } + + protected virtual ECFieldElement Eight(ECFieldElement x) + { + return Four(Two(x)); + } + + protected virtual ECFieldElement DoubleProductFromSquares(ECFieldElement a, ECFieldElement b, + ECFieldElement aSquared, ECFieldElement bSquared) + { + /* + * NOTE: If squaring in the field is faster than multiplication, then this is a quicker + * way to calculate 2.A.B, if A^2 and B^2 are already known. + */ + return a.Add(b).Square().Subtract(aSquared).Subtract(bSquared); + } + + public override ECPoint Negate() + { + if (IsInfinity) + return this; + + ECCurve curve = Curve; + int coord = curve.CoordinateSystem; + + if (ECCurve.COORD_AFFINE != coord) + { + return new FpPoint(curve, RawXCoord, RawYCoord.Negate(), RawZCoords, IsCompressed); + } + + return new FpPoint(curve, RawXCoord, RawYCoord.Negate(), IsCompressed); + } + + protected virtual ECFieldElement CalculateJacobianModifiedW(ECFieldElement Z, ECFieldElement ZSquared) + { + ECFieldElement a4 = this.Curve.A; + if (a4.IsZero || Z.IsOne) + return a4; + + if (ZSquared == null) + { + ZSquared = Z.Square(); + } + + ECFieldElement W = ZSquared.Square(); + ECFieldElement a4Neg = a4.Negate(); + if (a4Neg.BitLength < a4.BitLength) + { + W = W.Multiply(a4Neg).Negate(); + } + else + { + W = W.Multiply(a4); + } + return W; + } + + protected virtual ECFieldElement GetJacobianModifiedW() + { + ECFieldElement[] ZZ = this.RawZCoords; + ECFieldElement W = ZZ[1]; + if (W == null) + { + // NOTE: Rarely, TwicePlus will result in the need for a lazy W1 calculation here + ZZ[1] = W = CalculateJacobianModifiedW(ZZ[0], null); + } + return W; + } + + protected virtual FpPoint TwiceJacobianModified(bool calculateW) + { + ECFieldElement X1 = this.RawXCoord, Y1 = this.RawYCoord, Z1 = this.RawZCoords[0], W1 = GetJacobianModifiedW(); + + ECFieldElement X1Squared = X1.Square(); + ECFieldElement M = Three(X1Squared).Add(W1); + ECFieldElement _2Y1 = Two(Y1); + ECFieldElement _2Y1Squared = _2Y1.Multiply(Y1); + ECFieldElement S = Two(X1.Multiply(_2Y1Squared)); + ECFieldElement X3 = M.Square().Subtract(Two(S)); + ECFieldElement _4T = _2Y1Squared.Square(); + ECFieldElement _8T = Two(_4T); + ECFieldElement Y3 = M.Multiply(S.Subtract(X3)).Subtract(_8T); + ECFieldElement W3 = calculateW ? Two(_8T.Multiply(W1)) : null; + ECFieldElement Z3 = Z1.IsOne ? _2Y1 : _2Y1.Multiply(Z1); + + return new FpPoint(this.Curve, X3, Y3, new ECFieldElement[] { Z3, W3 }, IsCompressed); + } + } + + public abstract class AbstractF2mPoint + : ECPointBase + { + protected AbstractF2mPoint(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + } + + protected AbstractF2mPoint(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override bool SatisfiesCurveEquation() + { + ECCurve curve = Curve; + ECFieldElement X = this.RawXCoord, Y = this.RawYCoord, A = curve.A, B = curve.B; + ECFieldElement lhs, rhs; + + int coord = curve.CoordinateSystem; + if (coord == ECCurve.COORD_LAMBDA_PROJECTIVE) + { + ECFieldElement Z = this.RawZCoords[0]; + bool ZIsOne = Z.IsOne; + + if (X.IsZero) + { + // NOTE: For x == 0, we expect the affine-y instead of the lambda-y + lhs = Y.Square(); + rhs = B; + if (!ZIsOne) + { + ECFieldElement Z2 = Z.Square(); + rhs = rhs.Multiply(Z2); + } + } + else + { + ECFieldElement L = Y, X2 = X.Square(); + if (ZIsOne) + { + lhs = L.Square().Add(L).Add(A); + rhs = X2.Square().Add(B); + } + else + { + ECFieldElement Z2 = Z.Square(), Z4 = Z2.Square(); + lhs = L.Add(Z).MultiplyPlusProduct(L, A, Z2); + // TODO If sqrt(b) is precomputed this can be simplified to a single square + rhs = X2.SquarePlusProduct(B, Z4); + } + lhs = lhs.Multiply(X2); + } + } + else + { + lhs = Y.Add(X).Multiply(Y); + + switch (coord) + { + case ECCurve.COORD_AFFINE: + break; + case ECCurve.COORD_HOMOGENEOUS: + { + ECFieldElement Z = this.RawZCoords[0]; + if (!Z.IsOne) + { + ECFieldElement Z2 = Z.Square(), Z3 = Z.Multiply(Z2); + lhs = lhs.Multiply(Z); + A = A.Multiply(Z); + B = B.Multiply(Z3); + } + break; + } + default: + throw new InvalidOperationException("unsupported coordinate system"); + } + + rhs = X.Add(A).Multiply(X.Square()).Add(B); + } + + return lhs.Equals(rhs); + } + + protected override bool SatisfiesOrder() + { + ECCurve curve = Curve; + BigInteger cofactor = curve.Cofactor; + if (BigInteger.Two.Equals(cofactor)) + { + /* + * Check that 0 == Tr(X + A); then there exists a solution to L^2 + L = X + A, and + * so a halving is possible, so this point is the double of another. + * + * Note: Tr(A) == 1 for cofactor 2 curves. + */ + ECPoint N = this.Normalize(); + ECFieldElement X = N.AffineXCoord; + return 0 != ((AbstractF2mFieldElement)X).Trace(); + } + if (BigInteger.ValueOf(4).Equals(cofactor)) + { + /* + * Solve L^2 + L = X + A to find the half of this point, if it exists (fail if not). + * + * Note: Tr(A) == 0 for cofactor 4 curves. + */ + ECPoint N = this.Normalize(); + ECFieldElement X = N.AffineXCoord; + ECFieldElement L = ((AbstractF2mCurve)curve).SolveQuadraticEquation(X.Add(curve.A)); + if (null == L) + return false; + + /* + * A solution exists, therefore 0 == Tr(X + A) == Tr(X). + */ + ECFieldElement Y = N.AffineYCoord; + ECFieldElement T = X.Multiply(L).Add(Y); + + /* + * Either T or (T + X) is the square of a half-point's x coordinate (hx). In either + * case, the half-point can be halved again when 0 == Tr(hx + A). + * + * Note: Tr(hx + A) == Tr(hx) == Tr(hx^2) == Tr(T) == Tr(T + X) + * + * Check that 0 == Tr(T); then there exists a solution to L^2 + L = hx + A, and so a + * second halving is possible and this point is four times some other. + */ + return 0 == ((AbstractF2mFieldElement)T).Trace(); + } + + return base.SatisfiesOrder(); + } + + public override ECPoint ScaleX(ECFieldElement scale) + { + if (this.IsInfinity) + return this; + + switch (CurveCoordinateSystem) + { + case ECCurve.COORD_LAMBDA_AFFINE: + { + // Y is actually Lambda (X + Y/X) here + ECFieldElement X = RawXCoord, L = RawYCoord; + + ECFieldElement X2 = X.Multiply(scale); + ECFieldElement L2 = L.Add(X).Divide(scale).Add(X2); + + return Curve.CreateRawPoint(X, L2, RawZCoords, IsCompressed); + } + case ECCurve.COORD_LAMBDA_PROJECTIVE: + { + // Y is actually Lambda (X + Y/X) here + ECFieldElement X = RawXCoord, L = RawYCoord, Z = RawZCoords[0]; + + // We scale the Z coordinate also, to avoid an inversion + ECFieldElement X2 = X.Multiply(scale.Square()); + ECFieldElement L2 = L.Add(X).Add(X2); + ECFieldElement Z2 = Z.Multiply(scale); + + return Curve.CreateRawPoint(X, L2, new ECFieldElement[] { Z2 }, IsCompressed); + } + default: + { + return base.ScaleX(scale); + } + } + } + + public override ECPoint ScaleXNegateY(ECFieldElement scale) + { + return ScaleX(scale); + } + + public override ECPoint ScaleY(ECFieldElement scale) + { + if (this.IsInfinity) + return this; + + switch (CurveCoordinateSystem) + { + case ECCurve.COORD_LAMBDA_AFFINE: + case ECCurve.COORD_LAMBDA_PROJECTIVE: + { + ECFieldElement X = RawXCoord, L = RawYCoord; + + // Y is actually Lambda (X + Y/X) here + ECFieldElement L2 = L.Add(X).Multiply(scale).Add(X); + + return Curve.CreateRawPoint(X, L2, RawZCoords, IsCompressed); + } + default: + { + return base.ScaleY(scale); + } + } + } + + public override ECPoint ScaleYNegateX(ECFieldElement scale) + { + return ScaleY(scale); + } + + public override ECPoint Subtract(ECPoint b) + { + if (b.IsInfinity) + return this; + + // Add -b + return Add(b.Negate()); + } + + public virtual AbstractF2mPoint Tau() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + int coord = curve.CoordinateSystem; + + ECFieldElement X1 = this.RawXCoord; + + switch (coord) + { + case ECCurve.COORD_AFFINE: + case ECCurve.COORD_LAMBDA_AFFINE: + { + ECFieldElement Y1 = this.RawYCoord; + return (AbstractF2mPoint)curve.CreateRawPoint(X1.Square(), Y1.Square(), IsCompressed); + } + case ECCurve.COORD_HOMOGENEOUS: + case ECCurve.COORD_LAMBDA_PROJECTIVE: + { + ECFieldElement Y1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + return (AbstractF2mPoint)curve.CreateRawPoint(X1.Square(), Y1.Square(), + new ECFieldElement[] { Z1.Square() }, IsCompressed); + } + default: + { + throw new InvalidOperationException("unsupported coordinate system"); + } + } + } + + public virtual AbstractF2mPoint TauPow(int pow) + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + int coord = curve.CoordinateSystem; + + ECFieldElement X1 = this.RawXCoord; + + switch (coord) + { + case ECCurve.COORD_AFFINE: + case ECCurve.COORD_LAMBDA_AFFINE: + { + ECFieldElement Y1 = this.RawYCoord; + return (AbstractF2mPoint)curve.CreateRawPoint(X1.SquarePow(pow), Y1.SquarePow(pow), IsCompressed); + } + case ECCurve.COORD_HOMOGENEOUS: + case ECCurve.COORD_LAMBDA_PROJECTIVE: + { + ECFieldElement Y1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + return (AbstractF2mPoint)curve.CreateRawPoint(X1.SquarePow(pow), Y1.SquarePow(pow), + new ECFieldElement[] { Z1.SquarePow(pow) }, IsCompressed); + } + default: + { + throw new InvalidOperationException("unsupported coordinate system"); + } + } + } + } + + /** + * Elliptic curve points over F2m + */ + public class F2mPoint + : AbstractF2mPoint + { + /** + * @param curve base curve + * @param x x point + * @param y y point + */ + [Obsolete("Use ECCurve.CreatePoint to construct points")] + public F2mPoint( + ECCurve curve, + ECFieldElement x, + ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * @param curve base curve + * @param x x point + * @param y y point + * @param withCompression true if encode with point compression. + */ + [Obsolete("Per-point compression property will be removed, see GetEncoded(bool)")] + public F2mPoint( + ECCurve curve, + ECFieldElement x, + ECFieldElement y, + bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + { + throw new ArgumentException("Exactly one of the field elements is null"); + } + + if (x != null) + { + // Check if x and y are elements of the same field + F2mFieldElement.CheckFieldElements(x, y); + + // Check if x and a are elements of the same field + if (curve != null) + { + F2mFieldElement.CheckFieldElements(x, curve.A); + } + } + } + + internal F2mPoint(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new F2mPoint(null, AffineXCoord, AffineYCoord, false); + } + + public override ECFieldElement YCoord + { + get + { + int coord = this.CurveCoordinateSystem; + + switch (coord) + { + case ECCurve.COORD_LAMBDA_AFFINE: + case ECCurve.COORD_LAMBDA_PROJECTIVE: + { + ECFieldElement X = RawXCoord, L = RawYCoord; + + if (this.IsInfinity || X.IsZero) + return L; + + // Y is actually Lambda (X + Y/X) here; convert to affine value on the fly + ECFieldElement Y = L.Add(X).Multiply(X); + if (ECCurve.COORD_LAMBDA_PROJECTIVE == coord) + { + ECFieldElement Z = RawZCoords[0]; + if (!Z.IsOne) + { + Y = Y.Divide(Z); + } + } + return Y; + } + default: + { + return RawYCoord; + } + } + } + } + + protected internal override bool CompressionYTilde + { + get + { + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + { + return false; + } + + ECFieldElement Y = this.RawYCoord; + + switch (this.CurveCoordinateSystem) + { + case ECCurve.COORD_LAMBDA_AFFINE: + case ECCurve.COORD_LAMBDA_PROJECTIVE: + { + // Y is actually Lambda (X + Y/X) here + return Y.TestBitZero() != X.TestBitZero(); + } + default: + { + return Y.Divide(X).TestBitZero(); + } + } + } + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + + ECCurve curve = this.Curve; + int coord = curve.CoordinateSystem; + + ECFieldElement X1 = this.RawXCoord; + ECFieldElement X2 = b.RawXCoord; + + switch (coord) + { + case ECCurve.COORD_AFFINE: + { + ECFieldElement Y1 = this.RawYCoord; + ECFieldElement Y2 = b.RawYCoord; + + ECFieldElement dx = X1.Add(X2), dy = Y1.Add(Y2); + if (dx.IsZero) + { + if (dy.IsZero) + { + return Twice(); + } + + return curve.Infinity; + } + + ECFieldElement L = dy.Divide(dx); + + ECFieldElement X3 = L.Square().Add(L).Add(dx).Add(curve.A); + ECFieldElement Y3 = L.Multiply(X1.Add(X3)).Add(X3).Add(Y1); + + return new F2mPoint(curve, X3, Y3, IsCompressed); + } + case ECCurve.COORD_HOMOGENEOUS: + { + ECFieldElement Y1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement Y2 = b.RawYCoord, Z2 = b.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement U1 = Y2, V1 = X2; + if (!Z1IsOne) + { + U1 = U1.Multiply(Z1); + V1 = V1.Multiply(Z1); + } + + bool Z2IsOne = Z2.IsOne; + ECFieldElement U2 = Y1, V2 = X1; + if (!Z2IsOne) + { + U2 = U2.Multiply(Z2); + V2 = V2.Multiply(Z2); + } + + ECFieldElement U = U1.Add(U2); + ECFieldElement V = V1.Add(V2); + + if (V.IsZero) + { + if (U.IsZero) + { + return Twice(); + } + + return curve.Infinity; + } + + ECFieldElement VSq = V.Square(); + ECFieldElement VCu = VSq.Multiply(V); + ECFieldElement W = Z1IsOne ? Z2 : Z2IsOne ? Z1 : Z1.Multiply(Z2); + ECFieldElement uv = U.Add(V); + ECFieldElement A = uv.MultiplyPlusProduct(U, VSq, curve.A).Multiply(W).Add(VCu); + + ECFieldElement X3 = V.Multiply(A); + ECFieldElement VSqZ2 = Z2IsOne ? VSq : VSq.Multiply(Z2); + ECFieldElement Y3 = U.MultiplyPlusProduct(X1, V, Y1).MultiplyPlusProduct(VSqZ2, uv, A); + ECFieldElement Z3 = VCu.Multiply(W); + + return new F2mPoint(curve, X3, Y3, new ECFieldElement[] { Z3 }, IsCompressed); + } + case ECCurve.COORD_LAMBDA_PROJECTIVE: + { + if (X1.IsZero) + { + if (X2.IsZero) + return curve.Infinity; + + return b.Add(this); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord, Z2 = b.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement U2 = X2, S2 = L2; + if (!Z1IsOne) + { + U2 = U2.Multiply(Z1); + S2 = S2.Multiply(Z1); + } + + bool Z2IsOne = Z2.IsOne; + ECFieldElement U1 = X1, S1 = L1; + if (!Z2IsOne) + { + U1 = U1.Multiply(Z2); + S1 = S1.Multiply(Z2); + } + + ECFieldElement A = S1.Add(S2); + ECFieldElement B = U1.Add(U2); + + if (B.IsZero) + { + if (A.IsZero) + { + return Twice(); + } + + return curve.Infinity; + } + + ECFieldElement X3, L3, Z3; + if (X2.IsZero) + { + // TODO This can probably be optimized quite a bit + ECPoint p = this.Normalize(); + X1 = p.RawXCoord; + ECFieldElement Y1 = p.YCoord; + + ECFieldElement Y2 = L2; + ECFieldElement L = Y1.Add(Y2).Divide(X1); + + X3 = L.Square().Add(L).Add(X1).Add(curve.A); + if (X3.IsZero) + { + return new F2mPoint(curve, X3, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement Y3 = L.Multiply(X1.Add(X3)).Add(X3).Add(Y1); + L3 = Y3.Divide(X3).Add(X3); + Z3 = curve.FromBigInteger(BigInteger.One); + } + else + { + B = B.Square(); + + ECFieldElement AU1 = A.Multiply(U1); + ECFieldElement AU2 = A.Multiply(U2); + + X3 = AU1.Multiply(AU2); + if (X3.IsZero) + { + return new F2mPoint(curve, X3, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement ABZ2 = A.Multiply(B); + if (!Z2IsOne) + { + ABZ2 = ABZ2.Multiply(Z2); + } + + L3 = AU2.Add(B).SquarePlusProduct(ABZ2, L1.Add(Z1)); + + Z3 = ABZ2; + if (!Z1IsOne) + { + Z3 = Z3.Multiply(Z1); + } + } + + return new F2mPoint(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + default: + { + throw new InvalidOperationException("unsupported coordinate system"); + } + } + } + + /* (non-Javadoc) + * @see Org.BouncyCastle.Math.EC.ECPoint#twice() + */ + public override ECPoint Twice() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is its own additive inverse + return curve.Infinity; + } + + int coord = curve.CoordinateSystem; + + switch (coord) + { + case ECCurve.COORD_AFFINE: + { + ECFieldElement Y1 = this.RawYCoord; + + ECFieldElement L1 = Y1.Divide(X1).Add(X1); + + ECFieldElement X3 = L1.Square().Add(L1).Add(curve.A); + ECFieldElement Y3 = X1.SquarePlusProduct(X3, L1.AddOne()); + + return new F2mPoint(curve, X3, Y3, IsCompressed); + } + case ECCurve.COORD_HOMOGENEOUS: + { + ECFieldElement Y1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement X1Z1 = Z1IsOne ? X1 : X1.Multiply(Z1); + ECFieldElement Y1Z1 = Z1IsOne ? Y1 : Y1.Multiply(Z1); + + ECFieldElement X1Sq = X1.Square(); + ECFieldElement S = X1Sq.Add(Y1Z1); + ECFieldElement V = X1Z1; + ECFieldElement vSquared = V.Square(); + ECFieldElement sv = S.Add(V); + ECFieldElement h = sv.MultiplyPlusProduct(S, vSquared, curve.A); + + ECFieldElement X3 = V.Multiply(h); + ECFieldElement Y3 = X1Sq.Square().MultiplyPlusProduct(V, h, sv); + ECFieldElement Z3 = V.Multiply(vSquared); + + return new F2mPoint(curve, X3, Y3, new ECFieldElement[] { Z3 }, IsCompressed); + } + case ECCurve.COORD_LAMBDA_PROJECTIVE: + { + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement L1Z1 = Z1IsOne ? L1 : L1.Multiply(Z1); + ECFieldElement Z1Sq = Z1IsOne ? Z1 : Z1.Square(); + ECFieldElement a = curve.A; + ECFieldElement aZ1Sq = Z1IsOne ? a : a.Multiply(Z1Sq); + ECFieldElement T = L1.Square().Add(L1Z1).Add(aZ1Sq); + if (T.IsZero) + { + return new F2mPoint(curve, T, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement X3 = T.Square(); + ECFieldElement Z3 = Z1IsOne ? T : T.Multiply(Z1Sq); + + ECFieldElement b = curve.B; + ECFieldElement L3; + if (b.BitLength < (curve.FieldSize >> 1)) + { + ECFieldElement t1 = L1.Add(X1).Square(); + ECFieldElement t2; + if (b.IsOne) + { + t2 = aZ1Sq.Add(Z1Sq).Square(); + } + else + { + // TODO Can be calculated with one square if we pre-compute sqrt(b) + t2 = aZ1Sq.SquarePlusProduct(b, Z1Sq.Square()); + } + L3 = t1.Add(T).Add(Z1Sq).Multiply(t1).Add(t2).Add(X3); + if (a.IsZero) + { + L3 = L3.Add(Z3); + } + else if (!a.IsOne) + { + L3 = L3.Add(a.AddOne().Multiply(Z3)); + } + } + else + { + ECFieldElement X1Z1 = Z1IsOne ? X1 : X1.Multiply(Z1); + L3 = X1Z1.SquarePlusProduct(T, L1Z1).Add(X3).Add(Z3); + } + + return new F2mPoint(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + default: + { + throw new InvalidOperationException("unsupported coordinate system"); + } + } + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is its own additive inverse + return b; + } + + int coord = curve.CoordinateSystem; + + switch (coord) + { + case ECCurve.COORD_LAMBDA_PROJECTIVE: + { + // NOTE: twicePlus() only optimized for lambda-affine argument + ECFieldElement X2 = b.RawXCoord, Z2 = b.RawZCoords[0]; + if (X2.IsZero || !Z2.IsOne) + { + return Twice().Add(b); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord; + + ECFieldElement X1Sq = X1.Square(); + ECFieldElement L1Sq = L1.Square(); + ECFieldElement Z1Sq = Z1.Square(); + ECFieldElement L1Z1 = L1.Multiply(Z1); + + ECFieldElement T = curve.A.Multiply(Z1Sq).Add(L1Sq).Add(L1Z1); + ECFieldElement L2plus1 = L2.AddOne(); + ECFieldElement A = curve.A.Add(L2plus1).Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); + ECFieldElement X2Z1Sq = X2.Multiply(Z1Sq); + ECFieldElement B = X2Z1Sq.Add(T).Square(); + + if (B.IsZero) + { + if (A.IsZero) + { + return b.Twice(); + } + + return curve.Infinity; + } + + if (A.IsZero) + { + return new F2mPoint(curve, A, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement X3 = A.Square().Multiply(X2Z1Sq); + ECFieldElement Z3 = A.Multiply(B).Multiply(Z1Sq); + ECFieldElement L3 = A.Add(B).Square().MultiplyPlusProduct(T, L2plus1, Z3); + + return new F2mPoint(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + default: + { + return Twice().Add(b); + } + } + } + + public override ECPoint Negate() + { + if (this.IsInfinity) + return this; + + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return this; + + ECCurve curve = this.Curve; + int coord = curve.CoordinateSystem; + + switch (coord) + { + case ECCurve.COORD_AFFINE: + { + ECFieldElement Y = this.RawYCoord; + return new F2mPoint(curve, X, Y.Add(X), IsCompressed); + } + case ECCurve.COORD_HOMOGENEOUS: + { + ECFieldElement Y = this.RawYCoord, Z = this.RawZCoords[0]; + return new F2mPoint(curve, X, Y.Add(X), new ECFieldElement[] { Z }, IsCompressed); + } + case ECCurve.COORD_LAMBDA_AFFINE: + { + ECFieldElement L = this.RawYCoord; + return new F2mPoint(curve, X, L.AddOne(), IsCompressed); + } + case ECCurve.COORD_LAMBDA_PROJECTIVE: + { + // L is actually Lambda (X + Y/X) here + ECFieldElement L = this.RawYCoord, Z = this.RawZCoords[0]; + return new F2mPoint(curve, X, L.Add(Z), new ECFieldElement[] { Z }, IsCompressed); + } + default: + { + throw new InvalidOperationException("unsupported coordinate system"); + } + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ECPoint.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ECPoint.cs.meta new file mode 100644 index 0000000..66ed309 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ECPoint.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4470a2cc8dcbb2e4b886c3a6399e3776 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ECPointMap.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ECPointMap.cs new file mode 100644 index 0000000..e78c800 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ECPointMap.cs @@ -0,0 +1,9 @@ +using System; + +namespace Org.BouncyCastle.Math.EC +{ + public interface ECPointMap + { + ECPoint Map(ECPoint p); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ECPointMap.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ECPointMap.cs.meta new file mode 100644 index 0000000..858ff9c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ECPointMap.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6617bfd0db9496c48bec870741808ea3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/LongArray.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/LongArray.cs new file mode 100644 index 0000000..a6b834f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/LongArray.cs @@ -0,0 +1,2206 @@ +using System; +using System.Text; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math.EC +{ + internal class LongArray + { + //private static long DEInterleave_MASK = 0x5555555555555555L; + + /* + * This expands 8 bit indices into 16 bit contents (high bit 14), by inserting 0s between bits. + * In a binary field, this operation is the same as squaring an 8 bit number. + */ + private static readonly ushort[] INTERLEAVE2_TABLE = new ushort[] + { + 0x0000, 0x0001, 0x0004, 0x0005, 0x0010, 0x0011, 0x0014, 0x0015, + 0x0040, 0x0041, 0x0044, 0x0045, 0x0050, 0x0051, 0x0054, 0x0055, + 0x0100, 0x0101, 0x0104, 0x0105, 0x0110, 0x0111, 0x0114, 0x0115, + 0x0140, 0x0141, 0x0144, 0x0145, 0x0150, 0x0151, 0x0154, 0x0155, + 0x0400, 0x0401, 0x0404, 0x0405, 0x0410, 0x0411, 0x0414, 0x0415, + 0x0440, 0x0441, 0x0444, 0x0445, 0x0450, 0x0451, 0x0454, 0x0455, + 0x0500, 0x0501, 0x0504, 0x0505, 0x0510, 0x0511, 0x0514, 0x0515, + 0x0540, 0x0541, 0x0544, 0x0545, 0x0550, 0x0551, 0x0554, 0x0555, + 0x1000, 0x1001, 0x1004, 0x1005, 0x1010, 0x1011, 0x1014, 0x1015, + 0x1040, 0x1041, 0x1044, 0x1045, 0x1050, 0x1051, 0x1054, 0x1055, + 0x1100, 0x1101, 0x1104, 0x1105, 0x1110, 0x1111, 0x1114, 0x1115, + 0x1140, 0x1141, 0x1144, 0x1145, 0x1150, 0x1151, 0x1154, 0x1155, + 0x1400, 0x1401, 0x1404, 0x1405, 0x1410, 0x1411, 0x1414, 0x1415, + 0x1440, 0x1441, 0x1444, 0x1445, 0x1450, 0x1451, 0x1454, 0x1455, + 0x1500, 0x1501, 0x1504, 0x1505, 0x1510, 0x1511, 0x1514, 0x1515, + 0x1540, 0x1541, 0x1544, 0x1545, 0x1550, 0x1551, 0x1554, 0x1555, + 0x4000, 0x4001, 0x4004, 0x4005, 0x4010, 0x4011, 0x4014, 0x4015, + 0x4040, 0x4041, 0x4044, 0x4045, 0x4050, 0x4051, 0x4054, 0x4055, + 0x4100, 0x4101, 0x4104, 0x4105, 0x4110, 0x4111, 0x4114, 0x4115, + 0x4140, 0x4141, 0x4144, 0x4145, 0x4150, 0x4151, 0x4154, 0x4155, + 0x4400, 0x4401, 0x4404, 0x4405, 0x4410, 0x4411, 0x4414, 0x4415, + 0x4440, 0x4441, 0x4444, 0x4445, 0x4450, 0x4451, 0x4454, 0x4455, + 0x4500, 0x4501, 0x4504, 0x4505, 0x4510, 0x4511, 0x4514, 0x4515, + 0x4540, 0x4541, 0x4544, 0x4545, 0x4550, 0x4551, 0x4554, 0x4555, + 0x5000, 0x5001, 0x5004, 0x5005, 0x5010, 0x5011, 0x5014, 0x5015, + 0x5040, 0x5041, 0x5044, 0x5045, 0x5050, 0x5051, 0x5054, 0x5055, + 0x5100, 0x5101, 0x5104, 0x5105, 0x5110, 0x5111, 0x5114, 0x5115, + 0x5140, 0x5141, 0x5144, 0x5145, 0x5150, 0x5151, 0x5154, 0x5155, + 0x5400, 0x5401, 0x5404, 0x5405, 0x5410, 0x5411, 0x5414, 0x5415, + 0x5440, 0x5441, 0x5444, 0x5445, 0x5450, 0x5451, 0x5454, 0x5455, + 0x5500, 0x5501, 0x5504, 0x5505, 0x5510, 0x5511, 0x5514, 0x5515, + 0x5540, 0x5541, 0x5544, 0x5545, 0x5550, 0x5551, 0x5554, 0x5555 + }; + + /* + * This expands 7 bit indices into 21 bit contents (high bit 18), by inserting 0s between bits. + */ + private static readonly int[] INTERLEAVE3_TABLE = new int[] + { + 0x00000, 0x00001, 0x00008, 0x00009, 0x00040, 0x00041, 0x00048, 0x00049, + 0x00200, 0x00201, 0x00208, 0x00209, 0x00240, 0x00241, 0x00248, 0x00249, + 0x01000, 0x01001, 0x01008, 0x01009, 0x01040, 0x01041, 0x01048, 0x01049, + 0x01200, 0x01201, 0x01208, 0x01209, 0x01240, 0x01241, 0x01248, 0x01249, + 0x08000, 0x08001, 0x08008, 0x08009, 0x08040, 0x08041, 0x08048, 0x08049, + 0x08200, 0x08201, 0x08208, 0x08209, 0x08240, 0x08241, 0x08248, 0x08249, + 0x09000, 0x09001, 0x09008, 0x09009, 0x09040, 0x09041, 0x09048, 0x09049, + 0x09200, 0x09201, 0x09208, 0x09209, 0x09240, 0x09241, 0x09248, 0x09249, + 0x40000, 0x40001, 0x40008, 0x40009, 0x40040, 0x40041, 0x40048, 0x40049, + 0x40200, 0x40201, 0x40208, 0x40209, 0x40240, 0x40241, 0x40248, 0x40249, + 0x41000, 0x41001, 0x41008, 0x41009, 0x41040, 0x41041, 0x41048, 0x41049, + 0x41200, 0x41201, 0x41208, 0x41209, 0x41240, 0x41241, 0x41248, 0x41249, + 0x48000, 0x48001, 0x48008, 0x48009, 0x48040, 0x48041, 0x48048, 0x48049, + 0x48200, 0x48201, 0x48208, 0x48209, 0x48240, 0x48241, 0x48248, 0x48249, + 0x49000, 0x49001, 0x49008, 0x49009, 0x49040, 0x49041, 0x49048, 0x49049, + 0x49200, 0x49201, 0x49208, 0x49209, 0x49240, 0x49241, 0x49248, 0x49249 + }; + + /* + * This expands 8 bit indices into 32 bit contents (high bit 28), by inserting 0s between bits. + */ + private static readonly int[] INTERLEAVE4_TABLE = new int[] + { + 0x00000000, 0x00000001, 0x00000010, 0x00000011, 0x00000100, 0x00000101, 0x00000110, 0x00000111, + 0x00001000, 0x00001001, 0x00001010, 0x00001011, 0x00001100, 0x00001101, 0x00001110, 0x00001111, + 0x00010000, 0x00010001, 0x00010010, 0x00010011, 0x00010100, 0x00010101, 0x00010110, 0x00010111, + 0x00011000, 0x00011001, 0x00011010, 0x00011011, 0x00011100, 0x00011101, 0x00011110, 0x00011111, + 0x00100000, 0x00100001, 0x00100010, 0x00100011, 0x00100100, 0x00100101, 0x00100110, 0x00100111, + 0x00101000, 0x00101001, 0x00101010, 0x00101011, 0x00101100, 0x00101101, 0x00101110, 0x00101111, + 0x00110000, 0x00110001, 0x00110010, 0x00110011, 0x00110100, 0x00110101, 0x00110110, 0x00110111, + 0x00111000, 0x00111001, 0x00111010, 0x00111011, 0x00111100, 0x00111101, 0x00111110, 0x00111111, + 0x01000000, 0x01000001, 0x01000010, 0x01000011, 0x01000100, 0x01000101, 0x01000110, 0x01000111, + 0x01001000, 0x01001001, 0x01001010, 0x01001011, 0x01001100, 0x01001101, 0x01001110, 0x01001111, + 0x01010000, 0x01010001, 0x01010010, 0x01010011, 0x01010100, 0x01010101, 0x01010110, 0x01010111, + 0x01011000, 0x01011001, 0x01011010, 0x01011011, 0x01011100, 0x01011101, 0x01011110, 0x01011111, + 0x01100000, 0x01100001, 0x01100010, 0x01100011, 0x01100100, 0x01100101, 0x01100110, 0x01100111, + 0x01101000, 0x01101001, 0x01101010, 0x01101011, 0x01101100, 0x01101101, 0x01101110, 0x01101111, + 0x01110000, 0x01110001, 0x01110010, 0x01110011, 0x01110100, 0x01110101, 0x01110110, 0x01110111, + 0x01111000, 0x01111001, 0x01111010, 0x01111011, 0x01111100, 0x01111101, 0x01111110, 0x01111111, + 0x10000000, 0x10000001, 0x10000010, 0x10000011, 0x10000100, 0x10000101, 0x10000110, 0x10000111, + 0x10001000, 0x10001001, 0x10001010, 0x10001011, 0x10001100, 0x10001101, 0x10001110, 0x10001111, + 0x10010000, 0x10010001, 0x10010010, 0x10010011, 0x10010100, 0x10010101, 0x10010110, 0x10010111, + 0x10011000, 0x10011001, 0x10011010, 0x10011011, 0x10011100, 0x10011101, 0x10011110, 0x10011111, + 0x10100000, 0x10100001, 0x10100010, 0x10100011, 0x10100100, 0x10100101, 0x10100110, 0x10100111, + 0x10101000, 0x10101001, 0x10101010, 0x10101011, 0x10101100, 0x10101101, 0x10101110, 0x10101111, + 0x10110000, 0x10110001, 0x10110010, 0x10110011, 0x10110100, 0x10110101, 0x10110110, 0x10110111, + 0x10111000, 0x10111001, 0x10111010, 0x10111011, 0x10111100, 0x10111101, 0x10111110, 0x10111111, + 0x11000000, 0x11000001, 0x11000010, 0x11000011, 0x11000100, 0x11000101, 0x11000110, 0x11000111, + 0x11001000, 0x11001001, 0x11001010, 0x11001011, 0x11001100, 0x11001101, 0x11001110, 0x11001111, + 0x11010000, 0x11010001, 0x11010010, 0x11010011, 0x11010100, 0x11010101, 0x11010110, 0x11010111, + 0x11011000, 0x11011001, 0x11011010, 0x11011011, 0x11011100, 0x11011101, 0x11011110, 0x11011111, + 0x11100000, 0x11100001, 0x11100010, 0x11100011, 0x11100100, 0x11100101, 0x11100110, 0x11100111, + 0x11101000, 0x11101001, 0x11101010, 0x11101011, 0x11101100, 0x11101101, 0x11101110, 0x11101111, + 0x11110000, 0x11110001, 0x11110010, 0x11110011, 0x11110100, 0x11110101, 0x11110110, 0x11110111, + 0x11111000, 0x11111001, 0x11111010, 0x11111011, 0x11111100, 0x11111101, 0x11111110, 0x11111111 + }; + + /* + * This expands 7 bit indices into 35 bit contents (high bit 30), by inserting 0s between bits. + */ + private static readonly int[] INTERLEAVE5_TABLE = new int[] { + 0x00000000, 0x00000001, 0x00000020, 0x00000021, 0x00000400, 0x00000401, 0x00000420, 0x00000421, + 0x00008000, 0x00008001, 0x00008020, 0x00008021, 0x00008400, 0x00008401, 0x00008420, 0x00008421, + 0x00100000, 0x00100001, 0x00100020, 0x00100021, 0x00100400, 0x00100401, 0x00100420, 0x00100421, + 0x00108000, 0x00108001, 0x00108020, 0x00108021, 0x00108400, 0x00108401, 0x00108420, 0x00108421, + 0x02000000, 0x02000001, 0x02000020, 0x02000021, 0x02000400, 0x02000401, 0x02000420, 0x02000421, + 0x02008000, 0x02008001, 0x02008020, 0x02008021, 0x02008400, 0x02008401, 0x02008420, 0x02008421, + 0x02100000, 0x02100001, 0x02100020, 0x02100021, 0x02100400, 0x02100401, 0x02100420, 0x02100421, + 0x02108000, 0x02108001, 0x02108020, 0x02108021, 0x02108400, 0x02108401, 0x02108420, 0x02108421, + 0x40000000, 0x40000001, 0x40000020, 0x40000021, 0x40000400, 0x40000401, 0x40000420, 0x40000421, + 0x40008000, 0x40008001, 0x40008020, 0x40008021, 0x40008400, 0x40008401, 0x40008420, 0x40008421, + 0x40100000, 0x40100001, 0x40100020, 0x40100021, 0x40100400, 0x40100401, 0x40100420, 0x40100421, + 0x40108000, 0x40108001, 0x40108020, 0x40108021, 0x40108400, 0x40108401, 0x40108420, 0x40108421, + 0x42000000, 0x42000001, 0x42000020, 0x42000021, 0x42000400, 0x42000401, 0x42000420, 0x42000421, + 0x42008000, 0x42008001, 0x42008020, 0x42008021, 0x42008400, 0x42008401, 0x42008420, 0x42008421, + 0x42100000, 0x42100001, 0x42100020, 0x42100021, 0x42100400, 0x42100401, 0x42100420, 0x42100421, + 0x42108000, 0x42108001, 0x42108020, 0x42108021, 0x42108400, 0x42108401, 0x42108420, 0x42108421 + }; + + /* + * This expands 9 bit indices into 63 bit (long) contents (high bit 56), by inserting 0s between bits. + */ + private static readonly long[] INTERLEAVE7_TABLE = new long[] + { + 0x0000000000000000L, 0x0000000000000001L, 0x0000000000000080L, 0x0000000000000081L, + 0x0000000000004000L, 0x0000000000004001L, 0x0000000000004080L, 0x0000000000004081L, + 0x0000000000200000L, 0x0000000000200001L, 0x0000000000200080L, 0x0000000000200081L, + 0x0000000000204000L, 0x0000000000204001L, 0x0000000000204080L, 0x0000000000204081L, + 0x0000000010000000L, 0x0000000010000001L, 0x0000000010000080L, 0x0000000010000081L, + 0x0000000010004000L, 0x0000000010004001L, 0x0000000010004080L, 0x0000000010004081L, + 0x0000000010200000L, 0x0000000010200001L, 0x0000000010200080L, 0x0000000010200081L, + 0x0000000010204000L, 0x0000000010204001L, 0x0000000010204080L, 0x0000000010204081L, + 0x0000000800000000L, 0x0000000800000001L, 0x0000000800000080L, 0x0000000800000081L, + 0x0000000800004000L, 0x0000000800004001L, 0x0000000800004080L, 0x0000000800004081L, + 0x0000000800200000L, 0x0000000800200001L, 0x0000000800200080L, 0x0000000800200081L, + 0x0000000800204000L, 0x0000000800204001L, 0x0000000800204080L, 0x0000000800204081L, + 0x0000000810000000L, 0x0000000810000001L, 0x0000000810000080L, 0x0000000810000081L, + 0x0000000810004000L, 0x0000000810004001L, 0x0000000810004080L, 0x0000000810004081L, + 0x0000000810200000L, 0x0000000810200001L, 0x0000000810200080L, 0x0000000810200081L, + 0x0000000810204000L, 0x0000000810204001L, 0x0000000810204080L, 0x0000000810204081L, + 0x0000040000000000L, 0x0000040000000001L, 0x0000040000000080L, 0x0000040000000081L, + 0x0000040000004000L, 0x0000040000004001L, 0x0000040000004080L, 0x0000040000004081L, + 0x0000040000200000L, 0x0000040000200001L, 0x0000040000200080L, 0x0000040000200081L, + 0x0000040000204000L, 0x0000040000204001L, 0x0000040000204080L, 0x0000040000204081L, + 0x0000040010000000L, 0x0000040010000001L, 0x0000040010000080L, 0x0000040010000081L, + 0x0000040010004000L, 0x0000040010004001L, 0x0000040010004080L, 0x0000040010004081L, + 0x0000040010200000L, 0x0000040010200001L, 0x0000040010200080L, 0x0000040010200081L, + 0x0000040010204000L, 0x0000040010204001L, 0x0000040010204080L, 0x0000040010204081L, + 0x0000040800000000L, 0x0000040800000001L, 0x0000040800000080L, 0x0000040800000081L, + 0x0000040800004000L, 0x0000040800004001L, 0x0000040800004080L, 0x0000040800004081L, + 0x0000040800200000L, 0x0000040800200001L, 0x0000040800200080L, 0x0000040800200081L, + 0x0000040800204000L, 0x0000040800204001L, 0x0000040800204080L, 0x0000040800204081L, + 0x0000040810000000L, 0x0000040810000001L, 0x0000040810000080L, 0x0000040810000081L, + 0x0000040810004000L, 0x0000040810004001L, 0x0000040810004080L, 0x0000040810004081L, + 0x0000040810200000L, 0x0000040810200001L, 0x0000040810200080L, 0x0000040810200081L, + 0x0000040810204000L, 0x0000040810204001L, 0x0000040810204080L, 0x0000040810204081L, + 0x0002000000000000L, 0x0002000000000001L, 0x0002000000000080L, 0x0002000000000081L, + 0x0002000000004000L, 0x0002000000004001L, 0x0002000000004080L, 0x0002000000004081L, + 0x0002000000200000L, 0x0002000000200001L, 0x0002000000200080L, 0x0002000000200081L, + 0x0002000000204000L, 0x0002000000204001L, 0x0002000000204080L, 0x0002000000204081L, + 0x0002000010000000L, 0x0002000010000001L, 0x0002000010000080L, 0x0002000010000081L, + 0x0002000010004000L, 0x0002000010004001L, 0x0002000010004080L, 0x0002000010004081L, + 0x0002000010200000L, 0x0002000010200001L, 0x0002000010200080L, 0x0002000010200081L, + 0x0002000010204000L, 0x0002000010204001L, 0x0002000010204080L, 0x0002000010204081L, + 0x0002000800000000L, 0x0002000800000001L, 0x0002000800000080L, 0x0002000800000081L, + 0x0002000800004000L, 0x0002000800004001L, 0x0002000800004080L, 0x0002000800004081L, + 0x0002000800200000L, 0x0002000800200001L, 0x0002000800200080L, 0x0002000800200081L, + 0x0002000800204000L, 0x0002000800204001L, 0x0002000800204080L, 0x0002000800204081L, + 0x0002000810000000L, 0x0002000810000001L, 0x0002000810000080L, 0x0002000810000081L, + 0x0002000810004000L, 0x0002000810004001L, 0x0002000810004080L, 0x0002000810004081L, + 0x0002000810200000L, 0x0002000810200001L, 0x0002000810200080L, 0x0002000810200081L, + 0x0002000810204000L, 0x0002000810204001L, 0x0002000810204080L, 0x0002000810204081L, + 0x0002040000000000L, 0x0002040000000001L, 0x0002040000000080L, 0x0002040000000081L, + 0x0002040000004000L, 0x0002040000004001L, 0x0002040000004080L, 0x0002040000004081L, + 0x0002040000200000L, 0x0002040000200001L, 0x0002040000200080L, 0x0002040000200081L, + 0x0002040000204000L, 0x0002040000204001L, 0x0002040000204080L, 0x0002040000204081L, + 0x0002040010000000L, 0x0002040010000001L, 0x0002040010000080L, 0x0002040010000081L, + 0x0002040010004000L, 0x0002040010004001L, 0x0002040010004080L, 0x0002040010004081L, + 0x0002040010200000L, 0x0002040010200001L, 0x0002040010200080L, 0x0002040010200081L, + 0x0002040010204000L, 0x0002040010204001L, 0x0002040010204080L, 0x0002040010204081L, + 0x0002040800000000L, 0x0002040800000001L, 0x0002040800000080L, 0x0002040800000081L, + 0x0002040800004000L, 0x0002040800004001L, 0x0002040800004080L, 0x0002040800004081L, + 0x0002040800200000L, 0x0002040800200001L, 0x0002040800200080L, 0x0002040800200081L, + 0x0002040800204000L, 0x0002040800204001L, 0x0002040800204080L, 0x0002040800204081L, + 0x0002040810000000L, 0x0002040810000001L, 0x0002040810000080L, 0x0002040810000081L, + 0x0002040810004000L, 0x0002040810004001L, 0x0002040810004080L, 0x0002040810004081L, + 0x0002040810200000L, 0x0002040810200001L, 0x0002040810200080L, 0x0002040810200081L, + 0x0002040810204000L, 0x0002040810204001L, 0x0002040810204080L, 0x0002040810204081L, + 0x0100000000000000L, 0x0100000000000001L, 0x0100000000000080L, 0x0100000000000081L, + 0x0100000000004000L, 0x0100000000004001L, 0x0100000000004080L, 0x0100000000004081L, + 0x0100000000200000L, 0x0100000000200001L, 0x0100000000200080L, 0x0100000000200081L, + 0x0100000000204000L, 0x0100000000204001L, 0x0100000000204080L, 0x0100000000204081L, + 0x0100000010000000L, 0x0100000010000001L, 0x0100000010000080L, 0x0100000010000081L, + 0x0100000010004000L, 0x0100000010004001L, 0x0100000010004080L, 0x0100000010004081L, + 0x0100000010200000L, 0x0100000010200001L, 0x0100000010200080L, 0x0100000010200081L, + 0x0100000010204000L, 0x0100000010204001L, 0x0100000010204080L, 0x0100000010204081L, + 0x0100000800000000L, 0x0100000800000001L, 0x0100000800000080L, 0x0100000800000081L, + 0x0100000800004000L, 0x0100000800004001L, 0x0100000800004080L, 0x0100000800004081L, + 0x0100000800200000L, 0x0100000800200001L, 0x0100000800200080L, 0x0100000800200081L, + 0x0100000800204000L, 0x0100000800204001L, 0x0100000800204080L, 0x0100000800204081L, + 0x0100000810000000L, 0x0100000810000001L, 0x0100000810000080L, 0x0100000810000081L, + 0x0100000810004000L, 0x0100000810004001L, 0x0100000810004080L, 0x0100000810004081L, + 0x0100000810200000L, 0x0100000810200001L, 0x0100000810200080L, 0x0100000810200081L, + 0x0100000810204000L, 0x0100000810204001L, 0x0100000810204080L, 0x0100000810204081L, + 0x0100040000000000L, 0x0100040000000001L, 0x0100040000000080L, 0x0100040000000081L, + 0x0100040000004000L, 0x0100040000004001L, 0x0100040000004080L, 0x0100040000004081L, + 0x0100040000200000L, 0x0100040000200001L, 0x0100040000200080L, 0x0100040000200081L, + 0x0100040000204000L, 0x0100040000204001L, 0x0100040000204080L, 0x0100040000204081L, + 0x0100040010000000L, 0x0100040010000001L, 0x0100040010000080L, 0x0100040010000081L, + 0x0100040010004000L, 0x0100040010004001L, 0x0100040010004080L, 0x0100040010004081L, + 0x0100040010200000L, 0x0100040010200001L, 0x0100040010200080L, 0x0100040010200081L, + 0x0100040010204000L, 0x0100040010204001L, 0x0100040010204080L, 0x0100040010204081L, + 0x0100040800000000L, 0x0100040800000001L, 0x0100040800000080L, 0x0100040800000081L, + 0x0100040800004000L, 0x0100040800004001L, 0x0100040800004080L, 0x0100040800004081L, + 0x0100040800200000L, 0x0100040800200001L, 0x0100040800200080L, 0x0100040800200081L, + 0x0100040800204000L, 0x0100040800204001L, 0x0100040800204080L, 0x0100040800204081L, + 0x0100040810000000L, 0x0100040810000001L, 0x0100040810000080L, 0x0100040810000081L, + 0x0100040810004000L, 0x0100040810004001L, 0x0100040810004080L, 0x0100040810004081L, + 0x0100040810200000L, 0x0100040810200001L, 0x0100040810200080L, 0x0100040810200081L, + 0x0100040810204000L, 0x0100040810204001L, 0x0100040810204080L, 0x0100040810204081L, + 0x0102000000000000L, 0x0102000000000001L, 0x0102000000000080L, 0x0102000000000081L, + 0x0102000000004000L, 0x0102000000004001L, 0x0102000000004080L, 0x0102000000004081L, + 0x0102000000200000L, 0x0102000000200001L, 0x0102000000200080L, 0x0102000000200081L, + 0x0102000000204000L, 0x0102000000204001L, 0x0102000000204080L, 0x0102000000204081L, + 0x0102000010000000L, 0x0102000010000001L, 0x0102000010000080L, 0x0102000010000081L, + 0x0102000010004000L, 0x0102000010004001L, 0x0102000010004080L, 0x0102000010004081L, + 0x0102000010200000L, 0x0102000010200001L, 0x0102000010200080L, 0x0102000010200081L, + 0x0102000010204000L, 0x0102000010204001L, 0x0102000010204080L, 0x0102000010204081L, + 0x0102000800000000L, 0x0102000800000001L, 0x0102000800000080L, 0x0102000800000081L, + 0x0102000800004000L, 0x0102000800004001L, 0x0102000800004080L, 0x0102000800004081L, + 0x0102000800200000L, 0x0102000800200001L, 0x0102000800200080L, 0x0102000800200081L, + 0x0102000800204000L, 0x0102000800204001L, 0x0102000800204080L, 0x0102000800204081L, + 0x0102000810000000L, 0x0102000810000001L, 0x0102000810000080L, 0x0102000810000081L, + 0x0102000810004000L, 0x0102000810004001L, 0x0102000810004080L, 0x0102000810004081L, + 0x0102000810200000L, 0x0102000810200001L, 0x0102000810200080L, 0x0102000810200081L, + 0x0102000810204000L, 0x0102000810204001L, 0x0102000810204080L, 0x0102000810204081L, + 0x0102040000000000L, 0x0102040000000001L, 0x0102040000000080L, 0x0102040000000081L, + 0x0102040000004000L, 0x0102040000004001L, 0x0102040000004080L, 0x0102040000004081L, + 0x0102040000200000L, 0x0102040000200001L, 0x0102040000200080L, 0x0102040000200081L, + 0x0102040000204000L, 0x0102040000204001L, 0x0102040000204080L, 0x0102040000204081L, + 0x0102040010000000L, 0x0102040010000001L, 0x0102040010000080L, 0x0102040010000081L, + 0x0102040010004000L, 0x0102040010004001L, 0x0102040010004080L, 0x0102040010004081L, + 0x0102040010200000L, 0x0102040010200001L, 0x0102040010200080L, 0x0102040010200081L, + 0x0102040010204000L, 0x0102040010204001L, 0x0102040010204080L, 0x0102040010204081L, + 0x0102040800000000L, 0x0102040800000001L, 0x0102040800000080L, 0x0102040800000081L, + 0x0102040800004000L, 0x0102040800004001L, 0x0102040800004080L, 0x0102040800004081L, + 0x0102040800200000L, 0x0102040800200001L, 0x0102040800200080L, 0x0102040800200081L, + 0x0102040800204000L, 0x0102040800204001L, 0x0102040800204080L, 0x0102040800204081L, + 0x0102040810000000L, 0x0102040810000001L, 0x0102040810000080L, 0x0102040810000081L, + 0x0102040810004000L, 0x0102040810004001L, 0x0102040810004080L, 0x0102040810004081L, + 0x0102040810200000L, 0x0102040810200001L, 0x0102040810200080L, 0x0102040810200081L, + 0x0102040810204000L, 0x0102040810204001L, 0x0102040810204080L, 0x0102040810204081L + }; + + // For toString(); must have length 64 + private const string ZEROES = "0000000000000000000000000000000000000000000000000000000000000000"; + + internal static readonly byte[] BitLengths = + { + 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 + }; + + // TODO make m fixed for the LongArray, and hence compute T once and for all + + private long[] m_ints; + + public LongArray(int intLen) + { + m_ints = new long[intLen]; + } + + public LongArray(long[] ints) + { + m_ints = ints; + } + + public LongArray(long[] ints, int off, int len) + { + if (off == 0 && len == ints.Length) + { + m_ints = ints; + } + else + { + m_ints = new long[len]; + Array.Copy(ints, off, m_ints, 0, len); + } + } + + public LongArray(BigInteger bigInt) + { + if (bigInt == null || bigInt.SignValue < 0) + { + throw new ArgumentException("invalid F2m field value", "bigInt"); + } + + if (bigInt.SignValue == 0) + { + m_ints = new long[] { 0L }; + return; + } + + byte[] barr = bigInt.ToByteArray(); + int barrLen = barr.Length; + int barrStart = 0; + if (barr[0] == 0) + { + // First byte is 0 to enforce highest (=sign) bit is zero. + // In this case ignore barr[0]. + barrLen--; + barrStart = 1; + } + int intLen = (barrLen + 7) / 8; + m_ints = new long[intLen]; + + int iarrJ = intLen - 1; + int rem = barrLen % 8 + barrStart; + long temp = 0; + int barrI = barrStart; + if (barrStart < rem) + { + for (; barrI < rem; barrI++) + { + temp <<= 8; + uint barrBarrI = barr[barrI]; + temp |= barrBarrI; + } + m_ints[iarrJ--] = temp; + } + + for (; iarrJ >= 0; iarrJ--) + { + temp = 0; + for (int i = 0; i < 8; i++) + { + temp <<= 8; + uint barrBarrI = barr[barrI++]; + temp |= barrBarrI; + } + m_ints[iarrJ] = temp; + } + } + + internal void CopyTo(long[] z, int zOff) + { + Array.Copy(m_ints, 0, z, zOff, m_ints.Length); + } + + public bool IsOne() + { + long[] a = m_ints; + if (a[0] != 1L) + { + return false; + } + for (int i = 1; i < a.Length; ++i) + { + if (a[i] != 0L) + { + return false; + } + } + return true; + } + + public bool IsZero() + { + long[] a = m_ints; + for (int i = 0; i < a.Length; ++i) + { + if (a[i] != 0L) + { + return false; + } + } + return true; + } + + public int GetUsedLength() + { + return GetUsedLengthFrom(m_ints.Length); + } + + public int GetUsedLengthFrom(int from) + { + long[] a = m_ints; + from = System.Math.Min(from, a.Length); + + if (from < 1) + { + return 0; + } + + // Check if first element will act as sentinel + if (a[0] != 0) + { + while (a[--from] == 0) + { + } + return from + 1; + } + + do + { + if (a[--from] != 0) + { + return from + 1; + } + } + while (from > 0); + + return 0; + } + + public int Degree() + { + int i = m_ints.Length; + long w; + do + { + if (i == 0) + { + return 0; + } + w = m_ints[--i]; + } + while (w == 0); + + return (i << 6) + BitLength(w); + } + + private int DegreeFrom(int limit) + { + int i = (int)(((uint)limit + 62) >> 6); + long w; + do + { + if (i == 0) + { + return 0; + } + w = m_ints[--i]; + } + while (w == 0); + + return (i << 6) + BitLength(w); + } + + // private int lowestCoefficient() + // { + // for (int i = 0; i < m_ints.Length; ++i) + // { + // long mi = m_ints[i]; + // if (mi != 0) + // { + // int j = 0; + // while ((mi & 0xFFL) == 0) + // { + // j += 8; + // mi >>>= 8; + // } + // while ((mi & 1L) == 0) + // { + // ++j; + // mi >>>= 1; + // } + // return (i << 6) + j; + // } + // } + // return -1; + // } + + private static int BitLength(long w) + { + int u = (int)((ulong)w >> 32), b; + if (u == 0) + { + u = (int)w; + b = 0; + } + else + { + b = 32; + } + + int t = (int)((uint)u >> 16), k; + if (t == 0) + { + t = (int)((uint)u >> 8); + k = (t == 0) ? BitLengths[u] : 8 + BitLengths[t]; + } + else + { + int v = (int)((uint)t >> 8); + k = (v == 0) ? 16 + BitLengths[t] : 24 + BitLengths[v]; + } + + return b + k; + } + + private long[] ResizedInts(int newLen) + { + long[] newInts = new long[newLen]; + Array.Copy(m_ints, 0, newInts, 0, System.Math.Min(m_ints.Length, newLen)); + return newInts; + } + + public BigInteger ToBigInteger() + { + int usedLen = GetUsedLength(); + if (usedLen == 0) + { + return BigInteger.Zero; + } + + long highestInt = m_ints[usedLen - 1]; + byte[] temp = new byte[8]; + int barrI = 0; + bool trailingZeroBytesDone = false; + for (int j = 7; j >= 0; j--) + { + byte thisByte = (byte)((ulong)highestInt >> (8 * j)); + if (trailingZeroBytesDone || (thisByte != 0)) + { + trailingZeroBytesDone = true; + temp[barrI++] = thisByte; + } + } + + int barrLen = 8 * (usedLen - 1) + barrI; + byte[] barr = new byte[barrLen]; + for (int j = 0; j < barrI; j++) + { + barr[j] = temp[j]; + } + // Highest value int is done now + + for (int iarrJ = usedLen - 2; iarrJ >= 0; iarrJ--) + { + long mi = m_ints[iarrJ]; + for (int j = 7; j >= 0; j--) + { + barr[barrI++] = (byte)((ulong)mi >> (8 * j)); + } + } + return new BigInteger(1, barr); + } + + // private static long shiftUp(long[] x, int xOff, int count) + // { + // long prev = 0; + // for (int i = 0; i < count; ++i) + // { + // long next = x[xOff + i]; + // x[xOff + i] = (next << 1) | prev; + // prev = next >>> 63; + // } + // return prev; + // } + + private static long ShiftUp(long[] x, int xOff, int count, int shift) + { + int shiftInv = 64 - shift; + long prev = 0; + for (int i = 0; i < count; ++i) + { + long next = x[xOff + i]; + x[xOff + i] = (next << shift) | prev; + prev = (long)((ulong)next >> shiftInv); + } + return prev; + } + + private static long ShiftUp(long[] x, int xOff, long[] z, int zOff, int count, int shift) + { + int shiftInv = 64 - shift; + long prev = 0; + for (int i = 0; i < count; ++i) + { + long next = x[xOff + i]; + z[zOff + i] = (next << shift) | prev; + prev = (long)((ulong)next >> shiftInv); + } + return prev; + } + + public LongArray AddOne() + { + if (m_ints.Length == 0) + { + return new LongArray(new long[]{ 1L }); + } + + int resultLen = System.Math.Max(1, GetUsedLength()); + long[] ints = ResizedInts(resultLen); + ints[0] ^= 1L; + return new LongArray(ints); + } + + // private void addShiftedByBits(LongArray other, int bits) + // { + // int words = bits >>> 6; + // int shift = bits & 0x3F; + // + // if (shift == 0) + // { + // addShiftedByWords(other, words); + // return; + // } + // + // int otherUsedLen = other.GetUsedLength(); + // if (otherUsedLen == 0) + // { + // return; + // } + // + // int minLen = otherUsedLen + words + 1; + // if (minLen > m_ints.Length) + // { + // m_ints = resizedInts(minLen); + // } + // + // long carry = addShiftedByBits(m_ints, words, other.m_ints, 0, otherUsedLen, shift); + // m_ints[otherUsedLen + words] ^= carry; + // } + + private void AddShiftedByBitsSafe(LongArray other, int otherDegree, int bits) + { + int otherLen = (int)((uint)(otherDegree + 63) >> 6); + + int words = (int)((uint)bits >> 6); + int shift = bits & 0x3F; + + if (shift == 0) + { + Add(m_ints, words, other.m_ints, 0, otherLen); + return; + } + + long carry = AddShiftedUp(m_ints, words, other.m_ints, 0, otherLen, shift); + if (carry != 0L) + { + m_ints[otherLen + words] ^= carry; + } + } + + private static long AddShiftedUp(long[] x, int xOff, long[] y, int yOff, int count, int shift) + { + int shiftInv = 64 - shift; + long prev = 0; + for (int i = 0; i < count; ++i) + { + long next = y[yOff + i]; + x[xOff + i] ^= (next << shift) | prev; + prev = (long)((ulong)next >> shiftInv); + } + return prev; + } + + private static long AddShiftedDown(long[] x, int xOff, long[] y, int yOff, int count, int shift) + { + int shiftInv = 64 - shift; + long prev = 0; + int i = count; + while (--i >= 0) + { + long next = y[yOff + i]; + x[xOff + i] ^= (long)((ulong)next >> shift) | prev; + prev = next << shiftInv; + } + return prev; + } + + public void AddShiftedByWords(LongArray other, int words) + { + int otherUsedLen = other.GetUsedLength(); + if (otherUsedLen == 0) + { + return; + } + + int minLen = otherUsedLen + words; + if (minLen > m_ints.Length) + { + m_ints = ResizedInts(minLen); + } + + Add(m_ints, words, other.m_ints, 0, otherUsedLen); + } + + private static void Add(long[] x, int xOff, long[] y, int yOff, int count) + { + for (int i = 0; i < count; ++i) + { + x[xOff + i] ^= y[yOff + i]; + } + } + + private static void Add(long[] x, int xOff, long[] y, int yOff, long[] z, int zOff, int count) + { + for (int i = 0; i < count; ++i) + { + z[zOff + i] = x[xOff + i] ^ y[yOff + i]; + } + } + + private static void AddBoth(long[] x, int xOff, long[] y1, int y1Off, long[] y2, int y2Off, int count) + { + for (int i = 0; i < count; ++i) + { + x[xOff + i] ^= y1[y1Off + i] ^ y2[y2Off + i]; + } + } + + private static void Distribute(long[] x, int src, int dst1, int dst2, int count) + { + for (int i = 0; i < count; ++i) + { + long v = x[src + i]; + x[dst1 + i] ^= v; + x[dst2 + i] ^= v; + } + } + + public int Length + { + get { return m_ints.Length; } + } + + private static void FlipWord(long[] buf, int off, int bit, long word) + { + int n = off + (int)((uint)bit >> 6); + int shift = bit & 0x3F; + if (shift == 0) + { + buf[n] ^= word; + } + else + { + buf[n] ^= word << shift; + word = (long)((ulong)word >> (64 - shift)); + if (word != 0) + { + buf[++n] ^= word; + } + } + } + + // private static long getWord(long[] buf, int off, int len, int bit) + // { + // int n = off + (bit >>> 6); + // int shift = bit & 0x3F; + // if (shift == 0) + // { + // return buf[n]; + // } + // long result = buf[n] >>> shift; + // if (++n < len) + // { + // result |= buf[n] << (64 - shift); + // } + // return result; + // } + + public bool TestBitZero() + { + return m_ints.Length > 0 && (m_ints[0] & 1L) != 0; + } + + private static bool TestBit(long[] buf, int off, int n) + { + // theInt = n / 64 + int theInt = (int)((uint)n >> 6); + // theBit = n % 64 + int theBit = n & 0x3F; + long tester = 1L << theBit; + return (buf[off + theInt] & tester) != 0; + } + + private static void FlipBit(long[] buf, int off, int n) + { + // theInt = n / 64 + int theInt = (int)((uint)n >> 6); + // theBit = n % 64 + int theBit = n & 0x3F; + long flipper = 1L << theBit; + buf[off + theInt] ^= flipper; + } + + // private static void SetBit(long[] buf, int off, int n) + // { + // // theInt = n / 64 + // int theInt = n >>> 6; + // // theBit = n % 64 + // int theBit = n & 0x3F; + // long setter = 1L << theBit; + // buf[off + theInt] |= setter; + // } + // + // private static void ClearBit(long[] buf, int off, int n) + // { + // // theInt = n / 64 + // int theInt = n >>> 6; + // // theBit = n % 64 + // int theBit = n & 0x3F; + // long setter = 1L << theBit; + // buf[off + theInt] &= ~setter; + // } + + private static void MultiplyWord(long a, long[] b, int bLen, long[] c, int cOff) + { + if ((a & 1L) != 0L) + { + Add(c, cOff, b, 0, bLen); + } + int k = 1; + while ((a = (long)((ulong)a >> 1)) != 0L) + { + if ((a & 1L) != 0L) + { + long carry = AddShiftedUp(c, cOff, b, 0, bLen, k); + if (carry != 0L) + { + c[cOff + bLen] ^= carry; + } + } + ++k; + } + } + + public LongArray ModMultiplyLD(LongArray other, int m, int[] ks) + { + /* + * Find out the degree of each argument and handle the zero cases + */ + int aDeg = Degree(); + if (aDeg == 0) + { + return this; + } + int bDeg = other.Degree(); + if (bDeg == 0) + { + return other; + } + + /* + * Swap if necessary so that A is the smaller argument + */ + LongArray A = this, B = other; + if (aDeg > bDeg) + { + A = other; B = this; + int tmp = aDeg; aDeg = bDeg; bDeg = tmp; + } + + /* + * Establish the word lengths of the arguments and result + */ + int aLen = (int)((uint)(aDeg + 63) >> 6); + int bLen = (int)((uint)(bDeg + 63) >> 6); + int cLen = (int)((uint)(aDeg + bDeg + 62) >> 6); + + if (aLen == 1) + { + long a0 = A.m_ints[0]; + if (a0 == 1L) + { + return B; + } + + /* + * Fast path for small A, with performance dependent only on the number of set bits + */ + long[] c0 = new long[cLen]; + MultiplyWord(a0, B.m_ints, bLen, c0, 0); + + /* + * Reduce the raw answer against the reduction coefficients + */ + return ReduceResult(c0, 0, cLen, m, ks); + } + + /* + * Determine if B will get bigger during shifting + */ + int bMax = (int)((uint)(bDeg + 7 + 63) >> 6); + + /* + * Lookup table for the offset of each B in the tables + */ + int[] ti = new int[16]; + + /* + * Precompute table of all 4-bit products of B + */ + long[] T0 = new long[bMax << 4]; + int tOff = bMax; + ti[1] = tOff; + Array.Copy(B.m_ints, 0, T0, tOff, bLen); + for (int i = 2; i < 16; ++i) + { + ti[i] = (tOff += bMax); + if ((i & 1) == 0) + { + ShiftUp(T0, (int)((uint)tOff >> 1), T0, tOff, bMax, 1); + } + else + { + Add(T0, bMax, T0, tOff - bMax, T0, tOff, bMax); + } + } + + /* + * Second table with all 4-bit products of B shifted 4 bits + */ + long[] T1 = new long[T0.Length]; + ShiftUp(T0, 0, T1, 0, T0.Length, 4); + // shiftUp(T0, bMax, T1, bMax, tOff, 4); + + long[] a = A.m_ints; + long[] c = new long[cLen]; + + int MASK = 0xF; + + /* + * Lopez-Dahab algorithm + */ + + for (int k = 56; k >= 0; k -= 8) + { + for (int j = 1; j < aLen; j += 2) + { + int aVal = (int)((ulong)a[j] >> k); + int u = aVal & MASK; + int v = (int)((uint)aVal >> 4) & MASK; + AddBoth(c, j - 1, T0, ti[u], T1, ti[v], bMax); + } + ShiftUp(c, 0, cLen, 8); + } + + for (int k = 56; k >= 0; k -= 8) + { + for (int j = 0; j < aLen; j += 2) + { + int aVal = (int)((ulong)a[j] >> k); + int u = aVal & MASK; + int v = (int)((uint)aVal >> 4) & MASK; + AddBoth(c, j, T0, ti[u], T1, ti[v], bMax); + } + if (k > 0) + { + ShiftUp(c, 0, cLen, 8); + } + } + + /* + * Finally the raw answer is collected, reduce it against the reduction coefficients + */ + return ReduceResult(c, 0, cLen, m, ks); + } + + public LongArray ModMultiply(LongArray other, int m, int[] ks) + { + /* + * Find out the degree of each argument and handle the zero cases + */ + int aDeg = Degree(); + if (aDeg == 0) + { + return this; + } + int bDeg = other.Degree(); + if (bDeg == 0) + { + return other; + } + + /* + * Swap if necessary so that A is the smaller argument + */ + LongArray A = this, B = other; + if (aDeg > bDeg) + { + A = other; B = this; + int tmp = aDeg; aDeg = bDeg; bDeg = tmp; + } + + /* + * Establish the word lengths of the arguments and result + */ + int aLen = (int)((uint)(aDeg + 63) >> 6); + int bLen = (int)((uint)(bDeg + 63) >> 6); + int cLen = (int)((uint)(aDeg + bDeg + 62) >> 6); + + if (aLen == 1) + { + long a0 = A.m_ints[0]; + if (a0 == 1L) + { + return B; + } + + /* + * Fast path for small A, with performance dependent only on the number of set bits + */ + long[] c0 = new long[cLen]; + MultiplyWord(a0, B.m_ints, bLen, c0, 0); + + /* + * Reduce the raw answer against the reduction coefficients + */ + return ReduceResult(c0, 0, cLen, m, ks); + } + + /* + * Determine if B will get bigger during shifting + */ + int bMax = (int)((uint)(bDeg + 7 + 63) >> 6); + + /* + * Lookup table for the offset of each B in the tables + */ + int[] ti = new int[16]; + + /* + * Precompute table of all 4-bit products of B + */ + long[] T0 = new long[bMax << 4]; + int tOff = bMax; + ti[1] = tOff; + Array.Copy(B.m_ints, 0, T0, tOff, bLen); + for (int i = 2; i < 16; ++i) + { + ti[i] = (tOff += bMax); + if ((i & 1) == 0) + { + ShiftUp(T0, (int)((uint)tOff >> 1), T0, tOff, bMax, 1); + } + else + { + Add(T0, bMax, T0, tOff - bMax, T0, tOff, bMax); + } + } + + /* + * Second table with all 4-bit products of B shifted 4 bits + */ + long[] T1 = new long[T0.Length]; + ShiftUp(T0, 0, T1, 0, T0.Length, 4); + // ShiftUp(T0, bMax, T1, bMax, tOff, 4); + + long[] a = A.m_ints; + long[] c = new long[cLen << 3]; + + int MASK = 0xF; + + /* + * Lopez-Dahab (Modified) algorithm + */ + + for (int aPos = 0; aPos < aLen; ++aPos) + { + long aVal = a[aPos]; + int cOff = aPos; + for (;;) + { + int u = (int)aVal & MASK; + aVal = (long)((ulong)aVal >> 4); + int v = (int)aVal & MASK; + AddBoth(c, cOff, T0, ti[u], T1, ti[v], bMax); + aVal = (long)((ulong)aVal >> 4); + if (aVal == 0L) + { + break; + } + cOff += cLen; + } + } + + { + int cOff = c.Length; + while ((cOff -= cLen) != 0) + { + AddShiftedUp(c, cOff - cLen, c, cOff, cLen, 8); + } + } + + /* + * Finally the raw answer is collected, reduce it against the reduction coefficients + */ + return ReduceResult(c, 0, cLen, m, ks); + } + + public LongArray ModMultiplyAlt(LongArray other, int m, int[] ks) + { + /* + * Find out the degree of each argument and handle the zero cases + */ + int aDeg = Degree(); + if (aDeg == 0) + { + return this; + } + int bDeg = other.Degree(); + if (bDeg == 0) + { + return other; + } + + /* + * Swap if necessary so that A is the smaller argument + */ + LongArray A = this, B = other; + if (aDeg > bDeg) + { + A = other; B = this; + int tmp = aDeg; aDeg = bDeg; bDeg = tmp; + } + + /* + * Establish the word lengths of the arguments and result + */ + int aLen = (int)((uint)(aDeg + 63) >> 6); + int bLen = (int)((uint)(bDeg + 63) >> 6); + int cLen = (int)((uint)(aDeg + bDeg + 62) >> 6); + + if (aLen == 1) + { + long a0 = A.m_ints[0]; + if (a0 == 1L) + { + return B; + } + + /* + * Fast path for small A, with performance dependent only on the number of set bits + */ + long[] c0 = new long[cLen]; + MultiplyWord(a0, B.m_ints, bLen, c0, 0); + + /* + * Reduce the raw answer against the reduction coefficients + */ + return ReduceResult(c0, 0, cLen, m, ks); + } + + // NOTE: This works, but is slower than width 4 processing + // if (aLen == 2) + // { + // /* + // * Use common-multiplicand optimization to save ~1/4 of the adds + // */ + // long a1 = A.m_ints[0], a2 = A.m_ints[1]; + // long aa = a1 & a2; a1 ^= aa; a2 ^= aa; + // + // long[] b = B.m_ints; + // long[] c = new long[cLen]; + // multiplyWord(aa, b, bLen, c, 1); + // add(c, 0, c, 1, cLen - 1); + // multiplyWord(a1, b, bLen, c, 0); + // multiplyWord(a2, b, bLen, c, 1); + // + // /* + // * Reduce the raw answer against the reduction coefficients + // */ + // return ReduceResult(c, 0, cLen, m, ks); + // } + + /* + * Determine the parameters of the Interleaved window algorithm: the 'width' in bits to + * process together, the number of evaluation 'positions' implied by that width, and the + * 'top' position at which the regular window algorithm stops. + */ + int width, positions, top, banks; + + // NOTE: width 4 is the fastest over the entire range of sizes used in current crypto + // width = 1; positions = 64; top = 64; banks = 4; + // width = 2; positions = 32; top = 64; banks = 4; + // width = 3; positions = 21; top = 63; banks = 3; + width = 4; positions = 16; top = 64; banks = 8; + // width = 5; positions = 13; top = 65; banks = 7; + // width = 7; positions = 9; top = 63; banks = 9; + // width = 8; positions = 8; top = 64; banks = 8; + + /* + * Determine if B will get bigger during shifting + */ + int shifts = top < 64 ? positions : positions - 1; + int bMax = (int)((uint)(bDeg + shifts + 63) >> 6); + + int bTotal = bMax * banks, stride = width * banks; + + /* + * Create a single temporary buffer, with an offset table to find the positions of things in it + */ + int[] ci = new int[1 << width]; + int cTotal = aLen; + { + ci[0] = cTotal; + cTotal += bTotal; + ci[1] = cTotal; + for (int i = 2; i < ci.Length; ++i) + { + cTotal += cLen; + ci[i] = cTotal; + } + cTotal += cLen; + } + // NOTE: Provide a safe dump for "high zeroes" since we are adding 'bMax' and not 'bLen' + ++cTotal; + + long[] c = new long[cTotal]; + + // Prepare A in Interleaved form, according to the chosen width + Interleave(A.m_ints, 0, c, 0, aLen, width); + + // Make a working copy of B, since we will be shifting it + { + int bOff = aLen; + Array.Copy(B.m_ints, 0, c, bOff, bLen); + for (int bank = 1; bank < banks; ++bank) + { + ShiftUp(c, aLen, c, bOff += bMax, bMax, bank); + } + } + + /* + * The main loop analyzes the Interleaved windows in A, and for each non-zero window + * a single word-array XOR is performed to a carefully selected slice of 'c'. The loop is + * breadth-first, checking the lowest window in each word, then looping again for the + * next higher window position. + */ + int MASK = (1 << width) - 1; + + int k = 0; + for (;;) + { + int aPos = 0; + do + { + long aVal = (long)((ulong)c[aPos] >> k); + int bank = 0, bOff = aLen; + for (;;) + { + int index = (int)(aVal) & MASK; + if (index != 0) + { + /* + * Add to a 'c' buffer based on the bit-pattern of 'index'. Since A is in + * Interleaved form, the bits represent the current B shifted by 0, 'positions', + * 'positions' * 2, ..., 'positions' * ('width' - 1) + */ + Add(c, aPos + ci[index], c, bOff, bMax); + } + if (++bank == banks) + { + break; + } + bOff += bMax; + aVal = (long)((ulong)aVal >> width); + } + } + while (++aPos < aLen); + + if ((k += stride) >= top) + { + if (k >= 64) + { + break; + } + + /* + * Adjustment for window setups with top == 63, the final bit (if any) is processed + * as the top-bit of a window + */ + k = 64 - width; + MASK &= MASK << (top - k); + } + + /* + * After each position has been checked for all words of A, B is shifted up 1 place + */ + ShiftUp(c, aLen, bTotal, banks); + } + + int ciPos = ci.Length; + while (--ciPos > 1) + { + if ((ciPos & 1L) == 0L) + { + /* + * For even numbers, shift contents and add to the half-position + */ + AddShiftedUp(c, ci[(uint)ciPos >> 1], c, ci[ciPos], cLen, positions); + } + else + { + /* + * For odd numbers, 'distribute' contents to the result and the next-lowest position + */ + Distribute(c, ci[ciPos], ci[ciPos - 1], ci[1], cLen); + } + } + + /* + * Finally the raw answer is collected, reduce it against the reduction coefficients + */ + return ReduceResult(c, ci[1], cLen, m, ks); + } + + public LongArray ModReduce(int m, int[] ks) + { + long[] buf = Arrays.Clone(m_ints); + int rLen = ReduceInPlace(buf, 0, buf.Length, m, ks); + return new LongArray(buf, 0, rLen); + } + + public LongArray Multiply(LongArray other, int m, int[] ks) + { + /* + * Find out the degree of each argument and handle the zero cases + */ + int aDeg = Degree(); + if (aDeg == 0) + { + return this; + } + int bDeg = other.Degree(); + if (bDeg == 0) + { + return other; + } + + /* + * Swap if necessary so that A is the smaller argument + */ + LongArray A = this, B = other; + if (aDeg > bDeg) + { + A = other; B = this; + int tmp = aDeg; aDeg = bDeg; bDeg = tmp; + } + + /* + * Establish the word lengths of the arguments and result + */ + int aLen = (int)((uint)(aDeg + 63) >> 6); + int bLen = (int)((uint)(bDeg + 63) >> 6); + int cLen = (int)((uint)(aDeg + bDeg + 62) >> 6); + + if (aLen == 1) + { + long a0 = A.m_ints[0]; + if (a0 == 1L) + { + return B; + } + + /* + * Fast path for small A, with performance dependent only on the number of set bits + */ + long[] c0 = new long[cLen]; + MultiplyWord(a0, B.m_ints, bLen, c0, 0); + + /* + * Reduce the raw answer against the reduction coefficients + */ + //return ReduceResult(c0, 0, cLen, m, ks); + return new LongArray(c0, 0, cLen); + } + + /* + * Determine if B will get bigger during shifting + */ + int bMax = (int)((uint)(bDeg + 7 + 63) >> 6); + + /* + * Lookup table for the offset of each B in the tables + */ + int[] ti = new int[16]; + + /* + * Precompute table of all 4-bit products of B + */ + long[] T0 = new long[bMax << 4]; + int tOff = bMax; + ti[1] = tOff; + Array.Copy(B.m_ints, 0, T0, tOff, bLen); + for (int i = 2; i < 16; ++i) + { + ti[i] = (tOff += bMax); + if ((i & 1) == 0) + { + ShiftUp(T0, (int)((uint)tOff >> 1), T0, tOff, bMax, 1); + } + else + { + Add(T0, bMax, T0, tOff - bMax, T0, tOff, bMax); + } + } + + /* + * Second table with all 4-bit products of B shifted 4 bits + */ + long[] T1 = new long[T0.Length]; + ShiftUp(T0, 0, T1, 0, T0.Length, 4); + // ShiftUp(T0, bMax, T1, bMax, tOff, 4); + + long[] a = A.m_ints; + long[] c = new long[cLen << 3]; + + int MASK = 0xF; + + /* + * Lopez-Dahab (Modified) algorithm + */ + + for (int aPos = 0; aPos < aLen; ++aPos) + { + long aVal = a[aPos]; + int cOff = aPos; + for (; ; ) + { + int u = (int)aVal & MASK; + aVal = (long)((ulong)aVal >> 4); + int v = (int)aVal & MASK; + AddBoth(c, cOff, T0, ti[u], T1, ti[v], bMax); + aVal = (long)((ulong)aVal >> 4); + if (aVal == 0L) + { + break; + } + cOff += cLen; + } + } + + { + int cOff = c.Length; + while ((cOff -= cLen) != 0) + { + AddShiftedUp(c, cOff - cLen, c, cOff, cLen, 8); + } + } + + /* + * Finally the raw answer is collected, reduce it against the reduction coefficients + */ + //return ReduceResult(c, 0, cLen, m, ks); + return new LongArray(c, 0, cLen); + } + + public void Reduce(int m, int[] ks) + { + long[] buf = m_ints; + int rLen = ReduceInPlace(buf, 0, buf.Length, m, ks); + if (rLen < buf.Length) + { + m_ints = new long[rLen]; + Array.Copy(buf, 0, m_ints, 0, rLen); + } + } + + private static LongArray ReduceResult(long[] buf, int off, int len, int m, int[] ks) + { + int rLen = ReduceInPlace(buf, off, len, m, ks); + return new LongArray(buf, off, rLen); + } + + // private static void deInterleave(long[] x, int xOff, long[] z, int zOff, int count, int rounds) + // { + // for (int i = 0; i < count; ++i) + // { + // z[zOff + i] = deInterleave(x[zOff + i], rounds); + // } + // } + // + // private static long deInterleave(long x, int rounds) + // { + // while (--rounds >= 0) + // { + // x = deInterleave32(x & DEInterleave_MASK) | (deInterleave32((x >>> 1) & DEInterleave_MASK) << 32); + // } + // return x; + // } + // + // private static long deInterleave32(long x) + // { + // x = (x | (x >>> 1)) & 0x3333333333333333L; + // x = (x | (x >>> 2)) & 0x0F0F0F0F0F0F0F0FL; + // x = (x | (x >>> 4)) & 0x00FF00FF00FF00FFL; + // x = (x | (x >>> 8)) & 0x0000FFFF0000FFFFL; + // x = (x | (x >>> 16)) & 0x00000000FFFFFFFFL; + // return x; + // } + + private static int ReduceInPlace(long[] buf, int off, int len, int m, int[] ks) + { + int mLen = (m + 63) >> 6; + if (len < mLen) + { + return len; + } + + int numBits = System.Math.Min(len << 6, (m << 1) - 1); // TODO use actual degree? + int excessBits = (len << 6) - numBits; + while (excessBits >= 64) + { + --len; + excessBits -= 64; + } + + int kLen = ks.Length, kMax = ks[kLen - 1], kNext = kLen > 1 ? ks[kLen - 2] : 0; + int wordWiseLimit = System.Math.Max(m, kMax + 64); + int vectorableWords = (excessBits + System.Math.Min(numBits - wordWiseLimit, m - kNext)) >> 6; + if (vectorableWords > 1) + { + int vectorWiseWords = len - vectorableWords; + ReduceVectorWise(buf, off, len, vectorWiseWords, m, ks); + while (len > vectorWiseWords) + { + buf[off + --len] = 0L; + } + numBits = vectorWiseWords << 6; + } + + if (numBits > wordWiseLimit) + { + ReduceWordWise(buf, off, len, wordWiseLimit, m, ks); + numBits = wordWiseLimit; + } + + if (numBits > m) + { + ReduceBitWise(buf, off, numBits, m, ks); + } + + return mLen; + } + + private static void ReduceBitWise(long[] buf, int off, int BitLength, int m, int[] ks) + { + while (--BitLength >= m) + { + if (TestBit(buf, off, BitLength)) + { + ReduceBit(buf, off, BitLength, m, ks); + } + } + } + + private static void ReduceBit(long[] buf, int off, int bit, int m, int[] ks) + { + FlipBit(buf, off, bit); + int n = bit - m; + int j = ks.Length; + while (--j >= 0) + { + FlipBit(buf, off, ks[j] + n); + } + FlipBit(buf, off, n); + } + + private static void ReduceWordWise(long[] buf, int off, int len, int toBit, int m, int[] ks) + { + int toPos = (int)((uint)toBit >> 6); + + while (--len > toPos) + { + long word = buf[off + len]; + if (word != 0) + { + buf[off + len] = 0; + ReduceWord(buf, off, (len << 6), word, m, ks); + } + } + + { + int partial = toBit & 0x3F; + long word = (long)((ulong)buf[off + toPos] >> partial); + if (word != 0) + { + buf[off + toPos] ^= word << partial; + ReduceWord(buf, off, toBit, word, m, ks); + } + } + } + + private static void ReduceWord(long[] buf, int off, int bit, long word, int m, int[] ks) + { + int offset = bit - m; + int j = ks.Length; + while (--j >= 0) + { + FlipWord(buf, off, offset + ks[j], word); + } + FlipWord(buf, off, offset, word); + } + + private static void ReduceVectorWise(long[] buf, int off, int len, int words, int m, int[] ks) + { + /* + * NOTE: It's important we go from highest coefficient to lowest, because for the highest + * one (only) we allow the ranges to partially overlap, and therefore any changes must take + * effect for the subsequent lower coefficients. + */ + int baseBit = (words << 6) - m; + int j = ks.Length; + while (--j >= 0) + { + FlipVector(buf, off, buf, off + words, len - words, baseBit + ks[j]); + } + FlipVector(buf, off, buf, off + words, len - words, baseBit); + } + + private static void FlipVector(long[] x, int xOff, long[] y, int yOff, int yLen, int bits) + { + xOff += (int)((uint)bits >> 6); + bits &= 0x3F; + + if (bits == 0) + { + Add(x, xOff, y, yOff, yLen); + } + else + { + long carry = AddShiftedDown(x, xOff + 1, y, yOff, yLen, 64 - bits); + x[xOff] ^= carry; + } + } + + public LongArray ModSquare(int m, int[] ks) + { + int len = GetUsedLength(); + if (len == 0) + { + return this; + } + + int _2len = len << 1; + long[] r = new long[_2len]; + + int pos = 0; + while (pos < _2len) + { + long mi = m_ints[(uint)pos >> 1]; + r[pos++] = Interleave2_32to64((int)mi); + r[pos++] = Interleave2_32to64((int)((ulong)mi >> 32)); + } + + return new LongArray(r, 0, ReduceInPlace(r, 0, r.Length, m, ks)); + } + + public LongArray ModSquareN(int n, int m, int[] ks) + { + int len = GetUsedLength(); + if (len == 0) + { + return this; + } + + int mLen = (m + 63) >> 6; + long[] r = new long[mLen << 1]; + Array.Copy(m_ints, 0, r, 0, len); + + while (--n >= 0) + { + SquareInPlace(r, len, m, ks); + len = ReduceInPlace(r, 0, r.Length, m, ks); + } + + return new LongArray(r, 0, len); + } + + public LongArray Square(int m, int[] ks) + { + int len = GetUsedLength(); + if (len == 0) + { + return this; + } + + int _2len = len << 1; + long[] r = new long[_2len]; + + int pos = 0; + while (pos < _2len) + { + long mi = m_ints[(uint)pos >> 1]; + r[pos++] = Interleave2_32to64((int)mi); + r[pos++] = Interleave2_32to64((int)((ulong)mi >> 32)); + } + + return new LongArray(r, 0, r.Length); + } + + private static void SquareInPlace(long[] x, int xLen, int m, int[] ks) + { + int pos = xLen << 1; + while (--xLen >= 0) + { + long xVal = x[xLen]; + x[--pos] = Interleave2_32to64((int)((ulong)xVal >> 32)); + x[--pos] = Interleave2_32to64((int)xVal); + } + } + + private static void Interleave(long[] x, int xOff, long[] z, int zOff, int count, int width) + { + switch (width) + { + case 3: + Interleave3(x, xOff, z, zOff, count); + break; + case 5: + Interleave5(x, xOff, z, zOff, count); + break; + case 7: + Interleave7(x, xOff, z, zOff, count); + break; + default: + Interleave2_n(x, xOff, z, zOff, count, BitLengths[width] - 1); + break; + } + } + + private static void Interleave3(long[] x, int xOff, long[] z, int zOff, int count) + { + for (int i = 0; i < count; ++i) + { + z[zOff + i] = Interleave3(x[xOff + i]); + } + } + + private static long Interleave3(long x) + { + long z = x & (1L << 63); + return z + | Interleave3_21to63((int)x & 0x1FFFFF) + | Interleave3_21to63((int)((ulong)x >> 21) & 0x1FFFFF) << 1 + | Interleave3_21to63((int)((ulong)x >> 42) & 0x1FFFFF) << 2; + + // int zPos = 0, wPos = 0, xPos = 0; + // for (;;) + // { + // z |= ((x >>> xPos) & 1L) << zPos; + // if (++zPos == 63) + // { + // String sz2 = Long.toBinaryString(z); + // return z; + // } + // if ((xPos += 21) >= 63) + // { + // xPos = ++wPos; + // } + // } + } + + private static long Interleave3_21to63(int x) + { + int r00 = INTERLEAVE3_TABLE[x & 0x7F]; + int r21 = INTERLEAVE3_TABLE[((uint)x >> 7) & 0x7F]; + int r42 = INTERLEAVE3_TABLE[(uint)x >> 14]; + return (r42 & 0xFFFFFFFFL) << 42 | (r21 & 0xFFFFFFFFL) << 21 | (r00 & 0xFFFFFFFFL); + } + + private static void Interleave5(long[] x, int xOff, long[] z, int zOff, int count) + { + for (int i = 0; i < count; ++i) + { + z[zOff + i] = Interleave5(x[xOff + i]); + } + } + + private static long Interleave5(long x) + { + return Interleave3_13to65((int)x & 0x1FFF) + | Interleave3_13to65((int)((ulong)x >> 13) & 0x1FFF) << 1 + | Interleave3_13to65((int)((ulong)x >> 26) & 0x1FFF) << 2 + | Interleave3_13to65((int)((ulong)x >> 39) & 0x1FFF) << 3 + | Interleave3_13to65((int)((ulong)x >> 52) & 0x1FFF) << 4; + + // long z = 0; + // int zPos = 0, wPos = 0, xPos = 0; + // for (;;) + // { + // z |= ((x >>> xPos) & 1L) << zPos; + // if (++zPos == 64) + // { + // return z; + // } + // if ((xPos += 13) >= 64) + // { + // xPos = ++wPos; + // } + // } + } + + private static long Interleave3_13to65(int x) + { + int r00 = INTERLEAVE5_TABLE[x & 0x7F]; + int r35 = INTERLEAVE5_TABLE[(uint)x >> 7]; + return (r35 & 0xFFFFFFFFL) << 35 | (r00 & 0xFFFFFFFFL); + } + + private static void Interleave7(long[] x, int xOff, long[] z, int zOff, int count) + { + for (int i = 0; i < count; ++i) + { + z[zOff + i] = Interleave7(x[xOff + i]); + } + } + + private static long Interleave7(long x) + { + long z = x & (1L << 63); + return z + | INTERLEAVE7_TABLE[(int)x & 0x1FF] + | INTERLEAVE7_TABLE[(int)((ulong)x >> 9) & 0x1FF] << 1 + | INTERLEAVE7_TABLE[(int)((ulong)x >> 18) & 0x1FF] << 2 + | INTERLEAVE7_TABLE[(int)((ulong)x >> 27) & 0x1FF] << 3 + | INTERLEAVE7_TABLE[(int)((ulong)x >> 36) & 0x1FF] << 4 + | INTERLEAVE7_TABLE[(int)((ulong)x >> 45) & 0x1FF] << 5 + | INTERLEAVE7_TABLE[(int)((ulong)x >> 54) & 0x1FF] << 6; + + // int zPos = 0, wPos = 0, xPos = 0; + // for (;;) + // { + // z |= ((x >>> xPos) & 1L) << zPos; + // if (++zPos == 63) + // { + // return z; + // } + // if ((xPos += 9) >= 63) + // { + // xPos = ++wPos; + // } + // } + } + + private static void Interleave2_n(long[] x, int xOff, long[] z, int zOff, int count, int rounds) + { + for (int i = 0; i < count; ++i) + { + z[zOff + i] = Interleave2_n(x[xOff + i], rounds); + } + } + + private static long Interleave2_n(long x, int rounds) + { + while (rounds > 1) + { + rounds -= 2; + x = Interleave4_16to64((int)x & 0xFFFF) + | Interleave4_16to64((int)((ulong)x >> 16) & 0xFFFF) << 1 + | Interleave4_16to64((int)((ulong)x >> 32) & 0xFFFF) << 2 + | Interleave4_16to64((int)((ulong)x >> 48) & 0xFFFF) << 3; + } + if (rounds > 0) + { + x = Interleave2_32to64((int)x) | Interleave2_32to64((int)((ulong)x >> 32)) << 1; + } + return x; + } + + private static long Interleave4_16to64(int x) + { + int r00 = INTERLEAVE4_TABLE[x & 0xFF]; + int r32 = INTERLEAVE4_TABLE[(uint)x >> 8]; + return (r32 & 0xFFFFFFFFL) << 32 | (r00 & 0xFFFFFFFFL); + } + + private static long Interleave2_32to64(int x) + { + int r00 = INTERLEAVE2_TABLE[x & 0xFF] | INTERLEAVE2_TABLE[((uint)x >> 8) & 0xFF] << 16; + int r32 = INTERLEAVE2_TABLE[((uint)x >> 16) & 0xFF] | INTERLEAVE2_TABLE[(uint)x >> 24] << 16; + return (r32 & 0xFFFFFFFFL) << 32 | (r00 & 0xFFFFFFFFL); + } + + // private static LongArray ExpItohTsujii2(LongArray B, int n, int m, int[] ks) + // { + // LongArray t1 = B, t3 = new LongArray(new long[]{ 1L }); + // int scale = 1; + // + // int numTerms = n; + // while (numTerms > 1) + // { + // if ((numTerms & 1) != 0) + // { + // t3 = t3.ModMultiply(t1, m, ks); + // t1 = t1.modSquareN(scale, m, ks); + // } + // + // LongArray t2 = t1.modSquareN(scale, m, ks); + // t1 = t1.ModMultiply(t2, m, ks); + // numTerms >>>= 1; scale <<= 1; + // } + // + // return t3.ModMultiply(t1, m, ks); + // } + // + // private static LongArray ExpItohTsujii23(LongArray B, int n, int m, int[] ks) + // { + // LongArray t1 = B, t3 = new LongArray(new long[]{ 1L }); + // int scale = 1; + // + // int numTerms = n; + // while (numTerms > 1) + // { + // bool m03 = numTerms % 3 == 0; + // bool m14 = !m03 && (numTerms & 1) != 0; + // + // if (m14) + // { + // t3 = t3.ModMultiply(t1, m, ks); + // t1 = t1.modSquareN(scale, m, ks); + // } + // + // LongArray t2 = t1.modSquareN(scale, m, ks); + // t1 = t1.ModMultiply(t2, m, ks); + // + // if (m03) + // { + // t2 = t2.modSquareN(scale, m, ks); + // t1 = t1.ModMultiply(t2, m, ks); + // numTerms /= 3; scale *= 3; + // } + // else + // { + // numTerms >>>= 1; scale <<= 1; + // } + // } + // + // return t3.ModMultiply(t1, m, ks); + // } + // + // private static LongArray ExpItohTsujii235(LongArray B, int n, int m, int[] ks) + // { + // LongArray t1 = B, t4 = new LongArray(new long[]{ 1L }); + // int scale = 1; + // + // int numTerms = n; + // while (numTerms > 1) + // { + // if (numTerms % 5 == 0) + // { + //// t1 = ExpItohTsujii23(t1, 5, m, ks); + // + // LongArray t3 = t1; + // t1 = t1.modSquareN(scale, m, ks); + // + // LongArray t2 = t1.modSquareN(scale, m, ks); + // t1 = t1.ModMultiply(t2, m, ks); + // t2 = t1.modSquareN(scale << 1, m, ks); + // t1 = t1.ModMultiply(t2, m, ks); + // + // t1 = t1.ModMultiply(t3, m, ks); + // + // numTerms /= 5; scale *= 5; + // continue; + // } + // + // bool m03 = numTerms % 3 == 0; + // bool m14 = !m03 && (numTerms & 1) != 0; + // + // if (m14) + // { + // t4 = t4.ModMultiply(t1, m, ks); + // t1 = t1.modSquareN(scale, m, ks); + // } + // + // LongArray t2 = t1.modSquareN(scale, m, ks); + // t1 = t1.ModMultiply(t2, m, ks); + // + // if (m03) + // { + // t2 = t2.modSquareN(scale, m, ks); + // t1 = t1.ModMultiply(t2, m, ks); + // numTerms /= 3; scale *= 3; + // } + // else + // { + // numTerms >>>= 1; scale <<= 1; + // } + // } + // + // return t4.ModMultiply(t1, m, ks); + // } + + public LongArray ModInverse(int m, int[] ks) + { + /* + * Fermat's Little Theorem + */ + // LongArray A = this; + // LongArray B = A.modSquare(m, ks); + // LongArray R0 = B, R1 = B; + // for (int i = 2; i < m; ++i) + // { + // R1 = R1.modSquare(m, ks); + // R0 = R0.ModMultiply(R1, m, ks); + // } + // + // return R0; + + /* + * Itoh-Tsujii + */ + // LongArray B = modSquare(m, ks); + // switch (m) + // { + // case 409: + // return ExpItohTsujii23(B, m - 1, m, ks); + // case 571: + // return ExpItohTsujii235(B, m - 1, m, ks); + // case 163: + // case 233: + // case 283: + // default: + // return ExpItohTsujii2(B, m - 1, m, ks); + // } + + /* + * Inversion in F2m using the extended Euclidean algorithm + * + * Input: A nonzero polynomial a(z) of degree at most m-1 + * Output: a(z)^(-1) mod f(z) + */ + int uzDegree = Degree(); + if (uzDegree == 0) + { + throw new InvalidOperationException(); + } + if (uzDegree == 1) + { + return this; + } + + // u(z) := a(z) + LongArray uz = (LongArray)Copy(); + + int t = (m + 63) >> 6; + + // v(z) := f(z) + LongArray vz = new LongArray(t); + ReduceBit(vz.m_ints, 0, m, m, ks); + + // g1(z) := 1, g2(z) := 0 + LongArray g1z = new LongArray(t); + g1z.m_ints[0] = 1L; + LongArray g2z = new LongArray(t); + + int[] uvDeg = new int[]{ uzDegree, m + 1 }; + LongArray[] uv = new LongArray[]{ uz, vz }; + + int[] ggDeg = new int[]{ 1, 0 }; + LongArray[] gg = new LongArray[]{ g1z, g2z }; + + int b = 1; + int duv1 = uvDeg[b]; + int dgg1 = ggDeg[b]; + int j = duv1 - uvDeg[1 - b]; + + for (;;) + { + if (j < 0) + { + j = -j; + uvDeg[b] = duv1; + ggDeg[b] = dgg1; + b = 1 - b; + duv1 = uvDeg[b]; + dgg1 = ggDeg[b]; + } + + uv[b].AddShiftedByBitsSafe(uv[1 - b], uvDeg[1 - b], j); + + int duv2 = uv[b].DegreeFrom(duv1); + if (duv2 == 0) + { + return gg[1 - b]; + } + + { + int dgg2 = ggDeg[1 - b]; + gg[b].AddShiftedByBitsSafe(gg[1 - b], dgg2, j); + dgg2 += j; + + if (dgg2 > dgg1) + { + dgg1 = dgg2; + } + else if (dgg2 == dgg1) + { + dgg1 = gg[b].DegreeFrom(dgg1); + } + } + + j += (duv2 - duv1); + duv1 = duv2; + } + } + + public override bool Equals(object obj) + { + return Equals(obj as LongArray); + } + + public virtual bool Equals(LongArray other) + { + if (this == other) + return true; + if (null == other) + return false; + int usedLen = GetUsedLength(); + if (other.GetUsedLength() != usedLen) + { + return false; + } + for (int i = 0; i < usedLen; i++) + { + if (m_ints[i] != other.m_ints[i]) + { + return false; + } + } + return true; + } + + public override int GetHashCode() + { + int usedLen = GetUsedLength(); + int hash = 1; + for (int i = 0; i < usedLen; i++) + { + long mi = m_ints[i]; + hash *= 31; + hash ^= (int)mi; + hash *= 31; + hash ^= (int)((ulong)mi >> 32); + } + return hash; + } + + public LongArray Copy() + { + return new LongArray(Arrays.Clone(m_ints)); + } + + public override string ToString() + { + int i = GetUsedLength(); + if (i == 0) + { + return "0"; + } + + StringBuilder sb = new StringBuilder(Convert.ToString(m_ints[--i], 2)); + while (--i >= 0) + { + string s = Convert.ToString(m_ints[i], 2); + + // Add leading zeroes, except for highest significant word + int len = s.Length; + if (len < 64) + { + sb.Append(ZEROES.Substring(len)); + } + + sb.Append(s); + } + return sb.ToString(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/LongArray.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/LongArray.cs.meta new file mode 100644 index 0000000..8d42b23 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/LongArray.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e83e7f543f81c72429f3bb791053292e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ScaleXNegateYPointMap.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ScaleXNegateYPointMap.cs new file mode 100644 index 0000000..b0466a6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ScaleXNegateYPointMap.cs @@ -0,0 +1,20 @@ +using System; + +namespace Org.BouncyCastle.Math.EC +{ + public class ScaleXNegateYPointMap + : ECPointMap + { + protected readonly ECFieldElement scale; + + public ScaleXNegateYPointMap(ECFieldElement scale) + { + this.scale = scale; + } + + public virtual ECPoint Map(ECPoint p) + { + return p.ScaleXNegateY(scale); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ScaleXNegateYPointMap.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ScaleXNegateYPointMap.cs.meta new file mode 100644 index 0000000..0b2d270 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ScaleXNegateYPointMap.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ac248893ede2b4b4d90e647ad0c68e02 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ScaleXPointMap.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ScaleXPointMap.cs new file mode 100644 index 0000000..f8a363b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ScaleXPointMap.cs @@ -0,0 +1,20 @@ +using System; + +namespace Org.BouncyCastle.Math.EC +{ + public class ScaleXPointMap + : ECPointMap + { + protected readonly ECFieldElement scale; + + public ScaleXPointMap(ECFieldElement scale) + { + this.scale = scale; + } + + public virtual ECPoint Map(ECPoint p) + { + return p.ScaleX(scale); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ScaleXPointMap.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ScaleXPointMap.cs.meta new file mode 100644 index 0000000..bca3d1f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ScaleXPointMap.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4382205a628064646b1aab78aeb58b07 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ScaleYNegateXPointMap.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ScaleYNegateXPointMap.cs new file mode 100644 index 0000000..6a7fed1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ScaleYNegateXPointMap.cs @@ -0,0 +1,20 @@ +using System; + +namespace Org.BouncyCastle.Math.EC +{ + public class ScaleYNegateXPointMap + : ECPointMap + { + protected readonly ECFieldElement scale; + + public ScaleYNegateXPointMap(ECFieldElement scale) + { + this.scale = scale; + } + + public virtual ECPoint Map(ECPoint p) + { + return p.ScaleYNegateX(scale); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ScaleYNegateXPointMap.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ScaleYNegateXPointMap.cs.meta new file mode 100644 index 0000000..f495914 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ScaleYNegateXPointMap.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e9933796ef9a4624baa3b78f33061b00 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ScaleYPointMap.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ScaleYPointMap.cs new file mode 100644 index 0000000..1c4795b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ScaleYPointMap.cs @@ -0,0 +1,20 @@ +using System; + +namespace Org.BouncyCastle.Math.EC +{ + public class ScaleYPointMap + : ECPointMap + { + protected readonly ECFieldElement scale; + + public ScaleYPointMap(ECFieldElement scale) + { + this.scale = scale; + } + + public virtual ECPoint Map(ECPoint p) + { + return p.ScaleY(scale); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ScaleYPointMap.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ScaleYPointMap.cs.meta new file mode 100644 index 0000000..fc89f05 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/ScaleYPointMap.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3f315909fcd307a4bb6ffc50d426f502 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/SimpleLookupTable.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/SimpleLookupTable.cs new file mode 100644 index 0000000..ed300ba --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/SimpleLookupTable.cs @@ -0,0 +1,40 @@ +using System; + +namespace Org.BouncyCastle.Math.EC +{ + public class SimpleLookupTable + : AbstractECLookupTable + { + private static ECPoint[] Copy(ECPoint[] points, int off, int len) + { + ECPoint[] result = new ECPoint[len]; + for (int i = 0; i < len; ++i) + { + result[i] = points[off + i]; + } + return result; + } + + private readonly ECPoint[] points; + + public SimpleLookupTable(ECPoint[] points, int off, int len) + { + this.points = Copy(points, off, len); + } + + public override int Size + { + get { return points.Length; } + } + + public override ECPoint Lookup(int index) + { + throw new NotSupportedException("Constant-time lookup not supported"); + } + + public override ECPoint LookupVar(int index) + { + return points[index]; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/SimpleLookupTable.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/SimpleLookupTable.cs.meta new file mode 100644 index 0000000..adeaa4c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/SimpleLookupTable.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: af98b3ce535c5e8449b902d049ace419 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/abc.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/abc.meta new file mode 100644 index 0000000..9d87102 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/abc.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f894b70272e71a54ba1f99e2a88aa82d +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/abc/SimpleBigDecimal.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/abc/SimpleBigDecimal.cs new file mode 100644 index 0000000..d5664db --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/abc/SimpleBigDecimal.cs @@ -0,0 +1,241 @@ +using System; +using System.Text; + +namespace Org.BouncyCastle.Math.EC.Abc +{ + /** + * Class representing a simple version of a big decimal. A + * SimpleBigDecimal is basically a + * {@link java.math.BigInteger BigInteger} with a few digits on the right of + * the decimal point. The number of (binary) digits on the right of the decimal + * point is called the scale of the SimpleBigDecimal. + * Unlike in {@link java.math.BigDecimal BigDecimal}, the scale is not adjusted + * automatically, but must be set manually. All SimpleBigDecimals + * taking part in the same arithmetic operation must have equal scale. The + * result of a multiplication of two SimpleBigDecimals returns a + * SimpleBigDecimal with double scale. + */ + internal class SimpleBigDecimal + // : Number + { + // private static final long serialVersionUID = 1L; + + private readonly BigInteger bigInt; + private readonly int scale; + + /** + * Returns a SimpleBigDecimal representing the same numerical + * value as value. + * @param value The value of the SimpleBigDecimal to be + * created. + * @param scale The scale of the SimpleBigDecimal to be + * created. + * @return The such created SimpleBigDecimal. + */ + public static SimpleBigDecimal GetInstance(BigInteger val, int scale) + { + return new SimpleBigDecimal(val.ShiftLeft(scale), scale); + } + + /** + * Constructor for SimpleBigDecimal. The value of the + * constructed SimpleBigDecimal Equals bigInt / + * 2scale. + * @param bigInt The bigInt value parameter. + * @param scale The scale of the constructed SimpleBigDecimal. + */ + public SimpleBigDecimal(BigInteger bigInt, int scale) + { + if (scale < 0) + throw new ArgumentException("scale may not be negative"); + + this.bigInt = bigInt; + this.scale = scale; + } + + private SimpleBigDecimal(SimpleBigDecimal limBigDec) + { + bigInt = limBigDec.bigInt; + scale = limBigDec.scale; + } + + private void CheckScale(SimpleBigDecimal b) + { + if (scale != b.scale) + throw new ArgumentException("Only SimpleBigDecimal of same scale allowed in arithmetic operations"); + } + + public SimpleBigDecimal AdjustScale(int newScale) + { + if (newScale < 0) + throw new ArgumentException("scale may not be negative"); + + if (newScale == scale) + return this; + + return new SimpleBigDecimal(bigInt.ShiftLeft(newScale - scale), newScale); + } + + public SimpleBigDecimal Add(SimpleBigDecimal b) + { + CheckScale(b); + return new SimpleBigDecimal(bigInt.Add(b.bigInt), scale); + } + + public SimpleBigDecimal Add(BigInteger b) + { + return new SimpleBigDecimal(bigInt.Add(b.ShiftLeft(scale)), scale); + } + + public SimpleBigDecimal Negate() + { + return new SimpleBigDecimal(bigInt.Negate(), scale); + } + + public SimpleBigDecimal Subtract(SimpleBigDecimal b) + { + return Add(b.Negate()); + } + + public SimpleBigDecimal Subtract(BigInteger b) + { + return new SimpleBigDecimal(bigInt.Subtract(b.ShiftLeft(scale)), scale); + } + + public SimpleBigDecimal Multiply(SimpleBigDecimal b) + { + CheckScale(b); + return new SimpleBigDecimal(bigInt.Multiply(b.bigInt), scale + scale); + } + + public SimpleBigDecimal Multiply(BigInteger b) + { + return new SimpleBigDecimal(bigInt.Multiply(b), scale); + } + + public SimpleBigDecimal Divide(SimpleBigDecimal b) + { + CheckScale(b); + BigInteger dividend = bigInt.ShiftLeft(scale); + return new SimpleBigDecimal(dividend.Divide(b.bigInt), scale); + } + + public SimpleBigDecimal Divide(BigInteger b) + { + return new SimpleBigDecimal(bigInt.Divide(b), scale); + } + + public SimpleBigDecimal ShiftLeft(int n) + { + return new SimpleBigDecimal(bigInt.ShiftLeft(n), scale); + } + + public int CompareTo(SimpleBigDecimal val) + { + CheckScale(val); + return bigInt.CompareTo(val.bigInt); + } + + public int CompareTo(BigInteger val) + { + return bigInt.CompareTo(val.ShiftLeft(scale)); + } + + public BigInteger Floor() + { + return bigInt.ShiftRight(scale); + } + + public BigInteger Round() + { + SimpleBigDecimal oneHalf = new SimpleBigDecimal(BigInteger.One, 1); + return Add(oneHalf.AdjustScale(scale)).Floor(); + } + + public int IntValue + { + get { return Floor().IntValue; } + } + + public long LongValue + { + get { return Floor().LongValue; } + } + +// public double doubleValue() +// { +// return new Double(ToString()).doubleValue(); +// } +// +// public float floatValue() +// { +// return new Float(ToString()).floatValue(); +// } + + public int Scale + { + get { return scale; } + } + + public override string ToString() + { + if (scale == 0) + return bigInt.ToString(); + + BigInteger floorBigInt = Floor(); + + BigInteger fract = bigInt.Subtract(floorBigInt.ShiftLeft(scale)); + if (bigInt.SignValue < 0) + { + fract = BigInteger.One.ShiftLeft(scale).Subtract(fract); + } + + if ((floorBigInt.SignValue == -1) && (!(fract.Equals(BigInteger.Zero)))) + { + floorBigInt = floorBigInt.Add(BigInteger.One); + } + string leftOfPoint = floorBigInt.ToString(); + + char[] fractCharArr = new char[scale]; + string fractStr = fract.ToString(2); + int fractLen = fractStr.Length; + int zeroes = scale - fractLen; + for (int i = 0; i < zeroes; i++) + { + fractCharArr[i] = '0'; + } + for (int j = 0; j < fractLen; j++) + { + fractCharArr[zeroes + j] = fractStr[j]; + } + string rightOfPoint = new string(fractCharArr); + + StringBuilder sb = new StringBuilder(leftOfPoint); + sb.Append("."); + sb.Append(rightOfPoint); + + return sb.ToString(); + } + + public override bool Equals( + object obj) + { + if (this == obj) + return true; + + SimpleBigDecimal other = obj as SimpleBigDecimal; + + if (other == null) + return false; + + return bigInt.Equals(other.bigInt) + && scale == other.scale; + } + + public override int GetHashCode() + { + return bigInt.GetHashCode() ^ scale; + } + + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/abc/SimpleBigDecimal.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/abc/SimpleBigDecimal.cs.meta new file mode 100644 index 0000000..2b12c53 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/abc/SimpleBigDecimal.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 75c190cfa9734b54384fc8e88599d4f0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/abc/Tnaf.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/abc/Tnaf.cs new file mode 100644 index 0000000..b6e792a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/abc/Tnaf.cs @@ -0,0 +1,845 @@ +using System; + +namespace Org.BouncyCastle.Math.EC.Abc +{ + /** + * Class holding methods for point multiplication based on the window + * τ-adic nonadjacent form (WTNAF). The algorithms are based on the + * paper "Improved Algorithms for Arithmetic on Anomalous Binary Curves" + * by Jerome A. Solinas. The paper first appeared in the Proceedings of + * Crypto 1997. + */ + internal class Tnaf + { + private static readonly BigInteger MinusOne = BigInteger.One.Negate(); + private static readonly BigInteger MinusTwo = BigInteger.Two.Negate(); + private static readonly BigInteger MinusThree = BigInteger.Three.Negate(); + private static readonly BigInteger Four = BigInteger.ValueOf(4); + + /** + * The window width of WTNAF. The standard value of 4 is slightly less + * than optimal for running time, but keeps space requirements for + * precomputation low. For typical curves, a value of 5 or 6 results in + * a better running time. When changing this value, the + * αu's must be computed differently, see + * e.g. "Guide to Elliptic Curve Cryptography", Darrel Hankerson, + * Alfred Menezes, Scott Vanstone, Springer-Verlag New York Inc., 2004, + * p. 121-122 + */ + public const sbyte Width = 4; + + /** + * 24 + */ + public const sbyte Pow2Width = 16; + + /** + * The αu's for a=0 as an array + * of ZTauElements. + */ + public static readonly ZTauElement[] Alpha0 = + { + null, + new ZTauElement(BigInteger.One, BigInteger.Zero), null, + new ZTauElement(MinusThree, MinusOne), null, + new ZTauElement(MinusOne, MinusOne), null, + new ZTauElement(BigInteger.One, MinusOne), null + }; + + /** + * The αu's for a=0 as an array + * of TNAFs. + */ + public static readonly sbyte[][] Alpha0Tnaf = + { + null, new sbyte[]{1}, null, new sbyte[]{-1, 0, 1}, null, new sbyte[]{1, 0, 1}, null, new sbyte[]{-1, 0, 0, 1} + }; + + /** + * The αu's for a=1 as an array + * of ZTauElements. + */ + public static readonly ZTauElement[] Alpha1 = + { + null, + new ZTauElement(BigInteger.One, BigInteger.Zero), null, + new ZTauElement(MinusThree, BigInteger.One), null, + new ZTauElement(MinusOne, BigInteger.One), null, + new ZTauElement(BigInteger.One, BigInteger.One), null + }; + + /** + * The αu's for a=1 as an array + * of TNAFs. + */ + public static readonly sbyte[][] Alpha1Tnaf = + { + null, new sbyte[]{1}, null, new sbyte[]{-1, 0, 1}, null, new sbyte[]{1, 0, 1}, null, new sbyte[]{-1, 0, 0, -1} + }; + + /** + * Computes the norm of an element λ of + * Z[τ]. + * @param mu The parameter μ of the elliptic curve. + * @param lambda The element λ of + * Z[τ]. + * @return The norm of λ. + */ + public static BigInteger Norm(sbyte mu, ZTauElement lambda) + { + BigInteger norm; + + // s1 = u^2 + BigInteger s1 = lambda.u.Multiply(lambda.u); + + // s2 = u * v + BigInteger s2 = lambda.u.Multiply(lambda.v); + + // s3 = 2 * v^2 + BigInteger s3 = lambda.v.Multiply(lambda.v).ShiftLeft(1); + + if (mu == 1) + { + norm = s1.Add(s2).Add(s3); + } + else if (mu == -1) + { + norm = s1.Subtract(s2).Add(s3); + } + else + { + throw new ArgumentException("mu must be 1 or -1"); + } + + return norm; + } + + /** + * Computes the norm of an element λ of + * R[τ], where λ = u + vτ + * and u and u are real numbers (elements of + * R). + * @param mu The parameter μ of the elliptic curve. + * @param u The real part of the element λ of + * R[τ]. + * @param v The τ-adic part of the element + * λ of R[τ]. + * @return The norm of λ. + */ + public static SimpleBigDecimal Norm(sbyte mu, SimpleBigDecimal u, SimpleBigDecimal v) + { + SimpleBigDecimal norm; + + // s1 = u^2 + SimpleBigDecimal s1 = u.Multiply(u); + + // s2 = u * v + SimpleBigDecimal s2 = u.Multiply(v); + + // s3 = 2 * v^2 + SimpleBigDecimal s3 = v.Multiply(v).ShiftLeft(1); + + if (mu == 1) + { + norm = s1.Add(s2).Add(s3); + } + else if (mu == -1) + { + norm = s1.Subtract(s2).Add(s3); + } + else + { + throw new ArgumentException("mu must be 1 or -1"); + } + + return norm; + } + + /** + * Rounds an element λ of R[τ] + * to an element of Z[τ], such that their difference + * has minimal norm. λ is given as + * λ = λ0 + λ1τ. + * @param lambda0 The component λ0. + * @param lambda1 The component λ1. + * @param mu The parameter μ of the elliptic curve. Must + * equal 1 or -1. + * @return The rounded element of Z[τ]. + * @throws ArgumentException if lambda0 and + * lambda1 do not have same scale. + */ + public static ZTauElement Round(SimpleBigDecimal lambda0, + SimpleBigDecimal lambda1, sbyte mu) + { + int scale = lambda0.Scale; + if (lambda1.Scale != scale) + throw new ArgumentException("lambda0 and lambda1 do not have same scale"); + + if (!((mu == 1) || (mu == -1))) + throw new ArgumentException("mu must be 1 or -1"); + + BigInteger f0 = lambda0.Round(); + BigInteger f1 = lambda1.Round(); + + SimpleBigDecimal eta0 = lambda0.Subtract(f0); + SimpleBigDecimal eta1 = lambda1.Subtract(f1); + + // eta = 2*eta0 + mu*eta1 + SimpleBigDecimal eta = eta0.Add(eta0); + if (mu == 1) + { + eta = eta.Add(eta1); + } + else + { + // mu == -1 + eta = eta.Subtract(eta1); + } + + // check1 = eta0 - 3*mu*eta1 + // check2 = eta0 + 4*mu*eta1 + SimpleBigDecimal threeEta1 = eta1.Add(eta1).Add(eta1); + SimpleBigDecimal fourEta1 = threeEta1.Add(eta1); + SimpleBigDecimal check1; + SimpleBigDecimal check2; + if (mu == 1) + { + check1 = eta0.Subtract(threeEta1); + check2 = eta0.Add(fourEta1); + } + else + { + // mu == -1 + check1 = eta0.Add(threeEta1); + check2 = eta0.Subtract(fourEta1); + } + + sbyte h0 = 0; + sbyte h1 = 0; + + // if eta >= 1 + if (eta.CompareTo(BigInteger.One) >= 0) + { + if (check1.CompareTo(MinusOne) < 0) + { + h1 = mu; + } + else + { + h0 = 1; + } + } + else + { + // eta < 1 + if (check2.CompareTo(BigInteger.Two) >= 0) + { + h1 = mu; + } + } + + // if eta < -1 + if (eta.CompareTo(MinusOne) < 0) + { + if (check1.CompareTo(BigInteger.One) >= 0) + { + h1 = (sbyte)-mu; + } + else + { + h0 = -1; + } + } + else + { + // eta >= -1 + if (check2.CompareTo(MinusTwo) < 0) + { + h1 = (sbyte)-mu; + } + } + + BigInteger q0 = f0.Add(BigInteger.ValueOf(h0)); + BigInteger q1 = f1.Add(BigInteger.ValueOf(h1)); + return new ZTauElement(q0, q1); + } + + /** + * Approximate division by n. For an integer + * k, the value λ = s k / n is + * computed to c bits of accuracy. + * @param k The parameter k. + * @param s The curve parameter s0 or + * s1. + * @param vm The Lucas Sequence element Vm. + * @param a The parameter a of the elliptic curve. + * @param m The bit length of the finite field + * Fm. + * @param c The number of bits of accuracy, i.e. the scale of the returned + * SimpleBigDecimal. + * @return The value λ = s k / n computed to + * c bits of accuracy. + */ + public static SimpleBigDecimal ApproximateDivisionByN(BigInteger k, + BigInteger s, BigInteger vm, sbyte a, int m, int c) + { + int _k = (m + 5)/2 + c; + BigInteger ns = k.ShiftRight(m - _k - 2 + a); + + BigInteger gs = s.Multiply(ns); + + BigInteger hs = gs.ShiftRight(m); + + BigInteger js = vm.Multiply(hs); + + BigInteger gsPlusJs = gs.Add(js); + BigInteger ls = gsPlusJs.ShiftRight(_k-c); + if (gsPlusJs.TestBit(_k-c-1)) + { + // round up + ls = ls.Add(BigInteger.One); + } + + return new SimpleBigDecimal(ls, c); + } + + /** + * Computes the τ-adic NAF (non-adjacent form) of an + * element λ of Z[τ]. + * @param mu The parameter μ of the elliptic curve. + * @param lambda The element λ of + * Z[τ]. + * @return The τ-adic NAF of λ. + */ + public static sbyte[] TauAdicNaf(sbyte mu, ZTauElement lambda) + { + if (!((mu == 1) || (mu == -1))) + throw new ArgumentException("mu must be 1 or -1"); + + BigInteger norm = Norm(mu, lambda); + + // Ceiling of log2 of the norm + int log2Norm = norm.BitLength; + + // If length(TNAF) > 30, then length(TNAF) < log2Norm + 3.52 + int maxLength = log2Norm > 30 ? log2Norm + 4 : 34; + + // The array holding the TNAF + sbyte[] u = new sbyte[maxLength]; + int i = 0; + + // The actual length of the TNAF + int length = 0; + + BigInteger r0 = lambda.u; + BigInteger r1 = lambda.v; + + while(!((r0.Equals(BigInteger.Zero)) && (r1.Equals(BigInteger.Zero)))) + { + // If r0 is odd + if (r0.TestBit(0)) + { + u[i] = (sbyte) BigInteger.Two.Subtract((r0.Subtract(r1.ShiftLeft(1))).Mod(Four)).IntValue; + + // r0 = r0 - u[i] + if (u[i] == 1) + { + r0 = r0.ClearBit(0); + } + else + { + // u[i] == -1 + r0 = r0.Add(BigInteger.One); + } + length = i; + } + else + { + u[i] = 0; + } + + BigInteger t = r0; + BigInteger s = r0.ShiftRight(1); + if (mu == 1) + { + r0 = r1.Add(s); + } + else + { + // mu == -1 + r0 = r1.Subtract(s); + } + + r1 = t.ShiftRight(1).Negate(); + i++; + } + + length++; + + // Reduce the TNAF array to its actual length + sbyte[] tnaf = new sbyte[length]; + Array.Copy(u, 0, tnaf, 0, length); + return tnaf; + } + + /** + * Applies the operation τ() to an + * AbstractF2mPoint. + * @param p The AbstractF2mPoint to which τ() is applied. + * @return τ(p) + */ + public static AbstractF2mPoint Tau(AbstractF2mPoint p) + { + return p.Tau(); + } + + /** + * Returns the parameter μ of the elliptic curve. + * @param curve The elliptic curve from which to obtain μ. + * The curve must be a Koblitz curve, i.e. a Equals + * 0 or 1 and b Equals + * 1. + * @return μ of the elliptic curve. + * @throws ArgumentException if the given ECCurve is not a Koblitz + * curve. + */ + public static sbyte GetMu(AbstractF2mCurve curve) + { + BigInteger a = curve.A.ToBigInteger(); + + sbyte mu; + if (a.SignValue == 0) + { + mu = -1; + } + else if (a.Equals(BigInteger.One)) + { + mu = 1; + } + else + { + throw new ArgumentException("No Koblitz curve (ABC), TNAF multiplication not possible"); + } + return mu; + } + + public static sbyte GetMu(ECFieldElement curveA) + { + return (sbyte)(curveA.IsZero ? -1 : 1); + } + + public static sbyte GetMu(int curveA) + { + return (sbyte)(curveA == 0 ? -1 : 1); + } + + /** + * Calculates the Lucas Sequence elements Uk-1 and + * Uk or Vk-1 and + * Vk. + * @param mu The parameter μ of the elliptic curve. + * @param k The index of the second element of the Lucas Sequence to be + * returned. + * @param doV If set to true, computes Vk-1 and + * Vk, otherwise Uk-1 and + * Uk. + * @return An array with 2 elements, containing Uk-1 + * and Uk or Vk-1 + * and Vk. + */ + public static BigInteger[] GetLucas(sbyte mu, int k, bool doV) + { + if (!(mu == 1 || mu == -1)) + throw new ArgumentException("mu must be 1 or -1"); + + BigInteger u0; + BigInteger u1; + BigInteger u2; + + if (doV) + { + u0 = BigInteger.Two; + u1 = BigInteger.ValueOf(mu); + } + else + { + u0 = BigInteger.Zero; + u1 = BigInteger.One; + } + + for (int i = 1; i < k; i++) + { + // u2 = mu*u1 - 2*u0; + BigInteger s = null; + if (mu == 1) + { + s = u1; + } + else + { + // mu == -1 + s = u1.Negate(); + } + + u2 = s.Subtract(u0.ShiftLeft(1)); + u0 = u1; + u1 = u2; + // System.out.println(i + ": " + u2); + // System.out.println(); + } + + BigInteger[] retVal = {u0, u1}; + return retVal; + } + + /** + * Computes the auxiliary value tw. If the width is + * 4, then for mu = 1, tw = 6 and for + * mu = -1, tw = 10 + * @param mu The parameter μ of the elliptic curve. + * @param w The window width of the WTNAF. + * @return the auxiliary value tw + */ + public static BigInteger GetTw(sbyte mu, int w) + { + if (w == 4) + { + if (mu == 1) + { + return BigInteger.ValueOf(6); + } + else + { + // mu == -1 + return BigInteger.ValueOf(10); + } + } + else + { + // For w <> 4, the values must be computed + BigInteger[] us = GetLucas(mu, w, false); + BigInteger twoToW = BigInteger.Zero.SetBit(w); + BigInteger u1invert = us[1].ModInverse(twoToW); + BigInteger tw; + tw = BigInteger.Two.Multiply(us[0]).Multiply(u1invert).Mod(twoToW); + //System.out.println("mu = " + mu); + //System.out.println("tw = " + tw); + return tw; + } + } + + /** + * Computes the auxiliary values s0 and + * s1 used for partial modular reduction. + * @param curve The elliptic curve for which to compute + * s0 and s1. + * @throws ArgumentException if curve is not a + * Koblitz curve (Anomalous Binary Curve, ABC). + */ + public static BigInteger[] GetSi(AbstractF2mCurve curve) + { + if (!curve.IsKoblitz) + throw new ArgumentException("si is defined for Koblitz curves only"); + + int m = curve.FieldSize; + int a = curve.A.ToBigInteger().IntValue; + sbyte mu = GetMu(a); + int shifts = GetShiftsForCofactor(curve.Cofactor); + int index = m + 3 - a; + BigInteger[] ui = GetLucas(mu, index, false); + + if (mu == 1) + { + ui[0] = ui[0].Negate(); + ui[1] = ui[1].Negate(); + } + + BigInteger dividend0 = BigInteger.One.Add(ui[1]).ShiftRight(shifts); + BigInteger dividend1 = BigInteger.One.Add(ui[0]).ShiftRight(shifts).Negate(); + + return new BigInteger[] { dividend0, dividend1 }; + } + + public static BigInteger[] GetSi(int fieldSize, int curveA, BigInteger cofactor) + { + sbyte mu = GetMu(curveA); + int shifts = GetShiftsForCofactor(cofactor); + int index = fieldSize + 3 - curveA; + BigInteger[] ui = GetLucas(mu, index, false); + if (mu == 1) + { + ui[0] = ui[0].Negate(); + ui[1] = ui[1].Negate(); + } + + BigInteger dividend0 = BigInteger.One.Add(ui[1]).ShiftRight(shifts); + BigInteger dividend1 = BigInteger.One.Add(ui[0]).ShiftRight(shifts).Negate(); + + return new BigInteger[] { dividend0, dividend1 }; + } + + protected static int GetShiftsForCofactor(BigInteger h) + { + if (h != null && h.BitLength < 4) + { + int hi = h.IntValue; + if (hi == 2) + return 1; + if (hi == 4) + return 2; + } + + throw new ArgumentException("h (Cofactor) must be 2 or 4"); + } + + /** + * Partial modular reduction modulo + * m - 1)/(τ - 1). + * @param k The integer to be reduced. + * @param m The bitlength of the underlying finite field. + * @param a The parameter a of the elliptic curve. + * @param s The auxiliary values s0 and + * s1. + * @param mu The parameter μ of the elliptic curve. + * @param c The precision (number of bits of accuracy) of the partial + * modular reduction. + * @return ρ := k partmod (τm - 1)/(τ - 1) + */ + public static ZTauElement PartModReduction(BigInteger k, int m, sbyte a, + BigInteger[] s, sbyte mu, sbyte c) + { + // d0 = s[0] + mu*s[1]; mu is either 1 or -1 + BigInteger d0; + if (mu == 1) + { + d0 = s[0].Add(s[1]); + } + else + { + d0 = s[0].Subtract(s[1]); + } + + BigInteger[] v = GetLucas(mu, m, true); + BigInteger vm = v[1]; + + SimpleBigDecimal lambda0 = ApproximateDivisionByN( + k, s[0], vm, a, m, c); + + SimpleBigDecimal lambda1 = ApproximateDivisionByN( + k, s[1], vm, a, m, c); + + ZTauElement q = Round(lambda0, lambda1, mu); + + // r0 = n - d0*q0 - 2*s1*q1 + BigInteger r0 = k.Subtract(d0.Multiply(q.u)).Subtract( + BigInteger.ValueOf(2).Multiply(s[1]).Multiply(q.v)); + + // r1 = s1*q0 - s0*q1 + BigInteger r1 = s[1].Multiply(q.u).Subtract(s[0].Multiply(q.v)); + + return new ZTauElement(r0, r1); + } + + /** + * Multiplies a {@link org.bouncycastle.math.ec.AbstractF2mPoint AbstractF2mPoint} + * by a BigInteger using the reduced τ-adic + * NAF (RTNAF) method. + * @param p The AbstractF2mPoint to Multiply. + * @param k The BigInteger by which to Multiply p. + * @return k * p + */ + public static AbstractF2mPoint MultiplyRTnaf(AbstractF2mPoint p, BigInteger k) + { + AbstractF2mCurve curve = (AbstractF2mCurve)p.Curve; + int m = curve.FieldSize; + int a = curve.A.ToBigInteger().IntValue; + sbyte mu = GetMu(a); + BigInteger[] s = curve.GetSi(); + ZTauElement rho = PartModReduction(k, m, (sbyte)a, s, mu, (sbyte)10); + + return MultiplyTnaf(p, rho); + } + + /** + * Multiplies a {@link org.bouncycastle.math.ec.AbstractF2mPoint AbstractF2mPoint} + * by an element λ of Z[τ] + * using the τ-adic NAF (TNAF) method. + * @param p The AbstractF2mPoint to Multiply. + * @param lambda The element λ of + * Z[τ]. + * @return λ * p + */ + public static AbstractF2mPoint MultiplyTnaf(AbstractF2mPoint p, ZTauElement lambda) + { + AbstractF2mCurve curve = (AbstractF2mCurve)p.Curve; + sbyte mu = GetMu(curve.A); + sbyte[] u = TauAdicNaf(mu, lambda); + + AbstractF2mPoint q = MultiplyFromTnaf(p, u); + + return q; + } + + /** + * Multiplies a {@link org.bouncycastle.math.ec.AbstractF2mPoint AbstractF2mPoint} + * by an element λ of Z[τ] + * using the τ-adic NAF (TNAF) method, given the TNAF + * of λ. + * @param p The AbstractF2mPoint to Multiply. + * @param u The the TNAF of λ.. + * @return λ * p + */ + public static AbstractF2mPoint MultiplyFromTnaf(AbstractF2mPoint p, sbyte[] u) + { + ECCurve curve = p.Curve; + AbstractF2mPoint q = (AbstractF2mPoint)curve.Infinity; + AbstractF2mPoint pNeg = (AbstractF2mPoint)p.Negate(); + int tauCount = 0; + for (int i = u.Length - 1; i >= 0; i--) + { + ++tauCount; + sbyte ui = u[i]; + if (ui != 0) + { + q = q.TauPow(tauCount); + tauCount = 0; + + ECPoint x = ui > 0 ? p : pNeg; + q = (AbstractF2mPoint)q.Add(x); + } + } + if (tauCount > 0) + { + q = q.TauPow(tauCount); + } + return q; + } + + /** + * Computes the [τ]-adic window NAF of an element + * λ of Z[τ]. + * @param mu The parameter μ of the elliptic curve. + * @param lambda The element λ of + * Z[τ] of which to compute the + * [τ]-adic NAF. + * @param width The window width of the resulting WNAF. + * @param pow2w 2width. + * @param tw The auxiliary value tw. + * @param alpha The αu's for the window width. + * @return The [τ]-adic window NAF of + * λ. + */ + public static sbyte[] TauAdicWNaf(sbyte mu, ZTauElement lambda, + sbyte width, BigInteger pow2w, BigInteger tw, ZTauElement[] alpha) + { + if (!((mu == 1) || (mu == -1))) + throw new ArgumentException("mu must be 1 or -1"); + + BigInteger norm = Norm(mu, lambda); + + // Ceiling of log2 of the norm + int log2Norm = norm.BitLength; + + // If length(TNAF) > 30, then length(TNAF) < log2Norm + 3.52 + int maxLength = log2Norm > 30 ? log2Norm + 4 + width : 34 + width; + + // The array holding the TNAF + sbyte[] u = new sbyte[maxLength]; + + // 2^(width - 1) + BigInteger pow2wMin1 = pow2w.ShiftRight(1); + + // Split lambda into two BigIntegers to simplify calculations + BigInteger r0 = lambda.u; + BigInteger r1 = lambda.v; + int i = 0; + + // while lambda <> (0, 0) + while (!((r0.Equals(BigInteger.Zero))&&(r1.Equals(BigInteger.Zero)))) + { + // if r0 is odd + if (r0.TestBit(0)) + { + // uUnMod = r0 + r1*tw Mod 2^width + BigInteger uUnMod + = r0.Add(r1.Multiply(tw)).Mod(pow2w); + + sbyte uLocal; + // if uUnMod >= 2^(width - 1) + if (uUnMod.CompareTo(pow2wMin1) >= 0) + { + uLocal = (sbyte) uUnMod.Subtract(pow2w).IntValue; + } + else + { + uLocal = (sbyte) uUnMod.IntValue; + } + // uLocal is now in [-2^(width-1), 2^(width-1)-1] + + u[i] = uLocal; + bool s = true; + if (uLocal < 0) + { + s = false; + uLocal = (sbyte)-uLocal; + } + // uLocal is now >= 0 + + if (s) + { + r0 = r0.Subtract(alpha[uLocal].u); + r1 = r1.Subtract(alpha[uLocal].v); + } + else + { + r0 = r0.Add(alpha[uLocal].u); + r1 = r1.Add(alpha[uLocal].v); + } + } + else + { + u[i] = 0; + } + + BigInteger t = r0; + + if (mu == 1) + { + r0 = r1.Add(r0.ShiftRight(1)); + } + else + { + // mu == -1 + r0 = r1.Subtract(r0.ShiftRight(1)); + } + r1 = t.ShiftRight(1).Negate(); + i++; + } + return u; + } + + /** + * Does the precomputation for WTNAF multiplication. + * @param p The ECPoint for which to do the precomputation. + * @param a The parameter a of the elliptic curve. + * @return The precomputation array for p. + */ + public static AbstractF2mPoint[] GetPreComp(AbstractF2mPoint p, sbyte a) + { + sbyte[][] alphaTnaf = (a == 0) ? Tnaf.Alpha0Tnaf : Tnaf.Alpha1Tnaf; + + AbstractF2mPoint[] pu = new AbstractF2mPoint[(uint)(alphaTnaf.Length + 1) >> 1]; + pu[0] = p; + + uint precompLen = (uint)alphaTnaf.Length; + for (uint i = 3; i < precompLen; i += 2) + { + pu[i >> 1] = Tnaf.MultiplyFromTnaf(p, alphaTnaf[i]); + } + + p.Curve.NormalizeAll(pu); + + return pu; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/abc/Tnaf.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/abc/Tnaf.cs.meta new file mode 100644 index 0000000..77edec0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/abc/Tnaf.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ef965c60c1a720241bb351e4d4136093 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/abc/ZTauElement.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/abc/ZTauElement.cs new file mode 100644 index 0000000..4fcbf1b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/abc/ZTauElement.cs @@ -0,0 +1,36 @@ +namespace Org.BouncyCastle.Math.EC.Abc +{ + /** + * Class representing an element of Z[τ]. Let + * λ be an element of Z[τ]. Then + * λ is given as λ = u + vτ. The + * components u and v may be used directly, there + * are no accessor methods. + * Immutable class. + */ + internal class ZTauElement + { + /** + * The "real" part of λ. + */ + public readonly BigInteger u; + + /** + * The "τ-adic" part of λ. + */ + public readonly BigInteger v; + + /** + * Constructor for an element λ of + * Z[τ]. + * @param u The "real" part of λ. + * @param v The "τ-adic" part of + * λ. + */ + public ZTauElement(BigInteger u, BigInteger v) + { + this.u = u; + this.v = v; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/abc/ZTauElement.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/abc/ZTauElement.cs.meta new file mode 100644 index 0000000..71a1927 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/abc/ZTauElement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 85dfd0b40a414fd43a92147e18193d49 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom.meta new file mode 100644 index 0000000..1e27652 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d67ecb7ad2dc13a40bc7c87492381427 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/djb.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/djb.meta new file mode 100644 index 0000000..b33923f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/djb.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9aab62adc97288046b132a18b2aa0340 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/djb/Curve25519.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/djb/Curve25519.cs new file mode 100644 index 0000000..2566af0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/djb/Curve25519.cs @@ -0,0 +1,171 @@ +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Djb +{ + internal class Curve25519 + : AbstractFpCurve + { + public static readonly BigInteger q = Curve25519FieldElement.Q; + + private static readonly BigInteger C_a = new BigInteger(1, Hex.DecodeStrict("2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA984914A144")); + private static readonly BigInteger C_b = new BigInteger(1, Hex.DecodeStrict("7B425ED097B425ED097B425ED097B425ED097B425ED097B4260B5E9C7710C864")); + + private const int CURVE25519_DEFAULT_COORDS = COORD_JACOBIAN_MODIFIED; + private const int CURVE25519_FE_INTS = 8; + private static readonly ECFieldElement[] CURVE25519_AFFINE_ZS = new ECFieldElement[] { + new Curve25519FieldElement(BigInteger.One), new Curve25519FieldElement(C_a) }; + protected readonly Curve25519Point m_infinity; + + public Curve25519() + : base(q) + { + this.m_infinity = new Curve25519Point(this, null, null); + + this.m_a = FromBigInteger(C_a); + this.m_b = FromBigInteger(C_b); + this.m_order = new BigInteger(1, Hex.DecodeStrict("1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED")); + this.m_cofactor = BigInteger.ValueOf(8); + this.m_coord = CURVE25519_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new Curve25519(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_JACOBIAN_MODIFIED: + return true; + default: + return false; + } + } + + public virtual BigInteger Q + { + get { return q; } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return q.BitLength; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new Curve25519FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new Curve25519Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new Curve25519Point(this, x, y, zs, withCompression); + } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + uint[] table = new uint[len * CURVE25519_FE_INTS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat256.Copy(((Curve25519FieldElement)p.RawXCoord).x, 0, table, pos); pos += CURVE25519_FE_INTS; + Nat256.Copy(((Curve25519FieldElement)p.RawYCoord).x, 0, table, pos); pos += CURVE25519_FE_INTS; + } + } + + return new Curve25519LookupTable(this, table, len); + } + + public override ECFieldElement RandomFieldElement(SecureRandom r) + { + uint[] x = Nat256.Create(); + Curve25519Field.Random(r, x); + return new Curve25519FieldElement(x); + } + + public override ECFieldElement RandomFieldElementMult(SecureRandom r) + { + uint[] x = Nat256.Create(); + Curve25519Field.RandomMult(r, x); + return new Curve25519FieldElement(x); + } + + private class Curve25519LookupTable + : AbstractECLookupTable + { + private readonly Curve25519 m_outer; + private readonly uint[] m_table; + private readonly int m_size; + + internal Curve25519LookupTable(Curve25519 outer, uint[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public override int Size + { + get { return m_size; } + } + + public override ECPoint Lookup(int index) + { + uint[] x = Nat256.Create(), y = Nat256.Create(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + uint MASK = (uint)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < CURVE25519_FE_INTS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + CURVE25519_FE_INTS + j] & MASK; + } + + pos += (CURVE25519_FE_INTS * 2); + } + + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + uint[] x = Nat256.Create(), y = Nat256.Create(); + int pos = index * CURVE25519_FE_INTS * 2; + + for (int j = 0; j < CURVE25519_FE_INTS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + CURVE25519_FE_INTS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(uint[] x, uint[] y) + { + return m_outer.CreateRawPoint(new Curve25519FieldElement(x), new Curve25519FieldElement(y), CURVE25519_AFFINE_ZS, false); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/djb/Curve25519.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/djb/Curve25519.cs.meta new file mode 100644 index 0000000..06edad9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/djb/Curve25519.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b91f30b6aab50da4584721143a1190c8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/djb/Curve25519Field.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/djb/Curve25519Field.cs new file mode 100644 index 0000000..3141624 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/djb/Curve25519Field.cs @@ -0,0 +1,292 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Math.EC.Custom.Djb +{ + internal class Curve25519Field + { + // 2^255 - 19 + internal static readonly uint[] P = new uint[]{ 0xFFFFFFED, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x7FFFFFFF }; + private const uint P7 = 0x7FFFFFFF; + private static readonly uint[] PExt = new uint[]{ 0x00000169, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFED, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0x3FFFFFFF }; + private const uint PInv = 0x13; + + public static void Add(uint[] x, uint[] y, uint[] z) + { + Nat256.Add(x, y, z); + if (Nat256.Gte(z, P)) + { + SubPFrom(z); + } + } + + public static void AddExt(uint[] xx, uint[] yy, uint[] zz) + { + Nat.Add(16, xx, yy, zz); + if (Nat.Gte(16, zz, PExt)) + { + SubPExtFrom(zz); + } + } + + public static void AddOne(uint[] x, uint[] z) + { + Nat.Inc(8, x, z); + if (Nat256.Gte(z, P)) + { + SubPFrom(z); + } + } + + public static uint[] FromBigInteger(BigInteger x) + { + uint[] z = Nat.FromBigInteger(256, x); + while (Nat256.Gte(z, P)) + { + Nat256.SubFrom(P, z); + } + return z; + } + + public static void Half(uint[] x, uint[] z) + { + if ((x[0] & 1) == 0) + { + Nat.ShiftDownBit(8, x, 0, z); + } + else + { + Nat256.Add(x, P, z); + Nat.ShiftDownBit(8, z, 0); + } + } + + public static void Inv(uint[] x, uint[] z) + { + Mod.CheckedModOddInverse(P, x, z); + } + + public static int IsZero(uint[] x) + { + uint d = 0; + for (int i = 0; i < 8; ++i) + { + d |= x[i]; + } + d = (d >> 1) | (d & 1); + return ((int)d - 1) >> 31; + } + + public static void Multiply(uint[] x, uint[] y, uint[] z) + { + uint[] tt = Nat256.CreateExt(); + Nat256.Mul(x, y, tt); + Reduce(tt, z); + } + + public static void MultiplyAddToExt(uint[] x, uint[] y, uint[] zz) + { + Nat256.MulAddTo(x, y, zz); + if (Nat.Gte(16, zz, PExt)) + { + SubPExtFrom(zz); + } + } + + public static void Negate(uint[] x, uint[] z) + { + if (0 != IsZero(x)) + { + Nat256.Sub(P, P, z); + } + else + { + Nat256.Sub(P, x, z); + } + } + + public static void Random(SecureRandom r, uint[] z) + { + byte[] bb = new byte[8 * 4]; + do + { + r.NextBytes(bb); + Pack.LE_To_UInt32(bb, 0, z, 0, 8); + z[7] &= P7; + } + while (0 == Nat.LessThan(8, z, P)); + } + + public static void RandomMult(SecureRandom r, uint[] z) + { + do + { + Random(r, z); + } + while (0 != IsZero(z)); + } + + public static void Reduce(uint[] xx, uint[] z) + { + Debug.Assert(xx[15] >> 30 == 0); + + uint xx07 = xx[7]; + Nat.ShiftUpBit(8, xx, 8, xx07, z, 0); + uint c = Nat256.MulByWordAddTo(PInv, xx, z) << 1; + uint z7 = z[7]; + c += (z7 >> 31) - (xx07 >> 31); + z7 &= P7; + z7 += Nat.AddWordTo(7, c * PInv, z); + z[7] = z7; + if (z7 >= P7 && Nat256.Gte(z, P)) + { + SubPFrom(z); + } + } + + public static void Reduce27(uint x, uint[] z) + { + Debug.Assert(x >> 26 == 0); + + uint z7 = z[7]; + uint c = (x << 1 | z7 >> 31); + z7 &= P7; + z7 += Nat.AddWordTo(7, c * PInv, z); + z[7] = z7; + if (z7 >= P7 && Nat256.Gte(z, P)) + { + SubPFrom(z); + } + } + + public static void Square(uint[] x, uint[] z) + { + uint[] tt = Nat256.CreateExt(); + Nat256.Square(x, tt); + Reduce(tt, z); + } + + public static void SquareN(uint[] x, int n, uint[] z) + { + Debug.Assert(n > 0); + + uint[] tt = Nat256.CreateExt(); + Nat256.Square(x, tt); + Reduce(tt, z); + + while (--n > 0) + { + Nat256.Square(z, tt); + Reduce(tt, z); + } + } + + public static void Subtract(uint[] x, uint[] y, uint[] z) + { + int c = Nat256.Sub(x, y, z); + if (c != 0) + { + AddPTo(z); + } + } + + public static void SubtractExt(uint[] xx, uint[] yy, uint[] zz) + { + int c = Nat.Sub(16, xx, yy, zz); + if (c != 0) + { + AddPExtTo(zz); + } + } + + public static void Twice(uint[] x, uint[] z) + { + Nat.ShiftUpBit(8, x, 0, z); + if (Nat256.Gte(z, P)) + { + SubPFrom(z); + } + } + + private static uint AddPTo(uint[] z) + { + long c = (long)z[0] - PInv; + z[0] = (uint)c; + c >>= 32; + if (c != 0) + { + c = Nat.DecAt(7, z, 1); + } + c += (long)z[7] + (P7 + 1); + z[7] = (uint)c; + c >>= 32; + return (uint)c; + } + + private static uint AddPExtTo(uint[] zz) + { + long c = (long)zz[0] + PExt[0]; + zz[0] = (uint)c; + c >>= 32; + if (c != 0) + { + c = Nat.IncAt(8, zz, 1); + } + c += (long)zz[8] - PInv; + zz[8] = (uint)c; + c >>= 32; + if (c != 0) + { + c = Nat.DecAt(15, zz, 9); + } + c += (long)zz[15] + (PExt[15] + 1); + zz[15] = (uint)c; + c >>= 32; + return (uint)c; + } + + private static int SubPFrom(uint[] z) + { + long c = (long)z[0] + PInv; + z[0] = (uint)c; + c >>= 32; + if (c != 0) + { + c = Nat.IncAt(7, z, 1); + } + c += (long)z[7] - (P7 + 1); + z[7] = (uint)c; + c >>= 32; + return (int)c; + } + + private static int SubPExtFrom(uint[] zz) + { + long c = (long)zz[0] - PExt[0]; + zz[0] = (uint)c; + c >>= 32; + if (c != 0) + { + c = Nat.DecAt(8, zz, 1); + } + c += (long)zz[8] + PInv; + zz[8] = (uint)c; + c >>= 32; + if (c != 0) + { + c = Nat.IncAt(15, zz, 9); + } + c += (long)zz[15] - (PExt[15] + 1); + zz[15] = (uint)c; + c >>= 32; + return (int)c; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/djb/Curve25519Field.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/djb/Curve25519Field.cs.meta new file mode 100644 index 0000000..c1ee7a3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/djb/Curve25519Field.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c07260c7eae178d458d24656edddec52 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/djb/Curve25519FieldElement.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/djb/Curve25519FieldElement.cs new file mode 100644 index 0000000..a550984 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/djb/Curve25519FieldElement.cs @@ -0,0 +1,233 @@ +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math.EC.Custom.Djb +{ + internal class Curve25519FieldElement + : AbstractFpFieldElement + { + public static readonly BigInteger Q = Nat256.ToBigInteger(Curve25519Field.P); + + // Calculated as ECConstants.TWO.modPow(Q.shiftRight(2), Q) + private static readonly uint[] PRECOMP_POW2 = new uint[]{ 0x4a0ea0b0, 0xc4ee1b27, 0xad2fe478, 0x2f431806, + 0x3dfbd7a7, 0x2b4d0099, 0x4fc1df0b, 0x2b832480 }; + + protected internal readonly uint[] x; + + public Curve25519FieldElement(BigInteger x) + { + if (x == null || x.SignValue < 0 || x.CompareTo(Q) >= 0) + throw new ArgumentException("value invalid for Curve25519FieldElement", "x"); + + this.x = Curve25519Field.FromBigInteger(x); + } + + public Curve25519FieldElement() + { + this.x = Nat256.Create(); + } + + protected internal Curve25519FieldElement(uint[] x) + { + this.x = x; + } + + public override bool IsZero + { + get { return Nat256.IsZero(x); } + } + + public override bool IsOne + { + get { return Nat256.IsOne(x); } + } + + public override bool TestBitZero() + { + return Nat256.GetBit(x, 0) == 1; + } + + public override BigInteger ToBigInteger() + { + return Nat256.ToBigInteger(x); + } + + public override string FieldName + { + get { return "Curve25519Field"; } + } + + public override int FieldSize + { + get { return Q.BitLength; } + } + + public override ECFieldElement Add(ECFieldElement b) + { + uint[] z = Nat256.Create(); + Curve25519Field.Add(x, ((Curve25519FieldElement)b).x, z); + return new Curve25519FieldElement(z); + } + + public override ECFieldElement AddOne() + { + uint[] z = Nat256.Create(); + Curve25519Field.AddOne(x, z); + return new Curve25519FieldElement(z); + } + + public override ECFieldElement Subtract(ECFieldElement b) + { + uint[] z = Nat256.Create(); + Curve25519Field.Subtract(x, ((Curve25519FieldElement)b).x, z); + return new Curve25519FieldElement(z); + } + + public override ECFieldElement Multiply(ECFieldElement b) + { + uint[] z = Nat256.Create(); + Curve25519Field.Multiply(x, ((Curve25519FieldElement)b).x, z); + return new Curve25519FieldElement(z); + } + + public override ECFieldElement Divide(ECFieldElement b) + { + //return Multiply(b.Invert()); + uint[] z = Nat256.Create(); + Curve25519Field.Inv(((Curve25519FieldElement)b).x, z); + Curve25519Field.Multiply(z, x, z); + return new Curve25519FieldElement(z); + } + + public override ECFieldElement Negate() + { + uint[] z = Nat256.Create(); + Curve25519Field.Negate(x, z); + return new Curve25519FieldElement(z); + } + + public override ECFieldElement Square() + { + uint[] z = Nat256.Create(); + Curve25519Field.Square(x, z); + return new Curve25519FieldElement(z); + } + + public override ECFieldElement Invert() + { + //return new Curve25519FieldElement(ToBigInteger().ModInverse(Q)); + uint[] z = Nat256.Create(); + Curve25519Field.Inv(x, z); + return new Curve25519FieldElement(z); + } + + /** + * return a sqrt root - the routine verifies that the calculation returns the right value - if + * none exists it returns null. + */ + public override ECFieldElement Sqrt() + { + /* + * Q == 8m + 5, so we use Pocklington's method for this case. + * + * First, raise this element to the exponent 2^252 - 2^1 (i.e. m + 1) + * + * Breaking up the exponent's binary representation into "repunits", we get: + * { 251 1s } { 1 0s } + * + * Therefore we need an addition chain containing 251 (the lengths of the repunits) + * We use: 1, 2, 3, 4, 7, 11, 15, 30, 60, 120, 131, [251] + */ + + uint[] x1 = this.x; + if (Nat256.IsZero(x1) || Nat256.IsOne(x1)) + return this; + + uint[] x2 = Nat256.Create(); + Curve25519Field.Square(x1, x2); + Curve25519Field.Multiply(x2, x1, x2); + uint[] x3 = x2; + Curve25519Field.Square(x2, x3); + Curve25519Field.Multiply(x3, x1, x3); + uint[] x4 = Nat256.Create(); + Curve25519Field.Square(x3, x4); + Curve25519Field.Multiply(x4, x1, x4); + uint[] x7 = Nat256.Create(); + Curve25519Field.SquareN(x4, 3, x7); + Curve25519Field.Multiply(x7, x3, x7); + uint[] x11 = x3; + Curve25519Field.SquareN(x7, 4, x11); + Curve25519Field.Multiply(x11, x4, x11); + uint[] x15 = x7; + Curve25519Field.SquareN(x11, 4, x15); + Curve25519Field.Multiply(x15, x4, x15); + uint[] x30 = x4; + Curve25519Field.SquareN(x15, 15, x30); + Curve25519Field.Multiply(x30, x15, x30); + uint[] x60 = x15; + Curve25519Field.SquareN(x30, 30, x60); + Curve25519Field.Multiply(x60, x30, x60); + uint[] x120 = x30; + Curve25519Field.SquareN(x60, 60, x120); + Curve25519Field.Multiply(x120, x60, x120); + uint[] x131 = x60; + Curve25519Field.SquareN(x120, 11, x131); + Curve25519Field.Multiply(x131, x11, x131); + uint[] x251 = x11; + Curve25519Field.SquareN(x131, 120, x251); + Curve25519Field.Multiply(x251, x120, x251); + + uint[] t1 = x251; + Curve25519Field.Square(t1, t1); + + uint[] t2 = x120; + Curve25519Field.Square(t1, t2); + + if (Nat256.Eq(x1, t2)) + { + return new Curve25519FieldElement(t1); + } + + /* + * If the first guess is incorrect, we multiply by a precomputed power of 2 to get the second guess, + * which is ((4x)^(m + 1))/2 mod Q + */ + Curve25519Field.Multiply(t1, PRECOMP_POW2, t1); + + Curve25519Field.Square(t1, t2); + + if (Nat256.Eq(x1, t2)) + { + return new Curve25519FieldElement(t1); + } + + return null; + } + + public override bool Equals(object obj) + { + return Equals(obj as Curve25519FieldElement); + } + + public override bool Equals(ECFieldElement other) + { + return Equals(other as Curve25519FieldElement); + } + + public virtual bool Equals(Curve25519FieldElement other) + { + if (this == other) + return true; + if (null == other) + return false; + return Nat256.Eq(x, other.x); + } + + public override int GetHashCode() + { + return Q.GetHashCode() ^ Arrays.GetHashCode(x, 0, 8); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/djb/Curve25519FieldElement.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/djb/Curve25519FieldElement.cs.meta new file mode 100644 index 0000000..3d6fe2e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/djb/Curve25519FieldElement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5d46e0e0fad4a0a42a0c8e0f8891cd7a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/djb/Curve25519Point.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/djb/Curve25519Point.cs new file mode 100644 index 0000000..eb8fc12 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/djb/Curve25519Point.cs @@ -0,0 +1,313 @@ +using System; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Djb +{ + internal class Curve25519Point + : AbstractFpPoint + { + /** + * Create a point which encodes with point compression. + * + * @param curve the curve to use + * @param x affine x co-ordinate + * @param y affine y co-ordinate + * + * @deprecated Use ECCurve.CreatePoint to construct points + */ + public Curve25519Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * Create a point that encodes with or without point compresion. + * + * @param curve the curve to use + * @param x affine x co-ordinate + * @param y affine y co-ordinate + * @param withCompression if true encode with point compression + * + * @deprecated per-point compression property will be removed, refer {@link #getEncoded(bool)} + */ + public Curve25519Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal Curve25519Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new Curve25519Point(null, AffineXCoord, AffineYCoord); + } + + public override ECFieldElement GetZCoord(int index) + { + if (index == 1) + { + return GetJacobianModifiedW(); + } + + return base.GetZCoord(index); + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + if (this == b) + return Twice(); + + ECCurve curve = this.Curve; + + Curve25519FieldElement X1 = (Curve25519FieldElement)this.RawXCoord, Y1 = (Curve25519FieldElement)this.RawYCoord, + Z1 = (Curve25519FieldElement)this.RawZCoords[0]; + Curve25519FieldElement X2 = (Curve25519FieldElement)b.RawXCoord, Y2 = (Curve25519FieldElement)b.RawYCoord, + Z2 = (Curve25519FieldElement)b.RawZCoords[0]; + + uint c; + uint[] tt1 = Nat256.CreateExt(); + uint[] t2 = Nat256.Create(); + uint[] t3 = Nat256.Create(); + uint[] t4 = Nat256.Create(); + + bool Z1IsOne = Z1.IsOne; + uint[] U2, S2; + if (Z1IsOne) + { + U2 = X2.x; + S2 = Y2.x; + } + else + { + S2 = t3; + Curve25519Field.Square(Z1.x, S2); + + U2 = t2; + Curve25519Field.Multiply(S2, X2.x, U2); + + Curve25519Field.Multiply(S2, Z1.x, S2); + Curve25519Field.Multiply(S2, Y2.x, S2); + } + + bool Z2IsOne = Z2.IsOne; + uint[] U1, S1; + if (Z2IsOne) + { + U1 = X1.x; + S1 = Y1.x; + } + else + { + S1 = t4; + Curve25519Field.Square(Z2.x, S1); + + U1 = tt1; + Curve25519Field.Multiply(S1, X1.x, U1); + + Curve25519Field.Multiply(S1, Z2.x, S1); + Curve25519Field.Multiply(S1, Y1.x, S1); + } + + uint[] H = Nat256.Create(); + Curve25519Field.Subtract(U1, U2, H); + + uint[] R = t2; + Curve25519Field.Subtract(S1, S2, R); + + // Check if b == this or b == -this + if (Nat256.IsZero(H)) + { + if (Nat256.IsZero(R)) + { + // this == b, i.e. this must be doubled + return this.Twice(); + } + + // this == -b, i.e. the result is the point at infinity + return curve.Infinity; + } + + uint[] HSquared = Nat256.Create(); + Curve25519Field.Square(H, HSquared); + + uint[] G = Nat256.Create(); + Curve25519Field.Multiply(HSquared, H, G); + + uint[] V = t3; + Curve25519Field.Multiply(HSquared, U1, V); + + Curve25519Field.Negate(G, G); + Nat256.Mul(S1, G, tt1); + + c = Nat256.AddBothTo(V, V, G); + Curve25519Field.Reduce27(c, G); + + Curve25519FieldElement X3 = new Curve25519FieldElement(t4); + Curve25519Field.Square(R, X3.x); + Curve25519Field.Subtract(X3.x, G, X3.x); + + Curve25519FieldElement Y3 = new Curve25519FieldElement(G); + Curve25519Field.Subtract(V, X3.x, Y3.x); + Curve25519Field.MultiplyAddToExt(Y3.x, R, tt1); + Curve25519Field.Reduce(tt1, Y3.x); + + Curve25519FieldElement Z3 = new Curve25519FieldElement(H); + if (!Z1IsOne) + { + Curve25519Field.Multiply(Z3.x, Z1.x, Z3.x); + } + if (!Z2IsOne) + { + Curve25519Field.Multiply(Z3.x, Z2.x, Z3.x); + } + + uint[] Z3Squared = (Z1IsOne && Z2IsOne) ? HSquared : null; + + // TODO If the result will only be used in a subsequent addition, we don't need W3 + Curve25519FieldElement W3 = CalculateJacobianModifiedW((Curve25519FieldElement)Z3, Z3Squared); + + ECFieldElement[] zs = new ECFieldElement[] { Z3, W3 }; + + return new Curve25519Point(curve, X3, Y3, zs, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement Y1 = this.RawYCoord; + if (Y1.IsZero) + return curve.Infinity; + + return TwiceJacobianModified(true); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this == b) + return ThreeTimes(); + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECFieldElement Y1 = this.RawYCoord; + if (Y1.IsZero) + return b; + + return TwiceJacobianModified(false).Add(b); + } + + public override ECPoint ThreeTimes() + { + if (this.IsInfinity || this.RawYCoord.IsZero) + return this; + + return TwiceJacobianModified(false).Add(this); + } + + public override ECPoint Negate() + { + if (IsInfinity) + return this; + + return new Curve25519Point(Curve, RawXCoord, RawYCoord.Negate(), RawZCoords, IsCompressed); + } + + protected virtual Curve25519FieldElement CalculateJacobianModifiedW(Curve25519FieldElement Z, uint[] ZSquared) + { + Curve25519FieldElement a4 = (Curve25519FieldElement)this.Curve.A; + if (Z.IsOne) + return a4; + + Curve25519FieldElement W = new Curve25519FieldElement(); + if (ZSquared == null) + { + ZSquared = W.x; + Curve25519Field.Square(Z.x, ZSquared); + } + Curve25519Field.Square(ZSquared, W.x); + Curve25519Field.Multiply(W.x, a4.x, W.x); + return W; + } + + protected virtual Curve25519FieldElement GetJacobianModifiedW() + { + ECFieldElement[] ZZ = this.RawZCoords; + Curve25519FieldElement W = (Curve25519FieldElement)ZZ[1]; + if (W == null) + { + // NOTE: Rarely, TwicePlus will result in the need for a lazy W1 calculation here + ZZ[1] = W = CalculateJacobianModifiedW((Curve25519FieldElement)ZZ[0], null); + } + return W; + } + + protected virtual Curve25519Point TwiceJacobianModified(bool calculateW) + { + Curve25519FieldElement X1 = (Curve25519FieldElement)this.RawXCoord, Y1 = (Curve25519FieldElement)this.RawYCoord, + Z1 = (Curve25519FieldElement)this.RawZCoords[0], W1 = GetJacobianModifiedW(); + + uint c; + + uint[] M = Nat256.Create(); + Curve25519Field.Square(X1.x, M); + c = Nat256.AddBothTo(M, M, M); + c += Nat256.AddTo(W1.x, M); + Curve25519Field.Reduce27(c, M); + + uint[] _2Y1 = Nat256.Create(); + Curve25519Field.Twice(Y1.x, _2Y1); + + uint[] _2Y1Squared = Nat256.Create(); + Curve25519Field.Multiply(_2Y1, Y1.x, _2Y1Squared); + + uint[] S = Nat256.Create(); + Curve25519Field.Multiply(_2Y1Squared, X1.x, S); + Curve25519Field.Twice(S, S); + + uint[] _8T = Nat256.Create(); + Curve25519Field.Square(_2Y1Squared, _8T); + Curve25519Field.Twice(_8T, _8T); + + Curve25519FieldElement X3 = new Curve25519FieldElement(_2Y1Squared); + Curve25519Field.Square(M, X3.x); + Curve25519Field.Subtract(X3.x, S, X3.x); + Curve25519Field.Subtract(X3.x, S, X3.x); + + Curve25519FieldElement Y3 = new Curve25519FieldElement(S); + Curve25519Field.Subtract(S, X3.x, Y3.x); + Curve25519Field.Multiply(Y3.x, M, Y3.x); + Curve25519Field.Subtract(Y3.x, _8T, Y3.x); + + Curve25519FieldElement Z3 = new Curve25519FieldElement(_2Y1); + if (!Nat256.IsOne(Z1.x)) + { + Curve25519Field.Multiply(Z3.x, Z1.x, Z3.x); + } + + Curve25519FieldElement W3 = null; + if (calculateW) + { + W3 = new Curve25519FieldElement(_8T); + Curve25519Field.Multiply(W3.x, W1.x, W3.x); + Curve25519Field.Twice(W3.x, W3.x); + } + + return new Curve25519Point(this.Curve, X3, Y3, new ECFieldElement[] { Z3, W3 }, IsCompressed); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/djb/Curve25519Point.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/djb/Curve25519Point.cs.meta new file mode 100644 index 0000000..c2c551f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/djb/Curve25519Point.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a9a4041deb769a546bfc6826c5d82242 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/gm.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/gm.meta new file mode 100644 index 0000000..f2b1452 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/gm.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 592a3967899e72440be567a31488129c +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/gm/SM2P256V1Curve.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/gm/SM2P256V1Curve.cs new file mode 100644 index 0000000..805245c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/gm/SM2P256V1Curve.cs @@ -0,0 +1,170 @@ +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.GM +{ + internal class SM2P256V1Curve + : AbstractFpCurve + { + public static readonly BigInteger q = SM2P256V1FieldElement.Q; + + private const int SM2P256V1_DEFAULT_COORDS = COORD_JACOBIAN; + private const int SM2P256V1_FE_INTS = 8; + private static readonly ECFieldElement[] SM2P256V1_AFFINE_ZS = new ECFieldElement[] { new SM2P256V1FieldElement(BigInteger.One) }; + + protected readonly SM2P256V1Point m_infinity; + + public SM2P256V1Curve() + : base(q) + { + this.m_infinity = new SM2P256V1Point(this, null, null); + + this.m_a = FromBigInteger(new BigInteger(1, + Hex.DecodeStrict("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC"))); + this.m_b = FromBigInteger(new BigInteger(1, + Hex.DecodeStrict("28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93"))); + this.m_order = new BigInteger(1, Hex.DecodeStrict("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123")); + this.m_cofactor = BigInteger.One; + this.m_coord = SM2P256V1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SM2P256V1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_JACOBIAN: + return true; + default: + return false; + } + } + + public virtual BigInteger Q + { + get { return q; } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return q.BitLength; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SM2P256V1FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SM2P256V1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SM2P256V1Point(this, x, y, zs, withCompression); + } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + uint[] table = new uint[len * SM2P256V1_FE_INTS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat256.Copy(((SM2P256V1FieldElement)p.RawXCoord).x, 0, table, pos); pos += SM2P256V1_FE_INTS; + Nat256.Copy(((SM2P256V1FieldElement)p.RawYCoord).x, 0, table, pos); pos += SM2P256V1_FE_INTS; + } + } + + return new SM2P256V1LookupTable(this, table, len); + } + + public override ECFieldElement RandomFieldElement(SecureRandom r) + { + uint[] x = Nat256.Create(); + SM2P256V1Field.Random(r, x); + return new SM2P256V1FieldElement(x); + } + + public override ECFieldElement RandomFieldElementMult(SecureRandom r) + { + uint[] x = Nat256.Create(); + SM2P256V1Field.RandomMult(r, x); + return new SM2P256V1FieldElement(x); + } + + private class SM2P256V1LookupTable + : AbstractECLookupTable + { + private readonly SM2P256V1Curve m_outer; + private readonly uint[] m_table; + private readonly int m_size; + + internal SM2P256V1LookupTable(SM2P256V1Curve outer, uint[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public override int Size + { + get { return m_size; } + } + + public override ECPoint Lookup(int index) + { + uint[] x = Nat256.Create(), y = Nat256.Create(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + uint MASK = (uint)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SM2P256V1_FE_INTS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SM2P256V1_FE_INTS + j] & MASK; + } + + pos += (SM2P256V1_FE_INTS * 2); + } + + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + uint[] x = Nat256.Create(), y = Nat256.Create(); + int pos = index * SM2P256V1_FE_INTS * 2; + + for (int j = 0; j < SM2P256V1_FE_INTS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SM2P256V1_FE_INTS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(uint[] x, uint[] y) + { + return m_outer.CreateRawPoint(new SM2P256V1FieldElement(x), new SM2P256V1FieldElement(y), SM2P256V1_AFFINE_ZS, false); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/gm/SM2P256V1Curve.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/gm/SM2P256V1Curve.cs.meta new file mode 100644 index 0000000..07a3846 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/gm/SM2P256V1Curve.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 590c3d342211662459cfdbf0da7cbb14 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/gm/SM2P256V1Field.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/gm/SM2P256V1Field.cs new file mode 100644 index 0000000..6fbe849 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/gm/SM2P256V1Field.cs @@ -0,0 +1,345 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Math.EC.Custom.GM +{ + internal class SM2P256V1Field + { + // 2^256 - 2^224 - 2^96 + 2^64 - 1 + internal static readonly uint[] P = new uint[]{ 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE }; + private static readonly uint[] PExt = new uint[]{ 00000001, 0x00000000, 0xFFFFFFFE, 0x00000001, 0x00000001, + 0xFFFFFFFE, 0x00000000, 0x00000002, 0xFFFFFFFE, 0xFFFFFFFD, 0x00000003, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0xFFFFFFFE }; + private const uint P7 = 0xFFFFFFFE; + private const uint PExt15 = 0xFFFFFFFE; + + public static void Add(uint[] x, uint[] y, uint[] z) + { + uint c = Nat256.Add(x, y, z); + if (c != 0 || (z[7] >= P7 && Nat256.Gte(z, P))) + { + AddPInvTo(z); + } + } + + public static void AddExt(uint[] xx, uint[] yy, uint[] zz) + { + uint c = Nat.Add(16, xx, yy, zz); + if (c != 0 || (zz[15] >= PExt15 && Nat.Gte(16, zz, PExt))) + { + Nat.SubFrom(16, PExt, zz); + } + } + + public static void AddOne(uint[] x, uint[] z) + { + uint c = Nat.Inc(8, x, z); + if (c != 0 || (z[7] >= P7 && Nat256.Gte(z, P))) + { + AddPInvTo(z); + } + } + + public static uint[] FromBigInteger(BigInteger x) + { + uint[] z = Nat.FromBigInteger(256, x); + if (z[7] >= P7 && Nat256.Gte(z, P)) + { + Nat256.SubFrom(P, z); + } + return z; + } + + public static void Inv(uint[] x, uint[] z) + { + Mod.CheckedModOddInverse(P, x, z); + } + + public static void Half(uint[] x, uint[] z) + { + if ((x[0] & 1) == 0) + { + Nat.ShiftDownBit(8, x, 0, z); + } + else + { + uint c = Nat256.Add(x, P, z); + Nat.ShiftDownBit(8, z, c); + } + } + + public static int IsZero(uint[] x) + { + uint d = 0; + for (int i = 0; i < 8; ++i) + { + d |= x[i]; + } + d = (d >> 1) | (d & 1); + return ((int)d - 1) >> 31; + } + + public static void Multiply(uint[] x, uint[] y, uint[] z) + { + uint[] tt = Nat256.CreateExt(); + Nat256.Mul(x, y, tt); + Reduce(tt, z); + } + + public static void MultiplyAddToExt(uint[] x, uint[] y, uint[] zz) + { + uint c = Nat256.MulAddTo(x, y, zz); + if (c != 0 || (zz[15] >= PExt15 && Nat.Gte(16, zz, PExt))) + { + Nat.SubFrom(16, PExt, zz); + } + } + + public static void Negate(uint[] x, uint[] z) + { + if (0 != IsZero(x)) + { + Nat256.Sub(P, P, z); + } + else + { + Nat256.Sub(P, x, z); + } + } + + public static void Random(SecureRandom r, uint[] z) + { + byte[] bb = new byte[8 * 4]; + do + { + r.NextBytes(bb); + Pack.LE_To_UInt32(bb, 0, z, 0, 8); + } + while (0 == Nat.LessThan(8, z, P)); + } + + public static void RandomMult(SecureRandom r, uint[] z) + { + do + { + Random(r, z); + } + while (0 != IsZero(z)); + } + + public static void Reduce(uint[] xx, uint[] z) + { + long xx08 = xx[8], xx09 = xx[9], xx10 = xx[10], xx11 = xx[11]; + long xx12 = xx[12], xx13 = xx[13], xx14 = xx[14], xx15 = xx[15]; + + long t0 = xx08 + xx09; + long t1 = xx10 + xx11; + long t2 = xx12 + xx15; + long t3 = xx13 + xx14; + long t4 = t3 + (xx15 << 1); + + long ts = t0 + t3; + long tt = t1 + t2 + ts; + + long cc = 0; + cc += (long)xx[0] + tt + xx13 + xx14 + xx15; + z[0] = (uint)cc; + cc >>= 32; + cc += (long)xx[1] + tt - xx08 + xx14 + xx15; + z[1] = (uint)cc; + cc >>= 32; + cc += (long)xx[2] - ts; + z[2] = (uint)cc; + cc >>= 32; + cc += (long)xx[3] + tt - xx09 - xx10 + xx13; + z[3] = (uint)cc; + cc >>= 32; + cc += (long)xx[4] + tt - t1 - xx08 + xx14; + z[4] = (uint)cc; + cc >>= 32; + cc += (long)xx[5] + t4 + xx10; + z[5] = (uint)cc; + cc >>= 32; + cc += (long)xx[6] + xx11 + xx14 + xx15; + z[6] = (uint)cc; + cc >>= 32; + cc += (long)xx[7] + tt + t4 + xx12; + z[7] = (uint)cc; + cc >>= 32; + + Debug.Assert(cc >= 0); + + Reduce32((uint)cc, z); + } + + public static void Reduce32(uint x, uint[] z) + { + long cc = 0; + + if (x != 0) + { + long xx08 = x; + + cc += (long)z[0] + xx08; + z[0] = (uint)cc; + cc >>= 32; + if (cc != 0) + { + cc += (long)z[1]; + z[1] = (uint)cc; + cc >>= 32; + } + cc += (long)z[2] - xx08; + z[2] = (uint)cc; + cc >>= 32; + cc += (long)z[3] + xx08; + z[3] = (uint)cc; + cc >>= 32; + if (cc != 0) + { + cc += (long)z[4]; + z[4] = (uint)cc; + cc >>= 32; + cc += (long)z[5]; + z[5] = (uint)cc; + cc >>= 32; + cc += (long)z[6]; + z[6] = (uint)cc; + cc >>= 32; + } + cc += (long)z[7] + xx08; + z[7] = (uint)cc; + cc >>= 32; + + Debug.Assert(cc == 0 || cc == 1); + } + + if (cc != 0 || (z[7] >= P7 && Nat256.Gte(z, P))) + { + AddPInvTo(z); + } + } + + public static void Square(uint[] x, uint[] z) + { + uint[] tt = Nat256.CreateExt(); + Nat256.Square(x, tt); + Reduce(tt, z); + } + + public static void SquareN(uint[] x, int n, uint[] z) + { + Debug.Assert(n > 0); + + uint[] tt = Nat256.CreateExt(); + Nat256.Square(x, tt); + Reduce(tt, z); + + while (--n > 0) + { + Nat256.Square(z, tt); + Reduce(tt, z); + } + } + + public static void Subtract(uint[] x, uint[] y, uint[] z) + { + int c = Nat256.Sub(x, y, z); + if (c != 0) + { + SubPInvFrom(z); + } + } + + public static void SubtractExt(uint[] xx, uint[] yy, uint[] zz) + { + int c = Nat.Sub(16, xx, yy, zz); + if (c != 0) + { + Nat.AddTo(16, PExt, zz); + } + } + + public static void Twice(uint[] x, uint[] z) + { + uint c = Nat.ShiftUpBit(8, x, 0, z); + if (c != 0 || (z[7] >= P7 && Nat256.Gte(z, P))) + { + AddPInvTo(z); + } + } + + private static void AddPInvTo(uint[] z) + { + long c = (long)z[0] + 1; + z[0] = (uint)c; + c >>= 32; + if (c != 0) + { + c += (long)z[1]; + z[1] = (uint)c; + c >>= 32; + } + c += (long)z[2] - 1; + z[2] = (uint)c; + c >>= 32; + c += (long)z[3] + 1; + z[3] = (uint)c; + c >>= 32; + if (c != 0) + { + c += (long)z[4]; + z[4] = (uint)c; + c >>= 32; + c += (long)z[5]; + z[5] = (uint)c; + c >>= 32; + c += (long)z[6]; + z[6] = (uint)c; + c >>= 32; + } + c += (long)z[7] + 1; + z[7] = (uint)c; + //c >>= 32; + } + + private static void SubPInvFrom(uint[] z) + { + long c = (long)z[0] - 1; + z[0] = (uint)c; + c >>= 32; + if (c != 0) + { + c += (long)z[1]; + z[1] = (uint)c; + c >>= 32; + } + c += (long)z[2] + 1; + z[2] = (uint)c; + c >>= 32; + c += (long)z[3] - 1; + z[3] = (uint)c; + c >>= 32; + if (c != 0) + { + c += (long)z[4]; + z[4] = (uint)c; + c >>= 32; + c += (long)z[5]; + z[5] = (uint)c; + c >>= 32; + c += (long)z[6]; + z[6] = (uint)c; + c >>= 32; + } + c += (long)z[7] - 1; + z[7] = (uint)c; + //c >>= 32; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/gm/SM2P256V1Field.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/gm/SM2P256V1Field.cs.meta new file mode 100644 index 0000000..69998a0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/gm/SM2P256V1Field.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 38bebff964a0a6544931ae10dde87313 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/gm/SM2P256V1FieldElement.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/gm/SM2P256V1FieldElement.cs new file mode 100644 index 0000000..25cb249 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/gm/SM2P256V1FieldElement.cs @@ -0,0 +1,213 @@ +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.GM +{ + internal class SM2P256V1FieldElement + : AbstractFpFieldElement + { + public static readonly BigInteger Q = new BigInteger(1, + Hex.DecodeStrict("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF")); + + protected internal readonly uint[] x; + + public SM2P256V1FieldElement(BigInteger x) + { + if (x == null || x.SignValue < 0 || x.CompareTo(Q) >= 0) + throw new ArgumentException("value invalid for SM2P256V1FieldElement", "x"); + + this.x = SM2P256V1Field.FromBigInteger(x); + } + + public SM2P256V1FieldElement() + { + this.x = Nat256.Create(); + } + + protected internal SM2P256V1FieldElement(uint[] x) + { + this.x = x; + } + + public override bool IsZero + { + get { return Nat256.IsZero(x); } + } + + public override bool IsOne + { + get { return Nat256.IsOne(x); } + } + + public override bool TestBitZero() + { + return Nat256.GetBit(x, 0) == 1; + } + + public override BigInteger ToBigInteger() + { + return Nat256.ToBigInteger(x); + } + + public override string FieldName + { + get { return "SM2P256V1Field"; } + } + + public override int FieldSize + { + get { return Q.BitLength; } + } + + public override ECFieldElement Add(ECFieldElement b) + { + uint[] z = Nat256.Create(); + SM2P256V1Field.Add(x, ((SM2P256V1FieldElement)b).x, z); + return new SM2P256V1FieldElement(z); + } + + public override ECFieldElement AddOne() + { + uint[] z = Nat256.Create(); + SM2P256V1Field.AddOne(x, z); + return new SM2P256V1FieldElement(z); + } + + public override ECFieldElement Subtract(ECFieldElement b) + { + uint[] z = Nat256.Create(); + SM2P256V1Field.Subtract(x, ((SM2P256V1FieldElement)b).x, z); + return new SM2P256V1FieldElement(z); + } + + public override ECFieldElement Multiply(ECFieldElement b) + { + uint[] z = Nat256.Create(); + SM2P256V1Field.Multiply(x, ((SM2P256V1FieldElement)b).x, z); + return new SM2P256V1FieldElement(z); + } + + public override ECFieldElement Divide(ECFieldElement b) + { + //return Multiply(b.Invert()); + uint[] z = Nat256.Create(); + SM2P256V1Field.Inv(((SM2P256V1FieldElement)b).x, z); + SM2P256V1Field.Multiply(z, x, z); + return new SM2P256V1FieldElement(z); + } + + public override ECFieldElement Negate() + { + uint[] z = Nat256.Create(); + SM2P256V1Field.Negate(x, z); + return new SM2P256V1FieldElement(z); + } + + public override ECFieldElement Square() + { + uint[] z = Nat256.Create(); + SM2P256V1Field.Square(x, z); + return new SM2P256V1FieldElement(z); + } + + public override ECFieldElement Invert() + { + //return new SM2P256V1FieldElement(ToBigInteger().ModInverse(Q)); + uint[] z = Nat256.Create(); + SM2P256V1Field.Inv(x, z); + return new SM2P256V1FieldElement(z); + } + + /** + * return a sqrt root - the routine verifies that the calculation returns the right value - if + * none exists it returns null. + */ + public override ECFieldElement Sqrt() + { + /* + * Raise this element to the exponent 2^254 - 2^222 - 2^94 + 2^62 + * + * Breaking up the exponent's binary representation into "repunits", we get: + * { 31 1s } { 1 0s } { 128 1s } { 31 0s } { 1 1s } { 62 0s } + * + * We use an addition chain for the beginning: [1], 2, 3, 6, 12, [24], 30, [31] + */ + + uint[] x1 = this.x; + if (Nat256.IsZero(x1) || Nat256.IsOne(x1)) + { + return this; + } + + uint[] x2 = Nat256.Create(); + SM2P256V1Field.Square(x1, x2); + SM2P256V1Field.Multiply(x2, x1, x2); + uint[] x4 = Nat256.Create(); + SM2P256V1Field.SquareN(x2, 2, x4); + SM2P256V1Field.Multiply(x4, x2, x4); + uint[] x6 = Nat256.Create(); + SM2P256V1Field.SquareN(x4, 2, x6); + SM2P256V1Field.Multiply(x6, x2, x6); + uint[] x12 = x2; + SM2P256V1Field.SquareN(x6, 6, x12); + SM2P256V1Field.Multiply(x12, x6, x12); + uint[] x24 = Nat256.Create(); + SM2P256V1Field.SquareN(x12, 12, x24); + SM2P256V1Field.Multiply(x24, x12, x24); + uint[] x30 = x12; + SM2P256V1Field.SquareN(x24, 6, x30); + SM2P256V1Field.Multiply(x30, x6, x30); + uint[] x31 = x6; + SM2P256V1Field.Square(x30, x31); + SM2P256V1Field.Multiply(x31, x1, x31); + + uint[] t1 = x24; + SM2P256V1Field.SquareN(x31, 31, t1); + + uint[] x62 = x30; + SM2P256V1Field.Multiply(t1, x31, x62); + + SM2P256V1Field.SquareN(t1, 32, t1); + SM2P256V1Field.Multiply(t1, x62, t1); + SM2P256V1Field.SquareN(t1, 62, t1); + SM2P256V1Field.Multiply(t1, x62, t1); + SM2P256V1Field.SquareN(t1, 4, t1); + SM2P256V1Field.Multiply(t1, x4, t1); + SM2P256V1Field.SquareN(t1, 32, t1); + SM2P256V1Field.Multiply(t1, x1, t1); + SM2P256V1Field.SquareN(t1, 62, t1); + + uint[] t2 = x4; + SM2P256V1Field.Square(t1, t2); + + return Nat256.Eq(x1, t2) ? new SM2P256V1FieldElement(t1) : null; + } + + public override bool Equals(object obj) + { + return Equals(obj as SM2P256V1FieldElement); + } + + public override bool Equals(ECFieldElement other) + { + return Equals(other as SM2P256V1FieldElement); + } + + public virtual bool Equals(SM2P256V1FieldElement other) + { + if (this == other) + return true; + if (null == other) + return false; + return Nat256.Eq(x, other.x); + } + + public override int GetHashCode() + { + return Q.GetHashCode() ^ Arrays.GetHashCode(x, 0, 8); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/gm/SM2P256V1FieldElement.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/gm/SM2P256V1FieldElement.cs.meta new file mode 100644 index 0000000..2c9ba10 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/gm/SM2P256V1FieldElement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9c18f5f91d356f14f8439da14067934f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/gm/SM2P256V1Point.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/gm/SM2P256V1Point.cs new file mode 100644 index 0000000..916c906 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/gm/SM2P256V1Point.cs @@ -0,0 +1,279 @@ +using System; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.GM +{ + internal class SM2P256V1Point + : AbstractFpPoint + { + /** + * Create a point which encodes with point compression. + * + * @param curve + * the curve to use + * @param x + * affine x co-ordinate + * @param y + * affine y co-ordinate + * + * @deprecated Use ECCurve.createPoint to construct points + */ + public SM2P256V1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * Create a point that encodes with or without point compresion. + * + * @param curve + * the curve to use + * @param x + * affine x co-ordinate + * @param y + * affine y co-ordinate + * @param withCompression + * if true encode with point compression + * + * @deprecated per-point compression property will be removed, refer + * {@link #getEncoded(bool)} + */ + public SM2P256V1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SM2P256V1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SM2P256V1Point(null, AffineXCoord, AffineYCoord); + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + if (this == b) + return Twice(); + + ECCurve curve = this.Curve; + + SM2P256V1FieldElement X1 = (SM2P256V1FieldElement)this.RawXCoord, Y1 = (SM2P256V1FieldElement)this.RawYCoord; + SM2P256V1FieldElement X2 = (SM2P256V1FieldElement)b.RawXCoord, Y2 = (SM2P256V1FieldElement)b.RawYCoord; + + SM2P256V1FieldElement Z1 = (SM2P256V1FieldElement)this.RawZCoords[0]; + SM2P256V1FieldElement Z2 = (SM2P256V1FieldElement)b.RawZCoords[0]; + + uint c; + uint[] tt1 = Nat256.CreateExt(); + uint[] t2 = Nat256.Create(); + uint[] t3 = Nat256.Create(); + uint[] t4 = Nat256.Create(); + + bool Z1IsOne = Z1.IsOne; + uint[] U2, S2; + if (Z1IsOne) + { + U2 = X2.x; + S2 = Y2.x; + } + else + { + S2 = t3; + SM2P256V1Field.Square(Z1.x, S2); + + U2 = t2; + SM2P256V1Field.Multiply(S2, X2.x, U2); + + SM2P256V1Field.Multiply(S2, Z1.x, S2); + SM2P256V1Field.Multiply(S2, Y2.x, S2); + } + + bool Z2IsOne = Z2.IsOne; + uint[] U1, S1; + if (Z2IsOne) + { + U1 = X1.x; + S1 = Y1.x; + } + else + { + S1 = t4; + SM2P256V1Field.Square(Z2.x, S1); + + U1 = tt1; + SM2P256V1Field.Multiply(S1, X1.x, U1); + + SM2P256V1Field.Multiply(S1, Z2.x, S1); + SM2P256V1Field.Multiply(S1, Y1.x, S1); + } + + uint[] H = Nat256.Create(); + SM2P256V1Field.Subtract(U1, U2, H); + + uint[] R = t2; + SM2P256V1Field.Subtract(S1, S2, R); + + // Check if b == this or b == -this + if (Nat256.IsZero(H)) + { + if (Nat256.IsZero(R)) + { + // this == b, i.e. this must be doubled + return this.Twice(); + } + + // this == -b, i.e. the result is the point at infinity + return curve.Infinity; + } + + uint[] HSquared = t3; + SM2P256V1Field.Square(H, HSquared); + + uint[] G = Nat256.Create(); + SM2P256V1Field.Multiply(HSquared, H, G); + + uint[] V = t3; + SM2P256V1Field.Multiply(HSquared, U1, V); + + SM2P256V1Field.Negate(G, G); + Nat256.Mul(S1, G, tt1); + + c = Nat256.AddBothTo(V, V, G); + SM2P256V1Field.Reduce32(c, G); + + SM2P256V1FieldElement X3 = new SM2P256V1FieldElement(t4); + SM2P256V1Field.Square(R, X3.x); + SM2P256V1Field.Subtract(X3.x, G, X3.x); + + SM2P256V1FieldElement Y3 = new SM2P256V1FieldElement(G); + SM2P256V1Field.Subtract(V, X3.x, Y3.x); + SM2P256V1Field.MultiplyAddToExt(Y3.x, R, tt1); + SM2P256V1Field.Reduce(tt1, Y3.x); + + SM2P256V1FieldElement Z3 = new SM2P256V1FieldElement(H); + if (!Z1IsOne) + { + SM2P256V1Field.Multiply(Z3.x, Z1.x, Z3.x); + } + if (!Z2IsOne) + { + SM2P256V1Field.Multiply(Z3.x, Z2.x, Z3.x); + } + + ECFieldElement[] zs = new ECFieldElement[]{ Z3 }; + + return new SM2P256V1Point(curve, X3, Y3, zs, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + SM2P256V1FieldElement Y1 = (SM2P256V1FieldElement)this.RawYCoord; + if (Y1.IsZero) + return curve.Infinity; + + SM2P256V1FieldElement X1 = (SM2P256V1FieldElement)this.RawXCoord, Z1 = (SM2P256V1FieldElement)this.RawZCoords[0]; + + uint c; + uint[] t1 = Nat256.Create(); + uint[] t2 = Nat256.Create(); + + uint[] Y1Squared = Nat256.Create(); + SM2P256V1Field.Square(Y1.x, Y1Squared); + + uint[] T = Nat256.Create(); + SM2P256V1Field.Square(Y1Squared, T); + + bool Z1IsOne = Z1.IsOne; + + uint[] Z1Squared = Z1.x; + if (!Z1IsOne) + { + Z1Squared = t2; + SM2P256V1Field.Square(Z1.x, Z1Squared); + } + + SM2P256V1Field.Subtract(X1.x, Z1Squared, t1); + + uint[] M = t2; + SM2P256V1Field.Add(X1.x, Z1Squared, M); + SM2P256V1Field.Multiply(M, t1, M); + c = Nat256.AddBothTo(M, M, M); + SM2P256V1Field.Reduce32(c, M); + + uint[] S = Y1Squared; + SM2P256V1Field.Multiply(Y1Squared, X1.x, S); + c = Nat.ShiftUpBits(8, S, 2, 0); + SM2P256V1Field.Reduce32(c, S); + + c = Nat.ShiftUpBits(8, T, 3, 0, t1); + SM2P256V1Field.Reduce32(c, t1); + + SM2P256V1FieldElement X3 = new SM2P256V1FieldElement(T); + SM2P256V1Field.Square(M, X3.x); + SM2P256V1Field.Subtract(X3.x, S, X3.x); + SM2P256V1Field.Subtract(X3.x, S, X3.x); + + SM2P256V1FieldElement Y3 = new SM2P256V1FieldElement(S); + SM2P256V1Field.Subtract(S, X3.x, Y3.x); + SM2P256V1Field.Multiply(Y3.x, M, Y3.x); + SM2P256V1Field.Subtract(Y3.x, t1, Y3.x); + + SM2P256V1FieldElement Z3 = new SM2P256V1FieldElement(M); + SM2P256V1Field.Twice(Y1.x, Z3.x); + if (!Z1IsOne) + { + SM2P256V1Field.Multiply(Z3.x, Z1.x, Z3.x); + } + + return new SM2P256V1Point(curve, X3, Y3, new ECFieldElement[]{ Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this == b) + return ThreeTimes(); + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECFieldElement Y1 = this.RawYCoord; + if (Y1.IsZero) + return b; + + return Twice().Add(b); + } + + public override ECPoint ThreeTimes() + { + if (this.IsInfinity || this.RawYCoord.IsZero) + return this; + + // NOTE: Be careful about recursions between TwicePlus and ThreeTimes + return Twice().Add(this); + } + + public override ECPoint Negate() + { + if (IsInfinity) + return this; + + return new SM2P256V1Point(Curve, RawXCoord, RawYCoord.Negate(), RawZCoords, IsCompressed); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/gm/SM2P256V1Point.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/gm/SM2P256V1Point.cs.meta new file mode 100644 index 0000000..cbe9cb4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/gm/SM2P256V1Point.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c1921a8a9f4ed384a90643e240bffe0c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec.meta new file mode 100644 index 0000000..945d616 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9824a5c2c72ebd94e96604d5766b93c7 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP128R1Curve.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP128R1Curve.cs new file mode 100644 index 0000000..b4a150c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP128R1Curve.cs @@ -0,0 +1,171 @@ +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP128R1Curve + : AbstractFpCurve + { + public static readonly BigInteger q = SecP128R1FieldElement.Q; + + private const int SECP128R1_DEFAULT_COORDS = COORD_JACOBIAN; + private const int SECP128R1_FE_INTS = 4; + private static readonly ECFieldElement[] SECP128R1_AFFINE_ZS = new ECFieldElement[] { new SecP128R1FieldElement(BigInteger.One) }; + + protected readonly SecP128R1Point m_infinity; + + public SecP128R1Curve() + : base(q) + { + this.m_infinity = new SecP128R1Point(this, null, null); + + this.m_a = FromBigInteger(new BigInteger(1, + Hex.DecodeStrict("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC"))); + this.m_b = FromBigInteger(new BigInteger(1, + Hex.DecodeStrict("E87579C11079F43DD824993C2CEE5ED3"))); + this.m_order = new BigInteger(1, Hex.DecodeStrict("FFFFFFFE0000000075A30D1B9038A115")); + this.m_cofactor = BigInteger.One; + + this.m_coord = SECP128R1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecP128R1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_JACOBIAN: + return true; + default: + return false; + } + } + + public virtual BigInteger Q + { + get { return q; } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return q.BitLength; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecP128R1FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecP128R1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecP128R1Point(this, x, y, zs, withCompression); + } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + uint[] table = new uint[len * SECP128R1_FE_INTS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat128.Copy(((SecP128R1FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECP128R1_FE_INTS; + Nat128.Copy(((SecP128R1FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECP128R1_FE_INTS; + } + } + + return new SecP128R1LookupTable(this, table, len); + } + + public override ECFieldElement RandomFieldElement(SecureRandom r) + { + uint[] x = Nat128.Create(); + SecP128R1Field.Random(r, x); + return new SecP128R1FieldElement(x); + } + + public override ECFieldElement RandomFieldElementMult(SecureRandom r) + { + uint[] x = Nat128.Create(); + SecP128R1Field.RandomMult(r, x); + return new SecP128R1FieldElement(x); + } + + private class SecP128R1LookupTable + : AbstractECLookupTable + { + private readonly SecP128R1Curve m_outer; + private readonly uint[] m_table; + private readonly int m_size; + + internal SecP128R1LookupTable(SecP128R1Curve outer, uint[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public override int Size + { + get { return m_size; } + } + + public override ECPoint Lookup(int index) + { + uint[] x = Nat128.Create(), y = Nat128.Create(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + uint MASK = (uint)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECP128R1_FE_INTS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECP128R1_FE_INTS + j] & MASK; + } + + pos += (SECP128R1_FE_INTS * 2); + } + + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + uint[] x = Nat128.Create(), y = Nat128.Create(); + int pos = index * SECP128R1_FE_INTS * 2; + + for (int j = 0; j < SECP128R1_FE_INTS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECP128R1_FE_INTS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(uint[] x, uint[] y) + { + return m_outer.CreateRawPoint(new SecP128R1FieldElement(x), new SecP128R1FieldElement(y), SECP128R1_AFFINE_ZS, false); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP128R1Curve.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP128R1Curve.cs.meta new file mode 100644 index 0000000..63e3c93 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP128R1Curve.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d45b8940b4d8671408a7fb7d191f37b7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP128R1Field.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP128R1Field.cs new file mode 100644 index 0000000..838f4df --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP128R1Field.cs @@ -0,0 +1,261 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP128R1Field + { + // 2^128 - 2^97 - 1 + internal static readonly uint[] P = new uint[]{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFD }; + private static readonly uint[] PExt = new uint[]{ 0x00000001, 0x00000000, 0x00000000, 0x00000004, 0xFFFFFFFE, + 0xFFFFFFFF, 0x00000003, 0xFFFFFFFC }; + private static readonly uint[] PExtInv = new uint[]{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFB, + 0x00000001, 0x00000000, 0xFFFFFFFC, 0x00000003 }; + private const uint P3 = 0xFFFFFFFD; + private const uint PExt7 = 0xFFFFFFFC; + + public static void Add(uint[] x, uint[] y, uint[] z) + { + uint c = Nat128.Add(x, y, z); + if (c != 0 || (z[3] >= P3 && Nat128.Gte(z, P))) + { + AddPInvTo(z); + } + } + + public static void AddExt(uint[] xx, uint[] yy, uint[] zz) + { + uint c = Nat256.Add(xx, yy, zz); + if (c != 0 || (zz[7] >= PExt7 && Nat256.Gte(zz, PExt))) + { + Nat.AddTo(PExtInv.Length, PExtInv, zz); + } + } + + public static void AddOne(uint[] x, uint[] z) + { + uint c = Nat.Inc(4, x, z); + if (c != 0 || (z[3] >= P3 && Nat128.Gte(z, P))) + { + AddPInvTo(z); + } + } + + public static uint[] FromBigInteger(BigInteger x) + { + uint[] z = Nat.FromBigInteger(128, x); + if (z[3] >= P3 && Nat128.Gte(z, P)) + { + Nat128.SubFrom(P, z); + } + return z; + } + + public static void Half(uint[] x, uint[] z) + { + if ((x[0] & 1) == 0) + { + Nat.ShiftDownBit(4, x, 0, z); + } + else + { + uint c = Nat128.Add(x, P, z); + Nat.ShiftDownBit(4, z, c); + } + } + + public static void Inv(uint[] x, uint[] z) + { + Mod.CheckedModOddInverse(P, x, z); + } + + public static int IsZero(uint[] x) + { + uint d = 0; + for (int i = 0; i < 4; ++i) + { + d |= x[i]; + } + d = (d >> 1) | (d & 1); + return ((int)d - 1) >> 31; + } + + public static void Multiply(uint[] x, uint[] y, uint[] z) + { + uint[] tt = Nat128.CreateExt(); + Nat128.Mul(x, y, tt); + Reduce(tt, z); + } + + public static void MultiplyAddToExt(uint[] x, uint[] y, uint[] zz) + { + uint c = Nat128.MulAddTo(x, y, zz); + if (c != 0 || (zz[7] >= PExt7 && Nat256.Gte(zz, PExt))) + { + Nat.AddTo(PExtInv.Length, PExtInv, zz); + } + } + + public static void Negate(uint[] x, uint[] z) + { + if (0 != IsZero(x)) + { + Nat128.Sub(P, P, z); + } + else + { + Nat128.Sub(P, x, z); + } + } + + public static void Random(SecureRandom r, uint[] z) + { + byte[] bb = new byte[4 * 4]; + do + { + r.NextBytes(bb); + Pack.LE_To_UInt32(bb, 0, z, 0, 4); + } + while (0 == Nat.LessThan(4, z, P)); + } + + public static void RandomMult(SecureRandom r, uint[] z) + { + do + { + Random(r, z); + } + while (0 != IsZero(z)); + } + + public static void Reduce(uint[] xx, uint[] z) + { + ulong x0 = xx[0], x1 = xx[1], x2 = xx[2], x3 = xx[3]; + ulong x4 = xx[4], x5 = xx[5], x6 = xx[6], x7 = xx[7]; + + x3 += x7; x6 += (x7 << 1); + x2 += x6; x5 += (x6 << 1); + x1 += x5; x4 += (x5 << 1); + x0 += x4; x3 += (x4 << 1); + + z[0] = (uint)x0; x1 += (x0 >> 32); + z[1] = (uint)x1; x2 += (x1 >> 32); + z[2] = (uint)x2; x3 += (x2 >> 32); + z[3] = (uint)x3; + + Reduce32((uint)(x3 >> 32), z); + } + + public static void Reduce32(uint x, uint[] z) + { + while (x != 0) + { + ulong c, x4 = x; + + c = (ulong)z[0] + x4; + z[0] = (uint)c; c >>= 32; + if (c != 0) + { + c += (ulong)z[1]; + z[1] = (uint)c; c >>= 32; + c += (ulong)z[2]; + z[2] = (uint)c; c >>= 32; + } + c += (ulong)z[3] + (x4 << 1); + z[3] = (uint)c; c >>= 32; + + Debug.Assert(c >= 0 && c <= 2); + + x = (uint)c; + } + + if (z[3] >= P3 && Nat128.Gte(z, P)) + { + AddPInvTo(z); + } + } + + public static void Square(uint[] x, uint[] z) + { + uint[] tt = Nat128.CreateExt(); + Nat128.Square(x, tt); + Reduce(tt, z); + } + + public static void SquareN(uint[] x, int n, uint[] z) + { + Debug.Assert(n > 0); + + uint[] tt = Nat128.CreateExt(); + Nat128.Square(x, tt); + Reduce(tt, z); + + while (--n > 0) + { + Nat128.Square(z, tt); + Reduce(tt, z); + } + } + + public static void Subtract(uint[] x, uint[] y, uint[] z) + { + int c = Nat128.Sub(x, y, z); + if (c != 0) + { + SubPInvFrom(z); + } + } + + public static void SubtractExt(uint[] xx, uint[] yy, uint[] zz) + { + int c = Nat.Sub(10, xx, yy, zz); + if (c != 0) + { + Nat.SubFrom(PExtInv.Length, PExtInv, zz); + } + } + + public static void Twice(uint[] x, uint[] z) + { + uint c = Nat.ShiftUpBit(4, x, 0, z); + if (c != 0 || (z[3] >= P3 && Nat128.Gte(z, P))) + { + AddPInvTo(z); + } + } + + private static void AddPInvTo(uint[] z) + { + long c = (long)z[0] + 1; + z[0] = (uint)c; c >>= 32; + if (c != 0) + { + c += (long)z[1]; + z[1] = (uint)c; c >>= 32; + c += (long)z[2]; + z[2] = (uint)c; c >>= 32; + } + c += (long)z[3] + 2; + z[3] = (uint)c; + } + + private static void SubPInvFrom(uint[] z) + { + long c = (long)z[0] - 1; + z[0] = (uint)c; c >>= 32; + if (c != 0) + { + c += (long)z[1]; + z[1] = (uint)c; c >>= 32; + c += (long)z[2]; + z[2] = (uint)c; c >>= 32; + } + c += (long)z[3] - 2; + z[3] = (uint)c; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP128R1Field.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP128R1Field.cs.meta new file mode 100644 index 0000000..3c34e5f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP128R1Field.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5bbd105ab2df3b94aaeee4534c9f3fad +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP128R1FieldElement.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP128R1FieldElement.cs new file mode 100644 index 0000000..e9235c2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP128R1FieldElement.cs @@ -0,0 +1,200 @@ +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP128R1FieldElement + : AbstractFpFieldElement + { + public static readonly BigInteger Q = new BigInteger(1, + Hex.DecodeStrict("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF")); + + protected internal readonly uint[] x; + + public SecP128R1FieldElement(BigInteger x) + { + if (x == null || x.SignValue < 0 || x.CompareTo(Q) >= 0) + throw new ArgumentException("value invalid for SecP128R1FieldElement", "x"); + + this.x = SecP128R1Field.FromBigInteger(x); + } + + public SecP128R1FieldElement() + { + this.x = Nat128.Create(); + } + + protected internal SecP128R1FieldElement(uint[] x) + { + this.x = x; + } + + public override bool IsZero + { + get { return Nat128.IsZero(x); } + } + + public override bool IsOne + { + get { return Nat128.IsOne(x); } + } + + public override bool TestBitZero() + { + return Nat128.GetBit(x, 0) == 1; + } + + public override BigInteger ToBigInteger() + { + return Nat128.ToBigInteger(x); + } + + public override string FieldName + { + get { return "SecP128R1Field"; } + } + + public override int FieldSize + { + get { return Q.BitLength; } + } + + public override ECFieldElement Add(ECFieldElement b) + { + uint[] z = Nat128.Create(); + SecP128R1Field.Add(x, ((SecP128R1FieldElement)b).x, z); + return new SecP128R1FieldElement(z); + } + + public override ECFieldElement AddOne() + { + uint[] z = Nat128.Create(); + SecP128R1Field.AddOne(x, z); + return new SecP128R1FieldElement(z); + } + + public override ECFieldElement Subtract(ECFieldElement b) + { + uint[] z = Nat128.Create(); + SecP128R1Field.Subtract(x, ((SecP128R1FieldElement)b).x, z); + return new SecP128R1FieldElement(z); + } + + public override ECFieldElement Multiply(ECFieldElement b) + { + uint[] z = Nat128.Create(); + SecP128R1Field.Multiply(x, ((SecP128R1FieldElement)b).x, z); + return new SecP128R1FieldElement(z); + } + + public override ECFieldElement Divide(ECFieldElement b) + { + // return multiply(b.invert()); + uint[] z = Nat128.Create(); + SecP128R1Field.Inv(((SecP128R1FieldElement)b).x, z); + SecP128R1Field.Multiply(z, x, z); + return new SecP128R1FieldElement(z); + } + + public override ECFieldElement Negate() + { + uint[] z = Nat128.Create(); + SecP128R1Field.Negate(x, z); + return new SecP128R1FieldElement(z); + } + + public override ECFieldElement Square() + { + uint[] z = Nat128.Create(); + SecP128R1Field.Square(x, z); + return new SecP128R1FieldElement(z); + } + + public override ECFieldElement Invert() + { + // return new SecP128R1FieldElement(toBigInteger().modInverse(Q)); + uint[] z = Nat128.Create(); + SecP128R1Field.Inv(x, z); + return new SecP128R1FieldElement(z); + } + + // D.1.4 91 + /** + * return a sqrt root - the routine verifies that the calculation returns the right value - if + * none exists it returns null. + */ + public override ECFieldElement Sqrt() + { + /* + * Raise this element to the exponent 2^126 - 2^95 + * + * Breaking up the exponent's binary representation into "repunits", we get: + * { 31 1s } { 95 0s } + * + * Therefore we need an addition chain containing 31 (the length of the repunit) We use: + * 1, 2, 4, 8, 10, 20, 30, [31] + */ + + uint[] x1 = this.x; + if (Nat128.IsZero(x1) || Nat128.IsOne(x1)) + return this; + + uint[] x2 = Nat128.Create(); + SecP128R1Field.Square(x1, x2); + SecP128R1Field.Multiply(x2, x1, x2); + uint[] x4 = Nat128.Create(); + SecP128R1Field.SquareN(x2, 2, x4); + SecP128R1Field.Multiply(x4, x2, x4); + uint[] x8 = Nat128.Create(); + SecP128R1Field.SquareN(x4, 4, x8); + SecP128R1Field.Multiply(x8, x4, x8); + uint[] x10 = x4; + SecP128R1Field.SquareN(x8, 2, x10); + SecP128R1Field.Multiply(x10, x2, x10); + uint[] x20 = x2; + SecP128R1Field.SquareN(x10, 10, x20); + SecP128R1Field.Multiply(x20, x10, x20); + uint[] x30 = x8; + SecP128R1Field.SquareN(x20, 10, x30); + SecP128R1Field.Multiply(x30, x10, x30); + uint[] x31 = x10; + SecP128R1Field.Square(x30, x31); + SecP128R1Field.Multiply(x31, x1, x31); + + uint[] t1 = x31; + SecP128R1Field.SquareN(t1, 95, t1); + + uint[] t2 = x30; + SecP128R1Field.Square(t1, t2); + + return Nat128.Eq(x1, t2) ? new SecP128R1FieldElement(t1) : null; + } + + public override bool Equals(object obj) + { + return Equals(obj as SecP128R1FieldElement); + } + + public override bool Equals(ECFieldElement other) + { + return Equals(other as SecP128R1FieldElement); + } + + public virtual bool Equals(SecP128R1FieldElement other) + { + if (this == other) + return true; + if (null == other) + return false; + return Nat128.Eq(x, other.x); + } + + public override int GetHashCode() + { + return Q.GetHashCode() ^ Arrays.GetHashCode(x, 0, 4); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP128R1FieldElement.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP128R1FieldElement.cs.meta new file mode 100644 index 0000000..738cc43 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP128R1FieldElement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bc14f0fd837e123498b167a3cbbda7b3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP128R1Point.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP128R1Point.cs new file mode 100644 index 0000000..ae76d3c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP128R1Point.cs @@ -0,0 +1,279 @@ +using System; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP128R1Point + : AbstractFpPoint + { + /** + * Create a point which encodes with point compression. + * + * @param curve + * the curve to use + * @param x + * affine x co-ordinate + * @param y + * affine y co-ordinate + * + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecP128R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * Create a point that encodes with or without point compresion. + * + * @param curve + * the curve to use + * @param x + * affine x co-ordinate + * @param y + * affine y co-ordinate + * @param withCompression + * if true encode with point compression + * + * @deprecated per-point compression property will be removed, refer + * {@link #getEncoded(boolean)} + */ + public SecP128R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecP128R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecP128R1Point(null, AffineXCoord, AffineYCoord); + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + if (this == b) + return Twice(); + + ECCurve curve = this.Curve; + + SecP128R1FieldElement X1 = (SecP128R1FieldElement)this.RawXCoord, Y1 = (SecP128R1FieldElement)this.RawYCoord; + SecP128R1FieldElement X2 = (SecP128R1FieldElement)b.RawXCoord, Y2 = (SecP128R1FieldElement)b.RawYCoord; + + SecP128R1FieldElement Z1 = (SecP128R1FieldElement)this.RawZCoords[0]; + SecP128R1FieldElement Z2 = (SecP128R1FieldElement)b.RawZCoords[0]; + + uint c; + uint[] tt1 = Nat128.CreateExt(); + uint[] t2 = Nat128.Create(); + uint[] t3 = Nat128.Create(); + uint[] t4 = Nat128.Create(); + + bool Z1IsOne = Z1.IsOne; + uint[] U2, S2; + if (Z1IsOne) + { + U2 = X2.x; + S2 = Y2.x; + } + else + { + S2 = t3; + SecP128R1Field.Square(Z1.x, S2); + + U2 = t2; + SecP128R1Field.Multiply(S2, X2.x, U2); + + SecP128R1Field.Multiply(S2, Z1.x, S2); + SecP128R1Field.Multiply(S2, Y2.x, S2); + } + + bool Z2IsOne = Z2.IsOne; + uint[] U1, S1; + if (Z2IsOne) + { + U1 = X1.x; + S1 = Y1.x; + } + else + { + S1 = t4; + SecP128R1Field.Square(Z2.x, S1); + + U1 = tt1; + SecP128R1Field.Multiply(S1, X1.x, U1); + + SecP128R1Field.Multiply(S1, Z2.x, S1); + SecP128R1Field.Multiply(S1, Y1.x, S1); + } + + uint[] H = Nat128.Create(); + SecP128R1Field.Subtract(U1, U2, H); + + uint[] R = t2; + SecP128R1Field.Subtract(S1, S2, R); + + // Check if b == this or b == -this + if (Nat128.IsZero(H)) + { + if (Nat128.IsZero(R)) + { + // this == b, i.e. this must be doubled + return this.Twice(); + } + + // this == -b, i.e. the result is the point at infinity + return curve.Infinity; + } + + uint[] HSquared = t3; + SecP128R1Field.Square(H, HSquared); + + uint[] G = Nat128.Create(); + SecP128R1Field.Multiply(HSquared, H, G); + + uint[] V = t3; + SecP128R1Field.Multiply(HSquared, U1, V); + + SecP128R1Field.Negate(G, G); + Nat128.Mul(S1, G, tt1); + + c = Nat128.AddBothTo(V, V, G); + SecP128R1Field.Reduce32(c, G); + + SecP128R1FieldElement X3 = new SecP128R1FieldElement(t4); + SecP128R1Field.Square(R, X3.x); + SecP128R1Field.Subtract(X3.x, G, X3.x); + + SecP128R1FieldElement Y3 = new SecP128R1FieldElement(G); + SecP128R1Field.Subtract(V, X3.x, Y3.x); + SecP128R1Field.MultiplyAddToExt(Y3.x, R, tt1); + SecP128R1Field.Reduce(tt1, Y3.x); + + SecP128R1FieldElement Z3 = new SecP128R1FieldElement(H); + if (!Z1IsOne) + { + SecP128R1Field.Multiply(Z3.x, Z1.x, Z3.x); + } + if (!Z2IsOne) + { + SecP128R1Field.Multiply(Z3.x, Z2.x, Z3.x); + } + + ECFieldElement[] zs = new ECFieldElement[]{ Z3 }; + + return new SecP128R1Point(curve, X3, Y3, zs, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + SecP128R1FieldElement Y1 = (SecP128R1FieldElement)this.RawYCoord; + if (Y1.IsZero) + return curve.Infinity; + + SecP128R1FieldElement X1 = (SecP128R1FieldElement)this.RawXCoord, Z1 = (SecP128R1FieldElement)this.RawZCoords[0]; + + uint c; + uint[] t1 = Nat128.Create(); + uint[] t2 = Nat128.Create(); + + uint[] Y1Squared = Nat128.Create(); + SecP128R1Field.Square(Y1.x, Y1Squared); + + uint[] T = Nat128.Create(); + SecP128R1Field.Square(Y1Squared, T); + + bool Z1IsOne = Z1.IsOne; + + uint[] Z1Squared = Z1.x; + if (!Z1IsOne) + { + Z1Squared = t2; + SecP128R1Field.Square(Z1.x, Z1Squared); + } + + SecP128R1Field.Subtract(X1.x, Z1Squared, t1); + + uint[] M = t2; + SecP128R1Field.Add(X1.x, Z1Squared, M); + SecP128R1Field.Multiply(M, t1, M); + c = Nat128.AddBothTo(M, M, M); + SecP128R1Field.Reduce32(c, M); + + uint[] S = Y1Squared; + SecP128R1Field.Multiply(Y1Squared, X1.x, S); + c = Nat.ShiftUpBits(4, S, 2, 0); + SecP128R1Field.Reduce32(c, S); + + c = Nat.ShiftUpBits(4, T, 3, 0, t1); + SecP128R1Field.Reduce32(c, t1); + + SecP128R1FieldElement X3 = new SecP128R1FieldElement(T); + SecP128R1Field.Square(M, X3.x); + SecP128R1Field.Subtract(X3.x, S, X3.x); + SecP128R1Field.Subtract(X3.x, S, X3.x); + + SecP128R1FieldElement Y3 = new SecP128R1FieldElement(S); + SecP128R1Field.Subtract(S, X3.x, Y3.x); + SecP128R1Field.Multiply(Y3.x, M, Y3.x); + SecP128R1Field.Subtract(Y3.x, t1, Y3.x); + + SecP128R1FieldElement Z3 = new SecP128R1FieldElement(M); + SecP128R1Field.Twice(Y1.x, Z3.x); + if (!Z1IsOne) + { + SecP128R1Field.Multiply(Z3.x, Z1.x, Z3.x); + } + + return new SecP128R1Point(curve, X3, Y3, new ECFieldElement[]{ Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this == b) + return ThreeTimes(); + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECFieldElement Y1 = this.RawYCoord; + if (Y1.IsZero) + return b; + + return Twice().Add(b); + } + + public override ECPoint ThreeTimes() + { + if (this.IsInfinity || this.RawYCoord.IsZero) + return this; + + // NOTE: Be careful about recursions between twicePlus and threeTimes + return Twice().Add(this); + } + + public override ECPoint Negate() + { + if (IsInfinity) + return this; + + return new SecP128R1Point(Curve, RawXCoord, RawYCoord.Negate(), RawZCoords, IsCompressed); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP128R1Point.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP128R1Point.cs.meta new file mode 100644 index 0000000..6cac681 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP128R1Point.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ef8ff73abca38754a804885f47aa57ef +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160K1Curve.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160K1Curve.cs new file mode 100644 index 0000000..c2c78e4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160K1Curve.cs @@ -0,0 +1,168 @@ +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP160K1Curve + : AbstractFpCurve + { + public static readonly BigInteger q = SecP160R2FieldElement.Q; + + private const int SECP160K1_DEFAULT_COORDS = COORD_JACOBIAN; + private const int SECP160K1_FE_INTS = 5; + private static readonly ECFieldElement[] SECP160K1_AFFINE_ZS = new ECFieldElement[] { new SecP160R2FieldElement(BigInteger.One) }; + + protected readonly SecP160K1Point m_infinity; + + public SecP160K1Curve() + : base(q) + { + this.m_infinity = new SecP160K1Point(this, null, null); + + this.m_a = FromBigInteger(BigInteger.Zero); + this.m_b = FromBigInteger(BigInteger.ValueOf(7)); + this.m_order = new BigInteger(1, Hex.DecodeStrict("0100000000000000000001B8FA16DFAB9ACA16B6B3")); + this.m_cofactor = BigInteger.One; + this.m_coord = SECP160K1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecP160K1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_JACOBIAN: + return true; + default: + return false; + } + } + + public virtual BigInteger Q + { + get { return q; } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return q.BitLength; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecP160R2FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecP160K1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecP160K1Point(this, x, y, zs, withCompression); + } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + uint[] table = new uint[len * SECP160K1_FE_INTS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat160.Copy(((SecP160R2FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECP160K1_FE_INTS; + Nat160.Copy(((SecP160R2FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECP160K1_FE_INTS; + } + } + + return new SecP160K1LookupTable(this, table, len); + } + + public override ECFieldElement RandomFieldElement(SecureRandom r) + { + uint[] x = Nat160.Create(); + SecP160R2Field.Random(r, x); + return new SecP160R2FieldElement(x); + } + + public override ECFieldElement RandomFieldElementMult(SecureRandom r) + { + uint[] x = Nat160.Create(); + SecP160R2Field.RandomMult(r, x); + return new SecP160R2FieldElement(x); + } + + private class SecP160K1LookupTable + : AbstractECLookupTable + { + private readonly SecP160K1Curve m_outer; + private readonly uint[] m_table; + private readonly int m_size; + + internal SecP160K1LookupTable(SecP160K1Curve outer, uint[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public override int Size + { + get { return m_size; } + } + + public override ECPoint Lookup(int index) + { + uint[] x = Nat256.Create(), y = Nat256.Create(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + uint MASK = (uint)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECP160K1_FE_INTS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECP160K1_FE_INTS + j] & MASK; + } + + pos += (SECP160K1_FE_INTS * 2); + } + + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + uint[] x = Nat256.Create(), y = Nat256.Create(); + int pos = index * SECP160K1_FE_INTS * 2; + + for (int j = 0; j < SECP160K1_FE_INTS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECP160K1_FE_INTS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(uint[] x, uint[] y) + { + return m_outer.CreateRawPoint(new SecP160R2FieldElement(x), new SecP160R2FieldElement(y), SECP160K1_AFFINE_ZS, false); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160K1Curve.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160K1Curve.cs.meta new file mode 100644 index 0000000..565b457 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160K1Curve.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 976ebe15d6209b746adfde485d66fa87 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160K1Point.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160K1Point.cs new file mode 100644 index 0000000..1bcbadb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160K1Point.cs @@ -0,0 +1,269 @@ +using System; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP160K1Point + : AbstractFpPoint + { + /** + * Create a point which encodes with point compression. + * + * @param curve + * the curve to use + * @param x + * affine x co-ordinate + * @param y + * affine y co-ordinate + * + * @deprecated Use ECCurve.CreatePoint to construct points + */ + public SecP160K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * Create a point that encodes with or without point compresion. + * + * @param curve + * the curve to use + * @param x + * affine x co-ordinate + * @param y + * affine y co-ordinate + * @param withCompression + * if true encode with point compression + * + * @deprecated per-point compression property will be removed, refer + * {@link #getEncoded(bool)} + */ + public SecP160K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecP160K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, + bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecP160K1Point(null, AffineXCoord, AffineYCoord); + } + + // B.3 pg 62 + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + if (this == b) + return Twice(); + + ECCurve curve = this.Curve; + + SecP160R2FieldElement X1 = (SecP160R2FieldElement)this.RawXCoord, Y1 = (SecP160R2FieldElement)this.RawYCoord; + SecP160R2FieldElement X2 = (SecP160R2FieldElement)b.RawXCoord, Y2 = (SecP160R2FieldElement)b.RawYCoord; + + SecP160R2FieldElement Z1 = (SecP160R2FieldElement)this.RawZCoords[0]; + SecP160R2FieldElement Z2 = (SecP160R2FieldElement)b.RawZCoords[0]; + + uint c; + uint[] tt1 = Nat160.CreateExt(); + uint[] t2 = Nat160.Create(); + uint[] t3 = Nat160.Create(); + uint[] t4 = Nat160.Create(); + + bool Z1IsOne = Z1.IsOne; + uint[] U2, S2; + if (Z1IsOne) + { + U2 = X2.x; + S2 = Y2.x; + } + else + { + S2 = t3; + SecP160R2Field.Square(Z1.x, S2); + + U2 = t2; + SecP160R2Field.Multiply(S2, X2.x, U2); + + SecP160R2Field.Multiply(S2, Z1.x, S2); + SecP160R2Field.Multiply(S2, Y2.x, S2); + } + + bool Z2IsOne = Z2.IsOne; + uint[] U1, S1; + if (Z2IsOne) + { + U1 = X1.x; + S1 = Y1.x; + } + else + { + S1 = t4; + SecP160R2Field.Square(Z2.x, S1); + + U1 = tt1; + SecP160R2Field.Multiply(S1, X1.x, U1); + + SecP160R2Field.Multiply(S1, Z2.x, S1); + SecP160R2Field.Multiply(S1, Y1.x, S1); + } + + uint[] H = Nat160.Create(); + SecP160R2Field.Subtract(U1, U2, H); + + uint[] R = t2; + SecP160R2Field.Subtract(S1, S2, R); + + // Check if b == this or b == -this + if (Nat160.IsZero(H)) + { + if (Nat160.IsZero(R)) + { + // this == b, i.e. this must be doubled + return this.Twice(); + } + + // this == -b, i.e. the result is the point at infinity + return curve.Infinity; + } + + uint[] HSquared = t3; + SecP160R2Field.Square(H, HSquared); + + uint[] G = Nat160.Create(); + SecP160R2Field.Multiply(HSquared, H, G); + + uint[] V = t3; + SecP160R2Field.Multiply(HSquared, U1, V); + + SecP160R2Field.Negate(G, G); + Nat160.Mul(S1, G, tt1); + + c = Nat160.AddBothTo(V, V, G); + SecP160R2Field.Reduce32(c, G); + + SecP160R2FieldElement X3 = new SecP160R2FieldElement(t4); + SecP160R2Field.Square(R, X3.x); + SecP160R2Field.Subtract(X3.x, G, X3.x); + + SecP160R2FieldElement Y3 = new SecP160R2FieldElement(G); + SecP160R2Field.Subtract(V, X3.x, Y3.x); + SecP160R2Field.MultiplyAddToExt(Y3.x, R, tt1); + SecP160R2Field.Reduce(tt1, Y3.x); + + SecP160R2FieldElement Z3 = new SecP160R2FieldElement(H); + if (!Z1IsOne) + { + SecP160R2Field.Multiply(Z3.x, Z1.x, Z3.x); + } + if (!Z2IsOne) + { + SecP160R2Field.Multiply(Z3.x, Z2.x, Z3.x); + } + + ECFieldElement[] zs = new ECFieldElement[] { Z3 }; + + return new SecP160K1Point(curve, X3, Y3, zs, IsCompressed); + } + + // B.3 pg 62 + public override ECPoint Twice() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + SecP160R2FieldElement Y1 = (SecP160R2FieldElement)this.RawYCoord; + if (Y1.IsZero) + return curve.Infinity; + + SecP160R2FieldElement X1 = (SecP160R2FieldElement)this.RawXCoord, Z1 = (SecP160R2FieldElement)this.RawZCoords[0]; + + uint c; + + uint[] Y1Squared = Nat160.Create(); + SecP160R2Field.Square(Y1.x, Y1Squared); + + uint[] T = Nat160.Create(); + SecP160R2Field.Square(Y1Squared, T); + + uint[] M = Nat160.Create(); + SecP160R2Field.Square(X1.x, M); + c = Nat160.AddBothTo(M, M, M); + SecP160R2Field.Reduce32(c, M); + + uint[] S = Y1Squared; + SecP160R2Field.Multiply(Y1Squared, X1.x, S); + c = Nat.ShiftUpBits(5, S, 2, 0); + SecP160R2Field.Reduce32(c, S); + + uint[] t1 = Nat160.Create(); + c = Nat.ShiftUpBits(5, T, 3, 0, t1); + SecP160R2Field.Reduce32(c, t1); + + SecP160R2FieldElement X3 = new SecP160R2FieldElement(T); + SecP160R2Field.Square(M, X3.x); + SecP160R2Field.Subtract(X3.x, S, X3.x); + SecP160R2Field.Subtract(X3.x, S, X3.x); + + SecP160R2FieldElement Y3 = new SecP160R2FieldElement(S); + SecP160R2Field.Subtract(S, X3.x, Y3.x); + SecP160R2Field.Multiply(Y3.x, M, Y3.x); + SecP160R2Field.Subtract(Y3.x, t1, Y3.x); + + SecP160R2FieldElement Z3 = new SecP160R2FieldElement(M); + SecP160R2Field.Twice(Y1.x, Z3.x); + if (!Z1.IsOne) + { + SecP160R2Field.Multiply(Z3.x, Z1.x, Z3.x); + } + + return new SecP160K1Point(curve, X3, Y3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this == b) + return ThreeTimes(); + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECFieldElement Y1 = this.RawYCoord; + if (Y1.IsZero) + return b; + + return Twice().Add(b); + } + + public override ECPoint ThreeTimes() + { + if (this.IsInfinity || this.RawYCoord.IsZero) + return this; + + // NOTE: Be careful about recursions between TwicePlus and threeTimes + return Twice().Add(this); + } + + public override ECPoint Negate() + { + if (IsInfinity) + return this; + + return new SecP160K1Point(Curve, this.RawXCoord, this.RawYCoord.Negate(), this.RawZCoords, IsCompressed); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160K1Point.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160K1Point.cs.meta new file mode 100644 index 0000000..f3294aa --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160K1Point.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 26d9afbcc19634f41820ec499ccae9ce +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160R1Curve.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160R1Curve.cs new file mode 100644 index 0000000..8ae519a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160R1Curve.cs @@ -0,0 +1,171 @@ +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP160R1Curve + : AbstractFpCurve + { + public static readonly BigInteger q = SecP160R1FieldElement.Q; + + private const int SECP160R1_DEFAULT_COORDS = COORD_JACOBIAN; + private const int SECP160R1_FE_INTS = 5; + private static readonly ECFieldElement[] SECP160R1_AFFINE_ZS = new ECFieldElement[] { new SecP160R1FieldElement(BigInteger.One) }; + + protected readonly SecP160R1Point m_infinity; + + public SecP160R1Curve() + : base(q) + { + this.m_infinity = new SecP160R1Point(this, null, null); + + this.m_a = FromBigInteger(new BigInteger(1, + Hex.DecodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC"))); + this.m_b = FromBigInteger(new BigInteger(1, + Hex.DecodeStrict("1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45"))); + this.m_order = new BigInteger(1, Hex.DecodeStrict("0100000000000000000001F4C8F927AED3CA752257")); + this.m_cofactor = BigInteger.One; + + this.m_coord = SECP160R1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecP160R1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_JACOBIAN: + return true; + default: + return false; + } + } + + public virtual BigInteger Q + { + get { return q; } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return q.BitLength; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecP160R1FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecP160R1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecP160R1Point(this, x, y, zs, withCompression); + } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + uint[] table = new uint[len * SECP160R1_FE_INTS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat160.Copy(((SecP160R1FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECP160R1_FE_INTS; + Nat160.Copy(((SecP160R1FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECP160R1_FE_INTS; + } + } + + return new SecP160R1LookupTable(this, table, len); + } + + public override ECFieldElement RandomFieldElement(SecureRandom r) + { + uint[] x = Nat160.Create(); + SecP160R1Field.Random(r, x); + return new SecP160R1FieldElement(x); + } + + public override ECFieldElement RandomFieldElementMult(SecureRandom r) + { + uint[] x = Nat160.Create(); + SecP160R1Field.RandomMult(r, x); + return new SecP160R1FieldElement(x); + } + + private class SecP160R1LookupTable + : AbstractECLookupTable + { + private readonly SecP160R1Curve m_outer; + private readonly uint[] m_table; + private readonly int m_size; + + internal SecP160R1LookupTable(SecP160R1Curve outer, uint[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public override int Size + { + get { return m_size; } + } + + public override ECPoint Lookup(int index) + { + uint[] x = Nat160.Create(), y = Nat160.Create(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + uint MASK = (uint)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECP160R1_FE_INTS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECP160R1_FE_INTS + j] & MASK; + } + + pos += (SECP160R1_FE_INTS * 2); + } + + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + uint[] x = Nat160.Create(), y = Nat160.Create(); + int pos = index * SECP160R1_FE_INTS * 2; + + for (int j = 0; j < SECP160R1_FE_INTS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECP160R1_FE_INTS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(uint[] x, uint[] y) + { + return m_outer.CreateRawPoint(new SecP160R1FieldElement(x), new SecP160R1FieldElement(y), SECP160R1_AFFINE_ZS, false); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160R1Curve.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160R1Curve.cs.meta new file mode 100644 index 0000000..8347f3a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160R1Curve.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6bdf5e87e1dd1924a8f73f973e2de259 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160R1Field.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160R1Field.cs new file mode 100644 index 0000000..f4b1e2a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160R1Field.cs @@ -0,0 +1,224 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP160R1Field + { + // 2^160 - 2^31 - 1 + internal static readonly uint[] P = new uint[]{ 0x7FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; + private static readonly uint[] PExt = new uint[]{ 0x00000001, 0x40000001, 0x00000000, 0x00000000, 0x00000000, + 0xFFFFFFFE, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; + private static readonly uint[] PExtInv = new uint[]{ 0xFFFFFFFF, 0xBFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0x00000001, 0x00000001 }; + private const uint P4 = 0xFFFFFFFF; + private const uint PExt9 = 0xFFFFFFFF; + private const uint PInv = 0x80000001; + + public static void Add(uint[] x, uint[] y, uint[] z) + { + uint c = Nat160.Add(x, y, z); + if (c != 0 || (z[4] == P4 && Nat160.Gte(z, P))) + { + Nat.AddWordTo(5, PInv, z); + } + } + + public static void AddExt(uint[] xx, uint[] yy, uint[] zz) + { + uint c = Nat.Add(10, xx, yy, zz); + if (c != 0 || (zz[9] == PExt9 && Nat.Gte(10, zz, PExt))) + { + if (Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0) + { + Nat.IncAt(10, zz, PExtInv.Length); + } + } + } + + public static void AddOne(uint[] x, uint[] z) + { + uint c = Nat.Inc(5, x, z); + if (c != 0 || (z[4] == P4 && Nat160.Gte(z, P))) + { + Nat.AddWordTo(5, PInv, z); + } + } + + public static uint[] FromBigInteger(BigInteger x) + { + uint[] z = Nat.FromBigInteger(160, x); + if (z[4] == P4 && Nat160.Gte(z, P)) + { + Nat160.SubFrom(P, z); + } + return z; + } + + public static void Half(uint[] x, uint[] z) + { + if ((x[0] & 1) == 0) + { + Nat.ShiftDownBit(5, x, 0, z); + } + else + { + uint c = Nat160.Add(x, P, z); + Nat.ShiftDownBit(5, z, c); + } + } + + public static void Inv(uint[] x, uint[] z) + { + Mod.CheckedModOddInverse(P, x, z); + } + + public static int IsZero(uint[] x) + { + uint d = 0; + for (int i = 0; i < 5; ++i) + { + d |= x[i]; + } + d = (d >> 1) | (d & 1); + return ((int)d - 1) >> 31; + } + + public static void Multiply(uint[] x, uint[] y, uint[] z) + { + uint[] tt = Nat160.CreateExt(); + Nat160.Mul(x, y, tt); + Reduce(tt, z); + } + + public static void MultiplyAddToExt(uint[] x, uint[] y, uint[] zz) + { + uint c = Nat160.MulAddTo(x, y, zz); + if (c != 0 || (zz[9] == PExt9 && Nat.Gte(10, zz, PExt))) + { + if (Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0) + { + Nat.IncAt(10, zz, PExtInv.Length); + } + } + } + + public static void Negate(uint[] x, uint[] z) + { + if (0 != IsZero(x)) + { + Nat160.Sub(P, P, z); + } + else + { + Nat160.Sub(P, x, z); + } + } + + public static void Random(SecureRandom r, uint[] z) + { + byte[] bb = new byte[5 * 4]; + do + { + r.NextBytes(bb); + Pack.LE_To_UInt32(bb, 0, z, 0, 5); + } + while (0 == Nat.LessThan(5, z, P)); + } + + public static void RandomMult(SecureRandom r, uint[] z) + { + do + { + Random(r, z); + } + while (0 != IsZero(z)); + } + + public static void Reduce(uint[] xx, uint[] z) + { + ulong x5 = xx[5], x6 = xx[6], x7 = xx[7], x8 = xx[8], x9 = xx[9]; + + ulong c = 0; + c += (ulong)xx[0] + x5 + (x5 << 31); + z[0] = (uint)c; c >>= 32; + c += (ulong)xx[1] + x6 + (x6 << 31); + z[1] = (uint)c; c >>= 32; + c += (ulong)xx[2] + x7 + (x7 << 31); + z[2] = (uint)c; c >>= 32; + c += (ulong)xx[3] + x8 + (x8 << 31); + z[3] = (uint)c; c >>= 32; + c += (ulong)xx[4] + x9 + (x9 << 31); + z[4] = (uint)c; c >>= 32; + + Debug.Assert(c >> 32 == 0); + + Reduce32((uint)c, z); + } + + public static void Reduce32(uint x, uint[] z) + { + if ((x != 0 && Nat160.MulWordsAdd(PInv, x, z, 0) != 0) + || (z[4] == P4 && Nat160.Gte(z, P))) + { + Nat.AddWordTo(5, PInv, z); + } + } + + public static void Square(uint[] x, uint[] z) + { + uint[] tt = Nat160.CreateExt(); + Nat160.Square(x, tt); + Reduce(tt, z); + } + + public static void SquareN(uint[] x, int n, uint[] z) + { + Debug.Assert(n > 0); + + uint[] tt = Nat160.CreateExt(); + Nat160.Square(x, tt); + Reduce(tt, z); + + while (--n > 0) + { + Nat160.Square(z, tt); + Reduce(tt, z); + } + } + + public static void Subtract(uint[] x, uint[] y, uint[] z) + { + int c = Nat160.Sub(x, y, z); + if (c != 0) + { + Nat.SubWordFrom(5, PInv, z); + } + } + + public static void SubtractExt(uint[] xx, uint[] yy, uint[] zz) + { + int c = Nat.Sub(10, xx, yy, zz); + if (c != 0) + { + if (Nat.SubFrom(PExtInv.Length, PExtInv, zz) != 0) + { + Nat.DecAt(10, zz, PExtInv.Length); + } + } + } + + public static void Twice(uint[] x, uint[] z) + { + uint c = Nat.ShiftUpBit(5, x, 0, z); + if (c != 0 || (z[4] == P4 && Nat160.Gte(z, P))) + { + Nat.AddWordTo(5, PInv, z); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160R1Field.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160R1Field.cs.meta new file mode 100644 index 0000000..ca45386 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160R1Field.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 07ae4e46487b50b4495c17c05b5fd0f3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160R1FieldElement.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160R1FieldElement.cs new file mode 100644 index 0000000..4876faf --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160R1FieldElement.cs @@ -0,0 +1,205 @@ +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP160R1FieldElement + : AbstractFpFieldElement + { + public static readonly BigInteger Q = new BigInteger(1, + Hex.DecodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF")); + + protected internal readonly uint[] x; + + public SecP160R1FieldElement(BigInteger x) + { + if (x == null || x.SignValue < 0 || x.CompareTo(Q) >= 0) + throw new ArgumentException("value invalid for SecP160R1FieldElement", "x"); + + this.x = SecP160R1Field.FromBigInteger(x); + } + + public SecP160R1FieldElement() + { + this.x = Nat160.Create(); + } + + protected internal SecP160R1FieldElement(uint[] x) + { + this.x = x; + } + + public override bool IsZero + { + get { return Nat160.IsZero(x); } + } + + public override bool IsOne + { + get { return Nat160.IsOne(x); } + } + + public override bool TestBitZero() + { + return Nat160.GetBit(x, 0) == 1; + } + + public override BigInteger ToBigInteger() + { + return Nat160.ToBigInteger(x); + } + + public override string FieldName + { + get { return "SecP160R1Field"; } + } + + public override int FieldSize + { + get { return Q.BitLength; } + } + + public override ECFieldElement Add(ECFieldElement b) + { + uint[] z = Nat160.Create(); + SecP160R1Field.Add(x, ((SecP160R1FieldElement)b).x, z); + return new SecP160R1FieldElement(z); + } + + public override ECFieldElement AddOne() + { + uint[] z = Nat160.Create(); + SecP160R1Field.AddOne(x, z); + return new SecP160R1FieldElement(z); + } + + public override ECFieldElement Subtract(ECFieldElement b) + { + uint[] z = Nat160.Create(); + SecP160R1Field.Subtract(x, ((SecP160R1FieldElement)b).x, z); + return new SecP160R1FieldElement(z); + } + + public override ECFieldElement Multiply(ECFieldElement b) + { + uint[] z = Nat160.Create(); + SecP160R1Field.Multiply(x, ((SecP160R1FieldElement)b).x, z); + return new SecP160R1FieldElement(z); + } + + public override ECFieldElement Divide(ECFieldElement b) + { + // return multiply(b.invert()); + uint[] z = Nat160.Create(); + SecP160R1Field.Inv(((SecP160R1FieldElement)b).x, z); + SecP160R1Field.Multiply(z, x, z); + return new SecP160R1FieldElement(z); + } + + public override ECFieldElement Negate() + { + uint[] z = Nat160.Create(); + SecP160R1Field.Negate(x, z); + return new SecP160R1FieldElement(z); + } + + public override ECFieldElement Square() + { + uint[] z = Nat160.Create(); + SecP160R1Field.Square(x, z); + return new SecP160R1FieldElement(z); + } + + public override ECFieldElement Invert() + { + // return new SecP160R1FieldElement(ToBigInteger().modInverse(Q)); + uint[] z = Nat160.Create(); + SecP160R1Field.Inv(x, z); + return new SecP160R1FieldElement(z); + } + + // D.1.4 91 + /** + * return a sqrt root - the routine verifies that the calculation returns the right value - if + * none exists it returns null. + */ + public override ECFieldElement Sqrt() + { + /* + * Raise this element to the exponent 2^158 - 2^29 + * + * Breaking up the exponent's binary representation into "repunits", we get: + * { 129 1s } { 29 0s } + * + * Therefore we need an addition chain containing 129 (the length of the repunit) We use: + * 1, 2, 4, 8, 16, 32, 64, 128, [129] + */ + + uint[] x1 = this.x; + if (Nat160.IsZero(x1) || Nat160.IsOne(x1)) + { + return this; + } + + uint[] x2 = Nat160.Create(); + SecP160R1Field.Square(x1, x2); + SecP160R1Field.Multiply(x2, x1, x2); + uint[] x4 = Nat160.Create(); + SecP160R1Field.SquareN(x2, 2, x4); + SecP160R1Field.Multiply(x4, x2, x4); + uint[] x8 = x2; + SecP160R1Field.SquareN(x4, 4, x8); + SecP160R1Field.Multiply(x8, x4, x8); + uint[] x16 = x4; + SecP160R1Field.SquareN(x8, 8, x16); + SecP160R1Field.Multiply(x16, x8, x16); + uint[] x32 = x8; + SecP160R1Field.SquareN(x16, 16, x32); + SecP160R1Field.Multiply(x32, x16, x32); + uint[] x64 = x16; + SecP160R1Field.SquareN(x32, 32, x64); + SecP160R1Field.Multiply(x64, x32, x64); + uint[] x128 = x32; + SecP160R1Field.SquareN(x64, 64, x128); + SecP160R1Field.Multiply(x128, x64, x128); + uint[] x129 = x64; + SecP160R1Field.Square(x128, x129); + SecP160R1Field.Multiply(x129, x1, x129); + + uint[] t1 = x129; + SecP160R1Field.SquareN(t1, 29, t1); + + uint[] t2 = x128; + SecP160R1Field.Square(t1, t2); + + return Nat160.Eq(x1, t2) ? new SecP160R1FieldElement(t1) : null; + } + + public override bool Equals(object obj) + { + return Equals(obj as SecP160R1FieldElement); + } + + public override bool Equals(ECFieldElement other) + { + return Equals(other as SecP160R1FieldElement); + } + + public virtual bool Equals(SecP160R1FieldElement other) + { + if (this == other) + return true; + if (null == other) + return false; + return Nat160.Eq(x, other.x); + } + + public override int GetHashCode() + { + return Q.GetHashCode() ^ Arrays.GetHashCode(x, 0, 5); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160R1FieldElement.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160R1FieldElement.cs.meta new file mode 100644 index 0000000..4f167c2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160R1FieldElement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 59c72492d414dbd4c8276ccadfd972b6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160R1Point.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160R1Point.cs new file mode 100644 index 0000000..f9f065d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160R1Point.cs @@ -0,0 +1,279 @@ +using System; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP160R1Point + : AbstractFpPoint + { + /** + * Create a point which encodes with point compression. + * + * @param curve + * the curve to use + * @param x + * affine x co-ordinate + * @param y + * affine y co-ordinate + * + * @deprecated Use ECCurve.CreatePoint to construct points + */ + public SecP160R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * Create a point that encodes with or without point compresion. + * + * @param curve + * the curve to use + * @param x + * affine x co-ordinate + * @param y + * affine y co-ordinate + * @param withCompression + * if true encode with point compression + * + * @deprecated per-point compression property will be removed, refer + * {@link #getEncoded(bool)} + */ + public SecP160R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecP160R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecP160R1Point(null, AffineXCoord, AffineYCoord); + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + if (this == b) + return Twice(); + + ECCurve curve = this.Curve; + + SecP160R1FieldElement X1 = (SecP160R1FieldElement)this.RawXCoord, Y1 = (SecP160R1FieldElement)this.RawYCoord; + SecP160R1FieldElement X2 = (SecP160R1FieldElement)b.RawXCoord, Y2 = (SecP160R1FieldElement)b.RawYCoord; + + SecP160R1FieldElement Z1 = (SecP160R1FieldElement)this.RawZCoords[0]; + SecP160R1FieldElement Z2 = (SecP160R1FieldElement)b.RawZCoords[0]; + + uint c; + uint[] tt1 = Nat160.CreateExt(); + uint[] t2 = Nat160.Create(); + uint[] t3 = Nat160.Create(); + uint[] t4 = Nat160.Create(); + + bool Z1IsOne = Z1.IsOne; + uint[] U2, S2; + if (Z1IsOne) + { + U2 = X2.x; + S2 = Y2.x; + } + else + { + S2 = t3; + SecP160R1Field.Square(Z1.x, S2); + + U2 = t2; + SecP160R1Field.Multiply(S2, X2.x, U2); + + SecP160R1Field.Multiply(S2, Z1.x, S2); + SecP160R1Field.Multiply(S2, Y2.x, S2); + } + + bool Z2IsOne = Z2.IsOne; + uint[] U1, S1; + if (Z2IsOne) + { + U1 = X1.x; + S1 = Y1.x; + } + else + { + S1 = t4; + SecP160R1Field.Square(Z2.x, S1); + + U1 = tt1; + SecP160R1Field.Multiply(S1, X1.x, U1); + + SecP160R1Field.Multiply(S1, Z2.x, S1); + SecP160R1Field.Multiply(S1, Y1.x, S1); + } + + uint[] H = Nat160.Create(); + SecP160R1Field.Subtract(U1, U2, H); + + uint[] R = t2; + SecP160R1Field.Subtract(S1, S2, R); + + // Check if b == this or b == -this + if (Nat160.IsZero(H)) + { + if (Nat160.IsZero(R)) + { + // this == b, i.e. this must be doubled + return this.Twice(); + } + + // this == -b, i.e. the result is the point at infinity + return curve.Infinity; + } + + uint[] HSquared = t3; + SecP160R1Field.Square(H, HSquared); + + uint[] G = Nat160.Create(); + SecP160R1Field.Multiply(HSquared, H, G); + + uint[] V = t3; + SecP160R1Field.Multiply(HSquared, U1, V); + + SecP160R1Field.Negate(G, G); + Nat160.Mul(S1, G, tt1); + + c = Nat160.AddBothTo(V, V, G); + SecP160R1Field.Reduce32(c, G); + + SecP160R1FieldElement X3 = new SecP160R1FieldElement(t4); + SecP160R1Field.Square(R, X3.x); + SecP160R1Field.Subtract(X3.x, G, X3.x); + + SecP160R1FieldElement Y3 = new SecP160R1FieldElement(G); + SecP160R1Field.Subtract(V, X3.x, Y3.x); + SecP160R1Field.MultiplyAddToExt(Y3.x, R, tt1); + SecP160R1Field.Reduce(tt1, Y3.x); + + SecP160R1FieldElement Z3 = new SecP160R1FieldElement(H); + if (!Z1IsOne) + { + SecP160R1Field.Multiply(Z3.x, Z1.x, Z3.x); + } + if (!Z2IsOne) + { + SecP160R1Field.Multiply(Z3.x, Z2.x, Z3.x); + } + + ECFieldElement[] zs = new ECFieldElement[]{ Z3 }; + + return new SecP160R1Point(curve, X3, Y3, zs, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + SecP160R1FieldElement Y1 = (SecP160R1FieldElement)this.RawYCoord; + if (Y1.IsZero) + return curve.Infinity; + + SecP160R1FieldElement X1 = (SecP160R1FieldElement)this.RawXCoord, Z1 = (SecP160R1FieldElement)this.RawZCoords[0]; + + uint c; + uint[] t1 = Nat160.Create(); + uint[] t2 = Nat160.Create(); + + uint[] Y1Squared = Nat160.Create(); + SecP160R1Field.Square(Y1.x, Y1Squared); + + uint[] T = Nat160.Create(); + SecP160R1Field.Square(Y1Squared, T); + + bool Z1IsOne = Z1.IsOne; + + uint[] Z1Squared = Z1.x; + if (!Z1IsOne) + { + Z1Squared = t2; + SecP160R1Field.Square(Z1.x, Z1Squared); + } + + SecP160R1Field.Subtract(X1.x, Z1Squared, t1); + + uint[] M = t2; + SecP160R1Field.Add(X1.x, Z1Squared, M); + SecP160R1Field.Multiply(M, t1, M); + c = Nat160.AddBothTo(M, M, M); + SecP160R1Field.Reduce32(c, M); + + uint[] S = Y1Squared; + SecP160R1Field.Multiply(Y1Squared, X1.x, S); + c = Nat.ShiftUpBits(5, S, 2, 0); + SecP160R1Field.Reduce32(c, S); + + c = Nat.ShiftUpBits(5, T, 3, 0, t1); + SecP160R1Field.Reduce32(c, t1); + + SecP160R1FieldElement X3 = new SecP160R1FieldElement(T); + SecP160R1Field.Square(M, X3.x); + SecP160R1Field.Subtract(X3.x, S, X3.x); + SecP160R1Field.Subtract(X3.x, S, X3.x); + + SecP160R1FieldElement Y3 = new SecP160R1FieldElement(S); + SecP160R1Field.Subtract(S, X3.x, Y3.x); + SecP160R1Field.Multiply(Y3.x, M, Y3.x); + SecP160R1Field.Subtract(Y3.x, t1, Y3.x); + + SecP160R1FieldElement Z3 = new SecP160R1FieldElement(M); + SecP160R1Field.Twice(Y1.x, Z3.x); + if (!Z1IsOne) + { + SecP160R1Field.Multiply(Z3.x, Z1.x, Z3.x); + } + + return new SecP160R1Point(curve, X3, Y3, new ECFieldElement[]{ Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this == b) + return ThreeTimes(); + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECFieldElement Y1 = this.RawYCoord; + if (Y1.IsZero) + return b; + + return Twice().Add(b); + } + + public override ECPoint ThreeTimes() + { + if (this.IsInfinity || this.RawYCoord.IsZero) + return this; + + // NOTE: Be careful about recursions between TwicePlus and ThreeTimes + return Twice().Add(this); + } + + public override ECPoint Negate() + { + if (IsInfinity) + return this; + + return new SecP160R1Point(Curve, RawXCoord, RawYCoord.Negate(), RawZCoords, IsCompressed); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160R1Point.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160R1Point.cs.meta new file mode 100644 index 0000000..b6b1510 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160R1Point.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2e981a7502104174190271ac1f7228a3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160R2Curve.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160R2Curve.cs new file mode 100644 index 0000000..49c3fa3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160R2Curve.cs @@ -0,0 +1,171 @@ +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP160R2Curve + : AbstractFpCurve + { + public static readonly BigInteger q = SecP160R2FieldElement.Q; + + private const int SECP160R2_DEFAULT_COORDS = COORD_JACOBIAN; + private const int SECP160R2_FE_INTS = 5; + private static readonly ECFieldElement[] SECP160R2_AFFINE_ZS = new ECFieldElement[] { new SecP160R2FieldElement(BigInteger.One) }; + + protected readonly SecP160R2Point m_infinity; + + public SecP160R2Curve() + : base(q) + { + this.m_infinity = new SecP160R2Point(this, null, null); + + this.m_a = FromBigInteger(new BigInteger(1, + Hex.DecodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70"))); + this.m_b = FromBigInteger(new BigInteger(1, + Hex.DecodeStrict("B4E134D3FB59EB8BAB57274904664D5AF50388BA"))); + this.m_order = new BigInteger(1, Hex.DecodeStrict("0100000000000000000000351EE786A818F3A1A16B")); + this.m_cofactor = BigInteger.One; + + this.m_coord = SECP160R2_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecP160R2Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_JACOBIAN: + return true; + default: + return false; + } + } + + public virtual BigInteger Q + { + get { return q; } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return q.BitLength; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecP160R2FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecP160R2Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecP160R2Point(this, x, y, zs, withCompression); + } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + uint[] table = new uint[len * SECP160R2_FE_INTS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat160.Copy(((SecP160R2FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECP160R2_FE_INTS; + Nat160.Copy(((SecP160R2FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECP160R2_FE_INTS; + } + } + + return new SecP160R2LookupTable(this, table, len); + } + + public override ECFieldElement RandomFieldElement(SecureRandom r) + { + uint[] x = Nat160.Create(); + SecP160R2Field.Random(r, x); + return new SecP160R2FieldElement(x); + } + + public override ECFieldElement RandomFieldElementMult(SecureRandom r) + { + uint[] x = Nat160.Create(); + SecP160R2Field.RandomMult(r, x); + return new SecP160R2FieldElement(x); + } + + private class SecP160R2LookupTable + : AbstractECLookupTable + { + private readonly SecP160R2Curve m_outer; + private readonly uint[] m_table; + private readonly int m_size; + + internal SecP160R2LookupTable(SecP160R2Curve outer, uint[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public override int Size + { + get { return m_size; } + } + + public override ECPoint Lookup(int index) + { + uint[] x = Nat160.Create(), y = Nat160.Create(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + uint MASK = (uint)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECP160R2_FE_INTS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECP160R2_FE_INTS + j] & MASK; + } + + pos += (SECP160R2_FE_INTS * 2); + } + + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + uint[] x = Nat160.Create(), y = Nat160.Create(); + int pos = index * SECP160R2_FE_INTS * 2; + + for (int j = 0; j < SECP160R2_FE_INTS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECP160R2_FE_INTS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(uint[] x, uint[] y) + { + return m_outer.CreateRawPoint(new SecP160R2FieldElement(x), new SecP160R2FieldElement(y), SECP160R2_AFFINE_ZS, false); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160R2Curve.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160R2Curve.cs.meta new file mode 100644 index 0000000..66b82c0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160R2Curve.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 42fbcae0ad887eb4a8b08a0af25e0d6e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160R2Field.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160R2Field.cs new file mode 100644 index 0000000..9ad5943 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160R2Field.cs @@ -0,0 +1,216 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP160R2Field + { + // 2^160 - 2^32 - 2^14 - 2^12 - 2^9 - 2^8 - 2^7 - 2^3 - 2^2 - 1 + internal static readonly uint[] P = new uint[]{ 0xFFFFAC73, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; + private static readonly uint[] PExt = new uint[]{ 0x1B44BBA9, 0x0000A71A, 0x00000001, 0x00000000, 0x00000000, + 0xFFFF58E6, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; + private static readonly uint[] PExtInv = new uint[]{ 0xE4BB4457, 0xFFFF58E5, 0xFFFFFFFE, 0xFFFFFFFF, + 0xFFFFFFFF, 0x0000A719, 0x00000002 }; + private const uint P4 = 0xFFFFFFFF; + private const uint PExt9 = 0xFFFFFFFF; + private const uint PInv33 = 0x538D; + + public static void Add(uint[] x, uint[] y, uint[] z) + { + uint c = Nat160.Add(x, y, z); + if (c != 0 || (z[4] == P4 && Nat160.Gte(z, P))) + { + Nat.Add33To(5, PInv33, z); + } + } + + public static void AddExt(uint[] xx, uint[] yy, uint[] zz) + { + uint c = Nat.Add(10, xx, yy, zz); + if (c != 0 || (zz[9] == PExt9 && Nat.Gte(10, zz, PExt))) + { + if (Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0) + { + Nat.IncAt(10, zz, PExtInv.Length); + } + } + } + + public static void AddOne(uint[] x, uint[] z) + { + uint c = Nat.Inc(5, x, z); + if (c != 0 || (z[4] == P4 && Nat160.Gte(z, P))) + { + Nat.Add33To(5, PInv33, z); + } + } + + public static uint[] FromBigInteger(BigInteger x) + { + uint[] z = Nat.FromBigInteger(160, x); + if (z[4] == P4 && Nat160.Gte(z, P)) + { + Nat160.SubFrom(P, z); + } + return z; + } + + public static void Half(uint[] x, uint[] z) + { + if ((x[0] & 1) == 0) + { + Nat.ShiftDownBit(5, x, 0, z); + } + else + { + uint c = Nat160.Add(x, P, z); + Nat.ShiftDownBit(5, z, c); + } + } + + public static void Inv(uint[] x, uint[] z) + { + Mod.CheckedModOddInverse(P, x, z); + } + + public static int IsZero(uint[] x) + { + uint d = 0; + for (int i = 0; i < 5; ++i) + { + d |= x[i]; + } + d = (d >> 1) | (d & 1); + return ((int)d - 1) >> 31; + } + + public static void Multiply(uint[] x, uint[] y, uint[] z) + { + uint[] tt = Nat160.CreateExt(); + Nat160.Mul(x, y, tt); + Reduce(tt, z); + } + + public static void MultiplyAddToExt(uint[] x, uint[] y, uint[] zz) + { + uint c = Nat160.MulAddTo(x, y, zz); + if (c != 0 || (zz[9] == PExt9 && Nat.Gte(10, zz, PExt))) + { + if (Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0) + { + Nat.IncAt(10, zz, PExtInv.Length); + } + } + } + + public static void Negate(uint[] x, uint[] z) + { + if (0 != IsZero(x)) + { + Nat160.Sub(P, P, z); + } + else + { + Nat160.Sub(P, x, z); + } + } + + public static void Random(SecureRandom r, uint[] z) + { + byte[] bb = new byte[5 * 4]; + do + { + r.NextBytes(bb); + Pack.LE_To_UInt32(bb, 0, z, 0, 5); + } + while (0 == Nat.LessThan(5, z, P)); + } + + public static void RandomMult(SecureRandom r, uint[] z) + { + do + { + Random(r, z); + } + while (0 != IsZero(z)); + } + + public static void Reduce(uint[] xx, uint[] z) + { + ulong cc = Nat160.Mul33Add(PInv33, xx, 5, xx, 0, z, 0); + uint c = Nat160.Mul33DWordAdd(PInv33, cc, z, 0); + + Debug.Assert(c == 0 || c == 1); + + if (c != 0 || (z[4] == P4 && Nat160.Gte(z, P))) + { + Nat.Add33To(5, PInv33, z); + } + } + + public static void Reduce32(uint x, uint[] z) + { + if ((x != 0 && Nat160.Mul33WordAdd(PInv33, x, z, 0) != 0) + || (z[4] == P4 && Nat160.Gte(z, P))) + { + Nat.Add33To(5, PInv33, z); + } + } + + public static void Square(uint[] x, uint[] z) + { + uint[] tt = Nat160.CreateExt(); + Nat160.Square(x, tt); + Reduce(tt, z); + } + + public static void SquareN(uint[] x, int n, uint[] z) + { + Debug.Assert(n > 0); + + uint[] tt = Nat160.CreateExt(); + Nat160.Square(x, tt); + Reduce(tt, z); + + while (--n > 0) + { + Nat160.Square(z, tt); + Reduce(tt, z); + } + } + + public static void Subtract(uint[] x, uint[] y, uint[] z) + { + int c = Nat160.Sub(x, y, z); + if (c != 0) + { + Nat.Sub33From(5, PInv33, z); + } + } + + public static void SubtractExt(uint[] xx, uint[] yy, uint[] zz) + { + int c = Nat.Sub(10, xx, yy, zz); + if (c != 0) + { + if (Nat.SubFrom(PExtInv.Length, PExtInv, zz) != 0) + { + Nat.DecAt(10, zz, PExtInv.Length); + } + } + } + + public static void Twice(uint[] x, uint[] z) + { + uint c = Nat.ShiftUpBit(5, x, 0, z); + if (c != 0 || (z[4] == P4 && Nat160.Gte(z, P))) + { + Nat.Add33To(5, PInv33, z); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160R2Field.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160R2Field.cs.meta new file mode 100644 index 0000000..3e6f588 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160R2Field.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 24856a3070d40dc469ce00e892f7ec34 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160R2FieldElement.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160R2FieldElement.cs new file mode 100644 index 0000000..795fe3b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160R2FieldElement.cs @@ -0,0 +1,220 @@ +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP160R2FieldElement + : AbstractFpFieldElement + { + public static readonly BigInteger Q = new BigInteger(1, + Hex.DecodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73")); + + protected internal readonly uint[] x; + + public SecP160R2FieldElement(BigInteger x) + { + if (x == null || x.SignValue < 0 || x.CompareTo(Q) >= 0) + throw new ArgumentException("value invalid for SecP160R2FieldElement", "x"); + + this.x = SecP160R2Field.FromBigInteger(x); + } + + public SecP160R2FieldElement() + { + this.x = Nat160.Create(); + } + + protected internal SecP160R2FieldElement(uint[] x) + { + this.x = x; + } + + public override bool IsZero + { + get { return Nat160.IsZero(x); } + } + + public override bool IsOne + { + get { return Nat160.IsOne(x); } + } + + public override bool TestBitZero() + { + return Nat160.GetBit(x, 0) == 1; + } + + public override BigInteger ToBigInteger() + { + return Nat160.ToBigInteger(x); + } + + public override string FieldName + { + get { return "SecP160R2Field"; } + } + + public override int FieldSize + { + get { return Q.BitLength; } + } + + public override ECFieldElement Add(ECFieldElement b) + { + uint[] z = Nat160.Create(); + SecP160R2Field.Add(x, ((SecP160R2FieldElement)b).x, z); + return new SecP160R2FieldElement(z); + } + + public override ECFieldElement AddOne() + { + uint[] z = Nat160.Create(); + SecP160R2Field.AddOne(x, z); + return new SecP160R2FieldElement(z); + } + + public override ECFieldElement Subtract(ECFieldElement b) + { + uint[] z = Nat160.Create(); + SecP160R2Field.Subtract(x, ((SecP160R2FieldElement)b).x, z); + return new SecP160R2FieldElement(z); + } + + public override ECFieldElement Multiply(ECFieldElement b) + { + uint[] z = Nat160.Create(); + SecP160R2Field.Multiply(x, ((SecP160R2FieldElement)b).x, z); + return new SecP160R2FieldElement(z); + } + + public override ECFieldElement Divide(ECFieldElement b) + { + // return Multiply(b.invert()); + uint[] z = Nat160.Create(); + SecP160R2Field.Inv(((SecP160R2FieldElement)b).x, z); + SecP160R2Field.Multiply(z, x, z); + return new SecP160R2FieldElement(z); + } + + public override ECFieldElement Negate() + { + uint[] z = Nat160.Create(); + SecP160R2Field.Negate(x, z); + return new SecP160R2FieldElement(z); + } + + public override ECFieldElement Square() + { + uint[] z = Nat160.Create(); + SecP160R2Field.Square(x, z); + return new SecP160R2FieldElement(z); + } + + public override ECFieldElement Invert() + { + // return new SecP160R2FieldElement(ToBigInteger().modInverse(Q)); + uint[] z = Nat160.Create(); + SecP160R2Field.Inv(x, z); + return new SecP160R2FieldElement(z); + } + + // D.1.4 91 + /** + * return a sqrt root - the routine verifies that the calculation returns the right value - if + * none exists it returns null. + */ + public override ECFieldElement Sqrt() + { + /* + * Raise this element to the exponent 2^158 - 2^30 - 2^12 - 2^10 - 2^7 - 2^6 - 2^5 - 2^1 - 2^0 + * + * Breaking up the exponent's binary representation into "repunits", we get: { 127 1s } { 1 + * 0s } { 17 1s } { 1 0s } { 1 1s } { 1 0s } { 2 1s } { 3 0s } { 3 1s } { 1 0s } { 1 1s } + * + * Therefore we need an Addition chain containing 1, 2, 3, 17, 127 (the lengths of the repunits) + * We use: [1], [2], [3], 4, 7, 14, [17], 31, 62, 124, [127] + */ + + uint[] x1 = this.x; + if (Nat160.IsZero(x1) || Nat160.IsOne(x1)) + { + return this; + } + + uint[] x2 = Nat160.Create(); + SecP160R2Field.Square(x1, x2); + SecP160R2Field.Multiply(x2, x1, x2); + uint[] x3 = Nat160.Create(); + SecP160R2Field.Square(x2, x3); + SecP160R2Field.Multiply(x3, x1, x3); + uint[] x4 = Nat160.Create(); + SecP160R2Field.Square(x3, x4); + SecP160R2Field.Multiply(x4, x1, x4); + uint[] x7 = Nat160.Create(); + SecP160R2Field.SquareN(x4, 3, x7); + SecP160R2Field.Multiply(x7, x3, x7); + uint[] x14 = x4; + SecP160R2Field.SquareN(x7, 7, x14); + SecP160R2Field.Multiply(x14, x7, x14); + uint[] x17 = x7; + SecP160R2Field.SquareN(x14, 3, x17); + SecP160R2Field.Multiply(x17, x3, x17); + uint[] x31 = Nat160.Create(); + SecP160R2Field.SquareN(x17, 14, x31); + SecP160R2Field.Multiply(x31, x14, x31); + uint[] x62 = x14; + SecP160R2Field.SquareN(x31, 31, x62); + SecP160R2Field.Multiply(x62, x31, x62); + uint[] x124 = x31; + SecP160R2Field.SquareN(x62, 62, x124); + SecP160R2Field.Multiply(x124, x62, x124); + uint[] x127 = x62; + SecP160R2Field.SquareN(x124, 3, x127); + SecP160R2Field.Multiply(x127, x3, x127); + + uint[] t1 = x127; + SecP160R2Field.SquareN(t1, 18, t1); + SecP160R2Field.Multiply(t1, x17, t1); + SecP160R2Field.SquareN(t1, 2, t1); + SecP160R2Field.Multiply(t1, x1, t1); + SecP160R2Field.SquareN(t1, 3, t1); + SecP160R2Field.Multiply(t1, x2, t1); + SecP160R2Field.SquareN(t1, 6, t1); + SecP160R2Field.Multiply(t1, x3, t1); + SecP160R2Field.SquareN(t1, 2, t1); + SecP160R2Field.Multiply(t1, x1, t1); + + uint[] t2 = x2; + SecP160R2Field.Square(t1, t2); + + return Nat160.Eq(x1, t2) ? new SecP160R2FieldElement(t1) : null; + } + + public override bool Equals(object obj) + { + return Equals(obj as SecP160R2FieldElement); + } + + public override bool Equals(ECFieldElement other) + { + return Equals(other as SecP160R2FieldElement); + } + + public virtual bool Equals(SecP160R2FieldElement other) + { + if (this == other) + return true; + if (null == other) + return false; + return Nat160.Eq(x, other.x); + } + + public override int GetHashCode() + { + return Q.GetHashCode() ^ Arrays.GetHashCode(x, 0, 5); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160R2FieldElement.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160R2FieldElement.cs.meta new file mode 100644 index 0000000..708b4dd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160R2FieldElement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 55f3be36bf48ac343982e6fe51ec1a97 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160R2Point.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160R2Point.cs new file mode 100644 index 0000000..343cf8c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160R2Point.cs @@ -0,0 +1,279 @@ +using System; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP160R2Point + : AbstractFpPoint + { + /** + * Create a point which encodes with point compression. + * + * @param curve + * the curve to use + * @param x + * affine x co-ordinate + * @param y + * affine y co-ordinate + * + * @deprecated Use ECCurve.CreatePoint to construct points + */ + public SecP160R2Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * Create a point that encodes with or without point compresion. + * + * @param curve + * the curve to use + * @param x + * affine x co-ordinate + * @param y + * affine y co-ordinate + * @param withCompression + * if true encode with point compression + * + * @deprecated per-point compression property will be removed, refer + * {@link #getEncoded(bool)} + */ + public SecP160R2Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecP160R2Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecP160R2Point(null, AffineXCoord, AffineYCoord); + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + if (this == b) + return Twice(); + + ECCurve curve = this.Curve; + + SecP160R2FieldElement X1 = (SecP160R2FieldElement)this.RawXCoord, Y1 = (SecP160R2FieldElement)this.RawYCoord; + SecP160R2FieldElement X2 = (SecP160R2FieldElement)b.RawXCoord, Y2 = (SecP160R2FieldElement)b.RawYCoord; + + SecP160R2FieldElement Z1 = (SecP160R2FieldElement)this.RawZCoords[0]; + SecP160R2FieldElement Z2 = (SecP160R2FieldElement)b.RawZCoords[0]; + + uint c; + uint[] tt1 = Nat160.CreateExt(); + uint[] t2 = Nat160.Create(); + uint[] t3 = Nat160.Create(); + uint[] t4 = Nat160.Create(); + + bool Z1IsOne = Z1.IsOne; + uint[] U2, S2; + if (Z1IsOne) + { + U2 = X2.x; + S2 = Y2.x; + } + else + { + S2 = t3; + SecP160R2Field.Square(Z1.x, S2); + + U2 = t2; + SecP160R2Field.Multiply(S2, X2.x, U2); + + SecP160R2Field.Multiply(S2, Z1.x, S2); + SecP160R2Field.Multiply(S2, Y2.x, S2); + } + + bool Z2IsOne = Z2.IsOne; + uint[] U1, S1; + if (Z2IsOne) + { + U1 = X1.x; + S1 = Y1.x; + } + else + { + S1 = t4; + SecP160R2Field.Square(Z2.x, S1); + + U1 = tt1; + SecP160R2Field.Multiply(S1, X1.x, U1); + + SecP160R2Field.Multiply(S1, Z2.x, S1); + SecP160R2Field.Multiply(S1, Y1.x, S1); + } + + uint[] H = Nat160.Create(); + SecP160R2Field.Subtract(U1, U2, H); + + uint[] R = t2; + SecP160R2Field.Subtract(S1, S2, R); + + // Check if b == this or b == -this + if (Nat160.IsZero(H)) + { + if (Nat160.IsZero(R)) + { + // this == b, i.e. this must be doubled + return this.Twice(); + } + + // this == -b, i.e. the result is the point at infinity + return curve.Infinity; + } + + uint[] HSquared = t3; + SecP160R2Field.Square(H, HSquared); + + uint[] G = Nat160.Create(); + SecP160R2Field.Multiply(HSquared, H, G); + + uint[] V = t3; + SecP160R2Field.Multiply(HSquared, U1, V); + + SecP160R2Field.Negate(G, G); + Nat160.Mul(S1, G, tt1); + + c = Nat160.AddBothTo(V, V, G); + SecP160R2Field.Reduce32(c, G); + + SecP160R2FieldElement X3 = new SecP160R2FieldElement(t4); + SecP160R2Field.Square(R, X3.x); + SecP160R2Field.Subtract(X3.x, G, X3.x); + + SecP160R2FieldElement Y3 = new SecP160R2FieldElement(G); + SecP160R2Field.Subtract(V, X3.x, Y3.x); + SecP160R2Field.MultiplyAddToExt(Y3.x, R, tt1); + SecP160R2Field.Reduce(tt1, Y3.x); + + SecP160R2FieldElement Z3 = new SecP160R2FieldElement(H); + if (!Z1IsOne) + { + SecP160R2Field.Multiply(Z3.x, Z1.x, Z3.x); + } + if (!Z2IsOne) + { + SecP160R2Field.Multiply(Z3.x, Z2.x, Z3.x); + } + + ECFieldElement[] zs = new ECFieldElement[]{ Z3 }; + + return new SecP160R2Point(curve, X3, Y3, zs, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + SecP160R2FieldElement Y1 = (SecP160R2FieldElement)this.RawYCoord; + if (Y1.IsZero) + return curve.Infinity; + + SecP160R2FieldElement X1 = (SecP160R2FieldElement)this.RawXCoord, Z1 = (SecP160R2FieldElement)this.RawZCoords[0]; + + uint c; + uint[] t1 = Nat160.Create(); + uint[] t2 = Nat160.Create(); + + uint[] Y1Squared = Nat160.Create(); + SecP160R2Field.Square(Y1.x, Y1Squared); + + uint[] T = Nat160.Create(); + SecP160R2Field.Square(Y1Squared, T); + + bool Z1IsOne = Z1.IsOne; + + uint[] Z1Squared = Z1.x; + if (!Z1IsOne) + { + Z1Squared = t2; + SecP160R2Field.Square(Z1.x, Z1Squared); + } + + SecP160R2Field.Subtract(X1.x, Z1Squared, t1); + + uint[] M = t2; + SecP160R2Field.Add(X1.x, Z1Squared, M); + SecP160R2Field.Multiply(M, t1, M); + c = Nat160.AddBothTo(M, M, M); + SecP160R2Field.Reduce32(c, M); + + uint[] S = Y1Squared; + SecP160R2Field.Multiply(Y1Squared, X1.x, S); + c = Nat.ShiftUpBits(5, S, 2, 0); + SecP160R2Field.Reduce32(c, S); + + c = Nat.ShiftUpBits(5, T, 3, 0, t1); + SecP160R2Field.Reduce32(c, t1); + + SecP160R2FieldElement X3 = new SecP160R2FieldElement(T); + SecP160R2Field.Square(M, X3.x); + SecP160R2Field.Subtract(X3.x, S, X3.x); + SecP160R2Field.Subtract(X3.x, S, X3.x); + + SecP160R2FieldElement Y3 = new SecP160R2FieldElement(S); + SecP160R2Field.Subtract(S, X3.x, Y3.x); + SecP160R2Field.Multiply(Y3.x, M, Y3.x); + SecP160R2Field.Subtract(Y3.x, t1, Y3.x); + + SecP160R2FieldElement Z3 = new SecP160R2FieldElement(M); + SecP160R2Field.Twice(Y1.x, Z3.x); + if (!Z1IsOne) + { + SecP160R2Field.Multiply(Z3.x, Z1.x, Z3.x); + } + + return new SecP160R2Point(curve, X3, Y3, new ECFieldElement[]{ Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this == b) + return ThreeTimes(); + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECFieldElement Y1 = this.RawYCoord; + if (Y1.IsZero) + return b; + + return Twice().Add(b); + } + + public override ECPoint ThreeTimes() + { + if (this.IsInfinity || this.RawYCoord.IsZero) + return this; + + // NOTE: Be careful about recursions between TwicePlus and ThreeTimes + return Twice().Add(this); + } + + public override ECPoint Negate() + { + if (IsInfinity) + return this; + + return new SecP160R2Point(Curve, this.RawXCoord, this.RawYCoord.Negate(), this.RawZCoords, IsCompressed); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160R2Point.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160R2Point.cs.meta new file mode 100644 index 0000000..b052e40 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP160R2Point.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 43b23b8d3d68cd948a37a895557c4aeb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP192K1Curve.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP192K1Curve.cs new file mode 100644 index 0000000..b9fb08e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP192K1Curve.cs @@ -0,0 +1,168 @@ +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP192K1Curve + : AbstractFpCurve + { + public static readonly BigInteger q = SecP192K1FieldElement.Q; + + private const int SECP192K1_DEFAULT_COORDS = COORD_JACOBIAN; + private const int SECP192K1_FE_INTS = 6; + private static readonly ECFieldElement[] SECP192K1_AFFINE_ZS = new ECFieldElement[] { new SecP192K1FieldElement(BigInteger.One) }; + + protected readonly SecP192K1Point m_infinity; + + public SecP192K1Curve() + : base(q) + { + this.m_infinity = new SecP192K1Point(this, null, null); + + this.m_a = FromBigInteger(BigInteger.Zero); + this.m_b = FromBigInteger(BigInteger.ValueOf(3)); + this.m_order = new BigInteger(1, Hex.DecodeStrict("FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D")); + this.m_cofactor = BigInteger.One; + this.m_coord = SECP192K1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecP192K1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_JACOBIAN: + return true; + default: + return false; + } + } + + public virtual BigInteger Q + { + get { return q; } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return q.BitLength; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecP192K1FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecP192K1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecP192K1Point(this, x, y, zs, withCompression); + } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + uint[] table = new uint[len * SECP192K1_FE_INTS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat192.Copy(((SecP192K1FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECP192K1_FE_INTS; + Nat192.Copy(((SecP192K1FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECP192K1_FE_INTS; + } + } + + return new SecP192K1LookupTable(this, table, len); + } + + public override ECFieldElement RandomFieldElement(SecureRandom r) + { + uint[] x = Nat192.Create(); + SecP192K1Field.Random(r, x); + return new SecP192K1FieldElement(x); + } + + public override ECFieldElement RandomFieldElementMult(SecureRandom r) + { + uint[] x = Nat192.Create(); + SecP192K1Field.RandomMult(r, x); + return new SecP192K1FieldElement(x); + } + + private class SecP192K1LookupTable + : AbstractECLookupTable + { + private readonly SecP192K1Curve m_outer; + private readonly uint[] m_table; + private readonly int m_size; + + internal SecP192K1LookupTable(SecP192K1Curve outer, uint[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public override int Size + { + get { return m_size; } + } + + public override ECPoint Lookup(int index) + { + uint[] x = Nat192.Create(), y = Nat192.Create(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + uint MASK = (uint)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECP192K1_FE_INTS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECP192K1_FE_INTS + j] & MASK; + } + + pos += (SECP192K1_FE_INTS * 2); + } + + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + uint[] x = Nat192.Create(), y = Nat192.Create(); + int pos = index * SECP192K1_FE_INTS * 2; + + for (int j = 0; j < SECP192K1_FE_INTS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECP192K1_FE_INTS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(uint[] x, uint[] y) + { + return m_outer.CreateRawPoint(new SecP192K1FieldElement(x), new SecP192K1FieldElement(y), SECP192K1_AFFINE_ZS, false); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP192K1Curve.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP192K1Curve.cs.meta new file mode 100644 index 0000000..7d79165 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP192K1Curve.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b27815a549c10bd4589894de2226cc2e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP192K1Field.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP192K1Field.cs new file mode 100644 index 0000000..46b7c4e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP192K1Field.cs @@ -0,0 +1,217 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP192K1Field + { + // 2^192 - 2^32 - 2^12 - 2^8 - 2^7 - 2^6 - 2^3 - 1 + internal static readonly uint[] P = new uint[]{ 0xFFFFEE37, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF }; + private static readonly uint[] PExt = new uint[]{ 0x013C4FD1, 0x00002392, 0x00000001, 0x00000000, 0x00000000, + 0x00000000, 0xFFFFDC6E, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; + private static readonly uint[] PExtInv = new uint[]{ 0xFEC3B02F, 0xFFFFDC6D, 0xFFFFFFFE, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00002391, 0x00000002 }; + private const uint P5 = 0xFFFFFFFF; + private const uint PExt11 = 0xFFFFFFFF; + private const uint PInv33 = 0x11C9; + + public static void Add(uint[] x, uint[] y, uint[] z) + { + uint c = Nat192.Add(x, y, z); + if (c != 0 || (z[5] == P5 && Nat192.Gte(z, P))) + { + Nat.Add33To(6, PInv33, z); + } + } + + public static void AddExt(uint[] xx, uint[] yy, uint[] zz) + { + uint c = Nat.Add(12, xx, yy, zz); + if (c != 0 || (zz[11] == PExt11 && Nat.Gte(12, zz, PExt))) + { + if (Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0) + { + Nat.IncAt(12, zz, PExtInv.Length); + } + } + } + + public static void AddOne(uint[] x, uint[] z) + { + uint c = Nat.Inc(6, x, z); + if (c != 0 || (z[5] == P5 && Nat192.Gte(z, P))) + { + Nat.Add33To(6, PInv33, z); + } + } + + public static uint[] FromBigInteger(BigInteger x) + { + uint[] z = Nat.FromBigInteger(192, x); + if (z[5] == P5 && Nat192.Gte(z, P)) + { + Nat192.SubFrom(P, z); + } + return z; + } + + public static void Half(uint[] x, uint[] z) + { + if ((x[0] & 1) == 0) + { + Nat.ShiftDownBit(6, x, 0, z); + } + else + { + uint c = Nat192.Add(x, P, z); + Nat.ShiftDownBit(6, z, c); + } + } + + public static void Inv(uint[] x, uint[] z) + { + Mod.CheckedModOddInverse(P, x, z); + } + + public static int IsZero(uint[] x) + { + uint d = 0; + for (int i = 0; i < 6; ++i) + { + d |= x[i]; + } + d = (d >> 1) | (d & 1); + return ((int)d - 1) >> 31; + } + + public static void Multiply(uint[] x, uint[] y, uint[] z) + { + uint[] tt = Nat192.CreateExt(); + Nat192.Mul(x, y, tt); + Reduce(tt, z); + } + + public static void MultiplyAddToExt(uint[] x, uint[] y, uint[] zz) + { + uint c = Nat192.MulAddTo(x, y, zz); + if (c != 0 || (zz[11] == PExt11 && Nat.Gte(12, zz, PExt))) + { + if (Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0) + { + Nat.IncAt(12, zz, PExtInv.Length); + } + } + } + + public static void Negate(uint[] x, uint[] z) + { + if (0 != IsZero(x)) + { + Nat192.Sub(P, P, z); + } + else + { + Nat192.Sub(P, x, z); + } + } + + public static void Random(SecureRandom r, uint[] z) + { + byte[] bb = new byte[6 * 4]; + do + { + r.NextBytes(bb); + Pack.LE_To_UInt32(bb, 0, z, 0, 6); + } + while (0 == Nat.LessThan(6, z, P)); + } + + public static void RandomMult(SecureRandom r, uint[] z) + { + do + { + Random(r, z); + } + while (0 != IsZero(z)); + } + + public static void Reduce(uint[] xx, uint[] z) + { + ulong cc = Nat192.Mul33Add(PInv33, xx, 6, xx, 0, z, 0); + uint c = Nat192.Mul33DWordAdd(PInv33, cc, z, 0); + + Debug.Assert(c == 0 || c == 1); + + if (c != 0 || (z[5] == P5 && Nat192.Gte(z, P))) + { + Nat.Add33To(6, PInv33, z); + } + } + + public static void Reduce32(uint x, uint[] z) + { + if ((x != 0 && Nat192.Mul33WordAdd(PInv33, x, z, 0) != 0) + || (z[5] == P5 && Nat192.Gte(z, P))) + { + Nat.Add33To(6, PInv33, z); + } + } + + public static void Square(uint[] x, uint[] z) + { + uint[] tt = Nat192.CreateExt(); + Nat192.Square(x, tt); + Reduce(tt, z); + } + + public static void SquareN(uint[] x, int n, uint[] z) + { + Debug.Assert(n > 0); + + uint[] tt = Nat192.CreateExt(); + Nat192.Square(x, tt); + Reduce(tt, z); + + while (--n > 0) + { + Nat192.Square(z, tt); + Reduce(tt, z); + } + } + + public static void Subtract(uint[] x, uint[] y, uint[] z) + { + int c = Nat192.Sub(x, y, z); + if (c != 0) + { + Nat.Sub33From(6, PInv33, z); + } + } + + public static void SubtractExt(uint[] xx, uint[] yy, uint[] zz) + { + int c = Nat.Sub(12, xx, yy, zz); + if (c != 0) + { + if (Nat.SubFrom(PExtInv.Length, PExtInv, zz) != 0) + { + Nat.DecAt(12, zz, PExtInv.Length); + } + } + } + + public static void Twice(uint[] x, uint[] z) + { + uint c = Nat.ShiftUpBit(6, x, 0, z); + if (c != 0 || (z[5] == P5 && Nat192.Gte(z, P))) + { + Nat.Add33To(6, PInv33, z); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP192K1Field.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP192K1Field.cs.meta new file mode 100644 index 0000000..5973b06 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP192K1Field.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b6245e3f3e70f214b8a3be83a3dd18b8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP192K1FieldElement.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP192K1FieldElement.cs new file mode 100644 index 0000000..c933ffc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP192K1FieldElement.cs @@ -0,0 +1,215 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP192K1FieldElement + : AbstractFpFieldElement + { + public static readonly BigInteger Q = new BigInteger(1, + Hex.DecodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37")); + + protected internal readonly uint[] x; + + public SecP192K1FieldElement(BigInteger x) + { + if (x == null || x.SignValue < 0 || x.CompareTo(Q) >= 0) + throw new ArgumentException("value invalid for SecP192K1FieldElement", "x"); + + this.x = SecP192K1Field.FromBigInteger(x); + } + + public SecP192K1FieldElement() + { + this.x = Nat192.Create(); + } + + protected internal SecP192K1FieldElement(uint[] x) + { + this.x = x; + } + + public override bool IsZero + { + get { return Nat192.IsZero(x); } + } + + public override bool IsOne + { + get { return Nat192.IsOne(x); } + } + + public override bool TestBitZero() + { + return Nat192.GetBit(x, 0) == 1; + } + + public override BigInteger ToBigInteger() + { + return Nat192.ToBigInteger(x); + } + + public override string FieldName + { + get { return "SecP192K1Field"; } + } + + public override int FieldSize + { + get { return Q.BitLength; } + } + + public override ECFieldElement Add(ECFieldElement b) + { + uint[] z = Nat192.Create(); + SecP192K1Field.Add(x, ((SecP192K1FieldElement)b).x, z); + return new SecP192K1FieldElement(z); + } + + public override ECFieldElement AddOne() + { + uint[] z = Nat192.Create(); + SecP192K1Field.AddOne(x, z); + return new SecP192K1FieldElement(z); + } + + public override ECFieldElement Subtract(ECFieldElement b) + { + uint[] z = Nat192.Create(); + SecP192K1Field.Subtract(x, ((SecP192K1FieldElement)b).x, z); + return new SecP192K1FieldElement(z); + } + + public override ECFieldElement Multiply(ECFieldElement b) + { + uint[] z = Nat192.Create(); + SecP192K1Field.Multiply(x, ((SecP192K1FieldElement)b).x, z); + return new SecP192K1FieldElement(z); + } + + public override ECFieldElement Divide(ECFieldElement b) + { + //return Multiply(b.Invert()); + uint[] z = Nat192.Create(); + SecP192K1Field.Inv(((SecP192K1FieldElement)b).x, z); + SecP192K1Field.Multiply(z, x, z); + return new SecP192K1FieldElement(z); + } + + public override ECFieldElement Negate() + { + uint[] z = Nat192.Create(); + SecP192K1Field.Negate(x, z); + return new SecP192K1FieldElement(z); + } + + public override ECFieldElement Square() + { + uint[] z = Nat192.Create(); + SecP192K1Field.Square(x, z); + return new SecP192K1FieldElement(z); + } + + public override ECFieldElement Invert() + { + //return new SecP192K1FieldElement(ToBigInteger().ModInverse(Q)); + uint[] z = Nat192.Create(); + SecP192K1Field.Inv(x, z); + return new SecP192K1FieldElement(z); + } + + /** + * return a sqrt root - the routine verifies that the calculation returns the right value - if + * none exists it returns null. + */ + public override ECFieldElement Sqrt() + { + /* + * Raise this element to the exponent 2^190 - 2^30 - 2^10 - 2^6 - 2^5 - 2^4 - 2^1 + * + * Breaking up the exponent's binary representation into "repunits", we get: + * { 159 1s } { 1 0s } { 19 1s } { 1 0s } { 3 1s } { 3 0s } { 3 1s } { 1 0s } + * + * Therefore we need an addition chain containing 3, 19, 159 (the lengths of the repunits) + * We use: 1, 2, [3], 6, 8, 16, [19], 35, 70, 140, [159] + */ + + uint[] x1 = this.x; + if (Nat192.IsZero(x1) || Nat192.IsOne(x1)) + return this; + + uint[] x2 = Nat192.Create(); + SecP192K1Field.Square(x1, x2); + SecP192K1Field.Multiply(x2, x1, x2); + uint[] x3 = Nat192.Create(); + SecP192K1Field.Square(x2, x3); + SecP192K1Field.Multiply(x3, x1, x3); + uint[] x6 = Nat192.Create(); + SecP192K1Field.SquareN(x3, 3, x6); + SecP192K1Field.Multiply(x6, x3, x6); + uint[] x8 = x6; + SecP192K1Field.SquareN(x6, 2, x8); + SecP192K1Field.Multiply(x8, x2, x8); + uint[] x16 = x2; + SecP192K1Field.SquareN(x8, 8, x16); + SecP192K1Field.Multiply(x16, x8, x16); + uint[] x19 = x8; + SecP192K1Field.SquareN(x16, 3, x19); + SecP192K1Field.Multiply(x19, x3, x19); + uint[] x35 = Nat192.Create(); + SecP192K1Field.SquareN(x19, 16, x35); + SecP192K1Field.Multiply(x35, x16, x35); + uint[] x70 = x16; + SecP192K1Field.SquareN(x35, 35, x70); + SecP192K1Field.Multiply(x70, x35, x70); + uint[] x140 = x35; + SecP192K1Field.SquareN(x70, 70, x140); + SecP192K1Field.Multiply(x140, x70, x140); + uint[] x159 = x70; + SecP192K1Field.SquareN(x140, 19, x159); + SecP192K1Field.Multiply(x159, x19, x159); + + uint[] t1 = x159; + SecP192K1Field.SquareN(t1, 20, t1); + SecP192K1Field.Multiply(t1, x19, t1); + SecP192K1Field.SquareN(t1, 4, t1); + SecP192K1Field.Multiply(t1, x3, t1); + SecP192K1Field.SquareN(t1, 6, t1); + SecP192K1Field.Multiply(t1, x3, t1); + SecP192K1Field.Square(t1, t1); + + uint[] t2 = x3; + SecP192K1Field.Square(t1, t2); + + return Nat192.Eq(x1, t2) ? new SecP192K1FieldElement(t1) : null; + } + + public override bool Equals(object obj) + { + return Equals(obj as SecP192K1FieldElement); + } + + public override bool Equals(ECFieldElement other) + { + return Equals(other as SecP192K1FieldElement); + } + + public virtual bool Equals(SecP192K1FieldElement other) + { + if (this == other) + return true; + if (null == other) + return false; + return Nat192.Eq(x, other.x); + } + + public override int GetHashCode() + { + return Q.GetHashCode() ^ Arrays.GetHashCode(x, 0, 6); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP192K1FieldElement.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP192K1FieldElement.cs.meta new file mode 100644 index 0000000..d4aac7d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP192K1FieldElement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c48d3c75381f64d4c86f21baf59a1bbc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP192K1Point.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP192K1Point.cs new file mode 100644 index 0000000..58eb091 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP192K1Point.cs @@ -0,0 +1,267 @@ +using System; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP192K1Point + : AbstractFpPoint + { + /** + * Create a point which encodes with point compression. + * + * @param curve + * the curve to use + * @param x + * affine x co-ordinate + * @param y + * affine y co-ordinate + * + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecP192K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * Create a point that encodes with or without point compresion. + * + * @param curve + * the curve to use + * @param x + * affine x co-ordinate + * @param y + * affine y co-ordinate + * @param withCompression + * if true encode with point compression + * + * @deprecated per-point compression property will be removed, refer + * {@link #getEncoded(bool)} + */ + public SecP192K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecP192K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, + bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecP192K1Point(null, AffineXCoord, AffineYCoord); + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + if (this == b) + return Twice(); + + ECCurve curve = this.Curve; + + SecP192K1FieldElement X1 = (SecP192K1FieldElement)this.RawXCoord, Y1 = (SecP192K1FieldElement)this.RawYCoord; + SecP192K1FieldElement X2 = (SecP192K1FieldElement)b.RawXCoord, Y2 = (SecP192K1FieldElement)b.RawYCoord; + + SecP192K1FieldElement Z1 = (SecP192K1FieldElement)this.RawZCoords[0]; + SecP192K1FieldElement Z2 = (SecP192K1FieldElement)b.RawZCoords[0]; + + uint c; + uint[] tt1 = Nat192.CreateExt(); + uint[] t2 = Nat192.Create(); + uint[] t3 = Nat192.Create(); + uint[] t4 = Nat192.Create(); + + bool Z1IsOne = Z1.IsOne; + uint[] U2, S2; + if (Z1IsOne) + { + U2 = X2.x; + S2 = Y2.x; + } + else + { + S2 = t3; + SecP192K1Field.Square(Z1.x, S2); + + U2 = t2; + SecP192K1Field.Multiply(S2, X2.x, U2); + + SecP192K1Field.Multiply(S2, Z1.x, S2); + SecP192K1Field.Multiply(S2, Y2.x, S2); + } + + bool Z2IsOne = Z2.IsOne; + uint[] U1, S1; + if (Z2IsOne) + { + U1 = X1.x; + S1 = Y1.x; + } + else + { + S1 = t4; + SecP192K1Field.Square(Z2.x, S1); + + U1 = tt1; + SecP192K1Field.Multiply(S1, X1.x, U1); + + SecP192K1Field.Multiply(S1, Z2.x, S1); + SecP192K1Field.Multiply(S1, Y1.x, S1); + } + + uint[] H = Nat192.Create(); + SecP192K1Field.Subtract(U1, U2, H); + + uint[] R = t2; + SecP192K1Field.Subtract(S1, S2, R); + + // Check if b == this or b == -this + if (Nat192.IsZero(H)) + { + if (Nat192.IsZero(R)) + { + // this == b, i.e. this must be doubled + return this.Twice(); + } + + // this == -b, i.e. the result is the point at infinity + return curve.Infinity; + } + + uint[] HSquared = t3; + SecP192K1Field.Square(H, HSquared); + + uint[] G = Nat192.Create(); + SecP192K1Field.Multiply(HSquared, H, G); + + uint[] V = t3; + SecP192K1Field.Multiply(HSquared, U1, V); + + SecP192K1Field.Negate(G, G); + Nat192.Mul(S1, G, tt1); + + c = Nat192.AddBothTo(V, V, G); + SecP192K1Field.Reduce32(c, G); + + SecP192K1FieldElement X3 = new SecP192K1FieldElement(t4); + SecP192K1Field.Square(R, X3.x); + SecP192K1Field.Subtract(X3.x, G, X3.x); + + SecP192K1FieldElement Y3 = new SecP192K1FieldElement(G); + SecP192K1Field.Subtract(V, X3.x, Y3.x); + SecP192K1Field.MultiplyAddToExt(Y3.x, R, tt1); + SecP192K1Field.Reduce(tt1, Y3.x); + + SecP192K1FieldElement Z3 = new SecP192K1FieldElement(H); + if (!Z1IsOne) + { + SecP192K1Field.Multiply(Z3.x, Z1.x, Z3.x); + } + if (!Z2IsOne) + { + SecP192K1Field.Multiply(Z3.x, Z2.x, Z3.x); + } + + ECFieldElement[] zs = new ECFieldElement[] { Z3 }; + + return new SecP192K1Point(curve, X3, Y3, zs, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + SecP192K1FieldElement Y1 = (SecP192K1FieldElement)this.RawYCoord; + if (Y1.IsZero) + return curve.Infinity; + + SecP192K1FieldElement X1 = (SecP192K1FieldElement)this.RawXCoord, Z1 = (SecP192K1FieldElement)this.RawZCoords[0]; + + uint c; + + uint[] Y1Squared = Nat192.Create(); + SecP192K1Field.Square(Y1.x, Y1Squared); + + uint[] T = Nat192.Create(); + SecP192K1Field.Square(Y1Squared, T); + + uint[] M = Nat192.Create(); + SecP192K1Field.Square(X1.x, M); + c = Nat192.AddBothTo(M, M, M); + SecP192K1Field.Reduce32(c, M); + + uint[] S = Y1Squared; + SecP192K1Field.Multiply(Y1Squared, X1.x, S); + c = Nat.ShiftUpBits(6, S, 2, 0); + SecP192K1Field.Reduce32(c, S); + + uint[] t1 = Nat192.Create(); + c = Nat.ShiftUpBits(6, T, 3, 0, t1); + SecP192K1Field.Reduce32(c, t1); + + SecP192K1FieldElement X3 = new SecP192K1FieldElement(T); + SecP192K1Field.Square(M, X3.x); + SecP192K1Field.Subtract(X3.x, S, X3.x); + SecP192K1Field.Subtract(X3.x, S, X3.x); + + SecP192K1FieldElement Y3 = new SecP192K1FieldElement(S); + SecP192K1Field.Subtract(S, X3.x, Y3.x); + SecP192K1Field.Multiply(Y3.x, M, Y3.x); + SecP192K1Field.Subtract(Y3.x, t1, Y3.x); + + SecP192K1FieldElement Z3 = new SecP192K1FieldElement(M); + SecP192K1Field.Twice(Y1.x, Z3.x); + if (!Z1.IsOne) + { + SecP192K1Field.Multiply(Z3.x, Z1.x, Z3.x); + } + + return new SecP192K1Point(curve, X3, Y3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this == b) + return ThreeTimes(); + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECFieldElement Y1 = this.RawYCoord; + if (Y1.IsZero) + return b; + + return Twice().Add(b); + } + + public override ECPoint ThreeTimes() + { + if (this.IsInfinity || this.RawYCoord.IsZero) + return this; + + // NOTE: Be careful about recursions between TwicePlus and ThreeTimes + return Twice().Add(this); + } + + public override ECPoint Negate() + { + if (IsInfinity) + return this; + + return new SecP192K1Point(Curve, RawXCoord, RawYCoord.Negate(), RawZCoords, IsCompressed); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP192K1Point.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP192K1Point.cs.meta new file mode 100644 index 0000000..8cb7d3b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP192K1Point.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 803f1cbf00f8e83488b28405ffe3ac02 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP192R1Curve.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP192R1Curve.cs new file mode 100644 index 0000000..4657685 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP192R1Curve.cs @@ -0,0 +1,171 @@ +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP192R1Curve + : AbstractFpCurve + { + public static readonly BigInteger q = SecP192R1FieldElement.Q; + + private const int SECP192R1_DEFAULT_COORDS = COORD_JACOBIAN; + private const int SECP192R1_FE_INTS = 6; + private static readonly ECFieldElement[] SECP192R1_AFFINE_ZS = new ECFieldElement[] { new SecP192R1FieldElement(BigInteger.One) }; + + protected readonly SecP192R1Point m_infinity; + + public SecP192R1Curve() + : base(q) + { + this.m_infinity = new SecP192R1Point(this, null, null); + + this.m_a = FromBigInteger(new BigInteger(1, + Hex.DecodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC"))); + this.m_b = FromBigInteger(new BigInteger(1, + Hex.DecodeStrict("64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1"))); + this.m_order = new BigInteger(1, Hex.DecodeStrict("FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831")); + this.m_cofactor = BigInteger.One; + + this.m_coord = SECP192R1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecP192R1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_JACOBIAN: + return true; + default: + return false; + } + } + + public virtual BigInteger Q + { + get { return q; } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return q.BitLength; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecP192R1FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecP192R1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecP192R1Point(this, x, y, zs, withCompression); + } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + uint[] table = new uint[len * SECP192R1_FE_INTS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat192.Copy(((SecP192R1FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECP192R1_FE_INTS; + Nat192.Copy(((SecP192R1FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECP192R1_FE_INTS; + } + } + + return new SecP192R1LookupTable(this, table, len); + } + + public override ECFieldElement RandomFieldElement(SecureRandom r) + { + uint[] x = Nat192.Create(); + SecP192R1Field.Random(r, x); + return new SecP192R1FieldElement(x); + } + + public override ECFieldElement RandomFieldElementMult(SecureRandom r) + { + uint[] x = Nat192.Create(); + SecP192R1Field.RandomMult(r, x); + return new SecP192R1FieldElement(x); + } + + private class SecP192R1LookupTable + : AbstractECLookupTable + { + private readonly SecP192R1Curve m_outer; + private readonly uint[] m_table; + private readonly int m_size; + + internal SecP192R1LookupTable(SecP192R1Curve outer, uint[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public override int Size + { + get { return m_size; } + } + + public override ECPoint Lookup(int index) + { + uint[] x = Nat192.Create(), y = Nat192.Create(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + uint MASK = (uint)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECP192R1_FE_INTS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECP192R1_FE_INTS + j] & MASK; + } + + pos += (SECP192R1_FE_INTS * 2); + } + + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + uint[] x = Nat192.Create(), y = Nat192.Create(); + int pos = index * SECP192R1_FE_INTS * 2; + + for (int j = 0; j < SECP192R1_FE_INTS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECP192R1_FE_INTS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(uint[] x, uint[] y) + { + return m_outer.CreateRawPoint(new SecP192R1FieldElement(x), new SecP192R1FieldElement(y), SECP192R1_AFFINE_ZS, false); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP192R1Curve.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP192R1Curve.cs.meta new file mode 100644 index 0000000..5aa9789 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP192R1Curve.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b1cbdc9a5799b884f8548482a4338399 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP192R1Field.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP192R1Field.cs new file mode 100644 index 0000000..10e2046 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP192R1Field.cs @@ -0,0 +1,322 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP192R1Field + { + // 2^192 - 2^64 - 1 + internal static readonly uint[] P = new uint[]{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF }; + private static readonly uint[] PExt = new uint[]{ 0x00000001, 0x00000000, 0x00000002, 0x00000000, 0x00000001, + 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; + private static readonly uint[] PExtInv = new uint[]{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, + 0xFFFFFFFE, 0xFFFFFFFF, 0x00000001, 0x00000000, 0x00000002 }; + private const uint P5 = 0xFFFFFFFF; + private const uint PExt11 = 0xFFFFFFFF; + + public static void Add(uint[] x, uint[] y, uint[] z) + { + uint c = Nat192.Add(x, y, z); + if (c != 0 || (z[5] == P5 && Nat192.Gte(z, P))) + { + AddPInvTo(z); + } + } + + public static void AddExt(uint[] xx, uint[] yy, uint[] zz) + { + uint c = Nat.Add(12, xx, yy, zz); + if (c != 0 || (zz[11] == PExt11 && Nat.Gte(12, zz, PExt))) + { + if (Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0) + { + Nat.IncAt(12, zz, PExtInv.Length); + } + } + } + + public static void AddOne(uint[] x, uint[] z) + { + uint c = Nat.Inc(6, x, z); + if (c != 0 || (z[5] == P5 && Nat192.Gte(z, P))) + { + AddPInvTo(z); + } + } + + public static uint[] FromBigInteger(BigInteger x) + { + uint[] z = Nat.FromBigInteger(192, x); + if (z[5] == P5 && Nat192.Gte(z, P)) + { + Nat192.SubFrom(P, z); + } + return z; + } + + public static void Half(uint[] x, uint[] z) + { + if ((x[0] & 1) == 0) + { + Nat.ShiftDownBit(6, x, 0, z); + } + else + { + uint c = Nat192.Add(x, P, z); + Nat.ShiftDownBit(6, z, c); + } + } + + public static void Inv(uint[] x, uint[] z) + { + Mod.CheckedModOddInverse(P, x, z); + } + + public static int IsZero(uint[] x) + { + uint d = 0; + for (int i = 0; i < 6; ++i) + { + d |= x[i]; + } + d = (d >> 1) | (d & 1); + return ((int)d - 1) >> 31; + } + + public static void Multiply(uint[] x, uint[] y, uint[] z) + { + uint[] tt = Nat192.CreateExt(); + Nat192.Mul(x, y, tt); + Reduce(tt, z); + } + + public static void MultiplyAddToExt(uint[] x, uint[] y, uint[] zz) + { + uint c = Nat192.MulAddTo(x, y, zz); + if (c != 0 || (zz[11] == PExt11 && Nat.Gte(12, zz, PExt))) + { + if (Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0) + { + Nat.IncAt(12, zz, PExtInv.Length); + } + } + } + + public static void Negate(uint[] x, uint[] z) + { + if (0 != IsZero(x)) + { + Nat192.Sub(P, P, z); + } + else + { + Nat192.Sub(P, x, z); + } + } + + public static void Random(SecureRandom r, uint[] z) + { + byte[] bb = new byte[6 * 4]; + do + { + r.NextBytes(bb); + Pack.LE_To_UInt32(bb, 0, z, 0, 6); + } + while (0 == Nat.LessThan(6, z, P)); + } + + public static void RandomMult(SecureRandom r, uint[] z) + { + do + { + Random(r, z); + } + while (0 != IsZero(z)); + } + + public static void Reduce(uint[] xx, uint[] z) + { + ulong xx06 = xx[6], xx07 = xx[7], xx08 = xx[8]; + ulong xx09 = xx[9], xx10 = xx[10], xx11 = xx[11]; + + ulong t0 = xx06 + xx10; + ulong t1 = xx07 + xx11; + + ulong cc = 0; + cc += (ulong)xx[0] + t0; + uint z0 = (uint)cc; + cc >>= 32; + cc += (ulong)xx[1] + t1; + z[1] = (uint)cc; + cc >>= 32; + + t0 += xx08; + t1 += xx09; + + cc += (ulong)xx[2] + t0; + ulong z2 = (uint)cc; + cc >>= 32; + cc += (ulong)xx[3] + t1; + z[3] = (uint)cc; + cc >>= 32; + + t0 -= xx06; + t1 -= xx07; + + cc += (ulong)xx[4] + t0; + z[4] = (uint)cc; + cc >>= 32; + cc += (ulong)xx[5] + t1; + z[5] = (uint)cc; + cc >>= 32; + + z2 += cc; + + cc += z0; + z[0] = (uint)cc; + cc >>= 32; + if (cc != 0) + { + cc += z[1]; + z[1] = (uint)cc; + z2 += cc >> 32; + } + z[2] = (uint)z2; + cc = z2 >> 32; + + Debug.Assert(cc == 0 || cc == 1); + + if ((cc != 0 && Nat.IncAt(6, z, 3) != 0) + || (z[5] == P5 && Nat192.Gte(z, P))) + { + AddPInvTo(z); + } + } + + public static void Reduce32(uint x, uint[] z) + { + ulong cc = 0; + + if (x != 0) + { + cc += (ulong)z[0] + x; + z[0] = (uint)cc; + cc >>= 32; + if (cc != 0) + { + cc += (ulong)z[1]; + z[1] = (uint)cc; + cc >>= 32; + } + cc += (ulong)z[2] + x; + z[2] = (uint)cc; + cc >>= 32; + + Debug.Assert(cc == 0 || cc == 1); + } + + if ((cc != 0 && Nat.IncAt(6, z, 3) != 0) + || (z[5] == P5 && Nat192.Gte(z, P))) + { + AddPInvTo(z); + } + } + + public static void Square(uint[] x, uint[] z) + { + uint[] tt = Nat192.CreateExt(); + Nat192.Square(x, tt); + Reduce(tt, z); + } + + public static void SquareN(uint[] x, int n, uint[] z) + { + Debug.Assert(n > 0); + + uint[] tt = Nat192.CreateExt(); + Nat192.Square(x, tt); + Reduce(tt, z); + + while (--n > 0) + { + Nat192.Square(z, tt); + Reduce(tt, z); + } + } + + public static void Subtract(uint[] x, uint[] y, uint[] z) + { + int c = Nat192.Sub(x, y, z); + if (c != 0) + { + SubPInvFrom(z); + } + } + + public static void SubtractExt(uint[] xx, uint[] yy, uint[] zz) + { + int c = Nat.Sub(12, xx, yy, zz); + if (c != 0) + { + if (Nat.SubFrom(PExtInv.Length, PExtInv, zz) != 0) + { + Nat.DecAt(12, zz, PExtInv.Length); + } + } + } + + public static void Twice(uint[] x, uint[] z) + { + uint c = Nat.ShiftUpBit(6, x, 0, z); + if (c != 0 || (z[5] == P5 && Nat192.Gte(z, P))) + { + AddPInvTo(z); + } + } + + private static void AddPInvTo(uint[] z) + { + long c = (long)z[0] + 1; + z[0] = (uint)c; + c >>= 32; + if (c != 0) + { + c += (long)z[1]; + z[1] = (uint)c; + c >>= 32; + } + c += (long)z[2] + 1; + z[2] = (uint)c; + c >>= 32; + if (c != 0) + { + Nat.IncAt(6, z, 3); + } + } + + private static void SubPInvFrom(uint[] z) + { + long c = (long)z[0] - 1; + z[0] = (uint)c; + c >>= 32; + if (c != 0) + { + c += (long)z[1]; + z[1] = (uint)c; + c >>= 32; + } + c += (long)z[2] - 1; + z[2] = (uint)c; + c >>= 32; + if (c != 0) + { + Nat.DecAt(6, z, 3); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP192R1Field.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP192R1Field.cs.meta new file mode 100644 index 0000000..8ae9ea5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP192R1Field.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 81737610d81408145aef7a968680a104 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP192R1FieldElement.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP192R1FieldElement.cs new file mode 100644 index 0000000..e61c225 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP192R1FieldElement.cs @@ -0,0 +1,190 @@ +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP192R1FieldElement + : AbstractFpFieldElement + { + public static readonly BigInteger Q = new BigInteger(1, + Hex.DecodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF")); + + protected internal readonly uint[] x; + + public SecP192R1FieldElement(BigInteger x) + { + if (x == null || x.SignValue < 0 || x.CompareTo(Q) >= 0) + throw new ArgumentException("value invalid for SecP192R1FieldElement", "x"); + + this.x = SecP192R1Field.FromBigInteger(x); + } + + public SecP192R1FieldElement() + { + this.x = Nat192.Create(); + } + + protected internal SecP192R1FieldElement(uint[] x) + { + this.x = x; + } + + public override bool IsZero + { + get { return Nat192.IsZero(x); } + } + + public override bool IsOne + { + get { return Nat192.IsOne(x); } + } + + public override bool TestBitZero() + { + return Nat192.GetBit(x, 0) == 1; + } + + public override BigInteger ToBigInteger() + { + return Nat192.ToBigInteger(x); + } + + public override string FieldName + { + get { return "SecP192R1Field"; } + } + + public override int FieldSize + { + get { return Q.BitLength; } + } + + public override ECFieldElement Add(ECFieldElement b) + { + uint[] z = Nat192.Create(); + SecP192R1Field.Add(x, ((SecP192R1FieldElement)b).x, z); + return new SecP192R1FieldElement(z); + } + + public override ECFieldElement AddOne() + { + uint[] z = Nat192.Create(); + SecP192R1Field.AddOne(x, z); + return new SecP192R1FieldElement(z); + } + + public override ECFieldElement Subtract(ECFieldElement b) + { + uint[] z = Nat192.Create(); + SecP192R1Field.Subtract(x, ((SecP192R1FieldElement)b).x, z); + return new SecP192R1FieldElement(z); + } + + public override ECFieldElement Multiply(ECFieldElement b) + { + uint[] z = Nat192.Create(); + SecP192R1Field.Multiply(x, ((SecP192R1FieldElement)b).x, z); + return new SecP192R1FieldElement(z); + } + + public override ECFieldElement Divide(ECFieldElement b) + { + //return Multiply(b.Invert()); + uint[] z = Nat192.Create(); + SecP192R1Field.Inv(((SecP192R1FieldElement)b).x, z); + SecP192R1Field.Multiply(z, x, z); + return new SecP192R1FieldElement(z); + } + + public override ECFieldElement Negate() + { + uint[] z = Nat192.Create(); + SecP192R1Field.Negate(x, z); + return new SecP192R1FieldElement(z); + } + + public override ECFieldElement Square() + { + uint[] z = Nat192.Create(); + SecP192R1Field.Square(x, z); + return new SecP192R1FieldElement(z); + } + + public override ECFieldElement Invert() + { + //return new SecP192R1FieldElement(ToBigInteger().ModInverse(Q)); + uint[] z = Nat192.Create(); + SecP192R1Field.Inv(x, z); + return new SecP192R1FieldElement(z); + } + + /** + * return a sqrt root - the routine verifies that the calculation returns the right value - if + * none exists it returns null. + */ + public override ECFieldElement Sqrt() + { + // Raise this element to the exponent 2^190 - 2^62 + + uint[] x1 = this.x; + if (Nat192.IsZero(x1) || Nat192.IsOne(x1)) + return this; + + uint[] t1 = Nat192.Create(); + uint[] t2 = Nat192.Create(); + + SecP192R1Field.Square(x1, t1); + SecP192R1Field.Multiply(t1, x1, t1); + + SecP192R1Field.SquareN(t1, 2, t2); + SecP192R1Field.Multiply(t2, t1, t2); + + SecP192R1Field.SquareN(t2, 4, t1); + SecP192R1Field.Multiply(t1, t2, t1); + + SecP192R1Field.SquareN(t1, 8, t2); + SecP192R1Field.Multiply(t2, t1, t2); + + SecP192R1Field.SquareN(t2, 16, t1); + SecP192R1Field.Multiply(t1, t2, t1); + + SecP192R1Field.SquareN(t1, 32, t2); + SecP192R1Field.Multiply(t2, t1, t2); + + SecP192R1Field.SquareN(t2, 64, t1); + SecP192R1Field.Multiply(t1, t2, t1); + + SecP192R1Field.SquareN(t1, 62, t1); + SecP192R1Field.Square(t1, t2); + + return Nat192.Eq(x1, t2) ? new SecP192R1FieldElement(t1) : null; + } + + public override bool Equals(object obj) + { + return Equals(obj as SecP192R1FieldElement); + } + + public override bool Equals(ECFieldElement other) + { + return Equals(other as SecP192R1FieldElement); + } + + public virtual bool Equals(SecP192R1FieldElement other) + { + if (this == other) + return true; + if (null == other) + return false; + return Nat192.Eq(x, other.x); + } + + public override int GetHashCode() + { + return Q.GetHashCode() ^ Arrays.GetHashCode(x, 0, 6); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP192R1FieldElement.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP192R1FieldElement.cs.meta new file mode 100644 index 0000000..7ce7103 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP192R1FieldElement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 98e0fffacdc19e84c9f6da2c4e2f16f0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP192R1Point.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP192R1Point.cs new file mode 100644 index 0000000..3b53e34 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP192R1Point.cs @@ -0,0 +1,279 @@ +using System; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP192R1Point + : AbstractFpPoint + { + /** + * Create a point which encodes with point compression. + * + * @param curve + * the curve to use + * @param x + * affine x co-ordinate + * @param y + * affine y co-ordinate + * + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecP192R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * Create a point that encodes with or without point compresion. + * + * @param curve + * the curve to use + * @param x + * affine x co-ordinate + * @param y + * affine y co-ordinate + * @param withCompression + * if true encode with point compression + * + * @deprecated per-point compression property will be removed, refer + * {@link #getEncoded(bool)} + */ + public SecP192R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecP192R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecP192R1Point(null, AffineXCoord, AffineYCoord); + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + if (this == b) + return Twice(); + + ECCurve curve = this.Curve; + + SecP192R1FieldElement X1 = (SecP192R1FieldElement)this.RawXCoord, Y1 = (SecP192R1FieldElement)this.RawYCoord; + SecP192R1FieldElement X2 = (SecP192R1FieldElement)b.RawXCoord, Y2 = (SecP192R1FieldElement)b.RawYCoord; + + SecP192R1FieldElement Z1 = (SecP192R1FieldElement)this.RawZCoords[0]; + SecP192R1FieldElement Z2 = (SecP192R1FieldElement)b.RawZCoords[0]; + + uint c; + uint[] tt1 = Nat192.CreateExt(); + uint[] t2 = Nat192.Create(); + uint[] t3 = Nat192.Create(); + uint[] t4 = Nat192.Create(); + + bool Z1IsOne = Z1.IsOne; + uint[] U2, S2; + if (Z1IsOne) + { + U2 = X2.x; + S2 = Y2.x; + } + else + { + S2 = t3; + SecP192R1Field.Square(Z1.x, S2); + + U2 = t2; + SecP192R1Field.Multiply(S2, X2.x, U2); + + SecP192R1Field.Multiply(S2, Z1.x, S2); + SecP192R1Field.Multiply(S2, Y2.x, S2); + } + + bool Z2IsOne = Z2.IsOne; + uint[] U1, S1; + if (Z2IsOne) + { + U1 = X1.x; + S1 = Y1.x; + } + else + { + S1 = t4; + SecP192R1Field.Square(Z2.x, S1); + + U1 = tt1; + SecP192R1Field.Multiply(S1, X1.x, U1); + + SecP192R1Field.Multiply(S1, Z2.x, S1); + SecP192R1Field.Multiply(S1, Y1.x, S1); + } + + uint[] H = Nat192.Create(); + SecP192R1Field.Subtract(U1, U2, H); + + uint[] R = t2; + SecP192R1Field.Subtract(S1, S2, R); + + // Check if b == this or b == -this + if (Nat192.IsZero(H)) + { + if (Nat192.IsZero(R)) + { + // this == b, i.e. this must be doubled + return this.Twice(); + } + + // this == -b, i.e. the result is the point at infinity + return curve.Infinity; + } + + uint[] HSquared = t3; + SecP192R1Field.Square(H, HSquared); + + uint[] G = Nat192.Create(); + SecP192R1Field.Multiply(HSquared, H, G); + + uint[] V = t3; + SecP192R1Field.Multiply(HSquared, U1, V); + + SecP192R1Field.Negate(G, G); + Nat192.Mul(S1, G, tt1); + + c = Nat192.AddBothTo(V, V, G); + SecP192R1Field.Reduce32(c, G); + + SecP192R1FieldElement X3 = new SecP192R1FieldElement(t4); + SecP192R1Field.Square(R, X3.x); + SecP192R1Field.Subtract(X3.x, G, X3.x); + + SecP192R1FieldElement Y3 = new SecP192R1FieldElement(G); + SecP192R1Field.Subtract(V, X3.x, Y3.x); + SecP192R1Field.MultiplyAddToExt(Y3.x, R, tt1); + SecP192R1Field.Reduce(tt1, Y3.x); + + SecP192R1FieldElement Z3 = new SecP192R1FieldElement(H); + if (!Z1IsOne) + { + SecP192R1Field.Multiply(Z3.x, Z1.x, Z3.x); + } + if (!Z2IsOne) + { + SecP192R1Field.Multiply(Z3.x, Z2.x, Z3.x); + } + + ECFieldElement[] zs = new ECFieldElement[] { Z3 }; + + return new SecP192R1Point(curve, X3, Y3, zs, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + SecP192R1FieldElement Y1 = (SecP192R1FieldElement)this.RawYCoord; + if (Y1.IsZero) + return curve.Infinity; + + SecP192R1FieldElement X1 = (SecP192R1FieldElement)this.RawXCoord, Z1 = (SecP192R1FieldElement)this.RawZCoords[0]; + + uint c; + uint[] t1 = Nat192.Create(); + uint[] t2 = Nat192.Create(); + + uint[] Y1Squared = Nat192.Create(); + SecP192R1Field.Square(Y1.x, Y1Squared); + + uint[] T = Nat192.Create(); + SecP192R1Field.Square(Y1Squared, T); + + bool Z1IsOne = Z1.IsOne; + + uint[] Z1Squared = Z1.x; + if (!Z1IsOne) + { + Z1Squared = t2; + SecP192R1Field.Square(Z1.x, Z1Squared); + } + + SecP192R1Field.Subtract(X1.x, Z1Squared, t1); + + uint[] M = t2; + SecP192R1Field.Add(X1.x, Z1Squared, M); + SecP192R1Field.Multiply(M, t1, M); + c = Nat192.AddBothTo(M, M, M); + SecP192R1Field.Reduce32(c, M); + + uint[] S = Y1Squared; + SecP192R1Field.Multiply(Y1Squared, X1.x, S); + c = Nat.ShiftUpBits(6, S, 2, 0); + SecP192R1Field.Reduce32(c, S); + + c = Nat.ShiftUpBits(6, T, 3, 0, t1); + SecP192R1Field.Reduce32(c, t1); + + SecP192R1FieldElement X3 = new SecP192R1FieldElement(T); + SecP192R1Field.Square(M, X3.x); + SecP192R1Field.Subtract(X3.x, S, X3.x); + SecP192R1Field.Subtract(X3.x, S, X3.x); + + SecP192R1FieldElement Y3 = new SecP192R1FieldElement(S); + SecP192R1Field.Subtract(S, X3.x, Y3.x); + SecP192R1Field.Multiply(Y3.x, M, Y3.x); + SecP192R1Field.Subtract(Y3.x, t1, Y3.x); + + SecP192R1FieldElement Z3 = new SecP192R1FieldElement(M); + SecP192R1Field.Twice(Y1.x, Z3.x); + if (!Z1IsOne) + { + SecP192R1Field.Multiply(Z3.x, Z1.x, Z3.x); + } + + return new SecP192R1Point(curve, X3, Y3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this == b) + return ThreeTimes(); + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECFieldElement Y1 = this.RawYCoord; + if (Y1.IsZero) + return b; + + return Twice().Add(b); + } + + public override ECPoint ThreeTimes() + { + if (this.IsInfinity || this.RawYCoord.IsZero) + return this; + + // NOTE: Be careful about recursions between TwicePlus and ThreeTimes + return Twice().Add(this); + } + + public override ECPoint Negate() + { + if (IsInfinity) + return this; + + return new SecP192R1Point(Curve, RawXCoord, RawYCoord.Negate(), RawZCoords, IsCompressed); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP192R1Point.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP192R1Point.cs.meta new file mode 100644 index 0000000..306d8f8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP192R1Point.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6b9911f0eabd89543b50f17045a2a274 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP224K1Curve.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP224K1Curve.cs new file mode 100644 index 0000000..dc5cd6c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP224K1Curve.cs @@ -0,0 +1,168 @@ +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP224K1Curve + : AbstractFpCurve + { + public static readonly BigInteger q = SecP224K1FieldElement.Q; + + private const int SECP224K1_DEFAULT_COORDS = COORD_JACOBIAN; + private const int SECP224K1_FE_INTS = 7; + private static readonly ECFieldElement[] SECP224K1_AFFINE_ZS = new ECFieldElement[] { new SecP224K1FieldElement(BigInteger.One) }; + + protected readonly SecP224K1Point m_infinity; + + public SecP224K1Curve() + : base(q) + { + this.m_infinity = new SecP224K1Point(this, null, null); + + this.m_a = FromBigInteger(BigInteger.Zero); + this.m_b = FromBigInteger(BigInteger.ValueOf(5)); + this.m_order = new BigInteger(1, Hex.DecodeStrict("010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7")); + this.m_cofactor = BigInteger.One; + this.m_coord = SECP224K1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecP224K1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_JACOBIAN: + return true; + default: + return false; + } + } + + public virtual BigInteger Q + { + get { return q; } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return q.BitLength; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecP224K1FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecP224K1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecP224K1Point(this, x, y, zs, withCompression); + } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + uint[] table = new uint[len * SECP224K1_FE_INTS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat224.Copy(((SecP224K1FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECP224K1_FE_INTS; + Nat224.Copy(((SecP224K1FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECP224K1_FE_INTS; + } + } + + return new SecP224K1LookupTable(this, table, len); + } + + public override ECFieldElement RandomFieldElement(SecureRandom r) + { + uint[] x = Nat224.Create(); + SecP224K1Field.Random(r, x); + return new SecP224K1FieldElement(x); + } + + public override ECFieldElement RandomFieldElementMult(SecureRandom r) + { + uint[] x = Nat224.Create(); + SecP224K1Field.RandomMult(r, x); + return new SecP224K1FieldElement(x); + } + + private class SecP224K1LookupTable + : AbstractECLookupTable + { + private readonly SecP224K1Curve m_outer; + private readonly uint[] m_table; + private readonly int m_size; + + internal SecP224K1LookupTable(SecP224K1Curve outer, uint[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public override int Size + { + get { return m_size; } + } + + public override ECPoint Lookup(int index) + { + uint[] x = Nat224.Create(), y = Nat224.Create(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + uint MASK = (uint)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECP224K1_FE_INTS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECP224K1_FE_INTS + j] & MASK; + } + + pos += (SECP224K1_FE_INTS * 2); + } + + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + uint[] x = Nat224.Create(), y = Nat224.Create(); + int pos = index * SECP224K1_FE_INTS * 2; + + for (int j = 0; j < SECP224K1_FE_INTS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECP224K1_FE_INTS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(uint[] x, uint[] y) + { + return m_outer.CreateRawPoint(new SecP224K1FieldElement(x), new SecP224K1FieldElement(y), SECP224K1_AFFINE_ZS, false); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP224K1Curve.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP224K1Curve.cs.meta new file mode 100644 index 0000000..b0e43a1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP224K1Curve.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1c8b0c1f10745c446a8eb44bf4316268 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP224K1Field.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP224K1Field.cs new file mode 100644 index 0000000..36e5364 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP224K1Field.cs @@ -0,0 +1,218 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP224K1Field + { + // 2^224 - 2^32 - 2^12 - 2^11 - 2^9 - 2^7 - 2^4 - 2 - 1 + internal static readonly uint[] P = new uint[]{ 0xFFFFE56D, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF }; + private static readonly uint[] PExt = new uint[]{ 0x02C23069, 0x00003526, 0x00000001, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xFFFFCADA, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF + }; + private static readonly uint[] PExtInv = new uint[]{ 0xFD3DCF97, 0xFFFFCAD9, 0xFFFFFFFE, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00003525, 0x00000002 }; + private const uint P6 = 0xFFFFFFFF; + private const uint PExt13 = 0xFFFFFFFF; + private const uint PInv33 = 0x1A93; + + public static void Add(uint[] x, uint[] y, uint[] z) + { + uint c = Nat224.Add(x, y, z); + if (c != 0 || (z[6] == P6 && Nat224.Gte(z, P))) + { + Nat.Add33To(7, PInv33, z); + } + } + + public static void AddExt(uint[] xx, uint[] yy, uint[] zz) + { + uint c = Nat.Add(14, xx, yy, zz); + if (c != 0 || (zz[13] == PExt13 && Nat.Gte(14, zz, PExt))) + { + if (Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0) + { + Nat.IncAt(14, zz, PExtInv.Length); + } + } + } + + public static void AddOne(uint[] x, uint[] z) + { + uint c = Nat.Inc(7, x, z); + if (c != 0 || (z[6] == P6 && Nat224.Gte(z, P))) + { + Nat.Add33To(7, PInv33, z); + } + } + + public static uint[] FromBigInteger(BigInteger x) + { + uint[] z = Nat.FromBigInteger(224, x); + if (z[6] == P6 && Nat224.Gte(z, P)) + { + Nat224.SubFrom(P, z); + } + return z; + } + + public static void Half(uint[] x, uint[] z) + { + if ((x[0] & 1) == 0) + { + Nat.ShiftDownBit(7, x, 0, z); + } + else + { + uint c = Nat224.Add(x, P, z); + Nat.ShiftDownBit(7, z, c); + } + } + + public static void Inv(uint[] x, uint[] z) + { + Mod.CheckedModOddInverse(P, x, z); + } + + public static int IsZero(uint[] x) + { + uint d = 0; + for (int i = 0; i < 7; ++i) + { + d |= x[i]; + } + d = (d >> 1) | (d & 1); + return ((int)d - 1) >> 31; + } + + public static void Multiply(uint[] x, uint[] y, uint[] z) + { + uint[] tt = Nat224.CreateExt(); + Nat224.Mul(x, y, tt); + Reduce(tt, z); + } + + public static void MultiplyAddToExt(uint[] x, uint[] y, uint[] zz) + { + uint c = Nat224.MulAddTo(x, y, zz); + if (c != 0 || (zz[13] == PExt13 && Nat.Gte(14, zz, PExt))) + { + if (Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0) + { + Nat.IncAt(14, zz, PExtInv.Length); + } + } + } + + public static void Negate(uint[] x, uint[] z) + { + if (0 != IsZero(x)) + { + Nat224.Sub(P, P, z); + } + else + { + Nat224.Sub(P, x, z); + } + } + + public static void Random(SecureRandom r, uint[] z) + { + byte[] bb = new byte[7 * 4]; + do + { + r.NextBytes(bb); + Pack.LE_To_UInt32(bb, 0, z, 0, 7); + } + while (0 == Nat.LessThan(7, z, P)); + } + + public static void RandomMult(SecureRandom r, uint[] z) + { + do + { + Random(r, z); + } + while (0 != IsZero(z)); + } + + public static void Reduce(uint[] xx, uint[] z) + { + ulong cc = Nat224.Mul33Add(PInv33, xx, 7, xx, 0, z, 0); + uint c = Nat224.Mul33DWordAdd(PInv33, cc, z, 0); + + Debug.Assert(c == 0 || c == 1); + + if (c != 0 || (z[6] == P6 && Nat224.Gte(z, P))) + { + Nat.Add33To(7, PInv33, z); + } + } + + public static void Reduce32(uint x, uint[] z) + { + if ((x != 0 && Nat224.Mul33WordAdd(PInv33, x, z, 0) != 0) + || (z[6] == P6 && Nat224.Gte(z, P))) + { + Nat.Add33To(7, PInv33, z); + } + } + + public static void Square(uint[] x, uint[] z) + { + uint[] tt = Nat224.CreateExt(); + Nat224.Square(x, tt); + Reduce(tt, z); + } + + public static void SquareN(uint[] x, int n, uint[] z) + { + Debug.Assert(n > 0); + + uint[] tt = Nat224.CreateExt(); + Nat224.Square(x, tt); + Reduce(tt, z); + + while (--n > 0) + { + Nat224.Square(z, tt); + Reduce(tt, z); + } + } + + public static void Subtract(uint[] x, uint[] y, uint[] z) + { + int c = Nat224.Sub(x, y, z); + if (c != 0) + { + Nat.Sub33From(7, PInv33, z); + } + } + + public static void SubtractExt(uint[] xx, uint[] yy, uint[] zz) + { + int c = Nat.Sub(14, xx, yy, zz); + if (c != 0) + { + if (Nat.SubFrom(PExtInv.Length, PExtInv, zz) != 0) + { + Nat.DecAt(14, zz, PExtInv.Length); + } + } + } + + public static void Twice(uint[] x, uint[] z) + { + uint c = Nat.ShiftUpBit(7, x, 0, z); + if (c != 0 || (z[6] == P6 && Nat224.Gte(z, P))) + { + Nat.Add33To(7, PInv33, z); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP224K1Field.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP224K1Field.cs.meta new file mode 100644 index 0000000..dc287f3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP224K1Field.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1766e107e877ed14e8287cd201b5dd81 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP224K1FieldElement.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP224K1FieldElement.cs new file mode 100644 index 0000000..eb74041 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP224K1FieldElement.cs @@ -0,0 +1,244 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP224K1FieldElement + : AbstractFpFieldElement + { + public static readonly BigInteger Q = new BigInteger(1, + Hex.DecodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D")); + + // Calculated as BigInteger.Two.ModPow(Q.ShiftRight(2), Q) + private static readonly uint[] PRECOMP_POW2 = new uint[]{ 0x33bfd202, 0xdcfad133, 0x2287624a, 0xc3811ba8, + 0xa85558fc, 0x1eaef5d7, 0x8edf154c }; + + protected internal readonly uint[] x; + + public SecP224K1FieldElement(BigInteger x) + { + if (x == null || x.SignValue < 0 || x.CompareTo(Q) >= 0) + throw new ArgumentException("value invalid for SecP224K1FieldElement", "x"); + + this.x = SecP224K1Field.FromBigInteger(x); + } + + public SecP224K1FieldElement() + { + this.x = Nat224.Create(); + } + + protected internal SecP224K1FieldElement(uint[] x) + { + this.x = x; + } + + public override bool IsZero + { + get { return Nat224.IsZero(x); } + } + + public override bool IsOne + { + get { return Nat224.IsOne(x); } + } + + public override bool TestBitZero() + { + return Nat224.GetBit(x, 0) == 1; + } + + public override BigInteger ToBigInteger() + { + return Nat224.ToBigInteger(x); + } + + public override string FieldName + { + get { return "SecP224K1Field"; } + } + + public override int FieldSize + { + get { return Q.BitLength; } + } + + public override ECFieldElement Add(ECFieldElement b) + { + uint[] z = Nat224.Create(); + SecP224K1Field.Add(x, ((SecP224K1FieldElement)b).x, z); + return new SecP224K1FieldElement(z); + } + + public override ECFieldElement AddOne() + { + uint[] z = Nat224.Create(); + SecP224K1Field.AddOne(x, z); + return new SecP224K1FieldElement(z); + } + + public override ECFieldElement Subtract(ECFieldElement b) + { + uint[] z = Nat224.Create(); + SecP224K1Field.Subtract(x, ((SecP224K1FieldElement)b).x, z); + return new SecP224K1FieldElement(z); + } + + public override ECFieldElement Multiply(ECFieldElement b) + { + uint[] z = Nat224.Create(); + SecP224K1Field.Multiply(x, ((SecP224K1FieldElement)b).x, z); + return new SecP224K1FieldElement(z); + } + + public override ECFieldElement Divide(ECFieldElement b) + { + //return Multiply(b.Invert()); + uint[] z = Nat224.Create(); + SecP224K1Field.Inv(((SecP224K1FieldElement)b).x, z); + SecP224K1Field.Multiply(z, x, z); + return new SecP224K1FieldElement(z); + } + + public override ECFieldElement Negate() + { + uint[] z = Nat224.Create(); + SecP224K1Field.Negate(x, z); + return new SecP224K1FieldElement(z); + } + + public override ECFieldElement Square() + { + uint[] z = Nat224.Create(); + SecP224K1Field.Square(x, z); + return new SecP224K1FieldElement(z); + } + + public override ECFieldElement Invert() + { + //return new SecP224K1FieldElement(ToBigInteger().ModInverse(Q)); + uint[] z = Nat224.Create(); + SecP224K1Field.Inv(x, z); + return new SecP224K1FieldElement(z); + } + + /** + * return a sqrt root - the routine verifies that the calculation returns the right value - if + * none exists it returns null. + */ + public override ECFieldElement Sqrt() + { + /* + * Q == 8m + 5, so we use Pocklington's method for this case. + * + * First, raise this element to the exponent 2^221 - 2^29 - 2^9 - 2^8 - 2^6 - 2^4 - 2^1 (i.e. m + 1) + * + * Breaking up the exponent's binary representation into "repunits", we get: + * { 191 1s } { 1 0s } { 19 1s } { 2 0s } { 1 1s } { 1 0s } { 1 1s } { 1 0s } { 3 1s } { 1 0s } + * + * Therefore we need an addition chain containing 1, 3, 19, 191 (the lengths of the repunits) + * We use: [1], 2, [3], 4, 8, 11, [19], 23, 42, 84, 107, [191] + */ + + uint[] x1 = this.x; + if (Nat224.IsZero(x1) || Nat224.IsOne(x1)) + return this; + + uint[] x2 = Nat224.Create(); + SecP224K1Field.Square(x1, x2); + SecP224K1Field.Multiply(x2, x1, x2); + uint[] x3 = x2; + SecP224K1Field.Square(x2, x3); + SecP224K1Field.Multiply(x3, x1, x3); + uint[] x4 = Nat224.Create(); + SecP224K1Field.Square(x3, x4); + SecP224K1Field.Multiply(x4, x1, x4); + uint[] x8 = Nat224.Create(); + SecP224K1Field.SquareN(x4, 4, x8); + SecP224K1Field.Multiply(x8, x4, x8); + uint[] x11 = Nat224.Create(); + SecP224K1Field.SquareN(x8, 3, x11); + SecP224K1Field.Multiply(x11, x3, x11); + uint[] x19 = x11; + SecP224K1Field.SquareN(x11, 8, x19); + SecP224K1Field.Multiply(x19, x8, x19); + uint[] x23 = x8; + SecP224K1Field.SquareN(x19, 4, x23); + SecP224K1Field.Multiply(x23, x4, x23); + uint[] x42 = x4; + SecP224K1Field.SquareN(x23, 19, x42); + SecP224K1Field.Multiply(x42, x19, x42); + uint[] x84 = Nat224.Create(); + SecP224K1Field.SquareN(x42, 42, x84); + SecP224K1Field.Multiply(x84, x42, x84); + uint[] x107 = x42; + SecP224K1Field.SquareN(x84, 23, x107); + SecP224K1Field.Multiply(x107, x23, x107); + uint[] x191 = x23; + SecP224K1Field.SquareN(x107, 84, x191); + SecP224K1Field.Multiply(x191, x84, x191); + + uint[] t1 = x191; + SecP224K1Field.SquareN(t1, 20, t1); + SecP224K1Field.Multiply(t1, x19, t1); + SecP224K1Field.SquareN(t1, 3, t1); + SecP224K1Field.Multiply(t1, x1, t1); + SecP224K1Field.SquareN(t1, 2, t1); + SecP224K1Field.Multiply(t1, x1, t1); + SecP224K1Field.SquareN(t1, 4, t1); + SecP224K1Field.Multiply(t1, x3, t1); + SecP224K1Field.Square(t1, t1); + + uint[] t2 = x84; + SecP224K1Field.Square(t1, t2); + + if (Nat224.Eq(x1, t2)) + { + return new SecP224K1FieldElement(t1); + } + + /* + * If the first guess is incorrect, we multiply by a precomputed power of 2 to get the second guess, + * which is ((4x)^(m + 1))/2 mod Q + */ + SecP224K1Field.Multiply(t1, PRECOMP_POW2, t1); + + SecP224K1Field.Square(t1, t2); + + if (Nat224.Eq(x1, t2)) + { + return new SecP224K1FieldElement(t1); + } + + return null; + } + + public override bool Equals(object obj) + { + return Equals(obj as SecP224K1FieldElement); + } + + public override bool Equals(ECFieldElement other) + { + return Equals(other as SecP224K1FieldElement); + } + + public virtual bool Equals(SecP224K1FieldElement other) + { + if (this == other) + return true; + if (null == other) + return false; + return Nat224.Eq(x, other.x); + } + + public override int GetHashCode() + { + return Q.GetHashCode() ^ Arrays.GetHashCode(x, 0, 7); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP224K1FieldElement.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP224K1FieldElement.cs.meta new file mode 100644 index 0000000..f5d6ed9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP224K1FieldElement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7b6b30eab3bca83489b160352e716b4a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP224K1Point.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP224K1Point.cs new file mode 100644 index 0000000..98cb292 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP224K1Point.cs @@ -0,0 +1,267 @@ +using System; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP224K1Point + : AbstractFpPoint + { + /** + * Create a point which encodes with point compression. + * + * @param curve + * the curve to use + * @param x + * affine x co-ordinate + * @param y + * affine y co-ordinate + * + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecP224K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * Create a point that encodes with or without point compresion. + * + * @param curve + * the curve to use + * @param x + * affine x co-ordinate + * @param y + * affine y co-ordinate + * @param withCompression + * if true encode with point compression + * + * @deprecated per-point compression property will be removed, refer + * {@link #getEncoded(bool)} + */ + public SecP224K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecP224K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, + bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecP224K1Point(null, AffineXCoord, AffineYCoord); + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + if (this == b) + return Twice(); + + ECCurve curve = this.Curve; + + SecP224K1FieldElement X1 = (SecP224K1FieldElement)this.RawXCoord, Y1 = (SecP224K1FieldElement)this.RawYCoord; + SecP224K1FieldElement X2 = (SecP224K1FieldElement)b.RawXCoord, Y2 = (SecP224K1FieldElement)b.RawYCoord; + + SecP224K1FieldElement Z1 = (SecP224K1FieldElement)this.RawZCoords[0]; + SecP224K1FieldElement Z2 = (SecP224K1FieldElement)b.RawZCoords[0]; + + uint c; + uint[] tt1 = Nat224.CreateExt(); + uint[] t2 = Nat224.Create(); + uint[] t3 = Nat224.Create(); + uint[] t4 = Nat224.Create(); + + bool Z1IsOne = Z1.IsOne; + uint[] U2, S2; + if (Z1IsOne) + { + U2 = X2.x; + S2 = Y2.x; + } + else + { + S2 = t3; + SecP224K1Field.Square(Z1.x, S2); + + U2 = t2; + SecP224K1Field.Multiply(S2, X2.x, U2); + + SecP224K1Field.Multiply(S2, Z1.x, S2); + SecP224K1Field.Multiply(S2, Y2.x, S2); + } + + bool Z2IsOne = Z2.IsOne; + uint[] U1, S1; + if (Z2IsOne) + { + U1 = X1.x; + S1 = Y1.x; + } + else + { + S1 = t4; + SecP224K1Field.Square(Z2.x, S1); + + U1 = tt1; + SecP224K1Field.Multiply(S1, X1.x, U1); + + SecP224K1Field.Multiply(S1, Z2.x, S1); + SecP224K1Field.Multiply(S1, Y1.x, S1); + } + + uint[] H = Nat224.Create(); + SecP224K1Field.Subtract(U1, U2, H); + + uint[] R = t2; + SecP224K1Field.Subtract(S1, S2, R); + + // Check if b == this or b == -this + if (Nat224.IsZero(H)) + { + if (Nat224.IsZero(R)) + { + // this == b, i.e. this must be doubled + return this.Twice(); + } + + // this == -b, i.e. the result is the point at infinity + return curve.Infinity; + } + + uint[] HSquared = t3; + SecP224K1Field.Square(H, HSquared); + + uint[] G = Nat224.Create(); + SecP224K1Field.Multiply(HSquared, H, G); + + uint[] V = t3; + SecP224K1Field.Multiply(HSquared, U1, V); + + SecP224K1Field.Negate(G, G); + Nat224.Mul(S1, G, tt1); + + c = Nat224.AddBothTo(V, V, G); + SecP224K1Field.Reduce32(c, G); + + SecP224K1FieldElement X3 = new SecP224K1FieldElement(t4); + SecP224K1Field.Square(R, X3.x); + SecP224K1Field.Subtract(X3.x, G, X3.x); + + SecP224K1FieldElement Y3 = new SecP224K1FieldElement(G); + SecP224K1Field.Subtract(V, X3.x, Y3.x); + SecP224K1Field.MultiplyAddToExt(Y3.x, R, tt1); + SecP224K1Field.Reduce(tt1, Y3.x); + + SecP224K1FieldElement Z3 = new SecP224K1FieldElement(H); + if (!Z1IsOne) + { + SecP224K1Field.Multiply(Z3.x, Z1.x, Z3.x); + } + if (!Z2IsOne) + { + SecP224K1Field.Multiply(Z3.x, Z2.x, Z3.x); + } + + ECFieldElement[] zs = new ECFieldElement[] { Z3 }; + + return new SecP224K1Point(curve, X3, Y3, zs, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + SecP224K1FieldElement Y1 = (SecP224K1FieldElement)this.RawYCoord; + if (Y1.IsZero) + return curve.Infinity; + + SecP224K1FieldElement X1 = (SecP224K1FieldElement)this.RawXCoord, Z1 = (SecP224K1FieldElement)this.RawZCoords[0]; + + uint c; + + uint[] Y1Squared = Nat224.Create(); + SecP224K1Field.Square(Y1.x, Y1Squared); + + uint[] T = Nat224.Create(); + SecP224K1Field.Square(Y1Squared, T); + + uint[] M = Nat224.Create(); + SecP224K1Field.Square(X1.x, M); + c = Nat224.AddBothTo(M, M, M); + SecP224K1Field.Reduce32(c, M); + + uint[] S = Y1Squared; + SecP224K1Field.Multiply(Y1Squared, X1.x, S); + c = Nat.ShiftUpBits(7, S, 2, 0); + SecP224K1Field.Reduce32(c, S); + + uint[] t1 = Nat224.Create(); + c = Nat.ShiftUpBits(7, T, 3, 0, t1); + SecP224K1Field.Reduce32(c, t1); + + SecP224K1FieldElement X3 = new SecP224K1FieldElement(T); + SecP224K1Field.Square(M, X3.x); + SecP224K1Field.Subtract(X3.x, S, X3.x); + SecP224K1Field.Subtract(X3.x, S, X3.x); + + SecP224K1FieldElement Y3 = new SecP224K1FieldElement(S); + SecP224K1Field.Subtract(S, X3.x, Y3.x); + SecP224K1Field.Multiply(Y3.x, M, Y3.x); + SecP224K1Field.Subtract(Y3.x, t1, Y3.x); + + SecP224K1FieldElement Z3 = new SecP224K1FieldElement(M); + SecP224K1Field.Twice(Y1.x, Z3.x); + if (!Z1.IsOne) + { + SecP224K1Field.Multiply(Z3.x, Z1.x, Z3.x); + } + + return new SecP224K1Point(curve, X3, Y3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this == b) + return ThreeTimes(); + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECFieldElement Y1 = this.RawYCoord; + if (Y1.IsZero) + return b; + + return Twice().Add(b); + } + + public override ECPoint ThreeTimes() + { + if (this.IsInfinity || this.RawYCoord.IsZero) + return this; + + // NOTE: Be careful about recursions between TwicePlus and ThreeTimes + return Twice().Add(this); + } + + public override ECPoint Negate() + { + if (IsInfinity) + return this; + + return new SecP224K1Point(Curve, RawXCoord, RawYCoord.Negate(), RawZCoords, IsCompressed); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP224K1Point.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP224K1Point.cs.meta new file mode 100644 index 0000000..531fa7b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP224K1Point.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: de61e160cad4d7d48a8f64b634332872 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP224R1Curve.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP224R1Curve.cs new file mode 100644 index 0000000..8e79316 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP224R1Curve.cs @@ -0,0 +1,171 @@ +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP224R1Curve + : AbstractFpCurve + { + public static readonly BigInteger q = SecP224R1FieldElement.Q; + + private const int SECP224R1_DEFAULT_COORDS = COORD_JACOBIAN; + private const int SECP224R1_FE_INTS = 7; + private static readonly ECFieldElement[] SECP224R1_AFFINE_ZS = new ECFieldElement[] { new SecP224R1FieldElement(BigInteger.One) }; + + protected readonly SecP224R1Point m_infinity; + + public SecP224R1Curve() + : base(q) + { + this.m_infinity = new SecP224R1Point(this, null, null); + + this.m_a = FromBigInteger(new BigInteger(1, + Hex.DecodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE"))); + this.m_b = FromBigInteger(new BigInteger(1, + Hex.DecodeStrict("B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4"))); + this.m_order = new BigInteger(1, Hex.DecodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D")); + this.m_cofactor = BigInteger.One; + + this.m_coord = SECP224R1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecP224R1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_JACOBIAN: + return true; + default: + return false; + } + } + + public virtual BigInteger Q + { + get { return q; } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return q.BitLength; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecP224R1FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecP224R1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecP224R1Point(this, x, y, zs, withCompression); + } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + uint[] table = new uint[len * SECP224R1_FE_INTS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat224.Copy(((SecP224R1FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECP224R1_FE_INTS; + Nat224.Copy(((SecP224R1FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECP224R1_FE_INTS; + } + } + + return new SecP224R1LookupTable(this, table, len); + } + + public override ECFieldElement RandomFieldElement(SecureRandom r) + { + uint[] x = Nat224.Create(); + SecP224R1Field.Random(r, x); + return new SecP224R1FieldElement(x); + } + + public override ECFieldElement RandomFieldElementMult(SecureRandom r) + { + uint[] x = Nat224.Create(); + SecP224R1Field.RandomMult(r, x); + return new SecP224R1FieldElement(x); + } + + private class SecP224R1LookupTable + : AbstractECLookupTable + { + private readonly SecP224R1Curve m_outer; + private readonly uint[] m_table; + private readonly int m_size; + + internal SecP224R1LookupTable(SecP224R1Curve outer, uint[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public override int Size + { + get { return m_size; } + } + + public override ECPoint Lookup(int index) + { + uint[] x = Nat224.Create(), y = Nat224.Create(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + uint MASK = (uint)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECP224R1_FE_INTS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECP224R1_FE_INTS + j] & MASK; + } + + pos += (SECP224R1_FE_INTS * 2); + } + + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + uint[] x = Nat224.Create(), y = Nat224.Create(); + int pos = index * SECP224R1_FE_INTS * 2; + + for (int j = 0; j < SECP224R1_FE_INTS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECP224R1_FE_INTS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(uint[] x, uint[] y) + { + return m_outer.CreateRawPoint(new SecP224R1FieldElement(x), new SecP224R1FieldElement(y), SECP224R1_AFFINE_ZS, false); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP224R1Curve.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP224R1Curve.cs.meta new file mode 100644 index 0000000..65d73d2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP224R1Curve.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d57c00e9ef4844b49bdbfd35c0a32f97 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP224R1Field.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP224R1Field.cs new file mode 100644 index 0000000..242f8f3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP224R1Field.cs @@ -0,0 +1,337 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP224R1Field + { + // 2^224 - 2^96 + 1 + internal static readonly uint[] P = new uint[]{ 0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF }; + private static readonly uint[] PExt = new uint[]{ 0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF, + 0xFFFFFFFF, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF + }; + private static readonly uint[] PExtInv = new uint[]{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000001, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000001 }; + private const uint P6 = 0xFFFFFFFF; + private const uint PExt13 = 0xFFFFFFFF; + + public static void Add(uint[] x, uint[] y, uint[] z) + { + uint c = Nat224.Add(x, y, z); + if (c != 0 || (z[6] == P6 && Nat224.Gte(z, P))) + { + AddPInvTo(z); + } + } + + public static void AddExt(uint[] xx, uint[] yy, uint[] zz) + { + uint c = Nat.Add(14, xx, yy, zz); + if (c != 0 || (zz[13] == PExt13 && Nat.Gte(14, zz, PExt))) + { + if (Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0) + { + Nat.IncAt(14, zz, PExtInv.Length); + } + } + } + + public static void AddOne(uint[] x, uint[] z) + { + uint c = Nat.Inc(7, x, z); + if (c != 0 || (z[6] == P6 && Nat224.Gte(z, P))) + { + AddPInvTo(z); + } + } + + public static uint[] FromBigInteger(BigInteger x) + { + uint[] z = Nat.FromBigInteger(224, x); + if (z[6] == P6 && Nat224.Gte(z, P)) + { + Nat224.SubFrom(P, z); + } + return z; + } + + public static void Half(uint[] x, uint[] z) + { + if ((x[0] & 1) == 0) + { + Nat.ShiftDownBit(7, x, 0, z); + } + else + { + uint c = Nat224.Add(x, P, z); + Nat.ShiftDownBit(7, z, c); + } + } + + public static void Inv(uint[] x, uint[] z) + { + Mod.CheckedModOddInverse(P, x, z); + } + + public static int IsZero(uint[] x) + { + uint d = 0; + for (int i = 0; i < 7; ++i) + { + d |= x[i]; + } + d = (d >> 1) | (d & 1); + return ((int)d - 1) >> 31; + } + + public static void Multiply(uint[] x, uint[] y, uint[] z) + { + uint[] tt = Nat224.CreateExt(); + Nat224.Mul(x, y, tt); + Reduce(tt, z); + } + + public static void MultiplyAddToExt(uint[] x, uint[] y, uint[] zz) + { + uint c = Nat224.MulAddTo(x, y, zz); + if (c != 0 || (zz[13] == PExt13 && Nat.Gte(14, zz, PExt))) + { + if (Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0) + { + Nat.IncAt(14, zz, PExtInv.Length); + } + } + } + + public static void Negate(uint[] x, uint[] z) + { + if (0 != IsZero(x)) + { + Nat224.Sub(P, P, z); + } + else + { + Nat224.Sub(P, x, z); + } + } + + public static void Random(SecureRandom r, uint[] z) + { + byte[] bb = new byte[7 * 4]; + do + { + r.NextBytes(bb); + Pack.LE_To_UInt32(bb, 0, z, 0, 7); + } + while (0 == Nat.LessThan(7, z, P)); + } + + public static void RandomMult(SecureRandom r, uint[] z) + { + do + { + Random(r, z); + } + while (0 != IsZero(z)); + } + + public static void Reduce(uint[] xx, uint[] z) + { + long xx10 = xx[10], xx11 = xx[11], xx12 = xx[12], xx13 = xx[13]; + + const long n = 1; + + long t0 = (long)xx[7] + xx11 - n; + long t1 = (long)xx[8] + xx12; + long t2 = (long)xx[9] + xx13; + + long cc = 0; + cc += (long)xx[0] - t0; + long z0 = (uint)cc; + cc >>= 32; + cc += (long)xx[1] - t1; + z[1] = (uint)cc; + cc >>= 32; + cc += (long)xx[2] - t2; + z[2] = (uint)cc; + cc >>= 32; + cc += (long)xx[3] + t0 - xx10; + long z3 = (uint)cc; + cc >>= 32; + cc += (long)xx[4] + t1 - xx11; + z[4] = (uint)cc; + cc >>= 32; + cc += (long)xx[5] + t2 - xx12; + z[5] = (uint)cc; + cc >>= 32; + cc += (long)xx[6] + xx10 - xx13; + z[6] = (uint)cc; + cc >>= 32; + cc += n; + + Debug.Assert(cc >= 0); + + z3 += cc; + + z0 -= cc; + z[0] = (uint)z0; + cc = z0 >> 32; + if (cc != 0) + { + cc += (long)z[1]; + z[1] = (uint)cc; + cc >>= 32; + cc += (long)z[2]; + z[2] = (uint)cc; + z3 += cc >> 32; + } + z[3] = (uint)z3; + cc = z3 >> 32; + + Debug.Assert(cc == 0 || cc == 1); + + if ((cc != 0 && Nat.IncAt(7, z, 4) != 0) + || (z[6] == P6 && Nat224.Gte(z, P))) + { + AddPInvTo(z); + } + } + + public static void Reduce32(uint x, uint[] z) + { + long cc = 0; + + if (x != 0) + { + long xx07 = x; + + cc += (long)z[0] - xx07; + z[0] = (uint)cc; + cc >>= 32; + if (cc != 0) + { + cc += (long)z[1]; + z[1] = (uint)cc; + cc >>= 32; + cc += (long)z[2]; + z[2] = (uint)cc; + cc >>= 32; + } + cc += (long)z[3] + xx07; + z[3] = (uint)cc; + cc >>= 32; + + Debug.Assert(cc == 0 || cc == 1); + } + + if ((cc != 0 && Nat.IncAt(7, z, 4) != 0) + || (z[6] == P6 && Nat224.Gte(z, P))) + { + AddPInvTo(z); + } + } + + public static void Square(uint[] x, uint[] z) + { + uint[] tt = Nat224.CreateExt(); + Nat224.Square(x, tt); + Reduce(tt, z); + } + + public static void SquareN(uint[] x, int n, uint[] z) + { + Debug.Assert(n > 0); + + uint[] tt = Nat224.CreateExt(); + Nat224.Square(x, tt); + Reduce(tt, z); + + while (--n > 0) + { + Nat224.Square(z, tt); + Reduce(tt, z); + } + } + + public static void Subtract(uint[] x, uint[] y, uint[] z) + { + int c = Nat224.Sub(x, y, z); + if (c != 0) + { + SubPInvFrom(z); + } + } + + public static void SubtractExt(uint[] xx, uint[] yy, uint[] zz) + { + int c = Nat.Sub(14, xx, yy, zz); + if (c != 0) + { + if (Nat.SubFrom(PExtInv.Length, PExtInv, zz) != 0) + { + Nat.DecAt(14, zz, PExtInv.Length); + } + } + } + + public static void Twice(uint[] x, uint[] z) + { + uint c = Nat.ShiftUpBit(7, x, 0, z); + if (c != 0 || (z[6] == P6 && Nat224.Gte(z, P))) + { + AddPInvTo(z); + } + } + + private static void AddPInvTo(uint[] z) + { + long c = (long)z[0] - 1; + z[0] = (uint)c; + c >>= 32; + if (c != 0) + { + c += (long)z[1]; + z[1] = (uint)c; + c >>= 32; + c += (long)z[2]; + z[2] = (uint)c; + c >>= 32; + } + c += (long)z[3] + 1; + z[3] = (uint)c; + c >>= 32; + if (c != 0) + { + Nat.IncAt(7, z, 4); + } + } + + private static void SubPInvFrom(uint[] z) + { + long c = (long)z[0] + 1; + z[0] = (uint)c; + c >>= 32; + if (c != 0) + { + c += (long)z[1]; + z[1] = (uint)c; + c >>= 32; + c += (long)z[2]; + z[2] = (uint)c; + c >>= 32; + } + c += (long)z[3] - 1; + z[3] = (uint)c; + c >>= 32; + if (c != 0) + { + Nat.DecAt(7, z, 4); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP224R1Field.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP224R1Field.cs.meta new file mode 100644 index 0000000..3646dfc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP224R1Field.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 49c402bc18d41c048a87ccf2f0b864c8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP224R1FieldElement.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP224R1FieldElement.cs new file mode 100644 index 0000000..bb60eda --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP224R1FieldElement.cs @@ -0,0 +1,271 @@ +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP224R1FieldElement + : AbstractFpFieldElement + { + public static readonly BigInteger Q = new BigInteger(1, + Hex.DecodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001")); + + protected internal readonly uint[] x; + + public SecP224R1FieldElement(BigInteger x) + { + if (x == null || x.SignValue < 0 || x.CompareTo(Q) >= 0) + throw new ArgumentException("value invalid for SecP224R1FieldElement", "x"); + + this.x = SecP224R1Field.FromBigInteger(x); + } + + public SecP224R1FieldElement() + { + this.x = Nat224.Create(); + } + + protected internal SecP224R1FieldElement(uint[] x) + { + this.x = x; + } + + public override bool IsZero + { + get { return Nat224.IsZero(x); } + } + + public override bool IsOne + { + get { return Nat224.IsOne(x); } + } + + public override bool TestBitZero() + { + return Nat224.GetBit(x, 0) == 1; + } + + public override BigInteger ToBigInteger() + { + return Nat224.ToBigInteger(x); + } + + public override string FieldName + { + get { return "SecP224R1Field"; } + } + + public override int FieldSize + { + get { return Q.BitLength; } + } + + public override ECFieldElement Add(ECFieldElement b) + { + uint[] z = Nat224.Create(); + SecP224R1Field.Add(x, ((SecP224R1FieldElement)b).x, z); + return new SecP224R1FieldElement(z); + } + + public override ECFieldElement AddOne() + { + uint[] z = Nat224.Create(); + SecP224R1Field.AddOne(x, z); + return new SecP224R1FieldElement(z); + } + + public override ECFieldElement Subtract(ECFieldElement b) + { + uint[] z = Nat224.Create(); + SecP224R1Field.Subtract(x, ((SecP224R1FieldElement)b).x, z); + return new SecP224R1FieldElement(z); + } + + public override ECFieldElement Multiply(ECFieldElement b) + { + uint[] z = Nat224.Create(); + SecP224R1Field.Multiply(x, ((SecP224R1FieldElement)b).x, z); + return new SecP224R1FieldElement(z); + } + + public override ECFieldElement Divide(ECFieldElement b) + { + //return Multiply(b.Invert()); + uint[] z = Nat224.Create(); + SecP224R1Field.Inv(((SecP224R1FieldElement)b).x, z); + SecP224R1Field.Multiply(z, x, z); + return new SecP224R1FieldElement(z); + } + + public override ECFieldElement Negate() + { + uint[] z = Nat224.Create(); + SecP224R1Field.Negate(x, z); + return new SecP224R1FieldElement(z); + } + + public override ECFieldElement Square() + { + uint[] z = Nat224.Create(); + SecP224R1Field.Square(x, z); + return new SecP224R1FieldElement(z); + } + + public override ECFieldElement Invert() + { + //return new SecP224R1FieldElement(ToBigInteger().ModInverse(Q)); + uint[] z = Nat224.Create(); + SecP224R1Field.Inv(x, z); + return new SecP224R1FieldElement(z); + } + + /** + * return a sqrt root - the routine verifies that the calculation returns the right value - if + * none exists it returns null. + */ + public override ECFieldElement Sqrt() + { + uint[] c = this.x; + if (Nat224.IsZero(c) || Nat224.IsOne(c)) + return this; + + uint[] nc = Nat224.Create(); + SecP224R1Field.Negate(c, nc); + + uint[] r = Mod.Random(SecP224R1Field.P); + uint[] t = Nat224.Create(); + + if (!IsSquare(c)) + return null; + + while (!TrySqrt(nc, r, t)) + { + SecP224R1Field.AddOne(r, r); + } + + SecP224R1Field.Square(t, r); + + return Nat224.Eq(c, r) ? new SecP224R1FieldElement(t) : null; + } + + public override bool Equals(object obj) + { + return Equals(obj as SecP224R1FieldElement); + } + + public override bool Equals(ECFieldElement other) + { + return Equals(other as SecP224R1FieldElement); + } + + public virtual bool Equals(SecP224R1FieldElement other) + { + if (this == other) + return true; + if (null == other) + return false; + return Nat224.Eq(x, other.x); + } + + public override int GetHashCode() + { + return Q.GetHashCode() ^ Arrays.GetHashCode(x, 0, 7); + } + + private static bool IsSquare(uint[] x) + { + uint[] t1 = Nat224.Create(); + uint[] t2 = Nat224.Create(); + Nat224.Copy(x, t1); + + for (int i = 0; i < 7; ++i) + { + Nat224.Copy(t1, t2); + SecP224R1Field.SquareN(t1, 1 << i, t1); + SecP224R1Field.Multiply(t1, t2, t1); + } + + SecP224R1Field.SquareN(t1, 95, t1); + return Nat224.IsOne(t1); + } + + private static void RM(uint[] nc, uint[] d0, uint[] e0, uint[] d1, uint[] e1, uint[] f1, uint[] t) + { + SecP224R1Field.Multiply(e1, e0, t); + SecP224R1Field.Multiply(t, nc, t); + SecP224R1Field.Multiply(d1, d0, f1); + SecP224R1Field.Add(f1, t, f1); + SecP224R1Field.Multiply(d1, e0, t); + Nat224.Copy(f1, d1); + SecP224R1Field.Multiply(e1, d0, e1); + SecP224R1Field.Add(e1, t, e1); + SecP224R1Field.Square(e1, f1); + SecP224R1Field.Multiply(f1, nc, f1); + } + + private static void RP(uint[] nc, uint[] d1, uint[] e1, uint[] f1, uint[] t) + { + Nat224.Copy(nc, f1); + + uint[] d0 = Nat224.Create(); + uint[] e0 = Nat224.Create(); + + for (int i = 0; i < 7; ++i) + { + Nat224.Copy(d1, d0); + Nat224.Copy(e1, e0); + + int j = 1 << i; + while (--j >= 0) + { + RS(d1, e1, f1, t); + } + + RM(nc, d0, e0, d1, e1, f1, t); + } + } + + private static void RS(uint[] d, uint[] e, uint[] f, uint[] t) + { + SecP224R1Field.Multiply(e, d, e); + SecP224R1Field.Twice(e, e); + SecP224R1Field.Square(d, t); + SecP224R1Field.Add(f, t, d); + SecP224R1Field.Multiply(f, t, f); + uint c = Nat.ShiftUpBits(7, f, 2, 0); + SecP224R1Field.Reduce32(c, f); + } + + private static bool TrySqrt(uint[] nc, uint[] r, uint[] t) + { + uint[] d1 = Nat224.Create(); + Nat224.Copy(r, d1); + uint[] e1 = Nat224.Create(); + e1[0] = 1; + uint[] f1 = Nat224.Create(); + RP(nc, d1, e1, f1, t); + + uint[] d0 = Nat224.Create(); + uint[] e0 = Nat224.Create(); + + for (int k = 1; k < 96; ++k) + { + Nat224.Copy(d1, d0); + Nat224.Copy(e1, e0); + + RS(d1, e1, f1, t); + + if (Nat224.IsZero(d1)) + { + SecP224R1Field.Inv(e0, t); + SecP224R1Field.Multiply(t, d0, t); + return true; + } + } + + return false; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP224R1FieldElement.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP224R1FieldElement.cs.meta new file mode 100644 index 0000000..47381b1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP224R1FieldElement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 40622e93f8e97064eae6c3c3f0f48463 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP224R1Point.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP224R1Point.cs new file mode 100644 index 0000000..73c4f19 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP224R1Point.cs @@ -0,0 +1,279 @@ +using System; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP224R1Point + : AbstractFpPoint + { + /** + * Create a point which encodes with point compression. + * + * @param curve + * the curve to use + * @param x + * affine x co-ordinate + * @param y + * affine y co-ordinate + * + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecP224R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * Create a point that encodes with or without point compresion. + * + * @param curve + * the curve to use + * @param x + * affine x co-ordinate + * @param y + * affine y co-ordinate + * @param withCompression + * if true encode with point compression + * + * @deprecated per-point compression property will be removed, refer + * {@link #getEncoded(bool)} + */ + public SecP224R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecP224R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecP224R1Point(null, AffineXCoord, AffineYCoord); + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + if (this == b) + return Twice(); + + ECCurve curve = this.Curve; + + SecP224R1FieldElement X1 = (SecP224R1FieldElement)this.RawXCoord, Y1 = (SecP224R1FieldElement)this.RawYCoord; + SecP224R1FieldElement X2 = (SecP224R1FieldElement)b.RawXCoord, Y2 = (SecP224R1FieldElement)b.RawYCoord; + + SecP224R1FieldElement Z1 = (SecP224R1FieldElement)this.RawZCoords[0]; + SecP224R1FieldElement Z2 = (SecP224R1FieldElement)b.RawZCoords[0]; + + uint c; + uint[] tt1 = Nat224.CreateExt(); + uint[] t2 = Nat224.Create(); + uint[] t3 = Nat224.Create(); + uint[] t4 = Nat224.Create(); + + bool Z1IsOne = Z1.IsOne; + uint[] U2, S2; + if (Z1IsOne) + { + U2 = X2.x; + S2 = Y2.x; + } + else + { + S2 = t3; + SecP224R1Field.Square(Z1.x, S2); + + U2 = t2; + SecP224R1Field.Multiply(S2, X2.x, U2); + + SecP224R1Field.Multiply(S2, Z1.x, S2); + SecP224R1Field.Multiply(S2, Y2.x, S2); + } + + bool Z2IsOne = Z2.IsOne; + uint[] U1, S1; + if (Z2IsOne) + { + U1 = X1.x; + S1 = Y1.x; + } + else + { + S1 = t4; + SecP224R1Field.Square(Z2.x, S1); + + U1 = tt1; + SecP224R1Field.Multiply(S1, X1.x, U1); + + SecP224R1Field.Multiply(S1, Z2.x, S1); + SecP224R1Field.Multiply(S1, Y1.x, S1); + } + + uint[] H = Nat224.Create(); + SecP224R1Field.Subtract(U1, U2, H); + + uint[] R = t2; + SecP224R1Field.Subtract(S1, S2, R); + + // Check if b == this or b == -this + if (Nat224.IsZero(H)) + { + if (Nat224.IsZero(R)) + { + // this == b, i.e. this must be doubled + return this.Twice(); + } + + // this == -b, i.e. the result is the point at infinity + return curve.Infinity; + } + + uint[] HSquared = t3; + SecP224R1Field.Square(H, HSquared); + + uint[] G = Nat224.Create(); + SecP224R1Field.Multiply(HSquared, H, G); + + uint[] V = t3; + SecP224R1Field.Multiply(HSquared, U1, V); + + SecP224R1Field.Negate(G, G); + Nat224.Mul(S1, G, tt1); + + c = Nat224.AddBothTo(V, V, G); + SecP224R1Field.Reduce32(c, G); + + SecP224R1FieldElement X3 = new SecP224R1FieldElement(t4); + SecP224R1Field.Square(R, X3.x); + SecP224R1Field.Subtract(X3.x, G, X3.x); + + SecP224R1FieldElement Y3 = new SecP224R1FieldElement(G); + SecP224R1Field.Subtract(V, X3.x, Y3.x); + SecP224R1Field.MultiplyAddToExt(Y3.x, R, tt1); + SecP224R1Field.Reduce(tt1, Y3.x); + + SecP224R1FieldElement Z3 = new SecP224R1FieldElement(H); + if (!Z1IsOne) + { + SecP224R1Field.Multiply(Z3.x, Z1.x, Z3.x); + } + if (!Z2IsOne) + { + SecP224R1Field.Multiply(Z3.x, Z2.x, Z3.x); + } + + ECFieldElement[] zs = new ECFieldElement[] { Z3 }; + + return new SecP224R1Point(curve, X3, Y3, zs, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + SecP224R1FieldElement Y1 = (SecP224R1FieldElement)this.RawYCoord; + if (Y1.IsZero) + return curve.Infinity; + + SecP224R1FieldElement X1 = (SecP224R1FieldElement)this.RawXCoord, Z1 = (SecP224R1FieldElement)this.RawZCoords[0]; + + uint c; + uint[] t1 = Nat224.Create(); + uint[] t2 = Nat224.Create(); + + uint[] Y1Squared = Nat224.Create(); + SecP224R1Field.Square(Y1.x, Y1Squared); + + uint[] T = Nat224.Create(); + SecP224R1Field.Square(Y1Squared, T); + + bool Z1IsOne = Z1.IsOne; + + uint[] Z1Squared = Z1.x; + if (!Z1IsOne) + { + Z1Squared = t2; + SecP224R1Field.Square(Z1.x, Z1Squared); + } + + SecP224R1Field.Subtract(X1.x, Z1Squared, t1); + + uint[] M = t2; + SecP224R1Field.Add(X1.x, Z1Squared, M); + SecP224R1Field.Multiply(M, t1, M); + c = Nat224.AddBothTo(M, M, M); + SecP224R1Field.Reduce32(c, M); + + uint[] S = Y1Squared; + SecP224R1Field.Multiply(Y1Squared, X1.x, S); + c = Nat.ShiftUpBits(7, S, 2, 0); + SecP224R1Field.Reduce32(c, S); + + c = Nat.ShiftUpBits(7, T, 3, 0, t1); + SecP224R1Field.Reduce32(c, t1); + + SecP224R1FieldElement X3 = new SecP224R1FieldElement(T); + SecP224R1Field.Square(M, X3.x); + SecP224R1Field.Subtract(X3.x, S, X3.x); + SecP224R1Field.Subtract(X3.x, S, X3.x); + + SecP224R1FieldElement Y3 = new SecP224R1FieldElement(S); + SecP224R1Field.Subtract(S, X3.x, Y3.x); + SecP224R1Field.Multiply(Y3.x, M, Y3.x); + SecP224R1Field.Subtract(Y3.x, t1, Y3.x); + + SecP224R1FieldElement Z3 = new SecP224R1FieldElement(M); + SecP224R1Field.Twice(Y1.x, Z3.x); + if (!Z1IsOne) + { + SecP224R1Field.Multiply(Z3.x, Z1.x, Z3.x); + } + + return new SecP224R1Point(curve, X3, Y3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this == b) + return ThreeTimes(); + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECFieldElement Y1 = this.RawYCoord; + if (Y1.IsZero) + return b; + + return Twice().Add(b); + } + + public override ECPoint ThreeTimes() + { + if (this.IsInfinity || this.RawYCoord.IsZero) + return this; + + // NOTE: Be careful about recursions between TwicePlus and ThreeTimes + return Twice().Add(this); + } + + public override ECPoint Negate() + { + if (IsInfinity) + return this; + + return new SecP224R1Point(Curve, RawXCoord, RawYCoord.Negate(), RawZCoords, IsCompressed); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP224R1Point.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP224R1Point.cs.meta new file mode 100644 index 0000000..97a59ce --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP224R1Point.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e3a042cda60744f4eb95f1379abebe08 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP256K1Curve.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP256K1Curve.cs new file mode 100644 index 0000000..123305c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP256K1Curve.cs @@ -0,0 +1,168 @@ +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP256K1Curve + : AbstractFpCurve + { + public static readonly BigInteger q = SecP256K1FieldElement.Q; + + private const int SECP256K1_DEFAULT_COORDS = COORD_JACOBIAN; + private const int SECP256K1_FE_INTS = 8; + private static readonly ECFieldElement[] SECP256K1_AFFINE_ZS = new ECFieldElement[] { new SecP256K1FieldElement(BigInteger.One) }; + + protected readonly SecP256K1Point m_infinity; + + public SecP256K1Curve() + : base(q) + { + this.m_infinity = new SecP256K1Point(this, null, null); + + this.m_a = FromBigInteger(BigInteger.Zero); + this.m_b = FromBigInteger(BigInteger.ValueOf(7)); + this.m_order = new BigInteger(1, Hex.DecodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141")); + this.m_cofactor = BigInteger.One; + this.m_coord = SECP256K1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecP256K1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_JACOBIAN: + return true; + default: + return false; + } + } + + public virtual BigInteger Q + { + get { return q; } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return q.BitLength; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecP256K1FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecP256K1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecP256K1Point(this, x, y, zs, withCompression); + } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + uint[] table = new uint[len * SECP256K1_FE_INTS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat256.Copy(((SecP256K1FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECP256K1_FE_INTS; + Nat256.Copy(((SecP256K1FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECP256K1_FE_INTS; + } + } + + return new SecP256K1LookupTable(this, table, len); + } + + public override ECFieldElement RandomFieldElement(SecureRandom r) + { + uint[] x = Nat256.Create(); + SecP256K1Field.Random(r, x); + return new SecP256K1FieldElement(x); + } + + public override ECFieldElement RandomFieldElementMult(SecureRandom r) + { + uint[] x = Nat256.Create(); + SecP256K1Field.RandomMult(r, x); + return new SecP256K1FieldElement(x); + } + + private class SecP256K1LookupTable + : AbstractECLookupTable + { + private readonly SecP256K1Curve m_outer; + private readonly uint[] m_table; + private readonly int m_size; + + internal SecP256K1LookupTable(SecP256K1Curve outer, uint[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public override int Size + { + get { return m_size; } + } + + public override ECPoint Lookup(int index) + { + uint[] x = Nat256.Create(), y = Nat256.Create(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + uint MASK = (uint)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECP256K1_FE_INTS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECP256K1_FE_INTS + j] & MASK; + } + + pos += (SECP256K1_FE_INTS * 2); + } + + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + uint[] x = Nat256.Create(), y = Nat256.Create(); + int pos = index * SECP256K1_FE_INTS * 2; + + for (int j = 0; j < SECP256K1_FE_INTS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECP256K1_FE_INTS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(uint[] x, uint[] y) + { + return m_outer.CreateRawPoint(new SecP256K1FieldElement(x), new SecP256K1FieldElement(y), SECP256K1_AFFINE_ZS, false); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP256K1Curve.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP256K1Curve.cs.meta new file mode 100644 index 0000000..34bd45d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP256K1Curve.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d56e0ae744e7dab47843802668b9768a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP256K1Field.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP256K1Field.cs new file mode 100644 index 0000000..9a8915c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP256K1Field.cs @@ -0,0 +1,218 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP256K1Field + { + // 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1 + internal static readonly uint[] P = new uint[]{ 0xFFFFFC2F, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; + private static readonly uint[] PExt = new uint[]{ 0x000E90A1, 0x000007A2, 0x00000001, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0xFFFFF85E, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF }; + private static readonly uint[] PExtInv = new uint[]{ 0xFFF16F5F, 0xFFFFF85D, 0xFFFFFFFE, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000007A1, 0x00000002 }; + private const uint P7 = 0xFFFFFFFF; + private const uint PExt15 = 0xFFFFFFFF; + private const uint PInv33 = 0x3D1; + + public static void Add(uint[] x, uint[] y, uint[] z) + { + uint c = Nat256.Add(x, y, z); + if (c != 0 || (z[7] == P7 && Nat256.Gte(z, P))) + { + Nat.Add33To(8, PInv33, z); + } + } + + public static void AddExt(uint[] xx, uint[] yy, uint[] zz) + { + uint c = Nat.Add(16, xx, yy, zz); + if (c != 0 || (zz[15] == PExt15 && Nat.Gte(16, zz, PExt))) + { + if (Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0) + { + Nat.IncAt(16, zz, PExtInv.Length); + } + } + } + + public static void AddOne(uint[] x, uint[] z) + { + uint c = Nat.Inc(8, x, z); + if (c != 0 || (z[7] == P7 && Nat256.Gte(z, P))) + { + Nat.Add33To(8, PInv33, z); + } + } + + public static uint[] FromBigInteger(BigInteger x) + { + uint[] z = Nat.FromBigInteger(256, x); + if (z[7] == P7 && Nat256.Gte(z, P)) + { + Nat256.SubFrom(P, z); + } + return z; + } + + public static void Half(uint[] x, uint[] z) + { + if ((x[0] & 1) == 0) + { + Nat.ShiftDownBit(8, x, 0, z); + } + else + { + uint c = Nat256.Add(x, P, z); + Nat.ShiftDownBit(8, z, c); + } + } + + public static void Inv(uint[] x, uint[] z) + { + Mod.CheckedModOddInverse(P, x, z); + } + + public static int IsZero(uint[] x) + { + uint d = 0; + for (int i = 0; i < 8; ++i) + { + d |= x[i]; + } + d = (d >> 1) | (d & 1); + return ((int)d - 1) >> 31; + } + + public static void Multiply(uint[] x, uint[] y, uint[] z) + { + uint[] tt = Nat256.CreateExt(); + Nat256.Mul(x, y, tt); + Reduce(tt, z); + } + + public static void MultiplyAddToExt(uint[] x, uint[] y, uint[] zz) + { + uint c = Nat256.MulAddTo(x, y, zz); + if (c != 0 || (zz[15] == PExt15 && Nat.Gte(16, zz, PExt))) + { + if (Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0) + { + Nat.IncAt(16, zz, PExtInv.Length); + } + } + } + + public static void Negate(uint[] x, uint[] z) + { + if (0 != IsZero(x)) + { + Nat256.Sub(P, P, z); + } + else + { + Nat256.Sub(P, x, z); + } + } + + public static void Random(SecureRandom r, uint[] z) + { + byte[] bb = new byte[8 * 4]; + do + { + r.NextBytes(bb); + Pack.LE_To_UInt32(bb, 0, z, 0, 8); + } + while (0 == Nat.LessThan(8, z, P)); + } + + public static void RandomMult(SecureRandom r, uint[] z) + { + do + { + Random(r, z); + } + while (0 != IsZero(z)); + } + + public static void Reduce(uint[] xx, uint[] z) + { + ulong cc = Nat256.Mul33Add(PInv33, xx, 8, xx, 0, z, 0); + uint c = Nat256.Mul33DWordAdd(PInv33, cc, z, 0); + + Debug.Assert(c == 0 || c == 1); + + if (c != 0 || (z[7] == P7 && Nat256.Gte(z, P))) + { + Nat.Add33To(8, PInv33, z); + } + } + + public static void Reduce32(uint x, uint[] z) + { + if ((x != 0 && Nat256.Mul33WordAdd(PInv33, x, z, 0) != 0) + || (z[7] == P7 && Nat256.Gte(z, P))) + { + Nat.Add33To(8, PInv33, z); + } + } + + public static void Square(uint[] x, uint[] z) + { + uint[] tt = Nat256.CreateExt(); + Nat256.Square(x, tt); + Reduce(tt, z); + } + + public static void SquareN(uint[] x, int n, uint[] z) + { + Debug.Assert(n > 0); + + uint[] tt = Nat256.CreateExt(); + Nat256.Square(x, tt); + Reduce(tt, z); + + while (--n > 0) + { + Nat256.Square(z, tt); + Reduce(tt, z); + } + } + + public static void Subtract(uint[] x, uint[] y, uint[] z) + { + int c = Nat256.Sub(x, y, z); + if (c != 0) + { + Nat.Sub33From(8, PInv33, z); + } + } + + public static void SubtractExt(uint[] xx, uint[] yy, uint[] zz) + { + int c = Nat.Sub(16, xx, yy, zz); + if (c != 0) + { + if (Nat.SubFrom(PExtInv.Length, PExtInv, zz) != 0) + { + Nat.DecAt(16, zz, PExtInv.Length); + } + } + } + + public static void Twice(uint[] x, uint[] z) + { + uint c = Nat.ShiftUpBit(8, x, 0, z); + if (c != 0 || (z[7] == P7 && Nat256.Gte(z, P))) + { + Nat.Add33To(8, PInv33, z); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP256K1Field.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP256K1Field.cs.meta new file mode 100644 index 0000000..30d69bb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP256K1Field.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bb16b73dafe68644388721e3bd2aff15 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP256K1FieldElement.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP256K1FieldElement.cs new file mode 100644 index 0000000..d2ff05c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP256K1FieldElement.cs @@ -0,0 +1,215 @@ +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP256K1FieldElement + : AbstractFpFieldElement + { + public static readonly BigInteger Q = new BigInteger(1, + Hex.DecodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F")); + + protected internal readonly uint[] x; + + public SecP256K1FieldElement(BigInteger x) + { + if (x == null || x.SignValue < 0 || x.CompareTo(Q) >= 0) + throw new ArgumentException("value invalid for SecP256K1FieldElement", "x"); + + this.x = SecP256K1Field.FromBigInteger(x); + } + + public SecP256K1FieldElement() + { + this.x = Nat256.Create(); + } + + protected internal SecP256K1FieldElement(uint[] x) + { + this.x = x; + } + + public override bool IsZero + { + get { return Nat256.IsZero(x); } + } + + public override bool IsOne + { + get { return Nat256.IsOne(x); } + } + + public override bool TestBitZero() + { + return Nat256.GetBit(x, 0) == 1; + } + + public override BigInteger ToBigInteger() + { + return Nat256.ToBigInteger(x); + } + + public override string FieldName + { + get { return "SecP256K1Field"; } + } + + public override int FieldSize + { + get { return Q.BitLength; } + } + + public override ECFieldElement Add(ECFieldElement b) + { + uint[] z = Nat256.Create(); + SecP256K1Field.Add(x, ((SecP256K1FieldElement)b).x, z); + return new SecP256K1FieldElement(z); + } + + public override ECFieldElement AddOne() + { + uint[] z = Nat256.Create(); + SecP256K1Field.AddOne(x, z); + return new SecP256K1FieldElement(z); + } + + public override ECFieldElement Subtract(ECFieldElement b) + { + uint[] z = Nat256.Create(); + SecP256K1Field.Subtract(x, ((SecP256K1FieldElement)b).x, z); + return new SecP256K1FieldElement(z); + } + + public override ECFieldElement Multiply(ECFieldElement b) + { + uint[] z = Nat256.Create(); + SecP256K1Field.Multiply(x, ((SecP256K1FieldElement)b).x, z); + return new SecP256K1FieldElement(z); + } + + public override ECFieldElement Divide(ECFieldElement b) + { + //return Multiply(b.Invert()); + uint[] z = Nat256.Create(); + SecP256K1Field.Inv(((SecP256K1FieldElement)b).x, z); + SecP256K1Field.Multiply(z, x, z); + return new SecP256K1FieldElement(z); + } + + public override ECFieldElement Negate() + { + uint[] z = Nat256.Create(); + SecP256K1Field.Negate(x, z); + return new SecP256K1FieldElement(z); + } + + public override ECFieldElement Square() + { + uint[] z = Nat256.Create(); + SecP256K1Field.Square(x, z); + return new SecP256K1FieldElement(z); + } + + public override ECFieldElement Invert() + { + //return new SecP256K1FieldElement(ToBigInteger().ModInverse(Q)); + uint[] z = Nat256.Create(); + SecP256K1Field.Inv(x, z); + return new SecP256K1FieldElement(z); + } + + /** + * return a sqrt root - the routine verifies that the calculation returns the right value - if + * none exists it returns null. + */ + public override ECFieldElement Sqrt() + { + /* + * Raise this element to the exponent 2^254 - 2^30 - 2^7 - 2^6 - 2^5 - 2^4 - 2^2 + * + * Breaking up the exponent's binary representation into "repunits", we get: + * { 223 1s } { 1 0s } { 22 1s } { 4 0s } { 2 1s } { 2 0s} + * + * Therefore we need an addition chain containing 2, 22, 223 (the lengths of the repunits) + * We use: 1, [2], 3, 6, 9, 11, [22], 44, 88, 176, 220, [223] + */ + + uint[] x1 = this.x; + if (Nat256.IsZero(x1) || Nat256.IsOne(x1)) + return this; + + uint[] x2 = Nat256.Create(); + SecP256K1Field.Square(x1, x2); + SecP256K1Field.Multiply(x2, x1, x2); + uint[] x3 = Nat256.Create(); + SecP256K1Field.Square(x2, x3); + SecP256K1Field.Multiply(x3, x1, x3); + uint[] x6 = Nat256.Create(); + SecP256K1Field.SquareN(x3, 3, x6); + SecP256K1Field.Multiply(x6, x3, x6); + uint[] x9 = x6; + SecP256K1Field.SquareN(x6, 3, x9); + SecP256K1Field.Multiply(x9, x3, x9); + uint[] x11 = x9; + SecP256K1Field.SquareN(x9, 2, x11); + SecP256K1Field.Multiply(x11, x2, x11); + uint[] x22 = Nat256.Create(); + SecP256K1Field.SquareN(x11, 11, x22); + SecP256K1Field.Multiply(x22, x11, x22); + uint[] x44 = x11; + SecP256K1Field.SquareN(x22, 22, x44); + SecP256K1Field.Multiply(x44, x22, x44); + uint[] x88 = Nat256.Create(); + SecP256K1Field.SquareN(x44, 44, x88); + SecP256K1Field.Multiply(x88, x44, x88); + uint[] x176 = Nat256.Create(); + SecP256K1Field.SquareN(x88, 88, x176); + SecP256K1Field.Multiply(x176, x88, x176); + uint[] x220 = x88; + SecP256K1Field.SquareN(x176, 44, x220); + SecP256K1Field.Multiply(x220, x44, x220); + uint[] x223 = x44; + SecP256K1Field.SquareN(x220, 3, x223); + SecP256K1Field.Multiply(x223, x3, x223); + + uint[] t1 = x223; + SecP256K1Field.SquareN(t1, 23, t1); + SecP256K1Field.Multiply(t1, x22, t1); + SecP256K1Field.SquareN(t1, 6, t1); + SecP256K1Field.Multiply(t1, x2, t1); + SecP256K1Field.SquareN(t1, 2, t1); + + uint[] t2 = x2; + SecP256K1Field.Square(t1, t2); + + return Nat256.Eq(x1, t2) ? new SecP256K1FieldElement(t1) : null; + } + + public override bool Equals(object obj) + { + return Equals(obj as SecP256K1FieldElement); + } + + public override bool Equals(ECFieldElement other) + { + return Equals(other as SecP256K1FieldElement); + } + + public virtual bool Equals(SecP256K1FieldElement other) + { + if (this == other) + return true; + if (null == other) + return false; + return Nat256.Eq(x, other.x); + } + + public override int GetHashCode() + { + return Q.GetHashCode() ^ Arrays.GetHashCode(x, 0, 8); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP256K1FieldElement.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP256K1FieldElement.cs.meta new file mode 100644 index 0000000..fa0a550 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP256K1FieldElement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ffd46f56bd48bfb499c7cbd2267c9103 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP256K1Point.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP256K1Point.cs new file mode 100644 index 0000000..072a0b9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP256K1Point.cs @@ -0,0 +1,267 @@ +using System; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP256K1Point + : AbstractFpPoint + { + /** + * Create a point which encodes with point compression. + * + * @param curve + * the curve to use + * @param x + * affine x co-ordinate + * @param y + * affine y co-ordinate + * + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecP256K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * Create a point that encodes with or without point compresion. + * + * @param curve + * the curve to use + * @param x + * affine x co-ordinate + * @param y + * affine y co-ordinate + * @param withCompression + * if true encode with point compression + * + * @deprecated per-point compression property will be removed, refer + * {@link #getEncoded(bool)} + */ + public SecP256K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecP256K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, + bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecP256K1Point(null, AffineXCoord, AffineYCoord); + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + if (this == b) + return Twice(); + + ECCurve curve = this.Curve; + + SecP256K1FieldElement X1 = (SecP256K1FieldElement)this.RawXCoord, Y1 = (SecP256K1FieldElement)this.RawYCoord; + SecP256K1FieldElement X2 = (SecP256K1FieldElement)b.RawXCoord, Y2 = (SecP256K1FieldElement)b.RawYCoord; + + SecP256K1FieldElement Z1 = (SecP256K1FieldElement)this.RawZCoords[0]; + SecP256K1FieldElement Z2 = (SecP256K1FieldElement)b.RawZCoords[0]; + + uint c; + uint[] tt1 = Nat256.CreateExt(); + uint[] t2 = Nat256.Create(); + uint[] t3 = Nat256.Create(); + uint[] t4 = Nat256.Create(); + + bool Z1IsOne = Z1.IsOne; + uint[] U2, S2; + if (Z1IsOne) + { + U2 = X2.x; + S2 = Y2.x; + } + else + { + S2 = t3; + SecP256K1Field.Square(Z1.x, S2); + + U2 = t2; + SecP256K1Field.Multiply(S2, X2.x, U2); + + SecP256K1Field.Multiply(S2, Z1.x, S2); + SecP256K1Field.Multiply(S2, Y2.x, S2); + } + + bool Z2IsOne = Z2.IsOne; + uint[] U1, S1; + if (Z2IsOne) + { + U1 = X1.x; + S1 = Y1.x; + } + else + { + S1 = t4; + SecP256K1Field.Square(Z2.x, S1); + + U1 = tt1; + SecP256K1Field.Multiply(S1, X1.x, U1); + + SecP256K1Field.Multiply(S1, Z2.x, S1); + SecP256K1Field.Multiply(S1, Y1.x, S1); + } + + uint[] H = Nat256.Create(); + SecP256K1Field.Subtract(U1, U2, H); + + uint[] R = t2; + SecP256K1Field.Subtract(S1, S2, R); + + // Check if b == this or b == -this + if (Nat256.IsZero(H)) + { + if (Nat256.IsZero(R)) + { + // this == b, i.e. this must be doubled + return this.Twice(); + } + + // this == -b, i.e. the result is the point at infinity + return curve.Infinity; + } + + uint[] HSquared = t3; + SecP256K1Field.Square(H, HSquared); + + uint[] G = Nat256.Create(); + SecP256K1Field.Multiply(HSquared, H, G); + + uint[] V = t3; + SecP256K1Field.Multiply(HSquared, U1, V); + + SecP256K1Field.Negate(G, G); + Nat256.Mul(S1, G, tt1); + + c = Nat256.AddBothTo(V, V, G); + SecP256K1Field.Reduce32(c, G); + + SecP256K1FieldElement X3 = new SecP256K1FieldElement(t4); + SecP256K1Field.Square(R, X3.x); + SecP256K1Field.Subtract(X3.x, G, X3.x); + + SecP256K1FieldElement Y3 = new SecP256K1FieldElement(G); + SecP256K1Field.Subtract(V, X3.x, Y3.x); + SecP256K1Field.MultiplyAddToExt(Y3.x, R, tt1); + SecP256K1Field.Reduce(tt1, Y3.x); + + SecP256K1FieldElement Z3 = new SecP256K1FieldElement(H); + if (!Z1IsOne) + { + SecP256K1Field.Multiply(Z3.x, Z1.x, Z3.x); + } + if (!Z2IsOne) + { + SecP256K1Field.Multiply(Z3.x, Z2.x, Z3.x); + } + + ECFieldElement[] zs = new ECFieldElement[] { Z3 }; + + return new SecP256K1Point(curve, X3, Y3, zs, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + SecP256K1FieldElement Y1 = (SecP256K1FieldElement)this.RawYCoord; + if (Y1.IsZero) + return curve.Infinity; + + SecP256K1FieldElement X1 = (SecP256K1FieldElement)this.RawXCoord, Z1 = (SecP256K1FieldElement)this.RawZCoords[0]; + + uint c; + + uint[] Y1Squared = Nat256.Create(); + SecP256K1Field.Square(Y1.x, Y1Squared); + + uint[] T = Nat256.Create(); + SecP256K1Field.Square(Y1Squared, T); + + uint[] M = Nat256.Create(); + SecP256K1Field.Square(X1.x, M); + c = Nat256.AddBothTo(M, M, M); + SecP256K1Field.Reduce32(c, M); + + uint[] S = Y1Squared; + SecP256K1Field.Multiply(Y1Squared, X1.x, S); + c = Nat.ShiftUpBits(8, S, 2, 0); + SecP256K1Field.Reduce32(c, S); + + uint[] t1 = Nat256.Create(); + c = Nat.ShiftUpBits(8, T, 3, 0, t1); + SecP256K1Field.Reduce32(c, t1); + + SecP256K1FieldElement X3 = new SecP256K1FieldElement(T); + SecP256K1Field.Square(M, X3.x); + SecP256K1Field.Subtract(X3.x, S, X3.x); + SecP256K1Field.Subtract(X3.x, S, X3.x); + + SecP256K1FieldElement Y3 = new SecP256K1FieldElement(S); + SecP256K1Field.Subtract(S, X3.x, Y3.x); + SecP256K1Field.Multiply(Y3.x, M, Y3.x); + SecP256K1Field.Subtract(Y3.x, t1, Y3.x); + + SecP256K1FieldElement Z3 = new SecP256K1FieldElement(M); + SecP256K1Field.Twice(Y1.x, Z3.x); + if (!Z1.IsOne) + { + SecP256K1Field.Multiply(Z3.x, Z1.x, Z3.x); + } + + return new SecP256K1Point(curve, X3, Y3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this == b) + return ThreeTimes(); + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECFieldElement Y1 = this.RawYCoord; + if (Y1.IsZero) + return b; + + return Twice().Add(b); + } + + public override ECPoint ThreeTimes() + { + if (this.IsInfinity || this.RawYCoord.IsZero) + return this; + + // NOTE: Be careful about recursions between TwicePlus and ThreeTimes + return Twice().Add(this); + } + + public override ECPoint Negate() + { + if (IsInfinity) + return this; + + return new SecP256K1Point(Curve, RawXCoord, RawYCoord.Negate(), RawZCoords, IsCompressed); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP256K1Point.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP256K1Point.cs.meta new file mode 100644 index 0000000..0d1619a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP256K1Point.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 70ae9e49f524b244c90b524b2cd6a93e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP256R1Curve.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP256R1Curve.cs new file mode 100644 index 0000000..b90f5d0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP256R1Curve.cs @@ -0,0 +1,170 @@ +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP256R1Curve + : AbstractFpCurve + { + public static readonly BigInteger q = SecP256R1FieldElement.Q; + + private const int SECP256R1_DEFAULT_COORDS = COORD_JACOBIAN; + private const int SECP256R1_FE_INTS = 8; + private static readonly ECFieldElement[] SECP256R1_AFFINE_ZS = new ECFieldElement[] { new SecP256R1FieldElement(BigInteger.One) }; + + protected readonly SecP256R1Point m_infinity; + + public SecP256R1Curve() + : base(q) + { + this.m_infinity = new SecP256R1Point(this, null, null); + + this.m_a = FromBigInteger(new BigInteger(1, + Hex.DecodeStrict("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC"))); + this.m_b = FromBigInteger(new BigInteger(1, + Hex.DecodeStrict("5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B"))); + this.m_order = new BigInteger(1, Hex.DecodeStrict("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551")); + this.m_cofactor = BigInteger.One; + this.m_coord = SECP256R1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecP256R1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_JACOBIAN: + return true; + default: + return false; + } + } + + public virtual BigInteger Q + { + get { return q; } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return q.BitLength; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecP256R1FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecP256R1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecP256R1Point(this, x, y, zs, withCompression); + } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + uint[] table = new uint[len * SECP256R1_FE_INTS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat256.Copy(((SecP256R1FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECP256R1_FE_INTS; + Nat256.Copy(((SecP256R1FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECP256R1_FE_INTS; + } + } + + return new SecP256R1LookupTable(this, table, len); + } + + public override ECFieldElement RandomFieldElement(SecureRandom r) + { + uint[] x = Nat256.Create(); + SecP256R1Field.Random(r, x); + return new SecP256R1FieldElement(x); + } + + public override ECFieldElement RandomFieldElementMult(SecureRandom r) + { + uint[] x = Nat256.Create(); + SecP256R1Field.RandomMult(r, x); + return new SecP256R1FieldElement(x); + } + + private class SecP256R1LookupTable + : AbstractECLookupTable + { + private readonly SecP256R1Curve m_outer; + private readonly uint[] m_table; + private readonly int m_size; + + internal SecP256R1LookupTable(SecP256R1Curve outer, uint[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public override int Size + { + get { return m_size; } + } + + public override ECPoint Lookup(int index) + { + uint[] x = Nat256.Create(), y = Nat256.Create(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + uint MASK = (uint)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECP256R1_FE_INTS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECP256R1_FE_INTS + j] & MASK; + } + + pos += (SECP256R1_FE_INTS * 2); + } + + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + uint[] x = Nat256.Create(), y = Nat256.Create(); + int pos = index * SECP256R1_FE_INTS * 2; + + for (int j = 0; j < SECP256R1_FE_INTS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECP256R1_FE_INTS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(uint[] x, uint[] y) + { + return m_outer.CreateRawPoint(new SecP256R1FieldElement(x), new SecP256R1FieldElement(y), SECP256R1_AFFINE_ZS, false); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP256R1Curve.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP256R1Curve.cs.meta new file mode 100644 index 0000000..4a52484 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP256R1Curve.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3b3c24404bb7cac4f931d5973ad7f115 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP256R1Field.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP256R1Field.cs new file mode 100644 index 0000000..a1079f3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP256R1Field.cs @@ -0,0 +1,350 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP256R1Field + { + // 2^256 - 2^224 + 2^192 + 2^96 - 1 + internal static readonly uint[] P = new uint[]{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0x00000000, 0x00000001, 0xFFFFFFFF }; + private static readonly uint[] PExt = new uint[]{ 0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFE, 0x00000001, 0xFFFFFFFE, 0x00000001, 0xFFFFFFFE, 0x00000001, 0x00000001, 0xFFFFFFFE, + 0x00000002, 0xFFFFFFFE }; + private const uint P7 = 0xFFFFFFFF; + private const uint PExt15 = 0xFFFFFFFE; + + public static void Add(uint[] x, uint[] y, uint[] z) + { + uint c = Nat256.Add(x, y, z); + if (c != 0 || (z[7] == P7 && Nat256.Gte(z, P))) + { + AddPInvTo(z); + } + } + + public static void AddExt(uint[] xx, uint[] yy, uint[] zz) + { + uint c = Nat.Add(16, xx, yy, zz); + if (c != 0 || (zz[15] >= PExt15 && Nat.Gte(16, zz, PExt))) + { + Nat.SubFrom(16, PExt, zz); + } + } + + public static void AddOne(uint[] x, uint[] z) + { + uint c = Nat.Inc(8, x, z); + if (c != 0 || (z[7] == P7 && Nat256.Gte(z, P))) + { + AddPInvTo(z); + } + } + + public static uint[] FromBigInteger(BigInteger x) + { + uint[] z = Nat.FromBigInteger(256, x); + if (z[7] == P7 && Nat256.Gte(z, P)) + { + Nat256.SubFrom(P, z); + } + return z; + } + + public static void Half(uint[] x, uint[] z) + { + if ((x[0] & 1) == 0) + { + Nat.ShiftDownBit(8, x, 0, z); + } + else + { + uint c = Nat256.Add(x, P, z); + Nat.ShiftDownBit(8, z, c); + } + } + + public static void Inv(uint[] x, uint[] z) + { + Mod.CheckedModOddInverse(P, x, z); + } + + public static int IsZero(uint[] x) + { + uint d = 0; + for (int i = 0; i < 8; ++i) + { + d |= x[i]; + } + d = (d >> 1) | (d & 1); + return ((int)d - 1) >> 31; + } + + public static void Multiply(uint[] x, uint[] y, uint[] z) + { + uint[] tt = Nat256.CreateExt(); + Nat256.Mul(x, y, tt); + Reduce(tt, z); + } + + public static void MultiplyAddToExt(uint[] x, uint[] y, uint[] zz) + { + uint c = Nat256.MulAddTo(x, y, zz); + if (c != 0 || (zz[15] >= PExt15 && Nat.Gte(16, zz, PExt))) + { + Nat.SubFrom(16, PExt, zz); + } + } + + public static void Negate(uint[] x, uint[] z) + { + if (0 != IsZero(x)) + { + Nat256.Sub(P, P, z); + } + else + { + Nat256.Sub(P, x, z); + } + } + + public static void Random(SecureRandom r, uint[] z) + { + byte[] bb = new byte[8 * 4]; + do + { + r.NextBytes(bb); + Pack.LE_To_UInt32(bb, 0, z, 0, 8); + } + while (0 == Nat.LessThan(8, z, P)); + } + + public static void RandomMult(SecureRandom r, uint[] z) + { + do + { + Random(r, z); + } + while (0 != IsZero(z)); + } + + public static void Reduce(uint[] xx, uint[] z) + { + long xx08 = xx[8], xx09 = xx[9], xx10 = xx[10], xx11 = xx[11]; + long xx12 = xx[12], xx13 = xx[13], xx14 = xx[14], xx15 = xx[15]; + + const long n = 6; + + xx08 -= n; + + long t0 = xx08 + xx09; + long t1 = xx09 + xx10; + long t2 = xx10 + xx11 - xx15; + long t3 = xx11 + xx12; + long t4 = xx12 + xx13; + long t5 = xx13 + xx14; + long t6 = xx14 + xx15; + long t7 = t5 - t0; + + long cc = 0; + cc += (long)xx[0] - t3 - t7; + z[0] = (uint)cc; + cc >>= 32; + cc += (long)xx[1] + t1 - t4 - t6; + z[1] = (uint)cc; + cc >>= 32; + cc += (long)xx[2] + t2 - t5; + z[2] = (uint)cc; + cc >>= 32; + cc += (long)xx[3] + (t3 << 1) + t7 - t6; + z[3] = (uint)cc; + cc >>= 32; + cc += (long)xx[4] + (t4 << 1) + xx14 - t1; + z[4] = (uint)cc; + cc >>= 32; + cc += (long)xx[5] + (t5 << 1) - t2; + z[5] = (uint)cc; + cc >>= 32; + cc += (long)xx[6] + (t6 << 1) + t7; + z[6] = (uint)cc; + cc >>= 32; + cc += (long)xx[7] + (xx15 << 1) + xx08 - t2 - t4; + z[7] = (uint)cc; + cc >>= 32; + cc += n; + + Debug.Assert(cc >= 0); + + Reduce32((uint)cc, z); + } + + public static void Reduce32(uint x, uint[] z) + { + long cc = 0; + + if (x != 0) + { + long xx08 = x; + + cc += (long)z[0] + xx08; + z[0] = (uint)cc; + cc >>= 32; + if (cc != 0) + { + cc += (long)z[1]; + z[1] = (uint)cc; + cc >>= 32; + cc += (long)z[2]; + z[2] = (uint)cc; + cc >>= 32; + } + cc += (long)z[3] - xx08; + z[3] = (uint)cc; + cc >>= 32; + if (cc != 0) + { + cc += (long)z[4]; + z[4] = (uint)cc; + cc >>= 32; + cc += (long)z[5]; + z[5] = (uint)cc; + cc >>= 32; + } + cc += (long)z[6] - xx08; + z[6] = (uint)cc; + cc >>= 32; + cc += (long)z[7] + xx08; + z[7] = (uint)cc; + cc >>= 32; + + Debug.Assert(cc == 0 || cc == 1); + } + + if (cc != 0 || (z[7] == P7 && Nat256.Gte(z, P))) + { + AddPInvTo(z); + } + } + + public static void Square(uint[] x, uint[] z) + { + uint[] tt = Nat256.CreateExt(); + Nat256.Square(x, tt); + Reduce(tt, z); + } + + public static void SquareN(uint[] x, int n, uint[] z) + { + Debug.Assert(n > 0); + + uint[] tt = Nat256.CreateExt(); + Nat256.Square(x, tt); + Reduce(tt, z); + + while (--n > 0) + { + Nat256.Square(z, tt); + Reduce(tt, z); + } + } + + public static void Subtract(uint[] x, uint[] y, uint[] z) + { + int c = Nat256.Sub(x, y, z); + if (c != 0) + { + SubPInvFrom(z); + } + } + + public static void SubtractExt(uint[] xx, uint[] yy, uint[] zz) + { + int c = Nat.Sub(16, xx, yy, zz); + if (c != 0) + { + Nat.AddTo(16, PExt, zz); + } + } + + public static void Twice(uint[] x, uint[] z) + { + uint c = Nat.ShiftUpBit(8, x, 0, z); + if (c != 0 || (z[7] == P7 && Nat256.Gte(z, P))) + { + AddPInvTo(z); + } + } + + private static void AddPInvTo(uint[] z) + { + long c = (long)z[0] + 1; + z[0] = (uint)c; + c >>= 32; + if (c != 0) + { + c += (long)z[1]; + z[1] = (uint)c; + c >>= 32; + c += (long)z[2]; + z[2] = (uint)c; + c >>= 32; + } + c += (long)z[3] - 1; + z[3] = (uint)c; + c >>= 32; + if (c != 0) + { + c += (long)z[4]; + z[4] = (uint)c; + c >>= 32; + c += (long)z[5]; + z[5] = (uint)c; + c >>= 32; + } + c += (long)z[6] - 1; + z[6] = (uint)c; + c >>= 32; + c += (long)z[7] + 1; + z[7] = (uint)c; + //c >>= 32; + } + + private static void SubPInvFrom(uint[] z) + { + long c = (long)z[0] - 1; + z[0] = (uint)c; + c >>= 32; + if (c != 0) + { + c += (long)z[1]; + z[1] = (uint)c; + c >>= 32; + c += (long)z[2]; + z[2] = (uint)c; + c >>= 32; + } + c += (long)z[3] + 1; + z[3] = (uint)c; + c >>= 32; + if (c != 0) + { + c += (long)z[4]; + z[4] = (uint)c; + c >>= 32; + c += (long)z[5]; + z[5] = (uint)c; + c >>= 32; + } + c += (long)z[6] + 1; + z[6] = (uint)c; + c >>= 32; + c += (long)z[7] - 1; + z[7] = (uint)c; + //c >>= 32; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP256R1Field.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP256R1Field.cs.meta new file mode 100644 index 0000000..7d94b13 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP256R1Field.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ce34a65e73d48a244ad926f4671f271d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP256R1FieldElement.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP256R1FieldElement.cs new file mode 100644 index 0000000..bee3220 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP256R1FieldElement.cs @@ -0,0 +1,190 @@ +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP256R1FieldElement + : AbstractFpFieldElement + { + public static readonly BigInteger Q = new BigInteger(1, + Hex.DecodeStrict("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF")); + + protected internal readonly uint[] x; + + public SecP256R1FieldElement(BigInteger x) + { + if (x == null || x.SignValue < 0 || x.CompareTo(Q) >= 0) + throw new ArgumentException("value invalid for SecP256R1FieldElement", "x"); + + this.x = SecP256R1Field.FromBigInteger(x); + } + + public SecP256R1FieldElement() + { + this.x = Nat256.Create(); + } + + protected internal SecP256R1FieldElement(uint[] x) + { + this.x = x; + } + + public override bool IsZero + { + get { return Nat256.IsZero(x); } + } + + public override bool IsOne + { + get { return Nat256.IsOne(x); } + } + + public override bool TestBitZero() + { + return Nat256.GetBit(x, 0) == 1; + } + + public override BigInteger ToBigInteger() + { + return Nat256.ToBigInteger(x); + } + + public override string FieldName + { + get { return "SecP256R1Field"; } + } + + public override int FieldSize + { + get { return Q.BitLength; } + } + + public override ECFieldElement Add(ECFieldElement b) + { + uint[] z = Nat256.Create(); + SecP256R1Field.Add(x, ((SecP256R1FieldElement)b).x, z); + return new SecP256R1FieldElement(z); + } + + public override ECFieldElement AddOne() + { + uint[] z = Nat256.Create(); + SecP256R1Field.AddOne(x, z); + return new SecP256R1FieldElement(z); + } + + public override ECFieldElement Subtract(ECFieldElement b) + { + uint[] z = Nat256.Create(); + SecP256R1Field.Subtract(x, ((SecP256R1FieldElement)b).x, z); + return new SecP256R1FieldElement(z); + } + + public override ECFieldElement Multiply(ECFieldElement b) + { + uint[] z = Nat256.Create(); + SecP256R1Field.Multiply(x, ((SecP256R1FieldElement)b).x, z); + return new SecP256R1FieldElement(z); + } + + public override ECFieldElement Divide(ECFieldElement b) + { + //return Multiply(b.Invert()); + uint[] z = Nat256.Create(); + SecP256R1Field.Inv(((SecP256R1FieldElement)b).x, z); + SecP256R1Field.Multiply(z, x, z); + return new SecP256R1FieldElement(z); + } + + public override ECFieldElement Negate() + { + uint[] z = Nat256.Create(); + SecP256R1Field.Negate(x, z); + return new SecP256R1FieldElement(z); + } + + public override ECFieldElement Square() + { + uint[] z = Nat256.Create(); + SecP256R1Field.Square(x, z); + return new SecP256R1FieldElement(z); + } + + public override ECFieldElement Invert() + { + //return new SecP256R1FieldElement(ToBigInteger().ModInverse(Q)); + uint[] z = Nat256.Create(); + SecP256R1Field.Inv(x, z); + return new SecP256R1FieldElement(z); + } + + /** + * return a sqrt root - the routine verifies that the calculation returns the right value - if + * none exists it returns null. + */ + public override ECFieldElement Sqrt() + { + // Raise this element to the exponent 2^254 - 2^222 + 2^190 + 2^94 + + uint[] x1 = this.x; + if (Nat256.IsZero(x1) || Nat256.IsOne(x1)) + return this; + + uint[] t1 = Nat256.Create(); + uint[] t2 = Nat256.Create(); + + SecP256R1Field.Square(x1, t1); + SecP256R1Field.Multiply(t1, x1, t1); + + SecP256R1Field.SquareN(t1, 2, t2); + SecP256R1Field.Multiply(t2, t1, t2); + + SecP256R1Field.SquareN(t2, 4, t1); + SecP256R1Field.Multiply(t1, t2, t1); + + SecP256R1Field.SquareN(t1, 8, t2); + SecP256R1Field.Multiply(t2, t1, t2); + + SecP256R1Field.SquareN(t2, 16, t1); + SecP256R1Field.Multiply(t1, t2, t1); + + SecP256R1Field.SquareN(t1, 32, t1); + SecP256R1Field.Multiply(t1, x1, t1); + + SecP256R1Field.SquareN(t1, 96, t1); + SecP256R1Field.Multiply(t1, x1, t1); + + SecP256R1Field.SquareN(t1, 94, t1); + SecP256R1Field.Multiply(t1, t1, t2); + + return Nat256.Eq(x1, t2) ? new SecP256R1FieldElement(t1) : null; + } + + public override bool Equals(object obj) + { + return Equals(obj as SecP256R1FieldElement); + } + + public override bool Equals(ECFieldElement other) + { + return Equals(other as SecP256R1FieldElement); + } + + public virtual bool Equals(SecP256R1FieldElement other) + { + if (this == other) + return true; + if (null == other) + return false; + return Nat256.Eq(x, other.x); + } + + public override int GetHashCode() + { + return Q.GetHashCode() ^ Arrays.GetHashCode(x, 0, 8); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP256R1FieldElement.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP256R1FieldElement.cs.meta new file mode 100644 index 0000000..5926dfe --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP256R1FieldElement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 49dad2de1e7888443975d530e633ddb4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP256R1Point.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP256R1Point.cs new file mode 100644 index 0000000..8332082 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP256R1Point.cs @@ -0,0 +1,279 @@ +using System; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP256R1Point + : AbstractFpPoint + { + /** + * Create a point which encodes with point compression. + * + * @param curve + * the curve to use + * @param x + * affine x co-ordinate + * @param y + * affine y co-ordinate + * + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecP256R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * Create a point that encodes with or without point compresion. + * + * @param curve + * the curve to use + * @param x + * affine x co-ordinate + * @param y + * affine y co-ordinate + * @param withCompression + * if true encode with point compression + * + * @deprecated per-point compression property will be removed, refer + * {@link #getEncoded(bool)} + */ + public SecP256R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecP256R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecP256R1Point(null, AffineXCoord, AffineYCoord); + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + if (this == b) + return Twice(); + + ECCurve curve = this.Curve; + + SecP256R1FieldElement X1 = (SecP256R1FieldElement)this.RawXCoord, Y1 = (SecP256R1FieldElement)this.RawYCoord; + SecP256R1FieldElement X2 = (SecP256R1FieldElement)b.RawXCoord, Y2 = (SecP256R1FieldElement)b.RawYCoord; + + SecP256R1FieldElement Z1 = (SecP256R1FieldElement)this.RawZCoords[0]; + SecP256R1FieldElement Z2 = (SecP256R1FieldElement)b.RawZCoords[0]; + + uint c; + uint[] tt1 = Nat256.CreateExt(); + uint[] t2 = Nat256.Create(); + uint[] t3 = Nat256.Create(); + uint[] t4 = Nat256.Create(); + + bool Z1IsOne = Z1.IsOne; + uint[] U2, S2; + if (Z1IsOne) + { + U2 = X2.x; + S2 = Y2.x; + } + else + { + S2 = t3; + SecP256R1Field.Square(Z1.x, S2); + + U2 = t2; + SecP256R1Field.Multiply(S2, X2.x, U2); + + SecP256R1Field.Multiply(S2, Z1.x, S2); + SecP256R1Field.Multiply(S2, Y2.x, S2); + } + + bool Z2IsOne = Z2.IsOne; + uint[] U1, S1; + if (Z2IsOne) + { + U1 = X1.x; + S1 = Y1.x; + } + else + { + S1 = t4; + SecP256R1Field.Square(Z2.x, S1); + + U1 = tt1; + SecP256R1Field.Multiply(S1, X1.x, U1); + + SecP256R1Field.Multiply(S1, Z2.x, S1); + SecP256R1Field.Multiply(S1, Y1.x, S1); + } + + uint[] H = Nat256.Create(); + SecP256R1Field.Subtract(U1, U2, H); + + uint[] R = t2; + SecP256R1Field.Subtract(S1, S2, R); + + // Check if b == this or b == -this + if (Nat256.IsZero(H)) + { + if (Nat256.IsZero(R)) + { + // this == b, i.e. this must be doubled + return this.Twice(); + } + + // this == -b, i.e. the result is the point at infinity + return curve.Infinity; + } + + uint[] HSquared = t3; + SecP256R1Field.Square(H, HSquared); + + uint[] G = Nat256.Create(); + SecP256R1Field.Multiply(HSquared, H, G); + + uint[] V = t3; + SecP256R1Field.Multiply(HSquared, U1, V); + + SecP256R1Field.Negate(G, G); + Nat256.Mul(S1, G, tt1); + + c = Nat256.AddBothTo(V, V, G); + SecP256R1Field.Reduce32(c, G); + + SecP256R1FieldElement X3 = new SecP256R1FieldElement(t4); + SecP256R1Field.Square(R, X3.x); + SecP256R1Field.Subtract(X3.x, G, X3.x); + + SecP256R1FieldElement Y3 = new SecP256R1FieldElement(G); + SecP256R1Field.Subtract(V, X3.x, Y3.x); + SecP256R1Field.MultiplyAddToExt(Y3.x, R, tt1); + SecP256R1Field.Reduce(tt1, Y3.x); + + SecP256R1FieldElement Z3 = new SecP256R1FieldElement(H); + if (!Z1IsOne) + { + SecP256R1Field.Multiply(Z3.x, Z1.x, Z3.x); + } + if (!Z2IsOne) + { + SecP256R1Field.Multiply(Z3.x, Z2.x, Z3.x); + } + + ECFieldElement[] zs = new ECFieldElement[]{ Z3 }; + + return new SecP256R1Point(curve, X3, Y3, zs, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + SecP256R1FieldElement Y1 = (SecP256R1FieldElement)this.RawYCoord; + if (Y1.IsZero) + return curve.Infinity; + + SecP256R1FieldElement X1 = (SecP256R1FieldElement)this.RawXCoord, Z1 = (SecP256R1FieldElement)this.RawZCoords[0]; + + uint c; + uint[] t1 = Nat256.Create(); + uint[] t2 = Nat256.Create(); + + uint[] Y1Squared = Nat256.Create(); + SecP256R1Field.Square(Y1.x, Y1Squared); + + uint[] T = Nat256.Create(); + SecP256R1Field.Square(Y1Squared, T); + + bool Z1IsOne = Z1.IsOne; + + uint[] Z1Squared = Z1.x; + if (!Z1IsOne) + { + Z1Squared = t2; + SecP256R1Field.Square(Z1.x, Z1Squared); + } + + SecP256R1Field.Subtract(X1.x, Z1Squared, t1); + + uint[] M = t2; + SecP256R1Field.Add(X1.x, Z1Squared, M); + SecP256R1Field.Multiply(M, t1, M); + c = Nat256.AddBothTo(M, M, M); + SecP256R1Field.Reduce32(c, M); + + uint[] S = Y1Squared; + SecP256R1Field.Multiply(Y1Squared, X1.x, S); + c = Nat.ShiftUpBits(8, S, 2, 0); + SecP256R1Field.Reduce32(c, S); + + c = Nat.ShiftUpBits(8, T, 3, 0, t1); + SecP256R1Field.Reduce32(c, t1); + + SecP256R1FieldElement X3 = new SecP256R1FieldElement(T); + SecP256R1Field.Square(M, X3.x); + SecP256R1Field.Subtract(X3.x, S, X3.x); + SecP256R1Field.Subtract(X3.x, S, X3.x); + + SecP256R1FieldElement Y3 = new SecP256R1FieldElement(S); + SecP256R1Field.Subtract(S, X3.x, Y3.x); + SecP256R1Field.Multiply(Y3.x, M, Y3.x); + SecP256R1Field.Subtract(Y3.x, t1, Y3.x); + + SecP256R1FieldElement Z3 = new SecP256R1FieldElement(M); + SecP256R1Field.Twice(Y1.x, Z3.x); + if (!Z1IsOne) + { + SecP256R1Field.Multiply(Z3.x, Z1.x, Z3.x); + } + + return new SecP256R1Point(curve, X3, Y3, new ECFieldElement[]{ Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this == b) + return ThreeTimes(); + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECFieldElement Y1 = this.RawYCoord; + if (Y1.IsZero) + return b; + + return Twice().Add(b); + } + + public override ECPoint ThreeTimes() + { + if (this.IsInfinity || this.RawYCoord.IsZero) + return this; + + // NOTE: Be careful about recursions between TwicePlus and ThreeTimes + return Twice().Add(this); + } + + public override ECPoint Negate() + { + if (IsInfinity) + return this; + + return new SecP256R1Point(Curve, RawXCoord, RawYCoord.Negate(), RawZCoords, IsCompressed); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP256R1Point.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP256R1Point.cs.meta new file mode 100644 index 0000000..37c4762 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP256R1Point.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 50e2e2b43e58bf0488168eaff4a09fe7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP384R1Curve.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP384R1Curve.cs new file mode 100644 index 0000000..b57788e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP384R1Curve.cs @@ -0,0 +1,170 @@ +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP384R1Curve + : AbstractFpCurve + { + public static readonly BigInteger q = SecP384R1FieldElement.Q; + + private const int SECP384R1_DEFAULT_COORDS = COORD_JACOBIAN; + private const int SECP384R1_FE_INTS = 12; + private static readonly ECFieldElement[] SECP384R1_AFFINE_ZS = new ECFieldElement[] { new SecP384R1FieldElement(BigInteger.One) }; + + protected readonly SecP384R1Point m_infinity; + + public SecP384R1Curve() + : base(q) + { + this.m_infinity = new SecP384R1Point(this, null, null); + + this.m_a = FromBigInteger(new BigInteger(1, + Hex.DecodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC"))); + this.m_b = FromBigInteger(new BigInteger(1, + Hex.DecodeStrict("B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF"))); + this.m_order = new BigInteger(1, Hex.DecodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973")); + this.m_cofactor = BigInteger.One; + this.m_coord = SECP384R1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecP384R1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_JACOBIAN: + return true; + default: + return false; + } + } + + public virtual BigInteger Q + { + get { return q; } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return q.BitLength; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecP384R1FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecP384R1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecP384R1Point(this, x, y, zs, withCompression); + } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + uint[] table = new uint[len * SECP384R1_FE_INTS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat.Copy(SECP384R1_FE_INTS, ((SecP384R1FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECP384R1_FE_INTS; + Nat.Copy(SECP384R1_FE_INTS, ((SecP384R1FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECP384R1_FE_INTS; + } + } + + return new SecP384R1LookupTable(this, table, len); + } + + public override ECFieldElement RandomFieldElement(SecureRandom r) + { + uint[] x = Nat.Create(12); + SecP384R1Field.Random(r, x); + return new SecP384R1FieldElement(x); + } + + public override ECFieldElement RandomFieldElementMult(SecureRandom r) + { + uint[] x = Nat.Create(12); + SecP384R1Field.RandomMult(r, x); + return new SecP384R1FieldElement(x); + } + + private class SecP384R1LookupTable + : AbstractECLookupTable + { + private readonly SecP384R1Curve m_outer; + private readonly uint[] m_table; + private readonly int m_size; + + internal SecP384R1LookupTable(SecP384R1Curve outer, uint[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public override int Size + { + get { return m_size; } + } + + public override ECPoint Lookup(int index) + { + uint[] x = Nat.Create(SECP384R1_FE_INTS), y = Nat.Create(SECP384R1_FE_INTS); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + uint MASK = (uint)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECP384R1_FE_INTS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECP384R1_FE_INTS + j] & MASK; + } + + pos += (SECP384R1_FE_INTS * 2); + } + + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + uint[] x = Nat.Create(SECP384R1_FE_INTS), y = Nat.Create(SECP384R1_FE_INTS); + int pos = index * SECP384R1_FE_INTS * 2; + + for (int j = 0; j < SECP384R1_FE_INTS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECP384R1_FE_INTS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(uint[] x, uint[] y) + { + return m_outer.CreateRawPoint(new SecP384R1FieldElement(x), new SecP384R1FieldElement(y), SECP384R1_AFFINE_ZS, false); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP384R1Curve.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP384R1Curve.cs.meta new file mode 100644 index 0000000..f762877 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP384R1Curve.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d63d1180efdc0c341b8fc8c97d216aa7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP384R1Field.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP384R1Field.cs new file mode 100644 index 0000000..cddb468 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP384R1Field.cs @@ -0,0 +1,334 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP384R1Field + { + // 2^384 - 2^128 - 2^96 + 2^32 - 1 + internal static readonly uint[] P = new uint[]{ 0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFE, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; + private static readonly uint[] PExt = new uint[]{ 0x00000001, 0xFFFFFFFE, 0x00000000, 0x00000002, 0x00000000, + 0xFFFFFFFE, 0x00000000, 0x00000002, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFE, 0x00000001, + 0x00000000, 0xFFFFFFFE, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF }; + private static readonly uint[] PExtInv = new uint[]{ 0xFFFFFFFF, 0x00000001, 0xFFFFFFFF, 0xFFFFFFFD, + 0xFFFFFFFF, 0x00000001, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000001, + 0xFFFFFFFE, 0xFFFFFFFF, 0x00000001, 0x00000002 }; + private const uint P11 = 0xFFFFFFFF; + private const uint PExt23 = 0xFFFFFFFF; + + public static void Add(uint[] x, uint[] y, uint[] z) + { + uint c = Nat.Add(12, x, y, z); + if (c != 0 || (z[11] == P11 && Nat.Gte(12, z, P))) + { + AddPInvTo(z); + } + } + + public static void AddExt(uint[] xx, uint[] yy, uint[] zz) + { + uint c = Nat.Add(24, xx, yy, zz); + if (c != 0 || (zz[23] == PExt23 && Nat.Gte(24, zz, PExt))) + { + if (Nat.AddTo(PExtInv.Length, PExtInv, zz) != 0) + { + Nat.IncAt(24, zz, PExtInv.Length); + } + } + } + + public static void AddOne(uint[] x, uint[] z) + { + uint c = Nat.Inc(12, x, z); + if (c != 0 || (z[11] == P11 && Nat.Gte(12, z, P))) + { + AddPInvTo(z); + } + } + + public static uint[] FromBigInteger(BigInteger x) + { + uint[] z = Nat.FromBigInteger(384, x); + if (z[11] == P11 && Nat.Gte(12, z, P)) + { + Nat.SubFrom(12, P, z); + } + return z; + } + + public static void Half(uint[] x, uint[] z) + { + if ((x[0] & 1) == 0) + { + Nat.ShiftDownBit(12, x, 0, z); + } + else + { + uint c = Nat.Add(12, x, P, z); + Nat.ShiftDownBit(12, z, c); + } + } + + public static void Inv(uint[] x, uint[] z) + { + Mod.CheckedModOddInverse(P, x, z); + } + + public static int IsZero(uint[] x) + { + uint d = 0; + for (int i = 0; i < 12; ++i) + { + d |= x[i]; + } + d = (d >> 1) | (d & 1); + return ((int)d - 1) >> 31; + } + + public static void Multiply(uint[] x, uint[] y, uint[] z) + { + uint[] tt = Nat.Create(24); + Nat384.Mul(x, y, tt); + Reduce(tt, z); + } + + public static void Negate(uint[] x, uint[] z) + { + if (0 != IsZero(x)) + { + Nat.Sub(12, P, P, z); + } + else + { + Nat.Sub(12, P, x, z); + } + } + + public static void Random(SecureRandom r, uint[] z) + { + byte[] bb = new byte[12 * 4]; + do + { + r.NextBytes(bb); + Pack.LE_To_UInt32(bb, 0, z, 0, 12); + } + while (0 == Nat.LessThan(12, z, P)); + } + + public static void RandomMult(SecureRandom r, uint[] z) + { + do + { + Random(r, z); + } + while (0 != IsZero(z)); + } + + public static void Reduce(uint[] xx, uint[] z) + { + long xx16 = xx[16], xx17 = xx[17], xx18 = xx[18], xx19 = xx[19]; + long xx20 = xx[20], xx21 = xx[21], xx22 = xx[22], xx23 = xx[23]; + + const long n = 1; + + long t0 = (long)xx[12] + xx20 - n; + long t1 = (long)xx[13] + xx22; + long t2 = (long)xx[14] + xx22 + xx23; + long t3 = (long)xx[15] + xx23; + long t4 = xx17 + xx21; + long t5 = xx21 - xx23; + long t6 = xx22 - xx23; + long t7 = t0 + t5; + + long cc = 0; + cc += (long)xx[0] + t7; + z[0] = (uint)cc; + cc >>= 32; + cc += (long)xx[1] + xx23 - t0 + t1; + z[1] = (uint)cc; + cc >>= 32; + cc += (long)xx[2] - xx21 - t1 + t2; + z[2] = (uint)cc; + cc >>= 32; + cc += (long)xx[3] - t2 + t3 + t7; + z[3] = (uint)cc; + cc >>= 32; + cc += (long)xx[4] + xx16 + xx21 + t1 - t3 + t7; + z[4] = (uint)cc; + cc >>= 32; + cc += (long)xx[5] - xx16 + t1 + t2 + t4; + z[5] = (uint)cc; + cc >>= 32; + cc += (long)xx[6] + xx18 - xx17 + t2 + t3; + z[6] = (uint)cc; + cc >>= 32; + cc += (long)xx[7] + xx16 + xx19 - xx18 + t3; + z[7] = (uint)cc; + cc >>= 32; + cc += (long)xx[8] + xx16 + xx17 + xx20 - xx19; + z[8] = (uint)cc; + cc >>= 32; + cc += (long)xx[9] + xx18 - xx20 + t4; + z[9] = (uint)cc; + cc >>= 32; + cc += (long)xx[10] + xx18 + xx19 - t5 + t6; + z[10] = (uint)cc; + cc >>= 32; + cc += (long)xx[11] + xx19 + xx20 - t6; + z[11] = (uint)cc; + cc >>= 32; + cc += n; + + Debug.Assert(cc >= 0); + + Reduce32((uint)cc, z); + } + + public static void Reduce32(uint x, uint[] z) + { + long cc = 0; + + if (x != 0) + { + long xx12 = x; + + cc += (long)z[0] + xx12; + z[0] = (uint)cc; + cc >>= 32; + cc += (long)z[1] - xx12; + z[1] = (uint)cc; + cc >>= 32; + if (cc != 0) + { + cc += (long)z[2]; + z[2] = (uint)cc; + cc >>= 32; + } + cc += (long)z[3] + xx12; + z[3] = (uint)cc; + cc >>= 32; + cc += (long)z[4] + xx12; + z[4] = (uint)cc; + cc >>= 32; + + Debug.Assert(cc == 0 || cc == 1); + } + + if ((cc != 0 && Nat.IncAt(12, z, 5) != 0) + || (z[11] == P11 && Nat.Gte(12, z, P))) + { + AddPInvTo(z); + } + } + + public static void Square(uint[] x, uint[] z) + { + uint[] tt = Nat.Create(24); + Nat384.Square(x, tt); + Reduce(tt, z); + } + + public static void SquareN(uint[] x, int n, uint[] z) + { + Debug.Assert(n > 0); + + uint[] tt = Nat.Create(24); + Nat384.Square(x, tt); + Reduce(tt, z); + + while (--n > 0) + { + Nat384.Square(z, tt); + Reduce(tt, z); + } + } + + public static void Subtract(uint[] x, uint[] y, uint[] z) + { + int c = Nat.Sub(12, x, y, z); + if (c != 0) + { + SubPInvFrom(z); + } + } + + public static void SubtractExt(uint[] xx, uint[] yy, uint[] zz) + { + int c = Nat.Sub(24, xx, yy, zz); + if (c != 0) + { + if (Nat.SubFrom(PExtInv.Length, PExtInv, zz) != 0) + { + Nat.DecAt(24, zz, PExtInv.Length); + } + } + } + + public static void Twice(uint[] x, uint[] z) + { + uint c = Nat.ShiftUpBit(12, x, 0, z); + if (c != 0 || (z[11] == P11 && Nat.Gte(12, z, P))) + { + AddPInvTo(z); + } + } + + private static void AddPInvTo(uint[] z) + { + long c = (long)z[0] + 1; + z[0] = (uint)c; + c >>= 32; + c += (long)z[1] - 1; + z[1] = (uint)c; + c >>= 32; + if (c != 0) + { + c += (long)z[2]; + z[2] = (uint)c; + c >>= 32; + } + c += (long)z[3] + 1; + z[3] = (uint)c; + c >>= 32; + c += (long)z[4] + 1; + z[4] = (uint)c; + c >>= 32; + if (c != 0) + { + Nat.IncAt(12, z, 5); + } + } + + private static void SubPInvFrom(uint[] z) + { + long c = (long)z[0] - 1; + z[0] = (uint)c; + c >>= 32; + c += (long)z[1] + 1; + z[1] = (uint)c; + c >>= 32; + if (c != 0) + { + c += (long)z[2]; + z[2] = (uint)c; + c >>= 32; + } + c += (long)z[3] - 1; + z[3] = (uint)c; + c >>= 32; + c += (long)z[4] - 1; + z[4] = (uint)c; + c >>= 32; + if (c != 0) + { + Nat.DecAt(12, z, 5); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP384R1Field.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP384R1Field.cs.meta new file mode 100644 index 0000000..36f861b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP384R1Field.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 00c714cd71f6a6e448cf0b5d19eeaf77 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP384R1FieldElement.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP384R1FieldElement.cs new file mode 100644 index 0000000..3fc1fb8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP384R1FieldElement.cs @@ -0,0 +1,212 @@ +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP384R1FieldElement + : AbstractFpFieldElement + { + public static readonly BigInteger Q = new BigInteger(1, + Hex.DecodeStrict("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF")); + + protected internal readonly uint[] x; + + public SecP384R1FieldElement(BigInteger x) + { + if (x == null || x.SignValue < 0 || x.CompareTo(Q) >= 0) + throw new ArgumentException("value invalid for SecP384R1FieldElement", "x"); + + this.x = SecP384R1Field.FromBigInteger(x); + } + + public SecP384R1FieldElement() + { + this.x = Nat.Create(12); + } + + protected internal SecP384R1FieldElement(uint[] x) + { + this.x = x; + } + + public override bool IsZero + { + get { return Nat.IsZero(12, x); } + } + + public override bool IsOne + { + get { return Nat.IsOne(12, x); } + } + + public override bool TestBitZero() + { + return Nat.GetBit(x, 0) == 1; + } + + public override BigInteger ToBigInteger() + { + return Nat.ToBigInteger(12, x); + } + + public override string FieldName + { + get { return "SecP384R1Field"; } + } + + public override int FieldSize + { + get { return Q.BitLength; } + } + + public override ECFieldElement Add(ECFieldElement b) + { + uint[] z = Nat.Create(12); + SecP384R1Field.Add(x, ((SecP384R1FieldElement)b).x, z); + return new SecP384R1FieldElement(z); + } + + public override ECFieldElement AddOne() + { + uint[] z = Nat.Create(12); + SecP384R1Field.AddOne(x, z); + return new SecP384R1FieldElement(z); + } + + public override ECFieldElement Subtract(ECFieldElement b) + { + uint[] z = Nat.Create(12); + SecP384R1Field.Subtract(x, ((SecP384R1FieldElement)b).x, z); + return new SecP384R1FieldElement(z); + } + + public override ECFieldElement Multiply(ECFieldElement b) + { + uint[] z = Nat.Create(12); + SecP384R1Field.Multiply(x, ((SecP384R1FieldElement)b).x, z); + return new SecP384R1FieldElement(z); + } + + public override ECFieldElement Divide(ECFieldElement b) + { + //return Multiply(b.Invert()); + uint[] z = Nat.Create(12); + SecP384R1Field.Inv(((SecP384R1FieldElement)b).x, z); + SecP384R1Field.Multiply(z, x, z); + return new SecP384R1FieldElement(z); + } + + public override ECFieldElement Negate() + { + uint[] z = Nat.Create(12); + SecP384R1Field.Negate(x, z); + return new SecP384R1FieldElement(z); + } + + public override ECFieldElement Square() + { + uint[] z = Nat.Create(12); + SecP384R1Field.Square(x, z); + return new SecP384R1FieldElement(z); + } + + public override ECFieldElement Invert() + { + //return new SecP384R1FieldElement(ToBigInteger().ModInverse(Q)); + uint[] z = Nat.Create(12); + SecP384R1Field.Inv(x, z); + return new SecP384R1FieldElement(z); + } + + /** + * return a sqrt root - the routine verifies that the calculation returns the right value - if + * none exists it returns null. + */ + public override ECFieldElement Sqrt() + { + // Raise this element to the exponent 2^382 - 2^126 - 2^94 + 2^30 + + uint[] x1 = this.x; + if (Nat.IsZero(12, x1) || Nat.IsOne(12, x1)) + return this; + + uint[] t1 = Nat.Create(12); + uint[] t2 = Nat.Create(12); + uint[] t3 = Nat.Create(12); + uint[] t4 = Nat.Create(12); + + SecP384R1Field.Square(x1, t1); + SecP384R1Field.Multiply(t1, x1, t1); + + SecP384R1Field.SquareN(t1, 2, t2); + SecP384R1Field.Multiply(t2, t1, t2); + + SecP384R1Field.Square(t2, t2); + SecP384R1Field.Multiply(t2, x1, t2); + + SecP384R1Field.SquareN(t2, 5, t3); + SecP384R1Field.Multiply(t3, t2, t3); + + SecP384R1Field.SquareN(t3, 5, t4); + SecP384R1Field.Multiply(t4, t2, t4); + + SecP384R1Field.SquareN(t4, 15, t2); + SecP384R1Field.Multiply(t2, t4, t2); + + SecP384R1Field.SquareN(t2, 2, t3); + SecP384R1Field.Multiply(t1, t3, t1); + + SecP384R1Field.SquareN(t3, 28, t3); + SecP384R1Field.Multiply(t2, t3, t2); + + SecP384R1Field.SquareN(t2, 60, t3); + SecP384R1Field.Multiply(t3, t2, t3); + + uint[] r = t2; + + SecP384R1Field.SquareN(t3, 120, r); + SecP384R1Field.Multiply(r, t3, r); + + SecP384R1Field.SquareN(r, 15, r); + SecP384R1Field.Multiply(r, t4, r); + + SecP384R1Field.SquareN(r, 33, r); + SecP384R1Field.Multiply(r, t1, r); + + SecP384R1Field.SquareN(r, 64, r); + SecP384R1Field.Multiply(r, x1, r); + + SecP384R1Field.SquareN(r, 30, t1); + SecP384R1Field.Square(t1, t2); + + return Nat.Eq(12, x1, t2) ? new SecP384R1FieldElement(t1) : null; + } + + public override bool Equals(object obj) + { + return Equals(obj as SecP384R1FieldElement); + } + + public override bool Equals(ECFieldElement other) + { + return Equals(other as SecP384R1FieldElement); + } + + public virtual bool Equals(SecP384R1FieldElement other) + { + if (this == other) + return true; + if (null == other) + return false; + return Nat.Eq(12, x, other.x); + } + + public override int GetHashCode() + { + return Q.GetHashCode() ^ Arrays.GetHashCode(x, 0, 12); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP384R1FieldElement.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP384R1FieldElement.cs.meta new file mode 100644 index 0000000..afd66a1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP384R1FieldElement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 94578a249bbf65d4699c1e84fbd6a4df +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP384R1Point.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP384R1Point.cs new file mode 100644 index 0000000..83159ce --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP384R1Point.cs @@ -0,0 +1,280 @@ +using System; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP384R1Point + : AbstractFpPoint + { + /** + * Create a point which encodes with point compression. + * + * @param curve + * the curve to use + * @param x + * affine x co-ordinate + * @param y + * affine y co-ordinate + * + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecP384R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * Create a point that encodes with or without point compresion. + * + * @param curve + * the curve to use + * @param x + * affine x co-ordinate + * @param y + * affine y co-ordinate + * @param withCompression + * if true encode with point compression + * + * @deprecated per-point compression property will be removed, refer + * {@link #getEncoded(bool)} + */ + public SecP384R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecP384R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecP384R1Point(null, AffineXCoord, AffineYCoord); + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + if (this == b) + return Twice(); + + ECCurve curve = this.Curve; + + SecP384R1FieldElement X1 = (SecP384R1FieldElement)this.RawXCoord, Y1 = (SecP384R1FieldElement)this.RawYCoord; + SecP384R1FieldElement X2 = (SecP384R1FieldElement)b.RawXCoord, Y2 = (SecP384R1FieldElement)b.RawYCoord; + + SecP384R1FieldElement Z1 = (SecP384R1FieldElement)this.RawZCoords[0]; + SecP384R1FieldElement Z2 = (SecP384R1FieldElement)b.RawZCoords[0]; + + uint c; + uint[] tt1 = Nat.Create(24); + uint[] tt2 = Nat.Create(24); + uint[] t3 = Nat.Create(12); + uint[] t4 = Nat.Create(12); + + bool Z1IsOne = Z1.IsOne; + uint[] U2, S2; + if (Z1IsOne) + { + U2 = X2.x; + S2 = Y2.x; + } + else + { + S2 = t3; + SecP384R1Field.Square(Z1.x, S2); + + U2 = tt2; + SecP384R1Field.Multiply(S2, X2.x, U2); + + SecP384R1Field.Multiply(S2, Z1.x, S2); + SecP384R1Field.Multiply(S2, Y2.x, S2); + } + + bool Z2IsOne = Z2.IsOne; + uint[] U1, S1; + if (Z2IsOne) + { + U1 = X1.x; + S1 = Y1.x; + } + else + { + S1 = t4; + SecP384R1Field.Square(Z2.x, S1); + + U1 = tt1; + SecP384R1Field.Multiply(S1, X1.x, U1); + + SecP384R1Field.Multiply(S1, Z2.x, S1); + SecP384R1Field.Multiply(S1, Y1.x, S1); + } + + uint[] H = Nat.Create(12); + SecP384R1Field.Subtract(U1, U2, H); + + uint[] R = Nat.Create(12); + SecP384R1Field.Subtract(S1, S2, R); + + // Check if b == this or b == -this + if (Nat.IsZero(12, H)) + { + if (Nat.IsZero(12, R)) + { + // this == b, i.e. this must be doubled + return this.Twice(); + } + + // this == -b, i.e. the result is the point at infinity + return curve.Infinity; + } + + uint[] HSquared = t3; + SecP384R1Field.Square(H, HSquared); + + uint[] G = Nat.Create(12); + SecP384R1Field.Multiply(HSquared, H, G); + + uint[] V = t3; + SecP384R1Field.Multiply(HSquared, U1, V); + + SecP384R1Field.Negate(G, G); + Nat384.Mul(S1, G, tt1); + + c = Nat.AddBothTo(12, V, V, G); + SecP384R1Field.Reduce32(c, G); + + SecP384R1FieldElement X3 = new SecP384R1FieldElement(t4); + SecP384R1Field.Square(R, X3.x); + SecP384R1Field.Subtract(X3.x, G, X3.x); + + SecP384R1FieldElement Y3 = new SecP384R1FieldElement(G); + SecP384R1Field.Subtract(V, X3.x, Y3.x); + Nat384.Mul(Y3.x, R, tt2); + SecP384R1Field.AddExt(tt1, tt2, tt1); + SecP384R1Field.Reduce(tt1, Y3.x); + + SecP384R1FieldElement Z3 = new SecP384R1FieldElement(H); + if (!Z1IsOne) + { + SecP384R1Field.Multiply(Z3.x, Z1.x, Z3.x); + } + if (!Z2IsOne) + { + SecP384R1Field.Multiply(Z3.x, Z2.x, Z3.x); + } + + ECFieldElement[] zs = new ECFieldElement[] { Z3 }; + + return new SecP384R1Point(curve, X3, Y3, zs, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + SecP384R1FieldElement Y1 = (SecP384R1FieldElement)this.RawYCoord; + if (Y1.IsZero) + return curve.Infinity; + + SecP384R1FieldElement X1 = (SecP384R1FieldElement)this.RawXCoord, Z1 = (SecP384R1FieldElement)this.RawZCoords[0]; + + uint c; + uint[] t1 = Nat.Create(12); + uint[] t2 = Nat.Create(12); + + uint[] Y1Squared = Nat.Create(12); + SecP384R1Field.Square(Y1.x, Y1Squared); + + uint[] T = Nat.Create(12); + SecP384R1Field.Square(Y1Squared, T); + + bool Z1IsOne = Z1.IsOne; + + uint[] Z1Squared = Z1.x; + if (!Z1IsOne) + { + Z1Squared = t2; + SecP384R1Field.Square(Z1.x, Z1Squared); + } + + SecP384R1Field.Subtract(X1.x, Z1Squared, t1); + + uint[] M = t2; + SecP384R1Field.Add(X1.x, Z1Squared, M); + SecP384R1Field.Multiply(M, t1, M); + c = Nat.AddBothTo(12, M, M, M); + SecP384R1Field.Reduce32(c, M); + + uint[] S = Y1Squared; + SecP384R1Field.Multiply(Y1Squared, X1.x, S); + c = Nat.ShiftUpBits(12, S, 2, 0); + SecP384R1Field.Reduce32(c, S); + + c = Nat.ShiftUpBits(12, T, 3, 0, t1); + SecP384R1Field.Reduce32(c, t1); + + SecP384R1FieldElement X3 = new SecP384R1FieldElement(T); + SecP384R1Field.Square(M, X3.x); + SecP384R1Field.Subtract(X3.x, S, X3.x); + SecP384R1Field.Subtract(X3.x, S, X3.x); + + SecP384R1FieldElement Y3 = new SecP384R1FieldElement(S); + SecP384R1Field.Subtract(S, X3.x, Y3.x); + SecP384R1Field.Multiply(Y3.x, M, Y3.x); + SecP384R1Field.Subtract(Y3.x, t1, Y3.x); + + SecP384R1FieldElement Z3 = new SecP384R1FieldElement(M); + SecP384R1Field.Twice(Y1.x, Z3.x); + if (!Z1IsOne) + { + SecP384R1Field.Multiply(Z3.x, Z1.x, Z3.x); + } + + return new SecP384R1Point(curve, X3, Y3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this == b) + return ThreeTimes(); + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECFieldElement Y1 = this.RawYCoord; + if (Y1.IsZero) + return b; + + return Twice().Add(b); + } + + public override ECPoint ThreeTimes() + { + if (this.IsInfinity || this.RawYCoord.IsZero) + return this; + + // NOTE: Be careful about recursions between TwicePlus and ThreeTimes + return Twice().Add(this); + } + + public override ECPoint Negate() + { + if (IsInfinity) + return this; + + return new SecP384R1Point(Curve, RawXCoord, RawYCoord.Negate(), RawZCoords, IsCompressed); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP384R1Point.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP384R1Point.cs.meta new file mode 100644 index 0000000..7ae8199 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP384R1Point.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a1d19b5df387258439cd9145ef2f045f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP521R1Curve.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP521R1Curve.cs new file mode 100644 index 0000000..143176b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP521R1Curve.cs @@ -0,0 +1,170 @@ +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP521R1Curve + : AbstractFpCurve + { + public static readonly BigInteger q = SecP521R1FieldElement.Q; + + private const int SECP521R1_DEFAULT_COORDS = COORD_JACOBIAN; + private const int SECP521R1_FE_INTS = 17; + private static readonly ECFieldElement[] SECP521R1_AFFINE_ZS = new ECFieldElement[] { new SecP521R1FieldElement(BigInteger.One) }; + + protected readonly SecP521R1Point m_infinity; + + public SecP521R1Curve() + : base(q) + { + this.m_infinity = new SecP521R1Point(this, null, null); + + this.m_a = FromBigInteger(new BigInteger(1, + Hex.DecodeStrict("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC"))); + this.m_b = FromBigInteger(new BigInteger(1, + Hex.DecodeStrict("0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00"))); + this.m_order = new BigInteger(1, Hex.DecodeStrict("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409")); + this.m_cofactor = BigInteger.One; + this.m_coord = SECP521R1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecP521R1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_JACOBIAN: + return true; + default: + return false; + } + } + + public virtual BigInteger Q + { + get { return q; } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return q.BitLength; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecP521R1FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecP521R1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecP521R1Point(this, x, y, zs, withCompression); + } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + uint[] table = new uint[len * SECP521R1_FE_INTS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat.Copy(SECP521R1_FE_INTS, ((SecP521R1FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECP521R1_FE_INTS; + Nat.Copy(SECP521R1_FE_INTS, ((SecP521R1FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECP521R1_FE_INTS; + } + } + + return new SecP521R1LookupTable(this, table, len); + } + + public override ECFieldElement RandomFieldElement(SecureRandom r) + { + uint[] x = Nat.Create(17); + SecP521R1Field.Random(r, x); + return new SecP521R1FieldElement(x); + } + + public override ECFieldElement RandomFieldElementMult(SecureRandom r) + { + uint[] x = Nat.Create(17); + SecP521R1Field.RandomMult(r, x); + return new SecP521R1FieldElement(x); + } + + private class SecP521R1LookupTable + : AbstractECLookupTable + { + private readonly SecP521R1Curve m_outer; + private readonly uint[] m_table; + private readonly int m_size; + + internal SecP521R1LookupTable(SecP521R1Curve outer, uint[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public override int Size + { + get { return m_size; } + } + + public override ECPoint Lookup(int index) + { + uint[] x = Nat.Create(SECP521R1_FE_INTS), y = Nat.Create(SECP521R1_FE_INTS); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + uint MASK = (uint)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECP521R1_FE_INTS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECP521R1_FE_INTS + j] & MASK; + } + + pos += (SECP521R1_FE_INTS * 2); + } + + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + uint[] x = Nat.Create(SECP521R1_FE_INTS), y = Nat.Create(SECP521R1_FE_INTS); + int pos = index * SECP521R1_FE_INTS * 2; + + for (int j = 0; j < SECP521R1_FE_INTS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECP521R1_FE_INTS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(uint[] x, uint[] y) + { + return m_outer.CreateRawPoint(new SecP521R1FieldElement(x), new SecP521R1FieldElement(y), SECP521R1_AFFINE_ZS, false); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP521R1Curve.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP521R1Curve.cs.meta new file mode 100644 index 0000000..68eaae6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP521R1Curve.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8aaa6348e2dd9af4a9fe0b69369616d3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP521R1Field.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP521R1Field.cs new file mode 100644 index 0000000..0f1922f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP521R1Field.cs @@ -0,0 +1,195 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP521R1Field + { + // 2^521 - 1 + internal static readonly uint[] P = new uint[]{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x1FF }; + private const uint P16 = 0x1FFU; + + public static void Add(uint[] x, uint[] y, uint[] z) + { + uint c = Nat.Add(16, x, y, z) + x[16] + y[16]; + if (c > P16 || (c == P16 && Nat.Eq(16, z, P))) + { + c += Nat.Inc(16, z); + c &= P16; + } + z[16] = c; + } + + public static void AddOne(uint[] x, uint[] z) + { + uint c = Nat.Inc(16, x, z) + x[16]; + if (c > P16 || (c == P16 && Nat.Eq(16, z, P))) + { + c += Nat.Inc(16, z); + c &= P16; + } + z[16] = c; + } + + public static uint[] FromBigInteger(BigInteger x) + { + uint[] z = Nat.FromBigInteger(521, x); + if (Nat.Eq(17, z, P)) + { + Nat.Zero(17, z); + } + return z; + } + + public static void Half(uint[] x, uint[] z) + { + uint x16 = x[16]; + uint c = Nat.ShiftDownBit(16, x, x16, z); + z[16] = (x16 >> 1) | (c >> 23); + } + + public static void Inv(uint[] x, uint[] z) + { + Mod.CheckedModOddInverse(P, x, z); + } + + public static int IsZero(uint[] x) + { + uint d = 0; + for (int i = 0; i < 17; ++i) + { + d |= x[i]; + } + d = (d >> 1) | (d & 1); + return ((int)d - 1) >> 31; + } + + public static void Multiply(uint[] x, uint[] y, uint[] z) + { + uint[] tt = Nat.Create(33); + ImplMultiply(x, y, tt); + Reduce(tt, z); + } + + public static void Negate(uint[] x, uint[] z) + { + if (0 != IsZero(x)) + { + Nat.Sub(17, P, P, z); + } + else + { + Nat.Sub(17, P, x, z); + } + } + + public static void Random(SecureRandom r, uint[] z) + { + byte[] bb = new byte[17 * 4]; + do + { + r.NextBytes(bb); + Pack.LE_To_UInt32(bb, 0, z, 0, 17); + z[16] &= P16; + } + while (0 == Nat.LessThan(17, z, P)); + } + + public static void RandomMult(SecureRandom r, uint[] z) + { + do + { + Random(r, z); + } + while (0 != IsZero(z)); + } + + public static void Reduce(uint[] xx, uint[] z) + { + Debug.Assert(xx[32] >> 18 == 0); + uint xx32 = xx[32]; + uint c = Nat.ShiftDownBits(16, xx, 16, 9, xx32, z, 0) >> 23; + c += xx32 >> 9; + c += Nat.AddTo(16, xx, z); + if (c > P16 || (c == P16 && Nat.Eq(16, z, P))) + { + c += Nat.Inc(16, z); + c &= P16; + } + z[16] = c; + } + + public static void Reduce23(uint[] z) + { + uint z16 = z[16]; + uint c = Nat.AddWordTo(16, z16 >> 9, z) + (z16 & P16); + if (c > P16 || (c == P16 && Nat.Eq(16, z, P))) + { + c += Nat.Inc(16, z); + c &= P16; + } + z[16] = c; + } + + public static void Square(uint[] x, uint[] z) + { + uint[] tt = Nat.Create(33); + ImplSquare(x, tt); + Reduce(tt, z); + } + + public static void SquareN(uint[] x, int n, uint[] z) + { + Debug.Assert(n > 0); + uint[] tt = Nat.Create(33); + ImplSquare(x, tt); + Reduce(tt, z); + + while (--n > 0) + { + ImplSquare(z, tt); + Reduce(tt, z); + } + } + + public static void Subtract(uint[] x, uint[] y, uint[] z) + { + int c = Nat.Sub(16, x, y, z) + (int)(x[16] - y[16]); + if (c < 0) + { + c += Nat.Dec(16, z); + c &= (int)P16; + } + z[16] = (uint)c; + } + + public static void Twice(uint[] x, uint[] z) + { + uint x16 = x[16]; + uint c = Nat.ShiftUpBit(16, x, x16 << 23, z) | (x16 << 1); + z[16] = c & P16; + } + + protected static void ImplMultiply(uint[] x, uint[] y, uint[] zz) + { + Nat512.Mul(x, y, zz); + + uint x16 = x[16], y16 = y[16]; + zz[32] = Nat.Mul31BothAdd(16, x16, y, y16, x, zz, 16) + (x16 * y16); + } + + protected static void ImplSquare(uint[] x, uint[] zz) + { + Nat512.Square(x, zz); + + uint x16 = x[16]; + zz[32] = Nat.MulWordAddTo(16, x16 << 1, x, 0, zz, 16) + (x16 * x16); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP521R1Field.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP521R1Field.cs.meta new file mode 100644 index 0000000..8331c36 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP521R1Field.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 86af9d4b950716e4c984d68fb9d360a2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP521R1FieldElement.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP521R1FieldElement.cs new file mode 100644 index 0000000..adfc89e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP521R1FieldElement.cs @@ -0,0 +1,169 @@ +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP521R1FieldElement + : AbstractFpFieldElement + { + public static readonly BigInteger Q = new BigInteger(1, + Hex.DecodeStrict("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")); + + protected internal readonly uint[] x; + + public SecP521R1FieldElement(BigInteger x) + { + if (x == null || x.SignValue < 0 || x.CompareTo(Q) >= 0) + throw new ArgumentException("value invalid for SecP521R1FieldElement", "x"); + + this.x = SecP521R1Field.FromBigInteger(x); + } + + public SecP521R1FieldElement() + { + this.x = Nat.Create(17); + } + + protected internal SecP521R1FieldElement(uint[] x) + { + this.x = x; + } + + public override bool IsZero + { + get { return Nat.IsZero(17, x); } + } + + public override bool IsOne + { + get { return Nat.IsOne(17, x); } + } + + public override bool TestBitZero() + { + return Nat.GetBit(x, 0) == 1; + } + + public override BigInteger ToBigInteger() + { + return Nat.ToBigInteger(17, x); + } + + public override string FieldName + { + get { return "SecP521R1Field"; } + } + + public override int FieldSize + { + get { return Q.BitLength; } + } + + public override ECFieldElement Add(ECFieldElement b) + { + uint[] z = Nat.Create(17); + SecP521R1Field.Add(x, ((SecP521R1FieldElement)b).x, z); + return new SecP521R1FieldElement(z); + } + + public override ECFieldElement AddOne() + { + uint[] z = Nat.Create(17); + SecP521R1Field.AddOne(x, z); + return new SecP521R1FieldElement(z); + } + + public override ECFieldElement Subtract(ECFieldElement b) + { + uint[] z = Nat.Create(17); + SecP521R1Field.Subtract(x, ((SecP521R1FieldElement)b).x, z); + return new SecP521R1FieldElement(z); + } + + public override ECFieldElement Multiply(ECFieldElement b) + { + uint[] z = Nat.Create(17); + SecP521R1Field.Multiply(x, ((SecP521R1FieldElement)b).x, z); + return new SecP521R1FieldElement(z); + } + + public override ECFieldElement Divide(ECFieldElement b) + { + //return Multiply(b.Invert()); + uint[] z = Nat.Create(17); + SecP521R1Field.Inv(((SecP521R1FieldElement)b).x, z); + SecP521R1Field.Multiply(z, x, z); + return new SecP521R1FieldElement(z); + } + + public override ECFieldElement Negate() + { + uint[] z = Nat.Create(17); + SecP521R1Field.Negate(x, z); + return new SecP521R1FieldElement(z); + } + + public override ECFieldElement Square() + { + uint[] z = Nat.Create(17); + SecP521R1Field.Square(x, z); + return new SecP521R1FieldElement(z); + } + + public override ECFieldElement Invert() + { + //return new SecP521R1FieldElement(ToBigInteger().ModInverse(Q)); + uint[] z = Nat.Create(17); + SecP521R1Field.Inv(x, z); + return new SecP521R1FieldElement(z); + } + + /** + * return a sqrt root - the routine verifies that the calculation returns the right value - if + * none exists it returns null. + */ + public override ECFieldElement Sqrt() + { + // Raise this element to the exponent 2^519 + + uint[] x1 = this.x; + if (Nat.IsZero(17, x1) || Nat.IsOne(17, x1)) + return this; + + uint[] t1 = Nat.Create(17); + uint[] t2 = Nat.Create(17); + + SecP521R1Field.SquareN(x1, 519, t1); + SecP521R1Field.Square(t1, t2); + + return Nat.Eq(17, x1, t2) ? new SecP521R1FieldElement(t1) : null; + } + + public override bool Equals(object obj) + { + return Equals(obj as SecP521R1FieldElement); + } + + public override bool Equals(ECFieldElement other) + { + return Equals(other as SecP521R1FieldElement); + } + + public virtual bool Equals(SecP521R1FieldElement other) + { + if (this == other) + return true; + if (null == other) + return false; + return Nat.Eq(17, x, other.x); + } + + public override int GetHashCode() + { + return Q.GetHashCode() ^ Arrays.GetHashCode(x, 0, 17); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP521R1FieldElement.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP521R1FieldElement.cs.meta new file mode 100644 index 0000000..54f0930 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP521R1FieldElement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9b87deee759362244bad34295e22864e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP521R1Point.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP521R1Point.cs new file mode 100644 index 0000000..7ad97f7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP521R1Point.cs @@ -0,0 +1,275 @@ +using System; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecP521R1Point + : AbstractFpPoint + { + /** + * Create a point which encodes with point compression. + * + * @param curve + * the curve to use + * @param x + * affine x co-ordinate + * @param y + * affine y co-ordinate + * + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecP521R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * Create a point that encodes with or without point compresion. + * + * @param curve + * the curve to use + * @param x + * affine x co-ordinate + * @param y + * affine y co-ordinate + * @param withCompression + * if true encode with point compression + * + * @deprecated per-point compression property will be removed, refer + * {@link #getEncoded(bool)} + */ + public SecP521R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecP521R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecP521R1Point(null, AffineXCoord, AffineYCoord); + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + if (this == b) + return Twice(); + + ECCurve curve = this.Curve; + + SecP521R1FieldElement X1 = (SecP521R1FieldElement)this.RawXCoord, Y1 = (SecP521R1FieldElement)this.RawYCoord; + SecP521R1FieldElement X2 = (SecP521R1FieldElement)b.RawXCoord, Y2 = (SecP521R1FieldElement)b.RawYCoord; + + SecP521R1FieldElement Z1 = (SecP521R1FieldElement)this.RawZCoords[0]; + SecP521R1FieldElement Z2 = (SecP521R1FieldElement)b.RawZCoords[0]; + + uint[] t1 = Nat.Create(17); + uint[] t2 = Nat.Create(17); + uint[] t3 = Nat.Create(17); + uint[] t4 = Nat.Create(17); + + bool Z1IsOne = Z1.IsOne; + uint[] U2, S2; + if (Z1IsOne) + { + U2 = X2.x; + S2 = Y2.x; + } + else + { + S2 = t3; + SecP521R1Field.Square(Z1.x, S2); + + U2 = t2; + SecP521R1Field.Multiply(S2, X2.x, U2); + + SecP521R1Field.Multiply(S2, Z1.x, S2); + SecP521R1Field.Multiply(S2, Y2.x, S2); + } + + bool Z2IsOne = Z2.IsOne; + uint[] U1, S1; + if (Z2IsOne) + { + U1 = X1.x; + S1 = Y1.x; + } + else + { + S1 = t4; + SecP521R1Field.Square(Z2.x, S1); + + U1 = t1; + SecP521R1Field.Multiply(S1, X1.x, U1); + + SecP521R1Field.Multiply(S1, Z2.x, S1); + SecP521R1Field.Multiply(S1, Y1.x, S1); + } + + uint[] H = Nat.Create(17); + SecP521R1Field.Subtract(U1, U2, H); + + uint[] R = t2; + SecP521R1Field.Subtract(S1, S2, R); + + // Check if b == this or b == -this + if (Nat.IsZero(17, H)) + { + if (Nat.IsZero(17, R)) + { + // this == b, i.e. this must be doubled + return this.Twice(); + } + + // this == -b, i.e. the result is the point at infinity + return curve.Infinity; + } + + uint[] HSquared = t3; + SecP521R1Field.Square(H, HSquared); + + uint[] G = Nat.Create(17); + SecP521R1Field.Multiply(HSquared, H, G); + + uint[] V = t3; + SecP521R1Field.Multiply(HSquared, U1, V); + + SecP521R1Field.Multiply(S1, G, t1); + + SecP521R1FieldElement X3 = new SecP521R1FieldElement(t4); + SecP521R1Field.Square(R, X3.x); + SecP521R1Field.Add(X3.x, G, X3.x); + SecP521R1Field.Subtract(X3.x, V, X3.x); + SecP521R1Field.Subtract(X3.x, V, X3.x); + + SecP521R1FieldElement Y3 = new SecP521R1FieldElement(G); + SecP521R1Field.Subtract(V, X3.x, Y3.x); + SecP521R1Field.Multiply(Y3.x, R, t2); + SecP521R1Field.Subtract(t2, t1, Y3.x); + + SecP521R1FieldElement Z3 = new SecP521R1FieldElement(H); + if (!Z1IsOne) + { + SecP521R1Field.Multiply(Z3.x, Z1.x, Z3.x); + } + if (!Z2IsOne) + { + SecP521R1Field.Multiply(Z3.x, Z2.x, Z3.x); + } + + ECFieldElement[] zs = new ECFieldElement[] { Z3 }; + + return new SecP521R1Point(curve, X3, Y3, zs, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + SecP521R1FieldElement Y1 = (SecP521R1FieldElement)this.RawYCoord; + if (Y1.IsZero) + return curve.Infinity; + + SecP521R1FieldElement X1 = (SecP521R1FieldElement)this.RawXCoord, Z1 = (SecP521R1FieldElement)this.RawZCoords[0]; + + uint[] t1 = Nat.Create(17); + uint[] t2 = Nat.Create(17); + + uint[] Y1Squared = Nat.Create(17); + SecP521R1Field.Square(Y1.x, Y1Squared); + + uint[] T = Nat.Create(17); + SecP521R1Field.Square(Y1Squared, T); + + bool Z1IsOne = Z1.IsOne; + + uint[] Z1Squared = Z1.x; + if (!Z1IsOne) + { + Z1Squared = t2; + SecP521R1Field.Square(Z1.x, Z1Squared); + } + + SecP521R1Field.Subtract(X1.x, Z1Squared, t1); + + uint[] M = t2; + SecP521R1Field.Add(X1.x, Z1Squared, M); + SecP521R1Field.Multiply(M, t1, M); + Nat.AddBothTo(17, M, M, M); + SecP521R1Field.Reduce23(M); + + uint[] S = Y1Squared; + SecP521R1Field.Multiply(Y1Squared, X1.x, S); + Nat.ShiftUpBits(17, S, 2, 0); + SecP521R1Field.Reduce23(S); + + Nat.ShiftUpBits(17, T, 3, 0, t1); + SecP521R1Field.Reduce23(t1); + + SecP521R1FieldElement X3 = new SecP521R1FieldElement(T); + SecP521R1Field.Square(M, X3.x); + SecP521R1Field.Subtract(X3.x, S, X3.x); + SecP521R1Field.Subtract(X3.x, S, X3.x); + + SecP521R1FieldElement Y3 = new SecP521R1FieldElement(S); + SecP521R1Field.Subtract(S, X3.x, Y3.x); + SecP521R1Field.Multiply(Y3.x, M, Y3.x); + SecP521R1Field.Subtract(Y3.x, t1, Y3.x); + + SecP521R1FieldElement Z3 = new SecP521R1FieldElement(M); + SecP521R1Field.Twice(Y1.x, Z3.x); + if (!Z1IsOne) + { + SecP521R1Field.Multiply(Z3.x, Z1.x, Z3.x); + } + + return new SecP521R1Point(curve, X3, Y3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this == b) + return ThreeTimes(); + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECFieldElement Y1 = this.RawYCoord; + if (Y1.IsZero) + return b; + + return Twice().Add(b); + } + + public override ECPoint ThreeTimes() + { + if (this.IsInfinity || this.RawYCoord.IsZero) + return this; + + // NOTE: Be careful about recursions between TwicePlus and ThreeTimes + return Twice().Add(this); + } + + public override ECPoint Negate() + { + if (IsInfinity) + return this; + + return new SecP521R1Point(Curve, RawXCoord, RawYCoord.Negate(), RawZCoords, IsCompressed); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP521R1Point.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP521R1Point.cs.meta new file mode 100644 index 0000000..94e32d9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecP521R1Point.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 02e3676ba0cc5c24382ceedc5978cd85 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT113Field.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT113Field.cs new file mode 100644 index 0000000..56738a2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT113Field.cs @@ -0,0 +1,243 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT113Field + { + private const ulong M49 = ulong.MaxValue >> 15; + private const ulong M57 = ulong.MaxValue >> 7; + + public static void Add(ulong[] x, ulong[] y, ulong[] z) + { + z[0] = x[0] ^ y[0]; + z[1] = x[1] ^ y[1]; + } + + public static void AddExt(ulong[] xx, ulong[] yy, ulong[] zz) + { + zz[0] = xx[0] ^ yy[0]; + zz[1] = xx[1] ^ yy[1]; + zz[2] = xx[2] ^ yy[2]; + zz[3] = xx[3] ^ yy[3]; + } + + public static void AddOne(ulong[] x, ulong[] z) + { + z[0] = x[0] ^ 1UL; + z[1] = x[1]; + } + + private static void AddTo(ulong[] x, ulong[] z) + { + z[0] ^= x[0]; + z[1] ^= x[1]; + } + + public static ulong[] FromBigInteger(BigInteger x) + { + return Nat.FromBigInteger64(113, x); + } + + public static void HalfTrace(ulong[] x, ulong[] z) + { + ulong[] tt = Nat128.CreateExt64(); + + Nat128.Copy64(x, z); + for (int i = 1; i < 113; i += 2) + { + ImplSquare(z, tt); + Reduce(tt, z); + ImplSquare(z, tt); + Reduce(tt, z); + AddTo(x, z); + } + } + + public static void Invert(ulong[] x, ulong[] z) + { + if (Nat128.IsZero64(x)) + throw new InvalidOperationException(); + + // Itoh-Tsujii inversion + + ulong[] t0 = Nat128.Create64(); + ulong[] t1 = Nat128.Create64(); + + Square(x, t0); + Multiply(t0, x, t0); + Square(t0, t0); + Multiply(t0, x, t0); + SquareN(t0, 3, t1); + Multiply(t1, t0, t1); + Square(t1, t1); + Multiply(t1, x, t1); + SquareN(t1, 7, t0); + Multiply(t0, t1, t0); + SquareN(t0, 14, t1); + Multiply(t1, t0, t1); + SquareN(t1, 28, t0); + Multiply(t0, t1, t0); + SquareN(t0, 56, t1); + Multiply(t1, t0, t1); + Square(t1, z); + } + + public static void Multiply(ulong[] x, ulong[] y, ulong[] z) + { + ulong[] tt = new ulong[8]; + ImplMultiply(x, y, tt); + Reduce(tt, z); + } + + public static void MultiplyAddToExt(ulong[] x, ulong[] y, ulong[] zz) + { + ulong[] tt = new ulong[8]; + ImplMultiply(x, y, tt); + AddExt(zz, tt, zz); + } + + public static void Reduce(ulong[] xx, ulong[] z) + { + ulong x0 = xx[0], x1 = xx[1], x2 = xx[2], x3 = xx[3]; + + x1 ^= (x3 << 15) ^ (x3 << 24); + x2 ^= (x3 >> 49) ^ (x3 >> 40); + + x0 ^= (x2 << 15) ^ (x2 << 24); + x1 ^= (x2 >> 49) ^ (x2 >> 40); + + ulong t = x1 >> 49; + z[0] = x0 ^ t ^ (t << 9); + z[1] = x1 & M49; + } + + public static void Reduce15(ulong[] z, int zOff) + { + ulong z1 = z[zOff + 1], t = z1 >> 49; + z[zOff ] ^= t ^ (t << 9); + z[zOff + 1] = z1 & M49; + } + + public static void Sqrt(ulong[] x, ulong[] z) + { + ulong u0 = Interleave.Unshuffle(x[0]), u1 = Interleave.Unshuffle(x[1]); + ulong e0 = (u0 & 0x00000000FFFFFFFFUL) | (u1 << 32); + ulong c0 = (u0 >> 32) | (u1 & 0xFFFFFFFF00000000UL); + + z[0] = e0 ^ (c0 << 57) ^ (c0 << 5); + z[1] = (c0 >> 7) ^ (c0 >> 59); + } + + public static void Square(ulong[] x, ulong[] z) + { + ulong[] tt = Nat128.CreateExt64(); + ImplSquare(x, tt); + Reduce(tt, z); + } + + public static void SquareAddToExt(ulong[] x, ulong[] zz) + { + ulong[] tt = Nat128.CreateExt64(); + ImplSquare(x, tt); + AddExt(zz, tt, zz); + } + + public static void SquareN(ulong[] x, int n, ulong[] z) + { + Debug.Assert(n > 0); + + ulong[] tt = Nat128.CreateExt64(); + ImplSquare(x, tt); + Reduce(tt, z); + + while (--n > 0) + { + ImplSquare(z, tt); + Reduce(tt, z); + } + } + + public static uint Trace(ulong[] x) + { + // Non-zero-trace bits: 0 + return (uint)(x[0]) & 1U; + } + + protected static void ImplMultiply(ulong[] x, ulong[] y, ulong[] zz) + { + /* + * "Three-way recursion" as described in "Batch binary Edwards", Daniel J. Bernstein. + */ + + ulong f0 = x[0], f1 = x[1]; + f1 = ((f0 >> 57) ^ (f1 << 7)) & M57; + f0 &= M57; + + ulong g0 = y[0], g1 = y[1]; + g1 = ((g0 >> 57) ^ (g1 << 7)) & M57; + g0 &= M57; + + ulong[] u = zz; + ulong[] H = new ulong[6]; + + ImplMulw(u, f0, g0, H, 0); // H(0) 57/56 bits + ImplMulw(u, f1, g1, H, 2); // H(INF) 57/54 bits + ImplMulw(u, f0 ^ f1, g0 ^ g1, H, 4); // H(1) 57/56 bits + + ulong r = H[1] ^ H[2]; + ulong z0 = H[0], + z3 = H[3], + z1 = H[4] ^ z0 ^ r, + z2 = H[5] ^ z3 ^ r; + + zz[0] = z0 ^ (z1 << 57); + zz[1] = (z1 >> 7) ^ (z2 << 50); + zz[2] = (z2 >> 14) ^ (z3 << 43); + zz[3] = (z3 >> 21); + } + + protected static void ImplMulw(ulong[] u, ulong x, ulong y, ulong[] z, int zOff) + { + Debug.Assert(x >> 57 == 0); + Debug.Assert(y >> 57 == 0); + + //u[0] = 0; + u[1] = y; + u[2] = u[1] << 1; + u[3] = u[2] ^ y; + u[4] = u[2] << 1; + u[5] = u[4] ^ y; + u[6] = u[3] << 1; + u[7] = u[6] ^ y; + + uint j = (uint)x; + ulong g, h = 0, l = u[j & 7]; + int k = 48; + do + { + j = (uint)(x >> k); + g = u[j & 7] + ^ u[(j >> 3) & 7] << 3 + ^ u[(j >> 6) & 7] << 6; + l ^= (g << k); + h ^= (g >> -k); + } + while ((k -= 9) > 0); + + h ^= ((x & 0x0100804020100800UL) & (ulong)(((long)y << 7) >> 63)) >> 8; + + Debug.Assert(h >> 49 == 0); + + z[zOff ] = l & M57; + z[zOff + 1] = (l >> 57) ^ (h << 7); + } + + protected static void ImplSquare(ulong[] x, ulong[] zz) + { + Interleave.Expand64To128(x, 0, 2, zz, 0); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT113Field.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT113Field.cs.meta new file mode 100644 index 0000000..a695efb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT113Field.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b453f15765c0e314eb276ae64ac513a6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT113FieldElement.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT113FieldElement.cs new file mode 100644 index 0000000..63de2b8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT113FieldElement.cs @@ -0,0 +1,233 @@ +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT113FieldElement + : AbstractF2mFieldElement + { + protected internal readonly ulong[] x; + + public SecT113FieldElement(BigInteger x) + { + if (x == null || x.SignValue < 0 || x.BitLength > 113) + throw new ArgumentException("value invalid for SecT113FieldElement", "x"); + + this.x = SecT113Field.FromBigInteger(x); + } + + public SecT113FieldElement() + { + this.x = Nat128.Create64(); + } + + protected internal SecT113FieldElement(ulong[] x) + { + this.x = x; + } + + public override bool IsOne + { + get { return Nat128.IsOne64(x); } + } + + public override bool IsZero + { + get { return Nat128.IsZero64(x); } + } + + public override bool TestBitZero() + { + return (x[0] & 1L) != 0L; + } + + public override BigInteger ToBigInteger() + { + return Nat128.ToBigInteger64(x); + } + + public override string FieldName + { + get { return "SecT113Field"; } + } + + public override int FieldSize + { + get { return 113; } + } + + public override ECFieldElement Add(ECFieldElement b) + { + ulong[] z = Nat128.Create64(); + SecT113Field.Add(x, ((SecT113FieldElement)b).x, z); + return new SecT113FieldElement(z); + } + + public override ECFieldElement AddOne() + { + ulong[] z = Nat128.Create64(); + SecT113Field.AddOne(x, z); + return new SecT113FieldElement(z); + } + + public override ECFieldElement Subtract(ECFieldElement b) + { + // Addition and Subtraction are the same in F2m + return Add(b); + } + + public override ECFieldElement Multiply(ECFieldElement b) + { + ulong[] z = Nat128.Create64(); + SecT113Field.Multiply(x, ((SecT113FieldElement)b).x, z); + return new SecT113FieldElement(z); + } + + public override ECFieldElement MultiplyMinusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) + { + return MultiplyPlusProduct(b, x, y); + } + + public override ECFieldElement MultiplyPlusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) + { + ulong[] ax = this.x, bx = ((SecT113FieldElement)b).x; + ulong[] xx = ((SecT113FieldElement)x).x, yx = ((SecT113FieldElement)y).x; + + ulong[] tt = Nat128.CreateExt64(); + SecT113Field.MultiplyAddToExt(ax, bx, tt); + SecT113Field.MultiplyAddToExt(xx, yx, tt); + + ulong[] z = Nat128.Create64(); + SecT113Field.Reduce(tt, z); + return new SecT113FieldElement(z); + } + + public override ECFieldElement Divide(ECFieldElement b) + { + return Multiply(b.Invert()); + } + + public override ECFieldElement Negate() + { + return this; + } + + public override ECFieldElement Square() + { + ulong[] z = Nat128.Create64(); + SecT113Field.Square(x, z); + return new SecT113FieldElement(z); + } + + public override ECFieldElement SquareMinusProduct(ECFieldElement x, ECFieldElement y) + { + return SquarePlusProduct(x, y); + } + + public override ECFieldElement SquarePlusProduct(ECFieldElement x, ECFieldElement y) + { + ulong[] ax = this.x; + ulong[] xx = ((SecT113FieldElement)x).x, yx = ((SecT113FieldElement)y).x; + + ulong[] tt = Nat128.CreateExt64(); + SecT113Field.SquareAddToExt(ax, tt); + SecT113Field.MultiplyAddToExt(xx, yx, tt); + + ulong[] z = Nat128.Create64(); + SecT113Field.Reduce(tt, z); + return new SecT113FieldElement(z); + } + + public override ECFieldElement SquarePow(int pow) + { + if (pow < 1) + return this; + + ulong[] z = Nat128.Create64(); + SecT113Field.SquareN(x, pow, z); + return new SecT113FieldElement(z); + } + + public override ECFieldElement HalfTrace() + { + ulong[] z = Nat128.Create64(); + SecT113Field.HalfTrace(x, z); + return new SecT113FieldElement(z); + } + + public override bool HasFastTrace + { + get { return true; } + } + + public override int Trace() + { + return (int)SecT113Field.Trace(x); + } + + public override ECFieldElement Invert() + { + ulong[] z = Nat128.Create64(); + SecT113Field.Invert(x, z); + return new SecT113FieldElement(z); + } + + public override ECFieldElement Sqrt() + { + ulong[] z = Nat128.Create64(); + SecT113Field.Sqrt(x, z); + return new SecT113FieldElement(z); + } + + public virtual int Representation + { + get { return F2mFieldElement.Tpb; } + } + + public virtual int M + { + get { return 113; } + } + + public virtual int K1 + { + get { return 9; } + } + + public virtual int K2 + { + get { return 0; } + } + + public virtual int K3 + { + get { return 0; } + } + + public override bool Equals(object obj) + { + return Equals(obj as SecT113FieldElement); + } + + public override bool Equals(ECFieldElement other) + { + return Equals(other as SecT113FieldElement); + } + + public virtual bool Equals(SecT113FieldElement other) + { + if (this == other) + return true; + if (null == other) + return false; + return Nat128.Eq64(x, other.x); + } + + public override int GetHashCode() + { + return 113009 ^ Arrays.GetHashCode(x, 0, 2); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT113FieldElement.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT113FieldElement.cs.meta new file mode 100644 index 0000000..6fe339d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT113FieldElement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1f9392392f5e81a47a17ce0d127e4d16 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT113R1Curve.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT113R1Curve.cs new file mode 100644 index 0000000..492b1d8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT113R1Curve.cs @@ -0,0 +1,177 @@ +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT113R1Curve + : AbstractF2mCurve + { + private const int SECT113R1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT113R1_FE_LONGS = 2; + private static readonly ECFieldElement[] SECT113R1_AFFINE_ZS = new ECFieldElement[] { new SecT113FieldElement(BigInteger.One) }; + + protected readonly SecT113R1Point m_infinity; + + public SecT113R1Curve() + : base(113, 9, 0, 0) + { + this.m_infinity = new SecT113R1Point(this, null, null); + + this.m_a = FromBigInteger(new BigInteger(1, Hex.DecodeStrict("003088250CA6E7C7FE649CE85820F7"))); + this.m_b = FromBigInteger(new BigInteger(1, Hex.DecodeStrict("00E8BEE4D3E2260744188BE0E9C723"))); + this.m_order = new BigInteger(1, Hex.DecodeStrict("0100000000000000D9CCEC8A39E56F")); + this.m_cofactor = BigInteger.Two; + + this.m_coord = SECT113R1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecT113R1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_LAMBDA_PROJECTIVE: + return true; + default: + return false; + } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return 113; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecT113FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecT113R1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecT113R1Point(this, x, y, zs, withCompression); + } + + public override bool IsKoblitz + { + get { return false; } + } + + public virtual int M + { + get { return 113; } + } + + public virtual bool IsTrinomial + { + get { return true; } + } + + public virtual int K1 + { + get { return 9; } + } + + public virtual int K2 + { + get { return 0; } + } + + public virtual int K3 + { + get { return 0; } + } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + ulong[] table = new ulong[len * SECT113R1_FE_LONGS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat128.Copy64(((SecT113FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECT113R1_FE_LONGS; + Nat128.Copy64(((SecT113FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECT113R1_FE_LONGS; + } + } + + return new SecT113R1LookupTable(this, table, len); + } + + private class SecT113R1LookupTable + : AbstractECLookupTable + { + private readonly SecT113R1Curve m_outer; + private readonly ulong[] m_table; + private readonly int m_size; + + internal SecT113R1LookupTable(SecT113R1Curve outer, ulong[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public override int Size + { + get { return m_size; } + } + + public override ECPoint Lookup(int index) + { + ulong[] x = Nat128.Create64(), y = Nat128.Create64(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + ulong MASK = (ulong)(long)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECT113R1_FE_LONGS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECT113R1_FE_LONGS + j] & MASK; + } + + pos += (SECT113R1_FE_LONGS * 2); + } + + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + ulong[] x = Nat128.Create64(), y = Nat128.Create64(); + int pos = index * SECT113R1_FE_LONGS * 2; + + for (int j = 0; j < SECT113R1_FE_LONGS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECT113R1_FE_LONGS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(ulong[] x, ulong[] y) + { + return m_outer.CreateRawPoint(new SecT113FieldElement(x), new SecT113FieldElement(y), SECT113R1_AFFINE_ZS, false); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT113R1Curve.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT113R1Curve.cs.meta new file mode 100644 index 0000000..4ecc4fd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT113R1Curve.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 357dc5e8740c73c459bf5a729cca7ebd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT113R1Point.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT113R1Point.cs new file mode 100644 index 0000000..db085d0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT113R1Point.cs @@ -0,0 +1,281 @@ +using System; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT113R1Point + : AbstractF2mPoint + { + /** + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecT113R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * @deprecated per-point compression property will be removed, refer {@link #getEncoded(bool)} + */ + public SecT113R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecT113R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecT113R1Point(null, AffineXCoord, AffineYCoord); + } + + public override ECFieldElement YCoord + { + get + { + ECFieldElement X = RawXCoord, L = RawYCoord; + + if (this.IsInfinity || X.IsZero) + return L; + + // Y is actually Lambda (X + Y/X) here; convert to affine value on the fly + ECFieldElement Y = L.Add(X).Multiply(X); + + ECFieldElement Z = RawZCoords[0]; + if (!Z.IsOne) + { + Y = Y.Divide(Z); + } + + return Y; + } + } + + protected internal override bool CompressionYTilde + { + get + { + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return false; + + ECFieldElement Y = this.RawYCoord; + + // Y is actually Lambda (X + Y/X) here + return Y.TestBitZero() != X.TestBitZero(); + } + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + ECFieldElement X2 = b.RawXCoord; + + if (X1.IsZero) + { + if (X2.IsZero) + return curve.Infinity; + + return b.Add(this); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord, Z2 = b.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement U2 = X2, S2 = L2; + if (!Z1IsOne) + { + U2 = U2.Multiply(Z1); + S2 = S2.Multiply(Z1); + } + + bool Z2IsOne = Z2.IsOne; + ECFieldElement U1 = X1, S1 = L1; + if (!Z2IsOne) + { + U1 = U1.Multiply(Z2); + S1 = S1.Multiply(Z2); + } + + ECFieldElement A = S1.Add(S2); + ECFieldElement B = U1.Add(U2); + + if (B.IsZero) + { + if (A.IsZero) + return Twice(); + + return curve.Infinity; + } + + ECFieldElement X3, L3, Z3; + if (X2.IsZero) + { + // TODO This can probably be optimized quite a bit + ECPoint p = this.Normalize(); + X1 = p.XCoord; + ECFieldElement Y1 = p.YCoord; + + ECFieldElement Y2 = L2; + ECFieldElement L = Y1.Add(Y2).Divide(X1); + + X3 = L.Square().Add(L).Add(X1).Add(curve.A); + if (X3.IsZero) + { + return new SecT113R1Point(curve, X3, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement Y3 = L.Multiply(X1.Add(X3)).Add(X3).Add(Y1); + L3 = Y3.Divide(X3).Add(X3); + Z3 = curve.FromBigInteger(BigInteger.One); + } + else + { + B = B.Square(); + + ECFieldElement AU1 = A.Multiply(U1); + ECFieldElement AU2 = A.Multiply(U2); + + X3 = AU1.Multiply(AU2); + if (X3.IsZero) + { + return new SecT113R1Point(curve, X3, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement ABZ2 = A.Multiply(B); + if (!Z2IsOne) + { + ABZ2 = ABZ2.Multiply(Z2); + } + + L3 = AU2.Add(B).SquarePlusProduct(ABZ2, L1.Add(Z1)); + + Z3 = ABZ2; + if (!Z1IsOne) + { + Z3 = Z3.Multiply(Z1); + } + } + + return new SecT113R1Point(curve, X3, L3, new ECFieldElement[]{ Z3 }, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is its own additive inverse + return curve.Infinity; + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement L1Z1 = Z1IsOne ? L1 : L1.Multiply(Z1); + ECFieldElement Z1Sq = Z1IsOne ? Z1 : Z1.Square(); + ECFieldElement a = curve.A; + ECFieldElement aZ1Sq = Z1IsOne ? a : a.Multiply(Z1Sq); + ECFieldElement T = L1.Square().Add(L1Z1).Add(aZ1Sq); + if (T.IsZero) + { + return new SecT113R1Point(curve, T, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement X3 = T.Square(); + ECFieldElement Z3 = Z1IsOne ? T : T.Multiply(Z1Sq); + + ECFieldElement X1Z1 = Z1IsOne ? X1 : X1.Multiply(Z1); + ECFieldElement L3 = X1Z1.SquarePlusProduct(T, L1Z1).Add(X3).Add(Z3); + + return new SecT113R1Point(curve, X3, L3, new ECFieldElement[]{ Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is its own additive inverse + return b; + } + + ECFieldElement X2 = b.RawXCoord, Z2 = b.RawZCoords[0]; + if (X2.IsZero || !Z2.IsOne) + { + return Twice().Add(b); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord; + + ECFieldElement X1Sq = X1.Square(); + ECFieldElement L1Sq = L1.Square(); + ECFieldElement Z1Sq = Z1.Square(); + ECFieldElement L1Z1 = L1.Multiply(Z1); + + ECFieldElement T = curve.A.Multiply(Z1Sq).Add(L1Sq).Add(L1Z1); + ECFieldElement L2plus1 = L2.AddOne(); + ECFieldElement A = curve.A.Add(L2plus1).Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); + ECFieldElement X2Z1Sq = X2.Multiply(Z1Sq); + ECFieldElement B = X2Z1Sq.Add(T).Square(); + + if (B.IsZero) + { + if (A.IsZero) + return b.Twice(); + + return curve.Infinity; + } + + if (A.IsZero) + { + return new SecT113R1Point(curve, A, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement X3 = A.Square().Multiply(X2Z1Sq); + ECFieldElement Z3 = A.Multiply(B).Multiply(Z1Sq); + ECFieldElement L3 = A.Add(B).Square().MultiplyPlusProduct(T, L2plus1, Z3); + + return new SecT113R1Point(curve, X3, L3, new ECFieldElement[]{ Z3 }, IsCompressed); + } + + public override ECPoint Negate() + { + if (IsInfinity) + return this; + + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return this; + + // L is actually Lambda (X + Y/X) here + ECFieldElement L = this.RawYCoord, Z = this.RawZCoords[0]; + return new SecT113R1Point(Curve, X, L.Add(Z), new ECFieldElement[]{ Z }, IsCompressed); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT113R1Point.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT113R1Point.cs.meta new file mode 100644 index 0000000..c72a886 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT113R1Point.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: db24db508b408664992bb193c413a394 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT113R2Curve.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT113R2Curve.cs new file mode 100644 index 0000000..d0fad0f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT113R2Curve.cs @@ -0,0 +1,177 @@ +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT113R2Curve + : AbstractF2mCurve + { + private const int SECT113R2_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT113R2_FE_LONGS = 2; + private static readonly ECFieldElement[] SECT113R2_AFFINE_ZS = new ECFieldElement[] { new SecT113FieldElement(BigInteger.One) }; + + protected readonly SecT113R2Point m_infinity; + + public SecT113R2Curve() + : base(113, 9, 0, 0) + { + this.m_infinity = new SecT113R2Point(this, null, null); + + this.m_a = FromBigInteger(new BigInteger(1, Hex.DecodeStrict("00689918DBEC7E5A0DD6DFC0AA55C7"))); + this.m_b = FromBigInteger(new BigInteger(1, Hex.DecodeStrict("0095E9A9EC9B297BD4BF36E059184F"))); + this.m_order = new BigInteger(1, Hex.DecodeStrict("010000000000000108789B2496AF93")); + this.m_cofactor = BigInteger.Two; + + this.m_coord = SECT113R2_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecT113R2Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_LAMBDA_PROJECTIVE: + return true; + default: + return false; + } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return 113; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecT113FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecT113R2Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecT113R2Point(this, x, y, zs, withCompression); + } + + public override bool IsKoblitz + { + get { return false; } + } + + public virtual int M + { + get { return 113; } + } + + public virtual bool IsTrinomial + { + get { return true; } + } + + public virtual int K1 + { + get { return 9; } + } + + public virtual int K2 + { + get { return 0; } + } + + public virtual int K3 + { + get { return 0; } + } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + ulong[] table = new ulong[len * SECT113R2_FE_LONGS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat128.Copy64(((SecT113FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECT113R2_FE_LONGS; + Nat128.Copy64(((SecT113FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECT113R2_FE_LONGS; + } + } + + return new SecT113R2LookupTable(this, table, len); + } + + private class SecT113R2LookupTable + : AbstractECLookupTable + { + private readonly SecT113R2Curve m_outer; + private readonly ulong[] m_table; + private readonly int m_size; + + internal SecT113R2LookupTable(SecT113R2Curve outer, ulong[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public override int Size + { + get { return m_size; } + } + + public override ECPoint Lookup(int index) + { + ulong[] x = Nat128.Create64(), y = Nat128.Create64(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + ulong MASK = (ulong)(long)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECT113R2_FE_LONGS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECT113R2_FE_LONGS + j] & MASK; + } + + pos += (SECT113R2_FE_LONGS * 2); + } + + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + ulong[] x = Nat128.Create64(), y = Nat128.Create64(); + int pos = index * SECT113R2_FE_LONGS * 2; + + for (int j = 0; j < SECT113R2_FE_LONGS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECT113R2_FE_LONGS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(ulong[] x, ulong[] y) + { + return m_outer.CreateRawPoint(new SecT113FieldElement(x), new SecT113FieldElement(y), SECT113R2_AFFINE_ZS, false); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT113R2Curve.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT113R2Curve.cs.meta new file mode 100644 index 0000000..03157cd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT113R2Curve.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 838e2229d3850664db0cd0cc79e5cc14 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT113R2Point.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT113R2Point.cs new file mode 100644 index 0000000..45fae2d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT113R2Point.cs @@ -0,0 +1,291 @@ +using System; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT113R2Point + : AbstractF2mPoint + { + /** + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecT113R2Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * @deprecated per-point compression property will be removed, refer {@link #getEncoded(bool)} + */ + public SecT113R2Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecT113R2Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecT113R2Point(null, AffineXCoord, AffineYCoord); + } + + public override ECFieldElement YCoord + { + get + { + ECFieldElement X = RawXCoord, L = RawYCoord; + + if (this.IsInfinity || X.IsZero) + return L; + + // Y is actually Lambda (X + Y/X) here; convert to affine value on the fly + ECFieldElement Y = L.Add(X).Multiply(X); + + ECFieldElement Z = RawZCoords[0]; + if (!Z.IsOne) + { + Y = Y.Divide(Z); + } + + return Y; + } + } + + protected internal override bool CompressionYTilde + { + get + { + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return false; + + ECFieldElement Y = this.RawYCoord; + + // Y is actually Lambda (X + Y/X) here + return Y.TestBitZero() != X.TestBitZero(); + } + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + { + return b; + } + if (b.IsInfinity) + { + return this; + } + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + ECFieldElement X2 = b.RawXCoord; + + if (X1.IsZero) + { + if (X2.IsZero) + return curve.Infinity; + + return b.Add(this); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord, Z2 = b.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement U2 = X2, S2 = L2; + if (!Z1IsOne) + { + U2 = U2.Multiply(Z1); + S2 = S2.Multiply(Z1); + } + + bool Z2IsOne = Z2.IsOne; + ECFieldElement U1 = X1, S1 = L1; + if (!Z2IsOne) + { + U1 = U1.Multiply(Z2); + S1 = S1.Multiply(Z2); + } + + ECFieldElement A = S1.Add(S2); + ECFieldElement B = U1.Add(U2); + + if (B.IsZero) + { + if (A.IsZero) + return Twice(); + + return curve.Infinity; + } + + ECFieldElement X3, L3, Z3; + if (X2.IsZero) + { + // TODO This can probably be optimized quite a bit + ECPoint p = this.Normalize(); + X1 = p.XCoord; + ECFieldElement Y1 = p.YCoord; + + ECFieldElement Y2 = L2; + ECFieldElement L = Y1.Add(Y2).Divide(X1); + + X3 = L.Square().Add(L).Add(X1).Add(curve.A); + if (X3.IsZero) + { + return new SecT113R2Point(curve, X3, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement Y3 = L.Multiply(X1.Add(X3)).Add(X3).Add(Y1); + L3 = Y3.Divide(X3).Add(X3); + Z3 = curve.FromBigInteger(BigInteger.One); + } + else + { + B = B.Square(); + + ECFieldElement AU1 = A.Multiply(U1); + ECFieldElement AU2 = A.Multiply(U2); + + X3 = AU1.Multiply(AU2); + if (X3.IsZero) + { + return new SecT113R2Point(curve, X3, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement ABZ2 = A.Multiply(B); + if (!Z2IsOne) + { + ABZ2 = ABZ2.Multiply(Z2); + } + + L3 = AU2.Add(B).SquarePlusProduct(ABZ2, L1.Add(Z1)); + + Z3 = ABZ2; + if (!Z1IsOne) + { + Z3 = Z3.Multiply(Z1); + } + } + + return new SecT113R2Point(curve, X3, L3, new ECFieldElement[]{ Z3 }, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + { + return this; + } + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is its own additive inverse + return curve.Infinity; + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement L1Z1 = Z1IsOne ? L1 : L1.Multiply(Z1); + ECFieldElement Z1Sq = Z1IsOne ? Z1 : Z1.Square(); + ECFieldElement a = curve.A; + ECFieldElement aZ1Sq = Z1IsOne ? a : a.Multiply(Z1Sq); + ECFieldElement T = L1.Square().Add(L1Z1).Add(aZ1Sq); + if (T.IsZero) + { + return new SecT113R2Point(curve, T, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement X3 = T.Square(); + ECFieldElement Z3 = Z1IsOne ? T : T.Multiply(Z1Sq); + + ECFieldElement X1Z1 = Z1IsOne ? X1 : X1.Multiply(Z1); + ECFieldElement L3 = X1Z1.SquarePlusProduct(T, L1Z1).Add(X3).Add(Z3); + + return new SecT113R2Point(curve, X3, L3, new ECFieldElement[]{ Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this.IsInfinity) + { + return b; + } + if (b.IsInfinity) + { + return Twice(); + } + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is its own additive inverse + return b; + } + + ECFieldElement X2 = b.RawXCoord, Z2 = b.RawZCoords[0]; + if (X2.IsZero || !Z2.IsOne) + { + return Twice().Add(b); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord; + + ECFieldElement X1Sq = X1.Square(); + ECFieldElement L1Sq = L1.Square(); + ECFieldElement Z1Sq = Z1.Square(); + ECFieldElement L1Z1 = L1.Multiply(Z1); + + ECFieldElement T = curve.A.Multiply(Z1Sq).Add(L1Sq).Add(L1Z1); + ECFieldElement L2plus1 = L2.AddOne(); + ECFieldElement A = curve.A.Add(L2plus1).Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); + ECFieldElement X2Z1Sq = X2.Multiply(Z1Sq); + ECFieldElement B = X2Z1Sq.Add(T).Square(); + + if (B.IsZero) + { + if (A.IsZero) + return b.Twice(); + + return curve.Infinity; + } + + if (A.IsZero) + { + return new SecT113R2Point(curve, A, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement X3 = A.Square().Multiply(X2Z1Sq); + ECFieldElement Z3 = A.Multiply(B).Multiply(Z1Sq); + ECFieldElement L3 = A.Add(B).Square().MultiplyPlusProduct(T, L2plus1, Z3); + + return new SecT113R2Point(curve, X3, L3, new ECFieldElement[]{ Z3 }, IsCompressed); + } + + public override ECPoint Negate() + { + if (IsInfinity) + return this; + + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return this; + + // L is actually Lambda (X + Y/X) here + ECFieldElement L = this.RawYCoord, Z = this.RawZCoords[0]; + return new SecT113R2Point(Curve, X, L.Add(Z), new ECFieldElement[]{ Z }, IsCompressed); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT113R2Point.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT113R2Point.cs.meta new file mode 100644 index 0000000..1de9fb0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT113R2Point.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3afdae1e2c9ae9846b605c11834cce0d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT131Field.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT131Field.cs new file mode 100644 index 0000000..adf4f04 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT131Field.cs @@ -0,0 +1,351 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT131Field + { + private const ulong M03 = ulong.MaxValue >> 61; + private const ulong M44 = ulong.MaxValue >> 20; + + private static readonly ulong[] ROOT_Z = new ulong[]{ 0x26BC4D789AF13523UL, 0x26BC4D789AF135E2UL, 0x6UL }; + + public static void Add(ulong[] x, ulong[] y, ulong[] z) + { + z[0] = x[0] ^ y[0]; + z[1] = x[1] ^ y[1]; + z[2] = x[2] ^ y[2]; + } + + public static void AddExt(ulong[] xx, ulong[] yy, ulong[] zz) + { + zz[0] = xx[0] ^ yy[0]; + zz[1] = xx[1] ^ yy[1]; + zz[2] = xx[2] ^ yy[2]; + zz[3] = xx[3] ^ yy[3]; + zz[4] = xx[4] ^ yy[4]; + } + + public static void AddOne(ulong[] x, ulong[] z) + { + z[0] = x[0] ^ 1UL; + z[1] = x[1]; + z[2] = x[2]; + } + + private static void AddTo(ulong[] x, ulong[] z) + { + z[0] ^= x[0]; + z[1] ^= x[1]; + z[2] ^= x[2]; + } + + public static ulong[] FromBigInteger(BigInteger x) + { + return Nat.FromBigInteger64(131, x); + } + + public static void HalfTrace(ulong[] x, ulong[] z) + { + ulong[] tt = Nat.Create64(5); + + Nat192.Copy64(x, z); + for (int i = 1; i < 131; i += 2) + { + ImplSquare(z, tt); + Reduce(tt, z); + ImplSquare(z, tt); + Reduce(tt, z); + AddTo(x, z); + } + } + + public static void Invert(ulong[] x, ulong[] z) + { + if (Nat192.IsZero64(x)) + throw new InvalidOperationException(); + + // Itoh-Tsujii inversion + + ulong[] t0 = Nat192.Create64(); + ulong[] t1 = Nat192.Create64(); + + Square(x, t0); + Multiply(t0, x, t0); + SquareN(t0, 2, t1); + Multiply(t1, t0, t1); + SquareN(t1, 4, t0); + Multiply(t0, t1, t0); + SquareN(t0, 8, t1); + Multiply(t1, t0, t1); + SquareN(t1, 16, t0); + Multiply(t0, t1, t0); + SquareN(t0, 32, t1); + Multiply(t1, t0, t1); + Square(t1, t1); + Multiply(t1, x, t1); + SquareN(t1, 65, t0); + Multiply(t0, t1, t0); + Square(t0, z); + } + + public static void Multiply(ulong[] x, ulong[] y, ulong[] z) + { + ulong[] tt = new ulong[8]; + ImplMultiply(x, y, tt); + Reduce(tt, z); + } + + public static void MultiplyAddToExt(ulong[] x, ulong[] y, ulong[] zz) + { + ulong[] tt = new ulong[8]; + ImplMultiply(x, y, tt); + AddExt(zz, tt, zz); + } + + public static void Reduce(ulong[] xx, ulong[] z) + { + ulong x0 = xx[0], x1 = xx[1], x2 = xx[2], x3 = xx[3], x4 = xx[4]; + + x1 ^= (x4 << 61) ^ (x4 << 63); + x2 ^= (x4 >> 3) ^ (x4 >> 1) ^ x4 ^ (x4 << 5); + x3 ^= (x4 >> 59); + + x0 ^= (x3 << 61) ^ (x3 << 63); + x1 ^= (x3 >> 3) ^ (x3 >> 1) ^ x3 ^ (x3 << 5); + x2 ^= (x3 >> 59); + + ulong t = x2 >> 3; + z[0] = x0 ^ t ^ (t << 2) ^ (t << 3) ^ (t << 8); + z[1] = x1 ^ (t >> 56); + z[2] = x2 & M03; + } + + public static void Reduce61(ulong[] z, int zOff) + { + ulong z2 = z[zOff + 2], t = z2 >> 3; + z[zOff ] ^= t ^ (t << 2) ^ (t << 3) ^ (t << 8); + z[zOff + 1] ^= (t >> 56); + z[zOff + 2] = z2 & M03; + } + + public static void Sqrt(ulong[] x, ulong[] z) + { + ulong[] odd = Nat192.Create64(); + + ulong u0, u1; + u0 = Interleave.Unshuffle(x[0]); u1 = Interleave.Unshuffle(x[1]); + ulong e0 = (u0 & 0x00000000FFFFFFFFUL) | (u1 << 32); + odd[0] = (u0 >> 32) | (u1 & 0xFFFFFFFF00000000UL); + + u0 = Interleave.Unshuffle(x[2]); + ulong e1 = (u0 & 0x00000000FFFFFFFFUL); + odd[1] = (u0 >> 32); + + Multiply(odd, ROOT_Z, z); + + z[0] ^= e0; + z[1] ^= e1; + } + + public static void Square(ulong[] x, ulong[] z) + { + ulong[] tt = Nat.Create64(5); + ImplSquare(x, tt); + Reduce(tt, z); + } + + public static void SquareAddToExt(ulong[] x, ulong[] zz) + { + ulong[] tt = Nat.Create64(5); + ImplSquare(x, tt); + AddExt(zz, tt, zz); + } + + public static void SquareN(ulong[] x, int n, ulong[] z) + { + Debug.Assert(n > 0); + + ulong[] tt = Nat.Create64(5); + ImplSquare(x, tt); + Reduce(tt, z); + + while (--n > 0) + { + ImplSquare(z, tt); + Reduce(tt, z); + } + } + + public static uint Trace(ulong[] x) + { + // Non-zero-trace bits: 0, 123, 129 + return (uint)(x[0] ^ (x[1] >> 59) ^ (x[2] >> 1)) & 1U; + } + + protected static void ImplCompactExt(ulong[] zz) + { + ulong z0 = zz[0], z1 = zz[1], z2 = zz[2], z3 = zz[3], z4 = zz[4], z5 = zz[5]; + zz[0] = z0 ^ (z1 << 44); + zz[1] = (z1 >> 20) ^ (z2 << 24); + zz[2] = (z2 >> 40) ^ (z3 << 4) + ^ (z4 << 48); + zz[3] = (z3 >> 60) ^ (z5 << 28) + ^ (z4 >> 16); + zz[4] = (z5 >> 36); + zz[5] = 0; + } + + protected static void ImplMultiply(ulong[] x, ulong[] y, ulong[] zz) + { + /* + * "Five-way recursion" as described in "Batch binary Edwards", Daniel J. Bernstein. + */ + + ulong f0 = x[0], f1 = x[1], f2 = x[2]; + f2 = ((f1 >> 24) ^ (f2 << 40)) & M44; + f1 = ((f0 >> 44) ^ (f1 << 20)) & M44; + f0 &= M44; + + ulong g0 = y[0], g1 = y[1], g2 = y[2]; + g2 = ((g1 >> 24) ^ (g2 << 40)) & M44; + g1 = ((g0 >> 44) ^ (g1 << 20)) & M44; + g0 &= M44; + + ulong[] u = zz; + ulong[] H = new ulong[10]; + + ImplMulw(u, f0, g0, H, 0); // H(0) 44/43 bits + ImplMulw(u, f2, g2, H, 2); // H(INF) 44/41 bits + + ulong t0 = f0 ^ f1 ^ f2; + ulong t1 = g0 ^ g1 ^ g2; + + ImplMulw(u, t0, t1, H, 4); // H(1) 44/43 bits + + ulong t2 = (f1 << 1) ^ (f2 << 2); + ulong t3 = (g1 << 1) ^ (g2 << 2); + + ImplMulw(u, f0 ^ t2, g0 ^ t3, H, 6); // H(t) 44/45 bits + ImplMulw(u, t0 ^ t2, t1 ^ t3, H, 8); // H(t + 1) 44/45 bits + + ulong t4 = H[6] ^ H[8]; + ulong t5 = H[7] ^ H[9]; + + Debug.Assert(t5 >> 44 == 0); + + // Calculate V + ulong v0 = (t4 << 1) ^ H[6]; + ulong v1 = t4 ^ (t5 << 1) ^ H[7]; + ulong v2 = t5; + + // Calculate U + ulong u0 = H[0]; + ulong u1 = H[1] ^ H[0] ^ H[4]; + ulong u2 = H[1] ^ H[5]; + + // Calculate W + ulong w0 = u0 ^ v0 ^ (H[2] << 4) ^ (H[2] << 1); + ulong w1 = u1 ^ v1 ^ (H[3] << 4) ^ (H[3] << 1); + ulong w2 = u2 ^ v2; + + // Propagate carries + w1 ^= (w0 >> 44); w0 &= M44; + w2 ^= (w1 >> 44); w1 &= M44; + + Debug.Assert((w0 & 1UL) == 0); + + // Divide W by t + + w0 = (w0 >> 1) ^ ((w1 & 1UL) << 43); + w1 = (w1 >> 1) ^ ((w2 & 1UL) << 43); + w2 = (w2 >> 1); + + // Divide W by (t + 1) + + w0 ^= (w0 << 1); + w0 ^= (w0 << 2); + w0 ^= (w0 << 4); + w0 ^= (w0 << 8); + w0 ^= (w0 << 16); + w0 ^= (w0 << 32); + + w0 &= M44; w1 ^= (w0 >> 43); + + w1 ^= (w1 << 1); + w1 ^= (w1 << 2); + w1 ^= (w1 << 4); + w1 ^= (w1 << 8); + w1 ^= (w1 << 16); + w1 ^= (w1 << 32); + + w1 &= M44; w2 ^= (w1 >> 43); + + w2 ^= (w2 << 1); + w2 ^= (w2 << 2); + w2 ^= (w2 << 4); + w2 ^= (w2 << 8); + w2 ^= (w2 << 16); + w2 ^= (w2 << 32); + + Debug.Assert(w2 >> 42 == 0); + + zz[0] = u0; + zz[1] = u1 ^ w0 ^ H[2]; + zz[2] = u2 ^ w1 ^ w0 ^ H[3]; + zz[3] = w2 ^ w1; + zz[4] = w2 ^ H[2]; + zz[5] = H[3]; + + ImplCompactExt(zz); + } + + protected static void ImplMulw(ulong[] u, ulong x, ulong y, ulong[] z, int zOff) + { + Debug.Assert(x >> 45 == 0); + Debug.Assert(y >> 45 == 0); + + //u[0] = 0; + u[1] = y; + u[2] = u[1] << 1; + u[3] = u[2] ^ y; + u[4] = u[2] << 1; + u[5] = u[4] ^ y; + u[6] = u[3] << 1; + u[7] = u[6] ^ y; + + uint j = (uint)x; + ulong g, h = 0, l = u[j & 7] + ^ u[(j >> 3) & 7] << 3 + ^ u[(j >> 6) & 7] << 6 + ^ u[(j >> 9) & 7] << 9 + ^ u[(j >> 12) & 7] << 12; + int k = 30; + do + { + j = (uint)(x >> k); + g = u[j & 7] + ^ u[(j >> 3) & 7] << 3 + ^ u[(j >> 6) & 7] << 6 + ^ u[(j >> 9) & 7] << 9 + ^ u[(j >> 12) & 7] << 12; + l ^= (g << k); + h ^= (g >> -k); + } + while ((k -= 15) > 0); + + Debug.Assert(h >> 25 == 0); + + z[zOff ] = l & M44; + z[zOff + 1] = (l >> 44) ^ (h << 20); + } + + protected static void ImplSquare(ulong[] x, ulong[] zz) + { + Interleave.Expand64To128(x, 0, 2, zz, 0); + zz[4] = Interleave.Expand8to16((uint)x[2]); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT131Field.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT131Field.cs.meta new file mode 100644 index 0000000..2a8a365 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT131Field.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d6f2d139818c1ea439d6084492434b48 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT131FieldElement.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT131FieldElement.cs new file mode 100644 index 0000000..4884e71 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT131FieldElement.cs @@ -0,0 +1,233 @@ +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT131FieldElement + : AbstractF2mFieldElement + { + protected internal readonly ulong[] x; + + public SecT131FieldElement(BigInteger x) + { + if (x == null || x.SignValue < 0 || x.BitLength > 131) + throw new ArgumentException("value invalid for SecT131FieldElement", "x"); + + this.x = SecT131Field.FromBigInteger(x); + } + + public SecT131FieldElement() + { + this.x = Nat192.Create64(); + } + + protected internal SecT131FieldElement(ulong[] x) + { + this.x = x; + } + + public override bool IsOne + { + get { return Nat192.IsOne64(x); } + } + + public override bool IsZero + { + get { return Nat192.IsZero64(x); } + } + + public override bool TestBitZero() + { + return (x[0] & 1UL) != 0UL; + } + + public override BigInteger ToBigInteger() + { + return Nat192.ToBigInteger64(x); + } + + public override string FieldName + { + get { return "SecT131Field"; } + } + + public override int FieldSize + { + get { return 131; } + } + + public override ECFieldElement Add(ECFieldElement b) + { + ulong[] z = Nat192.Create64(); + SecT131Field.Add(x, ((SecT131FieldElement)b).x, z); + return new SecT131FieldElement(z); + } + + public override ECFieldElement AddOne() + { + ulong[] z = Nat192.Create64(); + SecT131Field.AddOne(x, z); + return new SecT131FieldElement(z); + } + + public override ECFieldElement Subtract(ECFieldElement b) + { + // Addition and Subtraction are the same in F2m + return Add(b); + } + + public override ECFieldElement Multiply(ECFieldElement b) + { + ulong[] z = Nat192.Create64(); + SecT131Field.Multiply(x, ((SecT131FieldElement)b).x, z); + return new SecT131FieldElement(z); + } + + public override ECFieldElement MultiplyMinusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) + { + return MultiplyPlusProduct(b, x, y); + } + + public override ECFieldElement MultiplyPlusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) + { + ulong[] ax = this.x, bx = ((SecT131FieldElement)b).x; + ulong[] xx = ((SecT131FieldElement)x).x, yx = ((SecT131FieldElement)y).x; + + ulong[] tt = Nat.Create64(5); + SecT131Field.MultiplyAddToExt(ax, bx, tt); + SecT131Field.MultiplyAddToExt(xx, yx, tt); + + ulong[] z = Nat192.Create64(); + SecT131Field.Reduce(tt, z); + return new SecT131FieldElement(z); + } + + public override ECFieldElement Divide(ECFieldElement b) + { + return Multiply(b.Invert()); + } + + public override ECFieldElement Negate() + { + return this; + } + + public override ECFieldElement Square() + { + ulong[] z = Nat192.Create64(); + SecT131Field.Square(x, z); + return new SecT131FieldElement(z); + } + + public override ECFieldElement SquareMinusProduct(ECFieldElement x, ECFieldElement y) + { + return SquarePlusProduct(x, y); + } + + public override ECFieldElement SquarePlusProduct(ECFieldElement x, ECFieldElement y) + { + ulong[] ax = this.x; + ulong[] xx = ((SecT131FieldElement)x).x, yx = ((SecT131FieldElement)y).x; + + ulong[] tt = Nat.Create64(5); + SecT131Field.SquareAddToExt(ax, tt); + SecT131Field.MultiplyAddToExt(xx, yx, tt); + + ulong[] z = Nat192.Create64(); + SecT131Field.Reduce(tt, z); + return new SecT131FieldElement(z); + } + + public override ECFieldElement SquarePow(int pow) + { + if (pow < 1) + return this; + + ulong[] z = Nat192.Create64(); + SecT131Field.SquareN(x, pow, z); + return new SecT131FieldElement(z); + } + + public override ECFieldElement HalfTrace() + { + ulong[] z = Nat192.Create64(); + SecT131Field.HalfTrace(x, z); + return new SecT131FieldElement(z); + } + + public override bool HasFastTrace + { + get { return true; } + } + + public override int Trace() + { + return (int)SecT131Field.Trace(x); + } + + public override ECFieldElement Invert() + { + ulong[] z = Nat192.Create64(); + SecT131Field.Invert(x, z); + return new SecT131FieldElement(z); + } + + public override ECFieldElement Sqrt() + { + ulong[] z = Nat192.Create64(); + SecT131Field.Sqrt(x, z); + return new SecT131FieldElement(z); + } + + public virtual int Representation + { + get { return F2mFieldElement.Ppb; } + } + + public virtual int M + { + get { return 131; } + } + + public virtual int K1 + { + get { return 2; } + } + + public virtual int K2 + { + get { return 3; } + } + + public virtual int K3 + { + get { return 8; } + } + + public override bool Equals(object obj) + { + return Equals(obj as SecT131FieldElement); + } + + public override bool Equals(ECFieldElement other) + { + return Equals(other as SecT131FieldElement); + } + + public virtual bool Equals(SecT131FieldElement other) + { + if (this == other) + return true; + if (null == other) + return false; + return Nat192.Eq64(x, other.x); + } + + public override int GetHashCode() + { + return 131832 ^ Arrays.GetHashCode(x, 0, 3); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT131FieldElement.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT131FieldElement.cs.meta new file mode 100644 index 0000000..42ae280 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT131FieldElement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b78ca056399fb2544afaf82ce86706d2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT131R1Curve.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT131R1Curve.cs new file mode 100644 index 0000000..2b26369 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT131R1Curve.cs @@ -0,0 +1,177 @@ +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT131R1Curve + : AbstractF2mCurve + { + private const int SECT131R1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT131R1_FE_LONGS = 3; + private static readonly ECFieldElement[] SECT131R1_AFFINE_ZS = new ECFieldElement[] { new SecT131FieldElement(BigInteger.One) }; + + protected readonly SecT131R1Point m_infinity; + + public SecT131R1Curve() + : base(131, 2, 3, 8) + { + this.m_infinity = new SecT131R1Point(this, null, null); + + this.m_a = FromBigInteger(new BigInteger(1, Hex.DecodeStrict("07A11B09A76B562144418FF3FF8C2570B8"))); + this.m_b = FromBigInteger(new BigInteger(1, Hex.DecodeStrict("0217C05610884B63B9C6C7291678F9D341"))); + this.m_order = new BigInteger(1, Hex.DecodeStrict("0400000000000000023123953A9464B54D")); + this.m_cofactor = BigInteger.Two; + + this.m_coord = SECT131R1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecT131R1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_LAMBDA_PROJECTIVE: + return true; + default: + return false; + } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return 131; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecT131FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecT131R1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecT131R1Point(this, x, y, zs, withCompression); + } + + public override bool IsKoblitz + { + get { return false; } + } + + public virtual int M + { + get { return 131; } + } + + public virtual bool IsTrinomial + { + get { return false; } + } + + public virtual int K1 + { + get { return 2; } + } + + public virtual int K2 + { + get { return 3; } + } + + public virtual int K3 + { + get { return 8; } + } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + ulong[] table = new ulong[len * SECT131R1_FE_LONGS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat192.Copy64(((SecT131FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECT131R1_FE_LONGS; + Nat192.Copy64(((SecT131FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECT131R1_FE_LONGS; + } + } + + return new SecT131R1LookupTable(this, table, len); + } + + private class SecT131R1LookupTable + : AbstractECLookupTable + { + private readonly SecT131R1Curve m_outer; + private readonly ulong[] m_table; + private readonly int m_size; + + internal SecT131R1LookupTable(SecT131R1Curve outer, ulong[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public override int Size + { + get { return m_size; } + } + + public override ECPoint Lookup(int index) + { + ulong[] x = Nat192.Create64(), y = Nat192.Create64(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + ulong MASK = (ulong)(long)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECT131R1_FE_LONGS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECT131R1_FE_LONGS + j] & MASK; + } + + pos += (SECT131R1_FE_LONGS * 2); + } + + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + ulong[] x = Nat192.Create64(), y = Nat192.Create64(); + int pos = index * SECT131R1_FE_LONGS * 2; + + for (int j = 0; j < SECT131R1_FE_LONGS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECT131R1_FE_LONGS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(ulong[] x, ulong[] y) + { + return m_outer.CreateRawPoint(new SecT131FieldElement(x), new SecT131FieldElement(y), SECT131R1_AFFINE_ZS, false); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT131R1Curve.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT131R1Curve.cs.meta new file mode 100644 index 0000000..a87c2da --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT131R1Curve.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 975d68cdf4430934c88acf4f5ccf5a7d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT131R1Point.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT131R1Point.cs new file mode 100644 index 0000000..7aba4f2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT131R1Point.cs @@ -0,0 +1,287 @@ +using System; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT131R1Point + : AbstractF2mPoint + { + /** + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecT131R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * @deprecated per-point compression property will be removed, refer {@link #getEncoded(bool)} + */ + public SecT131R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecT131R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecT131R1Point(null, AffineXCoord, AffineYCoord); + } + + public override ECFieldElement YCoord + { + get + { + ECFieldElement X = RawXCoord, L = RawYCoord; + + if (this.IsInfinity || X.IsZero) + return L; + + // Y is actually Lambda (X + Y/X) here; convert to affine value on the fly + ECFieldElement Y = L.Add(X).Multiply(X); + + ECFieldElement Z = RawZCoords[0]; + if (!Z.IsOne) + { + Y = Y.Divide(Z); + } + + return Y; + } + } + + protected internal override bool CompressionYTilde + { + get + { + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return false; + + ECFieldElement Y = this.RawYCoord; + + // Y is actually Lambda (X + Y/X) here + return Y.TestBitZero() != X.TestBitZero(); + } + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + ECFieldElement X2 = b.RawXCoord; + + if (X1.IsZero) + { + if (X2.IsZero) + return curve.Infinity; + + return b.Add(this); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord, Z2 = b.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement U2 = X2, S2 = L2; + if (!Z1IsOne) + { + U2 = U2.Multiply(Z1); + S2 = S2.Multiply(Z1); + } + + bool Z2IsOne = Z2.IsOne; + ECFieldElement U1 = X1, S1 = L1; + if (!Z2IsOne) + { + U1 = U1.Multiply(Z2); + S1 = S1.Multiply(Z2); + } + + ECFieldElement A = S1.Add(S2); + ECFieldElement B = U1.Add(U2); + + if (B.IsZero) + { + if (A.IsZero) + return Twice(); + + return curve.Infinity; + } + + ECFieldElement X3, L3, Z3; + if (X2.IsZero) + { + // TODO This can probably be optimized quite a bit + ECPoint p = this.Normalize(); + X1 = p.XCoord; + ECFieldElement Y1 = p.YCoord; + + ECFieldElement Y2 = L2; + ECFieldElement L = Y1.Add(Y2).Divide(X1); + + X3 = L.Square().Add(L).Add(X1).Add(curve.A); + if (X3.IsZero) + { + return new SecT131R1Point(curve, X3, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement Y3 = L.Multiply(X1.Add(X3)).Add(X3).Add(Y1); + L3 = Y3.Divide(X3).Add(X3); + Z3 = curve.FromBigInteger(BigInteger.One); + } + else + { + B = B.Square(); + + ECFieldElement AU1 = A.Multiply(U1); + ECFieldElement AU2 = A.Multiply(U2); + + X3 = AU1.Multiply(AU2); + if (X3.IsZero) + { + return new SecT131R1Point(curve, X3, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement ABZ2 = A.Multiply(B); + if (!Z2IsOne) + { + ABZ2 = ABZ2.Multiply(Z2); + } + + L3 = AU2.Add(B).SquarePlusProduct(ABZ2, L1.Add(Z1)); + + Z3 = ABZ2; + if (!Z1IsOne) + { + Z3 = Z3.Multiply(Z1); + } + } + + return new SecT131R1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + { + return this; + } + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is its own additive inverse + return curve.Infinity; + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement L1Z1 = Z1IsOne ? L1 : L1.Multiply(Z1); + ECFieldElement Z1Sq = Z1IsOne ? Z1 : Z1.Square(); + ECFieldElement a = curve.A; + ECFieldElement aZ1Sq = Z1IsOne ? a : a.Multiply(Z1Sq); + ECFieldElement T = L1.Square().Add(L1Z1).Add(aZ1Sq); + if (T.IsZero) + { + return new SecT131R1Point(curve, T, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement X3 = T.Square(); + ECFieldElement Z3 = Z1IsOne ? T : T.Multiply(Z1Sq); + + ECFieldElement X1Z1 = Z1IsOne ? X1 : X1.Multiply(Z1); + ECFieldElement L3 = X1Z1.SquarePlusProduct(T, L1Z1).Add(X3).Add(Z3); + + return new SecT131R1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this.IsInfinity) + { + return b; + } + if (b.IsInfinity) + { + return Twice(); + } + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is its own additive inverse + return b; + } + + ECFieldElement X2 = b.RawXCoord, Z2 = b.RawZCoords[0]; + if (X2.IsZero || !Z2.IsOne) + { + return Twice().Add(b); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord; + + ECFieldElement X1Sq = X1.Square(); + ECFieldElement L1Sq = L1.Square(); + ECFieldElement Z1Sq = Z1.Square(); + ECFieldElement L1Z1 = L1.Multiply(Z1); + + ECFieldElement T = curve.A.Multiply(Z1Sq).Add(L1Sq).Add(L1Z1); + ECFieldElement L2plus1 = L2.AddOne(); + ECFieldElement A = curve.A.Add(L2plus1).Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); + ECFieldElement X2Z1Sq = X2.Multiply(Z1Sq); + ECFieldElement B = X2Z1Sq.Add(T).Square(); + + if (B.IsZero) + { + if (A.IsZero) + return b.Twice(); + + return curve.Infinity; + } + + if (A.IsZero) + { + return new SecT131R1Point(curve, A, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement X3 = A.Square().Multiply(X2Z1Sq); + ECFieldElement Z3 = A.Multiply(B).Multiply(Z1Sq); + ECFieldElement L3 = A.Add(B).Square().MultiplyPlusProduct(T, L2plus1, Z3); + + return new SecT131R1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Negate() + { + if (IsInfinity) + return this; + + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return this; + + // L is actually Lambda (X + Y/X) here + ECFieldElement L = this.RawYCoord, Z = this.RawZCoords[0]; + return new SecT131R1Point(Curve, X, L.Add(Z), new ECFieldElement[] { Z }, IsCompressed); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT131R1Point.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT131R1Point.cs.meta new file mode 100644 index 0000000..f436777 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT131R1Point.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6a45b28249d78bd4c8e1ba0751ec3b4b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT131R2Curve.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT131R2Curve.cs new file mode 100644 index 0000000..123362f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT131R2Curve.cs @@ -0,0 +1,177 @@ +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT131R2Curve + : AbstractF2mCurve + { + private const int SECT131R2_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT131R2_FE_LONGS = 3; + private static readonly ECFieldElement[] SECT131R2_AFFINE_ZS = new ECFieldElement[] { new SecT131FieldElement(BigInteger.One) }; + + protected readonly SecT131R2Point m_infinity; + + public SecT131R2Curve() + : base(131, 2, 3, 8) + { + this.m_infinity = new SecT131R2Point(this, null, null); + + this.m_a = FromBigInteger(new BigInteger(1, Hex.DecodeStrict("03E5A88919D7CAFCBF415F07C2176573B2"))); + this.m_b = FromBigInteger(new BigInteger(1, Hex.DecodeStrict("04B8266A46C55657AC734CE38F018F2192"))); + this.m_order = new BigInteger(1, Hex.DecodeStrict("0400000000000000016954A233049BA98F")); + this.m_cofactor = BigInteger.Two; + + this.m_coord = SECT131R2_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecT131R2Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_LAMBDA_PROJECTIVE: + return true; + default: + return false; + } + } + + public override int FieldSize + { + get { return 131; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecT131FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecT131R2Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecT131R2Point(this, x, y, zs, withCompression); + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override bool IsKoblitz + { + get { return false; } + } + + public virtual int M + { + get { return 131; } + } + + public virtual bool IsTrinomial + { + get { return false; } + } + + public virtual int K1 + { + get { return 2; } + } + + public virtual int K2 + { + get { return 3; } + } + + public virtual int K3 + { + get { return 8; } + } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + ulong[] table = new ulong[len * SECT131R2_FE_LONGS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat192.Copy64(((SecT131FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECT131R2_FE_LONGS; + Nat192.Copy64(((SecT131FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECT131R2_FE_LONGS; + } + } + + return new SecT131R2LookupTable(this, table, len); + } + + private class SecT131R2LookupTable + : AbstractECLookupTable + { + private readonly SecT131R2Curve m_outer; + private readonly ulong[] m_table; + private readonly int m_size; + + internal SecT131R2LookupTable(SecT131R2Curve outer, ulong[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public override int Size + { + get { return m_size; } + } + + public override ECPoint Lookup(int index) + { + ulong[] x = Nat192.Create64(), y = Nat192.Create64(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + ulong MASK = (ulong)(long)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECT131R2_FE_LONGS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECT131R2_FE_LONGS + j] & MASK; + } + + pos += (SECT131R2_FE_LONGS * 2); + } + + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + ulong[] x = Nat192.Create64(), y = Nat192.Create64(); + int pos = index * SECT131R2_FE_LONGS * 2; + + for (int j = 0; j < SECT131R2_FE_LONGS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECT131R2_FE_LONGS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(ulong[] x, ulong[] y) + { + return m_outer.CreateRawPoint(new SecT131FieldElement(x), new SecT131FieldElement(y), SECT131R2_AFFINE_ZS, false); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT131R2Curve.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT131R2Curve.cs.meta new file mode 100644 index 0000000..67d7ec7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT131R2Curve.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e9ad2c3c4fb367c4381d077736fcbdcf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT131R2Point.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT131R2Point.cs new file mode 100644 index 0000000..5d06049 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT131R2Point.cs @@ -0,0 +1,283 @@ +using System; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT131R2Point + : AbstractF2mPoint + { + /** + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecT131R2Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * @deprecated per-point compression property will be removed, refer {@link #getEncoded(bool)} + */ + public SecT131R2Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecT131R2Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecT131R2Point(null, AffineXCoord, AffineYCoord); + } + + public override ECFieldElement YCoord + { + get + { + ECFieldElement X = RawXCoord, L = RawYCoord; + + if (this.IsInfinity || X.IsZero) + return L; + + // Y is actually Lambda (X + Y/X) here; convert to affine value on the fly + ECFieldElement Y = L.Add(X).Multiply(X); + + ECFieldElement Z = RawZCoords[0]; + if (!Z.IsOne) + { + Y = Y.Divide(Z); + } + + return Y; + } + } + + protected internal override bool CompressionYTilde + { + get + { + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return false; + + ECFieldElement Y = this.RawYCoord; + + // Y is actually Lambda (X + Y/X) here + return Y.TestBitZero() != X.TestBitZero(); + } + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + ECFieldElement X2 = b.RawXCoord; + + if (X1.IsZero) + { + if (X2.IsZero) + return curve.Infinity; + + return b.Add(this); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord, Z2 = b.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement U2 = X2, S2 = L2; + if (!Z1IsOne) + { + U2 = U2.Multiply(Z1); + S2 = S2.Multiply(Z1); + } + + bool Z2IsOne = Z2.IsOne; + ECFieldElement U1 = X1, S1 = L1; + if (!Z2IsOne) + { + U1 = U1.Multiply(Z2); + S1 = S1.Multiply(Z2); + } + + ECFieldElement A = S1.Add(S2); + ECFieldElement B = U1.Add(U2); + + if (B.IsZero) + { + if (A.IsZero) + return Twice(); + + return curve.Infinity; + } + + ECFieldElement X3, L3, Z3; + if (X2.IsZero) + { + // TODO This can probably be optimized quite a bit + ECPoint p = this.Normalize(); + X1 = p.XCoord; + ECFieldElement Y1 = p.YCoord; + + ECFieldElement Y2 = L2; + ECFieldElement L = Y1.Add(Y2).Divide(X1); + + X3 = L.Square().Add(L).Add(X1).Add(curve.A); + if (X3.IsZero) + { + return new SecT131R2Point(curve, X3, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement Y3 = L.Multiply(X1.Add(X3)).Add(X3).Add(Y1); + L3 = Y3.Divide(X3).Add(X3); + Z3 = curve.FromBigInteger(BigInteger.One); + } + else + { + B = B.Square(); + + ECFieldElement AU1 = A.Multiply(U1); + ECFieldElement AU2 = A.Multiply(U2); + + X3 = AU1.Multiply(AU2); + if (X3.IsZero) + { + return new SecT131R2Point(curve, X3, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement ABZ2 = A.Multiply(B); + if (!Z2IsOne) + { + ABZ2 = ABZ2.Multiply(Z2); + } + + L3 = AU2.Add(B).SquarePlusProduct(ABZ2, L1.Add(Z1)); + + Z3 = ABZ2; + if (!Z1IsOne) + { + Z3 = Z3.Multiply(Z1); + } + } + + return new SecT131R2Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + { + return this; + } + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is its own additive inverse + return curve.Infinity; + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement L1Z1 = Z1IsOne ? L1 : L1.Multiply(Z1); + ECFieldElement Z1Sq = Z1IsOne ? Z1 : Z1.Square(); + ECFieldElement a = curve.A; + ECFieldElement aZ1Sq = Z1IsOne ? a : a.Multiply(Z1Sq); + ECFieldElement T = L1.Square().Add(L1Z1).Add(aZ1Sq); + if (T.IsZero) + { + return new SecT131R2Point(curve, T, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement X3 = T.Square(); + ECFieldElement Z3 = Z1IsOne ? T : T.Multiply(Z1Sq); + + ECFieldElement X1Z1 = Z1IsOne ? X1 : X1.Multiply(Z1); + ECFieldElement L3 = X1Z1.SquarePlusProduct(T, L1Z1).Add(X3).Add(Z3); + + return new SecT131R2Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is its own additive inverse + return b; + } + + ECFieldElement X2 = b.RawXCoord, Z2 = b.RawZCoords[0]; + if (X2.IsZero || !Z2.IsOne) + { + return Twice().Add(b); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord; + + ECFieldElement X1Sq = X1.Square(); + ECFieldElement L1Sq = L1.Square(); + ECFieldElement Z1Sq = Z1.Square(); + ECFieldElement L1Z1 = L1.Multiply(Z1); + + ECFieldElement T = curve.A.Multiply(Z1Sq).Add(L1Sq).Add(L1Z1); + ECFieldElement L2plus1 = L2.AddOne(); + ECFieldElement A = curve.A.Add(L2plus1).Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); + ECFieldElement X2Z1Sq = X2.Multiply(Z1Sq); + ECFieldElement B = X2Z1Sq.Add(T).Square(); + + if (B.IsZero) + { + if (A.IsZero) + return b.Twice(); + + return curve.Infinity; + } + + if (A.IsZero) + { + return new SecT131R2Point(curve, A, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement X3 = A.Square().Multiply(X2Z1Sq); + ECFieldElement Z3 = A.Multiply(B).Multiply(Z1Sq); + ECFieldElement L3 = A.Add(B).Square().MultiplyPlusProduct(T, L2plus1, Z3); + + return new SecT131R2Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Negate() + { + if (IsInfinity) + return this; + + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return this; + + // L is actually Lambda (X + Y/X) here + ECFieldElement L = this.RawYCoord, Z = this.RawZCoords[0]; + return new SecT131R2Point(Curve, X, L.Add(Z), new ECFieldElement[] { Z }, IsCompressed); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT131R2Point.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT131R2Point.cs.meta new file mode 100644 index 0000000..48f1c4c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT131R2Point.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bfa1ca549c190c441b34d4208035aab3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT163Field.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT163Field.cs new file mode 100644 index 0000000..79079ac --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT163Field.cs @@ -0,0 +1,355 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT163Field + { + private const ulong M35 = ulong.MaxValue >> 29; + private const ulong M55 = ulong.MaxValue >> 9; + + private static readonly ulong[] ROOT_Z = new ulong[]{ 0xB6DB6DB6DB6DB6B0UL, 0x492492492492DB6DUL, 0x492492492UL }; + + public static void Add(ulong[] x, ulong[] y, ulong[] z) + { + z[0] = x[0] ^ y[0]; + z[1] = x[1] ^ y[1]; + z[2] = x[2] ^ y[2]; + } + + public static void AddExt(ulong[] xx, ulong[] yy, ulong[] zz) + { + zz[0] = xx[0] ^ yy[0]; + zz[1] = xx[1] ^ yy[1]; + zz[2] = xx[2] ^ yy[2]; + zz[3] = xx[3] ^ yy[3]; + zz[4] = xx[4] ^ yy[4]; + zz[5] = xx[5] ^ yy[5]; + } + + public static void AddOne(ulong[] x, ulong[] z) + { + z[0] = x[0] ^ 1UL; + z[1] = x[1]; + z[2] = x[2]; + } + + private static void AddTo(ulong[] x, ulong[] z) + { + z[0] ^= x[0]; + z[1] ^= x[1]; + z[2] ^= x[2]; + } + + public static ulong[] FromBigInteger(BigInteger x) + { + return Nat.FromBigInteger64(163, x); + } + + public static void HalfTrace(ulong[] x, ulong[] z) + { + ulong[] tt = Nat192.CreateExt64(); + + Nat192.Copy64(x, z); + for (int i = 1; i < 163; i += 2) + { + ImplSquare(z, tt); + Reduce(tt, z); + ImplSquare(z, tt); + Reduce(tt, z); + AddTo(x, z); + } + } + + public static void Invert(ulong[] x, ulong[] z) + { + if (Nat192.IsZero64(x)) + throw new InvalidOperationException(); + + // Itoh-Tsujii inversion with bases { 2, 3 } + + ulong[] t0 = Nat192.Create64(); + ulong[] t1 = Nat192.Create64(); + + Square(x, t0); + + // 3 | 162 + SquareN(t0, 1, t1); + Multiply(t0, t1, t0); + SquareN(t1, 1, t1); + Multiply(t0, t1, t0); + + // 3 | 54 + SquareN(t0, 3, t1); + Multiply(t0, t1, t0); + SquareN(t1, 3, t1); + Multiply(t0, t1, t0); + + // 3 | 18 + SquareN(t0, 9, t1); + Multiply(t0, t1, t0); + SquareN(t1, 9, t1); + Multiply(t0, t1, t0); + + // 3 | 6 + SquareN(t0, 27, t1); + Multiply(t0, t1, t0); + SquareN(t1, 27, t1); + Multiply(t0, t1, t0); + + // 2 | 2 + SquareN(t0, 81, t1); + Multiply(t0, t1, z); + } + + public static void Multiply(ulong[] x, ulong[] y, ulong[] z) + { + ulong[] tt = new ulong[8]; + ImplMultiply(x, y, tt); + Reduce(tt, z); + } + + public static void MultiplyAddToExt(ulong[] x, ulong[] y, ulong[] zz) + { + ulong[] tt = new ulong[8]; + ImplMultiply(x, y, tt); + AddExt(zz, tt, zz); + } + + public static void Reduce(ulong[] xx, ulong[] z) + { + ulong x0 = xx[0], x1 = xx[1], x2 = xx[2], x3 = xx[3], x4 = xx[4], x5 = xx[5]; + + x2 ^= (x5 << 29) ^ (x5 << 32) ^ (x5 << 35) ^ (x5 << 36); + x3 ^= (x5 >> 35) ^ (x5 >> 32) ^ (x5 >> 29) ^ (x5 >> 28); + + x1 ^= (x4 << 29) ^ (x4 << 32) ^ (x4 << 35) ^ (x4 << 36); + x2 ^= (x4 >> 35) ^ (x4 >> 32) ^ (x4 >> 29) ^ (x4 >> 28); + + x0 ^= (x3 << 29) ^ (x3 << 32) ^ (x3 << 35) ^ (x3 << 36); + x1 ^= (x3 >> 35) ^ (x3 >> 32) ^ (x3 >> 29) ^ (x3 >> 28); + + ulong t = x2 >> 35; + z[0] = x0 ^ t ^ (t << 3) ^ (t << 6) ^ (t << 7); + z[1] = x1; + z[2] = x2 & M35; + } + + public static void Reduce29(ulong[] z, int zOff) + { + ulong z2 = z[zOff + 2], t = z2 >> 35; + z[zOff ] ^= t ^ (t << 3) ^ (t << 6) ^ (t << 7); + z[zOff + 2] = z2 & M35; + } + + public static void Sqrt(ulong[] x, ulong[] z) + { + ulong[] odd = Nat192.Create64(); + + ulong u0, u1; + u0 = Interleave.Unshuffle(x[0]); u1 = Interleave.Unshuffle(x[1]); + ulong e0 = (u0 & 0x00000000FFFFFFFFUL) | (u1 << 32); + odd[0] = (u0 >> 32) | (u1 & 0xFFFFFFFF00000000UL); + + u0 = Interleave.Unshuffle(x[2]); + ulong e1 = (u0 & 0x00000000FFFFFFFFUL); + odd[1] = (u0 >> 32); + + Multiply(odd, ROOT_Z, z); + + z[0] ^= e0; + z[1] ^= e1; + } + + public static void Square(ulong[] x, ulong[] z) + { + ulong[] tt = Nat192.CreateExt64(); + ImplSquare(x, tt); + Reduce(tt, z); + } + + public static void SquareAddToExt(ulong[] x, ulong[] zz) + { + ulong[] tt = Nat192.CreateExt64(); + ImplSquare(x, tt); + AddExt(zz, tt, zz); + } + + public static void SquareN(ulong[] x, int n, ulong[] z) + { + Debug.Assert(n > 0); + + ulong[] tt = Nat192.CreateExt64(); + ImplSquare(x, tt); + Reduce(tt, z); + + while (--n > 0) + { + ImplSquare(z, tt); + Reduce(tt, z); + } + } + + public static uint Trace(ulong[] x) + { + // Non-zero-trace bits: 0, 157 + return (uint)(x[0] ^ (x[2] >> 29)) & 1U; + } + + protected static void ImplCompactExt(ulong[] zz) + { + ulong z0 = zz[0], z1 = zz[1], z2 = zz[2], z3 = zz[3], z4 = zz[4], z5 = zz[5]; + zz[0] = z0 ^ (z1 << 55); + zz[1] = (z1 >> 9) ^ (z2 << 46); + zz[2] = (z2 >> 18) ^ (z3 << 37); + zz[3] = (z3 >> 27) ^ (z4 << 28); + zz[4] = (z4 >> 36) ^ (z5 << 19); + zz[5] = (z5 >> 45); + } + + protected static void ImplMultiply(ulong[] x, ulong[] y, ulong[] zz) + { + /* + * "Five-way recursion" as described in "Batch binary Edwards", Daniel J. Bernstein. + */ + + ulong f0 = x[0], f1 = x[1], f2 = x[2]; + f2 = ((f1 >> 46) ^ (f2 << 18)); + f1 = ((f0 >> 55) ^ (f1 << 9)) & M55; + f0 &= M55; + + ulong g0 = y[0], g1 = y[1], g2 = y[2]; + g2 = ((g1 >> 46) ^ (g2 << 18)); + g1 = ((g0 >> 55) ^ (g1 << 9)) & M55; + g0 &= M55; + + ulong[] u = zz; + ulong[] H = new ulong[10]; + + ImplMulw(u, f0, g0, H, 0); // H(0) 55/54 bits + ImplMulw(u, f2, g2, H, 2); // H(INF) 55/50 bits + + ulong t0 = f0 ^ f1 ^ f2; + ulong t1 = g0 ^ g1 ^ g2; + + ImplMulw(u, t0, t1, H, 4); // H(1) 55/54 bits + + ulong t2 = (f1 << 1) ^ (f2 << 2); + ulong t3 = (g1 << 1) ^ (g2 << 2); + + ImplMulw(u, f0 ^ t2, g0 ^ t3, H, 6); // H(t) 55/56 bits + ImplMulw(u, t0 ^ t2, t1 ^ t3, H, 8); // H(t + 1) 55/56 bits + + ulong t4 = H[6] ^ H[8]; + ulong t5 = H[7] ^ H[9]; + + Debug.Assert(t5 >> 55 == 0); + + // Calculate V + ulong v0 = (t4 << 1) ^ H[6]; + ulong v1 = t4 ^ (t5 << 1) ^ H[7]; + ulong v2 = t5; + + // Calculate U + ulong u0 = H[0]; + ulong u1 = H[1] ^ H[0] ^ H[4]; + ulong u2 = H[1] ^ H[5]; + + // Calculate W + ulong w0 = u0 ^ v0 ^ (H[2] << 4) ^ (H[2] << 1); + ulong w1 = u1 ^ v1 ^ (H[3] << 4) ^ (H[3] << 1); + ulong w2 = u2 ^ v2; + + // Propagate carries + w1 ^= (w0 >> 55); w0 &= M55; + w2 ^= (w1 >> 55); w1 &= M55; + + Debug.Assert((w0 & 1UL) == 0UL); + + // Divide W by t + + w0 = (w0 >> 1) ^ ((w1 & 1UL) << 54); + w1 = (w1 >> 1) ^ ((w2 & 1UL) << 54); + w2 = (w2 >> 1); + + // Divide W by (t + 1) + + w0 ^= (w0 << 1); + w0 ^= (w0 << 2); + w0 ^= (w0 << 4); + w0 ^= (w0 << 8); + w0 ^= (w0 << 16); + w0 ^= (w0 << 32); + + w0 &= M55; w1 ^= (w0 >> 54); + + w1 ^= (w1 << 1); + w1 ^= (w1 << 2); + w1 ^= (w1 << 4); + w1 ^= (w1 << 8); + w1 ^= (w1 << 16); + w1 ^= (w1 << 32); + + w1 &= M55; w2 ^= (w1 >> 54); + + w2 ^= (w2 << 1); + w2 ^= (w2 << 2); + w2 ^= (w2 << 4); + w2 ^= (w2 << 8); + w2 ^= (w2 << 16); + w2 ^= (w2 << 32); + + Debug.Assert(w2 >> 52 == 0); + + zz[0] = u0; + zz[1] = u1 ^ w0 ^ H[2]; + zz[2] = u2 ^ w1 ^ w0 ^ H[3]; + zz[3] = w2 ^ w1; + zz[4] = w2 ^ H[2]; + zz[5] = H[3]; + + ImplCompactExt(zz); + } + + protected static void ImplMulw(ulong[] u, ulong x, ulong y, ulong[] z, int zOff) + { + Debug.Assert(x >> 56 == 0); + Debug.Assert(y >> 56 == 0); + + //u[0] = 0; + u[1] = y; + u[2] = u[1] << 1; + u[3] = u[2] ^ y; + u[4] = u[2] << 1; + u[5] = u[4] ^ y; + u[6] = u[3] << 1; + u[7] = u[6] ^ y; + + uint j = (uint)x; + ulong g, h = 0, l = u[j & 3]; + int k = 47; + do + { + j = (uint)(x >> k); + g = u[j & 7] + ^ u[(j >> 3) & 7] << 3 + ^ u[(j >> 6) & 7] << 6; + l ^= (g << k); + h ^= (g >> -k); + } + while ((k -= 9) > 0); + + Debug.Assert(h >> 47 == 0); + + z[zOff ] = l & M55; + z[zOff + 1] = (l >> 55) ^ (h << 9); + } + + protected static void ImplSquare(ulong[] x, ulong[] zz) + { + Interleave.Expand64To128(x, 0, 3, zz, 0); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT163Field.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT163Field.cs.meta new file mode 100644 index 0000000..89a02c0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT163Field.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2c83017c94dd44a4a9be27e00b6c7056 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT163FieldElement.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT163FieldElement.cs new file mode 100644 index 0000000..214a563 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT163FieldElement.cs @@ -0,0 +1,233 @@ +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT163FieldElement + : AbstractF2mFieldElement + { + protected internal readonly ulong[] x; + + public SecT163FieldElement(BigInteger x) + { + if (x == null || x.SignValue < 0 || x.BitLength > 163) + throw new ArgumentException("value invalid for SecT163FieldElement", "x"); + + this.x = SecT163Field.FromBigInteger(x); + } + + public SecT163FieldElement() + { + this.x = Nat192.Create64(); + } + + protected internal SecT163FieldElement(ulong[] x) + { + this.x = x; + } + + public override bool IsOne + { + get { return Nat192.IsOne64(x); } + } + + public override bool IsZero + { + get { return Nat192.IsZero64(x); } + } + + public override bool TestBitZero() + { + return (x[0] & 1L) != 0L; + } + + public override BigInteger ToBigInteger() + { + return Nat192.ToBigInteger64(x); + } + + public override string FieldName + { + get { return "SecT163Field"; } + } + + public override int FieldSize + { + get { return 163; } + } + + public override ECFieldElement Add(ECFieldElement b) + { + ulong[] z = Nat192.Create64(); + SecT163Field.Add(x, ((SecT163FieldElement)b).x, z); + return new SecT163FieldElement(z); + } + + public override ECFieldElement AddOne() + { + ulong[] z = Nat192.Create64(); + SecT163Field.AddOne(x, z); + return new SecT163FieldElement(z); + } + + public override ECFieldElement Subtract(ECFieldElement b) + { + // Addition and subtraction are the same in F2m + return Add(b); + } + + public override ECFieldElement Multiply(ECFieldElement b) + { + ulong[] z = Nat192.Create64(); + SecT163Field.Multiply(x, ((SecT163FieldElement)b).x, z); + return new SecT163FieldElement(z); + } + + public override ECFieldElement MultiplyMinusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) + { + return MultiplyPlusProduct(b, x, y); + } + + public override ECFieldElement MultiplyPlusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) + { + ulong[] ax = this.x, bx = ((SecT163FieldElement)b).x; + ulong[] xx = ((SecT163FieldElement)x).x, yx = ((SecT163FieldElement)y).x; + + ulong[] tt = Nat192.CreateExt64(); + SecT163Field.MultiplyAddToExt(ax, bx, tt); + SecT163Field.MultiplyAddToExt(xx, yx, tt); + + ulong[] z = Nat192.Create64(); + SecT163Field.Reduce(tt, z); + return new SecT163FieldElement(z); + } + + public override ECFieldElement Divide(ECFieldElement b) + { + return Multiply(b.Invert()); + } + + public override ECFieldElement Negate() + { + return this; + } + + public override ECFieldElement Square() + { + ulong[] z = Nat192.Create64(); + SecT163Field.Square(x, z); + return new SecT163FieldElement(z); + } + + public override ECFieldElement SquareMinusProduct(ECFieldElement x, ECFieldElement y) + { + return SquarePlusProduct(x, y); + } + + public override ECFieldElement SquarePlusProduct(ECFieldElement x, ECFieldElement y) + { + ulong[] ax = this.x; + ulong[] xx = ((SecT163FieldElement)x).x, yx = ((SecT163FieldElement)y).x; + + ulong[] tt = Nat192.CreateExt64(); + SecT163Field.SquareAddToExt(ax, tt); + SecT163Field.MultiplyAddToExt(xx, yx, tt); + + ulong[] z = Nat192.Create64(); + SecT163Field.Reduce(tt, z); + return new SecT163FieldElement(z); + } + + public override ECFieldElement SquarePow(int pow) + { + if (pow < 1) + return this; + + ulong[] z = Nat192.Create64(); + SecT163Field.SquareN(x, pow, z); + return new SecT163FieldElement(z); + } + + public override ECFieldElement HalfTrace() + { + ulong[] z = Nat192.Create64(); + SecT163Field.HalfTrace(x, z); + return new SecT163FieldElement(z); + } + + public override bool HasFastTrace + { + get { return true; } + } + + public override int Trace() + { + return (int)SecT163Field.Trace(x); + } + + public override ECFieldElement Invert() + { + ulong[] z = Nat192.Create64(); + SecT163Field.Invert(x, z); + return new SecT163FieldElement(z); + } + + public override ECFieldElement Sqrt() + { + ulong[] z = Nat192.Create64(); + SecT163Field.Sqrt(x, z); + return new SecT163FieldElement(z); + } + + public virtual int Representation + { + get { return F2mFieldElement.Ppb; } + } + + public virtual int M + { + get { return 163; } + } + + public virtual int K1 + { + get { return 3; } + } + + public virtual int K2 + { + get { return 6; } + } + + public virtual int K3 + { + get { return 7; } + } + + public override bool Equals(object obj) + { + return Equals(obj as SecT163FieldElement); + } + + public override bool Equals(ECFieldElement other) + { + return Equals(other as SecT163FieldElement); + } + + public virtual bool Equals(SecT163FieldElement other) + { + if (this == other) + return true; + if (null == other) + return false; + return Nat192.Eq64(x, other.x); + } + + public override int GetHashCode() + { + return 163763 ^ Arrays.GetHashCode(x, 0, 3); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT163FieldElement.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT163FieldElement.cs.meta new file mode 100644 index 0000000..291ba12 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT163FieldElement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3395dbfa60863f54f91d21f7e6f735b4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT163K1Curve.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT163K1Curve.cs new file mode 100644 index 0000000..31c63a8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT163K1Curve.cs @@ -0,0 +1,183 @@ +using System; + +using Org.BouncyCastle.Math.EC.Multiplier; +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT163K1Curve + : AbstractF2mCurve + { + private const int SECT163K1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT163K1_FE_LONGS = 3; + private static readonly ECFieldElement[] SECT163K1_AFFINE_ZS = new ECFieldElement[] { new SecT163FieldElement(BigInteger.One) }; + + protected readonly SecT163K1Point m_infinity; + + public SecT163K1Curve() + : base(163, 3, 6, 7) + { + this.m_infinity = new SecT163K1Point(this, null, null); + + this.m_a = FromBigInteger(BigInteger.One); + this.m_b = this.m_a; + this.m_order = new BigInteger(1, Hex.DecodeStrict("04000000000000000000020108A2E0CC0D99F8A5EF")); + this.m_cofactor = BigInteger.Two; + + this.m_coord = SECT163K1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecT163K1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_LAMBDA_PROJECTIVE: + return true; + default: + return false; + } + } + + protected override ECMultiplier CreateDefaultMultiplier() + { + return new WTauNafMultiplier(); + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return 163; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecT163FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecT163K1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecT163K1Point(this, x, y, zs, withCompression); + } + + public override bool IsKoblitz + { + get { return true; } + } + + public virtual int M + { + get { return 163; } + } + + public virtual bool IsTrinomial + { + get { return false; } + } + + public virtual int K1 + { + get { return 3; } + } + + public virtual int K2 + { + get { return 6; } + } + + public virtual int K3 + { + get { return 7; } + } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + ulong[] table = new ulong[len * SECT163K1_FE_LONGS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat192.Copy64(((SecT163FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECT163K1_FE_LONGS; + Nat192.Copy64(((SecT163FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECT163K1_FE_LONGS; + } + } + + return new SecT163K1LookupTable(this, table, len); + } + + private class SecT163K1LookupTable + : AbstractECLookupTable + { + private readonly SecT163K1Curve m_outer; + private readonly ulong[] m_table; + private readonly int m_size; + + internal SecT163K1LookupTable(SecT163K1Curve outer, ulong[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public override int Size + { + get { return m_size; } + } + + public override ECPoint Lookup(int index) + { + ulong[] x = Nat192.Create64(), y = Nat192.Create64(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + ulong MASK = (ulong)(long)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECT163K1_FE_LONGS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECT163K1_FE_LONGS + j] & MASK; + } + + pos += (SECT163K1_FE_LONGS * 2); + } + + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + ulong[] x = Nat192.Create64(), y = Nat192.Create64(); + int pos = index * SECT163K1_FE_LONGS * 2; + + for (int j = 0; j < SECT163K1_FE_LONGS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECT163K1_FE_LONGS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(ulong[] x, ulong[] y) + { + return m_outer.CreateRawPoint(new SecT163FieldElement(x), new SecT163FieldElement(y), SECT163K1_AFFINE_ZS, false); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT163K1Curve.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT163K1Curve.cs.meta new file mode 100644 index 0000000..2dbefc3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT163K1Curve.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 201c2b4a4cd84e644910489841c5a1e4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT163K1Point.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT163K1Point.cs new file mode 100644 index 0000000..66e657c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT163K1Point.cs @@ -0,0 +1,281 @@ +using System; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT163K1Point + : AbstractF2mPoint + { + /** + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecT163K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * @deprecated per-point compression property will be removed, refer {@link #getEncoded(bool)} + */ + public SecT163K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecT163K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecT163K1Point(null, this.AffineXCoord, this.AffineYCoord); + } + + public override ECFieldElement YCoord + { + get + { + ECFieldElement X = RawXCoord, L = RawYCoord; + + if (this.IsInfinity || X.IsZero) + return L; + + // Y is actually Lambda (X + Y/X) here; convert to affine value on the fly + ECFieldElement Y = L.Add(X).Multiply(X); + + ECFieldElement Z = RawZCoords[0]; + if (!Z.IsOne) + { + Y = Y.Divide(Z); + } + + return Y; + } + } + + protected internal override bool CompressionYTilde + { + get + { + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return false; + + ECFieldElement Y = this.RawYCoord; + + // Y is actually Lambda (X + Y/X) here + return Y.TestBitZero() != X.TestBitZero(); + } + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + ECFieldElement X2 = b.RawXCoord; + + if (X1.IsZero) + { + if (X2.IsZero) + return curve.Infinity; + + return b.Add(this); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord, Z2 = b.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement U2 = X2, S2 = L2; + if (!Z1IsOne) + { + U2 = U2.Multiply(Z1); + S2 = S2.Multiply(Z1); + } + + bool Z2IsOne = Z2.IsOne; + ECFieldElement U1 = X1, S1 = L1; + if (!Z2IsOne) + { + U1 = U1.Multiply(Z2); + S1 = S1.Multiply(Z2); + } + + ECFieldElement A = S1.Add(S2); + ECFieldElement B = U1.Add(U2); + + if (B.IsZero) + { + if (A.IsZero) + return Twice(); + + return curve.Infinity; + } + + ECFieldElement X3, L3, Z3; + if (X2.IsZero) + { + // TODO This can probably be optimized quite a bit + ECPoint p = this.Normalize(); + X1 = p.XCoord; + ECFieldElement Y1 = p.YCoord; + + ECFieldElement Y2 = L2; + ECFieldElement L = Y1.Add(Y2).Divide(X1); + + X3 = L.Square().Add(L).Add(X1).AddOne(); + if (X3.IsZero) + { + return new SecT163K1Point(curve, X3, curve.B, IsCompressed); + } + + ECFieldElement Y3 = L.Multiply(X1.Add(X3)).Add(X3).Add(Y1); + L3 = Y3.Divide(X3).Add(X3); + Z3 = curve.FromBigInteger(BigInteger.One); + } + else + { + B = B.Square(); + + ECFieldElement AU1 = A.Multiply(U1); + ECFieldElement AU2 = A.Multiply(U2); + + X3 = AU1.Multiply(AU2); + if (X3.IsZero) + { + return new SecT163K1Point(curve, X3, curve.B, IsCompressed); + } + + ECFieldElement ABZ2 = A.Multiply(B); + if (!Z2IsOne) + { + ABZ2 = ABZ2.Multiply(Z2); + } + + L3 = AU2.Add(B).SquarePlusProduct(ABZ2, L1.Add(Z1)); + + Z3 = ABZ2; + if (!Z1IsOne) + { + Z3 = Z3.Multiply(Z1); + } + } + + return new SecT163K1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + { + return this; + } + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is its own additive inverse + return curve.Infinity; + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement L1Z1 = Z1IsOne ? L1 : L1.Multiply(Z1); + ECFieldElement Z1Sq = Z1IsOne ? Z1 : Z1.Square(); + ECFieldElement T = L1.Square().Add(L1Z1).Add(Z1Sq); + if (T.IsZero) + { + return new SecT163K1Point(curve, T, curve.B, IsCompressed); + } + + ECFieldElement X3 = T.Square(); + ECFieldElement Z3 = Z1IsOne ? T : T.Multiply(Z1Sq); + + ECFieldElement t1 = L1.Add(X1).Square(); + ECFieldElement L3 = t1.Add(T).Add(Z1Sq).Multiply(t1).Add(X3); + + return new SecT163K1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is its own additive inverse + return b; + } + + // NOTE: TwicePlus() only optimized for lambda-affine argument + ECFieldElement X2 = b.RawXCoord, Z2 = b.RawZCoords[0]; + if (X2.IsZero || !Z2.IsOne) + { + return Twice().Add(b); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord; + + ECFieldElement X1Sq = X1.Square(); + ECFieldElement L1Sq = L1.Square(); + ECFieldElement Z1Sq = Z1.Square(); + ECFieldElement L1Z1 = L1.Multiply(Z1); + + ECFieldElement T = Z1Sq.Add(L1Sq).Add(L1Z1); + ECFieldElement A = L2.Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); + ECFieldElement X2Z1Sq = X2.Multiply(Z1Sq); + ECFieldElement B = X2Z1Sq.Add(T).Square(); + + if (B.IsZero) + { + if (A.IsZero) + return b.Twice(); + + return curve.Infinity; + } + + if (A.IsZero) + { + return new SecT163K1Point(curve, A, curve.B, IsCompressed); + } + + ECFieldElement X3 = A.Square().Multiply(X2Z1Sq); + ECFieldElement Z3 = A.Multiply(B).Multiply(Z1Sq); + ECFieldElement L3 = A.Add(B).Square().MultiplyPlusProduct(T, L2.AddOne(), Z3); + + return new SecT163K1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Negate() + { + if (this.IsInfinity) + return this; + + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return this; + + // L is actually Lambda (X + Y/X) here + ECFieldElement L = this.RawYCoord, Z = this.RawZCoords[0]; + return new SecT163K1Point(Curve, X, L.Add(Z), new ECFieldElement[] { Z }, IsCompressed); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT163K1Point.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT163K1Point.cs.meta new file mode 100644 index 0000000..4accc76 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT163K1Point.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 640503d25e172dc4d962eb6590e557cb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT163R1Curve.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT163R1Curve.cs new file mode 100644 index 0000000..61c452e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT163R1Curve.cs @@ -0,0 +1,177 @@ +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT163R1Curve + : AbstractF2mCurve + { + private const int SECT163R1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT163R1_FE_LONGS = 3; + private static readonly ECFieldElement[] SECT163R1_AFFINE_ZS = new ECFieldElement[] { new SecT163FieldElement(BigInteger.One) }; + + protected readonly SecT163R1Point m_infinity; + + public SecT163R1Curve() + : base(163, 3, 6, 7) + { + this.m_infinity = new SecT163R1Point(this, null, null); + + this.m_a = FromBigInteger(new BigInteger(1, Hex.DecodeStrict("07B6882CAAEFA84F9554FF8428BD88E246D2782AE2"))); + this.m_b = FromBigInteger(new BigInteger(1, Hex.DecodeStrict("0713612DCDDCB40AAB946BDA29CA91F73AF958AFD9"))); + this.m_order = new BigInteger(1, Hex.DecodeStrict("03FFFFFFFFFFFFFFFFFFFF48AAB689C29CA710279B")); + this.m_cofactor = BigInteger.Two; + + this.m_coord = SECT163R1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecT163R1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_LAMBDA_PROJECTIVE: + return true; + default: + return false; + } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return 163; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecT163FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecT163R1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecT163R1Point(this, x, y, zs, withCompression); + } + + public override bool IsKoblitz + { + get { return false; } + } + + public virtual int M + { + get { return 163; } + } + + public virtual bool IsTrinomial + { + get { return false; } + } + + public virtual int K1 + { + get { return 3; } + } + + public virtual int K2 + { + get { return 6; } + } + + public virtual int K3 + { + get { return 7; } + } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + ulong[] table = new ulong[len * SECT163R1_FE_LONGS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat192.Copy64(((SecT163FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECT163R1_FE_LONGS; + Nat192.Copy64(((SecT163FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECT163R1_FE_LONGS; + } + } + + return new SecT163R1LookupTable(this, table, len); + } + + private class SecT163R1LookupTable + : AbstractECLookupTable + { + private readonly SecT163R1Curve m_outer; + private readonly ulong[] m_table; + private readonly int m_size; + + internal SecT163R1LookupTable(SecT163R1Curve outer, ulong[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public override int Size + { + get { return m_size; } + } + + public override ECPoint Lookup(int index) + { + ulong[] x = Nat192.Create64(), y = Nat192.Create64(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + ulong MASK = (ulong)(long)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECT163R1_FE_LONGS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECT163R1_FE_LONGS + j] & MASK; + } + + pos += (SECT163R1_FE_LONGS * 2); + } + + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + ulong[] x = Nat192.Create64(), y = Nat192.Create64(); + int pos = index * SECT163R1_FE_LONGS * 2; + + for (int j = 0; j < SECT163R1_FE_LONGS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECT163R1_FE_LONGS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(ulong[] x, ulong[] y) + { + return m_outer.CreateRawPoint(new SecT163FieldElement(x), new SecT163FieldElement(y), SECT163R1_AFFINE_ZS, false); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT163R1Curve.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT163R1Curve.cs.meta new file mode 100644 index 0000000..b4918a8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT163R1Curve.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8eb2e0006b003be4e82d180938c448f4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT163R1Point.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT163R1Point.cs new file mode 100644 index 0000000..bab1f35 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT163R1Point.cs @@ -0,0 +1,283 @@ +using System; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT163R1Point + : AbstractF2mPoint + { + /** + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecT163R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * @deprecated per-point compression property will be removed, refer {@link #getEncoded(bool)} + */ + public SecT163R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecT163R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecT163R1Point(null, AffineXCoord, AffineYCoord); + } + + public override ECFieldElement YCoord + { + get + { + ECFieldElement X = RawXCoord, L = RawYCoord; + + if (this.IsInfinity || X.IsZero) + return L; + + // Y is actually Lambda (X + Y/X) here; convert to affine value on the fly + ECFieldElement Y = L.Add(X).Multiply(X); + + ECFieldElement Z = RawZCoords[0]; + if (!Z.IsOne) + { + Y = Y.Divide(Z); + } + + return Y; + } + } + + protected internal override bool CompressionYTilde + { + get + { + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return false; + + ECFieldElement Y = this.RawYCoord; + + // Y is actually Lambda (X + Y/X) here + return Y.TestBitZero() != X.TestBitZero(); + } + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + ECFieldElement X2 = b.RawXCoord; + + if (X1.IsZero) + { + if (X2.IsZero) + return curve.Infinity; + + return b.Add(this); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord, Z2 = b.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement U2 = X2, S2 = L2; + if (!Z1IsOne) + { + U2 = U2.Multiply(Z1); + S2 = S2.Multiply(Z1); + } + + bool Z2IsOne = Z2.IsOne; + ECFieldElement U1 = X1, S1 = L1; + if (!Z2IsOne) + { + U1 = U1.Multiply(Z2); + S1 = S1.Multiply(Z2); + } + + ECFieldElement A = S1.Add(S2); + ECFieldElement B = U1.Add(U2); + + if (B.IsZero) + { + if (A.IsZero) + return Twice(); + + return curve.Infinity; + } + + ECFieldElement X3, L3, Z3; + if (X2.IsZero) + { + // TODO This can probably be optimized quite a bit + ECPoint p = this.Normalize(); + X1 = p.XCoord; + ECFieldElement Y1 = p.YCoord; + + ECFieldElement Y2 = L2; + ECFieldElement L = Y1.Add(Y2).Divide(X1); + + X3 = L.Square().Add(L).Add(X1).Add(curve.A); + if (X3.IsZero) + { + return new SecT163R1Point(curve, X3, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement Y3 = L.Multiply(X1.Add(X3)).Add(X3).Add(Y1); + L3 = Y3.Divide(X3).Add(X3); + Z3 = curve.FromBigInteger(BigInteger.One); + } + else + { + B = B.Square(); + + ECFieldElement AU1 = A.Multiply(U1); + ECFieldElement AU2 = A.Multiply(U2); + + X3 = AU1.Multiply(AU2); + if (X3.IsZero) + { + return new SecT163R1Point(curve, X3, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement ABZ2 = A.Multiply(B); + if (!Z2IsOne) + { + ABZ2 = ABZ2.Multiply(Z2); + } + + L3 = AU2.Add(B).SquarePlusProduct(ABZ2, L1.Add(Z1)); + + Z3 = ABZ2; + if (!Z1IsOne) + { + Z3 = Z3.Multiply(Z1); + } + } + + return new SecT163R1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + { + return this; + } + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is its own additive inverse + return curve.Infinity; + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement L1Z1 = Z1IsOne ? L1 : L1.Multiply(Z1); + ECFieldElement Z1Sq = Z1IsOne ? Z1 : Z1.Square(); + ECFieldElement a = curve.A; + ECFieldElement aZ1Sq = Z1IsOne ? a : a.Multiply(Z1Sq); + ECFieldElement T = L1.Square().Add(L1Z1).Add(aZ1Sq); + if (T.IsZero) + { + return new SecT163R1Point(curve, T, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement X3 = T.Square(); + ECFieldElement Z3 = Z1IsOne ? T : T.Multiply(Z1Sq); + + ECFieldElement X1Z1 = Z1IsOne ? X1 : X1.Multiply(Z1); + ECFieldElement L3 = X1Z1.SquarePlusProduct(T, L1Z1).Add(X3).Add(Z3); + + return new SecT163R1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is its own additive inverse + return b; + } + + ECFieldElement X2 = b.RawXCoord, Z2 = b.RawZCoords[0]; + if (X2.IsZero || !Z2.IsOne) + { + return Twice().Add(b); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord; + + ECFieldElement X1Sq = X1.Square(); + ECFieldElement L1Sq = L1.Square(); + ECFieldElement Z1Sq = Z1.Square(); + ECFieldElement L1Z1 = L1.Multiply(Z1); + + ECFieldElement T = curve.A.Multiply(Z1Sq).Add(L1Sq).Add(L1Z1); + ECFieldElement L2plus1 = L2.AddOne(); + ECFieldElement A = curve.A.Add(L2plus1).Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); + ECFieldElement X2Z1Sq = X2.Multiply(Z1Sq); + ECFieldElement B = X2Z1Sq.Add(T).Square(); + + if (B.IsZero) + { + if (A.IsZero) + return b.Twice(); + + return curve.Infinity; + } + + if (A.IsZero) + { + return new SecT163R1Point(curve, A, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement X3 = A.Square().Multiply(X2Z1Sq); + ECFieldElement Z3 = A.Multiply(B).Multiply(Z1Sq); + ECFieldElement L3 = A.Add(B).Square().MultiplyPlusProduct(T, L2plus1, Z3); + + return new SecT163R1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Negate() + { + if (this.IsInfinity) + return this; + + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return this; + + // L is actually Lambda (X + Y/X) here + ECFieldElement L = this.RawYCoord, Z = this.RawZCoords[0]; + return new SecT163R1Point(Curve, X, L.Add(Z), new ECFieldElement[] { Z }, IsCompressed); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT163R1Point.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT163R1Point.cs.meta new file mode 100644 index 0000000..0768f4e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT163R1Point.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3d88f0584d8a7a84588e69b339687eb4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT163R2Curve.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT163R2Curve.cs new file mode 100644 index 0000000..c610b57 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT163R2Curve.cs @@ -0,0 +1,177 @@ +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT163R2Curve + : AbstractF2mCurve + { + private const int SECT163R2_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT163R2_FE_LONGS = 3; + private static readonly ECFieldElement[] SECT163R2_AFFINE_ZS = new ECFieldElement[] { new SecT163FieldElement(BigInteger.One) }; + + protected readonly SecT163R2Point m_infinity; + + public SecT163R2Curve() + : base(163, 3, 6, 7) + { + this.m_infinity = new SecT163R2Point(this, null, null); + + this.m_a = FromBigInteger(BigInteger.One); + this.m_b = FromBigInteger(new BigInteger(1, Hex.DecodeStrict("020A601907B8C953CA1481EB10512F78744A3205FD"))); + this.m_order = new BigInteger(1, Hex.DecodeStrict("040000000000000000000292FE77E70C12A4234C33")); + this.m_cofactor = BigInteger.Two; + + this.m_coord = SECT163R2_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecT163R2Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_LAMBDA_PROJECTIVE: + return true; + default: + return false; + } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return 163; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecT163FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecT163R2Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecT163R2Point(this, x, y, zs, withCompression); + } + + public override bool IsKoblitz + { + get { return false; } + } + + public virtual int M + { + get { return 163; } + } + + public virtual bool IsTrinomial + { + get { return false; } + } + + public virtual int K1 + { + get { return 3; } + } + + public virtual int K2 + { + get { return 6; } + } + + public virtual int K3 + { + get { return 7; } + } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + ulong[] table = new ulong[len * SECT163R2_FE_LONGS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat192.Copy64(((SecT163FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECT163R2_FE_LONGS; + Nat192.Copy64(((SecT163FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECT163R2_FE_LONGS; + } + } + + return new SecT163R2LookupTable(this, table, len); + } + + private class SecT163R2LookupTable + : AbstractECLookupTable + { + private readonly SecT163R2Curve m_outer; + private readonly ulong[] m_table; + private readonly int m_size; + + internal SecT163R2LookupTable(SecT163R2Curve outer, ulong[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public override int Size + { + get { return m_size; } + } + + public override ECPoint Lookup(int index) + { + ulong[] x = Nat192.Create64(), y = Nat192.Create64(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + ulong MASK = (ulong)(long)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECT163R2_FE_LONGS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECT163R2_FE_LONGS + j] & MASK; + } + + pos += (SECT163R2_FE_LONGS * 2); + } + + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + ulong[] x = Nat192.Create64(), y = Nat192.Create64(); + int pos = index * SECT163R2_FE_LONGS * 2; + + for (int j = 0; j < SECT163R2_FE_LONGS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECT163R2_FE_LONGS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(ulong[] x, ulong[] y) + { + return m_outer.CreateRawPoint(new SecT163FieldElement(x), new SecT163FieldElement(y), SECT163R2_AFFINE_ZS, false); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT163R2Curve.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT163R2Curve.cs.meta new file mode 100644 index 0000000..b6a2ec2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT163R2Curve.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cffcd6c4f6956574fac5833a757f5173 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT163R2Point.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT163R2Point.cs new file mode 100644 index 0000000..a207e6f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT163R2Point.cs @@ -0,0 +1,286 @@ +using System; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT163R2Point + : AbstractF2mPoint + { + /** + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecT163R2Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * @deprecated per-point compression property will be removed, refer {@link #getEncoded(bool)} + */ + public SecT163R2Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecT163R2Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecT163R2Point(null, AffineXCoord, AffineYCoord); + } + + public override ECFieldElement YCoord + { + get + { + ECFieldElement X = RawXCoord, L = RawYCoord; + + if (this.IsInfinity || X.IsZero) + return L; + + // Y is actually Lambda (X + Y/X) here; convert to affine value on the fly + ECFieldElement Y = L.Add(X).Multiply(X); + + ECFieldElement Z = RawZCoords[0]; + if (!Z.IsOne) + { + Y = Y.Divide(Z); + } + + return Y; + } + } + + protected internal override bool CompressionYTilde + { + get + { + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return false; + + ECFieldElement Y = this.RawYCoord; + + // Y is actually Lambda (X + Y/X) here + return Y.TestBitZero() != X.TestBitZero(); + } + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + ECFieldElement X2 = b.RawXCoord; + + if (X1.IsZero) + { + if (X2.IsZero) + return curve.Infinity; + + return b.Add(this); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord, Z2 = b.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement U2 = X2, S2 = L2; + if (!Z1IsOne) + { + U2 = U2.Multiply(Z1); + S2 = S2.Multiply(Z1); + } + + bool Z2IsOne = Z2.IsOne; + ECFieldElement U1 = X1, S1 = L1; + if (!Z2IsOne) + { + U1 = U1.Multiply(Z2); + S1 = S1.Multiply(Z2); + } + + ECFieldElement A = S1.Add(S2); + ECFieldElement B = U1.Add(U2); + + if (B.IsZero) + { + if (A.IsZero) + { + return Twice(); + } + + return curve.Infinity; + } + + ECFieldElement X3, L3, Z3; + if (X2.IsZero) + { + // TODO This can probably be optimized quite a bit + ECPoint p = this.Normalize(); + X1 = p.XCoord; + ECFieldElement Y1 = p.YCoord; + + ECFieldElement Y2 = L2; + ECFieldElement L = Y1.Add(Y2).Divide(X1); + + X3 = L.Square().Add(L).Add(X1).AddOne(); + if (X3.IsZero) + { + return new SecT163R2Point(curve, X3, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement Y3 = L.Multiply(X1.Add(X3)).Add(X3).Add(Y1); + L3 = Y3.Divide(X3).Add(X3); + Z3 = curve.FromBigInteger(BigInteger.One); + } + else + { + B = B.Square(); + + ECFieldElement AU1 = A.Multiply(U1); + ECFieldElement AU2 = A.Multiply(U2); + + X3 = AU1.Multiply(AU2); + if (X3.IsZero) + { + return new SecT163R2Point(curve, X3, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement ABZ2 = A.Multiply(B); + if (!Z2IsOne) + { + ABZ2 = ABZ2.Multiply(Z2); + } + + L3 = AU2.Add(B).SquarePlusProduct(ABZ2, L1.Add(Z1)); + + Z3 = ABZ2; + if (!Z1IsOne) + { + Z3 = Z3.Multiply(Z1); + } + } + + return new SecT163R2Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + { + return this; + } + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is its own additive inverse + return curve.Infinity; + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement L1Z1 = Z1IsOne ? L1 : L1.Multiply(Z1); + ECFieldElement Z1Sq = Z1IsOne ? Z1 : Z1.Square(); + ECFieldElement T = L1.Square().Add(L1Z1).Add(Z1Sq); + if (T.IsZero) + { + return new SecT163R2Point(curve, T, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement X3 = T.Square(); + ECFieldElement Z3 = Z1IsOne ? T : T.Multiply(Z1Sq); + + ECFieldElement X1Z1 = Z1IsOne ? X1 : X1.Multiply(Z1); + ECFieldElement L3 = X1Z1.SquarePlusProduct(T, L1Z1).Add(X3).Add(Z3); + + return new SecT163R2Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this.IsInfinity) + { + return b; + } + if (b.IsInfinity) + { + return Twice(); + } + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is its own additive inverse + return b; + } + + ECFieldElement X2 = b.RawXCoord, Z2 = b.RawZCoords[0]; + if (X2.IsZero || !Z2.IsOne) + { + return Twice().Add(b); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord; + + ECFieldElement X1Sq = X1.Square(); + ECFieldElement L1Sq = L1.Square(); + ECFieldElement Z1Sq = Z1.Square(); + ECFieldElement L1Z1 = L1.Multiply(Z1); + + ECFieldElement T = Z1Sq.Add(L1Sq).Add(L1Z1); + ECFieldElement A = L2.Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); + ECFieldElement X2Z1Sq = X2.Multiply(Z1Sq); + ECFieldElement B = X2Z1Sq.Add(T).Square(); + + if (B.IsZero) + { + if (A.IsZero) + return b.Twice(); + + return curve.Infinity; + } + + if (A.IsZero) + { + return new SecT163R2Point(curve, A, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement X3 = A.Square().Multiply(X2Z1Sq); + ECFieldElement Z3 = A.Multiply(B).Multiply(Z1Sq); + ECFieldElement L3 = A.Add(B).Square().MultiplyPlusProduct(T, L2.AddOne(), Z3); + + return new SecT163R2Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Negate() + { + if (this.IsInfinity) + return this; + + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return this; + + // L is actually Lambda (X + Y/X) here + ECFieldElement L = this.RawYCoord, Z = this.RawZCoords[0]; + return new SecT163R2Point(Curve, X, L.Add(Z), new ECFieldElement[] { Z }, IsCompressed); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT163R2Point.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT163R2Point.cs.meta new file mode 100644 index 0000000..b156ff0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT163R2Point.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 71e3f99da9b6cf94db2c291ee731d942 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT193Field.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT193Field.cs new file mode 100644 index 0000000..1a4739b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT193Field.cs @@ -0,0 +1,325 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT193Field + { + private const ulong M01 = 1UL; + private const ulong M49 = ulong.MaxValue >> 15; + + public static void Add(ulong[] x, ulong[] y, ulong[] z) + { + z[0] = x[0] ^ y[0]; + z[1] = x[1] ^ y[1]; + z[2] = x[2] ^ y[2]; + z[3] = x[3] ^ y[3]; + } + + public static void AddExt(ulong[] xx, ulong[] yy, ulong[] zz) + { + zz[0] = xx[0] ^ yy[0]; + zz[1] = xx[1] ^ yy[1]; + zz[2] = xx[2] ^ yy[2]; + zz[3] = xx[3] ^ yy[3]; + zz[4] = xx[4] ^ yy[4]; + zz[5] = xx[5] ^ yy[5]; + zz[6] = xx[6] ^ yy[6]; + } + + public static void AddOne(ulong[] x, ulong[] z) + { + z[0] = x[0] ^ 1UL; + z[1] = x[1]; + z[2] = x[2]; + z[3] = x[3]; + } + + private static void AddTo(ulong[] x, ulong[] z) + { + z[0] ^= x[0]; + z[1] ^= x[1]; + z[2] ^= x[2]; + z[3] ^= x[3]; + } + + public static ulong[] FromBigInteger(BigInteger x) + { + return Nat.FromBigInteger64(193, x); + } + + public static void HalfTrace(ulong[] x, ulong[] z) + { + ulong[] tt = Nat256.CreateExt64(); + + Nat256.Copy64(x, z); + for (int i = 1; i < 193; i += 2) + { + ImplSquare(z, tt); + Reduce(tt, z); + ImplSquare(z, tt); + Reduce(tt, z); + AddTo(x, z); + } + } + + public static void Invert(ulong[] x, ulong[] z) + { + if (Nat256.IsZero64(x)) + throw new InvalidOperationException(); + + // Itoh-Tsujii inversion with bases { 2, 3 } + + ulong[] t0 = Nat256.Create64(); + ulong[] t1 = Nat256.Create64(); + + Square(x, t0); + + // 3 | 192 + SquareN(t0, 1, t1); + Multiply(t0, t1, t0); + SquareN(t1, 1, t1); + Multiply(t0, t1, t0); + + // 2 | 64 + SquareN(t0, 3, t1); + Multiply(t0, t1, t0); + + // 2 | 32 + SquareN(t0, 6, t1); + Multiply(t0, t1, t0); + + // 2 | 16 + SquareN(t0, 12, t1); + Multiply(t0, t1, t0); + + // 2 | 8 + SquareN(t0, 24, t1); + Multiply(t0, t1, t0); + + // 2 | 4 + SquareN(t0, 48, t1); + Multiply(t0, t1, t0); + + // 2 | 2 + SquareN(t0, 96, t1); + Multiply(t0, t1, z); + } + + public static void Multiply(ulong[] x, ulong[] y, ulong[] z) + { + ulong[] tt = Nat256.CreateExt64(); + ImplMultiply(x, y, tt); + Reduce(tt, z); + } + + public static void MultiplyAddToExt(ulong[] x, ulong[] y, ulong[] zz) + { + ulong[] tt = Nat256.CreateExt64(); + ImplMultiply(x, y, tt); + AddExt(zz, tt, zz); + } + + public static void Reduce(ulong[] xx, ulong[] z) + { + ulong x0 = xx[0], x1 = xx[1], x2 = xx[2], x3 = xx[3], x4 = xx[4], x5 = xx[5], x6 = xx[6]; + + x2 ^= (x6 << 63); + x3 ^= (x6 >> 1) ^ (x6 << 14); + x4 ^= (x6 >> 50); + + x1 ^= (x5 << 63); + x2 ^= (x5 >> 1) ^ (x5 << 14); + x3 ^= (x5 >> 50); + + x0 ^= (x4 << 63); + x1 ^= (x4 >> 1) ^ (x4 << 14); + x2 ^= (x4 >> 50); + + ulong t = x3 >> 1; + z[0] = x0 ^ t ^ (t << 15); + z[1] = x1 ^ (t >> 49); + z[2] = x2; + z[3] = x3 & M01; + } + + public static void Reduce63(ulong[] z, int zOff) + { + ulong z3 = z[zOff + 3], t = z3 >> 1; + z[zOff ] ^= t ^ (t << 15); + z[zOff + 1] ^= (t >> 49); + z[zOff + 3] = z3 & M01; + } + + public static void Sqrt(ulong[] x, ulong[] z) + { + ulong u0, u1; + u0 = Interleave.Unshuffle(x[0]); u1 = Interleave.Unshuffle(x[1]); + ulong e0 = (u0 & 0x00000000FFFFFFFFUL) | (u1 << 32); + ulong c0 = (u0 >> 32) | (u1 & 0xFFFFFFFF00000000UL); + + u0 = Interleave.Unshuffle(x[2]); + ulong e1 = (u0 & 0x00000000FFFFFFFFUL) ^ (x[3] << 32); + ulong c1 = (u0 >> 32); + + z[0] = e0 ^ (c0 << 8); + z[1] = e1 ^ (c1 << 8) ^ (c0 >> 56) ^ (c0 << 33); + z[2] = (c1 >> 56) ^ (c1 << 33) ^ (c0 >> 31); + z[3] = (c1 >> 31); + } + + public static void Square(ulong[] x, ulong[] z) + { + ulong[] tt = Nat256.CreateExt64(); + ImplSquare(x, tt); + Reduce(tt, z); + } + + public static void SquareAddToExt(ulong[] x, ulong[] zz) + { + ulong[] tt = Nat256.CreateExt64(); + ImplSquare(x, tt); + AddExt(zz, tt, zz); + } + + public static void SquareN(ulong[] x, int n, ulong[] z) + { + Debug.Assert(n > 0); + + ulong[] tt = Nat256.CreateExt64(); + ImplSquare(x, tt); + Reduce(tt, z); + + while (--n > 0) + { + ImplSquare(z, tt); + Reduce(tt, z); + } + } + + public static uint Trace(ulong[] x) + { + // Non-zero-trace bits: 0 + return (uint)(x[0]) & 1U; + } + + protected static void ImplCompactExt(ulong[] zz) + { + ulong z0 = zz[0], z1 = zz[1], z2 = zz[2], z3 = zz[3], z4 = zz[4], z5 = zz[5], z6 = zz[6], z7 = zz[7]; + zz[0] = z0 ^ (z1 << 49); + zz[1] = (z1 >> 15) ^ (z2 << 34); + zz[2] = (z2 >> 30) ^ (z3 << 19); + zz[3] = (z3 >> 45) ^ (z4 << 4) + ^ (z5 << 53); + zz[4] = (z4 >> 60) ^ (z6 << 38) + ^ (z5 >> 11); + zz[5] = (z6 >> 26) ^ (z7 << 23); + zz[6] = (z7 >> 41); + zz[7] = 0; + } + + protected static void ImplExpand(ulong[] x, ulong[] z) + { + ulong x0 = x[0], x1 = x[1], x2 = x[2], x3 = x[3]; + z[0] = x0 & M49; + z[1] = ((x0 >> 49) ^ (x1 << 15)) & M49; + z[2] = ((x1 >> 34) ^ (x2 << 30)) & M49; + z[3] = ((x2 >> 19) ^ (x3 << 45)); + } + + protected static void ImplMultiply(ulong[] x, ulong[] y, ulong[] zz) + { + /* + * "Two-level seven-way recursion" as described in "Batch binary Edwards", Daniel J. Bernstein. + */ + + ulong[] f = new ulong[4], g = new ulong[4]; + ImplExpand(x, f); + ImplExpand(y, g); + + ulong[] u = new ulong[8]; + + ImplMulwAcc(u, f[0], g[0], zz, 0); + ImplMulwAcc(u, f[1], g[1], zz, 1); + ImplMulwAcc(u, f[2], g[2], zz, 2); + ImplMulwAcc(u, f[3], g[3], zz, 3); + + // U *= (1 - t^n) + for (int i = 5; i > 0; --i) + { + zz[i] ^= zz[i - 1]; + } + + ImplMulwAcc(u, f[0] ^ f[1], g[0] ^ g[1], zz, 1); + ImplMulwAcc(u, f[2] ^ f[3], g[2] ^ g[3], zz, 3); + + // V *= (1 - t^2n) + for (int i = 7; i > 1; --i) + { + zz[i] ^= zz[i - 2]; + } + + // Double-length recursion + { + ulong c0 = f[0] ^ f[2], c1 = f[1] ^ f[3]; + ulong d0 = g[0] ^ g[2], d1 = g[1] ^ g[3]; + ImplMulwAcc(u, c0 ^ c1, d0 ^ d1, zz, 3); + ulong[] t = new ulong[3]; + ImplMulwAcc(u, c0, d0, t, 0); + ImplMulwAcc(u, c1, d1, t, 1); + ulong t0 = t[0], t1 = t[1], t2 = t[2]; + zz[2] ^= t0; + zz[3] ^= t0 ^ t1; + zz[4] ^= t2 ^ t1; + zz[5] ^= t2; + } + + ImplCompactExt(zz); + } + + protected static void ImplMulwAcc(ulong[] u, ulong x, ulong y, ulong[] z, int zOff) + { + Debug.Assert(x >> 49 == 0); + Debug.Assert(y >> 49 == 0); + + //u[0] = 0; + u[1] = y; + u[2] = u[1] << 1; + u[3] = u[2] ^ y; + u[4] = u[2] << 1; + u[5] = u[4] ^ y; + u[6] = u[3] << 1; + u[7] = u[6] ^ y; + + uint j = (uint)x; + ulong g, h = 0, l = u[j & 7] + ^ (u[(j >> 3) & 7] << 3); + int k = 36; + do + { + j = (uint)(x >> k); + g = u[j & 7] + ^ u[(j >> 3) & 7] << 3 + ^ u[(j >> 6) & 7] << 6 + ^ u[(j >> 9) & 7] << 9 + ^ u[(j >> 12) & 7] << 12; + l ^= (g << k); + h ^= (g >> -k); + } + while ((k -= 15) > 0); + + Debug.Assert(h >> 33 == 0); + + z[zOff ] ^= l & M49; + z[zOff + 1] ^= (l >> 49) ^ (h << 15); + } + + protected static void ImplSquare(ulong[] x, ulong[] zz) + { + Interleave.Expand64To128(x, 0, 3, zz, 0); + zz[6] = (x[3] & M01); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT193Field.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT193Field.cs.meta new file mode 100644 index 0000000..970d0b7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT193Field.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2ff6272a4676e4a418279f862eed38b6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT193FieldElement.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT193FieldElement.cs new file mode 100644 index 0000000..3a3ed09 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT193FieldElement.cs @@ -0,0 +1,233 @@ +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT193FieldElement + : AbstractF2mFieldElement + { + protected internal readonly ulong[] x; + + public SecT193FieldElement(BigInteger x) + { + if (x == null || x.SignValue < 0 || x.BitLength > 193) + throw new ArgumentException("value invalid for SecT193FieldElement", "x"); + + this.x = SecT193Field.FromBigInteger(x); + } + + public SecT193FieldElement() + { + this.x = Nat256.Create64(); + } + + protected internal SecT193FieldElement(ulong[] x) + { + this.x = x; + } + + public override bool IsOne + { + get { return Nat256.IsOne64(x); } + } + + public override bool IsZero + { + get { return Nat256.IsZero64(x); } + } + + public override bool TestBitZero() + { + return (x[0] & 1UL) != 0UL; + } + + public override BigInteger ToBigInteger() + { + return Nat256.ToBigInteger64(x); + } + + public override string FieldName + { + get { return "SecT193Field"; } + } + + public override int FieldSize + { + get { return 193; } + } + + public override ECFieldElement Add(ECFieldElement b) + { + ulong[] z = Nat256.Create64(); + SecT193Field.Add(x, ((SecT193FieldElement)b).x, z); + return new SecT193FieldElement(z); + } + + public override ECFieldElement AddOne() + { + ulong[] z = Nat256.Create64(); + SecT193Field.AddOne(x, z); + return new SecT193FieldElement(z); + } + + public override ECFieldElement Subtract(ECFieldElement b) + { + // Addition and Subtraction are the same in F2m + return Add(b); + } + + public override ECFieldElement Multiply(ECFieldElement b) + { + ulong[] z = Nat256.Create64(); + SecT193Field.Multiply(x, ((SecT193FieldElement)b).x, z); + return new SecT193FieldElement(z); + } + + public override ECFieldElement MultiplyMinusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) + { + return MultiplyPlusProduct(b, x, y); + } + + public override ECFieldElement MultiplyPlusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) + { + ulong[] ax = this.x, bx = ((SecT193FieldElement)b).x; + ulong[] xx = ((SecT193FieldElement)x).x, yx = ((SecT193FieldElement)y).x; + + ulong[] tt = Nat256.CreateExt64(); + SecT193Field.MultiplyAddToExt(ax, bx, tt); + SecT193Field.MultiplyAddToExt(xx, yx, tt); + + ulong[] z = Nat256.Create64(); + SecT193Field.Reduce(tt, z); + return new SecT193FieldElement(z); + } + + public override ECFieldElement Divide(ECFieldElement b) + { + return Multiply(b.Invert()); + } + + public override ECFieldElement Negate() + { + return this; + } + + public override ECFieldElement Square() + { + ulong[] z = Nat256.Create64(); + SecT193Field.Square(x, z); + return new SecT193FieldElement(z); + } + + public override ECFieldElement SquareMinusProduct(ECFieldElement x, ECFieldElement y) + { + return SquarePlusProduct(x, y); + } + + public override ECFieldElement SquarePlusProduct(ECFieldElement x, ECFieldElement y) + { + ulong[] ax = this.x; + ulong[] xx = ((SecT193FieldElement)x).x, yx = ((SecT193FieldElement)y).x; + + ulong[] tt = Nat256.CreateExt64(); + SecT193Field.SquareAddToExt(ax, tt); + SecT193Field.MultiplyAddToExt(xx, yx, tt); + + ulong[] z = Nat256.Create64(); + SecT193Field.Reduce(tt, z); + return new SecT193FieldElement(z); + } + + public override ECFieldElement SquarePow(int pow) + { + if (pow < 1) + return this; + + ulong[] z = Nat256.Create64(); + SecT193Field.SquareN(x, pow, z); + return new SecT193FieldElement(z); + } + + public override ECFieldElement HalfTrace() + { + ulong[] z = Nat256.Create64(); + SecT193Field.HalfTrace(x, z); + return new SecT193FieldElement(z); + } + + public override bool HasFastTrace + { + get { return true; } + } + + public override int Trace() + { + return (int)SecT193Field.Trace(x); + } + + public override ECFieldElement Invert() + { + ulong[] z = Nat256.Create64(); + SecT193Field.Invert(x, z); + return new SecT193FieldElement(z); + } + + public override ECFieldElement Sqrt() + { + ulong[] z = Nat256.Create64(); + SecT193Field.Sqrt(x, z); + return new SecT193FieldElement(z); + } + + public virtual int Representation + { + get { return F2mFieldElement.Tpb; } + } + + public virtual int M + { + get { return 193; } + } + + public virtual int K1 + { + get { return 15; } + } + + public virtual int K2 + { + get { return 0; } + } + + public virtual int K3 + { + get { return 0; } + } + + public override bool Equals(object obj) + { + return Equals(obj as SecT193FieldElement); + } + + public override bool Equals(ECFieldElement other) + { + return Equals(other as SecT193FieldElement); + } + + public virtual bool Equals(SecT193FieldElement other) + { + if (this == other) + return true; + if (null == other) + return false; + return Nat256.Eq64(x, other.x); + } + + public override int GetHashCode() + { + return 1930015 ^ Arrays.GetHashCode(x, 0, 4); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT193FieldElement.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT193FieldElement.cs.meta new file mode 100644 index 0000000..3b83b1c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT193FieldElement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d8a2d37729e4cb741b829b7755154f09 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT193R1Curve.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT193R1Curve.cs new file mode 100644 index 0000000..32bc434 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT193R1Curve.cs @@ -0,0 +1,177 @@ +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT193R1Curve + : AbstractF2mCurve + { + private const int SECT193R1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT193R1_FE_LONGS = 4; + private static readonly ECFieldElement[] SECT193R1_AFFINE_ZS = new ECFieldElement[] { new SecT193FieldElement(BigInteger.One) }; + + protected readonly SecT193R1Point m_infinity; + + public SecT193R1Curve() + : base(193, 15, 0, 0) + { + this.m_infinity = new SecT193R1Point(this, null, null); + + this.m_a = FromBigInteger(new BigInteger(1, Hex.DecodeStrict("0017858FEB7A98975169E171F77B4087DE098AC8A911DF7B01"))); + this.m_b = FromBigInteger(new BigInteger(1, Hex.DecodeStrict("00FDFB49BFE6C3A89FACADAA7A1E5BBC7CC1C2E5D831478814"))); + this.m_order = new BigInteger(1, Hex.DecodeStrict("01000000000000000000000000C7F34A778F443ACC920EBA49")); + this.m_cofactor = BigInteger.Two; + + this.m_coord = SECT193R1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecT193R1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_LAMBDA_PROJECTIVE: + return true; + default: + return false; + } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return 193; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecT193FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecT193R1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecT193R1Point(this, x, y, zs, withCompression); + } + + public override bool IsKoblitz + { + get { return false; } + } + + public virtual int M + { + get { return 193; } + } + + public virtual bool IsTrinomial + { + get { return true; } + } + + public virtual int K1 + { + get { return 15; } + } + + public virtual int K2 + { + get { return 0; } + } + + public virtual int K3 + { + get { return 0; } + } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + ulong[] table = new ulong[len * SECT193R1_FE_LONGS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat256.Copy64(((SecT193FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECT193R1_FE_LONGS; + Nat256.Copy64(((SecT193FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECT193R1_FE_LONGS; + } + } + + return new SecT193R1LookupTable(this, table, len); + } + + private class SecT193R1LookupTable + : AbstractECLookupTable + { + private readonly SecT193R1Curve m_outer; + private readonly ulong[] m_table; + private readonly int m_size; + + internal SecT193R1LookupTable(SecT193R1Curve outer, ulong[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public override int Size + { + get { return m_size; } + } + + public override ECPoint Lookup(int index) + { + ulong[] x = Nat256.Create64(), y = Nat256.Create64(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + ulong MASK = (ulong)(long)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECT193R1_FE_LONGS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECT193R1_FE_LONGS + j] & MASK; + } + + pos += (SECT193R1_FE_LONGS * 2); + } + + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + ulong[] x = Nat256.Create64(), y = Nat256.Create64(); + int pos = index * SECT193R1_FE_LONGS * 2; + + for (int j = 0; j < SECT193R1_FE_LONGS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECT193R1_FE_LONGS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(ulong[] x, ulong[] y) + { + return m_outer.CreateRawPoint(new SecT193FieldElement(x), new SecT193FieldElement(y), SECT193R1_AFFINE_ZS, false); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT193R1Curve.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT193R1Curve.cs.meta new file mode 100644 index 0000000..9e8a1be --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT193R1Curve.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e98483e45f7cae14988dc767a0a7066b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT193R1Point.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT193R1Point.cs new file mode 100644 index 0000000..9dbdd14 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT193R1Point.cs @@ -0,0 +1,283 @@ +using System; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT193R1Point + : AbstractF2mPoint + { + /** + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecT193R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * @deprecated per-point compression property will be removed, refer {@link #getEncoded(bool)} + */ + public SecT193R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecT193R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecT193R1Point(null, AffineXCoord, AffineYCoord); + } + + public override ECFieldElement YCoord + { + get + { + ECFieldElement X = RawXCoord, L = RawYCoord; + + if (this.IsInfinity || X.IsZero) + return L; + + // Y is actually Lambda (X + Y/X) here; convert to affine value on the fly + ECFieldElement Y = L.Add(X).Multiply(X); + + ECFieldElement Z = RawZCoords[0]; + if (!Z.IsOne) + { + Y = Y.Divide(Z); + } + + return Y; + } + } + + protected internal override bool CompressionYTilde + { + get + { + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return false; + + ECFieldElement Y = this.RawYCoord; + + // Y is actually Lambda (X + Y/X) here + return Y.TestBitZero() != X.TestBitZero(); + } + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + ECFieldElement X2 = b.RawXCoord; + + if (X1.IsZero) + { + if (X2.IsZero) + return curve.Infinity; + + return b.Add(this); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord, Z2 = b.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement U2 = X2, S2 = L2; + if (!Z1IsOne) + { + U2 = U2.Multiply(Z1); + S2 = S2.Multiply(Z1); + } + + bool Z2IsOne = Z2.IsOne; + ECFieldElement U1 = X1, S1 = L1; + if (!Z2IsOne) + { + U1 = U1.Multiply(Z2); + S1 = S1.Multiply(Z2); + } + + ECFieldElement A = S1.Add(S2); + ECFieldElement B = U1.Add(U2); + + if (B.IsZero) + { + if (A.IsZero) + return Twice(); + + return curve.Infinity; + } + + ECFieldElement X3, L3, Z3; + if (X2.IsZero) + { + // TODO This can probably be optimized quite a bit + ECPoint p = this.Normalize(); + X1 = p.XCoord; + ECFieldElement Y1 = p.YCoord; + + ECFieldElement Y2 = L2; + ECFieldElement L = Y1.Add(Y2).Divide(X1); + + X3 = L.Square().Add(L).Add(X1).Add(curve.A); + if (X3.IsZero) + { + return new SecT193R1Point(curve, X3, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement Y3 = L.Multiply(X1.Add(X3)).Add(X3).Add(Y1); + L3 = Y3.Divide(X3).Add(X3); + Z3 = curve.FromBigInteger(BigInteger.One); + } + else + { + B = B.Square(); + + ECFieldElement AU1 = A.Multiply(U1); + ECFieldElement AU2 = A.Multiply(U2); + + X3 = AU1.Multiply(AU2); + if (X3.IsZero) + { + return new SecT193R1Point(curve, X3, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement ABZ2 = A.Multiply(B); + if (!Z2IsOne) + { + ABZ2 = ABZ2.Multiply(Z2); + } + + L3 = AU2.Add(B).SquarePlusProduct(ABZ2, L1.Add(Z1)); + + Z3 = ABZ2; + if (!Z1IsOne) + { + Z3 = Z3.Multiply(Z1); + } + } + + return new SecT193R1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + { + return this; + } + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is its own additive inverse + return curve.Infinity; + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement L1Z1 = Z1IsOne ? L1 : L1.Multiply(Z1); + ECFieldElement Z1Sq = Z1IsOne ? Z1 : Z1.Square(); + ECFieldElement a = curve.A; + ECFieldElement aZ1Sq = Z1IsOne ? a : a.Multiply(Z1Sq); + ECFieldElement T = L1.Square().Add(L1Z1).Add(aZ1Sq); + if (T.IsZero) + { + return new SecT193R1Point(curve, T, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement X3 = T.Square(); + ECFieldElement Z3 = Z1IsOne ? T : T.Multiply(Z1Sq); + + ECFieldElement X1Z1 = Z1IsOne ? X1 : X1.Multiply(Z1); + ECFieldElement L3 = X1Z1.SquarePlusProduct(T, L1Z1).Add(X3).Add(Z3); + + return new SecT193R1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is its own additive inverse + return b; + } + + ECFieldElement X2 = b.RawXCoord, Z2 = b.RawZCoords[0]; + if (X2.IsZero || !Z2.IsOne) + { + return Twice().Add(b); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord; + + ECFieldElement X1Sq = X1.Square(); + ECFieldElement L1Sq = L1.Square(); + ECFieldElement Z1Sq = Z1.Square(); + ECFieldElement L1Z1 = L1.Multiply(Z1); + + ECFieldElement T = curve.A.Multiply(Z1Sq).Add(L1Sq).Add(L1Z1); + ECFieldElement L2plus1 = L2.AddOne(); + ECFieldElement A = curve.A.Add(L2plus1).Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); + ECFieldElement X2Z1Sq = X2.Multiply(Z1Sq); + ECFieldElement B = X2Z1Sq.Add(T).Square(); + + if (B.IsZero) + { + if (A.IsZero) + return b.Twice(); + + return curve.Infinity; + } + + if (A.IsZero) + { + return new SecT193R1Point(curve, A, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement X3 = A.Square().Multiply(X2Z1Sq); + ECFieldElement Z3 = A.Multiply(B).Multiply(Z1Sq); + ECFieldElement L3 = A.Add(B).Square().MultiplyPlusProduct(T, L2plus1, Z3); + + return new SecT193R1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Negate() + { + if (this.IsInfinity) + return this; + + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return this; + + // L is actually Lambda (X + Y/X) here + ECFieldElement L = this.RawYCoord, Z = this.RawZCoords[0]; + return new SecT193R1Point(Curve, X, L.Add(Z), new ECFieldElement[] { Z }, IsCompressed); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT193R1Point.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT193R1Point.cs.meta new file mode 100644 index 0000000..5f6d36e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT193R1Point.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0b5f874853eec5d49a3625ab466a10f4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT193R2Curve.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT193R2Curve.cs new file mode 100644 index 0000000..7f53571 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT193R2Curve.cs @@ -0,0 +1,177 @@ +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT193R2Curve + : AbstractF2mCurve + { + private const int SECT193R2_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT193R2_FE_LONGS = 4; + private static readonly ECFieldElement[] SECT193R2_AFFINE_ZS = new ECFieldElement[] { new SecT193FieldElement(BigInteger.One) }; + + protected readonly SecT193R2Point m_infinity; + + public SecT193R2Curve() + : base(193, 15, 0, 0) + { + this.m_infinity = new SecT193R2Point(this, null, null); + + this.m_a = FromBigInteger(new BigInteger(1, Hex.DecodeStrict("0163F35A5137C2CE3EA6ED8667190B0BC43ECD69977702709B"))); + this.m_b = FromBigInteger(new BigInteger(1, Hex.DecodeStrict("00C9BB9E8927D4D64C377E2AB2856A5B16E3EFB7F61D4316AE"))); + this.m_order = new BigInteger(1, Hex.DecodeStrict("010000000000000000000000015AAB561B005413CCD4EE99D5")); + this.m_cofactor = BigInteger.Two; + + this.m_coord = SECT193R2_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecT193R2Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_LAMBDA_PROJECTIVE: + return true; + default: + return false; + } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return 193; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecT193FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecT193R2Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecT193R2Point(this, x, y, zs, withCompression); + } + + public override bool IsKoblitz + { + get { return false; } + } + + public virtual int M + { + get { return 193; } + } + + public virtual bool IsTrinomial + { + get { return true; } + } + + public virtual int K1 + { + get { return 15; } + } + + public virtual int K2 + { + get { return 0; } + } + + public virtual int K3 + { + get { return 0; } + } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + ulong[] table = new ulong[len * SECT193R2_FE_LONGS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat256.Copy64(((SecT193FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECT193R2_FE_LONGS; + Nat256.Copy64(((SecT193FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECT193R2_FE_LONGS; + } + } + + return new SecT193R2LookupTable(this, table, len); + } + + private class SecT193R2LookupTable + : AbstractECLookupTable + { + private readonly SecT193R2Curve m_outer; + private readonly ulong[] m_table; + private readonly int m_size; + + internal SecT193R2LookupTable(SecT193R2Curve outer, ulong[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public override int Size + { + get { return m_size; } + } + + public override ECPoint Lookup(int index) + { + ulong[] x = Nat256.Create64(), y = Nat256.Create64(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + ulong MASK = (ulong)(long)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECT193R2_FE_LONGS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECT193R2_FE_LONGS + j] & MASK; + } + + pos += (SECT193R2_FE_LONGS * 2); + } + + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + ulong[] x = Nat256.Create64(), y = Nat256.Create64(); + int pos = index * SECT193R2_FE_LONGS * 2; + + for (int j = 0; j < SECT193R2_FE_LONGS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECT193R2_FE_LONGS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(ulong[] x, ulong[] y) + { + return m_outer.CreateRawPoint(new SecT193FieldElement(x), new SecT193FieldElement(y), SECT193R2_AFFINE_ZS, false); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT193R2Curve.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT193R2Curve.cs.meta new file mode 100644 index 0000000..57cb544 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT193R2Curve.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fffe2850d167ec840ad56f6f6381884c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT193R2Point.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT193R2Point.cs new file mode 100644 index 0000000..b75a7ce --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT193R2Point.cs @@ -0,0 +1,283 @@ +using System; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT193R2Point + : AbstractF2mPoint + { + /** + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecT193R2Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * @deprecated per-point compression property will be removed, refer {@link #getEncoded(bool)} + */ + public SecT193R2Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecT193R2Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecT193R2Point(null, AffineXCoord, AffineYCoord); + } + + public override ECFieldElement YCoord + { + get + { + ECFieldElement X = RawXCoord, L = RawYCoord; + + if (this.IsInfinity || X.IsZero) + return L; + + // Y is actually Lambda (X + Y/X) here; convert to affine value on the fly + ECFieldElement Y = L.Add(X).Multiply(X); + + ECFieldElement Z = RawZCoords[0]; + if (!Z.IsOne) + { + Y = Y.Divide(Z); + } + + return Y; + } + } + + protected internal override bool CompressionYTilde + { + get + { + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return false; + + ECFieldElement Y = this.RawYCoord; + + // Y is actually Lambda (X + Y/X) here + return Y.TestBitZero() != X.TestBitZero(); + } + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + ECFieldElement X2 = b.RawXCoord; + + if (X1.IsZero) + { + if (X2.IsZero) + return curve.Infinity; + + return b.Add(this); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord, Z2 = b.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement U2 = X2, S2 = L2; + if (!Z1IsOne) + { + U2 = U2.Multiply(Z1); + S2 = S2.Multiply(Z1); + } + + bool Z2IsOne = Z2.IsOne; + ECFieldElement U1 = X1, S1 = L1; + if (!Z2IsOne) + { + U1 = U1.Multiply(Z2); + S1 = S1.Multiply(Z2); + } + + ECFieldElement A = S1.Add(S2); + ECFieldElement B = U1.Add(U2); + + if (B.IsZero) + { + if (A.IsZero) + return Twice(); + + return curve.Infinity; + } + + ECFieldElement X3, L3, Z3; + if (X2.IsZero) + { + // TODO This can probably be optimized quite a bit + ECPoint p = this.Normalize(); + X1 = p.XCoord; + ECFieldElement Y1 = p.YCoord; + + ECFieldElement Y2 = L2; + ECFieldElement L = Y1.Add(Y2).Divide(X1); + + X3 = L.Square().Add(L).Add(X1).Add(curve.A); + if (X3.IsZero) + { + return new SecT193R2Point(curve, X3, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement Y3 = L.Multiply(X1.Add(X3)).Add(X3).Add(Y1); + L3 = Y3.Divide(X3).Add(X3); + Z3 = curve.FromBigInteger(BigInteger.One); + } + else + { + B = B.Square(); + + ECFieldElement AU1 = A.Multiply(U1); + ECFieldElement AU2 = A.Multiply(U2); + + X3 = AU1.Multiply(AU2); + if (X3.IsZero) + { + return new SecT193R2Point(curve, X3, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement ABZ2 = A.Multiply(B); + if (!Z2IsOne) + { + ABZ2 = ABZ2.Multiply(Z2); + } + + L3 = AU2.Add(B).SquarePlusProduct(ABZ2, L1.Add(Z1)); + + Z3 = ABZ2; + if (!Z1IsOne) + { + Z3 = Z3.Multiply(Z1); + } + } + + return new SecT193R2Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + { + return this; + } + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is its own additive inverse + return curve.Infinity; + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement L1Z1 = Z1IsOne ? L1 : L1.Multiply(Z1); + ECFieldElement Z1Sq = Z1IsOne ? Z1 : Z1.Square(); + ECFieldElement a = curve.A; + ECFieldElement aZ1Sq = Z1IsOne ? a : a.Multiply(Z1Sq); + ECFieldElement T = L1.Square().Add(L1Z1).Add(aZ1Sq); + if (T.IsZero) + { + return new SecT193R2Point(curve, T, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement X3 = T.Square(); + ECFieldElement Z3 = Z1IsOne ? T : T.Multiply(Z1Sq); + + ECFieldElement X1Z1 = Z1IsOne ? X1 : X1.Multiply(Z1); + ECFieldElement L3 = X1Z1.SquarePlusProduct(T, L1Z1).Add(X3).Add(Z3); + + return new SecT193R2Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is its own additive inverse + return b; + } + + ECFieldElement X2 = b.RawXCoord, Z2 = b.RawZCoords[0]; + if (X2.IsZero || !Z2.IsOne) + { + return Twice().Add(b); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord; + + ECFieldElement X1Sq = X1.Square(); + ECFieldElement L1Sq = L1.Square(); + ECFieldElement Z1Sq = Z1.Square(); + ECFieldElement L1Z1 = L1.Multiply(Z1); + + ECFieldElement T = curve.A.Multiply(Z1Sq).Add(L1Sq).Add(L1Z1); + ECFieldElement L2plus1 = L2.AddOne(); + ECFieldElement A = curve.A.Add(L2plus1).Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); + ECFieldElement X2Z1Sq = X2.Multiply(Z1Sq); + ECFieldElement B = X2Z1Sq.Add(T).Square(); + + if (B.IsZero) + { + if (A.IsZero) + return b.Twice(); + + return curve.Infinity; + } + + if (A.IsZero) + { + return new SecT193R2Point(curve, A, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement X3 = A.Square().Multiply(X2Z1Sq); + ECFieldElement Z3 = A.Multiply(B).Multiply(Z1Sq); + ECFieldElement L3 = A.Add(B).Square().MultiplyPlusProduct(T, L2plus1, Z3); + + return new SecT193R2Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Negate() + { + if (this.IsInfinity) + return this; + + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return this; + + // L is actually Lambda (X + Y/X) here + ECFieldElement L = this.RawYCoord, Z = this.RawZCoords[0]; + return new SecT193R2Point(Curve, X, L.Add(Z), new ECFieldElement[] { Z }, IsCompressed); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT193R2Point.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT193R2Point.cs.meta new file mode 100644 index 0000000..6e748d2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT193R2Point.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 429fd22d4f9276a4c824a411952af971 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT233Field.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT233Field.cs new file mode 100644 index 0000000..1ebac2e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT233Field.cs @@ -0,0 +1,333 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT233Field + { + private const ulong M41 = ulong.MaxValue >> 23; + private const ulong M59 = ulong.MaxValue >> 5; + + public static void Add(ulong[] x, ulong[] y, ulong[] z) + { + z[0] = x[0] ^ y[0]; + z[1] = x[1] ^ y[1]; + z[2] = x[2] ^ y[2]; + z[3] = x[3] ^ y[3]; + } + + public static void AddExt(ulong[] xx, ulong[] yy, ulong[] zz) + { + zz[0] = xx[0] ^ yy[0]; + zz[1] = xx[1] ^ yy[1]; + zz[2] = xx[2] ^ yy[2]; + zz[3] = xx[3] ^ yy[3]; + zz[4] = xx[4] ^ yy[4]; + zz[5] = xx[5] ^ yy[5]; + zz[6] = xx[6] ^ yy[6]; + zz[7] = xx[7] ^ yy[7]; + } + + public static void AddOne(ulong[] x, ulong[] z) + { + z[0] = x[0] ^ 1UL; + z[1] = x[1]; + z[2] = x[2]; + z[3] = x[3]; + } + + private static void AddTo(ulong[] x, ulong[] z) + { + z[0] ^= x[0]; + z[1] ^= x[1]; + z[2] ^= x[2]; + z[3] ^= x[3]; + } + + public static ulong[] FromBigInteger(BigInteger x) + { + return Nat.FromBigInteger64(233, x); + } + + public static void HalfTrace(ulong[] x, ulong[] z) + { + ulong[] tt = Nat256.CreateExt64(); + + Nat256.Copy64(x, z); + for (int i = 1; i < 233; i += 2) + { + ImplSquare(z, tt); + Reduce(tt, z); + ImplSquare(z, tt); + Reduce(tt, z); + AddTo(x, z); + } + } + + public static void Invert(ulong[] x, ulong[] z) + { + if (Nat256.IsZero64(x)) + throw new InvalidOperationException(); + + // Itoh-Tsujii inversion + + ulong[] t0 = Nat256.Create64(); + ulong[] t1 = Nat256.Create64(); + + Square(x, t0); + Multiply(t0, x, t0); + Square(t0, t0); + Multiply(t0, x, t0); + SquareN(t0, 3, t1); + Multiply(t1, t0, t1); + Square(t1, t1); + Multiply(t1, x, t1); + SquareN(t1, 7, t0); + Multiply(t0, t1, t0); + SquareN(t0, 14, t1); + Multiply(t1, t0, t1); + Square(t1, t1); + Multiply(t1, x, t1); + SquareN(t1, 29, t0); + Multiply(t0, t1, t0); + SquareN(t0, 58, t1); + Multiply(t1, t0, t1); + SquareN(t1, 116, t0); + Multiply(t0, t1, t0); + Square(t0, z); + } + + public static void Multiply(ulong[] x, ulong[] y, ulong[] z) + { + ulong[] tt = Nat256.CreateExt64(); + ImplMultiply(x, y, tt); + Reduce(tt, z); + } + + public static void MultiplyAddToExt(ulong[] x, ulong[] y, ulong[] zz) + { + ulong[] tt = Nat256.CreateExt64(); + ImplMultiply(x, y, tt); + AddExt(zz, tt, zz); + } + + public static void Reduce(ulong[] xx, ulong[] z) + { + ulong x0 = xx[0], x1 = xx[1], x2 = xx[2], x3 = xx[3]; + ulong x4 = xx[4], x5 = xx[5], x6 = xx[6], x7 = xx[7]; + + x3 ^= (x7 << 23); + x4 ^= (x7 >> 41) ^ (x7 << 33); + x5 ^= (x7 >> 31); + + x2 ^= (x6 << 23); + x3 ^= (x6 >> 41) ^ (x6 << 33); + x4 ^= (x6 >> 31); + + x1 ^= (x5 << 23); + x2 ^= (x5 >> 41) ^ (x5 << 33); + x3 ^= (x5 >> 31); + + x0 ^= (x4 << 23); + x1 ^= (x4 >> 41) ^ (x4 << 33); + x2 ^= (x4 >> 31); + + ulong t = x3 >> 41; + z[0] = x0 ^ t; + z[1] = x1 ^ (t << 10); + z[2] = x2; + z[3] = x3 & M41; + } + + public static void Reduce23(ulong[] z, int zOff) + { + ulong z3 = z[zOff + 3], t = z3 >> 41; + z[zOff ] ^= t; + z[zOff + 1] ^= (t << 10); + z[zOff + 3] = z3 & M41; + } + + public static void Sqrt(ulong[] x, ulong[] z) + { + ulong u0, u1; + u0 = Interleave.Unshuffle(x[0]); u1 = Interleave.Unshuffle(x[1]); + ulong e0 = (u0 & 0x00000000FFFFFFFFUL) | (u1 << 32); + ulong c0 = (u0 >> 32) | (u1 & 0xFFFFFFFF00000000UL); + + u0 = Interleave.Unshuffle(x[2]); u1 = Interleave.Unshuffle(x[3]); + ulong e1 = (u0 & 0x00000000FFFFFFFFUL) | (u1 << 32); + ulong c1 = (u0 >> 32) | (u1 & 0xFFFFFFFF00000000UL); + + ulong c2; + c2 = (c1 >> 27); + c1 ^= (c0 >> 27) | (c1 << 37); + c0 ^= (c0 << 37); + + ulong[] tt = Nat256.CreateExt64(); + + int[] shifts = { 32, 117, 191 }; + for (int i = 0; i < shifts.Length; ++i) + { + int w = shifts[i] >> 6, s = shifts[i] & 63; + Debug.Assert(s != 0); + tt[w ] ^= (c0 << s); + tt[w + 1] ^= (c1 << s) | (c0 >> -s); + tt[w + 2] ^= (c2 << s) | (c1 >> -s); + tt[w + 3] ^= (c2 >> -s); + } + + Reduce(tt, z); + + z[0] ^= e0; + z[1] ^= e1; + } + + public static void Square(ulong[] x, ulong[] z) + { + ulong[] tt = Nat256.CreateExt64(); + ImplSquare(x, tt); + Reduce(tt, z); + } + + public static void SquareAddToExt(ulong[] x, ulong[] zz) + { + ulong[] tt = Nat256.CreateExt64(); + ImplSquare(x, tt); + AddExt(zz, tt, zz); + } + + public static void SquareN(ulong[] x, int n, ulong[] z) + { + Debug.Assert(n > 0); + + ulong[] tt = Nat256.CreateExt64(); + ImplSquare(x, tt); + Reduce(tt, z); + + while (--n > 0) + { + ImplSquare(z, tt); + Reduce(tt, z); + } + } + + public static uint Trace(ulong[] x) + { + // Non-zero-trace bits: 0, 159 + return (uint)(x[0] ^ (x[2] >> 31)) & 1U; + } + + protected static void ImplCompactExt(ulong[] zz) + { + ulong z0 = zz[0], z1 = zz[1], z2 = zz[2], z3 = zz[3], z4 = zz[4], z5 = zz[5], z6 = zz[6], z7 = zz[7]; + zz[0] = z0 ^ (z1 << 59); + zz[1] = (z1 >> 5) ^ (z2 << 54); + zz[2] = (z2 >> 10) ^ (z3 << 49); + zz[3] = (z3 >> 15) ^ (z4 << 44); + zz[4] = (z4 >> 20) ^ (z5 << 39); + zz[5] = (z5 >> 25) ^ (z6 << 34); + zz[6] = (z6 >> 30) ^ (z7 << 29); + zz[7] = (z7 >> 35); + } + + protected static void ImplExpand(ulong[] x, ulong[] z) + { + ulong x0 = x[0], x1 = x[1], x2 = x[2], x3 = x[3]; + z[0] = x0 & M59; + z[1] = ((x0 >> 59) ^ (x1 << 5)) & M59; + z[2] = ((x1 >> 54) ^ (x2 << 10)) & M59; + z[3] = ((x2 >> 49) ^ (x3 << 15)); + } + + protected static void ImplMultiply(ulong[] x, ulong[] y, ulong[] zz) + { + /* + * "Two-level seven-way recursion" as described in "Batch binary Edwards", Daniel J. Bernstein. + */ + + ulong[] f = new ulong[4], g = new ulong[4]; + ImplExpand(x, f); + ImplExpand(y, g); + + ulong[] u = new ulong[8]; + + ImplMulwAcc(u, f[0], g[0], zz, 0); + ImplMulwAcc(u, f[1], g[1], zz, 1); + ImplMulwAcc(u, f[2], g[2], zz, 2); + ImplMulwAcc(u, f[3], g[3], zz, 3); + + // U *= (1 - t^n) + for (int i = 5; i > 0; --i) + { + zz[i] ^= zz[i - 1]; + } + + ImplMulwAcc(u, f[0] ^ f[1], g[0] ^ g[1], zz, 1); + ImplMulwAcc(u, f[2] ^ f[3], g[2] ^ g[3], zz, 3); + + // V *= (1 - t^2n) + for (int i = 7; i > 1; --i) + { + zz[i] ^= zz[i - 2]; + } + + // Double-length recursion + { + ulong c0 = f[0] ^ f[2], c1 = f[1] ^ f[3]; + ulong d0 = g[0] ^ g[2], d1 = g[1] ^ g[3]; + ImplMulwAcc(u, c0 ^ c1, d0 ^ d1, zz, 3); + ulong[] t = new ulong[3]; + ImplMulwAcc(u, c0, d0, t, 0); + ImplMulwAcc(u, c1, d1, t, 1); + ulong t0 = t[0], t1 = t[1], t2 = t[2]; + zz[2] ^= t0; + zz[3] ^= t0 ^ t1; + zz[4] ^= t2 ^ t1; + zz[5] ^= t2; + } + + ImplCompactExt(zz); + } + + protected static void ImplMulwAcc(ulong[] u, ulong x, ulong y, ulong[] z, int zOff) + { + Debug.Assert(x >> 59 == 0); + Debug.Assert(y >> 59 == 0); + + //u[0] = 0; + u[1] = y; + u[2] = u[1] << 1; + u[3] = u[2] ^ y; + u[4] = u[2] << 1; + u[5] = u[4] ^ y; + u[6] = u[3] << 1; + u[7] = u[6] ^ y; + + uint j = (uint)x; + ulong g, h = 0, l = u[j & 7] + ^ (u[(j >> 3) & 7] << 3); + int k = 54; + do + { + j = (uint)(x >> k); + g = u[j & 7] + ^ u[(j >> 3) & 7] << 3; + l ^= (g << k); + h ^= (g >> -k); + } + while ((k -= 6) > 0); + + Debug.Assert(h >> 53 == 0); + + z[zOff ] ^= l & M59; + z[zOff + 1] ^= (l >> 59) ^ (h << 5); + } + + protected static void ImplSquare(ulong[] x, ulong[] zz) + { + Interleave.Expand64To128(x, 0, 4, zz, 0); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT233Field.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT233Field.cs.meta new file mode 100644 index 0000000..e58ee07 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT233Field.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6a5725e9044fda540b87336fd02f402f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT233FieldElement.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT233FieldElement.cs new file mode 100644 index 0000000..8aff8c8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT233FieldElement.cs @@ -0,0 +1,233 @@ +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT233FieldElement + : AbstractF2mFieldElement + { + protected internal readonly ulong[] x; + + public SecT233FieldElement(BigInteger x) + { + if (x == null || x.SignValue < 0 || x.BitLength > 233) + throw new ArgumentException("value invalid for SecT233FieldElement", "x"); + + this.x = SecT233Field.FromBigInteger(x); + } + + public SecT233FieldElement() + { + this.x = Nat256.Create64(); + } + + protected internal SecT233FieldElement(ulong[] x) + { + this.x = x; + } + + public override bool IsOne + { + get { return Nat256.IsOne64(x); } + } + + public override bool IsZero + { + get { return Nat256.IsZero64(x); } + } + + public override bool TestBitZero() + { + return (x[0] & 1UL) != 0UL; + } + + public override BigInteger ToBigInteger() + { + return Nat256.ToBigInteger64(x); + } + + public override string FieldName + { + get { return "SecT233Field"; } + } + + public override int FieldSize + { + get { return 233; } + } + + public override ECFieldElement Add(ECFieldElement b) + { + ulong[] z = Nat256.Create64(); + SecT233Field.Add(x, ((SecT233FieldElement)b).x, z); + return new SecT233FieldElement(z); + } + + public override ECFieldElement AddOne() + { + ulong[] z = Nat256.Create64(); + SecT233Field.AddOne(x, z); + return new SecT233FieldElement(z); + } + + public override ECFieldElement Subtract(ECFieldElement b) + { + // Addition and Subtraction are the same in F2m + return Add(b); + } + + public override ECFieldElement Multiply(ECFieldElement b) + { + ulong[] z = Nat256.Create64(); + SecT233Field.Multiply(x, ((SecT233FieldElement)b).x, z); + return new SecT233FieldElement(z); + } + + public override ECFieldElement MultiplyMinusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) + { + return MultiplyPlusProduct(b, x, y); + } + + public override ECFieldElement MultiplyPlusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) + { + ulong[] ax = this.x, bx = ((SecT233FieldElement)b).x; + ulong[] xx = ((SecT233FieldElement)x).x, yx = ((SecT233FieldElement)y).x; + + ulong[] tt = Nat256.CreateExt64(); + SecT233Field.MultiplyAddToExt(ax, bx, tt); + SecT233Field.MultiplyAddToExt(xx, yx, tt); + + ulong[] z = Nat256.Create64(); + SecT233Field.Reduce(tt, z); + return new SecT233FieldElement(z); + } + + public override ECFieldElement Divide(ECFieldElement b) + { + return Multiply(b.Invert()); + } + + public override ECFieldElement Negate() + { + return this; + } + + public override ECFieldElement Square() + { + ulong[] z = Nat256.Create64(); + SecT233Field.Square(x, z); + return new SecT233FieldElement(z); + } + + public override ECFieldElement SquareMinusProduct(ECFieldElement x, ECFieldElement y) + { + return SquarePlusProduct(x, y); + } + + public override ECFieldElement SquarePlusProduct(ECFieldElement x, ECFieldElement y) + { + ulong[] ax = this.x; + ulong[] xx = ((SecT233FieldElement)x).x, yx = ((SecT233FieldElement)y).x; + + ulong[] tt = Nat256.CreateExt64(); + SecT233Field.SquareAddToExt(ax, tt); + SecT233Field.MultiplyAddToExt(xx, yx, tt); + + ulong[] z = Nat256.Create64(); + SecT233Field.Reduce(tt, z); + return new SecT233FieldElement(z); + } + + public override ECFieldElement SquarePow(int pow) + { + if (pow < 1) + return this; + + ulong[] z = Nat256.Create64(); + SecT233Field.SquareN(x, pow, z); + return new SecT233FieldElement(z); + } + + public override ECFieldElement HalfTrace() + { + ulong[] z = Nat256.Create64(); + SecT233Field.HalfTrace(x, z); + return new SecT233FieldElement(z); + } + + public override bool HasFastTrace + { + get { return true; } + } + + public override int Trace() + { + return (int)SecT233Field.Trace(x); + } + + public override ECFieldElement Invert() + { + ulong[] z = Nat256.Create64(); + SecT233Field.Invert(x, z); + return new SecT233FieldElement(z); + } + + public override ECFieldElement Sqrt() + { + ulong[] z = Nat256.Create64(); + SecT233Field.Sqrt(x, z); + return new SecT233FieldElement(z); + } + + public virtual int Representation + { + get { return F2mFieldElement.Tpb; } + } + + public virtual int M + { + get { return 233; } + } + + public virtual int K1 + { + get { return 74; } + } + + public virtual int K2 + { + get { return 0; } + } + + public virtual int K3 + { + get { return 0; } + } + + public override bool Equals(object obj) + { + return Equals(obj as SecT233FieldElement); + } + + public override bool Equals(ECFieldElement other) + { + return Equals(other as SecT233FieldElement); + } + + public virtual bool Equals(SecT233FieldElement other) + { + if (this == other) + return true; + if (null == other) + return false; + return Nat256.Eq64(x, other.x); + } + + public override int GetHashCode() + { + return 2330074 ^ Arrays.GetHashCode(x, 0, 4); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT233FieldElement.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT233FieldElement.cs.meta new file mode 100644 index 0000000..2a3da9e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT233FieldElement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: aedf88be0a68f1049bf5216a6cb2d322 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT233K1Curve.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT233K1Curve.cs new file mode 100644 index 0000000..7a3f55f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT233K1Curve.cs @@ -0,0 +1,183 @@ +using System; + +using Org.BouncyCastle.Math.EC.Multiplier; +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT233K1Curve + : AbstractF2mCurve + { + private const int SECT233K1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT233K1_FE_LONGS = 4; + private static readonly ECFieldElement[] SECT233K1_AFFINE_ZS = new ECFieldElement[] { new SecT233FieldElement(BigInteger.One) }; + + protected readonly SecT233K1Point m_infinity; + + public SecT233K1Curve() + : base(233, 74, 0, 0) + { + this.m_infinity = new SecT233K1Point(this, null, null); + + this.m_a = FromBigInteger(BigInteger.Zero); + this.m_b = FromBigInteger(BigInteger.One); + this.m_order = new BigInteger(1, Hex.DecodeStrict("8000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF")); + this.m_cofactor = BigInteger.ValueOf(4); + + this.m_coord = SECT233K1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecT233K1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_LAMBDA_PROJECTIVE: + return true; + default: + return false; + } + } + + protected override ECMultiplier CreateDefaultMultiplier() + { + return new WTauNafMultiplier(); + } + + public override int FieldSize + { + get { return 233; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecT233FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecT233K1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecT233K1Point(this, x, y, zs, withCompression); + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override bool IsKoblitz + { + get { return true; } + } + + public virtual int M + { + get { return 233; } + } + + public virtual bool IsTrinomial + { + get { return true; } + } + + public virtual int K1 + { + get { return 74; } + } + + public virtual int K2 + { + get { return 0; } + } + + public virtual int K3 + { + get { return 0; } + } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + ulong[] table = new ulong[len * SECT233K1_FE_LONGS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat256.Copy64(((SecT233FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECT233K1_FE_LONGS; + Nat256.Copy64(((SecT233FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECT233K1_FE_LONGS; + } + } + + return new SecT233K1LookupTable(this, table, len); + } + + private class SecT233K1LookupTable + : AbstractECLookupTable + { + private readonly SecT233K1Curve m_outer; + private readonly ulong[] m_table; + private readonly int m_size; + + internal SecT233K1LookupTable(SecT233K1Curve outer, ulong[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public override int Size + { + get { return m_size; } + } + + public override ECPoint Lookup(int index) + { + ulong[] x = Nat256.Create64(), y = Nat256.Create64(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + ulong MASK = (ulong)(long)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECT233K1_FE_LONGS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECT233K1_FE_LONGS + j] & MASK; + } + + pos += (SECT233K1_FE_LONGS * 2); + } + + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + ulong[] x = Nat256.Create64(), y = Nat256.Create64(); + int pos = index * SECT233K1_FE_LONGS * 2; + + for (int j = 0; j < SECT233K1_FE_LONGS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECT233K1_FE_LONGS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(ulong[] x, ulong[] y) + { + return m_outer.CreateRawPoint(new SecT233FieldElement(x), new SecT233FieldElement(y), SECT233K1_AFFINE_ZS, false); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT233K1Curve.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT233K1Curve.cs.meta new file mode 100644 index 0000000..0a61ca6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT233K1Curve.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 496cfea968fbe334e970294742016462 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT233K1Point.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT233K1Point.cs new file mode 100644 index 0000000..ffb8655 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT233K1Point.cs @@ -0,0 +1,295 @@ +using System; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT233K1Point + : AbstractF2mPoint + { + /** + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecT233K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * @deprecated per-point compression property will be removed, refer {@link #getEncoded(bool)} + */ + public SecT233K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecT233K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecT233K1Point(null, this.AffineXCoord, this.AffineYCoord); // earlier JDK + } + + public override ECFieldElement YCoord + { + get + { + ECFieldElement X = RawXCoord, L = RawYCoord; + + if (this.IsInfinity || X.IsZero) + return L; + + // Y is actually Lambda (X + Y/X) here; convert to affine value on the fly + ECFieldElement Y = L.Add(X).Multiply(X); + + ECFieldElement Z = RawZCoords[0]; + if (!Z.IsOne) + { + Y = Y.Divide(Z); + } + + return Y; + } + } + + protected internal override bool CompressionYTilde + { + get + { + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return false; + + ECFieldElement Y = this.RawYCoord; + + // Y is actually Lambda (X + Y/X) here + return Y.TestBitZero() != X.TestBitZero(); + } + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + ECFieldElement X2 = b.RawXCoord; + + if (X1.IsZero) + { + if (X2.IsZero) + { + return curve.Infinity; + } + + return b.Add(this); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord, Z2 = b.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement U2 = X2, S2 = L2; + if (!Z1IsOne) + { + U2 = U2.Multiply(Z1); + S2 = S2.Multiply(Z1); + } + + bool Z2IsOne = Z2.IsOne; + ECFieldElement U1 = X1, S1 = L1; + if (!Z2IsOne) + { + U1 = U1.Multiply(Z2); + S1 = S1.Multiply(Z2); + } + + ECFieldElement A = S1.Add(S2); + ECFieldElement B = U1.Add(U2); + + if (B.IsZero) + { + if (A.IsZero) + return Twice(); + + return curve.Infinity; + } + + ECFieldElement X3, L3, Z3; + if (X2.IsZero) + { + // TODO This can probably be optimized quite a bit + ECPoint p = this.Normalize(); + X1 = p.XCoord; + ECFieldElement Y1 = p.YCoord; + + ECFieldElement Y2 = L2; + ECFieldElement L = Y1.Add(Y2).Divide(X1); + + X3 = L.Square().Add(L).Add(X1); + if (X3.IsZero) + { + return new SecT233K1Point(curve, X3, curve.B, IsCompressed); + } + + ECFieldElement Y3 = L.Multiply(X1.Add(X3)).Add(X3).Add(Y1); + L3 = Y3.Divide(X3).Add(X3); + Z3 = curve.FromBigInteger(BigInteger.One); + } + else + { + B = B.Square(); + + ECFieldElement AU1 = A.Multiply(U1); + ECFieldElement AU2 = A.Multiply(U2); + + X3 = AU1.Multiply(AU2); + if (X3.IsZero) + { + return new SecT233K1Point(curve, X3, curve.B, IsCompressed); + } + + ECFieldElement ABZ2 = A.Multiply(B); + if (!Z2IsOne) + { + ABZ2 = ABZ2.Multiply(Z2); + } + + L3 = AU2.Add(B).SquarePlusProduct(ABZ2, L1.Add(Z1)); + + Z3 = ABZ2; + if (!Z1IsOne) + { + Z3 = Z3.Multiply(Z1); + } + } + + return new SecT233K1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + { + return this; + } + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is its own additive inverse + return curve.Infinity; + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement Z1Sq = Z1IsOne ? Z1 : Z1.Square(); + ECFieldElement T; + if (Z1IsOne) + { + T = L1.Square().Add(L1); + } + else + { + T = L1.Add(Z1).Multiply(L1); + } + + if (T.IsZero) + { + return new SecT233K1Point(curve, T, curve.B, IsCompressed); + } + + ECFieldElement X3 = T.Square(); + ECFieldElement Z3 = Z1IsOne ? T : T.Multiply(Z1Sq); + + ECFieldElement t1 = L1.Add(X1).Square(); + ECFieldElement t2 = Z1IsOne ? Z1 : Z1Sq.Square(); + ECFieldElement L3 = t1.Add(T).Add(Z1Sq).Multiply(t1).Add(t2).Add(X3).Add(Z3); + + return new SecT233K1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is its own additive inverse + return b; + } + + // NOTE: TwicePlus() only optimized for lambda-affine argument + ECFieldElement X2 = b.RawXCoord, Z2 = b.RawZCoords[0]; + if (X2.IsZero || !Z2.IsOne) + { + return Twice().Add(b); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord; + + ECFieldElement X1Sq = X1.Square(); + ECFieldElement L1Sq = L1.Square(); + ECFieldElement Z1Sq = Z1.Square(); + ECFieldElement L1Z1 = L1.Multiply(Z1); + + ECFieldElement T = L1Sq.Add(L1Z1); + ECFieldElement L2plus1 = L2.AddOne(); + ECFieldElement A = L2plus1.Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); + ECFieldElement X2Z1Sq = X2.Multiply(Z1Sq); + ECFieldElement B = X2Z1Sq.Add(T).Square(); + + if (B.IsZero) + { + if (A.IsZero) + { + return b.Twice(); + } + + return curve.Infinity; + } + + if (A.IsZero) + { + return new SecT233K1Point(curve, A, curve.B, IsCompressed); + } + + ECFieldElement X3 = A.Square().Multiply(X2Z1Sq); + ECFieldElement Z3 = A.Multiply(B).Multiply(Z1Sq); + ECFieldElement L3 = A.Add(B).Square().MultiplyPlusProduct(T, L2plus1, Z3); + + return new SecT233K1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Negate() + { + if (this.IsInfinity) + return this; + + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return this; + + // L is actually Lambda (X + Y/X) here + ECFieldElement L = this.RawYCoord, Z = this.RawZCoords[0]; + return new SecT233K1Point(Curve, X, L.Add(Z), new ECFieldElement[] { Z }, IsCompressed); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT233K1Point.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT233K1Point.cs.meta new file mode 100644 index 0000000..758d5d9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT233K1Point.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e29d9908e8b94034f80bee5bdb201965 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT233R1Curve.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT233R1Curve.cs new file mode 100644 index 0000000..7b7e593 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT233R1Curve.cs @@ -0,0 +1,177 @@ +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT233R1Curve + : AbstractF2mCurve + { + private const int SECT233R1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT233R1_FE_LONGS = 4; + private static readonly ECFieldElement[] SECT233R1_AFFINE_ZS = new ECFieldElement[] { new SecT233FieldElement(BigInteger.One) }; + + protected readonly SecT233R1Point m_infinity; + + public SecT233R1Curve() + : base(233, 74, 0, 0) + { + this.m_infinity = new SecT233R1Point(this, null, null); + + this.m_a = FromBigInteger(BigInteger.One); + this.m_b = FromBigInteger(new BigInteger(1, Hex.DecodeStrict("0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD"))); + this.m_order = new BigInteger(1, Hex.DecodeStrict("01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7")); + this.m_cofactor = BigInteger.Two; + + this.m_coord = SECT233R1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecT233R1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_LAMBDA_PROJECTIVE: + return true; + default: + return false; + } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return 233; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecT233FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecT233R1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecT233R1Point(this, x, y, zs, withCompression); + } + + public override bool IsKoblitz + { + get { return false; } + } + + public virtual int M + { + get { return 233; } + } + + public virtual bool IsTrinomial + { + get { return true; } + } + + public virtual int K1 + { + get { return 74; } + } + + public virtual int K2 + { + get { return 0; } + } + + public virtual int K3 + { + get { return 0; } + } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + ulong[] table = new ulong[len * SECT233R1_FE_LONGS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat256.Copy64(((SecT233FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECT233R1_FE_LONGS; + Nat256.Copy64(((SecT233FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECT233R1_FE_LONGS; + } + } + + return new SecT233R1LookupTable(this, table, len); + } + + private class SecT233R1LookupTable + : AbstractECLookupTable + { + private readonly SecT233R1Curve m_outer; + private readonly ulong[] m_table; + private readonly int m_size; + + internal SecT233R1LookupTable(SecT233R1Curve outer, ulong[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public override int Size + { + get { return m_size; } + } + + public override ECPoint Lookup(int index) + { + ulong[] x = Nat256.Create64(), y = Nat256.Create64(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + ulong MASK = (ulong)(long)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECT233R1_FE_LONGS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECT233R1_FE_LONGS + j] & MASK; + } + + pos += (SECT233R1_FE_LONGS * 2); + } + + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + ulong[] x = Nat256.Create64(), y = Nat256.Create64(); + int pos = index * SECT233R1_FE_LONGS * 2; + + for (int j = 0; j < SECT233R1_FE_LONGS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECT233R1_FE_LONGS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(ulong[] x, ulong[] y) + { + return m_outer.CreateRawPoint(new SecT233FieldElement(x), new SecT233FieldElement(y), SECT233R1_AFFINE_ZS, false); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT233R1Curve.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT233R1Curve.cs.meta new file mode 100644 index 0000000..5d8ac54 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT233R1Curve.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e262115b25c65a04c83ad6cdcd28392b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT233R1Point.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT233R1Point.cs new file mode 100644 index 0000000..b9c6ce6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT233R1Point.cs @@ -0,0 +1,278 @@ +using System; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT233R1Point + : AbstractF2mPoint + { + /** + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecT233R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * @deprecated per-point compression property will be removed, refer {@link #getEncoded(bool)} + */ + public SecT233R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecT233R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecT233R1Point(null, AffineXCoord, AffineYCoord); + } + + public override ECFieldElement YCoord + { + get + { + ECFieldElement X = RawXCoord, L = RawYCoord; + + if (this.IsInfinity || X.IsZero) + return L; + + // Y is actually Lambda (X + Y/X) here; convert to affine value on the fly + ECFieldElement Y = L.Add(X).Multiply(X); + + ECFieldElement Z = RawZCoords[0]; + if (!Z.IsOne) + { + Y = Y.Divide(Z); + } + + return Y; + } + } + + protected internal override bool CompressionYTilde + { + get + { + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return false; + + ECFieldElement Y = this.RawYCoord; + + // Y is actually Lambda (X + Y/X) here + return Y.TestBitZero() != X.TestBitZero(); + } + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + ECFieldElement X2 = b.RawXCoord; + + if (X1.IsZero) + { + if (X2.IsZero) + return curve.Infinity; + + return b.Add(this); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord, Z2 = b.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement U2 = X2, S2 = L2; + if (!Z1IsOne) + { + U2 = U2.Multiply(Z1); + S2 = S2.Multiply(Z1); + } + + bool Z2IsOne = Z2.IsOne; + ECFieldElement U1 = X1, S1 = L1; + if (!Z2IsOne) + { + U1 = U1.Multiply(Z2); + S1 = S1.Multiply(Z2); + } + + ECFieldElement A = S1.Add(S2); + ECFieldElement B = U1.Add(U2); + + if (B.IsZero) + { + if (A.IsZero) + return Twice(); + + return curve.Infinity; + } + + ECFieldElement X3, L3, Z3; + if (X2.IsZero) + { + // TODO This can probably be optimized quite a bit + ECPoint p = this.Normalize(); + X1 = p.XCoord; + ECFieldElement Y1 = p.YCoord; + + ECFieldElement Y2 = L2; + ECFieldElement L = Y1.Add(Y2).Divide(X1); + + X3 = L.Square().Add(L).Add(X1).AddOne(); + if (X3.IsZero) + { + return new SecT233R1Point(curve, X3, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement Y3 = L.Multiply(X1.Add(X3)).Add(X3).Add(Y1); + L3 = Y3.Divide(X3).Add(X3); + Z3 = curve.FromBigInteger(BigInteger.One); + } + else + { + B = B.Square(); + + ECFieldElement AU1 = A.Multiply(U1); + ECFieldElement AU2 = A.Multiply(U2); + + X3 = AU1.Multiply(AU2); + if (X3.IsZero) + { + return new SecT233R1Point(curve, X3, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement ABZ2 = A.Multiply(B); + if (!Z2IsOne) + { + ABZ2 = ABZ2.Multiply(Z2); + } + + L3 = AU2.Add(B).SquarePlusProduct(ABZ2, L1.Add(Z1)); + + Z3 = ABZ2; + if (!Z1IsOne) + { + Z3 = Z3.Multiply(Z1); + } + } + + return new SecT233R1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is its own additive inverse + return curve.Infinity; + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement L1Z1 = Z1IsOne ? L1 : L1.Multiply(Z1); + ECFieldElement Z1Sq = Z1IsOne ? Z1 : Z1.Square(); + ECFieldElement T = L1.Square().Add(L1Z1).Add(Z1Sq); + if (T.IsZero) + { + return new SecT233R1Point(curve, T, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement X3 = T.Square(); + ECFieldElement Z3 = Z1IsOne ? T : T.Multiply(Z1Sq); + + ECFieldElement X1Z1 = Z1IsOne ? X1 : X1.Multiply(Z1); + ECFieldElement L3 = X1Z1.SquarePlusProduct(T, L1Z1).Add(X3).Add(Z3); + + return new SecT233R1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is its own additive inverse + return b; + } + + ECFieldElement X2 = b.RawXCoord, Z2 = b.RawZCoords[0]; + if (X2.IsZero || !Z2.IsOne) + { + return Twice().Add(b); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord; + + ECFieldElement X1Sq = X1.Square(); + ECFieldElement L1Sq = L1.Square(); + ECFieldElement Z1Sq = Z1.Square(); + ECFieldElement L1Z1 = L1.Multiply(Z1); + + ECFieldElement T = Z1Sq.Add(L1Sq).Add(L1Z1); + ECFieldElement A = L2.Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); + ECFieldElement X2Z1Sq = X2.Multiply(Z1Sq); + ECFieldElement B = X2Z1Sq.Add(T).Square(); + + if (B.IsZero) + { + if (A.IsZero) + return b.Twice(); + + return curve.Infinity; + } + + if (A.IsZero) + { + return new SecT233R1Point(curve, A, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement X3 = A.Square().Multiply(X2Z1Sq); + ECFieldElement Z3 = A.Multiply(B).Multiply(Z1Sq); + ECFieldElement L3 = A.Add(B).Square().MultiplyPlusProduct(T, L2.AddOne(), Z3); + + return new SecT233R1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Negate() + { + if (this.IsInfinity) + return this; + + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return this; + + // L is actually Lambda (X + Y/X) here + ECFieldElement L = this.RawYCoord, Z = this.RawZCoords[0]; + return new SecT233R1Point(Curve, X, L.Add(Z), new ECFieldElement[] { Z }, IsCompressed); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT233R1Point.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT233R1Point.cs.meta new file mode 100644 index 0000000..18f664f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT233R1Point.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 22c24c59c0ef3b441b4d878c0f1dac0f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT239Field.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT239Field.cs new file mode 100644 index 0000000..ce2e3ba --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT239Field.cs @@ -0,0 +1,344 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT239Field + { + private const ulong M47 = ulong.MaxValue >> 17; + private const ulong M60 = ulong.MaxValue >> 4; + + public static void Add(ulong[] x, ulong[] y, ulong[] z) + { + z[0] = x[0] ^ y[0]; + z[1] = x[1] ^ y[1]; + z[2] = x[2] ^ y[2]; + z[3] = x[3] ^ y[3]; + } + + public static void AddExt(ulong[] xx, ulong[] yy, ulong[] zz) + { + zz[0] = xx[0] ^ yy[0]; + zz[1] = xx[1] ^ yy[1]; + zz[2] = xx[2] ^ yy[2]; + zz[3] = xx[3] ^ yy[3]; + zz[4] = xx[4] ^ yy[4]; + zz[5] = xx[5] ^ yy[5]; + zz[6] = xx[6] ^ yy[6]; + zz[7] = xx[7] ^ yy[7]; + } + + public static void AddOne(ulong[] x, ulong[] z) + { + z[0] = x[0] ^ 1UL; + z[1] = x[1]; + z[2] = x[2]; + z[3] = x[3]; + } + + private static void AddTo(ulong[] x, ulong[] z) + { + z[0] ^= x[0]; + z[1] ^= x[1]; + z[2] ^= x[2]; + z[3] ^= x[3]; + } + + public static ulong[] FromBigInteger(BigInteger x) + { + return Nat.FromBigInteger64(239, x); + } + + public static void HalfTrace(ulong[] x, ulong[] z) + { + ulong[] tt = Nat256.CreateExt64(); + + Nat256.Copy64(x, z); + for (int i = 1; i < 239; i += 2) + { + ImplSquare(z, tt); + Reduce(tt, z); + ImplSquare(z, tt); + Reduce(tt, z); + AddTo(x, z); + } + } + + public static void Invert(ulong[] x, ulong[] z) + { + if (Nat256.IsZero64(x)) + throw new InvalidOperationException(); + + // Itoh-Tsujii inversion + + ulong[] t0 = Nat256.Create64(); + ulong[] t1 = Nat256.Create64(); + + Square(x, t0); + Multiply(t0, x, t0); + Square(t0, t0); + Multiply(t0, x, t0); + SquareN(t0, 3, t1); + Multiply(t1, t0, t1); + Square(t1, t1); + Multiply(t1, x, t1); + SquareN(t1, 7, t0); + Multiply(t0, t1, t0); + SquareN(t0, 14, t1); + Multiply(t1, t0, t1); + Square(t1, t1); + Multiply(t1, x, t1); + SquareN(t1, 29, t0); + Multiply(t0, t1, t0); + Square(t0, t0); + Multiply(t0, x, t0); + SquareN(t0, 59, t1); + Multiply(t1, t0, t1); + Square(t1, t1); + Multiply(t1, x, t1); + SquareN(t1, 119, t0); + Multiply(t0, t1, t0); + Square(t0, z); + } + + public static void Multiply(ulong[] x, ulong[] y, ulong[] z) + { + ulong[] tt = Nat256.CreateExt64(); + ImplMultiply(x, y, tt); + Reduce(tt, z); + } + + public static void MultiplyAddToExt(ulong[] x, ulong[] y, ulong[] zz) + { + ulong[] tt = Nat256.CreateExt64(); + ImplMultiply(x, y, tt); + AddExt(zz, tt, zz); + } + + public static void Reduce(ulong[] xx, ulong[] z) + { + ulong x0 = xx[0], x1 = xx[1], x2 = xx[2], x3 = xx[3]; + ulong x4 = xx[4], x5 = xx[5], x6 = xx[6], x7 = xx[7]; + + x3 ^= (x7 << 17); + x4 ^= (x7 >> 47); + x5 ^= (x7 << 47); + x6 ^= (x7 >> 17); + + x2 ^= (x6 << 17); + x3 ^= (x6 >> 47); + x4 ^= (x6 << 47); + x5 ^= (x6 >> 17); + + x1 ^= (x5 << 17); + x2 ^= (x5 >> 47); + x3 ^= (x5 << 47); + x4 ^= (x5 >> 17); + + x0 ^= (x4 << 17); + x1 ^= (x4 >> 47); + x2 ^= (x4 << 47); + x3 ^= (x4 >> 17); + + ulong t = x3 >> 47; + z[0] = x0 ^ t; + z[1] = x1; + z[2] = x2 ^ (t << 30); + z[3] = x3 & M47; + } + + public static void Reduce17(ulong[] z, int zOff) + { + ulong z3 = z[zOff + 3], t = z3 >> 47; + z[zOff ] ^= t; + z[zOff + 2] ^= (t << 30); + z[zOff + 3] = z3 & M47; + } + + public static void Sqrt(ulong[] x, ulong[] z) + { + ulong u0, u1; + u0 = Interleave.Unshuffle(x[0]); u1 = Interleave.Unshuffle(x[1]); + ulong e0 = (u0 & 0x00000000FFFFFFFFUL) | (u1 << 32); + ulong c0 = (u0 >> 32) | (u1 & 0xFFFFFFFF00000000UL); + + u0 = Interleave.Unshuffle(x[2]); u1 = Interleave.Unshuffle(x[3]); + ulong e1 = (u0 & 0x00000000FFFFFFFFUL) | (u1 << 32); + ulong c1 = (u0 >> 32) | (u1 & 0xFFFFFFFF00000000UL); + + ulong c2, c3; + c3 = (c1 >> 49); + c2 = (c0 >> 49) | (c1 << 15); + c1 ^= (c0 << 15); + + ulong[] tt = Nat256.CreateExt64(); + + int[] shifts = { 39, 120 }; + for (int i = 0; i < shifts.Length; ++i) + { + int w = shifts[i] >> 6, s = shifts[i] & 63; + Debug.Assert(s != 0); + tt[w ] ^= (c0 << s); + tt[w + 1] ^= (c1 << s) | (c0 >> -s); + tt[w + 2] ^= (c2 << s) | (c1 >> -s); + tt[w + 3] ^= (c3 << s) | (c2 >> -s); + tt[w + 4] ^= (c3 >> -s); + } + + Reduce(tt, z); + + z[0] ^= e0; + z[1] ^= e1; + } + + public static void Square(ulong[] x, ulong[] z) + { + ulong[] tt = Nat256.CreateExt64(); + ImplSquare(x, tt); + Reduce(tt, z); + } + + public static void SquareAddToExt(ulong[] x, ulong[] zz) + { + ulong[] tt = Nat256.CreateExt64(); + ImplSquare(x, tt); + AddExt(zz, tt, zz); + } + + public static void SquareN(ulong[] x, int n, ulong[] z) + { + Debug.Assert(n > 0); + + ulong[] tt = Nat256.CreateExt64(); + ImplSquare(x, tt); + Reduce(tt, z); + + while (--n > 0) + { + ImplSquare(z, tt); + Reduce(tt, z); + } + } + + public static uint Trace(ulong[] x) + { + // Non-zero-trace bits: 0, 81, 162 + return (uint)(x[0] ^ (x[1] >> 17) ^ (x[2] >> 34)) & 1U; + } + + protected static void ImplCompactExt(ulong[] zz) + { + ulong z0 = zz[0], z1 = zz[1], z2 = zz[2], z3 = zz[3], z4 = zz[4], z5 = zz[5], z6 = zz[6], z7 = zz[7]; + zz[0] = z0 ^ (z1 << 60); + zz[1] = (z1 >> 4) ^ (z2 << 56); + zz[2] = (z2 >> 8) ^ (z3 << 52); + zz[3] = (z3 >> 12) ^ (z4 << 48); + zz[4] = (z4 >> 16) ^ (z5 << 44); + zz[5] = (z5 >> 20) ^ (z6 << 40); + zz[6] = (z6 >> 24) ^ (z7 << 36); + zz[7] = (z7 >> 28); + } + + protected static void ImplExpand(ulong[] x, ulong[] z) + { + ulong x0 = x[0], x1 = x[1], x2 = x[2], x3 = x[3]; + z[0] = x0 & M60; + z[1] = ((x0 >> 60) ^ (x1 << 4)) & M60; + z[2] = ((x1 >> 56) ^ (x2 << 8)) & M60; + z[3] = ((x2 >> 52) ^ (x3 << 12)); + } + + protected static void ImplMultiply(ulong[] x, ulong[] y, ulong[] zz) + { + /* + * "Two-level seven-way recursion" as described in "Batch binary Edwards", Daniel J. Bernstein. + */ + + ulong[] f = new ulong[4], g = new ulong[4]; + ImplExpand(x, f); + ImplExpand(y, g); + + ulong[] u = new ulong[8]; + + ImplMulwAcc(u, f[0], g[0], zz, 0); + ImplMulwAcc(u, f[1], g[1], zz, 1); + ImplMulwAcc(u, f[2], g[2], zz, 2); + ImplMulwAcc(u, f[3], g[3], zz, 3); + + // U *= (1 - t^n) + for (int i = 5; i > 0; --i) + { + zz[i] ^= zz[i - 1]; + } + + ImplMulwAcc(u, f[0] ^ f[1], g[0] ^ g[1], zz, 1); + ImplMulwAcc(u, f[2] ^ f[3], g[2] ^ g[3], zz, 3); + + // V *= (1 - t^2n) + for (int i = 7; i > 1; --i) + { + zz[i] ^= zz[i - 2]; + } + + // Double-length recursion + { + ulong c0 = f[0] ^ f[2], c1 = f[1] ^ f[3]; + ulong d0 = g[0] ^ g[2], d1 = g[1] ^ g[3]; + ImplMulwAcc(u, c0 ^ c1, d0 ^ d1, zz, 3); + ulong[] t = new ulong[3]; + ImplMulwAcc(u, c0, d0, t, 0); + ImplMulwAcc(u, c1, d1, t, 1); + ulong t0 = t[0], t1 = t[1], t2 = t[2]; + zz[2] ^= t0; + zz[3] ^= t0 ^ t1; + zz[4] ^= t2 ^ t1; + zz[5] ^= t2; + } + + ImplCompactExt(zz); + } + + protected static void ImplMulwAcc(ulong[] u, ulong x, ulong y, ulong[] z, int zOff) + { + Debug.Assert(x >> 60 == 0); + Debug.Assert(y >> 60 == 0); + + //u[0] = 0; + u[1] = y; + u[2] = u[1] << 1; + u[3] = u[2] ^ y; + u[4] = u[2] << 1; + u[5] = u[4] ^ y; + u[6] = u[3] << 1; + u[7] = u[6] ^ y; + + uint j = (uint)x; + ulong g, h = 0, l = u[j & 7] + ^ (u[(j >> 3) & 7] << 3); + int k = 54; + do + { + j = (uint)(x >> k); + g = u[j & 7] + ^ u[(j >> 3) & 7] << 3; + l ^= (g << k); + h ^= (g >> -k); + } + while ((k -= 6) > 0); + + h ^= ((x & 0x0820820820820820L) & (ulong)(((long)y << 4) >> 63)) >> 5; + + Debug.Assert(h >> 55 == 0); + + z[zOff ] ^= l & M60; + z[zOff + 1] ^= (l >> 60) ^ (h << 4); + } + + protected static void ImplSquare(ulong[] x, ulong[] zz) + { + Interleave.Expand64To128(x, 0, 4, zz, 0); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT239Field.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT239Field.cs.meta new file mode 100644 index 0000000..da1ede0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT239Field.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 062c57030a50b3b419a9165d896bc37e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT239FieldElement.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT239FieldElement.cs new file mode 100644 index 0000000..9f1bf67 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT239FieldElement.cs @@ -0,0 +1,233 @@ +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT239FieldElement + : AbstractF2mFieldElement + { + protected internal readonly ulong[] x; + + public SecT239FieldElement(BigInteger x) + { + if (x == null || x.SignValue < 0 || x.BitLength > 239) + throw new ArgumentException("value invalid for SecT239FieldElement", "x"); + + this.x = SecT239Field.FromBigInteger(x); + } + + public SecT239FieldElement() + { + this.x = Nat256.Create64(); + } + + protected internal SecT239FieldElement(ulong[] x) + { + this.x = x; + } + + public override bool IsOne + { + get { return Nat256.IsOne64(x); } + } + + public override bool IsZero + { + get { return Nat256.IsZero64(x); } + } + + public override bool TestBitZero() + { + return (x[0] & 1L) != 0L; + } + + public override BigInteger ToBigInteger() + { + return Nat256.ToBigInteger64(x); + } + + public override string FieldName + { + get { return "SecT239Field"; } + } + + public override int FieldSize + { + get { return 239; } + } + + public override ECFieldElement Add(ECFieldElement b) + { + ulong[] z = Nat256.Create64(); + SecT239Field.Add(x, ((SecT239FieldElement)b).x, z); + return new SecT239FieldElement(z); + } + + public override ECFieldElement AddOne() + { + ulong[] z = Nat256.Create64(); + SecT239Field.AddOne(x, z); + return new SecT239FieldElement(z); + } + + public override ECFieldElement Subtract(ECFieldElement b) + { + // Addition and Subtraction are the same in F2m + return Add(b); + } + + public override ECFieldElement Multiply(ECFieldElement b) + { + ulong[] z = Nat256.Create64(); + SecT239Field.Multiply(x, ((SecT239FieldElement)b).x, z); + return new SecT239FieldElement(z); + } + + public override ECFieldElement MultiplyMinusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) + { + return MultiplyPlusProduct(b, x, y); + } + + public override ECFieldElement MultiplyPlusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) + { + ulong[] ax = this.x, bx = ((SecT239FieldElement)b).x; + ulong[] xx = ((SecT239FieldElement)x).x, yx = ((SecT239FieldElement)y).x; + + ulong[] tt = Nat256.CreateExt64(); + SecT239Field.MultiplyAddToExt(ax, bx, tt); + SecT239Field.MultiplyAddToExt(xx, yx, tt); + + ulong[] z = Nat256.Create64(); + SecT239Field.Reduce(tt, z); + return new SecT239FieldElement(z); + } + + public override ECFieldElement Divide(ECFieldElement b) + { + return Multiply(b.Invert()); + } + + public override ECFieldElement Negate() + { + return this; + } + + public override ECFieldElement Square() + { + ulong[] z = Nat256.Create64(); + SecT239Field.Square(x, z); + return new SecT239FieldElement(z); + } + + public override ECFieldElement SquareMinusProduct(ECFieldElement x, ECFieldElement y) + { + return SquarePlusProduct(x, y); + } + + public override ECFieldElement SquarePlusProduct(ECFieldElement x, ECFieldElement y) + { + ulong[] ax = this.x; + ulong[] xx = ((SecT239FieldElement)x).x, yx = ((SecT239FieldElement)y).x; + + ulong[] tt = Nat256.CreateExt64(); + SecT239Field.SquareAddToExt(ax, tt); + SecT239Field.MultiplyAddToExt(xx, yx, tt); + + ulong[] z = Nat256.Create64(); + SecT239Field.Reduce(tt, z); + return new SecT239FieldElement(z); + } + + public override ECFieldElement SquarePow(int pow) + { + if (pow < 1) + return this; + + ulong[] z = Nat256.Create64(); + SecT239Field.SquareN(x, pow, z); + return new SecT239FieldElement(z); + } + + public override ECFieldElement HalfTrace() + { + ulong[] z = Nat256.Create64(); + SecT239Field.HalfTrace(x, z); + return new SecT239FieldElement(z); + } + + public override bool HasFastTrace + { + get { return true; } + } + + public override int Trace() + { + return (int)SecT239Field.Trace(x); + } + + public override ECFieldElement Invert() + { + ulong[] z = Nat256.Create64(); + SecT239Field.Invert(x, z); + return new SecT239FieldElement(z); + } + + public override ECFieldElement Sqrt() + { + ulong[] z = Nat256.Create64(); + SecT239Field.Sqrt(x, z); + return new SecT239FieldElement(z); + } + + public virtual int Representation + { + get { return F2mFieldElement.Tpb; } + } + + public virtual int M + { + get { return 239; } + } + + public virtual int K1 + { + get { return 158; } + } + + public virtual int K2 + { + get { return 0; } + } + + public virtual int K3 + { + get { return 0; } + } + + public override bool Equals(object obj) + { + return Equals(obj as SecT239FieldElement); + } + + public override bool Equals(ECFieldElement other) + { + return Equals(other as SecT239FieldElement); + } + + public virtual bool Equals(SecT239FieldElement other) + { + if (this == other) + return true; + if (null == other) + return false; + return Nat256.Eq64(x, other.x); + } + + public override int GetHashCode() + { + return 23900158 ^ Arrays.GetHashCode(x, 0, 4); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT239FieldElement.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT239FieldElement.cs.meta new file mode 100644 index 0000000..a465244 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT239FieldElement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7a3e069ddf5335443a21cb23a1c57e22 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT239K1Curve.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT239K1Curve.cs new file mode 100644 index 0000000..48854ce --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT239K1Curve.cs @@ -0,0 +1,183 @@ +using System; + +using Org.BouncyCastle.Math.EC.Multiplier; +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT239K1Curve + : AbstractF2mCurve + { + private const int SECT239K1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT239K1_FE_LONGS = 4; + private static readonly ECFieldElement[] SECT239K1_AFFINE_ZS = new ECFieldElement[] { new SecT239FieldElement(BigInteger.One) }; + + protected readonly SecT239K1Point m_infinity; + + public SecT239K1Curve() + : base(239, 158, 0, 0) + { + this.m_infinity = new SecT239K1Point(this, null, null); + + this.m_a = FromBigInteger(BigInteger.Zero); + this.m_b = FromBigInteger(BigInteger.One); + this.m_order = new BigInteger(1, Hex.DecodeStrict("2000000000000000000000000000005A79FEC67CB6E91F1C1DA800E478A5")); + this.m_cofactor = BigInteger.ValueOf(4); + + this.m_coord = SECT239K1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecT239K1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_LAMBDA_PROJECTIVE: + return true; + default: + return false; + } + } + + protected override ECMultiplier CreateDefaultMultiplier() + { + return new WTauNafMultiplier(); + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return 239; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecT239FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecT239K1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecT239K1Point(this, x, y, zs, withCompression); + } + + public override bool IsKoblitz + { + get { return true; } + } + + public virtual int M + { + get { return 239; } + } + + public virtual bool IsTrinomial + { + get { return true; } + } + + public virtual int K1 + { + get { return 158; } + } + + public virtual int K2 + { + get { return 0; } + } + + public virtual int K3 + { + get { return 0; } + } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + ulong[] table = new ulong[len * SECT239K1_FE_LONGS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat256.Copy64(((SecT239FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECT239K1_FE_LONGS; + Nat256.Copy64(((SecT239FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECT239K1_FE_LONGS; + } + } + + return new SecT239K1LookupTable(this, table, len); + } + + private class SecT239K1LookupTable + : AbstractECLookupTable + { + private readonly SecT239K1Curve m_outer; + private readonly ulong[] m_table; + private readonly int m_size; + + internal SecT239K1LookupTable(SecT239K1Curve outer, ulong[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public override int Size + { + get { return m_size; } + } + + public override ECPoint Lookup(int index) + { + ulong[] x = Nat256.Create64(), y = Nat256.Create64(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + ulong MASK = (ulong)(long)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECT239K1_FE_LONGS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECT239K1_FE_LONGS + j] & MASK; + } + + pos += (SECT239K1_FE_LONGS * 2); + } + + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + ulong[] x = Nat256.Create64(), y = Nat256.Create64(); + int pos = index * SECT239K1_FE_LONGS * 2; + + for (int j = 0; j < SECT239K1_FE_LONGS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECT239K1_FE_LONGS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(ulong[] x, ulong[] y) + { + return m_outer.CreateRawPoint(new SecT239FieldElement(x), new SecT239FieldElement(y), SECT239K1_AFFINE_ZS, false); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT239K1Curve.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT239K1Curve.cs.meta new file mode 100644 index 0000000..323d767 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT239K1Curve.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f2b2c9d9f62795b4badc89a33be89cec +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT239K1Point.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT239K1Point.cs new file mode 100644 index 0000000..36b4606 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT239K1Point.cs @@ -0,0 +1,290 @@ +using System; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT239K1Point + : AbstractF2mPoint + { + /** + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecT239K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * @deprecated per-point compression property will be removed, refer {@link #getEncoded(bool)} + */ + public SecT239K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecT239K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecT239K1Point(null, this.AffineXCoord, this.AffineYCoord); // earlier JDK + } + + public override ECFieldElement YCoord + { + get + { + ECFieldElement X = RawXCoord, L = RawYCoord; + + if (this.IsInfinity || X.IsZero) + return L; + + // Y is actually Lambda (X + Y/X) here; convert to affine value on the fly + ECFieldElement Y = L.Add(X).Multiply(X); + + ECFieldElement Z = RawZCoords[0]; + if (!Z.IsOne) + { + Y = Y.Divide(Z); + } + + return Y; + } + } + + protected internal override bool CompressionYTilde + { + get + { + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return false; + + ECFieldElement Y = this.RawYCoord; + + // Y is actually Lambda (X + Y/X) here + return Y.TestBitZero() != X.TestBitZero(); + } + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + ECFieldElement X2 = b.RawXCoord; + + if (X1.IsZero) + { + if (X2.IsZero) + return curve.Infinity; + + return b.Add(this); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord, Z2 = b.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement U2 = X2, S2 = L2; + if (!Z1IsOne) + { + U2 = U2.Multiply(Z1); + S2 = S2.Multiply(Z1); + } + + bool Z2IsOne = Z2.IsOne; + ECFieldElement U1 = X1, S1 = L1; + if (!Z2IsOne) + { + U1 = U1.Multiply(Z2); + S1 = S1.Multiply(Z2); + } + + ECFieldElement A = S1.Add(S2); + ECFieldElement B = U1.Add(U2); + + if (B.IsZero) + { + if (A.IsZero) + return Twice(); + + return curve.Infinity; + } + + ECFieldElement X3, L3, Z3; + if (X2.IsZero) + { + // TODO This can probably be optimized quite a bit + ECPoint p = this.Normalize(); + X1 = p.XCoord; + ECFieldElement Y1 = p.YCoord; + + ECFieldElement Y2 = L2; + ECFieldElement L = Y1.Add(Y2).Divide(X1); + + X3 = L.Square().Add(L).Add(X1); + if (X3.IsZero) + { + return new SecT239K1Point(curve, X3, curve.B, IsCompressed); + } + + ECFieldElement Y3 = L.Multiply(X1.Add(X3)).Add(X3).Add(Y1); + L3 = Y3.Divide(X3).Add(X3); + Z3 = curve.FromBigInteger(BigInteger.One); + } + else + { + B = B.Square(); + + ECFieldElement AU1 = A.Multiply(U1); + ECFieldElement AU2 = A.Multiply(U2); + + X3 = AU1.Multiply(AU2); + if (X3.IsZero) + { + return new SecT239K1Point(curve, X3, curve.B, IsCompressed); + } + + ECFieldElement ABZ2 = A.Multiply(B); + if (!Z2IsOne) + { + ABZ2 = ABZ2.Multiply(Z2); + } + + L3 = AU2.Add(B).SquarePlusProduct(ABZ2, L1.Add(Z1)); + + Z3 = ABZ2; + if (!Z1IsOne) + { + Z3 = Z3.Multiply(Z1); + } + } + + return new SecT239K1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is its own additive inverse + return curve.Infinity; + } + + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement Z1Sq = Z1IsOne ? Z1 : Z1.Square(); + ECFieldElement T; + if (Z1IsOne) + { + T = L1.Square().Add(L1); + } + else + { + T = L1.Add(Z1).Multiply(L1); + } + + if (T.IsZero) + { + return new SecT239K1Point(curve, T, curve.B, IsCompressed); + } + + ECFieldElement X3 = T.Square(); + ECFieldElement Z3 = Z1IsOne ? T : T.Multiply(Z1Sq); + + ECFieldElement t1 = L1.Add(X1).Square(); + ECFieldElement t2 = Z1IsOne ? Z1 : Z1Sq.Square(); + ECFieldElement L3 = t1.Add(T).Add(Z1Sq).Multiply(t1).Add(t2).Add(X3).Add(Z3); + + return new SecT239K1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is its own additive inverse + return b; + } + + // NOTE: TwicePlus() only optimized for lambda-affine argument + ECFieldElement X2 = b.RawXCoord, Z2 = b.RawZCoords[0]; + if (X2.IsZero || !Z2.IsOne) + { + return Twice().Add(b); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord; + + ECFieldElement X1Sq = X1.Square(); + ECFieldElement L1Sq = L1.Square(); + ECFieldElement Z1Sq = Z1.Square(); + ECFieldElement L1Z1 = L1.Multiply(Z1); + + ECFieldElement T = L1Sq.Add(L1Z1); + ECFieldElement L2plus1 = L2.AddOne(); + ECFieldElement A = L2plus1.Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); + ECFieldElement X2Z1Sq = X2.Multiply(Z1Sq); + ECFieldElement B = X2Z1Sq.Add(T).Square(); + + if (B.IsZero) + { + if (A.IsZero) + return b.Twice(); + + return curve.Infinity; + } + + if (A.IsZero) + { + return new SecT239K1Point(curve, A, curve.B, IsCompressed); + } + + ECFieldElement X3 = A.Square().Multiply(X2Z1Sq); + ECFieldElement Z3 = A.Multiply(B).Multiply(Z1Sq); + ECFieldElement L3 = A.Add(B).Square().MultiplyPlusProduct(T, L2plus1, Z3); + + return new SecT239K1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Negate() + { + if (this.IsInfinity) + return this; + + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return this; + + // L is actually Lambda (X + Y/X) here + ECFieldElement L = this.RawYCoord, Z = this.RawZCoords[0]; + return new SecT239K1Point(Curve, X, L.Add(Z), new ECFieldElement[] { Z }, IsCompressed); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT239K1Point.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT239K1Point.cs.meta new file mode 100644 index 0000000..eada336 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT239K1Point.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4633dc2feab77a646bfe4f176839e89f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT283Field.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT283Field.cs new file mode 100644 index 0000000..61a1c9a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT283Field.cs @@ -0,0 +1,422 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT283Field + { + private const ulong M27 = ulong.MaxValue >> 37; + private const ulong M57 = ulong.MaxValue >> 7; + + private static readonly ulong[] ROOT_Z = new ulong[]{ 0x0C30C30C30C30808UL, 0x30C30C30C30C30C3UL, + 0x820820820820830CUL, 0x0820820820820820UL, 0x2082082UL }; + + public static void Add(ulong[] x, ulong[] y, ulong[] z) + { + z[0] = x[0] ^ y[0]; + z[1] = x[1] ^ y[1]; + z[2] = x[2] ^ y[2]; + z[3] = x[3] ^ y[3]; + z[4] = x[4] ^ y[4]; + } + + public static void AddExt(ulong[] xx, ulong[] yy, ulong[] zz) + { + zz[0] = xx[0] ^ yy[0]; + zz[1] = xx[1] ^ yy[1]; + zz[2] = xx[2] ^ yy[2]; + zz[3] = xx[3] ^ yy[3]; + zz[4] = xx[4] ^ yy[4]; + zz[5] = xx[5] ^ yy[5]; + zz[6] = xx[6] ^ yy[6]; + zz[7] = xx[7] ^ yy[7]; + zz[8] = xx[8] ^ yy[8]; + } + + public static void AddOne(ulong[] x, ulong[] z) + { + z[0] = x[0] ^ 1UL; + z[1] = x[1]; + z[2] = x[2]; + z[3] = x[3]; + z[4] = x[4]; + } + + private static void AddTo(ulong[] x, ulong[] z) + { + z[0] ^= x[0]; + z[1] ^= x[1]; + z[2] ^= x[2]; + z[3] ^= x[3]; + z[4] ^= x[4]; + } + + public static ulong[] FromBigInteger(BigInteger x) + { + return Nat.FromBigInteger64(283, x); + } + + public static void HalfTrace(ulong[] x, ulong[] z) + { + ulong[] tt = Nat.Create64(9); + + Nat320.Copy64(x, z); + for (int i = 1; i < 283; i += 2) + { + ImplSquare(z, tt); + Reduce(tt, z); + ImplSquare(z, tt); + Reduce(tt, z); + AddTo(x, z); + } + } + + public static void Invert(ulong[] x, ulong[] z) + { + if (Nat320.IsZero64(x)) + throw new InvalidOperationException(); + + // Itoh-Tsujii inversion + + ulong[] t0 = Nat320.Create64(); + ulong[] t1 = Nat320.Create64(); + + Square(x, t0); + Multiply(t0, x, t0); + SquareN(t0, 2, t1); + Multiply(t1, t0, t1); + SquareN(t1, 4, t0); + Multiply(t0, t1, t0); + SquareN(t0, 8, t1); + Multiply(t1, t0, t1); + Square(t1, t1); + Multiply(t1, x, t1); + SquareN(t1, 17, t0); + Multiply(t0, t1, t0); + Square(t0, t0); + Multiply(t0, x, t0); + SquareN(t0, 35, t1); + Multiply(t1, t0, t1); + SquareN(t1, 70, t0); + Multiply(t0, t1, t0); + Square(t0, t0); + Multiply(t0, x, t0); + SquareN(t0, 141, t1); + Multiply(t1, t0, t1); + Square(t1, z); + } + + public static void Multiply(ulong[] x, ulong[] y, ulong[] z) + { + ulong[] tt = Nat320.CreateExt64(); + ImplMultiply(x, y, tt); + Reduce(tt, z); + } + + public static void MultiplyAddToExt(ulong[] x, ulong[] y, ulong[] zz) + { + ulong[] tt = Nat320.CreateExt64(); + ImplMultiply(x, y, tt); + AddExt(zz, tt, zz); + } + + public static void Reduce(ulong[] xx, ulong[] z) + { + ulong x0 = xx[0], x1 = xx[1], x2 = xx[2], x3 = xx[3], x4 = xx[4]; + ulong x5 = xx[5], x6 = xx[6], x7 = xx[7], x8 = xx[8]; + + x3 ^= (x8 << 37) ^ (x8 << 42) ^ (x8 << 44) ^ (x8 << 49); + x4 ^= (x8 >> 27) ^ (x8 >> 22) ^ (x8 >> 20) ^ (x8 >> 15); + + x2 ^= (x7 << 37) ^ (x7 << 42) ^ (x7 << 44) ^ (x7 << 49); + x3 ^= (x7 >> 27) ^ (x7 >> 22) ^ (x7 >> 20) ^ (x7 >> 15); + + x1 ^= (x6 << 37) ^ (x6 << 42) ^ (x6 << 44) ^ (x6 << 49); + x2 ^= (x6 >> 27) ^ (x6 >> 22) ^ (x6 >> 20) ^ (x6 >> 15); + + x0 ^= (x5 << 37) ^ (x5 << 42) ^ (x5 << 44) ^ (x5 << 49); + x1 ^= (x5 >> 27) ^ (x5 >> 22) ^ (x5 >> 20) ^ (x5 >> 15); + + ulong t = x4 >> 27; + z[0] = x0 ^ t ^ (t << 5) ^ (t << 7) ^ (t << 12); + z[1] = x1; + z[2] = x2; + z[3] = x3; + z[4] = x4 & M27; + } + + public static void Reduce37(ulong[] z, int zOff) + { + ulong z4 = z[zOff + 4], t = z4 >> 27; + z[zOff ] ^= t ^ (t << 5) ^ (t << 7) ^ (t << 12); + z[zOff + 4] = z4 & M27; + } + + public static void Sqrt(ulong[] x, ulong[] z) + { + ulong[] odd = Nat320.Create64(); + + ulong u0, u1; + u0 = Interleave.Unshuffle(x[0]); u1 = Interleave.Unshuffle(x[1]); + ulong e0 = (u0 & 0x00000000FFFFFFFFUL) | (u1 << 32); + odd[0] = (u0 >> 32) | (u1 & 0xFFFFFFFF00000000UL); + + u0 = Interleave.Unshuffle(x[2]); u1 = Interleave.Unshuffle(x[3]); + ulong e1 = (u0 & 0x00000000FFFFFFFFUL) | (u1 << 32); + odd[1] = (u0 >> 32) | (u1 & 0xFFFFFFFF00000000UL); + + u0 = Interleave.Unshuffle(x[4]); + ulong e2 = (u0 & 0x00000000FFFFFFFFUL); + odd[2] = (u0 >> 32); + + Multiply(odd, ROOT_Z, z); + + z[0] ^= e0; + z[1] ^= e1; + z[2] ^= e2; + } + + public static void Square(ulong[] x, ulong[] z) + { + ulong[] tt = Nat.Create64(9); + ImplSquare(x, tt); + Reduce(tt, z); + } + + public static void SquareAddToExt(ulong[] x, ulong[] zz) + { + ulong[] tt = Nat.Create64(9); + ImplSquare(x, tt); + AddExt(zz, tt, zz); + } + + public static void SquareN(ulong[] x, int n, ulong[] z) + { + Debug.Assert(n > 0); + + ulong[] tt = Nat.Create64(9); + ImplSquare(x, tt); + Reduce(tt, z); + + while (--n > 0) + { + ImplSquare(z, tt); + Reduce(tt, z); + } + } + + public static uint Trace(ulong[] x) + { + // Non-zero-trace bits: 0, 271 + return (uint)(x[0] ^ (x[4] >> 15)) & 1U; + } + + protected static void ImplCompactExt(ulong[] zz) + { + ulong z0 = zz[0], z1 = zz[1], z2 = zz[2], z3 = zz[3], z4 = zz[4]; + ulong z5 = zz[5], z6 = zz[6], z7 = zz[7], z8 = zz[8], z9 = zz[9]; + zz[0] = z0 ^ (z1 << 57); + zz[1] = (z1 >> 7) ^ (z2 << 50); + zz[2] = (z2 >> 14) ^ (z3 << 43); + zz[3] = (z3 >> 21) ^ (z4 << 36); + zz[4] = (z4 >> 28) ^ (z5 << 29); + zz[5] = (z5 >> 35) ^ (z6 << 22); + zz[6] = (z6 >> 42) ^ (z7 << 15); + zz[7] = (z7 >> 49) ^ (z8 << 8); + zz[8] = (z8 >> 56) ^ (z9 << 1); + zz[9] = (z9 >> 63); // Zero! + } + + protected static void ImplExpand(ulong[] x, ulong[] z) + { + ulong x0 = x[0], x1 = x[1], x2 = x[2], x3 = x[3], x4 = x[4]; + z[0] = x0 & M57; + z[1] = ((x0 >> 57) ^ (x1 << 7)) & M57; + z[2] = ((x1 >> 50) ^ (x2 << 14)) & M57; + z[3] = ((x2 >> 43) ^ (x3 << 21)) & M57; + z[4] = ((x3 >> 36) ^ (x4 << 28)); + } + + //protected static void AddMs(ulong[] zz, int zOff, ulong[] p, params int[] ms) + //{ + // ulong t0 = 0, t1 = 0; + // foreach (int m in ms) + // { + // int i = (m - 1) << 1; + // t0 ^= p[i ]; + // t1 ^= p[i + 1]; + // } + // zz[zOff ] ^= t0; + // zz[zOff + 1] ^= t1; + //} + + protected static void ImplMultiply(ulong[] x, ulong[] y, ulong[] zz) + { + /* + * Formula (17) from "Some New Results on Binary Polynomial Multiplication", + * Murat Cenk and M. Anwar Hasan. + * + * The formula as given contained an error in the term t25, as noted below + */ + ulong[] a = new ulong[5], b = new ulong[5]; + ImplExpand(x, a); + ImplExpand(y, b); + + ulong[] u = zz; + ulong[] p = new ulong[26]; + + ImplMulw(u, a[0], b[0], p, 0); // m1 + ImplMulw(u, a[1], b[1], p, 2); // m2 + ImplMulw(u, a[2], b[2], p, 4); // m3 + ImplMulw(u, a[3], b[3], p, 6); // m4 + ImplMulw(u, a[4], b[4], p, 8); // m5 + + ulong u0 = a[0] ^ a[1], v0 = b[0] ^ b[1]; + ulong u1 = a[0] ^ a[2], v1 = b[0] ^ b[2]; + ulong u2 = a[2] ^ a[4], v2 = b[2] ^ b[4]; + ulong u3 = a[3] ^ a[4], v3 = b[3] ^ b[4]; + + ImplMulw(u, u1 ^ a[3], v1 ^ b[3], p, 18); // m10 + ImplMulw(u, u2 ^ a[1], v2 ^ b[1], p, 20); // m11 + + ulong A4 = u0 ^ u3 , B4 = v0 ^ v3; + ulong A5 = A4 ^ a[2], B5 = B4 ^ b[2]; + + ImplMulw(u, A4, B4, p, 22); // m12 + ImplMulw(u, A5, B5, p, 24); // m13 + + ImplMulw(u, u0, v0, p, 10); // m6 + ImplMulw(u, u1, v1, p, 12); // m7 + ImplMulw(u, u2, v2, p, 14); // m8 + ImplMulw(u, u3, v3, p, 16); // m9 + + + // Original method, corresponding to formula (16) + //AddMs(zz, 0, p, 1); + //AddMs(zz, 1, p, 1, 2, 6); + //AddMs(zz, 2, p, 1, 2, 3, 7); + //AddMs(zz, 3, p, 1, 3, 4, 5, 8, 10, 12, 13); + //AddMs(zz, 4, p, 1, 2, 4, 5, 6, 9, 10, 11, 13); + //AddMs(zz, 5, p, 1, 2, 3, 5, 7, 11, 12, 13); + //AddMs(zz, 6, p, 3, 4, 5, 8); + //AddMs(zz, 7, p, 4, 5, 9); + //AddMs(zz, 8, p, 5); + + // Improved method factors out common single-word terms + // NOTE: p1,...,p26 in the paper maps to p[0],...,p[25] here + + zz[0] = p[ 0]; + zz[9] = p[ 9]; + + ulong t1 = p[ 0] ^ p[ 1]; + ulong t2 = t1 ^ p[ 2]; + ulong t3 = t2 ^ p[10]; + + zz[1] = t3; + + ulong t4 = p[ 3] ^ p[ 4]; + ulong t5 = p[11] ^ p[12]; + ulong t6 = t4 ^ t5; + ulong t7 = t2 ^ t6; + + zz[2] = t7; + + ulong t8 = t1 ^ t4; + ulong t9 = p[ 5] ^ p[ 6]; + ulong t10 = t8 ^ t9; + ulong t11 = t10 ^ p[ 8]; + ulong t12 = p[13] ^ p[14]; + ulong t13 = t11 ^ t12; + ulong t14 = p[18] ^ p[22]; + ulong t15 = t14 ^ p[24]; + ulong t16 = t13 ^ t15; + + zz[3] = t16; + + ulong t17 = p[ 7] ^ p[ 8]; + ulong t18 = t17 ^ p[ 9]; + ulong t19 = t18 ^ p[17]; + + zz[8] = t19; + + ulong t20 = t18 ^ t9; + ulong t21 = p[15] ^ p[16]; + ulong t22 = t20 ^ t21; + + zz[7] = t22; + + ulong t23 = t22 ^ t3; + ulong t24 = p[19] ^ p[20]; + // ulong t25 = p[23] ^ p[24]; + ulong t25 = p[25] ^ p[24]; // Fixes an error in the paper: p[23] -> p{25] + ulong t26 = p[18] ^ p[23]; + ulong t27 = t24 ^ t25; + ulong t28 = t27 ^ t26; + ulong t29 = t28 ^ t23; + + zz[4] = t29; + + ulong t30 = t7 ^ t19; + ulong t31 = t27 ^ t30; + ulong t32 = p[21] ^ p[22]; + ulong t33 = t31 ^ t32; + + zz[5] = t33; + + ulong t34 = t11 ^ p[0]; + ulong t35 = t34 ^ p[9]; + ulong t36 = t35 ^ t12; + ulong t37 = t36 ^ p[21]; + ulong t38 = t37 ^ p[23]; + ulong t39 = t38 ^ p[25]; + + zz[6] = t39; + + ImplCompactExt(zz); + } + + protected static void ImplMulw(ulong[] u, ulong x, ulong y, ulong[] z, int zOff) + { + Debug.Assert(x >> 57 == 0); + Debug.Assert(y >> 57 == 0); + + //u[0] = 0; + u[1] = y; + u[2] = u[1] << 1; + u[3] = u[2] ^ y; + u[4] = u[2] << 1; + u[5] = u[4] ^ y; + u[6] = u[3] << 1; + u[7] = u[6] ^ y; + + uint j = (uint)x; + ulong g, h = 0, l = u[j & 7]; + int k = 48; + do + { + j = (uint)(x >> k); + g = u[j & 7] + ^ u[(j >> 3) & 7] << 3 + ^ u[(j >> 6) & 7] << 6; + l ^= (g << k); + h ^= (g >> -k); + } + while ((k -= 9) > 0); + + h ^= ((x & 0x0100804020100800L) & (ulong)(((long)y << 7) >> 63)) >> 8; + + Debug.Assert(h >> 49 == 0); + + z[zOff ] = l & M57; + z[zOff + 1] = (l >> 57) ^ (h << 7); + } + + protected static void ImplSquare(ulong[] x, ulong[] zz) + { + Interleave.Expand64To128(x, 0, 4, zz, 0); + zz[8] = Interleave.Expand32to64((uint)x[4]); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT283Field.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT283Field.cs.meta new file mode 100644 index 0000000..1270082 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT283Field.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 06333af63c7d7804c98c75befd59f448 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT283FieldElement.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT283FieldElement.cs new file mode 100644 index 0000000..6bd720a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT283FieldElement.cs @@ -0,0 +1,233 @@ +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT283FieldElement + : AbstractF2mFieldElement + { + protected internal readonly ulong[] x; + + public SecT283FieldElement(BigInteger x) + { + if (x == null || x.SignValue < 0 || x.BitLength > 283) + throw new ArgumentException("value invalid for SecT283FieldElement", "x"); + + this.x = SecT283Field.FromBigInteger(x); + } + + public SecT283FieldElement() + { + this.x = Nat320.Create64(); + } + + protected internal SecT283FieldElement(ulong[] x) + { + this.x = x; + } + + public override bool IsOne + { + get { return Nat320.IsOne64(x); } + } + + public override bool IsZero + { + get { return Nat320.IsZero64(x); } + } + + public override bool TestBitZero() + { + return (x[0] & 1UL) != 0UL; + } + + public override BigInteger ToBigInteger() + { + return Nat320.ToBigInteger64(x); + } + + public override string FieldName + { + get { return "SecT283Field"; } + } + + public override int FieldSize + { + get { return 283; } + } + + public override ECFieldElement Add(ECFieldElement b) + { + ulong[] z = Nat320.Create64(); + SecT283Field.Add(x, ((SecT283FieldElement)b).x, z); + return new SecT283FieldElement(z); + } + + public override ECFieldElement AddOne() + { + ulong[] z = Nat320.Create64(); + SecT283Field.AddOne(x, z); + return new SecT283FieldElement(z); + } + + public override ECFieldElement Subtract(ECFieldElement b) + { + // Addition and subtraction are the same in F2m + return Add(b); + } + + public override ECFieldElement Multiply(ECFieldElement b) + { + ulong[] z = Nat320.Create64(); + SecT283Field.Multiply(x, ((SecT283FieldElement)b).x, z); + return new SecT283FieldElement(z); + } + + public override ECFieldElement MultiplyMinusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) + { + return MultiplyPlusProduct(b, x, y); + } + + public override ECFieldElement MultiplyPlusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) + { + ulong[] ax = this.x, bx = ((SecT283FieldElement)b).x; + ulong[] xx = ((SecT283FieldElement)x).x, yx = ((SecT283FieldElement)y).x; + + ulong[] tt = Nat.Create64(9); + SecT283Field.MultiplyAddToExt(ax, bx, tt); + SecT283Field.MultiplyAddToExt(xx, yx, tt); + + ulong[] z = Nat320.Create64(); + SecT283Field.Reduce(tt, z); + return new SecT283FieldElement(z); + } + + public override ECFieldElement Divide(ECFieldElement b) + { + return Multiply(b.Invert()); + } + + public override ECFieldElement Negate() + { + return this; + } + + public override ECFieldElement Square() + { + ulong[] z = Nat320.Create64(); + SecT283Field.Square(x, z); + return new SecT283FieldElement(z); + } + + public override ECFieldElement SquareMinusProduct(ECFieldElement x, ECFieldElement y) + { + return SquarePlusProduct(x, y); + } + + public override ECFieldElement SquarePlusProduct(ECFieldElement x, ECFieldElement y) + { + ulong[] ax = this.x; + ulong[] xx = ((SecT283FieldElement)x).x, yx = ((SecT283FieldElement)y).x; + + ulong[] tt = Nat.Create64(9); + SecT283Field.SquareAddToExt(ax, tt); + SecT283Field.MultiplyAddToExt(xx, yx, tt); + + ulong[] z = Nat320.Create64(); + SecT283Field.Reduce(tt, z); + return new SecT283FieldElement(z); + } + + public override ECFieldElement SquarePow(int pow) + { + if (pow < 1) + return this; + + ulong[] z = Nat320.Create64(); + SecT283Field.SquareN(x, pow, z); + return new SecT283FieldElement(z); + } + + public override ECFieldElement HalfTrace() + { + ulong[] z = Nat320.Create64(); + SecT283Field.HalfTrace(x, z); + return new SecT283FieldElement(z); + } + + public override bool HasFastTrace + { + get { return true; } + } + + public override int Trace() + { + return (int)SecT283Field.Trace(x); + } + + public override ECFieldElement Invert() + { + ulong[] z = Nat320.Create64(); + SecT283Field.Invert(x, z); + return new SecT283FieldElement(z); + } + + public override ECFieldElement Sqrt() + { + ulong[] z = Nat320.Create64(); + SecT283Field.Sqrt(x, z); + return new SecT283FieldElement(z); + } + + public virtual int Representation + { + get { return F2mFieldElement.Ppb; } + } + + public virtual int M + { + get { return 283; } + } + + public virtual int K1 + { + get { return 5; } + } + + public virtual int K2 + { + get { return 7; } + } + + public virtual int K3 + { + get { return 12; } + } + + public override bool Equals(object obj) + { + return Equals(obj as SecT283FieldElement); + } + + public override bool Equals(ECFieldElement other) + { + return Equals(other as SecT283FieldElement); + } + + public virtual bool Equals(SecT283FieldElement other) + { + if (this == other) + return true; + if (null == other) + return false; + return Nat320.Eq64(x, other.x); + } + + public override int GetHashCode() + { + return 2831275 ^ Arrays.GetHashCode(x, 0, 5); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT283FieldElement.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT283FieldElement.cs.meta new file mode 100644 index 0000000..805218c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT283FieldElement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7266fad1b8fa156459a785d163076e66 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT283K1Curve.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT283K1Curve.cs new file mode 100644 index 0000000..c4d1824 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT283K1Curve.cs @@ -0,0 +1,183 @@ +using System; + +using Org.BouncyCastle.Math.EC.Multiplier; +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT283K1Curve + : AbstractF2mCurve + { + private const int SECT283K1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT283K1_FE_LONGS = 5; + private static readonly ECFieldElement[] SECT283K1_AFFINE_ZS = new ECFieldElement[] { new SecT283FieldElement(BigInteger.One) }; + + protected readonly SecT283K1Point m_infinity; + + public SecT283K1Curve() + : base(283, 5, 7, 12) + { + this.m_infinity = new SecT283K1Point(this, null, null); + + this.m_a = FromBigInteger(BigInteger.Zero); + this.m_b = FromBigInteger(BigInteger.One); + this.m_order = new BigInteger(1, Hex.DecodeStrict("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61")); + this.m_cofactor = BigInteger.ValueOf(4); + + this.m_coord = SECT283K1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecT283K1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_LAMBDA_PROJECTIVE: + return true; + default: + return false; + } + } + + protected override ECMultiplier CreateDefaultMultiplier() + { + return new WTauNafMultiplier(); + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return 283; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecT283FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecT283K1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecT283K1Point(this, x, y, zs, withCompression); + } + + public override bool IsKoblitz + { + get { return true; } + } + + public virtual int M + { + get { return 283; } + } + + public virtual bool IsTrinomial + { + get { return false; } + } + + public virtual int K1 + { + get { return 5; } + } + + public virtual int K2 + { + get { return 7; } + } + + public virtual int K3 + { + get { return 12; } + } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + ulong[] table = new ulong[len * SECT283K1_FE_LONGS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat320.Copy64(((SecT283FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECT283K1_FE_LONGS; + Nat320.Copy64(((SecT283FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECT283K1_FE_LONGS; + } + } + + return new SecT283K1LookupTable(this, table, len); + } + + private class SecT283K1LookupTable + : AbstractECLookupTable + { + private readonly SecT283K1Curve m_outer; + private readonly ulong[] m_table; + private readonly int m_size; + + internal SecT283K1LookupTable(SecT283K1Curve outer, ulong[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public override int Size + { + get { return m_size; } + } + + public override ECPoint Lookup(int index) + { + ulong[] x = Nat320.Create64(), y = Nat320.Create64(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + ulong MASK = (ulong)(long)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECT283K1_FE_LONGS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECT283K1_FE_LONGS + j] & MASK; + } + + pos += (SECT283K1_FE_LONGS * 2); + } + + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + ulong[] x = Nat320.Create64(), y = Nat320.Create64(); + int pos = index * SECT283K1_FE_LONGS * 2; + + for (int j = 0; j < SECT283K1_FE_LONGS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECT283K1_FE_LONGS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(ulong[] x, ulong[] y) + { + return m_outer.CreateRawPoint(new SecT283FieldElement(x), new SecT283FieldElement(y), SECT283K1_AFFINE_ZS, false); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT283K1Curve.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT283K1Curve.cs.meta new file mode 100644 index 0000000..2175677 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT283K1Curve.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: defc9514891d2124c9c623939694faa1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT283K1Point.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT283K1Point.cs new file mode 100644 index 0000000..d3d7fa1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT283K1Point.cs @@ -0,0 +1,289 @@ +using System; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT283K1Point + : AbstractF2mPoint + { + /** + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecT283K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * @deprecated per-point compression property will be removed, refer {@link #getEncoded(bool)} + */ + public SecT283K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecT283K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecT283K1Point(null, this.AffineXCoord, this.AffineYCoord); // earlier JDK + } + + public override ECFieldElement YCoord + { + get + { + ECFieldElement X = RawXCoord, L = RawYCoord; + + if (this.IsInfinity || X.IsZero) + return L; + + // Y is actually Lambda (X + Y/X) here; convert to affine value on the fly + ECFieldElement Y = L.Add(X).Multiply(X); + + ECFieldElement Z = RawZCoords[0]; + if (!Z.IsOne) + { + Y = Y.Divide(Z); + } + + return Y; + } + } + + protected internal override bool CompressionYTilde + { + get + { + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return false; + + ECFieldElement Y = this.RawYCoord; + + // Y is actually Lambda (X + Y/X) here + return Y.TestBitZero() != X.TestBitZero(); + } + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + ECFieldElement X2 = b.RawXCoord; + + if (X1.IsZero) + { + if (X2.IsZero) + return curve.Infinity; + + return b.Add(this); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord, Z2 = b.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement U2 = X2, S2 = L2; + if (!Z1IsOne) + { + U2 = U2.Multiply(Z1); + S2 = S2.Multiply(Z1); + } + + bool Z2IsOne = Z2.IsOne; + ECFieldElement U1 = X1, S1 = L1; + if (!Z2IsOne) + { + U1 = U1.Multiply(Z2); + S1 = S1.Multiply(Z2); + } + + ECFieldElement A = S1.Add(S2); + ECFieldElement B = U1.Add(U2); + + if (B.IsZero) + { + if (A.IsZero) + return Twice(); + + return curve.Infinity; + } + + ECFieldElement X3, L3, Z3; + if (X2.IsZero) + { + // TODO This can probably be optimized quite a bit + ECPoint p = this.Normalize(); + X1 = p.XCoord; + ECFieldElement Y1 = p.YCoord; + + ECFieldElement Y2 = L2; + ECFieldElement L = Y1.Add(Y2).Divide(X1); + + X3 = L.Square().Add(L).Add(X1); + if (X3.IsZero) + { + return new SecT283K1Point(curve, X3, curve.B, IsCompressed); + } + + ECFieldElement Y3 = L.Multiply(X1.Add(X3)).Add(X3).Add(Y1); + L3 = Y3.Divide(X3).Add(X3); + Z3 = curve.FromBigInteger(BigInteger.One); + } + else + { + B = B.Square(); + + ECFieldElement AU1 = A.Multiply(U1); + ECFieldElement AU2 = A.Multiply(U2); + + X3 = AU1.Multiply(AU2); + if (X3.IsZero) + { + return new SecT283K1Point(curve, X3, curve.B, IsCompressed); + } + + ECFieldElement ABZ2 = A.Multiply(B); + if (!Z2IsOne) + { + ABZ2 = ABZ2.Multiply(Z2); + } + + L3 = AU2.Add(B).SquarePlusProduct(ABZ2, L1.Add(Z1)); + + Z3 = ABZ2; + if (!Z1IsOne) + { + Z3 = Z3.Multiply(Z1); + } + } + + return new SecT283K1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is its own additive inverse + return curve.Infinity; + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement Z1Sq = Z1IsOne ? Z1 : Z1.Square(); + ECFieldElement T; + if (Z1IsOne) + { + T = L1.Square().Add(L1); + } + else + { + T = L1.Add(Z1).Multiply(L1); + } + + if (T.IsZero) + { + return new SecT283K1Point(curve, T, curve.B, IsCompressed); + } + + ECFieldElement X3 = T.Square(); + ECFieldElement Z3 = Z1IsOne ? T : T.Multiply(Z1Sq); + + ECFieldElement t1 = L1.Add(X1).Square(); + ECFieldElement t2 = Z1IsOne ? Z1 : Z1Sq.Square(); + ECFieldElement L3 = t1.Add(T).Add(Z1Sq).Multiply(t1).Add(t2).Add(X3).Add(Z3); + + return new SecT283K1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is its own additive inverse + return b; + } + + // NOTE: TwicePlus() only optimized for lambda-affine argument + ECFieldElement X2 = b.RawXCoord, Z2 = b.RawZCoords[0]; + if (X2.IsZero || !Z2.IsOne) + { + return Twice().Add(b); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord; + + ECFieldElement X1Sq = X1.Square(); + ECFieldElement L1Sq = L1.Square(); + ECFieldElement Z1Sq = Z1.Square(); + ECFieldElement L1Z1 = L1.Multiply(Z1); + + ECFieldElement T = L1Sq.Add(L1Z1); + ECFieldElement L2plus1 = L2.AddOne(); + ECFieldElement A = L2plus1.Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); + ECFieldElement X2Z1Sq = X2.Multiply(Z1Sq); + ECFieldElement B = X2Z1Sq.Add(T).Square(); + + if (B.IsZero) + { + if (A.IsZero) + return b.Twice(); + + return curve.Infinity; + } + + if (A.IsZero) + { + return new SecT283K1Point(curve, A, curve.B, IsCompressed); + } + + ECFieldElement X3 = A.Square().Multiply(X2Z1Sq); + ECFieldElement Z3 = A.Multiply(B).Multiply(Z1Sq); + ECFieldElement L3 = A.Add(B).Square().MultiplyPlusProduct(T, L2plus1, Z3); + + return new SecT283K1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Negate() + { + if (this.IsInfinity) + return this; + + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return this; + + // L is actually Lambda (X + Y/X) here + ECFieldElement L = this.RawYCoord, Z = this.RawZCoords[0]; + return new SecT283K1Point(Curve, X, L.Add(Z), new ECFieldElement[] { Z }, IsCompressed); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT283K1Point.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT283K1Point.cs.meta new file mode 100644 index 0000000..7b79c3f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT283K1Point.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 02c571744ee929a429a4f1eb006f9c9e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT283R1Curve.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT283R1Curve.cs new file mode 100644 index 0000000..c294137 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT283R1Curve.cs @@ -0,0 +1,177 @@ +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT283R1Curve + : AbstractF2mCurve + { + private const int SECT283R1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT283R1_FE_LONGS = 5; + private static readonly ECFieldElement[] SECT283R1_AFFINE_ZS = new ECFieldElement[] { new SecT283FieldElement(BigInteger.One) }; + + protected readonly SecT283R1Point m_infinity; + + public SecT283R1Curve() + : base(283, 5, 7, 12) + { + this.m_infinity = new SecT283R1Point(this, null, null); + + this.m_a = FromBigInteger(BigInteger.One); + this.m_b = FromBigInteger(new BigInteger(1, Hex.DecodeStrict("027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5"))); + this.m_order = new BigInteger(1, Hex.DecodeStrict("03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307")); + this.m_cofactor = BigInteger.Two; + + this.m_coord = SECT283R1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecT283R1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_LAMBDA_PROJECTIVE: + return true; + default: + return false; + } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return 283; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecT283FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecT283R1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecT283R1Point(this, x, y, zs, withCompression); + } + + public override bool IsKoblitz + { + get { return false; } + } + + public virtual int M + { + get { return 283; } + } + + public virtual bool IsTrinomial + { + get { return false; } + } + + public virtual int K1 + { + get { return 5; } + } + + public virtual int K2 + { + get { return 7; } + } + + public virtual int K3 + { + get { return 12; } + } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + ulong[] table = new ulong[len * SECT283R1_FE_LONGS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat320.Copy64(((SecT283FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECT283R1_FE_LONGS; + Nat320.Copy64(((SecT283FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECT283R1_FE_LONGS; + } + } + + return new SecT283R1LookupTable(this, table, len); + } + + private class SecT283R1LookupTable + : AbstractECLookupTable + { + private readonly SecT283R1Curve m_outer; + private readonly ulong[] m_table; + private readonly int m_size; + + internal SecT283R1LookupTable(SecT283R1Curve outer, ulong[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public override int Size + { + get { return m_size; } + } + + public override ECPoint Lookup(int index) + { + ulong[] x = Nat320.Create64(), y = Nat320.Create64(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + ulong MASK = (ulong)(long)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECT283R1_FE_LONGS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECT283R1_FE_LONGS + j] & MASK; + } + + pos += (SECT283R1_FE_LONGS * 2); + } + + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + ulong[] x = Nat320.Create64(), y = Nat320.Create64(); + int pos = index * SECT283R1_FE_LONGS * 2; + + for (int j = 0; j < SECT283R1_FE_LONGS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECT283R1_FE_LONGS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(ulong[] x, ulong[] y) + { + return m_outer.CreateRawPoint(new SecT283FieldElement(x), new SecT283FieldElement(y), SECT283R1_AFFINE_ZS, false); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT283R1Curve.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT283R1Curve.cs.meta new file mode 100644 index 0000000..d2aa1ec --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT283R1Curve.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5451758aa751a3141b35f3f7a9c44838 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT283R1Point.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT283R1Point.cs new file mode 100644 index 0000000..8c4092d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT283R1Point.cs @@ -0,0 +1,278 @@ +using System; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT283R1Point + : AbstractF2mPoint + { + /** + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecT283R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * @deprecated per-point compression property will be removed, refer {@link #getEncoded(bool)} + */ + public SecT283R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecT283R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecT283R1Point(null, AffineXCoord, AffineYCoord); + } + + public override ECFieldElement YCoord + { + get + { + ECFieldElement X = RawXCoord, L = RawYCoord; + + if (this.IsInfinity || X.IsZero) + return L; + + // Y is actually Lambda (X + Y/X) here; convert to affine value on the fly + ECFieldElement Y = L.Add(X).Multiply(X); + + ECFieldElement Z = RawZCoords[0]; + if (!Z.IsOne) + { + Y = Y.Divide(Z); + } + + return Y; + } + } + + protected internal override bool CompressionYTilde + { + get + { + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return false; + + ECFieldElement Y = this.RawYCoord; + + // Y is actually Lambda (X + Y/X) here + return Y.TestBitZero() != X.TestBitZero(); + } + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + ECFieldElement X2 = b.RawXCoord; + + if (X1.IsZero) + { + if (X2.IsZero) + return curve.Infinity; + + return b.Add(this); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord, Z2 = b.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement U2 = X2, S2 = L2; + if (!Z1IsOne) + { + U2 = U2.Multiply(Z1); + S2 = S2.Multiply(Z1); + } + + bool Z2IsOne = Z2.IsOne; + ECFieldElement U1 = X1, S1 = L1; + if (!Z2IsOne) + { + U1 = U1.Multiply(Z2); + S1 = S1.Multiply(Z2); + } + + ECFieldElement A = S1.Add(S2); + ECFieldElement B = U1.Add(U2); + + if (B.IsZero) + { + if (A.IsZero) + return Twice(); + + return curve.Infinity; + } + + ECFieldElement X3, L3, Z3; + if (X2.IsZero) + { + // TODO This can probably be optimized quite a bit + ECPoint p = this.Normalize(); + X1 = p.XCoord; + ECFieldElement Y1 = p.YCoord; + + ECFieldElement Y2 = L2; + ECFieldElement L = Y1.Add(Y2).Divide(X1); + + X3 = L.Square().Add(L).Add(X1).AddOne(); + if (X3.IsZero) + { + return new SecT283R1Point(curve, X3, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement Y3 = L.Multiply(X1.Add(X3)).Add(X3).Add(Y1); + L3 = Y3.Divide(X3).Add(X3); + Z3 = curve.FromBigInteger(BigInteger.One); + } + else + { + B = B.Square(); + + ECFieldElement AU1 = A.Multiply(U1); + ECFieldElement AU2 = A.Multiply(U2); + + X3 = AU1.Multiply(AU2); + if (X3.IsZero) + { + return new SecT283R1Point(curve, X3, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement ABZ2 = A.Multiply(B); + if (!Z2IsOne) + { + ABZ2 = ABZ2.Multiply(Z2); + } + + L3 = AU2.Add(B).SquarePlusProduct(ABZ2, L1.Add(Z1)); + + Z3 = ABZ2; + if (!Z1IsOne) + { + Z3 = Z3.Multiply(Z1); + } + } + + return new SecT283R1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is its own additive inverse + return curve.Infinity; + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement L1Z1 = Z1IsOne ? L1 : L1.Multiply(Z1); + ECFieldElement Z1Sq = Z1IsOne ? Z1 : Z1.Square(); + ECFieldElement T = L1.Square().Add(L1Z1).Add(Z1Sq); + if (T.IsZero) + { + return new SecT283R1Point(curve, T, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement X3 = T.Square(); + ECFieldElement Z3 = Z1IsOne ? T : T.Multiply(Z1Sq); + + ECFieldElement X1Z1 = Z1IsOne ? X1 : X1.Multiply(Z1); + ECFieldElement L3 = X1Z1.SquarePlusProduct(T, L1Z1).Add(X3).Add(Z3); + + return new SecT283R1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is its own additive inverse + return b; + } + + ECFieldElement X2 = b.RawXCoord, Z2 = b.RawZCoords[0]; + if (X2.IsZero || !Z2.IsOne) + { + return Twice().Add(b); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord; + + ECFieldElement X1Sq = X1.Square(); + ECFieldElement L1Sq = L1.Square(); + ECFieldElement Z1Sq = Z1.Square(); + ECFieldElement L1Z1 = L1.Multiply(Z1); + + ECFieldElement T = Z1Sq.Add(L1Sq).Add(L1Z1); + ECFieldElement A = L2.Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); + ECFieldElement X2Z1Sq = X2.Multiply(Z1Sq); + ECFieldElement B = X2Z1Sq.Add(T).Square(); + + if (B.IsZero) + { + if (A.IsZero) + return b.Twice(); + + return curve.Infinity; + } + + if (A.IsZero) + { + return new SecT283R1Point(curve, A, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement X3 = A.Square().Multiply(X2Z1Sq); + ECFieldElement Z3 = A.Multiply(B).Multiply(Z1Sq); + ECFieldElement L3 = A.Add(B).Square().MultiplyPlusProduct(T, L2.AddOne(), Z3); + + return new SecT283R1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Negate() + { + if (this.IsInfinity) + return this; + + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return this; + + // L is actually Lambda (X + Y/X) here + ECFieldElement L = this.RawYCoord, Z = this.RawZCoords[0]; + return new SecT283R1Point(Curve, X, L.Add(Z), new ECFieldElement[] { Z }, IsCompressed); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT283R1Point.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT283R1Point.cs.meta new file mode 100644 index 0000000..fb4048d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT283R1Point.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3587627174af39b488348398592c660f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT409Field.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT409Field.cs new file mode 100644 index 0000000..c35d3ce --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT409Field.cs @@ -0,0 +1,394 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT409Field + { + private const ulong M25 = ulong.MaxValue >> 39; + private const ulong M59 = ulong.MaxValue >> 5; + + public static void Add(ulong[] x, ulong[] y, ulong[] z) + { + z[0] = x[0] ^ y[0]; + z[1] = x[1] ^ y[1]; + z[2] = x[2] ^ y[2]; + z[3] = x[3] ^ y[3]; + z[4] = x[4] ^ y[4]; + z[5] = x[5] ^ y[5]; + z[6] = x[6] ^ y[6]; + } + + public static void AddExt(ulong[] xx, ulong[] yy, ulong[] zz) + { + for (int i = 0; i < 13; ++i) + { + zz[i] = xx[i] ^ yy[i]; + } + } + + public static void AddOne(ulong[] x, ulong[] z) + { + z[0] = x[0] ^ 1UL; + z[1] = x[1]; + z[2] = x[2]; + z[3] = x[3]; + z[4] = x[4]; + z[5] = x[5]; + z[6] = x[6]; + } + + private static void AddTo(ulong[] x, ulong[] z) + { + z[0] ^= x[0]; + z[1] ^= x[1]; + z[2] ^= x[2]; + z[3] ^= x[3]; + z[4] ^= x[4]; + z[5] ^= x[5]; + z[6] ^= x[6]; + } + + public static ulong[] FromBigInteger(BigInteger x) + { + return Nat.FromBigInteger64(409, x); + } + + public static void HalfTrace(ulong[] x, ulong[] z) + { + ulong[] tt = Nat.Create64(13); + + Nat448.Copy64(x, z); + for (int i = 1; i < 409; i += 2) + { + ImplSquare(z, tt); + Reduce(tt, z); + ImplSquare(z, tt); + Reduce(tt, z); + AddTo(x, z); + } + } + + public static void Invert(ulong[] x, ulong[] z) + { + if (Nat448.IsZero64(x)) + throw new InvalidOperationException(); + + // Itoh-Tsujii inversion with bases { 2, 3 } + + ulong[] t0 = Nat448.Create64(); + ulong[] t1 = Nat448.Create64(); + ulong[] t2 = Nat448.Create64(); + + Square(x, t0); + + // 3 | 408 + SquareN(t0, 1, t1); + Multiply(t0, t1, t0); + SquareN(t1, 1, t1); + Multiply(t0, t1, t0); + + // 2 | 136 + SquareN(t0, 3, t1); + Multiply(t0, t1, t0); + + // 2 | 68 + SquareN(t0, 6, t1); + Multiply(t0, t1, t0); + + // 2 | 34 + SquareN(t0, 12, t1); + Multiply(t0, t1, t2); + + // ! {2,3} | 17 + SquareN(t2, 24, t0); + SquareN(t0, 24, t1); + Multiply(t0, t1, t0); + + // 2 | 8 + SquareN(t0, 48, t1); + Multiply(t0, t1, t0); + + // 2 | 4 + SquareN(t0, 96, t1); + Multiply(t0, t1, t0); + + // 2 | 2 + SquareN(t0, 192, t1); + Multiply(t0, t1, t0); + + Multiply(t0, t2, z); + } + + public static void Multiply(ulong[] x, ulong[] y, ulong[] z) + { + ulong[] tt = Nat448.CreateExt64(); + ImplMultiply(x, y, tt); + Reduce(tt, z); + } + + public static void MultiplyAddToExt(ulong[] x, ulong[] y, ulong[] zz) + { + ulong[] tt = Nat448.CreateExt64(); + ImplMultiply(x, y, tt); + AddExt(zz, tt, zz); + } + + public static void Reduce(ulong[] xx, ulong[] z) + { + ulong x00 = xx[0], x01 = xx[1], x02 = xx[2], x03 = xx[3]; + ulong x04 = xx[4], x05 = xx[5], x06 = xx[6], x07 = xx[7]; + + ulong u = xx[12]; + x05 ^= (u << 39); + x06 ^= (u >> 25) ^ (u << 62); + x07 ^= (u >> 2); + + u = xx[11]; + x04 ^= (u << 39); + x05 ^= (u >> 25) ^ (u << 62); + x06 ^= (u >> 2); + + u = xx[10]; + x03 ^= (u << 39); + x04 ^= (u >> 25) ^ (u << 62); + x05 ^= (u >> 2); + + u = xx[9]; + x02 ^= (u << 39); + x03 ^= (u >> 25) ^ (u << 62); + x04 ^= (u >> 2); + + u = xx[8]; + x01 ^= (u << 39); + x02 ^= (u >> 25) ^ (u << 62); + x03 ^= (u >> 2); + + u = x07; + x00 ^= (u << 39); + x01 ^= (u >> 25) ^ (u << 62); + x02 ^= (u >> 2); + + ulong t = x06 >> 25; + z[0] = x00 ^ t; + z[1] = x01 ^ (t << 23); + z[2] = x02; + z[3] = x03; + z[4] = x04; + z[5] = x05; + z[6] = x06 & M25; + } + + public static void Reduce39(ulong[] z, int zOff) + { + ulong z6 = z[zOff + 6], t = z6 >> 25; + z[zOff ] ^= t; + z[zOff + 1] ^= (t << 23); + z[zOff + 6] = z6 & M25; + } + + public static void Sqrt(ulong[] x, ulong[] z) + { + ulong u0, u1; + u0 = Interleave.Unshuffle(x[0]); u1 = Interleave.Unshuffle(x[1]); + ulong e0 = (u0 & 0x00000000FFFFFFFFUL) | (u1 << 32); + ulong c0 = (u0 >> 32) | (u1 & 0xFFFFFFFF00000000UL); + + u0 = Interleave.Unshuffle(x[2]); u1 = Interleave.Unshuffle(x[3]); + ulong e1 = (u0 & 0x00000000FFFFFFFFUL) | (u1 << 32); + ulong c1 = (u0 >> 32) | (u1 & 0xFFFFFFFF00000000UL); + + u0 = Interleave.Unshuffle(x[4]); u1 = Interleave.Unshuffle(x[5]); + ulong e2 = (u0 & 0x00000000FFFFFFFFUL) | (u1 << 32); + ulong c2 = (u0 >> 32) | (u1 & 0xFFFFFFFF00000000UL); + + u0 = Interleave.Unshuffle(x[6]); + ulong e3 = (u0 & 0x00000000FFFFFFFFUL); + ulong c3 = (u0 >> 32); + + z[0] = e0 ^ (c0 << 44); + z[1] = e1 ^ (c1 << 44) ^ (c0 >> 20); + z[2] = e2 ^ (c2 << 44) ^ (c1 >> 20); + z[3] = e3 ^ (c3 << 44) ^ (c2 >> 20) ^ (c0 << 13); + z[4] = (c3 >> 20) ^ (c1 << 13) ^ (c0 >> 51); + z[5] = (c2 << 13) ^ (c1 >> 51); + z[6] = (c3 << 13) ^ (c2 >> 51); + + Debug.Assert((c3 >> 51) == 0); + } + + public static void Square(ulong[] x, ulong[] z) + { + ulong[] tt = Nat.Create64(13); + ImplSquare(x, tt); + Reduce(tt, z); + } + + public static void SquareAddToExt(ulong[] x, ulong[] zz) + { + ulong[] tt = Nat.Create64(13); + ImplSquare(x, tt); + AddExt(zz, tt, zz); + } + + public static void SquareN(ulong[] x, int n, ulong[] z) + { + Debug.Assert(n > 0); + + ulong[] tt = Nat.Create64(13); + ImplSquare(x, tt); + Reduce(tt, z); + + while (--n > 0) + { + ImplSquare(z, tt); + Reduce(tt, z); + } + } + + public static uint Trace(ulong[] x) + { + // Non-zero-trace bits: 0 + return (uint)(x[0]) & 1U; + } + + protected static void ImplCompactExt(ulong[] zz) + { + ulong z00 = zz[ 0], z01 = zz[ 1], z02 = zz[ 2], z03 = zz[ 3], z04 = zz[ 4], z05 = zz[ 5], z06 = zz[ 6]; + ulong z07 = zz[ 7], z08 = zz[ 8], z09 = zz[ 9], z10 = zz[10], z11 = zz[11], z12 = zz[12], z13 = zz[13]; + zz[ 0] = z00 ^ (z01 << 59); + zz[ 1] = (z01 >> 5) ^ (z02 << 54); + zz[ 2] = (z02 >> 10) ^ (z03 << 49); + zz[ 3] = (z03 >> 15) ^ (z04 << 44); + zz[ 4] = (z04 >> 20) ^ (z05 << 39); + zz[ 5] = (z05 >> 25) ^ (z06 << 34); + zz[ 6] = (z06 >> 30) ^ (z07 << 29); + zz[ 7] = (z07 >> 35) ^ (z08 << 24); + zz[ 8] = (z08 >> 40) ^ (z09 << 19); + zz[ 9] = (z09 >> 45) ^ (z10 << 14); + zz[10] = (z10 >> 50) ^ (z11 << 9); + zz[11] = (z11 >> 55) ^ (z12 << 4) + ^ (z13 << 63); + zz[12] = (z13 >> 1); + //zz[13] = 0; + } + + protected static void ImplExpand(ulong[] x, ulong[] z) + { + ulong x0 = x[0], x1 = x[1], x2 = x[2], x3 = x[3], x4 = x[4], x5 = x[5], x6 = x[6]; + z[0] = x0 & M59; + z[1] = ((x0 >> 59) ^ (x1 << 5)) & M59; + z[2] = ((x1 >> 54) ^ (x2 << 10)) & M59; + z[3] = ((x2 >> 49) ^ (x3 << 15)) & M59; + z[4] = ((x3 >> 44) ^ (x4 << 20)) & M59; + z[5] = ((x4 >> 39) ^ (x5 << 25)) & M59; + z[6] = ((x5 >> 34) ^ (x6 << 30)); + } + + protected static void ImplMultiply(ulong[] x, ulong[] y, ulong[] zz) + { + ulong[] a = new ulong[7], b = new ulong[7]; + ImplExpand(x, a); + ImplExpand(y, b); + + ulong[] u = new ulong[8]; + for (int i = 0; i < 7; ++i) + { + ImplMulwAcc(u, a[i], b[i], zz, i << 1); + } + + ulong v0 = zz[0], v1 = zz[1]; + v0 ^= zz[ 2]; zz[1] = v0 ^ v1; v1 ^= zz[ 3]; + v0 ^= zz[ 4]; zz[2] = v0 ^ v1; v1 ^= zz[ 5]; + v0 ^= zz[ 6]; zz[3] = v0 ^ v1; v1 ^= zz[ 7]; + v0 ^= zz[ 8]; zz[4] = v0 ^ v1; v1 ^= zz[ 9]; + v0 ^= zz[10]; zz[5] = v0 ^ v1; v1 ^= zz[11]; + v0 ^= zz[12]; zz[6] = v0 ^ v1; v1 ^= zz[13]; + + ulong w = v0 ^ v1; + zz[ 7] = zz[0] ^ w; + zz[ 8] = zz[1] ^ w; + zz[ 9] = zz[2] ^ w; + zz[10] = zz[3] ^ w; + zz[11] = zz[4] ^ w; + zz[12] = zz[5] ^ w; + zz[13] = zz[6] ^ w; + + ImplMulwAcc(u, a[0] ^ a[1], b[0] ^ b[1], zz, 1); + + ImplMulwAcc(u, a[0] ^ a[2], b[0] ^ b[2], zz, 2); + + ImplMulwAcc(u, a[0] ^ a[3], b[0] ^ b[3], zz, 3); + ImplMulwAcc(u, a[1] ^ a[2], b[1] ^ b[2], zz, 3); + + ImplMulwAcc(u, a[0] ^ a[4], b[0] ^ b[4], zz, 4); + ImplMulwAcc(u, a[1] ^ a[3], b[1] ^ b[3], zz, 4); + + ImplMulwAcc(u, a[0] ^ a[5], b[0] ^ b[5], zz, 5); + ImplMulwAcc(u, a[1] ^ a[4], b[1] ^ b[4], zz, 5); + ImplMulwAcc(u, a[2] ^ a[3], b[2] ^ b[3], zz, 5); + + ImplMulwAcc(u, a[0] ^ a[6], b[0] ^ b[6], zz, 6); + ImplMulwAcc(u, a[1] ^ a[5], b[1] ^ b[5], zz, 6); + ImplMulwAcc(u, a[2] ^ a[4], b[2] ^ b[4], zz, 6); + + ImplMulwAcc(u, a[1] ^ a[6], b[1] ^ b[6], zz, 7); + ImplMulwAcc(u, a[2] ^ a[5], b[2] ^ b[5], zz, 7); + ImplMulwAcc(u, a[3] ^ a[4], b[3] ^ b[4], zz, 7); + + ImplMulwAcc(u, a[2] ^ a[6], b[2] ^ b[6], zz, 8); + ImplMulwAcc(u, a[3] ^ a[5], b[3] ^ b[5], zz, 8); + + ImplMulwAcc(u, a[3] ^ a[6], b[3] ^ b[6], zz, 9); + ImplMulwAcc(u, a[4] ^ a[5], b[4] ^ b[5], zz, 9); + + ImplMulwAcc(u, a[4] ^ a[6], b[4] ^ b[6], zz, 10); + + ImplMulwAcc(u, a[5] ^ a[6], b[5] ^ b[6], zz, 11); + + ImplCompactExt(zz); + } + + protected static void ImplMulwAcc(ulong[] u, ulong x, ulong y, ulong[] z, int zOff) + { + Debug.Assert(x >> 59 == 0); + Debug.Assert(y >> 59 == 0); + + //u[0] = 0; + u[1] = y; + u[2] = u[1] << 1; + u[3] = u[2] ^ y; + u[4] = u[2] << 1; + u[5] = u[4] ^ y; + u[6] = u[3] << 1; + u[7] = u[6] ^ y; + + uint j = (uint)x; + ulong g, h = 0, l = u[j & 7] + ^ (u[(j >> 3) & 7] << 3); + int k = 54; + do + { + j = (uint)(x >> k); + g = u[j & 7] + ^ u[(j >> 3) & 7] << 3; + l ^= (g << k); + h ^= (g >> -k); + } + while ((k -= 6) > 0); + + Debug.Assert(h >> 53 == 0); + + z[zOff ] ^= l & M59; + z[zOff + 1] ^= (l >> 59) ^ (h << 5); + } + + protected static void ImplSquare(ulong[] x, ulong[] zz) + { + Interleave.Expand64To128(x, 0, 6, zz, 0); + zz[12] = Interleave.Expand32to64((uint)x[6]); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT409Field.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT409Field.cs.meta new file mode 100644 index 0000000..aa733f6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT409Field.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f7855c4d727dcc04abf179f94e1f4d7f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT409FieldElement.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT409FieldElement.cs new file mode 100644 index 0000000..a9b0852 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT409FieldElement.cs @@ -0,0 +1,233 @@ +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT409FieldElement + : AbstractF2mFieldElement + { + protected internal readonly ulong[] x; + + public SecT409FieldElement(BigInteger x) + { + if (x == null || x.SignValue < 0 || x.BitLength > 409) + throw new ArgumentException("value invalid for SecT409FieldElement", "x"); + + this.x = SecT409Field.FromBigInteger(x); + } + + public SecT409FieldElement() + { + this.x = Nat448.Create64(); + } + + protected internal SecT409FieldElement(ulong[] x) + { + this.x = x; + } + + public override bool IsOne + { + get { return Nat448.IsOne64(x); } + } + + public override bool IsZero + { + get { return Nat448.IsZero64(x); } + } + + public override bool TestBitZero() + { + return (x[0] & 1UL) != 0UL; + } + + public override BigInteger ToBigInteger() + { + return Nat448.ToBigInteger64(x); + } + + public override string FieldName + { + get { return "SecT409Field"; } + } + + public override int FieldSize + { + get { return 409; } + } + + public override ECFieldElement Add(ECFieldElement b) + { + ulong[] z = Nat448.Create64(); + SecT409Field.Add(x, ((SecT409FieldElement)b).x, z); + return new SecT409FieldElement(z); + } + + public override ECFieldElement AddOne() + { + ulong[] z = Nat448.Create64(); + SecT409Field.AddOne(x, z); + return new SecT409FieldElement(z); + } + + public override ECFieldElement Subtract(ECFieldElement b) + { + // Addition and subtraction are the same in F2m + return Add(b); + } + + public override ECFieldElement Multiply(ECFieldElement b) + { + ulong[] z = Nat448.Create64(); + SecT409Field.Multiply(x, ((SecT409FieldElement)b).x, z); + return new SecT409FieldElement(z); + } + + public override ECFieldElement MultiplyMinusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) + { + return MultiplyPlusProduct(b, x, y); + } + + public override ECFieldElement MultiplyPlusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) + { + ulong[] ax = this.x, bx = ((SecT409FieldElement)b).x; + ulong[] xx = ((SecT409FieldElement)x).x, yx = ((SecT409FieldElement)y).x; + + ulong[] tt = Nat.Create64(13); + SecT409Field.MultiplyAddToExt(ax, bx, tt); + SecT409Field.MultiplyAddToExt(xx, yx, tt); + + ulong[] z = Nat448.Create64(); + SecT409Field.Reduce(tt, z); + return new SecT409FieldElement(z); + } + + public override ECFieldElement Divide(ECFieldElement b) + { + return Multiply(b.Invert()); + } + + public override ECFieldElement Negate() + { + return this; + } + + public override ECFieldElement Square() + { + ulong[] z = Nat448.Create64(); + SecT409Field.Square(x, z); + return new SecT409FieldElement(z); + } + + public override ECFieldElement SquareMinusProduct(ECFieldElement x, ECFieldElement y) + { + return SquarePlusProduct(x, y); + } + + public override ECFieldElement SquarePlusProduct(ECFieldElement x, ECFieldElement y) + { + ulong[] ax = this.x; + ulong[] xx = ((SecT409FieldElement)x).x, yx = ((SecT409FieldElement)y).x; + + ulong[] tt = Nat.Create64(13); + SecT409Field.SquareAddToExt(ax, tt); + SecT409Field.MultiplyAddToExt(xx, yx, tt); + + ulong[] z = Nat448.Create64(); + SecT409Field.Reduce(tt, z); + return new SecT409FieldElement(z); + } + + public override ECFieldElement SquarePow(int pow) + { + if (pow < 1) + return this; + + ulong[] z = Nat448.Create64(); + SecT409Field.SquareN(x, pow, z); + return new SecT409FieldElement(z); + } + + public override ECFieldElement HalfTrace() + { + ulong[] z = Nat448.Create64(); + SecT409Field.HalfTrace(x, z); + return new SecT409FieldElement(z); + } + + public override bool HasFastTrace + { + get { return true; } + } + + public override int Trace() + { + return (int)SecT409Field.Trace(x); + } + + public override ECFieldElement Invert() + { + ulong[] z = Nat448.Create64(); + SecT409Field.Invert(x, z); + return new SecT409FieldElement(z); + } + + public override ECFieldElement Sqrt() + { + ulong[] z = Nat448.Create64(); + SecT409Field.Sqrt(x, z); + return new SecT409FieldElement(z); + } + + public virtual int Representation + { + get { return F2mFieldElement.Tpb; } + } + + public virtual int M + { + get { return 409; } + } + + public virtual int K1 + { + get { return 87; } + } + + public virtual int K2 + { + get { return 0; } + } + + public virtual int K3 + { + get { return 0; } + } + + public override bool Equals(object obj) + { + return Equals(obj as SecT409FieldElement); + } + + public override bool Equals(ECFieldElement other) + { + return Equals(other as SecT409FieldElement); + } + + public virtual bool Equals(SecT409FieldElement other) + { + if (this == other) + return true; + if (null == other) + return false; + return Nat448.Eq64(x, other.x); + } + + public override int GetHashCode() + { + return 4090087 ^ Arrays.GetHashCode(x, 0, 7); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT409FieldElement.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT409FieldElement.cs.meta new file mode 100644 index 0000000..84dce42 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT409FieldElement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8676e18be069cca40a1590ea0b42b005 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT409K1Curve.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT409K1Curve.cs new file mode 100644 index 0000000..9e5fe88 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT409K1Curve.cs @@ -0,0 +1,183 @@ +using System; + +using Org.BouncyCastle.Math.EC.Multiplier; +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT409K1Curve + : AbstractF2mCurve + { + private const int SECT409K1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT409K1_FE_LONGS = 7; + private static readonly ECFieldElement[] SECT409K1_AFFINE_ZS = new ECFieldElement[] { new SecT409FieldElement(BigInteger.One) }; + + protected readonly SecT409K1Point m_infinity; + + public SecT409K1Curve() + : base(409, 87, 0, 0) + { + this.m_infinity = new SecT409K1Point(this, null, null); + + this.m_a = FromBigInteger(BigInteger.Zero); + this.m_b = FromBigInteger(BigInteger.One); + this.m_order = new BigInteger(1, Hex.DecodeStrict("7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF")); + this.m_cofactor = BigInteger.ValueOf(4); + + this.m_coord = SECT409K1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecT409K1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_LAMBDA_PROJECTIVE: + return true; + default: + return false; + } + } + + protected override ECMultiplier CreateDefaultMultiplier() + { + return new WTauNafMultiplier(); + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return 409; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecT409FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecT409K1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecT409K1Point(this, x, y, zs, withCompression); + } + + public override bool IsKoblitz + { + get { return true; } + } + + public virtual int M + { + get { return 409; } + } + + public virtual bool IsTrinomial + { + get { return true; } + } + + public virtual int K1 + { + get { return 87; } + } + + public virtual int K2 + { + get { return 0; } + } + + public virtual int K3 + { + get { return 0; } + } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + ulong[] table = new ulong[len * SECT409K1_FE_LONGS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat448.Copy64(((SecT409FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECT409K1_FE_LONGS; + Nat448.Copy64(((SecT409FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECT409K1_FE_LONGS; + } + } + + return new SecT409K1LookupTable(this, table, len); + } + + private class SecT409K1LookupTable + : AbstractECLookupTable + { + private readonly SecT409K1Curve m_outer; + private readonly ulong[] m_table; + private readonly int m_size; + + internal SecT409K1LookupTable(SecT409K1Curve outer, ulong[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public override int Size + { + get { return m_size; } + } + + public override ECPoint Lookup(int index) + { + ulong[] x = Nat448.Create64(), y = Nat448.Create64(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + ulong MASK = (ulong)(long)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECT409K1_FE_LONGS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECT409K1_FE_LONGS + j] & MASK; + } + + pos += (SECT409K1_FE_LONGS * 2); + } + + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + ulong[] x = Nat448.Create64(), y = Nat448.Create64(); + int pos = index * SECT409K1_FE_LONGS * 2; + + for (int j = 0; j < SECT409K1_FE_LONGS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECT409K1_FE_LONGS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(ulong[] x, ulong[] y) + { + return m_outer.CreateRawPoint(new SecT409FieldElement(x), new SecT409FieldElement(y), SECT409K1_AFFINE_ZS, false); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT409K1Curve.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT409K1Curve.cs.meta new file mode 100644 index 0000000..8cc86c5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT409K1Curve.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0c3aa839b7b3b324ca9d83de775e378c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT409K1Point.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT409K1Point.cs new file mode 100644 index 0000000..b127aea --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT409K1Point.cs @@ -0,0 +1,289 @@ +using System; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT409K1Point + : AbstractF2mPoint + { + /** + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecT409K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * @deprecated per-point compression property will be removed, refer {@link #getEncoded(bool)} + */ + public SecT409K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecT409K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecT409K1Point(null, this.AffineXCoord, this.AffineYCoord); // earlier JDK + } + + public override ECFieldElement YCoord + { + get + { + ECFieldElement X = RawXCoord, L = RawYCoord; + + if (this.IsInfinity || X.IsZero) + return L; + + // Y is actually Lambda (X + Y/X) here; convert to affine value on the fly + ECFieldElement Y = L.Add(X).Multiply(X); + + ECFieldElement Z = RawZCoords[0]; + if (!Z.IsOne) + { + Y = Y.Divide(Z); + } + + return Y; + } + } + + protected internal override bool CompressionYTilde + { + get + { + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return false; + + ECFieldElement Y = this.RawYCoord; + + // Y is actually Lambda (X + Y/X) here + return Y.TestBitZero() != X.TestBitZero(); + } + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + ECFieldElement X2 = b.RawXCoord; + + if (X1.IsZero) + { + if (X2.IsZero) + return curve.Infinity; + + return b.Add(this); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord, Z2 = b.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement U2 = X2, S2 = L2; + if (!Z1IsOne) + { + U2 = U2.Multiply(Z1); + S2 = S2.Multiply(Z1); + } + + bool Z2IsOne = Z2.IsOne; + ECFieldElement U1 = X1, S1 = L1; + if (!Z2IsOne) + { + U1 = U1.Multiply(Z2); + S1 = S1.Multiply(Z2); + } + + ECFieldElement A = S1.Add(S2); + ECFieldElement B = U1.Add(U2); + + if (B.IsZero) + { + if (A.IsZero) + return Twice(); + + return curve.Infinity; + } + + ECFieldElement X3, L3, Z3; + if (X2.IsZero) + { + // TODO This can probably be optimized quite a bit + ECPoint p = this.Normalize(); + X1 = p.XCoord; + ECFieldElement Y1 = p.YCoord; + + ECFieldElement Y2 = L2; + ECFieldElement L = Y1.Add(Y2).Divide(X1); + + X3 = L.Square().Add(L).Add(X1); + if (X3.IsZero) + { + return new SecT409K1Point(curve, X3, curve.B, IsCompressed); + } + + ECFieldElement Y3 = L.Multiply(X1.Add(X3)).Add(X3).Add(Y1); + L3 = Y3.Divide(X3).Add(X3); + Z3 = curve.FromBigInteger(BigInteger.One); + } + else + { + B = B.Square(); + + ECFieldElement AU1 = A.Multiply(U1); + ECFieldElement AU2 = A.Multiply(U2); + + X3 = AU1.Multiply(AU2); + if (X3.IsZero) + { + return new SecT409K1Point(curve, X3, curve.B, IsCompressed); + } + + ECFieldElement ABZ2 = A.Multiply(B); + if (!Z2IsOne) + { + ABZ2 = ABZ2.Multiply(Z2); + } + + L3 = AU2.Add(B).SquarePlusProduct(ABZ2, L1.Add(Z1)); + + Z3 = ABZ2; + if (!Z1IsOne) + { + Z3 = Z3.Multiply(Z1); + } + } + + return new SecT409K1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is its own additive inverse + return curve.Infinity; + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement Z1Sq = Z1IsOne ? Z1 : Z1.Square(); + ECFieldElement T; + if (Z1IsOne) + { + T = L1.Square().Add(L1); + } + else + { + T = L1.Add(Z1).Multiply(L1); + } + + if (T.IsZero) + { + return new SecT409K1Point(curve, T, curve.B, IsCompressed); + } + + ECFieldElement X3 = T.Square(); + ECFieldElement Z3 = Z1IsOne ? T : T.Multiply(Z1Sq); + + ECFieldElement t1 = L1.Add(X1).Square(); + ECFieldElement t2 = Z1IsOne ? Z1 : Z1Sq.Square(); + ECFieldElement L3 = t1.Add(T).Add(Z1Sq).Multiply(t1).Add(t2).Add(X3).Add(Z3); + + return new SecT409K1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is its own additive inverse + return b; + } + + // NOTE: TwicePlus() only optimized for lambda-affine argument + ECFieldElement X2 = b.RawXCoord, Z2 = b.RawZCoords[0]; + if (X2.IsZero || !Z2.IsOne) + { + return Twice().Add(b); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord; + + ECFieldElement X1Sq = X1.Square(); + ECFieldElement L1Sq = L1.Square(); + ECFieldElement Z1Sq = Z1.Square(); + ECFieldElement L1Z1 = L1.Multiply(Z1); + + ECFieldElement T = L1Sq.Add(L1Z1); + ECFieldElement L2plus1 = L2.AddOne(); + ECFieldElement A = L2plus1.Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); + ECFieldElement X2Z1Sq = X2.Multiply(Z1Sq); + ECFieldElement B = X2Z1Sq.Add(T).Square(); + + if (B.IsZero) + { + if (A.IsZero) + return b.Twice(); + + return curve.Infinity; + } + + if (A.IsZero) + { + return new SecT409K1Point(curve, A, curve.B, IsCompressed); + } + + ECFieldElement X3 = A.Square().Multiply(X2Z1Sq); + ECFieldElement Z3 = A.Multiply(B).Multiply(Z1Sq); + ECFieldElement L3 = A.Add(B).Square().MultiplyPlusProduct(T, L2plus1, Z3); + + return new SecT409K1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Negate() + { + if (this.IsInfinity) + return this; + + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return this; + + // L is actually Lambda (X + Y/X) here + ECFieldElement L = this.RawYCoord, Z = this.RawZCoords[0]; + return new SecT409K1Point(Curve, X, L.Add(Z), new ECFieldElement[] { Z }, IsCompressed); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT409K1Point.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT409K1Point.cs.meta new file mode 100644 index 0000000..9456b91 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT409K1Point.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: eb78fdd5e9856dd429dd4fefac16eaf5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT409R1Curve.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT409R1Curve.cs new file mode 100644 index 0000000..845c14b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT409R1Curve.cs @@ -0,0 +1,177 @@ +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT409R1Curve + : AbstractF2mCurve + { + private const int SECT409R1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT409R1_FE_LONGS = 7; + private static readonly ECFieldElement[] SECT409R1_AFFINE_ZS = new ECFieldElement[] { new SecT409FieldElement(BigInteger.One) }; + + protected readonly SecT409R1Point m_infinity; + + public SecT409R1Curve() + : base(409, 87, 0, 0) + { + this.m_infinity = new SecT409R1Point(this, null, null); + + this.m_a = FromBigInteger(BigInteger.One); + this.m_b = FromBigInteger(new BigInteger(1, Hex.DecodeStrict("0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F"))); + this.m_order = new BigInteger(1, Hex.DecodeStrict("010000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173")); + this.m_cofactor = BigInteger.Two; + + this.m_coord = SECT409R1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecT409R1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_LAMBDA_PROJECTIVE: + return true; + default: + return false; + } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return 409; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecT409FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecT409R1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecT409R1Point(this, x, y, zs, withCompression); + } + + public override bool IsKoblitz + { + get { return false; } + } + + public virtual int M + { + get { return 409; } + } + + public virtual bool IsTrinomial + { + get { return true; } + } + + public virtual int K1 + { + get { return 87; } + } + + public virtual int K2 + { + get { return 0; } + } + + public virtual int K3 + { + get { return 0; } + } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + ulong[] table = new ulong[len * SECT409R1_FE_LONGS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat448.Copy64(((SecT409FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECT409R1_FE_LONGS; + Nat448.Copy64(((SecT409FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECT409R1_FE_LONGS; + } + } + + return new SecT409R1LookupTable(this, table, len); + } + + private class SecT409R1LookupTable + : AbstractECLookupTable + { + private readonly SecT409R1Curve m_outer; + private readonly ulong[] m_table; + private readonly int m_size; + + internal SecT409R1LookupTable(SecT409R1Curve outer, ulong[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public override int Size + { + get { return m_size; } + } + + public override ECPoint Lookup(int index) + { + ulong[] x = Nat448.Create64(), y = Nat448.Create64(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + ulong MASK = (ulong)(long)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECT409R1_FE_LONGS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECT409R1_FE_LONGS + j] & MASK; + } + + pos += (SECT409R1_FE_LONGS * 2); + } + + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + ulong[] x = Nat448.Create64(), y = Nat448.Create64(); + int pos = index * SECT409R1_FE_LONGS * 2; + + for (int j = 0; j < SECT409R1_FE_LONGS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECT409R1_FE_LONGS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(ulong[] x, ulong[] y) + { + return m_outer.CreateRawPoint(new SecT409FieldElement(x), new SecT409FieldElement(y), SECT409R1_AFFINE_ZS, false); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT409R1Curve.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT409R1Curve.cs.meta new file mode 100644 index 0000000..f7913a9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT409R1Curve.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ad9281d43d634194c81b47ecaf02c4d6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT409R1Point.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT409R1Point.cs new file mode 100644 index 0000000..546b107 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT409R1Point.cs @@ -0,0 +1,278 @@ +using System; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT409R1Point + : AbstractF2mPoint + { + /** + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecT409R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * @deprecated per-point compression property will be removed, refer {@link #getEncoded(bool)} + */ + public SecT409R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecT409R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecT409R1Point(null, AffineXCoord, AffineYCoord); + } + + public override ECFieldElement YCoord + { + get + { + ECFieldElement X = RawXCoord, L = RawYCoord; + + if (this.IsInfinity || X.IsZero) + return L; + + // Y is actually Lambda (X + Y/X) here; convert to affine value on the fly + ECFieldElement Y = L.Add(X).Multiply(X); + + ECFieldElement Z = RawZCoords[0]; + if (!Z.IsOne) + { + Y = Y.Divide(Z); + } + + return Y; + } + } + + protected internal override bool CompressionYTilde + { + get + { + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return false; + + ECFieldElement Y = this.RawYCoord; + + // Y is actually Lambda (X + Y/X) here + return Y.TestBitZero() != X.TestBitZero(); + } + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + ECFieldElement X2 = b.RawXCoord; + + if (X1.IsZero) + { + if (X2.IsZero) + return curve.Infinity; + + return b.Add(this); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord, Z2 = b.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement U2 = X2, S2 = L2; + if (!Z1IsOne) + { + U2 = U2.Multiply(Z1); + S2 = S2.Multiply(Z1); + } + + bool Z2IsOne = Z2.IsOne; + ECFieldElement U1 = X1, S1 = L1; + if (!Z2IsOne) + { + U1 = U1.Multiply(Z2); + S1 = S1.Multiply(Z2); + } + + ECFieldElement A = S1.Add(S2); + ECFieldElement B = U1.Add(U2); + + if (B.IsZero) + { + if (A.IsZero) + return Twice(); + + return curve.Infinity; + } + + ECFieldElement X3, L3, Z3; + if (X2.IsZero) + { + // TODO This can probably be optimized quite a bit + ECPoint p = this.Normalize(); + X1 = p.XCoord; + ECFieldElement Y1 = p.YCoord; + + ECFieldElement Y2 = L2; + ECFieldElement L = Y1.Add(Y2).Divide(X1); + + X3 = L.Square().Add(L).Add(X1).AddOne(); + if (X3.IsZero) + { + return new SecT409R1Point(curve, X3, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement Y3 = L.Multiply(X1.Add(X3)).Add(X3).Add(Y1); + L3 = Y3.Divide(X3).Add(X3); + Z3 = curve.FromBigInteger(BigInteger.One); + } + else + { + B = B.Square(); + + ECFieldElement AU1 = A.Multiply(U1); + ECFieldElement AU2 = A.Multiply(U2); + + X3 = AU1.Multiply(AU2); + if (X3.IsZero) + { + return new SecT409R1Point(curve, X3, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement ABZ2 = A.Multiply(B); + if (!Z2IsOne) + { + ABZ2 = ABZ2.Multiply(Z2); + } + + L3 = AU2.Add(B).SquarePlusProduct(ABZ2, L1.Add(Z1)); + + Z3 = ABZ2; + if (!Z1IsOne) + { + Z3 = Z3.Multiply(Z1); + } + } + + return new SecT409R1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is its own additive inverse + return curve.Infinity; + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement L1Z1 = Z1IsOne ? L1 : L1.Multiply(Z1); + ECFieldElement Z1Sq = Z1IsOne ? Z1 : Z1.Square(); + ECFieldElement T = L1.Square().Add(L1Z1).Add(Z1Sq); + if (T.IsZero) + { + return new SecT409R1Point(curve, T, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement X3 = T.Square(); + ECFieldElement Z3 = Z1IsOne ? T : T.Multiply(Z1Sq); + + ECFieldElement X1Z1 = Z1IsOne ? X1 : X1.Multiply(Z1); + ECFieldElement L3 = X1Z1.SquarePlusProduct(T, L1Z1).Add(X3).Add(Z3); + + return new SecT409R1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is its own additive inverse + return b; + } + + ECFieldElement X2 = b.RawXCoord, Z2 = b.RawZCoords[0]; + if (X2.IsZero || !Z2.IsOne) + { + return Twice().Add(b); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord; + + ECFieldElement X1Sq = X1.Square(); + ECFieldElement L1Sq = L1.Square(); + ECFieldElement Z1Sq = Z1.Square(); + ECFieldElement L1Z1 = L1.Multiply(Z1); + + ECFieldElement T = Z1Sq.Add(L1Sq).Add(L1Z1); + ECFieldElement A = L2.Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); + ECFieldElement X2Z1Sq = X2.Multiply(Z1Sq); + ECFieldElement B = X2Z1Sq.Add(T).Square(); + + if (B.IsZero) + { + if (A.IsZero) + return b.Twice(); + + return curve.Infinity; + } + + if (A.IsZero) + { + return new SecT409R1Point(curve, A, curve.B.Sqrt(), IsCompressed); + } + + ECFieldElement X3 = A.Square().Multiply(X2Z1Sq); + ECFieldElement Z3 = A.Multiply(B).Multiply(Z1Sq); + ECFieldElement L3 = A.Add(B).Square().MultiplyPlusProduct(T, L2.AddOne(), Z3); + + return new SecT409R1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Negate() + { + if (this.IsInfinity) + return this; + + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return this; + + // L is actually Lambda (X + Y/X) here + ECFieldElement L = this.RawYCoord, Z = this.RawZCoords[0]; + return new SecT409R1Point(Curve, X, L.Add(Z), new ECFieldElement[] { Z }, IsCompressed); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT409R1Point.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT409R1Point.cs.meta new file mode 100644 index 0000000..90d59d6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT409R1Point.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: eb43a857f54bfdf4684ba1e83623a27f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT571Field.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT571Field.cs new file mode 100644 index 0000000..1b8bb76 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT571Field.cs @@ -0,0 +1,449 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT571Field + { + private const ulong M59 = ulong.MaxValue >> 5; + + private static readonly ulong[] ROOT_Z = new ulong[]{ 0x2BE1195F08CAFB99UL, 0x95F08CAF84657C23UL, + 0xCAF84657C232BE11UL, 0x657C232BE1195F08UL, 0xF84657C2308CAF84UL, 0x7C232BE1195F08CAUL, + 0xBE1195F08CAF8465UL, 0x5F08CAF84657C232UL, 0x784657C232BE119UL }; + + public static void Add(ulong[] x, ulong[] y, ulong[] z) + { + for (int i = 0; i < 9; ++i) + { + z[i] = x[i] ^ y[i]; + } + } + + private static void Add(ulong[] x, int xOff, ulong[] y, int yOff, ulong[] z, int zOff) + { + for (int i = 0; i < 9; ++i) + { + z[zOff + i] = x[xOff + i] ^ y[yOff + i]; + } + } + + public static void AddBothTo(ulong[] x, ulong[] y, ulong[] z) + { + for (int i = 0; i < 9; ++i) + { + z[i] ^= x[i] ^ y[i]; + } + } + + private static void AddBothTo(ulong[] x, int xOff, ulong[] y, int yOff, ulong[] z, int zOff) + { + for (int i = 0; i < 9; ++i) + { + z[zOff + i] ^= x[xOff + i] ^ y[yOff + i]; + } + } + + public static void AddExt(ulong[] xx, ulong[] yy, ulong[] zz) + { + for (int i = 0; i < 18; ++i) + { + zz[i] = xx[i] ^ yy[i]; + } + } + + public static void AddOne(ulong[] x, ulong[] z) + { + z[0] = x[0] ^ 1UL; + for (int i = 1; i < 9; ++i) + { + z[i] = x[i]; + } + } + + private static void AddTo(ulong[] x, ulong[] z) + { + for (int i = 0; i < 9; ++i) + { + z[i] ^= x[i]; + } + } + + public static ulong[] FromBigInteger(BigInteger x) + { + return Nat.FromBigInteger64(571, x); + } + + public static void HalfTrace(ulong[] x, ulong[] z) + { + ulong[] tt = Nat576.CreateExt64(); + + Nat576.Copy64(x, z); + for (int i = 1; i < 571; i += 2) + { + ImplSquare(z, tt); + Reduce(tt, z); + ImplSquare(z, tt); + Reduce(tt, z); + AddTo(x, z); + } + } + + public static void Invert(ulong[] x, ulong[] z) + { + if (Nat576.IsZero64(x)) + throw new InvalidOperationException(); + + // Itoh-Tsujii inversion with bases { 2, 3, 5 } + + ulong[] t0 = Nat576.Create64(); + ulong[] t1 = Nat576.Create64(); + ulong[] t2 = Nat576.Create64(); + + Square(x, t2); + + // 5 | 570 + Square(t2, t0); + Square(t0, t1); + Multiply(t0, t1, t0); + SquareN(t0, 2, t1); + Multiply(t0, t1, t0); + Multiply(t0, t2, t0); + + // 3 | 114 + SquareN(t0, 5, t1); + Multiply(t0, t1, t0); + SquareN(t1, 5, t1); + Multiply(t0, t1, t0); + + // 2 | 38 + SquareN(t0, 15, t1); + Multiply(t0, t1, t2); + + // ! {2,3,5} | 19 + SquareN(t2, 30, t0); + SquareN(t0, 30, t1); + Multiply(t0, t1, t0); + + // 3 | 9 + SquareN(t0, 60, t1); + Multiply(t0, t1, t0); + SquareN(t1, 60, t1); + Multiply(t0, t1, t0); + + // 3 | 3 + SquareN(t0, 180, t1); + Multiply(t0, t1, t0); + SquareN(t1, 180, t1); + Multiply(t0, t1, t0); + + Multiply(t0, t2, z); + } + + public static void Multiply(ulong[] x, ulong[] y, ulong[] z) + { + ulong[] tt = Nat576.CreateExt64(); + ImplMultiply(x, y, tt); + Reduce(tt, z); + } + + public static void MultiplyAddToExt(ulong[] x, ulong[] y, ulong[] zz) + { + ulong[] tt = Nat576.CreateExt64(); + ImplMultiply(x, y, tt); + AddExt(zz, tt, zz); + } + + public static void MultiplyPrecomp(ulong[] x, ulong[] precomp, ulong[] z) + { + ulong[] tt = Nat576.CreateExt64(); + ImplMultiplyPrecomp(x, precomp, tt); + Reduce(tt, z); + } + + public static void MultiplyPrecompAddToExt(ulong[] x, ulong[] precomp, ulong[] zz) + { + ulong[] tt = Nat576.CreateExt64(); + ImplMultiplyPrecomp(x, precomp, tt); + AddExt(zz, tt, zz); + } + + public static ulong[] PrecompMultiplicand(ulong[] x) + { + /* + * Precompute table of all 4-bit products of x (first section) + */ + int len = 9 << 4; + ulong[] t = new ulong[len << 1]; + Array.Copy(x, 0, t, 9, 9); + //Reduce5(t, 9); + int tOff = 0; + for (int i = 7; i > 0; --i) + { + tOff += 18; + Nat.ShiftUpBit64(9, t, tOff >> 1, 0UL, t, tOff); + Reduce5(t, tOff); + Add(t, 9, t, tOff, t, tOff + 9); + } + + /* + * Second section with all 4-bit products of x shifted 4 bits + */ + Nat.ShiftUpBits64(len, t, 0, 4, 0UL, t, len); + + return t; + } + + public static void Reduce(ulong[] xx, ulong[] z) + { + ulong xx09 = xx[9]; + ulong u = xx[17], v = xx09; + + xx09 = v ^ (u >> 59) ^ (u >> 57) ^ (u >> 54) ^ (u >> 49); + v = xx[8] ^ (u << 5) ^ (u << 7) ^ (u << 10) ^ (u << 15); + + for (int i = 16; i >= 10; --i) + { + u = xx[i]; + z[i - 8] = v ^ (u >> 59) ^ (u >> 57) ^ (u >> 54) ^ (u >> 49); + v = xx[i - 9] ^ (u << 5) ^ (u << 7) ^ (u << 10) ^ (u << 15); + } + + u = xx09; + z[1] = v ^ (u >> 59) ^ (u >> 57) ^ (u >> 54) ^ (u >> 49); + v = xx[0] ^ (u << 5) ^ (u << 7) ^ (u << 10) ^ (u << 15); + + ulong x08 = z[8]; + ulong t = x08 >> 59; + z[0] = v ^ t ^ (t << 2) ^ (t << 5) ^ (t << 10); + z[8] = x08 & M59; + } + + public static void Reduce5(ulong[] z, int zOff) + { + ulong z8 = z[zOff + 8], t = z8 >> 59; + z[zOff ] ^= t ^ (t << 2) ^ (t << 5) ^ (t << 10); + z[zOff + 8] = z8 & M59; + } + + public static void Sqrt(ulong[] x, ulong[] z) + { + ulong[] evn = Nat576.Create64(), odd = Nat576.Create64(); + + int pos = 0; + for (int i = 0; i < 4; ++i) + { + ulong u0 = Interleave.Unshuffle(x[pos++]); + ulong u1 = Interleave.Unshuffle(x[pos++]); + evn[i] = (u0 & 0x00000000FFFFFFFFUL) | (u1 << 32); + odd[i] = (u0 >> 32) | (u1 & 0xFFFFFFFF00000000UL); + } + { + ulong u0 = Interleave.Unshuffle(x[pos]); + evn[4] = (u0 & 0x00000000FFFFFFFFUL); + odd[4] = (u0 >> 32); + } + + Multiply(odd, ROOT_Z, z); + Add(z, evn, z); + } + + public static void Square(ulong[] x, ulong[] z) + { + ulong[] tt = Nat576.CreateExt64(); + ImplSquare(x, tt); + Reduce(tt, z); + } + + public static void SquareAddToExt(ulong[] x, ulong[] zz) + { + ulong[] tt = Nat576.CreateExt64(); + ImplSquare(x, tt); + AddExt(zz, tt, zz); + } + + public static void SquareN(ulong[] x, int n, ulong[] z) + { + Debug.Assert(n > 0); + + ulong[] tt = Nat576.CreateExt64(); + ImplSquare(x, tt); + Reduce(tt, z); + + while (--n > 0) + { + ImplSquare(z, tt); + Reduce(tt, z); + } + } + + public static uint Trace(ulong[] x) + { + // Non-zero-trace bits: 0, 561, 569 + return (uint)(x[0] ^ (x[8] >> 49) ^ (x[8] >> 57)) & 1U; + } + + protected static void ImplMultiply(ulong[] x, ulong[] y, ulong[] zz) + { + //ulong[] precomp = PrecompMultiplicand(y); + + //ImplMultiplyPrecomp(x, precomp, zz); + + ulong[] u = new ulong[16]; + for (int i = 0; i < 9; ++i) + { + ImplMulwAcc(u, x[i], y[i], zz, i << 1); + } + + ulong v0 = zz[0], v1 = zz[1]; + v0 ^= zz[ 2]; zz[1] = v0 ^ v1; v1 ^= zz[ 3]; + v0 ^= zz[ 4]; zz[2] = v0 ^ v1; v1 ^= zz[ 5]; + v0 ^= zz[ 6]; zz[3] = v0 ^ v1; v1 ^= zz[ 7]; + v0 ^= zz[ 8]; zz[4] = v0 ^ v1; v1 ^= zz[ 9]; + v0 ^= zz[10]; zz[5] = v0 ^ v1; v1 ^= zz[11]; + v0 ^= zz[12]; zz[6] = v0 ^ v1; v1 ^= zz[13]; + v0 ^= zz[14]; zz[7] = v0 ^ v1; v1 ^= zz[15]; + v0 ^= zz[16]; zz[8] = v0 ^ v1; v1 ^= zz[17]; + + ulong w = v0 ^ v1; + zz[ 9] = zz[0] ^ w; + zz[10] = zz[1] ^ w; + zz[11] = zz[2] ^ w; + zz[12] = zz[3] ^ w; + zz[13] = zz[4] ^ w; + zz[14] = zz[5] ^ w; + zz[15] = zz[6] ^ w; + zz[16] = zz[7] ^ w; + zz[17] = zz[8] ^ w; + + ImplMulwAcc(u, x[0] ^ x[1], y[0] ^ y[1], zz, 1); + + ImplMulwAcc(u, x[0] ^ x[2], y[0] ^ y[2], zz, 2); + + ImplMulwAcc(u, x[0] ^ x[3], y[0] ^ y[3], zz, 3); + ImplMulwAcc(u, x[1] ^ x[2], y[1] ^ y[2], zz, 3); + + ImplMulwAcc(u, x[0] ^ x[4], y[0] ^ y[4], zz, 4); + ImplMulwAcc(u, x[1] ^ x[3], y[1] ^ y[3], zz, 4); + + ImplMulwAcc(u, x[0] ^ x[5], y[0] ^ y[5], zz, 5); + ImplMulwAcc(u, x[1] ^ x[4], y[1] ^ y[4], zz, 5); + ImplMulwAcc(u, x[2] ^ x[3], y[2] ^ y[3], zz, 5); + + ImplMulwAcc(u, x[0] ^ x[6], y[0] ^ y[6], zz, 6); + ImplMulwAcc(u, x[1] ^ x[5], y[1] ^ y[5], zz, 6); + ImplMulwAcc(u, x[2] ^ x[4], y[2] ^ y[4], zz, 6); + + ImplMulwAcc(u, x[0] ^ x[7], y[0] ^ y[7], zz, 7); + ImplMulwAcc(u, x[1] ^ x[6], y[1] ^ y[6], zz, 7); + ImplMulwAcc(u, x[2] ^ x[5], y[2] ^ y[5], zz, 7); + ImplMulwAcc(u, x[3] ^ x[4], y[3] ^ y[4], zz, 7); + + ImplMulwAcc(u, x[0] ^ x[8], y[0] ^ y[8], zz, 8); + ImplMulwAcc(u, x[1] ^ x[7], y[1] ^ y[7], zz, 8); + ImplMulwAcc(u, x[2] ^ x[6], y[2] ^ y[6], zz, 8); + ImplMulwAcc(u, x[3] ^ x[5], y[3] ^ y[5], zz, 8); + + ImplMulwAcc(u, x[1] ^ x[8], y[1] ^ y[8], zz, 9); + ImplMulwAcc(u, x[2] ^ x[7], y[2] ^ y[7], zz, 9); + ImplMulwAcc(u, x[3] ^ x[6], y[3] ^ y[6], zz, 9); + ImplMulwAcc(u, x[4] ^ x[5], y[4] ^ y[5], zz, 9); + + ImplMulwAcc(u, x[2] ^ x[8], y[2] ^ y[8], zz, 10); + ImplMulwAcc(u, x[3] ^ x[7], y[3] ^ y[7], zz, 10); + ImplMulwAcc(u, x[4] ^ x[6], y[4] ^ y[6], zz, 10); + + ImplMulwAcc(u, x[3] ^ x[8], y[3] ^ y[8], zz, 11); + ImplMulwAcc(u, x[4] ^ x[7], y[4] ^ y[7], zz, 11); + ImplMulwAcc(u, x[5] ^ x[6], y[5] ^ y[6], zz, 11); + + ImplMulwAcc(u, x[4] ^ x[8], y[4] ^ y[8], zz, 12); + ImplMulwAcc(u, x[5] ^ x[7], y[5] ^ y[7], zz, 12); + + ImplMulwAcc(u, x[5] ^ x[8], y[5] ^ y[8], zz, 13); + ImplMulwAcc(u, x[6] ^ x[7], y[6] ^ y[7], zz, 13); + + ImplMulwAcc(u, x[6] ^ x[8], y[6] ^ y[8], zz, 14); + + ImplMulwAcc(u, x[7] ^ x[8], y[7] ^ y[8], zz, 15); + } + + protected static void ImplMultiplyPrecomp(ulong[] x, ulong[] precomp, ulong[] zz) + { + uint MASK = 0xF; + + /* + * Lopez-Dahab algorithm + */ + + for (int k = 56; k >= 0; k -= 8) + { + for (int j = 1; j < 9; j += 2) + { + uint aVal = (uint)(x[j] >> k); + uint u = aVal & MASK; + uint v = (aVal >> 4) & MASK; + AddBothTo(precomp, (int)(9 * u), precomp, (int)(9 * (v + 16)), zz, j - 1); + } + Nat.ShiftUpBits64(16, zz, 0, 8, 0UL); + } + + for (int k = 56; k >= 0; k -= 8) + { + for (int j = 0; j < 9; j += 2) + { + uint aVal = (uint)(x[j] >> k); + uint u = aVal & MASK; + uint v = (aVal >> 4) & MASK; + AddBothTo(precomp, (int)(9 * u), precomp, (int)(9 * (v + 16)), zz, j); + } + if (k > 0) + { + Nat.ShiftUpBits64(18, zz, 0, 8, 0UL); + } + } + } + + protected static void ImplMulwAcc(ulong[] u, ulong x, ulong y, ulong[] z, int zOff) + { + //u[0] = 0; + u[1] = y; + for (int i = 2; i < 16; i += 2) + { + u[i ] = u[i >> 1] << 1; + u[i + 1] = u[i ] ^ y; + } + + uint j = (uint)x; + ulong g, h = 0, l = u[j & 15] + ^ u[(j >> 4) & 15] << 4; + int k = 56; + do + { + j = (uint)(x >> k); + g = u[j & 15] + ^ u[(j >> 4) & 15] << 4; + l ^= (g << k); + h ^= (g >> -k); + } + while ((k -= 8) > 0); + + for (int p = 0; p < 7; ++p) + { + x = (x & 0xFEFEFEFEFEFEFEFEUL) >> 1; + h ^= x & (ulong)((long)(y << p) >> 63); + } + + Debug.Assert(h >> 63 == 0); + + z[zOff ] ^= l; + z[zOff + 1] ^= h; + } + + protected static void ImplSquare(ulong[] x, ulong[] zz) + { + Interleave.Expand64To128(x, 0, 9, zz, 0); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT571Field.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT571Field.cs.meta new file mode 100644 index 0000000..cd70a7b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT571Field.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9f5915b98210f5849b12af63e65284e4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT571FieldElement.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT571FieldElement.cs new file mode 100644 index 0000000..22edfe0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT571FieldElement.cs @@ -0,0 +1,233 @@ +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT571FieldElement + : AbstractF2mFieldElement + { + protected internal readonly ulong[] x; + + public SecT571FieldElement(BigInteger x) + { + if (x == null || x.SignValue < 0 || x.BitLength > 571) + throw new ArgumentException("value invalid for SecT571FieldElement", "x"); + + this.x = SecT571Field.FromBigInteger(x); + } + + public SecT571FieldElement() + { + this.x = Nat576.Create64(); + } + + protected internal SecT571FieldElement(ulong[] x) + { + this.x = x; + } + + public override bool IsOne + { + get { return Nat576.IsOne64(x); } + } + + public override bool IsZero + { + get { return Nat576.IsZero64(x); } + } + + public override bool TestBitZero() + { + return (x[0] & 1UL) != 0UL; + } + + public override BigInteger ToBigInteger() + { + return Nat576.ToBigInteger64(x); + } + + public override String FieldName + { + get { return "SecT571Field"; } + } + + public override int FieldSize + { + get { return 571; } + } + + public override ECFieldElement Add(ECFieldElement b) + { + ulong[] z = Nat576.Create64(); + SecT571Field.Add(x, ((SecT571FieldElement)b).x, z); + return new SecT571FieldElement(z); + } + + public override ECFieldElement AddOne() + { + ulong[] z = Nat576.Create64(); + SecT571Field.AddOne(x, z); + return new SecT571FieldElement(z); + } + + public override ECFieldElement Subtract(ECFieldElement b) + { + // Addition and subtraction are the same in F2m + return Add(b); + } + + public override ECFieldElement Multiply(ECFieldElement b) + { + ulong[] z = Nat576.Create64(); + SecT571Field.Multiply(x, ((SecT571FieldElement)b).x, z); + return new SecT571FieldElement(z); + } + + public override ECFieldElement MultiplyMinusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) + { + return MultiplyPlusProduct(b, x, y); + } + + public override ECFieldElement MultiplyPlusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) + { + ulong[] ax = this.x, bx = ((SecT571FieldElement)b).x; + ulong[] xx = ((SecT571FieldElement)x).x, yx = ((SecT571FieldElement)y).x; + + ulong[] tt = Nat576.CreateExt64(); + SecT571Field.MultiplyAddToExt(ax, bx, tt); + SecT571Field.MultiplyAddToExt(xx, yx, tt); + + ulong[] z = Nat576.Create64(); + SecT571Field.Reduce(tt, z); + return new SecT571FieldElement(z); + } + + public override ECFieldElement Divide(ECFieldElement b) + { + return Multiply(b.Invert()); + } + + public override ECFieldElement Negate() + { + return this; + } + + public override ECFieldElement Square() + { + ulong[] z = Nat576.Create64(); + SecT571Field.Square(x, z); + return new SecT571FieldElement(z); + } + + public override ECFieldElement SquareMinusProduct(ECFieldElement x, ECFieldElement y) + { + return SquarePlusProduct(x, y); + } + + public override ECFieldElement SquarePlusProduct(ECFieldElement x, ECFieldElement y) + { + ulong[] ax = this.x; + ulong[] xx = ((SecT571FieldElement)x).x, yx = ((SecT571FieldElement)y).x; + + ulong[] tt = Nat576.CreateExt64(); + SecT571Field.SquareAddToExt(ax, tt); + SecT571Field.MultiplyAddToExt(xx, yx, tt); + + ulong[] z = Nat576.Create64(); + SecT571Field.Reduce(tt, z); + return new SecT571FieldElement(z); + } + + public override ECFieldElement SquarePow(int pow) + { + if (pow < 1) + return this; + + ulong[] z = Nat576.Create64(); + SecT571Field.SquareN(x, pow, z); + return new SecT571FieldElement(z); + } + + public override ECFieldElement HalfTrace() + { + ulong[] z = Nat576.Create64(); + SecT571Field.HalfTrace(x, z); + return new SecT571FieldElement(z); + } + + public override bool HasFastTrace + { + get { return true; } + } + + public override int Trace() + { + return (int)SecT571Field.Trace(x); + } + + public override ECFieldElement Invert() + { + ulong[] z = Nat576.Create64(); + SecT571Field.Invert(x, z); + return new SecT571FieldElement(z); + } + + public override ECFieldElement Sqrt() + { + ulong[] z = Nat576.Create64(); + SecT571Field.Sqrt(x, z); + return new SecT571FieldElement(z); + } + + public virtual int Representation + { + get { return F2mFieldElement.Ppb; } + } + + public virtual int M + { + get { return 571; } + } + + public virtual int K1 + { + get { return 2; } + } + + public virtual int K2 + { + get { return 5; } + } + + public virtual int K3 + { + get { return 10; } + } + + public override bool Equals(object obj) + { + return Equals(obj as SecT571FieldElement); + } + + public override bool Equals(ECFieldElement other) + { + return Equals(other as SecT571FieldElement); + } + + public virtual bool Equals(SecT571FieldElement other) + { + if (this == other) + return true; + if (null == other) + return false; + return Nat576.Eq64(x, other.x); + } + + public override int GetHashCode() + { + return 5711052 ^ Arrays.GetHashCode(x, 0, 9); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT571FieldElement.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT571FieldElement.cs.meta new file mode 100644 index 0000000..be11243 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT571FieldElement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d3b6532937aea634e870e9a9c7db2dfe +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT571K1Curve.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT571K1Curve.cs new file mode 100644 index 0000000..544a1ba --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT571K1Curve.cs @@ -0,0 +1,183 @@ +using System; + +using Org.BouncyCastle.Math.EC.Multiplier; +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT571K1Curve + : AbstractF2mCurve + { + private const int SECT571K1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT571K1_FE_LONGS = 9; + private static readonly ECFieldElement[] SECT571K1_AFFINE_ZS = new ECFieldElement[] { new SecT571FieldElement(BigInteger.One) }; + + protected readonly SecT571K1Point m_infinity; + + public SecT571K1Curve() + : base(571, 2, 5, 10) + { + this.m_infinity = new SecT571K1Point(this, null, null); + + this.m_a = FromBigInteger(BigInteger.Zero); + this.m_b = FromBigInteger(BigInteger.One); + this.m_order = new BigInteger(1, Hex.DecodeStrict("020000000000000000000000000000000000000000000000000000000000000000000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001")); + this.m_cofactor = BigInteger.ValueOf(4); + + this.m_coord = SECT571K1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecT571K1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_LAMBDA_PROJECTIVE: + return true; + default: + return false; + } + } + + protected override ECMultiplier CreateDefaultMultiplier() + { + return new WTauNafMultiplier(); + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return 571; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecT571FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecT571K1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecT571K1Point(this, x, y, zs, withCompression); + } + + public override bool IsKoblitz + { + get { return true; } + } + + public virtual int M + { + get { return 571; } + } + + public virtual bool IsTrinomial + { + get { return false; } + } + + public virtual int K1 + { + get { return 2; } + } + + public virtual int K2 + { + get { return 5; } + } + + public virtual int K3 + { + get { return 10; } + } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + ulong[] table = new ulong[len * SECT571K1_FE_LONGS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat576.Copy64(((SecT571FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECT571K1_FE_LONGS; + Nat576.Copy64(((SecT571FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECT571K1_FE_LONGS; + } + } + + return new SecT571K1LookupTable(this, table, len); + } + + private class SecT571K1LookupTable + : AbstractECLookupTable + { + private readonly SecT571K1Curve m_outer; + private readonly ulong[] m_table; + private readonly int m_size; + + internal SecT571K1LookupTable(SecT571K1Curve outer, ulong[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public override int Size + { + get { return m_size; } + } + + public override ECPoint Lookup(int index) + { + ulong[] x = Nat576.Create64(), y = Nat576.Create64(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + ulong MASK = (ulong)(long)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECT571K1_FE_LONGS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECT571K1_FE_LONGS + j] & MASK; + } + + pos += (SECT571K1_FE_LONGS * 2); + } + + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + ulong[] x = Nat576.Create64(), y = Nat576.Create64(); + int pos = index * SECT571K1_FE_LONGS * 2; + + for (int j = 0; j < SECT571K1_FE_LONGS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECT571K1_FE_LONGS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(ulong[] x, ulong[] y) + { + return m_outer.CreateRawPoint(new SecT571FieldElement(x), new SecT571FieldElement(y), SECT571K1_AFFINE_ZS, false); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT571K1Curve.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT571K1Curve.cs.meta new file mode 100644 index 0000000..8667beb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT571K1Curve.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2f1f7f488c2788745a4a4c022db4b976 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT571K1Point.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT571K1Point.cs new file mode 100644 index 0000000..0f132c8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT571K1Point.cs @@ -0,0 +1,327 @@ +using System; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT571K1Point + : AbstractF2mPoint + { + /** + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecT571K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * @deprecated per-point compression property will be removed, refer {@link #getEncoded(bool)} + */ + public SecT571K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecT571K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecT571K1Point(null, this.AffineXCoord, this.AffineYCoord); // earlier JDK + } + + public override ECFieldElement YCoord + { + get + { + ECFieldElement X = RawXCoord, L = RawYCoord; + + if (this.IsInfinity || X.IsZero) + return L; + + // Y is actually Lambda (X + Y/X) here; convert to affine value on the fly + ECFieldElement Y = L.Add(X).Multiply(X); + + ECFieldElement Z = RawZCoords[0]; + if (!Z.IsOne) + { + Y = Y.Divide(Z); + } + + return Y; + } + } + + protected internal override bool CompressionYTilde + { + get + { + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return false; + + ECFieldElement Y = this.RawYCoord; + + // Y is actually Lambda (X + Y/X) here + return Y.TestBitZero() != X.TestBitZero(); + } + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + SecT571FieldElement X1 = (SecT571FieldElement)this.RawXCoord; + SecT571FieldElement X2 = (SecT571FieldElement)b.RawXCoord; + + if (X1.IsZero) + { + if (X2.IsZero) + return curve.Infinity; + + return b.Add(this); + } + + SecT571FieldElement L1 = (SecT571FieldElement)this.RawYCoord, Z1 = (SecT571FieldElement)this.RawZCoords[0]; + SecT571FieldElement L2 = (SecT571FieldElement)b.RawYCoord, Z2 = (SecT571FieldElement)b.RawZCoords[0]; + + ulong[] t1 = Nat576.Create64(); + ulong[] t2 = Nat576.Create64(); + ulong[] t3 = Nat576.Create64(); + ulong[] t4 = Nat576.Create64(); + + ulong[] Z1Precomp = Z1.IsOne ? null : SecT571Field.PrecompMultiplicand(Z1.x); + ulong[] U2, S2; + if (Z1Precomp == null) + { + U2 = X2.x; + S2 = L2.x; + } + else + { + SecT571Field.MultiplyPrecomp(X2.x, Z1Precomp, U2 = t2); + SecT571Field.MultiplyPrecomp(L2.x, Z1Precomp, S2 = t4); + } + + ulong[] Z2Precomp = Z2.IsOne ? null : SecT571Field.PrecompMultiplicand(Z2.x); + ulong[] U1, S1; + if (Z2Precomp == null) + { + U1 = X1.x; + S1 = L1.x; + } + else + { + SecT571Field.MultiplyPrecomp(X1.x, Z2Precomp, U1 = t1); + SecT571Field.MultiplyPrecomp(L1.x, Z2Precomp, S1 = t3); + } + + ulong[] A = t3; + SecT571Field.Add(S1, S2, A); + + ulong[] B = t4; + SecT571Field.Add(U1, U2, B); + + if (Nat576.IsZero64(B)) + { + if (Nat576.IsZero64(A)) + return Twice(); + + return curve.Infinity; + } + + SecT571FieldElement X3, L3, Z3; + if (X2.IsZero) + { + // TODO This can probably be optimized quite a bit + ECPoint p = this.Normalize(); + X1 = (SecT571FieldElement)p.XCoord; + ECFieldElement Y1 = p.YCoord; + + ECFieldElement Y2 = L2; + ECFieldElement L = Y1.Add(Y2).Divide(X1); + + X3 = (SecT571FieldElement)L.Square().Add(L).Add(X1); + if (X3.IsZero) + { + return new SecT571K1Point(curve, X3, curve.B, IsCompressed); + } + + ECFieldElement Y3 = L.Multiply(X1.Add(X3)).Add(X3).Add(Y1); + L3 = (SecT571FieldElement)Y3.Divide(X3).Add(X3); + Z3 = (SecT571FieldElement)curve.FromBigInteger(BigInteger.One); + } + else + { + SecT571Field.Square(B, B); + + ulong[] APrecomp = SecT571Field.PrecompMultiplicand(A); + + ulong[] AU1 = t1; + ulong[] AU2 = t2; + + SecT571Field.MultiplyPrecomp(U1, APrecomp, AU1); + SecT571Field.MultiplyPrecomp(U2, APrecomp, AU2); + + X3 = new SecT571FieldElement(t1); + SecT571Field.Multiply(AU1, AU2, X3.x); + + if (X3.IsZero) + { + return new SecT571K1Point(curve, X3, curve.B, IsCompressed); + } + + Z3 = new SecT571FieldElement(t3); + SecT571Field.MultiplyPrecomp(B, APrecomp, Z3.x); + + if (Z2Precomp != null) + { + SecT571Field.MultiplyPrecomp(Z3.x, Z2Precomp, Z3.x); + } + + //L3 = AU2.Add(B).SquarePlusProduct(ABZ2, L1.Add(Z1)); + ulong[] tt = Nat576.CreateExt64(); + + SecT571Field.Add(AU2, B, t4); + SecT571Field.SquareAddToExt(t4, tt); + + SecT571Field.Add(L1.x, Z1.x, t4); + SecT571Field.MultiplyAddToExt(t4, Z3.x, tt); + + L3 = new SecT571FieldElement(t4); + SecT571Field.Reduce(tt, L3.x); + + if (Z1Precomp != null) + { + SecT571Field.MultiplyPrecomp(Z3.x, Z1Precomp, Z3.x); + } + } + + return new SecT571K1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is its own additive inverse + return curve.Infinity; + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + + bool Z1IsOne = Z1.IsOne; + ECFieldElement Z1Sq = Z1IsOne ? Z1 : Z1.Square(); + ECFieldElement T; + if (Z1IsOne) + { + T = L1.Square().Add(L1); + } + else + { + T = L1.Add(Z1).Multiply(L1); + } + + if (T.IsZero) + { + return new SecT571K1Point(curve, T, curve.B, IsCompressed); + } + + ECFieldElement X3 = T.Square(); + ECFieldElement Z3 = Z1IsOne ? T : T.Multiply(Z1Sq); + + ECFieldElement t1 = L1.Add(X1).Square(); + ECFieldElement t2 = Z1IsOne ? Z1 : Z1Sq.Square(); + ECFieldElement L3 = t1.Add(T).Add(Z1Sq).Multiply(t1).Add(t2).Add(X3).Add(Z3); + + return new SecT571K1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is its own additive inverse + return b; + } + + // NOTE: TwicePlus() only optimized for lambda-affine argument + ECFieldElement X2 = b.RawXCoord, Z2 = b.RawZCoords[0]; + if (X2.IsZero || !Z2.IsOne) + { + return Twice().Add(b); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord; + + ECFieldElement X1Sq = X1.Square(); + ECFieldElement L1Sq = L1.Square(); + ECFieldElement Z1Sq = Z1.Square(); + ECFieldElement L1Z1 = L1.Multiply(Z1); + + ECFieldElement T = L1Sq.Add(L1Z1); + ECFieldElement L2plus1 = L2.AddOne(); + ECFieldElement A = L2plus1.Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); + ECFieldElement X2Z1Sq = X2.Multiply(Z1Sq); + ECFieldElement B = X2Z1Sq.Add(T).Square(); + + if (B.IsZero) + { + if (A.IsZero) + return b.Twice(); + + return curve.Infinity; + } + + if (A.IsZero) + { + return new SecT571K1Point(curve, A, curve.B, IsCompressed); + } + + ECFieldElement X3 = A.Square().Multiply(X2Z1Sq); + ECFieldElement Z3 = A.Multiply(B).Multiply(Z1Sq); + ECFieldElement L3 = A.Add(B).Square().MultiplyPlusProduct(T, L2plus1, Z3); + + return new SecT571K1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Negate() + { + if (this.IsInfinity) + return this; + + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return this; + + // L is actually Lambda (X + Y/X) here + ECFieldElement L = this.RawYCoord, Z = this.RawZCoords[0]; + return new SecT571K1Point(Curve, X, L.Add(Z), new ECFieldElement[] { Z }, IsCompressed); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT571K1Point.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT571K1Point.cs.meta new file mode 100644 index 0000000..ba9f363 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT571K1Point.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 540f96c2524a80b419ecbea7a26ee9d0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT571R1Curve.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT571R1Curve.cs new file mode 100644 index 0000000..67343b0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT571R1Curve.cs @@ -0,0 +1,181 @@ +using System; + +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT571R1Curve + : AbstractF2mCurve + { + private const int SECT571R1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT571R1_FE_LONGS = 9; + private static readonly ECFieldElement[] SECT571R1_AFFINE_ZS = new ECFieldElement[] { new SecT571FieldElement(BigInteger.One) }; + + protected readonly SecT571R1Point m_infinity; + + internal static readonly SecT571FieldElement SecT571R1_B = new SecT571FieldElement( + new BigInteger(1, Hex.DecodeStrict("02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A"))); + internal static readonly SecT571FieldElement SecT571R1_B_SQRT = (SecT571FieldElement)SecT571R1_B.Sqrt(); + + public SecT571R1Curve() + : base(571, 2, 5, 10) + { + this.m_infinity = new SecT571R1Point(this, null, null); + + this.m_a = FromBigInteger(BigInteger.One); + this.m_b = SecT571R1_B; + this.m_order = new BigInteger(1, Hex.DecodeStrict("03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47")); + this.m_cofactor = BigInteger.Two; + + this.m_coord = SECT571R1_DEFAULT_COORDS; + } + + protected override ECCurve CloneCurve() + { + return new SecT571R1Curve(); + } + + public override bool SupportsCoordinateSystem(int coord) + { + switch (coord) + { + case COORD_LAMBDA_PROJECTIVE: + return true; + default: + return false; + } + } + + public override ECPoint Infinity + { + get { return m_infinity; } + } + + public override int FieldSize + { + get { return 571; } + } + + public override ECFieldElement FromBigInteger(BigInteger x) + { + return new SecT571FieldElement(x); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) + { + return new SecT571R1Point(this, x, y, withCompression); + } + + protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + { + return new SecT571R1Point(this, x, y, zs, withCompression); + } + + public override bool IsKoblitz + { + get { return false; } + } + + public virtual int M + { + get { return 571; } + } + + public virtual bool IsTrinomial + { + get { return false; } + } + + public virtual int K1 + { + get { return 2; } + } + + public virtual int K2 + { + get { return 5; } + } + + public virtual int K3 + { + get { return 10; } + } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + ulong[] table = new ulong[len * SECT571R1_FE_LONGS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat576.Copy64(((SecT571FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECT571R1_FE_LONGS; + Nat576.Copy64(((SecT571FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECT571R1_FE_LONGS; + } + } + + return new SecT571R1LookupTable(this, table, len); + } + + private class SecT571R1LookupTable + : AbstractECLookupTable + { + private readonly SecT571R1Curve m_outer; + private readonly ulong[] m_table; + private readonly int m_size; + + internal SecT571R1LookupTable(SecT571R1Curve outer, ulong[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public override int Size + { + get { return m_size; } + } + + public override ECPoint Lookup(int index) + { + ulong[] x = Nat576.Create64(), y = Nat576.Create64(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + ulong MASK = (ulong)(long)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECT571R1_FE_LONGS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECT571R1_FE_LONGS + j] & MASK; + } + + pos += (SECT571R1_FE_LONGS * 2); + } + + return CreatePoint(x, y); + } + + public override ECPoint LookupVar(int index) + { + ulong[] x = Nat576.Create64(), y = Nat576.Create64(); + int pos = index * SECT571R1_FE_LONGS * 2; + + for (int j = 0; j < SECT571R1_FE_LONGS; ++j) + { + x[j] = m_table[pos + j]; + y[j] = m_table[pos + SECT571R1_FE_LONGS + j]; + } + + return CreatePoint(x, y); + } + + private ECPoint CreatePoint(ulong[] x, ulong[] y) + { + return m_outer.CreateRawPoint(new SecT571FieldElement(x), new SecT571FieldElement(y), SECT571R1_AFFINE_ZS, false); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT571R1Curve.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT571R1Curve.cs.meta new file mode 100644 index 0000000..623a3f1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT571R1Curve.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b64c518740907be47a91b303aa42a165 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT571R1Point.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT571R1Point.cs new file mode 100644 index 0000000..6a82a5e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT571R1Point.cs @@ -0,0 +1,352 @@ +using System; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Custom.Sec +{ + internal class SecT571R1Point + : AbstractF2mPoint + { + /** + * @deprecated Use ECCurve.createPoint to construct points + */ + public SecT571R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y) + : this(curve, x, y, false) + { + } + + /** + * @deprecated per-point compression property will be removed, refer {@link #getEncoded(bool)} + */ + public SecT571R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression) + : base(curve, x, y, withCompression) + { + if ((x == null) != (y == null)) + throw new ArgumentException("Exactly one of the field elements is null"); + } + + internal SecT571R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) + : base(curve, x, y, zs, withCompression) + { + } + + protected override ECPoint Detach() + { + return new SecT571R1Point(null, AffineXCoord, AffineYCoord); + } + + public override ECFieldElement YCoord + { + get + { + ECFieldElement X = RawXCoord, L = RawYCoord; + + if (this.IsInfinity || X.IsZero) + return L; + + // Y is actually Lambda (X + Y/X) here; convert to affine value on the fly + ECFieldElement Y = L.Add(X).Multiply(X); + + ECFieldElement Z = RawZCoords[0]; + if (!Z.IsOne) + { + Y = Y.Divide(Z); + } + + return Y; + } + } + + protected internal override bool CompressionYTilde + { + get + { + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return false; + + ECFieldElement Y = this.RawYCoord; + + // Y is actually Lambda (X + Y/X) here + return Y.TestBitZero() != X.TestBitZero(); + } + } + + public override ECPoint Add(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + SecT571FieldElement X1 = (SecT571FieldElement)this.RawXCoord; + SecT571FieldElement X2 = (SecT571FieldElement)b.RawXCoord; + + if (X1.IsZero) + { + if (X2.IsZero) + return curve.Infinity; + + return b.Add(this); + } + + SecT571FieldElement L1 = (SecT571FieldElement)this.RawYCoord, Z1 = (SecT571FieldElement)this.RawZCoords[0]; + SecT571FieldElement L2 = (SecT571FieldElement)b.RawYCoord, Z2 = (SecT571FieldElement)b.RawZCoords[0]; + + ulong[] t1 = Nat576.Create64(); + ulong[] t2 = Nat576.Create64(); + ulong[] t3 = Nat576.Create64(); + ulong[] t4 = Nat576.Create64(); + + ulong[] Z1Precomp = Z1.IsOne ? null : SecT571Field.PrecompMultiplicand(Z1.x); + ulong[] U2, S2; + if (Z1Precomp == null) + { + U2 = X2.x; + S2 = L2.x; + } + else + { + SecT571Field.MultiplyPrecomp(X2.x, Z1Precomp, U2 = t2); + SecT571Field.MultiplyPrecomp(L2.x, Z1Precomp, S2 = t4); + } + + ulong[] Z2Precomp = Z2.IsOne ? null : SecT571Field.PrecompMultiplicand(Z2.x); + ulong[] U1, S1; + if (Z2Precomp == null) + { + U1 = X1.x; + S1 = L1.x; + } + else + { + SecT571Field.MultiplyPrecomp(X1.x, Z2Precomp, U1 = t1); + SecT571Field.MultiplyPrecomp(L1.x, Z2Precomp, S1 = t3); + } + + ulong[] A = t3; + SecT571Field.Add(S1, S2, A); + + ulong[] B = t4; + SecT571Field.Add(U1, U2, B); + + if (Nat576.IsZero64(B)) + { + if (Nat576.IsZero64(A)) + return Twice(); + + return curve.Infinity; + } + + SecT571FieldElement X3, L3, Z3; + if (X2.IsZero) + { + // TODO This can probably be optimized quite a bit + ECPoint p = this.Normalize(); + X1 = (SecT571FieldElement)p.XCoord; + ECFieldElement Y1 = p.YCoord; + + ECFieldElement Y2 = L2; + ECFieldElement L = Y1.Add(Y2).Divide(X1); + + X3 = (SecT571FieldElement)L.Square().Add(L).Add(X1).AddOne(); + if (X3.IsZero) + { + return new SecT571R1Point(curve, X3, SecT571R1Curve.SecT571R1_B_SQRT, IsCompressed); + } + + ECFieldElement Y3 = L.Multiply(X1.Add(X3)).Add(X3).Add(Y1); + L3 = (SecT571FieldElement)Y3.Divide(X3).Add(X3); + Z3 = (SecT571FieldElement)curve.FromBigInteger(BigInteger.One); + } + else + { + SecT571Field.Square(B, B); + + ulong[] APrecomp = SecT571Field.PrecompMultiplicand(A); + + ulong[] AU1 = t1; + ulong[] AU2 = t2; + + SecT571Field.MultiplyPrecomp(U1, APrecomp, AU1); + SecT571Field.MultiplyPrecomp(U2, APrecomp, AU2); + + X3 = new SecT571FieldElement(t1); + SecT571Field.Multiply(AU1, AU2, X3.x); + + if (X3.IsZero) + { + return new SecT571R1Point(curve, X3, SecT571R1Curve.SecT571R1_B_SQRT, IsCompressed); + } + + Z3 = new SecT571FieldElement(t3); + SecT571Field.MultiplyPrecomp(B, APrecomp, Z3.x); + + if (Z2Precomp != null) + { + SecT571Field.MultiplyPrecomp(Z3.x, Z2Precomp, Z3.x); + } + + ulong[] tt = Nat576.CreateExt64(); + + SecT571Field.Add(AU2, B, t4); + SecT571Field.SquareAddToExt(t4, tt); + + SecT571Field.Add(L1.x, Z1.x, t4); + SecT571Field.MultiplyAddToExt(t4, Z3.x, tt); + + L3 = new SecT571FieldElement(t4); + SecT571Field.Reduce(tt, L3.x); + + if (Z1Precomp != null) + { + SecT571Field.MultiplyPrecomp(Z3.x, Z1Precomp, Z3.x); + } + } + + return new SecT571R1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Twice() + { + if (this.IsInfinity) + return this; + + ECCurve curve = this.Curve; + + SecT571FieldElement X1 = (SecT571FieldElement)this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is its own additive inverse + return curve.Infinity; + } + + SecT571FieldElement L1 = (SecT571FieldElement)this.RawYCoord, Z1 = (SecT571FieldElement)this.RawZCoords[0]; + + ulong[] t1 = Nat576.Create64(); + ulong[] t2 = Nat576.Create64(); + + ulong[] Z1Precomp = Z1.IsOne ? null : SecT571Field.PrecompMultiplicand(Z1.x); + ulong[] L1Z1, Z1Sq; + if (Z1Precomp == null) + { + L1Z1 = L1.x; + Z1Sq = Z1.x; + } + else + { + SecT571Field.MultiplyPrecomp(L1.x, Z1Precomp, L1Z1 = t1); + SecT571Field.Square(Z1.x, Z1Sq = t2); + } + + ulong[] T = Nat576.Create64(); + SecT571Field.Square(L1.x, T); + SecT571Field.AddBothTo(L1Z1, Z1Sq, T); + + if (Nat576.IsZero64(T)) + { + return new SecT571R1Point(curve, new SecT571FieldElement(T), SecT571R1Curve.SecT571R1_B_SQRT, IsCompressed); + } + + ulong[] tt = Nat576.CreateExt64(); + SecT571Field.MultiplyAddToExt(T, L1Z1, tt); + + SecT571FieldElement X3 = new SecT571FieldElement(t1); + SecT571Field.Square(T, X3.x); + + SecT571FieldElement Z3 = new SecT571FieldElement(T); + if (Z1Precomp != null) + { + SecT571Field.Multiply(Z3.x, Z1Sq, Z3.x); + } + + ulong[] X1Z1; + if (Z1Precomp == null) + { + X1Z1 = X1.x; + } + else + { + SecT571Field.MultiplyPrecomp(X1.x, Z1Precomp, X1Z1 = t2); + } + + SecT571Field.SquareAddToExt(X1Z1, tt); + SecT571Field.Reduce(tt, t2); + SecT571Field.AddBothTo(X3.x, Z3.x, t2); + SecT571FieldElement L3 = new SecT571FieldElement(t2); + + return new SecT571R1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint TwicePlus(ECPoint b) + { + if (this.IsInfinity) + return b; + if (b.IsInfinity) + return Twice(); + + ECCurve curve = this.Curve; + + ECFieldElement X1 = this.RawXCoord; + if (X1.IsZero) + { + // A point with X == 0 is its own additive inverse + return b; + } + + ECFieldElement X2 = b.RawXCoord, Z2 = b.RawZCoords[0]; + if (X2.IsZero || !Z2.IsOne) + { + return Twice().Add(b); + } + + ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; + ECFieldElement L2 = b.RawYCoord; + + ECFieldElement X1Sq = X1.Square(); + ECFieldElement L1Sq = L1.Square(); + ECFieldElement Z1Sq = Z1.Square(); + ECFieldElement L1Z1 = L1.Multiply(Z1); + + ECFieldElement T = Z1Sq.Add(L1Sq).Add(L1Z1); + ECFieldElement A = L2.Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); + ECFieldElement X2Z1Sq = X2.Multiply(Z1Sq); + ECFieldElement B = X2Z1Sq.Add(T).Square(); + + if (B.IsZero) + { + if (A.IsZero) + return b.Twice(); + + return curve.Infinity; + } + + if (A.IsZero) + { + return new SecT571R1Point(curve, A, SecT571R1Curve.SecT571R1_B_SQRT, IsCompressed); + } + + ECFieldElement X3 = A.Square().Multiply(X2Z1Sq); + ECFieldElement Z3 = A.Multiply(B).Multiply(Z1Sq); + ECFieldElement L3 = A.Add(B).Square().MultiplyPlusProduct(T, L2.AddOne(), Z3); + + return new SecT571R1Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + } + + public override ECPoint Negate() + { + if (this.IsInfinity) + return this; + + ECFieldElement X = this.RawXCoord; + if (X.IsZero) + return this; + + // L is actually Lambda (X + Y/X) here + ECFieldElement L = this.RawYCoord, Z = this.RawZCoords[0]; + return new SecT571R1Point(Curve, X, L.Add(Z), new ECFieldElement[] { Z }, IsCompressed); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT571R1Point.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT571R1Point.cs.meta new file mode 100644 index 0000000..fbb4343 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/custom/sec/SecT571R1Point.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 211d67eaa827e16489ef6a4769140b6d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo.meta new file mode 100644 index 0000000..92adad8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 82dcfeca9ae4b40459c8a19f5fe5feb4 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/ECEndomorphism.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/ECEndomorphism.cs new file mode 100644 index 0000000..dfb3213 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/ECEndomorphism.cs @@ -0,0 +1,11 @@ +using System; + +namespace Org.BouncyCastle.Math.EC.Endo +{ + public interface ECEndomorphism + { + ECPointMap PointMap { get; } + + bool HasEfficientPointMap { get; } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/ECEndomorphism.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/ECEndomorphism.cs.meta new file mode 100644 index 0000000..1773cdd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/ECEndomorphism.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: acff193d10a36bb48a1ababbe7677d74 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/EndoPreCompInfo.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/EndoPreCompInfo.cs new file mode 100644 index 0000000..cb926fc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/EndoPreCompInfo.cs @@ -0,0 +1,26 @@ +using System; + +using Org.BouncyCastle.Math.EC.Multiplier; + +namespace Org.BouncyCastle.Math.EC.Endo +{ + public class EndoPreCompInfo + : PreCompInfo + { + protected ECEndomorphism m_endomorphism; + + protected ECPoint m_mappedPoint; + + public virtual ECEndomorphism Endomorphism + { + get { return m_endomorphism; } + set { this.m_endomorphism = value; } + } + + public virtual ECPoint MappedPoint + { + get { return m_mappedPoint; } + set { this.m_mappedPoint = value; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/EndoPreCompInfo.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/EndoPreCompInfo.cs.meta new file mode 100644 index 0000000..2d99847 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/EndoPreCompInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ae1d858d93aec58489776236fa39fe26 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/EndoUtilities.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/EndoUtilities.cs new file mode 100644 index 0000000..843103b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/EndoUtilities.cs @@ -0,0 +1,79 @@ +using System; + +using Org.BouncyCastle.Math.EC.Multiplier; + +namespace Org.BouncyCastle.Math.EC.Endo +{ + public abstract class EndoUtilities + { + public static readonly string PRECOMP_NAME = "bc_endo"; + + public static BigInteger[] DecomposeScalar(ScalarSplitParameters p, BigInteger k) + { + int bits = p.Bits; + BigInteger b1 = CalculateB(k, p.G1, bits); + BigInteger b2 = CalculateB(k, p.G2, bits); + + BigInteger a = k.Subtract((b1.Multiply(p.V1A)).Add(b2.Multiply(p.V2A))); + BigInteger b = (b1.Multiply(p.V1B)).Add(b2.Multiply(p.V2B)).Negate(); + + return new BigInteger[]{ a, b }; + } + + public static ECPoint MapPoint(ECEndomorphism endomorphism, ECPoint p) + { + EndoPreCompInfo precomp = (EndoPreCompInfo)p.Curve.Precompute(p, PRECOMP_NAME, + new MapPointCallback(endomorphism, p)); + return precomp.MappedPoint; + } + + private static BigInteger CalculateB(BigInteger k, BigInteger g, int t) + { + bool negative = (g.SignValue < 0); + BigInteger b = k.Multiply(g.Abs()); + bool extra = b.TestBit(t - 1); + b = b.ShiftRight(t); + if (extra) + { + b = b.Add(BigInteger.One); + } + return negative ? b.Negate() : b; + } + + private class MapPointCallback + : IPreCompCallback + { + private readonly ECEndomorphism m_endomorphism; + private readonly ECPoint m_point; + + internal MapPointCallback(ECEndomorphism endomorphism, ECPoint point) + { + this.m_endomorphism = endomorphism; + this.m_point = point; + } + + public PreCompInfo Precompute(PreCompInfo existing) + { + EndoPreCompInfo existingEndo = existing as EndoPreCompInfo; + + if (CheckExisting(existingEndo, m_endomorphism)) + return existingEndo; + + ECPoint mappedPoint = m_endomorphism.PointMap.Map(m_point); + + EndoPreCompInfo result = new EndoPreCompInfo(); + result.Endomorphism = m_endomorphism; + result.MappedPoint = mappedPoint; + return result; + } + + private bool CheckExisting(EndoPreCompInfo existingEndo, ECEndomorphism endomorphism) + { + return null != existingEndo + && existingEndo.Endomorphism == endomorphism + && existingEndo.MappedPoint != null; + } + + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/EndoUtilities.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/EndoUtilities.cs.meta new file mode 100644 index 0000000..35c60ea --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/EndoUtilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6c5102d7f0ba255428c3edc64ef98ed1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/GlvEndomorphism.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/GlvEndomorphism.cs new file mode 100644 index 0000000..f65bdd6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/GlvEndomorphism.cs @@ -0,0 +1,10 @@ +using System; + +namespace Org.BouncyCastle.Math.EC.Endo +{ + public interface GlvEndomorphism + : ECEndomorphism + { + BigInteger[] DecomposeScalar(BigInteger k); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/GlvEndomorphism.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/GlvEndomorphism.cs.meta new file mode 100644 index 0000000..3e32e20 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/GlvEndomorphism.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 189cf28d645dba344a8789b0e233ed3d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/GlvTypeAEndomorphism.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/GlvTypeAEndomorphism.cs new file mode 100644 index 0000000..fda8f15 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/GlvTypeAEndomorphism.cs @@ -0,0 +1,38 @@ +using System; + +namespace Org.BouncyCastle.Math.EC.Endo +{ + public class GlvTypeAEndomorphism + : GlvEndomorphism + { + protected readonly GlvTypeAParameters m_parameters; + protected readonly ECPointMap m_pointMap; + + public GlvTypeAEndomorphism(ECCurve curve, GlvTypeAParameters parameters) + { + /* + * NOTE: 'curve' MUST only be used to create a suitable ECFieldElement. Due to the way + * ECCurve configuration works, 'curve' will not be the actual instance of ECCurve that the + * endomorphism is being used with. + */ + + this.m_parameters = parameters; + this.m_pointMap = new ScaleYNegateXPointMap(curve.FromBigInteger(parameters.I)); + } + + public virtual BigInteger[] DecomposeScalar(BigInteger k) + { + return EndoUtilities.DecomposeScalar(m_parameters.SplitParams, k); + } + + public virtual ECPointMap PointMap + { + get { return m_pointMap; } + } + + public virtual bool HasEfficientPointMap + { + get { return true; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/GlvTypeAEndomorphism.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/GlvTypeAEndomorphism.cs.meta new file mode 100644 index 0000000..0d2220d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/GlvTypeAEndomorphism.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1e0ba02ff067fa54fb0c69fb02452be5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/GlvTypeAParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/GlvTypeAParameters.cs new file mode 100644 index 0000000..68464c5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/GlvTypeAParameters.cs @@ -0,0 +1,32 @@ +using System; + +namespace Org.BouncyCastle.Math.EC.Endo +{ + public class GlvTypeAParameters + { + protected readonly BigInteger m_i, m_lambda; + protected readonly ScalarSplitParameters m_splitParams; + + public GlvTypeAParameters(BigInteger i, BigInteger lambda, ScalarSplitParameters splitParams) + { + this.m_i = i; + this.m_lambda = lambda; + this.m_splitParams = splitParams; + } + + public virtual BigInteger I + { + get { return m_i; } + } + + public virtual BigInteger Lambda + { + get { return m_lambda; } + } + + public virtual ScalarSplitParameters SplitParams + { + get { return m_splitParams; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/GlvTypeAParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/GlvTypeAParameters.cs.meta new file mode 100644 index 0000000..64b1716 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/GlvTypeAParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9252e68ad4b7aa84cac5a69349077a06 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/GlvTypeBEndomorphism.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/GlvTypeBEndomorphism.cs new file mode 100644 index 0000000..e4f12fe --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/GlvTypeBEndomorphism.cs @@ -0,0 +1,38 @@ +using System; + +namespace Org.BouncyCastle.Math.EC.Endo +{ + public class GlvTypeBEndomorphism + : GlvEndomorphism + { + protected readonly GlvTypeBParameters m_parameters; + protected readonly ECPointMap m_pointMap; + + public GlvTypeBEndomorphism(ECCurve curve, GlvTypeBParameters parameters) + { + /* + * NOTE: 'curve' MUST only be used to create a suitable ECFieldElement. Due to the way + * ECCurve configuration works, 'curve' will not be the actual instance of ECCurve that the + * endomorphism is being used with. + */ + + this.m_parameters = parameters; + this.m_pointMap = new ScaleXPointMap(curve.FromBigInteger(parameters.Beta)); + } + + public virtual BigInteger[] DecomposeScalar(BigInteger k) + { + return EndoUtilities.DecomposeScalar(m_parameters.SplitParams, k); + } + + public virtual ECPointMap PointMap + { + get { return m_pointMap; } + } + + public virtual bool HasEfficientPointMap + { + get { return true; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/GlvTypeBEndomorphism.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/GlvTypeBEndomorphism.cs.meta new file mode 100644 index 0000000..b3d8bd3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/GlvTypeBEndomorphism.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c3f44b39f77647344a3e185a38dab737 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/GlvTypeBParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/GlvTypeBParameters.cs new file mode 100644 index 0000000..5e2937b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/GlvTypeBParameters.cs @@ -0,0 +1,71 @@ +using System; + +namespace Org.BouncyCastle.Math.EC.Endo +{ + public class GlvTypeBParameters + { + protected readonly BigInteger m_beta, m_lambda; + protected readonly ScalarSplitParameters m_splitParams; + + [Obsolete("Use constructor taking a ScalarSplitParameters instead")] + public GlvTypeBParameters(BigInteger beta, BigInteger lambda, BigInteger[] v1, BigInteger[] v2, + BigInteger g1, BigInteger g2, int bits) + { + this.m_beta = beta; + this.m_lambda = lambda; + this.m_splitParams = new ScalarSplitParameters(v1, v2, g1, g2, bits); + } + + public GlvTypeBParameters(BigInteger beta, BigInteger lambda, ScalarSplitParameters splitParams) + { + this.m_beta = beta; + this.m_lambda = lambda; + this.m_splitParams = splitParams; + } + + public virtual BigInteger Beta + { + get { return m_beta; } + } + + public virtual BigInteger Lambda + { + get { return m_lambda; } + } + + public virtual ScalarSplitParameters SplitParams + { + get { return m_splitParams; } + } + + [Obsolete("Access via SplitParams instead")] + public virtual BigInteger[] V1 + { + get { return new BigInteger[] { m_splitParams.V1A, m_splitParams.V1B }; } + } + + [Obsolete("Access via SplitParams instead")] + public virtual BigInteger[] V2 + { + get { return new BigInteger[] { m_splitParams.V2A, m_splitParams.V2B }; } + } + + [Obsolete("Access via SplitParams instead")] + public virtual BigInteger G1 + { + get { return m_splitParams.G1; } + } + + [Obsolete("Access via SplitParams instead")] + public virtual BigInteger G2 + { + get { return m_splitParams.G2; } + } + + [Obsolete("Access via SplitParams instead")] + public virtual int Bits + { + get { return m_splitParams.Bits; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/GlvTypeBParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/GlvTypeBParameters.cs.meta new file mode 100644 index 0000000..6123007 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/GlvTypeBParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cadba253418ad634483a375feb5b51ed +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/ScalarSplitParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/ScalarSplitParameters.cs new file mode 100644 index 0000000..18d0bdb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/ScalarSplitParameters.cs @@ -0,0 +1,69 @@ +using System; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Math.EC.Endo +{ + public class ScalarSplitParameters + { + private static void CheckVector(BigInteger[] v, string name) + { + if (v == null || v.Length != 2 || v[0] == null || v[1] == null) + throw new ArgumentException("Must consist of exactly 2 (non-null) values", name); + } + + protected readonly BigInteger m_v1A, m_v1B, m_v2A, m_v2B; + protected readonly BigInteger m_g1, m_g2; + protected readonly int m_bits; + + public ScalarSplitParameters(BigInteger[] v1, BigInteger[] v2, BigInteger g1, + BigInteger g2, int bits) + { + CheckVector(v1, "v1"); + CheckVector(v2, "v2"); + + this.m_v1A = v1[0]; + this.m_v1B = v1[1]; + this.m_v2A = v2[0]; + this.m_v2B = v2[1]; + this.m_g1 = g1; + this.m_g2 = g2; + this.m_bits = bits; + } + + public virtual BigInteger V1A + { + get { return m_v1A; } + } + + public virtual BigInteger V1B + { + get { return m_v1B; } + } + + public virtual BigInteger V2A + { + get { return m_v2A; } + } + + public virtual BigInteger V2B + { + get { return m_v2B; } + } + + public virtual BigInteger G1 + { + get { return m_g1; } + } + + public virtual BigInteger G2 + { + get { return m_g2; } + } + + public virtual int Bits + { + get { return m_bits; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/ScalarSplitParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/ScalarSplitParameters.cs.meta new file mode 100644 index 0000000..2812da6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/endo/ScalarSplitParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4263db4b6d9c88c4a854b87804644381 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier.meta new file mode 100644 index 0000000..11d3d4c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 796ad0cc7a406f94897280ec06e47b73 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/AbstractECMultiplier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/AbstractECMultiplier.cs new file mode 100644 index 0000000..c2580c8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/AbstractECMultiplier.cs @@ -0,0 +1,29 @@ +namespace Org.BouncyCastle.Math.EC.Multiplier +{ + public abstract class AbstractECMultiplier + : ECMultiplier + { + public virtual ECPoint Multiply(ECPoint p, BigInteger k) + { + int sign = k.SignValue; + if (sign == 0 || p.IsInfinity) + return p.Curve.Infinity; + + ECPoint positive = MultiplyPositive(p, k.Abs()); + ECPoint result = sign > 0 ? positive : positive.Negate(); + + /* + * Although the various multipliers ought not to produce invalid output under normal + * circumstances, a final check here is advised to guard against fault attacks. + */ + return CheckResult(result); + } + + protected abstract ECPoint MultiplyPositive(ECPoint p, BigInteger k); + + protected virtual ECPoint CheckResult(ECPoint p) + { + return ECAlgorithms.ImplCheckResult(p); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/AbstractECMultiplier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/AbstractECMultiplier.cs.meta new file mode 100644 index 0000000..8031bcd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/AbstractECMultiplier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f56bc2641850dec4c887ce086f91bd33 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/DoubleAddMultiplier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/DoubleAddMultiplier.cs new file mode 100644 index 0000000..6648727 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/DoubleAddMultiplier.cs @@ -0,0 +1,27 @@ +using System; + +namespace Org.BouncyCastle.Math.EC.Multiplier +{ + [Obsolete("Will be removed")] + public class DoubleAddMultiplier + : AbstractECMultiplier + { + /** + * Joye's double-add algorithm. + */ + protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k) + { + ECPoint[] R = new ECPoint[]{ p.Curve.Infinity, p }; + + int n = k.BitLength; + for (int i = 0; i < n; ++i) + { + int b = k.TestBit(i) ? 1 : 0; + int bp = 1 - b; + R[bp] = R[bp].TwicePlus(R[b]); + } + + return R[0]; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/DoubleAddMultiplier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/DoubleAddMultiplier.cs.meta new file mode 100644 index 0000000..84199f9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/DoubleAddMultiplier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bfa3bd3cece2c424b84343d1b8a5ca68 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/ECMultiplier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/ECMultiplier.cs new file mode 100644 index 0000000..8d6136b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/ECMultiplier.cs @@ -0,0 +1,18 @@ +namespace Org.BouncyCastle.Math.EC.Multiplier +{ + /** + * Interface for classes encapsulating a point multiplication algorithm + * for ECPoints. + */ + public interface ECMultiplier + { + /** + * Multiplies the ECPoint p by k, i.e. + * p is added k times to itself. + * @param p The ECPoint to be multiplied. + * @param k The factor by which p is multiplied. + * @return p multiplied by k. + */ + ECPoint Multiply(ECPoint p, BigInteger k); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/ECMultiplier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/ECMultiplier.cs.meta new file mode 100644 index 0000000..f444046 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/ECMultiplier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cbdcf6f4bec0e3540a329c7ce69ef47c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/FixedPointCombMultiplier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/FixedPointCombMultiplier.cs new file mode 100644 index 0000000..37e5b5c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/FixedPointCombMultiplier.cs @@ -0,0 +1,58 @@ +using System; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Multiplier +{ + public class FixedPointCombMultiplier + : AbstractECMultiplier + { + protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k) + { + ECCurve c = p.Curve; + int size = FixedPointUtilities.GetCombSize(c); + + if (k.BitLength > size) + { + /* + * TODO The comb works best when the scalars are less than the (possibly unknown) order. + * Still, if we want to handle larger scalars, we could allow customization of the comb + * size, or alternatively we could deal with the 'extra' bits either by running the comb + * multiple times as necessary, or by using an alternative multiplier as prelude. + */ + throw new InvalidOperationException("fixed-point comb doesn't support scalars larger than the curve order"); + } + + FixedPointPreCompInfo info = FixedPointUtilities.Precompute(p); + ECLookupTable lookupTable = info.LookupTable; + int width = info.Width; + + int d = (size + width - 1) / width; + + ECPoint R = c.Infinity; + + int fullComb = d * width; + uint[] K = Nat.FromBigInteger(fullComb, k); + + int top = fullComb - 1; + for (int i = 0; i < d; ++i) + { + uint secretIndex = 0; + + for (int j = top - i; j >= 0; j -= d) + { + uint secretBit = K[j >> 5] >> (j & 0x1F); + secretIndex ^= secretBit >> 1; + secretIndex <<= 1; + secretIndex ^= secretBit; + } + + ECPoint add = lookupTable.Lookup((int)secretIndex); + + R = R.TwicePlus(add); + } + + return R.Add(info.Offset); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/FixedPointCombMultiplier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/FixedPointCombMultiplier.cs.meta new file mode 100644 index 0000000..ef245fe --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/FixedPointCombMultiplier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 31a5aebaaa4fb75489ba888a9788e904 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/FixedPointPreCompInfo.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/FixedPointPreCompInfo.cs new file mode 100644 index 0000000..5d6af9e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/FixedPointPreCompInfo.cs @@ -0,0 +1,43 @@ +using System; + +namespace Org.BouncyCastle.Math.EC.Multiplier +{ + /** + * Class holding precomputation data for fixed-point multiplications. + */ + public class FixedPointPreCompInfo + : PreCompInfo + { + protected ECPoint m_offset = null; + + /** + * Lookup table for the precomputed ECPoints used for a fixed point multiplication. + */ + protected ECLookupTable m_lookupTable = null; + + /** + * The width used for the precomputation. If a larger width precomputation + * is already available this may be larger than was requested, so calling + * code should refer to the actual width. + */ + protected int m_width = -1; + + public virtual ECLookupTable LookupTable + { + get { return m_lookupTable; } + set { this.m_lookupTable = value; } + } + + public virtual ECPoint Offset + { + get { return m_offset; } + set { this.m_offset = value; } + } + + public virtual int Width + { + get { return m_width; } + set { this.m_width = value; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/FixedPointPreCompInfo.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/FixedPointPreCompInfo.cs.meta new file mode 100644 index 0000000..09cdeee --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/FixedPointPreCompInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c1b8e4360465c5b4ab52749bfef29929 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/FixedPointUtilities.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/FixedPointUtilities.cs new file mode 100644 index 0000000..88f178e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/FixedPointUtilities.cs @@ -0,0 +1,95 @@ +using System; + +namespace Org.BouncyCastle.Math.EC.Multiplier +{ + public class FixedPointUtilities + { + public static readonly string PRECOMP_NAME = "bc_fixed_point"; + + public static int GetCombSize(ECCurve c) + { + BigInteger order = c.Order; + return order == null ? c.FieldSize + 1 : order.BitLength; + } + + public static FixedPointPreCompInfo GetFixedPointPreCompInfo(PreCompInfo preCompInfo) + { + return preCompInfo as FixedPointPreCompInfo; + } + + public static FixedPointPreCompInfo Precompute(ECPoint p) + { + return (FixedPointPreCompInfo)p.Curve.Precompute(p, PRECOMP_NAME, new FixedPointCallback(p)); + } + + private class FixedPointCallback + : IPreCompCallback + { + private readonly ECPoint m_p; + + internal FixedPointCallback(ECPoint p) + { + this.m_p = p; + } + + public PreCompInfo Precompute(PreCompInfo existing) + { + FixedPointPreCompInfo existingFP = (existing is FixedPointPreCompInfo) ? (FixedPointPreCompInfo)existing : null; + + ECCurve c = m_p.Curve; + int bits = FixedPointUtilities.GetCombSize(c); + int minWidth = bits > 250 ? 6 : 5; + int n = 1 << minWidth; + + if (CheckExisting(existingFP, n)) + return existingFP; + + int d = (bits + minWidth - 1) / minWidth; + + ECPoint[] pow2Table = new ECPoint[minWidth + 1]; + pow2Table[0] = m_p; + for (int i = 1; i < minWidth; ++i) + { + pow2Table[i] = pow2Table[i - 1].TimesPow2(d); + } + + // This will be the 'offset' value + pow2Table[minWidth] = pow2Table[0].Subtract(pow2Table[1]); + + c.NormalizeAll(pow2Table); + + ECPoint[] lookupTable = new ECPoint[n]; + lookupTable[0] = pow2Table[0]; + + for (int bit = minWidth - 1; bit >= 0; --bit) + { + ECPoint pow2 = pow2Table[bit]; + + int step = 1 << bit; + for (int i = step; i < n; i += (step << 1)) + { + lookupTable[i] = lookupTable[i - step].Add(pow2); + } + } + + c.NormalizeAll(lookupTable); + + FixedPointPreCompInfo result = new FixedPointPreCompInfo(); + result.LookupTable = c.CreateCacheSafeLookupTable(lookupTable, 0, lookupTable.Length); + result.Offset = pow2Table[minWidth]; + result.Width = minWidth; + return result; + } + + private bool CheckExisting(FixedPointPreCompInfo existingFP, int n) + { + return existingFP != null && CheckTable(existingFP.LookupTable, n); + } + + private bool CheckTable(ECLookupTable table, int n) + { + return table != null && table.Size >= n; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/FixedPointUtilities.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/FixedPointUtilities.cs.meta new file mode 100644 index 0000000..aa91c32 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/FixedPointUtilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c0a9e7964de22a840a9a3ed5ae64f0c8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/GlvMultiplier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/GlvMultiplier.cs new file mode 100644 index 0000000..9ef7d6e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/GlvMultiplier.cs @@ -0,0 +1,41 @@ +using System; + +using Org.BouncyCastle.Math.EC.Endo; + +namespace Org.BouncyCastle.Math.EC.Multiplier +{ + public class GlvMultiplier + : AbstractECMultiplier + { + protected readonly ECCurve curve; + protected readonly GlvEndomorphism glvEndomorphism; + + public GlvMultiplier(ECCurve curve, GlvEndomorphism glvEndomorphism) + { + if (curve == null || curve.Order == null) + throw new ArgumentException("Need curve with known group order", "curve"); + + this.curve = curve; + this.glvEndomorphism = glvEndomorphism; + } + + protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k) + { + if (!curve.Equals(p.Curve)) + throw new InvalidOperationException(); + + BigInteger n = p.Curve.Order; + BigInteger[] ab = glvEndomorphism.DecomposeScalar(k.Mod(n)); + BigInteger a = ab[0], b = ab[1]; + + if (glvEndomorphism.HasEfficientPointMap) + { + return ECAlgorithms.ImplShamirsTrickWNaf(glvEndomorphism, p, a, b); + } + + ECPoint q = EndoUtilities.MapPoint(glvEndomorphism, p); + + return ECAlgorithms.ImplShamirsTrickWNaf(p, a, q, b); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/GlvMultiplier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/GlvMultiplier.cs.meta new file mode 100644 index 0000000..9eedbec --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/GlvMultiplier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 40686cfd9899e084e8dbe382c866f916 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/IPreCompCallback.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/IPreCompCallback.cs new file mode 100644 index 0000000..e64ae83 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/IPreCompCallback.cs @@ -0,0 +1,9 @@ +using System; + +namespace Org.BouncyCastle.Math.EC.Multiplier +{ + public interface IPreCompCallback + { + PreCompInfo Precompute(PreCompInfo existing); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/IPreCompCallback.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/IPreCompCallback.cs.meta new file mode 100644 index 0000000..1c80a2b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/IPreCompCallback.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2e956e68b3978c344865906272d86ae2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/MixedNafR2LMultiplier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/MixedNafR2LMultiplier.cs new file mode 100644 index 0000000..2bed892 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/MixedNafR2LMultiplier.cs @@ -0,0 +1,76 @@ +using System; + +namespace Org.BouncyCastle.Math.EC.Multiplier +{ + /** + * Class implementing the NAF (Non-Adjacent Form) multiplication algorithm (right-to-left) using + * mixed coordinates. + */ + [Obsolete("Will be removed")] + public class MixedNafR2LMultiplier + : AbstractECMultiplier + { + protected readonly int additionCoord, doublingCoord; + + /** + * By default, addition will be done in Jacobian coordinates, and doubling will be done in + * Modified Jacobian coordinates (independent of the original coordinate system of each point). + */ + public MixedNafR2LMultiplier() + : this(ECCurve.COORD_JACOBIAN, ECCurve.COORD_JACOBIAN_MODIFIED) + { + } + + public MixedNafR2LMultiplier(int additionCoord, int doublingCoord) + { + this.additionCoord = additionCoord; + this.doublingCoord = doublingCoord; + } + + protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k) + { + ECCurve curveOrig = p.Curve; + + ECCurve curveAdd = ConfigureCurve(curveOrig, additionCoord); + ECCurve curveDouble = ConfigureCurve(curveOrig, doublingCoord); + + int[] naf = WNafUtilities.GenerateCompactNaf(k); + + ECPoint Ra = curveAdd.Infinity; + ECPoint Td = curveDouble.ImportPoint(p); + + int zeroes = 0; + for (int i = 0; i < naf.Length; ++i) + { + int ni = naf[i]; + int digit = ni >> 16; + zeroes += ni & 0xFFFF; + + Td = Td.TimesPow2(zeroes); + + ECPoint Tj = curveAdd.ImportPoint(Td); + if (digit < 0) + { + Tj = Tj.Negate(); + } + + Ra = Ra.Add(Tj); + + zeroes = 1; + } + + return curveOrig.ImportPoint(Ra); + } + + protected virtual ECCurve ConfigureCurve(ECCurve c, int coord) + { + if (c.CoordinateSystem == coord) + return c; + + if (!c.SupportsCoordinateSystem(coord)) + throw new ArgumentException("Coordinate system " + coord + " not supported by this curve", "coord"); + + return c.Configure().SetCoordinateSystem(coord).Create(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/MixedNafR2LMultiplier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/MixedNafR2LMultiplier.cs.meta new file mode 100644 index 0000000..886d727 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/MixedNafR2LMultiplier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a2e6baa9de063824bb25d000dc9924af +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/MontgomeryLadderMultiplier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/MontgomeryLadderMultiplier.cs new file mode 100644 index 0000000..45df2fd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/MontgomeryLadderMultiplier.cs @@ -0,0 +1,28 @@ +using System; + +namespace Org.BouncyCastle.Math.EC.Multiplier +{ + [Obsolete("Will be removed")] + public class MontgomeryLadderMultiplier + : AbstractECMultiplier + { + /** + * Montgomery ladder. + */ + protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k) + { + ECPoint[] R = new ECPoint[]{ p.Curve.Infinity, p }; + + int n = k.BitLength; + int i = n; + while (--i >= 0) + { + int b = k.TestBit(i) ? 1 : 0; + int bp = 1 - b; + R[bp] = R[bp].Add(R[b]); + R[b] = R[b].Twice(); + } + return R[0]; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/MontgomeryLadderMultiplier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/MontgomeryLadderMultiplier.cs.meta new file mode 100644 index 0000000..c777028 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/MontgomeryLadderMultiplier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cdd2a5eb0110584498f62699ca318be6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/NafL2RMultiplier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/NafL2RMultiplier.cs new file mode 100644 index 0000000..d41a0d6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/NafL2RMultiplier.cs @@ -0,0 +1,33 @@ +using System; + +namespace Org.BouncyCastle.Math.EC.Multiplier +{ + /** + * Class implementing the NAF (Non-Adjacent Form) multiplication algorithm (left-to-right). + */ + [Obsolete("Will be removed")] + public class NafL2RMultiplier + : AbstractECMultiplier + { + protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k) + { + int[] naf = WNafUtilities.GenerateCompactNaf(k); + + ECPoint addP = p.Normalize(), subP = addP.Negate(); + + ECPoint R = p.Curve.Infinity; + + int i = naf.Length; + while (--i >= 0) + { + int ni = naf[i]; + int digit = ni >> 16, zeroes = ni & 0xFFFF; + + R = R.TwicePlus(digit < 0 ? subP : addP); + R = R.TimesPow2(zeroes); + } + + return R; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/NafL2RMultiplier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/NafL2RMultiplier.cs.meta new file mode 100644 index 0000000..52f26f3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/NafL2RMultiplier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: df30178c5fd97f7469d902af8add0f0c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/NafR2LMultiplier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/NafR2LMultiplier.cs new file mode 100644 index 0000000..8157cf0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/NafR2LMultiplier.cs @@ -0,0 +1,34 @@ +using System; + +namespace Org.BouncyCastle.Math.EC.Multiplier +{ + /** + * Class implementing the NAF (Non-Adjacent Form) multiplication algorithm (right-to-left). + */ + [Obsolete("Will be removed")] + public class NafR2LMultiplier + : AbstractECMultiplier + { + protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k) + { + int[] naf = WNafUtilities.GenerateCompactNaf(k); + + ECPoint R0 = p.Curve.Infinity, R1 = p; + + int zeroes = 0; + for (int i = 0; i < naf.Length; ++i) + { + int ni = naf[i]; + int digit = ni >> 16; + zeroes += ni & 0xFFFF; + + R1 = R1.TimesPow2(zeroes); + R0 = R0.Add(digit < 0 ? R1.Negate() : R1); + + zeroes = 1; + } + + return R0; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/NafR2LMultiplier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/NafR2LMultiplier.cs.meta new file mode 100644 index 0000000..1aacfd1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/NafR2LMultiplier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fe8f44df28afc1d43912c220a7e517c2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/PreCompInfo.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/PreCompInfo.cs new file mode 100644 index 0000000..5c32892 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/PreCompInfo.cs @@ -0,0 +1,11 @@ +namespace Org.BouncyCastle.Math.EC.Multiplier +{ + /** + * Interface for classes storing precomputation data for multiplication + * algorithms. Used as a Memento (see GOF patterns) for + * WNafMultiplier. + */ + public interface PreCompInfo + { + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/PreCompInfo.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/PreCompInfo.cs.meta new file mode 100644 index 0000000..b0f167f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/PreCompInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 686680777086ad44eb77f1de1b1f7eed +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/ReferenceMultiplier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/ReferenceMultiplier.cs new file mode 100644 index 0000000..40563cd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/ReferenceMultiplier.cs @@ -0,0 +1,14 @@ +using System; + +namespace Org.BouncyCastle.Math.EC.Multiplier +{ + [Obsolete("Will be removed")] + public class ReferenceMultiplier + : AbstractECMultiplier + { + protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k) + { + return ECAlgorithms.ReferenceMultiply(p, k); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/ReferenceMultiplier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/ReferenceMultiplier.cs.meta new file mode 100644 index 0000000..5dc3cea --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/ReferenceMultiplier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dff0b7c0f5ac59b4c8badcd54e675c5e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/ValidityPreCompInfo.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/ValidityPreCompInfo.cs new file mode 100644 index 0000000..7ec2cbb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/ValidityPreCompInfo.cs @@ -0,0 +1,44 @@ +using System; + +namespace Org.BouncyCastle.Math.EC.Multiplier +{ + internal class ValidityPreCompInfo + : PreCompInfo + { + internal static readonly string PRECOMP_NAME = "bc_validity"; + + private bool failed = false; + private bool curveEquationPassed = false; + private bool orderPassed = false; + + internal bool HasFailed() + { + return failed; + } + + internal void ReportFailed() + { + failed = true; + } + + internal bool HasCurveEquationPassed() + { + return curveEquationPassed; + } + + internal void ReportCurveEquationPassed() + { + curveEquationPassed = true; + } + + internal bool HasOrderPassed() + { + return orderPassed; + } + + internal void ReportOrderPassed() + { + orderPassed = true; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/ValidityPreCompInfo.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/ValidityPreCompInfo.cs.meta new file mode 100644 index 0000000..d7becbf --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/ValidityPreCompInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 34d646e08affc394c9d58368cebbb641 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/WNafL2RMultiplier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/WNafL2RMultiplier.cs new file mode 100644 index 0000000..833bbb5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/WNafL2RMultiplier.cs @@ -0,0 +1,89 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math.EC.Multiplier +{ + /** + * Class implementing the WNAF (Window Non-Adjacent Form) multiplication + * algorithm. + */ + public class WNafL2RMultiplier + : AbstractECMultiplier + { + /** + * Multiplies this by an integer k using the + * Window NAF method. + * @param k The integer by which this is multiplied. + * @return A new ECPoint which equals this + * multiplied by k. + */ + protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k) + { + int minWidth = WNafUtilities.GetWindowSize(k.BitLength); + + WNafPreCompInfo info = WNafUtilities.Precompute(p, minWidth, true); + ECPoint[] preComp = info.PreComp; + ECPoint[] preCompNeg = info.PreCompNeg; + int width = info.Width; + + int[] wnaf = WNafUtilities.GenerateCompactWindowNaf(width, k); + + ECPoint R = p.Curve.Infinity; + + int i = wnaf.Length; + + /* + * NOTE: We try to optimize the first window using the precomputed points to substitute an + * addition for 2 or more doublings. + */ + if (i > 1) + { + int wi = wnaf[--i]; + int digit = wi >> 16, zeroes = wi & 0xFFFF; + + int n = System.Math.Abs(digit); + ECPoint[] table = digit < 0 ? preCompNeg : preComp; + + // Optimization can only be used for values in the lower half of the table + if ((n << 2) < (1 << width)) + { + int highest = 32 - Integers.NumberOfLeadingZeros(n); + + // TODO Get addition/doubling cost ratio from curve and compare to 'scale' to see if worth substituting? + int scale = width - highest; + int lowBits = n ^ (1 << (highest - 1)); + + int i1 = ((1 << (width - 1)) - 1); + int i2 = (lowBits << scale) + 1; + R = table[i1 >> 1].Add(table[i2 >> 1]); + + zeroes -= scale; + + //Console.WriteLine("Optimized: 2^" + scale + " * " + n + " = " + i1 + " + " + i2); + } + else + { + R = table[n >> 1]; + } + + R = R.TimesPow2(zeroes); + } + + while (i > 0) + { + int wi = wnaf[--i]; + int digit = wi >> 16, zeroes = wi & 0xFFFF; + + int n = System.Math.Abs(digit); + ECPoint[] table = digit < 0 ? preCompNeg : preComp; + ECPoint r = table[n >> 1]; + + R = R.TwicePlus(r); + R = R.TimesPow2(zeroes); + } + + return R; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/WNafL2RMultiplier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/WNafL2RMultiplier.cs.meta new file mode 100644 index 0000000..06f7034 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/WNafL2RMultiplier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e0acc33825a1c5d408fdd5c7322e1b54 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/WNafPreCompInfo.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/WNafPreCompInfo.cs new file mode 100644 index 0000000..f979f33 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/WNafPreCompInfo.cs @@ -0,0 +1,85 @@ +namespace Org.BouncyCastle.Math.EC.Multiplier +{ + /** + * Class holding precomputation data for the WNAF (Window Non-Adjacent Form) + * algorithm. + */ + public class WNafPreCompInfo + : PreCompInfo + { + internal volatile int m_promotionCountdown = 4; + + protected int m_confWidth = -1; + + /** + * Array holding the precomputed ECPoints used for a Window + * NAF multiplication. + */ + protected ECPoint[] m_preComp = null; + + /** + * Array holding the negations of the precomputed ECPoints used + * for a Window NAF multiplication. + */ + protected ECPoint[] m_preCompNeg = null; + + /** + * Holds an ECPoint representing Twice(this). Used for the + * Window NAF multiplication to create or extend the precomputed values. + */ + protected ECPoint m_twice = null; + + protected int m_width = -1; + + internal int DecrementPromotionCountdown() + { + int t = m_promotionCountdown; + if (t > 0) + { + m_promotionCountdown = --t; + } + return t; + } + + internal int PromotionCountdown + { + get { return m_promotionCountdown; } + set { this.m_promotionCountdown = value; } + } + + public virtual bool IsPromoted + { + get { return m_promotionCountdown <= 0; } + } + + public virtual int ConfWidth + { + get { return m_confWidth; } + set { this.m_confWidth = value; } + } + + public virtual ECPoint[] PreComp + { + get { return m_preComp; } + set { this.m_preComp = value; } + } + + public virtual ECPoint[] PreCompNeg + { + get { return m_preCompNeg; } + set { this.m_preCompNeg = value; } + } + + public virtual ECPoint Twice + { + get { return m_twice; } + set { this.m_twice = value; } + } + + public virtual int Width + { + get { return m_width; } + set { this.m_width = value; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/WNafPreCompInfo.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/WNafPreCompInfo.cs.meta new file mode 100644 index 0000000..947004f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/WNafPreCompInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7b743f7d2b0d63b4db787636c18d57db +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/WNafUtilities.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/WNafUtilities.cs new file mode 100644 index 0000000..42265b2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/WNafUtilities.cs @@ -0,0 +1,767 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math.EC.Multiplier +{ + public abstract class WNafUtilities + { + public static readonly string PRECOMP_NAME = "bc_wnaf"; + + private static readonly int[] DEFAULT_WINDOW_SIZE_CUTOFFS = new int[]{ 13, 41, 121, 337, 897, 2305 }; + private static readonly int MAX_WIDTH = 16; + + private static readonly ECPoint[] EMPTY_POINTS = new ECPoint[0]; + + public static void ConfigureBasepoint(ECPoint p) + { + ECCurve c = p.Curve; + if (null == c) + return; + + BigInteger n = c.Order; + int bits = (null == n) ? c.FieldSize + 1 : n.BitLength; + int confWidth = System.Math.Min(MAX_WIDTH, GetWindowSize(bits) + 3); + + c.Precompute(p, PRECOMP_NAME, new ConfigureBasepointCallback(c, confWidth)); + } + + public static int[] GenerateCompactNaf(BigInteger k) + { + if ((k.BitLength >> 16) != 0) + throw new ArgumentException("must have bitlength < 2^16", "k"); + if (k.SignValue == 0) + return Arrays.EmptyInts; + + BigInteger _3k = k.ShiftLeft(1).Add(k); + + int bits = _3k.BitLength; + int[] naf = new int[bits >> 1]; + + BigInteger diff = _3k.Xor(k); + + int highBit = bits - 1, length = 0, zeroes = 0; + for (int i = 1; i < highBit; ++i) + { + if (!diff.TestBit(i)) + { + ++zeroes; + continue; + } + + int digit = k.TestBit(i) ? -1 : 1; + naf[length++] = (digit << 16) | zeroes; + zeroes = 1; + ++i; + } + + naf[length++] = (1 << 16) | zeroes; + + if (naf.Length > length) + { + naf = Trim(naf, length); + } + + return naf; + } + + public static int[] GenerateCompactWindowNaf(int width, BigInteger k) + { + if (width == 2) + { + return GenerateCompactNaf(k); + } + + if (width < 2 || width > 16) + throw new ArgumentException("must be in the range [2, 16]", "width"); + if ((k.BitLength >> 16) != 0) + throw new ArgumentException("must have bitlength < 2^16", "k"); + if (k.SignValue == 0) + return Arrays.EmptyInts; + + int[] wnaf = new int[k.BitLength / width + 1]; + + // 2^width and a mask and sign bit set accordingly + int pow2 = 1 << width; + int mask = pow2 - 1; + int sign = pow2 >> 1; + + bool carry = false; + int length = 0, pos = 0; + + while (pos <= k.BitLength) + { + if (k.TestBit(pos) == carry) + { + ++pos; + continue; + } + + k = k.ShiftRight(pos); + + int digit = k.IntValue & mask; + if (carry) + { + ++digit; + } + + carry = (digit & sign) != 0; + if (carry) + { + digit -= pow2; + } + + int zeroes = length > 0 ? pos - 1 : pos; + wnaf[length++] = (digit << 16) | zeroes; + pos = width; + } + + // Reduce the WNAF array to its actual length + if (wnaf.Length > length) + { + wnaf = Trim(wnaf, length); + } + + return wnaf; + } + + public static byte[] GenerateJsf(BigInteger g, BigInteger h) + { + int digits = System.Math.Max(g.BitLength, h.BitLength) + 1; + byte[] jsf = new byte[digits]; + + BigInteger k0 = g, k1 = h; + int j = 0, d0 = 0, d1 = 0; + + int offset = 0; + while ((d0 | d1) != 0 || k0.BitLength > offset || k1.BitLength > offset) + { + int n0 = ((int)((uint)k0.IntValue >> offset) + d0) & 7; + int n1 = ((int)((uint)k1.IntValue >> offset) + d1) & 7; + + int u0 = n0 & 1; + if (u0 != 0) + { + u0 -= (n0 & 2); + if ((n0 + u0) == 4 && (n1 & 3) == 2) + { + u0 = -u0; + } + } + + int u1 = n1 & 1; + if (u1 != 0) + { + u1 -= (n1 & 2); + if ((n1 + u1) == 4 && (n0 & 3) == 2) + { + u1 = -u1; + } + } + + if ((d0 << 1) == 1 + u0) + { + d0 ^= 1; + } + if ((d1 << 1) == 1 + u1) + { + d1 ^= 1; + } + + if (++offset == 30) + { + offset = 0; + k0 = k0.ShiftRight(30); + k1 = k1.ShiftRight(30); + } + + jsf[j++] = (byte)((u0 << 4) | (u1 & 0xF)); + } + + // Reduce the JSF array to its actual length + if (jsf.Length > j) + { + jsf = Trim(jsf, j); + } + + return jsf; + } + + public static byte[] GenerateNaf(BigInteger k) + { + if (k.SignValue == 0) + return Arrays.EmptyBytes; + + BigInteger _3k = k.ShiftLeft(1).Add(k); + + int digits = _3k.BitLength - 1; + byte[] naf = new byte[digits]; + + BigInteger diff = _3k.Xor(k); + + for (int i = 1; i < digits; ++i) + { + if (diff.TestBit(i)) + { + naf[i - 1] = (byte)(k.TestBit(i) ? -1 : 1); + ++i; + } + } + + naf[digits - 1] = 1; + + return naf; + } + + /** + * Computes the Window NAF (non-adjacent Form) of an integer. + * @param width The width w of the Window NAF. The width is + * defined as the minimal number w, such that for any + * w consecutive digits in the resulting representation, at + * most one is non-zero. + * @param k The integer of which the Window NAF is computed. + * @return The Window NAF of the given width, such that the following holds: + * k = &sum;i=0l-1 ki2i + * , where the ki denote the elements of the + * returned byte[]. + */ + public static byte[] GenerateWindowNaf(int width, BigInteger k) + { + if (width == 2) + { + return GenerateNaf(k); + } + + if (width < 2 || width > 8) + throw new ArgumentException("must be in the range [2, 8]", "width"); + if (k.SignValue == 0) + return Arrays.EmptyBytes; + + byte[] wnaf = new byte[k.BitLength + 1]; + + // 2^width and a mask and sign bit set accordingly + int pow2 = 1 << width; + int mask = pow2 - 1; + int sign = pow2 >> 1; + + bool carry = false; + int length = 0, pos = 0; + + while (pos <= k.BitLength) + { + if (k.TestBit(pos) == carry) + { + ++pos; + continue; + } + + k = k.ShiftRight(pos); + + int digit = k.IntValue & mask; + if (carry) + { + ++digit; + } + + carry = (digit & sign) != 0; + if (carry) + { + digit -= pow2; + } + + length += (length > 0) ? pos - 1 : pos; + wnaf[length++] = (byte)digit; + pos = width; + } + + // Reduce the WNAF array to its actual length + if (wnaf.Length > length) + { + wnaf = Trim(wnaf, length); + } + + return wnaf; + } + + public static int GetNafWeight(BigInteger k) + { + if (k.SignValue == 0) + return 0; + + BigInteger _3k = k.ShiftLeft(1).Add(k); + BigInteger diff = _3k.Xor(k); + + return diff.BitCount; + } + + public static WNafPreCompInfo GetWNafPreCompInfo(ECPoint p) + { + return GetWNafPreCompInfo(p.Curve.GetPreCompInfo(p, PRECOMP_NAME)); + } + + public static WNafPreCompInfo GetWNafPreCompInfo(PreCompInfo preCompInfo) + { + return preCompInfo as WNafPreCompInfo; + } + + /** + * Determine window width to use for a scalar multiplication of the given size. + * + * @param bits the bit-length of the scalar to multiply by + * @return the window size to use + */ + public static int GetWindowSize(int bits) + { + return GetWindowSize(bits, DEFAULT_WINDOW_SIZE_CUTOFFS, MAX_WIDTH); + } + + /** + * Determine window width to use for a scalar multiplication of the given size. + * + * @param bits the bit-length of the scalar to multiply by + * @param maxWidth the maximum window width to return + * @return the window size to use + */ + public static int GetWindowSize(int bits, int maxWidth) + { + return GetWindowSize(bits, DEFAULT_WINDOW_SIZE_CUTOFFS, maxWidth); + } + + /** + * Determine window width to use for a scalar multiplication of the given size. + * + * @param bits the bit-length of the scalar to multiply by + * @param windowSizeCutoffs a monotonically increasing list of bit sizes at which to increment the window width + * @return the window size to use + */ + public static int GetWindowSize(int bits, int[] windowSizeCutoffs) + { + return GetWindowSize(bits, windowSizeCutoffs, MAX_WIDTH); + } + + /** + * Determine window width to use for a scalar multiplication of the given size. + * + * @param bits the bit-length of the scalar to multiply by + * @param windowSizeCutoffs a monotonically increasing list of bit sizes at which to increment the window width + * @param maxWidth the maximum window width to return + * @return the window size to use + */ + public static int GetWindowSize(int bits, int[] windowSizeCutoffs, int maxWidth) + { + int w = 0; + for (; w < windowSizeCutoffs.Length; ++w) + { + if (bits < windowSizeCutoffs[w]) + { + break; + } + } + + return System.Math.Max(2, System.Math.Min(maxWidth, w + 2)); + } + + [Obsolete] + public static ECPoint MapPointWithPrecomp(ECPoint p, int minWidth, bool includeNegated, + ECPointMap pointMap) + { + ECCurve c = p.Curve; + WNafPreCompInfo infoP = Precompute(p, minWidth, includeNegated); + + ECPoint q = pointMap.Map(p); + c.Precompute(q, PRECOMP_NAME, new MapPointCallback(infoP, includeNegated, pointMap)); + return q; + } + + public static WNafPreCompInfo Precompute(ECPoint p, int minWidth, bool includeNegated) + { + return (WNafPreCompInfo)p.Curve.Precompute(p, PRECOMP_NAME, + new PrecomputeCallback(p, minWidth, includeNegated)); + } + + public static WNafPreCompInfo PrecomputeWithPointMap(ECPoint p, ECPointMap pointMap, WNafPreCompInfo fromWNaf, + bool includeNegated) + { + return (WNafPreCompInfo)p.Curve.Precompute(p, PRECOMP_NAME, + new PrecomputeWithPointMapCallback(p, pointMap, fromWNaf, includeNegated)); + } + + private static byte[] Trim(byte[] a, int length) + { + byte[] result = new byte[length]; + Array.Copy(a, 0, result, 0, result.Length); + return result; + } + + private static int[] Trim(int[] a, int length) + { + int[] result = new int[length]; + Array.Copy(a, 0, result, 0, result.Length); + return result; + } + + private static ECPoint[] ResizeTable(ECPoint[] a, int length) + { + ECPoint[] result = new ECPoint[length]; + Array.Copy(a, 0, result, 0, a.Length); + return result; + } + + private class ConfigureBasepointCallback + : IPreCompCallback + { + private readonly ECCurve m_curve; + private readonly int m_confWidth; + + internal ConfigureBasepointCallback(ECCurve curve, int confWidth) + { + this.m_curve = curve; + this.m_confWidth = confWidth; + } + + public PreCompInfo Precompute(PreCompInfo existing) + { + WNafPreCompInfo existingWNaf = existing as WNafPreCompInfo; + + if (null != existingWNaf && existingWNaf.ConfWidth == m_confWidth) + { + existingWNaf.PromotionCountdown = 0; + return existingWNaf; + } + + WNafPreCompInfo result = new WNafPreCompInfo(); + + result.PromotionCountdown = 0; + result.ConfWidth = m_confWidth; + + if (null != existingWNaf) + { + result.PreComp = existingWNaf.PreComp; + result.PreCompNeg = existingWNaf.PreCompNeg; + result.Twice = existingWNaf.Twice; + result.Width = existingWNaf.Width; + } + + return result; + } + } + + private class MapPointCallback + : IPreCompCallback + { + private readonly WNafPreCompInfo m_infoP; + private readonly bool m_includeNegated; + private readonly ECPointMap m_pointMap; + + internal MapPointCallback(WNafPreCompInfo infoP, bool includeNegated, ECPointMap pointMap) + { + this.m_infoP = infoP; + this.m_includeNegated = includeNegated; + this.m_pointMap = pointMap; + } + + public PreCompInfo Precompute(PreCompInfo existing) + { + WNafPreCompInfo result = new WNafPreCompInfo(); + + result.ConfWidth = m_infoP.ConfWidth; + + ECPoint twiceP = m_infoP.Twice; + if (null != twiceP) + { + ECPoint twiceQ = m_pointMap.Map(twiceP); + result.Twice = twiceQ; + } + + ECPoint[] preCompP = m_infoP.PreComp; + ECPoint[] preCompQ = new ECPoint[preCompP.Length]; + for (int i = 0; i < preCompP.Length; ++i) + { + preCompQ[i] = m_pointMap.Map(preCompP[i]); + } + result.PreComp = preCompQ; + result.Width = m_infoP.Width; + + if (m_includeNegated) + { + ECPoint[] preCompNegQ = new ECPoint[preCompQ.Length]; + for (int i = 0; i < preCompNegQ.Length; ++i) + { + preCompNegQ[i] = preCompQ[i].Negate(); + } + result.PreCompNeg = preCompNegQ; + } + + return result; + } + } + + private class PrecomputeCallback + : IPreCompCallback + { + private readonly ECPoint m_p; + private readonly int m_minWidth; + private readonly bool m_includeNegated; + + internal PrecomputeCallback(ECPoint p, int minWidth, bool includeNegated) + { + this.m_p = p; + this.m_minWidth = minWidth; + this.m_includeNegated = includeNegated; + } + + public PreCompInfo Precompute(PreCompInfo existing) + { + WNafPreCompInfo existingWNaf = existing as WNafPreCompInfo; + + int width = System.Math.Max(2, System.Math.Min(MAX_WIDTH, m_minWidth)); + int reqPreCompLen = 1 << (width - 2); + + if (CheckExisting(existingWNaf, width, reqPreCompLen, m_includeNegated)) + { + existingWNaf.DecrementPromotionCountdown(); + return existingWNaf; + } + + WNafPreCompInfo result = new WNafPreCompInfo(); + + ECCurve c = m_p.Curve; + ECPoint[] preComp = null, preCompNeg = null; + ECPoint twiceP = null; + + if (null != existingWNaf) + { + int promotionCountdown = existingWNaf.DecrementPromotionCountdown(); + result.PromotionCountdown = promotionCountdown; + + int confWidth = existingWNaf.ConfWidth; + result.ConfWidth = confWidth; + + preComp = existingWNaf.PreComp; + preCompNeg = existingWNaf.PreCompNeg; + twiceP = existingWNaf.Twice; + } + + width = System.Math.Min(MAX_WIDTH, System.Math.Max(result.ConfWidth, width)); + reqPreCompLen = 1 << (width - 2); + + int iniPreCompLen = 0; + if (null == preComp) + { + preComp = EMPTY_POINTS; + } + else + { + iniPreCompLen = preComp.Length; + } + + if (iniPreCompLen < reqPreCompLen) + { + preComp = WNafUtilities.ResizeTable(preComp, reqPreCompLen); + + if (reqPreCompLen == 1) + { + preComp[0] = m_p.Normalize(); + } + else + { + int curPreCompLen = iniPreCompLen; + if (curPreCompLen == 0) + { + preComp[0] = m_p; + curPreCompLen = 1; + } + + ECFieldElement iso = null; + + if (reqPreCompLen == 2) + { + preComp[1] = m_p.ThreeTimes(); + } + else + { + ECPoint isoTwiceP = twiceP, last = preComp[curPreCompLen - 1]; + if (null == isoTwiceP) + { + isoTwiceP = preComp[0].Twice(); + twiceP = isoTwiceP; + + /* + * For Fp curves with Jacobian projective coordinates, use a (quasi-)isomorphism + * where 'twiceP' is "affine", so that the subsequent additions are cheaper. This + * also requires scaling the initial point's X, Y coordinates, and reversing the + * isomorphism as part of the subsequent normalization. + * + * NOTE: The correctness of this optimization depends on: + * 1) additions do not use the curve's A, B coefficients. + * 2) no special cases (i.e. Q +/- Q) when calculating 1P, 3P, 5P, ... + */ + if (!twiceP.IsInfinity && ECAlgorithms.IsFpCurve(c) && c.FieldSize >= 64) + { + switch (c.CoordinateSystem) + { + case ECCurve.COORD_JACOBIAN: + case ECCurve.COORD_JACOBIAN_CHUDNOVSKY: + case ECCurve.COORD_JACOBIAN_MODIFIED: + { + iso = twiceP.GetZCoord(0); + isoTwiceP = c.CreatePoint(twiceP.XCoord.ToBigInteger(), + twiceP.YCoord.ToBigInteger()); + + ECFieldElement iso2 = iso.Square(), iso3 = iso2.Multiply(iso); + last = last.ScaleX(iso2).ScaleY(iso3); + + if (iniPreCompLen == 0) + { + preComp[0] = last; + } + break; + } + } + } + } + + while (curPreCompLen < reqPreCompLen) + { + /* + * Compute the new ECPoints for the precomputation array. The values 1, 3, + * 5, ..., 2^(width-1)-1 times p are computed + */ + preComp[curPreCompLen++] = last = last.Add(isoTwiceP); + } + } + + /* + * Having oft-used operands in affine form makes operations faster. + */ + c.NormalizeAll(preComp, iniPreCompLen, reqPreCompLen - iniPreCompLen, iso); + } + } + + if (m_includeNegated) + { + int pos; + if (null == preCompNeg) + { + pos = 0; + preCompNeg = new ECPoint[reqPreCompLen]; + } + else + { + pos = preCompNeg.Length; + if (pos < reqPreCompLen) + { + preCompNeg = WNafUtilities.ResizeTable(preCompNeg, reqPreCompLen); + } + } + + while (pos < reqPreCompLen) + { + preCompNeg[pos] = preComp[pos].Negate(); + ++pos; + } + } + + result.PreComp = preComp; + result.PreCompNeg = preCompNeg; + result.Twice = twiceP; + result.Width = width; + return result; + } + + private bool CheckExisting(WNafPreCompInfo existingWNaf, int width, int reqPreCompLen, bool includeNegated) + { + return null != existingWNaf + && existingWNaf.Width >= System.Math.Max(existingWNaf.ConfWidth, width) + && CheckTable(existingWNaf.PreComp, reqPreCompLen) + && (!includeNegated || CheckTable(existingWNaf.PreCompNeg, reqPreCompLen)); + } + + private bool CheckTable(ECPoint[] table, int reqLen) + { + return null != table && table.Length >= reqLen; + } + } + + private class PrecomputeWithPointMapCallback + : IPreCompCallback + { + private readonly ECPoint m_point; + private readonly ECPointMap m_pointMap; + private readonly WNafPreCompInfo m_fromWNaf; + private readonly bool m_includeNegated; + + internal PrecomputeWithPointMapCallback(ECPoint point, ECPointMap pointMap, WNafPreCompInfo fromWNaf, + bool includeNegated) + { + this.m_point = point; + this.m_pointMap = pointMap; + this.m_fromWNaf = fromWNaf; + this.m_includeNegated = includeNegated; + } + + public PreCompInfo Precompute(PreCompInfo existing) + { + WNafPreCompInfo existingWNaf = existing as WNafPreCompInfo; + + int width = m_fromWNaf.Width; + int reqPreCompLen = m_fromWNaf.PreComp.Length; + + if (CheckExisting(existingWNaf, width, reqPreCompLen, m_includeNegated)) + { + existingWNaf.DecrementPromotionCountdown(); + return existingWNaf; + } + + /* + * TODO Ideally this method would support incremental calculation, but given the + * existing use-cases it would be of little-to-no benefit. + */ + WNafPreCompInfo result = new WNafPreCompInfo(); + + result.PromotionCountdown = m_fromWNaf.PromotionCountdown; + + ECPoint twiceFrom = m_fromWNaf.Twice; + if (null != twiceFrom) + { + ECPoint twice = m_pointMap.Map(twiceFrom); + result.Twice = twice; + } + + ECPoint[] preCompFrom = m_fromWNaf.PreComp; + ECPoint[] preComp = new ECPoint[preCompFrom.Length]; + for (int i = 0; i < preCompFrom.Length; ++i) + { + preComp[i] = m_pointMap.Map(preCompFrom[i]); + } + result.PreComp = preComp; + result.Width = width; + + if (m_includeNegated) + { + ECPoint[] preCompNeg = new ECPoint[preComp.Length]; + for (int i = 0; i < preCompNeg.Length; ++i) + { + preCompNeg[i] = preComp[i].Negate(); + } + result.PreCompNeg = preCompNeg; + } + + return result; + } + + private bool CheckExisting(WNafPreCompInfo existingWNaf, int width, int reqPreCompLen, bool includeNegated) + { + return null != existingWNaf + && existingWNaf.Width >= width + && CheckTable(existingWNaf.PreComp, reqPreCompLen) + && (!includeNegated || CheckTable(existingWNaf.PreCompNeg, reqPreCompLen)); + } + + private bool CheckTable(ECPoint[] table, int reqLen) + { + return null != table && table.Length >= reqLen; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/WNafUtilities.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/WNafUtilities.cs.meta new file mode 100644 index 0000000..e077b11 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/WNafUtilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c6fb87350970cc84589738d664e0e8be +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/WTauNafMultiplier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/WTauNafMultiplier.cs new file mode 100644 index 0000000..4dce544 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/WTauNafMultiplier.cs @@ -0,0 +1,138 @@ +using System; + +using Org.BouncyCastle.Math.EC.Abc; + +namespace Org.BouncyCastle.Math.EC.Multiplier +{ + /** + * Class implementing the WTNAF (Window + * τ-adic Non-Adjacent Form) algorithm. + */ + public class WTauNafMultiplier + : AbstractECMultiplier + { + // TODO Create WTauNafUtilities class and move various functionality into it + internal static readonly string PRECOMP_NAME = "bc_wtnaf"; + + /** + * Multiplies a {@link org.bouncycastle.math.ec.AbstractF2mPoint AbstractF2mPoint} + * by k using the reduced τ-adic NAF (RTNAF) + * method. + * @param p The AbstractF2mPoint to multiply. + * @param k The integer by which to multiply k. + * @return p multiplied by k. + */ + protected override ECPoint MultiplyPositive(ECPoint point, BigInteger k) + { + if (!(point is AbstractF2mPoint)) + throw new ArgumentException("Only AbstractF2mPoint can be used in WTauNafMultiplier"); + + AbstractF2mPoint p = (AbstractF2mPoint)point; + AbstractF2mCurve curve = (AbstractF2mCurve)p.Curve; + int m = curve.FieldSize; + sbyte a = (sbyte)curve.A.ToBigInteger().IntValue; + sbyte mu = Tnaf.GetMu(a); + BigInteger[] s = curve.GetSi(); + + ZTauElement rho = Tnaf.PartModReduction(k, m, a, s, mu, (sbyte)10); + + return MultiplyWTnaf(p, rho, a, mu); + } + + /** + * Multiplies a {@link org.bouncycastle.math.ec.AbstractF2mPoint AbstractF2mPoint} + * by an element λ of Z[τ] using + * the τ-adic NAF (TNAF) method. + * @param p The AbstractF2mPoint to multiply. + * @param lambda The element λ of + * Z[τ] of which to compute the + * [τ]-adic NAF. + * @return p multiplied by λ. + */ + private AbstractF2mPoint MultiplyWTnaf(AbstractF2mPoint p, ZTauElement lambda, + sbyte a, sbyte mu) + { + ZTauElement[] alpha = (a == 0) ? Tnaf.Alpha0 : Tnaf.Alpha1; + + BigInteger tw = Tnaf.GetTw(mu, Tnaf.Width); + + sbyte[]u = Tnaf.TauAdicWNaf(mu, lambda, Tnaf.Width, + BigInteger.ValueOf(Tnaf.Pow2Width), tw, alpha); + + return MultiplyFromWTnaf(p, u); + } + + /** + * Multiplies a {@link org.bouncycastle.math.ec.AbstractF2mPoint AbstractF2mPoint} + * by an element λ of Z[τ] + * using the window τ-adic NAF (TNAF) method, given the + * WTNAF of λ. + * @param p The AbstractF2mPoint to multiply. + * @param u The the WTNAF of λ.. + * @return λ * p + */ + private static AbstractF2mPoint MultiplyFromWTnaf(AbstractF2mPoint p, sbyte[] u) + { + AbstractF2mCurve curve = (AbstractF2mCurve)p.Curve; + sbyte a = (sbyte)curve.A.ToBigInteger().IntValue; + + WTauNafCallback callback = new WTauNafCallback(p, a); + WTauNafPreCompInfo preCompInfo = (WTauNafPreCompInfo)curve.Precompute(p, PRECOMP_NAME, callback); + AbstractF2mPoint[] pu = preCompInfo.PreComp; + + // TODO Include negations in precomp (optionally) and use from here + AbstractF2mPoint[] puNeg = new AbstractF2mPoint[pu.Length]; + for (int i = 0; i < pu.Length; ++i) + { + puNeg[i] = (AbstractF2mPoint)pu[i].Negate(); + } + + + // q = infinity + AbstractF2mPoint q = (AbstractF2mPoint) p.Curve.Infinity; + + int tauCount = 0; + for (int i = u.Length - 1; i >= 0; i--) + { + ++tauCount; + int ui = u[i]; + if (ui != 0) + { + q = q.TauPow(tauCount); + tauCount = 0; + + ECPoint x = ui > 0 ? pu[ui >> 1] : puNeg[(-ui) >> 1]; + q = (AbstractF2mPoint)q.Add(x); + } + } + if (tauCount > 0) + { + q = q.TauPow(tauCount); + } + return q; + } + + private class WTauNafCallback + : IPreCompCallback + { + private readonly AbstractF2mPoint m_p; + private readonly sbyte m_a; + + internal WTauNafCallback(AbstractF2mPoint p, sbyte a) + { + this.m_p = p; + this.m_a = a; + } + + public PreCompInfo Precompute(PreCompInfo existing) + { + if (existing is WTauNafPreCompInfo) + return existing; + + WTauNafPreCompInfo result = new WTauNafPreCompInfo(); + result.PreComp = Tnaf.GetPreComp(m_p, m_a); + return result; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/WTauNafMultiplier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/WTauNafMultiplier.cs.meta new file mode 100644 index 0000000..ddda7f9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/WTauNafMultiplier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a6db02d941b7a9f4d8e4725e6b77a430 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/WTauNafPreCompInfo.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/WTauNafPreCompInfo.cs new file mode 100644 index 0000000..72659b3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/WTauNafPreCompInfo.cs @@ -0,0 +1,24 @@ +namespace Org.BouncyCastle.Math.EC.Multiplier +{ + /** + * Class holding precomputation data for the WTNAF (Window + * τ-adic Non-Adjacent Form) algorithm. + */ + public class WTauNafPreCompInfo + : PreCompInfo + { + /** + * Array holding the precomputed AbstractF2mPoints used for the + * WTNAF multiplication in + * {@link org.bouncycastle.math.ec.multiplier.WTauNafMultiplier.multiply() + * WTauNafMultiplier.multiply()}. + */ + protected AbstractF2mPoint[] m_preComp; + + public virtual AbstractF2mPoint[] PreComp + { + get { return m_preComp; } + set { this.m_preComp = value; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/WTauNafPreCompInfo.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/WTauNafPreCompInfo.cs.meta new file mode 100644 index 0000000..f9c2913 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/WTauNafPreCompInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d9421ef0ef635b446bc7221e37c94aa1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/ZSignedDigitL2RMultiplier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/ZSignedDigitL2RMultiplier.cs new file mode 100644 index 0000000..1c7a5d1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/ZSignedDigitL2RMultiplier.cs @@ -0,0 +1,32 @@ +using System; + +namespace Org.BouncyCastle.Math.EC.Multiplier +{ + [Obsolete("Will be removed")] + public class ZSignedDigitL2RMultiplier + : AbstractECMultiplier + { + /** + * 'Zeroless' Signed Digit Left-to-Right. + */ + protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k) + { + ECPoint addP = p.Normalize(), subP = addP.Negate(); + + ECPoint R0 = addP; + + int n = k.BitLength; + int s = k.GetLowestSetBit(); + + int i = n; + while (--i > s) + { + R0 = R0.TwicePlus(k.TestBit(i) ? addP : subP); + } + + R0 = R0.TimesPow2(s); + + return R0; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/ZSignedDigitL2RMultiplier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/ZSignedDigitL2RMultiplier.cs.meta new file mode 100644 index 0000000..60e0fcf --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/ZSignedDigitL2RMultiplier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 557235803e3ac3f49bed458b7c135d3d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/ZSignedDigitR2LMultiplier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/ZSignedDigitR2LMultiplier.cs new file mode 100644 index 0000000..46d234c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/ZSignedDigitR2LMultiplier.cs @@ -0,0 +1,33 @@ +using System; + +namespace Org.BouncyCastle.Math.EC.Multiplier +{ + [Obsolete("Will be removed")] + public class ZSignedDigitR2LMultiplier + : AbstractECMultiplier + { + /** + * 'Zeroless' Signed Digit Right-to-Left. + */ + protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k) + { + ECPoint R0 = p.Curve.Infinity, R1 = p; + + int n = k.BitLength; + int s = k.GetLowestSetBit(); + + R1 = R1.TimesPow2(s); + + int i = s; + while (++i < n) + { + R0 = R0.Add(k.TestBit(i) ? R1 : R1.Negate()); + R1 = R1.Twice(); + } + + R0 = R0.Add(R1); + + return R0; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/ZSignedDigitR2LMultiplier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/ZSignedDigitR2LMultiplier.cs.meta new file mode 100644 index 0000000..2df7f95 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/multiplier/ZSignedDigitR2LMultiplier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: de36c44f0fdd7fa48ba4cc53c50c5dc8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/rfc7748.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/rfc7748.meta new file mode 100644 index 0000000..b30a3f8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/rfc7748.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 88ea49c1f9d53ce419e113f9202bb277 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/rfc7748/X25519.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/rfc7748/X25519.cs new file mode 100644 index 0000000..bf845d2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/rfc7748/X25519.cs @@ -0,0 +1,161 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Math.EC.Rfc8032; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math.EC.Rfc7748 +{ + public abstract class X25519 + { + public const int PointSize = 32; + public const int ScalarSize = 32; + + private class F : X25519Field {}; + + private const int C_A = 486662; + private const int C_A24 = (C_A + 2)/4; + + //private static readonly int[] SqrtNeg486664 = { 0x03457E06, 0x03812ABF, 0x01A82CC6, 0x028A5BE8, 0x018B43A7, + // 0x03FC4F7E, 0x02C23700, 0x006BBD27, 0x03A30500, 0x001E4DDB }; + + public static bool CalculateAgreement(byte[] k, int kOff, byte[] u, int uOff, byte[] r, int rOff) + { + ScalarMult(k, kOff, u, uOff, r, rOff); + return !Arrays.AreAllZeroes(r, rOff, PointSize); + } + + private static uint Decode32(byte[] bs, int off) + { + uint n = bs[off]; + n |= (uint)bs[++off] << 8; + n |= (uint)bs[++off] << 16; + n |= (uint)bs[++off] << 24; + return n; + } + + private static void DecodeScalar(byte[] k, int kOff, uint[] n) + { + for (int i = 0; i < 8; ++i) + { + n[i] = Decode32(k, kOff + i * 4); + } + + n[0] &= 0xFFFFFFF8U; + n[7] &= 0x7FFFFFFFU; + n[7] |= 0x40000000U; + } + + public static void GeneratePrivateKey(SecureRandom random, byte[] k) + { + random.NextBytes(k); + + k[0] &= 0xF8; + k[ScalarSize - 1] &= 0x7F; + k[ScalarSize - 1] |= 0x40; + } + + public static void GeneratePublicKey(byte[] k, int kOff, byte[] r, int rOff) + { + ScalarMultBase(k, kOff, r, rOff); + } + + private static void PointDouble(int[] x, int[] z) + { + int[] a = F.Create(); + int[] b = F.Create(); + + F.Apm(x, z, a, b); + F.Sqr(a, a); + F.Sqr(b, b); + F.Mul(a, b, x); + F.Sub(a, b, a); + F.Mul(a, C_A24, z); + F.Add(z, b, z); + F.Mul(z, a, z); + } + + public static void Precompute() + { + Ed25519.Precompute(); + } + + public static void ScalarMult(byte[] k, int kOff, byte[] u, int uOff, byte[] r, int rOff) + { + uint[] n = new uint[8]; DecodeScalar(k, kOff, n); + + int[] x1 = F.Create(); F.Decode(u, uOff, x1); + int[] x2 = F.Create(); F.Copy(x1, 0, x2, 0); + int[] z2 = F.Create(); z2[0] = 1; + int[] x3 = F.Create(); x3[0] = 1; + int[] z3 = F.Create(); + + int[] t1 = F.Create(); + int[] t2 = F.Create(); + + Debug.Assert(n[7] >> 30 == 1U); + + int bit = 254, swap = 1; + do + { + F.Apm(x3, z3, t1, x3); + F.Apm(x2, z2, z3, x2); + F.Mul(t1, x2, t1); + F.Mul(x3, z3, x3); + F.Sqr(z3, z3); + F.Sqr(x2, x2); + + F.Sub(z3, x2, t2); + F.Mul(t2, C_A24, z2); + F.Add(z2, x2, z2); + F.Mul(z2, t2, z2); + F.Mul(x2, z3, x2); + + F.Apm(t1, x3, x3, z3); + F.Sqr(x3, x3); + F.Sqr(z3, z3); + F.Mul(z3, x1, z3); + + --bit; + + int word = bit >> 5, shift = bit & 0x1F; + int kt = (int)(n[word] >> shift) & 1; + swap ^= kt; + F.CSwap(swap, x2, x3); + F.CSwap(swap, z2, z3); + swap = kt; + } + while (bit >= 3); + + Debug.Assert(swap == 0); + + for (int i = 0; i < 3; ++i) + { + PointDouble(x2, z2); + } + + F.Inv(z2, z2); + F.Mul(x2, z2, x2); + + F.Normalize(x2); + F.Encode(x2, r, rOff); + } + + public static void ScalarMultBase(byte[] k, int kOff, byte[] r, int rOff) + { + int[] y = F.Create(); + int[] z = F.Create(); + + Ed25519.ScalarMultBaseYZ(k, kOff, y, z); + + F.Apm(z, y, y, z); + + F.Inv(z, z); + F.Mul(y, z, y); + + F.Normalize(y); + F.Encode(y, r, rOff); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/rfc7748/X25519.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/rfc7748/X25519.cs.meta new file mode 100644 index 0000000..d417227 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/rfc7748/X25519.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c56ea7b03ca1add4782a17b1a59239a5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/rfc7748/X25519Field.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/rfc7748/X25519Field.cs new file mode 100644 index 0000000..d0b8352 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/rfc7748/X25519Field.cs @@ -0,0 +1,759 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Rfc7748 +{ + public abstract class X25519Field + { + public const int Size = 10; + + private const int M24 = 0x00FFFFFF; + private const int M25 = 0x01FFFFFF; + private const int M26 = 0x03FFFFFF; + + private static readonly uint[] P32 = new uint[]{ 0xFFFFFFEDU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x7FFFFFFFU }; + private static readonly int[] RootNegOne = { 0x020EA0B0, 0x0386C9D2, 0x00478C4E, 0x0035697F, 0x005E8630, + 0x01FBD7A7, 0x0340264F, 0x01F0B2B4, 0x00027E0E, 0x00570649 }; + + protected X25519Field() {} + + public static void Add(int[] x, int[] y, int[] z) + { + for (int i = 0; i < Size; ++i) + { + z[i] = x[i] + y[i]; + } + } + + public static void AddOne(int[] z) + { + z[0] += 1; + } + + public static void AddOne(int[] z, int zOff) + { + z[zOff] += 1; + } + + public static void Apm(int[] x, int[] y, int[] zp, int[] zm) + { + for (int i = 0; i < Size; ++i) + { + int xi = x[i], yi = y[i]; + zp[i] = xi + yi; + zm[i] = xi - yi; + } + } + + public static int AreEqual(int[] x, int[] y) + { + int d = 0; + for (int i = 0; i < Size; ++i) + { + d |= x[i] ^ y[i]; + } + d |= d >> 16; + d &= 0xFFFF; + return (d - 1) >> 31; + } + + public static bool AreEqualVar(int[] x, int[] y) + { + return 0 != AreEqual(x, y); + } + + public static void Carry(int[] z) + { + int z0 = z[0], z1 = z[1], z2 = z[2], z3 = z[3], z4 = z[4]; + int z5 = z[5], z6 = z[6], z7 = z[7], z8 = z[8], z9 = z[9]; + + z2 += (z1 >> 26); z1 &= M26; + z4 += (z3 >> 26); z3 &= M26; + z7 += (z6 >> 26); z6 &= M26; + z9 += (z8 >> 26); z8 &= M26; + + z3 += (z2 >> 25); z2 &= M25; + z5 += (z4 >> 25); z4 &= M25; + z8 += (z7 >> 25); z7 &= M25; + //z0 += (z9 >> 24) * 19; z9 &= M24; + z0 += (z9 >> 25) * 38; z9 &= M25; + + z1 += (z0 >> 26); z0 &= M26; + z6 += (z5 >> 26); z5 &= M26; + + z2 += (z1 >> 26); z1 &= M26; + z4 += (z3 >> 26); z3 &= M26; + z7 += (z6 >> 26); z6 &= M26; + z9 += (z8 >> 26); z8 &= M26; + + z[0] = z0; z[1] = z1; z[2] = z2; z[3] = z3; z[4] = z4; + z[5] = z5; z[6] = z6; z[7] = z7; z[8] = z8; z[9] = z9; + } + + public static void CMov(int cond, int[] x, int xOff, int[] z, int zOff) + { + Debug.Assert(0 == cond || -1 == cond); + + for (int i = 0; i < Size; ++i) + { + int z_i = z[zOff + i], diff = z_i ^ x[xOff + i]; + z_i ^= (diff & cond); + z[zOff + i] = z_i; + } + } + + public static void CNegate(int negate, int[] z) + { + Debug.Assert(negate >> 1 == 0); + + int mask = 0 - negate; + for (int i = 0; i < Size; ++i) + { + z[i] = (z[i] ^ mask) - mask; + } + } + + public static void Copy(int[] x, int xOff, int[] z, int zOff) + { + for (int i = 0; i < Size; ++i) + { + z[zOff + i] = x[xOff + i]; + } + } + + public static int[] Create() + { + return new int[Size]; + } + + public static int[] CreateTable(int n) + { + return new int[Size * n]; + } + + public static void CSwap(int swap, int[] a, int[] b) + { + Debug.Assert(swap >> 1 == 0); + Debug.Assert(a != b); + + int mask = 0 - swap; + for (int i = 0; i < Size; ++i) + { + int ai = a[i], bi = b[i]; + int dummy = mask & (ai ^ bi); + a[i] = ai ^ dummy; + b[i] = bi ^ dummy; + } + } + + [CLSCompliantAttribute(false)] + public static void Decode(uint[] x, int xOff, int[] z) + { + Decode128(x, xOff, z, 0); + Decode128(x, xOff + 4, z, 5); + z[9] &= M24; + } + + public static void Decode(byte[] x, int xOff, int[] z) + { + Decode128(x, xOff, z, 0); + Decode128(x, xOff + 16, z, 5); + z[9] &= M24; + } + + private static void Decode128(uint[] x, int xOff, int[] z, int zOff) + { + uint t0 = x[xOff + 0], t1 = x[xOff + 1], t2 = x[xOff + 2], t3 = x[xOff + 3]; + + z[zOff + 0] = (int)t0 & M26; + z[zOff + 1] = (int)((t1 << 6) | (t0 >> 26)) & M26; + z[zOff + 2] = (int)((t2 << 12) | (t1 >> 20)) & M25; + z[zOff + 3] = (int)((t3 << 19) | (t2 >> 13)) & M26; + z[zOff + 4] = (int)(t3 >> 7); + } + + private static void Decode128(byte[] bs, int off, int[] z, int zOff) + { + uint t0 = Decode32(bs, off + 0); + uint t1 = Decode32(bs, off + 4); + uint t2 = Decode32(bs, off + 8); + uint t3 = Decode32(bs, off + 12); + + z[zOff + 0] = (int)t0 & M26; + z[zOff + 1] = (int)((t1 << 6) | (t0 >> 26)) & M26; + z[zOff + 2] = (int)((t2 << 12) | (t1 >> 20)) & M25; + z[zOff + 3] = (int)((t3 << 19) | (t2 >> 13)) & M26; + z[zOff + 4] = (int)(t3 >> 7); + } + + private static uint Decode32(byte[] bs, int off) + { + uint n = bs[off]; + n |= (uint)bs[++off] << 8; + n |= (uint)bs[++off] << 16; + n |= (uint)bs[++off] << 24; + return n; + } + + [CLSCompliantAttribute(false)] + public static void Encode(int[] x, uint[] z, int zOff) + { + Encode128(x, 0, z, zOff); + Encode128(x, 5, z, zOff + 4); + } + + public static void Encode(int[] x, byte[] z, int zOff) + { + Encode128(x, 0, z, zOff); + Encode128(x, 5, z, zOff + 16); + } + + private static void Encode128(int[] x, int xOff, uint[] z, int zOff) + { + uint x0 = (uint)x[xOff + 0], x1 = (uint)x[xOff + 1], x2 = (uint)x[xOff + 2], x3 = (uint)x[xOff + 3], + x4 = (uint)x[xOff + 4]; + + z[zOff + 0] = x0 | (x1 << 26); + z[zOff + 1] = (x1 >> 6) | (x2 << 20); + z[zOff + 2] = (x2 >> 12) | (x3 << 13); + z[zOff + 3] = (x3 >> 19) | (x4 << 7); + } + + private static void Encode128(int[] x, int xOff, byte[] bs, int off) + { + uint x0 = (uint)x[xOff + 0], x1 = (uint)x[xOff + 1], x2 = (uint)x[xOff + 2]; + uint x3 = (uint)x[xOff + 3], x4 = (uint)x[xOff + 4]; + + uint t0 = x0 | (x1 << 26); Encode32(t0, bs, off + 0); + uint t1 = (x1 >> 6) | (x2 << 20); Encode32(t1, bs, off + 4); + uint t2 = (x2 >> 12) | (x3 << 13); Encode32(t2, bs, off + 8); + uint t3 = (x3 >> 19) | (x4 << 7); Encode32(t3, bs, off + 12); + } + + private static void Encode32(uint n, byte[] bs, int off) + { + bs[ off] = (byte)(n ); + bs[++off] = (byte)(n >> 8); + bs[++off] = (byte)(n >> 16); + bs[++off] = (byte)(n >> 24); + } + + public static void Inv(int[] x, int[] z) + { + //int[] x2 = Create(); + //int[] t = Create(); + //PowPm5d8(x, x2, t); + //Sqr(t, 3, t); + //Mul(t, x2, z); + + int[] t = Create(); + uint[] u = new uint[8]; + + Copy(x, 0, t, 0); + Normalize(t); + Encode(t, u, 0); + + Mod.ModOddInverse(P32, u, u); + + Decode(u, 0, z); + } + + public static void InvVar(int[] x, int[] z) + { + int[] t = Create(); + uint[] u = new uint[8]; + + Copy(x, 0, t, 0); + Normalize(t); + Encode(t, u, 0); + + Mod.ModOddInverseVar(P32, u, u); + + Decode(u, 0, z); + } + + public static int IsOne(int[] x) + { + int d = x[0] ^ 1; + for (int i = 1; i < Size; ++i) + { + d |= x[i]; + } + d |= d >> 16; + d &= 0xFFFF; + return (d - 1) >> 31; + } + + public static bool IsOneVar(int[] x) + { + return 0 != IsOne(x); + } + + public static int IsZero(int[] x) + { + int d = 0; + for (int i = 0; i < Size; ++i) + { + d |= x[i]; + } + d |= d >> 16; + d &= 0xFFFF; + return (d - 1) >> 31; + } + + public static bool IsZeroVar(int[] x) + { + return 0 != IsZero(x); + } + + public static void Mul(int[] x, int y, int[] z) + { + int x0 = x[0], x1 = x[1], x2 = x[2], x3 = x[3], x4 = x[4]; + int x5 = x[5], x6 = x[6], x7 = x[7], x8 = x[8], x9 = x[9]; + long c0, c1, c2, c3; + + c0 = (long)x2 * y; x2 = (int)c0 & M25; c0 >>= 25; + c1 = (long)x4 * y; x4 = (int)c1 & M25; c1 >>= 25; + c2 = (long)x7 * y; x7 = (int)c2 & M25; c2 >>= 25; + //c3 = (long)x9 * y; x9 = (int)c3 & M24; c3 >>= 24; + //c3 *= 19; + c3 = (long)x9 * y; x9 = (int)c3 & M25; c3 >>= 25; + c3 *= 38; + + c3 += (long)x0 * y; z[0] = (int)c3 & M26; c3 >>= 26; + c1 += (long)x5 * y; z[5] = (int)c1 & M26; c1 >>= 26; + + c3 += (long)x1 * y; z[1] = (int)c3 & M26; c3 >>= 26; + c0 += (long)x3 * y; z[3] = (int)c0 & M26; c0 >>= 26; + c1 += (long)x6 * y; z[6] = (int)c1 & M26; c1 >>= 26; + c2 += (long)x8 * y; z[8] = (int)c2 & M26; c2 >>= 26; + + z[2] = x2 + (int)c3; + z[4] = x4 + (int)c0; + z[7] = x7 + (int)c1; + z[9] = x9 + (int)c2; + } + + public static void Mul(int[] x, int[] y, int[] z) + { + int x0 = x[0], y0 = y[0]; + int x1 = x[1], y1 = y[1]; + int x2 = x[2], y2 = y[2]; + int x3 = x[3], y3 = y[3]; + int x4 = x[4], y4 = y[4]; + + int u0 = x[5], v0 = y[5]; + int u1 = x[6], v1 = y[6]; + int u2 = x[7], v2 = y[7]; + int u3 = x[8], v3 = y[8]; + int u4 = x[9], v4 = y[9]; + + long a0 = (long)x0 * y0; + long a1 = (long)x0 * y1 + + (long)x1 * y0; + long a2 = (long)x0 * y2 + + (long)x1 * y1 + + (long)x2 * y0; + long a3 = (long)x1 * y2 + + (long)x2 * y1; + a3 <<= 1; + a3 += (long)x0 * y3 + + (long)x3 * y0; + long a4 = (long)x2 * y2; + a4 <<= 1; + a4 += (long)x0 * y4 + + (long)x1 * y3 + + (long)x3 * y1 + + (long)x4 * y0; + long a5 = (long)x1 * y4 + + (long)x2 * y3 + + (long)x3 * y2 + + (long)x4 * y1; + a5 <<= 1; + long a6 = (long)x2 * y4 + + (long)x4 * y2; + a6 <<= 1; + a6 += (long)x3 * y3; + long a7 = (long)x3 * y4 + + (long)x4 * y3; + long a8 = (long)x4 * y4; + a8 <<= 1; + + long b0 = (long)u0 * v0; + long b1 = (long)u0 * v1 + + (long)u1 * v0; + long b2 = (long)u0 * v2 + + (long)u1 * v1 + + (long)u2 * v0; + long b3 = (long)u1 * v2 + + (long)u2 * v1; + b3 <<= 1; + b3 += (long)u0 * v3 + + (long)u3 * v0; + long b4 = (long)u2 * v2; + b4 <<= 1; + b4 += (long)u0 * v4 + + (long)u1 * v3 + + (long)u3 * v1 + + (long)u4 * v0; + long b5 = (long)u1 * v4 + + (long)u2 * v3 + + (long)u3 * v2 + + (long)u4 * v1; + //b5 <<= 1; + long b6 = (long)u2 * v4 + + (long)u4 * v2; + b6 <<= 1; + b6 += (long)u3 * v3; + long b7 = (long)u3 * v4 + + (long)u4 * v3; + long b8 = (long)u4 * v4; + //b8 <<= 1; + + a0 -= b5 * 76; + a1 -= b6 * 38; + a2 -= b7 * 38; + a3 -= b8 * 76; + + a5 -= b0; + a6 -= b1; + a7 -= b2; + a8 -= b3; + //long a9 = -b4; + + x0 += u0; y0 += v0; + x1 += u1; y1 += v1; + x2 += u2; y2 += v2; + x3 += u3; y3 += v3; + x4 += u4; y4 += v4; + + long c0 = (long)x0 * y0; + long c1 = (long)x0 * y1 + + (long)x1 * y0; + long c2 = (long)x0 * y2 + + (long)x1 * y1 + + (long)x2 * y0; + long c3 = (long)x1 * y2 + + (long)x2 * y1; + c3 <<= 1; + c3 += (long)x0 * y3 + + (long)x3 * y0; + long c4 = (long)x2 * y2; + c4 <<= 1; + c4 += (long)x0 * y4 + + (long)x1 * y3 + + (long)x3 * y1 + + (long)x4 * y0; + long c5 = (long)x1 * y4 + + (long)x2 * y3 + + (long)x3 * y2 + + (long)x4 * y1; + c5 <<= 1; + long c6 = (long)x2 * y4 + + (long)x4 * y2; + c6 <<= 1; + c6 += (long)x3 * y3; + long c7 = (long)x3 * y4 + + (long)x4 * y3; + long c8 = (long)x4 * y4; + c8 <<= 1; + + int z8, z9; + long t; + + t = a8 + (c3 - a3); + z8 = (int)t & M26; t >>= 26; + //t += a9 + (c4 - a4); + t += (c4 - a4) - b4; + //z9 = (int)t & M24; t >>= 24; + //t = a0 + (t + ((c5 - a5) << 1)) * 19; + z9 = (int)t & M25; t >>= 25; + t = a0 + (t + c5 - a5) * 38; + z[0] = (int)t & M26; t >>= 26; + t += a1 + (c6 - a6) * 38; + z[1] = (int)t & M26; t >>= 26; + t += a2 + (c7 - a7) * 38; + z[2] = (int)t & M25; t >>= 25; + t += a3 + (c8 - a8) * 38; + z[3] = (int)t & M26; t >>= 26; + //t += a4 - a9 * 38; + t += a4 + b4 * 38; + z[4] = (int)t & M25; t >>= 25; + t += a5 + (c0 - a0); + z[5] = (int)t & M26; t >>= 26; + t += a6 + (c1 - a1); + z[6] = (int)t & M26; t >>= 26; + t += a7 + (c2 - a2); + z[7] = (int)t & M25; t >>= 25; + t += z8; + z[8] = (int)t & M26; t >>= 26; + z[9] = z9 + (int)t; + } + + public static void Negate(int[] x, int[] z) + { + for (int i = 0; i < Size; ++i) + { + z[i] = -x[i]; + } + } + + public static void Normalize(int[] z) + { + int x = (z[9] >> 23) & 1; + Reduce(z, x); + Reduce(z, -x); + Debug.Assert(z[9] >> 24 == 0); + } + + public static void One(int[] z) + { + z[0] = 1; + for (int i = 1; i < Size; ++i) + { + z[i] = 0; + } + } + + private static void PowPm5d8(int[] x, int[] rx2, int[] rz) + { + // z = x^((p-5)/8) = x^FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD + // (250 1s) (1 0s) (1 1s) + // Addition chain: [1] 2 3 5 10 15 25 50 75 125 [250] + + int[] x2 = rx2; Sqr(x, x2); Mul(x, x2, x2); + int[] x3 = Create(); Sqr(x2, x3); Mul(x, x3, x3); + int[] x5 = x3; Sqr(x3, 2, x5); Mul(x2, x5, x5); + int[] x10 = Create(); Sqr(x5, 5, x10); Mul(x5, x10, x10); + int[] x15 = Create(); Sqr(x10, 5, x15); Mul(x5, x15, x15); + int[] x25 = x5; Sqr(x15, 10, x25); Mul(x10, x25, x25); + int[] x50 = x10; Sqr(x25, 25, x50); Mul(x25, x50, x50); + int[] x75 = x15; Sqr(x50, 25, x75); Mul(x25, x75, x75); + int[] x125 = x25; Sqr(x75, 50, x125); Mul(x50, x125, x125); + int[] x250 = x50; Sqr(x125, 125, x250); Mul(x125, x250, x250); + + int[] t = x125; + Sqr(x250, 2, t); + Mul(t, x, rz); + } + + private static void Reduce(int[] z, int x) + { + int t = z[9], z9 = t & M24; + t = (t >> 24) + x; + + long cc = t * 19; + cc += z[0]; z[0] = (int)cc & M26; cc >>= 26; + cc += z[1]; z[1] = (int)cc & M26; cc >>= 26; + cc += z[2]; z[2] = (int)cc & M25; cc >>= 25; + cc += z[3]; z[3] = (int)cc & M26; cc >>= 26; + cc += z[4]; z[4] = (int)cc & M25; cc >>= 25; + cc += z[5]; z[5] = (int)cc & M26; cc >>= 26; + cc += z[6]; z[6] = (int)cc & M26; cc >>= 26; + cc += z[7]; z[7] = (int)cc & M25; cc >>= 25; + cc += z[8]; z[8] = (int)cc & M26; cc >>= 26; + z[9] = z9 + (int)cc; + } + + public static void Sqr(int[] x, int[] z) + { + int x0 = x[0]; + int x1 = x[1]; + int x2 = x[2]; + int x3 = x[3]; + int x4 = x[4]; + + int u0 = x[5]; + int u1 = x[6]; + int u2 = x[7]; + int u3 = x[8]; + int u4 = x[9]; + + int x1_2 = x1 * 2; + int x2_2 = x2 * 2; + int x3_2 = x3 * 2; + int x4_2 = x4 * 2; + + long a0 = (long)x0 * x0; + long a1 = (long)x0 * x1_2; + long a2 = (long)x0 * x2_2 + + (long)x1 * x1; + long a3 = (long)x1_2 * x2_2 + + (long)x0 * x3_2; + long a4 = (long)x2 * x2_2 + + (long)x0 * x4_2 + + (long)x1 * x3_2; + long a5 = (long)x1_2 * x4_2 + + (long)x2_2 * x3_2; + long a6 = (long)x2_2 * x4_2 + + (long)x3 * x3; + long a7 = (long)x3 * x4_2; + long a8 = (long)x4 * x4_2; + + int u1_2 = u1 * 2; + int u2_2 = u2 * 2; + int u3_2 = u3 * 2; + int u4_2 = u4 * 2; + + long b0 = (long)u0 * u0; + long b1 = (long)u0 * u1_2; + long b2 = (long)u0 * u2_2 + + (long)u1 * u1; + long b3 = (long)u1_2 * u2_2 + + (long)u0 * u3_2; + long b4 = (long)u2 * u2_2 + + (long)u0 * u4_2 + + (long)u1 * u3_2; + long b5 = (long)u1_2 * u4_2 + + (long)u2_2 * u3_2; + long b6 = (long)u2_2 * u4_2 + + (long)u3 * u3; + long b7 = (long)u3 * u4_2; + long b8 = (long)u4 * u4_2; + + a0 -= b5 * 38; + a1 -= b6 * 38; + a2 -= b7 * 38; + a3 -= b8 * 38; + + a5 -= b0; + a6 -= b1; + a7 -= b2; + a8 -= b3; + //long a9 = -b4; + + x0 += u0; + x1 += u1; + x2 += u2; + x3 += u3; + x4 += u4; + + x1_2 = x1 * 2; + x2_2 = x2 * 2; + x3_2 = x3 * 2; + x4_2 = x4 * 2; + + long c0 = (long)x0 * x0; + long c1 = (long)x0 * x1_2; + long c2 = (long)x0 * x2_2 + + (long)x1 * x1; + long c3 = (long)x1_2 * x2_2 + + (long)x0 * x3_2; + long c4 = (long)x2 * x2_2 + + (long)x0 * x4_2 + + (long)x1 * x3_2; + long c5 = (long)x1_2 * x4_2 + + (long)x2_2 * x3_2; + long c6 = (long)x2_2 * x4_2 + + (long)x3 * x3; + long c7 = (long)x3 * x4_2; + long c8 = (long)x4 * x4_2; + + int z8, z9; + long t; + + t = a8 + (c3 - a3); + z8 = (int)t & M26; t >>= 26; + //t += a9 + (c4 - a4); + t += (c4 - a4) - b4; + //z9 = (int)t & M24; t >>= 24; + //t = a0 + (t + ((c5 - a5) << 1)) * 19; + z9 = (int)t & M25; t >>= 25; + t = a0 + (t + c5 - a5) * 38; + z[0] = (int)t & M26; t >>= 26; + t += a1 + (c6 - a6) * 38; + z[1] = (int)t & M26; t >>= 26; + t += a2 + (c7 - a7) * 38; + z[2] = (int)t & M25; t >>= 25; + t += a3 + (c8 - a8) * 38; + z[3] = (int)t & M26; t >>= 26; + //t += a4 - a9 * 38; + t += a4 + b4 * 38; + z[4] = (int)t & M25; t >>= 25; + t += a5 + (c0 - a0); + z[5] = (int)t & M26; t >>= 26; + t += a6 + (c1 - a1); + z[6] = (int)t & M26; t >>= 26; + t += a7 + (c2 - a2); + z[7] = (int)t & M25; t >>= 25; + t += z8; + z[8] = (int)t & M26; t >>= 26; + z[9] = z9 + (int)t; + } + + public static void Sqr(int[] x, int n, int[] z) + { + Debug.Assert(n > 0); + + Sqr(x, z); + + while (--n > 0) + { + Sqr(z, z); + } + } + + public static bool SqrtRatioVar(int[] u, int[] v, int[] z) + { + int[] uv3 = Create(); + int[] uv7 = Create(); + + Mul(u, v, uv3); + Sqr(v, uv7); + Mul(uv3, uv7, uv3); + Sqr(uv7, uv7); + Mul(uv7, uv3, uv7); + + int[] t = Create(); + int[] x = Create(); + PowPm5d8(uv7, t, x); + Mul(x, uv3, x); + + int[] vx2 = Create(); + Sqr(x, vx2); + Mul(vx2, v, vx2); + + Sub(vx2, u, t); + Normalize(t); + if (IsZeroVar(t)) + { + Copy(x, 0, z, 0); + return true; + } + + Add(vx2, u, t); + Normalize(t); + if (IsZeroVar(t)) + { + Mul(x, RootNegOne, z); + return true; + } + + return false; + } + + public static void Sub(int[] x, int[] y, int[] z) + { + for (int i = 0; i < Size; ++i) + { + z[i] = x[i] - y[i]; + } + } + + public static void SubOne(int[] z) + { + z[0] -= 1; + } + + public static void Zero(int[] z) + { + for (int i = 0; i < Size; ++i) + { + z[i] = 0; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/rfc7748/X25519Field.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/rfc7748/X25519Field.cs.meta new file mode 100644 index 0000000..0b42716 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/rfc7748/X25519Field.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b53d6820c175d6f4bb2935de47234544 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/rfc7748/X448.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/rfc7748/X448.cs new file mode 100644 index 0000000..061a131 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/rfc7748/X448.cs @@ -0,0 +1,168 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Math.EC.Rfc8032; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math.EC.Rfc7748 +{ + public abstract class X448 + { + public const int PointSize = 56; + public const int ScalarSize = 56; + + private class F : X448Field {}; + + private const uint C_A = 156326; + private const uint C_A24 = (C_A + 2)/4; + + //private static readonly uint[] Sqrt156324 = { 0x0551B193U, 0x07A21E17U, 0x0E635AD3U, 0x00812ABBU, 0x025B3F99U, 0x01605224U, + // 0x0AF8CB32U, 0x0D2E7D68U, 0x06BA50FDU, 0x08E55693U, 0x0CB08EB4U, 0x02ABEBC1U, 0x051BA0BBU, 0x02F8812EU, 0x0829B611U, + // 0x0BA4D3A0U }; + + public static bool CalculateAgreement(byte[] k, int kOff, byte[] u, int uOff, byte[] r, int rOff) + { + ScalarMult(k, kOff, u, uOff, r, rOff); + return !Arrays.AreAllZeroes(r, rOff, PointSize); + } + + private static uint Decode32(byte[] bs, int off) + { + uint n = bs[off]; + n |= (uint)bs[++off] << 8; + n |= (uint)bs[++off] << 16; + n |= (uint)bs[++off] << 24; + return n; + } + + private static void DecodeScalar(byte[] k, int kOff, uint[] n) + { + for (int i = 0; i < 14; ++i) + { + n[i] = Decode32(k, kOff + i * 4); + } + + n[ 0] &= 0xFFFFFFFCU; + n[13] |= 0x80000000U; + } + + public static void GeneratePrivateKey(SecureRandom random, byte[] k) + { + random.NextBytes(k); + + k[0] &= 0xFC; + k[ScalarSize - 1] |= 0x80; + } + + public static void GeneratePublicKey(byte[] k, int kOff, byte[] r, int rOff) + { + ScalarMultBase(k, kOff, r, rOff); + } + + private static void PointDouble(uint[] x, uint[] z) + { + uint[] a = F.Create(); + uint[] b = F.Create(); + + //F.Apm(x, z, a, b); + F.Add(x, z, a); + F.Sub(x, z, b); + F.Sqr(a, a); + F.Sqr(b, b); + F.Mul(a, b, x); + F.Sub(a, b, a); + F.Mul(a, C_A24, z); + F.Add(z, b, z); + F.Mul(z, a, z); + } + + public static void Precompute() + { + Ed448.Precompute(); + } + + public static void ScalarMult(byte[] k, int kOff, byte[] u, int uOff, byte[] r, int rOff) + { + uint[] n = new uint[14]; DecodeScalar(k, kOff, n); + + uint[] x1 = F.Create(); F.Decode(u, uOff, x1); + uint[] x2 = F.Create(); F.Copy(x1, 0, x2, 0); + uint[] z2 = F.Create(); z2[0] = 1; + uint[] x3 = F.Create(); x3[0] = 1; + uint[] z3 = F.Create(); + + uint[] t1 = F.Create(); + uint[] t2 = F.Create(); + + Debug.Assert(n[13] >> 31 == 1U); + + int bit = 447, swap = 1; + do + { + //F.Apm(x3, z3, t1, x3); + F.Add(x3, z3, t1); + F.Sub(x3, z3, x3); + //F.Apm(x2, z2, z3, x2); + F.Add(x2, z2, z3); + F.Sub(x2, z2, x2); + + F.Mul(t1, x2, t1); + F.Mul(x3, z3, x3); + F.Sqr(z3, z3); + F.Sqr(x2, x2); + + F.Sub(z3, x2, t2); + F.Mul(t2, C_A24, z2); + F.Add(z2, x2, z2); + F.Mul(z2, t2, z2); + F.Mul(x2, z3, x2); + + //F.Apm(t1, x3, x3, z3); + F.Sub(t1, x3, z3); + F.Add(t1, x3, x3); + F.Sqr(x3, x3); + F.Sqr(z3, z3); + F.Mul(z3, x1, z3); + + --bit; + + int word = bit >> 5, shift = bit & 0x1F; + int kt = (int)(n[word] >> shift) & 1; + swap ^= kt; + F.CSwap(swap, x2, x3); + F.CSwap(swap, z2, z3); + swap = kt; + } + while (bit >= 2); + + Debug.Assert(swap == 0); + + for (int i = 0; i < 2; ++i) + { + PointDouble(x2, z2); + } + + F.Inv(z2, z2); + F.Mul(x2, z2, x2); + + F.Normalize(x2); + F.Encode(x2, r, rOff); + } + + public static void ScalarMultBase(byte[] k, int kOff, byte[] r, int rOff) + { + uint[] x = F.Create(); + uint[] y = F.Create(); + + Ed448.ScalarMultBaseXY(k, kOff, x, y); + + F.Inv(x, x); + F.Mul(x, y, x); + F.Sqr(x, x); + + F.Normalize(x); + F.Encode(x, r, rOff); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/rfc7748/X448.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/rfc7748/X448.cs.meta new file mode 100644 index 0000000..b682ab9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/rfc7748/X448.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 84638d63eed178c419581b19b84746bf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/rfc7748/X448Field.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/rfc7748/X448Field.cs new file mode 100644 index 0000000..6d8c60e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/rfc7748/X448Field.cs @@ -0,0 +1,1144 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Math.EC.Rfc7748 +{ + [CLSCompliantAttribute(false)] + public abstract class X448Field + { + public const int Size = 16; + + private const uint M28 = 0x0FFFFFFFU; + + private static readonly uint[] P32 = new uint[]{ 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFEU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0xFFFFFFFFU }; + + protected X448Field() {} + + public static void Add(uint[] x, uint[] y, uint[] z) + { + for (int i = 0; i < Size; ++i) + { + z[i] = x[i] + y[i]; + } + } + + public static void AddOne(uint[] z) + { + z[0] += 1; + } + + public static void AddOne(uint[] z, int zOff) + { + z[zOff] += 1; + } + + //public static void Apm(int[] x, int[] y, int[] zp, int[] zm) + //{ + // for (int i = 0; i < Size; ++i) + // { + // int xi = x[i], yi = y[i]; + // zp[i] = xi + yi; + // zm[i] = xi - yi; + // } + //} + + public static int AreEqual(uint[] x, uint[] y) + { + uint d = 0; + for (int i = 0; i < Size; ++i) + { + d |= x[i] ^ y[i]; + } + d |= d >> 16; + d &= 0xFFFF; + return ((int)d - 1) >> 31; + } + + public static bool AreEqualVar(uint[] x, uint[] y) + { + return 0 != AreEqual(x, y); + } + + public static void Carry(uint[] z) + { + uint z0 = z[0], z1 = z[1], z2 = z[2], z3 = z[3], z4 = z[4], z5 = z[5], z6 = z[6], z7 = z[7]; + uint z8 = z[8], z9 = z[9], z10 = z[10], z11 = z[11], z12 = z[12], z13 = z[13], z14 = z[14], z15 = z[15]; + + z1 += (z0 >> 28); z0 &= M28; + z5 += (z4 >> 28); z4 &= M28; + z9 += (z8 >> 28); z8 &= M28; + z13 += (z12 >> 28); z12 &= M28; + + z2 += (z1 >> 28); z1 &= M28; + z6 += (z5 >> 28); z5 &= M28; + z10 += (z9 >> 28); z9 &= M28; + z14 += (z13 >> 28); z13 &= M28; + + z3 += (z2 >> 28); z2 &= M28; + z7 += (z6 >> 28); z6 &= M28; + z11 += (z10 >> 28); z10 &= M28; + z15 += (z14 >> 28); z14 &= M28; + + uint t = z15 >> 28; z15 &= M28; + z0 += t; + z8 += t; + + z4 += (z3 >> 28); z3 &= M28; + z8 += (z7 >> 28); z7 &= M28; + z12 += (z11 >> 28); z11 &= M28; + + z1 += (z0 >> 28); z0 &= M28; + z5 += (z4 >> 28); z4 &= M28; + z9 += (z8 >> 28); z8 &= M28; + z13 += (z12 >> 28); z12 &= M28; + + z[0] = z0; z[1] = z1; z[2] = z2; z[3] = z3; z[4] = z4; z[5] = z5; z[6] = z6; z[7] = z7; + z[8] = z8; z[9] = z9; z[10] = z10; z[11] = z11; z[12] = z12; z[13] = z13; z[14] = z14; z[15] = z15; + } + + public static void CMov(int cond, uint[] x, int xOff, uint[] z, int zOff) + { + Debug.Assert(0 == cond || -1 == cond); + + uint MASK = (uint)cond; + + for (int i = 0; i < Size; ++i) + { + uint z_i = z[zOff + i], diff = z_i ^ x[xOff + i]; + z_i ^= (diff & MASK); + z[zOff + i] = z_i; + } + } + + public static void CNegate(int negate, uint[] z) + { + Debug.Assert(negate >> 1 == 0); + + uint[] t = Create(); + Sub(t, z, t); + + CMov(-negate, t, 0, z, 0); + } + + public static void Copy(uint[] x, int xOff, uint[] z, int zOff) + { + for (int i = 0; i < Size; ++i) + { + z[zOff + i] = x[xOff + i]; + } + } + + public static uint[] Create() + { + return new uint[Size]; + } + + public static uint[] CreateTable(int n) + { + return new uint[Size * n]; + } + + public static void CSwap(int swap, uint[] a, uint[] b) + { + Debug.Assert(swap >> 1 == 0); + Debug.Assert(a != b); + + uint mask = (uint)(0 - swap); + for (int i = 0; i < Size; ++i) + { + uint ai = a[i], bi = b[i]; + uint dummy = mask & (ai ^ bi); + a[i] = ai ^ dummy; + b[i] = bi ^ dummy; + } + } + + public static void Decode(uint[] x, int xOff, uint[] z) + { + Decode224(x, xOff, z, 0); + Decode224(x, xOff + 7, z, 8); + } + + public static void Decode(byte[] x, int xOff, uint[] z) + { + Decode56(x, xOff, z, 0); + Decode56(x, xOff + 7, z, 2); + Decode56(x, xOff + 14, z, 4); + Decode56(x, xOff + 21, z, 6); + Decode56(x, xOff + 28, z, 8); + Decode56(x, xOff + 35, z, 10); + Decode56(x, xOff + 42, z, 12); + Decode56(x, xOff + 49, z, 14); + } + + private static void Decode224(uint[] x, int xOff, uint[] z, int zOff) + { + uint x0 = x[xOff + 0], x1 = x[xOff + 1], x2 = x[xOff + 2], x3 = x[xOff + 3]; + uint x4 = x[xOff + 4], x5 = x[xOff + 5], x6 = x[xOff + 6]; + + z[zOff + 0] = x0 & M28; + z[zOff + 1] = (x0 >> 28 | x1 << 4) & M28; + z[zOff + 2] = (x1 >> 24 | x2 << 8) & M28; + z[zOff + 3] = (x2 >> 20 | x3 << 12) & M28; + z[zOff + 4] = (x3 >> 16 | x4 << 16) & M28; + z[zOff + 5] = (x4 >> 12 | x5 << 20) & M28; + z[zOff + 6] = (x5 >> 8 | x6 << 24) & M28; + z[zOff + 7] = x6 >> 4; + } + + private static uint Decode24(byte[] bs, int off) + { + uint n = bs[off]; + n |= (uint)bs[++off] << 8; + n |= (uint)bs[++off] << 16; + return n; + } + + private static uint Decode32(byte[] bs, int off) + { + uint n = bs[off]; + n |= (uint)bs[++off] << 8; + n |= (uint)bs[++off] << 16; + n |= (uint)bs[++off] << 24; + return n; + } + + private static void Decode56(byte[] bs, int off, uint[] z, int zOff) + { + uint lo = Decode32(bs, off); + uint hi = Decode24(bs, off + 4); + z[zOff] = lo & M28; + z[zOff + 1] = (lo >> 28) | (hi << 4); + } + + public static void Encode(uint[] x, uint[] z, int zOff) + { + Encode224(x, 0, z, zOff); + Encode224(x, 8, z, zOff + 7); + } + + public static void Encode(uint[] x, byte[] z, int zOff) + { + Encode56(x, 0, z, zOff); + Encode56(x, 2, z, zOff + 7); + Encode56(x, 4, z, zOff + 14); + Encode56(x, 6, z, zOff + 21); + Encode56(x, 8, z, zOff + 28); + Encode56(x, 10, z, zOff + 35); + Encode56(x, 12, z, zOff + 42); + Encode56(x, 14, z, zOff + 49); + } + + private static void Encode224(uint[] x, int xOff, uint[] z, int zOff) + { + uint x0 = x[xOff + 0], x1 = x[xOff + 1], x2 = x[xOff + 2], x3 = x[xOff + 3]; + uint x4 = x[xOff + 4], x5 = x[xOff + 5], x6 = x[xOff + 6], x7 = x[xOff + 7]; + + z[zOff + 0] = x0 | (x1 << 28); + z[zOff + 1] = (x1 >> 4) | (x2 << 24); + z[zOff + 2] = (x2 >> 8) | (x3 << 20); + z[zOff + 3] = (x3 >> 12) | (x4 << 16); + z[zOff + 4] = (x4 >> 16) | (x5 << 12); + z[zOff + 5] = (x5 >> 20) | (x6 << 8); + z[zOff + 6] = (x6 >> 24) | (x7 << 4); + } + + private static void Encode24(uint n, byte[] bs, int off) + { + bs[ off] = (byte)(n ); + bs[++off] = (byte)(n >> 8); + bs[++off] = (byte)(n >> 16); + } + + private static void Encode32(uint n, byte[] bs, int off) + { + bs[ off] = (byte)(n ); + bs[++off] = (byte)(n >> 8); + bs[++off] = (byte)(n >> 16); + bs[++off] = (byte)(n >> 24); + } + + private static void Encode56(uint[] x, int xOff, byte[] bs, int off) + { + uint lo = x[xOff], hi = x[xOff + 1]; + Encode32(lo | (hi << 28), bs, off); + Encode24(hi >> 4, bs, off + 4); + } + + public static void Inv(uint[] x, uint[] z) + { + //uint[] t = Create(); + //PowPm3d4(x, t); + //Sqr(t, 2, t); + //Mul(t, x, z); + + uint[] t = Create(); + uint[] u = new uint[14]; + + Copy(x, 0, t, 0); + Normalize(t); + Encode(t, u, 0); + + Mod.ModOddInverse(P32, u, u); + + Decode(u, 0, z); + } + + public static void InvVar(uint[] x, uint[] z) + { + uint[] t = Create(); + uint[] u = new uint[14]; + + Copy(x, 0, t, 0); + Normalize(t); + Encode(t, u, 0); + + Mod.ModOddInverseVar(P32, u, u); + + Decode(u, 0, z); + } + + public static int IsOne(uint[] x) + { + uint d = x[0] ^ 1; + for (int i = 1; i < Size; ++i) + { + d |= x[i]; + } + d |= d >> 16; + d &= 0xFFFF; + return ((int)d - 1) >> 31; + } + + public static bool IsOneVar(uint[] x) + { + return 0 != IsOne(x); + } + + public static int IsZero(uint[] x) + { + uint d = 0; + for (int i = 0; i < Size; ++i) + { + d |= x[i]; + } + d |= d >> 16; + d &= 0xFFFF; + return ((int)d - 1) >> 31; + } + + public static bool IsZeroVar(uint[] x) + { + return 0U != IsZero(x); + } + + public static void Mul(uint[] x, uint y, uint[] z) + { + uint x0 = x[0], x1 = x[1], x2 = x[2], x3 = x[3], x4 = x[4], x5 = x[5], x6 = x[6], x7 = x[7]; + uint x8 = x[8], x9 = x[9], x10 = x[10], x11 = x[11], x12 = x[12], x13 = x[13], x14 = x[14], x15 = x[15]; + + uint z1, z5, z9, z13; + ulong c, d, e, f; + + c = (ulong)x1 * y; + z1 = (uint)c & M28; c >>= 28; + d = (ulong)x5 * y; + z5 = (uint)d & M28; d >>= 28; + e = (ulong)x9 * y; + z9 = (uint)e & M28; e >>= 28; + f = (ulong)x13 * y; + z13 = (uint)f & M28; f >>= 28; + + c += (ulong)x2 * y; + z[2] = (uint)c & M28; c >>= 28; + d += (ulong)x6 * y; + z[6] = (uint)d & M28; d >>= 28; + e += (ulong)x10 * y; + z[10] = (uint)e & M28; e >>= 28; + f += (ulong)x14 * y; + z[14] = (uint)f & M28; f >>= 28; + + c += (ulong)x3 * y; + z[3] = (uint)c & M28; c >>= 28; + d += (ulong)x7 * y; + z[7] = (uint)d & M28; d >>= 28; + e += (ulong)x11 * y; + z[11] = (uint)e & M28; e >>= 28; + f += (ulong)x15 * y; + z[15] = (uint)f & M28; f >>= 28; + + d += f; + + c += (ulong)x4 * y; + z[4] = (uint)c & M28; c >>= 28; + d += (ulong)x8 * y; + z[8] = (uint)d & M28; d >>= 28; + e += (ulong)x12 * y; + z[12] = (uint)e & M28; e >>= 28; + f += (ulong)x0 * y; + z[0] = (uint)f & M28; f >>= 28; + + z[1] = z1 + (uint)f; + z[5] = z5 + (uint)c; + z[9] = z9 + (uint)d; + z[13] = z13 + (uint)e; + } + + public static void Mul(uint[] x, uint[] y, uint[] z) + { + uint x0 = x[0]; + uint x1 = x[1]; + uint x2 = x[2]; + uint x3 = x[3]; + uint x4 = x[4]; + uint x5 = x[5]; + uint x6 = x[6]; + uint x7 = x[7]; + + uint u0 = x[8]; + uint u1 = x[9]; + uint u2 = x[10]; + uint u3 = x[11]; + uint u4 = x[12]; + uint u5 = x[13]; + uint u6 = x[14]; + uint u7 = x[15]; + + uint y0 = y[0]; + uint y1 = y[1]; + uint y2 = y[2]; + uint y3 = y[3]; + uint y4 = y[4]; + uint y5 = y[5]; + uint y6 = y[6]; + uint y7 = y[7]; + + uint v0 = y[8]; + uint v1 = y[9]; + uint v2 = y[10]; + uint v3 = y[11]; + uint v4 = y[12]; + uint v5 = y[13]; + uint v6 = y[14]; + uint v7 = y[15]; + + uint s0 = x0 + u0; + uint s1 = x1 + u1; + uint s2 = x2 + u2; + uint s3 = x3 + u3; + uint s4 = x4 + u4; + uint s5 = x5 + u5; + uint s6 = x6 + u6; + uint s7 = x7 + u7; + + uint t0 = y0 + v0; + uint t1 = y1 + v1; + uint t2 = y2 + v2; + uint t3 = y3 + v3; + uint t4 = y4 + v4; + uint t5 = y5 + v5; + uint t6 = y6 + v6; + uint t7 = y7 + v7; + + uint z0, z1, z2, z3, z4, z5, z6, z7, z8, z9, z10, z11, z12, z13, z14, z15; + ulong c, d; + + ulong f0 = (ulong)x0 * y0; + ulong f8 = (ulong)x7 * y1 + + (ulong)x6 * y2 + + (ulong)x5 * y3 + + (ulong)x4 * y4 + + (ulong)x3 * y5 + + (ulong)x2 * y6 + + (ulong)x1 * y7; + ulong g0 = (ulong)u0 * v0; + ulong g8 = (ulong)u7 * v1 + + (ulong)u6 * v2 + + (ulong)u5 * v3 + + (ulong)u4 * v4 + + (ulong)u3 * v5 + + (ulong)u2 * v6 + + (ulong)u1 * v7; + ulong h0 = (ulong)s0 * t0; + ulong h8 = (ulong)s7 * t1 + + (ulong)s6 * t2 + + (ulong)s5 * t3 + + (ulong)s4 * t4 + + (ulong)s3 * t5 + + (ulong)s2 * t6 + + (ulong)s1 * t7; + + c = f0 + g0 + h8 - f8; + z0 = (uint)c & M28; c >>= 28; + d = g8 + h0 - f0 + h8; + z8 = (uint)d & M28; d >>= 28; + + ulong f1 = (ulong)x1 * y0 + + (ulong)x0 * y1; + ulong f9 = (ulong)x7 * y2 + + (ulong)x6 * y3 + + (ulong)x5 * y4 + + (ulong)x4 * y5 + + (ulong)x3 * y6 + + (ulong)x2 * y7; + ulong g1 = (ulong)u1 * v0 + + (ulong)u0 * v1; + ulong g9 = (ulong)u7 * v2 + + (ulong)u6 * v3 + + (ulong)u5 * v4 + + (ulong)u4 * v5 + + (ulong)u3 * v6 + + (ulong)u2 * v7; + ulong h1 = (ulong)s1 * t0 + + (ulong)s0 * t1; + ulong h9 = (ulong)s7 * t2 + + (ulong)s6 * t3 + + (ulong)s5 * t4 + + (ulong)s4 * t5 + + (ulong)s3 * t6 + + (ulong)s2 * t7; + + c += f1 + g1 + h9 - f9; + z1 = (uint)c & M28; c >>= 28; + d += g9 + h1 - f1 + h9; + z9 = (uint)d & M28; d >>= 28; + + ulong f2 = (ulong)x2 * y0 + + (ulong)x1 * y1 + + (ulong)x0 * y2; + ulong f10 = (ulong)x7 * y3 + + (ulong)x6 * y4 + + (ulong)x5 * y5 + + (ulong)x4 * y6 + + (ulong)x3 * y7; + ulong g2 = (ulong)u2 * v0 + + (ulong)u1 * v1 + + (ulong)u0 * v2; + ulong g10 = (ulong)u7 * v3 + + (ulong)u6 * v4 + + (ulong)u5 * v5 + + (ulong)u4 * v6 + + (ulong)u3 * v7; + ulong h2 = (ulong)s2 * t0 + + (ulong)s1 * t1 + + (ulong)s0 * t2; + ulong h10 = (ulong)s7 * t3 + + (ulong)s6 * t4 + + (ulong)s5 * t5 + + (ulong)s4 * t6 + + (ulong)s3 * t7; + + c += f2 + g2 + h10 - f10; + z2 = (uint)c & M28; c >>= 28; + d += g10 + h2 - f2 + h10; + z10 = (uint)d & M28; d >>= 28; + + ulong f3 = (ulong)x3 * y0 + + (ulong)x2 * y1 + + (ulong)x1 * y2 + + (ulong)x0 * y3; + ulong f11 = (ulong)x7 * y4 + + (ulong)x6 * y5 + + (ulong)x5 * y6 + + (ulong)x4 * y7; + ulong g3 = (ulong)u3 * v0 + + (ulong)u2 * v1 + + (ulong)u1 * v2 + + (ulong)u0 * v3; + ulong g11 = (ulong)u7 * v4 + + (ulong)u6 * v5 + + (ulong)u5 * v6 + + (ulong)u4 * v7; + ulong h3 = (ulong)s3 * t0 + + (ulong)s2 * t1 + + (ulong)s1 * t2 + + (ulong)s0 * t3; + ulong h11 = (ulong)s7 * t4 + + (ulong)s6 * t5 + + (ulong)s5 * t6 + + (ulong)s4 * t7; + + c += f3 + g3 + h11 - f11; + z3 = (uint)c & M28; c >>= 28; + d += g11 + h3 - f3 + h11; + z11 = (uint)d & M28; d >>= 28; + + ulong f4 = (ulong)x4 * y0 + + (ulong)x3 * y1 + + (ulong)x2 * y2 + + (ulong)x1 * y3 + + (ulong)x0 * y4; + ulong f12 = (ulong)x7 * y5 + + (ulong)x6 * y6 + + (ulong)x5 * y7; + ulong g4 = (ulong)u4 * v0 + + (ulong)u3 * v1 + + (ulong)u2 * v2 + + (ulong)u1 * v3 + + (ulong)u0 * v4; + ulong g12 = (ulong)u7 * v5 + + (ulong)u6 * v6 + + (ulong)u5 * v7; + ulong h4 = (ulong)s4 * t0 + + (ulong)s3 * t1 + + (ulong)s2 * t2 + + (ulong)s1 * t3 + + (ulong)s0 * t4; + ulong h12 = (ulong)s7 * t5 + + (ulong)s6 * t6 + + (ulong)s5 * t7; + + c += f4 + g4 + h12 - f12; + z4 = (uint)c & M28; c >>= 28; + d += g12 + h4 - f4 + h12; + z12 = (uint)d & M28; d >>= 28; + + ulong f5 = (ulong)x5 * y0 + + (ulong)x4 * y1 + + (ulong)x3 * y2 + + (ulong)x2 * y3 + + (ulong)x1 * y4 + + (ulong)x0 * y5; + ulong f13 = (ulong)x7 * y6 + + (ulong)x6 * y7; + ulong g5 = (ulong)u5 * v0 + + (ulong)u4 * v1 + + (ulong)u3 * v2 + + (ulong)u2 * v3 + + (ulong)u1 * v4 + + (ulong)u0 * v5; + ulong g13 = (ulong)u7 * v6 + + (ulong)u6 * v7; + ulong h5 = (ulong)s5 * t0 + + (ulong)s4 * t1 + + (ulong)s3 * t2 + + (ulong)s2 * t3 + + (ulong)s1 * t4 + + (ulong)s0 * t5; + ulong h13 = (ulong)s7 * t6 + + (ulong)s6 * t7; + + c += f5 + g5 + h13 - f13; + z5 = (uint)c & M28; c >>= 28; + d += g13 + h5 - f5 + h13; + z13 = (uint)d & M28; d >>= 28; + + ulong f6 = (ulong)x6 * y0 + + (ulong)x5 * y1 + + (ulong)x4 * y2 + + (ulong)x3 * y3 + + (ulong)x2 * y4 + + (ulong)x1 * y5 + + (ulong)x0 * y6; + ulong f14 = (ulong)x7 * y7; + ulong g6 = (ulong)u6 * v0 + + (ulong)u5 * v1 + + (ulong)u4 * v2 + + (ulong)u3 * v3 + + (ulong)u2 * v4 + + (ulong)u1 * v5 + + (ulong)u0 * v6; + ulong g14 = (ulong)u7 * v7; + ulong h6 = (ulong)s6 * t0 + + (ulong)s5 * t1 + + (ulong)s4 * t2 + + (ulong)s3 * t3 + + (ulong)s2 * t4 + + (ulong)s1 * t5 + + (ulong)s0 * t6; + ulong h14 = (ulong)s7 * t7; + + c += f6 + g6 + h14 - f14; + z6 = (uint)c & M28; c >>= 28; + d += g14 + h6 - f6 + h14; + z14 = (uint)d & M28; d >>= 28; + + ulong f7 = (ulong)x7 * y0 + + (ulong)x6 * y1 + + (ulong)x5 * y2 + + (ulong)x4 * y3 + + (ulong)x3 * y4 + + (ulong)x2 * y5 + + (ulong)x1 * y6 + + (ulong)x0 * y7; + ulong g7 = (ulong)u7 * v0 + + (ulong)u6 * v1 + + (ulong)u5 * v2 + + (ulong)u4 * v3 + + (ulong)u3 * v4 + + (ulong)u2 * v5 + + (ulong)u1 * v6 + + (ulong)u0 * v7; + ulong h7 = (ulong)s7 * t0 + + (ulong)s6 * t1 + + (ulong)s5 * t2 + + (ulong)s4 * t3 + + (ulong)s3 * t4 + + (ulong)s2 * t5 + + (ulong)s1 * t6 + + (ulong)s0 * t7; + + c += f7 + g7; + z7 = (uint)c & M28; c >>= 28; + d += h7 - f7; + z15 = (uint)d & M28; d >>= 28; + + c += d; + + c += z8; + z8 = (uint)c & M28; c >>= 28; + d += z0; + z0 = (uint)d & M28; d >>= 28; + z9 += (uint)c; + z1 += (uint)d; + + z[0] = z0; + z[1] = z1; + z[2] = z2; + z[3] = z3; + z[4] = z4; + z[5] = z5; + z[6] = z6; + z[7] = z7; + z[8] = z8; + z[9] = z9; + z[10] = z10; + z[11] = z11; + z[12] = z12; + z[13] = z13; + z[14] = z14; + z[15] = z15; + } + + public static void Negate(uint[] x, uint[] z) + { + uint[] zero = Create(); + Sub(zero, x, z); + } + + public static void Normalize(uint[] z) + { + //int x = (z[15] >> (28 - 1)) & 1; + Reduce(z, 1); + Reduce(z, -1); + Debug.Assert(z[15] >> 28 == 0U); + } + + public static void One(uint[] z) + { + z[0] = 1U; + for (int i = 1; i < Size; ++i) + { + z[i] = 0; + } + } + + private static void PowPm3d4(uint[] x, uint[] z) + { + // z = x^((p-3)/4) = x^(2^446 - 2^222 - 1) + // (223 1s) (1 0s) (222 1s) + // Addition chain: 1 2 3 6 9 18 19 37 74 111 [222] [223] + uint[] x2 = Create(); Sqr(x, x2); Mul(x, x2, x2); + uint[] x3 = Create(); Sqr(x2, x3); Mul(x, x3, x3); + uint[] x6 = Create(); Sqr(x3, 3, x6); Mul(x3, x6, x6); + uint[] x9 = Create(); Sqr(x6, 3, x9); Mul(x3, x9, x9); + uint[] x18 = Create(); Sqr(x9, 9, x18); Mul(x9, x18, x18); + uint[] x19 = Create(); Sqr(x18, x19); Mul(x, x19, x19); + uint[] x37 = Create(); Sqr(x19, 18, x37); Mul(x18, x37, x37); + uint[] x74 = Create(); Sqr(x37, 37, x74); Mul(x37, x74, x74); + uint[] x111 = Create(); Sqr(x74, 37, x111); Mul(x37, x111, x111); + uint[] x222 = Create(); Sqr(x111, 111, x222); Mul(x111, x222, x222); + uint[] x223 = Create(); Sqr(x222, x223); Mul(x, x223, x223); + + uint[] t = Create(); + Sqr(x223, 223, t); + Mul(t, x222, z); + } + + private static void Reduce(uint[] z, int x) + { + uint u = z[15], z15 = u & M28; + int t = (int)(u >> 28) + x; + + long cc = t; + for (int i = 0; i < 8; ++i) + { + cc += z[i]; z[i] = (uint)cc & M28; cc >>= 28; + } + cc += t; + for (int i = 8; i < 15; ++i) + { + cc += z[i]; z[i] = (uint)cc & M28; cc >>= 28; + } + z[15] = z15 + (uint)cc; + } + + public static void Sqr(uint[] x, uint[] z) + { + uint x0 = x[0]; + uint x1 = x[1]; + uint x2 = x[2]; + uint x3 = x[3]; + uint x4 = x[4]; + uint x5 = x[5]; + uint x6 = x[6]; + uint x7 = x[7]; + + uint u0 = x[8]; + uint u1 = x[9]; + uint u2 = x[10]; + uint u3 = x[11]; + uint u4 = x[12]; + uint u5 = x[13]; + uint u6 = x[14]; + uint u7 = x[15]; + + uint x0_2 = x0 * 2; + uint x1_2 = x1 * 2; + uint x2_2 = x2 * 2; + uint x3_2 = x3 * 2; + uint x4_2 = x4 * 2; + uint x5_2 = x5 * 2; + uint x6_2 = x6 * 2; + + uint u0_2 = u0 * 2; + uint u1_2 = u1 * 2; + uint u2_2 = u2 * 2; + uint u3_2 = u3 * 2; + uint u4_2 = u4 * 2; + uint u5_2 = u5 * 2; + uint u6_2 = u6 * 2; + + uint s0 = x0 + u0; + uint s1 = x1 + u1; + uint s2 = x2 + u2; + uint s3 = x3 + u3; + uint s4 = x4 + u4; + uint s5 = x5 + u5; + uint s6 = x6 + u6; + uint s7 = x7 + u7; + + uint s0_2 = s0 * 2; + uint s1_2 = s1 * 2; + uint s2_2 = s2 * 2; + uint s3_2 = s3 * 2; + uint s4_2 = s4 * 2; + uint s5_2 = s5 * 2; + uint s6_2 = s6 * 2; + + uint z0, z1, z2, z3, z4, z5, z6, z7, z8, z9, z10, z11, z12, z13, z14, z15; + ulong c, d; + + ulong f0 = (ulong)x0 * x0; + ulong f8 = (ulong)x7 * x1_2 + + (ulong)x6 * x2_2 + + (ulong)x5 * x3_2 + + (ulong)x4 * x4; + ulong g0 = (ulong)u0 * u0; + ulong g8 = (ulong)u7 * u1_2 + + (ulong)u6 * u2_2 + + (ulong)u5 * u3_2 + + (ulong)u4 * u4; + ulong h0 = (ulong)s0 * s0; + ulong h8 = (ulong)s7 * s1_2 + + (ulong)s6 * s2_2 + + (ulong)s5 * s3_2 + + (ulong)s4 * s4; + + c = f0 + g0 + h8 - f8; + z0 = (uint)c & M28; c >>= 28; + d = g8 + h0 - f0 + h8; + z8 = (uint)d & M28; d >>= 28; + + ulong f1 = (ulong)x1 * x0_2; + ulong f9 = (ulong)x7 * x2_2 + + (ulong)x6 * x3_2 + + (ulong)x5 * x4_2; + ulong g1 = (ulong)u1 * u0_2; + ulong g9 = (ulong)u7 * u2_2 + + (ulong)u6 * u3_2 + + (ulong)u5 * u4_2; + ulong h1 = (ulong)s1 * s0_2; + ulong h9 = (ulong)s7 * s2_2 + + (ulong)s6 * s3_2 + + (ulong)s5 * s4_2; + + c += f1 + g1 + h9 - f9; + z1 = (uint)c & M28; c >>= 28; + d += g9 + h1 - f1 + h9; + z9 = (uint)d & M28; d >>= 28; + + ulong f2 = (ulong)x2 * x0_2 + + (ulong)x1 * x1; + ulong f10 = (ulong)x7 * x3_2 + + (ulong)x6 * x4_2 + + (ulong)x5 * x5; + ulong g2 = (ulong)u2 * u0_2 + + (ulong)u1 * u1; + ulong g10 = (ulong)u7 * u3_2 + + (ulong)u6 * u4_2 + + (ulong)u5 * u5; + ulong h2 = (ulong)s2 * s0_2 + + (ulong)s1 * s1; + ulong h10 = (ulong)s7 * s3_2 + + (ulong)s6 * s4_2 + + (ulong)s5 * s5; + + c += f2 + g2 + h10 - f10; + z2 = (uint)c & M28; c >>= 28; + d += g10 + h2 - f2 + h10; + z10 = (uint)d & M28; d >>= 28; + + ulong f3 = (ulong)x3 * x0_2 + + (ulong)x2 * x1_2; + ulong f11 = (ulong)x7 * x4_2 + + (ulong)x6 * x5_2; + ulong g3 = (ulong)u3 * u0_2 + + (ulong)u2 * u1_2; + ulong g11 = (ulong)u7 * u4_2 + + (ulong)u6 * u5_2; + ulong h3 = (ulong)s3 * s0_2 + + (ulong)s2 * s1_2; + ulong h11 = (ulong)s7 * s4_2 + + (ulong)s6 * s5_2; + + c += f3 + g3 + h11 - f11; + z3 = (uint)c & M28; c >>= 28; + d += g11 + h3 - f3 + h11; + z11 = (uint)d & M28; d >>= 28; + + ulong f4 = (ulong)x4 * x0_2 + + (ulong)x3 * x1_2 + + (ulong)x2 * x2; + ulong f12 = (ulong)x7 * x5_2 + + (ulong)x6 * x6; + ulong g4 = (ulong)u4 * u0_2 + + (ulong)u3 * u1_2 + + (ulong)u2 * u2; + ulong g12 = (ulong)u7 * u5_2 + + (ulong)u6 * u6; + ulong h4 = (ulong)s4 * s0_2 + + (ulong)s3 * s1_2 + + (ulong)s2 * s2; + ulong h12 = (ulong)s7 * s5_2 + + (ulong)s6 * s6; + + c += f4 + g4 + h12 - f12; + z4 = (uint)c & M28; c >>= 28; + d += g12 + h4 - f4 + h12; + z12 = (uint)d & M28; d >>= 28; + + ulong f5 = (ulong)x5 * x0_2 + + (ulong)x4 * x1_2 + + (ulong)x3 * x2_2; + ulong f13 = (ulong)x7 * x6_2; + ulong g5 = (ulong)u5 * u0_2 + + (ulong)u4 * u1_2 + + (ulong)u3 * u2_2; + ulong g13 = (ulong)u7 * u6_2; + ulong h5 = (ulong)s5 * s0_2 + + (ulong)s4 * s1_2 + + (ulong)s3 * s2_2; + ulong h13 = (ulong)s7 * s6_2; + + c += f5 + g5 + h13 - f13; + z5 = (uint)c & M28; c >>= 28; + d += g13 + h5 - f5 + h13; + z13 = (uint)d & M28; d >>= 28; + + ulong f6 = (ulong)x6 * x0_2 + + (ulong)x5 * x1_2 + + (ulong)x4 * x2_2 + + (ulong)x3 * x3; + ulong f14 = (ulong)x7 * x7; + ulong g6 = (ulong)u6 * u0_2 + + (ulong)u5 * u1_2 + + (ulong)u4 * u2_2 + + (ulong)u3 * u3; + ulong g14 = (ulong)u7 * u7; + ulong h6 = (ulong)s6 * s0_2 + + (ulong)s5 * s1_2 + + (ulong)s4 * s2_2 + + (ulong)s3 * s3; + ulong h14 = (ulong)s7 * s7; + + c += f6 + g6 + h14 - f14; + z6 = (uint)c & M28; c >>= 28; + d += g14 + h6 - f6 + h14; + z14 = (uint)d & M28; d >>= 28; + + ulong f7 = (ulong)x7 * x0_2 + + (ulong)x6 * x1_2 + + (ulong)x5 * x2_2 + + (ulong)x4 * x3_2; + ulong g7 = (ulong)u7 * u0_2 + + (ulong)u6 * u1_2 + + (ulong)u5 * u2_2 + + (ulong)u4 * u3_2; + ulong h7 = (ulong)s7 * s0_2 + + (ulong)s6 * s1_2 + + (ulong)s5 * s2_2 + + (ulong)s4 * s3_2; + + c += f7 + g7; + z7 = (uint)c & M28; c >>= 28; + d += h7 - f7; + z15 = (uint)d & M28; d >>= 28; + + c += d; + + c += z8; + z8 = (uint)c & M28; c >>= 28; + d += z0; + z0 = (uint)d & M28; d >>= 28; + z9 += (uint)c; + z1 += (uint)d; + + z[0] = z0; + z[1] = z1; + z[2] = z2; + z[3] = z3; + z[4] = z4; + z[5] = z5; + z[6] = z6; + z[7] = z7; + z[8] = z8; + z[9] = z9; + z[10] = z10; + z[11] = z11; + z[12] = z12; + z[13] = z13; + z[14] = z14; + z[15] = z15; + } + + public static void Sqr(uint[] x, int n, uint[] z) + { + Debug.Assert(n > 0); + + Sqr(x, z); + + while (--n > 0) + { + Sqr(z, z); + } + } + + public static bool SqrtRatioVar(uint[] u, uint[] v, uint[] z) + { + uint[] u3v = Create(); + uint[] u5v3 = Create(); + + Sqr(u, u3v); + Mul(u3v, v, u3v); + Sqr(u3v, u5v3); + Mul(u3v, u, u3v); + Mul(u5v3, u, u5v3); + Mul(u5v3, v, u5v3); + + uint[] x = Create(); + PowPm3d4(u5v3, x); + Mul(x, u3v, x); + + uint[] t = Create(); + Sqr(x, t); + Mul(t, v, t); + + Sub(u, t, t); + Normalize(t); + + if (IsZeroVar(t)) + { + Copy(x, 0, z, 0); + return true; + } + + return false; + } + + public static void Sub(uint[] x, uint[] y, uint[] z) + { + uint x0 = x[0], x1 = x[1], x2 = x[2], x3 = x[3], x4 = x[4], x5 = x[5], x6 = x[6], x7 = x[7]; + uint x8 = x[8], x9 = x[9], x10 = x[10], x11 = x[11], x12 = x[12], x13 = x[13], x14 = x[14], x15 = x[15]; + uint y0 = y[0], y1 = y[1], y2 = y[2], y3 = y[3], y4 = y[4], y5 = y[5], y6 = y[6], y7 = y[7]; + uint y8 = y[8], y9 = y[9], y10 = y[10], y11 = y[11], y12 = y[12], y13 = y[13], y14 = y[14], y15 = y[15]; + + uint z0 = x0 + 0x1FFFFFFEU - y0; + uint z1 = x1 + 0x1FFFFFFEU - y1; + uint z2 = x2 + 0x1FFFFFFEU - y2; + uint z3 = x3 + 0x1FFFFFFEU - y3; + uint z4 = x4 + 0x1FFFFFFEU - y4; + uint z5 = x5 + 0x1FFFFFFEU - y5; + uint z6 = x6 + 0x1FFFFFFEU - y6; + uint z7 = x7 + 0x1FFFFFFEU - y7; + uint z8 = x8 + 0x1FFFFFFCU - y8; + uint z9 = x9 + 0x1FFFFFFEU - y9; + uint z10 = x10 + 0x1FFFFFFEU - y10; + uint z11 = x11 + 0x1FFFFFFEU - y11; + uint z12 = x12 + 0x1FFFFFFEU - y12; + uint z13 = x13 + 0x1FFFFFFEU - y13; + uint z14 = x14 + 0x1FFFFFFEU - y14; + uint z15 = x15 + 0x1FFFFFFEU - y15; + + z2 += z1 >> 28; z1 &= M28; + z6 += z5 >> 28; z5 &= M28; + z10 += z9 >> 28; z9 &= M28; + z14 += z13 >> 28; z13 &= M28; + + z3 += z2 >> 28; z2 &= M28; + z7 += z6 >> 28; z6 &= M28; + z11 += z10 >> 28; z10 &= M28; + z15 += z14 >> 28; z14 &= M28; + + uint t = z15 >> 28; z15 &= M28; + z0 += t; + z8 += t; + + z4 += z3 >> 28; z3 &= M28; + z8 += z7 >> 28; z7 &= M28; + z12 += z11 >> 28; z11 &= M28; + + z1 += z0 >> 28; z0 &= M28; + z5 += z4 >> 28; z4 &= M28; + z9 += z8 >> 28; z8 &= M28; + z13 += z12 >> 28; z12 &= M28; + + z[0] = z0; + z[1] = z1; + z[2] = z2; + z[3] = z3; + z[4] = z4; + z[5] = z5; + z[6] = z6; + z[7] = z7; + z[8] = z8; + z[9] = z9; + z[10] = z10; + z[11] = z11; + z[12] = z12; + z[13] = z13; + z[14] = z14; + z[15] = z15; + } + + public static void SubOne(uint[] z) + { + uint[] one = Create(); + one[0] = 1U; + + Sub(z, one, z); + } + + public static void Zero(uint[] z) + { + for (int i = 0; i < Size; ++i) + { + z[i] = 0; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/rfc7748/X448Field.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/rfc7748/X448Field.cs.meta new file mode 100644 index 0000000..57a99da --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/rfc7748/X448Field.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: da8c065858b5e88438f54b8cd48abfa1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/rfc8032.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/rfc8032.meta new file mode 100644 index 0000000..34876f7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/rfc8032.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 514147fdaf0808b4490ad66bb1c38823 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/rfc8032/Ed25519.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/rfc8032/Ed25519.cs new file mode 100644 index 0000000..8f87e3a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/rfc8032/Ed25519.cs @@ -0,0 +1,1444 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Math.EC.Rfc7748; +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math.EC.Rfc8032 +{ + public abstract class Ed25519 + { + // -x^2 + y^2 == 1 + 0x52036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978A3 * x^2 * y^2 + + public enum Algorithm + { + Ed25519 = 0, + Ed25519ctx = 1, + Ed25519ph = 2, + } + + private class F : X25519Field {}; + + private const long M08L = 0x000000FFL; + private const long M28L = 0x0FFFFFFFL; + private const long M32L = 0xFFFFFFFFL; + + private const int CoordUints = 8; + private const int PointBytes = CoordUints * 4; + private const int ScalarUints = 8; + private const int ScalarBytes = ScalarUints * 4; + + public static readonly int PrehashSize = 64; + public static readonly int PublicKeySize = PointBytes; + public static readonly int SecretKeySize = 32; + public static readonly int SignatureSize = PointBytes + ScalarBytes; + + // "SigEd25519 no Ed25519 collisions" + private static readonly byte[] Dom2Prefix = new byte[]{ 0x53, 0x69, 0x67, 0x45, 0x64, 0x32, 0x35, 0x35, 0x31, + 0x39, 0x20, 0x6e, 0x6f, 0x20, 0x45, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x20, 0x63, 0x6f, 0x6c, 0x6c, 0x69, + 0x73, 0x69, 0x6f, 0x6e, 0x73 }; + + private static readonly uint[] P = { 0xFFFFFFEDU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0x7FFFFFFFU }; + private static readonly uint[] L = { 0x5CF5D3EDU, 0x5812631AU, 0xA2F79CD6U, 0x14DEF9DEU, 0x00000000U, + 0x00000000U, 0x00000000U, 0x10000000U }; + + private const int L0 = unchecked((int)0xFCF5D3ED); // L0:26/-- + private const int L1 = 0x012631A6; // L1:24/22 + private const int L2 = 0x079CD658; // L2:27/-- + private const int L3 = unchecked((int)0xFF9DEA2F); // L3:23/-- + private const int L4 = 0x000014DF; // L4:12/11 + + private static readonly int[] B_x = { 0x0325D51A, 0x018B5823, 0x007B2C95, 0x0304A92D, 0x00D2598E, 0x01D6DC5C, + 0x01388C7F, 0x013FEC0A, 0x029E6B72, 0x0042D26D }; + private static readonly int[] B_y = { 0x02666658, 0x01999999, 0x00666666, 0x03333333, 0x00CCCCCC, 0x02666666, + 0x01999999, 0x00666666, 0x03333333, 0x00CCCCCC, }; + private static readonly int[] C_d = { 0x035978A3, 0x02D37284, 0x018AB75E, 0x026A0A0E, 0x0000E014, 0x0379E898, + 0x01D01E5D, 0x01E738CC, 0x03715B7F, 0x00A406D9 }; + private static readonly int[] C_d2 = { 0x02B2F159, 0x01A6E509, 0x01156EBD, 0x00D4141D, 0x0001C029, 0x02F3D130, + 0x03A03CBB, 0x01CE7198, 0x02E2B6FF, 0x00480DB3 }; + private static readonly int[] C_d4 = { 0x0165E2B2, 0x034DCA13, 0x002ADD7A, 0x01A8283B, 0x00038052, 0x01E7A260, + 0x03407977, 0x019CE331, 0x01C56DFF, 0x00901B67 }; + + private const int WnafWidthBase = 7; + + private const int PrecompBlocks = 8; + private const int PrecompTeeth = 4; + private const int PrecompSpacing = 8; + private const int PrecompPoints = 1 << (PrecompTeeth - 1); + private const int PrecompMask = PrecompPoints - 1; + + private static readonly object precompLock = new object(); + // TODO[ed25519] Convert to PointPrecomp + private static PointExt[] precompBaseTable = null; + private static int[] precompBase = null; + + private class PointAccum + { + internal int[] x = F.Create(); + internal int[] y = F.Create(); + internal int[] z = F.Create(); + internal int[] u = F.Create(); + internal int[] v = F.Create(); + } + + private class PointAffine + { + internal int[] x = F.Create(); + internal int[] y = F.Create(); + } + + private class PointExt + { + internal int[] x = F.Create(); + internal int[] y = F.Create(); + internal int[] z = F.Create(); + internal int[] t = F.Create(); + } + + private class PointPrecomp + { + internal int[] ypx_h = F.Create(); + internal int[] ymx_h = F.Create(); + internal int[] xyd = F.Create(); + } + + private static byte[] CalculateS(byte[] r, byte[] k, byte[] s) + { + uint[] t = new uint[ScalarUints * 2]; DecodeScalar(r, 0, t); + uint[] u = new uint[ScalarUints]; DecodeScalar(k, 0, u); + uint[] v = new uint[ScalarUints]; DecodeScalar(s, 0, v); + + Nat256.MulAddTo(u, v, t); + + byte[] result = new byte[ScalarBytes * 2]; + for (int i = 0; i < t.Length; ++i) + { + Encode32(t[i], result, i * 4); + } + return ReduceScalar(result); + } + + private static bool CheckContextVar(byte[] ctx, byte phflag) + { + return ctx == null && phflag == 0x00 + || ctx != null && ctx.Length < 256; + } + + private static int CheckPoint(int[] x, int[] y) + { + int[] t = F.Create(); + int[] u = F.Create(); + int[] v = F.Create(); + + F.Sqr(x, u); + F.Sqr(y, v); + F.Mul(u, v, t); + F.Sub(v, u, v); + F.Mul(t, C_d, t); + F.AddOne(t); + F.Sub(t, v, t); + F.Normalize(t); + + return F.IsZero(t); + } + + private static int CheckPoint(int[] x, int[] y, int[] z) + { + int[] t = F.Create(); + int[] u = F.Create(); + int[] v = F.Create(); + int[] w = F.Create(); + + F.Sqr(x, u); + F.Sqr(y, v); + F.Sqr(z, w); + F.Mul(u, v, t); + F.Sub(v, u, v); + F.Mul(v, w, v); + F.Sqr(w, w); + F.Mul(t, C_d, t); + F.Add(t, w, t); + F.Sub(t, v, t); + F.Normalize(t); + + return F.IsZero(t); + } + + private static bool CheckPointVar(byte[] p) + { + uint[] t = new uint[CoordUints]; + Decode32(p, 0, t, 0, CoordUints); + t[CoordUints - 1] &= 0x7FFFFFFFU; + return !Nat256.Gte(t, P); + } + + private static bool CheckScalarVar(byte[] s, uint[] n) + { + DecodeScalar(s, 0, n); + return !Nat256.Gte(n, L); + } + + private static byte[] Copy(byte[] buf, int off, int len) + { + byte[] result = new byte[len]; + Array.Copy(buf, off, result, 0, len); + return result; + } + + private static IDigest CreateDigest() + { + return new Sha512Digest(); + } + + public static IDigest CreatePrehash() + { + return CreateDigest(); + } + + private static uint Decode24(byte[] bs, int off) + { + uint n = bs[off]; + n |= (uint)bs[++off] << 8; + n |= (uint)bs[++off] << 16; + return n; + } + + private static uint Decode32(byte[] bs, int off) + { + uint n = bs[off]; + n |= (uint)bs[++off] << 8; + n |= (uint)bs[++off] << 16; + n |= (uint)bs[++off] << 24; + return n; + } + + private static void Decode32(byte[] bs, int bsOff, uint[] n, int nOff, int nLen) + { + for (int i = 0; i < nLen; ++i) + { + n[nOff + i] = Decode32(bs, bsOff + i * 4); + } + } + + private static bool DecodePointVar(byte[] p, int pOff, bool negate, PointAffine r) + { + byte[] py = Copy(p, pOff, PointBytes); + if (!CheckPointVar(py)) + return false; + + int x_0 = (py[PointBytes - 1] & 0x80) >> 7; + py[PointBytes - 1] &= 0x7F; + + F.Decode(py, 0, r.y); + + int[] u = F.Create(); + int[] v = F.Create(); + + F.Sqr(r.y, u); + F.Mul(C_d, u, v); + F.SubOne(u); + F.AddOne(v); + + if (!F.SqrtRatioVar(u, v, r.x)) + return false; + + F.Normalize(r.x); + if (x_0 == 1 && F.IsZeroVar(r.x)) + return false; + + if (negate ^ (x_0 != (r.x[0] & 1))) + { + F.Negate(r.x, r.x); + } + + return true; + } + + private static void DecodeScalar(byte[] k, int kOff, uint[] n) + { + Decode32(k, kOff, n, 0, ScalarUints); + } + + private static void Dom2(IDigest d, byte phflag, byte[] ctx) + { + if (ctx != null) + { + int n = Dom2Prefix.Length; + byte[] t = new byte[n + 2 + ctx.Length]; + Dom2Prefix.CopyTo(t, 0); + t[n] = phflag; + t[n + 1] = (byte)ctx.Length; + ctx.CopyTo(t, n + 2); + + d.BlockUpdate(t, 0, t.Length); + } + } + + private static void Encode24(uint n, byte[] bs, int off) + { + bs[off] = (byte)(n); + bs[++off] = (byte)(n >> 8); + bs[++off] = (byte)(n >> 16); + } + + private static void Encode32(uint n, byte[] bs, int off) + { + bs[off] = (byte)(n); + bs[++off] = (byte)(n >> 8); + bs[++off] = (byte)(n >> 16); + bs[++off] = (byte)(n >> 24); + } + + private static void Encode56(ulong n, byte[] bs, int off) + { + Encode32((uint)n, bs, off); + Encode24((uint)(n >> 32), bs, off + 4); + } + + private static int EncodePoint(PointAccum p, byte[] r, int rOff) + { + int[] x = F.Create(); + int[] y = F.Create(); + + F.Inv(p.z, y); + F.Mul(p.x, y, x); + F.Mul(p.y, y, y); + F.Normalize(x); + F.Normalize(y); + + int result = CheckPoint(x, y); + + F.Encode(y, r, rOff); + r[rOff + PointBytes - 1] |= (byte)((x[0] & 1) << 7); + + return result; + } + + public static void GeneratePrivateKey(SecureRandom random, byte[] k) + { + random.NextBytes(k); + } + + public static void GeneratePublicKey(byte[] sk, int skOff, byte[] pk, int pkOff) + { + IDigest d = CreateDigest(); + byte[] h = new byte[d.GetDigestSize()]; + + d.BlockUpdate(sk, skOff, SecretKeySize); + d.DoFinal(h, 0); + + byte[] s = new byte[ScalarBytes]; + PruneScalar(h, 0, s); + + ScalarMultBaseEncoded(s, pk, pkOff); + } + + private static uint GetWindow4(uint[] x, int n) + { + int w = (int)((uint)n >> 3), b = (n & 7) << 2; + return (x[w] >> b) & 15U; + } + + private static sbyte[] GetWnafVar(uint[] n, int width) + { + Debug.Assert(n[ScalarUints - 1] <= L[ScalarUints - 1]); + Debug.Assert(2 <= width && width <= 8); + + uint[] t = new uint[ScalarUints * 2]; + { + uint c = 0; + int tPos = t.Length, i = ScalarUints; + while (--i >= 0) + { + uint next = n[i]; + t[--tPos] = (next >> 16) | (c << 16); + t[--tPos] = c = next; + } + } + + sbyte[] ws = new sbyte[253]; + + int lead = 32 - width; + + uint carry = 0U; + int j = 0; + for (int i = 0; i < t.Length; ++i, j -= 16) + { + uint word = t[i]; + while (j < 16) + { + uint word16 = word >> j; + uint bit = word16 & 1U; + + if (bit == carry) + { + ++j; + continue; + } + + uint digit = (word16 | 1U) << lead; + carry = digit >> 31; + + ws[(i << 4) + j] = (sbyte)((int)digit >> lead); + + j += width; + } + } + + Debug.Assert(carry == 0); + + return ws; + } + + private static void ImplSign(IDigest d, byte[] h, byte[] s, byte[] pk, int pkOff, byte[] ctx, byte phflag, + byte[] m, int mOff, int mLen, byte[] sig, int sigOff) + { + Dom2(d, phflag, ctx); + d.BlockUpdate(h, ScalarBytes, ScalarBytes); + d.BlockUpdate(m, mOff, mLen); + d.DoFinal(h, 0); + + byte[] r = ReduceScalar(h); + byte[] R = new byte[PointBytes]; + ScalarMultBaseEncoded(r, R, 0); + + Dom2(d, phflag, ctx); + d.BlockUpdate(R, 0, PointBytes); + d.BlockUpdate(pk, pkOff, PointBytes); + d.BlockUpdate(m, mOff, mLen); + d.DoFinal(h, 0); + + byte[] k = ReduceScalar(h); + byte[] S = CalculateS(r, k, s); + + Array.Copy(R, 0, sig, sigOff, PointBytes); + Array.Copy(S, 0, sig, sigOff + PointBytes, ScalarBytes); + } + + private static void ImplSign(byte[] sk, int skOff, byte[] ctx, byte phflag, byte[] m, int mOff, int mLen, + byte[] sig, int sigOff) + { + if (!CheckContextVar(ctx, phflag)) + throw new ArgumentException("ctx"); + + IDigest d = CreateDigest(); + byte[] h = new byte[d.GetDigestSize()]; + + d.BlockUpdate(sk, skOff, SecretKeySize); + d.DoFinal(h, 0); + + byte[] s = new byte[ScalarBytes]; + PruneScalar(h, 0, s); + + byte[] pk = new byte[PointBytes]; + ScalarMultBaseEncoded(s, pk, 0); + + ImplSign(d, h, s, pk, 0, ctx, phflag, m, mOff, mLen, sig, sigOff); + } + + private static void ImplSign(byte[] sk, int skOff, byte[] pk, int pkOff, byte[] ctx, byte phflag, byte[] m, + int mOff, int mLen, byte[] sig, int sigOff) + { + if (!CheckContextVar(ctx, phflag)) + throw new ArgumentException("ctx"); + + IDigest d = CreateDigest(); + byte[] h = new byte[d.GetDigestSize()]; + + d.BlockUpdate(sk, skOff, SecretKeySize); + d.DoFinal(h, 0); + + byte[] s = new byte[ScalarBytes]; + PruneScalar(h, 0, s); + + ImplSign(d, h, s, pk, pkOff, ctx, phflag, m, mOff, mLen, sig, sigOff); + } + + private static bool ImplVerify(byte[] sig, int sigOff, byte[] pk, int pkOff, byte[] ctx, byte phflag, byte[] m, + int mOff, int mLen) + { + if (!CheckContextVar(ctx, phflag)) + throw new ArgumentException("ctx"); + + byte[] R = Copy(sig, sigOff, PointBytes); + byte[] S = Copy(sig, sigOff + PointBytes, ScalarBytes); + + if (!CheckPointVar(R)) + return false; + + uint[] nS = new uint[ScalarUints]; + if (!CheckScalarVar(S, nS)) + return false; + + PointAffine pA = new PointAffine(); + if (!DecodePointVar(pk, pkOff, true, pA)) + return false; + + IDigest d = CreateDigest(); + byte[] h = new byte[d.GetDigestSize()]; + + Dom2(d, phflag, ctx); + d.BlockUpdate(R, 0, PointBytes); + d.BlockUpdate(pk, pkOff, PointBytes); + d.BlockUpdate(m, mOff, mLen); + d.DoFinal(h, 0); + + byte[] k = ReduceScalar(h); + + uint[] nA = new uint[ScalarUints]; + DecodeScalar(k, 0, nA); + + PointAccum pR = new PointAccum(); + ScalarMultStrausVar(nS, nA, pA, pR); + + byte[] check = new byte[PointBytes]; + return 0 != EncodePoint(pR, check, 0) && Arrays.AreEqual(check, R); + } + + private static bool IsNeutralElementVar(int[] x, int[] y) + { + return F.IsZeroVar(x) && F.IsOneVar(y); + } + + private static bool IsNeutralElementVar(int[] x, int[] y, int[] z) + { + return F.IsZeroVar(x) && F.AreEqualVar(y, z); + } + + private static void PointAdd(PointExt p, PointAccum r) + { + int[] a = F.Create(); + int[] b = F.Create(); + int[] c = F.Create(); + int[] d = F.Create(); + int[] e = r.u; + int[] f = F.Create(); + int[] g = F.Create(); + int[] h = r.v; + + F.Apm(r.y, r.x, b, a); + F.Apm(p.y, p.x, d, c); + F.Mul(a, c, a); + F.Mul(b, d, b); + F.Mul(r.u, r.v, c); + F.Mul(c, p.t, c); + F.Mul(c, C_d2, c); + F.Mul(r.z, p.z, d); + F.Add(d, d, d); + F.Apm(b, a, h, e); + F.Apm(d, c, g, f); + F.Carry(g); + F.Mul(e, f, r.x); + F.Mul(g, h, r.y); + F.Mul(f, g, r.z); + } + + private static void PointAdd(PointExt p, PointExt r) + { + int[] a = F.Create(); + int[] b = F.Create(); + int[] c = F.Create(); + int[] d = F.Create(); + int[] e = F.Create(); + int[] f = F.Create(); + int[] g = F.Create(); + int[] h = F.Create(); + + F.Apm(p.y, p.x, b, a); + F.Apm(r.y, r.x, d, c); + F.Mul(a, c, a); + F.Mul(b, d, b); + F.Mul(p.t, r.t, c); + F.Mul(c, C_d2, c); + F.Mul(p.z, r.z, d); + F.Add(d, d, d); + F.Apm(b, a, h, e); + F.Apm(d, c, g, f); + F.Carry(g); + F.Mul(e, f, r.x); + F.Mul(g, h, r.y); + F.Mul(f, g, r.z); + F.Mul(e, h, r.t); + } + + private static void PointAddVar(bool negate, PointExt p, PointAccum r) + { + int[] a = F.Create(); + int[] b = F.Create(); + int[] c = F.Create(); + int[] d = F.Create(); + int[] e = r.u; + int[] f = F.Create(); + int[] g = F.Create(); + int[] h = r.v; + + int[] nc, nd, nf, ng; + if (negate) + { + nc = d; nd = c; nf = g; ng = f; + } + else + { + nc = c; nd = d; nf = f; ng = g; + } + + F.Apm(r.y, r.x, b, a); + F.Apm(p.y, p.x, nd, nc); + F.Mul(a, c, a); + F.Mul(b, d, b); + F.Mul(r.u, r.v, c); + F.Mul(c, p.t, c); + F.Mul(c, C_d2, c); + F.Mul(r.z, p.z, d); + F.Add(d, d, d); + F.Apm(b, a, h, e); + F.Apm(d, c, ng, nf); + F.Carry(ng); + F.Mul(e, f, r.x); + F.Mul(g, h, r.y); + F.Mul(f, g, r.z); + } + + private static void PointAddVar(bool negate, PointExt p, PointExt q, PointExt r) + { + int[] a = F.Create(); + int[] b = F.Create(); + int[] c = F.Create(); + int[] d = F.Create(); + int[] e = F.Create(); + int[] f = F.Create(); + int[] g = F.Create(); + int[] h = F.Create(); + + int[] nc, nd, nf, ng; + if (negate) + { + nc = d; nd = c; nf = g; ng = f; + } + else + { + nc = c; nd = d; nf = f; ng = g; + } + + F.Apm(p.y, p.x, b, a); + F.Apm(q.y, q.x, nd, nc); + F.Mul(a, c, a); + F.Mul(b, d, b); + F.Mul(p.t, q.t, c); + F.Mul(c, C_d2, c); + F.Mul(p.z, q.z, d); + F.Add(d, d, d); + F.Apm(b, a, h, e); + F.Apm(d, c, ng, nf); + F.Carry(ng); + F.Mul(e, f, r.x); + F.Mul(g, h, r.y); + F.Mul(f, g, r.z); + F.Mul(e, h, r.t); + } + + private static void PointAddPrecomp(PointPrecomp p, PointAccum r) + { + int[] a = F.Create(); + int[] b = F.Create(); + int[] c = F.Create(); + int[] e = r.u; + int[] f = F.Create(); + int[] g = F.Create(); + int[] h = r.v; + + F.Apm(r.y, r.x, b, a); + F.Mul(a, p.ymx_h, a); + F.Mul(b, p.ypx_h, b); + F.Mul(r.u, r.v, c); + F.Mul(c, p.xyd, c); + F.Apm(b, a, h, e); + F.Apm(r.z, c, g, f); + F.Carry(g); + F.Mul(e, f, r.x); + F.Mul(g, h, r.y); + F.Mul(f, g, r.z); + } + + private static PointExt PointCopy(PointAccum p) + { + PointExt r = new PointExt(); + F.Copy(p.x, 0, r.x, 0); + F.Copy(p.y, 0, r.y, 0); + F.Copy(p.z, 0, r.z, 0); + F.Mul(p.u, p.v, r.t); + return r; + } + + private static PointExt PointCopy(PointAffine p) + { + PointExt r = new PointExt(); + F.Copy(p.x, 0, r.x, 0); + F.Copy(p.y, 0, r.y, 0); + PointExtendXY(r); + return r; + } + + private static PointExt PointCopy(PointExt p) + { + PointExt r = new PointExt(); + PointCopy(p, r); + return r; + } + + private static void PointCopy(PointAffine p, PointAccum r) + { + F.Copy(p.x, 0, r.x, 0); + F.Copy(p.y, 0, r.y, 0); + PointExtendXY(r); + } + + private static void PointCopy(PointExt p, PointExt r) + { + F.Copy(p.x, 0, r.x, 0); + F.Copy(p.y, 0, r.y, 0); + F.Copy(p.z, 0, r.z, 0); + F.Copy(p.t, 0, r.t, 0); + } + + private static void PointDouble(PointAccum r) + { + int[] a = F.Create(); + int[] b = F.Create(); + int[] c = F.Create(); + int[] e = r.u; + int[] f = F.Create(); + int[] g = F.Create(); + int[] h = r.v; + + F.Sqr(r.x, a); + F.Sqr(r.y, b); + F.Sqr(r.z, c); + F.Add(c, c, c); + F.Apm(a, b, h, g); + F.Add(r.x, r.y, e); + F.Sqr(e, e); + F.Sub(h, e, e); + F.Add(c, g, f); + F.Carry(f); + F.Mul(e, f, r.x); + F.Mul(g, h, r.y); + F.Mul(f, g, r.z); + } + + private static void PointExtendXY(PointAccum p) + { + F.One(p.z); + F.Copy(p.x, 0, p.u, 0); + F.Copy(p.y, 0, p.v, 0); + } + + private static void PointExtendXY(PointExt p) + { + F.One(p.z); + F.Mul(p.x, p.y, p.t); + } + + private static void PointLookup(int block, int index, PointPrecomp p) + { + Debug.Assert(0 <= block && block < PrecompBlocks); + Debug.Assert(0 <= index && index < PrecompPoints); + + int off = block * PrecompPoints * 3 * F.Size; + + for (int i = 0; i < PrecompPoints; ++i) + { + int cond = ((i ^ index) - 1) >> 31; + F.CMov(cond, precompBase, off, p.ypx_h, 0); off += F.Size; + F.CMov(cond, precompBase, off, p.ymx_h, 0); off += F.Size; + F.CMov(cond, precompBase, off, p.xyd, 0); off += F.Size; + } + } + + private static void PointLookup(uint[] x, int n, int[] table, PointExt r) + { + // TODO This method is currently hardcoded to 4-bit windows and 8 precomputed points + + uint w = GetWindow4(x, n); + + int sign = (int)(w >> (4 - 1)) ^ 1; + int abs = ((int)w ^ -sign) & 7; + + Debug.Assert(sign == 0 || sign == 1); + Debug.Assert(0 <= abs && abs < 8); + + for (int i = 0, off = 0; i < 8; ++i) + { + int cond = ((i ^ abs) - 1) >> 31; + F.CMov(cond, table, off, r.x, 0); off += F.Size; + F.CMov(cond, table, off, r.y, 0); off += F.Size; + F.CMov(cond, table, off, r.z, 0); off += F.Size; + F.CMov(cond, table, off, r.t, 0); off += F.Size; + } + + F.CNegate(sign, r.x); + F.CNegate(sign, r.t); + } + + private static void PointLookup(int[] table, int index, PointExt r) + { + int off = F.Size * 4 * index; + + F.Copy(table, off, r.x, 0); off += F.Size; + F.Copy(table, off, r.y, 0); off += F.Size; + F.Copy(table, off, r.z, 0); off += F.Size; + F.Copy(table, off, r.t, 0); + } + + private static int[] PointPrecompute(PointAffine p, int count) + { + Debug.Assert(count > 0); + + PointExt q = PointCopy(p); + PointExt d = PointCopy(q); + PointAdd(q, d); + + int[] table = F.CreateTable(count * 4); + int off = 0; + + int i = 0; + for (;;) + { + F.Copy(q.x, 0, table, off); off += F.Size; + F.Copy(q.y, 0, table, off); off += F.Size; + F.Copy(q.z, 0, table, off); off += F.Size; + F.Copy(q.t, 0, table, off); off += F.Size; + + if (++i == count) + break; + + PointAdd(d, q); + } + + return table; + } + + private static PointExt[] PointPrecomputeVar(PointExt p, int count) + { + Debug.Assert(count > 0); + + PointExt d = new PointExt(); + PointAddVar(false, p, p, d); + + PointExt[] table = new PointExt[count]; + table[0] = PointCopy(p); + for (int i = 1; i < count; ++i) + { + PointAddVar(false, table[i - 1], d, table[i] = new PointExt()); + } + return table; + } + + private static void PointSetNeutral(PointAccum p) + { + F.Zero(p.x); + F.One(p.y); + F.One(p.z); + F.Zero(p.u); + F.One(p.v); + } + + private static void PointSetNeutral(PointExt p) + { + F.Zero(p.x); + F.One(p.y); + F.One(p.z); + F.Zero(p.t); + } + + public static void Precompute() + { + lock (precompLock) + { + if (precompBase != null) + return; + + // Precomputed table for the base point in verification ladder + { + PointExt b = new PointExt(); + F.Copy(B_x, 0, b.x, 0); + F.Copy(B_y, 0, b.y, 0); + PointExtendXY(b); + + precompBaseTable = PointPrecomputeVar(b, 1 << (WnafWidthBase - 2)); + } + + PointAccum p = new PointAccum(); + F.Copy(B_x, 0, p.x, 0); + F.Copy(B_y, 0, p.y, 0); + PointExtendXY(p); + + precompBase = F.CreateTable(PrecompBlocks * PrecompPoints * 3); + + int off = 0; + for (int b = 0; b < PrecompBlocks; ++b) + { + PointExt[] ds = new PointExt[PrecompTeeth]; + + PointExt sum = new PointExt(); + PointSetNeutral(sum); + + for (int t = 0; t < PrecompTeeth; ++t) + { + PointExt q = PointCopy(p); + PointAddVar(true, sum, q, sum); + PointDouble(p); + + ds[t] = PointCopy(p); + + if (b + t != PrecompBlocks + PrecompTeeth - 2) + { + for (int s = 1; s < PrecompSpacing; ++s) + { + PointDouble(p); + } + } + } + + PointExt[] points = new PointExt[PrecompPoints]; + int k = 0; + points[k++] = sum; + + for (int t = 0; t < (PrecompTeeth - 1); ++t) + { + int size = 1 << t; + for (int j = 0; j < size; ++j, ++k) + { + PointAddVar(false, points[k - size], ds[t], points[k] = new PointExt()); + } + } + + Debug.Assert(k == PrecompPoints); + + int[] cs = F.CreateTable(PrecompPoints); + + // TODO[ed25519] A single batch inversion across all blocks? + { + int[] u = F.Create(); + F.Copy(points[0].z, 0, u, 0); + F.Copy(u, 0, cs, 0); + + int i = 0; + while (++i < PrecompPoints) + { + F.Mul(u, points[i].z, u); + F.Copy(u, 0, cs, i * F.Size); + } + + F.Add(u, u, u); + F.InvVar(u, u); + --i; + + int[] t = F.Create(); + + while (i > 0) + { + int j = i--; + F.Copy(cs, i * F.Size, t, 0); + F.Mul(t, u, t); + F.Copy(t, 0, cs, j * F.Size); + F.Mul(u, points[j].z, u); + } + + F.Copy(u, 0, cs, 0); + } + + for (int i = 0; i < PrecompPoints; ++i) + { + PointExt q = points[i]; + + int[] x = F.Create(); + int[] y = F.Create(); + + //F.Add(q.z, q.z, x); + //F.InvVar(x, y); + F.Copy(cs, i * F.Size, y, 0); + + F.Mul(q.x, y, x); + F.Mul(q.y, y, y); + + PointPrecomp r = new PointPrecomp(); + F.Apm(y, x, r.ypx_h, r.ymx_h); + F.Mul(x, y, r.xyd); + F.Mul(r.xyd, C_d4, r.xyd); + + F.Normalize(r.ypx_h); + F.Normalize(r.ymx_h); + //F.Normalize(r.xyd); + + F.Copy(r.ypx_h, 0, precompBase, off); off += F.Size; + F.Copy(r.ymx_h, 0, precompBase, off); off += F.Size; + F.Copy(r.xyd, 0, precompBase, off); off += F.Size; + } + } + + Debug.Assert(off == precompBase.Length); + } + } + + private static void PruneScalar(byte[] n, int nOff, byte[] r) + { + Array.Copy(n, nOff, r, 0, ScalarBytes); + + r[0] &= 0xF8; + r[ScalarBytes - 1] &= 0x7F; + r[ScalarBytes - 1] |= 0x40; + } + + private static byte[] ReduceScalar(byte[] n) + { + long x00 = Decode32(n, 0) & M32L; // x00:32/-- + long x01 = (Decode24(n, 4) << 4) & M32L; // x01:28/-- + long x02 = Decode32(n, 7) & M32L; // x02:32/-- + long x03 = (Decode24(n, 11) << 4) & M32L; // x03:28/-- + long x04 = Decode32(n, 14) & M32L; // x04:32/-- + long x05 = (Decode24(n, 18) << 4) & M32L; // x05:28/-- + long x06 = Decode32(n, 21) & M32L; // x06:32/-- + long x07 = (Decode24(n, 25) << 4) & M32L; // x07:28/-- + long x08 = Decode32(n, 28) & M32L; // x08:32/-- + long x09 = (Decode24(n, 32) << 4) & M32L; // x09:28/-- + long x10 = Decode32(n, 35) & M32L; // x10:32/-- + long x11 = (Decode24(n, 39) << 4) & M32L; // x11:28/-- + long x12 = Decode32(n, 42) & M32L; // x12:32/-- + long x13 = (Decode24(n, 46) << 4) & M32L; // x13:28/-- + long x14 = Decode32(n, 49) & M32L; // x14:32/-- + long x15 = (Decode24(n, 53) << 4) & M32L; // x15:28/-- + long x16 = Decode32(n, 56) & M32L; // x16:32/-- + long x17 = (Decode24(n, 60) << 4) & M32L; // x17:28/-- + long x18 = n[63] & M08L; // x18:08/-- + long t; + + //x18 += (x17 >> 28); x17 &= M28L; + x09 -= x18 * L0; // x09:34/28 + x10 -= x18 * L1; // x10:33/30 + x11 -= x18 * L2; // x11:35/28 + x12 -= x18 * L3; // x12:32/31 + x13 -= x18 * L4; // x13:28/21 + + x17 += (x16 >> 28); x16 &= M28L; // x17:28/--, x16:28/-- + x08 -= x17 * L0; // x08:54/32 + x09 -= x17 * L1; // x09:52/51 + x10 -= x17 * L2; // x10:55/34 + x11 -= x17 * L3; // x11:51/36 + x12 -= x17 * L4; // x12:41/-- + + //x16 += (x15 >> 28); x15 &= M28L; + x07 -= x16 * L0; // x07:54/28 + x08 -= x16 * L1; // x08:54/53 + x09 -= x16 * L2; // x09:55/53 + x10 -= x16 * L3; // x10:55/52 + x11 -= x16 * L4; // x11:51/41 + + x15 += (x14 >> 28); x14 &= M28L; // x15:28/--, x14:28/-- + x06 -= x15 * L0; // x06:54/32 + x07 -= x15 * L1; // x07:54/53 + x08 -= x15 * L2; // x08:56/-- + x09 -= x15 * L3; // x09:55/54 + x10 -= x15 * L4; // x10:55/53 + + //x14 += (x13 >> 28); x13 &= M28L; + x05 -= x14 * L0; // x05:54/28 + x06 -= x14 * L1; // x06:54/53 + x07 -= x14 * L2; // x07:56/-- + x08 -= x14 * L3; // x08:56/51 + x09 -= x14 * L4; // x09:56/-- + + x13 += (x12 >> 28); x12 &= M28L; // x13:28/22, x12:28/-- + x04 -= x13 * L0; // x04:54/49 + x05 -= x13 * L1; // x05:54/53 + x06 -= x13 * L2; // x06:56/-- + x07 -= x13 * L3; // x07:56/52 + x08 -= x13 * L4; // x08:56/52 + + x12 += (x11 >> 28); x11 &= M28L; // x12:28/24, x11:28/-- + x03 -= x12 * L0; // x03:54/49 + x04 -= x12 * L1; // x04:54/51 + x05 -= x12 * L2; // x05:56/-- + x06 -= x12 * L3; // x06:56/52 + x07 -= x12 * L4; // x07:56/53 + + x11 += (x10 >> 28); x10 &= M28L; // x11:29/--, x10:28/-- + x02 -= x11 * L0; // x02:55/32 + x03 -= x11 * L1; // x03:55/-- + x04 -= x11 * L2; // x04:56/55 + x05 -= x11 * L3; // x05:56/52 + x06 -= x11 * L4; // x06:56/53 + + x10 += (x09 >> 28); x09 &= M28L; // x10:29/--, x09:28/-- + x01 -= x10 * L0; // x01:55/28 + x02 -= x10 * L1; // x02:55/54 + x03 -= x10 * L2; // x03:56/55 + x04 -= x10 * L3; // x04:57/-- + x05 -= x10 * L4; // x05:56/53 + + x08 += (x07 >> 28); x07 &= M28L; // x08:56/53, x07:28/-- + x09 += (x08 >> 28); x08 &= M28L; // x09:29/25, x08:28/-- + + t = (x08 >> 27) & 1L; + x09 += t; // x09:29/26 + + x00 -= x09 * L0; // x00:55/53 + x01 -= x09 * L1; // x01:55/54 + x02 -= x09 * L2; // x02:57/-- + x03 -= x09 * L3; // x03:57/-- + x04 -= x09 * L4; // x04:57/42 + + x01 += (x00 >> 28); x00 &= M28L; + x02 += (x01 >> 28); x01 &= M28L; + x03 += (x02 >> 28); x02 &= M28L; + x04 += (x03 >> 28); x03 &= M28L; + x05 += (x04 >> 28); x04 &= M28L; + x06 += (x05 >> 28); x05 &= M28L; + x07 += (x06 >> 28); x06 &= M28L; + x08 += (x07 >> 28); x07 &= M28L; + x09 = (x08 >> 28); x08 &= M28L; + + x09 -= t; + + Debug.Assert(x09 == 0L || x09 == -1L); + + x00 += x09 & L0; + x01 += x09 & L1; + x02 += x09 & L2; + x03 += x09 & L3; + x04 += x09 & L4; + + x01 += (x00 >> 28); x00 &= M28L; + x02 += (x01 >> 28); x01 &= M28L; + x03 += (x02 >> 28); x02 &= M28L; + x04 += (x03 >> 28); x03 &= M28L; + x05 += (x04 >> 28); x04 &= M28L; + x06 += (x05 >> 28); x05 &= M28L; + x07 += (x06 >> 28); x06 &= M28L; + x08 += (x07 >> 28); x07 &= M28L; + + byte[] r = new byte[ScalarBytes]; + Encode56((ulong)(x00 | (x01 << 28)), r, 0); + Encode56((ulong)(x02 | (x03 << 28)), r, 7); + Encode56((ulong)(x04 | (x05 << 28)), r, 14); + Encode56((ulong)(x06 | (x07 << 28)), r, 21); + Encode32((uint)x08, r, 28); + return r; + } + + private static void ScalarMult(byte[] k, PointAffine p, PointAccum r) + { + uint[] n = new uint[ScalarUints]; + DecodeScalar(k, 0, n); + + Debug.Assert(0U == (n[0] & 7)); + Debug.Assert(1U == n[ScalarUints - 1] >> 30); + + Nat.ShiftDownBits(ScalarUints, n, 3, 1U); + + // Recode the scalar into signed-digit form + { + uint c1 = Nat.CAdd(ScalarUints, ~(int)n[0] & 1, n, L, n); Debug.Assert(c1 == 0U); + uint c2 = Nat.ShiftDownBit(ScalarUints, n, 0U); Debug.Assert(c2 == (1U << 31)); + } + + Debug.Assert(1U == n[ScalarUints - 1] >> 28); + + int[] table = PointPrecompute(p, 8); + PointExt q = new PointExt(); + + // Replace first 4 doublings (2^4 * P) with 1 addition (P + 15 * P) + PointCopy(p, r); + PointLookup(table, 7, q); + PointAdd(q, r); + + int w = 62; + for (;;) + { + PointLookup(n, w, table, q); + PointAdd(q, r); + + PointDouble(r); + PointDouble(r); + PointDouble(r); + + if (--w < 0) + break; + + PointDouble(r); + } + } + + private static void ScalarMultBase(byte[] k, PointAccum r) + { + Precompute(); + + uint[] n = new uint[ScalarUints]; + DecodeScalar(k, 0, n); + + // Recode the scalar into signed-digit form, then group comb bits in each block + { + uint c1 = Nat.CAdd(ScalarUints, ~(int)n[0] & 1, n, L, n); Debug.Assert(c1 == 0U); + uint c2 = Nat.ShiftDownBit(ScalarUints, n, 1U); Debug.Assert(c2 == (1U << 31)); + + for (int i = 0; i < ScalarUints; ++i) + { + n[i] = Interleave.Shuffle2(n[i]); + } + } + + PointPrecomp p = new PointPrecomp(); + + PointSetNeutral(r); + + int cOff = (PrecompSpacing - 1) * PrecompTeeth; + for (;;) + { + for (int b = 0; b < PrecompBlocks; ++b) + { + uint w = n[b] >> cOff; + int sign = (int)(w >> (PrecompTeeth - 1)) & 1; + int abs = ((int)w ^ -sign) & PrecompMask; + + Debug.Assert(sign == 0 || sign == 1); + Debug.Assert(0 <= abs && abs < PrecompPoints); + + PointLookup(b, abs, p); + + F.CSwap(sign, p.ypx_h, p.ymx_h); + F.CNegate(sign, p.xyd); + + PointAddPrecomp(p, r); + } + + if ((cOff -= PrecompTeeth) < 0) + break; + + PointDouble(r); + } + } + + private static void ScalarMultBaseEncoded(byte[] k, byte[] r, int rOff) + { + PointAccum p = new PointAccum(); + ScalarMultBase(k, p); + if (0 == EncodePoint(p, r, rOff)) + throw new InvalidOperationException(); + } + + internal static void ScalarMultBaseYZ(byte[] k, int kOff, int[] y, int[] z) + { + byte[] n = new byte[ScalarBytes]; + PruneScalar(k, kOff, n); + + PointAccum p = new PointAccum(); + ScalarMultBase(n, p); + + if (0 == CheckPoint(p.x, p.y, p.z)) + throw new InvalidOperationException(); + + F.Copy(p.y, 0, y, 0); + F.Copy(p.z, 0, z, 0); + } + + private static void ScalarMultOrderVar(PointAffine p, PointAccum r) + { + int width = 5; + + sbyte[] ws_p = GetWnafVar(L, width); + + PointExt[] tp = PointPrecomputeVar(PointCopy(p), 1 << (width - 2)); + + PointSetNeutral(r); + + for (int bit = 252; ;) + { + int wp = ws_p[bit]; + if (wp != 0) + { + int sign = wp >> 31; + int index = (wp ^ sign) >> 1; + + PointAddVar((sign != 0), tp[index], r); + } + + if (--bit < 0) + break; + + PointDouble(r); + } + } + + private static void ScalarMultStrausVar(uint[] nb, uint[] np, PointAffine p, PointAccum r) + { + Precompute(); + + int width = 5; + + sbyte[] ws_b = GetWnafVar(nb, WnafWidthBase); + sbyte[] ws_p = GetWnafVar(np, width); + + PointExt[] tp = PointPrecomputeVar(PointCopy(p), 1 << (width - 2)); + + PointSetNeutral(r); + + for (int bit = 252;;) + { + int wb = ws_b[bit]; + if (wb != 0) + { + int sign = wb >> 31; + int index = (wb ^ sign) >> 1; + + PointAddVar((sign != 0), precompBaseTable[index], r); + } + + int wp = ws_p[bit]; + if (wp != 0) + { + int sign = wp >> 31; + int index = (wp ^ sign) >> 1; + + PointAddVar((sign != 0), tp[index], r); + } + + if (--bit < 0) + break; + + PointDouble(r); + } + } + + public static void Sign(byte[] sk, int skOff, byte[] m, int mOff, int mLen, byte[] sig, int sigOff) + { + byte[] ctx = null; + byte phflag = 0x00; + + ImplSign(sk, skOff, ctx, phflag, m, mOff, mLen, sig, sigOff); + } + + public static void Sign(byte[] sk, int skOff, byte[] pk, int pkOff, byte[] m, int mOff, int mLen, byte[] sig, int sigOff) + { + byte[] ctx = null; + byte phflag = 0x00; + + ImplSign(sk, skOff, pk, pkOff, ctx, phflag, m, mOff, mLen, sig, sigOff); + } + + public static void Sign(byte[] sk, int skOff, byte[] ctx, byte[] m, int mOff, int mLen, byte[] sig, int sigOff) + { + byte phflag = 0x00; + + ImplSign(sk, skOff, ctx, phflag, m, mOff, mLen, sig, sigOff); + } + + public static void Sign(byte[] sk, int skOff, byte[] pk, int pkOff, byte[] ctx, byte[] m, int mOff, int mLen, byte[] sig, int sigOff) + { + byte phflag = 0x00; + + ImplSign(sk, skOff, pk, pkOff, ctx, phflag, m, mOff, mLen, sig, sigOff); + } + + public static void SignPrehash(byte[] sk, int skOff, byte[] ctx, byte[] ph, int phOff, byte[] sig, int sigOff) + { + byte phflag = 0x01; + + ImplSign(sk, skOff, ctx, phflag, ph, phOff, PrehashSize, sig, sigOff); + } + + public static void SignPrehash(byte[] sk, int skOff, byte[] pk, int pkOff, byte[] ctx, byte[] ph, int phOff, byte[] sig, int sigOff) + { + byte phflag = 0x01; + + ImplSign(sk, skOff, pk, pkOff, ctx, phflag, ph, phOff, PrehashSize, sig, sigOff); + } + + public static void SignPrehash(byte[] sk, int skOff, byte[] ctx, IDigest ph, byte[] sig, int sigOff) + { + byte[] m = new byte[PrehashSize]; + if (PrehashSize != ph.DoFinal(m, 0)) + throw new ArgumentException("ph"); + + byte phflag = 0x01; + + ImplSign(sk, skOff, ctx, phflag, m, 0, m.Length, sig, sigOff); + } + + public static void SignPrehash(byte[] sk, int skOff, byte[] pk, int pkOff, byte[] ctx, IDigest ph, byte[] sig, int sigOff) + { + byte[] m = new byte[PrehashSize]; + if (PrehashSize != ph.DoFinal(m, 0)) + throw new ArgumentException("ph"); + + byte phflag = 0x01; + + ImplSign(sk, skOff, pk, pkOff, ctx, phflag, m, 0, m.Length, sig, sigOff); + } + + public static bool ValidatePublicKeyFull(byte[] pk, int pkOff) + { + PointAffine p = new PointAffine(); + if (!DecodePointVar(pk, pkOff, false, p)) + return false; + + F.Normalize(p.x); + F.Normalize(p.y); + + if (IsNeutralElementVar(p.x, p.y)) + return false; + + PointAccum r = new PointAccum(); + ScalarMultOrderVar(p, r); + + F.Normalize(r.x); + F.Normalize(r.y); + F.Normalize(r.z); + + return IsNeutralElementVar(r.x, r.y, r.z); + } + + public static bool ValidatePublicKeyPartial(byte[] pk, int pkOff) + { + PointAffine p = new PointAffine(); + return DecodePointVar(pk, pkOff, false, p); + } + + public static bool Verify(byte[] sig, int sigOff, byte[] pk, int pkOff, byte[] m, int mOff, int mLen) + { + byte[] ctx = null; + byte phflag = 0x00; + + return ImplVerify(sig, sigOff, pk, pkOff, ctx, phflag, m, mOff, mLen); + } + + public static bool Verify(byte[] sig, int sigOff, byte[] pk, int pkOff, byte[] ctx, byte[] m, int mOff, int mLen) + { + byte phflag = 0x00; + + return ImplVerify(sig, sigOff, pk, pkOff, ctx, phflag, m, mOff, mLen); + } + + public static bool VerifyPrehash(byte[] sig, int sigOff, byte[] pk, int pkOff, byte[] ctx, byte[] ph, int phOff) + { + byte phflag = 0x01; + + return ImplVerify(sig, sigOff, pk, pkOff, ctx, phflag, ph, phOff, PrehashSize); + } + + public static bool VerifyPrehash(byte[] sig, int sigOff, byte[] pk, int pkOff, byte[] ctx, IDigest ph) + { + byte[] m = new byte[PrehashSize]; + if (PrehashSize != ph.DoFinal(m, 0)) + throw new ArgumentException("ph"); + + byte phflag = 0x01; + + return ImplVerify(sig, sigOff, pk, pkOff, ctx, phflag, m, 0, m.Length); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/rfc8032/Ed25519.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/rfc8032/Ed25519.cs.meta new file mode 100644 index 0000000..f0ba427 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/rfc8032/Ed25519.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6d0ceffb22f0f814fabb6f36de81c926 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/rfc8032/Ed448.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/rfc8032/Ed448.cs new file mode 100644 index 0000000..e0478af --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/rfc8032/Ed448.cs @@ -0,0 +1,1442 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Math.EC.Rfc7748; +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math.EC.Rfc8032 +{ + public abstract class Ed448 + { + // x^2 + y^2 == 1 - 39081 * x^2 * y^2 + + public enum Algorithm + { + Ed448 = 0, + Ed448ph = 1, + } + + private class F : X448Field {}; + + private const ulong M26UL = 0x03FFFFFFUL; + private const ulong M28UL = 0x0FFFFFFFUL; + + private const int CoordUints = 14; + private const int PointBytes = CoordUints * 4 + 1; + private const int ScalarUints = 14; + private const int ScalarBytes = ScalarUints * 4 + 1; + + public static readonly int PrehashSize = 64; + public static readonly int PublicKeySize = PointBytes; + public static readonly int SecretKeySize = 57; + public static readonly int SignatureSize = PointBytes + ScalarBytes; + + // "SigEd448" + private static readonly byte[] Dom4Prefix = new byte[]{ 0x53, 0x69, 0x67, 0x45, 0x64, 0x34, 0x34, 0x38 }; + + private static readonly uint[] P = { 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0xFFFFFFFEU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU }; + private static readonly uint[] L = { 0xAB5844F3U, 0x2378C292U, 0x8DC58F55U, 0x216CC272U, 0xAED63690U, 0xC44EDB49U, 0x7CCA23E9U, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x3FFFFFFFU }; + + private const int L_0 = 0x04A7BB0D; // L_0:26/24 + private const int L_1 = 0x0873D6D5; // L_1:27/23 + private const int L_2 = 0x0A70AADC; // L_2:27/26 + private const int L_3 = 0x03D8D723; // L_3:26/-- + private const int L_4 = 0x096FDE93; // L_4:27/25 + private const int L_5 = 0x0B65129C; // L_5:27/26 + private const int L_6 = 0x063BB124; // L_6:27/-- + private const int L_7 = 0x08335DC1; // L_7:27/22 + + private const int L4_0 = 0x029EEC34; // L4_0:25/24 + private const int L4_1 = 0x01CF5B55; // L4_1:25/-- + private const int L4_2 = 0x09C2AB72; // L4_2:27/25 + private const int L4_3 = 0x0F635C8E; // L4_3:28/-- + private const int L4_4 = 0x05BF7A4C; // L4_4:26/25 + private const int L4_5 = 0x0D944A72; // L4_5:28/-- + private const int L4_6 = 0x08EEC492; // L4_6:27/24 + private const int L4_7 = 0x20CD7705; // L4_7:29/24 + + private static readonly uint[] B_x = { 0x070CC05EU, 0x026A82BCU, 0x00938E26U, 0x080E18B0U, 0x0511433BU, 0x0F72AB66U, 0x0412AE1AU, + 0x0A3D3A46U, 0x0A6DE324U, 0x00F1767EU, 0x04657047U, 0x036DA9E1U, 0x05A622BFU, 0x0ED221D1U, 0x066BED0DU, 0x04F1970CU }; + private static readonly uint[] B_y = { 0x0230FA14U, 0x008795BFU, 0x07C8AD98U, 0x0132C4EDU, 0x09C4FDBDU, 0x01CE67C3U, 0x073AD3FFU, + 0x005A0C2DU, 0x07789C1EU, 0x0A398408U, 0x0A73736CU, 0x0C7624BEU, 0x003756C9U, 0x02488762U, 0x016EB6BCU, 0x0693F467U }; + private const int C_d = -39081; + + private const int WnafWidthBase = 7; + + private const int PrecompBlocks = 5; + private const int PrecompTeeth = 5; + private const int PrecompSpacing = 18; + private const int PrecompPoints = 1 << (PrecompTeeth - 1); + private const int PrecompMask = PrecompPoints - 1; + + private static readonly object precompLock = new object(); + // TODO[ed448] Convert to PointPrecomp + private static PointExt[] precompBaseTable = null; + private static uint[] precompBase = null; + + private class PointExt + { + internal uint[] x = F.Create(); + internal uint[] y = F.Create(); + internal uint[] z = F.Create(); + } + + private class PointPrecomp + { + internal uint[] x = F.Create(); + internal uint[] y = F.Create(); + } + + private static byte[] CalculateS(byte[] r, byte[] k, byte[] s) + { + uint[] t = new uint[ScalarUints * 2]; DecodeScalar(r, 0, t); + uint[] u = new uint[ScalarUints]; DecodeScalar(k, 0, u); + uint[] v = new uint[ScalarUints]; DecodeScalar(s, 0, v); + + Nat.MulAddTo(ScalarUints, u, v, t); + + byte[] result = new byte[ScalarBytes * 2]; + for (int i = 0; i < t.Length; ++i) + { + Encode32(t[i], result, i * 4); + } + return ReduceScalar(result); + } + + private static bool CheckContextVar(byte[] ctx) + { + return ctx != null && ctx.Length < 256; + } + + private static int CheckPoint(uint[] x, uint[] y) + { + uint[] t = F.Create(); + uint[] u = F.Create(); + uint[] v = F.Create(); + + F.Sqr(x, u); + F.Sqr(y, v); + F.Mul(u, v, t); + F.Add(u, v, u); + F.Mul(t, -C_d, t); + F.SubOne(t); + F.Add(t, u, t); + F.Normalize(t); + + return F.IsZero(t); + } + + private static int CheckPoint(uint[] x, uint[] y, uint[] z) + { + uint[] t = F.Create(); + uint[] u = F.Create(); + uint[] v = F.Create(); + uint[] w = F.Create(); + + F.Sqr(x, u); + F.Sqr(y, v); + F.Sqr(z, w); + F.Mul(u, v, t); + F.Add(u, v, u); + F.Mul(u, w, u); + F.Sqr(w, w); + F.Mul(t, -C_d, t); + F.Sub(t, w, t); + F.Add(t, u, t); + F.Normalize(t); + + return F.IsZero(t); + } + + private static bool CheckPointVar(byte[] p) + { + if ((p[PointBytes - 1] & 0x7F) != 0x00) + return false; + + uint[] t = new uint[CoordUints]; + Decode32(p, 0, t, 0, CoordUints); + return !Nat.Gte(CoordUints, t, P); + } + + private static bool CheckScalarVar(byte[] s, uint[] n) + { + if (s[ScalarBytes - 1] != 0x00) + return false; + + DecodeScalar(s, 0, n); + return !Nat.Gte(ScalarUints, n, L); + } + + private static byte[] Copy(byte[] buf, int off, int len) + { + byte[] result = new byte[len]; + Array.Copy(buf, off, result, 0, len); + return result; + } + + public static IXof CreatePrehash() + { + return CreateXof(); + } + + private static IXof CreateXof() + { + return new ShakeDigest(256); + } + + private static uint Decode16(byte[] bs, int off) + { + uint n = bs[off]; + n |= (uint)bs[++off] << 8; + return n; + } + + private static uint Decode24(byte[] bs, int off) + { + uint n = bs[off]; + n |= (uint)bs[++off] << 8; + n |= (uint)bs[++off] << 16; + return n; + } + + private static uint Decode32(byte[] bs, int off) + { + uint n = bs[off]; + n |= (uint)bs[++off] << 8; + n |= (uint)bs[++off] << 16; + n |= (uint)bs[++off] << 24; + return n; + } + + private static void Decode32(byte[] bs, int bsOff, uint[] n, int nOff, int nLen) + { + for (int i = 0; i < nLen; ++i) + { + n[nOff + i] = Decode32(bs, bsOff + i * 4); + } + } + + private static bool DecodePointVar(byte[] p, int pOff, bool negate, PointExt r) + { + byte[] py = Copy(p, pOff, PointBytes); + if (!CheckPointVar(py)) + return false; + + int x_0 = (py[PointBytes - 1] & 0x80) >> 7; + py[PointBytes - 1] &= 0x7F; + + F.Decode(py, 0, r.y); + + uint[] u = F.Create(); + uint[] v = F.Create(); + + F.Sqr(r.y, u); + F.Mul(u, (uint)-C_d, v); + F.Negate(u, u); + F.AddOne(u); + F.AddOne(v); + + if (!F.SqrtRatioVar(u, v, r.x)) + return false; + + F.Normalize(r.x); + if (x_0 == 1 && F.IsZeroVar(r.x)) + return false; + + if (negate ^ (x_0 != (r.x[0] & 1))) + { + F.Negate(r.x, r.x); + } + + PointExtendXY(r); + return true; + } + + private static void DecodeScalar(byte[] k, int kOff, uint[] n) + { + Debug.Assert(k[kOff + ScalarBytes - 1] == 0x00); + + Decode32(k, kOff, n, 0, ScalarUints); + } + + private static void Dom4(IXof d, byte phflag, byte[] ctx) + { + int n = Dom4Prefix.Length; + byte[] t = new byte[n + 2 + ctx.Length]; + Dom4Prefix.CopyTo(t, 0); + t[n] = phflag; + t[n + 1] = (byte)ctx.Length; + ctx.CopyTo(t, n + 2); + + d.BlockUpdate(t, 0, t.Length); + } + + private static void Encode24(uint n, byte[] bs, int off) + { + bs[off] = (byte)(n); + bs[++off] = (byte)(n >> 8); + bs[++off] = (byte)(n >> 16); + } + + private static void Encode32(uint n, byte[] bs, int off) + { + bs[off] = (byte)(n); + bs[++off] = (byte)(n >> 8); + bs[++off] = (byte)(n >> 16); + bs[++off] = (byte)(n >> 24); + } + + private static void Encode56(ulong n, byte[] bs, int off) + { + Encode32((uint)n, bs, off); + Encode24((uint)(n >> 32), bs, off + 4); + } + + private static int EncodePoint(PointExt p, byte[] r, int rOff) + { + uint[] x = F.Create(); + uint[] y = F.Create(); + + F.Inv(p.z, y); + F.Mul(p.x, y, x); + F.Mul(p.y, y, y); + F.Normalize(x); + F.Normalize(y); + + int result = CheckPoint(x, y); + + F.Encode(y, r, rOff); + r[rOff + PointBytes - 1] = (byte)((x[0] & 1) << 7); + + return result; + } + + public static void GeneratePrivateKey(SecureRandom random, byte[] k) + { + random.NextBytes(k); + } + + public static void GeneratePublicKey(byte[] sk, int skOff, byte[] pk, int pkOff) + { + IXof d = CreateXof(); + byte[] h = new byte[ScalarBytes * 2]; + + d.BlockUpdate(sk, skOff, SecretKeySize); + d.DoFinal(h, 0, h.Length); + + byte[] s = new byte[ScalarBytes]; + PruneScalar(h, 0, s); + + ScalarMultBaseEncoded(s, pk, pkOff); + } + + private static uint GetWindow4(uint[] x, int n) + { + int w = (int)((uint)n >> 3), b = (n & 7) << 2; + return (x[w] >> b) & 15U; + } + + private static sbyte[] GetWnafVar(uint[] n, int width) + { + Debug.Assert(n[ScalarUints - 1] <= L[ScalarUints - 1]); + Debug.Assert(2 <= width && width <= 8); + + uint[] t = new uint[ScalarUints * 2]; + { + uint c = 0; + int tPos = t.Length, i = ScalarUints; + while (--i >= 0) + { + uint next = n[i]; + t[--tPos] = (next >> 16) | (c << 16); + t[--tPos] = c = next; + } + } + + sbyte[] ws = new sbyte[447]; + + int lead = 32 - width; + + uint carry = 0U; + int j = 0; + for (int i = 0; i < t.Length; ++i, j -= 16) + { + uint word = t[i]; + while (j < 16) + { + uint word16 = word >> j; + uint bit = word16 & 1U; + + if (bit == carry) + { + ++j; + continue; + } + + uint digit = (word16 | 1U) << lead; + carry = digit >> 31; + + ws[(i << 4) + j] = (sbyte)((int)digit >> lead); + + j += width; + } + } + + Debug.Assert(carry == 0); + + return ws; + } + + private static void ImplSign(IXof d, byte[] h, byte[] s, byte[] pk, int pkOff, byte[] ctx, byte phflag, + byte[] m, int mOff, int mLen, byte[] sig, int sigOff) + { + Dom4(d, phflag, ctx); + d.BlockUpdate(h, ScalarBytes, ScalarBytes); + d.BlockUpdate(m, mOff, mLen); + d.DoFinal(h, 0, h.Length); + + byte[] r = ReduceScalar(h); + byte[] R = new byte[PointBytes]; + ScalarMultBaseEncoded(r, R, 0); + + Dom4(d, phflag, ctx); + d.BlockUpdate(R, 0, PointBytes); + d.BlockUpdate(pk, pkOff, PointBytes); + d.BlockUpdate(m, mOff, mLen); + d.DoFinal(h, 0, h.Length); + + byte[] k = ReduceScalar(h); + byte[] S = CalculateS(r, k, s); + + Array.Copy(R, 0, sig, sigOff, PointBytes); + Array.Copy(S, 0, sig, sigOff + PointBytes, ScalarBytes); + } + + private static void ImplSign(byte[] sk, int skOff, byte[] ctx, byte phflag, byte[] m, int mOff, int mLen, + byte[] sig, int sigOff) + { + if (!CheckContextVar(ctx)) + throw new ArgumentException("ctx"); + + IXof d = CreateXof(); + byte[] h = new byte[ScalarBytes * 2]; + + d.BlockUpdate(sk, skOff, SecretKeySize); + d.DoFinal(h, 0, h.Length); + + byte[] s = new byte[ScalarBytes]; + PruneScalar(h, 0, s); + + byte[] pk = new byte[PointBytes]; + ScalarMultBaseEncoded(s, pk, 0); + + ImplSign(d, h, s, pk, 0, ctx, phflag, m, mOff, mLen, sig, sigOff); + } + + private static void ImplSign(byte[] sk, int skOff, byte[] pk, int pkOff, byte[] ctx, byte phflag, + byte[] m, int mOff, int mLen, byte[] sig, int sigOff) + { + if (!CheckContextVar(ctx)) + throw new ArgumentException("ctx"); + + IXof d = CreateXof(); + byte[] h = new byte[ScalarBytes * 2]; + + d.BlockUpdate(sk, skOff, SecretKeySize); + d.DoFinal(h, 0, h.Length); + + byte[] s = new byte[ScalarBytes]; + PruneScalar(h, 0, s); + + ImplSign(d, h, s, pk, pkOff, ctx, phflag, m, mOff, mLen, sig, sigOff); + } + + private static bool ImplVerify(byte[] sig, int sigOff, byte[] pk, int pkOff, byte[] ctx, byte phflag, + byte[] m, int mOff, int mLen) + { + if (!CheckContextVar(ctx)) + throw new ArgumentException("ctx"); + + byte[] R = Copy(sig, sigOff, PointBytes); + byte[] S = Copy(sig, sigOff + PointBytes, ScalarBytes); + + if (!CheckPointVar(R)) + return false; + + uint[] nS = new uint[ScalarUints]; + if (!CheckScalarVar(S, nS)) + return false; + + PointExt pA = new PointExt(); + if (!DecodePointVar(pk, pkOff, true, pA)) + return false; + + IXof d = CreateXof(); + byte[] h = new byte[ScalarBytes * 2]; + + Dom4(d, phflag, ctx); + d.BlockUpdate(R, 0, PointBytes); + d.BlockUpdate(pk, pkOff, PointBytes); + d.BlockUpdate(m, mOff, mLen); + d.DoFinal(h, 0, h.Length); + + byte[] k = ReduceScalar(h); + + uint[] nA = new uint[ScalarUints]; + DecodeScalar(k, 0, nA); + + PointExt pR = new PointExt(); + ScalarMultStrausVar(nS, nA, pA, pR); + + byte[] check = new byte[PointBytes]; + return 0 != EncodePoint(pR, check, 0) && Arrays.AreEqual(check, R); + } + + private static bool IsNeutralElementVar(uint[] x, uint[] y) + { + return F.IsZeroVar(x) && F.IsOneVar(y); + } + + private static bool IsNeutralElementVar(uint[] x, uint[] y, uint[] z) + { + return F.IsZeroVar(x) && F.AreEqualVar(y, z); + } + + private static void PointAdd(PointExt p, PointExt r) + { + uint[] a = F.Create(); + uint[] b = F.Create(); + uint[] c = F.Create(); + uint[] d = F.Create(); + uint[] e = F.Create(); + uint[] f = F.Create(); + uint[] g = F.Create(); + uint[] h = F.Create(); + + F.Mul(p.z, r.z, a); + F.Sqr(a, b); + F.Mul(p.x, r.x, c); + F.Mul(p.y, r.y, d); + F.Mul(c, d, e); + F.Mul(e, -C_d, e); + //F.Apm(b, e, f, g); + F.Add(b, e, f); + F.Sub(b, e, g); + F.Add(p.x, p.y, b); + F.Add(r.x, r.y, e); + F.Mul(b, e, h); + //F.Apm(d, c, b, e); + F.Add(d, c, b); + F.Sub(d, c, e); + F.Carry(b); + F.Sub(h, b, h); + F.Mul(h, a, h); + F.Mul(e, a, e); + F.Mul(f, h, r.x); + F.Mul(e, g, r.y); + F.Mul(f, g, r.z); + } + + private static void PointAddVar(bool negate, PointExt p, PointExt r) + { + uint[] a = F.Create(); + uint[] b = F.Create(); + uint[] c = F.Create(); + uint[] d = F.Create(); + uint[] e = F.Create(); + uint[] f = F.Create(); + uint[] g = F.Create(); + uint[] h = F.Create(); + + uint[] nb, ne, nf, ng; + if (negate) + { + nb = e; ne = b; nf = g; ng = f; + F.Sub(p.y, p.x, h); + } + else + { + nb = b; ne = e; nf = f; ng = g; + F.Add(p.y, p.x, h); + } + + F.Mul(p.z, r.z, a); + F.Sqr(a, b); + F.Mul(p.x, r.x, c); + F.Mul(p.y, r.y, d); + F.Mul(c, d, e); + F.Mul(e, -C_d, e); + //F.Apm(b, e, nf, ng); + F.Add(b, e, nf); + F.Sub(b, e, ng); + F.Add(r.x, r.y, e); + F.Mul(h, e, h); + //F.Apm(d, c, nb, ne); + F.Add(d, c, nb); + F.Sub(d, c, ne); + F.Carry(nb); + F.Sub(h, b, h); + F.Mul(h, a, h); + F.Mul(e, a, e); + F.Mul(f, h, r.x); + F.Mul(e, g, r.y); + F.Mul(f, g, r.z); + } + + private static void PointAddPrecomp(PointPrecomp p, PointExt r) + { + uint[] b = F.Create(); + uint[] c = F.Create(); + uint[] d = F.Create(); + uint[] e = F.Create(); + uint[] f = F.Create(); + uint[] g = F.Create(); + uint[] h = F.Create(); + + F.Sqr(r.z, b); + F.Mul(p.x, r.x, c); + F.Mul(p.y, r.y, d); + F.Mul(c, d, e); + F.Mul(e, -C_d, e); + //F.Apm(b, e, f, g); + F.Add(b, e, f); + F.Sub(b, e, g); + F.Add(p.x, p.y, b); + F.Add(r.x, r.y, e); + F.Mul(b, e, h); + //F.Apm(d, c, b, e); + F.Add(d, c, b); + F.Sub(d, c, e); + F.Carry(b); + F.Sub(h, b, h); + F.Mul(h, r.z, h); + F.Mul(e, r.z, e); + F.Mul(f, h, r.x); + F.Mul(e, g, r.y); + F.Mul(f, g, r.z); + } + + private static PointExt PointCopy(PointExt p) + { + PointExt r = new PointExt(); + PointCopy(p, r); + return r; + } + + private static void PointCopy(PointExt p, PointExt r) + { + F.Copy(p.x, 0, r.x, 0); + F.Copy(p.y, 0, r.y, 0); + F.Copy(p.z, 0, r.z, 0); + } + + private static void PointDouble(PointExt r) + { + uint[] b = F.Create(); + uint[] c = F.Create(); + uint[] d = F.Create(); + uint[] e = F.Create(); + uint[] h = F.Create(); + uint[] j = F.Create(); + + F.Add(r.x, r.y, b); + F.Sqr(b, b); + F.Sqr(r.x, c); + F.Sqr(r.y, d); + F.Add(c, d, e); + F.Carry(e); + F.Sqr(r.z, h); + F.Add(h, h, h); + F.Carry(h); + F.Sub(e, h, j); + F.Sub(b, e, b); + F.Sub(c, d, c); + F.Mul(b, j, r.x); + F.Mul(e, c, r.y); + F.Mul(e, j, r.z); + } + + private static void PointExtendXY(PointExt p) + { + F.One(p.z); + } + + private static void PointLookup(int block, int index, PointPrecomp p) + { + Debug.Assert(0 <= block && block < PrecompBlocks); + Debug.Assert(0 <= index && index < PrecompPoints); + + int off = block * PrecompPoints * 2 * F.Size; + + for (int i = 0; i < PrecompPoints; ++i) + { + int cond = ((i ^ index) - 1) >> 31; + F.CMov(cond, precompBase, off, p.x, 0); off += F.Size; + F.CMov(cond, precompBase, off, p.y, 0); off += F.Size; + } + } + + private static void PointLookup(uint[] x, int n, uint[] table, PointExt r) + { + // TODO This method is currently hardcoded to 4-bit windows and 8 precomputed points + + uint w = GetWindow4(x, n); + + int sign = (int)(w >> (4 - 1)) ^ 1; + int abs = ((int)w ^ -sign) & 7; + + Debug.Assert(sign == 0 || sign == 1); + Debug.Assert(0 <= abs && abs < 8); + + for (int i = 0, off = 0; i < 8; ++i) + { + int cond = ((i ^ abs) - 1) >> 31; + F.CMov(cond, table, off, r.x, 0); off += F.Size; + F.CMov(cond, table, off, r.y, 0); off += F.Size; + F.CMov(cond, table, off, r.z, 0); off += F.Size; + } + + F.CNegate(sign, r.x); + } + + private static uint[] PointPrecompute(PointExt p, int count) + { + Debug.Assert(count > 0); + + PointExt q = PointCopy(p); + PointExt d = PointCopy(q); + PointDouble(d); + + uint[] table = F.CreateTable(count * 3); + int off = 0; + + int i = 0; + for (;;) + { + F.Copy(q.x, 0, table, off); off += F.Size; + F.Copy(q.y, 0, table, off); off += F.Size; + F.Copy(q.z, 0, table, off); off += F.Size; + + if (++i == count) + break; + + PointAdd(d, q); + } + + return table; + } + + private static PointExt[] PointPrecomputeVar(PointExt p, int count) + { + Debug.Assert(count > 0); + + PointExt d = PointCopy(p); + PointDouble(d); + + PointExt[] table = new PointExt[count]; + table[0] = PointCopy(p); + for (int i = 1; i < count; ++i) + { + table[i] = PointCopy(table[i - 1]); + PointAddVar(false, d, table[i]); + } + return table; + } + + private static void PointSetNeutral(PointExt p) + { + F.Zero(p.x); + F.One(p.y); + F.One(p.z); + } + + public static void Precompute() + { + lock (precompLock) + { + if (precompBase != null) + return; + + PointExt p = new PointExt(); + F.Copy(B_x, 0, p.x, 0); + F.Copy(B_y, 0, p.y, 0); + PointExtendXY(p); + + precompBaseTable = PointPrecomputeVar(p, 1 << (WnafWidthBase - 2)); + + precompBase = F.CreateTable(PrecompBlocks * PrecompPoints * 2); + + int off = 0; + for (int b = 0; b < PrecompBlocks; ++b) + { + PointExt[] ds = new PointExt[PrecompTeeth]; + + PointExt sum = new PointExt(); + PointSetNeutral(sum); + + for (int t = 0; t < PrecompTeeth; ++t) + { + PointAddVar(true, p, sum); + PointDouble(p); + + ds[t] = PointCopy(p); + + if (b + t != PrecompBlocks + PrecompTeeth - 2) + { + for (int s = 1; s < PrecompSpacing; ++s) + { + PointDouble(p); + } + } + } + + PointExt[] points = new PointExt[PrecompPoints]; + int k = 0; + points[k++] = sum; + + for (int t = 0; t < (PrecompTeeth - 1); ++t) + { + int size = 1 << t; + for (int j = 0; j < size; ++j, ++k) + { + points[k] = PointCopy(points[k - size]); + PointAddVar(false, ds[t], points[k]); + } + } + + Debug.Assert(k == PrecompPoints); + + uint[] cs = F.CreateTable(PrecompPoints); + + // TODO[ed448] A single batch inversion across all blocks? + { + uint[] u = F.Create(); + F.Copy(points[0].z, 0, u, 0); + F.Copy(u, 0, cs, 0); + + int i = 0; + while (++i < PrecompPoints) + { + F.Mul(u, points[i].z, u); + F.Copy(u, 0, cs, i * F.Size); + } + + F.InvVar(u, u); + --i; + + uint[] t = F.Create(); + + while (i > 0) + { + int j = i--; + F.Copy(cs, i * F.Size, t, 0); + F.Mul(t, u, t); + F.Copy(t, 0, cs, j * F.Size); + F.Mul(u, points[j].z, u); + } + + F.Copy(u, 0, cs, 0); + } + + for (int i = 0; i < PrecompPoints; ++i) + { + PointExt q = points[i]; + + //F.InvVar(q.z, q.z); + F.Copy(cs, i * F.Size, q.z, 0); + + F.Mul(q.x, q.z, q.x); + F.Mul(q.y, q.z, q.y); + + //F.Normalize(q.x); + //F.Normalize(q.y); + + F.Copy(q.x, 0, precompBase, off); off += F.Size; + F.Copy(q.y, 0, precompBase, off); off += F.Size; + } + } + + Debug.Assert(off == precompBase.Length); + } + } + + private static void PruneScalar(byte[] n, int nOff, byte[] r) + { + Array.Copy(n, nOff, r, 0, ScalarBytes - 1); + + r[0] &= 0xFC; + r[ScalarBytes - 2] |= 0x80; + r[ScalarBytes - 1] = 0x00; + } + + private static byte[] ReduceScalar(byte[] n) + { + ulong x00 = Decode32(n, 0); // x00:32/-- + ulong x01 = (Decode24(n, 4) << 4); // x01:28/-- + ulong x02 = Decode32(n, 7); // x02:32/-- + ulong x03 = (Decode24(n, 11) << 4); // x03:28/-- + ulong x04 = Decode32(n, 14); // x04:32/-- + ulong x05 = (Decode24(n, 18) << 4); // x05:28/-- + ulong x06 = Decode32(n, 21); // x06:32/-- + ulong x07 = (Decode24(n, 25) << 4); // x07:28/-- + ulong x08 = Decode32(n, 28); // x08:32/-- + ulong x09 = (Decode24(n, 32) << 4); // x09:28/-- + ulong x10 = Decode32(n, 35); // x10:32/-- + ulong x11 = (Decode24(n, 39) << 4); // x11:28/-- + ulong x12 = Decode32(n, 42); // x12:32/-- + ulong x13 = (Decode24(n, 46) << 4); // x13:28/-- + ulong x14 = Decode32(n, 49); // x14:32/-- + ulong x15 = (Decode24(n, 53) << 4); // x15:28/-- + ulong x16 = Decode32(n, 56); // x16:32/-- + ulong x17 = (Decode24(n, 60) << 4); // x17:28/-- + ulong x18 = Decode32(n, 63); // x18:32/-- + ulong x19 = (Decode24(n, 67) << 4); // x19:28/-- + ulong x20 = Decode32(n, 70); // x20:32/-- + ulong x21 = (Decode24(n, 74) << 4); // x21:28/-- + ulong x22 = Decode32(n, 77); // x22:32/-- + ulong x23 = (Decode24(n, 81) << 4); // x23:28/-- + ulong x24 = Decode32(n, 84); // x24:32/-- + ulong x25 = (Decode24(n, 88) << 4); // x25:28/-- + ulong x26 = Decode32(n, 91); // x26:32/-- + ulong x27 = (Decode24(n, 95) << 4); // x27:28/-- + ulong x28 = Decode32(n, 98); // x28:32/-- + ulong x29 = (Decode24(n, 102) << 4); // x29:28/-- + ulong x30 = Decode32(n, 105); // x30:32/-- + ulong x31 = (Decode24(n, 109) << 4); // x31:28/-- + ulong x32 = Decode16(n, 112); // x32:16/-- + + // x32 += (x31 >> 28); x31 &= M28UL; + x16 += x32 * L4_0; // x16:42/-- + x17 += x32 * L4_1; // x17:41/28 + x18 += x32 * L4_2; // x18:43/42 + x19 += x32 * L4_3; // x19:44/28 + x20 += x32 * L4_4; // x20:43/-- + x21 += x32 * L4_5; // x21:44/28 + x22 += x32 * L4_6; // x22:43/41 + x23 += x32 * L4_7; // x23:45/41 + + x31 += (x30 >> 28); x30 &= M28UL; // x31:28/--, x30:28/-- + x15 += x31 * L4_0; // x15:54/-- + x16 += x31 * L4_1; // x16:53/42 + x17 += x31 * L4_2; // x17:55/54 + x18 += x31 * L4_3; // x18:56/44 + x19 += x31 * L4_4; // x19:55/-- + x20 += x31 * L4_5; // x20:56/43 + x21 += x31 * L4_6; // x21:55/53 + x22 += x31 * L4_7; // x22:57/53 + + //x30 += (x29 >> 28); x29 &= M28UL; + x14 += x30 * L4_0; // x14:54/-- + x15 += x30 * L4_1; // x15:54/53 + x16 += x30 * L4_2; // x16:56/-- + x17 += x30 * L4_3; // x17:57/-- + x18 += x30 * L4_4; // x18:56/55 + x19 += x30 * L4_5; // x19:56/55 + x20 += x30 * L4_6; // x20:57/-- + x21 += x30 * L4_7; // x21:57/56 + + x29 += (x28 >> 28); x28 &= M28UL; // x29:28/--, x28:28/-- + x13 += x29 * L4_0; // x13:54/-- + x14 += x29 * L4_1; // x14:54/53 + x15 += x29 * L4_2; // x15:56/-- + x16 += x29 * L4_3; // x16:57/-- + x17 += x29 * L4_4; // x17:57/55 + x18 += x29 * L4_5; // x18:57/55 + x19 += x29 * L4_6; // x19:57/52 + x20 += x29 * L4_7; // x20:58/52 + + //x28 += (x27 >> 28); x27 &= M28UL; + x12 += x28 * L4_0; // x12:54/-- + x13 += x28 * L4_1; // x13:54/53 + x14 += x28 * L4_2; // x14:56/-- + x15 += x28 * L4_3; // x15:57/-- + x16 += x28 * L4_4; // x16:57/55 + x17 += x28 * L4_5; // x17:58/-- + x18 += x28 * L4_6; // x18:58/-- + x19 += x28 * L4_7; // x19:58/53 + + x27 += (x26 >> 28); x26 &= M28UL; // x27:28/--, x26:28/-- + x11 += x27 * L4_0; // x11:54/-- + x12 += x27 * L4_1; // x12:54/53 + x13 += x27 * L4_2; // x13:56/-- + x14 += x27 * L4_3; // x14:57/-- + x15 += x27 * L4_4; // x15:57/55 + x16 += x27 * L4_5; // x16:58/-- + x17 += x27 * L4_6; // x17:58/56 + x18 += x27 * L4_7; // x18:59/-- + + //x26 += (x25 >> 28); x25 &= M28UL; + x10 += x26 * L4_0; // x10:54/-- + x11 += x26 * L4_1; // x11:54/53 + x12 += x26 * L4_2; // x12:56/-- + x13 += x26 * L4_3; // x13:57/-- + x14 += x26 * L4_4; // x14:57/55 + x15 += x26 * L4_5; // x15:58/-- + x16 += x26 * L4_6; // x16:58/56 + x17 += x26 * L4_7; // x17:59/-- + + x25 += (x24 >> 28); x24 &= M28UL; // x25:28/--, x24:28/-- + x09 += x25 * L4_0; // x09:54/-- + x10 += x25 * L4_1; // x10:54/53 + x11 += x25 * L4_2; // x11:56/-- + x12 += x25 * L4_3; // x12:57/-- + x13 += x25 * L4_4; // x13:57/55 + x14 += x25 * L4_5; // x14:58/-- + x15 += x25 * L4_6; // x15:58/56 + x16 += x25 * L4_7; // x16:59/-- + + x21 += (x20 >> 28); x20 &= M28UL; // x21:58/--, x20:28/-- + x22 += (x21 >> 28); x21 &= M28UL; // x22:57/54, x21:28/-- + x23 += (x22 >> 28); x22 &= M28UL; // x23:45/42, x22:28/-- + x24 += (x23 >> 28); x23 &= M28UL; // x24:28/18, x23:28/-- + + x08 += x24 * L4_0; // x08:54/-- + x09 += x24 * L4_1; // x09:55/-- + x10 += x24 * L4_2; // x10:56/46 + x11 += x24 * L4_3; // x11:57/46 + x12 += x24 * L4_4; // x12:57/55 + x13 += x24 * L4_5; // x13:58/-- + x14 += x24 * L4_6; // x14:58/56 + x15 += x24 * L4_7; // x15:59/-- + + x07 += x23 * L4_0; // x07:54/-- + x08 += x23 * L4_1; // x08:54/53 + x09 += x23 * L4_2; // x09:56/53 + x10 += x23 * L4_3; // x10:57/46 + x11 += x23 * L4_4; // x11:57/55 + x12 += x23 * L4_5; // x12:58/-- + x13 += x23 * L4_6; // x13:58/56 + x14 += x23 * L4_7; // x14:59/-- + + x06 += x22 * L4_0; // x06:54/-- + x07 += x22 * L4_1; // x07:54/53 + x08 += x22 * L4_2; // x08:56/-- + x09 += x22 * L4_3; // x09:57/53 + x10 += x22 * L4_4; // x10:57/55 + x11 += x22 * L4_5; // x11:58/-- + x12 += x22 * L4_6; // x12:58/56 + x13 += x22 * L4_7; // x13:59/-- + + x18 += (x17 >> 28); x17 &= M28UL; // x18:59/31, x17:28/-- + x19 += (x18 >> 28); x18 &= M28UL; // x19:58/54, x18:28/-- + x20 += (x19 >> 28); x19 &= M28UL; // x20:30/29, x19:28/-- + x21 += (x20 >> 28); x20 &= M28UL; // x21:28/03, x20:28/-- + + x05 += x21 * L4_0; // x05:54/-- + x06 += x21 * L4_1; // x06:55/-- + x07 += x21 * L4_2; // x07:56/31 + x08 += x21 * L4_3; // x08:57/31 + x09 += x21 * L4_4; // x09:57/56 + x10 += x21 * L4_5; // x10:58/-- + x11 += x21 * L4_6; // x11:58/56 + x12 += x21 * L4_7; // x12:59/-- + + x04 += x20 * L4_0; // x04:54/-- + x05 += x20 * L4_1; // x05:54/53 + x06 += x20 * L4_2; // x06:56/53 + x07 += x20 * L4_3; // x07:57/31 + x08 += x20 * L4_4; // x08:57/55 + x09 += x20 * L4_5; // x09:58/-- + x10 += x20 * L4_6; // x10:58/56 + x11 += x20 * L4_7; // x11:59/-- + + x03 += x19 * L4_0; // x03:54/-- + x04 += x19 * L4_1; // x04:54/53 + x05 += x19 * L4_2; // x05:56/-- + x06 += x19 * L4_3; // x06:57/53 + x07 += x19 * L4_4; // x07:57/55 + x08 += x19 * L4_5; // x08:58/-- + x09 += x19 * L4_6; // x09:58/56 + x10 += x19 * L4_7; // x10:59/-- + + x15 += (x14 >> 28); x14 &= M28UL; // x15:59/31, x14:28/-- + x16 += (x15 >> 28); x15 &= M28UL; // x16:59/32, x15:28/-- + x17 += (x16 >> 28); x16 &= M28UL; // x17:31/29, x16:28/-- + x18 += (x17 >> 28); x17 &= M28UL; // x18:28/04, x17:28/-- + + x02 += x18 * L4_0; // x02:54/-- + x03 += x18 * L4_1; // x03:55/-- + x04 += x18 * L4_2; // x04:56/32 + x05 += x18 * L4_3; // x05:57/32 + x06 += x18 * L4_4; // x06:57/56 + x07 += x18 * L4_5; // x07:58/-- + x08 += x18 * L4_6; // x08:58/56 + x09 += x18 * L4_7; // x09:59/-- + + x01 += x17 * L4_0; // x01:54/-- + x02 += x17 * L4_1; // x02:54/53 + x03 += x17 * L4_2; // x03:56/53 + x04 += x17 * L4_3; // x04:57/32 + x05 += x17 * L4_4; // x05:57/55 + x06 += x17 * L4_5; // x06:58/-- + x07 += x17 * L4_6; // x07:58/56 + x08 += x17 * L4_7; // x08:59/-- + + x16 *= 4; + x16 += (x15 >> 26); x15 &= M26UL; + x16 += 1; // x16:30/01 + + x00 += x16 * L_0; + x01 += x16 * L_1; + x02 += x16 * L_2; + x03 += x16 * L_3; + x04 += x16 * L_4; + x05 += x16 * L_5; + x06 += x16 * L_6; + x07 += x16 * L_7; + + x01 += (x00 >> 28); x00 &= M28UL; + x02 += (x01 >> 28); x01 &= M28UL; + x03 += (x02 >> 28); x02 &= M28UL; + x04 += (x03 >> 28); x03 &= M28UL; + x05 += (x04 >> 28); x04 &= M28UL; + x06 += (x05 >> 28); x05 &= M28UL; + x07 += (x06 >> 28); x06 &= M28UL; + x08 += (x07 >> 28); x07 &= M28UL; + x09 += (x08 >> 28); x08 &= M28UL; + x10 += (x09 >> 28); x09 &= M28UL; + x11 += (x10 >> 28); x10 &= M28UL; + x12 += (x11 >> 28); x11 &= M28UL; + x13 += (x12 >> 28); x12 &= M28UL; + x14 += (x13 >> 28); x13 &= M28UL; + x15 += (x14 >> 28); x14 &= M28UL; + x16 = (x15 >> 26); x15 &= M26UL; + + x16 -= 1; + + Debug.Assert(x16 == 0UL || x16 == ulong.MaxValue); + + x00 -= x16 & L_0; + x01 -= x16 & L_1; + x02 -= x16 & L_2; + x03 -= x16 & L_3; + x04 -= x16 & L_4; + x05 -= x16 & L_5; + x06 -= x16 & L_6; + x07 -= x16 & L_7; + + x01 += (ulong)((long)x00 >> 28); x00 &= M28UL; + x02 += (ulong)((long)x01 >> 28); x01 &= M28UL; + x03 += (ulong)((long)x02 >> 28); x02 &= M28UL; + x04 += (ulong)((long)x03 >> 28); x03 &= M28UL; + x05 += (ulong)((long)x04 >> 28); x04 &= M28UL; + x06 += (ulong)((long)x05 >> 28); x05 &= M28UL; + x07 += (ulong)((long)x06 >> 28); x06 &= M28UL; + x08 += (ulong)((long)x07 >> 28); x07 &= M28UL; + x09 += (ulong)((long)x08 >> 28); x08 &= M28UL; + x10 += (ulong)((long)x09 >> 28); x09 &= M28UL; + x11 += (ulong)((long)x10 >> 28); x10 &= M28UL; + x12 += (ulong)((long)x11 >> 28); x11 &= M28UL; + x13 += (ulong)((long)x12 >> 28); x12 &= M28UL; + x14 += (ulong)((long)x13 >> 28); x13 &= M28UL; + x15 += (ulong)((long)x14 >> 28); x14 &= M28UL; + + Debug.Assert(x15 >> 26 == 0UL); + + byte[] r = new byte[ScalarBytes]; + Encode56(x00 | (x01 << 28), r, 0); + Encode56(x02 | (x03 << 28), r, 7); + Encode56(x04 | (x05 << 28), r, 14); + Encode56(x06 | (x07 << 28), r, 21); + Encode56(x08 | (x09 << 28), r, 28); + Encode56(x10 | (x11 << 28), r, 35); + Encode56(x12 | (x13 << 28), r, 42); + Encode56(x14 | (x15 << 28), r, 49); + //r[ScalarBytes - 1] = 0; + return r; + } + + private static void ScalarMult(byte[] k, PointExt p, PointExt r) + { + uint[] n = new uint[ScalarUints]; + DecodeScalar(k, 0, n); + + Debug.Assert(0U == (n[0] & 3)); + Debug.Assert(1U == n[ScalarUints - 1] >> 31); + + Nat.ShiftDownBits(ScalarUints, n, 2, 0U); + + // Recode the scalar into signed-digit form + { + uint c1 = Nat.CAdd(ScalarUints, ~(int)n[0] & 1, n, L, n); Debug.Assert(c1 == 0U); + uint c2 = Nat.ShiftDownBit(ScalarUints, n, 1U); Debug.Assert(c2 == (1U << 31)); + } + + uint[] table = PointPrecompute(p, 8); + PointExt q = new PointExt(); + + PointLookup(n, 111, table, r); + + for (int w = 110; w >= 0; --w) + { + for (int i = 0; i < 4; ++i) + { + PointDouble(r); + } + + PointLookup(n, w, table, q); + PointAdd(q, r); + } + + for (int i = 0; i < 2; ++i) + { + PointDouble(r); + } + } + + private static void ScalarMultBase(byte[] k, PointExt r) + { + Precompute(); + + uint[] n = new uint[ScalarUints + 1]; + DecodeScalar(k, 0, n); + + // Recode the scalar into signed-digit form + { + n[ScalarUints] = 4U + Nat.CAdd(ScalarUints, ~(int)n[0] & 1, n, L, n); + uint c = Nat.ShiftDownBit(n.Length, n, 0); + Debug.Assert(c == (1U << 31)); + } + + PointPrecomp p = new PointPrecomp(); + + PointSetNeutral(r); + + int cOff = PrecompSpacing - 1; + for (;;) + { + int tPos = cOff; + + for (int b = 0; b < PrecompBlocks; ++b) + { + uint w = 0; + for (int t = 0; t < PrecompTeeth; ++t) + { + uint tBit = n[tPos >> 5] >> (tPos & 0x1F); + w &= ~(1U << t); + w ^= (tBit << t); + tPos += PrecompSpacing; + } + + int sign = (int)(w >> (PrecompTeeth - 1)) & 1; + int abs = ((int)w ^ -sign) & PrecompMask; + + Debug.Assert(sign == 0 || sign == 1); + Debug.Assert(0 <= abs && abs < PrecompPoints); + + PointLookup(b, abs, p); + + F.CNegate(sign, p.x); + + PointAddPrecomp(p, r); + } + + if (--cOff < 0) + break; + + PointDouble(r); + } + } + + private static void ScalarMultBaseEncoded(byte[] k, byte[] r, int rOff) + { + PointExt p = new PointExt(); + ScalarMultBase(k, p); + if (0 == EncodePoint(p, r, rOff)) + throw new InvalidOperationException(); + } + + internal static void ScalarMultBaseXY(byte[] k, int kOff, uint[] x, uint[] y) + { + byte[] n = new byte[ScalarBytes]; + PruneScalar(k, kOff, n); + + PointExt p = new PointExt(); + ScalarMultBase(n, p); + + if (0 == CheckPoint(p.x, p.y, p.z)) + throw new InvalidOperationException(); + + F.Copy(p.x, 0, x, 0); + F.Copy(p.y, 0, y, 0); + } + + private static void ScalarMultOrderVar(PointExt p, PointExt r) + { + int width = 5; + + sbyte[] ws_p = GetWnafVar(L, width); + + PointExt[] tp = PointPrecomputeVar(p, 1 << (width - 2)); + + PointSetNeutral(r); + + for (int bit = 446; ;) + { + int wp = ws_p[bit]; + if (wp != 0) + { + int sign = wp >> 31; + int index = (wp ^ sign) >> 1; + + PointAddVar((sign != 0), tp[index], r); + } + + if (--bit < 0) + break; + + PointDouble(r); + } + } + + private static void ScalarMultStrausVar(uint[] nb, uint[] np, PointExt p, PointExt r) + { + Precompute(); + + int width = 5; + + sbyte[] ws_b = GetWnafVar(nb, WnafWidthBase); + sbyte[] ws_p = GetWnafVar(np, width); + + PointExt[] tp = PointPrecomputeVar(p, 1 << (width - 2)); + + PointSetNeutral(r); + + for (int bit = 446;;) + { + int wb = ws_b[bit]; + if (wb != 0) + { + int sign = wb >> 31; + int index = (wb ^ sign) >> 1; + + PointAddVar((sign != 0), precompBaseTable[index], r); + } + + int wp = ws_p[bit]; + if (wp != 0) + { + int sign = wp >> 31; + int index = (wp ^ sign) >> 1; + + PointAddVar((sign != 0), tp[index], r); + } + + if (--bit < 0) + break; + + PointDouble(r); + } + } + + public static void Sign(byte[] sk, int skOff, byte[] ctx, byte[] m, int mOff, int mLen, byte[] sig, int sigOff) + { + byte phflag = 0x00; + + ImplSign(sk, skOff, ctx, phflag, m, mOff, mLen, sig, sigOff); + } + + public static void Sign(byte[] sk, int skOff, byte[] pk, int pkOff, byte[] ctx, byte[] m, int mOff, int mLen, byte[] sig, int sigOff) + { + byte phflag = 0x00; + + ImplSign(sk, skOff, pk, pkOff, ctx, phflag, m, mOff, mLen, sig, sigOff); + } + + public static void SignPrehash(byte[] sk, int skOff, byte[] ctx, byte[] ph, int phOff, byte[] sig, int sigOff) + { + byte phflag = 0x01; + + ImplSign(sk, skOff, ctx, phflag, ph, phOff, PrehashSize, sig, sigOff); + } + + public static void SignPrehash(byte[] sk, int skOff, byte[] pk, int pkOff, byte[] ctx, byte[] ph, int phOff, byte[] sig, int sigOff) + { + byte phflag = 0x01; + + ImplSign(sk, skOff, pk, pkOff, ctx, phflag, ph, phOff, PrehashSize, sig, sigOff); + } + + public static void SignPrehash(byte[] sk, int skOff, byte[] ctx, IXof ph, byte[] sig, int sigOff) + { + byte[] m = new byte[PrehashSize]; + if (PrehashSize != ph.DoFinal(m, 0, PrehashSize)) + throw new ArgumentException("ph"); + + byte phflag = 0x01; + + ImplSign(sk, skOff, ctx, phflag, m, 0, m.Length, sig, sigOff); + } + + public static void SignPrehash(byte[] sk, int skOff, byte[] pk, int pkOff, byte[] ctx, IXof ph, byte[] sig, int sigOff) + { + byte[] m = new byte[PrehashSize]; + if (PrehashSize != ph.DoFinal(m, 0, PrehashSize)) + throw new ArgumentException("ph"); + + byte phflag = 0x01; + + ImplSign(sk, skOff, pk, pkOff, ctx, phflag, m, 0, m.Length, sig, sigOff); + } + + public static bool ValidatePublicKeyFull(byte[] pk, int pkOff) + { + PointExt p = new PointExt(); + if (!DecodePointVar(pk, pkOff, false, p)) + return false; + + F.Normalize(p.x); + F.Normalize(p.y); + F.Normalize(p.z); + + if (IsNeutralElementVar(p.x, p.y, p.z)) + return false; + + PointExt r = new PointExt(); + ScalarMultOrderVar(p, r); + + F.Normalize(r.x); + F.Normalize(r.y); + F.Normalize(r.z); + + return IsNeutralElementVar(r.x, r.y, r.z); + } + + public static bool ValidatePublicKeyPartial(byte[] pk, int pkOff) + { + PointExt p = new PointExt(); + return DecodePointVar(pk, pkOff, false, p); + } + + public static bool Verify(byte[] sig, int sigOff, byte[] pk, int pkOff, byte[] ctx, byte[] m, int mOff, int mLen) + { + byte phflag = 0x00; + + return ImplVerify(sig, sigOff, pk, pkOff, ctx, phflag, m, mOff, mLen); + } + + public static bool VerifyPrehash(byte[] sig, int sigOff, byte[] pk, int pkOff, byte[] ctx, byte[] ph, int phOff) + { + byte phflag = 0x01; + + return ImplVerify(sig, sigOff, pk, pkOff, ctx, phflag, ph, phOff, PrehashSize); + } + + public static bool VerifyPrehash(byte[] sig, int sigOff, byte[] pk, int pkOff, byte[] ctx, IXof ph) + { + byte[] m = new byte[PrehashSize]; + if (PrehashSize != ph.DoFinal(m, 0, PrehashSize)) + throw new ArgumentException("ph"); + + byte phflag = 0x01; + + return ImplVerify(sig, sigOff, pk, pkOff, ctx, phflag, m, 0, m.Length); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/rfc8032/Ed448.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/rfc8032/Ed448.cs.meta new file mode 100644 index 0000000..9ee834a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/ec/rfc8032/Ed448.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7b6617c48dd88024794ec8d8e1350af7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field.meta new file mode 100644 index 0000000..3fe56ea --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 196617a41943cb040b57d52140fbd668 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field/FiniteFields.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field/FiniteFields.cs new file mode 100644 index 0000000..4aeb100 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field/FiniteFields.cs @@ -0,0 +1,54 @@ +using System; + +namespace Org.BouncyCastle.Math.Field +{ + public abstract class FiniteFields + { + internal static readonly IFiniteField GF_2 = new PrimeField(BigInteger.ValueOf(2)); + internal static readonly IFiniteField GF_3 = new PrimeField(BigInteger.ValueOf(3)); + + public static IPolynomialExtensionField GetBinaryExtensionField(int[] exponents) + { + if (exponents[0] != 0) + { + throw new ArgumentException("Irreducible polynomials in GF(2) must have constant term", "exponents"); + } + for (int i = 1; i < exponents.Length; ++i) + { + if (exponents[i] <= exponents[i - 1]) + { + throw new ArgumentException("Polynomial exponents must be monotonically increasing", "exponents"); + } + } + + return new GenericPolynomialExtensionField(GF_2, new GF2Polynomial(exponents)); + } + + // public static IPolynomialExtensionField GetTernaryExtensionField(Term[] terms) + // { + // return new GenericPolynomialExtensionField(GF_3, new GF3Polynomial(terms)); + // } + + public static IFiniteField GetPrimeField(BigInteger characteristic) + { + int bitLength = characteristic.BitLength; + if (characteristic.SignValue <= 0 || bitLength < 2) + { + throw new ArgumentException("Must be >= 2", "characteristic"); + } + + if (bitLength < 3) + { + switch (characteristic.IntValue) + { + case 2: + return GF_2; + case 3: + return GF_3; + } + } + + return new PrimeField(characteristic); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field/FiniteFields.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field/FiniteFields.cs.meta new file mode 100644 index 0000000..f3bbfac --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field/FiniteFields.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1934c35b3048ef644af1ebd1fbc2cac6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field/GF2Polynomial.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field/GF2Polynomial.cs new file mode 100644 index 0000000..c062d50 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field/GF2Polynomial.cs @@ -0,0 +1,46 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math.Field +{ + internal class GF2Polynomial + : IPolynomial + { + protected readonly int[] exponents; + + internal GF2Polynomial(int[] exponents) + { + this.exponents = Arrays.Clone(exponents); + } + + public virtual int Degree + { + get { return exponents[exponents.Length - 1]; } + } + + public virtual int[] GetExponentsPresent() + { + return Arrays.Clone(exponents); + } + + public override bool Equals(object obj) + { + if (this == obj) + { + return true; + } + GF2Polynomial other = obj as GF2Polynomial; + if (null == other) + { + return false; + } + return Arrays.AreEqual(exponents, other.exponents); + } + + public override int GetHashCode() + { + return Arrays.GetHashCode(exponents); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field/GF2Polynomial.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field/GF2Polynomial.cs.meta new file mode 100644 index 0000000..a63ea82 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field/GF2Polynomial.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cdfe7b0df9913474394076c39eec44af +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field/GenericPolynomialExtensionField.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field/GenericPolynomialExtensionField.cs new file mode 100644 index 0000000..13ef571 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field/GenericPolynomialExtensionField.cs @@ -0,0 +1,63 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math.Field +{ + internal class GenericPolynomialExtensionField + : IPolynomialExtensionField + { + protected readonly IFiniteField subfield; + protected readonly IPolynomial minimalPolynomial; + + internal GenericPolynomialExtensionField(IFiniteField subfield, IPolynomial polynomial) + { + this.subfield = subfield; + this.minimalPolynomial = polynomial; + } + + public virtual BigInteger Characteristic + { + get { return subfield.Characteristic; } + } + + public virtual int Dimension + { + get { return subfield.Dimension * minimalPolynomial.Degree; } + } + + public virtual IFiniteField Subfield + { + get { return subfield; } + } + + public virtual int Degree + { + get { return minimalPolynomial.Degree; } + } + + public virtual IPolynomial MinimalPolynomial + { + get { return minimalPolynomial; } + } + + public override bool Equals(object obj) + { + if (this == obj) + { + return true; + } + GenericPolynomialExtensionField other = obj as GenericPolynomialExtensionField; + if (null == other) + { + return false; + } + return subfield.Equals(other.subfield) && minimalPolynomial.Equals(other.minimalPolynomial); + } + + public override int GetHashCode() + { + return subfield.GetHashCode() ^ Integers.RotateLeft(minimalPolynomial.GetHashCode(), 16); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field/GenericPolynomialExtensionField.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field/GenericPolynomialExtensionField.cs.meta new file mode 100644 index 0000000..d927a07 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field/GenericPolynomialExtensionField.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 998cf5579dc38a746a7fd7ca856b6e6d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field/IExtensionField.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field/IExtensionField.cs new file mode 100644 index 0000000..17f45c1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field/IExtensionField.cs @@ -0,0 +1,12 @@ +using System; + +namespace Org.BouncyCastle.Math.Field +{ + public interface IExtensionField + : IFiniteField + { + IFiniteField Subfield { get; } + + int Degree { get; } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field/IExtensionField.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field/IExtensionField.cs.meta new file mode 100644 index 0000000..81d69ac --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field/IExtensionField.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 951ea553f11a756409a9ea16103842cf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field/IFiniteField.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field/IFiniteField.cs new file mode 100644 index 0000000..b618be7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field/IFiniteField.cs @@ -0,0 +1,11 @@ +using System; + +namespace Org.BouncyCastle.Math.Field +{ + public interface IFiniteField + { + BigInteger Characteristic { get; } + + int Dimension { get; } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field/IFiniteField.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field/IFiniteField.cs.meta new file mode 100644 index 0000000..72b7432 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field/IFiniteField.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0e2344878c7b4b4469b864cc6c0a7451 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field/IPolynomial.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field/IPolynomial.cs new file mode 100644 index 0000000..ad6dfb6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field/IPolynomial.cs @@ -0,0 +1,15 @@ +using System; + +namespace Org.BouncyCastle.Math.Field +{ + public interface IPolynomial + { + int Degree { get; } + + //BigInteger[] GetCoefficients(); + + int[] GetExponentsPresent(); + + //Term[] GetNonZeroTerms(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field/IPolynomial.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field/IPolynomial.cs.meta new file mode 100644 index 0000000..ee929b1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field/IPolynomial.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 82d14ae7761608c4a9d53c2e324088af +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field/IPolynomialExtensionField.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field/IPolynomialExtensionField.cs new file mode 100644 index 0000000..3818c18 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field/IPolynomialExtensionField.cs @@ -0,0 +1,10 @@ +using System; + +namespace Org.BouncyCastle.Math.Field +{ + public interface IPolynomialExtensionField + : IExtensionField + { + IPolynomial MinimalPolynomial { get; } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field/IPolynomialExtensionField.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field/IPolynomialExtensionField.cs.meta new file mode 100644 index 0000000..185497f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field/IPolynomialExtensionField.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 85daf986ab6a8f446ae59e96280d9c80 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field/PrimeField.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field/PrimeField.cs new file mode 100644 index 0000000..f6ba629 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field/PrimeField.cs @@ -0,0 +1,44 @@ +using System; + +namespace Org.BouncyCastle.Math.Field +{ + internal class PrimeField + : IFiniteField + { + protected readonly BigInteger characteristic; + + internal PrimeField(BigInteger characteristic) + { + this.characteristic = characteristic; + } + + public virtual BigInteger Characteristic + { + get { return characteristic; } + } + + public virtual int Dimension + { + get { return 1; } + } + + public override bool Equals(object obj) + { + if (this == obj) + { + return true; + } + PrimeField other = obj as PrimeField; + if (null == other) + { + return false; + } + return characteristic.Equals(other.characteristic); + } + + public override int GetHashCode() + { + return characteristic.GetHashCode(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field/PrimeField.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field/PrimeField.cs.meta new file mode 100644 index 0000000..dd1e887 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/field/PrimeField.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 477e525afb9e24b4baf602e73bf58509 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw.meta new file mode 100644 index 0000000..03fb7ad --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 1fd37533c34328d4b8ae460b033dc1c7 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Bits.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Bits.cs new file mode 100644 index 0000000..d344e16 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Bits.cs @@ -0,0 +1,29 @@ +using System; + +namespace Org.BouncyCastle.Math.Raw +{ + internal abstract class Bits + { + internal static uint BitPermuteStep(uint x, uint m, int s) + { + uint t = (x ^ (x >> s)) & m; + return (t ^ (t << s)) ^ x; + } + + internal static ulong BitPermuteStep(ulong x, ulong m, int s) + { + ulong t = (x ^ (x >> s)) & m; + return (t ^ (t << s)) ^ x; + } + + internal static uint BitPermuteStepSimple(uint x, uint m, int s) + { + return ((x & m) << s) | ((x >> s) & m); + } + + internal static ulong BitPermuteStepSimple(ulong x, ulong m, int s) + { + return ((x & m) << s) | ((x >> s) & m); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Bits.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Bits.cs.meta new file mode 100644 index 0000000..6b23cae --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Bits.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1edc4b235624ffb4d92a81041947ef02 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Interleave.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Interleave.cs new file mode 100644 index 0000000..8e98eac --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Interleave.cs @@ -0,0 +1,178 @@ +using System; + +namespace Org.BouncyCastle.Math.Raw +{ + internal abstract class Interleave + { + private const ulong M32 = 0x55555555UL; + private const ulong M64 = 0x5555555555555555UL; + private const ulong M64R = 0xAAAAAAAAAAAAAAAAUL; + + /* + * This expands 8 bit indices into 16 bit contents (high bit 14), by inserting 0s between bits. + * In a binary field, this operation is the same as squaring an 8 bit number. + */ + //private static readonly ushort[] INTERLEAVE2_TABLE = new ushort[] + //{ + // 0x0000, 0x0001, 0x0004, 0x0005, 0x0010, 0x0011, 0x0014, 0x0015, + // 0x0040, 0x0041, 0x0044, 0x0045, 0x0050, 0x0051, 0x0054, 0x0055, + // 0x0100, 0x0101, 0x0104, 0x0105, 0x0110, 0x0111, 0x0114, 0x0115, + // 0x0140, 0x0141, 0x0144, 0x0145, 0x0150, 0x0151, 0x0154, 0x0155, + // 0x0400, 0x0401, 0x0404, 0x0405, 0x0410, 0x0411, 0x0414, 0x0415, + // 0x0440, 0x0441, 0x0444, 0x0445, 0x0450, 0x0451, 0x0454, 0x0455, + // 0x0500, 0x0501, 0x0504, 0x0505, 0x0510, 0x0511, 0x0514, 0x0515, + // 0x0540, 0x0541, 0x0544, 0x0545, 0x0550, 0x0551, 0x0554, 0x0555, + // 0x1000, 0x1001, 0x1004, 0x1005, 0x1010, 0x1011, 0x1014, 0x1015, + // 0x1040, 0x1041, 0x1044, 0x1045, 0x1050, 0x1051, 0x1054, 0x1055, + // 0x1100, 0x1101, 0x1104, 0x1105, 0x1110, 0x1111, 0x1114, 0x1115, + // 0x1140, 0x1141, 0x1144, 0x1145, 0x1150, 0x1151, 0x1154, 0x1155, + // 0x1400, 0x1401, 0x1404, 0x1405, 0x1410, 0x1411, 0x1414, 0x1415, + // 0x1440, 0x1441, 0x1444, 0x1445, 0x1450, 0x1451, 0x1454, 0x1455, + // 0x1500, 0x1501, 0x1504, 0x1505, 0x1510, 0x1511, 0x1514, 0x1515, + // 0x1540, 0x1541, 0x1544, 0x1545, 0x1550, 0x1551, 0x1554, 0x1555, + // 0x4000, 0x4001, 0x4004, 0x4005, 0x4010, 0x4011, 0x4014, 0x4015, + // 0x4040, 0x4041, 0x4044, 0x4045, 0x4050, 0x4051, 0x4054, 0x4055, + // 0x4100, 0x4101, 0x4104, 0x4105, 0x4110, 0x4111, 0x4114, 0x4115, + // 0x4140, 0x4141, 0x4144, 0x4145, 0x4150, 0x4151, 0x4154, 0x4155, + // 0x4400, 0x4401, 0x4404, 0x4405, 0x4410, 0x4411, 0x4414, 0x4415, + // 0x4440, 0x4441, 0x4444, 0x4445, 0x4450, 0x4451, 0x4454, 0x4455, + // 0x4500, 0x4501, 0x4504, 0x4505, 0x4510, 0x4511, 0x4514, 0x4515, + // 0x4540, 0x4541, 0x4544, 0x4545, 0x4550, 0x4551, 0x4554, 0x4555, + // 0x5000, 0x5001, 0x5004, 0x5005, 0x5010, 0x5011, 0x5014, 0x5015, + // 0x5040, 0x5041, 0x5044, 0x5045, 0x5050, 0x5051, 0x5054, 0x5055, + // 0x5100, 0x5101, 0x5104, 0x5105, 0x5110, 0x5111, 0x5114, 0x5115, + // 0x5140, 0x5141, 0x5144, 0x5145, 0x5150, 0x5151, 0x5154, 0x5155, + // 0x5400, 0x5401, 0x5404, 0x5405, 0x5410, 0x5411, 0x5414, 0x5415, + // 0x5440, 0x5441, 0x5444, 0x5445, 0x5450, 0x5451, 0x5454, 0x5455, + // 0x5500, 0x5501, 0x5504, 0x5505, 0x5510, 0x5511, 0x5514, 0x5515, + // 0x5540, 0x5541, 0x5544, 0x5545, 0x5550, 0x5551, 0x5554, 0x5555 + //}; + + internal static uint Expand8to16(uint x) + { + x &= 0xFFU; + x = (x | (x << 4)) & 0x0F0FU; + x = (x | (x << 2)) & 0x3333U; + x = (x | (x << 1)) & 0x5555U; + return x; + } + + internal static uint Expand16to32(uint x) + { + x &= 0xFFFFU; + x = (x | (x << 8)) & 0x00FF00FFU; + x = (x | (x << 4)) & 0x0F0F0F0FU; + x = (x | (x << 2)) & 0x33333333U; + x = (x | (x << 1)) & 0x55555555U; + return x; + } + + internal static ulong Expand32to64(uint x) + { + // "shuffle" low half to even bits and high half to odd bits + x = Bits.BitPermuteStep(x, 0x0000FF00U, 8); + x = Bits.BitPermuteStep(x, 0x00F000F0U, 4); + x = Bits.BitPermuteStep(x, 0x0C0C0C0CU, 2); + x = Bits.BitPermuteStep(x, 0x22222222U, 1); + + return ((x >> 1) & M32) << 32 | (x & M32); + } + + internal static void Expand64To128(ulong x, ulong[] z, int zOff) + { + // "shuffle" low half to even bits and high half to odd bits + x = Bits.BitPermuteStep(x, 0x00000000FFFF0000UL, 16); + x = Bits.BitPermuteStep(x, 0x0000FF000000FF00UL, 8); + x = Bits.BitPermuteStep(x, 0x00F000F000F000F0UL, 4); + x = Bits.BitPermuteStep(x, 0x0C0C0C0C0C0C0C0CUL, 2); + x = Bits.BitPermuteStep(x, 0x2222222222222222UL, 1); + + z[zOff ] = (x ) & M64; + z[zOff + 1] = (x >> 1) & M64; + } + + internal static void Expand64To128(ulong[] xs, int xsOff, int xsLen, ulong[] zs, int zsOff) + { + for (int i = 0; i < xsLen; ++i) + { + Expand64To128(xs[xsOff + i], zs, zsOff); + zsOff += 2; + } + } + + internal static void Expand64To128Rev(ulong x, ulong[] z, int zOff) + { + // "shuffle" low half to even bits and high half to odd bits + x = Bits.BitPermuteStep(x, 0x00000000FFFF0000UL, 16); + x = Bits.BitPermuteStep(x, 0x0000FF000000FF00UL, 8); + x = Bits.BitPermuteStep(x, 0x00F000F000F000F0UL, 4); + x = Bits.BitPermuteStep(x, 0x0C0C0C0C0C0C0C0CUL, 2); + x = Bits.BitPermuteStep(x, 0x2222222222222222UL, 1); + + z[zOff] = (x ) & M64R; + z[zOff + 1] = (x << 1) & M64R; + } + + internal static uint Shuffle(uint x) + { + // "shuffle" low half to even bits and high half to odd bits + x = Bits.BitPermuteStep(x, 0x0000FF00U, 8); + x = Bits.BitPermuteStep(x, 0x00F000F0U, 4); + x = Bits.BitPermuteStep(x, 0x0C0C0C0CU, 2); + x = Bits.BitPermuteStep(x, 0x22222222U, 1); + return x; + } + + internal static ulong Shuffle(ulong x) + { + // "shuffle" low half to even bits and high half to odd bits + x = Bits.BitPermuteStep(x, 0x00000000FFFF0000UL, 16); + x = Bits.BitPermuteStep(x, 0x0000FF000000FF00UL, 8); + x = Bits.BitPermuteStep(x, 0x00F000F000F000F0UL, 4); + x = Bits.BitPermuteStep(x, 0x0C0C0C0C0C0C0C0CUL, 2); + x = Bits.BitPermuteStep(x, 0x2222222222222222UL, 1); + return x; + } + + internal static uint Shuffle2(uint x) + { + // "shuffle" (twice) low half to even bits and high half to odd bits + x = Bits.BitPermuteStep(x, 0x00AA00AAU, 7); + x = Bits.BitPermuteStep(x, 0x0000CCCCU, 14); + x = Bits.BitPermuteStep(x, 0x00F000F0U, 4); + x = Bits.BitPermuteStep(x, 0x0000FF00U, 8); + return x; + } + + internal static uint Unshuffle(uint x) + { + // "unshuffle" even bits to low half and odd bits to high half + x = Bits.BitPermuteStep(x, 0x22222222U, 1); + x = Bits.BitPermuteStep(x, 0x0C0C0C0CU, 2); + x = Bits.BitPermuteStep(x, 0x00F000F0U, 4); + x = Bits.BitPermuteStep(x, 0x0000FF00U, 8); + return x; + } + + internal static ulong Unshuffle(ulong x) + { + // "unshuffle" even bits to low half and odd bits to high half + x = Bits.BitPermuteStep(x, 0x2222222222222222UL, 1); + x = Bits.BitPermuteStep(x, 0x0C0C0C0C0C0C0C0CUL, 2); + x = Bits.BitPermuteStep(x, 0x00F000F000F000F0UL, 4); + x = Bits.BitPermuteStep(x, 0x0000FF000000FF00UL, 8); + x = Bits.BitPermuteStep(x, 0x00000000FFFF0000UL, 16); + return x; + } + + internal static uint Unshuffle2(uint x) + { + // "unshuffle" (twice) even bits to low half and odd bits to high half + x = Bits.BitPermuteStep(x, 0x0000FF00U, 8); + x = Bits.BitPermuteStep(x, 0x00F000F0U, 4); + x = Bits.BitPermuteStep(x, 0x0000CCCCU, 14); + x = Bits.BitPermuteStep(x, 0x00AA00AAU, 7); + return x; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Interleave.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Interleave.cs.meta new file mode 100644 index 0000000..812a7d1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Interleave.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 38ec87f0bb2852e4d9010429af0437a8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Mod.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Mod.cs new file mode 100644 index 0000000..49ac913 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Mod.cs @@ -0,0 +1,604 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Math.Raw +{ + /* + * Modular inversion as implemented in this class is based on the paper "Fast constant-time gcd + * computation and modular inversion" by Daniel J. Bernstein and Bo-Yin Yang. + */ + + internal abstract class Mod + { + private static readonly SecureRandom RandomSource = new SecureRandom(); + + private const int M30 = 0x3FFFFFFF; + private const ulong M32UL = 0xFFFFFFFFUL; + + public static void CheckedModOddInverse(uint[] m, uint[] x, uint[] z) + { + if (0 == ModOddInverse(m, x, z)) + throw new ArithmeticException("Inverse does not exist."); + } + + public static void CheckedModOddInverseVar(uint[] m, uint[] x, uint[] z) + { + if (!ModOddInverseVar(m, x, z)) + throw new ArithmeticException("Inverse does not exist."); + } + + public static uint Inverse32(uint d) + { + Debug.Assert((d & 1) == 1); + + //int x = d + (((d + 1) & 4) << 1); // d.x == 1 mod 2**4 + uint x = d; // d.x == 1 mod 2**3 + x *= 2 - d * x; // d.x == 1 mod 2**6 + x *= 2 - d * x; // d.x == 1 mod 2**12 + x *= 2 - d * x; // d.x == 1 mod 2**24 + x *= 2 - d * x; // d.x == 1 mod 2**48 + Debug.Assert(d * x == 1); + return x; + } + + public static uint ModOddInverse(uint[] m, uint[] x, uint[] z) + { + int len32 = m.Length; + Debug.Assert(len32 > 0); + Debug.Assert((m[0] & 1) != 0); + Debug.Assert(m[len32 - 1] != 0); + + int bits = (len32 << 5) - Integers.NumberOfLeadingZeros((int)m[len32 - 1]); + int len30 = (bits + 29) / 30; + + int[] t = new int[4]; + int[] D = new int[len30]; + int[] E = new int[len30]; + int[] F = new int[len30]; + int[] G = new int[len30]; + int[] M = new int[len30]; + + E[0] = 1; + Encode30(bits, x, 0, G, 0); + Encode30(bits, m, 0, M, 0); + Array.Copy(M, 0, F, 0, len30); + + int eta = -1; + int m0Inv32 = (int)Inverse32((uint)M[0]); + int maxDivsteps = GetMaximumDivsteps(bits); + + for (int divSteps = 0; divSteps < maxDivsteps; divSteps += 30) + { + eta = Divsteps30(eta, F[0], G[0], t); + UpdateDE30(len30, D, E, t, m0Inv32, M); + UpdateFG30(len30, F, G, t); + } + + int signF = F[len30 - 1] >> 31; + CNegate30(len30, signF, F); + + /* + * D is in the range (-2.M, M). First, conditionally add M if D is negative, to bring it + * into the range (-M, M). Then normalize by conditionally negating (according to signF) + * and/or then adding M, to bring it into the range [0, M). + */ + CNormalize30(len30, signF, D, M); + + Decode30(bits, D, 0, z, 0); + Debug.Assert(0 != Nat.LessThan(len32, z, m)); + + return (uint)(EqualTo(len30, F, 1) & EqualToZero(len30, G)); + } + + public static bool ModOddInverseVar(uint[] m, uint[] x, uint[] z) + { + int len32 = m.Length; + Debug.Assert(len32 > 0); + Debug.Assert((m[0] & 1) != 0); + Debug.Assert(m[len32 - 1] != 0); + + int bits = (len32 << 5) - Integers.NumberOfLeadingZeros((int)m[len32 - 1]); + int len30 = (bits + 29) / 30; + + int[] t = new int[4]; + int[] D = new int[len30]; + int[] E = new int[len30]; + int[] F = new int[len30]; + int[] G = new int[len30]; + int[] M = new int[len30]; + + E[0] = 1; + Encode30(bits, x, 0, G, 0); + Encode30(bits, m, 0, M, 0); + Array.Copy(M, 0, F, 0, len30); + + int clzG = Integers.NumberOfLeadingZeros(G[len30 - 1] | 1) - (len30 * 30 + 2 - bits); + int eta = -1 - clzG; + int lenDE = len30, lenFG = len30; + int m0Inv32 = (int)Inverse32((uint)M[0]); + int maxDivsteps = GetMaximumDivsteps(bits); + + int divsteps = 0; + while (!IsZero(lenFG, G)) + { + if (divsteps >= maxDivsteps) + return false; + + divsteps += 30; + + eta = Divsteps30Var(eta, F[0], G[0], t); + UpdateDE30(lenDE, D, E, t, m0Inv32, M); + UpdateFG30(lenFG, F, G, t); + + int fn = F[lenFG - 1]; + int gn = G[lenFG - 1]; + + int cond = (lenFG - 2) >> 31; + cond |= fn ^ (fn >> 31); + cond |= gn ^ (gn >> 31); + + if (cond == 0) + { + F[lenFG - 2] |= fn << 30; + G[lenFG - 2] |= gn << 30; + --lenFG; + } + } + + int signF = F[lenFG - 1] >> 31; + + /* + * D is in the range (-2.M, M). First, conditionally add M if D is negative, to bring it + * into the range (-M, M). Then normalize by conditionally negating (according to signF) + * and/or then adding M, to bring it into the range [0, M). + */ + int signD = D[lenDE - 1] >> 31; + if (signD < 0) + { + signD = Add30(lenDE, D, M); + } + if (signF < 0) + { + signD = Negate30(lenDE, D); + signF = Negate30(lenFG, F); + } + Debug.Assert(0 == signF); + + if (!IsOne(lenFG, F)) + return false; + + if (signD < 0) + { + signD = Add30(lenDE, D, M); + } + Debug.Assert(0 == signD); + + Decode30(bits, D, 0, z, 0); + Debug.Assert(!Nat.Gte(len32, z, m)); + + return true; + } + + public static uint[] Random(uint[] p) + { + int len = p.Length; + uint[] s = Nat.Create(len); + + uint m = p[len - 1]; + m |= m >> 1; + m |= m >> 2; + m |= m >> 4; + m |= m >> 8; + m |= m >> 16; + + do + { + byte[] bytes = new byte[len << 2]; + RandomSource.NextBytes(bytes); + Pack.BE_To_UInt32(bytes, 0, s); + s[len - 1] &= m; + } + while (Nat.Gte(len, s, p)); + + return s; + } + + private static int Add30(int len30, int[] D, int[] M) + { + Debug.Assert(len30 > 0); + Debug.Assert(D.Length >= len30); + Debug.Assert(M.Length >= len30); + + int c = 0, last = len30 - 1; + for (int i = 0; i < last; ++i) + { + c += D[i] + M[i]; + D[i] = c & M30; c >>= 30; + } + c += D[last] + M[last]; + D[last] = c; c >>= 30; + return c; + } + + private static void CNegate30(int len30, int cond, int[] D) + { + Debug.Assert(len30 > 0); + Debug.Assert(D.Length >= len30); + + int c = 0, last = len30 - 1; + for (int i = 0; i < last; ++i) + { + c += (D[i] ^ cond) - cond; + D[i] = c & M30; c >>= 30; + } + c += (D[last] ^ cond) - cond; + D[last] = c; + } + + private static void CNormalize30(int len30, int condNegate, int[] D, int[] M) + { + Debug.Assert(len30 > 0); + Debug.Assert(D.Length >= len30); + Debug.Assert(M.Length >= len30); + + int last = len30 - 1; + + { + int c = 0, condAdd = D[last] >> 31; + for (int i = 0; i < last; ++i) + { + int di = D[i] + (M[i] & condAdd); + di = (di ^ condNegate) - condNegate; + c += di; D[i] = c & M30; c >>= 30; + } + { + int di = D[last] + (M[last] & condAdd); + di = (di ^ condNegate) - condNegate; + c += di; D[last] = c; + } + } + + { + int c = 0, condAdd = D[last] >> 31; + for (int i = 0; i < last; ++i) + { + int di = D[i] + (M[i] & condAdd); + c += di; D[i] = c & M30; c >>= 30; + } + { + int di = D[last] + (M[last] & condAdd); + c += di; D[last] = c; + } + Debug.Assert(c >> 30 == 0); + } + } + + private static void Decode30(int bits, int[] x, int xOff, uint[] z, int zOff) + { + Debug.Assert(bits > 0); + + int avail = 0; + ulong data = 0L; + + while (bits > 0) + { + while (avail < System.Math.Min(32, bits)) + { + data |= (ulong)x[xOff++] << avail; + avail += 30; + } + + z[zOff++] = (uint)data; data >>= 32; + avail -= 32; + bits -= 32; + } + } + + private static int Divsteps30(int eta, int f0, int g0, int[] t) + { + int u = 1, v = 0, q = 0, r = 1; + int f = f0, g = g0; + + for (int i = 0; i < 30; ++i) + { + Debug.Assert((f & 1) == 1); + Debug.Assert((u * f0 + v * g0) == f << i); + Debug.Assert((q * f0 + r * g0) == g << i); + + int c1 = eta >> 31; + int c2 = -(g & 1); + + int x = (f ^ c1) - c1; + int y = (u ^ c1) - c1; + int z = (v ^ c1) - c1; + + g += x & c2; + q += y & c2; + r += z & c2; + + c1 &= c2; + eta = (eta ^ c1) - (c1 + 1); + + f += g & c1; + u += q & c1; + v += r & c1; + + g >>= 1; + u <<= 1; + v <<= 1; + } + + t[0] = u; + t[1] = v; + t[2] = q; + t[3] = r; + + return eta; + } + + private static int Divsteps30Var(int eta, int f0, int g0, int[] t) + { + int u = 1, v = 0, q = 0, r = 1; + int f = f0, g = g0, m, w, x, y, z; + int i = 30, limit, zeros; + + for (; ; ) + { + // Use a sentinel bit to count zeros only up to i. + zeros = Integers.NumberOfTrailingZeros(g | (-1 << i)); + + g >>= zeros; + u <<= zeros; + v <<= zeros; + eta -= zeros; + i -= zeros; + + if (i <= 0) + break; + + Debug.Assert((f & 1) == 1); + Debug.Assert((g & 1) == 1); + Debug.Assert((u * f0 + v * g0) == f << (30 - i)); + Debug.Assert((q * f0 + r * g0) == g << (30 - i)); + + if (eta < 0) + { + eta = -eta; + x = f; f = g; g = -x; + y = u; u = q; q = -y; + z = v; v = r; r = -z; + + // Handle up to 6 divsteps at once, subject to eta and i. + limit = (eta + 1) > i ? i : (eta + 1); + m = (int)((uint.MaxValue >> (32 - limit)) & 63U); + + w = (f * g * (f * f - 2)) & m; + } + else + { + // Handle up to 4 divsteps at once, subject to eta and i. + limit = (eta + 1) > i ? i : (eta + 1); + m = (int)((uint.MaxValue >> (32 - limit)) & 15U); + + w = f + (((f + 1) & 4) << 1); + w = (-w * g) & m; + } + + g += f * w; + q += u * w; + r += v * w; + + Debug.Assert((g & m) == 0); + } + + t[0] = u; + t[1] = v; + t[2] = q; + t[3] = r; + + return eta; + } + + private static void Encode30(int bits, uint[] x, int xOff, int[] z, int zOff) + { + Debug.Assert(bits > 0); + + int avail = 0; + ulong data = 0UL; + + while (bits > 0) + { + if (avail < System.Math.Min(30, bits)) + { + data |= (x[xOff++] & M32UL) << avail; + avail += 32; + } + + z[zOff++] = (int)data & M30; data >>= 30; + avail -= 30; + bits -= 30; + } + } + + private static int EqualTo(int len, int[] x, int y) + { + int d = x[0] ^ y; + for (int i = 1; i < len; ++i) + { + d |= x[i]; + } + d = (int)((uint)d >> 1) | (d & 1); + return (d - 1) >> 31; + } + + private static int EqualToZero(int len, int[] x) + { + int d = 0; + for (int i = 0; i < len; ++i) + { + d |= x[i]; + } + d = (int)((uint)d >> 1) | (d & 1); + return (d - 1) >> 31; + } + + private static int GetMaximumDivsteps(int bits) + { + return (49 * bits + (bits < 46 ? 80 : 47)) / 17; + } + + private static bool IsOne(int len, int[] x) + { + if (x[0] != 1) + { + return false; + } + for (int i = 1; i < len; ++i) + { + if (x[i] != 0) + { + return false; + } + } + return true; + } + + private static bool IsZero(int len, int[] x) + { + if (x[0] != 0) + { + return false; + } + for (int i = 1; i < len; ++i) + { + if (x[i] != 0) + { + return false; + } + } + return true; + } + + private static int Negate30(int len30, int[] D) + { + Debug.Assert(len30 > 0); + Debug.Assert(D.Length >= len30); + + int c = 0, last = len30 - 1; + for (int i = 0; i < last; ++i) + { + c -= D[i]; + D[i] = c & M30; c >>= 30; + } + c -= D[last]; + D[last] = c; c >>= 30; + return c; + } + + private static void UpdateDE30(int len30, int[] D, int[] E, int[] t, int m0Inv32, int[] M) + { + Debug.Assert(len30 > 0); + Debug.Assert(D.Length >= len30); + Debug.Assert(E.Length >= len30); + Debug.Assert(M.Length >= len30); + Debug.Assert(m0Inv32 * M[0] == 1); + + int u = t[0], v = t[1], q = t[2], r = t[3]; + int di, ei, i, md, me, mi, sd, se; + long cd, ce; + + /* + * We accept D (E) in the range (-2.M, M) and conceptually add the modulus to the input + * value if it is initially negative. Instead of adding it explicitly, we add u and/or v (q + * and/or r) to md (me). + */ + sd = D[len30 - 1] >> 31; + se = E[len30 - 1] >> 31; + + md = (u & sd) + (v & se); + me = (q & sd) + (r & se); + + mi = M[0]; + di = D[0]; + ei = E[0]; + + cd = (long)u * di + (long)v * ei; + ce = (long)q * di + (long)r * ei; + + /* + * Subtract from md/me an extra term in the range [0, 2^30) such that the low 30 bits of the + * intermediate D/E values will be 0, allowing clean division by 2^30. The final D/E are + * thus in the range (-2.M, M), consistent with the input constraint. + */ + md -= (m0Inv32 * (int)cd + md) & M30; + me -= (m0Inv32 * (int)ce + me) & M30; + + cd += (long)mi * md; + ce += (long)mi * me; + + Debug.Assert(((int)cd & M30) == 0); + Debug.Assert(((int)ce & M30) == 0); + + cd >>= 30; + ce >>= 30; + + for (i = 1; i < len30; ++i) + { + mi = M[i]; + di = D[i]; + ei = E[i]; + + cd += (long)u * di + (long)v * ei + (long)mi * md; + ce += (long)q * di + (long)r * ei + (long)mi * me; + + D[i - 1] = (int)cd & M30; cd >>= 30; + E[i - 1] = (int)ce & M30; ce >>= 30; + } + + D[len30 - 1] = (int)cd; + E[len30 - 1] = (int)ce; + } + + private static void UpdateFG30(int len30, int[] F, int[] G, int[] t) + { + Debug.Assert(len30 > 0); + Debug.Assert(F.Length >= len30); + Debug.Assert(G.Length >= len30); + + int u = t[0], v = t[1], q = t[2], r = t[3]; + int fi, gi, i; + long cf, cg; + + fi = F[0]; + gi = G[0]; + + cf = (long)u * fi + (long)v * gi; + cg = (long)q * fi + (long)r * gi; + + Debug.Assert(((int)cf & M30) == 0); + Debug.Assert(((int)cg & M30) == 0); + + cf >>= 30; + cg >>= 30; + + for (i = 1; i < len30; ++i) + { + fi = F[i]; + gi = G[i]; + + cf += (long)u * fi + (long)v * gi; + cg += (long)q * fi + (long)r * gi; + + F[i - 1] = (int)cf & M30; cf >>= 30; + G[i - 1] = (int)cg & M30; cg >>= 30; + } + + F[len30 - 1] = (int)cf; + G[len30 - 1] = (int)cg; + } + } +} \ No newline at end of file diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Mod.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Mod.cs.meta new file mode 100644 index 0000000..a0b3ad2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Mod.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f6313e4195ff43b4e9b6582324b84631 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat.cs new file mode 100644 index 0000000..effe464 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat.cs @@ -0,0 +1,1418 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Crypto.Utilities; + +namespace Org.BouncyCastle.Math.Raw +{ + internal abstract class Nat + { + private const ulong M = 0xFFFFFFFFUL; + + public static uint Add(int len, uint[] x, uint[] y, uint[] z) + { + ulong c = 0; + for (int i = 0; i < len; ++i) + { + c += (ulong)x[i] + y[i]; + z[i] = (uint)c; + c >>= 32; + } + return (uint)c; + } + + public static uint Add33At(int len, uint x, uint[] z, int zPos) + { + Debug.Assert(zPos <= (len - 2)); + ulong c = (ulong)z[zPos + 0] + x; + z[zPos + 0] = (uint)c; + c >>= 32; + c += (ulong)z[zPos + 1] + 1; + z[zPos + 1] = (uint)c; + c >>= 32; + return c == 0 ? 0 : IncAt(len, z, zPos + 2); + } + + public static uint Add33At(int len, uint x, uint[] z, int zOff, int zPos) + { + Debug.Assert(zPos <= (len - 2)); + ulong c = (ulong)z[zOff + zPos] + x; + z[zOff + zPos] = (uint)c; + c >>= 32; + c += (ulong)z[zOff + zPos + 1] + 1; + z[zOff + zPos + 1] = (uint)c; + c >>= 32; + return c == 0 ? 0 : IncAt(len, z, zOff, zPos + 2); + } + + public static uint Add33To(int len, uint x, uint[] z) + { + ulong c = (ulong)z[0] + x; + z[0] = (uint)c; + c >>= 32; + c += (ulong)z[1] + 1; + z[1] = (uint)c; + c >>= 32; + return c == 0 ? 0 : IncAt(len, z, 2); + } + + public static uint Add33To(int len, uint x, uint[] z, int zOff) + { + ulong c = (ulong)z[zOff + 0] + x; + z[zOff + 0] = (uint)c; + c >>= 32; + c += (ulong)z[zOff + 1] + 1; + z[zOff + 1] = (uint)c; + c >>= 32; + return c == 0 ? 0 : IncAt(len, z, zOff, 2); + } + + public static uint AddBothTo(int len, uint[] x, uint[] y, uint[] z) + { + ulong c = 0; + for (int i = 0; i < len; ++i) + { + c += (ulong)x[i] + y[i] + z[i]; + z[i] = (uint)c; + c >>= 32; + } + return (uint)c; + } + + public static uint AddBothTo(int len, uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + { + ulong c = 0; + for (int i = 0; i < len; ++i) + { + c += (ulong)x[xOff + i] + y[yOff + i] + z[zOff + i]; + z[zOff + i] = (uint)c; + c >>= 32; + } + return (uint)c; + } + + public static uint AddDWordAt(int len, ulong x, uint[] z, int zPos) + { + Debug.Assert(zPos <= (len - 2)); + ulong c = (ulong)z[zPos + 0] + (x & M); + z[zPos + 0] = (uint)c; + c >>= 32; + c += (ulong)z[zPos + 1] + (x >> 32); + z[zPos + 1] = (uint)c; + c >>= 32; + return c == 0 ? 0 : IncAt(len, z, zPos + 2); + } + + public static uint AddDWordAt(int len, ulong x, uint[] z, int zOff, int zPos) + { + Debug.Assert(zPos <= (len - 2)); + ulong c = (ulong)z[zOff + zPos] + (x & M); + z[zOff + zPos] = (uint)c; + c >>= 32; + c += (ulong)z[zOff + zPos + 1] + (x >> 32); + z[zOff + zPos + 1] = (uint)c; + c >>= 32; + return c == 0 ? 0 : IncAt(len, z, zOff, zPos + 2); + } + + public static uint AddDWordTo(int len, ulong x, uint[] z) + { + ulong c = (ulong)z[0] + (x & M); + z[0] = (uint)c; + c >>= 32; + c += (ulong)z[1] + (x >> 32); + z[1] = (uint)c; + c >>= 32; + return c == 0 ? 0 : IncAt(len, z, 2); + } + + public static uint AddDWordTo(int len, ulong x, uint[] z, int zOff) + { + ulong c = (ulong)z[zOff + 0] + (x & M); + z[zOff + 0] = (uint)c; + c >>= 32; + c += (ulong)z[zOff + 1] + (x >> 32); + z[zOff + 1] = (uint)c; + c >>= 32; + return c == 0 ? 0 : IncAt(len, z, zOff, 2); + } + + public static uint AddTo(int len, uint[] x, uint[] z) + { + ulong c = 0; + for (int i = 0; i < len; ++i) + { + c += (ulong)x[i] + z[i]; + z[i] = (uint)c; + c >>= 32; + } + return (uint)c; + } + + public static uint AddTo(int len, uint[] x, int xOff, uint[] z, int zOff) + { + ulong c = 0; + for (int i = 0; i < len; ++i) + { + c += (ulong)x[xOff + i] + z[zOff + i]; + z[zOff + i] = (uint)c; + c >>= 32; + } + return (uint)c; + } + + public static uint AddTo(int len, uint[] x, int xOff, uint[] z, int zOff, uint cIn) + { + ulong c = cIn; + for (int i = 0; i < len; ++i) + { + c += (ulong)x[xOff + i] + z[zOff + i]; + z[zOff + i] = (uint)c; + c >>= 32; + } + return (uint)c; + } + + public static uint AddToEachOther(int len, uint[] u, int uOff, uint[] v, int vOff) + { + ulong c = 0; + for (int i = 0; i < len; ++i) + { + c += (ulong)u[uOff + i] + v[vOff + i]; + u[uOff + i] = (uint)c; + v[vOff + i] = (uint)c; + c >>= 32; + } + return (uint)c; + } + + public static uint AddWordAt(int len, uint x, uint[] z, int zPos) + { + Debug.Assert(zPos <= (len - 1)); + ulong c = (ulong)x + z[zPos]; + z[zPos] = (uint)c; + c >>= 32; + return c == 0 ? 0 : IncAt(len, z, zPos + 1); + } + + public static uint AddWordAt(int len, uint x, uint[] z, int zOff, int zPos) + { + Debug.Assert(zPos <= (len - 1)); + ulong c = (ulong)x + z[zOff + zPos]; + z[zOff + zPos] = (uint)c; + c >>= 32; + return c == 0 ? 0 : IncAt(len, z, zOff, zPos + 1); + } + + public static uint AddWordTo(int len, uint x, uint[] z) + { + ulong c = (ulong)x + z[0]; + z[0] = (uint)c; + c >>= 32; + return c == 0 ? 0 : IncAt(len, z, 1); + } + + public static uint AddWordTo(int len, uint x, uint[] z, int zOff) + { + ulong c = (ulong)x + z[zOff]; + z[zOff] = (uint)c; + c >>= 32; + return c == 0 ? 0 : IncAt(len, z, zOff, 1); + } + + public static uint CAdd(int len, int mask, uint[] x, uint[] y, uint[] z) + { + uint MASK = (uint)-(mask & 1); + + ulong c = 0; + for (int i = 0; i < len; ++i) + { + c += (ulong)x[i] + (y[i] & MASK); + z[i] = (uint)c; + c >>= 32; + } + return (uint)c; + } + + public static void CMov(int len, int mask, uint[] x, int xOff, uint[] z, int zOff) + { + uint MASK = (uint)-(mask & 1); + + for (int i = 0; i < len; ++i) + { + uint z_i = z[zOff + i], diff = z_i ^ x[xOff + i]; + z_i ^= (diff & MASK); + z[zOff + i] = z_i; + } + + //uint half = 0x55555555U, rest = half << (-(int)MASK); + + //for (int i = 0; i < len; ++i) + //{ + // uint z_i = z[zOff + i], diff = z_i ^ x[xOff + i]; + // z_i ^= (diff & half); + // z_i ^= (diff & rest); + // z[zOff + i] = z_i; + //} + } + + public static void CMov(int len, int mask, int[] x, int xOff, int[] z, int zOff) + { + mask = -(mask & 1); + + for (int i = 0; i < len; ++i) + { + int z_i = z[zOff + i], diff = z_i ^ x[xOff + i]; + z_i ^= (diff & mask); + z[zOff + i] = z_i; + } + + //int half = 0x55555555, rest = half << (-mask); + + //for (int i = 0; i < len; ++i) + //{ + // int z_i = z[zOff + i], diff = z_i ^ x[xOff + i]; + // z_i ^= (diff & half); + // z_i ^= (diff & rest); + // z[zOff + i] = z_i; + //} + } + + public static int Compare(int len, uint[] x, uint[] y) + { + for (int i = len - 1; i >= 0; --i) + { + uint x_i = x[i]; + uint y_i = y[i]; + if (x_i < y_i) + return -1; + if (x_i > y_i) + return 1; + } + return 0; + } + + public static int Compare(int len, uint[] x, int xOff, uint[] y, int yOff) + { + for (int i = len - 1; i >= 0; --i) + { + uint x_i = x[xOff + i]; + uint y_i = y[yOff + i]; + if (x_i < y_i) + return -1; + if (x_i > y_i) + return 1; + } + return 0; + } + + public static void Copy(int len, uint[] x, uint[] z) + { + Array.Copy(x, 0, z, 0, len); + } + + public static uint[] Copy(int len, uint[] x) + { + uint[] z = new uint[len]; + Array.Copy(x, 0, z, 0, len); + return z; + } + + public static void Copy(int len, uint[] x, int xOff, uint[] z, int zOff) + { + Array.Copy(x, xOff, z, zOff, len); + } + + public static ulong[] Copy64(int len, ulong[] x) + { + ulong[] z = new ulong[len]; + Array.Copy(x, 0, z, 0, len); + return z; + } + + public static void Copy64(int len, ulong[] x, ulong[] z) + { + Array.Copy(x, 0, z, 0, len); + } + + public static void Copy64(int len, ulong[] x, int xOff, ulong[] z, int zOff) + { + Array.Copy(x, xOff, z, zOff, len); + } + + public static uint[] Create(int len) + { + return new uint[len]; + } + + public static ulong[] Create64(int len) + { + return new ulong[len]; + } + + public static int CSub(int len, int mask, uint[] x, uint[] y, uint[] z) + { + long MASK = (uint)-(mask & 1); + long c = 0; + for (int i = 0; i < len; ++i) + { + c += (long)x[i] - (y[i] & MASK); + z[i] = (uint)c; + c >>= 32; + } + return (int)c; + } + + public static int CSub(int len, int mask, uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + { + long MASK = (uint)-(mask & 1); + long c = 0; + for (int i = 0; i < len; ++i) + { + c += (long)x[xOff + i] - (y[yOff + i] & MASK); + z[zOff + i] = (uint)c; + c >>= 32; + } + return (int)c; + } + + public static int Dec(int len, uint[] z) + { + for (int i = 0; i < len; ++i) + { + if (--z[i] != uint.MaxValue) + { + return 0; + } + } + return -1; + } + + public static int Dec(int len, uint[] x, uint[] z) + { + int i = 0; + while (i < len) + { + uint c = x[i] - 1; + z[i] = c; + ++i; + if (c != uint.MaxValue) + { + while (i < len) + { + z[i] = x[i]; + ++i; + } + return 0; + } + } + return -1; + } + + public static int DecAt(int len, uint[] z, int zPos) + { + Debug.Assert(zPos <= len); + for (int i = zPos; i < len; ++i) + { + if (--z[i] != uint.MaxValue) + { + return 0; + } + } + return -1; + } + + public static int DecAt(int len, uint[] z, int zOff, int zPos) + { + Debug.Assert(zPos <= len); + for (int i = zPos; i < len; ++i) + { + if (--z[zOff + i] != uint.MaxValue) + { + return 0; + } + } + return -1; + } + + public static bool Eq(int len, uint[] x, uint[] y) + { + for (int i = len - 1; i >= 0; --i) + { + if (x[i] != y[i]) + { + return false; + } + } + return true; + } + + public static uint EqualTo(int len, uint[] x, uint y) + { + uint d = x[0] ^ y; + for (int i = 1; i < len; ++i) + { + d |= x[i]; + } + d = (d >> 1) | (d & 1); + return (uint)(((int)d - 1) >> 31); + } + + public static uint EqualTo(int len, uint[] x, int xOff, uint y) + { + uint d = x[xOff] ^ y; + for (int i = 1; i < len; ++i) + { + d |= x[xOff + i]; + } + d = (d >> 1) | (d & 1); + return (uint)(((int)d - 1) >> 31); + } + + public static uint EqualTo(int len, uint[] x, uint[] y) + { + uint d = 0; + for (int i = 0; i < len; ++i) + { + d |= x[i] ^ y[i]; + } + d = (d >> 1) | (d & 1); + return (uint)(((int)d - 1) >> 31); + } + + public static uint EqualTo(int len, uint[] x, int xOff, uint[] y, int yOff) + { + uint d = 0; + for (int i = 0; i < len; ++i) + { + d |= x[xOff + i] ^ y[yOff + i]; + } + d = (d >> 1) | (d & 1); + return (uint)(((int)d - 1) >> 31); + } + + public static uint EqualToZero(int len, uint[] x) + { + uint d = 0; + for (int i = 0; i < len; ++i) + { + d |= x[i]; + } + d = (d >> 1) | (d & 1); + return (uint)(((int)d - 1) >> 31); + } + + public static uint EqualToZero(int len, uint[] x, int xOff) + { + uint d = 0; + for (int i = 0; i < len; ++i) + { + d |= x[xOff + i]; + } + d = (d >> 1) | (d & 1); + return (uint)(((int)d - 1) >> 31); + } + + public static uint[] FromBigInteger(int bits, BigInteger x) + { + if (bits < 1) + throw new ArgumentException(); + if (x.SignValue < 0 || x.BitLength > bits) + throw new ArgumentException(); + + int len = (bits + 31) >> 5; + Debug.Assert(len > 0); + uint[] z = Create(len); + + // NOTE: Use a fixed number of loop iterations + z[0] = (uint)x.IntValue; + for (int i = 1; i < len; ++i) + { + x = x.ShiftRight(32); + z[i] = (uint)x.IntValue; + } + return z; + } + + public static ulong[] FromBigInteger64(int bits, BigInteger x) + { + if (bits < 1) + throw new ArgumentException(); + if (x.SignValue < 0 || x.BitLength > bits) + throw new ArgumentException(); + + int len = (bits + 63) >> 6; + Debug.Assert(len > 0); + ulong[] z = Create64(len); + + // NOTE: Use a fixed number of loop iterations + z[0] = (ulong)x.LongValue; + for (int i = 1; i < len; ++i) + { + x = x.ShiftRight(64); + z[i] = (ulong)x.LongValue; + } + return z; + } + + public static uint GetBit(uint[] x, int bit) + { + if (bit == 0) + { + return x[0] & 1; + } + int w = bit >> 5; + if (w < 0 || w >= x.Length) + { + return 0; + } + int b = bit & 31; + return (x[w] >> b) & 1; + } + + public static bool Gte(int len, uint[] x, uint[] y) + { + for (int i = len - 1; i >= 0; --i) + { + uint x_i = x[i], y_i = y[i]; + if (x_i < y_i) + return false; + if (x_i > y_i) + return true; + } + return true; + } + + public static uint Inc(int len, uint[] z) + { + for (int i = 0; i < len; ++i) + { + if (++z[i] != uint.MinValue) + { + return 0; + } + } + return 1; + } + + public static uint Inc(int len, uint[] x, uint[] z) + { + int i = 0; + while (i < len) + { + uint c = x[i] + 1; + z[i] = c; + ++i; + if (c != 0) + { + while (i < len) + { + z[i] = x[i]; + ++i; + } + return 0; + } + } + return 1; + } + + public static uint IncAt(int len, uint[] z, int zPos) + { + Debug.Assert(zPos <= len); + for (int i = zPos; i < len; ++i) + { + if (++z[i] != uint.MinValue) + { + return 0; + } + } + return 1; + } + + public static uint IncAt(int len, uint[] z, int zOff, int zPos) + { + Debug.Assert(zPos <= len); + for (int i = zPos; i < len; ++i) + { + if (++z[zOff + i] != uint.MinValue) + { + return 0; + } + } + return 1; + } + + public static bool IsOne(int len, uint[] x) + { + if (x[0] != 1) + { + return false; + } + for (int i = 1; i < len; ++i) + { + if (x[i] != 0) + { + return false; + } + } + return true; + } + + public static bool IsZero(int len, uint[] x) + { + if (x[0] != 0) + { + return false; + } + for (int i = 1; i < len; ++i) + { + if (x[i] != 0) + { + return false; + } + } + return true; + } + + public static int LessThan(int len, uint[] x, uint[] y) + { + long c = 0; + for (int i = 0; i < len; ++i) + { + c += (long)x[i] - y[i]; + c >>= 32; + } + Debug.Assert(c == 0L || c == -1L); + return (int)c; + } + + public static int LessThan(int len, uint[] x, int xOff, uint[] y, int yOff) + { + long c = 0; + for (int i = 0; i < len; ++i) + { + c += (long)x[xOff + i] - y[yOff + i]; + c >>= 32; + } + Debug.Assert(c == 0L || c == -1L); + return (int)c; + } + + public static void Mul(int len, uint[] x, uint[] y, uint[] zz) + { + zz[len] = MulWord(len, x[0], y, zz); + + for (int i = 1; i < len; ++i) + { + zz[i + len] = MulWordAddTo(len, x[i], y, 0, zz, i); + } + } + + public static void Mul(int len, uint[] x, int xOff, uint[] y, int yOff, uint[] zz, int zzOff) + { + zz[zzOff + len] = MulWord(len, x[xOff], y, yOff, zz, zzOff); + + for (int i = 1; i < len; ++i) + { + zz[zzOff + i + len] = MulWordAddTo(len, x[xOff + i], y, yOff, zz, zzOff + i); + } + } + + public static void Mul(uint[] x, int xOff, int xLen, uint[] y, int yOff, int yLen, uint[] zz, int zzOff) + { + zz[zzOff + yLen] = MulWord(yLen, x[xOff], y, yOff, zz, zzOff); + + for (int i = 1; i < xLen; ++i) + { + zz[zzOff + i + yLen] = MulWordAddTo(yLen, x[xOff + i], y, yOff, zz, zzOff + i); + } + } + + public static uint MulAddTo(int len, uint[] x, uint[] y, uint[] zz) + { + ulong zc = 0; + for (int i = 0; i < len; ++i) + { + zc += MulWordAddTo(len, x[i], y, 0, zz, i) & M; + zc += zz[i + len] & M; + zz[i + len] = (uint)zc; + zc >>= 32; + } + return (uint)zc; + } + + public static uint MulAddTo(int len, uint[] x, int xOff, uint[] y, int yOff, uint[] zz, int zzOff) + { + ulong zc = 0; + for (int i = 0; i < len; ++i) + { + zc += MulWordAddTo(len, x[xOff + i], y, yOff, zz, zzOff) & M; + zc += zz[zzOff + len] & M; + zz[zzOff + len] = (uint)zc; + zc >>= 32; + ++zzOff; + } + return (uint)zc; + } + + public static uint Mul31BothAdd(int len, uint a, uint[] x, uint b, uint[] y, uint[] z, int zOff) + { + ulong c = 0, aVal = (ulong)a, bVal = (ulong)b; + int i = 0; + do + { + c += aVal * x[i] + bVal * y[i] + z[zOff + i]; + z[zOff + i] = (uint)c; + c >>= 32; + } + while (++i < len); + return (uint)c; + } + + public static uint MulWord(int len, uint x, uint[] y, uint[] z) + { + ulong c = 0, xVal = (ulong)x; + int i = 0; + do + { + c += xVal * y[i]; + z[i] = (uint)c; + c >>= 32; + } + while (++i < len); + return (uint)c; + } + + public static uint MulWord(int len, uint x, uint[] y, int yOff, uint[] z, int zOff) + { + ulong c = 0, xVal = (ulong)x; + int i = 0; + do + { + c += xVal * y[yOff + i]; + z[zOff + i] = (uint)c; + c >>= 32; + } + while (++i < len); + return (uint)c; + } + + public static uint MulWordAddTo(int len, uint x, uint[] y, int yOff, uint[] z, int zOff) + { + ulong c = 0, xVal = (ulong)x; + int i = 0; + do + { + c += xVal * y[yOff + i] + z[zOff + i]; + z[zOff + i] = (uint)c; + c >>= 32; + } + while (++i < len); + return (uint)c; + } + + public static uint MulWordDwordAddAt(int len, uint x, ulong y, uint[] z, int zPos) + { + Debug.Assert(zPos <= (len - 3)); + ulong c = 0, xVal = (ulong)x; + c += xVal * (uint)y + z[zPos + 0]; + z[zPos + 0] = (uint)c; + c >>= 32; + c += xVal * (y >> 32) + z[zPos + 1]; + z[zPos + 1] = (uint)c; + c >>= 32; + c += (ulong)z[zPos + 2]; + z[zPos + 2] = (uint)c; + c >>= 32; + return c == 0 ? 0 : IncAt(len, z, zPos + 3); + } + + public static uint ShiftDownBit(int len, uint[] z, uint c) + { + int i = len; + while (--i >= 0) + { + uint next = z[i]; + z[i] = (next >> 1) | (c << 31); + c = next; + } + return c << 31; + } + + public static uint ShiftDownBit(int len, uint[] z, int zOff, uint c) + { + int i = len; + while (--i >= 0) + { + uint next = z[zOff + i]; + z[zOff + i] = (next >> 1) | (c << 31); + c = next; + } + return c << 31; + } + + public static uint ShiftDownBit(int len, uint[] x, uint c, uint[] z) + { + int i = len; + while (--i >= 0) + { + uint next = x[i]; + z[i] = (next >> 1) | (c << 31); + c = next; + } + return c << 31; + } + + public static uint ShiftDownBit(int len, uint[] x, int xOff, uint c, uint[] z, int zOff) + { + int i = len; + while (--i >= 0) + { + uint next = x[xOff + i]; + z[zOff + i] = (next >> 1) | (c << 31); + c = next; + } + return c << 31; + } + + public static uint ShiftDownBits(int len, uint[] z, int bits, uint c) + { + Debug.Assert(bits > 0 && bits < 32); + int i = len; + while (--i >= 0) + { + uint next = z[i]; + z[i] = (next >> bits) | (c << -bits); + c = next; + } + return c << -bits; + } + + public static uint ShiftDownBits(int len, uint[] z, int zOff, int bits, uint c) + { + Debug.Assert(bits > 0 && bits < 32); + int i = len; + while (--i >= 0) + { + uint next = z[zOff + i]; + z[zOff + i] = (next >> bits) | (c << -bits); + c = next; + } + return c << -bits; + } + + public static uint ShiftDownBits(int len, uint[] x, int bits, uint c, uint[] z) + { + Debug.Assert(bits > 0 && bits < 32); + int i = len; + while (--i >= 0) + { + uint next = x[i]; + z[i] = (next >> bits) | (c << -bits); + c = next; + } + return c << -bits; + } + + public static uint ShiftDownBits(int len, uint[] x, int xOff, int bits, uint c, uint[] z, int zOff) + { + Debug.Assert(bits > 0 && bits < 32); + int i = len; + while (--i >= 0) + { + uint next = x[xOff + i]; + z[zOff + i] = (next >> bits) | (c << -bits); + c = next; + } + return c << -bits; + } + + public static uint ShiftDownWord(int len, uint[] z, uint c) + { + int i = len; + while (--i >= 0) + { + uint next = z[i]; + z[i] = c; + c = next; + } + return c; + } + + public static uint ShiftUpBit(int len, uint[] z, uint c) + { + for (int i = 0; i < len; ++i) + { + uint next = z[i]; + z[i] = (next << 1) | (c >> 31); + c = next; + } + return c >> 31; + } + + public static uint ShiftUpBit(int len, uint[] z, int zOff, uint c) + { + for (int i = 0; i < len; ++i) + { + uint next = z[zOff + i]; + z[zOff + i] = (next << 1) | (c >> 31); + c = next; + } + return c >> 31; + } + + public static uint ShiftUpBit(int len, uint[] x, uint c, uint[] z) + { + for (int i = 0; i < len; ++i) + { + uint next = x[i]; + z[i] = (next << 1) | (c >> 31); + c = next; + } + return c >> 31; + } + + public static uint ShiftUpBit(int len, uint[] x, int xOff, uint c, uint[] z, int zOff) + { + for (int i = 0; i < len; ++i) + { + uint next = x[xOff + i]; + z[zOff + i] = (next << 1) | (c >> 31); + c = next; + } + return c >> 31; + } + + public static ulong ShiftUpBit64(int len, ulong[] x, int xOff, ulong c, ulong[] z, int zOff) + { + for (int i = 0; i < len; ++i) + { + ulong next = x[xOff + i]; + z[zOff + i] = (next << 1) | (c >> 63); + c = next; + } + return c >> 63; + } + + public static uint ShiftUpBits(int len, uint[] z, int bits, uint c) + { + Debug.Assert(bits > 0 && bits < 32); + for (int i = 0; i < len; ++i) + { + uint next = z[i]; + z[i] = (next << bits) | (c >> -bits); + c = next; + } + return c >> -bits; + } + + public static uint ShiftUpBits(int len, uint[] z, int zOff, int bits, uint c) + { + Debug.Assert(bits > 0 && bits < 32); + for (int i = 0; i < len; ++i) + { + uint next = z[zOff + i]; + z[zOff + i] = (next << bits) | (c >> -bits); + c = next; + } + return c >> -bits; + } + + public static ulong ShiftUpBits64(int len, ulong[] z, int zOff, int bits, ulong c) + { + Debug.Assert(bits > 0 && bits < 64); + for (int i = 0; i < len; ++i) + { + ulong next = z[zOff + i]; + z[zOff + i] = (next << bits) | (c >> -bits); + c = next; + } + return c >> -bits; + } + + public static uint ShiftUpBits(int len, uint[] x, int bits, uint c, uint[] z) + { + Debug.Assert(bits > 0 && bits < 32); + for (int i = 0; i < len; ++i) + { + uint next = x[i]; + z[i] = (next << bits) | (c >> -bits); + c = next; + } + return c >> -bits; + } + + public static uint ShiftUpBits(int len, uint[] x, int xOff, int bits, uint c, uint[] z, int zOff) + { + Debug.Assert(bits > 0 && bits < 32); + for (int i = 0; i < len; ++i) + { + uint next = x[xOff + i]; + z[zOff + i] = (next << bits) | (c >> -bits); + c = next; + } + return c >> -bits; + } + + public static ulong ShiftUpBits64(int len, ulong[] x, int xOff, int bits, ulong c, ulong[] z, int zOff) + { + Debug.Assert(bits > 0 && bits < 64); + for (int i = 0; i < len; ++i) + { + ulong next = x[xOff + i]; + z[zOff + i] = (next << bits) | (c >> -bits); + c = next; + } + return c >> -bits; + } + + public static void Square(int len, uint[] x, uint[] zz) + { + int extLen = len << 1; + uint c = 0; + int j = len, k = extLen; + do + { + ulong xVal = (ulong)x[--j]; + ulong p = xVal * xVal; + zz[--k] = (c << 31) | (uint)(p >> 33); + zz[--k] = (uint)(p >> 1); + c = (uint)p; + } + while (j > 0); + + ulong d = 0UL; + int zzPos = 2; + + for (int i = 1; i < len; ++i) + { + d += SquareWordAddTo(x, i, zz); + d += zz[zzPos]; + zz[zzPos++] = (uint)d; d >>= 32; + d += zz[zzPos]; + zz[zzPos++] = (uint)d; d >>= 32; + } + Debug.Assert(0UL == d); + + ShiftUpBit(extLen, zz, x[0] << 31); + } + + public static void Square(int len, uint[] x, int xOff, uint[] zz, int zzOff) + { + int extLen = len << 1; + uint c = 0; + int j = len, k = extLen; + do + { + ulong xVal = (ulong)x[xOff + --j]; + ulong p = xVal * xVal; + zz[zzOff + --k] = (c << 31) | (uint)(p >> 33); + zz[zzOff + --k] = (uint)(p >> 1); + c = (uint)p; + } + while (j > 0); + + ulong d = 0UL; + int zzPos = zzOff + 2; + + for (int i = 1; i < len; ++i) + { + d += SquareWordAddTo(x, xOff, i, zz, zzOff); + d += zz[zzPos]; + zz[zzPos++] = (uint)d; d >>= 32; + d += zz[zzPos]; + zz[zzPos++] = (uint)d; d >>= 32; + } + Debug.Assert(0UL == d); + + ShiftUpBit(extLen, zz, zzOff, x[xOff] << 31); + } + + [Obsolete("Use 'SquareWordAddTo' instead")] + public static uint SquareWordAdd(uint[] x, int xPos, uint[] z) + { + ulong c = 0, xVal = (ulong)x[xPos]; + int i = 0; + do + { + c += xVal * x[i] + z[xPos + i]; + z[xPos + i] = (uint)c; + c >>= 32; + } + while (++i < xPos); + return (uint)c; + } + + [Obsolete("Use 'SquareWordAddTo' instead")] + public static uint SquareWordAdd(uint[] x, int xOff, int xPos, uint[] z, int zOff) + { + ulong c = 0, xVal = (ulong)x[xOff + xPos]; + int i = 0; + do + { + c += xVal * (x[xOff + i] & M) + (z[xPos + zOff] & M); + z[xPos + zOff] = (uint)c; + c >>= 32; + ++zOff; + } + while (++i < xPos); + return (uint)c; + } + + public static uint SquareWordAddTo(uint[] x, int xPos, uint[] z) + { + ulong c = 0, xVal = (ulong)x[xPos]; + int i = 0; + do + { + c += xVal * x[i] + z[xPos + i]; + z[xPos + i] = (uint)c; + c >>= 32; + } + while (++i < xPos); + return (uint)c; + } + + public static uint SquareWordAddTo(uint[] x, int xOff, int xPos, uint[] z, int zOff) + { + ulong c = 0, xVal = (ulong)x[xOff + xPos]; + int i = 0; + do + { + c += xVal * (x[xOff + i] & M) + (z[xPos + zOff] & M); + z[xPos + zOff] = (uint)c; + c >>= 32; + ++zOff; + } + while (++i < xPos); + return (uint)c; + } + + public static int Sub(int len, uint[] x, uint[] y, uint[] z) + { + long c = 0; + for (int i = 0; i < len; ++i) + { + c += (long)x[i] - y[i]; + z[i] = (uint)c; + c >>= 32; + } + return (int)c; + } + + public static int Sub(int len, uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + { + long c = 0; + for (int i = 0; i < len; ++i) + { + c += (long)x[xOff + i] - y[yOff + i]; + z[zOff + i] = (uint)c; + c >>= 32; + } + return (int)c; + } + public static int Sub33At(int len, uint x, uint[] z, int zPos) + { + Debug.Assert(zPos <= (len - 2)); + long c = (long)z[zPos + 0] - x; + z[zPos + 0] = (uint)c; + c >>= 32; + c += (long)z[zPos + 1] - 1; + z[zPos + 1] = (uint)c; + c >>= 32; + return c == 0 ? 0 : DecAt(len, z, zPos + 2); + } + + public static int Sub33At(int len, uint x, uint[] z, int zOff, int zPos) + { + Debug.Assert(zPos <= (len - 2)); + long c = (long)z[zOff + zPos] - x; + z[zOff + zPos] = (uint)c; + c >>= 32; + c += (long)z[zOff + zPos + 1] - 1; + z[zOff + zPos + 1] = (uint)c; + c >>= 32; + return c == 0 ? 0 : DecAt(len, z, zOff, zPos + 2); + } + + public static int Sub33From(int len, uint x, uint[] z) + { + long c = (long)z[0] - x; + z[0] = (uint)c; + c >>= 32; + c += (long)z[1] - 1; + z[1] = (uint)c; + c >>= 32; + return c == 0 ? 0 : DecAt(len, z, 2); + } + + public static int Sub33From(int len, uint x, uint[] z, int zOff) + { + long c = (long)z[zOff + 0] - x; + z[zOff + 0] = (uint)c; + c >>= 32; + c += (long)z[zOff + 1] - 1; + z[zOff + 1] = (uint)c; + c >>= 32; + return c == 0 ? 0 : DecAt(len, z, zOff, 2); + } + + public static int SubBothFrom(int len, uint[] x, uint[] y, uint[] z) + { + long c = 0; + for (int i = 0; i < len; ++i) + { + c += (long)z[i] - x[i] - y[i]; + z[i] = (uint)c; + c >>= 32; + } + return (int)c; + } + + public static int SubBothFrom(int len, uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + { + long c = 0; + for (int i = 0; i < len; ++i) + { + c += (long)z[zOff + i] - x[xOff + i] - y[yOff + i]; + z[zOff + i] = (uint)c; + c >>= 32; + } + return (int)c; + } + + public static int SubDWordAt(int len, ulong x, uint[] z, int zPos) + { + Debug.Assert(zPos <= (len - 2)); + long c = (long)z[zPos + 0] - (long)(x & M); + z[zPos + 0] = (uint)c; + c >>= 32; + c += (long)z[zPos + 1] - (long)(x >> 32); + z[zPos + 1] = (uint)c; + c >>= 32; + return c == 0 ? 0 : DecAt(len, z, zPos + 2); + } + + public static int SubDWordAt(int len, ulong x, uint[] z, int zOff, int zPos) + { + Debug.Assert(zPos <= (len - 2)); + long c = (long)z[zOff + zPos] - (long)(x & M); + z[zOff + zPos] = (uint)c; + c >>= 32; + c += (long)z[zOff + zPos + 1] - (long)(x >> 32); + z[zOff + zPos + 1] = (uint)c; + c >>= 32; + return c == 0 ? 0 : DecAt(len, z, zOff, zPos + 2); + } + + public static int SubDWordFrom(int len, ulong x, uint[] z) + { + long c = (long)z[0] - (long)(x & M); + z[0] = (uint)c; + c >>= 32; + c += (long)z[1] - (long)(x >> 32); + z[1] = (uint)c; + c >>= 32; + return c == 0 ? 0 : DecAt(len, z, 2); + } + + public static int SubDWordFrom(int len, ulong x, uint[] z, int zOff) + { + long c = (long)z[zOff + 0] - (long)(x & M); + z[zOff + 0] = (uint)c; + c >>= 32; + c += (long)z[zOff + 1] - (long)(x >> 32); + z[zOff + 1] = (uint)c; + c >>= 32; + return c == 0 ? 0 : DecAt(len, z, zOff, 2); + } + + public static int SubFrom(int len, uint[] x, uint[] z) + { + long c = 0; + for (int i = 0; i < len; ++i) + { + c += (long)z[i] - x[i]; + z[i] = (uint)c; + c >>= 32; + } + return (int)c; + } + + public static int SubFrom(int len, uint[] x, int xOff, uint[] z, int zOff) + { + long c = 0; + for (int i = 0; i < len; ++i) + { + c += (long)z[zOff + i] - x[xOff + i]; + z[zOff + i] = (uint)c; + c >>= 32; + } + return (int)c; + } + + public static int SubWordAt(int len, uint x, uint[] z, int zPos) + { + Debug.Assert(zPos <= (len - 1)); + long c = (long)z[zPos] - x; + z[zPos] = (uint)c; + c >>= 32; + return c == 0 ? 0 : DecAt(len, z, zPos + 1); + } + + public static int SubWordAt(int len, uint x, uint[] z, int zOff, int zPos) + { + Debug.Assert(zPos <= (len - 1)); + long c = (long)z[zOff + zPos] - x; + z[zOff + zPos] = (uint)c; + c >>= 32; + return c == 0 ? 0 : DecAt(len, z, zOff, zPos + 1); + } + + public static int SubWordFrom(int len, uint x, uint[] z) + { + long c = (long)z[0] - x; + z[0] = (uint)c; + c >>= 32; + return c == 0 ? 0 : DecAt(len, z, 1); + } + + public static int SubWordFrom(int len, uint x, uint[] z, int zOff) + { + long c = (long)z[zOff + 0] - x; + z[zOff + 0] = (uint)c; + c >>= 32; + return c == 0 ? 0 : DecAt(len, z, zOff, 1); + } + + public static BigInteger ToBigInteger(int len, uint[] x) + { + byte[] bs = new byte[len << 2]; + for (int i = 0; i < len; ++i) + { + uint x_i = x[i]; + if (x_i != 0) + { + Pack.UInt32_To_BE(x_i, bs, (len - 1 - i) << 2); + } + } + return new BigInteger(1, bs); + } + + public static void Zero(int len, uint[] z) + { + for (int i = 0; i < len; ++i) + { + z[i] = 0; + } + } + + public static void Zero64(int len, ulong[] z) + { + for (int i = 0; i < len; ++i) + { + z[i] = 0UL; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat.cs.meta new file mode 100644 index 0000000..3e43deb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fef559e43892c434abb6f3fbc11e0939 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat128.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat128.cs new file mode 100644 index 0000000..d336b32 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat128.cs @@ -0,0 +1,842 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Crypto.Utilities; + +namespace Org.BouncyCastle.Math.Raw +{ + internal abstract class Nat128 + { + private const ulong M = 0xFFFFFFFFUL; + + public static uint Add(uint[] x, uint[] y, uint[] z) + { + ulong c = 0; + c += (ulong)x[0] + y[0]; + z[0] = (uint)c; + c >>= 32; + c += (ulong)x[1] + y[1]; + z[1] = (uint)c; + c >>= 32; + c += (ulong)x[2] + y[2]; + z[2] = (uint)c; + c >>= 32; + c += (ulong)x[3] + y[3]; + z[3] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint AddBothTo(uint[] x, uint[] y, uint[] z) + { + ulong c = 0; + c += (ulong)x[0] + y[0] + z[0]; + z[0] = (uint)c; + c >>= 32; + c += (ulong)x[1] + y[1] + z[1]; + z[1] = (uint)c; + c >>= 32; + c += (ulong)x[2] + y[2] + z[2]; + z[2] = (uint)c; + c >>= 32; + c += (ulong)x[3] + y[3] + z[3]; + z[3] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint AddTo(uint[] x, uint[] z) + { + ulong c = 0; + c += (ulong)x[0] + z[0]; + z[0] = (uint)c; + c >>= 32; + c += (ulong)x[1] + z[1]; + z[1] = (uint)c; + c >>= 32; + c += (ulong)x[2] + z[2]; + z[2] = (uint)c; + c >>= 32; + c += (ulong)x[3] + z[3]; + z[3] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint AddTo(uint[] x, int xOff, uint[] z, int zOff, uint cIn) + { + ulong c = cIn; + c += (ulong)x[xOff + 0] + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 1] + z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 2] + z[zOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 3] + z[zOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint AddToEachOther(uint[] u, int uOff, uint[] v, int vOff) + { + ulong c = 0; + c += (ulong)u[uOff + 0] + v[vOff + 0]; + u[uOff + 0] = (uint)c; + v[vOff + 0] = (uint)c; + c >>= 32; + c += (ulong)u[uOff + 1] + v[vOff + 1]; + u[uOff + 1] = (uint)c; + v[vOff + 1] = (uint)c; + c >>= 32; + c += (ulong)u[uOff + 2] + v[vOff + 2]; + u[uOff + 2] = (uint)c; + v[vOff + 2] = (uint)c; + c >>= 32; + c += (ulong)u[uOff + 3] + v[vOff + 3]; + u[uOff + 3] = (uint)c; + v[vOff + 3] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static void Copy(uint[] x, uint[] z) + { + z[0] = x[0]; + z[1] = x[1]; + z[2] = x[2]; + z[3] = x[3]; + } + + public static void Copy(uint[] x, int xOff, uint[] z, int zOff) + { + z[zOff + 0] = x[xOff + 0]; + z[zOff + 1] = x[xOff + 1]; + z[zOff + 2] = x[xOff + 2]; + z[zOff + 3] = x[xOff + 3]; + } + + public static void Copy64(ulong[] x, ulong[] z) + { + z[0] = x[0]; + z[1] = x[1]; + } + + public static void Copy64(ulong[] x, int xOff, ulong[] z, int zOff) + { + z[zOff + 0] = x[xOff + 0]; + z[zOff + 1] = x[xOff + 1]; + } + + public static uint[] Create() + { + return new uint[4]; + } + + public static ulong[] Create64() + { + return new ulong[2]; + } + + public static uint[] CreateExt() + { + return new uint[8]; + } + + public static ulong[] CreateExt64() + { + return new ulong[4]; + } + + public static bool Diff(uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + { + bool pos = Gte(x, xOff, y, yOff); + if (pos) + { + Sub(x, xOff, y, yOff, z, zOff); + } + else + { + Sub(y, yOff, x, xOff, z, zOff); + } + return pos; + } + + public static bool Eq(uint[] x, uint[] y) + { + for (int i = 3; i >= 0; --i) + { + if (x[i] != y[i]) + return false; + } + return true; + } + + public static bool Eq64(ulong[] x, ulong[] y) + { + for (int i = 1; i >= 0; --i) + { + if (x[i] != y[i]) + return false; + } + return true; + } + + public static uint GetBit(uint[] x, int bit) + { + if (bit == 0) + { + return x[0] & 1; + } + if ((bit & 127) != bit) + { + return 0; + } + int w = bit >> 5; + int b = bit & 31; + return (x[w] >> b) & 1; + } + + public static bool Gte(uint[] x, uint[] y) + { + for (int i = 3; i >= 0; --i) + { + uint x_i = x[i], y_i = y[i]; + if (x_i < y_i) + return false; + if (x_i > y_i) + return true; + } + return true; + } + + public static bool Gte(uint[] x, int xOff, uint[] y, int yOff) + { + for (int i = 3; i >= 0; --i) + { + uint x_i = x[xOff + i], y_i = y[yOff + i]; + if (x_i < y_i) + return false; + if (x_i > y_i) + return true; + } + return true; + } + + public static bool IsOne(uint[] x) + { + if (x[0] != 1) + { + return false; + } + for (int i = 1; i < 4; ++i) + { + if (x[i] != 0) + { + return false; + } + } + return true; + } + + public static bool IsOne64(ulong[] x) + { + if (x[0] != 1UL) + { + return false; + } + for (int i = 1; i < 2; ++i) + { + if (x[i] != 0UL) + { + return false; + } + } + return true; + } + + public static bool IsZero(uint[] x) + { + for (int i = 0; i < 4; ++i) + { + if (x[i] != 0) + { + return false; + } + } + return true; + } + + public static bool IsZero64(ulong[] x) + { + for (int i = 0; i < 2; ++i) + { + if (x[i] != 0UL) + { + return false; + } + } + return true; + } + + public static void Mul(uint[] x, uint[] y, uint[] zz) + { + ulong y_0 = y[0]; + ulong y_1 = y[1]; + ulong y_2 = y[2]; + ulong y_3 = y[3]; + + { + ulong c = 0, x_0 = x[0]; + c += x_0 * y_0; + zz[0] = (uint)c; + c >>= 32; + c += x_0 * y_1; + zz[1] = (uint)c; + c >>= 32; + c += x_0 * y_2; + zz[2] = (uint)c; + c >>= 32; + c += x_0 * y_3; + zz[3] = (uint)c; + c >>= 32; + zz[4] = (uint)c; + } + + for (int i = 1; i < 4; ++i) + { + ulong c = 0, x_i = x[i]; + c += x_i * y_0 + zz[i + 0]; + zz[i + 0] = (uint)c; + c >>= 32; + c += x_i * y_1 + zz[i + 1]; + zz[i + 1] = (uint)c; + c >>= 32; + c += x_i * y_2 + zz[i + 2]; + zz[i + 2] = (uint)c; + c >>= 32; + c += x_i * y_3 + zz[i + 3]; + zz[i + 3] = (uint)c; + c >>= 32; + zz[i + 4] = (uint)c; + } + } + + public static void Mul(uint[] x, int xOff, uint[] y, int yOff, uint[] zz, int zzOff) + { + ulong y_0 = y[yOff + 0]; + ulong y_1 = y[yOff + 1]; + ulong y_2 = y[yOff + 2]; + ulong y_3 = y[yOff + 3]; + + { + ulong c = 0, x_0 = x[xOff + 0]; + c += x_0 * y_0; + zz[zzOff + 0] = (uint)c; + c >>= 32; + c += x_0 * y_1; + zz[zzOff + 1] = (uint)c; + c >>= 32; + c += x_0 * y_2; + zz[zzOff + 2] = (uint)c; + c >>= 32; + c += x_0 * y_3; + zz[zzOff + 3] = (uint)c; + c >>= 32; + zz[zzOff + 4] = (uint)c; + } + + for (int i = 1; i < 4; ++i) + { + ++zzOff; + ulong c = 0, x_i = x[xOff + i]; + c += x_i * y_0 + zz[zzOff + 0]; + zz[zzOff + 0] = (uint)c; + c >>= 32; + c += x_i * y_1 + zz[zzOff + 1]; + zz[zzOff + 1] = (uint)c; + c >>= 32; + c += x_i * y_2 + zz[zzOff + 2]; + zz[zzOff + 2] = (uint)c; + c >>= 32; + c += x_i * y_3 + zz[zzOff + 3]; + zz[zzOff + 3] = (uint)c; + c >>= 32; + zz[zzOff + 4] = (uint)c; + } + } + + public static uint MulAddTo(uint[] x, uint[] y, uint[] zz) + { + ulong y_0 = y[0]; + ulong y_1 = y[1]; + ulong y_2 = y[2]; + ulong y_3 = y[3]; + + ulong zc = 0; + for (int i = 0; i < 4; ++i) + { + ulong c = 0, x_i = x[i]; + c += x_i * y_0 + zz[i + 0]; + zz[i + 0] = (uint)c; + c >>= 32; + c += x_i * y_1 + zz[i + 1]; + zz[i + 1] = (uint)c; + c >>= 32; + c += x_i * y_2 + zz[i + 2]; + zz[i + 2] = (uint)c; + c >>= 32; + c += x_i * y_3 + zz[i + 3]; + zz[i + 3] = (uint)c; + c >>= 32; + + zc += c + zz[i + 4]; + zz[i + 4] = (uint)zc; + zc >>= 32; + } + return (uint)zc; + } + + public static uint MulAddTo(uint[] x, int xOff, uint[] y, int yOff, uint[] zz, int zzOff) + { + ulong y_0 = y[yOff + 0]; + ulong y_1 = y[yOff + 1]; + ulong y_2 = y[yOff + 2]; + ulong y_3 = y[yOff + 3]; + + ulong zc = 0; + for (int i = 0; i < 4; ++i) + { + ulong c = 0, x_i = x[xOff + i]; + c += x_i * y_0 + zz[zzOff + 0]; + zz[zzOff + 0] = (uint)c; + c >>= 32; + c += x_i * y_1 + zz[zzOff + 1]; + zz[zzOff + 1] = (uint)c; + c >>= 32; + c += x_i * y_2 + zz[zzOff + 2]; + zz[zzOff + 2] = (uint)c; + c >>= 32; + c += x_i * y_3 + zz[zzOff + 3]; + zz[zzOff + 3] = (uint)c; + c >>= 32; + + zc += c + zz[zzOff + 4]; + zz[zzOff + 4] = (uint)zc; + zc >>= 32; + ++zzOff; + } + return (uint)zc; + } + + public static ulong Mul33Add(uint w, uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + { + Debug.Assert(w >> 31 == 0); + + ulong c = 0, wVal = w; + ulong x0 = x[xOff + 0]; + c += wVal * x0 + y[yOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + ulong x1 = x[xOff + 1]; + c += wVal * x1 + x0 + y[yOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + ulong x2 = x[xOff + 2]; + c += wVal * x2 + x1 + y[yOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + ulong x3 = x[xOff + 3]; + c += wVal * x3 + x2 + y[yOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + c += x3; + return c; + } + + public static uint MulWordAddExt(uint x, uint[] yy, int yyOff, uint[] zz, int zzOff) + { + Debug.Assert(yyOff <= 4); + Debug.Assert(zzOff <= 4); + + ulong c = 0, xVal = x; + c += xVal * yy[yyOff + 0] + zz[zzOff + 0]; + zz[zzOff + 0] = (uint)c; + c >>= 32; + c += xVal * yy[yyOff + 1] + zz[zzOff + 1]; + zz[zzOff + 1] = (uint)c; + c >>= 32; + c += xVal * yy[yyOff + 2] + zz[zzOff + 2]; + zz[zzOff + 2] = (uint)c; + c >>= 32; + c += xVal * yy[yyOff + 3] + zz[zzOff + 3]; + zz[zzOff + 3] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint Mul33DWordAdd(uint x, ulong y, uint[] z, int zOff) + { + Debug.Assert(x >> 31 == 0); + Debug.Assert(zOff <= 0); + ulong c = 0, xVal = x; + ulong y00 = y & M; + c += xVal * y00 + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + ulong y01 = y >> 32; + c += xVal * y01 + y00 + z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += y01 + z[zOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += z[zOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint Mul33WordAdd(uint x, uint y, uint[] z, int zOff) + { + Debug.Assert(x >> 31 == 0); + Debug.Assert(zOff <= 1); + ulong c = 0, yVal = y; + c += yVal * x + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += yVal + z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += z[zOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + return c == 0 ? 0 : Nat.IncAt(4, z, zOff, 3); + } + + public static uint MulWordDwordAdd(uint x, ulong y, uint[] z, int zOff) + { + Debug.Assert(zOff <= 1); + ulong c = 0, xVal = x; + c += xVal * y + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += xVal * (y >> 32) + z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += z[zOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + return c == 0 ? 0 : Nat.IncAt(4, z, zOff, 3); + } + + public static uint MulWordsAdd(uint x, uint y, uint[] z, int zOff) + { + Debug.Assert(zOff <= 2); + + ulong c = 0, xVal = x, yVal = y; + c += yVal * xVal + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + return c == 0 ? 0 : Nat.IncAt(4, z, zOff, 2); + } + + public static uint MulWord(uint x, uint[] y, uint[] z, int zOff) + { + ulong c = 0, xVal = x; + int i = 0; + do + { + c += xVal * y[i]; + z[zOff + i] = (uint)c; + c >>= 32; + } + while (++i < 4); + return (uint)c; + } + + public static void Square(uint[] x, uint[] zz) + { + ulong x_0 = x[0]; + ulong zz_1; + + uint c = 0, w; + { + int i = 3, j = 8; + do + { + ulong xVal = x[i--]; + ulong p = xVal * xVal; + zz[--j] = (c << 31) | (uint)(p >> 33); + zz[--j] = (uint)(p >> 1); + c = (uint)p; + } + while (i > 0); + + { + ulong p = x_0 * x_0; + zz_1 = (ulong)(c << 31) | (p >> 33); + zz[0] = (uint)p; + c = (uint)(p >> 32) & 1; + } + } + + ulong x_1 = x[1]; + ulong zz_2 = zz[2]; + + { + zz_1 += x_1 * x_0; + w = (uint)zz_1; + zz[1] = (w << 1) | c; + c = w >> 31; + zz_2 += zz_1 >> 32; + } + + ulong x_2 = x[2]; + ulong zz_3 = zz[3]; + ulong zz_4 = zz[4]; + { + zz_2 += x_2 * x_0; + w = (uint)zz_2; + zz[2] = (w << 1) | c; + c = w >> 31; + zz_3 += (zz_2 >> 32) + x_2 * x_1; + zz_4 += zz_3 >> 32; + zz_3 &= M; + } + + ulong x_3 = x[3]; + ulong zz_5 = zz[5] + (zz_4 >> 32); zz_4 &= M; + ulong zz_6 = zz[6] + (zz_5 >> 32); zz_5 &= M; + { + zz_3 += x_3 * x_0; + w = (uint)zz_3; + zz[3] = (w << 1) | c; + c = w >> 31; + zz_4 += (zz_3 >> 32) + x_3 * x_1; + zz_5 += (zz_4 >> 32) + x_3 * x_2; + zz_6 += zz_5 >> 32; + } + + w = (uint)zz_4; + zz[4] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_5; + zz[5] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_6; + zz[6] = (w << 1) | c; + c = w >> 31; + w = zz[7] + (uint)(zz_6 >> 32); + zz[7] = (w << 1) | c; + } + + public static void Square(uint[] x, int xOff, uint[] zz, int zzOff) + { + ulong x_0 = x[xOff + 0]; + ulong zz_1; + + uint c = 0, w; + { + int i = 3, j = 8; + do + { + ulong xVal = x[xOff + i--]; + ulong p = xVal * xVal; + zz[zzOff + --j] = (c << 31) | (uint)(p >> 33); + zz[zzOff + --j] = (uint)(p >> 1); + c = (uint)p; + } + while (i > 0); + + { + ulong p = x_0 * x_0; + zz_1 = (ulong)(c << 31) | (p >> 33); + zz[zzOff + 0] = (uint)p; + c = (uint)(p >> 32) & 1; + } + } + + ulong x_1 = x[xOff + 1]; + ulong zz_2 = zz[zzOff + 2]; + + { + zz_1 += x_1 * x_0; + w = (uint)zz_1; + zz[zzOff + 1] = (w << 1) | c; + c = w >> 31; + zz_2 += zz_1 >> 32; + } + + ulong x_2 = x[xOff + 2]; + ulong zz_3 = zz[zzOff + 3]; + ulong zz_4 = zz[zzOff + 4]; + { + zz_2 += x_2 * x_0; + w = (uint)zz_2; + zz[zzOff + 2] = (w << 1) | c; + c = w >> 31; + zz_3 += (zz_2 >> 32) + x_2 * x_1; + zz_4 += zz_3 >> 32; + zz_3 &= M; + } + + ulong x_3 = x[xOff + 3]; + ulong zz_5 = zz[zzOff + 5] + (zz_4 >> 32); zz_4 &= M; + ulong zz_6 = zz[zzOff + 6] + (zz_5 >> 32); zz_5 &= M; + { + zz_3 += x_3 * x_0; + w = (uint)zz_3; + zz[zzOff + 3] = (w << 1) | c; + c = w >> 31; + zz_4 += (zz_3 >> 32) + x_3 * x_1; + zz_5 += (zz_4 >> 32) + x_3 * x_2; + zz_6 += zz_5 >> 32; + } + + w = (uint)zz_4; + zz[zzOff + 4] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_5; + zz[zzOff + 5] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_6; + zz[zzOff + 6] = (w << 1) | c; + c = w >> 31; + w = zz[zzOff + 7] + (uint)(zz_6 >> 32); + zz[zzOff + 7] = (w << 1) | c; + } + + public static int Sub(uint[] x, uint[] y, uint[] z) + { + long c = 0; + c += (long)x[0] - y[0]; + z[0] = (uint)c; + c >>= 32; + c += (long)x[1] - y[1]; + z[1] = (uint)c; + c >>= 32; + c += (long)x[2] - y[2]; + z[2] = (uint)c; + c >>= 32; + c += (long)x[3] - y[3]; + z[3] = (uint)c; + c >>= 32; + return (int)c; + } + + public static int Sub(uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + { + long c = 0; + c += (long)x[xOff + 0] - y[yOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += (long)x[xOff + 1] - y[yOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += (long)x[xOff + 2] - y[yOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += (long)x[xOff + 3] - y[yOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + return (int)c; + } + + public static int SubBothFrom(uint[] x, uint[] y, uint[] z) + { + long c = 0; + c += (long)z[0] - x[0] - y[0]; + z[0] = (uint)c; + c >>= 32; + c += (long)z[1] - x[1] - y[1]; + z[1] = (uint)c; + c >>= 32; + c += (long)z[2] - x[2] - y[2]; + z[2] = (uint)c; + c >>= 32; + c += (long)z[3] - x[3] - y[3]; + z[3] = (uint)c; + c >>= 32; + return (int)c; + } + + public static int SubFrom(uint[] x, uint[] z) + { + long c = 0; + c += (long)z[0] - x[0]; + z[0] = (uint)c; + c >>= 32; + c += (long)z[1] - x[1]; + z[1] = (uint)c; + c >>= 32; + c += (long)z[2] - x[2]; + z[2] = (uint)c; + c >>= 32; + c += (long)z[3] - x[3]; + z[3] = (uint)c; + c >>= 32; + return (int)c; + } + + public static int SubFrom(uint[] x, int xOff, uint[] z, int zOff) + { + long c = 0; + c += (long)z[zOff + 0] - x[xOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += (long)z[zOff + 1] - x[xOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += (long)z[zOff + 2] - x[xOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += (long)z[zOff + 3] - x[xOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + return (int)c; + } + + public static BigInteger ToBigInteger(uint[] x) + { + byte[] bs = new byte[16]; + for (int i = 0; i < 4; ++i) + { + uint x_i = x[i]; + if (x_i != 0) + { + Pack.UInt32_To_BE(x_i, bs, (3 - i) << 2); + } + } + return new BigInteger(1, bs); + } + + public static BigInteger ToBigInteger64(ulong[] x) + { + byte[] bs = new byte[16]; + for (int i = 0; i < 2; ++i) + { + ulong x_i = x[i]; + if (x_i != 0UL) + { + Pack.UInt64_To_BE(x_i, bs, (1 - i) << 3); + } + } + return new BigInteger(1, bs); + } + + public static void Zero(uint[] z) + { + z[0] = 0; + z[1] = 0; + z[2] = 0; + z[3] = 0; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat128.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat128.cs.meta new file mode 100644 index 0000000..6da5955 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat128.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2a8e8097308805c4991015aa3ace8b1b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat160.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat160.cs new file mode 100644 index 0000000..f862700 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat160.cs @@ -0,0 +1,870 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Crypto.Utilities; + +namespace Org.BouncyCastle.Math.Raw +{ + internal abstract class Nat160 + { + private const ulong M = 0xFFFFFFFFUL; + + public static uint Add(uint[] x, uint[] y, uint[] z) + { + ulong c = 0; + c += (ulong)x[0] + y[0]; + z[0] = (uint)c; + c >>= 32; + c += (ulong)x[1] + y[1]; + z[1] = (uint)c; + c >>= 32; + c += (ulong)x[2] + y[2]; + z[2] = (uint)c; + c >>= 32; + c += (ulong)x[3] + y[3]; + z[3] = (uint)c; + c >>= 32; + c += (ulong)x[4] + y[4]; + z[4] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint AddBothTo(uint[] x, uint[] y, uint[] z) + { + ulong c = 0; + c += (ulong)x[0] + y[0] + z[0]; + z[0] = (uint)c; + c >>= 32; + c += (ulong)x[1] + y[1] + z[1]; + z[1] = (uint)c; + c >>= 32; + c += (ulong)x[2] + y[2] + z[2]; + z[2] = (uint)c; + c >>= 32; + c += (ulong)x[3] + y[3] + z[3]; + z[3] = (uint)c; + c >>= 32; + c += (ulong)x[4] + y[4] + z[4]; + z[4] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint AddTo(uint[] x, uint[] z) + { + ulong c = 0; + c += (ulong)x[0] + z[0]; + z[0] = (uint)c; + c >>= 32; + c += (ulong)x[1] + z[1]; + z[1] = (uint)c; + c >>= 32; + c += (ulong)x[2] + z[2]; + z[2] = (uint)c; + c >>= 32; + c += (ulong)x[3] + z[3]; + z[3] = (uint)c; + c >>= 32; + c += (ulong)x[4] + z[4]; + z[4] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint AddTo(uint[] x, int xOff, uint[] z, int zOff, uint cIn) + { + ulong c = cIn; + c += (ulong)x[xOff + 0] + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 1] + z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 2] + z[zOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 3] + z[zOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 4] + z[zOff + 4]; + z[zOff + 4] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 5] + z[zOff + 5]; + return (uint)c; + } + + public static uint AddToEachOther(uint[] u, int uOff, uint[] v, int vOff) + { + ulong c = 0; + c += (ulong)u[uOff + 0] + v[vOff + 0]; + u[uOff + 0] = (uint)c; + v[vOff + 0] = (uint)c; + c >>= 32; + c += (ulong)u[uOff + 1] + v[vOff + 1]; + u[uOff + 1] = (uint)c; + v[vOff + 1] = (uint)c; + c >>= 32; + c += (ulong)u[uOff + 2] + v[vOff + 2]; + u[uOff + 2] = (uint)c; + v[vOff + 2] = (uint)c; + c >>= 32; + c += (ulong)u[uOff + 3] + v[vOff + 3]; + u[uOff + 3] = (uint)c; + v[vOff + 3] = (uint)c; + c >>= 32; + c += (ulong)u[uOff + 4] + v[vOff + 4]; + u[uOff + 4] = (uint)c; + v[vOff + 4] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static void Copy(uint[] x, uint[] z) + { + z[0] = x[0]; + z[1] = x[1]; + z[2] = x[2]; + z[3] = x[3]; + z[4] = x[4]; + } + + public static void Copy(uint[] x, int xOff, uint[] z, int zOff) + { + z[zOff + 0] = x[xOff + 0]; + z[zOff + 1] = x[xOff + 1]; + z[zOff + 2] = x[xOff + 2]; + z[zOff + 3] = x[xOff + 3]; + z[zOff + 4] = x[xOff + 4]; + } + + public static uint[] Create() + { + return new uint[5]; + } + + public static uint[] CreateExt() + { + return new uint[10]; + } + + public static bool Diff(uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + { + bool pos = Gte(x, xOff, y, yOff); + if (pos) + { + Sub(x, xOff, y, yOff, z, zOff); + } + else + { + Sub(y, yOff, x, xOff, z, zOff); + } + return pos; + } + + public static bool Eq(uint[] x, uint[] y) + { + for (int i = 4; i >= 0; --i) + { + if (x[i] != y[i]) + return false; + } + return true; + } + + public static uint GetBit(uint[] x, int bit) + { + if (bit == 0) + { + return x[0] & 1; + } + int w = bit >> 5; + if (w < 0 || w >= 5) + { + return 0; + } + int b = bit & 31; + return (x[w] >> b) & 1; + } + + public static bool Gte(uint[] x, uint[] y) + { + for (int i = 4; i >= 0; --i) + { + uint x_i = x[i], y_i = y[i]; + if (x_i < y_i) + return false; + if (x_i > y_i) + return true; + } + return true; + } + + public static bool Gte(uint[] x, int xOff, uint[] y, int yOff) + { + for (int i = 4; i >= 0; --i) + { + uint x_i = x[xOff + i], y_i = y[yOff + i]; + if (x_i < y_i) + return false; + if (x_i > y_i) + return true; + } + return true; + } + + public static bool IsOne(uint[] x) + { + if (x[0] != 1) + { + return false; + } + for (int i = 1; i < 5; ++i) + { + if (x[i] != 0) + { + return false; + } + } + return true; + } + + public static bool IsZero(uint[] x) + { + for (int i = 0; i < 5; ++i) + { + if (x[i] != 0) + { + return false; + } + } + return true; + } + + public static void Mul(uint[] x, uint[] y, uint[] zz) + { + ulong y_0 = y[0]; + ulong y_1 = y[1]; + ulong y_2 = y[2]; + ulong y_3 = y[3]; + ulong y_4 = y[4]; + + { + ulong c = 0, x_0 = x[0]; + c += x_0 * y_0; + zz[0] = (uint)c; + c >>= 32; + c += x_0 * y_1; + zz[1] = (uint)c; + c >>= 32; + c += x_0 * y_2; + zz[2] = (uint)c; + c >>= 32; + c += x_0 * y_3; + zz[3] = (uint)c; + c >>= 32; + c += x_0 * y_4; + zz[4] = (uint)c; + c >>= 32; + zz[5] = (uint)c; + } + + for (int i = 1; i < 5; ++i) + { + ulong c = 0, x_i = x[i]; + c += x_i * y_0 + zz[i + 0]; + zz[i + 0] = (uint)c; + c >>= 32; + c += x_i * y_1 + zz[i + 1]; + zz[i + 1] = (uint)c; + c >>= 32; + c += x_i * y_2 + zz[i + 2]; + zz[i + 2] = (uint)c; + c >>= 32; + c += x_i * y_3 + zz[i + 3]; + zz[i + 3] = (uint)c; + c >>= 32; + c += x_i * y_4 + zz[i + 4]; + zz[i + 4] = (uint)c; + c >>= 32; + zz[i + 5] = (uint)c; + } + } + + public static void Mul(uint[] x, int xOff, uint[] y, int yOff, uint[] zz, int zzOff) + { + ulong y_0 = y[yOff + 0]; + ulong y_1 = y[yOff + 1]; + ulong y_2 = y[yOff + 2]; + ulong y_3 = y[yOff + 3]; + ulong y_4 = y[yOff + 4]; + + { + ulong c = 0, x_0 = x[xOff + 0]; + c += x_0 * y_0; + zz[zzOff + 0] = (uint)c; + c >>= 32; + c += x_0 * y_1; + zz[zzOff + 1] = (uint)c; + c >>= 32; + c += x_0 * y_2; + zz[zzOff + 2] = (uint)c; + c >>= 32; + c += x_0 * y_3; + zz[zzOff + 3] = (uint)c; + c >>= 32; + c += x_0 * y_4; + zz[zzOff + 4] = (uint)c; + c >>= 32; + zz[zzOff + 5] = (uint)c; + } + + for (int i = 1; i < 5; ++i) + { + ++zzOff; + ulong c = 0, x_i = x[xOff + i]; + c += x_i * y_0 + zz[zzOff + 0]; + zz[zzOff + 0] = (uint)c; + c >>= 32; + c += x_i * y_1 + zz[zzOff + 1]; + zz[zzOff + 1] = (uint)c; + c >>= 32; + c += x_i * y_2 + zz[zzOff + 2]; + zz[zzOff + 2] = (uint)c; + c >>= 32; + c += x_i * y_3 + zz[zzOff + 3]; + zz[zzOff + 3] = (uint)c; + c >>= 32; + c += x_i * y_4 + zz[zzOff + 4]; + zz[zzOff + 4] = (uint)c; + c >>= 32; + zz[zzOff + 5] = (uint)c; + } + } + + public static uint MulAddTo(uint[] x, uint[] y, uint[] zz) + { + ulong y_0 = y[0]; + ulong y_1 = y[1]; + ulong y_2 = y[2]; + ulong y_3 = y[3]; + ulong y_4 = y[4]; + + ulong zc = 0; + for (int i = 0; i < 5; ++i) + { + ulong c = 0, x_i = x[i]; + c += x_i * y_0 + zz[i + 0]; + zz[i + 0] = (uint)c; + c >>= 32; + c += x_i * y_1 + zz[i + 1]; + zz[i + 1] = (uint)c; + c >>= 32; + c += x_i * y_2 + zz[i + 2]; + zz[i + 2] = (uint)c; + c >>= 32; + c += x_i * y_3 + zz[i + 3]; + zz[i + 3] = (uint)c; + c >>= 32; + c += x_i * y_4 + zz[i + 4]; + zz[i + 4] = (uint)c; + c >>= 32; + + zc += c + zz[i + 5]; + zz[i + 5] = (uint)zc; + zc >>= 32; + } + return (uint)zc; + } + + public static uint MulAddTo(uint[] x, int xOff, uint[] y, int yOff, uint[] zz, int zzOff) + { + ulong y_0 = y[yOff + 0]; + ulong y_1 = y[yOff + 1]; + ulong y_2 = y[yOff + 2]; + ulong y_3 = y[yOff + 3]; + ulong y_4 = y[yOff + 4]; + + ulong zc = 0; + for (int i = 0; i < 5; ++i) + { + ulong c = 0, x_i = x[xOff + i]; + c += x_i * y_0 + zz[zzOff + 0]; + zz[zzOff + 0] = (uint)c; + c >>= 32; + c += x_i * y_1 + zz[zzOff + 1]; + zz[zzOff + 1] = (uint)c; + c >>= 32; + c += x_i * y_2 + zz[zzOff + 2]; + zz[zzOff + 2] = (uint)c; + c >>= 32; + c += x_i * y_3 + zz[zzOff + 3]; + zz[zzOff + 3] = (uint)c; + c >>= 32; + c += x_i * y_4 + zz[zzOff + 4]; + zz[zzOff + 4] = (uint)c; + c >>= 32; + + zc += c + zz[zzOff + 5]; + zz[zzOff + 5] = (uint)zc; + zc >>= 32; + ++zzOff; + } + return (uint)zc; + } + + public static ulong Mul33Add(uint w, uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + { + Debug.Assert(w >> 31 == 0); + + ulong c = 0, wVal = w; + ulong x0 = x[xOff + 0]; + c += wVal * x0 + y[yOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + ulong x1 = x[xOff + 1]; + c += wVal * x1 + x0 + y[yOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + ulong x2 = x[xOff + 2]; + c += wVal * x2 + x1 + y[yOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + ulong x3 = x[xOff + 3]; + c += wVal * x3 + x2 + y[yOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + ulong x4 = x[xOff + 4]; + c += wVal * x4 + x3 + y[yOff + 4]; + z[zOff + 4] = (uint)c; + c >>= 32; + c += x4; + return c; + } + + public static uint MulWordAddExt(uint x, uint[] yy, int yyOff, uint[] zz, int zzOff) + { + Debug.Assert(yyOff <= 5); + Debug.Assert(zzOff <= 5); + + ulong c = 0, xVal = x; + c += xVal * yy[yyOff + 0] + zz[zzOff + 0]; + zz[zzOff + 0] = (uint)c; + c >>= 32; + c += xVal * yy[yyOff + 1] + zz[zzOff + 1]; + zz[zzOff + 1] = (uint)c; + c >>= 32; + c += xVal * yy[yyOff + 2] + zz[zzOff + 2]; + zz[zzOff + 2] = (uint)c; + c >>= 32; + c += xVal * yy[yyOff + 3] + zz[zzOff + 3]; + zz[zzOff + 3] = (uint)c; + c >>= 32; + c += xVal * yy[yyOff + 4] + zz[zzOff + 4]; + zz[zzOff + 4] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint Mul33DWordAdd(uint x, ulong y, uint[] z, int zOff) + { + Debug.Assert(x >> 31 == 0); + Debug.Assert(zOff <= 1); + ulong c = 0, xVal = x; + ulong y00 = y & M; + c += xVal * y00 + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + ulong y01 = y >> 32; + c += xVal * y01 + y00 + z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += y01 + z[zOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += z[zOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + return c == 0 ? 0 : Nat.IncAt(5, z, zOff, 4); + } + + public static uint Mul33WordAdd(uint x, uint y, uint[] z, int zOff) + { + Debug.Assert(x >> 31 == 0); + Debug.Assert(zOff <= 2); + ulong c = 0, yVal = y; + c += yVal * x + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += yVal + z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += z[zOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + return c == 0 ? 0 : Nat.IncAt(5, z, zOff, 3); + } + + public static uint MulWordDwordAdd(uint x, ulong y, uint[] z, int zOff) + { + Debug.Assert(zOff <= 2); + ulong c = 0, xVal = x; + c += xVal * y + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += xVal * (y >> 32) + z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += z[zOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + return c == 0 ? 0 : Nat.IncAt(5, z, zOff, 3); + } + + public static uint MulWordsAdd(uint x, uint y, uint[] z, int zOff) + { + Debug.Assert(zOff <= 3); + + ulong c = 0, xVal = x, yVal = y; + c += yVal * xVal + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + return c == 0 ? 0 : Nat.IncAt(5, z, zOff, 2); + } + + public static uint MulWord(uint x, uint[] y, uint[] z, int zOff) + { + ulong c = 0, xVal = x; + int i = 0; + do + { + c += xVal * y[i]; + z[zOff + i] = (uint)c; + c >>= 32; + } + while (++i < 5); + return (uint)c; + } + + public static void Square(uint[] x, uint[] zz) + { + ulong x_0 = x[0]; + ulong zz_1; + + uint c = 0, w; + { + int i = 4, j = 10; + do + { + ulong xVal = x[i--]; + ulong p = xVal * xVal; + zz[--j] = (c << 31) | (uint)(p >> 33); + zz[--j] = (uint)(p >> 1); + c = (uint)p; + } + while (i > 0); + + { + ulong p = x_0 * x_0; + zz_1 = (ulong)(c << 31) | (p >> 33); + zz[0] = (uint)p; + c = (uint)(p >> 32) & 1; + } + } + + ulong x_1 = x[1]; + ulong zz_2 = zz[2]; + + { + zz_1 += x_1 * x_0; + w = (uint)zz_1; + zz[1] = (w << 1) | c; + c = w >> 31; + zz_2 += zz_1 >> 32; + } + + ulong x_2 = x[2]; + ulong zz_3 = zz[3]; + ulong zz_4 = zz[4]; + { + zz_2 += x_2 * x_0; + w = (uint)zz_2; + zz[2] = (w << 1) | c; + c = w >> 31; + zz_3 += (zz_2 >> 32) + x_2 * x_1; + zz_4 += zz_3 >> 32; + zz_3 &= M; + } + + ulong x_3 = x[3]; + ulong zz_5 = zz[5] + (zz_4 >> 32); zz_4 &= M; + ulong zz_6 = zz[6] + (zz_5 >> 32); zz_5 &= M; + { + zz_3 += x_3 * x_0; + w = (uint)zz_3; + zz[3] = (w << 1) | c; + c = w >> 31; + zz_4 += (zz_3 >> 32) + x_3 * x_1; + zz_5 += (zz_4 >> 32) + x_3 * x_2; + zz_4 &= M; + zz_6 += zz_5 >> 32; + zz_5 &= M; + } + + ulong x_4 = x[4]; + ulong zz_7 = zz[7] + (zz_6 >> 32); zz_6 &= M; + ulong zz_8 = zz[8] + (zz_7 >> 32); zz_7 &= M; + { + zz_4 += x_4 * x_0; + w = (uint)zz_4; + zz[4] = (w << 1) | c; + c = w >> 31; + zz_5 += (zz_4 >> 32) + x_4 * x_1; + zz_6 += (zz_5 >> 32) + x_4 * x_2; + zz_7 += (zz_6 >> 32) + x_4 * x_3; + zz_8 += zz_7 >> 32; + } + + w = (uint)zz_5; + zz[5] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_6; + zz[6] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_7; + zz[7] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_8; + zz[8] = (w << 1) | c; + c = w >> 31; + w = zz[9] + (uint)(zz_8 >> 32); + zz[9] = (w << 1) | c; + } + + public static void Square(uint[] x, int xOff, uint[] zz, int zzOff) + { + ulong x_0 = x[xOff + 0]; + ulong zz_1; + + uint c = 0, w; + { + int i = 4, j = 10; + do + { + ulong xVal = x[xOff + i--]; + ulong p = xVal * xVal; + zz[zzOff + --j] = (c << 31) | (uint)(p >> 33); + zz[zzOff + --j] = (uint)(p >> 1); + c = (uint)p; + } + while (i > 0); + + { + ulong p = x_0 * x_0; + zz_1 = (ulong)(c << 31) | (p >> 33); + zz[zzOff + 0] = (uint)p; + c = (uint)(p >> 32) & 1; + } + } + + ulong x_1 = x[xOff + 1]; + ulong zz_2 = zz[zzOff + 2]; + + { + zz_1 += x_1 * x_0; + w = (uint)zz_1; + zz[zzOff + 1] = (w << 1) | c; + c = w >> 31; + zz_2 += zz_1 >> 32; + } + + ulong x_2 = x[xOff + 2]; + ulong zz_3 = zz[zzOff + 3]; + ulong zz_4 = zz[zzOff + 4]; + { + zz_2 += x_2 * x_0; + w = (uint)zz_2; + zz[zzOff + 2] = (w << 1) | c; + c = w >> 31; + zz_3 += (zz_2 >> 32) + x_2 * x_1; + zz_4 += zz_3 >> 32; + zz_3 &= M; + } + + ulong x_3 = x[xOff + 3]; + ulong zz_5 = zz[zzOff + 5] + (zz_4 >> 32); zz_4 &= M; + ulong zz_6 = zz[zzOff + 6] + (zz_5 >> 32); zz_5 &= M; + { + zz_3 += x_3 * x_0; + w = (uint)zz_3; + zz[zzOff + 3] = (w << 1) | c; + c = w >> 31; + zz_4 += (zz_3 >> 32) + x_3 * x_1; + zz_5 += (zz_4 >> 32) + x_3 * x_2; + zz_4 &= M; + zz_6 += zz_5 >> 32; + zz_5 &= M; + } + + ulong x_4 = x[xOff + 4]; + ulong zz_7 = zz[zzOff + 7] + (zz_6 >> 32); zz_6 &= M; + ulong zz_8 = zz[zzOff + 8] + (zz_7 >> 32); zz_7 &= M; + { + zz_4 += x_4 * x_0; + w = (uint)zz_4; + zz[zzOff + 4] = (w << 1) | c; + c = w >> 31; + zz_5 += (zz_4 >> 32) + x_4 * x_1; + zz_6 += (zz_5 >> 32) + x_4 * x_2; + zz_7 += (zz_6 >> 32) + x_4 * x_3; + zz_8 += zz_7 >> 32; + } + + w = (uint)zz_5; + zz[zzOff + 5] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_6; + zz[zzOff + 6] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_7; + zz[zzOff + 7] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_8; + zz[zzOff + 8] = (w << 1) | c; + c = w >> 31; + w = zz[zzOff + 9] + (uint)(zz_8 >> 32); + zz[zzOff + 9] = (w << 1) | c; + } + + public static int Sub(uint[] x, uint[] y, uint[] z) + { + long c = 0; + c += (long)x[0] - y[0]; + z[0] = (uint)c; + c >>= 32; + c += (long)x[1] - y[1]; + z[1] = (uint)c; + c >>= 32; + c += (long)x[2] - y[2]; + z[2] = (uint)c; + c >>= 32; + c += (long)x[3] - y[3]; + z[3] = (uint)c; + c >>= 32; + c += (long)x[4] - y[4]; + z[4] = (uint)c; + c >>= 32; + return (int)c; + } + + public static int Sub(uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + { + long c = 0; + c += (long)x[xOff + 0] - y[yOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += (long)x[xOff + 1] - y[yOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += (long)x[xOff + 2] - y[yOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += (long)x[xOff + 3] - y[yOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + c += (long)x[xOff + 4] - y[yOff + 4]; + z[zOff + 4] = (uint)c; + c >>= 32; + return (int)c; + } + + public static int SubBothFrom(uint[] x, uint[] y, uint[] z) + { + long c = 0; + c += (long)z[0] - x[0] - y[0]; + z[0] = (uint)c; + c >>= 32; + c += (long)z[1] - x[1] - y[1]; + z[1] = (uint)c; + c >>= 32; + c += (long)z[2] - x[2] - y[2]; + z[2] = (uint)c; + c >>= 32; + c += (long)z[3] - x[3] - y[3]; + z[3] = (uint)c; + c >>= 32; + c += (long)z[4] - x[4] - y[4]; + z[4] = (uint)c; + c >>= 32; + return (int)c; + } + + public static int SubFrom(uint[] x, uint[] z) + { + long c = 0; + c += (long)z[0] - x[0]; + z[0] = (uint)c; + c >>= 32; + c += (long)z[1] - x[1]; + z[1] = (uint)c; + c >>= 32; + c += (long)z[2] - x[2]; + z[2] = (uint)c; + c >>= 32; + c += (long)z[3] - x[3]; + z[3] = (uint)c; + c >>= 32; + c += (long)z[4] - x[4]; + z[4] = (uint)c; + c >>= 32; + return (int)c; + } + + public static int SubFrom(uint[] x, int xOff, uint[] z, int zOff) + { + long c = 0; + c += (long)z[zOff + 0] - x[xOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += (long)z[zOff + 1] - x[xOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += (long)z[zOff + 2] - x[xOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += (long)z[zOff + 3] - x[xOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + c += (long)z[zOff + 4] - x[xOff + 4]; + z[zOff + 4] = (uint)c; + c >>= 32; + return (int)c; + } + + public static BigInteger ToBigInteger(uint[] x) + { + byte[] bs = new byte[20]; + for (int i = 0; i < 5; ++i) + { + uint x_i = x[i]; + if (x_i != 0) + { + Pack.UInt32_To_BE(x_i, bs, (4 - i) << 2); + } + } + return new BigInteger(1, bs); + } + + public static void Zero(uint[] z) + { + z[0] = 0; + z[1] = 0; + z[2] = 0; + z[3] = 0; + z[4] = 0; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat160.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat160.cs.meta new file mode 100644 index 0000000..8f4c3df --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat160.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bb5ccbebaf8adab468ca8b908c8c886f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat192.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat192.cs new file mode 100644 index 0000000..7522907 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat192.cs @@ -0,0 +1,1037 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Crypto.Utilities; + +namespace Org.BouncyCastle.Math.Raw +{ + internal abstract class Nat192 + { + private const ulong M = 0xFFFFFFFFUL; + + public static uint Add(uint[] x, uint[] y, uint[] z) + { + ulong c = 0; + c += (ulong)x[0] + y[0]; + z[0] = (uint)c; + c >>= 32; + c += (ulong)x[1] + y[1]; + z[1] = (uint)c; + c >>= 32; + c += (ulong)x[2] + y[2]; + z[2] = (uint)c; + c >>= 32; + c += (ulong)x[3] + y[3]; + z[3] = (uint)c; + c >>= 32; + c += (ulong)x[4] + y[4]; + z[4] = (uint)c; + c >>= 32; + c += (ulong)x[5] + y[5]; + z[5] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint AddBothTo(uint[] x, uint[] y, uint[] z) + { + ulong c = 0; + c += (ulong)x[0] + y[0] + z[0]; + z[0] = (uint)c; + c >>= 32; + c += (ulong)x[1] + y[1] + z[1]; + z[1] = (uint)c; + c >>= 32; + c += (ulong)x[2] + y[2] + z[2]; + z[2] = (uint)c; + c >>= 32; + c += (ulong)x[3] + y[3] + z[3]; + z[3] = (uint)c; + c >>= 32; + c += (ulong)x[4] + y[4] + z[4]; + z[4] = (uint)c; + c >>= 32; + c += (ulong)x[5] + y[5] + z[5]; + z[5] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint AddTo(uint[] x, uint[] z) + { + ulong c = 0; + c += (ulong)x[0] + z[0]; + z[0] = (uint)c; + c >>= 32; + c += (ulong)x[1] + z[1]; + z[1] = (uint)c; + c >>= 32; + c += (ulong)x[2] + z[2]; + z[2] = (uint)c; + c >>= 32; + c += (ulong)x[3] + z[3]; + z[3] = (uint)c; + c >>= 32; + c += (ulong)x[4] + z[4]; + z[4] = (uint)c; + c >>= 32; + c += (ulong)x[5] + z[5]; + z[5] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint AddTo(uint[] x, int xOff, uint[] z, int zOff, uint cIn) + { + ulong c = cIn; + c += (ulong)x[xOff + 0] + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 1] + z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 2] + z[zOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 3] + z[zOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 4] + z[zOff + 4]; + z[zOff + 4] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 5] + z[zOff + 5]; + z[zOff + 5] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint AddToEachOther(uint[] u, int uOff, uint[] v, int vOff) + { + ulong c = 0; + c += (ulong)u[uOff + 0] + v[vOff + 0]; + u[uOff + 0] = (uint)c; + v[vOff + 0] = (uint)c; + c >>= 32; + c += (ulong)u[uOff + 1] + v[vOff + 1]; + u[uOff + 1] = (uint)c; + v[vOff + 1] = (uint)c; + c >>= 32; + c += (ulong)u[uOff + 2] + v[vOff + 2]; + u[uOff + 2] = (uint)c; + v[vOff + 2] = (uint)c; + c >>= 32; + c += (ulong)u[uOff + 3] + v[vOff + 3]; + u[uOff + 3] = (uint)c; + v[vOff + 3] = (uint)c; + c >>= 32; + c += (ulong)u[uOff + 4] + v[vOff + 4]; + u[uOff + 4] = (uint)c; + v[vOff + 4] = (uint)c; + c >>= 32; + c += (ulong)u[uOff + 5] + v[vOff + 5]; + u[uOff + 5] = (uint)c; + v[vOff + 5] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static void Copy(uint[] x, uint[] z) + { + z[0] = x[0]; + z[1] = x[1]; + z[2] = x[2]; + z[3] = x[3]; + z[4] = x[4]; + z[5] = x[5]; + } + + public static void Copy(uint[] x, int xOff, uint[] z, int zOff) + { + z[zOff + 0] = x[xOff + 0]; + z[zOff + 1] = x[xOff + 1]; + z[zOff + 2] = x[xOff + 2]; + z[zOff + 3] = x[xOff + 3]; + z[zOff + 4] = x[xOff + 4]; + z[zOff + 5] = x[xOff + 5]; + } + + public static void Copy64(ulong[] x, ulong[] z) + { + z[0] = x[0]; + z[1] = x[1]; + z[2] = x[2]; + } + + public static void Copy64(ulong[] x, int xOff, ulong[] z, int zOff) + { + z[zOff + 0] = x[xOff + 0]; + z[zOff + 1] = x[xOff + 1]; + z[zOff + 2] = x[xOff + 2]; + } + + public static uint[] Create() + { + return new uint[6]; + } + + public static ulong[] Create64() + { + return new ulong[3]; + } + + public static uint[] CreateExt() + { + return new uint[12]; + } + + public static ulong[] CreateExt64() + { + return new ulong[6]; + } + + public static bool Diff(uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + { + bool pos = Gte(x, xOff, y, yOff); + if (pos) + { + Sub(x, xOff, y, yOff, z, zOff); + } + else + { + Sub(y, yOff, x, xOff, z, zOff); + } + return pos; + } + + public static bool Eq(uint[] x, uint[] y) + { + for (int i = 5; i >= 0; --i) + { + if (x[i] != y[i]) + return false; + } + return true; + } + + public static bool Eq64(ulong[] x, ulong[] y) + { + for (int i = 2; i >= 0; --i) + { + if (x[i] != y[i]) + { + return false; + } + } + return true; + } + + public static uint GetBit(uint[] x, int bit) + { + if (bit == 0) + { + return x[0] & 1; + } + int w = bit >> 5; + if (w < 0 || w >= 6) + { + return 0; + } + int b = bit & 31; + return (x[w] >> b) & 1; + } + + public static bool Gte(uint[] x, uint[] y) + { + for (int i = 5; i >= 0; --i) + { + uint x_i = x[i], y_i = y[i]; + if (x_i < y_i) + return false; + if (x_i > y_i) + return true; + } + return true; + } + + public static bool Gte(uint[] x, int xOff, uint[] y, int yOff) + { + for (int i = 5; i >= 0; --i) + { + uint x_i = x[xOff + i], y_i = y[yOff + i]; + if (x_i < y_i) + return false; + if (x_i > y_i) + return true; + } + return true; + } + + public static bool IsOne(uint[] x) + { + if (x[0] != 1) + { + return false; + } + for (int i = 1; i < 6; ++i) + { + if (x[i] != 0) + { + return false; + } + } + return true; + } + + public static bool IsOne64(ulong[] x) + { + if (x[0] != 1UL) + { + return false; + } + for (int i = 1; i < 3; ++i) + { + if (x[i] != 0UL) + { + return false; + } + } + return true; + } + + public static bool IsZero(uint[] x) + { + for (int i = 0; i < 6; ++i) + { + if (x[i] != 0) + { + return false; + } + } + return true; + } + + public static bool IsZero64(ulong[] x) + { + for (int i = 0; i < 3; ++i) + { + if (x[i] != 0UL) + { + return false; + } + } + return true; + } + + public static void Mul(uint[] x, uint[] y, uint[] zz) + { + ulong y_0 = y[0]; + ulong y_1 = y[1]; + ulong y_2 = y[2]; + ulong y_3 = y[3]; + ulong y_4 = y[4]; + ulong y_5 = y[5]; + + { + ulong c = 0, x_0 = x[0]; + c += x_0 * y_0; + zz[0] = (uint)c; + c >>= 32; + c += x_0 * y_1; + zz[1] = (uint)c; + c >>= 32; + c += x_0 * y_2; + zz[2] = (uint)c; + c >>= 32; + c += x_0 * y_3; + zz[3] = (uint)c; + c >>= 32; + c += x_0 * y_4; + zz[4] = (uint)c; + c >>= 32; + c += x_0 * y_5; + zz[5] = (uint)c; + c >>= 32; + zz[6] = (uint)c; + } + + for (int i = 1; i < 6; ++i) + { + ulong c = 0, x_i = x[i]; + c += x_i * y_0 + zz[i + 0]; + zz[i + 0] = (uint)c; + c >>= 32; + c += x_i * y_1 + zz[i + 1]; + zz[i + 1] = (uint)c; + c >>= 32; + c += x_i * y_2 + zz[i + 2]; + zz[i + 2] = (uint)c; + c >>= 32; + c += x_i * y_3 + zz[i + 3]; + zz[i + 3] = (uint)c; + c >>= 32; + c += x_i * y_4 + zz[i + 4]; + zz[i + 4] = (uint)c; + c >>= 32; + c += x_i * y_5 + zz[i + 5]; + zz[i + 5] = (uint)c; + c >>= 32; + zz[i + 6] = (uint)c; + } + } + + public static void Mul(uint[] x, int xOff, uint[] y, int yOff, uint[] zz, int zzOff) + { + ulong y_0 = y[yOff + 0]; + ulong y_1 = y[yOff + 1]; + ulong y_2 = y[yOff + 2]; + ulong y_3 = y[yOff + 3]; + ulong y_4 = y[yOff + 4]; + ulong y_5 = y[yOff + 5]; + + { + ulong c = 0, x_0 = x[xOff + 0]; + c += x_0 * y_0; + zz[zzOff + 0] = (uint)c; + c >>= 32; + c += x_0 * y_1; + zz[zzOff + 1] = (uint)c; + c >>= 32; + c += x_0 * y_2; + zz[zzOff + 2] = (uint)c; + c >>= 32; + c += x_0 * y_3; + zz[zzOff + 3] = (uint)c; + c >>= 32; + c += x_0 * y_4; + zz[zzOff + 4] = (uint)c; + c >>= 32; + c += x_0 * y_5; + zz[zzOff + 5] = (uint)c; + c >>= 32; + zz[zzOff + 6] = (uint)c; + } + + for (int i = 1; i < 6; ++i) + { + ++zzOff; + ulong c = 0, x_i = x[xOff + i]; + c += x_i * y_0 + zz[zzOff + 0]; + zz[zzOff + 0] = (uint)c; + c >>= 32; + c += x_i * y_1 + zz[zzOff + 1]; + zz[zzOff + 1] = (uint)c; + c >>= 32; + c += x_i * y_2 + zz[zzOff + 2]; + zz[zzOff + 2] = (uint)c; + c >>= 32; + c += x_i * y_3 + zz[zzOff + 3]; + zz[zzOff + 3] = (uint)c; + c >>= 32; + c += x_i * y_4 + zz[zzOff + 4]; + zz[zzOff + 4] = (uint)c; + c >>= 32; + c += x_i * y_5 + zz[zzOff + 5]; + zz[zzOff + 5] = (uint)c; + c >>= 32; + zz[zzOff + 6] = (uint)c; + } + } + + public static uint MulAddTo(uint[] x, uint[] y, uint[] zz) + { + ulong y_0 = y[0]; + ulong y_1 = y[1]; + ulong y_2 = y[2]; + ulong y_3 = y[3]; + ulong y_4 = y[4]; + ulong y_5 = y[5]; + + ulong zc = 0; + for (int i = 0; i < 6; ++i) + { + ulong c = 0, x_i = x[i]; + c += x_i * y_0 + zz[i + 0]; + zz[i + 0] = (uint)c; + c >>= 32; + c += x_i * y_1 + zz[i + 1]; + zz[i + 1] = (uint)c; + c >>= 32; + c += x_i * y_2 + zz[i + 2]; + zz[i + 2] = (uint)c; + c >>= 32; + c += x_i * y_3 + zz[i + 3]; + zz[i + 3] = (uint)c; + c >>= 32; + c += x_i * y_4 + zz[i + 4]; + zz[i + 4] = (uint)c; + c >>= 32; + c += x_i * y_5 + zz[i + 5]; + zz[i + 5] = (uint)c; + c >>= 32; + + zc += c + zz[i + 6]; + zz[i + 6] = (uint)zc; + zc >>= 32; + } + return (uint)zc; + } + + public static uint MulAddTo(uint[] x, int xOff, uint[] y, int yOff, uint[] zz, int zzOff) + { + ulong y_0 = y[yOff + 0]; + ulong y_1 = y[yOff + 1]; + ulong y_2 = y[yOff + 2]; + ulong y_3 = y[yOff + 3]; + ulong y_4 = y[yOff + 4]; + ulong y_5 = y[yOff + 5]; + + ulong zc = 0; + for (int i = 0; i < 6; ++i) + { + ulong c = 0, x_i = x[xOff + i]; + c += x_i * y_0 + zz[zzOff + 0]; + zz[zzOff + 0] = (uint)c; + c >>= 32; + c += x_i * y_1 + zz[zzOff + 1]; + zz[zzOff + 1] = (uint)c; + c >>= 32; + c += x_i * y_2 + zz[zzOff + 2]; + zz[zzOff + 2] = (uint)c; + c >>= 32; + c += x_i * y_3 + zz[zzOff + 3]; + zz[zzOff + 3] = (uint)c; + c >>= 32; + c += x_i * y_4 + zz[zzOff + 4]; + zz[zzOff + 4] = (uint)c; + c >>= 32; + c += x_i * y_5 + zz[zzOff + 5]; + zz[zzOff + 5] = (uint)c; + c >>= 32; + + zc += c + zz[zzOff + 6]; + zz[zzOff + 6] = (uint)zc; + zc >>= 32; + ++zzOff; + } + return (uint)zc; + } + + public static ulong Mul33Add(uint w, uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + { + Debug.Assert(w >> 31 == 0); + + ulong c = 0, wVal = w; + ulong x0 = x[xOff + 0]; + c += wVal * x0 + y[yOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + ulong x1 = x[xOff + 1]; + c += wVal * x1 + x0 + y[yOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + ulong x2 = x[xOff + 2]; + c += wVal * x2 + x1 + y[yOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + ulong x3 = x[xOff + 3]; + c += wVal * x3 + x2 + y[yOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + ulong x4 = x[xOff + 4]; + c += wVal * x4 + x3 + y[yOff + 4]; + z[zOff + 4] = (uint)c; + c >>= 32; + ulong x5 = x[xOff + 5]; + c += wVal * x5 + x4 + y[yOff + 5]; + z[zOff + 5] = (uint)c; + c >>= 32; + c += x5; + return c; + } + + public static uint MulWordAddExt(uint x, uint[] yy, int yyOff, uint[] zz, int zzOff) + { + Debug.Assert(yyOff <= 6); + Debug.Assert(zzOff <= 6); + ulong c = 0, xVal = x; + c += xVal * yy[yyOff + 0] + zz[zzOff + 0]; + zz[zzOff + 0] = (uint)c; + c >>= 32; + c += xVal * yy[yyOff + 1] + zz[zzOff + 1]; + zz[zzOff + 1] = (uint)c; + c >>= 32; + c += xVal * yy[yyOff + 2] + zz[zzOff + 2]; + zz[zzOff + 2] = (uint)c; + c >>= 32; + c += xVal * yy[yyOff + 3] + zz[zzOff + 3]; + zz[zzOff + 3] = (uint)c; + c >>= 32; + c += xVal * yy[yyOff + 4] + zz[zzOff + 4]; + zz[zzOff + 4] = (uint)c; + c >>= 32; + c += xVal * yy[yyOff + 5] + zz[zzOff + 5]; + zz[zzOff + 5] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint Mul33DWordAdd(uint x, ulong y, uint[] z, int zOff) + { + Debug.Assert(x >> 31 == 0); + Debug.Assert(zOff <= 2); + ulong c = 0, xVal = x; + ulong y00 = y & M; + c += xVal * y00 + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + ulong y01 = y >> 32; + c += xVal * y01 + y00 + z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += y01 + z[zOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += z[zOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + return c == 0 ? 0 : Nat.IncAt(6, z, zOff, 4); + } + + public static uint Mul33WordAdd(uint x, uint y, uint[] z, int zOff) + { + Debug.Assert(x >> 31 == 0); + Debug.Assert(zOff <=3); + ulong c = 0, yVal = y; + c += yVal * x + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += yVal + z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += z[zOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + return c == 0 ? 0 : Nat.IncAt(6, z, zOff, 3); + } + + public static uint MulWordDwordAdd(uint x, ulong y, uint[] z, int zOff) + { + Debug.Assert(zOff <= 3); + ulong c = 0, xVal = x; + c += xVal * y + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += xVal * (y >> 32) + z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += z[zOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + return c == 0 ? 0 : Nat.IncAt(6, z, zOff, 3); + } + + public static uint MulWord(uint x, uint[] y, uint[] z, int zOff) + { + ulong c = 0, xVal = x; + int i = 0; + do + { + c += xVal * y[i]; + z[zOff + i] = (uint)c; + c >>= 32; + } + while (++i < 6); + return (uint)c; + } + + public static void Square(uint[] x, uint[] zz) + { + ulong x_0 = x[0]; + ulong zz_1; + + uint c = 0, w; + { + int i = 5, j = 12; + do + { + ulong xVal = x[i--]; + ulong p = xVal * xVal; + zz[--j] = (c << 31) | (uint)(p >> 33); + zz[--j] = (uint)(p >> 1); + c = (uint)p; + } + while (i > 0); + + { + ulong p = x_0 * x_0; + zz_1 = (ulong)(c << 31) | (p >> 33); + zz[0] = (uint)p; + c = (uint)(p >> 32) & 1; + } + } + + ulong x_1 = x[1]; + ulong zz_2 = zz[2]; + + { + zz_1 += x_1 * x_0; + w = (uint)zz_1; + zz[1] = (w << 1) | c; + c = w >> 31; + zz_2 += zz_1 >> 32; + } + + ulong x_2 = x[2]; + ulong zz_3 = zz[3]; + ulong zz_4 = zz[4]; + { + zz_2 += x_2 * x_0; + w = (uint)zz_2; + zz[2] = (w << 1) | c; + c = w >> 31; + zz_3 += (zz_2 >> 32) + x_2 * x_1; + zz_4 += zz_3 >> 32; + zz_3 &= M; + } + + ulong x_3 = x[3]; + ulong zz_5 = zz[5] + (zz_4 >> 32); zz_4 &= M; + ulong zz_6 = zz[6] + (zz_5 >> 32); zz_5 &= M; + { + zz_3 += x_3 * x_0; + w = (uint)zz_3; + zz[3] = (w << 1) | c; + c = w >> 31; + zz_4 += (zz_3 >> 32) + x_3 * x_1; + zz_5 += (zz_4 >> 32) + x_3 * x_2; + zz_4 &= M; + zz_6 += zz_5 >> 32; + zz_5 &= M; + } + + ulong x_4 = x[4]; + ulong zz_7 = zz[7] + (zz_6 >> 32); zz_6 &= M; + ulong zz_8 = zz[8] + (zz_7 >> 32); zz_7 &= M; + { + zz_4 += x_4 * x_0; + w = (uint)zz_4; + zz[4] = (w << 1) | c; + c = w >> 31; + zz_5 += (zz_4 >> 32) + x_4 * x_1; + zz_6 += (zz_5 >> 32) + x_4 * x_2; + zz_5 &= M; + zz_7 += (zz_6 >> 32) + x_4 * x_3; + zz_6 &= M; + zz_8 += zz_7 >> 32; + zz_7 &= M; + } + + ulong x_5 = x[5]; + ulong zz_9 = zz[9] + (zz_8 >> 32); zz_8 &= M; + ulong zz_10 = zz[10] + (zz_9 >> 32); zz_9 &= M; + { + zz_5 += x_5 * x_0; + w = (uint)zz_5; + zz[5] = (w << 1) | c; + c = w >> 31; + zz_6 += (zz_5 >> 32) + x_5 * x_1; + zz_7 += (zz_6 >> 32) + x_5 * x_2; + zz_8 += (zz_7 >> 32) + x_5 * x_3; + zz_9 += (zz_8 >> 32) + x_5 * x_4; + zz_10 += zz_9 >> 32; + } + + w = (uint)zz_6; + zz[6] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_7; + zz[7] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_8; + zz[8] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_9; + zz[9] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_10; + zz[10] = (w << 1) | c; + c = w >> 31; + w = zz[11] + (uint)(zz_10 >> 32); + zz[11] = (w << 1) | c; + } + + public static void Square(uint[] x, int xOff, uint[] zz, int zzOff) + { + ulong x_0 = x[xOff + 0]; + ulong zz_1; + + uint c = 0, w; + { + int i = 5, j = 12; + do + { + ulong xVal = x[xOff + i--]; + ulong p = xVal * xVal; + zz[zzOff + --j] = (c << 31) | (uint)(p >> 33); + zz[zzOff + --j] = (uint)(p >> 1); + c = (uint)p; + } + while (i > 0); + + { + ulong p = x_0 * x_0; + zz_1 = (ulong)(c << 31) | (p >> 33); + zz[zzOff + 0] = (uint)p; + c = (uint)(p >> 32) & 1; + } + } + + ulong x_1 = x[xOff + 1]; + ulong zz_2 = zz[zzOff + 2]; + + { + zz_1 += x_1 * x_0; + w = (uint)zz_1; + zz[zzOff + 1] = (w << 1) | c; + c = w >> 31; + zz_2 += zz_1 >> 32; + } + + ulong x_2 = x[xOff + 2]; + ulong zz_3 = zz[zzOff + 3]; + ulong zz_4 = zz[zzOff + 4]; + { + zz_2 += x_2 * x_0; + w = (uint)zz_2; + zz[zzOff + 2] = (w << 1) | c; + c = w >> 31; + zz_3 += (zz_2 >> 32) + x_2 * x_1; + zz_4 += zz_3 >> 32; + zz_3 &= M; + } + + ulong x_3 = x[xOff + 3]; + ulong zz_5 = zz[zzOff + 5] + (zz_4 >> 32); zz_4 &= M; + ulong zz_6 = zz[zzOff + 6] + (zz_5 >> 32); zz_5 &= M; + { + zz_3 += x_3 * x_0; + w = (uint)zz_3; + zz[zzOff + 3] = (w << 1) | c; + c = w >> 31; + zz_4 += (zz_3 >> 32) + x_3 * x_1; + zz_5 += (zz_4 >> 32) + x_3 * x_2; + zz_4 &= M; + zz_6 += zz_5 >> 32; + zz_5 &= M; + } + + ulong x_4 = x[xOff + 4]; + ulong zz_7 = zz[zzOff + 7] + (zz_6 >> 32); zz_6 &= M; + ulong zz_8 = zz[zzOff + 8] + (zz_7 >> 32); zz_7 &= M; + { + zz_4 += x_4 * x_0; + w = (uint)zz_4; + zz[zzOff + 4] = (w << 1) | c; + c = w >> 31; + zz_5 += (zz_4 >> 32) + x_4 * x_1; + zz_6 += (zz_5 >> 32) + x_4 * x_2; + zz_5 &= M; + zz_7 += (zz_6 >> 32) + x_4 * x_3; + zz_6 &= M; + zz_8 += zz_7 >> 32; + zz_7 &= M; + } + + ulong x_5 = x[xOff + 5]; + ulong zz_9 = zz[zzOff + 9] + (zz_8 >> 32); zz_8 &= M; + ulong zz_10 = zz[zzOff + 10] + (zz_9 >> 32); zz_9 &= M; + { + zz_5 += x_5 * x_0; + w = (uint)zz_5; + zz[zzOff + 5] = (w << 1) | c; + c = w >> 31; + zz_6 += (zz_5 >> 32) + x_5 * x_1; + zz_7 += (zz_6 >> 32) + x_5 * x_2; + zz_8 += (zz_7 >> 32) + x_5 * x_3; + zz_9 += (zz_8 >> 32) + x_5 * x_4; + zz_10 += zz_9 >> 32; + } + + w = (uint)zz_6; + zz[zzOff + 6] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_7; + zz[zzOff + 7] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_8; + zz[zzOff + 8] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_9; + zz[zzOff + 9] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_10; + zz[zzOff + 10] = (w << 1) | c; + c = w >> 31; + w = zz[zzOff + 11] + (uint)(zz_10 >> 32); + zz[zzOff + 11] = (w << 1) | c; + } + + public static int Sub(uint[] x, uint[] y, uint[] z) + { + long c = 0; + c += (long)x[0] - y[0]; + z[0] = (uint)c; + c >>= 32; + c += (long)x[1] - y[1]; + z[1] = (uint)c; + c >>= 32; + c += (long)x[2] - y[2]; + z[2] = (uint)c; + c >>= 32; + c += (long)x[3] - y[3]; + z[3] = (uint)c; + c >>= 32; + c += (long)x[4] - y[4]; + z[4] = (uint)c; + c >>= 32; + c += (long)x[5] - y[5]; + z[5] = (uint)c; + c >>= 32; + return (int)c; + } + + public static int Sub(uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + { + long c = 0; + c += (long)x[xOff + 0] - y[yOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += (long)x[xOff + 1] - y[yOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += (long)x[xOff + 2] - y[yOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += (long)x[xOff + 3] - y[yOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + c += (long)x[xOff + 4] - y[yOff + 4]; + z[zOff + 4] = (uint)c; + c >>= 32; + c += (long)x[xOff + 5] - y[yOff + 5]; + z[zOff + 5] = (uint)c; + c >>= 32; + return (int)c; + } + + public static int SubBothFrom(uint[] x, uint[] y, uint[] z) + { + long c = 0; + c += (long)z[0] - x[0] - y[0]; + z[0] = (uint)c; + c >>= 32; + c += (long)z[1] - x[1] - y[1]; + z[1] = (uint)c; + c >>= 32; + c += (long)z[2] - x[2] - y[2]; + z[2] = (uint)c; + c >>= 32; + c += (long)z[3] - x[3] - y[3]; + z[3] = (uint)c; + c >>= 32; + c += (long)z[4] - x[4] - y[4]; + z[4] = (uint)c; + c >>= 32; + c += (long)z[5] - x[5] - y[5]; + z[5] = (uint)c; + c >>= 32; + return (int)c; + } + + public static int SubFrom(uint[] x, uint[] z) + { + long c = 0; + c += (long)z[0] - x[0]; + z[0] = (uint)c; + c >>= 32; + c += (long)z[1] - x[1]; + z[1] = (uint)c; + c >>= 32; + c += (long)z[2] - x[2]; + z[2] = (uint)c; + c >>= 32; + c += (long)z[3] - x[3]; + z[3] = (uint)c; + c >>= 32; + c += (long)z[4] - x[4]; + z[4] = (uint)c; + c >>= 32; + c += (long)z[5] - x[5]; + z[5] = (uint)c; + c >>= 32; + return (int)c; + } + + public static int SubFrom(uint[] x, int xOff, uint[] z, int zOff) + { + long c = 0; + c += (long)z[zOff + 0] - x[xOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += (long)z[zOff + 1] - x[xOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += (long)z[zOff + 2] - x[xOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += (long)z[zOff + 3] - x[xOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + c += (long)z[zOff + 4] - x[xOff + 4]; + z[zOff + 4] = (uint)c; + c >>= 32; + c += (long)z[zOff + 5] - x[xOff + 5]; + z[zOff + 5] = (uint)c; + c >>= 32; + return (int)c; + } + + public static BigInteger ToBigInteger(uint[] x) + { + byte[] bs = new byte[24]; + for (int i = 0; i < 6; ++i) + { + uint x_i = x[i]; + if (x_i != 0) + { + Pack.UInt32_To_BE(x_i, bs, (5 - i) << 2); + } + } + return new BigInteger(1, bs); + } + + public static BigInteger ToBigInteger64(ulong[] x) + { + byte[] bs = new byte[24]; + for (int i = 0; i < 3; ++i) + { + ulong x_i = x[i]; + if (x_i != 0L) + { + Pack.UInt64_To_BE(x_i, bs, (2 - i) << 3); + } + } + return new BigInteger(1, bs); + } + + public static void Zero(uint[] z) + { + z[0] = 0; + z[1] = 0; + z[2] = 0; + z[3] = 0; + z[4] = 0; + z[5] = 0; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat192.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat192.cs.meta new file mode 100644 index 0000000..8323558 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat192.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e61b41d71acd615479a851c460336fff +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat224.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat224.cs new file mode 100644 index 0000000..1aabd3f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat224.cs @@ -0,0 +1,1174 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Crypto.Utilities; + +namespace Org.BouncyCastle.Math.Raw +{ + internal abstract class Nat224 + { + private const ulong M = 0xFFFFFFFFUL; + + public static uint Add(uint[] x, uint[] y, uint[] z) + { + ulong c = 0; + c += (ulong)x[0] + y[0]; + z[0] = (uint)c; + c >>= 32; + c += (ulong)x[1] + y[1]; + z[1] = (uint)c; + c >>= 32; + c += (ulong)x[2] + y[2]; + z[2] = (uint)c; + c >>= 32; + c += (ulong)x[3] + y[3]; + z[3] = (uint)c; + c >>= 32; + c += (ulong)x[4] + y[4]; + z[4] = (uint)c; + c >>= 32; + c += (ulong)x[5] + y[5]; + z[5] = (uint)c; + c >>= 32; + c += (ulong)x[6] + y[6]; + z[6] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint Add(uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + { + ulong c = 0; + c += (ulong)x[xOff + 0] + y[yOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 1] + y[yOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 2] + y[yOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 3] + y[yOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 4] + y[yOff + 4]; + z[zOff + 4] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 5] + y[yOff + 5]; + z[zOff + 5] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 6] + y[yOff + 6]; + z[zOff + 6] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint AddBothTo(uint[] x, uint[] y, uint[] z) + { + ulong c = 0; + c += (ulong)x[0] + y[0] + z[0]; + z[0] = (uint)c; + c >>= 32; + c += (ulong)x[1] + y[1] + z[1]; + z[1] = (uint)c; + c >>= 32; + c += (ulong)x[2] + y[2] + z[2]; + z[2] = (uint)c; + c >>= 32; + c += (ulong)x[3] + y[3] + z[3]; + z[3] = (uint)c; + c >>= 32; + c += (ulong)x[4] + y[4] + z[4]; + z[4] = (uint)c; + c >>= 32; + c += (ulong)x[5] + y[5] + z[5]; + z[5] = (uint)c; + c >>= 32; + c += (ulong)x[6] + y[6] + z[6]; + z[6] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint AddBothTo(uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + { + ulong c = 0; + c += (ulong)x[xOff + 0] + y[yOff + 0] + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 1] + y[yOff + 1] + z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 2] + y[yOff + 2] + z[zOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 3] + y[yOff + 3] + z[zOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 4] + y[yOff + 4] + z[zOff + 4]; + z[zOff + 4] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 5] + y[yOff + 5] + z[zOff + 5]; + z[zOff + 5] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 6] + y[yOff + 6] + z[zOff + 6]; + z[zOff + 6] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint AddTo(uint[] x, uint[] z) + { + ulong c = 0; + c += (ulong)x[0] + z[0]; + z[0] = (uint)c; + c >>= 32; + c += (ulong)x[1] + z[1]; + z[1] = (uint)c; + c >>= 32; + c += (ulong)x[2] + z[2]; + z[2] = (uint)c; + c >>= 32; + c += (ulong)x[3] + z[3]; + z[3] = (uint)c; + c >>= 32; + c += (ulong)x[4] + z[4]; + z[4] = (uint)c; + c >>= 32; + c += (ulong)x[5] + z[5]; + z[5] = (uint)c; + c >>= 32; + c += (ulong)x[6] + z[6]; + z[6] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint AddTo(uint[] x, int xOff, uint[] z, int zOff, uint cIn) + { + ulong c = cIn; + c += (ulong)x[xOff + 0] + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 1] + z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 2] + z[zOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 3] + z[zOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 4] + z[zOff + 4]; + z[zOff + 4] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 5] + z[zOff + 5]; + z[zOff + 5] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 6] + z[zOff + 6]; + z[zOff + 6] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint AddToEachOther(uint[] u, int uOff, uint[] v, int vOff) + { + ulong c = 0; + c += (ulong)u[uOff + 0] + v[vOff + 0]; + u[uOff + 0] = (uint)c; + v[vOff + 0] = (uint)c; + c >>= 32; + c += (ulong)u[uOff + 1] + v[vOff + 1]; + u[uOff + 1] = (uint)c; + v[vOff + 1] = (uint)c; + c >>= 32; + c += (ulong)u[uOff + 2] + v[vOff + 2]; + u[uOff + 2] = (uint)c; + v[vOff + 2] = (uint)c; + c >>= 32; + c += (ulong)u[uOff + 3] + v[vOff + 3]; + u[uOff + 3] = (uint)c; + v[vOff + 3] = (uint)c; + c >>= 32; + c += (ulong)u[uOff + 4] + v[vOff + 4]; + u[uOff + 4] = (uint)c; + v[vOff + 4] = (uint)c; + c >>= 32; + c += (ulong)u[uOff + 5] + v[vOff + 5]; + u[uOff + 5] = (uint)c; + v[vOff + 5] = (uint)c; + c >>= 32; + c += (ulong)u[uOff + 6] + v[vOff + 6]; + u[uOff + 6] = (uint)c; + v[vOff + 6] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static void Copy(uint[] x, uint[] z) + { + z[0] = x[0]; + z[1] = x[1]; + z[2] = x[2]; + z[3] = x[3]; + z[4] = x[4]; + z[5] = x[5]; + z[6] = x[6]; + } + + public static void Copy(uint[] x, int xOff, uint[] z, int zOff) + { + z[zOff + 0] = x[xOff + 0]; + z[zOff + 1] = x[xOff + 1]; + z[zOff + 2] = x[xOff + 2]; + z[zOff + 3] = x[xOff + 3]; + z[zOff + 4] = x[xOff + 4]; + z[zOff + 5] = x[xOff + 5]; + z[zOff + 6] = x[xOff + 6]; + } + + public static uint[] Create() + { + return new uint[7]; + } + + public static uint[] CreateExt() + { + return new uint[14]; + } + + public static bool Diff(uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + { + bool pos = Gte(x, xOff, y, yOff); + if (pos) + { + Sub(x, xOff, y, yOff, z, zOff); + } + else + { + Sub(y, yOff, x, xOff, z, zOff); + } + return pos; + } + + public static bool Eq(uint[] x, uint[] y) + { + for (int i = 6; i >= 0; --i) + { + if (x[i] != y[i]) + return false; + } + return true; + } + + public static uint GetBit(uint[] x, int bit) + { + if (bit == 0) + { + return x[0] & 1; + } + int w = bit >> 5; + if (w < 0 || w >= 7) + { + return 0; + } + int b = bit & 31; + return (x[w] >> b) & 1; + } + + public static bool Gte(uint[] x, uint[] y) + { + for (int i = 6; i >= 0; --i) + { + uint x_i = x[i], y_i = y[i]; + if (x_i < y_i) + return false; + if (x_i > y_i) + return true; + } + return true; + } + + public static bool Gte(uint[] x, int xOff, uint[] y, int yOff) + { + for (int i = 6; i >= 0; --i) + { + uint x_i = x[xOff + i], y_i = y[yOff + i]; + if (x_i < y_i) + return false; + if (x_i > y_i) + return true; + } + return true; + } + + public static bool IsOne(uint[] x) + { + if (x[0] != 1) + { + return false; + } + for (int i = 1; i < 7; ++i) + { + if (x[i] != 0) + { + return false; + } + } + return true; + } + + public static bool IsZero(uint[] x) + { + for (int i = 0; i < 7; ++i) + { + if (x[i] != 0) + { + return false; + } + } + return true; + } + + public static void Mul(uint[] x, uint[] y, uint[] zz) + { + ulong y_0 = y[0]; + ulong y_1 = y[1]; + ulong y_2 = y[2]; + ulong y_3 = y[3]; + ulong y_4 = y[4]; + ulong y_5 = y[5]; + ulong y_6 = y[6]; + + { + ulong c = 0, x_0 = x[0]; + c += x_0 * y_0; + zz[0] = (uint)c; + c >>= 32; + c += x_0 * y_1; + zz[1] = (uint)c; + c >>= 32; + c += x_0 * y_2; + zz[2] = (uint)c; + c >>= 32; + c += x_0 * y_3; + zz[3] = (uint)c; + c >>= 32; + c += x_0 * y_4; + zz[4] = (uint)c; + c >>= 32; + c += x_0 * y_5; + zz[5] = (uint)c; + c >>= 32; + c += x_0 * y_6; + zz[6] = (uint)c; + c >>= 32; + zz[7] = (uint)c; + } + + for (int i = 1; i < 7; ++i) + { + ulong c = 0, x_i = x[i]; + c += x_i * y_0 + zz[i + 0]; + zz[i + 0] = (uint)c; + c >>= 32; + c += x_i * y_1 + zz[i + 1]; + zz[i + 1] = (uint)c; + c >>= 32; + c += x_i * y_2 + zz[i + 2]; + zz[i + 2] = (uint)c; + c >>= 32; + c += x_i * y_3 + zz[i + 3]; + zz[i + 3] = (uint)c; + c >>= 32; + c += x_i * y_4 + zz[i + 4]; + zz[i + 4] = (uint)c; + c >>= 32; + c += x_i * y_5 + zz[i + 5]; + zz[i + 5] = (uint)c; + c >>= 32; + c += x_i * y_6 + zz[i + 6]; + zz[i + 6] = (uint)c; + c >>= 32; + zz[i + 7] = (uint)c; + } + } + + public static void Mul(uint[] x, int xOff, uint[] y, int yOff, uint[] zz, int zzOff) + { + ulong y_0 = y[yOff + 0]; + ulong y_1 = y[yOff + 1]; + ulong y_2 = y[yOff + 2]; + ulong y_3 = y[yOff + 3]; + ulong y_4 = y[yOff + 4]; + ulong y_5 = y[yOff + 5]; + ulong y_6 = y[yOff + 6]; + + { + ulong c = 0, x_0 = x[xOff + 0]; + c += x_0 * y_0; + zz[zzOff + 0] = (uint)c; + c >>= 32; + c += x_0 * y_1; + zz[zzOff + 1] = (uint)c; + c >>= 32; + c += x_0 * y_2; + zz[zzOff + 2] = (uint)c; + c >>= 32; + c += x_0 * y_3; + zz[zzOff + 3] = (uint)c; + c >>= 32; + c += x_0 * y_4; + zz[zzOff + 4] = (uint)c; + c >>= 32; + c += x_0 * y_5; + zz[zzOff + 5] = (uint)c; + c >>= 32; + c += x_0 * y_6; + zz[zzOff + 6] = (uint)c; + c >>= 32; + zz[zzOff + 7] = (uint)c; + } + + for (int i = 1; i < 7; ++i) + { + ++zzOff; + ulong c = 0, x_i = x[xOff + i]; + c += x_i * y_0 + zz[zzOff + 0]; + zz[zzOff + 0] = (uint)c; + c >>= 32; + c += x_i * y_1 + zz[zzOff + 1]; + zz[zzOff + 1] = (uint)c; + c >>= 32; + c += x_i * y_2 + zz[zzOff + 2]; + zz[zzOff + 2] = (uint)c; + c >>= 32; + c += x_i * y_3 + zz[zzOff + 3]; + zz[zzOff + 3] = (uint)c; + c >>= 32; + c += x_i * y_4 + zz[zzOff + 4]; + zz[zzOff + 4] = (uint)c; + c >>= 32; + c += x_i * y_5 + zz[zzOff + 5]; + zz[zzOff + 5] = (uint)c; + c >>= 32; + c += x_i * y_6 + zz[zzOff + 6]; + zz[zzOff + 6] = (uint)c; + c >>= 32; + zz[zzOff + 7] = (uint)c; + } + } + + public static uint MulAddTo(uint[] x, uint[] y, uint[] zz) + { + ulong y_0 = y[0]; + ulong y_1 = y[1]; + ulong y_2 = y[2]; + ulong y_3 = y[3]; + ulong y_4 = y[4]; + ulong y_5 = y[5]; + ulong y_6 = y[6]; + + ulong zc = 0; + for (int i = 0; i < 7; ++i) + { + ulong c = 0, x_i = x[i]; + c += x_i * y_0 + zz[i + 0]; + zz[i + 0] = (uint)c; + c >>= 32; + c += x_i * y_1 + zz[i + 1]; + zz[i + 1] = (uint)c; + c >>= 32; + c += x_i * y_2 + zz[i + 2]; + zz[i + 2] = (uint)c; + c >>= 32; + c += x_i * y_3 + zz[i + 3]; + zz[i + 3] = (uint)c; + c >>= 32; + c += x_i * y_4 + zz[i + 4]; + zz[i + 4] = (uint)c; + c >>= 32; + c += x_i * y_5 + zz[i + 5]; + zz[i + 5] = (uint)c; + c >>= 32; + c += x_i * y_6 + zz[i + 6]; + zz[i + 6] = (uint)c; + c >>= 32; + + zc += c + zz[i + 7]; + zz[i + 7] = (uint)zc; + zc >>= 32; + } + return (uint)zc; + } + + public static uint MulAddTo(uint[] x, int xOff, uint[] y, int yOff, uint[] zz, int zzOff) + { + ulong y_0 = y[yOff + 0]; + ulong y_1 = y[yOff + 1]; + ulong y_2 = y[yOff + 2]; + ulong y_3 = y[yOff + 3]; + ulong y_4 = y[yOff + 4]; + ulong y_5 = y[yOff + 5]; + ulong y_6 = y[yOff + 6]; + + ulong zc = 0; + for (int i = 0; i < 7; ++i) + { + ulong c = 0, x_i = x[xOff + i]; + c += x_i * y_0 + zz[zzOff + 0]; + zz[zzOff + 0] = (uint)c; + c >>= 32; + c += x_i * y_1 + zz[zzOff + 1]; + zz[zzOff + 1] = (uint)c; + c >>= 32; + c += x_i * y_2 + zz[zzOff + 2]; + zz[zzOff + 2] = (uint)c; + c >>= 32; + c += x_i * y_3 + zz[zzOff + 3]; + zz[zzOff + 3] = (uint)c; + c >>= 32; + c += x_i * y_4 + zz[zzOff + 4]; + zz[zzOff + 4] = (uint)c; + c >>= 32; + c += x_i * y_5 + zz[zzOff + 5]; + zz[zzOff + 5] = (uint)c; + c >>= 32; + c += x_i * y_6 + zz[zzOff + 6]; + zz[zzOff + 6] = (uint)c; + c >>= 32; + + zc += c + zz[zzOff + 7]; + zz[zzOff + 7] = (uint)zc; + zc >>= 32; + ++zzOff; + } + return (uint)zc; + } + + public static ulong Mul33Add(uint w, uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + { + Debug.Assert(w >> 31 == 0); + + ulong c = 0, wVal = w; + ulong x0 = x[xOff + 0]; + c += wVal * x0 + y[yOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + ulong x1 = x[xOff + 1]; + c += wVal * x1 + x0 + y[yOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + ulong x2 = x[xOff + 2]; + c += wVal * x2 + x1 + y[yOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + ulong x3 = x[xOff + 3]; + c += wVal * x3 + x2 + y[yOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + ulong x4 = x[xOff + 4]; + c += wVal * x4 + x3 + y[yOff + 4]; + z[zOff + 4] = (uint)c; + c >>= 32; + ulong x5 = x[xOff + 5]; + c += wVal * x5 + x4 + y[yOff + 5]; + z[zOff + 5] = (uint)c; + c >>= 32; + ulong x6 = x[xOff + 6]; + c += wVal * x6 + x5 + y[yOff + 6]; + z[zOff + 6] = (uint)c; + c >>= 32; + c += x6; + return c; + } + + public static uint MulByWord(uint x, uint[] z) + { + ulong c = 0, xVal = x; + c += xVal * (ulong)z[0]; + z[0] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[1]; + z[1] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[2]; + z[2] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[3]; + z[3] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[4]; + z[4] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[5]; + z[5] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[6]; + z[6] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint MulByWordAddTo(uint x, uint[] y, uint[] z) + { + ulong c = 0, xVal = x; + c += xVal * (ulong)z[0] + y[0]; + z[0] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[1] + y[1]; + z[1] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[2] + y[2]; + z[2] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[3] + y[3]; + z[3] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[4] + y[4]; + z[4] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[5] + y[5]; + z[5] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[6] + y[6]; + z[6] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint MulWordAddTo(uint x, uint[] y, int yOff, uint[] z, int zOff) + { + ulong c = 0, xVal = x; + c += xVal * y[yOff + 0] + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += xVal * y[yOff + 1] + z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += xVal * y[yOff + 2] + z[zOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += xVal * y[yOff + 3] + z[zOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + c += xVal * y[yOff + 4] + z[zOff + 4]; + z[zOff + 4] = (uint)c; + c >>= 32; + c += xVal * y[yOff + 5] + z[zOff + 5]; + z[zOff + 5] = (uint)c; + c >>= 32; + c += xVal * y[yOff + 6] + z[zOff + 6]; + z[zOff + 6] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint Mul33DWordAdd(uint x, ulong y, uint[] z, int zOff) + { + Debug.Assert(x >> 31 == 0); + Debug.Assert(zOff <= 3); + ulong c = 0, xVal = x; + ulong y00 = y & M; + c += xVal * y00 + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + ulong y01 = y >> 32; + c += xVal * y01 + y00 + z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += y01 + z[zOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += z[zOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + return c == 0 ? 0 : Nat.IncAt(7, z, zOff, 4); + } + + public static uint Mul33WordAdd(uint x, uint y, uint[] z, int zOff) + { + Debug.Assert(x >> 31 == 0); + Debug.Assert(zOff <= 4); + ulong c = 0, yVal = y; + c += yVal * x + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += yVal + z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += z[zOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + return c == 0 ? 0 : Nat.IncAt(7, z, zOff, 3); + } + + public static uint MulWordDwordAdd(uint x, ulong y, uint[] z, int zOff) + { + Debug.Assert(zOff <= 4); + ulong c = 0, xVal = x; + c += xVal * y + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += xVal * (y >> 32) + z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += z[zOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + return c == 0 ? 0 : Nat.IncAt(7, z, zOff, 3); + } + + public static uint MulWord(uint x, uint[] y, uint[] z, int zOff) + { + ulong c = 0, xVal = x; + int i = 0; + do + { + c += xVal * y[i]; + z[zOff + i] = (uint)c; + c >>= 32; + } + while (++i < 7); + return (uint)c; + } + + public static void Square(uint[] x, uint[] zz) + { + ulong x_0 = x[0]; + ulong zz_1; + + uint c = 0, w; + { + int i = 6, j = 14; + do + { + ulong xVal = x[i--]; + ulong p = xVal * xVal; + zz[--j] = (c << 31) | (uint)(p >> 33); + zz[--j] = (uint)(p >> 1); + c = (uint)p; + } + while (i > 0); + + { + ulong p = x_0 * x_0; + zz_1 = (ulong)(c << 31) | (p >> 33); + zz[0] = (uint)p; + c = (uint)(p >> 32) & 1; + } + } + + ulong x_1 = x[1]; + ulong zz_2 = zz[2]; + + { + zz_1 += x_1 * x_0; + w = (uint)zz_1; + zz[1] = (w << 1) | c; + c = w >> 31; + zz_2 += zz_1 >> 32; + } + + ulong x_2 = x[2]; + ulong zz_3 = zz[3]; + ulong zz_4 = zz[4]; + { + zz_2 += x_2 * x_0; + w = (uint)zz_2; + zz[2] = (w << 1) | c; + c = w >> 31; + zz_3 += (zz_2 >> 32) + x_2 * x_1; + zz_4 += zz_3 >> 32; + zz_3 &= M; + } + + ulong x_3 = x[3]; + ulong zz_5 = zz[5] + (zz_4 >> 32); zz_4 &= M; + ulong zz_6 = zz[6] + (zz_5 >> 32); zz_5 &= M; + { + zz_3 += x_3 * x_0; + w = (uint)zz_3; + zz[3] = (w << 1) | c; + c = w >> 31; + zz_4 += (zz_3 >> 32) + x_3 * x_1; + zz_5 += (zz_4 >> 32) + x_3 * x_2; + zz_4 &= M; + zz_6 += zz_5 >> 32; + zz_5 &= M; + } + + ulong x_4 = x[4]; + ulong zz_7 = zz[7] + (zz_6 >> 32); zz_6 &= M; + ulong zz_8 = zz[8] + (zz_7 >> 32); zz_7 &= M; + { + zz_4 += x_4 * x_0; + w = (uint)zz_4; + zz[4] = (w << 1) | c; + c = w >> 31; + zz_5 += (zz_4 >> 32) + x_4 * x_1; + zz_6 += (zz_5 >> 32) + x_4 * x_2; + zz_5 &= M; + zz_7 += (zz_6 >> 32) + x_4 * x_3; + zz_6 &= M; + zz_8 += zz_7 >> 32; + zz_7 &= M; + } + + ulong x_5 = x[5]; + ulong zz_9 = zz[9] + (zz_8 >> 32); zz_8 &= M; + ulong zz_10 = zz[10] + (zz_9 >> 32); zz_9 &= M; + { + zz_5 += x_5 * x_0; + w = (uint)zz_5; + zz[5] = (w << 1) | c; + c = w >> 31; + zz_6 += (zz_5 >> 32) + x_5 * x_1; + zz_7 += (zz_6 >> 32) + x_5 * x_2; + zz_6 &= M; + zz_8 += (zz_7 >> 32) + x_5 * x_3; + zz_7 &= M; + zz_9 += (zz_8 >> 32) + x_5 * x_4; + zz_8 &= M; + zz_10 += zz_9 >> 32; + zz_9 &= M; + } + + ulong x_6 = x[6]; + ulong zz_11 = zz[11] + (zz_10 >> 32); zz_10 &= M; + ulong zz_12 = zz[12] + (zz_11 >> 32); zz_11 &= M; + { + zz_6 += x_6 * x_0; + w = (uint)zz_6; + zz[6] = (w << 1) | c; + c = w >> 31; + zz_7 += (zz_6 >> 32) + x_6 * x_1; + zz_8 += (zz_7 >> 32) + x_6 * x_2; + zz_9 += (zz_8 >> 32) + x_6 * x_3; + zz_10 += (zz_9 >> 32) + x_6 * x_4; + zz_11 += (zz_10 >> 32) + x_6 * x_5; + zz_12 += zz_11 >> 32; + } + + w = (uint)zz_7; + zz[7] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_8; + zz[8] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_9; + zz[9] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_10; + zz[10] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_11; + zz[11] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_12; + zz[12] = (w << 1) | c; + c = w >> 31; + w = zz[13] + (uint)(zz_12 >> 32); + zz[13] = (w << 1) | c; + } + + public static void Square(uint[] x, int xOff, uint[] zz, int zzOff) + { + ulong x_0 = x[xOff + 0]; + ulong zz_1; + + uint c = 0, w; + { + int i = 6, j = 14; + do + { + ulong xVal = x[xOff + i--]; + ulong p = xVal * xVal; + zz[zzOff + --j] = (c << 31) | (uint)(p >> 33); + zz[zzOff + --j] = (uint)(p >> 1); + c = (uint)p; + } + while (i > 0); + + { + ulong p = x_0 * x_0; + zz_1 = (ulong)(c << 31) | (p >> 33); + zz[zzOff + 0] = (uint)p; + c = (uint)(p >> 32) & 1; + } + } + + ulong x_1 = x[xOff + 1]; + ulong zz_2 = zz[zzOff + 2]; + + { + zz_1 += x_1 * x_0; + w = (uint)zz_1; + zz[zzOff + 1] = (w << 1) | c; + c = w >> 31; + zz_2 += zz_1 >> 32; + } + + ulong x_2 = x[xOff + 2]; + ulong zz_3 = zz[zzOff + 3]; + ulong zz_4 = zz[zzOff + 4]; + { + zz_2 += x_2 * x_0; + w = (uint)zz_2; + zz[zzOff + 2] = (w << 1) | c; + c = w >> 31; + zz_3 += (zz_2 >> 32) + x_2 * x_1; + zz_4 += zz_3 >> 32; + zz_3 &= M; + } + + ulong x_3 = x[xOff + 3]; + ulong zz_5 = zz[zzOff + 5] + (zz_4 >> 32); zz_4 &= M; + ulong zz_6 = zz[zzOff + 6] + (zz_5 >> 32); zz_5 &= M; + { + zz_3 += x_3 * x_0; + w = (uint)zz_3; + zz[zzOff + 3] = (w << 1) | c; + c = w >> 31; + zz_4 += (zz_3 >> 32) + x_3 * x_1; + zz_5 += (zz_4 >> 32) + x_3 * x_2; + zz_4 &= M; + zz_6 += zz_5 >> 32; + zz_5 &= M; + } + + ulong x_4 = x[xOff + 4]; + ulong zz_7 = zz[zzOff + 7] + (zz_6 >> 32); zz_6 &= M; + ulong zz_8 = zz[zzOff + 8] + (zz_7 >> 32); zz_7 &= M; + { + zz_4 += x_4 * x_0; + w = (uint)zz_4; + zz[zzOff + 4] = (w << 1) | c; + c = w >> 31; + zz_5 += (zz_4 >> 32) + x_4 * x_1; + zz_6 += (zz_5 >> 32) + x_4 * x_2; + zz_5 &= M; + zz_7 += (zz_6 >> 32) + x_4 * x_3; + zz_6 &= M; + zz_8 += zz_7 >> 32; + zz_7 &= M; + } + + ulong x_5 = x[xOff + 5]; + ulong zz_9 = zz[zzOff + 9] + (zz_8 >> 32); zz_8 &= M; + ulong zz_10 = zz[zzOff + 10] + (zz_9 >> 32); zz_9 &= M; + { + zz_5 += x_5 * x_0; + w = (uint)zz_5; + zz[zzOff + 5] = (w << 1) | c; + c = w >> 31; + zz_6 += (zz_5 >> 32) + x_5 * x_1; + zz_7 += (zz_6 >> 32) + x_5 * x_2; + zz_6 &= M; + zz_8 += (zz_7 >> 32) + x_5 * x_3; + zz_7 &= M; + zz_9 += (zz_8 >> 32) + x_5 * x_4; + zz_8 &= M; + zz_10 += zz_9 >> 32; + zz_9 &= M; + } + + ulong x_6 = x[xOff + 6]; + ulong zz_11 = zz[zzOff + 11] + (zz_10 >> 32); zz_10 &= M; + ulong zz_12 = zz[zzOff + 12] + (zz_11 >> 32); zz_11 &= M; + { + zz_6 += x_6 * x_0; + w = (uint)zz_6; + zz[zzOff + 6] = (w << 1) | c; + c = w >> 31; + zz_7 += (zz_6 >> 32) + x_6 * x_1; + zz_8 += (zz_7 >> 32) + x_6 * x_2; + zz_9 += (zz_8 >> 32) + x_6 * x_3; + zz_10 += (zz_9 >> 32) + x_6 * x_4; + zz_11 += (zz_10 >> 32) + x_6 * x_5; + zz_12 += zz_11 >> 32; + } + + w = (uint)zz_7; + zz[zzOff + 7] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_8; + zz[zzOff + 8] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_9; + zz[zzOff + 9] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_10; + zz[zzOff + 10] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_11; + zz[zzOff + 11] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_12; + zz[zzOff + 12] = (w << 1) | c; + c = w >> 31; + w = zz[zzOff + 13] + (uint)(zz_12 >> 32); + zz[zzOff + 13] = (w << 1) | c; + } + + public static int Sub(uint[] x, uint[] y, uint[] z) + { + long c = 0; + c += (long)x[0] - y[0]; + z[0] = (uint)c; + c >>= 32; + c += (long)x[1] - y[1]; + z[1] = (uint)c; + c >>= 32; + c += (long)x[2] - y[2]; + z[2] = (uint)c; + c >>= 32; + c += (long)x[3] - y[3]; + z[3] = (uint)c; + c >>= 32; + c += (long)x[4] - y[4]; + z[4] = (uint)c; + c >>= 32; + c += (long)x[5] - y[5]; + z[5] = (uint)c; + c >>= 32; + c += (long)x[6] - y[6]; + z[6] = (uint)c; + c >>= 32; + return (int)c; + } + + public static int Sub(uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + { + long c = 0; + c += (long)x[xOff + 0] - y[yOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += (long)x[xOff + 1] - y[yOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += (long)x[xOff + 2] - y[yOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += (long)x[xOff + 3] - y[yOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + c += (long)x[xOff + 4] - y[yOff + 4]; + z[zOff + 4] = (uint)c; + c >>= 32; + c += (long)x[xOff + 5] - y[yOff + 5]; + z[zOff + 5] = (uint)c; + c >>= 32; + c += (long)x[xOff + 6] - y[yOff + 6]; + z[zOff + 6] = (uint)c; + c >>= 32; + return (int)c; + } + + public static int SubBothFrom(uint[] x, uint[] y, uint[] z) + { + long c = 0; + c += (long)z[0] - x[0] - y[0]; + z[0] = (uint)c; + c >>= 32; + c += (long)z[1] - x[1] - y[1]; + z[1] = (uint)c; + c >>= 32; + c += (long)z[2] - x[2] - y[2]; + z[2] = (uint)c; + c >>= 32; + c += (long)z[3] - x[3] - y[3]; + z[3] = (uint)c; + c >>= 32; + c += (long)z[4] - x[4] - y[4]; + z[4] = (uint)c; + c >>= 32; + c += (long)z[5] - x[5] - y[5]; + z[5] = (uint)c; + c >>= 32; + c += (long)z[6] - x[6] - y[6]; + z[6] = (uint)c; + c >>= 32; + return (int)c; + } + + public static int SubFrom(uint[] x, uint[] z) + { + long c = 0; + c += (long)z[0] - x[0]; + z[0] = (uint)c; + c >>= 32; + c += (long)z[1] - x[1]; + z[1] = (uint)c; + c >>= 32; + c += (long)z[2] - x[2]; + z[2] = (uint)c; + c >>= 32; + c += (long)z[3] - x[3]; + z[3] = (uint)c; + c >>= 32; + c += (long)z[4] - x[4]; + z[4] = (uint)c; + c >>= 32; + c += (long)z[5] - x[5]; + z[5] = (uint)c; + c >>= 32; + c += (long)z[6] - x[6]; + z[6] = (uint)c; + c >>= 32; + return (int)c; + } + + public static int SubFrom(uint[] x, int xOff, uint[] z, int zOff) + { + long c = 0; + c += (long)z[zOff + 0] - x[xOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += (long)z[zOff + 1] - x[xOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += (long)z[zOff + 2] - x[xOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += (long)z[zOff + 3] - x[xOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + c += (long)z[zOff + 4] - x[xOff + 4]; + z[zOff + 4] = (uint)c; + c >>= 32; + c += (long)z[zOff + 5] - x[xOff + 5]; + z[zOff + 5] = (uint)c; + c >>= 32; + c += (long)z[zOff + 6] - x[xOff + 6]; + z[zOff + 6] = (uint)c; + c >>= 32; + return (int)c; + } + + public static BigInteger ToBigInteger(uint[] x) + { + byte[] bs = new byte[28]; + for (int i = 0; i < 7; ++i) + { + uint x_i = x[i]; + if (x_i != 0) + { + Pack.UInt32_To_BE(x_i, bs, (6 - i) << 2); + } + } + return new BigInteger(1, bs); + } + + public static void Zero(uint[] z) + { + z[0] = 0; + z[1] = 0; + z[2] = 0; + z[3] = 0; + z[4] = 0; + z[5] = 0; + z[6] = 0; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat224.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat224.cs.meta new file mode 100644 index 0000000..971a972 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat224.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 90b91d8562ccd8d4caa35bd96b09f520 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat256.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat256.cs new file mode 100644 index 0000000..710060b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat256.cs @@ -0,0 +1,1379 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Crypto.Utilities; + +namespace Org.BouncyCastle.Math.Raw +{ + internal abstract class Nat256 + { + private const ulong M = 0xFFFFFFFFUL; + + public static uint Add(uint[] x, uint[] y, uint[] z) + { + ulong c = 0; + c += (ulong)x[0] + y[0]; + z[0] = (uint)c; + c >>= 32; + c += (ulong)x[1] + y[1]; + z[1] = (uint)c; + c >>= 32; + c += (ulong)x[2] + y[2]; + z[2] = (uint)c; + c >>= 32; + c += (ulong)x[3] + y[3]; + z[3] = (uint)c; + c >>= 32; + c += (ulong)x[4] + y[4]; + z[4] = (uint)c; + c >>= 32; + c += (ulong)x[5] + y[5]; + z[5] = (uint)c; + c >>= 32; + c += (ulong)x[6] + y[6]; + z[6] = (uint)c; + c >>= 32; + c += (ulong)x[7] + y[7]; + z[7] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint Add(uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + { + ulong c = 0; + c += (ulong)x[xOff + 0] + y[yOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 1] + y[yOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 2] + y[yOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 3] + y[yOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 4] + y[yOff + 4]; + z[zOff + 4] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 5] + y[yOff + 5]; + z[zOff + 5] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 6] + y[yOff + 6]; + z[zOff + 6] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 7] + y[yOff + 7]; + z[zOff + 7] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint AddBothTo(uint[] x, uint[] y, uint[] z) + { + ulong c = 0; + c += (ulong)x[0] + y[0] + z[0]; + z[0] = (uint)c; + c >>= 32; + c += (ulong)x[1] + y[1] + z[1]; + z[1] = (uint)c; + c >>= 32; + c += (ulong)x[2] + y[2] + z[2]; + z[2] = (uint)c; + c >>= 32; + c += (ulong)x[3] + y[3] + z[3]; + z[3] = (uint)c; + c >>= 32; + c += (ulong)x[4] + y[4] + z[4]; + z[4] = (uint)c; + c >>= 32; + c += (ulong)x[5] + y[5] + z[5]; + z[5] = (uint)c; + c >>= 32; + c += (ulong)x[6] + y[6] + z[6]; + z[6] = (uint)c; + c >>= 32; + c += (ulong)x[7] + y[7] + z[7]; + z[7] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint AddBothTo(uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + { + ulong c = 0; + c += (ulong)x[xOff + 0] + y[yOff + 0] + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 1] + y[yOff + 1] + z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 2] + y[yOff + 2] + z[zOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 3] + y[yOff + 3] + z[zOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 4] + y[yOff + 4] + z[zOff + 4]; + z[zOff + 4] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 5] + y[yOff + 5] + z[zOff + 5]; + z[zOff + 5] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 6] + y[yOff + 6] + z[zOff + 6]; + z[zOff + 6] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 7] + y[yOff + 7] + z[zOff + 7]; + z[zOff + 7] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint AddTo(uint[] x, uint[] z) + { + ulong c = 0; + c += (ulong)x[0] + z[0]; + z[0] = (uint)c; + c >>= 32; + c += (ulong)x[1] + z[1]; + z[1] = (uint)c; + c >>= 32; + c += (ulong)x[2] + z[2]; + z[2] = (uint)c; + c >>= 32; + c += (ulong)x[3] + z[3]; + z[3] = (uint)c; + c >>= 32; + c += (ulong)x[4] + z[4]; + z[4] = (uint)c; + c >>= 32; + c += (ulong)x[5] + z[5]; + z[5] = (uint)c; + c >>= 32; + c += (ulong)x[6] + z[6]; + z[6] = (uint)c; + c >>= 32; + c += (ulong)x[7] + z[7]; + z[7] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint AddTo(uint[] x, int xOff, uint[] z, int zOff, uint cIn) + { + ulong c = cIn; + c += (ulong)x[xOff + 0] + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 1] + z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 2] + z[zOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 3] + z[zOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 4] + z[zOff + 4]; + z[zOff + 4] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 5] + z[zOff + 5]; + z[zOff + 5] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 6] + z[zOff + 6]; + z[zOff + 6] = (uint)c; + c >>= 32; + c += (ulong)x[xOff + 7] + z[zOff + 7]; + z[zOff + 7] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint AddToEachOther(uint[] u, int uOff, uint[] v, int vOff) + { + ulong c = 0; + c += (ulong)u[uOff + 0] + v[vOff + 0]; + u[uOff + 0] = (uint)c; + v[vOff + 0] = (uint)c; + c >>= 32; + c += (ulong)u[uOff + 1] + v[vOff + 1]; + u[uOff + 1] = (uint)c; + v[vOff + 1] = (uint)c; + c >>= 32; + c += (ulong)u[uOff + 2] + v[vOff + 2]; + u[uOff + 2] = (uint)c; + v[vOff + 2] = (uint)c; + c >>= 32; + c += (ulong)u[uOff + 3] + v[vOff + 3]; + u[uOff + 3] = (uint)c; + v[vOff + 3] = (uint)c; + c >>= 32; + c += (ulong)u[uOff + 4] + v[vOff + 4]; + u[uOff + 4] = (uint)c; + v[vOff + 4] = (uint)c; + c >>= 32; + c += (ulong)u[uOff + 5] + v[vOff + 5]; + u[uOff + 5] = (uint)c; + v[vOff + 5] = (uint)c; + c >>= 32; + c += (ulong)u[uOff + 6] + v[vOff + 6]; + u[uOff + 6] = (uint)c; + v[vOff + 6] = (uint)c; + c >>= 32; + c += (ulong)u[uOff + 7] + v[vOff + 7]; + u[uOff + 7] = (uint)c; + v[vOff + 7] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static void Copy(uint[] x, uint[] z) + { + z[0] = x[0]; + z[1] = x[1]; + z[2] = x[2]; + z[3] = x[3]; + z[4] = x[4]; + z[5] = x[5]; + z[6] = x[6]; + z[7] = x[7]; + } + + public static void Copy(uint[] x, int xOff, uint[] z, int zOff) + { + z[zOff + 0] = x[xOff + 0]; + z[zOff + 1] = x[xOff + 1]; + z[zOff + 2] = x[xOff + 2]; + z[zOff + 3] = x[xOff + 3]; + z[zOff + 4] = x[xOff + 4]; + z[zOff + 5] = x[xOff + 5]; + z[zOff + 6] = x[xOff + 6]; + z[zOff + 7] = x[xOff + 7]; + } + + public static void Copy64(ulong[] x, ulong[] z) + { + z[0] = x[0]; + z[1] = x[1]; + z[2] = x[2]; + z[3] = x[3]; + } + + public static void Copy64(ulong[] x, int xOff, ulong[] z, int zOff) + { + z[zOff + 0] = x[xOff + 0]; + z[zOff + 1] = x[xOff + 1]; + z[zOff + 2] = x[xOff + 2]; + z[zOff + 3] = x[xOff + 3]; + } + + public static uint[] Create() + { + return new uint[8]; + } + + public static ulong[] Create64() + { + return new ulong[4]; + } + + public static uint[] CreateExt() + { + return new uint[16]; + } + + public static ulong[] CreateExt64() + { + return new ulong[8]; + } + + public static bool Diff(uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + { + bool pos = Gte(x, xOff, y, yOff); + if (pos) + { + Sub(x, xOff, y, yOff, z, zOff); + } + else + { + Sub(y, yOff, x, xOff, z, zOff); + } + return pos; + } + + public static bool Eq(uint[] x, uint[] y) + { + for (int i = 7; i >= 0; --i) + { + if (x[i] != y[i]) + return false; + } + return true; + } + + public static bool Eq64(ulong[] x, ulong[] y) + { + for (int i = 3; i >= 0; --i) + { + if (x[i] != y[i]) + { + return false; + } + } + return true; + } + + public static uint GetBit(uint[] x, int bit) + { + if (bit == 0) + { + return x[0] & 1; + } + if ((bit & 255) != bit) + { + return 0; + } + int w = bit >> 5; + int b = bit & 31; + return (x[w] >> b) & 1; + } + + public static bool Gte(uint[] x, uint[] y) + { + for (int i = 7; i >= 0; --i) + { + uint x_i = x[i], y_i = y[i]; + if (x_i < y_i) + return false; + if (x_i > y_i) + return true; + } + return true; + } + + public static bool Gte(uint[] x, int xOff, uint[] y, int yOff) + { + for (int i = 7; i >= 0; --i) + { + uint x_i = x[xOff + i], y_i = y[yOff + i]; + if (x_i < y_i) + return false; + if (x_i > y_i) + return true; + } + return true; + } + + public static bool IsOne(uint[] x) + { + if (x[0] != 1) + { + return false; + } + for (int i = 1; i < 8; ++i) + { + if (x[i] != 0) + { + return false; + } + } + return true; + } + + public static bool IsOne64(ulong[] x) + { + if (x[0] != 1UL) + { + return false; + } + for (int i = 1; i < 4; ++i) + { + if (x[i] != 0UL) + { + return false; + } + } + return true; + } + + public static bool IsZero(uint[] x) + { + for (int i = 0; i < 8; ++i) + { + if (x[i] != 0) + { + return false; + } + } + return true; + } + + public static bool IsZero64(ulong[] x) + { + for (int i = 0; i < 4; ++i) + { + if (x[i] != 0UL) + { + return false; + } + } + return true; + } + + public static void Mul(uint[] x, uint[] y, uint[] zz) + { + ulong y_0 = y[0]; + ulong y_1 = y[1]; + ulong y_2 = y[2]; + ulong y_3 = y[3]; + ulong y_4 = y[4]; + ulong y_5 = y[5]; + ulong y_6 = y[6]; + ulong y_7 = y[7]; + + { + ulong c = 0, x_0 = x[0]; + c += x_0 * y_0; + zz[0] = (uint)c; + c >>= 32; + c += x_0 * y_1; + zz[1] = (uint)c; + c >>= 32; + c += x_0 * y_2; + zz[2] = (uint)c; + c >>= 32; + c += x_0 * y_3; + zz[3] = (uint)c; + c >>= 32; + c += x_0 * y_4; + zz[4] = (uint)c; + c >>= 32; + c += x_0 * y_5; + zz[5] = (uint)c; + c >>= 32; + c += x_0 * y_6; + zz[6] = (uint)c; + c >>= 32; + c += x_0 * y_7; + zz[7] = (uint)c; + c >>= 32; + zz[8] = (uint)c; + } + + for (int i = 1; i < 8; ++i) + { + ulong c = 0, x_i = x[i]; + c += x_i * y_0 + zz[i + 0]; + zz[i + 0] = (uint)c; + c >>= 32; + c += x_i * y_1 + zz[i + 1]; + zz[i + 1] = (uint)c; + c >>= 32; + c += x_i * y_2 + zz[i + 2]; + zz[i + 2] = (uint)c; + c >>= 32; + c += x_i * y_3 + zz[i + 3]; + zz[i + 3] = (uint)c; + c >>= 32; + c += x_i * y_4 + zz[i + 4]; + zz[i + 4] = (uint)c; + c >>= 32; + c += x_i * y_5 + zz[i + 5]; + zz[i + 5] = (uint)c; + c >>= 32; + c += x_i * y_6 + zz[i + 6]; + zz[i + 6] = (uint)c; + c >>= 32; + c += x_i * y_7 + zz[i + 7]; + zz[i + 7] = (uint)c; + c >>= 32; + zz[i + 8] = (uint)c; + } + } + + public static void Mul(uint[] x, int xOff, uint[] y, int yOff, uint[] zz, int zzOff) + { + ulong y_0 = y[yOff + 0]; + ulong y_1 = y[yOff + 1]; + ulong y_2 = y[yOff + 2]; + ulong y_3 = y[yOff + 3]; + ulong y_4 = y[yOff + 4]; + ulong y_5 = y[yOff + 5]; + ulong y_6 = y[yOff + 6]; + ulong y_7 = y[yOff + 7]; + + { + ulong c = 0, x_0 = x[xOff + 0]; + c += x_0 * y_0; + zz[zzOff + 0] = (uint)c; + c >>= 32; + c += x_0 * y_1; + zz[zzOff + 1] = (uint)c; + c >>= 32; + c += x_0 * y_2; + zz[zzOff + 2] = (uint)c; + c >>= 32; + c += x_0 * y_3; + zz[zzOff + 3] = (uint)c; + c >>= 32; + c += x_0 * y_4; + zz[zzOff + 4] = (uint)c; + c >>= 32; + c += x_0 * y_5; + zz[zzOff + 5] = (uint)c; + c >>= 32; + c += x_0 * y_6; + zz[zzOff + 6] = (uint)c; + c >>= 32; + c += x_0 * y_7; + zz[zzOff + 7] = (uint)c; + c >>= 32; + zz[zzOff + 8] = (uint)c; + } + + for (int i = 1; i < 8; ++i) + { + ++zzOff; + ulong c = 0, x_i = x[xOff + i]; + c += x_i * y_0 + zz[zzOff + 0]; + zz[zzOff + 0] = (uint)c; + c >>= 32; + c += x_i * y_1 + zz[zzOff + 1]; + zz[zzOff + 1] = (uint)c; + c >>= 32; + c += x_i * y_2 + zz[zzOff + 2]; + zz[zzOff + 2] = (uint)c; + c >>= 32; + c += x_i * y_3 + zz[zzOff + 3]; + zz[zzOff + 3] = (uint)c; + c >>= 32; + c += x_i * y_4 + zz[zzOff + 4]; + zz[zzOff + 4] = (uint)c; + c >>= 32; + c += x_i * y_5 + zz[zzOff + 5]; + zz[zzOff + 5] = (uint)c; + c >>= 32; + c += x_i * y_6 + zz[zzOff + 6]; + zz[zzOff + 6] = (uint)c; + c >>= 32; + c += x_i * y_7 + zz[zzOff + 7]; + zz[zzOff + 7] = (uint)c; + c >>= 32; + zz[zzOff + 8] = (uint)c; + } + } + + public static uint MulAddTo(uint[] x, uint[] y, uint[] zz) + { + ulong y_0 = y[0]; + ulong y_1 = y[1]; + ulong y_2 = y[2]; + ulong y_3 = y[3]; + ulong y_4 = y[4]; + ulong y_5 = y[5]; + ulong y_6 = y[6]; + ulong y_7 = y[7]; + + ulong zc = 0; + for (int i = 0; i < 8; ++i) + { + ulong c = 0, x_i = x[i]; + c += x_i * y_0 + zz[i + 0]; + zz[i + 0] = (uint)c; + c >>= 32; + c += x_i * y_1 + zz[i + 1]; + zz[i + 1] = (uint)c; + c >>= 32; + c += x_i * y_2 + zz[i + 2]; + zz[i + 2] = (uint)c; + c >>= 32; + c += x_i * y_3 + zz[i + 3]; + zz[i + 3] = (uint)c; + c >>= 32; + c += x_i * y_4 + zz[i + 4]; + zz[i + 4] = (uint)c; + c >>= 32; + c += x_i * y_5 + zz[i + 5]; + zz[i + 5] = (uint)c; + c >>= 32; + c += x_i * y_6 + zz[i + 6]; + zz[i + 6] = (uint)c; + c >>= 32; + c += x_i * y_7 + zz[i + 7]; + zz[i + 7] = (uint)c; + c >>= 32; + + zc += c + zz[i + 8]; + zz[i + 8] = (uint)zc; + zc >>= 32; + } + return (uint)zc; + } + + public static uint MulAddTo(uint[] x, int xOff, uint[] y, int yOff, uint[] zz, int zzOff) + { + ulong y_0 = y[yOff + 0]; + ulong y_1 = y[yOff + 1]; + ulong y_2 = y[yOff + 2]; + ulong y_3 = y[yOff + 3]; + ulong y_4 = y[yOff + 4]; + ulong y_5 = y[yOff + 5]; + ulong y_6 = y[yOff + 6]; + ulong y_7 = y[yOff + 7]; + + ulong zc = 0; + for (int i = 0; i < 8; ++i) + { + ulong c = 0, x_i = x[xOff + i]; + c += x_i * y_0 + zz[zzOff + 0]; + zz[zzOff + 0] = (uint)c; + c >>= 32; + c += x_i * y_1 + zz[zzOff + 1]; + zz[zzOff + 1] = (uint)c; + c >>= 32; + c += x_i * y_2 + zz[zzOff + 2]; + zz[zzOff + 2] = (uint)c; + c >>= 32; + c += x_i * y_3 + zz[zzOff + 3]; + zz[zzOff + 3] = (uint)c; + c >>= 32; + c += x_i * y_4 + zz[zzOff + 4]; + zz[zzOff + 4] = (uint)c; + c >>= 32; + c += x_i * y_5 + zz[zzOff + 5]; + zz[zzOff + 5] = (uint)c; + c >>= 32; + c += x_i * y_6 + zz[zzOff + 6]; + zz[zzOff + 6] = (uint)c; + c >>= 32; + c += x_i * y_7 + zz[zzOff + 7]; + zz[zzOff + 7] = (uint)c; + c >>= 32; + + zc += c + zz[zzOff + 8]; + zz[zzOff + 8] = (uint)zc; + zc >>= 32; + ++zzOff; + } + return (uint)zc; + } + + public static ulong Mul33Add(uint w, uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + { + Debug.Assert(w >> 31 == 0); + + ulong c = 0, wVal = w; + ulong x0 = x[xOff + 0]; + c += wVal * x0 + y[yOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + ulong x1 = x[xOff + 1]; + c += wVal * x1 + x0 + y[yOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + ulong x2 = x[xOff + 2]; + c += wVal * x2 + x1 + y[yOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + ulong x3 = x[xOff + 3]; + c += wVal * x3 + x2 + y[yOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + ulong x4 = x[xOff + 4]; + c += wVal * x4 + x3 + y[yOff + 4]; + z[zOff + 4] = (uint)c; + c >>= 32; + ulong x5 = x[xOff + 5]; + c += wVal * x5 + x4 + y[yOff + 5]; + z[zOff + 5] = (uint)c; + c >>= 32; + ulong x6 = x[xOff + 6]; + c += wVal * x6 + x5 + y[yOff + 6]; + z[zOff + 6] = (uint)c; + c >>= 32; + ulong x7 = x[xOff + 7]; + c += wVal * x7 + x6 + y[yOff + 7]; + z[zOff + 7] = (uint)c; + c >>= 32; + c += x7; + return c; + } + + public static uint MulByWord(uint x, uint[] z) + { + ulong c = 0, xVal = x; + c += xVal * (ulong)z[0]; + z[0] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[1]; + z[1] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[2]; + z[2] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[3]; + z[3] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[4]; + z[4] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[5]; + z[5] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[6]; + z[6] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[7]; + z[7] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint MulByWordAddTo(uint x, uint[] y, uint[] z) + { + ulong c = 0, xVal = x; + c += xVal * (ulong)z[0] + y[0]; + z[0] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[1] + y[1]; + z[1] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[2] + y[2]; + z[2] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[3] + y[3]; + z[3] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[4] + y[4]; + z[4] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[5] + y[5]; + z[5] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[6] + y[6]; + z[6] = (uint)c; + c >>= 32; + c += xVal * (ulong)z[7] + y[7]; + z[7] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint MulWordAddTo(uint x, uint[] y, int yOff, uint[] z, int zOff) + { + ulong c = 0, xVal = x; + c += xVal * y[yOff + 0] + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += xVal * y[yOff + 1] + z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += xVal * y[yOff + 2] + z[zOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += xVal * y[yOff + 3] + z[zOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + c += xVal * y[yOff + 4] + z[zOff + 4]; + z[zOff + 4] = (uint)c; + c >>= 32; + c += xVal * y[yOff + 5] + z[zOff + 5]; + z[zOff + 5] = (uint)c; + c >>= 32; + c += xVal * y[yOff + 6] + z[zOff + 6]; + z[zOff + 6] = (uint)c; + c >>= 32; + c += xVal * y[yOff + 7] + z[zOff + 7]; + z[zOff + 7] = (uint)c; + c >>= 32; + return (uint)c; + } + + public static uint Mul33DWordAdd(uint x, ulong y, uint[] z, int zOff) + { + Debug.Assert(x >> 31 == 0); + Debug.Assert(zOff <= 4); + ulong c = 0, xVal = x; + ulong y00 = y & M; + c += xVal * y00 + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + ulong y01 = y >> 32; + c += xVal * y01 + y00 + z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += y01 + z[zOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += z[zOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + return c == 0 ? 0 : Nat.IncAt(8, z, zOff, 4); + } + + public static uint Mul33WordAdd(uint x, uint y, uint[] z, int zOff) + { + Debug.Assert(x >> 31 == 0); + Debug.Assert(zOff <= 5); + ulong c = 0, yVal = y; + c += yVal * x + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += yVal + z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += z[zOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + return c == 0 ? 0 : Nat.IncAt(8, z, zOff, 3); + } + + public static uint MulWordDwordAdd(uint x, ulong y, uint[] z, int zOff) + { + Debug.Assert(zOff <= 5); + ulong c = 0, xVal = x; + c += xVal * y + z[zOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += xVal * (y >> 32) + z[zOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += z[zOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + return c == 0 ? 0 : Nat.IncAt(8, z, zOff, 3); + } + + public static uint MulWord(uint x, uint[] y, uint[] z, int zOff) + { + ulong c = 0, xVal = x; + int i = 0; + do + { + c += xVal * y[i]; + z[zOff + i] = (uint)c; + c >>= 32; + } + while (++i < 8); + return (uint)c; + } + + public static void Square(uint[] x, uint[] zz) + { + ulong x_0 = x[0]; + ulong zz_1; + + uint c = 0, w; + { + int i = 7, j = 16; + do + { + ulong xVal = x[i--]; + ulong p = xVal * xVal; + zz[--j] = (c << 31) | (uint)(p >> 33); + zz[--j] = (uint)(p >> 1); + c = (uint)p; + } + while (i > 0); + + { + ulong p = x_0 * x_0; + zz_1 = (ulong)(c << 31) | (p >> 33); + zz[0] = (uint)p; + c = (uint)(p >> 32) & 1; + } + } + + ulong x_1 = x[1]; + ulong zz_2 = zz[2]; + + { + zz_1 += x_1 * x_0; + w = (uint)zz_1; + zz[1] = (w << 1) | c; + c = w >> 31; + zz_2 += zz_1 >> 32; + } + + ulong x_2 = x[2]; + ulong zz_3 = zz[3]; + ulong zz_4 = zz[4]; + { + zz_2 += x_2 * x_0; + w = (uint)zz_2; + zz[2] = (w << 1) | c; + c = w >> 31; + zz_3 += (zz_2 >> 32) + x_2 * x_1; + zz_4 += zz_3 >> 32; + zz_3 &= M; + } + + ulong x_3 = x[3]; + ulong zz_5 = zz[5] + (zz_4 >> 32); zz_4 &= M; + ulong zz_6 = zz[6] + (zz_5 >> 32); zz_5 &= M; + { + zz_3 += x_3 * x_0; + w = (uint)zz_3; + zz[3] = (w << 1) | c; + c = w >> 31; + zz_4 += (zz_3 >> 32) + x_3 * x_1; + zz_5 += (zz_4 >> 32) + x_3 * x_2; + zz_4 &= M; + zz_6 += zz_5 >> 32; + zz_5 &= M; + } + + ulong x_4 = x[4]; + ulong zz_7 = zz[7] + (zz_6 >> 32); zz_6 &= M; + ulong zz_8 = zz[8] + (zz_7 >> 32); zz_7 &= M; + { + zz_4 += x_4 * x_0; + w = (uint)zz_4; + zz[4] = (w << 1) | c; + c = w >> 31; + zz_5 += (zz_4 >> 32) + x_4 * x_1; + zz_6 += (zz_5 >> 32) + x_4 * x_2; + zz_5 &= M; + zz_7 += (zz_6 >> 32) + x_4 * x_3; + zz_6 &= M; + zz_8 += zz_7 >> 32; + zz_7 &= M; + } + + ulong x_5 = x[5]; + ulong zz_9 = zz[9] + (zz_8 >> 32); zz_8 &= M; + ulong zz_10 = zz[10] + (zz_9 >> 32); zz_9 &= M; + { + zz_5 += x_5 * x_0; + w = (uint)zz_5; + zz[5] = (w << 1) | c; + c = w >> 31; + zz_6 += (zz_5 >> 32) + x_5 * x_1; + zz_7 += (zz_6 >> 32) + x_5 * x_2; + zz_6 &= M; + zz_8 += (zz_7 >> 32) + x_5 * x_3; + zz_7 &= M; + zz_9 += (zz_8 >> 32) + x_5 * x_4; + zz_8 &= M; + zz_10 += zz_9 >> 32; + zz_9 &= M; + } + + ulong x_6 = x[6]; + ulong zz_11 = zz[11] + (zz_10 >> 32); zz_10 &= M; + ulong zz_12 = zz[12] + (zz_11 >> 32); zz_11 &= M; + { + zz_6 += x_6 * x_0; + w = (uint)zz_6; + zz[6] = (w << 1) | c; + c = w >> 31; + zz_7 += (zz_6 >> 32) + x_6 * x_1; + zz_8 += (zz_7 >> 32) + x_6 * x_2; + zz_7 &= M; + zz_9 += (zz_8 >> 32) + x_6 * x_3; + zz_8 &= M; + zz_10 += (zz_9 >> 32) + x_6 * x_4; + zz_9 &= M; + zz_11 += (zz_10 >> 32) + x_6 * x_5; + zz_10 &= M; + zz_12 += zz_11 >> 32; + zz_11 &= M; + } + + ulong x_7 = x[7]; + ulong zz_13 = zz[13] + (zz_12 >> 32); zz_12 &= M; + ulong zz_14 = zz[14] + (zz_13 >> 32); zz_13 &= M; + { + zz_7 += x_7 * x_0; + w = (uint)zz_7; + zz[7] = (w << 1) | c; + c = w >> 31; + zz_8 += (zz_7 >> 32) + x_7 * x_1; + zz_9 += (zz_8 >> 32) + x_7 * x_2; + zz_10 += (zz_9 >> 32) + x_7 * x_3; + zz_11 += (zz_10 >> 32) + x_7 * x_4; + zz_12 += (zz_11 >> 32) + x_7 * x_5; + zz_13 += (zz_12 >> 32) + x_7 * x_6; + zz_14 += zz_13 >> 32; + } + + w = (uint)zz_8; + zz[8] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_9; + zz[9] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_10; + zz[10] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_11; + zz[11] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_12; + zz[12] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_13; + zz[13] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_14; + zz[14] = (w << 1) | c; + c = w >> 31; + w = zz[15] + (uint)(zz_14 >> 32); + zz[15] = (w << 1) | c; + } + + public static void Square(uint[] x, int xOff, uint[] zz, int zzOff) + { + ulong x_0 = x[xOff + 0]; + ulong zz_1; + + uint c = 0, w; + { + int i = 7, j = 16; + do + { + ulong xVal = x[xOff + i--]; + ulong p = xVal * xVal; + zz[zzOff + --j] = (c << 31) | (uint)(p >> 33); + zz[zzOff + --j] = (uint)(p >> 1); + c = (uint)p; + } + while (i > 0); + + { + ulong p = x_0 * x_0; + zz_1 = (ulong)(c << 31) | (p >> 33); + zz[zzOff + 0] = (uint)p; + c = (uint)(p >> 32) & 1; + } + } + + ulong x_1 = x[xOff + 1]; + ulong zz_2 = zz[zzOff + 2]; + + { + zz_1 += x_1 * x_0; + w = (uint)zz_1; + zz[zzOff + 1] = (w << 1) | c; + c = w >> 31; + zz_2 += zz_1 >> 32; + } + + ulong x_2 = x[xOff + 2]; + ulong zz_3 = zz[zzOff + 3]; + ulong zz_4 = zz[zzOff + 4]; + { + zz_2 += x_2 * x_0; + w = (uint)zz_2; + zz[zzOff + 2] = (w << 1) | c; + c = w >> 31; + zz_3 += (zz_2 >> 32) + x_2 * x_1; + zz_4 += zz_3 >> 32; + zz_3 &= M; + } + + ulong x_3 = x[xOff + 3]; + ulong zz_5 = zz[zzOff + 5] + (zz_4 >> 32); zz_4 &= M; + ulong zz_6 = zz[zzOff + 6] + (zz_5 >> 32); zz_5 &= M; + { + zz_3 += x_3 * x_0; + w = (uint)zz_3; + zz[zzOff + 3] = (w << 1) | c; + c = w >> 31; + zz_4 += (zz_3 >> 32) + x_3 * x_1; + zz_5 += (zz_4 >> 32) + x_3 * x_2; + zz_4 &= M; + zz_6 += zz_5 >> 32; + zz_5 &= M; + } + + ulong x_4 = x[xOff + 4]; + ulong zz_7 = zz[zzOff + 7] + (zz_6 >> 32); zz_6 &= M; + ulong zz_8 = zz[zzOff + 8] + (zz_7 >> 32); zz_7 &= M; + { + zz_4 += x_4 * x_0; + w = (uint)zz_4; + zz[zzOff + 4] = (w << 1) | c; + c = w >> 31; + zz_5 += (zz_4 >> 32) + x_4 * x_1; + zz_6 += (zz_5 >> 32) + x_4 * x_2; + zz_5 &= M; + zz_7 += (zz_6 >> 32) + x_4 * x_3; + zz_6 &= M; + zz_8 += zz_7 >> 32; + zz_7 &= M; + } + + ulong x_5 = x[xOff + 5]; + ulong zz_9 = zz[zzOff + 9] + (zz_8 >> 32); zz_8 &= M; + ulong zz_10 = zz[zzOff + 10] + (zz_9 >> 32); zz_9 &= M; + { + zz_5 += x_5 * x_0; + w = (uint)zz_5; + zz[zzOff + 5] = (w << 1) | c; + c = w >> 31; + zz_6 += (zz_5 >> 32) + x_5 * x_1; + zz_7 += (zz_6 >> 32) + x_5 * x_2; + zz_6 &= M; + zz_8 += (zz_7 >> 32) + x_5 * x_3; + zz_7 &= M; + zz_9 += (zz_8 >> 32) + x_5 * x_4; + zz_8 &= M; + zz_10 += zz_9 >> 32; + zz_9 &= M; + } + + ulong x_6 = x[xOff + 6]; + ulong zz_11 = zz[zzOff + 11] + (zz_10 >> 32); zz_10 &= M; + ulong zz_12 = zz[zzOff + 12] + (zz_11 >> 32); zz_11 &= M; + { + zz_6 += x_6 * x_0; + w = (uint)zz_6; + zz[zzOff + 6] = (w << 1) | c; + c = w >> 31; + zz_7 += (zz_6 >> 32) + x_6 * x_1; + zz_8 += (zz_7 >> 32) + x_6 * x_2; + zz_7 &= M; + zz_9 += (zz_8 >> 32) + x_6 * x_3; + zz_8 &= M; + zz_10 += (zz_9 >> 32) + x_6 * x_4; + zz_9 &= M; + zz_11 += (zz_10 >> 32) + x_6 * x_5; + zz_10 &= M; + zz_12 += zz_11 >> 32; + zz_11 &= M; + } + + ulong x_7 = x[xOff + 7]; + ulong zz_13 = zz[zzOff + 13] + (zz_12 >> 32); zz_12 &= M; + ulong zz_14 = zz[zzOff + 14] + (zz_13 >> 32); zz_13 &= M; + { + zz_7 += x_7 * x_0; + w = (uint)zz_7; + zz[zzOff + 7] = (w << 1) | c; + c = w >> 31; + zz_8 += (zz_7 >> 32) + x_7 * x_1; + zz_9 += (zz_8 >> 32) + x_7 * x_2; + zz_10 += (zz_9 >> 32) + x_7 * x_3; + zz_11 += (zz_10 >> 32) + x_7 * x_4; + zz_12 += (zz_11 >> 32) + x_7 * x_5; + zz_13 += (zz_12 >> 32) + x_7 * x_6; + zz_14 += zz_13 >> 32; + } + + w = (uint)zz_8; + zz[zzOff + 8] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_9; + zz[zzOff + 9] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_10; + zz[zzOff + 10] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_11; + zz[zzOff + 11] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_12; + zz[zzOff + 12] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_13; + zz[zzOff + 13] = (w << 1) | c; + c = w >> 31; + w = (uint)zz_14; + zz[zzOff + 14] = (w << 1) | c; + c = w >> 31; + w = zz[zzOff + 15] + (uint)(zz_14 >> 32); + zz[zzOff + 15] = (w << 1) | c; + } + + public static int Sub(uint[] x, uint[] y, uint[] z) + { + long c = 0; + c += (long)x[0] - y[0]; + z[0] = (uint)c; + c >>= 32; + c += (long)x[1] - y[1]; + z[1] = (uint)c; + c >>= 32; + c += (long)x[2] - y[2]; + z[2] = (uint)c; + c >>= 32; + c += (long)x[3] - y[3]; + z[3] = (uint)c; + c >>= 32; + c += (long)x[4] - y[4]; + z[4] = (uint)c; + c >>= 32; + c += (long)x[5] - y[5]; + z[5] = (uint)c; + c >>= 32; + c += (long)x[6] - y[6]; + z[6] = (uint)c; + c >>= 32; + c += (long)x[7] - y[7]; + z[7] = (uint)c; + c >>= 32; + return (int)c; + } + + public static int Sub(uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + { + long c = 0; + c += (long)x[xOff + 0] - y[yOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += (long)x[xOff + 1] - y[yOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += (long)x[xOff + 2] - y[yOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += (long)x[xOff + 3] - y[yOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + c += (long)x[xOff + 4] - y[yOff + 4]; + z[zOff + 4] = (uint)c; + c >>= 32; + c += (long)x[xOff + 5] - y[yOff + 5]; + z[zOff + 5] = (uint)c; + c >>= 32; + c += (long)x[xOff + 6] - y[yOff + 6]; + z[zOff + 6] = (uint)c; + c >>= 32; + c += (long)x[xOff + 7] - y[yOff + 7]; + z[zOff + 7] = (uint)c; + c >>= 32; + return (int)c; + } + + public static int SubBothFrom(uint[] x, uint[] y, uint[] z) + { + long c = 0; + c += (long)z[0] - x[0] - y[0]; + z[0] = (uint)c; + c >>= 32; + c += (long)z[1] - x[1] - y[1]; + z[1] = (uint)c; + c >>= 32; + c += (long)z[2] - x[2] - y[2]; + z[2] = (uint)c; + c >>= 32; + c += (long)z[3] - x[3] - y[3]; + z[3] = (uint)c; + c >>= 32; + c += (long)z[4] - x[4] - y[4]; + z[4] = (uint)c; + c >>= 32; + c += (long)z[5] - x[5] - y[5]; + z[5] = (uint)c; + c >>= 32; + c += (long)z[6] - x[6] - y[6]; + z[6] = (uint)c; + c >>= 32; + c += (long)z[7] - x[7] - y[7]; + z[7] = (uint)c; + c >>= 32; + return (int)c; + } + + public static int SubFrom(uint[] x, uint[] z) + { + long c = 0; + c += (long)z[0] - x[0]; + z[0] = (uint)c; + c >>= 32; + c += (long)z[1] - x[1]; + z[1] = (uint)c; + c >>= 32; + c += (long)z[2] - x[2]; + z[2] = (uint)c; + c >>= 32; + c += (long)z[3] - x[3]; + z[3] = (uint)c; + c >>= 32; + c += (long)z[4] - x[4]; + z[4] = (uint)c; + c >>= 32; + c += (long)z[5] - x[5]; + z[5] = (uint)c; + c >>= 32; + c += (long)z[6] - x[6]; + z[6] = (uint)c; + c >>= 32; + c += (long)z[7] - x[7]; + z[7] = (uint)c; + c >>= 32; + return (int)c; + } + + public static int SubFrom(uint[] x, int xOff, uint[] z, int zOff) + { + long c = 0; + c += (long)z[zOff + 0] - x[xOff + 0]; + z[zOff + 0] = (uint)c; + c >>= 32; + c += (long)z[zOff + 1] - x[xOff + 1]; + z[zOff + 1] = (uint)c; + c >>= 32; + c += (long)z[zOff + 2] - x[xOff + 2]; + z[zOff + 2] = (uint)c; + c >>= 32; + c += (long)z[zOff + 3] - x[xOff + 3]; + z[zOff + 3] = (uint)c; + c >>= 32; + c += (long)z[zOff + 4] - x[xOff + 4]; + z[zOff + 4] = (uint)c; + c >>= 32; + c += (long)z[zOff + 5] - x[xOff + 5]; + z[zOff + 5] = (uint)c; + c >>= 32; + c += (long)z[zOff + 6] - x[xOff + 6]; + z[zOff + 6] = (uint)c; + c >>= 32; + c += (long)z[zOff + 7] - x[xOff + 7]; + z[zOff + 7] = (uint)c; + c >>= 32; + return (int)c; + } + + public static BigInteger ToBigInteger(uint[] x) + { + byte[] bs = new byte[32]; + for (int i = 0; i < 8; ++i) + { + uint x_i = x[i]; + if (x_i != 0) + { + Pack.UInt32_To_BE(x_i, bs, (7 - i) << 2); + } + } + return new BigInteger(1, bs); + } + + public static BigInteger ToBigInteger64(ulong[] x) + { + byte[] bs = new byte[32]; + for (int i = 0; i < 4; ++i) + { + ulong x_i = x[i]; + if (x_i != 0L) + { + Pack.UInt64_To_BE(x_i, bs, (3 - i) << 3); + } + } + return new BigInteger(1, bs); + } + + public static void Zero(uint[] z) + { + z[0] = 0; + z[1] = 0; + z[2] = 0; + z[3] = 0; + z[4] = 0; + z[5] = 0; + z[6] = 0; + z[7] = 0; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat256.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat256.cs.meta new file mode 100644 index 0000000..97924fe --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat256.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: df6c923bb1aaacb4cb843c783a942a84 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat320.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat320.cs new file mode 100644 index 0000000..0b250aa --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat320.cs @@ -0,0 +1,92 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Crypto.Utilities; + +namespace Org.BouncyCastle.Math.Raw +{ + internal abstract class Nat320 + { + public static void Copy64(ulong[] x, ulong[] z) + { + z[0] = x[0]; + z[1] = x[1]; + z[2] = x[2]; + z[3] = x[3]; + z[4] = x[4]; + } + + public static void Copy64(ulong[] x, int xOff, ulong[] z, int zOff) + { + z[zOff + 0] = x[xOff + 0]; + z[zOff + 1] = x[xOff + 1]; + z[zOff + 2] = x[xOff + 2]; + z[zOff + 3] = x[xOff + 3]; + z[zOff + 4] = x[xOff + 4]; + } + + public static ulong[] Create64() + { + return new ulong[5]; + } + + public static ulong[] CreateExt64() + { + return new ulong[10]; + } + + public static bool Eq64(ulong[] x, ulong[] y) + { + for (int i = 4; i >= 0; --i) + { + if (x[i] != y[i]) + { + return false; + } + } + return true; + } + + public static bool IsOne64(ulong[] x) + { + if (x[0] != 1UL) + { + return false; + } + for (int i = 1; i < 5; ++i) + { + if (x[i] != 0UL) + { + return false; + } + } + return true; + } + + public static bool IsZero64(ulong[] x) + { + for (int i = 0; i < 5; ++i) + { + if (x[i] != 0UL) + { + return false; + } + } + return true; + } + + public static BigInteger ToBigInteger64(ulong[] x) + { + byte[] bs = new byte[40]; + for (int i = 0; i < 5; ++i) + { + ulong x_i = x[i]; + if (x_i != 0L) + { + Pack.UInt64_To_BE(x_i, bs, (4 - i) << 3); + } + } + return new BigInteger(1, bs); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat320.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat320.cs.meta new file mode 100644 index 0000000..6c7c544 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat320.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b37401553d24be34d8a6d73a993750ed +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat384.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat384.cs new file mode 100644 index 0000000..ed1c47e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat384.cs @@ -0,0 +1,46 @@ +using System; +using System.Diagnostics; + +namespace Org.BouncyCastle.Math.Raw +{ + internal abstract class Nat384 + { + public static void Mul(uint[] x, uint[] y, uint[] zz) + { + Nat192.Mul(x, y, zz); + Nat192.Mul(x, 6, y, 6, zz, 12); + + uint c18 = Nat192.AddToEachOther(zz, 6, zz, 12); + uint c12 = c18 + Nat192.AddTo(zz, 0, zz, 6, 0); + c18 += Nat192.AddTo(zz, 18, zz, 12, c12); + + uint[] dx = Nat192.Create(), dy = Nat192.Create(); + bool neg = Nat192.Diff(x, 6, x, 0, dx, 0) != Nat192.Diff(y, 6, y, 0, dy, 0); + + uint[] tt = Nat192.CreateExt(); + Nat192.Mul(dx, dy, tt); + + c18 += neg ? Nat.AddTo(12, tt, 0, zz, 6) : (uint)Nat.SubFrom(12, tt, 0, zz, 6); + Nat.AddWordAt(24, c18, zz, 18); + } + + public static void Square(uint[] x, uint[] zz) + { + Nat192.Square(x, zz); + Nat192.Square(x, 6, zz, 12); + + uint c18 = Nat192.AddToEachOther(zz, 6, zz, 12); + uint c12 = c18 + Nat192.AddTo(zz, 0, zz, 6, 0); + c18 += Nat192.AddTo(zz, 18, zz, 12, c12); + + uint[] dx = Nat192.Create(); + Nat192.Diff(x, 6, x, 0, dx, 0); + + uint[] m = Nat192.CreateExt(); + Nat192.Square(dx, m); + + c18 += (uint)Nat.SubFrom(12, m, 0, zz, 6); + Nat.AddWordAt(24, c18, zz, 18); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat384.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat384.cs.meta new file mode 100644 index 0000000..2baff75 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat384.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 40307584f4cd11a448271e89eb60a1fd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat448.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat448.cs new file mode 100644 index 0000000..898e331 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat448.cs @@ -0,0 +1,134 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Crypto.Utilities; + +namespace Org.BouncyCastle.Math.Raw +{ + internal abstract class Nat448 + { + public static void Copy64(ulong[] x, ulong[] z) + { + z[0] = x[0]; + z[1] = x[1]; + z[2] = x[2]; + z[3] = x[3]; + z[4] = x[4]; + z[5] = x[5]; + z[6] = x[6]; + } + + public static void Copy64(ulong[] x, int xOff, ulong[] z, int zOff) + { + z[zOff + 0] = x[xOff + 0]; + z[zOff + 1] = x[xOff + 1]; + z[zOff + 2] = x[xOff + 2]; + z[zOff + 3] = x[xOff + 3]; + z[zOff + 4] = x[xOff + 4]; + z[zOff + 5] = x[xOff + 5]; + z[zOff + 6] = x[xOff + 6]; + } + + public static ulong[] Create64() + { + return new ulong[7]; + } + + public static ulong[] CreateExt64() + { + return new ulong[14]; + } + + public static bool Eq64(ulong[] x, ulong[] y) + { + for (int i = 6; i >= 0; --i) + { + if (x[i] != y[i]) + { + return false; + } + } + return true; + } + + public static bool IsOne64(ulong[] x) + { + if (x[0] != 1UL) + { + return false; + } + for (int i = 1; i < 7; ++i) + { + if (x[i] != 0UL) + { + return false; + } + } + return true; + } + + public static bool IsZero64(ulong[] x) + { + for (int i = 0; i < 7; ++i) + { + if (x[i] != 0UL) + { + return false; + } + } + return true; + } + + public static void Mul(uint[] x, uint[] y, uint[] zz) + { + Nat224.Mul(x, y, zz); + Nat224.Mul(x, 7, y, 7, zz, 14); + + uint c21 = Nat224.AddToEachOther(zz, 7, zz, 14); + uint c14 = c21 + Nat224.AddTo(zz, 0, zz, 7, 0); + c21 += Nat224.AddTo(zz, 21, zz, 14, c14); + + uint[] dx = Nat224.Create(), dy = Nat224.Create(); + bool neg = Nat224.Diff(x, 7, x, 0, dx, 0) != Nat224.Diff(y, 7, y, 0, dy, 0); + + uint[] tt = Nat224.CreateExt(); + Nat224.Mul(dx, dy, tt); + + c21 += neg ? Nat.AddTo(14, tt, 0, zz, 7) : (uint)Nat.SubFrom(14, tt, 0, zz, 7); + Nat.AddWordAt(28, c21, zz, 21); + } + + public static void Square(uint[] x, uint[] zz) + { + Nat224.Square(x, zz); + Nat224.Square(x, 7, zz, 14); + + uint c21 = Nat224.AddToEachOther(zz, 7, zz, 14); + uint c14 = c21 + Nat224.AddTo(zz, 0, zz, 7, 0); + c21 += Nat224.AddTo(zz, 21, zz, 14, c14); + + uint[] dx = Nat224.Create(); + Nat224.Diff(x, 7, x, 0, dx, 0); + + uint[] tt = Nat224.CreateExt(); + Nat224.Square(dx, tt); + + c21 += (uint)Nat.SubFrom(14, tt, 0, zz, 7); + Nat.AddWordAt(28, c21, zz, 21); + } + + public static BigInteger ToBigInteger64(ulong[] x) + { + byte[] bs = new byte[56]; + for (int i = 0; i < 7; ++i) + { + ulong x_i = x[i]; + if (x_i != 0L) + { + Pack.UInt64_To_BE(x_i, bs, (6 - i) << 3); + } + } + return new BigInteger(1, bs); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat448.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat448.cs.meta new file mode 100644 index 0000000..fec5d64 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat448.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f0d175610163f1e4e900fdddef346726 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat512.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat512.cs new file mode 100644 index 0000000..a9ef2b3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat512.cs @@ -0,0 +1,46 @@ +using System; +using System.Diagnostics; + +namespace Org.BouncyCastle.Math.Raw +{ + internal abstract class Nat512 + { + public static void Mul(uint[] x, uint[] y, uint[] zz) + { + Nat256.Mul(x, y, zz); + Nat256.Mul(x, 8, y, 8, zz, 16); + + uint c24 = Nat256.AddToEachOther(zz, 8, zz, 16); + uint c16 = c24 + Nat256.AddTo(zz, 0, zz, 8, 0); + c24 += Nat256.AddTo(zz, 24, zz, 16, c16); + + uint[] dx = Nat256.Create(), dy = Nat256.Create(); + bool neg = Nat256.Diff(x, 8, x, 0, dx, 0) != Nat256.Diff(y, 8, y, 0, dy, 0); + + uint[] tt = Nat256.CreateExt(); + Nat256.Mul(dx, dy, tt); + + c24 += neg ? Nat.AddTo(16, tt, 0, zz, 8) : (uint)Nat.SubFrom(16, tt, 0, zz, 8); + Nat.AddWordAt(32, c24, zz, 24); + } + + public static void Square(uint[] x, uint[] zz) + { + Nat256.Square(x, zz); + Nat256.Square(x, 8, zz, 16); + + uint c24 = Nat256.AddToEachOther(zz, 8, zz, 16); + uint c16 = c24 + Nat256.AddTo(zz, 0, zz, 8, 0); + c24 += Nat256.AddTo(zz, 24, zz, 16, c16); + + uint[] dx = Nat256.Create(); + Nat256.Diff(x, 8, x, 0, dx, 0); + + uint[] m = Nat256.CreateExt(); + Nat256.Square(dx, m); + + c24 += (uint)Nat.SubFrom(16, m, 0, zz, 8); + Nat.AddWordAt(32, c24, zz, 24); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat512.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat512.cs.meta new file mode 100644 index 0000000..7e40e99 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat512.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5c6f7a7fc954af94596855b0b6aae056 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat576.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat576.cs new file mode 100644 index 0000000..174d52b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat576.cs @@ -0,0 +1,100 @@ +using System; +using System.Diagnostics; + +using Org.BouncyCastle.Crypto.Utilities; + +namespace Org.BouncyCastle.Math.Raw +{ + internal abstract class Nat576 + { + public static void Copy64(ulong[] x, ulong[] z) + { + z[0] = x[0]; + z[1] = x[1]; + z[2] = x[2]; + z[3] = x[3]; + z[4] = x[4]; + z[5] = x[5]; + z[6] = x[6]; + z[7] = x[7]; + z[8] = x[8]; + } + + public static void Copy64(ulong[] x, int xOff, ulong[] z, int zOff) + { + z[zOff + 0] = x[xOff + 0]; + z[zOff + 1] = x[xOff + 1]; + z[zOff + 2] = x[xOff + 2]; + z[zOff + 3] = x[xOff + 3]; + z[zOff + 4] = x[xOff + 4]; + z[zOff + 5] = x[xOff + 5]; + z[zOff + 6] = x[xOff + 6]; + z[zOff + 7] = x[xOff + 7]; + z[zOff + 8] = x[xOff + 8]; + } + + public static ulong[] Create64() + { + return new ulong[9]; + } + + public static ulong[] CreateExt64() + { + return new ulong[18]; + } + + public static bool Eq64(ulong[] x, ulong[] y) + { + for (int i = 8; i >= 0; --i) + { + if (x[i] != y[i]) + { + return false; + } + } + return true; + } + + public static bool IsOne64(ulong[] x) + { + if (x[0] != 1UL) + { + return false; + } + for (int i = 1; i < 9; ++i) + { + if (x[i] != 0UL) + { + return false; + } + } + return true; + } + + public static bool IsZero64(ulong[] x) + { + for (int i = 0; i < 9; ++i) + { + if (x[i] != 0UL) + { + return false; + } + } + return true; + } + + public static BigInteger ToBigInteger64(ulong[] x) + { + byte[] bs = new byte[72]; + for (int i = 0; i < 9; ++i) + { + ulong x_i = x[i]; + if (x_i != 0L) + { + Pack.UInt64_To_BE(x_i, bs, (8 - i) << 3); + } + } + return new BigInteger(1, bs); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat576.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat576.cs.meta new file mode 100644 index 0000000..062c1e9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/math/raw/Nat576.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d9bbf9475cf99e94396fd0297677d0ad +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp.meta new file mode 100644 index 0000000..b5fc6c8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ee651fbdb37e34a49822b310f025d5ea +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/BasicOCSPResp.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/BasicOCSPResp.cs new file mode 100644 index 0000000..e79d556 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/BasicOCSPResp.cs @@ -0,0 +1,220 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Ocsp; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Security.Certificates; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.X509; +using Org.BouncyCastle.X509.Store; + +namespace Org.BouncyCastle.Ocsp +{ + /// + /// + /// BasicOcspResponse ::= SEQUENCE { + /// tbsResponseData ResponseData, + /// signatureAlgorithm AlgorithmIdentifier, + /// signature BIT STRING, + /// certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL + /// } + /// + /// + public class BasicOcspResp + : X509ExtensionBase + { + private readonly BasicOcspResponse resp; + private readonly ResponseData data; +// private readonly X509Certificate[] chain; + + public BasicOcspResp( + BasicOcspResponse resp) + { + this.resp = resp; + this.data = resp.TbsResponseData; + } + + /// The DER encoding of the tbsResponseData field. + /// In the event of an encoding error. + public byte[] GetTbsResponseData() + { + try + { + return data.GetDerEncoded(); + } + catch (IOException e) + { + throw new OcspException("problem encoding tbsResponseData", e); + } + } + + public int Version + { + get { return data.Version.IntValueExact + 1; } + } + + public RespID ResponderId + { + get { return new RespID(data.ResponderID); } + } + + public DateTime ProducedAt + { + get { return data.ProducedAt.ToDateTime(); } + } + + public SingleResp[] Responses + { + get + { + Asn1Sequence s = data.Responses; + SingleResp[] rs = new SingleResp[s.Count]; + + for (int i = 0; i != rs.Length; i++) + { + rs[i] = new SingleResp(SingleResponse.GetInstance(s[i])); + } + + return rs; + } + } + + public X509Extensions ResponseExtensions + { + get { return data.ResponseExtensions; } + } + + protected override X509Extensions GetX509Extensions() + { + return ResponseExtensions; + } + + public string SignatureAlgName + { + get { return OcspUtilities.GetAlgorithmName(resp.SignatureAlgorithm.Algorithm); } + } + + public string SignatureAlgOid + { + get { return resp.SignatureAlgorithm.Algorithm.Id; } + } + + [Obsolete("RespData class is no longer required as all functionality is available on this class")] + public RespData GetResponseData() + { + return new RespData(data); + } + + public byte[] GetSignature() + { + return resp.GetSignatureOctets(); + } + + private IList GetCertList() + { + // load the certificates and revocation lists if we have any + + IList certs = Platform.CreateArrayList(); + Asn1Sequence s = resp.Certs; + + if (s != null) + { + foreach (Asn1Encodable ae in s) + { + try + { + certs.Add(new X509CertificateParser().ReadCertificate(ae.GetEncoded())); + } + catch (IOException ex) + { + throw new OcspException("can't re-encode certificate!", ex); + } + catch (CertificateException ex) + { + throw new OcspException("can't re-encode certificate!", ex); + } + } + } + + return certs; + } + + public X509Certificate[] GetCerts() + { + IList certs = GetCertList(); + X509Certificate[] result = new X509Certificate[certs.Count]; + for (int i = 0; i < certs.Count; ++i) + { + result[i] = (X509Certificate)certs[i]; + } + return result; + } + + /// The certificates, if any, associated with the response. + /// In the event of an encoding error. + public IX509Store GetCertificates( + string type) + { + try + { + return X509StoreFactory.Create( + "Certificate/" + type, + new X509CollectionStoreParameters(this.GetCertList())); + } + catch (Exception e) + { + throw new OcspException("can't setup the CertStore", e); + } + } + + /// + /// Verify the signature against the tbsResponseData object we contain. + /// + public bool Verify( + AsymmetricKeyParameter publicKey) + { + try + { + ISigner signature = SignerUtilities.GetSigner(this.SignatureAlgName); + signature.Init(false, publicKey); + byte[] bs = data.GetDerEncoded(); + signature.BlockUpdate(bs, 0, bs.Length); + + return signature.VerifySignature(this.GetSignature()); + } + catch (Exception e) + { + throw new OcspException("exception processing sig: " + e, e); + } + } + + /// The ASN.1 encoded representation of this object. + public byte[] GetEncoded() + { + return resp.GetEncoded(); + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + BasicOcspResp other = obj as BasicOcspResp; + + if (other == null) + return false; + + return resp.Equals(other.resp); + } + + public override int GetHashCode() + { + return resp.GetHashCode(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/BasicOCSPResp.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/BasicOCSPResp.cs.meta new file mode 100644 index 0000000..ce8c3bd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/BasicOCSPResp.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4ce00f0254f030048b9125023f29d9e3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/BasicOCSPRespGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/BasicOCSPRespGenerator.cs new file mode 100644 index 0000000..0dd4e0a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/BasicOCSPRespGenerator.cs @@ -0,0 +1,313 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Ocsp; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Security.Certificates; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.X509; +using Org.BouncyCastle.Crypto.Operators; + +namespace Org.BouncyCastle.Ocsp +{ + /** + * Generator for basic OCSP response objects. + */ + public class BasicOcspRespGenerator + { + private readonly IList list = Platform.CreateArrayList(); + + private X509Extensions responseExtensions; + private RespID responderID; + + private class ResponseObject + { + internal CertificateID certId; + internal CertStatus certStatus; + internal DerGeneralizedTime thisUpdate; + internal DerGeneralizedTime nextUpdate; + internal X509Extensions extensions; + + public ResponseObject( + CertificateID certId, + CertificateStatus certStatus, + DateTime thisUpdate, + X509Extensions extensions) + : this(certId, certStatus, new DerGeneralizedTime(thisUpdate), null, extensions) + { + } + + public ResponseObject( + CertificateID certId, + CertificateStatus certStatus, + DateTime thisUpdate, + DateTime nextUpdate, + X509Extensions extensions) + : this(certId, certStatus, new DerGeneralizedTime(thisUpdate), new DerGeneralizedTime(nextUpdate), extensions) + { + } + + private ResponseObject( + CertificateID certId, + CertificateStatus certStatus, + DerGeneralizedTime thisUpdate, + DerGeneralizedTime nextUpdate, + X509Extensions extensions) + { + this.certId = certId; + + if (certStatus == null) + { + this.certStatus = new CertStatus(); + } + else if (certStatus is UnknownStatus) + { + this.certStatus = new CertStatus(2, DerNull.Instance); + } + else + { + RevokedStatus rs = (RevokedStatus) certStatus; + CrlReason revocationReason = rs.HasRevocationReason + ? new CrlReason(rs.RevocationReason) + : null; + + this.certStatus = new CertStatus( + new RevokedInfo(new DerGeneralizedTime(rs.RevocationTime), revocationReason)); + } + + this.thisUpdate = thisUpdate; + this.nextUpdate = nextUpdate; + + this.extensions = extensions; + } + + public SingleResponse ToResponse() + { + return new SingleResponse(certId.ToAsn1Object(), certStatus, thisUpdate, nextUpdate, extensions); + } + } + + /** + * basic constructor + */ + public BasicOcspRespGenerator( + RespID responderID) + { + this.responderID = responderID; + } + + /** + * construct with the responderID to be the SHA-1 keyHash of the passed in public key. + */ + public BasicOcspRespGenerator( + AsymmetricKeyParameter publicKey) + { + this.responderID = new RespID(publicKey); + } + + /** + * Add a response for a particular Certificate ID. + * + * @param certID certificate ID details + * @param certStatus status of the certificate - null if okay + */ + public void AddResponse( + CertificateID certID, + CertificateStatus certStatus) + { + list.Add(new ResponseObject(certID, certStatus, DateTime.UtcNow, null)); + } + + /** + * Add a response for a particular Certificate ID. + * + * @param certID certificate ID details + * @param certStatus status of the certificate - null if okay + * @param singleExtensions optional extensions + */ + public void AddResponse( + CertificateID certID, + CertificateStatus certStatus, + X509Extensions singleExtensions) + { + list.Add(new ResponseObject(certID, certStatus, DateTime.UtcNow, singleExtensions)); + } + + /** + * Add a response for a particular Certificate ID. + * + * @param certID certificate ID details + * @param nextUpdate date when next update should be requested + * @param certStatus status of the certificate - null if okay + * @param singleExtensions optional extensions + */ + public void AddResponse( + CertificateID certID, + CertificateStatus certStatus, + DateTime nextUpdate, + X509Extensions singleExtensions) + { + list.Add(new ResponseObject(certID, certStatus, DateTime.UtcNow, nextUpdate, singleExtensions)); + } + + /** + * Add a response for a particular Certificate ID. + * + * @param certID certificate ID details + * @param thisUpdate date this response was valid on + * @param nextUpdate date when next update should be requested + * @param certStatus status of the certificate - null if okay + * @param singleExtensions optional extensions + */ + public void AddResponse( + CertificateID certID, + CertificateStatus certStatus, + DateTime thisUpdate, + DateTime nextUpdate, + X509Extensions singleExtensions) + { + list.Add(new ResponseObject(certID, certStatus, thisUpdate, nextUpdate, singleExtensions)); + } + + /** + * Set the extensions for the response. + * + * @param responseExtensions the extension object to carry. + */ + public void SetResponseExtensions( + X509Extensions responseExtensions) + { + this.responseExtensions = responseExtensions; + } + + private BasicOcspResp GenerateResponse( + ISignatureFactory signatureCalculator, + X509Certificate[] chain, + DateTime producedAt) + { + AlgorithmIdentifier signingAlgID = (AlgorithmIdentifier)signatureCalculator.AlgorithmDetails; + DerObjectIdentifier signingAlgorithm = signingAlgID.Algorithm; + + Asn1EncodableVector responses = new Asn1EncodableVector(); + + foreach (ResponseObject respObj in list) + { + try + { + responses.Add(respObj.ToResponse()); + } + catch (Exception e) + { + throw new OcspException("exception creating Request", e); + } + } + + ResponseData tbsResp = new ResponseData(responderID.ToAsn1Object(), new DerGeneralizedTime(producedAt), new DerSequence(responses), responseExtensions); + DerBitString bitSig = null; + + try + { + IStreamCalculator streamCalculator = signatureCalculator.CreateCalculator(); + + byte[] encoded = tbsResp.GetDerEncoded(); + + streamCalculator.Stream.Write(encoded, 0, encoded.Length); + + Platform.Dispose(streamCalculator.Stream); + + bitSig = new DerBitString(((IBlockResult)streamCalculator.GetResult()).Collect()); + } + catch (Exception e) + { + throw new OcspException("exception processing TBSRequest: " + e, e); + } + + AlgorithmIdentifier sigAlgId = OcspUtilities.GetSigAlgID(signingAlgorithm); + + DerSequence chainSeq = null; + if (chain != null && chain.Length > 0) + { + Asn1EncodableVector v = new Asn1EncodableVector(); + try + { + for (int i = 0; i != chain.Length; i++) + { + v.Add( + X509CertificateStructure.GetInstance( + Asn1Object.FromByteArray(chain[i].GetEncoded()))); + } + } + catch (IOException e) + { + throw new OcspException("error processing certs", e); + } + catch (CertificateEncodingException e) + { + throw new OcspException("error encoding certs", e); + } + + chainSeq = new DerSequence(v); + } + + return new BasicOcspResp(new BasicOcspResponse(tbsResp, sigAlgId, bitSig, chainSeq)); + } + + public BasicOcspResp Generate( + string signingAlgorithm, + AsymmetricKeyParameter privateKey, + X509Certificate[] chain, + DateTime thisUpdate) + { + return Generate(signingAlgorithm, privateKey, chain, thisUpdate, null); + } + + public BasicOcspResp Generate( + string signingAlgorithm, + AsymmetricKeyParameter privateKey, + X509Certificate[] chain, + DateTime producedAt, + SecureRandom random) + { + if (signingAlgorithm == null) + { + throw new ArgumentException("no signing algorithm specified"); + } + + return GenerateResponse(new Asn1SignatureFactory(signingAlgorithm, privateKey, random), chain, producedAt); + } + + /// + /// Generate the signed response using the passed in signature calculator. + /// + /// Implementation of signing calculator factory. + /// The certificate chain associated with the response signer. + /// "produced at" date. + /// + public BasicOcspResp Generate( + ISignatureFactory signatureCalculatorFactory, + X509Certificate[] chain, + DateTime producedAt) + { + if (signatureCalculatorFactory == null) + { + throw new ArgumentException("no signature calculator specified"); + } + + return GenerateResponse(signatureCalculatorFactory, chain, producedAt); + } + + /** + * Return an IEnumerable of the signature names supported by the generator. + * + * @return an IEnumerable containing recognised names. + */ + public IEnumerable SignatureAlgNames + { + get { return OcspUtilities.AlgNames; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/BasicOCSPRespGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/BasicOCSPRespGenerator.cs.meta new file mode 100644 index 0000000..7c0abfb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/BasicOCSPRespGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f4d3bb48cfee60a4cacc525048c0d2ef +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/CertificateID.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/CertificateID.cs new file mode 100644 index 0000000..ec902d5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/CertificateID.cs @@ -0,0 +1,141 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Ocsp; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.Ocsp +{ + public class CertificateID + { + public const string HashSha1 = "1.3.14.3.2.26"; + + private readonly CertID id; + + public CertificateID( + CertID id) + { + if (id == null) + throw new ArgumentNullException("id"); + + this.id = id; + } + + /** + * create from an issuer certificate and the serial number of the + * certificate it signed. + * @exception OcspException if any problems occur creating the id fields. + */ + public CertificateID( + string hashAlgorithm, + X509Certificate issuerCert, + BigInteger serialNumber) + { + AlgorithmIdentifier hashAlg = new AlgorithmIdentifier( + new DerObjectIdentifier(hashAlgorithm), DerNull.Instance); + + this.id = CreateCertID(hashAlg, issuerCert, new DerInteger(serialNumber)); + } + + public string HashAlgOid + { + get { return id.HashAlgorithm.Algorithm.Id; } + } + + public byte[] GetIssuerNameHash() + { + return id.IssuerNameHash.GetOctets(); + } + + public byte[] GetIssuerKeyHash() + { + return id.IssuerKeyHash.GetOctets(); + } + + /** + * return the serial number for the certificate associated + * with this request. + */ + public BigInteger SerialNumber + { + get { return id.SerialNumber.Value; } + } + + public bool MatchesIssuer( + X509Certificate issuerCert) + { + return CreateCertID(id.HashAlgorithm, issuerCert, id.SerialNumber).Equals(id); + } + + public CertID ToAsn1Object() + { + return id; + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + CertificateID other = obj as CertificateID; + + if (other == null) + return false; + + return id.ToAsn1Object().Equals(other.id.ToAsn1Object()); + } + + public override int GetHashCode() + { + return id.ToAsn1Object().GetHashCode(); + } + + + /** + * Create a new CertificateID for a new serial number derived from a previous one + * calculated for the same CA certificate. + * + * @param original the previously calculated CertificateID for the CA. + * @param newSerialNumber the serial number for the new certificate of interest. + * + * @return a new CertificateID for newSerialNumber + */ + public static CertificateID DeriveCertificateID(CertificateID original, BigInteger newSerialNumber) + { + return new CertificateID(new CertID(original.id.HashAlgorithm, original.id.IssuerNameHash, + original.id.IssuerKeyHash, new DerInteger(newSerialNumber))); + } + + private static CertID CreateCertID( + AlgorithmIdentifier hashAlg, + X509Certificate issuerCert, + DerInteger serialNumber) + { + try + { + String hashAlgorithm = hashAlg.Algorithm.Id; + + X509Name issuerName = PrincipalUtilities.GetSubjectX509Principal(issuerCert); + byte[] issuerNameHash = DigestUtilities.CalculateDigest( + hashAlgorithm, issuerName.GetEncoded()); + + AsymmetricKeyParameter issuerKey = issuerCert.GetPublicKey(); + SubjectPublicKeyInfo info = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(issuerKey); + byte[] issuerKeyHash = DigestUtilities.CalculateDigest( + hashAlgorithm, info.PublicKeyData.GetBytes()); + + return new CertID(hashAlg, new DerOctetString(issuerNameHash), + new DerOctetString(issuerKeyHash), serialNumber); + } + catch (Exception e) + { + throw new OcspException("problem creating ID: " + e, e); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/CertificateID.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/CertificateID.cs.meta new file mode 100644 index 0000000..f6104a9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/CertificateID.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f8d3c5e2144ffad47a00afd6991455e1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/CertificateStatus.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/CertificateStatus.cs new file mode 100644 index 0000000..edfcc25 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/CertificateStatus.cs @@ -0,0 +1,9 @@ +using System; + +namespace Org.BouncyCastle.Ocsp +{ + public abstract class CertificateStatus + { + public static readonly CertificateStatus Good = null; + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/CertificateStatus.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/CertificateStatus.cs.meta new file mode 100644 index 0000000..0d99e57 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/CertificateStatus.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c08f9029b0572a54bbe9ff04d283a296 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/OCSPException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/OCSPException.cs new file mode 100644 index 0000000..d7b14dd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/OCSPException.cs @@ -0,0 +1,28 @@ +using System; + +namespace Org.BouncyCastle.Ocsp +{ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE) + [Serializable] +#endif + public class OcspException + : Exception + { + public OcspException() + { + } + + public OcspException( + string message) + : base(message) + { + } + + public OcspException( + string message, + Exception e) + : base(message, e) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/OCSPException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/OCSPException.cs.meta new file mode 100644 index 0000000..0e5bc4a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/OCSPException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: df134edd5663d344c84b527a8cfd4fe8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/OCSPReq.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/OCSPReq.cs new file mode 100644 index 0000000..5408f06 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/OCSPReq.cs @@ -0,0 +1,268 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Ocsp; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Security.Certificates; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.X509; +using Org.BouncyCastle.X509.Store; + +namespace Org.BouncyCastle.Ocsp +{ + /** + *
    +	 * OcspRequest     ::=     SEQUENCE {
    +	 *       tbsRequest                  TBSRequest,
    +	 *       optionalSignature   [0]     EXPLICIT Signature OPTIONAL }
    +	 *
    +	 *   TBSRequest      ::=     SEQUENCE {
    +	 *       version             [0]     EXPLICIT Version DEFAULT v1,
    +	 *       requestorName       [1]     EXPLICIT GeneralName OPTIONAL,
    +	 *       requestList                 SEQUENCE OF Request,
    +	 *       requestExtensions   [2]     EXPLICIT Extensions OPTIONAL }
    +	 *
    +	 *   Signature       ::=     SEQUENCE {
    +	 *       signatureAlgorithm      AlgorithmIdentifier,
    +	 *       signature               BIT STRING,
    +	 *       certs               [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL}
    +	 *
    +	 *   Version         ::=             INTEGER  {  v1(0) }
    +	 *
    +	 *   Request         ::=     SEQUENCE {
    +	 *       reqCert                     CertID,
    +	 *       singleRequestExtensions     [0] EXPLICIT Extensions OPTIONAL }
    +	 *
    +	 *   CertID          ::=     SEQUENCE {
    +	 *       hashAlgorithm       AlgorithmIdentifier,
    +	 *       issuerNameHash      OCTET STRING, -- Hash of Issuer's DN
    +	 *       issuerKeyHash       OCTET STRING, -- Hash of Issuers public key
    +	 *       serialNumber        CertificateSerialNumber }
    +	 * 
    + */ + public class OcspReq + : X509ExtensionBase + { + private OcspRequest req; + + public OcspReq( + OcspRequest req) + { + this.req = req; + } + + public OcspReq( + byte[] req) + : this(new Asn1InputStream(req)) + { + } + + public OcspReq( + Stream inStr) + : this(new Asn1InputStream(inStr)) + { + } + + private OcspReq( + Asn1InputStream aIn) + { + try + { + this.req = OcspRequest.GetInstance(aIn.ReadObject()); + } + catch (ArgumentException e) + { + throw new IOException("malformed request: " + e.Message); + } + catch (InvalidCastException e) + { + throw new IOException("malformed request: " + e.Message); + } + } + + /** + * Return the DER encoding of the tbsRequest field. + * @return DER encoding of tbsRequest + * @throws OcspException in the event of an encoding error. + */ + public byte[] GetTbsRequest() + { + try + { + return req.TbsRequest.GetEncoded(); + } + catch (IOException e) + { + throw new OcspException("problem encoding tbsRequest", e); + } + } + + public int Version + { + get { return req.TbsRequest.Version.IntValueExact + 1; } + } + + public GeneralName RequestorName + { + get { return GeneralName.GetInstance(req.TbsRequest.RequestorName); } + } + + public Req[] GetRequestList() + { + Asn1Sequence seq = req.TbsRequest.RequestList; + Req[] requests = new Req[seq.Count]; + + for (int i = 0; i != requests.Length; i++) + { + requests[i] = new Req(Request.GetInstance(seq[i])); + } + + return requests; + } + + public X509Extensions RequestExtensions + { + get { return X509Extensions.GetInstance(req.TbsRequest.RequestExtensions); } + } + + protected override X509Extensions GetX509Extensions() + { + return RequestExtensions; + } + + /** + * return the object identifier representing the signature algorithm + */ + public string SignatureAlgOid + { + get + { + if (!this.IsSigned) + return null; + + return req.OptionalSignature.SignatureAlgorithm.Algorithm.Id; + } + } + + public byte[] GetSignature() + { + if (!this.IsSigned) + return null; + + return req.OptionalSignature.GetSignatureOctets(); + } + + private IList GetCertList() + { + // load the certificates if we have any + + IList certs = Platform.CreateArrayList(); + Asn1Sequence s = req.OptionalSignature.Certs; + + if (s != null) + { + foreach (Asn1Encodable ae in s) + { + try + { + certs.Add(new X509CertificateParser().ReadCertificate(ae.GetEncoded())); + } + catch (Exception e) + { + throw new OcspException("can't re-encode certificate!", e); + } + } + } + + return certs; + } + + public X509Certificate[] GetCerts() + { + if (!this.IsSigned) + return null; + + IList certs = this.GetCertList(); + X509Certificate[] result = new X509Certificate[certs.Count]; + for (int i = 0; i < certs.Count; ++i) + { + result[i] = (X509Certificate)certs[i]; + } + return result; + } + + /** + * If the request is signed return a possibly empty CertStore containing the certificates in the + * request. If the request is not signed the method returns null. + * + * @return null if not signed, a CertStore otherwise + * @throws OcspException + */ + public IX509Store GetCertificates( + string type) + { + if (!this.IsSigned) + return null; + + try + { + return X509StoreFactory.Create( + "Certificate/" + type, + new X509CollectionStoreParameters(this.GetCertList())); + } + catch (Exception e) + { + throw new OcspException("can't setup the CertStore", e); + } + } + + /** + * Return whether or not this request is signed. + * + * @return true if signed false otherwise. + */ + public bool IsSigned + { + get { return req.OptionalSignature != null; } + } + + /** + * Verify the signature against the TBSRequest object we contain. + */ + public bool Verify( + AsymmetricKeyParameter publicKey) + { + if (!this.IsSigned) + throw new OcspException("attempt to Verify signature on unsigned object"); + + try + { + ISigner signature = SignerUtilities.GetSigner(this.SignatureAlgOid); + + signature.Init(false, publicKey); + + byte[] encoded = req.TbsRequest.GetEncoded(); + + signature.BlockUpdate(encoded, 0, encoded.Length); + + return signature.VerifySignature(this.GetSignature()); + } + catch (Exception e) + { + throw new OcspException("exception processing sig: " + e, e); + } + } + + /** + * return the ASN.1 encoded representation of this object. + */ + public byte[] GetEncoded() + { + return req.GetEncoded(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/OCSPReq.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/OCSPReq.cs.meta new file mode 100644 index 0000000..b434e62 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/OCSPReq.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 38296b994b28d78419cc1dc0a150753a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/OCSPReqGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/OCSPReqGenerator.cs new file mode 100644 index 0000000..8032a45 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/OCSPReqGenerator.cs @@ -0,0 +1,243 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Ocsp; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Security.Certificates; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.Ocsp +{ + public class OcspReqGenerator + { + private IList list = Platform.CreateArrayList(); + private GeneralName requestorName = null; + private X509Extensions requestExtensions = null; + + private class RequestObject + { + internal CertificateID certId; + internal X509Extensions extensions; + + public RequestObject( + CertificateID certId, + X509Extensions extensions) + { + this.certId = certId; + this.extensions = extensions; + } + + public Request ToRequest() + { + return new Request(certId.ToAsn1Object(), extensions); + } + } + + /** + * Add a request for the given CertificateID. + * + * @param certId certificate ID of interest + */ + public void AddRequest( + CertificateID certId) + { + list.Add(new RequestObject(certId, null)); + } + + /** + * Add a request with extensions + * + * @param certId certificate ID of interest + * @param singleRequestExtensions the extensions to attach to the request + */ + public void AddRequest( + CertificateID certId, + X509Extensions singleRequestExtensions) + { + list.Add(new RequestObject(certId, singleRequestExtensions)); + } + + /** + * Set the requestor name to the passed in X509Principal + * + * @param requestorName a X509Principal representing the requestor name. + */ + public void SetRequestorName( + X509Name requestorName) + { + try + { + this.requestorName = new GeneralName(GeneralName.DirectoryName, requestorName); + } + catch (Exception e) + { + throw new ArgumentException("cannot encode principal", e); + } + } + + public void SetRequestorName( + GeneralName requestorName) + { + this.requestorName = requestorName; + } + + public void SetRequestExtensions( + X509Extensions requestExtensions) + { + this.requestExtensions = requestExtensions; + } + + private OcspReq GenerateRequest( + DerObjectIdentifier signingAlgorithm, + AsymmetricKeyParameter privateKey, + X509Certificate[] chain, + SecureRandom random) + { + Asn1EncodableVector requests = new Asn1EncodableVector(); + + foreach (RequestObject reqObj in list) + { + try + { + requests.Add(reqObj.ToRequest()); + } + catch (Exception e) + { + throw new OcspException("exception creating Request", e); + } + } + + TbsRequest tbsReq = new TbsRequest(requestorName, new DerSequence(requests), requestExtensions); + + ISigner sig = null; + Signature signature = null; + + if (signingAlgorithm != null) + { + if (requestorName == null) + { + throw new OcspException("requestorName must be specified if request is signed."); + } + + try + { + sig = SignerUtilities.GetSigner(signingAlgorithm.Id); + if (random != null) + { + sig.Init(true, new ParametersWithRandom(privateKey, random)); + } + else + { + sig.Init(true, privateKey); + } + } + catch (Exception e) + { + throw new OcspException("exception creating signature: " + e, e); + } + + DerBitString bitSig = null; + + try + { + byte[] encoded = tbsReq.GetEncoded(); + sig.BlockUpdate(encoded, 0, encoded.Length); + + bitSig = new DerBitString(sig.GenerateSignature()); + } + catch (Exception e) + { + throw new OcspException("exception processing TBSRequest: " + e, e); + } + + AlgorithmIdentifier sigAlgId = new AlgorithmIdentifier(signingAlgorithm, DerNull.Instance); + + if (chain != null && chain.Length > 0) + { + Asn1EncodableVector v = new Asn1EncodableVector(); + try + { + for (int i = 0; i != chain.Length; i++) + { + v.Add( + X509CertificateStructure.GetInstance( + Asn1Object.FromByteArray(chain[i].GetEncoded()))); + } + } + catch (IOException e) + { + throw new OcspException("error processing certs", e); + } + catch (CertificateEncodingException e) + { + throw new OcspException("error encoding certs", e); + } + + signature = new Signature(sigAlgId, bitSig, new DerSequence(v)); + } + else + { + signature = new Signature(sigAlgId, bitSig); + } + } + + return new OcspReq(new OcspRequest(tbsReq, signature)); + } + + /** + * Generate an unsigned request + * + * @return the OcspReq + * @throws OcspException + */ + public OcspReq Generate() + { + return GenerateRequest(null, null, null, null); + } + + public OcspReq Generate( + string signingAlgorithm, + AsymmetricKeyParameter privateKey, + X509Certificate[] chain) + { + return Generate(signingAlgorithm, privateKey, chain, null); + } + + public OcspReq Generate( + string signingAlgorithm, + AsymmetricKeyParameter privateKey, + X509Certificate[] chain, + SecureRandom random) + { + if (signingAlgorithm == null) + throw new ArgumentException("no signing algorithm specified"); + + try + { + DerObjectIdentifier oid = OcspUtilities.GetAlgorithmOid(signingAlgorithm); + + return GenerateRequest(oid, privateKey, chain, random); + } + catch (ArgumentException) + { + throw new ArgumentException("unknown signing algorithm specified: " + signingAlgorithm); + } + } + + /** + * Return an IEnumerable of the signature names supported by the generator. + * + * @return an IEnumerable containing recognised names. + */ + public IEnumerable SignatureAlgNames + { + get { return OcspUtilities.AlgNames; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/OCSPReqGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/OCSPReqGenerator.cs.meta new file mode 100644 index 0000000..a5329f3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/OCSPReqGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 28d79a54454578f4c991236c2830aea1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/OCSPResp.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/OCSPResp.cs new file mode 100644 index 0000000..1e65b2f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/OCSPResp.cs @@ -0,0 +1,100 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Ocsp; + +namespace Org.BouncyCastle.Ocsp +{ + public class OcspResp + { + private OcspResponse resp; + + public OcspResp( + OcspResponse resp) + { + this.resp = resp; + } + + public OcspResp( + byte[] resp) + : this(new Asn1InputStream(resp)) + { + } + + public OcspResp( + Stream inStr) + : this(new Asn1InputStream(inStr)) + { + } + + private OcspResp( + Asn1InputStream aIn) + { + try + { + this.resp = OcspResponse.GetInstance(aIn.ReadObject()); + } + catch (Exception e) + { + throw new IOException("malformed response: " + e.Message, e); + } + } + + public int Status + { + get { return this.resp.ResponseStatus.IntValueExact; } + } + + public object GetResponseObject() + { + ResponseBytes rb = this.resp.ResponseBytes; + + if (rb == null) + return null; + + if (rb.ResponseType.Equals(OcspObjectIdentifiers.PkixOcspBasic)) + { + try + { + return new BasicOcspResp( + BasicOcspResponse.GetInstance( + Asn1Object.FromByteArray(rb.Response.GetOctets()))); + } + catch (Exception e) + { + throw new OcspException("problem decoding object: " + e, e); + } + } + + return rb.Response; + } + + /** + * return the ASN.1 encoded representation of this object. + */ + public byte[] GetEncoded() + { + return resp.GetEncoded(); + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + OcspResp other = obj as OcspResp; + + if (other == null) + return false; + + return resp.Equals(other.resp); + } + + public override int GetHashCode() + { + return resp.GetHashCode(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/OCSPResp.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/OCSPResp.cs.meta new file mode 100644 index 0000000..17742dc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/OCSPResp.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5da6b58552d677e498561029bae345ad +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/OCSPRespGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/OCSPRespGenerator.cs new file mode 100644 index 0000000..e0eb9ae --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/OCSPRespGenerator.cs @@ -0,0 +1,54 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Ocsp; + +namespace Org.BouncyCastle.Ocsp +{ + /** + * base generator for an OCSP response - at the moment this only supports the + * generation of responses containing BasicOCSP responses. + */ + public class OCSPRespGenerator + { + public const int Successful = 0; // Response has valid confirmations + public const int MalformedRequest = 1; // Illegal confirmation request + public const int InternalError = 2; // Internal error in issuer + public const int TryLater = 3; // Try again later + // (4) is not used + public const int SigRequired = 5; // Must sign the request + public const int Unauthorized = 6; // Request unauthorized + + public OcspResp Generate( + int status, + object response) + { + if (response == null) + { + return new OcspResp(new OcspResponse(new OcspResponseStatus(status),null)); + } + if (response is BasicOcspResp) + { + BasicOcspResp r = (BasicOcspResp)response; + Asn1OctetString octs; + + try + { + octs = new DerOctetString(r.GetEncoded()); + } + catch (Exception e) + { + throw new OcspException("can't encode object.", e); + } + + ResponseBytes rb = new ResponseBytes( + OcspObjectIdentifiers.PkixOcspBasic, octs); + + return new OcspResp(new OcspResponse( + new OcspResponseStatus(status), rb)); + } + + throw new OcspException("unknown response object"); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/OCSPRespGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/OCSPRespGenerator.cs.meta new file mode 100644 index 0000000..a0f9dd1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/OCSPRespGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a13a6a9ae12d4d841b656794f5e76079 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/OCSPRespStatus.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/OCSPRespStatus.cs new file mode 100644 index 0000000..9c00c70 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/OCSPRespStatus.cs @@ -0,0 +1,22 @@ +using System; + +namespace Org.BouncyCastle.Ocsp +{ + [Obsolete("Use version with correct spelling 'OcspRespStatus'")] + public abstract class OcscpRespStatus : OcspRespStatus + { + } + + public abstract class OcspRespStatus + { + /** + * note 4 is not used. + */ + public const int Successful = 0; // --Response has valid confirmations + public const int MalformedRequest = 1; // --Illegal confirmation request + public const int InternalError = 2; // --Internal error in issuer + public const int TryLater = 3; // --Try again later + public const int SigRequired = 5; // --Must sign the request + public const int Unauthorized = 6; // --Request unauthorized + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/OCSPRespStatus.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/OCSPRespStatus.cs.meta new file mode 100644 index 0000000..8f35d6b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/OCSPRespStatus.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 02c637386d103a447b963aef3fe120b8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/OCSPUtil.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/OCSPUtil.cs new file mode 100644 index 0000000..e45b31b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/OCSPUtil.cs @@ -0,0 +1,157 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Oiw; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.TeleTrust; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Ocsp +{ + class OcspUtilities + { + private static readonly IDictionary algorithms = Platform.CreateHashtable(); + private static readonly IDictionary oids = Platform.CreateHashtable(); + private static readonly ISet noParams = new HashSet(); + + static OcspUtilities() + { + algorithms.Add("MD2WITHRSAENCRYPTION", PkcsObjectIdentifiers.MD2WithRsaEncryption); + algorithms.Add("MD2WITHRSA", PkcsObjectIdentifiers.MD2WithRsaEncryption); + algorithms.Add("MD5WITHRSAENCRYPTION", PkcsObjectIdentifiers.MD5WithRsaEncryption); + algorithms.Add("MD5WITHRSA", PkcsObjectIdentifiers.MD5WithRsaEncryption); + algorithms.Add("SHA1WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha1WithRsaEncryption); + algorithms.Add("SHA-1WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha1WithRsaEncryption); + algorithms.Add("SHA1WITHRSA", PkcsObjectIdentifiers.Sha1WithRsaEncryption); + algorithms.Add("SHA-1WITHRSA", PkcsObjectIdentifiers.Sha1WithRsaEncryption); + algorithms.Add("SHA224WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha224WithRsaEncryption); + algorithms.Add("SHA-224WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha224WithRsaEncryption); + algorithms.Add("SHA224WITHRSA", PkcsObjectIdentifiers.Sha224WithRsaEncryption); + algorithms.Add("SHA-224WITHRSA", PkcsObjectIdentifiers.Sha224WithRsaEncryption); + algorithms.Add("SHA256WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha256WithRsaEncryption); + algorithms.Add("SHA-256WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha256WithRsaEncryption); + algorithms.Add("SHA256WITHRSA", PkcsObjectIdentifiers.Sha256WithRsaEncryption); + algorithms.Add("SHA-256WITHRSA", PkcsObjectIdentifiers.Sha256WithRsaEncryption); + algorithms.Add("SHA384WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha384WithRsaEncryption); + algorithms.Add("SHA-384WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha384WithRsaEncryption); + algorithms.Add("SHA384WITHRSA", PkcsObjectIdentifiers.Sha384WithRsaEncryption); + algorithms.Add("SHA-384WITHRSA", PkcsObjectIdentifiers.Sha384WithRsaEncryption); + algorithms.Add("SHA512WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha512WithRsaEncryption); + algorithms.Add("SHA-512WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha512WithRsaEncryption); + algorithms.Add("SHA512WITHRSA", PkcsObjectIdentifiers.Sha512WithRsaEncryption); + algorithms.Add("SHA-512WITHRSA", PkcsObjectIdentifiers.Sha512WithRsaEncryption); + algorithms.Add("SHA512(224)WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha512_224WithRSAEncryption); + algorithms.Add("SHA-512(224)WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha512_224WithRSAEncryption); + algorithms.Add("SHA512(224)WITHRSA", PkcsObjectIdentifiers.Sha512_224WithRSAEncryption); + algorithms.Add("SHA-512(224)WITHRSA", PkcsObjectIdentifiers.Sha512_224WithRSAEncryption); + algorithms.Add("SHA512(256)WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha512_256WithRSAEncryption); + algorithms.Add("SHA-512(256)WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha512_256WithRSAEncryption); + algorithms.Add("SHA512(256)WITHRSA", PkcsObjectIdentifiers.Sha512_256WithRSAEncryption); + algorithms.Add("SHA-512(256)WITHRSA", PkcsObjectIdentifiers.Sha512_256WithRSAEncryption); + algorithms.Add("RIPEMD160WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160); + algorithms.Add("RIPEMD160WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160); + algorithms.Add("RIPEMD128WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128); + algorithms.Add("RIPEMD128WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128); + algorithms.Add("RIPEMD256WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256); + algorithms.Add("RIPEMD256WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256); + algorithms.Add("SHA1WITHDSA", X9ObjectIdentifiers.IdDsaWithSha1); + algorithms.Add("DSAWITHSHA1", X9ObjectIdentifiers.IdDsaWithSha1); + algorithms.Add("SHA224WITHDSA", NistObjectIdentifiers.DsaWithSha224); + algorithms.Add("SHA256WITHDSA", NistObjectIdentifiers.DsaWithSha256); + algorithms.Add("SHA1WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha1); + algorithms.Add("ECDSAWITHSHA1", X9ObjectIdentifiers.ECDsaWithSha1); + algorithms.Add("SHA224WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha224); + algorithms.Add("SHA256WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha256); + algorithms.Add("SHA384WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha384); + algorithms.Add("SHA512WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha512); + algorithms.Add("GOST3411WITHGOST3410", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94); + algorithms.Add("GOST3411WITHGOST3410-94", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94); + + oids.Add(PkcsObjectIdentifiers.MD2WithRsaEncryption, "MD2WITHRSA"); + oids.Add(PkcsObjectIdentifiers.MD5WithRsaEncryption, "MD5WITHRSA"); + oids.Add(PkcsObjectIdentifiers.Sha1WithRsaEncryption, "SHA1WITHRSA"); + oids.Add(PkcsObjectIdentifiers.Sha224WithRsaEncryption, "SHA224WITHRSA"); + oids.Add(PkcsObjectIdentifiers.Sha256WithRsaEncryption, "SHA256WITHRSA"); + oids.Add(PkcsObjectIdentifiers.Sha384WithRsaEncryption, "SHA384WITHRSA"); + oids.Add(PkcsObjectIdentifiers.Sha512WithRsaEncryption, "SHA512WITHRSA"); + oids.Add(PkcsObjectIdentifiers.Sha512_224WithRSAEncryption, "SHA512(224)WITHRSA"); + oids.Add(PkcsObjectIdentifiers.Sha512_256WithRSAEncryption, "SHA512(256)WITHRSA"); + oids.Add(TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160, "RIPEMD160WITHRSA"); + oids.Add(TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128, "RIPEMD128WITHRSA"); + oids.Add(TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256, "RIPEMD256WITHRSA"); + oids.Add(X9ObjectIdentifiers.IdDsaWithSha1, "SHA1WITHDSA"); + oids.Add(NistObjectIdentifiers.DsaWithSha224, "SHA224WITHDSA"); + oids.Add(NistObjectIdentifiers.DsaWithSha256, "SHA256WITHDSA"); + oids.Add(X9ObjectIdentifiers.ECDsaWithSha1, "SHA1WITHECDSA"); + oids.Add(X9ObjectIdentifiers.ECDsaWithSha224, "SHA224WITHECDSA"); + oids.Add(X9ObjectIdentifiers.ECDsaWithSha256, "SHA256WITHECDSA"); + oids.Add(X9ObjectIdentifiers.ECDsaWithSha384, "SHA384WITHECDSA"); + oids.Add(X9ObjectIdentifiers.ECDsaWithSha512, "SHA512WITHECDSA"); + oids.Add(CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94, "GOST3411WITHGOST3410"); + oids.Add(OiwObjectIdentifiers.MD5WithRsa, "MD5WITHRSA"); + oids.Add(OiwObjectIdentifiers.Sha1WithRsa, "SHA1WITHRSA"); + oids.Add(OiwObjectIdentifiers.DsaWithSha1, "SHA1WITHDSA"); + + // + // According to RFC 3279, the ASN.1 encoding SHALL (id-dsa-with-sha1) or MUST (ecdsa-with-SHA*) omit the parameters field. + // The parameters field SHALL be NULL for RSA based signature algorithms. + // + noParams.Add(X9ObjectIdentifiers.ECDsaWithSha1); + noParams.Add(X9ObjectIdentifiers.ECDsaWithSha224); + noParams.Add(X9ObjectIdentifiers.ECDsaWithSha256); + noParams.Add(X9ObjectIdentifiers.ECDsaWithSha384); + noParams.Add(X9ObjectIdentifiers.ECDsaWithSha512); + noParams.Add(X9ObjectIdentifiers.IdDsaWithSha1); + noParams.Add(OiwObjectIdentifiers.DsaWithSha1); + noParams.Add(NistObjectIdentifiers.DsaWithSha224); + noParams.Add(NistObjectIdentifiers.DsaWithSha256); + } + + internal static DerObjectIdentifier GetAlgorithmOid( + string algorithmName) + { + algorithmName = Platform.ToUpperInvariant(algorithmName); + + if (algorithms.Contains(algorithmName)) + { + return (DerObjectIdentifier)algorithms[algorithmName]; + } + + return new DerObjectIdentifier(algorithmName); + } + + + internal static string GetAlgorithmName( + DerObjectIdentifier oid) + { + if (oids.Contains(oid)) + { + return (string)oids[oid]; + } + + return oid.Id; + } + + internal static AlgorithmIdentifier GetSigAlgID( + DerObjectIdentifier sigOid) + { + if (noParams.Contains(sigOid)) + { + return new AlgorithmIdentifier(sigOid); + } + + return new AlgorithmIdentifier(sigOid, DerNull.Instance); + } + + internal static IEnumerable AlgNames + { + get { return new EnumerableProxy(algorithms.Keys); } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/OCSPUtil.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/OCSPUtil.cs.meta new file mode 100644 index 0000000..35efa1c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/OCSPUtil.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 988d0e34ac2471a46b79b86312061c9c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/Req.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/Req.cs new file mode 100644 index 0000000..68fd9f1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/Req.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Ocsp; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.Ocsp +{ + public class Req + : X509ExtensionBase + { + private Request req; + + public Req( + Request req) + { + this.req = req; + } + + public CertificateID GetCertID() + { + return new CertificateID(req.ReqCert); + } + + public X509Extensions SingleRequestExtensions + { + get { return req.SingleRequestExtensions; } + } + + protected override X509Extensions GetX509Extensions() + { + return SingleRequestExtensions; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/Req.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/Req.cs.meta new file mode 100644 index 0000000..0feefd8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/Req.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 07a64f1d3c5688449b19f8c858d52d08 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/RespData.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/RespData.cs new file mode 100644 index 0000000..7ec0e4b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/RespData.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Ocsp; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.Ocsp +{ + public class RespData + : X509ExtensionBase + { + internal readonly ResponseData data; + + public RespData( + ResponseData data) + { + this.data = data; + } + + public int Version + { + get { return data.Version.IntValueExact + 1; } + } + + public RespID GetResponderId() + { + return new RespID(data.ResponderID); + } + + public DateTime ProducedAt + { + get { return data.ProducedAt.ToDateTime(); } + } + + public SingleResp[] GetResponses() + { + Asn1Sequence s = data.Responses; + SingleResp[] rs = new SingleResp[s.Count]; + + for (int i = 0; i != rs.Length; i++) + { + rs[i] = new SingleResp(SingleResponse.GetInstance(s[i])); + } + + return rs; + } + + public X509Extensions ResponseExtensions + { + get { return data.ResponseExtensions; } + } + + protected override X509Extensions GetX509Extensions() + { + return ResponseExtensions; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/RespData.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/RespData.cs.meta new file mode 100644 index 0000000..2c9519a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/RespData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: af8938296cc095240931696bce6da4fc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/RespID.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/RespID.cs new file mode 100644 index 0000000..3238b26 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/RespID.cs @@ -0,0 +1,72 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Ocsp; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.Ocsp +{ + /** + * Carrier for a ResponderID. + */ + public class RespID + { + internal readonly ResponderID id; + + public RespID( + ResponderID id) + { + this.id = id; + } + + public RespID( + X509Name name) + { + this.id = new ResponderID(name); + } + + public RespID( + AsymmetricKeyParameter publicKey) + { + try + { + SubjectPublicKeyInfo info = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(publicKey); + + byte[] keyHash = DigestUtilities.CalculateDigest("SHA1", info.PublicKeyData.GetBytes()); + + this.id = new ResponderID(new DerOctetString(keyHash)); + } + catch (Exception e) + { + throw new OcspException("problem creating ID: " + e, e); + } + } + + public ResponderID ToAsn1Object() + { + return id; + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + RespID other = obj as RespID; + + if (other == null) + return false; + + return id.Equals(other.id); + } + + public override int GetHashCode() + { + return id.GetHashCode(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/RespID.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/RespID.cs.meta new file mode 100644 index 0000000..7f21e14 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/RespID.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 937e2e6d379015543a881d1c06b4cfff +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/RevokedStatus.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/RevokedStatus.cs new file mode 100644 index 0000000..edbeb57 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/RevokedStatus.cs @@ -0,0 +1,58 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Ocsp; +using Org.BouncyCastle.Asn1.X509; + +namespace Org.BouncyCastle.Ocsp +{ + /** + * wrapper for the RevokedInfo object + */ + public class RevokedStatus + : CertificateStatus + { + internal readonly RevokedInfo info; + + public RevokedStatus( + RevokedInfo info) + { + this.info = info; + } + + public RevokedStatus( + DateTime revocationDate, + int reason) + { + this.info = new RevokedInfo(new DerGeneralizedTime(revocationDate), new CrlReason(reason)); + } + + public DateTime RevocationTime + { + get { return info.RevocationTime.ToDateTime(); } + } + + public bool HasRevocationReason + { + get { return (info.RevocationReason != null); } + } + + /** + * return the revocation reason. Note: this field is optional, test for it + * with hasRevocationReason() first. + * @exception InvalidOperationException if a reason is asked for and none is avaliable + */ + public int RevocationReason + { + get + { + if (info.RevocationReason == null) + { + throw new InvalidOperationException("attempt to get a reason where none is available"); + } + + return info.RevocationReason.IntValueExact; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/RevokedStatus.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/RevokedStatus.cs.meta new file mode 100644 index 0000000..90b45b6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/RevokedStatus.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 37fc3d831623f9f439be045cf18ccb9b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/SingleResp.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/SingleResp.cs new file mode 100644 index 0000000..b8979c5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/SingleResp.cs @@ -0,0 +1,81 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Ocsp; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities.Date; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.Ocsp +{ + public class SingleResp + : X509ExtensionBase + { + internal readonly SingleResponse resp; + + public SingleResp( + SingleResponse resp) + { + this.resp = resp; + } + + public CertificateID GetCertID() + { + return new CertificateID(resp.CertId); + } + + /** + * Return the status object for the response - null indicates good. + * + * @return the status object for the response, null if it is good. + */ + public object GetCertStatus() + { + CertStatus s = resp.CertStatus; + + if (s.TagNo == 0) + { + return null; // good + } + + if (s.TagNo == 1) + { + return new RevokedStatus(RevokedInfo.GetInstance(s.Status)); + } + + return new UnknownStatus(); + } + + public DateTime ThisUpdate + { + get { return resp.ThisUpdate.ToDateTime(); } + } + + /** + * return the NextUpdate value - note: this is an optional field so may + * be returned as null. + * + * @return nextUpdate, or null if not present. + */ + public DateTimeObject NextUpdate + { + get + { + return resp.NextUpdate == null + ? null + : new DateTimeObject(resp.NextUpdate.ToDateTime()); + } + } + + public X509Extensions SingleExtensions + { + get { return resp.SingleExtensions; } + } + + protected override X509Extensions GetX509Extensions() + { + return SingleExtensions; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/SingleResp.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/SingleResp.cs.meta new file mode 100644 index 0000000..416ec78 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/SingleResp.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 04a45dbb83128ff4294ce227ff0cfb75 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/UnknownStatus.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/UnknownStatus.cs new file mode 100644 index 0000000..c0f7a3a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/UnknownStatus.cs @@ -0,0 +1,15 @@ +using System; + +namespace Org.BouncyCastle.Ocsp +{ + /** + * wrapper for the UnknownInfo object + */ + public class UnknownStatus + : CertificateStatus + { + public UnknownStatus() + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/UnknownStatus.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/UnknownStatus.cs.meta new file mode 100644 index 0000000..4007629 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/ocsp/UnknownStatus.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fc80d09d892ce6d4987313e9b160be03 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp.meta new file mode 100644 index 0000000..2cd3297 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 89e5d8ea03583804996ffe60166ee7ab +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/IStreamGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/IStreamGenerator.cs new file mode 100644 index 0000000..379213a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/IStreamGenerator.cs @@ -0,0 +1,7 @@ +namespace Org.BouncyCastle.Bcpg.OpenPgp +{ + public interface IStreamGenerator + { + void Close(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/IStreamGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/IStreamGenerator.cs.meta new file mode 100644 index 0000000..65a7706 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/IStreamGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2c566df51a1d45d4cabfbb2569810174 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PGPKeyRing.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PGPKeyRing.cs new file mode 100644 index 0000000..9d9454f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PGPKeyRing.cs @@ -0,0 +1,81 @@ +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Bcpg.OpenPgp +{ + public abstract class PgpKeyRing + : PgpObject + { + internal PgpKeyRing() + { + } + + internal static TrustPacket ReadOptionalTrustPacket(BcpgInputStream pIn) + { + PacketTag tag = pIn.SkipMarkerPackets(); + + return tag == PacketTag.Trust ? (TrustPacket)pIn.ReadPacket() : null; + } + + internal static IList ReadSignaturesAndTrust(BcpgInputStream pIn) + { + try + { + IList sigList = Platform.CreateArrayList(); + + while (pIn.SkipMarkerPackets() == PacketTag.Signature) + { + SignaturePacket signaturePacket = (SignaturePacket)pIn.ReadPacket(); + TrustPacket trustPacket = ReadOptionalTrustPacket(pIn); + + sigList.Add(new PgpSignature(signaturePacket, trustPacket)); + } + + return sigList; + } + catch (PgpException e) + { + throw new IOException("can't create signature object: " + e.Message, e); + } + } + + internal static void ReadUserIDs(BcpgInputStream pIn, out IList ids, out IList idTrusts, out IList idSigs) + { + ids = Platform.CreateArrayList(); + idTrusts = Platform.CreateArrayList(); + idSigs = Platform.CreateArrayList(); + + while (IsUserTag(pIn.SkipMarkerPackets())) + { + Packet obj = pIn.ReadPacket(); + if (obj is UserIdPacket) + { + UserIdPacket id = (UserIdPacket)obj; + ids.Add(id.GetId()); + } + else + { + UserAttributePacket user = (UserAttributePacket)obj; + ids.Add(new PgpUserAttributeSubpacketVector(user.GetSubpackets())); + } + + idTrusts.Add(ReadOptionalTrustPacket(pIn)); + idSigs.Add(ReadSignaturesAndTrust(pIn)); + } + } + + private static bool IsUserTag(PacketTag tag) + { + switch (tag) + { + case PacketTag.UserAttribute: + case PacketTag.UserId: + return true; + default: + return false; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PGPKeyRing.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PGPKeyRing.cs.meta new file mode 100644 index 0000000..2ed07aa --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PGPKeyRing.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8ce3ef4d043157b45aeba632c038ba80 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PGPObject.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PGPObject.cs new file mode 100644 index 0000000..d38276c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PGPObject.cs @@ -0,0 +1,9 @@ +namespace Org.BouncyCastle.Bcpg.OpenPgp +{ + public abstract class PgpObject + { + internal PgpObject() + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PGPObject.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PGPObject.cs.meta new file mode 100644 index 0000000..f762de4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PGPObject.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bbfb92c127e2c324996a8fc77540a680 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PGPUserAttributeSubpacketVectorGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PGPUserAttributeSubpacketVectorGenerator.cs new file mode 100644 index 0000000..9d56c8b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PGPUserAttributeSubpacketVectorGenerator.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Bcpg.Attr; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Bcpg.OpenPgp +{ + public class PgpUserAttributeSubpacketVectorGenerator + { + private IList list = Platform.CreateArrayList(); + + public virtual void SetImageAttribute( + ImageAttrib.Format imageType, + byte[] imageData) + { + if (imageData == null) + throw new ArgumentException("attempt to set null image", "imageData"); + + list.Add(new ImageAttrib(imageType, imageData)); + } + + public virtual PgpUserAttributeSubpacketVector Generate() + { + UserAttributeSubpacket[] a = new UserAttributeSubpacket[list.Count]; + for (int i = 0; i < list.Count; ++i) + { + a[i] = (UserAttributeSubpacket)list[i]; + } + return new PgpUserAttributeSubpacketVector(a); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PGPUserAttributeSubpacketVectorGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PGPUserAttributeSubpacketVectorGenerator.cs.meta new file mode 100644 index 0000000..481ab16 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PGPUserAttributeSubpacketVectorGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b2a2d3e177b7dcb458e961b7be483d93 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpCompressedData.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpCompressedData.cs new file mode 100644 index 0000000..c841b74 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpCompressedData.cs @@ -0,0 +1,54 @@ +using System.IO; + +using Org.BouncyCastle.Apache.Bzip2; +using Org.BouncyCastle.Utilities.Zlib; + +namespace Org.BouncyCastle.Bcpg.OpenPgp +{ + /// Compressed data objects + public class PgpCompressedData + : PgpObject + { + private readonly CompressedDataPacket data; + + public PgpCompressedData( + BcpgInputStream bcpgInput) + { + Packet packet = bcpgInput.ReadPacket(); + if (!(packet is CompressedDataPacket)) + throw new IOException("unexpected packet in stream: " + packet); + + this.data = (CompressedDataPacket)packet; + } + + /// The algorithm used for compression + public CompressionAlgorithmTag Algorithm + { + get { return data.Algorithm; } + } + + /// Get the raw input stream contained in the object. + public Stream GetInputStream() + { + return data.GetInputStream(); + } + + /// Return an uncompressed input stream which allows reading of the compressed data. + public Stream GetDataStream() + { + switch (Algorithm) + { + case CompressionAlgorithmTag.Uncompressed: + return GetInputStream(); + case CompressionAlgorithmTag.Zip: + return new ZInputStream(GetInputStream(), true); + case CompressionAlgorithmTag.ZLib: + return new ZInputStream(GetInputStream()); + case CompressionAlgorithmTag.BZip2: + return new CBZip2InputStream(GetInputStream()); + default: + throw new PgpException("can't recognise compression algorithm: " + Algorithm); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpCompressedData.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpCompressedData.cs.meta new file mode 100644 index 0000000..5f8b91e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpCompressedData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bbbd3dc6831027b47b000a0ffff81bf3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpCompressedDataGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpCompressedDataGenerator.cs new file mode 100644 index 0000000..51b6452 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpCompressedDataGenerator.cs @@ -0,0 +1,221 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Apache.Bzip2; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Zlib; + +namespace Org.BouncyCastle.Bcpg.OpenPgp +{ + /// Class for producing compressed data packets. + public class PgpCompressedDataGenerator + : IStreamGenerator + { + private readonly CompressionAlgorithmTag algorithm; + private readonly int compression; + + private Stream dOut; + private BcpgOutputStream pkOut; + + public PgpCompressedDataGenerator( + CompressionAlgorithmTag algorithm) + : this(algorithm, JZlib.Z_DEFAULT_COMPRESSION) + { + } + + public PgpCompressedDataGenerator( + CompressionAlgorithmTag algorithm, + int compression) + { + switch (algorithm) + { + case CompressionAlgorithmTag.Uncompressed: + case CompressionAlgorithmTag.Zip: + case CompressionAlgorithmTag.ZLib: + case CompressionAlgorithmTag.BZip2: + break; + default: + throw new ArgumentException("unknown compression algorithm", "algorithm"); + } + + if (compression != JZlib.Z_DEFAULT_COMPRESSION) + { + if ((compression < JZlib.Z_NO_COMPRESSION) || (compression > JZlib.Z_BEST_COMPRESSION)) + { + throw new ArgumentException("unknown compression level: " + compression); + } + } + + this.algorithm = algorithm; + this.compression = compression; + } + + /// + ///

    + /// Return an output stream which will save the data being written to + /// the compressed object. + ///

    + ///

    + /// The stream created can be closed off by either calling Close() + /// on the stream or Close() on the generator. Closing the returned + /// stream does not close off the Stream parameter outStr. + ///

    + ///
    + /// Stream to be used for output. + /// A Stream for output of the compressed data. + /// + /// + /// + public Stream Open( + Stream outStr) + { + if (dOut != null) + throw new InvalidOperationException("generator already in open state"); + if (outStr == null) + throw new ArgumentNullException("outStr"); + + this.pkOut = new BcpgOutputStream(outStr, PacketTag.CompressedData); + + doOpen(); + + return new WrappedGeneratorStream(this, dOut); + } + + /// + ///

    + /// Return an output stream which will compress the data as it is written to it. + /// The stream will be written out in chunks according to the size of the passed in buffer. + ///

    + ///

    + /// The stream created can be closed off by either calling Close() + /// on the stream or Close() on the generator. Closing the returned + /// stream does not close off the Stream parameter outStr. + ///

    + ///

    + /// Note: if the buffer is not a power of 2 in length only the largest power of 2 + /// bytes worth of the buffer will be used. + ///

    + ///

    + /// Note: using this may break compatibility with RFC 1991 compliant tools. + /// Only recent OpenPGP implementations are capable of accepting these streams. + ///

    + ///
    + /// Stream to be used for output. + /// The buffer to use. + /// A Stream for output of the compressed data. + /// + /// + /// + /// + public Stream Open( + Stream outStr, + byte[] buffer) + { + if (dOut != null) + throw new InvalidOperationException("generator already in open state"); + if (outStr == null) + throw new ArgumentNullException("outStr"); + if (buffer == null) + throw new ArgumentNullException("buffer"); + + this.pkOut = new BcpgOutputStream(outStr, PacketTag.CompressedData, buffer); + + doOpen(); + + return new WrappedGeneratorStream(this, dOut); + } + + private void doOpen() + { + pkOut.WriteByte((byte) algorithm); + + switch (algorithm) + { + case CompressionAlgorithmTag.Uncompressed: + dOut = pkOut; + break; + case CompressionAlgorithmTag.Zip: + dOut = new SafeZOutputStream(pkOut, compression, true); + break; + case CompressionAlgorithmTag.ZLib: + dOut = new SafeZOutputStream(pkOut, compression, false); + break; + case CompressionAlgorithmTag.BZip2: + dOut = new SafeCBZip2OutputStream(pkOut); + break; + default: + // Constructor should guard against this possibility + throw new InvalidOperationException(); + } + } + + /// Close the compressed object.summary> + public void Close() + { + if (dOut != null) + { + if (dOut != pkOut) + { + Platform.Dispose(dOut); + } + dOut = null; + + pkOut.Finish(); + pkOut.Flush(); + pkOut = null; + } + } + + private class SafeCBZip2OutputStream : CBZip2OutputStream + { + public SafeCBZip2OutputStream(Stream output) + : base(output) + { + } + +#if PORTABLE + protected override void Dispose(bool disposing) + { + if (disposing) + { + Finish(); + return; + } + base.Dispose(disposing); + } +#else + public override void Close() + { + Finish(); + } +#endif + } + + private class SafeZOutputStream : ZOutputStream + { + public SafeZOutputStream(Stream output, int level, bool nowrap) + : base(output, level, nowrap) + { + } + +#if PORTABLE + protected override void Dispose(bool disposing) + { + if (disposing) + { + Finish(); + End(); + return; + } + base.Dispose(disposing); + } +#else + public override void Close() + { + Finish(); + End(); + } +#endif + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpCompressedDataGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpCompressedDataGenerator.cs.meta new file mode 100644 index 0000000..f97266b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpCompressedDataGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a36d82181f52cf543becf3e1dd99f58d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpDataValidationException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpDataValidationException.cs new file mode 100644 index 0000000..d06833c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpDataValidationException.cs @@ -0,0 +1,18 @@ +using System; + +namespace Org.BouncyCastle.Bcpg.OpenPgp +{ + /// + /// Thrown if the IV at the start of a data stream indicates the wrong key is being used. + /// +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE) + [Serializable] +#endif + public class PgpDataValidationException + : PgpException + { + public PgpDataValidationException() : base() {} + public PgpDataValidationException(string message) : base(message) {} + public PgpDataValidationException(string message, Exception exception) : base(message, exception) {} + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpDataValidationException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpDataValidationException.cs.meta new file mode 100644 index 0000000..9ee0a77 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpDataValidationException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 342efd8b973d1ec46bded877d32add33 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpEncryptedData.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpEncryptedData.cs new file mode 100644 index 0000000..558e0b8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpEncryptedData.cs @@ -0,0 +1,151 @@ +using System; +using System.Diagnostics; +using System.IO; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.IO; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Bcpg.OpenPgp +{ + public abstract class PgpEncryptedData + { + internal class TruncatedStream + : BaseInputStream + { + private const int LookAheadSize = 22; + private const int LookAheadBufSize = 512; + private const int LookAheadBufLimit = LookAheadBufSize - LookAheadSize; + + private readonly Stream inStr; + private readonly byte[] lookAhead = new byte[LookAheadBufSize]; + private int bufStart, bufEnd; + + internal TruncatedStream( + Stream inStr) + { + int numRead = Streams.ReadFully(inStr, lookAhead, 0, lookAhead.Length); + + if (numRead < LookAheadSize) + throw new EndOfStreamException(); + + this.inStr = inStr; + this.bufStart = 0; + this.bufEnd = numRead - LookAheadSize; + } + + private int FillBuffer() + { + if (bufEnd < LookAheadBufLimit) + return 0; + + Debug.Assert(bufStart == LookAheadBufLimit); + Debug.Assert(bufEnd == LookAheadBufLimit); + + Array.Copy(lookAhead, LookAheadBufLimit, lookAhead, 0, LookAheadSize); + bufEnd = Streams.ReadFully(inStr, lookAhead, LookAheadSize, LookAheadBufLimit); + bufStart = 0; + return bufEnd; + } + + public override int ReadByte() + { + if (bufStart < bufEnd) + return lookAhead[bufStart++]; + + if (FillBuffer() < 1) + return -1; + + return lookAhead[bufStart++]; + } + + public override int Read(byte[] buf, int off, int len) + { + int avail = bufEnd - bufStart; + + int pos = off; + while (len > avail) + { + Array.Copy(lookAhead, bufStart, buf, pos, avail); + + bufStart += avail; + pos += avail; + len -= avail; + + if ((avail = FillBuffer()) < 1) + return pos - off; + } + + Array.Copy(lookAhead, bufStart, buf, pos, len); + bufStart += len; + + return pos + len - off; + } + + internal byte[] GetLookAhead() + { + byte[] temp = new byte[LookAheadSize]; + Array.Copy(lookAhead, bufStart, temp, 0, LookAheadSize); + return temp; + } + } + + internal InputStreamPacket encData; + internal Stream encStream; + internal TruncatedStream truncStream; + + internal PgpEncryptedData( + InputStreamPacket encData) + { + this.encData = encData; + } + + /// Return the raw input stream for the data stream. + public virtual Stream GetInputStream() + { + return encData.GetInputStream(); + } + + /// Return true if the message is integrity protected. + /// True, if there is a modification detection code namespace associated + /// with this stream. + public bool IsIntegrityProtected() + { + return encData is SymmetricEncIntegrityPacket; + } + + /// Note: This can only be called after the message has been read. + /// True, if the message verifies, false otherwise + public bool Verify() + { + if (!IsIntegrityProtected()) + throw new PgpException("data not integrity protected."); + + DigestStream dIn = (DigestStream) encStream; + + // + // make sure we are at the end. + // + while (encStream.ReadByte() >= 0) + { + // do nothing + } + + // + // process the MDC packet + // + byte[] lookAhead = truncStream.GetLookAhead(); + + IDigest hash = dIn.ReadDigest(); + hash.BlockUpdate(lookAhead, 0, 2); + byte[] digest = DigestUtilities.DoFinal(hash); + + byte[] streamDigest = new byte[digest.Length]; + Array.Copy(lookAhead, 2, streamDigest, 0, streamDigest.Length); + + return Arrays.ConstantTimeAreEqual(digest, streamDigest); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpEncryptedData.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpEncryptedData.cs.meta new file mode 100644 index 0000000..8e53bcd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpEncryptedData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8e7e6b725cbb81b4ea7b4eaf02164aa1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpEncryptedDataGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpEncryptedDataGenerator.cs new file mode 100644 index 0000000..336baf0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpEncryptedDataGenerator.cs @@ -0,0 +1,604 @@ +using System; +using System.Collections; +using System.Diagnostics; +using System.IO; + +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.IO; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Bcpg.OpenPgp +{ + /// Generator for encrypted objects. + public class PgpEncryptedDataGenerator + : IStreamGenerator + { + private BcpgOutputStream pOut; + private CipherStream cOut; + private IBufferedCipher c; + private bool withIntegrityPacket; + private bool oldFormat; + private DigestStream digestOut; + + private abstract class EncMethod + : ContainedPacket + { + protected byte[] sessionInfo; + protected SymmetricKeyAlgorithmTag encAlgorithm; + protected KeyParameter key; + + public abstract void AddSessionInfo(byte[] si, SecureRandom random); + } + + private class PbeMethod + : EncMethod + { + private S2k s2k; + + internal PbeMethod( + SymmetricKeyAlgorithmTag encAlgorithm, + S2k s2k, + KeyParameter key) + { + this.encAlgorithm = encAlgorithm; + this.s2k = s2k; + this.key = key; + } + + public KeyParameter GetKey() + { + return key; + } + + public override void AddSessionInfo( + byte[] si, + SecureRandom random) + { + string cName = PgpUtilities.GetSymmetricCipherName(encAlgorithm); + IBufferedCipher c = CipherUtilities.GetCipher(cName + "/CFB/NoPadding"); + + byte[] iv = new byte[c.GetBlockSize()]; + c.Init(true, new ParametersWithRandom(new ParametersWithIV(key, iv), random)); + + this.sessionInfo = c.DoFinal(si, 0, si.Length - 2); + } + + public override void Encode(BcpgOutputStream pOut) + { + SymmetricKeyEncSessionPacket pk = new SymmetricKeyEncSessionPacket( + encAlgorithm, s2k, sessionInfo); + + pOut.WritePacket(pk); + } + } + + private class PubMethod + : EncMethod + { + internal PgpPublicKey pubKey; + internal bool sessionKeyObfuscation; + internal byte[][] data; + + internal PubMethod(PgpPublicKey pubKey, bool sessionKeyObfuscation) + { + this.pubKey = pubKey; + this.sessionKeyObfuscation = sessionKeyObfuscation; + } + + public override void AddSessionInfo( + byte[] sessionInfo, + SecureRandom random) + { + byte[] encryptedSessionInfo = EncryptSessionInfo(sessionInfo, random); + + this.data = ProcessSessionInfo(encryptedSessionInfo); + } + + private byte[] EncryptSessionInfo(byte[] sessionInfo, SecureRandom random) + { + if (pubKey.Algorithm != PublicKeyAlgorithmTag.ECDH) + { + IBufferedCipher c; + switch (pubKey.Algorithm) + { + case PublicKeyAlgorithmTag.RsaEncrypt: + case PublicKeyAlgorithmTag.RsaGeneral: + c = CipherUtilities.GetCipher("RSA//PKCS1Padding"); + break; + case PublicKeyAlgorithmTag.ElGamalEncrypt: + case PublicKeyAlgorithmTag.ElGamalGeneral: + c = CipherUtilities.GetCipher("ElGamal/ECB/PKCS1Padding"); + break; + case PublicKeyAlgorithmTag.Dsa: + throw new PgpException("Can't use DSA for encryption."); + case PublicKeyAlgorithmTag.ECDsa: + throw new PgpException("Can't use ECDSA for encryption."); + default: + throw new PgpException("unknown asymmetric algorithm: " + pubKey.Algorithm); + } + + AsymmetricKeyParameter akp = pubKey.GetKey(); + c.Init(true, new ParametersWithRandom(akp, random)); + return c.DoFinal(sessionInfo); + } + + ECDHPublicBcpgKey ecKey = (ECDHPublicBcpgKey)pubKey.PublicKeyPacket.Key; + + // Generate the ephemeral key pair + IAsymmetricCipherKeyPairGenerator gen = GeneratorUtilities.GetKeyPairGenerator("ECDH"); + gen.Init(new ECKeyGenerationParameters(ecKey.CurveOid, random)); + + AsymmetricCipherKeyPair ephKp = gen.GenerateKeyPair(); + ECPrivateKeyParameters ephPriv = (ECPrivateKeyParameters)ephKp.Private; + ECPublicKeyParameters ephPub = (ECPublicKeyParameters)ephKp.Public; + + ECPublicKeyParameters pub = (ECPublicKeyParameters)pubKey.GetKey(); + ECPoint S = pub.Q.Multiply(ephPriv.D).Normalize(); + + KeyParameter key = new KeyParameter(Rfc6637Utilities.CreateKey(pubKey.PublicKeyPacket, S)); + + IWrapper w = PgpUtilities.CreateWrapper(ecKey.SymmetricKeyAlgorithm); + w.Init(true, new ParametersWithRandom(key, random)); + + byte[] paddedSessionData = PgpPad.PadSessionData(sessionInfo, sessionKeyObfuscation); + + byte[] C = w.Wrap(paddedSessionData, 0, paddedSessionData.Length); + byte[] VB = new MPInteger(new BigInteger(1, ephPub.Q.GetEncoded(false))).GetEncoded(); + + byte[] rv = new byte[VB.Length + 1 + C.Length]; + + Array.Copy(VB, 0, rv, 0, VB.Length); + rv[VB.Length] = (byte)C.Length; + Array.Copy(C, 0, rv, VB.Length + 1, C.Length); + + return rv; + } + + private byte[][] ProcessSessionInfo(byte[] encryptedSessionInfo) + { + byte[][] data; + + switch (pubKey.Algorithm) + { + case PublicKeyAlgorithmTag.RsaEncrypt: + case PublicKeyAlgorithmTag.RsaGeneral: + data = new byte[][] { ConvertToEncodedMpi(encryptedSessionInfo) }; + break; + case PublicKeyAlgorithmTag.ElGamalEncrypt: + case PublicKeyAlgorithmTag.ElGamalGeneral: + int halfLength = encryptedSessionInfo.Length / 2; + byte[] b1 = new byte[halfLength]; + byte[] b2 = new byte[halfLength]; + + Array.Copy(encryptedSessionInfo, 0, b1, 0, halfLength); + Array.Copy(encryptedSessionInfo, halfLength, b2, 0, halfLength); + + data = new byte[][] { + ConvertToEncodedMpi(b1), + ConvertToEncodedMpi(b2), + }; + break; + case PublicKeyAlgorithmTag.ECDH: + data = new byte[][]{ encryptedSessionInfo }; + break; + default: + throw new PgpException("unknown asymmetric algorithm: " + pubKey.Algorithm); + } + + return data; + } + + private byte[] ConvertToEncodedMpi(byte[] encryptedSessionInfo) + { + try + { + return new MPInteger(new BigInteger(1, encryptedSessionInfo)).GetEncoded(); + } + catch (IOException e) + { + throw new PgpException("Invalid MPI encoding: " + e.Message, e); + } + } + + public override void Encode(BcpgOutputStream pOut) + { + PublicKeyEncSessionPacket pk = new PublicKeyEncSessionPacket(pubKey.KeyId, pubKey.Algorithm, data); + + pOut.WritePacket(pk); + } + } + + private readonly IList methods = Platform.CreateArrayList(); + private readonly SymmetricKeyAlgorithmTag defAlgorithm; + private readonly SecureRandom rand; + + public PgpEncryptedDataGenerator( + SymmetricKeyAlgorithmTag encAlgorithm) + { + this.defAlgorithm = encAlgorithm; + this.rand = new SecureRandom(); + } + + public PgpEncryptedDataGenerator( + SymmetricKeyAlgorithmTag encAlgorithm, + bool withIntegrityPacket) + { + this.defAlgorithm = encAlgorithm; + this.withIntegrityPacket = withIntegrityPacket; + this.rand = new SecureRandom(); + } + + /// Existing SecureRandom constructor. + /// The symmetric algorithm to use. + /// Source of randomness. + public PgpEncryptedDataGenerator( + SymmetricKeyAlgorithmTag encAlgorithm, + SecureRandom rand) + { + this.defAlgorithm = encAlgorithm; + this.rand = rand; + } + + /// Creates a cipher stream which will have an integrity packet associated with it. + public PgpEncryptedDataGenerator( + SymmetricKeyAlgorithmTag encAlgorithm, + bool withIntegrityPacket, + SecureRandom rand) + { + this.defAlgorithm = encAlgorithm; + this.rand = rand; + this.withIntegrityPacket = withIntegrityPacket; + } + + /// Base constructor. + /// The symmetric algorithm to use. + /// Source of randomness. + /// PGP 2.6.x compatibility required. + public PgpEncryptedDataGenerator( + SymmetricKeyAlgorithmTag encAlgorithm, + SecureRandom rand, + bool oldFormat) + { + this.defAlgorithm = encAlgorithm; + this.rand = rand; + this.oldFormat = oldFormat; + } + + /// + /// Add a PBE encryption method to the encrypted object using the default algorithm (S2K_SHA1). + /// + /// + /// Conversion of the passphrase characters to bytes is performed using Convert.ToByte(), which is + /// the historical behaviour of the library (1.7 and earlier). + /// + [Obsolete("Use version that takes an explicit s2kDigest parameter")] + public void AddMethod(char[] passPhrase) + { + AddMethod(passPhrase, HashAlgorithmTag.Sha1); + } + + /// Add a PBE encryption method to the encrypted object. + /// + /// Conversion of the passphrase characters to bytes is performed using Convert.ToByte(), which is + /// the historical behaviour of the library (1.7 and earlier). + /// + public void AddMethod(char[] passPhrase, HashAlgorithmTag s2kDigest) + { + DoAddMethod(PgpUtilities.EncodePassPhrase(passPhrase, false), true, s2kDigest); + } + + /// Add a PBE encryption method to the encrypted object. + /// + /// The passphrase is encoded to bytes using UTF8 (Encoding.UTF8.GetBytes). + /// + public void AddMethodUtf8(char[] passPhrase, HashAlgorithmTag s2kDigest) + { + DoAddMethod(PgpUtilities.EncodePassPhrase(passPhrase, true), true, s2kDigest); + } + + /// Add a PBE encryption method to the encrypted object. + /// + /// Allows the caller to handle the encoding of the passphrase to bytes. + /// + public void AddMethodRaw(byte[] rawPassPhrase, HashAlgorithmTag s2kDigest) + { + DoAddMethod(rawPassPhrase, false, s2kDigest); + } + + internal void DoAddMethod(byte[] rawPassPhrase, bool clearPassPhrase, HashAlgorithmTag s2kDigest) + { + S2k s2k = PgpUtilities.GenerateS2k(s2kDigest, 0x60, rand); + + methods.Add(new PbeMethod(defAlgorithm, s2k, PgpUtilities.DoMakeKeyFromPassPhrase(defAlgorithm, s2k, rawPassPhrase, clearPassPhrase))); + } + + /// Add a public key encrypted session key to the encrypted object. + public void AddMethod(PgpPublicKey key) + { + AddMethod(key, true); + } + + public void AddMethod(PgpPublicKey key, bool sessionKeyObfuscation) + { + if (!key.IsEncryptionKey) + { + throw new ArgumentException("passed in key not an encryption key!"); + } + + methods.Add(new PubMethod(key, sessionKeyObfuscation)); + } + + private void AddCheckSum( + byte[] sessionInfo) + { + Debug.Assert(sessionInfo != null); + Debug.Assert(sessionInfo.Length >= 3); + + int check = 0; + + for (int i = 1; i < sessionInfo.Length - 2; i++) + { + check += sessionInfo[i]; + } + + sessionInfo[sessionInfo.Length - 2] = (byte)(check >> 8); + sessionInfo[sessionInfo.Length - 1] = (byte)(check); + } + + private byte[] CreateSessionInfo( + SymmetricKeyAlgorithmTag algorithm, + KeyParameter key) + { + byte[] keyBytes = key.GetKey(); + byte[] sessionInfo = new byte[keyBytes.Length + 3]; + sessionInfo[0] = (byte) algorithm; + keyBytes.CopyTo(sessionInfo, 1); + AddCheckSum(sessionInfo); + return sessionInfo; + } + + /// + ///

    + /// If buffer is non null stream assumed to be partial, otherwise the length will be used + /// to output a fixed length packet. + ///

    + ///

    + /// The stream created can be closed off by either calling Close() + /// on the stream or Close() on the generator. Closing the returned + /// stream does not close off the Stream parameter outStr. + ///

    + ///
    + private Stream Open( + Stream outStr, + long length, + byte[] buffer) + { + if (cOut != null) + throw new InvalidOperationException("generator already in open state"); + if (methods.Count == 0) + throw new InvalidOperationException("No encryption methods specified"); + if (outStr == null) + throw new ArgumentNullException("outStr"); + + pOut = new BcpgOutputStream(outStr); + + KeyParameter key; + + if (methods.Count == 1) + { + if (methods[0] is PbeMethod) + { + PbeMethod m = (PbeMethod)methods[0]; + + key = m.GetKey(); + } + else + { + key = PgpUtilities.MakeRandomKey(defAlgorithm, rand); + + byte[] sessionInfo = CreateSessionInfo(defAlgorithm, key); + PubMethod m = (PubMethod)methods[0]; + + try + { + m.AddSessionInfo(sessionInfo, rand); + } + catch (Exception e) + { + throw new PgpException("exception encrypting session key", e); + } + } + + pOut.WritePacket((ContainedPacket)methods[0]); + } + else // multiple methods + { + key = PgpUtilities.MakeRandomKey(defAlgorithm, rand); + byte[] sessionInfo = CreateSessionInfo(defAlgorithm, key); + + for (int i = 0; i != methods.Count; i++) + { + EncMethod m = (EncMethod)methods[i]; + + try + { + m.AddSessionInfo(sessionInfo, rand); + } + catch (Exception e) + { + throw new PgpException("exception encrypting session key", e); + } + + pOut.WritePacket(m); + } + } + + string cName = PgpUtilities.GetSymmetricCipherName(defAlgorithm); + if (cName == null) + { + throw new PgpException("null cipher specified"); + } + + try + { + if (withIntegrityPacket) + { + cName += "/CFB/NoPadding"; + } + else + { + cName += "/OpenPGPCFB/NoPadding"; + } + + c = CipherUtilities.GetCipher(cName); + + // TODO Confirm the IV should be all zero bytes (not inLineIv - see below) + byte[] iv = new byte[c.GetBlockSize()]; + c.Init(true, new ParametersWithRandom(new ParametersWithIV(key, iv), rand)); + + if (buffer == null) + { + // + // we have to Add block size + 2 for the Generated IV and + 1 + 22 if integrity protected + // + if (withIntegrityPacket) + { + pOut = new BcpgOutputStream(outStr, PacketTag.SymmetricEncryptedIntegrityProtected, length + c.GetBlockSize() + 2 + 1 + 22); + pOut.WriteByte(1); // version number + } + else + { + pOut = new BcpgOutputStream(outStr, PacketTag.SymmetricKeyEncrypted, length + c.GetBlockSize() + 2, oldFormat); + } + } + else + { + if (withIntegrityPacket) + { + pOut = new BcpgOutputStream(outStr, PacketTag.SymmetricEncryptedIntegrityProtected, buffer); + pOut.WriteByte(1); // version number + } + else + { + pOut = new BcpgOutputStream(outStr, PacketTag.SymmetricKeyEncrypted, buffer); + } + } + + int blockSize = c.GetBlockSize(); + byte[] inLineIv = new byte[blockSize + 2]; + rand.NextBytes(inLineIv, 0, blockSize); + Array.Copy(inLineIv, inLineIv.Length - 4, inLineIv, inLineIv.Length - 2, 2); + + Stream myOut = cOut = new CipherStream(pOut, null, c); + + if (withIntegrityPacket) + { + string digestName = PgpUtilities.GetDigestName(HashAlgorithmTag.Sha1); + IDigest digest = DigestUtilities.GetDigest(digestName); + myOut = digestOut = new DigestStream(myOut, null, digest); + } + + myOut.Write(inLineIv, 0, inLineIv.Length); + + return new WrappedGeneratorStream(this, myOut); + } + catch (Exception e) + { + throw new PgpException("Exception creating cipher", e); + } + } + + /// + ///

    + /// Return an output stream which will encrypt the data as it is written to it. + ///

    + ///

    + /// The stream created can be closed off by either calling Close() + /// on the stream or Close() on the generator. Closing the returned + /// stream does not close off the Stream parameter outStr. + ///

    + ///
    + public Stream Open( + Stream outStr, + long length) + { + return Open(outStr, length, null); + } + + /// + ///

    + /// Return an output stream which will encrypt the data as it is written to it. + /// The stream will be written out in chunks according to the size of the passed in buffer. + ///

    + ///

    + /// The stream created can be closed off by either calling Close() + /// on the stream or Close() on the generator. Closing the returned + /// stream does not close off the Stream parameter outStr. + ///

    + ///

    + /// Note: if the buffer is not a power of 2 in length only the largest power of 2 + /// bytes worth of the buffer will be used. + ///

    + ///
    + public Stream Open( + Stream outStr, + byte[] buffer) + { + return Open(outStr, 0, buffer); + } + + /// + ///

    + /// Close off the encrypted object - this is equivalent to calling Close() on the stream + /// returned by the Open() method. + ///

    + ///

    + /// Note: This does not close the underlying output stream, only the stream on top of + /// it created by the Open() method. + ///

    + ///
    + public void Close() + { + if (cOut != null) + { + // TODO Should this all be under the try/catch block? + if (digestOut != null) + { + // + // hand code a mod detection packet + // + BcpgOutputStream bOut = new BcpgOutputStream( + digestOut, PacketTag.ModificationDetectionCode, 20); + + bOut.Flush(); + digestOut.Flush(); + + // TODO + byte[] dig = DigestUtilities.DoFinal(digestOut.WriteDigest()); + cOut.Write(dig, 0, dig.Length); + } + + cOut.Flush(); + + try + { + pOut.Write(c.DoFinal()); + pOut.Finish(); + } + catch (Exception e) + { + throw new IOException(e.Message, e); + } + + cOut = null; + pOut = null; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpEncryptedDataGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpEncryptedDataGenerator.cs.meta new file mode 100644 index 0000000..71ab409 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpEncryptedDataGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 47048b82d1a0abe4ebc37b99406d5aa4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpEncryptedDataList.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpEncryptedDataList.cs new file mode 100644 index 0000000..1f605da --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpEncryptedDataList.cs @@ -0,0 +1,77 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Bcpg.OpenPgp +{ + /// A holder for a list of PGP encryption method packets. + public class PgpEncryptedDataList + : PgpObject + { + private readonly IList list = Platform.CreateArrayList(); + private readonly InputStreamPacket data; + + public PgpEncryptedDataList( + BcpgInputStream bcpgInput) + { + while (bcpgInput.NextPacketTag() == PacketTag.PublicKeyEncryptedSession + || bcpgInput.NextPacketTag() == PacketTag.SymmetricKeyEncryptedSessionKey) + { + list.Add(bcpgInput.ReadPacket()); + } + + Packet packet = bcpgInput.ReadPacket(); + if (!(packet is InputStreamPacket)) + throw new IOException("unexpected packet in stream: " + packet); + + this.data = (InputStreamPacket)packet; + + for (int i = 0; i != list.Count; i++) + { + if (list[i] is SymmetricKeyEncSessionPacket) + { + list[i] = new PgpPbeEncryptedData((SymmetricKeyEncSessionPacket) list[i], data); + } + else + { + list[i] = new PgpPublicKeyEncryptedData((PublicKeyEncSessionPacket) list[i], data); + } + } + } + + public PgpEncryptedData this[int index] + { + get { return (PgpEncryptedData) list[index]; } + } + + [Obsolete("Use 'object[index]' syntax instead")] + public object Get(int index) + { + return this[index]; + } + + [Obsolete("Use 'Count' property instead")] + public int Size + { + get { return list.Count; } + } + + public int Count + { + get { return list.Count; } + } + + public bool IsEmpty + { + get { return list.Count == 0; } + } + + public IEnumerable GetEncryptedDataObjects() + { + return new EnumerableProxy(list); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpEncryptedDataList.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpEncryptedDataList.cs.meta new file mode 100644 index 0000000..f24ef4a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpEncryptedDataList.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b7b4d73acc773e9459e75217145e2e18 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpException.cs new file mode 100644 index 0000000..230dab8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpException.cs @@ -0,0 +1,22 @@ +using System; + +namespace Org.BouncyCastle.Bcpg.OpenPgp +{ + /// Generic exception class for PGP encoding/decoding problems. +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE) + [Serializable] +#endif + public class PgpException + : Exception + { + public PgpException() : base() {} + public PgpException(string message) : base(message) {} + public PgpException(string message, Exception exception) : base(message, exception) {} + + [Obsolete("Use InnerException property")] + public Exception UnderlyingException + { + get { return InnerException; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpException.cs.meta new file mode 100644 index 0000000..558be35 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b06f3be9a3f2b4141a062832f1e72c21 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpExperimental.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpExperimental.cs new file mode 100644 index 0000000..8518335 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpExperimental.cs @@ -0,0 +1,16 @@ +using System; + +namespace Org.BouncyCastle.Bcpg.OpenPgp +{ + public class PgpExperimental + : PgpObject + { + private readonly ExperimentalPacket p; + + public PgpExperimental( + BcpgInputStream bcpgIn) + { + p = (ExperimentalPacket) bcpgIn.ReadPacket(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpExperimental.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpExperimental.cs.meta new file mode 100644 index 0000000..141d023 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpExperimental.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 896298f41be46e143bc328c972b9040c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpKeyFlags.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpKeyFlags.cs new file mode 100644 index 0000000..ea18006 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpKeyFlags.cs @@ -0,0 +1,13 @@ +namespace Org.BouncyCastle.Bcpg.OpenPgp +{ + /// Key flag values for the KeyFlags subpacket. + public abstract class PgpKeyFlags + { + public const int CanCertify = 0x01; // This key may be used to certify other keys. + public const int CanSign = 0x02; // This key may be used to sign data. + public const int CanEncryptCommunications = 0x04; // This key may be used to encrypt communications. + public const int CanEncryptStorage = 0x08; // This key may be used to encrypt storage. + public const int MaybeSplit = 0x10; // The private component of this key may have been split by a secret-sharing mechanism. + public const int MaybeShared = 0x80; // The private component of this key may be in the possession of more than one person. + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpKeyFlags.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpKeyFlags.cs.meta new file mode 100644 index 0000000..51db6c2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpKeyFlags.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 984c59490343d7e44aaf831be54bdd49 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpKeyPair.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpKeyPair.cs new file mode 100644 index 0000000..9cf78fa --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpKeyPair.cs @@ -0,0 +1,67 @@ +using System; + +using Org.BouncyCastle.Crypto; + +namespace Org.BouncyCastle.Bcpg.OpenPgp +{ + /// + /// General class to handle JCA key pairs and convert them into OpenPGP ones. + ///

    + /// A word for the unwary, the KeyId for an OpenPGP public key is calculated from + /// a hash that includes the time of creation, if you pass a different date to the + /// constructor below with the same public private key pair the KeyIs will not be the + /// same as for previous generations of the key, so ideally you only want to do + /// this once. + ///

    + ///
    + public class PgpKeyPair + { + private readonly PgpPublicKey pub; + private readonly PgpPrivateKey priv; + + public PgpKeyPair( + PublicKeyAlgorithmTag algorithm, + AsymmetricCipherKeyPair keyPair, + DateTime time) + : this(algorithm, keyPair.Public, keyPair.Private, time) + { + } + + public PgpKeyPair( + PublicKeyAlgorithmTag algorithm, + AsymmetricKeyParameter pubKey, + AsymmetricKeyParameter privKey, + DateTime time) + { + this.pub = new PgpPublicKey(algorithm, pubKey, time); + this.priv = new PgpPrivateKey(pub.KeyId, pub.PublicKeyPacket, privKey); + } + + /// Create a key pair from a PgpPrivateKey and a PgpPublicKey. + /// The public key. + /// The private key. + public PgpKeyPair( + PgpPublicKey pub, + PgpPrivateKey priv) + { + this.pub = pub; + this.priv = priv; + } + + /// The keyId associated with this key pair. + public long KeyId + { + get { return pub.KeyId; } + } + + public PgpPublicKey PublicKey + { + get { return pub; } + } + + public PgpPrivateKey PrivateKey + { + get { return priv; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpKeyPair.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpKeyPair.cs.meta new file mode 100644 index 0000000..8365bbd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpKeyPair.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4f706c8e15eb0984386cf9f6fcbd1f96 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpKeyRingGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpKeyRingGenerator.cs new file mode 100644 index 0000000..352575b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpKeyRingGenerator.cs @@ -0,0 +1,440 @@ +using System; +using System.Collections; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Bcpg.OpenPgp +{ + /// + /// Generator for a PGP master and subkey ring. + /// This class will generate both the secret and public key rings + /// + public class PgpKeyRingGenerator + { + private IList keys = Platform.CreateArrayList(); + private string id; + private SymmetricKeyAlgorithmTag encAlgorithm; + private HashAlgorithmTag hashAlgorithm; + private int certificationLevel; + private byte[] rawPassPhrase; + private bool useSha1; + private PgpKeyPair masterKey; + private PgpSignatureSubpacketVector hashedPacketVector; + private PgpSignatureSubpacketVector unhashedPacketVector; + private SecureRandom rand; + + /// + /// Create a new key ring generator using old style checksumming. It is recommended to use + /// SHA1 checksumming where possible. + /// + /// + /// Conversion of the passphrase characters to bytes is performed using Convert.ToByte(), which is + /// the historical behaviour of the library (1.7 and earlier). + /// + /// The certification level for keys on this ring. + /// The master key pair. + /// The id to be associated with the ring. + /// The algorithm to be used to protect secret keys. + /// The passPhrase to be used to protect secret keys. + /// Packets to be included in the certification hash. + /// Packets to be attached unhashed to the certification. + /// input secured random. + [Obsolete("Use version taking an explicit 'useSha1' parameter instead")] + public PgpKeyRingGenerator( + int certificationLevel, + PgpKeyPair masterKey, + string id, + SymmetricKeyAlgorithmTag encAlgorithm, + char[] passPhrase, + PgpSignatureSubpacketVector hashedPackets, + PgpSignatureSubpacketVector unhashedPackets, + SecureRandom rand) + : this(certificationLevel, masterKey, id, encAlgorithm, passPhrase, false, hashedPackets, unhashedPackets, rand) + { + } + + /// + /// Create a new key ring generator. + /// + /// + /// Conversion of the passphrase characters to bytes is performed using Convert.ToByte(), which is + /// the historical behaviour of the library (1.7 and earlier). + /// + /// The certification level for keys on this ring. + /// The master key pair. + /// The id to be associated with the ring. + /// The algorithm to be used to protect secret keys. + /// The passPhrase to be used to protect secret keys. + /// Checksum the secret keys with SHA1 rather than the older 16 bit checksum. + /// Packets to be included in the certification hash. + /// Packets to be attached unhashed to the certification. + /// input secured random. + public PgpKeyRingGenerator( + int certificationLevel, + PgpKeyPair masterKey, + string id, + SymmetricKeyAlgorithmTag encAlgorithm, + char[] passPhrase, + bool useSha1, + PgpSignatureSubpacketVector hashedPackets, + PgpSignatureSubpacketVector unhashedPackets, + SecureRandom rand) + : this(certificationLevel, masterKey, id, encAlgorithm, false, passPhrase, useSha1, hashedPackets, unhashedPackets, rand) + { + } + + /// + /// Create a new key ring generator. + /// + /// The certification level for keys on this ring. + /// The master key pair. + /// The id to be associated with the ring. + /// The algorithm to be used to protect secret keys. + /// + /// If true, conversion of the passphrase to bytes uses Encoding.UTF8.GetBytes(), otherwise the conversion + /// is performed using Convert.ToByte(), which is the historical behaviour of the library (1.7 and earlier). + /// + /// The passPhrase to be used to protect secret keys. + /// Checksum the secret keys with SHA1 rather than the older 16 bit checksum. + /// Packets to be included in the certification hash. + /// Packets to be attached unhashed to the certification. + /// input secured random. + public PgpKeyRingGenerator( + int certificationLevel, + PgpKeyPair masterKey, + string id, + SymmetricKeyAlgorithmTag encAlgorithm, + bool utf8PassPhrase, + char[] passPhrase, + bool useSha1, + PgpSignatureSubpacketVector hashedPackets, + PgpSignatureSubpacketVector unhashedPackets, + SecureRandom rand) + : this(certificationLevel, masterKey, id, encAlgorithm, + PgpUtilities.EncodePassPhrase(passPhrase, utf8PassPhrase), + useSha1, hashedPackets, unhashedPackets, rand) + { + } + + /// + /// Create a new key ring generator. + /// + /// The certification level for keys on this ring. + /// The master key pair. + /// The id to be associated with the ring. + /// The algorithm to be used to protect secret keys. + /// The passPhrase to be used to protect secret keys. + /// Checksum the secret keys with SHA1 rather than the older 16 bit checksum. + /// Packets to be included in the certification hash. + /// Packets to be attached unhashed to the certification. + /// input secured random. + public PgpKeyRingGenerator( + int certificationLevel, + PgpKeyPair masterKey, + string id, + SymmetricKeyAlgorithmTag encAlgorithm, + byte[] rawPassPhrase, + bool useSha1, + PgpSignatureSubpacketVector hashedPackets, + PgpSignatureSubpacketVector unhashedPackets, + SecureRandom rand) + { + this.certificationLevel = certificationLevel; + this.masterKey = masterKey; + this.id = id; + this.encAlgorithm = encAlgorithm; + this.rawPassPhrase = rawPassPhrase; + this.useSha1 = useSha1; + this.hashedPacketVector = hashedPackets; + this.unhashedPacketVector = unhashedPackets; + this.rand = rand; + + keys.Add(new PgpSecretKey(certificationLevel, masterKey, id, encAlgorithm, rawPassPhrase, false, useSha1, hashedPackets, unhashedPackets, rand)); + } + + /// + /// Create a new key ring generator. + /// + /// + /// Conversion of the passphrase characters to bytes is performed using Convert.ToByte(), which is + /// the historical behaviour of the library (1.7 and earlier). + /// + /// The certification level for keys on this ring. + /// The master key pair. + /// The id to be associated with the ring. + /// The algorithm to be used to protect secret keys. + /// The hash algorithm. + /// The passPhrase to be used to protect secret keys. + /// Checksum the secret keys with SHA1 rather than the older 16 bit checksum. + /// Packets to be included in the certification hash. + /// Packets to be attached unhashed to the certification. + /// input secured random. + public PgpKeyRingGenerator( + int certificationLevel, + PgpKeyPair masterKey, + string id, + SymmetricKeyAlgorithmTag encAlgorithm, + HashAlgorithmTag hashAlgorithm, + char[] passPhrase, + bool useSha1, + PgpSignatureSubpacketVector hashedPackets, + PgpSignatureSubpacketVector unhashedPackets, + SecureRandom rand) + : this(certificationLevel, masterKey, id, encAlgorithm, hashAlgorithm, false, passPhrase, useSha1, hashedPackets, unhashedPackets, rand) + { + } + + /// + /// Create a new key ring generator. + /// + /// The certification level for keys on this ring. + /// The master key pair. + /// The id to be associated with the ring. + /// The algorithm to be used to protect secret keys. + /// The hash algorithm. + /// + /// If true, conversion of the passphrase to bytes uses Encoding.UTF8.GetBytes(), otherwise the conversion + /// is performed using Convert.ToByte(), which is the historical behaviour of the library (1.7 and earlier). + /// + /// The passPhrase to be used to protect secret keys. + /// Checksum the secret keys with SHA1 rather than the older 16 bit checksum. + /// Packets to be included in the certification hash. + /// Packets to be attached unhashed to the certification. + /// input secured random. + public PgpKeyRingGenerator( + int certificationLevel, + PgpKeyPair masterKey, + string id, + SymmetricKeyAlgorithmTag encAlgorithm, + HashAlgorithmTag hashAlgorithm, + bool utf8PassPhrase, + char[] passPhrase, + bool useSha1, + PgpSignatureSubpacketVector hashedPackets, + PgpSignatureSubpacketVector unhashedPackets, + SecureRandom rand) + : this(certificationLevel, masterKey, id, encAlgorithm, hashAlgorithm, + PgpUtilities.EncodePassPhrase(passPhrase, utf8PassPhrase), + useSha1, hashedPackets, unhashedPackets, rand) + { + } + + /// + /// Create a new key ring generator. + /// + /// + /// Allows the caller to handle the encoding of the passphrase to bytes. + /// + /// The certification level for keys on this ring. + /// The master key pair. + /// The id to be associated with the ring. + /// The algorithm to be used to protect secret keys. + /// The hash algorithm. + /// The passPhrase to be used to protect secret keys. + /// Checksum the secret keys with SHA1 rather than the older 16 bit checksum. + /// Packets to be included in the certification hash. + /// Packets to be attached unhashed to the certification. + /// input secured random. + public PgpKeyRingGenerator( + int certificationLevel, + PgpKeyPair masterKey, + string id, + SymmetricKeyAlgorithmTag encAlgorithm, + HashAlgorithmTag hashAlgorithm, + byte[] rawPassPhrase, + bool useSha1, + PgpSignatureSubpacketVector hashedPackets, + PgpSignatureSubpacketVector unhashedPackets, + SecureRandom rand) + { + this.certificationLevel = certificationLevel; + this.masterKey = masterKey; + this.id = id; + this.encAlgorithm = encAlgorithm; + this.rawPassPhrase = rawPassPhrase; + this.useSha1 = useSha1; + this.hashedPacketVector = hashedPackets; + this.unhashedPacketVector = unhashedPackets; + this.rand = rand; + this.hashAlgorithm = hashAlgorithm; + + keys.Add(new PgpSecretKey(certificationLevel, masterKey, id, encAlgorithm, hashAlgorithm, rawPassPhrase, false, useSha1, hashedPackets, unhashedPackets, rand)); + } + + /// Add a subkey to the key ring to be generated with default certification. + public void AddSubKey( + PgpKeyPair keyPair) + { + AddSubKey(keyPair, this.hashedPacketVector, this.unhashedPacketVector); + } + + + /// + /// Add a subkey to the key ring to be generated with default certification. + /// + /// The key pair. + /// The hash algorithm. + public void AddSubKey(PgpKeyPair keyPair, HashAlgorithmTag hashAlgorithm) + { + this.AddSubKey(keyPair, this.hashedPacketVector, this.unhashedPacketVector, hashAlgorithm); + } + + /// + /// Add a signing subkey to the key ring to be generated with default certification and a primary key binding signature. + /// + /// The key pair. + /// The hash algorithm. + /// The primary-key binding hash algorithm. + public void AddSubKey(PgpKeyPair keyPair, HashAlgorithmTag hashAlgorithm, HashAlgorithmTag primaryKeyBindingHashAlgorithm) + { + this.AddSubKey(keyPair, this.hashedPacketVector, this.unhashedPacketVector, hashAlgorithm, primaryKeyBindingHashAlgorithm); + } + + /// + /// Add a subkey with specific hashed and unhashed packets associated with it and + /// default certification using SHA-1. + /// + /// Public/private key pair. + /// Hashed packet values to be included in certification. + /// Unhashed packets values to be included in certification. + /// + public void AddSubKey( + PgpKeyPair keyPair, + PgpSignatureSubpacketVector hashedPackets, + PgpSignatureSubpacketVector unhashedPackets) + { + AddSubKey(keyPair, hashedPackets, unhashedPackets, HashAlgorithmTag.Sha1); + } + + /// + /// Add a subkey with specific hashed and unhashed packets associated with it and + /// default certification. + /// + /// Public/private key pair. + /// Hashed packet values to be included in certification. + /// Unhashed packets values to be included in certification. + /// The hash algorithm. + /// exception adding subkey: + /// + public void AddSubKey( + PgpKeyPair keyPair, + PgpSignatureSubpacketVector hashedPackets, + PgpSignatureSubpacketVector unhashedPackets, + HashAlgorithmTag hashAlgorithm) + { + try + { + PgpSignatureGenerator sGen = new PgpSignatureGenerator(masterKey.PublicKey.Algorithm, hashAlgorithm); + + // + // Generate the certification + // + sGen.InitSign(PgpSignature.SubkeyBinding, masterKey.PrivateKey); + + sGen.SetHashedSubpackets(hashedPackets); + sGen.SetUnhashedSubpackets(unhashedPackets); + + IList subSigs = Platform.CreateArrayList(); + subSigs.Add(sGen.GenerateCertification(masterKey.PublicKey, keyPair.PublicKey)); + + keys.Add(new PgpSecretKey(keyPair.PrivateKey, new PgpPublicKey(keyPair.PublicKey, null, subSigs), encAlgorithm, + rawPassPhrase, false, useSha1, rand, false)); + } + catch (PgpException) + { + throw; + } + catch (Exception e) + { + throw new PgpException("exception adding subkey: ", e); + } + } + + /// + /// Add a signing subkey with specific hashed and unhashed packets associated with it and + /// default certifications, including the primary-key binding signature. + /// + /// Public/private key pair. + /// Hashed packet values to be included in certification. + /// Unhashed packets values to be included in certification. + /// The hash algorithm. + /// The primary-key binding hash algorithm. + /// exception adding subkey: + /// + public void AddSubKey( + PgpKeyPair keyPair, + PgpSignatureSubpacketVector hashedPackets, + PgpSignatureSubpacketVector unhashedPackets, + HashAlgorithmTag hashAlgorithm, + HashAlgorithmTag primaryKeyBindingHashAlgorithm) + { + try + { + PgpSignatureGenerator sGen = new PgpSignatureGenerator(masterKey.PublicKey.Algorithm, hashAlgorithm); + + // + // Generate the certification + // + sGen.InitSign(PgpSignature.SubkeyBinding, masterKey.PrivateKey); + + // add primary key binding sub packet + PgpSignatureGenerator pGen = new PgpSignatureGenerator(keyPair.PublicKey.Algorithm, primaryKeyBindingHashAlgorithm); + + pGen.InitSign(PgpSignature.PrimaryKeyBinding, keyPair.PrivateKey); + + PgpSignatureSubpacketGenerator spGen = new PgpSignatureSubpacketGenerator(hashedPackets); + + spGen.SetEmbeddedSignature(false, + pGen.GenerateCertification(masterKey.PublicKey, keyPair.PublicKey)); + + sGen.SetHashedSubpackets(spGen.Generate()); + sGen.SetUnhashedSubpackets(unhashedPackets); + + IList subSigs = Platform.CreateArrayList(); + subSigs.Add(sGen.GenerateCertification(masterKey.PublicKey, keyPair.PublicKey)); + + keys.Add(new PgpSecretKey(keyPair.PrivateKey, new PgpPublicKey(keyPair.PublicKey, null, subSigs), encAlgorithm, + rawPassPhrase, false, useSha1, rand, false)); + } + catch (PgpException) + { + throw; + } + catch (Exception e) + { + throw new PgpException("exception adding subkey: ", e); + } + } + + /// Return the secret key ring. + public PgpSecretKeyRing GenerateSecretKeyRing() + { + return new PgpSecretKeyRing(keys); + } + + /// Return the public key ring that corresponds to the secret key ring. + public PgpPublicKeyRing GeneratePublicKeyRing() + { + IList pubKeys = Platform.CreateArrayList(); + + IEnumerator enumerator = keys.GetEnumerator(); + enumerator.MoveNext(); + + PgpSecretKey pgpSecretKey = (PgpSecretKey) enumerator.Current; + pubKeys.Add(pgpSecretKey.PublicKey); + + while (enumerator.MoveNext()) + { + pgpSecretKey = (PgpSecretKey) enumerator.Current; + + PgpPublicKey k = new PgpPublicKey(pgpSecretKey.PublicKey); + k.publicPk = new PublicSubkeyPacket( + k.Algorithm, k.CreationTime, k.publicPk.Key); + + pubKeys.Add(k); + } + + return new PgpPublicKeyRing(pubKeys); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpKeyRingGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpKeyRingGenerator.cs.meta new file mode 100644 index 0000000..6d3a23c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpKeyRingGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 65708f312cd6d0745b30863edb4c8983 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpKeyValidationException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpKeyValidationException.cs new file mode 100644 index 0000000..383ae57 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpKeyValidationException.cs @@ -0,0 +1,18 @@ +using System; + +namespace Org.BouncyCastle.Bcpg.OpenPgp +{ + /// + /// Thrown if the key checksum is invalid. + /// +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE) + [Serializable] +#endif + public class PgpKeyValidationException + : PgpException + { + public PgpKeyValidationException() : base() {} + public PgpKeyValidationException(string message) : base(message) {} + public PgpKeyValidationException(string message, Exception exception) : base(message, exception) {} + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpKeyValidationException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpKeyValidationException.cs.meta new file mode 100644 index 0000000..1040706 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpKeyValidationException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9b242e396d0846d4fa8178cd0759e8ff +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpLiteralData.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpLiteralData.cs new file mode 100644 index 0000000..d1b7b4a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpLiteralData.cs @@ -0,0 +1,67 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Utilities.Date; + +namespace Org.BouncyCastle.Bcpg.OpenPgp +{ + /// Class for processing literal data objects. + public class PgpLiteralData + : PgpObject + { + public const char Binary = 'b'; + public const char Text = 't'; + public const char Utf8 = 'u'; + + /// The special name indicating a "for your eyes only" packet. + public const string Console = "_CONSOLE"; + + private readonly LiteralDataPacket data; + + public PgpLiteralData( + BcpgInputStream bcpgInput) + { + Packet packet = bcpgInput.ReadPacket(); + if (!(packet is LiteralDataPacket)) + throw new IOException("unexpected packet in stream: " + packet); + + this.data = (LiteralDataPacket)packet; + } + + /// The format of the data stream - Binary or Text + public int Format + { + get { return data.Format; } + } + + /// The file name that's associated with the data stream. + public string FileName + { + get { return data.FileName; } + } + + /// Return the file name as an unintrepreted byte array. + public byte[] GetRawFileName() + { + return data.GetRawFileName(); + } + + /// The modification time for the file. + public DateTime ModificationTime + { + get { return DateTimeUtilities.UnixMsToDateTime(data.ModificationTime); } + } + + /// The raw input stream for the data stream. + public Stream GetInputStream() + { + return data.GetInputStream(); + } + + /// The input stream representing the data stream. + public Stream GetDataStream() + { + return GetInputStream(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpLiteralData.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpLiteralData.cs.meta new file mode 100644 index 0000000..be2f2c6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpLiteralData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c9201964d642fe34690364b3951fa9aa +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpLiteralDataGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpLiteralDataGenerator.cs new file mode 100644 index 0000000..217d714 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpLiteralDataGenerator.cs @@ -0,0 +1,182 @@ +using System; +using System.IO; +using System.Text; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Date; + +namespace Org.BouncyCastle.Bcpg.OpenPgp +{ + /// Class for producing literal data packets. + public class PgpLiteralDataGenerator + : IStreamGenerator + { + public const char Binary = PgpLiteralData.Binary; + public const char Text = PgpLiteralData.Text; + public const char Utf8 = PgpLiteralData.Utf8; + + /// The special name indicating a "for your eyes only" packet. + public const string Console = PgpLiteralData.Console; + + private BcpgOutputStream pkOut; + private bool oldFormat; + + public PgpLiteralDataGenerator() + { + } + + /// + /// Generates literal data objects in the old format. + /// This is important if you need compatibility with PGP 2.6.x. + /// + /// If true, uses old format. + public PgpLiteralDataGenerator( + bool oldFormat) + { + this.oldFormat = oldFormat; + } + + private void WriteHeader( + BcpgOutputStream outStr, + char format, + byte[] encName, + long modificationTime) + { + outStr.Write( + (byte) format, + (byte) encName.Length); + + outStr.Write(encName); + + long modDate = modificationTime / 1000L; + + outStr.Write( + (byte)(modDate >> 24), + (byte)(modDate >> 16), + (byte)(modDate >> 8), + (byte)modDate); + } + + /// + ///

    + /// Open a literal data packet, returning a stream to store the data inside the packet. + ///

    + ///

    + /// The stream created can be closed off by either calling Close() + /// on the stream or Close() on the generator. Closing the returned + /// stream does not close off the Stream parameter outStr. + ///

    + ///
    + /// The stream we want the packet in. + /// The format we are using. + /// The name of the 'file'. + /// The length of the data we will write. + /// The time of last modification we want stored. + public Stream Open( + Stream outStr, + char format, + string name, + long length, + DateTime modificationTime) + { + if (pkOut != null) + throw new InvalidOperationException("generator already in open state"); + if (outStr == null) + throw new ArgumentNullException("outStr"); + + // Do this first, since it might throw an exception + long unixMs = DateTimeUtilities.DateTimeToUnixMs(modificationTime); + + byte[] encName = Strings.ToUtf8ByteArray(name); + + pkOut = new BcpgOutputStream(outStr, PacketTag.LiteralData, + length + 2 + encName.Length + 4, oldFormat); + + WriteHeader(pkOut, format, encName, unixMs); + + return new WrappedGeneratorStream(this, pkOut); + } + + /// + ///

    + /// Open a literal data packet, returning a stream to store the data inside the packet, + /// as an indefinite length stream. The stream is written out as a series of partial + /// packets with a chunk size determined by the size of the passed in buffer. + ///

    + ///

    + /// The stream created can be closed off by either calling Close() + /// on the stream or Close() on the generator. Closing the returned + /// stream does not close off the Stream parameter outStr. + ///

    + ///

    + /// Note: if the buffer is not a power of 2 in length only the largest power of 2 + /// bytes worth of the buffer will be used.

    + ///
    + /// The stream we want the packet in. + /// The format we are using. + /// The name of the 'file'. + /// The time of last modification we want stored. + /// The buffer to use for collecting data to put into chunks. + public Stream Open( + Stream outStr, + char format, + string name, + DateTime modificationTime, + byte[] buffer) + { + if (pkOut != null) + throw new InvalidOperationException("generator already in open state"); + if (outStr == null) + throw new ArgumentNullException("outStr"); + + // Do this first, since it might throw an exception + long unixMs = DateTimeUtilities.DateTimeToUnixMs(modificationTime); + + byte[] encName = Strings.ToUtf8ByteArray(name); + + pkOut = new BcpgOutputStream(outStr, PacketTag.LiteralData, buffer); + + WriteHeader(pkOut, format, encName, unixMs); + + return new WrappedGeneratorStream(this, pkOut); + } + +#if !PORTABLE || NETSTANDARD1_3 + /// + ///

    + /// Open a literal data packet for the passed in FileInfo object, returning + /// an output stream for saving the file contents. + ///

    + ///

    + /// The stream created can be closed off by either calling Close() + /// on the stream or Close() on the generator. Closing the returned + /// stream does not close off the Stream parameter outStr. + ///

    + ///
    + /// The stream we want the packet in. + /// The format we are using. + /// The FileInfo object containg the packet details. + public Stream Open( + Stream outStr, + char format, + FileInfo file) + { + return Open(outStr, format, file.Name, file.Length, file.LastWriteTime); + } +#endif + + /// + /// Close the literal data packet - this is equivalent to calling Close() + /// on the stream returned by the Open() method. + /// + public void Close() + { + if (pkOut != null) + { + pkOut.Finish(); + pkOut.Flush(); + pkOut = null; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpLiteralDataGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpLiteralDataGenerator.cs.meta new file mode 100644 index 0000000..feab633 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpLiteralDataGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 27b9effd46be2404d98782ef288cf48b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpMarker.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpMarker.cs new file mode 100644 index 0000000..7257767 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpMarker.cs @@ -0,0 +1,25 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Bcpg.OpenPgp +{ + /// + /// A PGP marker packet - in general these should be ignored other than where + /// the idea is to preserve the original input stream. + /// + public class PgpMarker + : PgpObject + { + private readonly MarkerPacket data; + + public PgpMarker( + BcpgInputStream bcpgInput) + { + Packet packet = bcpgInput.ReadPacket(); + if (!(packet is MarkerPacket)) + throw new IOException("unexpected packet in stream: " + packet); + + this.data = (MarkerPacket)packet; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpMarker.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpMarker.cs.meta new file mode 100644 index 0000000..3bfdbdc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpMarker.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dc1bc5814da23b349b0460e1e9d039f2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpObjectFactory.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpObjectFactory.cs new file mode 100644 index 0000000..c67c7cc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpObjectFactory.cs @@ -0,0 +1,168 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Bcpg.OpenPgp +{ + /// + /// General class for reading a PGP object stream. + ///

    + /// Note: if this class finds a PgpPublicKey or a PgpSecretKey it + /// will create a PgpPublicKeyRing, or a PgpSecretKeyRing for each + /// key found. If all you are trying to do is read a key ring file use + /// either PgpPublicKeyRingBundle or PgpSecretKeyRingBundle.

    + ///
    + public class PgpObjectFactory + { + private readonly BcpgInputStream bcpgIn; + + public PgpObjectFactory( + Stream inputStream) + { + this.bcpgIn = BcpgInputStream.Wrap(inputStream); + } + + public PgpObjectFactory( + byte[] bytes) + : this(new MemoryStream(bytes, false)) + { + } + + /// Return the next object in the stream, or null if the end is reached. + /// On a parse error + public PgpObject NextPgpObject() + { + PacketTag tag = bcpgIn.NextPacketTag(); + + if ((int) tag == -1) return null; + + switch (tag) + { + case PacketTag.Signature: + { + IList l = Platform.CreateArrayList(); + + while (bcpgIn.NextPacketTag() == PacketTag.Signature) + { + try + { + l.Add(new PgpSignature(bcpgIn)); + } + catch (UnsupportedPacketVersionException e) + { + // Signatures of unsupported version MUST BE ignored + // see: https://tests.sequoia-pgp.org/#Detached_signatures_with_unknown_packets + continue; + } + catch (PgpException e) + { + throw new IOException("can't create signature object: " + e); + } + } + + PgpSignature[] sigs = new PgpSignature[l.Count]; + for (int i = 0; i < l.Count; ++i) + { + sigs[i] = (PgpSignature)l[i]; + } + return new PgpSignatureList(sigs); + } + case PacketTag.SecretKey: + try + { + return new PgpSecretKeyRing(bcpgIn); + } + catch (PgpException e) + { + throw new IOException("can't create secret key object: " + e); + } + case PacketTag.PublicKey: + return new PgpPublicKeyRing(bcpgIn); + // TODO Make PgpPublicKey a PgpObject or return a PgpPublicKeyRing +// case PacketTag.PublicSubkey: +// return PgpPublicKeyRing.ReadSubkey(bcpgIn); + case PacketTag.CompressedData: + return new PgpCompressedData(bcpgIn); + case PacketTag.LiteralData: + return new PgpLiteralData(bcpgIn); + case PacketTag.PublicKeyEncryptedSession: + case PacketTag.SymmetricKeyEncryptedSessionKey: + return new PgpEncryptedDataList(bcpgIn); + case PacketTag.OnePassSignature: + { + IList l = Platform.CreateArrayList(); + + while (bcpgIn.NextPacketTag() == PacketTag.OnePassSignature) + { + try + { + l.Add(new PgpOnePassSignature(bcpgIn)); + } + catch (PgpException e) + { + throw new IOException("can't create one pass signature object: " + e); + } + } + + PgpOnePassSignature[] sigs = new PgpOnePassSignature[l.Count]; + for (int i = 0; i < l.Count; ++i) + { + sigs[i] = (PgpOnePassSignature)l[i]; + } + return new PgpOnePassSignatureList(sigs); + } + case PacketTag.Marker: + return new PgpMarker(bcpgIn); + case PacketTag.Experimental1: + case PacketTag.Experimental2: + case PacketTag.Experimental3: + case PacketTag.Experimental4: + return new PgpExperimental(bcpgIn); + } + + throw new IOException("unknown object in stream " + bcpgIn.NextPacketTag()); + } + + [Obsolete("Use NextPgpObject() instead")] + public object NextObject() + { + return NextPgpObject(); + } + + /// + /// Return all available objects in a list. + /// + /// An IList containing all objects from this factory, in order. + public IList AllPgpObjects() + { + IList result = Platform.CreateArrayList(); + PgpObject pgpObject; + while ((pgpObject = NextPgpObject()) != null) + { + result.Add(pgpObject); + } + return result; + } + + /// + /// Read all available objects, returning only those that are assignable to the specified type. + /// + /// The type of objects to return. All other objects are ignored. + /// An IList containing the filtered objects from this factory, in order. + public IList FilterPgpObjects(Type type) + { + IList result = Platform.CreateArrayList(); + PgpObject pgpObject; + while ((pgpObject = NextPgpObject()) != null) + { + if (type.IsInstanceOfType(pgpObject)) + { + result.Add(pgpObject); + } + } + return result; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpObjectFactory.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpObjectFactory.cs.meta new file mode 100644 index 0000000..6d341f3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpObjectFactory.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bbb1adcc0bcfd8c49b47ed0e85129391 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpOnePassSignature.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpOnePassSignature.cs new file mode 100644 index 0000000..2fab513 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpOnePassSignature.cs @@ -0,0 +1,187 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Bcpg.OpenPgp +{ + /// A one pass signature object. + public class PgpOnePassSignature + { + private static OnePassSignaturePacket Cast(Packet packet) + { + if (!(packet is OnePassSignaturePacket)) + throw new IOException("unexpected packet in stream: " + packet); + + return (OnePassSignaturePacket)packet; + } + + private readonly OnePassSignaturePacket sigPack; + private readonly int signatureType; + private ISigner sig; + private byte lastb; + + internal PgpOnePassSignature( + BcpgInputStream bcpgInput) + : this(Cast(bcpgInput.ReadPacket())) + { + } + + internal PgpOnePassSignature( + OnePassSignaturePacket sigPack) + { + this.sigPack = sigPack; + this.signatureType = sigPack.SignatureType; + } + + /// Initialise the signature object for verification. + public void InitVerify( + PgpPublicKey pubKey) + { + lastb = 0; + + try + { + sig = SignerUtilities.GetSigner( + PgpUtilities.GetSignatureName(sigPack.KeyAlgorithm, sigPack.HashAlgorithm)); + } + catch (Exception e) + { + throw new PgpException("can't set up signature object.", e); + } + + try + { + sig.Init(false, pubKey.GetKey()); + } + catch (InvalidKeyException e) + { + throw new PgpException("invalid key.", e); + } + } + + public void Update( + byte b) + { + if (signatureType == PgpSignature.CanonicalTextDocument) + { + doCanonicalUpdateByte(b); + } + else + { + sig.Update(b); + } + } + + private void doCanonicalUpdateByte( + byte b) + { + if (b == '\r') + { + doUpdateCRLF(); + } + else if (b == '\n') + { + if (lastb != '\r') + { + doUpdateCRLF(); + } + } + else + { + sig.Update(b); + } + + lastb = b; + } + + private void doUpdateCRLF() + { + sig.Update((byte)'\r'); + sig.Update((byte)'\n'); + } + + public void Update( + byte[] bytes) + { + if (signatureType == PgpSignature.CanonicalTextDocument) + { + for (int i = 0; i != bytes.Length; i++) + { + doCanonicalUpdateByte(bytes[i]); + } + } + else + { + sig.BlockUpdate(bytes, 0, bytes.Length); + } + } + + public void Update( + byte[] bytes, + int off, + int length) + { + if (signatureType == PgpSignature.CanonicalTextDocument) + { + int finish = off + length; + + for (int i = off; i != finish; i++) + { + doCanonicalUpdateByte(bytes[i]); + } + } + else + { + sig.BlockUpdate(bytes, off, length); + } + } + + /// Verify the calculated signature against the passed in PgpSignature. + public bool Verify( + PgpSignature pgpSig) + { + byte[] trailer = pgpSig.GetSignatureTrailer(); + + sig.BlockUpdate(trailer, 0, trailer.Length); + + return sig.VerifySignature(pgpSig.GetSignature()); + } + + public long KeyId + { + get { return sigPack.KeyId; } + } + + public int SignatureType + { + get { return sigPack.SignatureType; } + } + + public HashAlgorithmTag HashAlgorithm + { + get { return sigPack.HashAlgorithm; } + } + + public PublicKeyAlgorithmTag KeyAlgorithm + { + get { return sigPack.KeyAlgorithm; } + } + + public byte[] GetEncoded() + { + MemoryStream bOut = new MemoryStream(); + + Encode(bOut); + + return bOut.ToArray(); + } + + public void Encode( + Stream outStr) + { + BcpgOutputStream.Wrap(outStr).WritePacket(sigPack); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpOnePassSignature.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpOnePassSignature.cs.meta new file mode 100644 index 0000000..d751a64 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpOnePassSignature.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4140fb0a9c15a3342825c6a82650b33b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpOnePassSignatureList.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpOnePassSignatureList.cs new file mode 100644 index 0000000..37c4288 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpOnePassSignatureList.cs @@ -0,0 +1,51 @@ +using System; + +namespace Org.BouncyCastle.Bcpg.OpenPgp +{ + /// Holder for a list of PgpOnePassSignature objects. + public class PgpOnePassSignatureList + : PgpObject + { + private readonly PgpOnePassSignature[] sigs; + + public PgpOnePassSignatureList( + PgpOnePassSignature[] sigs) + { + this.sigs = (PgpOnePassSignature[]) sigs.Clone(); + } + + public PgpOnePassSignatureList( + PgpOnePassSignature sig) + { + this.sigs = new PgpOnePassSignature[]{ sig }; + } + + public PgpOnePassSignature this[int index] + { + get { return sigs[index]; } + } + + [Obsolete("Use 'object[index]' syntax instead")] + public PgpOnePassSignature Get( + int index) + { + return this[index]; + } + + [Obsolete("Use 'Count' property instead")] + public int Size + { + get { return sigs.Length; } + } + + public int Count + { + get { return sigs.Length; } + } + + public bool IsEmpty + { + get { return (sigs.Length == 0); } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpOnePassSignatureList.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpOnePassSignatureList.cs.meta new file mode 100644 index 0000000..acde891 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpOnePassSignatureList.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5028a85cbe251214382e767d80d37705 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpPad.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpPad.cs new file mode 100644 index 0000000..227e310 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpPad.cs @@ -0,0 +1,65 @@ +using System; + +namespace Org.BouncyCastle.Bcpg.OpenPgp +{ + /// Padding functions. + public sealed class PgpPad + { + private PgpPad() + { + } + + public static byte[] PadSessionData(byte[] sessionInfo) + { + return PadSessionData(sessionInfo, true); + } + + public static byte[] PadSessionData(byte[] sessionInfo, bool obfuscate) + { + int length = sessionInfo.Length; + int paddedLength = ((length >> 3) + 1) << 3; + + if (obfuscate) + { + paddedLength = System.Math.Max(40, paddedLength); + } + + int padCount = paddedLength - length; + byte padByte = (byte)padCount; + + byte[] result = new byte[paddedLength]; + Array.Copy(sessionInfo, 0, result, 0, length); + for (int i = length; i < paddedLength; ++i) + { + result[i] = padByte; + } + return result; + } + + public static byte[] UnpadSessionData(byte[] encoded) + { + int paddedLength = encoded.Length; + byte padByte = encoded[paddedLength - 1]; + int padCount = padByte; + int length = paddedLength - padCount; + int last = length - 1; + + int diff = 0; + for (int i = 0; i < paddedLength; ++i) + { + int mask = (last - i) >> 31; + diff |= (padByte ^ encoded[i]) & mask; + } + + diff |= paddedLength & 7; + diff |= (40 - paddedLength) >> 31; + + if (diff != 0) + throw new PgpException("bad padding found in session data"); + + byte[] result = new byte[length]; + Array.Copy(encoded, 0, result, 0, length); + return result; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpPad.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpPad.cs.meta new file mode 100644 index 0000000..9b25f3c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpPad.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b863784e78376d84da22099e4f6acd70 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpPbeEncryptedData.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpPbeEncryptedData.cs new file mode 100644 index 0000000..f43f2f5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpPbeEncryptedData.cs @@ -0,0 +1,160 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.IO; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Bcpg.OpenPgp +{ + /// A password based encryption object. + public class PgpPbeEncryptedData + : PgpEncryptedData + { + private readonly SymmetricKeyEncSessionPacket keyData; + + internal PgpPbeEncryptedData( + SymmetricKeyEncSessionPacket keyData, + InputStreamPacket encData) + : base(encData) + { + this.keyData = keyData; + } + + /// Return the raw input stream for the data stream. + public override Stream GetInputStream() + { + return encData.GetInputStream(); + } + + /// Return the decrypted input stream, using the passed in passphrase. + /// + /// Conversion of the passphrase characters to bytes is performed using Convert.ToByte(), which is + /// the historical behaviour of the library (1.7 and earlier). + /// + public Stream GetDataStream(char[] passPhrase) + { + return DoGetDataStream(PgpUtilities.EncodePassPhrase(passPhrase, false), true); + } + + /// Return the decrypted input stream, using the passed in passphrase. + /// + /// The passphrase is encoded to bytes using UTF8 (Encoding.UTF8.GetBytes). + /// + public Stream GetDataStreamUtf8(char[] passPhrase) + { + return DoGetDataStream(PgpUtilities.EncodePassPhrase(passPhrase, true), true); + } + + /// Return the decrypted input stream, using the passed in passphrase. + /// + /// Allows the caller to handle the encoding of the passphrase to bytes. + /// + public Stream GetDataStreamRaw(byte[] rawPassPhrase) + { + return DoGetDataStream(rawPassPhrase, false); + } + + internal Stream DoGetDataStream(byte[] rawPassPhrase, bool clearPassPhrase) + { + try + { + SymmetricKeyAlgorithmTag keyAlgorithm = keyData.EncAlgorithm; + + KeyParameter key = PgpUtilities.DoMakeKeyFromPassPhrase( + keyAlgorithm, keyData.S2k, rawPassPhrase, clearPassPhrase); + + byte[] secKeyData = keyData.GetSecKeyData(); + if (secKeyData != null && secKeyData.Length > 0) + { + IBufferedCipher keyCipher = CipherUtilities.GetCipher( + PgpUtilities.GetSymmetricCipherName(keyAlgorithm) + "/CFB/NoPadding"); + + keyCipher.Init(false, + new ParametersWithIV(key, new byte[keyCipher.GetBlockSize()])); + + byte[] keyBytes = keyCipher.DoFinal(secKeyData); + + keyAlgorithm = (SymmetricKeyAlgorithmTag) keyBytes[0]; + + key = ParameterUtilities.CreateKeyParameter( + PgpUtilities.GetSymmetricCipherName(keyAlgorithm), + keyBytes, 1, keyBytes.Length - 1); + } + + + IBufferedCipher c = CreateStreamCipher(keyAlgorithm); + + byte[] iv = new byte[c.GetBlockSize()]; + + c.Init(false, new ParametersWithIV(key, iv)); + + encStream = BcpgInputStream.Wrap(new CipherStream(encData.GetInputStream(), c, null)); + + if (encData is SymmetricEncIntegrityPacket) + { + truncStream = new TruncatedStream(encStream); + + string digestName = PgpUtilities.GetDigestName(HashAlgorithmTag.Sha1); + IDigest digest = DigestUtilities.GetDigest(digestName); + + encStream = new DigestStream(truncStream, digest, null); + } + + if (Streams.ReadFully(encStream, iv, 0, iv.Length) < iv.Length) + throw new EndOfStreamException("unexpected end of stream."); + + int v1 = encStream.ReadByte(); + int v2 = encStream.ReadByte(); + + if (v1 < 0 || v2 < 0) + throw new EndOfStreamException("unexpected end of stream."); + + + // Note: the oracle attack on the "quick check" bytes is not deemed + // a security risk for PBE (see PgpPublicKeyEncryptedData) + + bool repeatCheckPassed = + iv[iv.Length - 2] == (byte)v1 + && iv[iv.Length - 1] == (byte)v2; + + // Note: some versions of PGP appear to produce 0 for the extra + // bytes rather than repeating the two previous bytes + bool zeroesCheckPassed = + v1 == 0 + && v2 == 0; + + if (!repeatCheckPassed && !zeroesCheckPassed) + { + throw new PgpDataValidationException("quick check failed."); + } + + + return encStream; + } + catch (PgpException e) + { + throw e; + } + catch (Exception e) + { + throw new PgpException("Exception creating cipher", e); + } + } + + private IBufferedCipher CreateStreamCipher( + SymmetricKeyAlgorithmTag keyAlgorithm) + { + string mode = (encData is SymmetricEncIntegrityPacket) + ? "CFB" + : "OpenPGPCFB"; + + string cName = PgpUtilities.GetSymmetricCipherName(keyAlgorithm) + + "/" + mode + "/NoPadding"; + + return CipherUtilities.GetCipher(cName); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpPbeEncryptedData.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpPbeEncryptedData.cs.meta new file mode 100644 index 0000000..773cfda --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpPbeEncryptedData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ba0effdbcf47b964faaf5991be105d91 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpPrivateKey.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpPrivateKey.cs new file mode 100644 index 0000000..61487a5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpPrivateKey.cs @@ -0,0 +1,51 @@ +using System; + +using Org.BouncyCastle.Crypto; + +namespace Org.BouncyCastle.Bcpg.OpenPgp +{ + /// General class to contain a private key for use with other OpenPGP objects. + public class PgpPrivateKey + { + private readonly long keyID; + private readonly PublicKeyPacket publicKeyPacket; + private readonly AsymmetricKeyParameter privateKey; + + /// + /// Create a PgpPrivateKey from a keyID, the associated public data packet, and a regular private key. + /// + /// ID of the corresponding public key. + /// the public key data packet to be associated with this private key. + /// the private key data packet to be associated with this private key. + public PgpPrivateKey( + long keyID, + PublicKeyPacket publicKeyPacket, + AsymmetricKeyParameter privateKey) + { + if (!privateKey.IsPrivate) + throw new ArgumentException("Expected a private key", "privateKey"); + + this.keyID = keyID; + this.publicKeyPacket = publicKeyPacket; + this.privateKey = privateKey; + } + + /// The keyId associated with the contained private key. + public long KeyId + { + get { return keyID; } + } + + /// The public key packet associated with this private key, if available. + public PublicKeyPacket PublicKeyPacket + { + get { return publicKeyPacket; } + } + + /// The contained private key. + public AsymmetricKeyParameter Key + { + get { return privateKey; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpPrivateKey.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpPrivateKey.cs.meta new file mode 100644 index 0000000..f7f1d0c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpPrivateKey.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cc9e096763cac2c45a6131d65648304f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpPublicKey.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpPublicKey.cs new file mode 100644 index 0000000..9b8a956 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpPublicKey.cs @@ -0,0 +1,999 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1.Sec; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.IO; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Bcpg.OpenPgp +{ + /// General class to handle a PGP public key object. + public class PgpPublicKey + { + public static byte[] CalculateFingerprint(PublicKeyPacket publicPk) + { + IBcpgKey key = publicPk.Key; + IDigest digest; + + if (publicPk.Version <= 3) + { + RsaPublicBcpgKey rK = (RsaPublicBcpgKey)key; + + try + { + digest = DigestUtilities.GetDigest("MD5"); + UpdateDigest(digest, rK.Modulus); + UpdateDigest(digest, rK.PublicExponent); + } + catch (Exception e) + { + throw new PgpException("can't encode key components: " + e.Message, e); + } + } + else + { + try + { + byte[] kBytes = publicPk.GetEncodedContents(); + + digest = DigestUtilities.GetDigest("SHA1"); + + digest.Update(0x99); + digest.Update((byte)(kBytes.Length >> 8)); + digest.Update((byte)kBytes.Length); + digest.BlockUpdate(kBytes, 0, kBytes.Length); + } + catch (Exception e) + { + throw new PgpException("can't encode key components: " + e.Message, e); + } + } + + return DigestUtilities.DoFinal(digest); + } + + private static void UpdateDigest(IDigest d, BigInteger b) + { + byte[] bytes = b.ToByteArrayUnsigned(); + d.BlockUpdate(bytes, 0, bytes.Length); + } + + private static readonly int[] MasterKeyCertificationTypes = new int[] + { + PgpSignature.PositiveCertification, + PgpSignature.CasualCertification, + PgpSignature.NoCertification, + PgpSignature.DefaultCertification, + PgpSignature.DirectKey, + }; + + private long keyId; + private byte[] fingerprint; + private int keyStrength; + + internal PublicKeyPacket publicPk; + internal TrustPacket trustPk; + internal IList keySigs = Platform.CreateArrayList(); + internal IList ids = Platform.CreateArrayList(); + internal IList idTrusts = Platform.CreateArrayList(); + internal IList idSigs = Platform.CreateArrayList(); + internal IList subSigs; + + private void Init() + { + IBcpgKey key = publicPk.Key; + + this.fingerprint = CalculateFingerprint(publicPk); + + if (publicPk.Version <= 3) + { + RsaPublicBcpgKey rK = (RsaPublicBcpgKey) key; + + this.keyId = rK.Modulus.LongValue; + this.keyStrength = rK.Modulus.BitLength; + } + else + { + this.keyId = (long)(((ulong)fingerprint[fingerprint.Length - 8] << 56) + | ((ulong)fingerprint[fingerprint.Length - 7] << 48) + | ((ulong)fingerprint[fingerprint.Length - 6] << 40) + | ((ulong)fingerprint[fingerprint.Length - 5] << 32) + | ((ulong)fingerprint[fingerprint.Length - 4] << 24) + | ((ulong)fingerprint[fingerprint.Length - 3] << 16) + | ((ulong)fingerprint[fingerprint.Length - 2] << 8) + | (ulong)fingerprint[fingerprint.Length - 1]); + + if (key is RsaPublicBcpgKey) + { + this.keyStrength = ((RsaPublicBcpgKey)key).Modulus.BitLength; + } + else if (key is DsaPublicBcpgKey) + { + this.keyStrength = ((DsaPublicBcpgKey)key).P.BitLength; + } + else if (key is ElGamalPublicBcpgKey) + { + this.keyStrength = ((ElGamalPublicBcpgKey)key).P.BitLength; + } + else if (key is ECPublicBcpgKey) + { + this.keyStrength = ECKeyPairGenerator.FindECCurveByOid(((ECPublicBcpgKey)key).CurveOid).Curve.FieldSize; + } + } + } + + /// + /// Create a PgpPublicKey from the passed in lightweight one. + /// + /// + /// Note: the time passed in affects the value of the key's keyId, so you probably only want + /// to do this once for a lightweight key, or make sure you keep track of the time you used. + /// + /// Asymmetric algorithm type representing the public key. + /// Actual public key to associate. + /// Date of creation. + /// If pubKey is not public. + /// On key creation problem. + public PgpPublicKey( + PublicKeyAlgorithmTag algorithm, + AsymmetricKeyParameter pubKey, + DateTime time) + { + if (pubKey.IsPrivate) + throw new ArgumentException("Expected a public key", "pubKey"); + + IBcpgKey bcpgKey; + if (pubKey is RsaKeyParameters) + { + RsaKeyParameters rK = (RsaKeyParameters) pubKey; + + bcpgKey = new RsaPublicBcpgKey(rK.Modulus, rK.Exponent); + } + else if (pubKey is DsaPublicKeyParameters) + { + DsaPublicKeyParameters dK = (DsaPublicKeyParameters) pubKey; + DsaParameters dP = dK.Parameters; + + bcpgKey = new DsaPublicBcpgKey(dP.P, dP.Q, dP.G, dK.Y); + } + else if (pubKey is ECPublicKeyParameters) + { + ECPublicKeyParameters ecK = (ECPublicKeyParameters)pubKey; + + if (algorithm == PublicKeyAlgorithmTag.ECDH) + { + bcpgKey = new ECDHPublicBcpgKey(ecK.PublicKeyParamSet, ecK.Q, HashAlgorithmTag.Sha256, SymmetricKeyAlgorithmTag.Aes128); + } + else if (algorithm == PublicKeyAlgorithmTag.ECDsa) + { + bcpgKey = new ECDsaPublicBcpgKey(ecK.PublicKeyParamSet, ecK.Q); + } + else + { + throw new PgpException("unknown EC algorithm"); + } + } + else if (pubKey is ElGamalPublicKeyParameters) + { + ElGamalPublicKeyParameters eK = (ElGamalPublicKeyParameters) pubKey; + ElGamalParameters eS = eK.Parameters; + + bcpgKey = new ElGamalPublicBcpgKey(eS.P, eS.G, eK.Y); + } + else + { + throw new PgpException("unknown key class"); + } + + this.publicPk = new PublicKeyPacket(algorithm, time, bcpgKey); + this.ids = Platform.CreateArrayList(); + this.idSigs = Platform.CreateArrayList(); + + try + { + Init(); + } + catch (IOException e) + { + throw new PgpException("exception calculating keyId", e); + } + } + + public PgpPublicKey(PublicKeyPacket publicPk) + : this(publicPk, Platform.CreateArrayList(), Platform.CreateArrayList()) + { + } + + /// Constructor for a sub-key. + internal PgpPublicKey( + PublicKeyPacket publicPk, + TrustPacket trustPk, + IList sigs) + { + this.publicPk = publicPk; + this.trustPk = trustPk; + this.subSigs = sigs; + + Init(); + } + + internal PgpPublicKey( + PgpPublicKey key, + TrustPacket trust, + IList subSigs) + { + this.publicPk = key.publicPk; + this.trustPk = trust; + this.subSigs = subSigs; + + this.fingerprint = key.fingerprint; + this.keyId = key.keyId; + this.keyStrength = key.keyStrength; + } + + /// Copy constructor. + /// The public key to copy. + internal PgpPublicKey( + PgpPublicKey pubKey) + { + this.publicPk = pubKey.publicPk; + + this.keySigs = Platform.CreateArrayList(pubKey.keySigs); + this.ids = Platform.CreateArrayList(pubKey.ids); + this.idTrusts = Platform.CreateArrayList(pubKey.idTrusts); + this.idSigs = Platform.CreateArrayList(pubKey.idSigs.Count); + for (int i = 0; i != pubKey.idSigs.Count; i++) + { + this.idSigs.Add(Platform.CreateArrayList((IList)pubKey.idSigs[i])); + } + + if (pubKey.subSigs != null) + { + this.subSigs = Platform.CreateArrayList(pubKey.subSigs.Count); + for (int i = 0; i != pubKey.subSigs.Count; i++) + { + this.subSigs.Add(pubKey.subSigs[i]); + } + } + + this.fingerprint = pubKey.fingerprint; + this.keyId = pubKey.keyId; + this.keyStrength = pubKey.keyStrength; + } + + internal PgpPublicKey( + PublicKeyPacket publicPk, + TrustPacket trustPk, + IList keySigs, + IList ids, + IList idTrusts, + IList idSigs) + { + this.publicPk = publicPk; + this.trustPk = trustPk; + this.keySigs = keySigs; + this.ids = ids; + this.idTrusts = idTrusts; + this.idSigs = idSigs; + + Init(); + } + + internal PgpPublicKey( + PublicKeyPacket publicPk, + IList ids, + IList idSigs) + { + this.publicPk = publicPk; + this.ids = ids; + this.idSigs = idSigs; + Init(); + } + + /// The version of this key. + public int Version + { + get { return publicPk.Version; } + } + + /// The creation time of this key. + public DateTime CreationTime + { + get { return publicPk.GetTime(); } + } + + /// The number of valid days from creation time - zero means no expiry. + /// WARNING: This method will return 1 for keys with version > 3 that expire in less than 1 day + [Obsolete("Use 'GetValidSeconds' instead")] + public int ValidDays + { + get + { + if (publicPk.Version <= 3) + { + return publicPk.ValidDays; + } + + long expSecs = GetValidSeconds(); + if (expSecs <= 0) + return 0; + + int days = (int)(expSecs / (24 * 60 * 60)); + return System.Math.Max(1, days); + } + } + + /// Return the trust data associated with the public key, if present. + /// A byte array with trust data, null otherwise. + public byte[] GetTrustData() + { + if (trustPk == null) + { + return null; + } + + return Arrays.Clone(trustPk.GetLevelAndTrustAmount()); + } + + /// The number of valid seconds from creation time - zero means no expiry. + public long GetValidSeconds() + { + if (publicPk.Version <= 3) + { + return (long)publicPk.ValidDays * (24 * 60 * 60); + } + + if (IsMasterKey) + { + for (int i = 0; i != MasterKeyCertificationTypes.Length; i++) + { + long seconds = GetExpirationTimeFromSig(true, MasterKeyCertificationTypes[i]); + if (seconds >= 0) + { + return seconds; + } + } + } + else + { + long seconds = GetExpirationTimeFromSig(false, PgpSignature.SubkeyBinding); + if (seconds >= 0) + { + return seconds; + } + + seconds = GetExpirationTimeFromSig(false, PgpSignature.DirectKey); + if (seconds >= 0) + { + return seconds; + } + } + + return 0; + } + + private long GetExpirationTimeFromSig(bool selfSigned, int signatureType) + { + long expiryTime = -1; + long lastDate = -1; + + foreach (PgpSignature sig in GetSignaturesOfType(signatureType)) + { + if (selfSigned && sig.KeyId != this.KeyId) + continue; + + PgpSignatureSubpacketVector hashed = sig.GetHashedSubPackets(); + if (hashed == null) + continue; + + if (!hashed.HasSubpacket(SignatureSubpacketTag.KeyExpireTime)) + continue; + + long current = hashed.GetKeyExpirationTime(); + + if (sig.KeyId == this.KeyId) + { + if (sig.CreationTime.Ticks > lastDate) + { + lastDate = sig.CreationTime.Ticks; + expiryTime = current; + } + } + else if (current == 0 || current > expiryTime) + { + expiryTime = current; + } + } + + return expiryTime; + } + + /// The keyId associated with the public key. + public long KeyId + { + get { return keyId; } + } + + /// The fingerprint of the key + public byte[] GetFingerprint() + { + return (byte[]) fingerprint.Clone(); + } + + /// + /// Check if this key has an algorithm type that makes it suitable to use for encryption. + /// + /// + /// Note: with version 4 keys KeyFlags subpackets should also be considered when present for + /// determining the preferred use of the key. + /// + /// + /// true if this key algorithm is suitable for encryption. + /// + public bool IsEncryptionKey + { + get + { + switch (publicPk.Algorithm) + { + case PublicKeyAlgorithmTag.ECDH: + case PublicKeyAlgorithmTag.ElGamalEncrypt: + case PublicKeyAlgorithmTag.ElGamalGeneral: + case PublicKeyAlgorithmTag.RsaEncrypt: + case PublicKeyAlgorithmTag.RsaGeneral: + return true; + default: + return false; + } + } + } + + /// True, if this could be a master key. + public bool IsMasterKey + { + get { return (subSigs == null) && !(this.IsEncryptionKey && publicPk.Algorithm != PublicKeyAlgorithmTag.RsaGeneral); } + } + + /// The algorithm code associated with the public key. + public PublicKeyAlgorithmTag Algorithm + { + get { return publicPk.Algorithm; } + } + + /// The strength of the key in bits. + public int BitStrength + { + get { return keyStrength; } + } + + /// The public key contained in the object. + /// A lightweight public key. + /// If the key algorithm is not recognised. + public AsymmetricKeyParameter GetKey() + { + try + { + switch (publicPk.Algorithm) + { + case PublicKeyAlgorithmTag.RsaEncrypt: + case PublicKeyAlgorithmTag.RsaGeneral: + case PublicKeyAlgorithmTag.RsaSign: + RsaPublicBcpgKey rsaK = (RsaPublicBcpgKey)publicPk.Key; + return new RsaKeyParameters(false, rsaK.Modulus, rsaK.PublicExponent); + case PublicKeyAlgorithmTag.Dsa: + DsaPublicBcpgKey dsaK = (DsaPublicBcpgKey)publicPk.Key; + return new DsaPublicKeyParameters(dsaK.Y, new DsaParameters(dsaK.P, dsaK.Q, dsaK.G)); + case PublicKeyAlgorithmTag.ECDsa: + return GetECKey("ECDSA"); + case PublicKeyAlgorithmTag.ECDH: + return GetECKey("ECDH"); + case PublicKeyAlgorithmTag.ElGamalEncrypt: + case PublicKeyAlgorithmTag.ElGamalGeneral: + ElGamalPublicBcpgKey elK = (ElGamalPublicBcpgKey)publicPk.Key; + return new ElGamalPublicKeyParameters(elK.Y, new ElGamalParameters(elK.P, elK.G)); + default: + throw new PgpException("unknown public key algorithm encountered"); + } + } + catch (PgpException e) + { + throw e; + } + catch (Exception e) + { + throw new PgpException("exception constructing public key", e); + } + } + + private ECPublicKeyParameters GetECKey(string algorithm) + { + ECPublicBcpgKey ecK = (ECPublicBcpgKey)publicPk.Key; + X9ECParameters x9 = ECKeyPairGenerator.FindECCurveByOid(ecK.CurveOid); + ECPoint q = x9.Curve.DecodePoint(BigIntegers.AsUnsignedByteArray(ecK.EncodedPoint)); + return new ECPublicKeyParameters(algorithm, q, ecK.CurveOid); + } + + /// Allows enumeration of any user IDs associated with the key. + /// An IEnumerable of string objects. + public IEnumerable GetUserIds() + { + IList temp = Platform.CreateArrayList(); + + foreach (object o in ids) + { + if (o is string) + { + temp.Add(o); + } + } + + return new EnumerableProxy(temp); + } + + /// Allows enumeration of any user attribute vectors associated with the key. + /// An IEnumerable of PgpUserAttributeSubpacketVector objects. + public IEnumerable GetUserAttributes() + { + IList temp = Platform.CreateArrayList(); + + foreach (object o in ids) + { + if (o is PgpUserAttributeSubpacketVector) + { + temp.Add(o); + } + } + + return new EnumerableProxy(temp); + } + + /// Allows enumeration of any signatures associated with the passed in id. + /// The ID to be matched. + /// An IEnumerable of PgpSignature objects. + public IEnumerable GetSignaturesForId(string id) + { + if (id == null) + throw new ArgumentNullException("id"); + + IList signatures = Platform.CreateArrayList(); + bool userIdFound = false; + + for (int i = 0; i != ids.Count; i++) + { + if (id.Equals(ids[i])) + { + userIdFound = true; + CollectionUtilities.AddRange(signatures, (IList)idSigs[i]); + } + } + + return userIdFound ? signatures : null; + } + + /// Allows enumeration of signatures associated with the passed in user attributes. + /// The vector of user attributes to be matched. + /// An IEnumerable of PgpSignature objects. + public IEnumerable GetSignaturesForUserAttribute(PgpUserAttributeSubpacketVector userAttributes) + { + if (userAttributes == null) + throw new ArgumentNullException("userAttributes"); + + IList signatures = Platform.CreateArrayList(); + bool attributeFound = false; + + for (int i = 0; i != ids.Count; i++) + { + if (userAttributes.Equals(ids[i])) + { + attributeFound = true; + CollectionUtilities.AddRange(signatures, (IList)idSigs[i]); + } + } + + return attributeFound ? signatures : null; + } + + /// Allows enumeration of signatures of the passed in type that are on this key. + /// The type of the signature to be returned. + /// An IEnumerable of PgpSignature objects. + public IEnumerable GetSignaturesOfType( + int signatureType) + { + IList temp = Platform.CreateArrayList(); + + foreach (PgpSignature sig in GetSignatures()) + { + if (sig.SignatureType == signatureType) + { + temp.Add(sig); + } + } + + return new EnumerableProxy(temp); + } + + /// Allows enumeration of all signatures/certifications associated with this key. + /// An IEnumerable with all signatures/certifications. + public IEnumerable GetSignatures() + { + IList sigs = subSigs; + if (sigs == null) + { + sigs = Platform.CreateArrayList(keySigs); + + foreach (ICollection extraSigs in idSigs) + { + CollectionUtilities.AddRange(sigs, extraSigs); + } + } + + return new EnumerableProxy(sigs); + } + + /** + * Return all signatures/certifications directly associated with this key (ie, not to a user id). + * + * @return an iterator (possibly empty) with all signatures/certifications. + */ + public IEnumerable GetKeySignatures() + { + IList sigs = subSigs; + if (sigs == null) + { + sigs = Platform.CreateArrayList(keySigs); + } + return new EnumerableProxy(sigs); + } + + public PublicKeyPacket PublicKeyPacket + { + get { return publicPk; } + } + + public byte[] GetEncoded() + { + MemoryStream bOut = new MemoryStream(); + Encode(bOut); + return bOut.ToArray(); + } + + public void Encode( + Stream outStr) + { + BcpgOutputStream bcpgOut = BcpgOutputStream.Wrap(outStr); + + bcpgOut.WritePacket(publicPk); + if (trustPk != null) + { + bcpgOut.WritePacket(trustPk); + } + + if (subSigs == null) // not a sub-key + { + foreach (PgpSignature keySig in keySigs) + { + keySig.Encode(bcpgOut); + } + + for (int i = 0; i != ids.Count; i++) + { + if (ids[i] is string) + { + string id = (string) ids[i]; + + bcpgOut.WritePacket(new UserIdPacket(id)); + } + else + { + PgpUserAttributeSubpacketVector v = (PgpUserAttributeSubpacketVector)ids[i]; + bcpgOut.WritePacket(new UserAttributePacket(v.ToSubpacketArray())); + } + + if (idTrusts[i] != null) + { + bcpgOut.WritePacket((ContainedPacket)idTrusts[i]); + } + + foreach (PgpSignature sig in (IList) idSigs[i]) + { + sig.Encode(bcpgOut); + } + } + } + else + { + foreach (PgpSignature subSig in subSigs) + { + subSig.Encode(bcpgOut); + } + } + } + + /// Check whether this (sub)key has a revocation signature on it. + /// True, if this (sub)key has been revoked. + public bool IsRevoked() + { + int ns = 0; + bool revoked = false; + if (IsMasterKey) // Master key + { + while (!revoked && (ns < keySigs.Count)) + { + if (((PgpSignature)keySigs[ns++]).SignatureType == PgpSignature.KeyRevocation) + { + revoked = true; + } + } + } + else // Sub-key + { + while (!revoked && (ns < subSigs.Count)) + { + if (((PgpSignature)subSigs[ns++]).SignatureType == PgpSignature.SubkeyRevocation) + { + revoked = true; + } + } + } + return revoked; + } + + /// Add a certification for an id to the given public key. + /// The key the certification is to be added to. + /// The ID the certification is associated with. + /// The new certification. + /// The re-certified key. + public static PgpPublicKey AddCertification( + PgpPublicKey key, + string id, + PgpSignature certification) + { + return AddCert(key, id, certification); + } + + /// Add a certification for the given UserAttributeSubpackets to the given public key. + /// The key the certification is to be added to. + /// The attributes the certification is associated with. + /// The new certification. + /// The re-certified key. + public static PgpPublicKey AddCertification( + PgpPublicKey key, + PgpUserAttributeSubpacketVector userAttributes, + PgpSignature certification) + { + return AddCert(key, userAttributes, certification); + } + + private static PgpPublicKey AddCert( + PgpPublicKey key, + object id, + PgpSignature certification) + { + PgpPublicKey returnKey = new PgpPublicKey(key); + IList sigList = null; + + for (int i = 0; i != returnKey.ids.Count; i++) + { + if (id.Equals(returnKey.ids[i])) + { + sigList = (IList) returnKey.idSigs[i]; + } + } + + if (sigList != null) + { + sigList.Add(certification); + } + else + { + sigList = Platform.CreateArrayList(); + sigList.Add(certification); + returnKey.ids.Add(id); + returnKey.idTrusts.Add(null); + returnKey.idSigs.Add(sigList); + } + + return returnKey; + } + + /// + /// Remove any certifications associated with a user attribute subpacket on a key. + /// + /// The key the certifications are to be removed from. + /// The attributes to be removed. + /// + /// The re-certified key, or null if the user attribute subpacket was not found on the key. + /// + public static PgpPublicKey RemoveCertification( + PgpPublicKey key, + PgpUserAttributeSubpacketVector userAttributes) + { + return RemoveCert(key, userAttributes); + } + + /// Remove any certifications associated with a given ID on a key. + /// The key the certifications are to be removed from. + /// The ID that is to be removed. + /// The re-certified key, or null if the ID was not found on the key. + public static PgpPublicKey RemoveCertification( + PgpPublicKey key, + string id) + { + return RemoveCert(key, id); + } + + private static PgpPublicKey RemoveCert( + PgpPublicKey key, + object id) + { + PgpPublicKey returnKey = new PgpPublicKey(key); + bool found = false; + + for (int i = 0; i < returnKey.ids.Count; i++) + { + if (id.Equals(returnKey.ids[i])) + { + found = true; + returnKey.ids.RemoveAt(i); + returnKey.idTrusts.RemoveAt(i); + returnKey.idSigs.RemoveAt(i); + } + } + + return found ? returnKey : null; + } + + /// Remove a certification associated with a given ID on a key. + /// The key the certifications are to be removed from. + /// The ID that the certfication is to be removed from. + /// The certfication to be removed. + /// The re-certified key, or null if the certification was not found. + public static PgpPublicKey RemoveCertification( + PgpPublicKey key, + string id, + PgpSignature certification) + { + return RemoveCert(key, id, certification); + } + + /// Remove a certification associated with a given user attributes on a key. + /// The key the certifications are to be removed from. + /// The user attributes that the certfication is to be removed from. + /// The certification to be removed. + /// The re-certified key, or null if the certification was not found. + public static PgpPublicKey RemoveCertification( + PgpPublicKey key, + PgpUserAttributeSubpacketVector userAttributes, + PgpSignature certification) + { + return RemoveCert(key, userAttributes, certification); + } + + private static PgpPublicKey RemoveCert( + PgpPublicKey key, + object id, + PgpSignature certification) + { + PgpPublicKey returnKey = new PgpPublicKey(key); + bool found = false; + + for (int i = 0; i < returnKey.ids.Count; i++) + { + if (id.Equals(returnKey.ids[i])) + { + IList certs = (IList) returnKey.idSigs[i]; + found = certs.Contains(certification); + + if (found) + { + certs.Remove(certification); + } + } + } + + return found ? returnKey : null; + } + + /// Add a revocation or some other key certification to a key. + /// The key the revocation is to be added to. + /// The key signature to be added. + /// The new changed public key object. + public static PgpPublicKey AddCertification( + PgpPublicKey key, + PgpSignature certification) + { + if (key.IsMasterKey) + { + if (certification.SignatureType == PgpSignature.SubkeyRevocation) + { + throw new ArgumentException("signature type incorrect for master key revocation."); + } + } + else + { + if (certification.SignatureType == PgpSignature.KeyRevocation) + { + throw new ArgumentException("signature type incorrect for sub-key revocation."); + } + } + + PgpPublicKey returnKey = new PgpPublicKey(key); + + if (returnKey.subSigs != null) + { + returnKey.subSigs.Add(certification); + } + else + { + returnKey.keySigs.Add(certification); + } + + return returnKey; + } + + /// Remove a certification from the key. + /// The key the certifications are to be removed from. + /// The certfication to be removed. + /// The modified key, null if the certification was not found. + public static PgpPublicKey RemoveCertification( + PgpPublicKey key, + PgpSignature certification) + { + PgpPublicKey returnKey = new PgpPublicKey(key); + IList sigs = returnKey.subSigs != null + ? returnKey.subSigs + : returnKey.keySigs; + +// bool found = sigs.Remove(certification); + int pos = sigs.IndexOf(certification); + bool found = pos >= 0; + + if (found) + { + sigs.RemoveAt(pos); + } + else + { + foreach (String id in key.GetUserIds()) + { + foreach (object sig in key.GetSignaturesForId(id)) + { + // TODO Is this the right type of equality test? + if (certification == sig) + { + found = true; + returnKey = PgpPublicKey.RemoveCertification(returnKey, id, certification); + } + } + } + + if (!found) + { + foreach (PgpUserAttributeSubpacketVector id in key.GetUserAttributes()) + { + foreach (object sig in key.GetSignaturesForUserAttribute(id)) + { + // TODO Is this the right type of equality test? + if (certification == sig) + { + found = true; + returnKey = PgpPublicKey.RemoveCertification(returnKey, id, certification); + } + } + } + } + } + + return returnKey; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpPublicKey.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpPublicKey.cs.meta new file mode 100644 index 0000000..d6bc213 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpPublicKey.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 64c1f1401222fbd4d9791b77aff50976 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpPublicKeyEncryptedData.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpPublicKeyEncryptedData.cs new file mode 100644 index 0000000..04fe3ad --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpPublicKeyEncryptedData.cs @@ -0,0 +1,277 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.IO; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Bcpg.OpenPgp +{ + /// A public key encrypted data object. + public class PgpPublicKeyEncryptedData + : PgpEncryptedData + { + private PublicKeyEncSessionPacket keyData; + + internal PgpPublicKeyEncryptedData( + PublicKeyEncSessionPacket keyData, + InputStreamPacket encData) + : base(encData) + { + this.keyData = keyData; + } + + private static IBufferedCipher GetKeyCipher( + PublicKeyAlgorithmTag algorithm) + { + try + { + switch (algorithm) + { + case PublicKeyAlgorithmTag.RsaEncrypt: + case PublicKeyAlgorithmTag.RsaGeneral: + return CipherUtilities.GetCipher("RSA//PKCS1Padding"); + case PublicKeyAlgorithmTag.ElGamalEncrypt: + case PublicKeyAlgorithmTag.ElGamalGeneral: + return CipherUtilities.GetCipher("ElGamal/ECB/PKCS1Padding"); + default: + throw new PgpException("unknown asymmetric algorithm: " + algorithm); + } + } + catch (PgpException e) + { + throw e; + } + catch (Exception e) + { + throw new PgpException("Exception creating cipher", e); + } + } + + private bool ConfirmCheckSum( + byte[] sessionInfo) + { + int check = 0; + + for (int i = 1; i != sessionInfo.Length - 2; i++) + { + check += sessionInfo[i] & 0xff; + } + + return (sessionInfo[sessionInfo.Length - 2] == (byte)(check >> 8)) + && (sessionInfo[sessionInfo.Length - 1] == (byte)(check)); + } + + /// The key ID for the key used to encrypt the data. + public long KeyId + { + get { return keyData.KeyId; } + } + + /// + /// Return the algorithm code for the symmetric algorithm used to encrypt the data. + /// + public SymmetricKeyAlgorithmTag GetSymmetricAlgorithm( + PgpPrivateKey privKey) + { + byte[] sessionData = RecoverSessionData(privKey); + + return (SymmetricKeyAlgorithmTag)sessionData[0]; + } + + /// Return the decrypted data stream for the packet. + public Stream GetDataStream( + PgpPrivateKey privKey) + { + byte[] sessionData = RecoverSessionData(privKey); + + if (!ConfirmCheckSum(sessionData)) + throw new PgpKeyValidationException("key checksum failed"); + + SymmetricKeyAlgorithmTag symmAlg = (SymmetricKeyAlgorithmTag)sessionData[0]; + if (symmAlg == SymmetricKeyAlgorithmTag.Null) + return encData.GetInputStream(); + + IBufferedCipher cipher; + string cipherName = PgpUtilities.GetSymmetricCipherName(symmAlg); + string cName = cipherName; + + try + { + if (encData is SymmetricEncIntegrityPacket) + { + cName += "/CFB/NoPadding"; + } + else + { + cName += "/OpenPGPCFB/NoPadding"; + } + + cipher = CipherUtilities.GetCipher(cName); + } + catch (PgpException e) + { + throw e; + } + catch (Exception e) + { + throw new PgpException("exception creating cipher", e); + } + + try + { + KeyParameter key = ParameterUtilities.CreateKeyParameter( + cipherName, sessionData, 1, sessionData.Length - 3); + + byte[] iv = new byte[cipher.GetBlockSize()]; + + cipher.Init(false, new ParametersWithIV(key, iv)); + + encStream = BcpgInputStream.Wrap(new CipherStream(encData.GetInputStream(), cipher, null)); + + if (encData is SymmetricEncIntegrityPacket) + { + truncStream = new TruncatedStream(encStream); + + string digestName = PgpUtilities.GetDigestName(HashAlgorithmTag.Sha1); + IDigest digest = DigestUtilities.GetDigest(digestName); + + encStream = new DigestStream(truncStream, digest, null); + } + + if (Streams.ReadFully(encStream, iv, 0, iv.Length) < iv.Length) + throw new EndOfStreamException("unexpected end of stream."); + + int v1 = encStream.ReadByte(); + int v2 = encStream.ReadByte(); + + if (v1 < 0 || v2 < 0) + throw new EndOfStreamException("unexpected end of stream."); + + // Note: the oracle attack on the "quick check" bytes is deemed + // a security risk for typical public key encryption usages, + // therefore we do not perform the check. + +// bool repeatCheckPassed = +// iv[iv.Length - 2] == (byte)v1 +// && iv[iv.Length - 1] == (byte)v2; +// +// // Note: some versions of PGP appear to produce 0 for the extra +// // bytes rather than repeating the two previous bytes +// bool zeroesCheckPassed = +// v1 == 0 +// && v2 == 0; +// +// if (!repeatCheckPassed && !zeroesCheckPassed) +// { +// throw new PgpDataValidationException("quick check failed."); +// } + + return encStream; + } + catch (PgpException e) + { + throw e; + } + catch (Exception e) + { + throw new PgpException("Exception starting decryption", e); + } + } + + private byte[] RecoverSessionData(PgpPrivateKey privKey) + { + byte[][] secKeyData = keyData.GetEncSessionKey(); + + if (keyData.Algorithm == PublicKeyAlgorithmTag.ECDH) + { + ECDHPublicBcpgKey ecKey = (ECDHPublicBcpgKey)privKey.PublicKeyPacket.Key; + X9ECParameters x9Params = ECKeyPairGenerator.FindECCurveByOid(ecKey.CurveOid); + + byte[] enc = secKeyData[0]; + + int pLen = ((((enc[0] & 0xff) << 8) + (enc[1] & 0xff)) + 7) / 8; + if ((2 + pLen + 1) > enc.Length) + throw new PgpException("encoded length out of range"); + + byte[] pEnc = new byte[pLen]; + Array.Copy(enc, 2, pEnc, 0, pLen); + + int keyLen = enc[pLen + 2]; + if ((2 + pLen + 1 + keyLen) > enc.Length) + throw new PgpException("encoded length out of range"); + + byte[] keyEnc = new byte[keyLen]; + Array.Copy(enc, 2 + pLen + 1, keyEnc, 0, keyEnc.Length); + + ECPoint publicPoint = x9Params.Curve.DecodePoint(pEnc); + + ECPrivateKeyParameters privKeyParams = (ECPrivateKeyParameters)privKey.Key; + ECPoint S = publicPoint.Multiply(privKeyParams.D).Normalize(); + + KeyParameter key = new KeyParameter(Rfc6637Utilities.CreateKey(privKey.PublicKeyPacket, S)); + + IWrapper w = PgpUtilities.CreateWrapper(ecKey.SymmetricKeyAlgorithm); + w.Init(false, key); + + return PgpPad.UnpadSessionData(w.Unwrap(keyEnc, 0, keyEnc.Length)); + } + + IBufferedCipher cipher = GetKeyCipher(keyData.Algorithm); + + try + { + cipher.Init(false, privKey.Key); + } + catch (InvalidKeyException e) + { + throw new PgpException("error setting asymmetric cipher", e); + } + + if (keyData.Algorithm == PublicKeyAlgorithmTag.RsaEncrypt + || keyData.Algorithm == PublicKeyAlgorithmTag.RsaGeneral) + { + byte[] bi = secKeyData[0]; + + cipher.ProcessBytes(bi, 2, bi.Length - 2); + } + else + { + ElGamalPrivateKeyParameters k = (ElGamalPrivateKeyParameters)privKey.Key; + int size = (k.Parameters.P.BitLength + 7) / 8; + + ProcessEncodedMpi(cipher, size, secKeyData[0]); + ProcessEncodedMpi(cipher, size, secKeyData[1]); + } + + try + { + return cipher.DoFinal(); + } + catch (Exception e) + { + throw new PgpException("exception decrypting secret key", e); + } + } + + private static void ProcessEncodedMpi(IBufferedCipher cipher, int size, byte[] mpiEnc) + { + if (mpiEnc.Length - 2 > size) // leading Zero? Shouldn't happen but... + { + cipher.ProcessBytes(mpiEnc, 3, mpiEnc.Length - 3); + } + else + { + byte[] tmp = new byte[size]; + Array.Copy(mpiEnc, 2, tmp, tmp.Length - (mpiEnc.Length - 2), mpiEnc.Length - 2); + cipher.ProcessBytes(tmp, 0, tmp.Length); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpPublicKeyEncryptedData.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpPublicKeyEncryptedData.cs.meta new file mode 100644 index 0000000..aef9e1f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpPublicKeyEncryptedData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: db43eff165c8a624ca4f0abc0e42c9d2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpPublicKeyRing.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpPublicKeyRing.cs new file mode 100644 index 0000000..b35e014 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpPublicKeyRing.cs @@ -0,0 +1,209 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Bcpg.OpenPgp +{ + /// + /// Class to hold a single master public key and its subkeys. + ///

    + /// Often PGP keyring files consist of multiple master keys, if you are trying to process + /// or construct one of these you should use the PgpPublicKeyRingBundle class. + ///

    + ///
    + public class PgpPublicKeyRing + : PgpKeyRing + { + private readonly IList keys; + + public PgpPublicKeyRing( + byte[] encoding) + : this(new MemoryStream(encoding, false)) + { + } + + internal PgpPublicKeyRing( + IList pubKeys) + { + this.keys = pubKeys; + } + + public PgpPublicKeyRing( + Stream inputStream) + { + this.keys = Platform.CreateArrayList(); + + BcpgInputStream bcpgInput = BcpgInputStream.Wrap(inputStream); + + PacketTag initialTag = bcpgInput.SkipMarkerPackets(); + if (initialTag != PacketTag.PublicKey && initialTag != PacketTag.PublicSubkey) + { + throw new IOException("public key ring doesn't start with public key tag: " + + "tag 0x" + ((int)initialTag).ToString("X")); + } + + PublicKeyPacket pubPk = ReadPublicKeyPacket(bcpgInput); + TrustPacket trustPk = ReadOptionalTrustPacket(bcpgInput); + + // direct signatures and revocations + IList keySigs = ReadSignaturesAndTrust(bcpgInput); + + IList ids, idTrusts, idSigs; + ReadUserIDs(bcpgInput, out ids, out idTrusts, out idSigs); + + keys.Add(new PgpPublicKey(pubPk, trustPk, keySigs, ids, idTrusts, idSigs)); + + + // Read subkeys + while (bcpgInput.NextPacketTag() == PacketTag.PublicSubkey) + { + keys.Add(ReadSubkey(bcpgInput)); + } + } + + /// Return the first public key in the ring. + public virtual PgpPublicKey GetPublicKey() + { + return (PgpPublicKey) keys[0]; + } + + /// Return the public key referred to by the passed in key ID if it is present. + public virtual PgpPublicKey GetPublicKey( + long keyId) + { + foreach (PgpPublicKey k in keys) + { + if (keyId == k.KeyId) + { + return k; + } + } + + return null; + } + + /// Allows enumeration of all the public keys. + /// An IEnumerable of PgpPublicKey objects. + public virtual IEnumerable GetPublicKeys() + { + return new EnumerableProxy(keys); + } + + public virtual byte[] GetEncoded() + { + MemoryStream bOut = new MemoryStream(); + + Encode(bOut); + + return bOut.ToArray(); + } + + public virtual void Encode( + Stream outStr) + { + if (outStr == null) + throw new ArgumentNullException("outStr"); + + foreach (PgpPublicKey k in keys) + { + k.Encode(outStr); + } + } + + /// + /// Returns a new key ring with the public key passed in either added or + /// replacing an existing one. + /// + /// The public key ring to be modified. + /// The public key to be inserted. + /// A new PgpPublicKeyRing + public static PgpPublicKeyRing InsertPublicKey( + PgpPublicKeyRing pubRing, + PgpPublicKey pubKey) + { + IList keys = Platform.CreateArrayList(pubRing.keys); + bool found = false; + bool masterFound = false; + + for (int i = 0; i != keys.Count; i++) + { + PgpPublicKey key = (PgpPublicKey) keys[i]; + + if (key.KeyId == pubKey.KeyId) + { + found = true; + keys[i] = pubKey; + } + if (key.IsMasterKey) + { + masterFound = true; + } + } + + if (!found) + { + if (pubKey.IsMasterKey) + { + if (masterFound) + throw new ArgumentException("cannot add a master key to a ring that already has one"); + + keys.Insert(0, pubKey); + } + else + { + keys.Add(pubKey); + } + } + + return new PgpPublicKeyRing(keys); + } + + /// Returns a new key ring with the public key passed in removed from the key ring. + /// The public key ring to be modified. + /// The public key to be removed. + /// A new PgpPublicKeyRing, or null if pubKey is not found. + public static PgpPublicKeyRing RemovePublicKey( + PgpPublicKeyRing pubRing, + PgpPublicKey pubKey) + { + IList keys = Platform.CreateArrayList(pubRing.keys); + bool found = false; + + for (int i = 0; i < keys.Count; i++) + { + PgpPublicKey key = (PgpPublicKey) keys[i]; + + if (key.KeyId == pubKey.KeyId) + { + found = true; + keys.RemoveAt(i); + } + } + + return found ? new PgpPublicKeyRing(keys) : null; + } + + internal static PublicKeyPacket ReadPublicKeyPacket(BcpgInputStream bcpgInput) + { + Packet packet = bcpgInput.ReadPacket(); + if (!(packet is PublicKeyPacket)) + throw new IOException("unexpected packet in stream: " + packet); + + return (PublicKeyPacket)packet; + } + + internal static PgpPublicKey ReadSubkey(BcpgInputStream bcpgInput) + { + PublicKeyPacket pk = ReadPublicKeyPacket(bcpgInput); + TrustPacket kTrust = ReadOptionalTrustPacket(bcpgInput); + + // PGP 8 actually leaves out the signature. + IList sigList = ReadSignaturesAndTrust(bcpgInput); + + return new PgpPublicKey(pk, kTrust, sigList); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpPublicKeyRing.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpPublicKeyRing.cs.meta new file mode 100644 index 0000000..ba969b1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpPublicKeyRing.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e219dd4d3eb7c8040ba18e1e5ac80d20 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpPublicKeyRingBundle.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpPublicKeyRingBundle.cs new file mode 100644 index 0000000..08d0aa0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpPublicKeyRingBundle.cs @@ -0,0 +1,280 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Bcpg.OpenPgp +{ + /// + /// Often a PGP key ring file is made up of a succession of master/sub-key key rings. + /// If you want to read an entire public key file in one hit this is the class for you. + /// + public class PgpPublicKeyRingBundle + { + private readonly IDictionary pubRings; + private readonly IList order; + + private PgpPublicKeyRingBundle( + IDictionary pubRings, + IList order) + { + this.pubRings = pubRings; + this.order = order; + } + + public PgpPublicKeyRingBundle( + byte[] encoding) + : this(new MemoryStream(encoding, false)) + { + } + + /// Build a PgpPublicKeyRingBundle from the passed in input stream. + /// Input stream containing data. + /// If a problem parsing the stream occurs. + /// If an object is encountered which isn't a PgpPublicKeyRing. + public PgpPublicKeyRingBundle( + Stream inputStream) + : this(new PgpObjectFactory(inputStream).AllPgpObjects()) + { + } + + public PgpPublicKeyRingBundle( + IEnumerable e) + { + this.pubRings = Platform.CreateHashtable(); + this.order = Platform.CreateArrayList(); + + foreach (object obj in e) + { + // Marker packets must be ignored + if (obj is PgpMarker) + continue; + + PgpPublicKeyRing pgpPub = obj as PgpPublicKeyRing; + if (pgpPub == null) + throw new PgpException(Platform.GetTypeName(obj) + " found where PgpPublicKeyRing expected"); + + long key = pgpPub.GetPublicKey().KeyId; + pubRings.Add(key, pgpPub); + order.Add(key); + } + } + + [Obsolete("Use 'Count' property instead")] + public int Size + { + get { return order.Count; } + } + + /// Return the number of key rings in this collection. + public int Count + { + get { return order.Count; } + } + + /// Allow enumeration of the public key rings making up this collection. + public IEnumerable GetKeyRings() + { + return new EnumerableProxy(pubRings.Values); + } + + /// Allow enumeration of the key rings associated with the passed in userId. + /// The user ID to be matched. + /// An IEnumerable of key rings which matched (possibly none). + public IEnumerable GetKeyRings( + string userId) + { + return GetKeyRings(userId, false, false); + } + + /// Allow enumeration of the key rings associated with the passed in userId. + /// The user ID to be matched. + /// If true, userId need only be a substring of an actual ID string to match. + /// An IEnumerable of key rings which matched (possibly none). + public IEnumerable GetKeyRings( + string userId, + bool matchPartial) + { + return GetKeyRings(userId, matchPartial, false); + } + + /// Allow enumeration of the key rings associated with the passed in userId. + /// The user ID to be matched. + /// If true, userId need only be a substring of an actual ID string to match. + /// If true, case is ignored in user ID comparisons. + /// An IEnumerable of key rings which matched (possibly none). + public IEnumerable GetKeyRings( + string userId, + bool matchPartial, + bool ignoreCase) + { + IList rings = Platform.CreateArrayList(); + + if (ignoreCase) + { + userId = Platform.ToUpperInvariant(userId); + } + + foreach (PgpPublicKeyRing pubRing in GetKeyRings()) + { + foreach (string nextUserID in pubRing.GetPublicKey().GetUserIds()) + { + string next = nextUserID; + if (ignoreCase) + { + next = Platform.ToUpperInvariant(next); + } + + if (matchPartial) + { + if (Platform.IndexOf(next, userId) > -1) + { + rings.Add(pubRing); + } + } + else + { + if (next.Equals(userId)) + { + rings.Add(pubRing); + } + } + } + } + + return new EnumerableProxy(rings); + } + + /// Return the PGP public key associated with the given key id. + /// The ID of the public key to return. + public PgpPublicKey GetPublicKey( + long keyId) + { + foreach (PgpPublicKeyRing pubRing in GetKeyRings()) + { + PgpPublicKey pub = pubRing.GetPublicKey(keyId); + + if (pub != null) + { + return pub; + } + } + + return null; + } + + /// Return the public key ring which contains the key referred to by keyId + /// key ID to match against + public PgpPublicKeyRing GetPublicKeyRing( + long keyId) + { + if (pubRings.Contains(keyId)) + { + return (PgpPublicKeyRing)pubRings[keyId]; + } + + foreach (PgpPublicKeyRing pubRing in GetKeyRings()) + { + PgpPublicKey pub = pubRing.GetPublicKey(keyId); + + if (pub != null) + { + return pubRing; + } + } + + return null; + } + + /// + /// Return true if a key matching the passed in key ID is present, false otherwise. + /// + /// key ID to look for. + public bool Contains( + long keyID) + { + return GetPublicKey(keyID) != null; + } + + public byte[] GetEncoded() + { + MemoryStream bOut = new MemoryStream(); + + Encode(bOut); + + return bOut.ToArray(); + } + + public void Encode( + Stream outStr) + { + BcpgOutputStream bcpgOut = BcpgOutputStream.Wrap(outStr); + + foreach (long key in order) + { + PgpPublicKeyRing sec = (PgpPublicKeyRing) pubRings[key]; + + sec.Encode(bcpgOut); + } + } + + /// + /// Return a new bundle containing the contents of the passed in bundle and + /// the passed in public key ring. + /// + /// The PgpPublicKeyRingBundle the key ring is to be added to. + /// The key ring to be added. + /// A new PgpPublicKeyRingBundle merging the current one with the passed in key ring. + /// If the keyId for the passed in key ring is already present. + public static PgpPublicKeyRingBundle AddPublicKeyRing( + PgpPublicKeyRingBundle bundle, + PgpPublicKeyRing publicKeyRing) + { + long key = publicKeyRing.GetPublicKey().KeyId; + + if (bundle.pubRings.Contains(key)) + { + throw new ArgumentException("Bundle already contains a key with a keyId for the passed in ring."); + } + + IDictionary newPubRings = Platform.CreateHashtable(bundle.pubRings); + IList newOrder = Platform.CreateArrayList(bundle.order); + + newPubRings[key] = publicKeyRing; + + newOrder.Add(key); + + return new PgpPublicKeyRingBundle(newPubRings, newOrder); + } + + /// + /// Return a new bundle containing the contents of the passed in bundle with + /// the passed in public key ring removed. + /// + /// The PgpPublicKeyRingBundle the key ring is to be removed from. + /// The key ring to be removed. + /// A new PgpPublicKeyRingBundle not containing the passed in key ring. + /// If the keyId for the passed in key ring is not present. + public static PgpPublicKeyRingBundle RemovePublicKeyRing( + PgpPublicKeyRingBundle bundle, + PgpPublicKeyRing publicKeyRing) + { + long key = publicKeyRing.GetPublicKey().KeyId; + + if (!bundle.pubRings.Contains(key)) + { + throw new ArgumentException("Bundle does not contain a key with a keyId for the passed in ring."); + } + + IDictionary newPubRings = Platform.CreateHashtable(bundle.pubRings); + IList newOrder = Platform.CreateArrayList(bundle.order); + + newPubRings.Remove(key); + newOrder.Remove(key); + + return new PgpPublicKeyRingBundle(newPubRings, newOrder); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpPublicKeyRingBundle.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpPublicKeyRingBundle.cs.meta new file mode 100644 index 0000000..567c773 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpPublicKeyRingBundle.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2498336dd769e4c4198fad65ec3abfb7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpSecretKey.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpSecretKey.cs new file mode 100644 index 0000000..a3ffd4a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpSecretKey.cs @@ -0,0 +1,1302 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Bcpg.OpenPgp +{ + /// General class to handle a PGP secret key object. + public class PgpSecretKey + { + private readonly SecretKeyPacket secret; + private readonly PgpPublicKey pub; + + internal PgpSecretKey( + SecretKeyPacket secret, + PgpPublicKey pub) + { + this.secret = secret; + this.pub = pub; + } + + internal PgpSecretKey( + PgpPrivateKey privKey, + PgpPublicKey pubKey, + SymmetricKeyAlgorithmTag encAlgorithm, + byte[] rawPassPhrase, + bool clearPassPhrase, + bool useSha1, + SecureRandom rand, + bool isMasterKey) + { + BcpgObject secKey; + + this.pub = pubKey; + + switch (pubKey.Algorithm) + { + case PublicKeyAlgorithmTag.RsaEncrypt: + case PublicKeyAlgorithmTag.RsaSign: + case PublicKeyAlgorithmTag.RsaGeneral: + RsaPrivateCrtKeyParameters rsK = (RsaPrivateCrtKeyParameters) privKey.Key; + secKey = new RsaSecretBcpgKey(rsK.Exponent, rsK.P, rsK.Q); + break; + case PublicKeyAlgorithmTag.Dsa: + DsaPrivateKeyParameters dsK = (DsaPrivateKeyParameters) privKey.Key; + secKey = new DsaSecretBcpgKey(dsK.X); + break; + case PublicKeyAlgorithmTag.ECDH: + case PublicKeyAlgorithmTag.ECDsa: + ECPrivateKeyParameters ecK = (ECPrivateKeyParameters)privKey.Key; + secKey = new ECSecretBcpgKey(ecK.D); + break; + case PublicKeyAlgorithmTag.ElGamalEncrypt: + case PublicKeyAlgorithmTag.ElGamalGeneral: + ElGamalPrivateKeyParameters esK = (ElGamalPrivateKeyParameters) privKey.Key; + secKey = new ElGamalSecretBcpgKey(esK.X); + break; + default: + throw new PgpException("unknown key class"); + } + + try + { + MemoryStream bOut = new MemoryStream(); + BcpgOutputStream pOut = new BcpgOutputStream(bOut); + + pOut.WriteObject(secKey); + + byte[] keyData = bOut.ToArray(); + byte[] checksumData = Checksum(useSha1, keyData, keyData.Length); + + keyData = Arrays.Concatenate(keyData, checksumData); + + if (encAlgorithm == SymmetricKeyAlgorithmTag.Null) + { + if (isMasterKey) + { + this.secret = new SecretKeyPacket(pub.publicPk, encAlgorithm, null, null, keyData); + } + else + { + this.secret = new SecretSubkeyPacket(pub.publicPk, encAlgorithm, null, null, keyData); + } + } + else + { + S2k s2k; + byte[] iv; + + byte[] encData; + if (pub.Version >= 4) + { + encData = EncryptKeyDataV4(keyData, encAlgorithm, HashAlgorithmTag.Sha1, rawPassPhrase, clearPassPhrase, rand, out s2k, out iv); + } + else + { + encData = EncryptKeyDataV3(keyData, encAlgorithm, rawPassPhrase, clearPassPhrase, rand, out s2k, out iv); + } + + int s2kUsage = useSha1 + ? SecretKeyPacket.UsageSha1 + : SecretKeyPacket.UsageChecksum; + + if (isMasterKey) + { + this.secret = new SecretKeyPacket(pub.publicPk, encAlgorithm, s2kUsage, s2k, iv, encData); + } + else + { + this.secret = new SecretSubkeyPacket(pub.publicPk, encAlgorithm, s2kUsage, s2k, iv, encData); + } + } + } + catch (PgpException e) + { + throw e; + } + catch (Exception e) + { + throw new PgpException("Exception encrypting key", e); + } + } + + /// + /// Conversion of the passphrase characters to bytes is performed using Convert.ToByte(), which is + /// the historical behaviour of the library (1.7 and earlier). + /// + [Obsolete("Use the constructor taking an explicit 'useSha1' parameter instead")] + public PgpSecretKey( + int certificationLevel, + PgpKeyPair keyPair, + string id, + SymmetricKeyAlgorithmTag encAlgorithm, + char[] passPhrase, + PgpSignatureSubpacketVector hashedPackets, + PgpSignatureSubpacketVector unhashedPackets, + SecureRandom rand) + : this(certificationLevel, keyPair, id, encAlgorithm, passPhrase, false, hashedPackets, unhashedPackets, rand) + { + } + + /// + /// Conversion of the passphrase characters to bytes is performed using Convert.ToByte(), which is + /// the historical behaviour of the library (1.7 and earlier). + /// + public PgpSecretKey( + int certificationLevel, + PgpKeyPair keyPair, + string id, + SymmetricKeyAlgorithmTag encAlgorithm, + char[] passPhrase, + bool useSha1, + PgpSignatureSubpacketVector hashedPackets, + PgpSignatureSubpacketVector unhashedPackets, + SecureRandom rand) + : this(certificationLevel, keyPair, id, encAlgorithm, false, passPhrase, useSha1, hashedPackets, unhashedPackets, rand) + { + } + + /// + /// If utf8PassPhrase is true, conversion of the passphrase to bytes uses Encoding.UTF8.GetBytes(), otherwise the conversion + /// is performed using Convert.ToByte(), which is the historical behaviour of the library (1.7 and earlier). + /// + public PgpSecretKey( + int certificationLevel, + PgpKeyPair keyPair, + string id, + SymmetricKeyAlgorithmTag encAlgorithm, + bool utf8PassPhrase, + char[] passPhrase, + bool useSha1, + PgpSignatureSubpacketVector hashedPackets, + PgpSignatureSubpacketVector unhashedPackets, + SecureRandom rand) + : this(certificationLevel, keyPair, id, encAlgorithm, + PgpUtilities.EncodePassPhrase(passPhrase, utf8PassPhrase), true, + useSha1, hashedPackets, unhashedPackets, rand) + { + } + + /// + /// Allows the caller to handle the encoding of the passphrase to bytes. + /// + public PgpSecretKey( + int certificationLevel, + PgpKeyPair keyPair, + string id, + SymmetricKeyAlgorithmTag encAlgorithm, + byte[] rawPassPhrase, + bool useSha1, + PgpSignatureSubpacketVector hashedPackets, + PgpSignatureSubpacketVector unhashedPackets, + SecureRandom rand) + : this(certificationLevel, keyPair, id, encAlgorithm, rawPassPhrase, false, useSha1, hashedPackets, unhashedPackets, rand) + { + } + + internal PgpSecretKey( + int certificationLevel, + PgpKeyPair keyPair, + string id, + SymmetricKeyAlgorithmTag encAlgorithm, + byte[] rawPassPhrase, + bool clearPassPhrase, + bool useSha1, + PgpSignatureSubpacketVector hashedPackets, + PgpSignatureSubpacketVector unhashedPackets, + SecureRandom rand) + : this(keyPair.PrivateKey, CertifiedPublicKey(certificationLevel, keyPair, id, hashedPackets, unhashedPackets), + encAlgorithm, rawPassPhrase, clearPassPhrase, useSha1, rand, true) + { + } + + /// + /// Conversion of the passphrase characters to bytes is performed using Convert.ToByte(), which is + /// the historical behaviour of the library (1.7 and earlier). + /// + public PgpSecretKey( + int certificationLevel, + PgpKeyPair keyPair, + string id, + SymmetricKeyAlgorithmTag encAlgorithm, + HashAlgorithmTag hashAlgorithm, + char[] passPhrase, + bool useSha1, + PgpSignatureSubpacketVector hashedPackets, + PgpSignatureSubpacketVector unhashedPackets, + SecureRandom rand) + : this(certificationLevel, keyPair, id, encAlgorithm, hashAlgorithm, false, passPhrase, useSha1, hashedPackets, unhashedPackets, rand) + { + } + + /// + /// If utf8PassPhrase is true, conversion of the passphrase to bytes uses Encoding.UTF8.GetBytes(), otherwise the conversion + /// is performed using Convert.ToByte(), which is the historical behaviour of the library (1.7 and earlier). + /// + public PgpSecretKey( + int certificationLevel, + PgpKeyPair keyPair, + string id, + SymmetricKeyAlgorithmTag encAlgorithm, + HashAlgorithmTag hashAlgorithm, + bool utf8PassPhrase, + char[] passPhrase, + bool useSha1, + PgpSignatureSubpacketVector hashedPackets, + PgpSignatureSubpacketVector unhashedPackets, + SecureRandom rand) + : this(certificationLevel, keyPair, id, encAlgorithm, hashAlgorithm, + PgpUtilities.EncodePassPhrase(passPhrase, utf8PassPhrase), true, + useSha1, hashedPackets, unhashedPackets, rand) + { + } + + /// + /// Allows the caller to handle the encoding of the passphrase to bytes. + /// + public PgpSecretKey( + int certificationLevel, + PgpKeyPair keyPair, + string id, + SymmetricKeyAlgorithmTag encAlgorithm, + HashAlgorithmTag hashAlgorithm, + byte[] rawPassPhrase, + bool useSha1, + PgpSignatureSubpacketVector hashedPackets, + PgpSignatureSubpacketVector unhashedPackets, + SecureRandom rand) + : this(certificationLevel, keyPair, id, encAlgorithm, hashAlgorithm, rawPassPhrase, false, useSha1, hashedPackets, unhashedPackets, rand) + { + } + + internal PgpSecretKey( + int certificationLevel, + PgpKeyPair keyPair, + string id, + SymmetricKeyAlgorithmTag encAlgorithm, + HashAlgorithmTag hashAlgorithm, + byte[] rawPassPhrase, + bool clearPassPhrase, + bool useSha1, + PgpSignatureSubpacketVector hashedPackets, + PgpSignatureSubpacketVector unhashedPackets, + SecureRandom rand) + : this(keyPair.PrivateKey, CertifiedPublicKey(certificationLevel, keyPair, id, hashedPackets, unhashedPackets, hashAlgorithm), + encAlgorithm, rawPassPhrase, clearPassPhrase, useSha1, rand, true) + { + } + + private static PgpPublicKey CertifiedPublicKey( + int certificationLevel, + PgpKeyPair keyPair, + string id, + PgpSignatureSubpacketVector hashedPackets, + PgpSignatureSubpacketVector unhashedPackets) + { + PgpSignatureGenerator sGen; + try + { + sGen = new PgpSignatureGenerator(keyPair.PublicKey.Algorithm, HashAlgorithmTag.Sha1); + } + catch (Exception e) + { + throw new PgpException("Creating signature generator: " + e.Message, e); + } + + // + // Generate the certification + // + sGen.InitSign(certificationLevel, keyPair.PrivateKey); + + sGen.SetHashedSubpackets(hashedPackets); + sGen.SetUnhashedSubpackets(unhashedPackets); + + try + { + PgpSignature certification = sGen.GenerateCertification(id, keyPair.PublicKey); + return PgpPublicKey.AddCertification(keyPair.PublicKey, id, certification); + } + catch (Exception e) + { + throw new PgpException("Exception doing certification: " + e.Message, e); + } + } + + + private static PgpPublicKey CertifiedPublicKey( + int certificationLevel, + PgpKeyPair keyPair, + string id, + PgpSignatureSubpacketVector hashedPackets, + PgpSignatureSubpacketVector unhashedPackets, + HashAlgorithmTag hashAlgorithm) + { + PgpSignatureGenerator sGen; + try + { + sGen = new PgpSignatureGenerator(keyPair.PublicKey.Algorithm, hashAlgorithm); + } + catch (Exception e) + { + throw new PgpException("Creating signature generator: " + e.Message, e); + } + + // + // Generate the certification + // + sGen.InitSign(certificationLevel, keyPair.PrivateKey); + + sGen.SetHashedSubpackets(hashedPackets); + sGen.SetUnhashedSubpackets(unhashedPackets); + + try + { + PgpSignature certification = sGen.GenerateCertification(id, keyPair.PublicKey); + return PgpPublicKey.AddCertification(keyPair.PublicKey, id, certification); + } + catch (Exception e) + { + throw new PgpException("Exception doing certification: " + e.Message, e); + } + } + + public PgpSecretKey( + int certificationLevel, + PublicKeyAlgorithmTag algorithm, + AsymmetricKeyParameter pubKey, + AsymmetricKeyParameter privKey, + DateTime time, + string id, + SymmetricKeyAlgorithmTag encAlgorithm, + char[] passPhrase, + PgpSignatureSubpacketVector hashedPackets, + PgpSignatureSubpacketVector unhashedPackets, + SecureRandom rand) + : this(certificationLevel, + new PgpKeyPair(algorithm, pubKey, privKey, time), + id, encAlgorithm, passPhrase, false, hashedPackets, unhashedPackets, rand) + { + } + + public PgpSecretKey( + int certificationLevel, + PublicKeyAlgorithmTag algorithm, + AsymmetricKeyParameter pubKey, + AsymmetricKeyParameter privKey, + DateTime time, + string id, + SymmetricKeyAlgorithmTag encAlgorithm, + char[] passPhrase, + bool useSha1, + PgpSignatureSubpacketVector hashedPackets, + PgpSignatureSubpacketVector unhashedPackets, + SecureRandom rand) + : this(certificationLevel, new PgpKeyPair(algorithm, pubKey, privKey, time), id, encAlgorithm, passPhrase, useSha1, hashedPackets, unhashedPackets, rand) + { + } + + /// + /// Check if this key has an algorithm type that makes it suitable to use for signing. + /// + /// + /// Note: with version 4 keys KeyFlags subpackets should also be considered when present for + /// determining the preferred use of the key. + /// + /// + /// true if this key algorithm is suitable for use with signing. + /// + public bool IsSigningKey + { + get + { + switch (pub.Algorithm) + { + case PublicKeyAlgorithmTag.RsaGeneral: + case PublicKeyAlgorithmTag.RsaSign: + case PublicKeyAlgorithmTag.Dsa: + case PublicKeyAlgorithmTag.ECDsa: + case PublicKeyAlgorithmTag.EdDsa: + case PublicKeyAlgorithmTag.ElGamalGeneral: + return true; + default: + return false; + } + } + } + + /// True, if this is a master key. + public bool IsMasterKey + { + get { return pub.IsMasterKey; } + } + + /// Detect if the Secret Key's Private Key is empty or not + public bool IsPrivateKeyEmpty + { + get + { + byte[] secKeyData = secret.GetSecretKeyData(); + + return secKeyData == null || secKeyData.Length < 1; + } + } + + /// The algorithm the key is encrypted with. + public SymmetricKeyAlgorithmTag KeyEncryptionAlgorithm + { + get { return secret.EncAlgorithm; } + } + + /// The key ID of the public key associated with this key. + public long KeyId + { + get { return pub.KeyId; } + } + + /// Return the S2K usage associated with this key. + public int S2kUsage + { + get { return secret.S2kUsage; } + } + + /// Return the S2K used to process this key. + public S2k S2k + { + get { return secret.S2k; } + } + + /// The public key associated with this key. + public PgpPublicKey PublicKey + { + get { return pub; } + } + + /// Allows enumeration of any user IDs associated with the key. + /// An IEnumerable of string objects. + public IEnumerable UserIds + { + get { return pub.GetUserIds(); } + } + + /// Allows enumeration of any user attribute vectors associated with the key. + /// An IEnumerable of string objects. + public IEnumerable UserAttributes + { + get { return pub.GetUserAttributes(); } + } + + private byte[] ExtractKeyData(byte[] rawPassPhrase, bool clearPassPhrase) + { + SymmetricKeyAlgorithmTag encAlgorithm = secret.EncAlgorithm; + byte[] encData = secret.GetSecretKeyData(); + + if (encAlgorithm == SymmetricKeyAlgorithmTag.Null) + // TODO Check checksum here? + return encData; + + // TODO Factor this block out as 'decryptData' + try + { + KeyParameter key = PgpUtilities.DoMakeKeyFromPassPhrase(secret.EncAlgorithm, secret.S2k, rawPassPhrase, clearPassPhrase); + byte[] iv = secret.GetIV(); + byte[] data; + + if (secret.PublicKeyPacket.Version >= 4) + { + data = RecoverKeyData(encAlgorithm, "/CFB/NoPadding", key, iv, encData, 0, encData.Length); + + bool useSha1 = secret.S2kUsage == SecretKeyPacket.UsageSha1; + byte[] check = Checksum(useSha1, data, (useSha1) ? data.Length - 20 : data.Length - 2); + + for (int i = 0; i != check.Length; i++) + { + if (check[i] != data[data.Length - check.Length + i]) + { + throw new PgpException("Checksum mismatch at " + i + " of " + check.Length); + } + } + } + else // version 2 or 3, RSA only. + { + data = new byte[encData.Length]; + + iv = Arrays.Clone(iv); + + // + // read in the four numbers + // + int pos = 0; + + for (int i = 0; i != 4; i++) + { + int encLen = ((((encData[pos] & 0xff) << 8) | (encData[pos + 1] & 0xff)) + 7) / 8; + + data[pos] = encData[pos]; + data[pos + 1] = encData[pos + 1]; + pos += 2; + + if (encLen > (encData.Length - pos)) + throw new PgpException("out of range encLen found in encData"); + + byte[] tmp = RecoverKeyData(encAlgorithm, "/CFB/NoPadding", key, iv, encData, pos, encLen); + Array.Copy(tmp, 0, data, pos, encLen); + pos += encLen; + + if (i != 3) + { + Array.Copy(encData, pos - iv.Length, iv, 0, iv.Length); + } + } + + // + // verify and copy checksum + // + + data[pos] = encData[pos]; + data[pos + 1] = encData[pos + 1]; + + int cs = ((encData[pos] << 8) & 0xff00) | (encData[pos + 1] & 0xff); + int calcCs = 0; + for (int j = 0; j < pos; j++) + { + calcCs += data[j] & 0xff; + } + + calcCs &= 0xffff; + if (calcCs != cs) + { + throw new PgpException("Checksum mismatch: passphrase wrong, expected " + + cs.ToString("X") + + " found " + calcCs.ToString("X")); + } + } + + return data; + } + catch (PgpException e) + { + throw e; + } + catch (Exception e) + { + throw new PgpException("Exception decrypting key", e); + } + } + + private static byte[] RecoverKeyData(SymmetricKeyAlgorithmTag encAlgorithm, string modeAndPadding, + KeyParameter key, byte[] iv, byte[] keyData, int keyOff, int keyLen) + { + IBufferedCipher c; + try + { + string cName = PgpUtilities.GetSymmetricCipherName(encAlgorithm); + c = CipherUtilities.GetCipher(cName + modeAndPadding); + } + catch (Exception e) + { + throw new PgpException("Exception creating cipher", e); + } + + c.Init(false, new ParametersWithIV(key, iv)); + + return c.DoFinal(keyData, keyOff, keyLen); + } + + /// Extract a PgpPrivateKey from this secret key's encrypted contents. + /// + /// Conversion of the passphrase characters to bytes is performed using Convert.ToByte(), which is + /// the historical behaviour of the library (1.7 and earlier). + /// + public PgpPrivateKey ExtractPrivateKey(char[] passPhrase) + { + return DoExtractPrivateKey(PgpUtilities.EncodePassPhrase(passPhrase, false), true); + } + + /// Extract a PgpPrivateKey from this secret key's encrypted contents. + /// + /// The passphrase is encoded to bytes using UTF8 (Encoding.UTF8.GetBytes). + /// + public PgpPrivateKey ExtractPrivateKeyUtf8(char[] passPhrase) + { + return DoExtractPrivateKey(PgpUtilities.EncodePassPhrase(passPhrase, true), true); + } + + /// Extract a PgpPrivateKey from this secret key's encrypted contents. + /// + /// Allows the caller to handle the encoding of the passphrase to bytes. + /// + public PgpPrivateKey ExtractPrivateKeyRaw(byte[] rawPassPhrase) + { + return DoExtractPrivateKey(rawPassPhrase, false); + } + + internal PgpPrivateKey DoExtractPrivateKey(byte[] rawPassPhrase, bool clearPassPhrase) + { + if (IsPrivateKeyEmpty) + return null; + + PublicKeyPacket pubPk = secret.PublicKeyPacket; + try + { + byte[] data = ExtractKeyData(rawPassPhrase, clearPassPhrase); + BcpgInputStream bcpgIn = BcpgInputStream.Wrap(new MemoryStream(data, false)); + AsymmetricKeyParameter privateKey; + switch (pubPk.Algorithm) + { + case PublicKeyAlgorithmTag.RsaEncrypt: + case PublicKeyAlgorithmTag.RsaGeneral: + case PublicKeyAlgorithmTag.RsaSign: + RsaPublicBcpgKey rsaPub = (RsaPublicBcpgKey)pubPk.Key; + RsaSecretBcpgKey rsaPriv = new RsaSecretBcpgKey(bcpgIn); + RsaPrivateCrtKeyParameters rsaPrivSpec = new RsaPrivateCrtKeyParameters( + rsaPriv.Modulus, + rsaPub.PublicExponent, + rsaPriv.PrivateExponent, + rsaPriv.PrimeP, + rsaPriv.PrimeQ, + rsaPriv.PrimeExponentP, + rsaPriv.PrimeExponentQ, + rsaPriv.CrtCoefficient); + privateKey = rsaPrivSpec; + break; + case PublicKeyAlgorithmTag.Dsa: + DsaPublicBcpgKey dsaPub = (DsaPublicBcpgKey)pubPk.Key; + DsaSecretBcpgKey dsaPriv = new DsaSecretBcpgKey(bcpgIn); + DsaParameters dsaParams = new DsaParameters(dsaPub.P, dsaPub.Q, dsaPub.G); + privateKey = new DsaPrivateKeyParameters(dsaPriv.X, dsaParams); + break; + case PublicKeyAlgorithmTag.ECDH: + privateKey = GetECKey("ECDH", bcpgIn); + break; + case PublicKeyAlgorithmTag.ECDsa: + privateKey = GetECKey("ECDSA", bcpgIn); + break; + case PublicKeyAlgorithmTag.ElGamalEncrypt: + case PublicKeyAlgorithmTag.ElGamalGeneral: + ElGamalPublicBcpgKey elPub = (ElGamalPublicBcpgKey)pubPk.Key; + ElGamalSecretBcpgKey elPriv = new ElGamalSecretBcpgKey(bcpgIn); + ElGamalParameters elParams = new ElGamalParameters(elPub.P, elPub.G); + privateKey = new ElGamalPrivateKeyParameters(elPriv.X, elParams); + break; + default: + throw new PgpException("unknown public key algorithm encountered"); + } + + return new PgpPrivateKey(KeyId, pubPk, privateKey); + } + catch (PgpException e) + { + throw e; + } + catch (Exception e) + { + throw new PgpException("Exception constructing key", e); + } + } + + private ECPrivateKeyParameters GetECKey(string algorithm, BcpgInputStream bcpgIn) + { + ECPublicBcpgKey ecdsaPub = (ECPublicBcpgKey)secret.PublicKeyPacket.Key; + ECSecretBcpgKey ecdsaPriv = new ECSecretBcpgKey(bcpgIn); + return new ECPrivateKeyParameters(algorithm, ecdsaPriv.X, ecdsaPub.CurveOid); + } + + private static byte[] Checksum( + bool useSha1, + byte[] bytes, + int length) + { + if (useSha1) + { + try + { + IDigest dig = DigestUtilities.GetDigest("SHA1"); + dig.BlockUpdate(bytes, 0, length); + return DigestUtilities.DoFinal(dig); + } + //catch (NoSuchAlgorithmException e) + catch (Exception e) + { + throw new PgpException("Can't find SHA-1", e); + } + } + else + { + int Checksum = 0; + for (int i = 0; i != length; i++) + { + Checksum += bytes[i]; + } + + return new byte[] { (byte)(Checksum >> 8), (byte)Checksum }; + } + } + + public byte[] GetEncoded() + { + MemoryStream bOut = new MemoryStream(); + Encode(bOut); + return bOut.ToArray(); + } + + public void Encode( + Stream outStr) + { + BcpgOutputStream bcpgOut = BcpgOutputStream.Wrap(outStr); + + bcpgOut.WritePacket(secret); + if (pub.trustPk != null) + { + bcpgOut.WritePacket(pub.trustPk); + } + + if (pub.subSigs == null) // is not a sub key + { + foreach (PgpSignature keySig in pub.keySigs) + { + keySig.Encode(bcpgOut); + } + + for (int i = 0; i != pub.ids.Count; i++) + { + object pubID = pub.ids[i]; + if (pubID is string) + { + string id = (string) pubID; + bcpgOut.WritePacket(new UserIdPacket(id)); + } + else + { + PgpUserAttributeSubpacketVector v = (PgpUserAttributeSubpacketVector) pubID; + bcpgOut.WritePacket(new UserAttributePacket(v.ToSubpacketArray())); + } + + if (pub.idTrusts[i] != null) + { + bcpgOut.WritePacket((ContainedPacket)pub.idTrusts[i]); + } + + foreach (PgpSignature sig in (IList) pub.idSigs[i]) + { + sig.Encode(bcpgOut); + } + } + } + else + { + foreach (PgpSignature subSig in pub.subSigs) + { + subSig.Encode(bcpgOut); + } + } + + // TODO Check that this is right/necessary + //bcpgOut.Finish(); + } + + /// + /// Return a copy of the passed in secret key, encrypted using a new password + /// and the passed in algorithm. + /// + /// + /// Conversion of the passphrase characters to bytes is performed using Convert.ToByte(), which is + /// the historical behaviour of the library (1.7 and earlier). + /// + /// The PgpSecretKey to be copied. + /// The current password for the key. + /// The new password for the key. + /// The algorithm to be used for the encryption. + /// Source of randomness. + public static PgpSecretKey CopyWithNewPassword( + PgpSecretKey key, + char[] oldPassPhrase, + char[] newPassPhrase, + SymmetricKeyAlgorithmTag newEncAlgorithm, + SecureRandom rand) + { + return DoCopyWithNewPassword(key, PgpUtilities.EncodePassPhrase(oldPassPhrase, false), + PgpUtilities.EncodePassPhrase(newPassPhrase, false), true, newEncAlgorithm, rand); + } + + /// + /// Return a copy of the passed in secret key, encrypted using a new password + /// and the passed in algorithm. + /// + /// + /// The passphrase is encoded to bytes using UTF8 (Encoding.UTF8.GetBytes). + /// + /// The PgpSecretKey to be copied. + /// The current password for the key. + /// The new password for the key. + /// The algorithm to be used for the encryption. + /// Source of randomness. + public static PgpSecretKey CopyWithNewPasswordUtf8( + PgpSecretKey key, + char[] oldPassPhrase, + char[] newPassPhrase, + SymmetricKeyAlgorithmTag newEncAlgorithm, + SecureRandom rand) + { + return DoCopyWithNewPassword(key, PgpUtilities.EncodePassPhrase(oldPassPhrase, true), + PgpUtilities.EncodePassPhrase(newPassPhrase, true), true, newEncAlgorithm, rand); + } + + /// + /// Return a copy of the passed in secret key, encrypted using a new password + /// and the passed in algorithm. + /// + /// + /// Allows the caller to handle the encoding of the passphrase to bytes. + /// + /// The PgpSecretKey to be copied. + /// The current password for the key. + /// The new password for the key. + /// The algorithm to be used for the encryption. + /// Source of randomness. + public static PgpSecretKey CopyWithNewPasswordRaw( + PgpSecretKey key, + byte[] rawOldPassPhrase, + byte[] rawNewPassPhrase, + SymmetricKeyAlgorithmTag newEncAlgorithm, + SecureRandom rand) + { + return DoCopyWithNewPassword(key, rawOldPassPhrase, rawNewPassPhrase, false, newEncAlgorithm, rand); + } + + internal static PgpSecretKey DoCopyWithNewPassword( + PgpSecretKey key, + byte[] rawOldPassPhrase, + byte[] rawNewPassPhrase, + bool clearPassPhrase, + SymmetricKeyAlgorithmTag newEncAlgorithm, + SecureRandom rand) + { + if (key.IsPrivateKeyEmpty) + throw new PgpException("no private key in this SecretKey - public key present only."); + + byte[] rawKeyData = key.ExtractKeyData(rawOldPassPhrase, clearPassPhrase); + int s2kUsage = key.secret.S2kUsage; + byte[] iv = null; + S2k s2k = null; + byte[] keyData; + PublicKeyPacket pubKeyPacket = key.secret.PublicKeyPacket; + + if (newEncAlgorithm == SymmetricKeyAlgorithmTag.Null) + { + s2kUsage = SecretKeyPacket.UsageNone; + if (key.secret.S2kUsage == SecretKeyPacket.UsageSha1) // SHA-1 hash, need to rewrite Checksum + { + keyData = new byte[rawKeyData.Length - 18]; + + Array.Copy(rawKeyData, 0, keyData, 0, keyData.Length - 2); + + byte[] check = Checksum(false, keyData, keyData.Length - 2); + + keyData[keyData.Length - 2] = check[0]; + keyData[keyData.Length - 1] = check[1]; + } + else + { + keyData = rawKeyData; + } + } + else + { + if (s2kUsage == SecretKeyPacket.UsageNone) + { + s2kUsage = SecretKeyPacket.UsageChecksum; + } + + try + { + if (pubKeyPacket.Version >= 4) + { + keyData = EncryptKeyDataV4(rawKeyData, newEncAlgorithm, HashAlgorithmTag.Sha1, rawNewPassPhrase, clearPassPhrase, rand, out s2k, out iv); + } + else + { + keyData = EncryptKeyDataV3(rawKeyData, newEncAlgorithm, rawNewPassPhrase, clearPassPhrase, rand, out s2k, out iv); + } + } + catch (PgpException e) + { + throw e; + } + catch (Exception e) + { + throw new PgpException("Exception encrypting key", e); + } + } + + SecretKeyPacket secret; + if (key.secret is SecretSubkeyPacket) + { + secret = new SecretSubkeyPacket(pubKeyPacket, newEncAlgorithm, s2kUsage, s2k, iv, keyData); + } + else + { + secret = new SecretKeyPacket(pubKeyPacket, newEncAlgorithm, s2kUsage, s2k, iv, keyData); + } + + return new PgpSecretKey(secret, key.pub); + } + + /// Replace the passed the public key on the passed in secret key. + /// Secret key to change. + /// New public key. + /// A new secret key. + /// If KeyId's do not match. + public static PgpSecretKey ReplacePublicKey( + PgpSecretKey secretKey, + PgpPublicKey publicKey) + { + if (publicKey.KeyId != secretKey.KeyId) + throw new ArgumentException("KeyId's do not match"); + + return new PgpSecretKey(secretKey.secret, publicKey); + } + + private static byte[] EncryptKeyDataV3( + byte[] rawKeyData, + SymmetricKeyAlgorithmTag encAlgorithm, + byte[] rawPassPhrase, + bool clearPassPhrase, + SecureRandom random, + out S2k s2k, + out byte[] iv) + { + // Version 2 or 3 - RSA Keys only + + s2k = null; + iv = null; + + KeyParameter encKey = PgpUtilities.DoMakeKeyFromPassPhrase(encAlgorithm, s2k, rawPassPhrase, clearPassPhrase); + + byte[] keyData = new byte[rawKeyData.Length]; + + // + // process 4 numbers + // + int pos = 0; + for (int i = 0; i != 4; i++) + { + int encLen = ((((rawKeyData[pos] & 0xff) << 8) | (rawKeyData[pos + 1] & 0xff)) + 7) / 8; + + keyData[pos] = rawKeyData[pos]; + keyData[pos + 1] = rawKeyData[pos + 1]; + + if (encLen > (rawKeyData.Length - (pos + 2))) + throw new PgpException("out of range encLen found in rawKeyData"); + + byte[] tmp; + if (i == 0) + { + tmp = EncryptData(encAlgorithm, encKey, rawKeyData, pos + 2, encLen, random, ref iv); + } + else + { + byte[] tmpIv = Arrays.CopyOfRange(keyData, pos - iv.Length, pos); + + tmp = EncryptData(encAlgorithm, encKey, rawKeyData, pos + 2, encLen, random, ref tmpIv); + } + + Array.Copy(tmp, 0, keyData, pos + 2, tmp.Length); + pos += 2 + encLen; + } + + // + // copy in checksum. + // + keyData[pos] = rawKeyData[pos]; + keyData[pos + 1] = rawKeyData[pos + 1]; + + return keyData; + } + + private static byte[] EncryptKeyDataV4( + byte[] rawKeyData, + SymmetricKeyAlgorithmTag encAlgorithm, + HashAlgorithmTag hashAlgorithm, + byte[] rawPassPhrase, + bool clearPassPhrase, + SecureRandom random, + out S2k s2k, + out byte[] iv) + { + s2k = PgpUtilities.GenerateS2k(hashAlgorithm, 0x60, random); + + KeyParameter key = PgpUtilities.DoMakeKeyFromPassPhrase(encAlgorithm, s2k, rawPassPhrase, clearPassPhrase); + + iv = null; + return EncryptData(encAlgorithm, key, rawKeyData, 0, rawKeyData.Length, random, ref iv); + } + + private static byte[] EncryptData( + SymmetricKeyAlgorithmTag encAlgorithm, + KeyParameter key, + byte[] data, + int dataOff, + int dataLen, + SecureRandom random, + ref byte[] iv) + { + IBufferedCipher c; + try + { + string cName = PgpUtilities.GetSymmetricCipherName(encAlgorithm); + c = CipherUtilities.GetCipher(cName + "/CFB/NoPadding"); + } + catch (Exception e) + { + throw new PgpException("Exception creating cipher", e); + } + + if (iv == null) + { + iv = PgpUtilities.GenerateIV(c.GetBlockSize(), random); + } + + c.Init(true, new ParametersWithRandom(new ParametersWithIV(key, iv), random)); + + return c.DoFinal(data, dataOff, dataLen); + } + + /// + /// Parse a secret key from one of the GPG S expression keys associating it with the passed in public key. + /// + /// + /// Conversion of the passphrase characters to bytes is performed using Convert.ToByte(), which is + /// the historical behaviour of the library (1.7 and earlier). + /// + public static PgpSecretKey ParseSecretKeyFromSExpr(Stream inputStream, char[] passPhrase, PgpPublicKey pubKey) + { + return DoParseSecretKeyFromSExpr(inputStream, PgpUtilities.EncodePassPhrase(passPhrase, false), true, pubKey); + } + + /// + /// Parse a secret key from one of the GPG S expression keys associating it with the passed in public key. + /// + /// + /// The passphrase is encoded to bytes using UTF8 (Encoding.UTF8.GetBytes). + /// + public static PgpSecretKey ParseSecretKeyFromSExprUtf8(Stream inputStream, char[] passPhrase, PgpPublicKey pubKey) + { + return DoParseSecretKeyFromSExpr(inputStream, PgpUtilities.EncodePassPhrase(passPhrase, true), true, pubKey); + } + + /// + /// Parse a secret key from one of the GPG S expression keys associating it with the passed in public key. + /// + /// + /// Allows the caller to handle the encoding of the passphrase to bytes. + /// + public static PgpSecretKey ParseSecretKeyFromSExprRaw(Stream inputStream, byte[] rawPassPhrase, PgpPublicKey pubKey) + { + return DoParseSecretKeyFromSExpr(inputStream, rawPassPhrase, false, pubKey); + } + + internal static PgpSecretKey DoParseSecretKeyFromSExpr(Stream inputStream, byte[] rawPassPhrase, bool clearPassPhrase, PgpPublicKey pubKey) + { + SXprUtilities.SkipOpenParenthesis(inputStream); + + string type = SXprUtilities.ReadString(inputStream, inputStream.ReadByte()); + if (type.Equals("protected-private-key")) + { + SXprUtilities.SkipOpenParenthesis(inputStream); + + string curveName; + + string keyType = SXprUtilities.ReadString(inputStream, inputStream.ReadByte()); + if (keyType.Equals("ecc")) + { + SXprUtilities.SkipOpenParenthesis(inputStream); + + string curveID = SXprUtilities.ReadString(inputStream, inputStream.ReadByte()); + curveName = SXprUtilities.ReadString(inputStream, inputStream.ReadByte()); + + SXprUtilities.SkipCloseParenthesis(inputStream); + } + else + { + throw new PgpException("no curve details found"); + } + + byte[] qVal; + + SXprUtilities.SkipOpenParenthesis(inputStream); + + type = SXprUtilities.ReadString(inputStream, inputStream.ReadByte()); + if (type.Equals("q")) + { + qVal = SXprUtilities.ReadBytes(inputStream, inputStream.ReadByte()); + } + else + { + throw new PgpException("no q value found"); + } + + SXprUtilities.SkipCloseParenthesis(inputStream); + + byte[] dValue = GetDValue(inputStream, rawPassPhrase, clearPassPhrase, curveName); + // TODO: check SHA-1 hash. + + return new PgpSecretKey(new SecretKeyPacket(pubKey.PublicKeyPacket, SymmetricKeyAlgorithmTag.Null, null, null, + new ECSecretBcpgKey(new BigInteger(1, dValue)).GetEncoded()), pubKey); + } + + throw new PgpException("unknown key type found"); + } + + /// + /// Parse a secret key from one of the GPG S expression keys. + /// + /// + /// Conversion of the passphrase characters to bytes is performed using Convert.ToByte(), which is + /// the historical behaviour of the library (1.7 and earlier). + /// + public static PgpSecretKey ParseSecretKeyFromSExpr(Stream inputStream, char[] passPhrase) + { + return DoParseSecretKeyFromSExpr(inputStream, PgpUtilities.EncodePassPhrase(passPhrase, false), true); + } + + /// + /// Parse a secret key from one of the GPG S expression keys. + /// + /// + /// The passphrase is encoded to bytes using UTF8 (Encoding.UTF8.GetBytes). + /// + public static PgpSecretKey ParseSecretKeyFromSExprUtf8(Stream inputStream, char[] passPhrase) + { + return DoParseSecretKeyFromSExpr(inputStream, PgpUtilities.EncodePassPhrase(passPhrase, true), true); + } + + /// + /// Parse a secret key from one of the GPG S expression keys. + /// + /// + /// Allows the caller to handle the encoding of the passphrase to bytes. + /// + public static PgpSecretKey ParseSecretKeyFromSExprRaw(Stream inputStream, byte[] rawPassPhrase) + { + return DoParseSecretKeyFromSExpr(inputStream, rawPassPhrase, false); + } + + /// + /// Parse a secret key from one of the GPG S expression keys. + /// + internal static PgpSecretKey DoParseSecretKeyFromSExpr(Stream inputStream, byte[] rawPassPhrase, bool clearPassPhrase) + { + SXprUtilities.SkipOpenParenthesis(inputStream); + + string type = SXprUtilities.ReadString(inputStream, inputStream.ReadByte()); + if (type.Equals("protected-private-key")) + { + SXprUtilities.SkipOpenParenthesis(inputStream); + + string curveName; + + string keyType = SXprUtilities.ReadString(inputStream, inputStream.ReadByte()); + if (keyType.Equals("ecc")) + { + SXprUtilities.SkipOpenParenthesis(inputStream); + + string curveID = SXprUtilities.ReadString(inputStream, inputStream.ReadByte()); + curveName = SXprUtilities.ReadString(inputStream, inputStream.ReadByte()); + + if (Platform.StartsWith(curveName, "NIST ")) + { + curveName = curveName.Substring("NIST ".Length); + } + + SXprUtilities.SkipCloseParenthesis(inputStream); + } + else + { + throw new PgpException("no curve details found"); + } + + byte[] qVal; + + SXprUtilities.SkipOpenParenthesis(inputStream); + + type = SXprUtilities.ReadString(inputStream, inputStream.ReadByte()); + if (type.Equals("q")) + { + qVal = SXprUtilities.ReadBytes(inputStream, inputStream.ReadByte()); + } + else + { + throw new PgpException("no q value found"); + } + + PublicKeyPacket pubPacket = new PublicKeyPacket(PublicKeyAlgorithmTag.ECDsa, DateTime.UtcNow, + new ECDsaPublicBcpgKey(ECNamedCurveTable.GetOid(curveName), new BigInteger(1, qVal))); + + SXprUtilities.SkipCloseParenthesis(inputStream); + + byte[] dValue = GetDValue(inputStream, rawPassPhrase, clearPassPhrase, curveName); + // TODO: check SHA-1 hash. + + return new PgpSecretKey(new SecretKeyPacket(pubPacket, SymmetricKeyAlgorithmTag.Null, null, null, + new ECSecretBcpgKey(new BigInteger(1, dValue)).GetEncoded()), new PgpPublicKey(pubPacket)); + } + + throw new PgpException("unknown key type found"); + } + + private static byte[] GetDValue(Stream inputStream, byte[] rawPassPhrase, bool clearPassPhrase, string curveName) + { + string type; + SXprUtilities.SkipOpenParenthesis(inputStream); + + string protection; + S2k s2k; + byte[] iv; + byte[] secKeyData; + + type = SXprUtilities.ReadString(inputStream, inputStream.ReadByte()); + if (type.Equals("protected")) + { + protection = SXprUtilities.ReadString(inputStream, inputStream.ReadByte()); + + SXprUtilities.SkipOpenParenthesis(inputStream); + + s2k = SXprUtilities.ParseS2k(inputStream); + + iv = SXprUtilities.ReadBytes(inputStream, inputStream.ReadByte()); + + SXprUtilities.SkipCloseParenthesis(inputStream); + + secKeyData = SXprUtilities.ReadBytes(inputStream, inputStream.ReadByte()); + } + else + { + throw new PgpException("protected block not found"); + } + + // TODO: recognise other algorithms + KeyParameter key = PgpUtilities.DoMakeKeyFromPassPhrase(SymmetricKeyAlgorithmTag.Aes128, s2k, rawPassPhrase, clearPassPhrase); + + byte[] data = RecoverKeyData(SymmetricKeyAlgorithmTag.Aes128, "/CBC/NoPadding", key, iv, secKeyData, 0, secKeyData.Length); + + // + // parse the secret key S-expr + // + Stream keyIn = new MemoryStream(data, false); + + SXprUtilities.SkipOpenParenthesis(keyIn); + SXprUtilities.SkipOpenParenthesis(keyIn); + SXprUtilities.SkipOpenParenthesis(keyIn); + String name = SXprUtilities.ReadString(keyIn, keyIn.ReadByte()); + return SXprUtilities.ReadBytes(keyIn, keyIn.ReadByte()); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpSecretKey.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpSecretKey.cs.meta new file mode 100644 index 0000000..cc7be8d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpSecretKey.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 41fb6c960945a444ea55109243cf9195 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpSecretKeyRing.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpSecretKeyRing.cs new file mode 100644 index 0000000..06ad4d3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpSecretKeyRing.cs @@ -0,0 +1,308 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Bcpg.OpenPgp +{ + /// + /// Class to hold a single master secret key and its subkeys. + ///

    + /// Often PGP keyring files consist of multiple master keys, if you are trying to process + /// or construct one of these you should use the PgpSecretKeyRingBundle class. + ///

    + ///
    + public class PgpSecretKeyRing + : PgpKeyRing + { + private readonly IList keys; + private readonly IList extraPubKeys; + + internal PgpSecretKeyRing( + IList keys) + : this(keys, Platform.CreateArrayList()) + { + } + + private PgpSecretKeyRing( + IList keys, + IList extraPubKeys) + { + this.keys = keys; + this.extraPubKeys = extraPubKeys; + } + + public PgpSecretKeyRing( + byte[] encoding) + : this(new MemoryStream(encoding)) + { + } + + public PgpSecretKeyRing( + Stream inputStream) + { + this.keys = Platform.CreateArrayList(); + this.extraPubKeys = Platform.CreateArrayList(); + + BcpgInputStream bcpgInput = BcpgInputStream.Wrap(inputStream); + + PacketTag initialTag = bcpgInput.SkipMarkerPackets(); + if (initialTag != PacketTag.SecretKey && initialTag != PacketTag.SecretSubkey) + { + throw new IOException("secret key ring doesn't start with secret key tag: " + + "tag 0x" + ((int)initialTag).ToString("X")); + } + + SecretKeyPacket secret = (SecretKeyPacket) bcpgInput.ReadPacket(); + + // + // ignore GPG comment packets if found. + // + while (bcpgInput.NextPacketTag() == PacketTag.Experimental2) + { + bcpgInput.ReadPacket(); + } + + TrustPacket trust = ReadOptionalTrustPacket(bcpgInput); + + // revocation and direct signatures + IList keySigs = ReadSignaturesAndTrust(bcpgInput); + + IList ids, idTrusts, idSigs; + ReadUserIDs(bcpgInput, out ids, out idTrusts, out idSigs); + + keys.Add(new PgpSecretKey(secret, new PgpPublicKey(secret.PublicKeyPacket, trust, keySigs, ids, idTrusts, idSigs))); + + + // Read subkeys + while (bcpgInput.NextPacketTag() == PacketTag.SecretSubkey + || bcpgInput.NextPacketTag() == PacketTag.PublicSubkey) + { + if (bcpgInput.NextPacketTag() == PacketTag.SecretSubkey) + { + SecretSubkeyPacket sub = (SecretSubkeyPacket) bcpgInput.ReadPacket(); + + // + // ignore GPG comment packets if found. + // + while (bcpgInput.NextPacketTag() == PacketTag.Experimental2) + { + bcpgInput.ReadPacket(); + } + + TrustPacket subTrust = ReadOptionalTrustPacket(bcpgInput); + IList sigList = ReadSignaturesAndTrust(bcpgInput); + + keys.Add(new PgpSecretKey(sub, new PgpPublicKey(sub.PublicKeyPacket, subTrust, sigList))); + } + else + { + PublicSubkeyPacket sub = (PublicSubkeyPacket) bcpgInput.ReadPacket(); + + TrustPacket subTrust = ReadOptionalTrustPacket(bcpgInput); + IList sigList = ReadSignaturesAndTrust(bcpgInput); + + extraPubKeys.Add(new PgpPublicKey(sub, subTrust, sigList)); + } + } + } + + /// Return the public key for the master key. + public PgpPublicKey GetPublicKey() + { + return ((PgpSecretKey) keys[0]).PublicKey; + } + + /// Return the master private key. + public PgpSecretKey GetSecretKey() + { + return (PgpSecretKey) keys[0]; + } + + /// Allows enumeration of the secret keys. + /// An IEnumerable of PgpSecretKey objects. + public IEnumerable GetSecretKeys() + { + return new EnumerableProxy(keys); + } + + public PgpSecretKey GetSecretKey( + long keyId) + { + foreach (PgpSecretKey k in keys) + { + if (keyId == k.KeyId) + { + return k; + } + } + + return null; + } + + /// + /// Return an iterator of the public keys in the secret key ring that + /// have no matching private key. At the moment only personal certificate data + /// appears in this fashion. + /// + /// An IEnumerable of unattached, or extra, public keys. + public IEnumerable GetExtraPublicKeys() + { + return new EnumerableProxy(extraPubKeys); + } + + public byte[] GetEncoded() + { + MemoryStream bOut = new MemoryStream(); + + Encode(bOut); + + return bOut.ToArray(); + } + + public void Encode( + Stream outStr) + { + if (outStr == null) + throw new ArgumentNullException("outStr"); + + foreach (PgpSecretKey key in keys) + { + key.Encode(outStr); + } + foreach (PgpPublicKey extraPubKey in extraPubKeys) + { + extraPubKey.Encode(outStr); + } + } + + /// + /// Replace the public key set on the secret ring with the corresponding key off the public ring. + /// + /// Secret ring to be changed. + /// Public ring containing the new public key set. + public static PgpSecretKeyRing ReplacePublicKeys( + PgpSecretKeyRing secretRing, + PgpPublicKeyRing publicRing) + { + IList newList = Platform.CreateArrayList(secretRing.keys.Count); + + foreach (PgpSecretKey sk in secretRing.keys) + { + PgpPublicKey pk = publicRing.GetPublicKey(sk.KeyId); + + newList.Add(PgpSecretKey.ReplacePublicKey(sk, pk)); + } + + return new PgpSecretKeyRing(newList); + } + + /// + /// Return a copy of the passed in secret key ring, with the master key and sub keys encrypted + /// using a new password and the passed in algorithm. + /// + /// The PgpSecretKeyRing to be copied. + /// The current password for key. + /// The new password for the key. + /// The algorithm to be used for the encryption. + /// Source of randomness. + public static PgpSecretKeyRing CopyWithNewPassword( + PgpSecretKeyRing ring, + char[] oldPassPhrase, + char[] newPassPhrase, + SymmetricKeyAlgorithmTag newEncAlgorithm, + SecureRandom rand) + { + IList newKeys = Platform.CreateArrayList(ring.keys.Count); + foreach (PgpSecretKey secretKey in ring.GetSecretKeys()) + { + if (secretKey.IsPrivateKeyEmpty) + { + newKeys.Add(secretKey); + } + else + { + newKeys.Add(PgpSecretKey.CopyWithNewPassword(secretKey, oldPassPhrase, newPassPhrase, newEncAlgorithm, rand)); + } + } + + return new PgpSecretKeyRing(newKeys, ring.extraPubKeys); + } + + /// + /// Returns a new key ring with the secret key passed in either added or + /// replacing an existing one with the same key ID. + /// + /// The secret key ring to be modified. + /// The secret key to be inserted. + /// A new PgpSecretKeyRing + public static PgpSecretKeyRing InsertSecretKey( + PgpSecretKeyRing secRing, + PgpSecretKey secKey) + { + IList keys = Platform.CreateArrayList(secRing.keys); + bool found = false; + bool masterFound = false; + + for (int i = 0; i != keys.Count; i++) + { + PgpSecretKey key = (PgpSecretKey) keys[i]; + + if (key.KeyId == secKey.KeyId) + { + found = true; + keys[i] = secKey; + } + if (key.IsMasterKey) + { + masterFound = true; + } + } + + if (!found) + { + if (secKey.IsMasterKey) + { + if (masterFound) + throw new ArgumentException("cannot add a master key to a ring that already has one"); + + keys.Insert(0, secKey); + } + else + { + keys.Add(secKey); + } + } + + return new PgpSecretKeyRing(keys, secRing.extraPubKeys); + } + + /// Returns a new key ring with the secret key passed in removed from the key ring. + /// The secret key ring to be modified. + /// The secret key to be removed. + /// A new PgpSecretKeyRing, or null if secKey is not found. + public static PgpSecretKeyRing RemoveSecretKey( + PgpSecretKeyRing secRing, + PgpSecretKey secKey) + { + IList keys = Platform.CreateArrayList(secRing.keys); + bool found = false; + + for (int i = 0; i < keys.Count; i++) + { + PgpSecretKey key = (PgpSecretKey)keys[i]; + + if (key.KeyId == secKey.KeyId) + { + found = true; + keys.RemoveAt(i); + } + } + + return found ? new PgpSecretKeyRing(keys, secRing.extraPubKeys) : null; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpSecretKeyRing.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpSecretKeyRing.cs.meta new file mode 100644 index 0000000..2c150df --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpSecretKeyRing.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4cba26dcfb1f89449ac78fecf503284a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpSecretKeyRingBundle.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpSecretKeyRingBundle.cs new file mode 100644 index 0000000..26be9c1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpSecretKeyRingBundle.cs @@ -0,0 +1,281 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Bcpg.OpenPgp +{ + /// + /// Often a PGP key ring file is made up of a succession of master/sub-key key rings. + /// If you want to read an entire secret key file in one hit this is the class for you. + /// + public class PgpSecretKeyRingBundle + { + private readonly IDictionary secretRings; + private readonly IList order; + + private PgpSecretKeyRingBundle( + IDictionary secretRings, + IList order) + { + this.secretRings = secretRings; + this.order = order; + } + + public PgpSecretKeyRingBundle( + byte[] encoding) + : this(new MemoryStream(encoding, false)) + { + } + + /// Build a PgpSecretKeyRingBundle from the passed in input stream. + /// Input stream containing data. + /// If a problem parsing the stream occurs. + /// If an object is encountered which isn't a PgpSecretKeyRing. + public PgpSecretKeyRingBundle( + Stream inputStream) + : this(new PgpObjectFactory(inputStream).AllPgpObjects()) + { + } + + public PgpSecretKeyRingBundle( + IEnumerable e) + { + this.secretRings = Platform.CreateHashtable(); + this.order = Platform.CreateArrayList(); + + foreach (object obj in e) + { + // Marker packets must be ignored + if (obj is PgpMarker) + continue; + + PgpSecretKeyRing pgpSecret = obj as PgpSecretKeyRing; + if (pgpSecret == null) + throw new PgpException(Platform.GetTypeName(obj) + " found where PgpSecretKeyRing expected"); + + long key = pgpSecret.GetPublicKey().KeyId; + secretRings.Add(key, pgpSecret); + order.Add(key); + } + } + + [Obsolete("Use 'Count' property instead")] + public int Size + { + get { return order.Count; } + } + + /// Return the number of rings in this collection. + public int Count + { + get { return order.Count; } + } + + /// Allow enumeration of the secret key rings making up this collection. + public IEnumerable GetKeyRings() + { + return new EnumerableProxy(secretRings.Values); + } + + /// Allow enumeration of the key rings associated with the passed in userId. + /// The user ID to be matched. + /// An IEnumerable of key rings which matched (possibly none). + public IEnumerable GetKeyRings( + string userId) + { + return GetKeyRings(userId, false, false); + } + + /// Allow enumeration of the key rings associated with the passed in userId. + /// The user ID to be matched. + /// If true, userId need only be a substring of an actual ID string to match. + /// An IEnumerable of key rings which matched (possibly none). + public IEnumerable GetKeyRings( + string userId, + bool matchPartial) + { + return GetKeyRings(userId, matchPartial, false); + } + + /// Allow enumeration of the key rings associated with the passed in userId. + /// The user ID to be matched. + /// If true, userId need only be a substring of an actual ID string to match. + /// If true, case is ignored in user ID comparisons. + /// An IEnumerable of key rings which matched (possibly none). + public IEnumerable GetKeyRings( + string userId, + bool matchPartial, + bool ignoreCase) + { + IList rings = Platform.CreateArrayList(); + + if (ignoreCase) + { + userId = Platform.ToUpperInvariant(userId); + } + + foreach (PgpSecretKeyRing secRing in GetKeyRings()) + { + foreach (string nextUserID in secRing.GetSecretKey().UserIds) + { + string next = nextUserID; + if (ignoreCase) + { + next = Platform.ToUpperInvariant(next); + } + + if (matchPartial) + { + if (Platform.IndexOf(next, userId) > -1) + { + rings.Add(secRing); + } + } + else + { + if (next.Equals(userId)) + { + rings.Add(secRing); + } + } + } + } + + return new EnumerableProxy(rings); + } + + /// Return the PGP secret key associated with the given key id. + /// The ID of the secret key to return. + public PgpSecretKey GetSecretKey( + long keyId) + { + foreach (PgpSecretKeyRing secRing in GetKeyRings()) + { + PgpSecretKey sec = secRing.GetSecretKey(keyId); + + if (sec != null) + { + return sec; + } + } + + return null; + } + + /// Return the secret key ring which contains the key referred to by keyId + /// The ID of the secret key + public PgpSecretKeyRing GetSecretKeyRing( + long keyId) + { + long id = keyId; + + if (secretRings.Contains(id)) + { + return (PgpSecretKeyRing) secretRings[id]; + } + + foreach (PgpSecretKeyRing secretRing in GetKeyRings()) + { + PgpSecretKey secret = secretRing.GetSecretKey(keyId); + + if (secret != null) + { + return secretRing; + } + } + + return null; + } + + /// + /// Return true if a key matching the passed in key ID is present, false otherwise. + /// + /// key ID to look for. + public bool Contains( + long keyID) + { + return GetSecretKey(keyID) != null; + } + + public byte[] GetEncoded() + { + MemoryStream bOut = new MemoryStream(); + + Encode(bOut); + + return bOut.ToArray(); + } + + public void Encode( + Stream outStr) + { + BcpgOutputStream bcpgOut = BcpgOutputStream.Wrap(outStr); + + foreach (long key in order) + { + PgpSecretKeyRing pub = (PgpSecretKeyRing) secretRings[key]; + + pub.Encode(bcpgOut); + } + } + + /// + /// Return a new bundle containing the contents of the passed in bundle and + /// the passed in secret key ring. + /// + /// The PgpSecretKeyRingBundle the key ring is to be added to. + /// The key ring to be added. + /// A new PgpSecretKeyRingBundle merging the current one with the passed in key ring. + /// If the keyId for the passed in key ring is already present. + public static PgpSecretKeyRingBundle AddSecretKeyRing( + PgpSecretKeyRingBundle bundle, + PgpSecretKeyRing secretKeyRing) + { + long key = secretKeyRing.GetPublicKey().KeyId; + + if (bundle.secretRings.Contains(key)) + { + throw new ArgumentException("Collection already contains a key with a keyId for the passed in ring."); + } + + IDictionary newSecretRings = Platform.CreateHashtable(bundle.secretRings); + IList newOrder = Platform.CreateArrayList(bundle.order); + + newSecretRings[key] = secretKeyRing; + newOrder.Add(key); + + return new PgpSecretKeyRingBundle(newSecretRings, newOrder); + } + + /// + /// Return a new bundle containing the contents of the passed in bundle with + /// the passed in secret key ring removed. + /// + /// The PgpSecretKeyRingBundle the key ring is to be removed from. + /// The key ring to be removed. + /// A new PgpSecretKeyRingBundle not containing the passed in key ring. + /// If the keyId for the passed in key ring is not present. + public static PgpSecretKeyRingBundle RemoveSecretKeyRing( + PgpSecretKeyRingBundle bundle, + PgpSecretKeyRing secretKeyRing) + { + long key = secretKeyRing.GetPublicKey().KeyId; + + if (!bundle.secretRings.Contains(key)) + { + throw new ArgumentException("Collection does not contain a key with a keyId for the passed in ring."); + } + + IDictionary newSecretRings = Platform.CreateHashtable(bundle.secretRings); + IList newOrder = Platform.CreateArrayList(bundle.order); + + newSecretRings.Remove(key); + newOrder.Remove(key); + + return new PgpSecretKeyRingBundle(newSecretRings, newOrder); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpSecretKeyRingBundle.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpSecretKeyRingBundle.cs.meta new file mode 100644 index 0000000..4fb610f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpSecretKeyRingBundle.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1b6c79da6b26cca47b343b43bc03a9b0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpSignature.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpSignature.cs new file mode 100644 index 0000000..fb62447 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpSignature.cs @@ -0,0 +1,455 @@ +using System; +using System.IO; +using Org.BouncyCastle.Asn1; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Date; + +namespace Org.BouncyCastle.Bcpg.OpenPgp +{ + /// A PGP signature object. + public class PgpSignature + { + private static SignaturePacket Cast(Packet packet) + { + if (!(packet is SignaturePacket)) + throw new IOException("unexpected packet in stream: " + packet); + + return (SignaturePacket)packet; + } + + public const int BinaryDocument = 0x00; + public const int CanonicalTextDocument = 0x01; + public const int StandAlone = 0x02; + + public const int DefaultCertification = 0x10; + public const int NoCertification = 0x11; + public const int CasualCertification = 0x12; + public const int PositiveCertification = 0x13; + + public const int SubkeyBinding = 0x18; + public const int PrimaryKeyBinding = 0x19; + public const int DirectKey = 0x1f; + public const int KeyRevocation = 0x20; + public const int SubkeyRevocation = 0x28; + public const int CertificationRevocation = 0x30; + public const int Timestamp = 0x40; + + private readonly SignaturePacket sigPck; + private readonly int signatureType; + private readonly TrustPacket trustPck; + + private ISigner sig; + private byte lastb; // Initial value anything but '\r' + + internal PgpSignature( + BcpgInputStream bcpgInput) + : this(Cast(bcpgInput.ReadPacket())) + { + } + + internal PgpSignature( + SignaturePacket sigPacket) + : this(sigPacket, null) + { + } + + internal PgpSignature( + SignaturePacket sigPacket, + TrustPacket trustPacket) + { + if (sigPacket == null) + throw new ArgumentNullException("sigPacket"); + + this.sigPck = sigPacket; + this.signatureType = sigPck.SignatureType; + this.trustPck = trustPacket; + } + + private void GetSig() + { + this.sig = SignerUtilities.GetSigner( + PgpUtilities.GetSignatureName(sigPck.KeyAlgorithm, sigPck.HashAlgorithm)); + } + + /// The OpenPGP version number for this signature. + public int Version + { + get { return sigPck.Version; } + } + + /// The key algorithm associated with this signature. + public PublicKeyAlgorithmTag KeyAlgorithm + { + get { return sigPck.KeyAlgorithm; } + } + + /// The hash algorithm associated with this signature. + public HashAlgorithmTag HashAlgorithm + { + get { return sigPck.HashAlgorithm; } + } + + /// Return true if this signature represents a certification. + public bool IsCertification() + { + return IsCertification(SignatureType); + } + + public void InitVerify( + PgpPublicKey pubKey) + { + lastb = 0; + if (sig == null) + { + GetSig(); + } + try + { + sig.Init(false, pubKey.GetKey()); + } + catch (InvalidKeyException e) + { + throw new PgpException("invalid key.", e); + } + } + + public void Update( + byte b) + { + if (signatureType == CanonicalTextDocument) + { + doCanonicalUpdateByte(b); + } + else + { + sig.Update(b); + } + } + + private void doCanonicalUpdateByte( + byte b) + { + if (b == '\r') + { + doUpdateCRLF(); + } + else if (b == '\n') + { + if (lastb != '\r') + { + doUpdateCRLF(); + } + } + else + { + sig.Update(b); + } + + lastb = b; + } + + private void doUpdateCRLF() + { + sig.Update((byte)'\r'); + sig.Update((byte)'\n'); + } + + public void Update( + params byte[] bytes) + { + Update(bytes, 0, bytes.Length); + } + + public void Update( + byte[] bytes, + int off, + int length) + { + if (signatureType == CanonicalTextDocument) + { + int finish = off + length; + + for (int i = off; i != finish; i++) + { + doCanonicalUpdateByte(bytes[i]); + } + } + else + { + sig.BlockUpdate(bytes, off, length); + } + } + + public bool Verify() + { + byte[] trailer = GetSignatureTrailer(); + sig.BlockUpdate(trailer, 0, trailer.Length); + + return sig.VerifySignature(GetSignature()); + } + + private void UpdateWithIdData( + int header, + byte[] idBytes) + { + this.Update( + (byte) header, + (byte)(idBytes.Length >> 24), + (byte)(idBytes.Length >> 16), + (byte)(idBytes.Length >> 8), + (byte)(idBytes.Length)); + this.Update(idBytes); + } + + private void UpdateWithPublicKey( + PgpPublicKey key) + { + byte[] keyBytes = GetEncodedPublicKey(key); + + this.Update( + (byte) 0x99, + (byte)(keyBytes.Length >> 8), + (byte)(keyBytes.Length)); + this.Update(keyBytes); + } + + /// + /// Verify the signature as certifying the passed in public key as associated + /// with the passed in user attributes. + /// + /// User attributes the key was stored under. + /// The key to be verified. + /// True, if the signature matches, false otherwise. + public bool VerifyCertification( + PgpUserAttributeSubpacketVector userAttributes, + PgpPublicKey key) + { + UpdateWithPublicKey(key); + + // + // hash in the userAttributes + // + try + { + MemoryStream bOut = new MemoryStream(); + foreach (UserAttributeSubpacket packet in userAttributes.ToSubpacketArray()) + { + packet.Encode(bOut); + } + UpdateWithIdData(0xd1, bOut.ToArray()); + } + catch (IOException e) + { + throw new PgpException("cannot encode subpacket array", e); + } + + this.Update(sigPck.GetSignatureTrailer()); + + return sig.VerifySignature(this.GetSignature()); + } + + /// + /// Verify the signature as certifying the passed in public key as associated + /// with the passed in ID. + /// + /// ID the key was stored under. + /// The key to be verified. + /// True, if the signature matches, false otherwise. + public bool VerifyCertification( + string id, + PgpPublicKey key) + { + UpdateWithPublicKey(key); + + // + // hash in the id + // + UpdateWithIdData(0xb4, Strings.ToUtf8ByteArray(id)); + + Update(sigPck.GetSignatureTrailer()); + + return sig.VerifySignature(GetSignature()); + } + + /// Verify a certification for the passed in key against the passed in master key. + /// The key we are verifying against. + /// The key we are verifying. + /// True, if the certification is valid, false otherwise. + public bool VerifyCertification( + PgpPublicKey masterKey, + PgpPublicKey pubKey) + { + UpdateWithPublicKey(masterKey); + UpdateWithPublicKey(pubKey); + + Update(sigPck.GetSignatureTrailer()); + + return sig.VerifySignature(GetSignature()); + } + + /// Verify a key certification, such as revocation, for the passed in key. + /// The key we are checking. + /// True, if the certification is valid, false otherwise. + public bool VerifyCertification( + PgpPublicKey pubKey) + { + if (SignatureType != KeyRevocation + && SignatureType != SubkeyRevocation) + { + throw new InvalidOperationException("signature is not a key signature"); + } + + UpdateWithPublicKey(pubKey); + + Update(sigPck.GetSignatureTrailer()); + + return sig.VerifySignature(GetSignature()); + } + + public int SignatureType + { + get { return sigPck.SignatureType; } + } + + /// The ID of the key that created the signature. + public long KeyId + { + get { return sigPck.KeyId; } + } + + [Obsolete("Use 'CreationTime' property instead")] + public DateTime GetCreationTime() + { + return CreationTime; + } + + /// The creation time of this signature. + public DateTime CreationTime + { + get { return DateTimeUtilities.UnixMsToDateTime(sigPck.CreationTime); } + } + + public byte[] GetSignatureTrailer() + { + return sigPck.GetSignatureTrailer(); + } + + /// + /// Return true if the signature has either hashed or unhashed subpackets. + /// + public bool HasSubpackets + { + get + { + return sigPck.GetHashedSubPackets() != null + || sigPck.GetUnhashedSubPackets() != null; + } + } + + public PgpSignatureSubpacketVector GetHashedSubPackets() + { + return createSubpacketVector(sigPck.GetHashedSubPackets()); + } + + public PgpSignatureSubpacketVector GetUnhashedSubPackets() + { + return createSubpacketVector(sigPck.GetUnhashedSubPackets()); + } + + private PgpSignatureSubpacketVector createSubpacketVector(SignatureSubpacket[] pcks) + { + return pcks == null ? null : new PgpSignatureSubpacketVector(pcks); + } + + public byte[] GetSignature() + { + MPInteger[] sigValues = sigPck.GetSignature(); + byte[] signature; + + if (sigValues != null) + { + if (sigValues.Length == 1) // an RSA signature + { + signature = sigValues[0].Value.ToByteArrayUnsigned(); + } + else + { + try + { + signature = new DerSequence( + new DerInteger(sigValues[0].Value), + new DerInteger(sigValues[1].Value)).GetEncoded(); + } + catch (IOException e) + { + throw new PgpException("exception encoding DSA sig.", e); + } + } + } + else + { + signature = sigPck.GetSignatureBytes(); + } + + return signature; + } + + // TODO Handle the encoding stuff by subclassing BcpgObject? + public byte[] GetEncoded() + { + MemoryStream bOut = new MemoryStream(); + + Encode(bOut); + + return bOut.ToArray(); + } + + public void Encode( + Stream outStream) + { + BcpgOutputStream bcpgOut = BcpgOutputStream.Wrap(outStream); + + bcpgOut.WritePacket(sigPck); + + if (trustPck != null) + { + bcpgOut.WritePacket(trustPck); + } + } + + private byte[] GetEncodedPublicKey( + PgpPublicKey pubKey) + { + try + { + return pubKey.publicPk.GetEncodedContents(); + } + catch (IOException e) + { + throw new PgpException("exception preparing key.", e); + } + } + + /// + /// Return true if the passed in signature type represents a certification, false if the signature type is not. + /// + /// + /// true if signatureType is a certification, false otherwise. + public static bool IsCertification(int signatureType) + { + switch (signatureType) + { + case DefaultCertification: + case NoCertification: + case CasualCertification: + case PositiveCertification: + return true; + default: + return false; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpSignature.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpSignature.cs.meta new file mode 100644 index 0000000..6c60cde --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpSignature.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 52fd81b60e2bdf84a9952e1da8bab03c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpSignatureGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpSignatureGenerator.cs new file mode 100644 index 0000000..c530968 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpSignatureGenerator.cs @@ -0,0 +1,393 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Bcpg.Sig; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Bcpg.OpenPgp +{ + /// Generator for PGP signatures. + // TODO Should be able to implement ISigner? + public class PgpSignatureGenerator + { + private static readonly SignatureSubpacket[] EmptySignatureSubpackets = new SignatureSubpacket[0]; + + private PublicKeyAlgorithmTag keyAlgorithm; + private HashAlgorithmTag hashAlgorithm; + private PgpPrivateKey privKey; + private ISigner sig; + private IDigest dig; + private int signatureType; + private byte lastb; + + private SignatureSubpacket[] unhashed = EmptySignatureSubpackets; + private SignatureSubpacket[] hashed = EmptySignatureSubpackets; + + /// Create a generator for the passed in keyAlgorithm and hashAlgorithm codes. + public PgpSignatureGenerator( + PublicKeyAlgorithmTag keyAlgorithm, + HashAlgorithmTag hashAlgorithm) + { + this.keyAlgorithm = keyAlgorithm; + this.hashAlgorithm = hashAlgorithm; + + dig = DigestUtilities.GetDigest(PgpUtilities.GetDigestName(hashAlgorithm)); + sig = SignerUtilities.GetSigner(PgpUtilities.GetSignatureName(keyAlgorithm, hashAlgorithm)); + } + + /// Initialise the generator for signing. + public void InitSign( + int sigType, + PgpPrivateKey key) + { + InitSign(sigType, key, null); + } + + /// Initialise the generator for signing. + public void InitSign( + int sigType, + PgpPrivateKey key, + SecureRandom random) + { + this.privKey = key; + this.signatureType = sigType; + + try + { + ICipherParameters cp = key.Key; + if (random != null) + { + cp = new ParametersWithRandom(key.Key, random); + } + + sig.Init(true, cp); + } + catch (InvalidKeyException e) + { + throw new PgpException("invalid key.", e); + } + + dig.Reset(); + lastb = 0; + } + + public void Update( + byte b) + { + if (signatureType == PgpSignature.CanonicalTextDocument) + { + doCanonicalUpdateByte(b); + } + else + { + doUpdateByte(b); + } + } + + private void doCanonicalUpdateByte( + byte b) + { + if (b == '\r') + { + doUpdateCRLF(); + } + else if (b == '\n') + { + if (lastb != '\r') + { + doUpdateCRLF(); + } + } + else + { + doUpdateByte(b); + } + + lastb = b; + } + + private void doUpdateCRLF() + { + doUpdateByte((byte)'\r'); + doUpdateByte((byte)'\n'); + } + + private void doUpdateByte( + byte b) + { + sig.Update(b); + dig.Update(b); + } + + public void Update( + params byte[] b) + { + Update(b, 0, b.Length); + } + + public void Update( + byte[] b, + int off, + int len) + { + if (signatureType == PgpSignature.CanonicalTextDocument) + { + int finish = off + len; + + for (int i = off; i != finish; i++) + { + doCanonicalUpdateByte(b[i]); + } + } + else + { + sig.BlockUpdate(b, off, len); + dig.BlockUpdate(b, off, len); + } + } + + public void SetHashedSubpackets( + PgpSignatureSubpacketVector hashedPackets) + { + hashed = hashedPackets == null + ? EmptySignatureSubpackets + : hashedPackets.ToSubpacketArray(); + } + + public void SetUnhashedSubpackets( + PgpSignatureSubpacketVector unhashedPackets) + { + unhashed = unhashedPackets == null + ? EmptySignatureSubpackets + : unhashedPackets.ToSubpacketArray(); + } + + /// Return the one pass header associated with the current signature. + public PgpOnePassSignature GenerateOnePassVersion( + bool isNested) + { + return new PgpOnePassSignature( + new OnePassSignaturePacket( + signatureType, hashAlgorithm, keyAlgorithm, privKey.KeyId, isNested)); + } + + /// Return a signature object containing the current signature state. + public PgpSignature Generate() + { + SignatureSubpacket[] hPkts = hashed, unhPkts = unhashed; + + if (!packetPresent(hashed, SignatureSubpacketTag.CreationTime)) + { + hPkts = insertSubpacket(hPkts, new SignatureCreationTime(false, DateTime.UtcNow)); + } + + if (!packetPresent(hashed, SignatureSubpacketTag.IssuerKeyId) + && !packetPresent(unhashed, SignatureSubpacketTag.IssuerKeyId)) + { + unhPkts = insertSubpacket(unhPkts, new IssuerKeyId(false, privKey.KeyId)); + } + + int version = 4; + byte[] hData; + + try + { + MemoryStream hOut = new MemoryStream(); + + for (int i = 0; i != hPkts.Length; i++) + { + hPkts[i].Encode(hOut); + } + + byte[] data = hOut.ToArray(); + + MemoryStream sOut = new MemoryStream(data.Length + 6); + sOut.WriteByte((byte)version); + sOut.WriteByte((byte)signatureType); + sOut.WriteByte((byte)keyAlgorithm); + sOut.WriteByte((byte)hashAlgorithm); + sOut.WriteByte((byte)(data.Length >> 8)); + sOut.WriteByte((byte)data.Length); + sOut.Write(data, 0, data.Length); + + hData = sOut.ToArray(); + } + catch (IOException e) + { + throw new PgpException("exception encoding hashed data.", e); + } + + sig.BlockUpdate(hData, 0, hData.Length); + dig.BlockUpdate(hData, 0, hData.Length); + + hData = new byte[] + { + (byte) version, + 0xff, + (byte)(hData.Length >> 24), + (byte)(hData.Length >> 16), + (byte)(hData.Length >> 8), + (byte) hData.Length + }; + + sig.BlockUpdate(hData, 0, hData.Length); + dig.BlockUpdate(hData, 0, hData.Length); + + byte[] sigBytes = sig.GenerateSignature(); + byte[] digest = DigestUtilities.DoFinal(dig); + byte[] fingerPrint = new byte[] { digest[0], digest[1] }; + + // an RSA signature + bool isRsa = keyAlgorithm == PublicKeyAlgorithmTag.RsaSign + || keyAlgorithm == PublicKeyAlgorithmTag.RsaGeneral; + + MPInteger[] sigValues = isRsa + ? PgpUtilities.RsaSigToMpi(sigBytes) + : PgpUtilities.DsaSigToMpi(sigBytes); + + return new PgpSignature( + new SignaturePacket(signatureType, privKey.KeyId, keyAlgorithm, + hashAlgorithm, hPkts, unhPkts, fingerPrint, sigValues)); + } + + /// Generate a certification for the passed in ID and key. + /// The ID we are certifying against the public key. + /// The key we are certifying against the ID. + /// The certification. + public PgpSignature GenerateCertification( + string id, + PgpPublicKey pubKey) + { + UpdateWithPublicKey(pubKey); + + // + // hash in the id + // + UpdateWithIdData(0xb4, Strings.ToUtf8ByteArray(id)); + + return Generate(); + } + + /// Generate a certification for the passed in userAttributes. + /// The ID we are certifying against the public key. + /// The key we are certifying against the ID. + /// The certification. + public PgpSignature GenerateCertification( + PgpUserAttributeSubpacketVector userAttributes, + PgpPublicKey pubKey) + { + UpdateWithPublicKey(pubKey); + + // + // hash in the attributes + // + try + { + MemoryStream bOut = new MemoryStream(); + foreach (UserAttributeSubpacket packet in userAttributes.ToSubpacketArray()) + { + packet.Encode(bOut); + } + UpdateWithIdData(0xd1, bOut.ToArray()); + } + catch (IOException e) + { + throw new PgpException("cannot encode subpacket array", e); + } + + return this.Generate(); + } + + /// Generate a certification for the passed in key against the passed in master key. + /// The key we are certifying against. + /// The key we are certifying. + /// The certification. + public PgpSignature GenerateCertification( + PgpPublicKey masterKey, + PgpPublicKey pubKey) + { + UpdateWithPublicKey(masterKey); + UpdateWithPublicKey(pubKey); + + return Generate(); + } + + /// Generate a certification, such as a revocation, for the passed in key. + /// The key we are certifying. + /// The certification. + public PgpSignature GenerateCertification( + PgpPublicKey pubKey) + { + UpdateWithPublicKey(pubKey); + + return Generate(); + } + + private byte[] GetEncodedPublicKey( + PgpPublicKey pubKey) + { + try + { + return pubKey.publicPk.GetEncodedContents(); + } + catch (IOException e) + { + throw new PgpException("exception preparing key.", e); + } + } + + private bool packetPresent( + SignatureSubpacket[] packets, + SignatureSubpacketTag type) + { + for (int i = 0; i != packets.Length; i++) + { + if (packets[i].SubpacketType == type) + { + return true; + } + } + + return false; + } + + private SignatureSubpacket[] insertSubpacket( + SignatureSubpacket[] packets, + SignatureSubpacket subpacket) + { + SignatureSubpacket[] tmp = new SignatureSubpacket[packets.Length + 1]; + tmp[0] = subpacket; + packets.CopyTo(tmp, 1); + return tmp; + } + + private void UpdateWithIdData( + int header, + byte[] idBytes) + { + this.Update( + (byte) header, + (byte)(idBytes.Length >> 24), + (byte)(idBytes.Length >> 16), + (byte)(idBytes.Length >> 8), + (byte)(idBytes.Length)); + this.Update(idBytes); + } + + private void UpdateWithPublicKey( + PgpPublicKey key) + { + byte[] keyBytes = GetEncodedPublicKey(key); + + this.Update( + (byte) 0x99, + (byte)(keyBytes.Length >> 8), + (byte)(keyBytes.Length)); + this.Update(keyBytes); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpSignatureGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpSignatureGenerator.cs.meta new file mode 100644 index 0000000..ce7159e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpSignatureGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8b9a824e9485557408dc3da0e87bab5e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpSignatureList.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpSignatureList.cs new file mode 100644 index 0000000..61976fc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpSignatureList.cs @@ -0,0 +1,51 @@ +using System; + +namespace Org.BouncyCastle.Bcpg.OpenPgp +{ + /// A list of PGP signatures - normally in the signature block after literal data. + public class PgpSignatureList + : PgpObject + { + private PgpSignature[] sigs; + + public PgpSignatureList( + PgpSignature[] sigs) + { + this.sigs = (PgpSignature[]) sigs.Clone(); + } + + public PgpSignatureList( + PgpSignature sig) + { + this.sigs = new PgpSignature[]{ sig }; + } + + public PgpSignature this[int index] + { + get { return sigs[index]; } + } + + [Obsolete("Use 'object[index]' syntax instead")] + public PgpSignature Get( + int index) + { + return this[index]; + } + + [Obsolete("Use 'Count' property instead")] + public int Size + { + get { return sigs.Length; } + } + + public int Count + { + get { return sigs.Length; } + } + + public bool IsEmpty + { + get { return (sigs.Length == 0); } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpSignatureList.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpSignatureList.cs.meta new file mode 100644 index 0000000..4dacb9a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpSignatureList.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8a67231f5d543434da419215848b241e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpSignatureSubpacketGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpSignatureSubpacketGenerator.cs new file mode 100644 index 0000000..3987012 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpSignatureSubpacketGenerator.cs @@ -0,0 +1,236 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Bcpg.Sig; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Bcpg.OpenPgp +{ + /// Generator for signature subpackets. + public class PgpSignatureSubpacketGenerator + { + private IList list = Platform.CreateArrayList(); + + + /// + ///Base constructor, creates an empty generator. + /// + public PgpSignatureSubpacketGenerator() + { + } + + /// + /// Constructor for pre-initialising the generator from an existing one. + /// + /// + /// sigSubV an initial set of subpackets. + /// + public PgpSignatureSubpacketGenerator(PgpSignatureSubpacketVector sigSubV) + { + if (sigSubV != null) + { + SignatureSubpacket[] subs = sigSubV.ToSubpacketArray(); + for (int i = 0; i != sigSubV.Count; i++) + { + list.Add(subs[i]); + } + } + } + + public void SetRevocable( + bool isCritical, + bool isRevocable) + { + list.Add(new Revocable(isCritical, isRevocable)); + } + + public void SetExportable( + bool isCritical, + bool isExportable) + { + list.Add(new Exportable(isCritical, isExportable)); + } + + public void SetFeature( + bool isCritical, + byte feature) + { + list.Add(new Features(isCritical, feature)); + } + + /// + /// Add a TrustSignature packet to the signature. The values for depth and trust are largely + /// installation dependent but there are some guidelines in RFC 4880 - 5.2.3.13. + /// + /// true if the packet is critical. + /// depth level. + /// trust amount. + public void SetTrust( + bool isCritical, + int depth, + int trustAmount) + { + list.Add(new TrustSignature(isCritical, depth, trustAmount)); + } + + /// + /// Set the number of seconds a key is valid for after the time of its creation. + /// A value of zero means the key never expires. + /// + /// True, if should be treated as critical, false otherwise. + /// The number of seconds the key is valid, or zero if no expiry. + public void SetKeyExpirationTime( + bool isCritical, + long seconds) + { + list.Add(new KeyExpirationTime(isCritical, seconds)); + } + + /// + /// Set the number of seconds a signature is valid for after the time of its creation. + /// A value of zero means the signature never expires. + /// + /// True, if should be treated as critical, false otherwise. + /// The number of seconds the signature is valid, or zero if no expiry. + public void SetSignatureExpirationTime( + bool isCritical, + long seconds) + { + list.Add(new SignatureExpirationTime(isCritical, seconds)); + } + + /// + /// Set the creation time for the signature. + ///

    + /// Note: this overrides the generation of a creation time when the signature + /// is generated.

    + ///
    + public void SetSignatureCreationTime( + bool isCritical, + DateTime date) + { + list.Add(new SignatureCreationTime(isCritical, date)); + } + + public void SetPreferredHashAlgorithms( + bool isCritical, + int[] algorithms) + { + list.Add(new PreferredAlgorithms(SignatureSubpacketTag.PreferredHashAlgorithms, isCritical, algorithms)); + } + + public void SetPreferredSymmetricAlgorithms( + bool isCritical, + int[] algorithms) + { + list.Add(new PreferredAlgorithms(SignatureSubpacketTag.PreferredSymmetricAlgorithms, isCritical, algorithms)); + } + + public void SetPreferredCompressionAlgorithms( + bool isCritical, + int[] algorithms) + { + list.Add(new PreferredAlgorithms(SignatureSubpacketTag.PreferredCompressionAlgorithms, isCritical, algorithms)); + } + + public void SetKeyFlags( + bool isCritical, + int flags) + { + list.Add(new KeyFlags(isCritical, flags)); + } + + public void SetSignerUserId( + bool isCritical, + string userId) + { + if (userId == null) + throw new ArgumentNullException("userId"); + + list.Add(new SignerUserId(isCritical, userId)); + } + + public void SetSignerUserId( + bool isCritical, + byte[] rawUserId) + { + if (rawUserId == null) + throw new ArgumentNullException("rawUserId"); + + list.Add(new SignerUserId(isCritical, false, rawUserId)); + } + + public void SetEmbeddedSignature( + bool isCritical, + PgpSignature pgpSignature) + { + byte[] sig = pgpSignature.GetEncoded(); + byte[] data; + + // TODO Should be >= ? + if (sig.Length - 1 > 256) + { + data = new byte[sig.Length - 3]; + } + else + { + data = new byte[sig.Length - 2]; + } + + Array.Copy(sig, sig.Length - data.Length, data, 0, data.Length); + + list.Add(new EmbeddedSignature(isCritical, false, data)); + } + + public void SetPrimaryUserId( + bool isCritical, + bool isPrimaryUserId) + { + list.Add(new PrimaryUserId(isCritical, isPrimaryUserId)); + } + + public void SetNotationData( + bool isCritical, + bool isHumanReadable, + string notationName, + string notationValue) + { + list.Add(new NotationData(isCritical, isHumanReadable, notationName, notationValue)); + } + + /// + /// Sets revocation reason sub packet + /// + public void SetRevocationReason(bool isCritical, RevocationReasonTag reason, + string description) + { + list.Add(new RevocationReason(isCritical, reason, description)); + } + + /// + /// Sets revocation key sub packet + /// + public void SetRevocationKey(bool isCritical, PublicKeyAlgorithmTag keyAlgorithm, byte[] fingerprint) + { + list.Add(new RevocationKey(isCritical, RevocationKeyTag.ClassDefault, keyAlgorithm, fingerprint)); + } + + /// + /// Sets issuer key sub packet + /// + public void SetIssuerKeyID(bool isCritical, long keyID) + { + list.Add(new IssuerKeyId(isCritical, keyID)); + } + + public PgpSignatureSubpacketVector Generate() + { + SignatureSubpacket[] a = new SignatureSubpacket[list.Count]; + for (int i = 0; i < list.Count; ++i) + { + a[i] = (SignatureSubpacket)list[i]; + } + return new PgpSignatureSubpacketVector(a); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpSignatureSubpacketGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpSignatureSubpacketGenerator.cs.meta new file mode 100644 index 0000000..f777c14 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpSignatureSubpacketGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9b6ce08447461f64f95e29b4e078a078 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpSignatureSubpacketVector.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpSignatureSubpacketVector.cs new file mode 100644 index 0000000..810f49c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpSignatureSubpacketVector.cs @@ -0,0 +1,274 @@ +using System; +using System.Collections; +using System.IO; +using Org.BouncyCastle.Bcpg.Sig; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Bcpg.OpenPgp +{ + /// Container for a list of signature subpackets. + public class PgpSignatureSubpacketVector + { + public static PgpSignatureSubpacketVector FromSubpackets(SignatureSubpacket[] packets) + { + if (packets == null) + { + packets = new SignatureSubpacket[0]; + } + return new PgpSignatureSubpacketVector(packets); + } + + private readonly SignatureSubpacket[] packets; + + internal PgpSignatureSubpacketVector( + SignatureSubpacket[] packets) + { + this.packets = packets; + } + + public SignatureSubpacket GetSubpacket( + SignatureSubpacketTag type) + { + for (int i = 0; i != packets.Length; i++) + { + if (packets[i].SubpacketType == type) + { + return packets[i]; + } + } + + return null; + } + + /** + * Return true if a particular subpacket type exists. + * + * @param type type to look for. + * @return true if present, false otherwise. + */ + public bool HasSubpacket( + SignatureSubpacketTag type) + { + return GetSubpacket(type) != null; + } + + /** + * Return all signature subpackets of the passed in type. + * @param type subpacket type code + * @return an array of zero or more matching subpackets. + */ + public SignatureSubpacket[] GetSubpackets( + SignatureSubpacketTag type) + { + int count = 0; + for (int i = 0; i < packets.Length; ++i) + { + if (packets[i].SubpacketType == type) + { + ++count; + } + } + + SignatureSubpacket[] result = new SignatureSubpacket[count]; + + int pos = 0; + for (int i = 0; i < packets.Length; ++i) + { + if (packets[i].SubpacketType == type) + { + result[pos++] = packets[i]; + } + } + + return result; + } + + public NotationData[] GetNotationDataOccurrences() + { + SignatureSubpacket[] notations = GetSubpackets(SignatureSubpacketTag.NotationData); + NotationData[] vals = new NotationData[notations.Length]; + + for (int i = 0; i < notations.Length; i++) + { + vals[i] = (NotationData) notations[i]; + } + + return vals; + } + + [Obsolete("Use 'GetNotationDataOccurrences' instead")] + public NotationData[] GetNotationDataOccurences() + { + return GetNotationDataOccurrences(); + } + + public long GetIssuerKeyId() + { + SignatureSubpacket p = GetSubpacket(SignatureSubpacketTag.IssuerKeyId); + + return p == null ? 0 : ((IssuerKeyId) p).KeyId; + } + + public bool HasSignatureCreationTime() + { + return GetSubpacket(SignatureSubpacketTag.CreationTime) != null; + } + + public DateTime GetSignatureCreationTime() + { + SignatureSubpacket p = GetSubpacket(SignatureSubpacketTag.CreationTime); + + if (p == null) + { + throw new PgpException("SignatureCreationTime not available"); + } + + return ((SignatureCreationTime)p).GetTime(); + } + + /// + /// Return the number of seconds a signature is valid for after its creation date. + /// A value of zero means the signature never expires. + /// + /// Seconds a signature is valid for. + public long GetSignatureExpirationTime() + { + SignatureSubpacket p = GetSubpacket(SignatureSubpacketTag.ExpireTime); + + return p == null ? 0 : ((SignatureExpirationTime) p).Time; + } + + /// + /// Return the number of seconds a key is valid for after its creation date. + /// A value of zero means the key never expires. + /// + /// Seconds a signature is valid for. + public long GetKeyExpirationTime() + { + SignatureSubpacket p = GetSubpacket(SignatureSubpacketTag.KeyExpireTime); + + return p == null ? 0 : ((KeyExpirationTime) p).Time; + } + + public int[] GetPreferredHashAlgorithms() + { + SignatureSubpacket p = GetSubpacket(SignatureSubpacketTag.PreferredHashAlgorithms); + + return p == null ? null : ((PreferredAlgorithms) p).GetPreferences(); + } + + public int[] GetPreferredSymmetricAlgorithms() + { + SignatureSubpacket p = GetSubpacket(SignatureSubpacketTag.PreferredSymmetricAlgorithms); + + return p == null ? null : ((PreferredAlgorithms) p).GetPreferences(); + } + + public int[] GetPreferredCompressionAlgorithms() + { + SignatureSubpacket p = GetSubpacket(SignatureSubpacketTag.PreferredCompressionAlgorithms); + + return p == null ? null : ((PreferredAlgorithms) p).GetPreferences(); + } + + public int GetKeyFlags() + { + SignatureSubpacket p = GetSubpacket(SignatureSubpacketTag.KeyFlags); + + return p == null ? 0 : ((KeyFlags) p).Flags; + } + + public string GetSignerUserId() + { + SignatureSubpacket p = GetSubpacket(SignatureSubpacketTag.SignerUserId); + + return p == null ? null : ((SignerUserId) p).GetId(); + } + + public bool IsPrimaryUserId() + { + PrimaryUserId primaryId = (PrimaryUserId) + this.GetSubpacket(SignatureSubpacketTag.PrimaryUserId); + + if (primaryId != null) + { + return primaryId.IsPrimaryUserId(); + } + + return false; + } + + public PgpSignatureList GetEmbeddedSignatures() + { + SignatureSubpacket [] sigs = GetSubpackets(SignatureSubpacketTag.EmbeddedSignature); + PgpSignature[] l = new PgpSignature[sigs.Length]; + + for (int i = 0; i < sigs.Length; i++) + { + try + { + l[i] = new PgpSignature(SignaturePacket.FromByteArray(sigs[i].GetData())); + } + catch (IOException e) + { + throw new PgpException("Unable to parse signature packet: " + e.Message, e); + } + } + + return new PgpSignatureList(l); + } + + public SignatureSubpacketTag[] GetCriticalTags() + { + int count = 0; + for (int i = 0; i != packets.Length; i++) + { + if (packets[i].IsCritical()) + { + count++; + } + } + + SignatureSubpacketTag[] list = new SignatureSubpacketTag[count]; + + count = 0; + + for (int i = 0; i != packets.Length; i++) + { + if (packets[i].IsCritical()) + { + list[count++] = packets[i].SubpacketType; + } + } + + return list; + } + + public Features GetFeatures() + { + SignatureSubpacket p = this.GetSubpacket(SignatureSubpacketTag.Features); + + if (p == null) + return null; + + return new Features(p.IsCritical(), p.IsLongLength(), p.GetData()); + } + + [Obsolete("Use 'Count' property instead")] + public int Size + { + get { return packets.Length; } + } + + /// Return the number of packets this vector contains. + public int Count + { + get { return packets.Length; } + } + + internal SignatureSubpacket[] ToSubpacketArray() + { + return packets; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpSignatureSubpacketVector.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpSignatureSubpacketVector.cs.meta new file mode 100644 index 0000000..b476ca7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpSignatureSubpacketVector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ad36c5b60db917b4497847af518d179e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpUserAttributeSubpacketVector.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpUserAttributeSubpacketVector.cs new file mode 100644 index 0000000..df50813 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpUserAttributeSubpacketVector.cs @@ -0,0 +1,90 @@ +using Org.BouncyCastle.Bcpg.Attr; + +namespace Org.BouncyCastle.Bcpg.OpenPgp +{ + /// Container for a list of user attribute subpackets. + public class PgpUserAttributeSubpacketVector + { + public static PgpUserAttributeSubpacketVector FromSubpackets(UserAttributeSubpacket[] packets) + { + if (packets == null) + { + packets = new UserAttributeSubpacket[0]; + } + return new PgpUserAttributeSubpacketVector(packets); + } + + private readonly UserAttributeSubpacket[] packets; + + internal PgpUserAttributeSubpacketVector( + UserAttributeSubpacket[] packets) + { + this.packets = packets; + } + + public UserAttributeSubpacket GetSubpacket( + UserAttributeSubpacketTag type) + { + for (int i = 0; i != packets.Length; i++) + { + if (packets[i].SubpacketType == type) + { + return packets[i]; + } + } + + return null; + } + + public ImageAttrib GetImageAttribute() + { + UserAttributeSubpacket p = GetSubpacket(UserAttributeSubpacketTag.ImageAttribute); + + return p == null ? null : (ImageAttrib) p; + } + + internal UserAttributeSubpacket[] ToSubpacketArray() + { + return packets; + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + PgpUserAttributeSubpacketVector other = obj as PgpUserAttributeSubpacketVector; + + if (other == null) + return false; + + if (other.packets.Length != packets.Length) + { + return false; + } + + for (int i = 0; i != packets.Length; i++) + { + if (!other.packets[i].Equals(packets[i])) + { + return false; + } + } + + return true; + } + + public override int GetHashCode() + { + int code = 0; + + foreach (object o in packets) + { + code ^= o.GetHashCode(); + } + + return code; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpUserAttributeSubpacketVector.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpUserAttributeSubpacketVector.cs.meta new file mode 100644 index 0000000..d58720e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpUserAttributeSubpacketVector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f7f7b7ad1b41555459f2c8bb97fcce76 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpUtilities.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpUtilities.cs new file mode 100644 index 0000000..43d6090 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpUtilities.cs @@ -0,0 +1,528 @@ +using System; +using System.IO; +using System.Text; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Bcpg.OpenPgp +{ + /// Basic utility class. + public sealed class PgpUtilities + { + private PgpUtilities() + { + } + + public static MPInteger[] DsaSigToMpi( + byte[] encoding) + { + DerInteger i1, i2; + + try + { + Asn1Sequence s = Asn1Sequence.GetInstance(encoding); + + i1 = DerInteger.GetInstance(s[0]); + i2 = DerInteger.GetInstance(s[1]); + } + catch (Exception e) + { + throw new PgpException("exception encoding signature", e); + } + + return new MPInteger[]{ + new MPInteger(i1.Value), + new MPInteger(i2.Value) + }; + } + + public static MPInteger[] RsaSigToMpi( + byte[] encoding) + { + return new MPInteger[]{ new MPInteger(new BigInteger(1, encoding)) }; + } + + public static string GetDigestName( + HashAlgorithmTag hashAlgorithm) + { + switch (hashAlgorithm) + { + case HashAlgorithmTag.Sha1: + return "SHA1"; + case HashAlgorithmTag.MD2: + return "MD2"; + case HashAlgorithmTag.MD5: + return "MD5"; + case HashAlgorithmTag.RipeMD160: + return "RIPEMD160"; + case HashAlgorithmTag.Sha224: + return "SHA224"; + case HashAlgorithmTag.Sha256: + return "SHA256"; + case HashAlgorithmTag.Sha384: + return "SHA384"; + case HashAlgorithmTag.Sha512: + return "SHA512"; + default: + throw new PgpException("unknown hash algorithm tag in GetDigestName: " + hashAlgorithm); + } + } + + public static string GetSignatureName( + PublicKeyAlgorithmTag keyAlgorithm, + HashAlgorithmTag hashAlgorithm) + { + string encAlg; + switch (keyAlgorithm) + { + case PublicKeyAlgorithmTag.RsaGeneral: + case PublicKeyAlgorithmTag.RsaSign: + encAlg = "RSA"; + break; + case PublicKeyAlgorithmTag.Dsa: + encAlg = "DSA"; + break; + case PublicKeyAlgorithmTag.ECDH: + encAlg = "ECDH"; + break; + case PublicKeyAlgorithmTag.ECDsa: + encAlg = "ECDSA"; + break; + case PublicKeyAlgorithmTag.ElGamalEncrypt: // in some malformed cases. + case PublicKeyAlgorithmTag.ElGamalGeneral: + encAlg = "ElGamal"; + break; + default: + throw new PgpException("unknown algorithm tag in signature:" + keyAlgorithm); + } + + return GetDigestName(hashAlgorithm) + "with" + encAlg; + } + + public static string GetSymmetricCipherName( + SymmetricKeyAlgorithmTag algorithm) + { + switch (algorithm) + { + case SymmetricKeyAlgorithmTag.Null: + return null; + case SymmetricKeyAlgorithmTag.TripleDes: + return "DESEDE"; + case SymmetricKeyAlgorithmTag.Idea: + return "IDEA"; + case SymmetricKeyAlgorithmTag.Cast5: + return "CAST5"; + case SymmetricKeyAlgorithmTag.Blowfish: + return "Blowfish"; + case SymmetricKeyAlgorithmTag.Safer: + return "SAFER"; + case SymmetricKeyAlgorithmTag.Des: + return "DES"; + case SymmetricKeyAlgorithmTag.Aes128: + return "AES"; + case SymmetricKeyAlgorithmTag.Aes192: + return "AES"; + case SymmetricKeyAlgorithmTag.Aes256: + return "AES"; + case SymmetricKeyAlgorithmTag.Twofish: + return "Twofish"; + case SymmetricKeyAlgorithmTag.Camellia128: + return "Camellia"; + case SymmetricKeyAlgorithmTag.Camellia192: + return "Camellia"; + case SymmetricKeyAlgorithmTag.Camellia256: + return "Camellia"; + default: + throw new PgpException("unknown symmetric algorithm: " + algorithm); + } + } + + public static int GetKeySize(SymmetricKeyAlgorithmTag algorithm) + { + int keySize; + switch (algorithm) + { + case SymmetricKeyAlgorithmTag.Des: + keySize = 64; + break; + case SymmetricKeyAlgorithmTag.Idea: + case SymmetricKeyAlgorithmTag.Cast5: + case SymmetricKeyAlgorithmTag.Blowfish: + case SymmetricKeyAlgorithmTag.Safer: + case SymmetricKeyAlgorithmTag.Aes128: + case SymmetricKeyAlgorithmTag.Camellia128: + keySize = 128; + break; + case SymmetricKeyAlgorithmTag.TripleDes: + case SymmetricKeyAlgorithmTag.Aes192: + case SymmetricKeyAlgorithmTag.Camellia192: + keySize = 192; + break; + case SymmetricKeyAlgorithmTag.Aes256: + case SymmetricKeyAlgorithmTag.Twofish: + case SymmetricKeyAlgorithmTag.Camellia256: + keySize = 256; + break; + default: + throw new PgpException("unknown symmetric algorithm: " + algorithm); + } + + return keySize; + } + + public static KeyParameter MakeKey( + SymmetricKeyAlgorithmTag algorithm, + byte[] keyBytes) + { + string algName = GetSymmetricCipherName(algorithm); + + return ParameterUtilities.CreateKeyParameter(algName, keyBytes); + } + + public static KeyParameter MakeRandomKey( + SymmetricKeyAlgorithmTag algorithm, + SecureRandom random) + { + int keySize = GetKeySize(algorithm); + byte[] keyBytes = new byte[(keySize + 7) / 8]; + random.NextBytes(keyBytes); + return MakeKey(algorithm, keyBytes); + } + + internal static byte[] EncodePassPhrase(char[] passPhrase, bool utf8) + { + return passPhrase == null + ? null + : utf8 + ? Encoding.UTF8.GetBytes(passPhrase) + : Strings.ToByteArray(passPhrase); + } + + /// + /// Conversion of the passphrase characters to bytes is performed using Convert.ToByte(), which is + /// the historical behaviour of the library (1.7 and earlier). + /// + public static KeyParameter MakeKeyFromPassPhrase(SymmetricKeyAlgorithmTag algorithm, S2k s2k, char[] passPhrase) + { + return DoMakeKeyFromPassPhrase(algorithm, s2k, EncodePassPhrase(passPhrase, false), true); + } + + /// + /// The passphrase is encoded to bytes using UTF8 (Encoding.UTF8.GetBytes). + /// + public static KeyParameter MakeKeyFromPassPhraseUtf8(SymmetricKeyAlgorithmTag algorithm, S2k s2k, char[] passPhrase) + { + return DoMakeKeyFromPassPhrase(algorithm, s2k, EncodePassPhrase(passPhrase, true), true); + } + + /// + /// Allows the caller to handle the encoding of the passphrase to bytes. + /// + public static KeyParameter MakeKeyFromPassPhraseRaw(SymmetricKeyAlgorithmTag algorithm, S2k s2k, byte[] rawPassPhrase) + { + return DoMakeKeyFromPassPhrase(algorithm, s2k, rawPassPhrase, false); + } + + internal static KeyParameter DoMakeKeyFromPassPhrase(SymmetricKeyAlgorithmTag algorithm, S2k s2k, byte[] rawPassPhrase, bool clearPassPhrase) + { + int keySize = GetKeySize(algorithm); + byte[] pBytes = rawPassPhrase; + byte[] keyBytes = new byte[(keySize + 7) / 8]; + + int generatedBytes = 0; + int loopCount = 0; + + while (generatedBytes < keyBytes.Length) + { + IDigest digest; + if (s2k != null) + { + string digestName = GetDigestName(s2k.HashAlgorithm); + + try + { + digest = DigestUtilities.GetDigest(digestName); + } + catch (Exception e) + { + throw new PgpException("can't find S2k digest", e); + } + + for (int i = 0; i != loopCount; i++) + { + digest.Update(0); + } + + byte[] iv = s2k.GetIV(); + + switch (s2k.Type) + { + case S2k.Simple: + digest.BlockUpdate(pBytes, 0, pBytes.Length); + break; + case S2k.Salted: + digest.BlockUpdate(iv, 0, iv.Length); + digest.BlockUpdate(pBytes, 0, pBytes.Length); + break; + case S2k.SaltedAndIterated: + long count = s2k.IterationCount; + digest.BlockUpdate(iv, 0, iv.Length); + digest.BlockUpdate(pBytes, 0, pBytes.Length); + + count -= iv.Length + pBytes.Length; + + while (count > 0) + { + if (count < iv.Length) + { + digest.BlockUpdate(iv, 0, (int)count); + break; + } + else + { + digest.BlockUpdate(iv, 0, iv.Length); + count -= iv.Length; + } + + if (count < pBytes.Length) + { + digest.BlockUpdate(pBytes, 0, (int)count); + count = 0; + } + else + { + digest.BlockUpdate(pBytes, 0, pBytes.Length); + count -= pBytes.Length; + } + } + break; + default: + throw new PgpException("unknown S2k type: " + s2k.Type); + } + } + else + { + try + { + digest = DigestUtilities.GetDigest("MD5"); + + for (int i = 0; i != loopCount; i++) + { + digest.Update(0); + } + + digest.BlockUpdate(pBytes, 0, pBytes.Length); + } + catch (Exception e) + { + throw new PgpException("can't find MD5 digest", e); + } + } + + byte[] dig = DigestUtilities.DoFinal(digest); + + if (dig.Length > (keyBytes.Length - generatedBytes)) + { + Array.Copy(dig, 0, keyBytes, generatedBytes, keyBytes.Length - generatedBytes); + } + else + { + Array.Copy(dig, 0, keyBytes, generatedBytes, dig.Length); + } + + generatedBytes += dig.Length; + + loopCount++; + } + + if (clearPassPhrase && rawPassPhrase != null) + { + Array.Clear(rawPassPhrase, 0, rawPassPhrase.Length); + } + + return MakeKey(algorithm, keyBytes); + } + +#if !PORTABLE || NETSTANDARD1_3 + /// Write out the passed in file as a literal data packet. + public static void WriteFileToLiteralData( + Stream output, + char fileType, + FileInfo file) + { + PgpLiteralDataGenerator lData = new PgpLiteralDataGenerator(); + Stream pOut = lData.Open(output, fileType, file.Name, file.Length, file.LastWriteTime); + PipeFileContents(file, pOut, 32768); + } + + /// Write out the passed in file as a literal data packet in partial packet format. + public static void WriteFileToLiteralData( + Stream output, + char fileType, + FileInfo file, + byte[] buffer) + { + PgpLiteralDataGenerator lData = new PgpLiteralDataGenerator(); + Stream pOut = lData.Open(output, fileType, file.Name, file.LastWriteTime, buffer); + PipeFileContents(file, pOut, buffer.Length); + } + + private static void PipeFileContents(FileInfo file, Stream pOut, int bufSize) + { + FileStream inputStream = file.OpenRead(); + byte[] buf = new byte[bufSize]; + + try + { + int len; + while ((len = inputStream.Read(buf, 0, buf.Length)) > 0) + { + pOut.Write(buf, 0, len); + } + } + finally + { + Array.Clear(buf, 0, buf.Length); + + Platform.Dispose(pOut); + Platform.Dispose(inputStream); + } + } +#endif + + private const int ReadAhead = 60; + + private static bool IsPossiblyBase64( + int ch) + { + return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') + || (ch >= '0' && ch <= '9') || (ch == '+') || (ch == '/') + || (ch == '\r') || (ch == '\n'); + } + + /// + /// Return either an ArmoredInputStream or a BcpgInputStream based on whether + /// the initial characters of the stream are binary PGP encodings or not. + /// + public static Stream GetDecoderStream( + Stream inputStream) + { + // TODO Remove this restriction? + if (!inputStream.CanSeek) + throw new ArgumentException("inputStream must be seek-able", "inputStream"); + + long markedPos = inputStream.Position; + + int ch = inputStream.ReadByte(); + if ((ch & 0x80) != 0) + { + inputStream.Position = markedPos; + + return inputStream; + } + + if (!IsPossiblyBase64(ch)) + { + inputStream.Position = markedPos; + + return new ArmoredInputStream(inputStream); + } + + byte[] buf = new byte[ReadAhead]; + int count = 1; + int index = 1; + + buf[0] = (byte)ch; + while (count != ReadAhead && (ch = inputStream.ReadByte()) >= 0) + { + if (!IsPossiblyBase64(ch)) + { + inputStream.Position = markedPos; + + return new ArmoredInputStream(inputStream); + } + + if (ch != '\n' && ch != '\r') + { + buf[index++] = (byte)ch; + } + + count++; + } + + inputStream.Position = markedPos; + + // + // nothing but new lines, little else, assume regular armoring + // + if (count < 4) + { + return new ArmoredInputStream(inputStream); + } + + // + // test our non-blank data + // + byte[] firstBlock = new byte[8]; + + Array.Copy(buf, 0, firstBlock, 0, firstBlock.Length); + + try + { + byte[] decoded = Base64.Decode(firstBlock); + + // + // it's a base64 PGP block. + // + bool hasHeaders = (decoded[0] & 0x80) == 0; + + return new ArmoredInputStream(inputStream, hasHeaders); + } + catch (IOException e) + { + throw e; + } + catch (Exception e) + { + throw new IOException(e.Message); + } + } + + internal static IWrapper CreateWrapper(SymmetricKeyAlgorithmTag encAlgorithm) + { + switch (encAlgorithm) + { + case SymmetricKeyAlgorithmTag.Aes128: + case SymmetricKeyAlgorithmTag.Aes192: + case SymmetricKeyAlgorithmTag.Aes256: + return WrapperUtilities.GetWrapper("AESWRAP"); + case SymmetricKeyAlgorithmTag.Camellia128: + case SymmetricKeyAlgorithmTag.Camellia192: + case SymmetricKeyAlgorithmTag.Camellia256: + return WrapperUtilities.GetWrapper("CAMELLIAWRAP"); + default: + throw new PgpException("unknown wrap algorithm: " + encAlgorithm); + } + } + + internal static byte[] GenerateIV(int length, SecureRandom random) + { + byte[] iv = new byte[length]; + random.NextBytes(iv); + return iv; + } + + internal static S2k GenerateS2k(HashAlgorithmTag hashAlgorithm, int s2kCount, SecureRandom random) + { + byte[] iv = GenerateIV(8, random); + return new S2k(hashAlgorithm, iv, s2kCount); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpUtilities.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpUtilities.cs.meta new file mode 100644 index 0000000..a742ef6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpUtilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f331de8507a1b694c8843427e690cc1d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpV3SignatureGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpV3SignatureGenerator.cs new file mode 100644 index 0000000..fc8b42d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpV3SignatureGenerator.cs @@ -0,0 +1,199 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities.Date; + +namespace Org.BouncyCastle.Bcpg.OpenPgp +{ + /// Generator for old style PGP V3 Signatures. + // TODO Should be able to implement ISigner? + public class PgpV3SignatureGenerator + { + private PublicKeyAlgorithmTag keyAlgorithm; + private HashAlgorithmTag hashAlgorithm; + private PgpPrivateKey privKey; + private ISigner sig; + private IDigest dig; + private int signatureType; + private byte lastb; + + /// Create a generator for the passed in keyAlgorithm and hashAlgorithm codes. + public PgpV3SignatureGenerator( + PublicKeyAlgorithmTag keyAlgorithm, + HashAlgorithmTag hashAlgorithm) + { + this.keyAlgorithm = keyAlgorithm; + this.hashAlgorithm = hashAlgorithm; + + dig = DigestUtilities.GetDigest(PgpUtilities.GetDigestName(hashAlgorithm)); + sig = SignerUtilities.GetSigner(PgpUtilities.GetSignatureName(keyAlgorithm, hashAlgorithm)); + } + + /// Initialise the generator for signing. + public void InitSign( + int sigType, + PgpPrivateKey key) + { + InitSign(sigType, key, null); + } + + /// Initialise the generator for signing. + public void InitSign( + int sigType, + PgpPrivateKey key, + SecureRandom random) + { + this.privKey = key; + this.signatureType = sigType; + + try + { + ICipherParameters cp = key.Key; + if (random != null) + { + cp = new ParametersWithRandom(key.Key, random); + } + + sig.Init(true, cp); + } + catch (InvalidKeyException e) + { + throw new PgpException("invalid key.", e); + } + + dig.Reset(); + lastb = 0; + } + + public void Update( + byte b) + { + if (signatureType == PgpSignature.CanonicalTextDocument) + { + doCanonicalUpdateByte(b); + } + else + { + doUpdateByte(b); + } + } + + private void doCanonicalUpdateByte( + byte b) + { + if (b == '\r') + { + doUpdateCRLF(); + } + else if (b == '\n') + { + if (lastb != '\r') + { + doUpdateCRLF(); + } + } + else + { + doUpdateByte(b); + } + + lastb = b; + } + + private void doUpdateCRLF() + { + doUpdateByte((byte)'\r'); + doUpdateByte((byte)'\n'); + } + + private void doUpdateByte( + byte b) + { + sig.Update(b); + dig.Update(b); + } + + public void Update( + byte[] b) + { + if (signatureType == PgpSignature.CanonicalTextDocument) + { + for (int i = 0; i != b.Length; i++) + { + doCanonicalUpdateByte(b[i]); + } + } + else + { + sig.BlockUpdate(b, 0, b.Length); + dig.BlockUpdate(b, 0, b.Length); + } + } + + public void Update( + byte[] b, + int off, + int len) + { + if (signatureType == PgpSignature.CanonicalTextDocument) + { + int finish = off + len; + + for (int i = off; i != finish; i++) + { + doCanonicalUpdateByte(b[i]); + } + } + else + { + sig.BlockUpdate(b, off, len); + dig.BlockUpdate(b, off, len); + } + } + + /// Return the one pass header associated with the current signature. + public PgpOnePassSignature GenerateOnePassVersion( + bool isNested) + { + return new PgpOnePassSignature( + new OnePassSignaturePacket(signatureType, hashAlgorithm, keyAlgorithm, privKey.KeyId, isNested)); + } + + /// Return a V3 signature object containing the current signature state. + public PgpSignature Generate() + { + long creationTime = DateTimeUtilities.CurrentUnixMs() / 1000L; + + byte[] hData = new byte[] + { + (byte) signatureType, + (byte)(creationTime >> 24), + (byte)(creationTime >> 16), + (byte)(creationTime >> 8), + (byte) creationTime + }; + + sig.BlockUpdate(hData, 0, hData.Length); + dig.BlockUpdate(hData, 0, hData.Length); + + byte[] sigBytes = sig.GenerateSignature(); + byte[] digest = DigestUtilities.DoFinal(dig); + byte[] fingerPrint = new byte[]{ digest[0], digest[1] }; + + // an RSA signature + bool isRsa = keyAlgorithm == PublicKeyAlgorithmTag.RsaSign + || keyAlgorithm == PublicKeyAlgorithmTag.RsaGeneral; + + MPInteger[] sigValues = isRsa + ? PgpUtilities.RsaSigToMpi(sigBytes) + : PgpUtilities.DsaSigToMpi(sigBytes); + + return new PgpSignature( + new SignaturePacket(3, signatureType, privKey.KeyId, keyAlgorithm, + hashAlgorithm, creationTime * 1000L, fingerPrint, sigValues)); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpV3SignatureGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpV3SignatureGenerator.cs.meta new file mode 100644 index 0000000..39e7226 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/PgpV3SignatureGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 82ebc3f9cc36792499812a8bc735617f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/Rfc6637Utilities.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/Rfc6637Utilities.cs new file mode 100644 index 0000000..5d992ec --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/Rfc6637Utilities.cs @@ -0,0 +1,138 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Bcpg.OpenPgp +{ + public sealed class Rfc6637Utilities + { + private Rfc6637Utilities() + { + } + + // "Anonymous Sender ", which is the octet sequence + private static readonly byte[] ANONYMOUS_SENDER = Hex.Decode("416E6F6E796D6F75732053656E64657220202020"); + + public static string GetAgreementAlgorithm(PublicKeyPacket pubKeyData) + { + ECDHPublicBcpgKey ecKey = (ECDHPublicBcpgKey)pubKeyData.Key; + + switch (ecKey.HashAlgorithm) + { + case HashAlgorithmTag.Sha256: + return "ECCDHwithSHA256CKDF"; + case HashAlgorithmTag.Sha384: + return "ECCDHwithSHA384CKDF"; + case HashAlgorithmTag.Sha512: + return "ECCDHwithSHA512CKDF"; + default: + throw new ArgumentException("Unknown hash algorithm specified: " + ecKey.HashAlgorithm); + } + } + + public static DerObjectIdentifier GetKeyEncryptionOID(SymmetricKeyAlgorithmTag algID) + { + switch (algID) + { + case SymmetricKeyAlgorithmTag.Aes128: + return NistObjectIdentifiers.IdAes128Wrap; + case SymmetricKeyAlgorithmTag.Aes192: + return NistObjectIdentifiers.IdAes192Wrap; + case SymmetricKeyAlgorithmTag.Aes256: + return NistObjectIdentifiers.IdAes256Wrap; + default: + throw new PgpException("unknown symmetric algorithm ID: " + algID); + } + } + + public static int GetKeyLength(SymmetricKeyAlgorithmTag algID) + { + switch (algID) + { + case SymmetricKeyAlgorithmTag.Aes128: + return 16; + case SymmetricKeyAlgorithmTag.Aes192: + return 24; + case SymmetricKeyAlgorithmTag.Aes256: + return 32; + default: + throw new PgpException("unknown symmetric algorithm ID: " + algID); + } + } + + public static byte[] CreateKey(PublicKeyPacket pubKeyData, ECPoint s) + { + byte[] userKeyingMaterial = CreateUserKeyingMaterial(pubKeyData); + + ECDHPublicBcpgKey ecKey = (ECDHPublicBcpgKey)pubKeyData.Key; + + return Kdf(ecKey.HashAlgorithm, s, GetKeyLength(ecKey.SymmetricKeyAlgorithm), userKeyingMaterial); + } + + // RFC 6637 - Section 8 + // curve_OID_len = (byte)len(curve_OID); + // Param = curve_OID_len || curve_OID || public_key_alg_ID || 03 + // || 01 || KDF_hash_ID || KEK_alg_ID for AESKeyWrap || "Anonymous + // Sender " || recipient_fingerprint; + // Z_len = the key size for the KEK_alg_ID used with AESKeyWrap + // Compute Z = KDF( S, Z_len, Param ); + public static byte[] CreateUserKeyingMaterial(PublicKeyPacket pubKeyData) + { + MemoryStream pOut = new MemoryStream(); + ECDHPublicBcpgKey ecKey = (ECDHPublicBcpgKey)pubKeyData.Key; + byte[] encOid = ecKey.CurveOid.GetEncoded(); + + pOut.Write(encOid, 1, encOid.Length - 1); + pOut.WriteByte((byte)pubKeyData.Algorithm); + pOut.WriteByte(0x03); + pOut.WriteByte(0x01); + pOut.WriteByte((byte)ecKey.HashAlgorithm); + pOut.WriteByte((byte)ecKey.SymmetricKeyAlgorithm); + pOut.Write(ANONYMOUS_SENDER, 0, ANONYMOUS_SENDER.Length); + + byte[] fingerprint = PgpPublicKey.CalculateFingerprint(pubKeyData); + pOut.Write(fingerprint, 0, fingerprint.Length); + + return pOut.ToArray(); + } + + // RFC 6637 - Section 7 + // Implements KDF( X, oBits, Param ); + // Input: point X = (x,y) + // oBits - the desired size of output + // hBits - the size of output of hash function Hash + // Param - octets representing the parameters + // Assumes that oBits <= hBits + // Convert the point X to the octet string, see section 6: + // ZB' = 04 || x || y + // and extract the x portion from ZB' + // ZB = x; + // MB = Hash ( 00 || 00 || 00 || 01 || ZB || Param ); + // return oBits leftmost bits of MB. + private static byte[] Kdf(HashAlgorithmTag digestAlg, ECPoint s, int keyLen, byte[] parameters) + { + byte[] ZB = s.XCoord.GetEncoded(); + + string digestName = PgpUtilities.GetDigestName(digestAlg); + IDigest digest = DigestUtilities.GetDigest(digestName); + + digest.Update(0x00); + digest.Update(0x00); + digest.Update(0x00); + digest.Update(0x01); + digest.BlockUpdate(ZB, 0, ZB.Length); + digest.BlockUpdate(parameters, 0, parameters.Length); + + byte[] hash = DigestUtilities.DoFinal(digest); + + return Arrays.CopyOfRange(hash, 0, keyLen); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/Rfc6637Utilities.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/Rfc6637Utilities.cs.meta new file mode 100644 index 0000000..10d1ec6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/Rfc6637Utilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2f501f62893e1054885fb9d27ede2980 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/SXprUtilities.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/SXprUtilities.cs new file mode 100644 index 0000000..68ff373 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/SXprUtilities.cs @@ -0,0 +1,102 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Bcpg.OpenPgp +{ + /** + * Utility functions for looking a S-expression keys. This class will move when it finds a better home! + *

    + * Format documented here: + * http://git.gnupg.org/cgi-bin/gitweb.cgi?p=gnupg.git;a=blob;f=agent/keyformat.txt;h=42c4b1f06faf1bbe71ffadc2fee0fad6bec91a97;hb=refs/heads/master + *

    + */ + public sealed class SXprUtilities + { + private SXprUtilities() + { + } + + private static int ReadLength(Stream input, int ch) + { + int len = ch - '0'; + + while ((ch = input.ReadByte()) >= 0 && ch != ':') + { + len = len * 10 + ch - '0'; + } + + return len; + } + + internal static string ReadString(Stream input, int ch) + { + int len = ReadLength(input, ch); + + char[] chars = new char[len]; + + for (int i = 0; i != chars.Length; i++) + { + chars[i] = (char)input.ReadByte(); + } + + return new string(chars); + } + + internal static byte[] ReadBytes(Stream input, int ch) + { + int len = ReadLength(input, ch); + + byte[] data = new byte[len]; + + Streams.ReadFully(input, data); + + return data; + } + + internal static S2k ParseS2k(Stream input) + { + SkipOpenParenthesis(input); + + string alg = ReadString(input, input.ReadByte()); + byte[] iv = ReadBytes(input, input.ReadByte()); + long iterationCount = Int64.Parse(ReadString(input, input.ReadByte())); + + SkipCloseParenthesis(input); + + // we have to return the actual iteration count provided. + return new MyS2k(HashAlgorithmTag.Sha1, iv, iterationCount); + } + + internal static void SkipOpenParenthesis(Stream input) + { + int ch = input.ReadByte(); + if (ch != '(') + throw new IOException("unknown character encountered"); + } + + internal static void SkipCloseParenthesis(Stream input) + { + int ch = input.ReadByte(); + if (ch != ')') + throw new IOException("unknown character encountered"); + } + + private class MyS2k : S2k + { + private readonly long mIterationCount64; + + internal MyS2k(HashAlgorithmTag algorithm, byte[] iv, long iterationCount64) + : base(algorithm, iv, (int)iterationCount64) + { + this.mIterationCount64 = iterationCount64; + } + + public override long IterationCount + { + get { return mIterationCount64; } + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/SXprUtilities.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/SXprUtilities.cs.meta new file mode 100644 index 0000000..93396cb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/SXprUtilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 847510bb7bbc7a44089fd7e089ac800e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/WrappedGeneratorStream.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/WrappedGeneratorStream.cs new file mode 100644 index 0000000..5f4a4b0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/WrappedGeneratorStream.cs @@ -0,0 +1,37 @@ +using System.IO; + +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Bcpg.OpenPgp +{ + public class WrappedGeneratorStream + : FilterStream + { + private readonly IStreamGenerator gen; + + public WrappedGeneratorStream( + IStreamGenerator gen, + Stream str) + : base(str) + { + this.gen = gen; + } + +#if PORTABLE + protected override void Dispose(bool disposing) + { + if (disposing) + { + gen.Close(); + return; + } + base.Dispose(disposing); + } +#else + public override void Close() + { + gen.Close(); + } +#endif + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/WrappedGeneratorStream.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/WrappedGeneratorStream.cs.meta new file mode 100644 index 0000000..58a03da --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openpgp/WrappedGeneratorStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c98d78aa4334aeb4a8a7f50d07b9b5d2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl.meta new file mode 100644 index 0000000..a452d32 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: cad9eff1c8bc1824283287c982ee2630 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/EncryptionException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/EncryptionException.cs new file mode 100644 index 0000000..043e902 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/EncryptionException.cs @@ -0,0 +1,25 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Security +{ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE) + [Serializable] +#endif + public class EncryptionException + : IOException + { + public EncryptionException( + string message) + : base(message) + { + } + + public EncryptionException( + string message, + Exception exception) + : base(message, exception) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/EncryptionException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/EncryptionException.cs.meta new file mode 100644 index 0000000..aa62b00 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/EncryptionException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 614083bc2308b3b4799de5b6bce34265 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/IPasswordFinder.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/IPasswordFinder.cs new file mode 100644 index 0000000..4fcef1b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/IPasswordFinder.cs @@ -0,0 +1,9 @@ +using System; + +namespace Org.BouncyCastle.OpenSsl +{ + public interface IPasswordFinder + { + char[] GetPassword(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/IPasswordFinder.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/IPasswordFinder.cs.meta new file mode 100644 index 0000000..69d78c2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/IPasswordFinder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 395f3f3d2d51fdb4890813cbdcbc6b3d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/MiscPemGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/MiscPemGenerator.cs new file mode 100644 index 0000000..4237adf --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/MiscPemGenerator.cs @@ -0,0 +1,273 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Pkcs; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Security.Certificates; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; +using Org.BouncyCastle.Utilities.IO.Pem; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.OpenSsl +{ + /** + * PEM generator for the original set of PEM objects used in Open SSL. + */ + public class MiscPemGenerator + : PemObjectGenerator + { + private object obj; + private string algorithm; + private char[] password; + private SecureRandom random; + + public MiscPemGenerator(object obj) + { + this.obj = obj; + } + + public MiscPemGenerator( + object obj, + string algorithm, + char[] password, + SecureRandom random) + { + this.obj = obj; + this.algorithm = algorithm; + this.password = password; + this.random = random; + } + + private static PemObject CreatePemObject(object obj) + { + if (obj == null) + throw new ArgumentNullException("obj"); + + if (obj is AsymmetricCipherKeyPair) + { + return CreatePemObject(((AsymmetricCipherKeyPair)obj).Private); + } + + string type; + byte[] encoding; + + if (obj is PemObject) + return (PemObject)obj; + + if (obj is PemObjectGenerator) + return ((PemObjectGenerator)obj).Generate(); + + if (obj is X509Certificate) + { + // TODO Should we prefer "X509 CERTIFICATE" here? + type = "CERTIFICATE"; + try + { + encoding = ((X509Certificate)obj).GetEncoded(); + } + catch (CertificateEncodingException e) + { + throw new IOException("Cannot Encode object: " + e.ToString()); + } + } + else if (obj is X509Crl) + { + type = "X509 CRL"; + try + { + encoding = ((X509Crl)obj).GetEncoded(); + } + catch (CrlException e) + { + throw new IOException("Cannot Encode object: " + e.ToString()); + } + } + else if (obj is AsymmetricKeyParameter) + { + AsymmetricKeyParameter akp = (AsymmetricKeyParameter) obj; + if (akp.IsPrivate) + { + encoding = EncodePrivateKey(akp, out type); + } + else + { + type = "PUBLIC KEY"; + + encoding = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(akp).GetDerEncoded(); + } + } + else if (obj is IX509AttributeCertificate) + { + type = "ATTRIBUTE CERTIFICATE"; + encoding = ((X509V2AttributeCertificate)obj).GetEncoded(); + } + else if (obj is Pkcs10CertificationRequest) + { + type = "CERTIFICATE REQUEST"; + encoding = ((Pkcs10CertificationRequest)obj).GetEncoded(); + } + else if (obj is Asn1.Cms.ContentInfo) + { + type = "PKCS7"; + encoding = ((Asn1.Cms.ContentInfo)obj).GetEncoded(); + } + else + { + throw new PemGenerationException("Object type not supported: " + Platform.GetTypeName(obj)); + } + + return new PemObject(type, encoding); + } + +// private string GetHexEncoded(byte[] bytes) +// { +// bytes = Hex.Encode(bytes); +// +// char[] chars = new char[bytes.Length]; +// +// for (int i = 0; i != bytes.Length; i++) +// { +// chars[i] = (char)bytes[i]; +// } +// +// return new string(chars); +// } + + private static PemObject CreatePemObject( + object obj, + string algorithm, + char[] password, + SecureRandom random) + { + if (obj == null) + throw new ArgumentNullException("obj"); + if (algorithm == null) + throw new ArgumentNullException("algorithm"); + if (password == null) + throw new ArgumentNullException("password"); + if (random == null) + throw new ArgumentNullException("random"); + + if (obj is AsymmetricCipherKeyPair) + { + return CreatePemObject(((AsymmetricCipherKeyPair)obj).Private, algorithm, password, random); + } + + string type = null; + byte[] keyData = null; + + if (obj is AsymmetricKeyParameter) + { + AsymmetricKeyParameter akp = (AsymmetricKeyParameter) obj; + if (akp.IsPrivate) + { + keyData = EncodePrivateKey(akp, out type); + } + } + + if (type == null || keyData == null) + { + // TODO Support other types? + throw new PemGenerationException("Object type not supported: " + Platform.GetTypeName(obj)); + } + + + string dekAlgName = Platform.ToUpperInvariant(algorithm); + + // Note: For backward compatibility + if (dekAlgName == "DESEDE") + { + dekAlgName = "DES-EDE3-CBC"; + } + + int ivLength = Platform.StartsWith(dekAlgName, "AES-") ? 16 : 8; + + byte[] iv = new byte[ivLength]; + random.NextBytes(iv); + + byte[] encData = PemUtilities.Crypt(true, keyData, password, dekAlgName, iv); + + IList headers = Platform.CreateArrayList(2); + + headers.Add(new PemHeader("Proc-Type", "4,ENCRYPTED")); + headers.Add(new PemHeader("DEK-Info", dekAlgName + "," + Hex.ToHexString(iv))); + + return new PemObject(type, headers, encData); + } + + private static byte[] EncodePrivateKey( + AsymmetricKeyParameter akp, + out string keyType) + { + PrivateKeyInfo info = PrivateKeyInfoFactory.CreatePrivateKeyInfo(akp); + AlgorithmIdentifier algID = info.PrivateKeyAlgorithm; + DerObjectIdentifier oid = algID.Algorithm; + + if (oid.Equals(X9ObjectIdentifiers.IdDsa)) + { + keyType = "DSA PRIVATE KEY"; + + DsaParameter p = DsaParameter.GetInstance(algID.Parameters); + + BigInteger x = ((DsaPrivateKeyParameters) akp).X; + BigInteger y = p.G.ModPow(x, p.P); + + // TODO Create an ASN1 object somewhere for this? + return new DerSequence( + new DerInteger(0), + new DerInteger(p.P), + new DerInteger(p.Q), + new DerInteger(p.G), + new DerInteger(y), + new DerInteger(x)).GetEncoded(); + } + + if (oid.Equals(PkcsObjectIdentifiers.RsaEncryption)) + { + keyType = "RSA PRIVATE KEY"; + + return info.ParsePrivateKey().GetEncoded(); + } + else if (oid.Equals(CryptoProObjectIdentifiers.GostR3410x2001) + || oid.Equals(X9ObjectIdentifiers.IdECPublicKey)) + { + keyType = "EC PRIVATE KEY"; + + return info.ParsePrivateKey().GetEncoded(); + } + else + { + keyType = "PRIVATE KEY"; + + return info.GetEncoded(); + } + } + + public PemObject Generate() + { + try + { + if (algorithm != null) + { + return CreatePemObject(obj, algorithm, password, random); + } + + return CreatePemObject(obj); + } + catch (IOException e) + { + throw new PemGenerationException("encoding exception", e); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/MiscPemGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/MiscPemGenerator.cs.meta new file mode 100644 index 0000000..023b545 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/MiscPemGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2fffe2888242d6841a9d00b259ff3ac0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/PEMException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/PEMException.cs new file mode 100644 index 0000000..6b3e510 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/PEMException.cs @@ -0,0 +1,25 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.OpenSsl +{ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE) + [Serializable] +#endif + public class PemException + : IOException + { + public PemException( + string message) + : base(message) + { + } + + public PemException( + string message, + Exception exception) + : base(message, exception) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/PEMException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/PEMException.cs.meta new file mode 100644 index 0000000..f1a1ea8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/PEMException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c3896ddb39fee9246a1ea537793c8a84 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/PEMReader.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/PEMReader.cs new file mode 100644 index 0000000..9a5f99b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/PEMReader.cs @@ -0,0 +1,401 @@ +using System; +using System.Collections; +using System.Diagnostics; +using System.IO; +using System.Text; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.Sec; +using Org.BouncyCastle.Asn1.TeleTrust; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.EC; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Pkcs; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; +using Org.BouncyCastle.Utilities.IO.Pem; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.OpenSsl +{ + /** + * Class for reading OpenSSL PEM encoded streams containing + * X509 certificates, PKCS8 encoded keys and PKCS7 objects. + *

    + * In the case of PKCS7 objects the reader will return a CMS ContentInfo object. Keys and + * Certificates will be returned using the appropriate java.security type.

    + */ + public class PemReader + : Org.BouncyCastle.Utilities.IO.Pem.PemReader + { +// private static readonly IDictionary parsers = new Hashtable(); + + static PemReader() + { +// parsers.Add("CERTIFICATE REQUEST", new PKCS10CertificationRequestParser()); +// parsers.Add("NEW CERTIFICATE REQUEST", new PKCS10CertificationRequestParser()); +// parsers.Add("CERTIFICATE", new X509CertificateParser(provider)); +// parsers.Add("X509 CERTIFICATE", new X509CertificateParser(provider)); +// parsers.Add("X509 CRL", new X509CRLParser(provider)); +// parsers.Add("PKCS7", new PKCS7Parser()); +// parsers.Add("ATTRIBUTE CERTIFICATE", new X509AttributeCertificateParser()); +// parsers.Add("EC PARAMETERS", new ECNamedCurveSpecParser()); +// parsers.Add("PUBLIC KEY", new PublicKeyParser(provider)); +// parsers.Add("RSA PUBLIC KEY", new RSAPublicKeyParser(provider)); +// parsers.Add("RSA PRIVATE KEY", new RSAKeyPairParser(provider)); +// parsers.Add("DSA PRIVATE KEY", new DSAKeyPairParser(provider)); +// parsers.Add("EC PRIVATE KEY", new ECDSAKeyPairParser(provider)); +// parsers.Add("ENCRYPTED PRIVATE KEY", new EncryptedPrivateKeyParser(provider)); +// parsers.Add("PRIVATE KEY", new PrivateKeyParser(provider)); + } + + private readonly IPasswordFinder pFinder; + + /** + * Create a new PemReader + * + * @param reader the Reader + */ + public PemReader( + TextReader reader) + : this(reader, null) + { + } + + /** + * Create a new PemReader with a password finder + * + * @param reader the Reader + * @param pFinder the password finder + */ + public PemReader( + TextReader reader, + IPasswordFinder pFinder) + : base(reader) + { + this.pFinder = pFinder; + } + + public object ReadObject() + { + PemObject obj = ReadPemObject(); + + if (obj == null) + return null; + + // TODO Follow Java build and map to parser objects? +// if (parsers.Contains(obj.Type)) +// return ((PemObjectParser)parsers[obj.Type]).ParseObject(obj); + + if (Platform.EndsWith(obj.Type, "PRIVATE KEY")) + return ReadPrivateKey(obj); + + switch (obj.Type) + { + case "PUBLIC KEY": + return ReadPublicKey(obj); + case "RSA PUBLIC KEY": + return ReadRsaPublicKey(obj); + case "CERTIFICATE REQUEST": + case "NEW CERTIFICATE REQUEST": + return ReadCertificateRequest(obj); + case "CERTIFICATE": + case "X509 CERTIFICATE": + return ReadCertificate(obj); + case "PKCS7": + case "CMS": + return ReadPkcs7(obj); + case "X509 CRL": + return ReadCrl(obj); + case "ATTRIBUTE CERTIFICATE": + return ReadAttributeCertificate(obj); + // TODO Add back in when tests done, and return type issue resolved + //case "EC PARAMETERS": + // return ReadECParameters(obj); + default: + throw new IOException("unrecognised object: " + obj.Type); + } + } + + private AsymmetricKeyParameter ReadRsaPublicKey(PemObject pemObject) + { + RsaPublicKeyStructure rsaPubStructure = RsaPublicKeyStructure.GetInstance( + Asn1Object.FromByteArray(pemObject.Content)); + + return new RsaKeyParameters( + false, // not private + rsaPubStructure.Modulus, + rsaPubStructure.PublicExponent); + } + + private AsymmetricKeyParameter ReadPublicKey(PemObject pemObject) + { + return PublicKeyFactory.CreateKey(pemObject.Content); + } + + /** + * Reads in a X509Certificate. + * + * @return the X509Certificate + * @throws IOException if an I/O error occured + */ + private X509Certificate ReadCertificate(PemObject pemObject) + { + try + { + return new X509CertificateParser().ReadCertificate(pemObject.Content); + } + catch (Exception e) + { + throw new PemException("problem parsing cert: " + e.ToString()); + } + } + + /** + * Reads in a X509CRL. + * + * @return the X509Certificate + * @throws IOException if an I/O error occured + */ + private X509Crl ReadCrl(PemObject pemObject) + { + try + { + return new X509CrlParser().ReadCrl(pemObject.Content); + } + catch (Exception e) + { + throw new PemException("problem parsing cert: " + e.ToString()); + } + } + + /** + * Reads in a PKCS10 certification request. + * + * @return the certificate request. + * @throws IOException if an I/O error occured + */ + private Pkcs10CertificationRequest ReadCertificateRequest(PemObject pemObject) + { + try + { + return new Pkcs10CertificationRequest(pemObject.Content); + } + catch (Exception e) + { + throw new PemException("problem parsing cert: " + e.ToString()); + } + } + + /** + * Reads in a X509 Attribute Certificate. + * + * @return the X509 Attribute Certificate + * @throws IOException if an I/O error occured + */ + private IX509AttributeCertificate ReadAttributeCertificate(PemObject pemObject) + { + return new X509V2AttributeCertificate(pemObject.Content); + } + + /** + * Reads in a PKCS7 object. This returns a ContentInfo object suitable for use with the CMS + * API. + * + * @return the X509Certificate + * @throws IOException if an I/O error occured + */ + // TODO Consider returning Asn1.Pkcs.ContentInfo + private Asn1.Cms.ContentInfo ReadPkcs7(PemObject pemObject) + { + try + { + return Asn1.Cms.ContentInfo.GetInstance( + Asn1Object.FromByteArray(pemObject.Content)); + } + catch (Exception e) + { + throw new PemException("problem parsing PKCS7 object: " + e.ToString()); + } + } + + /** + * Read a Key Pair + */ + private object ReadPrivateKey(PemObject pemObject) + { + // + // extract the key + // + Debug.Assert(Platform.EndsWith(pemObject.Type, "PRIVATE KEY")); + + string type = pemObject.Type.Substring(0, pemObject.Type.Length - "PRIVATE KEY".Length).Trim(); + byte[] keyBytes = pemObject.Content; + + IDictionary fields = Platform.CreateHashtable(); + foreach (PemHeader header in pemObject.Headers) + { + fields[header.Name] = header.Value; + } + + string procType = (string) fields["Proc-Type"]; + + if (procType == "4,ENCRYPTED") + { + if (pFinder == null) + throw new PasswordException("No password finder specified, but a password is required"); + + char[] password = pFinder.GetPassword(); + + if (password == null) + throw new PasswordException("Password is null, but a password is required"); + + string dekInfo = (string) fields["DEK-Info"]; + string[] tknz = dekInfo.Split(','); + + string dekAlgName = tknz[0].Trim(); + byte[] iv = Hex.Decode(tknz[1].Trim()); + + keyBytes = PemUtilities.Crypt(false, keyBytes, password, dekAlgName, iv); + } + + try + { + AsymmetricKeyParameter pubSpec, privSpec; + Asn1Sequence seq = Asn1Sequence.GetInstance(keyBytes); + + switch (type) + { + case "RSA": + { + if (seq.Count != 9) + throw new PemException("malformed sequence in RSA private key"); + + RsaPrivateKeyStructure rsa = RsaPrivateKeyStructure.GetInstance(seq); + + pubSpec = new RsaKeyParameters(false, rsa.Modulus, rsa.PublicExponent); + privSpec = new RsaPrivateCrtKeyParameters( + rsa.Modulus, rsa.PublicExponent, rsa.PrivateExponent, + rsa.Prime1, rsa.Prime2, rsa.Exponent1, rsa.Exponent2, + rsa.Coefficient); + + break; + } + + case "DSA": + { + if (seq.Count != 6) + throw new PemException("malformed sequence in DSA private key"); + + // TODO Create an ASN1 object somewhere for this? + //DerInteger v = (DerInteger)seq[0]; + DerInteger p = (DerInteger)seq[1]; + DerInteger q = (DerInteger)seq[2]; + DerInteger g = (DerInteger)seq[3]; + DerInteger y = (DerInteger)seq[4]; + DerInteger x = (DerInteger)seq[5]; + + DsaParameters parameters = new DsaParameters(p.Value, q.Value, g.Value); + + privSpec = new DsaPrivateKeyParameters(x.Value, parameters); + pubSpec = new DsaPublicKeyParameters(y.Value, parameters); + + break; + } + + case "EC": + { + ECPrivateKeyStructure pKey = ECPrivateKeyStructure.GetInstance(seq); + AlgorithmIdentifier algId = new AlgorithmIdentifier( + X9ObjectIdentifiers.IdECPublicKey, pKey.GetParameters()); + + PrivateKeyInfo privInfo = new PrivateKeyInfo(algId, pKey.ToAsn1Object()); + + // TODO Are the keys returned here ECDSA, as Java version forces? + privSpec = PrivateKeyFactory.CreateKey(privInfo); + + DerBitString pubKey = pKey.GetPublicKey(); + if (pubKey != null) + { + SubjectPublicKeyInfo pubInfo = new SubjectPublicKeyInfo(algId, pubKey.GetBytes()); + + // TODO Are the keys returned here ECDSA, as Java version forces? + pubSpec = PublicKeyFactory.CreateKey(pubInfo); + } + else + { + pubSpec = ECKeyPairGenerator.GetCorrespondingPublicKey( + (ECPrivateKeyParameters)privSpec); + } + + break; + } + + case "ENCRYPTED": + { + char[] password = pFinder.GetPassword(); + + if (password == null) + throw new PasswordException("Password is null, but a password is required"); + + return PrivateKeyFactory.DecryptKey(password, EncryptedPrivateKeyInfo.GetInstance(seq)); + } + + case "": + { + return PrivateKeyFactory.CreateKey(PrivateKeyInfo.GetInstance(seq)); + } + + default: + throw new ArgumentException("Unknown key type: " + type, "type"); + } + + return new AsymmetricCipherKeyPair(pubSpec, privSpec); + } + catch (IOException e) + { + throw e; + } + catch (Exception e) + { + throw new PemException( + "problem creating " + type + " private key: " + e.ToString()); + } + } + + // TODO Add an equivalent class for ECNamedCurveParameterSpec? + //private ECNamedCurveParameterSpec ReadECParameters( +// private X9ECParameters ReadECParameters(PemObject pemObject) +// { +// DerObjectIdentifier oid = (DerObjectIdentifier)Asn1Object.FromByteArray(pemObject.Content); +// +// //return ECNamedCurveTable.getParameterSpec(oid.Id); +// return GetCurveParameters(oid.Id); +// } + + //private static ECDomainParameters GetCurveParameters( + private static X9ECParameters GetCurveParameters( + string name) + { + // TODO ECGost3410NamedCurves support (returns ECDomainParameters though) + + X9ECParameters ecP = CustomNamedCurves.GetByName(name); + if (ecP == null) + { + ecP = ECNamedCurveTable.GetByName(name); + } + + if (ecP == null) + throw new Exception("unknown curve name: " + name); + + //return new ECDomainParameters(ecP.Curve, ecP.G, ecP.N, ecP.H, ecP.GetSeed()); + return ecP; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/PEMReader.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/PEMReader.cs.meta new file mode 100644 index 0000000..b0b8456 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/PEMReader.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7d610847b28e0ae48ae59e46fac21cb0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/PEMUtilities.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/PEMUtilities.cs new file mode 100644 index 0000000..b58e5e7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/PEMUtilities.cs @@ -0,0 +1,158 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.OpenSsl +{ + internal sealed class PemUtilities + { + private enum PemBaseAlg { AES_128, AES_192, AES_256, BF, DES, DES_EDE, DES_EDE3, RC2, RC2_40, RC2_64 }; + private enum PemMode { CBC, CFB, ECB, OFB }; + + static PemUtilities() + { + // Signal to obfuscation tools not to change enum constants + ((PemBaseAlg)Enums.GetArbitraryValue(typeof(PemBaseAlg))).ToString(); + ((PemMode)Enums.GetArbitraryValue(typeof(PemMode))).ToString(); + } + + private static void ParseDekAlgName( + string dekAlgName, + out PemBaseAlg baseAlg, + out PemMode mode) + { + try + { + mode = PemMode.ECB; + + if (dekAlgName == "DES-EDE" || dekAlgName == "DES-EDE3") + { + baseAlg = (PemBaseAlg)Enums.GetEnumValue(typeof(PemBaseAlg), dekAlgName); + return; + } + + int pos = dekAlgName.LastIndexOf('-'); + if (pos >= 0) + { + baseAlg = (PemBaseAlg)Enums.GetEnumValue(typeof(PemBaseAlg), dekAlgName.Substring(0, pos)); + mode = (PemMode)Enums.GetEnumValue(typeof(PemMode), dekAlgName.Substring(pos + 1)); + return; + } + } + catch (ArgumentException) + { + } + + throw new EncryptionException("Unknown DEK algorithm: " + dekAlgName); + } + + internal static byte[] Crypt( + bool encrypt, + byte[] bytes, + char[] password, + string dekAlgName, + byte[] iv) + { + PemBaseAlg baseAlg; + PemMode mode; + ParseDekAlgName(dekAlgName, out baseAlg, out mode); + + string padding; + switch (mode) + { + case PemMode.CBC: + case PemMode.ECB: + padding = "PKCS5Padding"; + break; + case PemMode.CFB: + case PemMode.OFB: + padding = "NoPadding"; + break; + default: + throw new EncryptionException("Unknown DEK algorithm: " + dekAlgName); + } + + string algorithm; + + byte[] salt = iv; + switch (baseAlg) + { + case PemBaseAlg.AES_128: + case PemBaseAlg.AES_192: + case PemBaseAlg.AES_256: + algorithm = "AES"; + if (salt.Length > 8) + { + salt = new byte[8]; + Array.Copy(iv, 0, salt, 0, salt.Length); + } + break; + case PemBaseAlg.BF: + algorithm = "BLOWFISH"; + break; + case PemBaseAlg.DES: + algorithm = "DES"; + break; + case PemBaseAlg.DES_EDE: + case PemBaseAlg.DES_EDE3: + algorithm = "DESede"; + break; + case PemBaseAlg.RC2: + case PemBaseAlg.RC2_40: + case PemBaseAlg.RC2_64: + algorithm = "RC2"; + break; + default: + throw new EncryptionException("Unknown DEK algorithm: " + dekAlgName); + } + + string cipherName = algorithm + "/" + mode + "/" + padding; + IBufferedCipher cipher = CipherUtilities.GetCipher(cipherName); + + ICipherParameters cParams = GetCipherParameters(password, baseAlg, salt); + + if (mode != PemMode.ECB) + { + cParams = new ParametersWithIV(cParams, iv); + } + + cipher.Init(encrypt, cParams); + + return cipher.DoFinal(bytes); + } + + private static ICipherParameters GetCipherParameters( + char[] password, + PemBaseAlg baseAlg, + byte[] salt) + { + string algorithm; + int keyBits; + switch (baseAlg) + { + case PemBaseAlg.AES_128: keyBits = 128; algorithm = "AES128"; break; + case PemBaseAlg.AES_192: keyBits = 192; algorithm = "AES192"; break; + case PemBaseAlg.AES_256: keyBits = 256; algorithm = "AES256"; break; + case PemBaseAlg.BF: keyBits = 128; algorithm = "BLOWFISH"; break; + case PemBaseAlg.DES: keyBits = 64; algorithm = "DES"; break; + case PemBaseAlg.DES_EDE: keyBits = 128; algorithm = "DESEDE"; break; + case PemBaseAlg.DES_EDE3: keyBits = 192; algorithm = "DESEDE3"; break; + case PemBaseAlg.RC2: keyBits = 128; algorithm = "RC2"; break; + case PemBaseAlg.RC2_40: keyBits = 40; algorithm = "RC2"; break; + case PemBaseAlg.RC2_64: keyBits = 64; algorithm = "RC2"; break; + default: + return null; + } + + OpenSslPbeParametersGenerator pGen = new OpenSslPbeParametersGenerator(); + + pGen.Init(PbeParametersGenerator.Pkcs5PasswordToBytes(password), salt); + + return pGen.GenerateDerivedParameters(algorithm, keyBits); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/PEMUtilities.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/PEMUtilities.cs.meta new file mode 100644 index 0000000..9569f10 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/PEMUtilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0a81820d263a36742951d208185bd03b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/PEMWriter.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/PEMWriter.cs new file mode 100644 index 0000000..aefb018 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/PEMWriter.cs @@ -0,0 +1,61 @@ +using System; +using System.Diagnostics; +using System.Globalization; +using System.IO; +using System.Text; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Pkcs; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Security.Certificates; +using Org.BouncyCastle.Utilities.Encoders; +using Org.BouncyCastle.Utilities.IO.Pem; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.OpenSsl +{ + /// General purpose writer for OpenSSL PEM objects. + public class PemWriter + : Org.BouncyCastle.Utilities.IO.Pem.PemWriter + { + /// The TextWriter object to write the output to. + public PemWriter( + TextWriter writer) + : base(writer) + { + } + + public void WriteObject( + object obj) + { + try + { + base.WriteObject(new MiscPemGenerator(obj)); + } + catch (PemGenerationException e) + { + if (e.InnerException is IOException) + throw (IOException)e.InnerException; + + throw e; + } + } + + public void WriteObject( + object obj, + string algorithm, + char[] password, + SecureRandom random) + { + base.WriteObject(new MiscPemGenerator(obj, algorithm, password, random)); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/PEMWriter.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/PEMWriter.cs.meta new file mode 100644 index 0000000..a68496b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/PEMWriter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 899b0e978b8ad25478475eb4ca68c5e1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/PasswordException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/PasswordException.cs new file mode 100644 index 0000000..38e679b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/PasswordException.cs @@ -0,0 +1,25 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Security +{ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE) + [Serializable] +#endif + public class PasswordException + : IOException + { + public PasswordException( + string message) + : base(message) + { + } + + public PasswordException( + string message, + Exception exception) + : base(message, exception) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/PasswordException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/PasswordException.cs.meta new file mode 100644 index 0000000..8a2d1af --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/PasswordException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 22d2a0644e2dcf149913be5c97095846 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/Pkcs8Generator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/Pkcs8Generator.cs new file mode 100644 index 0000000..d03ea08 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/Pkcs8Generator.cs @@ -0,0 +1,111 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Pkcs; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities.IO.Pem; + +namespace Org.BouncyCastle.OpenSsl +{ + public class Pkcs8Generator + : PemObjectGenerator + { + // FIXME See PbeUtilities static constructor +// public static readonly string Aes128Cbc = NistObjectIdentifiers.IdAes128Cbc.Id; +// public static readonly string Aes192Cbc = NistObjectIdentifiers.IdAes192Cbc.Id; +// public static readonly string Aes256Cbc = NistObjectIdentifiers.IdAes256Cbc.Id; +// +// public static readonly string Des3Cbc = PkcsObjectIdentifiers.DesEde3Cbc.Id; + + public static readonly string PbeSha1_RC4_128 = PkcsObjectIdentifiers.PbeWithShaAnd128BitRC4.Id; + public static readonly string PbeSha1_RC4_40 = PkcsObjectIdentifiers.PbeWithShaAnd40BitRC4.Id; + public static readonly string PbeSha1_3DES = PkcsObjectIdentifiers.PbeWithShaAnd3KeyTripleDesCbc.Id; + public static readonly string PbeSha1_2DES = PkcsObjectIdentifiers.PbeWithShaAnd2KeyTripleDesCbc.Id; + public static readonly string PbeSha1_RC2_128 = PkcsObjectIdentifiers.PbeWithShaAnd128BitRC2Cbc.Id; + public static readonly string PbeSha1_RC2_40 = PkcsObjectIdentifiers.PbewithShaAnd40BitRC2Cbc.Id; + + private char[] password; + private string algorithm; + private int iterationCount; + private AsymmetricKeyParameter privKey; + private SecureRandom random; + + /** + * Constructor for an unencrypted private key PEM object. + * + * @param key private key to be encoded. + */ + public Pkcs8Generator(AsymmetricKeyParameter privKey) + { + this.privKey = privKey; + } + + /** + * Constructor for an encrypted private key PEM object. + * + * @param key private key to be encoded + * @param algorithm encryption algorithm to use + * @param provider provider to use + * @throws NoSuchAlgorithmException if algorithm/mode cannot be found + */ + public Pkcs8Generator(AsymmetricKeyParameter privKey, string algorithm) + { + // TODO Check privKey.IsPrivate + this.privKey = privKey; + this.algorithm = algorithm; + this.iterationCount = 2048; + } + + public SecureRandom SecureRandom + { + set { this.random = value; } + } + + public char[] Password + { + set { this.password = value; } + } + + public int IterationCount + { + set { this.iterationCount = value; } + } + + public PemObject Generate() + { + if (algorithm == null) + { + PrivateKeyInfo pki = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privKey); + + return new PemObject("PRIVATE KEY", pki.GetEncoded()); + } + + // TODO Theoretically, the amount of salt needed depends on the algorithm + byte[] salt = new byte[20]; + if (random == null) + { + random = new SecureRandom(); + } + random.NextBytes(salt); + + try + { + EncryptedPrivateKeyInfo epki = EncryptedPrivateKeyInfoFactory.CreateEncryptedPrivateKeyInfo( + algorithm, password, salt, iterationCount, privKey); + + return new PemObject("ENCRYPTED PRIVATE KEY", epki.GetEncoded()); + } + catch (Exception e) + { + throw new PemGenerationException("Couldn't encrypt private key", e); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/Pkcs8Generator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/Pkcs8Generator.cs.meta new file mode 100644 index 0000000..d72ea4a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/openssl/Pkcs8Generator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f54630bb520b2a745930948eaba7924f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs.meta new file mode 100644 index 0000000..ad457d7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 1c4e6109fa001904aa9db64f69e45a46 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/AsymmetricKeyEntry.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/AsymmetricKeyEntry.cs new file mode 100644 index 0000000..6da3ade --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/AsymmetricKeyEntry.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Pkcs +{ + public class AsymmetricKeyEntry + : Pkcs12Entry + { + private readonly AsymmetricKeyParameter key; + + public AsymmetricKeyEntry( + AsymmetricKeyParameter key) + : base(Platform.CreateHashtable()) + { + this.key = key; + } + +#if !(SILVERLIGHT || PORTABLE) + [Obsolete] + public AsymmetricKeyEntry( + AsymmetricKeyParameter key, + Hashtable attributes) + : base(attributes) + { + this.key = key; + } +#endif + + public AsymmetricKeyEntry( + AsymmetricKeyParameter key, + IDictionary attributes) + : base(attributes) + { + this.key = key; + } + + public AsymmetricKeyParameter Key + { + get { return this.key; } + } + + public override bool Equals(object obj) + { + AsymmetricKeyEntry other = obj as AsymmetricKeyEntry; + + if (other == null) + return false; + + return key.Equals(other.key); + } + + public override int GetHashCode() + { + return ~key.GetHashCode(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/AsymmetricKeyEntry.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/AsymmetricKeyEntry.cs.meta new file mode 100644 index 0000000..e068864 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/AsymmetricKeyEntry.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f3b61759ef248a7499975ea1da8d4d04 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/EncryptedPrivateKeyInfoFactory.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/EncryptedPrivateKeyInfoFactory.cs new file mode 100644 index 0000000..000eb7a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/EncryptedPrivateKeyInfoFactory.cs @@ -0,0 +1,102 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Pkcs +{ + public sealed class EncryptedPrivateKeyInfoFactory + { + private EncryptedPrivateKeyInfoFactory() + { + } + + public static EncryptedPrivateKeyInfo CreateEncryptedPrivateKeyInfo( + DerObjectIdentifier algorithm, + char[] passPhrase, + byte[] salt, + int iterationCount, + AsymmetricKeyParameter key) + { + return CreateEncryptedPrivateKeyInfo( + algorithm.Id, passPhrase, salt, iterationCount, + PrivateKeyInfoFactory.CreatePrivateKeyInfo(key)); + } + + public static EncryptedPrivateKeyInfo CreateEncryptedPrivateKeyInfo( + string algorithm, + char[] passPhrase, + byte[] salt, + int iterationCount, + AsymmetricKeyParameter key) + { + return CreateEncryptedPrivateKeyInfo( + algorithm, passPhrase, salt, iterationCount, + PrivateKeyInfoFactory.CreatePrivateKeyInfo(key)); + } + + public static EncryptedPrivateKeyInfo CreateEncryptedPrivateKeyInfo( + string algorithm, + char[] passPhrase, + byte[] salt, + int iterationCount, + PrivateKeyInfo keyInfo) + { + IBufferedCipher cipher = PbeUtilities.CreateEngine(algorithm) as IBufferedCipher; + if (cipher == null) + throw new Exception("Unknown encryption algorithm: " + algorithm); + + Asn1Encodable pbeParameters = PbeUtilities.GenerateAlgorithmParameters( + algorithm, salt, iterationCount); + ICipherParameters cipherParameters = PbeUtilities.GenerateCipherParameters( + algorithm, passPhrase, pbeParameters); + cipher.Init(true, cipherParameters); + byte[] encoding = cipher.DoFinal(keyInfo.GetEncoded()); + + DerObjectIdentifier oid = PbeUtilities.GetObjectIdentifier(algorithm); + AlgorithmIdentifier algID = new AlgorithmIdentifier(oid, pbeParameters); + return new EncryptedPrivateKeyInfo(algID, encoding); + } + + public static EncryptedPrivateKeyInfo CreateEncryptedPrivateKeyInfo( + DerObjectIdentifier cipherAlgorithm, + DerObjectIdentifier prfAlgorithm, + char[] passPhrase, + byte[] salt, + int iterationCount, + SecureRandom random, + AsymmetricKeyParameter key) + { + return CreateEncryptedPrivateKeyInfo( + cipherAlgorithm, prfAlgorithm, passPhrase, salt, iterationCount, random, + PrivateKeyInfoFactory.CreatePrivateKeyInfo(key)); + } + + public static EncryptedPrivateKeyInfo CreateEncryptedPrivateKeyInfo( + DerObjectIdentifier cipherAlgorithm, + DerObjectIdentifier prfAlgorithm, + char[] passPhrase, + byte[] salt, + int iterationCount, + SecureRandom random, + PrivateKeyInfo keyInfo) + { + IBufferedCipher cipher = CipherUtilities.GetCipher(cipherAlgorithm) as IBufferedCipher; + if (cipher == null) + throw new Exception("Unknown encryption algorithm: " + cipherAlgorithm); + + Asn1Encodable pbeParameters = PbeUtilities.GenerateAlgorithmParameters( + cipherAlgorithm, prfAlgorithm, salt, iterationCount, random); + ICipherParameters cipherParameters = PbeUtilities.GenerateCipherParameters( + PkcsObjectIdentifiers.IdPbeS2, passPhrase, pbeParameters); + cipher.Init(true, cipherParameters); + byte[] encoding = cipher.DoFinal(keyInfo.GetEncoded()); + + AlgorithmIdentifier algID = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdPbeS2, pbeParameters); + return new EncryptedPrivateKeyInfo(algID, encoding); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/EncryptedPrivateKeyInfoFactory.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/EncryptedPrivateKeyInfoFactory.cs.meta new file mode 100644 index 0000000..518df86 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/EncryptedPrivateKeyInfoFactory.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1ac26827948f18c408384f2d079ba676 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/PKCS12StoreBuilder.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/PKCS12StoreBuilder.cs new file mode 100644 index 0000000..b61a9ea --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/PKCS12StoreBuilder.cs @@ -0,0 +1,50 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Pkcs; + +namespace Org.BouncyCastle.Pkcs +{ + public class Pkcs12StoreBuilder + { + private DerObjectIdentifier keyAlgorithm = PkcsObjectIdentifiers.PbeWithShaAnd3KeyTripleDesCbc; + private DerObjectIdentifier certAlgorithm = PkcsObjectIdentifiers.PbewithShaAnd40BitRC2Cbc; + private DerObjectIdentifier keyPrfAlgorithm = null; + private DerObjectIdentifier certPrfAlgorithm = null; + private bool useDerEncoding = false; + + public Pkcs12StoreBuilder() + { + } + + public Pkcs12Store Build() + { + return new Pkcs12Store(keyAlgorithm, keyPrfAlgorithm, certAlgorithm, certPrfAlgorithm, useDerEncoding); + } + + public Pkcs12StoreBuilder SetCertAlgorithm(DerObjectIdentifier certAlgorithm) + { + this.certAlgorithm = certAlgorithm; + return this; + } + + public Pkcs12StoreBuilder SetKeyAlgorithm(DerObjectIdentifier keyAlgorithm) + { + this.keyAlgorithm = keyAlgorithm; + return this; + } + + // Specify a PKCS#5 Scheme 2 encryption for keys + public Pkcs12StoreBuilder SetKeyAlgorithm(DerObjectIdentifier keyAlgorithm, DerObjectIdentifier keyPrfAlgorithm) + { + this.keyAlgorithm = keyAlgorithm; + this.keyPrfAlgorithm = keyPrfAlgorithm; + return this; + } + public Pkcs12StoreBuilder SetUseDerEncoding(bool useDerEncoding) + { + this.useDerEncoding = useDerEncoding; + return this; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/PKCS12StoreBuilder.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/PKCS12StoreBuilder.cs.meta new file mode 100644 index 0000000..7a72777 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/PKCS12StoreBuilder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0912fc1422fbecc4794dbc6087dc6144 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/Pkcs10CertificationRequest.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/Pkcs10CertificationRequest.cs new file mode 100644 index 0000000..c4624bf --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/Pkcs10CertificationRequest.cs @@ -0,0 +1,553 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Oiw; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.TeleTrust; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; +using Org.BouncyCastle.X509; +using Org.BouncyCastle.Crypto.Operators; +using Org.BouncyCastle.Asn1.Utilities; + +namespace Org.BouncyCastle.Pkcs +{ + /// + /// A class for verifying and creating Pkcs10 Certification requests. + /// + /// + /// CertificationRequest ::= Sequence { + /// certificationRequestInfo CertificationRequestInfo, + /// signatureAlgorithm AlgorithmIdentifier{{ SignatureAlgorithms }}, + /// signature BIT STRING + /// } + /// + /// CertificationRequestInfo ::= Sequence { + /// version Integer { v1(0) } (v1,...), + /// subject Name, + /// subjectPKInfo SubjectPublicKeyInfo{{ PKInfoAlgorithms }}, + /// attributes [0] Attributes{{ CRIAttributes }} + /// } + /// + /// Attributes { ATTRIBUTE:IOSet } ::= Set OF Attr{{ IOSet }} + /// + /// Attr { ATTRIBUTE:IOSet } ::= Sequence { + /// type ATTRIBUTE.&id({IOSet}), + /// values Set SIZE(1..MAX) OF ATTRIBUTE.&Type({IOSet}{\@type}) + /// } + /// + /// see + public class Pkcs10CertificationRequest + : CertificationRequest + { + protected static readonly IDictionary algorithms = Platform.CreateHashtable(); + protected static readonly IDictionary exParams = Platform.CreateHashtable(); + protected static readonly IDictionary keyAlgorithms = Platform.CreateHashtable(); + protected static readonly IDictionary oids = Platform.CreateHashtable(); + protected static readonly ISet noParams = new HashSet(); + + static Pkcs10CertificationRequest() + { + algorithms.Add("MD2WITHRSAENCRYPTION", PkcsObjectIdentifiers.MD2WithRsaEncryption); + algorithms.Add("MD2WITHRSA", PkcsObjectIdentifiers.MD2WithRsaEncryption); + algorithms.Add("MD5WITHRSAENCRYPTION", PkcsObjectIdentifiers.MD5WithRsaEncryption); + algorithms.Add("MD5WITHRSA", PkcsObjectIdentifiers.MD5WithRsaEncryption); + algorithms.Add("RSAWITHMD5", PkcsObjectIdentifiers.MD5WithRsaEncryption); + algorithms.Add("SHA1WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha1WithRsaEncryption); + algorithms.Add("SHA-1WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha1WithRsaEncryption); + algorithms.Add("SHA1WITHRSA", PkcsObjectIdentifiers.Sha1WithRsaEncryption); + algorithms.Add("SHA-1WITHRSA", PkcsObjectIdentifiers.Sha1WithRsaEncryption); + algorithms.Add("SHA224WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha224WithRsaEncryption); + algorithms.Add("SHA-224WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha224WithRsaEncryption); + algorithms.Add("SHA224WITHRSA", PkcsObjectIdentifiers.Sha224WithRsaEncryption); + algorithms.Add("SHA-224WITHRSA", PkcsObjectIdentifiers.Sha224WithRsaEncryption); + algorithms.Add("SHA256WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha256WithRsaEncryption); + algorithms.Add("SHA-256WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha256WithRsaEncryption); + algorithms.Add("SHA256WITHRSA", PkcsObjectIdentifiers.Sha256WithRsaEncryption); + algorithms.Add("SHA-256WITHRSA", PkcsObjectIdentifiers.Sha256WithRsaEncryption); + algorithms.Add("SHA384WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha384WithRsaEncryption); + algorithms.Add("SHA-384WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha384WithRsaEncryption); + algorithms.Add("SHA384WITHRSA", PkcsObjectIdentifiers.Sha384WithRsaEncryption); + algorithms.Add("SHA-384WITHRSA", PkcsObjectIdentifiers.Sha384WithRsaEncryption); + algorithms.Add("SHA512WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha512WithRsaEncryption); + algorithms.Add("SHA-512WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha512WithRsaEncryption); + algorithms.Add("SHA512WITHRSA", PkcsObjectIdentifiers.Sha512WithRsaEncryption); + algorithms.Add("SHA-512WITHRSA", PkcsObjectIdentifiers.Sha512WithRsaEncryption); + algorithms.Add("SHA512(224)WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha512_224WithRSAEncryption); + algorithms.Add("SHA-512(224)WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha512_224WithRSAEncryption); + algorithms.Add("SHA512(224)WITHRSA", PkcsObjectIdentifiers.Sha512_224WithRSAEncryption); + algorithms.Add("SHA-512(224)WITHRSA", PkcsObjectIdentifiers.Sha512_224WithRSAEncryption); + algorithms.Add("SHA512(256)WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha512_256WithRSAEncryption); + algorithms.Add("SHA-512(256)WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha512_256WithRSAEncryption); + algorithms.Add("SHA512(256)WITHRSA", PkcsObjectIdentifiers.Sha512_256WithRSAEncryption); + algorithms.Add("SHA-512(256)WITHRSA", PkcsObjectIdentifiers.Sha512_256WithRSAEncryption); + algorithms.Add("SHA1WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss); + algorithms.Add("SHA224WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss); + algorithms.Add("SHA256WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss); + algorithms.Add("SHA384WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss); + algorithms.Add("SHA512WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss); + algorithms.Add("RSAWITHSHA1", PkcsObjectIdentifiers.Sha1WithRsaEncryption); + algorithms.Add("RIPEMD128WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128); + algorithms.Add("RIPEMD128WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128); + algorithms.Add("RIPEMD160WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160); + algorithms.Add("RIPEMD160WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160); + algorithms.Add("RIPEMD256WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256); + algorithms.Add("RIPEMD256WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256); + algorithms.Add("SHA1WITHDSA", X9ObjectIdentifiers.IdDsaWithSha1); + algorithms.Add("DSAWITHSHA1", X9ObjectIdentifiers.IdDsaWithSha1); + algorithms.Add("SHA224WITHDSA", NistObjectIdentifiers.DsaWithSha224); + algorithms.Add("SHA256WITHDSA", NistObjectIdentifiers.DsaWithSha256); + algorithms.Add("SHA384WITHDSA", NistObjectIdentifiers.DsaWithSha384); + algorithms.Add("SHA512WITHDSA", NistObjectIdentifiers.DsaWithSha512); + algorithms.Add("SHA1WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha1); + algorithms.Add("SHA224WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha224); + algorithms.Add("SHA256WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha256); + algorithms.Add("SHA384WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha384); + algorithms.Add("SHA512WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha512); + algorithms.Add("ECDSAWITHSHA1", X9ObjectIdentifiers.ECDsaWithSha1); + algorithms.Add("GOST3411WITHGOST3410", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94); + algorithms.Add("GOST3410WITHGOST3411", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94); + algorithms.Add("GOST3411WITHECGOST3410", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001); + algorithms.Add("GOST3411WITHECGOST3410-2001", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001); + algorithms.Add("GOST3411WITHGOST3410-2001", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001); + + // + // reverse mappings + // + oids.Add(PkcsObjectIdentifiers.Sha1WithRsaEncryption, "SHA1WITHRSA"); + oids.Add(PkcsObjectIdentifiers.Sha224WithRsaEncryption, "SHA224WITHRSA"); + oids.Add(PkcsObjectIdentifiers.Sha256WithRsaEncryption, "SHA256WITHRSA"); + oids.Add(PkcsObjectIdentifiers.Sha384WithRsaEncryption, "SHA384WITHRSA"); + oids.Add(PkcsObjectIdentifiers.Sha512WithRsaEncryption, "SHA512WITHRSA"); + oids.Add(PkcsObjectIdentifiers.Sha512_224WithRSAEncryption, "SHA512(224)WITHRSA"); + oids.Add(PkcsObjectIdentifiers.Sha512_256WithRSAEncryption, "SHA512(256)WITHRSA"); + oids.Add(CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94, "GOST3411WITHGOST3410"); + oids.Add(CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001, "GOST3411WITHECGOST3410"); + + oids.Add(PkcsObjectIdentifiers.MD5WithRsaEncryption, "MD5WITHRSA"); + oids.Add(PkcsObjectIdentifiers.MD2WithRsaEncryption, "MD2WITHRSA"); + oids.Add(X9ObjectIdentifiers.IdDsaWithSha1, "SHA1WITHDSA"); + oids.Add(X9ObjectIdentifiers.ECDsaWithSha1, "SHA1WITHECDSA"); + oids.Add(X9ObjectIdentifiers.ECDsaWithSha224, "SHA224WITHECDSA"); + oids.Add(X9ObjectIdentifiers.ECDsaWithSha256, "SHA256WITHECDSA"); + oids.Add(X9ObjectIdentifiers.ECDsaWithSha384, "SHA384WITHECDSA"); + oids.Add(X9ObjectIdentifiers.ECDsaWithSha512, "SHA512WITHECDSA"); + oids.Add(OiwObjectIdentifiers.MD5WithRsa, "MD5WITHRSA"); + oids.Add(OiwObjectIdentifiers.Sha1WithRsa, "SHA1WITHRSA"); + oids.Add(OiwObjectIdentifiers.DsaWithSha1, "SHA1WITHDSA"); + oids.Add(NistObjectIdentifiers.DsaWithSha224, "SHA224WITHDSA"); + oids.Add(NistObjectIdentifiers.DsaWithSha256, "SHA256WITHDSA"); + + // + // key types + // + keyAlgorithms.Add(PkcsObjectIdentifiers.RsaEncryption, "RSA"); + keyAlgorithms.Add(X9ObjectIdentifiers.IdDsa, "DSA"); + + // + // According to RFC 3279, the ASN.1 encoding SHALL (id-dsa-with-sha1) or MUST (ecdsa-with-SHA*) omit the parameters field. + // The parameters field SHALL be NULL for RSA based signature algorithms. + // + noParams.Add(X9ObjectIdentifiers.ECDsaWithSha1); + noParams.Add(X9ObjectIdentifiers.ECDsaWithSha224); + noParams.Add(X9ObjectIdentifiers.ECDsaWithSha256); + noParams.Add(X9ObjectIdentifiers.ECDsaWithSha384); + noParams.Add(X9ObjectIdentifiers.ECDsaWithSha512); + noParams.Add(X9ObjectIdentifiers.IdDsaWithSha1); + noParams.Add(OiwObjectIdentifiers.DsaWithSha1); + noParams.Add(NistObjectIdentifiers.DsaWithSha224); + noParams.Add(NistObjectIdentifiers.DsaWithSha256); + + // + // RFC 4491 + // + noParams.Add(CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94); + noParams.Add(CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001); + + // + // explicit params + // + AlgorithmIdentifier sha1AlgId = new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1, DerNull.Instance); + exParams.Add("SHA1WITHRSAANDMGF1", CreatePssParams(sha1AlgId, 20)); + + AlgorithmIdentifier sha224AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha224, DerNull.Instance); + exParams.Add("SHA224WITHRSAANDMGF1", CreatePssParams(sha224AlgId, 28)); + + AlgorithmIdentifier sha256AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha256, DerNull.Instance); + exParams.Add("SHA256WITHRSAANDMGF1", CreatePssParams(sha256AlgId, 32)); + + AlgorithmIdentifier sha384AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha384, DerNull.Instance); + exParams.Add("SHA384WITHRSAANDMGF1", CreatePssParams(sha384AlgId, 48)); + + AlgorithmIdentifier sha512AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha512, DerNull.Instance); + exParams.Add("SHA512WITHRSAANDMGF1", CreatePssParams(sha512AlgId, 64)); + } + + private static RsassaPssParameters CreatePssParams( + AlgorithmIdentifier hashAlgId, + int saltSize) + { + return new RsassaPssParameters( + hashAlgId, + new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, hashAlgId), + new DerInteger(saltSize), + new DerInteger(1)); + } + + protected Pkcs10CertificationRequest() + { + } + + public Pkcs10CertificationRequest( + byte[] encoded) + : base((Asn1Sequence)Asn1Object.FromByteArray(encoded)) + { + } + + public Pkcs10CertificationRequest( + Asn1Sequence seq) + : base(seq) + { + } + + public Pkcs10CertificationRequest( + Stream input) + : base((Asn1Sequence)Asn1Object.FromStream(input)) + { + } + + /// + /// Instantiate a Pkcs10CertificationRequest object with the necessary credentials. + /// + ///Name of Sig Alg. + /// X509Name of subject eg OU="My unit." O="My Organisatioin" C="au" + /// Public Key to be included in cert reqest. + /// ASN1Set of Attributes. + /// Matching Private key for nominated (above) public key to be used to sign the request. + public Pkcs10CertificationRequest( + string signatureAlgorithm, + X509Name subject, + AsymmetricKeyParameter publicKey, + Asn1Set attributes, + AsymmetricKeyParameter signingKey) + : this(new Asn1SignatureFactory(signatureAlgorithm, signingKey), subject, publicKey, attributes) + { + } + + /// + /// Instantiate a Pkcs10CertificationRequest object with the necessary credentials. + /// + ///The factory for signature calculators to sign the PKCS#10 request with. + /// X509Name of subject eg OU="My unit." O="My Organisatioin" C="au" + /// Public Key to be included in cert reqest. + /// ASN1Set of Attributes. + /// Ignored. + [Obsolete("Use constructor without 'signingKey' parameter (ignored here)")] + public Pkcs10CertificationRequest( + ISignatureFactory signatureFactory, + X509Name subject, + AsymmetricKeyParameter publicKey, + Asn1Set attributes, + AsymmetricKeyParameter signingKey) + : this(signatureFactory, subject, publicKey, attributes) + { + } + + /// + /// Instantiate a Pkcs10CertificationRequest object with the necessary credentials. + /// + ///The factory for signature calculators to sign the PKCS#10 request with. + /// X509Name of subject eg OU="My unit." O="My Organisatioin" C="au" + /// Public Key to be included in cert reqest. + /// ASN1Set of Attributes. + public Pkcs10CertificationRequest( + ISignatureFactory signatureFactory, + X509Name subject, + AsymmetricKeyParameter publicKey, + Asn1Set attributes) + { + if (signatureFactory == null) + throw new ArgumentNullException("signatureFactory"); + if (subject == null) + throw new ArgumentNullException("subject"); + if (publicKey == null) + throw new ArgumentNullException("publicKey"); + if (publicKey.IsPrivate) + throw new ArgumentException("expected public key", "publicKey"); + + Init(signatureFactory, subject, publicKey, attributes); + } + + private void Init( + ISignatureFactory signatureFactory, + X509Name subject, + AsymmetricKeyParameter publicKey, + Asn1Set attributes) + { + this.sigAlgId = (AlgorithmIdentifier)signatureFactory.AlgorithmDetails; + + SubjectPublicKeyInfo pubInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(publicKey); + + this.reqInfo = new CertificationRequestInfo(subject, pubInfo, attributes); + + IStreamCalculator streamCalculator = signatureFactory.CreateCalculator(); + + byte[] reqInfoData = reqInfo.GetDerEncoded(); + + streamCalculator.Stream.Write(reqInfoData, 0, reqInfoData.Length); + + Platform.Dispose(streamCalculator.Stream); + + // Generate Signature. + sigBits = new DerBitString(((IBlockResult)streamCalculator.GetResult()).Collect()); + } + + // internal Pkcs10CertificationRequest( + // Asn1InputStream seqStream) + // { + // Asn1Sequence seq = (Asn1Sequence) seqStream.ReadObject(); + // try + // { + // this.reqInfo = CertificationRequestInfo.GetInstance(seq[0]); + // this.sigAlgId = AlgorithmIdentifier.GetInstance(seq[1]); + // this.sigBits = (DerBitString) seq[2]; + // } + // catch (Exception ex) + // { + // throw new ArgumentException("Create From Asn1Sequence: " + ex.Message); + // } + // } + + /// + /// Get the public key. + /// + /// The public key. + public AsymmetricKeyParameter GetPublicKey() + { + return PublicKeyFactory.CreateKey(reqInfo.SubjectPublicKeyInfo); + } + + /// + /// Verify Pkcs10 Cert Request is valid. + /// + /// true = valid. + public bool Verify() + { + return Verify(this.GetPublicKey()); + } + + public bool Verify( + AsymmetricKeyParameter publicKey) + { + return Verify(new Asn1VerifierFactoryProvider(publicKey)); + } + + public bool Verify( + IVerifierFactoryProvider verifierProvider) + { + return Verify(verifierProvider.CreateVerifierFactory(sigAlgId)); + } + + public bool Verify( + IVerifierFactory verifier) + { + try + { + byte[] b = reqInfo.GetDerEncoded(); + + IStreamCalculator streamCalculator = verifier.CreateCalculator(); + + streamCalculator.Stream.Write(b, 0, b.Length); + + Platform.Dispose(streamCalculator.Stream); + + return ((IVerifier)streamCalculator.GetResult()).IsVerified(sigBits.GetOctets()); + } + catch (Exception e) + { + throw new SignatureException("exception encoding TBS cert request", e); + } + } + + // /// + // /// Get the Der Encoded Pkcs10 Certification Request. + // /// + // /// A byte array. + // public byte[] GetEncoded() + // { + // return new CertificationRequest(reqInfo, sigAlgId, sigBits).GetDerEncoded(); + // } + + // TODO Figure out how to set parameters on an ISigner + private void SetSignatureParameters( + ISigner signature, + Asn1Encodable asn1Params) + { + if (asn1Params != null && !(asn1Params is Asn1Null)) + { + // AlgorithmParameters sigParams = AlgorithmParameters.GetInstance(signature.getAlgorithm()); + // + // try + // { + // sigParams.init(asn1Params.ToAsn1Object().GetDerEncoded()); + // } + // catch (IOException e) + // { + // throw new SignatureException("IOException decoding parameters: " + e.Message); + // } + + if (Platform.EndsWith(signature.AlgorithmName, "MGF1")) + { + throw Platform.CreateNotImplementedException("signature algorithm with MGF1"); + + // try + // { + // signature.setParameter(sigParams.getParameterSpec(PSSParameterSpec.class)); + // } + // catch (GeneralSecurityException e) + // { + // throw new SignatureException("Exception extracting parameters: " + e.getMessage()); + // } + } + } + } + + internal static string GetSignatureName( + AlgorithmIdentifier sigAlgId) + { + Asn1Encodable asn1Params = sigAlgId.Parameters; + + if (asn1Params != null && !(asn1Params is Asn1Null)) + { + if (sigAlgId.Algorithm.Equals(PkcsObjectIdentifiers.IdRsassaPss)) + { + RsassaPssParameters rsaParams = RsassaPssParameters.GetInstance(asn1Params); + return GetDigestAlgName(rsaParams.HashAlgorithm.Algorithm) + "withRSAandMGF1"; + } + } + + return sigAlgId.Algorithm.Id; + } + + private static string GetDigestAlgName( + DerObjectIdentifier digestAlgOID) + { + if (PkcsObjectIdentifiers.MD5.Equals(digestAlgOID)) + { + return "MD5"; + } + else if (OiwObjectIdentifiers.IdSha1.Equals(digestAlgOID)) + { + return "SHA1"; + } + else if (NistObjectIdentifiers.IdSha224.Equals(digestAlgOID)) + { + return "SHA224"; + } + else if (NistObjectIdentifiers.IdSha256.Equals(digestAlgOID)) + { + return "SHA256"; + } + else if (NistObjectIdentifiers.IdSha384.Equals(digestAlgOID)) + { + return "SHA384"; + } + else if (NistObjectIdentifiers.IdSha512.Equals(digestAlgOID)) + { + return "SHA512"; + } + else if (NistObjectIdentifiers.IdSha512_224.Equals(digestAlgOID)) + { + return "SHA512(224)"; + } + else if (NistObjectIdentifiers.IdSha512_256.Equals(digestAlgOID)) + { + return "SHA512(256)"; + } + else if (TeleTrusTObjectIdentifiers.RipeMD128.Equals(digestAlgOID)) + { + return "RIPEMD128"; + } + else if (TeleTrusTObjectIdentifiers.RipeMD160.Equals(digestAlgOID)) + { + return "RIPEMD160"; + } + else if (TeleTrusTObjectIdentifiers.RipeMD256.Equals(digestAlgOID)) + { + return "RIPEMD256"; + } + else if (CryptoProObjectIdentifiers.GostR3411.Equals(digestAlgOID)) + { + return "GOST3411"; + } + else + { + return digestAlgOID.Id; + } + } + + /// + /// Returns X509Extensions if the Extensions Request attribute can be found and returns the extensions block. + /// + /// X509Extensions block or null if one cannot be found. + public X509Extensions GetRequestedExtensions() + { + if (reqInfo.Attributes != null) + { + foreach (Asn1Encodable item in reqInfo.Attributes) + { + AttributePkcs attributePkcs; + try + { + attributePkcs = AttributePkcs.GetInstance(item); + + } + catch (ArgumentException ex) + { + throw new ArgumentException("encountered non PKCS attribute in extensions block", ex); + } + + if (attributePkcs.AttrType.Equals(PkcsObjectIdentifiers.Pkcs9AtExtensionRequest)) + { + X509ExtensionsGenerator generator = new X509ExtensionsGenerator(); + + Asn1Sequence extensionSequence = Asn1Sequence.GetInstance(attributePkcs.AttrValues[0]); + + + foreach (Asn1Encodable seqItem in extensionSequence) + { + + Asn1Sequence itemSeq = Asn1Sequence.GetInstance(seqItem); + if (itemSeq.Count == 2) + { + generator.AddExtension(DerObjectIdentifier.GetInstance(itemSeq[0]), false, Asn1OctetString.GetInstance(itemSeq[1]).GetOctets()); + } + else if (itemSeq.Count == 3) + { + generator.AddExtension(DerObjectIdentifier.GetInstance(itemSeq[0]), DerBoolean.GetInstance(itemSeq[1]).IsTrue, Asn1OctetString.GetInstance(itemSeq[2]).GetOctets()); + } + else + { + throw new ArgumentException("incorrect sequence size of X509Extension got " + itemSeq.Count + " expected 2 or 3"); + } + } + + return generator.Generate(); + } + + } + } + + return null; + } + + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/Pkcs10CertificationRequest.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/Pkcs10CertificationRequest.cs.meta new file mode 100644 index 0000000..884d243 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/Pkcs10CertificationRequest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 67b86430259d5ba4784035507186675f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/Pkcs10CertificationRequestDelaySigned.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/Pkcs10CertificationRequestDelaySigned.cs new file mode 100644 index 0000000..ecbb4ab --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/Pkcs10CertificationRequestDelaySigned.cs @@ -0,0 +1,150 @@ +using System; +using System.Collections; +using System.Globalization; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Oiw; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.TeleTrust; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.Pkcs +{ + /// + /// A class for creating and verifying Pkcs10 Certification requests (this is an extension on ). + /// The requests are made using delay signing. This is useful for situations where + /// the private key is in another environment and not directly accessible (e.g. HSM) + /// So the first step creates the request, then the signing is done outside this + /// object and the signature is then used to complete the request. + /// + /// + /// CertificationRequest ::= Sequence { + /// certificationRequestInfo CertificationRequestInfo, + /// signatureAlgorithm AlgorithmIdentifier{{ SignatureAlgorithms }}, + /// signature BIT STRING + /// } + /// + /// CertificationRequestInfo ::= Sequence { + /// version Integer { v1(0) } (v1,...), + /// subject Name, + /// subjectPKInfo SubjectPublicKeyInfo{{ PKInfoAlgorithms }}, + /// attributes [0] Attributes{{ CRIAttributes }} + /// } + /// + /// Attributes { ATTRIBUTE:IOSet } ::= Set OF Attr{{ IOSet }} + /// + /// Attr { ATTRIBUTE:IOSet } ::= Sequence { + /// type ATTRIBUTE.&id({IOSet}), + /// values Set SIZE(1..MAX) OF ATTRIBUTE.&Type({IOSet}{\@type}) + /// } + /// + /// see + public class Pkcs10CertificationRequestDelaySigned : Pkcs10CertificationRequest + { + protected Pkcs10CertificationRequestDelaySigned() + : base() + { + } + public Pkcs10CertificationRequestDelaySigned( + byte[] encoded) + : base(encoded) + { + } + public Pkcs10CertificationRequestDelaySigned( + Asn1Sequence seq) + : base(seq) + { + } + public Pkcs10CertificationRequestDelaySigned( + Stream input) + : base(input) + { + } + public Pkcs10CertificationRequestDelaySigned( + string signatureAlgorithm, + X509Name subject, + AsymmetricKeyParameter publicKey, + Asn1Set attributes, + AsymmetricKeyParameter signingKey) + : base(signatureAlgorithm, subject, publicKey, attributes, signingKey) + { + } + /// + /// Instantiate a Pkcs10CertificationRequest object with the necessary credentials. + /// + /// Name of Sig Alg. + /// X509Name of subject eg OU="My unit." O="My Organisatioin" C="au" + /// Public Key to be included in cert reqest. + /// ASN1Set of Attributes. + /// + /// After the object is constructed use the and finally the + /// SignRequest methods to finalize the request. + /// + public Pkcs10CertificationRequestDelaySigned( + string signatureAlgorithm, + X509Name subject, + AsymmetricKeyParameter publicKey, + Asn1Set attributes) + { + if (signatureAlgorithm == null) + throw new ArgumentNullException("signatureAlgorithm"); + if (subject == null) + throw new ArgumentNullException("subject"); + if (publicKey == null) + throw new ArgumentNullException("publicKey"); + if (publicKey.IsPrivate) + throw new ArgumentException("expected public key", "publicKey"); +// DerObjectIdentifier sigOid = SignerUtilities.GetObjectIdentifier(signatureAlgorithm); + string algorithmName = Platform.ToUpperInvariant(signatureAlgorithm); + DerObjectIdentifier sigOid = (DerObjectIdentifier) algorithms[algorithmName]; + if (sigOid == null) + { + try + { + sigOid = new DerObjectIdentifier(algorithmName); + } + catch (Exception e) + { + throw new ArgumentException("Unknown signature type requested", e); + } + } + if (noParams.Contains(sigOid)) + { + this.sigAlgId = new AlgorithmIdentifier(sigOid); + } + else if (exParams.Contains(algorithmName)) + { + this.sigAlgId = new AlgorithmIdentifier(sigOid, (Asn1Encodable) exParams[algorithmName]); + } + else + { + this.sigAlgId = new AlgorithmIdentifier(sigOid, DerNull.Instance); + } + SubjectPublicKeyInfo pubInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(publicKey); + this.reqInfo = new CertificationRequestInfo(subject, pubInfo, attributes); + } + public byte[] GetDataToSign() + { + return reqInfo.GetDerEncoded(); + } + public void SignRequest(byte[] signedData) + { + //build the signature from the signed data + sigBits = new DerBitString(signedData); + } + public void SignRequest(DerBitString signedData) + { + //build the signature from the signed data + sigBits = signedData; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/Pkcs10CertificationRequestDelaySigned.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/Pkcs10CertificationRequestDelaySigned.cs.meta new file mode 100644 index 0000000..dc87b18 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/Pkcs10CertificationRequestDelaySigned.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e6a1682ff0eec2740aef6dde3b96bbb7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/Pkcs12Entry.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/Pkcs12Entry.cs new file mode 100644 index 0000000..5dcc94e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/Pkcs12Entry.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Pkcs +{ + public abstract class Pkcs12Entry + { + private readonly IDictionary attributes; + + protected internal Pkcs12Entry( + IDictionary attributes) + { + this.attributes = attributes; + + foreach (DictionaryEntry entry in attributes) + { + if (!(entry.Key is string)) + throw new ArgumentException("Attribute keys must be of type: " + typeof(string).FullName, "attributes"); + if (!(entry.Value is Asn1Encodable)) + throw new ArgumentException("Attribute values must be of type: " + typeof(Asn1Encodable).FullName, "attributes"); + } + } + + [Obsolete("Use 'object[index]' syntax instead")] + public Asn1Encodable GetBagAttribute( + DerObjectIdentifier oid) + { + return (Asn1Encodable)this.attributes[oid.Id]; + } + + [Obsolete("Use 'object[index]' syntax instead")] + public Asn1Encodable GetBagAttribute( + string oid) + { + return (Asn1Encodable)this.attributes[oid]; + } + + [Obsolete("Use 'BagAttributeKeys' property")] + public IEnumerator GetBagAttributeKeys() + { + return this.attributes.Keys.GetEnumerator(); + } + + public Asn1Encodable this[ + DerObjectIdentifier oid] + { + get { return (Asn1Encodable) this.attributes[oid.Id]; } + } + + public Asn1Encodable this[ + string oid] + { + get { return (Asn1Encodable) this.attributes[oid]; } + } + + public IEnumerable BagAttributeKeys + { + get { return new EnumerableProxy(this.attributes.Keys); } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/Pkcs12Entry.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/Pkcs12Entry.cs.meta new file mode 100644 index 0000000..7a953e9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/Pkcs12Entry.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 81f1eb0a20730f5409bb47eae93ff2e6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/Pkcs12Store.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/Pkcs12Store.cs new file mode 100644 index 0000000..5a6a566 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/Pkcs12Store.cs @@ -0,0 +1,1159 @@ +using System; +using System.Collections; +using System.IO; +using System.Text; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Oiw; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Asn1.Utilities; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; +using Org.BouncyCastle.Utilities.Encoders; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.Pkcs +{ + public class Pkcs12Store + { + public const string IgnoreUselessPasswordProperty = "Org.BouncyCastle.Pkcs12.IgnoreUselessPassword"; + + private readonly IgnoresCaseHashtable keys = new IgnoresCaseHashtable(); + private readonly IDictionary localIds = Platform.CreateHashtable(); + private readonly IgnoresCaseHashtable certs = new IgnoresCaseHashtable(); + private readonly IDictionary chainCerts = Platform.CreateHashtable(); + private readonly IDictionary keyCerts = Platform.CreateHashtable(); + private readonly DerObjectIdentifier keyAlgorithm; + private readonly DerObjectIdentifier keyPrfAlgorithm; + private readonly DerObjectIdentifier certAlgorithm; + private readonly DerObjectIdentifier certPrfAlgorithm; + private readonly bool useDerEncoding; + + private AsymmetricKeyEntry unmarkedKeyEntry = null; + + private const int MinIterations = 1024; + private const int SaltSize = 20; + + private static SubjectKeyIdentifier CreateSubjectKeyID( + AsymmetricKeyParameter pubKey) + { + return new SubjectKeyIdentifier( + SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(pubKey)); + } + + internal class CertId + { + private readonly byte[] id; + + internal CertId( + AsymmetricKeyParameter pubKey) + { + this.id = CreateSubjectKeyID(pubKey).GetKeyIdentifier(); + } + + internal CertId( + byte[] id) + { + this.id = id; + } + + internal byte[] Id + { + get { return id; } + } + + public override int GetHashCode() + { + return Arrays.GetHashCode(id); + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + CertId other = obj as CertId; + + if (other == null) + return false; + + return Arrays.AreEqual(id, other.id); + } + } + + internal Pkcs12Store( + DerObjectIdentifier keyAlgorithm, + DerObjectIdentifier certAlgorithm, + bool useDerEncoding) + { + this.keyAlgorithm = keyAlgorithm; + this.keyPrfAlgorithm = null; + this.certAlgorithm = certAlgorithm; + this.certPrfAlgorithm = null; + this.useDerEncoding = useDerEncoding; + } + + internal Pkcs12Store( + DerObjectIdentifier keyAlgorithm, + DerObjectIdentifier keyPrfAlgorithm, + DerObjectIdentifier certAlgorithm, + DerObjectIdentifier certPrfAlgorithm, + bool useDerEncoding) + { + this.keyAlgorithm = keyAlgorithm; + this.keyPrfAlgorithm = keyPrfAlgorithm; + this.certAlgorithm = certAlgorithm; + this.certPrfAlgorithm = certPrfAlgorithm; + this.useDerEncoding = useDerEncoding; + } + + // TODO Consider making obsolete + // [Obsolete("Use 'Pkcs12StoreBuilder' instead")] + public Pkcs12Store() + : this(PkcsObjectIdentifiers.PbeWithShaAnd3KeyTripleDesCbc, + PkcsObjectIdentifiers.PbewithShaAnd40BitRC2Cbc, false) + { + } + + // TODO Consider making obsolete +// [Obsolete("Use 'Pkcs12StoreBuilder' and 'Load' method instead")] + public Pkcs12Store( + Stream input, + char[] password) + : this() + { + Load(input, password); + } + + protected virtual void LoadKeyBag(PrivateKeyInfo privKeyInfo, Asn1Set bagAttributes) + { + AsymmetricKeyParameter privKey = PrivateKeyFactory.CreateKey(privKeyInfo); + + IDictionary attributes = Platform.CreateHashtable(); + AsymmetricKeyEntry keyEntry = new AsymmetricKeyEntry(privKey, attributes); + + string alias = null; + Asn1OctetString localId = null; + + if (bagAttributes != null) + { + foreach (Asn1Sequence sq in bagAttributes) + { + DerObjectIdentifier aOid = DerObjectIdentifier.GetInstance(sq[0]); + Asn1Set attrSet = Asn1Set.GetInstance(sq[1]); + Asn1Encodable attr = null; + + if (attrSet.Count > 0) + { + // TODO We should be adding all attributes in the set + attr = attrSet[0]; + + // TODO We might want to "merge" attribute sets with + // the same OID - currently, differing values give an error + if (attributes.Contains(aOid.Id)) + { + // OK, but the value has to be the same + if (!attributes[aOid.Id].Equals(attr)) + throw new IOException("attempt to add existing attribute with different value"); + } + else + { + attributes.Add(aOid.Id, attr); + } + + if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName)) + { + alias = ((DerBmpString)attr).GetString(); + // TODO Do these in a separate loop, just collect aliases here + keys[alias] = keyEntry; + } + else if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID)) + { + localId = (Asn1OctetString)attr; + } + } + } + } + + if (localId != null) + { + string name = Hex.ToHexString(localId.GetOctets()); + + if (alias == null) + { + keys[name] = keyEntry; + } + else + { + // TODO There may have been more than one alias + localIds[alias] = name; + } + } + else + { + unmarkedKeyEntry = keyEntry; + } + } + + protected virtual void LoadPkcs8ShroudedKeyBag(EncryptedPrivateKeyInfo encPrivKeyInfo, Asn1Set bagAttributes, + char[] password, bool wrongPkcs12Zero) + { + if (password != null) + { + PrivateKeyInfo privInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo( + password, wrongPkcs12Zero, encPrivKeyInfo); + + LoadKeyBag(privInfo, bagAttributes); + } + } + + public void Load( + Stream input, + char[] password) + { + if (input == null) + throw new ArgumentNullException("input"); + + Pfx bag = Pfx.GetInstance(Asn1Object.FromStream(input)); + ContentInfo info = bag.AuthSafe; + bool wrongPkcs12Zero = false; + + if (bag.MacData != null) // check the mac code + { + if (password == null) + throw new ArgumentNullException("password", "no password supplied when one expected"); + + MacData mData = bag.MacData; + DigestInfo dInfo = mData.Mac; + AlgorithmIdentifier algId = dInfo.AlgorithmID; + byte[] salt = mData.GetSalt(); + int itCount = mData.IterationCount.IntValue; + + byte[] data = Asn1OctetString.GetInstance(info.Content).GetOctets(); + + byte[] mac = CalculatePbeMac(algId.Algorithm, salt, itCount, password, false, data); + byte[] dig = dInfo.GetDigest(); + + if (!Arrays.ConstantTimeAreEqual(mac, dig)) + { + if (password.Length > 0) + throw new IOException("PKCS12 key store MAC invalid - wrong password or corrupted file."); + + // Try with incorrect zero length password + mac = CalculatePbeMac(algId.Algorithm, salt, itCount, password, true, data); + + if (!Arrays.ConstantTimeAreEqual(mac, dig)) + throw new IOException("PKCS12 key store MAC invalid - wrong password or corrupted file."); + + wrongPkcs12Zero = true; + } + } + else if (password != null) + { + string ignoreProperty = Platform.GetEnvironmentVariable(IgnoreUselessPasswordProperty); + bool ignore = ignoreProperty != null && Platform.EqualsIgnoreCase("true", ignoreProperty); + + if (!ignore) + { + throw new IOException("password supplied for keystore that does not require one"); + } + } + + keys.Clear(); + localIds.Clear(); + unmarkedKeyEntry = null; + + IList certBags = Platform.CreateArrayList(); + + if (info.ContentType.Equals(PkcsObjectIdentifiers.Data)) + { + Asn1OctetString content = Asn1OctetString.GetInstance(info.Content); + AuthenticatedSafe authSafe = AuthenticatedSafe.GetInstance(content.GetOctets()); + ContentInfo[] cis = authSafe.GetContentInfo(); + + foreach (ContentInfo ci in cis) + { + DerObjectIdentifier oid = ci.ContentType; + + byte[] octets = null; + if (oid.Equals(PkcsObjectIdentifiers.Data)) + { + octets = Asn1OctetString.GetInstance(ci.Content).GetOctets(); + } + else if (oid.Equals(PkcsObjectIdentifiers.EncryptedData)) + { + if (password != null) + { + EncryptedData d = EncryptedData.GetInstance(ci.Content); + octets = CryptPbeData(false, d.EncryptionAlgorithm, + password, wrongPkcs12Zero, d.Content.GetOctets()); + } + } + else + { + // TODO Other data types + } + + if (octets != null) + { + Asn1Sequence seq = Asn1Sequence.GetInstance(octets); + + foreach (Asn1Sequence subSeq in seq) + { + SafeBag b = SafeBag.GetInstance(subSeq); + + if (b.BagID.Equals(PkcsObjectIdentifiers.CertBag)) + { + certBags.Add(b); + } + else if (b.BagID.Equals(PkcsObjectIdentifiers.Pkcs8ShroudedKeyBag)) + { + LoadPkcs8ShroudedKeyBag(EncryptedPrivateKeyInfo.GetInstance(b.BagValue), + b.BagAttributes, password, wrongPkcs12Zero); + } + else if (b.BagID.Equals(PkcsObjectIdentifiers.KeyBag)) + { + LoadKeyBag(PrivateKeyInfo.GetInstance(b.BagValue), b.BagAttributes); + } + else + { + // TODO Other bag types + } + } + } + } + } + + certs.Clear(); + chainCerts.Clear(); + keyCerts.Clear(); + + foreach (SafeBag b in certBags) + { + CertBag certBag = CertBag.GetInstance(b.BagValue); + byte[] octets = ((Asn1OctetString)certBag.CertValue).GetOctets(); + X509Certificate cert = new X509CertificateParser().ReadCertificate(octets); + + // + // set the attributes + // + IDictionary attributes = Platform.CreateHashtable(); + Asn1OctetString localId = null; + string alias = null; + + if (b.BagAttributes != null) + { + foreach (Asn1Sequence sq in b.BagAttributes) + { + DerObjectIdentifier aOid = DerObjectIdentifier.GetInstance(sq[0]); + Asn1Set attrSet = Asn1Set.GetInstance(sq[1]); + + if (attrSet.Count > 0) + { + // TODO We should be adding all attributes in the set + Asn1Encodable attr = attrSet[0]; + + // TODO We might want to "merge" attribute sets with + // the same OID - currently, differing values give an error + if (attributes.Contains(aOid.Id)) + { + // we've found more than one - one might be incorrect + if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID)) + { + String id = Hex.ToHexString(Asn1OctetString.GetInstance(attr).GetOctets()); + if (!(keys[id] != null || localIds[id] != null)) + { + continue; // ignore this one - it's not valid + } + } + + // OK, but the value has to be the same + if (!attributes[aOid.Id].Equals(attr)) + { + throw new IOException("attempt to add existing attribute with different value"); + } + } + else + { + attributes.Add(aOid.Id, attr); + } + + if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName)) + { + alias = ((DerBmpString)attr).GetString(); + } + else if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID)) + { + localId = (Asn1OctetString)attr; + } + } + } + } + + CertId certId = new CertId(cert.GetPublicKey()); + X509CertificateEntry certEntry = new X509CertificateEntry(cert, attributes); + + chainCerts[certId] = certEntry; + + if (unmarkedKeyEntry != null) + { + if (keyCerts.Count == 0) + { + string name = Hex.ToHexString(certId.Id); + + keyCerts[name] = certEntry; + keys[name] = unmarkedKeyEntry; + } + else + { + keys["unmarked"] = unmarkedKeyEntry; + } + } + else + { + if (localId != null) + { + string name = Hex.ToHexString(localId.GetOctets()); + + keyCerts[name] = certEntry; + } + + if (alias != null) + { + // TODO There may have been more than one alias + certs[alias] = certEntry; + } + } + } + } + + public AsymmetricKeyEntry GetKey( + string alias) + { + if (alias == null) + throw new ArgumentNullException("alias"); + + return (AsymmetricKeyEntry)keys[alias]; + } + + public bool IsCertificateEntry( + string alias) + { + if (alias == null) + throw new ArgumentNullException("alias"); + + return (certs[alias] != null && keys[alias] == null); + } + + public bool IsKeyEntry( + string alias) + { + if (alias == null) + throw new ArgumentNullException("alias"); + + return (keys[alias] != null); + } + + private IDictionary GetAliasesTable() + { + IDictionary tab = Platform.CreateHashtable(); + + foreach (string key in certs.Keys) + { + tab[key] = "cert"; + } + + foreach (string a in keys.Keys) + { + if (tab[a] == null) + { + tab[a] = "key"; + } + } + + return tab; + } + + public IEnumerable Aliases + { + get { return new EnumerableProxy(GetAliasesTable().Keys); } + } + + public bool ContainsAlias( + string alias) + { + return certs[alias] != null || keys[alias] != null; + } + + /** + * simply return the cert entry for the private key + */ + public X509CertificateEntry GetCertificate( + string alias) + { + if (alias == null) + throw new ArgumentNullException("alias"); + + X509CertificateEntry c = (X509CertificateEntry) certs[alias]; + + // + // look up the key table - and try the local key id + // + if (c == null) + { + string id = (string)localIds[alias]; + if (id != null) + { + c = (X509CertificateEntry)keyCerts[id]; + } + else + { + c = (X509CertificateEntry)keyCerts[alias]; + } + } + + return c; + } + + public string GetCertificateAlias( + X509Certificate cert) + { + if (cert == null) + throw new ArgumentNullException("cert"); + + foreach (DictionaryEntry entry in certs) + { + X509CertificateEntry entryValue = (X509CertificateEntry) entry.Value; + if (entryValue.Certificate.Equals(cert)) + { + return (string) entry.Key; + } + } + + foreach (DictionaryEntry entry in keyCerts) + { + X509CertificateEntry entryValue = (X509CertificateEntry) entry.Value; + if (entryValue.Certificate.Equals(cert)) + { + return (string) entry.Key; + } + } + + return null; + } + + public X509CertificateEntry[] GetCertificateChain( + string alias) + { + if (alias == null) + throw new ArgumentNullException("alias"); + + if (!IsKeyEntry(alias)) + { + return null; + } + + X509CertificateEntry c = GetCertificate(alias); + + if (c != null) + { + IList cs = Platform.CreateArrayList(); + + while (c != null) + { + X509Certificate x509c = c.Certificate; + X509CertificateEntry nextC = null; + + Asn1OctetString akiValue = x509c.GetExtensionValue(X509Extensions.AuthorityKeyIdentifier); + if (akiValue != null) + { + AuthorityKeyIdentifier aki = AuthorityKeyIdentifier.GetInstance(akiValue.GetOctets()); + + byte[] keyID = aki.GetKeyIdentifier(); + if (keyID != null) + { + nextC = (X509CertificateEntry)chainCerts[new CertId(keyID)]; + } + } + + if (nextC == null) + { + // + // no authority key id, try the Issuer DN + // + X509Name i = x509c.IssuerDN; + X509Name s = x509c.SubjectDN; + + if (!i.Equivalent(s)) + { + foreach (CertId certId in chainCerts.Keys) + { + X509CertificateEntry x509CertEntry = (X509CertificateEntry) chainCerts[certId]; + + X509Certificate crt = x509CertEntry.Certificate; + + X509Name sub = crt.SubjectDN; + if (sub.Equivalent(i)) + { + try + { + x509c.Verify(crt.GetPublicKey()); + + nextC = x509CertEntry; + break; + } + catch (InvalidKeyException) + { + // TODO What if it doesn't verify? + } + } + } + } + } + + cs.Add(c); + if (nextC != c) // self signed - end of the chain + { + c = nextC; + } + else + { + c = null; + } + } + + X509CertificateEntry[] result = new X509CertificateEntry[cs.Count]; + for (int i = 0; i < cs.Count; ++i) + { + result[i] = (X509CertificateEntry)cs[i]; + } + return result; + } + + return null; + } + + public void SetCertificateEntry( + string alias, + X509CertificateEntry certEntry) + { + if (alias == null) + throw new ArgumentNullException("alias"); + if (certEntry == null) + throw new ArgumentNullException("certEntry"); + if (keys[alias] != null) + throw new ArgumentException("There is a key entry with the name " + alias + "."); + + certs[alias] = certEntry; + chainCerts[new CertId(certEntry.Certificate.GetPublicKey())] = certEntry; + } + + public void SetKeyEntry( + string alias, + AsymmetricKeyEntry keyEntry, + X509CertificateEntry[] chain) + { + if (alias == null) + throw new ArgumentNullException("alias"); + if (keyEntry == null) + throw new ArgumentNullException("keyEntry"); + if (keyEntry.Key.IsPrivate && (chain == null)) + throw new ArgumentException("No certificate chain for private key"); + + if (keys[alias] != null) + { + DeleteEntry(alias); + } + + keys[alias] = keyEntry; + certs[alias] = chain[0]; + + for (int i = 0; i != chain.Length; i++) + { + chainCerts[new CertId(chain[i].Certificate.GetPublicKey())] = chain[i]; + } + } + + public void DeleteEntry( + string alias) + { + if (alias == null) + throw new ArgumentNullException("alias"); + + AsymmetricKeyEntry k = (AsymmetricKeyEntry)keys[alias]; + if (k != null) + { + keys.Remove(alias); + } + + X509CertificateEntry c = (X509CertificateEntry)certs[alias]; + + if (c != null) + { + certs.Remove(alias); + chainCerts.Remove(new CertId(c.Certificate.GetPublicKey())); + } + + if (k != null) + { + string id = (string)localIds[alias]; + if (id != null) + { + localIds.Remove(alias); + c = (X509CertificateEntry)keyCerts[id]; + } + if (c != null) + { + keyCerts.Remove(id); + chainCerts.Remove(new CertId(c.Certificate.GetPublicKey())); + } + } + + if (c == null && k == null) + { + throw new ArgumentException("no such entry as " + alias); + } + } + + public bool IsEntryOfType( + string alias, + Type entryType) + { + if (entryType == typeof(X509CertificateEntry)) + return IsCertificateEntry(alias); + + if (entryType == typeof(AsymmetricKeyEntry)) + return IsKeyEntry(alias) && GetCertificate(alias) != null; + + return false; + } + + [Obsolete("Use 'Count' property instead")] + public int Size() + { + return Count; + } + + public int Count + { + // TODO Seems a little inefficient + get { return GetAliasesTable().Count; } + } + + public void Save( + Stream stream, + char[] password, + SecureRandom random) + { + if (stream == null) + throw new ArgumentNullException("stream"); + if (random == null) + throw new ArgumentNullException("random"); + + // + // handle the keys + // + Asn1EncodableVector keyBags = new Asn1EncodableVector(); + foreach (string name in keys.Keys) + { + byte[] kSalt = new byte[SaltSize]; + random.NextBytes(kSalt); + + AsymmetricKeyEntry privKey = (AsymmetricKeyEntry)keys[name]; + + DerObjectIdentifier bagOid; + Asn1Encodable bagData; + + if (password == null) + { + bagOid = PkcsObjectIdentifiers.KeyBag; + bagData = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privKey.Key); + } + else + { + bagOid = PkcsObjectIdentifiers.Pkcs8ShroudedKeyBag; + if (keyPrfAlgorithm != null) + { + bagData = EncryptedPrivateKeyInfoFactory.CreateEncryptedPrivateKeyInfo( + keyAlgorithm, keyPrfAlgorithm, password, kSalt, MinIterations, random, privKey.Key); + } + else + { + bagData = EncryptedPrivateKeyInfoFactory.CreateEncryptedPrivateKeyInfo( + keyAlgorithm, password, kSalt, MinIterations, privKey.Key); + } + } + + Asn1EncodableVector kName = new Asn1EncodableVector(); + + foreach (string oid in privKey.BagAttributeKeys) + { + Asn1Encodable entry = privKey[oid]; + + // NB: Ignore any existing FriendlyName + if (oid.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName.Id)) + continue; + + kName.Add( + new DerSequence( + new DerObjectIdentifier(oid), + new DerSet(entry))); + } + + // + // make sure we are using the local alias on store + // + // NB: We always set the FriendlyName based on 'name' + //if (privKey[PkcsObjectIdentifiers.Pkcs9AtFriendlyName] == null) + { + kName.Add( + new DerSequence( + PkcsObjectIdentifiers.Pkcs9AtFriendlyName, + new DerSet(new DerBmpString(name)))); + } + + // + // make sure we have a local key-id + // + if (privKey[PkcsObjectIdentifiers.Pkcs9AtLocalKeyID] == null) + { + X509CertificateEntry ct = GetCertificate(name); + AsymmetricKeyParameter pubKey = ct.Certificate.GetPublicKey(); + SubjectKeyIdentifier subjectKeyID = CreateSubjectKeyID(pubKey); + + kName.Add( + new DerSequence( + PkcsObjectIdentifiers.Pkcs9AtLocalKeyID, + new DerSet(subjectKeyID))); + } + + keyBags.Add(new SafeBag(bagOid, bagData.ToAsn1Object(), new DerSet(kName))); + } + + byte[] keyBagsEncoding = new DerSequence(keyBags).GetDerEncoded(); + ContentInfo keysInfo = new ContentInfo(PkcsObjectIdentifiers.Data, new BerOctetString(keyBagsEncoding)); + + // + // certificate processing + // + byte[] cSalt = new byte[SaltSize]; + + random.NextBytes(cSalt); + + Asn1EncodableVector certBags = new Asn1EncodableVector(); + Pkcs12PbeParams cParams = new Pkcs12PbeParams(cSalt, MinIterations); + AlgorithmIdentifier cAlgId = new AlgorithmIdentifier(certAlgorithm, cParams.ToAsn1Object()); + ISet doneCerts = new HashSet(); + + foreach (string name in keys.Keys) + { + X509CertificateEntry certEntry = GetCertificate(name); + CertBag cBag = new CertBag( + PkcsObjectIdentifiers.X509Certificate, + new DerOctetString(certEntry.Certificate.GetEncoded())); + + Asn1EncodableVector fName = new Asn1EncodableVector(); + + foreach (string oid in certEntry.BagAttributeKeys) + { + Asn1Encodable entry = certEntry[oid]; + + // NB: Ignore any existing FriendlyName + if (oid.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName.Id)) + continue; + + fName.Add( + new DerSequence( + new DerObjectIdentifier(oid), + new DerSet(entry))); + } + + // + // make sure we are using the local alias on store + // + // NB: We always set the FriendlyName based on 'name' + //if (certEntry[PkcsObjectIdentifiers.Pkcs9AtFriendlyName] == null) + { + fName.Add( + new DerSequence( + PkcsObjectIdentifiers.Pkcs9AtFriendlyName, + new DerSet(new DerBmpString(name)))); + } + + // + // make sure we have a local key-id + // + if (certEntry[PkcsObjectIdentifiers.Pkcs9AtLocalKeyID] == null) + { + AsymmetricKeyParameter pubKey = certEntry.Certificate.GetPublicKey(); + SubjectKeyIdentifier subjectKeyID = CreateSubjectKeyID(pubKey); + + fName.Add( + new DerSequence( + PkcsObjectIdentifiers.Pkcs9AtLocalKeyID, + new DerSet(subjectKeyID))); + } + + certBags.Add(new SafeBag(PkcsObjectIdentifiers.CertBag, cBag.ToAsn1Object(), new DerSet(fName))); + + doneCerts.Add(certEntry.Certificate); + } + + foreach (string certId in certs.Keys) + { + X509CertificateEntry cert = (X509CertificateEntry)certs[certId]; + + if (keys[certId] != null) + continue; + + CertBag cBag = new CertBag( + PkcsObjectIdentifiers.X509Certificate, + new DerOctetString(cert.Certificate.GetEncoded())); + + Asn1EncodableVector fName = new Asn1EncodableVector(); + + foreach (string oid in cert.BagAttributeKeys) + { + // a certificate not immediately linked to a key doesn't require + // a localKeyID and will confuse some PKCS12 implementations. + // + // If we find one, we'll prune it out. + if (oid.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID.Id)) + continue; + + Asn1Encodable entry = cert[oid]; + + // NB: Ignore any existing FriendlyName + if (oid.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName.Id)) + continue; + + fName.Add( + new DerSequence( + new DerObjectIdentifier(oid), + new DerSet(entry))); + } + + // + // make sure we are using the local alias on store + // + // NB: We always set the FriendlyName based on 'certId' + //if (cert[PkcsObjectIdentifiers.Pkcs9AtFriendlyName] == null) + { + fName.Add( + new DerSequence( + PkcsObjectIdentifiers.Pkcs9AtFriendlyName, + new DerSet(new DerBmpString(certId)))); + } + + certBags.Add(new SafeBag(PkcsObjectIdentifiers.CertBag, cBag.ToAsn1Object(), new DerSet(fName))); + + doneCerts.Add(cert.Certificate); + } + + foreach (CertId certId in chainCerts.Keys) + { + X509CertificateEntry cert = (X509CertificateEntry)chainCerts[certId]; + + if (doneCerts.Contains(cert.Certificate)) + continue; + + CertBag cBag = new CertBag( + PkcsObjectIdentifiers.X509Certificate, + new DerOctetString(cert.Certificate.GetEncoded())); + + Asn1EncodableVector fName = new Asn1EncodableVector(); + + foreach (string oid in cert.BagAttributeKeys) + { + // a certificate not immediately linked to a key doesn't require + // a localKeyID and will confuse some PKCS12 implementations. + // + // If we find one, we'll prune it out. + if (oid.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID.Id)) + continue; + + fName.Add( + new DerSequence( + new DerObjectIdentifier(oid), + new DerSet(cert[oid]))); + } + + certBags.Add(new SafeBag(PkcsObjectIdentifiers.CertBag, cBag.ToAsn1Object(), new DerSet(fName))); + } + + byte[] certBagsEncoding = new DerSequence(certBags).GetDerEncoded(); + + ContentInfo certsInfo; + if (password == null || certAlgorithm == null) + { + certsInfo = new ContentInfo(PkcsObjectIdentifiers.Data, new BerOctetString(certBagsEncoding)); + } + else + { + byte[] certBytes = CryptPbeData(true, cAlgId, password, false, certBagsEncoding); + EncryptedData cInfo = new EncryptedData(PkcsObjectIdentifiers.Data, cAlgId, new BerOctetString(certBytes)); + certsInfo = new ContentInfo(PkcsObjectIdentifiers.EncryptedData, cInfo.ToAsn1Object()); + } + + ContentInfo[] info = new ContentInfo[]{ keysInfo, certsInfo }; + + byte[] data = new AuthenticatedSafe(info).GetEncoded( + useDerEncoding ? Asn1Encodable.Der : Asn1Encodable.Ber); + + ContentInfo mainInfo = new ContentInfo(PkcsObjectIdentifiers.Data, new BerOctetString(data)); + + // + // create the mac + // + MacData macData = null; + if (password != null) + { + byte[] mSalt = new byte[20]; + random.NextBytes(mSalt); + + byte[] mac = CalculatePbeMac(OiwObjectIdentifiers.IdSha1, + mSalt, MinIterations, password, false, data); + + AlgorithmIdentifier algId = new AlgorithmIdentifier( + OiwObjectIdentifiers.IdSha1, DerNull.Instance); + DigestInfo dInfo = new DigestInfo(algId, mac); + + macData = new MacData(dInfo, mSalt, MinIterations); + } + + // + // output the Pfx + // + Pfx pfx = new Pfx(mainInfo, macData); + + pfx.EncodeTo(stream, useDerEncoding ? Asn1Encodable.Der : Asn1Encodable.Ber); + } + + internal static byte[] CalculatePbeMac( + DerObjectIdentifier oid, + byte[] salt, + int itCount, + char[] password, + bool wrongPkcs12Zero, + byte[] data) + { + Asn1Encodable asn1Params = PbeUtilities.GenerateAlgorithmParameters( + oid, salt, itCount); + ICipherParameters cipherParams = PbeUtilities.GenerateCipherParameters( + oid, password, wrongPkcs12Zero, asn1Params); + + IMac mac = (IMac) PbeUtilities.CreateEngine(oid); + mac.Init(cipherParams); + return MacUtilities.DoFinal(mac, data); + } + + private static byte[] CryptPbeData( + bool forEncryption, + AlgorithmIdentifier algId, + char[] password, + bool wrongPkcs12Zero, + byte[] data) + { + IBufferedCipher cipher = PbeUtilities.CreateEngine(algId) as IBufferedCipher; + + if (cipher == null) + throw new Exception("Unknown encryption algorithm: " + algId.Algorithm); + + if (algId.Algorithm.Equals(PkcsObjectIdentifiers.IdPbeS2)) + { + PbeS2Parameters pbeParameters = PbeS2Parameters.GetInstance(algId.Parameters); + ICipherParameters cipherParams = PbeUtilities.GenerateCipherParameters( + algId.Algorithm, password, pbeParameters); + cipher.Init(forEncryption, cipherParams); + return cipher.DoFinal(data); + } + else + { + Pkcs12PbeParams pbeParameters = Pkcs12PbeParams.GetInstance(algId.Parameters); + ICipherParameters cipherParams = PbeUtilities.GenerateCipherParameters( + algId.Algorithm, password, wrongPkcs12Zero, pbeParameters); + cipher.Init(forEncryption, cipherParams); + return cipher.DoFinal(data); + } + } + + private class IgnoresCaseHashtable + : IEnumerable + { + private readonly IDictionary orig = Platform.CreateHashtable(); + private readonly IDictionary keys = Platform.CreateHashtable(); + + public void Clear() + { + orig.Clear(); + keys.Clear(); + } + + public IEnumerator GetEnumerator() + { + return orig.GetEnumerator(); + } + + public ICollection Keys + { + get { return orig.Keys; } + } + + public object Remove( + string alias) + { + string upper = Platform.ToUpperInvariant(alias); + string k = (string)keys[upper]; + + if (k == null) + return null; + + keys.Remove(upper); + + object o = orig[k]; + orig.Remove(k); + return o; + } + + public object this[ + string alias] + { + get + { + string upper = Platform.ToUpperInvariant(alias); + string k = (string)keys[upper]; + + if (k == null) + return null; + + return orig[k]; + } + set + { + string upper = Platform.ToUpperInvariant(alias); + string k = (string)keys[upper]; + if (k != null) + { + orig.Remove(k); + } + keys[upper] = alias; + orig[alias] = value; + } + } + + public ICollection Values + { + get { return orig.Values; } + } + + public int Count + { + get { return orig.Count; } + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/Pkcs12Store.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/Pkcs12Store.cs.meta new file mode 100644 index 0000000..6fde12e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/Pkcs12Store.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9074dbfb9db9e3a43b208b3097ff7cd6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/Pkcs12Utilities.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/Pkcs12Utilities.cs new file mode 100644 index 0000000..2fbb82d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/Pkcs12Utilities.cs @@ -0,0 +1,77 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.X509; + +namespace Org.BouncyCastle.Pkcs +{ + /** + * Utility class for reencoding PKCS#12 files to definite length. + */ + public class Pkcs12Utilities + { + /** + * Just re-encode the outer layer of the PKCS#12 file to definite length encoding. + * + * @param berPKCS12File - original PKCS#12 file + * @return a byte array representing the DER encoding of the PFX structure + * @throws IOException + */ + public static byte[] ConvertToDefiniteLength( + byte[] berPkcs12File) + { + Pfx pfx = Pfx.GetInstance(berPkcs12File); + + return pfx.GetEncoded(Asn1Encodable.Der); + } + + /** + * Re-encode the PKCS#12 structure to definite length encoding at the inner layer + * as well, recomputing the MAC accordingly. + * + * @param berPKCS12File - original PKCS12 file. + * @param provider - provider to use for MAC calculation. + * @return a byte array representing the DER encoding of the PFX structure. + * @throws IOException on parsing, encoding errors. + */ + public static byte[] ConvertToDefiniteLength( + byte[] berPkcs12File, + char[] passwd) + { + Pfx pfx = Pfx.GetInstance(berPkcs12File); + + ContentInfo info = pfx.AuthSafe; + + Asn1OctetString content = Asn1OctetString.GetInstance(info.Content); + Asn1Object obj = Asn1Object.FromByteArray(content.GetOctets()); + + info = new ContentInfo(info.ContentType, new DerOctetString(obj.GetEncoded(Asn1Encodable.Der))); + + MacData mData = pfx.MacData; + + try + { + int itCount = mData.IterationCount.IntValue; + byte[] data = Asn1OctetString.GetInstance(info.Content).GetOctets(); + byte[] res = Pkcs12Store.CalculatePbeMac( + mData.Mac.AlgorithmID.Algorithm, mData.GetSalt(), itCount, passwd, false, data); + + AlgorithmIdentifier algId = new AlgorithmIdentifier( + mData.Mac.AlgorithmID.Algorithm, DerNull.Instance); + DigestInfo dInfo = new DigestInfo(algId, res); + + mData = new MacData(dInfo, mData.GetSalt(), itCount); + } + catch (Exception e) + { + throw new IOException("error constructing MAC: " + e.ToString()); + } + + pfx = new Pfx(info, mData); + + return pfx.GetEncoded(Asn1Encodable.Der); + } + } +} \ No newline at end of file diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/Pkcs12Utilities.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/Pkcs12Utilities.cs.meta new file mode 100644 index 0000000..c45a8ce --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/Pkcs12Utilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d90ed87284e370642ad18f12c9d83237 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/Pkcs8EncryptedPrivateKeyInfo.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/Pkcs8EncryptedPrivateKeyInfo.cs new file mode 100644 index 0000000..5882dee --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/Pkcs8EncryptedPrivateKeyInfo.cs @@ -0,0 +1,106 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Pkcs +{ + /// + /// A holding class for a PKCS#8 encrypted private key info object that allows for its decryption. + /// + public class Pkcs8EncryptedPrivateKeyInfo + { + private EncryptedPrivateKeyInfo encryptedPrivateKeyInfo; + + private static EncryptedPrivateKeyInfo parseBytes(byte[] pkcs8Encoding) + { + try + { + return EncryptedPrivateKeyInfo.GetInstance(pkcs8Encoding); + } + + catch (ArgumentException e) + { + throw new PkcsIOException("malformed data: " + e.Message, e); + } + catch (Exception e) + { + throw new PkcsIOException("malformed data: " + e.Message, e); + } + } + + /// + /// Base constructor from a PKCS#8 EncryptedPrivateKeyInfo object. + /// + /// A PKCS#8 EncryptedPrivateKeyInfo object. + public Pkcs8EncryptedPrivateKeyInfo(EncryptedPrivateKeyInfo encryptedPrivateKeyInfo) + { + this.encryptedPrivateKeyInfo = encryptedPrivateKeyInfo; + } + + /// + /// Base constructor from a BER encoding of a PKCS#8 EncryptedPrivateKeyInfo object. + /// + /// A BER encoding of a PKCS#8 EncryptedPrivateKeyInfo objects. + public Pkcs8EncryptedPrivateKeyInfo(byte[] encryptedPrivateKeyInfo) : this(parseBytes(encryptedPrivateKeyInfo)) + { + + } + + /// + /// Returns the underlying ASN.1 structure inside this object. + /// + /// Return the EncryptedPrivateKeyInfo structure in this object. + public EncryptedPrivateKeyInfo ToAsn1Structure() + { + return encryptedPrivateKeyInfo; + } + + /// + /// Returns a copy of the encrypted data in this structure. + /// + /// Return a copy of the encrypted data in this object. + public byte[] GetEncryptedData() + { + return encryptedPrivateKeyInfo.GetEncryptedData(); + } + + /// + /// Return a binary ASN.1 encoding of the EncryptedPrivateKeyInfo structure in this object. + /// + /// A byte array containing the encoded object. + public byte[] GetEncoded() + { + return encryptedPrivateKeyInfo.GetEncoded(); + } + + /// + /// Get a decryptor from the passed in provider and decrypt the encrypted private key info, returning the result. + /// + /// A provider to query for decryptors for the object. + /// The decrypted private key info structure. + public PrivateKeyInfo DecryptPrivateKeyInfo(IDecryptorBuilderProvider inputDecryptorProvider) + { + try + { + ICipherBuilder decryptorBuilder = inputDecryptorProvider.CreateDecryptorBuilder(encryptedPrivateKeyInfo.EncryptionAlgorithm); + + ICipher encIn = decryptorBuilder.BuildCipher(new MemoryInputStream(encryptedPrivateKeyInfo.GetEncryptedData())); + + Stream strm = encIn.Stream; + byte[] data = Streams.ReadAll(encIn.Stream); + Platform.Dispose(strm); + + return PrivateKeyInfo.GetInstance(data); + } + catch (Exception e) + { + throw new PkcsException("unable to read encrypted data: " + e.Message, e); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/Pkcs8EncryptedPrivateKeyInfo.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/Pkcs8EncryptedPrivateKeyInfo.cs.meta new file mode 100644 index 0000000..5137e01 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/Pkcs8EncryptedPrivateKeyInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5045b476422240d43a4d9876c9f5db9b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/Pkcs8EncryptedPrivateKeyInfoBuilder.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/Pkcs8EncryptedPrivateKeyInfoBuilder.cs new file mode 100644 index 0000000..8f75149 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/Pkcs8EncryptedPrivateKeyInfoBuilder.cs @@ -0,0 +1,51 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Pkcs +{ + public class Pkcs8EncryptedPrivateKeyInfoBuilder + { + private PrivateKeyInfo privateKeyInfo; + + public Pkcs8EncryptedPrivateKeyInfoBuilder(byte[] privateKeyInfo): this(PrivateKeyInfo.GetInstance(privateKeyInfo)) + { + } + + public Pkcs8EncryptedPrivateKeyInfoBuilder(PrivateKeyInfo privateKeyInfo) + { + this.privateKeyInfo = privateKeyInfo; + } + + /// + /// Create the encrypted private key info using the passed in encryptor. + /// + /// The encryptor to use. + /// An encrypted private key info containing the original private key info. + public Pkcs8EncryptedPrivateKeyInfo Build( + ICipherBuilder encryptor) + { + try + { + MemoryStream bOut = new MemoryOutputStream(); + ICipher cOut = encryptor.BuildCipher(bOut); + byte[] keyData = privateKeyInfo.GetEncoded(); + + Stream str = cOut.Stream; + str.Write(keyData, 0, keyData.Length); + Platform.Dispose(str); + + return new Pkcs8EncryptedPrivateKeyInfo(new EncryptedPrivateKeyInfo((AlgorithmIdentifier)encryptor.AlgorithmDetails, bOut.ToArray())); + } + catch (IOException) + { + throw new InvalidOperationException("cannot encode privateKeyInfo"); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/Pkcs8EncryptedPrivateKeyInfoBuilder.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/Pkcs8EncryptedPrivateKeyInfoBuilder.cs.meta new file mode 100644 index 0000000..69958de --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/Pkcs8EncryptedPrivateKeyInfoBuilder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5d17edcc2b2d6a1468bea356fee0adcc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/PkcsException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/PkcsException.cs new file mode 100644 index 0000000..7a69ff7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/PkcsException.cs @@ -0,0 +1,21 @@ +using System; + +namespace Org.BouncyCastle.Pkcs +{ + /// + /// Base exception for PKCS related issues. + /// + public class PkcsException + : Exception + { + public PkcsException(string message) + : base(message) + { + } + + public PkcsException(string message, Exception underlying) + : base(message, underlying) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/PkcsException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/PkcsException.cs.meta new file mode 100644 index 0000000..84b23be --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/PkcsException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b010a366275409849bfa7749f1ace5ad +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/PkcsIOException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/PkcsIOException.cs new file mode 100644 index 0000000..19f17a3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/PkcsIOException.cs @@ -0,0 +1,19 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Pkcs +{ + /// + /// Base exception for parsing related issues in the PKCS namespace. + /// + public class PkcsIOException: IOException + { + public PkcsIOException(String message) : base(message) + { + } + + public PkcsIOException(String message, Exception underlying) : base(message, underlying) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/PkcsIOException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/PkcsIOException.cs.meta new file mode 100644 index 0000000..cf11d27 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/PkcsIOException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 651d8892bc7323541a6d0a5696e6208c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/PrivateKeyInfoFactory.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/PrivateKeyInfoFactory.cs new file mode 100644 index 0000000..0d50269 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/PrivateKeyInfoFactory.cs @@ -0,0 +1,291 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Asn1.EdEC; +using Org.BouncyCastle.Asn1.Oiw; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.Rosstandart; +using Org.BouncyCastle.Asn1.Sec; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Pkcs +{ + public sealed class PrivateKeyInfoFactory + { + private PrivateKeyInfoFactory() + { + } + + public static PrivateKeyInfo CreatePrivateKeyInfo( + AsymmetricKeyParameter privateKey) + { + return CreatePrivateKeyInfo(privateKey, null); + } + + /** + * Create a PrivateKeyInfo representation of a private key with attributes. + * + * @param privateKey the key to be encoded into the info object. + * @param attributes the set of attributes to be included. + * @return the appropriate PrivateKeyInfo + * @throws java.io.IOException on an error encoding the key + */ + public static PrivateKeyInfo CreatePrivateKeyInfo(AsymmetricKeyParameter privateKey, Asn1Set attributes) + { + if (privateKey == null) + throw new ArgumentNullException("privateKey"); + if (!privateKey.IsPrivate) + throw new ArgumentException("Public key passed - private key expected", "privateKey"); + + if (privateKey is ElGamalPrivateKeyParameters) + { + ElGamalPrivateKeyParameters _key = (ElGamalPrivateKeyParameters)privateKey; + ElGamalParameters egp = _key.Parameters; + return new PrivateKeyInfo( + new AlgorithmIdentifier(OiwObjectIdentifiers.ElGamalAlgorithm, new ElGamalParameter(egp.P, egp.G).ToAsn1Object()), + new DerInteger(_key.X), + attributes); + } + + if (privateKey is DsaPrivateKeyParameters) + { + DsaPrivateKeyParameters _key = (DsaPrivateKeyParameters)privateKey; + DsaParameters dp = _key.Parameters; + return new PrivateKeyInfo( + new AlgorithmIdentifier(X9ObjectIdentifiers.IdDsa, new DsaParameter(dp.P, dp.Q, dp.G).ToAsn1Object()), + new DerInteger(_key.X), + attributes); + } + + if (privateKey is DHPrivateKeyParameters) + { + DHPrivateKeyParameters _key = (DHPrivateKeyParameters)privateKey; + + DHParameter p = new DHParameter( + _key.Parameters.P, _key.Parameters.G, _key.Parameters.L); + + return new PrivateKeyInfo( + new AlgorithmIdentifier(_key.AlgorithmOid, p.ToAsn1Object()), + new DerInteger(_key.X), + attributes); + } + + if (privateKey is RsaKeyParameters) + { + AlgorithmIdentifier algID = new AlgorithmIdentifier( + PkcsObjectIdentifiers.RsaEncryption, DerNull.Instance); + + RsaPrivateKeyStructure keyStruct; + if (privateKey is RsaPrivateCrtKeyParameters) + { + RsaPrivateCrtKeyParameters _key = (RsaPrivateCrtKeyParameters)privateKey; + + keyStruct = new RsaPrivateKeyStructure( + _key.Modulus, + _key.PublicExponent, + _key.Exponent, + _key.P, + _key.Q, + _key.DP, + _key.DQ, + _key.QInv); + } + else + { + RsaKeyParameters _key = (RsaKeyParameters) privateKey; + + keyStruct = new RsaPrivateKeyStructure( + _key.Modulus, + BigInteger.Zero, + _key.Exponent, + BigInteger.Zero, + BigInteger.Zero, + BigInteger.Zero, + BigInteger.Zero, + BigInteger.Zero); + } + + return new PrivateKeyInfo(algID, keyStruct.ToAsn1Object(), attributes); + } + + if (privateKey is ECPrivateKeyParameters) + { + ECPrivateKeyParameters priv = (ECPrivateKeyParameters) privateKey; + DerBitString publicKey = new DerBitString(ECKeyPairGenerator.GetCorrespondingPublicKey(priv).Q.GetEncoded(false)); + + ECDomainParameters dp = priv.Parameters; + + // ECGOST3410 + if (dp is ECGost3410Parameters) + { + ECGost3410Parameters domainParameters = (ECGost3410Parameters) dp; + + Gost3410PublicKeyAlgParameters gostParams = new Gost3410PublicKeyAlgParameters( + (domainParameters).PublicKeyParamSet, + (domainParameters).DigestParamSet, + (domainParameters).EncryptionParamSet); + + bool is512 = priv.D.BitLength > 256; + DerObjectIdentifier identifier = (is512) ? + RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512 : + RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256; + int size = (is512) ? 64 : 32; + + byte[] encKey = new byte[size]; + + ExtractBytes(encKey, size, 0, priv.D); + + return new PrivateKeyInfo(new AlgorithmIdentifier(identifier, gostParams), new DerOctetString(encKey)); + } + + + int orderBitLength = dp.N.BitLength; + + AlgorithmIdentifier algID; + ECPrivateKeyStructure ec; + + if (priv.AlgorithmName == "ECGOST3410") + { + if (priv.PublicKeyParamSet == null) + throw Platform.CreateNotImplementedException("Not a CryptoPro parameter set"); + + Gost3410PublicKeyAlgParameters gostParams = new Gost3410PublicKeyAlgParameters( + priv.PublicKeyParamSet, CryptoProObjectIdentifiers.GostR3411x94CryptoProParamSet); + + algID = new AlgorithmIdentifier(CryptoProObjectIdentifiers.GostR3410x2001, gostParams); + + // TODO Do we need to pass any parameters here? + ec = new ECPrivateKeyStructure(orderBitLength, priv.D, publicKey, null); + } + else + { + X962Parameters x962; + if (priv.PublicKeyParamSet == null) + { + X9ECParameters ecP = new X9ECParameters(dp.Curve, dp.G, dp.N, dp.H, dp.GetSeed()); + x962 = new X962Parameters(ecP); + } + else + { + x962 = new X962Parameters(priv.PublicKeyParamSet); + } + + ec = new ECPrivateKeyStructure(orderBitLength, priv.D, publicKey, x962); + + algID = new AlgorithmIdentifier(X9ObjectIdentifiers.IdECPublicKey, x962); + } + + return new PrivateKeyInfo(algID, ec, attributes); + } + + if (privateKey is Gost3410PrivateKeyParameters) + { + Gost3410PrivateKeyParameters _key = (Gost3410PrivateKeyParameters)privateKey; + + if (_key.PublicKeyParamSet == null) + throw Platform.CreateNotImplementedException("Not a CryptoPro parameter set"); + + byte[] keyEnc = _key.X.ToByteArrayUnsigned(); + byte[] keyBytes = new byte[keyEnc.Length]; + + for (int i = 0; i != keyBytes.Length; i++) + { + keyBytes[i] = keyEnc[keyEnc.Length - 1 - i]; // must be little endian + } + + Gost3410PublicKeyAlgParameters algParams = new Gost3410PublicKeyAlgParameters( + _key.PublicKeyParamSet, CryptoProObjectIdentifiers.GostR3411x94CryptoProParamSet, null); + + AlgorithmIdentifier algID = new AlgorithmIdentifier( + CryptoProObjectIdentifiers.GostR3410x94, + algParams.ToAsn1Object()); + + return new PrivateKeyInfo(algID, new DerOctetString(keyBytes), attributes); + } + + if (privateKey is X448PrivateKeyParameters) + { + X448PrivateKeyParameters key = (X448PrivateKeyParameters)privateKey; + + return new PrivateKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_X448), + new DerOctetString(key.GetEncoded()), attributes, key.GeneratePublicKey().GetEncoded()); + } + + if (privateKey is X25519PrivateKeyParameters) + { + X25519PrivateKeyParameters key = (X25519PrivateKeyParameters)privateKey; + + return new PrivateKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_X25519), + new DerOctetString(key.GetEncoded()), attributes, key.GeneratePublicKey().GetEncoded()); + } + + if (privateKey is Ed448PrivateKeyParameters) + { + Ed448PrivateKeyParameters key = (Ed448PrivateKeyParameters)privateKey; + + return new PrivateKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_Ed448), + new DerOctetString(key.GetEncoded()), attributes, key.GeneratePublicKey().GetEncoded()); + } + + if (privateKey is Ed25519PrivateKeyParameters) + { + Ed25519PrivateKeyParameters key = (Ed25519PrivateKeyParameters)privateKey; + + return new PrivateKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_Ed25519), + new DerOctetString(key.GetEncoded()), attributes, key.GeneratePublicKey().GetEncoded()); + } + + throw new ArgumentException("Class provided is not convertible: " + Platform.GetTypeName(privateKey)); + } + + public static PrivateKeyInfo CreatePrivateKeyInfo( + char[] passPhrase, + EncryptedPrivateKeyInfo encInfo) + { + return CreatePrivateKeyInfo(passPhrase, false, encInfo); + } + + public static PrivateKeyInfo CreatePrivateKeyInfo( + char[] passPhrase, + bool wrongPkcs12Zero, + EncryptedPrivateKeyInfo encInfo) + { + AlgorithmIdentifier algID = encInfo.EncryptionAlgorithm; + + IBufferedCipher cipher = PbeUtilities.CreateEngine(algID) as IBufferedCipher; + if (cipher == null) + throw new Exception("Unknown encryption algorithm: " + algID.Algorithm); + + ICipherParameters cipherParameters = PbeUtilities.GenerateCipherParameters( + algID, passPhrase, wrongPkcs12Zero); + cipher.Init(false, cipherParameters); + byte[] keyBytes = cipher.DoFinal(encInfo.GetEncryptedData()); + + return PrivateKeyInfo.GetInstance(keyBytes); + } + + private static void ExtractBytes(byte[] encKey, int size, int offSet, BigInteger bI) + { + byte[] val = bI.ToByteArray(); + if (val.Length < size) + { + byte[] tmp = new byte[size]; + Array.Copy(val, 0, tmp, tmp.Length - val.Length, val.Length); + val = tmp; + } + + for (int i = 0; i != size; i++) + { + encKey[offSet + i] = val[val.Length - 1 - i]; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/PrivateKeyInfoFactory.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/PrivateKeyInfoFactory.cs.meta new file mode 100644 index 0000000..0dff9a7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/PrivateKeyInfoFactory.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2c2340e73a1507040bde5920ec340c77 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/X509CertificateEntry.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/X509CertificateEntry.cs new file mode 100644 index 0000000..2f81dd8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/X509CertificateEntry.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.Pkcs +{ + public class X509CertificateEntry + : Pkcs12Entry + { + private readonly X509Certificate cert; + + public X509CertificateEntry( + X509Certificate cert) + : base(Platform.CreateHashtable()) + { + this.cert = cert; + } + +#if !(SILVERLIGHT || PORTABLE) + [Obsolete] + public X509CertificateEntry( + X509Certificate cert, + Hashtable attributes) + : base(attributes) + { + this.cert = cert; + } +#endif + + public X509CertificateEntry( + X509Certificate cert, + IDictionary attributes) + : base(attributes) + { + this.cert = cert; + } + + public X509Certificate Certificate + { + get { return this.cert; } + } + + public override bool Equals(object obj) + { + X509CertificateEntry other = obj as X509CertificateEntry; + + if (other == null) + return false; + + return cert.Equals(other.cert); + } + + public override int GetHashCode() + { + return ~cert.GetHashCode(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/X509CertificateEntry.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/X509CertificateEntry.cs.meta new file mode 100644 index 0000000..75afeaf --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkcs/X509CertificateEntry.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a5c8412ef7157344091774ff8489f750 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix.meta new file mode 100644 index 0000000..4c0cd94 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: cd52b460282bf3d48989f400f0e09aed +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/CertStatus.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/CertStatus.cs new file mode 100644 index 0000000..4f40b7b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/CertStatus.cs @@ -0,0 +1,35 @@ +using System; + +using Org.BouncyCastle.Utilities.Date; + +namespace Org.BouncyCastle.Pkix +{ + public class CertStatus + { + public const int Unrevoked = 11; + + public const int Undetermined = 12; + + private int status = Unrevoked; + + DateTimeObject revocationDate = null; + + /// + /// Returns the revocationDate. + /// + public DateTimeObject RevocationDate + { + get { return revocationDate; } + set { this.revocationDate = value; } + } + + /// + /// Returns the certStatus. + /// + public int Status + { + get { return status; } + set { this.status = value; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/CertStatus.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/CertStatus.cs.meta new file mode 100644 index 0000000..dcec13e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/CertStatus.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: aa02adb99eafe9e42a5eb88187d9479a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixAttrCertChecker.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixAttrCertChecker.cs new file mode 100644 index 0000000..a6eab84 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixAttrCertChecker.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Utilities.Collections; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.Pkix +{ + public abstract class PkixAttrCertChecker + { + /** + * Returns an immutable Set of X.509 attribute certificate + * extensions that this PkixAttrCertChecker supports or + * null if no extensions are supported. + *

    + * Each element of the set is a String representing the + * Object Identifier (OID) of the X.509 extension that is supported. + *

    + *

    + * All X.509 attribute certificate extensions that a + * PkixAttrCertChecker might possibly be able to process + * should be included in the set. + *

    + * + * @return an immutable Set of X.509 extension OIDs (in + * String format) supported by this + * PkixAttrCertChecker, or null if no + * extensions are supported + */ + public abstract ISet GetSupportedExtensions(); + + /** + * Performs checks on the specified attribute certificate. Every handled + * extension is rmeoved from the unresolvedCritExts + * collection. + * + * @param attrCert The attribute certificate to be checked. + * @param certPath The certificate path which belongs to the attribute + * certificate issuer public key certificate. + * @param holderCertPath The certificate path which belongs to the holder + * certificate. + * @param unresolvedCritExts a Collection of OID strings + * representing the current set of unresolved critical extensions + * @throws CertPathValidatorException if the specified attribute certificate + * does not pass the check. + */ + public abstract void Check(IX509AttributeCertificate attrCert, PkixCertPath certPath, + PkixCertPath holderCertPath, ICollection unresolvedCritExts); + + /** + * Returns a clone of this object. + * + * @return a copy of this PkixAttrCertChecker + */ + public abstract PkixAttrCertChecker Clone(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixAttrCertChecker.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixAttrCertChecker.cs.meta new file mode 100644 index 0000000..4311ea8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixAttrCertChecker.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 760e16ad440579b45a09ff6200c85fdb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixAttrCertPathBuilder.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixAttrCertPathBuilder.cs new file mode 100644 index 0000000..a45f30b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixAttrCertPathBuilder.cs @@ -0,0 +1,215 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Security.Certificates; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; +using Org.BouncyCastle.X509; +using Org.BouncyCastle.X509.Store; + +namespace Org.BouncyCastle.Pkix +{ + public class PkixAttrCertPathBuilder + { + /** + * Build and validate a CertPath using the given parameter. + * + * @param params PKIXBuilderParameters object containing all information to + * build the CertPath + */ + public virtual PkixCertPathBuilderResult Build( + PkixBuilderParameters pkixParams) + { + // search target certificates + + IX509Selector certSelect = pkixParams.GetTargetConstraints(); + if (!(certSelect is X509AttrCertStoreSelector)) + { + throw new PkixCertPathBuilderException( + "TargetConstraints must be an instance of " + + typeof(X509AttrCertStoreSelector).FullName + + " for " + + typeof(PkixAttrCertPathBuilder).FullName + " class."); + } + + ICollection targets; + try + { + targets = PkixCertPathValidatorUtilities.FindCertificates( + (X509AttrCertStoreSelector)certSelect, pkixParams.GetStores()); + } + catch (Exception e) + { + throw new PkixCertPathBuilderException("Error finding target attribute certificate.", e); + } + + if (targets.Count == 0) + { + throw new PkixCertPathBuilderException( + "No attribute certificate found matching targetConstraints."); + } + + PkixCertPathBuilderResult result = null; + + // check all potential target certificates + foreach (IX509AttributeCertificate cert in targets) + { + X509CertStoreSelector selector = new X509CertStoreSelector(); + X509Name[] principals = cert.Issuer.GetPrincipals(); + ISet issuers = new HashSet(); + for (int i = 0; i < principals.Length; i++) + { + try + { + selector.Subject = principals[i]; + + issuers.AddAll(PkixCertPathValidatorUtilities.FindCertificates(selector, pkixParams.GetStores())); + } + catch (Exception e) + { + throw new PkixCertPathBuilderException( + "Public key certificate for attribute certificate cannot be searched.", + e); + } + } + + if (issuers.IsEmpty) + throw new PkixCertPathBuilderException("Public key certificate for attribute certificate cannot be found."); + + IList certPathList = Platform.CreateArrayList(); + + foreach (X509Certificate issuer in issuers) + { + result = Build(cert, issuer, pkixParams, certPathList); + + if (result != null) + break; + } + + if (result != null) + break; + } + + if (result == null && certPathException != null) + { + throw new PkixCertPathBuilderException( + "Possible certificate chain could not be validated.", + certPathException); + } + + if (result == null && certPathException == null) + { + throw new PkixCertPathBuilderException( + "Unable to find certificate chain."); + } + + return result; + } + + private Exception certPathException; + + private PkixCertPathBuilderResult Build( + IX509AttributeCertificate attrCert, + X509Certificate tbvCert, + PkixBuilderParameters pkixParams, + IList tbvPath) + { + // If tbvCert is readily present in tbvPath, it indicates having run + // into a cycle in the + // PKI graph. + if (tbvPath.Contains(tbvCert)) + return null; + + // step out, the certificate is not allowed to appear in a certification + // chain + if (pkixParams.GetExcludedCerts().Contains(tbvCert)) + return null; + + // test if certificate path exceeds maximum length + if (pkixParams.MaxPathLength != -1) + { + if (tbvPath.Count - 1 > pkixParams.MaxPathLength) + return null; + } + + tbvPath.Add(tbvCert); + + PkixCertPathBuilderResult builderResult = null; + +// X509CertificateParser certParser = new X509CertificateParser(); + PkixAttrCertPathValidator validator = new PkixAttrCertPathValidator(); + + try + { + // check whether the issuer of is a TrustAnchor + if (PkixCertPathValidatorUtilities.IsIssuerTrustAnchor(tbvCert, pkixParams.GetTrustAnchors())) + { + PkixCertPath certPath = new PkixCertPath(tbvPath); + PkixCertPathValidatorResult result; + + try + { + result = validator.Validate(certPath, pkixParams); + } + catch (Exception e) + { + throw new Exception("Certification path could not be validated.", e); + } + + return new PkixCertPathBuilderResult(certPath, result.TrustAnchor, + result.PolicyTree, result.SubjectPublicKey); + } + else + { + // add additional X.509 stores from locations in certificate + try + { + PkixCertPathValidatorUtilities.AddAdditionalStoresFromAltNames(tbvCert, pkixParams); + } + catch (CertificateParsingException e) + { + throw new Exception("No additional X.509 stores can be added from certificate locations.", e); + } + + // try to get the issuer certificate from one of the stores + ISet issuers = new HashSet(); + try + { + issuers.AddAll(PkixCertPathValidatorUtilities.FindIssuerCerts(tbvCert, pkixParams)); + } + catch (Exception e) + { + throw new Exception("Cannot find issuer certificate for certificate in certification path.", e); + } + + if (issuers.IsEmpty) + throw new Exception("No issuer certificate for certificate in certification path found."); + + foreach (X509Certificate issuer in issuers) + { + // if untrusted self signed certificate continue + if (PkixCertPathValidatorUtilities.IsSelfIssued(issuer)) + continue; + + builderResult = Build(attrCert, issuer, pkixParams, tbvPath); + + if (builderResult != null) + break; + } + } + } + catch (Exception e) + { + certPathException = new Exception("No valid certification path could be build.", e); + } + + if (builderResult == null) + { + tbvPath.Remove(tbvCert); + } + + return builderResult; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixAttrCertPathBuilder.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixAttrCertPathBuilder.cs.meta new file mode 100644 index 0000000..20a4dfa --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixAttrCertPathBuilder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3866af074f0769042a05d393150b7359 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixAttrCertPathValidator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixAttrCertPathValidator.cs new file mode 100644 index 0000000..5f53bcd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixAttrCertPathValidator.cs @@ -0,0 +1,76 @@ +using System; + +using Org.BouncyCastle.X509; +using Org.BouncyCastle.X509.Store; + +namespace Org.BouncyCastle.Pkix +{ + /** + * CertPathValidatorSpi implementation for X.509 Attribute Certificates la RFC 3281. + * + * @see org.bouncycastle.x509.ExtendedPkixParameters + */ + public class PkixAttrCertPathValidator + // extends CertPathValidatorSpi + { + /** + * Validates an attribute certificate with the given certificate path. + * + *

    + * params must be an instance of + * ExtendedPkixParameters. + *

    + * The target constraints in the params must be an + * X509AttrCertStoreSelector with at least the attribute + * certificate criterion set. Obey that also target informations may be + * necessary to correctly validate this attribute certificate. + *

    + * The attribute certificate issuer must be added to the trusted attribute + * issuers with {@link ExtendedPkixParameters#setTrustedACIssuers(Set)}. + *

    + * @param certPath The certificate path which belongs to the attribute + * certificate issuer public key certificate. + * @param params The PKIX parameters. + * @return A PKIXCertPathValidatorResult of the result of + * validating the certPath. + * @throws InvalidAlgorithmParameterException if params is + * inappropriate for this validator. + * @throws CertPathValidatorException if the verification fails. + */ + public virtual PkixCertPathValidatorResult Validate( + PkixCertPath certPath, + PkixParameters pkixParams) + { + IX509Selector certSelect = pkixParams.GetTargetConstraints(); + if (!(certSelect is X509AttrCertStoreSelector)) + { + throw new ArgumentException( + "TargetConstraints must be an instance of " + typeof(X509AttrCertStoreSelector).FullName, + "pkixParams"); + } + IX509AttributeCertificate attrCert = ((X509AttrCertStoreSelector) certSelect).AttributeCert; + + PkixCertPath holderCertPath = Rfc3281CertPathUtilities.ProcessAttrCert1(attrCert, pkixParams); + PkixCertPathValidatorResult result = Rfc3281CertPathUtilities.ProcessAttrCert2(certPath, pkixParams); + X509Certificate issuerCert = (X509Certificate)certPath.Certificates[0]; + Rfc3281CertPathUtilities.ProcessAttrCert3(issuerCert, pkixParams); + Rfc3281CertPathUtilities.ProcessAttrCert4(issuerCert, pkixParams); + Rfc3281CertPathUtilities.ProcessAttrCert5(attrCert, pkixParams); + // 6 already done in X509AttrCertStoreSelector + Rfc3281CertPathUtilities.ProcessAttrCert7(attrCert, certPath, holderCertPath, pkixParams); + Rfc3281CertPathUtilities.AdditionalChecks(attrCert, pkixParams); + DateTime date; + try + { + date = PkixCertPathValidatorUtilities.GetValidCertDateFromValidityModel(pkixParams, null, -1); + } + catch (Exception e) + { + throw new PkixCertPathValidatorException( + "Could not get validity date from attribute certificate.", e); + } + Rfc3281CertPathUtilities.CheckCrls(attrCert, pkixParams, issuerCert, date, certPath.Certificates); + return result; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixAttrCertPathValidator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixAttrCertPathValidator.cs.meta new file mode 100644 index 0000000..5d898b3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixAttrCertPathValidator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1b9dbb6af2ea73f42b39f36f71f33d38 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixBuilderParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixBuilderParameters.cs new file mode 100644 index 0000000..9b8fb3d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixBuilderParameters.cs @@ -0,0 +1,140 @@ +using System; +using System.Text; + +using Org.BouncyCastle.Security; +using Org.BouncyCastle.X509.Store; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Pkix +{ + /// + /// Summary description for PkixBuilderParameters. + /// + public class PkixBuilderParameters + : PkixParameters + { + private int maxPathLength = 5; + + private ISet excludedCerts = new HashSet(); + + /** + * Returns an instance of PkixBuilderParameters. + *

    + * This method can be used to get a copy from other + * PKIXBuilderParameters, PKIXParameters, + * and ExtendedPKIXParameters instances. + *

    + * + * @param pkixParams The PKIX parameters to create a copy of. + * @return An PkixBuilderParameters instance. + */ + public static PkixBuilderParameters GetInstance( + PkixParameters pkixParams) + { + PkixBuilderParameters parameters = new PkixBuilderParameters( + pkixParams.GetTrustAnchors(), + new X509CertStoreSelector(pkixParams.GetTargetCertConstraints())); + parameters.SetParams(pkixParams); + return parameters; + } + + public PkixBuilderParameters( + ISet trustAnchors, + IX509Selector targetConstraints) + : base(trustAnchors) + { + SetTargetCertConstraints(targetConstraints); + } + + public virtual int MaxPathLength + { + get { return maxPathLength; } + set + { + if (value < -1) + { + throw new InvalidParameterException( + "The maximum path length parameter can not be less than -1."); + } + this.maxPathLength = value; + } + } + + /// + /// Excluded certificates are not used for building a certification path. + /// + /// the excluded certificates. + public virtual ISet GetExcludedCerts() + { + return new HashSet(excludedCerts); + } + + /// + /// Sets the excluded certificates which are not used for building a + /// certification path. If the ISet is null an + /// empty set is assumed. + /// + /// + /// The given set is cloned to protect it against subsequent modifications. + /// + /// The excluded certificates to set. + public virtual void SetExcludedCerts( + ISet excludedCerts) + { + if (excludedCerts == null) + { + this.excludedCerts = new HashSet(); + } + else + { + this.excludedCerts = new HashSet(excludedCerts); + } + } + + /** + * Can alse handle ExtendedPKIXBuilderParameters and + * PKIXBuilderParameters. + * + * @param params Parameters to set. + * @see org.bouncycastle.x509.ExtendedPKIXParameters#setParams(java.security.cert.PKIXParameters) + */ + protected override void SetParams( + PkixParameters parameters) + { + base.SetParams(parameters); + if (parameters is PkixBuilderParameters) + { + PkixBuilderParameters _params = (PkixBuilderParameters) parameters; + maxPathLength = _params.maxPathLength; + excludedCerts = new HashSet(_params.excludedCerts); + } + } + + /** + * Makes a copy of this PKIXParameters object. Changes to the + * copy will not affect the original and vice versa. + * + * @return a copy of this PKIXParameters object + */ + public override object Clone() + { + PkixBuilderParameters parameters = new PkixBuilderParameters( + GetTrustAnchors(), GetTargetCertConstraints()); + parameters.SetParams(this); + return parameters; + } + + public override string ToString() + { + string nl = Platform.NewLine; + StringBuilder s = new StringBuilder(); + s.Append("PkixBuilderParameters [" + nl); + s.Append(base.ToString()); + s.Append(" Maximum Path Length: "); + s.Append(MaxPathLength); + s.Append(nl + "]" + nl); + return s.ToString(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixBuilderParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixBuilderParameters.cs.meta new file mode 100644 index 0000000..98e2d6d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixBuilderParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a6007dcffe2dfc9499cc4c27cd1726b5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPath.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPath.cs new file mode 100644 index 0000000..459c161 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPath.cs @@ -0,0 +1,460 @@ +using System; +using System.Collections; +using System.IO; +using System.Text; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Cms; +using Org.BouncyCastle.X509; +using Org.BouncyCastle.OpenSsl; +using Org.BouncyCastle.Security.Certificates; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Pkix +{ + /** + * An immutable sequence of certificates (a certification path).
    + *
    + * This is an abstract class that defines the methods common to all CertPaths. + * Subclasses can handle different kinds of certificates (X.509, PGP, etc.).
    + *
    + * All CertPath objects have a type, a list of Certificates, and one or more + * supported encodings. Because the CertPath class is immutable, a CertPath + * cannot change in any externally visible way after being constructed. This + * stipulation applies to all public fields and methods of this class and any + * added or overridden by subclasses.
    + *
    + * The type is a string that identifies the type of Certificates in the + * certification path. For each certificate cert in a certification path + * certPath, cert.getType().equals(certPath.getType()) must be true.
    + *
    + * The list of Certificates is an ordered List of zero or more Certificates. + * This List and all of the Certificates contained in it must be immutable.
    + *
    + * Each CertPath object must support one or more encodings so that the object + * can be translated into a byte array for storage or transmission to other + * parties. Preferably, these encodings should be well-documented standards + * (such as PKCS#7). One of the encodings supported by a CertPath is considered + * the default encoding. This encoding is used if no encoding is explicitly + * requested (for the {@link #getEncoded()} method, for instance).
    + *
    + * All CertPath objects are also Serializable. CertPath objects are resolved + * into an alternate {@link CertPathRep} object during serialization. This + * allows a CertPath object to be serialized into an equivalent representation + * regardless of its underlying implementation.
    + *
    + * CertPath objects can be created with a CertificateFactory or they can be + * returned by other classes, such as a CertPathBuilder.
    + *
    + * By convention, X.509 CertPaths (consisting of X509Certificates), are ordered + * starting with the target certificate and ending with a certificate issued by + * the trust anchor. That is, the issuer of one certificate is the subject of + * the following one. The certificate representing the + * {@link TrustAnchor TrustAnchor} should not be included in the certification + * path. Unvalidated X.509 CertPaths may not follow these conventions. PKIX + * CertPathValidators will detect any departure from these conventions that + * cause the certification path to be invalid and throw a + * CertPathValidatorException.
    + *
    + * Concurrent Access
    + *
    + * All CertPath objects must be thread-safe. That is, multiple threads may + * concurrently invoke the methods defined in this class on a single CertPath + * object (or more than one) with no ill effects. This is also true for the List + * returned by CertPath.getCertificates.
    + *
    + * Requiring CertPath objects to be immutable and thread-safe allows them to be + * passed around to various pieces of code without worrying about coordinating + * access. Providing this thread-safety is generally not difficult, since the + * CertPath and List objects in question are immutable. + * + * @see CertificateFactory + * @see CertPathBuilder + */ + /// + /// CertPath implementation for X.509 certificates. + /// + public class PkixCertPath +// : CertPath + { + internal static readonly IList certPathEncodings; + + static PkixCertPath() + { + IList encodings = Platform.CreateArrayList(); + encodings.Add("PkiPath"); + encodings.Add("PEM"); + encodings.Add("PKCS7"); + certPathEncodings = CollectionUtilities.ReadOnly(encodings); + } + + private readonly IList certificates; + + /** + * @param certs + */ + private static IList SortCerts( + IList certs) + { + if (certs.Count < 2) + return certs; + + X509Name issuer = ((X509Certificate)certs[0]).IssuerDN; + bool okay = true; + + for (int i = 1; i != certs.Count; i++) + { + X509Certificate cert = (X509Certificate)certs[i]; + + if (issuer.Equivalent(cert.SubjectDN, true)) + { + issuer = ((X509Certificate)certs[i]).IssuerDN; + } + else + { + okay = false; + break; + } + } + + if (okay) + return certs; + + // find end-entity cert + IList retList = Platform.CreateArrayList(certs.Count); + IList orig = Platform.CreateArrayList(certs); + + for (int i = 0; i < certs.Count; i++) + { + X509Certificate cert = (X509Certificate)certs[i]; + bool found = false; + + X509Name subject = cert.SubjectDN; + foreach (X509Certificate c in certs) + { + if (c.IssuerDN.Equivalent(subject, true)) + { + found = true; + break; + } + } + + if (!found) + { + retList.Add(cert); + certs.RemoveAt(i); + } + } + + // can only have one end entity cert - something's wrong, give up. + if (retList.Count > 1) + return orig; + + for (int i = 0; i != retList.Count; i++) + { + issuer = ((X509Certificate)retList[i]).IssuerDN; + + for (int j = 0; j < certs.Count; j++) + { + X509Certificate c = (X509Certificate)certs[j]; + if (issuer.Equivalent(c.SubjectDN, true)) + { + retList.Add(c); + certs.RemoveAt(j); + break; + } + } + } + + // make sure all certificates are accounted for. + if (certs.Count > 0) + return orig; + + return retList; + } + + /** + * Creates a CertPath of the specified type. + * This constructor is protected because most users should use + * a CertificateFactory to create CertPaths. + * @param type the standard name of the type of Certificatesin this path + **/ + public PkixCertPath( + ICollection certificates) +// : base("X.509") + { + this.certificates = SortCerts(Platform.CreateArrayList(certificates)); + } + + public PkixCertPath( + Stream inStream) + : this(inStream, "PkiPath") + { + } + + /** + * Creates a CertPath of the specified type. + * This constructor is protected because most users should use + * a CertificateFactory to create CertPaths. + * + * @param type the standard name of the type of Certificatesin this path + **/ + public PkixCertPath( + Stream inStream, + string encoding) +// : base("X.509") + { + string upper = Platform.ToUpperInvariant(encoding); + + IList certs; + try + { + if (upper.Equals(Platform.ToUpperInvariant("PkiPath"))) + { + Asn1InputStream derInStream = new Asn1InputStream(inStream); + Asn1Object derObject = derInStream.ReadObject(); + if (!(derObject is Asn1Sequence)) + { + throw new CertificateException( + "input stream does not contain a ASN1 SEQUENCE while reading PkiPath encoded data to load CertPath"); + } + + certs = Platform.CreateArrayList(); + + foreach (Asn1Encodable ae in (Asn1Sequence)derObject) + { + byte[] derBytes = ae.GetEncoded(Asn1Encodable.Der); + Stream certInStream = new MemoryStream(derBytes, false); + + // TODO Is inserting at the front important (list will be sorted later anyway)? + certs.Insert(0, new X509CertificateParser().ReadCertificate(certInStream)); + } + } + else if (upper.Equals("PKCS7") || upper.Equals("PEM")) + { + certs = Platform.CreateArrayList(new X509CertificateParser().ReadCertificates(inStream)); + } + else + { + throw new CertificateException("unsupported encoding: " + encoding); + } + } + catch (IOException ex) + { + throw new CertificateException( + "IOException throw while decoding CertPath:\n" + + ex.ToString()); + } + + this.certificates = SortCerts(certs); + } + + /** + * Returns an iteration of the encodings supported by this + * certification path, with the default encoding + * first. Attempts to modify the returned Iterator via its + * remove method result in an UnsupportedOperationException. + * + * @return an Iterator over the names of the supported encodings (as Strings) + **/ + public virtual IEnumerable Encodings + { + get { return new EnumerableProxy(certPathEncodings); } + } + + /** + * Compares this certification path for equality with the specified object. + * Two CertPaths are equal if and only if their types are equal and their + * certificate Lists (and by implication the Certificates in those Lists) + * are equal. A CertPath is never equal to an object that is not a CertPath.
    + *
    + * This algorithm is implemented by this method. If it is overridden, the + * behavior specified here must be maintained. + * + * @param other + * the object to test for equality with this certification path + * + * @return true if the specified object is equal to this certification path, + * false otherwise + * + * @see Object#hashCode() Object.hashCode() + */ + public override bool Equals( + object obj) + { + if (this == obj) + return true; + + PkixCertPath other = obj as PkixCertPath; + if (other == null) + return false; + +// if (!this.Type.Equals(other.Type)) +// return false; + + //return this.Certificates.Equals(other.Certificates); + + // TODO Extract this to a utility class + IList thisCerts = this.Certificates; + IList otherCerts = other.Certificates; + + if (thisCerts.Count != otherCerts.Count) + return false; + + IEnumerator e1 = thisCerts.GetEnumerator(); + IEnumerator e2 = otherCerts.GetEnumerator(); + + while (e1.MoveNext()) + { + e2.MoveNext(); + + if (!Platform.Equals(e1.Current, e2.Current)) + return false; + } + + return true; + } + + public override int GetHashCode() + { + // FIXME? + return this.Certificates.GetHashCode(); + } + + /** + * Returns the encoded form of this certification path, using + * the default encoding. + * + * @return the encoded bytes + * @exception CertificateEncodingException if an encoding error occurs + **/ + public virtual byte[] GetEncoded() + { + foreach (object enc in Encodings) + { + if (enc is string) + { + return GetEncoded((string)enc); + } + } + return null; + } + + /** + * Returns the encoded form of this certification path, using + * the specified encoding. + * + * @param encoding the name of the encoding to use + * @return the encoded bytes + * @exception CertificateEncodingException if an encoding error + * occurs or the encoding requested is not supported + * + */ + public virtual byte[] GetEncoded( + string encoding) + { + if (Platform.EqualsIgnoreCase(encoding, "PkiPath")) + { + Asn1EncodableVector v = new Asn1EncodableVector(); + + for (int i = certificates.Count - 1; i >= 0; i--) + { + v.Add(ToAsn1Object((X509Certificate) certificates[i])); + } + + return ToDerEncoded(new DerSequence(v)); + } + else if (Platform.EqualsIgnoreCase(encoding, "PKCS7")) + { + Asn1.Pkcs.ContentInfo encInfo = new Asn1.Pkcs.ContentInfo( + PkcsObjectIdentifiers.Data, null); + + Asn1EncodableVector v = new Asn1EncodableVector(); + for (int i = 0; i != certificates.Count; i++) + { + v.Add(ToAsn1Object((X509Certificate)certificates[i])); + } + + Asn1.Pkcs.SignedData sd = new Asn1.Pkcs.SignedData( + new DerInteger(1), + new DerSet(), + encInfo, + new DerSet(v), + null, + new DerSet()); + + return ToDerEncoded(new Asn1.Pkcs.ContentInfo(PkcsObjectIdentifiers.SignedData, sd)); + } + else if (Platform.EqualsIgnoreCase(encoding, "PEM")) + { + MemoryStream bOut = new MemoryStream(); + PemWriter pWrt = new PemWriter(new StreamWriter(bOut)); + + try + { + for (int i = 0; i != certificates.Count; i++) + { + pWrt.WriteObject(certificates[i]); + } + + Platform.Dispose(pWrt.Writer); + } + catch (Exception) + { + throw new CertificateEncodingException("can't encode certificate for PEM encoded path"); + } + + return bOut.ToArray(); + } + else + { + throw new CertificateEncodingException("unsupported encoding: " + encoding); + } + } + + /// + /// Returns the list of certificates in this certification + /// path. + /// + public virtual IList Certificates + { + get { return CollectionUtilities.ReadOnly(certificates); } + } + + /** + * Return a DERObject containing the encoded certificate. + * + * @param cert the X509Certificate object to be encoded + * + * @return the DERObject + **/ + private Asn1Object ToAsn1Object( + X509Certificate cert) + { + try + { + return Asn1Object.FromByteArray(cert.GetEncoded()); + } + catch (Exception e) + { + throw new CertificateEncodingException("Exception while encoding certificate", e); + } + } + + private byte[] ToDerEncoded(Asn1Encodable obj) + { + try + { + return obj.GetEncoded(Asn1Encodable.Der); + } + catch (IOException e) + { + throw new CertificateEncodingException("Exception thrown", e); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPath.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPath.cs.meta new file mode 100644 index 0000000..49fd68e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPath.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 87ee7a54852388d408a443cef91bae11 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPathBuilder.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPathBuilder.cs new file mode 100644 index 0000000..1bc7b8c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPathBuilder.cs @@ -0,0 +1,205 @@ +using System; +using System.Collections; +using System.Text; + +using Org.BouncyCastle.Asn1.IsisMtt; +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Asn1.X500; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security.Certificates; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; +using Org.BouncyCastle.X509; +using Org.BouncyCastle.X509.Store; + +namespace Org.BouncyCastle.Pkix +{ + /** + * Implements the PKIX CertPathBuilding algorithm for BouncyCastle. + * + * @see CertPathBuilderSpi + */ + public class PkixCertPathBuilder + // : CertPathBuilderSpi + { + /** + * Build and validate a CertPath using the given parameter. + * + * @param params PKIXBuilderParameters object containing all information to + * build the CertPath + */ + public virtual PkixCertPathBuilderResult Build( + PkixBuilderParameters pkixParams) + { + // search target certificates + + IX509Selector certSelect = pkixParams.GetTargetCertConstraints(); + if (!(certSelect is X509CertStoreSelector)) + { + throw new PkixCertPathBuilderException( + "TargetConstraints must be an instance of " + + typeof(X509CertStoreSelector).FullName + " for " + + Platform.GetTypeName(this) + " class."); + } + + ISet targets = new HashSet(); + try + { + targets.AddAll(PkixCertPathValidatorUtilities.FindCertificates((X509CertStoreSelector)certSelect, pkixParams.GetStores())); + // TODO Should this include an entry for pkixParams.GetAdditionalStores() too? + } + catch (Exception e) + { + throw new PkixCertPathBuilderException( + "Error finding target certificate.", e); + } + + if (targets.IsEmpty) + throw new PkixCertPathBuilderException("No certificate found matching targetConstraints."); + + PkixCertPathBuilderResult result = null; + IList certPathList = Platform.CreateArrayList(); + + // check all potential target certificates + foreach (X509Certificate cert in targets) + { + result = Build(cert, pkixParams, certPathList); + + if (result != null) + break; + } + + if (result == null && certPathException != null) + { + throw new PkixCertPathBuilderException(certPathException.Message, certPathException.InnerException); + } + + if (result == null && certPathException == null) + { + throw new PkixCertPathBuilderException("Unable to find certificate chain."); + } + + return result; + } + + private Exception certPathException; + + protected virtual PkixCertPathBuilderResult Build( + X509Certificate tbvCert, + PkixBuilderParameters pkixParams, + IList tbvPath) + { + // If tbvCert is readily present in tbvPath, it indicates having run + // into a cycle in the PKI graph. + if (tbvPath.Contains(tbvCert)) + return null; + + // step out, the certificate is not allowed to appear in a certification + // chain. + if (pkixParams.GetExcludedCerts().Contains(tbvCert)) + return null; + + // test if certificate path exceeds maximum length + if (pkixParams.MaxPathLength != -1) + { + if (tbvPath.Count - 1 > pkixParams.MaxPathLength) + return null; + } + + tbvPath.Add(tbvCert); + +// X509CertificateParser certParser = new X509CertificateParser(); + PkixCertPathBuilderResult builderResult = null; + PkixCertPathValidator validator = new PkixCertPathValidator(); + + try + { + // check whether the issuer of is a TrustAnchor + if (PkixCertPathValidatorUtilities.IsIssuerTrustAnchor(tbvCert, pkixParams.GetTrustAnchors())) + { + // exception message from possibly later tried certification + // chains + PkixCertPath certPath = null; + try + { + certPath = new PkixCertPath(tbvPath); + } + catch (Exception e) + { + throw new Exception( + "Certification path could not be constructed from certificate list.", + e); + } + + PkixCertPathValidatorResult result = null; + try + { + result = (PkixCertPathValidatorResult)validator.Validate( + certPath, pkixParams); + } + catch (Exception e) + { + throw new Exception( + "Certification path could not be validated.", e); + } + + return new PkixCertPathBuilderResult(certPath, result.TrustAnchor, + result.PolicyTree, result.SubjectPublicKey); + } + else + { + // add additional X.509 stores from locations in certificate + try + { + PkixCertPathValidatorUtilities.AddAdditionalStoresFromAltNames( + tbvCert, pkixParams); + } + catch (CertificateParsingException e) + { + throw new Exception( + "No additiontal X.509 stores can be added from certificate locations.", + e); + } + + // try to get the issuer certificate from one of the stores + HashSet issuers = new HashSet(); + try + { + issuers.AddAll(PkixCertPathValidatorUtilities.FindIssuerCerts(tbvCert, pkixParams)); + } + catch (Exception e) + { + throw new Exception( + "Cannot find issuer certificate for certificate in certification path.", + e); + } + + if (issuers.IsEmpty) + throw new Exception("No issuer certificate for certificate in certification path found."); + + foreach (X509Certificate issuer in issuers) + { + builderResult = Build(issuer, pkixParams, tbvPath); + + if (builderResult != null) + break; + } + } + } + catch (Exception e) + { + certPathException = e; + } + + if (builderResult == null) + { + tbvPath.Remove(tbvCert); + } + + return builderResult; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPathBuilder.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPathBuilder.cs.meta new file mode 100644 index 0000000..6609678 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPathBuilder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 121166100e34fbc40ab2401f91b97d94 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPathBuilderException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPathBuilderException.cs new file mode 100644 index 0000000..0f10179 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPathBuilderException.cs @@ -0,0 +1,22 @@ +using System; + +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Pkix +{ + /// + /// Summary description for PkixCertPathBuilderException. + /// +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE) + [Serializable] +#endif + public class PkixCertPathBuilderException : GeneralSecurityException + { + public PkixCertPathBuilderException() : base() { } + + public PkixCertPathBuilderException(string message) : base(message) { } + + public PkixCertPathBuilderException(string message, Exception exception) : base(message, exception) { } + + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPathBuilderException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPathBuilderException.cs.meta new file mode 100644 index 0000000..8d30c59 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPathBuilderException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bbda5a594979f8b40b77d323bf40d138 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPathBuilderResult.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPathBuilderResult.cs new file mode 100644 index 0000000..f800303 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPathBuilderResult.cs @@ -0,0 +1,45 @@ +using System; +using System.Text; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Pkix; + +namespace Org.BouncyCastle.Pkix +{ + /// + /// Summary description for PkixCertPathBuilderResult. + /// + public class PkixCertPathBuilderResult + : PkixCertPathValidatorResult//, ICertPathBuilderResult + { + private PkixCertPath certPath; + + public PkixCertPathBuilderResult( + PkixCertPath certPath, + TrustAnchor trustAnchor, + PkixPolicyNode policyTree, + AsymmetricKeyParameter subjectPublicKey) + : base(trustAnchor, policyTree, subjectPublicKey) + { + if (certPath == null) + throw new ArgumentNullException("certPath"); + + this.certPath = certPath; + } + + public PkixCertPath CertPath + { + get { return certPath; } + } + + public override string ToString() + { + StringBuilder s = new StringBuilder(); + s.Append("SimplePKIXCertPathBuilderResult: [\n"); + s.Append(" Certification Path: ").Append(CertPath).Append('\n'); + s.Append(" Trust Anchor: ").Append(this.TrustAnchor.TrustedCert.IssuerDN.ToString()).Append('\n'); + s.Append(" Subject Public Key: ").Append(this.SubjectPublicKey).Append("\n]"); + return s.ToString(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPathBuilderResult.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPathBuilderResult.cs.meta new file mode 100644 index 0000000..a33b7df --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPathBuilderResult.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2968b8e5e46d61c4389781fc7bcdd74e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPathChecker.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPathChecker.cs new file mode 100644 index 0000000..da7e82b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPathChecker.cs @@ -0,0 +1,99 @@ +using Org.BouncyCastle.Utilities.Collections; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.Pkix +{ + public abstract class PkixCertPathChecker + { + protected PkixCertPathChecker() + { + } + + /** + * Initializes the internal state of this PKIXCertPathChecker. + *

    + * The forward flag specifies the order that certificates + * will be passed to the {@link #check check} method (forward or reverse). A + * PKIXCertPathChecker must support reverse checking + * and may support forward checking. + *

    + * + * @param forward + * the order that certificates are presented to the + * check method. If true, + * certificates are presented from target to most-trusted CA + * (forward); if false, from most-trusted CA to + * target (reverse). + * @exception CertPathValidatorException + * if this PKIXCertPathChecker is unable to + * check certificates in the specified order; it should never + * be thrown if the forward flag is false since reverse + * checking must be supported + */ + public abstract void Init(bool forward); + //throws CertPathValidatorException; + + /** + * Indicates if forward checking is supported. Forward checking refers to + * the ability of the PKIXCertPathChecker to perform its + * checks when certificates are presented to the check method + * in the forward direction (from target to most-trusted CA). + * + * @return true if forward checking is supported, + * false otherwise + */ + public abstract bool IsForwardCheckingSupported(); + + /** + * Returns an immutable Set of X.509 certificate extensions + * that this PKIXCertPathChecker supports (i.e. recognizes, + * is able to process), or null if no extensions are + * supported. + *

    + * Each element of the set is a String representing the + * Object Identifier (OID) of the X.509 extension that is supported. The OID + * is represented by a set of nonnegative integers separated by periods. + *

    + * All X.509 certificate extensions that a PKIXCertPathChecker + * might possibly be able to process should be included in the set. + *

    + * + * @return an immutable Set of X.509 extension OIDs (in + * String format) supported by this + * PKIXCertPathChecker, or null if no + * extensions are supported + */ + public abstract ISet GetSupportedExtensions(); + + /** + * Performs the check(s) on the specified certificate using its internal + * state and removes any critical extensions that it processes from the + * specified collection of OID strings that represent the unresolved + * critical extensions. The certificates are presented in the order + * specified by the init method. + * + * @param cert + * the Certificate to be checked + * @param unresolvedCritExts + * a Collection of OID strings representing the + * current set of unresolved critical extensions + * @exception CertPathValidatorException + * if the specified certificate does not pass the check + */ + public abstract void Check(X509Certificate cert, ISet unresolvedCritExts); + //throws CertPathValidatorException; + + /** + * Returns a clone of this object. Calls the Object.clone() + * method. All subclasses which maintain state must support and override + * this method, if necessary. + * + * @return a copy of this PKIXCertPathChecker + */ + public virtual object Clone() + { + // TODO Check this + return base.MemberwiseClone(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPathChecker.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPathChecker.cs.meta new file mode 100644 index 0000000..6df366d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPathChecker.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9ecc5bab0272d444fb26dc6307a0e723 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPathValidator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPathValidator.cs new file mode 100644 index 0000000..64039f9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPathValidator.cs @@ -0,0 +1,448 @@ +using System; +using System.Collections; +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Security.Certificates; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; +using Org.BouncyCastle.X509; +using Org.BouncyCastle.X509.Store; + +namespace Org.BouncyCastle.Pkix +{ + /** + * The Service Provider Interface (SPI) + * for the {@link CertPathValidator CertPathValidator} class. All + * CertPathValidator implementations must include a class (the + * SPI class) that extends this class (CertPathValidatorSpi) + * and implements all of its methods. In general, instances of this class + * should only be accessed through the CertPathValidator class. + * For details, see the Java Cryptography Architecture.
    + *
    + * Concurrent Access
    + *
    + * Instances of this class need not be protected against concurrent + * access from multiple threads. Threads that need to access a single + * CertPathValidatorSpi instance concurrently should synchronize + * amongst themselves and provide the necessary locking before calling the + * wrapping CertPathValidator object.
    + *
    + * However, implementations of CertPathValidatorSpi may still + * encounter concurrency issues, since multiple threads each + * manipulating a different CertPathValidatorSpi instance need not + * synchronize. + */ + /// + /// CertPathValidatorSpi implementation for X.509 Certificate validation a la RFC + /// 3280. + /// + public class PkixCertPathValidator + { + public virtual PkixCertPathValidatorResult Validate( + PkixCertPath certPath, + PkixParameters paramsPkix) + { + if (paramsPkix.GetTrustAnchors() == null) + { + throw new ArgumentException( + "trustAnchors is null, this is not allowed for certification path validation.", + "parameters"); + } + + // + // 6.1.1 - inputs + // + + // + // (a) + // + IList certs = certPath.Certificates; + int n = certs.Count; + + if (certs.Count == 0) + throw new PkixCertPathValidatorException("Certification path is empty.", null, certPath, 0); + + // + // (b) + // + // DateTime validDate = PkixCertPathValidatorUtilities.GetValidDate(paramsPkix); + + // + // (c) + // + ISet userInitialPolicySet = paramsPkix.GetInitialPolicies(); + + // + // (d) + // + TrustAnchor trust; + try + { + trust = PkixCertPathValidatorUtilities.FindTrustAnchor( + (X509Certificate)certs[certs.Count - 1], + paramsPkix.GetTrustAnchors()); + + if (trust == null) + throw new PkixCertPathValidatorException("Trust anchor for certification path not found.", null, certPath, -1); + + CheckCertificate(trust.TrustedCert); + } + catch (Exception e) + { + throw new PkixCertPathValidatorException(e.Message, e.InnerException, certPath, certs.Count - 1); + } + + // + // (e), (f), (g) are part of the paramsPkix object. + // + IEnumerator certIter; + int index = 0; + int i; + // Certificate for each interation of the validation loop + // Signature information for each iteration of the validation loop + // + // 6.1.2 - setup + // + + // + // (a) + // + IList[] policyNodes = new IList[n + 1]; + for (int j = 0; j < policyNodes.Length; j++) + { + policyNodes[j] = Platform.CreateArrayList(); + } + + ISet policySet = new HashSet(); + + policySet.Add(Rfc3280CertPathUtilities.ANY_POLICY); + + PkixPolicyNode validPolicyTree = new PkixPolicyNode(Platform.CreateArrayList(), 0, policySet, null, new HashSet(), + Rfc3280CertPathUtilities.ANY_POLICY, false); + + policyNodes[0].Add(validPolicyTree); + + // + // (b) and (c) + // + PkixNameConstraintValidator nameConstraintValidator = new PkixNameConstraintValidator(); + + // (d) + // + int explicitPolicy; + ISet acceptablePolicies = new HashSet(); + + if (paramsPkix.IsExplicitPolicyRequired) + { + explicitPolicy = 0; + } + else + { + explicitPolicy = n + 1; + } + + // + // (e) + // + int inhibitAnyPolicy; + + if (paramsPkix.IsAnyPolicyInhibited) + { + inhibitAnyPolicy = 0; + } + else + { + inhibitAnyPolicy = n + 1; + } + + // + // (f) + // + int policyMapping; + + if (paramsPkix.IsPolicyMappingInhibited) + { + policyMapping = 0; + } + else + { + policyMapping = n + 1; + } + + // + // (g), (h), (i), (j) + // + AsymmetricKeyParameter workingPublicKey; + X509Name workingIssuerName; + + X509Certificate sign = trust.TrustedCert; + try + { + if (sign != null) + { + workingIssuerName = sign.SubjectDN; + workingPublicKey = sign.GetPublicKey(); + } + else + { + workingIssuerName = new X509Name(trust.CAName); + workingPublicKey = trust.CAPublicKey; + } + } + catch (ArgumentException ex) + { + throw new PkixCertPathValidatorException("Subject of trust anchor could not be (re)encoded.", ex, certPath, + -1); + } + + AlgorithmIdentifier workingAlgId = null; + try + { + workingAlgId = PkixCertPathValidatorUtilities.GetAlgorithmIdentifier(workingPublicKey); + } + catch (PkixCertPathValidatorException e) + { + throw new PkixCertPathValidatorException( + "Algorithm identifier of public key of trust anchor could not be read.", e, certPath, -1); + } + +// DerObjectIdentifier workingPublicKeyAlgorithm = workingAlgId.Algorithm; +// Asn1Encodable workingPublicKeyParameters = workingAlgId.Parameters; + + // + // (k) + // + int maxPathLength = n; + + // + // 6.1.3 + // + + X509CertStoreSelector certConstraints = paramsPkix.GetTargetCertConstraints(); + if (certConstraints != null && !certConstraints.Match((X509Certificate)certs[0])) + { + throw new PkixCertPathValidatorException( + "Target certificate in certification path does not match targetConstraints.", null, certPath, 0); + } + + // + // initialize CertPathChecker's + // + IList pathCheckers = paramsPkix.GetCertPathCheckers(); + certIter = pathCheckers.GetEnumerator(); + + while (certIter.MoveNext()) + { + ((PkixCertPathChecker)certIter.Current).Init(false); + } + + X509Certificate cert = null; + + for (index = certs.Count - 1; index >= 0; index--) + { + // try + // { + // + // i as defined in the algorithm description + // + i = n - index; + + // + // set certificate to be checked in this round + // sign and workingPublicKey and workingIssuerName are set + // at the end of the for loop and initialized the + // first time from the TrustAnchor + // + cert = (X509Certificate)certs[index]; + + try + { + CheckCertificate(cert); + } + catch (Exception e) + { + throw new PkixCertPathValidatorException(e.Message, e.InnerException, certPath, index); + } + + // + // 6.1.3 + // + + Rfc3280CertPathUtilities.ProcessCertA(certPath, paramsPkix, index, workingPublicKey, + workingIssuerName, sign); + + Rfc3280CertPathUtilities.ProcessCertBC(certPath, index, nameConstraintValidator); + + validPolicyTree = Rfc3280CertPathUtilities.ProcessCertD(certPath, index, + acceptablePolicies, validPolicyTree, policyNodes, inhibitAnyPolicy); + + validPolicyTree = Rfc3280CertPathUtilities.ProcessCertE(certPath, index, validPolicyTree); + + Rfc3280CertPathUtilities.ProcessCertF(certPath, index, validPolicyTree, explicitPolicy); + + // + // 6.1.4 + // + + if (i != n) + { + if (cert != null && cert.Version == 1) + { + // we've found the trust anchor at the top of the path, ignore and keep going + if ((i == 1) && cert.Equals(trust.TrustedCert)) + continue; + + throw new PkixCertPathValidatorException( + "Version 1 certificates can't be used as CA ones.", null, certPath, index); + } + + Rfc3280CertPathUtilities.PrepareNextCertA(certPath, index); + + validPolicyTree = Rfc3280CertPathUtilities.PrepareCertB(certPath, index, policyNodes, + validPolicyTree, policyMapping); + + Rfc3280CertPathUtilities.PrepareNextCertG(certPath, index, nameConstraintValidator); + + // (h) + explicitPolicy = Rfc3280CertPathUtilities.PrepareNextCertH1(certPath, index, explicitPolicy); + policyMapping = Rfc3280CertPathUtilities.PrepareNextCertH2(certPath, index, policyMapping); + inhibitAnyPolicy = Rfc3280CertPathUtilities.PrepareNextCertH3(certPath, index, inhibitAnyPolicy); + + // + // (i) + // + explicitPolicy = Rfc3280CertPathUtilities.PrepareNextCertI1(certPath, index, explicitPolicy); + policyMapping = Rfc3280CertPathUtilities.PrepareNextCertI2(certPath, index, policyMapping); + + // (j) + inhibitAnyPolicy = Rfc3280CertPathUtilities.PrepareNextCertJ(certPath, index, inhibitAnyPolicy); + + // (k) + Rfc3280CertPathUtilities.PrepareNextCertK(certPath, index); + + // (l) + maxPathLength = Rfc3280CertPathUtilities.PrepareNextCertL(certPath, index, maxPathLength); + + // (m) + maxPathLength = Rfc3280CertPathUtilities.PrepareNextCertM(certPath, index, maxPathLength); + + // (n) + Rfc3280CertPathUtilities.PrepareNextCertN(certPath, index); + + ISet criticalExtensions1 = cert.GetCriticalExtensionOids(); + + if (criticalExtensions1 != null) + { + criticalExtensions1 = new HashSet(criticalExtensions1); + + // these extensions are handled by the algorithm + criticalExtensions1.Remove(X509Extensions.KeyUsage.Id); + criticalExtensions1.Remove(X509Extensions.CertificatePolicies.Id); + criticalExtensions1.Remove(X509Extensions.PolicyMappings.Id); + criticalExtensions1.Remove(X509Extensions.InhibitAnyPolicy.Id); + criticalExtensions1.Remove(X509Extensions.IssuingDistributionPoint.Id); + criticalExtensions1.Remove(X509Extensions.DeltaCrlIndicator.Id); + criticalExtensions1.Remove(X509Extensions.PolicyConstraints.Id); + criticalExtensions1.Remove(X509Extensions.BasicConstraints.Id); + criticalExtensions1.Remove(X509Extensions.SubjectAlternativeName.Id); + criticalExtensions1.Remove(X509Extensions.NameConstraints.Id); + } + else + { + criticalExtensions1 = new HashSet(); + } + + // (o) + Rfc3280CertPathUtilities.PrepareNextCertO(certPath, index, criticalExtensions1, pathCheckers); + + // set signing certificate for next round + sign = cert; + + // (c) + workingIssuerName = sign.SubjectDN; + + // (d) + try + { + workingPublicKey = PkixCertPathValidatorUtilities.GetNextWorkingKey(certPath.Certificates, index); + } + catch (PkixCertPathValidatorException e) + { + throw new PkixCertPathValidatorException("Next working key could not be retrieved.", e, certPath, index); + } + + workingAlgId = PkixCertPathValidatorUtilities.GetAlgorithmIdentifier(workingPublicKey); + // (f) +// workingPublicKeyAlgorithm = workingAlgId.Algorithm; + // (e) +// workingPublicKeyParameters = workingAlgId.Parameters; + } + } + + // + // 6.1.5 Wrap-up procedure + // + + explicitPolicy = Rfc3280CertPathUtilities.WrapupCertA(explicitPolicy, cert); + + explicitPolicy = Rfc3280CertPathUtilities.WrapupCertB(certPath, index + 1, explicitPolicy); + + // + // (c) (d) and (e) are already done + // + + // + // (f) + // + ISet criticalExtensions = cert.GetCriticalExtensionOids(); + + if (criticalExtensions != null) + { + criticalExtensions = new HashSet(criticalExtensions); + + // Requires .Id + // these extensions are handled by the algorithm + criticalExtensions.Remove(X509Extensions.KeyUsage.Id); + criticalExtensions.Remove(X509Extensions.CertificatePolicies.Id); + criticalExtensions.Remove(X509Extensions.PolicyMappings.Id); + criticalExtensions.Remove(X509Extensions.InhibitAnyPolicy.Id); + criticalExtensions.Remove(X509Extensions.IssuingDistributionPoint.Id); + criticalExtensions.Remove(X509Extensions.DeltaCrlIndicator.Id); + criticalExtensions.Remove(X509Extensions.PolicyConstraints.Id); + criticalExtensions.Remove(X509Extensions.BasicConstraints.Id); + criticalExtensions.Remove(X509Extensions.SubjectAlternativeName.Id); + criticalExtensions.Remove(X509Extensions.NameConstraints.Id); + criticalExtensions.Remove(X509Extensions.CrlDistributionPoints.Id); + } + else + { + criticalExtensions = new HashSet(); + } + + Rfc3280CertPathUtilities.WrapupCertF(certPath, index + 1, pathCheckers, criticalExtensions); + + PkixPolicyNode intersection = Rfc3280CertPathUtilities.WrapupCertG(certPath, paramsPkix, userInitialPolicySet, + index + 1, policyNodes, validPolicyTree, acceptablePolicies); + + if ((explicitPolicy > 0) || (intersection != null)) + { + return new PkixCertPathValidatorResult(trust, intersection, cert.GetPublicKey()); + } + + throw new PkixCertPathValidatorException("Path processing failed on policy.", null, certPath, index); + } + + internal static void CheckCertificate(X509Certificate cert) + { + try + { + TbsCertificateStructure.GetInstance(cert.CertificateStructure.TbsCertificate); + } + catch (CertificateEncodingException e) + { + throw new Exception("unable to process TBSCertificate", e); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPathValidator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPathValidator.cs.meta new file mode 100644 index 0000000..12bbee3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPathValidator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b80d61e0973c6b94ba60ea0ccac704ea +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPathValidatorException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPathValidatorException.cs new file mode 100644 index 0000000..a477f7d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPathValidatorException.cs @@ -0,0 +1,221 @@ +using System; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Pkix +{ + /** + * An exception indicating one of a variety of problems encountered when + * validating a certification path.
    + *
    + * A CertPathValidatorException provides support for wrapping + * exceptions. The {@link #getCause getCause} method returns the throwable, + * if any, that caused this exception to be thrown.
    + *
    + * A CertPathValidatorException may also include the + * certification path that was being validated when the exception was thrown + * and the index of the certificate in the certification path that caused the + * exception to be thrown. Use the {@link #getCertPath getCertPath} and + * {@link #getIndex getIndex} methods to retrieve this information.
    + *
    + * Concurrent Access
    + *
    + * Unless otherwise specified, the methods defined in this class are not + * thread-safe. Multiple threads that need to access a single + * object concurrently should synchronize amongst themselves and + * provide the necessary locking. Multiple threads each manipulating + * separate objects need not synchronize. + * + * @see CertPathValidator + **/ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE) + [Serializable] +#endif + public class PkixCertPathValidatorException + : GeneralSecurityException + { + private Exception cause; + private PkixCertPath certPath; + private int index = -1; + + public PkixCertPathValidatorException() : base() { } + + /// + /// Creates a PkixCertPathValidatorException with the given detail + /// message. A detail message is a String that describes this + /// particular exception. + /// + /// the detail message + public PkixCertPathValidatorException(string message) : base(message) { } + + /// + /// Creates a PkixCertPathValidatorException with the specified + /// detail message and cause. + /// + /// the detail message + /// the cause (which is saved for later retrieval by the + /// {@link #getCause getCause()} method). (A null + /// value is permitted, and indicates that the cause is + /// nonexistent or unknown.) + public PkixCertPathValidatorException(string message, Exception cause) : base(message) + { + this.cause = cause; + } + + /// + /// Creates a PkixCertPathValidatorException with the specified + /// detail message, cause, certification path, and index. + /// + /// the detail message (or null if none) + /// the cause (or null if none) + /// the certification path that was in the process of being + /// validated when the error was encountered + /// the index of the certificate in the certification path that * + public PkixCertPathValidatorException( + string message, + Exception cause, + PkixCertPath certPath, + int index) + : base(message) + { + if (certPath == null && index != -1) + { + throw new ArgumentNullException( + "certPath = null and index != -1"); + } + if (index < -1 + || (certPath != null && index >= certPath.Certificates.Count)) + { + throw new IndexOutOfRangeException( + " index < -1 or out of bound of certPath.getCertificates()"); + } + + this.cause = cause; + this.certPath = certPath; + this.index = index; + } + + // + // Prints a stack trace to a PrintWriter, including the + // backtrace of the cause, if any. + // + // @param pw + // the PrintWriter to use for output + // + // public void printStackTrace(PrintWriter pw) + // { + // super.printStackTrace(pw); + // if (getCause() != null) + // { + // getCause().printStackTrace(pw); + // } + // } + //} + + + // /** + // * Creates a CertPathValidatorException that wraps the + // * specified throwable. This allows any exception to be converted into a + // * CertPathValidatorException, while retaining information + // * about the wrapped exception, which may be useful for debugging. The + // * detail message is set to (cause==null ? null : cause.toString() + // * ) + // * (which typically contains the class and detail message of cause). + // * + // * @param cause + // * the cause (which is saved for later retrieval by the + // * {@link #getCause getCause()} method). (A null + // * value is permitted, and indicates that the cause is + // * nonexistent or unknown.) + // */ + // public PkixCertPathValidatorException(Throwable cause) + // { + // this.cause = cause; + // } + // + + /// + /// Returns the detail message for this CertPathValidatorException. + /// + /// the detail message, or null if neither the message nor cause were specified + public override string Message + { + get + { + string message = base.Message; + + if (message != null) + { + return message; + } + + if (cause != null) + { + return cause.Message; + } + + return null; + } + } + + /** + * Returns the certification path that was being validated when the + * exception was thrown. + * + * @return the CertPath that was being validated when the + * exception was thrown (or null if not specified) + */ + public PkixCertPath CertPath + { + get { return certPath; } + } + + /** + * Returns the index of the certificate in the certification path that + * caused the exception to be thrown. Note that the list of certificates in + * a CertPath is zero based. If no index has been set, -1 is + * returned. + * + * @return the index that has been set, or -1 if none has been set + */ + public int Index + { + get { return index; } + } + +// /** +// * Returns the cause of this CertPathValidatorException or +// * null if the cause is nonexistent or unknown. +// * +// * @return the cause of this throwable or null if the cause +// * is nonexistent or unknown. +// */ +// public Throwable getCause() +// { +// return cause; +// } +// +// /** +// * Returns a string describing this exception, including a description of +// * the internal (wrapped) cause if there is one. +// * +// * @return a string representation of this +// * CertPathValidatorException +// */ +// public String toString() +// { +// StringBuffer sb = new StringBuffer(); +// String s = getMessage(); +// if (s != null) +// { +// sb.append(s); +// } +// if (getIndex() >= 0) +// { +// sb.append("index in certpath: ").append(getIndex()).append('\n'); +// sb.append(getCertPath()); +// } +// return sb.toString(); +// } + + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPathValidatorException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPathValidatorException.cs.meta new file mode 100644 index 0000000..841973e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPathValidatorException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1afa899b44b27f840947741c5ad4a7fa +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPathValidatorResult.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPathValidatorResult.cs new file mode 100644 index 0000000..c7d81c7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPathValidatorResult.cs @@ -0,0 +1,69 @@ +using System; +using System.Text; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Pkix +{ + /// + /// Summary description for PkixCertPathValidatorResult. + /// + public class PkixCertPathValidatorResult + //: ICertPathValidatorResult + { + private TrustAnchor trustAnchor; + private PkixPolicyNode policyTree; + private AsymmetricKeyParameter subjectPublicKey; + + public PkixPolicyNode PolicyTree + { + get { return this.policyTree; } + } + + public TrustAnchor TrustAnchor + { + get { return this.trustAnchor; } + } + + public AsymmetricKeyParameter SubjectPublicKey + { + get { return this.subjectPublicKey; } + } + + public PkixCertPathValidatorResult( + TrustAnchor trustAnchor, + PkixPolicyNode policyTree, + AsymmetricKeyParameter subjectPublicKey) + { + if (subjectPublicKey == null) + { + throw new NullReferenceException("subjectPublicKey must be non-null"); + } + if (trustAnchor == null) + { + throw new NullReferenceException("trustAnchor must be non-null"); + } + + this.trustAnchor = trustAnchor; + this.policyTree = policyTree; + this.subjectPublicKey = subjectPublicKey; + } + + public object Clone() + { + return new PkixCertPathValidatorResult(this.TrustAnchor, this.PolicyTree, this.SubjectPublicKey); + } + + public override String ToString() + { + StringBuilder sB = new StringBuilder(); + sB.Append("PKIXCertPathValidatorResult: [ \n"); + sB.Append(" Trust Anchor: ").Append(this.TrustAnchor).Append('\n'); + sB.Append(" Policy Tree: ").Append(this.PolicyTree).Append('\n'); + sB.Append(" Subject Public Key: ").Append(this.SubjectPublicKey).Append("\n]"); + return sB.ToString(); + } + + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPathValidatorResult.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPathValidatorResult.cs.meta new file mode 100644 index 0000000..c51d147 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPathValidatorResult.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8259fcf0fe572574e829c2428f84b18b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPathValidatorUtilities.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPathValidatorUtilities.cs new file mode 100644 index 0000000..57dfcd6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPathValidatorUtilities.cs @@ -0,0 +1,1212 @@ +using System; +using System.Collections; +using System.IO; +using System.Text; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.IsisMtt; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; +using Org.BouncyCastle.Utilities.Date; +using Org.BouncyCastle.X509; +using Org.BouncyCastle.X509.Extension; +using Org.BouncyCastle.X509.Store; + +namespace Org.BouncyCastle.Pkix +{ + /// + /// Summary description for PkixCertPathValidatorUtilities. + /// + public class PkixCertPathValidatorUtilities + { + private static readonly PkixCrlUtilities CrlUtilities = new PkixCrlUtilities(); + + internal static readonly string ANY_POLICY = "2.5.29.32.0"; + + internal static readonly string CRL_NUMBER = X509Extensions.CrlNumber.Id; + + /// + /// key usage bits + /// + internal static readonly int KEY_CERT_SIGN = 5; + internal static readonly int CRL_SIGN = 6; + + internal static readonly string[] crlReasons = new string[] + { + "unspecified", + "keyCompromise", + "cACompromise", + "affiliationChanged", + "superseded", + "cessationOfOperation", + "certificateHold", + "unknown", + "removeFromCRL", + "privilegeWithdrawn", + "aACompromise" + }; + + /// + /// Search the given Set of TrustAnchor's for one that is the + /// issuer of the given X509 certificate. + /// + /// the X509 certificate + /// a Set of TrustAnchor's + /// the TrustAnchor object if found or + /// null if not. + /// + /// @exception + internal static TrustAnchor FindTrustAnchor( + X509Certificate cert, + ISet trustAnchors) + { + IEnumerator iter = trustAnchors.GetEnumerator(); + TrustAnchor trust = null; + AsymmetricKeyParameter trustPublicKey = null; + Exception invalidKeyEx = null; + + X509CertStoreSelector certSelectX509 = new X509CertStoreSelector(); + + try + { + certSelectX509.Subject = GetIssuerPrincipal(cert); + } + catch (IOException ex) + { + throw new Exception("Cannot set subject search criteria for trust anchor.", ex); + } + + while (iter.MoveNext() && trust == null) + { + trust = (TrustAnchor) iter.Current; + if (trust.TrustedCert != null) + { + if (certSelectX509.Match(trust.TrustedCert)) + { + trustPublicKey = trust.TrustedCert.GetPublicKey(); + } + else + { + trust = null; + } + } + else if (trust.CAName != null && trust.CAPublicKey != null) + { + try + { + X509Name certIssuer = GetIssuerPrincipal(cert); + X509Name caName = new X509Name(trust.CAName); + + if (certIssuer.Equivalent(caName, true)) + { + trustPublicKey = trust.CAPublicKey; + } + else + { + trust = null; + } + } + catch (InvalidParameterException) + { + trust = null; + } + } + else + { + trust = null; + } + + if (trustPublicKey != null) + { + try + { + cert.Verify(trustPublicKey); + } + catch (Exception ex) + { + invalidKeyEx = ex; + trust = null; + } + } + } + + if (trust == null && invalidKeyEx != null) + { + throw new Exception("TrustAnchor found but certificate validation failed.", invalidKeyEx); + } + + return trust; + } + + internal static bool IsIssuerTrustAnchor( + X509Certificate cert, + ISet trustAnchors) + { + try + { + return FindTrustAnchor(cert, trustAnchors) != null; + } + catch (Exception) + { + return false; + } + } + + internal static void AddAdditionalStoresFromAltNames( + X509Certificate cert, + PkixParameters pkixParams) + { + // if in the IssuerAltName extension an URI + // is given, add an additinal X.509 store + if (cert.GetIssuerAlternativeNames() != null) + { + IEnumerator it = cert.GetIssuerAlternativeNames().GetEnumerator(); + while (it.MoveNext()) + { + // look for URI + IList list = (IList)it.Current; + //if (list[0].Equals(new Integer(GeneralName.UniformResourceIdentifier))) + if (list[0].Equals(GeneralName.UniformResourceIdentifier)) + { + // found + string temp = (string)list[1]; + PkixCertPathValidatorUtilities.AddAdditionalStoreFromLocation(temp, pkixParams); + } + } + } + } + + internal static DateTime GetValidDate(PkixParameters paramsPKIX) + { + DateTimeObject validDate = paramsPKIX.Date; + + if (validDate == null) + return DateTime.UtcNow; + + return validDate.Value; + } + + /// + /// Returns the issuer of an attribute certificate or certificate. + /// + /// The attribute certificate or certificate. + /// The issuer as X500Principal. + internal static X509Name GetIssuerPrincipal( + object cert) + { + if (cert is X509Certificate) + { + return ((X509Certificate)cert).IssuerDN; + } + else + { + return ((IX509AttributeCertificate)cert).Issuer.GetPrincipals()[0]; + } + } + + internal static bool IsSelfIssued( + X509Certificate cert) + { + return cert.SubjectDN.Equivalent(cert.IssuerDN, true); + } + + internal static AlgorithmIdentifier GetAlgorithmIdentifier( + AsymmetricKeyParameter key) + { + try + { + SubjectPublicKeyInfo info = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(key); + + return info.AlgorithmID; + } + catch (Exception e) + { + throw new PkixCertPathValidatorException("Subject public key cannot be decoded.", e); + } + } + + internal static bool IsAnyPolicy( + ISet policySet) + { + return policySet == null || policySet.Contains(ANY_POLICY) || policySet.Count == 0; + } + + internal static void AddAdditionalStoreFromLocation( + string location, + PkixParameters pkixParams) + { + if (pkixParams.IsAdditionalLocationsEnabled) + { + try + { + if (Platform.StartsWith(location, "ldap://")) + { + // ldap://directory.d-trust.net/CN=D-TRUST + // Qualified CA 2003 1:PN,O=D-Trust GmbH,C=DE + // skip "ldap://" + location = location.Substring(7); + // after first / baseDN starts + string url;//, baseDN; + int slashPos = location.IndexOf('/'); + if (slashPos != -1) + { + url = "ldap://" + location.Substring(0, slashPos); +// baseDN = location.Substring(slashPos); + } + else + { + url = "ldap://" + location; +// baseDN = nsull; + } + + throw Platform.CreateNotImplementedException("LDAP cert/CRL stores"); + + // use all purpose parameters + //X509LDAPCertStoreParameters ldapParams = new X509LDAPCertStoreParameters.Builder( + // url, baseDN).build(); + //pkixParams.AddAdditionalStore(X509Store.getInstance( + // "CERTIFICATE/LDAP", ldapParams)); + //pkixParams.AddAdditionalStore(X509Store.getInstance( + // "CRL/LDAP", ldapParams)); + //pkixParams.AddAdditionalStore(X509Store.getInstance( + // "ATTRIBUTECERTIFICATE/LDAP", ldapParams)); + //pkixParams.AddAdditionalStore(X509Store.getInstance( + // "CERTIFICATEPAIR/LDAP", ldapParams)); + } + } + catch (Exception) + { + // cannot happen + throw new Exception("Exception adding X.509 stores."); + } + } + } + + private static BigInteger GetSerialNumber( + object cert) + { + if (cert is X509Certificate) + { + return ((X509Certificate)cert).SerialNumber; + } + else + { + return ((X509V2AttributeCertificate)cert).SerialNumber; + } + } + + // + // policy checking + // + + internal static ISet GetQualifierSet(Asn1Sequence qualifiers) + { + ISet pq = new HashSet(); + + if (qualifiers == null) + { + return pq; + } + + foreach (Asn1Encodable ae in qualifiers) + { + try + { +// pq.Add(PolicyQualifierInfo.GetInstance(Asn1Object.FromByteArray(ae.GetEncoded()))); + pq.Add(PolicyQualifierInfo.GetInstance(ae.ToAsn1Object())); + } + catch (IOException ex) + { + throw new PkixCertPathValidatorException("Policy qualifier info cannot be decoded.", ex); + } + } + + return pq; + } + + internal static PkixPolicyNode RemovePolicyNode( + PkixPolicyNode validPolicyTree, + IList[] policyNodes, + PkixPolicyNode _node) + { + PkixPolicyNode _parent = (PkixPolicyNode)_node.Parent; + + if (validPolicyTree == null) + { + return null; + } + + if (_parent == null) + { + for (int j = 0; j < policyNodes.Length; j++) + { + policyNodes[j] = Platform.CreateArrayList(); + } + + return null; + } + else + { + _parent.RemoveChild(_node); + RemovePolicyNodeRecurse(policyNodes, _node); + + return validPolicyTree; + } + } + + private static void RemovePolicyNodeRecurse(IList[] policyNodes, PkixPolicyNode _node) + { + policyNodes[_node.Depth].Remove(_node); + + if (_node.HasChildren) + { + foreach (PkixPolicyNode _child in _node.Children) + { + RemovePolicyNodeRecurse(policyNodes, _child); + } + } + } + + internal static void PrepareNextCertB1( + int i, + IList[] policyNodes, + string id_p, + IDictionary m_idp, + X509Certificate cert) + { + bool idp_found = false; + IEnumerator nodes_i = policyNodes[i].GetEnumerator(); + while (nodes_i.MoveNext()) + { + PkixPolicyNode node = (PkixPolicyNode)nodes_i.Current; + if (node.ValidPolicy.Equals(id_p)) + { + idp_found = true; + node.ExpectedPolicies = (ISet)m_idp[id_p]; + break; + } + } + + if (!idp_found) + { + nodes_i = policyNodes[i].GetEnumerator(); + while (nodes_i.MoveNext()) + { + PkixPolicyNode node = (PkixPolicyNode)nodes_i.Current; + if (ANY_POLICY.Equals(node.ValidPolicy)) + { + ISet pq = null; + Asn1Sequence policies = null; + try + { + policies = DerSequence.GetInstance(GetExtensionValue(cert, X509Extensions.CertificatePolicies)); + } + catch (Exception e) + { + throw new Exception("Certificate policies cannot be decoded.", e); + } + + IEnumerator enm = policies.GetEnumerator(); + while (enm.MoveNext()) + { + PolicyInformation pinfo = null; + + try + { + pinfo = PolicyInformation.GetInstance(enm.Current); + } + catch (Exception ex) + { + throw new Exception("Policy information cannot be decoded.", ex); + } + + if (ANY_POLICY.Equals(pinfo.PolicyIdentifier.Id)) + { + try + { + pq = GetQualifierSet(pinfo.PolicyQualifiers); + } + catch (PkixCertPathValidatorException ex) + { + throw new PkixCertPathValidatorException( + "Policy qualifier info set could not be built.", ex); + } + break; + } + } + bool ci = false; + ISet critExtOids = cert.GetCriticalExtensionOids(); + if (critExtOids != null) + { + ci = critExtOids.Contains(X509Extensions.CertificatePolicies.Id); + } + + PkixPolicyNode p_node = (PkixPolicyNode)node.Parent; + if (ANY_POLICY.Equals(p_node.ValidPolicy)) + { + PkixPolicyNode c_node = new PkixPolicyNode( + Platform.CreateArrayList(), i, + (ISet)m_idp[id_p], + p_node, pq, id_p, ci); + p_node.AddChild(c_node); + policyNodes[i].Add(c_node); + } + break; + } + } + } + } + + internal static PkixPolicyNode PrepareNextCertB2( + int i, + IList[] policyNodes, + string id_p, + PkixPolicyNode validPolicyTree) + { + int pos = 0; + + // Copy to avoid RemoveAt calls interfering with enumeration + foreach (PkixPolicyNode node in Platform.CreateArrayList(policyNodes[i])) + { + if (node.ValidPolicy.Equals(id_p)) + { + PkixPolicyNode p_node = (PkixPolicyNode)node.Parent; + p_node.RemoveChild(node); + + // Removal of element at current iterator position not supported in C# + //nodes_i.remove(); + policyNodes[i].RemoveAt(pos); + + for (int k = (i - 1); k >= 0; k--) + { + IList nodes = policyNodes[k]; + for (int l = 0; l < nodes.Count; l++) + { + PkixPolicyNode node2 = (PkixPolicyNode)nodes[l]; + if (!node2.HasChildren) + { + validPolicyTree = RemovePolicyNode(validPolicyTree, policyNodes, node2); + if (validPolicyTree == null) + break; + } + } + } + } + else + { + ++pos; + } + } + return validPolicyTree; + } + + internal static void GetCertStatus( + DateTime validDate, + X509Crl crl, + Object cert, + CertStatus certStatus) + { + X509Crl bcCRL = null; + + try + { + bcCRL = new X509Crl(CertificateList.GetInstance((Asn1Sequence)Asn1Sequence.FromByteArray(crl.GetEncoded()))); + } + catch (Exception exception) + { + throw new Exception("Bouncy Castle X509Crl could not be created.", exception); + } + + X509CrlEntry crl_entry = (X509CrlEntry)bcCRL.GetRevokedCertificate(GetSerialNumber(cert)); + + if (crl_entry == null) + return; + + X509Name issuer = GetIssuerPrincipal(cert); + + if (!issuer.Equivalent(crl_entry.GetCertificateIssuer(), true) + && !issuer.Equivalent(crl.IssuerDN, true)) + { + return; + } + + int reasonCodeValue = CrlReason.Unspecified; + + if (crl_entry.HasExtensions) + { + try + { + Asn1Object extValue = GetExtensionValue(crl_entry, X509Extensions.ReasonCode); + DerEnumerated reasonCode = DerEnumerated.GetInstance(extValue); + if (null != reasonCode) + { + reasonCodeValue = reasonCode.IntValueExact; + } + } + catch (Exception e) + { + throw new Exception("Reason code CRL entry extension could not be decoded.", e); + } + } + + DateTime revocationDate = crl_entry.RevocationDate; + if (validDate.Ticks < revocationDate.Ticks) + { + switch (reasonCodeValue) + { + case CrlReason.Unspecified: + case CrlReason.KeyCompromise: + case CrlReason.CACompromise: + case CrlReason.AACompromise: + break; + default: + return; + } + } + + // (i) or (j) + certStatus.Status = reasonCodeValue; + certStatus.RevocationDate = new DateTimeObject(revocationDate); + } + + /** + * Return the next working key inheriting DSA parameters if necessary. + *

    + * This methods inherits DSA parameters from the indexed certificate or + * previous certificates in the certificate chain to the returned + * PublicKey. The list is searched upwards, meaning the end + * certificate is at position 0 and previous certificates are following. + *

    + *

    + * If the indexed certificate does not contain a DSA key this method simply + * returns the public key. If the DSA key already contains DSA parameters + * the key is also only returned. + *

    + * + * @param certs The certification path. + * @param index The index of the certificate which contains the public key + * which should be extended with DSA parameters. + * @return The public key of the certificate in list position + * index extended with DSA parameters if applicable. + * @throws Exception if DSA parameters cannot be inherited. + */ + internal static AsymmetricKeyParameter GetNextWorkingKey( + IList certs, + int index) + { + //Only X509Certificate + X509Certificate cert = (X509Certificate)certs[index]; + + AsymmetricKeyParameter pubKey = cert.GetPublicKey(); + + if (!(pubKey is DsaPublicKeyParameters)) + return pubKey; + + DsaPublicKeyParameters dsaPubKey = (DsaPublicKeyParameters)pubKey; + + if (dsaPubKey.Parameters != null) + return dsaPubKey; + + for (int i = index + 1; i < certs.Count; i++) + { + X509Certificate parentCert = (X509Certificate)certs[i]; + pubKey = parentCert.GetPublicKey(); + + if (!(pubKey is DsaPublicKeyParameters)) + { + throw new PkixCertPathValidatorException( + "DSA parameters cannot be inherited from previous certificate."); + } + + DsaPublicKeyParameters prevDSAPubKey = (DsaPublicKeyParameters)pubKey; + + if (prevDSAPubKey.Parameters == null) + continue; + + DsaParameters dsaParams = prevDSAPubKey.Parameters; + + try + { + return new DsaPublicKeyParameters(dsaPubKey.Y, dsaParams); + } + catch (Exception exception) + { + throw new Exception(exception.Message); + } + } + + throw new PkixCertPathValidatorException("DSA parameters cannot be inherited from previous certificate."); + } + + internal static DateTime GetValidCertDateFromValidityModel( + PkixParameters paramsPkix, + PkixCertPath certPath, + int index) + { + if (paramsPkix.ValidityModel != PkixParameters.ChainValidityModel) + { + return GetValidDate(paramsPkix); + } + + // if end cert use given signing/encryption/... time + if (index <= 0) + { + return PkixCertPathValidatorUtilities.GetValidDate(paramsPkix); + // else use time when previous cert was created + } + + if (index - 1 == 0) + { + DerGeneralizedTime dateOfCertgen = null; + try + { + X509Certificate cert = (X509Certificate)certPath.Certificates[index - 1]; + Asn1OctetString extVal = cert.GetExtensionValue( + IsisMttObjectIdentifiers.IdIsisMttATDateOfCertGen); + dateOfCertgen = DerGeneralizedTime.GetInstance(extVal); + } + catch (ArgumentException) + { + throw new Exception( + "Date of cert gen extension could not be read."); + } + if (dateOfCertgen != null) + { + try + { + return dateOfCertgen.ToDateTime(); + } + catch (ArgumentException e) + { + throw new Exception( + "Date from date of cert gen extension could not be parsed.", + e); + } + } + } + + return ((X509Certificate)certPath.Certificates[index - 1]).NotBefore; + } + + /// + /// Return a Collection of all certificates or attribute certificates found + /// in the X509Store's that are matching the certSelect criteriums. + /// + /// a {@link Selector} object that will be used to select + /// the certificates + /// a List containing only X509Store objects. These + /// are used to search for certificates. + /// a Collection of all found or + /// objects. + /// May be empty but never null. + /// + internal static ICollection FindCertificates( + X509CertStoreSelector certSelect, + IList certStores) + { + ISet certs = new HashSet(); + + foreach (IX509Store certStore in certStores) + { + try + { +// certs.AddAll(certStore.GetMatches(certSelect)); + foreach (X509Certificate c in certStore.GetMatches(certSelect)) + { + certs.Add(c); + } + } + catch (Exception e) + { + throw new Exception("Problem while picking certificates from X.509 store.", e); + } + } + + return certs; + } + + /** + * Add the CRL issuers from the cRLIssuer field of the distribution point or + * from the certificate if not given to the issuer criterion of the + * selector. + *

    + * The issuerPrincipals are a collection with a single + * X500Principal for X509Certificates. For + * {@link X509AttributeCertificate}s the issuer may contain more than one + * X500Principal. + *

    + * + * @param dp The distribution point. + * @param issuerPrincipals The issuers of the certificate or attribute + * certificate which contains the distribution point. + * @param selector The CRL selector. + * @param pkixParams The PKIX parameters containing the cert stores. + * @throws Exception if an exception occurs while processing. + * @throws ClassCastException if issuerPrincipals does not + * contain only X500Principals. + */ + internal static void GetCrlIssuersFromDistributionPoint( + DistributionPoint dp, + ICollection issuerPrincipals, + X509CrlStoreSelector selector, + PkixParameters pkixParams) + { + IList issuers = Platform.CreateArrayList(); + // indirect CRL + if (dp.CrlIssuer != null) + { + GeneralName[] genNames = dp.CrlIssuer.GetNames(); + // look for a DN + for (int j = 0; j < genNames.Length; j++) + { + if (genNames[j].TagNo == GeneralName.DirectoryName) + { + try + { + issuers.Add(X509Name.GetInstance(genNames[j].Name.ToAsn1Object())); + } + catch (IOException e) + { + throw new Exception( + "CRL issuer information from distribution point cannot be decoded.", + e); + } + } + } + } + else + { + /* + * certificate issuer is CRL issuer, distributionPoint field MUST be + * present. + */ + if (dp.DistributionPointName == null) + { + throw new Exception( + "CRL issuer is omitted from distribution point but no distributionPoint field present."); + } + + // add and check issuer principals + for (IEnumerator it = issuerPrincipals.GetEnumerator(); it.MoveNext(); ) + { + issuers.Add((X509Name)it.Current); + } + } + // TODO: is not found although this should correctly add the rel name. selector of Sun is buggy here or PKI test case is invalid + // distributionPoint + // if (dp.getDistributionPoint() != null) + // { + // // look for nameRelativeToCRLIssuer + // if (dp.getDistributionPoint().getType() == DistributionPointName.NAME_RELATIVE_TO_CRL_ISSUER) + // { + // // append fragment to issuer, only one + // // issuer can be there, if this is given + // if (issuers.size() != 1) + // { + // throw new AnnotatedException( + // "nameRelativeToCRLIssuer field is given but more than one CRL issuer is given."); + // } + // DEREncodable relName = dp.getDistributionPoint().getName(); + // Iterator it = issuers.iterator(); + // List issuersTemp = new ArrayList(issuers.size()); + // while (it.hasNext()) + // { + // Enumeration e = null; + // try + // { + // e = ASN1Sequence.getInstance( + // new ASN1InputStream(((X500Principal) it.next()) + // .getEncoded()).readObject()).getObjects(); + // } + // catch (IOException ex) + // { + // throw new AnnotatedException( + // "Cannot decode CRL issuer information.", ex); + // } + // ASN1EncodableVector v = new ASN1EncodableVector(); + // while (e.hasMoreElements()) + // { + // v.add((DEREncodable) e.nextElement()); + // } + // v.add(relName); + // issuersTemp.add(new X500Principal(new DERSequence(v) + // .getDEREncoded())); + // } + // issuers.clear(); + // issuers.addAll(issuersTemp); + // } + // } + + selector.Issuers = issuers; + } + + /** + * Fetches complete CRLs according to RFC 3280. + * + * @param dp The distribution point for which the complete CRL + * @param cert The X509Certificate or + * {@link org.bouncycastle.x509.X509AttributeCertificate} for + * which the CRL should be searched. + * @param currentDate The date for which the delta CRLs must be valid. + * @param paramsPKIX The extended PKIX parameters. + * @return A Set of X509CRLs with complete + * CRLs. + * @throws Exception if an exception occurs while picking the CRLs + * or no CRLs are found. + */ + internal static ISet GetCompleteCrls( + DistributionPoint dp, + object cert, + DateTime currentDate, + PkixParameters paramsPKIX) + { + X509CrlStoreSelector crlselect = new X509CrlStoreSelector(); + try + { + ISet issuers = new HashSet(); + if (cert is X509V2AttributeCertificate) + { + issuers.Add(((X509V2AttributeCertificate)cert) + .Issuer.GetPrincipals()[0]); + } + else + { + issuers.Add(GetIssuerPrincipal(cert)); + } + PkixCertPathValidatorUtilities.GetCrlIssuersFromDistributionPoint(dp, issuers, crlselect, paramsPKIX); + } + catch (Exception e) + { + throw new Exception("Could not get issuer information from distribution point.", e); + } + + if (cert is X509Certificate) + { + crlselect.CertificateChecking = (X509Certificate)cert; + } + else if (cert is X509V2AttributeCertificate) + { + crlselect.AttrCertChecking = (IX509AttributeCertificate)cert; + } + + crlselect.CompleteCrlEnabled = true; + ISet crls = CrlUtilities.FindCrls(crlselect, paramsPKIX, currentDate); + + if (crls.IsEmpty) + { + if (cert is IX509AttributeCertificate) + { + IX509AttributeCertificate aCert = (IX509AttributeCertificate)cert; + + throw new Exception("No CRLs found for issuer \"" + aCert.Issuer.GetPrincipals()[0] + "\""); + } + else + { + X509Certificate xCert = (X509Certificate)cert; + + throw new Exception("No CRLs found for issuer \"" + xCert.IssuerDN + "\""); + } + } + + return crls; + } + + /** + * Fetches delta CRLs according to RFC 3280 section 5.2.4. + * + * @param currentDate The date for which the delta CRLs must be valid. + * @param paramsPKIX The extended PKIX parameters. + * @param completeCRL The complete CRL the delta CRL is for. + * @return A Set of X509CRLs with delta CRLs. + * @throws Exception if an exception occurs while picking the delta + * CRLs. + */ + internal static ISet GetDeltaCrls( + DateTime currentDate, + PkixParameters paramsPKIX, + X509Crl completeCRL) + { + X509CrlStoreSelector deltaSelect = new X509CrlStoreSelector(); + + // 5.2.4 (a) + try + { + IList deltaSelectIssuer = Platform.CreateArrayList(); + deltaSelectIssuer.Add(completeCRL.IssuerDN); + deltaSelect.Issuers = deltaSelectIssuer; + } + catch (IOException e) + { + throw new Exception("Cannot extract issuer from CRL.", e); + } + + BigInteger completeCRLNumber = null; + try + { + Asn1Object asn1Object = GetExtensionValue(completeCRL, X509Extensions.CrlNumber); + if (asn1Object != null) + { + completeCRLNumber = CrlNumber.GetInstance(asn1Object).PositiveValue; + } + } + catch (Exception e) + { + throw new Exception( + "CRL number extension could not be extracted from CRL.", e); + } + + // 5.2.4 (b) + byte[] idp = null; + + try + { + Asn1Object obj = GetExtensionValue(completeCRL, X509Extensions.IssuingDistributionPoint); + if (obj != null) + { + idp = obj.GetDerEncoded(); + } + } + catch (Exception e) + { + throw new Exception( + "Issuing distribution point extension value could not be read.", + e); + } + + // 5.2.4 (d) + + deltaSelect.MinCrlNumber = (completeCRLNumber == null) + ? null + : completeCRLNumber.Add(BigInteger.One); + + deltaSelect.IssuingDistributionPoint = idp; + deltaSelect.IssuingDistributionPointEnabled = true; + + // 5.2.4 (c) + deltaSelect.MaxBaseCrlNumber = completeCRLNumber; + + // find delta CRLs + ISet temp = CrlUtilities.FindCrls(deltaSelect, paramsPKIX, currentDate); + + ISet result = new HashSet(); + + foreach (X509Crl crl in temp) + { + if (isDeltaCrl(crl)) + { + result.Add(crl); + } + } + + return result; + } + + private static bool isDeltaCrl( + X509Crl crl) + { + ISet critical = crl.GetCriticalExtensionOids(); + + return critical.Contains(X509Extensions.DeltaCrlIndicator.Id); + } + + internal static ICollection FindCertificates( + X509AttrCertStoreSelector certSelect, + IList certStores) + { + ISet certs = new HashSet(); + + foreach (IX509Store certStore in certStores) + { + try + { +// certs.AddAll(certStore.GetMatches(certSelect)); + foreach (X509V2AttributeCertificate ac in certStore.GetMatches(certSelect)) + { + certs.Add(ac); + } + } + catch (Exception e) + { + throw new Exception( + "Problem while picking certificates from X.509 store.", e); + } + } + + return certs; + } + + internal static void AddAdditionalStoresFromCrlDistributionPoint( + CrlDistPoint crldp, + PkixParameters pkixParams) + { + if (crldp != null) + { + DistributionPoint[] dps = null; + try + { + dps = crldp.GetDistributionPoints(); + } + catch (Exception e) + { + throw new Exception( + "Distribution points could not be read.", e); + } + for (int i = 0; i < dps.Length; i++) + { + DistributionPointName dpn = dps[i].DistributionPointName; + // look for URIs in fullName + if (dpn != null) + { + if (dpn.PointType == DistributionPointName.FullName) + { + GeneralName[] genNames = GeneralNames.GetInstance( + dpn.Name).GetNames(); + // look for an URI + for (int j = 0; j < genNames.Length; j++) + { + if (genNames[j].TagNo == GeneralName.UniformResourceIdentifier) + { + string location = DerIA5String.GetInstance( + genNames[j].Name).GetString(); + PkixCertPathValidatorUtilities.AddAdditionalStoreFromLocation( + location, pkixParams); + } + } + } + } + } + } + } + + internal static bool ProcessCertD1i( + int index, + IList[] policyNodes, + DerObjectIdentifier pOid, + ISet pq) + { + IList policyNodeVec = policyNodes[index - 1]; + + for (int j = 0; j < policyNodeVec.Count; j++) + { + PkixPolicyNode node = (PkixPolicyNode)policyNodeVec[j]; + ISet expectedPolicies = node.ExpectedPolicies; + + if (expectedPolicies.Contains(pOid.Id)) + { + ISet childExpectedPolicies = new HashSet(); + childExpectedPolicies.Add(pOid.Id); + + PkixPolicyNode child = new PkixPolicyNode(Platform.CreateArrayList(), + index, + childExpectedPolicies, + node, + pq, + pOid.Id, + false); + node.AddChild(child); + policyNodes[index].Add(child); + + return true; + } + } + + return false; + } + + internal static void ProcessCertD1ii( + int index, + IList[] policyNodes, + DerObjectIdentifier _poid, + ISet _pq) + { + IList policyNodeVec = policyNodes[index - 1]; + + for (int j = 0; j < policyNodeVec.Count; j++) + { + PkixPolicyNode _node = (PkixPolicyNode)policyNodeVec[j]; + + if (ANY_POLICY.Equals(_node.ValidPolicy)) + { + ISet _childExpectedPolicies = new HashSet(); + _childExpectedPolicies.Add(_poid.Id); + + PkixPolicyNode _child = new PkixPolicyNode(Platform.CreateArrayList(), + index, + _childExpectedPolicies, + _node, + _pq, + _poid.Id, + false); + _node.AddChild(_child); + policyNodes[index].Add(_child); + return; + } + } + } + + /** + * Find the issuer certificates of a given certificate. + * + * @param cert + * The certificate for which an issuer should be found. + * @param pkixParams + * @return A Collection object containing the issuer + * X509Certificates. Never null. + * + * @exception Exception + * if an error occurs. + */ + internal static ICollection FindIssuerCerts( + X509Certificate cert, + PkixBuilderParameters pkixParams) + { + X509CertStoreSelector certSelect = new X509CertStoreSelector(); + ISet certs = new HashSet(); + try + { + certSelect.Subject = cert.IssuerDN; + } + catch (IOException ex) + { + throw new Exception( + "Subject criteria for certificate selector to find issuer certificate could not be set.", ex); + } + + try + { + certs.AddAll(PkixCertPathValidatorUtilities.FindCertificates(certSelect, pkixParams.GetStores())); + certs.AddAll(PkixCertPathValidatorUtilities.FindCertificates(certSelect, pkixParams.GetAdditionalStores())); + } + catch (Exception e) + { + throw new Exception("Issuer certificate cannot be searched.", e); + } + + return certs; + } + + /// + /// Extract the value of the given extension, if it exists. + /// + /// The extension object. + /// The object identifier to obtain. + /// Asn1Object + /// if the extension cannot be read. + internal static Asn1Object GetExtensionValue( + IX509Extension ext, + DerObjectIdentifier oid) + { + Asn1OctetString bytes = ext.GetExtensionValue(oid); + + if (bytes == null) + return null; + + return X509ExtensionUtilities.FromExtensionValue(bytes); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPathValidatorUtilities.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPathValidatorUtilities.cs.meta new file mode 100644 index 0000000..f19715c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCertPathValidatorUtilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 39c73b2d5ceaf714fbe9e8e826d7b780 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCrlUtilities.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCrlUtilities.cs new file mode 100644 index 0000000..06a7caa --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCrlUtilities.cs @@ -0,0 +1,110 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Utilities.Collections; +using Org.BouncyCastle.Utilities.Date; +using Org.BouncyCastle.X509; +using Org.BouncyCastle.X509.Store; + +namespace Org.BouncyCastle.Pkix +{ + public class PkixCrlUtilities + { + public virtual ISet FindCrls(X509CrlStoreSelector crlselect, PkixParameters paramsPkix, DateTime currentDate) + { + ISet initialSet = new HashSet(); + + // get complete CRL(s) + try + { + initialSet.AddAll(FindCrls(crlselect, paramsPkix.GetAdditionalStores())); + initialSet.AddAll(FindCrls(crlselect, paramsPkix.GetStores())); + } + catch (Exception e) + { + throw new Exception("Exception obtaining complete CRLs.", e); + } + + ISet finalSet = new HashSet(); + DateTime validityDate = currentDate; + + if (paramsPkix.Date != null) + { + validityDate = paramsPkix.Date.Value; + } + + // based on RFC 5280 6.3.3 + foreach (X509Crl crl in initialSet) + { + DateTimeObject nextUpdate = crl.NextUpdate; + + if (null == nextUpdate || nextUpdate.Value.CompareTo(validityDate) > 0) + { + X509Certificate cert = crlselect.CertificateChecking; + + if (null == cert || crl.ThisUpdate.CompareTo(cert.NotAfter) < 0) + { + finalSet.Add(crl); + } + } + } + + return finalSet; + } + + public virtual ISet FindCrls(X509CrlStoreSelector crlselect, PkixParameters paramsPkix) + { + ISet completeSet = new HashSet(); + + // get complete CRL(s) + try + { + completeSet.AddAll(FindCrls(crlselect, paramsPkix.GetStores())); + } + catch (Exception e) + { + throw new Exception("Exception obtaining complete CRLs.", e); + } + + return completeSet; + } + + /// + /// crl checking + /// Return a Collection of all CRLs found in the X509Store's that are + /// matching the crlSelect criteriums. + /// + /// a {@link X509CRLStoreSelector} object that will be used + /// to select the CRLs + /// a List containing only {@link org.bouncycastle.x509.X509Store + /// X509Store} objects. These are used to search for CRLs + /// a Collection of all found {@link X509CRL X509CRL} objects. May be + /// empty but never null. + /// + private ICollection FindCrls(X509CrlStoreSelector crlSelect, IList crlStores) + { + ISet crls = new HashSet(); + + Exception lastException = null; + bool foundValidStore = false; + + foreach (IX509Store store in crlStores) + { + try + { + crls.AddAll(store.GetMatches(crlSelect)); + foundValidStore = true; + } + catch (X509StoreException e) + { + lastException = new Exception("Exception searching in X.509 CRL store.", e); + } + } + + if (!foundValidStore && lastException != null) + throw lastException; + + return crls; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCrlUtilities.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCrlUtilities.cs.meta new file mode 100644 index 0000000..ff8dd3d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixCrlUtilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f799f5cb61bf7d945b801866c7c8ff2b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixNameConstraintValidator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixNameConstraintValidator.cs new file mode 100644 index 0000000..dbf7625 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixNameConstraintValidator.cs @@ -0,0 +1,1939 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X500; +using Org.BouncyCastle.Asn1.X500.Style; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Pkix +{ + public class PkixNameConstraintValidator + { + // TODO Implement X500Name and styles + //private static readonly DerObjectIdentifier SerialNumberOid = Rfc4519Style.SerialNumber; + private static readonly DerObjectIdentifier SerialNumberOid = new DerObjectIdentifier("2.5.4.5"); + + private ISet excludedSubtreesDN = new HashSet(); + + private ISet excludedSubtreesDNS = new HashSet(); + + private ISet excludedSubtreesEmail = new HashSet(); + + private ISet excludedSubtreesURI = new HashSet(); + + private ISet excludedSubtreesIP = new HashSet(); + + private ISet excludedSubtreesOtherName = new HashSet(); + + private ISet permittedSubtreesDN; + + private ISet permittedSubtreesDNS; + + private ISet permittedSubtreesEmail; + + private ISet permittedSubtreesURI; + + private ISet permittedSubtreesIP; + + private ISet permittedSubtreesOtherName; + + public PkixNameConstraintValidator() + { + } + + private static bool WithinDNSubtree( + Asn1Sequence dns, + Asn1Sequence subtree) + { + if (subtree.Count < 1 || subtree.Count > dns.Count) + return false; + + int start = 0; + Rdn subtreeRdnStart = Rdn.GetInstance(subtree[0]); + for (int j = 0; j < dns.Count; j++) + { + start = j; + Rdn dnsRdn = Rdn.GetInstance(dns[j]); + if (IetfUtilities.RdnAreEqual(subtreeRdnStart, dnsRdn)) + break; + } + + if (subtree.Count > dns.Count - start) + return false; + + for (int j = 0; j < subtree.Count; ++j) + { + // both subtree and dns are a ASN.1 Name and the elements are a RDN + Rdn subtreeRdn = Rdn.GetInstance(subtree[j]); + Rdn dnsRdn = Rdn.GetInstance(dns[start + j]); + + // check if types and values of all naming attributes are matching, other types which are not restricted are allowed, see https://tools.ietf.org/html/rfc5280#section-7.1 + + // Two relative distinguished names + // RDN1 and RDN2 match if they have the same number of naming attributes + // and for each naming attribute in RDN1 there is a matching naming attribute in RDN2. + // NOTE: this is checking the attributes in the same order, which might be not necessary, if this is a problem also IETFUtils.rDNAreEqual mus tbe changed. + // use new RFC 5280 comparison, NOTE: this is now different from with RFC 3280, where only binary comparison is used + // obey RFC 5280 7.1 + // special treatment of serialNumber for GSMA SGP.22 RSP specification + if (subtreeRdn.Count == 1 && dnsRdn.Count == 1 + && subtreeRdn.GetFirst().GetType().Equals(SerialNumberOid) + && dnsRdn.GetFirst().GetType().Equals(SerialNumberOid)) + { + if (!Platform.StartsWith(dnsRdn.GetFirst().Value.ToString(), subtreeRdn.GetFirst().Value.ToString())) + return false; + } + else if (!IetfUtilities.RdnAreEqual(subtreeRdn, dnsRdn)) + { + return false; + } + } + + return true; + } + + public void CheckPermittedDN(Asn1Sequence dn) + { + CheckPermittedDirectory(permittedSubtreesDN, dn); + } + + public void CheckExcludedDN(Asn1Sequence dn) + { + CheckExcludedDirectory(excludedSubtreesDN, dn); + } + + private ISet IntersectDN(ISet permitted, ISet dns) + { + ISet intersect = new HashSet(); + foreach (GeneralSubtree subtree1 in dns) + { + Asn1Sequence dn1 = Asn1Sequence.GetInstance(subtree1.Base.Name); + if (permitted == null) + { + if (dn1 != null) + { + intersect.Add(dn1); + } + } + else + { + foreach (object obj2 in permitted) + { + Asn1Sequence dn2 = Asn1Sequence.GetInstance(obj2); + + if (WithinDNSubtree(dn1, dn2)) + { + intersect.Add(dn1); + } + else if (WithinDNSubtree(dn2, dn1)) + { + intersect.Add(dn2); + } + } + } + } + return intersect; + } + + private ISet UnionDN(ISet excluded, Asn1Sequence dn) + { + if (excluded.IsEmpty) + { + if (dn == null) + return excluded; + + excluded.Add(dn); + return excluded; + } + else + { + ISet union = new HashSet(); + + foreach (object obj in excluded) + { + Asn1Sequence subtree = Asn1Sequence.GetInstance(obj); + + if (WithinDNSubtree(dn, subtree)) + { + union.Add(subtree); + } + else if (WithinDNSubtree(subtree, dn)) + { + union.Add(dn); + } + else + { + union.Add(subtree); + union.Add(dn); + } + } + + return union; + } + } + + private ISet IntersectOtherName(ISet permitted, ISet otherNames) + { + ISet intersect = new HashSet(); + foreach (GeneralSubtree subtree1 in otherNames) + { + OtherName otherName1 = OtherName.GetInstance(subtree1.Base.Name); + if (otherName1 == null) + continue; + + if (permitted == null) + { + intersect.Add(otherName1); + } + else + { + foreach (object obj2 in permitted) + { + OtherName otherName2 = OtherName.GetInstance(obj2); + if (otherName2 == null) + continue; + + IntersectOtherName(otherName1, otherName2, intersect); + } + } + } + return intersect; + } + + private void IntersectOtherName(OtherName otherName1, OtherName otherName2, ISet intersect) + { + if (otherName1.Equals(otherName2)) + { + intersect.Add(otherName1); + } + } + + private ISet UnionOtherName(ISet permitted, OtherName otherName) + { + ISet union = permitted != null ? new HashSet(permitted) : new HashSet(); + union.Add(otherName); + return union; + } + + private ISet IntersectEmail(ISet permitted, ISet emails) + { + ISet intersect = new HashSet(); + foreach (GeneralSubtree subtree1 in emails) + { + string email = ExtractNameAsString(subtree1.Base); + + if (permitted == null) + { + if (email != null) + { + intersect.Add(email); + } + } + else + { + foreach (string _permitted in permitted) + { + IntersectEmail(email, _permitted, intersect); + } + } + } + return intersect; + } + + private ISet UnionEmail(ISet excluded, string email) + { + if (excluded.IsEmpty) + { + if (email == null) + { + return excluded; + } + excluded.Add(email); + return excluded; + } + else + { + ISet union = new HashSet(); + foreach (string _excluded in excluded) + { + UnionEmail(_excluded, email, union); + } + return union; + } + } + + /** + * Returns the intersection of the permitted IP ranges in + * permitted with ip. + * + * @param permitted A Set of permitted IP addresses with + * their subnet mask as byte arrays. + * @param ips The IP address with its subnet mask. + * @return The Set of permitted IP ranges intersected with + * ip. + */ + private ISet IntersectIP(ISet permitted, ISet ips) + { + ISet intersect = new HashSet(); + foreach (GeneralSubtree subtree in ips) + { + byte[] ip = Asn1OctetString.GetInstance(subtree.Base.Name).GetOctets(); + if (permitted == null) + { + if (ip != null) + { + intersect.Add(ip); + } + } + else + { + foreach (byte[] _permitted in permitted) + { + intersect.AddAll(IntersectIPRange(_permitted, ip)); + } + } + } + return intersect; + } + + /** + * Returns the union of the excluded IP ranges in excluded + * with ip. + * + * @param excluded A Set of excluded IP addresses with their + * subnet mask as byte arrays. + * @param ip The IP address with its subnet mask. + * @return The Set of excluded IP ranges unified with + * ip as byte arrays. + */ + private ISet UnionIP(ISet excluded, byte[] ip) + { + if (excluded.IsEmpty) + { + if (ip == null) + { + return excluded; + } + excluded.Add(ip); + + return excluded; + } + else + { + ISet union = new HashSet(); + foreach (byte[] _excluded in excluded) + { + union.AddAll(UnionIPRange(_excluded, ip)); + } + return union; + } + } + + /** + * Calculates the union if two IP ranges. + * + * @param ipWithSubmask1 The first IP address with its subnet mask. + * @param ipWithSubmask2 The second IP address with its subnet mask. + * @return A Set with the union of both addresses. + */ + private ISet UnionIPRange(byte[] ipWithSubmask1, byte[] ipWithSubmask2) + { + ISet set = new HashSet(); + // difficult, adding always all IPs is not wrong + if (Arrays.AreEqual(ipWithSubmask1, ipWithSubmask2)) + { + set.Add(ipWithSubmask1); + } + else + { + set.Add(ipWithSubmask1); + set.Add(ipWithSubmask2); + } + return set; + } + + /** + * Calculates the interesction if two IP ranges. + * + * @param ipWithSubmask1 The first IP address with its subnet mask. + * @param ipWithSubmask2 The second IP address with its subnet mask. + * @return A Set with the single IP address with its subnet + * mask as a byte array or an empty Set. + */ + private ISet IntersectIPRange(byte[] ipWithSubmask1, byte[] ipWithSubmask2) + { + if (ipWithSubmask1.Length != ipWithSubmask2.Length) + { + //Collections.EMPTY_SET; + return new HashSet(); + } + + byte[][] temp = ExtractIPsAndSubnetMasks(ipWithSubmask1, ipWithSubmask2); + byte[] ip1 = temp[0]; + byte[] subnetmask1 = temp[1]; + byte[] ip2 = temp[2]; + byte[] subnetmask2 = temp[3]; + + byte[][] minMax = MinMaxIPs(ip1, subnetmask1, ip2, subnetmask2); + byte[] min; + byte[] max; + max = Min(minMax[1], minMax[3]); + min = Max(minMax[0], minMax[2]); + + // minimum IP address must be bigger than max + if (CompareTo(min, max) == 1) + { + //return Collections.EMPTY_SET; + return new HashSet(); + } + // OR keeps all significant bits + byte[] ip = Or(minMax[0], minMax[2]); + byte[] subnetmask = Or(subnetmask1, subnetmask2); + + //return new HashSet( ICollectionsingleton(IpWithSubnetMask(ip, subnetmask)); + ISet hs = new HashSet(); + hs.Add(IpWithSubnetMask(ip, subnetmask)); + + return hs; + } + + /** + * Concatenates the IP address with its subnet mask. + * + * @param ip The IP address. + * @param subnetMask Its subnet mask. + * @return The concatenated IP address with its subnet mask. + */ + private byte[] IpWithSubnetMask(byte[] ip, byte[] subnetMask) + { + int ipLength = ip.Length; + byte[] temp = new byte[ipLength * 2]; + Array.Copy(ip, 0, temp, 0, ipLength); + Array.Copy(subnetMask, 0, temp, ipLength, ipLength); + return temp; + } + + /** + * Splits the IP addresses and their subnet mask. + * + * @param ipWithSubmask1 The first IP address with the subnet mask. + * @param ipWithSubmask2 The second IP address with the subnet mask. + * @return An array with two elements. Each element contains the IP address + * and the subnet mask in this order. + */ + private byte[][] ExtractIPsAndSubnetMasks( + byte[] ipWithSubmask1, + byte[] ipWithSubmask2) + { + int ipLength = ipWithSubmask1.Length / 2; + byte[] ip1 = new byte[ipLength]; + byte[] subnetmask1 = new byte[ipLength]; + Array.Copy(ipWithSubmask1, 0, ip1, 0, ipLength); + Array.Copy(ipWithSubmask1, ipLength, subnetmask1, 0, ipLength); + + byte[] ip2 = new byte[ipLength]; + byte[] subnetmask2 = new byte[ipLength]; + Array.Copy(ipWithSubmask2, 0, ip2, 0, ipLength); + Array.Copy(ipWithSubmask2, ipLength, subnetmask2, 0, ipLength); + return new byte[][]{ ip1, subnetmask1, ip2, subnetmask2 }; + } + + /** + * Based on the two IP addresses and their subnet masks the IP range is + * computed for each IP address - subnet mask pair and returned as the + * minimum IP address and the maximum address of the range. + * + * @param ip1 The first IP address. + * @param subnetmask1 The subnet mask of the first IP address. + * @param ip2 The second IP address. + * @param subnetmask2 The subnet mask of the second IP address. + * @return A array with two elements. The first/second element contains the + * min and max IP address of the first/second IP address and its + * subnet mask. + */ + private byte[][] MinMaxIPs( + byte[] ip1, + byte[] subnetmask1, + byte[] ip2, + byte[] subnetmask2) + { + int ipLength = ip1.Length; + byte[] min1 = new byte[ipLength]; + byte[] max1 = new byte[ipLength]; + + byte[] min2 = new byte[ipLength]; + byte[] max2 = new byte[ipLength]; + + for (int i = 0; i < ipLength; i++) + { + min1[i] = (byte)(ip1[i] & subnetmask1[i]); + max1[i] = (byte)(ip1[i] & subnetmask1[i] | ~subnetmask1[i]); + + min2[i] = (byte)(ip2[i] & subnetmask2[i]); + max2[i] = (byte)(ip2[i] & subnetmask2[i] | ~subnetmask2[i]); + } + + return new byte[][]{ min1, max1, min2, max2 }; + } + + private bool IsOtherNameConstrained(OtherName constraint, OtherName otherName) + { + return constraint.Equals(otherName); + } + + private bool IsOtherNameConstrained(ISet constraints, OtherName otherName) + { + foreach (object obj in constraints) + { + OtherName constraint = OtherName.GetInstance(obj); + + if (IsOtherNameConstrained(constraint, otherName)) + return true; + } + + return false; + } + + private void CheckPermittedOtherName(ISet permitted, OtherName name) + { + if (permitted != null && !IsOtherNameConstrained(permitted, name)) + { + throw new PkixNameConstraintValidatorException( + "Subject OtherName is not from a permitted subtree."); + } + } + + private void CheckExcludedOtherName(ISet excluded, OtherName name) + { + if (IsOtherNameConstrained(excluded, name)) + { + throw new PkixNameConstraintValidatorException( + "OtherName is from an excluded subtree."); + } + } + + private bool IsEmailConstrained(string constraint, string email) + { + string sub = email.Substring(email.IndexOf('@') + 1); + // a particular mailbox + if (constraint.IndexOf('@') != -1) + { + if (Platform.ToUpperInvariant(email).Equals(Platform.ToUpperInvariant(constraint))) + { + return true; + } + } + // on particular host + else if (!(constraint[0].Equals('.'))) + { + if (Platform.ToUpperInvariant(sub).Equals(Platform.ToUpperInvariant(constraint))) + { + return true; + } + } + // address in sub domain + else if (WithinDomain(sub, constraint)) + { + return true; + } + return false; + } + + private bool IsEmailConstrained(ISet constraints, string email) + { + foreach (string constraint in constraints) + { + if (IsEmailConstrained(constraint, email)) + return true; + } + + return false; + } + + private void CheckPermittedEmail(ISet permitted, string email) + { + if (permitted != null + && !(email.Length == 0 && permitted.IsEmpty) + && !IsEmailConstrained(permitted, email)) + { + throw new PkixNameConstraintValidatorException( + "Subject email address is not from a permitted subtree."); + } + } + + private void CheckExcludedEmail(ISet excluded, string email) + { + if (IsEmailConstrained(excluded, email)) + { + throw new PkixNameConstraintValidatorException( + "Email address is from an excluded subtree."); + } + } + + private bool IsDnsConstrained(string constraint, string dns) + { + return WithinDomain(dns, constraint) || Platform.EqualsIgnoreCase(dns, constraint); + } + + private bool IsDnsConstrained(ISet constraints, string dns) + { + foreach (string constraint in constraints) + { + if (IsDnsConstrained(constraint, dns)) + return true; + } + + return false; + } + + private void CheckPermittedDns(ISet permitted, string dns) + { + if (permitted != null + && !(dns.Length == 0 && permitted.IsEmpty) + && !IsDnsConstrained(permitted, dns)) + { + throw new PkixNameConstraintValidatorException( + "DNS is not from a permitted subtree."); + } + } + + private void CheckExcludedDns(ISet excluded, string dns) + { + if (IsDnsConstrained(excluded, dns)) + { + throw new PkixNameConstraintValidatorException( + "DNS is from an excluded subtree."); + } + } + + private bool IsDirectoryConstrained(ISet constraints, Asn1Sequence directory) + { + foreach (object obj in constraints) + { + Asn1Sequence constraint = Asn1Sequence.GetInstance(obj); + + if (WithinDNSubtree(directory, constraint)) + return true; + } + + return false; + } + + private void CheckPermittedDirectory(ISet permitted, Asn1Sequence directory) + { + if (permitted != null + && !(directory.Count == 0 && permitted.IsEmpty) + && !IsDirectoryConstrained(permitted, directory)) + { + throw new PkixNameConstraintValidatorException( + "Subject distinguished name is not from a permitted subtree"); + } + } + + private void CheckExcludedDirectory(ISet excluded, Asn1Sequence directory) + { + if (IsDirectoryConstrained(excluded, directory)) + { + throw new PkixNameConstraintValidatorException( + "Subject distinguished name is from an excluded subtree"); + } + } + + private bool IsUriConstrained(string constraint, string uri) + { + string host = ExtractHostFromURL(uri); + + if (Platform.StartsWith(constraint, ".")) + { + // in sub domain or domain + return WithinDomain(host, constraint); + } + + // a host + return Platform.EqualsIgnoreCase(host, constraint); + } + + private bool IsUriConstrained(ISet constraints, string uri) + { + foreach (string constraint in constraints) + { + if (IsUriConstrained(constraint, uri)) + return true; + } + + return false; + } + + private void CheckPermittedUri(ISet permitted, string uri) + { + if (permitted != null + && !(uri.Length == 0 && permitted.IsEmpty) + && !IsUriConstrained(permitted, uri)) + { + throw new PkixNameConstraintValidatorException( + "URI is not from a permitted subtree."); + } + } + + private void CheckExcludedUri(ISet excluded, string uri) + { + if (IsUriConstrained(excluded, uri)) + { + throw new PkixNameConstraintValidatorException( + "URI is from an excluded subtree."); + } + } + + /** + * Checks if the IP address ip is constrained by + * constraint. + * + * @param constraint The constraint. This is an IP address concatenated with + * its subnetmask. + * @param ip The IP address. + * @return true if constrained, false + * otherwise. + */ + private bool IsIPConstrained(byte[] constraint, byte[] ip) + { + int ipLength = ip.Length; + if (ipLength != (constraint.Length / 2)) + { + return false; + } + + byte[] subnetMask = new byte[ipLength]; + Array.Copy(constraint, ipLength, subnetMask, 0, ipLength); + + byte[] permittedSubnetAddress = new byte[ipLength]; + + byte[] ipSubnetAddress = new byte[ipLength]; + + // the resulting IP address by applying the subnet mask + for (int i = 0; i < ipLength; i++) + { + permittedSubnetAddress[i] = (byte)(constraint[i] & subnetMask[i]); + ipSubnetAddress[i] = (byte)(ip[i] & subnetMask[i]); + } + + return Arrays.AreEqual(permittedSubnetAddress, ipSubnetAddress); + } + + private bool IsIPConstrained(ISet constraints, byte[] ip) + { + foreach (byte[] constraint in constraints) + { + if (IsIPConstrained(constraint, ip)) + return true; + } + + return false; + } + + /** + * Checks if the IP ip is included in the permitted ISet + * permitted. + * + * @param permitted A Set of permitted IP addresses with + * their subnet mask as byte arrays. + * @param ip The IP address. + * @throws PkixNameConstraintValidatorException + * if the IP is not permitted. + */ + private void CheckPermittedIP(ISet permitted, byte[] ip) + { + if (permitted != null + && !(ip.Length == 0 && permitted.IsEmpty) + && !IsIPConstrained(permitted, ip)) + { + throw new PkixNameConstraintValidatorException( + "IP is not from a permitted subtree."); + } + } + + /** + * Checks if the IP ip is included in the excluded ISet + * excluded. + * + * @param excluded A Set of excluded IP addresses with their + * subnet mask as byte arrays. + * @param ip The IP address. + * @throws PkixNameConstraintValidatorException + * if the IP is excluded. + */ + private void CheckExcludedIP(ISet excluded, byte[] ip) + { + if (IsIPConstrained(excluded, ip)) + { + throw new PkixNameConstraintValidatorException( + "IP is from an excluded subtree."); + } + } + + private bool WithinDomain(string testDomain, string domain) + { + string tempDomain = domain; + if (Platform.StartsWith(tempDomain, ".")) + { + tempDomain = tempDomain.Substring(1); + } + + string[] domainParts = tempDomain.Split('.'); // Strings.split(tempDomain, '.'); + string[] testDomainParts = testDomain.Split('.'); // Strings.split(testDomain, '.'); + + // must have at least one subdomain + if (testDomainParts.Length <= domainParts.Length) + return false; + + int d = testDomainParts.Length - domainParts.Length; + for (int i = -1; i < domainParts.Length; i++) + { + if (i == -1) + { + if (testDomainParts[i + d].Length < 1) + { + return false; + } + } + else if (!Platform.EqualsIgnoreCase(testDomainParts[i + d], domainParts[i])) + { + return false; + } + } + return true; + } + + /** + * The common part of email1 and email2 is + * added to the union union. If email1 and + * email2 have nothing in common they are added both. + * + * @param email1 Email address constraint 1. + * @param email2 Email address constraint 2. + * @param union The union. + */ + private void UnionEmail(string email1, string email2, ISet union) + { + // email1 is a particular address + if (email1.IndexOf('@') != -1) + { + string _sub = email1.Substring(email1.IndexOf('@') + 1); + // both are a particular mailbox + if (email2.IndexOf('@') != -1) + { + if (Platform.EqualsIgnoreCase(email1, email2)) + { + union.Add(email1); + } + else + { + union.Add(email1); + union.Add(email2); + } + } + // email2 specifies a domain + else if (Platform.StartsWith(email2, ".")) + { + if (WithinDomain(_sub, email2)) + { + union.Add(email2); + } + else + { + union.Add(email1); + union.Add(email2); + } + } + // email2 specifies a particular host + else + { + if (Platform.EqualsIgnoreCase(_sub, email2)) + { + union.Add(email2); + } + else + { + union.Add(email1); + union.Add(email2); + } + } + } + // email1 specifies a domain + else if (Platform.StartsWith(email1, ".")) + { + if (email2.IndexOf('@') != -1) + { + string _sub = email2.Substring(email1.IndexOf('@') + 1); + if (WithinDomain(_sub, email1)) + { + union.Add(email1); + } + else + { + union.Add(email1); + union.Add(email2); + } + } + // email2 specifies a domain + else if (Platform.StartsWith(email2, ".")) + { + if (WithinDomain(email1, email2) || Platform.EqualsIgnoreCase(email1, email2)) + { + union.Add(email2); + } + else if (WithinDomain(email2, email1)) + { + union.Add(email1); + } + else + { + union.Add(email1); + union.Add(email2); + } + } + else + { + if (WithinDomain(email2, email1)) + { + union.Add(email1); + } + else + { + union.Add(email1); + union.Add(email2); + } + } + } + // email specifies a host + else + { + if (email2.IndexOf('@') != -1) + { + string _sub = email2.Substring(email1.IndexOf('@') + 1); + if (Platform.EqualsIgnoreCase(_sub, email1)) + { + union.Add(email1); + } + else + { + union.Add(email1); + union.Add(email2); + } + } + // email2 specifies a domain + else if (Platform.StartsWith(email2, ".")) + { + if (WithinDomain(email1, email2)) + { + union.Add(email2); + } + else + { + union.Add(email1); + union.Add(email2); + } + } + // email2 specifies a particular host + else + { + if (Platform.EqualsIgnoreCase(email1, email2)) + { + union.Add(email1); + } + else + { + union.Add(email1); + union.Add(email2); + } + } + } + } + + private void unionURI(string email1, string email2, ISet union) + { + // email1 is a particular address + if (email1.IndexOf('@') != -1) + { + string _sub = email1.Substring(email1.IndexOf('@') + 1); + // both are a particular mailbox + if (email2.IndexOf('@') != -1) + { + if (Platform.EqualsIgnoreCase(email1, email2)) + { + union.Add(email1); + } + else + { + union.Add(email1); + union.Add(email2); + } + } + // email2 specifies a domain + else if (Platform.StartsWith(email2, ".")) + { + if (WithinDomain(_sub, email2)) + { + union.Add(email2); + } + else + { + union.Add(email1); + union.Add(email2); + } + } + // email2 specifies a particular host + else + { + if (Platform.EqualsIgnoreCase(_sub, email2)) + { + union.Add(email2); + } + else + { + union.Add(email1); + union.Add(email2); + + } + } + } + // email1 specifies a domain + else if (Platform.StartsWith(email1, ".")) + { + if (email2.IndexOf('@') != -1) + { + string _sub = email2.Substring(email1.IndexOf('@') + 1); + if (WithinDomain(_sub, email1)) + { + union.Add(email1); + } + else + { + union.Add(email1); + union.Add(email2); + } + } + // email2 specifies a domain + else if (Platform.StartsWith(email2, ".")) + { + if (WithinDomain(email1, email2) || Platform.EqualsIgnoreCase(email1, email2)) + { + union.Add(email2); + } + else if (WithinDomain(email2, email1)) + { + union.Add(email1); + } + else + { + union.Add(email1); + union.Add(email2); + } + } + else + { + if (WithinDomain(email2, email1)) + { + union.Add(email1); + } + else + { + union.Add(email1); + union.Add(email2); + } + } + } + // email specifies a host + else + { + if (email2.IndexOf('@') != -1) + { + string _sub = email2.Substring(email1.IndexOf('@') + 1); + if (Platform.EqualsIgnoreCase(_sub, email1)) + { + union.Add(email1); + } + else + { + union.Add(email1); + union.Add(email2); + } + } + // email2 specifies a domain + else if (Platform.StartsWith(email2, ".")) + { + if (WithinDomain(email1, email2)) + { + union.Add(email2); + } + else + { + union.Add(email1); + union.Add(email2); + } + } + // email2 specifies a particular host + else + { + if (Platform.EqualsIgnoreCase(email1, email2)) + { + union.Add(email1); + } + else + { + union.Add(email1); + union.Add(email2); + } + } + } + } + + private ISet IntersectDns(ISet permitted, ISet dnss) + { + ISet intersect = new HashSet(); + foreach (GeneralSubtree subtree in dnss) + { + string dns = ExtractNameAsString(subtree.Base); + if (permitted == null) + { + if (dns != null) + { + intersect.Add(dns); + } + } + else + { + foreach (string _permitted in permitted) + { + if (WithinDomain(_permitted, dns)) + { + intersect.Add(_permitted); + } + else if (WithinDomain(dns, _permitted)) + { + intersect.Add(dns); + } + } + } + } + + return intersect; + } + + private ISet UnionDns(ISet excluded, string dns) + { + if (excluded.IsEmpty) + { + if (dns == null) + return excluded; + + excluded.Add(dns); + return excluded; + } + else + { + ISet union = new HashSet(); + foreach (string _excluded in excluded) + { + if (WithinDomain(_excluded, dns)) + { + union.Add(dns); + } + else if (WithinDomain(dns, _excluded)) + { + union.Add(_excluded); + } + else + { + union.Add(_excluded); + union.Add(dns); + } + } + return union; + } + } + + /** + * The most restricting part from email1 and + * email2 is added to the intersection intersect. + * + * @param email1 Email address constraint 1. + * @param email2 Email address constraint 2. + * @param intersect The intersection. + */ + private void IntersectEmail(string email1, string email2, ISet intersect) + { + // email1 is a particular address + if (email1.IndexOf('@') != -1) + { + string _sub = email1.Substring(email1.IndexOf('@') + 1); + // both are a particular mailbox + if (email2.IndexOf('@') != -1) + { + if (Platform.EqualsIgnoreCase(email1, email2)) + { + intersect.Add(email1); + } + } + // email2 specifies a domain + else if (Platform.StartsWith(email2, ".")) + { + if (WithinDomain(_sub, email2)) + { + intersect.Add(email1); + } + } + // email2 specifies a particular host + else + { + if (Platform.EqualsIgnoreCase(_sub, email2)) + { + intersect.Add(email1); + } + } + } + // email specifies a domain + else if (Platform.StartsWith(email1, ".")) + { + if (email2.IndexOf('@') != -1) + { + string _sub = email2.Substring(email1.IndexOf('@') + 1); + if (WithinDomain(_sub, email1)) + { + intersect.Add(email2); + } + } + // email2 specifies a domain + else if (Platform.StartsWith(email2, ".")) + { + if (WithinDomain(email1, email2) || Platform.EqualsIgnoreCase(email1, email2)) + { + intersect.Add(email1); + } + else if (WithinDomain(email2, email1)) + { + intersect.Add(email2); + } + } + else + { + if (WithinDomain(email2, email1)) + { + intersect.Add(email2); + } + } + } + // email1 specifies a host + else + { + if (email2.IndexOf('@') != -1) + { + string _sub = email2.Substring(email2.IndexOf('@') + 1); + if (Platform.EqualsIgnoreCase(_sub, email1)) + { + intersect.Add(email2); + } + } + // email2 specifies a domain + else if (Platform.StartsWith(email2, ".")) + { + if (WithinDomain(email1, email2)) + { + intersect.Add(email1); + } + } + // email2 specifies a particular host + else + { + if (Platform.EqualsIgnoreCase(email1, email2)) + { + intersect.Add(email1); + } + } + } + } + + private ISet IntersectUri(ISet permitted, ISet uris) + { + ISet intersect = new HashSet(); + foreach (GeneralSubtree subtree in uris) + { + string uri = ExtractNameAsString(subtree.Base); + if (permitted == null) + { + if (uri != null) + { + intersect.Add(uri); + } + } + else + { + foreach (string _permitted in permitted) + { + IntersectUri(_permitted, uri, intersect); + } + } + } + return intersect; + } + + private ISet UnionUri(ISet excluded, string uri) + { + if (excluded.IsEmpty) + { + if (uri == null) + return excluded; + + excluded.Add(uri); + return excluded; + } + else + { + ISet union = new HashSet(); + foreach (string _excluded in excluded) + { + unionURI(_excluded, uri, union); + } + return union; + } + } + + private void IntersectUri(string email1, string email2, ISet intersect) + { + // email1 is a particular address + if (email1.IndexOf('@') != -1) + { + string _sub = email1.Substring(email1.IndexOf('@') + 1); + // both are a particular mailbox + if (email2.IndexOf('@') != -1) + { + if (Platform.EqualsIgnoreCase(email1, email2)) + { + intersect.Add(email1); + } + } + // email2 specifies a domain + else if (Platform.StartsWith(email2, ".")) + { + if (WithinDomain(_sub, email2)) + { + intersect.Add(email1); + } + } + // email2 specifies a particular host + else + { + if (Platform.EqualsIgnoreCase(_sub, email2)) + { + intersect.Add(email1); + } + } + } + // email specifies a domain + else if (Platform.StartsWith(email1, ".")) + { + if (email2.IndexOf('@') != -1) + { + string _sub = email2.Substring(email1.IndexOf('@') + 1); + if (WithinDomain(_sub, email1)) + { + intersect.Add(email2); + } + } + // email2 specifies a domain + else if (Platform.StartsWith(email2, ".")) + { + if (WithinDomain(email1, email2) || Platform.EqualsIgnoreCase(email1, email2)) + { + intersect.Add(email1); + } + else if (WithinDomain(email2, email1)) + { + intersect.Add(email2); + } + } + else + { + if (WithinDomain(email2, email1)) + { + intersect.Add(email2); + } + } + } + // email1 specifies a host + else + { + if (email2.IndexOf('@') != -1) + { + string _sub = email2.Substring(email2.IndexOf('@') + 1); + if (Platform.EqualsIgnoreCase(_sub, email1)) + { + intersect.Add(email2); + } + } + // email2 specifies a domain + else if (Platform.StartsWith(email2, ".")) + { + if (WithinDomain(email1, email2)) + { + intersect.Add(email1); + } + } + // email2 specifies a particular host + else + { + if (Platform.EqualsIgnoreCase(email1, email2)) + { + intersect.Add(email1); + } + } + } + } + + private static string ExtractHostFromURL(string url) + { + // see RFC 1738 + // remove ':' after protocol, e.g. http: + string sub = url.Substring(url.IndexOf(':') + 1); + // extract host from Common Internet Scheme Syntax, e.g. http:// + int idxOfSlashes = Platform.IndexOf(sub, "//"); + if (idxOfSlashes != -1) + { + sub = sub.Substring(idxOfSlashes + 2); + } + // first remove port, e.g. http://test.com:21 + if (sub.LastIndexOf(':') != -1) + { + sub = sub.Substring(0, sub.LastIndexOf(':')); + } + // remove user and password, e.g. http://john:password@test.com + sub = sub.Substring(sub.IndexOf(':') + 1); + sub = sub.Substring(sub.IndexOf('@') + 1); + // remove local parts, e.g. http://test.com/bla + if (sub.IndexOf('/') != -1) + { + sub = sub.Substring(0, sub.IndexOf('/')); + } + return sub; + } + + /** + * Checks if the given GeneralName is in the permitted ISet. + * + * @param name The GeneralName + * @throws PkixNameConstraintValidatorException + * If the name + */ + public void checkPermitted(GeneralName name) + //throws PkixNameConstraintValidatorException + { + switch (name.TagNo) + { + case GeneralName.OtherName: + CheckPermittedOtherName(permittedSubtreesOtherName, OtherName.GetInstance(name.Name)); + break; + case GeneralName.Rfc822Name: + CheckPermittedEmail(permittedSubtreesEmail, ExtractNameAsString(name)); + break; + case GeneralName.DnsName: + CheckPermittedDns(permittedSubtreesDNS, ExtractNameAsString(name)); + break; + case GeneralName.DirectoryName: + CheckPermittedDN(Asn1Sequence.GetInstance(name.Name.ToAsn1Object())); + break; + case GeneralName.UniformResourceIdentifier: + CheckPermittedUri(permittedSubtreesURI, ExtractNameAsString(name)); + break; + case GeneralName.IPAddress: + CheckPermittedIP(permittedSubtreesIP, Asn1OctetString.GetInstance(name.Name).GetOctets()); + break; + } + } + + /** + * Check if the given GeneralName is contained in the excluded ISet. + * + * @param name The GeneralName. + * @throws PkixNameConstraintValidatorException + * If the name is + * excluded. + */ + public void checkExcluded(GeneralName name) + //throws PkixNameConstraintValidatorException + { + switch (name.TagNo) + { + case GeneralName.OtherName: + CheckExcludedOtherName(excludedSubtreesOtherName, OtherName.GetInstance(name.Name)); + break; + case GeneralName.Rfc822Name: + CheckExcludedEmail(excludedSubtreesEmail, ExtractNameAsString(name)); + break; + case GeneralName.DnsName: + CheckExcludedDns(excludedSubtreesDNS, ExtractNameAsString(name)); + break; + case GeneralName.DirectoryName: + CheckExcludedDN(Asn1Sequence.GetInstance(name.Name.ToAsn1Object())); + break; + case GeneralName.UniformResourceIdentifier: + CheckExcludedUri(excludedSubtreesURI, ExtractNameAsString(name)); + break; + case GeneralName.IPAddress: + CheckExcludedIP(excludedSubtreesIP, Asn1OctetString.GetInstance(name.Name).GetOctets()); + break; + } + } + + /** + * Updates the permitted ISet of these name constraints with the intersection + * with the given subtree. + * + * @param permitted The permitted subtrees + */ + + public void IntersectPermittedSubtree(Asn1Sequence permitted) + { + IDictionary subtreesMap = Platform.CreateHashtable(); + + // group in ISets in a map ordered by tag no. + foreach (object obj in permitted) + { + GeneralSubtree subtree = GeneralSubtree.GetInstance(obj); + + int tagNo = subtree.Base.TagNo; + if (subtreesMap[tagNo] == null) + { + subtreesMap[tagNo] = new HashSet(); + } + + ((ISet)subtreesMap[tagNo]).Add(subtree); + } + + foreach (DictionaryEntry entry in subtreesMap) + { + // go through all subtree groups + switch ((int)entry.Key) + { + case GeneralName.OtherName: + permittedSubtreesOtherName = IntersectOtherName(permittedSubtreesOtherName, + (ISet)entry.Value); + break; + case GeneralName.Rfc822Name: + permittedSubtreesEmail = IntersectEmail(permittedSubtreesEmail, + (ISet)entry.Value); + break; + case GeneralName.DnsName: + permittedSubtreesDNS = IntersectDns(permittedSubtreesDNS, + (ISet)entry.Value); + break; + case GeneralName.DirectoryName: + permittedSubtreesDN = IntersectDN(permittedSubtreesDN, + (ISet)entry.Value); + break; + case GeneralName.UniformResourceIdentifier: + permittedSubtreesURI = IntersectUri(permittedSubtreesURI, + (ISet)entry.Value); + break; + case GeneralName.IPAddress: + permittedSubtreesIP = IntersectIP(permittedSubtreesIP, + (ISet)entry.Value); + break; + } + } + } + + private string ExtractNameAsString(GeneralName name) + { + return DerIA5String.GetInstance(name.Name).GetString(); + } + + public void IntersectEmptyPermittedSubtree(int nameType) + { + switch (nameType) + { + case GeneralName.OtherName: + permittedSubtreesOtherName = new HashSet(); + break; + case GeneralName.Rfc822Name: + permittedSubtreesEmail = new HashSet(); + break; + case GeneralName.DnsName: + permittedSubtreesDNS = new HashSet(); + break; + case GeneralName.DirectoryName: + permittedSubtreesDN = new HashSet(); + break; + case GeneralName.UniformResourceIdentifier: + permittedSubtreesURI = new HashSet(); + break; + case GeneralName.IPAddress: + permittedSubtreesIP = new HashSet(); + break; + } + } + + /** + * Adds a subtree to the excluded ISet of these name constraints. + * + * @param subtree A subtree with an excluded GeneralName. + */ + public void AddExcludedSubtree(GeneralSubtree subtree) + { + GeneralName subTreeBase = subtree.Base; + + switch (subTreeBase.TagNo) + { + case GeneralName.OtherName: + excludedSubtreesOtherName = UnionOtherName(excludedSubtreesOtherName, + OtherName.GetInstance(subTreeBase.Name)); + break; + case GeneralName.Rfc822Name: + excludedSubtreesEmail = UnionEmail(excludedSubtreesEmail, + ExtractNameAsString(subTreeBase)); + break; + case GeneralName.DnsName: + excludedSubtreesDNS = UnionDns(excludedSubtreesDNS, + ExtractNameAsString(subTreeBase)); + break; + case GeneralName.DirectoryName: + excludedSubtreesDN = UnionDN(excludedSubtreesDN, + (Asn1Sequence)subTreeBase.Name.ToAsn1Object()); + break; + case GeneralName.UniformResourceIdentifier: + excludedSubtreesURI = UnionUri(excludedSubtreesURI, + ExtractNameAsString(subTreeBase)); + break; + case GeneralName.IPAddress: + excludedSubtreesIP = UnionIP(excludedSubtreesIP, + Asn1OctetString.GetInstance(subTreeBase.Name).GetOctets()); + break; + } + } + + /** + * Returns the maximum IP address. + * + * @param ip1 The first IP address. + * @param ip2 The second IP address. + * @return The maximum IP address. + */ + private static byte[] Max(byte[] ip1, byte[] ip2) + { + for (int i = 0; i < ip1.Length; i++) + { + if ((ip1[i] & 0xFFFF) > (ip2[i] & 0xFFFF)) + { + return ip1; + } + } + return ip2; + } + + /** + * Returns the minimum IP address. + * + * @param ip1 The first IP address. + * @param ip2 The second IP address. + * @return The minimum IP address. + */ + private static byte[] Min(byte[] ip1, byte[] ip2) + { + for (int i = 0; i < ip1.Length; i++) + { + if ((ip1[i] & 0xFFFF) < (ip2[i] & 0xFFFF)) + { + return ip1; + } + } + return ip2; + } + + /** + * Compares IP address ip1 with ip2. If ip1 + * is equal to ip2 0 is returned. If ip1 is bigger 1 is returned, -1 + * otherwise. + * + * @param ip1 The first IP address. + * @param ip2 The second IP address. + * @return 0 if ip1 is equal to ip2, 1 if ip1 is bigger, -1 otherwise. + */ + private static int CompareTo(byte[] ip1, byte[] ip2) + { + if (Org.BouncyCastle.Utilities.Arrays.AreEqual(ip1, ip2)) + { + return 0; + } + if (Org.BouncyCastle.Utilities.Arrays.AreEqual(Max(ip1, ip2), ip1)) + { + return 1; + } + return -1; + } + + /** + * Returns the logical OR of the IP addresses ip1 and + * ip2. + * + * @param ip1 The first IP address. + * @param ip2 The second IP address. + * @return The OR of ip1 and ip2. + */ + private static byte[] Or(byte[] ip1, byte[] ip2) + { + byte[] temp = new byte[ip1.Length]; + for (int i = 0; i < ip1.Length; i++) + { + temp[i] = (byte)(ip1[i] | ip2[i]); + } + return temp; + } + + [Obsolete("Use GetHashCode instead")] + public int HashCode() + { + return GetHashCode(); + } + + public override int GetHashCode() + { + return HashCollection(excludedSubtreesDN) + + HashCollection(excludedSubtreesDNS) + + HashCollection(excludedSubtreesEmail) + + HashCollection(excludedSubtreesIP) + + HashCollection(excludedSubtreesURI) + + HashCollection(excludedSubtreesOtherName) + + HashCollection(permittedSubtreesDN) + + HashCollection(permittedSubtreesDNS) + + HashCollection(permittedSubtreesEmail) + + HashCollection(permittedSubtreesIP) + + HashCollection(permittedSubtreesURI) + + HashCollection(permittedSubtreesOtherName); + } + + private int HashCollection(ICollection c) + { + if (c == null) + return 0; + + int hash = 0; + foreach (Object o in c) + { + if (o is byte[]) + { + hash += Arrays.GetHashCode((byte[])o); + } + else + { + hash += o.GetHashCode(); + } + } + return hash; + } + + public override bool Equals(Object o) + { + if (!(o is PkixNameConstraintValidator)) + return false; + + PkixNameConstraintValidator constraintValidator = (PkixNameConstraintValidator)o; + + return CollectionsAreEqual(constraintValidator.excludedSubtreesDN, excludedSubtreesDN) + && CollectionsAreEqual(constraintValidator.excludedSubtreesDNS, excludedSubtreesDNS) + && CollectionsAreEqual(constraintValidator.excludedSubtreesEmail, excludedSubtreesEmail) + && CollectionsAreEqual(constraintValidator.excludedSubtreesIP, excludedSubtreesIP) + && CollectionsAreEqual(constraintValidator.excludedSubtreesURI, excludedSubtreesURI) + && CollectionsAreEqual(constraintValidator.excludedSubtreesOtherName, excludedSubtreesOtherName) + && CollectionsAreEqual(constraintValidator.permittedSubtreesDN, permittedSubtreesDN) + && CollectionsAreEqual(constraintValidator.permittedSubtreesDNS, permittedSubtreesDNS) + && CollectionsAreEqual(constraintValidator.permittedSubtreesEmail, permittedSubtreesEmail) + && CollectionsAreEqual(constraintValidator.permittedSubtreesIP, permittedSubtreesIP) + && CollectionsAreEqual(constraintValidator.permittedSubtreesURI, permittedSubtreesURI) + && CollectionsAreEqual(constraintValidator.permittedSubtreesOtherName, permittedSubtreesOtherName); + } + + private bool CollectionsAreEqual(ICollection coll1, ICollection coll2) + { + if (coll1 == coll2) + return true; + if (coll1 == null || coll2 == null || coll1.Count != coll2.Count) + return false; + + foreach (Object a in coll1) + { + bool found = false; + foreach (Object b in coll2) + { + if (SpecialEquals(a, b)) + { + found = true; + break; + } + } + + if (!found) + return false; + } + return true; + } + + private bool SpecialEquals(Object o1, Object o2) + { + if (o1 == o2) + { + return true; + } + if (o1 == null || o2 == null) + { + return false; + } + if ((o1 is byte[]) && (o2 is byte[])) + { + return Arrays.AreEqual((byte[])o1, (byte[])o2); + } + else + { + return o1.Equals(o2); + } + } + + /** + * Stringifies an IPv4 or v6 address with subnet mask. + * + * @param ip The IP with subnet mask. + * @return The stringified IP address. + */ + private string StringifyIP(byte[] ip) + { + string temp = ""; + for (int i = 0; i < ip.Length / 2; i++) + { + //temp += Integer.toString(ip[i] & 0x00FF) + "."; + temp += (ip[i] & 0x00FF) + "."; + } + temp = temp.Substring(0, temp.Length - 1); + temp += "/"; + for (int i = ip.Length / 2; i < ip.Length; i++) + { + //temp += Integer.toString(ip[i] & 0x00FF) + "."; + temp += (ip[i] & 0x00FF) + "."; + } + temp = temp.Substring(0, temp.Length - 1); + return temp; + } + + private string StringifyIPCollection(ISet ips) + { + string temp = ""; + temp += "["; + foreach (byte[] ip in ips) + { + temp += StringifyIP(ip) + ","; + } + if (temp.Length > 1) + { + temp = temp.Substring(0, temp.Length - 1); + } + temp += "]"; + return temp; + } + + private string StringifyOtherNameCollection(ISet otherNames) + { + string temp = ""; + temp += "["; + foreach (object obj in otherNames) + { + OtherName name = OtherName.GetInstance(obj); + if (temp.Length > 1) + { + temp += ","; + } + temp += name.TypeID.Id; + temp += ":"; + try + { + temp += Hex.ToHexString(name.Value.ToAsn1Object().GetEncoded()); + } + catch (IOException e) + { + temp += e.ToString(); + } + } + temp += "]"; + return temp; + } + + public override string ToString() + { + string temp = ""; + + temp += "permitted:\n"; + if (permittedSubtreesDN != null) + { + temp += "DN:\n"; + temp += permittedSubtreesDN.ToString() + "\n"; + } + if (permittedSubtreesDNS != null) + { + temp += "DNS:\n"; + temp += permittedSubtreesDNS.ToString() + "\n"; + } + if (permittedSubtreesEmail != null) + { + temp += "Email:\n"; + temp += permittedSubtreesEmail.ToString() + "\n"; + } + if (permittedSubtreesURI != null) + { + temp += "URI:\n"; + temp += permittedSubtreesURI.ToString() + "\n"; + } + if (permittedSubtreesIP != null) + { + temp += "IP:\n"; + temp += StringifyIPCollection(permittedSubtreesIP) + "\n"; + } + if (permittedSubtreesOtherName != null) + { + temp += "OtherName:\n"; + temp += StringifyOtherNameCollection(permittedSubtreesOtherName); + } + temp += "excluded:\n"; + if (!(excludedSubtreesDN.IsEmpty)) + { + temp += "DN:\n"; + temp += excludedSubtreesDN.ToString() + "\n"; + } + if (!excludedSubtreesDNS.IsEmpty) + { + temp += "DNS:\n"; + temp += excludedSubtreesDNS.ToString() + "\n"; + } + if (!excludedSubtreesEmail.IsEmpty) + { + temp += "Email:\n"; + temp += excludedSubtreesEmail.ToString() + "\n"; + } + if (!excludedSubtreesURI.IsEmpty) + { + temp += "URI:\n"; + temp += excludedSubtreesURI.ToString() + "\n"; + } + if (!excludedSubtreesIP.IsEmpty) + { + temp += "IP:\n"; + temp += StringifyIPCollection(excludedSubtreesIP) + "\n"; + } + if (!excludedSubtreesOtherName.IsEmpty) + { + temp += "OtherName:\n"; + temp += StringifyOtherNameCollection(excludedSubtreesOtherName); + } + return temp; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixNameConstraintValidator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixNameConstraintValidator.cs.meta new file mode 100644 index 0000000..d0cf0b7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixNameConstraintValidator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 89f29584c0c85de45a96b8ddd74953bb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixNameConstraintValidatorException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixNameConstraintValidatorException.cs new file mode 100644 index 0000000..b187525 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixNameConstraintValidatorException.cs @@ -0,0 +1,16 @@ +using System; + +namespace Org.BouncyCastle.Pkix +{ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE) + [Serializable] +#endif + public class PkixNameConstraintValidatorException + : Exception + { + public PkixNameConstraintValidatorException(String msg) + : base(msg) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixNameConstraintValidatorException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixNameConstraintValidatorException.cs.meta new file mode 100644 index 0000000..81f3349 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixNameConstraintValidatorException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b4eff131bb3548741a88155c61aaa275 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixParameters.cs new file mode 100644 index 0000000..01ed9d4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixParameters.cs @@ -0,0 +1,893 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; +using Org.BouncyCastle.Utilities.Date; +using Org.BouncyCastle.X509.Store; + +namespace Org.BouncyCastle.Pkix +{ + /// + /// Summary description for PkixParameters. + /// + public class PkixParameters +// : ICertPathParameters + { + /** + * This is the default PKIX validity model. Actually there are two variants + * of this: The PKIX model and the modified PKIX model. The PKIX model + * verifies that all involved certificates must have been valid at the + * current time. The modified PKIX model verifies that all involved + * certificates were valid at the signing time. Both are indirectly choosen + * with the {@link PKIXParameters#setDate(java.util.Date)} method, so this + * methods sets the Date when all certificates must have been + * valid. + */ + public const int PkixValidityModel = 0; + + /** + * This model uses the following validity model. Each certificate must have + * been valid at the moment where is was used. That means the end + * certificate must have been valid at the time the signature was done. The + * CA certificate which signed the end certificate must have been valid, + * when the end certificate was signed. The CA (or Root CA) certificate must + * have been valid, when the CA certificate was signed and so on. So the + * {@link PKIXParameters#setDate(java.util.Date)} method sets the time, when + * the end certificate must have been valid.

    It is used e.g. + * in the German signature law. + */ + public const int ChainValidityModel = 1; + + private ISet trustAnchors; + private DateTimeObject date; + private IList certPathCheckers; + private bool revocationEnabled = true; + private ISet initialPolicies; + //private bool checkOnlyEECertificateCrl = false; + private bool explicitPolicyRequired = false; + private bool anyPolicyInhibited = false; + private bool policyMappingInhibited = false; + private bool policyQualifiersRejected = true; + private IX509Selector certSelector; + private IList stores; + private IX509Selector selector; + private bool additionalLocationsEnabled; + private IList additionalStores; + private ISet trustedACIssuers; + private ISet necessaryACAttributes; + private ISet prohibitedACAttributes; + private ISet attrCertCheckers; + private int validityModel = PkixValidityModel; + private bool useDeltas = false; + + /** + * Creates an instance of PKIXParameters with the specified Set of + * most-trusted CAs. Each element of the set is a TrustAnchor.
    + *
    + * Note that the Set is copied to protect against subsequent modifications. + * + * @param trustAnchors + * a Set of TrustAnchors + * + * @exception InvalidAlgorithmParameterException + * if the specified Set is empty + * (trustAnchors.isEmpty() == true) + * @exception NullPointerException + * if the specified Set is null + * @exception ClassCastException + * if any of the elements in the Set are not of type + * java.security.cert.TrustAnchor + */ + public PkixParameters( + ISet trustAnchors) + { + SetTrustAnchors(trustAnchors); + + this.initialPolicies = new HashSet(); + this.certPathCheckers = Platform.CreateArrayList(); + this.stores = Platform.CreateArrayList(); + this.additionalStores = Platform.CreateArrayList(); + this.trustedACIssuers = new HashSet(); + this.necessaryACAttributes = new HashSet(); + this.prohibitedACAttributes = new HashSet(); + this.attrCertCheckers = new HashSet(); + } + +// // TODO implement for other keystores (see Java build)? +// /** +// * Creates an instance of PKIXParameters that +// * populates the set of most-trusted CAs from the trusted +// * certificate entries contained in the specified KeyStore. +// * Only keystore entries that contain trusted X509Certificates +// * are considered; all other certificate types are ignored. +// * +// * @param keystore a KeyStore from which the set of +// * most-trusted CAs will be populated +// * @throws KeyStoreException if the keystore has not been initialized +// * @throws InvalidAlgorithmParameterException if the keystore does +// * not contain at least one trusted certificate entry +// * @throws NullPointerException if the keystore is null +// */ +// public PkixParameters( +// Pkcs12Store keystore) +//// throws KeyStoreException, InvalidAlgorithmParameterException +// { +// if (keystore == null) +// throw new ArgumentNullException("keystore"); +// ISet trustAnchors = new HashSet(); +// foreach (string alias in keystore.Aliases) +// { +// if (keystore.IsCertificateEntry(alias)) +// { +// X509CertificateEntry x509Entry = keystore.GetCertificate(alias); +// trustAnchors.Add(new TrustAnchor(x509Entry.Certificate, null)); +// } +// } +// SetTrustAnchors(trustAnchors); +// +// this.initialPolicies = new HashSet(); +// this.certPathCheckers = new ArrayList(); +// this.stores = new ArrayList(); +// this.additionalStores = new ArrayList(); +// this.trustedACIssuers = new HashSet(); +// this.necessaryACAttributes = new HashSet(); +// this.prohibitedACAttributes = new HashSet(); +// this.attrCertCheckers = new HashSet(); +// } + + public virtual bool IsRevocationEnabled + { + get { return revocationEnabled; } + set { revocationEnabled = value; } + } + + public virtual bool IsExplicitPolicyRequired + { + get { return explicitPolicyRequired; } + set { this.explicitPolicyRequired = value; } + } + + public virtual bool IsAnyPolicyInhibited + { + get { return anyPolicyInhibited; } + set { this.anyPolicyInhibited = value; } + } + + public virtual bool IsPolicyMappingInhibited + { + get { return policyMappingInhibited; } + set { this.policyMappingInhibited = value; } + } + + public virtual bool IsPolicyQualifiersRejected + { + get { return policyQualifiersRejected; } + set { this.policyQualifiersRejected = value; } + } + + //public bool IsCheckOnlyEECertificateCrl + //{ + // get { return this.checkOnlyEECertificateCrl; } + // set { this.checkOnlyEECertificateCrl = value; } + //} + + public virtual DateTimeObject Date + { + get { return this.date; } + set { this.date = value; } + } + + // Returns a Set of the most-trusted CAs. + public virtual ISet GetTrustAnchors() + { + return new HashSet(this.trustAnchors); + } + + // Sets the set of most-trusted CAs. + // Set is copied to protect against subsequent modifications. + public virtual void SetTrustAnchors( + ISet tas) + { + if (tas == null) + throw new ArgumentNullException("value"); + if (tas.IsEmpty) + throw new ArgumentException("non-empty set required", "value"); + + // Explicit copy to enforce type-safety + this.trustAnchors = new HashSet(); + foreach (TrustAnchor ta in tas) + { + if (ta != null) + { + trustAnchors.Add(ta); + } + } + } + + /** + * Returns the required constraints on the target certificate. The + * constraints are returned as an instance of CertSelector. If + * null, no constraints are defined.
    + *
    + * Note that the CertSelector returned is cloned to protect against + * subsequent modifications. + * + * @return a CertSelector specifying the constraints on the target + * certificate (or null) + * + * @see #setTargetCertConstraints(CertSelector) + */ + public virtual X509CertStoreSelector GetTargetCertConstraints() + { + if (certSelector == null) + { + return null; + } + + return (X509CertStoreSelector)certSelector.Clone(); + } + + /** + * Sets the required constraints on the target certificate. The constraints + * are specified as an instance of CertSelector. If null, no constraints are + * defined.
    + *
    + * Note that the CertSelector specified is cloned to protect against + * subsequent modifications. + * + * @param selector + * a CertSelector specifying the constraints on the target + * certificate (or null) + * + * @see #getTargetCertConstraints() + */ + public virtual void SetTargetCertConstraints( + IX509Selector selector) + { + if (selector == null) + { + certSelector = null; + } + else + { + certSelector = (IX509Selector)selector.Clone(); + } + } + + /** + * Returns an immutable Set of initial policy identifiers (OID strings), + * indicating that any one of these policies would be acceptable to the + * certificate user for the purposes of certification path processing. The + * default return value is an empty Set, which is + * interpreted as meaning that any policy would be acceptable. + * + * @return an immutable Set of initial policy OIDs in String + * format, or an empty Set (implying any policy is + * acceptable). Never returns null. + * + * @see #setInitialPolicies(java.util.Set) + */ + public virtual ISet GetInitialPolicies() + { + ISet returnSet = initialPolicies; + + // TODO Can it really be null? + if (initialPolicies == null) + { + returnSet = new HashSet(); + } + + return new HashSet(returnSet); + } + + /** + * Sets the Set of initial policy identifiers (OID strings), + * indicating that any one of these policies would be acceptable to the + * certificate user for the purposes of certification path processing. By + * default, any policy is acceptable (i.e. all policies), so a user that + * wants to allow any policy as acceptable does not need to call this + * method, or can call it with an empty Set (or + * null).
    + *
    + * Note that the Set is copied to protect against subsequent modifications.
    + *
    + * + * @param initialPolicies + * a Set of initial policy OIDs in String format (or + * null) + * + * @exception ClassCastException + * if any of the elements in the set are not of type String + * + * @see #getInitialPolicies() + */ + public virtual void SetInitialPolicies( + ISet initialPolicies) + { + this.initialPolicies = new HashSet(); + if (initialPolicies != null) + { + foreach (string obj in initialPolicies) + { + if (obj != null) + { + this.initialPolicies.Add(obj); + } + } + } + } + + /** + * Sets a List of additional certification path checkers. If + * the specified List contains an object that is not a PKIXCertPathChecker, + * it is ignored.
    + *
    + * Each PKIXCertPathChecker specified implements additional + * checks on a certificate. Typically, these are checks to process and + * verify private extensions contained in certificates. Each + * PKIXCertPathChecker should be instantiated with any + * initialization parameters needed to execute the check.
    + *
    + * This method allows sophisticated applications to extend a PKIX + * CertPathValidator or CertPathBuilder. Each + * of the specified PKIXCertPathCheckers will be called, in turn, by a PKIX + * CertPathValidator or CertPathBuilder for + * each certificate processed or validated.
    + *
    + * Regardless of whether these additional PKIXCertPathCheckers are set, a + * PKIX CertPathValidator or CertPathBuilder + * must perform all of the required PKIX checks on each certificate. The one + * exception to this rule is if the RevocationEnabled flag is set to false + * (see the {@link #setRevocationEnabled(boolean) setRevocationEnabled} + * method).
    + *
    + * Note that the List supplied here is copied and each PKIXCertPathChecker + * in the list is cloned to protect against subsequent modifications. + * + * @param checkers + * a List of PKIXCertPathCheckers. May be null, in which case no + * additional checkers will be used. + * @exception ClassCastException + * if any of the elements in the list are not of type + * java.security.cert.PKIXCertPathChecker + * @see #getCertPathCheckers() + */ + public virtual void SetCertPathCheckers(IList checkers) + { + certPathCheckers = Platform.CreateArrayList(); + if (checkers != null) + { + foreach (PkixCertPathChecker obj in checkers) + { + certPathCheckers.Add(obj.Clone()); + } + } + } + + /** + * Returns the List of certification path checkers. Each PKIXCertPathChecker + * in the returned IList is cloned to protect against subsequent modifications. + * + * @return an immutable List of PKIXCertPathCheckers (may be empty, but not + * null) + * + * @see #setCertPathCheckers(java.util.List) + */ + public virtual IList GetCertPathCheckers() + { + IList checkers = Platform.CreateArrayList(); + foreach (PkixCertPathChecker obj in certPathCheckers) + { + checkers.Add(obj.Clone()); + } + return checkers; + } + + /** + * Adds a PKIXCertPathChecker to the list of certification + * path checkers. See the {@link #setCertPathCheckers setCertPathCheckers} + * method for more details. + *

    + * Note that the PKIXCertPathChecker is cloned to protect + * against subsequent modifications.

    + * + * @param checker a PKIXCertPathChecker to add to the list of + * checks. If null, the checker is ignored (not added to list). + */ + public virtual void AddCertPathChecker( + PkixCertPathChecker checker) + { + if (checker != null) + { + certPathCheckers.Add(checker.Clone()); + } + } + + public virtual object Clone() + { + // FIXME Check this whole method against the Java implementation! + + PkixParameters parameters = new PkixParameters(GetTrustAnchors()); + parameters.SetParams(this); + return parameters; + + +// PkixParameters obj = new PkixParameters(new HashSet()); +//// (PkixParameters) this.MemberwiseClone(); +// obj.x509Stores = new ArrayList(x509Stores); +// obj.certPathCheckers = new ArrayList(certPathCheckers); +// +// //Iterator iter = certPathCheckers.iterator(); +// //obj.certPathCheckers = new ArrayList(); +// //while (iter.hasNext()) +// //{ +// // obj.certPathCheckers.add(((PKIXCertPathChecker)iter.next()) +// // .clone()); +// //} +// //if (initialPolicies != null) +// //{ +// // obj.initialPolicies = new HashSet(initialPolicies); +// //} +//// if (trustAnchors != null) +//// { +//// obj.trustAnchors = new HashSet(trustAnchors); +//// } +//// if (certSelector != null) +//// { +//// obj.certSelector = (X509CertStoreSelector) certSelector.Clone(); +//// } +// return obj; + } + + /** + * Method to support Clone() under J2ME. + * super.Clone() does not exist and fields are not copied. + * + * @param params Parameters to set. If this are + * ExtendedPkixParameters they are copied to. + */ + protected virtual void SetParams( + PkixParameters parameters) + { + Date = parameters.Date; + SetCertPathCheckers(parameters.GetCertPathCheckers()); + IsAnyPolicyInhibited = parameters.IsAnyPolicyInhibited; + IsExplicitPolicyRequired = parameters.IsExplicitPolicyRequired; + IsPolicyMappingInhibited = parameters.IsPolicyMappingInhibited; + IsRevocationEnabled = parameters.IsRevocationEnabled; + SetInitialPolicies(parameters.GetInitialPolicies()); + IsPolicyQualifiersRejected = parameters.IsPolicyQualifiersRejected; + SetTargetCertConstraints(parameters.GetTargetCertConstraints()); + SetTrustAnchors(parameters.GetTrustAnchors()); + + validityModel = parameters.validityModel; + useDeltas = parameters.useDeltas; + additionalLocationsEnabled = parameters.additionalLocationsEnabled; + selector = parameters.selector == null ? null + : (IX509Selector) parameters.selector.Clone(); + stores = Platform.CreateArrayList(parameters.stores); + additionalStores = Platform.CreateArrayList(parameters.additionalStores); + trustedACIssuers = new HashSet(parameters.trustedACIssuers); + prohibitedACAttributes = new HashSet(parameters.prohibitedACAttributes); + necessaryACAttributes = new HashSet(parameters.necessaryACAttributes); + attrCertCheckers = new HashSet(parameters.attrCertCheckers); + } + + /** + * Whether delta CRLs should be used for checking the revocation status. + * Defaults to false. + */ + public virtual bool IsUseDeltasEnabled + { + get { return useDeltas; } + set { useDeltas = value; } + } + + /** + * The validity model. + * @see #CHAIN_VALIDITY_MODEL + * @see #PKIX_VALIDITY_MODEL + */ + public virtual int ValidityModel + { + get { return validityModel; } + set { validityModel = value; } + } + + /** + * Sets the Bouncy Castle Stores for finding CRLs, certificates, attribute + * certificates or cross certificates. + *

    + * The IList is cloned. + *

    + * + * @param stores A list of stores to use. + * @see #getStores + * @throws ClassCastException if an element of stores is not + * a {@link Store}. + */ + public virtual void SetStores( + IList stores) + { + if (stores == null) + { + this.stores = Platform.CreateArrayList(); + } + else + { + foreach (object obj in stores) + { + if (!(obj is IX509Store)) + { + throw new InvalidCastException( + "All elements of list must be of type " + typeof(IX509Store).FullName); + } + } + this.stores = Platform.CreateArrayList(stores); + } + } + + /** + * Adds a Bouncy Castle {@link Store} to find CRLs, certificates, attribute + * certificates or cross certificates. + *

    + * This method should be used to add local stores, like collection based + * X.509 stores, if available. Local stores should be considered first, + * before trying to use additional (remote) locations, because they do not + * need possible additional network traffic. + *

    + * If store is null it is ignored. + *

    + * + * @param store The store to add. + * @see #getStores + */ + public virtual void AddStore( + IX509Store store) + { + if (store != null) + { + stores.Add(store); + } + } + + /** + * Adds an additional Bouncy Castle {@link Store} to find CRLs, certificates, + * attribute certificates or cross certificates. + *

    + * You should not use this method. This method is used for adding additional + * X.509 stores, which are used to add (remote) locations, e.g. LDAP, found + * during X.509 object processing, e.g. in certificates or CRLs. This method + * is used in PKIX certification path processing. + *

    + * If store is null it is ignored. + *

    + * + * @param store The store to add. + * @see #getStores() + */ + public virtual void AddAdditionalStore( + IX509Store store) + { + if (store != null) + { + additionalStores.Add(store); + } + } + + /** + * Returns an IList of additional Bouncy Castle + * Stores used for finding CRLs, certificates, attribute + * certificates or cross certificates. + * + * @return an immutable IList of additional Bouncy Castle + * Stores. Never null. + * + * @see #addAddionalStore(Store) + */ + public virtual IList GetAdditionalStores() + { + return Platform.CreateArrayList(additionalStores); + } + + /** + * Returns an IList of Bouncy Castle + * Stores used for finding CRLs, certificates, attribute + * certificates or cross certificates. + * + * @return an immutable IList of Bouncy Castle + * Stores. Never null. + * + * @see #setStores(IList) + */ + public virtual IList GetStores() + { + return Platform.CreateArrayList(stores); + } + + /** + * Returns if additional {@link X509Store}s for locations like LDAP found + * in certificates or CRLs should be used. + * + * @return Returns true if additional stores are used. + */ + public virtual bool IsAdditionalLocationsEnabled + { + get { return additionalLocationsEnabled; } + } + + /** + * Sets if additional {@link X509Store}s for locations like LDAP found in + * certificates or CRLs should be used. + * + * @param enabled true if additional stores are used. + */ + public virtual void SetAdditionalLocationsEnabled( + bool enabled) + { + additionalLocationsEnabled = enabled; + } + + /** + * Returns the required constraints on the target certificate or attribute + * certificate. The constraints are returned as an instance of + * IX509Selector. If null, no constraints are + * defined. + * + *

    + * The target certificate in a PKIX path may be a certificate or an + * attribute certificate. + *

    + * Note that the IX509Selector returned is cloned to protect + * against subsequent modifications. + *

    + * @return a IX509Selector specifying the constraints on the + * target certificate or attribute certificate (or null) + * @see #setTargetConstraints + * @see X509CertStoreSelector + * @see X509AttributeCertStoreSelector + */ + public virtual IX509Selector GetTargetConstraints() + { + if (selector != null) + { + return (IX509Selector) selector.Clone(); + } + else + { + return null; + } + } + + /** + * Sets the required constraints on the target certificate or attribute + * certificate. The constraints are specified as an instance of + * IX509Selector. If null, no constraints are + * defined. + *

    + * The target certificate in a PKIX path may be a certificate or an + * attribute certificate. + *

    + * Note that the IX509Selector specified is cloned to protect + * against subsequent modifications. + *

    + * + * @param selector a IX509Selector specifying the constraints on + * the target certificate or attribute certificate (or + * null) + * @see #getTargetConstraints + * @see X509CertStoreSelector + * @see X509AttributeCertStoreSelector + */ + public virtual void SetTargetConstraints(IX509Selector selector) + { + if (selector != null) + { + this.selector = (IX509Selector) selector.Clone(); + } + else + { + this.selector = null; + } + } + + /** + * Returns the trusted attribute certificate issuers. If attribute + * certificates is verified the trusted AC issuers must be set. + *

    + * The returned ISet consists of TrustAnchors. + *

    + * The returned ISet is immutable. Never null + *

    + * + * @return Returns an immutable set of the trusted AC issuers. + */ + public virtual ISet GetTrustedACIssuers() + { + return new HashSet(trustedACIssuers); + } + + /** + * Sets the trusted attribute certificate issuers. If attribute certificates + * is verified the trusted AC issuers must be set. + *

    + * The trustedACIssuers must be a ISet of + * TrustAnchor + *

    + * The given set is cloned. + *

    + * + * @param trustedACIssuers The trusted AC issuers to set. Is never + * null. + * @throws ClassCastException if an element of stores is not + * a TrustAnchor. + */ + public virtual void SetTrustedACIssuers( + ISet trustedACIssuers) + { + if (trustedACIssuers == null) + { + this.trustedACIssuers = new HashSet(); + } + else + { + foreach (object obj in trustedACIssuers) + { + if (!(obj is TrustAnchor)) + { + throw new InvalidCastException("All elements of set must be " + + "of type " + typeof(TrustAnchor).FullName + "."); + } + } + this.trustedACIssuers = new HashSet(trustedACIssuers); + } + } + + /** + * Returns the necessary attributes which must be contained in an attribute + * certificate. + *

    + * The returned ISet is immutable and contains + * Strings with the OIDs. + *

    + * + * @return Returns the necessary AC attributes. + */ + public virtual ISet GetNecessaryACAttributes() + { + return new HashSet(necessaryACAttributes); + } + + /** + * Sets the necessary which must be contained in an attribute certificate. + *

    + * The ISet must contain Strings with the + * OIDs. + *

    + * The set is cloned. + *

    + * + * @param necessaryACAttributes The necessary AC attributes to set. + * @throws ClassCastException if an element of + * necessaryACAttributes is not a + * String. + */ + public virtual void SetNecessaryACAttributes( + ISet necessaryACAttributes) + { + if (necessaryACAttributes == null) + { + this.necessaryACAttributes = new HashSet(); + } + else + { + foreach (object obj in necessaryACAttributes) + { + if (!(obj is string)) + { + throw new InvalidCastException("All elements of set must be " + + "of type string."); + } + } + this.necessaryACAttributes = new HashSet(necessaryACAttributes); + } + } + + /** + * Returns the attribute certificates which are not allowed. + *

    + * The returned ISet is immutable and contains + * Strings with the OIDs. + *

    + * + * @return Returns the prohibited AC attributes. Is never null. + */ + public virtual ISet GetProhibitedACAttributes() + { + return new HashSet(prohibitedACAttributes); + } + + /** + * Sets the attribute certificates which are not allowed. + *

    + * The ISet must contain Strings with the + * OIDs. + *

    + * The set is cloned. + *

    + * + * @param prohibitedACAttributes The prohibited AC attributes to set. + * @throws ClassCastException if an element of + * prohibitedACAttributes is not a + * String. + */ + public virtual void SetProhibitedACAttributes( + ISet prohibitedACAttributes) + { + if (prohibitedACAttributes == null) + { + this.prohibitedACAttributes = new HashSet(); + } + else + { + foreach (object obj in prohibitedACAttributes) + { + if (!(obj is String)) + { + throw new InvalidCastException("All elements of set must be " + + "of type string."); + } + } + this.prohibitedACAttributes = new HashSet(prohibitedACAttributes); + } + } + + /** + * Returns the attribute certificate checker. The returned set contains + * {@link PKIXAttrCertChecker}s and is immutable. + * + * @return Returns the attribute certificate checker. Is never + * null. + */ + public virtual ISet GetAttrCertCheckers() + { + return new HashSet(attrCertCheckers); + } + + /** + * Sets the attribute certificate checkers. + *

    + * All elements in the ISet must a {@link PKIXAttrCertChecker}. + *

    + *

    + * The given set is cloned. + *

    + * + * @param attrCertCheckers The attribute certificate checkers to set. Is + * never null. + * @throws ClassCastException if an element of attrCertCheckers + * is not a PKIXAttrCertChecker. + */ + public virtual void SetAttrCertCheckers( + ISet attrCertCheckers) + { + if (attrCertCheckers == null) + { + this.attrCertCheckers = new HashSet(); + } + else + { + foreach (object obj in attrCertCheckers) + { + if (!(obj is PkixAttrCertChecker)) + { + throw new InvalidCastException("All elements of set must be " + + "of type " + typeof(PkixAttrCertChecker).FullName + "."); + } + } + this.attrCertCheckers = new HashSet(attrCertCheckers); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixParameters.cs.meta new file mode 100644 index 0000000..96429ba --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9bd320910f1d1744d92361bc60082d27 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixPolicyNode.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixPolicyNode.cs new file mode 100644 index 0000000..fc5b82f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixPolicyNode.cs @@ -0,0 +1,158 @@ +using System; +using System.Collections; +using System.Text; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Pkix +{ + /// + /// Summary description for PkixPolicyNode. + /// + public class PkixPolicyNode +// : IPolicyNode + { + protected IList mChildren; + protected int mDepth; + protected ISet mExpectedPolicies; + protected PkixPolicyNode mParent; + protected ISet mPolicyQualifiers; + protected string mValidPolicy; + protected bool mCritical; + + public virtual int Depth + { + get { return this.mDepth; } + } + + public virtual IEnumerable Children + { + get { return new EnumerableProxy(mChildren); } + } + + public virtual bool IsCritical + { + get { return this.mCritical; } + set { this.mCritical = value; } + } + + public virtual ISet PolicyQualifiers + { + get { return new HashSet(this.mPolicyQualifiers); } + } + + public virtual string ValidPolicy + { + get { return this.mValidPolicy; } + } + + public virtual bool HasChildren + { + get { return mChildren.Count != 0; } + } + + public virtual ISet ExpectedPolicies + { + get { return new HashSet(this.mExpectedPolicies); } + set { this.mExpectedPolicies = new HashSet(value); } + } + + public virtual PkixPolicyNode Parent + { + get { return this.mParent; } + set { this.mParent = value; } + } + + /// Constructors + public PkixPolicyNode( + IList children, + int depth, + ISet expectedPolicies, + PkixPolicyNode parent, + ISet policyQualifiers, + string validPolicy, + bool critical) + { + if (children == null) + { + this.mChildren = Platform.CreateArrayList(); + } + else + { + this.mChildren = Platform.CreateArrayList(children); + } + + this.mDepth = depth; + this.mExpectedPolicies = expectedPolicies; + this.mParent = parent; + this.mPolicyQualifiers = policyQualifiers; + this.mValidPolicy = validPolicy; + this.mCritical = critical; + } + + public virtual void AddChild( + PkixPolicyNode child) + { + child.Parent = this; + mChildren.Add(child); + } + + public virtual void RemoveChild( + PkixPolicyNode child) + { + mChildren.Remove(child); + } + + public override string ToString() + { + return ToString(""); + } + + public virtual string ToString( + string indent) + { + StringBuilder buf = new StringBuilder(); + buf.Append(indent); + buf.Append(mValidPolicy); + buf.Append(" {"); + buf.Append(Platform.NewLine); + + foreach (PkixPolicyNode child in mChildren) + { + buf.Append(child.ToString(indent + " ")); + } + + buf.Append(indent); + buf.Append("}"); + buf.Append(Platform.NewLine); + return buf.ToString(); + } + + public virtual object Clone() + { + return Copy(); + } + + public virtual PkixPolicyNode Copy() + { + PkixPolicyNode node = new PkixPolicyNode( + Platform.CreateArrayList(), + mDepth, + new HashSet(mExpectedPolicies), + null, + new HashSet(mPolicyQualifiers), + mValidPolicy, + mCritical); + + foreach (PkixPolicyNode child in mChildren) + { + PkixPolicyNode copy = child.Copy(); + copy.Parent = node; + node.AddChild(copy); + } + + return node; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixPolicyNode.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixPolicyNode.cs.meta new file mode 100644 index 0000000..5a3f3b8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/PkixPolicyNode.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 291dc550e7aa8a3448fe6b071ad9f85f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/ReasonsMask.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/ReasonsMask.cs new file mode 100644 index 0000000..e389bfe --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/ReasonsMask.cs @@ -0,0 +1,96 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; + +namespace Org.BouncyCastle.Pkix +{ + /// + /// This class helps to handle CRL revocation reasons mask. Each CRL handles a + /// certain set of revocation reasons. + /// + internal class ReasonsMask + { + private int _reasons; + + /// + /// Constructs are reason mask with the reasons. + /// + /// The reasons. + internal ReasonsMask( + int reasons) + { + _reasons = reasons; + } + + /// + /// A reason mask with no reason. + /// + internal ReasonsMask() + : this(0) + { + } + + /// + /// A mask with all revocation reasons. + /// + internal static readonly ReasonsMask AllReasons = new ReasonsMask( + ReasonFlags.AACompromise | ReasonFlags.AffiliationChanged | ReasonFlags.CACompromise + | ReasonFlags.CertificateHold | ReasonFlags.CessationOfOperation + | ReasonFlags.KeyCompromise | ReasonFlags.PrivilegeWithdrawn | ReasonFlags.Unused + | ReasonFlags.Superseded); + + /** + * Adds all reasons from the reasons mask to this mask. + * + * @param mask The reasons mask to add. + */ + internal void AddReasons( + ReasonsMask mask) + { + _reasons = _reasons | mask.Reasons.IntValue; + } + + /// + /// Returns true if this reasons mask contains all possible + /// reasons. + /// + /// true if this reasons mask contains all possible reasons. + /// + internal bool IsAllReasons + { + get { return _reasons == AllReasons._reasons; } + } + + /// + /// Intersects this mask with the given reasons mask. + /// + /// mask The mask to intersect with. + /// The intersection of this and teh given mask. + internal ReasonsMask Intersect( + ReasonsMask mask) + { + ReasonsMask _mask = new ReasonsMask(); + _mask.AddReasons(new ReasonsMask(_reasons & mask.Reasons.IntValue)); + return _mask; + } + + /// + /// Returns true if the passed reasons mask has new reasons. + /// + /// The reasons mask which should be tested for new reasons. + /// true if the passed reasons mask has new reasons. + internal bool HasNewReasons( + ReasonsMask mask) + { + return ((_reasons | mask.Reasons.IntValue ^ _reasons) != 0); + } + + /// + /// Returns the reasons in this mask. + /// + public ReasonFlags Reasons + { + get { return new ReasonFlags(_reasons); } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/ReasonsMask.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/ReasonsMask.cs.meta new file mode 100644 index 0000000..0d1b937 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/ReasonsMask.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8ecd92852d3575640a36c58a7606de41 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/Rfc3280CertPathUtilities.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/Rfc3280CertPathUtilities.cs new file mode 100644 index 0000000..d6594f4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/Rfc3280CertPathUtilities.cs @@ -0,0 +1,2447 @@ +using System; +using System.Collections; +using System.Globalization; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Security.Certificates; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; +using Org.BouncyCastle.Utilities.Date; +using Org.BouncyCastle.X509; +using Org.BouncyCastle.X509.Store; + +namespace Org.BouncyCastle.Pkix +{ + public class Rfc3280CertPathUtilities + { + private static readonly PkixCrlUtilities CrlUtilities = new PkixCrlUtilities(); + + internal static readonly string ANY_POLICY = "2.5.29.32.0"; + + // key usage bits + internal static readonly int KEY_CERT_SIGN = 5; + internal static readonly int CRL_SIGN = 6; + + /** + * If the complete CRL includes an issuing distribution point (IDP) CRL + * extension check the following: + *

    + * (i) If the distribution point name is present in the IDP CRL extension + * and the distribution field is present in the DP, then verify that one of + * the names in the IDP matches one of the names in the DP. If the + * distribution point name is present in the IDP CRL extension and the + * distribution field is omitted from the DP, then verify that one of the + * names in the IDP matches one of the names in the cRLIssuer field of the + * DP. + *

    + *

    + * (ii) If the onlyContainsUserCerts boolean is asserted in the IDP CRL + * extension, verify that the certificate does not include the basic + * constraints extension with the cA boolean asserted. + *

    + *

    + * (iii) If the onlyContainsCACerts boolean is asserted in the IDP CRL + * extension, verify that the certificate includes the basic constraints + * extension with the cA boolean asserted. + *

    + *

    + * (iv) Verify that the onlyContainsAttributeCerts boolean is not asserted. + *

    + * + * @param dp The distribution point. + * @param cert The certificate. + * @param crl The CRL. + * @throws AnnotatedException if one of the conditions is not met or an error occurs. + */ + internal static void ProcessCrlB2( + DistributionPoint dp, + object cert, + X509Crl crl) + { + IssuingDistributionPoint idp = null; + try + { + idp = IssuingDistributionPoint.GetInstance(PkixCertPathValidatorUtilities.GetExtensionValue(crl, X509Extensions.IssuingDistributionPoint)); + } + catch (Exception e) + { + throw new Exception("0 Issuing distribution point extension could not be decoded.", e); + } + // (b) (2) (i) + // distribution point name is present + if (idp != null) + { + if (idp.DistributionPoint != null) + { + // make list of names + DistributionPointName dpName = IssuingDistributionPoint.GetInstance(idp).DistributionPoint; + IList names = Platform.CreateArrayList(); + + if (dpName.PointType == DistributionPointName.FullName) + { + GeneralName[] genNames = GeneralNames.GetInstance(dpName.Name).GetNames(); + for (int j = 0; j < genNames.Length; j++) + { + names.Add(genNames[j]); + } + } + if (dpName.PointType == DistributionPointName.NameRelativeToCrlIssuer) + { + Asn1EncodableVector vec = new Asn1EncodableVector(); + try + { + IEnumerator e = Asn1Sequence.GetInstance( + Asn1Sequence.FromByteArray(crl.IssuerDN.GetEncoded())).GetEnumerator(); + while (e.MoveNext()) + { + vec.Add((Asn1Encodable)e.Current); + } + } + catch (IOException e) + { + throw new Exception("Could not read CRL issuer.", e); + } + vec.Add(dpName.Name); + names.Add(new GeneralName(X509Name.GetInstance(new DerSequence(vec)))); + } + bool matches = false; + // verify that one of the names in the IDP matches one + // of the names in the DP. + if (dp.DistributionPointName != null) + { + dpName = dp.DistributionPointName; + GeneralName[] genNames = null; + if (dpName.PointType == DistributionPointName.FullName) + { + genNames = GeneralNames.GetInstance(dpName.Name).GetNames(); + } + if (dpName.PointType == DistributionPointName.NameRelativeToCrlIssuer) + { + if (dp.CrlIssuer != null) + { + genNames = dp.CrlIssuer.GetNames(); + } + else + { + genNames = new GeneralName[1]; + try + { + genNames[0] = new GeneralName( + PkixCertPathValidatorUtilities.GetIssuerPrincipal(cert)); + } + catch (IOException e) + { + throw new Exception("Could not read certificate issuer.", e); + } + } + for (int j = 0; j < genNames.Length; j++) + { + IEnumerator e = Asn1Sequence.GetInstance(genNames[j].Name.ToAsn1Object()).GetEnumerator(); + Asn1EncodableVector vec = new Asn1EncodableVector(); + while (e.MoveNext()) + { + vec.Add((Asn1Encodable)e.Current); + } + vec.Add(dpName.Name); + genNames[j] = new GeneralName(X509Name.GetInstance(new DerSequence(vec))); + } + } + if (genNames != null) + { + for (int j = 0; j < genNames.Length; j++) + { + if (names.Contains(genNames[j])) + { + matches = true; + break; + } + } + } + if (!matches) + { + throw new Exception( + "No match for certificate CRL issuing distribution point name to cRLIssuer CRL distribution point."); + } + } + // verify that one of the names in + // the IDP matches one of the names in the cRLIssuer field of + // the DP + else + { + if (dp.CrlIssuer == null) + { + throw new Exception("Either the cRLIssuer or the distributionPoint field must " + + "be contained in DistributionPoint."); + } + GeneralName[] genNames = dp.CrlIssuer.GetNames(); + for (int j = 0; j < genNames.Length; j++) + { + if (names.Contains(genNames[j])) + { + matches = true; + break; + } + } + if (!matches) + { + throw new Exception( + "No match for certificate CRL issuing distribution point name to cRLIssuer CRL distribution point."); + } + } + } + BasicConstraints bc = null; + try + { + bc = BasicConstraints.GetInstance(PkixCertPathValidatorUtilities.GetExtensionValue( + (IX509Extension)cert, X509Extensions.BasicConstraints)); + } + catch (Exception e) + { + throw new Exception("Basic constraints extension could not be decoded.", e); + } + + //if (cert is X509Certificate) + { + // (b) (2) (ii) + if (idp.OnlyContainsUserCerts && ((bc != null) && bc.IsCA())) + { + throw new Exception("CA Cert CRL only contains user certificates."); + } + + // (b) (2) (iii) + if (idp.OnlyContainsCACerts && (bc == null || !bc.IsCA())) + { + throw new Exception("End CRL only contains CA certificates."); + } + } + + // (b) (2) (iv) + if (idp.OnlyContainsAttributeCerts) + { + throw new Exception("onlyContainsAttributeCerts boolean is asserted."); + } + } + } + + internal static void ProcessCertBC( + PkixCertPath certPath, + int index, + PkixNameConstraintValidator nameConstraintValidator) + //throws CertPathValidatorException + { + IList certs = certPath.Certificates; + X509Certificate cert = (X509Certificate)certs[index]; + int n = certs.Count; + // i as defined in the algorithm description + int i = n - index; + // + // (b), (c) permitted and excluded subtree checking. + // + if (!(PkixCertPathValidatorUtilities.IsSelfIssued(cert) && (i < n))) + { + X509Name principal = cert.SubjectDN; + Asn1Sequence dns; + + try + { + dns = Asn1Sequence.GetInstance(principal.GetEncoded()); + } + catch (Exception e) + { + throw new PkixCertPathValidatorException( + "Exception extracting subject name when checking subtrees.", e, certPath, index); + } + + try + { + nameConstraintValidator.CheckPermittedDN(dns); + nameConstraintValidator.CheckExcludedDN(dns); + } + catch (PkixNameConstraintValidatorException e) + { + throw new PkixCertPathValidatorException( + "Subtree check for certificate subject failed.", e, certPath, index); + } + + GeneralNames altName = null; + try + { + altName = GeneralNames.GetInstance( + PkixCertPathValidatorUtilities.GetExtensionValue(cert, X509Extensions.SubjectAlternativeName)); + } + catch (Exception e) + { + throw new PkixCertPathValidatorException( + "Subject alternative name extension could not be decoded.", e, certPath, index); + } + + IList emails = X509Name.GetInstance(dns).GetValueList(X509Name.EmailAddress); + foreach (string email in emails) + { + GeneralName emailAsGeneralName = new GeneralName(GeneralName.Rfc822Name, email); + try + { + nameConstraintValidator.checkPermitted(emailAsGeneralName); + nameConstraintValidator.checkExcluded(emailAsGeneralName); + } + catch (PkixNameConstraintValidatorException ex) + { + throw new PkixCertPathValidatorException( + "Subtree check for certificate subject alternative email failed.", ex, certPath, index); + } + } + if (altName != null) + { + GeneralName[] genNames = null; + try + { + genNames = altName.GetNames(); + } + catch (Exception e) + { + throw new PkixCertPathValidatorException( + "Subject alternative name contents could not be decoded.", e, certPath, index); + } + foreach (GeneralName genName in genNames) + { + try + { + nameConstraintValidator.checkPermitted(genName); + nameConstraintValidator.checkExcluded(genName); + } + catch (PkixNameConstraintValidatorException e) + { + throw new PkixCertPathValidatorException( + "Subtree check for certificate subject alternative name failed.", e, certPath, index); + } + } + } + } + } + + internal static void PrepareNextCertA( + PkixCertPath certPath, + int index) + //throws CertPathValidatorException + { + IList certs = certPath.Certificates; + X509Certificate cert = (X509Certificate)certs[index]; + // + // + // (a) check the policy mappings + // + Asn1Sequence pm = null; + try + { + pm = Asn1Sequence.GetInstance( + PkixCertPathValidatorUtilities.GetExtensionValue(cert, X509Extensions.PolicyMappings)); + } + catch (Exception ex) + { + throw new PkixCertPathValidatorException( + "Policy mappings extension could not be decoded.", ex, certPath, index); + } + if (pm != null) + { + Asn1Sequence mappings = pm; + + for (int j = 0; j < mappings.Count; j++) + { + DerObjectIdentifier issuerDomainPolicy = null; + DerObjectIdentifier subjectDomainPolicy = null; + try + { + Asn1Sequence mapping = Asn1Sequence.GetInstance(mappings[j]); + + issuerDomainPolicy = DerObjectIdentifier.GetInstance(mapping[0]); + subjectDomainPolicy = DerObjectIdentifier.GetInstance(mapping[1]); + } + catch (Exception e) + { + throw new PkixCertPathValidatorException( + "Policy mappings extension contents could not be decoded.", e, certPath, index); + } + + if (Rfc3280CertPathUtilities.ANY_POLICY.Equals(issuerDomainPolicy.Id)) + throw new PkixCertPathValidatorException( + "IssuerDomainPolicy is anyPolicy", null, certPath, index); + + if (Rfc3280CertPathUtilities.ANY_POLICY.Equals(subjectDomainPolicy.Id)) + throw new PkixCertPathValidatorException( + "SubjectDomainPolicy is anyPolicy,", null, certPath, index); + } + } + } + + internal static PkixPolicyNode ProcessCertD( + PkixCertPath certPath, + int index, + ISet acceptablePolicies, + PkixPolicyNode validPolicyTree, + IList[] policyNodes, + int inhibitAnyPolicy) + //throws CertPathValidatorException + { + IList certs = certPath.Certificates; + X509Certificate cert = (X509Certificate)certs[index]; + int n = certs.Count; + // i as defined in the algorithm description + int i = n - index; + // + // (d) policy Information checking against initial policy and + // policy mapping + // + Asn1Sequence certPolicies = null; + try + { + certPolicies = Asn1Sequence.GetInstance( + PkixCertPathValidatorUtilities.GetExtensionValue(cert, X509Extensions.CertificatePolicies)); + } + catch (Exception e) + { + throw new PkixCertPathValidatorException( + "Could not read certificate policies extension from certificate.", e, certPath, index); + } + if (certPolicies != null && validPolicyTree != null) + { + // + // (d) (1) + // + ISet pols = new HashSet(); + + foreach (Asn1Encodable ae in certPolicies) + { + PolicyInformation pInfo = PolicyInformation.GetInstance(ae.ToAsn1Object()); + DerObjectIdentifier pOid = pInfo.PolicyIdentifier; + + pols.Add(pOid.Id); + + if (!Rfc3280CertPathUtilities.ANY_POLICY.Equals(pOid.Id)) + { + ISet pq = null; + try + { + pq = PkixCertPathValidatorUtilities.GetQualifierSet(pInfo.PolicyQualifiers); + } + catch (PkixCertPathValidatorException ex) + { + throw new PkixCertPathValidatorException( + "Policy qualifier info set could not be build.", ex, certPath, index); + } + + bool match = PkixCertPathValidatorUtilities.ProcessCertD1i(i, policyNodes, pOid, pq); + + if (!match) + { + PkixCertPathValidatorUtilities.ProcessCertD1ii(i, policyNodes, pOid, pq); + } + } + } + + if (acceptablePolicies.IsEmpty || acceptablePolicies.Contains(Rfc3280CertPathUtilities.ANY_POLICY)) + { + acceptablePolicies.Clear(); + acceptablePolicies.AddAll(pols); + } + else + { + ISet t1 = new HashSet(); + + foreach (object o in acceptablePolicies) + { + if (pols.Contains(o)) + { + t1.Add(o); + } + } + acceptablePolicies.Clear(); + acceptablePolicies.AddAll(t1); + } + + // + // (d) (2) + // + if ((inhibitAnyPolicy > 0) || ((i < n) && PkixCertPathValidatorUtilities.IsSelfIssued(cert))) + { + foreach (Asn1Encodable ae in certPolicies) + { + PolicyInformation pInfo = PolicyInformation.GetInstance(ae.ToAsn1Object()); + if (Rfc3280CertPathUtilities.ANY_POLICY.Equals(pInfo.PolicyIdentifier.Id)) + { + ISet _apq = PkixCertPathValidatorUtilities.GetQualifierSet(pInfo.PolicyQualifiers); + IList _nodes = policyNodes[i - 1]; + + for (int k = 0; k < _nodes.Count; k++) + { + PkixPolicyNode _node = (PkixPolicyNode)_nodes[k]; + + IEnumerator _policySetIter = _node.ExpectedPolicies.GetEnumerator(); + while (_policySetIter.MoveNext()) + { + object _tmp = _policySetIter.Current; + + string _policy; + if (_tmp is string) + { + _policy = (string)_tmp; + } + else if (_tmp is DerObjectIdentifier) + { + _policy = ((DerObjectIdentifier)_tmp).Id; + } + else + { + continue; + } + + bool _found = false; + + foreach (PkixPolicyNode _child in _node.Children) + { + if (_policy.Equals(_child.ValidPolicy)) + { + _found = true; + } + } + + if (!_found) + { + ISet _newChildExpectedPolicies = new HashSet(); + _newChildExpectedPolicies.Add(_policy); + + PkixPolicyNode _newChild = new PkixPolicyNode(Platform.CreateArrayList(), i, + _newChildExpectedPolicies, _node, _apq, _policy, false); + _node.AddChild(_newChild); + policyNodes[i].Add(_newChild); + } + } + } + break; + } + } + } + + PkixPolicyNode _validPolicyTree = validPolicyTree; + // + // (d) (3) + // + for (int j = (i - 1); j >= 0; j--) + { + IList nodes = policyNodes[j]; + + for (int k = 0; k < nodes.Count; k++) + { + PkixPolicyNode node = (PkixPolicyNode)nodes[k]; + if (!node.HasChildren) + { + _validPolicyTree = PkixCertPathValidatorUtilities.RemovePolicyNode(_validPolicyTree, policyNodes, + node); + if (_validPolicyTree == null) + { + break; + } + } + } + } + + // + // d (4) + // + ISet criticalExtensionOids = cert.GetCriticalExtensionOids(); + + if (criticalExtensionOids != null) + { + bool critical = criticalExtensionOids.Contains(X509Extensions.CertificatePolicies.Id); + + IList nodes = policyNodes[i]; + for (int j = 0; j < nodes.Count; j++) + { + PkixPolicyNode node = (PkixPolicyNode)nodes[j]; + node.IsCritical = critical; + } + } + return _validPolicyTree; + } + return null; + } + + /** + * If the DP includes cRLIssuer, then verify that the issuer field in the + * complete CRL matches cRLIssuer in the DP and that the complete CRL + * contains an + * g distribution point extension with the indirectCRL + * boolean asserted. Otherwise, verify that the CRL issuer matches the + * certificate issuer. + * + * @param dp The distribution point. + * @param cert The certificate ot attribute certificate. + * @param crl The CRL for cert. + * @throws AnnotatedException if one of the above conditions does not apply or an error + * occurs. + */ + internal static void ProcessCrlB1( + DistributionPoint dp, + object cert, + X509Crl crl) + { + Asn1Object idp = PkixCertPathValidatorUtilities.GetExtensionValue( + crl, X509Extensions.IssuingDistributionPoint); + + bool isIndirect = false; + if (idp != null) + { + if (IssuingDistributionPoint.GetInstance(idp).IsIndirectCrl) + { + isIndirect = true; + } + } + byte[] issuerBytes = crl.IssuerDN.GetEncoded(); + + bool matchIssuer = false; + if (dp.CrlIssuer != null) + { + GeneralName[] genNames = dp.CrlIssuer.GetNames(); + for (int j = 0; j < genNames.Length; j++) + { + if (genNames[j].TagNo == GeneralName.DirectoryName) + { + try + { + if (Org.BouncyCastle.Utilities.Arrays.AreEqual(genNames[j].Name.ToAsn1Object().GetEncoded(), issuerBytes)) + { + matchIssuer = true; + } + } + catch (IOException e) + { + throw new Exception( + "CRL issuer information from distribution point cannot be decoded.", e); + } + } + } + if (matchIssuer && !isIndirect) + { + throw new Exception("Distribution point contains cRLIssuer field but CRL is not indirect."); + } + if (!matchIssuer) + { + throw new Exception("CRL issuer of CRL does not match CRL issuer of distribution point."); + } + } + else + { + if (crl.IssuerDN.Equivalent(PkixCertPathValidatorUtilities.GetIssuerPrincipal(cert), true)) + { + matchIssuer = true; + } + } + if (!matchIssuer) + { + throw new Exception("Cannot find matching CRL issuer for certificate."); + } + } + + internal static ReasonsMask ProcessCrlD( + X509Crl crl, + DistributionPoint dp) + //throws AnnotatedException + { + IssuingDistributionPoint idp = null; + try + { + idp = IssuingDistributionPoint.GetInstance(PkixCertPathValidatorUtilities.GetExtensionValue(crl, X509Extensions.IssuingDistributionPoint)); + } + catch (Exception e) + { + throw new Exception("issuing distribution point extension could not be decoded.", e); + } + + // (d) (1) + if (idp != null && idp.OnlySomeReasons != null && dp.Reasons != null) + { + return new ReasonsMask(dp.Reasons.IntValue).Intersect(new ReasonsMask(idp.OnlySomeReasons + .IntValue)); + } + // (d) (4) + if ((idp == null || idp.OnlySomeReasons == null) && dp.Reasons == null) + { + return ReasonsMask.AllReasons; + } + + // (d) (2) and (d)(3) + + ReasonsMask dpReasons = null; + + if (dp.Reasons == null) + { + dpReasons = ReasonsMask.AllReasons; + } + else + { + dpReasons = new ReasonsMask(dp.Reasons.IntValue); + } + + ReasonsMask idpReasons = null; + + if (idp == null) + { + idpReasons = ReasonsMask.AllReasons; + } + else + { + idpReasons = new ReasonsMask(idp.OnlySomeReasons.IntValue); + } + + return dpReasons.Intersect(idpReasons); + } + + /** + * Obtain and validate the certification path for the complete CRL issuer. + * If a key usage extension is present in the CRL issuer's certificate, + * verify that the cRLSign bit is set. + * + * @param crl CRL which contains revocation information for the certificate + * cert. + * @param cert The attribute certificate or certificate to check if it is + * revoked. + * @param defaultCRLSignCert The issuer certificate of the certificate cert. + * @param defaultCRLSignKey The public key of the issuer certificate + * defaultCRLSignCert. + * @param paramsPKIX paramsPKIX PKIX parameters. + * @param certPathCerts The certificates on the certification path. + * @return A Set with all keys of possible CRL issuer + * certificates. + * @throws AnnotatedException if the CRL is not valid or the status cannot be checked or + * some error occurs. + */ + internal static ISet ProcessCrlF( + X509Crl crl, + object cert, + X509Certificate defaultCRLSignCert, + AsymmetricKeyParameter defaultCRLSignKey, + PkixParameters paramsPKIX, + IList certPathCerts) + { + // (f) + + // get issuer from CRL + X509CertStoreSelector selector = new X509CertStoreSelector(); + try + { + selector.Subject = crl.IssuerDN; + } + catch (IOException e) + { + throw new Exception( + "Subject criteria for certificate selector to find issuer certificate for CRL could not be set.", e); + } + + // get CRL signing certs + IList coll = Platform.CreateArrayList(); + + try + { + CollectionUtilities.AddRange(coll, PkixCertPathValidatorUtilities.FindCertificates(selector, paramsPKIX.GetStores())); + CollectionUtilities.AddRange(coll, PkixCertPathValidatorUtilities.FindCertificates(selector, paramsPKIX.GetAdditionalStores())); + } + catch (Exception e) + { + throw new Exception("Issuer certificate for CRL cannot be searched.", e); + } + + coll.Add(defaultCRLSignCert); + + IEnumerator cert_it = coll.GetEnumerator(); + + IList validCerts = Platform.CreateArrayList(); + IList validKeys = Platform.CreateArrayList(); + + while (cert_it.MoveNext()) + { + X509Certificate signingCert = (X509Certificate)cert_it.Current; + + /* + * CA of the certificate, for which this CRL is checked, has also + * signed CRL, so skip the path validation, because is already done + */ + if (signingCert.Equals(defaultCRLSignCert)) + { + validCerts.Add(signingCert); + validKeys.Add(defaultCRLSignKey); + continue; + } + try + { +// CertPathBuilder builder = CertPathBuilder.GetInstance("PKIX"); + PkixCertPathBuilder builder = new PkixCertPathBuilder(); + selector = new X509CertStoreSelector(); + selector.Certificate = signingCert; + + PkixParameters temp = (PkixParameters)paramsPKIX.Clone(); + temp.SetTargetCertConstraints(selector); + + PkixBuilderParameters parameters = (PkixBuilderParameters) + PkixBuilderParameters.GetInstance(temp); + + /* + * if signingCert is placed not higher on the cert path a + * dependency loop results. CRL for cert is checked, but + * signingCert is needed for checking the CRL which is dependent + * on checking cert because it is higher in the cert path and so + * signing signingCert transitively. so, revocation is disabled, + * forgery attacks of the CRL are detected in this outer loop + * for all other it must be enabled to prevent forgery attacks + */ + if (certPathCerts.Contains(signingCert)) + { + parameters.IsRevocationEnabled = false; + } + else + { + parameters.IsRevocationEnabled = true; + } + IList certs = builder.Build(parameters).CertPath.Certificates; + validCerts.Add(signingCert); + validKeys.Add(PkixCertPathValidatorUtilities.GetNextWorkingKey(certs, 0)); + } + catch (PkixCertPathBuilderException e) + { + throw new Exception("CertPath for CRL signer failed to validate.", e); + } + catch (PkixCertPathValidatorException e) + { + throw new Exception("Public key of issuer certificate of CRL could not be retrieved.", e); + } + //catch (Exception e) + //{ + // throw new Exception(e.Message); + //} + } + + ISet checkKeys = new HashSet(); + + Exception lastException = null; + for (int i = 0; i < validCerts.Count; i++) + { + X509Certificate signCert = (X509Certificate)validCerts[i]; + bool[] keyusage = signCert.GetKeyUsage(); + + if (keyusage != null && (keyusage.Length < 7 || !keyusage[CRL_SIGN])) + { + lastException = new Exception( + "Issuer certificate key usage extension does not permit CRL signing."); + } + else + { + checkKeys.Add(validKeys[i]); + } + } + + if ((checkKeys.Count == 0) && lastException == null) + { + throw new Exception("Cannot find a valid issuer certificate."); + } + if ((checkKeys.Count == 0) && lastException != null) + { + throw lastException; + } + + return checkKeys; + } + + internal static AsymmetricKeyParameter ProcessCrlG( + X509Crl crl, + ISet keys) + { + Exception lastException = null; + foreach (AsymmetricKeyParameter key in keys) + { + try + { + crl.Verify(key); + return key; + } + catch (Exception e) + { + lastException = e; + } + } + throw new Exception("Cannot verify CRL.", lastException); + } + + internal static X509Crl ProcessCrlH( + ISet deltaCrls, + AsymmetricKeyParameter key) + { + Exception lastException = null; + foreach (X509Crl crl in deltaCrls) + { + try + { + crl.Verify(key); + return crl; + } + catch (Exception e) + { + lastException = e; + } + } + if (lastException != null) + { + throw new Exception("Cannot verify delta CRL.", lastException); + } + return null; + } + + /** + * Checks a distribution point for revocation information for the + * certificate cert. + * + * @param dp The distribution point to consider. + * @param paramsPKIX PKIX parameters. + * @param cert Certificate to check if it is revoked. + * @param validDate The date when the certificate revocation status should be + * checked. + * @param defaultCRLSignCert The issuer certificate of the certificate cert. + * @param defaultCRLSignKey The public key of the issuer certificate + * defaultCRLSignCert. + * @param certStatus The current certificate revocation status. + * @param reasonMask The reasons mask which is already checked. + * @param certPathCerts The certificates of the certification path. + * @throws AnnotatedException if the certificate is revoked or the status cannot be checked + * or some error occurs. + */ + private static void CheckCrl( + DistributionPoint dp, + PkixParameters paramsPKIX, + X509Certificate cert, + DateTime validDate, + X509Certificate defaultCRLSignCert, + AsymmetricKeyParameter defaultCRLSignKey, + CertStatus certStatus, + ReasonsMask reasonMask, + IList certPathCerts) + //throws AnnotatedException + { + DateTime currentDate = DateTime.UtcNow; + + if (validDate.Ticks > currentDate.Ticks) + { + throw new Exception("Validation time is in future."); + } + + // (a) + /* + * We always get timely valid CRLs, so there is no step (a) (1). + * "locally cached" CRLs are assumed to be in getStore(), additional + * CRLs must be enabled in the ExtendedPKIXParameters and are in + * getAdditionalStore() + */ + + ISet crls = PkixCertPathValidatorUtilities.GetCompleteCrls(dp, cert, currentDate, paramsPKIX); + bool validCrlFound = false; + Exception lastException = null; + + IEnumerator crl_iter = crls.GetEnumerator(); + + while (crl_iter.MoveNext() && certStatus.Status == CertStatus.Unrevoked && !reasonMask.IsAllReasons) + { + try + { + X509Crl crl = (X509Crl)crl_iter.Current; + + // (d) + ReasonsMask interimReasonsMask = Rfc3280CertPathUtilities.ProcessCrlD(crl, dp); + + // (e) + /* + * The reasons mask is updated at the end, so only valid CRLs + * can update it. If this CRL does not contain new reasons it + * must be ignored. + */ + if (!interimReasonsMask.HasNewReasons(reasonMask)) + { + continue; + } + + // (f) + ISet keys = Rfc3280CertPathUtilities.ProcessCrlF(crl, cert, defaultCRLSignCert, defaultCRLSignKey, + paramsPKIX, certPathCerts); + // (g) + AsymmetricKeyParameter key = Rfc3280CertPathUtilities.ProcessCrlG(crl, keys); + + X509Crl deltaCRL = null; + + if (paramsPKIX.IsUseDeltasEnabled) + { + // get delta CRLs + ISet deltaCRLs = PkixCertPathValidatorUtilities.GetDeltaCrls(currentDate, paramsPKIX, crl); + // we only want one valid delta CRL + // (h) + deltaCRL = Rfc3280CertPathUtilities.ProcessCrlH(deltaCRLs, key); + } + + /* + * CRL must be be valid at the current time, not the validation + * time. If a certificate is revoked with reason keyCompromise, + * cACompromise, it can be used for forgery, also for the past. + * This reason may not be contained in older CRLs. + */ + + /* + * in the chain model signatures stay valid also after the + * certificate has been expired, so they do not have to be in + * the CRL validity time + */ + + if (paramsPKIX.ValidityModel != PkixParameters.ChainValidityModel) + { + /* + * if a certificate has expired, but was revoked, it is not + * more in the CRL, so it would be regarded as valid if the + * first check is not done + */ + if (cert.NotAfter.Ticks < crl.ThisUpdate.Ticks) + { + throw new Exception("No valid CRL for current time found."); + } + } + + Rfc3280CertPathUtilities.ProcessCrlB1(dp, cert, crl); + + // (b) (2) + Rfc3280CertPathUtilities.ProcessCrlB2(dp, cert, crl); + + // (c) + Rfc3280CertPathUtilities.ProcessCrlC(deltaCRL, crl, paramsPKIX); + + // (i) + Rfc3280CertPathUtilities.ProcessCrlI(validDate, deltaCRL, cert, certStatus, paramsPKIX); + + // (j) + Rfc3280CertPathUtilities.ProcessCrlJ(validDate, crl, cert, certStatus); + + // (k) + if (certStatus.Status == CrlReason.RemoveFromCrl) + { + certStatus.Status = CertStatus.Unrevoked; + } + + // update reasons mask + reasonMask.AddReasons(interimReasonsMask); + + ISet criticalExtensions = crl.GetCriticalExtensionOids(); + + if (criticalExtensions != null) + { + criticalExtensions = new HashSet(criticalExtensions); + criticalExtensions.Remove(X509Extensions.IssuingDistributionPoint.Id); + criticalExtensions.Remove(X509Extensions.DeltaCrlIndicator.Id); + + if (!criticalExtensions.IsEmpty) + throw new Exception("CRL contains unsupported critical extensions."); + } + + if (deltaCRL != null) + { + criticalExtensions = deltaCRL.GetCriticalExtensionOids(); + if (criticalExtensions != null) + { + criticalExtensions = new HashSet(criticalExtensions); + criticalExtensions.Remove(X509Extensions.IssuingDistributionPoint.Id); + criticalExtensions.Remove(X509Extensions.DeltaCrlIndicator.Id); + + if (!criticalExtensions.IsEmpty) + throw new Exception("Delta CRL contains unsupported critical extension."); + } + } + + validCrlFound = true; + } + catch (Exception e) + { + lastException = e; + } + } + if (!validCrlFound) + { + throw lastException; + } + } + + /** + * Checks a certificate if it is revoked. + * + * @param paramsPKIX PKIX parameters. + * @param cert Certificate to check if it is revoked. + * @param validDate The date when the certificate revocation status should be + * checked. + * @param sign The issuer certificate of the certificate cert. + * @param workingPublicKey The public key of the issuer certificate sign. + * @param certPathCerts The certificates of the certification path. + * @throws AnnotatedException if the certificate is revoked or the status cannot be checked + * or some error occurs. + */ + protected static void CheckCrls( + PkixParameters paramsPKIX, + X509Certificate cert, + DateTime validDate, + X509Certificate sign, + AsymmetricKeyParameter workingPublicKey, + IList certPathCerts) + { + Exception lastException = null; + CrlDistPoint crldp = null; + + try + { + crldp = CrlDistPoint.GetInstance(PkixCertPathValidatorUtilities.GetExtensionValue(cert, X509Extensions.CrlDistributionPoints)); + } + catch (Exception e) + { + throw new Exception("CRL distribution point extension could not be read.", e); + } + + try + { + PkixCertPathValidatorUtilities.AddAdditionalStoresFromCrlDistributionPoint(crldp, paramsPKIX); + } + catch (Exception e) + { + throw new Exception( + "No additional CRL locations could be decoded from CRL distribution point extension.", e); + } + CertStatus certStatus = new CertStatus(); + ReasonsMask reasonsMask = new ReasonsMask(); + + bool validCrlFound = false; + + // for each distribution point + if (crldp != null) + { + DistributionPoint[] dps = null; + try + { + dps = crldp.GetDistributionPoints(); + } + catch (Exception e) + { + throw new Exception("Distribution points could not be read.", e); + } + if (dps != null) + { + for (int i = 0; i < dps.Length && certStatus.Status == CertStatus.Unrevoked && !reasonsMask.IsAllReasons; i++) + { + PkixParameters paramsPKIXClone = (PkixParameters)paramsPKIX.Clone(); + try + { + CheckCrl(dps[i], paramsPKIXClone, cert, validDate, sign, workingPublicKey, certStatus, reasonsMask, certPathCerts); + validCrlFound = true; + } + catch (Exception e) + { + lastException = e; + } + } + } + } + + /* + * If the revocation status has not been determined, repeat the process + * above with any available CRLs not specified in a distribution point + * but issued by the certificate issuer. + */ + + if (certStatus.Status == CertStatus.Unrevoked && !reasonsMask.IsAllReasons) + { + try + { + /* + * assume a DP with both the reasons and the cRLIssuer fields + * omitted and a distribution point name of the certificate + * issuer. + */ + X509Name issuer; + try + { + issuer = X509Name.GetInstance(cert.IssuerDN.GetEncoded()); + } + catch (Exception e) + { + throw new Exception("Issuer from certificate for CRL could not be reencoded.", e); + } + DistributionPoint dp = new DistributionPoint(new DistributionPointName(0, new GeneralNames( + new GeneralName(GeneralName.DirectoryName, issuer))), null, null); + PkixParameters paramsPKIXClone = (PkixParameters)paramsPKIX.Clone(); + + CheckCrl(dp, paramsPKIXClone, cert, validDate, sign, workingPublicKey, certStatus, reasonsMask, + certPathCerts); + + validCrlFound = true; + } + catch (Exception e) + { + lastException = e; + } + } + + if (!validCrlFound) + { + throw lastException; + } + if (certStatus.Status != CertStatus.Unrevoked) + { + // This format is enforced by the NistCertPath tests + string formattedDate = certStatus.RevocationDate.Value.ToString( + "ddd MMM dd HH:mm:ss K yyyy"); + string message = "Certificate revocation after " + formattedDate; + message += ", reason: " + CrlReasons[certStatus.Status]; + throw new Exception(message); + } + + if (!reasonsMask.IsAllReasons && certStatus.Status == CertStatus.Unrevoked) + { + certStatus.Status = CertStatus.Undetermined; + } + + if (certStatus.Status == CertStatus.Undetermined) + { + throw new Exception("Certificate status could not be determined."); + } + } + + internal static PkixPolicyNode PrepareCertB( + PkixCertPath certPath, + int index, + IList[] policyNodes, + PkixPolicyNode validPolicyTree, + int policyMapping) + //throws CertPathValidatorException + { + IList certs = certPath.Certificates; + X509Certificate cert = (X509Certificate)certs[index]; + int n = certs.Count; + // i as defined in the algorithm description + int i = n - index; + // (b) + // + Asn1Sequence pm = null; + try + { + pm = (Asn1Sequence)Asn1Sequence.GetInstance(PkixCertPathValidatorUtilities.GetExtensionValue(cert, X509Extensions.PolicyMappings)); + } + catch (Exception ex) + { + throw new PkixCertPathValidatorException( + "Policy mappings extension could not be decoded.", ex, certPath, index); + } + PkixPolicyNode _validPolicyTree = validPolicyTree; + if (pm != null) + { + Asn1Sequence mappings = (Asn1Sequence)pm; + IDictionary m_idp = Platform.CreateHashtable(); + ISet s_idp = new HashSet(); + + for (int j = 0; j < mappings.Count; j++) + { + Asn1Sequence mapping = (Asn1Sequence) mappings[j]; + string id_p = ((DerObjectIdentifier) mapping[0]).Id; + string sd_p = ((DerObjectIdentifier) mapping[1]).Id; + ISet tmp; + + if (!m_idp.Contains(id_p)) + { + tmp = new HashSet(); + tmp.Add(sd_p); + m_idp[id_p] = tmp; + s_idp.Add(id_p); + } + else + { + tmp = (ISet)m_idp[id_p]; + tmp.Add(sd_p); + } + } + + IEnumerator it_idp = s_idp.GetEnumerator(); + while (it_idp.MoveNext()) + { + string id_p = (string)it_idp.Current; + + // + // (1) + // + if (policyMapping > 0) + { + bool idp_found = false; + IEnumerator nodes_i = policyNodes[i].GetEnumerator(); + + while (nodes_i.MoveNext()) + { + PkixPolicyNode node = (PkixPolicyNode)nodes_i.Current; + if (node.ValidPolicy.Equals(id_p)) + { + idp_found = true; + node.ExpectedPolicies = (ISet)m_idp[id_p]; + break; + } + } + + if (!idp_found) + { + nodes_i = policyNodes[i].GetEnumerator(); + while (nodes_i.MoveNext()) + { + PkixPolicyNode node = (PkixPolicyNode)nodes_i.Current; + if (Rfc3280CertPathUtilities.ANY_POLICY.Equals(node.ValidPolicy)) + { + ISet pq = null; + Asn1Sequence policies = null; + try + { + policies = (Asn1Sequence)PkixCertPathValidatorUtilities.GetExtensionValue(cert, + X509Extensions.CertificatePolicies); + } + catch (Exception e) + { + throw new PkixCertPathValidatorException( + "Certificate policies extension could not be decoded.", e, certPath, index); + } + + foreach (Asn1Encodable ae in policies) + { + PolicyInformation pinfo = null; + try + { + pinfo = PolicyInformation.GetInstance(ae.ToAsn1Object()); + } + catch (Exception ex) + { + throw new PkixCertPathValidatorException( + "Policy information could not be decoded.", ex, certPath, index); + } + if (Rfc3280CertPathUtilities.ANY_POLICY.Equals(pinfo.PolicyIdentifier.Id)) + { + try + { + pq = PkixCertPathValidatorUtilities + .GetQualifierSet(pinfo.PolicyQualifiers); + } + catch (PkixCertPathValidatorException ex) + { + throw new PkixCertPathValidatorException( + "Policy qualifier info set could not be decoded.", ex, certPath, + index); + } + break; + } + } + bool ci = false; + ISet critExtOids = cert.GetCriticalExtensionOids(); + if (critExtOids != null) + { + ci = critExtOids.Contains(X509Extensions.CertificatePolicies.Id); + } + + PkixPolicyNode p_node = (PkixPolicyNode)node.Parent; + if (Rfc3280CertPathUtilities.ANY_POLICY.Equals(p_node.ValidPolicy)) + { + PkixPolicyNode c_node = new PkixPolicyNode(Platform.CreateArrayList(), i, + (ISet)m_idp[id_p], p_node, pq, id_p, ci); + p_node.AddChild(c_node); + policyNodes[i].Add(c_node); + } + break; + } + } + } + + // + // (2) + // + } + else if (policyMapping <= 0) + { + foreach (PkixPolicyNode node in Platform.CreateArrayList(policyNodes[i])) + { + if (node.ValidPolicy.Equals(id_p)) + { + node.Parent.RemoveChild(node); + + for (int k = i - 1; k >= 0; k--) + { + foreach (PkixPolicyNode node2 in Platform.CreateArrayList(policyNodes[k])) + { + if (!node2.HasChildren) + { + _validPolicyTree = PkixCertPathValidatorUtilities.RemovePolicyNode( + _validPolicyTree, policyNodes, node2); + + if (_validPolicyTree == null) + break; + } + } + } + } + } + } + } + } + return _validPolicyTree; + } + + internal static ISet[] ProcessCrlA1ii( + DateTime currentDate, + PkixParameters paramsPKIX, + X509Certificate cert, + X509Crl crl) + { + ISet deltaSet = new HashSet(); + X509CrlStoreSelector crlselect = new X509CrlStoreSelector(); + crlselect.CertificateChecking = cert; + + try + { + IList issuer = Platform.CreateArrayList(); + issuer.Add(crl.IssuerDN); + crlselect.Issuers = issuer; + } + catch (IOException e) + { + throw new Exception("Cannot extract issuer from CRL." + e, e); + } + + crlselect.CompleteCrlEnabled = true; + ISet completeSet = CrlUtilities.FindCrls(crlselect, paramsPKIX, currentDate); + + if (paramsPKIX.IsUseDeltasEnabled) + { + // get delta CRL(s) + try + { + deltaSet.AddAll(PkixCertPathValidatorUtilities.GetDeltaCrls(currentDate, paramsPKIX, crl)); + } + catch (Exception e) + { + throw new Exception("Exception obtaining delta CRLs.", e); + } + } + + return new ISet[]{ completeSet, deltaSet }; + } + + internal static ISet ProcessCrlA1i( + DateTime currentDate, + PkixParameters paramsPKIX, + X509Certificate cert, + X509Crl crl) + { + ISet deltaSet = new HashSet(); + if (paramsPKIX.IsUseDeltasEnabled) + { + CrlDistPoint freshestCRL = null; + try + { + freshestCRL = CrlDistPoint.GetInstance( + PkixCertPathValidatorUtilities.GetExtensionValue(cert, X509Extensions.FreshestCrl)); + } + catch (Exception e) + { + throw new Exception("Freshest CRL extension could not be decoded from certificate.", e); + } + + if (freshestCRL == null) + { + try + { + freshestCRL = CrlDistPoint.GetInstance(PkixCertPathValidatorUtilities.GetExtensionValue(crl, X509Extensions.FreshestCrl)); + } + catch (Exception e) + { + throw new Exception("Freshest CRL extension could not be decoded from CRL.", e); + } + } + if (freshestCRL != null) + { + try + { + PkixCertPathValidatorUtilities.AddAdditionalStoresFromCrlDistributionPoint(freshestCRL, paramsPKIX); + } + catch (Exception e) + { + throw new Exception( + "No new delta CRL locations could be added from Freshest CRL extension.", e); + } + // get delta CRL(s) + try + { + deltaSet.AddAll(PkixCertPathValidatorUtilities.GetDeltaCrls(currentDate, paramsPKIX, crl)); + } + catch (Exception e) + { + throw new Exception("Exception obtaining delta CRLs.", e); + } + } + } + return deltaSet; + } + + internal static void ProcessCertF( + PkixCertPath certPath, + int index, + PkixPolicyNode validPolicyTree, + int explicitPolicy) + { + // + // (f) + // + if (explicitPolicy <= 0 && validPolicyTree == null) + { + throw new PkixCertPathValidatorException( + "No valid policy tree found when one expected.", null, certPath, index); + } + } + + internal static void ProcessCertA( + PkixCertPath certPath, + PkixParameters paramsPKIX, + int index, + AsymmetricKeyParameter workingPublicKey, + X509Name workingIssuerName, + X509Certificate sign) + { + IList certs = certPath.Certificates; + X509Certificate cert = (X509Certificate)certs[index]; + // + // (a) verify + // + try + { + // (a) (1) + // + cert.Verify(workingPublicKey); + } + catch (GeneralSecurityException e) + { + throw new PkixCertPathValidatorException("Could not validate certificate signature.", e, certPath, index); + } + + try + { + // (a) (2) + // + cert.CheckValidity(PkixCertPathValidatorUtilities + .GetValidCertDateFromValidityModel(paramsPKIX, certPath, index)); + } + catch (CertificateExpiredException e) + { + throw new PkixCertPathValidatorException("Could not validate certificate: " + e.Message, e, certPath, index); + } + catch (CertificateNotYetValidException e) + { + throw new PkixCertPathValidatorException("Could not validate certificate: " + e.Message, e, certPath, index); + } + catch (Exception e) + { + throw new PkixCertPathValidatorException("Could not validate time of certificate.", e, certPath, index); + } + + // + // (a) (3) + // + if (paramsPKIX.IsRevocationEnabled) + { + try + { + CheckCrls(paramsPKIX, cert, PkixCertPathValidatorUtilities.GetValidCertDateFromValidityModel(paramsPKIX, + certPath, index), sign, workingPublicKey, certs); + } + catch (Exception e) + { + Exception cause = e.InnerException; + if (cause == null) + { + cause = e; + } + throw new PkixCertPathValidatorException(e.Message, cause, certPath, index); + } + } + + // + // (a) (4) name chaining + // + X509Name issuer = PkixCertPathValidatorUtilities.GetIssuerPrincipal(cert); + if (!issuer.Equivalent(workingIssuerName, true)) + { + throw new PkixCertPathValidatorException("IssuerName(" + issuer + + ") does not match SubjectName(" + workingIssuerName + ") of signing certificate.", null, + certPath, index); + } + } + + internal static int PrepareNextCertI1( + PkixCertPath certPath, + int index, + int explicitPolicy) + { + IList certs = certPath.Certificates; + X509Certificate cert = (X509Certificate)certs[index]; + // + // (i) + // + Asn1Sequence pc = null; + try + { + pc = Asn1Sequence.GetInstance( + PkixCertPathValidatorUtilities.GetExtensionValue(cert, X509Extensions.PolicyConstraints)); + } + catch (Exception e) + { + throw new PkixCertPathValidatorException( + "Policy constraints extension cannot be decoded.", e, certPath, index); + } + + int tmpInt; + + if (pc != null) + { + IEnumerator policyConstraints = pc.GetEnumerator(); + + while (policyConstraints.MoveNext()) + { + try + { + Asn1TaggedObject constraint = Asn1TaggedObject.GetInstance(policyConstraints.Current); + if (constraint.TagNo == 0) + { + tmpInt = DerInteger.GetInstance(constraint, false).IntValueExact; + if (tmpInt < explicitPolicy) + { + return tmpInt; + } + break; + } + } + catch (ArgumentException e) + { + throw new PkixCertPathValidatorException( + "Policy constraints extension contents cannot be decoded.", e, certPath, index); + } + } + } + return explicitPolicy; + } + + internal static int PrepareNextCertI2( + PkixCertPath certPath, + int index, + int policyMapping) + //throws CertPathValidatorException + { + IList certs = certPath.Certificates; + X509Certificate cert = (X509Certificate)certs[index]; + + // + // (i) + // + Asn1Sequence pc = null; + try + { + pc = Asn1Sequence.GetInstance( + PkixCertPathValidatorUtilities.GetExtensionValue(cert, X509Extensions.PolicyConstraints)); + } + catch (Exception e) + { + throw new PkixCertPathValidatorException( + "Policy constraints extension cannot be decoded.", e, certPath, index); + } + + int tmpInt; + + if (pc != null) + { + IEnumerator policyConstraints = pc.GetEnumerator(); + + while (policyConstraints.MoveNext()) + { + try + { + Asn1TaggedObject constraint = Asn1TaggedObject.GetInstance(policyConstraints.Current); + if (constraint.TagNo == 1) + { + tmpInt = DerInteger.GetInstance(constraint, false).IntValueExact; + if (tmpInt < policyMapping) + { + return tmpInt; + } + break; + } + } + catch (ArgumentException e) + { + throw new PkixCertPathValidatorException( + "Policy constraints extension contents cannot be decoded.", e, certPath, index); + } + } + } + return policyMapping; + } + + internal static void PrepareNextCertG( + PkixCertPath certPath, + int index, + PkixNameConstraintValidator nameConstraintValidator) + //throws CertPathValidatorException + { + IList certs = certPath.Certificates; + X509Certificate cert = (X509Certificate)certs[index]; + + // + // (g) handle the name constraints extension + // + NameConstraints nc = null; + try + { + Asn1Sequence ncSeq = Asn1Sequence.GetInstance( + PkixCertPathValidatorUtilities.GetExtensionValue(cert, X509Extensions.NameConstraints)); + if (ncSeq != null) + { + nc = new NameConstraints(ncSeq); + } + } + catch (Exception e) + { + throw new PkixCertPathValidatorException( + "Name constraints extension could not be decoded.", e, certPath, index); + } + if (nc != null) + { + // + // (g) (1) permitted subtrees + // + Asn1Sequence permitted = nc.PermittedSubtrees; + if (permitted != null) + { + try + { + nameConstraintValidator.IntersectPermittedSubtree(permitted); + } + catch (Exception ex) + { + throw new PkixCertPathValidatorException( + "Permitted subtrees cannot be build from name constraints extension.", ex, certPath, index); + } + } + + // + // (g) (2) excluded subtrees + // + Asn1Sequence excluded = nc.ExcludedSubtrees; + if (excluded != null) + { + IEnumerator e = excluded.GetEnumerator(); + try + { + while (e.MoveNext()) + { + GeneralSubtree subtree = GeneralSubtree.GetInstance(e.Current); + nameConstraintValidator.AddExcludedSubtree(subtree); + } + } + catch (Exception ex) + { + throw new PkixCertPathValidatorException( + "Excluded subtrees cannot be build from name constraints extension.", ex, certPath, index); + } + } + } + } + + internal static int PrepareNextCertJ( + PkixCertPath certPath, + int index, + int inhibitAnyPolicy) + //throws CertPathValidatorException + { + IList certs = certPath.Certificates; + X509Certificate cert = (X509Certificate)certs[index]; + + // + // (j) + // + DerInteger iap = null; + try + { + iap = DerInteger.GetInstance( + PkixCertPathValidatorUtilities.GetExtensionValue(cert, X509Extensions.InhibitAnyPolicy)); + } + catch (Exception e) + { + throw new PkixCertPathValidatorException( + "Inhibit any-policy extension cannot be decoded.", e, certPath, index); + } + + if (iap != null) + { + int _inhibitAnyPolicy = iap.IntValueExact; + + if (_inhibitAnyPolicy < inhibitAnyPolicy) + return _inhibitAnyPolicy; + } + return inhibitAnyPolicy; + } + + internal static void PrepareNextCertK( + PkixCertPath certPath, + int index) + //throws CertPathValidatorException + { + IList certs = certPath.Certificates; + X509Certificate cert = (X509Certificate)certs[index]; + // + // (k) + // + BasicConstraints bc = null; + try + { + bc = BasicConstraints.GetInstance( + PkixCertPathValidatorUtilities.GetExtensionValue(cert, X509Extensions.BasicConstraints)); + } + catch (Exception e) + { + throw new PkixCertPathValidatorException("Basic constraints extension cannot be decoded.", e, certPath, + index); + } + if (bc != null) + { + if (!(bc.IsCA())) + throw new PkixCertPathValidatorException("Not a CA certificate"); + } + else + { + throw new PkixCertPathValidatorException("Intermediate certificate lacks BasicConstraints"); + } + } + + internal static int PrepareNextCertL( + PkixCertPath certPath, + int index, + int maxPathLength) + //throws CertPathValidatorException + { + IList certs = certPath.Certificates; + X509Certificate cert = (X509Certificate)certs[index]; + // + // (l) + // + if (!PkixCertPathValidatorUtilities.IsSelfIssued(cert)) + { + if (maxPathLength <= 0) + { + throw new PkixCertPathValidatorException("Max path length not greater than zero", null, certPath, index); + } + + return maxPathLength - 1; + } + return maxPathLength; + } + + internal static int PrepareNextCertM( + PkixCertPath certPath, + int index, + int maxPathLength) + //throws CertPathValidatorException + { + IList certs = certPath.Certificates; + X509Certificate cert = (X509Certificate)certs[index]; + + // + // (m) + // + BasicConstraints bc = null; + try + { + bc = BasicConstraints.GetInstance( + PkixCertPathValidatorUtilities.GetExtensionValue(cert, X509Extensions.BasicConstraints)); + } + catch (Exception e) + { + throw new PkixCertPathValidatorException("Basic constraints extension cannot be decoded.", e, certPath, + index); + } + if (bc != null) + { + BigInteger _pathLengthConstraint = bc.PathLenConstraint; + + if (_pathLengthConstraint != null) + { + int _plc = _pathLengthConstraint.IntValue; + + if (_plc < maxPathLength) + { + return _plc; + } + } + } + return maxPathLength; + } + + internal static void PrepareNextCertN( + PkixCertPath certPath, + int index) + //throws CertPathValidatorException + { + IList certs = certPath.Certificates; + X509Certificate cert = (X509Certificate)certs[index]; + + // + // (n) + // + bool[] _usage = cert.GetKeyUsage(); + + if ((_usage != null) && !_usage[Rfc3280CertPathUtilities.KEY_CERT_SIGN]) + { + throw new PkixCertPathValidatorException( + "Issuer certificate keyusage extension is critical and does not permit key signing.", null, + certPath, index); + } + } + + internal static void PrepareNextCertO( + PkixCertPath certPath, + int index, + ISet criticalExtensions, + IList pathCheckers) + //throws CertPathValidatorException + { + IList certs = certPath.Certificates; + X509Certificate cert = (X509Certificate)certs[index]; + + // + // (o) + // + IEnumerator tmpIter = pathCheckers.GetEnumerator(); + while (tmpIter.MoveNext()) + { + try + { + ((PkixCertPathChecker)tmpIter.Current).Check(cert, criticalExtensions); + } + catch (PkixCertPathValidatorException e) + { + throw new PkixCertPathValidatorException(e.Message, e.InnerException, certPath, index); + } + } + if (!criticalExtensions.IsEmpty) + { + throw new PkixCertPathValidatorException("Certificate has unsupported critical extension.", null, certPath, + index); + } + } + + internal static int PrepareNextCertH1( + PkixCertPath certPath, + int index, + int explicitPolicy) + { + IList certs = certPath.Certificates; + X509Certificate cert = (X509Certificate)certs[index]; + + // + // (h) + // + if (!PkixCertPathValidatorUtilities.IsSelfIssued(cert)) + { + // + // (1) + // + if (explicitPolicy != 0) + return explicitPolicy - 1; + } + return explicitPolicy; + } + + internal static int PrepareNextCertH2( + PkixCertPath certPath, + int index, + int policyMapping) + { + IList certs = certPath.Certificates; + X509Certificate cert = (X509Certificate)certs[index]; + + // + // (h) + // + if (!PkixCertPathValidatorUtilities.IsSelfIssued(cert)) + { + // + // (2) + // + if (policyMapping != 0) + return policyMapping - 1; + } + return policyMapping; + } + + + internal static int PrepareNextCertH3( + PkixCertPath certPath, + int index, + int inhibitAnyPolicy) + { + IList certs = certPath.Certificates; + X509Certificate cert = (X509Certificate)certs[index]; + + // + // (h) + // + if (!PkixCertPathValidatorUtilities.IsSelfIssued(cert)) + { + // + // (3) + // + if (inhibitAnyPolicy != 0) + return inhibitAnyPolicy - 1; + } + return inhibitAnyPolicy; + } + + internal static int WrapupCertA( + int explicitPolicy, + X509Certificate cert) + { + // + // (a) + // + if (!PkixCertPathValidatorUtilities.IsSelfIssued(cert) && (explicitPolicy != 0)) + { + explicitPolicy--; + } + return explicitPolicy; + } + + internal static int WrapupCertB( + PkixCertPath certPath, + int index, + int explicitPolicy) + //throws CertPathValidatorException + { + IList certs = certPath.Certificates; + X509Certificate cert = (X509Certificate)certs[index]; + + // + // (b) + // + int tmpInt; + Asn1Sequence pc = null; + try + { + pc = Asn1Sequence.GetInstance( + PkixCertPathValidatorUtilities.GetExtensionValue(cert, X509Extensions.PolicyConstraints)); + } + catch (Exception e) + { + throw new PkixCertPathValidatorException("Policy constraints could not be decoded.", e, certPath, index); + } + + if (pc != null) + { + IEnumerator policyConstraints = pc.GetEnumerator(); + + while (policyConstraints.MoveNext()) + { + Asn1TaggedObject constraint = (Asn1TaggedObject)policyConstraints.Current; + switch (constraint.TagNo) + { + case 0: + try + { + tmpInt = DerInteger.GetInstance(constraint, false).IntValueExact; + } + catch (Exception e) + { + throw new PkixCertPathValidatorException( + "Policy constraints requireExplicitPolicy field could not be decoded.", e, certPath, + index); + } + if (tmpInt == 0) + { + return 0; + } + break; + } + } + } + return explicitPolicy; + } + + internal static void WrapupCertF( + PkixCertPath certPath, + int index, + IList pathCheckers, + ISet criticalExtensions) + //throws CertPathValidatorException + { + IList certs = certPath.Certificates; + X509Certificate cert = (X509Certificate)certs[index]; + IEnumerator tmpIter = pathCheckers.GetEnumerator(); + + while (tmpIter.MoveNext()) + { + try + { + ((PkixCertPathChecker)tmpIter.Current).Check(cert, criticalExtensions); + } + catch (PkixCertPathValidatorException e) + { + throw new PkixCertPathValidatorException("Additional certificate path checker failed.", e, certPath, + index); + } + } + + if (!criticalExtensions.IsEmpty) + { + throw new PkixCertPathValidatorException("Certificate has unsupported critical extension", + null, certPath, index); + } + } + + internal static PkixPolicyNode WrapupCertG( + PkixCertPath certPath, + PkixParameters paramsPKIX, + ISet userInitialPolicySet, + int index, + IList[] policyNodes, + PkixPolicyNode validPolicyTree, + ISet acceptablePolicies) + { + int n = certPath.Certificates.Count; + + // + // (g) + // + PkixPolicyNode intersection; + + // + // (g) (i) + // + if (validPolicyTree == null) + { + if (paramsPKIX.IsExplicitPolicyRequired) + { + throw new PkixCertPathValidatorException( + "Explicit policy requested but none available.", null, certPath, index); + } + intersection = null; + } + else if (PkixCertPathValidatorUtilities.IsAnyPolicy(userInitialPolicySet)) // (g) + // (ii) + { + if (paramsPKIX.IsExplicitPolicyRequired) + { + if (acceptablePolicies.IsEmpty) + { + throw new PkixCertPathValidatorException( + "Explicit policy requested but none available.", null, certPath, index); + } + else + { + ISet _validPolicyNodeSet = new HashSet(); + + for (int j = 0; j < policyNodes.Length; j++) + { + IList _nodeDepth = policyNodes[j]; + + for (int k = 0; k < _nodeDepth.Count; k++) + { + PkixPolicyNode _node = (PkixPolicyNode)_nodeDepth[k]; + + if (Rfc3280CertPathUtilities.ANY_POLICY.Equals(_node.ValidPolicy)) + { + foreach (object o in _node.Children) + { + _validPolicyNodeSet.Add(o); + } + } + } + } + + foreach (PkixPolicyNode _node in _validPolicyNodeSet) + { + string _validPolicy = _node.ValidPolicy; + + if (!acceptablePolicies.Contains(_validPolicy)) + { + // TODO? + // validPolicyTree = + // removePolicyNode(validPolicyTree, policyNodes, + // _node); + } + } + if (validPolicyTree != null) + { + for (int j = (n - 1); j >= 0; j--) + { + IList nodes = policyNodes[j]; + + for (int k = 0; k < nodes.Count; k++) + { + PkixPolicyNode node = (PkixPolicyNode)nodes[k]; + if (!node.HasChildren) + { + validPolicyTree = PkixCertPathValidatorUtilities.RemovePolicyNode(validPolicyTree, + policyNodes, node); + } + } + } + } + } + } + + intersection = validPolicyTree; + } + else + { + // + // (g) (iii) + // + // This implementation is not exactly same as the one described in + // RFC3280. + // However, as far as the validation result is concerned, both + // produce + // adequate result. The only difference is whether AnyPolicy is + // remain + // in the policy tree or not. + // + // (g) (iii) 1 + // + ISet _validPolicyNodeSet = new HashSet(); + + for (int j = 0; j < policyNodes.Length; j++) + { + IList _nodeDepth = policyNodes[j]; + + for (int k = 0; k < _nodeDepth.Count; k++) + { + PkixPolicyNode _node = (PkixPolicyNode)_nodeDepth[k]; + + if (Rfc3280CertPathUtilities.ANY_POLICY.Equals(_node.ValidPolicy)) + { + foreach (PkixPolicyNode _c_node in _node.Children) + { + if (!Rfc3280CertPathUtilities.ANY_POLICY.Equals(_c_node.ValidPolicy)) + { + _validPolicyNodeSet.Add(_c_node); + } + } + } + } + } + + // + // (g) (iii) 2 + // + IEnumerator _vpnsIter = _validPolicyNodeSet.GetEnumerator(); + while (_vpnsIter.MoveNext()) + { + PkixPolicyNode _node = (PkixPolicyNode)_vpnsIter.Current; + string _validPolicy = _node.ValidPolicy; + + if (!userInitialPolicySet.Contains(_validPolicy)) + { + validPolicyTree = PkixCertPathValidatorUtilities.RemovePolicyNode(validPolicyTree, policyNodes, _node); + } + } + + // + // (g) (iii) 4 + // + if (validPolicyTree != null) + { + for (int j = (n - 1); j >= 0; j--) + { + IList nodes = policyNodes[j]; + + for (int k = 0; k < nodes.Count; k++) + { + PkixPolicyNode node = (PkixPolicyNode)nodes[k]; + if (!node.HasChildren) + { + validPolicyTree = PkixCertPathValidatorUtilities.RemovePolicyNode(validPolicyTree, policyNodes, + node); + } + } + } + } + + intersection = validPolicyTree; + } + return intersection; + } + + /** + * If use-deltas is set, verify the issuer and scope of the delta CRL. + * + * @param deltaCRL The delta CRL. + * @param completeCRL The complete CRL. + * @param pkixParams The PKIX paramaters. + * @throws AnnotatedException if an exception occurs. + */ + internal static void ProcessCrlC( + X509Crl deltaCRL, + X509Crl completeCRL, + PkixParameters pkixParams) + { + if (deltaCRL == null) + return; + + IssuingDistributionPoint completeidp = null; + try + { + completeidp = IssuingDistributionPoint.GetInstance( + PkixCertPathValidatorUtilities.GetExtensionValue(completeCRL, X509Extensions.IssuingDistributionPoint)); + } + catch (Exception e) + { + throw new Exception("000 Issuing distribution point extension could not be decoded.", e); + } + + if (pkixParams.IsUseDeltasEnabled) + { + // (c) (1) + if (!deltaCRL.IssuerDN.Equivalent(completeCRL.IssuerDN, true)) + throw new Exception("Complete CRL issuer does not match delta CRL issuer."); + + // (c) (2) + IssuingDistributionPoint deltaidp = null; + try + { + deltaidp = IssuingDistributionPoint.GetInstance( + PkixCertPathValidatorUtilities.GetExtensionValue(deltaCRL, X509Extensions.IssuingDistributionPoint)); + } + catch (Exception e) + { + throw new Exception( + "Issuing distribution point extension from delta CRL could not be decoded.", e); + } + + if (!Platform.Equals(completeidp, deltaidp)) + { + throw new Exception( + "Issuing distribution point extension from delta CRL and complete CRL does not match."); + } + + // (c) (3) + Asn1Object completeKeyIdentifier = null; + try + { + completeKeyIdentifier = PkixCertPathValidatorUtilities.GetExtensionValue( + completeCRL, X509Extensions.AuthorityKeyIdentifier); + } + catch (Exception e) + { + throw new Exception( + "Authority key identifier extension could not be extracted from complete CRL.", e); + } + + Asn1Object deltaKeyIdentifier = null; + try + { + deltaKeyIdentifier = PkixCertPathValidatorUtilities.GetExtensionValue( + deltaCRL, X509Extensions.AuthorityKeyIdentifier); + } + catch (Exception e) + { + throw new Exception( + "Authority key identifier extension could not be extracted from delta CRL.", e); + } + + if (completeKeyIdentifier == null) + throw new Exception("CRL authority key identifier is null."); + + if (deltaKeyIdentifier == null) + throw new Exception("Delta CRL authority key identifier is null."); + + if (!completeKeyIdentifier.Equals(deltaKeyIdentifier)) + { + throw new Exception( + "Delta CRL authority key identifier does not match complete CRL authority key identifier."); + } + } + } + + internal static void ProcessCrlI( + DateTime validDate, + X509Crl deltacrl, + object cert, + CertStatus certStatus, + PkixParameters pkixParams) + { + if (pkixParams.IsUseDeltasEnabled && deltacrl != null) + { + PkixCertPathValidatorUtilities.GetCertStatus(validDate, deltacrl, cert, certStatus); + } + } + + internal static void ProcessCrlJ( + DateTime validDate, + X509Crl completecrl, + object cert, + CertStatus certStatus) + { + if (certStatus.Status == CertStatus.Unrevoked) + { + PkixCertPathValidatorUtilities.GetCertStatus(validDate, completecrl, cert, certStatus); + } + } + + internal static PkixPolicyNode ProcessCertE( + PkixCertPath certPath, + int index, + PkixPolicyNode validPolicyTree) + { + IList certs = certPath.Certificates; + X509Certificate cert = (X509Certificate)certs[index]; + + // + // (e) + // + Asn1Sequence certPolicies = null; + try + { + certPolicies = Asn1Sequence.GetInstance( + PkixCertPathValidatorUtilities.GetExtensionValue(cert, X509Extensions.CertificatePolicies)); + } + catch (Exception e) + { + throw new PkixCertPathValidatorException("Could not read certificate policies extension from certificate.", + e, certPath, index); + } + if (certPolicies == null) + { + validPolicyTree = null; + } + return validPolicyTree; + } + + internal static readonly string[] CrlReasons = new string[] + { + "unspecified", + "keyCompromise", + "cACompromise", + "affiliationChanged", + "superseded", + "cessationOfOperation", + "certificateHold", + "unknown", + "removeFromCRL", + "privilegeWithdrawn", + "aACompromise" + }; + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/Rfc3280CertPathUtilities.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/Rfc3280CertPathUtilities.cs.meta new file mode 100644 index 0000000..292f3a1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/Rfc3280CertPathUtilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: abc0a73143522dd4e8c71f8e1f146306 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/Rfc3281CertPathUtilities.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/Rfc3281CertPathUtilities.cs new file mode 100644 index 0000000..66025f0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/Rfc3281CertPathUtilities.cs @@ -0,0 +1,609 @@ +using System; +using System.Collections; +using System.Globalization; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Security.Certificates; +using Org.BouncyCastle.Utilities.Collections; +using Org.BouncyCastle.X509; +using Org.BouncyCastle.X509.Store; + +namespace Org.BouncyCastle.Pkix +{ + internal class Rfc3281CertPathUtilities + { + internal static void ProcessAttrCert7( + IX509AttributeCertificate attrCert, + PkixCertPath certPath, + PkixCertPath holderCertPath, + PkixParameters pkixParams) + { + // TODO: + // AA Controls + // Attribute encryption + // Proxy + ISet critExtOids = attrCert.GetCriticalExtensionOids(); + + // 7.1 + // process extensions + + // target information checked in step 6 / X509AttributeCertStoreSelector + if (critExtOids.Contains(X509Extensions.TargetInformation.Id)) + { + try + { + TargetInformation.GetInstance(PkixCertPathValidatorUtilities + .GetExtensionValue(attrCert, X509Extensions.TargetInformation)); + } + catch (Exception e) + { + throw new PkixCertPathValidatorException( + "Target information extension could not be read.", e); + } + } + critExtOids.Remove(X509Extensions.TargetInformation.Id); + foreach (PkixAttrCertChecker checker in pkixParams.GetAttrCertCheckers()) + { + checker.Check(attrCert, certPath, holderCertPath, critExtOids); + } + if (!critExtOids.IsEmpty) + { + throw new PkixCertPathValidatorException( + "Attribute certificate contains unsupported critical extensions: " + + critExtOids); + } + } + + /** + * Checks if an attribute certificate is revoked. + * + * @param attrCert Attribute certificate to check if it is revoked. + * @param paramsPKIX PKIX parameters. + * @param issuerCert The issuer certificate of the attribute certificate + * attrCert. + * @param validDate The date when the certificate revocation status should + * be checked. + * @param certPathCerts The certificates of the certification path to be + * checked. + * + * @throws CertPathValidatorException if the certificate is revoked or the + * status cannot be checked or some error occurs. + */ + internal static void CheckCrls( + IX509AttributeCertificate attrCert, + PkixParameters paramsPKIX, + X509Certificate issuerCert, + DateTime validDate, + IList certPathCerts) + { + if (!paramsPKIX.IsRevocationEnabled) + { + return; + } + + // check if revocation is available + if (attrCert.GetExtensionValue(X509Extensions.NoRevAvail) != null) + { + if (attrCert.GetExtensionValue(X509Extensions.CrlDistributionPoints) != null + || attrCert.GetExtensionValue(X509Extensions.AuthorityInfoAccess) != null) + { + throw new PkixCertPathValidatorException( + "No rev avail extension is set, but also an AC revocation pointer."); + } + + return; + } + + CrlDistPoint crldp = null; + try + { + crldp = CrlDistPoint.GetInstance( + PkixCertPathValidatorUtilities.GetExtensionValue( + attrCert, X509Extensions.CrlDistributionPoints)); + } + catch (Exception e) + { + throw new PkixCertPathValidatorException( + "CRL distribution point extension could not be read.", e); + } + try + { + PkixCertPathValidatorUtilities + .AddAdditionalStoresFromCrlDistributionPoint(crldp, paramsPKIX); + } + catch (Exception e) + { + throw new PkixCertPathValidatorException( + "No additional CRL locations could be decoded from CRL distribution point extension.", e); + } + + CertStatus certStatus = new CertStatus(); + ReasonsMask reasonsMask = new ReasonsMask(); + + Exception lastException = null; + bool validCrlFound = false; + // for each distribution point + if (crldp != null) + { + DistributionPoint[] dps = null; + try + { + dps = crldp.GetDistributionPoints(); + } + catch (Exception e) + { + throw new PkixCertPathValidatorException( + "Distribution points could not be read.", e); + } + try + { + for (int i = 0; i < dps.Length + && certStatus.Status == CertStatus.Unrevoked + && !reasonsMask.IsAllReasons; i++) + { + PkixParameters paramsPKIXClone = (PkixParameters) paramsPKIX + .Clone(); + CheckCrl(dps[i], attrCert, paramsPKIXClone, + validDate, issuerCert, certStatus, reasonsMask, + certPathCerts); + validCrlFound = true; + } + } + catch (Exception e) + { + lastException = new Exception( + "No valid CRL for distribution point found.", e); + } + } + + /* + * If the revocation status has not been determined, repeat the + * process above with any available CRLs not specified in a + * distribution point but issued by the certificate issuer. + */ + + if (certStatus.Status == CertStatus.Unrevoked + && !reasonsMask.IsAllReasons) + { + try + { + /* + * assume a DP with both the reasons and the cRLIssuer + * fields omitted and a distribution point name of the + * certificate issuer. + */ + X509Name issuer; + try + { + issuer = X509Name.GetInstance(attrCert.Issuer.GetPrincipals()[0].GetEncoded()); + } + catch (Exception e) + { + throw new Exception( + "Issuer from certificate for CRL could not be reencoded.", + e); + } + DistributionPoint dp = new DistributionPoint( + new DistributionPointName(0, new GeneralNames( + new GeneralName(GeneralName.DirectoryName, issuer))), null, null); + PkixParameters paramsPKIXClone = (PkixParameters) paramsPKIX.Clone(); + CheckCrl(dp, attrCert, paramsPKIXClone, validDate, + issuerCert, certStatus, reasonsMask, certPathCerts); + validCrlFound = true; + } + catch (Exception e) + { + lastException = new Exception( + "No valid CRL for distribution point found.", e); + } + } + + if (!validCrlFound) + { + throw new PkixCertPathValidatorException( + "No valid CRL found.", lastException); + } + if (certStatus.Status != CertStatus.Unrevoked) + { + // This format is enforced by the NistCertPath tests + string formattedDate = certStatus.RevocationDate.Value.ToString( + "ddd MMM dd HH:mm:ss K yyyy"); + string message = "Attribute certificate revocation after " + + formattedDate; + message += ", reason: " + + Rfc3280CertPathUtilities.CrlReasons[certStatus.Status]; + throw new PkixCertPathValidatorException(message); + } + if (!reasonsMask.IsAllReasons + && certStatus.Status == CertStatus.Unrevoked) + { + certStatus.Status = CertStatus.Undetermined; + } + if (certStatus.Status == CertStatus.Undetermined) + { + throw new PkixCertPathValidatorException( + "Attribute certificate status could not be determined."); + } + } + + internal static void AdditionalChecks( + IX509AttributeCertificate attrCert, + PkixParameters pkixParams) + { + // 1 + foreach (string oid in pkixParams.GetProhibitedACAttributes()) + { + if (attrCert.GetAttributes(oid) != null) + { + throw new PkixCertPathValidatorException( + "Attribute certificate contains prohibited attribute: " + + oid + "."); + } + } + foreach (string oid in pkixParams.GetNecessaryACAttributes()) + { + if (attrCert.GetAttributes(oid) == null) + { + throw new PkixCertPathValidatorException( + "Attribute certificate does not contain necessary attribute: " + + oid + "."); + } + } + } + + internal static void ProcessAttrCert5( + IX509AttributeCertificate attrCert, + PkixParameters pkixParams) + { + try + { + attrCert.CheckValidity(PkixCertPathValidatorUtilities.GetValidDate(pkixParams)); + } + catch (CertificateExpiredException e) + { + throw new PkixCertPathValidatorException( + "Attribute certificate is not valid.", e); + } + catch (CertificateNotYetValidException e) + { + throw new PkixCertPathValidatorException( + "Attribute certificate is not valid.", e); + } + } + + internal static void ProcessAttrCert4( + X509Certificate acIssuerCert, + PkixParameters pkixParams) + { + ISet set = pkixParams.GetTrustedACIssuers(); + bool trusted = false; + foreach (TrustAnchor anchor in set) + { + IDictionary symbols = X509Name.RFC2253Symbols; + if (acIssuerCert.SubjectDN.ToString(false, symbols).Equals(anchor.CAName) + || acIssuerCert.Equals(anchor.TrustedCert)) + { + trusted = true; + } + } + if (!trusted) + { + throw new PkixCertPathValidatorException( + "Attribute certificate issuer is not directly trusted."); + } + } + + internal static void ProcessAttrCert3( + X509Certificate acIssuerCert, + PkixParameters pkixParams) + { + if (acIssuerCert.GetKeyUsage() != null + && (!acIssuerCert.GetKeyUsage()[0] && !acIssuerCert.GetKeyUsage()[1])) + { + throw new PkixCertPathValidatorException( + "Attribute certificate issuer public key cannot be used to validate digital signatures."); + } + if (acIssuerCert.GetBasicConstraints() != -1) + { + throw new PkixCertPathValidatorException( + "Attribute certificate issuer is also a public key certificate issuer."); + } + } + + internal static PkixCertPathValidatorResult ProcessAttrCert2( + PkixCertPath certPath, + PkixParameters pkixParams) + { + PkixCertPathValidator validator = new PkixCertPathValidator(); + + try + { + return validator.Validate(certPath, pkixParams); + } + catch (PkixCertPathValidatorException e) + { + throw new PkixCertPathValidatorException( + "Certification path for issuer certificate of attribute certificate could not be validated.", + e); + } + } + + /** + * Searches for a holder public key certificate and verifies its + * certification path. + * + * @param attrCert the attribute certificate. + * @param pkixParams The PKIX parameters. + * @return The certificate path of the holder certificate. + * @throws Exception if + *
      + *
    • no public key certificate can be found although holder + * information is given by an entity name or a base certificate + * ID
    • + *
    • support classes cannot be created
    • + *
    • no certification path for the public key certificate can + * be built
    • + *
    + */ + internal static PkixCertPath ProcessAttrCert1( + IX509AttributeCertificate attrCert, + PkixParameters pkixParams) + { + PkixCertPathBuilderResult result = null; + // find holder PKCs + ISet holderPKCs = new HashSet(); + if (attrCert.Holder.GetIssuer() != null) + { + X509CertStoreSelector selector = new X509CertStoreSelector(); + selector.SerialNumber = attrCert.Holder.SerialNumber; + X509Name[] principals = attrCert.Holder.GetIssuer(); + for (int i = 0; i < principals.Length; i++) + { + try + { +// if (principals[i] is X500Principal) + { + selector.Issuer = principals[i]; + } + holderPKCs.AddAll(PkixCertPathValidatorUtilities + .FindCertificates(selector, pkixParams.GetStores())); + } + catch (Exception e) + { + throw new PkixCertPathValidatorException( + "Public key certificate for attribute certificate cannot be searched.", + e); + } + } + if (holderPKCs.IsEmpty) + { + throw new PkixCertPathValidatorException( + "Public key certificate specified in base certificate ID for attribute certificate cannot be found."); + } + } + if (attrCert.Holder.GetEntityNames() != null) + { + X509CertStoreSelector selector = new X509CertStoreSelector(); + X509Name[] principals = attrCert.Holder.GetEntityNames(); + for (int i = 0; i < principals.Length; i++) + { + try + { +// if (principals[i] is X500Principal) + { + selector.Issuer = principals[i]; + } + holderPKCs.AddAll(PkixCertPathValidatorUtilities + .FindCertificates(selector, pkixParams.GetStores())); + } + catch (Exception e) + { + throw new PkixCertPathValidatorException( + "Public key certificate for attribute certificate cannot be searched.", + e); + } + } + if (holderPKCs.IsEmpty) + { + throw new PkixCertPathValidatorException( + "Public key certificate specified in entity name for attribute certificate cannot be found."); + } + } + + // verify cert paths for PKCs + PkixBuilderParameters parameters = (PkixBuilderParameters) + PkixBuilderParameters.GetInstance(pkixParams); + + PkixCertPathValidatorException lastException = null; + foreach (X509Certificate cert in holderPKCs) + { + X509CertStoreSelector selector = new X509CertStoreSelector(); + selector.Certificate = cert; + parameters.SetTargetConstraints(selector); + + PkixCertPathBuilder builder = new PkixCertPathBuilder(); + + try + { + result = builder.Build(PkixBuilderParameters.GetInstance(parameters)); + } + catch (PkixCertPathBuilderException e) + { + lastException = new PkixCertPathValidatorException( + "Certification path for public key certificate of attribute certificate could not be build.", + e); + } + } + if (lastException != null) + { + throw lastException; + } + return result.CertPath; + } + + /** + * + * Checks a distribution point for revocation information for the + * certificate attrCert. + * + * @param dp The distribution point to consider. + * @param attrCert The attribute certificate which should be checked. + * @param paramsPKIX PKIX parameters. + * @param validDate The date when the certificate revocation status should + * be checked. + * @param issuerCert Certificate to check if it is revoked. + * @param reasonMask The reasons mask which is already checked. + * @param certPathCerts The certificates of the certification path to be + * checked. + * @throws Exception if the certificate is revoked or the status + * cannot be checked or some error occurs. + */ + private static void CheckCrl( + DistributionPoint dp, + IX509AttributeCertificate attrCert, + PkixParameters paramsPKIX, + DateTime validDate, + X509Certificate issuerCert, + CertStatus certStatus, + ReasonsMask reasonMask, + IList certPathCerts) + { + /* + * 4.3.6 No Revocation Available + * + * The noRevAvail extension, defined in [X.509-2000], allows an AC + * issuer to indicate that no revocation information will be made + * available for this AC. + */ + if (attrCert.GetExtensionValue(X509Extensions.NoRevAvail) != null) + { + return; + } + + DateTime currentDate = DateTime.UtcNow; + if (validDate.CompareTo(currentDate) > 0) + { + throw new Exception("Validation time is in future."); + } + + // (a) + /* + * We always get timely valid CRLs, so there is no step (a) (1). + * "locally cached" CRLs are assumed to be in getStore(), additional + * CRLs must be enabled in the ExtendedPkixParameters and are in + * getAdditionalStore() + */ + ISet crls = PkixCertPathValidatorUtilities.GetCompleteCrls(dp, attrCert, + currentDate, paramsPKIX); + bool validCrlFound = false; + Exception lastException = null; + + IEnumerator crl_iter = crls.GetEnumerator(); + + while (crl_iter.MoveNext() + && certStatus.Status == CertStatus.Unrevoked + && !reasonMask.IsAllReasons) + { + try + { + X509Crl crl = (X509Crl) crl_iter.Current; + + // (d) + ReasonsMask interimReasonsMask = Rfc3280CertPathUtilities.ProcessCrlD(crl, dp); + + // (e) + /* + * The reasons mask is updated at the end, so only valid CRLs + * can update it. If this CRL does not contain new reasons it + * must be ignored. + */ + if (!interimReasonsMask.HasNewReasons(reasonMask)) + { + continue; + } + + // (f) + ISet keys = Rfc3280CertPathUtilities.ProcessCrlF(crl, attrCert, + null, null, paramsPKIX, certPathCerts); + // (g) + AsymmetricKeyParameter pubKey = Rfc3280CertPathUtilities.ProcessCrlG(crl, keys); + + X509Crl deltaCRL = null; + + if (paramsPKIX.IsUseDeltasEnabled) + { + // get delta CRLs + ISet deltaCRLs = PkixCertPathValidatorUtilities.GetDeltaCrls( + currentDate, paramsPKIX, crl); + // we only want one valid delta CRL + // (h) + deltaCRL = Rfc3280CertPathUtilities.ProcessCrlH(deltaCRLs, pubKey); + } + + /* + * CRL must be be valid at the current time, not the validation + * time. If a certificate is revoked with reason keyCompromise, + * cACompromise, it can be used for forgery, also for the past. + * This reason may not be contained in older CRLs. + */ + + /* + * in the chain model signatures stay valid also after the + * certificate has been expired, so they do not have to be in + * the CRL vality time + */ + if (paramsPKIX.ValidityModel != PkixParameters.ChainValidityModel) + { + /* + * if a certificate has expired, but was revoked, it is not + * more in the CRL, so it would be regarded as valid if the + * first check is not done + */ + if (attrCert.NotAfter.CompareTo(crl.ThisUpdate) < 0) + { + throw new Exception( + "No valid CRL for current time found."); + } + } + + Rfc3280CertPathUtilities.ProcessCrlB1(dp, attrCert, crl); + + // (b) (2) + Rfc3280CertPathUtilities.ProcessCrlB2(dp, attrCert, crl); + + // (c) + Rfc3280CertPathUtilities.ProcessCrlC(deltaCRL, crl, paramsPKIX); + + // (i) + Rfc3280CertPathUtilities.ProcessCrlI(validDate, deltaCRL, + attrCert, certStatus, paramsPKIX); + + // (j) + Rfc3280CertPathUtilities.ProcessCrlJ(validDate, crl, attrCert, + certStatus); + + // (k) + if (certStatus.Status == CrlReason.RemoveFromCrl) + { + certStatus.Status = CertStatus.Unrevoked; + } + + // update reasons mask + reasonMask.AddReasons(interimReasonsMask); + validCrlFound = true; + } + catch (Exception e) + { + lastException = e; + } + } + if (!validCrlFound) + { + throw lastException; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/Rfc3281CertPathUtilities.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/Rfc3281CertPathUtilities.cs.meta new file mode 100644 index 0000000..7d9168d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/Rfc3281CertPathUtilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a4cb25441af70564196837e1cc1314c4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/TrustAnchor.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/TrustAnchor.cs new file mode 100644 index 0000000..22078ba --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/TrustAnchor.cs @@ -0,0 +1,259 @@ +using System; +using System.IO; +using System.Text; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.Pkix +{ + /// + /// A trust anchor or most-trusted Certification Authority (CA). + /// + /// This class represents a "most-trusted CA", which is used as a trust anchor + /// for validating X.509 certification paths. A most-trusted CA includes the + /// public key of the CA, the CA's name, and any constraints upon the set of + /// paths which may be validated using this key. These parameters can be + /// specified in the form of a trusted X509Certificate or as individual + /// parameters. + /// + public class TrustAnchor + { + private readonly AsymmetricKeyParameter pubKey; + private readonly string caName; + private readonly X509Name caPrincipal; + private readonly X509Certificate trustedCert; + private byte[] ncBytes; + private NameConstraints nc; + + /// + /// Creates an instance of TrustAnchor with the specified X509Certificate and + /// optional name constraints, which are intended to be used as additional + /// constraints when validating an X.509 certification path. + /// The name constraints are specified as a byte array. This byte array + /// should contain the DER encoded form of the name constraints, as they + /// would appear in the NameConstraints structure defined in RFC 2459 and + /// X.509. The ASN.1 definition of this structure appears below. + /// + ///
    +	    ///	NameConstraints ::= SEQUENCE {
    +	    ///		permittedSubtrees       [0]     GeneralSubtrees OPTIONAL,
    +	    ///		excludedSubtrees        [1]     GeneralSubtrees OPTIONAL }
    +	    ///	   
    +        /// GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
    +        /// 
    +        ///		GeneralSubtree ::= SEQUENCE {
    +        ///		base                    GeneralName,
    +        ///		minimum         [0]     BaseDistance DEFAULT 0,
    +        ///		maximum         [1]     BaseDistance OPTIONAL }
    +        ///		
    +        ///		BaseDistance ::= INTEGER (0..MAX)
    +		///
    +		///		GeneralName ::= CHOICE {
    +		///		otherName                       [0]     OtherName,
    +		///		rfc822Name                      [1]     IA5String,
    +		///		dNSName                         [2]     IA5String,
    +		///		x400Address                     [3]     ORAddress,
    +		///		directoryName                   [4]     Name,
    +		///		ediPartyName                    [5]     EDIPartyName,
    +		///		uniformResourceIdentifier       [6]     IA5String,
    +		///		iPAddress                       [7]     OCTET STRING,
    +		///		registeredID                    [8]     OBJECT IDENTIFIER}
    +		///	
    + /// + /// Note that the name constraints byte array supplied is cloned to protect + /// against subsequent modifications. + ///
    + /// a trusted X509Certificate + /// a byte array containing the ASN.1 DER encoding of a + /// NameConstraints extension to be used for checking name + /// constraints. Only the value of the extension is included, not + /// the OID or criticality flag. Specify null to omit the + /// parameter. + /// if the specified X509Certificate is null + public TrustAnchor( + X509Certificate trustedCert, + byte[] nameConstraints) + { + if (trustedCert == null) + throw new ArgumentNullException("trustedCert"); + + this.trustedCert = trustedCert; + this.pubKey = null; + this.caName = null; + this.caPrincipal = null; + setNameConstraints(nameConstraints); + } + + /// + /// Creates an instance of TrustAnchor where the + /// most-trusted CA is specified as an X500Principal and public key. + /// + /// + ///

    + /// Name constraints are an optional parameter, and are intended to be used + /// as additional constraints when validating an X.509 certification path. + ///

    + /// The name constraints are specified as a byte array. This byte array + /// contains the DER encoded form of the name constraints, as they + /// would appear in the NameConstraints structure defined in RFC 2459 + /// and X.509. The ASN.1 notation for this structure is supplied in the + /// documentation for the other constructors. + ///

    + /// Note that the name constraints byte array supplied here is cloned to + /// protect against subsequent modifications. + ///

    + ///
    + /// the name of the most-trusted CA as X509Name + /// the public key of the most-trusted CA + /// + /// a byte array containing the ASN.1 DER encoding of a NameConstraints extension to + /// be used for checking name constraints. Only the value of the extension is included, + /// not the OID or criticality flag. Specify null to omit the parameter. + /// + /// + /// if caPrincipal or pubKey is null + /// + public TrustAnchor( + X509Name caPrincipal, + AsymmetricKeyParameter pubKey, + byte[] nameConstraints) + { + if (caPrincipal == null) + throw new ArgumentNullException("caPrincipal"); + if (pubKey == null) + throw new ArgumentNullException("pubKey"); + + this.trustedCert = null; + this.caPrincipal = caPrincipal; + this.caName = caPrincipal.ToString(); + this.pubKey = pubKey; + setNameConstraints(nameConstraints); + } + + /// + /// Creates an instance of TrustAnchor where the most-trusted + /// CA is specified as a distinguished name and public key. Name constraints + /// are an optional parameter, and are intended to be used as additional + /// constraints when validating an X.509 certification path. + ///
    + /// The name constraints are specified as a byte array. This byte array + /// contains the DER encoded form of the name constraints, as they would + /// appear in the NameConstraints structure defined in RFC 2459 and X.509. + ///
    + /// the X.500 distinguished name of the most-trusted CA in RFC + /// 2253 string format + /// the public key of the most-trusted CA + /// a byte array containing the ASN.1 DER encoding of a + /// NameConstraints extension to be used for checking name + /// constraints. Only the value of the extension is included, not + /// the OID or criticality flag. Specify null to omit the + /// parameter. + /// throws NullPointerException, IllegalArgumentException + public TrustAnchor( + string caName, + AsymmetricKeyParameter pubKey, + byte[] nameConstraints) + { + if (caName == null) + throw new ArgumentNullException("caName"); + if (pubKey == null) + throw new ArgumentNullException("pubKey"); + if (caName.Length == 0) + throw new ArgumentException("caName can not be an empty string"); + + this.caPrincipal = new X509Name(caName); + this.pubKey = pubKey; + this.caName = caName; + this.trustedCert = null; + setNameConstraints(nameConstraints); + } + + /// + /// Returns the most-trusted CA certificate. + /// + public X509Certificate TrustedCert + { + get { return this.trustedCert; } + } + + /// + /// Returns the name of the most-trusted CA as an X509Name. + /// + public X509Name CA + { + get { return this.caPrincipal; } + } + + /// + /// Returns the name of the most-trusted CA in RFC 2253 string format. + /// + public string CAName + { + get { return this.caName; } + } + + /// + /// Returns the public key of the most-trusted CA. + /// + public AsymmetricKeyParameter CAPublicKey + { + get { return this.pubKey; } + } + + /// + /// Decode the name constraints and clone them if not null. + /// + private void setNameConstraints( + byte[] bytes) + { + if (bytes == null) + { + ncBytes = null; + nc = null; + } + else + { + ncBytes = (byte[]) bytes.Clone(); + // validate DER encoding + //nc = new NameConstraintsExtension(Boolean.FALSE, bytes); + nc = NameConstraints.GetInstance(Asn1Object.FromByteArray(bytes)); + } + } + + public byte[] GetNameConstraints + { + get { return Arrays.Clone(ncBytes); } + } + + /// + /// Returns a formatted string describing the TrustAnchor. + /// + /// a formatted string describing the TrustAnchor + public override string ToString() + { + // TODO Some of the sub-objects might not implement ToString() properly + string nl = Platform.NewLine; + StringBuilder sb = new StringBuilder(); + sb.Append("["); + sb.Append(nl); + if (this.pubKey != null) + { + sb.Append(" Trusted CA Public Key: ").Append(this.pubKey).Append(nl); + sb.Append(" Trusted CA Issuer Name: ").Append(this.caName).Append(nl); + } + else + { + sb.Append(" Trusted CA cert: ").Append(this.TrustedCert).Append(nl); + } + if (nc != null) + { + sb.Append(" Name Constraints: ").Append(nc).Append(nl); + } + return sb.ToString(); + } + } +} \ No newline at end of file diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/TrustAnchor.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/TrustAnchor.cs.meta new file mode 100644 index 0000000..ae813fb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/pkix/TrustAnchor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 72d06cacad56f6a4ba9c9488387fc17b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security.meta new file mode 100644 index 0000000..f34a584 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 3e79e275e7307f141885ed4b04ac2c35 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/AgreementUtilities.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/AgreementUtilities.cs new file mode 100644 index 0000000..26d1628 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/AgreementUtilities.cs @@ -0,0 +1,124 @@ +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.EdEC; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Agreement; +using Org.BouncyCastle.Crypto.Agreement.Kdf; +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Security +{ + /// + /// Utility class for creating IBasicAgreement objects from their names/Oids + /// + public sealed class AgreementUtilities + { + private AgreementUtilities() + { + } + + private static readonly IDictionary algorithms = Platform.CreateHashtable(); + //private static readonly IDictionary oids = Platform.CreateHashtable(); + + static AgreementUtilities() + { + algorithms[X9ObjectIdentifiers.DHSinglePassCofactorDHSha1KdfScheme.Id] = "ECCDHWITHSHA1KDF"; + algorithms[X9ObjectIdentifiers.DHSinglePassStdDHSha1KdfScheme.Id] = "ECDHWITHSHA1KDF"; + algorithms[X9ObjectIdentifiers.MqvSinglePassSha1KdfScheme.Id] = "ECMQVWITHSHA1KDF"; + + algorithms[EdECObjectIdentifiers.id_X25519.Id] = "X25519"; + algorithms[EdECObjectIdentifiers.id_X448.Id] = "X448"; + } + + public static IBasicAgreement GetBasicAgreement( + DerObjectIdentifier oid) + { + return GetBasicAgreement(oid.Id); + } + + public static IBasicAgreement GetBasicAgreement( + string algorithm) + { + string mechanism = GetMechanism(algorithm); + + if (mechanism == "DH" || mechanism == "DIFFIEHELLMAN") + return new DHBasicAgreement(); + + if (mechanism == "ECDH") + return new ECDHBasicAgreement(); + + if (mechanism == "ECDHC" || mechanism == "ECCDH") + return new ECDHCBasicAgreement(); + + if (mechanism == "ECMQV") + return new ECMqvBasicAgreement(); + + throw new SecurityUtilityException("Basic Agreement " + algorithm + " not recognised."); + } + + public static IBasicAgreement GetBasicAgreementWithKdf( + DerObjectIdentifier oid, + string wrapAlgorithm) + { + return GetBasicAgreementWithKdf(oid.Id, wrapAlgorithm); + } + + public static IBasicAgreement GetBasicAgreementWithKdf( + string agreeAlgorithm, + string wrapAlgorithm) + { + string mechanism = GetMechanism(agreeAlgorithm); + + // 'DHWITHSHA1KDF' retained for backward compatibility + if (mechanism == "DHWITHSHA1KDF" || mechanism == "ECDHWITHSHA1KDF") + return new ECDHWithKdfBasicAgreement( + wrapAlgorithm, + new ECDHKekGenerator( + new Sha1Digest())); + + if (mechanism == "ECMQVWITHSHA1KDF") + return new ECMqvWithKdfBasicAgreement( + wrapAlgorithm, + new ECDHKekGenerator( + new Sha1Digest())); + + throw new SecurityUtilityException("Basic Agreement (with KDF) " + agreeAlgorithm + " not recognised."); + } + + public static IRawAgreement GetRawAgreement( + DerObjectIdentifier oid) + { + return GetRawAgreement(oid.Id); + } + + public static IRawAgreement GetRawAgreement( + string algorithm) + { + string mechanism = GetMechanism(algorithm); + + if (mechanism == "X25519") + return new X25519Agreement(); + + if (mechanism == "X448") + return new X448Agreement(); + + throw new SecurityUtilityException("Raw Agreement " + algorithm + " not recognised."); + } + + public static string GetAlgorithmName( + DerObjectIdentifier oid) + { + return (string)algorithms[oid.Id]; + } + + private static string GetMechanism(string algorithm) + { + string upper = Platform.ToUpperInvariant(algorithm); + string mechanism = (string)algorithms[upper]; + return mechanism == null ? upper : mechanism; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/AgreementUtilities.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/AgreementUtilities.cs.meta new file mode 100644 index 0000000..beb30d2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/AgreementUtilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b5a3ba69d7fe8f941a57dd89898cdd73 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/CipherUtilities.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/CipherUtilities.cs new file mode 100644 index 0000000..3b92add --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/CipherUtilities.cs @@ -0,0 +1,840 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Asn1.Kisa; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Nsri; +using Org.BouncyCastle.Asn1.Ntt; +using Org.BouncyCastle.Asn1.Oiw; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Agreement; +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Encodings; +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Macs; +using Org.BouncyCastle.Crypto.Modes; +using Org.BouncyCastle.Crypto.Paddings; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Security +{ + /// + /// Cipher Utility class contains methods that can not be specifically grouped into other classes. + /// + public sealed class CipherUtilities + { + private enum CipherAlgorithm { + AES, + ARC4, + ARIA, + BLOWFISH, + CAMELLIA, + CAST5, + CAST6, + CHACHA, + CHACHA20_POLY1305, + CHACHA7539, + DES, + DESEDE, + ELGAMAL, + GOST28147, + HC128, + HC256, + IDEA, + NOEKEON, + PBEWITHSHAAND128BITRC4, + PBEWITHSHAAND40BITRC4, + RC2, + RC5, + RC5_64, + RC6, + RIJNDAEL, + RSA, + SALSA20, + SEED, + SERPENT, + SKIPJACK, + SM4, + TEA, + THREEFISH_256, + THREEFISH_512, + THREEFISH_1024, + TNEPRES, + TWOFISH, + VMPC, + VMPC_KSA3, + XTEA, + }; + + private enum CipherMode { ECB, NONE, CBC, CCM, CFB, CTR, CTS, EAX, GCM, GOFB, OCB, OFB, OPENPGPCFB, SIC }; + private enum CipherPadding + { + NOPADDING, + RAW, + ISO10126PADDING, + ISO10126D2PADDING, + ISO10126_2PADDING, + ISO7816_4PADDING, + ISO9797_1PADDING, + ISO9796_1, + ISO9796_1PADDING, + OAEP, + OAEPPADDING, + OAEPWITHMD5ANDMGF1PADDING, + OAEPWITHSHA1ANDMGF1PADDING, + OAEPWITHSHA_1ANDMGF1PADDING, + OAEPWITHSHA224ANDMGF1PADDING, + OAEPWITHSHA_224ANDMGF1PADDING, + OAEPWITHSHA256ANDMGF1PADDING, + OAEPWITHSHA_256ANDMGF1PADDING, + OAEPWITHSHA256ANDMGF1WITHSHA256PADDING, + OAEPWITHSHA_256ANDMGF1WITHSHA_256PADDING, + OAEPWITHSHA256ANDMGF1WITHSHA1PADDING, + OAEPWITHSHA_256ANDMGF1WITHSHA_1PADDING, + OAEPWITHSHA384ANDMGF1PADDING, + OAEPWITHSHA_384ANDMGF1PADDING, + OAEPWITHSHA512ANDMGF1PADDING, + OAEPWITHSHA_512ANDMGF1PADDING, + PKCS1, + PKCS1PADDING, + PKCS5, + PKCS5PADDING, + PKCS7, + PKCS7PADDING, + TBCPADDING, + WITHCTS, + X923PADDING, + ZEROBYTEPADDING, + }; + + private static readonly IDictionary algorithms = Platform.CreateHashtable(); + private static readonly IDictionary oids = Platform.CreateHashtable(); + + static CipherUtilities() + { + // Signal to obfuscation tools not to change enum constants + ((CipherAlgorithm)Enums.GetArbitraryValue(typeof(CipherAlgorithm))).ToString(); + ((CipherMode)Enums.GetArbitraryValue(typeof(CipherMode))).ToString(); + ((CipherPadding)Enums.GetArbitraryValue(typeof(CipherPadding))).ToString(); + + // TODO Flesh out the list of aliases + + algorithms[NistObjectIdentifiers.IdAes128Cbc.Id] = "AES/CBC/PKCS7PADDING"; + algorithms[NistObjectIdentifiers.IdAes192Cbc.Id] = "AES/CBC/PKCS7PADDING"; + algorithms[NistObjectIdentifiers.IdAes256Cbc.Id] = "AES/CBC/PKCS7PADDING"; + + algorithms[NistObjectIdentifiers.IdAes128Ccm.Id] = "AES/CCM/NOPADDING"; + algorithms[NistObjectIdentifiers.IdAes192Ccm.Id] = "AES/CCM/NOPADDING"; + algorithms[NistObjectIdentifiers.IdAes256Ccm.Id] = "AES/CCM/NOPADDING"; + + algorithms[NistObjectIdentifiers.IdAes128Cfb.Id] = "AES/CFB/NOPADDING"; + algorithms[NistObjectIdentifiers.IdAes192Cfb.Id] = "AES/CFB/NOPADDING"; + algorithms[NistObjectIdentifiers.IdAes256Cfb.Id] = "AES/CFB/NOPADDING"; + + algorithms[NistObjectIdentifiers.IdAes128Ecb.Id] = "AES/ECB/PKCS7PADDING"; + algorithms[NistObjectIdentifiers.IdAes192Ecb.Id] = "AES/ECB/PKCS7PADDING"; + algorithms[NistObjectIdentifiers.IdAes256Ecb.Id] = "AES/ECB/PKCS7PADDING"; + algorithms["AES//PKCS7"] = "AES/ECB/PKCS7PADDING"; + algorithms["AES//PKCS7PADDING"] = "AES/ECB/PKCS7PADDING"; + algorithms["AES//PKCS5"] = "AES/ECB/PKCS7PADDING"; + algorithms["AES//PKCS5PADDING"] = "AES/ECB/PKCS7PADDING"; + + algorithms[NistObjectIdentifiers.IdAes128Gcm.Id] = "AES/GCM/NOPADDING"; + algorithms[NistObjectIdentifiers.IdAes192Gcm.Id] = "AES/GCM/NOPADDING"; + algorithms[NistObjectIdentifiers.IdAes256Gcm.Id] = "AES/GCM/NOPADDING"; + + algorithms[NistObjectIdentifiers.IdAes128Ofb.Id] = "AES/OFB/NOPADDING"; + algorithms[NistObjectIdentifiers.IdAes192Ofb.Id] = "AES/OFB/NOPADDING"; + algorithms[NistObjectIdentifiers.IdAes256Ofb.Id] = "AES/OFB/NOPADDING"; + + algorithms[NsriObjectIdentifiers.id_aria128_cbc.Id] = "ARIA/CBC/PKCS7PADDING"; + algorithms[NsriObjectIdentifiers.id_aria192_cbc.Id] = "ARIA/CBC/PKCS7PADDING"; + algorithms[NsriObjectIdentifiers.id_aria256_cbc.Id] = "ARIA/CBC/PKCS7PADDING"; + + algorithms[NsriObjectIdentifiers.id_aria128_ccm.Id] = "ARIA/CCM/NOPADDING"; + algorithms[NsriObjectIdentifiers.id_aria192_ccm.Id] = "ARIA/CCM/NOPADDING"; + algorithms[NsriObjectIdentifiers.id_aria256_ccm.Id] = "ARIA/CCM/NOPADDING"; + + algorithms[NsriObjectIdentifiers.id_aria128_cfb.Id] = "ARIA/CFB/NOPADDING"; + algorithms[NsriObjectIdentifiers.id_aria192_cfb.Id] = "ARIA/CFB/NOPADDING"; + algorithms[NsriObjectIdentifiers.id_aria256_cfb.Id] = "ARIA/CFB/NOPADDING"; + + algorithms[NsriObjectIdentifiers.id_aria128_ctr.Id] = "ARIA/CTR/NOPADDING"; + algorithms[NsriObjectIdentifiers.id_aria192_ctr.Id] = "ARIA/CTR/NOPADDING"; + algorithms[NsriObjectIdentifiers.id_aria256_ctr.Id] = "ARIA/CTR/NOPADDING"; + + algorithms[NsriObjectIdentifiers.id_aria128_ecb.Id] = "ARIA/ECB/PKCS7PADDING"; + algorithms[NsriObjectIdentifiers.id_aria192_ecb.Id] = "ARIA/ECB/PKCS7PADDING"; + algorithms[NsriObjectIdentifiers.id_aria256_ecb.Id] = "ARIA/ECB/PKCS7PADDING"; + algorithms["ARIA//PKCS7"] = "ARIA/ECB/PKCS7PADDING"; + algorithms["ARIA//PKCS7PADDING"] = "ARIA/ECB/PKCS7PADDING"; + algorithms["ARIA//PKCS5"] = "ARIA/ECB/PKCS7PADDING"; + algorithms["ARIA//PKCS5PADDING"] = "ARIA/ECB/PKCS7PADDING"; + + algorithms[NsriObjectIdentifiers.id_aria128_gcm.Id] = "ARIA/GCM/NOPADDING"; + algorithms[NsriObjectIdentifiers.id_aria192_gcm.Id] = "ARIA/GCM/NOPADDING"; + algorithms[NsriObjectIdentifiers.id_aria256_gcm.Id] = "ARIA/GCM/NOPADDING"; + + algorithms[NsriObjectIdentifiers.id_aria128_ofb.Id] = "ARIA/OFB/NOPADDING"; + algorithms[NsriObjectIdentifiers.id_aria192_ofb.Id] = "ARIA/OFB/NOPADDING"; + algorithms[NsriObjectIdentifiers.id_aria256_ofb.Id] = "ARIA/OFB/NOPADDING"; + + algorithms["RSA/ECB/PKCS1"] = "RSA//PKCS1PADDING"; + algorithms["RSA/ECB/PKCS1PADDING"] = "RSA//PKCS1PADDING"; + algorithms[PkcsObjectIdentifiers.RsaEncryption.Id] = "RSA//PKCS1PADDING"; + algorithms[PkcsObjectIdentifiers.IdRsaesOaep.Id] = "RSA//OAEPPADDING"; + + algorithms[OiwObjectIdentifiers.DesCbc.Id] = "DES/CBC"; + algorithms[OiwObjectIdentifiers.DesCfb.Id] = "DES/CFB"; + algorithms[OiwObjectIdentifiers.DesEcb.Id] = "DES/ECB"; + algorithms[OiwObjectIdentifiers.DesOfb.Id] = "DES/OFB"; + algorithms[OiwObjectIdentifiers.DesEde.Id] = "DESEDE"; + algorithms["TDEA"] = "DESEDE"; + algorithms[PkcsObjectIdentifiers.DesEde3Cbc.Id] = "DESEDE/CBC"; + algorithms[PkcsObjectIdentifiers.RC2Cbc.Id] = "RC2/CBC"; + algorithms["1.3.6.1.4.1.188.7.1.1.2"] = "IDEA/CBC"; + algorithms["1.2.840.113533.7.66.10"] = "CAST5/CBC"; + + algorithms["RC4"] = "ARC4"; + algorithms["ARCFOUR"] = "ARC4"; + algorithms["1.2.840.113549.3.4"] = "ARC4"; + + + + algorithms["PBEWITHSHA1AND128BITRC4"] = "PBEWITHSHAAND128BITRC4"; + algorithms[PkcsObjectIdentifiers.PbeWithShaAnd128BitRC4.Id] = "PBEWITHSHAAND128BITRC4"; + algorithms["PBEWITHSHA1AND40BITRC4"] = "PBEWITHSHAAND40BITRC4"; + algorithms[PkcsObjectIdentifiers.PbeWithShaAnd40BitRC4.Id] = "PBEWITHSHAAND40BITRC4"; + + algorithms["PBEWITHSHA1ANDDES"] = "PBEWITHSHA1ANDDES-CBC"; + algorithms[PkcsObjectIdentifiers.PbeWithSha1AndDesCbc.Id] = "PBEWITHSHA1ANDDES-CBC"; + algorithms["PBEWITHSHA1ANDRC2"] = "PBEWITHSHA1ANDRC2-CBC"; + algorithms[PkcsObjectIdentifiers.PbeWithSha1AndRC2Cbc.Id] = "PBEWITHSHA1ANDRC2-CBC"; + + algorithms["PBEWITHSHA1AND3-KEYTRIPLEDES-CBC"] = "PBEWITHSHAAND3-KEYTRIPLEDES-CBC"; + algorithms["PBEWITHSHAAND3KEYTRIPLEDES"] = "PBEWITHSHAAND3-KEYTRIPLEDES-CBC"; + algorithms[PkcsObjectIdentifiers.PbeWithShaAnd3KeyTripleDesCbc.Id] = "PBEWITHSHAAND3-KEYTRIPLEDES-CBC"; + algorithms["PBEWITHSHA1ANDDESEDE"] = "PBEWITHSHAAND3-KEYTRIPLEDES-CBC"; + + algorithms["PBEWITHSHA1AND2-KEYTRIPLEDES-CBC"] = "PBEWITHSHAAND2-KEYTRIPLEDES-CBC"; + algorithms[PkcsObjectIdentifiers.PbeWithShaAnd2KeyTripleDesCbc.Id] = "PBEWITHSHAAND2-KEYTRIPLEDES-CBC"; + + algorithms["PBEWITHSHA1AND128BITRC2-CBC"] = "PBEWITHSHAAND128BITRC2-CBC"; + algorithms[PkcsObjectIdentifiers.PbeWithShaAnd128BitRC2Cbc.Id] = "PBEWITHSHAAND128BITRC2-CBC"; + + algorithms["PBEWITHSHA1AND40BITRC2-CBC"] = "PBEWITHSHAAND40BITRC2-CBC"; + algorithms[PkcsObjectIdentifiers.PbewithShaAnd40BitRC2Cbc.Id] = "PBEWITHSHAAND40BITRC2-CBC"; + + algorithms["PBEWITHSHA1AND128BITAES-CBC-BC"] = "PBEWITHSHAAND128BITAES-CBC-BC"; + algorithms["PBEWITHSHA-1AND128BITAES-CBC-BC"] = "PBEWITHSHAAND128BITAES-CBC-BC"; + + algorithms["PBEWITHSHA1AND192BITAES-CBC-BC"] = "PBEWITHSHAAND192BITAES-CBC-BC"; + algorithms["PBEWITHSHA-1AND192BITAES-CBC-BC"] = "PBEWITHSHAAND192BITAES-CBC-BC"; + + algorithms["PBEWITHSHA1AND256BITAES-CBC-BC"] = "PBEWITHSHAAND256BITAES-CBC-BC"; + algorithms["PBEWITHSHA-1AND256BITAES-CBC-BC"] = "PBEWITHSHAAND256BITAES-CBC-BC"; + + algorithms["PBEWITHSHA-256AND128BITAES-CBC-BC"] = "PBEWITHSHA256AND128BITAES-CBC-BC"; + algorithms["PBEWITHSHA-256AND192BITAES-CBC-BC"] = "PBEWITHSHA256AND192BITAES-CBC-BC"; + algorithms["PBEWITHSHA-256AND256BITAES-CBC-BC"] = "PBEWITHSHA256AND256BITAES-CBC-BC"; + + + algorithms["GOST"] = "GOST28147"; + algorithms["GOST-28147"] = "GOST28147"; + algorithms[CryptoProObjectIdentifiers.GostR28147Cbc.Id] = "GOST28147/CBC/PKCS7PADDING"; + + algorithms["RC5-32"] = "RC5"; + + algorithms[NttObjectIdentifiers.IdCamellia128Cbc.Id] = "CAMELLIA/CBC/PKCS7PADDING"; + algorithms[NttObjectIdentifiers.IdCamellia192Cbc.Id] = "CAMELLIA/CBC/PKCS7PADDING"; + algorithms[NttObjectIdentifiers.IdCamellia256Cbc.Id] = "CAMELLIA/CBC/PKCS7PADDING"; + + algorithms[KisaObjectIdentifiers.IdSeedCbc.Id] = "SEED/CBC/PKCS7PADDING"; + + algorithms["1.3.6.1.4.1.3029.1.2"] = "BLOWFISH/CBC"; + + algorithms["CHACHA20"] = "CHACHA7539"; + algorithms[PkcsObjectIdentifiers.IdAlgAeadChaCha20Poly1305.Id] = "CHACHA20-POLY1305"; + } + + private CipherUtilities() + { + } + + /// + /// Returns a ObjectIdentifier for a give encoding. + /// + /// A string representation of the encoding. + /// A DerObjectIdentifier, null if the Oid is not available. + // TODO Don't really want to support this + public static DerObjectIdentifier GetObjectIdentifier( + string mechanism) + { + if (mechanism == null) + throw new ArgumentNullException("mechanism"); + + mechanism = Platform.ToUpperInvariant(mechanism); + string aliased = (string) algorithms[mechanism]; + + if (aliased != null) + mechanism = aliased; + + return (DerObjectIdentifier) oids[mechanism]; + } + + public static ICollection Algorithms + { + get { return oids.Keys; } + } + + public static IBufferedCipher GetCipher( + DerObjectIdentifier oid) + { + return GetCipher(oid.Id); + } + + public static IBufferedCipher GetCipher( + string algorithm) + { + if (algorithm == null) + throw new ArgumentNullException("algorithm"); + + algorithm = Platform.ToUpperInvariant(algorithm); + + { + string aliased = (string) algorithms[algorithm]; + + if (aliased != null) + algorithm = aliased; + } + + IBasicAgreement iesAgreement = null; + if (algorithm == "IES") + { + iesAgreement = new DHBasicAgreement(); + } + else if (algorithm == "ECIES") + { + iesAgreement = new ECDHBasicAgreement(); + } + + if (iesAgreement != null) + { + return new BufferedIesCipher( + new IesEngine( + iesAgreement, + new Kdf2BytesGenerator( + new Sha1Digest()), + new HMac( + new Sha1Digest()))); + } + + + + if (Platform.StartsWith(algorithm, "PBE")) + { + if (Platform.EndsWith(algorithm, "-CBC")) + { + if (algorithm == "PBEWITHSHA1ANDDES-CBC") + { + return new PaddedBufferedBlockCipher( + new CbcBlockCipher(new DesEngine())); + } + else if (algorithm == "PBEWITHSHA1ANDRC2-CBC") + { + return new PaddedBufferedBlockCipher( + new CbcBlockCipher(new RC2Engine())); + } + else if (Strings.IsOneOf(algorithm, + "PBEWITHSHAAND2-KEYTRIPLEDES-CBC", "PBEWITHSHAAND3-KEYTRIPLEDES-CBC")) + { + return new PaddedBufferedBlockCipher( + new CbcBlockCipher(new DesEdeEngine())); + } + else if (Strings.IsOneOf(algorithm, + "PBEWITHSHAAND128BITRC2-CBC", "PBEWITHSHAAND40BITRC2-CBC")) + { + return new PaddedBufferedBlockCipher( + new CbcBlockCipher(new RC2Engine())); + } + } + else if (Platform.EndsWith(algorithm, "-BC") || Platform.EndsWith(algorithm, "-OPENSSL")) + { + if (Strings.IsOneOf(algorithm, + "PBEWITHSHAAND128BITAES-CBC-BC", + "PBEWITHSHAAND192BITAES-CBC-BC", + "PBEWITHSHAAND256BITAES-CBC-BC", + "PBEWITHSHA256AND128BITAES-CBC-BC", + "PBEWITHSHA256AND192BITAES-CBC-BC", + "PBEWITHSHA256AND256BITAES-CBC-BC", + "PBEWITHMD5AND128BITAES-CBC-OPENSSL", + "PBEWITHMD5AND192BITAES-CBC-OPENSSL", + "PBEWITHMD5AND256BITAES-CBC-OPENSSL")) + { + return new PaddedBufferedBlockCipher( + new CbcBlockCipher(new AesEngine())); + } + } + } + + + + string[] parts = algorithm.Split('/'); + + IAeadCipher aeadCipher = null; + IBlockCipher blockCipher = null; + IAsymmetricBlockCipher asymBlockCipher = null; + IStreamCipher streamCipher = null; + + string algorithmName = parts[0]; + + { + string aliased = (string)algorithms[algorithmName]; + + if (aliased != null) + algorithmName = aliased; + } + + CipherAlgorithm cipherAlgorithm; + try + { + cipherAlgorithm = (CipherAlgorithm)Enums.GetEnumValue(typeof(CipherAlgorithm), algorithmName); + } + catch (ArgumentException) + { + throw new SecurityUtilityException("Cipher " + algorithm + " not recognised."); + } + + switch (cipherAlgorithm) + { + case CipherAlgorithm.AES: + blockCipher = new AesEngine(); + break; + case CipherAlgorithm.ARC4: + streamCipher = new RC4Engine(); + break; + case CipherAlgorithm.ARIA: + blockCipher = new AriaEngine(); + break; + case CipherAlgorithm.BLOWFISH: + blockCipher = new BlowfishEngine(); + break; + case CipherAlgorithm.CAMELLIA: + blockCipher = new CamelliaEngine(); + break; + case CipherAlgorithm.CAST5: + blockCipher = new Cast5Engine(); + break; + case CipherAlgorithm.CAST6: + blockCipher = new Cast6Engine(); + break; + case CipherAlgorithm.CHACHA: + streamCipher = new ChaChaEngine(); + break; + case CipherAlgorithm.CHACHA20_POLY1305: + aeadCipher = new ChaCha20Poly1305(); + break; + case CipherAlgorithm.CHACHA7539: + streamCipher = new ChaCha7539Engine(); + break; + case CipherAlgorithm.DES: + blockCipher = new DesEngine(); + break; + case CipherAlgorithm.DESEDE: + blockCipher = new DesEdeEngine(); + break; + case CipherAlgorithm.ELGAMAL: + asymBlockCipher = new ElGamalEngine(); + break; + case CipherAlgorithm.GOST28147: + blockCipher = new Gost28147Engine(); + break; + case CipherAlgorithm.HC128: + streamCipher = new HC128Engine(); + break; + case CipherAlgorithm.HC256: + streamCipher = new HC256Engine(); + break; + case CipherAlgorithm.IDEA: + blockCipher = new IdeaEngine(); + break; + case CipherAlgorithm.NOEKEON: + blockCipher = new NoekeonEngine(); + break; + case CipherAlgorithm.PBEWITHSHAAND128BITRC4: + case CipherAlgorithm.PBEWITHSHAAND40BITRC4: + streamCipher = new RC4Engine(); + break; + case CipherAlgorithm.RC2: + blockCipher = new RC2Engine(); + break; + case CipherAlgorithm.RC5: + blockCipher = new RC532Engine(); + break; + case CipherAlgorithm.RC5_64: + blockCipher = new RC564Engine(); + break; + case CipherAlgorithm.RC6: + blockCipher = new RC6Engine(); + break; + case CipherAlgorithm.RIJNDAEL: + blockCipher = new RijndaelEngine(); + break; + case CipherAlgorithm.RSA: + asymBlockCipher = new RsaBlindedEngine(); + break; + case CipherAlgorithm.SALSA20: + streamCipher = new Salsa20Engine(); + break; + case CipherAlgorithm.SEED: + blockCipher = new SeedEngine(); + break; + case CipherAlgorithm.SERPENT: + blockCipher = new SerpentEngine(); + break; + case CipherAlgorithm.SKIPJACK: + blockCipher = new SkipjackEngine(); + break; + case CipherAlgorithm.SM4: + blockCipher = new SM4Engine(); + break; + case CipherAlgorithm.TEA: + blockCipher = new TeaEngine(); + break; + case CipherAlgorithm.THREEFISH_256: + blockCipher = new ThreefishEngine(ThreefishEngine.BLOCKSIZE_256); + break; + case CipherAlgorithm.THREEFISH_512: + blockCipher = new ThreefishEngine(ThreefishEngine.BLOCKSIZE_512); + break; + case CipherAlgorithm.THREEFISH_1024: + blockCipher = new ThreefishEngine(ThreefishEngine.BLOCKSIZE_1024); + break; + case CipherAlgorithm.TNEPRES: + blockCipher = new TnepresEngine(); + break; + case CipherAlgorithm.TWOFISH: + blockCipher = new TwofishEngine(); + break; + case CipherAlgorithm.VMPC: + streamCipher = new VmpcEngine(); + break; + case CipherAlgorithm.VMPC_KSA3: + streamCipher = new VmpcKsa3Engine(); + break; + case CipherAlgorithm.XTEA: + blockCipher = new XteaEngine(); + break; + default: + throw new SecurityUtilityException("Cipher " + algorithm + " not recognised."); + } + + if (aeadCipher != null) + { + if (parts.Length > 1) + throw new ArgumentException("Modes and paddings cannot be applied to AEAD ciphers"); + + return new BufferedAeadCipher(aeadCipher); + } + + if (streamCipher != null) + { + if (parts.Length > 1) + throw new ArgumentException("Modes and paddings not used for stream ciphers"); + + return new BufferedStreamCipher(streamCipher); + } + + + bool cts = false; + bool padded = true; + IBlockCipherPadding padding = null; + IAeadBlockCipher aeadBlockCipher = null; + + if (parts.Length > 2) + { + if (streamCipher != null) + throw new ArgumentException("Paddings not used for stream ciphers"); + + string paddingName = parts[2]; + + CipherPadding cipherPadding; + if (paddingName == "") + { + cipherPadding = CipherPadding.RAW; + } + else if (paddingName == "X9.23PADDING") + { + cipherPadding = CipherPadding.X923PADDING; + } + else + { + try + { + cipherPadding = (CipherPadding)Enums.GetEnumValue(typeof(CipherPadding), paddingName); + } + catch (ArgumentException) + { + throw new SecurityUtilityException("Cipher " + algorithm + " not recognised."); + } + } + + switch (cipherPadding) + { + case CipherPadding.NOPADDING: + padded = false; + break; + case CipherPadding.RAW: + break; + case CipherPadding.ISO10126PADDING: + case CipherPadding.ISO10126D2PADDING: + case CipherPadding.ISO10126_2PADDING: + padding = new ISO10126d2Padding(); + break; + case CipherPadding.ISO7816_4PADDING: + case CipherPadding.ISO9797_1PADDING: + padding = new ISO7816d4Padding(); + break; + case CipherPadding.ISO9796_1: + case CipherPadding.ISO9796_1PADDING: + asymBlockCipher = new ISO9796d1Encoding(asymBlockCipher); + break; + case CipherPadding.OAEP: + case CipherPadding.OAEPPADDING: + asymBlockCipher = new OaepEncoding(asymBlockCipher); + break; + case CipherPadding.OAEPWITHMD5ANDMGF1PADDING: + asymBlockCipher = new OaepEncoding(asymBlockCipher, new MD5Digest()); + break; + case CipherPadding.OAEPWITHSHA1ANDMGF1PADDING: + case CipherPadding.OAEPWITHSHA_1ANDMGF1PADDING: + asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha1Digest()); + break; + case CipherPadding.OAEPWITHSHA224ANDMGF1PADDING: + case CipherPadding.OAEPWITHSHA_224ANDMGF1PADDING: + asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha224Digest()); + break; + case CipherPadding.OAEPWITHSHA256ANDMGF1PADDING: + case CipherPadding.OAEPWITHSHA_256ANDMGF1PADDING: + case CipherPadding.OAEPWITHSHA256ANDMGF1WITHSHA256PADDING: + case CipherPadding.OAEPWITHSHA_256ANDMGF1WITHSHA_256PADDING: + asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha256Digest()); + break; + case CipherPadding.OAEPWITHSHA256ANDMGF1WITHSHA1PADDING: + case CipherPadding.OAEPWITHSHA_256ANDMGF1WITHSHA_1PADDING: + asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha256Digest(), new Sha1Digest(), null); + break; + case CipherPadding.OAEPWITHSHA384ANDMGF1PADDING: + case CipherPadding.OAEPWITHSHA_384ANDMGF1PADDING: + asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha384Digest()); + break; + case CipherPadding.OAEPWITHSHA512ANDMGF1PADDING: + case CipherPadding.OAEPWITHSHA_512ANDMGF1PADDING: + asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha512Digest()); + break; + case CipherPadding.PKCS1: + case CipherPadding.PKCS1PADDING: + asymBlockCipher = new Pkcs1Encoding(asymBlockCipher); + break; + case CipherPadding.PKCS5: + case CipherPadding.PKCS5PADDING: + case CipherPadding.PKCS7: + case CipherPadding.PKCS7PADDING: + padding = new Pkcs7Padding(); + break; + case CipherPadding.TBCPADDING: + padding = new TbcPadding(); + break; + case CipherPadding.WITHCTS: + cts = true; + break; + case CipherPadding.X923PADDING: + padding = new X923Padding(); + break; + case CipherPadding.ZEROBYTEPADDING: + padding = new ZeroBytePadding(); + break; + default: + throw new SecurityUtilityException("Cipher " + algorithm + " not recognised."); + } + } + + string mode = ""; + if (parts.Length > 1) + { + mode = parts[1]; + + int di = GetDigitIndex(mode); + string modeName = di >= 0 ? mode.Substring(0, di) : mode; + + try + { + CipherMode cipherMode = modeName == "" + ? CipherMode.NONE + : (CipherMode)Enums.GetEnumValue(typeof(CipherMode), modeName); + + switch (cipherMode) + { + case CipherMode.ECB: + case CipherMode.NONE: + break; + case CipherMode.CBC: + blockCipher = new CbcBlockCipher(blockCipher); + break; + case CipherMode.CCM: + aeadBlockCipher = new CcmBlockCipher(blockCipher); + break; + case CipherMode.CFB: + { + int bits = (di < 0) + ? 8 * blockCipher.GetBlockSize() + : int.Parse(mode.Substring(di)); + + blockCipher = new CfbBlockCipher(blockCipher, bits); + break; + } + case CipherMode.CTR: + blockCipher = new SicBlockCipher(blockCipher); + break; + case CipherMode.CTS: + cts = true; + blockCipher = new CbcBlockCipher(blockCipher); + break; + case CipherMode.EAX: + aeadBlockCipher = new EaxBlockCipher(blockCipher); + break; + case CipherMode.GCM: + aeadBlockCipher = new GcmBlockCipher(blockCipher); + break; + case CipherMode.GOFB: + blockCipher = new GOfbBlockCipher(blockCipher); + break; + case CipherMode.OCB: + aeadBlockCipher = new OcbBlockCipher(blockCipher, CreateBlockCipher(cipherAlgorithm)); + break; + case CipherMode.OFB: + { + int bits = (di < 0) + ? 8 * blockCipher.GetBlockSize() + : int.Parse(mode.Substring(di)); + + blockCipher = new OfbBlockCipher(blockCipher, bits); + break; + } + case CipherMode.OPENPGPCFB: + blockCipher = new OpenPgpCfbBlockCipher(blockCipher); + break; + case CipherMode.SIC: + if (blockCipher.GetBlockSize() < 16) + { + throw new ArgumentException("Warning: SIC-Mode can become a twotime-pad if the blocksize of the cipher is too small. Use a cipher with a block size of at least 128 bits (e.g. AES)"); + } + blockCipher = new SicBlockCipher(blockCipher); + break; + default: + throw new SecurityUtilityException("Cipher " + algorithm + " not recognised."); + } + } + catch (ArgumentException) + { + throw new SecurityUtilityException("Cipher " + algorithm + " not recognised."); + } + } + + if (aeadBlockCipher != null) + { + if (cts) + throw new SecurityUtilityException("CTS mode not valid for AEAD ciphers."); + if (padded && parts.Length > 2 && parts[2] != "") + throw new SecurityUtilityException("Bad padding specified for AEAD cipher."); + + return new BufferedAeadBlockCipher(aeadBlockCipher); + } + + if (blockCipher != null) + { + if (cts) + { + return new CtsBlockCipher(blockCipher); + } + + if (padding != null) + { + return new PaddedBufferedBlockCipher(blockCipher, padding); + } + + if (!padded || blockCipher.IsPartialBlockOkay) + { + return new BufferedBlockCipher(blockCipher); + } + + return new PaddedBufferedBlockCipher(blockCipher); + } + + if (asymBlockCipher != null) + { + return new BufferedAsymmetricBlockCipher(asymBlockCipher); + } + + throw new SecurityUtilityException("Cipher " + algorithm + " not recognised."); + } + + public static string GetAlgorithmName( + DerObjectIdentifier oid) + { + return (string) algorithms[oid.Id]; + } + + private static int GetDigitIndex( + string s) + { + for (int i = 0; i < s.Length; ++i) + { + if (char.IsDigit(s[i])) + return i; + } + + return -1; + } + + private static IBlockCipher CreateBlockCipher(CipherAlgorithm cipherAlgorithm) + { + switch (cipherAlgorithm) + { + case CipherAlgorithm.AES: return new AesEngine(); + case CipherAlgorithm.ARIA: return new AriaEngine(); + case CipherAlgorithm.BLOWFISH: return new BlowfishEngine(); + case CipherAlgorithm.CAMELLIA: return new CamelliaEngine(); + case CipherAlgorithm.CAST5: return new Cast5Engine(); + case CipherAlgorithm.CAST6: return new Cast6Engine(); + case CipherAlgorithm.DES: return new DesEngine(); + case CipherAlgorithm.DESEDE: return new DesEdeEngine(); + case CipherAlgorithm.GOST28147: return new Gost28147Engine(); + case CipherAlgorithm.IDEA: return new IdeaEngine(); + case CipherAlgorithm.NOEKEON: return new NoekeonEngine(); + case CipherAlgorithm.RC2: return new RC2Engine(); + case CipherAlgorithm.RC5: return new RC532Engine(); + case CipherAlgorithm.RC5_64: return new RC564Engine(); + case CipherAlgorithm.RC6: return new RC6Engine(); + case CipherAlgorithm.RIJNDAEL: return new RijndaelEngine(); + case CipherAlgorithm.SEED: return new SeedEngine(); + case CipherAlgorithm.SERPENT: return new SerpentEngine(); + case CipherAlgorithm.SKIPJACK: return new SkipjackEngine(); + case CipherAlgorithm.SM4: return new SM4Engine(); + case CipherAlgorithm.TEA: return new TeaEngine(); + case CipherAlgorithm.THREEFISH_256: return new ThreefishEngine(ThreefishEngine.BLOCKSIZE_256); + case CipherAlgorithm.THREEFISH_512: return new ThreefishEngine(ThreefishEngine.BLOCKSIZE_512); + case CipherAlgorithm.THREEFISH_1024: return new ThreefishEngine(ThreefishEngine.BLOCKSIZE_1024); + case CipherAlgorithm.TNEPRES: return new TnepresEngine(); + case CipherAlgorithm.TWOFISH: return new TwofishEngine(); + case CipherAlgorithm.XTEA: return new XteaEngine(); + default: + throw new SecurityUtilityException("Cipher " + cipherAlgorithm + " not recognised or not a block cipher"); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/CipherUtilities.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/CipherUtilities.cs.meta new file mode 100644 index 0000000..cdd2f72 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/CipherUtilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4e64fc2bd7bd0c34a95edbfb325b5964 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/DigestUtilities.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/DigestUtilities.cs new file mode 100644 index 0000000..c67dd8b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/DigestUtilities.cs @@ -0,0 +1,307 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Asn1.GM; +using Org.BouncyCastle.Asn1.Misc; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.Oiw; +using Org.BouncyCastle.Asn1.Rosstandart; +using Org.BouncyCastle.Asn1.TeleTrust; +using Org.BouncyCastle.Asn1.UA; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Security +{ + /// + /// Utility class for creating IDigest objects from their names/Oids + /// + public sealed class DigestUtilities + { + private enum DigestAlgorithm { + BLAKE2B_160, BLAKE2B_256, BLAKE2B_384, BLAKE2B_512, + BLAKE2S_128, BLAKE2S_160, BLAKE2S_224, BLAKE2S_256, + DSTU7564_256, DSTU7564_384, DSTU7564_512, + GOST3411, + GOST3411_2012_256, GOST3411_2012_512, + KECCAK_224, KECCAK_256, KECCAK_288, KECCAK_384, KECCAK_512, + MD2, MD4, MD5, + NONE, + RIPEMD128, RIPEMD160, RIPEMD256, RIPEMD320, + SHA_1, SHA_224, SHA_256, SHA_384, SHA_512, + SHA_512_224, SHA_512_256, + SHA3_224, SHA3_256, SHA3_384, SHA3_512, + SHAKE128_256, SHAKE256_512, + SM3, + TIGER, + WHIRLPOOL, + }; + + private DigestUtilities() + { + } + + private static readonly IDictionary algorithms = Platform.CreateHashtable(); + private static readonly IDictionary oids = Platform.CreateHashtable(); + + static DigestUtilities() + { + // Signal to obfuscation tools not to change enum constants + ((DigestAlgorithm)Enums.GetArbitraryValue(typeof(DigestAlgorithm))).ToString(); + + algorithms[PkcsObjectIdentifiers.MD2.Id] = "MD2"; + algorithms[PkcsObjectIdentifiers.MD4.Id] = "MD4"; + algorithms[PkcsObjectIdentifiers.MD5.Id] = "MD5"; + + algorithms["SHA1"] = "SHA-1"; + algorithms[OiwObjectIdentifiers.IdSha1.Id] = "SHA-1"; + algorithms[PkcsObjectIdentifiers.IdHmacWithSha1.Id] = "SHA-1"; + algorithms[MiscObjectIdentifiers.HMAC_SHA1.Id] = "SHA-1"; + algorithms["SHA224"] = "SHA-224"; + algorithms[NistObjectIdentifiers.IdSha224.Id] = "SHA-224"; + algorithms[PkcsObjectIdentifiers.IdHmacWithSha224.Id] = "SHA-224"; + algorithms["SHA256"] = "SHA-256"; + algorithms[NistObjectIdentifiers.IdSha256.Id] = "SHA-256"; + algorithms[PkcsObjectIdentifiers.IdHmacWithSha256.Id] = "SHA-256"; + algorithms["SHA384"] = "SHA-384"; + algorithms[NistObjectIdentifiers.IdSha384.Id] = "SHA-384"; + algorithms[PkcsObjectIdentifiers.IdHmacWithSha384.Id] = "SHA-384"; + algorithms["SHA512"] = "SHA-512"; + algorithms[NistObjectIdentifiers.IdSha512.Id] = "SHA-512"; + algorithms[PkcsObjectIdentifiers.IdHmacWithSha512.Id] = "SHA-512"; + + algorithms["SHA512/224"] = "SHA-512/224"; + algorithms["SHA512(224)"] = "SHA-512/224"; + algorithms["SHA-512(224)"] = "SHA-512/224"; + algorithms[NistObjectIdentifiers.IdSha512_224.Id] = "SHA-512/224"; + algorithms["SHA512/256"] = "SHA-512/256"; + algorithms["SHA512(256)"] = "SHA-512/256"; + algorithms["SHA-512(256)"] = "SHA-512/256"; + algorithms[NistObjectIdentifiers.IdSha512_256.Id] = "SHA-512/256"; + + algorithms["RIPEMD-128"] = "RIPEMD128"; + algorithms[TeleTrusTObjectIdentifiers.RipeMD128.Id] = "RIPEMD128"; + algorithms["RIPEMD-160"] = "RIPEMD160"; + algorithms[TeleTrusTObjectIdentifiers.RipeMD160.Id] = "RIPEMD160"; + algorithms["RIPEMD-256"] = "RIPEMD256"; + algorithms[TeleTrusTObjectIdentifiers.RipeMD256.Id] = "RIPEMD256"; + algorithms["RIPEMD-320"] = "RIPEMD320"; +// algorithms[TeleTrusTObjectIdentifiers.RipeMD320.Id] = "RIPEMD320"; + + algorithms[CryptoProObjectIdentifiers.GostR3411.Id] = "GOST3411"; + + algorithms["KECCAK224"] = "KECCAK-224"; + algorithms["KECCAK256"] = "KECCAK-256"; + algorithms["KECCAK288"] = "KECCAK-288"; + algorithms["KECCAK384"] = "KECCAK-384"; + algorithms["KECCAK512"] = "KECCAK-512"; + + algorithms[NistObjectIdentifiers.IdSha3_224.Id] = "SHA3-224"; + algorithms[NistObjectIdentifiers.IdHMacWithSha3_224.Id] = "SHA3-224"; + algorithms[NistObjectIdentifiers.IdSha3_256.Id] = "SHA3-256"; + algorithms[NistObjectIdentifiers.IdHMacWithSha3_256.Id] = "SHA3-256"; + algorithms[NistObjectIdentifiers.IdSha3_384.Id] = "SHA3-384"; + algorithms[NistObjectIdentifiers.IdHMacWithSha3_384.Id] = "SHA3-384"; + algorithms[NistObjectIdentifiers.IdSha3_512.Id] = "SHA3-512"; + algorithms[NistObjectIdentifiers.IdHMacWithSha3_512.Id] = "SHA3-512"; + algorithms["SHAKE128"] = "SHAKE128-256"; + algorithms[NistObjectIdentifiers.IdShake128.Id] = "SHAKE128-256"; + algorithms["SHAKE256"] = "SHAKE256-512"; + algorithms[NistObjectIdentifiers.IdShake256.Id] = "SHAKE256-512"; + + algorithms[GMObjectIdentifiers.sm3.Id] = "SM3"; + + algorithms[MiscObjectIdentifiers.id_blake2b160.Id] = "BLAKE2B-160"; + algorithms[MiscObjectIdentifiers.id_blake2b256.Id] = "BLAKE2B-256"; + algorithms[MiscObjectIdentifiers.id_blake2b384.Id] = "BLAKE2B-384"; + algorithms[MiscObjectIdentifiers.id_blake2b512.Id] = "BLAKE2B-512"; + algorithms[MiscObjectIdentifiers.id_blake2s128.Id] = "BLAKE2S-128"; + algorithms[MiscObjectIdentifiers.id_blake2s160.Id] = "BLAKE2S-160"; + algorithms[MiscObjectIdentifiers.id_blake2s224.Id] = "BLAKE2S-224"; + algorithms[MiscObjectIdentifiers.id_blake2s256.Id] = "BLAKE2S-256"; + + algorithms[RosstandartObjectIdentifiers.id_tc26_gost_3411_12_256.Id] = "GOST3411-2012-256"; + algorithms[RosstandartObjectIdentifiers.id_tc26_gost_3411_12_512.Id] = "GOST3411-2012-512"; + + algorithms[UAObjectIdentifiers.dstu7564digest_256.Id] = "DSTU7564-256"; + algorithms[UAObjectIdentifiers.dstu7564digest_384.Id] = "DSTU7564-384"; + algorithms[UAObjectIdentifiers.dstu7564digest_512.Id] = "DSTU7564-512"; + + oids["MD2"] = PkcsObjectIdentifiers.MD2; + oids["MD4"] = PkcsObjectIdentifiers.MD4; + oids["MD5"] = PkcsObjectIdentifiers.MD5; + oids["SHA-1"] = OiwObjectIdentifiers.IdSha1; + oids["SHA-224"] = NistObjectIdentifiers.IdSha224; + oids["SHA-256"] = NistObjectIdentifiers.IdSha256; + oids["SHA-384"] = NistObjectIdentifiers.IdSha384; + oids["SHA-512"] = NistObjectIdentifiers.IdSha512; + oids["SHA-512/224"] = NistObjectIdentifiers.IdSha512_224; + oids["SHA-512/256"] = NistObjectIdentifiers.IdSha512_256; + oids["SHA3-224"] = NistObjectIdentifiers.IdSha3_224; + oids["SHA3-256"] = NistObjectIdentifiers.IdSha3_256; + oids["SHA3-384"] = NistObjectIdentifiers.IdSha3_384; + oids["SHA3-512"] = NistObjectIdentifiers.IdSha3_512; + oids["SHAKE128-256"] = NistObjectIdentifiers.IdShake128; + oids["SHAKE256-512"] = NistObjectIdentifiers.IdShake256; + oids["RIPEMD128"] = TeleTrusTObjectIdentifiers.RipeMD128; + oids["RIPEMD160"] = TeleTrusTObjectIdentifiers.RipeMD160; + oids["RIPEMD256"] = TeleTrusTObjectIdentifiers.RipeMD256; + oids["GOST3411"] = CryptoProObjectIdentifiers.GostR3411; + oids["SM3"] = GMObjectIdentifiers.sm3; + oids["BLAKE2B-160"] = MiscObjectIdentifiers.id_blake2b160; + oids["BLAKE2B-256"] = MiscObjectIdentifiers.id_blake2b256; + oids["BLAKE2B-384"] = MiscObjectIdentifiers.id_blake2b384; + oids["BLAKE2B-512"] = MiscObjectIdentifiers.id_blake2b512; + oids["BLAKE2S-128"] = MiscObjectIdentifiers.id_blake2s128; + oids["BLAKE2S-160"] = MiscObjectIdentifiers.id_blake2s160; + oids["BLAKE2S-224"] = MiscObjectIdentifiers.id_blake2s224; + oids["BLAKE2S-256"] = MiscObjectIdentifiers.id_blake2s256; + oids["GOST3411-2012-256"] = RosstandartObjectIdentifiers.id_tc26_gost_3411_12_256; + oids["GOST3411-2012-512"] = RosstandartObjectIdentifiers.id_tc26_gost_3411_12_512; + oids["DSTU7564-256"] = UAObjectIdentifiers.dstu7564digest_256; + oids["DSTU7564-384"] = UAObjectIdentifiers.dstu7564digest_384; + oids["DSTU7564-512"] = UAObjectIdentifiers.dstu7564digest_512; + } + + /// + /// Returns a ObjectIdentifier for a given digest mechanism. + /// + /// A string representation of the digest meanism. + /// A DerObjectIdentifier, null if the Oid is not available. + + public static DerObjectIdentifier GetObjectIdentifier( + string mechanism) + { + if (mechanism == null) + throw new System.ArgumentNullException("mechanism"); + + mechanism = Platform.ToUpperInvariant(mechanism); + string aliased = (string) algorithms[mechanism]; + + if (aliased != null) + mechanism = aliased; + + return (DerObjectIdentifier) oids[mechanism]; + } + + public static ICollection Algorithms + { + get { return oids.Keys; } + } + + public static IDigest GetDigest( + DerObjectIdentifier id) + { + return GetDigest(id.Id); + } + + public static IDigest GetDigest( + string algorithm) + { + string upper = Platform.ToUpperInvariant(algorithm); + string mechanism = (string) algorithms[upper]; + + if (mechanism == null) + { + mechanism = upper; + } + + try + { + DigestAlgorithm digestAlgorithm = (DigestAlgorithm)Enums.GetEnumValue( + typeof(DigestAlgorithm), mechanism); + + switch (digestAlgorithm) + { + case DigestAlgorithm.BLAKE2B_160: return new Blake2bDigest(160); + case DigestAlgorithm.BLAKE2B_256: return new Blake2bDigest(256); + case DigestAlgorithm.BLAKE2B_384: return new Blake2bDigest(384); + case DigestAlgorithm.BLAKE2B_512: return new Blake2bDigest(512); + case DigestAlgorithm.BLAKE2S_128: return new Blake2sDigest(128); + case DigestAlgorithm.BLAKE2S_160: return new Blake2sDigest(160); + case DigestAlgorithm.BLAKE2S_224: return new Blake2sDigest(224); + case DigestAlgorithm.BLAKE2S_256: return new Blake2sDigest(256); + case DigestAlgorithm.DSTU7564_256: return new Dstu7564Digest(256); + case DigestAlgorithm.DSTU7564_384: return new Dstu7564Digest(384); + case DigestAlgorithm.DSTU7564_512: return new Dstu7564Digest(512); + case DigestAlgorithm.GOST3411: return new Gost3411Digest(); + case DigestAlgorithm.GOST3411_2012_256: return new Gost3411_2012_256Digest(); + case DigestAlgorithm.GOST3411_2012_512: return new Gost3411_2012_512Digest(); + case DigestAlgorithm.KECCAK_224: return new KeccakDigest(224); + case DigestAlgorithm.KECCAK_256: return new KeccakDigest(256); + case DigestAlgorithm.KECCAK_288: return new KeccakDigest(288); + case DigestAlgorithm.KECCAK_384: return new KeccakDigest(384); + case DigestAlgorithm.KECCAK_512: return new KeccakDigest(512); + case DigestAlgorithm.MD2: return new MD2Digest(); + case DigestAlgorithm.MD4: return new MD4Digest(); + case DigestAlgorithm.MD5: return new MD5Digest(); + case DigestAlgorithm.NONE: return new NullDigest(); + case DigestAlgorithm.RIPEMD128: return new RipeMD128Digest(); + case DigestAlgorithm.RIPEMD160: return new RipeMD160Digest(); + case DigestAlgorithm.RIPEMD256: return new RipeMD256Digest(); + case DigestAlgorithm.RIPEMD320: return new RipeMD320Digest(); + case DigestAlgorithm.SHA_1: return new Sha1Digest(); + case DigestAlgorithm.SHA_224: return new Sha224Digest(); + case DigestAlgorithm.SHA_256: return new Sha256Digest(); + case DigestAlgorithm.SHA_384: return new Sha384Digest(); + case DigestAlgorithm.SHA_512: return new Sha512Digest(); + case DigestAlgorithm.SHA_512_224: return new Sha512tDigest(224); + case DigestAlgorithm.SHA_512_256: return new Sha512tDigest(256); + case DigestAlgorithm.SHA3_224: return new Sha3Digest(224); + case DigestAlgorithm.SHA3_256: return new Sha3Digest(256); + case DigestAlgorithm.SHA3_384: return new Sha3Digest(384); + case DigestAlgorithm.SHA3_512: return new Sha3Digest(512); + case DigestAlgorithm.SHAKE128_256: return new ShakeDigest(128); + case DigestAlgorithm.SHAKE256_512: return new ShakeDigest(256); + case DigestAlgorithm.SM3: return new SM3Digest(); + case DigestAlgorithm.TIGER: return new TigerDigest(); + case DigestAlgorithm.WHIRLPOOL: return new WhirlpoolDigest(); + } + } + catch (ArgumentException) + { + } + + throw new SecurityUtilityException("Digest " + mechanism + " not recognised."); + } + + public static string GetAlgorithmName( + DerObjectIdentifier oid) + { + return (string) algorithms[oid.Id]; + } + + public static byte[] CalculateDigest(DerObjectIdentifier id, byte[] input) + { + return CalculateDigest(id.Id, input); + } + + public static byte[] CalculateDigest(string algorithm, byte[] input) + { + IDigest digest = GetDigest(algorithm); + digest.BlockUpdate(input, 0, input.Length); + return DoFinal(digest); + } + + public static byte[] DoFinal( + IDigest digest) + { + byte[] b = new byte[digest.GetDigestSize()]; + digest.DoFinal(b, 0); + return b; + } + + public static byte[] DoFinal( + IDigest digest, + byte[] input) + { + digest.BlockUpdate(input, 0, input.Length); + return DoFinal(digest); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/DigestUtilities.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/DigestUtilities.cs.meta new file mode 100644 index 0000000..0fc1268 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/DigestUtilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1526a5a4bd227ca48a4f50d2e2089b52 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/DotNetUtilities.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/DotNetUtilities.cs new file mode 100644 index 0000000..df9d327 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/DotNetUtilities.cs @@ -0,0 +1,260 @@ +#if !(NETCF_1_0 || SILVERLIGHT || PORTABLE) + +using System; +using System.Security.Cryptography; +using SystemX509 = System.Security.Cryptography.X509Certificates; + +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.Security +{ + /// + /// A class containing methods to interface the BouncyCastle world to the .NET Crypto world. + /// + public sealed class DotNetUtilities + { + private DotNetUtilities() + { + } + + /// + /// Create an System.Security.Cryptography.X509Certificate from an X509Certificate Structure. + /// + /// + /// A System.Security.Cryptography.X509Certificate. + public static SystemX509.X509Certificate ToX509Certificate( + X509CertificateStructure x509Struct) + { + return new SystemX509.X509Certificate(x509Struct.GetDerEncoded()); + } + + public static SystemX509.X509Certificate ToX509Certificate( + X509Certificate x509Cert) + { + return new SystemX509.X509Certificate(x509Cert.GetEncoded()); + } + + public static X509Certificate FromX509Certificate( + SystemX509.X509Certificate x509Cert) + { + return new X509CertificateParser().ReadCertificate(x509Cert.GetRawCertData()); + } + + public static AsymmetricCipherKeyPair GetDsaKeyPair(DSA dsa) + { + return GetDsaKeyPair(dsa.ExportParameters(true)); + } + + public static AsymmetricCipherKeyPair GetDsaKeyPair(DSAParameters dp) + { + DsaValidationParameters validationParameters = (dp.Seed != null) + ? new DsaValidationParameters(dp.Seed, dp.Counter) + : null; + + DsaParameters parameters = new DsaParameters( + new BigInteger(1, dp.P), + new BigInteger(1, dp.Q), + new BigInteger(1, dp.G), + validationParameters); + + DsaPublicKeyParameters pubKey = new DsaPublicKeyParameters( + new BigInteger(1, dp.Y), + parameters); + + DsaPrivateKeyParameters privKey = new DsaPrivateKeyParameters( + new BigInteger(1, dp.X), + parameters); + + return new AsymmetricCipherKeyPair(pubKey, privKey); + } + + public static DsaPublicKeyParameters GetDsaPublicKey(DSA dsa) + { + return GetDsaPublicKey(dsa.ExportParameters(false)); + } + + public static DsaPublicKeyParameters GetDsaPublicKey(DSAParameters dp) + { + DsaValidationParameters validationParameters = (dp.Seed != null) + ? new DsaValidationParameters(dp.Seed, dp.Counter) + : null; + + DsaParameters parameters = new DsaParameters( + new BigInteger(1, dp.P), + new BigInteger(1, dp.Q), + new BigInteger(1, dp.G), + validationParameters); + + return new DsaPublicKeyParameters( + new BigInteger(1, dp.Y), + parameters); + } + + public static AsymmetricCipherKeyPair GetRsaKeyPair(RSA rsa) + { + return GetRsaKeyPair(rsa.ExportParameters(true)); + } + + public static AsymmetricCipherKeyPair GetRsaKeyPair(RSAParameters rp) + { + BigInteger modulus = new BigInteger(1, rp.Modulus); + BigInteger pubExp = new BigInteger(1, rp.Exponent); + + RsaKeyParameters pubKey = new RsaKeyParameters( + false, + modulus, + pubExp); + + RsaPrivateCrtKeyParameters privKey = new RsaPrivateCrtKeyParameters( + modulus, + pubExp, + new BigInteger(1, rp.D), + new BigInteger(1, rp.P), + new BigInteger(1, rp.Q), + new BigInteger(1, rp.DP), + new BigInteger(1, rp.DQ), + new BigInteger(1, rp.InverseQ)); + + return new AsymmetricCipherKeyPair(pubKey, privKey); + } + + public static RsaKeyParameters GetRsaPublicKey(RSA rsa) + { + return GetRsaPublicKey(rsa.ExportParameters(false)); + } + + public static RsaKeyParameters GetRsaPublicKey( + RSAParameters rp) + { + return new RsaKeyParameters( + false, + new BigInteger(1, rp.Modulus), + new BigInteger(1, rp.Exponent)); + } + + public static AsymmetricCipherKeyPair GetKeyPair(AsymmetricAlgorithm privateKey) + { + if (privateKey is DSA) + { + return GetDsaKeyPair((DSA)privateKey); + } + + if (privateKey is RSA) + { + return GetRsaKeyPair((RSA)privateKey); + } + + throw new ArgumentException("Unsupported algorithm specified", "privateKey"); + } + + public static RSA ToRSA(RsaKeyParameters rsaKey) + { + // TODO This appears to not work for private keys (when no CRT info) + return CreateRSAProvider(ToRSAParameters(rsaKey)); + } + + public static RSA ToRSA(RsaKeyParameters rsaKey, CspParameters csp) + { + // TODO This appears to not work for private keys (when no CRT info) + return CreateRSAProvider(ToRSAParameters(rsaKey), csp); + } + + public static RSA ToRSA(RsaPrivateCrtKeyParameters privKey) + { + return CreateRSAProvider(ToRSAParameters(privKey)); + } + + public static RSA ToRSA(RsaPrivateCrtKeyParameters privKey, CspParameters csp) + { + return CreateRSAProvider(ToRSAParameters(privKey), csp); + } + + public static RSA ToRSA(RsaPrivateKeyStructure privKey) + { + return CreateRSAProvider(ToRSAParameters(privKey)); + } + + public static RSA ToRSA(RsaPrivateKeyStructure privKey, CspParameters csp) + { + return CreateRSAProvider(ToRSAParameters(privKey), csp); + } + + public static RSAParameters ToRSAParameters(RsaKeyParameters rsaKey) + { + RSAParameters rp = new RSAParameters(); + rp.Modulus = rsaKey.Modulus.ToByteArrayUnsigned(); + if (rsaKey.IsPrivate) + rp.D = ConvertRSAParametersField(rsaKey.Exponent, rp.Modulus.Length); + else + rp.Exponent = rsaKey.Exponent.ToByteArrayUnsigned(); + return rp; + } + + public static RSAParameters ToRSAParameters(RsaPrivateCrtKeyParameters privKey) + { + RSAParameters rp = new RSAParameters(); + rp.Modulus = privKey.Modulus.ToByteArrayUnsigned(); + rp.Exponent = privKey.PublicExponent.ToByteArrayUnsigned(); + rp.P = privKey.P.ToByteArrayUnsigned(); + rp.Q = privKey.Q.ToByteArrayUnsigned(); + rp.D = ConvertRSAParametersField(privKey.Exponent, rp.Modulus.Length); + rp.DP = ConvertRSAParametersField(privKey.DP, rp.P.Length); + rp.DQ = ConvertRSAParametersField(privKey.DQ, rp.Q.Length); + rp.InverseQ = ConvertRSAParametersField(privKey.QInv, rp.Q.Length); + return rp; + } + + public static RSAParameters ToRSAParameters(RsaPrivateKeyStructure privKey) + { + RSAParameters rp = new RSAParameters(); + rp.Modulus = privKey.Modulus.ToByteArrayUnsigned(); + rp.Exponent = privKey.PublicExponent.ToByteArrayUnsigned(); + rp.P = privKey.Prime1.ToByteArrayUnsigned(); + rp.Q = privKey.Prime2.ToByteArrayUnsigned(); + rp.D = ConvertRSAParametersField(privKey.PrivateExponent, rp.Modulus.Length); + rp.DP = ConvertRSAParametersField(privKey.Exponent1, rp.P.Length); + rp.DQ = ConvertRSAParametersField(privKey.Exponent2, rp.Q.Length); + rp.InverseQ = ConvertRSAParametersField(privKey.Coefficient, rp.Q.Length); + return rp; + } + + // TODO Move functionality to more general class + private static byte[] ConvertRSAParametersField(BigInteger n, int size) + { + byte[] bs = n.ToByteArrayUnsigned(); + + if (bs.Length == size) + return bs; + + if (bs.Length > size) + throw new ArgumentException("Specified size too small", "size"); + + byte[] padded = new byte[size]; + Array.Copy(bs, 0, padded, size - bs.Length, bs.Length); + return padded; + } + + private static RSA CreateRSAProvider(RSAParameters rp) + { + CspParameters csp = new CspParameters(); + csp.KeyContainerName = string.Format("BouncyCastle-{0}", Guid.NewGuid()); + RSACryptoServiceProvider rsaCsp = new RSACryptoServiceProvider(csp); + rsaCsp.ImportParameters(rp); + return rsaCsp; + } + + private static RSA CreateRSAProvider(RSAParameters rp, CspParameters csp) + { + RSACryptoServiceProvider rsaCsp = new RSACryptoServiceProvider(csp); + rsaCsp.ImportParameters(rp); + return rsaCsp; + } + } +} + +#endif diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/DotNetUtilities.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/DotNetUtilities.cs.meta new file mode 100644 index 0000000..7ce1a0f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/DotNetUtilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e5a7dabd409afc54fae16e1955e40650 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/GeneralSecurityException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/GeneralSecurityException.cs new file mode 100644 index 0000000..d4ab38c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/GeneralSecurityException.cs @@ -0,0 +1,29 @@ +using System; + +namespace Org.BouncyCastle.Security +{ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE) + [Serializable] +#endif + public class GeneralSecurityException + : Exception + { + public GeneralSecurityException() + : base() + { + } + + public GeneralSecurityException( + string message) + : base(message) + { + } + + public GeneralSecurityException( + string message, + Exception exception) + : base(message, exception) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/GeneralSecurityException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/GeneralSecurityException.cs.meta new file mode 100644 index 0000000..9c29dd9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/GeneralSecurityException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6ec5b06910f275547a690d5921e59c18 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/GeneratorUtilities.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/GeneratorUtilities.cs new file mode 100644 index 0000000..8f996bc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/GeneratorUtilities.cs @@ -0,0 +1,432 @@ +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Asn1.EdEC; +using Org.BouncyCastle.Asn1.Iana; +using Org.BouncyCastle.Asn1.Kisa; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Nsri; +using Org.BouncyCastle.Asn1.Ntt; +using Org.BouncyCastle.Asn1.Oiw; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.Rosstandart; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Security +{ + public sealed class GeneratorUtilities + { + private GeneratorUtilities() + { + } + + private static readonly IDictionary kgAlgorithms = Platform.CreateHashtable(); + private static readonly IDictionary kpgAlgorithms = Platform.CreateHashtable(); + private static readonly IDictionary defaultKeySizes = Platform.CreateHashtable(); + + static GeneratorUtilities() + { + // + // key generators. + // + AddKgAlgorithm("AES", + "AESWRAP"); + AddKgAlgorithm("AES128", + "2.16.840.1.101.3.4.2", + NistObjectIdentifiers.IdAes128Cbc, + NistObjectIdentifiers.IdAes128Ccm, + NistObjectIdentifiers.IdAes128Cfb, + NistObjectIdentifiers.IdAes128Ecb, + NistObjectIdentifiers.IdAes128Gcm, + NistObjectIdentifiers.IdAes128Ofb, + NistObjectIdentifiers.IdAes128Wrap); + AddKgAlgorithm("AES192", + "2.16.840.1.101.3.4.22", + NistObjectIdentifiers.IdAes192Cbc, + NistObjectIdentifiers.IdAes192Ccm, + NistObjectIdentifiers.IdAes192Cfb, + NistObjectIdentifiers.IdAes192Ecb, + NistObjectIdentifiers.IdAes192Gcm, + NistObjectIdentifiers.IdAes192Ofb, + NistObjectIdentifiers.IdAes192Wrap); + AddKgAlgorithm("AES256", + "2.16.840.1.101.3.4.42", + NistObjectIdentifiers.IdAes256Cbc, + NistObjectIdentifiers.IdAes256Ccm, + NistObjectIdentifiers.IdAes256Cfb, + NistObjectIdentifiers.IdAes256Ecb, + NistObjectIdentifiers.IdAes256Gcm, + NistObjectIdentifiers.IdAes256Ofb, + NistObjectIdentifiers.IdAes256Wrap); + AddKgAlgorithm("BLOWFISH", + "1.3.6.1.4.1.3029.1.2"); + AddKgAlgorithm("CAMELLIA", + "CAMELLIAWRAP"); + AddKgAlgorithm("ARIA"); + AddKgAlgorithm("ARIA128", + NsriObjectIdentifiers.id_aria128_cbc, + NsriObjectIdentifiers.id_aria128_ccm, + NsriObjectIdentifiers.id_aria128_cfb, + NsriObjectIdentifiers.id_aria128_ctr, + NsriObjectIdentifiers.id_aria128_ecb, + NsriObjectIdentifiers.id_aria128_gcm, + NsriObjectIdentifiers.id_aria128_ocb2, + NsriObjectIdentifiers.id_aria128_ofb); + AddKgAlgorithm("ARIA192", + NsriObjectIdentifiers.id_aria192_cbc, + NsriObjectIdentifiers.id_aria192_ccm, + NsriObjectIdentifiers.id_aria192_cfb, + NsriObjectIdentifiers.id_aria192_ctr, + NsriObjectIdentifiers.id_aria192_ecb, + NsriObjectIdentifiers.id_aria192_gcm, + NsriObjectIdentifiers.id_aria192_ocb2, + NsriObjectIdentifiers.id_aria192_ofb); + AddKgAlgorithm("ARIA256", + NsriObjectIdentifiers.id_aria256_cbc, + NsriObjectIdentifiers.id_aria256_ccm, + NsriObjectIdentifiers.id_aria256_cfb, + NsriObjectIdentifiers.id_aria256_ctr, + NsriObjectIdentifiers.id_aria256_ecb, + NsriObjectIdentifiers.id_aria256_gcm, + NsriObjectIdentifiers.id_aria256_ocb2, + NsriObjectIdentifiers.id_aria256_ofb); + AddKgAlgorithm("CAMELLIA128", + NttObjectIdentifiers.IdCamellia128Cbc, + NttObjectIdentifiers.IdCamellia128Wrap); + AddKgAlgorithm("CAMELLIA192", + NttObjectIdentifiers.IdCamellia192Cbc, + NttObjectIdentifiers.IdCamellia192Wrap); + AddKgAlgorithm("CAMELLIA256", + NttObjectIdentifiers.IdCamellia256Cbc, + NttObjectIdentifiers.IdCamellia256Wrap); + AddKgAlgorithm("CAST5", + "1.2.840.113533.7.66.10"); + AddKgAlgorithm("CAST6"); + AddKgAlgorithm("CHACHA"); + AddKgAlgorithm("CHACHA7539", + "CHACHA20", + "CHACHA20-POLY1305", + PkcsObjectIdentifiers.IdAlgAeadChaCha20Poly1305); + AddKgAlgorithm("DES", + OiwObjectIdentifiers.DesCbc, + OiwObjectIdentifiers.DesCfb, + OiwObjectIdentifiers.DesEcb, + OiwObjectIdentifiers.DesOfb); + AddKgAlgorithm("DESEDE", + "DESEDEWRAP", + "TDEA", + OiwObjectIdentifiers.DesEde); + AddKgAlgorithm("DESEDE3", + PkcsObjectIdentifiers.DesEde3Cbc, + PkcsObjectIdentifiers.IdAlgCms3DesWrap); + AddKgAlgorithm("GOST28147", + "GOST", + "GOST-28147", + CryptoProObjectIdentifiers.GostR28147Cbc); + AddKgAlgorithm("HC128"); + AddKgAlgorithm("HC256"); + AddKgAlgorithm("IDEA", + "1.3.6.1.4.1.188.7.1.1.2"); + AddKgAlgorithm("NOEKEON"); + AddKgAlgorithm("RC2", + PkcsObjectIdentifiers.RC2Cbc, + PkcsObjectIdentifiers.IdAlgCmsRC2Wrap); + AddKgAlgorithm("RC4", + "ARC4", + "1.2.840.113549.3.4"); + AddKgAlgorithm("RC5", + "RC5-32"); + AddKgAlgorithm("RC5-64"); + AddKgAlgorithm("RC6"); + AddKgAlgorithm("RIJNDAEL"); + AddKgAlgorithm("SALSA20"); + AddKgAlgorithm("SEED", + KisaObjectIdentifiers.IdNpkiAppCmsSeedWrap, + KisaObjectIdentifiers.IdSeedCbc); + AddKgAlgorithm("SERPENT"); + AddKgAlgorithm("SKIPJACK"); + AddKgAlgorithm("SM4"); + AddKgAlgorithm("TEA"); + AddKgAlgorithm("THREEFISH-256"); + AddKgAlgorithm("THREEFISH-512"); + AddKgAlgorithm("THREEFISH-1024"); + AddKgAlgorithm("TNEPRES"); + AddKgAlgorithm("TWOFISH"); + AddKgAlgorithm("VMPC"); + AddKgAlgorithm("VMPC-KSA3"); + AddKgAlgorithm("XTEA"); + + // + // HMac key generators + // + AddHMacKeyGenerator("MD2"); + AddHMacKeyGenerator("MD4"); + AddHMacKeyGenerator("MD5", + IanaObjectIdentifiers.HmacMD5); + AddHMacKeyGenerator("SHA1", + PkcsObjectIdentifiers.IdHmacWithSha1, + IanaObjectIdentifiers.HmacSha1); + AddHMacKeyGenerator("SHA224", + PkcsObjectIdentifiers.IdHmacWithSha224); + AddHMacKeyGenerator("SHA256", + PkcsObjectIdentifiers.IdHmacWithSha256); + AddHMacKeyGenerator("SHA384", + PkcsObjectIdentifiers.IdHmacWithSha384); + AddHMacKeyGenerator("SHA512", + PkcsObjectIdentifiers.IdHmacWithSha512); + AddHMacKeyGenerator("SHA512/224"); + AddHMacKeyGenerator("SHA512/256"); + AddHMacKeyGenerator("KECCAK224"); + AddHMacKeyGenerator("KECCAK256"); + AddHMacKeyGenerator("KECCAK288"); + AddHMacKeyGenerator("KECCAK384"); + AddHMacKeyGenerator("KECCAK512"); + AddHMacKeyGenerator("SHA3-224", + NistObjectIdentifiers.IdHMacWithSha3_224); + AddHMacKeyGenerator("SHA3-256", + NistObjectIdentifiers.IdHMacWithSha3_256); + AddHMacKeyGenerator("SHA3-384", + NistObjectIdentifiers.IdHMacWithSha3_384); + AddHMacKeyGenerator("SHA3-512", + NistObjectIdentifiers.IdHMacWithSha3_512); + AddHMacKeyGenerator("RIPEMD128"); + AddHMacKeyGenerator("RIPEMD160", + IanaObjectIdentifiers.HmacRipeMD160); + AddHMacKeyGenerator("TIGER", + IanaObjectIdentifiers.HmacTiger); + AddHMacKeyGenerator("GOST3411-2012-256", + RosstandartObjectIdentifiers.id_tc26_hmac_gost_3411_12_256); + AddHMacKeyGenerator("GOST3411-2012-512", + RosstandartObjectIdentifiers.id_tc26_hmac_gost_3411_12_512); + + // + // key pair generators. + // + AddKpgAlgorithm("DH", + "DIFFIEHELLMAN"); + AddKpgAlgorithm("DSA"); + AddKpgAlgorithm("EC", + // TODO Should this be an alias for ECDH? + X9ObjectIdentifiers.DHSinglePassStdDHSha1KdfScheme); + AddKpgAlgorithm("ECDH", + "ECIES"); + AddKpgAlgorithm("ECDHC"); + AddKpgAlgorithm("ECMQV", + X9ObjectIdentifiers.MqvSinglePassSha1KdfScheme); + AddKpgAlgorithm("ECDSA"); + AddKpgAlgorithm("ECGOST3410", + "ECGOST-3410", + "GOST-3410-2001"); + AddKpgAlgorithm("Ed25519", + "Ed25519ctx", + "Ed25519ph", + EdECObjectIdentifiers.id_Ed25519); + AddKpgAlgorithm("Ed448", + "Ed448ph", + EdECObjectIdentifiers.id_Ed448); + AddKpgAlgorithm("ELGAMAL"); + AddKpgAlgorithm("GOST3410", + "GOST-3410", + "GOST-3410-94"); + AddKpgAlgorithm("RSA", + "1.2.840.113549.1.1.1"); + AddKpgAlgorithm("RSASSA-PSS"); + AddKpgAlgorithm("X25519", + EdECObjectIdentifiers.id_X25519); + AddKpgAlgorithm("X448", + EdECObjectIdentifiers.id_X448); + + AddDefaultKeySizeEntries(64, "DES"); + AddDefaultKeySizeEntries(80, "SKIPJACK"); + AddDefaultKeySizeEntries(128, "AES128", "ARIA128", "BLOWFISH", "CAMELLIA128", "CAST5", "CHACHA", "DESEDE", + "HC128", "HMACMD2", "HMACMD4", "HMACMD5", "HMACRIPEMD128", "IDEA", "NOEKEON", + "RC2", "RC4", "RC5", "SALSA20", "SEED", "SM4", "TEA", "XTEA", "VMPC", "VMPC-KSA3"); + AddDefaultKeySizeEntries(160, "HMACRIPEMD160", "HMACSHA1"); + AddDefaultKeySizeEntries(192, "AES", "AES192", "ARIA192", "CAMELLIA192", "DESEDE3", "HMACTIGER", + "RIJNDAEL", "SERPENT", "TNEPRES"); + AddDefaultKeySizeEntries(224, "HMACSHA3-224", "HMACKECCAK224", "HMACSHA224", "HMACSHA512/224"); + AddDefaultKeySizeEntries(256, "AES256", "ARIA", "ARIA256", "CAMELLIA", "CAMELLIA256", "CAST6", + "CHACHA7539", "GOST28147", "HC256", "HMACGOST3411-2012-256", "HMACSHA3-256", "HMACKECCAK256", + "HMACSHA256", "HMACSHA512/256", "RC5-64", "RC6", "THREEFISH-256", "TWOFISH"); + AddDefaultKeySizeEntries(288, "HMACKECCAK288"); + AddDefaultKeySizeEntries(384, "HMACSHA3-384", "HMACKECCAK384", "HMACSHA384"); + AddDefaultKeySizeEntries(512, "HMACGOST3411-2012-512", "HMACSHA3-512", "HMACKECCAK512", "HMACSHA512", + "THREEFISH-512"); + AddDefaultKeySizeEntries(1024, "THREEFISH-1024"); + } + + private static void AddDefaultKeySizeEntries(int size, params string[] algorithms) + { + foreach (string algorithm in algorithms) + { + defaultKeySizes.Add(algorithm, size); + } + } + + private static void AddKgAlgorithm( + string canonicalName, + params object[] aliases) + { + kgAlgorithms[Platform.ToUpperInvariant(canonicalName)] = canonicalName; + + foreach (object alias in aliases) + { + kgAlgorithms[Platform.ToUpperInvariant(alias.ToString())] = canonicalName; + } + } + + private static void AddKpgAlgorithm( + string canonicalName, + params object[] aliases) + { + kpgAlgorithms[Platform.ToUpperInvariant(canonicalName)] = canonicalName; + + foreach (object alias in aliases) + { + kpgAlgorithms[Platform.ToUpperInvariant(alias.ToString())] = canonicalName; + } + } + + private static void AddHMacKeyGenerator( + string algorithm, + params object[] aliases) + { + string mainName = "HMAC" + algorithm; + + kgAlgorithms[mainName] = mainName; + kgAlgorithms["HMAC-" + algorithm] = mainName; + kgAlgorithms["HMAC/" + algorithm] = mainName; + + foreach (object alias in aliases) + { + kgAlgorithms[Platform.ToUpperInvariant(alias.ToString())] = mainName; + } + } + + // TODO Consider making this public + internal static string GetCanonicalKeyGeneratorAlgorithm( + string algorithm) + { + return (string) kgAlgorithms[Platform.ToUpperInvariant(algorithm)]; + } + + // TODO Consider making this public + internal static string GetCanonicalKeyPairGeneratorAlgorithm( + string algorithm) + { + return (string)kpgAlgorithms[Platform.ToUpperInvariant(algorithm)]; + } + + public static CipherKeyGenerator GetKeyGenerator( + DerObjectIdentifier oid) + { + return GetKeyGenerator(oid.Id); + } + + public static CipherKeyGenerator GetKeyGenerator( + string algorithm) + { + string canonicalName = GetCanonicalKeyGeneratorAlgorithm(algorithm); + + if (canonicalName == null) + throw new SecurityUtilityException("KeyGenerator " + algorithm + " not recognised."); + + int defaultKeySize = FindDefaultKeySize(canonicalName); + if (defaultKeySize == -1) + throw new SecurityUtilityException("KeyGenerator " + algorithm + + " (" + canonicalName + ") not supported."); + + if (canonicalName == "DES") + return new DesKeyGenerator(defaultKeySize); + + if (canonicalName == "DESEDE" || canonicalName == "DESEDE3") + return new DesEdeKeyGenerator(defaultKeySize); + + return new CipherKeyGenerator(defaultKeySize); + } + + public static IAsymmetricCipherKeyPairGenerator GetKeyPairGenerator( + DerObjectIdentifier oid) + { + return GetKeyPairGenerator(oid.Id); + } + + public static IAsymmetricCipherKeyPairGenerator GetKeyPairGenerator( + string algorithm) + { + string canonicalName = GetCanonicalKeyPairGeneratorAlgorithm(algorithm); + + if (canonicalName == null) + throw new SecurityUtilityException("KeyPairGenerator " + algorithm + " not recognised."); + + if (canonicalName == "DH") + return new DHKeyPairGenerator(); + + if (canonicalName == "DSA") + return new DsaKeyPairGenerator(); + + // "EC", "ECDH", "ECDHC", "ECDSA", "ECGOST3410", "ECMQV" + if (Platform.StartsWith(canonicalName, "EC")) + return new ECKeyPairGenerator(canonicalName); + + if (canonicalName == "Ed25519") + return new Ed25519KeyPairGenerator(); + + if (canonicalName == "Ed448") + return new Ed448KeyPairGenerator(); + + if (canonicalName == "ELGAMAL") + return new ElGamalKeyPairGenerator(); + + if (canonicalName == "GOST3410") + return new Gost3410KeyPairGenerator(); + + if (canonicalName == "RSA" || canonicalName == "RSASSA-PSS") + return new RsaKeyPairGenerator(); + + if (canonicalName == "X25519") + return new X25519KeyPairGenerator(); + + if (canonicalName == "X448") + return new X448KeyPairGenerator(); + + throw new SecurityUtilityException("KeyPairGenerator " + algorithm + + " (" + canonicalName + ") not supported."); + } + + internal static int GetDefaultKeySize( + DerObjectIdentifier oid) + { + return GetDefaultKeySize(oid.Id); + } + + internal static int GetDefaultKeySize( + string algorithm) + { + string canonicalName = GetCanonicalKeyGeneratorAlgorithm(algorithm); + + if (canonicalName == null) + throw new SecurityUtilityException("KeyGenerator " + algorithm + " not recognised."); + + int defaultKeySize = FindDefaultKeySize(canonicalName); + if (defaultKeySize == -1) + throw new SecurityUtilityException("KeyGenerator " + algorithm + + " (" + canonicalName + ") not supported."); + + return defaultKeySize; + } + + private static int FindDefaultKeySize( + string canonicalName) + { + if (!defaultKeySizes.Contains(canonicalName)) + return -1; + + return (int)defaultKeySizes[canonicalName]; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/GeneratorUtilities.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/GeneratorUtilities.cs.meta new file mode 100644 index 0000000..da7d30c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/GeneratorUtilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c86c04a71e9654b43b02c6b6f64a7676 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/InvalidKeyException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/InvalidKeyException.cs new file mode 100644 index 0000000..ebad9e3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/InvalidKeyException.cs @@ -0,0 +1,14 @@ +using System; + +namespace Org.BouncyCastle.Security +{ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE) + [Serializable] +#endif + public class InvalidKeyException : KeyException + { + public InvalidKeyException() : base() { } + public InvalidKeyException(string message) : base(message) { } + public InvalidKeyException(string message, Exception exception) : base(message, exception) { } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/InvalidKeyException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/InvalidKeyException.cs.meta new file mode 100644 index 0000000..7060927 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/InvalidKeyException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9e4c2aebf18187746b77a8687438453b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/InvalidParameterException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/InvalidParameterException.cs new file mode 100644 index 0000000..48172f4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/InvalidParameterException.cs @@ -0,0 +1,14 @@ +using System; + +namespace Org.BouncyCastle.Security +{ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE) + [Serializable] +#endif + public class InvalidParameterException : KeyException + { + public InvalidParameterException() : base() { } + public InvalidParameterException(string message) : base(message) { } + public InvalidParameterException(string message, Exception exception) : base(message, exception) { } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/InvalidParameterException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/InvalidParameterException.cs.meta new file mode 100644 index 0000000..41f02bf --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/InvalidParameterException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 72ccec73f2fb472459b193926689f532 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/KeyException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/KeyException.cs new file mode 100644 index 0000000..e19fa89 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/KeyException.cs @@ -0,0 +1,14 @@ +using System; + +namespace Org.BouncyCastle.Security +{ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE) + [Serializable] +#endif + public class KeyException : GeneralSecurityException + { + public KeyException() : base() { } + public KeyException(string message) : base(message) { } + public KeyException(string message, Exception exception) : base(message, exception) { } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/KeyException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/KeyException.cs.meta new file mode 100644 index 0000000..4b5c978 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/KeyException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1771c2c58959e7c4eb16ee09ce73d3fe +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/MacUtilities.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/MacUtilities.cs new file mode 100644 index 0000000..f36fc6a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/MacUtilities.cs @@ -0,0 +1,268 @@ +using System; +using System.Collections; +using System.Globalization; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Iana; +using Org.BouncyCastle.Asn1.Misc; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.Rosstandart; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Macs; +using Org.BouncyCastle.Crypto.Paddings; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Security +{ + /// + /// Utility class for creating HMac object from their names/Oids + /// + public sealed class MacUtilities + { + private MacUtilities() + { + } + + private static readonly IDictionary algorithms = Platform.CreateHashtable(); + //private static readonly IDictionary oids = Platform.CreateHashtable(); + + static MacUtilities() + { + algorithms[IanaObjectIdentifiers.HmacMD5.Id] = "HMAC-MD5"; + algorithms[IanaObjectIdentifiers.HmacRipeMD160.Id] = "HMAC-RIPEMD160"; + algorithms[IanaObjectIdentifiers.HmacSha1.Id] = "HMAC-SHA1"; + algorithms[IanaObjectIdentifiers.HmacTiger.Id] = "HMAC-TIGER"; + + algorithms[PkcsObjectIdentifiers.IdHmacWithSha1.Id] = "HMAC-SHA1"; + algorithms[MiscObjectIdentifiers.HMAC_SHA1.Id] = "HMAC-SHA1"; + algorithms[PkcsObjectIdentifiers.IdHmacWithSha224.Id] = "HMAC-SHA224"; + algorithms[PkcsObjectIdentifiers.IdHmacWithSha256.Id] = "HMAC-SHA256"; + algorithms[PkcsObjectIdentifiers.IdHmacWithSha384.Id] = "HMAC-SHA384"; + algorithms[PkcsObjectIdentifiers.IdHmacWithSha512.Id] = "HMAC-SHA512"; + + algorithms[NistObjectIdentifiers.IdHMacWithSha3_224.Id] = "HMAC-SHA3-224"; + algorithms[NistObjectIdentifiers.IdHMacWithSha3_256.Id] = "HMAC-SHA3-256"; + algorithms[NistObjectIdentifiers.IdHMacWithSha3_384.Id] = "HMAC-SHA3-384"; + algorithms[NistObjectIdentifiers.IdHMacWithSha3_512.Id] = "HMAC-SHA3-512"; + + algorithms[RosstandartObjectIdentifiers.id_tc26_hmac_gost_3411_12_256.Id] = "HMAC-GOST3411-2012-256"; + algorithms[RosstandartObjectIdentifiers.id_tc26_hmac_gost_3411_12_512.Id] = "HMAC-GOST3411-2012-512"; + + // TODO AESMAC? + + algorithms["DES"] = "DESMAC"; + algorithms["DES/CFB8"] = "DESMAC/CFB8"; + algorithms["DES64"] = "DESMAC64"; + algorithms["DESEDE"] = "DESEDEMAC"; + algorithms[PkcsObjectIdentifiers.DesEde3Cbc.Id] = "DESEDEMAC"; + algorithms["DESEDE/CFB8"] = "DESEDEMAC/CFB8"; + algorithms["DESISO9797MAC"] = "DESWITHISO9797"; + algorithms["DESEDE64"] = "DESEDEMAC64"; + + algorithms["DESEDE64WITHISO7816-4PADDING"] = "DESEDEMAC64WITHISO7816-4PADDING"; + algorithms["DESEDEISO9797ALG1MACWITHISO7816-4PADDING"] = "DESEDEMAC64WITHISO7816-4PADDING"; + algorithms["DESEDEISO9797ALG1WITHISO7816-4PADDING"] = "DESEDEMAC64WITHISO7816-4PADDING"; + + algorithms["ISO9797ALG3"] = "ISO9797ALG3MAC"; + algorithms["ISO9797ALG3MACWITHISO7816-4PADDING"] = "ISO9797ALG3WITHISO7816-4PADDING"; + + algorithms["SKIPJACK"] = "SKIPJACKMAC"; + algorithms["SKIPJACK/CFB8"] = "SKIPJACKMAC/CFB8"; + algorithms["IDEA"] = "IDEAMAC"; + algorithms["IDEA/CFB8"] = "IDEAMAC/CFB8"; + algorithms["RC2"] = "RC2MAC"; + algorithms["RC2/CFB8"] = "RC2MAC/CFB8"; + algorithms["RC5"] = "RC5MAC"; + algorithms["RC5/CFB8"] = "RC5MAC/CFB8"; + algorithms["GOST28147"] = "GOST28147MAC"; + algorithms["VMPC"] = "VMPCMAC"; + algorithms["VMPC-MAC"] = "VMPCMAC"; + algorithms["SIPHASH"] = "SIPHASH-2-4"; + + algorithms["PBEWITHHMACSHA"] = "PBEWITHHMACSHA1"; + algorithms["1.3.14.3.2.26"] = "PBEWITHHMACSHA1"; + } + +// /// +// /// Returns a ObjectIdentifier for a given digest mechanism. +// /// +// /// A string representation of the digest meanism. +// /// A DerObjectIdentifier, null if the Oid is not available. +// public static DerObjectIdentifier GetObjectIdentifier( +// string mechanism) +// { +// mechanism = (string) algorithms[Platform.ToUpperInvariant(mechanism)]; +// +// if (mechanism != null) +// { +// return (DerObjectIdentifier)oids[mechanism]; +// } +// +// return null; +// } + +// public static ICollection Algorithms +// { +// get { return oids.Keys; } +// } + + public static IMac GetMac( + DerObjectIdentifier id) + { + return GetMac(id.Id); + } + + public static IMac GetMac( + string algorithm) + { + string upper = Platform.ToUpperInvariant(algorithm); + + string mechanism = (string) algorithms[upper]; + + if (mechanism == null) + { + mechanism = upper; + } + + if (Platform.StartsWith(mechanism, "PBEWITH")) + { + mechanism = mechanism.Substring("PBEWITH".Length); + } + + if (Platform.StartsWith(mechanism, "HMAC")) + { + string digestName; + if (Platform.StartsWith(mechanism, "HMAC-") || Platform.StartsWith(mechanism, "HMAC/")) + { + digestName = mechanism.Substring(5); + } + else + { + digestName = mechanism.Substring(4); + } + + return new HMac(DigestUtilities.GetDigest(digestName)); + } + + if (mechanism == "AESCMAC") + { + return new CMac(new AesEngine()); + } + if (mechanism == "DESMAC") + { + return new CbcBlockCipherMac(new DesEngine()); + } + if (mechanism == "DESMAC/CFB8") + { + return new CfbBlockCipherMac(new DesEngine()); + } + if (mechanism == "DESMAC64") + { + return new CbcBlockCipherMac(new DesEngine(), 64); + } + if (mechanism == "DESEDECMAC") + { + return new CMac(new DesEdeEngine()); + } + if (mechanism == "DESEDEMAC") + { + return new CbcBlockCipherMac(new DesEdeEngine()); + } + if (mechanism == "DESEDEMAC/CFB8") + { + return new CfbBlockCipherMac(new DesEdeEngine()); + } + if (mechanism == "DESEDEMAC64") + { + return new CbcBlockCipherMac(new DesEdeEngine(), 64); + } + if (mechanism == "DESEDEMAC64WITHISO7816-4PADDING") + { + return new CbcBlockCipherMac(new DesEdeEngine(), 64, new ISO7816d4Padding()); + } + if (mechanism == "DESWITHISO9797" + || mechanism == "ISO9797ALG3MAC") + { + return new ISO9797Alg3Mac(new DesEngine()); + } + if (mechanism == "ISO9797ALG3WITHISO7816-4PADDING") + { + return new ISO9797Alg3Mac(new DesEngine(), new ISO7816d4Padding()); + } + if (mechanism == "SKIPJACKMAC") + { + return new CbcBlockCipherMac(new SkipjackEngine()); + } + if (mechanism == "SKIPJACKMAC/CFB8") + { + return new CfbBlockCipherMac(new SkipjackEngine()); + } + if (mechanism == "IDEAMAC") + { + return new CbcBlockCipherMac(new IdeaEngine()); + } + if (mechanism == "IDEAMAC/CFB8") + { + return new CfbBlockCipherMac(new IdeaEngine()); + } + if (mechanism == "RC2MAC") + { + return new CbcBlockCipherMac(new RC2Engine()); + } + if (mechanism == "RC2MAC/CFB8") + { + return new CfbBlockCipherMac(new RC2Engine()); + } + if (mechanism == "RC5MAC") + { + return new CbcBlockCipherMac(new RC532Engine()); + } + if (mechanism == "RC5MAC/CFB8") + { + return new CfbBlockCipherMac(new RC532Engine()); + } + if (mechanism == "GOST28147MAC") + { + return new Gost28147Mac(); + } + if (mechanism == "VMPCMAC") + { + return new VmpcMac(); + } + if (mechanism == "SIPHASH-2-4") + { + return new SipHash(); + } + throw new SecurityUtilityException("Mac " + mechanism + " not recognised."); + } + + public static string GetAlgorithmName( + DerObjectIdentifier oid) + { + return (string) algorithms[oid.Id]; + } + + public static byte[] CalculateMac(string algorithm, ICipherParameters cp, byte[] input) + { + IMac mac = GetMac(algorithm); + mac.Init(cp); + mac.BlockUpdate(input, 0, input.Length); + return DoFinal(mac); + } + + public static byte[] DoFinal(IMac mac) + { + byte[] b = new byte[mac.GetMacSize()]; + mac.DoFinal(b, 0); + return b; + } + + public static byte[] DoFinal(IMac mac, byte[] input) + { + mac.BlockUpdate(input, 0, input.Length); + return DoFinal(mac); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/MacUtilities.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/MacUtilities.cs.meta new file mode 100644 index 0000000..c2fb674 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/MacUtilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7e28ab8364775824a9d3609fc954a23c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/NoSuchAlgorithmException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/NoSuchAlgorithmException.cs new file mode 100644 index 0000000..c56ec65 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/NoSuchAlgorithmException.cs @@ -0,0 +1,15 @@ +using System; + +namespace Org.BouncyCastle.Security +{ + [Obsolete("Never thrown")] +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE) + [Serializable] +#endif + public class NoSuchAlgorithmException : GeneralSecurityException + { + public NoSuchAlgorithmException() : base() {} + public NoSuchAlgorithmException(string message) : base(message) {} + public NoSuchAlgorithmException(string message, Exception exception) : base(message, exception) {} + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/NoSuchAlgorithmException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/NoSuchAlgorithmException.cs.meta new file mode 100644 index 0000000..0e144d2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/NoSuchAlgorithmException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f7038e726e22d4647a650c83b6a8ec74 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/ParameterUtilities.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/ParameterUtilities.cs new file mode 100644 index 0000000..fdb8d86 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/ParameterUtilities.cs @@ -0,0 +1,372 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Asn1.Kisa; +using Org.BouncyCastle.Asn1.Misc; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Nsri; +using Org.BouncyCastle.Asn1.Ntt; +using Org.BouncyCastle.Asn1.Oiw; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Security +{ + public sealed class ParameterUtilities + { + private ParameterUtilities() + { + } + + private static readonly IDictionary algorithms = Platform.CreateHashtable(); + private static readonly IDictionary basicIVSizes = Platform.CreateHashtable(); + + static ParameterUtilities() + { + AddAlgorithm("AES", + "AESWRAP"); + AddAlgorithm("AES128", + "2.16.840.1.101.3.4.2", + NistObjectIdentifiers.IdAes128Cbc, + NistObjectIdentifiers.IdAes128Ccm, + NistObjectIdentifiers.IdAes128Cfb, + NistObjectIdentifiers.IdAes128Ecb, + NistObjectIdentifiers.IdAes128Gcm, + NistObjectIdentifiers.IdAes128Ofb, + NistObjectIdentifiers.IdAes128Wrap); + AddAlgorithm("AES192", + "2.16.840.1.101.3.4.22", + NistObjectIdentifiers.IdAes192Cbc, + NistObjectIdentifiers.IdAes192Ccm, + NistObjectIdentifiers.IdAes192Cfb, + NistObjectIdentifiers.IdAes192Ecb, + NistObjectIdentifiers.IdAes192Gcm, + NistObjectIdentifiers.IdAes192Ofb, + NistObjectIdentifiers.IdAes192Wrap); + AddAlgorithm("AES256", + "2.16.840.1.101.3.4.42", + NistObjectIdentifiers.IdAes256Cbc, + NistObjectIdentifiers.IdAes256Ccm, + NistObjectIdentifiers.IdAes256Cfb, + NistObjectIdentifiers.IdAes256Ecb, + NistObjectIdentifiers.IdAes256Gcm, + NistObjectIdentifiers.IdAes256Ofb, + NistObjectIdentifiers.IdAes256Wrap); + AddAlgorithm("ARIA"); + AddAlgorithm("ARIA128", + NsriObjectIdentifiers.id_aria128_cbc, + NsriObjectIdentifiers.id_aria128_ccm, + NsriObjectIdentifiers.id_aria128_cfb, + NsriObjectIdentifiers.id_aria128_ctr, + NsriObjectIdentifiers.id_aria128_ecb, + NsriObjectIdentifiers.id_aria128_gcm, + NsriObjectIdentifiers.id_aria128_ocb2, + NsriObjectIdentifiers.id_aria128_ofb); + AddAlgorithm("ARIA192", + NsriObjectIdentifiers.id_aria192_cbc, + NsriObjectIdentifiers.id_aria192_ccm, + NsriObjectIdentifiers.id_aria192_cfb, + NsriObjectIdentifiers.id_aria192_ctr, + NsriObjectIdentifiers.id_aria192_ecb, + NsriObjectIdentifiers.id_aria192_gcm, + NsriObjectIdentifiers.id_aria192_ocb2, + NsriObjectIdentifiers.id_aria192_ofb); + AddAlgorithm("ARIA256", + NsriObjectIdentifiers.id_aria256_cbc, + NsriObjectIdentifiers.id_aria256_ccm, + NsriObjectIdentifiers.id_aria256_cfb, + NsriObjectIdentifiers.id_aria256_ctr, + NsriObjectIdentifiers.id_aria256_ecb, + NsriObjectIdentifiers.id_aria256_gcm, + NsriObjectIdentifiers.id_aria256_ocb2, + NsriObjectIdentifiers.id_aria256_ofb); + AddAlgorithm("BLOWFISH", + "1.3.6.1.4.1.3029.1.2"); + AddAlgorithm("CAMELLIA", + "CAMELLIAWRAP"); + AddAlgorithm("CAMELLIA128", + NttObjectIdentifiers.IdCamellia128Cbc, + NttObjectIdentifiers.IdCamellia128Wrap); + AddAlgorithm("CAMELLIA192", + NttObjectIdentifiers.IdCamellia192Cbc, + NttObjectIdentifiers.IdCamellia192Wrap); + AddAlgorithm("CAMELLIA256", + NttObjectIdentifiers.IdCamellia256Cbc, + NttObjectIdentifiers.IdCamellia256Wrap); + AddAlgorithm("CAST5", + "1.2.840.113533.7.66.10"); + AddAlgorithm("CAST6"); + AddAlgorithm("CHACHA"); + AddAlgorithm("CHACHA7539", + "CHACHA20", + "CHACHA20-POLY1305", + PkcsObjectIdentifiers.IdAlgAeadChaCha20Poly1305); + AddAlgorithm("DES", + OiwObjectIdentifiers.DesCbc, + OiwObjectIdentifiers.DesCfb, + OiwObjectIdentifiers.DesEcb, + OiwObjectIdentifiers.DesOfb); + AddAlgorithm("DESEDE", + "DESEDEWRAP", + "TDEA", + OiwObjectIdentifiers.DesEde, + PkcsObjectIdentifiers.IdAlgCms3DesWrap); + AddAlgorithm("DESEDE3", + PkcsObjectIdentifiers.DesEde3Cbc); + AddAlgorithm("GOST28147", + "GOST", + "GOST-28147", + CryptoProObjectIdentifiers.GostR28147Cbc); + AddAlgorithm("HC128"); + AddAlgorithm("HC256"); + AddAlgorithm("IDEA", + "1.3.6.1.4.1.188.7.1.1.2"); + AddAlgorithm("NOEKEON"); + AddAlgorithm("RC2", + PkcsObjectIdentifiers.RC2Cbc, + PkcsObjectIdentifiers.IdAlgCmsRC2Wrap); + AddAlgorithm("RC4", + "ARC4", + "1.2.840.113549.3.4"); + AddAlgorithm("RC5", + "RC5-32"); + AddAlgorithm("RC5-64"); + AddAlgorithm("RC6"); + AddAlgorithm("RIJNDAEL"); + AddAlgorithm("SALSA20"); + AddAlgorithm("SEED", + KisaObjectIdentifiers.IdNpkiAppCmsSeedWrap, + KisaObjectIdentifiers.IdSeedCbc); + AddAlgorithm("SERPENT"); + AddAlgorithm("SKIPJACK"); + AddAlgorithm("SM4"); + AddAlgorithm("TEA"); + AddAlgorithm("THREEFISH-256"); + AddAlgorithm("THREEFISH-512"); + AddAlgorithm("THREEFISH-1024"); + AddAlgorithm("TNEPRES"); + AddAlgorithm("TWOFISH"); + AddAlgorithm("VMPC"); + AddAlgorithm("VMPC-KSA3"); + AddAlgorithm("XTEA"); + + AddBasicIVSizeEntries(8, "BLOWFISH", "CHACHA", "DES", "DESEDE", "DESEDE3", "SALSA20"); + AddBasicIVSizeEntries(12, "CHACHA7539"); + AddBasicIVSizeEntries(16, "AES", "AES128", "AES192", "AES256", "ARIA", "ARIA128", "ARIA192", "ARIA256", + "CAMELLIA", "CAMELLIA128", "CAMELLIA192", "CAMELLIA256", "NOEKEON", "SEED", "SM4"); + + // TODO These algorithms support an IV + // but JCE doesn't seem to provide an AlgorithmParametersGenerator for them + // "RIJNDAEL", "SKIPJACK", "TWOFISH" + } + + private static void AddAlgorithm( + string canonicalName, + params object[] aliases) + { + algorithms[canonicalName] = canonicalName; + + foreach (object alias in aliases) + { + algorithms[alias.ToString()] = canonicalName; + } + } + + private static void AddBasicIVSizeEntries(int size, params string[] algorithms) + { + foreach (string algorithm in algorithms) + { + basicIVSizes.Add(algorithm, size); + } + } + + public static string GetCanonicalAlgorithmName( + string algorithm) + { + return (string) algorithms[Platform.ToUpperInvariant(algorithm)]; + } + + public static KeyParameter CreateKeyParameter( + DerObjectIdentifier algOid, + byte[] keyBytes) + { + return CreateKeyParameter(algOid.Id, keyBytes, 0, keyBytes.Length); + } + + public static KeyParameter CreateKeyParameter( + string algorithm, + byte[] keyBytes) + { + return CreateKeyParameter(algorithm, keyBytes, 0, keyBytes.Length); + } + + public static KeyParameter CreateKeyParameter( + DerObjectIdentifier algOid, + byte[] keyBytes, + int offset, + int length) + { + return CreateKeyParameter(algOid.Id, keyBytes, offset, length); + } + + public static KeyParameter CreateKeyParameter( + string algorithm, + byte[] keyBytes, + int offset, + int length) + { + if (algorithm == null) + throw new ArgumentNullException("algorithm"); + + string canonical = GetCanonicalAlgorithmName(algorithm); + + if (canonical == null) + throw new SecurityUtilityException("Algorithm " + algorithm + " not recognised."); + + if (canonical == "DES") + return new DesParameters(keyBytes, offset, length); + + if (canonical == "DESEDE" || canonical =="DESEDE3") + return new DesEdeParameters(keyBytes, offset, length); + + if (canonical == "RC2") + return new RC2Parameters(keyBytes, offset, length); + + return new KeyParameter(keyBytes, offset, length); + } + + public static ICipherParameters GetCipherParameters( + DerObjectIdentifier algOid, + ICipherParameters key, + Asn1Object asn1Params) + { + return GetCipherParameters(algOid.Id, key, asn1Params); + } + + public static ICipherParameters GetCipherParameters( + string algorithm, + ICipherParameters key, + Asn1Object asn1Params) + { + if (algorithm == null) + throw new ArgumentNullException("algorithm"); + + string canonical = GetCanonicalAlgorithmName(algorithm); + + if (canonical == null) + throw new SecurityUtilityException("Algorithm " + algorithm + " not recognised."); + + byte[] iv = null; + + try + { + // TODO These algorithms support an IV + // but JCE doesn't seem to provide an AlgorithmParametersGenerator for them + // "RIJNDAEL", "SKIPJACK", "TWOFISH" + + int basicIVKeySize = FindBasicIVSize(canonical); + if (basicIVKeySize != -1 + || canonical == "RIJNDAEL" || canonical == "SKIPJACK" || canonical == "TWOFISH") + { + iv = ((Asn1OctetString) asn1Params).GetOctets(); + } + else if (canonical == "CAST5") + { + iv = Cast5CbcParameters.GetInstance(asn1Params).GetIV(); + } + else if (canonical == "IDEA") + { + iv = IdeaCbcPar.GetInstance(asn1Params).GetIV(); + } + else if (canonical == "RC2") + { + iv = RC2CbcParameter.GetInstance(asn1Params).GetIV(); + } + } + catch (Exception e) + { + throw new ArgumentException("Could not process ASN.1 parameters", e); + } + + if (iv != null) + { + return new ParametersWithIV(key, iv); + } + + throw new SecurityUtilityException("Algorithm " + algorithm + " not recognised."); + } + + public static Asn1Encodable GenerateParameters( + DerObjectIdentifier algID, + SecureRandom random) + { + return GenerateParameters(algID.Id, random); + } + + public static Asn1Encodable GenerateParameters( + string algorithm, + SecureRandom random) + { + if (algorithm == null) + throw new ArgumentNullException("algorithm"); + + string canonical = GetCanonicalAlgorithmName(algorithm); + + if (canonical == null) + throw new SecurityUtilityException("Algorithm " + algorithm + " not recognised."); + + // TODO These algorithms support an IV + // but JCE doesn't seem to provide an AlgorithmParametersGenerator for them + // "RIJNDAEL", "SKIPJACK", "TWOFISH" + + int basicIVKeySize = FindBasicIVSize(canonical); + if (basicIVKeySize != -1) + return CreateIVOctetString(random, basicIVKeySize); + + if (canonical == "CAST5") + return new Cast5CbcParameters(CreateIV(random, 8), 128); + + if (canonical == "IDEA") + return new IdeaCbcPar(CreateIV(random, 8)); + + if (canonical == "RC2") + return new RC2CbcParameter(CreateIV(random, 8)); + + throw new SecurityUtilityException("Algorithm " + algorithm + " not recognised."); + } + + public static ICipherParameters WithRandom(ICipherParameters cp, SecureRandom random) + { + if (random != null) + { + cp = new ParametersWithRandom(cp, random); + } + return cp; + } + + private static Asn1OctetString CreateIVOctetString( + SecureRandom random, + int ivLength) + { + return new DerOctetString(CreateIV(random, ivLength)); + } + + private static byte[] CreateIV(SecureRandom random, int ivLength) + { + return SecureRandom.GetNextBytes(random, ivLength); + } + + private static int FindBasicIVSize( + string canonicalName) + { + if (!basicIVSizes.Contains(canonicalName)) + return -1; + + return (int)basicIVSizes[canonicalName]; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/ParameterUtilities.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/ParameterUtilities.cs.meta new file mode 100644 index 0000000..aa379e5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/ParameterUtilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d4687c1b2e204d543af09eb94f85593b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/PbeUtilities.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/PbeUtilities.cs new file mode 100644 index 0000000..622c6dd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/PbeUtilities.cs @@ -0,0 +1,693 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.BC; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Oiw; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.TeleTrust; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Macs; +using Org.BouncyCastle.Crypto.Modes; +using Org.BouncyCastle.Crypto.Paddings; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Security +{ + /// + /// + /// + public sealed class PbeUtilities + { + private PbeUtilities() + { + } + + const string Pkcs5S1 = "Pkcs5S1"; + const string Pkcs5S2 = "Pkcs5S2"; + const string Pkcs12 = "Pkcs12"; + const string OpenSsl = "OpenSsl"; + + private static readonly IDictionary algorithms = Platform.CreateHashtable(); + private static readonly IDictionary algorithmType = Platform.CreateHashtable(); + private static readonly IDictionary oids = Platform.CreateHashtable(); + + static PbeUtilities() + { + algorithms["PKCS5SCHEME1"] = "Pkcs5scheme1"; + algorithms["PKCS5SCHEME2"] = "Pkcs5scheme2"; + algorithms["PBKDF2"] = "Pkcs5scheme2"; + algorithms[PkcsObjectIdentifiers.IdPbeS2.Id] = "Pkcs5scheme2"; +// algorithms[PkcsObjectIdentifiers.IdPbkdf2.Id] = "Pkcs5scheme2"; + + // FIXME Add support for these? (see Pkcs8Generator) +// algorithms[PkcsObjectIdentifiers.DesEde3Cbc.Id] = "Pkcs5scheme2"; +// algorithms[NistObjectIdentifiers.IdAes128Cbc.Id] = "Pkcs5scheme2"; +// algorithms[NistObjectIdentifiers.IdAes192Cbc.Id] = "Pkcs5scheme2"; +// algorithms[NistObjectIdentifiers.IdAes256Cbc.Id] = "Pkcs5scheme2"; + + algorithms["PBEWITHMD2ANDDES-CBC"] = "PBEwithMD2andDES-CBC"; + algorithms[PkcsObjectIdentifiers.PbeWithMD2AndDesCbc.Id] = "PBEwithMD2andDES-CBC"; + algorithms["PBEWITHMD2ANDRC2-CBC"] = "PBEwithMD2andRC2-CBC"; + algorithms[PkcsObjectIdentifiers.PbeWithMD2AndRC2Cbc.Id] = "PBEwithMD2andRC2-CBC"; + algorithms["PBEWITHMD5ANDDES-CBC"] = "PBEwithMD5andDES-CBC"; + algorithms[PkcsObjectIdentifiers.PbeWithMD5AndDesCbc.Id] = "PBEwithMD5andDES-CBC"; + algorithms["PBEWITHMD5ANDRC2-CBC"] = "PBEwithMD5andRC2-CBC"; + algorithms[PkcsObjectIdentifiers.PbeWithMD5AndRC2Cbc.Id] = "PBEwithMD5andRC2-CBC"; + algorithms["PBEWITHSHA1ANDDES"] = "PBEwithSHA-1andDES-CBC"; + algorithms["PBEWITHSHA-1ANDDES"] = "PBEwithSHA-1andDES-CBC"; + algorithms["PBEWITHSHA1ANDDES-CBC"] = "PBEwithSHA-1andDES-CBC"; + algorithms["PBEWITHSHA-1ANDDES-CBC"] = "PBEwithSHA-1andDES-CBC"; + algorithms[PkcsObjectIdentifiers.PbeWithSha1AndDesCbc.Id] = "PBEwithSHA-1andDES-CBC"; + algorithms["PBEWITHSHA1ANDRC2"] = "PBEwithSHA-1andRC2-CBC"; + algorithms["PBEWITHSHA-1ANDRC2"] = "PBEwithSHA-1andRC2-CBC"; + algorithms["PBEWITHSHA1ANDRC2-CBC"] = "PBEwithSHA-1andRC2-CBC"; + algorithms["PBEWITHSHA-1ANDRC2-CBC"] = "PBEwithSHA-1andRC2-CBC"; + algorithms[PkcsObjectIdentifiers.PbeWithSha1AndRC2Cbc.Id] = "PBEwithSHA-1andRC2-CBC"; + algorithms["PKCS12"] = "Pkcs12"; + algorithms[BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes128_cbc.Id] = "PBEwithSHA-1and128bitAES-CBC-BC"; + algorithms[BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes192_cbc.Id] = "PBEwithSHA-1and192bitAES-CBC-BC"; + algorithms[BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes256_cbc.Id] = "PBEwithSHA-1and256bitAES-CBC-BC"; + algorithms[BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes128_cbc.Id] = "PBEwithSHA-256and128bitAES-CBC-BC"; + algorithms[BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes192_cbc.Id] = "PBEwithSHA-256and192bitAES-CBC-BC"; + algorithms[BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes256_cbc.Id] = "PBEwithSHA-256and256bitAES-CBC-BC"; + algorithms["PBEWITHSHAAND128BITRC4"] = "PBEwithSHA-1and128bitRC4"; + algorithms["PBEWITHSHA1AND128BITRC4"] = "PBEwithSHA-1and128bitRC4"; + algorithms["PBEWITHSHA-1AND128BITRC4"] = "PBEwithSHA-1and128bitRC4"; + algorithms[PkcsObjectIdentifiers.PbeWithShaAnd128BitRC4.Id] = "PBEwithSHA-1and128bitRC4"; + algorithms["PBEWITHSHAAND40BITRC4"] = "PBEwithSHA-1and40bitRC4"; + algorithms["PBEWITHSHA1AND40BITRC4"] = "PBEwithSHA-1and40bitRC4"; + algorithms["PBEWITHSHA-1AND40BITRC4"] = "PBEwithSHA-1and40bitRC4"; + algorithms[PkcsObjectIdentifiers.PbeWithShaAnd40BitRC4.Id] = "PBEwithSHA-1and40bitRC4"; + algorithms["PBEWITHSHAAND3-KEYDESEDE-CBC"] = "PBEwithSHA-1and3-keyDESEDE-CBC"; + algorithms["PBEWITHSHAAND3-KEYTRIPLEDES-CBC"] = "PBEwithSHA-1and3-keyDESEDE-CBC"; + algorithms["PBEWITHSHA1AND3-KEYDESEDE-CBC"] = "PBEwithSHA-1and3-keyDESEDE-CBC"; + algorithms["PBEWITHSHA1AND3-KEYTRIPLEDES-CBC"] = "PBEwithSHA-1and3-keyDESEDE-CBC"; + algorithms["PBEWITHSHA-1AND3-KEYDESEDE-CBC"] = "PBEwithSHA-1and3-keyDESEDE-CBC"; + algorithms["PBEWITHSHA-1AND3-KEYTRIPLEDES-CBC"] = "PBEwithSHA-1and3-keyDESEDE-CBC"; + algorithms[PkcsObjectIdentifiers.PbeWithShaAnd3KeyTripleDesCbc.Id] = "PBEwithSHA-1and3-keyDESEDE-CBC"; + algorithms["PBEWITHSHAAND2-KEYDESEDE-CBC"] = "PBEwithSHA-1and2-keyDESEDE-CBC"; + algorithms["PBEWITHSHAAND2-KEYTRIPLEDES-CBC"] = "PBEwithSHA-1and2-keyDESEDE-CBC"; + algorithms["PBEWITHSHA1AND2-KEYDESEDE-CBC"] = "PBEwithSHA-1and2-keyDESEDE-CBC"; + algorithms["PBEWITHSHA1AND2-KEYTRIPLEDES-CBC"] = "PBEwithSHA-1and2-keyDESEDE-CBC"; + algorithms["PBEWITHSHA-1AND2-KEYDESEDE-CBC"] = "PBEwithSHA-1and2-keyDESEDE-CBC"; + algorithms["PBEWITHSHA-1AND2-KEYTRIPLEDES-CBC"] = "PBEwithSHA-1and2-keyDESEDE-CBC"; + algorithms[PkcsObjectIdentifiers.PbeWithShaAnd2KeyTripleDesCbc.Id] = "PBEwithSHA-1and2-keyDESEDE-CBC"; + algorithms["PBEWITHSHAAND128BITRC2-CBC"] = "PBEwithSHA-1and128bitRC2-CBC"; + algorithms["PBEWITHSHA1AND128BITRC2-CBC"] = "PBEwithSHA-1and128bitRC2-CBC"; + algorithms["PBEWITHSHA-1AND128BITRC2-CBC"] = "PBEwithSHA-1and128bitRC2-CBC"; + algorithms[PkcsObjectIdentifiers.PbeWithShaAnd128BitRC2Cbc.Id] = "PBEwithSHA-1and128bitRC2-CBC"; + algorithms["PBEWITHSHAAND40BITRC2-CBC"] = "PBEwithSHA-1and40bitRC2-CBC"; + algorithms["PBEWITHSHA1AND40BITRC2-CBC"] = "PBEwithSHA-1and40bitRC2-CBC"; + algorithms["PBEWITHSHA-1AND40BITRC2-CBC"] = "PBEwithSHA-1and40bitRC2-CBC"; + algorithms[PkcsObjectIdentifiers.PbewithShaAnd40BitRC2Cbc.Id] = "PBEwithSHA-1and40bitRC2-CBC"; + algorithms["PBEWITHSHAAND128BITAES-CBC-BC"] = "PBEwithSHA-1and128bitAES-CBC-BC"; + algorithms["PBEWITHSHA1AND128BITAES-CBC-BC"] = "PBEwithSHA-1and128bitAES-CBC-BC"; + algorithms["PBEWITHSHA-1AND128BITAES-CBC-BC"] = "PBEwithSHA-1and128bitAES-CBC-BC"; + algorithms["PBEWITHSHAAND192BITAES-CBC-BC"] = "PBEwithSHA-1and192bitAES-CBC-BC"; + algorithms["PBEWITHSHA1AND192BITAES-CBC-BC"] = "PBEwithSHA-1and192bitAES-CBC-BC"; + algorithms["PBEWITHSHA-1AND192BITAES-CBC-BC"] = "PBEwithSHA-1and192bitAES-CBC-BC"; + algorithms["PBEWITHSHAAND256BITAES-CBC-BC"] = "PBEwithSHA-1and256bitAES-CBC-BC"; + algorithms["PBEWITHSHA1AND256BITAES-CBC-BC"] = "PBEwithSHA-1and256bitAES-CBC-BC"; + algorithms["PBEWITHSHA-1AND256BITAES-CBC-BC"] = "PBEwithSHA-1and256bitAES-CBC-BC"; + algorithms["PBEWITHSHA256AND128BITAES-CBC-BC"] = "PBEwithSHA-256and128bitAES-CBC-BC"; + algorithms["PBEWITHSHA-256AND128BITAES-CBC-BC"] = "PBEwithSHA-256and128bitAES-CBC-BC"; + algorithms["PBEWITHSHA256AND192BITAES-CBC-BC"] = "PBEwithSHA-256and192bitAES-CBC-BC"; + algorithms["PBEWITHSHA-256AND192BITAES-CBC-BC"] = "PBEwithSHA-256and192bitAES-CBC-BC"; + algorithms["PBEWITHSHA256AND256BITAES-CBC-BC"] = "PBEwithSHA-256and256bitAES-CBC-BC"; + algorithms["PBEWITHSHA-256AND256BITAES-CBC-BC"] = "PBEwithSHA-256and256bitAES-CBC-BC"; + algorithms["PBEWITHSHAANDIDEA"] = "PBEwithSHA-1andIDEA-CBC"; + algorithms["PBEWITHSHAANDIDEA-CBC"] = "PBEwithSHA-1andIDEA-CBC"; + algorithms["PBEWITHSHAANDTWOFISH"] = "PBEwithSHA-1andTWOFISH-CBC"; + algorithms["PBEWITHSHAANDTWOFISH-CBC"] = "PBEwithSHA-1andTWOFISH-CBC"; + algorithms["PBEWITHHMACSHA1"] = "PBEwithHmacSHA-1"; + algorithms["PBEWITHHMACSHA-1"] = "PBEwithHmacSHA-1"; + algorithms[OiwObjectIdentifiers.IdSha1.Id] = "PBEwithHmacSHA-1"; + algorithms["PBEWITHHMACSHA224"] = "PBEwithHmacSHA-224"; + algorithms["PBEWITHHMACSHA-224"] = "PBEwithHmacSHA-224"; + algorithms[NistObjectIdentifiers.IdSha224.Id] = "PBEwithHmacSHA-224"; + algorithms["PBEWITHHMACSHA256"] = "PBEwithHmacSHA-256"; + algorithms["PBEWITHHMACSHA-256"] = "PBEwithHmacSHA-256"; + algorithms[NistObjectIdentifiers.IdSha256.Id] = "PBEwithHmacSHA-256"; + algorithms["PBEWITHHMACRIPEMD128"] = "PBEwithHmacRipeMD128"; + algorithms[TeleTrusTObjectIdentifiers.RipeMD128.Id] = "PBEwithHmacRipeMD128"; + algorithms["PBEWITHHMACRIPEMD160"] = "PBEwithHmacRipeMD160"; + algorithms[TeleTrusTObjectIdentifiers.RipeMD160.Id] = "PBEwithHmacRipeMD160"; + algorithms["PBEWITHHMACRIPEMD256"] = "PBEwithHmacRipeMD256"; + algorithms[TeleTrusTObjectIdentifiers.RipeMD256.Id] = "PBEwithHmacRipeMD256"; + algorithms["PBEWITHHMACTIGER"] = "PBEwithHmacTiger"; + + algorithms["PBEWITHMD5AND128BITAES-CBC-OPENSSL"] = "PBEwithMD5and128bitAES-CBC-OpenSSL"; + algorithms["PBEWITHMD5AND192BITAES-CBC-OPENSSL"] = "PBEwithMD5and192bitAES-CBC-OpenSSL"; + algorithms["PBEWITHMD5AND256BITAES-CBC-OPENSSL"] = "PBEwithMD5and256bitAES-CBC-OpenSSL"; + + algorithmType["Pkcs5scheme1"] = Pkcs5S1; + algorithmType["Pkcs5scheme2"] = Pkcs5S2; + algorithmType["PBEwithMD2andDES-CBC"] = Pkcs5S1; + algorithmType["PBEwithMD2andRC2-CBC"] = Pkcs5S1; + algorithmType["PBEwithMD5andDES-CBC"] = Pkcs5S1; + algorithmType["PBEwithMD5andRC2-CBC"] = Pkcs5S1; + algorithmType["PBEwithSHA-1andDES-CBC"] = Pkcs5S1; + algorithmType["PBEwithSHA-1andRC2-CBC"] = Pkcs5S1; + algorithmType["Pkcs12"] = Pkcs12; + algorithmType["PBEwithSHA-1and128bitRC4"] = Pkcs12; + algorithmType["PBEwithSHA-1and40bitRC4"] = Pkcs12; + algorithmType["PBEwithSHA-1and3-keyDESEDE-CBC"] = Pkcs12; + algorithmType["PBEwithSHA-1and2-keyDESEDE-CBC"] = Pkcs12; + algorithmType["PBEwithSHA-1and128bitRC2-CBC"] = Pkcs12; + algorithmType["PBEwithSHA-1and40bitRC2-CBC"] = Pkcs12; + algorithmType["PBEwithSHA-1and128bitAES-CBC-BC"] = Pkcs12; + algorithmType["PBEwithSHA-1and192bitAES-CBC-BC"] = Pkcs12; + algorithmType["PBEwithSHA-1and256bitAES-CBC-BC"] = Pkcs12; + algorithmType["PBEwithSHA-256and128bitAES-CBC-BC"] = Pkcs12; + algorithmType["PBEwithSHA-256and192bitAES-CBC-BC"] = Pkcs12; + algorithmType["PBEwithSHA-256and256bitAES-CBC-BC"] = Pkcs12; + algorithmType["PBEwithSHA-1andIDEA-CBC"] = Pkcs12; + algorithmType["PBEwithSHA-1andTWOFISH-CBC"] = Pkcs12; + algorithmType["PBEwithHmacSHA-1"] = Pkcs12; + algorithmType["PBEwithHmacSHA-224"] = Pkcs12; + algorithmType["PBEwithHmacSHA-256"] = Pkcs12; + algorithmType["PBEwithHmacRipeMD128"] = Pkcs12; + algorithmType["PBEwithHmacRipeMD160"] = Pkcs12; + algorithmType["PBEwithHmacRipeMD256"] = Pkcs12; + algorithmType["PBEwithHmacTiger"] = Pkcs12; + + algorithmType["PBEwithMD5and128bitAES-CBC-OpenSSL"] = OpenSsl; + algorithmType["PBEwithMD5and192bitAES-CBC-OpenSSL"] = OpenSsl; + algorithmType["PBEwithMD5and256bitAES-CBC-OpenSSL"] = OpenSsl; + + oids["PBEwithMD2andDES-CBC"] = PkcsObjectIdentifiers.PbeWithMD2AndDesCbc; + oids["PBEwithMD2andRC2-CBC"] = PkcsObjectIdentifiers.PbeWithMD2AndRC2Cbc; + oids["PBEwithMD5andDES-CBC"] = PkcsObjectIdentifiers.PbeWithMD5AndDesCbc; + oids["PBEwithMD5andRC2-CBC"] = PkcsObjectIdentifiers.PbeWithMD5AndRC2Cbc; + oids["PBEwithSHA-1andDES-CBC"] = PkcsObjectIdentifiers.PbeWithSha1AndDesCbc; + oids["PBEwithSHA-1andRC2-CBC"] = PkcsObjectIdentifiers.PbeWithSha1AndRC2Cbc; + oids["PBEwithSHA-1and128bitRC4"] = PkcsObjectIdentifiers.PbeWithShaAnd128BitRC4; + oids["PBEwithSHA-1and40bitRC4"] = PkcsObjectIdentifiers.PbeWithShaAnd40BitRC4; + oids["PBEwithSHA-1and3-keyDESEDE-CBC"] = PkcsObjectIdentifiers.PbeWithShaAnd3KeyTripleDesCbc; + oids["PBEwithSHA-1and2-keyDESEDE-CBC"] = PkcsObjectIdentifiers.PbeWithShaAnd2KeyTripleDesCbc; + oids["PBEwithSHA-1and128bitRC2-CBC"] = PkcsObjectIdentifiers.PbeWithShaAnd128BitRC2Cbc; + oids["PBEwithSHA-1and40bitRC2-CBC"] = PkcsObjectIdentifiers.PbewithShaAnd40BitRC2Cbc; + oids["PBEwithHmacSHA-1"] = OiwObjectIdentifiers.IdSha1; + oids["PBEwithHmacSHA-224"] = NistObjectIdentifiers.IdSha224; + oids["PBEwithHmacSHA-256"] = NistObjectIdentifiers.IdSha256; + oids["PBEwithHmacRipeMD128"] = TeleTrusTObjectIdentifiers.RipeMD128; + oids["PBEwithHmacRipeMD160"] = TeleTrusTObjectIdentifiers.RipeMD160; + oids["PBEwithHmacRipeMD256"] = TeleTrusTObjectIdentifiers.RipeMD256; + oids["Pkcs5scheme2"] = PkcsObjectIdentifiers.IdPbeS2; + } + + static PbeParametersGenerator MakePbeGenerator( + string type, + IDigest digest, + byte[] key, + byte[] salt, + int iterationCount) + { + PbeParametersGenerator generator; + + if (type.Equals(Pkcs5S1)) + { + generator = new Pkcs5S1ParametersGenerator(digest); + } + else if (type.Equals(Pkcs5S2)) + { + generator = new Pkcs5S2ParametersGenerator(digest); + } + else if (type.Equals(Pkcs12)) + { + generator = new Pkcs12ParametersGenerator(digest); + } + else if (type.Equals(OpenSsl)) + { + generator = new OpenSslPbeParametersGenerator(); + } + else + { + throw new ArgumentException("Unknown PBE type: " + type, "type"); + } + + generator.Init(key, salt, iterationCount); + return generator; + } + + /// + /// Returns a ObjectIdentifier for a give encoding. + /// + /// A string representation of the encoding. + /// A DerObjectIdentifier, null if the Oid is not available. + public static DerObjectIdentifier GetObjectIdentifier( + string mechanism) + { + mechanism = (string) algorithms[Platform.ToUpperInvariant(mechanism)]; + if (mechanism != null) + { + return (DerObjectIdentifier)oids[mechanism]; + } + return null; + } + + public static ICollection Algorithms + { + get { return oids.Keys; } + } + + public static bool IsPkcs12( + string algorithm) + { + string mechanism = (string)algorithms[Platform.ToUpperInvariant(algorithm)]; + + return mechanism != null && Pkcs12.Equals(algorithmType[mechanism]); + } + + public static bool IsPkcs5Scheme1( + string algorithm) + { + string mechanism = (string)algorithms[Platform.ToUpperInvariant(algorithm)]; + + return mechanism != null && Pkcs5S1.Equals(algorithmType[mechanism]); + } + + public static bool IsPkcs5Scheme2( + string algorithm) + { + string mechanism = (string)algorithms[Platform.ToUpperInvariant(algorithm)]; + + return mechanism != null && Pkcs5S2.Equals(algorithmType[mechanism]); + } + + public static bool IsOpenSsl( + string algorithm) + { + string mechanism = (string)algorithms[Platform.ToUpperInvariant(algorithm)]; + + return mechanism != null && OpenSsl.Equals(algorithmType[mechanism]); + } + + public static bool IsPbeAlgorithm( + string algorithm) + { + string mechanism = (string)algorithms[Platform.ToUpperInvariant(algorithm)]; + + return mechanism != null && algorithmType[mechanism] != null; + } + + public static Asn1Encodable GenerateAlgorithmParameters( + DerObjectIdentifier algorithmOid, + byte[] salt, + int iterationCount) + { + return GenerateAlgorithmParameters(algorithmOid.Id, salt, iterationCount); + } + + public static Asn1Encodable GenerateAlgorithmParameters( + string algorithm, + byte[] salt, + int iterationCount) + { + if (IsPkcs12(algorithm)) + { + return new Pkcs12PbeParams(salt, iterationCount); + } + else if (IsPkcs5Scheme2(algorithm)) + { + return new Pbkdf2Params(salt, iterationCount); + } + else + { + return new PbeParameter(salt, iterationCount); + } + } + + public static Asn1Encodable GenerateAlgorithmParameters( + DerObjectIdentifier cipherAlgorithm, + DerObjectIdentifier hashAlgorithm, + byte[] salt, + int iterationCount, + SecureRandom secureRandom) + { + EncryptionScheme encScheme; + if (NistObjectIdentifiers.IdAes128Cbc.Equals(cipherAlgorithm) + || NistObjectIdentifiers.IdAes192Cbc.Equals(cipherAlgorithm) + || NistObjectIdentifiers.IdAes256Cbc.Equals(cipherAlgorithm) + || NistObjectIdentifiers.IdAes128Cfb.Equals(cipherAlgorithm) + || NistObjectIdentifiers.IdAes192Cfb.Equals(cipherAlgorithm) + || NistObjectIdentifiers.IdAes256Cfb.Equals(cipherAlgorithm)) + { + byte[] iv = new byte[16]; + secureRandom.NextBytes(iv); + encScheme = new EncryptionScheme(cipherAlgorithm, new DerOctetString(iv)); + } + else + { + throw new ArgumentException("unknown cipher: " + cipherAlgorithm); + } + + KeyDerivationFunc func = new KeyDerivationFunc(PkcsObjectIdentifiers.IdPbkdf2, new Pbkdf2Params(salt, iterationCount, new AlgorithmIdentifier(hashAlgorithm, DerNull.Instance))); + + return new PbeS2Parameters(func, encScheme); + } + + public static ICipherParameters GenerateCipherParameters( + DerObjectIdentifier algorithmOid, + char[] password, + Asn1Encodable pbeParameters) + { + return GenerateCipherParameters(algorithmOid.Id, password, false, pbeParameters); + } + + public static ICipherParameters GenerateCipherParameters( + DerObjectIdentifier algorithmOid, + char[] password, + bool wrongPkcs12Zero, + Asn1Encodable pbeParameters) + { + return GenerateCipherParameters(algorithmOid.Id, password, wrongPkcs12Zero, pbeParameters); + } + + public static ICipherParameters GenerateCipherParameters( + AlgorithmIdentifier algID, + char[] password) + { + return GenerateCipherParameters(algID.Algorithm.Id, password, false, algID.Parameters); + } + + public static ICipherParameters GenerateCipherParameters( + AlgorithmIdentifier algID, + char[] password, + bool wrongPkcs12Zero) + { + return GenerateCipherParameters(algID.Algorithm.Id, password, wrongPkcs12Zero, algID.Parameters); + } + + public static ICipherParameters GenerateCipherParameters( + string algorithm, + char[] password, + Asn1Encodable pbeParameters) + { + return GenerateCipherParameters(algorithm, password, false, pbeParameters); + } + + public static ICipherParameters GenerateCipherParameters( + string algorithm, + char[] password, + bool wrongPkcs12Zero, + Asn1Encodable pbeParameters) + { + string mechanism = (string)algorithms[Platform.ToUpperInvariant(algorithm)]; + + byte[] keyBytes = null; + byte[] salt = null; + int iterationCount = 0; + + if (IsPkcs12(mechanism)) + { + Pkcs12PbeParams pbeParams = Pkcs12PbeParams.GetInstance(pbeParameters); + salt = pbeParams.GetIV(); + iterationCount = pbeParams.Iterations.IntValue; + keyBytes = PbeParametersGenerator.Pkcs12PasswordToBytes(password, wrongPkcs12Zero); + } + else if (IsPkcs5Scheme2(mechanism)) + { + // See below + } + else + { + PbeParameter pbeParams = PbeParameter.GetInstance(pbeParameters); + salt = pbeParams.GetSalt(); + iterationCount = pbeParams.IterationCount.IntValue; + keyBytes = PbeParametersGenerator.Pkcs5PasswordToBytes(password); + } + + ICipherParameters parameters = null; + + if (IsPkcs5Scheme2(mechanism)) + { + PbeS2Parameters s2p = PbeS2Parameters.GetInstance(pbeParameters.ToAsn1Object()); + AlgorithmIdentifier encScheme = s2p.EncryptionScheme; + DerObjectIdentifier encOid = encScheme.Algorithm; + Asn1Object encParams = encScheme.Parameters.ToAsn1Object(); + + Pbkdf2Params pbeParams = Pbkdf2Params.GetInstance(s2p.KeyDerivationFunc.Parameters.ToAsn1Object()); + IDigest digest = DigestUtilities.GetDigest(pbeParams.Prf.Algorithm); + + byte[] iv; + if (encOid.Equals(PkcsObjectIdentifiers.RC2Cbc)) // PKCS5.B.2.3 + { + RC2CbcParameter rc2Params = RC2CbcParameter.GetInstance(encParams); + iv = rc2Params.GetIV(); + } + else + { + iv = Asn1OctetString.GetInstance(encParams).GetOctets(); + } + + salt = pbeParams.GetSalt(); + iterationCount = pbeParams.IterationCount.IntValue; + keyBytes = PbeParametersGenerator.Pkcs5PasswordToBytes(password); + + int keyLength = pbeParams.KeyLength != null + ? pbeParams.KeyLength.IntValue * 8 + : GeneratorUtilities.GetDefaultKeySize(encOid); + + PbeParametersGenerator gen = MakePbeGenerator( + (string)algorithmType[mechanism], digest, keyBytes, salt, iterationCount); + + parameters = gen.GenerateDerivedParameters(encOid.Id, keyLength); + + if (iv != null) + { + // FIXME? OpenSSL weirdness with IV of zeros (for ECB keys?) + if (Arrays.AreEqual(iv, new byte[iv.Length])) + { + //Console.Error.Write("***** IV all 0 (length " + iv.Length + ") *****"); + } + else + { + parameters = new ParametersWithIV(parameters, iv); + } + } + } + else if (Platform.StartsWith(mechanism, "PBEwithSHA-1")) + { + PbeParametersGenerator generator = MakePbeGenerator( + (string) algorithmType[mechanism], new Sha1Digest(), keyBytes, salt, iterationCount); + + if (mechanism.Equals("PBEwithSHA-1and128bitAES-CBC-BC")) + { + parameters = generator.GenerateDerivedParameters("AES", 128, 128); + } + else if (mechanism.Equals("PBEwithSHA-1and192bitAES-CBC-BC")) + { + parameters = generator.GenerateDerivedParameters("AES", 192, 128); + } + else if (mechanism.Equals("PBEwithSHA-1and256bitAES-CBC-BC")) + { + parameters = generator.GenerateDerivedParameters("AES", 256, 128); + } + else if (mechanism.Equals("PBEwithSHA-1and128bitRC4")) + { + parameters = generator.GenerateDerivedParameters("RC4", 128); + } + else if (mechanism.Equals("PBEwithSHA-1and40bitRC4")) + { + parameters = generator.GenerateDerivedParameters("RC4", 40); + } + else if (mechanism.Equals("PBEwithSHA-1and3-keyDESEDE-CBC")) + { + parameters = generator.GenerateDerivedParameters("DESEDE", 192, 64); + } + else if (mechanism.Equals("PBEwithSHA-1and2-keyDESEDE-CBC")) + { + parameters = generator.GenerateDerivedParameters("DESEDE", 128, 64); + } + else if (mechanism.Equals("PBEwithSHA-1and128bitRC2-CBC")) + { + parameters = generator.GenerateDerivedParameters("RC2", 128, 64); + } + else if (mechanism.Equals("PBEwithSHA-1and40bitRC2-CBC")) + { + parameters = generator.GenerateDerivedParameters("RC2", 40, 64); + } + else if (mechanism.Equals("PBEwithSHA-1andDES-CBC")) + { + parameters = generator.GenerateDerivedParameters("DES", 64, 64); + } + else if (mechanism.Equals("PBEwithSHA-1andRC2-CBC")) + { + parameters = generator.GenerateDerivedParameters("RC2", 64, 64); + } + } + else if (Platform.StartsWith(mechanism, "PBEwithSHA-256")) + { + PbeParametersGenerator generator = MakePbeGenerator( + (string) algorithmType[mechanism], new Sha256Digest(), keyBytes, salt, iterationCount); + + if (mechanism.Equals("PBEwithSHA-256and128bitAES-CBC-BC")) + { + parameters = generator.GenerateDerivedParameters("AES", 128, 128); + } + else if (mechanism.Equals("PBEwithSHA-256and192bitAES-CBC-BC")) + { + parameters = generator.GenerateDerivedParameters("AES", 192, 128); + } + else if (mechanism.Equals("PBEwithSHA-256and256bitAES-CBC-BC")) + { + parameters = generator.GenerateDerivedParameters("AES", 256, 128); + } + } + else if (Platform.StartsWith(mechanism, "PBEwithMD5")) + { + PbeParametersGenerator generator = MakePbeGenerator( + (string)algorithmType[mechanism], new MD5Digest(), keyBytes, salt, iterationCount); + + if (mechanism.Equals("PBEwithMD5andDES-CBC")) + { + parameters = generator.GenerateDerivedParameters("DES", 64, 64); + } + else if (mechanism.Equals("PBEwithMD5andRC2-CBC")) + { + parameters = generator.GenerateDerivedParameters("RC2", 64, 64); + } + else if (mechanism.Equals("PBEwithMD5and128bitAES-CBC-OpenSSL")) + { + parameters = generator.GenerateDerivedParameters("AES", 128, 128); + } + else if (mechanism.Equals("PBEwithMD5and192bitAES-CBC-OpenSSL")) + { + parameters = generator.GenerateDerivedParameters("AES", 192, 128); + } + else if (mechanism.Equals("PBEwithMD5and256bitAES-CBC-OpenSSL")) + { + parameters = generator.GenerateDerivedParameters("AES", 256, 128); + } + } + else if (Platform.StartsWith(mechanism, "PBEwithMD2")) + { + PbeParametersGenerator generator = MakePbeGenerator( + (string)algorithmType[mechanism], new MD2Digest(), keyBytes, salt, iterationCount); + if (mechanism.Equals("PBEwithMD2andDES-CBC")) + { + parameters = generator.GenerateDerivedParameters("DES", 64, 64); + } + else if (mechanism.Equals("PBEwithMD2andRC2-CBC")) + { + parameters = generator.GenerateDerivedParameters("RC2", 64, 64); + } + } + else if (Platform.StartsWith(mechanism, "PBEwithHmac")) + { + string digestName = mechanism.Substring("PBEwithHmac".Length); + IDigest digest = DigestUtilities.GetDigest(digestName); + + PbeParametersGenerator generator = MakePbeGenerator( + (string) algorithmType[mechanism], digest, keyBytes, salt, iterationCount); + + int bitLen = digest.GetDigestSize() * 8; + parameters = generator.GenerateDerivedMacParameters(bitLen); + } + + Array.Clear(keyBytes, 0, keyBytes.Length); + + return FixDesParity(mechanism, parameters); + } + + public static object CreateEngine( + DerObjectIdentifier algorithmOid) + { + return CreateEngine(algorithmOid.Id); + } + + public static object CreateEngine( + AlgorithmIdentifier algID) + { + string algorithm = algID.Algorithm.Id; + + if (IsPkcs5Scheme2(algorithm)) + { + PbeS2Parameters s2p = PbeS2Parameters.GetInstance(algID.Parameters.ToAsn1Object()); + AlgorithmIdentifier encScheme = s2p.EncryptionScheme; + return CipherUtilities.GetCipher(encScheme.Algorithm); + } + + return CreateEngine(algorithm); + } + + public static object CreateEngine( + string algorithm) + { + string mechanism = (string)algorithms[Platform.ToUpperInvariant(algorithm)]; + + if (Platform.StartsWith(mechanism, "PBEwithHmac")) + { + string digestName = mechanism.Substring("PBEwithHmac".Length); + + return MacUtilities.GetMac("HMAC/" + digestName); + } + + if (Platform.StartsWith(mechanism, "PBEwithMD2") + || Platform.StartsWith(mechanism, "PBEwithMD5") + || Platform.StartsWith(mechanism, "PBEwithSHA-1") + || Platform.StartsWith(mechanism, "PBEwithSHA-256")) + { + if (Platform.EndsWith(mechanism, "AES-CBC-BC") || Platform.EndsWith(mechanism, "AES-CBC-OPENSSL")) + { + return CipherUtilities.GetCipher("AES/CBC"); + } + + if (Platform.EndsWith(mechanism, "DES-CBC")) + { + return CipherUtilities.GetCipher("DES/CBC"); + } + + if (Platform.EndsWith(mechanism, "DESEDE-CBC")) + { + return CipherUtilities.GetCipher("DESEDE/CBC"); + } + + if (Platform.EndsWith(mechanism, "RC2-CBC")) + { + return CipherUtilities.GetCipher("RC2/CBC"); + } + + if (Platform.EndsWith(mechanism, "RC4")) + { + return CipherUtilities.GetCipher("RC4"); + } + } + + return null; + } + + public static string GetEncodingName( + DerObjectIdentifier oid) + { + return (string) algorithms[oid.Id]; + } + + private static ICipherParameters FixDesParity(string mechanism, ICipherParameters parameters) + { + if (!Platform.EndsWith(mechanism, "DES-CBC") && !Platform.EndsWith(mechanism, "DESEDE-CBC")) + { + return parameters; + } + + if (parameters is ParametersWithIV) + { + ParametersWithIV ivParams = (ParametersWithIV)parameters; + return new ParametersWithIV(FixDesParity(mechanism, ivParams.Parameters), ivParams.GetIV()); + } + + KeyParameter kParam = (KeyParameter)parameters; + byte[] keyBytes = kParam.GetKey(); + DesParameters.SetOddParity(keyBytes); + return new KeyParameter(keyBytes); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/PbeUtilities.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/PbeUtilities.cs.meta new file mode 100644 index 0000000..65b641a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/PbeUtilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bf7dc1b20584ce84995be7e36ac6dd0c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/PrivateKeyFactory.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/PrivateKeyFactory.cs new file mode 100644 index 0000000..408c8b6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/PrivateKeyFactory.cs @@ -0,0 +1,338 @@ +using System; +using System.Collections; +using System.IO; +using System.Text; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Asn1.EdEC; +using Org.BouncyCastle.Asn1.Oiw; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.Rosstandart; +using Org.BouncyCastle.Asn1.Sec; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Pkcs; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Security +{ + public sealed class PrivateKeyFactory + { + private PrivateKeyFactory() + { + } + + public static AsymmetricKeyParameter CreateKey( + byte[] privateKeyInfoData) + { + return CreateKey( + PrivateKeyInfo.GetInstance( + Asn1Object.FromByteArray(privateKeyInfoData))); + } + + public static AsymmetricKeyParameter CreateKey( + Stream inStr) + { + return CreateKey( + PrivateKeyInfo.GetInstance( + Asn1Object.FromStream(inStr))); + } + + public static AsymmetricKeyParameter CreateKey( + PrivateKeyInfo keyInfo) + { + AlgorithmIdentifier algID = keyInfo.PrivateKeyAlgorithm; + DerObjectIdentifier algOid = algID.Algorithm; + + // TODO See RSAUtil.isRsaOid in Java build + if (algOid.Equals(PkcsObjectIdentifiers.RsaEncryption) + || algOid.Equals(X509ObjectIdentifiers.IdEARsa) + || algOid.Equals(PkcsObjectIdentifiers.IdRsassaPss) + || algOid.Equals(PkcsObjectIdentifiers.IdRsaesOaep)) + { + RsaPrivateKeyStructure keyStructure = RsaPrivateKeyStructure.GetInstance(keyInfo.ParsePrivateKey()); + + return new RsaPrivateCrtKeyParameters( + keyStructure.Modulus, + keyStructure.PublicExponent, + keyStructure.PrivateExponent, + keyStructure.Prime1, + keyStructure.Prime2, + keyStructure.Exponent1, + keyStructure.Exponent2, + keyStructure.Coefficient); + } + // TODO? + // else if (algOid.Equals(X9ObjectIdentifiers.DHPublicNumber)) + else if (algOid.Equals(PkcsObjectIdentifiers.DhKeyAgreement)) + { + DHParameter para = new DHParameter( + Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object())); + DerInteger derX = (DerInteger)keyInfo.ParsePrivateKey(); + + BigInteger lVal = para.L; + int l = lVal == null ? 0 : lVal.IntValue; + DHParameters dhParams = new DHParameters(para.P, para.G, null, l); + + return new DHPrivateKeyParameters(derX.Value, dhParams, algOid); + } + else if (algOid.Equals(OiwObjectIdentifiers.ElGamalAlgorithm)) + { + ElGamalParameter para = new ElGamalParameter( + Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object())); + DerInteger derX = (DerInteger)keyInfo.ParsePrivateKey(); + + return new ElGamalPrivateKeyParameters( + derX.Value, + new ElGamalParameters(para.P, para.G)); + } + else if (algOid.Equals(X9ObjectIdentifiers.IdDsa)) + { + DerInteger derX = (DerInteger)keyInfo.ParsePrivateKey(); + Asn1Encodable ae = algID.Parameters; + + DsaParameters parameters = null; + if (ae != null) + { + DsaParameter para = DsaParameter.GetInstance(ae.ToAsn1Object()); + parameters = new DsaParameters(para.P, para.Q, para.G); + } + + return new DsaPrivateKeyParameters(derX.Value, parameters); + } + else if (algOid.Equals(X9ObjectIdentifiers.IdECPublicKey)) + { + X962Parameters para = X962Parameters.GetInstance(algID.Parameters.ToAsn1Object()); + + X9ECParameters x9; + if (para.IsNamedCurve) + { + x9 = ECKeyPairGenerator.FindECCurveByOid((DerObjectIdentifier)para.Parameters); + } + else + { + x9 = new X9ECParameters((Asn1Sequence)para.Parameters); + } + + ECPrivateKeyStructure ec = ECPrivateKeyStructure.GetInstance(keyInfo.ParsePrivateKey()); + BigInteger d = ec.GetKey(); + + if (para.IsNamedCurve) + { + return new ECPrivateKeyParameters("EC", d, (DerObjectIdentifier)para.Parameters); + } + + ECDomainParameters dParams = new ECDomainParameters(x9.Curve, x9.G, x9.N, x9.H, x9.GetSeed()); + return new ECPrivateKeyParameters(d, dParams); + } + else if (algOid.Equals(CryptoProObjectIdentifiers.GostR3410x2001)) + { + Gost3410PublicKeyAlgParameters gostParams = Gost3410PublicKeyAlgParameters.GetInstance( + algID.Parameters.ToAsn1Object()); + + X9ECParameters ecP = ECGost3410NamedCurves.GetByOidX9(gostParams.PublicKeyParamSet); + + if (ecP == null) + throw new ArgumentException("Unrecognized curve OID for GostR3410x2001 private key"); + + Asn1Object privKey = keyInfo.ParsePrivateKey(); + ECPrivateKeyStructure ec; + + if (privKey is DerInteger) + { + ec = new ECPrivateKeyStructure(ecP.N.BitLength, ((DerInteger)privKey).PositiveValue); + } + else + { + ec = ECPrivateKeyStructure.GetInstance(privKey); + } + + return new ECPrivateKeyParameters("ECGOST3410", ec.GetKey(), gostParams.PublicKeyParamSet); + } + else if (algOid.Equals(CryptoProObjectIdentifiers.GostR3410x94)) + { + Gost3410PublicKeyAlgParameters gostParams = Gost3410PublicKeyAlgParameters.GetInstance(algID.Parameters); + + Asn1Object privKey = keyInfo.ParsePrivateKey(); + BigInteger x; + + if (privKey is DerInteger) + { + x = DerInteger.GetInstance(privKey).PositiveValue; + } + else + { + x = new BigInteger(1, Arrays.Reverse(Asn1OctetString.GetInstance(privKey).GetOctets())); + } + + return new Gost3410PrivateKeyParameters(x, gostParams.PublicKeyParamSet); + } + else if (algOid.Equals(EdECObjectIdentifiers.id_X25519)) + { + return new X25519PrivateKeyParameters(GetRawKey(keyInfo)); + } + else if (algOid.Equals(EdECObjectIdentifiers.id_X448)) + { + return new X448PrivateKeyParameters(GetRawKey(keyInfo)); + } + else if (algOid.Equals(EdECObjectIdentifiers.id_Ed25519)) + { + return new Ed25519PrivateKeyParameters(GetRawKey(keyInfo)); + } + else if (algOid.Equals(EdECObjectIdentifiers.id_Ed448)) + { + return new Ed448PrivateKeyParameters(GetRawKey(keyInfo)); + } + else if (algOid.Equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512) + || algOid.Equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256)) + { + Gost3410PublicKeyAlgParameters gostParams = Gost3410PublicKeyAlgParameters.GetInstance(keyInfo.PrivateKeyAlgorithm.Parameters); + ECGost3410Parameters ecSpec; + BigInteger d; + Asn1Object p = keyInfo.PrivateKeyAlgorithm.Parameters.ToAsn1Object(); + if (p is Asn1Sequence && (Asn1Sequence.GetInstance(p).Count == 2 || Asn1Sequence.GetInstance(p).Count == 3)) + { + + X9ECParameters ecP = ECGost3410NamedCurves.GetByOidX9(gostParams.PublicKeyParamSet); + + ecSpec = new ECGost3410Parameters( + new ECNamedDomainParameters( + gostParams.PublicKeyParamSet, ecP), + gostParams.PublicKeyParamSet, + gostParams.DigestParamSet, + gostParams.EncryptionParamSet); + + Asn1OctetString privEnc = keyInfo.PrivateKeyData; + if (privEnc.GetOctets().Length == 32 || privEnc.GetOctets().Length == 64) + { + byte[] dVal = Arrays.Reverse(privEnc.GetOctets()); + d = new BigInteger(1, dVal); + } + else + { + Asn1Encodable privKey = keyInfo.ParsePrivateKey(); + if (privKey is DerInteger) + { + d = DerInteger.GetInstance(privKey).PositiveValue; + } + else + { + byte[] dVal = Arrays.Reverse(Asn1OctetString.GetInstance(privKey).GetOctets()); + d = new BigInteger(1, dVal); + } + } + } + else + { + X962Parameters parameters = X962Parameters.GetInstance(keyInfo.PrivateKeyAlgorithm.Parameters); + + if (parameters.IsNamedCurve) + { + DerObjectIdentifier oid = DerObjectIdentifier.GetInstance(parameters.Parameters); + X9ECParameters ecP = ECNamedCurveTable.GetByOid(oid); + + ecSpec = new ECGost3410Parameters(new ECNamedDomainParameters(oid, ecP), + gostParams.PublicKeyParamSet, gostParams.DigestParamSet, + gostParams.EncryptionParamSet); + } + else if (parameters.IsImplicitlyCA) + { + ecSpec = null; + } + else + { + X9ECParameters ecP = X9ECParameters.GetInstance(parameters.Parameters); + ecSpec = new ECGost3410Parameters(new ECNamedDomainParameters(algOid, ecP), + gostParams.PublicKeyParamSet, gostParams.DigestParamSet, + gostParams.EncryptionParamSet); + } + + Asn1Encodable privKey = keyInfo.ParsePrivateKey(); + if (privKey is DerInteger) + { + DerInteger derD = DerInteger.GetInstance(privKey); + d = derD.Value; + } + else + { + ECPrivateKeyStructure ec = ECPrivateKeyStructure.GetInstance(privKey); + d = ec.GetKey(); + } + } + + return new ECPrivateKeyParameters( + d, + new ECGost3410Parameters( + ecSpec, + gostParams.PublicKeyParamSet, + gostParams.DigestParamSet, + gostParams.EncryptionParamSet)); + + } + else + { + throw new SecurityUtilityException("algorithm identifier in private key not recognised"); + } + } + + private static byte[] GetRawKey(PrivateKeyInfo keyInfo) + { + return Asn1OctetString.GetInstance(keyInfo.ParsePrivateKey()).GetOctets(); + } + + public static AsymmetricKeyParameter DecryptKey( + char[] passPhrase, + EncryptedPrivateKeyInfo encInfo) + { + return CreateKey(PrivateKeyInfoFactory.CreatePrivateKeyInfo(passPhrase, encInfo)); + } + + public static AsymmetricKeyParameter DecryptKey( + char[] passPhrase, + byte[] encryptedPrivateKeyInfoData) + { + return DecryptKey(passPhrase, Asn1Object.FromByteArray(encryptedPrivateKeyInfoData)); + } + + public static AsymmetricKeyParameter DecryptKey( + char[] passPhrase, + Stream encryptedPrivateKeyInfoStream) + { + return DecryptKey(passPhrase, Asn1Object.FromStream(encryptedPrivateKeyInfoStream)); + } + + private static AsymmetricKeyParameter DecryptKey( + char[] passPhrase, + Asn1Object asn1Object) + { + return DecryptKey(passPhrase, EncryptedPrivateKeyInfo.GetInstance(asn1Object)); + } + + public static byte[] EncryptKey( + DerObjectIdentifier algorithm, + char[] passPhrase, + byte[] salt, + int iterationCount, + AsymmetricKeyParameter key) + { + return EncryptedPrivateKeyInfoFactory.CreateEncryptedPrivateKeyInfo( + algorithm, passPhrase, salt, iterationCount, key).GetEncoded(); + } + + public static byte[] EncryptKey( + string algorithm, + char[] passPhrase, + byte[] salt, + int iterationCount, + AsymmetricKeyParameter key) + { + return EncryptedPrivateKeyInfoFactory.CreateEncryptedPrivateKeyInfo( + algorithm, passPhrase, salt, iterationCount, key).GetEncoded(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/PrivateKeyFactory.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/PrivateKeyFactory.cs.meta new file mode 100644 index 0000000..1fa0058 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/PrivateKeyFactory.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3f0b22aa4a72db045ac056c27fc6281d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/PublicKeyFactory.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/PublicKeyFactory.cs new file mode 100644 index 0000000..10b2aac --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/PublicKeyFactory.cs @@ -0,0 +1,320 @@ +using System; +using System.Collections; +using System.IO; +using System.Text; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Asn1.EdEC; +using Org.BouncyCastle.Asn1.Oiw; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.Rosstandart; +using Org.BouncyCastle.Asn1.Sec; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Security +{ + public sealed class PublicKeyFactory + { + private PublicKeyFactory() + { + } + + public static AsymmetricKeyParameter CreateKey( + byte[] keyInfoData) + { + return CreateKey( + SubjectPublicKeyInfo.GetInstance( + Asn1Object.FromByteArray(keyInfoData))); + } + + public static AsymmetricKeyParameter CreateKey( + Stream inStr) + { + return CreateKey( + SubjectPublicKeyInfo.GetInstance( + Asn1Object.FromStream(inStr))); + } + + public static AsymmetricKeyParameter CreateKey( + SubjectPublicKeyInfo keyInfo) + { + AlgorithmIdentifier algID = keyInfo.AlgorithmID; + DerObjectIdentifier algOid = algID.Algorithm; + + // TODO See RSAUtil.isRsaOid in Java build + if (algOid.Equals(PkcsObjectIdentifiers.RsaEncryption) + || algOid.Equals(X509ObjectIdentifiers.IdEARsa) + || algOid.Equals(PkcsObjectIdentifiers.IdRsassaPss) + || algOid.Equals(PkcsObjectIdentifiers.IdRsaesOaep)) + { + RsaPublicKeyStructure pubKey = RsaPublicKeyStructure.GetInstance( + keyInfo.ParsePublicKey()); + + return new RsaKeyParameters(false, pubKey.Modulus, pubKey.PublicExponent); + } + else if (algOid.Equals(X9ObjectIdentifiers.DHPublicNumber)) + { + Asn1Sequence seq = Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object()); + + DHPublicKey dhPublicKey = DHPublicKey.GetInstance(keyInfo.ParsePublicKey()); + + BigInteger y = dhPublicKey.Y.Value; + + if (IsPkcsDHParam(seq)) + return ReadPkcsDHParam(algOid, y, seq); + + DHDomainParameters dhParams = DHDomainParameters.GetInstance(seq); + + BigInteger p = dhParams.P.Value; + BigInteger g = dhParams.G.Value; + BigInteger q = dhParams.Q.Value; + + BigInteger j = null; + if (dhParams.J != null) + { + j = dhParams.J.Value; + } + + DHValidationParameters validation = null; + DHValidationParms dhValidationParms = dhParams.ValidationParms; + if (dhValidationParms != null) + { + byte[] seed = dhValidationParms.Seed.GetBytes(); + BigInteger pgenCounter = dhValidationParms.PgenCounter.Value; + + // TODO Check pgenCounter size? + + validation = new DHValidationParameters(seed, pgenCounter.IntValue); + } + + return new DHPublicKeyParameters(y, new DHParameters(p, g, q, j, validation)); + } + else if (algOid.Equals(PkcsObjectIdentifiers.DhKeyAgreement)) + { + Asn1Sequence seq = Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object()); + + DerInteger derY = (DerInteger)keyInfo.ParsePublicKey(); + + return ReadPkcsDHParam(algOid, derY.Value, seq); + } + else if (algOid.Equals(OiwObjectIdentifiers.ElGamalAlgorithm)) + { + ElGamalParameter para = new ElGamalParameter( + Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object())); + DerInteger derY = (DerInteger)keyInfo.ParsePublicKey(); + + return new ElGamalPublicKeyParameters( + derY.Value, + new ElGamalParameters(para.P, para.G)); + } + else if (algOid.Equals(X9ObjectIdentifiers.IdDsa) + || algOid.Equals(OiwObjectIdentifiers.DsaWithSha1)) + { + DerInteger derY = (DerInteger)keyInfo.ParsePublicKey(); + Asn1Encodable ae = algID.Parameters; + + DsaParameters parameters = null; + if (ae != null) + { + DsaParameter para = DsaParameter.GetInstance(ae.ToAsn1Object()); + parameters = new DsaParameters(para.P, para.Q, para.G); + } + + return new DsaPublicKeyParameters(derY.Value, parameters); + } + else if (algOid.Equals(X9ObjectIdentifiers.IdECPublicKey)) + { + X962Parameters para = X962Parameters.GetInstance(algID.Parameters.ToAsn1Object()); + + X9ECParameters x9; + if (para.IsNamedCurve) + { + x9 = ECKeyPairGenerator.FindECCurveByOid((DerObjectIdentifier)para.Parameters); + } + else + { + x9 = new X9ECParameters((Asn1Sequence)para.Parameters); + } + + Asn1OctetString key = new DerOctetString(keyInfo.PublicKeyData.GetBytes()); + X9ECPoint derQ = new X9ECPoint(x9.Curve, key); + ECPoint q = derQ.Point; + + if (para.IsNamedCurve) + { + return new ECPublicKeyParameters("EC", q, (DerObjectIdentifier)para.Parameters); + } + + ECDomainParameters dParams = new ECDomainParameters(x9); + return new ECPublicKeyParameters(q, dParams); + } + else if (algOid.Equals(CryptoProObjectIdentifiers.GostR3410x2001)) + { + Gost3410PublicKeyAlgParameters gostParams = Gost3410PublicKeyAlgParameters.GetInstance(algID.Parameters); + DerObjectIdentifier publicKeyParamSet = gostParams.PublicKeyParamSet; + + X9ECParameters ecP = ECGost3410NamedCurves.GetByOidX9(publicKeyParamSet); + if (ecP == null) + return null; + + Asn1OctetString key; + try + { + key = (Asn1OctetString)keyInfo.ParsePublicKey(); + } + catch (IOException e) + { + throw new ArgumentException("error recovering GOST3410_2001 public key", e); + } + + int fieldSize = 32; + int keySize = 2 * fieldSize; + + byte[] keyEnc = key.GetOctets(); + if (keyEnc.Length != keySize) + throw new ArgumentException("invalid length for GOST3410_2001 public key"); + + byte[] x9Encoding = new byte[1 + keySize]; + x9Encoding[0] = 0x04; + for (int i = 1; i <= fieldSize; ++i) + { + x9Encoding[i] = keyEnc[fieldSize - i]; + x9Encoding[i + fieldSize] = keyEnc[keySize - i]; + } + + ECPoint q = ecP.Curve.DecodePoint(x9Encoding); + + return new ECPublicKeyParameters("ECGOST3410", q, publicKeyParamSet); + } + else if (algOid.Equals(CryptoProObjectIdentifiers.GostR3410x94)) + { + Gost3410PublicKeyAlgParameters algParams = Gost3410PublicKeyAlgParameters.GetInstance(algID.Parameters); + + Asn1OctetString key; + try + { + key = (Asn1OctetString)keyInfo.ParsePublicKey(); + } + catch (IOException e) + { + throw new ArgumentException("error recovering GOST3410_94 public key", e); + } + + byte[] keyBytes = Arrays.Reverse(key.GetOctets()); // was little endian + + BigInteger y = new BigInteger(1, keyBytes); + + return new Gost3410PublicKeyParameters(y, algParams.PublicKeyParamSet); + } + else if (algOid.Equals(EdECObjectIdentifiers.id_X25519)) + { + return new X25519PublicKeyParameters(GetRawKey(keyInfo)); + } + else if (algOid.Equals(EdECObjectIdentifiers.id_X448)) + { + return new X448PublicKeyParameters(GetRawKey(keyInfo)); + } + else if (algOid.Equals(EdECObjectIdentifiers.id_Ed25519)) + { + return new Ed25519PublicKeyParameters(GetRawKey(keyInfo)); + } + else if (algOid.Equals(EdECObjectIdentifiers.id_Ed448)) + { + return new Ed448PublicKeyParameters(GetRawKey(keyInfo)); + } + else if (algOid.Equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256) + || algOid.Equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512)) + { + Gost3410PublicKeyAlgParameters gostParams = Gost3410PublicKeyAlgParameters.GetInstance(algID.Parameters); + DerObjectIdentifier publicKeyParamSet = gostParams.PublicKeyParamSet; + + ECGost3410Parameters ecDomainParameters =new ECGost3410Parameters( + new ECNamedDomainParameters(publicKeyParamSet, ECGost3410NamedCurves.GetByOidX9(publicKeyParamSet)), + publicKeyParamSet, + gostParams.DigestParamSet, + gostParams.EncryptionParamSet); + + Asn1OctetString key; + try + { + key = (Asn1OctetString)keyInfo.ParsePublicKey(); + } + catch (IOException e) + { + throw new ArgumentException("error recovering GOST3410_2012 public key", e); + } + + int fieldSize = 32; + if (algOid.Equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512)) + { + fieldSize = 64; + } + int keySize = 2 * fieldSize; + + byte[] keyEnc = key.GetOctets(); + if (keyEnc.Length != keySize) + throw new ArgumentException("invalid length for GOST3410_2012 public key"); + + byte[] x9Encoding = new byte[1 + keySize]; + x9Encoding[0] = 0x04; + for (int i = 1; i <= fieldSize; ++i) + { + x9Encoding[i] = keyEnc[fieldSize - i]; + x9Encoding[i + fieldSize] = keyEnc[keySize - i]; + } + + ECPoint q = ecDomainParameters.Curve.DecodePoint(x9Encoding); + + return new ECPublicKeyParameters(q, ecDomainParameters); + } + else + { + throw new SecurityUtilityException("algorithm identifier in public key not recognised: " + algOid); + } + } + + private static byte[] GetRawKey(SubjectPublicKeyInfo keyInfo) + { + /* + * TODO[RFC 8422] + * - Require keyInfo.Algorithm.Parameters == null? + */ + return keyInfo.PublicKeyData.GetOctets(); + } + + private static bool IsPkcsDHParam(Asn1Sequence seq) + { + if (seq.Count == 2) + return true; + + if (seq.Count > 3) + return false; + + DerInteger l = DerInteger.GetInstance(seq[2]); + DerInteger p = DerInteger.GetInstance(seq[0]); + + return l.Value.CompareTo(BigInteger.ValueOf(p.Value.BitLength)) <= 0; + } + + private static DHPublicKeyParameters ReadPkcsDHParam(DerObjectIdentifier algOid, + BigInteger y, Asn1Sequence seq) + { + DHParameter para = new DHParameter(seq); + + BigInteger lVal = para.L; + int l = lVal == null ? 0 : lVal.IntValue; + DHParameters dhParams = new DHParameters(para.P, para.G, null, l); + + return new DHPublicKeyParameters(y, dhParams, algOid); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/PublicKeyFactory.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/PublicKeyFactory.cs.meta new file mode 100644 index 0000000..0c545a7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/PublicKeyFactory.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9d69b25d9151e7740b8617a040de36df +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/SecureRandom.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/SecureRandom.cs new file mode 100644 index 0000000..982fbf3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/SecureRandom.cs @@ -0,0 +1,259 @@ +using System; +using System.Threading; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Prng; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Security +{ + public class SecureRandom + : Random + { + private static long counter = Times.NanoTime(); + +#if NETCF_1_0 || PORTABLE + private static object counterLock = new object(); + private static long NextCounterValue() + { + lock (counterLock) + { + return ++counter; + } + } + + private static readonly SecureRandom[] master = { null }; + private static SecureRandom Master + { + get + { + lock (master) + { + if (master[0] == null) + { + SecureRandom sr = master[0] = GetInstance("SHA256PRNG", false); + + // Even though Ticks has at most 8 or 14 bits of entropy, there's no harm in adding it. + sr.SetSeed(DateTime.Now.Ticks); + + // 32 will be enough when ThreadedSeedGenerator is fixed. Until then, ThreadedSeedGenerator returns low + // entropy, and this is not sufficient to be secure. http://www.bouncycastle.org/csharpdevmailarchive/msg00814.html + sr.SetSeed(new ThreadedSeedGenerator().GenerateSeed(32, true)); + } + + return master[0]; + } + } + } +#else + private static long NextCounterValue() + { + return Interlocked.Increment(ref counter); + } + + private static readonly SecureRandom master = new SecureRandom(new CryptoApiRandomGenerator()); + private static SecureRandom Master + { + get { return master; } + } +#endif + + private static DigestRandomGenerator CreatePrng(string digestName, bool autoSeed) + { + IDigest digest = DigestUtilities.GetDigest(digestName); + if (digest == null) + return null; + DigestRandomGenerator prng = new DigestRandomGenerator(digest); + if (autoSeed) + { + prng.AddSeedMaterial(NextCounterValue()); + prng.AddSeedMaterial(GetNextBytes(Master, digest.GetDigestSize())); + } + return prng; + } + + public static byte[] GetNextBytes(SecureRandom secureRandom, int length) + { + byte[] result = new byte[length]; + secureRandom.NextBytes(result); + return result; + } + + /// + /// Create and auto-seed an instance based on the given algorithm. + /// + /// Equivalent to GetInstance(algorithm, true) + /// e.g. "SHA256PRNG" + public static SecureRandom GetInstance(string algorithm) + { + return GetInstance(algorithm, true); + } + + /// + /// Create an instance based on the given algorithm, with optional auto-seeding + /// + /// e.g. "SHA256PRNG" + /// If true, the instance will be auto-seeded. + public static SecureRandom GetInstance(string algorithm, bool autoSeed) + { + string upper = Platform.ToUpperInvariant(algorithm); + if (Platform.EndsWith(upper, "PRNG")) + { + string digestName = upper.Substring(0, upper.Length - "PRNG".Length); + DigestRandomGenerator prng = CreatePrng(digestName, autoSeed); + if (prng != null) + { + return new SecureRandom(prng); + } + } + + throw new ArgumentException("Unrecognised PRNG algorithm: " + algorithm, "algorithm"); + } + + [Obsolete("Call GenerateSeed() on a SecureRandom instance instead")] + public static byte[] GetSeed(int length) + { + return GetNextBytes(Master, length); + } + + protected readonly IRandomGenerator generator; + + public SecureRandom() + : this(CreatePrng("SHA256", true)) + { + } + + /// + /// To replicate existing predictable output, replace with GetInstance("SHA1PRNG", false), followed by SetSeed(seed) + /// + [Obsolete("Use GetInstance/SetSeed instead")] + public SecureRandom(byte[] seed) + : this(CreatePrng("SHA1", false)) + { + SetSeed(seed); + } + + /// Use the specified instance of IRandomGenerator as random source. + /// + /// This constructor performs no seeding of either the IRandomGenerator or the + /// constructed SecureRandom. It is the responsibility of the client to provide + /// proper seed material as necessary/appropriate for the given IRandomGenerator + /// implementation. + /// + /// The source to generate all random bytes from. + public SecureRandom(IRandomGenerator generator) + : base(0) + { + this.generator = generator; + } + + public virtual byte[] GenerateSeed(int length) + { + return GetNextBytes(Master, length); + } + + public virtual void SetSeed(byte[] seed) + { + generator.AddSeedMaterial(seed); + } + + public virtual void SetSeed(long seed) + { + generator.AddSeedMaterial(seed); + } + + public override int Next() + { + return NextInt() & int.MaxValue; + } + + public override int Next(int maxValue) + { + + if (maxValue < 2) + { + if (maxValue < 0) + throw new ArgumentOutOfRangeException("maxValue", "cannot be negative"); + + return 0; + } + + int bits; + + // Test whether maxValue is a power of 2 + if ((maxValue & (maxValue - 1)) == 0) + { + bits = NextInt() & int.MaxValue; + return (int)(((long)bits * maxValue) >> 31); + } + + int result; + do + { + bits = NextInt() & int.MaxValue; + result = bits % maxValue; + } + while (bits - result + (maxValue - 1) < 0); // Ignore results near overflow + + return result; + } + + public override int Next(int minValue, int maxValue) + { + if (maxValue <= minValue) + { + if (maxValue == minValue) + return minValue; + + throw new ArgumentException("maxValue cannot be less than minValue"); + } + + int diff = maxValue - minValue; + if (diff > 0) + return minValue + Next(diff); + + for (;;) + { + int i = NextInt(); + + if (i >= minValue && i < maxValue) + return i; + } + } + + public override void NextBytes(byte[] buf) + { + generator.NextBytes(buf); + } + + public virtual void NextBytes(byte[] buf, int off, int len) + { + generator.NextBytes(buf, off, len); + } + + private static readonly double DoubleScale = 1.0 / Convert.ToDouble(1L << 53); + + public override double NextDouble() + { + ulong x = (ulong)NextLong() >> 11; + + return Convert.ToDouble(x) * DoubleScale; + } + + public virtual int NextInt() + { + byte[] bytes = new byte[4]; + NextBytes(bytes); + return (int)Pack.BE_To_UInt32(bytes, 0); + } + + public virtual long NextLong() + { + byte[] bytes = new byte[8]; + NextBytes(bytes); + return (long)Pack.BE_To_UInt64(bytes, 0); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/SecureRandom.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/SecureRandom.cs.meta new file mode 100644 index 0000000..8cba042 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/SecureRandom.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 496492058bf173b49af69231f817e264 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/SecurityUtilityException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/SecurityUtilityException.cs new file mode 100644 index 0000000..8a19530 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/SecurityUtilityException.cs @@ -0,0 +1,36 @@ +using System; + +namespace Org.BouncyCastle.Security +{ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE) + [Serializable] +#endif + public class SecurityUtilityException + : Exception + { + /** + * base constructor. + */ + public SecurityUtilityException() + { + } + + /** + * create a SecurityUtilityException with the given message. + * + * @param message the message to be carried with the exception. + */ + public SecurityUtilityException( + string message) + : base(message) + { + } + + public SecurityUtilityException( + string message, + Exception exception) + : base(message, exception) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/SecurityUtilityException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/SecurityUtilityException.cs.meta new file mode 100644 index 0000000..2e11052 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/SecurityUtilityException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 87829eb438b300d4b91cb39cf3c1c023 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/SignatureException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/SignatureException.cs new file mode 100644 index 0000000..3ad617d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/SignatureException.cs @@ -0,0 +1,14 @@ +using System; + +namespace Org.BouncyCastle.Security +{ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE) + [Serializable] +#endif + public class SignatureException : GeneralSecurityException + { + public SignatureException() : base() { } + public SignatureException(string message) : base(message) { } + public SignatureException(string message, Exception exception) : base(message, exception) { } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/SignatureException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/SignatureException.cs.meta new file mode 100644 index 0000000..60945e5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/SignatureException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 215e3232748ee2b48a8b20802af376d5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/SignerUtilities.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/SignerUtilities.cs new file mode 100644 index 0000000..8a28989 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/SignerUtilities.cs @@ -0,0 +1,698 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Bsi; +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Asn1.Eac; +using Org.BouncyCastle.Asn1.EdEC; +using Org.BouncyCastle.Asn1.GM; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Oiw; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.TeleTrust; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Signers; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Security +{ + /// + /// Signer Utility class contains methods that can not be specifically grouped into other classes. + /// + public sealed class SignerUtilities + { + private SignerUtilities() + { + } + + internal static readonly IDictionary algorithms = Platform.CreateHashtable(); + internal static readonly IDictionary oids = Platform.CreateHashtable(); + + static SignerUtilities() + { + algorithms["MD2WITHRSA"] = "MD2withRSA"; + algorithms["MD2WITHRSAENCRYPTION"] = "MD2withRSA"; + algorithms[PkcsObjectIdentifiers.MD2WithRsaEncryption.Id] = "MD2withRSA"; + + algorithms["MD4WITHRSA"] = "MD4withRSA"; + algorithms["MD4WITHRSAENCRYPTION"] = "MD4withRSA"; + algorithms[PkcsObjectIdentifiers.MD4WithRsaEncryption.Id] = "MD4withRSA"; + algorithms[OiwObjectIdentifiers.MD4WithRsa.Id] = "MD4withRSA"; + algorithms[OiwObjectIdentifiers.MD4WithRsaEncryption.Id] = "MD4withRSA"; + + algorithms["MD5WITHRSA"] = "MD5withRSA"; + algorithms["MD5WITHRSAENCRYPTION"] = "MD5withRSA"; + algorithms[PkcsObjectIdentifiers.MD5WithRsaEncryption.Id] = "MD5withRSA"; + algorithms[OiwObjectIdentifiers.MD5WithRsa.Id] = "MD5withRSA"; + + algorithms["SHA1WITHRSA"] = "SHA-1withRSA"; + algorithms["SHA-1WITHRSA"] = "SHA-1withRSA"; + algorithms["SHA1WITHRSAENCRYPTION"] = "SHA-1withRSA"; + algorithms["SHA-1WITHRSAENCRYPTION"] = "SHA-1withRSA"; + algorithms[PkcsObjectIdentifiers.Sha1WithRsaEncryption.Id] = "SHA-1withRSA"; + algorithms[OiwObjectIdentifiers.Sha1WithRsa.Id] = "SHA-1withRSA"; + + algorithms["SHA224WITHRSA"] = "SHA-224withRSA"; + algorithms["SHA-224WITHRSA"] = "SHA-224withRSA"; + algorithms["SHA224WITHRSAENCRYPTION"] = "SHA-224withRSA"; + algorithms["SHA-224WITHRSAENCRYPTION"] = "SHA-224withRSA"; + algorithms[PkcsObjectIdentifiers.Sha224WithRsaEncryption.Id] = "SHA-224withRSA"; + + algorithms["SHA256WITHRSA"] = "SHA-256withRSA"; + algorithms["SHA-256WITHRSA"] = "SHA-256withRSA"; + algorithms["SHA256WITHRSAENCRYPTION"] = "SHA-256withRSA"; + algorithms["SHA-256WITHRSAENCRYPTION"] = "SHA-256withRSA"; + algorithms[PkcsObjectIdentifiers.Sha256WithRsaEncryption.Id] = "SHA-256withRSA"; + + algorithms["SHA384WITHRSA"] = "SHA-384withRSA"; + algorithms["SHA-384WITHRSA"] = "SHA-384withRSA"; + algorithms["SHA384WITHRSAENCRYPTION"] = "SHA-384withRSA"; + algorithms["SHA-384WITHRSAENCRYPTION"] = "SHA-384withRSA"; + algorithms[PkcsObjectIdentifiers.Sha384WithRsaEncryption.Id] = "SHA-384withRSA"; + + algorithms["SHA512WITHRSA"] = "SHA-512withRSA"; + algorithms["SHA-512WITHRSA"] = "SHA-512withRSA"; + algorithms["SHA512WITHRSAENCRYPTION"] = "SHA-512withRSA"; + algorithms["SHA-512WITHRSAENCRYPTION"] = "SHA-512withRSA"; + algorithms[PkcsObjectIdentifiers.Sha512WithRsaEncryption.Id] = "SHA-512withRSA"; + + algorithms["SHA512(224)WITHRSA"] = "SHA-512(224)withRSA"; + algorithms["SHA-512(224)WITHRSA"] = "SHA-512(224)withRSA"; + algorithms["SHA512(224)WITHRSAENCRYPTION"] = "SHA-512(224)withRSA"; + algorithms["SHA-512(224)WITHRSAENCRYPTION"] = "SHA-512(224)withRSA"; + algorithms[PkcsObjectIdentifiers.Sha512_224WithRSAEncryption.Id] = "SHA-512(224)withRSA"; + + algorithms["SHA512(256)WITHRSA"] = "SHA-512(256)withRSA"; + algorithms["SHA-512(256)WITHRSA"] = "SHA-512(256)withRSA"; + algorithms["SHA512(256)WITHRSAENCRYPTION"] = "SHA-512(256)withRSA"; + algorithms["SHA-512(256)WITHRSAENCRYPTION"] = "SHA-512(256)withRSA"; + algorithms[PkcsObjectIdentifiers.Sha512_256WithRSAEncryption.Id] = "SHA-512(256)withRSA"; + + algorithms["SHA3-224WITHRSA"] = "SHA3-224withRSA"; + algorithms["SHA3-224WITHRSAENCRYPTION"] = "SHA3-224withRSA"; + algorithms[NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_224.Id] = "SHA3-224withRSA"; + algorithms["SHA3-256WITHRSA"] = "SHA3-256withRSA"; + algorithms["SHA3-256WITHRSAENCRYPTION"] = "SHA3-256withRSA"; + algorithms[NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_256.Id] = "SHA3-256withRSA"; + algorithms["SHA3-384WITHRSA"] = "SHA3-384withRSA"; + algorithms["SHA3-384WITHRSAENCRYPTION"] = "SHA3-384withRSA"; + algorithms[NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_384.Id] = "SHA3-384withRSA"; + algorithms["SHA3-512WITHRSA"] = "SHA3-512withRSA"; + algorithms["SHA3-512WITHRSAENCRYPTION"] = "SHA3-512withRSA"; + algorithms[NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_512.Id] = "SHA3-512withRSA"; + + algorithms["PSSWITHRSA"] = "PSSwithRSA"; + algorithms["RSASSA-PSS"] = "PSSwithRSA"; + algorithms[PkcsObjectIdentifiers.IdRsassaPss.Id] = "PSSwithRSA"; + algorithms["RSAPSS"] = "PSSwithRSA"; + + algorithms["SHA1WITHRSAANDMGF1"] = "SHA-1withRSAandMGF1"; + algorithms["SHA-1WITHRSAANDMGF1"] = "SHA-1withRSAandMGF1"; + algorithms["SHA1WITHRSA/PSS"] = "SHA-1withRSAandMGF1"; + algorithms["SHA-1WITHRSA/PSS"] = "SHA-1withRSAandMGF1"; + algorithms["SHA1WITHRSASSA-PSS"] = "SHA-1withRSAandMGF1"; + algorithms["SHA-1WITHRSASSA-PSS"] = "SHA-1withRSAandMGF1"; + + algorithms["SHA224WITHRSAANDMGF1"] = "SHA-224withRSAandMGF1"; + algorithms["SHA-224WITHRSAANDMGF1"] = "SHA-224withRSAandMGF1"; + algorithms["SHA224WITHRSA/PSS"] = "SHA-224withRSAandMGF1"; + algorithms["SHA-224WITHRSA/PSS"] = "SHA-224withRSAandMGF1"; + algorithms["SHA224WITHRSASSA-PSS"] = "SHA-224withRSAandMGF1"; + algorithms["SHA-224WITHRSASSA-PSS"] = "SHA-224withRSAandMGF1"; + + algorithms["SHA256WITHRSAANDMGF1"] = "SHA-256withRSAandMGF1"; + algorithms["SHA-256WITHRSAANDMGF1"] = "SHA-256withRSAandMGF1"; + algorithms["SHA256WITHRSA/PSS"] = "SHA-256withRSAandMGF1"; + algorithms["SHA-256WITHRSA/PSS"] = "SHA-256withRSAandMGF1"; + algorithms["SHA256WITHRSASSA-PSS"] = "SHA-256withRSAandMGF1"; + algorithms["SHA-256WITHRSASSA-PSS"] = "SHA-256withRSAandMGF1"; + + algorithms["SHA384WITHRSAANDMGF1"] = "SHA-384withRSAandMGF1"; + algorithms["SHA-384WITHRSAANDMGF1"] = "SHA-384withRSAandMGF1"; + algorithms["SHA384WITHRSA/PSS"] = "SHA-384withRSAandMGF1"; + algorithms["SHA-384WITHRSA/PSS"] = "SHA-384withRSAandMGF1"; + algorithms["SHA384WITHRSASSA-PSS"] = "SHA-384withRSAandMGF1"; + algorithms["SHA-384WITHRSASSA-PSS"] = "SHA-384withRSAandMGF1"; + + algorithms["SHA512WITHRSAANDMGF1"] = "SHA-512withRSAandMGF1"; + algorithms["SHA-512WITHRSAANDMGF1"] = "SHA-512withRSAandMGF1"; + algorithms["SHA512WITHRSA/PSS"] = "SHA-512withRSAandMGF1"; + algorithms["SHA-512WITHRSA/PSS"] = "SHA-512withRSAandMGF1"; + algorithms["SHA512WITHRSASSA-PSS"] = "SHA-512withRSAandMGF1"; + algorithms["SHA-512WITHRSASSA-PSS"] = "SHA-512withRSAandMGF1"; + + algorithms["RIPEMD128WITHRSA"] = "RIPEMD128withRSA"; + algorithms["RIPEMD128WITHRSAENCRYPTION"] = "RIPEMD128withRSA"; + algorithms[TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128.Id] = "RIPEMD128withRSA"; + + algorithms["RIPEMD160WITHRSA"] = "RIPEMD160withRSA"; + algorithms["RIPEMD160WITHRSAENCRYPTION"] = "RIPEMD160withRSA"; + algorithms[TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160.Id] = "RIPEMD160withRSA"; + + algorithms["RIPEMD256WITHRSA"] = "RIPEMD256withRSA"; + algorithms["RIPEMD256WITHRSAENCRYPTION"] = "RIPEMD256withRSA"; + algorithms[TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256.Id] = "RIPEMD256withRSA"; + + algorithms["NONEWITHRSA"] = "RSA"; + algorithms["RSAWITHNONE"] = "RSA"; + algorithms["RAWRSA"] = "RSA"; + + algorithms["RAWRSAPSS"] = "RAWRSASSA-PSS"; + algorithms["NONEWITHRSAPSS"] = "RAWRSASSA-PSS"; + algorithms["NONEWITHRSASSA-PSS"] = "RAWRSASSA-PSS"; + + algorithms["NONEWITHDSA"] = "NONEwithDSA"; + algorithms["DSAWITHNONE"] = "NONEwithDSA"; + algorithms["RAWDSA"] = "NONEwithDSA"; + + algorithms["DSA"] = "SHA-1withDSA"; + algorithms["DSAWITHSHA1"] = "SHA-1withDSA"; + algorithms["DSAWITHSHA-1"] = "SHA-1withDSA"; + algorithms["SHA/DSA"] = "SHA-1withDSA"; + algorithms["SHA1/DSA"] = "SHA-1withDSA"; + algorithms["SHA-1/DSA"] = "SHA-1withDSA"; + algorithms["SHA1WITHDSA"] = "SHA-1withDSA"; + algorithms["SHA-1WITHDSA"] = "SHA-1withDSA"; + algorithms[X9ObjectIdentifiers.IdDsaWithSha1.Id] = "SHA-1withDSA"; + algorithms[OiwObjectIdentifiers.DsaWithSha1.Id] = "SHA-1withDSA"; + + algorithms["DSAWITHSHA224"] = "SHA-224withDSA"; + algorithms["DSAWITHSHA-224"] = "SHA-224withDSA"; + algorithms["SHA224/DSA"] = "SHA-224withDSA"; + algorithms["SHA-224/DSA"] = "SHA-224withDSA"; + algorithms["SHA224WITHDSA"] = "SHA-224withDSA"; + algorithms["SHA-224WITHDSA"] = "SHA-224withDSA"; + algorithms[NistObjectIdentifiers.DsaWithSha224.Id] = "SHA-224withDSA"; + + algorithms["DSAWITHSHA256"] = "SHA-256withDSA"; + algorithms["DSAWITHSHA-256"] = "SHA-256withDSA"; + algorithms["SHA256/DSA"] = "SHA-256withDSA"; + algorithms["SHA-256/DSA"] = "SHA-256withDSA"; + algorithms["SHA256WITHDSA"] = "SHA-256withDSA"; + algorithms["SHA-256WITHDSA"] = "SHA-256withDSA"; + algorithms[NistObjectIdentifiers.DsaWithSha256.Id] = "SHA-256withDSA"; + + algorithms["DSAWITHSHA384"] = "SHA-384withDSA"; + algorithms["DSAWITHSHA-384"] = "SHA-384withDSA"; + algorithms["SHA384/DSA"] = "SHA-384withDSA"; + algorithms["SHA-384/DSA"] = "SHA-384withDSA"; + algorithms["SHA384WITHDSA"] = "SHA-384withDSA"; + algorithms["SHA-384WITHDSA"] = "SHA-384withDSA"; + algorithms[NistObjectIdentifiers.DsaWithSha384.Id] = "SHA-384withDSA"; + + algorithms["DSAWITHSHA512"] = "SHA-512withDSA"; + algorithms["DSAWITHSHA-512"] = "SHA-512withDSA"; + algorithms["SHA512/DSA"] = "SHA-512withDSA"; + algorithms["SHA-512/DSA"] = "SHA-512withDSA"; + algorithms["SHA512WITHDSA"] = "SHA-512withDSA"; + algorithms["SHA-512WITHDSA"] = "SHA-512withDSA"; + algorithms[NistObjectIdentifiers.DsaWithSha512.Id] = "SHA-512withDSA"; + + algorithms["NONEWITHECDSA"] = "NONEwithECDSA"; + algorithms["ECDSAWITHNONE"] = "NONEwithECDSA"; + + algorithms["ECDSA"] = "SHA-1withECDSA"; + algorithms["SHA1/ECDSA"] = "SHA-1withECDSA"; + algorithms["SHA-1/ECDSA"] = "SHA-1withECDSA"; + algorithms["ECDSAWITHSHA1"] = "SHA-1withECDSA"; + algorithms["ECDSAWITHSHA-1"] = "SHA-1withECDSA"; + algorithms["SHA1WITHECDSA"] = "SHA-1withECDSA"; + algorithms["SHA-1WITHECDSA"] = "SHA-1withECDSA"; + algorithms[X9ObjectIdentifiers.ECDsaWithSha1.Id] = "SHA-1withECDSA"; + algorithms[TeleTrusTObjectIdentifiers.ECSignWithSha1.Id] = "SHA-1withECDSA"; + + algorithms["SHA224/ECDSA"] = "SHA-224withECDSA"; + algorithms["SHA-224/ECDSA"] = "SHA-224withECDSA"; + algorithms["ECDSAWITHSHA224"] = "SHA-224withECDSA"; + algorithms["ECDSAWITHSHA-224"] = "SHA-224withECDSA"; + algorithms["SHA224WITHECDSA"] = "SHA-224withECDSA"; + algorithms["SHA-224WITHECDSA"] = "SHA-224withECDSA"; + algorithms[X9ObjectIdentifiers.ECDsaWithSha224.Id] = "SHA-224withECDSA"; + + algorithms["SHA256/ECDSA"] = "SHA-256withECDSA"; + algorithms["SHA-256/ECDSA"] = "SHA-256withECDSA"; + algorithms["ECDSAWITHSHA256"] = "SHA-256withECDSA"; + algorithms["ECDSAWITHSHA-256"] = "SHA-256withECDSA"; + algorithms["SHA256WITHECDSA"] = "SHA-256withECDSA"; + algorithms["SHA-256WITHECDSA"] = "SHA-256withECDSA"; + algorithms[X9ObjectIdentifiers.ECDsaWithSha256.Id] = "SHA-256withECDSA"; + + algorithms["SHA384/ECDSA"] = "SHA-384withECDSA"; + algorithms["SHA-384/ECDSA"] = "SHA-384withECDSA"; + algorithms["ECDSAWITHSHA384"] = "SHA-384withECDSA"; + algorithms["ECDSAWITHSHA-384"] = "SHA-384withECDSA"; + algorithms["SHA384WITHECDSA"] = "SHA-384withECDSA"; + algorithms["SHA-384WITHECDSA"] = "SHA-384withECDSA"; + algorithms[X9ObjectIdentifiers.ECDsaWithSha384.Id] = "SHA-384withECDSA"; + + algorithms["SHA512/ECDSA"] = "SHA-512withECDSA"; + algorithms["SHA-512/ECDSA"] = "SHA-512withECDSA"; + algorithms["ECDSAWITHSHA512"] = "SHA-512withECDSA"; + algorithms["ECDSAWITHSHA-512"] = "SHA-512withECDSA"; + algorithms["SHA512WITHECDSA"] = "SHA-512withECDSA"; + algorithms["SHA-512WITHECDSA"] = "SHA-512withECDSA"; + algorithms[X9ObjectIdentifiers.ECDsaWithSha512.Id] = "SHA-512withECDSA"; + + algorithms["RIPEMD160/ECDSA"] = "RIPEMD160withECDSA"; + algorithms["ECDSAWITHRIPEMD160"] = "RIPEMD160withECDSA"; + algorithms["RIPEMD160WITHECDSA"] = "RIPEMD160withECDSA"; + algorithms[TeleTrusTObjectIdentifiers.ECSignWithRipeMD160.Id] = "RIPEMD160withECDSA"; + + algorithms["NONEWITHCVC-ECDSA"] = "NONEwithCVC-ECDSA"; + algorithms["CVC-ECDSAWITHNONE"] = "NONEwithCVC-ECDSA"; + + algorithms["SHA1/CVC-ECDSA"] = "SHA-1withCVC-ECDSA"; + algorithms["SHA-1/CVC-ECDSA"] = "SHA-1withCVC-ECDSA"; + algorithms["CVC-ECDSAWITHSHA1"] = "SHA-1withCVC-ECDSA"; + algorithms["CVC-ECDSAWITHSHA-1"] = "SHA-1withCVC-ECDSA"; + algorithms["SHA1WITHCVC-ECDSA"] = "SHA-1withCVC-ECDSA"; + algorithms["SHA-1WITHCVC-ECDSA"] = "SHA-1withCVC-ECDSA"; + algorithms[EacObjectIdentifiers.id_TA_ECDSA_SHA_1.Id] = "SHA-1withCVC-ECDSA"; + + algorithms["SHA224/CVC-ECDSA"] = "SHA-224withCVC-ECDSA"; + algorithms["SHA-224/CVC-ECDSA"] = "SHA-224withCVC-ECDSA"; + algorithms["CVC-ECDSAWITHSHA224"] = "SHA-224withCVC-ECDSA"; + algorithms["CVC-ECDSAWITHSHA-224"] = "SHA-224withCVC-ECDSA"; + algorithms["SHA224WITHCVC-ECDSA"] = "SHA-224withCVC-ECDSA"; + algorithms["SHA-224WITHCVC-ECDSA"] = "SHA-224withCVC-ECDSA"; + algorithms[EacObjectIdentifiers.id_TA_ECDSA_SHA_224.Id] = "SHA-224withCVC-ECDSA"; + + algorithms["SHA256/CVC-ECDSA"] = "SHA-256withCVC-ECDSA"; + algorithms["SHA-256/CVC-ECDSA"] = "SHA-256withCVC-ECDSA"; + algorithms["CVC-ECDSAWITHSHA256"] = "SHA-256withCVC-ECDSA"; + algorithms["CVC-ECDSAWITHSHA-256"] = "SHA-256withCVC-ECDSA"; + algorithms["SHA256WITHCVC-ECDSA"] = "SHA-256withCVC-ECDSA"; + algorithms["SHA-256WITHCVC-ECDSA"] = "SHA-256withCVC-ECDSA"; + algorithms[EacObjectIdentifiers.id_TA_ECDSA_SHA_256.Id] = "SHA-256withCVC-ECDSA"; + + algorithms["SHA384/CVC-ECDSA"] = "SHA-384withCVC-ECDSA"; + algorithms["SHA-384/CVC-ECDSA"] = "SHA-384withCVC-ECDSA"; + algorithms["CVC-ECDSAWITHSHA384"] = "SHA-384withCVC-ECDSA"; + algorithms["CVC-ECDSAWITHSHA-384"] = "SHA-384withCVC-ECDSA"; + algorithms["SHA384WITHCVC-ECDSA"] = "SHA-384withCVC-ECDSA"; + algorithms["SHA-384WITHCVC-ECDSA"] = "SHA-384withCVC-ECDSA"; + algorithms[EacObjectIdentifiers.id_TA_ECDSA_SHA_384.Id] = "SHA-384withCVC-ECDSA"; + + algorithms["SHA512/CVC-ECDSA"] = "SHA-512withCVC-ECDSA"; + algorithms["SHA-512/CVC-ECDSA"] = "SHA-512withCVC-ECDSA"; + algorithms["CVC-ECDSAWITHSHA512"] = "SHA-512withCVC-ECDSA"; + algorithms["CVC-ECDSAWITHSHA-512"] = "SHA-512withCVC-ECDSA"; + algorithms["SHA512WITHCVC-ECDSA"] = "SHA-512withCVC-ECDSA"; + algorithms["SHA-512WITHCVC-ECDSA"] = "SHA-512withCVC-ECDSA"; + algorithms[EacObjectIdentifiers.id_TA_ECDSA_SHA_512.Id] = "SHA-512withCVC-ECDSA"; + + algorithms["NONEWITHPLAIN-ECDSA"] = "NONEwithPLAIN-ECDSA"; + algorithms["PLAIN-ECDSAWITHNONE"] = "NONEwithPLAIN-ECDSA"; + + algorithms["SHA1/PLAIN-ECDSA"] = "SHA-1withPLAIN-ECDSA"; + algorithms["SHA-1/PLAIN-ECDSA"] = "SHA-1withPLAIN-ECDSA"; + algorithms["PLAIN-ECDSAWITHSHA1"] = "SHA-1withPLAIN-ECDSA"; + algorithms["PLAIN-ECDSAWITHSHA-1"] = "SHA-1withPLAIN-ECDSA"; + algorithms["SHA1WITHPLAIN-ECDSA"] = "SHA-1withPLAIN-ECDSA"; + algorithms["SHA-1WITHPLAIN-ECDSA"] = "SHA-1withPLAIN-ECDSA"; + algorithms[BsiObjectIdentifiers.ecdsa_plain_SHA1.Id] = "SHA-1withPLAIN-ECDSA"; + + algorithms["SHA224/PLAIN-ECDSA"] = "SHA-224withPLAIN-ECDSA"; + algorithms["SHA-224/PLAIN-ECDSA"] = "SHA-224withPLAIN-ECDSA"; + algorithms["PLAIN-ECDSAWITHSHA224"] = "SHA-224withPLAIN-ECDSA"; + algorithms["PLAIN-ECDSAWITHSHA-224"] = "SHA-224withPLAIN-ECDSA"; + algorithms["SHA224WITHPLAIN-ECDSA"] = "SHA-224withPLAIN-ECDSA"; + algorithms["SHA-224WITHPLAIN-ECDSA"] = "SHA-224withPLAIN-ECDSA"; + algorithms[BsiObjectIdentifiers.ecdsa_plain_SHA224.Id] = "SHA-224withPLAIN-ECDSA"; + + algorithms["SHA256/PLAIN-ECDSA"] = "SHA-256withPLAIN-ECDSA"; + algorithms["SHA-256/PLAIN-ECDSA"] = "SHA-256withPLAIN-ECDSA"; + algorithms["PLAIN-ECDSAWITHSHA256"] = "SHA-256withPLAIN-ECDSA"; + algorithms["PLAIN-ECDSAWITHSHA-256"] = "SHA-256withPLAIN-ECDSA"; + algorithms["SHA256WITHPLAIN-ECDSA"] = "SHA-256withPLAIN-ECDSA"; + algorithms["SHA-256WITHPLAIN-ECDSA"] = "SHA-256withPLAIN-ECDSA"; + algorithms[BsiObjectIdentifiers.ecdsa_plain_SHA256.Id] = "SHA-256withPLAIN-ECDSA"; + + algorithms["SHA384/PLAIN-ECDSA"] = "SHA-384withPLAIN-ECDSA"; + algorithms["SHA-384/PLAIN-ECDSA"] = "SHA-384withPLAIN-ECDSA"; + algorithms["PLAIN-ECDSAWITHSHA384"] = "SHA-384withPLAIN-ECDSA"; + algorithms["PLAIN-ECDSAWITHSHA-384"] = "SHA-384withPLAIN-ECDSA"; + algorithms["SHA384WITHPLAIN-ECDSA"] = "SHA-384withPLAIN-ECDSA"; + algorithms["SHA-384WITHPLAIN-ECDSA"] = "SHA-384withPLAIN-ECDSA"; + algorithms[BsiObjectIdentifiers.ecdsa_plain_SHA384.Id] = "SHA-384withPLAIN-ECDSA"; + + algorithms["SHA512/PLAIN-ECDSA"] = "SHA-512withPLAIN-ECDSA"; + algorithms["SHA-512/PLAIN-ECDSA"] = "SHA-512withPLAIN-ECDSA"; + algorithms["PLAIN-ECDSAWITHSHA512"] = "SHA-512withPLAIN-ECDSA"; + algorithms["PLAIN-ECDSAWITHSHA-512"] = "SHA-512withPLAIN-ECDSA"; + algorithms["SHA512WITHPLAIN-ECDSA"] = "SHA-512withPLAIN-ECDSA"; + algorithms["SHA-512WITHPLAIN-ECDSA"] = "SHA-512withPLAIN-ECDSA"; + algorithms[BsiObjectIdentifiers.ecdsa_plain_SHA512.Id] = "SHA-512withPLAIN-ECDSA"; + + algorithms["RIPEMD160/PLAIN-ECDSA"] = "RIPEMD160withPLAIN-ECDSA"; + algorithms["PLAIN-ECDSAWITHRIPEMD160"] = "RIPEMD160withPLAIN-ECDSA"; + algorithms["RIPEMD160WITHPLAIN-ECDSA"] = "RIPEMD160withPLAIN-ECDSA"; + algorithms[BsiObjectIdentifiers.ecdsa_plain_RIPEMD160.Id] = "RIPEMD160withPLAIN-ECDSA"; + + algorithms["SHA1WITHECNR"] = "SHA-1withECNR"; + algorithms["SHA-1WITHECNR"] = "SHA-1withECNR"; + algorithms["SHA224WITHECNR"] = "SHA-224withECNR"; + algorithms["SHA-224WITHECNR"] = "SHA-224withECNR"; + algorithms["SHA256WITHECNR"] = "SHA-256withECNR"; + algorithms["SHA-256WITHECNR"] = "SHA-256withECNR"; + algorithms["SHA384WITHECNR"] = "SHA-384withECNR"; + algorithms["SHA-384WITHECNR"] = "SHA-384withECNR"; + algorithms["SHA512WITHECNR"] = "SHA-512withECNR"; + algorithms["SHA-512WITHECNR"] = "SHA-512withECNR"; + + algorithms["GOST-3410"] = "GOST3410"; + algorithms["GOST-3410-94"] = "GOST3410"; + algorithms["GOST3411WITHGOST3410"] = "GOST3410"; + algorithms[CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94.Id] = "GOST3410"; + + algorithms["ECGOST-3410"] = "ECGOST3410"; + algorithms["ECGOST-3410-2001"] = "ECGOST3410"; + algorithms["GOST3411WITHECGOST3410"] = "ECGOST3410"; + algorithms[CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001.Id] = "ECGOST3410"; + + algorithms["ED25519"] = "Ed25519"; + algorithms[EdECObjectIdentifiers.id_Ed25519.Id] = "Ed25519"; + algorithms["ED25519CTX"] = "Ed25519ctx"; + algorithms["ED25519PH"] = "Ed25519ph"; + algorithms["ED448"] = "Ed448"; + algorithms[EdECObjectIdentifiers.id_Ed448.Id] = "Ed448"; + algorithms["ED448PH"] = "Ed448ph"; + + algorithms["SHA256WITHSM2"] = "SHA256withSM2"; + algorithms[GMObjectIdentifiers.sm2sign_with_sha256.Id] = "SHA256withSM2"; + algorithms["SM3WITHSM2"] = "SM3withSM2"; + algorithms[GMObjectIdentifiers.sm2sign_with_sm3.Id] = "SM3withSM2"; + + oids["MD2withRSA"] = PkcsObjectIdentifiers.MD2WithRsaEncryption; + oids["MD4withRSA"] = PkcsObjectIdentifiers.MD4WithRsaEncryption; + oids["MD5withRSA"] = PkcsObjectIdentifiers.MD5WithRsaEncryption; + + oids["SHA-1withRSA"] = PkcsObjectIdentifiers.Sha1WithRsaEncryption; + oids["SHA-224withRSA"] = PkcsObjectIdentifiers.Sha224WithRsaEncryption; + oids["SHA-256withRSA"] = PkcsObjectIdentifiers.Sha256WithRsaEncryption; + oids["SHA-384withRSA"] = PkcsObjectIdentifiers.Sha384WithRsaEncryption; + oids["SHA-512withRSA"] = PkcsObjectIdentifiers.Sha512WithRsaEncryption; + oids["SHA-512(224)withRSA"] = PkcsObjectIdentifiers.Sha512_224WithRSAEncryption; + oids["SHA-512(256)withRSA"] = PkcsObjectIdentifiers.Sha512_256WithRSAEncryption; + oids["SHA3-224withRSA"] = NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_224; + oids["SHA3-256withRSA"] = NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_256; + oids["SHA3-384withRSA"] = NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_384; + oids["SHA3-512withRSA"] = NistObjectIdentifiers.IdRsassaPkcs1V15WithSha3_512; + + oids["PSSwithRSA"] = PkcsObjectIdentifiers.IdRsassaPss; + oids["SHA-1withRSAandMGF1"] = PkcsObjectIdentifiers.IdRsassaPss; + oids["SHA-224withRSAandMGF1"] = PkcsObjectIdentifiers.IdRsassaPss; + oids["SHA-256withRSAandMGF1"] = PkcsObjectIdentifiers.IdRsassaPss; + oids["SHA-384withRSAandMGF1"] = PkcsObjectIdentifiers.IdRsassaPss; + oids["SHA-512withRSAandMGF1"] = PkcsObjectIdentifiers.IdRsassaPss; + + oids["RIPEMD128withRSA"] = TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128; + oids["RIPEMD160withRSA"] = TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160; + oids["RIPEMD256withRSA"] = TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256; + + oids["SHA-1withDSA"] = X9ObjectIdentifiers.IdDsaWithSha1; + + oids["SHA-1withECDSA"] = X9ObjectIdentifiers.ECDsaWithSha1; + oids["SHA-224withECDSA"] = X9ObjectIdentifiers.ECDsaWithSha224; + oids["SHA-256withECDSA"] = X9ObjectIdentifiers.ECDsaWithSha256; + oids["SHA-384withECDSA"] = X9ObjectIdentifiers.ECDsaWithSha384; + oids["SHA-512withECDSA"] = X9ObjectIdentifiers.ECDsaWithSha512; + oids["RIPEMD160withECDSA"] = TeleTrusTObjectIdentifiers.ECSignWithRipeMD160; + + oids["SHA-1withCVC-ECDSA"] = EacObjectIdentifiers.id_TA_ECDSA_SHA_1; + oids["SHA-224withCVC-ECDSA"] = EacObjectIdentifiers.id_TA_ECDSA_SHA_224; + oids["SHA-256withCVC-ECDSA"] = EacObjectIdentifiers.id_TA_ECDSA_SHA_256; + oids["SHA-384withCVC-ECDSA"] = EacObjectIdentifiers.id_TA_ECDSA_SHA_384; + oids["SHA-512withCVC-ECDSA"] = EacObjectIdentifiers.id_TA_ECDSA_SHA_512; + + oids["SHA-1withPLAIN-ECDSA"] = BsiObjectIdentifiers.ecdsa_plain_SHA1; + oids["SHA-224withPLAIN-ECDSA"] = BsiObjectIdentifiers.ecdsa_plain_SHA224; + oids["SHA-256withPLAIN-ECDSA"] = BsiObjectIdentifiers.ecdsa_plain_SHA256; + oids["SHA-384withPLAIN-ECDSA"] = BsiObjectIdentifiers.ecdsa_plain_SHA384; + oids["SHA-512withPLAIN-ECDSA"] = BsiObjectIdentifiers.ecdsa_plain_SHA512; + oids["RIPEMD160withPLAIN-ECDSA"] = BsiObjectIdentifiers.ecdsa_plain_RIPEMD160; + + oids["GOST3410"] = CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94; + oids["ECGOST3410"] = CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001; + + oids["Ed25519"] = EdECObjectIdentifiers.id_Ed25519; + oids["Ed448"] = EdECObjectIdentifiers.id_Ed448; + + oids["SHA256withSM2"] = GMObjectIdentifiers.sm2sign_with_sha256; + oids["SM3withSM2"] = GMObjectIdentifiers.sm2sign_with_sm3; + } + + /// + /// Returns an ObjectIdentifier for a given encoding. + /// + /// A string representation of the encoding. + /// A DerObjectIdentifier, null if the OID is not available. + // TODO Don't really want to support this + public static DerObjectIdentifier GetObjectIdentifier( + string mechanism) + { + if (mechanism == null) + throw new ArgumentNullException("mechanism"); + + mechanism = Platform.ToUpperInvariant(mechanism); + string aliased = (string) algorithms[mechanism]; + + if (aliased != null) + mechanism = aliased; + + return (DerObjectIdentifier) oids[mechanism]; + } + + public static ICollection Algorithms + { + get { return oids.Keys; } + } + + public static Asn1Encodable GetDefaultX509Parameters( + DerObjectIdentifier id) + { + return GetDefaultX509Parameters(id.Id); + } + + public static Asn1Encodable GetDefaultX509Parameters( + string algorithm) + { + if (algorithm == null) + throw new ArgumentNullException("algorithm"); + + algorithm = Platform.ToUpperInvariant(algorithm); + + string mechanism = (string) algorithms[algorithm]; + + if (mechanism == null) + mechanism = algorithm; + + if (mechanism == "PSSwithRSA") + { + // TODO The Sha1Digest here is a default. In JCE version, the actual digest + // to be used can be overridden by subsequent parameter settings. + return GetPssX509Parameters("SHA-1"); + } + + if (Platform.EndsWith(mechanism, "withRSAandMGF1")) + { + string digestName = mechanism.Substring(0, mechanism.Length - "withRSAandMGF1".Length); + return GetPssX509Parameters(digestName); + } + + return DerNull.Instance; + } + + private static Asn1Encodable GetPssX509Parameters( + string digestName) + { + AlgorithmIdentifier hashAlgorithm = new AlgorithmIdentifier( + DigestUtilities.GetObjectIdentifier(digestName), DerNull.Instance); + + // TODO Is it possible for the MGF hash alg to be different from the PSS one? + AlgorithmIdentifier maskGenAlgorithm = new AlgorithmIdentifier( + PkcsObjectIdentifiers.IdMgf1, hashAlgorithm); + + int saltLen = DigestUtilities.GetDigest(digestName).GetDigestSize(); + return new RsassaPssParameters(hashAlgorithm, maskGenAlgorithm, + new DerInteger(saltLen), new DerInteger(1)); + } + + public static ISigner GetSigner( + DerObjectIdentifier id) + { + return GetSigner(id.Id); + } + + public static ISigner GetSigner( + string algorithm) + { + if (algorithm == null) + throw new ArgumentNullException("algorithm"); + + algorithm = Platform.ToUpperInvariant(algorithm); + + string mechanism = (string) algorithms[algorithm]; + + if (mechanism == null) + mechanism = algorithm; + + if (Platform.StartsWith(mechanism, "Ed")) + { + if (mechanism.Equals("Ed25519")) + { + return new Ed25519Signer(); + } + if (mechanism.Equals("Ed25519ctx")) + { + return new Ed25519ctxSigner(Arrays.EmptyBytes); + } + if (mechanism.Equals("Ed25519ph")) + { + return new Ed25519phSigner(Arrays.EmptyBytes); + } + if (mechanism.Equals("Ed448")) + { + return new Ed448Signer(Arrays.EmptyBytes); + } + if (mechanism.Equals("Ed448ph")) + { + return new Ed448phSigner(Arrays.EmptyBytes); + } + } + + if (mechanism.Equals("RSA")) + { + return (new RsaDigestSigner(new NullDigest(), (AlgorithmIdentifier)null)); + } + if (mechanism.Equals("RAWRSASSA-PSS")) + { + // TODO Add support for other parameter settings + return PssSigner.CreateRawSigner(new RsaBlindedEngine(), new Sha1Digest()); + } + if (mechanism.Equals("PSSwithRSA")) + { + // TODO The Sha1Digest here is a default. In JCE version, the actual digest + // to be used can be overridden by subsequent parameter settings. + return new PssSigner(new RsaBlindedEngine(), new Sha1Digest()); + } + if (Platform.EndsWith(mechanism, "withRSA")) + { + string digestName = mechanism.Substring(0, mechanism.LastIndexOf("with")); + IDigest digest = DigestUtilities.GetDigest(digestName); + return new RsaDigestSigner(digest); + } + if (Platform.EndsWith(mechanism, "withRSAandMGF1")) + { + string digestName = mechanism.Substring(0, mechanism.LastIndexOf("with")); + IDigest digest = DigestUtilities.GetDigest(digestName); + return new PssSigner(new RsaBlindedEngine(), digest); + } + + if (Platform.EndsWith(mechanism, "withDSA")) + { + string digestName = mechanism.Substring(0, mechanism.LastIndexOf("with")); + IDigest digest = DigestUtilities.GetDigest(digestName); + return new DsaDigestSigner(new DsaSigner(), digest); + } + + if (Platform.EndsWith(mechanism, "withECDSA")) + { + string digestName = mechanism.Substring(0, mechanism.LastIndexOf("with")); + IDigest digest = DigestUtilities.GetDigest(digestName); + return new DsaDigestSigner(new ECDsaSigner(), digest); + } + + if (Platform.EndsWith(mechanism, "withCVC-ECDSA") + || Platform.EndsWith(mechanism, "withPLAIN-ECDSA")) + { + string digestName = mechanism.Substring(0, mechanism.LastIndexOf("with")); + IDigest digest = DigestUtilities.GetDigest(digestName); + return new DsaDigestSigner(new ECDsaSigner(), digest, PlainDsaEncoding.Instance); + } + + if (Platform.EndsWith(mechanism, "withECNR")) + { + string digestName = mechanism.Substring(0, mechanism.LastIndexOf("with")); + IDigest digest = DigestUtilities.GetDigest(digestName); + return new DsaDigestSigner(new ECNRSigner(), digest); + } + + if (Platform.EndsWith(mechanism, "withSM2")) + { + string digestName = mechanism.Substring(0, mechanism.LastIndexOf("with")); + IDigest digest = DigestUtilities.GetDigest(digestName); + return new SM2Signer(digest); + } + + if (mechanism.Equals("GOST3410")) + { + return new Gost3410DigestSigner(new Gost3410Signer(), new Gost3411Digest()); + } + if (mechanism.Equals("ECGOST3410")) + { + return new Gost3410DigestSigner(new ECGost3410Signer(), new Gost3411Digest()); + } + + if (mechanism.Equals("SHA1WITHRSA/ISO9796-2")) + { + return new Iso9796d2Signer(new RsaBlindedEngine(), new Sha1Digest(), true); + } + if (mechanism.Equals("MD5WITHRSA/ISO9796-2")) + { + return new Iso9796d2Signer(new RsaBlindedEngine(), new MD5Digest(), true); + } + if (mechanism.Equals("RIPEMD160WITHRSA/ISO9796-2")) + { + return new Iso9796d2Signer(new RsaBlindedEngine(), new RipeMD160Digest(), true); + } + + if (Platform.EndsWith(mechanism, "/X9.31")) + { + string x931 = mechanism.Substring(0, mechanism.Length - "/X9.31".Length); + int withPos = Platform.IndexOf(x931, "WITH"); + if (withPos > 0) + { + int endPos = withPos + "WITH".Length; + + string digestName = x931.Substring(0, withPos); + IDigest digest = DigestUtilities.GetDigest(digestName); + + string cipherName = x931.Substring(endPos, x931.Length - endPos); + if (cipherName.Equals("RSA")) + { + IAsymmetricBlockCipher cipher = new RsaBlindedEngine(); + return new X931Signer(cipher, digest); + } + } + } + + throw new SecurityUtilityException("Signer " + algorithm + " not recognised."); + } + + public static string GetEncodingName( + DerObjectIdentifier oid) + { + return (string) algorithms[oid.Id]; + } + + public static ISigner InitSigner(DerObjectIdentifier algorithmOid, bool forSigning, AsymmetricKeyParameter privateKey, SecureRandom random) + { + return InitSigner(algorithmOid.Id, forSigning, privateKey, random); + } + + public static ISigner InitSigner(string algorithm, bool forSigning, AsymmetricKeyParameter privateKey, SecureRandom random) + { + ISigner signer = SignerUtilities.GetSigner(algorithm); + signer.Init(forSigning, ParameterUtilities.WithRandom(privateKey, random)); + return signer; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/SignerUtilities.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/SignerUtilities.cs.meta new file mode 100644 index 0000000..e9c05f4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/SignerUtilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d0df8ac453a556640abf3324bfb105f5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/WrapperUtilities.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/WrapperUtilities.cs new file mode 100644 index 0000000..c576320 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/WrapperUtilities.cs @@ -0,0 +1,153 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Kisa; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Ntt; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Security +{ + /// + /// Utility class for creating IWrapper objects from their names/Oids + /// + public sealed class WrapperUtilities + { + private enum WrapAlgorithm { AESWRAP, CAMELLIAWRAP, DESEDEWRAP, RC2WRAP, SEEDWRAP, + DESEDERFC3211WRAP, AESRFC3211WRAP, CAMELLIARFC3211WRAP }; + + private WrapperUtilities() + { + } + + private static readonly IDictionary algorithms = Platform.CreateHashtable(); + //private static readonly IDictionary oids = Platform.CreateHashtable(); + + static WrapperUtilities() + { + // Signal to obfuscation tools not to change enum constants + ((WrapAlgorithm)Enums.GetArbitraryValue(typeof(WrapAlgorithm))).ToString(); + + algorithms[NistObjectIdentifiers.IdAes128Wrap.Id] = "AESWRAP"; + algorithms[NistObjectIdentifiers.IdAes192Wrap.Id] = "AESWRAP"; + algorithms[NistObjectIdentifiers.IdAes256Wrap.Id] = "AESWRAP"; + + algorithms[NttObjectIdentifiers.IdCamellia128Wrap.Id] = "CAMELLIAWRAP"; + algorithms[NttObjectIdentifiers.IdCamellia192Wrap.Id] = "CAMELLIAWRAP"; + algorithms[NttObjectIdentifiers.IdCamellia256Wrap.Id] = "CAMELLIAWRAP"; + + algorithms[PkcsObjectIdentifiers.IdAlgCms3DesWrap.Id] = "DESEDEWRAP"; + algorithms["TDEAWRAP"] = "DESEDEWRAP"; + + algorithms[PkcsObjectIdentifiers.IdAlgCmsRC2Wrap.Id] = "RC2WRAP"; + + algorithms[KisaObjectIdentifiers.IdNpkiAppCmsSeedWrap.Id] = "SEEDWRAP"; + } + + public static IWrapper GetWrapper( + DerObjectIdentifier oid) + { + return GetWrapper(oid.Id); + } + + public static IWrapper GetWrapper( + string algorithm) + { + string upper = Platform.ToUpperInvariant(algorithm); + string mechanism = (string)algorithms[upper]; + + if (mechanism == null) + { + mechanism = upper; + } + + try + { + WrapAlgorithm wrapAlgorithm = (WrapAlgorithm)Enums.GetEnumValue( + typeof(WrapAlgorithm), mechanism); + + switch (wrapAlgorithm) + { + case WrapAlgorithm.AESWRAP: return new AesWrapEngine(); + case WrapAlgorithm.CAMELLIAWRAP: return new CamelliaWrapEngine(); + case WrapAlgorithm.DESEDEWRAP: return new DesEdeWrapEngine(); + case WrapAlgorithm.RC2WRAP: return new RC2WrapEngine(); + case WrapAlgorithm.SEEDWRAP: return new SeedWrapEngine(); + case WrapAlgorithm.DESEDERFC3211WRAP: return new Rfc3211WrapEngine(new DesEdeEngine()); + case WrapAlgorithm.AESRFC3211WRAP: return new Rfc3211WrapEngine(new AesEngine()); + case WrapAlgorithm.CAMELLIARFC3211WRAP: return new Rfc3211WrapEngine(new CamelliaEngine()); + } + } + catch (ArgumentException) + { + } + + // Create an IBufferedCipher and use it as IWrapper (via BufferedCipherWrapper) + IBufferedCipher blockCipher = CipherUtilities.GetCipher(algorithm); + + if (blockCipher != null) + return new BufferedCipherWrapper(blockCipher); + + throw new SecurityUtilityException("Wrapper " + algorithm + " not recognised."); + } + + public static string GetAlgorithmName( + DerObjectIdentifier oid) + { + return (string) algorithms[oid.Id]; + } + + private class BufferedCipherWrapper + : IWrapper + { + private readonly IBufferedCipher cipher; + private bool forWrapping; + + public BufferedCipherWrapper( + IBufferedCipher cipher) + { + this.cipher = cipher; + } + + public string AlgorithmName + { + get { return cipher.AlgorithmName; } + } + + public void Init( + bool forWrapping, + ICipherParameters parameters) + { + this.forWrapping = forWrapping; + + cipher.Init(forWrapping, parameters); + } + + public byte[] Wrap( + byte[] input, + int inOff, + int length) + { + if (!forWrapping) + throw new InvalidOperationException("Not initialised for wrapping"); + + return cipher.DoFinal(input, inOff, length); + } + + public byte[] Unwrap( + byte[] input, + int inOff, + int length) + { + if (forWrapping) + throw new InvalidOperationException("Not initialised for unwrapping"); + + return cipher.DoFinal(input, inOff, length); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/WrapperUtilities.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/WrapperUtilities.cs.meta new file mode 100644 index 0000000..7026994 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/WrapperUtilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 16f4194afd6c7df49be4041e447557e6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/cert.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/cert.meta new file mode 100644 index 0000000..104f141 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/cert.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4e4b6ef673ea2914cb4713d9b1e53586 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/cert/CertificateEncodingException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/cert/CertificateEncodingException.cs new file mode 100644 index 0000000..ab9024f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/cert/CertificateEncodingException.cs @@ -0,0 +1,14 @@ +using System; + +namespace Org.BouncyCastle.Security.Certificates +{ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE) + [Serializable] +#endif + public class CertificateEncodingException : CertificateException + { + public CertificateEncodingException() : base() { } + public CertificateEncodingException(string msg) : base(msg) { } + public CertificateEncodingException(string msg, Exception e) : base(msg, e) { } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/cert/CertificateEncodingException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/cert/CertificateEncodingException.cs.meta new file mode 100644 index 0000000..ca6a9c2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/cert/CertificateEncodingException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c594be542f05da44b86d40bdadc3e5d9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/cert/CertificateException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/cert/CertificateException.cs new file mode 100644 index 0000000..4bbaccf --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/cert/CertificateException.cs @@ -0,0 +1,14 @@ +using System; + +namespace Org.BouncyCastle.Security.Certificates +{ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE) + [Serializable] +#endif + public class CertificateException : GeneralSecurityException + { + public CertificateException() : base() { } + public CertificateException(string message) : base(message) { } + public CertificateException(string message, Exception exception) : base(message, exception) { } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/cert/CertificateException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/cert/CertificateException.cs.meta new file mode 100644 index 0000000..46c84e4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/cert/CertificateException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f3b0b33128896de49bf32cd87f9860e7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/cert/CertificateExpiredException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/cert/CertificateExpiredException.cs new file mode 100644 index 0000000..864fb85 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/cert/CertificateExpiredException.cs @@ -0,0 +1,14 @@ +using System; + +namespace Org.BouncyCastle.Security.Certificates +{ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE) + [Serializable] +#endif + public class CertificateExpiredException : CertificateException + { + public CertificateExpiredException() : base() { } + public CertificateExpiredException(string message) : base(message) { } + public CertificateExpiredException(string message, Exception exception) : base(message, exception) { } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/cert/CertificateExpiredException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/cert/CertificateExpiredException.cs.meta new file mode 100644 index 0000000..4605fd1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/cert/CertificateExpiredException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 86dd5f9dbf8384a4b965fe37f87ec334 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/cert/CertificateNotYetValidException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/cert/CertificateNotYetValidException.cs new file mode 100644 index 0000000..02112be --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/cert/CertificateNotYetValidException.cs @@ -0,0 +1,14 @@ +using System; + +namespace Org.BouncyCastle.Security.Certificates +{ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE) + [Serializable] +#endif + public class CertificateNotYetValidException : CertificateException + { + public CertificateNotYetValidException() : base() { } + public CertificateNotYetValidException(string message) : base(message) { } + public CertificateNotYetValidException(string message, Exception exception) : base(message, exception) { } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/cert/CertificateNotYetValidException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/cert/CertificateNotYetValidException.cs.meta new file mode 100644 index 0000000..195e781 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/cert/CertificateNotYetValidException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 48630a69994e6254ba87d35f6de7234a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/cert/CertificateParsingException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/cert/CertificateParsingException.cs new file mode 100644 index 0000000..ae909ca --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/cert/CertificateParsingException.cs @@ -0,0 +1,14 @@ +using System; + +namespace Org.BouncyCastle.Security.Certificates +{ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE) + [Serializable] +#endif + public class CertificateParsingException : CertificateException + { + public CertificateParsingException() : base() { } + public CertificateParsingException(string message) : base(message) { } + public CertificateParsingException(string message, Exception exception) : base(message, exception) { } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/cert/CertificateParsingException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/cert/CertificateParsingException.cs.meta new file mode 100644 index 0000000..5330d30 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/cert/CertificateParsingException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 856f40cbacde9fe449f1dd0164500a4f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/cert/CrlException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/cert/CrlException.cs new file mode 100644 index 0000000..fe9807e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/cert/CrlException.cs @@ -0,0 +1,14 @@ +using System; + +namespace Org.BouncyCastle.Security.Certificates +{ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE) + [Serializable] +#endif + public class CrlException : GeneralSecurityException + { + public CrlException() : base() { } + public CrlException(string msg) : base(msg) {} + public CrlException(string msg, Exception e) : base(msg, e) {} + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/cert/CrlException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/cert/CrlException.cs.meta new file mode 100644 index 0000000..69b8235 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/security/cert/CrlException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4dd2d682dfe30564e9b54fc438e76e3e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls.meta new file mode 100644 index 0000000..ff162da --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 82eeac877ac4c5844bd3b470be119358 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/AbstractTlsClient.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/AbstractTlsClient.cs new file mode 100644 index 0000000..d5e1925 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/AbstractTlsClient.cs @@ -0,0 +1,445 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Tls.Crypto; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls +{ + /// Base class for a TLS client. + public abstract class AbstractTlsClient + : AbstractTlsPeer, TlsClient + { + protected TlsClientContext m_context; + protected ProtocolVersion[] m_protocolVersions; + protected int[] m_cipherSuites; + + protected IList m_supportedGroups; + protected IList m_supportedSignatureAlgorithms; + protected IList m_supportedSignatureAlgorithmsCert; + + protected AbstractTlsClient(TlsCrypto crypto) + : base(crypto) + { + } + + /// + protected virtual bool AllowUnexpectedServerExtension(int extensionType, byte[] extensionData) + { + switch (extensionType) + { + case ExtensionType.supported_groups: + /* + * Exception added based on field reports that some servers do send this, although the + * Supported Elliptic Curves Extension is clearly intended to be client-only. If + * present, we still require that it is a valid EllipticCurveList. + */ + TlsExtensionsUtilities.ReadSupportedGroupsExtension(extensionData); + return true; + + case ExtensionType.ec_point_formats: + /* + * Exception added based on field reports that some servers send this even when they + * didn't negotiate an ECC cipher suite. If present, we still require that it is a valid + * ECPointFormatList. + */ + TlsExtensionsUtilities.ReadSupportedPointFormatsExtension(extensionData); + return true; + + default: + return false; + } + } + + protected virtual IList GetNamedGroupRoles() + { + IList namedGroupRoles = TlsUtilities.GetNamedGroupRoles(GetCipherSuites()); + IList sigAlgs = m_supportedSignatureAlgorithms, sigAlgsCert = m_supportedSignatureAlgorithmsCert; + + if ((null == sigAlgs || TlsUtilities.ContainsAnySignatureAlgorithm(sigAlgs, SignatureAlgorithm.ecdsa)) + || (null != sigAlgsCert + && TlsUtilities.ContainsAnySignatureAlgorithm(sigAlgsCert, SignatureAlgorithm.ecdsa))) + { + TlsUtilities.AddToSet(namedGroupRoles, NamedGroupRole.ecdsa); + } + + return namedGroupRoles; + } + + /// + protected virtual void CheckForUnexpectedServerExtension(IDictionary serverExtensions, int extensionType) + { + byte[] extensionData = TlsUtilities.GetExtensionData(serverExtensions, extensionType); + if (extensionData != null && !AllowUnexpectedServerExtension(extensionType, extensionData)) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + /// + public virtual TlsPskIdentity GetPskIdentity() + { + return null; + } + + /// + public virtual TlsSrpIdentity GetSrpIdentity() + { + return null; + } + + public virtual TlsDHGroupVerifier GetDHGroupVerifier() + { + return new DefaultTlsDHGroupVerifier(); + } + + public virtual TlsSrpConfigVerifier GetSrpConfigVerifier() + { + return new DefaultTlsSrpConfigVerifier(); + } + + protected virtual IList GetCertificateAuthorities() + { + return null; + } + + protected virtual IList GetProtocolNames() + { + return null; + } + + protected virtual CertificateStatusRequest GetCertificateStatusRequest() + { + return new CertificateStatusRequest(CertificateStatusType.ocsp, new OcspStatusRequest(null, null)); + } + + /// an of (or null). + protected virtual IList GetMultiCertStatusRequest() + { + return null; + } + + protected virtual IList GetSniServerNames() + { + return null; + } + + /// The default implementation calls this to determine which named + /// groups to include in the supported_groups extension for the ClientHello. + /// The named group roles for which there should + /// be at least one supported group. By default this is inferred from the offered cipher suites and signature + /// algorithms. + /// an of . See for group constants. + /// + protected virtual IList GetSupportedGroups(IList namedGroupRoles) + { + TlsCrypto crypto = Crypto; + IList supportedGroups = Platform.CreateArrayList(); + + if (namedGroupRoles.Contains(NamedGroupRole.ecdh)) + { + TlsUtilities.AddIfSupported(supportedGroups, crypto, + new int[]{ NamedGroup.x25519, NamedGroup.x448 }); + } + + if (namedGroupRoles.Contains(NamedGroupRole.ecdh) || + namedGroupRoles.Contains(NamedGroupRole.ecdsa)) + { + TlsUtilities.AddIfSupported(supportedGroups, crypto, + new int[]{ NamedGroup.secp256r1, NamedGroup.secp384r1 }); + } + + if (namedGroupRoles.Contains(NamedGroupRole.dh)) + { + TlsUtilities.AddIfSupported(supportedGroups, crypto, + new int[]{ NamedGroup.ffdhe2048, NamedGroup.ffdhe3072, NamedGroup.ffdhe4096 }); + } + + return supportedGroups; + } + + protected virtual IList GetSupportedSignatureAlgorithms() + { + return TlsUtilities.GetDefaultSupportedSignatureAlgorithms(m_context); + } + + protected virtual IList GetSupportedSignatureAlgorithmsCert() + { + return null; + } + + protected virtual IList GetTrustedCAIndication() + { + return null; + } + + public virtual void Init(TlsClientContext context) + { + this.m_context = context; + + this.m_protocolVersions = GetSupportedVersions(); + this.m_cipherSuites = GetSupportedCipherSuites(); + } + + public override ProtocolVersion[] GetProtocolVersions() + { + return m_protocolVersions; + } + + public override int[] GetCipherSuites() + { + return m_cipherSuites; + } + + /// + public override void NotifyHandshakeBeginning() + { + base.NotifyHandshakeBeginning(); + + this.m_supportedGroups = null; + this.m_supportedSignatureAlgorithms = null; + this.m_supportedSignatureAlgorithmsCert = null; + } + + public virtual TlsSession GetSessionToResume() + { + return null; + } + + public virtual IList GetExternalPsks() + { + return null; + } + + public virtual bool IsFallback() + { + /* + * RFC 7507 4. The TLS_FALLBACK_SCSV cipher suite value is meant for use by clients that + * repeat a connection attempt with a downgraded protocol (perform a "fallback retry") in + * order to work around interoperability problems with legacy servers. + */ + return false; + } + + /// + public virtual IDictionary GetClientExtensions() + { + IDictionary clientExtensions = Platform.CreateHashtable(); + + bool offeringTlsV13Plus = false; + bool offeringPreTlsV13 = false; + { + ProtocolVersion[] supportedVersions = GetProtocolVersions(); + for (int i = 0; i < supportedVersions.Length; ++i) + { + if (TlsUtilities.IsTlsV13(supportedVersions[i])) + { + offeringTlsV13Plus = true; + } + else + { + offeringPreTlsV13 = true; + } + } + } + + IList protocolNames = GetProtocolNames(); + if (protocolNames != null) + { + TlsExtensionsUtilities.AddAlpnExtensionClient(clientExtensions, protocolNames); + } + + IList sniServerNames = GetSniServerNames(); + if (sniServerNames != null) + { + TlsExtensionsUtilities.AddServerNameExtensionClient(clientExtensions, sniServerNames); + } + + CertificateStatusRequest statusRequest = GetCertificateStatusRequest(); + if (statusRequest != null) + { + TlsExtensionsUtilities.AddStatusRequestExtension(clientExtensions, statusRequest); + } + + if (offeringTlsV13Plus) + { + IList certificateAuthorities = GetCertificateAuthorities(); + if (certificateAuthorities != null) + { + TlsExtensionsUtilities.AddCertificateAuthoritiesExtension(clientExtensions, certificateAuthorities); + } + } + + if (offeringPreTlsV13) + { + // TODO Shouldn't add if no offered cipher suite uses a block cipher? + TlsExtensionsUtilities.AddEncryptThenMacExtension(clientExtensions); + + IList statusRequestV2 = GetMultiCertStatusRequest(); + if (statusRequestV2 != null) + { + TlsExtensionsUtilities.AddStatusRequestV2Extension(clientExtensions, statusRequestV2); + } + + IList trustedCAKeys = GetTrustedCAIndication(); + if (trustedCAKeys != null) + { + TlsExtensionsUtilities.AddTrustedCAKeysExtensionClient(clientExtensions, trustedCAKeys); + } + } + + ProtocolVersion clientVersion = m_context.ClientVersion; + + /* + * RFC 5246 7.4.1.4.1. Note: this extension is not meaningful for TLS versions prior to 1.2. + * Clients MUST NOT offer it if they are offering prior versions. + */ + if (TlsUtilities.IsSignatureAlgorithmsExtensionAllowed(clientVersion)) + { + IList supportedSigAlgs = GetSupportedSignatureAlgorithms(); + if (null != supportedSigAlgs && supportedSigAlgs.Count > 0) + { + this.m_supportedSignatureAlgorithms = supportedSigAlgs; + + TlsExtensionsUtilities.AddSignatureAlgorithmsExtension(clientExtensions, supportedSigAlgs); + } + + IList supportedSigAlgsCert = GetSupportedSignatureAlgorithmsCert(); + if (null != supportedSigAlgsCert && supportedSigAlgsCert.Count > 0) + { + this.m_supportedSignatureAlgorithmsCert = supportedSigAlgsCert; + + TlsExtensionsUtilities.AddSignatureAlgorithmsCertExtension(clientExtensions, supportedSigAlgsCert); + } + } + + IList namedGroupRoles = GetNamedGroupRoles(); + + IList supportedGroups = GetSupportedGroups(namedGroupRoles); + if (supportedGroups != null && supportedGroups.Count > 0) + { + this.m_supportedGroups = supportedGroups; + + TlsExtensionsUtilities.AddSupportedGroupsExtension(clientExtensions, supportedGroups); + } + + if (offeringPreTlsV13) + { + if (namedGroupRoles.Contains(NamedGroupRole.ecdh) || + namedGroupRoles.Contains(NamedGroupRole.ecdsa)) + { + TlsExtensionsUtilities.AddSupportedPointFormatsExtension(clientExtensions, + new short[]{ ECPointFormat.uncompressed }); + } + } + + return clientExtensions; + } + + public virtual IList GetEarlyKeyShareGroups() + { + /* + * RFC 8446 4.2.8. Each KeyShareEntry value MUST correspond to a group offered in the + * "supported_groups" extension and MUST appear in the same order. However, the values MAY + * be a non-contiguous subset of the "supported_groups" extension and MAY omit the most + * preferred groups. + */ + + if (null == m_supportedGroups || m_supportedGroups.Count < 1) + return null; + + if (m_supportedGroups.Contains(NamedGroup.x25519)) + return TlsUtilities.VectorOfOne(NamedGroup.x25519); + + if (m_supportedGroups.Contains(NamedGroup.secp256r1)) + return TlsUtilities.VectorOfOne(NamedGroup.secp256r1); + + return TlsUtilities.VectorOfOne(m_supportedGroups[0]); + } + + /// + public virtual void NotifyServerVersion(ProtocolVersion serverVersion) + { + } + + public virtual void NotifySessionToResume(TlsSession session) + { + } + + public virtual void NotifySessionID(byte[] sessionID) + { + } + + public virtual void NotifySelectedCipherSuite(int selectedCipherSuite) + { + } + + /// + public virtual void NotifySelectedPsk(TlsPsk selectedPsk) + { + } + + /// + public virtual void ProcessServerExtensions(IDictionary serverExtensions) + { + if (null == serverExtensions) + return; + + SecurityParameters securityParameters = m_context.SecurityParameters; + bool isTlsV13 = TlsUtilities.IsTlsV13(securityParameters.NegotiatedVersion); + + if (isTlsV13) + { + /* + * NOTE: From TLS 1.3 the protocol classes are strict about what extensions can appear. + */ + } + else + { + /* + * RFC 5246 7.4.1.4.1. Servers MUST NOT send this extension. + */ + CheckForUnexpectedServerExtension(serverExtensions, ExtensionType.signature_algorithms); + CheckForUnexpectedServerExtension(serverExtensions, ExtensionType.signature_algorithms_cert); + + CheckForUnexpectedServerExtension(serverExtensions, ExtensionType.supported_groups); + + int selectedCipherSuite = securityParameters.CipherSuite; + + if (TlsEccUtilities.IsEccCipherSuite(selectedCipherSuite)) + { + // We only support uncompressed format, this is just to validate the extension, if present. + TlsExtensionsUtilities.GetSupportedPointFormatsExtension(serverExtensions); + } + else + { + CheckForUnexpectedServerExtension(serverExtensions, ExtensionType.ec_point_formats); + } + + /* + * RFC 7685 3. The server MUST NOT echo the extension. + */ + CheckForUnexpectedServerExtension(serverExtensions, ExtensionType.padding); + } + } + + /// + public virtual void ProcessServerSupplementalData(IList serverSupplementalData) + { + if (serverSupplementalData != null) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + public abstract TlsAuthentication GetAuthentication(); + + /// + public virtual IList GetClientSupplementalData() + { + return null; + } + + /// + public virtual void NotifyNewSessionTicket(NewSessionTicket newSessionTicket) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/AbstractTlsClient.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/AbstractTlsClient.cs.meta new file mode 100644 index 0000000..6a234ec --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/AbstractTlsClient.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0c8a31cdb0a7b394db608304c11e14cb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/AbstractTlsContext.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/AbstractTlsContext.cs new file mode 100644 index 0000000..75e46d9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/AbstractTlsContext.cs @@ -0,0 +1,288 @@ +using System; +using System.IO; +using System.Threading; + +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Tls.Crypto; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls +{ + internal abstract class AbstractTlsContext + : TlsContext + { + private static long counter = Times.NanoTime(); + +#if NETCF_1_0 + private static object counterLock = new object(); + private static long NextCounterValue() + { + lock (counterLock) + { + return ++counter; + } + } +#else + private static long NextCounterValue() + { + return Interlocked.Increment(ref counter); + } +#endif + + private static TlsNonceGenerator CreateNonceGenerator(TlsCrypto crypto, int connectionEnd) + { + byte[] additionalSeedMaterial = new byte[16]; + Pack.UInt64_To_BE((ulong)NextCounterValue(), additionalSeedMaterial, 0); + Pack.UInt64_To_BE((ulong)Times.NanoTime(), additionalSeedMaterial, 8); + additionalSeedMaterial[0] &= 0x7F; + additionalSeedMaterial[0] |= (byte)(connectionEnd << 7); + + return crypto.CreateNonceGenerator(additionalSeedMaterial); + } + + private readonly TlsCrypto m_crypto; + private readonly int m_connectionEnd; + private readonly TlsNonceGenerator m_nonceGenerator; + + private SecurityParameters m_securityParameters = null; + private ProtocolVersion[] m_clientSupportedVersions = null; + private ProtocolVersion m_clientVersion = null; + private ProtocolVersion m_rsaPreMasterSecretVersion = null; + private TlsSession m_session = null; + private object m_userObject = null; + private bool m_connected = false; + + internal AbstractTlsContext(TlsCrypto crypto, int connectionEnd) + { + this.m_crypto = crypto; + this.m_connectionEnd = connectionEnd; + this.m_nonceGenerator = CreateNonceGenerator(crypto, connectionEnd); + } + + /// + internal void HandshakeBeginning(TlsPeer peer) + { + lock (this) + { + if (null != m_securityParameters) + throw new TlsFatalAlert(AlertDescription.internal_error, "Handshake already started"); + + m_securityParameters = new SecurityParameters(); + m_securityParameters.m_entity = m_connectionEnd; + } + + peer.NotifyHandshakeBeginning(); + } + + /// + internal void HandshakeComplete(TlsPeer peer, TlsSession session) + { + lock (this) + { + if (null == m_securityParameters) + throw new TlsFatalAlert(AlertDescription.internal_error); + + this.m_session = session; + this.m_connected = true; + } + + peer.NotifyHandshakeComplete(); + } + + internal bool IsConnected + { + get { lock (this) return m_connected; } + } + + internal bool IsHandshaking + { + get { lock (this) return !m_connected && null != m_securityParameters; } + } + + public TlsCrypto Crypto + { + get { return m_crypto; } + } + + public virtual TlsNonceGenerator NonceGenerator + { + get { return m_nonceGenerator; } + } + + public SecurityParameters SecurityParameters + { + get { lock (this) return m_securityParameters; } + } + + public abstract bool IsServer { get; } + + public virtual ProtocolVersion[] ClientSupportedVersions + { + get { return m_clientSupportedVersions; } + } + + internal void SetClientSupportedVersions(ProtocolVersion[] clientSupportedVersions) + { + this.m_clientSupportedVersions = clientSupportedVersions; + } + + public virtual ProtocolVersion ClientVersion + { + get { return m_clientVersion; } + } + + internal void SetClientVersion(ProtocolVersion clientVersion) + { + this.m_clientVersion = clientVersion; + } + + public virtual ProtocolVersion RsaPreMasterSecretVersion + { + get { return m_rsaPreMasterSecretVersion; } + } + + internal void SetRsaPreMasterSecretVersion(ProtocolVersion rsaPreMasterSecretVersion) + { + this.m_rsaPreMasterSecretVersion = rsaPreMasterSecretVersion; + } + + public virtual ProtocolVersion ServerVersion + { + get { return SecurityParameters.NegotiatedVersion; } + } + + public virtual TlsSession ResumableSession + { + get + { + TlsSession session = Session; + if (session == null || !session.IsResumable) + return null; + + return session; + } + } + + public virtual TlsSession Session + { + get { return m_session; } + } + + public virtual object UserObject + { + get { return m_userObject; } + set { this.m_userObject = value; } + } + + public virtual byte[] ExportChannelBinding(int channelBinding) + { + if (!IsConnected) + throw new InvalidOperationException("Export of channel bindings unavailable before handshake completion"); + + SecurityParameters securityParameters = SecurityParameters; + + if (TlsUtilities.IsTlsV13(securityParameters.NegotiatedVersion)) + return null; + + switch (channelBinding) + { + case ChannelBinding.tls_server_end_point: + { + byte[] tlsServerEndPoint = securityParameters.TlsServerEndPoint; + + return TlsUtilities.IsNullOrEmpty(tlsServerEndPoint) ? null : Arrays.Clone(tlsServerEndPoint); + } + + case ChannelBinding.tls_unique: + { + return Arrays.Clone(securityParameters.TlsUnique); + } + + case ChannelBinding.tls_unique_for_telnet: + default: + throw new NotSupportedException(); + } + } + + public virtual byte[] ExportEarlyKeyingMaterial(string asciiLabel, byte[] context, int length) + { + // TODO[tls13] Ensure early_exporter_master_secret is available suitably early! + if (!IsConnected) + throw new InvalidOperationException("Export of early key material only available during handshake"); + + SecurityParameters sp = SecurityParameters; + + return ExportKeyingMaterial13(CheckEarlyExportSecret(sp.EarlyExporterMasterSecret), + sp.PrfCryptoHashAlgorithm, asciiLabel, context, length); + } + + public virtual byte[] ExportKeyingMaterial(string asciiLabel, byte[] context, int length) + { + if (!IsConnected) + throw new InvalidOperationException("Export of key material unavailable before handshake completion"); + + /* + * TODO[tls13] Introduce a TlsExporter interface? Avoid calculating (early) exporter + * secret(s) unless the peer actually uses it. + */ + SecurityParameters sp = SecurityParameters; + + if (!sp.IsExtendedMasterSecret) + { + /* + * RFC 7627 5.4. If a client or server chooses to continue with a full handshake without + * the extended master secret extension, [..] the client or server MUST NOT export any + * key material based on the new master secret for any subsequent application-level + * authentication. In particular, it MUST disable [RFC5705] [..]. + */ + throw new InvalidOperationException("Export of key material requires extended_master_secret"); + } + + if (TlsUtilities.IsTlsV13(sp.NegotiatedVersion)) + { + return ExportKeyingMaterial13(CheckExportSecret(sp.ExporterMasterSecret), sp.PrfCryptoHashAlgorithm, + asciiLabel, context, length); + } + + byte[] seed = TlsUtilities.CalculateExporterSeed(sp, context); + + return TlsUtilities.Prf(sp, CheckExportSecret(sp.MasterSecret), asciiLabel, seed, length).Extract(); + } + + protected virtual byte[] ExportKeyingMaterial13(TlsSecret secret, int cryptoHashAlgorithm, string asciiLabel, + byte[] context, int length) + { + if (null == context) + { + context = TlsUtilities.EmptyBytes; + } + else if (!TlsUtilities.IsValidUint16(context.Length)) + { + throw new ArgumentException("must have length less than 2^16 (or be null)", "context"); + } + + return TlsCryptoUtilities.HkdfExpandLabel(secret, cryptoHashAlgorithm, asciiLabel, context, length) + .Extract(); + } + + protected virtual TlsSecret CheckEarlyExportSecret(TlsSecret secret) + { + if (null == secret) + { + // TODO[tls13] For symmetry with normal export, ideally available for NotifyHandshakeBeginning() only + //throw new InvalidOperationException("Export of early key material only available from NotifyHandshakeBeginning()"); + throw new InvalidOperationException("Export of early key material not available for this handshake"); + } + return secret; + } + + protected virtual TlsSecret CheckExportSecret(TlsSecret secret) + { + if (null == secret) + throw new InvalidOperationException( + "Export of key material only available from NotifyHandshakeComplete()"); + + return secret; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/AbstractTlsContext.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/AbstractTlsContext.cs.meta new file mode 100644 index 0000000..f153c3d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/AbstractTlsContext.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c7da35d20cfa63d46827e311040ebda0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/AbstractTlsKeyExchange.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/AbstractTlsKeyExchange.cs new file mode 100644 index 0000000..4e61f4c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/AbstractTlsKeyExchange.cs @@ -0,0 +1,90 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Tls.Crypto; + +namespace Org.BouncyCastle.Tls +{ + /// Base class for supporting a TLS key exchange implementation. + public abstract class AbstractTlsKeyExchange + : TlsKeyExchange + { + protected readonly int m_keyExchange; + + protected TlsContext m_context; + + protected AbstractTlsKeyExchange(int keyExchange) + { + this.m_keyExchange = keyExchange; + } + + public virtual void Init(TlsContext context) + { + this.m_context = context; + } + + public abstract void SkipServerCredentials(); + + public abstract void ProcessServerCredentials(TlsCredentials serverCredentials); + + public virtual void ProcessServerCertificate(Certificate serverCertificate) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public virtual bool RequiresServerKeyExchange + { + get { return false; } + } + + public virtual byte[] GenerateServerKeyExchange() + { + if (RequiresServerKeyExchange) + throw new TlsFatalAlert(AlertDescription.internal_error); + + return null; + } + + public virtual void SkipServerKeyExchange() + { + if (RequiresServerKeyExchange) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + public virtual void ProcessServerKeyExchange(Stream input) + { + if (!RequiresServerKeyExchange) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + public virtual short[] GetClientCertificateTypes() + { + return null; + } + + public virtual void SkipClientCredentials() + { + } + + public abstract void ProcessClientCredentials(TlsCredentials clientCredentials); + + public virtual void ProcessClientCertificate(Certificate clientCertificate) + { + } + + public abstract void GenerateClientKeyExchange(Stream output); + + public virtual void ProcessClientKeyExchange(Stream input) + { + // Key exchange implementation MUST support client key exchange + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public virtual bool RequiresCertificateVerify + { + get { return true; } + } + + public abstract TlsSecret GeneratePreMasterSecret(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/AbstractTlsKeyExchange.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/AbstractTlsKeyExchange.cs.meta new file mode 100644 index 0000000..ca09672 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/AbstractTlsKeyExchange.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e09971ecd83033c40a5c04b8c01d2691 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/AbstractTlsKeyExchangeFactory.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/AbstractTlsKeyExchangeFactory.cs new file mode 100644 index 0000000..946ad5f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/AbstractTlsKeyExchangeFactory.cs @@ -0,0 +1,90 @@ +using System; + +using Org.BouncyCastle.Tls.Crypto; + +namespace Org.BouncyCastle.Tls +{ + /// Base class for supporting a TLS key exchange factory implementation. + public abstract class AbstractTlsKeyExchangeFactory + : TlsKeyExchangeFactory + { + public virtual TlsKeyExchange CreateDHKeyExchange(int keyExchange) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public virtual TlsKeyExchange CreateDHanonKeyExchangeClient(int keyExchange, TlsDHGroupVerifier dhGroupVerifier) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public virtual TlsKeyExchange CreateDHanonKeyExchangeServer(int keyExchange, TlsDHConfig dhConfig) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public virtual TlsKeyExchange CreateDheKeyExchangeClient(int keyExchange, TlsDHGroupVerifier dhGroupVerifier) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public virtual TlsKeyExchange CreateDheKeyExchangeServer(int keyExchange, TlsDHConfig dhConfig) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public virtual TlsKeyExchange CreateECDHKeyExchange(int keyExchange) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public virtual TlsKeyExchange CreateECDHanonKeyExchangeClient(int keyExchange) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public virtual TlsKeyExchange CreateECDHanonKeyExchangeServer(int keyExchange, TlsECConfig ecConfig) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public virtual TlsKeyExchange CreateECDheKeyExchangeClient(int keyExchange) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public virtual TlsKeyExchange CreateECDheKeyExchangeServer(int keyExchange, TlsECConfig ecConfig) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public virtual TlsKeyExchange CreatePskKeyExchangeClient(int keyExchange, TlsPskIdentity pskIdentity, + TlsDHGroupVerifier dhGroupVerifier) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public virtual TlsKeyExchange CreatePskKeyExchangeServer(int keyExchange, + TlsPskIdentityManager pskIdentityManager, TlsDHConfig dhConfig, TlsECConfig ecConfig) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public virtual TlsKeyExchange CreateRsaKeyExchange(int keyExchange) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public virtual TlsKeyExchange CreateSrpKeyExchangeClient(int keyExchange, TlsSrpIdentity srpIdentity, + TlsSrpConfigVerifier srpConfigVerifier) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public virtual TlsKeyExchange CreateSrpKeyExchangeServer(int keyExchange, + TlsSrpLoginParameters loginParameters) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/AbstractTlsKeyExchangeFactory.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/AbstractTlsKeyExchangeFactory.cs.meta new file mode 100644 index 0000000..5b8611f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/AbstractTlsKeyExchangeFactory.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cd8be8767a8cf5f40bf0e58f9d397759 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/AbstractTlsPeer.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/AbstractTlsPeer.cs new file mode 100644 index 0000000..6d29953 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/AbstractTlsPeer.cs @@ -0,0 +1,162 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Tls.Crypto; + +namespace Org.BouncyCastle.Tls +{ + /// Base class for a TLS client or server. + public abstract class AbstractTlsPeer + : TlsPeer + { + private readonly TlsCrypto m_crypto; + + private volatile TlsCloseable m_closeHandle; + + protected AbstractTlsPeer(TlsCrypto crypto) + { + this.m_crypto = crypto; + } + + /// Get the values that are supported by this peer. + /// + /// WARNING: Mixing DTLS and TLS versions in the returned array is currently NOT supported. Use a separate + /// (sub-)class for each case. + /// + /// an array of supported values. + protected virtual ProtocolVersion[] GetSupportedVersions() + { + // TODO[tls13] Enable TLSv13 by default in due course + return ProtocolVersion.TLSv12.DownTo(ProtocolVersion.TLSv10); + } + + protected abstract int[] GetSupportedCipherSuites(); + + /// + public virtual void Cancel() + { + TlsCloseable closeHandle = this.m_closeHandle; + if (null != closeHandle) + { + closeHandle.Close(); + } + } + + public virtual TlsCrypto Crypto + { + get { return m_crypto; } + } + + public virtual void NotifyCloseHandle(TlsCloseable closeHandle) + { + this.m_closeHandle = closeHandle; + } + + public abstract ProtocolVersion[] GetProtocolVersions(); + + public abstract int[] GetCipherSuites(); + + /// + public virtual void NotifyHandshakeBeginning() + { + } + + public virtual int GetHandshakeTimeoutMillis() + { + return 0; + } + + public virtual bool AllowLegacyResumption() + { + return false; + } + + public virtual int GetMaxCertificateChainLength() + { + return 10; + } + + public virtual int GetMaxHandshakeMessageSize() + { + return 32768; + } + + public virtual short[] GetPskKeyExchangeModes() + { + return new short[]{ PskKeyExchangeMode.psk_dhe_ke }; + } + + public virtual bool RequiresCloseNotify() + { + return true; + } + + public virtual bool RequiresExtendedMasterSecret() + { + return false; + } + + public virtual bool ShouldCheckSigAlgOfPeerCerts() + { + return true; + } + + public virtual bool ShouldUseExtendedMasterSecret() + { + return true; + } + + public virtual bool ShouldUseExtendedPadding() + { + return false; + } + + public virtual bool ShouldUseGmtUnixTime() + { + /* + * draft-mathewson-no-gmtunixtime-00 2. For the reasons we discuss above, we recommend that + * TLS implementors MUST by default set the entire value the ClientHello.Random and + * ServerHello.Random fields, including gmt_unix_time, to a cryptographically random + * sequence. + */ + return false; + } + + /// + public virtual void NotifySecureRenegotiation(bool secureRenegotiation) + { + if (!secureRenegotiation) + throw new TlsFatalAlert(AlertDescription.handshake_failure); + } + + /// + public virtual TlsKeyExchangeFactory GetKeyExchangeFactory() + { + return new DefaultTlsKeyExchangeFactory(); + } + + public virtual void NotifyAlertRaised(short alertLevel, short alertDescription, string message, + Exception cause) + { + } + + public virtual void NotifyAlertReceived(short alertLevel, short alertDescription) + { + } + + /// + public virtual void NotifyHandshakeComplete() + { + } + + public virtual TlsHeartbeat GetHeartbeat() + { + return null; + } + + public virtual short GetHeartbeatPolicy() + { + return HeartbeatMode.peer_not_allowed_to_send; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/AbstractTlsPeer.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/AbstractTlsPeer.cs.meta new file mode 100644 index 0000000..1609f8a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/AbstractTlsPeer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bb1443ab5d688cb4e94a356b7eabf7a9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/AbstractTlsServer.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/AbstractTlsServer.cs new file mode 100644 index 0000000..f122333 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/AbstractTlsServer.cs @@ -0,0 +1,583 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Tls.Crypto; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls +{ + /// Base class for a TLS server. + public abstract class AbstractTlsServer + : AbstractTlsPeer, TlsServer + { + protected TlsServerContext m_context; + protected ProtocolVersion[] m_protocolVersions; + protected int[] m_cipherSuites; + + protected int[] m_offeredCipherSuites; + protected IDictionary m_clientExtensions; + + protected bool m_encryptThenMACOffered; + protected short m_maxFragmentLengthOffered; + protected bool m_truncatedHMacOffered; + protected bool m_clientSentECPointFormats; + protected CertificateStatusRequest m_certificateStatusRequest; + protected IList m_statusRequestV2; + protected IList m_trustedCAKeys; + + protected int m_selectedCipherSuite; + protected IList m_clientProtocolNames; + protected ProtocolName m_selectedProtocolName; + + protected readonly IDictionary m_serverExtensions = Platform.CreateHashtable(); + + public AbstractTlsServer(TlsCrypto crypto) + : base(crypto) + { + } + + protected virtual bool AllowCertificateStatus() + { + return true; + } + + protected virtual bool AllowEncryptThenMac() + { + return true; + } + + protected virtual bool AllowMultiCertStatus() + { + return false; + } + + protected virtual bool AllowTruncatedHmac() + { + return false; + } + + protected virtual bool AllowTrustedCAIndication() + { + return false; + } + + protected virtual int GetMaximumNegotiableCurveBits() + { + int[] clientSupportedGroups = m_context.SecurityParameters.ClientSupportedGroups; + if (clientSupportedGroups == null) + { + /* + * RFC 4492 4. A client that proposes ECC cipher suites may choose not to include these + * extensions. In this case, the server is free to choose any one of the elliptic curves + * or point formats [...]. + */ + return NamedGroup.GetMaximumCurveBits(); + } + + int maxBits = 0; + for (int i = 0; i < clientSupportedGroups.Length; ++i) + { + maxBits = System.Math.Max(maxBits, NamedGroup.GetCurveBits(clientSupportedGroups[i])); + } + return maxBits; + } + + protected virtual int GetMaximumNegotiableFiniteFieldBits() + { + int[] clientSupportedGroups = m_context.SecurityParameters.ClientSupportedGroups; + if (clientSupportedGroups == null) + { + return NamedGroup.GetMaximumFiniteFieldBits(); + } + + int maxBits = 0; + for (int i = 0; i < clientSupportedGroups.Length; ++i) + { + maxBits = System.Math.Max(maxBits, NamedGroup.GetFiniteFieldBits(clientSupportedGroups[i])); + } + return maxBits; + } + + protected virtual IList GetProtocolNames() + { + return null; + } + + protected virtual bool IsSelectableCipherSuite(int cipherSuite, int availCurveBits, int availFiniteFieldBits, + IList sigAlgs) + { + // TODO[tls13] The version check should be separated out (eventually select ciphersuite before version) + return TlsUtilities.IsValidVersionForCipherSuite(cipherSuite, m_context.ServerVersion) + && availCurveBits >= TlsEccUtilities.GetMinimumCurveBits(cipherSuite) + && availFiniteFieldBits >= TlsDHUtilities.GetMinimumFiniteFieldBits(cipherSuite) + && TlsUtilities.IsValidCipherSuiteForSignatureAlgorithms(cipherSuite, sigAlgs); + } + + protected virtual bool PreferLocalCipherSuites() + { + return false; + } + + /// + protected virtual bool SelectCipherSuite(int cipherSuite) + { + this.m_selectedCipherSuite = cipherSuite; + return true; + } + + protected virtual int SelectDH(int minimumFiniteFieldBits) + { + int[] clientSupportedGroups = m_context.SecurityParameters.ClientSupportedGroups; + if (clientSupportedGroups == null) + return SelectDHDefault(minimumFiniteFieldBits); + + // Try to find a supported named group of the required size from the client's list. + for (int i = 0; i < clientSupportedGroups.Length; ++i) + { + int namedGroup = clientSupportedGroups[i]; + if (NamedGroup.GetFiniteFieldBits(namedGroup) >= minimumFiniteFieldBits) + return namedGroup; + } + + return -1; + } + + protected virtual int SelectDHDefault(int minimumFiniteFieldBits) + { + return minimumFiniteFieldBits <= 2048 ? NamedGroup.ffdhe2048 + : minimumFiniteFieldBits <= 3072 ? NamedGroup.ffdhe3072 + : minimumFiniteFieldBits <= 4096 ? NamedGroup.ffdhe4096 + : minimumFiniteFieldBits <= 6144 ? NamedGroup.ffdhe6144 + : minimumFiniteFieldBits <= 8192 ? NamedGroup.ffdhe8192 + : -1; + } + + protected virtual int SelectECDH(int minimumCurveBits) + { + int[] clientSupportedGroups = m_context.SecurityParameters.ClientSupportedGroups; + if (clientSupportedGroups == null) + return SelectECDHDefault(minimumCurveBits); + + // Try to find a supported named group of the required size from the client's list. + for (int i = 0; i < clientSupportedGroups.Length; ++i) + { + int namedGroup = clientSupportedGroups[i]; + if (NamedGroup.GetCurveBits(namedGroup) >= minimumCurveBits) + return namedGroup; + } + + return -1; + } + + protected virtual int SelectECDHDefault(int minimumCurveBits) + { + return minimumCurveBits <= 256 ? NamedGroup.secp256r1 + : minimumCurveBits <= 384 ? NamedGroup.secp384r1 + : minimumCurveBits <= 521 ? NamedGroup.secp521r1 + : -1; + } + + protected virtual ProtocolName SelectProtocolName() + { + IList serverProtocolNames = GetProtocolNames(); + if (null == serverProtocolNames || serverProtocolNames.Count < 1) + return null; + + ProtocolName result = SelectProtocolName(m_clientProtocolNames, serverProtocolNames); + if (null == result) + throw new TlsFatalAlert(AlertDescription.no_application_protocol); + + return result; + } + + protected virtual ProtocolName SelectProtocolName(IList clientProtocolNames, IList serverProtocolNames) + { + foreach (ProtocolName serverProtocolName in serverProtocolNames) + { + if (clientProtocolNames.Contains(serverProtocolName)) + return serverProtocolName; + } + return null; + } + + protected virtual bool ShouldSelectProtocolNameEarly() + { + return true; + } + + public virtual void Init(TlsServerContext context) + { + this.m_context = context; + + this.m_protocolVersions = GetSupportedVersions(); + this.m_cipherSuites = GetSupportedCipherSuites(); + } + + public override ProtocolVersion[] GetProtocolVersions() + { + return m_protocolVersions; + } + + public override int[] GetCipherSuites() + { + return m_cipherSuites; + } + + public override void NotifyHandshakeBeginning() + { + base.NotifyHandshakeBeginning(); + + this.m_offeredCipherSuites = null; + this.m_clientExtensions = null; + this.m_encryptThenMACOffered = false; + this.m_maxFragmentLengthOffered = 0; + this.m_truncatedHMacOffered = false; + this.m_clientSentECPointFormats = false; + this.m_certificateStatusRequest = null; + this.m_selectedCipherSuite = -1; + this.m_selectedProtocolName = null; + this.m_serverExtensions.Clear(); + } + + public virtual TlsSession GetSessionToResume(byte[] sessionID) + { + return null; + } + + public virtual byte[] GetNewSessionID() + { + return null; + } + + public virtual TlsPskExternal GetExternalPsk(IList identities) + { + return null; + } + + public virtual void NotifySession(TlsSession session) + { + } + + public virtual void NotifyClientVersion(ProtocolVersion clientVersion) + { + } + + public virtual void NotifyFallback(bool isFallback) + { + /* + * RFC 7507 3. If TLS_FALLBACK_SCSV appears in ClientHello.cipher_suites and the highest + * protocol version supported by the server is higher than the version indicated in + * ClientHello.client_version, the server MUST respond with a fatal inappropriate_fallback + * alert [..]. + */ + if (isFallback) + { + ProtocolVersion[] serverVersions = GetProtocolVersions(); + ProtocolVersion clientVersion = m_context.ClientVersion; + + ProtocolVersion latestServerVersion; + if (clientVersion.IsTls) + { + latestServerVersion = ProtocolVersion.GetLatestTls(serverVersions); + } + else if (clientVersion.IsDtls) + { + latestServerVersion = ProtocolVersion.GetLatestDtls(serverVersions); + } + else + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + if (null != latestServerVersion && latestServerVersion.IsLaterVersionOf(clientVersion)) + { + throw new TlsFatalAlert(AlertDescription.inappropriate_fallback); + } + } + } + + public virtual void NotifyOfferedCipherSuites(int[] offeredCipherSuites) + { + this.m_offeredCipherSuites = offeredCipherSuites; + } + + public virtual void ProcessClientExtensions(IDictionary clientExtensions) + { + this.m_clientExtensions = clientExtensions; + + if (null != clientExtensions) + { + this.m_clientProtocolNames = TlsExtensionsUtilities.GetAlpnExtensionClient(clientExtensions); + + if (ShouldSelectProtocolNameEarly()) + { + if (null != m_clientProtocolNames && m_clientProtocolNames.Count > 0) + { + this.m_selectedProtocolName = SelectProtocolName(); + } + } + + // TODO[tls13] Don't need these if we have negotiated (D)TLS 1.3+ + { + this.m_encryptThenMACOffered = TlsExtensionsUtilities.HasEncryptThenMacExtension(clientExtensions); + this.m_truncatedHMacOffered = TlsExtensionsUtilities.HasTruncatedHmacExtension(clientExtensions); + this.m_statusRequestV2 = TlsExtensionsUtilities.GetStatusRequestV2Extension(clientExtensions); + this.m_trustedCAKeys = TlsExtensionsUtilities.GetTrustedCAKeysExtensionClient(clientExtensions); + + // We only support uncompressed format, this is just to validate the extension, and note its presence. + this.m_clientSentECPointFormats = + null != TlsExtensionsUtilities.GetSupportedPointFormatsExtension(clientExtensions); + } + + this.m_certificateStatusRequest = TlsExtensionsUtilities.GetStatusRequestExtension(clientExtensions); + + this.m_maxFragmentLengthOffered = TlsExtensionsUtilities.GetMaxFragmentLengthExtension(clientExtensions); + if (m_maxFragmentLengthOffered >= 0 && !MaxFragmentLength.IsValid(m_maxFragmentLengthOffered)) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + } + + public virtual ProtocolVersion GetServerVersion() + { + ProtocolVersion[] serverVersions = GetProtocolVersions(); + ProtocolVersion[] clientVersions = m_context.ClientSupportedVersions; + + foreach (ProtocolVersion clientVersion in clientVersions) + { + if (ProtocolVersion.Contains(serverVersions, clientVersion)) + return clientVersion; + } + + throw new TlsFatalAlert(AlertDescription.protocol_version); + } + + public virtual int[] GetSupportedGroups() + { + // TODO[tls13] The rest of this class assumes all named groups are supported + return new int[]{ NamedGroup.x25519, NamedGroup.x448, NamedGroup.secp256r1, NamedGroup.secp384r1, + NamedGroup.ffdhe2048, NamedGroup.ffdhe3072, NamedGroup.ffdhe4096 }; + } + + public virtual int GetSelectedCipherSuite() + { + SecurityParameters securityParameters = m_context.SecurityParameters; + ProtocolVersion negotiatedVersion = securityParameters.NegotiatedVersion; + + if (TlsUtilities.IsTlsV13(negotiatedVersion)) + { + int commonCipherSuite13 = TlsUtilities.GetCommonCipherSuite13(negotiatedVersion, m_offeredCipherSuites, + GetCipherSuites(), PreferLocalCipherSuites()); + + if (commonCipherSuite13 >= 0 && SelectCipherSuite(commonCipherSuite13)) + { + return commonCipherSuite13; + } + } + else + { + /* + * RFC 5246 7.4.3. In order to negotiate correctly, the server MUST check any candidate + * cipher suites against the "signature_algorithms" extension before selecting them. This is + * somewhat inelegant but is a compromise designed to minimize changes to the original + * cipher suite design. + */ + IList sigAlgs = TlsUtilities.GetUsableSignatureAlgorithms(securityParameters.ClientSigAlgs); + + /* + * RFC 4429 5.1. A server that receives a ClientHello containing one or both of these + * extensions MUST use the client's enumerated capabilities to guide its selection of an + * appropriate cipher suite. One of the proposed ECC cipher suites must be negotiated only + * if the server can successfully complete the handshake while using the curves and point + * formats supported by the client [...]. + */ + int availCurveBits = GetMaximumNegotiableCurveBits(); + int availFiniteFieldBits = GetMaximumNegotiableFiniteFieldBits(); + + int[] cipherSuites = TlsUtilities.GetCommonCipherSuites(m_offeredCipherSuites, GetCipherSuites(), + PreferLocalCipherSuites()); + + for (int i = 0; i < cipherSuites.Length; ++i) + { + int cipherSuite = cipherSuites[i]; + if (IsSelectableCipherSuite(cipherSuite, availCurveBits, availFiniteFieldBits, sigAlgs) + && SelectCipherSuite(cipherSuite)) + { + return cipherSuite; + } + } + } + + throw new TlsFatalAlert(AlertDescription.handshake_failure, "No selectable cipher suite"); + } + + // IDictionary is (Int32 -> byte[]) + public virtual IDictionary GetServerExtensions() + { + bool isTlsV13 = TlsUtilities.IsTlsV13(m_context); + + if (isTlsV13) + { + if (null != m_certificateStatusRequest && AllowCertificateStatus()) + { + /* + * TODO[tls13] RFC 8446 4.4.2.1. OCSP Status and SCT Extensions. + * + * OCSP information is carried in an extension for a CertificateEntry. + */ + } + } + else + { + if (m_encryptThenMACOffered && AllowEncryptThenMac()) + { + /* + * RFC 7366 3. If a server receives an encrypt-then-MAC request extension from a client + * and then selects a stream or Authenticated Encryption with Associated Data (AEAD) + * ciphersuite, it MUST NOT send an encrypt-then-MAC response extension back to the + * client. + */ + if (TlsUtilities.IsBlockCipherSuite(m_selectedCipherSuite)) + { + TlsExtensionsUtilities.AddEncryptThenMacExtension(m_serverExtensions); + } + } + + if (m_truncatedHMacOffered && AllowTruncatedHmac()) + { + TlsExtensionsUtilities.AddTruncatedHmacExtension(m_serverExtensions); + } + + if (m_clientSentECPointFormats && TlsEccUtilities.IsEccCipherSuite(m_selectedCipherSuite)) + { + /* + * RFC 4492 5.2. A server that selects an ECC cipher suite in response to a ClientHello + * message including a Supported Point Formats Extension appends this extension (along + * with others) to its ServerHello message, enumerating the point formats it can parse. + */ + TlsExtensionsUtilities.AddSupportedPointFormatsExtension(m_serverExtensions, + new short[]{ ECPointFormat.uncompressed }); + } + + // TODO[tls13] See RFC 8446 4.4.2.1 + if (null != m_statusRequestV2 && AllowMultiCertStatus()) + { + /* + * RFC 6961 2.2. If a server returns a "CertificateStatus" message in response to a + * "status_request_v2" request, then the server MUST have included an extension of type + * "status_request_v2" with empty "extension_data" in the extended server hello.. + */ + TlsExtensionsUtilities.AddEmptyExtensionData(m_serverExtensions, ExtensionType.status_request_v2); + } + else if (null != this.m_certificateStatusRequest && AllowCertificateStatus()) + { + /* + * RFC 6066 8. If a server returns a "CertificateStatus" message, then the server MUST + * have included an extension of type "status_request" with empty "extension_data" in + * the extended server hello. + */ + TlsExtensionsUtilities.AddEmptyExtensionData(m_serverExtensions, ExtensionType.status_request); + } + + if (null != m_trustedCAKeys && AllowTrustedCAIndication()) + { + TlsExtensionsUtilities.AddTrustedCAKeysExtensionServer(m_serverExtensions); + } + } + + if (m_maxFragmentLengthOffered >= 0 && MaxFragmentLength.IsValid(m_maxFragmentLengthOffered)) + { + TlsExtensionsUtilities.AddMaxFragmentLengthExtension(m_serverExtensions, m_maxFragmentLengthOffered); + } + + return m_serverExtensions; + } + + public virtual void GetServerExtensionsForConnection(IDictionary serverExtensions) + { + if (!ShouldSelectProtocolNameEarly()) + { + if (null != m_clientProtocolNames && m_clientProtocolNames.Count > 0) + { + this.m_selectedProtocolName = SelectProtocolName(); + } + } + + /* + * RFC 7301 3.1. When session resumption or session tickets [...] are used, the previous + * contents of this extension are irrelevant, and only the values in the new handshake + * messages are considered. + */ + if (null == m_selectedProtocolName) + { + serverExtensions.Remove(ExtensionType.application_layer_protocol_negotiation); + } + else + { + TlsExtensionsUtilities.AddAlpnExtensionServer(serverExtensions, m_selectedProtocolName); + } + } + + public virtual IList GetServerSupplementalData() + { + return null; + } + + public abstract TlsCredentials GetCredentials(); + + public virtual CertificateStatus GetCertificateStatus() + { + return null; + } + + public virtual CertificateRequest GetCertificateRequest() + { + return null; + } + + public virtual TlsPskIdentityManager GetPskIdentityManager() + { + return null; + } + + public virtual TlsSrpLoginParameters GetSrpLoginParameters() + { + return null; + } + + public virtual TlsDHConfig GetDHConfig() + { + int minimumFiniteFieldBits = TlsDHUtilities.GetMinimumFiniteFieldBits(m_selectedCipherSuite); + int namedGroup = SelectDH(minimumFiniteFieldBits); + return TlsDHUtilities.CreateNamedDHConfig(m_context, namedGroup); + } + + public virtual TlsECConfig GetECDHConfig() + { + int minimumCurveBits = TlsEccUtilities.GetMinimumCurveBits(m_selectedCipherSuite); + int namedGroup = SelectECDH(minimumCurveBits); + return TlsEccUtilities.CreateNamedECConfig(m_context, namedGroup); + } + + public virtual void ProcessClientSupplementalData(IList clientSupplementalData) + { + if (clientSupplementalData != null) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + public virtual void NotifyClientCertificate(Certificate clientCertificate) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public virtual NewSessionTicket GetNewSessionTicket() + { + /* + * RFC 5077 3.3. If the server determines that it does not want to include a ticket after it + * has included the SessionTicket extension in the ServerHello, then it sends a zero-length + * ticket in the NewSessionTicket handshake message. + */ + return new NewSessionTicket(0L, TlsUtilities.EmptyBytes); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/AbstractTlsServer.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/AbstractTlsServer.cs.meta new file mode 100644 index 0000000..32847c7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/AbstractTlsServer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b080ddecef79a4b438c3fd62b7933580 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/AlertDescription.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/AlertDescription.cs new file mode 100644 index 0000000..dc207bb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/AlertDescription.cs @@ -0,0 +1,323 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + /// RFC 5246 7.2. + public abstract class AlertDescription + { + /// This message notifies the recipient that the sender will not send any more messages on this + /// connection. + /// + /// Note that as of TLS 1.1, failure to properly close a connection no longer requires that a session not be + /// resumed. This is a change from TLS 1.0 ("The session becomes unresumable if any connection is terminated + /// without proper close_notify messages with level equal to warning.") to conform with widespread + /// implementation practice. + /// + public const short close_notify = 0; + + /// An inappropriate message was received. + /// + /// This alert is always fatal and should never be observed in communication between proper implementations. + /// + public const short unexpected_message = 10; + + /// This alert is returned if a record is received with an incorrect MAC. + /// + /// This alert also MUST be returned if an alert is sent because a TLSCiphertext decrypted in an invalid way: + /// either it wasn't an even multiple of the block length, or its padding values, when checked, weren't + /// correct. This message is always fatal and should never be observed in communication between proper + /// implementations (except when messages were corrupted in the network). + /// + public const short bad_record_mac = 20; + + /// + /// This alert was used in some earlier versions of TLS, and may have permitted certain attacks against the CBC + /// mode [CBCATT]. It MUST NOT be sent by compliant implementations. + /// + public const short decryption_failed = 21; + + /// A TLSCiphertext record was received that had a length more than 2^14+2048 bytes, or a record + /// decrypted to a TLSCompressed record with more than 2^14+1024 bytes. + /// + /// This message is always fatal and should never be observed in communication between proper implementations + /// (except when messages were corrupted in the network). + /// + public const short record_overflow = 22; + + /// The decompression function received improper input (e.g., data that would expand to excessive + /// length). + /// + /// This message is always fatal and should never be observed in communication between proper implementations. + /// + public const short decompression_failure = 30; + + /// Reception of a handshake_failure alert message indicates that the sender was unable to negotiate + /// an acceptable set of security parameters given the options available. + /// + /// This is a fatal error. + /// + public const short handshake_failure = 40; + + /// + /// This alert was used in SSLv3 but not any version of TLS. It MUST NOT be sent by compliant implementations. + /// + public const short no_certificate = 41; + + /// A certificate was corrupt, contained signatures that did not verify correctly, etc. + public const short bad_certificate = 42; + + /// A certificate was of an unsupported type. + public const short unsupported_certificate = 43; + + /// A certificate was revoked by its signer. + public const short certificate_revoked = 44; + + /// A certificate has expired or is not currently valid. + public const short certificate_expired = 45; + + /// Some other (unspecified) issue arose in processing the certificate, rendering it unacceptable. + /// + public const short certificate_unknown = 46; + + /// A field in the handshake was out of range or inconsistent with other fields. + /// + /// This message is always fatal. + /// + public const short illegal_parameter = 47; + + /// A valid certificate chain or partial chain was received, but the certificate was not accepted + /// because the CA certificate could not be located or couldn't be matched with a known, trusted CA. + /// + /// This message is always fatal. + /// + public const short unknown_ca = 48; + + /// A valid certificate was received, but when access control was applied, the sender decided not to + /// proceed with negotiation. + /// + /// This message is always fatal. + /// + public const short access_denied = 49; + + /// A message could not be decoded because some field was out of the specified range or the length of + /// the message was incorrect. + /// + /// This message is always fatal and should never be observed in communication between proper + /// implementations (except when messages were corrupted in the network). + /// + public const short decode_error = 50; + + /// A handshake cryptographic operation failed, including being unable to correctly verify a signature + /// or validate a Finished message. + /// + /// This message is always fatal. + /// + public const short decrypt_error = 51; + + /// + /// This alert was used in some earlier versions of TLS. It MUST NOT be sent by compliant implementations. + /// + public const short export_restriction = 60; + + /// The protocol version the client has attempted to negotiate is recognized but not supported. + /// + /// + /// (For example, old protocol versions might be avoided for security reasons.) This message is always fatal. + /// + public const short protocol_version = 70; + + /// Returned instead of handshake_failure when a negotiation has failed specifically because the + /// server requires ciphers more secure than those supported by the client. + /// + /// This message is always fatal. + /// + public const short insufficient_security = 71; + + /// An internal error unrelated to the peer or the correctness of the protocol (such as a memory + /// allocation failure) makes it impossible to continue. + /// + /// This message is always fatal. + /// + public const short internal_error = 80; + + /// This handshake is being canceled for some reason unrelated to a protocol failure. + /// + /// If the user cancels an operation after the handshake is complete, just closing the connection by sending a + /// close_notify is more appropriate. This alert should be followed by a close_notify. This message is + /// generally a warning. + /// + public const short user_canceled = 90; + + /// Sent by the client in response to a hello request or by the server in response to a client hello + /// after initial handshaking. + /// + /// Either of these would normally lead to renegotiation; when that is not appropriate, the recipient should + /// respond with this alert. At that point, the original requester can decide whether to proceed with the + /// connection. One case where this would be appropriate is where a server has spawned a process to satisfy a + /// request; the process might receive security parameters (key length, authentication, etc.) at startup, and + /// it might be difficult to communicate changes to these parameters after that point. This message is always a + /// warning. + /// + public const short no_renegotiation = 100; + + /// Sent by clients that receive an extended server hello containing an extension that they did not + /// put in the corresponding client hello. + /// + /// This message is always fatal. + /// + public const short unsupported_extension = 110; + + /* + * RFC 3546 + */ + + /// This alert is sent by servers who are unable to retrieve a certificate chain from the URL supplied + /// by the client(see Section 3.3). + /// + /// This message MAY be fatal - for example if client authentication is required by the server for the + /// handshake to continue and the server is unable to retrieve the certificate chain, it may send a fatal + /// alert. + /// + public const short certificate_unobtainable = 111; + + /// This alert is sent by servers that receive a server_name extension request, but do not recognize + /// the server name. + /// + /// This message MAY be fatal. + /// + public const short unrecognized_name = 112; + + /// This alert is sent by clients that receive an invalid certificate status response (see Section 3.6 + /// ). + /// + /// This message is always fatal. + /// + public const short bad_certificate_status_response = 113; + + /// This alert is sent by servers when a certificate hash does not match a client provided + /// certificate_hash. + /// + /// This message is always fatal. + /// + public const short bad_certificate_hash_value = 114; + + /* + * RFC 4279 + */ + + /// If the server does not recognize the PSK identity, it MAY respond with an "unknown_psk_identity" + /// alert message. + public const short unknown_psk_identity = 115; + + /* + * RFC 7301 + */ + + /// In the event that the server supports no protocols that the client advertises, then the server + /// SHALL respond with a fatal "no_application_protocol" alert. + public const short no_application_protocol = 120; + + /* + * RFC 7507 + */ + + /// If TLS_FALLBACK_SCSV appears in ClientHello.cipher_suites and the highest protocol version + /// supported by the server is higher than the version indicated in ClientHello.client_version, the server MUST + /// respond with a fatal inappropriate_fallback alert[..]. + public const short inappropriate_fallback = 86; + + /* + * RFC 8446 + */ + + /// Sent by endpoints that receive a handshake message not containing an extension that is mandatory + /// to send for the offered TLS version or other negotiated parameters. + public const short missing_extension = 109; + + /// Sent by servers when a client certificate is desired but none was provided by the client. + /// + public const short certificate_required = 116; + + public static string GetName(short alertDescription) + { + switch (alertDescription) + { + case close_notify: + return "close_notify"; + case unexpected_message: + return "unexpected_message"; + case bad_record_mac: + return "bad_record_mac"; + case decryption_failed: + return "decryption_failed"; + case record_overflow: + return "record_overflow"; + case decompression_failure: + return "decompression_failure"; + case handshake_failure: + return "handshake_failure"; + case no_certificate: + return "no_certificate"; + case bad_certificate: + return "bad_certificate"; + case unsupported_certificate: + return "unsupported_certificate"; + case certificate_revoked: + return "certificate_revoked"; + case certificate_expired: + return "certificate_expired"; + case certificate_unknown: + return "certificate_unknown"; + case illegal_parameter: + return "illegal_parameter"; + case unknown_ca: + return "unknown_ca"; + case access_denied: + return "access_denied"; + case decode_error: + return "decode_error"; + case decrypt_error: + return "decrypt_error"; + case export_restriction: + return "export_restriction"; + case protocol_version: + return "protocol_version"; + case insufficient_security: + return "insufficient_security"; + case internal_error: + return "internal_error"; + case user_canceled: + return "user_canceled"; + case no_renegotiation: + return "no_renegotiation"; + case unsupported_extension: + return "unsupported_extension"; + case certificate_unobtainable: + return "certificate_unobtainable"; + case unrecognized_name: + return "unrecognized_name"; + case bad_certificate_status_response: + return "bad_certificate_status_response"; + case bad_certificate_hash_value: + return "bad_certificate_hash_value"; + case unknown_psk_identity: + return "unknown_psk_identity"; + case no_application_protocol: + return "no_application_protocol"; + case inappropriate_fallback: + return "inappropriate_fallback"; + case missing_extension: + return "missing_extension"; + case certificate_required: + return "certificate_required"; + default: + return "UNKNOWN"; + } + } + + public static string GetText(short alertDescription) + { + return GetName(alertDescription) + "(" + alertDescription + ")"; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/AlertDescription.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/AlertDescription.cs.meta new file mode 100644 index 0000000..61910aa --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/AlertDescription.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f3d504158a3f2a649b0564bd63c42834 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/AlertLevel.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/AlertLevel.cs new file mode 100644 index 0000000..6e128e0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/AlertLevel.cs @@ -0,0 +1,29 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + /// RFC 5246 7.2 + public abstract class AlertLevel + { + public const short warning = 1; + public const short fatal = 2; + + public static string GetName(short alertDescription) + { + switch (alertDescription) + { + case warning: + return "warning"; + case fatal: + return "fatal"; + default: + return "UNKNOWN"; + } + } + + public static string GetText(short alertDescription) + { + return GetName(alertDescription) + "(" + alertDescription + ")"; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/AlertLevel.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/AlertLevel.cs.meta new file mode 100644 index 0000000..81361b6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/AlertLevel.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4fc0f7c94643a164380e13586f0a7d91 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/BasicTlsPskExternal.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/BasicTlsPskExternal.cs new file mode 100644 index 0000000..dd9b7b2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/BasicTlsPskExternal.cs @@ -0,0 +1,42 @@ +using System; + +using Org.BouncyCastle.Tls.Crypto; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls +{ + public class BasicTlsPskExternal + : TlsPskExternal + { + protected readonly byte[] m_identity; + protected readonly TlsSecret m_key; + protected readonly int m_prfAlgorithm; + + public BasicTlsPskExternal(byte[] identity, TlsSecret key) + : this(identity, key, Tls.PrfAlgorithm.tls13_hkdf_sha256) + { + } + + public BasicTlsPskExternal(byte[] identity, TlsSecret key, int prfAlgorithm) + { + this.m_identity = Arrays.Clone(identity); + this.m_key = key; + this.m_prfAlgorithm = prfAlgorithm; + } + + public virtual byte[] Identity + { + get { return m_identity; } + } + + public virtual TlsSecret Key + { + get { return m_key; } + } + + public virtual int PrfAlgorithm + { + get { return m_prfAlgorithm; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/BasicTlsPskExternal.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/BasicTlsPskExternal.cs.meta new file mode 100644 index 0000000..f2803c8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/BasicTlsPskExternal.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2370d56ed3a0a684283b21c0c00b1b91 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/BasicTlsPskIdentity.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/BasicTlsPskIdentity.cs new file mode 100644 index 0000000..4ed385a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/BasicTlsPskIdentity.cs @@ -0,0 +1,44 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls +{ + /// A basic PSK Identity holder. + public class BasicTlsPskIdentity + : TlsPskIdentity + { + protected readonly byte[] m_identity; + protected readonly byte[] m_psk; + + public BasicTlsPskIdentity(byte[] identity, byte[] psk) + { + this.m_identity = Arrays.Clone(identity); + this.m_psk = Arrays.Clone(psk); + } + + public BasicTlsPskIdentity(string identity, byte[] psk) + { + this.m_identity = Strings.ToUtf8ByteArray(identity); + this.m_psk = Arrays.Clone(psk); + } + + public virtual void SkipIdentityHint() + { + } + + public virtual void NotifyIdentityHint(byte[] psk_identity_hint) + { + } + + public virtual byte[] GetPskIdentity() + { + return m_identity; + } + + public byte[] GetPsk() + { + return Arrays.Clone(m_psk); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/BasicTlsPskIdentity.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/BasicTlsPskIdentity.cs.meta new file mode 100644 index 0000000..c1f4f41 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/BasicTlsPskIdentity.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 843c5171dd1968140a485fe5dbf4b247 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/BasicTlsSrpIdentity.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/BasicTlsSrpIdentity.cs new file mode 100644 index 0000000..9a527a7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/BasicTlsSrpIdentity.cs @@ -0,0 +1,36 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls +{ + /// A basic SRP Identity holder. + public class BasicTlsSrpIdentity + : TlsSrpIdentity + { + protected readonly byte[] m_identity; + protected readonly byte[] m_password; + + public BasicTlsSrpIdentity(byte[] identity, byte[] password) + { + this.m_identity = Arrays.Clone(identity); + this.m_password = Arrays.Clone(password); + } + + public BasicTlsSrpIdentity(string identity, string password) + { + this.m_identity = Strings.ToUtf8ByteArray(identity); + this.m_password = Strings.ToUtf8ByteArray(password); + } + + public virtual byte[] GetSrpIdentity() + { + return m_identity; + } + + public virtual byte[] GetSrpPassword() + { + return m_password; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/BasicTlsSrpIdentity.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/BasicTlsSrpIdentity.cs.meta new file mode 100644 index 0000000..ad2ceee --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/BasicTlsSrpIdentity.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 41a874deab1093d449f00e10e478f7ab +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ByteQueue.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ByteQueue.cs new file mode 100644 index 0000000..b024197 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ByteQueue.cs @@ -0,0 +1,195 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Tls +{ + /// A queue for bytes. This file could be more optimized. + public sealed class ByteQueue + { + /// The smallest number which can be written as 2^x which is bigger than i. + public static int NextTwoPow(int i) + { + /* + * This code is based of a lot of code I found on the Internet which mostly + * referenced a book called "Hacking delight". + */ + i |= i >> 1; + i |= i >> 2; + i |= i >> 4; + i |= i >> 8; + i |= i >> 16; + return i + 1; + } + + /// The buffer where we store our data. + private byte[] m_databuf; + + /// How many bytes at the beginning of the buffer are skipped. + private int m_skipped = 0; + + /// How many bytes in the buffer are valid data. + private int m_available = 0; + + private bool m_readOnlyBuf = false; + + public ByteQueue() + : this(0) + { + } + + public ByteQueue(int capacity) + { + this.m_databuf = capacity == 0 ? TlsUtilities.EmptyBytes : new byte[capacity]; + } + + public ByteQueue(byte[] buf, int off, int len) + { + this.m_databuf = buf; + this.m_skipped = off; + this.m_available = len; + this.m_readOnlyBuf = true; + } + + /// Add some data to our buffer. + /// A byte-array to read data from. + /// How many bytes to skip at the beginning of the array. + /// How many bytes to read from the array. + public void AddData(byte[] buf, int off, int len) + { + if (m_readOnlyBuf) + throw new InvalidOperationException("Cannot add data to read-only buffer"); + + if ((m_skipped + m_available + len) > m_databuf.Length) + { + int desiredSize = ByteQueue.NextTwoPow(m_available + len); + if (desiredSize > m_databuf.Length) + { + byte[] tmp = new byte[desiredSize]; + Array.Copy(m_databuf, m_skipped, tmp, 0, m_available); + m_databuf = tmp; + } + else + { + Array.Copy(m_databuf, m_skipped, m_databuf, 0, m_available); + } + m_skipped = 0; + } + + Array.Copy(buf, off, m_databuf, m_skipped + m_available, len); + m_available += len; + } + + /// The number of bytes which are available in this buffer. + public int Available + { + get { return m_available; } + } + + /// Copy some bytes from the beginning of the data to the provided . + /// The to copy the bytes to. + /// How many bytes to copy. + public void CopyTo(Stream output, int length) + { + if (length > m_available) + throw new InvalidOperationException("Cannot copy " + length + " bytes, only got " + m_available); + + output.Write(m_databuf, m_skipped, length); + } + + /// Read data from the buffer. + /// The buffer where the read data will be copied to. + /// How many bytes to skip at the beginning of buf. + /// How many bytes to read at all. + /// How many bytes from our data to skip. + public void Read(byte[] buf, int offset, int len, int skip) + { + if ((buf.Length - offset) < len) + { + throw new ArgumentException("Buffer size of " + buf.Length + + " is too small for a read of " + len + " bytes"); + } + if ((m_available - skip) < len) + { + throw new InvalidOperationException("Not enough data to read"); + } + Array.Copy(m_databuf, m_skipped + skip, buf, offset, len); + } + + /// Return a over some bytes at the beginning of the data. + /// + /// How many bytes will be readable. + /// A over the data. + internal HandshakeMessageInput ReadHandshakeMessage(int length) + { + if (length > m_available) + throw new InvalidOperationException("Cannot read " + length + " bytes, only got " + m_available); + + int position = m_skipped; + + m_available -= length; + m_skipped += length; + + return new HandshakeMessageInput(m_databuf, position, length); + } + + public int ReadInt32() + { + if (m_available < 4) + throw new InvalidOperationException("Not enough data to read"); + + return TlsUtilities.ReadInt32(m_databuf, m_skipped); + } + + /// Remove some bytes from our data from the beginning. + /// How many bytes to remove. + public void RemoveData(int i) + { + if (i > m_available) + throw new InvalidOperationException("Cannot remove " + i + " bytes, only got " + m_available); + + /* + * Skip the data. + */ + m_available -= i; + m_skipped += i; + } + + /// Remove data from the buffer. + /// The buffer where the removed data will be copied to. + /// How many bytes to skip at the beginning of buf. + /// How many bytes to read at all. + /// How many bytes from our data to skip. + public void RemoveData(byte[] buf, int off, int len, int skip) + { + Read(buf, off, len, skip); + RemoveData(skip + len); + } + + public byte[] RemoveData(int len, int skip) + { + byte[] buf = new byte[len]; + RemoveData(buf, 0, len, skip); + return buf; + } + + public void Shrink() + { + if (m_available == 0) + { + m_databuf = TlsUtilities.EmptyBytes; + m_skipped = 0; + } + else + { + int desiredSize = ByteQueue.NextTwoPow(m_available); + if (desiredSize < m_databuf.Length) + { + byte[] tmp = new byte[desiredSize]; + Array.Copy(m_databuf, m_skipped, tmp, 0, m_available); + m_databuf = tmp; + m_skipped = 0; + } + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ByteQueue.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ByteQueue.cs.meta new file mode 100644 index 0000000..bb4302f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ByteQueue.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c6be53f645f697040991004cdab924d4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ByteQueueInputStream.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ByteQueueInputStream.cs new file mode 100644 index 0000000..b59b5d1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ByteQueueInputStream.cs @@ -0,0 +1,72 @@ +using System; + +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Tls +{ + public sealed class ByteQueueInputStream + : BaseInputStream + { + private readonly ByteQueue m_buffer; + + public ByteQueueInputStream() + { + this.m_buffer = new ByteQueue(); + } + + public void AddBytes(byte[] buf) + { + m_buffer.AddData(buf, 0, buf.Length); + } + + public void AddBytes(byte[] buf, int bufOff, int bufLen) + { + m_buffer.AddData(buf, bufOff, bufLen); + } + + public int Peek(byte[] buf) + { + int bytesToRead = System.Math.Min(m_buffer.Available, buf.Length); + m_buffer.Read(buf, 0, bytesToRead, 0); + return bytesToRead; + } + + public override int ReadByte() + { + if (m_buffer.Available == 0) + return -1; + + return m_buffer.RemoveData(1, 0)[0]; + } + + public override int Read(byte[] buf, int off, int len) + { + int bytesToRead = System.Math.Min(m_buffer.Available, len); + m_buffer.RemoveData(buf, off, bytesToRead, 0); + return bytesToRead; + } + + public long Skip(long n) + { + int bytesToRemove = System.Math.Min((int)n, m_buffer.Available); + m_buffer.RemoveData(bytesToRemove); + return bytesToRemove; + } + + public int Available + { + get { return m_buffer.Available; } + } + +#if PORTABLE + //protected override void Dispose(bool disposing) + //{ + // base.Dispose(disposing); + //} +#else + public override void Close() + { + } +#endif + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ByteQueueInputStream.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ByteQueueInputStream.cs.meta new file mode 100644 index 0000000..a87eed7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ByteQueueInputStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: df8b4c75d47c3314abe50457078b4490 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ByteQueueOutputStream.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ByteQueueOutputStream.cs new file mode 100644 index 0000000..76f0491 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ByteQueueOutputStream.cs @@ -0,0 +1,33 @@ +using System; + +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Tls +{ + /// OutputStream based on a ByteQueue implementation. + public sealed class ByteQueueOutputStream + : BaseOutputStream + { + private readonly ByteQueue m_buffer; + + public ByteQueueOutputStream() + { + this.m_buffer = new ByteQueue(); + } + + public ByteQueue Buffer + { + get { return m_buffer; } + } + + public override void WriteByte(byte b) + { + m_buffer.AddData(new byte[]{ b }, 0, 1); + } + + public override void Write(byte[] buf, int off, int len) + { + m_buffer.AddData(buf, off, len); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ByteQueueOutputStream.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ByteQueueOutputStream.cs.meta new file mode 100644 index 0000000..d4f8ef7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ByteQueueOutputStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ca349c7322726fa4a8cbdb112381a416 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CachedInformationType.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CachedInformationType.cs new file mode 100644 index 0000000..273efab --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CachedInformationType.cs @@ -0,0 +1,28 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + public abstract class CachedInformationType + { + public const short cert = 1; + public const short cert_req = 2; + + public static string GetName(short cachedInformationType) + { + switch (cachedInformationType) + { + case cert: + return "cert"; + case cert_req: + return "cert_req"; + default: + return "UNKNOWN"; + } + } + + public static string GetText(short cachedInformationType) + { + return GetName(cachedInformationType) + "(" + cachedInformationType + ")"; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CachedInformationType.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CachedInformationType.cs.meta new file mode 100644 index 0000000..135dd61 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CachedInformationType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6074e68f88614ee4cbc50c0dcc773212 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertChainType.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertChainType.cs new file mode 100644 index 0000000..8b989e8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertChainType.cs @@ -0,0 +1,34 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + /// Implementation of the RFC 3546 3.3. CertChainType. + public abstract class CertChainType + { + public const short individual_certs = 0; + public const short pkipath = 1; + + public static string GetName(short certChainType) + { + switch (certChainType) + { + case individual_certs: + return "individual_certs"; + case pkipath: + return "pkipath"; + default: + return "UNKNOWN"; + } + } + + public static string GetText(short certChainType) + { + return GetName(certChainType) + "(" + certChainType + ")"; + } + + public static bool IsValid(short certChainType) + { + return certChainType >= individual_certs && certChainType <= pkipath; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertChainType.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertChainType.cs.meta new file mode 100644 index 0000000..903ce93 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertChainType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c4a9cbe107ad95b4592df7c8fdb698d7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/Certificate.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/Certificate.cs new file mode 100644 index 0000000..fef35fc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/Certificate.cs @@ -0,0 +1,294 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Tls.Crypto; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls +{ + /// Parsing and encoding of a Certificate struct from RFC 4346. + /// + ///
    +    /// opaque ASN.1Cert<2^24-1>;
    +    /// struct {
    +    ///   ASN.1Cert certificate_list<0..2^24-1>;
    +    /// } Certificate;
    +    /// 
    + ///
    + public sealed class Certificate + { + private static readonly TlsCertificate[] EmptyCerts = new TlsCertificate[0]; + private static readonly CertificateEntry[] EmptyCertEntries = new CertificateEntry[0]; + + public static readonly Certificate EmptyChain = new Certificate(EmptyCerts); + public static readonly Certificate EmptyChainTls13 = new Certificate(TlsUtilities.EmptyBytes, EmptyCertEntries); + + public sealed class ParseOptions + { + private int m_maxChainLength = int.MaxValue; + + public int MaxChainLength + { + get { return m_maxChainLength; } + } + + public ParseOptions SetMaxChainLength(int maxChainLength) + { + this.m_maxChainLength = maxChainLength; + return this; + } + } + + private static CertificateEntry[] Convert(TlsCertificate[] certificateList) + { + if (TlsUtilities.IsNullOrContainsNull(certificateList)) + throw new ArgumentException("cannot be null or contain any nulls", "certificateList"); + + int count = certificateList.Length; + CertificateEntry[] result = new CertificateEntry[count]; + for (int i = 0; i < count; ++i) + { + result[i] = new CertificateEntry(certificateList[i], null); + } + return result; + } + + private readonly byte[] m_certificateRequestContext; + private readonly CertificateEntry[] m_certificateEntryList; + + public Certificate(TlsCertificate[] certificateList) + : this(null, Convert(certificateList)) + { + } + + // TODO[tls13] Prefer to manage the certificateRequestContext internally only? + public Certificate(byte[] certificateRequestContext, CertificateEntry[] certificateEntryList) + { + if (null != certificateRequestContext && !TlsUtilities.IsValidUint8(certificateRequestContext.Length)) + throw new ArgumentException("cannot be longer than 255", "certificateRequestContext"); + if (TlsUtilities.IsNullOrContainsNull(certificateEntryList)) + throw new ArgumentException("cannot be null or contain any nulls", "certificateEntryList"); + + this.m_certificateRequestContext = TlsUtilities.Clone(certificateRequestContext); + this.m_certificateEntryList = certificateEntryList; + } + + public byte[] GetCertificateRequestContext() + { + return TlsUtilities.Clone(m_certificateRequestContext); + } + + /// an array of representing a certificate chain. + public TlsCertificate[] GetCertificateList() + { + return CloneCertificateList(); + } + + public TlsCertificate GetCertificateAt(int index) + { + return m_certificateEntryList[index].Certificate; + } + + public CertificateEntry GetCertificateEntryAt(int index) + { + return m_certificateEntryList[index]; + } + + public CertificateEntry[] GetCertificateEntryList() + { + return CloneCertificateEntryList(); + } + + public short CertificateType + { + get { return Tls.CertificateType.X509; } + } + + public int Length + { + get { return m_certificateEntryList.Length; } + } + + /// true if this certificate chain contains no certificates, or false otherwise. + /// + public bool IsEmpty + { + get { return m_certificateEntryList.Length == 0; } + } + + /// Encode this to a , and optionally calculate the + /// "end point hash" (per RFC 5929's tls-server-end-point binding). + /// the of the current connection. + /// the to encode to. + /// the to write the "end point hash" to (or null). + /// + /// + public void Encode(TlsContext context, Stream messageOutput, Stream endPointHashOutput) + { + bool isTlsV13 = TlsUtilities.IsTlsV13(context); + + if ((null != m_certificateRequestContext) != isTlsV13) + throw new InvalidOperationException(); + + if (isTlsV13) + { + TlsUtilities.WriteOpaque8(m_certificateRequestContext, messageOutput); + } + + int count = m_certificateEntryList.Length; + IList certEncodings = Platform.CreateArrayList(count); + IList extEncodings = isTlsV13 ? Platform.CreateArrayList(count) : null; + + long totalLength = 0; + for (int i = 0; i < count; ++i) + { + CertificateEntry entry = m_certificateEntryList[i]; + TlsCertificate cert = entry.Certificate; + byte[] derEncoding = cert.GetEncoded(); + + if (i == 0 && endPointHashOutput != null) + { + CalculateEndPointHash(context, cert, derEncoding, endPointHashOutput); + } + + certEncodings.Add(derEncoding); + totalLength += derEncoding.Length; + totalLength += 3; + + if (isTlsV13) + { + IDictionary extensions = entry.Extensions; + byte[] extEncoding = (null == extensions) + ? TlsUtilities.EmptyBytes + : TlsProtocol.WriteExtensionsData(extensions); + + extEncodings.Add(extEncoding); + totalLength += extEncoding.Length; + totalLength += 2; + } + } + + TlsUtilities.CheckUint24(totalLength); + TlsUtilities.WriteUint24((int)totalLength, messageOutput); + + for (int i = 0; i < count; ++i) + { + byte[] certEncoding = (byte[])certEncodings[i]; + TlsUtilities.WriteOpaque24(certEncoding, messageOutput); + + if (isTlsV13) + { + byte[] extEncoding = (byte[])extEncodings[i]; + TlsUtilities.WriteOpaque16(extEncoding, messageOutput); + } + } + } + + /// Parse a from a . + /// the to apply during parsing. + /// the of the current connection. + /// the to parse from. + /// the to write the "end point hash" to (or null). + /// + /// a object. + /// + public static Certificate Parse(ParseOptions options, TlsContext context, Stream messageInput, + Stream endPointHashOutput) + { + SecurityParameters securityParameters = context.SecurityParameters; + bool isTlsV13 = TlsUtilities.IsTlsV13(securityParameters.NegotiatedVersion); + + byte[] certificateRequestContext = null; + if (isTlsV13) + { + certificateRequestContext = TlsUtilities.ReadOpaque8(messageInput); + } + + int totalLength = TlsUtilities.ReadUint24(messageInput); + if (totalLength == 0) + { + return !isTlsV13 ? EmptyChain + : certificateRequestContext.Length < 1 ? EmptyChainTls13 + : new Certificate(certificateRequestContext, EmptyCertEntries); + } + + byte[] certListData = TlsUtilities.ReadFully(totalLength, messageInput); + MemoryStream buf = new MemoryStream(certListData, false); + + TlsCrypto crypto = context.Crypto; + int maxChainLength = System.Math.Max(1, options.MaxChainLength); + + IList certificate_list = Platform.CreateArrayList(); + while (buf.Position < buf.Length) + { + if (certificate_list.Count >= maxChainLength) + { + throw new TlsFatalAlert(AlertDescription.internal_error, + "Certificate chain longer than maximum (" + maxChainLength + ")"); + } + + byte[] derEncoding = TlsUtilities.ReadOpaque24(buf, 1); + TlsCertificate cert = crypto.CreateCertificate(derEncoding); + + if (certificate_list.Count < 1 && endPointHashOutput != null) + { + CalculateEndPointHash(context, cert, derEncoding, endPointHashOutput); + } + + IDictionary extensions = null; + if (isTlsV13) + { + byte[] extEncoding = TlsUtilities.ReadOpaque16(buf); + + extensions = TlsProtocol.ReadExtensionsData13(HandshakeType.certificate, extEncoding); + } + + certificate_list.Add(new CertificateEntry(cert, extensions)); + } + + CertificateEntry[] certificateList = new CertificateEntry[certificate_list.Count]; + for (int i = 0; i < certificate_list.Count; i++) + { + certificateList[i] = (CertificateEntry)certificate_list[i]; + } + + return new Certificate(certificateRequestContext, certificateList); + } + + private static void CalculateEndPointHash(TlsContext context, TlsCertificate cert, byte[] encoding, + Stream output) + { + byte[] endPointHash = TlsUtilities.CalculateEndPointHash(context, cert, encoding); + if (endPointHash != null && endPointHash.Length > 0) + { + output.Write(endPointHash, 0, endPointHash.Length); + } + } + + private TlsCertificate[] CloneCertificateList() + { + int count = m_certificateEntryList.Length; + if (0 == count) + return EmptyCerts; + + TlsCertificate[] result = new TlsCertificate[count]; + for (int i = 0; i < count; ++i) + { + result[i] = m_certificateEntryList[i].Certificate; + } + return result; + } + + private CertificateEntry[] CloneCertificateEntryList() + { + int count = m_certificateEntryList.Length; + if (0 == count) + return EmptyCertEntries; + + CertificateEntry[] result = new CertificateEntry[count]; + Array.Copy(m_certificateEntryList, 0, result, 0, count); + return result; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/Certificate.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/Certificate.cs.meta new file mode 100644 index 0000000..26dc88c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/Certificate.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 37298f80bf5bf3647b9af13da2f74622 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertificateEntry.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertificateEntry.cs new file mode 100644 index 0000000..b886775 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertificateEntry.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Tls.Crypto; + +namespace Org.BouncyCastle.Tls +{ + public sealed class CertificateEntry + { + private readonly TlsCertificate m_certificate; + private readonly IDictionary m_extensions; + + public CertificateEntry(TlsCertificate certificate, IDictionary extensions) + { + if (null == certificate) + throw new ArgumentNullException("certificate"); + + this.m_certificate = certificate; + this.m_extensions = extensions; + } + + public TlsCertificate Certificate + { + get { return m_certificate; } + } + + public IDictionary Extensions + { + get { return m_extensions; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertificateEntry.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertificateEntry.cs.meta new file mode 100644 index 0000000..d3864cc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertificateEntry.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ff4dfef9bbf86974889d578ce6c97549 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertificateRequest.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertificateRequest.cs new file mode 100644 index 0000000..1abf01a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertificateRequest.cs @@ -0,0 +1,276 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls +{ + /// Parsing and encoding of a CertificateRequest struct from RFC 4346. + /// + ///
    +    /// struct {
    +    ///   ClientCertificateType certificate_types<1..2^8-1>;
    +    ///   DistinguishedName certificate_authorities<3..2^16-1>;
    +    /// } CertificateRequest;
    +    /// 
    + /// Updated for RFC 5246: + ///
    +    /// struct {
    +    ///   ClientCertificateType certificate_types <1..2 ^ 8 - 1>;
    +    ///   SignatureAndHashAlgorithm supported_signature_algorithms <2 ^ 16 - 1>;
    +    ///   DistinguishedName certificate_authorities <0..2 ^ 16 - 1>;
    +    /// } CertificateRequest;
    +    /// 
    + /// Revised for RFC 8446: + ///
    +    /// struct {
    +    ///   opaque certificate_request_context <0..2 ^ 8 - 1>;
    +    ///   Extension extensions <2..2 ^ 16 - 1>;
    +    /// } CertificateRequest;
    +    /// 
    + ///
    + /// + /// + public sealed class CertificateRequest + { + /// + private static IList CheckSupportedSignatureAlgorithms(IList supportedSignatureAlgorithms, + short alertDescription) + { + if (null == supportedSignatureAlgorithms) + throw new TlsFatalAlert(alertDescription, "'signature_algorithms' is required"); + + return supportedSignatureAlgorithms; + } + + private readonly byte[] m_certificateRequestContext; + private readonly short[] m_certificateTypes; + private readonly IList m_supportedSignatureAlgorithms; + private readonly IList m_supportedSignatureAlgorithmsCert; + private readonly IList m_certificateAuthorities; + + /// see for valid constants. + /// + /// an of . + public CertificateRequest(short[] certificateTypes, IList supportedSignatureAlgorithms, + IList certificateAuthorities) + : this(null, certificateTypes, supportedSignatureAlgorithms, null, certificateAuthorities) + { + } + + // TODO[tls13] Prefer to manage the certificateRequestContext internally only? + /// + public CertificateRequest(byte[] certificateRequestContext, IList supportedSignatureAlgorithms, + IList supportedSignatureAlgorithmsCert, IList certificateAuthorities) + : this(certificateRequestContext, null, + CheckSupportedSignatureAlgorithms(supportedSignatureAlgorithms, AlertDescription.internal_error), + supportedSignatureAlgorithmsCert, certificateAuthorities) + { + /* + * TODO[tls13] Removed certificateTypes, added certificate_request_context, added extensions + * (required: signature_algorithms, optional: status_request, signed_certificate_timestamp, + * certificate_authorities, oid_filters, signature_algorithms_cert) + */ + } + + private CertificateRequest(byte[] certificateRequestContext, short[] certificateTypes, + IList supportedSignatureAlgorithms, IList supportedSignatureAlgorithmsCert, IList certificateAuthorities) + { + if (null != certificateRequestContext && !TlsUtilities.IsValidUint8(certificateRequestContext.Length)) + throw new ArgumentException("cannot be longer than 255", "certificateRequestContext"); + if (null != certificateTypes + && (certificateTypes.Length < 1 || !TlsUtilities.IsValidUint8(certificateTypes.Length))) + { + throw new ArgumentException("should have length from 1 to 255", "certificateTypes"); + } + + this.m_certificateRequestContext = TlsUtilities.Clone(certificateRequestContext); + this.m_certificateTypes = certificateTypes; + this.m_supportedSignatureAlgorithms = supportedSignatureAlgorithms; + this.m_supportedSignatureAlgorithmsCert = supportedSignatureAlgorithmsCert; + this.m_certificateAuthorities = certificateAuthorities; + } + + public byte[] GetCertificateRequestContext() + { + return TlsUtilities.Clone(m_certificateRequestContext); + } + + /// an array of certificate types + /// + public short[] CertificateTypes + { + get { return m_certificateTypes; } + } + + /// an of (or null before TLS 1.2). + /// + public IList SupportedSignatureAlgorithms + { + get { return m_supportedSignatureAlgorithms; } + } + + /// an optional of . May be non-null from + /// TLS 1.3 onwards. + public IList SupportedSignatureAlgorithmsCert + { + get { return m_supportedSignatureAlgorithmsCert; } + } + + /// an of . + public IList CertificateAuthorities + { + get { return m_certificateAuthorities; } + } + + public bool HasCertificateRequestContext(byte[] certificateRequestContext) + { + return Arrays.AreEqual(m_certificateRequestContext, certificateRequestContext); + } + + /// Encode this to a . + /// the of the current connection. + /// the to encode to. + /// + public void Encode(TlsContext context, Stream output) + { + ProtocolVersion negotiatedVersion = context.ServerVersion; + bool isTlsV12 = TlsUtilities.IsTlsV12(negotiatedVersion); + bool isTlsV13 = TlsUtilities.IsTlsV13(negotiatedVersion); + + if (isTlsV13 != (null != m_certificateRequestContext) || + isTlsV13 != (null == m_certificateTypes) || + isTlsV12 != (null != m_supportedSignatureAlgorithms) || + (!isTlsV13 && (null != m_supportedSignatureAlgorithmsCert))) + { + throw new InvalidOperationException(); + } + + if (isTlsV13) + { + TlsUtilities.WriteOpaque8(m_certificateRequestContext, output); + + IDictionary extensions = Platform.CreateHashtable(); + TlsExtensionsUtilities.AddSignatureAlgorithmsExtension(extensions, m_supportedSignatureAlgorithms); + + if (null != m_supportedSignatureAlgorithmsCert) + { + TlsExtensionsUtilities.AddSignatureAlgorithmsCertExtension(extensions, + m_supportedSignatureAlgorithmsCert); + } + + if (null != m_certificateAuthorities) + { + TlsExtensionsUtilities.AddCertificateAuthoritiesExtension(extensions, m_certificateAuthorities); + } + + byte[] extEncoding = TlsProtocol.WriteExtensionsData(extensions); + + TlsUtilities.WriteOpaque16(extEncoding, output); + return; + } + + TlsUtilities.WriteUint8ArrayWithUint8Length(m_certificateTypes, output); + + if (isTlsV12) + { + // TODO Check whether SignatureAlgorithm.anonymous is allowed here + TlsUtilities.EncodeSupportedSignatureAlgorithms(m_supportedSignatureAlgorithms, output); + } + + if (m_certificateAuthorities == null || m_certificateAuthorities.Count < 1) + { + TlsUtilities.WriteUint16(0, output); + } + else + { + IList derEncodings = Platform.CreateArrayList(m_certificateAuthorities.Count); + + int totalLength = 0; + foreach (X509Name certificateAuthority in m_certificateAuthorities) + { + byte[] derEncoding = certificateAuthority.GetEncoded(Asn1Encodable.Der); + derEncodings.Add(derEncoding); + totalLength += derEncoding.Length + 2; + } + + TlsUtilities.CheckUint16(totalLength); + TlsUtilities.WriteUint16(totalLength, output); + + foreach (byte[] derEncoding in derEncodings) + { + TlsUtilities.WriteOpaque16(derEncoding, output); + } + } + } + + /// Parse a from a + /// the of the current connection. + /// the to parse from. + /// a object. + /// + public static CertificateRequest Parse(TlsContext context, Stream input) + { + ProtocolVersion negotiatedVersion = context.ServerVersion; + bool isTlsV13 = TlsUtilities.IsTlsV13(negotiatedVersion); + + if (isTlsV13) + { + byte[] certificateRequestContext = TlsUtilities.ReadOpaque8(input); + + /* + * TODO[tls13] required: signature_algorithms; optional: status_request, + * signed_certificate_timestamp, certificate_authorities, oid_filters, + * signature_algorithms_cert + */ + + byte[] extEncoding = TlsUtilities.ReadOpaque16(input); + + IDictionary extensions = TlsProtocol.ReadExtensionsData13(HandshakeType.certificate_request, + extEncoding); + + IList supportedSignatureAlgorithms13 = CheckSupportedSignatureAlgorithms( + TlsExtensionsUtilities.GetSignatureAlgorithmsExtension(extensions), + AlertDescription.missing_extension); + IList supportedSignatureAlgorithmsCert13 = TlsExtensionsUtilities + .GetSignatureAlgorithmsCertExtension(extensions); + IList certificateAuthorities13 = TlsExtensionsUtilities.GetCertificateAuthoritiesExtension(extensions); + + return new CertificateRequest(certificateRequestContext, supportedSignatureAlgorithms13, + supportedSignatureAlgorithmsCert13, certificateAuthorities13); + } + + bool isTLSv12 = TlsUtilities.IsTlsV12(negotiatedVersion); + + short[] certificateTypes = TlsUtilities.ReadUint8ArrayWithUint8Length(input, 1); + + IList supportedSignatureAlgorithms = null; + if (isTLSv12) + { + supportedSignatureAlgorithms = TlsUtilities.ParseSupportedSignatureAlgorithms(input); + } + + IList certificateAuthorities = null; + { + byte[] certAuthData = TlsUtilities.ReadOpaque16(input); + if (certAuthData.Length > 0) + { + certificateAuthorities = Platform.CreateArrayList(); + MemoryStream bis = new MemoryStream(certAuthData, false); + do + { + byte[] derEncoding = TlsUtilities.ReadOpaque16(bis, 1); + Asn1Object asn1 = TlsUtilities.ReadDerObject(derEncoding); + certificateAuthorities.Add(X509Name.GetInstance(asn1)); + } + while (bis.Position < bis.Length); + } + } + + return new CertificateRequest(certificateTypes, supportedSignatureAlgorithms, certificateAuthorities); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertificateRequest.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertificateRequest.cs.meta new file mode 100644 index 0000000..becd4ae --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertificateRequest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6c318c4874b5ffd49a53d8923bd3293c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertificateStatus.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertificateStatus.cs new file mode 100644 index 0000000..61f4336 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertificateStatus.cs @@ -0,0 +1,220 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Ocsp; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls +{ + public sealed class CertificateStatus + { + private readonly short m_statusType; + private readonly object m_response; + + public CertificateStatus(short statusType, object response) + { + if (!IsCorrectType(statusType, response)) + throw new ArgumentException("not an instance of the correct type", "response"); + + this.m_statusType = statusType; + this.m_response = response; + } + + public short StatusType + { + get { return m_statusType; } + } + + public object Response + { + get { return m_response; } + } + + public OcspResponse OcspResponse + { + get + { + if (!IsCorrectType(CertificateStatusType.ocsp, m_response)) + throw new InvalidOperationException("'response' is not an OCSPResponse"); + + return (OcspResponse)m_response; + } + } + + /// an of (possibly null) . + public IList OcspResponseList + { + get + { + if (!IsCorrectType(CertificateStatusType.ocsp_multi, m_response)) + throw new InvalidOperationException("'response' is not an OCSPResponseList"); + + return (IList)m_response; + } + } + + /// Encode this to a . + /// the to encode to. + /// + public void Encode(Stream output) + { + TlsUtilities.WriteUint8(m_statusType, output); + + switch (m_statusType) + { + case CertificateStatusType.ocsp: + { + OcspResponse ocspResponse = (OcspResponse)m_response; + byte[] derEncoding = ocspResponse.GetEncoded(Asn1Encodable.Der); + TlsUtilities.WriteOpaque24(derEncoding, output); + break; + } + case CertificateStatusType.ocsp_multi: + { + IList ocspResponseList = (IList)m_response; + int count = ocspResponseList.Count; + + IList derEncodings = Platform.CreateArrayList(count); + long totalLength = 0; + foreach (OcspResponse ocspResponse in ocspResponseList) + { + if (ocspResponse == null) + { + derEncodings.Add(TlsUtilities.EmptyBytes); + } + else + { + byte[] derEncoding = ocspResponse.GetEncoded(Asn1Encodable.Der); + derEncodings.Add(derEncoding); + totalLength += derEncoding.Length; + } + totalLength += 3; + } + + TlsUtilities.CheckUint24(totalLength); + TlsUtilities.WriteUint24((int)totalLength, output); + + foreach (byte[] derEncoding in derEncodings) + { + TlsUtilities.WriteOpaque24(derEncoding, output); + } + + break; + } + default: + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + /// Parse a from a . + /// the of the current connection. + /// the to parse from. + /// a object. + /// + public static CertificateStatus Parse(TlsContext context, Stream input) + { + SecurityParameters securityParameters = context.SecurityParameters; + + Certificate peerCertificate = securityParameters.PeerCertificate; + if (null == peerCertificate || peerCertificate.IsEmpty + || CertificateType.X509 != peerCertificate.CertificateType) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + int certificateCount = peerCertificate.Length; + int statusRequestVersion = securityParameters.StatusRequestVersion; + + short status_type = TlsUtilities.ReadUint8(input); + object response; + + switch (status_type) + { + case CertificateStatusType.ocsp: + { + RequireStatusRequestVersion(1, statusRequestVersion); + + byte[] derEncoding = TlsUtilities.ReadOpaque24(input, 1); + Asn1Object derObject = TlsUtilities.ReadDerObject(derEncoding); + response = OcspResponse.GetInstance(derObject); + break; + } + case CertificateStatusType.ocsp_multi: + { + RequireStatusRequestVersion(2, statusRequestVersion); + + byte[] ocsp_response_list = TlsUtilities.ReadOpaque24(input, 1); + MemoryStream buf = new MemoryStream(ocsp_response_list, false); + + IList ocspResponseList = Platform.CreateArrayList(); + while (buf.Position < buf.Length) + { + if (ocspResponseList.Count >= certificateCount) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + int length = TlsUtilities.ReadUint24(buf); + if (length < 1) + { + ocspResponseList.Add(null); + } + else + { + byte[] derEncoding = TlsUtilities.ReadFully(length, buf); + Asn1Object derObject = TlsUtilities.ReadDerObject(derEncoding); + OcspResponse ocspResponse = OcspResponse.GetInstance(derObject); + ocspResponseList.Add(ocspResponse); + } + } + + // Match IList capacity to actual size + response = Platform.CreateArrayList(ocspResponseList); + break; + } + default: + throw new TlsFatalAlert(AlertDescription.decode_error); + } + + return new CertificateStatus(status_type, response); + } + + private static bool IsCorrectType(short statusType, Object response) + { + switch (statusType) + { + case CertificateStatusType.ocsp: + return response is OcspResponse; + case CertificateStatusType.ocsp_multi: + return IsOcspResponseList(response); + default: + throw new ArgumentException("unsupported CertificateStatusType", "statusType"); + } + } + + private static bool IsOcspResponseList(object response) + { + if (!(response is IList)) + return false; + + IList v = (IList)response; + int count = v.Count; + if (count < 1) + return false; + + foreach (object e in v) + { + if (null != e && !(e is OcspResponse)) + return false; + } + return true; + } + + /// + private static void RequireStatusRequestVersion(int minVersion, int statusRequestVersion) + { + if (statusRequestVersion < minVersion) + throw new TlsFatalAlert(AlertDescription.decode_error); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertificateStatus.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertificateStatus.cs.meta new file mode 100644 index 0000000..c009a13 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertificateStatus.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9224b551ec73d864a93fced11a59617d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertificateStatusRequest.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertificateStatusRequest.cs new file mode 100644 index 0000000..4731316 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertificateStatusRequest.cs @@ -0,0 +1,91 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Tls +{ + /// Implementation of the RFC 3546 3.6. CertificateStatusRequest. + public sealed class CertificateStatusRequest + { + private short m_statusType; + private object m_request; + + public CertificateStatusRequest(short statusType, object request) + { + if (!IsCorrectType(statusType, request)) + throw new ArgumentException("not an instance of the correct type", "request"); + + this.m_statusType = statusType; + this.m_request = request; + } + + public short StatusType + { + get { return m_statusType; } + } + + public object Request + { + get { return m_request; } + } + + public OcspStatusRequest OcspStatusRequest + { + get + { + if (!IsCorrectType(CertificateStatusType.ocsp, m_request)) + throw new InvalidOperationException("'request' is not an OCSPStatusRequest"); + + return (OcspStatusRequest)m_request; + } + } + + /// Encode this to a . + /// the to encode to. + /// + public void Encode(Stream output) + { + TlsUtilities.WriteUint8(m_statusType, output); + + switch (m_statusType) + { + case CertificateStatusType.ocsp: + ((OcspStatusRequest)m_request).Encode(output); + break; + default: + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + /// Parse a from a . + /// the to parse from. + /// a object. + /// + public static CertificateStatusRequest Parse(Stream input) + { + short status_type = TlsUtilities.ReadUint8(input); + object request; + + switch (status_type) + { + case CertificateStatusType.ocsp: + request = OcspStatusRequest.Parse(input); + break; + default: + throw new TlsFatalAlert(AlertDescription.decode_error); + } + + return new CertificateStatusRequest(status_type, request); + } + + private static bool IsCorrectType(short statusType, object request) + { + switch (statusType) + { + case CertificateStatusType.ocsp: + return request is OcspStatusRequest; + default: + throw new ArgumentException("unsupported CertificateStatusType", "statusType"); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertificateStatusRequest.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertificateStatusRequest.cs.meta new file mode 100644 index 0000000..476b91a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertificateStatusRequest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 268a76240cdea72488b0a637ec41f5f1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertificateStatusRequestItemV2.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertificateStatusRequestItemV2.cs new file mode 100644 index 0000000..a30d9ad --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertificateStatusRequestItemV2.cs @@ -0,0 +1,100 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Tls +{ + /// Implementation of the RFC 6961 2.2. CertificateStatusRequestItemV2. + public sealed class CertificateStatusRequestItemV2 + { + private readonly short m_statusType; + private readonly object m_request; + + public CertificateStatusRequestItemV2(short statusType, object request) + { + if (!IsCorrectType(statusType, request)) + throw new ArgumentException("not an instance of the correct type", "request"); + + this.m_statusType = statusType; + this.m_request = request; + } + + public short StatusType + { + get { return m_statusType; } + } + + public object Request + { + get { return m_request; } + } + + public OcspStatusRequest OcspStatusRequest + { + get + { + if (!(m_request is OcspStatusRequest)) + throw new InvalidOperationException("'request' is not an OcspStatusRequest"); + + return (OcspStatusRequest)m_request; + } + } + + /// Encode this to a . + /// the to encode to. + /// + public void Encode(Stream output) + { + TlsUtilities.WriteUint8(m_statusType, output); + + MemoryStream buf = new MemoryStream(); + switch (m_statusType) + { + case CertificateStatusType.ocsp: + case CertificateStatusType.ocsp_multi: + ((OcspStatusRequest)m_request).Encode(buf); + break; + default: + throw new TlsFatalAlert(AlertDescription.internal_error); + } + byte[] requestBytes = buf.ToArray(); + TlsUtilities.WriteOpaque16(requestBytes, output); + } + + /// Parse a from a . + /// the to parse from. + /// a object. + /// + public static CertificateStatusRequestItemV2 Parse(Stream input) + { + short status_type = TlsUtilities.ReadUint8(input); + + object request; + byte[] requestBytes = TlsUtilities.ReadOpaque16(input); + MemoryStream buf = new MemoryStream(requestBytes, false); + switch (status_type) + { + case CertificateStatusType.ocsp: + case CertificateStatusType.ocsp_multi: + request = OcspStatusRequest.Parse(buf); + break; + default: + throw new TlsFatalAlert(AlertDescription.decode_error); + } + TlsProtocol.AssertEmpty(buf); + + return new CertificateStatusRequestItemV2(status_type, request); + } + + private static bool IsCorrectType(short statusType, object request) + { + switch (statusType) + { + case CertificateStatusType.ocsp: + case CertificateStatusType.ocsp_multi: + return request is OcspStatusRequest; + default: + throw new ArgumentException("unsupported CertificateStatusType", "statusType"); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertificateStatusRequestItemV2.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertificateStatusRequestItemV2.cs.meta new file mode 100644 index 0000000..6df77d3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertificateStatusRequestItemV2.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 57b064a360046604bb5657e287a62e04 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertificateStatusType.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertificateStatusType.cs new file mode 100644 index 0000000..bb0c424 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertificateStatusType.cs @@ -0,0 +1,17 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + public abstract class CertificateStatusType + { + /* + * RFC 6066 + */ + public const short ocsp = 1; + + /* + * RFC 6961 + */ + public const short ocsp_multi = 2; + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertificateStatusType.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertificateStatusType.cs.meta new file mode 100644 index 0000000..aa8e343 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertificateStatusType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bd692766b54a2ce4098a0c3c3f565f05 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertificateType.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertificateType.cs new file mode 100644 index 0000000..eed3024 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertificateType.cs @@ -0,0 +1,16 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + /// RFC 6091 + public abstract class CertificateType + { + public const short X509 = 0; + public const short OpenPGP = 1; + + /* + * RFC 7250 + */ + public const short RawPublicKey = 2; + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertificateType.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertificateType.cs.meta new file mode 100644 index 0000000..a33fa7a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertificateType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: aa19883ad2c060542beadcfd9bc11d55 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertificateUrl.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertificateUrl.cs new file mode 100644 index 0000000..d244577 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertificateUrl.cs @@ -0,0 +1,116 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Tls +{ + /// RFC 3546 3.3 + public sealed class CertificateUrl + { + private readonly short m_type; + private readonly IList m_urlAndHashList; + + /// see for valid constants. + /// an of . + public CertificateUrl(short type, IList urlAndHashList) + { + if (!CertChainType.IsValid(type)) + throw new ArgumentException("not a valid CertChainType value", "type"); + if (urlAndHashList == null || urlAndHashList.Count < 1) + throw new ArgumentException("must have length > 0", "urlAndHashList"); + if (type == CertChainType.pkipath && urlAndHashList.Count != 1) + throw new ArgumentException("must contain exactly one entry when type is " + + CertChainType.GetText(type), "urlAndHashList"); + + this.m_type = type; + this.m_urlAndHashList = urlAndHashList; + } + + /// + public short Type + { + get { return m_type; } + } + + /// an of . + public IList UrlAndHashList + { + get { return m_urlAndHashList; } + } + + /// Encode this to a . + /// the to encode to. + /// + public void Encode(Stream output) + { + TlsUtilities.WriteUint8(m_type, output); + + ListBuffer16 buf = new ListBuffer16(); + foreach (UrlAndHash urlAndHash in m_urlAndHashList) + { + urlAndHash.Encode(buf); + } + buf.EncodeTo(output); + } + + /// Parse a from a . + /// the of the current connection. + /// the to parse from. + /// a object. + /// + public static CertificateUrl Parse(TlsContext context, Stream input) + { + short type = TlsUtilities.ReadUint8(input); + if (!CertChainType.IsValid(type)) + throw new TlsFatalAlert(AlertDescription.decode_error); + + int totalLength = TlsUtilities.ReadUint16(input); + if (totalLength < 1) + throw new TlsFatalAlert(AlertDescription.decode_error); + + byte[] urlAndHashListData = TlsUtilities.ReadFully(totalLength, input); + + MemoryStream buf = new MemoryStream(urlAndHashListData, false); + + IList url_and_hash_list = Platform.CreateArrayList(); + while (buf.Position < buf.Length) + { + UrlAndHash url_and_hash = UrlAndHash.Parse(context, buf); + url_and_hash_list.Add(url_and_hash); + } + + if (type == CertChainType.pkipath && url_and_hash_list.Count != 1) + throw new TlsFatalAlert(AlertDescription.decode_error); + + return new CertificateUrl(type, url_and_hash_list); + } + + // TODO Could be more generally useful + internal class ListBuffer16 + : MemoryStream + { + internal ListBuffer16() + { + // Reserve space for length + TlsUtilities.WriteUint16(0, this); + } + + internal void EncodeTo(Stream output) + { + // Patch actual length back in + int length = (int)Length - 2; + TlsUtilities.CheckUint16(length); + + Seek(0L, SeekOrigin.Begin); + TlsUtilities.WriteUint16(length, this); + + Streams.WriteBufTo(this, output); + + Platform.Dispose(this); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertificateUrl.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertificateUrl.cs.meta new file mode 100644 index 0000000..c8ced55 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CertificateUrl.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f7a9d57d98550f74c80d4bea9fbe1a75 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ChangeCipherSpec.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ChangeCipherSpec.cs new file mode 100644 index 0000000..f83fdb4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ChangeCipherSpec.cs @@ -0,0 +1,9 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + public abstract class ChangeCipherSpec + { + public const short change_cipher_spec = 1; + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ChangeCipherSpec.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ChangeCipherSpec.cs.meta new file mode 100644 index 0000000..272b51a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ChangeCipherSpec.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 106aa21760eba064b875df5089472475 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ChannelBinding.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ChannelBinding.cs new file mode 100644 index 0000000..84f8bc4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ChannelBinding.cs @@ -0,0 +1,19 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + /// RFC 5056 + /// + /// Note that the values here are implementation-specific and arbitrary. It is recommended not to depend on the + /// particular values (e.g.serialization). + /// + public abstract class ChannelBinding + { + /* + * RFC 5929 + */ + public const int tls_server_end_point = 0; + public const int tls_unique = 1; + public const int tls_unique_for_telnet = 2; + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ChannelBinding.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ChannelBinding.cs.meta new file mode 100644 index 0000000..1667dac --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ChannelBinding.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d718b9b67bd627e48844a846f9c1c922 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CipherSuite.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CipherSuite.cs new file mode 100644 index 0000000..5c53268 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CipherSuite.cs @@ -0,0 +1,461 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + /// RFC 2246 A.5 + public abstract class CipherSuite + { + public static bool IsScsv(int cipherSuite) + { + switch (cipherSuite) + { + case TLS_EMPTY_RENEGOTIATION_INFO_SCSV: + case TLS_FALLBACK_SCSV: + return true; + default: + return false; + } + } + + public const int TLS_NULL_WITH_NULL_NULL = 0x0000; + public const int TLS_RSA_WITH_NULL_MD5 = 0x0001; + public const int TLS_RSA_WITH_NULL_SHA = 0x0002; + public const int TLS_RSA_EXPORT_WITH_RC4_40_MD5 = 0x0003; + public const int TLS_RSA_WITH_RC4_128_MD5 = 0x0004; + public const int TLS_RSA_WITH_RC4_128_SHA = 0x0005; + public const int TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 = 0x0006; + public const int TLS_RSA_WITH_IDEA_CBC_SHA = 0x0007; + public const int TLS_RSA_EXPORT_WITH_DES40_CBC_SHA = 0x0008; + public const int TLS_RSA_WITH_DES_CBC_SHA = 0x0009; + public const int TLS_RSA_WITH_3DES_EDE_CBC_SHA = 0x000A; + public const int TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA = 0x000B; + public const int TLS_DH_DSS_WITH_DES_CBC_SHA = 0x000C; + public const int TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA = 0x000D; + public const int TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA = 0x000E; + public const int TLS_DH_RSA_WITH_DES_CBC_SHA = 0x000F; + public const int TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA = 0x0010; + public const int TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA = 0x0011; + public const int TLS_DHE_DSS_WITH_DES_CBC_SHA = 0x0012; + public const int TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA = 0x0013; + public const int TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA = 0x0014; + public const int TLS_DHE_RSA_WITH_DES_CBC_SHA = 0x0015; + public const int TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = 0x0016; + public const int TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 = 0x0017; + public const int TLS_DH_anon_WITH_RC4_128_MD5 = 0x0018; + public const int TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA = 0x0019; + public const int TLS_DH_anon_WITH_DES_CBC_SHA = 0x001A; + public const int TLS_DH_anon_WITH_3DES_EDE_CBC_SHA = 0x001B; + + /* + * Note: The cipher suite values { 0x00, 0x1C } and { 0x00, 0x1D } are reserved to avoid + * collision with Fortezza-based cipher suites in SSL 3. + */ + + /* + * RFC 3268 + */ + public const int TLS_RSA_WITH_AES_128_CBC_SHA = 0x002F; + public const int TLS_DH_DSS_WITH_AES_128_CBC_SHA = 0x0030; + public const int TLS_DH_RSA_WITH_AES_128_CBC_SHA = 0x0031; + public const int TLS_DHE_DSS_WITH_AES_128_CBC_SHA = 0x0032; + public const int TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0x0033; + public const int TLS_DH_anon_WITH_AES_128_CBC_SHA = 0x0034; + public const int TLS_RSA_WITH_AES_256_CBC_SHA = 0x0035; + public const int TLS_DH_DSS_WITH_AES_256_CBC_SHA = 0x0036; + public const int TLS_DH_RSA_WITH_AES_256_CBC_SHA = 0x0037; + public const int TLS_DHE_DSS_WITH_AES_256_CBC_SHA = 0x0038; + public const int TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0x0039; + public const int TLS_DH_anon_WITH_AES_256_CBC_SHA = 0x003A; + + /* + * RFC 5932 + */ + public const int TLS_RSA_WITH_CAMELLIA_128_CBC_SHA = 0x0041; + public const int TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA = 0x0042; + public const int TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA = 0x0043; + public const int TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA = 0x0044; + public const int TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA = 0x0045; + public const int TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA = 0x0046; + + public const int TLS_RSA_WITH_CAMELLIA_256_CBC_SHA = 0x0084; + public const int TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA = 0x0085; + public const int TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA = 0x0086; + public const int TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA = 0x0087; + public const int TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA = 0x0088; + public const int TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA = 0x0089; + + public const int TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 0x00BA; + public const int TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256 = 0x00BB; + public const int TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 0x00BC; + public const int TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 = 0x00BD; + public const int TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 0x00BE; + public const int TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256 = 0x00BF; + + public const int TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 = 0x00C0; + public const int TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256 = 0x00C1; + public const int TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256 = 0x00C2; + public const int TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 = 0x00C3; + public const int TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 = 0x00C4; + public const int TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256 = 0x00C5; + + /* + * RFC 4162 + */ + public const int TLS_RSA_WITH_SEED_CBC_SHA = 0x0096; + public const int TLS_DH_DSS_WITH_SEED_CBC_SHA = 0x0097; + public const int TLS_DH_RSA_WITH_SEED_CBC_SHA = 0x0098; + public const int TLS_DHE_DSS_WITH_SEED_CBC_SHA = 0x0099; + public const int TLS_DHE_RSA_WITH_SEED_CBC_SHA = 0x009A; + public const int TLS_DH_anon_WITH_SEED_CBC_SHA = 0x009B; + + /* + * RFC 4279 + */ + public const int TLS_PSK_WITH_RC4_128_SHA = 0x008A; + public const int TLS_PSK_WITH_3DES_EDE_CBC_SHA = 0x008B; + public const int TLS_PSK_WITH_AES_128_CBC_SHA = 0x008C; + public const int TLS_PSK_WITH_AES_256_CBC_SHA = 0x008D; + public const int TLS_DHE_PSK_WITH_RC4_128_SHA = 0x008E; + public const int TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA = 0x008F; + public const int TLS_DHE_PSK_WITH_AES_128_CBC_SHA = 0x0090; + public const int TLS_DHE_PSK_WITH_AES_256_CBC_SHA = 0x0091; + public const int TLS_RSA_PSK_WITH_RC4_128_SHA = 0x0092; + public const int TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA = 0x0093; + public const int TLS_RSA_PSK_WITH_AES_128_CBC_SHA = 0x0094; + public const int TLS_RSA_PSK_WITH_AES_256_CBC_SHA = 0x0095; + + /* + * RFC 4492 + */ + public const int TLS_ECDH_ECDSA_WITH_NULL_SHA = 0xC001; + public const int TLS_ECDH_ECDSA_WITH_RC4_128_SHA = 0xC002; + public const int TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA = 0xC003; + public const int TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA = 0xC004; + public const int TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA = 0xC005; + public const int TLS_ECDHE_ECDSA_WITH_NULL_SHA = 0xC006; + public const int TLS_ECDHE_ECDSA_WITH_RC4_128_SHA = 0xC007; + public const int TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA = 0xC008; + public const int TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA = 0xC009; + public const int TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = 0xC00A; + public const int TLS_ECDH_RSA_WITH_NULL_SHA = 0xC00B; + public const int TLS_ECDH_RSA_WITH_RC4_128_SHA = 0xC00C; + public const int TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA = 0xC00D; + public const int TLS_ECDH_RSA_WITH_AES_128_CBC_SHA = 0xC00E; + public const int TLS_ECDH_RSA_WITH_AES_256_CBC_SHA = 0xC00F; + public const int TLS_ECDHE_RSA_WITH_NULL_SHA = 0xC010; + public const int TLS_ECDHE_RSA_WITH_RC4_128_SHA = 0xC011; + public const int TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA = 0xC012; + public const int TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = 0xC013; + public const int TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xC014; + public const int TLS_ECDH_anon_WITH_NULL_SHA = 0xC015; + public const int TLS_ECDH_anon_WITH_RC4_128_SHA = 0xC016; + public const int TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA = 0xC017; + public const int TLS_ECDH_anon_WITH_AES_128_CBC_SHA = 0xC018; + public const int TLS_ECDH_anon_WITH_AES_256_CBC_SHA = 0xC019; + + /* + * RFC 4785 + */ + public const int TLS_PSK_WITH_NULL_SHA = 0x002C; + public const int TLS_DHE_PSK_WITH_NULL_SHA = 0x002D; + public const int TLS_RSA_PSK_WITH_NULL_SHA = 0x002E; + + /* + * RFC 5054 + */ + public const int TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA = 0xC01A; + public const int TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA = 0xC01B; + public const int TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA = 0xC01C; + public const int TLS_SRP_SHA_WITH_AES_128_CBC_SHA = 0xC01D; + public const int TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA = 0xC01E; + public const int TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA = 0xC01F; + public const int TLS_SRP_SHA_WITH_AES_256_CBC_SHA = 0xC020; + public const int TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA = 0xC021; + public const int TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA = 0xC022; + + /* + * RFC 5246 + */ + public const int TLS_RSA_WITH_NULL_SHA256 = 0x003B; + public const int TLS_RSA_WITH_AES_128_CBC_SHA256 = 0x003C; + public const int TLS_RSA_WITH_AES_256_CBC_SHA256 = 0x003D; + public const int TLS_DH_DSS_WITH_AES_128_CBC_SHA256 = 0x003E; + public const int TLS_DH_RSA_WITH_AES_128_CBC_SHA256 = 0x003F; + public const int TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 = 0x0040; + public const int TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 = 0x0067; + public const int TLS_DH_DSS_WITH_AES_256_CBC_SHA256 = 0x0068; + public const int TLS_DH_RSA_WITH_AES_256_CBC_SHA256 = 0x0069; + public const int TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 = 0x006A; + public const int TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 = 0x006B; + public const int TLS_DH_anon_WITH_AES_128_CBC_SHA256 = 0x006C; + public const int TLS_DH_anon_WITH_AES_256_CBC_SHA256 = 0x006D; + + /* + * RFC 5288 + */ + public const int TLS_RSA_WITH_AES_128_GCM_SHA256 = 0x009C; + public const int TLS_RSA_WITH_AES_256_GCM_SHA384 = 0x009D; + public const int TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 = 0x009E; + public const int TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 = 0x009F; + public const int TLS_DH_RSA_WITH_AES_128_GCM_SHA256 = 0x00A0; + public const int TLS_DH_RSA_WITH_AES_256_GCM_SHA384 = 0x00A1; + public const int TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 = 0x00A2; + public const int TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 = 0x00A3; + public const int TLS_DH_DSS_WITH_AES_128_GCM_SHA256 = 0x00A4; + public const int TLS_DH_DSS_WITH_AES_256_GCM_SHA384 = 0x00A5; + public const int TLS_DH_anon_WITH_AES_128_GCM_SHA256 = 0x00A6; + public const int TLS_DH_anon_WITH_AES_256_GCM_SHA384 = 0x00A7; + + /* + * RFC 5289 + */ + public const int TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 = 0xC023; + public const int TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 = 0xC024; + public const int TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 = 0xC025; + public const int TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 = 0xC026; + public const int TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 = 0xC027; + public const int TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 = 0xC028; + public const int TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 = 0xC029; + public const int TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 = 0xC02A; + public const int TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02B; + public const int TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = 0xC02C; + public const int TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02D; + public const int TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 = 0xC02E; + public const int TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xC02F; + public const int TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = 0xC030; + public const int TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 = 0xC031; + public const int TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 = 0xC032; + + /* + * RFC 5487 + */ + public const int TLS_PSK_WITH_AES_128_GCM_SHA256 = 0x00A8; + public const int TLS_PSK_WITH_AES_256_GCM_SHA384 = 0x00A9; + public const int TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 = 0x00AA; + public const int TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 = 0x00AB; + public const int TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 = 0x00AC; + public const int TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 = 0x00AD; + public const int TLS_PSK_WITH_AES_128_CBC_SHA256 = 0x00AE; + public const int TLS_PSK_WITH_AES_256_CBC_SHA384 = 0x00AF; + public const int TLS_PSK_WITH_NULL_SHA256 = 0x00B0; + public const int TLS_PSK_WITH_NULL_SHA384 = 0x00B1; + public const int TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 = 0x00B2; + public const int TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 = 0x00B3; + public const int TLS_DHE_PSK_WITH_NULL_SHA256 = 0x00B4; + public const int TLS_DHE_PSK_WITH_NULL_SHA384 = 0x00B5; + public const int TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 = 0x00B6; + public const int TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 = 0x00B7; + public const int TLS_RSA_PSK_WITH_NULL_SHA256 = 0x00B8; + public const int TLS_RSA_PSK_WITH_NULL_SHA384 = 0x00B9; + + /* + * RFC 5489 + */ + public const int TLS_ECDHE_PSK_WITH_RC4_128_SHA = 0xC033; + public const int TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA = 0xC034; + public const int TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA = 0xC035; + public const int TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA = 0xC036; + public const int TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 = 0xC037; + public const int TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 = 0xC038; + public const int TLS_ECDHE_PSK_WITH_NULL_SHA = 0xC039; + public const int TLS_ECDHE_PSK_WITH_NULL_SHA256 = 0xC03A; + public const int TLS_ECDHE_PSK_WITH_NULL_SHA384 = 0xC03B; + + /* + * RFC 5746 + */ + public const int TLS_EMPTY_RENEGOTIATION_INFO_SCSV = 0x00FF; + + /* + * RFC 6209 + */ + public const int TLS_RSA_WITH_ARIA_128_CBC_SHA256 = 0xC03C; + public const int TLS_RSA_WITH_ARIA_256_CBC_SHA384 = 0xC03D; + public const int TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256 = 0xC03E; + public const int TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384 = 0xC03F; + public const int TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256 = 0xC040; + public const int TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384 = 0xC041; + public const int TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256 = 0xC042; + public const int TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384 = 0xC043; + public const int TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256 = 0xC044; + public const int TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384 = 0xC045; + public const int TLS_DH_anon_WITH_ARIA_128_CBC_SHA256 = 0xC046; + public const int TLS_DH_anon_WITH_ARIA_256_CBC_SHA384 = 0xC047; + + public const int TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256 = 0xC048; + public const int TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384 = 0xC049; + public const int TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256 = 0xC04A; + public const int TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384 = 0xC04B; + public const int TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256 = 0xC04C; + public const int TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384 = 0xC04D; + public const int TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256 = 0xC04E; + public const int TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384 = 0xC04F; + + public const int TLS_RSA_WITH_ARIA_128_GCM_SHA256 = 0xC050; + public const int TLS_RSA_WITH_ARIA_256_GCM_SHA384 = 0xC051; + public const int TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256 = 0xC052; + public const int TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384 = 0xC053; + public const int TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256 = 0xC054; + public const int TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384 = 0xC055; + public const int TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256 = 0xC056; + public const int TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384 = 0xC057; + public const int TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256 = 0xC058; + public const int TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384 = 0xC059; + public const int TLS_DH_anon_WITH_ARIA_128_GCM_SHA256 = 0xC05A; + public const int TLS_DH_anon_WITH_ARIA_256_GCM_SHA384 = 0xC05B; + + public const int TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 = 0xC05C; + public const int TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 = 0xC05D; + public const int TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 = 0xC05E; + public const int TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 = 0xC05F; + public const int TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256 = 0xC060; + public const int TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384 = 0xC061; + public const int TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 = 0xC062; + public const int TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 = 0xC063; + + public const int TLS_PSK_WITH_ARIA_128_CBC_SHA256 = 0xC064; + public const int TLS_PSK_WITH_ARIA_256_CBC_SHA384 = 0xC065; + public const int TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256 = 0xC066; + public const int TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384 = 0xC067; + public const int TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256 = 0xC068; + public const int TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384 = 0xC069; + public const int TLS_PSK_WITH_ARIA_128_GCM_SHA256 = 0xC06A; + public const int TLS_PSK_WITH_ARIA_256_GCM_SHA384 = 0xC06B; + public const int TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256 = 0xC06C; + public const int TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384 = 0xC06D; + public const int TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256 = 0xC06E; + public const int TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384 = 0xC06F; + public const int TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256 = 0xC070; + public const int TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384 = 0xC071; + + /* + * RFC 6367 + */ + public const int TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 = 0xC072; + public const int TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 = 0xC073; + public const int TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 = 0xC074; + public const int TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 = 0xC075; + public const int TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 0xC076; + public const int TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 = 0xC077; + public const int TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 0xC078; + public const int TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 = 0xC079; + + public const int TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC07A; + public const int TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC07B; + public const int TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC07C; + public const int TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC07D; + public const int TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC07E; + public const int TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC07F; + public const int TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256 = 0xC080; + public const int TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384 = 0xC081; + public const int TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256 = 0xC082; + public const int TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384 = 0xC083; + public const int TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256 = 0xC084; + public const int TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384 = 0xC085; + public const int TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC086; + public const int TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC087; + public const int TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC088; + public const int TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC089; + public const int TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC08A; + public const int TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC08B; + public const int TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC08C; + public const int TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC08D; + + public const int TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 = 0xC08E; + public const int TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 = 0xC08F; + public const int TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 = 0xC090; + public const int TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 = 0xC091; + public const int TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 = 0xC092; + public const int TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 = 0xC093; + public const int TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 = 0xC094; + public const int TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 = 0xC095; + public const int TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 = 0xC096; + public const int TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 = 0xC097; + public const int TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 = 0xC098; + public const int TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 = 0xC099; + public const int TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 = 0xC09A; + public const int TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 = 0xC09B; + + /* + * RFC 6655 + */ + public const int TLS_RSA_WITH_AES_128_CCM = 0xC09C; + public const int TLS_RSA_WITH_AES_256_CCM = 0xC09D; + public const int TLS_DHE_RSA_WITH_AES_128_CCM = 0xC09E; + public const int TLS_DHE_RSA_WITH_AES_256_CCM = 0xC09F; + public const int TLS_RSA_WITH_AES_128_CCM_8 = 0xC0A0; + public const int TLS_RSA_WITH_AES_256_CCM_8 = 0xC0A1; + public const int TLS_DHE_RSA_WITH_AES_128_CCM_8 = 0xC0A2; + public const int TLS_DHE_RSA_WITH_AES_256_CCM_8 = 0xC0A3; + public const int TLS_PSK_WITH_AES_128_CCM = 0xC0A4; + public const int TLS_PSK_WITH_AES_256_CCM = 0xC0A5; + public const int TLS_DHE_PSK_WITH_AES_128_CCM = 0xC0A6; + public const int TLS_DHE_PSK_WITH_AES_256_CCM = 0xC0A7; + public const int TLS_PSK_WITH_AES_128_CCM_8 = 0xC0A8; + public const int TLS_PSK_WITH_AES_256_CCM_8 = 0xC0A9; + public const int TLS_PSK_DHE_WITH_AES_128_CCM_8 = 0xC0AA; + public const int TLS_PSK_DHE_WITH_AES_256_CCM_8 = 0xC0AB; + + /* + * RFC 7251 + */ + public const int TLS_ECDHE_ECDSA_WITH_AES_128_CCM = 0xC0AC; + public const int TLS_ECDHE_ECDSA_WITH_AES_256_CCM = 0xC0AD; + public const int TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 = 0xC0AE; + public const int TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 = 0xC0AF; + + /* + * RFC 7507 + */ + public const int TLS_FALLBACK_SCSV = 0x5600; + + /* + * RFC 7905 + */ + public const int TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCA8; + public const int TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCA9; + public const int TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAA; + public const int TLS_PSK_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAB; + public const int TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAC; + public const int TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAD; + public const int TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAE; + + /* + * RFC 8442 + */ + public const int TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256 = 0xD001; + public const int TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384 = 0xD002; + public const int TLS_ECDHE_PSK_WITH_AES_128_CCM_8_SHA256 = 0xD003; + public const int TLS_ECDHE_PSK_WITH_AES_128_CCM_SHA256 = 0xD005; + + /* + * TLS 1.3 Section + * + * Although TLS 1.3 uses the same cipher suite space as previous versions of TLS, TLS 1.3 cipher + * suites are defined differently, only specifying the symmetric ciphers, and cannot be used for + * TLS 1.2. Similarly, cipher suites for TLS 1.2 and lower cannot be used with TLS 1.3. + */ + + /* + * RFC 8446 + */ + public const int TLS_AES_128_GCM_SHA256 = 0x1301; + public const int TLS_AES_256_GCM_SHA384 = 0x1302; + public const int TLS_CHACHA20_POLY1305_SHA256 = 0x1303; + public const int TLS_AES_128_CCM_SHA256 = 0x1304; + public const int TLS_AES_128_CCM_8_SHA256 = 0x1305; + + /* + * RFC 8998 + */ + public const int TLS_SM4_GCM_SM3 = 0x00C6; + public const int TLS_SM4_CCM_SM3 = 0x00C7; + + /* + * draft-smyshlyaev-tls12-gost-suites-10 + */ + public const int TLS_GOSTR341112_256_WITH_KUZNYECHIK_CTR_OMAC = 0xC100; + public const int TLS_GOSTR341112_256_WITH_MAGMA_CTR_OMAC = 0xC101; + public const int TLS_GOSTR341112_256_WITH_28147_CNT_IMIT = 0xC102; + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CipherSuite.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CipherSuite.cs.meta new file mode 100644 index 0000000..3540b4d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CipherSuite.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 43eed3f4d4e7c7840817f6fa169eb7a3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CipherType.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CipherType.cs new file mode 100644 index 0000000..3525960 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CipherType.cs @@ -0,0 +1,20 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + /// RFC 2246 + /// + /// Note that the values here are implementation-specific and arbitrary. It is recommended not to depend on the + /// particular values (e.g. serialization). + /// + public abstract class CipherType + { + public const int stream = 0; + public const int block = 1; + + /* + * RFC 5246 + */ + public const int aead = 2; + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CipherType.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CipherType.cs.meta new file mode 100644 index 0000000..2802b34 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CipherType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 34f1acab72ac5bd43a1320a905054e12 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ClientAuthenticationType.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ClientAuthenticationType.cs new file mode 100644 index 0000000..2166e97 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ClientAuthenticationType.cs @@ -0,0 +1,14 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + public abstract class ClientAuthenticationType + { + /* + * RFC 5077 4 + */ + public const short anonymous = 0; + public const short certificate_based = 1; + public const short psk = 2; + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ClientAuthenticationType.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ClientAuthenticationType.cs.meta new file mode 100644 index 0000000..f8304f0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ClientAuthenticationType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4c516cfed213bad488094d686f57b4ff +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ClientCertificateType.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ClientCertificateType.cs new file mode 100644 index 0000000..f3a4a08 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ClientCertificateType.cs @@ -0,0 +1,69 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + public abstract class ClientCertificateType + { + /* + * RFC 4346 7.4.4 + */ + public const short rsa_sign = 1; + public const short dss_sign = 2; + public const short rsa_fixed_dh = 3; + public const short dss_fixed_dh = 4; + public const short rsa_ephemeral_dh_RESERVED = 5; + public const short dss_ephemeral_dh_RESERVED = 6; + public const short fortezza_dms_RESERVED = 20; + + /* + * RFC 4492 5.5 + */ + public const short ecdsa_sign = 64; + public const short rsa_fixed_ecdh = 65; + public const short ecdsa_fixed_ecdh = 66; + + /* + * draft-smyshlyaev-tls12-gost-suites-10 + */ + public const short gost_sign256 = 67; + public const short gost_sign512 = 68; + + public static string GetName(short clientCertificateType) + { + switch (clientCertificateType) + { + case rsa_sign: + return "rsa_sign"; + case dss_sign: + return "dss_sign"; + case rsa_fixed_dh: + return "rsa_fixed_dh"; + case dss_fixed_dh: + return "dss_fixed_dh"; + case rsa_ephemeral_dh_RESERVED: + return "rsa_ephemeral_dh_RESERVED"; + case dss_ephemeral_dh_RESERVED: + return "dss_ephemeral_dh_RESERVED"; + case fortezza_dms_RESERVED: + return "fortezza_dms_RESERVED"; + case ecdsa_sign: + return "ecdsa_sign"; + case rsa_fixed_ecdh: + return "rsa_fixed_ecdh"; + case ecdsa_fixed_ecdh: + return "ecdsa_fixed_ecdh"; + case gost_sign256: + return "gost_sign256"; + case gost_sign512: + return "gost_sign512"; + default: + return "UNKNOWN"; + } + } + + public static string GetText(short clientCertificateType) + { + return GetName(clientCertificateType) + "(" + clientCertificateType + ")"; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ClientCertificateType.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ClientCertificateType.cs.meta new file mode 100644 index 0000000..73f35a9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ClientCertificateType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 655db407abcca1c41807a1551b6a796d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ClientHello.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ClientHello.cs new file mode 100644 index 0000000..7f1018e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ClientHello.cs @@ -0,0 +1,177 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Tls +{ + public sealed class ClientHello + { + private readonly ProtocolVersion m_version; + private readonly byte[] m_random; + private readonly byte[] m_sessionID; + private readonly byte[] m_cookie; + private readonly int[] m_cipherSuites; + private readonly IDictionary m_extensions; + private readonly int m_bindersSize; + + public ClientHello(ProtocolVersion version, byte[] random, byte[] sessionID, byte[] cookie, + int[] cipherSuites, IDictionary extensions, int bindersSize) + { + this.m_version = version; + this.m_random = random; + this.m_sessionID = sessionID; + this.m_cookie = cookie; + this.m_cipherSuites = cipherSuites; + this.m_extensions = extensions; + this.m_bindersSize = bindersSize; + } + + public int BindersSize + { + get { return m_bindersSize; } + } + + public int[] CipherSuites + { + get { return m_cipherSuites; } + } + + public byte[] Cookie + { + get { return m_cookie; } + } + + public IDictionary Extensions + { + get { return m_extensions; } + } + + public byte[] Random + { + get { return m_random; } + } + + public byte[] SessionID + { + get { return m_sessionID; } + } + + public ProtocolVersion Version + { + get { return m_version; } + } + + /// Encode this to a . + /// the of the current connection. + /// the to encode to. + /// + public void Encode(TlsContext context, Stream output) + { + if (m_bindersSize < 0) + throw new TlsFatalAlert(AlertDescription.internal_error); + + TlsUtilities.WriteVersion(m_version, output); + + output.Write(m_random, 0, m_random.Length); + + TlsUtilities.WriteOpaque8(m_sessionID, output); + + if (null != m_cookie) + { + TlsUtilities.WriteOpaque8(m_cookie, output); + } + + TlsUtilities.WriteUint16ArrayWithUint16Length(m_cipherSuites, output); + + TlsUtilities.WriteUint8ArrayWithUint8Length(new short[]{ CompressionMethod.cls_null }, output); + + TlsProtocol.WriteExtensions(output, m_extensions, m_bindersSize); + } + + /// Parse a from a . + /// the to parse from. + /// for DTLS this should be non-null; the input is copied to this + /// , minus the cookie field. + /// a object. + /// + public static ClientHello Parse(MemoryStream messageInput, Stream dtlsOutput) + { + try + { + return ImplParse(messageInput, dtlsOutput); + } + catch (TlsFatalAlert e) + { + throw e; + } + catch (IOException e) + { + throw new TlsFatalAlert(AlertDescription.decode_error, e); + } + } + + /// + private static ClientHello ImplParse(MemoryStream messageInput, Stream dtlsOutput) + { + Stream input = messageInput; + if (null != dtlsOutput) + { + input = new TeeInputStream(input, dtlsOutput); + } + + ProtocolVersion clientVersion = TlsUtilities.ReadVersion(input); + + byte[] random = TlsUtilities.ReadFully(32, input); + + byte[] sessionID = TlsUtilities.ReadOpaque8(input, 0, 32); + + byte[] cookie = null; + if (null != dtlsOutput) + { + /* + * RFC 6347 This specification increases the cookie size limit to 255 bytes for greater + * future flexibility. The limit remains 32 for previous versions of DTLS. + */ + int maxCookieLength = ProtocolVersion.DTLSv12.IsEqualOrEarlierVersionOf(clientVersion) ? 255 : 32; + + cookie = TlsUtilities.ReadOpaque8(messageInput, 0, maxCookieLength); + } + + int cipher_suites_length = TlsUtilities.ReadUint16(input); + if (cipher_suites_length < 2 || (cipher_suites_length & 1) != 0 + || (int)(messageInput.Length - messageInput.Position) < cipher_suites_length) + { + throw new TlsFatalAlert(AlertDescription.decode_error); + } + + /* + * NOTE: "If the session_id field is not empty (implying a session resumption request) this + * vector must include at least the cipher_suite from that session." + */ + int[] cipherSuites = TlsUtilities.ReadUint16Array(cipher_suites_length / 2, input); + + short[] compressionMethods = TlsUtilities.ReadUint8ArrayWithUint8Length(input, 1); + if (!Arrays.Contains(compressionMethods, CompressionMethod.cls_null)) + throw new TlsFatalAlert(AlertDescription.handshake_failure); + + /* + * NOTE: Can't use TlsProtocol.ReadExtensions directly because TeeInputStream a) won't have + * 'Length' or 'Position' properties in the FIPS provider, b) isn't a MemoryStream. + */ + IDictionary extensions = null; + if (messageInput.Position < messageInput.Length) + { + byte[] extBytes = TlsUtilities.ReadOpaque16(input); + + TlsProtocol.AssertEmpty(messageInput); + + extensions = TlsProtocol.ReadExtensionsDataClientHello(extBytes); + } + + return new ClientHello(clientVersion, random, sessionID, cookie, cipherSuites, extensions, -1); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ClientHello.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ClientHello.cs.meta new file mode 100644 index 0000000..e696bcf --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ClientHello.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 10b9e3512aa343a4f83616fc6aeb38ac +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CombinedHash.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CombinedHash.cs new file mode 100644 index 0000000..71151d2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CombinedHash.cs @@ -0,0 +1,67 @@ +using System; + +using Org.BouncyCastle.Tls.Crypto; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls +{ + /// A combined hash, which implements md5(m) || sha1(m). + public class CombinedHash + : TlsHash + { + protected readonly TlsContext m_context; + protected readonly TlsCrypto m_crypto; + protected readonly TlsHash m_md5; + protected readonly TlsHash m_sha1; + + internal CombinedHash(TlsContext context, TlsHash md5, TlsHash sha1) + { + this.m_context = context; + this.m_crypto = context.Crypto; + this.m_md5 = md5; + this.m_sha1 = sha1; + } + + public CombinedHash(TlsCrypto crypto) + { + this.m_crypto = crypto; + this.m_md5 = crypto.CreateHash(CryptoHashAlgorithm.md5); + this.m_sha1 = crypto.CreateHash(CryptoHashAlgorithm.sha1); + } + + public CombinedHash(CombinedHash t) + { + this.m_context = t.m_context; + this.m_crypto = t.m_crypto; + this.m_md5 = t.m_md5.CloneHash(); + this.m_sha1 = t.m_sha1.CloneHash(); + } + + public virtual void Update(byte[] input, int inOff, int len) + { + m_md5.Update(input, inOff, len); + m_sha1.Update(input, inOff, len); + } + + public virtual byte[] CalculateHash() + { + if (null != m_context && TlsUtilities.IsSsl(m_context)) + { + Ssl3Utilities.CompleteCombinedHash(m_context, m_md5, m_sha1); + } + + return Arrays.Concatenate(m_md5.CalculateHash(), m_sha1.CalculateHash()); + } + + public virtual TlsHash CloneHash() + { + return new CombinedHash(this); + } + + public virtual void Reset() + { + m_md5.Reset(); + m_sha1.Reset(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CombinedHash.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CombinedHash.cs.meta new file mode 100644 index 0000000..88ee91b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CombinedHash.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d856445dc7adaec4f8d0779c221ab674 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CompressionMethod.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CompressionMethod.cs new file mode 100644 index 0000000..21b43d4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CompressionMethod.cs @@ -0,0 +1,20 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + /// RFC 2246 6.1 + public abstract class CompressionMethod + { + public const short cls_null = 0; + + /* + * RFC 3749 2 + */ + public const short DEFLATE = 1; + + /* + * Values from 224 decimal (0xE0) through 255 decimal (0xFF) + * inclusive are reserved for private use. + */ + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CompressionMethod.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CompressionMethod.cs.meta new file mode 100644 index 0000000..e7ef325 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/CompressionMethod.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6af598f4e9418d64fbf8f8c85b5aab76 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ConnectionEnd.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ConnectionEnd.cs new file mode 100644 index 0000000..01ceb1b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ConnectionEnd.cs @@ -0,0 +1,15 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + /// RFC 2246 + /// + /// Note that the values here are implementation-specific and arbitrary. It is recommended not to depend on the + /// particular values(e.g.serialization). + /// + public abstract class ConnectionEnd + { + public const int server = 0; + public const int client = 1; + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ConnectionEnd.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ConnectionEnd.cs.meta new file mode 100644 index 0000000..6e0c467 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ConnectionEnd.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ffb76a1a0ccea304bbb7787a0670caea +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ContentType.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ContentType.cs new file mode 100644 index 0000000..cf89539 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ContentType.cs @@ -0,0 +1,38 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + /// RFC 2246 6.2.1 + public abstract class ContentType + { + public const short change_cipher_spec = 20; + public const short alert = 21; + public const short handshake = 22; + public const short application_data = 23; + public const short heartbeat = 24; + + public static string GetName(short contentType) + { + switch (contentType) + { + case alert: + return "alert"; + case application_data: + return "application_data"; + case change_cipher_spec: + return "change_cipher_spec"; + case handshake: + return "handshake"; + case heartbeat: + return "heartbeat"; + default: + return "UNKNOWN"; + } + } + + public static string GetText(short contentType) + { + return GetName(contentType) + "(" + contentType + ")"; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ContentType.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ContentType.cs.meta new file mode 100644 index 0000000..a5caa5b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ContentType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 55ee3c4a87c75ef4bbb0cbc961e1bf37 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DatagramReceiver.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DatagramReceiver.cs new file mode 100644 index 0000000..5ab605a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DatagramReceiver.cs @@ -0,0 +1,14 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Tls +{ + public interface DatagramReceiver + { + /// + int GetReceiveLimit(); + + /// + int Receive(byte[] buf, int off, int len, int waitMillis); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DatagramReceiver.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DatagramReceiver.cs.meta new file mode 100644 index 0000000..f4f6362 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DatagramReceiver.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fa769140f7d64be49bd043be2154f047 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DatagramSender.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DatagramSender.cs new file mode 100644 index 0000000..bf14c18 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DatagramSender.cs @@ -0,0 +1,14 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Tls +{ + public interface DatagramSender + { + /// + int GetSendLimit(); + + /// + void Send(byte[] buf, int off, int len); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DatagramSender.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DatagramSender.cs.meta new file mode 100644 index 0000000..bff3c57 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DatagramSender.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4e09b23e2275e5d4eb3a3d334c8d7512 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DatagramTransport.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DatagramTransport.cs new file mode 100644 index 0000000..4aecd05 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DatagramTransport.cs @@ -0,0 +1,10 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + /// Base interface for an object sending and receiving DTLS data. + public interface DatagramTransport + : DatagramReceiver, DatagramSender, TlsCloseable + { + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DatagramTransport.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DatagramTransport.cs.meta new file mode 100644 index 0000000..038214c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DatagramTransport.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0c5b40b183ccffc40a892d7d147c60a6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DefaultTlsClient.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DefaultTlsClient.cs new file mode 100644 index 0000000..a2a7426 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DefaultTlsClient.cs @@ -0,0 +1,48 @@ +using System; + +using Org.BouncyCastle.Tls.Crypto; + +namespace Org.BouncyCastle.Tls +{ + public abstract class DefaultTlsClient + : AbstractTlsClient + { + private static readonly int[] DefaultCipherSuites = new int[] + { + /* + * TODO[tls13] TLS 1.3 + */ + //CipherSuite.TLS_CHACHA20_POLY1305_SHA256, + //CipherSuite.TLS_AES_128_GCM_SHA256, + + /* + * pre-TLS 1.3 + */ + CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, + CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, + CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, + CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, + CipherSuite.TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, + CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, + CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA, + CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256, + CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256, + CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, + }; + + public DefaultTlsClient(TlsCrypto crypto) + : base(crypto) + { + } + + protected override int[] GetSupportedCipherSuites() + { + return TlsUtilities.GetSupportedCipherSuites(Crypto, DefaultCipherSuites); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DefaultTlsClient.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DefaultTlsClient.cs.meta new file mode 100644 index 0000000..4b24a84 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DefaultTlsClient.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8072340b27adc674cbdef0e6c601ec49 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DefaultTlsCredentialedSigner.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DefaultTlsCredentialedSigner.cs new file mode 100644 index 0000000..64bc30a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DefaultTlsCredentialedSigner.cs @@ -0,0 +1,66 @@ +using System; + +using Org.BouncyCastle.Tls.Crypto; +using Org.BouncyCastle.Tls.Crypto.Impl; + +namespace Org.BouncyCastle.Tls +{ + /// Container class for generating signatures that carries the signature type, parameters, public key + /// certificate and public key's associated signer object. + public class DefaultTlsCredentialedSigner + : TlsCredentialedSigner + { + protected readonly TlsCryptoParameters m_cryptoParams; + protected readonly Certificate m_certificate; + protected readonly SignatureAndHashAlgorithm m_signatureAndHashAlgorithm; + protected readonly TlsSigner m_signer; + + public DefaultTlsCredentialedSigner(TlsCryptoParameters cryptoParams, TlsSigner signer, + Certificate certificate, SignatureAndHashAlgorithm signatureAndHashAlgorithm) + { + if (certificate == null) + throw new ArgumentNullException("certificate"); + if (certificate.IsEmpty) + throw new ArgumentException("cannot be empty", "certificate"); + if (signer == null) + throw new ArgumentNullException("signer"); + + this.m_cryptoParams = cryptoParams; + this.m_certificate = certificate; + this.m_signatureAndHashAlgorithm = signatureAndHashAlgorithm; + this.m_signer = signer; + } + + public virtual Certificate Certificate + { + get { return m_certificate; } + } + + public virtual byte[] GenerateRawSignature(byte[] hash) + { + return m_signer.GenerateRawSignature(GetEffectiveAlgorithm(), hash); + } + + public virtual SignatureAndHashAlgorithm SignatureAndHashAlgorithm + { + get { return m_signatureAndHashAlgorithm; } + } + + public virtual TlsStreamSigner GetStreamSigner() + { + return m_signer.GetStreamSigner(GetEffectiveAlgorithm()); + } + + protected virtual SignatureAndHashAlgorithm GetEffectiveAlgorithm() + { + SignatureAndHashAlgorithm algorithm = null; + if (TlsImplUtilities.IsTlsV12(m_cryptoParams)) + { + algorithm = SignatureAndHashAlgorithm; + if (algorithm == null) + throw new InvalidOperationException("'signatureAndHashAlgorithm' cannot be null for (D)TLS 1.2+"); + } + return algorithm; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DefaultTlsCredentialedSigner.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DefaultTlsCredentialedSigner.cs.meta new file mode 100644 index 0000000..9762a61 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DefaultTlsCredentialedSigner.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 90ce4cbd3369ac94dba4ec04e59b4c36 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DefaultTlsDHGroupVerifier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DefaultTlsDHGroupVerifier.cs new file mode 100644 index 0000000..8b9cf2e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DefaultTlsDHGroupVerifier.cs @@ -0,0 +1,107 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Tls.Crypto; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls +{ + public class DefaultTlsDHGroupVerifier + : TlsDHGroupVerifier + { + public static readonly int DefaultMinimumPrimeBits = 2048; + + private static readonly IList DefaultGroups = Platform.CreateArrayList(); + + private static void AddDefaultGroup(DHGroup dhGroup) + { + DefaultGroups.Add(dhGroup); + } + + static DefaultTlsDHGroupVerifier() + { + /* + * These 10 standard groups are those specified in NIST SP 800-56A Rev. 3 Appendix D. Make + * sure to consider the impact on BCJSSE's FIPS mode and/or usage with the BCFIPS provider + * before modifying this list. + */ + + AddDefaultGroup(DHStandardGroups.rfc3526_2048); + AddDefaultGroup(DHStandardGroups.rfc3526_3072); + AddDefaultGroup(DHStandardGroups.rfc3526_4096); + AddDefaultGroup(DHStandardGroups.rfc3526_6144); + AddDefaultGroup(DHStandardGroups.rfc3526_8192); + + AddDefaultGroup(DHStandardGroups.rfc7919_ffdhe2048); + AddDefaultGroup(DHStandardGroups.rfc7919_ffdhe3072); + AddDefaultGroup(DHStandardGroups.rfc7919_ffdhe4096); + AddDefaultGroup(DHStandardGroups.rfc7919_ffdhe6144); + AddDefaultGroup(DHStandardGroups.rfc7919_ffdhe8192); + } + + // IList is (DHGroup) + protected readonly IList m_groups; + protected readonly int m_minimumPrimeBits; + + /// Accept named groups and various standard DH groups with 'P' at least + /// bits. + public DefaultTlsDHGroupVerifier() + : this(DefaultMinimumPrimeBits) + { + } + + /// Accept named groups and various standard DH groups with 'P' at least the specified number of bits. + /// + /// the minimum bitlength of 'P'. + public DefaultTlsDHGroupVerifier(int minimumPrimeBits) + : this(DefaultGroups, minimumPrimeBits) + { + } + + /// Accept named groups and a custom set of group parameters, subject to a minimum bitlength for 'P'. + /// + /// a list of acceptable s. + /// the minimum bitlength of 'P'. + public DefaultTlsDHGroupVerifier(IList groups, int minimumPrimeBits) + { + this.m_groups = Platform.CreateArrayList(groups); + this.m_minimumPrimeBits = minimumPrimeBits; + } + + public virtual bool Accept(DHGroup dhGroup) + { + return CheckMinimumPrimeBits(dhGroup) && CheckGroup(dhGroup); + } + + public virtual int MinimumPrimeBits + { + get { return m_minimumPrimeBits; } + } + + protected virtual bool AreGroupsEqual(DHGroup a, DHGroup b) + { + return a == b || (AreParametersEqual(a.P, b.P) && AreParametersEqual(a.G, b.G)); + } + + protected virtual bool AreParametersEqual(BigInteger a, BigInteger b) + { + return a == b || a.Equals(b); + } + + protected virtual bool CheckGroup(DHGroup dhGroup) + { + foreach (DHGroup group in m_groups) + { + if (AreGroupsEqual(dhGroup, group)) + return true; + } + return false; + } + + protected virtual bool CheckMinimumPrimeBits(DHGroup dhGroup) + { + return dhGroup.P.BitLength >= MinimumPrimeBits; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DefaultTlsDHGroupVerifier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DefaultTlsDHGroupVerifier.cs.meta new file mode 100644 index 0000000..ab9a98e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DefaultTlsDHGroupVerifier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ba58e15dd4a291e4abb6248ba4908f7f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DefaultTlsHeartbeat.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DefaultTlsHeartbeat.cs new file mode 100644 index 0000000..9090d2c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DefaultTlsHeartbeat.cs @@ -0,0 +1,44 @@ +using System; + +using Org.BouncyCastle.Crypto.Utilities; + +namespace Org.BouncyCastle.Tls +{ + public class DefaultTlsHeartbeat + : TlsHeartbeat + { + private readonly int idleMillis, timeoutMillis; + + private uint counter = 0U; + + public DefaultTlsHeartbeat(int idleMillis, int timeoutMillis) + { + if (idleMillis <= 0) + throw new ArgumentException("must be > 0", "idleMillis"); + if (timeoutMillis <= 0) + throw new ArgumentException("must be > 0", "timeoutMillis"); + + this.idleMillis = idleMillis; + this.timeoutMillis = timeoutMillis; + } + + public virtual byte[] GeneratePayload() + { + lock (this) + { + // NOTE: The counter naturally wraps back to 0 + return Pack.UInt32_To_BE(++counter); + } + } + + public virtual int IdleMillis + { + get { return idleMillis; } + } + + public virtual int TimeoutMillis + { + get { return timeoutMillis; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DefaultTlsHeartbeat.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DefaultTlsHeartbeat.cs.meta new file mode 100644 index 0000000..9879e44 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DefaultTlsHeartbeat.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b4f201a01bd036c4fb742c28321ab6ad +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DefaultTlsKeyExchangeFactory.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DefaultTlsKeyExchangeFactory.cs new file mode 100644 index 0000000..c8d6ff1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DefaultTlsKeyExchangeFactory.cs @@ -0,0 +1,89 @@ +using System; + +using Org.BouncyCastle.Tls.Crypto; + +namespace Org.BouncyCastle.Tls +{ + public class DefaultTlsKeyExchangeFactory + : AbstractTlsKeyExchangeFactory + { + public override TlsKeyExchange CreateDHKeyExchange(int keyExchange) + { + return new TlsDHKeyExchange(keyExchange); + } + + public override TlsKeyExchange CreateDHanonKeyExchangeClient(int keyExchange, + TlsDHGroupVerifier dhGroupVerifier) + { + return new TlsDHanonKeyExchange(keyExchange, dhGroupVerifier); + } + + public override TlsKeyExchange CreateDHanonKeyExchangeServer(int keyExchange, TlsDHConfig dhConfig) + { + return new TlsDHanonKeyExchange(keyExchange, dhConfig); + } + + public override TlsKeyExchange CreateDheKeyExchangeClient(int keyExchange, TlsDHGroupVerifier dhGroupVerifier) + { + return new TlsDheKeyExchange(keyExchange, dhGroupVerifier); + } + + public override TlsKeyExchange CreateDheKeyExchangeServer(int keyExchange, TlsDHConfig dhConfig) + { + return new TlsDheKeyExchange(keyExchange, dhConfig); + } + + public override TlsKeyExchange CreateECDHKeyExchange(int keyExchange) + { + return new TlsECDHKeyExchange(keyExchange); + } + + public override TlsKeyExchange CreateECDHanonKeyExchangeClient(int keyExchange) + { + return new TlsECDHanonKeyExchange(keyExchange); + } + + public override TlsKeyExchange CreateECDHanonKeyExchangeServer(int keyExchange, TlsECConfig ecConfig) + { + return new TlsECDHanonKeyExchange(keyExchange, ecConfig); + } + + public override TlsKeyExchange CreateECDheKeyExchangeClient(int keyExchange) + { + return new TlsECDheKeyExchange(keyExchange); + } + + public override TlsKeyExchange CreateECDheKeyExchangeServer(int keyExchange, TlsECConfig ecConfig) + { + return new TlsECDheKeyExchange(keyExchange, ecConfig); + } + + public override TlsKeyExchange CreatePskKeyExchangeClient(int keyExchange, TlsPskIdentity pskIdentity, + TlsDHGroupVerifier dhGroupVerifier) + { + return new TlsPskKeyExchange(keyExchange, pskIdentity, dhGroupVerifier); + } + + public override TlsKeyExchange CreatePskKeyExchangeServer(int keyExchange, + TlsPskIdentityManager pskIdentityManager, TlsDHConfig dhConfig, TlsECConfig ecConfig) + { + return new TlsPskKeyExchange(keyExchange, pskIdentityManager, dhConfig, ecConfig); + } + + public override TlsKeyExchange CreateRsaKeyExchange(int keyExchange) + { + return new TlsRsaKeyExchange(keyExchange); + } + + public override TlsKeyExchange CreateSrpKeyExchangeClient(int keyExchange, TlsSrpIdentity srpIdentity, + TlsSrpConfigVerifier srpConfigVerifier) + { + return new TlsSrpKeyExchange(keyExchange, srpIdentity, srpConfigVerifier); + } + + public override TlsKeyExchange CreateSrpKeyExchangeServer(int keyExchange, TlsSrpLoginParameters loginParameters) + { + return new TlsSrpKeyExchange(keyExchange, loginParameters); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DefaultTlsKeyExchangeFactory.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DefaultTlsKeyExchangeFactory.cs.meta new file mode 100644 index 0000000..2f15ef1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DefaultTlsKeyExchangeFactory.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0657693cbc0973348b11be22f13f6453 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DefaultTlsServer.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DefaultTlsServer.cs new file mode 100644 index 0000000..de8a3f4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DefaultTlsServer.cs @@ -0,0 +1,108 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Tls.Crypto; + +namespace Org.BouncyCastle.Tls +{ + public abstract class DefaultTlsServer + : AbstractTlsServer + { + private static readonly int[] DefaultCipherSuites = new int[] + { + /* + * TODO[tls13] TLS 1.3 + */ + //CipherSuite.TLS_CHACHA20_POLY1305_SHA256, + //CipherSuite.TLS_AES_256_GCM_SHA384, + //CipherSuite.TLS_AES_128_GCM_SHA256, + + /* + * pre-TLS 1.3 + */ + CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, + CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, + CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, + CipherSuite.TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, + CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, + CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, + CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, + CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA, + CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA, + CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384, + CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256, + CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256, + CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256, + CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA, + CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, + }; + + public DefaultTlsServer(TlsCrypto crypto) + : base(crypto) + { + } + + /// + protected virtual TlsCredentialedSigner GetDsaSignerCredentials() + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + /// + protected virtual TlsCredentialedSigner GetECDsaSignerCredentials() + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + /// + protected virtual TlsCredentialedDecryptor GetRsaEncryptionCredentials() + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + /// + protected virtual TlsCredentialedSigner GetRsaSignerCredentials() + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + protected override int[] GetSupportedCipherSuites() + { + return TlsUtilities.GetSupportedCipherSuites(Crypto, DefaultCipherSuites); + } + + public override TlsCredentials GetCredentials() + { + int keyExchangeAlgorithm = m_context.SecurityParameters.KeyExchangeAlgorithm; + + switch (keyExchangeAlgorithm) + { + case KeyExchangeAlgorithm.DHE_DSS: + return GetDsaSignerCredentials(); + + case KeyExchangeAlgorithm.DH_anon: + case KeyExchangeAlgorithm.ECDH_anon: + return null; + + case KeyExchangeAlgorithm.ECDHE_ECDSA: + return GetECDsaSignerCredentials(); + + case KeyExchangeAlgorithm.DHE_RSA: + case KeyExchangeAlgorithm.ECDHE_RSA: + return GetRsaSignerCredentials(); + + case KeyExchangeAlgorithm.RSA: + return GetRsaEncryptionCredentials(); + + default: + // Note: internal error here; selected a key exchange we don't implement! + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DefaultTlsServer.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DefaultTlsServer.cs.meta new file mode 100644 index 0000000..75d4d75 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DefaultTlsServer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 75779e7bd6ad1ae459fc061abee0e96c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DefaultTlsSrpConfigVerifier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DefaultTlsSrpConfigVerifier.cs new file mode 100644 index 0000000..7812498 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DefaultTlsSrpConfigVerifier.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Tls.Crypto; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls +{ + public class DefaultTlsSrpConfigVerifier + : TlsSrpConfigVerifier + { + private static readonly IList DefaultGroups = Platform.CreateArrayList(); + + static DefaultTlsSrpConfigVerifier() + { + DefaultGroups.Add(Srp6StandardGroups.rfc5054_1024); + DefaultGroups.Add(Srp6StandardGroups.rfc5054_1536); + DefaultGroups.Add(Srp6StandardGroups.rfc5054_2048); + DefaultGroups.Add(Srp6StandardGroups.rfc5054_3072); + DefaultGroups.Add(Srp6StandardGroups.rfc5054_4096); + DefaultGroups.Add(Srp6StandardGroups.rfc5054_6144); + DefaultGroups.Add(Srp6StandardGroups.rfc5054_8192); + } + + // IList is (SRP6Group) + protected readonly IList m_groups; + + /// Accept only the group parameters specified in RFC 5054 Appendix A. + public DefaultTlsSrpConfigVerifier() + : this(DefaultGroups) + { + } + + /// Specify a custom set of acceptable group parameters. + /// an of acceptable . + public DefaultTlsSrpConfigVerifier(IList groups) + { + this.m_groups = Platform.CreateArrayList(groups); + } + + public virtual bool Accept(TlsSrpConfig srpConfig) + { + foreach (Srp6Group group in m_groups) + { + if (AreGroupsEqual(srpConfig, group)) + return true; + } + return false; + } + + protected virtual bool AreGroupsEqual(TlsSrpConfig a, Srp6Group b) + { + BigInteger[] ng = a.GetExplicitNG(); + return AreParametersEqual(ng[0], b.N) && AreParametersEqual(ng[1], b.G); + } + + protected virtual bool AreParametersEqual(BigInteger a, BigInteger b) + { + return a == b || a.Equals(b); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DefaultTlsSrpConfigVerifier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DefaultTlsSrpConfigVerifier.cs.meta new file mode 100644 index 0000000..92837b6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DefaultTlsSrpConfigVerifier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fe08904ee866b504ead587fca3172aa0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DeferredHash.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DeferredHash.cs new file mode 100644 index 0000000..bba3019 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DeferredHash.cs @@ -0,0 +1,245 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Tls.Crypto; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls +{ + /// Buffers input until the hash algorithm is determined. + internal sealed class DeferredHash + : TlsHandshakeHash + { + private const int BufferingHashLimit = 4; + + private readonly TlsContext m_context; + + private DigestInputBuffer m_buf; + private readonly IDictionary m_hashes; + private bool m_forceBuffering; + private bool m_sealed; + + internal DeferredHash(TlsContext context) + { + this.m_context = context; + this.m_buf = new DigestInputBuffer(); + this.m_hashes = Platform.CreateHashtable(); + this.m_forceBuffering = false; + this.m_sealed = false; + } + + private DeferredHash(TlsContext context, IDictionary hashes) + { + this.m_context = context; + this.m_buf = null; + this.m_hashes = hashes; + this.m_forceBuffering = false; + this.m_sealed = true; + } + + /// + public void CopyBufferTo(Stream output) + { + if (m_buf == null) + { + // If you see this, you need to call forceBuffering() before SealHashAlgorithms() + throw new InvalidOperationException("Not buffering"); + } + + m_buf.CopyTo(output); + } + + public void ForceBuffering() + { + if (m_sealed) + throw new InvalidOperationException("Too late to force buffering"); + + this.m_forceBuffering = true; + } + + public void NotifyPrfDetermined() + { + SecurityParameters securityParameters = m_context.SecurityParameters; + + switch (securityParameters.PrfAlgorithm) + { + case PrfAlgorithm.ssl_prf_legacy: + case PrfAlgorithm.tls_prf_legacy: + { + CheckTrackingHash(CryptoHashAlgorithm.md5); + CheckTrackingHash(CryptoHashAlgorithm.sha1); + break; + } + default: + { + CheckTrackingHash(securityParameters.PrfCryptoHashAlgorithm); + break; + } + } + } + + public void TrackHashAlgorithm(int cryptoHashAlgorithm) + { + if (m_sealed) + throw new InvalidOperationException("Too late to track more hash algorithms"); + + CheckTrackingHash(cryptoHashAlgorithm); + } + + public void SealHashAlgorithms() + { + if (m_sealed) + throw new InvalidOperationException("Already sealed"); + + this.m_sealed = true; + CheckStopBuffering(); + } + + public TlsHandshakeHash StopTracking() + { + SecurityParameters securityParameters = m_context.SecurityParameters; + + IDictionary newHashes = Platform.CreateHashtable(); + switch (securityParameters.PrfAlgorithm) + { + case PrfAlgorithm.ssl_prf_legacy: + case PrfAlgorithm.tls_prf_legacy: + { + CloneHash(newHashes, HashAlgorithm.md5); + CloneHash(newHashes, HashAlgorithm.sha1); + break; + } + default: + { + CloneHash(newHashes, securityParameters.PrfCryptoHashAlgorithm); + break; + } + } + return new DeferredHash(m_context, newHashes); + } + + public TlsHash ForkPrfHash() + { + CheckStopBuffering(); + + SecurityParameters securityParameters = m_context.SecurityParameters; + + TlsHash prfHash; + switch (securityParameters.PrfAlgorithm) + { + case PrfAlgorithm.ssl_prf_legacy: + case PrfAlgorithm.tls_prf_legacy: + { + prfHash = new CombinedHash(m_context, CloneHash(HashAlgorithm.md5), CloneHash(HashAlgorithm.sha1)); + break; + } + default: + { + prfHash = CloneHash(securityParameters.PrfCryptoHashAlgorithm); + break; + } + } + + if (m_buf != null) + { + m_buf.UpdateDigest(prfHash); + } + + return prfHash; + } + + public byte[] GetFinalHash(int cryptoHashAlgorithm) + { + TlsHash d = (TlsHash)m_hashes[cryptoHashAlgorithm]; + if (d == null) + throw new InvalidOperationException("CryptoHashAlgorithm." + cryptoHashAlgorithm + + " is not being tracked"); + + CheckStopBuffering(); + + d = d.CloneHash(); + if (m_buf != null) + { + m_buf.UpdateDigest(d); + } + + return d.CalculateHash(); + } + + public void Update(byte[] input, int inOff, int len) + { + if (m_buf != null) + { + m_buf.Write(input, inOff, len); + return; + } + + foreach (TlsHash hash in m_hashes.Values) + { + hash.Update(input, inOff, len); + } + } + + public byte[] CalculateHash() + { + throw new InvalidOperationException("Use 'ForkPrfHash' to get a definite hash"); + } + + public TlsHash CloneHash() + { + throw new InvalidOperationException("attempt to clone a DeferredHash"); + } + + public void Reset() + { + if (m_buf != null) + { + m_buf.SetLength(0); + return; + } + + foreach (TlsHash hash in m_hashes.Values) + { + hash.Reset(); + } + } + + private void CheckStopBuffering() + { + if (!m_forceBuffering && m_sealed && m_buf != null && m_hashes.Count <= BufferingHashLimit) + { + foreach (TlsHash hash in m_hashes.Values) + { + m_buf.UpdateDigest(hash); + } + + this.m_buf = null; + } + } + + private void CheckTrackingHash(int cryptoHashAlgorithm) + { + if (!m_hashes.Contains(cryptoHashAlgorithm)) + { + TlsHash hash = m_context.Crypto.CreateHash(cryptoHashAlgorithm); + m_hashes[cryptoHashAlgorithm] = hash; + } + } + + private TlsHash CloneHash(int cryptoHashAlgorithm) + { + return ((TlsHash)m_hashes[cryptoHashAlgorithm]).CloneHash(); + } + + private void CloneHash(IDictionary newHashes, int cryptoHashAlgorithm) + { + TlsHash hash = CloneHash(cryptoHashAlgorithm); + if (m_buf != null) + { + m_buf.UpdateDigest(hash); + } + newHashes[cryptoHashAlgorithm] = hash; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DeferredHash.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DeferredHash.cs.meta new file mode 100644 index 0000000..3ae6a58 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DeferredHash.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ee52d2b70b1c1414e9ab54f4786d4984 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DigestInputBuffer.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DigestInputBuffer.cs new file mode 100644 index 0000000..7dd525f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DigestInputBuffer.cs @@ -0,0 +1,26 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Tls.Crypto; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Tls +{ + internal class DigestInputBuffer + : MemoryStream + { + internal void UpdateDigest(TlsHash hash) + { + Streams.WriteBufTo(this, new TlsHashSink(hash)); + } + + /// + internal void CopyTo(Stream output) + { + // TODO[tls-port] + // NOTE: Copy data since the output here may be under control of external code. + //Streams.PipeAll(new MemoryStream(buf, 0, count), output); + Streams.WriteBufTo(this, output); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DigestInputBuffer.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DigestInputBuffer.cs.meta new file mode 100644 index 0000000..e3b54be --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DigestInputBuffer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e90980387ce56094580cd0c430d223cb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DigitallySigned.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DigitallySigned.cs new file mode 100644 index 0000000..e977b35 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DigitallySigned.cs @@ -0,0 +1,62 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Tls +{ + public sealed class DigitallySigned + { + private readonly SignatureAndHashAlgorithm algorithm; + private readonly byte[] signature; + + public DigitallySigned(SignatureAndHashAlgorithm algorithm, byte[] signature) + { + if (signature == null) + throw new ArgumentNullException("signature"); + + this.algorithm = algorithm; + this.signature = signature; + } + + /// a (or null before TLS 1.2). + public SignatureAndHashAlgorithm Algorithm + { + get { return algorithm; } + } + + public byte[] Signature + { + get { return signature; } + } + + /// Encode this to a . + /// the to encode to. + /// + public void Encode(Stream output) + { + if (algorithm != null) + { + algorithm.Encode(output); + } + TlsUtilities.WriteOpaque16(signature, output); + } + + /// Parse a from a . + /// the of the current connection. + /// the to parse from. + /// a object. + /// + public static DigitallySigned Parse(TlsContext context, Stream input) + { + SignatureAndHashAlgorithm algorithm = null; + if (TlsUtilities.IsTlsV12(context)) + { + algorithm = SignatureAndHashAlgorithm.Parse(input); + + if (SignatureAlgorithm.anonymous == algorithm.Signature) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + byte[] signature = TlsUtilities.ReadOpaque16(input); + return new DigitallySigned(algorithm, signature); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DigitallySigned.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DigitallySigned.cs.meta new file mode 100644 index 0000000..32ae403 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DigitallySigned.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1a6749cb2026831438c4113ddeb4a316 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsClientProtocol.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsClientProtocol.cs new file mode 100644 index 0000000..44f574e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsClientProtocol.cs @@ -0,0 +1,981 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Tls.Crypto; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls +{ + public class DtlsClientProtocol + : DtlsProtocol + { + public DtlsClientProtocol() + : base() + { + } + + /// + public virtual DtlsTransport Connect(TlsClient client, DatagramTransport transport) + { + if (client == null) + throw new ArgumentNullException("client"); + if (transport == null) + throw new ArgumentNullException("transport"); + + ClientHandshakeState state = new ClientHandshakeState(); + state.client = client; + state.clientContext = new TlsClientContextImpl(client.Crypto); + + client.Init(state.clientContext); + state.clientContext.HandshakeBeginning(client); + + SecurityParameters securityParameters = state.clientContext.SecurityParameters; + securityParameters.m_extendedPadding = client.ShouldUseExtendedPadding(); + + TlsSession sessionToResume = state.client.GetSessionToResume(); + if (sessionToResume != null && sessionToResume.IsResumable) + { + SessionParameters sessionParameters = sessionToResume.ExportSessionParameters(); + + /* + * NOTE: If we ever enable session resumption without extended_master_secret, then + * renegotiation MUST be disabled (see RFC 7627 5.4). + */ + if (sessionParameters != null + && (sessionParameters.IsExtendedMasterSecret + || (!state.client.RequiresExtendedMasterSecret() && state.client.AllowLegacyResumption()))) + { + TlsSecret masterSecret = sessionParameters.MasterSecret; + lock (masterSecret) + { + if (masterSecret.IsAlive()) + { + state.tlsSession = sessionToResume; + state.sessionParameters = sessionParameters; + state.sessionMasterSecret = state.clientContext.Crypto.AdoptSecret(masterSecret); + } + } + } + } + + DtlsRecordLayer recordLayer = new DtlsRecordLayer(state.clientContext, state.client, transport); + client.NotifyCloseHandle(recordLayer); + + try + { + return ClientHandshake(state, recordLayer); + } + catch (TlsFatalAlert fatalAlert) + { + AbortClientHandshake(state, recordLayer, fatalAlert.AlertDescription); + throw fatalAlert; + } + catch (IOException e) + { + AbortClientHandshake(state, recordLayer, AlertDescription.internal_error); + throw e; + } + catch (Exception e) + { + AbortClientHandshake(state, recordLayer, AlertDescription.internal_error); + throw new TlsFatalAlert(AlertDescription.internal_error, e); + } + finally + { + securityParameters.Clear(); + } + } + + internal virtual void AbortClientHandshake(ClientHandshakeState state, DtlsRecordLayer recordLayer, + short alertDescription) + { + recordLayer.Fail(alertDescription); + InvalidateSession(state); + } + + /// + internal virtual DtlsTransport ClientHandshake(ClientHandshakeState state, DtlsRecordLayer recordLayer) + { + SecurityParameters securityParameters = state.clientContext.SecurityParameters; + + DtlsReliableHandshake handshake = new DtlsReliableHandshake(state.clientContext, recordLayer, + state.client.GetHandshakeTimeoutMillis(), null); + + byte[] clientHelloBody = GenerateClientHello(state); + + recordLayer.SetWriteVersion(ProtocolVersion.DTLSv10); + + handshake.SendMessage(HandshakeType.client_hello, clientHelloBody); + + DtlsReliableHandshake.Message serverMessage = handshake.ReceiveMessage(); + + // TODO Consider stricter HelloVerifyRequest protocol + //if (serverMessage.Type == HandshakeType.hello_verify_request) + while (serverMessage.Type == HandshakeType.hello_verify_request) + { + byte[] cookie = ProcessHelloVerifyRequest(state, serverMessage.Body); + byte[] patched = PatchClientHelloWithCookie(clientHelloBody, cookie); + + handshake.ResetAfterHelloVerifyRequestClient(); + handshake.SendMessage(HandshakeType.client_hello, patched); + + serverMessage = handshake.ReceiveMessage(); + } + + if (serverMessage.Type == HandshakeType.server_hello) + { + ProtocolVersion recordLayerVersion = recordLayer.ReadVersion; + ReportServerVersion(state, recordLayerVersion); + recordLayer.SetWriteVersion(recordLayerVersion); + + ProcessServerHello(state, serverMessage.Body); + } + else + { + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + handshake.HandshakeHash.NotifyPrfDetermined(); + + ApplyMaxFragmentLengthExtension(recordLayer, securityParameters.MaxFragmentLength); + + if (state.resumedSession) + { + securityParameters.m_masterSecret = state.sessionMasterSecret; + recordLayer.InitPendingEpoch(TlsUtilities.InitCipher(state.clientContext)); + + // NOTE: Calculated exclusive of the actual Finished message from the server + securityParameters.m_peerVerifyData = TlsUtilities.CalculateVerifyData(state.clientContext, + handshake.HandshakeHash, true); + ProcessFinished(handshake.ReceiveMessageBody(HandshakeType.finished), + securityParameters.PeerVerifyData); + + // NOTE: Calculated exclusive of the Finished message itself + securityParameters.m_localVerifyData = TlsUtilities.CalculateVerifyData(state.clientContext, + handshake.HandshakeHash, false); + handshake.SendMessage(HandshakeType.finished, securityParameters.LocalVerifyData); + + handshake.Finish(); + + if (securityParameters.IsExtendedMasterSecret) + { + securityParameters.m_tlsUnique = securityParameters.PeerVerifyData; + } + + securityParameters.m_localCertificate = state.sessionParameters.LocalCertificate; + securityParameters.m_peerCertificate = state.sessionParameters.PeerCertificate; + securityParameters.m_pskIdentity = state.sessionParameters.PskIdentity; + securityParameters.m_srpIdentity = state.sessionParameters.SrpIdentity; + + state.clientContext.HandshakeComplete(state.client, state.tlsSession); + + recordLayer.InitHeartbeat(state.heartbeat, + HeartbeatMode.peer_allowed_to_send == state.heartbeatPolicy); + + return new DtlsTransport(recordLayer); + } + + InvalidateSession(state); + state.tlsSession = TlsUtilities.ImportSession(securityParameters.SessionID, null); + + serverMessage = handshake.ReceiveMessage(); + + if (serverMessage.Type == HandshakeType.supplemental_data) + { + ProcessServerSupplementalData(state, serverMessage.Body); + serverMessage = handshake.ReceiveMessage(); + } + else + { + state.client.ProcessServerSupplementalData(null); + } + + state.keyExchange = TlsUtilities.InitKeyExchangeClient(state.clientContext, state.client); + + if (serverMessage.Type == HandshakeType.certificate) + { + ProcessServerCertificate(state, serverMessage.Body); + serverMessage = handshake.ReceiveMessage(); + } + else + { + // Okay, Certificate is optional + state.authentication = null; + } + + if (serverMessage.Type == HandshakeType.certificate_status) + { + if (securityParameters.StatusRequestVersion < 1) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + + ProcessCertificateStatus(state, serverMessage.Body); + serverMessage = handshake.ReceiveMessage(); + } + else + { + // Okay, CertificateStatus is optional + } + + TlsUtilities.ProcessServerCertificate(state.clientContext, state.certificateStatus, state.keyExchange, + state.authentication, state.clientExtensions, state.serverExtensions); + + if (serverMessage.Type == HandshakeType.server_key_exchange) + { + ProcessServerKeyExchange(state, serverMessage.Body); + serverMessage = handshake.ReceiveMessage(); + } + else + { + // Okay, ServerKeyExchange is optional + state.keyExchange.SkipServerKeyExchange(); + } + + if (serverMessage.Type == HandshakeType.certificate_request) + { + ProcessCertificateRequest(state, serverMessage.Body); + + TlsUtilities.EstablishServerSigAlgs(securityParameters, state.certificateRequest); + + /* + * TODO Give the client a chance to immediately select the CertificateVerify hash + * algorithm here to avoid tracking the other hash algorithms unnecessarily? + */ + TlsUtilities.TrackHashAlgorithms(handshake.HandshakeHash, securityParameters.ServerSigAlgs); + + serverMessage = handshake.ReceiveMessage(); + } + else + { + // Okay, CertificateRequest is optional + } + + if (serverMessage.Type == HandshakeType.server_hello_done) + { + if (serverMessage.Body.Length != 0) + { + throw new TlsFatalAlert(AlertDescription.decode_error); + } + } + else + { + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + IList clientSupplementalData = state.client.GetClientSupplementalData(); + if (clientSupplementalData != null) + { + byte[] supplementalDataBody = GenerateSupplementalData(clientSupplementalData); + handshake.SendMessage(HandshakeType.supplemental_data, supplementalDataBody); + } + + if (null != state.certificateRequest) + { + state.clientCredentials = TlsUtilities.EstablishClientCredentials(state.authentication, + state.certificateRequest); + + /* + * RFC 5246 If no suitable certificate is available, the client MUST send a certificate + * message containing no certificates. + * + * NOTE: In previous RFCs, this was SHOULD instead of MUST. + */ + + Certificate clientCertificate = null; + if (null != state.clientCredentials) + { + clientCertificate = state.clientCredentials.Certificate; + } + + SendCertificateMessage(state.clientContext, handshake, clientCertificate, null); + } + + TlsCredentialedSigner credentialedSigner = null; + TlsStreamSigner streamSigner = null; + + if (null != state.clientCredentials) + { + state.keyExchange.ProcessClientCredentials(state.clientCredentials); + + if (state.clientCredentials is TlsCredentialedSigner) + { + credentialedSigner = (TlsCredentialedSigner)state.clientCredentials; + streamSigner = credentialedSigner.GetStreamSigner(); + } + } + else + { + state.keyExchange.SkipClientCredentials(); + } + + bool forceBuffering = streamSigner != null; + TlsUtilities.SealHandshakeHash(state.clientContext, handshake.HandshakeHash, forceBuffering); + + byte[] clientKeyExchangeBody = GenerateClientKeyExchange(state); + handshake.SendMessage(HandshakeType.client_key_exchange, clientKeyExchangeBody); + + securityParameters.m_sessionHash = TlsUtilities.GetCurrentPrfHash(handshake.HandshakeHash); + + TlsProtocol.EstablishMasterSecret(state.clientContext, state.keyExchange); + recordLayer.InitPendingEpoch(TlsUtilities.InitCipher(state.clientContext)); + + { + if (credentialedSigner != null) + { + DigitallySigned certificateVerify = TlsUtilities.GenerateCertificateVerifyClient( + state.clientContext, credentialedSigner, streamSigner, handshake.HandshakeHash); + byte[] certificateVerifyBody = GenerateCertificateVerify(state, certificateVerify); + handshake.SendMessage(HandshakeType.certificate_verify, certificateVerifyBody); + } + + handshake.PrepareToFinish(); + } + + securityParameters.m_localVerifyData = TlsUtilities.CalculateVerifyData(state.clientContext, + handshake.HandshakeHash, false); + handshake.SendMessage(HandshakeType.finished, securityParameters.LocalVerifyData); + + if (state.expectSessionTicket) + { + serverMessage = handshake.ReceiveMessage(); + if (serverMessage.Type == HandshakeType.new_session_ticket) + { + /* + * RFC 5077 3.4. If the client receives a session ticket from the server, then it + * discards any Session ID that was sent in the ServerHello. + */ + securityParameters.m_sessionID = TlsUtilities.EmptyBytes; + InvalidateSession(state); + state.tlsSession = TlsUtilities.ImportSession(securityParameters.SessionID, null); + + ProcessNewSessionTicket(state, serverMessage.Body); + } + else + { + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + } + + // NOTE: Calculated exclusive of the actual Finished message from the server + securityParameters.m_peerVerifyData = TlsUtilities.CalculateVerifyData(state.clientContext, + handshake.HandshakeHash, true); + ProcessFinished(handshake.ReceiveMessageBody(HandshakeType.finished), securityParameters.PeerVerifyData); + + handshake.Finish(); + + state.sessionMasterSecret = securityParameters.MasterSecret; + + state.sessionParameters = new SessionParameters.Builder() + .SetCipherSuite(securityParameters.CipherSuite) + .SetExtendedMasterSecret(securityParameters.IsExtendedMasterSecret) + .SetLocalCertificate(securityParameters.LocalCertificate) + .SetMasterSecret(state.clientContext.Crypto.AdoptSecret(state.sessionMasterSecret)) + .SetNegotiatedVersion(securityParameters.NegotiatedVersion) + .SetPeerCertificate(securityParameters.PeerCertificate) + .SetPskIdentity(securityParameters.PskIdentity) + .SetSrpIdentity(securityParameters.SrpIdentity) + // TODO Consider filtering extensions that aren't relevant to resumed sessions + .SetServerExtensions(state.serverExtensions) + .Build(); + + state.tlsSession = TlsUtilities.ImportSession(securityParameters.SessionID, state.sessionParameters); + + securityParameters.m_tlsUnique = securityParameters.LocalVerifyData; + + state.clientContext.HandshakeComplete(state.client, state.tlsSession); + + recordLayer.InitHeartbeat(state.heartbeat, HeartbeatMode.peer_allowed_to_send == state.heartbeatPolicy); + + return new DtlsTransport(recordLayer); + } + + /// + protected virtual byte[] GenerateCertificateVerify(ClientHandshakeState state, + DigitallySigned certificateVerify) + { + MemoryStream buf = new MemoryStream(); + certificateVerify.Encode(buf); + return buf.ToArray(); + } + + /// + protected virtual byte[] GenerateClientHello(ClientHandshakeState state) + { + TlsClientContextImpl context = state.clientContext; + SecurityParameters securityParameters = context.SecurityParameters; + + context.SetClientSupportedVersions(state.client.GetProtocolVersions()); + + ProtocolVersion client_version = ProtocolVersion.GetLatestDtls(context.ClientSupportedVersions); + if (!ProtocolVersion.IsSupportedDtlsVersionClient(client_version)) + throw new TlsFatalAlert(AlertDescription.internal_error); + + context.SetClientVersion(client_version); + + byte[] session_id = TlsUtilities.GetSessionID(state.tlsSession); + + bool fallback = state.client.IsFallback(); + + state.offeredCipherSuites = state.client.GetCipherSuites(); + + if (session_id.Length > 0 && state.sessionParameters != null) + { + if (!Arrays.Contains(state.offeredCipherSuites, state.sessionParameters.CipherSuite)) + { + session_id = TlsUtilities.EmptyBytes; + } + } + + state.clientExtensions = TlsExtensionsUtilities.EnsureExtensionsInitialised( + state.client.GetClientExtensions()); + + ProtocolVersion legacy_version = client_version; + if (client_version.IsLaterVersionOf(ProtocolVersion.DTLSv12)) + { + legacy_version = ProtocolVersion.DTLSv12; + + TlsExtensionsUtilities.AddSupportedVersionsExtensionClient(state.clientExtensions, + context.ClientSupportedVersions); + } + + context.SetRsaPreMasterSecretVersion(legacy_version); + + securityParameters.m_clientServerNames = TlsExtensionsUtilities.GetServerNameExtensionClient( + state.clientExtensions); + + if (TlsUtilities.IsSignatureAlgorithmsExtensionAllowed(client_version)) + { + TlsUtilities.EstablishClientSigAlgs(securityParameters, state.clientExtensions); + } + + securityParameters.m_clientSupportedGroups = TlsExtensionsUtilities.GetSupportedGroupsExtension( + state.clientExtensions); + + state.clientAgreements = TlsUtilities.AddKeyShareToClientHello(state.clientContext, state.client, + state.clientExtensions); + + if (TlsUtilities.IsExtendedMasterSecretOptionalDtls(context.ClientSupportedVersions) + && state.client.ShouldUseExtendedMasterSecret()) + { + TlsExtensionsUtilities.AddExtendedMasterSecretExtension(state.clientExtensions); + } + else if (!TlsUtilities.IsTlsV13(client_version) + && state.client.RequiresExtendedMasterSecret()) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + { + bool useGmtUnixTime = ProtocolVersion.DTLSv12.IsEqualOrLaterVersionOf(client_version) + && state.client.ShouldUseGmtUnixTime(); + + securityParameters.m_clientRandom = TlsProtocol.CreateRandomBlock(useGmtUnixTime, state.clientContext); + } + + // Cipher Suites (and SCSV) + { + /* + * RFC 5746 3.4. The client MUST include either an empty "renegotiation_info" extension, + * or the TLS_EMPTY_RENEGOTIATION_INFO_SCSV signaling cipher suite value in the + * ClientHello. Including both is NOT RECOMMENDED. + */ + bool noRenegExt = (null == TlsUtilities.GetExtensionData(state.clientExtensions, + ExtensionType.renegotiation_info)); + bool noRenegScsv = !Arrays.Contains(state.offeredCipherSuites, + CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV); + + if (noRenegExt && noRenegScsv) + { + state.offeredCipherSuites = Arrays.Append(state.offeredCipherSuites, + CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV); + } + } + + /* (Fallback SCSV) + * RFC 7507 4. If a client sends a ClientHello.client_version containing a lower value + * than the latest (highest-valued) version supported by the client, it SHOULD include + * the TLS_FALLBACK_SCSV cipher suite value in ClientHello.cipher_suites [..]. (The + * client SHOULD put TLS_FALLBACK_SCSV after all cipher suites that it actually intends + * to negotiate.) + */ + if (fallback && !Arrays.Contains(state.offeredCipherSuites, CipherSuite.TLS_FALLBACK_SCSV)) + { + state.offeredCipherSuites = Arrays.Append(state.offeredCipherSuites, CipherSuite.TLS_FALLBACK_SCSV); + } + + // Heartbeats + { + state.heartbeat = state.client.GetHeartbeat(); + state.heartbeatPolicy = state.client.GetHeartbeatPolicy(); + + if (null != state.heartbeat || HeartbeatMode.peer_allowed_to_send == state.heartbeatPolicy) + { + TlsExtensionsUtilities.AddHeartbeatExtension(state.clientExtensions, + new HeartbeatExtension(state.heartbeatPolicy)); + } + } + + + + ClientHello clientHello = new ClientHello(legacy_version, securityParameters.ClientRandom, session_id, + TlsUtilities.EmptyBytes, state.offeredCipherSuites, state.clientExtensions, 0); + + MemoryStream buf = new MemoryStream(); + clientHello.Encode(state.clientContext, buf); + return buf.ToArray(); + } + + /// + protected virtual byte[] GenerateClientKeyExchange(ClientHandshakeState state) + { + MemoryStream buf = new MemoryStream(); + state.keyExchange.GenerateClientKeyExchange(buf); + return buf.ToArray(); + } + + protected virtual void InvalidateSession(ClientHandshakeState state) + { + if (state.sessionMasterSecret != null) + { + state.sessionMasterSecret.Destroy(); + state.sessionMasterSecret = null; + } + + if (state.sessionParameters != null) + { + state.sessionParameters.Clear(); + state.sessionParameters = null; + } + + if (state.tlsSession != null) + { + state.tlsSession.Invalidate(); + state.tlsSession = null; + } + } + + /// + protected virtual void ProcessCertificateRequest(ClientHandshakeState state, byte[] body) + { + if (null == state.authentication) + { + /* + * RFC 2246 7.4.4. It is a fatal handshake_failure alert for an anonymous server to + * request client identification. + */ + throw new TlsFatalAlert(AlertDescription.handshake_failure); + } + + MemoryStream buf = new MemoryStream(body, false); + + CertificateRequest certificateRequest = CertificateRequest.Parse(state.clientContext, buf); + + TlsProtocol.AssertEmpty(buf); + + state.certificateRequest = TlsUtilities.ValidateCertificateRequest(certificateRequest, state.keyExchange); + } + + /// + protected virtual void ProcessCertificateStatus(ClientHandshakeState state, byte[] body) + { + MemoryStream buf = new MemoryStream(body, false); + + // TODO[tls13] Ensure this cannot happen for (D)TLS1.3+ + state.certificateStatus = CertificateStatus.Parse(state.clientContext, buf); + + TlsProtocol.AssertEmpty(buf); + } + + /// + protected virtual byte[] ProcessHelloVerifyRequest(ClientHandshakeState state, byte[] body) + { + MemoryStream buf = new MemoryStream(body, false); + + ProtocolVersion server_version = TlsUtilities.ReadVersion(buf); + + /* + * RFC 6347 This specification increases the cookie size limit to 255 bytes for greater + * future flexibility. The limit remains 32 for previous versions of DTLS. + */ + int maxCookieLength = ProtocolVersion.DTLSv12.IsEqualOrEarlierVersionOf(server_version) ? 255 : 32; + + byte[] cookie = TlsUtilities.ReadOpaque8(buf, 0, maxCookieLength); + + TlsProtocol.AssertEmpty(buf); + + // TODO Seems this behaviour is not yet in line with OpenSSL for DTLS 1.2 + //ReportServerVersion(state, server_version); + if (!server_version.IsEqualOrEarlierVersionOf(state.clientContext.ClientVersion)) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + return cookie; + } + + /// + protected virtual void ProcessNewSessionTicket(ClientHandshakeState state, byte[] body) + { + MemoryStream buf = new MemoryStream(body, false); + + NewSessionTicket newSessionTicket = NewSessionTicket.Parse(buf); + + TlsProtocol.AssertEmpty(buf); + + state.client.NotifyNewSessionTicket(newSessionTicket); + } + + /// + protected virtual void ProcessServerCertificate(ClientHandshakeState state, byte[] body) + { + state.authentication = TlsUtilities.ReceiveServerCertificate(state.clientContext, state.client, + new MemoryStream(body, false)); + } + + /// + protected virtual void ProcessServerHello(ClientHandshakeState state, byte[] body) + { + MemoryStream buf = new MemoryStream(body, false); + + ServerHello serverHello = ServerHello.Parse(buf); + ProtocolVersion server_version = serverHello.Version; + + state.serverExtensions = serverHello.Extensions; + + + + SecurityParameters securityParameters = state.clientContext.SecurityParameters; + + // TODO[dtls13] Check supported_version extension for negotiated version + + ReportServerVersion(state, server_version); + + securityParameters.m_serverRandom = serverHello.Random; + + if (!state.clientContext.ClientVersion.Equals(server_version)) + { + TlsUtilities.CheckDowngradeMarker(server_version, securityParameters.ServerRandom); + } + + { + byte[] selectedSessionID = serverHello.SessionID; + securityParameters.m_sessionID = selectedSessionID; + state.client.NotifySessionID(selectedSessionID); + state.resumedSession = selectedSessionID.Length > 0 && state.tlsSession != null + && Arrays.AreEqual(selectedSessionID, state.tlsSession.SessionID); + } + + /* + * Find out which CipherSuite the server has chosen and check that it was one of the offered + * ones, and is a valid selection for the negotiated version. + */ + { + int cipherSuite = ValidateSelectedCipherSuite(serverHello.CipherSuite, + AlertDescription.illegal_parameter); + + if (!TlsUtilities.IsValidCipherSuiteSelection(state.offeredCipherSuites, cipherSuite) || + !TlsUtilities.IsValidVersionForCipherSuite(cipherSuite, securityParameters.NegotiatedVersion)) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + TlsUtilities.NegotiatedCipherSuite(securityParameters, cipherSuite); + state.client.NotifySelectedCipherSuite(cipherSuite); + } + + /* + * RFC3546 2.2 The extended server hello message format MAY be sent in place of the server + * hello message when the client has requested extended functionality via the extended + * client hello message specified in Section 2.1. ... Note that the extended server hello + * message is only sent in response to an extended client hello message. This prevents the + * possibility that the extended server hello message could "break" existing TLS 1.0 + * clients. + */ + + /* + * TODO RFC 3546 2.3 If [...] the older session is resumed, then the server MUST ignore + * extensions appearing in the client hello, and send a server hello containing no + * extensions. + */ + + /* + * RFC 7627 4. Clients and servers SHOULD NOT accept handshakes that do not use the extended + * master secret [..]. (and see 5.2, 5.3) + * + * RFC 8446 Appendix D. Because TLS 1.3 always hashes in the transcript up to the server + * Finished, implementations which support both TLS 1.3 and earlier versions SHOULD indicate + * the use of the Extended Master Secret extension in their APIs whenever TLS 1.3 is used. + */ + if (TlsUtilities.IsTlsV13(server_version)) + { + securityParameters.m_extendedMasterSecret = true; + } + else + { + bool acceptedExtendedMasterSecret = TlsExtensionsUtilities.HasExtendedMasterSecretExtension( + state.serverExtensions); + + if (acceptedExtendedMasterSecret) + { + if (!state.resumedSession && !state.client.ShouldUseExtendedMasterSecret()) + throw new TlsFatalAlert(AlertDescription.handshake_failure); + } + else + { + if (state.client.RequiresExtendedMasterSecret() + || (state.resumedSession && !state.client.AllowLegacyResumption())) + { + throw new TlsFatalAlert(AlertDescription.handshake_failure); + } + } + + securityParameters.m_extendedMasterSecret = acceptedExtendedMasterSecret; + } + + /* + * + * RFC 3546 2.2 Note that the extended server hello message is only sent in response to an + * extended client hello message. However, see RFC 5746 exception below. We always include + * the SCSV, so an Extended Server Hello is always allowed. + */ + if (state.serverExtensions != null) + { + foreach (int extType in state.serverExtensions.Keys) + { + /* + * RFC 5746 3.6. Note that sending a "renegotiation_info" extension in response to a + * ClientHello containing only the SCSV is an explicit exception to the prohibition + * in RFC 5246, Section 7.4.1.4, on the server sending unsolicited extensions and is + * only allowed because the client is signaling its willingness to receive the + * extension via the TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV. + */ + if (extType == ExtensionType.renegotiation_info) + continue; + + /* + * RFC 5246 7.4.1.4 An extension type MUST NOT appear in the ServerHello unless the + * same extension type appeared in the corresponding ClientHello. If a client + * receives an extension type in ServerHello that it did not request in the + * associated ClientHello, it MUST abort the handshake with an unsupported_extension + * fatal alert. + */ + if (null == TlsUtilities.GetExtensionData(state.clientExtensions, extType)) + throw new TlsFatalAlert(AlertDescription.unsupported_extension); + + /* + * RFC 3546 2.3. If [...] the older session is resumed, then the server MUST ignore + * extensions appearing in the client hello, and send a server hello containing no + * extensions[.] + */ + if (state.resumedSession) + { + // TODO[compat-gnutls] GnuTLS test server sends server extensions e.g. ec_point_formats + // TODO[compat-openssl] OpenSSL test server sends server extensions e.g. ec_point_formats + // TODO[compat-polarssl] PolarSSL test server sends server extensions e.g. ec_point_formats + //throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + } + } + + /* + * RFC 5746 3.4. Client Behavior: Initial Handshake + */ + { + /* + * When a ServerHello is received, the client MUST check if it includes the + * "renegotiation_info" extension: + */ + byte[] renegExtData = TlsUtilities.GetExtensionData(state.serverExtensions, + ExtensionType.renegotiation_info); + if (renegExtData != null) + { + /* + * If the extension is present, set the secure_renegotiation flag to TRUE. The + * client MUST then verify that the length of the "renegotiated_connection" + * field is zero, and if it is not, MUST abort the handshake (by sending a fatal + * handshake_failure alert). + */ + securityParameters.m_secureRenegotiation = true; + + if (!Arrays.ConstantTimeAreEqual(renegExtData, + TlsProtocol.CreateRenegotiationInfo(TlsUtilities.EmptyBytes))) + { + throw new TlsFatalAlert(AlertDescription.handshake_failure); + } + } + } + + // TODO[compat-gnutls] GnuTLS test server fails to send renegotiation_info extension when resuming + state.client.NotifySecureRenegotiation(securityParameters.IsSecureRenegotiation); + + /* + * RFC 7301 3.1. When session resumption or session tickets [...] are used, the previous + * contents of this extension are irrelevant, and only the values in the new handshake + * messages are considered. + */ + securityParameters.m_applicationProtocol = TlsExtensionsUtilities.GetAlpnExtensionServer( + state.serverExtensions); + securityParameters.m_applicationProtocolSet = true; + + // Heartbeats + { + HeartbeatExtension heartbeatExtension = TlsExtensionsUtilities.GetHeartbeatExtension( + state.serverExtensions); + if (null == heartbeatExtension) + { + state.heartbeat = null; + state.heartbeatPolicy = HeartbeatMode.peer_not_allowed_to_send; + } + else if (HeartbeatMode.peer_allowed_to_send != heartbeatExtension.Mode) + { + state.heartbeat = null; + } + } + + + + IDictionary sessionClientExtensions = state.clientExtensions, + sessionServerExtensions = state.serverExtensions; + + if (state.resumedSession) + { + if (securityParameters.CipherSuite != state.sessionParameters.CipherSuite + || !server_version.Equals(state.sessionParameters.NegotiatedVersion)) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + sessionClientExtensions = null; + sessionServerExtensions = state.sessionParameters.ReadServerExtensions(); + } + + if (sessionServerExtensions != null && sessionServerExtensions.Count > 0) + { + { + /* + * RFC 7366 3. If a server receives an encrypt-then-MAC request extension from a client + * and then selects a stream or Authenticated Encryption with Associated Data (AEAD) + * ciphersuite, it MUST NOT send an encrypt-then-MAC response extension back to the + * client. + */ + bool serverSentEncryptThenMac = TlsExtensionsUtilities.HasEncryptThenMacExtension( + sessionServerExtensions); + if (serverSentEncryptThenMac && !TlsUtilities.IsBlockCipherSuite(securityParameters.CipherSuite)) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + securityParameters.m_encryptThenMac = serverSentEncryptThenMac; + } + + securityParameters.m_maxFragmentLength = EvaluateMaxFragmentLengthExtension(state.resumedSession, + sessionClientExtensions, sessionServerExtensions, AlertDescription.illegal_parameter); + + securityParameters.m_truncatedHmac = TlsExtensionsUtilities.HasTruncatedHmacExtension( + sessionServerExtensions); + + if (!state.resumedSession) + { + // TODO[tls13] See RFC 8446 4.4.2.1 + if (TlsUtilities.HasExpectedEmptyExtensionData(sessionServerExtensions, + ExtensionType.status_request_v2, AlertDescription.illegal_parameter)) + { + securityParameters.m_statusRequestVersion = 2; + } + else if (TlsUtilities.HasExpectedEmptyExtensionData(sessionServerExtensions, + ExtensionType.status_request, AlertDescription.illegal_parameter)) + { + securityParameters.m_statusRequestVersion = 1; + } + } + + state.expectSessionTicket = !state.resumedSession + && TlsUtilities.HasExpectedEmptyExtensionData(sessionServerExtensions, + ExtensionType.session_ticket, AlertDescription.illegal_parameter); + } + + if (sessionClientExtensions != null) + { + state.client.ProcessServerExtensions(sessionServerExtensions); + } + } + + /// + protected virtual void ProcessServerKeyExchange(ClientHandshakeState state, byte[] body) + { + MemoryStream buf = new MemoryStream(body, false); + state.keyExchange.ProcessServerKeyExchange(buf); + TlsProtocol.AssertEmpty(buf); + } + + /// + protected virtual void ProcessServerSupplementalData(ClientHandshakeState state, byte[] body) + { + MemoryStream buf = new MemoryStream(body, false); + IList serverSupplementalData = TlsProtocol.ReadSupplementalDataMessage(buf); + state.client.ProcessServerSupplementalData(serverSupplementalData); + } + + /// + protected virtual void ReportServerVersion(ClientHandshakeState state, ProtocolVersion server_version) + { + TlsClientContextImpl context = state.clientContext; + SecurityParameters securityParameters = context.SecurityParameters; + + ProtocolVersion currentServerVersion = securityParameters.NegotiatedVersion; + if (null != currentServerVersion) + { + if (!currentServerVersion.Equals(server_version)) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + return; + } + + if (!ProtocolVersion.Contains(context.ClientSupportedVersions, server_version)) + throw new TlsFatalAlert(AlertDescription.protocol_version); + + securityParameters.m_negotiatedVersion = server_version; + + TlsUtilities.NegotiatedVersionDtlsClient(state.clientContext, state.client); + } + + /// + protected static byte[] PatchClientHelloWithCookie(byte[] clientHelloBody, byte[] cookie) + { + int sessionIDPos = 34; + int sessionIDLength = TlsUtilities.ReadUint8(clientHelloBody, sessionIDPos); + + int cookieLengthPos = sessionIDPos + 1 + sessionIDLength; + int cookiePos = cookieLengthPos + 1; + + byte[] patched = new byte[clientHelloBody.Length + cookie.Length]; + Array.Copy(clientHelloBody, 0, patched, 0, cookieLengthPos); + TlsUtilities.CheckUint8(cookie.Length); + TlsUtilities.WriteUint8(cookie.Length, patched, cookieLengthPos); + Array.Copy(cookie, 0, patched, cookiePos, cookie.Length); + Array.Copy(clientHelloBody, cookiePos, patched, cookiePos + cookie.Length, + clientHelloBody.Length - cookiePos); + + return patched; + } + + protected internal class ClientHandshakeState + { + internal TlsClient client = null; + internal TlsClientContextImpl clientContext = null; + internal TlsSession tlsSession = null; + internal SessionParameters sessionParameters = null; + internal TlsSecret sessionMasterSecret = null; + internal SessionParameters.Builder sessionParametersBuilder = null; + internal int[] offeredCipherSuites = null; + internal IDictionary clientExtensions = null; + internal IDictionary serverExtensions = null; + internal bool resumedSession = false; + internal bool expectSessionTicket = false; + internal IDictionary clientAgreements = null; + internal TlsKeyExchange keyExchange = null; + internal TlsAuthentication authentication = null; + internal CertificateStatus certificateStatus = null; + internal CertificateRequest certificateRequest = null; + internal TlsCredentials clientCredentials = null; + internal TlsHeartbeat heartbeat = null; + internal short heartbeatPolicy = HeartbeatMode.peer_not_allowed_to_send; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsClientProtocol.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsClientProtocol.cs.meta new file mode 100644 index 0000000..05f98e2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsClientProtocol.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 01a3741adb38b1f418f1181f629e6fe7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsEpoch.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsEpoch.cs new file mode 100644 index 0000000..e4ce849 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsEpoch.cs @@ -0,0 +1,61 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Tls.Crypto; + +namespace Org.BouncyCastle.Tls +{ + internal sealed class DtlsEpoch + { + private readonly DtlsReplayWindow m_replayWindow = new DtlsReplayWindow(); + + private readonly int m_epoch; + private readonly TlsCipher m_cipher; + + private long m_sequenceNumber = 0; + + internal DtlsEpoch(int epoch, TlsCipher cipher) + { + if (epoch < 0) + throw new ArgumentException("must be >= 0", "epoch"); + if (cipher == null) + throw new ArgumentNullException("cipher"); + + this.m_epoch = epoch; + this.m_cipher = cipher; + } + + /// + internal long AllocateSequenceNumber() + { + lock (this) + { + if (m_sequenceNumber >= (1L << 48)) + throw new TlsFatalAlert(AlertDescription.internal_error); + + return m_sequenceNumber++; + } + } + + internal TlsCipher Cipher + { + get { return m_cipher; } + } + + internal int Epoch + { + get { return m_epoch; } + } + + internal DtlsReplayWindow ReplayWindow + { + get { return m_replayWindow; } + } + + internal long SequenceNumber + { + get { lock (this) return m_sequenceNumber; } + set { lock (this) this.m_sequenceNumber = value; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsEpoch.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsEpoch.cs.meta new file mode 100644 index 0000000..7880c15 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsEpoch.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f67316f0c3744a94fa55d963ad3d683c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsHandshakeRetransmit.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsHandshakeRetransmit.cs new file mode 100644 index 0000000..6e691b8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsHandshakeRetransmit.cs @@ -0,0 +1,11 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Tls +{ + internal interface DtlsHandshakeRetransmit + { + /// + void ReceivedHandshakeRecord(int epoch, byte[] buf, int off, int len); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsHandshakeRetransmit.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsHandshakeRetransmit.cs.meta new file mode 100644 index 0000000..3106d67 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsHandshakeRetransmit.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3cdfad30de53850458d4af0637ff085c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsProtocol.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsProtocol.cs new file mode 100644 index 0000000..f0f42f9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsProtocol.cs @@ -0,0 +1,107 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls +{ + public abstract class DtlsProtocol + { + internal DtlsProtocol() + { + } + + /// + internal virtual void ProcessFinished(byte[] body, byte[] expected_verify_data) + { + MemoryStream buf = new MemoryStream(body, false); + + byte[] verify_data = TlsUtilities.ReadFully(expected_verify_data.Length, buf); + + TlsProtocol.AssertEmpty(buf); + + if (!Arrays.ConstantTimeAreEqual(expected_verify_data, verify_data)) + throw new TlsFatalAlert(AlertDescription.handshake_failure); + } + + /// + internal static void ApplyMaxFragmentLengthExtension(DtlsRecordLayer recordLayer, short maxFragmentLength) + { + if (maxFragmentLength >= 0) + { + if (!MaxFragmentLength.IsValid(maxFragmentLength)) + throw new TlsFatalAlert(AlertDescription.internal_error); + + int plainTextLimit = 1 << (8 + maxFragmentLength); + recordLayer.SetPlaintextLimit(plainTextLimit); + } + } + + /// + internal static short EvaluateMaxFragmentLengthExtension(bool resumedSession, IDictionary clientExtensions, + IDictionary serverExtensions, short alertDescription) + { + short maxFragmentLength = TlsExtensionsUtilities.GetMaxFragmentLengthExtension(serverExtensions); + if (maxFragmentLength >= 0) + { + if (!MaxFragmentLength.IsValid(maxFragmentLength) + || (!resumedSession && maxFragmentLength != TlsExtensionsUtilities + .GetMaxFragmentLengthExtension(clientExtensions))) + { + throw new TlsFatalAlert(alertDescription); + } + } + return maxFragmentLength; + } + + /// + internal static byte[] GenerateCertificate(TlsContext context, Certificate certificate, Stream endPointHash) + { + MemoryStream buf = new MemoryStream(); + certificate.Encode(context, buf, endPointHash); + return buf.ToArray(); + } + + /// + internal static byte[] GenerateSupplementalData(IList supplementalData) + { + MemoryStream buf = new MemoryStream(); + TlsProtocol.WriteSupplementalData(buf, supplementalData); + return buf.ToArray(); + } + + /// + internal static void SendCertificateMessage(TlsContext context, DtlsReliableHandshake handshake, + Certificate certificate, Stream endPointHash) + { + SecurityParameters securityParameters = context.SecurityParameters; + if (null != securityParameters.LocalCertificate) + throw new TlsFatalAlert(AlertDescription.internal_error); + + if (null == certificate) + { + certificate = Certificate.EmptyChain; + } + + byte[] certificateBody = GenerateCertificate(context, certificate, endPointHash); + handshake.SendMessage(HandshakeType.certificate, certificateBody); + + securityParameters.m_localCertificate = certificate; + } + + /// + internal static int ValidateSelectedCipherSuite(int selectedCipherSuite, short alertDescription) + { + switch (TlsUtilities.GetEncryptionAlgorithm(selectedCipherSuite)) + { + case EncryptionAlgorithm.RC4_40: + case EncryptionAlgorithm.RC4_128: + case -1: + throw new TlsFatalAlert(alertDescription); + default: + return selectedCipherSuite; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsProtocol.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsProtocol.cs.meta new file mode 100644 index 0000000..4782b79 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsProtocol.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7420be6afc485884da0069ad5534d6e0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsReassembler.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsReassembler.cs new file mode 100644 index 0000000..964c8eb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsReassembler.cs @@ -0,0 +1,120 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls +{ + internal sealed class DtlsReassembler + { + private readonly short m_msg_type; + private readonly byte[] m_body; + + private readonly IList m_missing = Platform.CreateArrayList(); + + internal DtlsReassembler(short msg_type, int length) + { + this.m_msg_type = msg_type; + this.m_body = new byte[length]; + this.m_missing.Add(new Range(0, length)); + } + + internal short MsgType + { + get { return m_msg_type; } + } + + internal byte[] GetBodyIfComplete() + { + return m_missing.Count > 0 ? null : m_body; + } + + internal void ContributeFragment(short msg_type, int length, byte[] buf, int off, int fragment_offset, + int fragment_length) + { + int fragment_end = fragment_offset + fragment_length; + + if (m_msg_type != msg_type || m_body.Length != length || fragment_end > length) + return; + + if (fragment_length == 0) + { + // NOTE: Empty messages still require an empty fragment to complete it + if (fragment_offset == 0 && m_missing.Count > 0) + { + Range firstRange = (Range)m_missing[0]; + if (firstRange.End == 0) + { + m_missing.RemoveAt(0); + } + } + return; + } + + for (int i = 0; i < m_missing.Count; ++i) + { + Range range = (Range)m_missing[i]; + if (range.Start >= fragment_end) + break; + + if (range.End > fragment_offset) + { + int copyStart = System.Math.Max(range.Start, fragment_offset); + int copyEnd = System.Math.Min(range.End, fragment_end); + int copyLength = copyEnd - copyStart; + + Array.Copy(buf, off + copyStart - fragment_offset, m_body, copyStart, copyLength); + + if (copyStart == range.Start) + { + if (copyEnd == range.End) + { + m_missing.RemoveAt(i--); + } + else + { + range.Start = copyEnd; + } + } + else + { + if (copyEnd != range.End) + { + m_missing.Insert(++i, new Range(copyEnd, range.End)); + } + range.End = copyStart; + } + } + } + } + + internal void Reset() + { + m_missing.Clear(); + m_missing.Add(new Range(0, m_body.Length)); + } + + private sealed class Range + { + private int m_start, m_end; + + internal Range(int start, int end) + { + this.m_start = start; + this.m_end = end; + } + + public int Start + { + get { return m_start; } + set { this.m_start = value; } + } + + public int End + { + get { return m_end; } + set { this.m_end = value; } + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsReassembler.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsReassembler.cs.meta new file mode 100644 index 0000000..d435786 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsReassembler.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cfd4f7c10af3e914cb489a901792babb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsRecordLayer.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsRecordLayer.cs new file mode 100644 index 0000000..ffc0719 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsRecordLayer.cs @@ -0,0 +1,817 @@ +using System; +using System.IO; +#if !PORTABLE || DOTNET +using System.Net.Sockets; +#endif + +using Org.BouncyCastle.Tls.Crypto; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Date; + +namespace Org.BouncyCastle.Tls +{ + internal class DtlsRecordLayer + : DatagramTransport + { + private const int RECORD_HEADER_LENGTH = 13; + private const int MAX_FRAGMENT_LENGTH = 1 << 14; + private const long TCP_MSL = 1000L * 60 * 2; + private const long RETRANSMIT_TIMEOUT = TCP_MSL * 2; + + /// + internal static byte[] ReceiveClientHelloRecord(byte[] data, int dataOff, int dataLen) + { + if (dataLen < RECORD_HEADER_LENGTH) + { + return null; + } + + short contentType = TlsUtilities.ReadUint8(data, dataOff + 0); + if (ContentType.handshake != contentType) + return null; + + ProtocolVersion version = TlsUtilities.ReadVersion(data, dataOff + 1); + if (!ProtocolVersion.DTLSv10.IsEqualOrEarlierVersionOf(version)) + return null; + + int epoch = TlsUtilities.ReadUint16(data, dataOff + 3); + if (0 != epoch) + return null; + + //long sequenceNumber = TlsUtilities.ReadUint48(data, dataOff + 5); + + int length = TlsUtilities.ReadUint16(data, dataOff + 11); + if (dataLen < RECORD_HEADER_LENGTH + length) + return null; + + if (length > MAX_FRAGMENT_LENGTH) + return null; + + // NOTE: We ignore/drop any data after the first record + return TlsUtilities.CopyOfRangeExact(data, dataOff + RECORD_HEADER_LENGTH, + dataOff + RECORD_HEADER_LENGTH + length); + } + + /// + internal static void SendHelloVerifyRequestRecord(DatagramSender sender, long recordSeq, byte[] message) + { + TlsUtilities.CheckUint16(message.Length); + + byte[] record = new byte[RECORD_HEADER_LENGTH + message.Length]; + TlsUtilities.WriteUint8(ContentType.handshake, record, 0); + TlsUtilities.WriteVersion(ProtocolVersion.DTLSv10, record, 1); + TlsUtilities.WriteUint16(0, record, 3); + TlsUtilities.WriteUint48(recordSeq, record, 5); + TlsUtilities.WriteUint16(message.Length, record, 11); + + Array.Copy(message, 0, record, RECORD_HEADER_LENGTH, message.Length); + + SendDatagram(sender, record, 0, record.Length); + } + + /// + private static void SendDatagram(DatagramSender sender, byte[] buf, int off, int len) + { + // TODO[tls-port] Can we support interrupted IO on .NET? + //try + //{ + // sender.Send(buf, off, len); + //} + //catch (InterruptedIOException e) + //{ + // e.bytesTransferred = 0; + // throw e; + //} + + sender.Send(buf, off, len); + } + + private readonly TlsContext m_context; + private readonly TlsPeer m_peer; + private readonly DatagramTransport m_transport; + + private readonly ByteQueue m_recordQueue = new ByteQueue(); + private readonly object m_writeLock = new object(); + + private volatile bool m_closed = false; + private volatile bool m_failed = false; + // TODO[dtls13] Review the draft/RFC (legacy_record_version) to see if readVersion can be removed + private volatile ProtocolVersion m_readVersion = null, m_writeVersion = null; + private volatile bool m_inConnection; + private volatile bool m_inHandshake; + private volatile int m_plaintextLimit; + private DtlsEpoch m_currentEpoch, m_pendingEpoch; + private DtlsEpoch m_readEpoch, m_writeEpoch; + + private DtlsHandshakeRetransmit m_retransmit = null; + private DtlsEpoch m_retransmitEpoch = null; + private Timeout m_retransmitTimeout = null; + + private TlsHeartbeat m_heartbeat = null; // If non-null, controls the sending of heartbeat requests + private bool m_heartBeatResponder = false; // Whether we should send heartbeat responses + + private HeartbeatMessage m_heartbeatInFlight = null; // The current in-flight heartbeat request, if any + private Timeout m_heartbeatTimeout = null; // Idle timeout (if none in-flight), else expiry timeout for response + + private int m_heartbeatResendMillis = -1; // Delay before retransmit of current in-flight heartbeat request + private Timeout m_heartbeatResendTimeout = null; // Timeout for next retransmit of the in-flight heartbeat request + + internal DtlsRecordLayer(TlsContext context, TlsPeer peer, DatagramTransport transport) + { + this.m_context = context; + this.m_peer = peer; + this.m_transport = transport; + + this.m_inHandshake = true; + + this.m_currentEpoch = new DtlsEpoch(0, TlsNullNullCipher.Instance); + this.m_pendingEpoch = null; + this.m_readEpoch = m_currentEpoch; + this.m_writeEpoch = m_currentEpoch; + + SetPlaintextLimit(MAX_FRAGMENT_LENGTH); + } + + internal virtual bool IsClosed + { + get { return m_closed; } + } + + internal virtual void ResetAfterHelloVerifyRequestServer(long recordSeq) + { + this.m_inConnection = true; + + m_currentEpoch.SequenceNumber = recordSeq; + m_currentEpoch.ReplayWindow.Reset(recordSeq); + } + + internal virtual void SetPlaintextLimit(int plaintextLimit) + { + this.m_plaintextLimit = plaintextLimit; + } + + internal virtual int ReadEpoch + { + get { return m_readEpoch.Epoch; } + } + + internal virtual ProtocolVersion ReadVersion + { + get { return m_readVersion; } + set { this.m_readVersion = value; } + } + + internal virtual void SetWriteVersion(ProtocolVersion writeVersion) + { + this.m_writeVersion = writeVersion; + } + + internal virtual void InitPendingEpoch(TlsCipher pendingCipher) + { + if (m_pendingEpoch != null) + throw new InvalidOperationException(); + + /* + * TODO "In order to ensure that any given sequence/epoch pair is unique, implementations + * MUST NOT allow the same epoch value to be reused within two times the TCP maximum segment + * lifetime." + */ + + // TODO Check for overflow + this.m_pendingEpoch = new DtlsEpoch(m_writeEpoch.Epoch + 1, pendingCipher); + } + + internal virtual void HandshakeSuccessful(DtlsHandshakeRetransmit retransmit) + { + if (m_readEpoch == m_currentEpoch || m_writeEpoch == m_currentEpoch) + { + // TODO + throw new InvalidOperationException(); + } + + if (null != retransmit) + { + this.m_retransmit = retransmit; + this.m_retransmitEpoch = m_currentEpoch; + this.m_retransmitTimeout = new Timeout(RETRANSMIT_TIMEOUT); + } + + this.m_inHandshake = false; + this.m_currentEpoch = m_pendingEpoch; + this.m_pendingEpoch = null; + } + + internal virtual void InitHeartbeat(TlsHeartbeat heartbeat, bool heartbeatResponder) + { + if (m_inHandshake) + throw new InvalidOperationException(); + + this.m_heartbeat = heartbeat; + this.m_heartBeatResponder = heartbeatResponder; + + if (null != heartbeat) + { + ResetHeartbeat(); + } + } + + internal virtual void ResetWriteEpoch() + { + if (null != m_retransmitEpoch) + { + this.m_writeEpoch = m_retransmitEpoch; + } + else + { + this.m_writeEpoch = m_currentEpoch; + } + } + + /// + public virtual int GetReceiveLimit() + { + return System.Math.Min(m_plaintextLimit, + m_readEpoch.Cipher.GetPlaintextLimit(m_transport.GetReceiveLimit() - RECORD_HEADER_LENGTH)); + } + + /// + public virtual int GetSendLimit() + { + return System.Math.Min(m_plaintextLimit, + m_writeEpoch.Cipher.GetPlaintextLimit(m_transport.GetSendLimit() - RECORD_HEADER_LENGTH)); + } + + /// + public virtual int Receive(byte[] buf, int off, int len, int waitMillis) + { + long currentTimeMillis = DateTimeUtilities.CurrentUnixMs(); + + Timeout timeout = Timeout.ForWaitMillis(waitMillis, currentTimeMillis); + byte[] record = null; + + while (waitMillis >= 0) + { + if (null != m_retransmitTimeout && m_retransmitTimeout.RemainingMillis(currentTimeMillis) < 1) + { + m_retransmit = null; + m_retransmitEpoch = null; + m_retransmitTimeout = null; + } + + if (Timeout.HasExpired(m_heartbeatTimeout, currentTimeMillis)) + { + if (null != m_heartbeatInFlight) + throw new TlsTimeoutException("Heartbeat timed out"); + + this.m_heartbeatInFlight = HeartbeatMessage.Create(m_context, + HeartbeatMessageType.heartbeat_request, m_heartbeat.GeneratePayload()); + this.m_heartbeatTimeout = new Timeout(m_heartbeat.TimeoutMillis, currentTimeMillis); + + this.m_heartbeatResendMillis = DtlsReliableHandshake.INITIAL_RESEND_MILLIS; + this.m_heartbeatResendTimeout = new Timeout(m_heartbeatResendMillis, currentTimeMillis); + + SendHeartbeatMessage(m_heartbeatInFlight); + } + else if (Timeout.HasExpired(m_heartbeatResendTimeout, currentTimeMillis)) + { + this.m_heartbeatResendMillis = DtlsReliableHandshake.BackOff(m_heartbeatResendMillis); + this.m_heartbeatResendTimeout = new Timeout(m_heartbeatResendMillis, currentTimeMillis); + + SendHeartbeatMessage(m_heartbeatInFlight); + } + + waitMillis = Timeout.ConstrainWaitMillis(waitMillis, m_heartbeatTimeout, currentTimeMillis); + waitMillis = Timeout.ConstrainWaitMillis(waitMillis, m_heartbeatResendTimeout, currentTimeMillis); + + // NOTE: Guard against bad logic giving a negative value + if (waitMillis < 0) + { + waitMillis = 1; + } + + int receiveLimit = System.Math.Min(len, GetReceiveLimit()) + RECORD_HEADER_LENGTH; + if (null == record || record.Length < receiveLimit) + { + record = new byte[receiveLimit]; + } + + int received = ReceiveRecord(record, 0, receiveLimit, waitMillis); + int processed = ProcessRecord(received, record, buf, off); + if (processed >= 0) + { + return processed; + } + + currentTimeMillis = DateTimeUtilities.CurrentUnixMs(); + waitMillis = Timeout.GetWaitMillis(timeout, currentTimeMillis); + } + + return -1; + } + + /// + public virtual void Send(byte[] buf, int off, int len) + { + short contentType = ContentType.application_data; + + if (m_inHandshake || m_writeEpoch == m_retransmitEpoch) + { + contentType = ContentType.handshake; + + short handshakeType = TlsUtilities.ReadUint8(buf, off); + if (handshakeType == HandshakeType.finished) + { + DtlsEpoch nextEpoch = null; + if (m_inHandshake) + { + nextEpoch = m_pendingEpoch; + } + else if (m_writeEpoch == m_retransmitEpoch) + { + nextEpoch = m_currentEpoch; + } + + if (nextEpoch == null) + { + // TODO + throw new InvalidOperationException(); + } + + // Implicitly send change_cipher_spec and change to pending cipher state + + // TODO Send change_cipher_spec and finished records in single datagram? + byte[] data = new byte[]{ 1 }; + SendRecord(ContentType.change_cipher_spec, data, 0, data.Length); + + this.m_writeEpoch = nextEpoch; + } + } + + SendRecord(contentType, buf, off, len); + } + + /// + public virtual void Close() + { + if (!m_closed) + { + if (m_inHandshake && m_inConnection) + { + Warn(AlertDescription.user_canceled, "User canceled handshake"); + } + CloseTransport(); + } + } + + internal virtual void Fail(short alertDescription) + { + if (!m_closed) + { + if (m_inConnection) + { + try + { + RaiseAlert(AlertLevel.fatal, alertDescription, null, null); + } + catch (Exception) + { + // Ignore + } + } + + this.m_failed = true; + + CloseTransport(); + } + } + + internal virtual void Failed() + { + if (!m_closed) + { + this.m_failed = true; + + CloseTransport(); + } + } + + /// + internal virtual void Warn(short alertDescription, String message) + { + RaiseAlert(AlertLevel.warning, alertDescription, message, null); + } + + private void CloseTransport() + { + if (!m_closed) + { + /* + * RFC 5246 7.2.1. Unless some other fatal alert has been transmitted, each party is + * required to send a close_notify alert before closing the write side of the + * connection. The other party MUST respond with a close_notify alert of its own and + * close down the connection immediately, discarding any pending writes. + */ + + try + { + if (!m_failed) + { + Warn(AlertDescription.close_notify, null); + } + m_transport.Close(); + } + catch (Exception) + { + // Ignore + } + + this.m_closed = true; + } + } + + /// + private void RaiseAlert(short alertLevel, short alertDescription, string message, Exception cause) + { + m_peer.NotifyAlertRaised(alertLevel, alertDescription, message, cause); + + byte[] error = new byte[2]; + error[0] = (byte)alertLevel; + error[1] = (byte)alertDescription; + + SendRecord(ContentType.alert, error, 0, 2); + } + + /// + private int ReceiveDatagram(byte[] buf, int off, int len, int waitMillis) + { + try + { + return m_transport.Receive(buf, off, len, waitMillis); + } + catch (TlsTimeoutException) + { + return -1; + } +#if !PORTABLE || DOTNET + catch (SocketException e) + { + if (TlsUtilities.IsTimeout(e)) + return -1; + + throw e; + } +#endif + // TODO[tls-port] Can we support interrupted IO on .NET? + //catch (InterruptedIOException e) + //{ + // e.bytesTransferred = 0; + // throw e; + //} + } + + // TODO Include 'currentTimeMillis' as an argument, use with Timeout, resetHeartbeat + /// + private int ProcessRecord(int received, byte[] record, byte[] buf, int off) + { + // NOTE: received < 0 (timeout) is covered by this first case + if (received < RECORD_HEADER_LENGTH) + return -1; + + int length = TlsUtilities.ReadUint16(record, 11); + if (received != (length + RECORD_HEADER_LENGTH)) + return -1; + + // TODO[dtls13] Deal with opaque record type for 1.3 AEAD ciphers + short recordType = TlsUtilities.ReadUint8(record, 0); + + switch (recordType) + { + case ContentType.alert: + case ContentType.application_data: + case ContentType.change_cipher_spec: + case ContentType.handshake: + case ContentType.heartbeat: + break; + default: + return -1; + } + + int epoch = TlsUtilities.ReadUint16(record, 3); + + DtlsEpoch recordEpoch = null; + if (epoch == m_readEpoch.Epoch) + { + recordEpoch = m_readEpoch; + } + else if (recordType == ContentType.handshake && null != m_retransmitEpoch + && epoch == m_retransmitEpoch.Epoch) + { + recordEpoch = m_retransmitEpoch; + } + + if (null == recordEpoch) + return -1; + + long seq = TlsUtilities.ReadUint48(record, 5); + if (recordEpoch.ReplayWindow.ShouldDiscard(seq)) + return -1; + + ProtocolVersion recordVersion = TlsUtilities.ReadVersion(record, 1); + if (!recordVersion.IsDtls) + return -1; + + if (null != m_readVersion && !m_readVersion.Equals(recordVersion)) + { + /* + * Special-case handling for retransmitted ClientHello records. + * + * TODO Revisit how 'readVersion' works, since this is quite awkward. + */ + bool isClientHelloFragment = + ReadEpoch == 0 + && length > 0 + && ContentType.handshake == recordType + && HandshakeType.client_hello == TlsUtilities.ReadUint8(record, RECORD_HEADER_LENGTH); + + if (!isClientHelloFragment) + return -1; + } + + long macSeqNo = GetMacSequenceNumber(recordEpoch.Epoch, seq); + + TlsDecodeResult decoded = recordEpoch.Cipher.DecodeCiphertext(macSeqNo, recordType, recordVersion, record, + RECORD_HEADER_LENGTH, length); + + recordEpoch.ReplayWindow.ReportAuthenticated(seq); + + if (decoded.len > m_plaintextLimit) + return -1; + + if (decoded.len < 1 && decoded.contentType != ContentType.application_data) + return -1; + + if (null == m_readVersion) + { + bool isHelloVerifyRequest = + ReadEpoch == 0 + && length > 0 + && ContentType.handshake == recordType + && HandshakeType.hello_verify_request == TlsUtilities.ReadUint8(record, RECORD_HEADER_LENGTH); + + if (isHelloVerifyRequest) + { + /* + * RFC 6347 4.2.1 DTLS 1.2 server implementations SHOULD use DTLS version 1.0 + * regardless of the version of TLS that is expected to be negotiated. DTLS 1.2 and + * 1.0 clients MUST use the version solely to indicate packet formatting (which is + * the same in both DTLS 1.2 and 1.0) and not as part of version negotiation. + */ + if (!ProtocolVersion.DTLSv12.IsEqualOrLaterVersionOf(recordVersion)) + return -1; + } + else + { + this.m_readVersion = recordVersion; + } + } + + switch (decoded.contentType) + { + case ContentType.alert: + { + if (decoded.len == 2) + { + short alertLevel = TlsUtilities.ReadUint8(decoded.buf, decoded.off); + short alertDescription = TlsUtilities.ReadUint8(decoded.buf, decoded.off + 1); + + m_peer.NotifyAlertReceived(alertLevel, alertDescription); + + if (alertLevel == AlertLevel.fatal) + { + Failed(); + throw new TlsFatalAlert(alertDescription); + } + + // TODO Can close_notify be a fatal alert? + if (alertDescription == AlertDescription.close_notify) + { + CloseTransport(); + } + } + + return -1; + } + case ContentType.application_data: + { + if (m_inHandshake) + { + // TODO Consider buffering application data for new epoch that arrives + // out-of-order with the Finished message + return -1; + } + break; + } + case ContentType.change_cipher_spec: + { + // Implicitly receive change_cipher_spec and change to pending cipher state + + for (int i = 0; i < decoded.len; ++i) + { + short message = TlsUtilities.ReadUint8(decoded.buf, decoded.off + i); + if (message != ChangeCipherSpec.change_cipher_spec) + continue; + + if (m_pendingEpoch != null) + { + m_readEpoch = m_pendingEpoch; + } + } + + return -1; + } + case ContentType.handshake: + { + if (!m_inHandshake) + { + if (null != m_retransmit) + { + m_retransmit.ReceivedHandshakeRecord(epoch, decoded.buf, decoded.off, decoded.len); + } + + // TODO Consider support for HelloRequest + return -1; + } + break; + } + case ContentType.heartbeat: + { + if (null != m_heartbeatInFlight || m_heartBeatResponder) + { + try + { + MemoryStream input = new MemoryStream(decoded.buf, decoded.off, decoded.len, false); + HeartbeatMessage heartbeatMessage = HeartbeatMessage.Parse(input); + + if (null != heartbeatMessage) + { + switch (heartbeatMessage.Type) + { + case HeartbeatMessageType.heartbeat_request: + { + if (m_heartBeatResponder) + { + HeartbeatMessage response = HeartbeatMessage.Create(m_context, + HeartbeatMessageType.heartbeat_response, heartbeatMessage.Payload); + + SendHeartbeatMessage(response); + } + break; + } + case HeartbeatMessageType.heartbeat_response: + { + if (null != m_heartbeatInFlight + && Arrays.AreEqual(heartbeatMessage.Payload, m_heartbeatInFlight.Payload)) + { + ResetHeartbeat(); + } + break; + } + default: + break; + } + } + } + catch (Exception) + { + // Ignore + } + } + + return -1; + } + default: + return -1; + } + + /* + * NOTE: If we receive any non-handshake data in the new epoch implies the peer has + * received our final flight. + */ + if (!m_inHandshake && null != m_retransmit) + { + this.m_retransmit = null; + this.m_retransmitEpoch = null; + this.m_retransmitTimeout = null; + } + + Array.Copy(decoded.buf, decoded.off, buf, off, decoded.len); + return decoded.len; + } + + /// + private int ReceiveRecord(byte[] buf, int off, int len, int waitMillis) + { + if (m_recordQueue.Available > 0) + { + int length = 0; + if (m_recordQueue.Available >= RECORD_HEADER_LENGTH) + { + byte[] lengthBytes = new byte[2]; + m_recordQueue.Read(lengthBytes, 0, 2, 11); + length = TlsUtilities.ReadUint16(lengthBytes, 0); + } + + int received = System.Math.Min(m_recordQueue.Available, RECORD_HEADER_LENGTH + length); + m_recordQueue.RemoveData(buf, off, received, 0); + return received; + } + + { + int received = ReceiveDatagram(buf, off, len, waitMillis); + if (received >= RECORD_HEADER_LENGTH) + { + this.m_inConnection = true; + + int fragmentLength = TlsUtilities.ReadUint16(buf, off + 11); + int recordLength = RECORD_HEADER_LENGTH + fragmentLength; + if (received > recordLength) + { + m_recordQueue.AddData(buf, off + recordLength, received - recordLength); + received = recordLength; + } + } + + return received; + } + } + + private void ResetHeartbeat() + { + this.m_heartbeatInFlight = null; + this.m_heartbeatResendMillis = -1; + this.m_heartbeatResendTimeout = null; + this.m_heartbeatTimeout = new Timeout(m_heartbeat.IdleMillis); + } + + /// + private void SendHeartbeatMessage(HeartbeatMessage heartbeatMessage) + { + MemoryStream output = new MemoryStream(); + heartbeatMessage.Encode(output); + byte[] buf = output.ToArray(); + + SendRecord(ContentType.heartbeat, buf, 0, buf.Length); + } + + /* + * Currently uses synchronization to ensure heartbeat sends and application data sends don't + * interfere with each other. It may be overly cautious; the sequence number allocation is + * atomic, and if we synchronize only on the datagram send instead, then the only effect should + * be possible reordering of records (which might surprise a reliable transport implementation). + */ + /// + private void SendRecord(short contentType, byte[] buf, int off, int len) + { + // Never send anything until a valid ClientHello has been received + if (m_writeVersion == null) + return; + + if (len > m_plaintextLimit) + throw new TlsFatalAlert(AlertDescription.internal_error); + + /* + * RFC 5246 6.2.1 Implementations MUST NOT send zero-length fragments of Handshake, Alert, + * or ChangeCipherSpec content types. + */ + if (len < 1 && contentType != ContentType.application_data) + throw new TlsFatalAlert(AlertDescription.internal_error); + + lock (m_writeLock) + { + int recordEpoch = m_writeEpoch.Epoch; + long recordSequenceNumber = m_writeEpoch.AllocateSequenceNumber(); + long macSequenceNumber = GetMacSequenceNumber(recordEpoch, recordSequenceNumber); + ProtocolVersion recordVersion = m_writeVersion; + + TlsEncodeResult encoded = m_writeEpoch.Cipher.EncodePlaintext(macSequenceNumber, contentType, + recordVersion, RECORD_HEADER_LENGTH, buf, off, len); + + int ciphertextLength = encoded.len - RECORD_HEADER_LENGTH; + TlsUtilities.CheckUint16(ciphertextLength); + + TlsUtilities.WriteUint8(encoded.recordType, encoded.buf, encoded.off + 0); + TlsUtilities.WriteVersion(recordVersion, encoded.buf, encoded.off + 1); + TlsUtilities.WriteUint16(recordEpoch, encoded.buf, encoded.off + 3); + TlsUtilities.WriteUint48(recordSequenceNumber, encoded.buf, encoded.off + 5); + TlsUtilities.WriteUint16(ciphertextLength, encoded.buf, encoded.off + 11); + + SendDatagram(m_transport, encoded.buf, encoded.off, encoded.len); + } + } + + private static long GetMacSequenceNumber(int epoch, long sequence_number) + { + return ((epoch & 0xFFFFFFFFL) << 48) | sequence_number; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsRecordLayer.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsRecordLayer.cs.meta new file mode 100644 index 0000000..3924ef0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsRecordLayer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 21e5e3dfbb6811a4ebdb89947f3d0215 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsReliableHandshake.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsReliableHandshake.cs new file mode 100644 index 0000000..e27d727 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsReliableHandshake.cs @@ -0,0 +1,559 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Date; + +namespace Org.BouncyCastle.Tls +{ + internal class DtlsReliableHandshake + { + private const int MAX_RECEIVE_AHEAD = 16; + private const int MESSAGE_HEADER_LENGTH = 12; + + internal const int INITIAL_RESEND_MILLIS = 1000; + private const int MAX_RESEND_MILLIS = 60000; + + /// + internal static DtlsRequest ReadClientRequest(byte[] data, int dataOff, int dataLen, Stream dtlsOutput) + { + // TODO Support the possibility of a fragmented ClientHello datagram + + byte[] message = DtlsRecordLayer.ReceiveClientHelloRecord(data, dataOff, dataLen); + if (null == message || message.Length < MESSAGE_HEADER_LENGTH) + return null; + + long recordSeq = TlsUtilities.ReadUint48(data, dataOff + 5); + + short msgType = TlsUtilities.ReadUint8(message, 0); + if (HandshakeType.client_hello != msgType) + return null; + + int length = TlsUtilities.ReadUint24(message, 1); + if (message.Length != MESSAGE_HEADER_LENGTH + length) + return null; + + // TODO Consider stricter HelloVerifyRequest-related checks + //int messageSeq = TlsUtilities.ReadUint16(message, 4); + //if (messageSeq > 1) + // return null; + + int fragmentOffset = TlsUtilities.ReadUint24(message, 6); + if (0 != fragmentOffset) + return null; + + int fragmentLength = TlsUtilities.ReadUint24(message, 9); + if (length != fragmentLength) + return null; + + ClientHello clientHello = ClientHello.Parse( + new MemoryStream(message, MESSAGE_HEADER_LENGTH, length, false), dtlsOutput); + + return new DtlsRequest(recordSeq, message, clientHello); + } + + /// + internal static void SendHelloVerifyRequest(DatagramSender sender, long recordSeq, byte[] cookie) + { + TlsUtilities.CheckUint8(cookie.Length); + + int length = 3 + cookie.Length; + + byte[] message = new byte[MESSAGE_HEADER_LENGTH + length]; + TlsUtilities.WriteUint8(HandshakeType.hello_verify_request, message, 0); + TlsUtilities.WriteUint24(length, message, 1); + //TlsUtilities.WriteUint16(0, message, 4); + //TlsUtilities.WriteUint24(0, message, 6); + TlsUtilities.WriteUint24(length, message, 9); + + // HelloVerifyRequest fields + TlsUtilities.WriteVersion(ProtocolVersion.DTLSv10, message, MESSAGE_HEADER_LENGTH + 0); + TlsUtilities.WriteOpaque8(cookie, message, MESSAGE_HEADER_LENGTH + 2); + + DtlsRecordLayer.SendHelloVerifyRequestRecord(sender, recordSeq, message); + } + + /* + * No 'final' modifiers so that it works in earlier JDKs + */ + private DtlsRecordLayer m_recordLayer; + private Timeout m_handshakeTimeout; + + private TlsHandshakeHash m_handshakeHash; + + private IDictionary m_currentInboundFlight = Platform.CreateHashtable(); + private IDictionary m_previousInboundFlight = null; + private IList m_outboundFlight = Platform.CreateArrayList(); + + private int m_resendMillis = -1; + private Timeout m_resendTimeout = null; + + private int m_next_send_seq = 0, m_next_receive_seq = 0; + + internal DtlsReliableHandshake(TlsContext context, DtlsRecordLayer transport, int timeoutMillis, + DtlsRequest request) + { + this.m_recordLayer = transport; + this.m_handshakeHash = new DeferredHash(context); + this.m_handshakeTimeout = Timeout.ForWaitMillis(timeoutMillis); + + if (null != request) + { + this.m_resendMillis = INITIAL_RESEND_MILLIS; + this.m_resendTimeout = new Timeout(m_resendMillis); + + long recordSeq = request.RecordSeq; + int messageSeq = request.MessageSeq; + byte[] message = request.Message; + + m_recordLayer.ResetAfterHelloVerifyRequestServer(recordSeq); + + // Simulate a previous flight consisting of the request ClientHello + DtlsReassembler reassembler = new DtlsReassembler(HandshakeType.client_hello, + message.Length - MESSAGE_HEADER_LENGTH); + m_currentInboundFlight[messageSeq] = reassembler; + + // We sent HelloVerifyRequest with (message) sequence number 0 + this.m_next_send_seq = 1; + this.m_next_receive_seq = messageSeq + 1; + + m_handshakeHash.Update(message, 0, message.Length); + } + } + + internal void ResetAfterHelloVerifyRequestClient() + { + this.m_currentInboundFlight = Platform.CreateHashtable(); + this.m_previousInboundFlight = null; + this.m_outboundFlight = Platform.CreateArrayList(); + + this.m_resendMillis = -1; + this.m_resendTimeout = null; + + // We're waiting for ServerHello, always with (message) sequence number 1 + this.m_next_receive_seq = 1; + + m_handshakeHash.Reset(); + } + + internal TlsHandshakeHash HandshakeHash + { + get { return m_handshakeHash; } + } + + internal TlsHandshakeHash PrepareToFinish() + { + TlsHandshakeHash result = m_handshakeHash; + this.m_handshakeHash = m_handshakeHash.StopTracking(); + return result; + } + + /// + internal void SendMessage(short msg_type, byte[] body) + { + TlsUtilities.CheckUint24(body.Length); + + if (null != m_resendTimeout) + { + CheckInboundFlight(); + + this.m_resendMillis = -1; + this.m_resendTimeout = null; + + m_outboundFlight.Clear(); + } + + Message message = new Message(m_next_send_seq++, msg_type, body); + + m_outboundFlight.Add(message); + + WriteMessage(message); + UpdateHandshakeMessagesDigest(message); + } + + /// + internal byte[] ReceiveMessageBody(short msg_type) + { + Message message = ReceiveMessage(); + if (message.Type != msg_type) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + + return message.Body; + } + + /// + internal Message ReceiveMessage() + { + long currentTimeMillis = DateTimeUtilities.CurrentUnixMs(); + + if (null == m_resendTimeout) + { + m_resendMillis = INITIAL_RESEND_MILLIS; + m_resendTimeout = new Timeout(m_resendMillis, currentTimeMillis); + + PrepareInboundFlight(Platform.CreateHashtable()); + } + + byte[] buf = null; + + for (;;) + { + if (m_recordLayer.IsClosed) + throw new TlsFatalAlert(AlertDescription.user_canceled); + + Message pending = GetPendingMessage(); + if (pending != null) + return pending; + + if (Timeout.HasExpired(m_handshakeTimeout, currentTimeMillis)) + throw new TlsTimeoutException("Handshake timed out"); + + int waitMillis = Timeout.GetWaitMillis(m_handshakeTimeout, currentTimeMillis); + waitMillis = Timeout.ConstrainWaitMillis(waitMillis, m_resendTimeout, currentTimeMillis); + + // NOTE: Ensure a finite wait, of at least 1ms + if (waitMillis < 1) + { + waitMillis = 1; + } + + int receiveLimit = m_recordLayer.GetReceiveLimit(); + if (buf == null || buf.Length < receiveLimit) + { + buf = new byte[receiveLimit]; + } + + int received = m_recordLayer.Receive(buf, 0, receiveLimit, waitMillis); + if (received < 0) + { + ResendOutboundFlight(); + } + else + { + ProcessRecord(MAX_RECEIVE_AHEAD, m_recordLayer.ReadEpoch, buf, 0, received); + } + + currentTimeMillis = DateTimeUtilities.CurrentUnixMs(); + } + } + + internal void Finish() + { + DtlsHandshakeRetransmit retransmit = null; + if (null != m_resendTimeout) + { + CheckInboundFlight(); + } + else + { + PrepareInboundFlight(null); + + if (m_previousInboundFlight != null) + { + /* + * RFC 6347 4.2.4. In addition, for at least twice the default MSL defined for [TCP], + * when in the FINISHED state, the node that transmits the last flight (the server in an + * ordinary handshake or the client in a resumed handshake) MUST respond to a retransmit + * of the peer's last flight with a retransmit of the last flight. + */ + retransmit = new Retransmit(this); + } + } + + m_recordLayer.HandshakeSuccessful(retransmit); + } + + internal static int BackOff(int timeoutMillis) + { + /* + * TODO[DTLS] implementations SHOULD back off handshake packet size during the + * retransmit backoff. + */ + return System.Math.Min(timeoutMillis * 2, MAX_RESEND_MILLIS); + } + + /** + * Check that there are no "extra" messages left in the current inbound flight + */ + private void CheckInboundFlight() + { + foreach (int key in m_currentInboundFlight.Keys) + { + if (key >= m_next_receive_seq) + { + // TODO Should this be considered an error? + } + } + } + + /// + private Message GetPendingMessage() + { + DtlsReassembler next = (DtlsReassembler)m_currentInboundFlight[m_next_receive_seq]; + if (next != null) + { + byte[] body = next.GetBodyIfComplete(); + if (body != null) + { + m_previousInboundFlight = null; + return UpdateHandshakeMessagesDigest(new Message(m_next_receive_seq++, next.MsgType, body)); + } + } + return null; + } + + private void PrepareInboundFlight(IDictionary nextFlight) + { + ResetAll(m_currentInboundFlight); + m_previousInboundFlight = m_currentInboundFlight; + m_currentInboundFlight = nextFlight; + } + + /// + private void ProcessRecord(int windowSize, int epoch, byte[] buf, int off, int len) + { + bool checkPreviousFlight = false; + + while (len >= MESSAGE_HEADER_LENGTH) + { + int fragment_length = TlsUtilities.ReadUint24(buf, off + 9); + int message_length = fragment_length + MESSAGE_HEADER_LENGTH; + if (len < message_length) + { + // NOTE: Truncated message - ignore it + break; + } + + int length = TlsUtilities.ReadUint24(buf, off + 1); + int fragment_offset = TlsUtilities.ReadUint24(buf, off + 6); + if (fragment_offset + fragment_length > length) + { + // NOTE: Malformed fragment - ignore it and the rest of the record + break; + } + + /* + * NOTE: This very simple epoch check will only work until we want to support + * renegotiation (and we're not likely to do that anyway). + */ + short msg_type = TlsUtilities.ReadUint8(buf, off + 0); + int expectedEpoch = msg_type == HandshakeType.finished ? 1 : 0; + if (epoch != expectedEpoch) + break; + + int message_seq = TlsUtilities.ReadUint16(buf, off + 4); + if (message_seq >= (m_next_receive_seq + windowSize)) + { + // NOTE: Too far ahead - ignore + } + else if (message_seq >= m_next_receive_seq) + { + DtlsReassembler reassembler = (DtlsReassembler)m_currentInboundFlight[message_seq]; + if (reassembler == null) + { + reassembler = new DtlsReassembler(msg_type, length); + m_currentInboundFlight[message_seq] = reassembler; + } + + reassembler.ContributeFragment(msg_type, length, buf, off + MESSAGE_HEADER_LENGTH, fragment_offset, + fragment_length); + } + else if (m_previousInboundFlight != null) + { + /* + * NOTE: If we receive the previous flight of incoming messages in full again, + * retransmit our last flight + */ + + DtlsReassembler reassembler = (DtlsReassembler)m_previousInboundFlight[message_seq]; + if (reassembler != null) + { + reassembler.ContributeFragment(msg_type, length, buf, off + MESSAGE_HEADER_LENGTH, + fragment_offset, fragment_length); + checkPreviousFlight = true; + } + } + + off += message_length; + len -= message_length; + } + + if (checkPreviousFlight && CheckAll(m_previousInboundFlight)) + { + ResendOutboundFlight(); + ResetAll(m_previousInboundFlight); + } + } + + /// + private void ResendOutboundFlight() + { + m_recordLayer.ResetWriteEpoch(); + foreach (Message message in m_outboundFlight) + { + WriteMessage(message); + } + + m_resendMillis = BackOff(m_resendMillis); + m_resendTimeout = new Timeout(m_resendMillis); + } + + /// + private Message UpdateHandshakeMessagesDigest(Message message) + { + short msg_type = message.Type; + switch (msg_type) + { + case HandshakeType.hello_request: + case HandshakeType.hello_verify_request: + case HandshakeType.key_update: + break; + + // TODO[dtls13] Not included in the transcript for (D)TLS 1.3+ + case HandshakeType.new_session_ticket: + default: + { + byte[] body = message.Body; + byte[] buf = new byte[MESSAGE_HEADER_LENGTH]; + TlsUtilities.WriteUint8(msg_type, buf, 0); + TlsUtilities.WriteUint24(body.Length, buf, 1); + TlsUtilities.WriteUint16(message.Seq, buf, 4); + TlsUtilities.WriteUint24(0, buf, 6); + TlsUtilities.WriteUint24(body.Length, buf, 9); + m_handshakeHash.Update(buf, 0, buf.Length); + m_handshakeHash.Update(body, 0, body.Length); + break; + } + } + + return message; + } + + /// + private void WriteMessage(Message message) + { + int sendLimit = m_recordLayer.GetSendLimit(); + int fragmentLimit = sendLimit - MESSAGE_HEADER_LENGTH; + + // TODO Support a higher minimum fragment size? + if (fragmentLimit < 1) + { + // TODO Should we be throwing an exception here? + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + int length = message.Body.Length; + + // NOTE: Must still send a fragment if body is empty + int fragment_offset = 0; + do + { + int fragment_length = System.Math.Min(length - fragment_offset, fragmentLimit); + WriteHandshakeFragment(message, fragment_offset, fragment_length); + fragment_offset += fragment_length; + } + while (fragment_offset < length); + } + + /// + private void WriteHandshakeFragment(Message message, int fragment_offset, int fragment_length) + { + RecordLayerBuffer fragment = new RecordLayerBuffer(MESSAGE_HEADER_LENGTH + fragment_length); + TlsUtilities.WriteUint8(message.Type, fragment); + TlsUtilities.WriteUint24(message.Body.Length, fragment); + TlsUtilities.WriteUint16(message.Seq, fragment); + TlsUtilities.WriteUint24(fragment_offset, fragment); + TlsUtilities.WriteUint24(fragment_length, fragment); + fragment.Write(message.Body, fragment_offset, fragment_length); + + fragment.SendToRecordLayer(m_recordLayer); + } + + private static bool CheckAll(IDictionary inboundFlight) + { + foreach (DtlsReassembler r in inboundFlight.Values) + { + if (r.GetBodyIfComplete() == null) + return false; + } + return true; + } + + private static void ResetAll(IDictionary inboundFlight) + { + foreach (DtlsReassembler r in inboundFlight.Values) + { + r.Reset(); + } + } + + internal class Message + { + private readonly int m_message_seq; + private readonly short m_msg_type; + private readonly byte[] m_body; + + internal Message(int message_seq, short msg_type, byte[] body) + { + this.m_message_seq = message_seq; + this.m_msg_type = msg_type; + this.m_body = body; + } + + public int Seq + { + get { return m_message_seq; } + } + + public short Type + { + get { return m_msg_type; } + } + + public byte[] Body + { + get { return m_body; } + } + } + + internal class RecordLayerBuffer + : MemoryStream + { + internal RecordLayerBuffer(int size) + : base(size) + { + } + + internal void SendToRecordLayer(DtlsRecordLayer recordLayer) + { +#if PORTABLE + byte[] buf = ToArray(); + int bufLen = buf.Length; +#else + byte[] buf = GetBuffer(); + int bufLen = (int)Length; +#endif + + recordLayer.Send(buf, 0, bufLen); + Platform.Dispose(this); + } + } + + internal class Retransmit + : DtlsHandshakeRetransmit + { + private readonly DtlsReliableHandshake m_outer; + + internal Retransmit(DtlsReliableHandshake outer) + { + this.m_outer = outer; + } + + public void ReceivedHandshakeRecord(int epoch, byte[] buf, int off, int len) + { + m_outer.ProcessRecord(0, epoch, buf, off, len); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsReliableHandshake.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsReliableHandshake.cs.meta new file mode 100644 index 0000000..6c42804 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsReliableHandshake.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 86777160b9b595b4283ed9db7e0e9e93 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsReplayWindow.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsReplayWindow.cs new file mode 100644 index 0000000..a08114c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsReplayWindow.cs @@ -0,0 +1,84 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + /** + * RFC 4347 4.1.2.5 Anti-replay + *

    + * Support fast rejection of duplicate records by maintaining a sliding receive window + *

    + */ + internal sealed class DtlsReplayWindow + { + private const long ValidSeqMask = 0x0000FFFFFFFFFFFFL; + + private const long WindowSize = 64L; + + private long m_latestConfirmedSeq = -1; + private ulong m_bitmap = 0; + + /// Check whether a received record with the given sequence number should be rejected as a duplicate. + /// + /// the 48-bit DTLSPlainText.sequence_number field of a received record. + /// true if the record should be discarded without further processing. + internal bool ShouldDiscard(long seq) + { + if ((seq & ValidSeqMask) != seq) + return true; + + if (seq <= m_latestConfirmedSeq) + { + long diff = m_latestConfirmedSeq - seq; + if (diff >= WindowSize) + return true; + + if ((m_bitmap & (1UL << (int)diff)) != 0) + return true; + } + + return false; + } + + /// Report that a received record with the given sequence number passed authentication checks. + /// + /// the 48-bit DTLSPlainText.sequence_number field of an authenticated record. + internal void ReportAuthenticated(long seq) + { + if ((seq & ValidSeqMask) != seq) + throw new ArgumentException("out of range", "seq"); + + if (seq <= m_latestConfirmedSeq) + { + long diff = m_latestConfirmedSeq - seq; + if (diff < WindowSize) + { + m_bitmap |= (1UL << (int)diff); + } + } + else + { + long diff = seq - m_latestConfirmedSeq; + if (diff >= WindowSize) + { + m_bitmap = 1; + } + else + { + m_bitmap <<= (int)diff; // for earlier JDKs + m_bitmap |= 1UL; + } + m_latestConfirmedSeq = seq; + } + } + + internal void Reset(long seq) + { + if ((seq & ValidSeqMask) != seq) + throw new ArgumentException("out of range", "seq"); + + // Discard future records unless sequence number > 'seq' + m_latestConfirmedSeq = seq; + m_bitmap = ulong.MaxValue >> (int)System.Math.Max(0, 63 - seq); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsReplayWindow.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsReplayWindow.cs.meta new file mode 100644 index 0000000..475ae9d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsReplayWindow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9c5deaf8f4c42bf4d92bb63648cb5fa1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsRequest.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsRequest.cs new file mode 100644 index 0000000..126429e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsRequest.cs @@ -0,0 +1,38 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + public sealed class DtlsRequest + { + private readonly long m_recordSeq; + private readonly byte[] m_message; + private readonly ClientHello m_clientHello; + + internal DtlsRequest(long recordSeq, byte[] message, ClientHello clientHello) + { + this.m_recordSeq = recordSeq; + this.m_message = message; + this.m_clientHello = clientHello; + } + + internal ClientHello ClientHello + { + get { return m_clientHello; } + } + + internal byte[] Message + { + get { return m_message; } + } + + internal int MessageSeq + { + get { return TlsUtilities.ReadUint16(m_message, 4); } + } + + internal long RecordSeq + { + get { return m_recordSeq; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsRequest.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsRequest.cs.meta new file mode 100644 index 0000000..893d331 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsRequest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ef8a213b40de558489a68abb0a2b3219 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsServerProtocol.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsServerProtocol.cs new file mode 100644 index 0000000..99c47ba --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsServerProtocol.cs @@ -0,0 +1,840 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Tls.Crypto; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Tls +{ + public class DtlsServerProtocol + : DtlsProtocol + { + protected bool m_verifyRequests = true; + + public DtlsServerProtocol() + : base() + { + } + + public virtual bool VerifyRequests + { + get { return m_verifyRequests; } + set { this.m_verifyRequests = value; } + } + + /// + public virtual DtlsTransport Accept(TlsServer server, DatagramTransport transport) + { + return Accept(server, transport, null); + } + + /// + public virtual DtlsTransport Accept(TlsServer server, DatagramTransport transport, DtlsRequest request) + { + if (server == null) + throw new ArgumentNullException("server"); + if (transport == null) + throw new ArgumentNullException("transport"); + + ServerHandshakeState state = new ServerHandshakeState(); + state.server = server; + state.serverContext = new TlsServerContextImpl(server.Crypto); + server.Init(state.serverContext); + state.serverContext.HandshakeBeginning(server); + + SecurityParameters securityParameters = state.serverContext.SecurityParameters; + securityParameters.m_extendedPadding = server.ShouldUseExtendedPadding(); + + DtlsRecordLayer recordLayer = new DtlsRecordLayer(state.serverContext, state.server, transport); + server.NotifyCloseHandle(recordLayer); + + try + { + return ServerHandshake(state, recordLayer, request); + } + catch (TlsFatalAlert fatalAlert) + { + AbortServerHandshake(state, recordLayer, fatalAlert.AlertDescription); + throw fatalAlert; + } + catch (IOException e) + { + AbortServerHandshake(state, recordLayer, AlertDescription.internal_error); + throw e; + } + catch (Exception e) + { + AbortServerHandshake(state, recordLayer, AlertDescription.internal_error); + throw new TlsFatalAlert(AlertDescription.internal_error, e); + } + finally + { + securityParameters.Clear(); + } + } + + internal virtual void AbortServerHandshake(ServerHandshakeState state, DtlsRecordLayer recordLayer, + short alertDescription) + { + recordLayer.Fail(alertDescription); + InvalidateSession(state); + } + + /// + internal virtual DtlsTransport ServerHandshake(ServerHandshakeState state, DtlsRecordLayer recordLayer, + DtlsRequest request) + { + SecurityParameters securityParameters = state.serverContext.SecurityParameters; + + DtlsReliableHandshake handshake = new DtlsReliableHandshake(state.serverContext, recordLayer, + state.server.GetHandshakeTimeoutMillis(), request); + + DtlsReliableHandshake.Message clientMessage = null; + + if (null == request) + { + clientMessage = handshake.ReceiveMessage(); + + // NOTE: DtlsRecordLayer requires any DTLS version, we don't otherwise constrain this + //ProtocolVersion recordLayerVersion = recordLayer.ReadVersion; + + if (clientMessage.Type == HandshakeType.client_hello) + { + ProcessClientHello(state, clientMessage.Body); + } + else + { + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + } + else + { + ProcessClientHello(state, request.ClientHello); + } + + /* + * NOTE: Currently no server support for session resumption + * + * If adding support, ensure securityParameters.tlsUnique is set to the localVerifyData, but + * ONLY when extended_master_secret has been negotiated (otherwise NULL). + */ + { + // TODO[resumption] + + state.tlsSession = TlsUtilities.ImportSession(TlsUtilities.EmptyBytes, null); + state.sessionParameters = null; + state.sessionMasterSecret = null; + } + + securityParameters.m_sessionID = state.tlsSession.SessionID; + + state.server.NotifySession(state.tlsSession); + + { + byte[] serverHelloBody = GenerateServerHello(state, recordLayer); + + // TODO[dtls13] Ideally, move this into GenerateServerHello once legacy_record_version clarified + { + ProtocolVersion recordLayerVersion = state.serverContext.ServerVersion; + recordLayer.ReadVersion = recordLayerVersion; + recordLayer.SetWriteVersion(recordLayerVersion); + } + + handshake.SendMessage(HandshakeType.server_hello, serverHelloBody); + } + + handshake.HandshakeHash.NotifyPrfDetermined(); + + IList serverSupplementalData = state.server.GetServerSupplementalData(); + if (serverSupplementalData != null) + { + byte[] supplementalDataBody = GenerateSupplementalData(serverSupplementalData); + handshake.SendMessage(HandshakeType.supplemental_data, supplementalDataBody); + } + + state.keyExchange = TlsUtilities.InitKeyExchangeServer(state.serverContext, state.server); + state.serverCredentials = TlsUtilities.EstablishServerCredentials(state.server); + + // Server certificate + { + Certificate serverCertificate = null; + + MemoryStream endPointHash = new MemoryStream(); + if (state.serverCredentials == null) + { + state.keyExchange.SkipServerCredentials(); + } + else + { + state.keyExchange.ProcessServerCredentials(state.serverCredentials); + + serverCertificate = state.serverCredentials.Certificate; + + SendCertificateMessage(state.serverContext, handshake, serverCertificate, endPointHash); + } + securityParameters.m_tlsServerEndPoint = endPointHash.ToArray(); + + // TODO[RFC 3546] Check whether empty certificates is possible, allowed, or excludes CertificateStatus + if (serverCertificate == null || serverCertificate.IsEmpty) + { + securityParameters.m_statusRequestVersion = 0; + } + } + + if (securityParameters.StatusRequestVersion > 0) + { + CertificateStatus certificateStatus = state.server.GetCertificateStatus(); + if (certificateStatus != null) + { + byte[] certificateStatusBody = GenerateCertificateStatus(state, certificateStatus); + handshake.SendMessage(HandshakeType.certificate_status, certificateStatusBody); + } + } + + byte[] serverKeyExchange = state.keyExchange.GenerateServerKeyExchange(); + if (serverKeyExchange != null) + { + handshake.SendMessage(HandshakeType.server_key_exchange, serverKeyExchange); + } + + if (state.serverCredentials != null) + { + state.certificateRequest = state.server.GetCertificateRequest(); + + if (null == state.certificateRequest) + { + /* + * For static agreement key exchanges, CertificateRequest is required since + * the client Certificate message is mandatory but can only be sent if the + * server requests it. + */ + if (!state.keyExchange.RequiresCertificateVerify) + throw new TlsFatalAlert(AlertDescription.internal_error); + } + else + { + if (TlsUtilities.IsTlsV12(state.serverContext) + != (state.certificateRequest.SupportedSignatureAlgorithms != null)) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + state.certificateRequest = TlsUtilities.ValidateCertificateRequest(state.certificateRequest, state.keyExchange); + + TlsUtilities.EstablishServerSigAlgs(securityParameters, state.certificateRequest); + + TlsUtilities.TrackHashAlgorithms(handshake.HandshakeHash, securityParameters.ServerSigAlgs); + + byte[] certificateRequestBody = GenerateCertificateRequest(state, state.certificateRequest); + handshake.SendMessage(HandshakeType.certificate_request, certificateRequestBody); + } + } + + handshake.SendMessage(HandshakeType.server_hello_done, TlsUtilities.EmptyBytes); + + bool forceBuffering = false; + TlsUtilities.SealHandshakeHash(state.serverContext, handshake.HandshakeHash, forceBuffering); + + clientMessage = handshake.ReceiveMessage(); + + if (clientMessage.Type == HandshakeType.supplemental_data) + { + ProcessClientSupplementalData(state, clientMessage.Body); + clientMessage = handshake.ReceiveMessage(); + } + else + { + state.server.ProcessClientSupplementalData(null); + } + + if (state.certificateRequest == null) + { + state.keyExchange.SkipClientCredentials(); + } + else + { + if (clientMessage.Type == HandshakeType.certificate) + { + ProcessClientCertificate(state, clientMessage.Body); + clientMessage = handshake.ReceiveMessage(); + } + else + { + if (TlsUtilities.IsTlsV12(state.serverContext)) + { + /* + * RFC 5246 If no suitable certificate is available, the client MUST send a + * certificate message containing no certificates. + * + * NOTE: In previous RFCs, this was SHOULD instead of MUST. + */ + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + NotifyClientCertificate(state, Certificate.EmptyChain); + } + } + + if (clientMessage.Type == HandshakeType.client_key_exchange) + { + ProcessClientKeyExchange(state, clientMessage.Body); + } + else + { + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + securityParameters.m_sessionHash = TlsUtilities.GetCurrentPrfHash(handshake.HandshakeHash); + + TlsProtocol.EstablishMasterSecret(state.serverContext, state.keyExchange); + recordLayer.InitPendingEpoch(TlsUtilities.InitCipher(state.serverContext)); + + /* + * RFC 5246 7.4.8 This message is only sent following a client certificate that has signing + * capability (i.e., all certificates except those containing fixed Diffie-Hellman + * parameters). + */ + { + TlsHandshakeHash certificateVerifyHash = handshake.PrepareToFinish(); + + if (ExpectCertificateVerifyMessage(state)) + { + byte[] certificateVerifyBody = handshake.ReceiveMessageBody(HandshakeType.certificate_verify); + ProcessCertificateVerify(state, certificateVerifyBody, certificateVerifyHash); + } + } + + // NOTE: Calculated exclusive of the actual Finished message from the client + securityParameters.m_peerVerifyData = TlsUtilities.CalculateVerifyData(state.serverContext, + handshake.HandshakeHash, false); + ProcessFinished(handshake.ReceiveMessageBody(HandshakeType.finished), securityParameters.PeerVerifyData); + + if (state.expectSessionTicket) + { + /* + * TODO[new_session_ticket] Check the server-side rules regarding the session ID, since the client + * is going to ignore any session ID it received once it sees the new_session_ticket message. + */ + + NewSessionTicket newSessionTicket = state.server.GetNewSessionTicket(); + byte[] newSessionTicketBody = GenerateNewSessionTicket(state, newSessionTicket); + handshake.SendMessage(HandshakeType.new_session_ticket, newSessionTicketBody); + } + + // NOTE: Calculated exclusive of the Finished message itself + securityParameters.m_localVerifyData = TlsUtilities.CalculateVerifyData(state.serverContext, + handshake.HandshakeHash, true); + handshake.SendMessage(HandshakeType.finished, securityParameters.LocalVerifyData); + + handshake.Finish(); + + state.sessionMasterSecret = securityParameters.MasterSecret; + + state.sessionParameters = new SessionParameters.Builder() + .SetCipherSuite(securityParameters.CipherSuite) + .SetExtendedMasterSecret(securityParameters.IsExtendedMasterSecret) + .SetLocalCertificate(securityParameters.LocalCertificate) + .SetMasterSecret(state.serverContext.Crypto.AdoptSecret(state.sessionMasterSecret)) + .SetNegotiatedVersion(securityParameters.NegotiatedVersion) + .SetPeerCertificate(securityParameters.PeerCertificate) + .SetPskIdentity(securityParameters.PskIdentity) + .SetSrpIdentity(securityParameters.SrpIdentity) + // TODO Consider filtering extensions that aren't relevant to resumed sessions + .SetServerExtensions(state.serverExtensions) + .Build(); + + state.tlsSession = TlsUtilities.ImportSession(state.tlsSession.SessionID, state.sessionParameters); + + securityParameters.m_tlsUnique = securityParameters.PeerVerifyData; + + state.serverContext.HandshakeComplete(state.server, state.tlsSession); + + recordLayer.InitHeartbeat(state.heartbeat, HeartbeatMode.peer_allowed_to_send == state.heartbeatPolicy); + + return new DtlsTransport(recordLayer); + } + + /// + protected virtual byte[] GenerateCertificateRequest(ServerHandshakeState state, + CertificateRequest certificateRequest) + { + MemoryStream buf = new MemoryStream(); + certificateRequest.Encode(state.serverContext, buf); + return buf.ToArray(); + } + + /// + protected virtual byte[] GenerateCertificateStatus(ServerHandshakeState state, + CertificateStatus certificateStatus) + { + MemoryStream buf = new MemoryStream(); + // TODO[tls13] Ensure this cannot happen for (D)TLS1.3+ + certificateStatus.Encode(buf); + return buf.ToArray(); + } + + /// + protected virtual byte[] GenerateNewSessionTicket(ServerHandshakeState state, + NewSessionTicket newSessionTicket) + { + MemoryStream buf = new MemoryStream(); + newSessionTicket.Encode(buf); + return buf.ToArray(); + } + + /// + internal virtual byte[] GenerateServerHello(ServerHandshakeState state, DtlsRecordLayer recordLayer) + { + TlsServerContextImpl context = state.serverContext; + SecurityParameters securityParameters = context.SecurityParameters; + + ProtocolVersion server_version = state.server.GetServerVersion(); + { + if (!ProtocolVersion.Contains(context.ClientSupportedVersions, server_version)) + throw new TlsFatalAlert(AlertDescription.internal_error); + + // TODO[dtls13] Read draft/RFC for guidance on the legacy_record_version field + //ProtocolVersion legacy_record_version = server_version.IsLaterVersionOf(ProtocolVersion.DTLSv12) + // ? ProtocolVersion.DTLSv12 + // : server_version; + + //recordLayer.SetWriteVersion(legacy_record_version); + securityParameters.m_negotiatedVersion = server_version; + + TlsUtilities.NegotiatedVersionDtlsServer(context); + } + + { + bool useGmtUnixTime = ProtocolVersion.DTLSv12.IsEqualOrLaterVersionOf(server_version) + && state.server.ShouldUseGmtUnixTime(); + + securityParameters.m_serverRandom = TlsProtocol.CreateRandomBlock(useGmtUnixTime, context); + + if (!server_version.Equals(ProtocolVersion.GetLatestDtls(state.server.GetProtocolVersions()))) + { + TlsUtilities.WriteDowngradeMarker(server_version, securityParameters.ServerRandom); + } + } + + { + int cipherSuite = ValidateSelectedCipherSuite(state.server.GetSelectedCipherSuite(), + AlertDescription.internal_error); + + if (!TlsUtilities.IsValidCipherSuiteSelection(state.offeredCipherSuites, cipherSuite) || + !TlsUtilities.IsValidVersionForCipherSuite(cipherSuite, securityParameters.NegotiatedVersion)) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + TlsUtilities.NegotiatedCipherSuite(securityParameters, cipherSuite); + } + + state.serverExtensions = TlsExtensionsUtilities.EnsureExtensionsInitialised( + state.server.GetServerExtensions()); + + state.server.GetServerExtensionsForConnection(state.serverExtensions); + + ProtocolVersion legacy_version = server_version; + if (server_version.IsLaterVersionOf(ProtocolVersion.DTLSv12)) + { + legacy_version = ProtocolVersion.DTLSv12; + + TlsExtensionsUtilities.AddSupportedVersionsExtensionServer(state.serverExtensions, server_version); + } + + /* + * RFC 5746 3.6. Server Behavior: Initial Handshake + */ + if (securityParameters.IsSecureRenegotiation) + { + byte[] renegExtData = TlsUtilities.GetExtensionData(state.serverExtensions, + ExtensionType.renegotiation_info); + bool noRenegExt = (null == renegExtData); + + if (noRenegExt) + { + /* + * Note that sending a "renegotiation_info" extension in response to a ClientHello + * containing only the SCSV is an explicit exception to the prohibition in RFC 5246, + * Section 7.4.1.4, on the server sending unsolicited extensions and is only allowed + * because the client is signaling its willingness to receive the extension via the + * TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV. + */ + + /* + * If the secure_renegotiation flag is set to TRUE, the server MUST include an empty + * "renegotiation_info" extension in the ServerHello message. + */ + state.serverExtensions[ExtensionType.renegotiation_info] = TlsProtocol.CreateRenegotiationInfo( + TlsUtilities.EmptyBytes); + } + } + + /* + * RFC 7627 4. Clients and servers SHOULD NOT accept handshakes that do not use the extended + * master secret [..]. (and see 5.2, 5.3) + * + * RFC 8446 Appendix D. Because TLS 1.3 always hashes in the transcript up to the server + * Finished, implementations which support both TLS 1.3 and earlier versions SHOULD indicate + * the use of the Extended Master Secret extension in their APIs whenever TLS 1.3 is used. + */ + if (TlsUtilities.IsTlsV13(server_version)) + { + securityParameters.m_extendedMasterSecret = true; + } + else + { + securityParameters.m_extendedMasterSecret = state.offeredExtendedMasterSecret + && state.server.ShouldUseExtendedMasterSecret(); + + if (securityParameters.IsExtendedMasterSecret) + { + TlsExtensionsUtilities.AddExtendedMasterSecretExtension(state.serverExtensions); + } + else if (state.server.RequiresExtendedMasterSecret()) + { + throw new TlsFatalAlert(AlertDescription.handshake_failure); + } + else if (state.resumedSession && !state.server.AllowLegacyResumption()) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + // Heartbeats + if (null != state.heartbeat || HeartbeatMode.peer_allowed_to_send == state.heartbeatPolicy) + { + TlsExtensionsUtilities.AddHeartbeatExtension(state.serverExtensions, + new HeartbeatExtension(state.heartbeatPolicy)); + } + + + + /* + * RFC 7301 3.1. When session resumption or session tickets [...] are used, the previous + * contents of this extension are irrelevant, and only the values in the new handshake + * messages are considered. + */ + securityParameters.m_applicationProtocol = TlsExtensionsUtilities.GetAlpnExtensionServer( + state.serverExtensions); + securityParameters.m_applicationProtocolSet = true; + + /* + * TODO RFC 3546 2.3 If [...] the older session is resumed, then the server MUST ignore + * extensions appearing in the client hello, and send a server hello containing no + * extensions. + */ + if (state.serverExtensions.Count > 0) + { + securityParameters.m_encryptThenMac = TlsExtensionsUtilities.HasEncryptThenMacExtension( + state.serverExtensions); + + securityParameters.m_maxFragmentLength = EvaluateMaxFragmentLengthExtension(state.resumedSession, + state.clientExtensions, state.serverExtensions, AlertDescription.internal_error); + + securityParameters.m_truncatedHmac = TlsExtensionsUtilities.HasTruncatedHmacExtension(state.serverExtensions); + + /* + * TODO It's surprising that there's no provision to allow a 'fresh' CertificateStatus to be sent in + * a session resumption handshake. + */ + if (!state.resumedSession) + { + // TODO[tls13] See RFC 8446 4.4.2.1 + if (TlsUtilities.HasExpectedEmptyExtensionData(state.serverExtensions, + ExtensionType.status_request_v2, AlertDescription.internal_error)) + { + securityParameters.m_statusRequestVersion = 2; + } + else if (TlsUtilities.HasExpectedEmptyExtensionData(state.serverExtensions, + ExtensionType.status_request, AlertDescription.internal_error)) + { + securityParameters.m_statusRequestVersion = 1; + } + } + + state.expectSessionTicket = !state.resumedSession + && TlsUtilities.HasExpectedEmptyExtensionData(state.serverExtensions, ExtensionType.session_ticket, + AlertDescription.internal_error); + } + + ApplyMaxFragmentLengthExtension(recordLayer, securityParameters.MaxFragmentLength); + + + + ServerHello serverHello = new ServerHello(legacy_version, securityParameters.ServerRandom, + state.tlsSession.SessionID, securityParameters.CipherSuite, state.serverExtensions); + + MemoryStream buf = new MemoryStream(); + serverHello.Encode(state.serverContext, buf); + return buf.ToArray(); + } + + protected virtual void InvalidateSession(ServerHandshakeState state) + { + if (state.sessionMasterSecret != null) + { + state.sessionMasterSecret.Destroy(); + state.sessionMasterSecret = null; + } + + if (state.sessionParameters != null) + { + state.sessionParameters.Clear(); + state.sessionParameters = null; + } + + if (state.tlsSession != null) + { + state.tlsSession.Invalidate(); + state.tlsSession = null; + } + } + + /// + protected virtual void NotifyClientCertificate(ServerHandshakeState state, Certificate clientCertificate) + { + if (null == state.certificateRequest) + throw new TlsFatalAlert(AlertDescription.internal_error); + + TlsUtilities.ProcessClientCertificate(state.serverContext, clientCertificate, state.keyExchange, + state.server); + } + + /// + protected virtual void ProcessClientCertificate(ServerHandshakeState state, byte[] body) + { + MemoryStream buf = new MemoryStream(body, false); + + Certificate.ParseOptions options = new Certificate.ParseOptions() + .SetMaxChainLength(state.server.GetMaxCertificateChainLength()); + + Certificate clientCertificate = Certificate.Parse(options, state.serverContext, buf, null); + + TlsProtocol.AssertEmpty(buf); + + NotifyClientCertificate(state, clientCertificate); + } + + /// + protected virtual void ProcessCertificateVerify(ServerHandshakeState state, byte[] body, + TlsHandshakeHash handshakeHash) + { + if (state.certificateRequest == null) + throw new InvalidOperationException(); + + MemoryStream buf = new MemoryStream(body, false); + + TlsServerContextImpl context = state.serverContext; + DigitallySigned certificateVerify = DigitallySigned.Parse(context, buf); + + TlsProtocol.AssertEmpty(buf); + + TlsUtilities.VerifyCertificateVerifyClient(context, state.certificateRequest, certificateVerify, handshakeHash); + } + + /// + protected virtual void ProcessClientHello(ServerHandshakeState state, byte[] body) + { + MemoryStream buf = new MemoryStream(body, false); + ClientHello clientHello = ClientHello.Parse(buf, new NullOutputStream()); + ProcessClientHello(state, clientHello); + } + + /// + protected virtual void ProcessClientHello(ServerHandshakeState state, ClientHello clientHello) + { + // TODO Read RFCs for guidance on the expected record layer version number + ProtocolVersion legacy_version = clientHello.Version; + state.offeredCipherSuites = clientHello.CipherSuites; + + /* + * TODO RFC 3546 2.3 If [...] the older session is resumed, then the server MUST ignore + * extensions appearing in the client hello, and send a server hello containing no + * extensions. + */ + state.clientExtensions = clientHello.Extensions; + + + + TlsServerContextImpl context = state.serverContext; + SecurityParameters securityParameters = context.SecurityParameters; + + if (!legacy_version.IsDtls) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + context.SetRsaPreMasterSecretVersion(legacy_version); + + context.SetClientSupportedVersions( + TlsExtensionsUtilities.GetSupportedVersionsExtensionClient(state.clientExtensions)); + + ProtocolVersion client_version = legacy_version; + if (null == context.ClientSupportedVersions) + { + if (client_version.IsLaterVersionOf(ProtocolVersion.DTLSv12)) + { + client_version = ProtocolVersion.DTLSv12; + } + + context.SetClientSupportedVersions(client_version.DownTo(ProtocolVersion.DTLSv10)); + } + else + { + client_version = ProtocolVersion.GetLatestDtls(context.ClientSupportedVersions); + } + + if (!ProtocolVersion.SERVER_EARLIEST_SUPPORTED_DTLS.IsEqualOrEarlierVersionOf(client_version)) + throw new TlsFatalAlert(AlertDescription.protocol_version); + + context.SetClientVersion(client_version); + + state.server.NotifyClientVersion(context.ClientVersion); + + securityParameters.m_clientRandom = clientHello.Random; + + state.server.NotifyFallback(Arrays.Contains(state.offeredCipherSuites, CipherSuite.TLS_FALLBACK_SCSV)); + + state.server.NotifyOfferedCipherSuites(state.offeredCipherSuites); + + /* + * TODO[resumption] Check RFC 7627 5.4. for required behaviour + */ + + /* + * RFC 5746 3.6. Server Behavior: Initial Handshake + */ + { + /* + * RFC 5746 3.4. The client MUST include either an empty "renegotiation_info" extension, + * or the TLS_EMPTY_RENEGOTIATION_INFO_SCSV signaling cipher suite value in the + * ClientHello. Including both is NOT RECOMMENDED. + */ + + /* + * When a ClientHello is received, the server MUST check if it includes the + * TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV. If it does, set the secure_renegotiation flag + * to TRUE. + */ + if (Arrays.Contains(state.offeredCipherSuites, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV)) + { + securityParameters.m_secureRenegotiation = true; + } + + /* + * The server MUST check if the "renegotiation_info" extension is included in the + * ClientHello. + */ + byte[] renegExtData = TlsUtilities.GetExtensionData(state.clientExtensions, + ExtensionType.renegotiation_info); + if (renegExtData != null) + { + /* + * If the extension is present, set secure_renegotiation flag to TRUE. The + * server MUST then verify that the length of the "renegotiated_connection" + * field is zero, and if it is not, MUST abort the handshake. + */ + securityParameters.m_secureRenegotiation = true; + + if (!Arrays.ConstantTimeAreEqual(renegExtData, + TlsProtocol.CreateRenegotiationInfo(TlsUtilities.EmptyBytes))) + { + throw new TlsFatalAlert(AlertDescription.handshake_failure); + } + } + } + + state.server.NotifySecureRenegotiation(securityParameters.IsSecureRenegotiation); + + state.offeredExtendedMasterSecret = TlsExtensionsUtilities.HasExtendedMasterSecretExtension( + state.clientExtensions); + + if (state.clientExtensions != null) + { + // NOTE: Validates the padding extension data, if present + TlsExtensionsUtilities.GetPaddingExtension(state.clientExtensions); + + securityParameters.m_clientServerNames = TlsExtensionsUtilities.GetServerNameExtensionClient( + state.clientExtensions); + + /* + * RFC 5246 7.4.1.4.1. Note: this extension is not meaningful for TLS versions prior + * to 1.2. Clients MUST NOT offer it if they are offering prior versions. + */ + if (TlsUtilities.IsSignatureAlgorithmsExtensionAllowed(client_version)) + { + TlsUtilities.EstablishClientSigAlgs(securityParameters, state.clientExtensions); + } + + securityParameters.m_clientSupportedGroups = TlsExtensionsUtilities.GetSupportedGroupsExtension( + state.clientExtensions); + + // Heartbeats + { + HeartbeatExtension heartbeatExtension = TlsExtensionsUtilities.GetHeartbeatExtension( + state.clientExtensions); + if (null != heartbeatExtension) + { + if (HeartbeatMode.peer_allowed_to_send == heartbeatExtension.Mode) + { + state.heartbeat = state.server.GetHeartbeat(); + } + + state.heartbeatPolicy = state.server.GetHeartbeatPolicy(); + } + } + + state.server.ProcessClientExtensions(state.clientExtensions); + } + } + + /// + protected virtual void ProcessClientKeyExchange(ServerHandshakeState state, byte[] body) + { + MemoryStream buf = new MemoryStream(body, false); + state.keyExchange.ProcessClientKeyExchange(buf); + TlsProtocol.AssertEmpty(buf); + } + + /// + protected virtual void ProcessClientSupplementalData(ServerHandshakeState state, byte[] body) + { + MemoryStream buf = new MemoryStream(body, false); + IList clientSupplementalData = TlsProtocol.ReadSupplementalDataMessage(buf); + state.server.ProcessClientSupplementalData(clientSupplementalData); + } + + protected virtual bool ExpectCertificateVerifyMessage(ServerHandshakeState state) + { + if (null == state.certificateRequest) + return false; + + Certificate clientCertificate = state.serverContext.SecurityParameters.PeerCertificate; + + return null != clientCertificate && !clientCertificate.IsEmpty + && (null == state.keyExchange || state.keyExchange.RequiresCertificateVerify); + } + + protected internal class ServerHandshakeState + { + internal TlsServer server = null; + internal TlsServerContextImpl serverContext = null; + internal TlsSession tlsSession = null; + internal SessionParameters sessionParameters = null; + internal TlsSecret sessionMasterSecret = null; + internal SessionParameters.Builder sessionParametersBuilder = null; + internal int[] offeredCipherSuites = null; + internal IDictionary clientExtensions = null; + internal IDictionary serverExtensions = null; + internal bool offeredExtendedMasterSecret = false; + internal bool resumedSession = false; + internal bool expectSessionTicket = false; + internal TlsKeyExchange keyExchange = null; + internal TlsCredentials serverCredentials = null; + internal CertificateRequest certificateRequest = null; + internal TlsHeartbeat heartbeat = null; + internal short heartbeatPolicy = HeartbeatMode.peer_not_allowed_to_send; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsServerProtocol.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsServerProtocol.cs.meta new file mode 100644 index 0000000..44c4cce --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsServerProtocol.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: eb1360e2d2e53254d8aefaea4336de3f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsTransport.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsTransport.cs new file mode 100644 index 0000000..a41cb78 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsTransport.cs @@ -0,0 +1,139 @@ +using System; +using System.IO; +#if !PORTABLE || DOTNET +using System.Net.Sockets; +#endif + +namespace Org.BouncyCastle.Tls +{ + public class DtlsTransport + : DatagramTransport + { + private readonly DtlsRecordLayer m_recordLayer; + + internal DtlsTransport(DtlsRecordLayer recordLayer) + { + this.m_recordLayer = recordLayer; + } + + /// + public virtual int GetReceiveLimit() + { + return m_recordLayer.GetReceiveLimit(); + } + + /// + public virtual int GetSendLimit() + { + return m_recordLayer.GetSendLimit(); + } + + /// + public virtual int Receive(byte[] buf, int off, int len, int waitMillis) + { + if (null == buf) + throw new ArgumentNullException("buf"); + if (off < 0 || off >= buf.Length) + throw new ArgumentException("invalid offset: " + off, "off"); + if (len < 0 || len > buf.Length - off) + throw new ArgumentException("invalid length: " + len, "len"); + if (waitMillis < 0) + throw new ArgumentException("cannot be negative", "waitMillis"); + + try + { + return m_recordLayer.Receive(buf, off, len, waitMillis); + } + catch (TlsFatalAlert fatalAlert) + { + m_recordLayer.Fail(fatalAlert.AlertDescription); + throw fatalAlert; + } + catch (TlsTimeoutException e) + { + throw e; + } +#if !PORTABLE || DOTNET + catch (SocketException e) + { + if (TlsUtilities.IsTimeout(e)) + throw e; + + m_recordLayer.Fail(AlertDescription.internal_error); + throw new TlsFatalAlert(AlertDescription.internal_error, e); + } +#endif + // TODO[tls-port] Can we support interrupted IO on .NET? + //catch (InterruptedIOException e) + //{ + // throw e; + //} + catch (IOException e) + { + m_recordLayer.Fail(AlertDescription.internal_error); + throw e; + } + catch (Exception e) + { + m_recordLayer.Fail(AlertDescription.internal_error); + throw new TlsFatalAlert(AlertDescription.internal_error, e); + } + } + + /// + public virtual void Send(byte[] buf, int off, int len) + { + if (null == buf) + throw new ArgumentNullException("buf"); + if (off < 0 || off >= buf.Length) + throw new ArgumentException("invalid offset: " + off, "off"); + if (len < 0 || len > buf.Length - off) + throw new ArgumentException("invalid length: " + len, "len"); + + try + { + m_recordLayer.Send(buf, off, len); + } + catch (TlsFatalAlert fatalAlert) + { + m_recordLayer.Fail(fatalAlert.AlertDescription); + throw fatalAlert; + } + catch (TlsTimeoutException e) + { + throw e; + } +#if !PORTABLE || DOTNET + catch (SocketException e) + { + if (TlsUtilities.IsTimeout(e)) + throw e; + + m_recordLayer.Fail(AlertDescription.internal_error); + throw new TlsFatalAlert(AlertDescription.internal_error, e); + } +#endif + // TODO[tls-port] Can we support interrupted IO on .NET? + //catch (InterruptedIOException e) + //{ + // throw e; + //} + catch (IOException e) + { + m_recordLayer.Fail(AlertDescription.internal_error); + throw e; + } + catch (Exception e) + { + m_recordLayer.Fail(AlertDescription.internal_error); + throw new TlsFatalAlert(AlertDescription.internal_error, e); + } + } + + /// + public virtual void Close() + { + m_recordLayer.Close(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsTransport.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsTransport.cs.meta new file mode 100644 index 0000000..3966853 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsTransport.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6f1c48e069ce8bf4bb51e12450447458 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsVerifier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsVerifier.cs new file mode 100644 index 0000000..edadeae --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsVerifier.cs @@ -0,0 +1,89 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Tls.Crypto; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls +{ + public class DtlsVerifier + { + private static TlsMac CreateCookieMac(TlsCrypto crypto) + { + TlsMac mac = crypto.CreateHmac(MacAlgorithm.hmac_sha256); + + byte[] secret = new byte[mac.MacLength]; + crypto.SecureRandom.NextBytes(secret); + + mac.SetKey(secret, 0, secret.Length); + + return mac; + } + + private readonly TlsMac m_cookieMac; + private readonly TlsMacSink m_cookieMacSink; + + public DtlsVerifier(TlsCrypto crypto) + { + this.m_cookieMac = CreateCookieMac(crypto); + this.m_cookieMacSink = new TlsMacSink(m_cookieMac); + } + + public virtual DtlsRequest VerifyRequest(byte[] clientID, byte[] data, int dataOff, int dataLen, + DatagramSender sender) + { + lock (this) + { + bool resetCookieMac = true; + + try + { + m_cookieMac.Update(clientID, 0, clientID.Length); + + DtlsRequest request = DtlsReliableHandshake.ReadClientRequest(data, dataOff, dataLen, + m_cookieMacSink); + if (null != request) + { + byte[] expectedCookie = m_cookieMac.CalculateMac(); + resetCookieMac = false; + + // TODO Consider stricter HelloVerifyRequest protocol + //switch (request.MessageSeq) + //{ + //case 0: + //{ + // DtlsReliableHandshake.SendHelloVerifyRequest(sender, request.RecordSeq, expectedCookie); + // break; + //} + //case 1: + //{ + // if (Arrays.ConstantTimeAreEqual(expectedCookie, request.ClientHello.Cookie)) + // return request; + + // break; + //} + //} + + if (Arrays.ConstantTimeAreEqual(expectedCookie, request.ClientHello.Cookie)) + return request; + + DtlsReliableHandshake.SendHelloVerifyRequest(sender, request.RecordSeq, expectedCookie); + } + } + catch (IOException) + { + // Ignore + } + finally + { + if (resetCookieMac) + { + m_cookieMac.Reset(); + } + } + + return null; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsVerifier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsVerifier.cs.meta new file mode 100644 index 0000000..ac08c85 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/DtlsVerifier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1e12169367327374bbfeed0590cab11d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ECCurveType.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ECCurveType.cs new file mode 100644 index 0000000..969d51b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ECCurveType.cs @@ -0,0 +1,29 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + /// RFC 4492 5.4 + public abstract class ECCurveType + { + /** + * Indicates the elliptic curve domain parameters are conveyed verbosely, and the + * underlying finite field is a prime field. + */ + public const short explicit_prime = 1; + + /** + * Indicates the elliptic curve domain parameters are conveyed verbosely, and the + * underlying finite field is a characteristic-2 field. + */ + public const short explicit_char2 = 2; + + /** + * Indicates that a named curve is used. This option SHOULD be used when applicable. + */ + public const short named_curve = 3; + + /* + * Values 248 through 255 are reserved for private use. + */ + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ECCurveType.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ECCurveType.cs.meta new file mode 100644 index 0000000..66d5caa --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ECCurveType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 38d3f867f962a9142951d2ff484de431 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ECPointFormat.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ECPointFormat.cs new file mode 100644 index 0000000..d399cc6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ECPointFormat.cs @@ -0,0 +1,16 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + /// RFC 4492 5.1.2 + public abstract class ECPointFormat + { + public const short uncompressed = 0; + public const short ansiX962_compressed_prime = 1; + public const short ansiX962_compressed_char2 = 2; + + /* + * reserved (248..255) + */ + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ECPointFormat.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ECPointFormat.cs.meta new file mode 100644 index 0000000..7a462a8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ECPointFormat.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a40ef2fc43648814db93b63cc0d854c2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/EncryptionAlgorithm.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/EncryptionAlgorithm.cs new file mode 100644 index 0000000..8064451 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/EncryptionAlgorithm.cs @@ -0,0 +1,82 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + /// RFC 2246 + /// + /// Note that the values here are implementation-specific and arbitrary. It is recommended not to depend on the + /// particular values (e.g. serialization). + /// + public abstract class EncryptionAlgorithm + { + public const int NULL = 0; + public const int RC4_40 = 1; + public const int RC4_128 = 2; + public const int RC2_CBC_40 = 3; + public const int IDEA_CBC = 4; + public const int DES40_CBC = 5; + public const int DES_CBC = 6; + public const int cls_3DES_EDE_CBC = 7; + + /* + * RFC 3268 + */ + public const int AES_128_CBC = 8; + public const int AES_256_CBC = 9; + + /* + * RFC 5289 + */ + public const int AES_128_GCM = 10; + public const int AES_256_GCM = 11; + + /* + * RFC 5932 + */ + public const int CAMELLIA_128_CBC = 12; + public const int CAMELLIA_256_CBC = 13; + + /* + * RFC 4162 + */ + public const int SEED_CBC = 14; + + /* + * RFC 6655 + */ + public const int AES_128_CCM = 15; + public const int AES_128_CCM_8 = 16; + public const int AES_256_CCM = 17; + public const int AES_256_CCM_8 = 18; + + /* + * RFC 6367 + */ + public const int CAMELLIA_128_GCM = 19; + public const int CAMELLIA_256_GCM = 20; + + /* + * RFC 7905 + */ + public const int CHACHA20_POLY1305 = 21; + + /* + * RFC 6209 + */ + public const int ARIA_128_CBC = 22; + public const int ARIA_256_CBC = 23; + public const int ARIA_128_GCM = 24; + public const int ARIA_256_GCM = 25; + + /* + * RFC 8998 + */ + public const int SM4_CCM = 26; + public const int SM4_GCM = 27; + + /* + * GMT 0024-2014 + */ + public const int SM4_CBC = 28; + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/EncryptionAlgorithm.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/EncryptionAlgorithm.cs.meta new file mode 100644 index 0000000..fc3cdd0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/EncryptionAlgorithm.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d04f5b494fd1adf46b8b4f5c1e29258e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ExporterLabel.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ExporterLabel.cs new file mode 100644 index 0000000..481a3ee --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ExporterLabel.cs @@ -0,0 +1,42 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + /// RFC 5705 + public abstract class ExporterLabel + { + /* + * RFC 5246 + */ + public const string client_finished = "client finished"; + public const string server_finished = "server finished"; + public const string master_secret = "master secret"; + public const string key_expansion = "key expansion"; + + /* + * RFC 5216 + */ + public const string client_EAP_encryption = "client EAP encryption"; + + /* + * RFC 5281 + */ + public const string ttls_keying_material = "ttls keying material"; + public const string ttls_challenge = "ttls challenge"; + + /* + * RFC 5764 + */ + public const string dtls_srtp = "EXTRACTOR-dtls_srtp"; + + /* + * RFC 7627 + */ + public const string extended_master_secret = "extended master secret"; + + /* + * draft-ietf-tokbind-protocol-16 + */ + public const string token_binding = "EXPORTER-Token-Binding"; + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ExporterLabel.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ExporterLabel.cs.meta new file mode 100644 index 0000000..90b879a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ExporterLabel.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 98acea225bc64dd46b91bc48e5ef453f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ExtensionType.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ExtensionType.cs new file mode 100644 index 0000000..87f6a75 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ExtensionType.cs @@ -0,0 +1,279 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + public abstract class ExtensionType + { + /* + * RFC 2546 2.3. + */ + public const int server_name = 0; + public const int max_fragment_length = 1; + public const int client_certificate_url = 2; + public const int trusted_ca_keys = 3; + public const int truncated_hmac = 4; + public const int status_request = 5; + + /* + * RFC 4681 + */ + public const int user_mapping = 6; + + /* + * RFC 5878 + */ + public const int client_authz = 7; + public const int server_authz = 8; + + /* + * RFC 6091 + */ + public const int cert_type = 9; + + /* + * RFC 7919 (originally 'elliptic_curves' from RFC 4492) + */ + public const int supported_groups = 10; + + /* + * RFC 4492 5.1. + */ + public const int ec_point_formats = 11; + + /* + * RFC 5054 2.8.1. + */ + public const int srp = 12; + + /* + * RFC 5246 7.4.1.4. + */ + public const int signature_algorithms = 13; + + /* + * RFC 5764 9. + */ + public const int use_srtp = 14; + + /* + * RFC 6520 6. + */ + public const int heartbeat = 15; + + /* + * RFC 7301 + */ + public const int application_layer_protocol_negotiation = 16; + + /* + * RFC 6961 + */ + public const int status_request_v2 = 17; + + /* + * RFC 6962 + */ + public const int signed_certificate_timestamp = 18; + + /* + * RFC 7250 + */ + public const int client_certificate_type = 19; + public const int server_certificate_type = 20; + + /* + * RFC 7685 + */ + public const int padding = 21; + + /* + * RFC 7366 + */ + public const int encrypt_then_mac = 22; + + /* + * RFC 7627 + */ + public const int extended_master_secret = 23; + + /* + * RFC 8472 + */ + public const int token_binding = 24; + + /* + * RFC 7924 + */ + public const int cached_info = 25; + + /* + * RFC 8449 + */ + public const int record_size_limit = 28; + + /* + * RFC 5077 7. + */ + public const int session_ticket = 35; + + /* + * RFC 8446 + */ + public const int pre_shared_key = 41; + public const int early_data = 42; + public const int supported_versions = 43; + public const int cookie = 44; + public const int psk_key_exchange_modes = 45; + public const int certificate_authorities = 47; + public const int oid_filters = 48; + public const int post_handshake_auth = 49; + public const int signature_algorithms_cert = 50; + public const int key_share = 51; + + /* + * RFC 5746 3.2. + */ + public const int renegotiation_info = 0xff01; + + public static string GetName(int extensionType) + { + switch (extensionType) + { + case server_name: + return "server_name"; + case max_fragment_length: + return "max_fragment_length"; + case client_certificate_url: + return "client_certificate_url"; + case trusted_ca_keys: + return "trusted_ca_keys"; + case truncated_hmac: + return "truncated_hmac"; + case status_request: + return "status_request"; + case user_mapping: + return "user_mapping"; + case client_authz: + return "client_authz"; + case server_authz: + return "server_authz"; + case cert_type: + return "cert_type"; + case supported_groups: + return "supported_groups"; + case ec_point_formats: + return "ec_point_formats"; + case srp: + return "srp"; + case signature_algorithms: + return "signature_algorithms"; + case use_srtp: + return "use_srtp"; + case heartbeat: + return "heartbeat"; + case application_layer_protocol_negotiation: + return "application_layer_protocol_negotiation"; + case status_request_v2: + return "status_request_v2"; + case signed_certificate_timestamp: + return "signed_certificate_timestamp"; + case client_certificate_type: + return "client_certificate_type"; + case server_certificate_type: + return "server_certificate_type"; + case padding: + return "padding"; + case encrypt_then_mac: + return "encrypt_then_mac"; + case extended_master_secret: + return "extended_master_secret"; + case token_binding: + return "token_binding"; + case cached_info: + return "cached_info"; + case record_size_limit: + return "record_size_limit"; + case session_ticket: + return "session_ticket"; + case pre_shared_key: + return "pre_shared_key"; + case early_data: + return "early_data"; + case supported_versions: + return "supported_versions"; + case cookie: + return "cookie"; + case psk_key_exchange_modes: + return "psk_key_exchange_modes"; + case certificate_authorities: + return "certificate_authorities"; + case oid_filters: + return "oid_filters"; + case post_handshake_auth: + return "post_handshake_auth"; + case signature_algorithms_cert: + return "signature_algorithms_cert"; + case key_share: + return "key_share"; + case renegotiation_info: + return "renegotiation_info"; + default: + return "UNKNOWN"; + } + } + + public static string GetText(int extensionType) + { + return GetName(extensionType) + "(" + extensionType + ")"; + } + + public static bool IsRecognized(int extensionType) + { + switch (extensionType) + { + case server_name: + case max_fragment_length: + case client_certificate_url: + case trusted_ca_keys: + case truncated_hmac: + case status_request: + case user_mapping: + case client_authz: + case server_authz: + case cert_type: + case supported_groups: + case ec_point_formats: + case srp: + case signature_algorithms: + case use_srtp: + case heartbeat: + case application_layer_protocol_negotiation: + case status_request_v2: + case signed_certificate_timestamp: + case client_certificate_type: + case server_certificate_type: + case padding: + case encrypt_then_mac: + case extended_master_secret: + case token_binding: + case cached_info: + case record_size_limit: + case session_ticket: + case pre_shared_key: + case early_data: + case supported_versions: + case cookie: + case psk_key_exchange_modes: + case certificate_authorities: + case oid_filters: + case post_handshake_auth: + case signature_algorithms_cert: + case key_share: + case renegotiation_info: + return true; + default: + return false; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ExtensionType.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ExtensionType.cs.meta new file mode 100644 index 0000000..7c779f0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ExtensionType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9af6f3edc00606d49971e36ebb1a60ca +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/HandshakeMessageInput.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/HandshakeMessageInput.cs new file mode 100644 index 0000000..8d9a291 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/HandshakeMessageInput.cs @@ -0,0 +1,60 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Tls.Crypto; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Tls +{ + // TODO Rewrite without MemoryStream + public sealed class HandshakeMessageInput + : MemoryStream + { + private readonly int m_offset; + + internal HandshakeMessageInput(byte[] buf, int offset, int length) +#if PORTABLE + : base(buf, offset, length, false) +#else + : base(buf, offset, length, false, true) +#endif + { +#if PORTABLE + this.m_offset = 0; +#else + this.m_offset = offset; +#endif + } + + public void UpdateHash(TlsHash hash) + { + Streams.WriteBufTo(this, new TlsHashSink(hash)); + } + + internal void UpdateHashPrefix(TlsHash hash, int bindersSize) + { +#if PORTABLE + byte[] buf = ToArray(); + int count = buf.Length; +#else + byte[] buf = GetBuffer(); + int count = (int)Length; +#endif + + hash.Update(buf, m_offset, count - bindersSize); + } + + internal void UpdateHashSuffix(TlsHash hash, int bindersSize) + { +#if PORTABLE + byte[] buf = ToArray(); + int count = buf.Length; +#else + byte[] buf = GetBuffer(); + int count = (int)Length; +#endif + + hash.Update(buf, m_offset + count - bindersSize, bindersSize); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/HandshakeMessageInput.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/HandshakeMessageInput.cs.meta new file mode 100644 index 0000000..5bf74ba --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/HandshakeMessageInput.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 838299bd0b4051742bcbb14fa384a708 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/HandshakeMessageOutput.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/HandshakeMessageOutput.cs new file mode 100644 index 0000000..ff45ce6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/HandshakeMessageOutput.cs @@ -0,0 +1,104 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls +{ + internal sealed class HandshakeMessageOutput + : MemoryStream + { + internal static int GetLength(int bodyLength) + { + return 4 + bodyLength; + } + + /// + internal static void Send(TlsProtocol protocol, short handshakeType, byte[] body) + { + HandshakeMessageOutput message = new HandshakeMessageOutput(handshakeType, body.Length); + message.Write(body, 0, body.Length); + message.Send(protocol); + } + + /// + internal HandshakeMessageOutput(short handshakeType) + : this(handshakeType, 60) + { + } + + /// + internal HandshakeMessageOutput(short handshakeType, int bodyLength) + : base(GetLength(bodyLength)) + { + TlsUtilities.CheckUint8(handshakeType); + TlsUtilities.WriteUint8(handshakeType, this); + // Reserve space for length + Seek(3L, SeekOrigin.Current); + } + + /// + internal void Send(TlsProtocol protocol) + { + // Patch actual length back in + int bodyLength = (int)Length - 4; + TlsUtilities.CheckUint24(bodyLength); + + Seek(1L, SeekOrigin.Begin); + TlsUtilities.WriteUint24(bodyLength, this); + +#if PORTABLE + byte[] buf = ToArray(); + int count = buf.Length; +#else + byte[] buf = GetBuffer(); + int count = (int)Length; +#endif + protocol.WriteHandshakeMessage(buf, 0, count); + + Platform.Dispose(this); + } + + internal void PrepareClientHello(TlsHandshakeHash handshakeHash, int bindersSize) + { + // Patch actual length back in + int bodyLength = (int)Length - 4 + bindersSize; + TlsUtilities.CheckUint24(bodyLength); + + Seek(1L, SeekOrigin.Begin); + TlsUtilities.WriteUint24(bodyLength, this); + +#if PORTABLE + byte[] buf = ToArray(); + int count = buf.Length; +#else + byte[] buf = GetBuffer(); + int count = (int)Length; +#endif + + handshakeHash.Update(buf, 0, count); + + Seek(0L, SeekOrigin.End); + } + + internal void SendClientHello(TlsClientProtocol clientProtocol, TlsHandshakeHash handshakeHash, int bindersSize) + { +#if PORTABLE + byte[] buf = ToArray(); + int count = buf.Length; +#else + byte[] buf = GetBuffer(); + int count = (int)Length; +#endif + + if (bindersSize > 0) + { + handshakeHash.Update(buf, count - bindersSize, bindersSize); + } + + clientProtocol.WriteHandshakeMessage(buf, 0, count); + + Platform.Dispose(this); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/HandshakeMessageOutput.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/HandshakeMessageOutput.cs.meta new file mode 100644 index 0000000..396e69e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/HandshakeMessageOutput.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8b67adaad7f892942b2701ba054afc2b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/HandshakeType.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/HandshakeType.cs new file mode 100644 index 0000000..563cd11 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/HandshakeType.cs @@ -0,0 +1,131 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + public abstract class HandshakeType + { + /* + * RFC 2246 7.4 + */ + public const short hello_request = 0; + public const short client_hello = 1; + public const short server_hello = 2; + public const short certificate = 11; + public const short server_key_exchange = 12; + public const short certificate_request = 13; + public const short server_hello_done = 14; + public const short certificate_verify = 15; + public const short client_key_exchange = 16; + public const short finished = 20; + + /* + * RFC 3546 2.4 + */ + public const short certificate_url = 21; + public const short certificate_status = 22; + + /* + * (DTLS) RFC 4347 4.3.2 + */ + public const short hello_verify_request = 3; + + /* + * RFC 4680 + */ + public const short supplemental_data = 23; + + /* + * RFC 8446 + */ + public const short new_session_ticket = 4; + public const short end_of_early_data = 5; + public const short hello_retry_request = 6; + public const short encrypted_extensions = 8; + public const short key_update = 24; + public const short message_hash = 254; + + public static string GetName(short handshakeType) + { + switch (handshakeType) + { + case hello_request: + return "hello_request"; + case client_hello: + return "client_hello"; + case server_hello: + return "server_hello"; + case certificate: + return "certificate"; + case server_key_exchange: + return "server_key_exchange"; + case certificate_request: + return "certificate_request"; + case server_hello_done: + return "server_hello_done"; + case certificate_verify: + return "certificate_verify"; + case client_key_exchange: + return "client_key_exchange"; + case finished: + return "finished"; + case certificate_url: + return "certificate_url"; + case certificate_status: + return "certificate_status"; + case hello_verify_request: + return "hello_verify_request"; + case supplemental_data: + return "supplemental_data"; + case new_session_ticket: + return "new_session_ticket"; + case end_of_early_data: + return "end_of_early_data"; + case hello_retry_request: + return "hello_retry_request"; + case encrypted_extensions: + return "encrypted_extensions"; + case key_update: + return "key_update"; + case message_hash: + return "message_hash"; + default: + return "UNKNOWN"; + } + } + + public static string GetText(short handshakeType) + { + return GetName(handshakeType) + "(" + handshakeType + ")"; + } + + public static bool IsRecognized(short handshakeType) + { + switch (handshakeType) + { + case hello_request: + case client_hello: + case server_hello: + case certificate: + case server_key_exchange: + case certificate_request: + case server_hello_done: + case certificate_verify: + case client_key_exchange: + case finished: + case certificate_url: + case certificate_status: + case hello_verify_request: + case supplemental_data: + case new_session_ticket: + case end_of_early_data: + case hello_retry_request: + case encrypted_extensions: + case key_update: + case message_hash: + return true; + default: + return false; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/HandshakeType.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/HandshakeType.cs.meta new file mode 100644 index 0000000..44eebda --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/HandshakeType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c12094de64971ab4f8ce5323f6763653 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/HashAlgorithm.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/HashAlgorithm.cs new file mode 100644 index 0000000..2c8ba4f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/HashAlgorithm.cs @@ -0,0 +1,94 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + /// RFC 5246 7.4.1.4.1 + public abstract class HashAlgorithm + { + public const short none = 0; + public const short md5 = 1; + public const short sha1 = 2; + public const short sha224 = 3; + public const short sha256 = 4; + public const short sha384 = 5; + public const short sha512 = 6; + + /* + * RFC 8422 + */ + public const short Intrinsic = 8; + + public static string GetName(short hashAlgorithm) + { + switch (hashAlgorithm) + { + case none: + return "none"; + case md5: + return "md5"; + case sha1: + return "sha1"; + case sha224: + return "sha224"; + case sha256: + return "sha256"; + case sha384: + return "sha384"; + case sha512: + return "sha512"; + case Intrinsic: + return "Intrinsic"; + default: + return "UNKNOWN"; + } + } + + public static int GetOutputSize(short hashAlgorithm) + { + switch (hashAlgorithm) + { + case md5: + return 16; + case sha1: + return 20; + case sha224: + return 28; + case sha256: + return 32; + case sha384: + return 48; + case sha512: + return 64; + default: + return -1; + } + } + + public static string GetText(short hashAlgorithm) + { + return GetName(hashAlgorithm) + "(" + hashAlgorithm + ")"; + } + + public static bool IsPrivate(short hashAlgorithm) + { + return 224 <= hashAlgorithm && hashAlgorithm <= 255; + } + + public static bool IsRecognized(short hashAlgorithm) + { + switch (hashAlgorithm) + { + case md5: + case sha1: + case sha224: + case sha256: + case sha384: + case sha512: + case Intrinsic: + return true; + default: + return false; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/HashAlgorithm.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/HashAlgorithm.cs.meta new file mode 100644 index 0000000..4ffc618 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/HashAlgorithm.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ff4fe3ed796828f4aba63880ba74085d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/HeartbeatExtension.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/HeartbeatExtension.cs new file mode 100644 index 0000000..c44d84a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/HeartbeatExtension.cs @@ -0,0 +1,44 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Tls +{ + public sealed class HeartbeatExtension + { + private readonly short m_mode; + + public HeartbeatExtension(short mode) + { + if (!HeartbeatMode.IsValid(mode)) + throw new ArgumentException("not a valid HeartbeatMode value", "mode"); + + this.m_mode = mode; + } + + public short Mode + { + get { return m_mode; } + } + + /// Encode this to a . + /// the to encode to. + /// + public void Encode(Stream output) + { + TlsUtilities.WriteUint8(m_mode, output); + } + + /// Parse a from a . + /// the to parse from. + /// a object. + /// + public static HeartbeatExtension Parse(Stream input) + { + short mode = TlsUtilities.ReadUint8(input); + if (!HeartbeatMode.IsValid(mode)) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + return new HeartbeatExtension(mode); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/HeartbeatExtension.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/HeartbeatExtension.cs.meta new file mode 100644 index 0000000..516aae2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/HeartbeatExtension.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6cc1d5a4df4c7ec4793d2a79faf7a58b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/HeartbeatMessage.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/HeartbeatMessage.cs new file mode 100644 index 0000000..9e5c7d1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/HeartbeatMessage.cs @@ -0,0 +1,118 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Tls +{ + public sealed class HeartbeatMessage + { + public static HeartbeatMessage Create(TlsContext context, short type, byte[] payload) + { + return Create(context, type, payload, 16); + } + + public static HeartbeatMessage Create(TlsContext context, short type, byte[] payload, int paddingLength) + { + byte[] padding = context.NonceGenerator.GenerateNonce(paddingLength); + + return new HeartbeatMessage(type, payload, padding); + } + + private readonly short m_type; + private readonly byte[] m_payload; + private readonly byte[] m_padding; + + public HeartbeatMessage(short type, byte[] payload, byte[] padding) + { + if (!HeartbeatMessageType.IsValid(type)) + throw new ArgumentException("not a valid HeartbeatMessageType value", "type"); + if (null == payload || payload.Length >= (1 << 16)) + throw new ArgumentException("must have length < 2^16", "payload"); + if (null == padding || padding.Length < 16) + throw new ArgumentException("must have length >= 16", "padding"); + + this.m_type = type; + this.m_payload = payload; + this.m_padding = padding; + } + + public int PaddingLength + { + /* + * RFC 6520 4. The padding of a received HeartbeatMessage message MUST be ignored + */ + get { return m_padding.Length; } + } + + public byte[] Payload + { + get { return m_payload; } + } + + public short Type + { + get { return m_type; } + } + + /// Encode this to a . + /// the to encode to. + /// + public void Encode(Stream output) + { + TlsUtilities.WriteUint8(m_type, output); + + TlsUtilities.CheckUint16(m_payload.Length); + TlsUtilities.WriteUint16(m_payload.Length, output); + output.Write(m_payload, 0, m_payload.Length); + + output.Write(m_padding, 0, m_padding.Length); + } + + /// Parse a from a . + /// the to parse from. + /// a object. + /// + public static HeartbeatMessage Parse(Stream input) + { + short type = TlsUtilities.ReadUint8(input); + if (!HeartbeatMessageType.IsValid(type)) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + int payload_length = TlsUtilities.ReadUint16(input); + byte[] payloadBuffer = Streams.ReadAll(input); + + byte[] payload = GetPayload(payloadBuffer, payload_length); + if (null == payload) + { + /* + * RFC 6520 4. If the payload_length of a received HeartbeatMessage is too large, the received + * HeartbeatMessage MUST be discarded silently. + */ + return null; + } + + byte[] padding = GetPadding(payloadBuffer, payload_length); + + return new HeartbeatMessage(type, payload, padding); + } + + private static byte[] GetPayload(byte[] payloadBuffer, int payloadLength) + { + /* + * RFC 6520 4. The padding_length MUST be at least 16. + */ + int maxPayloadLength = payloadBuffer.Length - 16; + if (payloadLength > maxPayloadLength) + return null; + + return Arrays.CopyOf(payloadBuffer, payloadLength); + } + + private static byte[] GetPadding(byte[] payloadBuffer, int payloadLength) + { + return TlsUtilities.CopyOfRangeExact(payloadBuffer, payloadLength, payloadBuffer.Length); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/HeartbeatMessage.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/HeartbeatMessage.cs.meta new file mode 100644 index 0000000..0cdd94d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/HeartbeatMessage.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f9acb9d6e4b4bd04fa9ae9526fe0e591 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/HeartbeatMessageType.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/HeartbeatMessageType.cs new file mode 100644 index 0000000..18f86b1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/HeartbeatMessageType.cs @@ -0,0 +1,34 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + /// RFC 6520 3. + public abstract class HeartbeatMessageType + { + public const short heartbeat_request = 1; + public const short heartbeat_response = 2; + + public static string GetName(short heartbeatMessageType) + { + switch (heartbeatMessageType) + { + case heartbeat_request: + return "heartbeat_request"; + case heartbeat_response: + return "heartbeat_response"; + default: + return "UNKNOWN"; + } + } + + public static string GetText(short heartbeatMessageType) + { + return GetName(heartbeatMessageType) + "(" + heartbeatMessageType + ")"; + } + + public static bool IsValid(short heartbeatMessageType) + { + return heartbeatMessageType >= heartbeat_request && heartbeatMessageType <= heartbeat_response; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/HeartbeatMessageType.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/HeartbeatMessageType.cs.meta new file mode 100644 index 0000000..133dbc6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/HeartbeatMessageType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: adbf8117feec7904fb6ed506e161c4c5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/HeartbeatMode.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/HeartbeatMode.cs new file mode 100644 index 0000000..8e65d54 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/HeartbeatMode.cs @@ -0,0 +1,36 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + /* + * RFC 6520 + */ + public abstract class HeartbeatMode + { + public const short peer_allowed_to_send = 1; + public const short peer_not_allowed_to_send = 2; + + public static string GetName(short heartbeatMode) + { + switch (heartbeatMode) + { + case peer_allowed_to_send: + return "peer_allowed_to_send"; + case peer_not_allowed_to_send: + return "peer_not_allowed_to_send"; + default: + return "UNKNOWN"; + } + } + + public static string GetText(short heartbeatMode) + { + return GetName(heartbeatMode) + "(" + heartbeatMode + ")"; + } + + public static bool IsValid(short heartbeatMode) + { + return heartbeatMode >= peer_allowed_to_send && heartbeatMode <= peer_not_allowed_to_send; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/HeartbeatMode.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/HeartbeatMode.cs.meta new file mode 100644 index 0000000..cc45787 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/HeartbeatMode.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7ea5af25f1f50b942a61af7b621b4cc2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/IdentifierType.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/IdentifierType.cs new file mode 100644 index 0000000..df62e82 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/IdentifierType.cs @@ -0,0 +1,35 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + /// RFC 6066 + public abstract class IdentifierType + { + public const short pre_agreed = 0; + public const short key_sha1_hash = 1; + public const short x509_name = 2; + public const short cert_sha1_hash = 3; + + public static string GetName(short identifierType) + { + switch (identifierType) + { + case pre_agreed: + return "pre_agreed"; + case key_sha1_hash: + return "key_sha1_hash"; + case x509_name: + return "x509_name"; + case cert_sha1_hash: + return "cert_sha1_hash"; + default: + return "UNKNOWN"; + } + } + + public static string GetText(short identifierType) + { + return GetName(identifierType) + "(" + identifierType + ")"; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/IdentifierType.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/IdentifierType.cs.meta new file mode 100644 index 0000000..02a8162 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/IdentifierType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d38f84e6dba8a5d4b9a241f2e05ab1d6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/KeyExchangeAlgorithm.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/KeyExchangeAlgorithm.cs new file mode 100644 index 0000000..1dfa6db --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/KeyExchangeAlgorithm.cs @@ -0,0 +1,63 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + /// RFC 2246 + /// + /// Note that the values here are implementation-specific and arbitrary. It is recommended not to depend on the + /// particular values (e.g. serialization). + /// + public abstract class KeyExchangeAlgorithm + { + /* + * NOTE: We interpret TLS 1.3 cipher suites as having a NULL key exchange + */ + public const int NULL = 0; + + public const int RSA = 1; + public const int RSA_EXPORT = 2; + public const int DHE_DSS = 3; + public const int DHE_DSS_EXPORT = 4; + public const int DHE_RSA = 5; + public const int DHE_RSA_EXPORT = 6; + public const int DH_DSS = 7; + public const int DH_DSS_EXPORT = 8; + public const int DH_RSA = 9; + public const int DH_RSA_EXPORT = 10; + public const int DH_anon = 11; + public const int DH_anon_EXPORT = 12; + + /* + * RFC 4279 + */ + public const int PSK = 13; + public const int DHE_PSK = 14; + public const int RSA_PSK = 15; + + /* + * RFC 4429 + */ + public const int ECDH_ECDSA = 16; + public const int ECDHE_ECDSA = 17; + public const int ECDH_RSA = 18; + public const int ECDHE_RSA = 19; + public const int ECDH_anon = 20; + + /* + * RFC 5054 + */ + public const int SRP = 21; + public const int SRP_DSS = 22; + public const int SRP_RSA = 23; + + /* + * RFC 5489 + */ + public const int ECDHE_PSK = 24; + + /* + * GMT 0024-2014 + */ + public const int SM2 = 25; + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/KeyExchangeAlgorithm.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/KeyExchangeAlgorithm.cs.meta new file mode 100644 index 0000000..2006973 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/KeyExchangeAlgorithm.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c891c3e18f0592f44b1d7ccd844e976a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/KeyShareEntry.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/KeyShareEntry.cs new file mode 100644 index 0000000..c4be657 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/KeyShareEntry.cs @@ -0,0 +1,62 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Tls +{ + public sealed class KeyShareEntry + { + private static bool CheckKeyExchangeLength(int length) + { + return 0 < length && length < (1 << 16); + } + + private readonly int m_namedGroup; + private readonly byte[] m_keyExchange; + + /// + /// + public KeyShareEntry(int namedGroup, byte[] keyExchange) + { + if (!TlsUtilities.IsValidUint16(namedGroup)) + throw new ArgumentException("should be a uint16", "namedGroup"); + if (null == keyExchange) + throw new ArgumentNullException("keyExchange"); + if (!CheckKeyExchangeLength(keyExchange.Length)) + throw new ArgumentException("must have length from 1 to (2^16 - 1)", "keyExchange"); + + this.m_namedGroup = namedGroup; + this.m_keyExchange = keyExchange; + } + + /// + public int NamedGroup + { + get { return m_namedGroup; } + } + + public byte[] KeyExchange + { + get { return m_keyExchange; } + } + + /// Encode this to a . + /// the to encode to. + /// + public void Encode(Stream output) + { + TlsUtilities.WriteUint16(NamedGroup, output); + TlsUtilities.WriteOpaque16(KeyExchange, output); + } + + /// Parse a from a . + /// the to parse from. + /// a object. + /// + public static KeyShareEntry Parse(Stream input) + { + int namedGroup = TlsUtilities.ReadUint16(input); + byte[] keyExchange = TlsUtilities.ReadOpaque16(input, 1); + return new KeyShareEntry(namedGroup, keyExchange); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/KeyShareEntry.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/KeyShareEntry.cs.meta new file mode 100644 index 0000000..5a7f0c0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/KeyShareEntry.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c0b6472467efa6d4e943d4a083dc9c37 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/KeyUpdateRequest.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/KeyUpdateRequest.cs new file mode 100644 index 0000000..2a784e6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/KeyUpdateRequest.cs @@ -0,0 +1,34 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + /// RFC 8446 4.6.3 + public abstract class KeyUpdateRequest + { + public const short update_not_requested = 0; + public const short update_requested = 1; + + public static string GetName(short keyUpdateRequest) + { + switch (keyUpdateRequest) + { + case update_not_requested: + return "update_not_requested"; + case update_requested: + return "update_requested"; + default: + return "UNKNOWN"; + } + } + + public static string GetText(short keyUpdateRequest) + { + return GetName(keyUpdateRequest) + "(" + keyUpdateRequest + ")"; + } + + public static bool IsValid(short keyUpdateRequest) + { + return keyUpdateRequest >= update_not_requested && keyUpdateRequest <= update_requested; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/KeyUpdateRequest.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/KeyUpdateRequest.cs.meta new file mode 100644 index 0000000..8f64209 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/KeyUpdateRequest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e3d43df9e2daade47aa84a35c42e88a7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/MacAlgorithm.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/MacAlgorithm.cs new file mode 100644 index 0000000..1706de1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/MacAlgorithm.cs @@ -0,0 +1,66 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + /// RFC 2246 + /// + /// Note that the values here are implementation-specific and arbitrary. It is recommended not to depend on the + /// particular values (e.g. serialization). + /// + public abstract class MacAlgorithm + { + public const int cls_null = 0; + public const int md5 = 1; + public const int sha = 2; + + /* + * RFC 5246 + */ + public const int hmac_md5 = md5; + public const int hmac_sha1 = sha; + public const int hmac_sha256 = 3; + public const int hmac_sha384 = 4; + public const int hmac_sha512 = 5; + + public static string GetName(int macAlgorithm) + { + switch (macAlgorithm) + { + case cls_null: + return "null"; + case hmac_md5: + return "hmac_md5"; + case hmac_sha1: + return "hmac_sha1"; + case hmac_sha256: + return "hmac_sha256"; + case hmac_sha384: + return "hmac_sha384"; + case hmac_sha512: + return "hmac_sha512"; + default: + return "UNKNOWN"; + } + } + + public static string GetText(int macAlgorithm) + { + return GetName(macAlgorithm) + "(" + macAlgorithm + ")"; + } + + public static bool IsHmac(int macAlgorithm) + { + switch (macAlgorithm) + { + case hmac_md5: + case hmac_sha1: + case hmac_sha256: + case hmac_sha384: + case hmac_sha512: + return true; + default: + return false; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/MacAlgorithm.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/MacAlgorithm.cs.meta new file mode 100644 index 0000000..a3aea93 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/MacAlgorithm.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 97a7e78f29bbbaa41aa4b13b11a02284 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/MaxFragmentLength.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/MaxFragmentLength.cs new file mode 100644 index 0000000..d335de5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/MaxFragmentLength.cs @@ -0,0 +1,20 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + public abstract class MaxFragmentLength + { + /* + * RFC 3546 3.2. + */ + public const short pow2_9 = 1; + public const short pow2_10 = 2; + public const short pow2_11 = 3; + public const short pow2_12 = 4; + + public static bool IsValid(short maxFragmentLength) + { + return maxFragmentLength >= pow2_9 && maxFragmentLength <= pow2_12; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/MaxFragmentLength.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/MaxFragmentLength.cs.meta new file mode 100644 index 0000000..4a8275d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/MaxFragmentLength.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0675b9f6242eb5b42b15e9ef336d6adb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/NameType.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/NameType.cs new file mode 100644 index 0000000..f2e8ec6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/NameType.cs @@ -0,0 +1,38 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + public abstract class NameType + { + /* + * RFC 3546 3.1. + */ + public const short host_name = 0; + + public static string GetName(short nameType) + { + switch (nameType) + { + case host_name: + return "host_name"; + default: + return "UNKNOWN"; + } + } + + public static string GetText(short nameType) + { + return GetName(nameType) + "(" + nameType + ")"; + } + + public static bool IsRecognized(short nameType) + { + return host_name == nameType; + } + + public static bool IsValid(short nameType) + { + return TlsUtilities.IsValidUint8(nameType); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/NameType.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/NameType.cs.meta new file mode 100644 index 0000000..c011cd0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/NameType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 12460ae9e4220034d839a57d7fda3aee +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/NamedGroup.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/NamedGroup.cs new file mode 100644 index 0000000..0035ef9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/NamedGroup.cs @@ -0,0 +1,416 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + /// RFC 7919 + public abstract class NamedGroup + { + /* + * RFC 4492 5.1.1 + *

    + * The named curves defined here are those specified in SEC 2 [13]. Note that many of these curves + * are also recommended in ANSI X9.62 [7] and FIPS 186-2 [11]. Values 0xFE00 through 0xFEFF are + * reserved for private use. Values 0xFF01 and 0xFF02 indicate that the client supports arbitrary + * prime and characteristic-2 curves, respectively (the curve parameters must be encoded explicitly + * in ECParameters). + */ + public const int sect163k1 = 1; + public const int sect163r1 = 2; + public const int sect163r2 = 3; + public const int sect193r1 = 4; + public const int sect193r2 = 5; + public const int sect233k1 = 6; + public const int sect233r1 = 7; + public const int sect239k1 = 8; + public const int sect283k1 = 9; + public const int sect283r1 = 10; + public const int sect409k1 = 11; + public const int sect409r1 = 12; + public const int sect571k1 = 13; + public const int sect571r1 = 14; + public const int secp160k1 = 15; + public const int secp160r1 = 16; + public const int secp160r2 = 17; + public const int secp192k1 = 18; + public const int secp192r1 = 19; + public const int secp224k1 = 20; + public const int secp224r1 = 21; + public const int secp256k1 = 22; + public const int secp256r1 = 23; + public const int secp384r1 = 24; + public const int secp521r1 = 25; + + /* + * RFC 7027 + */ + public const int brainpoolP256r1 = 26; + public const int brainpoolP384r1 = 27; + public const int brainpoolP512r1 = 28; + + /* + * RFC 8422 + */ + public const int x25519 = 29; + public const int x448 = 30; + + /* + * RFC 8734 + */ + public const int brainpoolP256r1tls13 = 31; + public const int brainpoolP384r1tls13 = 32; + public const int brainpoolP512r1tls13 = 33; + + /* + * draft-smyshlyaev-tls12-gost-suites-10 + */ + public const int GC256A = 34; + public const int GC256B = 35; + public const int GC256C = 36; + public const int GC256D = 37; + public const int GC512A = 38; + public const int GC512B = 39; + public const int GC512C = 40; + + /* + * RFC 8998 + */ + public const int curveSM2 = 41; + + /* + * RFC 7919 2. Codepoints in the "Supported Groups Registry" with a high byte of 0x01 (that is, + * between 256 and 511, inclusive) are set aside for FFDHE groups, though only a small number of + * them are initially defined and we do not expect many other FFDHE groups to be added to this + * range. No codepoints outside of this range will be allocated to FFDHE groups. + */ + public const int ffdhe2048 = 256; + public const int ffdhe3072 = 257; + public const int ffdhe4096 = 258; + public const int ffdhe6144 = 259; + public const int ffdhe8192 = 260; + + /* + * RFC 8446 reserved ffdhe_private_use (0x01FC..0x01FF) + */ + + /* + * RFC 4492 reserved ecdhe_private_use (0xFE00..0xFEFF) + */ + + /* + * RFC 4492 + */ + public const int arbitrary_explicit_prime_curves = 0xFF01; + public const int arbitrary_explicit_char2_curves = 0xFF02; + + /* Names of the actual underlying elliptic curves (not necessarily matching the NamedGroup names). */ + private static readonly string[] CurveNames = new string[]{ "sect163k1", "sect163r1", "sect163r2", "sect193r1", + "sect193r2", "sect233k1", "sect233r1", "sect239k1", "sect283k1", "sect283r1", "sect409k1", "sect409r1", + "sect571k1", "sect571r1", "secp160k1", "secp160r1", "secp160r2", "secp192k1", "secp192r1", "secp224k1", + "secp224r1", "secp256k1", "secp256r1", "secp384r1", "secp521r1", "brainpoolP256r1", "brainpoolP384r1", + "brainpoolP512r1", "X25519", "X448", "brainpoolP256r1", "brainpoolP384r1", "brainpoolP512r1", + "Tc26-Gost-3410-12-256-paramSetA", "GostR3410-2001-CryptoPro-A", "GostR3410-2001-CryptoPro-B", + "GostR3410-2001-CryptoPro-C", "Tc26-Gost-3410-12-512-paramSetA", "Tc26-Gost-3410-12-512-paramSetB", + "Tc26-Gost-3410-12-512-paramSetC", "sm2p256v1" }; + + private static readonly string[] FiniteFieldNames = new string[]{ "ffdhe2048", "ffdhe3072", "ffdhe4096", + "ffdhe6144", "ffdhe8192" }; + + public static bool CanBeNegotiated(int namedGroup, ProtocolVersion version) + { + if (TlsUtilities.IsTlsV13(version)) + { + if ((namedGroup >= sect163k1 && namedGroup <= secp256k1) + || (namedGroup >= brainpoolP256r1 && namedGroup <= brainpoolP512r1) + || (namedGroup >= GC256A && namedGroup <= GC512C) + || (namedGroup >= arbitrary_explicit_prime_curves && namedGroup <= arbitrary_explicit_char2_curves)) + { + return false; + } + } + else + { + if ((namedGroup >= brainpoolP256r1tls13 && namedGroup <= brainpoolP512r1tls13) + || (namedGroup == curveSM2)) + { + return false; + } + } + + return IsValid(namedGroup); + } + + public static int GetCurveBits(int namedGroup) + { + switch (namedGroup) + { + case secp160k1: + case secp160r1: + case secp160r2: + return 160; + + case sect163k1: + case sect163r1: + case sect163r2: + return 163; + + case secp192k1: + case secp192r1: + return 192; + + case sect193r1: + case sect193r2: + return 193; + + case secp224k1: + case secp224r1: + return 224; + + case sect233k1: + case sect233r1: + return 233; + + case sect239k1: + return 239; + + case x25519: + return 252; + + case brainpoolP256r1: + case brainpoolP256r1tls13: + case curveSM2: + case GC256A: + case GC256B: + case GC256C: + case GC256D: + case secp256k1: + case secp256r1: + return 256; + + case sect283k1: + case sect283r1: + return 283; + + case brainpoolP384r1: + case brainpoolP384r1tls13: + case secp384r1: + return 384; + + case sect409k1: + case sect409r1: + return 409; + + case x448: + return 446; + + case brainpoolP512r1: + case brainpoolP512r1tls13: + case GC512A: + case GC512B: + case GC512C: + return 512; + + case secp521r1: + return 521; + + case sect571k1: + case sect571r1: + return 571; + + default: + return 0; + } + } + + public static string GetCurveName(int namedGroup) + { + if (RefersToASpecificCurve(namedGroup)) + { + return CurveNames[namedGroup - sect163k1]; + } + + return null; + } + + public static int GetFiniteFieldBits(int namedGroup) + { + switch (namedGroup) + { + case ffdhe2048: + return 2048; + case ffdhe3072: + return 3072; + case ffdhe4096: + return 4096; + case ffdhe6144: + return 6144; + case ffdhe8192: + return 8192; + default: + return 0; + } + } + + public static string GetFiniteFieldName(int namedGroup) + { + if (RefersToASpecificFiniteField(namedGroup)) + { + return FiniteFieldNames[namedGroup - ffdhe2048]; + } + + return null; + } + + public static int GetMaximumChar2CurveBits() + { + return 571; + } + + public static int GetMaximumCurveBits() + { + return 571; + } + + public static int GetMaximumFiniteFieldBits() + { + return 8192; + } + + public static int GetMaximumPrimeCurveBits() + { + return 521; + } + + public static string GetName(int namedGroup) + { + if (IsPrivate(namedGroup)) + { + return "PRIVATE"; + } + + switch (namedGroup) + { + case x25519: + return "x25519"; + case x448: + return "x448"; + case brainpoolP256r1tls13: + return "brainpoolP256r1tls13"; + case brainpoolP384r1tls13: + return "brainpoolP384r1tls13"; + case brainpoolP512r1tls13: + return "brainpoolP512r1tls13"; + case GC256A: + return "GC256A"; + case GC256B: + return "GC256B"; + case GC256C: + return "GC256C"; + case GC256D: + return "GC256D"; + case GC512A: + return "GC512A"; + case GC512B: + return "GC512B"; + case GC512C: + return "GC512C"; + case curveSM2: + return "curveSM2"; + case arbitrary_explicit_prime_curves: + return "arbitrary_explicit_prime_curves"; + case arbitrary_explicit_char2_curves: + return "arbitrary_explicit_char2_curves"; + } + + string standardName = GetStandardName(namedGroup); + if (null != standardName) + { + return standardName; + } + + return "UNKNOWN"; + } + + public static string GetStandardName(int namedGroup) + { + string curveName = GetCurveName(namedGroup); + if (null != curveName) + { + return curveName; + } + + string finiteFieldName = GetFiniteFieldName(namedGroup); + if (null != finiteFieldName) + { + return finiteFieldName; + } + + return null; + } + + public static string GetText(int namedGroup) + { + return GetName(namedGroup) + "(" + namedGroup + ")"; + } + + public static bool IsChar2Curve(int namedGroup) + { + return (namedGroup >= sect163k1 && namedGroup <= sect571r1) + || (namedGroup == arbitrary_explicit_char2_curves); + } + + public static bool IsPrimeCurve(int namedGroup) + { + return (namedGroup >= secp160k1 && namedGroup <= curveSM2) + || (namedGroup == arbitrary_explicit_prime_curves); + } + + public static bool IsPrivate(int namedGroup) + { + return (namedGroup >> 2) == 0x7F || (namedGroup >> 8) == 0xFE; + } + + public static bool IsValid(int namedGroup) + { + return RefersToASpecificGroup(namedGroup) + || IsPrivate(namedGroup) + || (namedGroup >= arbitrary_explicit_prime_curves && namedGroup <= arbitrary_explicit_char2_curves); + } + + public static bool RefersToAnECDHCurve(int namedGroup) + { + return RefersToASpecificCurve(namedGroup); + } + + public static bool RefersToAnECDSACurve(int namedGroup) + { + /* + * TODO[RFC 8998] Double-check whether this method is only being used to mean + * "signature-capable" or specifically ECDSA, and consider curveSM2 behaviour + * accordingly. + */ + return RefersToASpecificCurve(namedGroup) + && !RefersToAnXDHCurve(namedGroup); + } + + public static bool RefersToAnXDHCurve(int namedGroup) + { + return namedGroup >= x25519 && namedGroup <= x448; + } + + public static bool RefersToASpecificCurve(int namedGroup) + { + return namedGroup >= sect163k1 && namedGroup <= curveSM2; + } + + public static bool RefersToASpecificFiniteField(int namedGroup) + { + return namedGroup >= ffdhe2048 && namedGroup <= ffdhe8192; + } + + public static bool RefersToASpecificGroup(int namedGroup) + { + return RefersToASpecificCurve(namedGroup) + || RefersToASpecificFiniteField(namedGroup); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/NamedGroup.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/NamedGroup.cs.meta new file mode 100644 index 0000000..ab0ee1e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/NamedGroup.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b28e46acdef45484880cc4dd36bca91e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/NamedGroupRole.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/NamedGroupRole.cs new file mode 100644 index 0000000..d86e6ad --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/NamedGroupRole.cs @@ -0,0 +1,15 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + /// + /// Note that the values here are implementation-specific and arbitrary. It is recommended not to depend on the + /// particular values (e.g. serialization). + /// + public abstract class NamedGroupRole + { + public const int dh = 1; + public const int ecdh = 2; + public const int ecdsa = 3; + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/NamedGroupRole.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/NamedGroupRole.cs.meta new file mode 100644 index 0000000..dbbe0d4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/NamedGroupRole.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9079a9dbed53c6e468b670e38fb6ebbc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/NewSessionTicket.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/NewSessionTicket.cs new file mode 100644 index 0000000..6e2a013 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/NewSessionTicket.cs @@ -0,0 +1,47 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Tls +{ + public sealed class NewSessionTicket + { + private readonly long m_ticketLifetimeHint; + private readonly byte[] m_ticket; + + public NewSessionTicket(long ticketLifetimeHint, byte[] ticket) + { + this.m_ticketLifetimeHint = ticketLifetimeHint; + this.m_ticket = ticket; + } + + public long TicketLifetimeHint + { + get { return m_ticketLifetimeHint; } + } + + public byte[] Ticket + { + get { return m_ticket; } + } + + ///

    Encode this to a . + /// the to encode to. + /// + public void Encode(Stream output) + { + TlsUtilities.WriteUint32(TicketLifetimeHint, output); + TlsUtilities.WriteOpaque16(Ticket, output); + } + + /// Parse a from a . + /// the to parse from. + /// a object. + /// + public static NewSessionTicket Parse(Stream input) + { + long ticketLifetimeHint = TlsUtilities.ReadUint32(input); + byte[] ticket = TlsUtilities.ReadOpaque16(input); + return new NewSessionTicket(ticketLifetimeHint, ticket); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/NewSessionTicket.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/NewSessionTicket.cs.meta new file mode 100644 index 0000000..1b7ed9f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/NewSessionTicket.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b1aa51044c7cce240b4196e8f52b9b74 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/OcspStatusRequest.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/OcspStatusRequest.cs new file mode 100644 index 0000000..b52517e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/OcspStatusRequest.cs @@ -0,0 +1,111 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Ocsp; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Tls +{ + /// RFC 3546 3.6 + public sealed class OcspStatusRequest + { + private readonly IList m_responderIDList; + private readonly X509Extensions m_requestExtensions; + + /// an of , specifying the list of + /// trusted OCSP responders. An empty list has the special meaning that the responders are implicitly known to + /// the server - e.g., by prior arrangement. + /// OCSP request extensions. A null value means that there are no extensions. + /// + public OcspStatusRequest(IList responderIDList, X509Extensions requestExtensions) + { + this.m_responderIDList = responderIDList; + this.m_requestExtensions = requestExtensions; + } + + /// an of . + public IList ResponderIDList + { + get { return m_responderIDList; } + } + + /// OCSP request extensions. + public X509Extensions RequestExtensions + { + get { return m_requestExtensions; } + } + + /// Encode this to a . + /// the to encode to. + /// + public void Encode(Stream output) + { + if (m_responderIDList == null || m_responderIDList.Count < 1) + { + TlsUtilities.WriteUint16(0, output); + } + else + { + MemoryStream buf = new MemoryStream(); + foreach (ResponderID responderID in m_responderIDList) + { + byte[] derEncoding = responderID.GetEncoded(Asn1Encodable.Der); + TlsUtilities.WriteOpaque16(derEncoding, buf); + } + TlsUtilities.CheckUint16(buf.Length); + TlsUtilities.WriteUint16((int)buf.Length, output); + Streams.WriteBufTo(buf, output); + } + + if (m_requestExtensions == null) + { + TlsUtilities.WriteUint16(0, output); + } + else + { + byte[] derEncoding = m_requestExtensions.GetEncoded(Asn1Encodable.Der); + TlsUtilities.CheckUint16(derEncoding.Length); + TlsUtilities.WriteUint16(derEncoding.Length, output); + output.Write(derEncoding, 0, derEncoding.Length); + } + } + + /// Parse an from a . + /// the to parse from. + /// an object. + /// + public static OcspStatusRequest Parse(Stream input) + { + IList responderIDList = Platform.CreateArrayList(); + { + byte[] data = TlsUtilities.ReadOpaque16(input); + if (data.Length > 0) + { + MemoryStream buf = new MemoryStream(data, false); + do + { + byte[] derEncoding = TlsUtilities.ReadOpaque16(buf, 1); + ResponderID responderID = ResponderID.GetInstance(TlsUtilities.ReadDerObject(derEncoding)); + responderIDList.Add(responderID); + } + while (buf.Position < buf.Length); + } + } + + X509Extensions requestExtensions = null; + { + byte[] derEncoding = TlsUtilities.ReadOpaque16(input); + if (derEncoding.Length > 0) + { + requestExtensions = X509Extensions.GetInstance(TlsUtilities.ReadDerObject(derEncoding)); + } + } + + return new OcspStatusRequest(responderIDList, requestExtensions); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/OcspStatusRequest.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/OcspStatusRequest.cs.meta new file mode 100644 index 0000000..f672661 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/OcspStatusRequest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8d1ed65f412ea4b46ab1480ba8f7b60c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/OfferedPsks.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/OfferedPsks.cs new file mode 100644 index 0000000..1cc8a2a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/OfferedPsks.cs @@ -0,0 +1,224 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Tls.Crypto; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls +{ + public sealed class OfferedPsks + { + internal class BindersConfig + { + internal readonly TlsPsk[] m_psks; + internal readonly short[] m_pskKeyExchangeModes; + internal readonly TlsSecret[] m_earlySecrets; + internal int m_bindersSize; + + internal BindersConfig(TlsPsk[] psks, short[] pskKeyExchangeModes, TlsSecret[] earlySecrets, + int bindersSize) + { + this.m_psks = psks; + this.m_pskKeyExchangeModes = pskKeyExchangeModes; + this.m_earlySecrets = earlySecrets; + this.m_bindersSize = bindersSize; + } + } + + internal class SelectedConfig + { + internal readonly int m_index; + internal readonly TlsPsk m_psk; + internal readonly short[] m_pskKeyExchangeModes; + internal readonly TlsSecret m_earlySecret; + + internal SelectedConfig(int index, TlsPsk psk, short[] pskKeyExchangeModes, TlsSecret earlySecret) + { + this.m_index = index; + this.m_psk = psk; + this.m_pskKeyExchangeModes = pskKeyExchangeModes; + this.m_earlySecret = earlySecret; + } + } + + private readonly IList m_identities; + private readonly IList m_binders; + private readonly int m_bindersSize; + + public OfferedPsks(IList identities) + : this(identities, null, -1) + { + } + + private OfferedPsks(IList identities, IList binders, int bindersSize) + { + if (null == identities || identities.Count < 1) + throw new ArgumentException("cannot be null or empty", "identities"); + if (null != binders && identities.Count != binders.Count) + throw new ArgumentException("must be the same length as 'identities' (or null)", "binders"); + if ((null != binders) != (bindersSize >= 0)) + throw new ArgumentException("must be >= 0 iff 'binders' are present", "bindersSize"); + + this.m_identities = identities; + this.m_binders = binders; + this.m_bindersSize = bindersSize; + } + + public IList Binders + { + get { return m_binders; } + } + + public int BindersSize + { + get { return m_bindersSize; } + } + + public IList Identities + { + get { return m_identities; } + } + + public int GetIndexOfIdentity(PskIdentity pskIdentity) + { + for (int i = 0, count = m_identities.Count; i < count; ++i) + { + if (pskIdentity.Equals(m_identities[i])) + return i; + } + return -1; + } + + /// + public void Encode(Stream output) + { + // identities + { + int lengthOfIdentitiesList = 0; + foreach (PskIdentity identity in m_identities) + { + lengthOfIdentitiesList += identity.GetEncodedLength(); + } + + TlsUtilities.CheckUint16(lengthOfIdentitiesList); + TlsUtilities.WriteUint16(lengthOfIdentitiesList, output); + + foreach (PskIdentity identity in m_identities) + { + identity.Encode(output); + } + } + + // binders + if (null != m_binders) + { + int lengthOfBindersList = 0; + foreach (byte[] binder in m_binders) + { + lengthOfBindersList += 1 + binder.Length; + } + + TlsUtilities.CheckUint16(lengthOfBindersList); + TlsUtilities.WriteUint16(lengthOfBindersList, output); + + foreach (byte[] binder in m_binders) + { + TlsUtilities.WriteOpaque8(binder, output); + } + } + } + + /// + internal static void EncodeBinders(Stream output, TlsCrypto crypto, TlsHandshakeHash handshakeHash, + BindersConfig bindersConfig) + { + TlsPsk[] psks = bindersConfig.m_psks; + TlsSecret[] earlySecrets = bindersConfig.m_earlySecrets; + int expectedLengthOfBindersList = bindersConfig.m_bindersSize - 2; + + TlsUtilities.CheckUint16(expectedLengthOfBindersList); + TlsUtilities.WriteUint16(expectedLengthOfBindersList, output); + + int lengthOfBindersList = 0; + for (int i = 0; i < psks.Length; ++i) + { + TlsPsk psk = psks[i]; + TlsSecret earlySecret = earlySecrets[i]; + + // TODO[tls13-psk] Handle resumption PSKs + bool isExternalPsk = true; + int pskCryptoHashAlgorithm = TlsCryptoUtilities.GetHashForPrf(psk.PrfAlgorithm); + + // TODO[tls13-psk] Cache the transcript hashes per algorithm to avoid duplicates for multiple PSKs + TlsHash hash = crypto.CreateHash(pskCryptoHashAlgorithm); + handshakeHash.CopyBufferTo(new TlsHashSink(hash)); + byte[] transcriptHash = hash.CalculateHash(); + + byte[] binder = TlsUtilities.CalculatePskBinder(crypto, isExternalPsk, pskCryptoHashAlgorithm, + earlySecret, transcriptHash); + + lengthOfBindersList += 1 + binder.Length; + TlsUtilities.WriteOpaque8(binder, output); + } + + if (expectedLengthOfBindersList != lengthOfBindersList) + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + /// + internal static int GetBindersSize(TlsPsk[] psks) + { + int lengthOfBindersList = 0; + for (int i = 0; i < psks.Length; ++i) + { + TlsPsk psk = psks[i]; + + int prfAlgorithm = psk.PrfAlgorithm; + int prfCryptoHashAlgorithm = TlsCryptoUtilities.GetHashForPrf(prfAlgorithm); + + lengthOfBindersList += 1 + TlsCryptoUtilities.GetHashOutputSize(prfCryptoHashAlgorithm); + } + TlsUtilities.CheckUint16(lengthOfBindersList); + return 2 + lengthOfBindersList; + } + + /// + public static OfferedPsks Parse(Stream input) + { + IList identities = Platform.CreateArrayList(); + { + int totalLengthIdentities = TlsUtilities.ReadUint16(input); + if (totalLengthIdentities < 7) + throw new TlsFatalAlert(AlertDescription.decode_error); + + byte[] identitiesData = TlsUtilities.ReadFully(totalLengthIdentities, input); + MemoryStream buf = new MemoryStream(identitiesData, false); + do + { + PskIdentity identity = PskIdentity.Parse(buf); + identities.Add(identity); + } + while (buf.Position < buf.Length); + } + + IList binders = Platform.CreateArrayList(); + int totalLengthBinders = TlsUtilities.ReadUint16(input); + { + if (totalLengthBinders < 33) + throw new TlsFatalAlert(AlertDescription.decode_error); + + byte[] bindersData = TlsUtilities.ReadFully(totalLengthBinders, input); + MemoryStream buf = new MemoryStream(bindersData, false); + do + { + byte[] binder = TlsUtilities.ReadOpaque8(buf, 32); + binders.Add(binder); + } + while (buf.Position < buf.Length); + } + + return new OfferedPsks(identities, binders, 2 + totalLengthBinders); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/OfferedPsks.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/OfferedPsks.cs.meta new file mode 100644 index 0000000..c49dc02 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/OfferedPsks.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e7f9264560ad1874db7f8cd2711de20b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/PrfAlgorithm.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/PrfAlgorithm.cs new file mode 100644 index 0000000..ec9c2f2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/PrfAlgorithm.cs @@ -0,0 +1,49 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + /// RFC 5246 + /// + /// Note that the values here are implementation-specific and arbitrary. It is recommended not to depend on the + /// particular values (e.g. serialization). + /// + public abstract class PrfAlgorithm + { + public const int ssl_prf_legacy = 0; + public const int tls_prf_legacy = 1; + public const int tls_prf_sha256 = 2; + public const int tls_prf_sha384 = 3; + public const int tls13_hkdf_sha256 = 4; + public const int tls13_hkdf_sha384 = 5; + //public const int tls13_hkdf_sha512 = 6; + public const int tls13_hkdf_sm3 = 7; + + public static string GetName(int prfAlgorithm) + { + switch (prfAlgorithm) + { + case ssl_prf_legacy: + return "ssl_prf_legacy"; + case tls_prf_legacy: + return "tls_prf_legacy"; + case tls_prf_sha256: + return "tls_prf_sha256"; + case tls_prf_sha384: + return "tls_prf_sha384"; + case tls13_hkdf_sha256: + return "tls13_hkdf_sha256"; + case tls13_hkdf_sha384: + return "tls13_hkdf_sha384"; + case tls13_hkdf_sm3: + return "tls13_hkdf_sm3"; + default: + return "UNKNOWN"; + } + } + + public static string GetText(int prfAlgorithm) + { + return GetName(prfAlgorithm) + "(" + prfAlgorithm + ")"; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/PrfAlgorithm.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/PrfAlgorithm.cs.meta new file mode 100644 index 0000000..2042905 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/PrfAlgorithm.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6d1d09a8b77da67418e85d6aec413002 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ProtocolName.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ProtocolName.cs new file mode 100644 index 0000000..529e81b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ProtocolName.cs @@ -0,0 +1,88 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls +{ + /// RFC 7301 Represents a protocol name for use with ALPN. + public sealed class ProtocolName + { + public static ProtocolName AsRawBytes(byte[] bytes) + { + return new ProtocolName(Arrays.Clone(bytes)); + } + + public static ProtocolName AsUtf8Encoding(String name) + { + return new ProtocolName(Strings.ToUtf8ByteArray(name)); + } + + public static readonly ProtocolName Http_1_1 = AsUtf8Encoding("http/1.1"); + public static readonly ProtocolName Spdy_1 = AsUtf8Encoding("spdy/1"); + public static readonly ProtocolName Spdy_2 = AsUtf8Encoding("spdy/2"); + public static readonly ProtocolName Spdy_3 = AsUtf8Encoding("spdy/3"); + public static readonly ProtocolName Stun_Turn = AsUtf8Encoding("stun.turn"); + public static readonly ProtocolName Stun_Nat_Discovery = AsUtf8Encoding("stun.nat-discovery"); + public static readonly ProtocolName Http_2_Tls = AsUtf8Encoding("h2"); + public static readonly ProtocolName Http_2_Tcp = AsUtf8Encoding("h2c"); + public static readonly ProtocolName WebRtc = AsUtf8Encoding("webrtc"); + public static readonly ProtocolName WebRtc_Confidential = AsUtf8Encoding("c-webrtc"); + public static readonly ProtocolName Ftp = AsUtf8Encoding("ftp"); + public static readonly ProtocolName Imap = AsUtf8Encoding("imap"); + public static readonly ProtocolName Pop3 = AsUtf8Encoding("pop3"); + public static readonly ProtocolName ManageSieve = AsUtf8Encoding("managesieve"); + public static readonly ProtocolName Coap = AsUtf8Encoding("coap"); + public static readonly ProtocolName Xmpp_Client = AsUtf8Encoding("xmpp-client"); + public static readonly ProtocolName Xmpp_Server = AsUtf8Encoding("xmpp-server"); + + private readonly byte[] m_bytes; + + private ProtocolName(byte[] bytes) + { + if (bytes == null) + throw new ArgumentNullException("bytes"); + if (bytes.Length < 1 || bytes.Length > 255) + throw new ArgumentException("must have length from 1 to 255", "bytes"); + + this.m_bytes = bytes; + } + + public byte[] GetBytes() + { + return Arrays.Clone(m_bytes); + } + + public string GetUtf8Decoding() + { + return Strings.FromUtf8ByteArray(m_bytes); + } + + /// Encode this to a . + /// the to encode to. + /// + public void Encode(Stream output) + { + TlsUtilities.WriteOpaque8(m_bytes, output); + } + + /// Parse a from a . + /// the to parse from. + /// a object. + /// + public static ProtocolName Parse(Stream input) + { + return new ProtocolName(TlsUtilities.ReadOpaque8(input, 1)); + } + + public override bool Equals(object obj) + { + return obj is ProtocolName && Arrays.AreEqual(m_bytes, ((ProtocolName)obj).m_bytes); + } + + public override int GetHashCode() + { + return Arrays.GetHashCode(m_bytes); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ProtocolName.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ProtocolName.cs.meta new file mode 100644 index 0000000..d4eb690 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ProtocolName.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d029edff75fd386489568ac5358ce715 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ProtocolVersion.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ProtocolVersion.cs new file mode 100644 index 0000000..f37ce38 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ProtocolVersion.cs @@ -0,0 +1,406 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls +{ + public sealed class ProtocolVersion + { + public static readonly ProtocolVersion SSLv3 = new ProtocolVersion(0x0300, "SSL 3.0"); + public static readonly ProtocolVersion TLSv10 = new ProtocolVersion(0x0301, "TLS 1.0"); + public static readonly ProtocolVersion TLSv11 = new ProtocolVersion(0x0302, "TLS 1.1"); + public static readonly ProtocolVersion TLSv12 = new ProtocolVersion(0x0303, "TLS 1.2"); + public static readonly ProtocolVersion TLSv13 = new ProtocolVersion(0x0304, "TLS 1.3"); + public static readonly ProtocolVersion DTLSv10 = new ProtocolVersion(0xFEFF, "DTLS 1.0"); + public static readonly ProtocolVersion DTLSv12 = new ProtocolVersion(0xFEFD, "DTLS 1.2"); + + internal static readonly ProtocolVersion CLIENT_EARLIEST_SUPPORTED_DTLS = DTLSv10; + internal static readonly ProtocolVersion CLIENT_EARLIEST_SUPPORTED_TLS = SSLv3; + internal static readonly ProtocolVersion CLIENT_LATEST_SUPPORTED_DTLS = DTLSv12; + internal static readonly ProtocolVersion CLIENT_LATEST_SUPPORTED_TLS = TLSv13; + + internal static readonly ProtocolVersion SERVER_EARLIEST_SUPPORTED_DTLS = DTLSv10; + internal static readonly ProtocolVersion SERVER_EARLIEST_SUPPORTED_TLS = SSLv3; + internal static readonly ProtocolVersion SERVER_LATEST_SUPPORTED_DTLS = DTLSv12; + internal static readonly ProtocolVersion SERVER_LATEST_SUPPORTED_TLS = TLSv13; + + public static bool Contains(ProtocolVersion[] versions, ProtocolVersion version) + { + if (versions != null && version != null) + { + for (int i = 0; i < versions.Length; ++i) + { + if (version.Equals(versions[i])) + return true; + } + } + return false; + } + + public static ProtocolVersion GetEarliestDtls(ProtocolVersion[] versions) + { + ProtocolVersion earliest = null; + if (null != versions) + { + for (int i = 0; i < versions.Length; ++i) + { + ProtocolVersion next = versions[i]; + if (null != next && next.IsDtls) + { + if (null == earliest || next.MinorVersion > earliest.MinorVersion) + { + earliest = next; + } + } + } + } + return earliest; + } + + public static ProtocolVersion GetEarliestTls(ProtocolVersion[] versions) + { + ProtocolVersion earliest = null; + if (null != versions) + { + for (int i = 0; i < versions.Length; ++i) + { + ProtocolVersion next = versions[i]; + if (null != next && next.IsTls) + { + if (null == earliest || next.MinorVersion < earliest.MinorVersion) + { + earliest = next; + } + } + } + } + return earliest; + } + + public static ProtocolVersion GetLatestDtls(ProtocolVersion[] versions) + { + ProtocolVersion latest = null; + if (null != versions) + { + for (int i = 0; i < versions.Length; ++i) + { + ProtocolVersion next = versions[i]; + if (null != next && next.IsDtls) + { + if (null == latest || next.MinorVersion < latest.MinorVersion) + { + latest = next; + } + } + } + } + return latest; + } + + public static ProtocolVersion GetLatestTls(ProtocolVersion[] versions) + { + ProtocolVersion latest = null; + if (null != versions) + { + for (int i = 0; i < versions.Length; ++i) + { + ProtocolVersion next = versions[i]; + if (null != next && next.IsTls) + { + if (null == latest || next.MinorVersion > latest.MinorVersion) + { + latest = next; + } + } + } + } + return latest; + } + + internal static bool IsSupportedDtlsVersionClient(ProtocolVersion version) + { + return null != version + && version.IsEqualOrLaterVersionOf(CLIENT_EARLIEST_SUPPORTED_DTLS) + && version.IsEqualOrEarlierVersionOf(CLIENT_LATEST_SUPPORTED_DTLS); + } + + internal static bool IsSupportedDtlsVersionServer(ProtocolVersion version) + { + return null != version + && version.IsEqualOrLaterVersionOf(SERVER_EARLIEST_SUPPORTED_DTLS) + && version.IsEqualOrEarlierVersionOf(SERVER_LATEST_SUPPORTED_DTLS); + } + + internal static bool IsSupportedTlsVersionClient(ProtocolVersion version) + { + if (null == version) + return false; + + int fullVersion = version.FullVersion; + + return fullVersion >= CLIENT_EARLIEST_SUPPORTED_TLS.FullVersion + && fullVersion <= CLIENT_LATEST_SUPPORTED_TLS.FullVersion; + } + + internal static bool IsSupportedTlsVersionServer(ProtocolVersion version) + { + if (null == version) + return false; + + int fullVersion = version.FullVersion; + + return fullVersion >= SERVER_EARLIEST_SUPPORTED_TLS.FullVersion + && fullVersion <= SERVER_LATEST_SUPPORTED_TLS.FullVersion; + } + + private readonly int version; + private readonly string name; + + private ProtocolVersion(int v, string name) + { + this.version = v & 0xFFFF; + this.name = name; + } + + public ProtocolVersion[] DownTo(ProtocolVersion min) + { + if (!IsEqualOrLaterVersionOf(min)) + throw new ArgumentException("must be an equal or earlier version of this one", "min"); + + IList result = Platform.CreateArrayList(); + result.Add(this); + + ProtocolVersion current = this; + while (!current.Equals(min)) + { + current = current.GetPreviousVersion(); + result.Add(current); + } + + ProtocolVersion[] versions = new ProtocolVersion[result.Count]; + for (int i = 0; i < result.Count; ++i) + { + versions[i] = (ProtocolVersion)result[i]; + } + return versions; + } + + public int FullVersion + { + get { return version; } + } + + public int MajorVersion + { + get { return version >> 8; } + } + + public int MinorVersion + { + get { return version & 0xFF; } + } + + public string Name + { + get { return name; } + } + + public bool IsDtls + { + get { return MajorVersion == 0xFE; } + } + + public bool IsSsl + { + get { return this == SSLv3; } + } + + public bool IsTls + { + get { return MajorVersion == 0x03; } + } + + public ProtocolVersion GetEquivalentTlsVersion() + { + switch (MajorVersion) + { + case 0x03: + return this; + case 0xFE: + switch (MinorVersion) + { + case 0xFF: return TLSv11; + case 0xFD: return TLSv12; + default: return null; + } + default: + return null; + } + } + + public ProtocolVersion GetNextVersion() + { + int major = MajorVersion, minor = MinorVersion; + switch (major) + { + case 0x03: + switch (minor) + { + case 0xFF: return null; + default: return Get(major, minor + 1); + } + case 0xFE: + switch (minor) + { + case 0x00: return null; + case 0xFF: return DTLSv12; + default: return Get(major, minor - 1); + } + default: + return null; + } + } + + public ProtocolVersion GetPreviousVersion() + { + int major = MajorVersion, minor = MinorVersion; + switch (major) + { + case 0x03: + switch (minor) + { + case 0x00: return null; + default: return Get(major, minor - 1); + } + case 0xFE: + switch (minor) + { + case 0xFF: return null; + case 0xFD: return DTLSv10; + default: return Get(major, minor + 1); + } + default: + return null; + } + } + + public bool IsEarlierVersionOf(ProtocolVersion version) + { + if (null == version || MajorVersion != version.MajorVersion) + return false; + + int diffMinorVersion = MinorVersion - version.MinorVersion; + return IsDtls ? diffMinorVersion > 0 : diffMinorVersion < 0; + } + + public bool IsEqualOrEarlierVersionOf(ProtocolVersion version) + { + if (null == version || MajorVersion != version.MajorVersion) + return false; + + int diffMinorVersion = MinorVersion - version.MinorVersion; + return IsDtls ? diffMinorVersion >= 0 : diffMinorVersion <= 0; + } + + public bool IsEqualOrLaterVersionOf(ProtocolVersion version) + { + if (null == version || MajorVersion != version.MajorVersion) + return false; + + int diffMinorVersion = MinorVersion - version.MinorVersion; + return IsDtls ? diffMinorVersion <= 0 : diffMinorVersion >= 0; + } + + public bool IsLaterVersionOf(ProtocolVersion version) + { + if (null == version || MajorVersion != version.MajorVersion) + return false; + + int diffMinorVersion = MinorVersion - version.MinorVersion; + return IsDtls ? diffMinorVersion < 0 : diffMinorVersion > 0; + } + + public override bool Equals(object other) + { + return this == other || (other is ProtocolVersion && Equals((ProtocolVersion)other)); + } + + public bool Equals(ProtocolVersion other) + { + return other != null && this.version == other.version; + } + + public override int GetHashCode() + { + return version; + } + + public static ProtocolVersion Get(int major, int minor) + { + switch (major) + { + case 0x03: + { + switch (minor) + { + case 0x00: + return SSLv3; + case 0x01: + return TLSv10; + case 0x02: + return TLSv11; + case 0x03: + return TLSv12; + case 0x04: + return TLSv13; + } + return GetUnknownVersion(major, minor, "TLS"); + } + case 0xFE: + { + switch (minor) + { + case 0xFF: + return DTLSv10; + case 0xFE: + throw new ArgumentException("{0xFE, 0xFE} is a reserved protocol version"); + case 0xFD: + return DTLSv12; + } + return GetUnknownVersion(major, minor, "DTLS"); + } + default: + { + return GetUnknownVersion(major, minor, "UNKNOWN"); + } + } + } + + public ProtocolVersion[] Only() + { + return new ProtocolVersion[]{ this }; + } + + public override string ToString() + { + return name; + } + + private static void CheckUint8(int versionOctet) + { + if (!TlsUtilities.IsValidUint8(versionOctet)) + throw new ArgumentException("not a valid octet", "versionOctet"); + } + + private static ProtocolVersion GetUnknownVersion(int major, int minor, string prefix) + { + CheckUint8(major); + CheckUint8(minor); + + int v = (major << 8) | minor; + string hex = Platform.ToUpperInvariant(Convert.ToString(0x10000 | v, 16).Substring(1)); + return new ProtocolVersion(v, prefix + " 0x" + hex); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ProtocolVersion.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ProtocolVersion.cs.meta new file mode 100644 index 0000000..54d0f5e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ProtocolVersion.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c088a79839e7095498d0d851ca452c49 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/PskIdentity.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/PskIdentity.cs new file mode 100644 index 0000000..1887d0a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/PskIdentity.cs @@ -0,0 +1,69 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls +{ + public sealed class PskIdentity + { + private readonly byte[] m_identity; + private readonly long m_obfuscatedTicketAge; + + public PskIdentity(byte[] identity, long obfuscatedTicketAge) + { + if (null == identity) + throw new ArgumentNullException("identity"); + if (identity.Length < 1 || !TlsUtilities.IsValidUint16(identity.Length)) + throw new ArgumentException("should have length from 1 to 65535", "identity"); + if (!TlsUtilities.IsValidUint32(obfuscatedTicketAge)) + throw new ArgumentException("should be a uint32", "obfuscatedTicketAge"); + + this.m_identity = identity; + this.m_obfuscatedTicketAge = obfuscatedTicketAge; + } + + public int GetEncodedLength() + { + return 6 + m_identity.Length; + } + + public byte[] Identity + { + get { return m_identity; } + } + + public long ObfuscatedTicketAge + { + get { return m_obfuscatedTicketAge; } + } + + public void Encode(Stream output) + { + TlsUtilities.WriteOpaque16(Identity, output); + TlsUtilities.WriteUint32(ObfuscatedTicketAge, output); + } + + public static PskIdentity Parse(Stream input) + { + byte[] identity = TlsUtilities.ReadOpaque16(input, 1); + long obfuscatedTicketAge = TlsUtilities.ReadUint32(input); + return new PskIdentity(identity, obfuscatedTicketAge); + } + + public override bool Equals(object obj) + { + PskIdentity that = obj as PskIdentity; + if (null == that) + return false; + + return this.m_obfuscatedTicketAge == that.m_obfuscatedTicketAge + && Arrays.ConstantTimeAreEqual(this.m_identity, that.m_identity); + } + + public override int GetHashCode() + { + return Arrays.GetHashCode(m_identity) ^ m_obfuscatedTicketAge.GetHashCode(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/PskIdentity.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/PskIdentity.cs.meta new file mode 100644 index 0000000..a9aecdd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/PskIdentity.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3d9755a29f6396a40823f713d2408e2a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/PskKeyExchangeMode.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/PskKeyExchangeMode.cs new file mode 100644 index 0000000..565745b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/PskKeyExchangeMode.cs @@ -0,0 +1,32 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + public abstract class PskKeyExchangeMode + { + /* + * RFC 8446 + */ + + public const short psk_ke = 0; + public const short psk_dhe_ke = 1; + + public static string GetName(short pskKeyExchangeMode) + { + switch (pskKeyExchangeMode) + { + case psk_ke: + return "psk_ke"; + case psk_dhe_ke: + return "psk_dhe_ke"; + default: + return "UNKNOWN"; + } + } + + public static string GetText(short pskKeyExchangeMode) + { + return GetName(pskKeyExchangeMode) + "(" + pskKeyExchangeMode + ")"; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/PskKeyExchangeMode.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/PskKeyExchangeMode.cs.meta new file mode 100644 index 0000000..458ee4a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/PskKeyExchangeMode.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 328f67f4c2808314d8d41003cfa9b031 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/PskTlsClient.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/PskTlsClient.cs new file mode 100644 index 0000000..3e9a003 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/PskTlsClient.cs @@ -0,0 +1,60 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Tls.Crypto; + +namespace Org.BouncyCastle.Tls +{ + public class PskTlsClient + : AbstractTlsClient + { + private static readonly int[] DefaultCipherSuites = new int[] + { + CipherSuite.TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256, + CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, + CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, + CipherSuite.TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256, + CipherSuite.TLS_DHE_PSK_WITH_AES_128_GCM_SHA256, + CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA256, + CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA + }; + + protected readonly TlsPskIdentity m_pskIdentity; + + public PskTlsClient(TlsCrypto crypto, byte[] identity, byte[] psk) + : this(crypto, new BasicTlsPskIdentity(identity, psk)) + { + } + + public PskTlsClient(TlsCrypto crypto, TlsPskIdentity pskIdentity) + : base(crypto) + { + this.m_pskIdentity = pskIdentity; + } + + protected override ProtocolVersion[] GetSupportedVersions() + { + return ProtocolVersion.TLSv12.DownTo(ProtocolVersion.TLSv10); + } + + protected override int[] GetSupportedCipherSuites() + { + return TlsUtilities.GetSupportedCipherSuites(Crypto, DefaultCipherSuites); + } + + public override TlsPskIdentity GetPskIdentity() + { + return m_pskIdentity; + } + + /// + public override TlsAuthentication GetAuthentication() + { + /* + * Note: This method is not called unless a server certificate is sent, which may be the + * case e.g. for RSA_PSK key exchange. + */ + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/PskTlsClient.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/PskTlsClient.cs.meta new file mode 100644 index 0000000..4951cfd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/PskTlsClient.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b6bc678082e164a4488559c2486fb5ab +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/PskTlsServer.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/PskTlsServer.cs new file mode 100644 index 0000000..7197b6a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/PskTlsServer.cs @@ -0,0 +1,76 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Tls.Crypto; + +namespace Org.BouncyCastle.Tls +{ + public class PskTlsServer + : AbstractTlsServer + { + private static readonly int[] DefaultCipherSuites = new int[] + { + CipherSuite.TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256, + CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384, + CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, + CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, + CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, + CipherSuite.TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256, + CipherSuite.TLS_DHE_PSK_WITH_AES_256_GCM_SHA384, + CipherSuite.TLS_DHE_PSK_WITH_AES_128_GCM_SHA256, + CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA384, + CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA256, + CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA, + CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA + }; + + protected readonly TlsPskIdentityManager m_pskIdentityManager; + + public PskTlsServer(TlsCrypto crypto, TlsPskIdentityManager pskIdentityManager) + : base(crypto) + { + this.m_pskIdentityManager = pskIdentityManager; + } + + /// + protected virtual TlsCredentialedDecryptor GetRsaEncryptionCredentials() + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + protected override ProtocolVersion[] GetSupportedVersions() + { + return ProtocolVersion.TLSv12.DownTo(ProtocolVersion.TLSv10); + } + + protected override int[] GetSupportedCipherSuites() + { + return TlsUtilities.GetSupportedCipherSuites(Crypto, DefaultCipherSuites); + } + + public override TlsCredentials GetCredentials() + { + int keyExchangeAlgorithm = m_context.SecurityParameters.KeyExchangeAlgorithm; + + switch (keyExchangeAlgorithm) + { + case KeyExchangeAlgorithm.DHE_PSK: + case KeyExchangeAlgorithm.ECDHE_PSK: + case KeyExchangeAlgorithm.PSK: + return null; + + case KeyExchangeAlgorithm.RSA_PSK: + return GetRsaEncryptionCredentials(); + + default: + // Note: internal error here; selected a key exchange we don't implement! + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + public override TlsPskIdentityManager GetPskIdentityManager() + { + return m_pskIdentityManager; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/PskTlsServer.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/PskTlsServer.cs.meta new file mode 100644 index 0000000..dfb7c7e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/PskTlsServer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 25c02d80ca776e24cb3803e0acd06232 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/RecordFormat.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/RecordFormat.cs new file mode 100644 index 0000000..3bc0469 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/RecordFormat.cs @@ -0,0 +1,12 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + public abstract class RecordFormat + { + public const int TypeOffset = 0; + public const int VersionOffset = 1; + public const int LengthOffset = 3; + public const int FragmentOffset = 5; + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/RecordFormat.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/RecordFormat.cs.meta new file mode 100644 index 0000000..d034012 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/RecordFormat.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: abaf174fb70b81e4ba57c00e90cb4c13 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/RecordPreview.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/RecordPreview.cs new file mode 100644 index 0000000..a0abb0f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/RecordPreview.cs @@ -0,0 +1,36 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + public sealed class RecordPreview + { + private readonly int recordSize; + private readonly int contentLimit; + + internal static RecordPreview CombineAppData(RecordPreview a, RecordPreview b) + { + return new RecordPreview(a.RecordSize + b.RecordSize, a.ContentLimit + b.ContentLimit); + } + + internal static RecordPreview ExtendRecordSize(RecordPreview a, int recordSize) + { + return new RecordPreview(a.RecordSize + recordSize, a.ContentLimit); + } + + internal RecordPreview(int recordSize, int contentLimit) + { + this.recordSize = recordSize; + this.contentLimit = contentLimit; + } + + public int ContentLimit + { + get { return contentLimit; } + } + + public int RecordSize + { + get { return recordSize; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/RecordPreview.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/RecordPreview.cs.meta new file mode 100644 index 0000000..21cbe8a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/RecordPreview.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ead56c6195f29204a97b09c8608407cd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/RecordStream.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/RecordStream.cs new file mode 100644 index 0000000..a97d346 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/RecordStream.cs @@ -0,0 +1,533 @@ +using System; +using System.Diagnostics; +using System.IO; + +using Org.BouncyCastle.Tls.Crypto; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls +{ + /// An implementation of the TLS 1.0/1.1/1.2 record layer. + internal sealed class RecordStream + { + private const int DefaultPlaintextLimit = (1 << 14); + + private readonly Record m_inputRecord = new Record(); + private readonly SequenceNumber m_readSeqNo = new SequenceNumber(), m_writeSeqNo = new SequenceNumber(); + + private readonly TlsProtocol m_handler; + private readonly Stream m_input; + private readonly Stream m_output; + + private TlsCipher m_pendingCipher = null; + private TlsCipher m_readCipher = TlsNullNullCipher.Instance; + private TlsCipher m_readCipherDeferred = null; + private TlsCipher m_writeCipher = TlsNullNullCipher.Instance; + + private ProtocolVersion m_writeVersion = null; + + private int m_plaintextLimit = DefaultPlaintextLimit; + private int m_ciphertextLimit = DefaultPlaintextLimit; + private bool m_ignoreChangeCipherSpec = false; + + internal RecordStream(TlsProtocol handler, Stream input, Stream output) + { + this.m_handler = handler; + this.m_input = input; + this.m_output = output; + } + + internal int PlaintextLimit + { + get { return m_plaintextLimit; } + } + + internal void SetPlaintextLimit(int plaintextLimit) + { + this.m_plaintextLimit = plaintextLimit; + this.m_ciphertextLimit = m_readCipher.GetCiphertextDecodeLimit(plaintextLimit); + } + + internal void SetWriteVersion(ProtocolVersion writeVersion) + { + this.m_writeVersion = writeVersion; + } + + internal void SetIgnoreChangeCipherSpec(bool ignoreChangeCipherSpec) + { + this.m_ignoreChangeCipherSpec = ignoreChangeCipherSpec; + } + + internal void SetPendingCipher(TlsCipher tlsCipher) + { + this.m_pendingCipher = tlsCipher; + } + + /// + internal void NotifyChangeCipherSpecReceived() + { + if (m_pendingCipher == null) + throw new TlsFatalAlert(AlertDescription.unexpected_message, "No pending cipher"); + + EnablePendingCipherRead(false); + } + + /// + internal void EnablePendingCipherRead(bool deferred) + { + if (m_pendingCipher == null) + throw new TlsFatalAlert(AlertDescription.internal_error); + + if (m_readCipherDeferred != null) + throw new TlsFatalAlert(AlertDescription.internal_error); + + if (deferred) + { + this.m_readCipherDeferred = m_pendingCipher; + } + else + { + this.m_readCipher = m_pendingCipher; + this.m_ciphertextLimit = m_readCipher.GetCiphertextDecodeLimit(m_plaintextLimit); + m_readSeqNo.Reset(); + } + } + + /// + internal void EnablePendingCipherWrite() + { + if (m_pendingCipher == null) + throw new TlsFatalAlert(AlertDescription.internal_error); + + this.m_writeCipher = this.m_pendingCipher; + m_writeSeqNo.Reset(); + } + + /// + internal void FinaliseHandshake() + { + if (m_readCipher != m_pendingCipher || m_writeCipher != m_pendingCipher) + throw new TlsFatalAlert(AlertDescription.handshake_failure); + + this.m_pendingCipher = null; + } + + internal bool NeedsKeyUpdate() + { + return m_writeSeqNo.CurrentValue >= (1L << 20); + } + + /// + internal void NotifyKeyUpdateReceived() + { + m_readCipher.RekeyDecoder(); + m_readSeqNo.Reset(); + } + + /// + internal void NotifyKeyUpdateSent() + { + m_writeCipher.RekeyEncoder(); + m_writeSeqNo.Reset(); + } + + /// + internal RecordPreview PreviewRecordHeader(byte[] recordHeader) + { + short recordType = CheckRecordType(recordHeader, RecordFormat.TypeOffset); + + //ProtocolVersion recordVersion = TlsUtilities.ReadVersion(recordHeader, RecordFormat.VersionOffset); + + int length = TlsUtilities.ReadUint16(recordHeader, RecordFormat.LengthOffset); + + CheckLength(length, m_ciphertextLimit, AlertDescription.record_overflow); + + int recordSize = RecordFormat.FragmentOffset + length; + int applicationDataLimit = 0; + + // NOTE: For TLS 1.3, this only MIGHT be application data + if (ContentType.application_data == recordType && m_handler.IsApplicationDataReady) + { + applicationDataLimit = System.Math.Max(0, System.Math.Min(m_plaintextLimit, + m_readCipher.GetPlaintextLimit(length))); + } + + return new RecordPreview(recordSize, applicationDataLimit); + } + + internal RecordPreview PreviewOutputRecord(int contentLength) + { + int contentLimit = System.Math.Max(0, System.Math.Min(m_plaintextLimit, contentLength)); + int recordSize = PreviewOutputRecordSize(contentLimit); + return new RecordPreview(recordSize, contentLimit); + } + + internal int PreviewOutputRecordSize(int contentLength) + { + Debug.Assert(contentLength <= m_plaintextLimit); + + return RecordFormat.FragmentOffset + m_writeCipher.GetCiphertextEncodeLimit(contentLength, m_plaintextLimit); + } + + /// + internal bool ReadFullRecord(byte[] input, int inputOff, int inputLen) + { + if (inputLen < RecordFormat.FragmentOffset) + return false; + + int length = TlsUtilities.ReadUint16(input, inputOff + RecordFormat.LengthOffset); + if (inputLen != (RecordFormat.FragmentOffset + length)) + return false; + + short recordType = CheckRecordType(input, inputOff + RecordFormat.TypeOffset); + + ProtocolVersion recordVersion = TlsUtilities.ReadVersion(input, inputOff + RecordFormat.VersionOffset); + + CheckLength(length, m_ciphertextLimit, AlertDescription.record_overflow); + + if (m_ignoreChangeCipherSpec && ContentType.change_cipher_spec == recordType) + { + CheckChangeCipherSpec(input, inputOff + RecordFormat.FragmentOffset, length); + return true; + } + + TlsDecodeResult decoded = DecodeAndVerify(recordType, recordVersion, input, + inputOff + RecordFormat.FragmentOffset, length); + + m_handler.ProcessRecord(decoded.contentType, decoded.buf, decoded.off, decoded.len); + return true; + } + + /// + internal bool ReadRecord() + { + if (!m_inputRecord.ReadHeader(m_input)) + return false; + + short recordType = CheckRecordType(m_inputRecord.m_buf, RecordFormat.TypeOffset); + + ProtocolVersion recordVersion = TlsUtilities.ReadVersion(m_inputRecord.m_buf, RecordFormat.VersionOffset); + + int length = TlsUtilities.ReadUint16(m_inputRecord.m_buf, RecordFormat.LengthOffset); + + CheckLength(length, m_ciphertextLimit, AlertDescription.record_overflow); + + m_inputRecord.ReadFragment(m_input, length); + + TlsDecodeResult decoded; + try + { + if (m_ignoreChangeCipherSpec && ContentType.change_cipher_spec == recordType) + { + CheckChangeCipherSpec(m_inputRecord.m_buf, RecordFormat.FragmentOffset, length); + return true; + } + + decoded = DecodeAndVerify(recordType, recordVersion, m_inputRecord.m_buf, RecordFormat.FragmentOffset, + length); + } + finally + { + m_inputRecord.Reset(); + } + + m_handler.ProcessRecord(decoded.contentType, decoded.buf, decoded.off, decoded.len); + return true; + } + + /// + internal TlsDecodeResult DecodeAndVerify(short recordType, ProtocolVersion recordVersion, byte[] ciphertext, + int off, int len) + { + long seqNo = m_readSeqNo.NextValue(AlertDescription.unexpected_message); + TlsDecodeResult decoded = m_readCipher.DecodeCiphertext(seqNo, recordType, recordVersion, ciphertext, off, + len); + + CheckLength(decoded.len, m_plaintextLimit, AlertDescription.record_overflow); + + /* + * RFC 5246 6.2.1 Implementations MUST NOT send zero-length fragments of Handshake, Alert, + * or ChangeCipherSpec content types. + */ + if (decoded.len < 1 && decoded.contentType != ContentType.application_data) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + return decoded; + } + + /// + internal void WriteRecord(short contentType, byte[] plaintext, int plaintextOffset, int plaintextLength) + { + // Never send anything until a valid ClientHello has been received + if (m_writeVersion == null) + return; + + /* + * RFC 5246 6.2.1 The length should not exceed 2^14. + */ + CheckLength(plaintextLength, m_plaintextLimit, AlertDescription.internal_error); + + /* + * RFC 5246 6.2.1 Implementations MUST NOT send zero-length fragments of Handshake, Alert, + * or ChangeCipherSpec content types. + */ + if (plaintextLength < 1 && contentType != ContentType.application_data) + throw new TlsFatalAlert(AlertDescription.internal_error); + + long seqNo = m_writeSeqNo.NextValue(AlertDescription.internal_error); + ProtocolVersion recordVersion = m_writeVersion; + + TlsEncodeResult encoded = m_writeCipher.EncodePlaintext(seqNo, contentType, recordVersion, + RecordFormat.FragmentOffset, plaintext, plaintextOffset, plaintextLength); + + int ciphertextLength = encoded.len - RecordFormat.FragmentOffset; + TlsUtilities.CheckUint16(ciphertextLength); + + TlsUtilities.WriteUint8(encoded.recordType, encoded.buf, encoded.off + RecordFormat.TypeOffset); + TlsUtilities.WriteVersion(recordVersion, encoded.buf, encoded.off + RecordFormat.VersionOffset); + TlsUtilities.WriteUint16(ciphertextLength, encoded.buf, encoded.off + RecordFormat.LengthOffset); + + // TODO[tls-port] Can we support interrupted IO on .NET? + //try + //{ + m_output.Write(encoded.buf, encoded.off, encoded.len); + //} + //catch (InterruptedIOException e) + //{ + // throw new TlsFatalAlert(AlertDescription.internal_error, e); + //} + + m_output.Flush(); + } + + /// + internal void Close() + { + m_inputRecord.Reset(); + + IOException io = null; + try + { + Platform.Dispose(m_input); + } + catch (IOException e) + { + io = e; + } + + try + { + Platform.Dispose(m_output); + } + catch (IOException e) + { + if (io == null) + { + io = e; + } + else + { + // TODO[tls] Available from JDK 7 + //io.addSuppressed(e); + } + } + + if (io != null) + throw io; + } + + /// + private void CheckChangeCipherSpec(byte[] buf, int off, int len) + { + if (1 != len || (byte)ChangeCipherSpec.change_cipher_spec != buf[off]) + { + throw new TlsFatalAlert(AlertDescription.unexpected_message, + "Malformed " + ContentType.GetText(ContentType.change_cipher_spec)); + } + } + + /// + private short CheckRecordType(byte[] buf, int off) + { + short recordType = TlsUtilities.ReadUint8(buf, off); + + if (null != m_readCipherDeferred && recordType == ContentType.application_data) + { + this.m_readCipher = m_readCipherDeferred; + this.m_readCipherDeferred = null; + this.m_ciphertextLimit = m_readCipher.GetCiphertextDecodeLimit(m_plaintextLimit); + m_readSeqNo.Reset(); + } + else if (m_readCipher.UsesOpaqueRecordType) + { + if (ContentType.application_data != recordType) + { + if (m_ignoreChangeCipherSpec && ContentType.change_cipher_spec == recordType) + { + // See RFC 8446 D.4. + } + else + { + throw new TlsFatalAlert(AlertDescription.unexpected_message, + "Opaque " + ContentType.GetText(recordType)); + } + } + } + else + { + switch (recordType) + { + case ContentType.application_data: + { + if (!m_handler.IsApplicationDataReady) + { + throw new TlsFatalAlert(AlertDescription.unexpected_message, + "Not ready for " + ContentType.GetText(ContentType.application_data)); + } + break; + } + case ContentType.alert: + case ContentType.change_cipher_spec: + case ContentType.handshake: + // case ContentType.heartbeat: + break; + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message, + "Unsupported " + ContentType.GetText(recordType)); + } + } + + return recordType; + } + + /// + private static void CheckLength(int length, int limit, short alertDescription) + { + if (length > limit) + throw new TlsFatalAlert(alertDescription); + } + + private sealed class Record + { + private readonly byte[] m_header = new byte[RecordFormat.FragmentOffset]; + + internal volatile byte[] m_buf; + internal volatile int m_pos; + + internal Record() + { + this.m_buf = m_header; + this.m_pos = 0; + } + + /// + internal void FillTo(Stream input, int length) + { + while (m_pos < length) + { + // TODO[tls-port] Can we support interrupted IO on .NET? + //try + //{ + int numRead = input.Read(m_buf, m_pos, length - m_pos); + if (numRead < 1) + break; + + m_pos += numRead; + //} + //catch (InterruptedIOException e) + //{ + // /* + // * Although modifying the bytesTransferred doesn't seem ideal, it's the simplest + // * way to make sure we don't break client code that depends on the exact type, + // * e.g. in Apache's httpcomponents-core-4.4.9, BHttpConnectionBase.isStale + // * depends on the exception type being SocketTimeoutException (or a subclass). + // * + // * We can set to 0 here because the only relevant callstack (via + // * TlsProtocol.readApplicationData) only ever processes one non-empty record (so + // * interruption after partial output cannot occur). + // */ + // m_pos += e.bytesTransferred; + // e.bytesTransferred = 0; + // throw e; + //} + } + } + + /// + internal void ReadFragment(Stream input, int fragmentLength) + { + int recordLength = RecordFormat.FragmentOffset + fragmentLength; + Resize(recordLength); + FillTo(input, recordLength); + if (m_pos < recordLength) + throw new EndOfStreamException(); + } + + /// + internal bool ReadHeader(Stream input) + { + FillTo(input, RecordFormat.FragmentOffset); + if (m_pos == 0) + return false; + + if (m_pos < RecordFormat.FragmentOffset) + throw new EndOfStreamException(); + + return true; + } + + internal void Reset() + { + m_buf = m_header; + m_pos = 0; + } + + private void Resize(int length) + { + if (m_buf.Length < length) + { + byte[] tmp = new byte[length]; + Array.Copy(m_buf, 0, tmp, 0, m_pos); + m_buf = tmp; + } + } + } + + private sealed class SequenceNumber + { + private long m_value = 0L; + private bool m_exhausted = false; + + internal long CurrentValue + { + get { lock (this) return m_value; } + } + + /// + internal long NextValue(short alertDescription) + { + lock (this) + { + if (m_exhausted) + throw new TlsFatalAlert(alertDescription, "Sequence numbers exhausted"); + + long result = m_value; + if (++m_value == 0L) + { + this.m_exhausted = true; + } + return result; + } + } + + internal void Reset() + { + lock (this) + { + this.m_value = 0L; + this.m_exhausted = false; + } + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/RecordStream.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/RecordStream.cs.meta new file mode 100644 index 0000000..1f7bcf9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/RecordStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 95efa56f1f1f10640b5aee72c7c6f0ed +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SecurityParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SecurityParameters.cs new file mode 100644 index 0000000..548e4a4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SecurityParameters.cs @@ -0,0 +1,321 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Tls.Crypto; + +namespace Org.BouncyCastle.Tls +{ + public sealed class SecurityParameters + { + internal int m_entity = -1; + internal bool m_secureRenegotiation = false; + internal int m_cipherSuite = Tls.CipherSuite.TLS_NULL_WITH_NULL_NULL; + internal short m_maxFragmentLength = -1; + internal int m_prfAlgorithm = -1; + internal int m_prfCryptoHashAlgorithm = -1; + internal int m_prfHashLength = -1; + internal int m_verifyDataLength = -1; + internal TlsSecret m_baseKeyClient = null; + internal TlsSecret m_baseKeyServer = null; + internal TlsSecret m_earlyExporterMasterSecret = null; + internal TlsSecret m_earlySecret = null; + internal TlsSecret m_exporterMasterSecret = null; + internal TlsSecret m_handshakeSecret = null; + internal TlsSecret m_masterSecret = null; + internal TlsSecret m_trafficSecretClient = null; + internal TlsSecret m_trafficSecretServer = null; + internal byte[] m_clientRandom = null; + internal byte[] m_serverRandom = null; + internal byte[] m_sessionHash = null; + internal byte[] m_sessionID = null; + internal byte[] m_pskIdentity = null; + internal byte[] m_srpIdentity = null; + internal byte[] m_tlsServerEndPoint = null; + internal byte[] m_tlsUnique = null; + internal bool m_encryptThenMac = false; + internal bool m_extendedMasterSecret = false; + internal bool m_extendedPadding = false; + internal bool m_truncatedHmac = false; + internal ProtocolName m_applicationProtocol = null; + internal bool m_applicationProtocolSet = false; + internal short[] m_clientCertTypes = null; + internal IList m_clientServerNames = null; + internal IList m_clientSigAlgs = null; + internal IList m_clientSigAlgsCert = null; + internal int[] m_clientSupportedGroups = null; + internal IList m_serverSigAlgs = null; + internal IList m_serverSigAlgsCert = null; + internal int[] m_serverSupportedGroups = null; + internal int m_keyExchangeAlgorithm = -1; + internal Certificate m_localCertificate = null; + internal Certificate m_peerCertificate = null; + internal ProtocolVersion m_negotiatedVersion = null; + internal int m_statusRequestVersion = 0; + + // TODO[tls-ops] Investigate whether we can handle verify data using TlsSecret + internal byte[] m_localVerifyData = null; + internal byte[] m_peerVerifyData = null; + + internal void Clear() + { + this.m_sessionHash = null; + this.m_sessionID = null; + this.m_clientCertTypes = null; + this.m_clientServerNames = null; + this.m_clientSigAlgs = null; + this.m_clientSigAlgsCert = null; + this.m_clientSupportedGroups = null; + this.m_serverSigAlgs = null; + this.m_serverSigAlgsCert = null; + this.m_serverSupportedGroups = null; + this.m_statusRequestVersion = 0; + + this.m_baseKeyClient = ClearSecret(m_baseKeyClient); + this.m_baseKeyServer = ClearSecret(m_baseKeyServer); + this.m_earlyExporterMasterSecret = ClearSecret(m_earlyExporterMasterSecret); + this.m_earlySecret = ClearSecret(m_earlySecret); + this.m_exporterMasterSecret = ClearSecret(m_exporterMasterSecret); + this.m_handshakeSecret = ClearSecret(m_handshakeSecret); + this.m_masterSecret = ClearSecret(m_masterSecret); + } + + public ProtocolName ApplicationProtocol + { + get { return m_applicationProtocol; } + } + + public TlsSecret BaseKeyClient + { + get { return m_baseKeyClient; } + } + + public TlsSecret BaseKeyServer + { + get { return m_baseKeyServer; } + } + + public int CipherSuite + { + get { return m_cipherSuite; } + } + + public short[] ClientCertTypes + { + get { return m_clientCertTypes; } + } + + public byte[] ClientRandom + { + get { return m_clientRandom; } + } + + public IList ClientServerNames + { + get { return m_clientServerNames; } + } + + public IList ClientSigAlgs + { + get { return m_clientSigAlgs; } + } + + public IList ClientSigAlgsCert + { + get { return m_clientSigAlgsCert; } + } + + public int[] ClientSupportedGroups + { + get { return m_clientSupportedGroups; } + } + + public TlsSecret EarlyExporterMasterSecret + { + get { return m_earlyExporterMasterSecret; } + } + + public TlsSecret EarlySecret + { + get { return m_earlySecret; } + } + + public TlsSecret ExporterMasterSecret + { + get { return m_exporterMasterSecret; } + } + + public int Entity + { + get { return m_entity; } + } + + public TlsSecret HandshakeSecret + { + get { return m_handshakeSecret; } + } + + public bool IsApplicationProtocolSet + { + get { return m_applicationProtocolSet; } + } + + public bool IsEncryptThenMac + { + get { return m_encryptThenMac; } + } + + public bool IsExtendedMasterSecret + { + get { return m_extendedMasterSecret; } + } + + public bool IsExtendedPadding + { + get { return m_extendedPadding; } + } + + public bool IsSecureRenegotiation + { + get { return m_secureRenegotiation; } + } + + public bool IsTruncatedHmac + { + get { return m_truncatedHmac; } + } + + public int KeyExchangeAlgorithm + { + get { return m_keyExchangeAlgorithm; } + } + + public Certificate LocalCertificate + { + get { return m_localCertificate; } + } + + public byte[] LocalVerifyData + { + get { return m_localVerifyData; } + } + + public TlsSecret MasterSecret + { + get { return m_masterSecret; } + } + + public short MaxFragmentLength + { + get { return m_maxFragmentLength; } + } + + public ProtocolVersion NegotiatedVersion + { + get { return m_negotiatedVersion; } + } + + public Certificate PeerCertificate + { + get { return m_peerCertificate; } + } + + public byte[] PeerVerifyData + { + get { return m_peerVerifyData; } + } + + public int PrfAlgorithm + { + get { return m_prfAlgorithm; } + } + + public int PrfCryptoHashAlgorithm + { + get { return m_prfCryptoHashAlgorithm; } + } + + public int PrfHashLength + { + get { return m_prfHashLength; } + } + + public byte[] PskIdentity + { + get { return m_pskIdentity; } + } + + public byte[] ServerRandom + { + get { return m_serverRandom; } + } + + public IList ServerSigAlgs + { + get { return m_serverSigAlgs; } + } + + public IList ServerSigAlgsCert + { + get { return m_serverSigAlgsCert; } + } + + public int[] ServerSupportedGroups + { + get { return m_serverSupportedGroups; } + } + + public byte[] SessionHash + { + get { return m_sessionHash; } + } + + public byte[] SessionID + { + get { return m_sessionID; } + } + + public byte[] SrpIdentity + { + get { return m_srpIdentity; } + } + + public int StatusRequestVersion + { + get { return m_statusRequestVersion; } + } + + public byte[] TlsServerEndPoint + { + get { return m_tlsServerEndPoint; } + } + + public byte[] TlsUnique + { + get { return m_tlsUnique; } + } + + public TlsSecret TrafficSecretClient + { + get { return m_trafficSecretClient; } + } + + public TlsSecret TrafficSecretServer + { + get { return m_trafficSecretServer; } + } + + public int VerifyDataLength + { + get { return m_verifyDataLength; } + } + + private static TlsSecret ClearSecret(TlsSecret secret) + { + if (null != secret) + { + secret.Destroy(); + } + return null; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SecurityParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SecurityParameters.cs.meta new file mode 100644 index 0000000..5f86bef --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SecurityParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0d1e9907b0201b6458d635cbe4a90a1b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ServerHello.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ServerHello.cs new file mode 100644 index 0000000..15cc090 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ServerHello.cs @@ -0,0 +1,108 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls +{ + public sealed class ServerHello + { + private static readonly byte[] HelloRetryRequestMagic = { 0xCF, 0x21, 0xAD, 0x74, 0xE5, 0x9A, 0x61, 0x11, 0xBE, + 0x1D, 0x8C, 0x02, 0x1E, 0x65, 0xB8, 0x91, 0xC2, 0xA2, 0x11, 0x16, 0x7A, 0xBB, 0x8C, 0x5E, 0x07, 0x9E, 0x09, + 0xE2, 0xC8, 0xA8, 0x33, 0x9C }; + + private readonly ProtocolVersion m_version; + private readonly byte[] m_random; + private readonly byte[] m_sessionID; + private readonly int m_cipherSuite; + private readonly IDictionary m_extensions; + + public ServerHello(byte[] sessionID, int cipherSuite, IDictionary extensions) + : this(ProtocolVersion.TLSv12, Arrays.Clone(HelloRetryRequestMagic), sessionID, cipherSuite, extensions) + { + } + + public ServerHello(ProtocolVersion version, byte[] random, byte[] sessionID, int cipherSuite, + IDictionary extensions) + { + this.m_version = version; + this.m_random = random; + this.m_sessionID = sessionID; + this.m_cipherSuite = cipherSuite; + this.m_extensions = extensions; + } + + public int CipherSuite + { + get { return m_cipherSuite; } + } + + public IDictionary Extensions + { + get { return m_extensions; } + } + + public byte[] Random + { + get { return m_random; } + } + + public byte[] SessionID + { + get { return m_sessionID; } + } + + public ProtocolVersion Version + { + get { return m_version; } + } + + public bool IsHelloRetryRequest() + { + return Arrays.AreEqual(HelloRetryRequestMagic, m_random); + } + + /// Encode this to a . + /// the of the current connection. + /// the to encode to. + /// + public void Encode(TlsContext context, Stream output) + { + TlsUtilities.WriteVersion(m_version, output); + + output.Write(m_random, 0, m_random.Length); + + TlsUtilities.WriteOpaque8(m_sessionID, output); + + TlsUtilities.WriteUint16(m_cipherSuite, output); + + TlsUtilities.WriteUint8(CompressionMethod.cls_null, output); + + TlsProtocol.WriteExtensions(output, m_extensions); + } + + /// Parse a from a . + /// the to parse from. + /// a object. + /// + public static ServerHello Parse(MemoryStream input) + { + ProtocolVersion version = TlsUtilities.ReadVersion(input); + + byte[] random = TlsUtilities.ReadFully(32, input); + + byte[] sessionID = TlsUtilities.ReadOpaque8(input, 0, 32); + + int cipherSuite = TlsUtilities.ReadUint16(input); + + short compressionMethod = TlsUtilities.ReadUint8(input); + if (CompressionMethod.cls_null != compressionMethod) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + IDictionary extensions = TlsProtocol.ReadExtensions(input); + + return new ServerHello(version, random, sessionID, cipherSuite, extensions); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ServerHello.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ServerHello.cs.meta new file mode 100644 index 0000000..d85b612 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ServerHello.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5f3bb5506545ac64dbaa7d1681607f6e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ServerName.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ServerName.cs new file mode 100644 index 0000000..da40c2c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ServerName.cs @@ -0,0 +1,63 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Tls +{ + /// RFC 6066 3. Server Name Indication + /// + /// Current implementation uses this guidance: "For backward compatibility, all future data structures associated + /// with new NameTypes MUST begin with a 16-bit length field. TLS MAY treat provided server names as opaque data + /// and pass the names and types to the application.". RFC 6066 specifies ASCII encoding for host_name (possibly + /// using A-labels for IDNs), but note that the previous version (RFC 4366) specified UTF-8 encoding (see RFC 6066 + /// Appendix A). For maximum compatibility, it is recommended that client code tolerate receiving UTF-8 from the + /// peer, but only generate ASCII itself. + /// + public sealed class ServerName + { + private readonly short nameType; + private readonly byte[] nameData; + + public ServerName(short nameType, byte[] nameData) + { + if (!TlsUtilities.IsValidUint8(nameType)) + throw new ArgumentException("must be from 0 to 255", "nameType"); + if (null == nameData) + throw new ArgumentNullException("nameData"); + if (nameData.Length < 1 || !TlsUtilities.IsValidUint16(nameData.Length)) + throw new ArgumentException("must have length from 1 to 65535", "nameData"); + + this.nameType = nameType; + this.nameData = nameData; + } + + public byte[] NameData + { + get { return nameData; } + } + + public short NameType + { + get { return nameType; } + } + + /// Encode this to a . + /// the to encode to. + /// + public void Encode(Stream output) + { + TlsUtilities.WriteUint8(nameType, output); + TlsUtilities.WriteOpaque16(nameData, output); + } + + /// Parse a from a . + /// the to parse from. + /// a object. + /// + public static ServerName Parse(Stream input) + { + short name_type = TlsUtilities.ReadUint8(input); + byte[] nameData = TlsUtilities.ReadOpaque16(input, 1); + return new ServerName(name_type, nameData); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ServerName.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ServerName.cs.meta new file mode 100644 index 0000000..2efc947 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ServerName.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bdac5426bd1e8da43b44371f369a611e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ServerNameList.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ServerNameList.cs new file mode 100644 index 0000000..915e943 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ServerNameList.cs @@ -0,0 +1,87 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Tls +{ + public sealed class ServerNameList + { + private readonly IList m_serverNameList; + + /// an of . + public ServerNameList(IList serverNameList) + { + if (null == serverNameList) + throw new ArgumentNullException("serverNameList"); + + this.m_serverNameList = serverNameList; + } + + /// an of . + public IList ServerNames + { + get { return m_serverNameList; } + } + + /// Encode this to a . + /// the to encode to . + /// + public void Encode(Stream output) + { + MemoryStream buf = new MemoryStream(); + + short[] nameTypesSeen = TlsUtilities.EmptyShorts; + foreach (ServerName entry in ServerNames) + { + nameTypesSeen = CheckNameType(nameTypesSeen, entry.NameType); + if (null == nameTypesSeen) + throw new TlsFatalAlert(AlertDescription.internal_error); + + entry.Encode(buf); + } + + int length = (int)buf.Length; + TlsUtilities.CheckUint16(length); + TlsUtilities.WriteUint16(length, output); + Streams.WriteBufTo(buf, output); + } + + /// Parse a from a . + /// the to parse from. + /// a object. + /// + public static ServerNameList Parse(Stream input) + { + byte[] data = TlsUtilities.ReadOpaque16(input, 1); + + MemoryStream buf = new MemoryStream(data, false); + + short[] nameTypesSeen = TlsUtilities.EmptyShorts; + IList server_name_list = Platform.CreateArrayList(); + while (buf.Position < buf.Length) + { + ServerName entry = ServerName.Parse(buf); + + nameTypesSeen = CheckNameType(nameTypesSeen, entry.NameType); + if (null == nameTypesSeen) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + server_name_list.Add(entry); + } + + return new ServerNameList(server_name_list); + } + + private static short[] CheckNameType(short[] nameTypesSeen, short nameType) + { + // RFC 6066 3. The ServerNameList MUST NOT contain more than one name of the same NameType. + if (Arrays.Contains(nameTypesSeen, nameType)) + return null; + + return Arrays.Append(nameTypesSeen, nameType); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ServerNameList.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ServerNameList.cs.meta new file mode 100644 index 0000000..e62fe45 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ServerNameList.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6eb28b710960c784a97c9cd2e00150df +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ServerOnlyTlsAuthentication.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ServerOnlyTlsAuthentication.cs new file mode 100644 index 0000000..5a8d599 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ServerOnlyTlsAuthentication.cs @@ -0,0 +1,15 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + public abstract class ServerOnlyTlsAuthentication + : TlsAuthentication + { + public abstract void NotifyServerCertificate(TlsServerCertificate serverCertificate); + + public TlsCredentials GetClientCredentials(CertificateRequest certificateRequest) + { + return null; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ServerOnlyTlsAuthentication.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ServerOnlyTlsAuthentication.cs.meta new file mode 100644 index 0000000..be03fd3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ServerOnlyTlsAuthentication.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c8dc5ac068c3e8c4b921c94d0a1a874d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ServerSrpParams.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ServerSrpParams.cs new file mode 100644 index 0000000..9aca882 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ServerSrpParams.cs @@ -0,0 +1,67 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls +{ + public sealed class ServerSrpParams + { + private BigInteger m_N, m_g, m_B; + private byte[] m_s; + + public ServerSrpParams(BigInteger N, BigInteger g, byte[] s, BigInteger B) + { + this.m_N = N; + this.m_g = g; + this.m_s = Arrays.Clone(s); + this.m_B = B; + } + + public BigInteger B + { + get { return m_B; } + } + + public BigInteger G + { + get { return m_g; } + } + + public BigInteger N + { + get { return m_N; } + } + + public byte[] S + { + get { return m_s; } + } + + /// Encode this to a . + /// the to encode to. + /// + public void Encode(Stream output) + { + TlsSrpUtilities.WriteSrpParameter(m_N, output); + TlsSrpUtilities.WriteSrpParameter(m_g, output); + TlsUtilities.WriteOpaque8(m_s, output); + TlsSrpUtilities.WriteSrpParameter(m_B, output); + } + + /// Parse a from a . + /// the to parse from. + /// a object. + /// + public static ServerSrpParams Parse(Stream input) + { + BigInteger N = TlsSrpUtilities.ReadSrpParameter(input); + BigInteger g = TlsSrpUtilities.ReadSrpParameter(input); + byte[] s = TlsUtilities.ReadOpaque8(input, 1); + BigInteger B = TlsSrpUtilities.ReadSrpParameter(input); + + return new ServerSrpParams(N, g, s, B); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ServerSrpParams.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ServerSrpParams.cs.meta new file mode 100644 index 0000000..c4fbe3a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/ServerSrpParams.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d93829080f523f443b34eaa1c739f317 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SessionParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SessionParameters.cs new file mode 100644 index 0000000..9a62e35 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SessionParameters.cs @@ -0,0 +1,195 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Tls.Crypto; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls +{ + public sealed class SessionParameters + { + public sealed class Builder + { + private int m_cipherSuite = -1; + private Certificate m_localCertificate = null; + private TlsSecret m_masterSecret = null; + private ProtocolVersion m_negotiatedVersion; + private Certificate m_peerCertificate = null; + private byte[] m_pskIdentity = null; + private byte[] m_srpIdentity = null; + private byte[] m_encodedServerExtensions = null; + private bool m_extendedMasterSecret = false; + + public Builder() + { + } + + public SessionParameters Build() + { + Validate(m_cipherSuite >= 0, "cipherSuite"); + Validate(m_masterSecret != null, "masterSecret"); + return new SessionParameters(m_cipherSuite, m_localCertificate, m_masterSecret, m_negotiatedVersion, + m_peerCertificate, m_pskIdentity, m_srpIdentity, m_encodedServerExtensions, m_extendedMasterSecret); + } + + public Builder SetCipherSuite(int cipherSuite) + { + this.m_cipherSuite = cipherSuite; + return this; + } + + public Builder SetExtendedMasterSecret(bool extendedMasterSecret) + { + this.m_extendedMasterSecret = extendedMasterSecret; + return this; + } + + public Builder SetLocalCertificate(Certificate localCertificate) + { + this.m_localCertificate = localCertificate; + return this; + } + + public Builder SetMasterSecret(TlsSecret masterSecret) + { + this.m_masterSecret = masterSecret; + return this; + } + + public Builder SetNegotiatedVersion(ProtocolVersion negotiatedVersion) + { + this.m_negotiatedVersion = negotiatedVersion; + return this; + } + + public Builder SetPeerCertificate(Certificate peerCertificate) + { + this.m_peerCertificate = peerCertificate; + return this; + } + + public Builder SetPskIdentity(byte[] pskIdentity) + { + this.m_pskIdentity = pskIdentity; + return this; + } + + public Builder SetSrpIdentity(byte[] srpIdentity) + { + this.m_srpIdentity = srpIdentity; + return this; + } + + /// + public Builder SetServerExtensions(IDictionary serverExtensions) + { + if (serverExtensions == null || serverExtensions.Count < 1) + { + this.m_encodedServerExtensions = null; + } + else + { + MemoryStream buf = new MemoryStream(); + TlsProtocol.WriteExtensions(buf, serverExtensions); + this.m_encodedServerExtensions = buf.ToArray(); + } + return this; + } + + private void Validate(bool condition, string parameter) + { + if (!condition) + throw new InvalidOperationException("Required session parameter '" + parameter + "' not configured"); + } + } + + private readonly int m_cipherSuite; + private readonly Certificate m_localCertificate; + private readonly TlsSecret m_masterSecret; + private readonly ProtocolVersion m_negotiatedVersion; + private readonly Certificate m_peerCertificate; + private readonly byte[] m_pskIdentity; + private readonly byte[] m_srpIdentity; + private readonly byte[] m_encodedServerExtensions; + private readonly bool m_extendedMasterSecret; + + private SessionParameters(int cipherSuite, Certificate localCertificate, TlsSecret masterSecret, + ProtocolVersion negotiatedVersion, Certificate peerCertificate, byte[] pskIdentity, byte[] srpIdentity, + byte[] encodedServerExtensions, bool extendedMasterSecret) + { + this.m_cipherSuite = cipherSuite; + this.m_localCertificate = localCertificate; + this.m_masterSecret = masterSecret; + this.m_negotiatedVersion = negotiatedVersion; + this.m_peerCertificate = peerCertificate; + this.m_pskIdentity = Arrays.Clone(pskIdentity); + this.m_srpIdentity = Arrays.Clone(srpIdentity); + this.m_encodedServerExtensions = encodedServerExtensions; + this.m_extendedMasterSecret = extendedMasterSecret; + } + + public int CipherSuite + { + get { return m_cipherSuite; } + } + + public void Clear() + { + if (m_masterSecret != null) + { + m_masterSecret.Destroy(); + } + } + + public SessionParameters Copy() + { + return new SessionParameters(m_cipherSuite, m_localCertificate, m_masterSecret, m_negotiatedVersion, + m_peerCertificate, m_pskIdentity, m_srpIdentity, m_encodedServerExtensions, m_extendedMasterSecret); + } + + public bool IsExtendedMasterSecret + { + get { return m_extendedMasterSecret; } + } + + public Certificate LocalCertificate + { + get { return m_localCertificate; } + } + + public TlsSecret MasterSecret + { + get { return m_masterSecret; } + } + + public ProtocolVersion NegotiatedVersion + { + get { return m_negotiatedVersion; } + } + + public Certificate PeerCertificate + { + get { return m_peerCertificate; } + } + + public byte[] PskIdentity + { + get { return m_pskIdentity; } + } + + /// + public IDictionary ReadServerExtensions() + { + if (m_encodedServerExtensions == null) + return null; + + return TlsProtocol.ReadExtensions(new MemoryStream(m_encodedServerExtensions, false)); + } + + public byte[] SrpIdentity + { + get { return m_srpIdentity; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SessionParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SessionParameters.cs.meta new file mode 100644 index 0000000..35b500a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SessionParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0f955978e6b9f364884e28eee9a3501e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SignatureAlgorithm.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SignatureAlgorithm.cs new file mode 100644 index 0000000..726504c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SignatureAlgorithm.cs @@ -0,0 +1,125 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + /** + * RFC 5246 7.4.1.4.1 (in RFC 2246, there were no specific values assigned) + */ + public class SignatureAlgorithm + { + public const short anonymous = 0; + public const short rsa = 1; + public const short dsa = 2; + public const short ecdsa = 3; + + /* + * RFC 8422 + */ + public const short ed25519 = 7; + public const short ed448 = 8; + + /* + * RFC 8446 (implied from SignatureScheme values) + * RFC 8447 reserved these values without allocating the implied names + */ + public const short rsa_pss_rsae_sha256 = 4; + public const short rsa_pss_rsae_sha384 = 5; + public const short rsa_pss_rsae_sha512 = 6; + public const short rsa_pss_pss_sha256 = 9; + public const short rsa_pss_pss_sha384 = 10; + public const short rsa_pss_pss_sha512 = 11; + + /* + * RFC 8734 (implied from SignatureScheme values) + */ + public const short ecdsa_brainpoolP256r1tls13_sha256 = 26; + public const short ecdsa_brainpoolP384r1tls13_sha384 = 27; + public const short ecdsa_brainpoolP512r1tls13_sha512 = 28; + + /* + * draft-smyshlyaev-tls12-gost-suites-10 + */ + public const short gostr34102012_256 = 64; + public const short gostr34102012_512 = 65; + + public static short GetClientCertificateType(short signatureAlgorithm) + { + switch (signatureAlgorithm) + { + case SignatureAlgorithm.rsa: + case SignatureAlgorithm.rsa_pss_rsae_sha256: + case SignatureAlgorithm.rsa_pss_rsae_sha384: + case SignatureAlgorithm.rsa_pss_rsae_sha512: + case SignatureAlgorithm.rsa_pss_pss_sha256: + case SignatureAlgorithm.rsa_pss_pss_sha384: + case SignatureAlgorithm.rsa_pss_pss_sha512: + return ClientCertificateType.rsa_sign; + + case SignatureAlgorithm.dsa: + return ClientCertificateType.dss_sign; + + case SignatureAlgorithm.ecdsa: + case SignatureAlgorithm.ed25519: + case SignatureAlgorithm.ed448: + return ClientCertificateType.ecdsa_sign; + + case SignatureAlgorithm.gostr34102012_256: + return ClientCertificateType.gost_sign256; + + case SignatureAlgorithm.gostr34102012_512: + return ClientCertificateType.gost_sign512; + + default: + return -1; + } + } + + public static string GetName(short signatureAlgorithm) + { + switch (signatureAlgorithm) + { + case anonymous: + return "anonymous"; + case rsa: + return "rsa"; + case dsa: + return "dsa"; + case ecdsa: + return "ecdsa"; + case ed25519: + return "ed25519"; + case ed448: + return "ed448"; + case gostr34102012_256: + return "gostr34102012_256"; + case gostr34102012_512: + return "gostr34102012_512"; + case rsa_pss_rsae_sha256: + return "rsa_pss_rsae_sha256"; + case rsa_pss_rsae_sha384: + return "rsa_pss_rsae_sha384"; + case rsa_pss_rsae_sha512: + return "rsa_pss_rsae_sha512"; + case rsa_pss_pss_sha256: + return "rsa_pss_pss_sha256"; + case rsa_pss_pss_sha384: + return "rsa_pss_pss_sha384"; + case rsa_pss_pss_sha512: + return "rsa_pss_pss_sha512"; + case ecdsa_brainpoolP256r1tls13_sha256: + return "ecdsa_brainpoolP256r1tls13_sha256"; + case ecdsa_brainpoolP384r1tls13_sha384: + return "ecdsa_brainpoolP384r1tls13_sha384"; + case ecdsa_brainpoolP512r1tls13_sha512: + return "ecdsa_brainpoolP512r1tls13_sha512"; + default: + return "UNKNOWN"; + } + } + + public static string GetText(short signatureAlgorithm) + { + return GetName(signatureAlgorithm) + "(" + signatureAlgorithm + ")"; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SignatureAlgorithm.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SignatureAlgorithm.cs.meta new file mode 100644 index 0000000..655ad29 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SignatureAlgorithm.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d170846397d647a4781314b1fccee1ab +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SignatureAndHashAlgorithm.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SignatureAndHashAlgorithm.cs new file mode 100644 index 0000000..9de2a42 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SignatureAndHashAlgorithm.cs @@ -0,0 +1,171 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Tls +{ + /// RFC 5246 7.4.1.4.1 + public sealed class SignatureAndHashAlgorithm + { + public static readonly SignatureAndHashAlgorithm ecdsa_brainpoolP256r1tls13_sha256 = + Create(SignatureScheme.ecdsa_brainpoolP256r1tls13_sha256); + public static readonly SignatureAndHashAlgorithm ecdsa_brainpoolP384r1tls13_sha384 = + Create(SignatureScheme.ecdsa_brainpoolP384r1tls13_sha384); + public static readonly SignatureAndHashAlgorithm ecdsa_brainpoolP512r1tls13_sha512 = + Create(SignatureScheme.ecdsa_brainpoolP512r1tls13_sha512); + public static readonly SignatureAndHashAlgorithm ed25519 = + Create(SignatureScheme.ed25519); + public static readonly SignatureAndHashAlgorithm ed448 = + Create(SignatureScheme.ed448); + public static readonly SignatureAndHashAlgorithm gostr34102012_256 = + Create(HashAlgorithm.Intrinsic, SignatureAlgorithm.gostr34102012_256); + public static readonly SignatureAndHashAlgorithm gostr34102012_512 = + Create(HashAlgorithm.Intrinsic, SignatureAlgorithm.gostr34102012_512); + public static readonly SignatureAndHashAlgorithm rsa_pss_rsae_sha256 = + Create(SignatureScheme.rsa_pss_rsae_sha256); + public static readonly SignatureAndHashAlgorithm rsa_pss_rsae_sha384 = + Create(SignatureScheme.rsa_pss_rsae_sha384); + public static readonly SignatureAndHashAlgorithm rsa_pss_rsae_sha512 = + Create(SignatureScheme.rsa_pss_rsae_sha512); + public static readonly SignatureAndHashAlgorithm rsa_pss_pss_sha256 = + Create(SignatureScheme.rsa_pss_pss_sha256); + public static readonly SignatureAndHashAlgorithm rsa_pss_pss_sha384 = + Create(SignatureScheme.rsa_pss_pss_sha384); + public static readonly SignatureAndHashAlgorithm rsa_pss_pss_sha512 = + Create(SignatureScheme.rsa_pss_pss_sha512); + + public static SignatureAndHashAlgorithm GetInstance(short hashAlgorithm, short signatureAlgorithm) + { + switch (hashAlgorithm) + { + case HashAlgorithm.Intrinsic: + return GetInstanceIntrinsic(signatureAlgorithm); + default: + return Create(hashAlgorithm, signatureAlgorithm); + } + } + + private static SignatureAndHashAlgorithm GetInstanceIntrinsic(short signatureAlgorithm) + { + switch (signatureAlgorithm) + { + case SignatureAlgorithm.ed25519: + return ed25519; + case SignatureAlgorithm.ed448: + return ed448; + case SignatureAlgorithm.gostr34102012_256: + return gostr34102012_256; + case SignatureAlgorithm.gostr34102012_512: + return gostr34102012_512; + case SignatureAlgorithm.rsa_pss_rsae_sha256: + return rsa_pss_rsae_sha256; + case SignatureAlgorithm.rsa_pss_rsae_sha384: + return rsa_pss_rsae_sha384; + case SignatureAlgorithm.rsa_pss_rsae_sha512: + return rsa_pss_rsae_sha512; + case SignatureAlgorithm.rsa_pss_pss_sha256: + return rsa_pss_pss_sha256; + case SignatureAlgorithm.rsa_pss_pss_sha384: + return rsa_pss_pss_sha384; + case SignatureAlgorithm.rsa_pss_pss_sha512: + return rsa_pss_pss_sha512; + case SignatureAlgorithm.ecdsa_brainpoolP256r1tls13_sha256: + return ecdsa_brainpoolP256r1tls13_sha256; + case SignatureAlgorithm.ecdsa_brainpoolP384r1tls13_sha384: + return ecdsa_brainpoolP384r1tls13_sha384; + case SignatureAlgorithm.ecdsa_brainpoolP512r1tls13_sha512: + return ecdsa_brainpoolP512r1tls13_sha512; + default: + return Create(HashAlgorithm.Intrinsic, signatureAlgorithm); + } + } + + private static SignatureAndHashAlgorithm Create(int signatureScheme) + { + short hashAlgorithm = SignatureScheme.GetHashAlgorithm(signatureScheme); + short signatureAlgorithm = SignatureScheme.GetSignatureAlgorithm(signatureScheme); + return Create(hashAlgorithm, signatureAlgorithm); + } + + private static SignatureAndHashAlgorithm Create(short hashAlgorithm, short signatureAlgorithm) + { + return new SignatureAndHashAlgorithm(hashAlgorithm, signatureAlgorithm); + } + + private readonly short m_hash; + private readonly short m_signature; + + /// + /// + public SignatureAndHashAlgorithm(short hash, short signature) + { + /* + * TODO]tls] The TlsUtils methods are inlined here to avoid circular static initialization + * b/w these classes. We should refactor parts of TlsUtils into separate classes. e.g. the + * TLS low-level encoding methods, and/or the SigAndHash registry and methods. + */ + + //if (!TlsUtilities.IsValidUint8(hash)) + if ((hash & 0xFF) != hash) + throw new ArgumentException("should be a uint8", "hash"); + + //if (!TlsUtilities.IsValidUint8(signature)) + if ((signature & 0xFF) != signature) + throw new ArgumentException("should be a uint8", "signature"); + + this.m_hash = hash; + this.m_signature = signature; + } + + /// + public short Hash + { + get { return m_hash; } + } + + /// + public short Signature + { + get { return m_signature; } + } + + /// Encode this to a . + /// the to encode to. + /// + public void Encode(Stream output) + { + TlsUtilities.WriteUint8(Hash, output); + TlsUtilities.WriteUint8(Signature, output); + } + + /// Parse a from a . + /// the to parse from. + /// a object. + /// + public static SignatureAndHashAlgorithm Parse(Stream input) + { + short hash = TlsUtilities.ReadUint8(input); + short signature = TlsUtilities.ReadUint8(input); + + return GetInstance(hash, signature); + } + + public override bool Equals(object obj) + { + if (!(obj is SignatureAndHashAlgorithm)) + return false; + + SignatureAndHashAlgorithm other = (SignatureAndHashAlgorithm)obj; + return other.Hash == Hash && other.Signature == Signature; + } + + public override int GetHashCode() + { + return ((int)Hash << 16) | (int)Signature; + } + + public override string ToString() + { + return "{" + HashAlgorithm.GetText(Hash) + "," + SignatureAlgorithm.GetText(Signature) + "}"; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SignatureAndHashAlgorithm.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SignatureAndHashAlgorithm.cs.meta new file mode 100644 index 0000000..fc69584 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SignatureAndHashAlgorithm.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0f7e6954382c6a14782e24f526e2cef1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SignatureScheme.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SignatureScheme.cs new file mode 100644 index 0000000..4b93413 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SignatureScheme.cs @@ -0,0 +1,235 @@ +using System; + +using Org.BouncyCastle.Tls.Crypto; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls +{ + public abstract class SignatureScheme + { + /* + * RFC 8446 + */ + + public const int rsa_pkcs1_sha1 = 0x0201; + public const int ecdsa_sha1 = 0x0203; + + public const int rsa_pkcs1_sha256 = 0x0401; + public const int rsa_pkcs1_sha384 = 0x0501; + public const int rsa_pkcs1_sha512 = 0x0601; + + public const int ecdsa_secp256r1_sha256 = 0x0403; + public const int ecdsa_secp384r1_sha384 = 0x0503; + public const int ecdsa_secp521r1_sha512 = 0x0603; + + public const int rsa_pss_rsae_sha256 = 0x0804; + public const int rsa_pss_rsae_sha384 = 0x0805; + public const int rsa_pss_rsae_sha512 = 0x0806; + + public const int ed25519 = 0x0807; + public const int ed448 = 0x0808; + + public const int rsa_pss_pss_sha256 = 0x0809; + public const int rsa_pss_pss_sha384 = 0x080A; + public const int rsa_pss_pss_sha512 = 0x080B; + + /* + * RFC 8734 + */ + + public const int ecdsa_brainpoolP256r1tls13_sha256 = 0x081A; + public const int ecdsa_brainpoolP384r1tls13_sha384 = 0x081B; + public const int ecdsa_brainpoolP512r1tls13_sha512 = 0x081C; + + /* + * RFC 8998 + */ + + public const int sm2sig_sm3 = 0x0708; + + /* + * RFC 8446 reserved for private use (0xFE00..0xFFFF) + */ + + public static int From(SignatureAndHashAlgorithm sigAndHashAlg) + { + if (null == sigAndHashAlg) + throw new ArgumentNullException(); + + return From(sigAndHashAlg.Hash, sigAndHashAlg.Signature); + } + + public static int From(short hashAlgorithm, short signatureAlgorithm) + { + return ((hashAlgorithm & 0xFF) << 8) | (signatureAlgorithm & 0xFF); + } + + public static int GetCryptoHashAlgorithm(int signatureScheme) + { + switch (signatureScheme) + { + case ed25519: + case ed448: + return -1; + case ecdsa_brainpoolP256r1tls13_sha256: + case rsa_pss_pss_sha256: + case rsa_pss_rsae_sha256: + return CryptoHashAlgorithm.sha256; + case ecdsa_brainpoolP384r1tls13_sha384: + case rsa_pss_pss_sha384: + case rsa_pss_rsae_sha384: + return CryptoHashAlgorithm.sha384; + case ecdsa_brainpoolP512r1tls13_sha512: + case rsa_pss_pss_sha512: + case rsa_pss_rsae_sha512: + return CryptoHashAlgorithm.sha512; + case sm2sig_sm3: + return CryptoHashAlgorithm.sm3; + default: + { + short hashAlgorithm = GetHashAlgorithm(signatureScheme); + if (HashAlgorithm.Intrinsic == hashAlgorithm || !HashAlgorithm.IsRecognized(hashAlgorithm)) + return -1; + + return TlsCryptoUtilities.GetHash(GetHashAlgorithm(signatureScheme)); + } + } + } + + public static string GetName(int signatureScheme) + { + switch (signatureScheme) + { + case rsa_pkcs1_sha1: + return "rsa_pkcs1_sha1"; + case ecdsa_sha1: + return "ecdsa_sha1"; + case rsa_pkcs1_sha256: + return "rsa_pkcs1_sha256"; + case rsa_pkcs1_sha384: + return "rsa_pkcs1_sha384"; + case rsa_pkcs1_sha512: + return "rsa_pkcs1_sha512"; + case ecdsa_secp256r1_sha256: + return "ecdsa_secp256r1_sha256"; + case ecdsa_secp384r1_sha384: + return "ecdsa_secp384r1_sha384"; + case ecdsa_secp521r1_sha512: + return "ecdsa_secp521r1_sha512"; + case rsa_pss_rsae_sha256: + return "rsa_pss_rsae_sha256"; + case rsa_pss_rsae_sha384: + return "rsa_pss_rsae_sha384"; + case rsa_pss_rsae_sha512: + return "rsa_pss_rsae_sha512"; + case ed25519: + return "ed25519"; + case ed448: + return "ed448"; + case rsa_pss_pss_sha256: + return "rsa_pss_pss_sha256"; + case rsa_pss_pss_sha384: + return "rsa_pss_pss_sha384"; + case rsa_pss_pss_sha512: + return "rsa_pss_pss_sha512"; + case ecdsa_brainpoolP256r1tls13_sha256: + return "ecdsa_brainpoolP256r1tls13_sha256"; + case ecdsa_brainpoolP384r1tls13_sha384: + return "ecdsa_brainpoolP384r1tls13_sha384"; + case ecdsa_brainpoolP512r1tls13_sha512: + return "ecdsa_brainpoolP512r1tls13_sha512"; + case sm2sig_sm3: + return "sm2sig_sm3"; + default: + return "UNKNOWN"; + } + } + + /** + * For TLS 1.3+ usage, some signature schemes are constrained to use a particular + * ({@link NamedGroup}. Not relevant for TLS 1.2 and below. + */ + public static int GetNamedGroup(int signatureScheme) + { + switch (signatureScheme) + { + case ecdsa_brainpoolP256r1tls13_sha256: + return NamedGroup.brainpoolP256r1tls13; + case ecdsa_brainpoolP384r1tls13_sha384: + return NamedGroup.brainpoolP384r1tls13; + case ecdsa_brainpoolP512r1tls13_sha512: + return NamedGroup.brainpoolP512r1tls13; + case ecdsa_secp256r1_sha256: + return NamedGroup.secp256r1; + case ecdsa_secp384r1_sha384: + return NamedGroup.secp384r1; + case ecdsa_secp521r1_sha512: + return NamedGroup.secp521r1; + case sm2sig_sm3: + return NamedGroup.curveSM2; + default: + return -1; + } + } + + public static short GetHashAlgorithm(int signatureScheme) + { + // TODO[RFC 8998] sm2sig_sm3 + return (short)((signatureScheme >> 8) & 0xFF); + } + + public static short GetSignatureAlgorithm(int signatureScheme) + { + // TODO[RFC 8998] sm2sig_sm3 + return (short)(signatureScheme & 0xFF); + } + + public static SignatureAndHashAlgorithm GetSignatureAndHashAlgorithm(int signatureScheme) + { + return SignatureAndHashAlgorithm.GetInstance( + GetHashAlgorithm(signatureScheme), + GetSignatureAlgorithm(signatureScheme)); + } + + public static string GetText(int signatureScheme) + { + string hex = Platform.ToUpperInvariant(Convert.ToString(signatureScheme, 16)); + return GetName(signatureScheme) + "(0x" + hex + ")"; + } + + public static bool IsPrivate(int signatureScheme) + { + return (signatureScheme >> 9) == 0xFE; + } + + public static bool IsECDsa(int signatureScheme) + { + switch (signatureScheme) + { + case ecdsa_brainpoolP256r1tls13_sha256: + case ecdsa_brainpoolP384r1tls13_sha384: + case ecdsa_brainpoolP512r1tls13_sha512: + return true; + default: + return SignatureAlgorithm.ecdsa == GetSignatureAlgorithm(signatureScheme); + } + } + + public static bool IsRsaPss(int signatureScheme) + { + switch (signatureScheme) + { + case rsa_pss_rsae_sha256: + case rsa_pss_rsae_sha384: + case rsa_pss_rsae_sha512: + case rsa_pss_pss_sha256: + case rsa_pss_pss_sha384: + case rsa_pss_pss_sha512: + return true; + default: + return false; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SignatureScheme.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SignatureScheme.cs.meta new file mode 100644 index 0000000..faa4488 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SignatureScheme.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2b85fc50395e9ec4284b2c8974d27794 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SimulatedTlsSrpIdentityManager.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SimulatedTlsSrpIdentityManager.cs new file mode 100644 index 0000000..904bdae --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SimulatedTlsSrpIdentityManager.cs @@ -0,0 +1,69 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Tls.Crypto; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls +{ + /// An implementation of that simulates the existence of "unknown" + /// identities to obscure the fact that there is no verifier for them. + public class SimulatedTlsSrpIdentityManager + : TlsSrpIdentityManager + { + private static readonly byte[] PrefixPassword = Strings.ToByteArray("password"); + private static readonly byte[] PrefixSalt = Strings.ToByteArray("salt"); + + /// Create a that implements the algorithm from RFC 5054 + /// 2.5.1.3. + /// + /// the defining the group that SRP is operating in. + /// the secret "seed key" referred to in RFC 5054 2.5.1.3. + /// an instance of . + /// + public static SimulatedTlsSrpIdentityManager GetRfc5054Default(TlsCrypto crypto, Srp6Group group, byte[] seedKey) + { + TlsMac mac = crypto.CreateHmac(MacAlgorithm.hmac_sha1); + + mac.SetKey(seedKey, 0, seedKey.Length); + + TlsSrpConfig srpConfig = new TlsSrpConfig(); + + srpConfig.SetExplicitNG(new BigInteger[]{ group.N, group.G }); + + return new SimulatedTlsSrpIdentityManager(group, crypto.CreateSrp6VerifierGenerator(srpConfig), mac); + } + + protected readonly Srp6Group m_group; + protected readonly TlsSrp6VerifierGenerator m_verifierGenerator; + protected readonly TlsMac m_mac; + + public SimulatedTlsSrpIdentityManager(Srp6Group group, TlsSrp6VerifierGenerator verifierGenerator, TlsMac mac) + { + this.m_group = group; + this.m_verifierGenerator = verifierGenerator; + this.m_mac = mac; + } + + public virtual TlsSrpLoginParameters GetLoginParameters(byte[] identity) + { + m_mac.Update(PrefixSalt, 0, PrefixSalt.Length); + m_mac.Update(identity, 0, identity.Length); + + byte[] salt = m_mac.CalculateMac(); + + m_mac.Update(PrefixPassword, 0, PrefixPassword.Length); + m_mac.Update(identity, 0, identity.Length); + + byte[] password = m_mac.CalculateMac(); + + BigInteger verifier = m_verifierGenerator.GenerateVerifier(salt, identity, password); + + TlsSrpConfig srpConfig = new TlsSrpConfig(); + srpConfig.SetExplicitNG(new BigInteger[]{ m_group.N, m_group.G }); + + return new TlsSrpLoginParameters(identity, srpConfig, verifier, salt); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SimulatedTlsSrpIdentityManager.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SimulatedTlsSrpIdentityManager.cs.meta new file mode 100644 index 0000000..84b6735 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SimulatedTlsSrpIdentityManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f1109ee7a8bbb584483719cce6ae6680 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SrpTlsClient.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SrpTlsClient.cs new file mode 100644 index 0000000..a2b0e94 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SrpTlsClient.cs @@ -0,0 +1,83 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Tls.Crypto; + +namespace Org.BouncyCastle.Tls +{ + public class SrpTlsClient + : AbstractTlsClient + { + private static readonly int[] DefaultCipherSuites = new int[] + { + CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA + }; + + protected readonly TlsSrpIdentity m_srpIdentity; + + public SrpTlsClient(TlsCrypto crypto, byte[] identity, byte[] password) + : this(crypto, new BasicTlsSrpIdentity(identity, password)) + { + } + + public SrpTlsClient(TlsCrypto crypto, TlsSrpIdentity srpIdentity) + : base(crypto) + { + this.m_srpIdentity = srpIdentity; + } + + protected override int[] GetSupportedCipherSuites() + { + return TlsUtilities.GetSupportedCipherSuites(Crypto, DefaultCipherSuites); + } + + protected override ProtocolVersion[] GetSupportedVersions() + { + return ProtocolVersion.TLSv12.DownTo(ProtocolVersion.TLSv10); + } + + protected virtual bool RequireSrpServerExtension + { + // No explicit guidance in RFC 5054; by default an (empty) extension from server is optional + get { return false; } + } + + /// + public override IDictionary GetClientExtensions() + { + IDictionary clientExtensions = TlsExtensionsUtilities.EnsureExtensionsInitialised( + base.GetClientExtensions()); + TlsSrpUtilities.AddSrpExtension(clientExtensions, m_srpIdentity.GetSrpIdentity()); + return clientExtensions; + } + + /// + public override void ProcessServerExtensions(IDictionary serverExtensions) + { + if (!TlsUtilities.HasExpectedEmptyExtensionData(serverExtensions, ExtensionType.srp, + AlertDescription.illegal_parameter)) + { + if (RequireSrpServerExtension) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + base.ProcessServerExtensions(serverExtensions); + } + + public override TlsSrpIdentity GetSrpIdentity() + { + return m_srpIdentity; + } + + /// + public override TlsAuthentication GetAuthentication() + { + /* + * Note: This method is not called unless a server certificate is sent, which may be the + * case e.g. for SRP_DSS or SRP_RSA key exchange. + */ + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SrpTlsClient.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SrpTlsClient.cs.meta new file mode 100644 index 0000000..861a42c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SrpTlsClient.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 10d4de25ed639b049a9b367469db628f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SrpTlsServer.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SrpTlsServer.cs new file mode 100644 index 0000000..58f89ee --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SrpTlsServer.cs @@ -0,0 +1,106 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Tls.Crypto; + +namespace Org.BouncyCastle.Tls +{ + public class SrpTlsServer + : AbstractTlsServer + { + private static readonly int[] DefaultCipherSuites = new int[] + { + CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA, + CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA, + CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA, + CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA, + CipherSuite.TLS_SRP_SHA_WITH_AES_256_CBC_SHA, + CipherSuite.TLS_SRP_SHA_WITH_AES_128_CBC_SHA + }; + + protected readonly TlsSrpIdentityManager m_srpIdentityManager; + + protected byte[] m_srpIdentity = null; + protected TlsSrpLoginParameters m_srpLoginParameters = null; + + public SrpTlsServer(TlsCrypto crypto, TlsSrpIdentityManager srpIdentityManager) + : base(crypto) + { + this.m_srpIdentityManager = srpIdentityManager; + } + + /// + protected virtual TlsCredentialedSigner GetDsaSignerCredentials() + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + /// + protected virtual TlsCredentialedSigner GetRsaSignerCredentials() + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + protected override ProtocolVersion[] GetSupportedVersions() + { + return ProtocolVersion.TLSv12.DownTo(ProtocolVersion.TLSv10); + } + + protected override int[] GetSupportedCipherSuites() + { + return TlsUtilities.GetSupportedCipherSuites(Crypto, DefaultCipherSuites); + } + + public override void ProcessClientExtensions(IDictionary clientExtensions) + { + base.ProcessClientExtensions(clientExtensions); + + this.m_srpIdentity = TlsSrpUtilities.GetSrpExtension(clientExtensions); + } + + public override int GetSelectedCipherSuite() + { + int cipherSuite = base.GetSelectedCipherSuite(); + + if (TlsSrpUtilities.IsSrpCipherSuite(cipherSuite)) + { + if (m_srpIdentity != null) + { + this.m_srpLoginParameters = m_srpIdentityManager.GetLoginParameters(m_srpIdentity); + } + + if (m_srpLoginParameters == null) + throw new TlsFatalAlert(AlertDescription.unknown_psk_identity); + } + + return cipherSuite; + } + + public override TlsCredentials GetCredentials() + { + int keyExchangeAlgorithm = m_context.SecurityParameters.KeyExchangeAlgorithm; + + switch (keyExchangeAlgorithm) + { + case KeyExchangeAlgorithm.SRP: + return null; + + case KeyExchangeAlgorithm.SRP_DSS: + return GetDsaSignerCredentials(); + + case KeyExchangeAlgorithm.SRP_RSA: + return GetRsaSignerCredentials(); + + default: + // Note: internal error here; selected a key exchange we don't implement! + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + public override TlsSrpLoginParameters GetSrpLoginParameters() + { + return m_srpLoginParameters; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SrpTlsServer.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SrpTlsServer.cs.meta new file mode 100644 index 0000000..3931890 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SrpTlsServer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 046cd0d2775f9734f98dbc33c4eebbdc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SrtpProtectionProfile.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SrtpProtectionProfile.cs new file mode 100644 index 0000000..e81988e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SrtpProtectionProfile.cs @@ -0,0 +1,21 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + public abstract class SrtpProtectionProfile + { + /* + * RFC 5764 4.1.2. + */ + public const int SRTP_AES128_CM_HMAC_SHA1_80 = 0x0001; + public const int SRTP_AES128_CM_HMAC_SHA1_32 = 0x0002; + public const int SRTP_NULL_HMAC_SHA1_80 = 0x0005; + public const int SRTP_NULL_HMAC_SHA1_32 = 0x0006; + + /* + * RFC 7714 14.2. + */ + public const int SRTP_AEAD_AES_128_GCM = 0x0007; + public const int SRTP_AEAD_AES_256_GCM = 0x0008; + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SrtpProtectionProfile.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SrtpProtectionProfile.cs.meta new file mode 100644 index 0000000..4f1967f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SrtpProtectionProfile.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fa263d5b4096c454892d030ff993ebff +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/Ssl3Utilities.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/Ssl3Utilities.cs new file mode 100644 index 0000000..594bdef --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/Ssl3Utilities.cs @@ -0,0 +1,69 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Tls.Crypto; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Tls +{ + internal abstract class Ssl3Utilities + { + private static readonly byte[] SSL_CLIENT = {0x43, 0x4C, 0x4E, 0x54}; + private static readonly byte[] SSL_SERVER = {0x53, 0x52, 0x56, 0x52}; + + private const byte IPAD_BYTE = (byte)0x36; + private const byte OPAD_BYTE = (byte)0x5C; + + private static readonly byte[] IPAD = GenPad(IPAD_BYTE, 48); + private static readonly byte[] OPAD = GenPad(OPAD_BYTE, 48); + + internal static byte[] CalculateVerifyData(TlsHandshakeHash handshakeHash, bool isServer) + { + TlsHash prf = handshakeHash.ForkPrfHash(); + byte[] sslSender = isServer ? SSL_SERVER : SSL_CLIENT; + prf.Update(sslSender, 0, sslSender.Length); + return prf.CalculateHash(); + } + + internal static void CompleteCombinedHash(TlsContext context, TlsHash md5, TlsHash sha1) + { + TlsSecret masterSecret = context.SecurityParameters.MasterSecret; + byte[] master_secret = context.Crypto.AdoptSecret(masterSecret).Extract(); + + CompleteHash(master_secret, md5, 48); + CompleteHash(master_secret, sha1, 40); + } + + private static void CompleteHash(byte[] master_secret, TlsHash hash, int padLength) + { + hash.Update(master_secret, 0, master_secret.Length); + hash.Update(IPAD, 0, padLength); + + byte[] tmp = hash.CalculateHash(); + + hash.Update(master_secret, 0, master_secret.Length); + hash.Update(OPAD, 0, padLength); + hash.Update(tmp, 0, tmp.Length); + } + + private static byte[] GenPad(byte b, int count) + { + byte[] padding = new byte[count]; + Arrays.Fill(padding, b); + return padding; + } + + /// + internal static byte[] ReadEncryptedPms(Stream input) + { + return Streams.ReadAll(input); + } + + /// + internal static void WriteEncryptedPms(byte[] encryptedPms, Stream output) + { + output.Write(encryptedPms, 0, encryptedPms.Length); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/Ssl3Utilities.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/Ssl3Utilities.cs.meta new file mode 100644 index 0000000..2e34159 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/Ssl3Utilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8e06430af84344644a4a4abacdfbc494 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SupplementalDataEntry.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SupplementalDataEntry.cs new file mode 100644 index 0000000..baf4289 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SupplementalDataEntry.cs @@ -0,0 +1,26 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + public sealed class SupplementalDataEntry + { + private readonly int m_dataType; + private readonly byte[] m_data; + + public SupplementalDataEntry(int dataType, byte[] data) + { + this.m_dataType = dataType; + this.m_data = data; + } + + public int DataType + { + get { return m_dataType; } + } + + public byte[] Data + { + get { return m_data; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SupplementalDataEntry.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SupplementalDataEntry.cs.meta new file mode 100644 index 0000000..58d1d85 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SupplementalDataEntry.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5df1d9ac6eb5920468e035d153fcc533 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SupplementalDataType.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SupplementalDataType.cs new file mode 100644 index 0000000..d1eebfd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SupplementalDataType.cs @@ -0,0 +1,13 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + /// RFC 4680 + public abstract class SupplementalDataType + { + /* + * RFC 4681 + */ + public const int user_mapping_data = 0; + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SupplementalDataType.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SupplementalDataType.cs.meta new file mode 100644 index 0000000..7c9e810 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/SupplementalDataType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9268de98fd347e44780663663a82d116 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/Timeout.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/Timeout.cs new file mode 100644 index 0000000..e47fc5d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/Timeout.cs @@ -0,0 +1,119 @@ +using System; + +using Org.BouncyCastle.Utilities.Date; + +namespace Org.BouncyCastle.Tls +{ + internal class Timeout + { + private long durationMillis; + private long startMillis; + + internal Timeout(long durationMillis) + : this(durationMillis, DateTimeUtilities.CurrentUnixMs()) + { + } + + internal Timeout(long durationMillis, long currentTimeMillis) + { + this.durationMillis = System.Math.Max(0, durationMillis); + this.startMillis = System.Math.Max(0, currentTimeMillis); + } + + //internal long RemainingMillis() + //{ + // return RemainingMillis(DateTimeUtilities.CurrentUnixMs()); + //} + + internal long RemainingMillis(long currentTimeMillis) + { + lock (this) + { + // If clock jumped backwards, reset start time + if (startMillis > currentTimeMillis) + { + startMillis = currentTimeMillis; + return durationMillis; + } + + long elapsed = currentTimeMillis - startMillis; + long remaining = durationMillis - elapsed; + + // Once timeout reached, lock it in + if (remaining <= 0) + return durationMillis = 0L; + + return remaining; + } + } + + //internal static int ConstrainWaitMillis(int waitMillis, Timeout timeout) + //{ + // return constrainWaitMillis(waitMillis, timeout, DateTimeUtilities.CurrentUnixMs()); + //} + + internal static int ConstrainWaitMillis(int waitMillis, Timeout timeout, long currentTimeMillis) + { + if (waitMillis < 0) + return -1; + + int timeoutMillis = GetWaitMillis(timeout, currentTimeMillis); + if (timeoutMillis < 0) + return -1; + + if (waitMillis == 0) + return timeoutMillis; + + if (timeoutMillis == 0) + return waitMillis; + + return System.Math.Min(waitMillis, timeoutMillis); + } + + internal static Timeout ForWaitMillis(int waitMillis) + { + return ForWaitMillis(waitMillis, DateTimeUtilities.CurrentUnixMs()); + } + + internal static Timeout ForWaitMillis(int waitMillis, long currentTimeMillis) + { + if (waitMillis < 0) + throw new ArgumentException("cannot be negative", "waitMillis"); + + if (waitMillis > 0) + return new Timeout(waitMillis, currentTimeMillis); + + return null; + } + + //internal static int GetWaitMillis(Timeout timeout) + //{ + // return GetWaitMillis(timeout, DateTimeUtilities.CurrentUnixMs()); + //} + + internal static int GetWaitMillis(Timeout timeout, long currentTimeMillis) + { + if (null == timeout) + return 0; + + long remainingMillis = timeout.RemainingMillis(currentTimeMillis); + if (remainingMillis < 1L) + return -1; + + if (remainingMillis > int.MaxValue) + return int.MaxValue; + + return (int)remainingMillis; + } + + internal static bool HasExpired(Timeout timeout) + { + return HasExpired(timeout, DateTimeUtilities.CurrentUnixMs()); + } + + internal static bool HasExpired(Timeout timeout, long currentTimeMillis) + { + return null != timeout && timeout.RemainingMillis(currentTimeMillis) < 1L; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/Timeout.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/Timeout.cs.meta new file mode 100644 index 0000000..489c2eb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/Timeout.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 39a80d17805147c439cf8f03c61a412b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsAuthentication.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsAuthentication.cs new file mode 100644 index 0000000..32228ed --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsAuthentication.cs @@ -0,0 +1,29 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Tls +{ + /// Base interface to provide TLS authentication credentials. + public interface TlsAuthentication + { + /// Called by the protocol handler to report the server certificate. + /// + /// Note: this method is responsible for certificate verification and validation. + /// + /// the server certificate received. + /// + void NotifyServerCertificate(TlsServerCertificate serverCertificate); + + /// Return client credentials in response to server's certificate request. + /// + /// The returned value may be null, or else it MUST implement exactly one of + /// , , or + /// , depending on the key exchange that was negotiated and the details of + /// the . + /// + /// details of the certificate request. + /// a object or null for no client authentication. + /// + TlsCredentials GetClientCredentials(CertificateRequest certificateRequest); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsAuthentication.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsAuthentication.cs.meta new file mode 100644 index 0000000..77f14a8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsAuthentication.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a99b3775a27a6ed48ab8024b33aa168f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsClient.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsClient.cs new file mode 100644 index 0000000..66bb3bc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsClient.cs @@ -0,0 +1,110 @@ +using System; +using System.Collections; +using System.IO; + +namespace Org.BouncyCastle.Tls +{ + public interface TlsClient + : TlsPeer + { + void Init(TlsClientContext context); + + /// Return the session this client wants to resume, if any. + /// + /// Note that the peer's certificate chain for the session (if any) may need to be periodically revalidated. + /// + /// A representing the resumable session to be used for this connection, or + /// null to use a new session. + /// + TlsSession GetSessionToResume(); + + /// Return the external PSKs to offer in the ClientHello. + /// This will only be called when TLS 1.3 or higher is amongst the offered protocol versions. + /// an of instances, or null if none should be + /// offered. + IList GetExternalPsks(); + + bool IsFallback(); + + /// (Int32 -> byte[]) + /// + IDictionary GetClientExtensions(); + + /// If this client is offering TLS 1.3 or higher, this method may be called to determine for which + /// groups a key share should be included in the initial ClientHello. + /// + /// Groups that were not included in the supported_groups extension (by will + /// be ignored. The protocol will then add a suitable key_share extension to the ClientHello extensions. + /// + /// an of named group values, possibly empty or null. + /// + IList GetEarlyKeyShareGroups(); + + /// + void NotifyServerVersion(ProtocolVersion selectedVersion); + + /// Notifies the client of the session that will be offered in ClientHello for resumption, if any. + /// + /// + /// This will be either the session returned from {@link #getSessionToResume()} or null if that session was + /// unusable. NOTE: the actual negotiated session_id is notified by . + /// + /// The representing the resumable session to be offered for + /// this connection, or null if there is none. + /// + void NotifySessionToResume(TlsSession session); + + /// Notifies the client of the session_id sent in the ServerHello. + /// + /// + void NotifySessionID(byte[] sessionID); + + void NotifySelectedCipherSuite(int selectedCipherSuite); + + /// + void NotifySelectedPsk(TlsPsk selectedPsk); + + /// The protocol implementation validates that any server extensions received correspond to client + /// extensions sent. + /// + /// If further processing of the server extensions is needed, it can be done in this callback. NOTE: This is + /// not called for session resumption handshakes. + /// + /// (Int32 -> byte[]) + /// + void ProcessServerExtensions(IDictionary serverExtensions); + + /// (SupplementalDataEntry) + /// + void ProcessServerSupplementalData(IList serverSupplementalData); + + /// + TlsPskIdentity GetPskIdentity(); + + /// + TlsSrpIdentity GetSrpIdentity(); + + /// + TlsDHGroupVerifier GetDHGroupVerifier(); + + /// + TlsSrpConfigVerifier GetSrpConfigVerifier(); + + /// + TlsAuthentication GetAuthentication(); + + /// (SupplementalDataEntry) + /// + IList GetClientSupplementalData(); + + /// RFC 5077 3.3. NewSessionTicket Handshake Message + /// + /// This method will be called (only) when a NewSessionTicket handshake message is received. The ticket is + /// opaque to the client and clients MUST NOT examine the ticket under the assumption that it complies with e.g. + /// RFC 5077 4. "Recommended Ticket Construction". + /// + /// The ticket. + /// + void NotifyNewSessionTicket(NewSessionTicket newSessionTicket); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsClient.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsClient.cs.meta new file mode 100644 index 0000000..474cb46 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsClient.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6f867a3cdf232244ebaca268f9077d7c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsClientContext.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsClientContext.cs new file mode 100644 index 0000000..f1ed06e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsClientContext.cs @@ -0,0 +1,10 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + /// Marker interface to distinguish a TLS client context. + public interface TlsClientContext + : TlsContext + { + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsClientContext.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsClientContext.cs.meta new file mode 100644 index 0000000..22a8a32 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsClientContext.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 248059e387849d745a25bc7a1ec3e414 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsClientContextImpl.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsClientContextImpl.cs new file mode 100644 index 0000000..3ce4ab8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsClientContextImpl.cs @@ -0,0 +1,20 @@ +using System; + +using Org.BouncyCastle.Tls.Crypto; + +namespace Org.BouncyCastle.Tls +{ + internal class TlsClientContextImpl + : AbstractTlsContext, TlsClientContext + { + internal TlsClientContextImpl(TlsCrypto crypto) + : base(crypto, ConnectionEnd.client) + { + } + + public override bool IsServer + { + get { return false; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsClientContextImpl.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsClientContextImpl.cs.meta new file mode 100644 index 0000000..74a1019 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsClientContextImpl.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: da31d026f7cd8c4498b0f2a555ebdc87 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsClientProtocol.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsClientProtocol.cs new file mode 100644 index 0000000..c132b25 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsClientProtocol.cs @@ -0,0 +1,1796 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Tls.Crypto; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls +{ + public class TlsClientProtocol + : TlsProtocol + { + protected TlsClient m_tlsClient = null; + internal TlsClientContextImpl m_tlsClientContext = null; + + protected IDictionary m_clientAgreements = null; + internal OfferedPsks.BindersConfig m_clientBinders = null; + protected ClientHello m_clientHello = null; + protected TlsKeyExchange m_keyExchange = null; + protected TlsAuthentication m_authentication = null; + + protected CertificateStatus m_certificateStatus = null; + protected CertificateRequest m_certificateRequest = null; + + /// Constructor for non-blocking mode. + /// + /// When data is received, use to provide the received ciphertext, + /// then use to read the corresponding cleartext.

    + /// Similarly, when data needs to be sent, use + /// to provide the cleartext, then use to get the + /// corresponding ciphertext. + ///
    + public TlsClientProtocol() + : base() + { + } + + /// Constructor for blocking mode. + /// The of data to/from the server. + public TlsClientProtocol(Stream stream) + : base(stream) + { + } + + /// Constructor for blocking mode. + /// The of data from the server. + /// The of data to the server. + public TlsClientProtocol(Stream input, Stream output) + : base(input, output) + { + } + + /// Initiates a TLS handshake in the role of client. + /// + /// In blocking mode, this will not return until the handshake is complete. In non-blocking mode, use + /// to receive a callback when the handshake is complete. + /// + /// The to use for the handshake. + /// If in blocking mode and handshake was not successful. + public virtual void Connect(TlsClient tlsClient) + { + if (tlsClient == null) + throw new ArgumentNullException("tlsClient"); + if (m_tlsClient != null) + throw new InvalidOperationException("'Connect' can only be called once"); + + this.m_tlsClient = tlsClient; + this.m_tlsClientContext = new TlsClientContextImpl(tlsClient.Crypto); + + tlsClient.Init(m_tlsClientContext); + tlsClient.NotifyCloseHandle(this); + + BeginHandshake(); + + if (m_blocking) + { + BlockForHandshake(); + } + } + + protected override void BeginHandshake() + { + base.BeginHandshake(); + + SendClientHello(); + this.m_connectionState = CS_CLIENT_HELLO; + } + + protected override void CleanupHandshake() + { + base.CleanupHandshake(); + + this.m_clientAgreements = null; + this.m_clientBinders = null; + this.m_clientHello = null; + this.m_keyExchange = null; + this.m_authentication = null; + + this.m_certificateStatus = null; + this.m_certificateRequest = null; + } + + protected override TlsContext Context + { + get { return m_tlsClientContext; } + } + + internal override AbstractTlsContext ContextAdmin + { + get { return m_tlsClientContext; } + } + + protected override TlsPeer Peer + { + get { return m_tlsClient; } + } + + /// + protected virtual void Handle13HandshakeMessage(short type, HandshakeMessageInput buf) + { + if (!IsTlsV13ConnectionState() || m_resumedSession) + throw new TlsFatalAlert(AlertDescription.internal_error); + + switch (type) + { + case HandshakeType.certificate: + { + switch (m_connectionState) + { + case CS_SERVER_ENCRYPTED_EXTENSIONS: + case CS_SERVER_CERTIFICATE_REQUEST: + { + if (m_connectionState != CS_SERVER_CERTIFICATE_REQUEST) + { + Skip13CertificateRequest(); + } + + Receive13ServerCertificate(buf); + this.m_connectionState = CS_SERVER_CERTIFICATE; + break; + } + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + break; + } + case HandshakeType.certificate_request: + { + switch (m_connectionState) + { + case CS_END: + { + // TODO[tls13] Permit post-handshake authentication if we sent post_handshake_auth extension + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + case CS_SERVER_ENCRYPTED_EXTENSIONS: + { + Receive13CertificateRequest(buf, false); + this.m_connectionState = CS_SERVER_CERTIFICATE_REQUEST; + break; + } + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + break; + } + case HandshakeType.certificate_verify: + { + switch (m_connectionState) + { + case CS_SERVER_CERTIFICATE: + { + Receive13ServerCertificateVerify(buf); + buf.UpdateHash(m_handshakeHash); + this.m_connectionState = CS_SERVER_CERTIFICATE_VERIFY; + break; + } + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + break; + } + case HandshakeType.encrypted_extensions: + { + switch (m_connectionState) + { + case CS_SERVER_HELLO: + { + Receive13EncryptedExtensions(buf); + this.m_connectionState = CS_SERVER_ENCRYPTED_EXTENSIONS; + break; + } + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + break; + } + case HandshakeType.finished: + { + switch (m_connectionState) + { + case CS_SERVER_ENCRYPTED_EXTENSIONS: + case CS_SERVER_CERTIFICATE_REQUEST: + case CS_SERVER_CERTIFICATE_VERIFY: + { + if (m_connectionState == CS_SERVER_ENCRYPTED_EXTENSIONS) + { + Skip13CertificateRequest(); + } + if (m_connectionState != CS_SERVER_CERTIFICATE_VERIFY) + { + Skip13ServerCertificate(); + } + + Receive13ServerFinished(buf); + buf.UpdateHash(m_handshakeHash); + this.m_connectionState = CS_SERVER_FINISHED; + + byte[] serverFinishedTranscriptHash = TlsUtilities.GetCurrentPrfHash(m_handshakeHash); + + // See RFC 8446 D.4. + m_recordStream.SetIgnoreChangeCipherSpec(false); + + /* + * TODO[tls13] After receiving the server's Finished message, if the server has accepted early + * data, an EndOfEarlyData message will be sent to indicate the key change. This message will + * be encrypted with the 0-RTT traffic keys. + */ + + if (null != m_certificateRequest) + { + TlsCredentialedSigner clientCredentials = TlsUtilities.Establish13ClientCredentials( + m_authentication, m_certificateRequest); + + Certificate clientCertificate = null; + if (null != clientCredentials) + { + clientCertificate = clientCredentials.Certificate; + } + + if (null == clientCertificate) + { + // In this calling context, certificate_request_context is length 0 + clientCertificate = Certificate.EmptyChainTls13; + } + + Send13CertificateMessage(clientCertificate); + this.m_connectionState = CS_CLIENT_CERTIFICATE; + + if (null != clientCredentials) + { + DigitallySigned certificateVerify = TlsUtilities.Generate13CertificateVerify( + m_tlsClientContext, clientCredentials, m_handshakeHash); + Send13CertificateVerifyMessage(certificateVerify); + this.m_connectionState = CS_CLIENT_CERTIFICATE_VERIFY; + } + } + + Send13FinishedMessage(); + this.m_connectionState = CS_CLIENT_FINISHED; + + TlsUtilities.Establish13PhaseApplication(m_tlsClientContext, serverFinishedTranscriptHash, + m_recordStream); + + m_recordStream.EnablePendingCipherWrite(); + m_recordStream.EnablePendingCipherRead(false); + + CompleteHandshake(); + break; + } + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + break; + } + case HandshakeType.key_update: + { + Receive13KeyUpdate(buf); + break; + } + case HandshakeType.new_session_ticket: + { + Receive13NewSessionTicket(buf); + break; + } + case HandshakeType.server_hello: + { + switch (m_connectionState) + { + case CS_CLIENT_HELLO: + { + // NOTE: Legacy handler should be dispatching initial ServerHello/HelloRetryRequest. + throw new TlsFatalAlert(AlertDescription.internal_error); + } + case CS_CLIENT_HELLO_RETRY: + { + ServerHello serverHello = ReceiveServerHelloMessage(buf); + if (serverHello.IsHelloRetryRequest()) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + + Process13ServerHello(serverHello, true); + buf.UpdateHash(m_handshakeHash); + this.m_connectionState = CS_SERVER_HELLO; + + Process13ServerHelloCoda(serverHello, true); + break; + } + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + break; + } + + case HandshakeType.certificate_status: + case HandshakeType.certificate_url: + case HandshakeType.client_hello: + case HandshakeType.client_key_exchange: + case HandshakeType.end_of_early_data: + case HandshakeType.hello_request: + case HandshakeType.hello_verify_request: + case HandshakeType.message_hash: + case HandshakeType.server_hello_done: + case HandshakeType.server_key_exchange: + case HandshakeType.supplemental_data: + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + } + + protected override void HandleHandshakeMessage(short type, HandshakeMessageInput buf) + { + SecurityParameters securityParameters = m_tlsClientContext.SecurityParameters; + + if (m_connectionState > CS_CLIENT_HELLO + && TlsUtilities.IsTlsV13(securityParameters.NegotiatedVersion)) + { + Handle13HandshakeMessage(type, buf); + return; + } + + if (!IsLegacyConnectionState()) + throw new TlsFatalAlert(AlertDescription.internal_error); + + if (m_resumedSession) + { + if (type != HandshakeType.finished || m_connectionState != CS_SERVER_HELLO) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + + ProcessFinishedMessage(buf); + buf.UpdateHash(m_handshakeHash); + this.m_connectionState = CS_SERVER_FINISHED; + + SendChangeCipherSpec(); + SendFinishedMessage(); + this.m_connectionState = CS_CLIENT_FINISHED; + + CompleteHandshake(); + return; + } + + switch (type) + { + case HandshakeType.certificate: + { + switch (m_connectionState) + { + case CS_SERVER_HELLO: + case CS_SERVER_SUPPLEMENTAL_DATA: + { + if (m_connectionState != CS_SERVER_SUPPLEMENTAL_DATA) + { + HandleSupplementalData(null); + } + + /* + * NOTE: Certificate processing (including authentication) is delayed to allow for a + * possible CertificateStatus message. + */ + this.m_authentication = TlsUtilities.ReceiveServerCertificate(m_tlsClientContext, m_tlsClient, + buf); + break; + } + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + this.m_connectionState = CS_SERVER_CERTIFICATE; + break; + } + case HandshakeType.certificate_status: + { + switch (m_connectionState) + { + case CS_SERVER_CERTIFICATE: + { + if (securityParameters.StatusRequestVersion < 1) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + + this.m_certificateStatus = CertificateStatus.Parse(m_tlsClientContext, buf); + + AssertEmpty(buf); + + this.m_connectionState = CS_SERVER_CERTIFICATE_STATUS; + break; + } + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + break; + } + case HandshakeType.finished: + { + switch (m_connectionState) + { + case CS_CLIENT_FINISHED: + case CS_SERVER_SESSION_TICKET: + { + if (m_connectionState != CS_SERVER_SESSION_TICKET) + { + /* + * RFC 5077 3.3. This message MUST be sent if the server included a + * SessionTicket extension in the ServerHello. + */ + if (m_expectSessionTicket) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + ProcessFinishedMessage(buf); + this.m_connectionState = CS_SERVER_FINISHED; + + CompleteHandshake(); + break; + } + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + break; + } + case HandshakeType.server_hello: + { + switch (m_connectionState) + { + case CS_CLIENT_HELLO: + { + ServerHello serverHello = ReceiveServerHelloMessage(buf); + + // TODO[tls13] Only treat as HRR if it's TLS 1.3?? + if (serverHello.IsHelloRetryRequest()) + { + Process13HelloRetryRequest(serverHello); + m_handshakeHash.NotifyPrfDetermined(); + TlsUtilities.AdjustTranscriptForRetry(m_handshakeHash); + buf.UpdateHash(m_handshakeHash); + this.m_connectionState = CS_SERVER_HELLO_RETRY_REQUEST; + + Send13ClientHelloRetry(); + m_handshakeHash.SealHashAlgorithms(); + this.m_connectionState = CS_CLIENT_HELLO_RETRY; + } + else + { + ProcessServerHello(serverHello); + m_handshakeHash.NotifyPrfDetermined(); + buf.UpdateHash(m_handshakeHash); + this.m_connectionState = CS_SERVER_HELLO; + + if (TlsUtilities.IsTlsV13(securityParameters.NegotiatedVersion)) + { + m_handshakeHash.SealHashAlgorithms(); + Process13ServerHelloCoda(serverHello, false); + } + } + + break; + } + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + break; + } + case HandshakeType.supplemental_data: + { + switch (m_connectionState) + { + case CS_SERVER_HELLO: + { + HandleSupplementalData(ReadSupplementalDataMessage(buf)); + break; + } + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + break; + } + case HandshakeType.server_hello_done: + { + switch (m_connectionState) + { + case CS_SERVER_HELLO: + case CS_SERVER_SUPPLEMENTAL_DATA: + case CS_SERVER_CERTIFICATE: + case CS_SERVER_CERTIFICATE_STATUS: + case CS_SERVER_KEY_EXCHANGE: + case CS_SERVER_CERTIFICATE_REQUEST: + { + if (m_connectionState == CS_SERVER_HELLO) + { + HandleSupplementalData(null); + } + if (m_connectionState == CS_SERVER_HELLO || + m_connectionState == CS_SERVER_SUPPLEMENTAL_DATA) + { + this.m_authentication = null; + } + if (m_connectionState != CS_SERVER_KEY_EXCHANGE && + m_connectionState != CS_SERVER_CERTIFICATE_REQUEST) + { + HandleServerCertificate(); + + // There was no server key exchange message; check it's OK + m_keyExchange.SkipServerKeyExchange(); + } + + AssertEmpty(buf); + + this.m_connectionState = CS_SERVER_HELLO_DONE; + + IList clientSupplementalData = m_tlsClient.GetClientSupplementalData(); + if (clientSupplementalData != null) + { + SendSupplementalDataMessage(clientSupplementalData); + this.m_connectionState = CS_CLIENT_SUPPLEMENTAL_DATA; + } + + TlsCredentialedSigner credentialedSigner = null; + TlsStreamSigner streamSigner = null; + + if (m_certificateRequest == null) + { + m_keyExchange.SkipClientCredentials(); + } + else + { + Certificate clientCertificate = null; + + TlsCredentials clientCredentials = TlsUtilities.EstablishClientCredentials(m_authentication, + m_certificateRequest); + if (null == clientCredentials) + { + m_keyExchange.SkipClientCredentials(); + + /* + * RFC 5246 If no suitable certificate is available, the client MUST send a + * certificate message containing no certificates. + * + * NOTE: In previous RFCs, this was SHOULD instead of MUST. + */ + } + else + { + m_keyExchange.ProcessClientCredentials(clientCredentials); + + clientCertificate = clientCredentials.Certificate; + + if (clientCredentials is TlsCredentialedSigner) + { + credentialedSigner = (TlsCredentialedSigner)clientCredentials; + streamSigner = credentialedSigner.GetStreamSigner(); + } + } + + SendCertificateMessage(clientCertificate, null); + this.m_connectionState = CS_CLIENT_CERTIFICATE; + } + + bool forceBuffering = streamSigner != null; + TlsUtilities.SealHandshakeHash(m_tlsClientContext, m_handshakeHash, forceBuffering); + + /* + * Send the client key exchange message, depending on the key exchange we are using + * in our CipherSuite. + */ + SendClientKeyExchange(); + this.m_connectionState = CS_CLIENT_KEY_EXCHANGE; + + bool isSsl = TlsUtilities.IsSsl(m_tlsClientContext); + if (isSsl) + { + // NOTE: For SSLv3 (only), master_secret needed to calculate session hash + EstablishMasterSecret(m_tlsClientContext, m_keyExchange); + } + + securityParameters.m_sessionHash = TlsUtilities.GetCurrentPrfHash(m_handshakeHash); + + if (!isSsl) + { + // NOTE: For (D)TLS, session hash potentially needed for extended_master_secret + EstablishMasterSecret(m_tlsClientContext, m_keyExchange); + } + + m_recordStream.SetPendingCipher(TlsUtilities.InitCipher(m_tlsClientContext)); + + if (credentialedSigner != null) + { + DigitallySigned certificateVerify = TlsUtilities.GenerateCertificateVerifyClient( + m_tlsClientContext, credentialedSigner, streamSigner, m_handshakeHash); + SendCertificateVerifyMessage(certificateVerify); + this.m_connectionState = CS_CLIENT_CERTIFICATE_VERIFY; + } + + this.m_handshakeHash = m_handshakeHash.StopTracking(); + + SendChangeCipherSpec(); + SendFinishedMessage(); + break; + } + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + this.m_connectionState = CS_CLIENT_FINISHED; + break; + } + case HandshakeType.server_key_exchange: + { + switch (m_connectionState) + { + case CS_SERVER_HELLO: + case CS_SERVER_SUPPLEMENTAL_DATA: + case CS_SERVER_CERTIFICATE: + case CS_SERVER_CERTIFICATE_STATUS: + { + if (m_connectionState == CS_SERVER_HELLO) + { + HandleSupplementalData(null); + } + if (m_connectionState != CS_SERVER_CERTIFICATE && + m_connectionState != CS_SERVER_CERTIFICATE_STATUS) + { + this.m_authentication = null; + } + + HandleServerCertificate(); + + m_keyExchange.ProcessServerKeyExchange(buf); + + AssertEmpty(buf); + break; + } + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + this.m_connectionState = CS_SERVER_KEY_EXCHANGE; + break; + } + case HandshakeType.certificate_request: + { + switch (m_connectionState) + { + case CS_SERVER_CERTIFICATE: + case CS_SERVER_CERTIFICATE_STATUS: + case CS_SERVER_KEY_EXCHANGE: + { + if (m_connectionState != CS_SERVER_KEY_EXCHANGE) + { + HandleServerCertificate(); + + // There was no server key exchange message; check it's OK + m_keyExchange.SkipServerKeyExchange(); + } + + ReceiveCertificateRequest(buf); + + TlsUtilities.EstablishServerSigAlgs(securityParameters, m_certificateRequest); + + /* + * TODO Give the client a chance to immediately select the CertificateVerify hash + * algorithm here to avoid tracking the other hash algorithms unnecessarily? + */ + TlsUtilities.TrackHashAlgorithms(m_handshakeHash, securityParameters.ServerSigAlgs); + + break; + } + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + this.m_connectionState = CS_SERVER_CERTIFICATE_REQUEST; + break; + } + case HandshakeType.new_session_ticket: + { + switch (m_connectionState) + { + case CS_CLIENT_FINISHED: + { + if (!m_expectSessionTicket) + { + /* + * RFC 5077 3.3. This message MUST NOT be sent if the server did not include a + * SessionTicket extension in the ServerHello. + */ + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + /* + * RFC 5077 3.4. If the client receives a session ticket from the server, then it + * discards any Session ID that was sent in the ServerHello. + */ + securityParameters.m_sessionID = TlsUtilities.EmptyBytes; + InvalidateSession(); + this.m_tlsSession = TlsUtilities.ImportSession(securityParameters.SessionID, null); + + ReceiveNewSessionTicket(buf); + break; + } + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + this.m_connectionState = CS_SERVER_SESSION_TICKET; + break; + } + case HandshakeType.hello_request: + { + AssertEmpty(buf); + + /* + * RFC 2246 7.4.1.1 Hello request This message will be ignored by the client if the + * client is currently negotiating a session. This message may be ignored by the client + * if it does not wish to renegotiate a session, or the client may, if it wishes, + * respond with a no_renegotiation alert. + */ + if (IsApplicationDataReady) + { + RefuseRenegotiation(); + } + break; + } + + case HandshakeType.certificate_url: + case HandshakeType.certificate_verify: + case HandshakeType.client_hello: + case HandshakeType.client_key_exchange: + case HandshakeType.encrypted_extensions: + case HandshakeType.end_of_early_data: + case HandshakeType.hello_verify_request: + case HandshakeType.key_update: + case HandshakeType.message_hash: + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + } + + /// + protected virtual void HandleServerCertificate() + { + TlsUtilities.ProcessServerCertificate(m_tlsClientContext, m_certificateStatus, m_keyExchange, + m_authentication, m_clientExtensions, m_serverExtensions); + } + + /// + protected virtual void HandleSupplementalData(IList serverSupplementalData) + { + m_tlsClient.ProcessServerSupplementalData(serverSupplementalData); + this.m_connectionState = CS_SERVER_SUPPLEMENTAL_DATA; + + this.m_keyExchange = TlsUtilities.InitKeyExchangeClient(m_tlsClientContext, m_tlsClient); + } + + /// + protected virtual void Process13HelloRetryRequest(ServerHello helloRetryRequest) + { + ProtocolVersion legacy_record_version = ProtocolVersion.TLSv12; + m_recordStream.SetWriteVersion(legacy_record_version); + + SecurityParameters securityParameters = m_tlsClientContext.SecurityParameters; + + /* + * RFC 8446 4.1.4. Upon receipt of a HelloRetryRequest, the client MUST check the + * legacy_version, legacy_session_id_echo, cipher_suite, and legacy_compression_method as + * specified in Section 4.1.3 and then process the extensions, starting with determining the + * version using "supported_versions". + */ + ProtocolVersion legacy_version = helloRetryRequest.Version; + byte[] legacy_session_id_echo = helloRetryRequest.SessionID; + int cipherSuite = helloRetryRequest.CipherSuite; + // NOTE: legacy_compression_method checked during ServerHello parsing + + if (!ProtocolVersion.TLSv12.Equals(legacy_version) || + !Arrays.AreEqual(m_clientHello.SessionID, legacy_session_id_echo) || + !TlsUtilities.IsValidCipherSuiteSelection(m_clientHello.CipherSuites, cipherSuite)) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + IDictionary extensions = helloRetryRequest.Extensions; + if (null == extensions) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + TlsUtilities.CheckExtensionData13(extensions, HandshakeType.hello_retry_request, + AlertDescription.illegal_parameter); + + { + /* + * RFC 8446 4.2. Implementations MUST NOT send extension responses if the remote + * endpoint did not send the corresponding extension requests, with the exception of the + * "cookie" extension in the HelloRetryRequest. Upon receiving such an extension, an + * endpoint MUST abort the handshake with an "unsupported_extension" alert. + */ + foreach (int extType in extensions.Keys) + { + if (ExtensionType.cookie == extType) + continue; + + if (null == TlsUtilities.GetExtensionData(m_clientExtensions, extType)) + throw new TlsFatalAlert(AlertDescription.unsupported_extension); + } + } + + ProtocolVersion server_version = TlsExtensionsUtilities.GetSupportedVersionsExtensionServer(extensions); + if (null == server_version) + throw new TlsFatalAlert(AlertDescription.missing_extension); + + if (!ProtocolVersion.TLSv13.IsEqualOrEarlierVersionOf(server_version) || + !ProtocolVersion.Contains(m_tlsClientContext.ClientSupportedVersions, server_version) || + !TlsUtilities.IsValidVersionForCipherSuite(cipherSuite, server_version)) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + if (null != m_clientBinders) + { + if (!Arrays.Contains(m_clientBinders.m_pskKeyExchangeModes, PskKeyExchangeMode.psk_dhe_ke)) + { + this.m_clientBinders = null; + + m_tlsClient.NotifySelectedPsk(null); + } + } + + /* + * RFC 8446 4.2.8. Upon receipt of this [Key Share] extension in a HelloRetryRequest, the + * client MUST verify that (1) the selected_group field corresponds to a group which was + * provided in the "supported_groups" extension in the original ClientHello and (2) the + * selected_group field does not correspond to a group which was provided in the "key_share" + * extension in the original ClientHello. If either of these checks fails, then the client + * MUST abort the handshake with an "illegal_parameter" alert. + */ + int selected_group = TlsExtensionsUtilities.GetKeyShareHelloRetryRequest(extensions); + + if (!TlsUtilities.IsValidKeyShareSelection(server_version, securityParameters.ClientSupportedGroups, + m_clientAgreements, selected_group)) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + byte[] cookie = TlsExtensionsUtilities.GetCookieExtension(extensions); + + + + securityParameters.m_negotiatedVersion = server_version; + TlsUtilities.NegotiatedVersionTlsClient(m_tlsClientContext, m_tlsClient); + + this.m_resumedSession = false; + securityParameters.m_sessionID = TlsUtilities.EmptyBytes; + m_tlsClient.NotifySessionID(TlsUtilities.EmptyBytes); + + TlsUtilities.NegotiatedCipherSuite(securityParameters, cipherSuite); + m_tlsClient.NotifySelectedCipherSuite(cipherSuite); + + this.m_clientAgreements = null; + this.m_retryCookie = cookie; + this.m_retryGroup = selected_group; + } + + /// + protected virtual void Process13ServerHello(ServerHello serverHello, bool afterHelloRetryRequest) + { + SecurityParameters securityParameters = m_tlsClientContext.SecurityParameters; + + ProtocolVersion legacy_version = serverHello.Version; + byte[] legacy_session_id_echo = serverHello.SessionID; + int cipherSuite = serverHello.CipherSuite; + // NOTE: legacy_compression_method checked during ServerHello parsing + + if (!ProtocolVersion.TLSv12.Equals(legacy_version) || + !Arrays.AreEqual(m_clientHello.SessionID, legacy_session_id_echo)) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + IDictionary extensions = serverHello.Extensions; + if (null == extensions) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + TlsUtilities.CheckExtensionData13(extensions, HandshakeType.server_hello, + AlertDescription.illegal_parameter); + + if (afterHelloRetryRequest) + { + ProtocolVersion server_version = TlsExtensionsUtilities.GetSupportedVersionsExtensionServer(extensions); + if (null == server_version) + throw new TlsFatalAlert(AlertDescription.missing_extension); + + if (!securityParameters.NegotiatedVersion.Equals(server_version) || + securityParameters.CipherSuite != cipherSuite) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + } + else + { + if (!TlsUtilities.IsValidCipherSuiteSelection(m_clientHello.CipherSuites, cipherSuite) || + !TlsUtilities.IsValidVersionForCipherSuite(cipherSuite, securityParameters.NegotiatedVersion)) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + this.m_resumedSession = false; + securityParameters.m_sessionID = TlsUtilities.EmptyBytes; + m_tlsClient.NotifySessionID(TlsUtilities.EmptyBytes); + + TlsUtilities.NegotiatedCipherSuite(securityParameters, cipherSuite); + m_tlsClient.NotifySelectedCipherSuite(cipherSuite); + } + + this.m_clientHello = null; + + // NOTE: Apparently downgrade marker mechanism not used for TLS 1.3+? + securityParameters.m_serverRandom = serverHello.Random; + + securityParameters.m_secureRenegotiation = false; + + /* + * RFC 8446 Appendix D. Because TLS 1.3 always hashes in the transcript up to the server + * Finished, implementations which support both TLS 1.3 and earlier versions SHOULD indicate + * the use of the Extended Master Secret extension in their APIs whenever TLS 1.3 is used. + */ + securityParameters.m_extendedMasterSecret = true; + + /* + * TODO[tls13] RFC 8446 4.4.2.1. OCSP Status and SCT Extensions. + * + * OCSP information is carried in an extension for a CertificateEntry. + */ + securityParameters.m_statusRequestVersion = m_clientExtensions.Contains(ExtensionType.status_request) ? 1 : 0; + + TlsSecret pskEarlySecret = null; + { + int selected_identity = TlsExtensionsUtilities.GetPreSharedKeyServerHello(extensions); + TlsPsk selectedPsk = null; + + if (selected_identity >= 0) + { + if (null == m_clientBinders || selected_identity >= m_clientBinders.m_psks.Length) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + selectedPsk = m_clientBinders.m_psks[selected_identity]; + if (selectedPsk.PrfAlgorithm != securityParameters.PrfAlgorithm) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + pskEarlySecret = m_clientBinders.m_earlySecrets[selected_identity]; + + this.m_selectedPsk13 = true; + } + + m_tlsClient.NotifySelectedPsk(selectedPsk); + } + + TlsSecret sharedSecret = null; + { + KeyShareEntry keyShareEntry = TlsExtensionsUtilities.GetKeyShareServerHello(extensions); + if (null == keyShareEntry) + { + if (afterHelloRetryRequest + || null == pskEarlySecret + || !Arrays.Contains(m_clientBinders.m_pskKeyExchangeModes, PskKeyExchangeMode.psk_ke)) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + } + else + { + if (null != pskEarlySecret + && !Arrays.Contains(m_clientBinders.m_pskKeyExchangeModes, PskKeyExchangeMode.psk_dhe_ke)) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + TlsAgreement agreement = (TlsAgreement)m_clientAgreements[keyShareEntry.NamedGroup]; + if (null == agreement) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + agreement.ReceivePeerValue(keyShareEntry.KeyExchange); + sharedSecret = agreement.CalculateSecret(); + } + } + + this.m_clientAgreements = null; + this.m_clientBinders = null; + + TlsUtilities.Establish13PhaseSecrets(m_tlsClientContext, pskEarlySecret, sharedSecret); + + InvalidateSession(); + this.m_tlsSession = TlsUtilities.ImportSession(securityParameters.SessionID, null); + } + + /// + protected virtual void Process13ServerHelloCoda(ServerHello serverHello, bool afterHelloRetryRequest) + { + byte[] serverHelloTranscriptHash = TlsUtilities.GetCurrentPrfHash(m_handshakeHash); + + TlsUtilities.Establish13PhaseHandshake(m_tlsClientContext, serverHelloTranscriptHash, m_recordStream); + + // See RFC 8446 D.4. + if (!afterHelloRetryRequest) + { + m_recordStream.SetIgnoreChangeCipherSpec(true); + + /* + * TODO[tls13] If offering early_data, the record is placed immediately after the first + * ClientHello. + */ + /* + * TODO[tls13] Ideally wait until just after Server Finished received, but then we'd need to defer + * the enabling of the pending write cipher + */ + SendChangeCipherSpecMessage(); + } + + m_recordStream.EnablePendingCipherWrite(); + m_recordStream.EnablePendingCipherRead(false); + } + + /// + protected virtual void ProcessServerHello(ServerHello serverHello) + { + IDictionary serverHelloExtensions = serverHello.Extensions; + + ProtocolVersion legacy_version = serverHello.Version; + ProtocolVersion supported_version = TlsExtensionsUtilities.GetSupportedVersionsExtensionServer( + serverHelloExtensions); + + ProtocolVersion server_version; + if (null == supported_version) + { + server_version = legacy_version; + } + else + { + if (!ProtocolVersion.TLSv12.Equals(legacy_version) || + !ProtocolVersion.TLSv13.IsEqualOrEarlierVersionOf(supported_version)) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + server_version = supported_version; + } + + SecurityParameters securityParameters = m_tlsClientContext.SecurityParameters; + + // NOT renegotiating + { + if (!ProtocolVersion.Contains(m_tlsClientContext.ClientSupportedVersions, server_version)) + throw new TlsFatalAlert(AlertDescription.protocol_version); + + ProtocolVersion legacy_record_version = server_version.IsLaterVersionOf(ProtocolVersion.TLSv12) + ? ProtocolVersion.TLSv12 + : server_version; + + m_recordStream.SetWriteVersion(legacy_record_version); + securityParameters.m_negotiatedVersion = server_version; + } + + TlsUtilities.NegotiatedVersionTlsClient(m_tlsClientContext, m_tlsClient); + + if (ProtocolVersion.TLSv13.IsEqualOrEarlierVersionOf(server_version)) + { + Process13ServerHello(serverHello, false); + return; + } + + int[] offeredCipherSuites = m_clientHello.CipherSuites; + + this.m_clientHello = null; + this.m_retryCookie = null; + this.m_retryGroup = -1; + + securityParameters.m_serverRandom = serverHello.Random; + + if (!m_tlsClientContext.ClientVersion.Equals(server_version)) + { + TlsUtilities.CheckDowngradeMarker(server_version, securityParameters.ServerRandom); + } + + { + byte[] selectedSessionID = serverHello.SessionID; + securityParameters.m_sessionID = selectedSessionID; + m_tlsClient.NotifySessionID(selectedSessionID); + this.m_resumedSession = selectedSessionID.Length > 0 && m_tlsSession != null + && Arrays.AreEqual(selectedSessionID, m_tlsSession.SessionID); + } + + /* + * Find out which CipherSuite the server has chosen and check that it was one of the offered + * ones, and is a valid selection for the negotiated version. + */ + { + int cipherSuite = serverHello.CipherSuite; + + if (!TlsUtilities.IsValidCipherSuiteSelection(offeredCipherSuites, cipherSuite) || + !TlsUtilities.IsValidVersionForCipherSuite(cipherSuite, securityParameters.NegotiatedVersion)) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + TlsUtilities.NegotiatedCipherSuite(securityParameters, cipherSuite); + m_tlsClient.NotifySelectedCipherSuite(cipherSuite); + } + + /* + * RFC 3546 2.2 Note that the extended server hello message is only sent in response to an + * extended client hello message. + * + * However, see RFC 5746 exception below. We always include the SCSV, so an Extended Server + * Hello is always allowed. + */ + this.m_serverExtensions = serverHelloExtensions; + if (m_serverExtensions != null) + { + foreach (int extType in m_serverExtensions.Keys) + { + /* + * RFC 5746 3.6. Note that sending a "renegotiation_info" extension in response to a + * ClientHello containing only the SCSV is an explicit exception to the prohibition + * in RFC 5246, Section 7.4.1.4, on the server sending unsolicited extensions and is + * only allowed because the client is signaling its willingness to receive the + * extension via the TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV. + */ + if (ExtensionType.renegotiation_info == extType) + continue; + + /* + * RFC 5246 7.4.1.4 An extension type MUST NOT appear in the ServerHello unless the + * same extension type appeared in the corresponding ClientHello. If a client + * receives an extension type in ServerHello that it did not request in the + * associated ClientHello, it MUST abort the handshake with an unsupported_extension + * fatal alert. + */ + if (null == TlsUtilities.GetExtensionData(m_clientExtensions, extType)) + throw new TlsFatalAlert(AlertDescription.unsupported_extension); + + /* + * RFC 3546 2.3. If [...] the older session is resumed, then the server MUST ignore + * extensions appearing in the client hello, and send a server hello containing no + * extensions[.] + */ + if (m_resumedSession) + { + // TODO[compat-gnutls] GnuTLS test server sends server extensions e.g. ec_point_formats + // TODO[compat-openssl] OpenSSL test server sends server extensions e.g. ec_point_formats + // TODO[compat-polarssl] PolarSSL test server sends server extensions e.g. ec_point_formats + // throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + } + } + + byte[] renegExtData = TlsUtilities.GetExtensionData(m_serverExtensions, ExtensionType.renegotiation_info); + + // NOT renegotiating + { + /* + * RFC 5746 3.4. Client Behavior: Initial Handshake (both full and session-resumption) + */ + + /* + * When a ServerHello is received, the client MUST check if it includes the + * "renegotiation_info" extension: + */ + if (renegExtData == null) + { + /* + * If the extension is not present, the server does not support secure + * renegotiation; set secure_renegotiation flag to FALSE. In this case, some clients + * may want to terminate the handshake instead of continuing; see Section 4.1 for + * discussion. + */ + securityParameters.m_secureRenegotiation = false; + } + else + { + /* + * If the extension is present, set the secure_renegotiation flag to TRUE. The + * client MUST then verify that the length of the "renegotiated_connection" + * field is zero, and if it is not, MUST abort the handshake (by sending a fatal + * handshake_failure alert). + */ + securityParameters.m_secureRenegotiation = true; + + if (!Arrays.ConstantTimeAreEqual(renegExtData, CreateRenegotiationInfo(TlsUtilities.EmptyBytes))) + throw new TlsFatalAlert(AlertDescription.handshake_failure); + } + } + + // TODO[compat-gnutls] GnuTLS test server fails to send renegotiation_info extension when resuming + m_tlsClient.NotifySecureRenegotiation(securityParameters.IsSecureRenegotiation); + + /* + * RFC 7627 4. Clients and servers SHOULD NOT accept handshakes that do not use the extended + * master secret [..]. (and see 5.2, 5.3) + * + * RFC 8446 Appendix D. Because TLS 1.3 always hashes in the transcript up to the server + * Finished, implementations which support both TLS 1.3 and earlier versions SHOULD indicate + * the use of the Extended Master Secret extension in their APIs whenever TLS 1.3 is used. + */ + { + bool acceptedExtendedMasterSecret = TlsExtensionsUtilities.HasExtendedMasterSecretExtension( + m_serverExtensions); + + if (acceptedExtendedMasterSecret) + { + if (server_version.IsSsl + || (!m_resumedSession && !m_tlsClient.ShouldUseExtendedMasterSecret())) + { + throw new TlsFatalAlert(AlertDescription.handshake_failure); + } + } + else + { + if (m_tlsClient.RequiresExtendedMasterSecret() + || (m_resumedSession && !m_tlsClient.AllowLegacyResumption())) + { + throw new TlsFatalAlert(AlertDescription.handshake_failure); + } + } + + securityParameters.m_extendedMasterSecret = acceptedExtendedMasterSecret; + } + + /* + * RFC 7301 3.1. When session resumption or session tickets [...] are used, the previous + * contents of this extension are irrelevant, and only the values in the new handshake + * messages are considered. + */ + securityParameters.m_applicationProtocol = TlsExtensionsUtilities.GetAlpnExtensionServer( + m_serverExtensions); + securityParameters.m_applicationProtocolSet = true; + + IDictionary sessionClientExtensions = m_clientExtensions, sessionServerExtensions = m_serverExtensions; + if (m_resumedSession) + { + if (securityParameters.CipherSuite != m_sessionParameters.CipherSuite + || !server_version.Equals(m_sessionParameters.NegotiatedVersion)) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + sessionClientExtensions = null; + sessionServerExtensions = m_sessionParameters.ReadServerExtensions(); + } + + if (sessionServerExtensions != null && sessionServerExtensions.Count > 0) + { + { + /* + * RFC 7366 3. If a server receives an encrypt-then-MAC request extension from a client + * and then selects a stream or Authenticated Encryption with Associated Data (AEAD) + * ciphersuite, it MUST NOT send an encrypt-then-MAC response extension back to the + * client. + */ + bool serverSentEncryptThenMAC = TlsExtensionsUtilities.HasEncryptThenMacExtension( + sessionServerExtensions); + if (serverSentEncryptThenMAC && !TlsUtilities.IsBlockCipherSuite(securityParameters.CipherSuite)) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + securityParameters.m_encryptThenMac = serverSentEncryptThenMAC; + } + + securityParameters.m_maxFragmentLength = ProcessMaxFragmentLengthExtension(sessionClientExtensions, + sessionServerExtensions, AlertDescription.illegal_parameter); + + securityParameters.m_truncatedHmac = TlsExtensionsUtilities.HasTruncatedHmacExtension( + sessionServerExtensions); + + /* + * TODO It's surprising that there's no provision to allow a 'fresh' CertificateStatus to be sent in + * a session resumption handshake. + */ + if (!m_resumedSession) + { + // TODO[tls13] See RFC 8446 4.4.2.1 + if (TlsUtilities.HasExpectedEmptyExtensionData(sessionServerExtensions, + ExtensionType.status_request_v2, AlertDescription.illegal_parameter)) + { + securityParameters.m_statusRequestVersion = 2; + } + else if (TlsUtilities.HasExpectedEmptyExtensionData(sessionServerExtensions, + ExtensionType.status_request, AlertDescription.illegal_parameter)) + { + securityParameters.m_statusRequestVersion = 1; + } + + this.m_expectSessionTicket = TlsUtilities.HasExpectedEmptyExtensionData(sessionServerExtensions, + ExtensionType.session_ticket, AlertDescription.illegal_parameter); + } + } + + if (sessionClientExtensions != null) + { + m_tlsClient.ProcessServerExtensions(sessionServerExtensions); + } + + ApplyMaxFragmentLengthExtension(securityParameters.MaxFragmentLength); + + if (m_resumedSession) + { + securityParameters.m_masterSecret = m_sessionMasterSecret; + m_recordStream.SetPendingCipher(TlsUtilities.InitCipher(m_tlsClientContext)); + } + else + { + InvalidateSession(); + this.m_tlsSession = TlsUtilities.ImportSession(securityParameters.SessionID, null); + } + } + + /// + protected virtual void Receive13CertificateRequest(MemoryStream buf, bool postHandshakeAuth) + { + // TODO[tls13] Support for post_handshake_auth + if (postHandshakeAuth) + throw new TlsFatalAlert(AlertDescription.internal_error); + + /* + * RFC 8446 4.3.2. A server which is authenticating with a certificate MAY optionally + * request a certificate from the client. + */ + + if (m_selectedPsk13) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + + CertificateRequest certificateRequest = CertificateRequest.Parse(m_tlsClientContext, buf); + + AssertEmpty(buf); + + if (!certificateRequest.HasCertificateRequestContext(TlsUtilities.EmptyBytes)) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + this.m_certificateRequest = certificateRequest; + + TlsUtilities.EstablishServerSigAlgs(m_tlsClientContext.SecurityParameters, certificateRequest); + } + + /// + protected virtual void Receive13EncryptedExtensions(MemoryStream buf) + { + byte[] extBytes = TlsUtilities.ReadOpaque16(buf); + + AssertEmpty(buf); + + + this.m_serverExtensions = ReadExtensionsData13(HandshakeType.encrypted_extensions, extBytes); + + { + /* + * RFC 8446 4.2. Implementations MUST NOT send extension responses if the remote + * endpoint did not send the corresponding extension requests, with the exception of the + * "cookie" extension in the HelloRetryRequest. Upon receiving such an extension, an + * endpoint MUST abort the handshake with an "unsupported_extension" alert. + */ + foreach (int extType in m_serverExtensions.Keys) + { + if (null == TlsUtilities.GetExtensionData(m_clientExtensions, extType)) + throw new TlsFatalAlert(AlertDescription.unsupported_extension); + } + } + + + SecurityParameters securityParameters = m_tlsClientContext.SecurityParameters; + ProtocolVersion negotiatedVersion = securityParameters.NegotiatedVersion; + + securityParameters.m_applicationProtocol = TlsExtensionsUtilities.GetAlpnExtensionServer( + m_serverExtensions); + securityParameters.m_applicationProtocolSet = true; + + IDictionary sessionClientExtensions = m_clientExtensions, sessionServerExtensions = m_serverExtensions; + if (m_resumedSession) + { + if (securityParameters.CipherSuite != m_sessionParameters.CipherSuite + || !negotiatedVersion.Equals(m_sessionParameters.NegotiatedVersion)) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + sessionClientExtensions = null; + sessionServerExtensions = m_sessionParameters.ReadServerExtensions(); + } + + securityParameters.m_maxFragmentLength = ProcessMaxFragmentLengthExtension(sessionClientExtensions, + sessionServerExtensions, AlertDescription.illegal_parameter); + + securityParameters.m_encryptThenMac = false; + securityParameters.m_truncatedHmac = false; + + /* + * TODO[tls13] RFC 8446 4.4.2.1. OCSP Status and SCT Extensions. + * + * OCSP information is carried in an extension for a CertificateEntry. + */ + securityParameters.m_statusRequestVersion = m_clientExtensions.Contains(ExtensionType.status_request) + ? 1 : 0; + + this.m_expectSessionTicket = false; + + if (null != sessionClientExtensions) + { + m_tlsClient.ProcessServerExtensions(m_serverExtensions); + } + + ApplyMaxFragmentLengthExtension(securityParameters.MaxFragmentLength); + } + + /// + protected virtual void Receive13NewSessionTicket(MemoryStream buf) + { + if (!IsApplicationDataReady) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + + // TODO[tls13] Do something more than just ignore them + + // struct { + // uint32 ticket_lifetime; + // uint32 ticket_age_add; + // opaque ticket_nonce<0..255>; + // opaque ticket<1..2^16-1>; + // Extension extensions<0..2^16-2>; + // } NewSessionTicket; + + TlsUtilities.ReadUint32(buf); + TlsUtilities.ReadUint32(buf); + TlsUtilities.ReadOpaque8(buf); + TlsUtilities.ReadOpaque16(buf); + TlsUtilities.ReadOpaque16(buf); + AssertEmpty(buf); + } + + /// + protected virtual void Receive13ServerCertificate(MemoryStream buf) + { + if (m_selectedPsk13) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + + this.m_authentication = TlsUtilities.Receive13ServerCertificate(m_tlsClientContext, m_tlsClient, buf); + + // NOTE: In TLS 1.3 we don't have to wait for a possible CertificateStatus message. + HandleServerCertificate(); + } + + /// + protected virtual void Receive13ServerCertificateVerify(MemoryStream buf) + { + Certificate serverCertificate = m_tlsClientContext.SecurityParameters.PeerCertificate; + if (null == serverCertificate || serverCertificate.IsEmpty) + throw new TlsFatalAlert(AlertDescription.internal_error); + + // TODO[tls13] Actual structure is 'CertificateVerify' in RFC 8446, consider adding for clarity + DigitallySigned certificateVerify = DigitallySigned.Parse(m_tlsClientContext, buf); + + AssertEmpty(buf); + + TlsUtilities.Verify13CertificateVerifyServer(m_tlsClientContext, certificateVerify, m_handshakeHash); + } + + /// + protected virtual void Receive13ServerFinished(MemoryStream buf) + { + Process13FinishedMessage(buf); + } + + /// + protected virtual void ReceiveCertificateRequest(MemoryStream buf) + { + if (null == m_authentication) + { + /* + * RFC 2246 7.4.4. It is a fatal handshake_failure alert for an anonymous server to + * request client identification. + */ + throw new TlsFatalAlert(AlertDescription.handshake_failure); + } + + CertificateRequest certificateRequest = CertificateRequest.Parse(m_tlsClientContext, buf); + + AssertEmpty(buf); + + this.m_certificateRequest = TlsUtilities.ValidateCertificateRequest(certificateRequest, m_keyExchange); + } + + /// + protected virtual void ReceiveNewSessionTicket(MemoryStream buf) + { + NewSessionTicket newSessionTicket = NewSessionTicket.Parse(buf); + + AssertEmpty(buf); + + m_tlsClient.NotifyNewSessionTicket(newSessionTicket); + } + + /// + protected virtual ServerHello ReceiveServerHelloMessage(MemoryStream buf) + { + return ServerHello.Parse(buf); + } + + /// + protected virtual void Send13ClientHelloRetry() + { + IDictionary clientHelloExtensions = m_clientHello.Extensions; + + clientHelloExtensions.Remove(ExtensionType.cookie); + clientHelloExtensions.Remove(ExtensionType.early_data); + clientHelloExtensions.Remove(ExtensionType.key_share); + clientHelloExtensions.Remove(ExtensionType.pre_shared_key); + + /* + * RFC 4.2.2. When sending the new ClientHello, the client MUST copy the contents of the + * extension received in the HelloRetryRequest into a "cookie" extension in the new + * ClientHello. + */ + if (null != m_retryCookie) + { + /* + * - Including a "cookie" extension if one was provided in the HelloRetryRequest. + */ + TlsExtensionsUtilities.AddCookieExtension(clientHelloExtensions, m_retryCookie); + this.m_retryCookie = null; + } + + /* + * - Updating the "pre_shared_key" extension if present by recomputing the "obfuscated_ticket_age" + * and binder values and (optionally) removing any PSKs which are incompatible with the server's + * indicated cipher suite. + */ + if (null != m_clientBinders) + { + this.m_clientBinders = TlsUtilities.AddPreSharedKeyToClientHelloRetry(m_tlsClientContext, + m_clientBinders, clientHelloExtensions); + if (null == m_clientBinders) + { + m_tlsClient.NotifySelectedPsk(null); + } + } + + /* + * RFC 8446 4.2.8. [..] when sending the new ClientHello, the client MUST replace the + * original "key_share" extension with one containing only a new KeyShareEntry for the group + * indicated in the selected_group field of the triggering HelloRetryRequest. + */ + if (m_retryGroup < 0) + throw new TlsFatalAlert(AlertDescription.internal_error); + + /* + * - If a "key_share" extension was supplied in the HelloRetryRequest, replacing the list of shares + * with a list containing a single KeyShareEntry from the indicated group + */ + this.m_clientAgreements = TlsUtilities.AddKeyShareToClientHelloRetry(m_tlsClientContext, + clientHelloExtensions, m_retryGroup); + + /* + * TODO[tls13] Optionally adding, removing, or changing the length of the "padding" + * extension [RFC7685]. + */ + + // See RFC 8446 D.4. + { + m_recordStream.SetIgnoreChangeCipherSpec(true); + + /* + * TODO[tls13] If offering early_data, the record is placed immediately after the first + * ClientHello. + */ + SendChangeCipherSpecMessage(); + } + + SendClientHelloMessage(); + } + + /// + protected virtual void SendCertificateVerifyMessage(DigitallySigned certificateVerify) + { + HandshakeMessageOutput message = new HandshakeMessageOutput(HandshakeType.certificate_verify); + certificateVerify.Encode(message); + message.Send(this); + } + + /// + protected virtual void SendClientHello() + { + SecurityParameters securityParameters = m_tlsClientContext.SecurityParameters; + + ProtocolVersion[] supportedVersions; + ProtocolVersion earliestVersion, latestVersion; + + // NOT renegotiating + { + supportedVersions = m_tlsClient.GetProtocolVersions(); + + if (ProtocolVersion.Contains(supportedVersions, ProtocolVersion.SSLv3)) + { + // TODO[tls13] Prevent offering SSLv3 AND TLSv13? + m_recordStream.SetWriteVersion(ProtocolVersion.SSLv3); + } + else + { + m_recordStream.SetWriteVersion(ProtocolVersion.TLSv10); + } + + earliestVersion = ProtocolVersion.GetEarliestTls(supportedVersions); + latestVersion = ProtocolVersion.GetLatestTls(supportedVersions); + + if (!ProtocolVersion.IsSupportedTlsVersionClient(latestVersion)) + throw new TlsFatalAlert(AlertDescription.internal_error); + + m_tlsClientContext.SetClientVersion(latestVersion); + } + + m_tlsClientContext.SetClientSupportedVersions(supportedVersions); + + bool offeringTlsV12Minus = ProtocolVersion.TLSv12.IsEqualOrLaterVersionOf(earliestVersion); + bool offeringTlsV13Plus = ProtocolVersion.TLSv13.IsEqualOrEarlierVersionOf(latestVersion); + + EstablishSession(offeringTlsV12Minus ? m_tlsClient.GetSessionToResume() : null); + m_tlsClient.NotifySessionToResume(m_tlsSession); + + /* + * TODO RFC 5077 3.4. When presenting a ticket, the client MAY generate and include a + * Session ID in the TLS ClientHello. + */ + byte[] legacy_session_id = TlsUtilities.GetSessionID(m_tlsSession); + + bool fallback = m_tlsClient.IsFallback(); + + int[] offeredCipherSuites = m_tlsClient.GetCipherSuites(); + + if (legacy_session_id.Length > 0 && m_sessionParameters != null) + { + if (!Arrays.Contains(offeredCipherSuites, m_sessionParameters.CipherSuite)) + { + legacy_session_id = TlsUtilities.EmptyBytes; + } + } + + this.m_clientExtensions = TlsExtensionsUtilities.EnsureExtensionsInitialised( + m_tlsClient.GetClientExtensions()); + + ProtocolVersion legacy_version = latestVersion; + if (offeringTlsV13Plus) + { + legacy_version = ProtocolVersion.TLSv12; + + TlsExtensionsUtilities.AddSupportedVersionsExtensionClient(m_clientExtensions, supportedVersions); + + /* + * RFC 8446 4.2.1. In compatibility mode [..], this field MUST be non-empty, so a client + * not offering a pre-TLS 1.3 session MUST generate a new 32-byte value. + */ + if (legacy_session_id.Length < 1) + { + legacy_session_id = m_tlsClientContext.NonceGenerator.GenerateNonce(32); + } + } + + m_tlsClientContext.SetRsaPreMasterSecretVersion(legacy_version); + + securityParameters.m_clientServerNames = TlsExtensionsUtilities.GetServerNameExtensionClient( + m_clientExtensions); + + if (TlsUtilities.IsSignatureAlgorithmsExtensionAllowed(latestVersion)) + { + TlsUtilities.EstablishClientSigAlgs(securityParameters, m_clientExtensions); + } + + securityParameters.m_clientSupportedGroups = TlsExtensionsUtilities.GetSupportedGroupsExtension( + m_clientExtensions); + + this.m_clientBinders = TlsUtilities.AddPreSharedKeyToClientHello(m_tlsClientContext, m_tlsClient, + m_clientExtensions, offeredCipherSuites); + + // TODO[tls13-psk] Perhaps don't add key_share if external PSK(s) offered and 'psk_dhe_ke' not offered + this.m_clientAgreements = TlsUtilities.AddKeyShareToClientHello(m_tlsClientContext, m_tlsClient, + m_clientExtensions); + + if (TlsUtilities.IsExtendedMasterSecretOptionalTls(supportedVersions) + && (m_tlsClient.ShouldUseExtendedMasterSecret() || + (null != m_sessionParameters && m_sessionParameters.IsExtendedMasterSecret))) + { + TlsExtensionsUtilities.AddExtendedMasterSecretExtension(m_clientExtensions); + } + else if (!offeringTlsV13Plus && m_tlsClient.RequiresExtendedMasterSecret()) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + { + bool useGmtUnixTime = !offeringTlsV13Plus && m_tlsClient.ShouldUseGmtUnixTime(); + + securityParameters.m_clientRandom = CreateRandomBlock(useGmtUnixTime, m_tlsClientContext); + } + + // NOT renegotiating + { + /* + * RFC 5746 3.4. Client Behavior: Initial Handshake (both full and session-resumption) + */ + + /* + * The client MUST include either an empty "renegotiation_info" extension, or the + * TLS_EMPTY_RENEGOTIATION_INFO_SCSV signaling cipher suite value in the ClientHello. + * Including both is NOT RECOMMENDED. + */ + bool noRenegExt = (null == TlsUtilities.GetExtensionData(m_clientExtensions, + ExtensionType.renegotiation_info)); + bool noRenegScsv = !Arrays.Contains(offeredCipherSuites, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV); + + if (noRenegExt && noRenegScsv) + { + // TODO[tls13] Probably want to not add this if no pre-TLSv13 versions offered? + offeredCipherSuites = Arrays.Append(offeredCipherSuites, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV); + } + } + + /* + * (Fallback SCSV) + * RFC 7507 4. If a client sends a ClientHello.client_version containing a lower value + * than the latest (highest-valued) version supported by the client, it SHOULD include + * the TLS_FALLBACK_SCSV cipher suite value in ClientHello.cipher_suites [..]. (The + * client SHOULD put TLS_FALLBACK_SCSV after all cipher suites that it actually intends + * to negotiate.) + */ + if (fallback && !Arrays.Contains(offeredCipherSuites, CipherSuite.TLS_FALLBACK_SCSV)) + { + offeredCipherSuites = Arrays.Append(offeredCipherSuites, CipherSuite.TLS_FALLBACK_SCSV); + } + + + + int bindersSize = null == m_clientBinders ? 0 : m_clientBinders.m_bindersSize; + + this.m_clientHello = new ClientHello(legacy_version, securityParameters.ClientRandom, legacy_session_id, + null, offeredCipherSuites, m_clientExtensions, bindersSize); + + SendClientHelloMessage(); + } + + /// + protected virtual void SendClientHelloMessage() + { + HandshakeMessageOutput message = new HandshakeMessageOutput(HandshakeType.client_hello); + m_clientHello.Encode(m_tlsClientContext, message); + + message.PrepareClientHello(m_handshakeHash, m_clientHello.BindersSize); + + if (null != m_clientBinders) + { + OfferedPsks.EncodeBinders(message, m_tlsClientContext.Crypto, m_handshakeHash, m_clientBinders); + } + + message.SendClientHello(this, m_handshakeHash, m_clientHello.BindersSize); + } + + /// + protected virtual void SendClientKeyExchange() + { + HandshakeMessageOutput message = new HandshakeMessageOutput(HandshakeType.client_key_exchange); + m_keyExchange.GenerateClientKeyExchange(message); + message.Send(this); + } + + /// + protected virtual void Skip13CertificateRequest() + { + this.m_certificateRequest = null; + } + + /// + protected virtual void Skip13ServerCertificate() + { + if (!m_selectedPsk13) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + + this.m_authentication = TlsUtilities.Skip13ServerCertificate(m_tlsClientContext); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsClientProtocol.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsClientProtocol.cs.meta new file mode 100644 index 0000000..dcd8baa --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsClientProtocol.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c70d051ca32e4a241a66bfe4b181b6bb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsCloseable.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsCloseable.cs new file mode 100644 index 0000000..baf2ff4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsCloseable.cs @@ -0,0 +1,11 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Tls +{ + public interface TlsCloseable + { + /// + void Close(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsCloseable.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsCloseable.cs.meta new file mode 100644 index 0000000..f63fbbe --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsCloseable.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4e9b54e5617b14e4aa1904022a44f05b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsContext.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsContext.cs new file mode 100644 index 0000000..5a2802f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsContext.cs @@ -0,0 +1,79 @@ +using System; + +using Org.BouncyCastle.Tls.Crypto; + +namespace Org.BouncyCastle.Tls +{ + /// Base interface for a TLS context implementation. + public interface TlsContext + { + TlsCrypto Crypto { get; } + + TlsNonceGenerator NonceGenerator { get; } + + SecurityParameters SecurityParameters { get; } + + /// Return true if this context is for a server, false otherwise. + /// true for a server based context, false for a client based one. + bool IsServer { get; } + + ProtocolVersion[] ClientSupportedVersions { get; } + + ProtocolVersion ClientVersion { get; } + + ProtocolVersion RsaPreMasterSecretVersion { get; } + + ProtocolVersion ServerVersion { get; } + + /// Used to get the resumable session, if any, used by this connection. + /// + /// Only available after the handshake has successfully completed. + /// + /// A representing the resumable session used by this connection, or null if + /// no resumable session available. + /// + TlsSession ResumableSession { get; } + + /// Used to get the session information for this connection. + /// + /// Only available after the handshake has successfully completed. Use + /// to find out if the session is resumable. + /// + /// A representing the session used by this connection. + /// + TlsSession Session { get; } + + object UserObject { get; set; } + + /// Export the value of the specified channel binding. + /// + /// Only available after the handshake has successfully completed. + /// + /// A constant specifying the channel binding to + /// export. + /// A copy of the channel binding data as a byte[], or null if the binding could not be + /// determined. + byte[] ExportChannelBinding(int channelBinding); + + /// Export (early data) keying material according to RFC 5705: "Keying Material Exporters for TLS", as + /// updated for TLS 1.3 (RFC 8446). + /// + /// NOTE: for use in settings where an exporter is needed for 0-RTT data. + /// + /// indicates which application will use the exported keys. + /// allows the application using the exporter to mix its own data with the TLS PRF + /// for the exporter output. + /// the number of bytes to generate. + /// a pseudorandom bit string of 'length' bytes generated from the (exporter_)master_secret. + byte[] ExportEarlyKeyingMaterial(string asciiLabel, byte[] context_value, int length); + + /// Export keying material according to RFC 5705: "Keying Material Exporters for TLS", as updated for + /// TLS 1.3 (RFC 8446) when negotiated. + /// indicates which application will use the exported keys. + /// allows the application using the exporter to mix its own data with the TLS PRF + /// for the exporter output. + /// the number of bytes to generate. + /// a pseudorandom bit string of 'length' bytes generated from the (exporter_)master_secret. + byte[] ExportKeyingMaterial(string asciiLabel, byte[] context_value, int length); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsContext.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsContext.cs.meta new file mode 100644 index 0000000..3113fb4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsContext.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 26490e367e27a154e901a84246f12a68 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsCredentialedAgreement.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsCredentialedAgreement.cs new file mode 100644 index 0000000..354a177 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsCredentialedAgreement.cs @@ -0,0 +1,19 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Tls.Crypto; + +namespace Org.BouncyCastle.Tls +{ + /// Support interface for generating a secret based on the credentials sent by a TLS peer. + public interface TlsCredentialedAgreement + : TlsCredentials + { + /// Calculate an agreed secret based on our credentials and the public key credentials of our peer. + /// + /// public key certificate of our TLS peer. + /// the agreed secret. + /// in case of an exception on generation of the secret. + TlsSecret GenerateAgreement(TlsCertificate peerCertificate); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsCredentialedAgreement.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsCredentialedAgreement.cs.meta new file mode 100644 index 0000000..b0380b4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsCredentialedAgreement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 20ba4cf7451aeb641a3d6110f39fa040 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsCredentialedDecryptor.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsCredentialedDecryptor.cs new file mode 100644 index 0000000..5fa021d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsCredentialedDecryptor.cs @@ -0,0 +1,19 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Tls.Crypto; + +namespace Org.BouncyCastle.Tls +{ + /// Base interface for a class that decrypts TLS secrets. + public interface TlsCredentialedDecryptor + : TlsCredentials + { + /// Decrypt the passed in cipher text using the parameters available. + /// the parameters to use for the decryption. + /// the cipher text containing the secret. + /// a TLS secret. + /// on a parsing or decryption error. + TlsSecret Decrypt(TlsCryptoParameters cryptoParams, byte[] ciphertext); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsCredentialedDecryptor.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsCredentialedDecryptor.cs.meta new file mode 100644 index 0000000..f59b7c0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsCredentialedDecryptor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 23073c4fc67cf564b898b02d58c9f1ad +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsCredentialedSigner.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsCredentialedSigner.cs new file mode 100644 index 0000000..c6f5a8d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsCredentialedSigner.cs @@ -0,0 +1,26 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Tls.Crypto; + +namespace Org.BouncyCastle.Tls +{ + /// Support interface for generating a signature based on our private credentials. + public interface TlsCredentialedSigner + : TlsCredentials + { + /// Generate a signature against the passed in hash. + /// a message digest calculated across the message the signature is to apply to. + /// an encoded signature. + /// if the hash cannot be processed, or there is an issue with the private + /// credentials. + byte[] GenerateRawSignature(byte[] hash); + + /// Return the algorithm IDs for the signature algorithm and the associated hash it uses. + /// the full algorithm details for the signature. + SignatureAndHashAlgorithm SignatureAndHashAlgorithm { get; } + + /// + TlsStreamSigner GetStreamSigner(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsCredentialedSigner.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsCredentialedSigner.cs.meta new file mode 100644 index 0000000..ac6200d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsCredentialedSigner.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3903136836d145d42a6306964564797f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsCredentials.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsCredentials.cs new file mode 100644 index 0000000..4a6084a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsCredentials.cs @@ -0,0 +1,12 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + /// Base interface for interfaces/classes carrying TLS credentials. + public interface TlsCredentials + { + /// Return the certificate structure representing our identity. + /// our certificate structure. + Certificate Certificate { get; } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsCredentials.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsCredentials.cs.meta new file mode 100644 index 0000000..ac6e50e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsCredentials.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6d1956ceffc785e4c823346c48df17d5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsDHGroupVerifier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsDHGroupVerifier.cs new file mode 100644 index 0000000..2fb208c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsDHGroupVerifier.cs @@ -0,0 +1,15 @@ +using System; + +using Org.BouncyCastle.Tls.Crypto; + +namespace Org.BouncyCastle.Tls +{ + /// Interface for verifying explicit Diffie-Hellman group parameters. + public interface TlsDHGroupVerifier + { + /// Check whether the given DH group is acceptable for use. + /// the to check. + /// true if (and only if) the specified group is acceptable. + bool Accept(DHGroup dhGroup); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsDHGroupVerifier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsDHGroupVerifier.cs.meta new file mode 100644 index 0000000..b5c1ca9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsDHGroupVerifier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ff223d2a480b5414584a8fe3bbb0b39a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsDHKeyExchange.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsDHKeyExchange.cs new file mode 100644 index 0000000..abce91f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsDHKeyExchange.cs @@ -0,0 +1,91 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Tls.Crypto; + +namespace Org.BouncyCastle.Tls +{ + /// (D)TLS DH key exchange. + public class TlsDHKeyExchange + : AbstractTlsKeyExchange + { + private static int CheckKeyExchange(int keyExchange) + { + switch (keyExchange) + { + case KeyExchangeAlgorithm.DH_DSS: + case KeyExchangeAlgorithm.DH_RSA: + return keyExchange; + default: + throw new ArgumentException("unsupported key exchange algorithm", "keyExchange"); + } + } + + protected TlsCredentialedAgreement m_agreementCredentials; + protected TlsCertificate m_dhPeerCertificate; + + public TlsDHKeyExchange(int keyExchange) + : base(CheckKeyExchange(keyExchange)) + { + } + + public override void SkipServerCredentials() + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public override void ProcessServerCredentials(TlsCredentials serverCredentials) + { + this.m_agreementCredentials = TlsUtilities.RequireAgreementCredentials(serverCredentials); + } + + public override void ProcessServerCertificate(Certificate serverCertificate) + { + this.m_dhPeerCertificate = serverCertificate.GetCertificateAt(0).CheckUsageInRole(TlsCertificateRole.DH); + } + + public override short[] GetClientCertificateTypes() + { + return new short[]{ ClientCertificateType.dss_fixed_dh, ClientCertificateType.rsa_fixed_dh }; + } + + public override void SkipClientCredentials() + { + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + public override void ProcessClientCredentials(TlsCredentials clientCredentials) + { + this.m_agreementCredentials = TlsUtilities.RequireAgreementCredentials(clientCredentials); + } + + public override void GenerateClientKeyExchange(Stream output) + { + /* + * RFC 2246 7.4.7.2 If the client certificate already contains a suitable Diffie-Hellman + * key, then Yc is implicit and does not need to be sent again. In this case, the Client Key + * Exchange message will be sent, but will be empty. + */ + } + + public override void ProcessClientCertificate(Certificate clientCertificate) + { + this.m_dhPeerCertificate = clientCertificate.GetCertificateAt(0).CheckUsageInRole(TlsCertificateRole.DH); + } + + public override void ProcessClientKeyExchange(Stream input) + { + // For dss_fixed_dh and rsa_fixed_dh, the key arrived in the client certificate + } + + public override bool RequiresCertificateVerify + { + get { return false; } + } + + public override TlsSecret GeneratePreMasterSecret() + { + return m_agreementCredentials.GenerateAgreement(m_dhPeerCertificate); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsDHKeyExchange.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsDHKeyExchange.cs.meta new file mode 100644 index 0000000..e503cb7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsDHKeyExchange.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5a2b40e687c20374783d02921bf9df5b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsDHUtilities.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsDHUtilities.cs new file mode 100644 index 0000000..7605b00 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsDHUtilities.cs @@ -0,0 +1,159 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Tls.Crypto; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls +{ + public abstract class TlsDHUtilities + { + public static TlsDHConfig CreateNamedDHConfig(TlsContext context, int namedGroup) + { + if (namedGroup < 0 || NamedGroup.GetFiniteFieldBits(namedGroup) < 1) + return null; + + bool padded = TlsUtilities.IsTlsV13(context); + return new TlsDHConfig(namedGroup, padded); + } + + public static DHGroup GetDHGroup(TlsDHConfig dhConfig) + { + int namedGroup = dhConfig.NamedGroup; + if (namedGroup >= 0) + return GetNamedDHGroup(namedGroup); + + return dhConfig.ExplicitGroup; + } + + public static DHGroup GetNamedDHGroup(int namedGroup) + { + switch (namedGroup) + { + case NamedGroup.ffdhe2048: + return DHStandardGroups.rfc7919_ffdhe2048; + case NamedGroup.ffdhe3072: + return DHStandardGroups.rfc7919_ffdhe3072; + case NamedGroup.ffdhe4096: + return DHStandardGroups.rfc7919_ffdhe4096; + case NamedGroup.ffdhe6144: + return DHStandardGroups.rfc7919_ffdhe6144; + case NamedGroup.ffdhe8192: + return DHStandardGroups.rfc7919_ffdhe8192; + default: + return null; + } + } + + public static int GetMinimumFiniteFieldBits(int cipherSuite) + { + /* + * NOTE: An equivalent mechanism was added to support a minimum bit-size requirement for ECC + * mooted in early drafts of RFC 8442. This requirement was removed in later drafts, so that + * mechanism is currently somewhat trivial, and this similarly so. + */ + return IsDHCipherSuite(cipherSuite) ? 1 : 0; + } + + public static bool IsDHCipherSuite(int cipherSuite) + { + switch (TlsUtilities.GetKeyExchangeAlgorithm(cipherSuite)) + { + case KeyExchangeAlgorithm.DH_anon: + case KeyExchangeAlgorithm.DH_DSS: + case KeyExchangeAlgorithm.DH_RSA: + case KeyExchangeAlgorithm.DHE_DSS: + case KeyExchangeAlgorithm.DHE_PSK: + case KeyExchangeAlgorithm.DHE_RSA: + return true; + + default: + return false; + } + } + + public static int GetNamedGroupForDHParameters(BigInteger p, BigInteger g) + { + int[] namedGroups = new int[]{ NamedGroup.ffdhe2048, NamedGroup.ffdhe3072, NamedGroup.ffdhe4096, + NamedGroup.ffdhe6144, NamedGroup.ffdhe8192 }; + + for (int i = 0; i < namedGroups.Length; ++i) + { + int namedGroup = namedGroups[i]; + DHGroup dhGroup = GetNamedDHGroup(namedGroup); + if (dhGroup != null && dhGroup.P.Equals(p) && dhGroup.G.Equals(g)) + return namedGroup; + } + + return -1; + } + + public static DHGroup GetStandardGroupForDHParameters(BigInteger p, BigInteger g) + { + DHGroup[] standardGroups = new DHGroup[] { DHStandardGroups.rfc7919_ffdhe2048, + DHStandardGroups.rfc7919_ffdhe3072, DHStandardGroups.rfc7919_ffdhe4096, DHStandardGroups.rfc7919_ffdhe6144, + DHStandardGroups.rfc7919_ffdhe8192, DHStandardGroups.rfc3526_1536, DHStandardGroups.rfc3526_2048, + DHStandardGroups.rfc3526_3072, DHStandardGroups.rfc3526_4096, DHStandardGroups.rfc3526_6144, + DHStandardGroups.rfc3526_8192, DHStandardGroups.rfc5996_768, DHStandardGroups.rfc5996_1024 }; + + for (int i = 0; i < standardGroups.Length; ++i) + { + DHGroup dhGroup = standardGroups[i]; + if (dhGroup != null && dhGroup.P.Equals(p) && dhGroup.G.Equals(g)) + return dhGroup; + } + + return null; + } + + /// + public static TlsDHConfig ReceiveDHConfig(TlsContext context, TlsDHGroupVerifier dhGroupVerifier, + Stream input) + { + BigInteger p = ReadDHParameter(input); + BigInteger g = ReadDHParameter(input); + + int namedGroup = GetNamedGroupForDHParameters(p, g); + if (namedGroup< 0) + { + DHGroup dhGroup = GetStandardGroupForDHParameters(p, g); + if (null == dhGroup) + { + dhGroup = new DHGroup(p, null, g, 0); + } + + if (!dhGroupVerifier.Accept(dhGroup)) + throw new TlsFatalAlert(AlertDescription.insufficient_security); + + return new TlsDHConfig(dhGroup); + } + + int[] clientSupportedGroups = context.SecurityParameters.ClientSupportedGroups; + if (null == clientSupportedGroups || Arrays.Contains(clientSupportedGroups, namedGroup)) + return new TlsDHConfig(namedGroup, false); + + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + /// + public static BigInteger ReadDHParameter(Stream input) + { + return new BigInteger(1, TlsUtilities.ReadOpaque16(input, 1)); + } + + /// + public static void WriteDHConfig(TlsDHConfig dhConfig, Stream output) + { + DHGroup group = GetDHGroup(dhConfig); + WriteDHParameter(group.P, output); + WriteDHParameter(group.G, output); + } + + /// + public static void WriteDHParameter(BigInteger x, Stream output) + { + TlsUtilities.WriteOpaque16(BigIntegers.AsUnsignedByteArray(x), output); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsDHUtilities.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsDHUtilities.cs.meta new file mode 100644 index 0000000..eae74ef --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsDHUtilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 009449fd8b4a4b34babf594302b992e8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsDHanonKeyExchange.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsDHanonKeyExchange.cs new file mode 100644 index 0000000..dd03ce0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsDHanonKeyExchange.cs @@ -0,0 +1,124 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Tls.Crypto; + +namespace Org.BouncyCastle.Tls +{ + /// (D)TLS DH_anon key exchange. + public class TlsDHanonKeyExchange + : AbstractTlsKeyExchange + { + private static int CheckKeyExchange(int keyExchange) + { + switch (keyExchange) + { + case KeyExchangeAlgorithm.DH_anon: + return keyExchange; + default: + throw new ArgumentException("unsupported key exchange algorithm", "keyExchange"); + } + } + + protected TlsDHGroupVerifier m_dhGroupVerifier; + protected TlsDHConfig m_dhConfig; + + protected TlsAgreement m_agreement; + + public TlsDHanonKeyExchange(int keyExchange, TlsDHGroupVerifier dhGroupVerifier) + : this(keyExchange, dhGroupVerifier, null) + { + } + + public TlsDHanonKeyExchange(int keyExchange, TlsDHConfig dhConfig) + : this(keyExchange, null, dhConfig) + { + } + + private TlsDHanonKeyExchange(int keyExchange, TlsDHGroupVerifier dhGroupVerifier, TlsDHConfig dhConfig) + : base(CheckKeyExchange(keyExchange)) + { + this.m_dhGroupVerifier = dhGroupVerifier; + this.m_dhConfig = dhConfig; + } + + public override void SkipServerCredentials() + { + } + + public override void ProcessServerCredentials(TlsCredentials serverCredentials) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public override void ProcessServerCertificate(Certificate serverCertificate) + { + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + public override bool RequiresServerKeyExchange + { + get { return true; } + } + + public override byte[] GenerateServerKeyExchange() + { + MemoryStream buf = new MemoryStream(); + + TlsDHUtilities.WriteDHConfig(m_dhConfig, buf); + + this.m_agreement = m_context.Crypto.CreateDHDomain(m_dhConfig).CreateDH(); + + byte[] y = m_agreement.GenerateEphemeral(); + + TlsUtilities.WriteOpaque16(y, buf); + + return buf. ToArray(); + } + + public override void ProcessServerKeyExchange(Stream input) + { + this.m_dhConfig = TlsDHUtilities.ReceiveDHConfig(m_context, m_dhGroupVerifier, input); + + byte[] y = TlsUtilities.ReadOpaque16(input, 1); + + this.m_agreement = m_context.Crypto.CreateDHDomain(m_dhConfig).CreateDH(); + + m_agreement.ReceivePeerValue(y); + } + + public override short[] GetClientCertificateTypes() + { + return null; + } + + public override void ProcessClientCredentials(TlsCredentials clientCredentials) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public override void GenerateClientKeyExchange(Stream output) + { + byte[] y = m_agreement.GenerateEphemeral(); + + TlsUtilities.WriteOpaque16(y, output); + } + + public override void ProcessClientCertificate(Certificate clientCertificate) + { + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + public override void ProcessClientKeyExchange(Stream input) + { + byte[] y = TlsUtilities.ReadOpaque16(input, 1); + + m_agreement.ReceivePeerValue(y); + } + + public override TlsSecret GeneratePreMasterSecret() + { + return m_agreement.CalculateSecret(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsDHanonKeyExchange.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsDHanonKeyExchange.cs.meta new file mode 100644 index 0000000..3635d3b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsDHanonKeyExchange.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a7445a5ec93aa7f498157f2905bc11b1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsDheKeyExchange.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsDheKeyExchange.cs new file mode 100644 index 0000000..74b919c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsDheKeyExchange.cs @@ -0,0 +1,129 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Tls.Crypto; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Tls +{ + public class TlsDheKeyExchange + : AbstractTlsKeyExchange + { + private static int CheckKeyExchange(int keyExchange) + { + switch (keyExchange) + { + case KeyExchangeAlgorithm.DHE_DSS: + case KeyExchangeAlgorithm.DHE_RSA: + return keyExchange; + default: + throw new ArgumentException("unsupported key exchange algorithm", "keyExchange"); + } + } + + protected TlsDHGroupVerifier m_dhGroupVerifier; + protected TlsDHConfig m_dhConfig; + + protected TlsCredentialedSigner m_serverCredentials = null; + protected TlsCertificate m_serverCertificate = null; + protected TlsAgreement m_agreement; + + public TlsDheKeyExchange(int keyExchange, TlsDHGroupVerifier dhGroupVerifier) + : this(keyExchange, dhGroupVerifier, null) + { + } + + public TlsDheKeyExchange(int keyExchange, TlsDHConfig dhConfig) + : this(keyExchange, null, dhConfig) + { + } + + private TlsDheKeyExchange(int keyExchange, TlsDHGroupVerifier dhGroupVerifier, TlsDHConfig dhConfig) + : base(CheckKeyExchange(keyExchange)) + { + this.m_dhGroupVerifier = dhGroupVerifier; + this.m_dhConfig = dhConfig; + } + + public override void SkipServerCredentials() + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public override void ProcessServerCredentials(TlsCredentials serverCredentials) + { + this.m_serverCredentials = TlsUtilities.RequireSignerCredentials(serverCredentials); + } + + public override void ProcessServerCertificate(Certificate serverCertificate) + { + this.m_serverCertificate = serverCertificate.GetCertificateAt(0); + } + + public override bool RequiresServerKeyExchange + { + get { return true; } + } + + public override byte[] GenerateServerKeyExchange() + { + DigestInputBuffer digestBuffer = new DigestInputBuffer(); + + TlsDHUtilities.WriteDHConfig(m_dhConfig, digestBuffer); + + this.m_agreement = m_context.Crypto.CreateDHDomain(m_dhConfig).CreateDH(); + + byte[] y = m_agreement.GenerateEphemeral(); + + TlsUtilities.WriteOpaque16(y, digestBuffer); + + TlsUtilities.GenerateServerKeyExchangeSignature(m_context, m_serverCredentials, null, digestBuffer); + + return digestBuffer.ToArray(); + } + + public override void ProcessServerKeyExchange(Stream input) + { + DigestInputBuffer digestBuffer = new DigestInputBuffer(); + Stream teeIn = new TeeInputStream(input, digestBuffer); + + this.m_dhConfig = TlsDHUtilities.ReceiveDHConfig(m_context, m_dhGroupVerifier, teeIn); + + byte[] y = TlsUtilities.ReadOpaque16(teeIn, 1); + + TlsUtilities.VerifyServerKeyExchangeSignature(m_context, input, m_serverCertificate, null, digestBuffer); + + this.m_agreement = m_context.Crypto.CreateDHDomain(m_dhConfig).CreateDH(); + + m_agreement.ReceivePeerValue(y); + } + + public override short[] GetClientCertificateTypes() + { + return new short[]{ ClientCertificateType.dss_sign, ClientCertificateType.ecdsa_sign, + ClientCertificateType.rsa_sign }; + } + + public override void ProcessClientCredentials(TlsCredentials clientCredentials) + { + TlsUtilities.RequireSignerCredentials(clientCredentials); + } + + public override void GenerateClientKeyExchange(Stream output) + { + byte[] y = m_agreement.GenerateEphemeral(); + + TlsUtilities.WriteOpaque16(y, output); + } + + public override void ProcessClientKeyExchange(Stream input) + { + m_agreement.ReceivePeerValue(TlsUtilities.ReadOpaque16(input, 1)); + } + + public override TlsSecret GeneratePreMasterSecret() + { + return m_agreement.CalculateSecret(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsDheKeyExchange.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsDheKeyExchange.cs.meta new file mode 100644 index 0000000..b1141b0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsDheKeyExchange.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: af2129885e1fad94daa2038ce604dbf2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsECDHKeyExchange.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsECDHKeyExchange.cs new file mode 100644 index 0000000..e7e2981 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsECDHKeyExchange.cs @@ -0,0 +1,95 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Tls.Crypto; + +namespace Org.BouncyCastle.Tls +{ + /// (D)TLS ECDH key exchange (see RFC 4492). + public class TlsECDHKeyExchange + : AbstractTlsKeyExchange + { + private static int CheckKeyExchange(int keyExchange) + { + switch (keyExchange) + { + case KeyExchangeAlgorithm.ECDH_ECDSA: + case KeyExchangeAlgorithm.ECDH_RSA: + return keyExchange; + default: + throw new ArgumentException("unsupported key exchange algorithm", "keyExchange"); + } + } + + protected TlsCredentialedAgreement m_agreementCredentials; + protected TlsCertificate m_ecdhPeerCertificate; + + public TlsECDHKeyExchange(int keyExchange) + : base(CheckKeyExchange(keyExchange)) + { + } + + public override void SkipServerCredentials() + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public override void ProcessServerCredentials(TlsCredentials serverCredentials) + { + this.m_agreementCredentials = TlsUtilities.RequireAgreementCredentials(serverCredentials); + } + + public override void ProcessServerCertificate(Certificate serverCertificate) + { + this.m_ecdhPeerCertificate = serverCertificate.GetCertificateAt(0).CheckUsageInRole( + TlsCertificateRole.ECDH); + } + + public override short[] GetClientCertificateTypes() + { + /* + * RFC 4492 3. [...] The ECDSA_fixed_ECDH and RSA_fixed_ECDH mechanisms are usable with + * ECDH_ECDSA and ECDH_RSA. Their use with ECDHE_ECDSA and ECDHE_RSA is prohibited because + * the use of a long-term ECDH client key would jeopardize the forward secrecy property of + * these algorithms. + */ + return new short[]{ ClientCertificateType.ecdsa_fixed_ecdh, ClientCertificateType.rsa_fixed_ecdh }; + } + + public override void SkipClientCredentials() + { + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + public override void ProcessClientCredentials(TlsCredentials clientCredentials) + { + this.m_agreementCredentials = TlsUtilities.RequireAgreementCredentials(clientCredentials); + } + + public override void GenerateClientKeyExchange(Stream output) + { + // In this case, the Client Key Exchange message will be sent, but will be empty. + } + + public override void ProcessClientCertificate(Certificate clientCertificate) + { + this.m_ecdhPeerCertificate = clientCertificate.GetCertificateAt(0).CheckUsageInRole( + TlsCertificateRole.ECDH); + } + + public override void ProcessClientKeyExchange(Stream input) + { + // For ecdsa_fixed_ecdh and rsa_fixed_ecdh, the key arrived in the client certificate + } + + public override bool RequiresCertificateVerify + { + get { return false; } + } + + public override TlsSecret GeneratePreMasterSecret() + { + return m_agreementCredentials.GenerateAgreement(m_ecdhPeerCertificate); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsECDHKeyExchange.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsECDHKeyExchange.cs.meta new file mode 100644 index 0000000..9a05737 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsECDHKeyExchange.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 170ffa7a225c4054ebc11bbdaebf03e4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsECDHanonKeyExchange.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsECDHanonKeyExchange.cs new file mode 100644 index 0000000..66b0ec9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsECDHanonKeyExchange.cs @@ -0,0 +1,127 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Tls.Crypto; + +namespace Org.BouncyCastle.Tls +{ + /// (D)TLS ECDH_anon key exchange (see RFC 4492). + public class TlsECDHanonKeyExchange + : AbstractTlsKeyExchange + { + private static int CheckKeyExchange(int keyExchange) + { + switch (keyExchange) + { + case KeyExchangeAlgorithm.ECDH_anon: + return keyExchange; + default: + throw new ArgumentException("unsupported key exchange algorithm", "keyExchange"); + } + } + + protected TlsECConfig m_ecConfig; + + protected TlsAgreement m_agreement; + + public TlsECDHanonKeyExchange(int keyExchange) + : this(keyExchange, null) + { + } + + public TlsECDHanonKeyExchange(int keyExchange, TlsECConfig ecConfig) + : base(CheckKeyExchange(keyExchange)) + { + this.m_ecConfig = ecConfig; + } + + public override void SkipServerCredentials() + { + } + + public override void ProcessServerCredentials(TlsCredentials serverCredentials) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public override void ProcessServerCertificate(Certificate serverCertificate) + { + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + public override bool RequiresServerKeyExchange + { + get { return true; } + } + + public override byte[] GenerateServerKeyExchange() + { + MemoryStream buf = new MemoryStream(); + + TlsEccUtilities.WriteECConfig(m_ecConfig, buf); + + this.m_agreement = m_context.Crypto.CreateECDomain(m_ecConfig).CreateECDH(); + + GenerateEphemeral(buf); + + return buf.ToArray(); + } + + public override void ProcessServerKeyExchange(Stream input) + { + this.m_ecConfig = TlsEccUtilities.ReceiveECDHConfig(m_context, input); + + byte[] point = TlsUtilities.ReadOpaque8(input, 1); + + this.m_agreement = m_context.Crypto.CreateECDomain(m_ecConfig).CreateECDH(); + + ProcessEphemeral(point); + } + + public override short[] GetClientCertificateTypes() + { + return null; + } + + public override void ProcessClientCredentials(TlsCredentials clientCredentials) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public override void GenerateClientKeyExchange(Stream output) + { + GenerateEphemeral(output); + } + + public override void ProcessClientCertificate(Certificate clientCertificate) + { + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + public override void ProcessClientKeyExchange(Stream input) + { + byte[] point = TlsUtilities.ReadOpaque8(input, 1); + + ProcessEphemeral(point); + } + + public override TlsSecret GeneratePreMasterSecret() + { + return m_agreement.CalculateSecret(); + } + + protected virtual void GenerateEphemeral(Stream output) + { + byte[] point = m_agreement.GenerateEphemeral(); + + TlsUtilities.WriteOpaque8(point, output); + } + + protected virtual void ProcessEphemeral(byte[] point) + { + TlsEccUtilities.CheckPointEncoding(m_ecConfig.NamedGroup, point); + + this.m_agreement.ReceivePeerValue(point); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsECDHanonKeyExchange.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsECDHanonKeyExchange.cs.meta new file mode 100644 index 0000000..b329ee3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsECDHanonKeyExchange.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6a71c35a3c26329499af54441bec999d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsECDheKeyExchange.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsECDheKeyExchange.cs new file mode 100644 index 0000000..1073775 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsECDheKeyExchange.cs @@ -0,0 +1,141 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Tls.Crypto; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Tls +{ + /// (D)TLS ECDHE key exchange (see RFC 4492). + public class TlsECDheKeyExchange + : AbstractTlsKeyExchange + { + private static int CheckKeyExchange(int keyExchange) + { + switch (keyExchange) + { + case KeyExchangeAlgorithm.ECDHE_ECDSA: + case KeyExchangeAlgorithm.ECDHE_RSA: + return keyExchange; + default: + throw new ArgumentException("unsupported key exchange algorithm", "keyExchange"); + } + } + + protected TlsECConfig m_ecConfig; + + protected TlsCredentialedSigner m_serverCredentials = null; + protected TlsCertificate m_serverCertificate = null; + protected TlsAgreement m_agreement; + + public TlsECDheKeyExchange(int keyExchange) + : this(keyExchange, null) + { + } + + public TlsECDheKeyExchange(int keyExchange, TlsECConfig ecConfig) + : base(CheckKeyExchange(keyExchange)) + { + this.m_ecConfig = ecConfig; + } + + public override void SkipServerCredentials() + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public override void ProcessServerCredentials(TlsCredentials serverCredentials) + { + this.m_serverCredentials = TlsUtilities.RequireSignerCredentials(serverCredentials); + } + + public override void ProcessServerCertificate(Certificate serverCertificate) + { + this.m_serverCertificate = serverCertificate.GetCertificateAt(0); + } + + public override bool RequiresServerKeyExchange + { + get { return true; } + } + + public override byte[] GenerateServerKeyExchange() + { + DigestInputBuffer digestBuffer = new DigestInputBuffer(); + + TlsEccUtilities.WriteECConfig(m_ecConfig, digestBuffer); + + this.m_agreement = m_context.Crypto.CreateECDomain(m_ecConfig).CreateECDH(); + + GenerateEphemeral(digestBuffer); + + TlsUtilities.GenerateServerKeyExchangeSignature(m_context, m_serverCredentials, null, digestBuffer); + + return digestBuffer.ToArray(); + } + + public override void ProcessServerKeyExchange(Stream input) + { + DigestInputBuffer digestBuffer = new DigestInputBuffer(); + Stream teeIn = new TeeInputStream(input, digestBuffer); + + this.m_ecConfig = TlsEccUtilities.ReceiveECDHConfig(m_context, teeIn); + + byte[] point = TlsUtilities.ReadOpaque8(teeIn, 1); + + TlsUtilities.VerifyServerKeyExchangeSignature(m_context, input, m_serverCertificate, null, digestBuffer); + + this.m_agreement = m_context.Crypto.CreateECDomain(m_ecConfig).CreateECDH(); + + ProcessEphemeral(point); + } + + public override short[] GetClientCertificateTypes() + { + /* + * RFC 4492 3. [...] The ECDSA_fixed_ECDH and RSA_fixed_ECDH mechanisms are usable with + * ECDH_ECDSA and ECDH_RSA. Their use with ECDHE_ECDSA and ECDHE_RSA is prohibited because + * the use of a long-term ECDH client key would jeopardize the forward secrecy property of + * these algorithms. + */ + return new short[]{ ClientCertificateType.dss_sign, ClientCertificateType.ecdsa_sign, + ClientCertificateType.rsa_sign }; + } + + public override void ProcessClientCredentials(TlsCredentials clientCredentials) + { + TlsUtilities.RequireSignerCredentials(clientCredentials); + } + + public override void GenerateClientKeyExchange(Stream output) + { + GenerateEphemeral(output); + } + + public override void ProcessClientKeyExchange(Stream input) + { + byte[] point = TlsUtilities.ReadOpaque8(input, 1); + + ProcessEphemeral(point); + } + + public override TlsSecret GeneratePreMasterSecret() + { + return m_agreement.CalculateSecret(); + } + + protected virtual void GenerateEphemeral(Stream output) + { + byte[] point = m_agreement.GenerateEphemeral(); + + TlsUtilities.WriteOpaque8(point, output); + } + + protected virtual void ProcessEphemeral(byte[] point) + { + TlsEccUtilities.CheckPointEncoding(m_ecConfig.NamedGroup, point); + + this.m_agreement.ReceivePeerValue(point); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsECDheKeyExchange.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsECDheKeyExchange.cs.meta new file mode 100644 index 0000000..5945016 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsECDheKeyExchange.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a3790eb3c0c590b449f604d572053bd0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsEccUtilities.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsEccUtilities.cs new file mode 100644 index 0000000..59320a7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsEccUtilities.cs @@ -0,0 +1,117 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Tls.Crypto; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls +{ + public abstract class TlsEccUtilities + { + /// + public static TlsECConfig CreateNamedECConfig(TlsContext context, int namedGroup) + { + if (NamedGroup.GetCurveBits(namedGroup) < 1) + throw new TlsFatalAlert(AlertDescription.internal_error); + + return new TlsECConfig(namedGroup); + } + + public static int GetMinimumCurveBits(int cipherSuite) + { + /* + * NOTE: This mechanism was added to support a minimum bit-size requirement mooted in early + * drafts of RFC 8442. This requirement was removed in later drafts, so this mechanism is + * currently somewhat trivial. + */ + return IsEccCipherSuite(cipherSuite) ? 1 : 0; + } + + public static bool IsEccCipherSuite(int cipherSuite) + { + switch (TlsUtilities.GetKeyExchangeAlgorithm(cipherSuite)) + { + case KeyExchangeAlgorithm.ECDH_anon: + case KeyExchangeAlgorithm.ECDH_ECDSA: + case KeyExchangeAlgorithm.ECDH_RSA: + case KeyExchangeAlgorithm.ECDHE_ECDSA: + case KeyExchangeAlgorithm.ECDHE_PSK: + case KeyExchangeAlgorithm.ECDHE_RSA: + return true; + + default: + return false; + } + } + + /// + public static void CheckPointEncoding(int namedGroup, byte[] encoding) + { + if (TlsUtilities.IsNullOrEmpty(encoding)) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + switch (namedGroup) + { + case NamedGroup.x25519: + case NamedGroup.x448: + return; + } + + switch (encoding[0]) + { + case 0x04: // uncompressed + return; + + case 0x00: // infinity + case 0x02: // compressed + case 0x03: // compressed + case 0x06: // hybrid + case 0x07: // hybrid + default: + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + } + + /// + public static TlsECConfig ReceiveECDHConfig(TlsContext context, Stream input) + { + short curveType = TlsUtilities.ReadUint8(input); + if (curveType != ECCurveType.named_curve) + throw new TlsFatalAlert(AlertDescription.handshake_failure); + + int namedGroup = TlsUtilities.ReadUint16(input); + if (NamedGroup.RefersToAnECDHCurve(namedGroup)) + { + int[] clientSupportedGroups = context.SecurityParameters.ClientSupportedGroups; + if (null == clientSupportedGroups || Arrays.Contains(clientSupportedGroups, namedGroup)) + return new TlsECConfig(namedGroup); + } + + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + /// + public static void WriteECConfig(TlsECConfig ecConfig, Stream output) + { + WriteNamedECParameters(ecConfig.NamedGroup, output); + } + + /// + public static void WriteNamedECParameters(int namedGroup, Stream output) + { + if (!NamedGroup.RefersToASpecificCurve(namedGroup)) + { + /* + * RFC 4492 5.4. All those values of NamedCurve are allowed that refer to a specific + * curve. Values of NamedCurve that indicate support for a class of explicitly defined + * curves are not allowed here [...]. + */ + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + TlsUtilities.WriteUint8(ECCurveType.named_curve, output); + TlsUtilities.CheckUint16(namedGroup); + TlsUtilities.WriteUint16(namedGroup, output); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsEccUtilities.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsEccUtilities.cs.meta new file mode 100644 index 0000000..c289e76 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsEccUtilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2c8851e54e818004784e3b90c38bce02 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsException.cs new file mode 100644 index 0000000..c6d7a19 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsException.cs @@ -0,0 +1,24 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Tls +{ + public class TlsException + : IOException + { + public TlsException() + : base() + { + } + + public TlsException(string message) + : base(message) + { + } + + public TlsException(string message, Exception cause) + : base(message, cause) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsException.cs.meta new file mode 100644 index 0000000..b8e91bc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e5c50a7d5c665f34290c71830d91c73b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsExtensionsUtilities.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsExtensionsUtilities.cs new file mode 100644 index 0000000..688fee3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsExtensionsUtilities.cs @@ -0,0 +1,1377 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls +{ + public abstract class TlsExtensionsUtilities + { + public static IDictionary EnsureExtensionsInitialised(IDictionary extensions) + { + return extensions == null ? Platform.CreateHashtable() : extensions; + } + + /// (Int32 -> byte[]) + /// an of . + /// + public static void AddAlpnExtensionClient(IDictionary extensions, IList protocolNameList) + { + extensions[ExtensionType.application_layer_protocol_negotiation] = CreateAlpnExtensionClient(protocolNameList); + } + + /// + public static void AddAlpnExtensionServer(IDictionary extensions, ProtocolName protocolName) + { + extensions[ExtensionType.application_layer_protocol_negotiation] = CreateAlpnExtensionServer(protocolName); + } + + /// + public static void AddCertificateAuthoritiesExtension(IDictionary extensions, IList authorities) + { + extensions[ExtensionType.certificate_authorities] = CreateCertificateAuthoritiesExtension(authorities); + } + + /// + public static void AddClientCertificateTypeExtensionClient(IDictionary extensions, short[] certificateTypes) + { + extensions[ExtensionType.client_certificate_type] = CreateCertificateTypeExtensionClient(certificateTypes); + } + + /// + public static void AddClientCertificateTypeExtensionServer(IDictionary extensions, short certificateType) + { + extensions[ExtensionType.client_certificate_type] = CreateCertificateTypeExtensionServer(certificateType); + } + + public static void AddClientCertificateUrlExtension(IDictionary extensions) + { + extensions[ExtensionType.client_certificate_url] = CreateClientCertificateUrlExtension(); + } + + /// + public static void AddCookieExtension(IDictionary extensions, byte[] cookie) + { + extensions[ExtensionType.cookie] = CreateCookieExtension(cookie); + } + + public static void AddEarlyDataIndication(IDictionary extensions) + { + extensions[ExtensionType.early_data] = CreateEarlyDataIndication(); + } + + /// + public static void AddEarlyDataMaxSize(IDictionary extensions, long maxSize) + { + extensions[ExtensionType.early_data] = CreateEarlyDataMaxSize(maxSize); + } + + public static void AddEmptyExtensionData(IDictionary extensions, Int32 extType) + { + extensions[extType] = CreateEmptyExtensionData(); + } + + public static void AddEncryptThenMacExtension(IDictionary extensions) + { + extensions[ExtensionType.encrypt_then_mac] = CreateEncryptThenMacExtension(); + } + + public static void AddExtendedMasterSecretExtension(IDictionary extensions) + { + extensions[ExtensionType.extended_master_secret] = CreateExtendedMasterSecretExtension(); + } + + /// + public static void AddHeartbeatExtension(IDictionary extensions, HeartbeatExtension heartbeatExtension) + { + extensions[ExtensionType.heartbeat] = CreateHeartbeatExtension(heartbeatExtension); + } + + /// + public static void AddKeyShareClientHello(IDictionary extensions, IList clientShares) + { + extensions[ExtensionType.key_share] = CreateKeyShareClientHello(clientShares); + } + + /// + public static void AddKeyShareHelloRetryRequest(IDictionary extensions, int namedGroup) + { + extensions[ExtensionType.key_share] = CreateKeyShareHelloRetryRequest(namedGroup); + } + + /// + public static void AddKeyShareServerHello(IDictionary extensions, KeyShareEntry serverShare) + { + extensions[ExtensionType.key_share] = CreateKeyShareServerHello(serverShare); + } + + /// + public static void AddMaxFragmentLengthExtension(IDictionary extensions, short maxFragmentLength) + { + extensions[ExtensionType.max_fragment_length] = CreateMaxFragmentLengthExtension(maxFragmentLength); + } + + /// + public static void AddOidFiltersExtension(IDictionary extensions, IDictionary filters) + { + extensions[ExtensionType.oid_filters] = CreateOidFiltersExtension(filters); + } + + /// + public static void AddPaddingExtension(IDictionary extensions, int dataLength) + { + extensions[ExtensionType.padding] = CreatePaddingExtension(dataLength); + } + + public static void AddPostHandshakeAuthExtension(IDictionary extensions) + { + extensions[ExtensionType.post_handshake_auth] = CreatePostHandshakeAuthExtension(); + } + + /// + public static void AddPreSharedKeyClientHello(IDictionary extensions, OfferedPsks offeredPsks) + { + extensions[ExtensionType.pre_shared_key] = CreatePreSharedKeyClientHello(offeredPsks); + } + + /// + public static void AddPreSharedKeyServerHello(IDictionary extensions, int selectedIdentity) + { + extensions[ExtensionType.pre_shared_key] = CreatePreSharedKeyServerHello(selectedIdentity); + } + + /// + public static void AddPskKeyExchangeModesExtension(IDictionary extensions, short[] modes) + { + extensions[ExtensionType.psk_key_exchange_modes] = CreatePskKeyExchangeModesExtension(modes); + } + + /// + public static void AddRecordSizeLimitExtension(IDictionary extensions, int recordSizeLimit) + { + extensions[ExtensionType.record_size_limit] = CreateRecordSizeLimitExtension(recordSizeLimit); + } + + /// + public static void AddServerCertificateTypeExtensionClient(IDictionary extensions, short[] certificateTypes) + { + extensions[ExtensionType.server_certificate_type] = CreateCertificateTypeExtensionClient(certificateTypes); + } + + /// + public static void AddServerCertificateTypeExtensionServer(IDictionary extensions, short certificateType) + { + extensions[ExtensionType.server_certificate_type] = CreateCertificateTypeExtensionServer(certificateType); + } + + /// + public static void AddServerNameExtensionClient(IDictionary extensions, IList serverNameList) + { + extensions[ExtensionType.server_name] = CreateServerNameExtensionClient(serverNameList); + } + + /// + public static void AddServerNameExtensionServer(IDictionary extensions) + { + extensions[ExtensionType.server_name] = CreateServerNameExtensionServer(); + } + + /// + public static void AddSignatureAlgorithmsExtension(IDictionary extensions, IList supportedSignatureAlgorithms) + { + extensions[ExtensionType.signature_algorithms] = CreateSignatureAlgorithmsExtension(supportedSignatureAlgorithms); + } + + /// + public static void AddSignatureAlgorithmsCertExtension(IDictionary extensions, IList supportedSignatureAlgorithms) + { + extensions[ExtensionType.signature_algorithms_cert] = CreateSignatureAlgorithmsCertExtension(supportedSignatureAlgorithms); + } + + /// + public static void AddStatusRequestExtension(IDictionary extensions, CertificateStatusRequest statusRequest) + { + extensions[ExtensionType.status_request] = CreateStatusRequestExtension(statusRequest); + } + + /// + public static void AddStatusRequestV2Extension(IDictionary extensions, IList statusRequestV2) + { + extensions[ExtensionType.status_request_v2] = CreateStatusRequestV2Extension(statusRequestV2); + } + + /// + public static void AddSupportedGroupsExtension(IDictionary extensions, IList namedGroups) + { + extensions[ExtensionType.supported_groups] = CreateSupportedGroupsExtension(namedGroups); + } + + /// + public static void AddSupportedPointFormatsExtension(IDictionary extensions, short[] ecPointFormats) + { + extensions[ExtensionType.ec_point_formats] = CreateSupportedPointFormatsExtension(ecPointFormats); + } + + /// + public static void AddSupportedVersionsExtensionClient(IDictionary extensions, ProtocolVersion[] versions) + { + extensions[ExtensionType.supported_versions] = CreateSupportedVersionsExtensionClient(versions); + } + + /// + public static void AddSupportedVersionsExtensionServer(IDictionary extensions, ProtocolVersion selectedVersion) + { + extensions[ExtensionType.supported_versions] = CreateSupportedVersionsExtensionServer(selectedVersion); + } + + public static void AddTruncatedHmacExtension(IDictionary extensions) + { + extensions[ExtensionType.truncated_hmac] = CreateTruncatedHmacExtension(); + } + + /// + public static void AddTrustedCAKeysExtensionClient(IDictionary extensions, IList trustedAuthoritiesList) + { + extensions[ExtensionType.trusted_ca_keys] = CreateTrustedCAKeysExtensionClient(trustedAuthoritiesList); + } + + public static void AddTrustedCAKeysExtensionServer(IDictionary extensions) + { + extensions[ExtensionType.trusted_ca_keys] = CreateTrustedCAKeysExtensionServer(); + } + + /// an of . + /// + public static IList GetAlpnExtensionClient(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.application_layer_protocol_negotiation); + return extensionData == null ? null : ReadAlpnExtensionClient(extensionData); + } + + /// + public static ProtocolName GetAlpnExtensionServer(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.application_layer_protocol_negotiation); + return extensionData == null ? null : ReadAlpnExtensionServer(extensionData); + } + + /// + public static IList GetCertificateAuthoritiesExtension(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.certificate_authorities); + return extensionData == null ? null : ReadCertificateAuthoritiesExtension(extensionData); + } + + /// + public static short[] GetClientCertificateTypeExtensionClient(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.client_certificate_type); + return extensionData == null ? null : ReadCertificateTypeExtensionClient(extensionData); + } + + /// + public static short GetClientCertificateTypeExtensionServer(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.client_certificate_type); + return extensionData == null ? (short)-1 : ReadCertificateTypeExtensionServer(extensionData); + } + + /// + public static byte[] GetCookieExtension(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.cookie); + return extensionData == null ? null : ReadCookieExtension(extensionData); + } + + /// + public static long GetEarlyDataMaxSize(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.early_data); + return extensionData == null ? -1L : ReadEarlyDataMaxSize(extensionData); + } + + /// + public static HeartbeatExtension GetHeartbeatExtension(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.heartbeat); + return extensionData == null ? null : ReadHeartbeatExtension(extensionData); + } + + /// + public static IList GetKeyShareClientHello(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.key_share); + return extensionData == null ? null : ReadKeyShareClientHello(extensionData); + } + + /// + public static int GetKeyShareHelloRetryRequest(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.key_share); + return extensionData == null ? -1 : ReadKeyShareHelloRetryRequest(extensionData); + } + + /// + public static KeyShareEntry GetKeyShareServerHello(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.key_share); + return extensionData == null ? null : ReadKeyShareServerHello(extensionData); + } + + /// + public static short GetMaxFragmentLengthExtension(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.max_fragment_length); + return extensionData == null ? (short)-1 : ReadMaxFragmentLengthExtension(extensionData); + } + + /// + public static IDictionary GetOidFiltersExtension(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.oid_filters); + return extensionData == null ? null : ReadOidFiltersExtension(extensionData); + } + + /// + public static int GetPaddingExtension(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.padding); + return extensionData == null ? -1 : ReadPaddingExtension(extensionData); + } + + /// + public static OfferedPsks GetPreSharedKeyClientHello(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.pre_shared_key); + return extensionData == null ? null : ReadPreSharedKeyClientHello(extensionData); + } + + /// + public static int GetPreSharedKeyServerHello(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.pre_shared_key); + return extensionData == null ? -1 : ReadPreSharedKeyServerHello(extensionData); + } + + /// + public static short[] GetPskKeyExchangeModesExtension(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.psk_key_exchange_modes); + return extensionData == null ? null : ReadPskKeyExchangeModesExtension(extensionData); + } + + /// + public static int GetRecordSizeLimitExtension(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.record_size_limit); + return extensionData == null ? -1 : ReadRecordSizeLimitExtension(extensionData); + } + + /// + public static short[] GetServerCertificateTypeExtensionClient(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.server_certificate_type); + return extensionData == null ? null : ReadCertificateTypeExtensionClient(extensionData); + } + + /// + public static short GetServerCertificateTypeExtensionServer(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.server_certificate_type); + return extensionData == null ? (short)-1 : ReadCertificateTypeExtensionServer(extensionData); + } + + /// + public static IList GetServerNameExtensionClient(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.server_name); + return extensionData == null ? null : ReadServerNameExtensionClient(extensionData); + } + + /// + public static IList GetSignatureAlgorithmsExtension(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.signature_algorithms); + return extensionData == null ? null : ReadSignatureAlgorithmsExtension(extensionData); + } + + /// + public static IList GetSignatureAlgorithmsCertExtension(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.signature_algorithms_cert); + return extensionData == null ? null : ReadSignatureAlgorithmsCertExtension(extensionData); + } + + /// + public static CertificateStatusRequest GetStatusRequestExtension(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.status_request); + return extensionData == null ? null : ReadStatusRequestExtension(extensionData); + } + + /// + public static IList GetStatusRequestV2Extension(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.status_request_v2); + return extensionData == null ? null : ReadStatusRequestV2Extension(extensionData); + } + + /// + public static int[] GetSupportedGroupsExtension(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.supported_groups); + return extensionData == null ? null : ReadSupportedGroupsExtension(extensionData); + } + + /// + public static short[] GetSupportedPointFormatsExtension(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.ec_point_formats); + return extensionData == null ? null : ReadSupportedPointFormatsExtension(extensionData); + } + + /// + public static ProtocolVersion[] GetSupportedVersionsExtensionClient(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.supported_versions); + return extensionData == null ? null : ReadSupportedVersionsExtensionClient(extensionData); + } + + /// + public static ProtocolVersion GetSupportedVersionsExtensionServer(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.supported_versions); + return extensionData == null ? null : ReadSupportedVersionsExtensionServer(extensionData); + } + + /// + public static IList GetTrustedCAKeysExtensionClient(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.trusted_ca_keys); + return extensionData == null ? null : ReadTrustedCAKeysExtensionClient(extensionData); + } + + /// + public static bool HasClientCertificateUrlExtension(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.client_certificate_url); + return extensionData == null ? false : ReadClientCertificateUrlExtension(extensionData); + } + + /// + public static bool HasEarlyDataIndication(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.early_data); + return extensionData == null ? false : ReadEarlyDataIndication(extensionData); + } + + /// + public static bool HasEncryptThenMacExtension(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.encrypt_then_mac); + return extensionData == null ? false : ReadEncryptThenMacExtension(extensionData); + } + + /// + public static bool HasExtendedMasterSecretExtension(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.extended_master_secret); + return extensionData == null ? false : ReadExtendedMasterSecretExtension(extensionData); + } + + /// + public static bool HasServerNameExtensionServer(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.server_name); + return extensionData == null ? false : ReadServerNameExtensionServer(extensionData); + } + + /// + public static bool HasPostHandshakeAuthExtension(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.post_handshake_auth); + return extensionData == null ? false : ReadPostHandshakeAuthExtension(extensionData); + } + + /// + public static bool HasTruncatedHmacExtension(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.truncated_hmac); + return extensionData == null ? false : ReadTruncatedHmacExtension(extensionData); + } + + /// + public static bool HasTrustedCAKeysExtensionServer(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.trusted_ca_keys); + return extensionData == null ? false : ReadTrustedCAKeysExtensionServer(extensionData); + } + + /// an of . + /// + public static byte[] CreateAlpnExtensionClient(IList protocolNameList) + { + if (protocolNameList == null || protocolNameList.Count < 1) + throw new TlsFatalAlert(AlertDescription.internal_error); + + MemoryStream buf = new MemoryStream(); + + // Placeholder for length + TlsUtilities.WriteUint16(0, buf); + + foreach (ProtocolName protocolName in protocolNameList) + { + protocolName.Encode(buf); + } + + return PatchOpaque16(buf); + } + + /// + public static byte[] CreateAlpnExtensionServer(ProtocolName protocolName) + { + IList protocol_name_list = Platform.CreateArrayList(); + protocol_name_list.Add(protocolName); + + return CreateAlpnExtensionClient(protocol_name_list); + } + + /// + public static byte[] CreateCertificateAuthoritiesExtension(IList authorities) + { + if (null == authorities || authorities.Count < 1) + throw new TlsFatalAlert(AlertDescription.internal_error); + + MemoryStream buf = new MemoryStream(); + + // Placeholder for length + TlsUtilities.WriteUint16(0, buf); + + foreach (X509Name authority in authorities) + { + byte[] derEncoding = authority.GetEncoded(Asn1Encodable.Der); + TlsUtilities.WriteOpaque16(derEncoding, buf); + } + + return PatchOpaque16(buf); + } + + /// + public static byte[] CreateCertificateTypeExtensionClient(short[] certificateTypes) + { + if (TlsUtilities.IsNullOrEmpty(certificateTypes) || certificateTypes.Length > 255) + throw new TlsFatalAlert(AlertDescription.internal_error); + + return TlsUtilities.EncodeUint8ArrayWithUint8Length(certificateTypes); + } + + /// + public static byte[] CreateCertificateTypeExtensionServer(short certificateType) + { + return TlsUtilities.EncodeUint8(certificateType); + } + + public static byte[] CreateClientCertificateUrlExtension() + { + return CreateEmptyExtensionData(); + } + + /// + public static byte[] CreateCookieExtension(byte[] cookie) + { + if (TlsUtilities.IsNullOrEmpty(cookie) || cookie.Length >= (1 << 16)) + throw new TlsFatalAlert(AlertDescription.internal_error); + + return TlsUtilities.EncodeOpaque16(cookie); + } + + public static byte[] CreateEarlyDataIndication() + { + return CreateEmptyExtensionData(); + } + + /// + public static byte[] CreateEarlyDataMaxSize(long maxSize) + { + return TlsUtilities.EncodeUint32(maxSize); + } + + public static byte[] CreateEmptyExtensionData() + { + return TlsUtilities.EmptyBytes; + } + + public static byte[] CreateEncryptThenMacExtension() + { + return CreateEmptyExtensionData(); + } + + public static byte[] CreateExtendedMasterSecretExtension() + { + return CreateEmptyExtensionData(); + } + + /// + public static byte[] CreateHeartbeatExtension(HeartbeatExtension heartbeatExtension) + { + if (heartbeatExtension == null) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + MemoryStream buf = new MemoryStream(); + + heartbeatExtension.Encode(buf); + + return buf.ToArray(); + } + + /// + public static byte[] CreateKeyShareClientHello(IList clientShares) + { + if (clientShares == null || clientShares.Count < 1) + return TlsUtilities.EncodeUint16(0); + + MemoryStream buf = new MemoryStream(); + + // Placeholder for length + TlsUtilities.WriteUint16(0, buf); + + foreach (KeyShareEntry clientShare in clientShares) + { + clientShare.Encode(buf); + } + + return PatchOpaque16(buf); + } + + /// + public static byte[] CreateKeyShareHelloRetryRequest(int namedGroup) + { + return TlsUtilities.EncodeUint16(namedGroup); + } + + /// + public static byte[] CreateKeyShareServerHello(KeyShareEntry serverShare) + { + if (serverShare == null) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + MemoryStream buf = new MemoryStream(); + + serverShare.Encode(buf); + + return buf.ToArray(); + } + + /// + public static byte[] CreateMaxFragmentLengthExtension(short maxFragmentLength) + { + return TlsUtilities.EncodeUint8(maxFragmentLength); + } + + /// + public static byte[] CreateOidFiltersExtension(IDictionary filters) + { + MemoryStream buf = new MemoryStream(); + + // Placeholder for length + TlsUtilities.WriteUint16(0, buf); + + if (null != filters) + { + foreach (DerObjectIdentifier certificateExtensionOid in filters.Keys) + { + byte[] certificateExtensionValues = (byte[])filters[certificateExtensionOid]; + + if (null == certificateExtensionOid || null == certificateExtensionValues) + throw new TlsFatalAlert(AlertDescription.internal_error); + + byte[] derEncoding = certificateExtensionOid.GetEncoded(Asn1Encodable.Der); + TlsUtilities.WriteOpaque8(derEncoding, buf); + + TlsUtilities.WriteOpaque16(certificateExtensionValues, buf); + } + } + + return PatchOpaque16(buf); + } + + /// + public static byte[] CreatePaddingExtension(int dataLength) + { + TlsUtilities.CheckUint16(dataLength); + return new byte[dataLength]; + } + + public static byte[] CreatePostHandshakeAuthExtension() + { + return CreateEmptyExtensionData(); + } + + /// + public static byte[] CreatePreSharedKeyClientHello(OfferedPsks offeredPsks) + { + if (offeredPsks == null) + throw new TlsFatalAlert(AlertDescription.internal_error); + + MemoryStream buf = new MemoryStream(); + + offeredPsks.Encode(buf); + + return buf.ToArray(); + } + + /// + public static byte[] CreatePreSharedKeyServerHello(int selectedIdentity) + { + return TlsUtilities.EncodeUint16(selectedIdentity); + } + + /// + public static byte[] CreatePskKeyExchangeModesExtension(short[] modes) + { + if (TlsUtilities.IsNullOrEmpty(modes) || modes.Length > 255) + throw new TlsFatalAlert(AlertDescription.internal_error); + + return TlsUtilities.EncodeUint8ArrayWithUint8Length(modes); + } + + /// + public static byte[] CreateRecordSizeLimitExtension(int recordSizeLimit) + { + if (recordSizeLimit < 64) + throw new TlsFatalAlert(AlertDescription.internal_error); + + return TlsUtilities.EncodeUint16(recordSizeLimit); + } + + /// + public static byte[] CreateServerNameExtensionClient(IList serverNameList) + { + if (serverNameList == null) + throw new TlsFatalAlert(AlertDescription.internal_error); + + MemoryStream buf = new MemoryStream(); + + new ServerNameList(serverNameList).Encode(buf); + + return buf.ToArray(); + } + + public static byte[] CreateServerNameExtensionServer() + { + return CreateEmptyExtensionData(); + } + + /// + public static byte[] CreateSignatureAlgorithmsExtension(IList supportedSignatureAlgorithms) + { + MemoryStream buf = new MemoryStream(); + + TlsUtilities.EncodeSupportedSignatureAlgorithms(supportedSignatureAlgorithms, buf); + + return buf.ToArray(); + } + + /// + public static byte[] CreateSignatureAlgorithmsCertExtension(IList supportedSignatureAlgorithms) + { + return CreateSignatureAlgorithmsExtension(supportedSignatureAlgorithms); + } + + /// + public static byte[] CreateStatusRequestExtension(CertificateStatusRequest statusRequest) + { + if (statusRequest == null) + throw new TlsFatalAlert(AlertDescription.internal_error); + + MemoryStream buf = new MemoryStream(); + + statusRequest.Encode(buf); + + return buf.ToArray(); + } + + /// + public static byte[] CreateStatusRequestV2Extension(IList statusRequestV2) + { + if (statusRequestV2 == null || statusRequestV2.Count < 1) + throw new TlsFatalAlert(AlertDescription.internal_error); + + MemoryStream buf = new MemoryStream(); + + // Placeholder for length + TlsUtilities.WriteUint16(0, buf); + + foreach (CertificateStatusRequestItemV2 entry in statusRequestV2) + { + entry.Encode(buf); + } + + return PatchOpaque16(buf); + } + + /// + public static byte[] CreateSupportedGroupsExtension(IList namedGroups) + { + if (namedGroups == null || namedGroups.Count < 1) + throw new TlsFatalAlert(AlertDescription.internal_error); + + int count = namedGroups.Count; + int[] values = new int[count]; + for (int i = 0; i < count; ++i) + { + values[i] = (Int32)namedGroups[i]; + } + + return TlsUtilities.EncodeUint16ArrayWithUint16Length(values); + } + + /// + public static byte[] CreateSupportedPointFormatsExtension(short[] ecPointFormats) + { + if (ecPointFormats == null || !Arrays.Contains(ecPointFormats, ECPointFormat.uncompressed)) + { + /* + * RFC 4492 5.1. If the Supported Point Formats Extension is indeed sent, it MUST + * contain the value 0 (uncompressed) as one of the items in the list of point formats. + */ + + // NOTE: We add it at the start (highest preference) + ecPointFormats = Arrays.Prepend(ecPointFormats, ECPointFormat.uncompressed); + } + + return TlsUtilities.EncodeUint8ArrayWithUint8Length(ecPointFormats); + } + + /// + public static byte[] CreateSupportedVersionsExtensionClient(ProtocolVersion[] versions) + { + if (TlsUtilities.IsNullOrEmpty(versions) || versions.Length > 127) + throw new TlsFatalAlert(AlertDescription.internal_error); + + int count = versions.Length; + byte[] data = new byte[1 + count * 2]; + TlsUtilities.WriteUint8(count * 2, data, 0); + for (int i = 0; i < count; ++i) + { + TlsUtilities.WriteVersion((ProtocolVersion)versions[i], data, 1 + i * 2); + } + return data; + } + + /// + public static byte[] CreateSupportedVersionsExtensionServer(ProtocolVersion selectedVersion) + { + return TlsUtilities.EncodeVersion(selectedVersion); + } + + public static byte[] CreateTruncatedHmacExtension() + { + return CreateEmptyExtensionData(); + } + + /// + public static byte[] CreateTrustedCAKeysExtensionClient(IList trustedAuthoritiesList) + { + MemoryStream buf = new MemoryStream(); + + // Placeholder for length + TlsUtilities.WriteUint16(0, buf); + + if (trustedAuthoritiesList != null) + { + foreach (TrustedAuthority entry in trustedAuthoritiesList) + { + entry.Encode(buf); + } + } + + return PatchOpaque16(buf); + } + + public static byte[] CreateTrustedCAKeysExtensionServer() + { + return CreateEmptyExtensionData(); + } + + /// + private static bool ReadEmptyExtensionData(byte[] extensionData) + { + if (extensionData == null) + throw new ArgumentNullException("extensionData"); + + if (extensionData.Length != 0) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + return true; + } + + /// an of . + /// + public static IList ReadAlpnExtensionClient(byte[] extensionData) + { + if (extensionData == null) + throw new ArgumentNullException("extensionData"); + + MemoryStream buf = new MemoryStream(extensionData); + + int length = TlsUtilities.ReadUint16(buf); + if (length != (extensionData.Length - 2)) + throw new TlsFatalAlert(AlertDescription.decode_error); + + IList protocol_name_list = Platform.CreateArrayList(); + while (buf.Position < buf.Length) + { + ProtocolName protocolName = ProtocolName.Parse(buf); + + protocol_name_list.Add(protocolName); + } + return protocol_name_list; + } + + /// + public static ProtocolName ReadAlpnExtensionServer(byte[] extensionData) + { + IList protocol_name_list = ReadAlpnExtensionClient(extensionData); + if (protocol_name_list.Count != 1) + throw new TlsFatalAlert(AlertDescription.decode_error); + + return (ProtocolName)protocol_name_list[0]; + } + + /// + public static IList ReadCertificateAuthoritiesExtension(byte[] extensionData) + { + if (extensionData == null) + throw new ArgumentNullException("extensionData"); + if (extensionData.Length < 5) + throw new TlsFatalAlert(AlertDescription.decode_error); + + MemoryStream buf = new MemoryStream(extensionData); + + int length = TlsUtilities.ReadUint16(buf); + if (length != (extensionData.Length - 2)) + throw new TlsFatalAlert(AlertDescription.decode_error); + + IList authorities = Platform.CreateArrayList(); + while (buf.Position < buf.Length) + { + byte[] derEncoding = TlsUtilities.ReadOpaque16(buf, 1); + Asn1Object asn1 = TlsUtilities.ReadDerObject(derEncoding); + authorities.Add(X509Name.GetInstance(asn1)); + } + return authorities; + } + + /// + public static short[] ReadCertificateTypeExtensionClient(byte[] extensionData) + { + short[] certificateTypes = TlsUtilities.DecodeUint8ArrayWithUint8Length(extensionData); + if (certificateTypes.Length < 1) + throw new TlsFatalAlert(AlertDescription.decode_error); + + return certificateTypes; + } + + /// + public static short ReadCertificateTypeExtensionServer(byte[] extensionData) + { + return TlsUtilities.DecodeUint8(extensionData); + } + + /// + public static bool ReadClientCertificateUrlExtension(byte[] extensionData) + { + return ReadEmptyExtensionData(extensionData); + } + + /// + public static byte[] ReadCookieExtension(byte[] extensionData) + { + return TlsUtilities.DecodeOpaque16(extensionData, 1); + } + + /// + public static bool ReadEarlyDataIndication(byte[] extensionData) + { + return ReadEmptyExtensionData(extensionData); + } + + /// + public static long ReadEarlyDataMaxSize(byte[] extensionData) + { + return TlsUtilities.DecodeUint32(extensionData); + } + + /// + public static bool ReadEncryptThenMacExtension(byte[] extensionData) + { + return ReadEmptyExtensionData(extensionData); + } + + /// + public static bool ReadExtendedMasterSecretExtension(byte[] extensionData) + { + return ReadEmptyExtensionData(extensionData); + } + + /// + public static HeartbeatExtension ReadHeartbeatExtension(byte[] extensionData) + { + if (extensionData == null) + throw new ArgumentNullException("extensionData"); + + MemoryStream buf = new MemoryStream(extensionData, false); + + HeartbeatExtension heartbeatExtension = HeartbeatExtension.Parse(buf); + + TlsProtocol.AssertEmpty(buf); + + return heartbeatExtension; + } + + /// + public static IList ReadKeyShareClientHello(byte[] extensionData) + { + if (extensionData == null) + throw new ArgumentNullException("extensionData"); + + /* + * TODO[tls13] Clients MUST NOT offer multiple KeyShareEntry values for the same group. + * Clients MUST NOT offer any KeyShareEntry values for groups not listed in the client's + * "supported_groups" extension. Servers MAY check for violations of these rules and abort + * the handshake with an "illegal_parameter" alert if one is violated. + */ + + MemoryStream buf = new MemoryStream(extensionData, false); + + int length = TlsUtilities.ReadUint16(buf); + if (length != (extensionData.Length - 2)) + throw new TlsFatalAlert(AlertDescription.decode_error); + + IList clientShares = Platform.CreateArrayList(); + while (buf.Position < buf.Length) + { + KeyShareEntry clientShare = KeyShareEntry.Parse(buf); + + clientShares.Add(clientShare); + } + return clientShares; + } + + /// + public static int ReadKeyShareHelloRetryRequest(byte[] extensionData) + { + return TlsUtilities.DecodeUint16(extensionData); + } + + /// + public static KeyShareEntry ReadKeyShareServerHello(byte[] extensionData) + { + if (extensionData == null) + throw new ArgumentNullException("extensionData"); + + MemoryStream buf = new MemoryStream(extensionData, false); + + KeyShareEntry serverShare = KeyShareEntry.Parse(buf); + + TlsProtocol.AssertEmpty(buf); + + return serverShare; + } + + /// + public static short ReadMaxFragmentLengthExtension(byte[] extensionData) + { + return TlsUtilities.DecodeUint8(extensionData); + } + + /// + public static IDictionary ReadOidFiltersExtension(byte[] extensionData) + { + if (extensionData == null) + throw new ArgumentNullException("extensionData"); + if (extensionData.Length < 2) + throw new TlsFatalAlert(AlertDescription.decode_error); + + MemoryStream buf = new MemoryStream(extensionData, false); + + int length = TlsUtilities.ReadUint16(buf); + if (length != (extensionData.Length - 2)) + throw new TlsFatalAlert(AlertDescription.decode_error); + + IDictionary filters = Platform.CreateHashtable(); + while (buf.Position < buf.Length) + { + byte[] derEncoding = TlsUtilities.ReadOpaque8(buf, 1); + Asn1Object asn1 = TlsUtilities.ReadDerObject(derEncoding); + DerObjectIdentifier certificateExtensionOid = DerObjectIdentifier.GetInstance(asn1); + + if (filters.Contains(certificateExtensionOid)) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + byte[] certificateExtensionValues = TlsUtilities.ReadOpaque16(buf); + + filters[certificateExtensionOid] = certificateExtensionValues; + } + return filters; + } + + /// + public static int ReadPaddingExtension(byte[] extensionData) + { + if (extensionData == null) + throw new ArgumentNullException("extensionData"); + + if (!Arrays.AreAllZeroes(extensionData, 0, extensionData.Length)) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + return extensionData.Length; + } + + /// + public static bool ReadPostHandshakeAuthExtension(byte[] extensionData) + { + return ReadEmptyExtensionData(extensionData); + } + + /// + public static OfferedPsks ReadPreSharedKeyClientHello(byte[] extensionData) + { + if (extensionData == null) + throw new ArgumentNullException("extensionData"); + + MemoryStream buf = new MemoryStream(extensionData, false); + + OfferedPsks offeredPsks = OfferedPsks.Parse(buf); + + TlsProtocol.AssertEmpty(buf); + + return offeredPsks; + } + + /// + public static int ReadPreSharedKeyServerHello(byte[] extensionData) + { + return TlsUtilities.DecodeUint16(extensionData); + } + + /// + public static short[] ReadPskKeyExchangeModesExtension(byte[] extensionData) + { + short[] modes = TlsUtilities.DecodeUint8ArrayWithUint8Length(extensionData); + if (modes.Length < 1) + throw new TlsFatalAlert(AlertDescription.decode_error); + + return modes; + } + + /// + public static int ReadRecordSizeLimitExtension(byte[] extensionData) + { + int recordSizeLimit = TlsUtilities.DecodeUint16(extensionData); + if (recordSizeLimit < 64) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + return recordSizeLimit; + } + + /// + public static IList ReadServerNameExtensionClient(byte[] extensionData) + { + if (extensionData == null) + throw new ArgumentNullException("extensionData"); + + MemoryStream buf = new MemoryStream(extensionData, false); + + ServerNameList serverNameList = ServerNameList.Parse(buf); + + TlsProtocol.AssertEmpty(buf); + + return serverNameList.ServerNames; + } + + /// + public static bool ReadServerNameExtensionServer(byte[] extensionData) + { + return ReadEmptyExtensionData(extensionData); + } + + /// + public static IList ReadSignatureAlgorithmsExtension(byte[] extensionData) + { + if (extensionData == null) + throw new ArgumentNullException("extensionData"); + + MemoryStream buf = new MemoryStream(extensionData, false); + + IList supported_signature_algorithms = TlsUtilities.ParseSupportedSignatureAlgorithms(buf); + + TlsProtocol.AssertEmpty(buf); + + return supported_signature_algorithms; + } + + /// + public static IList ReadSignatureAlgorithmsCertExtension(byte[] extensionData) + { + return ReadSignatureAlgorithmsExtension(extensionData); + } + + /// + public static CertificateStatusRequest ReadStatusRequestExtension(byte[] extensionData) + { + if (extensionData == null) + throw new ArgumentNullException("extensionData"); + + MemoryStream buf = new MemoryStream(extensionData, false); + + CertificateStatusRequest statusRequest = CertificateStatusRequest.Parse(buf); + + TlsProtocol.AssertEmpty(buf); + + return statusRequest; + } + + /// + public static IList ReadStatusRequestV2Extension(byte[] extensionData) + { + if (extensionData == null) + throw new ArgumentNullException("extensionData"); + if (extensionData.Length < 3) + throw new TlsFatalAlert(AlertDescription.decode_error); + + MemoryStream buf = new MemoryStream(extensionData, false); + + int length = TlsUtilities.ReadUint16(buf); + if (length != (extensionData.Length - 2)) + throw new TlsFatalAlert(AlertDescription.decode_error); + + IList statusRequestV2 = Platform.CreateArrayList(); + while (buf.Position < buf.Length) + { + CertificateStatusRequestItemV2 entry = CertificateStatusRequestItemV2.Parse(buf); + statusRequestV2.Add(entry); + } + return statusRequestV2; + } + + /// + public static int[] ReadSupportedGroupsExtension(byte[] extensionData) + { + if (extensionData == null) + throw new ArgumentNullException("extensionData"); + + MemoryStream buf = new MemoryStream(extensionData, false); + + int length = TlsUtilities.ReadUint16(buf); + if (length < 2 || (length & 1) != 0) + throw new TlsFatalAlert(AlertDescription.decode_error); + + int[] namedGroups = TlsUtilities.ReadUint16Array(length / 2, buf); + + TlsProtocol.AssertEmpty(buf); + + return namedGroups; + } + + /// + public static short[] ReadSupportedPointFormatsExtension(byte[] extensionData) + { + short[] ecPointFormats = TlsUtilities.DecodeUint8ArrayWithUint8Length(extensionData); + if (!Arrays.Contains(ecPointFormats, ECPointFormat.uncompressed)) + { + /* + * RFC 4492 5.1. If the Supported Point Formats Extension is indeed sent, it MUST + * contain the value 0 (uncompressed) as one of the items in the list of point formats. + */ + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + return ecPointFormats; + } + + /// + public static ProtocolVersion[] ReadSupportedVersionsExtensionClient(byte[] extensionData) + { + if (extensionData == null) + throw new ArgumentNullException("extensionData"); + if (extensionData.Length < 3 || extensionData.Length > 255 || (extensionData.Length & 1) == 0) + throw new TlsFatalAlert(AlertDescription.decode_error); + + int length = TlsUtilities.ReadUint8(extensionData, 0); + if (length != (extensionData.Length - 1)) + throw new TlsFatalAlert(AlertDescription.decode_error); + + int count = length / 2; + ProtocolVersion[] versions = new ProtocolVersion[count]; + for (int i = 0; i < count; ++i) + { + versions[i] = TlsUtilities.ReadVersion(extensionData, 1 + i * 2); + } + return versions; + } + + /// + public static ProtocolVersion ReadSupportedVersionsExtensionServer(byte[] extensionData) + { + if (extensionData == null) + throw new ArgumentNullException("extensionData"); + if (extensionData.Length != 2) + throw new TlsFatalAlert(AlertDescription.decode_error); + + return TlsUtilities.ReadVersion(extensionData, 0); + } + + /// + public static bool ReadTruncatedHmacExtension(byte[] extensionData) + { + return ReadEmptyExtensionData(extensionData); + } + + /// + public static IList ReadTrustedCAKeysExtensionClient(byte[] extensionData) + { + if (extensionData == null) + throw new ArgumentNullException("extensionData"); + if (extensionData.Length < 2) + throw new TlsFatalAlert(AlertDescription.decode_error); + + MemoryStream buf = new MemoryStream(extensionData, false); + + int length = TlsUtilities.ReadUint16(buf); + if (length != (extensionData.Length - 2)) + throw new TlsFatalAlert(AlertDescription.decode_error); + + IList trusted_authorities_list = Platform.CreateArrayList(); + while (buf.Position < buf.Length) + { + TrustedAuthority entry = TrustedAuthority.Parse(buf); + trusted_authorities_list.Add(entry); + } + return trusted_authorities_list; + } + + /// + public static bool ReadTrustedCAKeysExtensionServer(byte[] extensionData) + { + return ReadEmptyExtensionData(extensionData); + } + + /// + private static byte[] PatchOpaque16(MemoryStream buf) + { + int length = (int)buf.Length - 2; + TlsUtilities.CheckUint16(length); + byte[] extensionData = buf.ToArray(); + TlsUtilities.WriteUint16(length, extensionData, 0); + return extensionData; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsExtensionsUtilities.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsExtensionsUtilities.cs.meta new file mode 100644 index 0000000..56df423 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsExtensionsUtilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d0701541b3fdb4b4a833e26b1b6cbddd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsFatalAlert.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsFatalAlert.cs new file mode 100644 index 0000000..9f0ea8f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsFatalAlert.cs @@ -0,0 +1,46 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + public class TlsFatalAlert + : TlsException + { + private static string GetMessage(short alertDescription, string detailMessage) + { + string msg = Tls.AlertDescription.GetText(alertDescription); + if (null != detailMessage) + { + msg += "; " + detailMessage; + } + return msg; + } + + protected readonly short m_alertDescription; + + public TlsFatalAlert(short alertDescription) + : this(alertDescription, (string)null) + { + } + + public TlsFatalAlert(short alertDescription, string detailMessage) + : this(alertDescription, detailMessage, null) + { + } + + public TlsFatalAlert(short alertDescription, Exception alertCause) + : this(alertDescription, null, alertCause) + { + } + + public TlsFatalAlert(short alertDescription, string detailMessage, Exception alertCause) + : base(GetMessage(alertDescription, detailMessage), alertCause) + { + this.m_alertDescription = alertDescription; + } + + public virtual short AlertDescription + { + get { return m_alertDescription; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsFatalAlert.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsFatalAlert.cs.meta new file mode 100644 index 0000000..5f98248 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsFatalAlert.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4faad54da1790264f9aafa7750224f7c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsFatalAlertReceived.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsFatalAlertReceived.cs new file mode 100644 index 0000000..0bf6cff --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsFatalAlertReceived.cs @@ -0,0 +1,21 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + public class TlsFatalAlertReceived + : TlsException + { + protected readonly short m_alertDescription; + + public TlsFatalAlertReceived(short alertDescription) + : base(Tls.AlertDescription.GetText(alertDescription)) + { + this.m_alertDescription = alertDescription; + } + + public virtual short AlertDescription + { + get { return m_alertDescription; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsFatalAlertReceived.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsFatalAlertReceived.cs.meta new file mode 100644 index 0000000..dadf510 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsFatalAlertReceived.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2e51be77000e42d4f8e8a23cfe4ebfbe +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsHandshakeHash.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsHandshakeHash.cs new file mode 100644 index 0000000..aa33c68 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsHandshakeHash.cs @@ -0,0 +1,29 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Tls.Crypto; + +namespace Org.BouncyCastle.Tls +{ + /// Base interface for an object that can calculate a handshake hash. + public interface TlsHandshakeHash + : TlsHash + { + /// + void CopyBufferTo(Stream output); + + void ForceBuffering(); + + void NotifyPrfDetermined(); + + void TrackHashAlgorithm(int cryptoHashAlgorithm); + + void SealHashAlgorithms(); + + TlsHandshakeHash StopTracking(); + + TlsHash ForkPrfHash(); + + byte[] GetFinalHash(int cryptoHashAlgorithm); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsHandshakeHash.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsHandshakeHash.cs.meta new file mode 100644 index 0000000..ab7995e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsHandshakeHash.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dacaa61d394f93b4cb98aefd52caea10 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsHeartbeat.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsHeartbeat.cs new file mode 100644 index 0000000..3f208a8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsHeartbeat.cs @@ -0,0 +1,13 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + public interface TlsHeartbeat + { + byte[] GeneratePayload(); + + int IdleMillis { get; } + + int TimeoutMillis { get; } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsHeartbeat.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsHeartbeat.cs.meta new file mode 100644 index 0000000..e06c047 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsHeartbeat.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 63beb9ae9bbb3c148905eff7616afc11 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsKeyExchange.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsKeyExchange.cs new file mode 100644 index 0000000..42c2aa4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsKeyExchange.cs @@ -0,0 +1,55 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Tls.Crypto; + +namespace Org.BouncyCastle.Tls +{ + /// A generic interface for key exchange implementations in (D)TLS. + public interface TlsKeyExchange + { + void Init(TlsContext context); + + /// + void SkipServerCredentials(); + + /// + void ProcessServerCredentials(TlsCredentials serverCredentials); + + /// + void ProcessServerCertificate(Certificate serverCertificate); + + bool RequiresServerKeyExchange { get; } + + /// + byte[] GenerateServerKeyExchange(); + + /// + void SkipServerKeyExchange(); + + /// + void ProcessServerKeyExchange(Stream input); + + short[] GetClientCertificateTypes(); + + /// + void SkipClientCredentials(); + + /// + void ProcessClientCredentials(TlsCredentials clientCredentials); + + /// + void ProcessClientCertificate(Certificate clientCertificate); + + /// + void GenerateClientKeyExchange(Stream output); + + /// + void ProcessClientKeyExchange(Stream input); + + bool RequiresCertificateVerify { get; } + + /// + TlsSecret GeneratePreMasterSecret(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsKeyExchange.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsKeyExchange.cs.meta new file mode 100644 index 0000000..90cc81a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsKeyExchange.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2f09d07cbe512c9458177cd9756e2af4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsKeyExchangeFactory.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsKeyExchangeFactory.cs new file mode 100644 index 0000000..59b5327 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsKeyExchangeFactory.cs @@ -0,0 +1,59 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Tls.Crypto; + +namespace Org.BouncyCastle.Tls +{ + /// Interface for a key exchange factory offering a variety of specific algorithms. + public interface TlsKeyExchangeFactory + { + /// + TlsKeyExchange CreateDHKeyExchange(int keyExchange); + + /// + TlsKeyExchange CreateDHanonKeyExchangeClient(int keyExchange, TlsDHGroupVerifier dhGroupVerifier); + + /// + TlsKeyExchange CreateDHanonKeyExchangeServer(int keyExchange, TlsDHConfig dhConfig); + + /// + TlsKeyExchange CreateDheKeyExchangeClient(int keyExchange, TlsDHGroupVerifier dhGroupVerifier); + + /// + TlsKeyExchange CreateDheKeyExchangeServer(int keyExchange, TlsDHConfig dhConfig); + + /// + TlsKeyExchange CreateECDHKeyExchange(int keyExchange); + + /// + TlsKeyExchange CreateECDHanonKeyExchangeClient(int keyExchange); + + /// + TlsKeyExchange CreateECDHanonKeyExchangeServer(int keyExchange, TlsECConfig ecConfig); + + /// + TlsKeyExchange CreateECDheKeyExchangeClient(int keyExchange); + + /// + TlsKeyExchange CreateECDheKeyExchangeServer(int keyExchange, TlsECConfig ecConfig); + + /// + TlsKeyExchange CreatePskKeyExchangeClient(int keyExchange, TlsPskIdentity pskIdentity, + TlsDHGroupVerifier dhGroupVerifier); + + /// + TlsKeyExchange CreatePskKeyExchangeServer(int keyExchange, TlsPskIdentityManager pskIdentityManager, + TlsDHConfig dhConfig, TlsECConfig ecConfig); + + /// + TlsKeyExchange CreateRsaKeyExchange(int keyExchange); + + /// + TlsKeyExchange CreateSrpKeyExchangeClient(int keyExchange, TlsSrpIdentity srpIdentity, + TlsSrpConfigVerifier srpConfigVerifier); + + /// + TlsKeyExchange CreateSrpKeyExchangeServer(int keyExchange, TlsSrpLoginParameters loginParameters); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsKeyExchangeFactory.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsKeyExchangeFactory.cs.meta new file mode 100644 index 0000000..6ba7a68 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsKeyExchangeFactory.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d8943070833a6cd4490e13e40142bd64 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsNoCloseNotifyException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsNoCloseNotifyException.cs new file mode 100644 index 0000000..8fdfbbf --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsNoCloseNotifyException.cs @@ -0,0 +1,21 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Tls +{ + /// This exception will be thrown (only) when the connection is closed by the peer without sending a + /// close_notify warning alert. + /// + /// If this happens, the TLS protocol cannot rule out truncation of the connection data (potentially + /// malicious). It may be possible to check for truncation via some property of a higher level protocol + /// built upon TLS, e.g.the Content-Length header for HTTPS. + /// + public class TlsNoCloseNotifyException + : EndOfStreamException + { + public TlsNoCloseNotifyException() + : base("No close_notify alert received before connection closed") + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsNoCloseNotifyException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsNoCloseNotifyException.cs.meta new file mode 100644 index 0000000..430559f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsNoCloseNotifyException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fa7c8365a7ae87640a0fdb0b3887d025 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsObjectIdentifiers.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsObjectIdentifiers.cs new file mode 100644 index 0000000..e4bba69 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsObjectIdentifiers.cs @@ -0,0 +1,14 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; + +namespace Org.BouncyCastle.Tls +{ + /// Object Identifiers associated with TLS extensions. + public abstract class TlsObjectIdentifiers + { + /// RFC 7633 + public static readonly DerObjectIdentifier id_pe_tlsfeature = X509ObjectIdentifiers.IdPE.Branch("24"); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsObjectIdentifiers.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsObjectIdentifiers.cs.meta new file mode 100644 index 0000000..934a0aa --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsObjectIdentifiers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3f6641b9b47f16542ac0b873da3788a2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsPeer.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsPeer.cs new file mode 100644 index 0000000..ef28371 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsPeer.cs @@ -0,0 +1,123 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Tls.Crypto; + +namespace Org.BouncyCastle.Tls +{ + /// Base interface for a (D)TLS endpoint. + public interface TlsPeer + { + TlsCrypto Crypto { get; } + + void NotifyCloseHandle(TlsCloseable closehandle); + + /// + void Cancel(); + + ProtocolVersion[] GetProtocolVersions(); + + int[] GetCipherSuites(); + + /// Notifies the peer that a new handshake is about to begin. + /// + void NotifyHandshakeBeginning(); + + /// Specify the timeout, in milliseconds, to use for the complete handshake process. + /// + /// NOTE: Currently only respected by DTLS protocols. Negative values are not allowed. A timeout of zero means + /// an infinite timeout (i.e.the handshake will never time out). + /// + /// the handshake timeout, in milliseconds. + int GetHandshakeTimeoutMillis(); + + bool AllowLegacyResumption(); + + int GetMaxCertificateChainLength(); + + int GetMaxHandshakeMessageSize(); + + short[] GetPskKeyExchangeModes(); + + /// + /// This option is provided as a last resort for interoperability with TLS peers that fail to correctly send a + /// close_notify alert at end of stream. Implementations SHOULD return true; caution is advised if returning + /// false without a full understanding of the implications. + /// + bool RequiresCloseNotify(); + + /// This implementation supports RFC 7627 and will always negotiate the extended_master_secret + /// extension where possible. When connecting to a peer that does not offer/accept this extension, it is + /// recommended to abort the handshake.This option is provided for interoperability with legacy peers, although + /// some TLS features will be disabled in that case (see RFC 7627 5.4). + /// + /// true if the handshake should be aborted when the peer does not negotiate the + /// extended_master_secret extension, or false to support legacy interoperability. + bool RequiresExtendedMasterSecret(); + + bool ShouldUseExtendedMasterSecret(); + + /// See RFC 5246 6.2.3.2. Controls whether block cipher encryption may randomly add extra padding + /// beyond the minimum. + /// + /// Note that in configurations where this is known to be potential security risk this setting will be ignored + /// (and extended padding disabled). Extra padding is always supported when decrypting received records. + /// + /// true if random extra padding should be added during block cipher encryption, or + /// false to always use the minimum amount of required padding. + bool ShouldUseExtendedPadding(); + + /// draft-mathewson-no-gmtunixtime-00 2. "If existing users of a TLS implementation may rely on + /// gmt_unix_time containing the current time, we recommend that implementors MAY provide the ability to set + /// gmt_unix_time as an option only, off by default.". + /// + /// NOTE: For a server that has negotiated TLS 1.3 (or later), or a client that has offered TLS 1.3 (or later), + /// this is not called and gmt_unix_time is not used. + /// + /// true if the current time should be used in the gmt_unix_time field of Random, or + /// false if gmt_unix_time should contain a cryptographically random value. + bool ShouldUseGmtUnixTime(); + + /// RFC 5746 3.4/3.6. In case this is false, peers may want to terminate the handshake instead of + /// continuing; see Section 4.1/4.3 for discussion. + /// + /// NOTE: TLS 1.3 forbids renegotiation, so this is never called when TLS 1.3 (or later) was negotiated. + /// + /// + void NotifySecureRenegotiation(bool secureRenegotiation); + + /// + TlsKeyExchangeFactory GetKeyExchangeFactory(); + + /// This method will be called when an alert is raised by the protocol. + /// + /// + /// A human-readable message explaining what caused this alert. May be null. + /// The that caused this alert to be raised. May be null. + void NotifyAlertRaised(short alertLevel, short alertDescription, string message, Exception cause); + + /// This method will be called when an alert is received from the remote peer. + /// + /// + void NotifyAlertReceived(short alertLevel, short alertDescription); + + /// Notifies the peer that the handshake has been successfully completed. + /// + void NotifyHandshakeComplete(); + + /// Return a instance that will control the generation of heartbeats + /// locally (if permitted by the remote peer), or null to not generate heartbeats. Heartbeats are described in + /// RFC 6520. + /// an instance of . + /// + TlsHeartbeat GetHeartbeat(); + + /// Return the heartbeat mode applicable to the remote peer. Heartbeats are described in RFC 6520. + /// + /// + /// See enumeration class for appropriate return values. + /// + /// the value. + short GetHeartbeatPolicy(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsPeer.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsPeer.cs.meta new file mode 100644 index 0000000..62a06e5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsPeer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 139384a1dbc859849aee50f9312e223a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsProtocol.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsProtocol.cs new file mode 100644 index 0000000..8fe6dc2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsProtocol.cs @@ -0,0 +1,1965 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Tls.Crypto; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls +{ + public abstract class TlsProtocol + : TlsCloseable + { + /* + * Connection States. + * + * NOTE: Redirection of handshake messages to TLS 1.3 handlers assumes CS_START, CS_CLIENT_HELLO + * are lower than any of the other values. + */ + protected const short CS_START = 0; + protected const short CS_CLIENT_HELLO = 1; + protected const short CS_SERVER_HELLO_RETRY_REQUEST = 2; + protected const short CS_CLIENT_HELLO_RETRY = 3; + protected const short CS_SERVER_HELLO = 4; + protected const short CS_SERVER_ENCRYPTED_EXTENSIONS = 5; + protected const short CS_SERVER_SUPPLEMENTAL_DATA = 6; + protected const short CS_SERVER_CERTIFICATE = 7; + protected const short CS_SERVER_CERTIFICATE_STATUS = 8; + protected const short CS_SERVER_CERTIFICATE_VERIFY = 9; + protected const short CS_SERVER_KEY_EXCHANGE = 10; + protected const short CS_SERVER_CERTIFICATE_REQUEST = 11; + protected const short CS_SERVER_HELLO_DONE = 12; + protected const short CS_CLIENT_END_OF_EARLY_DATA = 13; + protected const short CS_CLIENT_SUPPLEMENTAL_DATA = 14; + protected const short CS_CLIENT_CERTIFICATE = 15; + protected const short CS_CLIENT_KEY_EXCHANGE = 16; + protected const short CS_CLIENT_CERTIFICATE_VERIFY = 17; + protected const short CS_CLIENT_FINISHED = 18; + protected const short CS_SERVER_SESSION_TICKET = 19; + protected const short CS_SERVER_FINISHED = 20; + protected const short CS_END = 21; + + protected bool IsLegacyConnectionState() + { + switch (m_connectionState) + { + case CS_START: + case CS_CLIENT_HELLO: + case CS_SERVER_HELLO: + case CS_SERVER_SUPPLEMENTAL_DATA: + case CS_SERVER_CERTIFICATE: + case CS_SERVER_CERTIFICATE_STATUS: + case CS_SERVER_KEY_EXCHANGE: + case CS_SERVER_CERTIFICATE_REQUEST: + case CS_SERVER_HELLO_DONE: + case CS_CLIENT_SUPPLEMENTAL_DATA: + case CS_CLIENT_CERTIFICATE: + case CS_CLIENT_KEY_EXCHANGE: + case CS_CLIENT_CERTIFICATE_VERIFY: + case CS_CLIENT_FINISHED: + case CS_SERVER_SESSION_TICKET: + case CS_SERVER_FINISHED: + case CS_END: + return true; + + case CS_SERVER_HELLO_RETRY_REQUEST: + case CS_CLIENT_HELLO_RETRY: + case CS_SERVER_ENCRYPTED_EXTENSIONS: + case CS_SERVER_CERTIFICATE_VERIFY: + case CS_CLIENT_END_OF_EARLY_DATA: + default: + return false; + } + } + + protected bool IsTlsV13ConnectionState() + { + switch (m_connectionState) + { + case CS_START: + case CS_CLIENT_HELLO: + case CS_SERVER_HELLO_RETRY_REQUEST: + case CS_CLIENT_HELLO_RETRY: + case CS_SERVER_HELLO: + case CS_SERVER_ENCRYPTED_EXTENSIONS: + case CS_SERVER_CERTIFICATE_REQUEST: + case CS_SERVER_CERTIFICATE: + case CS_SERVER_CERTIFICATE_VERIFY: + case CS_SERVER_FINISHED: + case CS_CLIENT_END_OF_EARLY_DATA: + case CS_CLIENT_CERTIFICATE: + case CS_CLIENT_CERTIFICATE_VERIFY: + case CS_CLIENT_FINISHED: + case CS_END: + return true; + + case CS_SERVER_SUPPLEMENTAL_DATA: + case CS_SERVER_CERTIFICATE_STATUS: + case CS_SERVER_KEY_EXCHANGE: + case CS_SERVER_HELLO_DONE: + case CS_CLIENT_SUPPLEMENTAL_DATA: + case CS_CLIENT_KEY_EXCHANGE: + case CS_SERVER_SESSION_TICKET: + default: + return false; + } + } + + /* + * Different modes to handle the known IV weakness + */ + protected const short ADS_MODE_1_Nsub1 = 0; // 1/n-1 record splitting + protected const short ADS_MODE_0_N = 1; // 0/n record splitting + protected const short ADS_MODE_0_N_FIRSTONLY = 2; // 0/n record splitting on first data fragment only + + /* + * Queues for data from some protocols. + */ + private readonly ByteQueue m_applicationDataQueue = new ByteQueue(0); + private readonly ByteQueue m_alertQueue = new ByteQueue(2); + private readonly ByteQueue m_handshakeQueue = new ByteQueue(0); + //private readonly ByteQueue m_heartbeatQueue = new ByteQueue(0); + + internal readonly RecordStream m_recordStream; + internal readonly object m_recordWriteLock = new object(); + + private int m_maxHandshakeMessageSize = -1; + + internal TlsHandshakeHash m_handshakeHash; + + private TlsStream m_tlsStream = null; + + private volatile bool m_closed = false; + private volatile bool m_failedWithError = false; + private volatile bool m_appDataReady = false; + private volatile bool m_appDataSplitEnabled = true; + private volatile bool m_keyUpdateEnabled = false; + //private volatile bool m_keyUpdatePendingReceive = false; + private volatile bool m_keyUpdatePendingSend = false; + private volatile bool m_resumableHandshake = false; + private volatile int m_appDataSplitMode = ADS_MODE_1_Nsub1; + + protected TlsSession m_tlsSession = null; + protected SessionParameters m_sessionParameters = null; + protected TlsSecret m_sessionMasterSecret = null; + + protected byte[] m_retryCookie = null; + protected int m_retryGroup = -1; + protected IDictionary m_clientExtensions = null; + protected IDictionary m_serverExtensions = null; + + protected short m_connectionState = CS_START; + protected bool m_resumedSession = false; + protected bool m_selectedPsk13 = false; + protected bool m_receivedChangeCipherSpec = false; + protected bool m_expectSessionTicket = false; + + protected readonly bool m_blocking; + protected readonly ByteQueueInputStream m_inputBuffers; + protected readonly ByteQueueOutputStream m_outputBuffer; + + protected TlsProtocol() + { + this.m_blocking = false; + this.m_inputBuffers = new ByteQueueInputStream(); + this.m_outputBuffer = new ByteQueueOutputStream(); + this.m_recordStream = new RecordStream(this, m_inputBuffers, m_outputBuffer); + } + + public TlsProtocol(Stream stream) + : this(stream, stream) + { + } + + public TlsProtocol(Stream input, Stream output) + { + this.m_blocking = true; + this.m_inputBuffers = null; + this.m_outputBuffer = null; + this.m_recordStream = new RecordStream(this, input, output); + } + + /// + public virtual void ResumeHandshake() + { + if (!m_blocking) + throw new InvalidOperationException("Cannot use ResumeHandshake() in non-blocking mode!"); + if (!IsHandshaking) + throw new InvalidOperationException("No handshake in progress"); + + BlockForHandshake(); + } + + /// + protected virtual void CloseConnection() + { + m_recordStream.Close(); + } + + protected abstract TlsContext Context { get; } + + internal abstract AbstractTlsContext ContextAdmin { get; } + + protected abstract TlsPeer Peer { get; } + + /// + protected virtual void HandleAlertMessage(short alertLevel, short alertDescription) + { + Peer.NotifyAlertReceived(alertLevel, alertDescription); + + if (alertLevel == AlertLevel.warning) + { + HandleAlertWarningMessage(alertDescription); + } + else + { + HandleFailure(); + + throw new TlsFatalAlertReceived(alertDescription); + } + } + + /// + protected virtual void HandleAlertWarningMessage(short alertDescription) + { + switch (alertDescription) + { + /* + * RFC 5246 7.2.1. The other party MUST respond with a close_notify alert of its own + * and close down the connection immediately, discarding any pending writes. + */ + case AlertDescription.close_notify: + { + if (!m_appDataReady) + throw new TlsFatalAlert(AlertDescription.handshake_failure); + + HandleClose(false); + break; + } + case AlertDescription.no_certificate: + { + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + case AlertDescription.no_renegotiation: + { + // TODO[reneg] Give peer the option to tolerate this + throw new TlsFatalAlert(AlertDescription.handshake_failure); + } + } + } + + /// + protected virtual void HandleChangeCipherSpecMessage() + { + } + + /// + protected virtual void HandleClose(bool user_canceled) + { + if (!m_closed) + { + this.m_closed = true; + + if (!m_appDataReady) + { + CleanupHandshake(); + + if (user_canceled) + { + RaiseAlertWarning(AlertDescription.user_canceled, "User canceled handshake"); + } + } + + RaiseAlertWarning(AlertDescription.close_notify, "Connection closed"); + + CloseConnection(); + } + } + + /// + protected virtual void HandleException(short alertDescription, string message, Exception e) + { + // TODO[tls-port] Can we support interrupted IO on .NET? + //if ((m_appDataReady || IsResumableHandshake()) && (e is InterruptedIOException)) + // return; + + if (!m_closed) + { + RaiseAlertFatal(alertDescription, message, e); + + HandleFailure(); + } + } + + /// + protected virtual void HandleFailure() + { + this.m_closed = true; + this.m_failedWithError = true; + + /* + * RFC 2246 7.2.1. The session becomes unresumable if any connection is terminated + * without proper close_notify messages with level equal to warning. + */ + // TODO This isn't quite in the right place. Also, as of TLS 1.1 the above is obsolete. + InvalidateSession(); + + if (!m_appDataReady) + { + CleanupHandshake(); + } + + CloseConnection(); + } + + /// + protected abstract void HandleHandshakeMessage(short type, HandshakeMessageInput buf); + + /// + protected virtual void ApplyMaxFragmentLengthExtension(short maxFragmentLength) + { + if (maxFragmentLength >= 0) + { + if (!MaxFragmentLength.IsValid(maxFragmentLength)) + throw new TlsFatalAlert(AlertDescription.internal_error); + + int plainTextLimit = 1 << (8 + maxFragmentLength); + m_recordStream.SetPlaintextLimit(plainTextLimit); + } + } + + /// + protected virtual void CheckReceivedChangeCipherSpec(bool expected) + { + if (expected != m_receivedChangeCipherSpec) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + /// + protected virtual void BlockForHandshake() + { + while (m_connectionState != CS_END) + { + if (IsClosed) + { + // NOTE: Any close during the handshake should have raised an exception. + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + SafeReadRecord(); + } + } + + /// + protected virtual void BeginHandshake() + { + AbstractTlsContext context = ContextAdmin; + TlsPeer peer = Peer; + + this.m_maxHandshakeMessageSize = System.Math.Max(1024, peer.GetMaxHandshakeMessageSize()); + + this.m_handshakeHash = new DeferredHash(context); + this.m_connectionState = CS_START; + this.m_resumedSession = false; + this.m_selectedPsk13 = false; + + context.HandshakeBeginning(peer); + + SecurityParameters securityParameters = context.SecurityParameters; + + securityParameters.m_extendedPadding = peer.ShouldUseExtendedPadding(); + } + + protected virtual void CleanupHandshake() + { + TlsContext context = Context; + if (null != context) + { + SecurityParameters securityParameters = context.SecurityParameters; + if (null != securityParameters) + { + securityParameters.Clear(); + } + } + + this.m_tlsSession = null; + this.m_sessionParameters = null; + this.m_sessionMasterSecret = null; + + this.m_retryCookie = null; + this.m_retryGroup = -1; + this.m_clientExtensions = null; + this.m_serverExtensions = null; + + this.m_resumedSession = false; + this.m_selectedPsk13 = false; + this.m_receivedChangeCipherSpec = false; + this.m_expectSessionTicket = false; + } + + /// + protected virtual void CompleteHandshake() + { + try + { + AbstractTlsContext context = ContextAdmin; + SecurityParameters securityParameters = context.SecurityParameters; + + if (!context.IsHandshaking || + null == securityParameters.LocalVerifyData || + null == securityParameters.PeerVerifyData) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + m_recordStream.FinaliseHandshake(); + this.m_connectionState = CS_END; + + // TODO Prefer to set to null, but would need guards elsewhere + this.m_handshakeHash = new DeferredHash(context); + + m_alertQueue.Shrink(); + m_handshakeQueue.Shrink(); + + ProtocolVersion negotiatedVersion = securityParameters.NegotiatedVersion; + + this.m_appDataSplitEnabled = !TlsUtilities.IsTlsV11(negotiatedVersion); + this.m_appDataReady = true; + + this.m_keyUpdateEnabled = TlsUtilities.IsTlsV13(negotiatedVersion); + + if (m_blocking) + { + this.m_tlsStream = new TlsStream(this); + } + + if (m_sessionParameters == null) + { + this.m_sessionMasterSecret = securityParameters.MasterSecret; + + this.m_sessionParameters = new SessionParameters.Builder() + .SetCipherSuite(securityParameters.CipherSuite) + .SetExtendedMasterSecret(securityParameters.IsExtendedMasterSecret) + .SetLocalCertificate(securityParameters.LocalCertificate) + .SetMasterSecret(context.Crypto.AdoptSecret(m_sessionMasterSecret)) + .SetNegotiatedVersion(securityParameters.NegotiatedVersion) + .SetPeerCertificate(securityParameters.PeerCertificate) + .SetPskIdentity(securityParameters.PskIdentity) + .SetSrpIdentity(securityParameters.SrpIdentity) + // TODO Consider filtering extensions that aren't relevant to resumed sessions + .SetServerExtensions(m_serverExtensions) + .Build(); + + this.m_tlsSession = TlsUtilities.ImportSession(securityParameters.SessionID, m_sessionParameters); + } + else + { + securityParameters.m_localCertificate = m_sessionParameters.LocalCertificate; + securityParameters.m_peerCertificate = m_sessionParameters.PeerCertificate; + securityParameters.m_pskIdentity = m_sessionParameters.PskIdentity; + securityParameters.m_srpIdentity = m_sessionParameters.SrpIdentity; + } + + context.HandshakeComplete(Peer, m_tlsSession); + } + finally + { + CleanupHandshake(); + } + } + + /// + internal void ProcessRecord(short protocol, byte[] buf, int off, int len) + { + /* + * Have a look at the protocol type, and add it to the correct queue. + */ + switch (protocol) + { + case ContentType.alert: + { + m_alertQueue.AddData(buf, off, len); + ProcessAlertQueue(); + break; + } + case ContentType.application_data: + { + if (!m_appDataReady) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + + m_applicationDataQueue.AddData(buf, off, len); + ProcessApplicationDataQueue(); + break; + } + case ContentType.change_cipher_spec: + { + ProcessChangeCipherSpec(buf, off, len); + break; + } + case ContentType.handshake: + { + if (m_handshakeQueue.Available > 0) + { + m_handshakeQueue.AddData(buf, off, len); + ProcessHandshakeQueue(m_handshakeQueue); + } + else + { + ByteQueue tmpQueue = new ByteQueue(buf, off, len); + ProcessHandshakeQueue(tmpQueue); + int remaining = tmpQueue.Available; + if (remaining > 0) + { + m_handshakeQueue.AddData(buf, off + len - remaining, remaining); + } + } + break; + } + //case ContentType.heartbeat: + //{ + // if (!m_appDataReady) + // throw new TlsFatalAlert(AlertDescription.unexpected_message); + + // // TODO[RFC 6520] + // m_heartbeatQueue.addData(buf, off, len); + // ProcessHeartbeatQueue(); + // break; + //} + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + } + + /// + private void ProcessHandshakeQueue(ByteQueue queue) + { + /* + * We need the first 4 bytes, they contain type and length of the message. + */ + while (queue.Available >= 4) + { + int header = queue.ReadInt32(); + + short type = (short)((uint)header >> 24); + if (!HandshakeType.IsRecognized(type)) + { + throw new TlsFatalAlert(AlertDescription.unexpected_message, + "Handshake message of unrecognized type: " + type); + } + + int length = header & 0x00FFFFFF; + if (length > m_maxHandshakeMessageSize) + { + throw new TlsFatalAlert(AlertDescription.internal_error, + "Handshake message length exceeds the maximum: " + HandshakeType.GetText(type) + ", " + length + + " > " + m_maxHandshakeMessageSize); + } + + int totalLength = 4 + length; + if (queue.Available < totalLength) + { + // Not enough bytes in the buffer to read the full message. + break; + } + + /* + * Check ChangeCipherSpec status + */ + switch (type) + { + case HandshakeType.hello_request: + break; + + default: + { + ProtocolVersion negotiatedVersion = Context.ServerVersion; + if (null != negotiatedVersion && TlsUtilities.IsTlsV13(negotiatedVersion)) + break; + + CheckReceivedChangeCipherSpec(HandshakeType.finished == type); + break; + } + } + + HandshakeMessageInput buf = queue.ReadHandshakeMessage(totalLength); + + switch (type) + { + /* + * These message types aren't included in the transcript. + */ + case HandshakeType.hello_request: + case HandshakeType.key_update: + break; + + /* + * Not included in the transcript for (D)TLS 1.3+ + */ + case HandshakeType.new_session_ticket: + { + ProtocolVersion negotiatedVersion = Context.ServerVersion; + if (null != negotiatedVersion && !TlsUtilities.IsTlsV13(negotiatedVersion)) + { + buf.UpdateHash(m_handshakeHash); + } + + break; + } + + /* + * These message types are deferred to the handler to explicitly update the transcript. + */ + case HandshakeType.certificate_verify: + case HandshakeType.client_hello: + case HandshakeType.finished: + case HandshakeType.server_hello: + break; + + /* + * For all others we automatically update the transcript immediately. + */ + default: + { + buf.UpdateHash(m_handshakeHash); + break; + } + } + + buf.Seek(4L, SeekOrigin.Current); + + HandleHandshakeMessage(type, buf); + } + } + + private void ProcessApplicationDataQueue() + { + /* + * There is nothing we need to do here. + * + * This function could be used for callbacks when application data arrives in the future. + */ + } + + /// + private void ProcessAlertQueue() + { + while (m_alertQueue.Available >= 2) + { + /* + * An alert is always 2 bytes. Read the alert. + */ + byte[] alert = m_alertQueue.RemoveData(2, 0); + short alertLevel = alert[0]; + short alertDescription = alert[1]; + + HandleAlertMessage(alertLevel, alertDescription); + } + } + + /// This method is called, when a change cipher spec message is received. + /// If the message has an invalid content or the handshake is not in the correct + /// state. + private void ProcessChangeCipherSpec(byte[] buf, int off, int len) + { + ProtocolVersion negotiatedVersion = Context.ServerVersion; + if (null == negotiatedVersion || TlsUtilities.IsTlsV13(negotiatedVersion)) + { + // See RFC 8446 D.4. + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + for (int i = 0; i < len; ++i) + { + short message = TlsUtilities.ReadUint8(buf, off + i); + + if (message != ChangeCipherSpec.change_cipher_spec) + throw new TlsFatalAlert(AlertDescription.decode_error); + + if (this.m_receivedChangeCipherSpec + || m_alertQueue.Available > 0 + || m_handshakeQueue.Available > 0) + { + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + m_recordStream.NotifyChangeCipherSpecReceived(); + + this.m_receivedChangeCipherSpec = true; + + HandleChangeCipherSpecMessage(); + } + } + + public virtual int ApplicationDataAvailable + { + get { return m_applicationDataQueue.Available; } + } + + /// Read data from the network. + /// + /// The method will return immediately, if there is still some data left in the buffer, or block until some + /// application data has been read from the network. + /// + /// The buffer where the data will be copied to. + /// The position where the data will be placed in the buffer. + /// The maximum number of bytes to read. + /// The number of bytes read. + /// If something goes wrong during reading data. + public virtual int ReadApplicationData(byte[] buf, int off, int len) + { + if (len < 1) + return 0; + + while (m_applicationDataQueue.Available == 0) + { + if (this.m_closed) + { + if (this.m_failedWithError) + throw new IOException("Cannot read application data on failed TLS connection"); + + return -1; + } + if (!m_appDataReady) + throw new InvalidOperationException("Cannot read application data until initial handshake completed."); + + /* + * NOTE: Only called more than once when empty records are received, so no special + * InterruptedIOException handling is necessary. + */ + SafeReadRecord(); + } + + len = System.Math.Min(len, m_applicationDataQueue.Available); + m_applicationDataQueue.RemoveData(buf, off, len, 0); + return len; + } + + /// + protected virtual RecordPreview SafePreviewRecordHeader(byte[] recordHeader) + { + try + { + return m_recordStream.PreviewRecordHeader(recordHeader); + } + catch (TlsFatalAlert e) + { + HandleException(e.AlertDescription, "Failed to read record", e); + throw e; + } + catch (IOException e) + { + HandleException(AlertDescription.internal_error, "Failed to read record", e); + throw e; + } + catch (Exception e) + { + HandleException(AlertDescription.internal_error, "Failed to read record", e); + throw new TlsFatalAlert(AlertDescription.internal_error, e); + } + } + + /// + protected virtual void SafeReadRecord() + { + try + { + if (m_recordStream.ReadRecord()) + return; + + if (!m_appDataReady) + throw new TlsFatalAlert(AlertDescription.handshake_failure); + + if (!Peer.RequiresCloseNotify()) + { + HandleClose(false); + return; + } + } + catch (TlsFatalAlertReceived e) + { + // Connection failure already handled at source + throw e; + } + catch (TlsFatalAlert e) + { + HandleException(e.AlertDescription, "Failed to read record", e); + throw e; + } + catch (IOException e) + { + HandleException(AlertDescription.internal_error, "Failed to read record", e); + throw e; + } + catch (Exception e) + { + HandleException(AlertDescription.internal_error, "Failed to read record", e); + throw new TlsFatalAlert(AlertDescription.internal_error, e); + } + + HandleFailure(); + + throw new TlsNoCloseNotifyException(); + } + + /// + protected virtual bool SafeReadFullRecord(byte[] input, int inputOff, int inputLen) + { + try + { + return m_recordStream.ReadFullRecord(input, inputOff, inputLen); + } + catch (TlsFatalAlert e) + { + HandleException(e.AlertDescription, "Failed to process record", e); + throw e; + } + catch (IOException e) + { + HandleException(AlertDescription.internal_error, "Failed to process record", e); + throw e; + } + catch (Exception e) + { + HandleException(AlertDescription.internal_error, "Failed to process record", e); + throw new TlsFatalAlert(AlertDescription.internal_error, e); + } + } + + /// + protected virtual void SafeWriteRecord(short type, byte[] buf, int offset, int len) + { + try + { + m_recordStream.WriteRecord(type, buf, offset, len); + } + catch (TlsFatalAlert e) + { + HandleException(e.AlertDescription, "Failed to write record", e); + throw e; + } + catch (IOException e) + { + HandleException(AlertDescription.internal_error, "Failed to write record", e); + throw e; + } + catch (Exception e) + { + HandleException(AlertDescription.internal_error, "Failed to write record", e); + throw new TlsFatalAlert(AlertDescription.internal_error, e); + } + } + + /// Write some application data. + /// + /// Fragmentation is handled internally. Usable in both blocking/non-blocking modes.

    + /// In blocking mode, the output will be automatically sent via the underlying transport. In non-blocking mode, + /// call to get the output bytes to send to the peer.

    + /// This method must not be called until after the initial handshake is complete. Attempting to call it earlier + /// will result in an . + ///
    + /// The buffer containing application data to send. + /// The offset at which the application data begins + /// The number of bytes of application data. + /// If called before the initial handshake has completed. + /// + /// If connection is already closed, or for encryption or transport errors. + /// + public virtual void WriteApplicationData(byte[] buf, int off, int len) + { + if (!m_appDataReady) + throw new InvalidOperationException( + "Cannot write application data until initial handshake completed."); + + lock (m_recordWriteLock) + { + while (len > 0) + { + if (m_closed) + throw new IOException("Cannot write application data on closed/failed TLS connection"); + + /* + * RFC 5246 6.2.1. Zero-length fragments of Application data MAY be sent as they are + * potentially useful as a traffic analysis countermeasure. + * + * NOTE: Actually, implementations appear to have settled on 1/n-1 record splitting. + */ + if (m_appDataSplitEnabled) + { + /* + * Protect against known IV attack! + * + * DO NOT REMOVE THIS CODE, EXCEPT YOU KNOW EXACTLY WHAT YOU ARE DOING HERE. + */ + switch (m_appDataSplitMode) + { + case ADS_MODE_0_N_FIRSTONLY: + { + this.m_appDataSplitEnabled = false; + SafeWriteRecord(ContentType.application_data, TlsUtilities.EmptyBytes, 0, 0); + break; + } + case ADS_MODE_0_N: + { + SafeWriteRecord(ContentType.application_data, TlsUtilities.EmptyBytes, 0, 0); + break; + } + case ADS_MODE_1_Nsub1: + default: + { + if (len > 1) + { + SafeWriteRecord(ContentType.application_data, buf, off, 1); + ++off; + --len; + } + break; + } + } + } + else if (m_keyUpdateEnabled) + { + if (m_keyUpdatePendingSend) + { + Send13KeyUpdate(false); + } + else if (m_recordStream.NeedsKeyUpdate()) + { + Send13KeyUpdate(true); + } + } + + // Fragment data according to the current fragment limit. + int toWrite = System.Math.Min(len, m_recordStream.PlaintextLimit); + SafeWriteRecord(ContentType.application_data, buf, off, toWrite); + off += toWrite; + len -= toWrite; + } + } + } + + public virtual int AppDataSplitMode + { + get { return m_appDataSplitMode; } + set + { + if (value < ADS_MODE_1_Nsub1 || value > ADS_MODE_0_N_FIRSTONLY) + throw new InvalidOperationException("Illegal appDataSplitMode mode: " + value); + + this.m_appDataSplitMode = value; + } + } + + public virtual bool IsResumableHandshake + { + get { return m_resumableHandshake; } + set { this.m_resumableHandshake = value; } + } + + /// + internal void WriteHandshakeMessage(byte[] buf, int off, int len) + { + if (len < 4) + throw new TlsFatalAlert(AlertDescription.internal_error); + + short type = TlsUtilities.ReadUint8(buf, off); + switch (type) + { + /* + * These message types aren't included in the transcript. + */ + case HandshakeType.hello_request: + case HandshakeType.key_update: + break; + + /* + * Not included in the transcript for (D)TLS 1.3+ + */ + case HandshakeType.new_session_ticket: + { + ProtocolVersion negotiatedVersion = Context.ServerVersion; + if (null != negotiatedVersion && !TlsUtilities.IsTlsV13(negotiatedVersion)) + { + m_handshakeHash.Update(buf, off, len); + } + + break; + } + + /* + * These message types are deferred to the writer to explicitly update the transcript. + */ + case HandshakeType.client_hello: + break; + + /* + * For all others we automatically update the transcript. + */ + default: + { + m_handshakeHash.Update(buf, off, len); + break; + } + } + + int total = 0; + do + { + // Fragment data according to the current fragment limit. + int toWrite = System.Math.Min(len - total, m_recordStream.PlaintextLimit); + SafeWriteRecord(ContentType.handshake, buf, off + total, toWrite); + total += toWrite; + } + while (total < len); + } + + /// The secure bidirectional stream for this connection + /// Only allowed in blocking mode. + public virtual Stream Stream + { + get + { + if (!m_blocking) + throw new InvalidOperationException( + "Cannot use Stream in non-blocking mode! Use OfferInput()/OfferOutput() instead."); + + return this.m_tlsStream; + } + } + + /// Should be called in non-blocking mode when the input data reaches EOF. + /// + public virtual void CloseInput() + { + if (m_blocking) + throw new InvalidOperationException("Cannot use CloseInput() in blocking mode!"); + + if (m_closed) + return; + + if (m_inputBuffers.Available > 0) + throw new EndOfStreamException(); + + if (!m_appDataReady) + throw new TlsFatalAlert(AlertDescription.handshake_failure); + + if (!Peer.RequiresCloseNotify()) + { + HandleClose(false); + return; + } + + HandleFailure(); + + throw new TlsNoCloseNotifyException(); + } + + /// + public virtual RecordPreview PreviewInputRecord(byte[] recordHeader) + { + if (m_blocking) + throw new InvalidOperationException("Cannot use PreviewInputRecord() in blocking mode!"); + if (m_inputBuffers.Available != 0) + throw new InvalidOperationException("Can only use PreviewInputRecord() for record-aligned input."); + if (m_closed) + throw new IOException("Connection is closed, cannot accept any more input"); + + return SafePreviewRecordHeader(recordHeader); + } + + /// + public virtual RecordPreview PreviewOutputRecord(int applicationDataSize) + { + if (!m_appDataReady) + throw new InvalidOperationException( + "Cannot use PreviewOutputRecord() until initial handshake completed."); + if (m_blocking) + throw new InvalidOperationException("Cannot use PreviewOutputRecord() in blocking mode!"); + if (m_outputBuffer.Buffer.Available != 0) + throw new InvalidOperationException("Can only use PreviewOutputRecord() for record-aligned output."); + if (m_closed) + throw new IOException("Connection is closed, cannot produce any more output"); + + if (applicationDataSize < 1) + return new RecordPreview(0, 0); + + if (m_appDataSplitEnabled) + { + switch (m_appDataSplitMode) + { + case ADS_MODE_0_N_FIRSTONLY: + case ADS_MODE_0_N: + { + RecordPreview a = m_recordStream.PreviewOutputRecord(0); + RecordPreview b = m_recordStream.PreviewOutputRecord(applicationDataSize); + return RecordPreview.CombineAppData(a, b); + } + case ADS_MODE_1_Nsub1: + default: + { + RecordPreview a = m_recordStream.PreviewOutputRecord(1); + if (applicationDataSize > 1) + { + RecordPreview b = m_recordStream.PreviewOutputRecord(applicationDataSize - 1); + a = RecordPreview.CombineAppData(a, b); + } + return a; + } + } + } + else + { + RecordPreview a = m_recordStream.PreviewOutputRecord(applicationDataSize); + if (m_keyUpdateEnabled && (m_keyUpdatePendingSend || m_recordStream.NeedsKeyUpdate())) + { + int keyUpdateLength = HandshakeMessageOutput.GetLength(1); + int recordSize = m_recordStream.PreviewOutputRecordSize(keyUpdateLength); + a = RecordPreview.ExtendRecordSize(a, recordSize); + } + return a; + } + } + + /// Equivalent to OfferInput(input, 0, input.Length). + /// The input buffer to offer. + /// + /// + public virtual void OfferInput(byte[] input) + { + OfferInput(input, 0, input.Length); + } + + /// Offer input from an arbitrary source. + /// Only allowed in non-blocking mode.

    + /// This method will decrypt and process all records that are fully available. If only part of a record is + /// available, the buffer will be retained until the remainder of the record is offered.

    + /// If any records containing application data were processed, the decrypted data can be obtained using + /// . If any records containing protocol data were processed, a + /// response may have been generated. You should always check to see if there is any available output after + /// calling this method by calling . + ///
    + /// The input buffer to offer. + /// The offset within the input buffer that input begins. + /// The number of bytes of input being offered. + /// If an error occurs while decrypting or processing a record. + public virtual void OfferInput(byte[] input, int inputOff, int inputLen) + { + if (m_blocking) + throw new InvalidOperationException("Cannot use OfferInput() in blocking mode! Use Stream instead."); + if (m_closed) + throw new IOException("Connection is closed, cannot accept any more input"); + + // Fast path if the input is arriving one record at a time + if (m_inputBuffers.Available == 0 && SafeReadFullRecord(input, inputOff, inputLen)) + { + if (m_closed) + { + if (!m_appDataReady) + { + // NOTE: Any close during the handshake should have raised an exception. + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + return; + } + + m_inputBuffers.AddBytes(input, inputOff, inputLen); + + // loop while there are enough bytes to read the length of the next record + while (m_inputBuffers.Available >= RecordFormat.FragmentOffset) + { + byte[] recordHeader = new byte[RecordFormat.FragmentOffset]; + if (RecordFormat.FragmentOffset != m_inputBuffers.Peek(recordHeader)) + throw new TlsFatalAlert(AlertDescription.internal_error); + + RecordPreview preview = SafePreviewRecordHeader(recordHeader); + if (m_inputBuffers.Available < preview.RecordSize) + { + // not enough bytes to read a whole record + break; + } + + // NOTE: This is actually reading from inputBuffers, so InterruptedIOException shouldn't be possible + SafeReadRecord(); + + if (m_closed) + { + if (!m_appDataReady) + { + // NOTE: Any close during the handshake should have raised an exception. + throw new TlsFatalAlert(AlertDescription.internal_error); + } + break; + } + } + } + + public virtual int ApplicationDataLimit + { + get { return m_recordStream.PlaintextLimit; } + } + + /// Gets the amount of received application data. + /// A call to is guaranteed to be able to return at least + /// this much data.

    + /// Only allowed in non-blocking mode. + ///
    + /// The number of bytes of available application data. + public virtual int GetAvailableInputBytes() + { + if (m_blocking) + throw new InvalidOperationException("Cannot use GetAvailableInputBytes() in blocking mode!"); + + return ApplicationDataAvailable; + } + + /// Retrieves received application data. + /// + /// Use to check how much application data is currently available. This + /// method functions similarly to , except that it never blocks. If + /// no data is available, nothing will be copied and zero will be returned.

    + /// Only allowed in non-blocking mode. + ///
    + /// The buffer to hold the application data. + /// The start offset in the buffer at which the data is written. + /// The maximum number of bytes to read. + /// The total number of bytes copied to the buffer. May be less than the length specified if the + /// length was greater than the amount of available data. + public virtual int ReadInput(byte[] buf, int off, int len) + { + if (m_blocking) + throw new InvalidOperationException("Cannot use ReadInput() in blocking mode! Use Stream instead."); + + len = System.Math.Min(len, ApplicationDataAvailable); + if (len < 1) + return 0; + + m_applicationDataQueue.RemoveData(buf, off, len, 0); + return len; + } + + /// Gets the amount of encrypted data available to be sent. + /// + /// A call to is guaranteed to be able to return at least this much + /// data. Only allowed in non-blocking mode. + /// + /// The number of bytes of available encrypted data. + public virtual int GetAvailableOutputBytes() + { + if (m_blocking) + throw new InvalidOperationException("Cannot use GetAvailableOutputBytes() in blocking mode! Use Stream instead."); + + return m_outputBuffer.Buffer.Available; + } + + /// Retrieves encrypted data to be sent. + /// + /// Use to check how much encrypted data is currently available. This + /// method functions similarly to , except that it never blocks. If + /// no data is available, nothing will be copied and zero will be returned. Only allowed in non-blocking mode. + /// + /// The buffer to hold the encrypted data. + /// The start offset in the buffer at which the data is written. + /// The maximum number of bytes to read. + /// The total number of bytes copied to the buffer. May be less than the length specified if the + /// length was greater than the amount of available data. + public virtual int ReadOutput(byte[] buffer, int offset, int length) + { + if (m_blocking) + throw new InvalidOperationException("Cannot use ReadOutput() in blocking mode! Use 'Stream() instead."); + + int bytesToRead = System.Math.Min(GetAvailableOutputBytes(), length); + m_outputBuffer.Buffer.RemoveData(buffer, offset, bytesToRead, 0); + return bytesToRead; + } + + protected virtual bool EstablishSession(TlsSession sessionToResume) + { + this.m_tlsSession = null; + this.m_sessionParameters = null; + this.m_sessionMasterSecret = null; + + if (null == sessionToResume || !sessionToResume.IsResumable) + return false; + + SessionParameters sessionParameters = sessionToResume.ExportSessionParameters(); + if (null == sessionParameters) + return false; + + if (!sessionParameters.IsExtendedMasterSecret) + { + TlsPeer peer = Peer; + if (!peer.AllowLegacyResumption() || peer.RequiresExtendedMasterSecret()) + return false; + + /* + * NOTE: For session resumption without extended_master_secret, renegotiation MUST be + * disabled (see RFC 7627 5.4). We currently do not implement renegotiation and it is + * unlikely we ever would since it was removed in TLS 1.3. + */ + } + + TlsSecret sessionMasterSecret = TlsUtilities.GetSessionMasterSecret(Context.Crypto, + sessionParameters.MasterSecret); + if (null == sessionMasterSecret) + return false; + + this.m_tlsSession = sessionToResume; + this.m_sessionParameters = sessionParameters; + this.m_sessionMasterSecret = sessionMasterSecret; + + return true; + } + + protected virtual void InvalidateSession() + { + if (m_sessionMasterSecret != null) + { + m_sessionMasterSecret.Destroy(); + this.m_sessionMasterSecret = null; + } + + if (m_sessionParameters != null) + { + m_sessionParameters.Clear(); + this.m_sessionParameters = null; + } + + if (m_tlsSession != null) + { + m_tlsSession.Invalidate(); + this.m_tlsSession = null; + } + } + + /// + protected virtual void ProcessFinishedMessage(MemoryStream buf) + { + TlsContext context = Context; + SecurityParameters securityParameters = context.SecurityParameters; + bool isServerContext = context.IsServer; + + byte[] verify_data = TlsUtilities.ReadFully(securityParameters.VerifyDataLength, buf); + + AssertEmpty(buf); + + byte[] expected_verify_data = TlsUtilities.CalculateVerifyData(context, m_handshakeHash, !isServerContext); + + /* + * Compare both checksums. + */ + if (!Arrays.ConstantTimeAreEqual(expected_verify_data, verify_data)) + { + /* + * Wrong checksum in the finished message. + */ + throw new TlsFatalAlert(AlertDescription.decrypt_error); + } + + securityParameters.m_peerVerifyData = expected_verify_data; + + if (!m_resumedSession || securityParameters.IsExtendedMasterSecret) + { + if (null == securityParameters.LocalVerifyData) + { + securityParameters.m_tlsUnique = expected_verify_data; + } + } + } + + /// + protected virtual void Process13FinishedMessage(MemoryStream buf) + { + TlsContext context = Context; + SecurityParameters securityParameters = context.SecurityParameters; + bool isServerContext = context.IsServer; + + byte[] verify_data = TlsUtilities.ReadFully(securityParameters.VerifyDataLength, buf); + + AssertEmpty(buf); + + byte[] expected_verify_data = TlsUtilities.CalculateVerifyData(context, m_handshakeHash, !isServerContext); + + /* + * Compare both checksums. + */ + if (!Arrays.ConstantTimeAreEqual(expected_verify_data, verify_data)) + { + /* + * Wrong checksum in the finished message. + */ + throw new TlsFatalAlert(AlertDescription.decrypt_error); + } + + securityParameters.m_peerVerifyData = expected_verify_data; + securityParameters.m_tlsUnique = null; + } + + /// + protected virtual void RaiseAlertFatal(short alertDescription, string message, Exception cause) + { + Peer.NotifyAlertRaised(AlertLevel.fatal, alertDescription, message, cause); + + byte[] alert = new byte[]{ (byte)AlertLevel.fatal, (byte)alertDescription }; + + try + { + m_recordStream.WriteRecord(ContentType.alert, alert, 0, 2); + } + catch (Exception) + { + // We are already processing an exception, so just ignore this + } + } + + /// + protected virtual void RaiseAlertWarning(short alertDescription, string message) + { + Peer.NotifyAlertRaised(AlertLevel.warning, alertDescription, message, null); + + byte[] alert = new byte[]{ (byte)AlertLevel.warning, (byte)alertDescription }; + + SafeWriteRecord(ContentType.alert, alert, 0, 2); + } + + + /// + protected virtual void Receive13KeyUpdate(MemoryStream buf) + { + // TODO[tls13] This is interesting enough to notify the TlsPeer for possible logging/vetting + + if (!(m_appDataReady && m_keyUpdateEnabled)) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + + short requestUpdate = TlsUtilities.ReadUint8(buf); + + AssertEmpty(buf); + + if (!KeyUpdateRequest.IsValid(requestUpdate)) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + bool updateRequested = (KeyUpdateRequest.update_requested == requestUpdate); + + TlsUtilities.Update13TrafficSecretPeer(Context); + m_recordStream.NotifyKeyUpdateReceived(); + + //this.m_keyUpdatePendingReceive &= updateRequested; + this.m_keyUpdatePendingSend |= updateRequested; + } + + /// + protected virtual void SendCertificateMessage(Certificate certificate, Stream endPointHash) + { + TlsContext context = Context; + SecurityParameters securityParameters = context.SecurityParameters; + if (null != securityParameters.LocalCertificate) + throw new TlsFatalAlert(AlertDescription.internal_error); + + if (null == certificate) + { + certificate = Certificate.EmptyChain; + } + + if (certificate.IsEmpty && !context.IsServer && securityParameters.NegotiatedVersion.IsSsl) + { + string message = "SSLv3 client didn't provide credentials"; + RaiseAlertWarning(AlertDescription.no_certificate, message); + } + else + { + HandshakeMessageOutput message = new HandshakeMessageOutput(HandshakeType.certificate); + certificate.Encode(context, message, endPointHash); + message.Send(this); + } + + securityParameters.m_localCertificate = certificate; + } + + /// + protected virtual void Send13CertificateMessage(Certificate certificate) + { + if (null == certificate) + throw new TlsFatalAlert(AlertDescription.internal_error); + + TlsContext context = Context; + SecurityParameters securityParameters = context.SecurityParameters; + if (null != securityParameters.LocalCertificate) + throw new TlsFatalAlert(AlertDescription.internal_error); + + HandshakeMessageOutput message = new HandshakeMessageOutput(HandshakeType.certificate); + certificate.Encode(context, message, null); + message.Send(this); + + securityParameters.m_localCertificate = certificate; + } + + /// + protected virtual void Send13CertificateVerifyMessage(DigitallySigned certificateVerify) + { + HandshakeMessageOutput message = new HandshakeMessageOutput(HandshakeType.certificate_verify); + certificateVerify.Encode(message); + message.Send(this); + } + + /// + protected virtual void SendChangeCipherSpec() + { + SendChangeCipherSpecMessage(); + m_recordStream.EnablePendingCipherWrite(); + } + + /// + protected virtual void SendChangeCipherSpecMessage() + { + byte[] message = new byte[]{ 1 }; + SafeWriteRecord(ContentType.change_cipher_spec, message, 0, message.Length); + } + + /// + protected virtual void SendFinishedMessage() + { + TlsContext context = Context; + SecurityParameters securityParameters = context.SecurityParameters; + bool isServerContext = context.IsServer; + + byte[] verify_data = TlsUtilities.CalculateVerifyData(context, m_handshakeHash, isServerContext); + + securityParameters.m_localVerifyData = verify_data; + + if (!m_resumedSession || securityParameters.IsExtendedMasterSecret) + { + if (null == securityParameters.PeerVerifyData) + { + securityParameters.m_tlsUnique = verify_data; + } + } + + HandshakeMessageOutput.Send(this, HandshakeType.finished, verify_data); + } + + /// + protected virtual void Send13FinishedMessage() + { + TlsContext context = Context; + SecurityParameters securityParameters = context.SecurityParameters; + bool isServerContext = context.IsServer; + + byte[] verify_data = TlsUtilities.CalculateVerifyData(context, m_handshakeHash, isServerContext); + + securityParameters.m_localVerifyData = verify_data; + securityParameters.m_tlsUnique = null; + + HandshakeMessageOutput.Send(this, HandshakeType.finished, verify_data); + } + + /// + protected virtual void Send13KeyUpdate(bool updateRequested) + { + // TODO[tls13] This is interesting enough to notify the TlsPeer for possible logging/vetting + + if (!(m_appDataReady && m_keyUpdateEnabled)) + throw new TlsFatalAlert(AlertDescription.internal_error); + + short requestUpdate = updateRequested + ? KeyUpdateRequest.update_requested + : KeyUpdateRequest.update_not_requested; + + HandshakeMessageOutput.Send(this, HandshakeType.key_update, TlsUtilities.EncodeUint8(requestUpdate)); + + TlsUtilities.Update13TrafficSecretLocal(Context); + m_recordStream.NotifyKeyUpdateSent(); + + //this.m_keyUpdatePendingReceive |= updateRequested; + this.m_keyUpdatePendingSend &= updateRequested; + } + + /// + protected virtual void SendSupplementalDataMessage(IList supplementalData) + { + HandshakeMessageOutput message = new HandshakeMessageOutput(HandshakeType.supplemental_data); + WriteSupplementalData(message, supplementalData); + message.Send(this); + } + + public virtual void Close() + { + HandleClose(true); + } + + public virtual void Flush() + { + } + + internal bool IsApplicationDataReady + { + get { return m_appDataReady; } + } + + public virtual bool IsClosed + { + get { return m_closed; } + } + + public virtual bool IsConnected + { + get + { + if (m_closed) + return false; + + AbstractTlsContext context = ContextAdmin; + + return null != context && context.IsConnected; + } + } + + public virtual bool IsHandshaking + { + get + { + if (m_closed) + return false; + + AbstractTlsContext context = ContextAdmin; + + return null != context && context.IsHandshaking; + } + } + + /// + protected virtual short ProcessMaxFragmentLengthExtension(IDictionary clientExtensions, + IDictionary serverExtensions, short alertDescription) + { + short maxFragmentLength = TlsExtensionsUtilities.GetMaxFragmentLengthExtension(serverExtensions); + if (maxFragmentLength >= 0) + { + if (!MaxFragmentLength.IsValid(maxFragmentLength) + || (!m_resumedSession && + maxFragmentLength != TlsExtensionsUtilities.GetMaxFragmentLengthExtension(clientExtensions))) + { + throw new TlsFatalAlert(alertDescription); + } + } + return maxFragmentLength; + } + + /// + protected virtual void RefuseRenegotiation() + { + /* + * RFC 5746 4.5 SSLv3 clients [..] SHOULD use a fatal handshake_failure alert. + */ + if (TlsUtilities.IsSsl(Context)) + throw new TlsFatalAlert(AlertDescription.handshake_failure); + + RaiseAlertWarning(AlertDescription.no_renegotiation, "Renegotiation not supported"); + } + + /// Make sure the 'buf' is now empty. Fail otherwise. + /// The to check. + /// + internal static void AssertEmpty(MemoryStream buf) + { + if (buf.Position < buf.Length) + throw new TlsFatalAlert(AlertDescription.decode_error); + } + + internal static byte[] CreateRandomBlock(bool useGmtUnixTime, TlsContext context) + { + byte[] result = context.NonceGenerator.GenerateNonce(32); + + if (useGmtUnixTime) + { + TlsUtilities.WriteGmtUnixTime(result, 0); + } + + return result; + } + + /// + internal static byte[] CreateRenegotiationInfo(byte[] renegotiated_connection) + { + return TlsUtilities.EncodeOpaque8(renegotiated_connection); + } + + /// + internal static void EstablishMasterSecret(TlsContext context, TlsKeyExchange keyExchange) + { + TlsSecret preMasterSecret = keyExchange.GeneratePreMasterSecret(); + if (preMasterSecret == null) + throw new TlsFatalAlert(AlertDescription.internal_error); + + try + { + context.SecurityParameters.m_masterSecret = TlsUtilities.CalculateMasterSecret(context, + preMasterSecret); + } + finally + { + /* + * RFC 2246 8.1. The pre_master_secret should be deleted from memory once the + * master_secret has been computed. + */ + preMasterSecret.Destroy(); + } + } + + /// + internal static IDictionary ReadExtensions(MemoryStream input) + { + if (input.Position >= input.Length) + return null; + + byte[] extBytes = TlsUtilities.ReadOpaque16(input); + + AssertEmpty(input); + + return ReadExtensionsData(extBytes); + } + + /// + internal static IDictionary ReadExtensionsData(byte[] extBytes) + { + // Int32 -> byte[] + IDictionary extensions = Platform.CreateHashtable(); + + if (extBytes.Length > 0) + { + MemoryStream buf = new MemoryStream(extBytes, false); + + do + { + int extension_type = TlsUtilities.ReadUint16(buf); + byte[] extension_data = TlsUtilities.ReadOpaque16(buf); + + /* + * RFC 3546 2.3 There MUST NOT be more than one extension of the same type. + */ + Int32 key = extension_type; + if (extensions.Contains(key)) + throw new TlsFatalAlert(AlertDescription.illegal_parameter, + "Repeated extension: " + ExtensionType.GetText(extension_type)); + + extensions.Add(key, extension_data); + } + while (buf.Position < buf.Length); + } + + return extensions; + } + + /// + internal static IDictionary ReadExtensionsData13(int handshakeType, byte[] extBytes) + { + // Int32 -> byte[] + IDictionary extensions = Platform.CreateHashtable(); + + if (extBytes.Length > 0) + { + MemoryStream buf = new MemoryStream(extBytes, false); + + do + { + int extension_type = TlsUtilities.ReadUint16(buf); + + if (!TlsUtilities.IsPermittedExtensionType13(handshakeType, extension_type)) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter, + "Invalid extension: " + ExtensionType.GetText(extension_type)); + } + + byte[] extension_data = TlsUtilities.ReadOpaque16(buf); + + /* + * RFC 3546 2.3 There MUST NOT be more than one extension of the same type. + */ + Int32 key = extension_type; + if (extensions.Contains(key)) + throw new TlsFatalAlert(AlertDescription.illegal_parameter, + "Repeated extension: " + ExtensionType.GetText(extension_type)); + + extensions.Add(key, extension_data); + } + while (buf.Position < buf.Length); + } + + return extensions; + } + + /// + internal static IDictionary ReadExtensionsDataClientHello(byte[] extBytes) + { + /* + * TODO[tls13] We are currently allowing any extensions to appear in ClientHello. It is + * somewhat complicated to restrict what can appear based on the specific set of versions + * the client is offering, and anyway could be fragile since clients may take a + * "kitchen sink" approach to adding extensions independently of the offered versions. + */ + + // Int32 -> byte[] + IDictionary extensions = Platform.CreateHashtable(); + + if (extBytes.Length > 0) + { + MemoryStream buf = new MemoryStream(extBytes, false); + + int extension_type; + bool pre_shared_key_found = false; + + do + { + extension_type = TlsUtilities.ReadUint16(buf); + byte[] extension_data = TlsUtilities.ReadOpaque16(buf); + + /* + * RFC 3546 2.3 There MUST NOT be more than one extension of the same type. + */ + Int32 key = extension_type; + if (extensions.Contains(key)) + throw new TlsFatalAlert(AlertDescription.illegal_parameter, + "Repeated extension: " + ExtensionType.GetText(extension_type)); + + extensions.Add(key, extension_data); + + pre_shared_key_found |= (ExtensionType.pre_shared_key == extension_type); + } + while (buf.Position < buf.Length); + + if (pre_shared_key_found && (ExtensionType.pre_shared_key != extension_type)) + throw new TlsFatalAlert(AlertDescription.illegal_parameter, + "'pre_shared_key' MUST be last in ClientHello"); + } + + return extensions; + } + + /// + internal static IList ReadSupplementalDataMessage(MemoryStream input) + { + byte[] supp_data = TlsUtilities.ReadOpaque24(input, 1); + + AssertEmpty(input); + + MemoryStream buf = new MemoryStream(supp_data, false); + + IList supplementalData = Platform.CreateArrayList(); + + while (buf.Position < buf.Length) + { + int supp_data_type = TlsUtilities.ReadUint16(buf); + byte[] data = TlsUtilities.ReadOpaque16(buf); + + supplementalData.Add(new SupplementalDataEntry(supp_data_type, data)); + } + + return supplementalData; + } + + /// + internal static void WriteExtensions(Stream output, IDictionary extensions) + { + WriteExtensions(output, extensions, 0); + } + + /// + internal static void WriteExtensions(Stream output, IDictionary extensions, int bindersSize) + { + if (null == extensions || extensions.Count < 1) + return; + + byte[] extBytes = WriteExtensionsData(extensions, bindersSize); + + int lengthWithBinders = extBytes.Length + bindersSize; + TlsUtilities.CheckUint16(lengthWithBinders); + TlsUtilities.WriteUint16(lengthWithBinders, output); + output.Write(extBytes, 0, extBytes.Length); + } + + /// + internal static byte[] WriteExtensionsData(IDictionary extensions) + { + return WriteExtensionsData(extensions, 0); + } + + /// + internal static byte[] WriteExtensionsData(IDictionary extensions, int bindersSize) + { + MemoryStream buf = new MemoryStream(); + WriteExtensionsData(extensions, buf, bindersSize); + return buf.ToArray(); + } + + /// + internal static void WriteExtensionsData(IDictionary extensions, MemoryStream buf) + { + WriteExtensionsData(extensions, buf, 0); + } + + /// + internal static void WriteExtensionsData(IDictionary extensions, MemoryStream buf, int bindersSize) + { + /* + * NOTE: There are reports of servers that don't accept a zero-length extension as the last + * one, so we write out any zero-length ones first as a best-effort workaround. + */ + WriteSelectedExtensions(buf, extensions, true); + WriteSelectedExtensions(buf, extensions, false); + WritePreSharedKeyExtension(buf, extensions, bindersSize); + } + + /// + internal static void WritePreSharedKeyExtension(MemoryStream buf, IDictionary extensions, int bindersSize) + { + byte[] extension_data = (byte[])extensions[ExtensionType.pre_shared_key]; + if (null != extension_data) + { + TlsUtilities.CheckUint16(ExtensionType.pre_shared_key); + TlsUtilities.WriteUint16(ExtensionType.pre_shared_key, buf); + + int lengthWithBinders = extension_data.Length + bindersSize; + TlsUtilities.CheckUint16(lengthWithBinders); + TlsUtilities.WriteUint16(lengthWithBinders, buf); + buf.Write(extension_data, 0, extension_data.Length); + } + } + + /// + internal static void WriteSelectedExtensions(Stream output, IDictionary extensions, bool selectEmpty) + { + foreach (Int32 key in extensions.Keys) + { + int extension_type = key; + + // NOTE: Must be last; handled by 'WritePreSharedKeyExtension' + if (ExtensionType.pre_shared_key == extension_type) + continue; + + byte[] extension_data = (byte[])extensions[key]; + + if (selectEmpty == (extension_data.Length == 0)) + { + TlsUtilities.CheckUint16(extension_type); + TlsUtilities.WriteUint16(extension_type, output); + TlsUtilities.WriteOpaque16(extension_data, output); + } + } + } + + /// + internal static void WriteSupplementalData(Stream output, IList supplementalData) + { + MemoryStream buf = new MemoryStream(); + + foreach (SupplementalDataEntry entry in supplementalData) + { + int supp_data_type = entry.DataType; + TlsUtilities.CheckUint16(supp_data_type); + TlsUtilities.WriteUint16(supp_data_type, buf); + TlsUtilities.WriteOpaque16(entry.Data, buf); + } + + byte[] supp_data = buf.ToArray(); + + TlsUtilities.WriteOpaque24(supp_data, output); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsProtocol.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsProtocol.cs.meta new file mode 100644 index 0000000..da4c9b8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsProtocol.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3c2c124af38d7e54e86ae5c9009783fb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsPsk.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsPsk.cs new file mode 100644 index 0000000..c3aac32 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsPsk.cs @@ -0,0 +1,15 @@ +using System; + +using Org.BouncyCastle.Tls.Crypto; + +namespace Org.BouncyCastle.Tls +{ + public interface TlsPsk + { + byte[] Identity { get; } + + TlsSecret Key { get; } + + int PrfAlgorithm { get; } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsPsk.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsPsk.cs.meta new file mode 100644 index 0000000..91f2c92 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsPsk.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 67c5d2fc47dab43489659f7a4a3fc2eb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsPskExternal.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsPskExternal.cs new file mode 100644 index 0000000..1e7b717 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsPskExternal.cs @@ -0,0 +1,9 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + public interface TlsPskExternal + : TlsPsk + { + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsPskExternal.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsPskExternal.cs.meta new file mode 100644 index 0000000..320778a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsPskExternal.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c4a30bb42adca7a41b656bdaf021ecbf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsPskIdentity.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsPskIdentity.cs new file mode 100644 index 0000000..ae78872 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsPskIdentity.cs @@ -0,0 +1,16 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + /// Processor interface for a PSK identity. + public interface TlsPskIdentity + { + void SkipIdentityHint(); + + void NotifyIdentityHint(byte[] psk_identity_hint); + + byte[] GetPskIdentity(); + + byte[] GetPsk(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsPskIdentity.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsPskIdentity.cs.meta new file mode 100644 index 0000000..773d8bd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsPskIdentity.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 30ed61a7589ef974184bc82af577947d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsPskIdentityManager.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsPskIdentityManager.cs new file mode 100644 index 0000000..5bf10bc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsPskIdentityManager.cs @@ -0,0 +1,12 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + /// Base interface for an object that can process a PSK identity. + public interface TlsPskIdentityManager + { + byte[] GetHint(); + + byte[] GetPsk(byte[] identity); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsPskIdentityManager.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsPskIdentityManager.cs.meta new file mode 100644 index 0000000..6b27593 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsPskIdentityManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d48081a78b339a74ca48974a39b52283 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsPskKeyExchange.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsPskKeyExchange.cs new file mode 100644 index 0000000..8a279c6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsPskKeyExchange.cs @@ -0,0 +1,305 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Tls.Crypto; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls +{ + /// (D)TLS PSK key exchange (RFC 4279). + public class TlsPskKeyExchange + : AbstractTlsKeyExchange + { + private static int CheckKeyExchange(int keyExchange) + { + switch (keyExchange) + { + case KeyExchangeAlgorithm.DHE_PSK: + case KeyExchangeAlgorithm.ECDHE_PSK: + case KeyExchangeAlgorithm.PSK: + case KeyExchangeAlgorithm.RSA_PSK: + return keyExchange; + default: + throw new ArgumentException("unsupported key exchange algorithm", "keyExchange"); + } + } + + protected TlsPskIdentity m_pskIdentity; + protected TlsPskIdentityManager m_pskIdentityManager; + protected TlsDHGroupVerifier m_dhGroupVerifier; + + protected byte[] m_psk_identity_hint = null; + protected byte[] m_psk = null; + + protected TlsDHConfig m_dhConfig; + protected TlsECConfig m_ecConfig; + protected TlsAgreement m_agreement; + + protected TlsCredentialedDecryptor m_serverCredentials = null; + protected TlsEncryptor m_serverEncryptor; + protected TlsSecret m_preMasterSecret; + + public TlsPskKeyExchange(int keyExchange, TlsPskIdentity pskIdentity, TlsDHGroupVerifier dhGroupVerifier) + : this(keyExchange, pskIdentity, null, dhGroupVerifier, null, null) + { + } + + public TlsPskKeyExchange(int keyExchange, TlsPskIdentityManager pskIdentityManager, + TlsDHConfig dhConfig, TlsECConfig ecConfig) + : this(keyExchange, null, pskIdentityManager, null, dhConfig, ecConfig) + { + } + + private TlsPskKeyExchange(int keyExchange, TlsPskIdentity pskIdentity, TlsPskIdentityManager pskIdentityManager, + TlsDHGroupVerifier dhGroupVerifier, TlsDHConfig dhConfig, TlsECConfig ecConfig) + : base(CheckKeyExchange(keyExchange)) + { + this.m_pskIdentity = pskIdentity; + this.m_pskIdentityManager = pskIdentityManager; + this.m_dhGroupVerifier = dhGroupVerifier; + this.m_dhConfig = dhConfig; + this.m_ecConfig = ecConfig; + } + + public override void SkipServerCredentials() + { + if (m_keyExchange == KeyExchangeAlgorithm.RSA_PSK) + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public override void ProcessServerCredentials(TlsCredentials serverCredentials) + { + if (m_keyExchange != KeyExchangeAlgorithm.RSA_PSK) + throw new TlsFatalAlert(AlertDescription.internal_error); + + this.m_serverCredentials = TlsUtilities.RequireDecryptorCredentials(serverCredentials); + } + + public override void ProcessServerCertificate(Certificate serverCertificate) + { + if (m_keyExchange != KeyExchangeAlgorithm.RSA_PSK) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + + this.m_serverEncryptor = serverCertificate.GetCertificateAt(0).CreateEncryptor( + TlsCertificateRole.RsaEncryption); + } + + public override byte[] GenerateServerKeyExchange() + { + this.m_psk_identity_hint = m_pskIdentityManager.GetHint(); + + if (this.m_psk_identity_hint == null && !RequiresServerKeyExchange) + return null; + + MemoryStream buf = new MemoryStream(); + + if (this.m_psk_identity_hint == null) + { + TlsUtilities.WriteOpaque16(TlsUtilities.EmptyBytes, buf); + } + else + { + TlsUtilities.WriteOpaque16(this.m_psk_identity_hint, buf); + } + + if (this.m_keyExchange == KeyExchangeAlgorithm.DHE_PSK) + { + if (this.m_dhConfig == null) + throw new TlsFatalAlert(AlertDescription.internal_error); + + TlsDHUtilities.WriteDHConfig(m_dhConfig, buf); + + this.m_agreement = m_context.Crypto.CreateDHDomain(m_dhConfig).CreateDH(); + + GenerateEphemeralDH(buf); + } + else if (this.m_keyExchange == KeyExchangeAlgorithm.ECDHE_PSK) + { + if (this.m_ecConfig == null) + throw new TlsFatalAlert(AlertDescription.internal_error); + + TlsEccUtilities.WriteECConfig(m_ecConfig, buf); + + this.m_agreement = m_context.Crypto.CreateECDomain(m_ecConfig).CreateECDH(); + + GenerateEphemeralECDH(buf); + } + + return buf.ToArray(); + } + + public override bool RequiresServerKeyExchange + { + get + { + switch (m_keyExchange) + { + case KeyExchangeAlgorithm.DHE_PSK: + case KeyExchangeAlgorithm.ECDHE_PSK: + return true; + default: + return false; + } + } + } + + public override void ProcessServerKeyExchange(Stream input) + { + this.m_psk_identity_hint = TlsUtilities.ReadOpaque16(input); + + if (this.m_keyExchange == KeyExchangeAlgorithm.DHE_PSK) + { + this.m_dhConfig = TlsDHUtilities.ReceiveDHConfig(m_context, m_dhGroupVerifier, input); + + byte[] y = TlsUtilities.ReadOpaque16(input, 1); + + this.m_agreement = m_context.Crypto.CreateDHDomain(m_dhConfig).CreateDH(); + + ProcessEphemeralDH(y); + } + else if (this.m_keyExchange == KeyExchangeAlgorithm.ECDHE_PSK) + { + this.m_ecConfig = TlsEccUtilities.ReceiveECDHConfig(m_context, input); + + byte[] point = TlsUtilities.ReadOpaque8(input, 1); + + this.m_agreement = m_context.Crypto.CreateECDomain(m_ecConfig).CreateECDH(); + + ProcessEphemeralECDH(point); + } + } + + public override void ProcessClientCredentials(TlsCredentials clientCredentials) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public override void GenerateClientKeyExchange(Stream output) + { + if (m_psk_identity_hint == null) + { + m_pskIdentity.SkipIdentityHint(); + } + else + { + m_pskIdentity.NotifyIdentityHint(m_psk_identity_hint); + } + + byte[] psk_identity = m_pskIdentity.GetPskIdentity(); + if (psk_identity == null) + throw new TlsFatalAlert(AlertDescription.internal_error); + + this.m_psk = m_pskIdentity.GetPsk(); + if (m_psk == null) + throw new TlsFatalAlert(AlertDescription.internal_error); + + TlsUtilities.WriteOpaque16(psk_identity, output); + + m_context.SecurityParameters.m_pskIdentity = Arrays.Clone(psk_identity); + + if (this.m_keyExchange == KeyExchangeAlgorithm.DHE_PSK) + { + GenerateEphemeralDH(output); + } + else if (this.m_keyExchange == KeyExchangeAlgorithm.ECDHE_PSK) + { + GenerateEphemeralECDH(output); + } + else if (this.m_keyExchange == KeyExchangeAlgorithm.RSA_PSK) + { + this.m_preMasterSecret = TlsUtilities.GenerateEncryptedPreMasterSecret(m_context, m_serverEncryptor, + output); + } + } + + public override void ProcessClientKeyExchange(Stream input) + { + byte[] psk_identity = TlsUtilities.ReadOpaque16(input); + + this.m_psk = m_pskIdentityManager.GetPsk(psk_identity); + if (m_psk == null) + throw new TlsFatalAlert(AlertDescription.unknown_psk_identity); + + m_context.SecurityParameters.m_pskIdentity = psk_identity; + + if (this.m_keyExchange == KeyExchangeAlgorithm.DHE_PSK) + { + byte[] y = TlsUtilities.ReadOpaque16(input, 1); + + ProcessEphemeralDH(y); + } + else if (this.m_keyExchange == KeyExchangeAlgorithm.ECDHE_PSK) + { + byte[] point = TlsUtilities.ReadOpaque8(input, 1); + + ProcessEphemeralECDH(point); + } + else if (this.m_keyExchange == KeyExchangeAlgorithm.RSA_PSK) + { + byte[] encryptedPreMasterSecret = TlsUtilities.ReadEncryptedPms(m_context, input); + + this.m_preMasterSecret = m_serverCredentials.Decrypt(new TlsCryptoParameters(m_context), + encryptedPreMasterSecret); + } + } + + public override TlsSecret GeneratePreMasterSecret() + { + byte[] other_secret = GenerateOtherSecret(m_psk.Length); + + MemoryStream buf = new MemoryStream(4 + other_secret.Length + m_psk.Length); + TlsUtilities.WriteOpaque16(other_secret, buf); + TlsUtilities.WriteOpaque16(m_psk, buf); + + Array.Clear(m_psk, 0, m_psk.Length); + this.m_psk = null; + + return m_context.Crypto.CreateSecret(buf.ToArray()); + } + + protected virtual void GenerateEphemeralDH(Stream output) + { + byte[] y = m_agreement.GenerateEphemeral(); + TlsUtilities.WriteOpaque16(y, output); + } + + protected virtual void GenerateEphemeralECDH(Stream output) + { + byte[] point = m_agreement.GenerateEphemeral(); + TlsUtilities.WriteOpaque8(point, output); + } + + protected virtual byte[] GenerateOtherSecret(int pskLength) + { + if (this.m_keyExchange == KeyExchangeAlgorithm.PSK) + return new byte[pskLength]; + + if (this.m_keyExchange == KeyExchangeAlgorithm.DHE_PSK || + this.m_keyExchange == KeyExchangeAlgorithm.ECDHE_PSK) + { + if (m_agreement != null) + return m_agreement.CalculateSecret().Extract(); + } + + if (this.m_keyExchange == KeyExchangeAlgorithm.RSA_PSK) + { + if (m_preMasterSecret != null) + return this.m_preMasterSecret.Extract(); + } + + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + protected virtual void ProcessEphemeralDH(byte[] y) + { + this.m_agreement.ReceivePeerValue(y); + } + + protected virtual void ProcessEphemeralECDH(byte[] point) + { + TlsEccUtilities.CheckPointEncoding(m_ecConfig.NamedGroup, point); + + this.m_agreement.ReceivePeerValue(point); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsPskKeyExchange.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsPskKeyExchange.cs.meta new file mode 100644 index 0000000..2a4493a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsPskKeyExchange.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a052e0c5e14e7b6478fac961a99a116f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsRsaKeyExchange.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsRsaKeyExchange.cs new file mode 100644 index 0000000..a2f5559 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsRsaKeyExchange.cs @@ -0,0 +1,80 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Tls.Crypto; + +namespace Org.BouncyCastle.Tls +{ + /// (D)TLS RSA key exchange. + public class TlsRsaKeyExchange + : AbstractTlsKeyExchange + { + private static int CheckKeyExchange(int keyExchange) + { + switch (keyExchange) + { + case KeyExchangeAlgorithm.RSA: + return keyExchange; + default: + throw new ArgumentException("unsupported key exchange algorithm", "keyExchange"); + } + } + + protected TlsCredentialedDecryptor m_serverCredentials = null; + protected TlsEncryptor m_serverEncryptor; + protected TlsSecret m_preMasterSecret; + + public TlsRsaKeyExchange(int keyExchange) + : base(CheckKeyExchange(keyExchange)) + { + } + + public override void SkipServerCredentials() + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public override void ProcessServerCredentials(TlsCredentials serverCredentials) + { + this.m_serverCredentials = TlsUtilities.RequireDecryptorCredentials(serverCredentials); + } + + public override void ProcessServerCertificate(Certificate serverCertificate) + { + this.m_serverEncryptor = serverCertificate.GetCertificateAt(0).CreateEncryptor( + TlsCertificateRole.RsaEncryption); + } + + public override short[] GetClientCertificateTypes() + { + return new short[]{ ClientCertificateType.rsa_sign, ClientCertificateType.dss_sign, + ClientCertificateType.ecdsa_sign }; + } + + public override void ProcessClientCredentials(TlsCredentials clientCredentials) + { + TlsUtilities.RequireSignerCredentials(clientCredentials); + } + + public override void GenerateClientKeyExchange(Stream output) + { + this.m_preMasterSecret = TlsUtilities.GenerateEncryptedPreMasterSecret(m_context, m_serverEncryptor, + output); + } + + public override void ProcessClientKeyExchange(Stream input) + { + byte[] encryptedPreMasterSecret = TlsUtilities.ReadEncryptedPms(m_context, input); + + this.m_preMasterSecret = m_serverCredentials.Decrypt(new TlsCryptoParameters(m_context), + encryptedPreMasterSecret); + } + + public override TlsSecret GeneratePreMasterSecret() + { + TlsSecret tmp = this.m_preMasterSecret; + this.m_preMasterSecret = null; + return tmp; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsRsaKeyExchange.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsRsaKeyExchange.cs.meta new file mode 100644 index 0000000..2d448b1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsRsaKeyExchange.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bbd99fdca3f7742459c79d79a28c2d5b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsServer.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsServer.cs new file mode 100644 index 0000000..fe88d7c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsServer.cs @@ -0,0 +1,130 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Tls.Crypto; + +namespace Org.BouncyCastle.Tls +{ + /// Interface describing a TLS server endpoint. + public interface TlsServer + : TlsPeer + { + void Init(TlsServerContext context); + + /// Return the specified session, if available. + /// + /// Note that the peer's certificate chain for the session (if any) may need to be periodically revalidated. + /// + /// the ID of the session to resume. + /// A with the specified session ID, or null. + /// + TlsSession GetSessionToResume(byte[] sessionID); + + byte[] GetNewSessionID(); + + /// Return the external PSK to select from the ClientHello. + /// + /// WARNING: EXPERIMENTAL FEATURE, UNSTABLE API + /// Note that this will only be called when TLS 1.3 or higher is amongst the offered protocol versions, and one + /// or more PSKs are actually offered. + /// + /// an of instances. + /// The corresponding to the selected identity, or null to not select + /// any. + TlsPskExternal GetExternalPsk(IList identities); + + void NotifySession(TlsSession session); + + /// + void NotifyClientVersion(ProtocolVersion clientVersion); + + /// + void NotifyFallback(bool isFallback); + + /// + void NotifyOfferedCipherSuites(int[] offeredCipherSuites); + + /// (Int32 -> byte[]) + /// + void ProcessClientExtensions(IDictionary clientExtensions); + + /// + ProtocolVersion GetServerVersion(); + + /// + int[] GetSupportedGroups(); + + /// + int GetSelectedCipherSuite(); + + /// (Int32 -> byte[]) + /// + IDictionary GetServerExtensions(); + + /// (Int32 -> byte[]) + /// + void GetServerExtensionsForConnection(IDictionary serverExtensions); + + /// (SupplementalDataEntry) + /// + IList GetServerSupplementalData(); + + /// Return server credentials to use. + /// + /// The returned value may be null, or else it MUST implement exactly one of + /// , , or + /// , depending on the key exchange that was negotiated. + /// + /// a object or null for anonymous key exchanges. + /// + TlsCredentials GetCredentials(); + + /// + /// This method will be called (only) if the server included an extension of type "status_request" with empty + /// "extension_data" in the extended server hello. See RFC 3546 3.6. Certificate Status Request. If a + /// non-null is returned, it is sent to the client as a handshake message of + /// type "certificate_status". + /// + /// A to be sent to the client (or null for none). + /// + CertificateStatus GetCertificateStatus(); + + /// + CertificateRequest GetCertificateRequest(); + + /// + TlsPskIdentityManager GetPskIdentityManager(); + + /// + TlsSrpLoginParameters GetSrpLoginParameters(); + + /// + TlsDHConfig GetDHConfig(); + + /// + TlsECConfig GetECDHConfig(); + + /// (SupplementalDataEntry) + /// + void ProcessClientSupplementalData(IList clientSupplementalData); + + /// Called by the protocol handler to report the client certificate, only if + /// returned non-null. + /// + /// Note: this method is responsible for certificate verification and validation. + /// + /// the effective client certificate (may be an empty chain). + /// + void NotifyClientCertificate(Certificate clientCertificate); + + /// RFC 5077 3.3. NewSessionTicket Handshake Message. + /// + /// This method will be called (only) if a NewSessionTicket extension was sent by the server. See RFC 5077 + /// 4. Recommended Ticket Construction for recommended format and protection. + /// + /// The ticket. + /// + NewSessionTicket GetNewSessionTicket(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsServer.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsServer.cs.meta new file mode 100644 index 0000000..ff9efcf --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsServer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 000d867b0d310fb4bb44942abd6628d5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsServerCertificate.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsServerCertificate.cs new file mode 100644 index 0000000..bea896a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsServerCertificate.cs @@ -0,0 +1,12 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + /// Server certificate carrier interface. + public interface TlsServerCertificate + { + Certificate Certificate { get; } + + CertificateStatus CertificateStatus { get; } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsServerCertificate.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsServerCertificate.cs.meta new file mode 100644 index 0000000..966354d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsServerCertificate.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 31398d71d8c67494db07f16301fe0d74 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsServerCertificateImpl.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsServerCertificateImpl.cs new file mode 100644 index 0000000..db2d091 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsServerCertificateImpl.cs @@ -0,0 +1,27 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + internal sealed class TlsServerCertificateImpl + : TlsServerCertificate + { + private readonly Certificate m_certificate; + private readonly CertificateStatus m_certificateStatus; + + internal TlsServerCertificateImpl(Certificate certificate, CertificateStatus certificateStatus) + { + this.m_certificate = certificate; + this.m_certificateStatus = certificateStatus; + } + + public Certificate Certificate + { + get { return m_certificate; } + } + + public CertificateStatus CertificateStatus + { + get { return m_certificateStatus; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsServerCertificateImpl.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsServerCertificateImpl.cs.meta new file mode 100644 index 0000000..68b06e1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsServerCertificateImpl.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0b4a6f33d85e3054eafafc16b51709bb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsServerContext.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsServerContext.cs new file mode 100644 index 0000000..85a0751 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsServerContext.cs @@ -0,0 +1,10 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + /// Marker interface to distinguish a TLS server context. + public interface TlsServerContext + : TlsContext + { + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsServerContext.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsServerContext.cs.meta new file mode 100644 index 0000000..33847af --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsServerContext.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7050c2adf1f3b6e4f82cce05cc77f4aa +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsServerContextImpl.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsServerContextImpl.cs new file mode 100644 index 0000000..0c719bc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsServerContextImpl.cs @@ -0,0 +1,20 @@ +using System; + +using Org.BouncyCastle.Tls.Crypto; + +namespace Org.BouncyCastle.Tls +{ + internal class TlsServerContextImpl + : AbstractTlsContext, TlsServerContext + { + internal TlsServerContextImpl(TlsCrypto crypto) + : base(crypto, ConnectionEnd.server) + { + } + + public override bool IsServer + { + get { return true; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsServerContextImpl.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsServerContextImpl.cs.meta new file mode 100644 index 0000000..549733c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsServerContextImpl.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 76acf8ef4598e7844ae8b736a8f689de +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsServerProtocol.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsServerProtocol.cs new file mode 100644 index 0000000..40218a2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsServerProtocol.cs @@ -0,0 +1,1523 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Tls.Crypto; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls +{ + public class TlsServerProtocol + : TlsProtocol + { + protected TlsServer m_tlsServer = null; + internal TlsServerContextImpl m_tlsServerContext = null; + + protected int[] m_offeredCipherSuites = null; + protected TlsKeyExchange m_keyExchange = null; + protected CertificateRequest m_certificateRequest = null; + + /// Constructor for non-blocking mode. + /// + /// When data is received, use to provide the received ciphertext, + /// then use to read the corresponding cleartext.

    + /// Similarly, when data needs to be sent, use + /// to provide the cleartext, then use to get the + /// corresponding ciphertext. + ///
    + public TlsServerProtocol() + : base() + { + } + + /// Constructor for blocking mode. + /// The of data to/from the server. + public TlsServerProtocol(Stream stream) + : base(stream) + { + } + + /// Constructor for blocking mode. + /// The of data from the server. + /// The of data to the server. + public TlsServerProtocol(Stream input, Stream output) + : base(input, output) + { + } + + /// Receives a TLS handshake in the role of server. + /// + /// In blocking mode, this will not return until the handshake is complete. In non-blocking mode, use + /// to receive a callback when the handshake is complete. + /// + /// The to use for the handshake. + /// If in blocking mode and handshake was not successful. + public void Accept(TlsServer tlsServer) + { + if (tlsServer == null) + throw new ArgumentNullException("tlsServer"); + if (m_tlsServer != null) + throw new InvalidOperationException("'Accept' can only be called once"); + + this.m_tlsServer = tlsServer; + this.m_tlsServerContext = new TlsServerContextImpl(tlsServer.Crypto); + + tlsServer.Init(m_tlsServerContext); + tlsServer.NotifyCloseHandle(this); + + BeginHandshake(); + + if (m_blocking) + { + BlockForHandshake(); + } + } + + protected override void CleanupHandshake() + { + base.CleanupHandshake(); + + this.m_offeredCipherSuites = null; + this.m_keyExchange = null; + this.m_certificateRequest = null; + } + + protected virtual bool ExpectCertificateVerifyMessage() + { + if (null == m_certificateRequest) + return false; + + Certificate clientCertificate = m_tlsServerContext.SecurityParameters.PeerCertificate; + + return null != clientCertificate && !clientCertificate.IsEmpty + && (null == m_keyExchange || m_keyExchange.RequiresCertificateVerify); + } + + /// + protected virtual ServerHello Generate13HelloRetryRequest(ClientHello clientHello) + { + // TODO[tls13] In future there might be other reasons for a HelloRetryRequest. + if (m_retryGroup < 0) + throw new TlsFatalAlert(AlertDescription.internal_error); + + SecurityParameters securityParameters = m_tlsServerContext.SecurityParameters; + ProtocolVersion serverVersion = securityParameters.NegotiatedVersion; + + IDictionary serverHelloExtensions = Platform.CreateHashtable(); + TlsExtensionsUtilities.AddSupportedVersionsExtensionServer(serverHelloExtensions, serverVersion); + if (m_retryGroup >= 0) + { + TlsExtensionsUtilities.AddKeyShareHelloRetryRequest(serverHelloExtensions, m_retryGroup); + } + if (null != m_retryCookie) + { + TlsExtensionsUtilities.AddCookieExtension(serverHelloExtensions, m_retryCookie); + } + + TlsUtilities.CheckExtensionData13(serverHelloExtensions, HandshakeType.hello_retry_request, + AlertDescription.internal_error); + + return new ServerHello(clientHello.SessionID, securityParameters.CipherSuite, serverHelloExtensions); + } + + /// + protected virtual ServerHello Generate13ServerHello(ClientHello clientHello, + HandshakeMessageInput clientHelloMessage, bool afterHelloRetryRequest) + { + SecurityParameters securityParameters = m_tlsServerContext.SecurityParameters; + + + byte[] legacy_session_id = clientHello.SessionID; + + IDictionary clientHelloExtensions = clientHello.Extensions; + if (null == clientHelloExtensions) + throw new TlsFatalAlert(AlertDescription.missing_extension); + + + ProtocolVersion serverVersion = securityParameters.NegotiatedVersion; + TlsCrypto crypto = m_tlsServerContext.Crypto; + + // NOTE: Will only select for psk_dhe_ke + OfferedPsks.SelectedConfig selectedPsk = TlsUtilities.SelectPreSharedKey(m_tlsServerContext, m_tlsServer, + clientHelloExtensions, clientHelloMessage, m_handshakeHash, afterHelloRetryRequest); + + IList clientShares = TlsExtensionsUtilities.GetKeyShareClientHello(clientHelloExtensions); + KeyShareEntry clientShare = null; + + if (afterHelloRetryRequest) + { + if (m_retryGroup < 0) + throw new TlsFatalAlert(AlertDescription.internal_error); + + if (null == selectedPsk) + { + /* + * RFC 8446 4.2.3. If a server is authenticating via a certificate and the client has + * not sent a "signature_algorithms" extension, then the server MUST abort the handshake + * with a "missing_extension" alert. + */ + if (null == securityParameters.ClientSigAlgs) + throw new TlsFatalAlert(AlertDescription.missing_extension); + } + else + { + // TODO[tls13] Maybe filter the offered PSKs by PRF algorithm before server selection instead + if (selectedPsk.m_psk.PrfAlgorithm != securityParameters.PrfAlgorithm) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + /* + * TODO[tls13] Confirm fields in the ClientHello haven't changed + * + * RFC 8446 4.1.2 [..] when the server has responded to its ClientHello with a + * HelloRetryRequest [..] the client MUST send the same ClientHello without + * modification, except as follows: [key_share, early_data, cookie, pre_shared_key, + * padding]. + */ + + byte[] cookie = TlsExtensionsUtilities.GetCookieExtension(clientHelloExtensions); + if (!Arrays.AreEqual(m_retryCookie, cookie)) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + this.m_retryCookie = null; + + clientShare = TlsUtilities.SelectKeyShare(clientShares, m_retryGroup); + if (null == clientShare) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + else + { + this.m_clientExtensions = clientHelloExtensions; + + securityParameters.m_secureRenegotiation = false; + + // NOTE: Validates the padding extension data, if present + TlsExtensionsUtilities.GetPaddingExtension(clientHelloExtensions); + + securityParameters.m_clientServerNames = TlsExtensionsUtilities + .GetServerNameExtensionClient(clientHelloExtensions); + + TlsUtilities.EstablishClientSigAlgs(securityParameters, clientHelloExtensions); + + /* + * RFC 8446 4.2.3. If a server is authenticating via a certificate and the client has + * not sent a "signature_algorithms" extension, then the server MUST abort the handshake + * with a "missing_extension" alert. + */ + if (null == selectedPsk && null == securityParameters.ClientSigAlgs) + throw new TlsFatalAlert(AlertDescription.missing_extension); + + m_tlsServer.ProcessClientExtensions(clientHelloExtensions); + + /* + * NOTE: Currently no server support for session resumption + * + * If adding support, ensure securityParameters.tlsUnique is set to the localVerifyData, but + * ONLY when extended_master_secret has been negotiated (otherwise NULL). + */ + { + // TODO[tls13] Resumption/PSK + + this.m_tlsSession = TlsUtilities.ImportSession(TlsUtilities.EmptyBytes, null); + this.m_sessionParameters = null; + this.m_sessionMasterSecret = null; + } + + securityParameters.m_sessionID = m_tlsSession.SessionID; + + m_tlsServer.NotifySession(m_tlsSession); + + TlsUtilities.NegotiatedVersionTlsServer(m_tlsServerContext); + + { + securityParameters.m_serverRandom = CreateRandomBlock(false, m_tlsServerContext); + + if (!serverVersion.Equals(ProtocolVersion.GetLatestTls(m_tlsServer.GetProtocolVersions()))) + { + TlsUtilities.WriteDowngradeMarker(serverVersion, securityParameters.ServerRandom); + } + } + + { + // TODO[tls13] Constrain selection when PSK selected + int cipherSuite = m_tlsServer.GetSelectedCipherSuite(); + + if (!TlsUtilities.IsValidCipherSuiteSelection(m_offeredCipherSuites, cipherSuite) || + !TlsUtilities.IsValidVersionForCipherSuite(cipherSuite, serverVersion)) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + TlsUtilities.NegotiatedCipherSuite(securityParameters, cipherSuite); + } + + int[] clientSupportedGroups = securityParameters.ClientSupportedGroups; + int[] serverSupportedGroups = securityParameters.ServerSupportedGroups; + + clientShare = TlsUtilities.SelectKeyShare(crypto, serverVersion, clientShares, clientSupportedGroups, + serverSupportedGroups); + + if (null == clientShare) + { + this.m_retryGroup = TlsUtilities.SelectKeyShareGroup(crypto, serverVersion, clientSupportedGroups, + serverSupportedGroups); + if (m_retryGroup < 0) + throw new TlsFatalAlert(AlertDescription.handshake_failure); + + this.m_retryCookie = m_tlsServerContext.NonceGenerator.GenerateNonce(16); + + return Generate13HelloRetryRequest(clientHello); + } + + if (clientShare.NamedGroup != serverSupportedGroups[0]) + { + /* + * TODO[tls13] RFC 8446 4.2.7. As of TLS 1.3, servers are permitted to send the + * "supported_groups" extension to the client. Clients MUST NOT act upon any + * information found in "supported_groups" prior to successful completion of the + * handshake but MAY use the information learned from a successfully completed + * handshake to change what groups they use in their "key_share" extension in + * subsequent connections. If the server has a group it prefers to the ones in the + * "key_share" extension but is still willing to accept the ClientHello, it SHOULD + * send "supported_groups" to update the client's view of its preferences; this + * extension SHOULD contain all groups the server supports, regardless of whether + * they are currently supported by the client. + */ + } + } + + + IDictionary serverHelloExtensions = Platform.CreateHashtable(); + IDictionary serverEncryptedExtensions = TlsExtensionsUtilities.EnsureExtensionsInitialised( + m_tlsServer.GetServerExtensions()); + + m_tlsServer.GetServerExtensionsForConnection(serverEncryptedExtensions); + + ProtocolVersion serverLegacyVersion = ProtocolVersion.TLSv12; + TlsExtensionsUtilities.AddSupportedVersionsExtensionServer(serverHelloExtensions, serverVersion); + + /* + * RFC 8446 Appendix D. Because TLS 1.3 always hashes in the transcript up to the server + * Finished, implementations which support both TLS 1.3 and earlier versions SHOULD indicate + * the use of the Extended Master Secret extension in their APIs whenever TLS 1.3 is used. + */ + securityParameters.m_extendedMasterSecret = true; + + /* + * RFC 7301 3.1. When session resumption or session tickets [...] are used, the previous + * contents of this extension are irrelevant, and only the values in the new handshake + * messages are considered. + */ + securityParameters.m_applicationProtocol = TlsExtensionsUtilities.GetAlpnExtensionServer( + serverEncryptedExtensions); + securityParameters.m_applicationProtocolSet = true; + + if (serverEncryptedExtensions.Count > 0) + { + securityParameters.m_maxFragmentLength = ProcessMaxFragmentLengthExtension(clientHelloExtensions, + serverEncryptedExtensions, AlertDescription.internal_error); + } + + securityParameters.m_encryptThenMac = false; + securityParameters.m_truncatedHmac = false; + + /* + * TODO[tls13] RFC 8446 4.4.2.1. OCSP Status and SCT Extensions. + * + * OCSP information is carried in an extension for a CertificateEntry. + */ + securityParameters.m_statusRequestVersion = clientHelloExtensions.Contains(ExtensionType.status_request) + ? 1 : 0; + + this.m_expectSessionTicket = false; + + TlsSecret pskEarlySecret = null; + if (null != selectedPsk) + { + pskEarlySecret = selectedPsk.m_earlySecret; + + this.m_selectedPsk13 = true; + + TlsExtensionsUtilities.AddPreSharedKeyServerHello(serverHelloExtensions, selectedPsk.m_index); + } + + TlsSecret sharedSecret; + { + int namedGroup = clientShare.NamedGroup; + + TlsAgreement agreement; + if (NamedGroup.RefersToASpecificCurve(namedGroup)) + { + agreement = crypto.CreateECDomain(new TlsECConfig(namedGroup)).CreateECDH(); + } + else if (NamedGroup.RefersToASpecificFiniteField(namedGroup)) + { + agreement = crypto.CreateDHDomain(new TlsDHConfig(namedGroup, true)).CreateDH(); + } + else + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + byte[] key_exchange = agreement.GenerateEphemeral(); + KeyShareEntry serverShare = new KeyShareEntry(namedGroup, key_exchange); + TlsExtensionsUtilities.AddKeyShareServerHello(serverHelloExtensions, serverShare); + + agreement.ReceivePeerValue(clientShare.KeyExchange); + sharedSecret = agreement.CalculateSecret(); + } + + TlsUtilities.Establish13PhaseSecrets(m_tlsServerContext, pskEarlySecret, sharedSecret); + + this.m_serverExtensions = serverEncryptedExtensions; + + ApplyMaxFragmentLengthExtension(securityParameters.MaxFragmentLength); + + TlsUtilities.CheckExtensionData13(serverHelloExtensions, HandshakeType.server_hello, + AlertDescription.internal_error); + + return new ServerHello(serverLegacyVersion, securityParameters.ServerRandom, legacy_session_id, + securityParameters.CipherSuite, serverHelloExtensions); + } + + /// + protected virtual ServerHello GenerateServerHello(ClientHello clientHello, + HandshakeMessageInput clientHelloMessage) + { + ProtocolVersion clientLegacyVersion = clientHello.Version; + if (!clientLegacyVersion.IsTls) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + this.m_offeredCipherSuites = clientHello.CipherSuites; + + + + SecurityParameters securityParameters = m_tlsServerContext.SecurityParameters; + + m_tlsServerContext.SetClientSupportedVersions( + TlsExtensionsUtilities.GetSupportedVersionsExtensionClient(clientHello.Extensions)); + + ProtocolVersion clientVersion = clientLegacyVersion; + if (null == m_tlsServerContext.ClientSupportedVersions) + { + if (clientVersion.IsLaterVersionOf(ProtocolVersion.TLSv12)) + { + clientVersion = ProtocolVersion.TLSv12; + } + + m_tlsServerContext.SetClientSupportedVersions(clientVersion.DownTo(ProtocolVersion.SSLv3)); + } + else + { + clientVersion = ProtocolVersion.GetLatestTls(m_tlsServerContext.ClientSupportedVersions); + } + + // Set the legacy_record_version to use for early alerts + m_recordStream.SetWriteVersion(clientVersion); + + if (!ProtocolVersion.SERVER_EARLIEST_SUPPORTED_TLS.IsEqualOrEarlierVersionOf(clientVersion)) + throw new TlsFatalAlert(AlertDescription.protocol_version); + + // NOT renegotiating + { + m_tlsServerContext.SetClientVersion(clientVersion); + } + + m_tlsServer.NotifyClientVersion(m_tlsServerContext.ClientVersion); + + securityParameters.m_clientRandom = clientHello.Random; + + m_tlsServer.NotifyFallback(Arrays.Contains(m_offeredCipherSuites, CipherSuite.TLS_FALLBACK_SCSV)); + + m_tlsServer.NotifyOfferedCipherSuites(m_offeredCipherSuites); + + // TODO[tls13] Negotiate cipher suite first? + + ProtocolVersion serverVersion; + + // NOT renegotiating + { + serverVersion = m_tlsServer.GetServerVersion(); + if (!ProtocolVersion.Contains(m_tlsServerContext.ClientSupportedVersions, serverVersion)) + throw new TlsFatalAlert(AlertDescription.internal_error); + + securityParameters.m_negotiatedVersion = serverVersion; + } + + securityParameters.m_clientSupportedGroups = TlsExtensionsUtilities.GetSupportedGroupsExtension( + clientHello.Extensions); + securityParameters.m_serverSupportedGroups = m_tlsServer.GetSupportedGroups(); + + if (ProtocolVersion.TLSv13.IsEqualOrEarlierVersionOf(serverVersion)) + { + // See RFC 8446 D.4. + m_recordStream.SetIgnoreChangeCipherSpec(true); + + m_recordStream.SetWriteVersion(ProtocolVersion.TLSv12); + + return Generate13ServerHello(clientHello, clientHelloMessage, false); + } + + m_recordStream.SetWriteVersion(serverVersion); + + this.m_clientExtensions = clientHello.Extensions; + + byte[] clientRenegExtData = TlsUtilities.GetExtensionData(m_clientExtensions, ExtensionType.renegotiation_info); + + // NOT renegotiating + { + /* + * RFC 5746 3.6. Server Behavior: Initial Handshake (both full and session-resumption) + */ + + /* + * RFC 5746 3.4. The client MUST include either an empty "renegotiation_info" extension, + * or the TLS_EMPTY_RENEGOTIATION_INFO_SCSV signaling cipher suite value in the + * ClientHello. Including both is NOT RECOMMENDED. + */ + + /* + * When a ClientHello is received, the server MUST check if it includes the + * TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV. If it does, set the secure_renegotiation flag + * to TRUE. + */ + if (Arrays.Contains(m_offeredCipherSuites, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV)) + { + securityParameters.m_secureRenegotiation = true; + } + + /* + * The server MUST check if the "renegotiation_info" extension is included in the + * ClientHello. + */ + if (clientRenegExtData != null) + { + /* + * If the extension is present, set secure_renegotiation flag to TRUE. The + * server MUST then verify that the length of the "renegotiated_connection" + * field is zero, and if it is not, MUST abort the handshake. + */ + securityParameters.m_secureRenegotiation = true; + + if (!Arrays.ConstantTimeAreEqual(clientRenegExtData, + CreateRenegotiationInfo(TlsUtilities.EmptyBytes))) + { + throw new TlsFatalAlert(AlertDescription.handshake_failure); + } + } + } + + m_tlsServer.NotifySecureRenegotiation(securityParameters.IsSecureRenegotiation); + + bool offeredExtendedMasterSecret = TlsExtensionsUtilities.HasExtendedMasterSecretExtension( + m_clientExtensions); + + if (m_clientExtensions != null) + { + // NOTE: Validates the padding extension data, if present + TlsExtensionsUtilities.GetPaddingExtension(m_clientExtensions); + + securityParameters.m_clientServerNames = TlsExtensionsUtilities.GetServerNameExtensionClient( + m_clientExtensions); + + /* + * RFC 5246 7.4.1.4.1. Note: this extension is not meaningful for TLS versions prior + * to 1.2. Clients MUST NOT offer it if they are offering prior versions. + */ + if (TlsUtilities.IsSignatureAlgorithmsExtensionAllowed(clientVersion)) + { + TlsUtilities.EstablishClientSigAlgs(securityParameters, m_clientExtensions); + } + + securityParameters.m_clientSupportedGroups = TlsExtensionsUtilities.GetSupportedGroupsExtension( + m_clientExtensions); + + m_tlsServer.ProcessClientExtensions(m_clientExtensions); + } + + this.m_resumedSession = EstablishSession(m_tlsServer.GetSessionToResume(clientHello.SessionID)); + + if (!m_resumedSession) + { + byte[] newSessionID = m_tlsServer.GetNewSessionID(); + if (null == newSessionID) + { + newSessionID = TlsUtilities.EmptyBytes; + } + + this.m_tlsSession = TlsUtilities.ImportSession(newSessionID, null); + this.m_sessionParameters = null; + this.m_sessionMasterSecret = null; + } + + securityParameters.m_sessionID = m_tlsSession.SessionID; + + m_tlsServer.NotifySession(m_tlsSession); + + TlsUtilities.NegotiatedVersionTlsServer(m_tlsServerContext); + + { + bool useGmtUnixTime = m_tlsServer.ShouldUseGmtUnixTime(); + + securityParameters.m_serverRandom = CreateRandomBlock(useGmtUnixTime, m_tlsServerContext); + + if (!serverVersion.Equals(ProtocolVersion.GetLatestTls(m_tlsServer.GetProtocolVersions()))) + { + TlsUtilities.WriteDowngradeMarker(serverVersion, securityParameters.ServerRandom); + } + } + + { + int cipherSuite = m_resumedSession + ? m_sessionParameters.CipherSuite + : m_tlsServer.GetSelectedCipherSuite(); + + if (!TlsUtilities.IsValidCipherSuiteSelection(m_offeredCipherSuites, cipherSuite) || + !TlsUtilities.IsValidVersionForCipherSuite(cipherSuite, serverVersion)) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + TlsUtilities.NegotiatedCipherSuite(securityParameters, cipherSuite); + } + + m_tlsServerContext.SetRsaPreMasterSecretVersion(clientLegacyVersion); + + { + IDictionary sessionServerExtensions = m_resumedSession + ? m_sessionParameters.ReadServerExtensions() + : m_tlsServer.GetServerExtensions(); + + this.m_serverExtensions = TlsExtensionsUtilities.EnsureExtensionsInitialised(sessionServerExtensions); + } + + m_tlsServer.GetServerExtensionsForConnection(m_serverExtensions); + + // NOT renegotiating + { + /* + * RFC 5746 3.6. Server Behavior: Initial Handshake (both full and session-resumption) + */ + if (securityParameters.IsSecureRenegotiation) + { + byte[] serverRenegExtData = TlsUtilities.GetExtensionData(m_serverExtensions, + ExtensionType.renegotiation_info); + bool noRenegExt = (null == serverRenegExtData); + + if (noRenegExt) + { + /* + * Note that sending a "renegotiation_info" extension in response to a ClientHello + * containing only the SCSV is an explicit exception to the prohibition in RFC 5246, + * Section 7.4.1.4, on the server sending unsolicited extensions and is only allowed + * because the client is signaling its willingness to receive the extension via the + * TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV. + */ + + /* + * If the secure_renegotiation flag is set to TRUE, the server MUST include an empty + * "renegotiation_info" extension in the ServerHello message. + */ + this.m_serverExtensions[ExtensionType.renegotiation_info] = CreateRenegotiationInfo( + TlsUtilities.EmptyBytes); + } + } + } + + /* + * RFC 7627 4. Clients and servers SHOULD NOT accept handshakes that do not use the extended + * master secret [..]. (and see 5.2, 5.3) + */ + if (m_resumedSession) + { + if (!m_sessionParameters.IsExtendedMasterSecret) + { + /* + * TODO[resumption] ProvTlsServer currently only resumes EMS sessions. Revisit this + * in relation to 'tlsServer.allowLegacyResumption()'. + */ + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + if (!offeredExtendedMasterSecret) + throw new TlsFatalAlert(AlertDescription.handshake_failure); + + securityParameters.m_extendedMasterSecret = true; + + TlsExtensionsUtilities.AddExtendedMasterSecretExtension(m_serverExtensions); + } + else + { + securityParameters.m_extendedMasterSecret = offeredExtendedMasterSecret && !serverVersion.IsSsl + && m_tlsServer.ShouldUseExtendedMasterSecret(); + + if (securityParameters.IsExtendedMasterSecret) + { + TlsExtensionsUtilities.AddExtendedMasterSecretExtension(m_serverExtensions); + } + else if (m_tlsServer.RequiresExtendedMasterSecret()) + { + throw new TlsFatalAlert(AlertDescription.handshake_failure); + } + } + + securityParameters.m_applicationProtocol = TlsExtensionsUtilities.GetAlpnExtensionServer(m_serverExtensions); + securityParameters.m_applicationProtocolSet = true; + + if (m_serverExtensions.Count > 0) + { + securityParameters.m_encryptThenMac = TlsExtensionsUtilities.HasEncryptThenMacExtension( + m_serverExtensions); + + securityParameters.m_maxFragmentLength = ProcessMaxFragmentLengthExtension(m_clientExtensions, + m_serverExtensions, AlertDescription.internal_error); + + securityParameters.m_truncatedHmac = TlsExtensionsUtilities.HasTruncatedHmacExtension( + m_serverExtensions); + + if (!m_resumedSession) + { + if (TlsUtilities.HasExpectedEmptyExtensionData(m_serverExtensions, ExtensionType.status_request_v2, + AlertDescription.internal_error)) + { + securityParameters.m_statusRequestVersion = 2; + } + else if (TlsUtilities.HasExpectedEmptyExtensionData(m_serverExtensions, ExtensionType.status_request, + AlertDescription.internal_error)) + { + securityParameters.m_statusRequestVersion = 1; + } + + this.m_expectSessionTicket = TlsUtilities.HasExpectedEmptyExtensionData(m_serverExtensions, + ExtensionType.session_ticket, AlertDescription.internal_error); + } + } + + ApplyMaxFragmentLengthExtension(securityParameters.MaxFragmentLength); + + return new ServerHello(serverVersion, securityParameters.ServerRandom, m_tlsSession.SessionID, + securityParameters.CipherSuite, m_serverExtensions); + } + + protected override TlsContext Context + { + get { return m_tlsServerContext; } + } + + internal override AbstractTlsContext ContextAdmin + { + get { return m_tlsServerContext; } + } + + protected override TlsPeer Peer + { + get { return m_tlsServer; } + } + + /// + protected virtual void Handle13HandshakeMessage(short type, HandshakeMessageInput buf) + { + if (!IsTlsV13ConnectionState()) + throw new TlsFatalAlert(AlertDescription.internal_error); + + if (m_resumedSession) + { + /* + * TODO[tls13] Abbreviated handshakes (PSK resumption) + * + * NOTE: No CertificateRequest, Certificate, CertificateVerify messages, but client + * might now send EndOfEarlyData after receiving server Finished message. + */ + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + switch (type) + { + case HandshakeType.certificate: + { + switch (m_connectionState) + { + case CS_SERVER_FINISHED: + { + Receive13ClientCertificate(buf); + this.m_connectionState = CS_CLIENT_CERTIFICATE; + break; + } + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + break; + } + case HandshakeType.certificate_verify: + { + switch (m_connectionState) + { + case CS_CLIENT_CERTIFICATE: + { + Receive13ClientCertificateVerify(buf); + buf.UpdateHash(m_handshakeHash); + this.m_connectionState = CS_CLIENT_CERTIFICATE_VERIFY; + break; + } + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + break; + } + case HandshakeType.client_hello: + { + switch (m_connectionState) + { + case CS_START: + { + // NOTE: Legacy handler should be dispatching initial ClientHello. + throw new TlsFatalAlert(AlertDescription.internal_error); + } + case CS_SERVER_HELLO_RETRY_REQUEST: + { + ClientHello clientHelloRetry = ReceiveClientHelloMessage(buf); + this.m_connectionState = CS_CLIENT_HELLO_RETRY; + + ServerHello serverHello = Generate13ServerHello(clientHelloRetry, buf, true); + SendServerHelloMessage(serverHello); + this.m_connectionState = CS_SERVER_HELLO; + + Send13ServerHelloCoda(serverHello, true); + break; + } + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + break; + } + case HandshakeType.finished: + { + switch (m_connectionState) + { + case CS_SERVER_FINISHED: + case CS_CLIENT_CERTIFICATE: + case CS_CLIENT_CERTIFICATE_VERIFY: + { + if (m_connectionState == CS_SERVER_FINISHED) + { + Skip13ClientCertificate(); + } + if (m_connectionState != CS_CLIENT_CERTIFICATE_VERIFY) + { + Skip13ClientCertificateVerify(); + } + + Receive13ClientFinished(buf); + this.m_connectionState = CS_CLIENT_FINISHED; + + // See RFC 8446 D.4. + m_recordStream.SetIgnoreChangeCipherSpec(false); + + // NOTE: Completes the switch to application-data phase (server entered after CS_SERVER_FINISHED). + m_recordStream.EnablePendingCipherRead(false); + + CompleteHandshake(); + break; + } + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + break; + } + case HandshakeType.key_update: + { + Receive13KeyUpdate(buf); + break; + } + + case HandshakeType.certificate_request: + case HandshakeType.certificate_status: + case HandshakeType.certificate_url: + case HandshakeType.client_key_exchange: + case HandshakeType.encrypted_extensions: + case HandshakeType.end_of_early_data: + case HandshakeType.hello_request: + case HandshakeType.hello_verify_request: + case HandshakeType.message_hash: + case HandshakeType.new_session_ticket: + case HandshakeType.server_hello: + case HandshakeType.server_hello_done: + case HandshakeType.server_key_exchange: + case HandshakeType.supplemental_data: + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + } + + protected override void HandleHandshakeMessage(short type, HandshakeMessageInput buf) + { + SecurityParameters securityParameters = m_tlsServerContext.SecurityParameters; + + if (m_connectionState > CS_CLIENT_HELLO + && TlsUtilities.IsTlsV13(securityParameters.NegotiatedVersion)) + { + Handle13HandshakeMessage(type, buf); + return; + } + + if (!IsLegacyConnectionState()) + throw new TlsFatalAlert(AlertDescription.internal_error); + + if (m_resumedSession) + { + if (type != HandshakeType.finished || m_connectionState != CS_SERVER_FINISHED) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + + ProcessFinishedMessage(buf); + this.m_connectionState = CS_CLIENT_FINISHED; + + CompleteHandshake(); + return; + } + + switch (type) + { + case HandshakeType.client_hello: + { + if (IsApplicationDataReady) + { + RefuseRenegotiation(); + break; + } + + switch (m_connectionState) + { + case CS_END: + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + case CS_START: + { + ClientHello clientHello = ReceiveClientHelloMessage(buf); + this.m_connectionState = CS_CLIENT_HELLO; + + ServerHello serverHello = GenerateServerHello(clientHello, buf); + m_handshakeHash.NotifyPrfDetermined(); + + if (TlsUtilities.IsTlsV13(securityParameters.NegotiatedVersion)) + { + m_handshakeHash.SealHashAlgorithms(); + + if (serverHello.IsHelloRetryRequest()) + { + TlsUtilities.AdjustTranscriptForRetry(m_handshakeHash); + SendServerHelloMessage(serverHello); + this.m_connectionState = CS_SERVER_HELLO_RETRY_REQUEST; + + // See RFC 8446 D.4. + SendChangeCipherSpecMessage(); + } + else + { + SendServerHelloMessage(serverHello); + this.m_connectionState = CS_SERVER_HELLO; + + // See RFC 8446 D.4. + SendChangeCipherSpecMessage(); + + Send13ServerHelloCoda(serverHello, false); + } + break; + } + + // For TLS 1.3+, this was already done by GenerateServerHello + buf.UpdateHash(m_handshakeHash); + + SendServerHelloMessage(serverHello); + this.m_connectionState = CS_SERVER_HELLO; + + if (m_resumedSession) + { + securityParameters.m_masterSecret = m_sessionMasterSecret; + m_recordStream.SetPendingCipher(TlsUtilities.InitCipher(m_tlsServerContext)); + + SendChangeCipherSpec(); + SendFinishedMessage(); + this.m_connectionState = CS_SERVER_FINISHED; + break; + } + + IList serverSupplementalData = m_tlsServer.GetServerSupplementalData(); + if (serverSupplementalData != null) + { + SendSupplementalDataMessage(serverSupplementalData); + this.m_connectionState = CS_SERVER_SUPPLEMENTAL_DATA; + } + + this.m_keyExchange = TlsUtilities.InitKeyExchangeServer(m_tlsServerContext, m_tlsServer); + + TlsCredentials serverCredentials = TlsUtilities.EstablishServerCredentials(m_tlsServer); + + // Server certificate + { + Certificate serverCertificate = null; + + MemoryStream endPointHash = new MemoryStream(); + if (null == serverCredentials) + { + m_keyExchange.SkipServerCredentials(); + } + else + { + m_keyExchange.ProcessServerCredentials(serverCredentials); + + serverCertificate = serverCredentials.Certificate; + SendCertificateMessage(serverCertificate, endPointHash); + this.m_connectionState = CS_SERVER_CERTIFICATE; + } + + securityParameters.m_tlsServerEndPoint = endPointHash.ToArray(); + + // TODO[RFC 3546] Check whether empty certificates is possible, allowed, or excludes + // CertificateStatus + if (null == serverCertificate || serverCertificate.IsEmpty) + { + securityParameters.m_statusRequestVersion = 0; + } + } + + if (securityParameters.StatusRequestVersion > 0) + { + CertificateStatus certificateStatus = m_tlsServer.GetCertificateStatus(); + if (certificateStatus != null) + { + SendCertificateStatusMessage(certificateStatus); + this.m_connectionState = CS_SERVER_CERTIFICATE_STATUS; + } + } + + byte[] serverKeyExchange = m_keyExchange.GenerateServerKeyExchange(); + if (serverKeyExchange != null) + { + SendServerKeyExchangeMessage(serverKeyExchange); + this.m_connectionState = CS_SERVER_KEY_EXCHANGE; + } + + if (null != serverCredentials) + { + this.m_certificateRequest = m_tlsServer.GetCertificateRequest(); + + if (null == m_certificateRequest) + { + /* + * For static agreement key exchanges, CertificateRequest is required since + * the client Certificate message is mandatory but can only be sent if the + * server requests it. + */ + if (!m_keyExchange.RequiresCertificateVerify) + throw new TlsFatalAlert(AlertDescription.internal_error); + } + else + { + if (TlsUtilities.IsTlsV12(m_tlsServerContext) + != (m_certificateRequest.SupportedSignatureAlgorithms != null)) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + this.m_certificateRequest = TlsUtilities.ValidateCertificateRequest(m_certificateRequest, + m_keyExchange); + + TlsUtilities.EstablishServerSigAlgs(securityParameters, m_certificateRequest); + + TlsUtilities.TrackHashAlgorithms(m_handshakeHash, securityParameters.ServerSigAlgs); + + SendCertificateRequestMessage(m_certificateRequest); + this.m_connectionState = CS_SERVER_CERTIFICATE_REQUEST; + } + } + + SendServerHelloDoneMessage(); + this.m_connectionState = CS_SERVER_HELLO_DONE; + + bool forceBuffering = false; + TlsUtilities.SealHandshakeHash(m_tlsServerContext, m_handshakeHash, forceBuffering); + + break; + } + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + break; + } + case HandshakeType.supplemental_data: + { + switch (m_connectionState) + { + case CS_SERVER_HELLO_DONE: + { + m_tlsServer.ProcessClientSupplementalData(ReadSupplementalDataMessage(buf)); + this.m_connectionState = CS_CLIENT_SUPPLEMENTAL_DATA; + break; + } + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + break; + } + case HandshakeType.certificate: + { + switch (m_connectionState) + { + case CS_SERVER_HELLO_DONE: + case CS_CLIENT_SUPPLEMENTAL_DATA: + { + if (m_connectionState != CS_CLIENT_SUPPLEMENTAL_DATA) + { + m_tlsServer.ProcessClientSupplementalData(null); + } + + ReceiveCertificateMessage(buf); + this.m_connectionState = CS_CLIENT_CERTIFICATE; + break; + } + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + break; + } + case HandshakeType.client_key_exchange: + { + switch (m_connectionState) + { + case CS_SERVER_HELLO_DONE: + case CS_CLIENT_SUPPLEMENTAL_DATA: + case CS_CLIENT_CERTIFICATE: + { + if (m_connectionState == CS_SERVER_HELLO_DONE) + { + m_tlsServer.ProcessClientSupplementalData(null); + } + if (m_connectionState != CS_CLIENT_CERTIFICATE) + { + if (null == m_certificateRequest) + { + m_keyExchange.SkipClientCredentials(); + } + else if (TlsUtilities.IsTlsV12(m_tlsServerContext)) + { + /* + * RFC 5246 If no suitable certificate is available, the client MUST send a + * certificate message containing no certificates. + * + * NOTE: In previous RFCs, this was SHOULD instead of MUST. + */ + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + else if (TlsUtilities.IsSsl(m_tlsServerContext)) + { + /* + * SSL 3.0 If the server has sent a certificate request Message, the client must + * send either the certificate message or a no_certificate alert. + */ + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + else + { + NotifyClientCertificate(Certificate.EmptyChain); + } + } + + ReceiveClientKeyExchangeMessage(buf); + this.m_connectionState = CS_CLIENT_KEY_EXCHANGE; + break; + } + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + break; + } + case HandshakeType.certificate_verify: + { + switch (m_connectionState) + { + case CS_CLIENT_KEY_EXCHANGE: + { + /* + * RFC 5246 7.4.8 This message is only sent following a client certificate that has + * signing capability (i.e., all certificates except those containing fixed + * Diffie-Hellman parameters). + */ + if (!ExpectCertificateVerifyMessage()) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + + ReceiveCertificateVerifyMessage(buf); + buf.UpdateHash(m_handshakeHash); + this.m_connectionState = CS_CLIENT_CERTIFICATE_VERIFY; + break; + } + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + break; + } + case HandshakeType.finished: + { + switch (m_connectionState) + { + case CS_CLIENT_KEY_EXCHANGE: + case CS_CLIENT_CERTIFICATE_VERIFY: + { + if (m_connectionState != CS_CLIENT_CERTIFICATE_VERIFY) + { + if (ExpectCertificateVerifyMessage()) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + ProcessFinishedMessage(buf); + buf.UpdateHash(m_handshakeHash); + this.m_connectionState = CS_CLIENT_FINISHED; + + if (m_expectSessionTicket) + { + /* + * TODO[new_session_ticket] Check the server-side rules regarding the session ID, since + * the client is going to ignore any session ID it received once it sees the + * new_session_ticket message. + */ + + SendNewSessionTicketMessage(m_tlsServer.GetNewSessionTicket()); + this.m_connectionState = CS_SERVER_SESSION_TICKET; + } + + SendChangeCipherSpec(); + SendFinishedMessage(); + this.m_connectionState = CS_SERVER_FINISHED; + + CompleteHandshake(); + break; + } + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + break; + } + + case HandshakeType.certificate_request: + case HandshakeType.certificate_status: + case HandshakeType.certificate_url: + case HandshakeType.encrypted_extensions: + case HandshakeType.end_of_early_data: + case HandshakeType.hello_request: + case HandshakeType.hello_verify_request: + case HandshakeType.key_update: + case HandshakeType.message_hash: + case HandshakeType.new_session_ticket: + case HandshakeType.server_hello: + case HandshakeType.server_hello_done: + case HandshakeType.server_key_exchange: + default: + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + } + + protected override void HandleAlertWarningMessage(short alertDescription) + { + /* + * SSL 3.0 If the server has sent a certificate request Message, the client must send + * either the certificate message or a no_certificate alert. + */ + if (AlertDescription.no_certificate == alertDescription && null != m_certificateRequest + && TlsUtilities.IsSsl(m_tlsServerContext)) + { + switch (m_connectionState) + { + case CS_SERVER_HELLO_DONE: + case CS_CLIENT_SUPPLEMENTAL_DATA: + { + if (m_connectionState != CS_CLIENT_SUPPLEMENTAL_DATA) + { + m_tlsServer.ProcessClientSupplementalData(null); + } + + NotifyClientCertificate(Certificate.EmptyChain); + this.m_connectionState = CS_CLIENT_CERTIFICATE; + return; + } + } + } + + base.HandleAlertWarningMessage(alertDescription); + } + + /// + protected virtual void NotifyClientCertificate(Certificate clientCertificate) + { + if (null == m_certificateRequest) + throw new TlsFatalAlert(AlertDescription.internal_error); + + TlsUtilities.ProcessClientCertificate(m_tlsServerContext, clientCertificate, m_keyExchange, m_tlsServer); + } + + /// + protected virtual void Receive13ClientCertificate(MemoryStream buf) + { + // TODO[tls13] This currently just duplicates 'receiveCertificateMessage' + + if (null == m_certificateRequest) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + + Certificate.ParseOptions options = new Certificate.ParseOptions() + .SetMaxChainLength(m_tlsServer.GetMaxCertificateChainLength()); + + Certificate clientCertificate = Certificate.Parse(options, m_tlsServerContext, buf, null); + + AssertEmpty(buf); + + NotifyClientCertificate(clientCertificate); + } + + /// + protected void Receive13ClientCertificateVerify(MemoryStream buf) + { + Certificate clientCertificate = m_tlsServerContext.SecurityParameters.PeerCertificate; + if (null == clientCertificate || clientCertificate.IsEmpty) + throw new TlsFatalAlert(AlertDescription.internal_error); + + // TODO[tls13] Actual structure is 'CertificateVerify' in RFC 8446, consider adding for clarity + DigitallySigned certificateVerify = DigitallySigned.Parse(m_tlsServerContext, buf); + + AssertEmpty(buf); + + TlsUtilities.Verify13CertificateVerifyClient(m_tlsServerContext, m_certificateRequest, certificateVerify, + m_handshakeHash); + } + + /// + protected virtual void Receive13ClientFinished(MemoryStream buf) + { + Process13FinishedMessage(buf); + } + + /// + protected virtual void ReceiveCertificateMessage(MemoryStream buf) + { + if (null == m_certificateRequest) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + + Certificate.ParseOptions options = new Certificate.ParseOptions() + .SetMaxChainLength(m_tlsServer.GetMaxCertificateChainLength()); + + Certificate clientCertificate = Certificate.Parse(options, m_tlsServerContext, buf, null); + + AssertEmpty(buf); + + NotifyClientCertificate(clientCertificate); + } + + /// + protected virtual void ReceiveCertificateVerifyMessage(MemoryStream buf) + { + DigitallySigned certificateVerify = DigitallySigned.Parse(m_tlsServerContext, buf); + + AssertEmpty(buf); + + TlsUtilities.VerifyCertificateVerifyClient(m_tlsServerContext, m_certificateRequest, certificateVerify, + m_handshakeHash); + + this.m_handshakeHash = m_handshakeHash.StopTracking(); + } + + /// + protected virtual ClientHello ReceiveClientHelloMessage(MemoryStream buf) + { + return ClientHello.Parse(buf, null); + } + + /// + protected virtual void ReceiveClientKeyExchangeMessage(MemoryStream buf) + { + m_keyExchange.ProcessClientKeyExchange(buf); + + AssertEmpty(buf); + + bool isSsl = TlsUtilities.IsSsl(m_tlsServerContext); + if (isSsl) + { + // NOTE: For SSLv3 (only), master_secret needed to calculate session hash + EstablishMasterSecret(m_tlsServerContext, m_keyExchange); + } + + m_tlsServerContext.SecurityParameters.m_sessionHash = TlsUtilities.GetCurrentPrfHash(m_handshakeHash); + + if (!isSsl) + { + // NOTE: For (D)TLS, session hash potentially needed for extended_master_secret + EstablishMasterSecret(m_tlsServerContext, m_keyExchange); + } + + m_recordStream.SetPendingCipher(TlsUtilities.InitCipher(m_tlsServerContext)); + + if (!ExpectCertificateVerifyMessage()) + { + this.m_handshakeHash = m_handshakeHash.StopTracking(); + } + } + + /// + protected virtual void Send13EncryptedExtensionsMessage(IDictionary serverExtensions) + { + // TODO[tls13] Avoid extra copy; use placeholder to write opaque-16 data directly to message buffer + + byte[] extBytes = WriteExtensionsData(serverExtensions); + + HandshakeMessageOutput message = new HandshakeMessageOutput(HandshakeType.encrypted_extensions); + TlsUtilities.WriteOpaque16(extBytes, message); + message.Send(this); + } + + /// + protected virtual void Send13ServerHelloCoda(ServerHello serverHello, bool afterHelloRetryRequest) + { + SecurityParameters securityParameters = m_tlsServerContext.SecurityParameters; + + byte[] serverHelloTranscriptHash = TlsUtilities.GetCurrentPrfHash(m_handshakeHash); + + TlsUtilities.Establish13PhaseHandshake(m_tlsServerContext, serverHelloTranscriptHash, m_recordStream); + + m_recordStream.EnablePendingCipherWrite(); + m_recordStream.EnablePendingCipherRead(true); + + Send13EncryptedExtensionsMessage(m_serverExtensions); + this.m_connectionState = CS_SERVER_ENCRYPTED_EXTENSIONS; + + if (m_selectedPsk13) + { + /* + * For PSK-only key exchange, there's no CertificateRequest, Certificate, CertificateVerify. + */ + } + else + { + // CertificateRequest + { + this.m_certificateRequest = m_tlsServer.GetCertificateRequest(); + if (null != m_certificateRequest) + { + if (!m_certificateRequest.HasCertificateRequestContext(TlsUtilities.EmptyBytes)) + throw new TlsFatalAlert(AlertDescription.internal_error); + + TlsUtilities.EstablishServerSigAlgs(securityParameters, m_certificateRequest); + + SendCertificateRequestMessage(m_certificateRequest); + this.m_connectionState = CS_SERVER_CERTIFICATE_REQUEST; + } + } + + TlsCredentialedSigner serverCredentials = TlsUtilities.Establish13ServerCredentials(m_tlsServer); + if (null == serverCredentials) + throw new TlsFatalAlert(AlertDescription.internal_error); + + // Certificate + { + /* + * TODO[tls13] Note that we are expecting the TlsServer implementation to take care of + * e.g. adding optional "status_request" extension to each CertificateEntry. + */ + /* + * No CertificateStatus message is sent; TLS 1.3 uses per-CertificateEntry + * "status_request" extension instead. + */ + + Certificate serverCertificate = serverCredentials.Certificate; + Send13CertificateMessage(serverCertificate); + securityParameters.m_tlsServerEndPoint = null; + this.m_connectionState = CS_SERVER_CERTIFICATE; + } + + // CertificateVerify + { + DigitallySigned certificateVerify = TlsUtilities.Generate13CertificateVerify(m_tlsServerContext, + serverCredentials, m_handshakeHash); + Send13CertificateVerifyMessage(certificateVerify); + this.m_connectionState = CS_CLIENT_CERTIFICATE_VERIFY; + } + } + + // Finished + { + Send13FinishedMessage(); + this.m_connectionState = CS_SERVER_FINISHED; + } + + byte[] serverFinishedTranscriptHash = TlsUtilities.GetCurrentPrfHash(m_handshakeHash); + + TlsUtilities.Establish13PhaseApplication(m_tlsServerContext, serverFinishedTranscriptHash, m_recordStream); + + m_recordStream.EnablePendingCipherWrite(); + } + + /// + protected virtual void SendCertificateRequestMessage(CertificateRequest certificateRequest) + { + HandshakeMessageOutput message = new HandshakeMessageOutput(HandshakeType.certificate_request); + certificateRequest.Encode(m_tlsServerContext, message); + message.Send(this); + } + + /// + protected virtual void SendCertificateStatusMessage(CertificateStatus certificateStatus) + { + HandshakeMessageOutput message = new HandshakeMessageOutput(HandshakeType.certificate_status); + // TODO[tls13] Ensure this cannot happen for (D)TLS1.3+ + certificateStatus.Encode(message); + message.Send(this); + } + + /// + protected virtual void SendHelloRequestMessage() + { + HandshakeMessageOutput.Send(this, HandshakeType.hello_request, TlsUtilities.EmptyBytes); + } + + /// + protected virtual void SendNewSessionTicketMessage(NewSessionTicket newSessionTicket) + { + if (newSessionTicket == null) + throw new TlsFatalAlert(AlertDescription.internal_error); + + HandshakeMessageOutput message = new HandshakeMessageOutput(HandshakeType.new_session_ticket); + newSessionTicket.Encode(message); + message.Send(this); + } + + /// + protected virtual void SendServerHelloDoneMessage() + { + HandshakeMessageOutput.Send(this, HandshakeType.server_hello_done, TlsUtilities.EmptyBytes); + } + + /// + protected virtual void SendServerHelloMessage(ServerHello serverHello) + { + HandshakeMessageOutput message = new HandshakeMessageOutput(HandshakeType.server_hello); + serverHello.Encode(m_tlsServerContext, message); + message.Send(this); + } + + /// + protected virtual void SendServerKeyExchangeMessage(byte[] serverKeyExchange) + { + HandshakeMessageOutput.Send(this, HandshakeType.server_key_exchange, serverKeyExchange); + } + + /// + protected virtual void Skip13ClientCertificate() + { + if (null != m_certificateRequest) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + + /// + protected virtual void Skip13ClientCertificateVerify() + { + if (ExpectCertificateVerifyMessage()) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsServerProtocol.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsServerProtocol.cs.meta new file mode 100644 index 0000000..abe34b5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsServerProtocol.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d7f715afc32bad84db97b2e8f88e90e3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSession.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSession.cs new file mode 100644 index 0000000..bc68757 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSession.cs @@ -0,0 +1,16 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + /// Base interface for a carrier object for a TLS session. + public interface TlsSession + { + SessionParameters ExportSessionParameters(); + + byte[] SessionID { get; } + + void Invalidate(); + + bool IsResumable { get; } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSession.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSession.cs.meta new file mode 100644 index 0000000..72f3fc0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSession.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: aed60de792508d847b84db47b8bd22cd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSessionImpl.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSessionImpl.cs new file mode 100644 index 0000000..a4eb6b9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSessionImpl.cs @@ -0,0 +1,52 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls +{ + internal class TlsSessionImpl + : TlsSession + { + private readonly byte[] m_sessionID; + private readonly SessionParameters m_sessionParameters; + private bool m_resumable; + + internal TlsSessionImpl(byte[] sessionID, SessionParameters sessionParameters) + { + if (sessionID == null) + throw new ArgumentNullException("sessionID"); + if (sessionID.Length > 32) + throw new ArgumentException("cannot be longer than 32 bytes", "sessionID"); + + this.m_sessionID = Arrays.Clone(sessionID); + this.m_sessionParameters = sessionParameters; + this.m_resumable = sessionID.Length > 0 && null != sessionParameters; + } + + public SessionParameters ExportSessionParameters() + { + lock (this) + { + return m_sessionParameters == null ? null : m_sessionParameters.Copy(); + } + } + + public byte[] SessionID + { + get { lock (this) return m_sessionID; } + } + + public void Invalidate() + { + lock (this) + { + this.m_resumable = false; + } + } + + public bool IsResumable + { + get { lock (this) return m_resumable; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSessionImpl.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSessionImpl.cs.meta new file mode 100644 index 0000000..0113734 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSessionImpl.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4363f1c47576e03489bdc87d484e1075 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSrpConfigVerifier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSrpConfigVerifier.cs new file mode 100644 index 0000000..e4d83ab --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSrpConfigVerifier.cs @@ -0,0 +1,15 @@ +using System; + +using Org.BouncyCastle.Tls.Crypto; + +namespace Org.BouncyCastle.Tls +{ + /// Interface for verifying SRP config needs to conform to. + public interface TlsSrpConfigVerifier + { + /// Check whether the given SRP configuration is acceptable for use. + /// the to check. + /// true if (and only if) the specified configuration is acceptable. + bool Accept(TlsSrpConfig srpConfig); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSrpConfigVerifier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSrpConfigVerifier.cs.meta new file mode 100644 index 0000000..20cf8fb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSrpConfigVerifier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9d60035af1c69a64bb9b601833d23b41 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSrpIdentity.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSrpIdentity.cs new file mode 100644 index 0000000..c0492e4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSrpIdentity.cs @@ -0,0 +1,12 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + /// Processor interface for an SRP identity. + public interface TlsSrpIdentity + { + byte[] GetSrpIdentity(); + + byte[] GetSrpPassword(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSrpIdentity.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSrpIdentity.cs.meta new file mode 100644 index 0000000..4de3cd9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSrpIdentity.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b13ec21f20247314fac409d753388f3b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSrpIdentityManager.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSrpIdentityManager.cs new file mode 100644 index 0000000..1cc2840 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSrpIdentityManager.cs @@ -0,0 +1,18 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + /// Base interface for an object that can return login parameters from an SRP identity. + public interface TlsSrpIdentityManager + { + /// Lookup the corresponding to the specified identity. + /// + /// NOTE: To avoid "identity probing", unknown identities SHOULD be handled as recommended in RFC 5054 2.5.1.3. + /// is provided for this purpose. + /// + /// the SRP identity sent by the connecting client. + /// the for the specified identity, or else 'simulated' parameters + /// if the identity is not recognized. A null value is also allowed, but not recommended. + TlsSrpLoginParameters GetLoginParameters(byte[] identity); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSrpIdentityManager.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSrpIdentityManager.cs.meta new file mode 100644 index 0000000..59ec352 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSrpIdentityManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 98afa79d45d0b844cbb1a5be5afd7c4f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSrpKeyExchange.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSrpKeyExchange.cs new file mode 100644 index 0000000..b4b35ae --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSrpKeyExchange.cs @@ -0,0 +1,187 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Tls.Crypto; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Tls +{ + /// (D)TLS SRP key exchange (RFC 5054). + public class TlsSrpKeyExchange + : AbstractTlsKeyExchange + { + private static int CheckKeyExchange(int keyExchange) + { + switch (keyExchange) + { + case KeyExchangeAlgorithm.SRP: + case KeyExchangeAlgorithm.SRP_DSS: + case KeyExchangeAlgorithm.SRP_RSA: + return keyExchange; + default: + throw new ArgumentException("unsupported key exchange algorithm", "keyExchange"); + } + } + + protected TlsSrpIdentity m_srpIdentity; + protected TlsSrpConfigVerifier m_srpConfigVerifier; + protected TlsCertificate m_serverCertificate = null; + protected byte[] m_srpSalt = null; + protected TlsSrp6Client m_srpClient = null; + + protected TlsSrpLoginParameters m_srpLoginParameters; + protected TlsCredentialedSigner m_serverCredentials = null; + protected TlsSrp6Server m_srpServer = null; + + protected BigInteger m_srpPeerCredentials = null; + + public TlsSrpKeyExchange(int keyExchange, TlsSrpIdentity srpIdentity, TlsSrpConfigVerifier srpConfigVerifier) + : base(CheckKeyExchange(keyExchange)) + { + this.m_srpIdentity = srpIdentity; + this.m_srpConfigVerifier = srpConfigVerifier; + } + + public TlsSrpKeyExchange(int keyExchange, TlsSrpLoginParameters srpLoginParameters) + : base(CheckKeyExchange(keyExchange)) + { + this.m_srpLoginParameters = srpLoginParameters; + } + + public override void SkipServerCredentials() + { + if (m_keyExchange != KeyExchangeAlgorithm.SRP) + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public override void ProcessServerCredentials(TlsCredentials serverCredentials) + { + if (m_keyExchange == KeyExchangeAlgorithm.SRP) + throw new TlsFatalAlert(AlertDescription.internal_error); + + this.m_serverCredentials = TlsUtilities.RequireSignerCredentials(serverCredentials); + } + + public override void ProcessServerCertificate(Certificate serverCertificate) + { + if (m_keyExchange == KeyExchangeAlgorithm.SRP) + throw new TlsFatalAlert(AlertDescription.internal_error); + + this.m_serverCertificate = serverCertificate.GetCertificateAt(0); + } + + public override bool RequiresServerKeyExchange + { + get { return true; } + } + + public override byte[] GenerateServerKeyExchange() + { + TlsSrpConfig config = m_srpLoginParameters.Config; + + this.m_srpServer = m_context.Crypto.CreateSrp6Server(config, m_srpLoginParameters.Verifier); + + BigInteger B = m_srpServer.GenerateServerCredentials(); + + BigInteger[] ng = config.GetExplicitNG(); + ServerSrpParams srpParams = new ServerSrpParams(ng[0], ng[1], m_srpLoginParameters.Salt, B); + + DigestInputBuffer digestBuffer = new DigestInputBuffer(); + + srpParams.Encode(digestBuffer); + + if (m_serverCredentials != null) + { + TlsUtilities.GenerateServerKeyExchangeSignature(m_context, m_serverCredentials, null, digestBuffer); + } + + return digestBuffer.ToArray(); + } + + public override void ProcessServerKeyExchange(Stream input) + { + DigestInputBuffer digestBuffer = null; + Stream teeIn = input; + + if (m_keyExchange != KeyExchangeAlgorithm.SRP) + { + digestBuffer = new DigestInputBuffer(); + teeIn = new TeeInputStream(input, digestBuffer); + } + + ServerSrpParams srpParams = ServerSrpParams.Parse(teeIn); + + if (digestBuffer != null) + { + TlsUtilities.VerifyServerKeyExchangeSignature(m_context, input, m_serverCertificate, null, + digestBuffer); + } + + TlsSrpConfig config = new TlsSrpConfig(); + config.SetExplicitNG(new BigInteger[]{ srpParams.N, srpParams.G }); + + if (!m_srpConfigVerifier.Accept(config)) + throw new TlsFatalAlert(AlertDescription.insufficient_security); + + this.m_srpSalt = srpParams.S; + + /* + * RFC 5054 2.5.3: The client MUST abort the handshake with an "illegal_parameter" alert if + * B % N = 0. + */ + this.m_srpPeerCredentials = ValidatePublicValue(srpParams.N, srpParams.B); + this.m_srpClient = m_context.Crypto.CreateSrp6Client(config); + } + + public override void ProcessClientCredentials(TlsCredentials clientCredentials) + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public override void GenerateClientKeyExchange(Stream output) + { + byte[] identity = m_srpIdentity.GetSrpIdentity(); + byte[] password = m_srpIdentity.GetSrpPassword(); + + BigInteger A = m_srpClient.GenerateClientCredentials(m_srpSalt, identity, password); + TlsSrpUtilities.WriteSrpParameter(A, output); + + m_context.SecurityParameters.m_srpIdentity = Arrays.Clone(identity); + } + + public override void ProcessClientKeyExchange(Stream input) + { + /* + * RFC 5054 2.5.4: The server MUST abort the handshake with an "illegal_parameter" alert if + * A % N = 0. + */ + this.m_srpPeerCredentials = ValidatePublicValue(m_srpLoginParameters.Config.GetExplicitNG()[0], + TlsSrpUtilities.ReadSrpParameter(input)); + + m_context.SecurityParameters.m_srpIdentity = Arrays.Clone(m_srpLoginParameters.Identity); + } + + public override TlsSecret GeneratePreMasterSecret() + { + BigInteger S = m_srpServer != null + ? m_srpServer.CalculateSecret(m_srpPeerCredentials) + : m_srpClient.CalculateSecret(m_srpPeerCredentials); + + // TODO Check if this needs to be a fixed size + return m_context.Crypto.CreateSecret(BigIntegers.AsUnsignedByteArray(S)); + } + + protected static BigInteger ValidatePublicValue(BigInteger N, BigInteger val) + { + val = val.Mod(N); + + // Check that val % N != 0 + if (val.Equals(BigInteger.Zero)) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + return val; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSrpKeyExchange.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSrpKeyExchange.cs.meta new file mode 100644 index 0000000..0e1b76c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSrpKeyExchange.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 77607ba71189aed448556ce600be7637 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSrpLoginParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSrpLoginParameters.cs new file mode 100644 index 0000000..2dda942 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSrpLoginParameters.cs @@ -0,0 +1,44 @@ +using System; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Tls.Crypto; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls +{ + public class TlsSrpLoginParameters + { + protected byte[] m_identity; + protected TlsSrpConfig m_srpConfig; + protected BigInteger m_verifier; + protected byte[] m_salt; + + public TlsSrpLoginParameters(byte[] identity, TlsSrpConfig srpConfig, BigInteger verifier, byte[] salt) + { + this.m_identity = Arrays.Clone(identity); + this.m_srpConfig = srpConfig; + this.m_verifier = verifier; + this.m_salt = Arrays.Clone(salt); + } + + public virtual TlsSrpConfig Config + { + get { return m_srpConfig; } + } + + public virtual byte[] Identity + { + get { return m_identity; } + } + + public virtual byte[] Salt + { + get { return m_salt; } + } + + public virtual BigInteger Verifier + { + get { return m_verifier; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSrpLoginParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSrpLoginParameters.cs.meta new file mode 100644 index 0000000..57025ab --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSrpLoginParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dd7bfbc16052cb2469e8e5b7730934f0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSrpUtilities.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSrpUtilities.cs new file mode 100644 index 0000000..c36a667 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSrpUtilities.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls +{ + public abstract class TlsSrpUtilities + { + /// + public static void AddSrpExtension(IDictionary extensions, byte[] identity) + { + extensions[ExtensionType.srp] = CreateSrpExtension(identity); + } + + /// + public static byte[] GetSrpExtension(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.srp); + return extensionData == null ? null : ReadSrpExtension(extensionData); + } + + /// + public static byte[] CreateSrpExtension(byte[] identity) + { + if (identity == null) + throw new TlsFatalAlert(AlertDescription.internal_error); + + return TlsUtilities.EncodeOpaque8(identity); + } + + /// + public static byte[] ReadSrpExtension(byte[] extensionData) + { + if (extensionData == null) + throw new ArgumentNullException("extensionData"); + + return TlsUtilities.DecodeOpaque8(extensionData, 1); + } + + /// + public static BigInteger ReadSrpParameter(Stream input) + { + return new BigInteger(1, TlsUtilities.ReadOpaque16(input, 1)); + } + + /// + public static void WriteSrpParameter(BigInteger x, Stream output) + { + TlsUtilities.WriteOpaque16(BigIntegers.AsUnsignedByteArray(x), output); + } + + public static bool IsSrpCipherSuite(int cipherSuite) + { + switch (TlsUtilities.GetKeyExchangeAlgorithm(cipherSuite)) + { + case KeyExchangeAlgorithm.SRP: + case KeyExchangeAlgorithm.SRP_DSS: + case KeyExchangeAlgorithm.SRP_RSA: + return true; + + default: + return false; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSrpUtilities.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSrpUtilities.cs.meta new file mode 100644 index 0000000..f93df45 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSrpUtilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 41f9db7e0aabc9142945195ed43f673b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSrtpUtilities.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSrtpUtilities.cs new file mode 100644 index 0000000..72a9e77 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSrtpUtilities.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections; +using System.IO; + +namespace Org.BouncyCastle.Tls +{ + /// RFC 5764 DTLS Extension to Establish Keys for SRTP. + public abstract class TlsSrtpUtilities +{ + /// + public static void AddUseSrtpExtension(IDictionary extensions, UseSrtpData useSrtpData) + { + extensions[ExtensionType.use_srtp] = CreateUseSrtpExtension(useSrtpData); + } + + /// + public static UseSrtpData GetUseSrtpExtension(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.use_srtp); + return extensionData == null ? null : ReadUseSrtpExtension(extensionData); + } + + /// + public static byte[] CreateUseSrtpExtension(UseSrtpData useSrtpData) + { + if (useSrtpData == null) + throw new ArgumentNullException("useSrtpData"); + + MemoryStream buf = new MemoryStream(); + + // SRTPProtectionProfiles + TlsUtilities.WriteUint16ArrayWithUint16Length(useSrtpData.ProtectionProfiles, buf); + + // srtp_mki + TlsUtilities.WriteOpaque8(useSrtpData.Mki, buf); + + return buf.ToArray(); + } + + /// + public static UseSrtpData ReadUseSrtpExtension(byte[] extensionData) + { + if (extensionData == null) + throw new ArgumentNullException("extensionData"); + + MemoryStream buf = new MemoryStream(extensionData, false); + + // SRTPProtectionProfiles + int length = TlsUtilities.ReadUint16(buf); + if (length < 2 || (length & 1) != 0) + throw new TlsFatalAlert(AlertDescription.decode_error); + + int[] protectionProfiles = TlsUtilities.ReadUint16Array(length / 2, buf); + + // srtp_mki + byte[] mki = TlsUtilities.ReadOpaque8(buf); + + TlsProtocol.AssertEmpty(buf); + + return new UseSrtpData(protectionProfiles, mki); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSrtpUtilities.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSrtpUtilities.cs.meta new file mode 100644 index 0000000..099a463 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsSrtpUtilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 789d95ccc6503bf45b2def43d6746e62 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsStream.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsStream.cs new file mode 100644 index 0000000..9ca88a2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsStream.cs @@ -0,0 +1,96 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Tls +{ + internal class TlsStream + : Stream + { + private readonly TlsProtocol m_handler; + + internal TlsStream(TlsProtocol handler) + { + this.m_handler = handler; + } + + public override bool CanRead + { + get { return !m_handler.IsClosed; } + } + + public override bool CanSeek + { + get { return false; } + } + + public override bool CanWrite + { + get { return !m_handler.IsClosed; } + } + +#if PORTABLE + protected override void Dispose(bool disposing) + { + if (disposing) + { + m_handler.Close(); + } + base.Dispose(disposing); + } +#else + public override void Close() + { + m_handler.Close(); + base.Close(); + } +#endif + + public override void Flush() + { + m_handler.Flush(); + } + + public override long Length + { + get { throw new NotSupportedException(); } + } + + public override long Position + { + get { throw new NotSupportedException(); } + set { throw new NotSupportedException(); } + } + + public override int Read(byte[] buf, int off, int len) + { + return m_handler.ReadApplicationData(buf, off, len); + } + + public override int ReadByte() + { + byte[] buf = new byte[1]; + int ret = Read(buf, 0, 1); + return ret <= 0 ? -1 : buf[0]; + } + + public override long Seek(long offset, SeekOrigin origin) + { + throw new NotSupportedException(); + } + + public override void SetLength(long value) + { + throw new NotSupportedException(); + } + + public override void Write(byte[] buf, int off, int len) + { + m_handler.WriteApplicationData(buf, off, len); + } + + public override void WriteByte(byte b) + { + Write(new byte[]{ b }, 0, 1); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsStream.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsStream.cs.meta new file mode 100644 index 0000000..64136ad --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e281ade7a16561940ab7000921f9b0e6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsTimeoutException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsTimeoutException.cs new file mode 100644 index 0000000..ce2e1ac --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsTimeoutException.cs @@ -0,0 +1,24 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Tls +{ + public class TlsTimeoutException + : IOException + { + public TlsTimeoutException() + : base() + { + } + + public TlsTimeoutException(string message) + : base(message) + { + } + + public TlsTimeoutException(string message, Exception cause) + : base(message, cause) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsTimeoutException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsTimeoutException.cs.meta new file mode 100644 index 0000000..a136b64 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsTimeoutException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a843a13bf9057e244a2eed8c5fbaac6c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsUtilities.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsUtilities.cs new file mode 100644 index 0000000..d1e0469 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsUtilities.cs @@ -0,0 +1,5662 @@ +using System; +using System.Collections; +using System.IO; +#if !PORTABLE || DOTNET +using System.Net.Sockets; +#endif + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Bsi; +using Org.BouncyCastle.Asn1.Eac; +using Org.BouncyCastle.Asn1.EdEC; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Oiw; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.Rosstandart; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Tls.Crypto; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Date; +using Org.BouncyCastle.Utilities.Encoders; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Tls +{ + public abstract class TlsUtilities + { + private static readonly byte[] DowngradeTlsV11 = Hex.DecodeStrict("444F574E47524400"); + private static readonly byte[] DowngradeTlsV12 = Hex.DecodeStrict("444F574E47524401"); + + private static readonly IDictionary CertSigAlgOids = CreateCertSigAlgOids(); + private static readonly IList DefaultSupportedSigAlgs = CreateDefaultSupportedSigAlgs(); + + private static void AddCertSigAlgOid(IDictionary d, DerObjectIdentifier oid, + SignatureAndHashAlgorithm sigAndHash) + { + d[oid.Id] = sigAndHash; + } + + private static void AddCertSigAlgOid(IDictionary d, DerObjectIdentifier oid, short hashAlgorithm, + short signatureAlgorithm) + { + AddCertSigAlgOid(d, oid, SignatureAndHashAlgorithm.GetInstance(hashAlgorithm, signatureAlgorithm)); + } + + private static IDictionary CreateCertSigAlgOids() + { + IDictionary d = Platform.CreateHashtable(); + + AddCertSigAlgOid(d, NistObjectIdentifiers.DsaWithSha224, HashAlgorithm.sha224, SignatureAlgorithm.dsa); + AddCertSigAlgOid(d, NistObjectIdentifiers.DsaWithSha256, HashAlgorithm.sha256, SignatureAlgorithm.dsa); + AddCertSigAlgOid(d, NistObjectIdentifiers.DsaWithSha384, HashAlgorithm.sha384, SignatureAlgorithm.dsa); + AddCertSigAlgOid(d, NistObjectIdentifiers.DsaWithSha512, HashAlgorithm.sha512, SignatureAlgorithm.dsa); + + AddCertSigAlgOid(d, OiwObjectIdentifiers.DsaWithSha1, HashAlgorithm.sha1, SignatureAlgorithm.dsa); + AddCertSigAlgOid(d, OiwObjectIdentifiers.Sha1WithRsa, HashAlgorithm.sha1, SignatureAlgorithm.rsa); + + AddCertSigAlgOid(d, PkcsObjectIdentifiers.Sha1WithRsaEncryption, HashAlgorithm.sha1, SignatureAlgorithm.rsa); + AddCertSigAlgOid(d, PkcsObjectIdentifiers.Sha224WithRsaEncryption, HashAlgorithm.sha224, SignatureAlgorithm.rsa); + AddCertSigAlgOid(d, PkcsObjectIdentifiers.Sha256WithRsaEncryption, HashAlgorithm.sha256, SignatureAlgorithm.rsa); + AddCertSigAlgOid(d, PkcsObjectIdentifiers.Sha384WithRsaEncryption, HashAlgorithm.sha384, SignatureAlgorithm.rsa); + AddCertSigAlgOid(d, PkcsObjectIdentifiers.Sha512WithRsaEncryption, HashAlgorithm.sha512, SignatureAlgorithm.rsa); + + AddCertSigAlgOid(d, X9ObjectIdentifiers.ECDsaWithSha1, HashAlgorithm.sha1, SignatureAlgorithm.ecdsa); + AddCertSigAlgOid(d, X9ObjectIdentifiers.ECDsaWithSha224, HashAlgorithm.sha224, SignatureAlgorithm.ecdsa); + AddCertSigAlgOid(d, X9ObjectIdentifiers.ECDsaWithSha256, HashAlgorithm.sha256, SignatureAlgorithm.ecdsa); + AddCertSigAlgOid(d, X9ObjectIdentifiers.ECDsaWithSha384, HashAlgorithm.sha384, SignatureAlgorithm.ecdsa); + AddCertSigAlgOid(d, X9ObjectIdentifiers.ECDsaWithSha512, HashAlgorithm.sha512, SignatureAlgorithm.ecdsa); + AddCertSigAlgOid(d, X9ObjectIdentifiers.IdDsaWithSha1, HashAlgorithm.sha1, SignatureAlgorithm.dsa); + + AddCertSigAlgOid(d, EacObjectIdentifiers.id_TA_ECDSA_SHA_1, HashAlgorithm.sha1, SignatureAlgorithm.ecdsa); + AddCertSigAlgOid(d, EacObjectIdentifiers.id_TA_ECDSA_SHA_224, HashAlgorithm.sha224, SignatureAlgorithm.ecdsa); + AddCertSigAlgOid(d, EacObjectIdentifiers.id_TA_ECDSA_SHA_256, HashAlgorithm.sha256, SignatureAlgorithm.ecdsa); + AddCertSigAlgOid(d, EacObjectIdentifiers.id_TA_ECDSA_SHA_384, HashAlgorithm.sha384, SignatureAlgorithm.ecdsa); + AddCertSigAlgOid(d, EacObjectIdentifiers.id_TA_ECDSA_SHA_512, HashAlgorithm.sha512, SignatureAlgorithm.ecdsa); + AddCertSigAlgOid(d, EacObjectIdentifiers.id_TA_RSA_v1_5_SHA_1, HashAlgorithm.sha1, SignatureAlgorithm.rsa); + AddCertSigAlgOid(d, EacObjectIdentifiers.id_TA_RSA_v1_5_SHA_256, HashAlgorithm.sha256, SignatureAlgorithm.rsa); + + AddCertSigAlgOid(d, BsiObjectIdentifiers.ecdsa_plain_SHA1, HashAlgorithm.sha1, SignatureAlgorithm.ecdsa); + AddCertSigAlgOid(d, BsiObjectIdentifiers.ecdsa_plain_SHA224, HashAlgorithm.sha224, SignatureAlgorithm.ecdsa); + AddCertSigAlgOid(d, BsiObjectIdentifiers.ecdsa_plain_SHA256, HashAlgorithm.sha256, SignatureAlgorithm.ecdsa); + AddCertSigAlgOid(d, BsiObjectIdentifiers.ecdsa_plain_SHA384, HashAlgorithm.sha384, SignatureAlgorithm.ecdsa); + AddCertSigAlgOid(d, BsiObjectIdentifiers.ecdsa_plain_SHA512, HashAlgorithm.sha512, SignatureAlgorithm.ecdsa); + + AddCertSigAlgOid(d, EdECObjectIdentifiers.id_Ed25519, SignatureAndHashAlgorithm.ed25519); + AddCertSigAlgOid(d, EdECObjectIdentifiers.id_Ed448, SignatureAndHashAlgorithm.ed448); + + AddCertSigAlgOid(d, RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_256, + SignatureAndHashAlgorithm.gostr34102012_256); + AddCertSigAlgOid(d, RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512, + SignatureAndHashAlgorithm.gostr34102012_512); + + // TODO[RFC 8998] + //AddCertSigAlgOid(d, GMObjectIdentifiers.sm2sign_with_sm3, HashAlgorithm.sm3, SignatureAlgorithm.sm2); + + return d; + } + + private static IList CreateDefaultSupportedSigAlgs() + { + IList result = Platform.CreateArrayList(); + result.Add(SignatureAndHashAlgorithm.ed25519); + result.Add(SignatureAndHashAlgorithm.ed448); + result.Add(SignatureAndHashAlgorithm.GetInstance(HashAlgorithm.sha256, SignatureAlgorithm.ecdsa)); + result.Add(SignatureAndHashAlgorithm.GetInstance(HashAlgorithm.sha384, SignatureAlgorithm.ecdsa)); + result.Add(SignatureAndHashAlgorithm.GetInstance(HashAlgorithm.sha512, SignatureAlgorithm.ecdsa)); + result.Add(SignatureAndHashAlgorithm.rsa_pss_rsae_sha256); + result.Add(SignatureAndHashAlgorithm.rsa_pss_rsae_sha384); + result.Add(SignatureAndHashAlgorithm.rsa_pss_rsae_sha512); + result.Add(SignatureAndHashAlgorithm.rsa_pss_pss_sha256); + result.Add(SignatureAndHashAlgorithm.rsa_pss_pss_sha384); + result.Add(SignatureAndHashAlgorithm.rsa_pss_pss_sha512); + result.Add(SignatureAndHashAlgorithm.GetInstance(HashAlgorithm.sha256, SignatureAlgorithm.rsa)); + result.Add(SignatureAndHashAlgorithm.GetInstance(HashAlgorithm.sha384, SignatureAlgorithm.rsa)); + result.Add(SignatureAndHashAlgorithm.GetInstance(HashAlgorithm.sha512, SignatureAlgorithm.rsa)); + result.Add(SignatureAndHashAlgorithm.GetInstance(HashAlgorithm.sha256, SignatureAlgorithm.dsa)); + result.Add(SignatureAndHashAlgorithm.GetInstance(HashAlgorithm.sha384, SignatureAlgorithm.dsa)); + result.Add(SignatureAndHashAlgorithm.GetInstance(HashAlgorithm.sha512, SignatureAlgorithm.dsa)); + result.Add(SignatureAndHashAlgorithm.GetInstance(HashAlgorithm.sha224, SignatureAlgorithm.ecdsa)); + result.Add(SignatureAndHashAlgorithm.GetInstance(HashAlgorithm.sha224, SignatureAlgorithm.rsa)); + result.Add(SignatureAndHashAlgorithm.GetInstance(HashAlgorithm.sha224, SignatureAlgorithm.dsa)); + result.Add(SignatureAndHashAlgorithm.GetInstance(HashAlgorithm.sha1, SignatureAlgorithm.ecdsa)); + result.Add(SignatureAndHashAlgorithm.GetInstance(HashAlgorithm.sha1, SignatureAlgorithm.rsa)); + result.Add(SignatureAndHashAlgorithm.GetInstance(HashAlgorithm.sha1, SignatureAlgorithm.dsa)); + return result; + } + + public static readonly byte[] EmptyBytes = new byte[0]; + public static readonly short[] EmptyShorts = new short[0]; + public static readonly int[] EmptyInts = new int[0]; + public static readonly long[] EmptyLongs = new long[0]; + public static readonly string[] EmptyStrings = new string[0]; + + internal static short MinimumHashStrict = HashAlgorithm.sha1; + internal static short MinimumHashPreferred = HashAlgorithm.sha256; + + public static void CheckUint8(short i) + { + if (!IsValidUint8(i)) + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public static void CheckUint8(int i) + { + if (!IsValidUint8(i)) + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public static void CheckUint8(long i) + { + if (!IsValidUint8(i)) + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public static void CheckUint16(int i) + { + if (!IsValidUint16(i)) + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public static void CheckUint16(long i) + { + if (!IsValidUint16(i)) + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public static void CheckUint24(int i) + { + if (!IsValidUint24(i)) + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public static void CheckUint24(long i) + { + if (!IsValidUint24(i)) + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public static void CheckUint32(long i) + { + if (!IsValidUint32(i)) + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public static void CheckUint48(long i) + { + if (!IsValidUint48(i)) + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public static void CheckUint64(long i) + { + if (!IsValidUint64(i)) + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public static bool IsValidUint8(short i) + { + return (i & 0xFF) == i; + } + + public static bool IsValidUint8(int i) + { + return (i & 0xFF) == i; + } + + public static bool IsValidUint8(long i) + { + return (i & 0xFFL) == i; + } + + public static bool IsValidUint16(int i) + { + return (i & 0xFFFF) == i; + } + + public static bool IsValidUint16(long i) + { + return (i & 0xFFFFL) == i; + } + + public static bool IsValidUint24(int i) + { + return (i & 0xFFFFFF) == i; + } + + public static bool IsValidUint24(long i) + { + return (i & 0xFFFFFFL) == i; + } + + public static bool IsValidUint32(long i) + { + return (i & 0xFFFFFFFFL) == i; + } + + public static bool IsValidUint48(long i) + { + return (i & 0xFFFFFFFFFFFFL) == i; + } + + public static bool IsValidUint64(long i) + { + return true; + } + + public static bool IsSsl(TlsContext context) + { + return context.ServerVersion.IsSsl; + } + + public static bool IsTlsV10(ProtocolVersion version) + { + return ProtocolVersion.TLSv10.IsEqualOrEarlierVersionOf(version.GetEquivalentTlsVersion()); + } + + public static bool IsTlsV10(TlsContext context) + { + return IsTlsV10(context.ServerVersion); + } + + public static bool IsTlsV11(ProtocolVersion version) + { + return ProtocolVersion.TLSv11.IsEqualOrEarlierVersionOf(version.GetEquivalentTlsVersion()); + } + + public static bool IsTlsV11(TlsContext context) + { + return IsTlsV11(context.ServerVersion); + } + + public static bool IsTlsV12(ProtocolVersion version) + { + return ProtocolVersion.TLSv12.IsEqualOrEarlierVersionOf(version.GetEquivalentTlsVersion()); + } + + public static bool IsTlsV12(TlsContext context) + { + return IsTlsV12(context.ServerVersion); + } + + public static bool IsTlsV13(ProtocolVersion version) + { + return ProtocolVersion.TLSv13.IsEqualOrEarlierVersionOf(version.GetEquivalentTlsVersion()); + } + + public static bool IsTlsV13(TlsContext context) + { + return IsTlsV13(context.ServerVersion); + } + + public static void WriteUint8(short i, Stream output) + { + output.WriteByte((byte)i); + } + + public static void WriteUint8(int i, Stream output) + { + output.WriteByte((byte)i); + } + + public static void WriteUint8(short i, byte[] buf, int offset) + { + buf[offset] = (byte)i; + } + + public static void WriteUint8(int i, byte[] buf, int offset) + { + buf[offset] = (byte)i; + } + + public static void WriteUint16(int i, Stream output) + { + output.WriteByte((byte)(i >> 8)); + output.WriteByte((byte)i); + } + + public static void WriteUint16(int i, byte[] buf, int offset) + { + buf[offset ] = (byte)(i >> 8); + buf[offset + 1] = (byte)i; + } + + public static void WriteUint24(int i, Stream output) + { + output.WriteByte((byte)(i >> 16)); + output.WriteByte((byte)(i >> 8)); + output.WriteByte((byte)i); + } + + public static void WriteUint24(int i, byte[] buf, int offset) + { + buf[offset ] = (byte)(i >> 16); + buf[offset + 1] = (byte)(i >> 8); + buf[offset + 2] = (byte)i; + } + + public static void WriteUint32(long i, Stream output) + { + output.WriteByte((byte)(i >> 24)); + output.WriteByte((byte)(i >> 16)); + output.WriteByte((byte)(i >> 8)); + output.WriteByte((byte)i); + } + + public static void WriteUint32(long i, byte[] buf, int offset) + { + buf[offset ] = (byte)(i >> 24); + buf[offset + 1] = (byte)(i >> 16); + buf[offset + 2] = (byte)(i >> 8); + buf[offset + 3] = (byte)i; + } + + public static void WriteUint48(long i, Stream output) + { + output.WriteByte((byte)(i >> 40)); + output.WriteByte((byte)(i >> 32)); + output.WriteByte((byte)(i >> 24)); + output.WriteByte((byte)(i >> 16)); + output.WriteByte((byte)(i >> 8)); + output.WriteByte((byte)i); + } + + public static void WriteUint48(long i, byte[] buf, int offset) + { + buf[offset ] = (byte)(i >> 40); + buf[offset + 1] = (byte)(i >> 32); + buf[offset + 2] = (byte)(i >> 24); + buf[offset + 3] = (byte)(i >> 16); + buf[offset + 4] = (byte)(i >> 8); + buf[offset + 5] = (byte)i; + } + + public static void WriteUint64(long i, Stream output) + { + output.WriteByte((byte)(i >> 56)); + output.WriteByte((byte)(i >> 48)); + output.WriteByte((byte)(i >> 40)); + output.WriteByte((byte)(i >> 32)); + output.WriteByte((byte)(i >> 24)); + output.WriteByte((byte)(i >> 16)); + output.WriteByte((byte)(i >> 8)); + output.WriteByte((byte) i); + } + + public static void WriteUint64(long i, byte[] buf, int offset) + { + buf[offset ] = (byte)(i >> 56); + buf[offset + 1] = (byte)(i >> 48); + buf[offset + 2] = (byte)(i >> 40); + buf[offset + 3] = (byte)(i >> 32); + buf[offset + 4] = (byte)(i >> 24); + buf[offset + 5] = (byte)(i >> 16); + buf[offset + 6] = (byte)(i >> 8); + buf[offset + 7] = (byte)i; + } + + public static void WriteOpaque8(byte[] buf, Stream output) + { + CheckUint8(buf.Length); + WriteUint8(buf.Length, output); + output.Write(buf, 0, buf.Length); + } + + public static void WriteOpaque8(byte[] data, byte[] buf, int off) + { + CheckUint8(data.Length); + WriteUint8(data.Length, buf, off); + Array.Copy(data, 0, buf, off + 1, data.Length); + } + + public static void WriteOpaque16(byte[] buf, Stream output) + { + CheckUint16(buf.Length); + WriteUint16(buf.Length, output); + output.Write(buf, 0, buf.Length); + } + + public static void WriteOpaque16(byte[] data, byte[] buf, int off) + { + CheckUint16(data.Length); + WriteUint16(data.Length, buf, off); + Array.Copy(data, 0, buf, off + 2, data.Length); + } + + public static void WriteOpaque24(byte[] buf, Stream output) + { + CheckUint24(buf.Length); + WriteUint24(buf.Length, output); + output.Write(buf, 0, buf.Length); + } + + public static void WriteOpaque24(byte[] data, byte[] buf, int off) + { + CheckUint24(data.Length); + WriteUint24(data.Length, buf, off); + Array.Copy(data, 0, buf, off + 3, data.Length); + } + + public static void WriteUint8Array(short[] u8s, Stream output) + { + for (int i = 0; i < u8s.Length; ++i) + { + WriteUint8(u8s[i], output); + } + } + + public static void WriteUint8Array(short[] u8s, byte[] buf, int offset) + { + for (int i = 0; i < u8s.Length; ++i) + { + WriteUint8(u8s[i], buf, offset); + ++offset; + } + } + + public static void WriteUint8ArrayWithUint8Length(short[] u8s, Stream output) + { + CheckUint8(u8s.Length); + WriteUint8(u8s.Length, output); + WriteUint8Array(u8s, output); + } + + public static void WriteUint8ArrayWithUint8Length(short[] u8s, byte[] buf, int offset) + { + CheckUint8(u8s.Length); + WriteUint8(u8s.Length, buf, offset); + WriteUint8Array(u8s, buf, offset + 1); + } + + public static void WriteUint16Array(int[] u16s, Stream output) + { + for (int i = 0; i < u16s.Length; ++i) + { + WriteUint16(u16s[i], output); + } + } + + public static void WriteUint16Array(int[] u16s, byte[] buf, int offset) + { + for (int i = 0; i < u16s.Length; ++i) + { + WriteUint16(u16s[i], buf, offset); + offset += 2; + } + } + + public static void WriteUint16ArrayWithUint16Length(int[] u16s, Stream output) + { + int length = 2 * u16s.Length; + CheckUint16(length); + WriteUint16(length, output); + WriteUint16Array(u16s, output); + } + + public static void WriteUint16ArrayWithUint16Length(int[] u16s, byte[] buf, int offset) + { + int length = 2 * u16s.Length; + CheckUint16(length); + WriteUint16(length, buf, offset); + WriteUint16Array(u16s, buf, offset + 2); + } + + public static byte[] DecodeOpaque8(byte[] buf) + { + return DecodeOpaque8(buf, 0); + } + + public static byte[] DecodeOpaque8(byte[] buf, int minLength) + { + if (buf == null) + throw new ArgumentNullException("buf"); + if (buf.Length < 1) + throw new TlsFatalAlert(AlertDescription.decode_error); + + short length = ReadUint8(buf, 0); + if (buf.Length != (length + 1) || length < minLength) + throw new TlsFatalAlert(AlertDescription.decode_error); + + return CopyOfRangeExact(buf, 1, buf.Length); + } + + public static byte[] DecodeOpaque16(byte[] buf) + { + return DecodeOpaque16(buf, 0); + } + + public static byte[] DecodeOpaque16(byte[] buf, int minLength) + { + if (buf == null) + throw new ArgumentNullException("buf"); + if (buf.Length < 2) + throw new TlsFatalAlert(AlertDescription.decode_error); + + int length = ReadUint16(buf, 0); + if (buf.Length != (length + 2) || length < minLength) + throw new TlsFatalAlert(AlertDescription.decode_error); + + return CopyOfRangeExact(buf, 2, buf.Length); + } + + public static short DecodeUint8(byte[] buf) + { + if (buf == null) + throw new ArgumentNullException("buf"); + if (buf.Length != 1) + throw new TlsFatalAlert(AlertDescription.decode_error); + + return ReadUint8(buf, 0); + } + + public static short[] DecodeUint8ArrayWithUint8Length(byte[] buf) + { + if (buf == null) + throw new ArgumentNullException("buf"); + + int count = ReadUint8(buf, 0); + if (buf.Length != (count + 1)) + throw new TlsFatalAlert(AlertDescription.decode_error); + + short[] uints = new short[count]; + for (int i = 0; i < count; ++i) + { + uints[i] = ReadUint8(buf, i + 1); + } + return uints; + } + + public static int DecodeUint16(byte[] buf) + { + if (buf == null) + throw new ArgumentNullException("buf"); + if (buf.Length != 2) + throw new TlsFatalAlert(AlertDescription.decode_error); + + return ReadUint16(buf, 0); + } + + public static long DecodeUint32(byte[] buf) + { + if (buf == null) + throw new ArgumentNullException("buf"); + if (buf.Length != 4) + throw new TlsFatalAlert(AlertDescription.decode_error); + + return ReadUint32(buf, 0); + } + + public static byte[] EncodeOpaque8(byte[] buf) + { + CheckUint8(buf.Length); + return Arrays.Prepend(buf, (byte)buf.Length); + } + + public static byte[] EncodeOpaque16(byte[] buf) + { + CheckUint16(buf.Length); + byte[] r = new byte[2 + buf.Length]; + WriteUint16(buf.Length, r, 0); + Array.Copy(buf, 0, r, 2, buf.Length); + return r; + } + + public static byte[] EncodeOpaque24(byte[] buf) + { + CheckUint24(buf.Length); + byte[] r = new byte[3 + buf.Length]; + WriteUint24(buf.Length, r, 0); + Array.Copy(buf, 0, r, 3, buf.Length); + return r; + } + + public static byte[] EncodeUint8(short u8) + { + CheckUint8(u8); + + byte[] encoding = new byte[1]; + WriteUint8(u8, encoding, 0); + return encoding; + } + + public static byte[] EncodeUint8ArrayWithUint8Length(short[] u8s) + { + byte[] result = new byte[1 + u8s.Length]; + WriteUint8ArrayWithUint8Length(u8s, result, 0); + return result; + } + + public static byte[] EncodeUint16(int u16) + { + CheckUint16(u16); + + byte[] encoding = new byte[2]; + WriteUint16(u16, encoding, 0); + return encoding; + } + + public static byte[] EncodeUint16ArrayWithUint16Length(int[] u16s) + { + int length = 2 * u16s.Length; + byte[] result = new byte[2 + length]; + WriteUint16ArrayWithUint16Length(u16s, result, 0); + return result; + } + + public static byte[] EncodeUint24(int u24) + { + CheckUint24(u24); + + byte[] encoding = new byte[3]; + WriteUint24(u24, encoding, 0); + return encoding; + } + + public static byte[] EncodeUint32(long u32) + { + CheckUint32(u32); + + byte[] encoding = new byte[4]; + WriteUint32(u32, encoding, 0); + return encoding; + } + + public static byte[] EncodeVersion(ProtocolVersion version) + { + return new byte[]{ + (byte)version.MajorVersion, + (byte)version.MinorVersion + }; + } + + public static int ReadInt32(byte[] buf, int offset) + { + int n = buf[offset] << 24; + n |= (buf[++offset] & 0xff) << 16; + n |= (buf[++offset] & 0xff) << 8; + n |= (buf[++offset] & 0xff); + return n; + } + + public static short ReadUint8(Stream input) + { + int i = input.ReadByte(); + if (i < 0) + throw new EndOfStreamException(); + return (short)i; + } + + public static short ReadUint8(byte[] buf, int offset) + { + return (short)(buf[offset] & 0xff); + } + + public static int ReadUint16(Stream input) + { + int i1 = input.ReadByte(); + int i2 = input.ReadByte(); + if (i2 < 0) + throw new EndOfStreamException(); + return (i1 << 8) | i2; + } + + public static int ReadUint16(byte[] buf, int offset) + { + int n = (buf[offset] & 0xff) << 8; + n |= (buf[++offset] & 0xff); + return n; + } + + public static int ReadUint24(Stream input) + { + int i1 = input.ReadByte(); + int i2 = input.ReadByte(); + int i3 = input.ReadByte(); + if (i3 < 0) + throw new EndOfStreamException(); + + return (i1 << 16) | (i2 << 8) | i3; + } + + public static int ReadUint24(byte[] buf, int offset) + { + int n = (buf[offset] & 0xff) << 16; + n |= (buf[++offset] & 0xff) << 8; + n |= (buf[++offset] & 0xff); + return n; + } + + public static long ReadUint32(Stream input) + { + int i1 = input.ReadByte(); + int i2 = input.ReadByte(); + int i3 = input.ReadByte(); + int i4 = input.ReadByte(); + if (i4 < 0) + throw new EndOfStreamException(); + + return ((i1 << 24) | (i2 << 16) | (i3 << 8) | i4) & 0xFFFFFFFFL; + } + + public static long ReadUint32(byte[] buf, int offset) + { + int n = (buf[offset] & 0xff) << 24; + n |= (buf[++offset] & 0xff) << 16; + n |= (buf[++offset] & 0xff) << 8; + n |= (buf[++offset] & 0xff); + return n & 0xFFFFFFFFL; + } + + public static long ReadUint48(Stream input) + { + int hi = ReadUint24(input); + int lo = ReadUint24(input); + return ((long)(hi & 0xffffffffL) << 24) | (long)(lo & 0xffffffffL); + } + + public static long ReadUint48(byte[] buf, int offset) + { + int hi = ReadUint24(buf, offset); + int lo = ReadUint24(buf, offset + 3); + return ((long)(hi & 0xffffffffL) << 24) | (long)(lo & 0xffffffffL); + } + + public static byte[] ReadAllOrNothing(int length, Stream input) + { + if (length < 1) + return EmptyBytes; + byte[] buf = new byte[length]; + int read = Streams.ReadFully(input, buf); + if (read == 0) + return null; + if (read != length) + throw new EndOfStreamException(); + return buf; + } + + public static byte[] ReadFully(int length, Stream input) + { + if (length < 1) + return EmptyBytes; + byte[] buf = new byte[length]; + if (length != Streams.ReadFully(input, buf)) + throw new EndOfStreamException(); + return buf; + } + + public static void ReadFully(byte[] buf, Stream input) + { + int length = buf.Length; + if (length > 0 && length != Streams.ReadFully(input, buf)) + throw new EndOfStreamException(); + } + + public static byte[] ReadOpaque8(Stream input) + { + short length = ReadUint8(input); + return ReadFully(length, input); + } + + public static byte[] ReadOpaque8(Stream input, int minLength) + { + short length = ReadUint8(input); + if (length < minLength) + throw new TlsFatalAlert(AlertDescription.decode_error); + + return ReadFully(length, input); + } + + public static byte[] ReadOpaque8(Stream input, int minLength, int maxLength) + { + short length = ReadUint8(input); + if (length < minLength || maxLength < length) + throw new TlsFatalAlert(AlertDescription.decode_error); + + return ReadFully(length, input); + } + + public static byte[] ReadOpaque16(Stream input) + { + int length = ReadUint16(input); + return ReadFully(length, input); + } + + public static byte[] ReadOpaque16(Stream input, int minLength) + { + int length = ReadUint16(input); + if (length < minLength) + throw new TlsFatalAlert(AlertDescription.decode_error); + + return ReadFully(length, input); + } + + public static byte[] ReadOpaque24(Stream input) + { + int length = ReadUint24(input); + return ReadFully(length, input); + } + + public static byte[] ReadOpaque24(Stream input, int minLength) + { + int length = ReadUint24(input); + if (length < minLength) + throw new TlsFatalAlert(AlertDescription.decode_error); + + return ReadFully(length, input); + } + + public static short[] ReadUint8Array(int count, Stream input) + { + short[] uints = new short[count]; + for (int i = 0; i < count; ++i) + { + uints[i] = ReadUint8(input); + } + return uints; + } + + public static short[] ReadUint8ArrayWithUint8Length(Stream input, int minLength) + { + int length = ReadUint8(input); + if (length < minLength) + throw new TlsFatalAlert(AlertDescription.decode_error); + + return ReadUint8Array(length, input); + } + + public static int[] ReadUint16Array(int count, Stream input) + { + int[] uints = new int[count]; + for (int i = 0; i < count; ++i) + { + uints[i] = ReadUint16(input); + } + return uints; + } + + public static ProtocolVersion ReadVersion(byte[] buf, int offset) + { + return ProtocolVersion.Get(buf[offset], buf[offset + 1]); + } + + public static ProtocolVersion ReadVersion(Stream input) + { + int i1 = input.ReadByte(); + int i2 = input.ReadByte(); + if (i2 < 0) + throw new EndOfStreamException(); + + return ProtocolVersion.Get(i1, i2); + } + + public static Asn1Object ReadAsn1Object(byte[] encoding) + { + Asn1InputStream asn1 = new Asn1InputStream(encoding); + Asn1Object result = asn1.ReadObject(); + if (null == result) + throw new TlsFatalAlert(AlertDescription.decode_error); + if (null != asn1.ReadObject()) + throw new TlsFatalAlert(AlertDescription.decode_error); + + return result; + } + + public static Asn1Object ReadDerObject(byte[] encoding) + { + /* + * NOTE: The current ASN.1 parsing code can't enforce DER-only parsing, but since DER is + * canonical, we can check it by re-encoding the result and comparing to the original. + */ + Asn1Object result = ReadAsn1Object(encoding); + byte[] check = result.GetEncoded(Asn1Encodable.Der); + if (!Arrays.AreEqual(check, encoding)) + throw new TlsFatalAlert(AlertDescription.decode_error); + + return result; + } + + public static void WriteGmtUnixTime(byte[] buf, int offset) + { + int t = (int)(DateTimeUtilities.CurrentUnixMs() / 1000L); + buf[offset ] = (byte)(t >> 24); + buf[offset + 1] = (byte)(t >> 16); + buf[offset + 2] = (byte)(t >> 8); + buf[offset + 3] = (byte)t; + } + + public static void WriteVersion(ProtocolVersion version, Stream output) + { + output.WriteByte((byte)version.MajorVersion); + output.WriteByte((byte)version.MinorVersion); + } + + public static void WriteVersion(ProtocolVersion version, byte[] buf, int offset) + { + buf[offset] = (byte)version.MajorVersion; + buf[offset + 1] = (byte)version.MinorVersion; + } + + public static void AddIfSupported(IList supportedAlgs, TlsCrypto crypto, SignatureAndHashAlgorithm alg) + { + if (crypto.HasSignatureAndHashAlgorithm(alg)) + { + supportedAlgs.Add(alg); + } + } + + public static void AddIfSupported(IList supportedGroups, TlsCrypto crypto, int namedGroup) + { + if (crypto.HasNamedGroup(namedGroup)) + { + supportedGroups.Add(namedGroup); + } + } + + public static void AddIfSupported(IList supportedGroups, TlsCrypto crypto, int[] namedGroups) + { + for (int i = 0; i < namedGroups.Length; ++i) + { + AddIfSupported(supportedGroups, crypto, namedGroups[i]); + } + } + + public static bool AddToSet(IList s, int i) + { + bool result = !s.Contains(i); + if (result) + { + s.Add(i); + } + return result; + } + + public static IList GetDefaultDssSignatureAlgorithms() + { + return GetDefaultSignatureAlgorithms(SignatureAlgorithm.dsa); + } + + public static IList GetDefaultECDsaSignatureAlgorithms() + { + return GetDefaultSignatureAlgorithms(SignatureAlgorithm.ecdsa); + } + + public static IList GetDefaultRsaSignatureAlgorithms() + { + return GetDefaultSignatureAlgorithms(SignatureAlgorithm.rsa); + } + + public static SignatureAndHashAlgorithm GetDefaultSignatureAlgorithm(short signatureAlgorithm) + { + /* + * RFC 5246 7.4.1.4.1. If the client does not send the signature_algorithms extension, + * the server MUST do the following: + * + * - If the negotiated key exchange algorithm is one of (RSA, DHE_RSA, DH_RSA, RSA_PSK, + * ECDH_RSA, ECDHE_RSA), behave as if client had sent the value {sha1,rsa}. + * + * - If the negotiated key exchange algorithm is one of (DHE_DSS, DH_DSS), behave as if + * the client had sent the value {sha1,dsa}. + * + * - If the negotiated key exchange algorithm is one of (ECDH_ECDSA, ECDHE_ECDSA), + * behave as if the client had sent value {sha1,ecdsa}. + */ + + switch (signatureAlgorithm) + { + case SignatureAlgorithm.dsa: + case SignatureAlgorithm.ecdsa: + case SignatureAlgorithm.rsa: + return SignatureAndHashAlgorithm.GetInstance(HashAlgorithm.sha1, signatureAlgorithm); + default: + return null; + } + } + + public static IList GetDefaultSignatureAlgorithms(short signatureAlgorithm) + { + SignatureAndHashAlgorithm sigAndHashAlg = GetDefaultSignatureAlgorithm(signatureAlgorithm); + + return null == sigAndHashAlg ? Platform.CreateArrayList() : VectorOfOne(sigAndHashAlg); + } + + public static IList GetDefaultSupportedSignatureAlgorithms(TlsContext context) + { + TlsCrypto crypto = context.Crypto; + + IList result = Platform.CreateArrayList(DefaultSupportedSigAlgs.Count); + foreach (SignatureAndHashAlgorithm sigAndHashAlg in DefaultSupportedSigAlgs) + { + AddIfSupported(result, crypto, sigAndHashAlg); + } + return result; + } + + public static SignatureAndHashAlgorithm GetSignatureAndHashAlgorithm(TlsContext context, + TlsCredentialedSigner signerCredentials) + { + return GetSignatureAndHashAlgorithm(context.ServerVersion, signerCredentials); + } + + internal static SignatureAndHashAlgorithm GetSignatureAndHashAlgorithm(ProtocolVersion negotiatedVersion, + TlsCredentialedSigner signerCredentials) + { + SignatureAndHashAlgorithm signatureAndHashAlgorithm = null; + if (IsTlsV12(negotiatedVersion)) + { + signatureAndHashAlgorithm = signerCredentials.SignatureAndHashAlgorithm; + if (signatureAndHashAlgorithm == null) + throw new TlsFatalAlert(AlertDescription.internal_error); + } + return signatureAndHashAlgorithm; + } + + public static byte[] GetExtensionData(IDictionary extensions, int extensionType) + { + return extensions == null || !extensions.Contains(extensionType) + ? null + : (byte[])extensions[extensionType]; + } + + public static bool HasExpectedEmptyExtensionData(IDictionary extensions, int extensionType, + short alertDescription) + { + byte[] extension_data = GetExtensionData(extensions, extensionType); + if (extension_data == null) + return false; + + if (extension_data.Length != 0) + throw new TlsFatalAlert(alertDescription); + + return true; + } + + public static TlsSession ImportSession(byte[] sessionID, SessionParameters sessionParameters) + { + return new TlsSessionImpl(sessionID, sessionParameters); + } + + internal static bool IsExtendedMasterSecretOptionalDtls(ProtocolVersion[] activeProtocolVersions) + { + return ProtocolVersion.Contains(activeProtocolVersions, ProtocolVersion.DTLSv12) + || ProtocolVersion.Contains(activeProtocolVersions, ProtocolVersion.DTLSv10); + } + + internal static bool IsExtendedMasterSecretOptionalTls(ProtocolVersion[] activeProtocolVersions) + { + return ProtocolVersion.Contains(activeProtocolVersions, ProtocolVersion.TLSv12) + || ProtocolVersion.Contains(activeProtocolVersions, ProtocolVersion.TLSv11) + || ProtocolVersion.Contains(activeProtocolVersions, ProtocolVersion.TLSv10); + } + + public static bool IsNullOrContainsNull(object[] array) + { + if (null == array) + return true; + + int count = array.Length; + for (int i = 0; i < count; ++i) + { + if (null == array[i]) + return true; + } + return false; + } + + public static bool IsNullOrEmpty(byte[] array) + { + return null == array || array.Length < 1; + } + + public static bool IsNullOrEmpty(short[] array) + { + return null == array || array.Length < 1; + } + + public static bool IsNullOrEmpty(int[] array) + { + return null == array || array.Length < 1; + } + + public static bool IsNullOrEmpty(object[] array) + { + return null == array || array.Length < 1; + } + + public static bool IsNullOrEmpty(string s) + { + return null == s || s.Length < 1; + } + + public static bool IsNullOrEmpty(IList v) + { + return null == v || v.Count < 1; + } + + public static bool IsSignatureAlgorithmsExtensionAllowed(ProtocolVersion version) + { + return null != version + && ProtocolVersion.TLSv12.IsEqualOrEarlierVersionOf(version.GetEquivalentTlsVersion()); + } + + public static short GetLegacyClientCertType(short signatureAlgorithm) + { + switch (signatureAlgorithm) + { + case SignatureAlgorithm.rsa: + return ClientCertificateType.rsa_sign; + case SignatureAlgorithm.dsa: + return ClientCertificateType.dss_sign; + case SignatureAlgorithm.ecdsa: + return ClientCertificateType.ecdsa_sign; + default: + return -1; + } + } + + public static short GetLegacySignatureAlgorithmClient(short clientCertificateType) + { + switch (clientCertificateType) + { + case ClientCertificateType.dss_sign: + return SignatureAlgorithm.dsa; + case ClientCertificateType.ecdsa_sign: + return SignatureAlgorithm.ecdsa; + case ClientCertificateType.rsa_sign: + return SignatureAlgorithm.rsa; + default: + return -1; + } + } + + public static short GetLegacySignatureAlgorithmClientCert(short clientCertificateType) + { + switch (clientCertificateType) + { + case ClientCertificateType.dss_sign: + case ClientCertificateType.dss_fixed_dh: + return SignatureAlgorithm.dsa; + + case ClientCertificateType.ecdsa_sign: + case ClientCertificateType.ecdsa_fixed_ecdh: + return SignatureAlgorithm.ecdsa; + + case ClientCertificateType.rsa_sign: + case ClientCertificateType.rsa_fixed_dh: + case ClientCertificateType.rsa_fixed_ecdh: + return SignatureAlgorithm.rsa; + default: + return -1; + } + } + + public static short GetLegacySignatureAlgorithmServer(int keyExchangeAlgorithm) + { + switch (keyExchangeAlgorithm) + { + case KeyExchangeAlgorithm.DHE_DSS: + case KeyExchangeAlgorithm.SRP_DSS: + return SignatureAlgorithm.dsa; + + case KeyExchangeAlgorithm.ECDHE_ECDSA: + return SignatureAlgorithm.ecdsa; + + case KeyExchangeAlgorithm.DHE_RSA: + case KeyExchangeAlgorithm.ECDHE_RSA: + case KeyExchangeAlgorithm.SRP_RSA: + return SignatureAlgorithm.rsa; + + default: + return -1; + } + } + + public static short GetLegacySignatureAlgorithmServerCert(int keyExchangeAlgorithm) + { + switch (keyExchangeAlgorithm) + { + case KeyExchangeAlgorithm.DH_DSS: + case KeyExchangeAlgorithm.DHE_DSS: + case KeyExchangeAlgorithm.SRP_DSS: + return SignatureAlgorithm.dsa; + + case KeyExchangeAlgorithm.ECDH_ECDSA: + case KeyExchangeAlgorithm.ECDHE_ECDSA: + return SignatureAlgorithm.ecdsa; + + case KeyExchangeAlgorithm.DH_RSA: + case KeyExchangeAlgorithm.DHE_RSA: + case KeyExchangeAlgorithm.ECDH_RSA: + case KeyExchangeAlgorithm.ECDHE_RSA: + case KeyExchangeAlgorithm.RSA: + case KeyExchangeAlgorithm.RSA_PSK: + case KeyExchangeAlgorithm.SRP_RSA: + return SignatureAlgorithm.rsa; + + default: + return -1; + } + } + + public static IList GetLegacySupportedSignatureAlgorithms() + { + IList result = Platform.CreateArrayList(3); + result.Add(SignatureAndHashAlgorithm.GetInstance(HashAlgorithm.sha1, SignatureAlgorithm.dsa)); + result.Add(SignatureAndHashAlgorithm.GetInstance(HashAlgorithm.sha1, SignatureAlgorithm.ecdsa)); + result.Add(SignatureAndHashAlgorithm.GetInstance(HashAlgorithm.sha1, SignatureAlgorithm.rsa)); + return result; + } + + /// + public static void EncodeSupportedSignatureAlgorithms(IList supportedSignatureAlgorithms, Stream output) + { + if (supportedSignatureAlgorithms == null || supportedSignatureAlgorithms.Count < 1 + || supportedSignatureAlgorithms.Count >= (1 << 15)) + { + throw new ArgumentException("must have length from 1 to (2^15 - 1)", "supportedSignatureAlgorithms"); + } + + // supported_signature_algorithms + int length = 2 * supportedSignatureAlgorithms.Count; + CheckUint16(length); + WriteUint16(length, output); + foreach (SignatureAndHashAlgorithm entry in supportedSignatureAlgorithms) + { + if (entry.Signature == SignatureAlgorithm.anonymous) + { + /* + * RFC 5246 7.4.1.4.1 The "anonymous" value is meaningless in this context but used + * in Section 7.4.3. It MUST NOT appear in this extension. + */ + throw new ArgumentException( + "SignatureAlgorithm.anonymous MUST NOT appear in the signature_algorithms extension"); + } + entry.Encode(output); + } + } + + /// + public static IList ParseSupportedSignatureAlgorithms(Stream input) + { + // supported_signature_algorithms + int length = ReadUint16(input); + if (length < 2 || (length & 1) != 0) + throw new TlsFatalAlert(AlertDescription.decode_error); + + int count = length / 2; + IList supportedSignatureAlgorithms = Platform.CreateArrayList(count); + for (int i = 0; i < count; ++i) + { + SignatureAndHashAlgorithm sigAndHashAlg = SignatureAndHashAlgorithm.Parse(input); + + if (SignatureAlgorithm.anonymous != sigAndHashAlg.Signature) + { + supportedSignatureAlgorithms.Add(sigAndHashAlg); + } + } + return supportedSignatureAlgorithms; + } + + /// + public static void VerifySupportedSignatureAlgorithm(IList supportedSignatureAlgorithms, + SignatureAndHashAlgorithm signatureAlgorithm) + { + if (supportedSignatureAlgorithms == null || supportedSignatureAlgorithms.Count < 1 + || supportedSignatureAlgorithms.Count >= (1 << 15)) + { + throw new ArgumentException("must have length from 1 to (2^15 - 1)", "supportedSignatureAlgorithms"); + } + if (signatureAlgorithm == null) + throw new ArgumentNullException("signatureAlgorithm"); + + if (signatureAlgorithm.Signature == SignatureAlgorithm.anonymous + || !ContainsSignatureAlgorithm(supportedSignatureAlgorithms, signatureAlgorithm)) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + } + + /// + public static bool ContainsSignatureAlgorithm(IList supportedSignatureAlgorithms, + SignatureAndHashAlgorithm signatureAlgorithm) + { + foreach (SignatureAndHashAlgorithm entry in supportedSignatureAlgorithms) + { + if (entry.Equals(signatureAlgorithm)) + return true; + } + + return false; + } + + public static bool ContainsAnySignatureAlgorithm(IList supportedSignatureAlgorithms, short signatureAlgorithm) + { + foreach (SignatureAndHashAlgorithm entry in supportedSignatureAlgorithms) + { + if (entry.Signature == signatureAlgorithm) + return true; + } + + return false; + } + + public static TlsSecret Prf(SecurityParameters securityParameters, TlsSecret secret, string asciiLabel, + byte[] seed, int length) + { + return secret.DeriveUsingPrf(securityParameters.PrfAlgorithm, asciiLabel, seed, length); + } + + public static byte[] Clone(byte[] data) + { + return null == data ? null : data.Length == 0 ? EmptyBytes : (byte[])data.Clone(); + } + + public static string[] Clone(string[] s) + { + return null == s ? null : s.Length < 1 ? EmptyStrings : (string[])s.Clone(); + } + + public static bool ConstantTimeAreEqual(int len, byte[] a, int aOff, byte[] b, int bOff) + { + int d = 0; + for (int i = 0; i < len; ++i) + { + d |= a[aOff + i] ^ b[bOff + i]; + } + return 0 == d; + } + + public static byte[] CopyOfRangeExact(byte[] original, int from, int to) + { + int newLength = to - from; + byte[] copy = new byte[newLength]; + Array.Copy(original, from, copy, 0, newLength); + return copy; + } + + internal static byte[] Concat(byte[] a, byte[] b) + { + byte[] c = new byte[a.Length + b.Length]; + Array.Copy(a, 0, c, 0, a.Length); + Array.Copy(b, 0, c, a.Length, b.Length); + return c; + } + + /// + internal static byte[] CalculateEndPointHash(TlsContext context, TlsCertificate certificate, byte[] enc) + { + return CalculateEndPointHash(context, certificate, enc, 0, enc.Length); + } + + /// + internal static byte[] CalculateEndPointHash(TlsContext context, TlsCertificate certificate, byte[] enc, + int encOff, int encLen) + { + short hashAlgorithm = HashAlgorithm.none; + + string sigAlgOid = certificate.SigAlgOid; + if (sigAlgOid != null) + { + if (PkcsObjectIdentifiers.IdRsassaPss.Id.Equals(sigAlgOid)) + { + RsassaPssParameters pssParams = RsassaPssParameters.GetInstance(certificate.GetSigAlgParams()); + if (null != pssParams) + { + DerObjectIdentifier hashOid = pssParams.HashAlgorithm.Algorithm; + if (NistObjectIdentifiers.IdSha256.Equals(hashOid)) + { + hashAlgorithm = HashAlgorithm.sha256; + } + else if (NistObjectIdentifiers.IdSha384.Equals(hashOid)) + { + hashAlgorithm = HashAlgorithm.sha384; + } + else if (NistObjectIdentifiers.IdSha512.Equals(hashOid)) + { + hashAlgorithm = HashAlgorithm.sha512; + } + } + } + else + { + if (CertSigAlgOids.Contains(sigAlgOid)) + { + hashAlgorithm = ((SignatureAndHashAlgorithm)CertSigAlgOids[sigAlgOid]).Hash; + } + } + } + + switch (hashAlgorithm) + { + case HashAlgorithm.Intrinsic: + hashAlgorithm = HashAlgorithm.none; + break; + case HashAlgorithm.md5: + case HashAlgorithm.sha1: + hashAlgorithm = HashAlgorithm.sha256; + break; + } + + if (HashAlgorithm.none != hashAlgorithm) + { + TlsHash hash = CreateHash(context.Crypto, hashAlgorithm); + if (hash != null) + { + hash.Update(enc, encOff, encLen); + return hash.CalculateHash(); + } + } + + return EmptyBytes; + } + + public static byte[] CalculateExporterSeed(SecurityParameters securityParameters, byte[] context) + { + byte[] cr = securityParameters.ClientRandom, sr = securityParameters.ServerRandom; + if (null == context) + return Arrays.Concatenate(cr, sr); + + if (!IsValidUint16(context.Length)) + throw new ArgumentException("must have length less than 2^16 (or be null)", "context"); + + byte[] contextLength = new byte[2]; + WriteUint16(context.Length, contextLength, 0); + + return Arrays.ConcatenateAll(cr, sr, contextLength, context); + } + + private static byte[] CalculateFinishedHmac(SecurityParameters securityParameters, TlsSecret baseKey, + byte[] transcriptHash) + { + int prfCryptoHashAlgorithm = securityParameters.PrfCryptoHashAlgorithm; + int prfHashLength = securityParameters.PrfHashLength; + + return CalculateFinishedHmac(prfCryptoHashAlgorithm, prfHashLength, baseKey, transcriptHash); + } + + private static byte[] CalculateFinishedHmac(int prfCryptoHashAlgorithm, int prfHashLength, TlsSecret baseKey, + byte[] transcriptHash) + { + TlsSecret finishedKey = TlsCryptoUtilities.HkdfExpandLabel(baseKey, prfCryptoHashAlgorithm, "finished", + EmptyBytes, prfHashLength); + + try + { + return finishedKey.CalculateHmac(prfCryptoHashAlgorithm, transcriptHash, 0, transcriptHash.Length); + } + finally + { + finishedKey.Destroy(); + } + } + + internal static TlsSecret CalculateMasterSecret(TlsContext context, TlsSecret preMasterSecret) + { + SecurityParameters sp = context.SecurityParameters; + + string asciiLabel; + byte[] seed; + if (sp.IsExtendedMasterSecret) + { + asciiLabel = ExporterLabel.extended_master_secret; + seed = sp.SessionHash; + } + else + { + asciiLabel = ExporterLabel.master_secret; + seed = Concat(sp.ClientRandom, sp.ServerRandom); + } + + return Prf(sp, preMasterSecret, asciiLabel, seed, 48); + } + + internal static byte[] CalculatePskBinder(TlsCrypto crypto, bool isExternalPsk, int pskCryptoHashAlgorithm, + TlsSecret earlySecret, byte[] transcriptHash) + { + int prfHashLength = TlsCryptoUtilities.GetHashOutputSize(pskCryptoHashAlgorithm); + + string label = isExternalPsk ? "ext binder" : "res binder"; + byte[] emptyTranscriptHash = crypto.CreateHash(pskCryptoHashAlgorithm).CalculateHash(); + + TlsSecret binderKey = DeriveSecret(pskCryptoHashAlgorithm, prfHashLength, earlySecret, label, + emptyTranscriptHash); + + try + { + return CalculateFinishedHmac(pskCryptoHashAlgorithm, prfHashLength, binderKey, transcriptHash); + } + finally + { + binderKey.Destroy(); + } + } + + internal static byte[] CalculateVerifyData(TlsContext context, TlsHandshakeHash handshakeHash, bool isServer) + { + SecurityParameters securityParameters = context.SecurityParameters; + ProtocolVersion negotiatedVersion = securityParameters.NegotiatedVersion; + + if (IsTlsV13(negotiatedVersion)) + { + TlsSecret baseKey = isServer + ? securityParameters.BaseKeyServer + : securityParameters.BaseKeyClient; + byte[] transcriptHash = GetCurrentPrfHash(handshakeHash); + + return CalculateFinishedHmac(securityParameters, baseKey, transcriptHash); + } + + if (negotiatedVersion.IsSsl) + { + return Ssl3Utilities.CalculateVerifyData(handshakeHash, isServer); + } + + string asciiLabel = isServer ? ExporterLabel.server_finished : ExporterLabel.client_finished; + byte[] prfHash = GetCurrentPrfHash(handshakeHash); + + TlsSecret master_secret = securityParameters.MasterSecret; + int verify_data_length = securityParameters.VerifyDataLength; + + return Prf(securityParameters, master_secret, asciiLabel, prfHash, verify_data_length).Extract(); + } + + internal static void Establish13PhaseSecrets(TlsContext context, TlsSecret pskEarlySecret, + TlsSecret sharedSecret) + { + TlsCrypto crypto = context.Crypto; + SecurityParameters securityParameters = context.SecurityParameters; + int cryptoHashAlgorithm = securityParameters.PrfCryptoHashAlgorithm; + TlsSecret zeros = crypto.HkdfInit(cryptoHashAlgorithm); + byte[] emptyTranscriptHash = crypto.CreateHash(cryptoHashAlgorithm).CalculateHash(); + + TlsSecret earlySecret = pskEarlySecret; + if (null == earlySecret) + { + earlySecret = crypto + .HkdfInit(cryptoHashAlgorithm) + .HkdfExtract(cryptoHashAlgorithm, zeros); + } + + if (null == sharedSecret) + { + sharedSecret = zeros; + } + + TlsSecret handshakeSecret = DeriveSecret(securityParameters, earlySecret, "derived", emptyTranscriptHash) + .HkdfExtract(cryptoHashAlgorithm, sharedSecret); + + if (sharedSecret != zeros) + { + sharedSecret.Destroy(); + } + + TlsSecret masterSecret = DeriveSecret(securityParameters, handshakeSecret, "derived", emptyTranscriptHash) + .HkdfExtract(cryptoHashAlgorithm, zeros); + + securityParameters.m_earlySecret = earlySecret; + securityParameters.m_handshakeSecret = handshakeSecret; + securityParameters.m_masterSecret = masterSecret; + } + + private static void Establish13TrafficSecrets(TlsContext context, byte[] transcriptHash, TlsSecret phaseSecret, + string clientLabel, string serverLabel, RecordStream recordStream) + { + SecurityParameters securityParameters = context.SecurityParameters; + + securityParameters.m_trafficSecretClient = DeriveSecret(securityParameters, phaseSecret, clientLabel, + transcriptHash); + + if (null != serverLabel) + { + securityParameters.m_trafficSecretServer = DeriveSecret(securityParameters, phaseSecret, serverLabel, + transcriptHash); + } + + // TODO[tls13] Early data (client->server only) + + recordStream.SetPendingCipher(InitCipher(context)); + } + + internal static void Establish13PhaseApplication(TlsContext context, byte[] serverFinishedTranscriptHash, + RecordStream recordStream) + { + SecurityParameters securityParameters = context.SecurityParameters; + TlsSecret phaseSecret = securityParameters.MasterSecret; + + Establish13TrafficSecrets(context, serverFinishedTranscriptHash, phaseSecret, "c ap traffic", + "s ap traffic", recordStream); + + securityParameters.m_exporterMasterSecret = DeriveSecret(securityParameters, phaseSecret, "exp master", + serverFinishedTranscriptHash); + } + + internal static void Establish13PhaseEarly(TlsContext context, byte[] clientHelloTranscriptHash, + RecordStream recordStream) + { + SecurityParameters securityParameters = context.SecurityParameters; + TlsSecret phaseSecret = securityParameters.EarlySecret; + + // TODO[tls13] binder_key + + // TODO[tls13] Early data (client->server only) + if (null != recordStream) + { + Establish13TrafficSecrets(context, clientHelloTranscriptHash, phaseSecret, "c e traffic", null, + recordStream); + } + + securityParameters.m_earlyExporterMasterSecret = DeriveSecret(securityParameters, phaseSecret, + "e exp master", clientHelloTranscriptHash); + } + + internal static void Establish13PhaseHandshake(TlsContext context, byte[] serverHelloTranscriptHash, + RecordStream recordStream) + { + SecurityParameters securityParameters = context.SecurityParameters; + TlsSecret phaseSecret = securityParameters.HandshakeSecret; + + Establish13TrafficSecrets(context, serverHelloTranscriptHash, phaseSecret, "c hs traffic", "s hs traffic", + recordStream); + + securityParameters.m_baseKeyClient = securityParameters.TrafficSecretClient; + securityParameters.m_baseKeyServer = securityParameters.TrafficSecretServer; + } + + internal static void Update13TrafficSecretLocal(TlsContext context) + { + Update13TrafficSecret(context, context.IsServer); + } + + internal static void Update13TrafficSecretPeer(TlsContext context) + { + Update13TrafficSecret(context, !context.IsServer); + } + + private static void Update13TrafficSecret(TlsContext context, bool forServer) + { + SecurityParameters securityParameters = context.SecurityParameters; + + TlsSecret current; + if (forServer) + { + current = securityParameters.TrafficSecretServer; + securityParameters.m_trafficSecretServer = Update13TrafficSecret(securityParameters, current); + } + else + { + current = securityParameters.TrafficSecretClient; + securityParameters.m_trafficSecretClient = Update13TrafficSecret(securityParameters, current); + } + + if (null != current) + { + current.Destroy(); + } + } + + private static TlsSecret Update13TrafficSecret(SecurityParameters securityParameters, TlsSecret secret) + { + return TlsCryptoUtilities.HkdfExpandLabel(secret, securityParameters.PrfCryptoHashAlgorithm, "traffic upd", + EmptyBytes, securityParameters.PrfHashLength); + } + + public static DerObjectIdentifier GetOidForHashAlgorithm(short hashAlgorithm) + { + switch (hashAlgorithm) + { + case HashAlgorithm.md5: + return PkcsObjectIdentifiers.MD5; + case HashAlgorithm.sha1: + return X509ObjectIdentifiers.IdSha1; + case HashAlgorithm.sha224: + return NistObjectIdentifiers.IdSha224; + case HashAlgorithm.sha256: + return NistObjectIdentifiers.IdSha256; + case HashAlgorithm.sha384: + return NistObjectIdentifiers.IdSha384; + case HashAlgorithm.sha512: + return NistObjectIdentifiers.IdSha512; + // TODO[RFC 8998] + //case HashAlgorithm.sm3: + // return GMObjectIdentifiers.sm3; + default: + throw new ArgumentException("invalid HashAlgorithm: " + HashAlgorithm.GetText(hashAlgorithm)); + } + } + + internal static int GetPrfAlgorithm(SecurityParameters securityParameters, int cipherSuite) + { + ProtocolVersion negotiatedVersion = securityParameters.NegotiatedVersion; + + bool isTlsV13 = IsTlsV13(negotiatedVersion); + bool isTlsV12Exactly = !isTlsV13 && IsTlsV12(negotiatedVersion); + bool isSsl = negotiatedVersion.IsSsl; + + switch (cipherSuite) + { + case CipherSuite.TLS_AES_128_CCM_SHA256: + case CipherSuite.TLS_AES_128_CCM_8_SHA256: + case CipherSuite.TLS_AES_128_GCM_SHA256: + case CipherSuite.TLS_CHACHA20_POLY1305_SHA256: + { + if (isTlsV13) + return PrfAlgorithm.tls13_hkdf_sha256; + + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + case CipherSuite.TLS_AES_256_GCM_SHA384: + { + if (isTlsV13) + return PrfAlgorithm.tls13_hkdf_sha384; + + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + case CipherSuite.TLS_SM4_CCM_SM3: + case CipherSuite.TLS_SM4_GCM_SM3: + { + if (isTlsV13) + return PrfAlgorithm.tls13_hkdf_sm3; + + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + case CipherSuite.TLS_DH_anon_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DH_anon_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DH_anon_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DH_anon_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_anon_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CCM: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CCM: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM_8: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM_8: + case CipherSuite.TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CCM_8_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CCM_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_PSK_DHE_WITH_AES_128_CCM_8: + case CipherSuite.TLS_PSK_DHE_WITH_AES_256_CCM_8: + case CipherSuite.TLS_PSK_WITH_AES_128_CCM: + case CipherSuite.TLS_PSK_WITH_AES_128_CCM_8: + case CipherSuite.TLS_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_PSK_WITH_AES_256_CCM: + case CipherSuite.TLS_PSK_WITH_AES_256_CCM_8: + case CipherSuite.TLS_PSK_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_PSK_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_128_CCM: + case CipherSuite.TLS_RSA_WITH_AES_128_CCM_8: + case CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_256_CCM: + case CipherSuite.TLS_RSA_WITH_AES_256_CCM_8: + case CipherSuite.TLS_RSA_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_NULL_SHA256: + { + if (isTlsV12Exactly) + return PrfAlgorithm.tls_prf_sha256; + + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + case CipherSuite.TLS_DH_anon_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DH_anon_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_DH_anon_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DH_DSS_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DH_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_DSS_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_PSK_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_PSK_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_RSA_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_RSA_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384: + { + if (isTlsV12Exactly) + return PrfAlgorithm.tls_prf_sha384; + + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA384: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA384: + case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_PSK_WITH_NULL_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA384: + { + if (isTlsV13) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + if (isTlsV12Exactly) + return PrfAlgorithm.tls_prf_sha384; + + if (isSsl) + return PrfAlgorithm.ssl_prf_legacy; + + return PrfAlgorithm.tls_prf_legacy; + } + + default: + { + if (isTlsV13) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + if (isTlsV12Exactly) + return PrfAlgorithm.tls_prf_sha256; + + if (isSsl) + return PrfAlgorithm.ssl_prf_legacy; + + return PrfAlgorithm.tls_prf_legacy; + } + } + } + + internal static int GetPrfAlgorithm13(int cipherSuite) + { + // NOTE: GetPrfAlgorithms13 relies on the number of distinct return values + switch (cipherSuite) + { + case CipherSuite.TLS_AES_128_CCM_SHA256: + case CipherSuite.TLS_AES_128_CCM_8_SHA256: + case CipherSuite.TLS_AES_128_GCM_SHA256: + case CipherSuite.TLS_CHACHA20_POLY1305_SHA256: + return PrfAlgorithm.tls13_hkdf_sha256; + + case CipherSuite.TLS_AES_256_GCM_SHA384: + return PrfAlgorithm.tls13_hkdf_sha384; + + case CipherSuite.TLS_SM4_CCM_SM3: + case CipherSuite.TLS_SM4_GCM_SM3: + return PrfAlgorithm.tls13_hkdf_sm3; + + default: + return -1; + } + } + + internal static int[] GetPrfAlgorithms13(int[] cipherSuites) + { + int[] result = new int[System.Math.Min(3, cipherSuites.Length)]; + + int count = 0; + for (int i = 0; i < cipherSuites.Length; ++i) + { + int prfAlgorithm = GetPrfAlgorithm13(cipherSuites[i]); + if (prfAlgorithm >= 0 && !Arrays.Contains(result, prfAlgorithm)) + { + result[count++] = prfAlgorithm; + } + } + + return Truncate(result, count); + } + + internal static byte[] CalculateSignatureHash(TlsContext context, SignatureAndHashAlgorithm algorithm, + byte[] extraSignatureInput, DigestInputBuffer buf) + { + TlsCrypto crypto = context.Crypto; + + TlsHash h = algorithm == null + ? new CombinedHash(crypto) + : CreateHash(crypto, algorithm.Hash); + + SecurityParameters sp = context.SecurityParameters; + // NOTE: The implicit copy here is intended (and important) + byte[] randoms = Arrays.Concatenate(sp.ClientRandom, sp.ServerRandom); + h.Update(randoms, 0, randoms.Length); + + if (null != extraSignatureInput) + { + h.Update(extraSignatureInput, 0, extraSignatureInput.Length); + } + + buf.UpdateDigest(h); + + return h.CalculateHash(); + } + + internal static void SendSignatureInput(TlsContext context, byte[] extraSignatureInput, DigestInputBuffer buf, + Stream output) + { + SecurityParameters sp = context.SecurityParameters; + // NOTE: The implicit copy here is intended (and important) + byte[] randoms = Arrays.Concatenate(sp.ClientRandom, sp.ServerRandom); + output.Write(randoms, 0, randoms.Length); + + if (null != extraSignatureInput) + { + output.Write(extraSignatureInput, 0, extraSignatureInput.Length); + } + + buf.CopyTo(output); + + Platform.Dispose(output); + } + + internal static DigitallySigned GenerateCertificateVerifyClient(TlsClientContext clientContext, + TlsCredentialedSigner credentialedSigner, TlsStreamSigner streamSigner, TlsHandshakeHash handshakeHash) + { + SecurityParameters securityParameters = clientContext.SecurityParameters; + ProtocolVersion negotiatedVersion = securityParameters.NegotiatedVersion; + + if (IsTlsV13(negotiatedVersion)) + { + // Should be using GenerateCertificateVerify13 instead + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + /* + * RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm from TLS 1.2 + */ + SignatureAndHashAlgorithm signatureAndHashAlgorithm = GetSignatureAndHashAlgorithm(negotiatedVersion, + credentialedSigner); + + byte[] signature; + if (streamSigner != null) + { + handshakeHash.CopyBufferTo(streamSigner.GetOutputStream()); + signature = streamSigner.GetSignature(); + } + else + { + byte[] hash; + if (signatureAndHashAlgorithm == null) + { + hash = securityParameters.SessionHash; + } + else + { + int signatureScheme = SignatureScheme.From(signatureAndHashAlgorithm); + int cryptoHashAlgorithm = SignatureScheme.GetCryptoHashAlgorithm(signatureScheme); + + hash = handshakeHash.GetFinalHash(cryptoHashAlgorithm); + } + + signature = credentialedSigner.GenerateRawSignature(hash); + } + + return new DigitallySigned(signatureAndHashAlgorithm, signature); + } + + internal static DigitallySigned Generate13CertificateVerify(TlsContext context, + TlsCredentialedSigner credentialedSigner, TlsHandshakeHash handshakeHash) + { + SignatureAndHashAlgorithm signatureAndHashAlgorithm = credentialedSigner.SignatureAndHashAlgorithm; + if (null == signatureAndHashAlgorithm) + throw new TlsFatalAlert(AlertDescription.internal_error); + + string contextString = context.IsServer + ? "TLS 1.3, server CertificateVerify" + : "TLS 1.3, client CertificateVerify"; + + byte[] signature = Generate13CertificateVerify(context.Crypto, credentialedSigner, contextString, + handshakeHash, signatureAndHashAlgorithm); + + return new DigitallySigned(signatureAndHashAlgorithm, signature); + } + + private static byte[] Generate13CertificateVerify(TlsCrypto crypto, TlsCredentialedSigner credentialedSigner, + string contextString, TlsHandshakeHash handshakeHash, SignatureAndHashAlgorithm signatureAndHashAlgorithm) + { + TlsStreamSigner streamSigner = credentialedSigner.GetStreamSigner(); + + byte[] header = GetCertificateVerifyHeader(contextString); + byte[] prfHash = GetCurrentPrfHash(handshakeHash); + + if (null != streamSigner) + { + Stream output = streamSigner.GetOutputStream(); + output.Write(header, 0, header.Length); + output.Write(prfHash, 0, prfHash.Length); + return streamSigner.GetSignature(); + } + + int signatureScheme = SignatureScheme.From(signatureAndHashAlgorithm); + int cryptoHashAlgorithm = SignatureScheme.GetCryptoHashAlgorithm(signatureScheme); + + TlsHash tlsHash = crypto.CreateHash(cryptoHashAlgorithm); + tlsHash.Update(header, 0, header.Length); + tlsHash.Update(prfHash, 0, prfHash.Length); + byte[] hash = tlsHash.CalculateHash(); + return credentialedSigner.GenerateRawSignature(hash); + } + + internal static void VerifyCertificateVerifyClient(TlsServerContext serverContext, + CertificateRequest certificateRequest, DigitallySigned certificateVerify, TlsHandshakeHash handshakeHash) + { + SecurityParameters securityParameters = serverContext.SecurityParameters; + Certificate clientCertificate = securityParameters.PeerCertificate; + TlsCertificate verifyingCert = clientCertificate.GetCertificateAt(0); + SignatureAndHashAlgorithm sigAndHashAlg = certificateVerify.Algorithm; + short signatureAlgorithm; + + if (null == sigAndHashAlg) + { + signatureAlgorithm = verifyingCert.GetLegacySignatureAlgorithm(); + + short clientCertType = GetLegacyClientCertType(signatureAlgorithm); + if (clientCertType < 0 || !Arrays.Contains(certificateRequest.CertificateTypes, clientCertType)) + throw new TlsFatalAlert(AlertDescription.unsupported_certificate); + } + else + { + signatureAlgorithm = sigAndHashAlg.Signature; + + // TODO Is it possible (maybe only pre-1.2 to check this immediately when the Certificate arrives? + if (!IsValidSignatureAlgorithmForCertificateVerify(signatureAlgorithm, + certificateRequest.CertificateTypes)) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + VerifySupportedSignatureAlgorithm(securityParameters.ServerSigAlgs, sigAndHashAlg); + } + + // Verify the CertificateVerify message contains a correct signature. + bool verified; + try + { + TlsVerifier verifier = verifyingCert.CreateVerifier(signatureAlgorithm); + TlsStreamVerifier streamVerifier = verifier.GetStreamVerifier(certificateVerify); + + if (streamVerifier != null) + { + handshakeHash.CopyBufferTo(streamVerifier.GetOutputStream()); + verified = streamVerifier.IsVerified(); + } + else + { + byte[] hash; + if (IsTlsV12(serverContext)) + { + int signatureScheme = SignatureScheme.From(sigAndHashAlg); + int cryptoHashAlgorithm = SignatureScheme.GetCryptoHashAlgorithm(signatureScheme); + + hash = handshakeHash.GetFinalHash(cryptoHashAlgorithm); + } + else + { + hash = securityParameters.SessionHash; + } + + verified = verifier.VerifyRawSignature(certificateVerify, hash); + } + } + catch (TlsFatalAlert e) + { + throw e; + } + catch (Exception e) + { + throw new TlsFatalAlert(AlertDescription.decrypt_error, e); + } + + if (!verified) + { + throw new TlsFatalAlert(AlertDescription.decrypt_error); + } + } + + internal static void Verify13CertificateVerifyClient(TlsServerContext serverContext, + CertificateRequest certificateRequest, DigitallySigned certificateVerify, TlsHandshakeHash handshakeHash) + { + SecurityParameters securityParameters = serverContext.SecurityParameters; + Certificate clientCertificate = securityParameters.PeerCertificate; + TlsCertificate verifyingCert = clientCertificate.GetCertificateAt(0); + + SignatureAndHashAlgorithm sigAndHashAlg = certificateVerify.Algorithm; + VerifySupportedSignatureAlgorithm(securityParameters.ServerSigAlgs, sigAndHashAlg); + + int signatureScheme = SignatureScheme.From(sigAndHashAlg); + + // Verify the CertificateVerify message contains a correct signature. + bool verified; + try + { + TlsVerifier verifier = verifyingCert.CreateVerifier(signatureScheme); + + verified = Verify13CertificateVerify(serverContext.Crypto, certificateVerify, verifier, + "TLS 1.3, client CertificateVerify", handshakeHash); + } + catch (TlsFatalAlert e) + { + throw e; + } + catch (Exception e) + { + throw new TlsFatalAlert(AlertDescription.decrypt_error, e); + } + + if (!verified) + { + throw new TlsFatalAlert(AlertDescription.decrypt_error); + } + } + + internal static void Verify13CertificateVerifyServer(TlsClientContext clientContext, + DigitallySigned certificateVerify, TlsHandshakeHash handshakeHash) + { + SecurityParameters securityParameters = clientContext.SecurityParameters; + Certificate serverCertificate = securityParameters.PeerCertificate; + TlsCertificate verifyingCert = serverCertificate.GetCertificateAt(0); + + SignatureAndHashAlgorithm sigAndHashAlg = certificateVerify.Algorithm; + VerifySupportedSignatureAlgorithm(securityParameters.ClientSigAlgs, sigAndHashAlg); + + int signatureScheme = SignatureScheme.From(sigAndHashAlg); + + // Verify the CertificateVerify message contains a correct signature. + bool verified; + try + { + TlsVerifier verifier = verifyingCert.CreateVerifier(signatureScheme); + + verified = Verify13CertificateVerify(clientContext.Crypto, certificateVerify, verifier, + "TLS 1.3, server CertificateVerify", handshakeHash); + } + catch (TlsFatalAlert e) + { + throw e; + } + catch (Exception e) + { + throw new TlsFatalAlert(AlertDescription.decrypt_error, e); + } + + if (!verified) + { + throw new TlsFatalAlert(AlertDescription.decrypt_error); + } + } + + private static bool Verify13CertificateVerify(TlsCrypto crypto, DigitallySigned certificateVerify, + TlsVerifier verifier, string contextString, TlsHandshakeHash handshakeHash) + { + TlsStreamVerifier streamVerifier = verifier.GetStreamVerifier(certificateVerify); + + byte[] header = GetCertificateVerifyHeader(contextString); + byte[] prfHash = GetCurrentPrfHash(handshakeHash); + + if (null != streamVerifier) + { + Stream output = streamVerifier.GetOutputStream(); + output.Write(header, 0, header.Length); + output.Write(prfHash, 0, prfHash.Length); + return streamVerifier.IsVerified(); + } + + int signatureScheme = SignatureScheme.From(certificateVerify.Algorithm); + int cryptoHashAlgorithm = SignatureScheme.GetCryptoHashAlgorithm(signatureScheme); + + TlsHash tlsHash = crypto.CreateHash(cryptoHashAlgorithm); + tlsHash.Update(header, 0, header.Length); + tlsHash.Update(prfHash, 0, prfHash.Length); + byte[] hash = tlsHash.CalculateHash(); + return verifier.VerifyRawSignature(certificateVerify, hash); + } + + private static byte[] GetCertificateVerifyHeader(string contextString) + { + int count = contextString.Length; + byte[] header = new byte[64 + count + 1]; + for (int i = 0; i < 64; ++i) + { + header[i] = 0x20; + } + for (int i = 0; i < count; ++i) + { + char c = contextString[i]; + header[64 + i] = (byte)c; + } + header[64 + count] = 0x00; + return header; + } + + /// + internal static void GenerateServerKeyExchangeSignature(TlsContext context, TlsCredentialedSigner credentials, + byte[] extraSignatureInput, DigestInputBuffer digestBuffer) + { + /* + * RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm from TLS 1.2 + */ + SignatureAndHashAlgorithm algorithm = GetSignatureAndHashAlgorithm(context, credentials); + TlsStreamSigner streamSigner = credentials.GetStreamSigner(); + + byte[] signature; + if (streamSigner != null) + { + SendSignatureInput(context, extraSignatureInput, digestBuffer, streamSigner.GetOutputStream()); + signature = streamSigner.GetSignature(); + } + else + { + byte[] hash = CalculateSignatureHash(context, algorithm, extraSignatureInput, digestBuffer); + signature = credentials.GenerateRawSignature(hash); + } + + DigitallySigned digitallySigned = new DigitallySigned(algorithm, signature); + + digitallySigned.Encode(digestBuffer); + } + + /// + internal static void VerifyServerKeyExchangeSignature(TlsContext context, Stream signatureInput, + TlsCertificate serverCertificate, byte[] extraSignatureInput, DigestInputBuffer digestBuffer) + { + DigitallySigned digitallySigned = DigitallySigned.Parse(context, signatureInput); + + SecurityParameters securityParameters = context.SecurityParameters; + int keyExchangeAlgorithm = securityParameters.KeyExchangeAlgorithm; + + SignatureAndHashAlgorithm sigAndHashAlg = digitallySigned.Algorithm; + short signatureAlgorithm; + + if (sigAndHashAlg == null) + { + signatureAlgorithm = GetLegacySignatureAlgorithmServer(keyExchangeAlgorithm); + } + else + { + signatureAlgorithm = sigAndHashAlg.Signature; + + if (!IsValidSignatureAlgorithmForServerKeyExchange(signatureAlgorithm, keyExchangeAlgorithm)) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + VerifySupportedSignatureAlgorithm(securityParameters.ClientSigAlgs, sigAndHashAlg); + } + + TlsVerifier verifier = serverCertificate.CreateVerifier(signatureAlgorithm); + TlsStreamVerifier streamVerifier = verifier.GetStreamVerifier(digitallySigned); + + bool verified; + if (streamVerifier != null) + { + SendSignatureInput(context, null, digestBuffer, streamVerifier.GetOutputStream()); + verified = streamVerifier.IsVerified(); + } + else + { + byte[] hash = CalculateSignatureHash(context, sigAndHashAlg, null, digestBuffer); + verified = verifier.VerifyRawSignature(digitallySigned, hash); + } + + if (!verified) + { + throw new TlsFatalAlert(AlertDescription.decrypt_error); + } + } + + internal static void TrackHashAlgorithms(TlsHandshakeHash handshakeHash, IList supportedSignatureAlgorithms) + { + if (supportedSignatureAlgorithms != null) + { + foreach (SignatureAndHashAlgorithm signatureAndHashAlgorithm in supportedSignatureAlgorithms) + { + /* + * TODO We could validate the signature algorithm part. Currently the impact is + * that we might be tracking extra hashes pointlessly (but there are only a + * limited number of recognized hash algorithms). + */ + int signatureScheme = SignatureScheme.From(signatureAndHashAlgorithm); + int cryptoHashAlgorithm = SignatureScheme.GetCryptoHashAlgorithm(signatureScheme); + + if (cryptoHashAlgorithm >= 0) + { + handshakeHash.TrackHashAlgorithm(cryptoHashAlgorithm); + } + else if (HashAlgorithm.Intrinsic == signatureAndHashAlgorithm.Hash) + { + handshakeHash.ForceBuffering(); + } + } + } + } + + public static bool HasSigningCapability(short clientCertificateType) + { + switch (clientCertificateType) + { + case ClientCertificateType.dss_sign: + case ClientCertificateType.ecdsa_sign: + case ClientCertificateType.rsa_sign: + return true; + default: + return false; + } + } + + public static IList VectorOfOne(object obj) + { + IList v = Platform.CreateArrayList(1); + v.Add(obj); + return v; + } + + public static int GetCipherType(int cipherSuite) + { + int encryptionAlgorithm = GetEncryptionAlgorithm(cipherSuite); + + return GetEncryptionAlgorithmType(encryptionAlgorithm); + } + + public static int GetEncryptionAlgorithm(int cipherSuite) + { + switch (cipherSuite) + { + case CipherSuite.TLS_DH_anon_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_PSK_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA: + return EncryptionAlgorithm.cls_3DES_EDE_CBC; + + case CipherSuite.TLS_DH_anon_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DH_anon_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_anon_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_WITH_AES_128_CBC_SHA: + return EncryptionAlgorithm.AES_128_CBC; + + case CipherSuite.TLS_AES_128_CCM_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CCM: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CCM_SHA256: + case CipherSuite.TLS_PSK_WITH_AES_128_CCM: + case CipherSuite.TLS_RSA_WITH_AES_128_CCM: + return EncryptionAlgorithm.AES_128_CCM; + + case CipherSuite.TLS_AES_128_CCM_8_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM_8: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CCM_8_SHA256: + case CipherSuite.TLS_PSK_DHE_WITH_AES_128_CCM_8: + case CipherSuite.TLS_PSK_WITH_AES_128_CCM_8: + case CipherSuite.TLS_RSA_WITH_AES_128_CCM_8: + return EncryptionAlgorithm.AES_128_CCM_8; + + case CipherSuite.TLS_AES_128_GCM_SHA256: + case CipherSuite.TLS_DH_anon_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256: + return EncryptionAlgorithm.AES_128_GCM; + + case CipherSuite.TLS_DH_anon_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DH_anon_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_ECDH_anon_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_WITH_AES_256_CBC_SHA: + return EncryptionAlgorithm.AES_256_CBC; + + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CCM: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM: + case CipherSuite.TLS_PSK_WITH_AES_256_CCM: + case CipherSuite.TLS_RSA_WITH_AES_256_CCM: + return EncryptionAlgorithm.AES_256_CCM; + + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM_8: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8: + case CipherSuite.TLS_PSK_DHE_WITH_AES_256_CCM_8: + case CipherSuite.TLS_PSK_WITH_AES_256_CCM_8: + case CipherSuite.TLS_RSA_WITH_AES_256_CCM_8: + return EncryptionAlgorithm.AES_256_CCM_8; + + case CipherSuite.TLS_AES_256_GCM_SHA384: + case CipherSuite.TLS_DH_anon_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DH_DSS_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DH_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DHE_DSS_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384: + return EncryptionAlgorithm.AES_256_GCM; + + case CipherSuite.TLS_DH_anon_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_PSK_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256: + return EncryptionAlgorithm.ARIA_128_CBC; + + case CipherSuite.TLS_DH_anon_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_PSK_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_RSA_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256: + return EncryptionAlgorithm.ARIA_128_GCM; + + case CipherSuite.TLS_DH_anon_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_PSK_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_RSA_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384: + return EncryptionAlgorithm.ARIA_256_CBC; + + case CipherSuite.TLS_DH_anon_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_PSK_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_RSA_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384: + return EncryptionAlgorithm.ARIA_256_GCM; + + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256: + return EncryptionAlgorithm.CAMELLIA_128_CBC; + + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256: + return EncryptionAlgorithm.CAMELLIA_128_GCM; + + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384: + return EncryptionAlgorithm.CAMELLIA_256_CBC; + + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384: + return EncryptionAlgorithm.CAMELLIA_256_GCM; + + case CipherSuite.TLS_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256: + return EncryptionAlgorithm.CHACHA20_POLY1305; + + case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA: + case CipherSuite.TLS_ECDH_anon_WITH_NULL_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_NULL_SHA: + case CipherSuite.TLS_ECDH_RSA_WITH_NULL_SHA: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_NULL_SHA: + case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA: + case CipherSuite.TLS_ECDHE_RSA_WITH_NULL_SHA: + case CipherSuite.TLS_PSK_WITH_NULL_SHA: + case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA: + case CipherSuite.TLS_RSA_WITH_NULL_SHA: + return EncryptionAlgorithm.NULL; + + case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA256: + case CipherSuite.TLS_PSK_WITH_NULL_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA256: + case CipherSuite.TLS_RSA_WITH_NULL_SHA256: + return EncryptionAlgorithm.NULL; + + case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA384: + case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA384: + case CipherSuite.TLS_PSK_WITH_NULL_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA384: + return EncryptionAlgorithm.NULL; + + case CipherSuite.TLS_DH_anon_WITH_SEED_CBC_SHA: + case CipherSuite.TLS_DH_DSS_WITH_SEED_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_SEED_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_SEED_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_SEED_CBC_SHA: + case CipherSuite.TLS_RSA_WITH_SEED_CBC_SHA: + return EncryptionAlgorithm.SEED_CBC; + + case CipherSuite.TLS_SM4_CCM_SM3: + return EncryptionAlgorithm.SM4_CCM; + + case CipherSuite.TLS_SM4_GCM_SM3: + return EncryptionAlgorithm.SM4_GCM; + + default: + return -1; + } + } + + public static int GetEncryptionAlgorithmType(int encryptionAlgorithm) + { + switch (encryptionAlgorithm) + { + case EncryptionAlgorithm.AES_128_CCM: + case EncryptionAlgorithm.AES_128_CCM_8: + case EncryptionAlgorithm.AES_128_GCM: + case EncryptionAlgorithm.AES_256_CCM: + case EncryptionAlgorithm.AES_256_CCM_8: + case EncryptionAlgorithm.AES_256_GCM: + case EncryptionAlgorithm.ARIA_128_GCM: + case EncryptionAlgorithm.ARIA_256_GCM: + case EncryptionAlgorithm.CAMELLIA_128_GCM: + case EncryptionAlgorithm.CAMELLIA_256_GCM: + case EncryptionAlgorithm.CHACHA20_POLY1305: + case EncryptionAlgorithm.SM4_CCM: + case EncryptionAlgorithm.SM4_GCM: + return CipherType.aead; + + case EncryptionAlgorithm.RC2_CBC_40: + case EncryptionAlgorithm.IDEA_CBC: + case EncryptionAlgorithm.DES40_CBC: + case EncryptionAlgorithm.DES_CBC: + case EncryptionAlgorithm.cls_3DES_EDE_CBC: + case EncryptionAlgorithm.AES_128_CBC: + case EncryptionAlgorithm.AES_256_CBC: + case EncryptionAlgorithm.ARIA_128_CBC: + case EncryptionAlgorithm.ARIA_256_CBC: + case EncryptionAlgorithm.CAMELLIA_128_CBC: + case EncryptionAlgorithm.CAMELLIA_256_CBC: + case EncryptionAlgorithm.SEED_CBC: + case EncryptionAlgorithm.SM4_CBC: + return CipherType.block; + + case EncryptionAlgorithm.NULL: + case EncryptionAlgorithm.RC4_40: + case EncryptionAlgorithm.RC4_128: + return CipherType.stream; + + default: + return -1; + } + } + + public static int GetKeyExchangeAlgorithm(int cipherSuite) + { + switch (cipherSuite) + { + case CipherSuite.TLS_DH_anon_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DH_anon_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DH_anon_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DH_anon_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DH_anon_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DH_anon_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DH_anon_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DH_anon_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_anon_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_anon_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_DH_anon_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DH_anon_WITH_SEED_CBC_SHA: + return KeyExchangeAlgorithm.DH_anon; + + case CipherSuite.TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DH_DSS_WITH_SEED_CBC_SHA: + return KeyExchangeAlgorithm.DH_DSS; + + case CipherSuite.TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DH_RSA_WITH_SEED_CBC_SHA: + return KeyExchangeAlgorithm.DH_RSA; + + case CipherSuite.TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_DSS_WITH_SEED_CBC_SHA: + return KeyExchangeAlgorithm.DHE_DSS; + + case CipherSuite.TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CCM: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CCM: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA: + case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA384: + case CipherSuite.TLS_PSK_DHE_WITH_AES_128_CCM_8: + case CipherSuite.TLS_PSK_DHE_WITH_AES_256_CCM_8: + return KeyExchangeAlgorithm.DHE_PSK; + + case CipherSuite.TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM_8: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM_8: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_SEED_CBC_SHA: + return KeyExchangeAlgorithm.DHE_RSA; + + case CipherSuite.TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDH_anon_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDH_anon_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDH_anon_WITH_NULL_SHA: + return KeyExchangeAlgorithm.ECDH_anon; + + case CipherSuite.TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_NULL_SHA: + return KeyExchangeAlgorithm.ECDH_ECDSA; + + case CipherSuite.TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_NULL_SHA: + return KeyExchangeAlgorithm.ECDH_RSA; + + case CipherSuite.TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_NULL_SHA: + return KeyExchangeAlgorithm.ECDHE_ECDSA; + + case CipherSuite.TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CCM_8_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CCM_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA: + case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA384: + return KeyExchangeAlgorithm.ECDHE_PSK; + + case CipherSuite.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_NULL_SHA: + return KeyExchangeAlgorithm.ECDHE_RSA; + + case CipherSuite.TLS_AES_128_CCM_8_SHA256: + case CipherSuite.TLS_AES_128_CCM_SHA256: + case CipherSuite.TLS_AES_128_GCM_SHA256: + case CipherSuite.TLS_AES_256_GCM_SHA384: + case CipherSuite.TLS_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_SM4_CCM_SM3: + case CipherSuite.TLS_SM4_GCM_SM3: + return KeyExchangeAlgorithm.NULL; + + case CipherSuite.TLS_PSK_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_PSK_WITH_AES_128_CCM: + case CipherSuite.TLS_PSK_WITH_AES_128_CCM_8: + case CipherSuite.TLS_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_PSK_WITH_AES_256_CCM: + case CipherSuite.TLS_PSK_WITH_AES_256_CCM_8: + case CipherSuite.TLS_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_PSK_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_PSK_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_PSK_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_PSK_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_PSK_WITH_NULL_SHA: + case CipherSuite.TLS_PSK_WITH_NULL_SHA256: + case CipherSuite.TLS_PSK_WITH_NULL_SHA384: + return KeyExchangeAlgorithm.PSK; + + case CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_128_CCM: + case CipherSuite.TLS_RSA_WITH_AES_128_CCM_8: + case CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_256_CCM: + case CipherSuite.TLS_RSA_WITH_AES_256_CCM_8: + case CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_RSA_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_RSA_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_RSA_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_RSA_WITH_NULL_SHA: + case CipherSuite.TLS_RSA_WITH_NULL_SHA256: + case CipherSuite.TLS_RSA_WITH_SEED_CBC_SHA: + return KeyExchangeAlgorithm.RSA; + + case CipherSuite.TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA: + case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA384: + return KeyExchangeAlgorithm.RSA_PSK; + + case CipherSuite.TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_WITH_AES_256_CBC_SHA: + return KeyExchangeAlgorithm.SRP; + + case CipherSuite.TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA: + return KeyExchangeAlgorithm.SRP_DSS; + + case CipherSuite.TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA: + return KeyExchangeAlgorithm.SRP_RSA; + + default: + return -1; + } + } + + public static IList GetKeyExchangeAlgorithms(int[] cipherSuites) + { + IList result = Platform.CreateArrayList(); + if (null != cipherSuites) + { + for (int i = 0; i < cipherSuites.Length; ++i) + { + AddToSet(result, GetKeyExchangeAlgorithm(cipherSuites[i])); + } + result.Remove(-1); + } + return result; + } + + public static int GetMacAlgorithm(int cipherSuite) + { + switch (cipherSuite) + { + case CipherSuite.TLS_AES_128_CCM_SHA256: + case CipherSuite.TLS_AES_128_CCM_8_SHA256: + case CipherSuite.TLS_AES_128_GCM_SHA256: + case CipherSuite.TLS_AES_256_GCM_SHA384: + case CipherSuite.TLS_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_DH_anon_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DH_anon_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DH_anon_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_anon_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DH_DSS_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DH_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CCM: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CCM: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM_8: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM_8: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CCM_8_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CCM_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_PSK_DHE_WITH_AES_128_CCM_8: + case CipherSuite.TLS_PSK_DHE_WITH_AES_256_CCM_8: + case CipherSuite.TLS_PSK_WITH_AES_128_CCM: + case CipherSuite.TLS_PSK_WITH_AES_128_CCM_8: + case CipherSuite.TLS_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_PSK_WITH_AES_256_CCM: + case CipherSuite.TLS_PSK_WITH_AES_256_CCM_8: + case CipherSuite.TLS_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_PSK_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_PSK_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_128_CCM: + case CipherSuite.TLS_RSA_WITH_AES_128_CCM_8: + case CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_256_CCM: + case CipherSuite.TLS_RSA_WITH_AES_256_CCM_8: + case CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_RSA_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_RSA_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_SM4_CCM_SM3: + case CipherSuite.TLS_SM4_GCM_SM3: + return MacAlgorithm.cls_null; + + case CipherSuite.TLS_DH_anon_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DH_anon_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DH_anon_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_DH_anon_WITH_SEED_CBC_SHA: + case CipherSuite.TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_DH_DSS_WITH_SEED_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_DH_RSA_WITH_SEED_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_DHE_DSS_WITH_SEED_CBC_SHA: + case CipherSuite.TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_DHE_RSA_WITH_SEED_CBC_SHA: + case CipherSuite.TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDH_anon_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDH_anon_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDH_anon_WITH_NULL_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDH_ECDSA_WITH_NULL_SHA: + case CipherSuite.TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDH_RSA_WITH_NULL_SHA: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_NULL_SHA: + case CipherSuite.TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA: + case CipherSuite.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_ECDHE_RSA_WITH_NULL_SHA: + case CipherSuite.TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_PSK_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_PSK_WITH_NULL_SHA: + case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA: + case CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA: + case CipherSuite.TLS_RSA_WITH_NULL_SHA: + case CipherSuite.TLS_RSA_WITH_SEED_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_WITH_AES_128_CBC_SHA: + case CipherSuite.TLS_SRP_SHA_WITH_AES_256_CBC_SHA: + return MacAlgorithm.hmac_sha1; + + case CipherSuite.TLS_DH_anon_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DH_anon_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DH_anon_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_PSK_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_PSK_WITH_NULL_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_NULL_SHA256: + return MacAlgorithm.hmac_sha256; + + case CipherSuite.TLS_DH_anon_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA384: + case CipherSuite.TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_PSK_WITH_NULL_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_PSK_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_PSK_WITH_NULL_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_NULL_SHA384: + case CipherSuite.TLS_RSA_WITH_ARIA_256_CBC_SHA384: + return MacAlgorithm.hmac_sha384; + + default: + return -1; + } + } + + public static ProtocolVersion GetMinimumVersion(int cipherSuite) + { + switch (cipherSuite) + { + case CipherSuite.TLS_AES_128_CCM_SHA256: + case CipherSuite.TLS_AES_128_CCM_8_SHA256: + case CipherSuite.TLS_AES_128_GCM_SHA256: + case CipherSuite.TLS_AES_256_GCM_SHA384: + case CipherSuite.TLS_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_SM4_CCM_SM3: + case CipherSuite.TLS_SM4_GCM_SM3: + return ProtocolVersion.TLSv13; + + case CipherSuite.TLS_DH_anon_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DH_anon_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DH_anon_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DH_anon_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DH_anon_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_anon_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_anon_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_DH_anon_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_CCM: + case CipherSuite.TLS_DHE_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_CCM: + case CipherSuite.TLS_DHE_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_CCM_8: + case CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_CCM_8: + case CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CCM_8_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CCM_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_PSK_DHE_WITH_AES_128_CCM_8: + case CipherSuite.TLS_PSK_DHE_WITH_AES_256_CCM_8: + case CipherSuite.TLS_PSK_WITH_AES_128_CCM: + case CipherSuite.TLS_PSK_WITH_AES_128_CCM_8: + case CipherSuite.TLS_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_PSK_WITH_AES_256_CCM: + case CipherSuite.TLS_PSK_WITH_AES_256_CCM_8: + case CipherSuite.TLS_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_PSK_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_PSK_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_PSK_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_PSK_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_128_CCM: + case CipherSuite.TLS_RSA_WITH_AES_128_CCM_8: + case CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_AES_256_CCM: + case CipherSuite.TLS_RSA_WITH_AES_256_CCM_8: + case CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384: + case CipherSuite.TLS_RSA_WITH_ARIA_128_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_ARIA_128_GCM_SHA256: + case CipherSuite.TLS_RSA_WITH_ARIA_256_CBC_SHA384: + case CipherSuite.TLS_RSA_WITH_ARIA_256_GCM_SHA384: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256: + case CipherSuite.TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384: + case CipherSuite.TLS_RSA_WITH_NULL_SHA256: + return ProtocolVersion.TLSv12; + + default: + return ProtocolVersion.SSLv3; + } + } + + public static IList GetNamedGroupRoles(int[] cipherSuites) + { + return GetNamedGroupRoles(GetKeyExchangeAlgorithms(cipherSuites)); + } + + public static IList GetNamedGroupRoles(IList keyExchangeAlgorithms) + { + IList result = Platform.CreateArrayList(); + foreach (int keyExchangeAlgorithm in keyExchangeAlgorithms) + { + switch (keyExchangeAlgorithm) + { + case KeyExchangeAlgorithm.DH_anon: + case KeyExchangeAlgorithm.DH_DSS: + case KeyExchangeAlgorithm.DH_RSA: + case KeyExchangeAlgorithm.DHE_DSS: + case KeyExchangeAlgorithm.DHE_PSK: + case KeyExchangeAlgorithm.DHE_RSA: + { + AddToSet(result, NamedGroupRole.dh); + break; + } + + case KeyExchangeAlgorithm.ECDH_anon: + case KeyExchangeAlgorithm.ECDH_RSA: + case KeyExchangeAlgorithm.ECDHE_PSK: + case KeyExchangeAlgorithm.ECDHE_RSA: + { + AddToSet(result, NamedGroupRole.ecdh); + break; + } + + case KeyExchangeAlgorithm.ECDH_ECDSA: + case KeyExchangeAlgorithm.ECDHE_ECDSA: + { + AddToSet(result, NamedGroupRole.ecdh); + AddToSet(result, NamedGroupRole.ecdsa); + break; + } + + case KeyExchangeAlgorithm.NULL: + { + // TODO[tls13] We're conservatively adding both here, though maybe only one is needed + AddToSet(result, NamedGroupRole.dh); + AddToSet(result, NamedGroupRole.ecdh); + break; + } + } + } + return result; + } + + /// + public static bool IsAeadCipherSuite(int cipherSuite) + { + return CipherType.aead == GetCipherType(cipherSuite); + } + + /// + public static bool IsBlockCipherSuite(int cipherSuite) + { + return CipherType.block == GetCipherType(cipherSuite); + } + + /// + public static bool IsStreamCipherSuite(int cipherSuite) + { + return CipherType.stream == GetCipherType(cipherSuite); + } + + /// Whether a server can select the specified cipher suite given the available signature algorithms + /// for ServerKeyExchange. + public static bool IsValidCipherSuiteForSignatureAlgorithms(int cipherSuite, IList sigAlgs) + { + int keyExchangeAlgorithm = GetKeyExchangeAlgorithm(cipherSuite); + + switch (keyExchangeAlgorithm) + { + case KeyExchangeAlgorithm.DHE_DSS: + case KeyExchangeAlgorithm.DHE_RSA: + case KeyExchangeAlgorithm.ECDHE_ECDSA: + case KeyExchangeAlgorithm.ECDHE_RSA: + case KeyExchangeAlgorithm.NULL: + case KeyExchangeAlgorithm.SRP_RSA: + case KeyExchangeAlgorithm.SRP_DSS: + break; + + default: + return true; + } + + foreach (short signatureAlgorithm in sigAlgs) + { + if (IsValidSignatureAlgorithmForServerKeyExchange(signatureAlgorithm, keyExchangeAlgorithm)) + return true; + } + + return false; + } + + internal static bool IsValidCipherSuiteSelection(int[] offeredCipherSuites, int cipherSuite) + { + return null != offeredCipherSuites + && Arrays.Contains(offeredCipherSuites, cipherSuite) + && CipherSuite.TLS_NULL_WITH_NULL_NULL != cipherSuite + && !CipherSuite.IsScsv(cipherSuite); + } + + internal static bool IsValidKeyShareSelection(ProtocolVersion negotiatedVersion, int[] clientSupportedGroups, + IDictionary clientAgreements, int keyShareGroup) + { + return null != clientSupportedGroups + && Arrays.Contains(clientSupportedGroups, keyShareGroup) + && !clientAgreements.Contains(keyShareGroup) + && NamedGroup.CanBeNegotiated(keyShareGroup, negotiatedVersion); + } + + internal static bool IsValidSignatureAlgorithmForCertificateVerify(short signatureAlgorithm, + short[] clientCertificateTypes) + { + short clientCertificateType = SignatureAlgorithm.GetClientCertificateType(signatureAlgorithm); + + return clientCertificateType >= 0 && Arrays.Contains(clientCertificateTypes, clientCertificateType); + } + + internal static bool IsValidSignatureAlgorithmForServerKeyExchange(short signatureAlgorithm, + int keyExchangeAlgorithm) + { + // TODO[tls13] + + switch (keyExchangeAlgorithm) + { + case KeyExchangeAlgorithm.DHE_RSA: + case KeyExchangeAlgorithm.ECDHE_RSA: + case KeyExchangeAlgorithm.SRP_RSA: + switch (signatureAlgorithm) + { + case SignatureAlgorithm.rsa: + case SignatureAlgorithm.rsa_pss_rsae_sha256: + case SignatureAlgorithm.rsa_pss_rsae_sha384: + case SignatureAlgorithm.rsa_pss_rsae_sha512: + case SignatureAlgorithm.rsa_pss_pss_sha256: + case SignatureAlgorithm.rsa_pss_pss_sha384: + case SignatureAlgorithm.rsa_pss_pss_sha512: + return true; + default: + return false; + } + + case KeyExchangeAlgorithm.DHE_DSS: + case KeyExchangeAlgorithm.SRP_DSS: + return SignatureAlgorithm.dsa == signatureAlgorithm; + + case KeyExchangeAlgorithm.ECDHE_ECDSA: + switch (signatureAlgorithm) + { + case SignatureAlgorithm.ecdsa: + case SignatureAlgorithm.ed25519: + case SignatureAlgorithm.ed448: + return true; + default: + return false; + } + + case KeyExchangeAlgorithm.NULL: + return SignatureAlgorithm.anonymous != signatureAlgorithm; + + default: + return false; + } + } + + public static bool IsValidSignatureSchemeForServerKeyExchange(int signatureScheme, int keyExchangeAlgorithm) + { + short signatureAlgorithm = SignatureScheme.GetSignatureAlgorithm(signatureScheme); + + return IsValidSignatureAlgorithmForServerKeyExchange(signatureAlgorithm, keyExchangeAlgorithm); + } + + public static bool IsValidVersionForCipherSuite(int cipherSuite, ProtocolVersion version) + { + version = version.GetEquivalentTlsVersion(); + + ProtocolVersion minimumVersion = GetMinimumVersion(cipherSuite); + if (minimumVersion == version) + return true; + + if (!minimumVersion.IsEarlierVersionOf(version)) + return false; + + return ProtocolVersion.TLSv13.IsEqualOrEarlierVersionOf(minimumVersion) + || ProtocolVersion.TLSv13.IsLaterVersionOf(version); + } + + /// + public static SignatureAndHashAlgorithm ChooseSignatureAndHashAlgorithm(TlsContext context, IList sigHashAlgs, + short signatureAlgorithm) + { + return ChooseSignatureAndHashAlgorithm(context.ServerVersion, sigHashAlgs, signatureAlgorithm); + } + + /// + public static SignatureAndHashAlgorithm ChooseSignatureAndHashAlgorithm(ProtocolVersion negotiatedVersion, + IList sigHashAlgs, short signatureAlgorithm) + { + if (!IsTlsV12(negotiatedVersion)) + return null; + + + if (sigHashAlgs == null) + { + /* + * TODO[tls13] RFC 8446 4.2.3 Clients which desire the server to authenticate itself via + * a certificate MUST send the "signature_algorithms" extension. + */ + + sigHashAlgs = GetDefaultSignatureAlgorithms(signatureAlgorithm); + } + + SignatureAndHashAlgorithm result = null; + foreach (SignatureAndHashAlgorithm sigHashAlg in sigHashAlgs) + { + if (sigHashAlg.Signature != signatureAlgorithm) + continue; + + short hash = sigHashAlg.Hash; + if (hash < MinimumHashStrict) + continue; + + if (result == null) + { + result = sigHashAlg; + continue; + } + + short current = result.Hash; + if (current < MinimumHashPreferred) + { + if (hash > current) + { + result = sigHashAlg; + } + } + else if (hash >= MinimumHashPreferred) + { + if (hash < current) + { + result = sigHashAlg; + } + } + } + if (result == null) + throw new TlsFatalAlert(AlertDescription.internal_error); + + return result; + } + + public static IList GetUsableSignatureAlgorithms(IList sigHashAlgs) + { + if (sigHashAlgs == null) + { + IList v = Platform.CreateArrayList(3); + v.Add(SignatureAlgorithm.rsa); + v.Add(SignatureAlgorithm.dsa); + v.Add(SignatureAlgorithm.ecdsa); + return v; + } + else + { + IList v = Platform.CreateArrayList(); + foreach (SignatureAndHashAlgorithm sigHashAlg in sigHashAlgs) + { + if (sigHashAlg.Hash >= MinimumHashStrict) + { + short sigAlg = sigHashAlg.Signature; + if (!v.Contains(sigAlg)) + { + // TODO Check for crypto support before choosing (or pass in cached list?) + v.Add(sigAlg); + } + } + } + return v; + } + } + + public static int GetCommonCipherSuite13(ProtocolVersion negotiatedVersion, int[] peerCipherSuites, + int[] localCipherSuites, bool useLocalOrder) + { + int[] ordered = peerCipherSuites, unordered = localCipherSuites; + if (useLocalOrder) + { + ordered = localCipherSuites; + unordered = peerCipherSuites; + } + + for (int i = 0; i < ordered.Length; ++i) + { + int candidate = ordered[i]; + if (Arrays.Contains(unordered, candidate) && + IsValidVersionForCipherSuite(candidate, negotiatedVersion)) + { + return candidate; + } + } + + return -1; + } + + public static int[] GetCommonCipherSuites(int[] peerCipherSuites, int[] localCipherSuites, bool useLocalOrder) + { + int[] ordered = peerCipherSuites, unordered = localCipherSuites; + if (useLocalOrder) + { + ordered = localCipherSuites; + unordered = peerCipherSuites; + } + + int count = 0, limit = System.Math.Min(ordered.Length, unordered.Length); + int[] candidates = new int[limit]; + for (int i = 0; i < ordered.Length; ++i) + { + int candidate = ordered[i]; + if (!Contains(candidates, 0, count, candidate) + && Arrays.Contains(unordered, candidate)) + { + candidates[count++] = candidate; + } + } + + if (count < limit) + { + candidates = Arrays.CopyOf(candidates, count); + } + + return candidates; + } + + public static int[] GetSupportedCipherSuites(TlsCrypto crypto, int[] suites) + { + return GetSupportedCipherSuites(crypto, suites, 0, suites.Length); + } + + public static int[] GetSupportedCipherSuites(TlsCrypto crypto, int[] suites, int suitesOff, int suitesCount) + { + int[] supported = new int[suitesCount]; + int count = 0; + + for (int i = 0; i < suitesCount; ++i) + { + int suite = suites[suitesOff + i]; + if (IsSupportedCipherSuite(crypto, suite)) + { + supported[count++] = suite; + } + } + + if (count < suitesCount) + { + supported = Arrays.CopyOf(supported, count); + } + + return supported; + } + + public static bool IsSupportedCipherSuite(TlsCrypto crypto, int cipherSuite) + { + return IsSupportedKeyExchange(crypto, GetKeyExchangeAlgorithm(cipherSuite)) + && crypto.HasEncryptionAlgorithm(GetEncryptionAlgorithm(cipherSuite)) + && crypto.HasMacAlgorithm(GetMacAlgorithm(cipherSuite)); + } + + public static bool IsSupportedKeyExchange(TlsCrypto crypto, int keyExchangeAlgorithm) + { + switch (keyExchangeAlgorithm) + { + case KeyExchangeAlgorithm.DH_anon: + case KeyExchangeAlgorithm.DH_DSS: + case KeyExchangeAlgorithm.DH_RSA: + case KeyExchangeAlgorithm.DHE_PSK: + return crypto.HasDHAgreement(); + + case KeyExchangeAlgorithm.DHE_DSS: + return crypto.HasDHAgreement() + && crypto.HasSignatureAlgorithm(SignatureAlgorithm.dsa); + + case KeyExchangeAlgorithm.DHE_RSA: + return crypto.HasDHAgreement() + && HasAnyRsaSigAlgs(crypto); + + case KeyExchangeAlgorithm.ECDH_anon: + case KeyExchangeAlgorithm.ECDH_ECDSA: + case KeyExchangeAlgorithm.ECDH_RSA: + case KeyExchangeAlgorithm.ECDHE_PSK: + return crypto.HasECDHAgreement(); + + case KeyExchangeAlgorithm.ECDHE_ECDSA: + return crypto.HasECDHAgreement() + && (crypto.HasSignatureAlgorithm(SignatureAlgorithm.ecdsa) + || crypto.HasSignatureAlgorithm(SignatureAlgorithm.ed25519) + || crypto.HasSignatureAlgorithm(SignatureAlgorithm.ed448)); + + case KeyExchangeAlgorithm.ECDHE_RSA: + return crypto.HasECDHAgreement() + && HasAnyRsaSigAlgs(crypto); + + case KeyExchangeAlgorithm.NULL: + case KeyExchangeAlgorithm.PSK: + return true; + + case KeyExchangeAlgorithm.RSA: + case KeyExchangeAlgorithm.RSA_PSK: + return crypto.HasRsaEncryption(); + + case KeyExchangeAlgorithm.SRP: + return crypto.HasSrpAuthentication(); + + case KeyExchangeAlgorithm.SRP_DSS: + return crypto.HasSrpAuthentication() + && crypto.HasSignatureAlgorithm(SignatureAlgorithm.dsa); + + case KeyExchangeAlgorithm.SRP_RSA: + return crypto.HasSrpAuthentication() + && HasAnyRsaSigAlgs(crypto); + + default: + return false; + } + } + + internal static bool HasAnyRsaSigAlgs(TlsCrypto crypto) + { + return crypto.HasSignatureAlgorithm(SignatureAlgorithm.rsa) + || crypto.HasSignatureAlgorithm(SignatureAlgorithm.rsa_pss_rsae_sha256) + || crypto.HasSignatureAlgorithm(SignatureAlgorithm.rsa_pss_rsae_sha384) + || crypto.HasSignatureAlgorithm(SignatureAlgorithm.rsa_pss_rsae_sha512) + || crypto.HasSignatureAlgorithm(SignatureAlgorithm.rsa_pss_pss_sha256) + || crypto.HasSignatureAlgorithm(SignatureAlgorithm.rsa_pss_pss_sha384) + || crypto.HasSignatureAlgorithm(SignatureAlgorithm.rsa_pss_pss_sha512); + } + + internal static byte[] GetCurrentPrfHash(TlsHandshakeHash handshakeHash) + { + return handshakeHash.ForkPrfHash().CalculateHash(); + } + + internal static void SealHandshakeHash(TlsContext context, TlsHandshakeHash handshakeHash, bool forceBuffering) + { + if (forceBuffering || !context.Crypto.HasAllRawSignatureAlgorithms()) + { + handshakeHash.ForceBuffering(); + } + + handshakeHash.SealHashAlgorithms(); + } + + private static TlsHash CreateHash(TlsCrypto crypto, short hashAlgorithm) + { + int cryptoHashAlgorithm = TlsCryptoUtilities.GetHash(hashAlgorithm); + + return crypto.CreateHash(cryptoHashAlgorithm); + } + + /// + private static TlsKeyExchange CreateKeyExchangeClient(TlsClient client, int keyExchange) + { + TlsKeyExchangeFactory factory = client.GetKeyExchangeFactory(); + + switch (keyExchange) + { + case KeyExchangeAlgorithm.DH_anon: + return factory.CreateDHanonKeyExchangeClient(keyExchange, client.GetDHGroupVerifier()); + + case KeyExchangeAlgorithm.DH_DSS: + case KeyExchangeAlgorithm.DH_RSA: + return factory.CreateDHKeyExchange(keyExchange); + + case KeyExchangeAlgorithm.DHE_DSS: + case KeyExchangeAlgorithm.DHE_RSA: + return factory.CreateDheKeyExchangeClient(keyExchange, client.GetDHGroupVerifier()); + + case KeyExchangeAlgorithm.ECDH_anon: + return factory.CreateECDHanonKeyExchangeClient(keyExchange); + + case KeyExchangeAlgorithm.ECDH_ECDSA: + case KeyExchangeAlgorithm.ECDH_RSA: + return factory.CreateECDHKeyExchange(keyExchange); + + case KeyExchangeAlgorithm.ECDHE_ECDSA: + case KeyExchangeAlgorithm.ECDHE_RSA: + return factory.CreateECDheKeyExchangeClient(keyExchange); + + case KeyExchangeAlgorithm.RSA: + return factory.CreateRsaKeyExchange(keyExchange); + + case KeyExchangeAlgorithm.DHE_PSK: + return factory.CreatePskKeyExchangeClient(keyExchange, client.GetPskIdentity(), + client.GetDHGroupVerifier()); + + case KeyExchangeAlgorithm.ECDHE_PSK: + case KeyExchangeAlgorithm.PSK: + case KeyExchangeAlgorithm.RSA_PSK: + return factory.CreatePskKeyExchangeClient(keyExchange, client.GetPskIdentity(), null); + + case KeyExchangeAlgorithm.SRP: + case KeyExchangeAlgorithm.SRP_DSS: + case KeyExchangeAlgorithm.SRP_RSA: + return factory.CreateSrpKeyExchangeClient(keyExchange, client.GetSrpIdentity(), + client.GetSrpConfigVerifier()); + + default: + /* + * Note: internal error here; the TlsProtocol implementation verifies that the + * server-selected cipher suite was in the list of client-offered cipher suites, so if + * we now can't produce an implementation, we shouldn't have offered it! + */ + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + /// + private static TlsKeyExchange CreateKeyExchangeServer(TlsServer server, int keyExchange) + { + TlsKeyExchangeFactory factory = server.GetKeyExchangeFactory(); + + switch (keyExchange) + { + case KeyExchangeAlgorithm.DH_anon: + return factory.CreateDHanonKeyExchangeServer(keyExchange, server.GetDHConfig()); + + case KeyExchangeAlgorithm.DH_DSS: + case KeyExchangeAlgorithm.DH_RSA: + return factory.CreateDHKeyExchange(keyExchange); + + case KeyExchangeAlgorithm.DHE_DSS: + case KeyExchangeAlgorithm.DHE_RSA: + return factory.CreateDheKeyExchangeServer(keyExchange, server.GetDHConfig()); + + case KeyExchangeAlgorithm.ECDH_anon: + return factory.CreateECDHanonKeyExchangeServer(keyExchange, server.GetECDHConfig()); + + case KeyExchangeAlgorithm.ECDH_ECDSA: + case KeyExchangeAlgorithm.ECDH_RSA: + return factory.CreateECDHKeyExchange(keyExchange); + + case KeyExchangeAlgorithm.ECDHE_ECDSA: + case KeyExchangeAlgorithm.ECDHE_RSA: + return factory.CreateECDheKeyExchangeServer(keyExchange, server.GetECDHConfig()); + + case KeyExchangeAlgorithm.RSA: + return factory.CreateRsaKeyExchange(keyExchange); + + case KeyExchangeAlgorithm.DHE_PSK: + return factory.CreatePskKeyExchangeServer(keyExchange, server.GetPskIdentityManager(), + server.GetDHConfig(), null); + + case KeyExchangeAlgorithm.ECDHE_PSK: + return factory.CreatePskKeyExchangeServer(keyExchange, server.GetPskIdentityManager(), null, + server.GetECDHConfig()); + + case KeyExchangeAlgorithm.PSK: + case KeyExchangeAlgorithm.RSA_PSK: + return factory.CreatePskKeyExchangeServer(keyExchange, server.GetPskIdentityManager(), null, null); + + case KeyExchangeAlgorithm.SRP: + case KeyExchangeAlgorithm.SRP_DSS: + case KeyExchangeAlgorithm.SRP_RSA: + return factory.CreateSrpKeyExchangeServer(keyExchange, server.GetSrpLoginParameters()); + + default: + /* + * Note: internal error here; the TlsProtocol implementation verifies that the + * server-selected cipher suite was in the list of client-offered cipher suites, so if + * we now can't produce an implementation, we shouldn't have offered it! + */ + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + /// + internal static TlsKeyExchange InitKeyExchangeClient(TlsClientContext clientContext, TlsClient client) + { + SecurityParameters securityParameters = clientContext.SecurityParameters; + TlsKeyExchange keyExchange = CreateKeyExchangeClient(client, securityParameters.KeyExchangeAlgorithm); + keyExchange.Init(clientContext); + return keyExchange; + } + + /// + internal static TlsKeyExchange InitKeyExchangeServer(TlsServerContext serverContext, TlsServer server) + { + SecurityParameters securityParameters = serverContext.SecurityParameters; + TlsKeyExchange keyExchange = CreateKeyExchangeServer(server, securityParameters.KeyExchangeAlgorithm); + keyExchange.Init(serverContext); + return keyExchange; + } + + internal static TlsCipher InitCipher(TlsContext context) + { + SecurityParameters securityParameters = context.SecurityParameters; + int cipherSuite = securityParameters.CipherSuite; + int encryptionAlgorithm = GetEncryptionAlgorithm(cipherSuite); + int macAlgorithm = GetMacAlgorithm(cipherSuite); + + if (encryptionAlgorithm < 0 || macAlgorithm < 0) + throw new TlsFatalAlert(AlertDescription.internal_error); + + return context.Crypto.CreateCipher(new TlsCryptoParameters(context), encryptionAlgorithm, macAlgorithm); + } + + /// Check the signature algorithm for certificates in the peer's CertPath as specified in RFC 5246 + /// 7.4.2, 7.4.4, 7.4.6 and similar rules for earlier TLS versions. + /// + /// The supplied CertPath should include the trust anchor (its signature algorithm isn't checked, but in the + /// general case checking a certificate requires the issuer certificate). + /// + /// if any certificate in the CertPath (excepting the trust anchor) has a + /// signature algorithm that is not one of the locally supported signature algorithms. + public static void CheckPeerSigAlgs(TlsContext context, TlsCertificate[] peerCertPath) + { + if (context.IsServer) + { + CheckSigAlgOfClientCerts(context, peerCertPath); + } + else + { + CheckSigAlgOfServerCerts(context, peerCertPath); + } + } + + private static void CheckSigAlgOfClientCerts(TlsContext context, TlsCertificate[] clientCertPath) + { + SecurityParameters securityParameters = context.SecurityParameters; + short[] clientCertTypes = securityParameters.ClientCertTypes; + IList serverSigAlgsCert = securityParameters.ServerSigAlgsCert; + + int trustAnchorPos = clientCertPath.Length - 1; + for (int i = 0; i < trustAnchorPos; ++i) + { + TlsCertificate subjectCert = clientCertPath[i]; + TlsCertificate issuerCert = clientCertPath[i + 1]; + + SignatureAndHashAlgorithm sigAndHashAlg = GetCertSigAndHashAlg(subjectCert, issuerCert); + + bool valid = false; + if (null == sigAndHashAlg) + { + // We don't recognize the 'signatureAlgorithm' of the certificate + } + else if (null == serverSigAlgsCert) + { + // TODO Review this (legacy) logic with RFC 4346 (7.4?.2?) + if (null != clientCertTypes) + { + for (int j = 0; j < clientCertTypes.Length; ++j) + { + short signatureAlgorithm = GetLegacySignatureAlgorithmClientCert(clientCertTypes[j]); + if (sigAndHashAlg.Signature == signatureAlgorithm) + { + valid = true; + break; + } + } + } + } + else + { + /* + * RFC 5246 7.4.4 Any certificates provided by the client MUST be signed using a + * hash/signature algorithm pair found in supported_signature_algorithms. + */ + valid = ContainsSignatureAlgorithm(serverSigAlgsCert, sigAndHashAlg); + } + + if (!valid) + { + throw new TlsFatalAlert(AlertDescription.bad_certificate); + } + } + } + + private static void CheckSigAlgOfServerCerts(TlsContext context, TlsCertificate[] serverCertPath) + { + SecurityParameters securityParameters = context.SecurityParameters; + IList clientSigAlgsCert = securityParameters.ClientSigAlgsCert; + IList clientSigAlgs = securityParameters.ClientSigAlgs; + + /* + * NOTE: For TLS 1.2, we'll check 'signature_algorithms' too (if it's distinct), since + * there's no way of knowing whether the server understood 'signature_algorithms_cert'. + */ + if (clientSigAlgs == clientSigAlgsCert || IsTlsV13(securityParameters.NegotiatedVersion)) + { + clientSigAlgs = null; + } + + int trustAnchorPos = serverCertPath.Length - 1; + for (int i = 0; i < trustAnchorPos; ++i) + { + TlsCertificate subjectCert = serverCertPath[i]; + TlsCertificate issuerCert = serverCertPath[i + 1]; + + SignatureAndHashAlgorithm sigAndHashAlg = GetCertSigAndHashAlg(subjectCert, issuerCert); + + bool valid = false; + if (null == sigAndHashAlg) + { + // We don't recognize the 'signatureAlgorithm' of the certificate + } + else if (null == clientSigAlgsCert) + { + /* + * RFC 4346 7.4.2. Unless otherwise specified, the signing algorithm for the + * certificate MUST be the same as the algorithm for the certificate key. + */ + short signatureAlgorithm = GetLegacySignatureAlgorithmServerCert( + securityParameters.KeyExchangeAlgorithm); + + valid = (signatureAlgorithm == sigAndHashAlg.Signature); + } + else + { + /* + * RFC 5246 7.4.2. If the client provided a "signature_algorithms" extension, then + * all certificates provided by the server MUST be signed by a hash/signature algorithm + * pair that appears in that extension. + */ + valid = ContainsSignatureAlgorithm(clientSigAlgsCert, sigAndHashAlg) + || (null != clientSigAlgs && ContainsSignatureAlgorithm(clientSigAlgs, sigAndHashAlg)); + } + + if (!valid) + throw new TlsFatalAlert(AlertDescription.bad_certificate); + } + } + + internal static void CheckTlsFeatures(Certificate serverCertificate, IDictionary clientExtensions, + IDictionary serverExtensions) + { + /* + * RFC 7633 4.3.3. A client MUST treat a certificate with a TLS feature extension as an + * invalid certificate if the features offered by the server do not contain all features + * present in both the client's ClientHello message and the TLS feature extension. + */ + byte[] tlsFeatures = serverCertificate.GetCertificateAt(0).GetExtension(TlsObjectIdentifiers.id_pe_tlsfeature); + if (tlsFeatures != null) + { + foreach (DerInteger tlsExtension in Asn1Sequence.GetInstance(ReadDerObject(tlsFeatures))) + { + int extensionType = tlsExtension.IntValueExact; + CheckUint16(extensionType); + + if (clientExtensions.Contains(extensionType) && !serverExtensions.Contains(extensionType)) + throw new TlsFatalAlert(AlertDescription.certificate_unknown); + } + } + } + + internal static void ProcessClientCertificate(TlsServerContext serverContext, Certificate clientCertificate, + TlsKeyExchange keyExchange, TlsServer server) + { + SecurityParameters securityParameters = serverContext.SecurityParameters; + if (null != securityParameters.PeerCertificate) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + + bool isTlsV13 = IsTlsV13(securityParameters.NegotiatedVersion); + if (isTlsV13) + { + // 'keyExchange' not used + } + else if (clientCertificate.IsEmpty) + { + /* + * NOTE: We tolerate SSLv3 clients sending an empty chain, although "If no suitable + * certificate is available, the client should send a no_certificate alert instead". + */ + + keyExchange.SkipClientCredentials(); + } + else + { + keyExchange.ProcessClientCertificate(clientCertificate); + } + + securityParameters.m_peerCertificate = clientCertificate; + + /* + * RFC 5246 7.4.6. If the client does not send any certificates, the server MAY at its + * discretion either continue the handshake without client authentication, or respond with a + * fatal handshake_failure alert. Also, if some aspect of the certificate chain was + * unacceptable (e.g., it was not signed by a known, trusted CA), the server MAY at its + * discretion either continue the handshake (considering the client unauthenticated) or send + * a fatal alert. + */ + server.NotifyClientCertificate(clientCertificate); + } + + internal static void ProcessServerCertificate(TlsClientContext clientContext, + CertificateStatus serverCertificateStatus, TlsKeyExchange keyExchange, + TlsAuthentication clientAuthentication, IDictionary clientExtensions, IDictionary serverExtensions) + { + SecurityParameters securityParameters = clientContext.SecurityParameters; + bool isTlsV13 = IsTlsV13(securityParameters.NegotiatedVersion); + + if (null == clientAuthentication) + { + if (isTlsV13) + throw new TlsFatalAlert(AlertDescription.internal_error); + + // There was no server certificate message; check it's OK + keyExchange.SkipServerCredentials(); + securityParameters.m_tlsServerEndPoint = EmptyBytes; + return; + } + + Certificate serverCertificate = securityParameters.PeerCertificate; + + CheckTlsFeatures(serverCertificate, clientExtensions, serverExtensions); + + if (!isTlsV13) + { + keyExchange.ProcessServerCertificate(serverCertificate); + } + + clientAuthentication.NotifyServerCertificate( + new TlsServerCertificateImpl(serverCertificate, serverCertificateStatus)); + } + + internal static SignatureAndHashAlgorithm GetCertSigAndHashAlg(TlsCertificate subjectCert, TlsCertificate issuerCert) + { + string sigAlgOid = subjectCert.SigAlgOid; + + if (null != sigAlgOid) + { + if (!PkcsObjectIdentifiers.IdRsassaPss.Id.Equals(sigAlgOid)) + { + if (!CertSigAlgOids.Contains(sigAlgOid)) + return null; + + return (SignatureAndHashAlgorithm)CertSigAlgOids[sigAlgOid]; + } + + RsassaPssParameters pssParams = RsassaPssParameters.GetInstance(subjectCert.GetSigAlgParams()); + if (null != pssParams) + { + DerObjectIdentifier hashOid = pssParams.HashAlgorithm.Algorithm; + if (NistObjectIdentifiers.IdSha256.Equals(hashOid)) + { + if (issuerCert.SupportsSignatureAlgorithmCA(SignatureAlgorithm.rsa_pss_pss_sha256)) + return SignatureAndHashAlgorithm.rsa_pss_pss_sha256; + + if (issuerCert.SupportsSignatureAlgorithmCA(SignatureAlgorithm.rsa_pss_rsae_sha256)) + return SignatureAndHashAlgorithm.rsa_pss_rsae_sha256; + } + else if (NistObjectIdentifiers.IdSha384.Equals(hashOid)) + { + if (issuerCert.SupportsSignatureAlgorithmCA(SignatureAlgorithm.rsa_pss_pss_sha384)) + return SignatureAndHashAlgorithm.rsa_pss_pss_sha384; + + if (issuerCert.SupportsSignatureAlgorithmCA(SignatureAlgorithm.rsa_pss_rsae_sha384)) + return SignatureAndHashAlgorithm.rsa_pss_rsae_sha384; + } + else if (NistObjectIdentifiers.IdSha512.Equals(hashOid)) + { + if (issuerCert.SupportsSignatureAlgorithmCA(SignatureAlgorithm.rsa_pss_pss_sha512)) + return SignatureAndHashAlgorithm.rsa_pss_pss_sha512; + + if (issuerCert.SupportsSignatureAlgorithmCA(SignatureAlgorithm.rsa_pss_rsae_sha512)) + return SignatureAndHashAlgorithm.rsa_pss_rsae_sha512; + } + } + } + + return null; + } + + internal static CertificateRequest ValidateCertificateRequest(CertificateRequest certificateRequest, + TlsKeyExchange keyExchange) + { + short[] validClientCertificateTypes = keyExchange.GetClientCertificateTypes(); + if (IsNullOrEmpty(validClientCertificateTypes)) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + + certificateRequest = NormalizeCertificateRequest(certificateRequest, validClientCertificateTypes); + if (certificateRequest == null) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + return certificateRequest; + } + + internal static CertificateRequest NormalizeCertificateRequest(CertificateRequest certificateRequest, + short[] validClientCertificateTypes) + { + if (ContainsAll(validClientCertificateTypes, certificateRequest.CertificateTypes)) + return certificateRequest; + + short[] retained = RetainAll(certificateRequest.CertificateTypes, validClientCertificateTypes); + if (retained.Length < 1) + return null; + + // TODO Filter for unique sigAlgs/CAs only + return new CertificateRequest(retained, certificateRequest.SupportedSignatureAlgorithms, + certificateRequest.CertificateAuthorities); + } + + internal static bool Contains(int[] buf, int off, int len, int value) + { + for (int i = 0; i < len; ++i) + { + if (value == buf[off + i]) + return true; + } + return false; + } + + internal static bool ContainsAll(short[] container, short[] elements) + { + for (int i = 0; i < elements.Length; ++i) + { + if (!Arrays.Contains(container, elements[i])) + return false; + } + return true; + } + + internal static short[] RetainAll(short[] retainer, short[] elements) + { + short[] retained = new short[System.Math.Min(retainer.Length, elements.Length)]; + + int count = 0; + for (int i = 0; i < elements.Length; ++i) + { + if (Arrays.Contains(retainer, elements[i])) + { + retained[count++] = elements[i]; + } + } + + return Truncate(retained, count); + } + + internal static short[] Truncate(short[] a, int n) + { + if (n >= a.Length) + return a; + + short[] t = new short[n]; + Array.Copy(a, 0, t, 0, n); + return t; + } + + internal static int[] Truncate(int[] a, int n) + { + if (n >= a.Length) + return a; + + int[] t = new int[n]; + Array.Copy(a, 0, t, 0, n); + return t; + } + + /// + internal static TlsCredentialedAgreement RequireAgreementCredentials(TlsCredentials credentials) + { + if (!(credentials is TlsCredentialedAgreement)) + throw new TlsFatalAlert(AlertDescription.internal_error); + + return (TlsCredentialedAgreement)credentials; + } + + /// + internal static TlsCredentialedDecryptor RequireDecryptorCredentials(TlsCredentials credentials) + { + if (!(credentials is TlsCredentialedDecryptor)) + throw new TlsFatalAlert(AlertDescription.internal_error); + + return (TlsCredentialedDecryptor)credentials; + } + + /// + internal static TlsCredentialedSigner RequireSignerCredentials(TlsCredentials credentials) + { + if (!(credentials is TlsCredentialedSigner)) + throw new TlsFatalAlert(AlertDescription.internal_error); + + return (TlsCredentialedSigner)credentials; + } + + private static void CheckDowngradeMarker(byte[] randomBlock, byte[] downgradeMarker) + { + int len = downgradeMarker.Length; + if (ConstantTimeAreEqual(len, downgradeMarker, 0, randomBlock, randomBlock.Length - len)) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + internal static void CheckDowngradeMarker(ProtocolVersion version, byte[] randomBlock) + { + version = version.GetEquivalentTlsVersion(); + + if (version.IsEqualOrEarlierVersionOf(ProtocolVersion.TLSv11)) + { + CheckDowngradeMarker(randomBlock, DowngradeTlsV11); + } + if (version.IsEqualOrEarlierVersionOf(ProtocolVersion.TLSv12)) + { + CheckDowngradeMarker(randomBlock, DowngradeTlsV12); + } + } + + internal static void WriteDowngradeMarker(ProtocolVersion version, byte[] randomBlock) + { + version = version.GetEquivalentTlsVersion(); + + byte[] marker; + if (ProtocolVersion.TLSv12 == version) + { + marker = DowngradeTlsV12; + } + else if (version.IsEqualOrEarlierVersionOf(ProtocolVersion.TLSv11)) + { + marker = DowngradeTlsV11; + } + else + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + Array.Copy(marker, 0, randomBlock, randomBlock.Length - marker.Length, marker.Length); + } + + internal static TlsAuthentication ReceiveServerCertificate(TlsClientContext clientContext, TlsClient client, + MemoryStream buf) + { + SecurityParameters securityParameters = clientContext.SecurityParameters; + if (null != securityParameters.PeerCertificate) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + + MemoryStream endPointHash = new MemoryStream(); + + Certificate.ParseOptions options = new Certificate.ParseOptions() + .SetMaxChainLength(client.GetMaxCertificateChainLength()); + + Certificate serverCertificate = Certificate.Parse(options, clientContext, buf, endPointHash); + + TlsProtocol.AssertEmpty(buf); + + if (serverCertificate.IsEmpty) + throw new TlsFatalAlert(AlertDescription.decode_error); + + securityParameters.m_peerCertificate = serverCertificate; + securityParameters.m_tlsServerEndPoint = endPointHash.ToArray(); + + TlsAuthentication authentication = client.GetAuthentication(); + if (null == authentication) + throw new TlsFatalAlert(AlertDescription.internal_error); + + return authentication; + } + + internal static TlsAuthentication Receive13ServerCertificate(TlsClientContext clientContext, TlsClient client, + MemoryStream buf) + { + SecurityParameters securityParameters = clientContext.SecurityParameters; + if (null != securityParameters.PeerCertificate) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + + Certificate.ParseOptions options = new Certificate.ParseOptions() + .SetMaxChainLength(client.GetMaxCertificateChainLength()); + + Certificate serverCertificate = Certificate.Parse(options, clientContext, buf, null); + + TlsProtocol.AssertEmpty(buf); + + if (serverCertificate.GetCertificateRequestContext().Length > 0) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + if (serverCertificate.IsEmpty) + throw new TlsFatalAlert(AlertDescription.decode_error); + + securityParameters.m_peerCertificate = serverCertificate; + securityParameters.m_tlsServerEndPoint = null; + + TlsAuthentication authentication = client.GetAuthentication(); + if (null == authentication) + throw new TlsFatalAlert(AlertDescription.internal_error); + + return authentication; + } + + internal static TlsAuthentication Skip13ServerCertificate(TlsClientContext clientContext) + { + SecurityParameters securityParameters = clientContext.SecurityParameters; + if (null != securityParameters.PeerCertificate) + throw new TlsFatalAlert(AlertDescription.internal_error); + + securityParameters.m_peerCertificate = null; + securityParameters.m_tlsServerEndPoint = null; + + return null; + } + + public static bool ContainsNonAscii(byte[] bs) + { + for (int i = 0; i < bs.Length; ++i) + { + int c = bs[i]; + if (c >= 0x80) + return true; + } + return false; + } + + public static bool ContainsNonAscii(string s) + { + for (int i = 0; i < s.Length; ++i) + { + int c = s[i]; + if (c >= 0x80) + return true; + } + return false; + } + + internal static IDictionary AddKeyShareToClientHello(TlsClientContext clientContext, TlsClient client, + IDictionary clientExtensions) + { + /* + * RFC 8446 9.2. If containing a "supported_groups" extension, it MUST also contain a + * "key_share" extension, and vice versa. An empty KeyShare.client_shares vector is + * permitted. + */ + if (!IsTlsV13(clientContext.ClientVersion) + || !clientExtensions.Contains(ExtensionType.supported_groups)) + { + return null; + } + + int[] supportedGroups = TlsExtensionsUtilities.GetSupportedGroupsExtension(clientExtensions); + IList keyShareGroups = client.GetEarlyKeyShareGroups(); + IDictionary clientAgreements = Platform.CreateHashtable(3); + IList clientShares = Platform.CreateArrayList(2); + + CollectKeyShares(clientContext.Crypto, supportedGroups, keyShareGroups, clientAgreements, clientShares); + + // TODO[tls13-psk] When clientShares empty, consider not adding extension if pre_shared_key in use + TlsExtensionsUtilities.AddKeyShareClientHello(clientExtensions, clientShares); + + return clientAgreements; + } + + internal static IDictionary AddKeyShareToClientHelloRetry(TlsClientContext clientContext, + IDictionary clientExtensions, int keyShareGroup) + { + int[] supportedGroups = new int[]{ keyShareGroup }; + IList keyShareGroups = VectorOfOne(keyShareGroup); + IDictionary clientAgreements = Platform.CreateHashtable(1); + IList clientShares = Platform.CreateArrayList(1); + + CollectKeyShares(clientContext.Crypto, supportedGroups, keyShareGroups, clientAgreements, clientShares); + + TlsExtensionsUtilities.AddKeyShareClientHello(clientExtensions, clientShares); + + if (clientAgreements.Count < 1 || clientShares.Count < 1) + { + // NOTE: Probable cause is declaring an unsupported NamedGroup in supported_groups extension + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + return clientAgreements; + } + + private static void CollectKeyShares(TlsCrypto crypto, int[] supportedGroups, IList keyShareGroups, + IDictionary clientAgreements, IList clientShares) + { + if (IsNullOrEmpty(supportedGroups)) + return; + + if (null == keyShareGroups || keyShareGroups.Count < 1) + return; + + for (int i = 0; i < supportedGroups.Length; ++i) + { + int supportedGroup = supportedGroups[i]; + + if (!keyShareGroups.Contains(supportedGroup) + || clientAgreements.Contains(supportedGroup) + || !crypto.HasNamedGroup(supportedGroup)) + { + continue; + } + + TlsAgreement agreement = null; + if (NamedGroup.RefersToASpecificCurve(supportedGroup)) + { + if (crypto.HasECDHAgreement()) + { + agreement = crypto.CreateECDomain(new TlsECConfig(supportedGroup)).CreateECDH(); + } + } + else if (NamedGroup.RefersToASpecificFiniteField(supportedGroup)) + { + if (crypto.HasDHAgreement()) + { + agreement = crypto.CreateDHDomain(new TlsDHConfig(supportedGroup, true)).CreateDH(); + } + } + + if (null != agreement) + { + byte[] key_exchange = agreement.GenerateEphemeral(); + KeyShareEntry clientShare = new KeyShareEntry(supportedGroup, key_exchange); + + clientShares.Add(clientShare); + clientAgreements[supportedGroup] = agreement; + } + } + } + + internal static KeyShareEntry SelectKeyShare(IList clientShares, int keyShareGroup) + { + if (null != clientShares && 1 == clientShares.Count) + { + KeyShareEntry clientShare = (KeyShareEntry)clientShares[0]; + if (null != clientShare && clientShare.NamedGroup == keyShareGroup) + { + return clientShare; + } + } + return null; + } + + internal static KeyShareEntry SelectKeyShare(TlsCrypto crypto, ProtocolVersion negotiatedVersion, + IList clientShares, int[] clientSupportedGroups, int[] serverSupportedGroups) + { + if (null != clientShares && !IsNullOrEmpty(clientSupportedGroups) && !IsNullOrEmpty(serverSupportedGroups)) + { + foreach (KeyShareEntry clientShare in clientShares) + { + int group = clientShare.NamedGroup; + + if (!NamedGroup.CanBeNegotiated(group, negotiatedVersion)) + continue; + + if (!Arrays.Contains(serverSupportedGroups, group) || + !Arrays.Contains(clientSupportedGroups, group)) + { + continue; + } + + if (!crypto.HasNamedGroup(group)) + continue; + + if ((NamedGroup.RefersToASpecificCurve(group) && !crypto.HasECDHAgreement()) || + (NamedGroup.RefersToASpecificFiniteField(group) && !crypto.HasDHAgreement())) + { + continue; + } + + return clientShare; + } + } + return null; + } + + internal static int SelectKeyShareGroup(TlsCrypto crypto, ProtocolVersion negotiatedVersion, + int[] clientSupportedGroups, int[] serverSupportedGroups) + { + if (!IsNullOrEmpty(clientSupportedGroups) && !IsNullOrEmpty(serverSupportedGroups)) + { + foreach (int group in clientSupportedGroups) + { + if (!NamedGroup.CanBeNegotiated(group, negotiatedVersion)) + continue; + + if (!Arrays.Contains(serverSupportedGroups, group)) + continue; + + if (!crypto.HasNamedGroup(group)) + continue; + + if ((NamedGroup.RefersToASpecificCurve(group) && !crypto.HasECDHAgreement()) || + (NamedGroup.RefersToASpecificFiniteField(group) && !crypto.HasDHAgreement())) + { + continue; + } + + return group; + } + } + return -1; + } + + internal static byte[] ReadEncryptedPms(TlsContext context, Stream input) + { + if (IsSsl(context)) + return Ssl3Utilities.ReadEncryptedPms(input); + + return ReadOpaque16(input); + } + + internal static void WriteEncryptedPms(TlsContext context, byte[] encryptedPms, Stream output) + { + if (IsSsl(context)) + { + Ssl3Utilities.WriteEncryptedPms(encryptedPms, output); + } + else + { + WriteOpaque16(encryptedPms, output); + } + } + + internal static byte[] GetSessionID(TlsSession tlsSession) + { + if (null != tlsSession) + { + byte[] sessionID = tlsSession.SessionID; + if (null != sessionID + && sessionID.Length > 0 + && sessionID.Length <= 32) + { + return sessionID; + } + } + return EmptyBytes; + } + + internal static void AdjustTranscriptForRetry(TlsHandshakeHash handshakeHash) + { + byte[] clientHelloHash = GetCurrentPrfHash(handshakeHash); + handshakeHash.Reset(); + + int length = clientHelloHash.Length; + CheckUint8(length); + + byte[] synthetic = new byte[4 + length]; + WriteUint8(HandshakeType.message_hash, synthetic, 0); + WriteUint24(length, synthetic, 1); + Array.Copy(clientHelloHash, 0, synthetic, 4, length); + + handshakeHash.Update(synthetic, 0, synthetic.Length); + } + + internal static TlsCredentials EstablishClientCredentials(TlsAuthentication clientAuthentication, + CertificateRequest certificateRequest) + { + return ValidateCredentials(clientAuthentication.GetClientCredentials(certificateRequest)); + } + + internal static TlsCredentialedSigner Establish13ClientCredentials(TlsAuthentication clientAuthentication, + CertificateRequest certificateRequest) + { + return Validate13Credentials(clientAuthentication.GetClientCredentials(certificateRequest)); + } + + internal static void EstablishClientSigAlgs(SecurityParameters securityParameters, + IDictionary clientExtensions) + { + securityParameters.m_clientSigAlgs = TlsExtensionsUtilities.GetSignatureAlgorithmsExtension( + clientExtensions); + securityParameters.m_clientSigAlgsCert = TlsExtensionsUtilities.GetSignatureAlgorithmsCertExtension( + clientExtensions); + } + + internal static TlsCredentials EstablishServerCredentials(TlsServer server) + { + return ValidateCredentials(server.GetCredentials()); + } + + internal static TlsCredentialedSigner Establish13ServerCredentials(TlsServer server) + { + return Validate13Credentials(server.GetCredentials()); + } + + internal static void EstablishServerSigAlgs(SecurityParameters securityParameters, + CertificateRequest certificateRequest) + { + securityParameters.m_clientCertTypes = certificateRequest.CertificateTypes; + securityParameters.m_serverSigAlgs = certificateRequest.SupportedSignatureAlgorithms; + securityParameters.m_serverSigAlgsCert = certificateRequest.SupportedSignatureAlgorithmsCert; + + if (null == securityParameters.ServerSigAlgsCert) + { + securityParameters.m_serverSigAlgsCert = securityParameters.ServerSigAlgs; + } + } + + internal static TlsCredentials ValidateCredentials(TlsCredentials credentials) + { + if (null != credentials) + { + int count = 0; + count += (credentials is TlsCredentialedAgreement) ? 1 : 0; + count += (credentials is TlsCredentialedDecryptor) ? 1 : 0; + count += (credentials is TlsCredentialedSigner) ? 1 : 0; + if (count != 1) + throw new TlsFatalAlert(AlertDescription.internal_error); + } + return credentials; + } + + internal static TlsCredentialedSigner Validate13Credentials(TlsCredentials credentials) + { + if (null == credentials) + return null; + + if (!(credentials is TlsCredentialedSigner)) + throw new TlsFatalAlert(AlertDescription.internal_error); + + return (TlsCredentialedSigner)credentials; + } + + internal static void NegotiatedCipherSuite(SecurityParameters securityParameters, int cipherSuite) + { + securityParameters.m_cipherSuite = cipherSuite; + securityParameters.m_keyExchangeAlgorithm = GetKeyExchangeAlgorithm(cipherSuite); + + int prfAlgorithm = GetPrfAlgorithm(securityParameters, cipherSuite); + securityParameters.m_prfAlgorithm = prfAlgorithm; + + switch (prfAlgorithm) + { + case PrfAlgorithm.ssl_prf_legacy: + case PrfAlgorithm.tls_prf_legacy: + { + securityParameters.m_prfCryptoHashAlgorithm = -1; + securityParameters.m_prfHashLength = -1; + break; + } + default: + { + int prfCryptoHashAlgorithm = TlsCryptoUtilities.GetHashForPrf(prfAlgorithm); + + securityParameters.m_prfCryptoHashAlgorithm = prfCryptoHashAlgorithm; + securityParameters.m_prfHashLength = TlsCryptoUtilities.GetHashOutputSize(prfCryptoHashAlgorithm); + break; + } + } + + /* + * TODO[tls13] We're slowly moving towards negotiating cipherSuite THEN version. We could + * move this to "after parameter negotiation" i.e. after ServerHello/EncryptedExtensions. + */ + ProtocolVersion negotiatedVersion = securityParameters.NegotiatedVersion; + if (IsTlsV13(negotiatedVersion)) + { + securityParameters.m_verifyDataLength = securityParameters.PrfHashLength; + } + else + { + securityParameters.m_verifyDataLength = negotiatedVersion.IsSsl ? 36 : 12; + } + } + + internal static void NegotiatedVersion(SecurityParameters securityParameters) + { + if (!IsSignatureAlgorithmsExtensionAllowed(securityParameters.NegotiatedVersion)) + { + securityParameters.m_clientSigAlgs = null; + securityParameters.m_clientSigAlgsCert = null; + return; + } + + if (null == securityParameters.ClientSigAlgs) + { + securityParameters.m_clientSigAlgs = GetLegacySupportedSignatureAlgorithms(); + } + + if (null == securityParameters.ClientSigAlgsCert) + { + securityParameters.m_clientSigAlgsCert = securityParameters.ClientSigAlgs; + } + } + + internal static void NegotiatedVersionDtlsClient(TlsClientContext clientContext, TlsClient client) + { + SecurityParameters securityParameters = clientContext.SecurityParameters; + ProtocolVersion negotiatedVersion = securityParameters.NegotiatedVersion; + + if (!ProtocolVersion.IsSupportedDtlsVersionClient(negotiatedVersion)) + throw new TlsFatalAlert(AlertDescription.internal_error); + + NegotiatedVersion(securityParameters); + + client.NotifyServerVersion(negotiatedVersion); + } + + internal static void NegotiatedVersionDtlsServer(TlsServerContext serverContext) + { + SecurityParameters securityParameters = serverContext.SecurityParameters; + ProtocolVersion negotiatedVersion = securityParameters.NegotiatedVersion; + + if (!ProtocolVersion.IsSupportedDtlsVersionServer(negotiatedVersion)) + throw new TlsFatalAlert(AlertDescription.internal_error); + + NegotiatedVersion(securityParameters); + } + + internal static void NegotiatedVersionTlsClient(TlsClientContext clientContext, TlsClient client) + { + SecurityParameters securityParameters = clientContext.SecurityParameters; + ProtocolVersion negotiatedVersion = securityParameters.NegotiatedVersion; + + if (!ProtocolVersion.IsSupportedTlsVersionClient(negotiatedVersion)) + throw new TlsFatalAlert(AlertDescription.internal_error); + + NegotiatedVersion(securityParameters); + + client.NotifyServerVersion(negotiatedVersion); + } + + internal static void NegotiatedVersionTlsServer(TlsServerContext serverContext) + { + SecurityParameters securityParameters = serverContext.SecurityParameters; + ProtocolVersion negotiatedVersion = securityParameters.NegotiatedVersion; + + if (!ProtocolVersion.IsSupportedTlsVersionServer(negotiatedVersion)) + throw new TlsFatalAlert(AlertDescription.internal_error); + + NegotiatedVersion(securityParameters); + } + + internal static TlsSecret DeriveSecret(SecurityParameters securityParameters, TlsSecret secret, string label, + byte[] transcriptHash) + { + int prfCryptoHashAlgorithm = securityParameters.PrfCryptoHashAlgorithm; + int prfHashLength = securityParameters.PrfHashLength; + + return DeriveSecret(prfCryptoHashAlgorithm, prfHashLength, secret, label, transcriptHash); + } + + internal static TlsSecret DeriveSecret(int prfCryptoHashAlgorithm, int prfHashLength, TlsSecret secret, + string label, byte[] transcriptHash) + { + if (transcriptHash.Length != prfHashLength) + throw new TlsFatalAlert(AlertDescription.internal_error); + + return TlsCryptoUtilities.HkdfExpandLabel(secret, prfCryptoHashAlgorithm, label, transcriptHash, + prfHashLength); + } + + internal static TlsSecret GetSessionMasterSecret(TlsCrypto crypto, TlsSecret masterSecret) + { + if (null != masterSecret) + { + lock (masterSecret) + { + if (masterSecret.IsAlive()) + return crypto.AdoptSecret(masterSecret); + } + } + + return null; + } + + internal static bool IsPermittedExtensionType13(int handshakeType, int extensionType) + { + switch (extensionType) + { + case ExtensionType.server_name: + case ExtensionType.max_fragment_length: + case ExtensionType.supported_groups: + case ExtensionType.use_srtp: + case ExtensionType.heartbeat: + case ExtensionType.application_layer_protocol_negotiation: + case ExtensionType.client_certificate_type: + case ExtensionType.server_certificate_type: + { + switch (handshakeType) + { + case HandshakeType.client_hello: + case HandshakeType.encrypted_extensions: + return true; + default: + return false; + } + } + case ExtensionType.status_request: + case ExtensionType.signed_certificate_timestamp: + { + switch (handshakeType) + { + case HandshakeType.client_hello: + case HandshakeType.certificate_request: + case HandshakeType.certificate: + return true; + default: + return false; + } + } + case ExtensionType.signature_algorithms: + case ExtensionType.certificate_authorities: + case ExtensionType.signature_algorithms_cert: + { + switch (handshakeType) + { + case HandshakeType.client_hello: + case HandshakeType.certificate_request: + return true; + default: + return false; + } + } + case ExtensionType.padding: + case ExtensionType.psk_key_exchange_modes: + case ExtensionType.post_handshake_auth: + { + switch (handshakeType) + { + case HandshakeType.client_hello: + return true; + default: + return false; + } + } + case ExtensionType.key_share: + case ExtensionType.supported_versions: + { + switch (handshakeType) + { + case HandshakeType.client_hello: + case HandshakeType.server_hello: + case HandshakeType.hello_retry_request: + return true; + default: + return false; + } + } + case ExtensionType.pre_shared_key: + { + switch (handshakeType) + { + case HandshakeType.client_hello: + case HandshakeType.server_hello: + return true; + default: + return false; + } + } + case ExtensionType.early_data: + { + switch (handshakeType) + { + case HandshakeType.client_hello: + case HandshakeType.encrypted_extensions: + case HandshakeType.new_session_ticket: + return true; + default: + return false; + } + } + case ExtensionType.cookie: + { + switch (handshakeType) + { + case HandshakeType.client_hello: + case HandshakeType.hello_retry_request: + return true; + default: + return false; + } + } + case ExtensionType.oid_filters: + { + switch (handshakeType) + { + case HandshakeType.certificate_request: + return true; + default: + return false; + } + } + default: + { + return !ExtensionType.IsRecognized(extensionType); + } + } + } + + /// + internal static void CheckExtensionData13(IDictionary extensions, int handshakeType, short alertDescription) + { + foreach (int extensionType in extensions.Keys) + { + if (!IsPermittedExtensionType13(handshakeType, extensionType)) + throw new TlsFatalAlert(alertDescription, "Invalid extension: " + + ExtensionType.GetText(extensionType)); + } + } + + /// Generate a pre_master_secret and send it encrypted to the server. + /// + public static TlsSecret GenerateEncryptedPreMasterSecret(TlsContext context, TlsEncryptor encryptor, + Stream output) + { + ProtocolVersion version = context.RsaPreMasterSecretVersion; + TlsSecret preMasterSecret = context.Crypto.GenerateRsaPreMasterSecret(version); + byte[] encryptedPreMasterSecret = preMasterSecret.Encrypt(encryptor); + WriteEncryptedPms(context, encryptedPreMasterSecret, output); + return preMasterSecret; + } + +#if !PORTABLE || DOTNET + public static bool IsTimeout(SocketException e) + { +#if NET_1_1 + return 10060 == e.ErrorCode; +#else + return SocketError.TimedOut == e.SocketErrorCode; +#endif + } +#endif + + /// + internal static void AddPreSharedKeyToClientExtensions(TlsPsk[] psks, IDictionary clientExtensions) + { + IList identities = Platform.CreateArrayList(psks.Length); + for (int i = 0; i < psks.Length; ++i) + { + TlsPsk psk = psks[i]; + + // TODO[tls13-psk] Handle obfuscated_ticket_age for resumption PSKs + identities.Add(new PskIdentity(psk.Identity, 0L)); + } + + TlsExtensionsUtilities.AddPreSharedKeyClientHello(clientExtensions, new OfferedPsks(identities)); + } + + /// + internal static OfferedPsks.BindersConfig AddPreSharedKeyToClientHello(TlsClientContext clientContext, + TlsClient client, IDictionary clientExtensions, int[] offeredCipherSuites) + { + if (!IsTlsV13(clientContext.ClientVersion)) + return null; + + TlsPskExternal[] pskExternals = GetPskExternalsClient(client, offeredCipherSuites); + if (null == pskExternals) + return null; + + short[] pskKeyExchangeModes = client.GetPskKeyExchangeModes(); + if (IsNullOrEmpty(pskKeyExchangeModes)) + throw new TlsFatalAlert(AlertDescription.internal_error, + "External PSKs configured but no PskKeyExchangeMode available"); + + TlsSecret[] pskEarlySecrets = GetPskEarlySecrets(clientContext.Crypto, pskExternals); + + int bindersSize = OfferedPsks.GetBindersSize(pskExternals); + + AddPreSharedKeyToClientExtensions(pskExternals, clientExtensions); + TlsExtensionsUtilities.AddPskKeyExchangeModesExtension(clientExtensions, pskKeyExchangeModes); + + return new OfferedPsks.BindersConfig(pskExternals, pskKeyExchangeModes, pskEarlySecrets, bindersSize); + } + + /// + internal static OfferedPsks.BindersConfig AddPreSharedKeyToClientHelloRetry(TlsClientContext clientContext, + OfferedPsks.BindersConfig clientBinders, IDictionary clientExtensions) + { + SecurityParameters securityParameters = clientContext.SecurityParameters; + + int prfAlgorithm = GetPrfAlgorithm13(securityParameters.CipherSuite); + + IList pskIndices = GetPskIndices(clientBinders.m_psks, prfAlgorithm); + if (pskIndices.Count < 1) + return null; + + OfferedPsks.BindersConfig result = clientBinders; + + int count = pskIndices.Count; + if (count < clientBinders.m_psks.Length) + { + TlsPsk[] psks = new TlsPsk[count]; + TlsSecret[] earlySecrets = new TlsSecret[count]; + + for (int i = 0; i < count; ++i) + { + int j = (int)pskIndices[i]; + + psks[i] = clientBinders.m_psks[j]; + earlySecrets[i] = clientBinders.m_earlySecrets[j]; + } + + int bindersSize = OfferedPsks.GetBindersSize(psks); + + result = new OfferedPsks.BindersConfig(psks, clientBinders.m_pskKeyExchangeModes, earlySecrets, + bindersSize); + } + + AddPreSharedKeyToClientExtensions(result.m_psks, clientExtensions); + // NOTE: psk_key_exchange_modes should already be in 'clientExtensions' from the ClientHello + + return result; + } + + internal static OfferedPsks.SelectedConfig SelectPreSharedKey(TlsServerContext serverContext, TlsServer server, + IDictionary clientHelloExtensions, HandshakeMessageInput clientHelloMessage, TlsHandshakeHash handshakeHash, + bool afterHelloRetryRequest) + { + bool handshakeHashUpdated = false; + + OfferedPsks offeredPsks = TlsExtensionsUtilities.GetPreSharedKeyClientHello(clientHelloExtensions); + if (null != offeredPsks) + { + short[] pskKeyExchangeModes = TlsExtensionsUtilities.GetPskKeyExchangeModesExtension( + clientHelloExtensions); + if (IsNullOrEmpty(pskKeyExchangeModes)) + throw new TlsFatalAlert(AlertDescription.missing_extension); + + // TODO[tls13] Add support for psk_ke? + if (Arrays.Contains(pskKeyExchangeModes, PskKeyExchangeMode.psk_dhe_ke)) + { + // TODO[tls13] Prefer to get the exact index from the server? + TlsPskExternal psk = server.GetExternalPsk(offeredPsks.Identities); + if (null != psk) + { + int index = offeredPsks.GetIndexOfIdentity(new PskIdentity(psk.Identity, 0L)); + if (index >= 0) + { + byte[] binder = (byte[])offeredPsks.Binders[index]; + + TlsCrypto crypto = serverContext.Crypto; + TlsSecret earlySecret = GetPskEarlySecret(crypto, psk); + + // TODO[tls13-psk] Handle resumption PSKs + bool isExternalPsk = true; + int pskCryptoHashAlgorithm = TlsCryptoUtilities.GetHashForPrf(psk.PrfAlgorithm); + + byte[] transcriptHash; + { + handshakeHashUpdated = true; + int bindersSize = offeredPsks.BindersSize; + clientHelloMessage.UpdateHashPrefix(handshakeHash, bindersSize); + + if (afterHelloRetryRequest) + { + transcriptHash = handshakeHash.GetFinalHash(pskCryptoHashAlgorithm); + } + else + { + TlsHash hash = crypto.CreateHash(pskCryptoHashAlgorithm); + handshakeHash.CopyBufferTo(new TlsHashSink(hash)); + transcriptHash = hash.CalculateHash(); + } + + clientHelloMessage.UpdateHashSuffix(handshakeHash, bindersSize); + } + + byte[] calculatedBinder = CalculatePskBinder(crypto, isExternalPsk, pskCryptoHashAlgorithm, + earlySecret, transcriptHash); + + if (Arrays.ConstantTimeAreEqual(calculatedBinder, binder)) + return new OfferedPsks.SelectedConfig(index, psk, pskKeyExchangeModes, earlySecret); + } + } + } + } + + if (!handshakeHashUpdated) + { + clientHelloMessage.UpdateHash(handshakeHash); + } + + return null; + } + + internal static TlsSecret GetPskEarlySecret(TlsCrypto crypto, TlsPsk psk) + { + int cryptoHashAlgorithm = TlsCryptoUtilities.GetHashForPrf(psk.PrfAlgorithm); + + return crypto + .HkdfInit(cryptoHashAlgorithm) + .HkdfExtract(cryptoHashAlgorithm, psk.Key); + } + + internal static TlsSecret[] GetPskEarlySecrets(TlsCrypto crypto, TlsPsk[] psks) + { + int count = psks.Length; + TlsSecret[] earlySecrets = new TlsSecret[count]; + for (int i = 0; i < count; ++i) + { + earlySecrets[i] = GetPskEarlySecret(crypto, psks[i]); + } + return earlySecrets; + } + + /// + internal static TlsPskExternal[] GetPskExternalsClient(TlsClient client, int[] offeredCipherSuites) + { + IList externalPsks = client.GetExternalPsks(); + if (IsNullOrEmpty(externalPsks)) + return null; + + int[] prfAlgorithms = GetPrfAlgorithms13(offeredCipherSuites); + + int count = externalPsks.Count; + TlsPskExternal[] result = new TlsPskExternal[count]; + + for (int i = 0; i < count; ++i) + { + TlsPskExternal pskExternal = externalPsks[i] as TlsPskExternal; + if (null == pskExternal) + throw new TlsFatalAlert(AlertDescription.internal_error, + "External PSKs element is not a TlsPSKExternal"); + + if (!Arrays.Contains(prfAlgorithms, pskExternal.PrfAlgorithm)) + throw new TlsFatalAlert(AlertDescription.internal_error, + "External PSK incompatible with offered cipher suites"); + + result[i] = pskExternal; + } + + return result; + } + + internal static IList GetPskIndices(TlsPsk[] psks, int prfAlgorithm) + { + IList v = Platform.CreateArrayList(psks.Length); + for (int i = 0; i < psks.Length; ++i) + { + if (psks[i].PrfAlgorithm == prfAlgorithm) + { + v.Add(i); + } + } + return v; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsUtilities.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsUtilities.cs.meta new file mode 100644 index 0000000..c3acf65 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TlsUtilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8a3f9e3642b27bf4da3a3ce9d30ed8e8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TrustedAuthority.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TrustedAuthority.cs new file mode 100644 index 0000000..cd564eb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TrustedAuthority.cs @@ -0,0 +1,149 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls +{ + public sealed class TrustedAuthority + { + private readonly short m_identifierType; + private readonly object m_identifier; + + public TrustedAuthority(short identifierType, object identifier) + { + if (!IsCorrectType(identifierType, identifier)) + throw new ArgumentException("not an instance of the correct type", "identifier"); + + this.m_identifierType = identifierType; + this.m_identifier = identifier; + } + + public short IdentifierType + { + get { return m_identifierType; } + } + + public object Identifier + { + get { return m_identifier; } + } + + public byte[] GetCertSha1Hash() + { + return Arrays.Clone((byte[])m_identifier); + } + + public byte[] GetKeySha1Hash() + { + return Arrays.Clone((byte[])m_identifier); + } + + public X509Name X509Name + { + get + { + CheckCorrectType(Tls.IdentifierType.x509_name); + return (X509Name)m_identifier; + } + } + + /// Encode this to a . + /// the to encode to. + /// + public void Encode(Stream output) + { + TlsUtilities.WriteUint8(m_identifierType, output); + + switch (m_identifierType) + { + case Tls.IdentifierType.cert_sha1_hash: + case Tls.IdentifierType.key_sha1_hash: + { + byte[] sha1Hash = (byte[])m_identifier; + output.Write(sha1Hash, 0, sha1Hash.Length); + break; + } + case Tls.IdentifierType.pre_agreed: + { + break; + } + case Tls.IdentifierType.x509_name: + { + X509Name dn = (X509Name)m_identifier; + byte[] derEncoding = dn.GetEncoded(Asn1Encodable.Der); + TlsUtilities.WriteOpaque16(derEncoding, output); + break; + } + default: + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + /// Parse a from a . + /// the to parse from. + /// a object. + /// + public static TrustedAuthority Parse(Stream input) + { + short identifier_type = TlsUtilities.ReadUint8(input); + object identifier; + + switch (identifier_type) + { + case Tls.IdentifierType.cert_sha1_hash: + case Tls.IdentifierType.key_sha1_hash: + { + identifier = TlsUtilities.ReadFully(20, input); + break; + } + case Tls.IdentifierType.pre_agreed: + { + identifier = null; + break; + } + case Tls.IdentifierType.x509_name: + { + byte[] derEncoding = TlsUtilities.ReadOpaque16(input, 1); + Asn1Object asn1 = TlsUtilities.ReadDerObject(derEncoding); + identifier = X509Name.GetInstance(asn1); + break; + } + default: + throw new TlsFatalAlert(AlertDescription.decode_error); + } + + return new TrustedAuthority(identifier_type, identifier); + } + + private void CheckCorrectType(short expectedIdentifierType) + { + if (m_identifierType != expectedIdentifierType || !IsCorrectType(expectedIdentifierType, m_identifier)) + throw new InvalidOperationException("TrustedAuthority is not of type " + + Tls.IdentifierType.GetName(expectedIdentifierType)); + } + + private static bool IsCorrectType(short identifierType, object identifier) + { + switch (identifierType) + { + case Tls.IdentifierType.cert_sha1_hash: + case Tls.IdentifierType.key_sha1_hash: + return IsSha1Hash(identifier); + case Tls.IdentifierType.pre_agreed: + return identifier == null; + case Tls.IdentifierType.x509_name: + return identifier is X509Name; + default: + throw new ArgumentException("unsupported IdentifierType", "identifierType"); + } + } + + private static bool IsSha1Hash(object identifier) + { + return identifier is byte[] && ((byte[])identifier).Length == 20; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TrustedAuthority.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TrustedAuthority.cs.meta new file mode 100644 index 0000000..bee8e9e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/TrustedAuthority.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a43da32ab01a68a4aa4d95370e36dc12 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/UrlAndHash.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/UrlAndHash.cs new file mode 100644 index 0000000..47347c1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/UrlAndHash.cs @@ -0,0 +1,83 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls +{ + /// RFC 6066 5. + public sealed class UrlAndHash + { + private readonly string m_url; + private readonly byte[] m_sha1Hash; + + public UrlAndHash(string url, byte[] sha1Hash) + { + if (TlsUtilities.IsNullOrEmpty(url) || url.Length >= (1 << 16)) + throw new ArgumentException("must have length from 1 to (2^16 - 1)", "url"); + if (sha1Hash != null && sha1Hash.Length != 20) + throw new ArgumentException("must have length == 20, if present", "sha1Hash"); + + this.m_url = url; + this.m_sha1Hash = sha1Hash; + } + + public string Url + { + get { return m_url; } + } + + public byte[] Sha1Hash + { + get { return m_sha1Hash; } + } + + /// Encode this to a . + /// the to encode to. + /// + public void Encode(Stream output) + { + byte[] urlEncoding = Strings.ToByteArray(m_url); + TlsUtilities.WriteOpaque16(urlEncoding, output); + + if (m_sha1Hash == null) + { + TlsUtilities.WriteUint8(0, output); + } + else + { + TlsUtilities.WriteUint8(1, output); + output.Write(m_sha1Hash, 0, m_sha1Hash.Length); + } + } + + /// Parse a from a . + /// the of the current connection. + /// the to parse from. + /// a object. + /// + public static UrlAndHash Parse(TlsContext context, Stream input) + { + byte[] urlEncoding = TlsUtilities.ReadOpaque16(input, 1); + string url = Strings.FromByteArray(urlEncoding); + + byte[] sha1Hash = null; + short padding = TlsUtilities.ReadUint8(input); + switch (padding) + { + case 0: + if (TlsUtilities.IsTlsV12(context)) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + break; + case 1: + sha1Hash = TlsUtilities.ReadFully(20, input); + break; + default: + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + return new UrlAndHash(url, sha1Hash); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/UrlAndHash.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/UrlAndHash.cs.meta new file mode 100644 index 0000000..440deb6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/UrlAndHash.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2372f764a555a9b4a9ea3c48c6450642 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/UseSrtpData.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/UseSrtpData.cs new file mode 100644 index 0000000..6c7e7da --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/UseSrtpData.cs @@ -0,0 +1,43 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + /// RFC 5764 4.1.1 + public sealed class UseSrtpData + { + private readonly int[] m_protectionProfiles; + private readonly byte[] m_mki; + + /// see for valid constants. + /// valid lengths from 0 to 255. + public UseSrtpData(int[] protectionProfiles, byte[] mki) + { + if (TlsUtilities.IsNullOrEmpty(protectionProfiles) || protectionProfiles.Length >= (1 << 15)) + throw new ArgumentException("must have length from 1 to (2^15 - 1)", "protectionProfiles"); + + if (mki == null) + { + mki = TlsUtilities.EmptyBytes; + } + else if (mki.Length > 255) + { + throw new ArgumentException("cannot be longer than 255 bytes", "mki"); + } + + this.m_protectionProfiles = protectionProfiles; + this.m_mki = mki; + } + + /// see for valid constants. + public int[] ProtectionProfiles + { + get { return m_protectionProfiles; } + } + + /// valid lengths from 0 to 255. + public byte[] Mki + { + get { return m_mki; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/UseSrtpData.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/UseSrtpData.cs.meta new file mode 100644 index 0000000..bd9699d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/UseSrtpData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 31faf505535f55448864eb8c97cc221a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/UserMappingType.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/UserMappingType.cs new file mode 100644 index 0000000..ba02cbc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/UserMappingType.cs @@ -0,0 +1,13 @@ +using System; + +namespace Org.BouncyCastle.Tls +{ + /// RFC 4681 + public abstract class UserMappingType + { + /* + * RFC 4681 + */ + public const short upn_domain_hint = 64; + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/UserMappingType.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/UserMappingType.cs.meta new file mode 100644 index 0000000..3af1dcb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/UserMappingType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 197dac89155a77c40bfe0e406c9a1a0d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto.meta new file mode 100644 index 0000000..6407372 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4c2e170da1bac394ca37c74aa58f540f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/CryptoHashAlgorithm.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/CryptoHashAlgorithm.cs new file mode 100644 index 0000000..dc3c869 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/CryptoHashAlgorithm.cs @@ -0,0 +1,15 @@ +using System; + +namespace Org.BouncyCastle.Tls.Crypto +{ + public abstract class CryptoHashAlgorithm + { + public const int md5 = 1; + public const int sha1 = 2; + public const int sha224 = 3; + public const int sha256 = 4; + public const int sha384 = 5; + public const int sha512 = 6; + public const int sm3 = 7; + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/CryptoHashAlgorithm.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/CryptoHashAlgorithm.cs.meta new file mode 100644 index 0000000..dbb4bd0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/CryptoHashAlgorithm.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fc4a17bd2a322df4e83b9faaafd052db +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/CryptoSignatureAlgorithm.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/CryptoSignatureAlgorithm.cs new file mode 100644 index 0000000..ed58820 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/CryptoSignatureAlgorithm.cs @@ -0,0 +1,22 @@ +using System; + +namespace Org.BouncyCastle.Tls.Crypto +{ + public abstract class CryptoSignatureAlgorithm + { + public const int rsa = 1; + public const int dsa = 2; + public const int ecdsa = 3; + public const int rsa_pss_rsae_sha256 = 4; + public const int rsa_pss_rsae_sha384 = 5; + public const int rsa_pss_rsae_sha512 = 6; + public const int ed25519 = 7; + public const int ed448 = 8; + public const int rsa_pss_pss_sha256 = 9; + public const int rsa_pss_pss_sha384 = 10; + public const int rsa_pss_pss_sha512 = 11; + public const int gostr34102012_256 = 64; + public const int gostr34102012_512 = 65; + public const int sm2 = 200; + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/CryptoSignatureAlgorithm.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/CryptoSignatureAlgorithm.cs.meta new file mode 100644 index 0000000..e047ede --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/CryptoSignatureAlgorithm.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 09e2d86f374a3e744945bbb86ca1bd23 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/DHGroup.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/DHGroup.cs new file mode 100644 index 0000000..364a604 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/DHGroup.cs @@ -0,0 +1,46 @@ +using System; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Tls.Crypto +{ + /// Carrier class for Diffie-Hellman group parameters. + public class DHGroup + { + private readonly BigInteger g, p, q; + private readonly int l; + + /// Base constructor with the prime factor of (p - 1). + /// the prime modulus. + /// specifies the prime factor of (p - 1). + /// the base generator. + /// + public DHGroup(BigInteger p, BigInteger q, BigInteger g, int l) + { + this.p = p; + this.g = g; + this.q = q; + this.l = l; + } + + public virtual BigInteger G + { + get { return g; } + } + + public virtual int L + { + get { return l; } + } + + public virtual BigInteger P + { + get { return p; } + } + + public virtual BigInteger Q + { + get { return q; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/DHGroup.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/DHGroup.cs.meta new file mode 100644 index 0000000..01c63e6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/DHGroup.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 128522c5f31d1fe4282145c9f1f412fb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/DHStandardGroups.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/DHStandardGroups.cs new file mode 100644 index 0000000..40ddb57 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/DHStandardGroups.cs @@ -0,0 +1,248 @@ +using System; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Tls.Crypto +{ + /// Standard Diffie-Hellman groups from various IETF specifications. + public class DHStandardGroups + { + private static readonly BigInteger Two = BigInteger.Two; + + private static BigInteger FromHex(string hex) + { + return new BigInteger(1, Hex.DecodeStrict(hex)); + } + + //private static DHGroup FromPG(string hexP, string hexG) + //{ + // return new DHGroup(FromHex(hexP), null, FromHex(hexG), 0); + //} + + private static DHGroup SafePrimeGen2(string hexP) + { + return SafePrimeGen2(hexP, 0); + } + + private static DHGroup SafePrimeGen2(string hexP, int l) + { + // NOTE: A group using a safe prime (i.e. q = (p-1)/2), and generator g = 2 + BigInteger p = FromHex(hexP); + return new DHGroup(p, p.ShiftRight(1), Two, l); + } + + /* + * RFC 2409 + */ + private static readonly string rfc2409_768_p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + + "E485B576625E7EC6F44C42E9A63A3620FFFFFFFFFFFFFFFF"; + public static readonly DHGroup rfc2409_768 = SafePrimeGen2(rfc2409_768_p); + + private static readonly string rfc2409_1024_p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381" + + "FFFFFFFFFFFFFFFF"; + public static readonly DHGroup rfc2409_1024 = SafePrimeGen2(rfc2409_1024_p); + + /* + * RFC 3526 + */ + private static readonly string rfc3526_1536_p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" + + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" + "83655D23DCA3AD961C62F356208552BB9ED529077096966D" + + "670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF"; + private static readonly int rfc3526_1536_l = 200; // RFC3526/RFC7919 + public static readonly DHGroup rfc3526_1536 = SafePrimeGen2(rfc3526_1536_p, rfc3526_1536_l); + + private static readonly string rfc3526_2048_p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" + + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" + "83655D23DCA3AD961C62F356208552BB9ED529077096966D" + + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" + + "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" + "15728E5A8AACAA68FFFFFFFFFFFFFFFF"; + private static readonly int rfc3526_2048_l = System.Math.Max(225, 112 * 2); // MAX(RFC3526/RFC7919,FIPS) + public static readonly DHGroup rfc3526_2048 = SafePrimeGen2(rfc3526_2048_p, rfc3526_2048_l); + + private static readonly string rfc3526_3072_p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" + + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" + "83655D23DCA3AD961C62F356208552BB9ED529077096966D" + + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" + + "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" + "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" + + "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" + "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" + + "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" + + "43DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF"; + private static readonly int rfc3526_3072_l = System.Math.Max(275, 128 * 2); // MAX(RFC3526/RFC7919,FIPS) + public static readonly DHGroup rfc3526_3072 = SafePrimeGen2(rfc3526_3072_p, rfc3526_3072_l); + + private static readonly string rfc3526_4096_p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" + + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" + "83655D23DCA3AD961C62F356208552BB9ED529077096966D" + + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" + + "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" + "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" + + "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" + "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" + + "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" + + "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7" + "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA" + + "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6" + "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED" + + "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9" + "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199" + + "FFFFFFFFFFFFFFFF"; + private static readonly int rfc3526_4096_l = System.Math.Max(325, 152 * 2); // MAX(RFC3526/RFC7919,FIPS) + public static readonly DHGroup rfc3526_4096 = SafePrimeGen2(rfc3526_4096_p, rfc3526_4096_l); + + private static readonly string rfc3526_6144_p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E08" + + "8A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B" + + "302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9" + + "A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE6" + + "49286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8" + + "FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D" + + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C" + + "180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718" + + "3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D" + + "04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7D" + + "B3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D226" + + "1AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200C" + + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFC" + + "E0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B26" + + "99C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB" + + "04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2" + + "233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127" + + "D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492" + + "36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BDF8FF9406" + + "AD9E530EE5DB382F413001AEB06A53ED9027D831179727B0865A8918" + + "DA3EDBEBCF9B14ED44CE6CBACED4BB1BDB7F1447E6CC254B33205151" + + "2BD7AF426FB8F401378CD2BF5983CA01C64B92ECF032EA15D1721D03" + + "F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E59E7C97F" + + "BEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA" + + "CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58B" + + "B7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632" + + "387FE8D76E3C0468043E8F663F4860EE12BF2D5B0B7474D6E694F91E" + + "6DCC4024FFFFFFFFFFFFFFFF"; + private static readonly int rfc3526_6144_l = System.Math.Max(375, 176 * 2); // MAX(RFC3526/RFC7919,FIPS) + public static readonly DHGroup rfc3526_6144 = SafePrimeGen2(rfc3526_6144_p, rfc3526_6144_l); + + private static readonly string rfc3526_8192_p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" + + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" + "83655D23DCA3AD961C62F356208552BB9ED529077096966D" + + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" + + "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" + "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" + + "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" + "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" + + "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" + + "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7" + "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA" + + "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6" + "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED" + + "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9" + "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492" + + "36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BD" + "F8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831" + + "179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B" + "DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF" + + "5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6" + "D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F3" + + "23A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA" + "CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE328" + + "06A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55C" + "DA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE" + + "12BF2D5B0B7474D6E694F91E6DBE115974A3926F12FEE5E4" + "38777CB6A932DF8CD8BEC4D073B931BA3BC832B68D9DD300" + + "741FA7BF8AFC47ED2576F6936BA424663AAB639C5AE4F568" + "3423B4742BF1C978238F16CBE39D652DE3FDB8BEFC848AD9" + + "22222E04A4037C0713EB57A81A23F0C73473FC646CEA306B" + "4BCBC8862F8385DDFA9D4B7FA2C087E879683303ED5BDD3A" + + "062B3CF5B3A278A66D2A13F83F44F82DDF310EE074AB6A36" + "4597E899A0255DC164F31CC50846851DF9AB48195DED7EA1" + + "B1D510BD7EE74D73FAF36BC31ECFA268359046F4EB879F92" + "4009438B481C6CD7889A002ED5EE382BC9190DA6FC026E47" + + "9558E4475677E9AA9E3050E2765694DFC81F56E880B96E71" + "60C980DD98EDD3DFFFFFFFFFFFFFFFFF"; + private static readonly int rfc3526_8192_l = System.Math.Max(400, 200 * 2); // MAX(RFC3526/RFC7919,FIPS) + public static readonly DHGroup rfc3526_8192 = SafePrimeGen2(rfc3526_8192_p, rfc3526_8192_l); + + /* + * RFC 4306 + */ + public static readonly DHGroup rfc4306_768 = rfc2409_768; + public static readonly DHGroup rfc4306_1024 = rfc2409_1024; + + /* + * RFC 5996 + */ + public static readonly DHGroup rfc5996_768 = rfc4306_768; + public static readonly DHGroup rfc5996_1024 = rfc4306_1024; + + /* + * RFC 7919 + */ + private static readonly string rfc7919_ffdhe2048_p = "FFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1" + + "D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF9" + "7D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD6561" + + "2433F51F5F066ED0856365553DED1AF3B557135E7F57C935" + "984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE735" + + "30ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FB" + "B96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB19" + + "0B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F61" + "9172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD73" + + "3BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA" + "886B423861285C97FFFFFFFFFFFFFFFF"; + private static readonly int rfc7919_ffdhe2048_l = System.Math.Max(225, 112 * 2); // MAX(RFC7919,FIPS) + public static readonly DHGroup rfc7919_ffdhe2048 = SafePrimeGen2(rfc7919_ffdhe2048_p, rfc7919_ffdhe2048_l); + + private static readonly string rfc7919_ffdhe3072_p = "FFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1" + + "D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF9" + "7D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD6561" + + "2433F51F5F066ED0856365553DED1AF3B557135E7F57C935" + "984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE735" + + "30ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FB" + "B96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB19" + + "0B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F61" + "9172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD73" + + "3BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA" + "886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C0238" + + "61B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91C" + "AEFE130985139270B4130C93BC437944F4FD4452E2D74DD3" + + "64F2E21E71F54BFF5CAE82AB9C9DF69EE86D2BC522363A0D" + "ABC521979B0DEADA1DBF9A42D5C4484E0ABCD06BFA53DDEF" + + "3C1B20EE3FD59D7C25E41D2B66C62E37FFFFFFFFFFFFFFFF"; + private static readonly int rfc7919_ffdhe3072_l = System.Math.Max(275, 128 * 2); // MAX(RFC7919,FIPS) + public static readonly DHGroup rfc7919_ffdhe3072 = SafePrimeGen2(rfc7919_ffdhe3072_p, rfc7919_ffdhe3072_l); + + private static readonly string rfc7919_ffdhe4096_p = "FFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1" + + "D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF9" + "7D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD6561" + + "2433F51F5F066ED0856365553DED1AF3B557135E7F57C935" + "984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE735" + + "30ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FB" + "B96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB19" + + "0B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F61" + "9172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD73" + + "3BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA" + "886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C0238" + + "61B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91C" + "AEFE130985139270B4130C93BC437944F4FD4452E2D74DD3" + + "64F2E21E71F54BFF5CAE82AB9C9DF69EE86D2BC522363A0D" + "ABC521979B0DEADA1DBF9A42D5C4484E0ABCD06BFA53DDEF" + + "3C1B20EE3FD59D7C25E41D2B669E1EF16E6F52C3164DF4FB" + "7930E9E4E58857B6AC7D5F42D69F6D187763CF1D55034004" + + "87F55BA57E31CC7A7135C886EFB4318AED6A1E012D9E6832" + "A907600A918130C46DC778F971AD0038092999A333CB8B7A" + + "1A1DB93D7140003C2A4ECEA9F98D0ACC0A8291CDCEC97DCF" + "8EC9B55A7F88A46B4DB5A851F44182E1C68A007E5E655F6A" + + "FFFFFFFFFFFFFFFF"; + private static readonly int rfc7919_ffdhe4096_l = System.Math.Max(325, 152 * 2); // MAX(RFC7919,FIPS) + public static readonly DHGroup rfc7919_ffdhe4096 = SafePrimeGen2(rfc7919_ffdhe4096_p, rfc7919_ffdhe4096_l); + + private static readonly string rfc7919_ffdhe6144_p = "FFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1" + + "D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF9" + "7D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD6561" + + "2433F51F5F066ED0856365553DED1AF3B557135E7F57C935" + "984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE735" + + "30ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FB" + "B96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB19" + + "0B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F61" + "9172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD73" + + "3BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA" + "886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C0238" + + "61B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91C" + "AEFE130985139270B4130C93BC437944F4FD4452E2D74DD3" + + "64F2E21E71F54BFF5CAE82AB9C9DF69EE86D2BC522363A0D" + "ABC521979B0DEADA1DBF9A42D5C4484E0ABCD06BFA53DDEF" + + "3C1B20EE3FD59D7C25E41D2B669E1EF16E6F52C3164DF4FB" + "7930E9E4E58857B6AC7D5F42D69F6D187763CF1D55034004" + + "87F55BA57E31CC7A7135C886EFB4318AED6A1E012D9E6832" + "A907600A918130C46DC778F971AD0038092999A333CB8B7A" + + "1A1DB93D7140003C2A4ECEA9F98D0ACC0A8291CDCEC97DCF" + "8EC9B55A7F88A46B4DB5A851F44182E1C68A007E5E0DD902" + + "0BFD64B645036C7A4E677D2C38532A3A23BA4442CAF53EA6" + "3BB454329B7624C8917BDD64B1C0FD4CB38E8C334C701C3A" + + "CDAD0657FCCFEC719B1F5C3E4E46041F388147FB4CFDB477" + "A52471F7A9A96910B855322EDB6340D8A00EF092350511E3" + + "0ABEC1FFF9E3A26E7FB29F8C183023C3587E38DA0077D9B4" + "763E4E4B94B2BBC194C6651E77CAF992EEAAC0232A281BF6" + + "B3A739C1226116820AE8DB5847A67CBEF9C9091B462D538C" + "D72B03746AE77F5E62292C311562A846505DC82DB854338A" + + "E49F5235C95B91178CCF2DD5CACEF403EC9D1810C6272B04" + "5B3B71F9DC6B80D63FDD4A8E9ADB1E6962A69526D43161C1" + + "A41D570D7938DAD4A40E329CD0E40E65FFFFFFFFFFFFFFFF"; + private static readonly int rfc7919_ffdhe6144_l = System.Math.Max(375, 176 * 2); // MAX(RFC7919,FIPS) + public static readonly DHGroup rfc7919_ffdhe6144 = SafePrimeGen2(rfc7919_ffdhe6144_p, rfc7919_ffdhe6144_l); + + private static readonly string rfc7919_ffdhe8192_p = "FFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1" + + "D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF9" + "7D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD6561" + + "2433F51F5F066ED0856365553DED1AF3B557135E7F57C935" + "984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE735" + + "30ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FB" + "B96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB19" + + "0B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F61" + "9172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD73" + + "3BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA" + "886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C0238" + + "61B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91C" + "AEFE130985139270B4130C93BC437944F4FD4452E2D74DD3" + + "64F2E21E71F54BFF5CAE82AB9C9DF69EE86D2BC522363A0D" + "ABC521979B0DEADA1DBF9A42D5C4484E0ABCD06BFA53DDEF" + + "3C1B20EE3FD59D7C25E41D2B669E1EF16E6F52C3164DF4FB" + "7930E9E4E58857B6AC7D5F42D69F6D187763CF1D55034004" + + "87F55BA57E31CC7A7135C886EFB4318AED6A1E012D9E6832" + "A907600A918130C46DC778F971AD0038092999A333CB8B7A" + + "1A1DB93D7140003C2A4ECEA9F98D0ACC0A8291CDCEC97DCF" + "8EC9B55A7F88A46B4DB5A851F44182E1C68A007E5E0DD902" + + "0BFD64B645036C7A4E677D2C38532A3A23BA4442CAF53EA6" + "3BB454329B7624C8917BDD64B1C0FD4CB38E8C334C701C3A" + + "CDAD0657FCCFEC719B1F5C3E4E46041F388147FB4CFDB477" + "A52471F7A9A96910B855322EDB6340D8A00EF092350511E3" + + "0ABEC1FFF9E3A26E7FB29F8C183023C3587E38DA0077D9B4" + "763E4E4B94B2BBC194C6651E77CAF992EEAAC0232A281BF6" + + "B3A739C1226116820AE8DB5847A67CBEF9C9091B462D538C" + "D72B03746AE77F5E62292C311562A846505DC82DB854338A" + + "E49F5235C95B91178CCF2DD5CACEF403EC9D1810C6272B04" + "5B3B71F9DC6B80D63FDD4A8E9ADB1E6962A69526D43161C1" + + "A41D570D7938DAD4A40E329CCFF46AAA36AD004CF600C838" + "1E425A31D951AE64FDB23FCEC9509D43687FEB69EDD1CC5E" + + "0B8CC3BDF64B10EF86B63142A3AB8829555B2F747C932665" + "CB2C0F1CC01BD70229388839D2AF05E454504AC78B758282" + + "2846C0BA35C35F5C59160CC046FD8251541FC68C9C86B022" + "BB7099876A460E7451A8A93109703FEE1C217E6C3826E52C" + + "51AA691E0E423CFC99E9E31650C1217B624816CDAD9A95F9" + "D5B8019488D9C0A0A1FE3075A577E23183F81D4A3F2FA457" + + "1EFC8CE0BA8A4FE8B6855DFE72B0A66EDED2FBABFBE58A30" + "FAFABE1C5D71A87E2F741EF8C1FE86FEA6BBFDE530677F0D" + + "97D11D49F7A8443D0822E506A9F4614E011E2A94838FF88C" + "D68C8BB7C5C6424CFFFFFFFFFFFFFFFF"; + private static readonly int rfc7919_ffdhe8192_l = System.Math.Max(400, 200 * 2); // MAX(RFC7919,FIPS) + public static readonly DHGroup rfc7919_ffdhe8192 = SafePrimeGen2(rfc7919_ffdhe8192_p, rfc7919_ffdhe8192_l); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/DHStandardGroups.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/DHStandardGroups.cs.meta new file mode 100644 index 0000000..853b4a5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/DHStandardGroups.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1f86484e280e6c9409c9f73b837af704 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/Srp6Group.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/Srp6Group.cs new file mode 100644 index 0000000..dae4ca1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/Srp6Group.cs @@ -0,0 +1,31 @@ +using System; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Tls.Crypto +{ + /// Carrier class for SRP-6 group parameters. + public class Srp6Group + { + private readonly BigInteger n, g; + + /// Base constructor. + /// the n value. + /// the g value. + public Srp6Group(BigInteger n, BigInteger g) + { + this.n = n; + this.g = g; + } + + public virtual BigInteger G + { + get { return g; } + } + + public virtual BigInteger N + { + get { return n; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/Srp6Group.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/Srp6Group.cs.meta new file mode 100644 index 0000000..83ff718 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/Srp6Group.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4bc1600b0b40e8f4cbbc8f792389e763 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/Srp6StandardGroups.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/Srp6StandardGroups.cs new file mode 100644 index 0000000..371079c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/Srp6StandardGroups.cs @@ -0,0 +1,159 @@ +using System; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Tls.Crypto +{ + /// A selection of standard groups for SRP-6. + public class Srp6StandardGroups + { + private static BigInteger FromHex(string hex) + { + return new BigInteger(1, Hex.DecodeStrict(hex)); + } + + private static Srp6Group FromNG(string hexN, string hexG) + { + return new Srp6Group(FromHex(hexN), FromHex(hexG)); + } + + /* + * RFC 5054 + */ + private static readonly string rfc5054_1024_N = "EEAF0AB9ADB38DD69C33F80AFA8FC5E86072618775FF3C0B9EA2314C" + + "9C256576D674DF7496EA81D3383B4813D692C6E0E0D5D8E250B98BE4" + + "8E495C1D6089DAD15DC7D7B46154D6B6CE8EF4AD69B15D4982559B29" + + "7BCF1885C529F566660E57EC68EDBC3C05726CC02FD4CBF4976EAA9A" + "FD5138FE8376435B9FC61D2FC0EB06E3"; + private static readonly string rfc5054_1024_g = "02"; + public static readonly Srp6Group rfc5054_1024 = FromNG(rfc5054_1024_N, rfc5054_1024_g); + + private static readonly string rfc5054_1536_N = "9DEF3CAFB939277AB1F12A8617A47BBBDBA51DF499AC4C80BEEEA961" + + "4B19CC4D5F4F5F556E27CBDE51C6A94BE4607A291558903BA0D0F843" + + "80B655BB9A22E8DCDF028A7CEC67F0D08134B1C8B97989149B609E0B" + + "E3BAB63D47548381DBC5B1FC764E3F4B53DD9DA1158BFD3E2B9C8CF5" + + "6EDF019539349627DB2FD53D24B7C48665772E437D6C7F8CE442734A" + + "F7CCB7AE837C264AE3A9BEB87F8A2FE9B8B5292E5A021FFF5E91479E" + + "8CE7A28C2442C6F315180F93499A234DCF76E3FED135F9BB"; + private static readonly string rfc5054_1536_g = "02"; + public static readonly Srp6Group rfc5054_1536 = FromNG(rfc5054_1536_N, rfc5054_1536_g); + + private static readonly string rfc5054_2048_N = "AC6BDB41324A9A9BF166DE5E1389582FAF72B6651987EE07FC319294" + + "3DB56050A37329CBB4A099ED8193E0757767A13DD52312AB4B03310D" + + "CD7F48A9DA04FD50E8083969EDB767B0CF6095179A163AB3661A05FB" + + "D5FAAAE82918A9962F0B93B855F97993EC975EEAA80D740ADBF4FF74" + + "7359D041D5C33EA71D281E446B14773BCA97B43A23FB801676BD207A" + + "436C6481F1D2B9078717461A5B9D32E688F87748544523B524B0D57D" + + "5EA77A2775D2ECFA032CFBDBF52FB3786160279004E57AE6AF874E73" + + "03CE53299CCC041C7BC308D82A5698F3A8D0C38271AE35F8E9DBFBB6" + + "94B5C803D89F7AE435DE236D525F54759B65E372FCD68EF20FA7111F" + "9E4AFF73"; + private static readonly string rfc5054_2048_g = "02"; + public static readonly Srp6Group rfc5054_2048 = FromNG(rfc5054_2048_N, rfc5054_2048_g); + + private static readonly string rfc5054_3072_N = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E08" + + "8A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B" + + "302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9" + + "A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE6" + + "49286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8" + + "FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D" + + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C" + + "180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718" + + "3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D" + + "04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7D" + + "B3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D226" + + "1AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200C" + + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFC" + "E0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF"; + private static readonly string rfc5054_3072_g = "05"; + public static readonly Srp6Group rfc5054_3072 = FromNG(rfc5054_3072_N, rfc5054_3072_g); + + private static readonly string rfc5054_4096_N = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E08" + + "8A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B" + + "302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9" + + "A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE6" + + "49286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8" + + "FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D" + + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C" + + "180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718" + + "3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D" + + "04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7D" + + "B3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D226" + + "1AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200C" + + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFC" + + "E0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B26" + + "99C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB" + + "04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2" + + "233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127" + + "D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199" + "FFFFFFFFFFFFFFFF"; + private static readonly string rfc5054_4096_g = "05"; + public static readonly Srp6Group rfc5054_4096 = FromNG(rfc5054_4096_N, rfc5054_4096_g); + + private static readonly string rfc5054_6144_N = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E08" + + "8A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B" + + "302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9" + + "A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE6" + + "49286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8" + + "FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D" + + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C" + + "180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718" + + "3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D" + + "04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7D" + + "B3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D226" + + "1AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200C" + + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFC" + + "E0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B26" + + "99C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB" + + "04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2" + + "233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127" + + "D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492" + + "36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BDF8FF9406" + + "AD9E530EE5DB382F413001AEB06A53ED9027D831179727B0865A8918" + + "DA3EDBEBCF9B14ED44CE6CBACED4BB1BDB7F1447E6CC254B33205151" + + "2BD7AF426FB8F401378CD2BF5983CA01C64B92ECF032EA15D1721D03" + + "F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E59E7C97F" + + "BEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA" + + "CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58B" + + "B7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632" + + "387FE8D76E3C0468043E8F663F4860EE12BF2D5B0B7474D6E694F91E" + "6DCC4024FFFFFFFFFFFFFFFF"; + private static readonly string rfc5054_6144_g = "05"; + public static readonly Srp6Group rfc5054_6144 = FromNG(rfc5054_6144_N, rfc5054_6144_g); + + private static readonly string rfc5054_8192_N = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E08" + + "8A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B" + + "302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9" + + "A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE6" + + "49286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8" + + "FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D" + + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C" + + "180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718" + + "3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D" + + "04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7D" + + "B3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D226" + + "1AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200C" + + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFC" + + "E0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B26" + + "99C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB" + + "04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2" + + "233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127" + + "D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492" + + "36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BDF8FF9406" + + "AD9E530EE5DB382F413001AEB06A53ED9027D831179727B0865A8918" + + "DA3EDBEBCF9B14ED44CE6CBACED4BB1BDB7F1447E6CC254B33205151" + + "2BD7AF426FB8F401378CD2BF5983CA01C64B92ECF032EA15D1721D03" + + "F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E59E7C97F" + + "BEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA" + + "CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58B" + + "B7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632" + + "387FE8D76E3C0468043E8F663F4860EE12BF2D5B0B7474D6E694F91E" + + "6DBE115974A3926F12FEE5E438777CB6A932DF8CD8BEC4D073B931BA" + + "3BC832B68D9DD300741FA7BF8AFC47ED2576F6936BA424663AAB639C" + + "5AE4F5683423B4742BF1C978238F16CBE39D652DE3FDB8BEFC848AD9" + + "22222E04A4037C0713EB57A81A23F0C73473FC646CEA306B4BCBC886" + + "2F8385DDFA9D4B7FA2C087E879683303ED5BDD3A062B3CF5B3A278A6" + + "6D2A13F83F44F82DDF310EE074AB6A364597E899A0255DC164F31CC5" + + "0846851DF9AB48195DED7EA1B1D510BD7EE74D73FAF36BC31ECFA268" + + "359046F4EB879F924009438B481C6CD7889A002ED5EE382BC9190DA6" + + "FC026E479558E4475677E9AA9E3050E2765694DFC81F56E880B96E71" + "60C980DD98EDD3DFFFFFFFFFFFFFFFFF"; + private static readonly string rfc5054_8192_g = "13"; + public static readonly Srp6Group rfc5054_8192 = FromNG(rfc5054_8192_N, rfc5054_8192_g); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/Srp6StandardGroups.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/Srp6StandardGroups.cs.meta new file mode 100644 index 0000000..31cd9f4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/Srp6StandardGroups.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 345679a7713135c4d82144fe80519bab +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsAgreement.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsAgreement.cs new file mode 100644 index 0000000..0635b4e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsAgreement.cs @@ -0,0 +1,24 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Tls.Crypto +{ + /// Base interface for ephemeral key agreement calculator. + public interface TlsAgreement + { + /// Generate an ephemeral key pair, returning the encoding of the public key. + /// a byte encoding of the public key. + /// + byte[] GenerateEphemeral(); + + /// Pass in the public key for the peer to the agreement calculator. + /// a byte encoding of the peer public key. + /// + void ReceivePeerValue(byte[] peerValue); + + /// Calculate the agreed secret based on the calculator's current state. + /// the calculated secret. + /// + TlsSecret CalculateSecret(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsAgreement.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsAgreement.cs.meta new file mode 100644 index 0000000..4a42ab4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsAgreement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dcaf25cb9d5a93e4e9804cd8c901c463 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsCertificate.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsCertificate.cs new file mode 100644 index 0000000..fe507a6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsCertificate.cs @@ -0,0 +1,57 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Tls.Crypto +{ + /// Interface providing the functional representation of a single X.509 certificate. + public interface TlsCertificate + { + /// Return an encryptor based on the public key in this certificate. + /// + /// a based on this certificate's public key. + /// + TlsEncryptor CreateEncryptor(int tlsCertificateRole); + + /// + /// + TlsVerifier CreateVerifier(short signatureAlgorithm); + + /// + /// + TlsVerifier CreateVerifier(int signatureScheme); + + /// + byte[] GetEncoded(); + + /// + byte[] GetExtension(DerObjectIdentifier extensionOid); + + BigInteger SerialNumber { get; } + + /// the OID of this certificate's 'signatureAlgorithm', as a string. + string SigAlgOid { get; } + + /// + Asn1Encodable GetSigAlgParams(); + + /// + /// + short GetLegacySignatureAlgorithm(); + + /// + /// true if (and only if) this certificate can be used to verify the given signature algorithm. + /// + /// + bool SupportsSignatureAlgorithm(short signatureAlgorithm); + + /// + bool SupportsSignatureAlgorithmCA(short signatureAlgorithm); + + /// + /// + TlsCertificate CheckUsageInRole(int tlsCertificateRole); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsCertificate.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsCertificate.cs.meta new file mode 100644 index 0000000..f321674 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsCertificate.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e94ad3beb01200e47887932a9c9271e4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsCertificateRole.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsCertificateRole.cs new file mode 100644 index 0000000..f7d81b1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsCertificateRole.cs @@ -0,0 +1,12 @@ +using System; + +namespace Org.BouncyCastle.Tls.Crypto +{ + public abstract class TlsCertificateRole + { + public const int DH = 1; + public const int ECDH = 2; + public const int RsaEncryption = 3; + public const int Sm2Encryption = 4; + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsCertificateRole.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsCertificateRole.cs.meta new file mode 100644 index 0000000..1a78510 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsCertificateRole.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cb63e45a44a9df5459bf8f92bbe4e512 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsCipher.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsCipher.cs new file mode 100644 index 0000000..4c2147b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsCipher.cs @@ -0,0 +1,61 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Tls.Crypto +{ + /// Base interface for a TLS bulk cipher. + public interface TlsCipher + { + /// Return the maximum input size for a ciphertext given a maximum output size for the plaintext of + /// plaintextLimit bytes. + /// the maximum output size for the plaintext. + /// the maximum input size of the ciphertext for plaintextlimit bytes of output. + int GetCiphertextDecodeLimit(int plaintextLimit); + + /// Return the maximum output size for a ciphertext given an actual input plaintext size of + /// plaintextLength bytes and a maximum input plaintext size of plaintextLimit bytes. + /// the actual input size for the plaintext. + /// the maximum input size for the plaintext. + /// the maximum output size of the ciphertext for plaintextlimit bytes of input. + int GetCiphertextEncodeLimit(int plaintextLength, int plaintextLimit); + + /// Return the maximum size for the plaintext given ciphertextlimit bytes of ciphertext. + /// the maximum number of bytes of ciphertext. + /// the maximum size of the plaintext for ciphertextlimit bytes of input. + int GetPlaintextLimit(int ciphertextLimit); + + /// Encode the passed in plaintext using the current bulk cipher. + /// sequence number of the message represented by plaintext. + /// content type of the message represented by plaintext. + /// used for the record. + /// extra bytes to allocate at start of returned byte array. + /// array holding input plaintext to the cipher. + /// offset into input array the plaintext starts at. + /// length of the plaintext in the array. + /// A containing the result of encoding (after 'headerAllocation' unused + /// bytes). + /// + TlsEncodeResult EncodePlaintext(long seqNo, short contentType, ProtocolVersion recordVersion, + int headerAllocation, byte[] plaintext, int offset, int len); + + /// Decode the passed in ciphertext using the current bulk cipher. + /// sequence number of the message represented by ciphertext. + /// content type used in the record for this message. + /// used for the record. + /// array holding input ciphertext to the cipher. + /// offset into input array the ciphertext starts at. + /// length of the ciphertext in the array. + /// A containing the result of decoding. + /// + TlsDecodeResult DecodeCiphertext(long seqNo, short recordType, ProtocolVersion recordVersion, + byte[] ciphertext, int offset, int len); + + /// + void RekeyDecoder(); + + /// + void RekeyEncoder(); + + bool UsesOpaqueRecordType { get; } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsCipher.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsCipher.cs.meta new file mode 100644 index 0000000..de217d4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsCipher.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6e3b1bd68d6dcd44dae670da8efbbe7a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsCrypto.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsCrypto.cs new file mode 100644 index 0000000..bd003ae --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsCrypto.cs @@ -0,0 +1,181 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Tls.Crypto +{ + /// Service and object creation interface for the primitive types and services that are associated with + /// cryptography in the API. + public interface TlsCrypto + { + /// Return true if this TlsCrypto can perform raw signatures and verifications for all supported + /// algorithms. + /// true if this instance can perform raw signatures and verifications for all supported algorithms, + /// false otherwise. + bool HasAllRawSignatureAlgorithms(); + + /// Return true if this TlsCrypto can support DH key agreement. + /// true if this instance can support DH key agreement, false otherwise. + bool HasDHAgreement(); + + /// Return true if this TlsCrypto can support ECDH key agreement. + /// true if this instance can support ECDH key agreement, false otherwise. + bool HasECDHAgreement(); + + /// Return true if this TlsCrypto can support the passed in block/stream encryption algorithm. + /// + /// the algorithm of interest. + /// true if encryptionAlgorithm is supported, false otherwise. + bool HasEncryptionAlgorithm(int encryptionAlgorithm); + + /// Return true if this TlsCrypto can support the passed in hash algorithm. + /// the algorithm of interest. + /// true if cryptoHashAlgorithm is supported, false otherwise. + bool HasCryptoHashAlgorithm(int cryptoHashAlgorithm); + + /// Return true if this TlsCrypto can support the passed in signature algorithm (not necessarily in + /// combination with EVERY hash algorithm). + /// the algorithm of interest. + /// true if cryptoSignatureAlgorithm is supported, false otherwise. + bool HasCryptoSignatureAlgorithm(int cryptoSignatureAlgorithm); + + /// Return true if this TlsCrypto can support the passed in MAC algorithm. + /// the algorithm of interest. + /// true if macAlgorithm is supported, false otherwise. + bool HasMacAlgorithm(int macAlgorithm); + + /// Return true if this TlsCrypto supports the passed in named group + /// value. + /// true if this instance supports the passed in named group value. + /// + bool HasNamedGroup(int namedGroup); + + /// Return true if this TlsCrypto can support RSA encryption/decryption. + /// true if this instance can support RSA encryption/decryption, false otherwise. + bool HasRsaEncryption(); + + /// Return true if this TlsCrypto can support the passed in signature algorithm (not necessarily in + /// combination with EVERY hash algorithm). + /// true if signatureAlgorithm is supported, false otherwise. + bool HasSignatureAlgorithm(short signatureAlgorithm); + + /// Return true if this TlsCrypto can support the passed in signature algorithm. + /// the algorithm of interest. + /// true if sigAndHashAlgorithm is supported, false otherwise. + bool HasSignatureAndHashAlgorithm(SignatureAndHashAlgorithm sigAndHashAlgorithm); + + /// Return true if this TlsCrypto can support the passed in signature scheme. + /// the scheme of interest. + /// true if signatureScheme is supported, false otherwise. + bool HasSignatureScheme(int signatureScheme); + + /// Return true if this TlsCrypto can support SRP authentication. + /// true if this instance can support SRP authentication, false otherwise. + bool HasSrpAuthentication(); + + /// Create a TlsSecret object based on provided data. + /// the data to base the TlsSecret on. + /// a TlsSecret based on the provided data. + TlsSecret CreateSecret(byte[] data); + + /// Create a TlsSecret object containing a randomly-generated RSA PreMasterSecret + /// the client version to place in the first 2 bytes + /// a TlsSecret containing the PreMasterSecret. + TlsSecret GenerateRsaPreMasterSecret(ProtocolVersion clientVersion); + + /// Return the primary (safest) SecureRandom for this crypto. + /// a SecureRandom suitable for key generation. + SecureRandom SecureRandom { get; } + + /// Create a TlsCertificate from an ASN.1 binary encoding of an X.509 certificate. + /// DER/BER encoding of the certificate of interest. + /// a TlsCertificate. + /// if there is an issue on decoding or constructing the certificate. + TlsCertificate CreateCertificate(byte[] encoding); + + /// Create a cipher for the specified encryption and MAC algorithms. + /// + /// See enumeration classes , for appropriate + /// argument values. + /// + /// context specific parameters. + /// the encryption algorithm to be employed by the cipher. + /// the MAC algorithm to be employed by the cipher. + /// a implementing the encryption and MAC algorithms. + /// + TlsCipher CreateCipher(TlsCryptoParameters cryptoParams, int encryptionAlgorithm, int macAlgorithm); + + /// Create a domain object supporting the domain parameters described in dhConfig. + /// the config describing the DH parameters to use. + /// a TlsDHDomain supporting the parameters in dhConfig. + TlsDHDomain CreateDHDomain(TlsDHConfig dhConfig); + + /// Create a domain object supporting the domain parameters described in ecConfig. + /// the config describing the EC parameters to use. + /// a TlsECDomain supporting the parameters in ecConfig. + TlsECDomain CreateECDomain(TlsECConfig ecConfig); + + /// Adopt the passed in secret, creating a new copy of it. + /// the secret to make a copy of. + /// a TlsSecret based on the original secret. + TlsSecret AdoptSecret(TlsSecret secret); + + /// Create a suitable hash for the hash algorithm identifier passed in. + /// + /// See enumeration class for appropriate argument values. + /// + /// the hash algorithm the hash needs to implement. + /// a . + TlsHash CreateHash(int cryptoHashAlgorithm); + + /// Create a suitable HMAC for the MAC algorithm identifier passed in. + /// + /// See enumeration class for appropriate argument values. + /// + /// the MAC algorithm the HMAC needs to match. + /// a . + TlsHmac CreateHmac(int macAlgorithm); + + /// Create a suitable HMAC using the hash algorithm identifier passed in. + /// + /// See enumeration class for appropriate argument values. + /// + /// the hash algorithm the HMAC should use. + /// a . + TlsHmac CreateHmacForHash(int cryptoHashAlgorithm); + + /// Create a nonce generator. + /// + /// Each call should construct a new generator, and the generator should be returned from this call only after + /// automatically seeding from this 's entropy source, and from the provided additional + /// seed material. The output of each returned generator must be completely independent of the others. + /// + /// context-specific seed material + /// a . + TlsNonceGenerator CreateNonceGenerator(byte[] additionalSeedMaterial); + + /// Create an SRP-6 client. + /// client config. + /// an initialised SRP6 client object. + TlsSrp6Client CreateSrp6Client(TlsSrpConfig srpConfig); + + /// Create an SRP-6 server. + /// server config. + /// the SRP6 verifier value. + /// an initialised SRP6 server object. + TlsSrp6Server CreateSrp6Server(TlsSrpConfig srpConfig, BigInteger srpVerifier); + + /// Create an SRP-6 verifier generator. + /// generator config. + /// an initialized SRP6 verifier generator. + TlsSrp6VerifierGenerator CreateSrp6VerifierGenerator(TlsSrpConfig srpConfig); + + /// Setup an initial "secret" for a chain of HKDF calls (RFC 5869), containing a string of HashLen + /// zeroes. + /// the hash algorithm to instantiate HMAC with. See + /// for values. + TlsSecret HkdfInit(int cryptoHashAlgorithm); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsCrypto.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsCrypto.cs.meta new file mode 100644 index 0000000..c45d217 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsCrypto.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ee5e0f53459e28a4bb5e0c2d0412458c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsCryptoException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsCryptoException.cs new file mode 100644 index 0000000..83c3ef7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsCryptoException.cs @@ -0,0 +1,19 @@ +using System; + +namespace Org.BouncyCastle.Tls.Crypto +{ + /// Basic exception class for crypto services to pass back a cause. + public class TlsCryptoException + : TlsException + { + public TlsCryptoException(string msg) + : base(msg) + { + } + + public TlsCryptoException(string msg, Exception cause) + : base(msg, cause) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsCryptoException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsCryptoException.cs.meta new file mode 100644 index 0000000..0af6422 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsCryptoException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bc405646f936f6649806a390076bc07e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsCryptoParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsCryptoParameters.cs new file mode 100644 index 0000000..008a2dd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsCryptoParameters.cs @@ -0,0 +1,49 @@ +using System; + +namespace Org.BouncyCastle.Tls.Crypto +{ + // TODO[tls-port] Would rather this be sealed + /// Carrier class for context-related parameters needed for creating secrets and ciphers. + public class TlsCryptoParameters + { + private readonly TlsContext m_context; + + /// Base constructor. + /// the context for this parameters object. + public TlsCryptoParameters(TlsContext context) + { + this.m_context = context; + } + + public SecurityParameters SecurityParameters + { + get { return m_context.SecurityParameters; } + } + + public ProtocolVersion ClientVersion + { + get { return m_context.ClientVersion; } + } + + public ProtocolVersion RsaPreMasterSecretVersion + { + get { return m_context.RsaPreMasterSecretVersion; } + } + + // TODO[tls-port] Would rather this be non-virtual + public virtual ProtocolVersion ServerVersion + { + get { return m_context.ServerVersion; } + } + + public bool IsServer + { + get { return m_context.IsServer; } + } + + public TlsNonceGenerator NonceGenerator + { + get { return m_context.NonceGenerator; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsCryptoParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsCryptoParameters.cs.meta new file mode 100644 index 0000000..cac5139 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsCryptoParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 361e9fd46ed0e3b438dc818c5b1a7116 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsCryptoUtilities.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsCryptoUtilities.cs new file mode 100644 index 0000000..a22049e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsCryptoUtilities.cs @@ -0,0 +1,171 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Tls.Crypto +{ + public abstract class TlsCryptoUtilities + { + // "tls13 " + private static readonly byte[] Tls13Prefix = new byte[] { 0x74, 0x6c, 0x73, 0x31, 0x33, 0x20 }; + + public static int GetHash(short hashAlgorithm) + { + switch (hashAlgorithm) + { + case HashAlgorithm.md5: + return CryptoHashAlgorithm.md5; + case HashAlgorithm.sha1: + return CryptoHashAlgorithm.sha1; + case HashAlgorithm.sha224: + return CryptoHashAlgorithm.sha224; + case HashAlgorithm.sha256: + return CryptoHashAlgorithm.sha256; + case HashAlgorithm.sha384: + return CryptoHashAlgorithm.sha384; + case HashAlgorithm.sha512: + return CryptoHashAlgorithm.sha512; + default: + throw new ArgumentException("specified HashAlgorithm invalid: " + HashAlgorithm.GetText(hashAlgorithm)); + } + } + + public static int GetHashForHmac(int macAlgorithm) + { + switch (macAlgorithm) + { + case MacAlgorithm.hmac_md5: + return CryptoHashAlgorithm.md5; + case MacAlgorithm.hmac_sha1: + return CryptoHashAlgorithm.sha1; + case MacAlgorithm.hmac_sha256: + return CryptoHashAlgorithm.sha256; + case MacAlgorithm.hmac_sha384: + return CryptoHashAlgorithm.sha384; + case MacAlgorithm.hmac_sha512: + return CryptoHashAlgorithm.sha512; + default: + throw new ArgumentException("specified MacAlgorithm not an HMAC: " + MacAlgorithm.GetText(macAlgorithm)); + } + } + + public static int GetHashForPrf(int prfAlgorithm) + { + switch (prfAlgorithm) + { + case PrfAlgorithm.ssl_prf_legacy: + case PrfAlgorithm.tls_prf_legacy: + throw new ArgumentException("legacy PRF not a valid algorithm"); + case PrfAlgorithm.tls_prf_sha256: + case PrfAlgorithm.tls13_hkdf_sha256: + return CryptoHashAlgorithm.sha256; + case PrfAlgorithm.tls_prf_sha384: + case PrfAlgorithm.tls13_hkdf_sha384: + return CryptoHashAlgorithm.sha384; + case PrfAlgorithm.tls13_hkdf_sm3: + return CryptoHashAlgorithm.sm3; + default: + throw new ArgumentException("unknown PrfAlgorithm: " + PrfAlgorithm.GetText(prfAlgorithm)); + } + } + + public static int GetHashOutputSize(int cryptoHashAlgorithm) + { + switch (cryptoHashAlgorithm) + { + case CryptoHashAlgorithm.md5: + return 16; + case CryptoHashAlgorithm.sha1: + return 20; + case CryptoHashAlgorithm.sha224: + return 28; + case CryptoHashAlgorithm.sha256: + case CryptoHashAlgorithm.sm3: + return 32; + case CryptoHashAlgorithm.sha384: + return 48; + case CryptoHashAlgorithm.sha512: + return 64; + default: + throw new ArgumentException(); + } + } + + public static int GetSignature(short signatureAlgorithm) + { + switch (signatureAlgorithm) + { + case SignatureAlgorithm.rsa: + return CryptoSignatureAlgorithm.rsa; + case SignatureAlgorithm.dsa: + return CryptoSignatureAlgorithm.dsa; + case SignatureAlgorithm.ecdsa: + return CryptoSignatureAlgorithm.ecdsa; + case SignatureAlgorithm.rsa_pss_rsae_sha256: + return CryptoSignatureAlgorithm.rsa_pss_rsae_sha256; + case SignatureAlgorithm.rsa_pss_rsae_sha384: + return CryptoSignatureAlgorithm.rsa_pss_rsae_sha384; + case SignatureAlgorithm.rsa_pss_rsae_sha512: + return CryptoSignatureAlgorithm.rsa_pss_rsae_sha512; + case SignatureAlgorithm.ed25519: + return CryptoSignatureAlgorithm.ed25519; + case SignatureAlgorithm.ed448: + return CryptoSignatureAlgorithm.ed448; + case SignatureAlgorithm.rsa_pss_pss_sha256: + return CryptoSignatureAlgorithm.rsa_pss_pss_sha256; + case SignatureAlgorithm.rsa_pss_pss_sha384: + return CryptoSignatureAlgorithm.rsa_pss_pss_sha384; + case SignatureAlgorithm.rsa_pss_pss_sha512: + return CryptoSignatureAlgorithm.rsa_pss_pss_sha512; + case SignatureAlgorithm.gostr34102012_256: + return CryptoSignatureAlgorithm.gostr34102012_256; + case SignatureAlgorithm.gostr34102012_512: + return CryptoSignatureAlgorithm.gostr34102012_512; + default: + throw new ArgumentException("specified SignatureAlgorithm invalid: " + + SignatureAlgorithm.GetText(signatureAlgorithm)); + } + } + + /// + public static TlsSecret HkdfExpandLabel(TlsSecret secret, int cryptoHashAlgorithm, string label, + byte[] context, int length) + { + int labelLength = label.Length; + if (labelLength < 1) + throw new TlsFatalAlert(AlertDescription.internal_error); + + int contextLength = context.Length; + int expandedLabelLength = Tls13Prefix.Length + labelLength; + + byte[] hkdfLabel = new byte[2 + (1 + expandedLabelLength) + (1 + contextLength)]; + + // uint16 length + { + TlsUtilities.CheckUint16(length); + TlsUtilities.WriteUint16(length, hkdfLabel, 0); + } + + // opaque label<7..255> + { + TlsUtilities.CheckUint8(expandedLabelLength); + TlsUtilities.WriteUint8(expandedLabelLength, hkdfLabel, 2); + + Array.Copy(Tls13Prefix, 0, hkdfLabel, 2 + 1, Tls13Prefix.Length); + + int labelPos = 2 + (1 + Tls13Prefix.Length); + for (int i = 0; i < labelLength; ++i) + { + char c = label[i]; + hkdfLabel[labelPos + i] = (byte)c; + } + } + + // context + { + TlsUtilities.WriteOpaque8(context, hkdfLabel, 2 + (1 + expandedLabelLength)); + } + + return secret.HkdfExpand(cryptoHashAlgorithm, hkdfLabel, length); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsCryptoUtilities.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsCryptoUtilities.cs.meta new file mode 100644 index 0000000..50f1c27 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsCryptoUtilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f58d6727537afd1439e32f7f34ab51a3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsDHConfig.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsDHConfig.cs new file mode 100644 index 0000000..8ec7030 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsDHConfig.cs @@ -0,0 +1,41 @@ +using System; + +namespace Org.BouncyCastle.Tls.Crypto +{ + /// Basic config for Diffie-Hellman. + public class TlsDHConfig + { + protected readonly DHGroup m_explicitGroup; + protected readonly int m_namedGroup; + protected readonly bool m_padded; + + public TlsDHConfig(DHGroup explicitGroup) + { + this.m_explicitGroup = explicitGroup; + this.m_namedGroup = -1; + this.m_padded = false; + } + + public TlsDHConfig(int namedGroup, bool padded) + { + this.m_explicitGroup = null; + this.m_namedGroup = namedGroup; + this.m_padded = padded; + } + + public virtual DHGroup ExplicitGroup + { + get { return m_explicitGroup; } + } + + public virtual int NamedGroup + { + get { return m_namedGroup; } + } + + public virtual bool IsPadded + { + get { return m_padded; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsDHConfig.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsDHConfig.cs.meta new file mode 100644 index 0000000..c9fd0f7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsDHConfig.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5f5ae8b9837d39a45b415109bfeda23d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsDHDomain.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsDHDomain.cs new file mode 100644 index 0000000..1184412 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsDHDomain.cs @@ -0,0 +1,12 @@ +using System; + +namespace Org.BouncyCastle.Tls.Crypto +{ + /// Domain interface to service factory for creating Diffie-Hellman operators. + public interface TlsDHDomain + { + /// Return an agreement operator suitable for ephemeral Diffie-Hellman. + /// a key agreement operator. + TlsAgreement CreateDH(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsDHDomain.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsDHDomain.cs.meta new file mode 100644 index 0000000..229d8d8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsDHDomain.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 99b26a1d9c6cda74fbfdf7e8d653aaed +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsDecodeResult.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsDecodeResult.cs new file mode 100644 index 0000000..84b911b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsDecodeResult.cs @@ -0,0 +1,19 @@ +using System; + +namespace Org.BouncyCastle.Tls.Crypto +{ + public sealed class TlsDecodeResult + { + public readonly byte[] buf; + public readonly int off, len; + public readonly short contentType; + + public TlsDecodeResult(byte[] buf, int off, int len, short contentType) + { + this.buf = buf; + this.off = off; + this.len = len; + this.contentType = contentType; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsDecodeResult.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsDecodeResult.cs.meta new file mode 100644 index 0000000..9a4cd75 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsDecodeResult.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 31fdbf44326df194a8e8ce4a48ff9eef +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsECConfig.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsECConfig.cs new file mode 100644 index 0000000..156e59d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsECConfig.cs @@ -0,0 +1,22 @@ +using System; + +namespace Org.BouncyCastle.Tls.Crypto +{ + /// Carrier class for Elliptic Curve parameter configuration. + public class TlsECConfig + { + protected readonly int m_namedGroup; + + public TlsECConfig(int namedGroup) + { + this.m_namedGroup = namedGroup; + } + + /// Return the group used. + /// the named group used. + public virtual int NamedGroup + { + get { return m_namedGroup; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsECConfig.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsECConfig.cs.meta new file mode 100644 index 0000000..784f5c1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsECConfig.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fa22493b426a91c409dbb65b13390bd8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsECDomain.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsECDomain.cs new file mode 100644 index 0000000..74567b3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsECDomain.cs @@ -0,0 +1,12 @@ +using System; + +namespace Org.BouncyCastle.Tls.Crypto +{ + /// Domain interface to service factory for creating Elliptic-Curve (EC) based operators. + public interface TlsECDomain + { + /// Return an agreement operator suitable for ephemeral EC Diffie-Hellman. + /// a key agreement operator. + TlsAgreement CreateECDH(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsECDomain.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsECDomain.cs.meta new file mode 100644 index 0000000..1e933af --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsECDomain.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8353b7036bdaad14086b4cf7195aca07 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsEncodeResult.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsEncodeResult.cs new file mode 100644 index 0000000..963e456 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsEncodeResult.cs @@ -0,0 +1,19 @@ +using System; + +namespace Org.BouncyCastle.Tls.Crypto +{ + public sealed class TlsEncodeResult + { + public readonly byte[] buf; + public readonly int off, len; + public readonly short recordType; + + public TlsEncodeResult(byte[] buf, int off, int len, short recordType) + { + this.buf = buf; + this.off = off; + this.len = len; + this.recordType = recordType; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsEncodeResult.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsEncodeResult.cs.meta new file mode 100644 index 0000000..9b9f497 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsEncodeResult.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 612100a810025884a9a0cb1948a31ebe +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsEncryptor.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsEncryptor.cs new file mode 100644 index 0000000..53f1973 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsEncryptor.cs @@ -0,0 +1,17 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Tls.Crypto +{ + /// Base interface for an encryptor. + public interface TlsEncryptor + { + /// Encrypt data from the passed in input array. + /// byte array containing the input data. + /// offset into input where the data starts. + /// the length of the data to encrypt. + /// the encrypted data. + /// + byte[] Encrypt(byte[] input, int inOff, int length); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsEncryptor.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsEncryptor.cs.meta new file mode 100644 index 0000000..1fe8c69 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsEncryptor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: abdb9ff9d520eec41b9f9ea675e63062 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsHash.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsHash.cs new file mode 100644 index 0000000..4732fc2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsHash.cs @@ -0,0 +1,25 @@ +using System; + +namespace Org.BouncyCastle.Tls.Crypto +{ + /// Interface for message digest, or hash, services. + public interface TlsHash + { + /// Update the hash with the passed in input. + /// input array containing the data. + /// offset into the input array the input starts at. + /// the length of the input data. + void Update(byte[] input, int inOff, int length); + + /// Return calculated hash for any input passed in. + /// the hash value. + byte[] CalculateHash(); + + /// Return a clone of this hash object representing its current state. + /// a clone of the current hash. + TlsHash CloneHash(); + + /// Reset the hash underlying this service. + void Reset(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsHash.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsHash.cs.meta new file mode 100644 index 0000000..677b94e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsHash.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d34761815bd69a14b9081a8474914dd1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsHashSink.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsHashSink.cs new file mode 100644 index 0000000..6449674 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsHashSink.cs @@ -0,0 +1,35 @@ +using System; + +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Tls.Crypto +{ + public class TlsHashSink + : BaseOutputStream + { + private readonly TlsHash m_hash; + + public TlsHashSink(TlsHash hash) + { + this.m_hash = hash; + } + + public virtual TlsHash Hash + { + get { return m_hash; } + } + + public override void WriteByte(byte b) + { + m_hash.Update(new byte[] { b }, 0, 1); + } + + public override void Write(byte[] buf, int off, int len) + { + if (len > 0) + { + m_hash.Update(buf, off, len); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsHashSink.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsHashSink.cs.meta new file mode 100644 index 0000000..3b58bd5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsHashSink.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 37a36aa31a0af8445a8b428464d3aa69 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsHmac.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsHmac.cs new file mode 100644 index 0000000..7629548 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsHmac.cs @@ -0,0 +1,13 @@ +using System; + +namespace Org.BouncyCastle.Tls.Crypto +{ + /// Interface for MAC services based on HMAC. + public interface TlsHmac + : TlsMac + { + /// Return the internal block size for the message digest underlying this HMAC service. + /// the internal block size for the digest (in bytes). + int InternalBlockSize { get; } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsHmac.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsHmac.cs.meta new file mode 100644 index 0000000..192d08f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsHmac.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9ed94a61283a86d4595fa80f0ff8ecde +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsMac.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsMac.cs new file mode 100644 index 0000000..f92d946 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsMac.cs @@ -0,0 +1,36 @@ +using System; + +namespace Org.BouncyCastle.Tls.Crypto +{ + /// Interface for MAC services. + public interface TlsMac + { + /// Set the key to be used by the MAC implementation supporting this service. + /// array holding the MAC key. + /// offset into the array the key starts at. + /// length of the key in the array. + void SetKey(byte[] key, int keyOff, int keyLen); + + /// Update the MAC with the passed in input. + /// input array containing the data. + /// offset into the input array the input starts at. + /// the length of the input data. + void Update(byte[] input, int inOff, int length); + + /// Return calculated MAC for any input passed in. + /// the MAC value. + byte[] CalculateMac(); + + /// Write the calculated MAC to an output buffer. + /// output array to write the MAC to. + /// offset into the output array to write the MAC to. + void CalculateMac(byte[] output, int outOff); + + /// Return the length of the MAC generated by this service. + /// the MAC length. + int MacLength { get; } + + /// Reset the MAC underlying this service. + void Reset(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsMac.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsMac.cs.meta new file mode 100644 index 0000000..0e12953 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsMac.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ff8cd6b7fe115cb4b9ef276667b45982 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsMacSink.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsMacSink.cs new file mode 100644 index 0000000..58e65c7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsMacSink.cs @@ -0,0 +1,35 @@ +using System; + +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Tls.Crypto +{ + public class TlsMacSink + : BaseOutputStream + { + private readonly TlsMac m_mac; + + public TlsMacSink(TlsMac mac) + { + this.m_mac = mac; + } + + public virtual TlsMac Mac + { + get { return m_mac; } + } + + public override void WriteByte(byte b) + { + m_mac.Update(new byte[]{ b }, 0, 1); + } + + public override void Write(byte[] buf, int off, int len) + { + if (len > 0) + { + m_mac.Update(buf, off, len); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsMacSink.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsMacSink.cs.meta new file mode 100644 index 0000000..8d0578f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsMacSink.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 558c8afbb5a033e419c40acb8bb319a8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsNonceGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsNonceGenerator.cs new file mode 100644 index 0000000..00cadc7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsNonceGenerator.cs @@ -0,0 +1,12 @@ +using System; + +namespace Org.BouncyCastle.Tls.Crypto +{ + public interface TlsNonceGenerator + { + /// Generate a nonce byte[] string. + /// the length, in bytes, of the nonce to generate. + /// the nonce value. + byte[] GenerateNonce(int size); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsNonceGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsNonceGenerator.cs.meta new file mode 100644 index 0000000..c5d8521 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsNonceGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9a39333327678eb41a70d09aca20a48e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsNullNullCipher.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsNullNullCipher.cs new file mode 100644 index 0000000..082dff3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsNullNullCipher.cs @@ -0,0 +1,55 @@ +using System; + +namespace Org.BouncyCastle.Tls.Crypto +{ + /// The cipher for TLS_NULL_WITH_NULL_NULL. + public sealed class TlsNullNullCipher + : TlsCipher + { + public static readonly TlsNullNullCipher Instance = new TlsNullNullCipher(); + + public int GetCiphertextDecodeLimit(int plaintextLimit) + { + return plaintextLimit; + } + + public int GetCiphertextEncodeLimit(int plaintextLength, int plaintextLimit) + { + return plaintextLength; + } + + public int GetPlaintextLimit(int ciphertextLimit) + { + return ciphertextLimit; + } + + public TlsEncodeResult EncodePlaintext(long seqNo, short contentType, ProtocolVersion recordVersion, + int headerAllocation, byte[] plaintext, int offset, int len) + { + byte[] result = new byte[headerAllocation + len]; + Array.Copy(plaintext, offset, result, headerAllocation, len); + return new TlsEncodeResult(result, 0, result.Length, contentType); + } + + public TlsDecodeResult DecodeCiphertext(long seqNo, short recordType, ProtocolVersion recordVersion, + byte[] ciphertext, int offset, int len) + { + return new TlsDecodeResult(ciphertext, offset, len, recordType); + } + + public void RekeyDecoder() + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public void RekeyEncoder() + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public bool UsesOpaqueRecordType + { + get { return false; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsNullNullCipher.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsNullNullCipher.cs.meta new file mode 100644 index 0000000..a34f585 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsNullNullCipher.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 76f4a0c3c50c63b44815441c00a42846 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsSecret.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsSecret.cs new file mode 100644 index 0000000..8aea34b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsSecret.cs @@ -0,0 +1,68 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Tls.Crypto +{ + /// Interface supporting the generation of key material and other SSL/TLS secret values from PRFs. + /// + public interface TlsSecret + { + /// Calculate an HMAC with this secret's data as the key. + /// the hash algorithm to instantiate HMAC with. See + /// for values. + /// array containing the input data. + /// offset into the input array the input starts at. + /// the length of the input data. + byte[] CalculateHmac(int cryptoHashAlgorithm, byte[] buf, int off, int len); + + /// Return a new secret based on applying a PRF to this one. + /// PRF algorithm to use. + /// the label details. + /// the seed details. + /// the size (in bytes) of the secret to generate. + /// the new secret. + TlsSecret DeriveUsingPrf(int prfAlgorithm, string label, byte[] seed, int length); + + /// Destroy the internal state of the secret. + /// + /// After this call, any attempt to use the will result in an + /// being thrown. + /// + void Destroy(); + + /// Return an encrypted copy of the data this secret is based on. + /// the encryptor to use for protecting the internal data. + /// an encrypted copy of this secret's internal data. + /// + byte[] Encrypt(TlsEncryptor encryptor); + + /// Return the internal data from this secret. + /// + /// The does not keep a copy of the data. After this call, any attempt to use the + /// will result in an being thrown. + /// + /// the secret's internal data. + byte[] Extract(); + + /// RFC 5869 HKDF-Expand function, with this secret's data as the pseudo-random key ('prk'). + /// the hash algorithm to instantiate HMAC with. See + /// for values. + /// optional context and application specific information (can be zero-length). + /// length of output keying material in octets. + /// output keying material (of 'length' octets). + TlsSecret HkdfExpand(int cryptoHashAlgorithm, byte[] info, int length); + + /// RFC 5869 HKDF-Extract function, with this secret's data as the 'salt'. + /// + /// The does not keep a copy of the data. After this call, any attempt to use + /// the will result in an being thrown. + /// + /// the hash algorithm to instantiate HMAC with. See + /// for values. + /// input keying material. + /// a pseudo-random key (of HashLen octets). + TlsSecret HkdfExtract(int cryptoHashAlgorithm, TlsSecret ikm); + + bool IsAlive(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsSecret.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsSecret.cs.meta new file mode 100644 index 0000000..41b41e5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsSecret.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b1c0ae55fcbc0a14eb98cc0c1810ae97 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsSigner.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsSigner.cs new file mode 100644 index 0000000..ffd05d9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsSigner.cs @@ -0,0 +1,19 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Tls.Crypto +{ + /// Base interface for a TLS signer that works on raw message digests. + public interface TlsSigner + { + /// Generate an encoded signature based on the passed in hash. + /// the signature algorithm to use. + /// the hash calculated for the signature. + /// an encoded signature. + /// in case of an exception processing the hash. + byte[] GenerateRawSignature(SignatureAndHashAlgorithm algorithm, byte[] hash); + + /// + TlsStreamSigner GetStreamSigner(SignatureAndHashAlgorithm algorithm); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsSigner.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsSigner.cs.meta new file mode 100644 index 0000000..2bc828d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsSigner.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 85331a7659db2384c8b6c7a111241678 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsSrp6Client.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsSrp6Client.cs new file mode 100644 index 0000000..e2b545a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsSrp6Client.cs @@ -0,0 +1,24 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Tls.Crypto +{ + /// Basic interface for an SRP-6 client implementation. + public interface TlsSrp6Client + { + /// Generates the secret S given the server's credentials + /// The server's credentials + /// Client's verification message for the server + /// If server's credentials are invalid + BigInteger CalculateSecret(BigInteger serverB); + + /// Generates client's credentials given the client's salt, identity and password + /// The salt used in the client's verifier. + /// The user's identity (eg. username) + /// The user's password + /// Client's public value to send to server + BigInteger GenerateClientCredentials(byte[] salt, byte[] identity, byte[] password); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsSrp6Client.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsSrp6Client.cs.meta new file mode 100644 index 0000000..e3ebb8e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsSrp6Client.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9d2bbf09c1920c94c8dd9a315681ba1c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsSrp6Server.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsSrp6Server.cs new file mode 100644 index 0000000..75dc6fc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsSrp6Server.cs @@ -0,0 +1,22 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Tls.Crypto +{ + /// Basic interface for an SRP-6 server implementation. + public interface TlsSrp6Server + { + /// Generates the server's credentials that are to be sent to the client. + /// The server's public value to the client + BigInteger GenerateServerCredentials(); + + /// Processes the client's credentials. If valid the shared secret is generated and returned. + /// + /// The client's credentials. + /// A shared secret . + /// If client's credentials are invalid. + BigInteger CalculateSecret(BigInteger clientA); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsSrp6Server.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsSrp6Server.cs.meta new file mode 100644 index 0000000..48089e3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsSrp6Server.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 452213297542dae40bb8bf6f30dcf06b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsSrp6VerifierGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsSrp6VerifierGenerator.cs new file mode 100644 index 0000000..238de98 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsSrp6VerifierGenerator.cs @@ -0,0 +1,17 @@ +using System; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Tls.Crypto +{ + /// Base interface for a generator for SRP-6 verifiers. + public interface TlsSrp6VerifierGenerator + { + /// Creates a new SRP-6 verifier value. + /// The salt to use, generally should be large and random + /// The user's identifying information (eg. username) + /// The user's password + /// A new verifier for use in future SRP authentication + BigInteger GenerateVerifier(byte[] salt, byte[] identity, byte[] password); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsSrp6VerifierGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsSrp6VerifierGenerator.cs.meta new file mode 100644 index 0000000..5ed0da7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsSrp6VerifierGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 258cbb1e39331f340bd41cde53bbe103 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsSrpConfig.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsSrpConfig.cs new file mode 100644 index 0000000..e31e4a5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsSrpConfig.cs @@ -0,0 +1,26 @@ +using System; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Tls.Crypto +{ + /// Basic config for SRP. + public class TlsSrpConfig + { + protected BigInteger[] m_explicitNG; + + /// Return the (N, g) values used in SRP-6. + /// (N, g) as a BigInteger array (N=[0], g=[1]). + public BigInteger[] GetExplicitNG() + { + return (BigInteger[])m_explicitNG.Clone(); + } + + /// Set the (N, g) values used for SRP-6. + /// (N, g) as a BigInteger array (N=[0], g=[1]). + public void SetExplicitNG(BigInteger[] explicitNG) + { + this.m_explicitNG = (BigInteger[])explicitNG.Clone(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsSrpConfig.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsSrpConfig.cs.meta new file mode 100644 index 0000000..42d4b8a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsSrpConfig.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c210da887aa66234d9e1862c79d2e520 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsStreamSigner.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsStreamSigner.cs new file mode 100644 index 0000000..8f79346 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsStreamSigner.cs @@ -0,0 +1,14 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Tls.Crypto +{ + public interface TlsStreamSigner + { + /// + Stream GetOutputStream(); + + /// + byte[] GetSignature(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsStreamSigner.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsStreamSigner.cs.meta new file mode 100644 index 0000000..189df63 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsStreamSigner.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 084f47f7af56a674db023c8abe71a8a5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsStreamVerifier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsStreamVerifier.cs new file mode 100644 index 0000000..9d18a9c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsStreamVerifier.cs @@ -0,0 +1,14 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Tls.Crypto +{ + public interface TlsStreamVerifier + { + /// + Stream GetOutputStream(); + + /// + bool IsVerified(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsStreamVerifier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsStreamVerifier.cs.meta new file mode 100644 index 0000000..d9a62ac --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsStreamVerifier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3db874fe8c389bc439fe1599f2ffb476 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsVerifier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsVerifier.cs new file mode 100644 index 0000000..ad2ddbc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsVerifier.cs @@ -0,0 +1,20 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Tls.Crypto +{ + /// Base interface for a TLS verifier that works with signatures and either raw message digests, or entire + /// messages. + public interface TlsVerifier + { + /// + TlsStreamVerifier GetStreamVerifier(DigitallySigned signature); + + /// Return true if the passed in signature and hash represent a real signature. + /// the signature object containing the signature to be verified. + /// the hash calculated for the signature. + /// true if signature verifies, false otherwise. + /// in case of an exception verifying signature. + bool VerifyRawSignature(DigitallySigned signature, byte[] hash); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsVerifier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsVerifier.cs.meta new file mode 100644 index 0000000..d839307 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/TlsVerifier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6fda44b335de50b4f814e0c80eeabb1a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl.meta new file mode 100644 index 0000000..43a30a7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a2fbe6b4920def44897525e1b1b60f6d +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/AbstractTlsCrypto.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/AbstractTlsCrypto.cs new file mode 100644 index 0000000..0a634ff --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/AbstractTlsCrypto.cs @@ -0,0 +1,84 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls.Crypto.Impl +{ + /// Base class for a TlsCrypto implementation that provides some needed methods from elsewhere in the impl + /// package. + public abstract class AbstractTlsCrypto + : TlsCrypto + { + public abstract bool HasAllRawSignatureAlgorithms(); + + public abstract bool HasDHAgreement(); + + public abstract bool HasECDHAgreement(); + + public abstract bool HasEncryptionAlgorithm(int encryptionAlgorithm); + + public abstract bool HasCryptoHashAlgorithm(int cryptoHashAlgorithm); + + public abstract bool HasCryptoSignatureAlgorithm(int cryptoSignatureAlgorithm); + + public abstract bool HasMacAlgorithm(int macAlgorithm); + + public abstract bool HasNamedGroup(int namedGroup); + + public abstract bool HasRsaEncryption(); + + public abstract bool HasSignatureAlgorithm(short signatureAlgorithm); + + public abstract bool HasSignatureAndHashAlgorithm(SignatureAndHashAlgorithm sigAndHashAlgorithm); + + public abstract bool HasSignatureScheme(int signatureScheme); + + public abstract bool HasSrpAuthentication(); + + public abstract TlsSecret CreateSecret(byte[] data); + + public abstract TlsSecret GenerateRsaPreMasterSecret(ProtocolVersion clientVersion); + + public abstract SecureRandom SecureRandom { get; } + + public abstract TlsCertificate CreateCertificate(byte[] encoding); + + public abstract TlsCipher CreateCipher(TlsCryptoParameters cryptoParams, int encryptionAlgorithm, int macAlgorithm); + + public abstract TlsDHDomain CreateDHDomain(TlsDHConfig dhConfig); + + public abstract TlsECDomain CreateECDomain(TlsECConfig ecConfig); + + public virtual TlsSecret AdoptSecret(TlsSecret secret) + { + // TODO[tls] Need an alternative that doesn't require AbstractTlsSecret (which holds literal data) + if (secret is AbstractTlsSecret) + { + AbstractTlsSecret sec = (AbstractTlsSecret)secret; + + return CreateSecret(sec.CopyData()); + } + + throw new ArgumentException("unrecognized TlsSecret - cannot copy data: " + Platform.GetTypeName(secret)); + } + + public abstract TlsHash CreateHash(int cryptoHashAlgorithm); + + public abstract TlsHmac CreateHmac(int macAlgorithm); + + public abstract TlsHmac CreateHmacForHash(int cryptoHashAlgorithm); + + public abstract TlsNonceGenerator CreateNonceGenerator(byte[] additionalSeedMaterial); + + public abstract TlsSrp6Client CreateSrp6Client(TlsSrpConfig srpConfig); + + public abstract TlsSrp6Server CreateSrp6Server(TlsSrpConfig srpConfig, BigInteger srpVerifier); + + public abstract TlsSrp6VerifierGenerator CreateSrp6VerifierGenerator(TlsSrpConfig srpConfig); + + public abstract TlsSecret HkdfInit(int cryptoHashAlgorithm); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/AbstractTlsCrypto.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/AbstractTlsCrypto.cs.meta new file mode 100644 index 0000000..7ccf40c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/AbstractTlsCrypto.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cb0430616931d5a438cb29fdf3b1e13b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/AbstractTlsSecret.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/AbstractTlsSecret.cs new file mode 100644 index 0000000..cc07f97 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/AbstractTlsSecret.cs @@ -0,0 +1,105 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls.Crypto.Impl +{ + /// Base class for a TlsSecret implementation which captures common code and fields. + public abstract class AbstractTlsSecret + : TlsSecret + { + protected static byte[] CopyData(AbstractTlsSecret other) + { + return other.CopyData(); + } + + protected byte[] m_data; + + /// Base constructor. + /// the byte[] making up the secret value. + protected AbstractTlsSecret(byte[] data) + { + this.m_data = data; + } + + protected virtual void CheckAlive() + { + if (m_data == null) + throw new InvalidOperationException("Secret has already been extracted or destroyed"); + } + + protected abstract AbstractTlsCrypto Crypto { get; } + + public virtual byte[] CalculateHmac(int cryptoHashAlgorithm, byte[] buf, int off, int len) + { + lock (this) + { + CheckAlive(); + + TlsHmac hmac = Crypto.CreateHmacForHash(cryptoHashAlgorithm); + hmac.SetKey(m_data, 0, m_data.Length); + hmac.Update(buf, off, len); + return hmac.CalculateMac(); + } + } + + public abstract TlsSecret DeriveUsingPrf(int prfAlgorithm, string label, byte[] seed, int length); + + public virtual void Destroy() + { + lock (this) + { + if (m_data != null) + { + // TODO Is there a way to ensure the data is really overwritten? + Array.Clear(m_data, 0, m_data.Length); + this.m_data = null; + } + } + } + + /// + public virtual byte[] Encrypt(TlsEncryptor encryptor) + { + lock (this) + { + CheckAlive(); + + return encryptor.Encrypt(m_data, 0, m_data.Length); + } + } + + public virtual byte[] Extract() + { + lock (this) + { + CheckAlive(); + + byte[] result = m_data; + this.m_data = null; + return result; + } + } + + public abstract TlsSecret HkdfExpand(int cryptoHashAlgorithm, byte[] info, int length); + + public abstract TlsSecret HkdfExtract(int cryptoHashAlgorithm, TlsSecret ikm); + + public virtual bool IsAlive() + { + lock (this) + { + return null != m_data; + } + } + + internal virtual byte[] CopyData() + { + lock (this) + { + return Arrays.Clone(m_data); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/AbstractTlsSecret.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/AbstractTlsSecret.cs.meta new file mode 100644 index 0000000..4e11dee --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/AbstractTlsSecret.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 847fa9401b1469d4587c19a926f5582c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/RsaUtilities.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/RsaUtilities.cs new file mode 100644 index 0000000..83782a2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/RsaUtilities.cs @@ -0,0 +1,136 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls.Crypto.Impl +{ + public abstract class RsaUtilities + { + private static readonly byte[] RSAPSSParams_256_A, RSAPSSParams_384_A, RSAPSSParams_512_A; + private static readonly byte[] RSAPSSParams_256_B, RSAPSSParams_384_B, RSAPSSParams_512_B; + + static RsaUtilities() + { + /* + * RFC 4055 + */ + + AlgorithmIdentifier sha256Identifier_A = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha256); + AlgorithmIdentifier sha384Identifier_A = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha384); + AlgorithmIdentifier sha512Identifier_A = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha512); + AlgorithmIdentifier sha256Identifier_B = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha256, DerNull.Instance); + AlgorithmIdentifier sha384Identifier_B = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha384, DerNull.Instance); + AlgorithmIdentifier sha512Identifier_B = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha512, DerNull.Instance); + + AlgorithmIdentifier mgf1SHA256Identifier_A = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, sha256Identifier_A); + AlgorithmIdentifier mgf1SHA384Identifier_A = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, sha384Identifier_A); + AlgorithmIdentifier mgf1SHA512Identifier_A = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, sha512Identifier_A); + AlgorithmIdentifier mgf1SHA256Identifier_B = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, sha256Identifier_B); + AlgorithmIdentifier mgf1SHA384Identifier_B = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, sha384Identifier_B); + AlgorithmIdentifier mgf1SHA512Identifier_B = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, sha512Identifier_B); + + DerInteger sha256Size = new DerInteger(TlsCryptoUtilities.GetHashOutputSize(CryptoHashAlgorithm.sha256)); + DerInteger sha384Size = new DerInteger(TlsCryptoUtilities.GetHashOutputSize(CryptoHashAlgorithm.sha384)); + DerInteger sha512Size = new DerInteger(TlsCryptoUtilities.GetHashOutputSize(CryptoHashAlgorithm.sha512)); + + DerInteger trailerField = new DerInteger(1); + + try + { + RSAPSSParams_256_A = new RsassaPssParameters(sha256Identifier_A, mgf1SHA256Identifier_A, sha256Size, trailerField) + .GetEncoded(Asn1Encodable.Der); + RSAPSSParams_384_A = new RsassaPssParameters(sha384Identifier_A, mgf1SHA384Identifier_A, sha384Size, trailerField) + .GetEncoded(Asn1Encodable.Der); + RSAPSSParams_512_A = new RsassaPssParameters(sha512Identifier_A, mgf1SHA512Identifier_A, sha512Size, trailerField) + .GetEncoded(Asn1Encodable.Der); + RSAPSSParams_256_B = new RsassaPssParameters(sha256Identifier_B, mgf1SHA256Identifier_B, sha256Size, trailerField) + .GetEncoded(Asn1Encodable.Der); + RSAPSSParams_384_B = new RsassaPssParameters(sha384Identifier_B, mgf1SHA384Identifier_B, sha384Size, trailerField) + .GetEncoded(Asn1Encodable.Der); + RSAPSSParams_512_B = new RsassaPssParameters(sha512Identifier_B, mgf1SHA512Identifier_B, sha512Size, trailerField) + .GetEncoded(Asn1Encodable.Der); + } + catch (IOException e) + { + throw new InvalidOperationException(e.Message); + } + } + + public static bool SupportsPkcs1(AlgorithmIdentifier pubKeyAlgID) + { + DerObjectIdentifier oid = pubKeyAlgID.Algorithm; + return PkcsObjectIdentifiers.RsaEncryption.Equals(oid) + || X509ObjectIdentifiers.IdEARsa.Equals(oid); + } + + public static bool SupportsPss_Pss(short signatureAlgorithm, AlgorithmIdentifier pubKeyAlgID) + { + DerObjectIdentifier oid = pubKeyAlgID.Algorithm; + if (!PkcsObjectIdentifiers.IdRsassaPss.Equals(oid)) + return false; + + /* + * TODO ASN.1 NULL shouldn't really be allowed here; it's a workaround for e.g. Oracle JDK + * 1.8.0_241, where the X.509 certificate implementation adds the NULL when re-encoding the + * original parameters. It appears it was fixed at some later date (OpenJDK 12.0.2 does not + * have the issue), but not sure exactly when. + */ + Asn1Encodable pssParams = pubKeyAlgID.Parameters; + if (null == pssParams || pssParams is DerNull) + { + switch (signatureAlgorithm) + { + case SignatureAlgorithm.rsa_pss_pss_sha256: + case SignatureAlgorithm.rsa_pss_pss_sha384: + case SignatureAlgorithm.rsa_pss_pss_sha512: + return true; + default: + return false; + } + } + + byte[] encoded; + try + { + encoded = pssParams.ToAsn1Object().GetEncoded(Asn1Encodable.Der); + } + catch (Exception) + { + return false; + } + + byte[] expected_A, expected_B; + switch (signatureAlgorithm) + { + case SignatureAlgorithm.rsa_pss_pss_sha256: + expected_A = RSAPSSParams_256_A; + expected_B = RSAPSSParams_256_B; + break; + case SignatureAlgorithm.rsa_pss_pss_sha384: + expected_A = RSAPSSParams_384_A; + expected_B = RSAPSSParams_384_B; + break; + case SignatureAlgorithm.rsa_pss_pss_sha512: + expected_A = RSAPSSParams_512_A; + expected_B = RSAPSSParams_512_B; + break; + default: + return false; + } + + return Arrays.AreEqual(expected_A, encoded) + || Arrays.AreEqual(expected_B, encoded); + } + + public static bool SupportsPss_Rsae(AlgorithmIdentifier pubKeyAlgID) + { + DerObjectIdentifier oid = pubKeyAlgID.Algorithm; + return PkcsObjectIdentifiers.RsaEncryption.Equals(oid); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/RsaUtilities.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/RsaUtilities.cs.meta new file mode 100644 index 0000000..c315596 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/RsaUtilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ca9a3d76ef0104f47a48e56a2060e1d5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/TlsAeadCipher.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/TlsAeadCipher.cs new file mode 100644 index 0000000..ec76e98 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/TlsAeadCipher.cs @@ -0,0 +1,377 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Tls.Crypto.Impl +{ + /// A generic TLS 1.2 AEAD cipher. + public class TlsAeadCipher + : TlsCipher + { + public const int AEAD_CCM = 1; + public const int AEAD_CHACHA20_POLY1305 = 2; + public const int AEAD_GCM = 3; + + private const int NONCE_RFC5288 = 1; + private const int NONCE_RFC7905 = 2; + + protected readonly TlsCryptoParameters m_cryptoParams; + protected readonly int m_keySize; + protected readonly int m_macSize; + protected readonly int m_fixed_iv_length; + protected readonly int m_record_iv_length; + + protected readonly TlsAeadCipherImpl m_decryptCipher, m_encryptCipher; + protected readonly byte[] m_decryptNonce, m_encryptNonce; + + protected readonly bool m_isTlsV13; + protected readonly int m_nonceMode; + + /// + public TlsAeadCipher(TlsCryptoParameters cryptoParams, TlsAeadCipherImpl encryptCipher, + TlsAeadCipherImpl decryptCipher, int keySize, int macSize, int aeadType) + { + SecurityParameters securityParameters = cryptoParams.SecurityParameters; + ProtocolVersion negotiatedVersion = securityParameters.NegotiatedVersion; + + if (!TlsImplUtilities.IsTlsV12(negotiatedVersion)) + throw new TlsFatalAlert(AlertDescription.internal_error); + + this.m_isTlsV13 = TlsImplUtilities.IsTlsV13(negotiatedVersion); + this.m_nonceMode = GetNonceMode(m_isTlsV13, aeadType); + + switch (m_nonceMode) + { + case NONCE_RFC5288: + this.m_fixed_iv_length = 4; + this.m_record_iv_length = 8; + break; + case NONCE_RFC7905: + this.m_fixed_iv_length = 12; + this.m_record_iv_length = 0; + break; + default: + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + this.m_cryptoParams = cryptoParams; + this.m_keySize = keySize; + this.m_macSize = macSize; + + this.m_decryptCipher = decryptCipher; + this.m_encryptCipher = encryptCipher; + + this.m_decryptNonce = new byte[m_fixed_iv_length]; + this.m_encryptNonce = new byte[m_fixed_iv_length]; + + bool isServer = cryptoParams.IsServer; + if (m_isTlsV13) + { + RekeyCipher(securityParameters, decryptCipher, m_decryptNonce, !isServer); + RekeyCipher(securityParameters, encryptCipher, m_encryptNonce, isServer); + return; + } + + int keyBlockSize = (2 * keySize) + (2 * m_fixed_iv_length); + byte[] keyBlock = TlsImplUtilities.CalculateKeyBlock(cryptoParams, keyBlockSize); + int pos = 0; + + if (isServer) + { + decryptCipher.SetKey(keyBlock, pos, keySize); pos += keySize; + encryptCipher.SetKey(keyBlock, pos, keySize); pos += keySize; + + Array.Copy(keyBlock, pos, m_decryptNonce, 0, m_fixed_iv_length); pos += m_fixed_iv_length; + Array.Copy(keyBlock, pos, m_encryptNonce, 0, m_fixed_iv_length); pos += m_fixed_iv_length; + } + else + { + encryptCipher.SetKey(keyBlock, pos, keySize); pos += keySize; + decryptCipher.SetKey(keyBlock, pos, keySize); pos += keySize; + + Array.Copy(keyBlock, pos, m_encryptNonce, 0, m_fixed_iv_length); pos += m_fixed_iv_length; + Array.Copy(keyBlock, pos, m_decryptNonce, 0, m_fixed_iv_length); pos += m_fixed_iv_length; + } + + if (keyBlockSize != pos) + throw new TlsFatalAlert(AlertDescription.internal_error); + + int nonceLength = m_fixed_iv_length + m_record_iv_length; + + // NOTE: Ensure dummy nonce is not part of the generated sequence(s) + byte[] dummyNonce = new byte[nonceLength]; + dummyNonce[0] = (byte)~m_encryptNonce[0]; + dummyNonce[1] = (byte)~m_decryptNonce[1]; + + encryptCipher.Init(dummyNonce, macSize, null); + decryptCipher.Init(dummyNonce, macSize, null); + } + + public virtual int GetCiphertextDecodeLimit(int plaintextLimit) + { + return plaintextLimit + m_macSize + m_record_iv_length + (m_isTlsV13 ? 1 : 0); + } + + public virtual int GetCiphertextEncodeLimit(int plaintextLength, int plaintextLimit) + { + int innerPlaintextLimit = plaintextLength; + if (m_isTlsV13) + { + // TODO[tls13] Add support for padding + int maxPadding = 0; + + innerPlaintextLimit = 1 + System.Math.Min(plaintextLimit, plaintextLength + maxPadding); + } + + return innerPlaintextLimit + m_macSize + m_record_iv_length; + } + + public virtual int GetPlaintextLimit(int ciphertextLimit) + { + return ciphertextLimit - m_macSize - m_record_iv_length - (m_isTlsV13 ? 1 : 0); + } + + public virtual TlsEncodeResult EncodePlaintext(long seqNo, short contentType, ProtocolVersion recordVersion, + int headerAllocation, byte[] plaintext, int plaintextOffset, int plaintextLength) + { + byte[] nonce = new byte[m_encryptNonce.Length + m_record_iv_length]; + + switch (m_nonceMode) + { + case NONCE_RFC5288: + Array.Copy(m_encryptNonce, 0, nonce, 0, m_encryptNonce.Length); + // RFC 5288/6655: The nonce_explicit MAY be the 64-bit sequence number. + TlsUtilities.WriteUint64(seqNo, nonce, m_encryptNonce.Length); + break; + case NONCE_RFC7905: + TlsUtilities.WriteUint64(seqNo, nonce, nonce.Length - 8); + for (int i = 0; i < m_encryptNonce.Length; ++i) + { + nonce[i] ^= m_encryptNonce[i]; + } + break; + default: + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + int extraLength = m_isTlsV13 ? 1 : 0; + + // TODO[tls13] If we support adding padding to TLSInnerPlaintext, this will need review + int encryptionLength = m_encryptCipher.GetOutputSize(plaintextLength + extraLength); + int ciphertextLength = m_record_iv_length + encryptionLength; + + byte[] output = new byte[headerAllocation + ciphertextLength]; + int outputPos = headerAllocation; + + if (m_record_iv_length != 0) + { + Array.Copy(nonce, nonce.Length - m_record_iv_length, output, outputPos, m_record_iv_length); + outputPos += m_record_iv_length; + } + + short recordType = m_isTlsV13 ? ContentType.application_data : contentType; + + byte[] additionalData = GetAdditionalData(seqNo, recordType, recordVersion, ciphertextLength, + plaintextLength); + + try + { + m_encryptCipher.Init(nonce, m_macSize, additionalData); + + Array.Copy(plaintext, plaintextOffset, output, outputPos, plaintextLength); + if (m_isTlsV13) + { + output[outputPos + plaintextLength] = (byte)contentType; + } + + outputPos += m_encryptCipher.DoFinal(output, outputPos, plaintextLength + extraLength, output, + outputPos); + } + catch (IOException e) + { + throw e; + } + catch (Exception e) + { + throw new TlsFatalAlert(AlertDescription.internal_error, e); + } + + if (outputPos != output.Length) + { + // NOTE: The additional data mechanism for AEAD ciphers requires exact output size prediction. + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + return new TlsEncodeResult(output, 0, output.Length, recordType); + } + + public virtual TlsDecodeResult DecodeCiphertext(long seqNo, short recordType, ProtocolVersion recordVersion, + byte[] ciphertext, int ciphertextOffset, int ciphertextLength) + { + if (GetPlaintextLimit(ciphertextLength) < 0) + throw new TlsFatalAlert(AlertDescription.decode_error); + + byte[] nonce = new byte[m_decryptNonce.Length + m_record_iv_length]; + + switch (m_nonceMode) + { + case NONCE_RFC5288: + Array.Copy(m_decryptNonce, 0, nonce, 0, m_decryptNonce.Length); + Array.Copy(ciphertext, ciphertextOffset, nonce, nonce.Length - m_record_iv_length, + m_record_iv_length); + break; + case NONCE_RFC7905: + TlsUtilities.WriteUint64(seqNo, nonce, nonce.Length - 8); + for (int i = 0; i < m_decryptNonce.Length; ++i) + { + nonce[i] ^= m_decryptNonce[i]; + } + break; + default: + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + int encryptionOffset = ciphertextOffset + m_record_iv_length; + int encryptionLength = ciphertextLength - m_record_iv_length; + int plaintextLength = m_decryptCipher.GetOutputSize(encryptionLength); + + byte[] additionalData = GetAdditionalData(seqNo, recordType, recordVersion, ciphertextLength, + plaintextLength); + + int outputPos; + try + { + m_decryptCipher.Init(nonce, m_macSize, additionalData); + outputPos = m_decryptCipher.DoFinal(ciphertext, encryptionOffset, encryptionLength, ciphertext, + encryptionOffset); + } + catch (IOException e) + { + throw e; + } + catch (Exception e) + { + throw new TlsFatalAlert(AlertDescription.bad_record_mac, e); + } + + if (outputPos != plaintextLength) + { + // NOTE: The additional data mechanism for AEAD ciphers requires exact output size prediction. + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + short contentType = recordType; + if (m_isTlsV13) + { + // Strip padding and read true content type from TLSInnerPlaintext + int pos = plaintextLength; + for (;;) + { + if (--pos < 0) + throw new TlsFatalAlert(AlertDescription.unexpected_message); + + byte octet = ciphertext[encryptionOffset + pos]; + if (0 != octet) + { + contentType = (short)(octet & 0xFF); + plaintextLength = pos; + break; + } + } + } + + return new TlsDecodeResult(ciphertext, encryptionOffset, plaintextLength, contentType); + } + + public virtual void RekeyDecoder() + { + RekeyCipher(m_cryptoParams.SecurityParameters, m_decryptCipher, m_decryptNonce, !m_cryptoParams.IsServer); + } + + public virtual void RekeyEncoder() + { + RekeyCipher(m_cryptoParams.SecurityParameters, m_encryptCipher, m_encryptNonce, m_cryptoParams.IsServer); + } + + public virtual bool UsesOpaqueRecordType + { + get { return m_isTlsV13; } + } + + protected virtual byte[] GetAdditionalData(long seqNo, short recordType, ProtocolVersion recordVersion, + int ciphertextLength, int plaintextLength) + { + if (m_isTlsV13) + { + /* + * TLSCiphertext.opaque_type || TLSCiphertext.legacy_record_version || TLSCiphertext.length + */ + byte[] additional_data = new byte[5]; + TlsUtilities.WriteUint8(recordType, additional_data, 0); + TlsUtilities.WriteVersion(recordVersion, additional_data, 1); + TlsUtilities.WriteUint16(ciphertextLength, additional_data, 3); + return additional_data; + } + else + { + /* + * seq_num + TLSCompressed.type + TLSCompressed.version + TLSCompressed.length + */ + byte[] additional_data = new byte[13]; + TlsUtilities.WriteUint64(seqNo, additional_data, 0); + TlsUtilities.WriteUint8(recordType, additional_data, 8); + TlsUtilities.WriteVersion(recordVersion, additional_data, 9); + TlsUtilities.WriteUint16(plaintextLength, additional_data, 11); + return additional_data; + } + } + + protected virtual void RekeyCipher(SecurityParameters securityParameters, TlsAeadCipherImpl cipher, + byte[] nonce, bool serverSecret) + { + if (!m_isTlsV13) + throw new TlsFatalAlert(AlertDescription.internal_error); + + TlsSecret secret = serverSecret + ? securityParameters.TrafficSecretServer + : securityParameters.TrafficSecretClient; + + // TODO[tls13] For early data, have to disable server->client + if (null == secret) + throw new TlsFatalAlert(AlertDescription.internal_error); + + Setup13Cipher(cipher, nonce, secret, securityParameters.PrfCryptoHashAlgorithm); + } + + protected virtual void Setup13Cipher(TlsAeadCipherImpl cipher, byte[] nonce, TlsSecret secret, + int cryptoHashAlgorithm) + { + byte[] key = TlsCryptoUtilities.HkdfExpandLabel(secret, cryptoHashAlgorithm, "key", + TlsUtilities.EmptyBytes, m_keySize).Extract(); + byte[] iv = TlsCryptoUtilities.HkdfExpandLabel(secret, cryptoHashAlgorithm, "iv", TlsUtilities.EmptyBytes, + m_fixed_iv_length).Extract(); + + cipher.SetKey(key, 0, m_keySize); + Array.Copy(iv, 0, nonce, 0, m_fixed_iv_length); + + // NOTE: Ensure dummy nonce is not part of the generated sequence(s) + iv [0] ^= 0x80; + cipher.Init(iv, m_macSize, null); + } + + private static int GetNonceMode(bool isTLSv13, int aeadType) + { + switch (aeadType) + { + case AEAD_CCM: + case AEAD_GCM: + return isTLSv13 ? NONCE_RFC7905 : NONCE_RFC5288; + + case AEAD_CHACHA20_POLY1305: + return NONCE_RFC7905; + + default: + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/TlsAeadCipher.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/TlsAeadCipher.cs.meta new file mode 100644 index 0000000..9712fd7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/TlsAeadCipher.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7666a97a1714dc543a5878627e0cfd82 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/TlsAeadCipherImpl.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/TlsAeadCipherImpl.cs new file mode 100644 index 0000000..44e6fda --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/TlsAeadCipherImpl.cs @@ -0,0 +1,41 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Tls.Crypto.Impl +{ + /// Base interface for services supporting AEAD encryption/decryption. + public interface TlsAeadCipherImpl + { + /// Set the key to be used by the AEAD cipher implementation supporting this service. + /// array holding the AEAD cipher key. + /// offset into the array the key starts at. + /// length of the key in the array. + /// + void SetKey(byte[] key, int keyOff, int keyLen); + + /// Initialise the parameters for the AEAD operator. + /// the nonce. + /// MAC size in bytes. + /// any additional data to be included in the MAC calculation. + /// if the parameters are inappropriate. + void Init(byte[] nonce, int macSize, byte[] additionalData); + + /// Return the maximum size of the output for input of inputLength bytes. + /// the length (in bytes) of the proposed input. + /// the maximum size of the output. + int GetOutputSize(int inputLength); + + /// Perform the cipher encryption/decryption returning the output in output. + /// + /// Note: we have to use DoFinal() here as it is the only way to guarantee output from the underlying cipher. + /// + /// array holding input data to the cipher. + /// offset into input array data starts at. + /// length of the input data in the array. + /// array to hold the cipher output. + /// offset into output array to start saving output. + /// the amount of data written to output. + /// in case of failure. + int DoFinal(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/TlsAeadCipherImpl.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/TlsAeadCipherImpl.cs.meta new file mode 100644 index 0000000..4b8df38 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/TlsAeadCipherImpl.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c8ec97ef01050bd4593411ae63b69486 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/TlsBlockCipher.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/TlsBlockCipher.cs new file mode 100644 index 0000000..64cfc75 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/TlsBlockCipher.cs @@ -0,0 +1,423 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls.Crypto.Impl +{ + /// A generic TLS 1.0-1.2 block cipher. This can be used for AES or 3DES for example. + public class TlsBlockCipher + : TlsCipher + { + protected readonly TlsCryptoParameters m_cryptoParams; + protected readonly byte[] m_randomData; + protected readonly bool m_encryptThenMac; + protected readonly bool m_useExplicitIV; + protected readonly bool m_acceptExtraPadding; + protected readonly bool m_useExtraPadding; + + protected readonly TlsBlockCipherImpl m_decryptCipher, m_encryptCipher; + protected readonly TlsSuiteMac m_readMac, m_writeMac; + + /// + public TlsBlockCipher(TlsCryptoParameters cryptoParams, TlsBlockCipherImpl encryptCipher, + TlsBlockCipherImpl decryptCipher, TlsHmac clientMac, TlsHmac serverMac, int cipherKeySize) + { + SecurityParameters securityParameters = cryptoParams.SecurityParameters; + ProtocolVersion negotiatedVersion = securityParameters.NegotiatedVersion; + + if (TlsImplUtilities.IsTlsV13(negotiatedVersion)) + throw new TlsFatalAlert(AlertDescription.internal_error); + + this.m_cryptoParams = cryptoParams; + this.m_randomData = cryptoParams.NonceGenerator.GenerateNonce(256); + + this.m_encryptThenMac = securityParameters.IsEncryptThenMac; + this.m_useExplicitIV = TlsImplUtilities.IsTlsV11(negotiatedVersion); + + this.m_acceptExtraPadding = !negotiatedVersion.IsSsl; + + /* + * Don't use variable-length padding with truncated MACs. + * + * See "Tag Size Does Matter: Attacks and Proofs for the TLS Record Protocol", Paterson, + * Ristenpart, Shrimpton. + * + * TODO[DTLS] Consider supporting in DTLS (without exceeding send limit though) + */ + this.m_useExtraPadding = securityParameters.IsExtendedPadding + && ProtocolVersion.TLSv10.IsEqualOrEarlierVersionOf(negotiatedVersion) + && (m_encryptThenMac || !securityParameters.IsTruncatedHmac); + + this.m_encryptCipher = encryptCipher; + this.m_decryptCipher = decryptCipher; + + TlsBlockCipherImpl clientCipher, serverCipher; + if (cryptoParams.IsServer) + { + clientCipher = decryptCipher; + serverCipher = encryptCipher; + } + else + { + clientCipher = encryptCipher; + serverCipher = decryptCipher; + } + + int key_block_size = (2 * cipherKeySize) + clientMac.MacLength + serverMac.MacLength; + + // From TLS 1.1 onwards, block ciphers don't need IVs from the key_block + if (!m_useExplicitIV) + { + key_block_size += clientCipher.GetBlockSize() + serverCipher.GetBlockSize(); + } + + byte[] key_block = TlsImplUtilities.CalculateKeyBlock(cryptoParams, key_block_size); + + int offset = 0; + + clientMac.SetKey(key_block, offset, clientMac.MacLength); + offset += clientMac.MacLength; + serverMac.SetKey(key_block, offset, serverMac.MacLength); + offset += serverMac.MacLength; + + clientCipher.SetKey(key_block, offset, cipherKeySize); + offset += cipherKeySize; + serverCipher.SetKey(key_block, offset, cipherKeySize); + offset += cipherKeySize; + + int clientIVLength = clientCipher.GetBlockSize(); + int serverIVLength = serverCipher.GetBlockSize(); + + if (m_useExplicitIV) + { + clientCipher.Init(new byte[clientIVLength], 0, clientIVLength); + serverCipher.Init(new byte[serverIVLength], 0, serverIVLength); + } + else + { + clientCipher.Init(key_block, offset, clientIVLength); + offset += clientIVLength; + serverCipher.Init(key_block, offset, serverIVLength); + offset += serverIVLength; + } + + if (offset != key_block_size) + throw new TlsFatalAlert(AlertDescription.internal_error); + + if (cryptoParams.IsServer) + { + this.m_writeMac = new TlsSuiteHmac(cryptoParams, serverMac); + this.m_readMac = new TlsSuiteHmac(cryptoParams, clientMac); + } + else + { + this.m_writeMac = new TlsSuiteHmac(cryptoParams, clientMac); + this.m_readMac = new TlsSuiteHmac(cryptoParams, serverMac); + } + } + + public virtual int GetCiphertextDecodeLimit(int plaintextLimit) + { + int blockSize = m_decryptCipher.GetBlockSize(); + int macSize = m_readMac.Size; + int maxPadding = 256; + + return GetCiphertextLength(blockSize, macSize, maxPadding, plaintextLimit); + } + + public virtual int GetCiphertextEncodeLimit(int plaintextLength, int plaintextLimit) + { + int blockSize = m_encryptCipher.GetBlockSize(); + int macSize = m_writeMac.Size; + int maxPadding = m_useExtraPadding ? 256 : blockSize; + + return GetCiphertextLength(blockSize, macSize, maxPadding, plaintextLength); + } + + public virtual int GetPlaintextLimit(int ciphertextLimit) + { + int blockSize = m_encryptCipher.GetBlockSize(); + int macSize = m_writeMac.Size; + + int plaintextLimit = ciphertextLimit; + + // Leave room for the MAC, and require block-alignment + if (m_encryptThenMac) + { + plaintextLimit -= macSize; + plaintextLimit -= plaintextLimit % blockSize; + } + else + { + plaintextLimit -= plaintextLimit % blockSize; + plaintextLimit -= macSize; + } + + // Minimum 1 byte of padding + --plaintextLimit; + + // An explicit IV consumes 1 block + if (m_useExplicitIV) + { + plaintextLimit -= blockSize; + } + + return plaintextLimit; + } + + public virtual TlsEncodeResult EncodePlaintext(long seqNo, short contentType, ProtocolVersion recordVersion, + int headerAllocation, byte[] plaintext, int offset, int len) + { + int blockSize = m_encryptCipher.GetBlockSize(); + int macSize = m_writeMac.Size; + + int enc_input_length = len; + if (!m_encryptThenMac) + { + enc_input_length += macSize; + } + + int padding_length = blockSize - (enc_input_length % blockSize); + if (m_useExtraPadding) + { + // Add a random number of extra blocks worth of padding + int maxExtraPadBlocks = (256 - padding_length) / blockSize; + int actualExtraPadBlocks = ChooseExtraPadBlocks(maxExtraPadBlocks); + padding_length += actualExtraPadBlocks * blockSize; + } + + int totalSize = len + macSize + padding_length; + if (m_useExplicitIV) + { + totalSize += blockSize; + } + + byte[] outBuf = new byte[headerAllocation + totalSize]; + int outOff = headerAllocation; + + if (m_useExplicitIV) + { + // Technically the explicit IV will be the encryption of this nonce + byte[] explicitIV = m_cryptoParams.NonceGenerator.GenerateNonce(blockSize); + Array.Copy(explicitIV, 0, outBuf, outOff, blockSize); + outOff += blockSize; + } + + Array.Copy(plaintext, offset, outBuf, outOff, len); + outOff += len; + + if (!m_encryptThenMac) + { + byte[] mac = m_writeMac.CalculateMac(seqNo, contentType, plaintext, offset, len); + Array.Copy(mac, 0, outBuf, outOff, mac.Length); + outOff += mac.Length; + } + + byte padByte = (byte)(padding_length - 1); + for (int i = 0; i < padding_length; ++i) + { + outBuf[outOff++] = padByte; + } + + m_encryptCipher.DoFinal(outBuf, headerAllocation, outOff - headerAllocation, outBuf, headerAllocation); + + if (m_encryptThenMac) + { + byte[] mac = m_writeMac.CalculateMac(seqNo, contentType, outBuf, headerAllocation, + outOff - headerAllocation); + Array.Copy(mac, 0, outBuf, outOff, mac.Length); + outOff += mac.Length; + } + + if (outOff != outBuf.Length) + throw new TlsFatalAlert(AlertDescription.internal_error); + + return new TlsEncodeResult(outBuf, 0, outBuf.Length, contentType); + } + + public virtual TlsDecodeResult DecodeCiphertext(long seqNo, short recordType, ProtocolVersion recordVersion, + byte[] ciphertext, int offset, int len) + { + int blockSize = m_decryptCipher.GetBlockSize(); + int macSize = m_readMac.Size; + + int minLen = blockSize; + if (m_encryptThenMac) + { + minLen += macSize; + } + else + { + minLen = System.Math.Max(minLen, macSize + 1); + } + + if (m_useExplicitIV) + { + minLen += blockSize; + } + + if (len < minLen) + throw new TlsFatalAlert(AlertDescription.decode_error); + + int blocks_length = len; + if (m_encryptThenMac) + { + blocks_length -= macSize; + } + + if (blocks_length % blockSize != 0) + throw new TlsFatalAlert(AlertDescription.decryption_failed); + + if (m_encryptThenMac) + { + byte[] expectedMac = m_readMac.CalculateMac(seqNo, recordType, ciphertext, offset, len - macSize); + + bool checkMac = TlsUtilities.ConstantTimeAreEqual(macSize, expectedMac, 0, ciphertext, + offset + len - macSize); + if (!checkMac) + { + /* + * RFC 7366 3. The MAC SHALL be evaluated before any further processing such as + * decryption is performed, and if the MAC verification fails, then processing SHALL + * terminate immediately. For TLS, a fatal bad_record_mac MUST be generated [2]. For + * DTLS, the record MUST be discarded, and a fatal bad_record_mac MAY be generated + * [4]. This immediate response to a bad MAC eliminates any timing channels that may + * be available through the use of manipulated packet data. + */ + throw new TlsFatalAlert(AlertDescription.bad_record_mac); + } + } + + m_decryptCipher.DoFinal(ciphertext, offset, blocks_length, ciphertext, offset); + + if (m_useExplicitIV) + { + offset += blockSize; + blocks_length -= blockSize; + } + + // If there's anything wrong with the padding, this will return zero + int totalPad = CheckPaddingConstantTime(ciphertext, offset, blocks_length, blockSize, + m_encryptThenMac ? 0 : macSize); + bool badMac = (totalPad == 0); + + int dec_output_length = blocks_length - totalPad; + + if (!m_encryptThenMac) + { + dec_output_length -= macSize; + + byte[] expectedMac = m_readMac.CalculateMacConstantTime(seqNo, recordType, ciphertext, offset, + dec_output_length, blocks_length - macSize, m_randomData); + + badMac |= !TlsUtilities.ConstantTimeAreEqual(macSize, expectedMac, 0, ciphertext, + offset + dec_output_length); + } + + if (badMac) + throw new TlsFatalAlert(AlertDescription.bad_record_mac); + + return new TlsDecodeResult(ciphertext, offset, dec_output_length, recordType); + } + + public virtual void RekeyDecoder() + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public virtual void RekeyEncoder() + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public virtual bool UsesOpaqueRecordType + { + get { return false; } + } + + protected virtual int CheckPaddingConstantTime(byte[] buf, int off, int len, int blockSize, int macSize) + { + int end = off + len; + byte lastByte = buf[end - 1]; + int padlen = lastByte & 0xff; + int totalPad = padlen + 1; + + int dummyIndex = 0; + byte padDiff = 0; + + int totalPadLimit = System.Math.Min(m_acceptExtraPadding ? 256 : blockSize, len - macSize); + + if (totalPad > totalPadLimit) + { + totalPad = 0; + } + else + { + int padPos = end - totalPad; + do + { + padDiff |= (byte)(buf[padPos++] ^ lastByte); + } + while (padPos < end); + + dummyIndex = totalPad; + + if (padDiff != 0) + { + totalPad = 0; + } + } + + // Run some extra dummy checks so the number of checks is always constant + { + byte[] dummyPad = m_randomData; + while (dummyIndex < 256) + { + padDiff |= (byte)(dummyPad[dummyIndex++] ^ lastByte); + } + // Ensure the above loop is not eliminated + dummyPad[0] ^= padDiff; + } + + return totalPad; + } + + protected virtual int ChooseExtraPadBlocks(int max) + { + byte[] random = m_cryptoParams.NonceGenerator.GenerateNonce(4); + int x = (int)Pack.LE_To_UInt32(random, 0); + int n = Integers.NumberOfTrailingZeros(x); + return System.Math.Min(n, max); + } + + protected virtual int GetCiphertextLength(int blockSize, int macSize, int maxPadding, int plaintextLength) + { + int ciphertextLength = plaintextLength; + + // An explicit IV consumes 1 block + if (m_useExplicitIV) + { + ciphertextLength += blockSize; + } + + // Leave room for the MAC and (block-aligning) padding + + ciphertextLength += maxPadding; + + if (m_encryptThenMac) + { + ciphertextLength -= (ciphertextLength % blockSize); + ciphertextLength += macSize; + } + else + { + ciphertextLength += macSize; + ciphertextLength -= (ciphertextLength % blockSize); + } + + return ciphertextLength; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/TlsBlockCipher.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/TlsBlockCipher.cs.meta new file mode 100644 index 0000000..c782025 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/TlsBlockCipher.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 40a3c58afd6fb7749b536e21d191cb90 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/TlsBlockCipherImpl.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/TlsBlockCipherImpl.cs new file mode 100644 index 0000000..7df2ed7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/TlsBlockCipherImpl.cs @@ -0,0 +1,40 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Tls.Crypto.Impl +{ + /// Interface for block cipher services. + public interface TlsBlockCipherImpl + { + /// Set the key to be used by the block cipher implementation supporting this service. + /// array holding the block cipher key. + /// offset into the array the key starts at. + /// length of the key in the array. + /// + void SetKey(byte[] key, int keyOff, int keyLen); + + /// Initialise the parameters for operator. + /// array holding the initialization vector (IV). + /// offset into the array the IV starts at. + /// length of the IV in the array. + /// if the parameters are inappropriate. + void Init(byte[] iv, int ivOff, int ivLen); + + /// Perform the cipher encryption/decryption returning the output in output. + /// + /// Note: we have to use DoFinal() here as it is the only way to guarantee output from the underlying cipher. + /// + /// array holding input data to the cipher. + /// offset into input array data starts at. + /// length of the input data in the array. + /// array to hold the cipher output. + /// offset into output array to start saving output. + /// the amount of data written to output. + /// in case of failure. + int DoFinal(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset); + + /// Return the blocksize (in bytes) of the underlying block cipher. + /// the cipher's blocksize. + int GetBlockSize(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/TlsBlockCipherImpl.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/TlsBlockCipherImpl.cs.meta new file mode 100644 index 0000000..804ac06 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/TlsBlockCipherImpl.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c86b777095d5b674d97ed6421562c3a2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/TlsImplUtilities.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/TlsImplUtilities.cs new file mode 100644 index 0000000..db936e6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/TlsImplUtilities.cs @@ -0,0 +1,75 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls.Crypto.Impl +{ + /// Useful utility methods. + public abstract class TlsImplUtilities + { + public static bool IsSsl(TlsCryptoParameters cryptoParams) + { + return cryptoParams.ServerVersion.IsSsl; + } + + public static bool IsTlsV10(ProtocolVersion version) + { + return ProtocolVersion.TLSv10.IsEqualOrEarlierVersionOf(version.GetEquivalentTlsVersion()); + } + + public static bool IsTlsV10(TlsCryptoParameters cryptoParams) + { + return IsTlsV10(cryptoParams.ServerVersion); + } + + public static bool IsTlsV11(ProtocolVersion version) + { + return ProtocolVersion.TLSv11.IsEqualOrEarlierVersionOf(version.GetEquivalentTlsVersion()); + } + + public static bool IsTlsV11(TlsCryptoParameters cryptoParams) + { + return IsTlsV11(cryptoParams.ServerVersion); + } + + public static bool IsTlsV12(ProtocolVersion version) + { + return ProtocolVersion.TLSv12.IsEqualOrEarlierVersionOf(version.GetEquivalentTlsVersion()); + } + + public static bool IsTlsV12(TlsCryptoParameters cryptoParams) + { + return IsTlsV12(cryptoParams.ServerVersion); + } + + public static bool IsTlsV13(ProtocolVersion version) + { + return ProtocolVersion.TLSv13.IsEqualOrEarlierVersionOf(version.GetEquivalentTlsVersion()); + } + + public static bool IsTlsV13(TlsCryptoParameters cryptoParams) + { + return IsTlsV13(cryptoParams.ServerVersion); + } + + public static byte[] CalculateKeyBlock(TlsCryptoParameters cryptoParams, int length) + { + SecurityParameters securityParameters = cryptoParams.SecurityParameters; + TlsSecret master_secret = securityParameters.MasterSecret; + byte[] seed = Arrays.Concatenate(securityParameters.ServerRandom, securityParameters.ClientRandom); + return Prf(securityParameters, master_secret, ExporterLabel.key_expansion, seed, length).Extract(); + } + + public static TlsSecret Prf(SecurityParameters securityParameters, TlsSecret secret, string asciiLabel, + byte[] seed, int length) + { + return secret.DeriveUsingPrf(securityParameters.PrfAlgorithm, asciiLabel, seed, length); + } + + public static TlsSecret Prf(TlsCryptoParameters cryptoParams, TlsSecret secret, string asciiLabel, byte[] seed, + int length) + { + return Prf(cryptoParams.SecurityParameters, secret, asciiLabel, seed, length); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/TlsImplUtilities.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/TlsImplUtilities.cs.meta new file mode 100644 index 0000000..e4d7848 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/TlsImplUtilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 71a5115afab3b8945b810299c3feb33f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/TlsNullCipher.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/TlsNullCipher.cs new file mode 100644 index 0000000..3ca4951 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/TlsNullCipher.cs @@ -0,0 +1,104 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Tls.Crypto.Impl +{ + /// The NULL cipher. + public class TlsNullCipher + : TlsCipher + { + protected readonly TlsCryptoParameters m_cryptoParams; + protected readonly TlsSuiteHmac m_readMac, m_writeMac; + + /// + public TlsNullCipher(TlsCryptoParameters cryptoParams, TlsHmac clientMac, TlsHmac serverMac) + { + if (TlsImplUtilities.IsTlsV13(cryptoParams)) + throw new TlsFatalAlert(AlertDescription.internal_error); + + this.m_cryptoParams = cryptoParams; + + int key_block_size = clientMac.MacLength + serverMac.MacLength; + byte[] key_block = TlsImplUtilities.CalculateKeyBlock(cryptoParams, key_block_size); + + int offset = 0; + + clientMac.SetKey(key_block, offset, clientMac.MacLength); + offset += clientMac.MacLength; + serverMac.SetKey(key_block, offset, serverMac.MacLength); + offset += serverMac.MacLength; + + if (offset != key_block_size) + throw new TlsFatalAlert(AlertDescription.internal_error); + + if (cryptoParams.IsServer) + { + this.m_writeMac = new TlsSuiteHmac(cryptoParams, serverMac); + this.m_readMac = new TlsSuiteHmac(cryptoParams, clientMac); + } + else + { + this.m_writeMac = new TlsSuiteHmac(cryptoParams, clientMac); + this.m_readMac = new TlsSuiteHmac(cryptoParams, serverMac); + } + } + + public virtual int GetCiphertextDecodeLimit(int plaintextLimit) + { + return plaintextLimit + m_writeMac.Size; + } + + public virtual int GetCiphertextEncodeLimit(int plaintextLength, int plaintextLimit) + { + return plaintextLength + m_writeMac.Size; + } + + public virtual int GetPlaintextLimit(int ciphertextLimit) + { + return ciphertextLimit - m_writeMac.Size; + } + + public virtual TlsEncodeResult EncodePlaintext(long seqNo, short contentType, ProtocolVersion recordVersion, + int headerAllocation, byte[] plaintext, int offset, int len) + { + byte[] mac = m_writeMac.CalculateMac(seqNo, contentType, plaintext, offset, len); + byte[] ciphertext = new byte[headerAllocation + len + mac.Length]; + Array.Copy(plaintext, offset, ciphertext, headerAllocation, len); + Array.Copy(mac, 0, ciphertext, headerAllocation + len, mac.Length); + return new TlsEncodeResult(ciphertext, 0, ciphertext.Length, contentType); + } + + public virtual TlsDecodeResult DecodeCiphertext(long seqNo, short recordType, ProtocolVersion recordVersion, + byte[] ciphertext, int offset, int len) + { + int macSize = m_readMac.Size; + if (len < macSize) + throw new TlsFatalAlert(AlertDescription.decode_error); + + int macInputLen = len - macSize; + + byte[] expectedMac = m_readMac.CalculateMac(seqNo, recordType, ciphertext, offset, macInputLen); + + bool badMac = !TlsUtilities.ConstantTimeAreEqual(macSize, expectedMac, 0, ciphertext, offset + macInputLen); + if (badMac) + throw new TlsFatalAlert(AlertDescription.bad_record_mac); + + return new TlsDecodeResult(ciphertext, offset, macInputLen, recordType); + } + + public virtual void RekeyDecoder() + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public virtual void RekeyEncoder() + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public virtual bool UsesOpaqueRecordType + { + get { return false; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/TlsNullCipher.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/TlsNullCipher.cs.meta new file mode 100644 index 0000000..563de32 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/TlsNullCipher.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9c49293d6940c5f4fb15753610adbd16 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/TlsSuiteHmac.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/TlsSuiteHmac.cs new file mode 100644 index 0000000..9f43f43 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/TlsSuiteHmac.cs @@ -0,0 +1,121 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls.Crypto.Impl +{ + /// A generic TLS MAC implementation, acting as an HMAC based on some underlying Digest. + public class TlsSuiteHmac + : TlsSuiteMac + { + protected static int GetMacSize(TlsCryptoParameters cryptoParams, TlsMac mac) + { + int macSize = mac.MacLength; + if (cryptoParams.SecurityParameters.IsTruncatedHmac) + { + macSize = System.Math.Min(macSize, 10); + } + return macSize; + } + + protected readonly TlsCryptoParameters m_cryptoParams; + protected readonly TlsHmac m_mac; + protected readonly int m_digestBlockSize; + protected readonly int m_digestOverhead; + protected readonly int m_macSize; + + /// Generate a new instance of a TlsMac. + /// the TLS client context specific crypto parameters. + /// The MAC to use. + public TlsSuiteHmac(TlsCryptoParameters cryptoParams, TlsHmac mac) + { + this.m_cryptoParams = cryptoParams; + this.m_mac = mac; + this.m_macSize = GetMacSize(cryptoParams, mac); + this.m_digestBlockSize = mac.InternalBlockSize; + + // TODO This should check the actual algorithm, not assume based on the digest size + if (TlsImplUtilities.IsSsl(cryptoParams) && mac.MacLength == 20) + { + /* + * NOTE: For the SSL 3.0 MAC with SHA-1, the secret + input pad is not block-aligned. + */ + this.m_digestOverhead = 4; + } + else + { + this.m_digestOverhead = m_digestBlockSize / 8; + } + } + + public virtual int Size + { + get { return m_macSize; } + } + + public virtual byte[] CalculateMac(long seqNo, short type, byte[] msg, int msgOff, int msgLen) + { + ProtocolVersion serverVersion = m_cryptoParams.ServerVersion; + bool isSsl = serverVersion.IsSsl; + + byte[] macHeader = new byte[isSsl ? 11 : 13]; + TlsUtilities.WriteUint64(seqNo, macHeader, 0); + TlsUtilities.WriteUint8(type, macHeader, 8); + if (!isSsl) + { + TlsUtilities.WriteVersion(serverVersion, macHeader, 9); + } + TlsUtilities.WriteUint16(msgLen, macHeader, macHeader.Length - 2); + + m_mac.Update(macHeader, 0, macHeader.Length); + m_mac.Update(msg, msgOff, msgLen); + + return Truncate(m_mac.CalculateMac()); + } + + public virtual byte[] CalculateMacConstantTime(long seqNo, short type, byte[] msg, int msgOff, int msgLen, + int fullLength, byte[] dummyData) + { + /* + * Actual MAC only calculated on 'length' bytes... + */ + byte[] result = CalculateMac(seqNo, type, msg, msgOff, msgLen); + + /* + * ...but ensure a constant number of complete digest blocks are processed (as many as would + * be needed for 'fullLength' bytes of input). + */ + int headerLength = TlsImplUtilities.IsSsl(m_cryptoParams) ? 11 : 13; + + // How many extra full blocks do we need to calculate? + int extra = GetDigestBlockCount(headerLength + fullLength) - GetDigestBlockCount(headerLength + msgLen); + + while (--extra >= 0) + { + m_mac.Update(dummyData, 0, m_digestBlockSize); + } + + // One more byte in case the implementation is "lazy" about processing blocks + m_mac.Update(dummyData, 0, 1); + m_mac.Reset(); + + return result; + } + + protected virtual int GetDigestBlockCount(int inputLength) + { + // NOTE: The input pad for HMAC is always a full digest block + + // NOTE: This calculation assumes a minimum of 1 pad byte + return (inputLength + m_digestOverhead) / m_digestBlockSize; + } + + protected virtual byte[] Truncate(byte[] bs) + { + if (bs.Length <= m_macSize) + return bs; + + return Arrays.CopyOf(bs, m_macSize); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/TlsSuiteHmac.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/TlsSuiteHmac.cs.meta new file mode 100644 index 0000000..3e92175 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/TlsSuiteHmac.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 55de7b806d04fc1408c01c22c3fbe88f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/TlsSuiteMac.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/TlsSuiteMac.cs new file mode 100644 index 0000000..6e49429 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/TlsSuiteMac.cs @@ -0,0 +1,33 @@ +using System; + +namespace Org.BouncyCastle.Tls.Crypto.Impl +{ + /// Base interface for a generic TLS MAC implementation for use with a bulk cipher. + public interface TlsSuiteMac + { + /// Return the output length (in bytes) of this MAC. + /// The output length of this MAC. + int Size { get; } + + /// Calculate the MAC for some given data. + /// The sequence number of the record. + /// The content type of the message. + /// A byte array containing the message. + /// The number of bytes to skip, before the message starts. + /// The length of the message. + /// A new byte array containing the MAC value. + byte[] CalculateMac(long seqNo, short type, byte[] message, int offset, int length); + + /// Constant time calculation of the MAC for some given data with a given expected length. + /// The sequence number of the record. + /// The content type of the message. + /// A byte array containing the message. + /// The number of bytes to skip, before the message starts. + /// The length of the message. + /// The expected length of the full message. + /// Random data for padding out the MAC calculation if required. + /// A new byte array containing the MAC value. + byte[] CalculateMacConstantTime(long seqNo, short type, byte[] message, int offset, int length, + int expectedLength, byte[] randomData); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/TlsSuiteMac.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/TlsSuiteMac.cs.meta new file mode 100644 index 0000000..60f2ca5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/TlsSuiteMac.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d2e88a03a17686f4ca5c1e71f7057ccd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc.meta new file mode 100644 index 0000000..c71013a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5cfd519c01fa51d428487e9568aa335e +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcChaCha20Poly1305.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcChaCha20Poly1305.cs new file mode 100644 index 0000000..8d801ed --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcChaCha20Poly1305.cs @@ -0,0 +1,124 @@ +using System; + +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Macs; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; + +namespace Org.BouncyCastle.Tls.Crypto.Impl.BC +{ + public sealed class BcChaCha20Poly1305 + : TlsAeadCipherImpl + { + private static readonly byte[] Zeroes = new byte[15]; + + private readonly ChaCha7539Engine m_cipher = new ChaCha7539Engine(); + private readonly Poly1305 m_mac = new Poly1305(); + + private readonly bool m_isEncrypting; + + private int m_additionalDataLength; + + public BcChaCha20Poly1305(bool isEncrypting) + { + this.m_isEncrypting = isEncrypting; + } + + public int DoFinal(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset) + { + if (m_isEncrypting) + { + int ciphertextLength = inputLength; + + m_cipher.ProcessBytes(input, inputOffset, inputLength, output, outputOffset); + int outputLength = inputLength; + + if (ciphertextLength != outputLength) + throw new InvalidOperationException(); + + UpdateMac(output, outputOffset, ciphertextLength); + + byte[] lengths = new byte[16]; + Pack.UInt64_To_LE((ulong)m_additionalDataLength, lengths, 0); + Pack.UInt64_To_LE((ulong)ciphertextLength, lengths, 8); + m_mac.BlockUpdate(lengths, 0, 16); + + m_mac.DoFinal(output, outputOffset + ciphertextLength); + + return ciphertextLength + 16; + } + else + { + int ciphertextLength = inputLength - 16; + + UpdateMac(input, inputOffset, ciphertextLength); + + byte[] expectedMac = new byte[16]; + Pack.UInt64_To_LE((ulong)m_additionalDataLength, expectedMac, 0); + Pack.UInt64_To_LE((ulong)ciphertextLength, expectedMac, 8); + m_mac.BlockUpdate(expectedMac, 0, 16); + m_mac.DoFinal(expectedMac, 0); + + bool badMac = !TlsUtilities.ConstantTimeAreEqual(16, expectedMac, 0, input, inputOffset + ciphertextLength); + if (badMac) + throw new TlsFatalAlert(AlertDescription.bad_record_mac); + + m_cipher.ProcessBytes(input, inputOffset, ciphertextLength, output, outputOffset); + int outputLength = ciphertextLength; + + if (ciphertextLength != outputLength) + throw new InvalidOperationException(); + + return ciphertextLength; + } + } + + public int GetOutputSize(int inputLength) + { + return m_isEncrypting ? inputLength + 16 : inputLength - 16; + } + + public void Init(byte[] nonce, int macSize, byte[] additionalData) + { + if (nonce == null || nonce.Length != 12 || macSize != 16) + throw new TlsFatalAlert(AlertDescription.internal_error); + + m_cipher.Init(m_isEncrypting, new ParametersWithIV(null, nonce)); + InitMac(); + if (additionalData == null) + { + this.m_additionalDataLength = 0; + } + else + { + this.m_additionalDataLength = additionalData.Length; + UpdateMac(additionalData, 0, additionalData.Length); + } + } + + public void SetKey(byte[] key, int keyOff, int keyLen) + { + KeyParameter cipherKey = new KeyParameter(key, keyOff, keyLen); + m_cipher.Init(m_isEncrypting, new ParametersWithIV(cipherKey, Zeroes, 0, 12)); + } + + private void InitMac() + { + byte[] firstBlock = new byte[64]; + m_cipher.ProcessBytes(firstBlock, 0, 64, firstBlock, 0); + m_mac.Init(new KeyParameter(firstBlock, 0, 32)); + Array.Clear(firstBlock, 0, firstBlock.Length); + } + + private void UpdateMac(byte[] buf, int off, int len) + { + m_mac.BlockUpdate(buf, off, len); + + int partial = len % 16; + if (partial != 0) + { + m_mac.BlockUpdate(Zeroes, 0, 16 - partial); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcChaCha20Poly1305.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcChaCha20Poly1305.cs.meta new file mode 100644 index 0000000..f55830b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcChaCha20Poly1305.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2cf509f1f755f5b4bba614910b670839 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcDefaultTlsCredentialedAgreement.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcDefaultTlsCredentialedAgreement.cs new file mode 100644 index 0000000..15944cd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcDefaultTlsCredentialedAgreement.cs @@ -0,0 +1,112 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls.Crypto.Impl.BC +{ + /// Credentialed class generating agreed secrets from a peer's public key for our end of the TLS connection + /// using the BC light-weight API. + public class BcDefaultTlsCredentialedAgreement + : TlsCredentialedAgreement + { + protected readonly TlsCredentialedAgreement m_agreementCredentials; + + public BcDefaultTlsCredentialedAgreement(BcTlsCrypto crypto, Certificate certificate, + AsymmetricKeyParameter privateKey) + { + if (crypto == null) + throw new ArgumentNullException("crypto"); + if (certificate == null) + throw new ArgumentNullException("certificate"); + if (certificate.IsEmpty) + throw new ArgumentException("cannot be empty", "certificate"); + if (privateKey == null) + throw new ArgumentNullException("privateKey"); + if (!privateKey.IsPrivate) + throw new ArgumentException("must be private", "privateKey"); + + if (privateKey is DHPrivateKeyParameters) + { + this.m_agreementCredentials = new DHCredentialedAgreement(crypto, certificate, + (DHPrivateKeyParameters)privateKey); + } + else if (privateKey is ECPrivateKeyParameters) + { + this.m_agreementCredentials = new ECCredentialedAgreement(crypto, certificate, + (ECPrivateKeyParameters)privateKey); + } + else + { + throw new ArgumentException("'privateKey' type not supported: " + Platform.GetTypeName(privateKey)); + } + } + + public virtual Certificate Certificate + { + get { return m_agreementCredentials.Certificate; } + } + + public virtual TlsSecret GenerateAgreement(TlsCertificate peerCertificate) + { + return m_agreementCredentials.GenerateAgreement(peerCertificate); + } + + private sealed class DHCredentialedAgreement + : TlsCredentialedAgreement + { + private readonly BcTlsCrypto m_crypto; + private readonly Certificate m_certificate; + private readonly DHPrivateKeyParameters m_privateKey; + + internal DHCredentialedAgreement(BcTlsCrypto crypto, Certificate certificate, + DHPrivateKeyParameters privateKey) + { + this.m_crypto = crypto; + this.m_certificate = certificate; + this.m_privateKey = privateKey; + } + + public TlsSecret GenerateAgreement(TlsCertificate peerCertificate) + { + BcTlsCertificate bcCert = BcTlsCertificate.Convert(m_crypto, peerCertificate); + DHPublicKeyParameters peerPublicKey = bcCert.GetPubKeyDH(); + return BcTlsDHDomain.CalculateDHAgreement(m_crypto, m_privateKey, peerPublicKey, false); + } + + public Certificate Certificate + { + get { return m_certificate; } + } + } + + private sealed class ECCredentialedAgreement + : TlsCredentialedAgreement + { + private readonly BcTlsCrypto m_crypto; + private readonly Certificate m_certificate; + private readonly ECPrivateKeyParameters m_privateKey; + + internal ECCredentialedAgreement(BcTlsCrypto crypto, Certificate certificate, + ECPrivateKeyParameters privateKey) + { + this.m_crypto = crypto; + this.m_certificate = certificate; + this.m_privateKey = privateKey; + } + + public TlsSecret GenerateAgreement(TlsCertificate peerCertificate) + { + BcTlsCertificate bcCert = BcTlsCertificate.Convert(m_crypto, peerCertificate); + ECPublicKeyParameters peerPublicKey = bcCert.GetPubKeyEC(); + return BcTlsECDomain.CalculateBasicAgreement(m_crypto, m_privateKey, peerPublicKey); + } + + public Certificate Certificate + { + get { return m_certificate; } + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcDefaultTlsCredentialedAgreement.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcDefaultTlsCredentialedAgreement.cs.meta new file mode 100644 index 0000000..4ac9850 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcDefaultTlsCredentialedAgreement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2c1da0684089d6e4a8a24d330d8a52df +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcDefaultTlsCredentialedDecryptor.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcDefaultTlsCredentialedDecryptor.cs new file mode 100644 index 0000000..b0e9f12 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcDefaultTlsCredentialedDecryptor.cs @@ -0,0 +1,139 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Encodings; +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls.Crypto.Impl.BC +{ + /// Credentialed class decrypting RSA encrypted secrets sent from a peer for our end of the TLS connection + /// using the BC light-weight API. + public class BcDefaultTlsCredentialedDecryptor + : TlsCredentialedDecryptor + { + protected readonly BcTlsCrypto m_crypto; + protected readonly Certificate m_certificate; + protected readonly AsymmetricKeyParameter m_privateKey; + + public BcDefaultTlsCredentialedDecryptor(BcTlsCrypto crypto, Certificate certificate, + AsymmetricKeyParameter privateKey) + { + if (crypto == null) + throw new ArgumentNullException("crypto"); + if (certificate == null) + throw new ArgumentNullException("certificate"); + if (certificate.IsEmpty) + throw new ArgumentException("cannot be empty", "certificate"); + if (privateKey == null) + throw new ArgumentNullException("privateKey"); + if (!privateKey.IsPrivate) + throw new ArgumentException("must be private", "privateKey"); + + if (privateKey is RsaKeyParameters) + { + } + else + { + throw new ArgumentException("'privateKey' type not supported: " + Platform.GetTypeName(privateKey)); + } + + this.m_crypto = crypto; + this.m_certificate = certificate; + this.m_privateKey = privateKey; + } + + public virtual Certificate Certificate + { + get { return m_certificate; } + } + + public virtual TlsSecret Decrypt(TlsCryptoParameters cryptoParams, byte[] ciphertext) + { + // TODO Keep only the decryption itself here - move error handling outside + return SafeDecryptPreMasterSecret(cryptoParams, (RsaKeyParameters)m_privateKey, ciphertext); + } + + /* + * TODO[tls-ops] Probably need to make RSA encryption/decryption into TlsCrypto functions so + * that users can implement "generic" encryption credentials externally + */ + protected virtual TlsSecret SafeDecryptPreMasterSecret(TlsCryptoParameters cryptoParams, + RsaKeyParameters rsaServerPrivateKey, byte[] encryptedPreMasterSecret) + { + SecureRandom secureRandom = m_crypto.SecureRandom; + + /* + * RFC 5246 7.4.7.1. + */ + ProtocolVersion expectedVersion = cryptoParams.RsaPreMasterSecretVersion; + + // TODO Provide as configuration option? + bool versionNumberCheckDisabled = false; + + /* + * Generate 48 random bytes we can use as a Pre-Master-Secret, if the + * PKCS1 padding check should fail. + */ + byte[] fallback = new byte[48]; + secureRandom.NextBytes(fallback); + + byte[] M = Arrays.Clone(fallback); + try + { + Pkcs1Encoding encoding = new Pkcs1Encoding(new RsaBlindedEngine(), fallback); + encoding.Init(false, new ParametersWithRandom(rsaServerPrivateKey, secureRandom)); + + M = encoding.ProcessBlock(encryptedPreMasterSecret, 0, encryptedPreMasterSecret.Length); + } + catch (Exception) + { + /* + * This should never happen since the decryption should never throw an exception + * and return a random value instead. + * + * In any case, a TLS server MUST NOT generate an alert if processing an + * RSA-encrypted premaster secret message fails, or the version number is not as + * expected. Instead, it MUST continue the handshake with a randomly generated + * premaster secret. + */ + } + + /* + * If ClientHello.legacy_version is TLS 1.1 or higher, server implementations MUST check the + * version number [..]. + */ + if (versionNumberCheckDisabled && !TlsImplUtilities.IsTlsV11(expectedVersion)) + { + /* + * If the version number is TLS 1.0 or earlier, server implementations SHOULD check the + * version number, but MAY have a configuration option to disable the check. + */ + } + else + { + /* + * Compare the version number in the decrypted Pre-Master-Secret with the legacy_version + * field from the ClientHello. If they don't match, continue the handshake with the + * randomly generated 'fallback' value. + * + * NOTE: The comparison and replacement must be constant-time. + */ + int mask = (expectedVersion.MajorVersion ^ (M[0] & 0xFF)) + | (expectedVersion.MinorVersion ^ (M[1] & 0xFF)); + + // 'mask' will be all 1s if the versions matched, or else all 0s. + mask = (mask - 1) >> 31; + + for (int i = 0; i < 48; i++) + { + M[i] = (byte)((M[i] & mask) | (fallback[i] & ~mask)); + } + } + + return m_crypto.CreateSecret(M); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcDefaultTlsCredentialedDecryptor.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcDefaultTlsCredentialedDecryptor.cs.meta new file mode 100644 index 0000000..d88829a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcDefaultTlsCredentialedDecryptor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9c319aa3cf9892941bee2c18513ab1b9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcDefaultTlsCredentialedSigner.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcDefaultTlsCredentialedSigner.cs new file mode 100644 index 0000000..6db84cd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcDefaultTlsCredentialedSigner.cs @@ -0,0 +1,85 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls.Crypto.Impl.BC +{ + /// Credentialed class for generating signatures based on the use of primitives from the BC light-weight API. + public class BcDefaultTlsCredentialedSigner + : DefaultTlsCredentialedSigner + { + private static BcTlsCertificate GetEndEntity(BcTlsCrypto crypto, Certificate certificate) + { + if (certificate == null || certificate.IsEmpty) + throw new ArgumentException("No certificate"); + + return BcTlsCertificate.Convert(crypto, certificate.GetCertificateAt(0)); + } + + private static TlsSigner MakeSigner(BcTlsCrypto crypto, AsymmetricKeyParameter privateKey, + Certificate certificate, SignatureAndHashAlgorithm signatureAndHashAlgorithm) + { + TlsSigner signer; + if (privateKey is RsaKeyParameters) + { + RsaKeyParameters privKeyRsa = (RsaKeyParameters)privateKey; + + if (signatureAndHashAlgorithm != null) + { + int signatureScheme = SignatureScheme.From(signatureAndHashAlgorithm); + if (SignatureScheme.IsRsaPss(signatureScheme)) + { + return new BcTlsRsaPssSigner(crypto, privKeyRsa, signatureScheme); + } + } + + RsaKeyParameters pubKeyRsa = GetEndEntity(crypto, certificate).GetPubKeyRsa(); + + signer = new BcTlsRsaSigner(crypto, privKeyRsa, pubKeyRsa); + } + else if (privateKey is DsaPrivateKeyParameters) + { + signer = new BcTlsDsaSigner(crypto, (DsaPrivateKeyParameters)privateKey); + } + else if (privateKey is ECPrivateKeyParameters) + { + ECPrivateKeyParameters privKeyEC = (ECPrivateKeyParameters)privateKey; + + if (signatureAndHashAlgorithm != null) + { + int signatureScheme = SignatureScheme.From(signatureAndHashAlgorithm); + if (SignatureScheme.IsECDsa(signatureScheme)) + { + return new BcTlsECDsa13Signer(crypto, privKeyEC, signatureScheme); + } + } + + signer = new BcTlsECDsaSigner(crypto, privKeyEC); + } + else if (privateKey is Ed25519PrivateKeyParameters) + { + signer = new BcTlsEd25519Signer(crypto, (Ed25519PrivateKeyParameters)privateKey); + } + else if (privateKey is Ed448PrivateKeyParameters) + { + signer = new BcTlsEd448Signer(crypto, (Ed448PrivateKeyParameters)privateKey); + } + else + { + throw new ArgumentException("'privateKey' type not supported: " + Platform.GetTypeName(privateKey)); + } + + return signer; + } + + public BcDefaultTlsCredentialedSigner(TlsCryptoParameters cryptoParams, BcTlsCrypto crypto, + AsymmetricKeyParameter privateKey, Certificate certificate, + SignatureAndHashAlgorithm signatureAndHashAlgorithm) + : base(cryptoParams, MakeSigner(crypto, privateKey, certificate, signatureAndHashAlgorithm), certificate, + signatureAndHashAlgorithm) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcDefaultTlsCredentialedSigner.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcDefaultTlsCredentialedSigner.cs.meta new file mode 100644 index 0000000..b819814 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcDefaultTlsCredentialedSigner.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 90d909eb56e0e8e45b624fefba054b81 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcSsl3Hmac.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcSsl3Hmac.cs new file mode 100644 index 0000000..df2ccd2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcSsl3Hmac.cs @@ -0,0 +1,112 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls.Crypto.Impl.BC +{ + /// HMAC implementation based on original internet draft for HMAC (RFC 2104). + /// + /// The difference is that padding is concatenated versus XORed with the key, e.g: + /// H(K + opad, H(K + ipad, text)) + /// + internal class BcSsl3Hmac + : TlsHmac + { + private const byte IPAD_BYTE = (byte)0x36; + private const byte OPAD_BYTE = (byte)0x5C; + + private static readonly byte[] IPAD = GenPad(IPAD_BYTE, 48); + private static readonly byte[] OPAD = GenPad(OPAD_BYTE, 48); + + private readonly IDigest m_digest; + private readonly int m_padLength; + + private byte[] m_secret; + + /// Base constructor for one of the standard digest algorithms for which the byteLength is known. + /// + /// + /// Behaviour is undefined for digests other than MD5 or SHA1. + /// + /// the digest. + internal BcSsl3Hmac(IDigest digest) + { + this.m_digest = digest; + + if (digest.GetDigestSize() == 20) + { + this.m_padLength = 40; + } + else + { + this.m_padLength = 48; + } + } + + public virtual void SetKey(byte[] key, int keyOff, int keyLen) + { + this.m_secret = TlsUtilities.CopyOfRangeExact(key, keyOff, keyOff + keyLen); + + Reset(); + } + + public virtual void Update(byte[] input, int inOff, int len) + { + m_digest.BlockUpdate(input, inOff, len); + } + + public virtual byte[] CalculateMac() + { + byte[] result = new byte[m_digest.GetDigestSize()]; + DoFinal(result, 0); + return result; + } + + public virtual void CalculateMac(byte[] output, int outOff) + { + DoFinal(output, outOff); + } + + public virtual int InternalBlockSize + { + get { return m_digest.GetByteLength(); } + } + + public virtual int MacLength + { + get { return m_digest.GetDigestSize(); } + } + + /** + * Reset the mac generator. + */ + public virtual void Reset() + { + m_digest.Reset(); + m_digest.BlockUpdate(m_secret, 0, m_secret.Length); + m_digest.BlockUpdate(IPAD, 0, m_padLength); + } + + private void DoFinal(byte[] output, int outOff) + { + byte[] tmp = new byte[m_digest.GetDigestSize()]; + m_digest.DoFinal(tmp, 0); + + m_digest.BlockUpdate(m_secret, 0, m_secret.Length); + m_digest.BlockUpdate(OPAD, 0, m_padLength); + m_digest.BlockUpdate(tmp, 0, tmp.Length); + + m_digest.DoFinal(output, outOff); + + Reset(); + } + + private static byte[] GenPad(byte b, int count) + { + byte[] padding = new byte[count]; + Arrays.Fill(padding, b); + return padding; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcSsl3Hmac.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcSsl3Hmac.cs.meta new file mode 100644 index 0000000..e0f9ebf --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcSsl3Hmac.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1b565c5433f6ec24981da139064ab768 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsAeadCipherImpl.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsAeadCipherImpl.cs new file mode 100644 index 0000000..ae05a16 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsAeadCipherImpl.cs @@ -0,0 +1,54 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Modes; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Tls.Crypto.Impl.BC +{ + internal sealed class BcTlsAeadCipherImpl + : TlsAeadCipherImpl + { + private readonly bool m_isEncrypting; + private readonly IAeadBlockCipher m_cipher; + + private KeyParameter key; + + internal BcTlsAeadCipherImpl(IAeadBlockCipher cipher, bool isEncrypting) + { + this.m_cipher = cipher; + this.m_isEncrypting = isEncrypting; + } + + public void SetKey(byte[] key, int keyOff, int keyLen) + { + this.key = new KeyParameter(key, keyOff, keyLen); + } + + public void Init(byte[] nonce, int macSize, byte[] additionalData) + { + m_cipher.Init(m_isEncrypting, new AeadParameters(key, macSize * 8, nonce, additionalData)); + } + + public int GetOutputSize(int inputLength) + { + return m_cipher.GetOutputSize(inputLength); + } + + public int DoFinal(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset) + { + int len = m_cipher.ProcessBytes(input, inputOffset, inputLength, output, outputOffset); + + try + { + len += m_cipher.DoFinal(output, outputOffset + len); + } + catch (InvalidCipherTextException e) + { + throw new TlsFatalAlert(AlertDescription.bad_record_mac, e); + } + + return len; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsAeadCipherImpl.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsAeadCipherImpl.cs.meta new file mode 100644 index 0000000..28b3c80 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsAeadCipherImpl.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d0d61d11315b7db4bbe6f0e17edece64 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsBlockCipherImpl.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsBlockCipherImpl.cs new file mode 100644 index 0000000..b51d38c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsBlockCipherImpl.cs @@ -0,0 +1,49 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Tls.Crypto.Impl.BC +{ + internal sealed class BcTlsBlockCipherImpl + : TlsBlockCipherImpl + { + private readonly bool m_isEncrypting; + private readonly IBlockCipher m_cipher; + + private KeyParameter key; + + internal BcTlsBlockCipherImpl(IBlockCipher cipher, bool isEncrypting) + { + this.m_cipher = cipher; + this.m_isEncrypting = isEncrypting; + } + + public void SetKey(byte[] key, int keyOff, int keyLen) + { + this.key = new KeyParameter(key, keyOff, keyLen); + } + + public void Init(byte[] iv, int ivOff, int ivLen) + { + m_cipher.Init(m_isEncrypting, new ParametersWithIV(key, iv, ivOff, ivLen)); + } + + public int DoFinal(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset) + { + int blockSize = m_cipher.GetBlockSize(); + + for (int i = 0; i < inputLength; i += blockSize) + { + m_cipher.ProcessBlock(input, inputOffset + i, output, outputOffset + i); + } + + return inputLength; + } + + public int GetBlockSize() + { + return m_cipher.GetBlockSize(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsBlockCipherImpl.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsBlockCipherImpl.cs.meta new file mode 100644 index 0000000..08f0a24 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsBlockCipherImpl.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c1cfbf8eba86fc34ca26835151f07bae +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsCertificate.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsCertificate.cs new file mode 100644 index 0000000..9d41570 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsCertificate.cs @@ -0,0 +1,488 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls.Crypto.Impl.BC +{ + /// Implementation class for a single X.509 certificate based on the BC light-weight API. + public class BcTlsCertificate + : TlsCertificate + { + /// + public static BcTlsCertificate Convert(BcTlsCrypto crypto, TlsCertificate certificate) + { + if (certificate is BcTlsCertificate) + return (BcTlsCertificate)certificate; + + return new BcTlsCertificate(crypto, certificate.GetEncoded()); + } + + /// + public static X509CertificateStructure ParseCertificate(byte[] encoding) + { + try + { + return X509CertificateStructure.GetInstance(encoding); + } + catch (Exception e) + { + throw new TlsFatalAlert(AlertDescription.bad_certificate, e); + } + } + + protected readonly BcTlsCrypto m_crypto; + protected readonly X509CertificateStructure m_certificate; + + protected DHPublicKeyParameters m_pubKeyDH = null; + protected ECPublicKeyParameters m_pubKeyEC = null; + protected Ed25519PublicKeyParameters m_pubKeyEd25519 = null; + protected Ed448PublicKeyParameters m_pubKeyEd448 = null; + protected RsaKeyParameters m_pubKeyRsa = null; + + /// + public BcTlsCertificate(BcTlsCrypto crypto, byte[] encoding) + : this(crypto, ParseCertificate(encoding)) + { + } + + public BcTlsCertificate(BcTlsCrypto crypto, X509CertificateStructure certificate) + { + this.m_crypto = crypto; + this.m_certificate = certificate; + } + + /// + public virtual TlsEncryptor CreateEncryptor(int tlsCertificateRole) + { + ValidateKeyUsage(KeyUsage.KeyEncipherment); + + switch (tlsCertificateRole) + { + case TlsCertificateRole.RsaEncryption: + { + this.m_pubKeyRsa = GetPubKeyRsa(); + return new BcTlsRsaEncryptor(m_crypto, m_pubKeyRsa); + } + // TODO[gmssl] + //case TlsCertificateRole.Sm2Encryption: + //{ + // this.m_pubKeyEC = GetPubKeyEC(); + // return new BcTlsSM2Encryptor(m_crypto, m_pubKeyEC); + //} + } + + throw new TlsFatalAlert(AlertDescription.certificate_unknown); + } + + /// + public virtual TlsVerifier CreateVerifier(short signatureAlgorithm) + { + switch (signatureAlgorithm) + { + case SignatureAlgorithm.rsa_pss_rsae_sha256: + case SignatureAlgorithm.rsa_pss_rsae_sha384: + case SignatureAlgorithm.rsa_pss_rsae_sha512: + case SignatureAlgorithm.ed25519: + case SignatureAlgorithm.ed448: + case SignatureAlgorithm.rsa_pss_pss_sha256: + case SignatureAlgorithm.rsa_pss_pss_sha384: + case SignatureAlgorithm.rsa_pss_pss_sha512: + return CreateVerifier(SignatureScheme.From(HashAlgorithm.Intrinsic, signatureAlgorithm)); + } + + ValidateKeyUsage(KeyUsage.DigitalSignature); + + switch (signatureAlgorithm) + { + case SignatureAlgorithm.rsa: + ValidateRsa_Pkcs1(); + return new BcTlsRsaVerifier(m_crypto, GetPubKeyRsa()); + + case SignatureAlgorithm.dsa: + return new BcTlsDsaVerifier(m_crypto, GetPubKeyDss()); + + case SignatureAlgorithm.ecdsa: + return new BcTlsECDsaVerifier(m_crypto, GetPubKeyEC()); + + default: + throw new TlsFatalAlert(AlertDescription.certificate_unknown); + } + } + + /// + public virtual TlsVerifier CreateVerifier(int signatureScheme) + { + ValidateKeyUsage(KeyUsage.DigitalSignature); + + switch (signatureScheme) + { + case SignatureScheme.ecdsa_brainpoolP256r1tls13_sha256: + case SignatureScheme.ecdsa_brainpoolP384r1tls13_sha384: + case SignatureScheme.ecdsa_brainpoolP512r1tls13_sha512: + case SignatureScheme.ecdsa_secp256r1_sha256: + case SignatureScheme.ecdsa_secp384r1_sha384: + case SignatureScheme.ecdsa_secp521r1_sha512: + case SignatureScheme.ecdsa_sha1: + return new BcTlsECDsa13Verifier(m_crypto, GetPubKeyEC(), signatureScheme); + + case SignatureScheme.ed25519: + return new BcTlsEd25519Verifier(m_crypto, GetPubKeyEd25519()); + + case SignatureScheme.ed448: + return new BcTlsEd448Verifier(m_crypto, GetPubKeyEd448()); + + case SignatureScheme.rsa_pkcs1_sha1: + case SignatureScheme.rsa_pkcs1_sha256: + case SignatureScheme.rsa_pkcs1_sha384: + case SignatureScheme.rsa_pkcs1_sha512: + { + ValidateRsa_Pkcs1(); + return new BcTlsRsaVerifier(m_crypto, GetPubKeyRsa()); + } + + case SignatureScheme.rsa_pss_pss_sha256: + case SignatureScheme.rsa_pss_pss_sha384: + case SignatureScheme.rsa_pss_pss_sha512: + { + ValidateRsa_Pss_Pss(SignatureScheme.GetSignatureAlgorithm(signatureScheme)); + return new BcTlsRsaPssVerifier(m_crypto, GetPubKeyRsa(), signatureScheme); + } + + case SignatureScheme.rsa_pss_rsae_sha256: + case SignatureScheme.rsa_pss_rsae_sha384: + case SignatureScheme.rsa_pss_rsae_sha512: + { + ValidateRsa_Pss_Rsae(); + return new BcTlsRsaPssVerifier(m_crypto, GetPubKeyRsa(), signatureScheme); + } + + // TODO[RFC 8998] + //case SignatureScheme.sm2sig_sm3: + // return new BcTlsSM2Verifier(m_crypto, GetPubKeyEC(), Strings.ToByteArray("TLSv1.3+GM+Cipher+Suite")); + + default: + throw new TlsFatalAlert(AlertDescription.certificate_unknown); + } + } + + /// + public virtual byte[] GetEncoded() + { + return m_certificate.GetEncoded(Asn1Encodable.Der); + } + + /// + public virtual byte[] GetExtension(DerObjectIdentifier extensionOid) + { + X509Extensions extensions = m_certificate.TbsCertificate.Extensions; + if (extensions != null) + { + X509Extension extension = extensions.GetExtension(extensionOid); + if (extension != null) + { + return Arrays.Clone(extension.Value.GetOctets()); + } + } + return null; + } + + public virtual BigInteger SerialNumber + { + get { return m_certificate.SerialNumber.Value; } + } + + public virtual string SigAlgOid + { + get { return m_certificate.SignatureAlgorithm.Algorithm.Id; } + } + + public virtual Asn1Encodable GetSigAlgParams() + { + return m_certificate.SignatureAlgorithm.Parameters; + } + + /// + public virtual short GetLegacySignatureAlgorithm() + { + AsymmetricKeyParameter publicKey = GetPublicKey(); + if (publicKey.IsPrivate) + throw new TlsFatalAlert(AlertDescription.internal_error); + + if (!SupportsKeyUsage(KeyUsage.DigitalSignature)) + return -1; + + /* + * RFC 5246 7.4.6. Client Certificate + */ + + /* + * RSA public key; the certificate MUST allow the key to be used for signing with the + * signature scheme and hash algorithm that will be employed in the certificate verify + * message. + */ + if (publicKey is RsaKeyParameters) + return SignatureAlgorithm.rsa; + + /* + * DSA public key; the certificate MUST allow the key to be used for signing with the + * hash algorithm that will be employed in the certificate verify message. + */ + if (publicKey is DsaPublicKeyParameters) + return SignatureAlgorithm.dsa; + + /* + * ECDSA-capable public key; the certificate MUST allow the key to be used for signing + * with the hash algorithm that will be employed in the certificate verify message; the + * public key MUST use a curve and point format supported by the server. + */ + if (publicKey is ECPublicKeyParameters) + { + // TODO Check the curve and point format + return SignatureAlgorithm.ecdsa; + } + + return -1; + } + + /// + public virtual DHPublicKeyParameters GetPubKeyDH() + { + try + { + return (DHPublicKeyParameters)GetPublicKey(); + } + catch (InvalidCastException e) + { + throw new TlsFatalAlert(AlertDescription.certificate_unknown, e); + } + } + + /// + public virtual DsaPublicKeyParameters GetPubKeyDss() + { + try + { + return (DsaPublicKeyParameters)GetPublicKey(); + } + catch (InvalidCastException e) + { + throw new TlsFatalAlert(AlertDescription.certificate_unknown, e); + } + } + + /// + public virtual ECPublicKeyParameters GetPubKeyEC() + { + try + { + return (ECPublicKeyParameters)GetPublicKey(); + } + catch (InvalidCastException e) + { + throw new TlsFatalAlert(AlertDescription.certificate_unknown, e); + } + } + + /// + public virtual Ed25519PublicKeyParameters GetPubKeyEd25519() + { + try + { + return (Ed25519PublicKeyParameters)GetPublicKey(); + } + catch (InvalidCastException e) + { + throw new TlsFatalAlert(AlertDescription.certificate_unknown, e); + } + } + + /// + public virtual Ed448PublicKeyParameters GetPubKeyEd448() + { + try + { + return (Ed448PublicKeyParameters)GetPublicKey(); + } + catch (InvalidCastException e) + { + throw new TlsFatalAlert(AlertDescription.certificate_unknown, e); + } + } + + /// + public virtual RsaKeyParameters GetPubKeyRsa() + { + try + { + return (RsaKeyParameters)GetPublicKey(); + } + catch (InvalidCastException e) + { + throw new TlsFatalAlert(AlertDescription.certificate_unknown, e); + } + } + + /// + public virtual bool SupportsSignatureAlgorithm(short signatureAlgorithm) + { + return SupportsSignatureAlgorithm(signatureAlgorithm, KeyUsage.DigitalSignature); + } + + /// + public virtual bool SupportsSignatureAlgorithmCA(short signatureAlgorithm) + { + return SupportsSignatureAlgorithm(signatureAlgorithm, KeyUsage.KeyCertSign); + } + + /// + public virtual TlsCertificate CheckUsageInRole(int tlsCertificateRole) + { + switch (tlsCertificateRole) + { + case TlsCertificateRole.DH: + { + ValidateKeyUsage(KeyUsage.KeyAgreement); + this.m_pubKeyDH = GetPubKeyDH(); + return this; + } + case TlsCertificateRole.ECDH: + { + ValidateKeyUsage(KeyUsage.KeyAgreement); + this.m_pubKeyEC = GetPubKeyEC(); + return this; + } + } + + throw new TlsFatalAlert(AlertDescription.certificate_unknown); + } + + /// + protected virtual AsymmetricKeyParameter GetPublicKey() + { + SubjectPublicKeyInfo keyInfo = m_certificate.SubjectPublicKeyInfo; + try + { + return PublicKeyFactory.CreateKey(keyInfo); + } + catch (Exception e) + { + throw new TlsFatalAlert(AlertDescription.unsupported_certificate, e); + } + } + + protected virtual bool SupportsKeyUsage(int keyUsageBits) + { + X509Extensions exts = m_certificate.TbsCertificate.Extensions; + if (exts != null) + { + KeyUsage ku = KeyUsage.FromExtensions(exts); + if (ku != null) + { + int bits = ku.GetBytes()[0] & 0xff; + if ((bits & keyUsageBits) != keyUsageBits) + return false; + } + } + return true; + } + + protected virtual bool SupportsRsa_Pkcs1() + { + AlgorithmIdentifier pubKeyAlgID = m_certificate.SubjectPublicKeyInfo.AlgorithmID; + return RsaUtilities.SupportsPkcs1(pubKeyAlgID); + } + + protected virtual bool SupportsRsa_Pss_Pss(short signatureAlgorithm) + { + AlgorithmIdentifier pubKeyAlgID = m_certificate.SubjectPublicKeyInfo.AlgorithmID; + return RsaUtilities.SupportsPss_Pss(signatureAlgorithm, pubKeyAlgID); + } + + protected virtual bool SupportsRsa_Pss_Rsae() + { + AlgorithmIdentifier pubKeyAlgID = m_certificate.SubjectPublicKeyInfo.AlgorithmID; + return RsaUtilities.SupportsPss_Rsae(pubKeyAlgID); + } + + /// + protected virtual bool SupportsSignatureAlgorithm(short signatureAlgorithm, int keyUsage) + { + if (!SupportsKeyUsage(keyUsage)) + return false; + + AsymmetricKeyParameter publicKey = GetPublicKey(); + + switch (signatureAlgorithm) + { + case SignatureAlgorithm.rsa: + return SupportsRsa_Pkcs1() + && publicKey is RsaKeyParameters; + + case SignatureAlgorithm.dsa: + return publicKey is DsaPublicKeyParameters; + + case SignatureAlgorithm.ecdsa: + case SignatureAlgorithm.ecdsa_brainpoolP256r1tls13_sha256: + case SignatureAlgorithm.ecdsa_brainpoolP384r1tls13_sha384: + case SignatureAlgorithm.ecdsa_brainpoolP512r1tls13_sha512: + return publicKey is ECPublicKeyParameters; + + case SignatureAlgorithm.ed25519: + return publicKey is Ed25519PublicKeyParameters; + + case SignatureAlgorithm.ed448: + return publicKey is Ed448PublicKeyParameters; + + case SignatureAlgorithm.rsa_pss_rsae_sha256: + case SignatureAlgorithm.rsa_pss_rsae_sha384: + case SignatureAlgorithm.rsa_pss_rsae_sha512: + return SupportsRsa_Pss_Rsae() + && publicKey is RsaKeyParameters; + + case SignatureAlgorithm.rsa_pss_pss_sha256: + case SignatureAlgorithm.rsa_pss_pss_sha384: + case SignatureAlgorithm.rsa_pss_pss_sha512: + return SupportsRsa_Pss_Pss(signatureAlgorithm) + && publicKey is RsaKeyParameters; + + default: + return false; + } + } + + /// + public virtual void ValidateKeyUsage(int keyUsageBits) + { + if (!SupportsKeyUsage(keyUsageBits)) + throw new TlsFatalAlert(AlertDescription.certificate_unknown); + } + + /// + protected virtual void ValidateRsa_Pkcs1() + { + if (!SupportsRsa_Pkcs1()) + throw new TlsFatalAlert(AlertDescription.certificate_unknown); + } + + /// + protected virtual void ValidateRsa_Pss_Pss(short signatureAlgorithm) + { + if (!SupportsRsa_Pss_Pss(signatureAlgorithm)) + throw new TlsFatalAlert(AlertDescription.certificate_unknown); + } + + /// + protected virtual void ValidateRsa_Pss_Rsae() + { + if (!SupportsRsa_Pss_Rsae()) + throw new TlsFatalAlert(AlertDescription.certificate_unknown); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsCertificate.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsCertificate.cs.meta new file mode 100644 index 0000000..5fc9fdd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsCertificate.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0217cc2c8aaeb2e46a18555e3c9ce78e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsCrypto.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsCrypto.cs new file mode 100644 index 0000000..69e353b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsCrypto.cs @@ -0,0 +1,642 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Agreement.Srp; +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Macs; +using Org.BouncyCastle.Crypto.Modes; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Prng; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls.Crypto.Impl.BC +{ + /** + * Class for providing cryptographic services for TLS based on implementations in the BC light-weight API. + *

    + * This class provides default implementations for everything. If you need to customise it, extend the class + * and override the appropriate methods. + *

    + */ + public class BcTlsCrypto + : AbstractTlsCrypto + { + private readonly SecureRandom m_entropySource; + + public BcTlsCrypto(SecureRandom entropySource) + { + this.m_entropySource = entropySource; + } + + internal virtual BcTlsSecret AdoptLocalSecret(byte[] data) + { + return new BcTlsSecret(this, data); + } + + public override SecureRandom SecureRandom + { + get { return m_entropySource; } + } + + public override TlsCertificate CreateCertificate(byte[] encoding) + { + return new BcTlsCertificate(this, encoding); + } + + public override TlsCipher CreateCipher(TlsCryptoParameters cryptoParams, int encryptionAlgorithm, + int macAlgorithm) + { + switch (encryptionAlgorithm) + { + case EncryptionAlgorithm.AES_128_CBC: + case EncryptionAlgorithm.ARIA_128_CBC: + case EncryptionAlgorithm.CAMELLIA_128_CBC: + case EncryptionAlgorithm.SEED_CBC: + case EncryptionAlgorithm.SM4_CBC: + return CreateCipher_Cbc(cryptoParams, encryptionAlgorithm, 16, macAlgorithm); + + case EncryptionAlgorithm.cls_3DES_EDE_CBC: + return CreateCipher_Cbc(cryptoParams, encryptionAlgorithm, 24, macAlgorithm); + + case EncryptionAlgorithm.AES_256_CBC: + case EncryptionAlgorithm.ARIA_256_CBC: + case EncryptionAlgorithm.CAMELLIA_256_CBC: + return CreateCipher_Cbc(cryptoParams, encryptionAlgorithm, 32, macAlgorithm); + + case EncryptionAlgorithm.AES_128_CCM: + // NOTE: Ignores macAlgorithm + return CreateCipher_Aes_Ccm(cryptoParams, 16, 16); + case EncryptionAlgorithm.AES_128_CCM_8: + // NOTE: Ignores macAlgorithm + return CreateCipher_Aes_Ccm(cryptoParams, 16, 8); + case EncryptionAlgorithm.AES_128_GCM: + // NOTE: Ignores macAlgorithm + return CreateCipher_Aes_Gcm(cryptoParams, 16, 16); + case EncryptionAlgorithm.AES_256_CCM: + // NOTE: Ignores macAlgorithm + return CreateCipher_Aes_Ccm(cryptoParams, 32, 16); + case EncryptionAlgorithm.AES_256_CCM_8: + // NOTE: Ignores macAlgorithm + return CreateCipher_Aes_Ccm(cryptoParams, 32, 8); + case EncryptionAlgorithm.AES_256_GCM: + // NOTE: Ignores macAlgorithm + return CreateCipher_Aes_Gcm(cryptoParams, 32, 16); + case EncryptionAlgorithm.ARIA_128_GCM: + // NOTE: Ignores macAlgorithm + return CreateCipher_Aria_Gcm(cryptoParams, 16, 16); + case EncryptionAlgorithm.ARIA_256_GCM: + // NOTE: Ignores macAlgorithm + return CreateCipher_Aria_Gcm(cryptoParams, 32, 16); + case EncryptionAlgorithm.CAMELLIA_128_GCM: + // NOTE: Ignores macAlgorithm + return CreateCipher_Camellia_Gcm(cryptoParams, 16, 16); + case EncryptionAlgorithm.CAMELLIA_256_GCM: + // NOTE: Ignores macAlgorithm + return CreateCipher_Camellia_Gcm(cryptoParams, 32, 16); + case EncryptionAlgorithm.CHACHA20_POLY1305: + // NOTE: Ignores macAlgorithm + return CreateChaCha20Poly1305(cryptoParams); + case EncryptionAlgorithm.NULL: + return CreateNullCipher(cryptoParams, macAlgorithm); + case EncryptionAlgorithm.SM4_CCM: + // NOTE: Ignores macAlgorithm + return CreateCipher_SM4_Ccm(cryptoParams); + case EncryptionAlgorithm.SM4_GCM: + // NOTE: Ignores macAlgorithm + return CreateCipher_SM4_Gcm(cryptoParams); + + case EncryptionAlgorithm.DES40_CBC: + case EncryptionAlgorithm.DES_CBC: + case EncryptionAlgorithm.IDEA_CBC: + case EncryptionAlgorithm.RC2_CBC_40: + case EncryptionAlgorithm.RC4_128: + case EncryptionAlgorithm.RC4_40: + default: + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + public override TlsDHDomain CreateDHDomain(TlsDHConfig dhConfig) + { + return new BcTlsDHDomain(this, dhConfig); + } + + public override TlsECDomain CreateECDomain(TlsECConfig ecConfig) + { + switch (ecConfig.NamedGroup) + { + case NamedGroup.x25519: + return new BcX25519Domain(this); + case NamedGroup.x448: + return new BcX448Domain(this); + default: + return new BcTlsECDomain(this, ecConfig); + } + } + + public override TlsNonceGenerator CreateNonceGenerator(byte[] additionalSeedMaterial) + { + IDigest digest = CreateDigest(CryptoHashAlgorithm.sha256); + + byte[] seed = new byte[digest.GetDigestSize()]; + SecureRandom.NextBytes(seed); + + DigestRandomGenerator randomGenerator = new DigestRandomGenerator(digest); + randomGenerator.AddSeedMaterial(additionalSeedMaterial); + randomGenerator.AddSeedMaterial(seed); + + return new BcTlsNonceGenerator(randomGenerator); + } + + public override bool HasAllRawSignatureAlgorithms() + { + // TODO[RFC 8422] Revisit the need to buffer the handshake for "Intrinsic" hash signatures + return !HasSignatureAlgorithm(SignatureAlgorithm.ed25519) + && !HasSignatureAlgorithm(SignatureAlgorithm.ed448); + } + + public override bool HasDHAgreement() + { + return true; + } + + public override bool HasECDHAgreement() + { + return true; + } + + public override bool HasEncryptionAlgorithm(int encryptionAlgorithm) + { + switch (encryptionAlgorithm) + { + case EncryptionAlgorithm.DES40_CBC: + case EncryptionAlgorithm.DES_CBC: + case EncryptionAlgorithm.IDEA_CBC: + case EncryptionAlgorithm.RC2_CBC_40: + case EncryptionAlgorithm.RC4_128: + case EncryptionAlgorithm.RC4_40: + return false; + + default: + return true; + } + } + + public override bool HasCryptoHashAlgorithm(int cryptoHashAlgorithm) + { + return true; + } + + public override bool HasCryptoSignatureAlgorithm(int cryptoSignatureAlgorithm) + { + switch (cryptoSignatureAlgorithm) + { + case CryptoSignatureAlgorithm.rsa: + case CryptoSignatureAlgorithm.dsa: + case CryptoSignatureAlgorithm.ecdsa: + case CryptoSignatureAlgorithm.rsa_pss_rsae_sha256: + case CryptoSignatureAlgorithm.rsa_pss_rsae_sha384: + case CryptoSignatureAlgorithm.rsa_pss_rsae_sha512: + case CryptoSignatureAlgorithm.ed25519: + case CryptoSignatureAlgorithm.ed448: + case CryptoSignatureAlgorithm.rsa_pss_pss_sha256: + case CryptoSignatureAlgorithm.rsa_pss_pss_sha384: + case CryptoSignatureAlgorithm.rsa_pss_pss_sha512: + return true; + + // TODO[draft-smyshlyaev-tls12-gost-suites-10] + case CryptoSignatureAlgorithm.gostr34102012_256: + case CryptoSignatureAlgorithm.gostr34102012_512: + + // TODO[RFC 8998] + case CryptoSignatureAlgorithm.sm2: + + default: + return false; + } + } + + public override bool HasMacAlgorithm(int macAlgorithm) + { + return true; + } + + public override bool HasNamedGroup(int namedGroup) + { + return NamedGroup.RefersToASpecificGroup(namedGroup); + } + + public override bool HasRsaEncryption() + { + return true; + } + + public override bool HasSignatureAlgorithm(short signatureAlgorithm) + { + switch (signatureAlgorithm) + { + case SignatureAlgorithm.rsa: + case SignatureAlgorithm.dsa: + case SignatureAlgorithm.ecdsa: + case SignatureAlgorithm.ed25519: + case SignatureAlgorithm.ed448: + case SignatureAlgorithm.rsa_pss_rsae_sha256: + case SignatureAlgorithm.rsa_pss_rsae_sha384: + case SignatureAlgorithm.rsa_pss_rsae_sha512: + case SignatureAlgorithm.rsa_pss_pss_sha256: + case SignatureAlgorithm.rsa_pss_pss_sha384: + case SignatureAlgorithm.rsa_pss_pss_sha512: + case SignatureAlgorithm.ecdsa_brainpoolP256r1tls13_sha256: + case SignatureAlgorithm.ecdsa_brainpoolP384r1tls13_sha384: + case SignatureAlgorithm.ecdsa_brainpoolP512r1tls13_sha512: + return true; + + // TODO[draft-smyshlyaev-tls12-gost-suites-10] + case SignatureAlgorithm.gostr34102012_256: + case SignatureAlgorithm.gostr34102012_512: + // TODO[RFC 8998] + //case SignatureAlgorithm.sm2: + default: + return false; + } + } + + public override bool HasSignatureAndHashAlgorithm(SignatureAndHashAlgorithm sigAndHashAlgorithm) + { + short signature = sigAndHashAlgorithm.Signature; + + switch (sigAndHashAlgorithm.Hash) + { + case HashAlgorithm.md5: + return SignatureAlgorithm.rsa == signature && HasSignatureAlgorithm(signature); + default: + return HasSignatureAlgorithm(signature); + } + } + + public override bool HasSignatureScheme(int signatureScheme) + { + switch (signatureScheme) + { + case SignatureScheme.sm2sig_sm3: + return false; + default: + { + short signature = SignatureScheme.GetSignatureAlgorithm(signatureScheme); + + switch(SignatureScheme.GetCryptoHashAlgorithm(signatureScheme)) + { + case CryptoHashAlgorithm.md5: + return SignatureAlgorithm.rsa == signature && HasSignatureAlgorithm(signature); + default: + return HasSignatureAlgorithm(signature); + } + } + } + } + + public override bool HasSrpAuthentication() + { + return true; + } + + public override TlsSecret CreateSecret(byte[] data) + { + try + { + return AdoptLocalSecret(Arrays.Clone(data)); + } + finally + { + // TODO[tls-ops] Add this after checking all callers + //if (data != null) + //{ + // Array.Clear(data, 0, data.Length); + //} + } + } + + public override TlsSecret GenerateRsaPreMasterSecret(ProtocolVersion version) + { + byte[] data = new byte[48]; + SecureRandom.NextBytes(data); + TlsUtilities.WriteVersion(version, data, 0); + return AdoptLocalSecret(data); + } + + public virtual IDigest CloneDigest(int cryptoHashAlgorithm, IDigest digest) + { + switch (cryptoHashAlgorithm) + { + case CryptoHashAlgorithm.md5: + return new MD5Digest((MD5Digest)digest); + case CryptoHashAlgorithm.sha1: + return new Sha1Digest((Sha1Digest)digest); + case CryptoHashAlgorithm.sha224: + return new Sha224Digest((Sha224Digest)digest); + case CryptoHashAlgorithm.sha256: + return new Sha256Digest((Sha256Digest)digest); + case CryptoHashAlgorithm.sha384: + return new Sha384Digest((Sha384Digest)digest); + case CryptoHashAlgorithm.sha512: + return new Sha512Digest((Sha512Digest)digest); + case CryptoHashAlgorithm.sm3: + return new SM3Digest((SM3Digest)digest); + default: + throw new ArgumentException("invalid CryptoHashAlgorithm: " + cryptoHashAlgorithm); + } + } + + public virtual IDigest CreateDigest(int cryptoHashAlgorithm) + { + switch (cryptoHashAlgorithm) + { + case CryptoHashAlgorithm.md5: + return new MD5Digest(); + case CryptoHashAlgorithm.sha1: + return new Sha1Digest(); + case CryptoHashAlgorithm.sha224: + return new Sha224Digest(); + case CryptoHashAlgorithm.sha256: + return new Sha256Digest(); + case CryptoHashAlgorithm.sha384: + return new Sha384Digest(); + case CryptoHashAlgorithm.sha512: + return new Sha512Digest(); + case CryptoHashAlgorithm.sm3: + return new SM3Digest(); + default: + throw new ArgumentException("invalid CryptoHashAlgorithm: " + cryptoHashAlgorithm); + } + } + + public override TlsHash CreateHash(int cryptoHashAlgorithm) + { + return new BcTlsHash(this, cryptoHashAlgorithm); + } + + protected virtual IBlockCipher CreateBlockCipher(int encryptionAlgorithm) + { + switch (encryptionAlgorithm) + { + case EncryptionAlgorithm.cls_3DES_EDE_CBC: + return CreateDesEdeEngine(); + case EncryptionAlgorithm.AES_128_CBC: + case EncryptionAlgorithm.AES_256_CBC: + return CreateAesEngine(); + case EncryptionAlgorithm.ARIA_128_CBC: + case EncryptionAlgorithm.ARIA_256_CBC: + return CreateAriaEngine(); + case EncryptionAlgorithm.CAMELLIA_128_CBC: + case EncryptionAlgorithm.CAMELLIA_256_CBC: + return CreateCamelliaEngine(); + case EncryptionAlgorithm.SEED_CBC: + return CreateSeedEngine(); + case EncryptionAlgorithm.SM4_CBC: + return CreateSM4Engine(); + default: + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + protected virtual IBlockCipher CreateCbcBlockCipher(IBlockCipher blockCipher) + { + return new CbcBlockCipher(blockCipher); + } + + protected virtual IBlockCipher CreateCbcBlockCipher(int encryptionAlgorithm) + { + return CreateCbcBlockCipher(CreateBlockCipher(encryptionAlgorithm)); + } + + protected virtual TlsCipher CreateChaCha20Poly1305(TlsCryptoParameters cryptoParams) + { + BcChaCha20Poly1305 encrypt = new BcChaCha20Poly1305(true); + BcChaCha20Poly1305 decrypt = new BcChaCha20Poly1305(false); + + return new TlsAeadCipher(cryptoParams, encrypt, decrypt, 32, 16, TlsAeadCipher.AEAD_CHACHA20_POLY1305); + } + + protected virtual TlsAeadCipher CreateCipher_Aes_Ccm(TlsCryptoParameters cryptoParams, int cipherKeySize, + int macSize) + { + BcTlsAeadCipherImpl encrypt = new BcTlsAeadCipherImpl(CreateAeadBlockCipher_Aes_Ccm(), true); + BcTlsAeadCipherImpl decrypt = new BcTlsAeadCipherImpl(CreateAeadBlockCipher_Aes_Ccm(), false); + + return new TlsAeadCipher(cryptoParams, encrypt, decrypt, cipherKeySize, macSize, TlsAeadCipher.AEAD_CCM); + } + + protected virtual TlsAeadCipher CreateCipher_Aes_Gcm(TlsCryptoParameters cryptoParams, int cipherKeySize, + int macSize) + { + BcTlsAeadCipherImpl encrypt = new BcTlsAeadCipherImpl(CreateAeadBlockCipher_Aes_Gcm(), true); + BcTlsAeadCipherImpl decrypt = new BcTlsAeadCipherImpl(CreateAeadBlockCipher_Aes_Gcm(), false); + + return new TlsAeadCipher(cryptoParams, encrypt, decrypt, cipherKeySize, macSize, TlsAeadCipher.AEAD_GCM); + } + + protected virtual TlsAeadCipher CreateCipher_Aria_Gcm(TlsCryptoParameters cryptoParams, int cipherKeySize, + int macSize) + { + BcTlsAeadCipherImpl encrypt = new BcTlsAeadCipherImpl(CreateAeadBlockCipher_Aria_Gcm(), true); + BcTlsAeadCipherImpl decrypt = new BcTlsAeadCipherImpl(CreateAeadBlockCipher_Aria_Gcm(), false); + + return new TlsAeadCipher(cryptoParams, encrypt, decrypt, cipherKeySize, macSize, TlsAeadCipher.AEAD_GCM); + } + + protected virtual TlsAeadCipher CreateCipher_Camellia_Gcm(TlsCryptoParameters cryptoParams, int cipherKeySize, + int macSize) + { + BcTlsAeadCipherImpl encrypt = new BcTlsAeadCipherImpl(CreateAeadBlockCipher_Camellia_Gcm(), true); + BcTlsAeadCipherImpl decrypt = new BcTlsAeadCipherImpl(CreateAeadBlockCipher_Camellia_Gcm(), false); + + return new TlsAeadCipher(cryptoParams, encrypt, decrypt, cipherKeySize, macSize, TlsAeadCipher.AEAD_GCM); + } + + protected virtual TlsCipher CreateCipher_Cbc(TlsCryptoParameters cryptoParams, int encryptionAlgorithm, + int cipherKeySize, int macAlgorithm) + { + BcTlsBlockCipherImpl encrypt = new BcTlsBlockCipherImpl(CreateCbcBlockCipher(encryptionAlgorithm), true); + BcTlsBlockCipherImpl decrypt = new BcTlsBlockCipherImpl(CreateCbcBlockCipher(encryptionAlgorithm), false); + + TlsHmac clientMac = CreateMac(cryptoParams, macAlgorithm); + TlsHmac serverMac = CreateMac(cryptoParams, macAlgorithm); + + return new TlsBlockCipher(cryptoParams, encrypt, decrypt, clientMac, serverMac, cipherKeySize); + } + + protected virtual TlsAeadCipher CreateCipher_SM4_Ccm(TlsCryptoParameters cryptoParams) + { + BcTlsAeadCipherImpl encrypt = new BcTlsAeadCipherImpl(CreateAeadBlockCipher_SM4_Ccm(), true); + BcTlsAeadCipherImpl decrypt = new BcTlsAeadCipherImpl(CreateAeadBlockCipher_SM4_Ccm(), false); + + return new TlsAeadCipher(cryptoParams, encrypt, decrypt, 16, 16, TlsAeadCipher.AEAD_CCM); + } + + protected virtual TlsAeadCipher CreateCipher_SM4_Gcm(TlsCryptoParameters cryptoParams) + { + BcTlsAeadCipherImpl encrypt = new BcTlsAeadCipherImpl(CreateAeadBlockCipher_SM4_Gcm(), true); + BcTlsAeadCipherImpl decrypt = new BcTlsAeadCipherImpl(CreateAeadBlockCipher_SM4_Gcm(), false); + + return new TlsAeadCipher(cryptoParams, encrypt, decrypt, 16, 16, TlsAeadCipher.AEAD_GCM); + } + + protected virtual TlsNullCipher CreateNullCipher(TlsCryptoParameters cryptoParams, int macAlgorithm) + { + return new TlsNullCipher(cryptoParams, CreateMac(cryptoParams, macAlgorithm), + CreateMac(cryptoParams, macAlgorithm)); + } + + protected virtual IBlockCipher CreateAesEngine() + { + return new AesEngine(); + } + + protected virtual IBlockCipher CreateAriaEngine() + { + return new AriaEngine(); + } + + protected virtual IBlockCipher CreateCamelliaEngine() + { + return new CamelliaEngine(); + } + + protected virtual IBlockCipher CreateDesEdeEngine() + { + return new DesEdeEngine(); + } + + protected virtual IBlockCipher CreateSeedEngine() + { + return new SeedEngine(); + } + + protected virtual IBlockCipher CreateSM4Engine() + { + return new SM4Engine(); + } + + protected virtual IAeadBlockCipher CreateCcmMode(IBlockCipher engine) + { + return new CcmBlockCipher(engine); + } + + protected virtual IAeadBlockCipher CreateGcmMode(IBlockCipher engine) + { + // TODO Consider allowing custom configuration of multiplier + return new GcmBlockCipher(engine); + } + + protected virtual IAeadBlockCipher CreateAeadBlockCipher_Aes_Ccm() + { + return CreateCcmMode(CreateAesEngine()); + } + + protected virtual IAeadBlockCipher CreateAeadBlockCipher_Aes_Gcm() + { + return CreateGcmMode(CreateAesEngine()); + } + + protected virtual IAeadBlockCipher CreateAeadBlockCipher_Aria_Gcm() + { + return CreateGcmMode(CreateAriaEngine()); + } + + protected virtual IAeadBlockCipher CreateAeadBlockCipher_Camellia_Gcm() + { + return CreateGcmMode(CreateCamelliaEngine()); + } + + protected virtual IAeadBlockCipher CreateAeadBlockCipher_SM4_Ccm() + { + return CreateCcmMode(CreateSM4Engine()); + } + + protected virtual IAeadBlockCipher CreateAeadBlockCipher_SM4_Gcm() + { + return CreateGcmMode(CreateSM4Engine()); + } + + public override TlsHmac CreateHmac(int macAlgorithm) + { + return CreateHmacForHash(TlsCryptoUtilities.GetHashForHmac(macAlgorithm)); + } + + public override TlsHmac CreateHmacForHash(int cryptoHashAlgorithm) + { + return new BcTlsHmac(new HMac(CreateDigest(cryptoHashAlgorithm))); + } + + protected virtual TlsHmac CreateHmac_Ssl(int macAlgorithm) + { + switch (macAlgorithm) + { + case MacAlgorithm.hmac_md5: + return new BcSsl3Hmac(CreateDigest(CryptoHashAlgorithm.md5)); + case MacAlgorithm.hmac_sha1: + return new BcSsl3Hmac(CreateDigest(CryptoHashAlgorithm.sha1)); + case MacAlgorithm.hmac_sha256: + return new BcSsl3Hmac(CreateDigest(CryptoHashAlgorithm.sha256)); + case MacAlgorithm.hmac_sha384: + return new BcSsl3Hmac(CreateDigest(CryptoHashAlgorithm.sha384)); + case MacAlgorithm.hmac_sha512: + return new BcSsl3Hmac(CreateDigest(CryptoHashAlgorithm.sha512)); + default: + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } + + protected virtual TlsHmac CreateMac(TlsCryptoParameters cryptoParams, int macAlgorithm) + { + if (TlsImplUtilities.IsSsl(cryptoParams)) + { + return CreateHmac_Ssl(macAlgorithm); + } + else + { + return CreateHmac(macAlgorithm); + } + } + + public override TlsSrp6Client CreateSrp6Client(TlsSrpConfig srpConfig) + { + BigInteger[] ng = srpConfig.GetExplicitNG(); + Srp6GroupParameters srpGroup = new Srp6GroupParameters(ng[0], ng[1]); + + Srp6Client srp6Client = new Srp6Client(); + srp6Client.Init(srpGroup, CreateDigest(CryptoHashAlgorithm.sha1), SecureRandom); + + return new BcTlsSrp6Client(srp6Client); + } + + public override TlsSrp6Server CreateSrp6Server(TlsSrpConfig srpConfig, BigInteger srpVerifier) + { + BigInteger[] ng = srpConfig.GetExplicitNG(); + Srp6GroupParameters srpGroup = new Srp6GroupParameters(ng[0], ng[1]); + + Srp6Server srp6Server = new Srp6Server(); + srp6Server.Init(srpGroup, srpVerifier, CreateDigest(CryptoHashAlgorithm.sha1), SecureRandom); + + return new BcTlsSrp6Server(srp6Server); + } + + public override TlsSrp6VerifierGenerator CreateSrp6VerifierGenerator(TlsSrpConfig srpConfig) + { + BigInteger[] ng = srpConfig.GetExplicitNG(); + + Srp6VerifierGenerator srp6VerifierGenerator = new Srp6VerifierGenerator(); + srp6VerifierGenerator.Init(ng[0], ng[1], CreateDigest(CryptoHashAlgorithm.sha1)); + + return new BcTlsSrp6VerifierGenerator(srp6VerifierGenerator); + } + + public override TlsSecret HkdfInit(int cryptoHashAlgorithm) + { + return AdoptLocalSecret(new byte[TlsCryptoUtilities.GetHashOutputSize(cryptoHashAlgorithm)]); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsCrypto.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsCrypto.cs.meta new file mode 100644 index 0000000..c174fd2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsCrypto.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: be8ba45baaf0c384da01e5cefd759eeb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsDH.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsDH.cs new file mode 100644 index 0000000..8af94f7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsDH.cs @@ -0,0 +1,43 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Tls.Crypto.Impl.BC +{ + /// Support class for ephemeral Diffie-Hellman using the BC light-weight library. + public class BcTlsDH + : TlsAgreement + { + protected readonly BcTlsDHDomain m_domain; + + protected AsymmetricCipherKeyPair m_localKeyPair; + protected DHPublicKeyParameters m_peerPublicKey; + + public BcTlsDH(BcTlsDHDomain domain) + { + this.m_domain = domain; + } + + /// + public virtual byte[] GenerateEphemeral() + { + this.m_localKeyPair = m_domain.GenerateKeyPair(); + + return m_domain.EncodePublicKey((DHPublicKeyParameters)m_localKeyPair.Public); + } + + /// + public virtual void ReceivePeerValue(byte[] peerValue) + { + this.m_peerPublicKey = m_domain.DecodePublicKey(peerValue); + } + + /// + public virtual TlsSecret CalculateSecret() + { + return m_domain.CalculateDHAgreement((DHPrivateKeyParameters)m_localKeyPair.Private, m_peerPublicKey); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsDH.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsDH.cs.meta new file mode 100644 index 0000000..ccc82c3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsDH.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fa4ca5bb5e4e2844ca55e8236c3d3773 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsDHDomain.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsDHDomain.cs new file mode 100644 index 0000000..90b8ce9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsDHDomain.cs @@ -0,0 +1,119 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Agreement; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls.Crypto.Impl.BC +{ + /// BC light-weight support class for Diffie-Hellman key pair generation and key agreement over a + /// specified Diffie-Hellman configuration. + public class BcTlsDHDomain + : TlsDHDomain + { + private static byte[] EncodeValue(DHParameters dh, bool padded, BigInteger x) + { + return padded + ? BigIntegers.AsUnsignedByteArray(GetValueLength(dh), x) + : BigIntegers.AsUnsignedByteArray(x); + } + + private static int GetValueLength(DHParameters dh) + { + return (dh.P.BitLength + 7) / 8; + } + + public static BcTlsSecret CalculateDHAgreement(BcTlsCrypto crypto, DHPrivateKeyParameters privateKey, + DHPublicKeyParameters publicKey, bool padded) + { + DHBasicAgreement basicAgreement = new DHBasicAgreement(); + basicAgreement.Init(privateKey); + BigInteger agreementValue = basicAgreement.CalculateAgreement(publicKey); + byte[] secret = EncodeValue(privateKey.Parameters, padded, agreementValue); + return crypto.AdoptLocalSecret(secret); + } + + public static DHParameters GetParameters(TlsDHConfig dhConfig) + { + DHGroup dhGroup = TlsDHUtilities.GetDHGroup(dhConfig); + if (dhGroup == null) + throw new ArgumentException("No DH configuration provided"); + + return new DHParameters(dhGroup.P, dhGroup.G, dhGroup.Q, dhGroup.L); + } + + protected readonly BcTlsCrypto crypto; + protected readonly TlsDHConfig dhConfig; + protected readonly DHParameters dhParameters; + + public BcTlsDHDomain(BcTlsCrypto crypto, TlsDHConfig dhConfig) + { + this.crypto = crypto; + this.dhConfig = dhConfig; + this.dhParameters = GetParameters(dhConfig); + } + + public virtual BcTlsSecret CalculateDHAgreement(DHPrivateKeyParameters privateKey, + DHPublicKeyParameters publicKey) + { + return CalculateDHAgreement(crypto, privateKey, publicKey, dhConfig.IsPadded); + } + + public virtual TlsAgreement CreateDH() + { + return new BcTlsDH(this); + } + + /// + public virtual BigInteger DecodeParameter(byte[] encoding) + { + if (dhConfig.IsPadded && GetValueLength(dhParameters) != encoding.Length) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + return new BigInteger(1, encoding); + } + + /// + public virtual DHPublicKeyParameters DecodePublicKey(byte[] encoding) + { + /* + * RFC 7919 3. [..] the client MUST verify that dh_Ys is in the range 1 < dh_Ys < dh_p - 1. + * If dh_Ys is not in this range, the client MUST terminate the connection with a fatal + * handshake_failure(40) alert. + */ + try + { + BigInteger y = DecodeParameter(encoding); + + return new DHPublicKeyParameters(y, dhParameters); + } + catch (Exception e) + { + throw new TlsFatalAlert(AlertDescription.handshake_failure, e); + } + } + + /// + public virtual byte[] EncodeParameter(BigInteger x) + { + return EncodeValue(dhParameters, dhConfig.IsPadded, x); + } + + /// + public virtual byte[] EncodePublicKey(DHPublicKeyParameters publicKey) + { + return EncodeValue(dhParameters, true, publicKey.Y); + } + + public virtual AsymmetricCipherKeyPair GenerateKeyPair() + { + DHBasicKeyPairGenerator keyPairGenerator = new DHBasicKeyPairGenerator(); + keyPairGenerator.Init(new DHKeyGenerationParameters(crypto.SecureRandom, dhParameters)); + return keyPairGenerator.GenerateKeyPair(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsDHDomain.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsDHDomain.cs.meta new file mode 100644 index 0000000..559b29f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsDHDomain.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 73086c9af3fafc34d9d1f3415f32dbcb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsDsaSigner.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsDsaSigner.cs new file mode 100644 index 0000000..a104028 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsDsaSigner.cs @@ -0,0 +1,29 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Signers; + +namespace Org.BouncyCastle.Tls.Crypto.Impl.BC +{ + /// Implementation class for generation of the raw DSA signature type using the BC light-weight API. + /// + public class BcTlsDsaSigner + : BcTlsDssSigner + { + public BcTlsDsaSigner(BcTlsCrypto crypto, DsaPrivateKeyParameters privateKey) + : base(crypto, privateKey) + { + } + + protected override IDsa CreateDsaImpl(int cryptoHashAlgorithm) + { + return new DsaSigner(new HMacDsaKCalculator(m_crypto.CreateDigest(cryptoHashAlgorithm))); + } + + protected override short SignatureAlgorithm + { + get { return Tls.SignatureAlgorithm.dsa; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsDsaSigner.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsDsaSigner.cs.meta new file mode 100644 index 0000000..b62087e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsDsaSigner.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f0b8ed52723aa664e9769238205d5f1e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsDsaVerifier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsDsaVerifier.cs new file mode 100644 index 0000000..bc8395a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsDsaVerifier.cs @@ -0,0 +1,29 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Signers; + +namespace Org.BouncyCastle.Tls.Crypto.Impl.BC +{ + /// Implementation class for the verification of the raw DSA signature type using the BC light-weight API. + /// + public class BcTlsDsaVerifier + : BcTlsDssVerifier + { + public BcTlsDsaVerifier(BcTlsCrypto crypto, DsaPublicKeyParameters publicKey) + : base(crypto, publicKey) + { + } + + protected override IDsa CreateDsaImpl(int cryptoHashAlgorithm) + { + return new DsaSigner(new HMacDsaKCalculator(m_crypto.CreateDigest(cryptoHashAlgorithm))); + } + + protected override short SignatureAlgorithm + { + get { return Tls.SignatureAlgorithm.dsa; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsDsaVerifier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsDsaVerifier.cs.meta new file mode 100644 index 0000000..57b2f80 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsDsaVerifier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 73e39486973b6b14da8b3215fcca4758 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsDssSigner.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsDssSigner.cs new file mode 100644 index 0000000..8a687d5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsDssSigner.cs @@ -0,0 +1,54 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Signers; + +namespace Org.BouncyCastle.Tls.Crypto.Impl.BC +{ + /// BC light-weight base class for the signers implementing the two DSA style algorithms from FIPS PUB + /// 186-4: DSA and ECDSA. + public abstract class BcTlsDssSigner + : BcTlsSigner + { + protected BcTlsDssSigner(BcTlsCrypto crypto, AsymmetricKeyParameter privateKey) + : base(crypto, privateKey) + { + } + + protected abstract IDsa CreateDsaImpl(int cryptoHashAlgorithm); + + protected abstract short SignatureAlgorithm { get; } + + public override byte[] GenerateRawSignature(SignatureAndHashAlgorithm algorithm, byte[] hash) + { + if (algorithm != null && algorithm.Signature != SignatureAlgorithm) + throw new InvalidOperationException("Invalid algorithm: " + algorithm); + + int cryptoHashAlgorithm = (null == algorithm) + ? CryptoHashAlgorithm.sha1 + : TlsCryptoUtilities.GetHash(algorithm.Hash); + + ISigner signer = new DsaDigestSigner(CreateDsaImpl(cryptoHashAlgorithm), new NullDigest()); + signer.Init(true, new ParametersWithRandom(m_privateKey, m_crypto.SecureRandom)); + if (algorithm == null) + { + // Note: Only use the SHA1 part of the (MD5/SHA1) hash + signer.BlockUpdate(hash, 16, 20); + } + else + { + signer.BlockUpdate(hash, 0, hash.Length); + } + try + { + return signer.GenerateSignature(); + } + catch (CryptoException e) + { + throw new TlsFatalAlert(AlertDescription.internal_error, e); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsDssSigner.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsDssSigner.cs.meta new file mode 100644 index 0000000..107da1b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsDssSigner.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d6b5212554aa5954b9f08c9c207ff137 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsDssVerifier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsDssVerifier.cs new file mode 100644 index 0000000..f2e3710 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsDssVerifier.cs @@ -0,0 +1,47 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Signers; + +namespace Org.BouncyCastle.Tls.Crypto.Impl.BC +{ + /// BC light-weight base class for the verifiers supporting the two DSA style algorithms from FIPS PUB + /// 186-4: DSA and ECDSA. + public abstract class BcTlsDssVerifier + : BcTlsVerifier + { + protected BcTlsDssVerifier(BcTlsCrypto crypto, AsymmetricKeyParameter publicKey) + : base(crypto, publicKey) + { + } + + protected abstract IDsa CreateDsaImpl(int cryptoHashAlgorithm); + + protected abstract short SignatureAlgorithm { get; } + + public override bool VerifyRawSignature(DigitallySigned signedParams, byte[] hash) + { + SignatureAndHashAlgorithm algorithm = signedParams.Algorithm; + if (algorithm != null && algorithm.Signature != SignatureAlgorithm) + throw new InvalidOperationException("Invalid algorithm: " + algorithm); + + int cryptoHashAlgorithm = (null == algorithm) + ? CryptoHashAlgorithm.sha1 + : TlsCryptoUtilities.GetHash(algorithm.Hash); + + ISigner signer = new DsaDigestSigner(CreateDsaImpl(cryptoHashAlgorithm), new NullDigest()); + signer.Init(false, m_publicKey); + if (algorithm == null) + { + // Note: Only use the SHA1 part of the (MD5/SHA1) hash + signer.BlockUpdate(hash, 16, 20); + } + else + { + signer.BlockUpdate(hash, 0, hash.Length); + } + return signer.VerifySignature(signedParams.Signature); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsDssVerifier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsDssVerifier.cs.meta new file mode 100644 index 0000000..a31ff74 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsDssVerifier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6a7f3dd5eb1d4664c9ae2d667bddc7b8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsECDH.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsECDH.cs new file mode 100644 index 0000000..55b8ed6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsECDH.cs @@ -0,0 +1,39 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Tls.Crypto.Impl.BC +{ + /// Support class for ephemeral Elliptic Curve Diffie-Hellman using the BC light-weight library. + public class BcTlsECDH + : TlsAgreement + { + protected readonly BcTlsECDomain m_domain; + + protected AsymmetricCipherKeyPair m_localKeyPair; + protected ECPublicKeyParameters m_peerPublicKey; + + public BcTlsECDH(BcTlsECDomain domain) + { + this.m_domain = domain; + } + + public virtual byte[] GenerateEphemeral() + { + this.m_localKeyPair = m_domain.GenerateKeyPair(); + + return m_domain.EncodePublicKey((ECPublicKeyParameters)m_localKeyPair.Public); + } + + public virtual void ReceivePeerValue(byte[] peerValue) + { + this.m_peerPublicKey = m_domain.DecodePublicKey(peerValue); + } + + public virtual TlsSecret CalculateSecret() + { + return m_domain.CalculateECDHAgreement((ECPrivateKeyParameters)m_localKeyPair.Private, m_peerPublicKey); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsECDH.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsECDH.cs.meta new file mode 100644 index 0000000..c68d729 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsECDH.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 70141202e693c904abfb4529310adcbe +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsECDomain.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsECDomain.cs new file mode 100644 index 0000000..f4c5cfc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsECDomain.cs @@ -0,0 +1,125 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Agreement; +using Org.BouncyCastle.Crypto.EC; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls.Crypto.Impl.BC +{ + /** + * EC domain class for generating key pairs and performing key agreement. + */ + public class BcTlsECDomain + : TlsECDomain + { + public static BcTlsSecret CalculateBasicAgreement(BcTlsCrypto crypto, ECPrivateKeyParameters privateKey, + ECPublicKeyParameters publicKey) + { + ECDHBasicAgreement basicAgreement = new ECDHBasicAgreement(); + basicAgreement.Init(privateKey); + BigInteger agreementValue = basicAgreement.CalculateAgreement(publicKey); + + /* + * RFC 4492 5.10. Note that this octet string (Z in IEEE 1363 terminology) as output by + * FE2OSP, the Field Element to Octet String Conversion Primitive, has constant length for + * any given field; leading zeros found in this octet string MUST NOT be truncated. + */ + byte[] secret = BigIntegers.AsUnsignedByteArray(basicAgreement.GetFieldSize(), agreementValue); + return crypto.AdoptLocalSecret(secret); + } + + public static ECDomainParameters GetDomainParameters(TlsECConfig ecConfig) + { + return GetDomainParameters(ecConfig.NamedGroup); + } + + public static ECDomainParameters GetDomainParameters(int namedGroup) + { + if (!NamedGroup.RefersToASpecificCurve(namedGroup)) + return null; + + // Parameters are lazily created the first time a particular curve is accessed + + string curveName = NamedGroup.GetCurveName(namedGroup); + X9ECParameters ecP = CustomNamedCurves.GetByName(curveName); + if (ecP == null) + { + ecP = ECNamedCurveTable.GetByName(curveName); + if (ecP == null) + return null; + } + + // It's a bit inefficient to do this conversion every time + return new ECDomainParameters(ecP.Curve, ecP.G, ecP.N, ecP.H, ecP.GetSeed()); + } + + protected readonly BcTlsCrypto m_crypto; + protected readonly TlsECConfig m_ecConfig; + protected readonly ECDomainParameters m_ecDomainParameters; + + public BcTlsECDomain(BcTlsCrypto crypto, TlsECConfig ecConfig) + { + this.m_crypto = crypto; + this.m_ecConfig = ecConfig; + this.m_ecDomainParameters = GetDomainParameters(ecConfig); + } + + public virtual BcTlsSecret CalculateECDHAgreement(ECPrivateKeyParameters privateKey, + ECPublicKeyParameters publicKey) + { + return CalculateBasicAgreement(m_crypto, privateKey, publicKey); + } + + public virtual TlsAgreement CreateECDH() + { + return new BcTlsECDH(this); + } + + public virtual ECPoint DecodePoint(byte[] encoding) + { + return m_ecDomainParameters.Curve.DecodePoint(encoding); + } + + public virtual ECPublicKeyParameters DecodePublicKey(byte[] encoding) + { + try + { + ECPoint point = DecodePoint(encoding); + + return new ECPublicKeyParameters(point, m_ecDomainParameters); + } + catch (IOException e) + { + throw e; + } + catch (Exception e) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter, e); + } + } + + public virtual byte[] EncodePoint(ECPoint point) + { + return point.GetEncoded(false); + } + + public virtual byte[] EncodePublicKey(ECPublicKeyParameters publicKey) + { + return EncodePoint(publicKey.Q); + } + + public virtual AsymmetricCipherKeyPair GenerateKeyPair() + { + ECKeyPairGenerator keyPairGenerator = new ECKeyPairGenerator(); + keyPairGenerator.Init(new ECKeyGenerationParameters(m_ecDomainParameters, m_crypto.SecureRandom)); + return keyPairGenerator.GenerateKeyPair(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsECDomain.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsECDomain.cs.meta new file mode 100644 index 0000000..86035ad --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsECDomain.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 91092c55861144b47a5449a6a3590a67 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsECDsa13Signer.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsECDsa13Signer.cs new file mode 100644 index 0000000..5901767 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsECDsa13Signer.cs @@ -0,0 +1,47 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Signers; + +namespace Org.BouncyCastle.Tls.Crypto.Impl.BC +{ + /// Implementation class for generation of ECDSA signatures in TLS 1.3+ using the BC light-weight API. + /// + public class BcTlsECDsa13Signer + : BcTlsSigner + { + private readonly int m_signatureScheme; + + public BcTlsECDsa13Signer(BcTlsCrypto crypto, ECPrivateKeyParameters privateKey, int signatureScheme) + : base(crypto, privateKey) + { + if (!SignatureScheme.IsECDsa(signatureScheme)) + throw new ArgumentException("signatureScheme"); + + this.m_signatureScheme = signatureScheme; + } + + public override byte[] GenerateRawSignature(SignatureAndHashAlgorithm algorithm, byte[] hash) + { + if (algorithm == null || SignatureScheme.From(algorithm) != m_signatureScheme) + throw new InvalidOperationException("Invalid algorithm: " + algorithm); + + int cryptoHashAlgorithm = SignatureScheme.GetCryptoHashAlgorithm(m_signatureScheme); + IDsa dsa = new ECDsaSigner(new HMacDsaKCalculator(m_crypto.CreateDigest(cryptoHashAlgorithm))); + + ISigner signer = new DsaDigestSigner(dsa, new NullDigest()); + signer.Init(true, new ParametersWithRandom(m_privateKey, m_crypto.SecureRandom)); + signer.BlockUpdate(hash, 0, hash.Length); + try + { + return signer.GenerateSignature(); + } + catch (CryptoException e) + { + throw new TlsFatalAlert(AlertDescription.internal_error, e); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsECDsa13Signer.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsECDsa13Signer.cs.meta new file mode 100644 index 0000000..4513bc3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsECDsa13Signer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1ca2d5913736e064aa10511071261581 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsECDsa13Verifier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsECDsa13Verifier.cs new file mode 100644 index 0000000..8488dc8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsECDsa13Verifier.cs @@ -0,0 +1,41 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Signers; + +namespace Org.BouncyCastle.Tls.Crypto.Impl.BC +{ + /// Implementation class for verification of ECDSA signatures in TLS 1.3+ using the BC light-weight API. + /// + public class BcTlsECDsa13Verifier + : BcTlsVerifier + { + private readonly int m_signatureScheme; + + public BcTlsECDsa13Verifier(BcTlsCrypto crypto, ECPublicKeyParameters publicKey, int signatureScheme) + : base(crypto, publicKey) + { + if (!SignatureScheme.IsECDsa(signatureScheme)) + throw new ArgumentException("signatureScheme"); + + this.m_signatureScheme = signatureScheme; + } + + public override bool VerifyRawSignature(DigitallySigned signature, byte[] hash) + { + SignatureAndHashAlgorithm algorithm = signature.Algorithm; + if (algorithm == null || SignatureScheme.From(algorithm) != m_signatureScheme) + throw new InvalidOperationException("Invalid algorithm: " + algorithm); + + int cryptoHashAlgorithm = SignatureScheme.GetCryptoHashAlgorithm(m_signatureScheme); + IDsa dsa = new ECDsaSigner(new HMacDsaKCalculator(m_crypto.CreateDigest(cryptoHashAlgorithm))); + + ISigner signer = new DsaDigestSigner(dsa, new NullDigest()); + signer.Init(false, m_publicKey); + signer.BlockUpdate(hash, 0, hash.Length); + return signer.VerifySignature(signature.Signature); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsECDsa13Verifier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsECDsa13Verifier.cs.meta new file mode 100644 index 0000000..7009be2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsECDsa13Verifier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5cb1522dcd491dc4984e949c7bc340a9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsECDsaSigner.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsECDsaSigner.cs new file mode 100644 index 0000000..8b29912 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsECDsaSigner.cs @@ -0,0 +1,29 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Signers; + +namespace Org.BouncyCastle.Tls.Crypto.Impl.BC +{ + /// Implementation class for generation of the raw ECDSA signature type using the BC light-weight API. + /// + public class BcTlsECDsaSigner + : BcTlsDssSigner + { + public BcTlsECDsaSigner(BcTlsCrypto crypto, ECPrivateKeyParameters privateKey) + : base(crypto, privateKey) + { + } + + protected override IDsa CreateDsaImpl(int cryptoHashAlgorithm) + { + return new ECDsaSigner(new HMacDsaKCalculator(m_crypto.CreateDigest(cryptoHashAlgorithm))); + } + + protected override short SignatureAlgorithm + { + get { return Tls.SignatureAlgorithm.ecdsa; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsECDsaSigner.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsECDsaSigner.cs.meta new file mode 100644 index 0000000..5245def --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsECDsaSigner.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 676069b3322729d4ba55cc366f5bcaa1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsECDsaVerifier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsECDsaVerifier.cs new file mode 100644 index 0000000..1cd6ff1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsECDsaVerifier.cs @@ -0,0 +1,29 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Signers; + +namespace Org.BouncyCastle.Tls.Crypto.Impl.BC +{ + /// Implementation class for the verification of the raw ECDSA signature type using the BC light-weight + /// API. + public class BcTlsECDsaVerifier + : BcTlsDssVerifier + { + public BcTlsECDsaVerifier(BcTlsCrypto crypto, ECPublicKeyParameters publicKey) + : base(crypto, publicKey) + { + } + + protected override IDsa CreateDsaImpl(int cryptoHashAlgorithm) + { + return new ECDsaSigner(new HMacDsaKCalculator(m_crypto.CreateDigest(cryptoHashAlgorithm))); + } + + protected override short SignatureAlgorithm + { + get { return Tls.SignatureAlgorithm.ecdsa; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsECDsaVerifier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsECDsaVerifier.cs.meta new file mode 100644 index 0000000..129d66a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsECDsaVerifier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 40561d58c1341264dbbd5c1d03278407 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsEd25519Signer.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsEd25519Signer.cs new file mode 100644 index 0000000..c8fc99e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsEd25519Signer.cs @@ -0,0 +1,32 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Signers; + +namespace Org.BouncyCastle.Tls.Crypto.Impl.BC +{ + public class BcTlsEd25519Signer + : BcTlsSigner + { + public BcTlsEd25519Signer(BcTlsCrypto crypto, Ed25519PrivateKeyParameters privateKey) + : base(crypto, privateKey) + { + } + + public override byte[] GenerateRawSignature(SignatureAndHashAlgorithm algorithm, byte[] hash) + { + throw new NotSupportedException(); + } + + public override TlsStreamSigner GetStreamSigner(SignatureAndHashAlgorithm algorithm) + { + if (algorithm == null || SignatureScheme.From(algorithm) != SignatureScheme.ed25519) + throw new InvalidOperationException("Invalid algorithm: " + algorithm); + + Ed25519Signer signer = new Ed25519Signer(); + signer.Init(true, m_privateKey); + + return new BcTlsStreamSigner(signer); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsEd25519Signer.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsEd25519Signer.cs.meta new file mode 100644 index 0000000..15973e7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsEd25519Signer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b682bc44d22653d40897a2a11f7a0913 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsEd25519Verifier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsEd25519Verifier.cs new file mode 100644 index 0000000..fb91442 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsEd25519Verifier.cs @@ -0,0 +1,33 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Signers; + +namespace Org.BouncyCastle.Tls.Crypto.Impl.BC +{ + public class BcTlsEd25519Verifier + : BcTlsVerifier + { + public BcTlsEd25519Verifier(BcTlsCrypto crypto, Ed25519PublicKeyParameters publicKey) + : base(crypto, publicKey) + { + } + + public override bool VerifyRawSignature(DigitallySigned signature, byte[] hash) + { + throw new NotSupportedException(); + } + + public override TlsStreamVerifier GetStreamVerifier(DigitallySigned signature) + { + SignatureAndHashAlgorithm algorithm = signature.Algorithm; + if (algorithm == null || SignatureScheme.From(algorithm) != SignatureScheme.ed25519) + throw new InvalidOperationException("Invalid algorithm: " + algorithm); + + Ed25519Signer verifier = new Ed25519Signer(); + verifier.Init(false, m_publicKey); + + return new BcTlsStreamVerifier(verifier, signature.Signature); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsEd25519Verifier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsEd25519Verifier.cs.meta new file mode 100644 index 0000000..da20572 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsEd25519Verifier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bbbbddbfbd970b44792877c6d2e90770 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsEd448Signer.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsEd448Signer.cs new file mode 100644 index 0000000..06d4d7a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsEd448Signer.cs @@ -0,0 +1,32 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Signers; + +namespace Org.BouncyCastle.Tls.Crypto.Impl.BC +{ + public class BcTlsEd448Signer + : BcTlsSigner + { + public BcTlsEd448Signer(BcTlsCrypto crypto, Ed448PrivateKeyParameters privateKey) + : base(crypto, privateKey) + { + } + + public override byte[] GenerateRawSignature(SignatureAndHashAlgorithm algorithm, byte[] hash) + { + throw new NotSupportedException(); + } + + public override TlsStreamSigner GetStreamSigner(SignatureAndHashAlgorithm algorithm) + { + if (algorithm == null || SignatureScheme.From(algorithm) != SignatureScheme.ed448) + throw new InvalidOperationException("Invalid algorithm: " + algorithm); + + Ed448Signer signer = new Ed448Signer(TlsUtilities.EmptyBytes); + signer.Init(true, m_privateKey); + + return new BcTlsStreamSigner(signer); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsEd448Signer.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsEd448Signer.cs.meta new file mode 100644 index 0000000..207d711 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsEd448Signer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 54cca99351b214c40b683f9693ca5ca3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsEd448Verifier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsEd448Verifier.cs new file mode 100644 index 0000000..4492fdd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsEd448Verifier.cs @@ -0,0 +1,33 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Signers; + +namespace Org.BouncyCastle.Tls.Crypto.Impl.BC +{ + public class BcTlsEd448Verifier + : BcTlsVerifier + { + public BcTlsEd448Verifier(BcTlsCrypto crypto, Ed448PublicKeyParameters publicKey) + : base(crypto, publicKey) + { + } + + public override bool VerifyRawSignature(DigitallySigned signature, byte[] hash) + { + throw new NotSupportedException(); + } + + public override TlsStreamVerifier GetStreamVerifier(DigitallySigned signature) + { + SignatureAndHashAlgorithm algorithm = signature.Algorithm; + if (algorithm == null || SignatureScheme.From(algorithm) != SignatureScheme.ed448) + throw new InvalidOperationException("Invalid algorithm: " + algorithm); + + Ed448Signer verifier = new Ed448Signer(TlsUtilities.EmptyBytes); + verifier.Init(false, m_publicKey); + + return new BcTlsStreamVerifier(verifier, signature.Signature); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsEd448Verifier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsEd448Verifier.cs.meta new file mode 100644 index 0000000..81fdfa5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsEd448Verifier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 98879bd4a34395f40b6d71b1d1ddb741 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsHash.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsHash.cs new file mode 100644 index 0000000..0b35831 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsHash.cs @@ -0,0 +1,49 @@ +using System; + +using Org.BouncyCastle.Crypto; + +namespace Org.BouncyCastle.Tls.Crypto.Impl.BC +{ + internal sealed class BcTlsHash + : TlsHash + { + private readonly BcTlsCrypto m_crypto; + private readonly int m_cryptoHashAlgorithm; + private readonly IDigest m_digest; + + internal BcTlsHash(BcTlsCrypto crypto, int cryptoHashAlgorithm) + : this(crypto, cryptoHashAlgorithm, crypto.CreateDigest(cryptoHashAlgorithm)) + { + } + + private BcTlsHash(BcTlsCrypto crypto, int cryptoHashAlgorithm, IDigest digest) + { + this.m_crypto = crypto; + this.m_cryptoHashAlgorithm = cryptoHashAlgorithm; + this.m_digest = digest; + } + + public void Update(byte[] data, int offSet, int length) + { + m_digest.BlockUpdate(data, offSet, length); + } + + public byte[] CalculateHash() + { + byte[] rv = new byte[m_digest.GetDigestSize()]; + m_digest.DoFinal(rv, 0); + return rv; + } + + public TlsHash CloneHash() + { + IDigest clone = m_crypto.CloneDigest(m_cryptoHashAlgorithm, m_digest); + return new BcTlsHash(m_crypto, m_cryptoHashAlgorithm, clone); + } + + public void Reset() + { + m_digest.Reset(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsHash.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsHash.cs.meta new file mode 100644 index 0000000..558939b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsHash.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0656b510f30e7fd4e83d4e740a03dcf4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsHmac.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsHmac.cs new file mode 100644 index 0000000..485a3f7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsHmac.cs @@ -0,0 +1,55 @@ +using System; + +using Org.BouncyCastle.Crypto.Macs; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Tls.Crypto.Impl.BC +{ + internal sealed class BcTlsHmac + : TlsHmac + { + private readonly HMac m_hmac; + + internal BcTlsHmac(HMac hmac) + { + this.m_hmac = hmac; + } + + public void SetKey(byte[] key, int keyOff, int keyLen) + { + m_hmac.Init(new KeyParameter(key, keyOff, keyLen)); + } + + public void Update(byte[] input, int inOff, int length) + { + m_hmac.BlockUpdate(input, inOff, length); + } + + public byte[] CalculateMac() + { + byte[] rv = new byte[m_hmac.GetMacSize()]; + m_hmac.DoFinal(rv, 0); + return rv; + } + + public void CalculateMac(byte[] output, int outOff) + { + m_hmac.DoFinal(output, outOff); + } + + public int InternalBlockSize + { + get { return m_hmac.GetUnderlyingDigest().GetByteLength(); } + } + + public int MacLength + { + get { return m_hmac.GetMacSize(); } + } + + public void Reset() + { + m_hmac.Reset(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsHmac.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsHmac.cs.meta new file mode 100644 index 0000000..2e9f8c3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsHmac.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3b5cc3e842023f044acf72f58fdb6556 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsNonceGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsNonceGenerator.cs new file mode 100644 index 0000000..d33c622 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsNonceGenerator.cs @@ -0,0 +1,24 @@ +using System; + +using Org.BouncyCastle.Crypto.Prng; + +namespace Org.BouncyCastle.Tls.Crypto.Impl.BC +{ + internal sealed class BcTlsNonceGenerator + : TlsNonceGenerator + { + private readonly IRandomGenerator m_randomGenerator; + + internal BcTlsNonceGenerator(IRandomGenerator randomGenerator) + { + this.m_randomGenerator = randomGenerator; + } + + public byte[] GenerateNonce(int size) + { + byte[] nonce = new byte[size]; + m_randomGenerator.NextBytes(nonce); + return nonce; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsNonceGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsNonceGenerator.cs.meta new file mode 100644 index 0000000..95ed668 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsNonceGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8b321241593bdbb45bb771133bd70119 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsRsaEncryptor.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsRsaEncryptor.cs new file mode 100644 index 0000000..1582ff6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsRsaEncryptor.cs @@ -0,0 +1,47 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Encodings; +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Tls.Crypto.Impl.BC +{ + internal sealed class BcTlsRsaEncryptor + : TlsEncryptor + { + private static RsaKeyParameters CheckPublicKey(RsaKeyParameters pubKeyRsa) + { + if (null == pubKeyRsa || pubKeyRsa.IsPrivate) + throw new ArgumentException("No public RSA key provided", "pubKeyRsa"); + + return pubKeyRsa; + } + + private readonly BcTlsCrypto m_crypto; + private readonly RsaKeyParameters m_pubKeyRsa; + + internal BcTlsRsaEncryptor(BcTlsCrypto crypto, RsaKeyParameters pubKeyRsa) + { + this.m_crypto = crypto; + this.m_pubKeyRsa = CheckPublicKey(pubKeyRsa); + } + + public byte[] Encrypt(byte[] input, int inOff, int length) + { + try + { + Pkcs1Encoding encoding = new Pkcs1Encoding(new RsaBlindedEngine()); + encoding.Init(true, new ParametersWithRandom(m_pubKeyRsa, m_crypto.SecureRandom)); + return encoding.ProcessBlock(input, inOff, length); + } + catch (InvalidCipherTextException e) + { + /* + * This should never happen, only during decryption. + */ + throw new TlsFatalAlert(AlertDescription.internal_error, e); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsRsaEncryptor.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsRsaEncryptor.cs.meta new file mode 100644 index 0000000..61f9cd3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsRsaEncryptor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a7fc91561e53b2d47bbac34a2aefa9ca +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsRsaPssSigner.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsRsaPssSigner.cs new file mode 100644 index 0000000..2c1b411 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsRsaPssSigner.cs @@ -0,0 +1,44 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Signers; + +namespace Org.BouncyCastle.Tls.Crypto.Impl.BC +{ + /// Operator supporting the generation of RSASSA-PSS signatures using the BC light-weight API. + public class BcTlsRsaPssSigner + : BcTlsSigner + { + private readonly int m_signatureScheme; + + public BcTlsRsaPssSigner(BcTlsCrypto crypto, RsaKeyParameters privateKey, int signatureScheme) + : base(crypto, privateKey) + { + if (!SignatureScheme.IsRsaPss(signatureScheme)) + throw new ArgumentException("signatureScheme"); + + this.m_signatureScheme = signatureScheme; + } + + public override byte[] GenerateRawSignature(SignatureAndHashAlgorithm algorithm, byte[] hash) + { + throw new NotSupportedException(); + } + + public override TlsStreamSigner GetStreamSigner(SignatureAndHashAlgorithm algorithm) + { + if (algorithm == null || SignatureScheme.From(algorithm) != m_signatureScheme) + throw new InvalidOperationException("Invalid algorithm: " + algorithm); + + int cryptoHashAlgorithm = SignatureScheme.GetCryptoHashAlgorithm(m_signatureScheme); + IDigest digest = m_crypto.CreateDigest(cryptoHashAlgorithm); + + PssSigner signer = new PssSigner(new RsaBlindedEngine(), digest, digest.GetDigestSize()); + signer.Init(true, new ParametersWithRandom(m_privateKey, m_crypto.SecureRandom)); + + return new BcTlsStreamSigner(signer); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsRsaPssSigner.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsRsaPssSigner.cs.meta new file mode 100644 index 0000000..5b6d59a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsRsaPssSigner.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: aead30e057f4dd64f802693ae44abd53 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsRsaPssVerifier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsRsaPssVerifier.cs new file mode 100644 index 0000000..1b14d1a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsRsaPssVerifier.cs @@ -0,0 +1,45 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Signers; + +namespace Org.BouncyCastle.Tls.Crypto.Impl.BC +{ + /// Operator supporting the verification of RSASSA-PSS signatures using the BC light-weight API. + public class BcTlsRsaPssVerifier + : BcTlsVerifier + { + private readonly int m_signatureScheme; + + public BcTlsRsaPssVerifier(BcTlsCrypto crypto, RsaKeyParameters publicKey, int signatureScheme) + : base(crypto, publicKey) + { + if (!SignatureScheme.IsRsaPss(signatureScheme)) + throw new ArgumentException("signatureScheme"); + + this.m_signatureScheme = signatureScheme; + } + + public override bool VerifyRawSignature(DigitallySigned signature, byte[] hash) + { + throw new NotSupportedException(); + } + + public override TlsStreamVerifier GetStreamVerifier(DigitallySigned signature) + { + SignatureAndHashAlgorithm algorithm = signature.Algorithm; + if (algorithm == null || SignatureScheme.From(algorithm) != m_signatureScheme) + throw new InvalidOperationException("Invalid algorithm: " + algorithm); + + int cryptoHashAlgorithm = SignatureScheme.GetCryptoHashAlgorithm(m_signatureScheme); + IDigest digest = m_crypto.CreateDigest(cryptoHashAlgorithm); + + PssSigner verifier = new PssSigner(new RsaEngine(), digest, digest.GetDigestSize()); + verifier.Init(false, m_publicKey); + + return new BcTlsStreamVerifier(verifier, signature.Signature); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsRsaPssVerifier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsRsaPssVerifier.cs.meta new file mode 100644 index 0000000..2e3efb2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsRsaPssVerifier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 283fbe0717ffdc34fa2422e3136aebc9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsRsaSigner.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsRsaSigner.cs new file mode 100644 index 0000000..0e741a5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsRsaSigner.cs @@ -0,0 +1,71 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Encodings; +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Signers; + +namespace Org.BouncyCastle.Tls.Crypto.Impl.BC +{ + /// Operator supporting the generation of RSASSA-PKCS1-v1_5 signatures using the BC light-weight API. + /// + public class BcTlsRsaSigner + : BcTlsSigner + { + private readonly RsaKeyParameters m_publicKey; + + public BcTlsRsaSigner(BcTlsCrypto crypto, RsaKeyParameters privateKey, RsaKeyParameters publicKey) + : base(crypto, privateKey) + { + this.m_publicKey = publicKey; + } + + public override byte[] GenerateRawSignature(SignatureAndHashAlgorithm algorithm, byte[] hash) + { + IDigest nullDigest = new NullDigest(); + + ISigner signer; + if (algorithm != null) + { + if (algorithm.Signature != SignatureAlgorithm.rsa) + throw new InvalidOperationException("Invalid algorithm: " + algorithm); + + /* + * RFC 5246 4.7. In RSA signing, the opaque vector contains the signature generated + * using the RSASSA-PKCS1-v1_5 signature scheme defined in [PKCS1]. + */ + signer = new RsaDigestSigner(nullDigest, TlsUtilities.GetOidForHashAlgorithm(algorithm.Hash)); + } + else + { + /* + * RFC 5246 4.7. Note that earlier versions of TLS used a different RSA signature scheme + * that did not include a DigestInfo encoding. + */ + signer = new GenericSigner(new Pkcs1Encoding(new RsaBlindedEngine()), nullDigest); + } + signer.Init(true, new ParametersWithRandom(m_privateKey, m_crypto.SecureRandom)); + signer.BlockUpdate(hash, 0, hash.Length); + try + { + byte[] signature = signer.GenerateSignature(); + + signer.Init(false, m_publicKey); + signer.BlockUpdate(hash, 0, hash.Length); + + if (signer.VerifySignature(signature)) + { + return signature; + } + } + catch (CryptoException e) + { + throw new TlsFatalAlert(AlertDescription.internal_error, e); + } + + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsRsaSigner.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsRsaSigner.cs.meta new file mode 100644 index 0000000..e956247 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsRsaSigner.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 791653778fae9fc4794ecaa673b81d6e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsRsaVerifier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsRsaVerifier.cs new file mode 100644 index 0000000..41f1bb1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsRsaVerifier.cs @@ -0,0 +1,52 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Encodings; +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Signers; + +namespace Org.BouncyCastle.Tls.Crypto.Impl.BC +{ + /// Operator supporting the verification of RSASSA-PKCS1-v1_5 signatures using the BC light-weight API. + /// + public class BcTlsRsaVerifier + : BcTlsVerifier + { + public BcTlsRsaVerifier(BcTlsCrypto crypto, RsaKeyParameters publicKey) + : base(crypto, publicKey) + { + } + + public override bool VerifyRawSignature(DigitallySigned signedParams, byte[] hash) + { + IDigest nullDigest = new NullDigest(); + + SignatureAndHashAlgorithm algorithm = signedParams.Algorithm; + ISigner signer; + if (algorithm != null) + { + if (algorithm.Signature != SignatureAlgorithm.rsa) + throw new InvalidOperationException("Invalid algorithm: " + algorithm); + + /* + * RFC 5246 4.7. In RSA signing, the opaque vector contains the signature generated + * using the RSASSA-PKCS1-v1_5 signature scheme defined in [PKCS1]. + */ + signer = new RsaDigestSigner(nullDigest, TlsUtilities.GetOidForHashAlgorithm(algorithm.Hash)); + } + else + { + /* + * RFC 5246 4.7. Note that earlier versions of TLS used a different RSA signature scheme + * that did not include a DigestInfo encoding. + */ + signer = new GenericSigner(new Pkcs1Encoding(new RsaBlindedEngine()), nullDigest); + } + signer.Init(false, m_publicKey); + signer.BlockUpdate(hash, 0, hash.Length); + return signer.VerifySignature(signedParams.Signature); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsRsaVerifier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsRsaVerifier.cs.meta new file mode 100644 index 0000000..528e379 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsRsaVerifier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b2c5e769a78c3124ba22fe63e5f3a970 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsSecret.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsSecret.cs new file mode 100644 index 0000000..47a3d12 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsSecret.cs @@ -0,0 +1,267 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Macs; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tls.Crypto.Impl.BC +{ + /// BC light-weight support class for handling TLS secrets and deriving key material and other secrets + /// from them. + public class BcTlsSecret + : AbstractTlsSecret + { + public static BcTlsSecret Convert(BcTlsCrypto crypto, TlsSecret secret) + { + if (secret is BcTlsSecret) + return (BcTlsSecret)secret; + + if (secret is AbstractTlsSecret) + { + AbstractTlsSecret abstractTlsSecret = (AbstractTlsSecret)secret; + + return crypto.AdoptLocalSecret(CopyData(abstractTlsSecret)); + } + + throw new ArgumentException("unrecognized TlsSecret - cannot copy data: " + Platform.GetTypeName(secret)); + } + + // SSL3 magic mix constants ("A", "BB", "CCC", ...) + private static readonly byte[] Ssl3Const = GenerateSsl3Constants(); + + private static byte[] GenerateSsl3Constants() + { + int n = 15; + byte[] result = new byte[n * (n + 1) / 2]; + int pos = 0; + for (int i = 0; i < n; ++i) + { + byte b = (byte)('A' + i); + for (int j = 0; j <= i; ++j) + { + result[pos++] = b; + } + } + return result; + } + + protected readonly BcTlsCrypto m_crypto; + + public BcTlsSecret(BcTlsCrypto crypto, byte[] data) + : base(data) + { + this.m_crypto = crypto; + } + + public override TlsSecret DeriveUsingPrf(int prfAlgorithm, string label, byte[] seed, int length) + { + lock (this) + { + CheckAlive(); + + switch (prfAlgorithm) + { + case PrfAlgorithm.tls13_hkdf_sha256: + return TlsCryptoUtilities.HkdfExpandLabel(this, CryptoHashAlgorithm.sha256, label, seed, length); + case PrfAlgorithm.tls13_hkdf_sha384: + return TlsCryptoUtilities.HkdfExpandLabel(this, CryptoHashAlgorithm.sha384, label, seed, length); + case PrfAlgorithm.tls13_hkdf_sm3: + return TlsCryptoUtilities.HkdfExpandLabel(this, CryptoHashAlgorithm.sm3, label, seed, length); + default: + return m_crypto.AdoptLocalSecret(Prf(prfAlgorithm, label, seed, length)); + } + } + } + + public override TlsSecret HkdfExpand(int cryptoHashAlgorithm, byte[] info, int length) + { + lock (this) + { + if (length < 1) + return m_crypto.AdoptLocalSecret(TlsUtilities.EmptyBytes); + + int hashLen = TlsCryptoUtilities.GetHashOutputSize(cryptoHashAlgorithm); + if (length > (255 * hashLen)) + throw new ArgumentException("must be <= 255 * (output size of 'hashAlgorithm')", "length"); + + CheckAlive(); + + byte[] prk = m_data; + + HMac hmac = new HMac(m_crypto.CreateDigest(cryptoHashAlgorithm)); + hmac.Init(new KeyParameter(prk)); + + byte[] okm = new byte[length]; + + byte[] t = new byte[hashLen]; + byte counter = 0x00; + + int pos = 0; + for (; ; ) + { + hmac.BlockUpdate(info, 0, info.Length); + hmac.Update((byte)++counter); + hmac.DoFinal(t, 0); + + int remaining = length - pos; + if (remaining <= hashLen) + { + Array.Copy(t, 0, okm, pos, remaining); + break; + } + + Array.Copy(t, 0, okm, pos, hashLen); + pos += hashLen; + hmac.BlockUpdate(t, 0, t.Length); + } + + return m_crypto.AdoptLocalSecret(okm); + } + } + + public override TlsSecret HkdfExtract(int cryptoHashAlgorithm, TlsSecret ikm) + { + lock (this) + { + CheckAlive(); + + byte[] salt = m_data; + this.m_data = null; + + HMac hmac = new HMac(m_crypto.CreateDigest(cryptoHashAlgorithm)); + hmac.Init(new KeyParameter(salt)); + + Convert(m_crypto, ikm).UpdateMac(hmac); + + byte[] prk = new byte[hmac.GetMacSize()]; + hmac.DoFinal(prk, 0); + + return m_crypto.AdoptLocalSecret(prk); + } + } + + protected override AbstractTlsCrypto Crypto + { + get { return m_crypto; } + } + + protected virtual void HmacHash(IDigest digest, byte[] secret, int secretOff, int secretLen, byte[] seed, + byte[] output) + { + HMac mac = new HMac(digest); + mac.Init(new KeyParameter(secret, secretOff, secretLen)); + + byte[] a = seed; + + int macSize = mac.GetMacSize(); + + byte[] b1 = new byte[macSize]; + byte[] b2 = new byte[macSize]; + + int pos = 0; + while (pos < output.Length) + { + mac.BlockUpdate(a, 0, a.Length); + mac.DoFinal(b1, 0); + a = b1; + mac.BlockUpdate(a, 0, a.Length); + mac.BlockUpdate(seed, 0, seed.Length); + mac.DoFinal(b2, 0); + Array.Copy(b2, 0, output, pos, System.Math.Min(macSize, output.Length - pos)); + pos += macSize; + } + } + + protected virtual byte[] Prf(int prfAlgorithm, string label, byte[] seed, int length) + { + if (PrfAlgorithm.ssl_prf_legacy == prfAlgorithm) + return Prf_Ssl(seed, length); + + byte[] labelSeed = Arrays.Concatenate(Strings.ToByteArray(label), seed); + + if (PrfAlgorithm.tls_prf_legacy == prfAlgorithm) + return Prf_1_0(labelSeed, length); + + return Prf_1_2(prfAlgorithm, labelSeed, length); + } + + protected virtual byte[] Prf_Ssl(byte[] seed, int length) + { + IDigest md5 = m_crypto.CreateDigest(CryptoHashAlgorithm.md5); + IDigest sha1 = m_crypto.CreateDigest(CryptoHashAlgorithm.sha1); + + int md5Size = md5.GetDigestSize(); + int sha1Size = sha1.GetDigestSize(); + + byte[] tmp = new byte[System.Math.Max(md5Size, sha1Size)]; + byte[] result = new byte[length]; + + int constLen = 1, constPos = 0, resultPos = 0; + while (resultPos < length) + { + sha1.BlockUpdate(Ssl3Const, constPos, constLen); + constPos += constLen++; + + sha1.BlockUpdate(m_data, 0, m_data.Length); + sha1.BlockUpdate(seed, 0, seed.Length); + sha1.DoFinal(tmp, 0); + + md5.BlockUpdate(m_data, 0, m_data.Length); + md5.BlockUpdate(tmp, 0, sha1Size); + + int remaining = length - resultPos; + if (remaining < md5Size) + { + md5.DoFinal(tmp, 0); + Array.Copy(tmp, 0, result, resultPos, remaining); + resultPos += remaining; + } + else + { + md5.DoFinal(result, resultPos); + resultPos += md5Size; + } + } + + return result; + } + + protected virtual byte[] Prf_1_0(byte[] labelSeed, int length) + { + int s_half = (m_data.Length + 1) / 2; + + IDigest md5 = m_crypto.CreateDigest(CryptoHashAlgorithm.md5); + byte[] b1 = new byte[length]; + HmacHash(md5, m_data, 0, s_half, labelSeed, b1); + + IDigest sha1 = m_crypto.CreateDigest(CryptoHashAlgorithm.sha1); + byte[] b2 = new byte[length]; + HmacHash(sha1, m_data, m_data.Length - s_half, s_half, labelSeed, b2); + + for (int i = 0; i < length; i++) + { + b1[i] ^= b2[i]; + } + return b1; + } + + protected virtual byte[] Prf_1_2(int prfAlgorithm, byte[] labelSeed, int length) + { + IDigest digest = m_crypto.CreateDigest(TlsCryptoUtilities.GetHashForPrf(prfAlgorithm)); + byte[] result = new byte[length]; + HmacHash(digest, m_data, 0, m_data.Length, labelSeed, result); + return result; + } + + protected virtual void UpdateMac(IMac mac) + { + lock (this) + { + CheckAlive(); + + mac.BlockUpdate(m_data, 0, m_data.Length); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsSecret.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsSecret.cs.meta new file mode 100644 index 0000000..346e262 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsSecret.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: eee3ba04384c15049a9a3d88e3f264a2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsSigner.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsSigner.cs new file mode 100644 index 0000000..8418030 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsSigner.cs @@ -0,0 +1,33 @@ +using System; + +using Org.BouncyCastle.Crypto; + +namespace Org.BouncyCastle.Tls.Crypto.Impl.BC +{ + public abstract class BcTlsSigner + : TlsSigner + { + protected readonly BcTlsCrypto m_crypto; + protected readonly AsymmetricKeyParameter m_privateKey; + + protected BcTlsSigner(BcTlsCrypto crypto, AsymmetricKeyParameter privateKey) + { + if (crypto == null) + throw new ArgumentNullException("crypto"); + if (privateKey == null) + throw new ArgumentNullException("privateKey"); + if (!privateKey.IsPrivate) + throw new ArgumentException("must be private", "privateKey"); + + this.m_crypto = crypto; + this.m_privateKey = privateKey; + } + + public abstract byte[] GenerateRawSignature(SignatureAndHashAlgorithm algorithm, byte[] hash); + + public virtual TlsStreamSigner GetStreamSigner(SignatureAndHashAlgorithm algorithm) + { + return null; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsSigner.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsSigner.cs.meta new file mode 100644 index 0000000..16dbb2d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsSigner.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3d028b4876ec12d4185a6e2a69d1b2f1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsSrp6Client.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsSrp6Client.cs new file mode 100644 index 0000000..de4b9bd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsSrp6Client.cs @@ -0,0 +1,36 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Agreement.Srp; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Tls.Crypto.Impl.BC +{ + internal sealed class BcTlsSrp6Client + : TlsSrp6Client + { + private readonly Srp6Client m_srp6Client; + + internal BcTlsSrp6Client(Srp6Client srpClient) + { + this.m_srp6Client = srpClient; + } + + public BigInteger CalculateSecret(BigInteger serverB) + { + try + { + return m_srp6Client.CalculateSecret(serverB); + } + catch (CryptoException e) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter, e); + } + } + + public BigInteger GenerateClientCredentials(byte[] srpSalt, byte[] identity, byte[] password) + { + return m_srp6Client.GenerateClientCredentials(srpSalt, identity, password); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsSrp6Client.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsSrp6Client.cs.meta new file mode 100644 index 0000000..ecbe752 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsSrp6Client.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8c11a864cd00b4b41b612ac26a882700 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsSrp6Server.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsSrp6Server.cs new file mode 100644 index 0000000..8ee79f6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsSrp6Server.cs @@ -0,0 +1,36 @@ +using System; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Agreement.Srp; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Tls.Crypto.Impl.BC +{ + internal sealed class BcTlsSrp6Server + : TlsSrp6Server + { + private readonly Srp6Server m_srp6Server; + + internal BcTlsSrp6Server(Srp6Server srp6Server) + { + this.m_srp6Server = srp6Server; + } + + public BigInteger GenerateServerCredentials() + { + return m_srp6Server.GenerateServerCredentials(); + } + + public BigInteger CalculateSecret(BigInteger clientA) + { + try + { + return m_srp6Server.CalculateSecret(clientA); + } + catch (CryptoException e) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter, e); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsSrp6Server.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsSrp6Server.cs.meta new file mode 100644 index 0000000..764eb23 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsSrp6Server.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2182e6be20287e144b8300ddf3e31e5b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsSrp6VerifierGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsSrp6VerifierGenerator.cs new file mode 100644 index 0000000..3d9e23a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsSrp6VerifierGenerator.cs @@ -0,0 +1,23 @@ +using System; + +using Org.BouncyCastle.Crypto.Agreement.Srp; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Tls.Crypto.Impl.BC +{ + internal sealed class BcTlsSrp6VerifierGenerator + : TlsSrp6VerifierGenerator + { + private readonly Srp6VerifierGenerator m_srp6VerifierGenerator; + + internal BcTlsSrp6VerifierGenerator(Srp6VerifierGenerator srp6VerifierGenerator) + { + this.m_srp6VerifierGenerator = srp6VerifierGenerator; + } + + public BigInteger GenerateVerifier(byte[] salt, byte[] identity, byte[] password) + { + return m_srp6VerifierGenerator.GenerateVerifier(salt, identity, password); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsSrp6VerifierGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsSrp6VerifierGenerator.cs.meta new file mode 100644 index 0000000..c5a7309 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsSrp6VerifierGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 19c09490146b63d42beedd3ec4d62b89 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsStreamSigner.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsStreamSigner.cs new file mode 100644 index 0000000..158fb05 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsStreamSigner.cs @@ -0,0 +1,36 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.IO; + +namespace Org.BouncyCastle.Tls.Crypto.Impl.BC +{ + internal sealed class BcTlsStreamSigner + : TlsStreamSigner + { + private readonly SignerSink m_output; + + internal BcTlsStreamSigner(ISigner signer) + { + this.m_output = new SignerSink(signer); + } + + public Stream GetOutputStream() + { + return m_output; + } + + public byte[] GetSignature() + { + try + { + return m_output.Signer.GenerateSignature(); + } + catch (CryptoException e) + { + throw new TlsFatalAlert(AlertDescription.internal_error, e); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsStreamSigner.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsStreamSigner.cs.meta new file mode 100644 index 0000000..252bd9d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsStreamSigner.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bad2cf2e850a9bd4ba8b2436d3022207 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsStreamVerifier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsStreamVerifier.cs new file mode 100644 index 0000000..0848a30 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsStreamVerifier.cs @@ -0,0 +1,31 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.IO; + +namespace Org.BouncyCastle.Tls.Crypto.Impl.BC +{ + internal sealed class BcTlsStreamVerifier + : TlsStreamVerifier + { + private readonly SignerSink m_output; + private readonly byte[] m_signature; + + internal BcTlsStreamVerifier(ISigner verifier, byte[] signature) + { + this.m_output = new SignerSink(verifier); + this.m_signature = signature; + } + + public Stream GetOutputStream() + { + return m_output; + } + + public bool IsVerified() + { + return m_output.Signer.VerifySignature(m_signature); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsStreamVerifier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsStreamVerifier.cs.meta new file mode 100644 index 0000000..65ce15d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsStreamVerifier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c0a367caf7b30d14daac84044ed6922d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsVerifier.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsVerifier.cs new file mode 100644 index 0000000..dc8d21d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsVerifier.cs @@ -0,0 +1,33 @@ +using System; + +using Org.BouncyCastle.Crypto; + +namespace Org.BouncyCastle.Tls.Crypto.Impl.BC +{ + public abstract class BcTlsVerifier + : TlsVerifier + { + protected readonly BcTlsCrypto m_crypto; + protected readonly AsymmetricKeyParameter m_publicKey; + + protected BcTlsVerifier(BcTlsCrypto crypto, AsymmetricKeyParameter publicKey) + { + if (crypto == null) + throw new ArgumentNullException("crypto"); + if (publicKey == null) + throw new ArgumentNullException("publicKey"); + if (publicKey.IsPrivate) + throw new ArgumentException("must be public", "publicKey"); + + this.m_crypto = crypto; + this.m_publicKey = publicKey; + } + + public virtual TlsStreamVerifier GetStreamVerifier(DigitallySigned signature) + { + return null; + } + + public abstract bool VerifyRawSignature(DigitallySigned signature, byte[] hash); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsVerifier.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsVerifier.cs.meta new file mode 100644 index 0000000..cbd91d7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcTlsVerifier.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fdc33da8c761c2244b9e53c10512ccec +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcVerifyingStreamSigner.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcVerifyingStreamSigner.cs new file mode 100644 index 0000000..4d95068 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcVerifyingStreamSigner.cs @@ -0,0 +1,48 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.IO; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Tls.Crypto.Impl.BC +{ + internal sealed class BcVerifyingStreamSigner + : TlsStreamSigner + { + private readonly ISigner m_signer; + private readonly ISigner m_verifier; + private readonly TeeOutputStream m_output; + + internal BcVerifyingStreamSigner(ISigner signer, ISigner verifier) + { + Stream outputSigner = new SignerSink(signer); + Stream outputVerifier = new SignerSink(verifier); + + this.m_signer = signer; + this.m_verifier = verifier; + this.m_output = new TeeOutputStream(outputSigner, outputVerifier); + } + + public Stream GetOutputStream() + { + return m_output; + } + + public byte[] GetSignature() + { + try + { + byte[] signature = m_signer.GenerateSignature(); + if (m_verifier.VerifySignature(signature)) + return signature; + } + catch (CryptoException e) + { + throw new TlsFatalAlert(AlertDescription.internal_error, e); + } + + throw new TlsFatalAlert(AlertDescription.internal_error); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcVerifyingStreamSigner.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcVerifyingStreamSigner.cs.meta new file mode 100644 index 0000000..a07bfcc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcVerifyingStreamSigner.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7068e33679aa4ad488e55dc11564c0ee +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcX25519.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcX25519.cs new file mode 100644 index 0000000..c26bc51 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcX25519.cs @@ -0,0 +1,54 @@ +using System; + +using Org.BouncyCastle.Math.EC.Rfc7748; + +namespace Org.BouncyCastle.Tls.Crypto.Impl.BC +{ + /// Support class for X25519 using the BC light-weight library. + public class BcX25519 + : TlsAgreement + { + protected readonly BcTlsCrypto m_crypto; + protected readonly byte[] m_privateKey = new byte[X25519.ScalarSize]; + protected readonly byte[] m_peerPublicKey = new byte[X25519.PointSize]; + + public BcX25519(BcTlsCrypto crypto) + { + this.m_crypto = crypto; + } + + public virtual byte[] GenerateEphemeral() + { + m_crypto.SecureRandom.NextBytes(m_privateKey); + + byte[] publicKey = new byte[X25519.PointSize]; + X25519.ScalarMultBase(m_privateKey, 0, publicKey, 0); + return publicKey; + } + + public virtual void ReceivePeerValue(byte[] peerValue) + { + if (peerValue == null || peerValue.Length != X25519.PointSize) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + Array.Copy(peerValue, 0, m_peerPublicKey, 0, X25519.PointSize); + } + + public virtual TlsSecret CalculateSecret() + { + try + { + byte[] secret = new byte[X25519.PointSize]; + if (!X25519.CalculateAgreement(m_privateKey, 0, m_peerPublicKey, 0, secret, 0)) + throw new TlsFatalAlert(AlertDescription.handshake_failure); + + return m_crypto.AdoptLocalSecret(secret); + } + finally + { + Array.Clear(m_privateKey, 0, m_privateKey.Length); + Array.Clear(m_peerPublicKey, 0, m_peerPublicKey.Length); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcX25519.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcX25519.cs.meta new file mode 100644 index 0000000..b85781e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcX25519.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 445fc59c2bb7f454f8de935e46379aae +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcX25519Domain.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcX25519Domain.cs new file mode 100644 index 0000000..58767cf --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcX25519Domain.cs @@ -0,0 +1,20 @@ +using System; + +namespace Org.BouncyCastle.Tls.Crypto.Impl.BC +{ + public class BcX25519Domain + : TlsECDomain + { + protected readonly BcTlsCrypto m_crypto; + + public BcX25519Domain(BcTlsCrypto crypto) + { + this.m_crypto = crypto; + } + + public virtual TlsAgreement CreateECDH() + { + return new BcX25519(m_crypto); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcX25519Domain.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcX25519Domain.cs.meta new file mode 100644 index 0000000..3cc53f5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcX25519Domain.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 34caed3908f87014db7b8f59d977800e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcX448.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcX448.cs new file mode 100644 index 0000000..ebeba4e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcX448.cs @@ -0,0 +1,54 @@ +using System; + +using Org.BouncyCastle.Math.EC.Rfc7748; + +namespace Org.BouncyCastle.Tls.Crypto.Impl.BC +{ + /// Support class for X448 using the BC light-weight library. + public class BcX448 + : TlsAgreement + { + protected readonly BcTlsCrypto m_crypto; + protected readonly byte[] m_privateKey = new byte[X448.ScalarSize]; + protected readonly byte[] m_peerPublicKey = new byte[X448.PointSize]; + + public BcX448(BcTlsCrypto crypto) + { + this.m_crypto = crypto; + } + + public virtual byte[] GenerateEphemeral() + { + m_crypto.SecureRandom.NextBytes(m_privateKey); + + byte[] publicKey = new byte[X448.PointSize]; + X448.ScalarMultBase(m_privateKey, 0, publicKey, 0); + return publicKey; + } + + public virtual void ReceivePeerValue(byte[] peerValue) + { + if (peerValue == null || peerValue.Length != X448.PointSize) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + + Array.Copy(peerValue, 0, m_peerPublicKey, 0, X448.PointSize); + } + + public virtual TlsSecret CalculateSecret() + { + try + { + byte[] secret = new byte[X448.PointSize]; + if (!X448.CalculateAgreement(m_privateKey, 0, m_peerPublicKey, 0, secret, 0)) + throw new TlsFatalAlert(AlertDescription.handshake_failure); + + return m_crypto.AdoptLocalSecret(secret); + } + finally + { + Array.Clear(m_privateKey, 0, m_privateKey.Length); + Array.Clear(m_peerPublicKey, 0, m_peerPublicKey.Length); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcX448.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcX448.cs.meta new file mode 100644 index 0000000..134f69f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcX448.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4d107e1c0d28722448b93627c9e43a94 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcX448Domain.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcX448Domain.cs new file mode 100644 index 0000000..757fa8f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcX448Domain.cs @@ -0,0 +1,20 @@ +using System; + +namespace Org.BouncyCastle.Tls.Crypto.Impl.BC +{ + public class BcX448Domain + : TlsECDomain + { + protected readonly BcTlsCrypto m_crypto; + + public BcX448Domain(BcTlsCrypto crypto) + { + this.m_crypto = crypto; + } + + public virtual TlsAgreement CreateECDH() + { + return new BcX448(m_crypto); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcX448Domain.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcX448Domain.cs.meta new file mode 100644 index 0000000..ad48558 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tls/crypto/impl/bc/BcX448Domain.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fed16569f05adba4da44ac0520b09626 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp.meta new file mode 100644 index 0000000..0b20f95 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d617ff087e0812c49a48f620d2ae906e +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/GenTimeAccuracy.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/GenTimeAccuracy.cs new file mode 100644 index 0000000..400bf6f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/GenTimeAccuracy.cs @@ -0,0 +1,33 @@ +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Tsp; + +namespace Org.BouncyCastle.Tsp +{ + public class GenTimeAccuracy + { + private Accuracy accuracy; + + public GenTimeAccuracy( + Accuracy accuracy) + { + this.accuracy = accuracy; + } + + public int Seconds { get { return GetTimeComponent(accuracy.Seconds); } } + + public int Millis { get { return GetTimeComponent(accuracy.Millis); } } + + public int Micros { get { return GetTimeComponent(accuracy.Micros); } } + + private int GetTimeComponent( + DerInteger time) + { + return time == null ? 0 : time.IntValueExact; + } + + public override string ToString() + { + return Seconds + "." + Millis.ToString("000") + Micros.ToString("000"); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/GenTimeAccuracy.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/GenTimeAccuracy.cs.meta new file mode 100644 index 0000000..213f5c4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/GenTimeAccuracy.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9446bed1d9c9e3c49b00fc2be9a0b375 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TSPAlgorithms.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TSPAlgorithms.cs new file mode 100644 index 0000000..928468e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TSPAlgorithms.cs @@ -0,0 +1,54 @@ +using System.Collections; + +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Asn1.GM; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Oiw; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.Rosstandart; +using Org.BouncyCastle.Asn1.TeleTrust; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tsp +{ + /** + * Recognised hash algorithms for the time stamp protocol. + */ + public abstract class TspAlgorithms + { + public static readonly string MD5 = PkcsObjectIdentifiers.MD5.Id; + + public static readonly string Sha1 = OiwObjectIdentifiers.IdSha1.Id; + + public static readonly string Sha224 = NistObjectIdentifiers.IdSha224.Id; + public static readonly string Sha256 = NistObjectIdentifiers.IdSha256.Id; + public static readonly string Sha384 = NistObjectIdentifiers.IdSha384.Id; + public static readonly string Sha512 = NistObjectIdentifiers.IdSha512.Id; + + public static readonly string RipeMD128 = TeleTrusTObjectIdentifiers.RipeMD128.Id; + public static readonly string RipeMD160 = TeleTrusTObjectIdentifiers.RipeMD160.Id; + public static readonly string RipeMD256 = TeleTrusTObjectIdentifiers.RipeMD256.Id; + + public static readonly string Gost3411 = CryptoProObjectIdentifiers.GostR3411.Id; + public static readonly string Gost3411_2012_256 = RosstandartObjectIdentifiers.id_tc26_gost_3411_12_256.Id; + public static readonly string Gost3411_2012_512 = RosstandartObjectIdentifiers.id_tc26_gost_3411_12_512.Id; + + public static readonly string SM3 = GMObjectIdentifiers.sm3.Id; + + public static readonly IList Allowed; + + static TspAlgorithms() + { + string[] algs = new string[] + { + Gost3411, Gost3411_2012_256, Gost3411_2012_512, MD5, RipeMD128, RipeMD160, RipeMD256, Sha1, Sha224, Sha256, Sha384, Sha512, SM3 + }; + + Allowed = Platform.CreateArrayList(); + foreach (string alg in algs) + { + Allowed.Add(alg); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TSPAlgorithms.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TSPAlgorithms.cs.meta new file mode 100644 index 0000000..14b9620 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TSPAlgorithms.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ab90b3d40749f604398b7d5995d4638b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TSPException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TSPException.cs new file mode 100644 index 0000000..0f29b12 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TSPException.cs @@ -0,0 +1,28 @@ +using System; + +namespace Org.BouncyCastle.Tsp +{ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE) + [Serializable] +#endif + public class TspException + : Exception + { + public TspException() + { + } + + public TspException( + string message) + : base(message) + { + } + + public TspException( + string message, + Exception e) + : base(message, e) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TSPException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TSPException.cs.meta new file mode 100644 index 0000000..3a2519e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TSPException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8cd17e24ed8b2864996fd8b5749d1cdc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TSPUtil.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TSPUtil.cs new file mode 100644 index 0000000..a176574 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TSPUtil.cs @@ -0,0 +1,214 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Asn1.GM; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Oiw; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.Rosstandart; +using Org.BouncyCastle.Asn1.TeleTrust; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Cms; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.Tsp +{ + public class TspUtil + { + private static ISet EmptySet = CollectionUtilities.ReadOnly(new HashSet()); + private static IList EmptyList = CollectionUtilities.ReadOnly(Platform.CreateArrayList()); + + private static readonly IDictionary digestLengths = Platform.CreateHashtable(); + private static readonly IDictionary digestNames = Platform.CreateHashtable(); + + static TspUtil() + { + digestLengths.Add(PkcsObjectIdentifiers.MD5.Id, 16); + digestLengths.Add(OiwObjectIdentifiers.IdSha1.Id, 20); + digestLengths.Add(NistObjectIdentifiers.IdSha224.Id, 28); + digestLengths.Add(NistObjectIdentifiers.IdSha256.Id, 32); + digestLengths.Add(NistObjectIdentifiers.IdSha384.Id, 48); + digestLengths.Add(NistObjectIdentifiers.IdSha512.Id, 64); + digestLengths.Add(TeleTrusTObjectIdentifiers.RipeMD128.Id, 16); + digestLengths.Add(TeleTrusTObjectIdentifiers.RipeMD160.Id, 20); + digestLengths.Add(TeleTrusTObjectIdentifiers.RipeMD256.Id, 32); + digestLengths.Add(CryptoProObjectIdentifiers.GostR3411.Id, 32); + digestLengths.Add(RosstandartObjectIdentifiers.id_tc26_gost_3411_12_256.Id, 32); + digestLengths.Add(RosstandartObjectIdentifiers.id_tc26_gost_3411_12_512.Id, 64); + digestLengths.Add(GMObjectIdentifiers.sm3.Id, 32); + + digestNames.Add(PkcsObjectIdentifiers.MD5.Id, "MD5"); + digestNames.Add(OiwObjectIdentifiers.IdSha1.Id, "SHA1"); + digestNames.Add(NistObjectIdentifiers.IdSha224.Id, "SHA224"); + digestNames.Add(NistObjectIdentifiers.IdSha256.Id, "SHA256"); + digestNames.Add(NistObjectIdentifiers.IdSha384.Id, "SHA384"); + digestNames.Add(NistObjectIdentifiers.IdSha512.Id, "SHA512"); + digestNames.Add(PkcsObjectIdentifiers.MD5WithRsaEncryption.Id, "MD5"); + digestNames.Add(PkcsObjectIdentifiers.Sha1WithRsaEncryption.Id, "SHA1"); + digestNames.Add(PkcsObjectIdentifiers.Sha224WithRsaEncryption.Id, "SHA224"); + digestNames.Add(PkcsObjectIdentifiers.Sha256WithRsaEncryption.Id, "SHA256"); + digestNames.Add(PkcsObjectIdentifiers.Sha384WithRsaEncryption.Id, "SHA384"); + digestNames.Add(PkcsObjectIdentifiers.Sha512WithRsaEncryption.Id, "SHA512"); + digestNames.Add(TeleTrusTObjectIdentifiers.RipeMD128.Id, "RIPEMD128"); + digestNames.Add(TeleTrusTObjectIdentifiers.RipeMD160.Id, "RIPEMD160"); + digestNames.Add(TeleTrusTObjectIdentifiers.RipeMD256.Id, "RIPEMD256"); + digestNames.Add(CryptoProObjectIdentifiers.GostR3411.Id, "GOST3411"); + digestNames.Add(OiwObjectIdentifiers.DsaWithSha1.Id, "SHA1"); + digestNames.Add(OiwObjectIdentifiers.Sha1WithRsa.Id, "SHA1"); + digestNames.Add(OiwObjectIdentifiers.MD5WithRsa.Id, "MD5"); + digestNames.Add(RosstandartObjectIdentifiers.id_tc26_gost_3411_12_256.Id, "GOST3411-2012-256"); + digestNames.Add(RosstandartObjectIdentifiers.id_tc26_gost_3411_12_512.Id, "GOST3411-2012-512"); + digestNames.Add(GMObjectIdentifiers.sm3.Id, "SM3"); + } + + + /** + * Fetches the signature time-stamp attributes from a SignerInformation object. + * Checks that the MessageImprint for each time-stamp matches the signature field. + * (see RFC 3161 Appendix A). + * + * @param signerInfo a SignerInformation to search for time-stamps + * @return a collection of TimeStampToken objects + * @throws TSPValidationException + */ + public static ICollection GetSignatureTimestamps( + SignerInformation signerInfo) + { + IList timestamps = Platform.CreateArrayList(); + + Asn1.Cms.AttributeTable unsignedAttrs = signerInfo.UnsignedAttributes; + if (unsignedAttrs != null) + { + foreach (Asn1.Cms.Attribute tsAttr in unsignedAttrs.GetAll( + PkcsObjectIdentifiers.IdAASignatureTimeStampToken)) + { + foreach (Asn1Encodable asn1 in tsAttr.AttrValues) + { + try + { + Asn1.Cms.ContentInfo contentInfo = Asn1.Cms.ContentInfo.GetInstance( + asn1.ToAsn1Object()); + TimeStampToken timeStampToken = new TimeStampToken(contentInfo); + TimeStampTokenInfo tstInfo = timeStampToken.TimeStampInfo; + + byte[] expectedDigest = DigestUtilities.CalculateDigest( + GetDigestAlgName(tstInfo.MessageImprintAlgOid), + signerInfo.GetSignature()); + + if (!Arrays.ConstantTimeAreEqual(expectedDigest, tstInfo.GetMessageImprintDigest())) + throw new TspValidationException("Incorrect digest in message imprint"); + + timestamps.Add(timeStampToken); + } + catch (SecurityUtilityException) + { + throw new TspValidationException("Unknown hash algorithm specified in timestamp"); + } + catch (Exception) + { + throw new TspValidationException("Timestamp could not be parsed"); + } + } + } + } + + return timestamps; + } + + /** + * Validate the passed in certificate as being of the correct type to be used + * for time stamping. To be valid it must have an ExtendedKeyUsage extension + * which has a key purpose identifier of id-kp-timeStamping. + * + * @param cert the certificate of interest. + * @throws TspValidationException if the certicate fails on one of the check points. + */ + public static void ValidateCertificate( + X509Certificate cert) + { + if (cert.Version != 3) + throw new ArgumentException("Certificate must have an ExtendedKeyUsage extension."); + + Asn1OctetString ext = cert.GetExtensionValue(X509Extensions.ExtendedKeyUsage); + if (ext == null) + throw new TspValidationException("Certificate must have an ExtendedKeyUsage extension."); + + if (!cert.GetCriticalExtensionOids().Contains(X509Extensions.ExtendedKeyUsage.Id)) + throw new TspValidationException("Certificate must have an ExtendedKeyUsage extension marked as critical."); + + try + { + ExtendedKeyUsage extKey = ExtendedKeyUsage.GetInstance( + Asn1Object.FromByteArray(ext.GetOctets())); + + if (!extKey.HasKeyPurposeId(KeyPurposeID.IdKPTimeStamping) || extKey.Count != 1) + throw new TspValidationException("ExtendedKeyUsage not solely time stamping."); + } + catch (IOException) + { + throw new TspValidationException("cannot process ExtendedKeyUsage extension"); + } + } + + /// + /// Return the digest algorithm using one of the standard JCA string + /// representations rather than the algorithm identifier (if possible). + /// + internal static string GetDigestAlgName( + string digestAlgOID) + { + string digestName = (string) digestNames[digestAlgOID]; + + return digestName != null ? digestName : digestAlgOID; + } + + internal static int GetDigestLength( + string digestAlgOID) + { + if (!digestLengths.Contains(digestAlgOID)) + throw new TspException("digest algorithm cannot be found."); + + return (int)digestLengths[digestAlgOID]; + } + + internal static IDigest CreateDigestInstance( + String digestAlgOID) + { + string digestName = GetDigestAlgName(digestAlgOID); + + return DigestUtilities.GetDigest(digestName); + } + + internal static ISet GetCriticalExtensionOids(X509Extensions extensions) + { + if (extensions == null) + return EmptySet; + + return CollectionUtilities.ReadOnly(new HashSet(extensions.GetCriticalExtensionOids())); + } + + internal static ISet GetNonCriticalExtensionOids(X509Extensions extensions) + { + if (extensions == null) + return EmptySet; + + // TODO: should probably produce a set that imposes correct ordering + return CollectionUtilities.ReadOnly(new HashSet(extensions.GetNonCriticalExtensionOids())); + } + + internal static IList GetExtensionOids(X509Extensions extensions) + { + if (extensions == null) + return EmptyList; + + return CollectionUtilities.ReadOnly(Platform.CreateArrayList(extensions.GetExtensionOids())); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TSPUtil.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TSPUtil.cs.meta new file mode 100644 index 0000000..f9c057f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TSPUtil.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3d8071b6899e41545bf1740e7ae8b819 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TSPValidationException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TSPValidationException.cs new file mode 100644 index 0000000..80f6420 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TSPValidationException.cs @@ -0,0 +1,44 @@ +using System; + +namespace Org.BouncyCastle.Tsp +{ + /** + * Exception thrown if a TSP request or response fails to validate. + *

    + * If a failure code is associated with the exception it can be retrieved using + * the getFailureCode() method.

    + */ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE) + [Serializable] +#endif + public class TspValidationException + : TspException + { + private int failureCode; + + public TspValidationException( + string message) + : base(message) + { + this.failureCode = -1; + } + + public TspValidationException( + string message, + int failureCode) + : base(message) + { + this.failureCode = failureCode; + } + + /** + * Return the failure code associated with this exception - if one is set. + * + * @return the failure code if set, -1 otherwise. + */ + public int FailureCode + { + get { return failureCode; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TSPValidationException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TSPValidationException.cs.meta new file mode 100644 index 0000000..730feaa --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TSPValidationException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8cba33fe63514a643a83c110ceade533 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TimeStampRequest.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TimeStampRequest.cs new file mode 100644 index 0000000..f5c6a09 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TimeStampRequest.cs @@ -0,0 +1,186 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cmp; +using Org.BouncyCastle.Asn1.Tsp; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.Tsp +{ + /** + * Base class for an RFC 3161 Time Stamp Request. + */ + public class TimeStampRequest + : X509ExtensionBase + { + private TimeStampReq req; + private X509Extensions extensions; + + public TimeStampRequest( + TimeStampReq req) + { + this.req = req; + this.extensions = req.Extensions; + } + + /** + * Create a TimeStampRequest from the past in byte array. + * + * @param req byte array containing the request. + * @throws IOException if the request is malformed. + */ + public TimeStampRequest( + byte[] req) + : this(new Asn1InputStream(req)) + { + } + + /** + * Create a TimeStampRequest from the past in input stream. + * + * @param in input stream containing the request. + * @throws IOException if the request is malformed. + */ + public TimeStampRequest( + Stream input) + : this(new Asn1InputStream(input)) + { + } + + private TimeStampRequest( + Asn1InputStream str) + { + try + { + this.req = TimeStampReq.GetInstance(str.ReadObject()); + } + catch (InvalidCastException e) + { + throw new IOException("malformed request: " + e); + } + catch (ArgumentException e) + { + throw new IOException("malformed request: " + e); + } + } + + public int Version + { + get { return req.Version.IntValueExact; } + } + + public string MessageImprintAlgOid + { + get { return req.MessageImprint.HashAlgorithm.Algorithm.Id; } + } + + public byte[] GetMessageImprintDigest() + { + return req.MessageImprint.GetHashedMessage(); + } + + public string ReqPolicy + { + get + { + return req.ReqPolicy == null + ? null + : req.ReqPolicy.Id; + } + } + + public BigInteger Nonce + { + get + { + return req.Nonce == null + ? null + : req.Nonce.Value; + } + } + + public bool CertReq + { + get + { + return req.CertReq == null + ? false + : req.CertReq.IsTrue; + } + } + + /** + * Validate the timestamp request, checking the digest to see if it is of an + * accepted type and whether it is of the correct length for the algorithm specified. + * + * @param algorithms a set of string OIDS giving accepted algorithms. + * @param policies if non-null a set of policies we are willing to sign under. + * @param extensions if non-null a set of extensions we are willing to accept. + * @throws TspException if the request is invalid, or processing fails. + */ + public void Validate( + IList algorithms, + IList policies, + IList extensions) + { + if (!algorithms.Contains(this.MessageImprintAlgOid)) + throw new TspValidationException("request contains unknown algorithm", PkiFailureInfo.BadAlg); + + if (policies != null && this.ReqPolicy != null && !policies.Contains(this.ReqPolicy)) + throw new TspValidationException("request contains unknown policy", PkiFailureInfo.UnacceptedPolicy); + + if (this.Extensions != null && extensions != null) + { + foreach (DerObjectIdentifier oid in this.Extensions.ExtensionOids) + { + if (!extensions.Contains(oid.Id)) + throw new TspValidationException("request contains unknown extension", PkiFailureInfo.UnacceptedExtension); + } + } + + int digestLength = TspUtil.GetDigestLength(this.MessageImprintAlgOid); + + if (digestLength != this.GetMessageImprintDigest().Length) + throw new TspValidationException("imprint digest the wrong length", PkiFailureInfo.BadDataFormat); + } + + /** + * return the ASN.1 encoded representation of this object. + */ + public byte[] GetEncoded() + { + return req.GetEncoded(); + } + + internal X509Extensions Extensions + { + get { return req.Extensions; } + } + + public virtual bool HasExtensions + { + get { return extensions != null; } + } + + public virtual X509Extension GetExtension(DerObjectIdentifier oid) + { + return extensions == null ? null : extensions.GetExtension(oid); + } + + public virtual IList GetExtensionOids() + { + return TspUtil.GetExtensionOids(extensions); + } + + protected override X509Extensions GetX509Extensions() + { + return Extensions; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TimeStampRequest.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TimeStampRequest.cs.meta new file mode 100644 index 0000000..5416135 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TimeStampRequest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 043a57a2b0f527e4daa237ae23b37874 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TimeStampRequestGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TimeStampRequestGenerator.cs new file mode 100644 index 0000000..2c698e4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TimeStampRequestGenerator.cs @@ -0,0 +1,139 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Tsp; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Math; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tsp +{ + /** + * Generator for RFC 3161 Time Stamp Request objects. + */ + public class TimeStampRequestGenerator + { + private DerObjectIdentifier reqPolicy; + + private DerBoolean certReq; + + private IDictionary extensions = Platform.CreateHashtable(); + private IList extOrdering = Platform.CreateArrayList(); + + public void SetReqPolicy( + string reqPolicy) + { + this.reqPolicy = new DerObjectIdentifier(reqPolicy); + } + + public void SetCertReq( + bool certReq) + { + this.certReq = DerBoolean.GetInstance(certReq); + } + + /** + * add a given extension field for the standard extensions tag (tag 3) + * @throws IOException + */ + [Obsolete("Use method taking DerObjectIdentifier")] + public void AddExtension( + string oid, + bool critical, + Asn1Encodable value) + { + this.AddExtension(oid, critical, value.GetEncoded()); + } + + /** + * add a given extension field for the standard extensions tag + * The value parameter becomes the contents of the octet string associated + * with the extension. + */ + [Obsolete("Use method taking DerObjectIdentifier")] + public void AddExtension( + string oid, + bool critical, + byte[] value) + { + DerObjectIdentifier derOid = new DerObjectIdentifier(oid); + extensions[derOid] = new X509Extension(critical, new DerOctetString(value)); + extOrdering.Add(derOid); + } + + /** + * add a given extension field for the standard extensions tag (tag 3) + * @throws IOException + */ + public virtual void AddExtension( + DerObjectIdentifier oid, + bool critical, + Asn1Encodable extValue) + { + this.AddExtension(oid, critical, extValue.GetEncoded()); + } + + /** + * add a given extension field for the standard extensions tag + * The value parameter becomes the contents of the octet string associated + * with the extension. + */ + public virtual void AddExtension( + DerObjectIdentifier oid, + bool critical, + byte[] extValue) + { + extensions.Add(oid, new X509Extension(critical, new DerOctetString(extValue))); + extOrdering.Add(oid); + } + + public TimeStampRequest Generate( + string digestAlgorithm, + byte[] digest) + { + return this.Generate(digestAlgorithm, digest, null); + } + + public TimeStampRequest Generate( + string digestAlgorithmOid, + byte[] digest, + BigInteger nonce) + { + if (digestAlgorithmOid == null) + { + throw new ArgumentException("No digest algorithm specified"); + } + + DerObjectIdentifier digestAlgOid = new DerObjectIdentifier(digestAlgorithmOid); + + AlgorithmIdentifier algID = new AlgorithmIdentifier(digestAlgOid, DerNull.Instance); + MessageImprint messageImprint = new MessageImprint(algID, digest); + + X509Extensions ext = null; + + if (extOrdering.Count != 0) + { + ext = new X509Extensions(extOrdering, extensions); + } + + DerInteger derNonce = nonce == null + ? null + : new DerInteger(nonce); + + return new TimeStampRequest( + new TimeStampReq(messageImprint, reqPolicy, derNonce, certReq, ext)); + } + + public virtual TimeStampRequest Generate(DerObjectIdentifier digestAlgorithm, byte[] digest) + { + return Generate(digestAlgorithm.Id, digest); + } + + public virtual TimeStampRequest Generate(DerObjectIdentifier digestAlgorithm, byte[] digest, BigInteger nonce) + { + return Generate(digestAlgorithm.Id, digest, nonce); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TimeStampRequestGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TimeStampRequestGenerator.cs.meta new file mode 100644 index 0000000..18a726d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TimeStampRequestGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ba9095a8b2bfc314f8f87958966f37dc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TimeStampResponse.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TimeStampResponse.cs new file mode 100644 index 0000000..0695211 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TimeStampResponse.cs @@ -0,0 +1,184 @@ +using System; +using System.IO; +using System.Text; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cmp; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.Tsp; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Tsp +{ + /** + * Base class for an RFC 3161 Time Stamp Response object. + */ + public class TimeStampResponse + { + private TimeStampResp resp; + private TimeStampToken timeStampToken; + + public TimeStampResponse( + TimeStampResp resp) + { + this.resp = resp; + + if (resp.TimeStampToken != null) + { + timeStampToken = new TimeStampToken(resp.TimeStampToken); + } + } + + /** + * Create a TimeStampResponse from a byte array containing an ASN.1 encoding. + * + * @param resp the byte array containing the encoded response. + * @throws TspException if the response is malformed. + * @throws IOException if the byte array doesn't represent an ASN.1 encoding. + */ + public TimeStampResponse( + byte[] resp) + : this(readTimeStampResp(new Asn1InputStream(resp))) + { + } + + /** + * Create a TimeStampResponse from an input stream containing an ASN.1 encoding. + * + * @param input the input stream containing the encoded response. + * @throws TspException if the response is malformed. + * @throws IOException if the stream doesn't represent an ASN.1 encoding. + */ + public TimeStampResponse( + Stream input) + : this(readTimeStampResp(new Asn1InputStream(input))) + { + } + + private static TimeStampResp readTimeStampResp( + Asn1InputStream input) + { + try + { + return TimeStampResp.GetInstance(input.ReadObject()); + } + catch (ArgumentException e) + { + throw new TspException("malformed timestamp response: " + e, e); + } + catch (InvalidCastException e) + { + throw new TspException("malformed timestamp response: " + e, e); + } + } + + public int Status + { + get { return resp.Status.Status.IntValue; } + } + + public string GetStatusString() + { + if (resp.Status.StatusString == null) + { + return null; + } + + StringBuilder statusStringBuf = new StringBuilder(); + PkiFreeText text = resp.Status.StatusString; + for (int i = 0; i != text.Count; i++) + { + statusStringBuf.Append(text[i].GetString()); + } + + return statusStringBuf.ToString(); + } + + public PkiFailureInfo GetFailInfo() + { + if (resp.Status.FailInfo == null) + { + return null; + } + + return new PkiFailureInfo(resp.Status.FailInfo); + } + + public TimeStampToken TimeStampToken + { + get { return timeStampToken; } + } + + /** + * Check this response against to see if it a well formed response for + * the passed in request. Validation will include checking the time stamp + * token if the response status is GRANTED or GRANTED_WITH_MODS. + * + * @param request the request to be checked against + * @throws TspException if the request can not match this response. + */ + public void Validate( + TimeStampRequest request) + { + TimeStampToken tok = this.TimeStampToken; + + if (tok != null) + { + TimeStampTokenInfo tstInfo = tok.TimeStampInfo; + + if (request.Nonce != null && !request.Nonce.Equals(tstInfo.Nonce)) + { + throw new TspValidationException("response contains wrong nonce value."); + } + + if (this.Status != (int) PkiStatus.Granted && this.Status != (int) PkiStatus.GrantedWithMods) + { + throw new TspValidationException("time stamp token found in failed request."); + } + + if (!Arrays.ConstantTimeAreEqual(request.GetMessageImprintDigest(), tstInfo.GetMessageImprintDigest())) + { + throw new TspValidationException("response for different message imprint digest."); + } + + if (!tstInfo.MessageImprintAlgOid.Equals(request.MessageImprintAlgOid)) + { + throw new TspValidationException("response for different message imprint algorithm."); + } + + Asn1.Cms.Attribute scV1 = tok.SignedAttributes[PkcsObjectIdentifiers.IdAASigningCertificate]; + Asn1.Cms.Attribute scV2 = tok.SignedAttributes[PkcsObjectIdentifiers.IdAASigningCertificateV2]; + + if (scV1 == null && scV2 == null) + { + throw new TspValidationException("no signing certificate attribute present."); + } + + if (scV1 != null && scV2 != null) + { + /* + * RFC 5035 5.4. If both attributes exist in a single message, + * they are independently evaluated. + */ + } + + if (request.ReqPolicy != null && !request.ReqPolicy.Equals(tstInfo.Policy)) + { + throw new TspValidationException("TSA policy wrong for request."); + } + } + else if (this.Status == (int) PkiStatus.Granted || this.Status == (int) PkiStatus.GrantedWithMods) + { + throw new TspValidationException("no time stamp token found and one expected."); + } + } + + /** + * return the ASN.1 encoded representation of this object. + */ + public byte[] GetEncoded() + { + return resp.GetEncoded(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TimeStampResponse.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TimeStampResponse.cs.meta new file mode 100644 index 0000000..8e78fee --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TimeStampResponse.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f0c55b752ae252a438847e67b86c142b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TimeStampResponseGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TimeStampResponseGenerator.cs new file mode 100644 index 0000000..69a5c09 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TimeStampResponseGenerator.cs @@ -0,0 +1,272 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cmp; +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Asn1.Tsp; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities.Date; + +namespace Org.BouncyCastle.Tsp +{ + /** + * Generator for RFC 3161 Time Stamp Responses. + */ + public class TimeStampResponseGenerator + { + private PkiStatus status; + + private Asn1EncodableVector statusStrings; + + private int failInfo; + private TimeStampTokenGenerator tokenGenerator; + private IList acceptedAlgorithms; + private IList acceptedPolicies; + private IList acceptedExtensions; + + public TimeStampResponseGenerator( + TimeStampTokenGenerator tokenGenerator, + IList acceptedAlgorithms) + : this(tokenGenerator, acceptedAlgorithms, null, null) + { + } + + public TimeStampResponseGenerator( + TimeStampTokenGenerator tokenGenerator, + IList acceptedAlgorithms, + IList acceptedPolicy) + : this(tokenGenerator, acceptedAlgorithms, acceptedPolicy, null) + { + } + + public TimeStampResponseGenerator( + TimeStampTokenGenerator tokenGenerator, + IList acceptedAlgorithms, + IList acceptedPolicies, + IList acceptedExtensions) + { + this.tokenGenerator = tokenGenerator; + this.acceptedAlgorithms = acceptedAlgorithms; + this.acceptedPolicies = acceptedPolicies; + this.acceptedExtensions = acceptedExtensions; + + statusStrings = new Asn1EncodableVector(); + } + + private void AddStatusString(string statusString) + { + statusStrings.Add(new DerUtf8String(statusString)); + } + + private void SetFailInfoField(int field) + { + failInfo |= field; + } + + private PkiStatusInfo GetPkiStatusInfo() + { + Asn1EncodableVector v = new Asn1EncodableVector( + new DerInteger((int)status)); + + if (statusStrings.Count > 0) + { + v.Add(new PkiFreeText(new DerSequence(statusStrings))); + } + + if (failInfo != 0) + { + v.Add(new FailInfo(failInfo)); + } + + return new PkiStatusInfo(new DerSequence(v)); + } + + public TimeStampResponse Generate( + TimeStampRequest request, + BigInteger serialNumber, + DateTime genTime) + { + return Generate(request, serialNumber, new DateTimeObject(genTime)); + } + + /** + * Return an appropriate TimeStampResponse. + *

    + * If genTime is null a timeNotAvailable error response will be returned. + * + * @param request the request this response is for. + * @param serialNumber serial number for the response token. + * @param genTime generation time for the response token. + * @param provider provider to use for signature calculation. + * @return + * @throws NoSuchAlgorithmException + * @throws NoSuchProviderException + * @throws TSPException + *

    + */ + public TimeStampResponse Generate( + TimeStampRequest request, + BigInteger serialNumber, + DateTimeObject genTime) + { + TimeStampResp resp; + + try + { + if (genTime == null) + throw new TspValidationException("The time source is not available.", + PkiFailureInfo.TimeNotAvailable); + + request.Validate(acceptedAlgorithms, acceptedPolicies, acceptedExtensions); + + this.status = PkiStatus.Granted; + this.AddStatusString("Operation Okay"); + + PkiStatusInfo pkiStatusInfo = GetPkiStatusInfo(); + + ContentInfo tstTokenContentInfo; + try + { + TimeStampToken token = tokenGenerator.Generate(request, serialNumber, genTime.Value); + byte[] encoded = token.ToCmsSignedData().GetEncoded(); + + tstTokenContentInfo = ContentInfo.GetInstance(Asn1Object.FromByteArray(encoded)); + } + catch (IOException e) + { + throw new TspException("Timestamp token received cannot be converted to ContentInfo", e); + } + + resp = new TimeStampResp(pkiStatusInfo, tstTokenContentInfo); + } + catch (TspValidationException e) + { + status = PkiStatus.Rejection; + + this.SetFailInfoField(e.FailureCode); + this.AddStatusString(e.Message); + + PkiStatusInfo pkiStatusInfo = GetPkiStatusInfo(); + + resp = new TimeStampResp(pkiStatusInfo, null); + } + + try + { + return new TimeStampResponse(resp); + } + catch (IOException e) + { + throw new TspException("created badly formatted response!", e); + } + } + + + public TimeStampResponse GenerateGrantedResponse( + TimeStampRequest request, + BigInteger serialNumber, + DateTimeObject genTime, + String statusString, + X509Extensions additionalExtensions) + { + TimeStampResp resp; + + try + { + if (genTime == null) + throw new TspValidationException("The time source is not available.", + PkiFailureInfo.TimeNotAvailable); + + request.Validate(acceptedAlgorithms, acceptedPolicies, acceptedExtensions); + + this.status = PkiStatus.Granted; + this.AddStatusString(statusString); + + PkiStatusInfo pkiStatusInfo = GetPkiStatusInfo(); + + ContentInfo tstTokenContentInfo; + try + { + TimeStampToken token = tokenGenerator.Generate(request, serialNumber, genTime.Value,additionalExtensions); + byte[] encoded = token.ToCmsSignedData().GetEncoded(); + + tstTokenContentInfo = ContentInfo.GetInstance(Asn1Object.FromByteArray(encoded)); + } + catch (IOException e) + { + throw new TspException("Timestamp token received cannot be converted to ContentInfo", e); + } + + resp = new TimeStampResp(pkiStatusInfo, tstTokenContentInfo); + } + catch (TspValidationException e) + { + status = PkiStatus.Rejection; + + this.SetFailInfoField(e.FailureCode); + this.AddStatusString(e.Message); + + PkiStatusInfo pkiStatusInfo = GetPkiStatusInfo(); + + resp = new TimeStampResp(pkiStatusInfo, null); + } + + try + { + return new TimeStampResponse(resp); + } + catch (IOException e) + { + throw new TspException("created badly formatted response!", e); + } + } + + + + class FailInfo + : DerBitString + { + internal FailInfo(int failInfoValue) + : base(failInfoValue) + { + } + } + + /** + * Generate a TimeStampResponse with chosen status and FailInfoField. + * + * @param status the PKIStatus to set. + * @param failInfoField the FailInfoField to set. + * @param statusString an optional string describing the failure. + * @return a TimeStampResponse with a failInfoField and optional statusString + * @throws TSPException in case the response could not be created + */ + public TimeStampResponse GenerateFailResponse(PkiStatus status, int failInfoField, string statusString) + { + this.status = status; + + this.SetFailInfoField(failInfoField); + + if (statusString != null) + { + this.AddStatusString(statusString); + } + + PkiStatusInfo pkiStatusInfo = GetPkiStatusInfo(); + + TimeStampResp resp = new TimeStampResp(pkiStatusInfo, null); + + try + { + return new TimeStampResponse(resp); + } + catch (IOException e) + { + throw new TspException("created badly formatted response!", e); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TimeStampResponseGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TimeStampResponseGenerator.cs.meta new file mode 100644 index 0000000..6040a3e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TimeStampResponseGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0a723995245082c408e6e2f6a8e14dbf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TimeStampToken.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TimeStampToken.cs new file mode 100644 index 0000000..9b2a7a4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TimeStampToken.cs @@ -0,0 +1,322 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Ess; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Oiw; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.Tsp; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Cms; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Security.Certificates; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.X509; +using Org.BouncyCastle.X509.Store; + +namespace Org.BouncyCastle.Tsp +{ + public class TimeStampToken + { + private readonly CmsSignedData tsToken; + private readonly SignerInformation tsaSignerInfo; +// private readonly DateTime genTime; + private readonly TimeStampTokenInfo tstInfo; + private readonly CertID certID; + + public TimeStampToken( + Asn1.Cms.ContentInfo contentInfo) + : this(new CmsSignedData(contentInfo)) + { + } + + public TimeStampToken( + CmsSignedData signedData) + { + this.tsToken = signedData; + + if (!this.tsToken.SignedContentType.Equals(PkcsObjectIdentifiers.IdCTTstInfo)) + { + throw new TspValidationException("ContentInfo object not for a time stamp."); + } + + ICollection signers = tsToken.GetSignerInfos().GetSigners(); + + if (signers.Count != 1) + { + throw new ArgumentException("Time-stamp token signed by " + + signers.Count + + " signers, but it must contain just the TSA signature."); + } + + + IEnumerator signerEnum = signers.GetEnumerator(); + + signerEnum.MoveNext(); + tsaSignerInfo = (SignerInformation) signerEnum.Current; + + try + { + CmsProcessable content = tsToken.SignedContent; + MemoryStream bOut = new MemoryStream(); + + content.Write(bOut); + + this.tstInfo = new TimeStampTokenInfo( + TstInfo.GetInstance( + Asn1Object.FromByteArray(bOut.ToArray()))); + + Asn1.Cms.Attribute attr = tsaSignerInfo.SignedAttributes[ + PkcsObjectIdentifiers.IdAASigningCertificate]; + +// if (attr == null) +// { +// throw new TspValidationException( +// "no signing certificate attribute found, time stamp invalid."); +// } +// +// SigningCertificate signCert = SigningCertificate.GetInstance( +// attr.AttrValues[0]); +// +// this.certID = EssCertID.GetInstance(signCert.GetCerts()[0]); + + if (attr != null) + { + + if (attr.AttrValues[0] is SigningCertificateV2) + { + SigningCertificateV2 signCert = SigningCertificateV2.GetInstance(attr.AttrValues[0]); + this.certID = new CertID(EssCertIDv2.GetInstance(signCert.GetCerts()[0])); + } + else + { + SigningCertificate signCert = SigningCertificate.GetInstance(attr.AttrValues[0]); + this.certID = new CertID(EssCertID.GetInstance(signCert.GetCerts()[0])); + } + } + else + { + attr = tsaSignerInfo.SignedAttributes[PkcsObjectIdentifiers.IdAASigningCertificateV2]; + + if (attr == null) + throw new TspValidationException("no signing certificate attribute found, time stamp invalid."); + + SigningCertificateV2 signCertV2 = SigningCertificateV2.GetInstance(attr.AttrValues[0]); + + this.certID = new CertID(EssCertIDv2.GetInstance(signCertV2.GetCerts()[0])); + } + } + catch (CmsException e) + { + throw new TspException(e.Message, e.InnerException); + } + } + + public TimeStampTokenInfo TimeStampInfo + { + get { return tstInfo; } + } + + public SignerID SignerID + { + get { return tsaSignerInfo.SignerID; } + } + + public Asn1.Cms.AttributeTable SignedAttributes + { + get { return tsaSignerInfo.SignedAttributes; } + } + + public Asn1.Cms.AttributeTable UnsignedAttributes + { + get { return tsaSignerInfo.UnsignedAttributes; } + } + + public IX509Store GetCertificates( + string type) + { + return tsToken.GetCertificates(type); + } + + public IX509Store GetCrls( + string type) + { + return tsToken.GetCrls(type); + } + + public IX509Store GetCertificates() + { + return tsToken.GetCertificates(); + } + + public IX509Store GetAttributeCertificates( + string type) + { + return tsToken.GetAttributeCertificates(type); + } + + /** + * Validate the time stamp token. + *

    + * To be valid the token must be signed by the passed in certificate and + * the certificate must be the one referred to by the SigningCertificate + * attribute included in the hashed attributes of the token. The + * certificate must also have the ExtendedKeyUsageExtension with only + * KeyPurposeID.IdKPTimeStamping and have been valid at the time the + * timestamp was created. + *

    + *

    + * A successful call to validate means all the above are true. + *

    + */ + public void Validate( + X509Certificate cert) + { + try + { + byte[] hash = DigestUtilities.CalculateDigest( + certID.GetHashAlgorithmName(), cert.GetEncoded()); + + if (!Arrays.ConstantTimeAreEqual(certID.GetCertHash(), hash)) + throw new TspValidationException("certificate hash does not match certID hash."); + + if (certID.IssuerSerial != null) + { + if (!certID.IssuerSerial.Serial.HasValue(cert.SerialNumber)) + throw new TspValidationException("certificate serial number does not match certID for signature."); + + GeneralName[] names = certID.IssuerSerial.Issuer.GetNames(); + X509Name principal = PrincipalUtilities.GetIssuerX509Principal(cert); + bool found = false; + + for (int i = 0; i != names.Length; i++) + { + if (names[i].TagNo == 4 + && X509Name.GetInstance(names[i].Name).Equivalent(principal)) + { + found = true; + break; + } + } + + if (!found) + { + throw new TspValidationException("certificate name does not match certID for signature. "); + } + } + + TspUtil.ValidateCertificate(cert); + + cert.CheckValidity(tstInfo.GenTime); + + if (!tsaSignerInfo.Verify(cert)) + { + throw new TspValidationException("signature not created by certificate."); + } + } + catch (CmsException e) + { + if (e.InnerException != null) + { + throw new TspException(e.Message, e.InnerException); + } + + throw new TspException("CMS exception: " + e, e); + } + catch (CertificateEncodingException e) + { + throw new TspException("problem processing certificate: " + e, e); + } + catch (SecurityUtilityException e) + { + throw new TspException("cannot find algorithm: " + e.Message, e); + } + } + + /** + * Return the underlying CmsSignedData object. + * + * @return the underlying CMS structure. + */ + public CmsSignedData ToCmsSignedData() + { + return tsToken; + } + + /** + * Return a ASN.1 encoded byte stream representing the encoded object. + * + * @throws IOException if encoding fails. + */ + public byte[] GetEncoded() + { + return tsToken.GetEncoded(Asn1Encodable.Der); + } + + /** + * return the ASN.1 encoded representation of this object using the specified encoding. + * + * @param encoding the ASN.1 encoding format to use ("BER" or "DER"). + */ + public byte[] GetEncoded(string encoding) + { + return tsToken.GetEncoded(encoding); + } + + // perhaps this should be done using an interface on the ASN.1 classes... + private class CertID + { + private EssCertID certID; + private EssCertIDv2 certIDv2; + + internal CertID(EssCertID certID) + { + this.certID = certID; + this.certIDv2 = null; + } + + internal CertID(EssCertIDv2 certID) + { + this.certIDv2 = certID; + this.certID = null; + } + + public string GetHashAlgorithmName() + { + if (certID != null) + return "SHA-1"; + + if (NistObjectIdentifiers.IdSha256.Equals(certIDv2.HashAlgorithm.Algorithm)) + return "SHA-256"; + + return certIDv2.HashAlgorithm.Algorithm.Id; + } + + public AlgorithmIdentifier GetHashAlgorithm() + { + return (certID != null) + ? new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1) + : certIDv2.HashAlgorithm; + } + + public byte[] GetCertHash() + { + return certID != null + ? certID.GetCertHash() + : certIDv2.GetCertHash(); + } + + public IssuerSerial IssuerSerial + { + get + { + return certID != null + ? certID.IssuerSerial + : certIDv2.IssuerSerial; + } + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TimeStampToken.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TimeStampToken.cs.meta new file mode 100644 index 0000000..549be07 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TimeStampToken.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3894877af73300b458b8e33db34f95df +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TimeStampTokenGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TimeStampTokenGenerator.cs new file mode 100644 index 0000000..55142a5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TimeStampTokenGenerator.cs @@ -0,0 +1,496 @@ +using System; +using System.Collections; +using System.IO; +using System.Text; +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cmp; +using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Asn1.Ess; +using Org.BouncyCastle.Asn1.Oiw; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.Tsp; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Cms; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Operators; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.X509; +using Org.BouncyCastle.X509.Store; + +namespace Org.BouncyCastle.Tsp +{ + public enum Resolution + { + R_SECONDS, R_TENTHS_OF_SECONDS, R_HUNDREDTHS_OF_SECONDS, R_MILLISECONDS + } + + public class TimeStampTokenGenerator + { + private int accuracySeconds = -1; + private int accuracyMillis = -1; + private int accuracyMicros = -1; + private bool ordering = false; + private GeneralName tsa = null; + private DerObjectIdentifier tsaPolicyOID; + + private IX509Store x509Certs; + private IX509Store x509Crls; + private SignerInfoGenerator signerInfoGenerator; + IDigestFactory digestCalculator; + + private Resolution resolution = Resolution.R_SECONDS; + + public Resolution Resolution + { + get { return resolution; } + set { resolution = value; } + } + + /** + * basic creation - only the default attributes will be included here. + */ + public TimeStampTokenGenerator( + AsymmetricKeyParameter key, + X509Certificate cert, + string digestOID, + string tsaPolicyOID) + : this(key, cert, digestOID, tsaPolicyOID, null, null) + { + } + + + public TimeStampTokenGenerator( + SignerInfoGenerator signerInfoGen, + IDigestFactory digestCalculator, + DerObjectIdentifier tsaPolicy, + bool isIssuerSerialIncluded) + { + + this.signerInfoGenerator = signerInfoGen; + this.digestCalculator = digestCalculator; + this.tsaPolicyOID = tsaPolicy; + + if (signerInfoGenerator.certificate == null) + { + throw new ArgumentException("SignerInfoGenerator must have an associated certificate"); + } + + X509Certificate assocCert = signerInfoGenerator.certificate; + TspUtil.ValidateCertificate(assocCert); + + try + { + IStreamCalculator calculator = digestCalculator.CreateCalculator(); + Stream stream = calculator.Stream; + byte[] certEnc = assocCert.GetEncoded(); + stream.Write(certEnc, 0, certEnc.Length); + stream.Flush(); + Platform.Dispose(stream); + + if (((AlgorithmIdentifier)digestCalculator.AlgorithmDetails).Algorithm.Equals(OiwObjectIdentifiers.IdSha1)) + { + EssCertID essCertID = new EssCertID( + ((IBlockResult)calculator.GetResult()).Collect(), + isIssuerSerialIncluded ? + new IssuerSerial( + new GeneralNames( + new GeneralName(assocCert.IssuerDN)), + new DerInteger(assocCert.SerialNumber)) : null); + + this.signerInfoGenerator = signerInfoGen.NewBuilder() + .WithSignedAttributeGenerator(new TableGen(signerInfoGen, essCertID)) + .Build(signerInfoGen.contentSigner, signerInfoGen.certificate); + } + else + { + AlgorithmIdentifier digestAlgID = new AlgorithmIdentifier( + ((AlgorithmIdentifier)digestCalculator.AlgorithmDetails).Algorithm); + + EssCertIDv2 essCertID = new EssCertIDv2( + ((IBlockResult)calculator.GetResult()).Collect(), + isIssuerSerialIncluded ? + new IssuerSerial( + new GeneralNames( + new GeneralName(assocCert.IssuerDN)), + new DerInteger(assocCert.SerialNumber)) : null); + + this.signerInfoGenerator = signerInfoGen.NewBuilder() + .WithSignedAttributeGenerator(new TableGen2(signerInfoGen, essCertID)) + .Build(signerInfoGen.contentSigner, signerInfoGen.certificate); + } + + } + catch (Exception ex) + { + throw new TspException("Exception processing certificate", ex); + } + } + + /** + * create with a signer with extra signed/unsigned attributes. + */ + public TimeStampTokenGenerator( + AsymmetricKeyParameter key, + X509Certificate cert, + string digestOID, + string tsaPolicyOID, + Asn1.Cms.AttributeTable signedAttr, + Asn1.Cms.AttributeTable unsignedAttr) : this( + makeInfoGenerator(key, cert, digestOID, signedAttr, unsignedAttr), + Asn1DigestFactory.Get(OiwObjectIdentifiers.IdSha1), + tsaPolicyOID != null ? new DerObjectIdentifier(tsaPolicyOID):null, false) + { + } + + + internal static SignerInfoGenerator makeInfoGenerator( + AsymmetricKeyParameter key, + X509Certificate cert, + string digestOID, + + Asn1.Cms.AttributeTable signedAttr, + Asn1.Cms.AttributeTable unsignedAttr) + { + + + TspUtil.ValidateCertificate(cert); + + // + // Add the ESSCertID attribute + // + IDictionary signedAttrs; + if (signedAttr != null) + { + signedAttrs = signedAttr.ToDictionary(); + } + else + { + signedAttrs = Platform.CreateHashtable(); + } + + //try + //{ + // byte[] hash = DigestUtilities.CalculateDigest("SHA-1", cert.GetEncoded()); + + // EssCertID essCertid = new EssCertID(hash); + + // Asn1.Cms.Attribute attr = new Asn1.Cms.Attribute( + // PkcsObjectIdentifiers.IdAASigningCertificate, + // new DerSet(new SigningCertificate(essCertid))); + + // signedAttrs[attr.AttrType] = attr; + //} + //catch (CertificateEncodingException e) + //{ + // throw new TspException("Exception processing certificate.", e); + //} + //catch (SecurityUtilityException e) + //{ + // throw new TspException("Can't find a SHA-1 implementation.", e); + //} + + + string digestName = CmsSignedHelper.Instance.GetDigestAlgName(digestOID); + string signatureName = digestName + "with" + CmsSignedHelper.Instance.GetEncryptionAlgName(CmsSignedHelper.Instance.GetEncOid(key, digestOID)); + + Asn1SignatureFactory sigfact = new Asn1SignatureFactory(signatureName, key); + return new SignerInfoGeneratorBuilder() + .WithSignedAttributeGenerator( + new DefaultSignedAttributeTableGenerator( + new Asn1.Cms.AttributeTable(signedAttrs))) + .WithUnsignedAttributeGenerator( + new SimpleAttributeTableGenerator(unsignedAttr)) + .Build(sigfact, cert); + } + + + public void SetCertificates( + IX509Store certificates) + { + this.x509Certs = certificates; + } + + public void SetCrls( + IX509Store crls) + { + this.x509Crls = crls; + } + + public void SetAccuracySeconds( + int accuracySeconds) + { + this.accuracySeconds = accuracySeconds; + } + + public void SetAccuracyMillis( + int accuracyMillis) + { + this.accuracyMillis = accuracyMillis; + } + + public void SetAccuracyMicros( + int accuracyMicros) + { + this.accuracyMicros = accuracyMicros; + } + + public void SetOrdering( + bool ordering) + { + this.ordering = ordering; + } + + public void SetTsa( + GeneralName tsa) + { + this.tsa = tsa; + } + + //------------------------------------------------------------------------------ + + public TimeStampToken Generate( + TimeStampRequest request, + BigInteger serialNumber, + DateTime genTime) + { + return Generate(request, serialNumber, genTime, null); + } + + + public TimeStampToken Generate( + TimeStampRequest request, + BigInteger serialNumber, + DateTime genTime, X509Extensions additionalExtensions) + { + DerObjectIdentifier digestAlgOID = new DerObjectIdentifier(request.MessageImprintAlgOid); + + AlgorithmIdentifier algID = new AlgorithmIdentifier(digestAlgOID, DerNull.Instance); + MessageImprint messageImprint = new MessageImprint(algID, request.GetMessageImprintDigest()); + + Accuracy accuracy = null; + if (accuracySeconds > 0 || accuracyMillis > 0 || accuracyMicros > 0) + { + DerInteger seconds = null; + if (accuracySeconds > 0) + { + seconds = new DerInteger(accuracySeconds); + } + + DerInteger millis = null; + if (accuracyMillis > 0) + { + millis = new DerInteger(accuracyMillis); + } + + DerInteger micros = null; + if (accuracyMicros > 0) + { + micros = new DerInteger(accuracyMicros); + } + + accuracy = new Accuracy(seconds, millis, micros); + } + + DerBoolean derOrdering = null; + if (ordering) + { + derOrdering = DerBoolean.GetInstance(ordering); + } + + DerInteger nonce = null; + if (request.Nonce != null) + { + nonce = new DerInteger(request.Nonce); + } + + DerObjectIdentifier tsaPolicy = tsaPolicyOID; + if (request.ReqPolicy != null) + { + tsaPolicy = new DerObjectIdentifier(request.ReqPolicy); + } + + if (tsaPolicy == null) + { + throw new TspValidationException("request contains no policy", PkiFailureInfo.UnacceptedPolicy); + } + + X509Extensions respExtensions = request.Extensions; + if (additionalExtensions != null) + { + X509ExtensionsGenerator extGen = new X509ExtensionsGenerator(); + + if (respExtensions != null) + { + foreach(object oid in respExtensions.ExtensionOids) + { + DerObjectIdentifier id = DerObjectIdentifier.GetInstance(oid); + extGen.AddExtension(id, respExtensions.GetExtension(DerObjectIdentifier.GetInstance(id))); + } + } + + foreach (object oid in additionalExtensions.ExtensionOids) + { + DerObjectIdentifier id = DerObjectIdentifier.GetInstance(oid); + extGen.AddExtension(id, additionalExtensions.GetExtension(DerObjectIdentifier.GetInstance(id))); + + } + + respExtensions = extGen.Generate(); + } + + + + DerGeneralizedTime generalizedTime; + if (resolution != Resolution.R_SECONDS) + { + generalizedTime = new DerGeneralizedTime(createGeneralizedTime(genTime)); + } + else + { + generalizedTime = new DerGeneralizedTime(genTime); + } + + + TstInfo tstInfo = new TstInfo(tsaPolicy, messageImprint, + new DerInteger(serialNumber), generalizedTime, accuracy, + derOrdering, nonce, tsa, respExtensions); + + try + { + CmsSignedDataGenerator signedDataGenerator = new CmsSignedDataGenerator(); + + byte[] derEncodedTstInfo = tstInfo.GetDerEncoded(); + + if (request.CertReq) + { + signedDataGenerator.AddCertificates(x509Certs); + } + + signedDataGenerator.AddCrls(x509Crls); + + signedDataGenerator.AddSignerInfoGenerator(signerInfoGenerator); + + CmsSignedData signedData = signedDataGenerator.Generate( + PkcsObjectIdentifiers.IdCTTstInfo.Id, + new CmsProcessableByteArray(derEncodedTstInfo), + true); + + return new TimeStampToken(signedData); + } + catch (CmsException cmsEx) + { + throw new TspException("Error generating time-stamp token", cmsEx); + } + catch (IOException e) + { + throw new TspException("Exception encoding info", e); + } + catch (X509StoreException e) + { + throw new TspException("Exception handling CertStore", e); + } + // catch (InvalidAlgorithmParameterException e) + // { + // throw new TspException("Exception handling CertStore CRLs", e); + // } + } + + private string createGeneralizedTime(DateTime genTime) + { + String format = "yyyyMMddHHmmss.fff"; + + StringBuilder sBuild = new StringBuilder(genTime.ToString(format)); + int dotIndex = sBuild.ToString().IndexOf("."); + + if (dotIndex <0) + { + sBuild.Append("Z"); + return sBuild.ToString(); + } + + switch(resolution) + { + case Resolution.R_TENTHS_OF_SECONDS: + if (sBuild.Length > dotIndex + 2) + { + sBuild.Remove(dotIndex + 2, sBuild.Length-(dotIndex+2)); + } + break; + case Resolution.R_HUNDREDTHS_OF_SECONDS: + if (sBuild.Length > dotIndex + 3) + { + sBuild.Remove(dotIndex + 3, sBuild.Length-(dotIndex+3)); + } + break; + + + case Resolution.R_SECONDS: + case Resolution.R_MILLISECONDS: + // do nothing. + break; + + } + + + while (sBuild[sBuild.Length - 1] == '0') + { + sBuild.Remove(sBuild.Length - 1,1); + } + + if (sBuild.Length - 1 == dotIndex) + { + sBuild.Remove(sBuild.Length - 1, 1); + } + + sBuild.Append("Z"); + return sBuild.ToString(); + } + + private class TableGen : CmsAttributeTableGenerator + { + private readonly SignerInfoGenerator infoGen; + private readonly EssCertID essCertID; + + + public TableGen(SignerInfoGenerator infoGen, EssCertID essCertID) + { + this.infoGen = infoGen; + this.essCertID = essCertID; + } + + public Asn1.Cms.AttributeTable GetAttributes(IDictionary parameters) + { + Asn1.Cms.AttributeTable tab = infoGen.signedGen.GetAttributes(parameters); + if (tab[PkcsObjectIdentifiers.IdAASigningCertificate] == null) + { + return tab.Add(PkcsObjectIdentifiers.IdAASigningCertificate, new SigningCertificate(essCertID)); + } + return tab; + } + } + + private class TableGen2 : CmsAttributeTableGenerator + { + private readonly SignerInfoGenerator infoGen; + private readonly EssCertIDv2 essCertID; + + + public TableGen2(SignerInfoGenerator infoGen, EssCertIDv2 essCertID) + { + this.infoGen = infoGen; + this.essCertID = essCertID; + } + + public Asn1.Cms.AttributeTable GetAttributes(IDictionary parameters) + { + Asn1.Cms.AttributeTable tab = infoGen.signedGen.GetAttributes(parameters); + if (tab[PkcsObjectIdentifiers.IdAASigningCertificateV2] == null) + { + return tab.Add(PkcsObjectIdentifiers.IdAASigningCertificateV2, new SigningCertificateV2(essCertID)); + } + return tab; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TimeStampTokenGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TimeStampTokenGenerator.cs.meta new file mode 100644 index 0000000..9f8c9ed --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TimeStampTokenGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5c55c5f73dcca5e4d837442fe53f0c39 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TimeStampTokenInfo.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TimeStampTokenInfo.cs new file mode 100644 index 0000000..cdef826 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TimeStampTokenInfo.cs @@ -0,0 +1,107 @@ +using System; + +using Org.BouncyCastle.Asn1.Tsp; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Tsp +{ + public class TimeStampTokenInfo + { + private TstInfo tstInfo; + private DateTime genTime; + + public TimeStampTokenInfo( + TstInfo tstInfo) + { + this.tstInfo = tstInfo; + + try + { + this.genTime = tstInfo.GenTime.ToDateTime(); + } + catch (Exception e) + { + throw new TspException("unable to parse genTime field: " + e.Message); + } + } + + public bool IsOrdered + { + get { return tstInfo.Ordering.IsTrue; } + } + + public Accuracy Accuracy + { + get { return tstInfo.Accuracy; } + } + + public DateTime GenTime + { + get { return genTime; } + } + + public GenTimeAccuracy GenTimeAccuracy + { + get + { + return this.Accuracy == null + ? null + : new GenTimeAccuracy(this.Accuracy); + } + } + + public string Policy + { + get { return tstInfo.Policy.Id; } + } + + public BigInteger SerialNumber + { + get { return tstInfo.SerialNumber.Value; } + } + + public GeneralName Tsa + { + get { return tstInfo.Tsa; } + } + + /** + * @return the nonce value, null if there isn't one. + */ + public BigInteger Nonce + { + get + { + return tstInfo.Nonce == null + ? null + : tstInfo.Nonce.Value; + } + } + + public AlgorithmIdentifier HashAlgorithm + { + get { return tstInfo.MessageImprint.HashAlgorithm; } + } + + public string MessageImprintAlgOid + { + get { return tstInfo.MessageImprint.HashAlgorithm.Algorithm.Id; } + } + + public byte[] GetMessageImprintDigest() + { + return tstInfo.MessageImprint.GetHashedMessage(); + } + + public byte[] GetEncoded() + { + return tstInfo.GetEncoded(); + } + + public TstInfo TstInfo + { + get { return tstInfo; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TimeStampTokenInfo.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TimeStampTokenInfo.cs.meta new file mode 100644 index 0000000..4f4fc23 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/tsp/TimeStampTokenInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e7aabed398fee0d41b362d8e49842f5b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util.meta new file mode 100644 index 0000000..858f2cc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 56426038dcf087b4e80783c6def3ec46 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/Arrays.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/Arrays.cs new file mode 100644 index 0000000..86848af --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/Arrays.cs @@ -0,0 +1,922 @@ +using System; +using System.Text; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Utilities +{ + /// General array utilities. + public abstract class Arrays + { + public static readonly byte[] EmptyBytes = new byte[0]; + public static readonly int[] EmptyInts = new int[0]; + + public static bool AreAllZeroes(byte[] buf, int off, int len) + { + uint bits = 0; + for (int i = 0; i < len; ++i) + { + bits |= buf[off + i]; + } + return bits == 0; + } + + public static bool AreEqual( + bool[] a, + bool[] b) + { + if (a == b) + return true; + + if (a == null || b == null) + return false; + + return HaveSameContents(a, b); + } + + public static bool AreEqual( + char[] a, + char[] b) + { + if (a == b) + return true; + + if (a == null || b == null) + return false; + + return HaveSameContents(a, b); + } + + /// + /// Are two arrays equal. + /// + /// Left side. + /// Right side. + /// True if equal. + public static bool AreEqual(byte[] a, byte[] b) + { + if (a == b) + return true; + + if (a == null || b == null) + return false; + + return HaveSameContents(a, b); + } + + public static bool AreEqual(byte[] a, int aFromIndex, int aToIndex, byte[] b, int bFromIndex, int bToIndex) + { + int aLength = aToIndex - aFromIndex; + int bLength = bToIndex - bFromIndex; + + if (aLength != bLength) + return false; + + for (int i = 0; i < aLength; ++i) + { + if (a[aFromIndex + i] != b[bFromIndex + i]) + return false; + } + + return true; + } + + [Obsolete("Use 'AreEqual' method instead")] + public static bool AreSame( + byte[] a, + byte[] b) + { + return AreEqual(a, b); + } + + /// + /// A constant time equals comparison - does not terminate early if + /// test will fail. + /// + /// first array + /// second array + /// true if arrays equal, false otherwise. + public static bool ConstantTimeAreEqual(byte[] a, byte[] b) + { + if (null == a || null == b) + return false; + if (a == b) + return true; + + int len = System.Math.Min(a.Length, b.Length); + int nonEqual = a.Length ^ b.Length; + for (int i = 0; i < len; ++i) + { + nonEqual |= (a[i] ^ b[i]); + } + for (int i = len; i < b.Length; ++i) + { + nonEqual |= (b[i] ^ ~b[i]); + } + return 0 == nonEqual; + } + + public static bool ConstantTimeAreEqual(int len, byte[] a, int aOff, byte[] b, int bOff) + { + if (null == a) + throw new ArgumentNullException("a"); + if (null == b) + throw new ArgumentNullException("b"); + if (len < 0) + throw new ArgumentException("cannot be negative", "len"); + if (aOff > (a.Length - len)) + throw new IndexOutOfRangeException("'aOff' value invalid for specified length"); + if (bOff > (b.Length - len)) + throw new IndexOutOfRangeException("'bOff' value invalid for specified length"); + + int d = 0; + for (int i = 0; i < len; ++i) + { + d |= (a[aOff + i] ^ b[bOff + i]); + } + return 0 == d; + } + + public static bool AreEqual( + int[] a, + int[] b) + { + if (a == b) + return true; + + if (a == null || b == null) + return false; + + return HaveSameContents(a, b); + } + + [CLSCompliantAttribute(false)] + public static bool AreEqual(uint[] a, uint[] b) + { + if (a == b) + return true; + + if (a == null || b == null) + return false; + + return HaveSameContents(a, b); + } + + public static bool AreEqual(long[] a, long[] b) + { + if (a == b) + return true; + + if (a == null || b == null) + return false; + + return HaveSameContents(a, b); + } + + [CLSCompliantAttribute(false)] + public static bool AreEqual(ulong[] a, ulong[] b) + { + if (a == b) + return true; + + if (a == null || b == null) + return false; + + return HaveSameContents(a, b); + } + + private static bool HaveSameContents( + bool[] a, + bool[] b) + { + int i = a.Length; + if (i != b.Length) + return false; + while (i != 0) + { + --i; + if (a[i] != b[i]) + return false; + } + return true; + } + + private static bool HaveSameContents( + char[] a, + char[] b) + { + int i = a.Length; + if (i != b.Length) + return false; + while (i != 0) + { + --i; + if (a[i] != b[i]) + return false; + } + return true; + } + + private static bool HaveSameContents( + byte[] a, + byte[] b) + { + int i = a.Length; + if (i != b.Length) + return false; + while (i != 0) + { + --i; + if (a[i] != b[i]) + return false; + } + return true; + } + + private static bool HaveSameContents( + int[] a, + int[] b) + { + int i = a.Length; + if (i != b.Length) + return false; + while (i != 0) + { + --i; + if (a[i] != b[i]) + return false; + } + return true; + } + + private static bool HaveSameContents(uint[] a, uint[] b) + { + int i = a.Length; + if (i != b.Length) + return false; + while (i != 0) + { + --i; + if (a[i] != b[i]) + return false; + } + return true; + } + + private static bool HaveSameContents(long[] a, long[] b) + { + int i = a.Length; + if (i != b.Length) + return false; + while (i != 0) + { + --i; + if (a[i] != b[i]) + return false; + } + return true; + } + + private static bool HaveSameContents(ulong[] a, ulong[] b) + { + int i = a.Length; + if (i != b.Length) + return false; + while (i != 0) + { + --i; + if (a[i] != b[i]) + return false; + } + return true; + } + + public static string ToString( + object[] a) + { + StringBuilder sb = new StringBuilder("["); + if (a.Length > 0) + { + sb.Append(a[0]); + for (int index = 1; index < a.Length; ++index) + { + sb.Append(", ").Append(a[index]); + } + } + sb.Append(']'); + return sb.ToString(); + } + + public static int GetHashCode(byte[] data) + { + if (data == null) + { + return 0; + } + + int i = data.Length; + int hc = i + 1; + + while (--i >= 0) + { + hc *= 257; + hc ^= data[i]; + } + + return hc; + } + + public static int GetHashCode(byte[] data, int off, int len) + { + if (data == null) + { + return 0; + } + + int i = len; + int hc = i + 1; + + while (--i >= 0) + { + hc *= 257; + hc ^= data[off + i]; + } + + return hc; + } + + public static int GetHashCode(int[] data) + { + if (data == null) + return 0; + + int i = data.Length; + int hc = i + 1; + + while (--i >= 0) + { + hc *= 257; + hc ^= data[i]; + } + + return hc; + } + + [CLSCompliantAttribute(false)] + public static int GetHashCode(ushort[] data) + { + if (data == null) + return 0; + + int i = data.Length; + int hc = i + 1; + + while (--i >= 0) + { + hc *= 257; + hc ^= data[i]; + } + + return hc; + } + + public static int GetHashCode(int[] data, int off, int len) + { + if (data == null) + return 0; + + int i = len; + int hc = i + 1; + + while (--i >= 0) + { + hc *= 257; + hc ^= data[off + i]; + } + + return hc; + } + + [CLSCompliantAttribute(false)] + public static int GetHashCode(uint[] data) + { + if (data == null) + return 0; + + int i = data.Length; + int hc = i + 1; + + while (--i >= 0) + { + hc *= 257; + hc ^= (int)data[i]; + } + + return hc; + } + + [CLSCompliantAttribute(false)] + public static int GetHashCode(uint[] data, int off, int len) + { + if (data == null) + return 0; + + int i = len; + int hc = i + 1; + + while (--i >= 0) + { + hc *= 257; + hc ^= (int)data[off + i]; + } + + return hc; + } + + [CLSCompliantAttribute(false)] + public static int GetHashCode(ulong[] data) + { + if (data == null) + return 0; + + int i = data.Length; + int hc = i + 1; + + while (--i >= 0) + { + ulong di = data[i]; + hc *= 257; + hc ^= (int)di; + hc *= 257; + hc ^= (int)(di >> 32); + } + + return hc; + } + + [CLSCompliantAttribute(false)] + public static int GetHashCode(ulong[] data, int off, int len) + { + if (data == null) + return 0; + + int i = len; + int hc = i + 1; + + while (--i >= 0) + { + ulong di = data[off + i]; + hc *= 257; + hc ^= (int)di; + hc *= 257; + hc ^= (int)(di >> 32); + } + + return hc; + } + + public static bool[] Clone(bool[] data) + { + return data == null ? null : (bool[])data.Clone(); + } + + public static byte[] Clone(byte[] data) + { + return data == null ? null : (byte[])data.Clone(); + } + + public static short[] Clone(short[] data) + { + return data == null ? null : (short[])data.Clone(); + } + + [CLSCompliantAttribute(false)] + public static ushort[] Clone(ushort[] data) + { + return data == null ? null : (ushort[])data.Clone(); + } + + public static int[] Clone(int[] data) + { + return data == null ? null : (int[])data.Clone(); + } + + [CLSCompliantAttribute(false)] + public static uint[] Clone(uint[] data) + { + return data == null ? null : (uint[])data.Clone(); + } + + public static long[] Clone(long[] data) + { + return data == null ? null : (long[])data.Clone(); + } + + [CLSCompliantAttribute(false)] + public static ulong[] Clone(ulong[] data) + { + return data == null ? null : (ulong[])data.Clone(); + } + + public static byte[] Clone(byte[] data, byte[] existing) + { + if (data == null) + return null; + if (existing == null || existing.Length != data.Length) + return Clone(data); + Array.Copy(data, 0, existing, 0, existing.Length); + return existing; + } + + [CLSCompliantAttribute(false)] + public static ulong[] Clone(ulong[] data, ulong[] existing) + { + if (data == null) + return null; + if (existing == null || existing.Length != data.Length) + return Clone(data); + Array.Copy(data, 0, existing, 0, existing.Length); + return existing; + } + + public static bool Contains(byte[] a, byte n) + { + for (int i = 0; i < a.Length; ++i) + { + if (a[i] == n) + return true; + } + return false; + } + + public static bool Contains(short[] a, short n) + { + for (int i = 0; i < a.Length; ++i) + { + if (a[i] == n) + return true; + } + return false; + } + + public static bool Contains(int[] a, int n) + { + for (int i = 0; i < a.Length; ++i) + { + if (a[i] == n) + return true; + } + return false; + } + + public static void Fill( + byte[] buf, + byte b) + { + int i = buf.Length; + while (i > 0) + { + buf[--i] = b; + } + } + + public static void Fill(byte[] buf, int from, int to, byte b) + { + for (int i = from; i < to; ++i) + { + buf[i] = b; + } + } + + public static byte[] CopyOf(byte[] data, int newLength) + { + byte[] tmp = new byte[newLength]; + Array.Copy(data, 0, tmp, 0, System.Math.Min(newLength, data.Length)); + return tmp; + } + + public static char[] CopyOf(char[] data, int newLength) + { + char[] tmp = new char[newLength]; + Array.Copy(data, 0, tmp, 0, System.Math.Min(newLength, data.Length)); + return tmp; + } + + public static int[] CopyOf(int[] data, int newLength) + { + int[] tmp = new int[newLength]; + Array.Copy(data, 0, tmp, 0, System.Math.Min(newLength, data.Length)); + return tmp; + } + + public static long[] CopyOf(long[] data, int newLength) + { + long[] tmp = new long[newLength]; + Array.Copy(data, 0, tmp, 0, System.Math.Min(newLength, data.Length)); + return tmp; + } + + public static BigInteger[] CopyOf(BigInteger[] data, int newLength) + { + BigInteger[] tmp = new BigInteger[newLength]; + Array.Copy(data, 0, tmp, 0, System.Math.Min(newLength, data.Length)); + return tmp; + } + + /** + * Make a copy of a range of bytes from the passed in data array. The range can + * extend beyond the end of the input array, in which case the return array will + * be padded with zeroes. + * + * @param data the array from which the data is to be copied. + * @param from the start index at which the copying should take place. + * @param to the final index of the range (exclusive). + * + * @return a new byte array containing the range given. + */ + public static byte[] CopyOfRange(byte[] data, int from, int to) + { + int newLength = GetLength(from, to); + byte[] tmp = new byte[newLength]; + Array.Copy(data, from, tmp, 0, System.Math.Min(newLength, data.Length - from)); + return tmp; + } + + public static int[] CopyOfRange(int[] data, int from, int to) + { + int newLength = GetLength(from, to); + int[] tmp = new int[newLength]; + Array.Copy(data, from, tmp, 0, System.Math.Min(newLength, data.Length - from)); + return tmp; + } + + public static long[] CopyOfRange(long[] data, int from, int to) + { + int newLength = GetLength(from, to); + long[] tmp = new long[newLength]; + Array.Copy(data, from, tmp, 0, System.Math.Min(newLength, data.Length - from)); + return tmp; + } + + public static BigInteger[] CopyOfRange(BigInteger[] data, int from, int to) + { + int newLength = GetLength(from, to); + BigInteger[] tmp = new BigInteger[newLength]; + Array.Copy(data, from, tmp, 0, System.Math.Min(newLength, data.Length - from)); + return tmp; + } + + private static int GetLength(int from, int to) + { + int newLength = to - from; + if (newLength < 0) + throw new ArgumentException(from + " > " + to); + return newLength; + } + + public static byte[] Append(byte[] a, byte b) + { + if (a == null) + return new byte[] { b }; + + int length = a.Length; + byte[] result = new byte[length + 1]; + Array.Copy(a, 0, result, 0, length); + result[length] = b; + return result; + } + + public static short[] Append(short[] a, short b) + { + if (a == null) + return new short[] { b }; + + int length = a.Length; + short[] result = new short[length + 1]; + Array.Copy(a, 0, result, 0, length); + result[length] = b; + return result; + } + + public static int[] Append(int[] a, int b) + { + if (a == null) + return new int[] { b }; + + int length = a.Length; + int[] result = new int[length + 1]; + Array.Copy(a, 0, result, 0, length); + result[length] = b; + return result; + } + + public static byte[] Concatenate(byte[] a, byte[] b) + { + if (a == null) + return Clone(b); + if (b == null) + return Clone(a); + + byte[] rv = new byte[a.Length + b.Length]; + Array.Copy(a, 0, rv, 0, a.Length); + Array.Copy(b, 0, rv, a.Length, b.Length); + return rv; + } + + [CLSCompliantAttribute(false)] + public static ushort[] Concatenate(ushort[] a, ushort[] b) + { + if (a == null) + return Clone(b); + if (b == null) + return Clone(a); + + ushort[] rv = new ushort[a.Length + b.Length]; + Array.Copy(a, 0, rv, 0, a.Length); + Array.Copy(b, 0, rv, a.Length, b.Length); + return rv; + } + + public static byte[] ConcatenateAll(params byte[][] vs) + { + byte[][] nonNull = new byte[vs.Length][]; + int count = 0; + int totalLength = 0; + + for (int i = 0; i < vs.Length; ++i) + { + byte[] v = vs[i]; + if (v != null) + { + nonNull[count++] = v; + totalLength += v.Length; + } + } + + byte[] result = new byte[totalLength]; + int pos = 0; + + for (int j = 0; j < count; ++j) + { + byte[] v = nonNull[j]; + Array.Copy(v, 0, result, pos, v.Length); + pos += v.Length; + } + + return result; + } + + public static int[] Concatenate(int[] a, int[] b) + { + if (a == null) + return Clone(b); + if (b == null) + return Clone(a); + + int[] rv = new int[a.Length + b.Length]; + Array.Copy(a, 0, rv, 0, a.Length); + Array.Copy(b, 0, rv, a.Length, b.Length); + return rv; + } + + public static byte[] Prepend(byte[] a, byte b) + { + if (a == null) + return new byte[] { b }; + + int length = a.Length; + byte[] result = new byte[length + 1]; + Array.Copy(a, 0, result, 1, length); + result[0] = b; + return result; + } + + public static short[] Prepend(short[] a, short b) + { + if (a == null) + return new short[] { b }; + + int length = a.Length; + short[] result = new short[length + 1]; + Array.Copy(a, 0, result, 1, length); + result[0] = b; + return result; + } + + public static int[] Prepend(int[] a, int b) + { + if (a == null) + return new int[] { b }; + + int length = a.Length; + int[] result = new int[length + 1]; + Array.Copy(a, 0, result, 1, length); + result[0] = b; + return result; + } + + public static byte[] Reverse(byte[] a) + { + if (a == null) + return null; + + int p1 = 0, p2 = a.Length; + byte[] result = new byte[p2]; + + while (--p2 >= 0) + { + result[p2] = a[p1++]; + } + + return result; + } + + public static int[] Reverse(int[] a) + { + if (a == null) + return null; + + int p1 = 0, p2 = a.Length; + int[] result = new int[p2]; + + while (--p2 >= 0) + { + result[p2] = a[p1++]; + } + + return result; + } + + public static byte[] ReverseInPlace(byte[] a) + { + if (null == a) + return null; + + int p1 = 0, p2 = a.Length - 1; + while (p1 < p2) + { + byte t1 = a[p1], t2 = a[p2]; + a[p1++] = t2; + a[p2--] = t1; + } + + return a; + } + + public static int[] ReverseInPlace(int[] a) + { + if (null == a) + return null; + + int p1 = 0, p2 = a.Length - 1; + while (p1 < p2) + { + int t1 = a[p1], t2 = a[p2]; + a[p1++] = t2; + a[p2--] = t1; + } + + return a; + } + + public static void Clear(byte[] data) + { + if (null != data) + { + Array.Clear(data, 0, data.Length); + } + } + + public static void Clear(int[] data) + { + if (null != data) + { + Array.Clear(data, 0, data.Length); + } + } + + public static bool IsNullOrContainsNull(object[] array) + { + if (null == array) + return true; + + int count = array.Length; + for (int i = 0; i < count; ++i) + { + if (null == array[i]) + return true; + } + return false; + } + + public static bool IsNullOrEmpty(byte[] array) + { + return null == array || array.Length < 1; + } + + public static bool IsNullOrEmpty(object[] array) + { + return null == array || array.Length < 1; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/Arrays.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/Arrays.cs.meta new file mode 100644 index 0000000..7fccf30 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/Arrays.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: de84375c47ddc844989e507b9eab9567 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/BigIntegers.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/BigIntegers.cs new file mode 100644 index 0000000..d9c8986 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/BigIntegers.cs @@ -0,0 +1,189 @@ +using System; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.Raw; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Utilities +{ + /** + * BigInteger utilities. + */ + public abstract class BigIntegers + { + public static readonly BigInteger Zero = BigInteger.Zero; + public static readonly BigInteger One = BigInteger.One; + + private const int MaxIterations = 1000; + + /** + * Return the passed in value as an unsigned byte array. + * + * @param value the value to be converted. + * @return a byte array without a leading zero byte if present in the signed encoding. + */ + public static byte[] AsUnsignedByteArray( + BigInteger n) + { + return n.ToByteArrayUnsigned(); + } + + /** + * Return the passed in value as an unsigned byte array of the specified length, padded with + * leading zeros as necessary. + * @param length the fixed length of the result. + * @param n the value to be converted. + * @return a byte array padded to a fixed length with leading zeros. + */ + public static byte[] AsUnsignedByteArray(int length, BigInteger n) + { + byte[] bytes = n.ToByteArrayUnsigned(); + + if (bytes.Length > length) + throw new ArgumentException("standard length exceeded", "n"); + + if (bytes.Length == length) + return bytes; + + byte[] tmp = new byte[length]; + Array.Copy(bytes, 0, tmp, tmp.Length - bytes.Length, bytes.Length); + return tmp; + } + + /** + * Write the passed in value as unsigned bytes to the specified buffer range, padded with + * leading zeros as necessary. + * + * @param value + * the value to be converted. + * @param buf + * the buffer to which the value is written. + * @param off + * the start offset in array buf at which the data is written. + * @param len + * the fixed length of data written (possibly padded with leading zeros). + */ + public static void AsUnsignedByteArray(BigInteger value, byte[] buf, int off, int len) + { + byte[] bytes = value.ToByteArrayUnsigned(); + if (bytes.Length == len) + { + Array.Copy(bytes, 0, buf, off, len); + return; + } + + int start = bytes[0] == 0 ? 1 : 0; + int count = bytes.Length - start; + + if (count > len) + throw new ArgumentException("standard length exceeded for value"); + + int padLen = len - count; + Arrays.Fill(buf, off, off + padLen, 0); + Array.Copy(bytes, start, buf, off + padLen, count); + } + + /// + /// Creates a Random BigInteger from the secure random of a given bit length. + /// + /// + /// + /// + public static BigInteger CreateRandomBigInteger(int bitLength, SecureRandom secureRandom) + { + return new BigInteger(bitLength, secureRandom); + } + + /** + * Return a random BigInteger not less than 'min' and not greater than 'max' + * + * @param min the least value that may be generated + * @param max the greatest value that may be generated + * @param random the source of randomness + * @return a random BigInteger value in the range [min,max] + */ + public static BigInteger CreateRandomInRange( + BigInteger min, + BigInteger max, + // TODO Should have been just Random class + SecureRandom random) + { + int cmp = min.CompareTo(max); + if (cmp >= 0) + { + if (cmp > 0) + throw new ArgumentException("'min' may not be greater than 'max'"); + + return min; + } + + if (min.BitLength > max.BitLength / 2) + { + return CreateRandomInRange(BigInteger.Zero, max.Subtract(min), random).Add(min); + } + + for (int i = 0; i < MaxIterations; ++i) + { + BigInteger x = new BigInteger(max.BitLength, random); + if (x.CompareTo(min) >= 0 && x.CompareTo(max) <= 0) + { + return x; + } + } + + // fall back to a faster (restricted) method + return new BigInteger(max.Subtract(min).BitLength - 1, random).Add(min); + } + + public static BigInteger ModOddInverse(BigInteger M, BigInteger X) + { + if (!M.TestBit(0)) + throw new ArgumentException("must be odd", "M"); + if (M.SignValue != 1) + throw new ArithmeticException("BigInteger: modulus not positive"); + if (X.SignValue < 0 || X.CompareTo(M) >= 0) + { + X = X.Mod(M); + } + + int bits = M.BitLength; + uint[] m = Nat.FromBigInteger(bits, M); + uint[] x = Nat.FromBigInteger(bits, X); + int len = m.Length; + uint[] z = Nat.Create(len); + if (0 == Mod.ModOddInverse(m, x, z)) + throw new ArithmeticException("BigInteger not invertible"); + return Nat.ToBigInteger(len, z); + } + + public static BigInteger ModOddInverseVar(BigInteger M, BigInteger X) + { + if (!M.TestBit(0)) + throw new ArgumentException("must be odd", "M"); + if (M.SignValue != 1) + throw new ArithmeticException("BigInteger: modulus not positive"); + if (M.Equals(One)) + return Zero; + if (X.SignValue < 0 || X.CompareTo(M) >= 0) + { + X = X.Mod(M); + } + if (X.Equals(One)) + return One; + + int bits = M.BitLength; + uint[] m = Nat.FromBigInteger(bits, M); + uint[] x = Nat.FromBigInteger(bits, X); + int len = m.Length; + uint[] z = Nat.Create(len); + if (!Mod.ModOddInverseVar(m, x, z)) + throw new ArithmeticException("BigInteger not invertible"); + return Nat.ToBigInteger(len, z); + } + + public static int GetUnsignedByteLength(BigInteger n) + { + return (n.BitLength + 7) / 8; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/BigIntegers.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/BigIntegers.cs.meta new file mode 100644 index 0000000..d6c619a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/BigIntegers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a0d6c4e493b3c124389b9c579854c5fd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/Bytes.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/Bytes.cs new file mode 100644 index 0000000..ecde85d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/Bytes.cs @@ -0,0 +1,10 @@ +using System; + +namespace Org.BouncyCastle.Utilities +{ + public abstract class Bytes + { + public const int NumBits = 8; + public const int NumBytes = 1; + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/Bytes.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/Bytes.cs.meta new file mode 100644 index 0000000..039ce81 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/Bytes.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2efe4ad864f1db34c8c50a6f1335370b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/Enums.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/Enums.cs new file mode 100644 index 0000000..9e908c4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/Enums.cs @@ -0,0 +1,78 @@ +using System; +using System.Text; + +#if NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE +using System.Collections; +using System.Reflection; +#endif + +using Org.BouncyCastle.Utilities.Date; + +namespace Org.BouncyCastle.Utilities +{ + internal abstract class Enums + { + internal static Enum GetEnumValue(System.Type enumType, string s) + { + if (!IsEnumType(enumType)) + throw new ArgumentException("Not an enumeration type", "enumType"); + + // We only want to parse single named constants + if (s.Length > 0 && char.IsLetter(s[0]) && s.IndexOf(',') < 0) + { + s = s.Replace('-', '_'); + s = s.Replace('/', '_'); + +#if NETCF_1_0 + FieldInfo field = enumType.GetField(s, BindingFlags.Static | BindingFlags.Public); + if (field != null) + { + return (Enum)field.GetValue(null); + } +#else + return (Enum)Enum.Parse(enumType, s, false); +#endif + } + + throw new ArgumentException(); + } + + internal static Array GetEnumValues(System.Type enumType) + { + if (!IsEnumType(enumType)) + throw new ArgumentException("Not an enumeration type", "enumType"); + +#if NETCF_1_0 || NETCF_2_0 || SILVERLIGHT + IList result = Platform.CreateArrayList(); + FieldInfo[] fields = enumType.GetFields(BindingFlags.Static | BindingFlags.Public); + foreach (FieldInfo field in fields) + { + // Note: Argument to GetValue() ignored since the fields are static, + // but Silverlight for Windows Phone throws exception if we pass null + result.Add(field.GetValue(enumType)); + } + object[] arr = new object[result.Count]; + result.CopyTo(arr, 0); + return arr; +#else + return Enum.GetValues(enumType); +#endif + } + + internal static Enum GetArbitraryValue(System.Type enumType) + { + Array values = GetEnumValues(enumType); + int pos = (int)(DateTimeUtilities.CurrentUnixMs() & int.MaxValue) % values.Length; + return (Enum)values.GetValue(pos); + } + + internal static bool IsEnumType(System.Type t) + { +#if NEW_REFLECTION + return t.GetTypeInfo().IsEnum; +#else + return t.IsEnum; +#endif + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/Enums.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/Enums.cs.meta new file mode 100644 index 0000000..4aca744 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/Enums.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e1263fc38e6db824aba9c4cdd6eda61d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/IMemoable.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/IMemoable.cs new file mode 100644 index 0000000..cc8a2e5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/IMemoable.cs @@ -0,0 +1,29 @@ +using System; + +namespace Org.BouncyCastle.Utilities +{ + public interface IMemoable + { + /// + /// Produce a copy of this object with its configuration and in its current state. + /// + /// + /// The returned object may be used simply to store the state, or may be used as a similar object + /// starting from the copied state. + /// + IMemoable Copy(); + + /// + /// Restore a copied object state into this object. + /// + /// + /// Implementations of this method should try to avoid or minimise memory allocation to perform the reset. + /// + /// an object originally {@link #copy() copied} from an object of the same type as this instance. + /// if the provided object is not of the correct type. + /// if the other parameter is in some other way invalid. + void Reset(IMemoable other); + } + +} + diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/IMemoable.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/IMemoable.cs.meta new file mode 100644 index 0000000..3bcb807 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/IMemoable.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a0da64bc1ab125547947e32b8517cb1f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/Integers.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/Integers.cs new file mode 100644 index 0000000..efa437e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/Integers.cs @@ -0,0 +1,86 @@ +using System; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Utilities +{ + public abstract class Integers + { + public const int NumBits = 32; + public const int NumBytes = 4; + + private static readonly byte[] DeBruijnTZ = { + 0x1F, 0x00, 0x1B, 0x01, 0x1C, 0x0D, 0x17, 0x02, 0x1D, 0x15, 0x13, 0x0E, 0x18, 0x10, 0x03, 0x07, + 0x1E, 0x1A, 0x0C, 0x16, 0x14, 0x12, 0x0F, 0x06, 0x19, 0x0B, 0x11, 0x05, 0x0A, 0x04, 0x09, 0x08 }; + + public static int NumberOfLeadingZeros(int i) + { + if (i <= 0) + return (~i >> (31 - 5)) & (1 << 5); + + uint u = (uint)i; + int n = 1; + if (0 == (u >> 16)) { n += 16; u <<= 16; } + if (0 == (u >> 24)) { n += 8; u <<= 8; } + if (0 == (u >> 28)) { n += 4; u <<= 4; } + if (0 == (u >> 30)) { n += 2; u <<= 2; } + n -= (int)(u >> 31); + return n; + } + + public static int NumberOfTrailingZeros(int i) + { + int n = DeBruijnTZ[(uint)((i & -i) * 0x0EF96A62) >> 27]; + int m = (((i & 0xFFFF) | (int)((uint)i >> 16)) - 1) >> 31; + return n - m; + } + + public static int Reverse(int i) + { + return (int)Reverse((uint)i); + } + + [CLSCompliantAttribute(false)] + public static uint Reverse(uint i) + { + i = Bits.BitPermuteStepSimple(i, 0x55555555U, 1); + i = Bits.BitPermuteStepSimple(i, 0x33333333U, 2); + i = Bits.BitPermuteStepSimple(i, 0x0F0F0F0FU, 4); + return ReverseBytes(i); + } + + public static int ReverseBytes(int i) + { + return (int)ReverseBytes((uint)i); + } + + [CLSCompliantAttribute(false)] + public static uint ReverseBytes(uint i) + { + return RotateLeft(i & 0xFF00FF00U, 8) | + RotateLeft(i & 0x00FF00FFU, 24); + } + + public static int RotateLeft(int i, int distance) + { + return (i << distance) ^ (int)((uint)i >> -distance); + } + + [CLSCompliantAttribute(false)] + public static uint RotateLeft(uint i, int distance) + { + return (i << distance) ^ (i >> -distance); + } + + public static int RotateRight(int i, int distance) + { + return (int)((uint)i >> distance) ^ (i << -distance); + } + + [CLSCompliantAttribute(false)] + public static uint RotateRight(uint i, int distance) + { + return (i >> distance) ^ (i << -distance); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/Integers.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/Integers.cs.meta new file mode 100644 index 0000000..de55efd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/Integers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 88d954f035472e14a95bd6d064e52a4a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/Longs.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/Longs.cs new file mode 100644 index 0000000..4d675bd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/Longs.cs @@ -0,0 +1,86 @@ +using System; + +using Org.BouncyCastle.Math.Raw; + +namespace Org.BouncyCastle.Utilities +{ + public abstract class Longs + { + public const int NumBits = 64; + public const int NumBytes = 8; + + private static readonly byte[] DeBruijnTZ = { + 0x3F, 0x00, 0x01, 0x34, 0x02, 0x06, 0x35, 0x1A, 0x03, 0x25, 0x28, 0x07, 0x21, 0x36, 0x2F, 0x1B, + 0x3D, 0x04, 0x26, 0x2D, 0x2B, 0x29, 0x15, 0x08, 0x17, 0x22, 0x3A, 0x37, 0x30, 0x11, 0x1C, 0x0A, + 0x3E, 0x33, 0x05, 0x19, 0x24, 0x27, 0x20, 0x2E, 0x3C, 0x2C, 0x2A, 0x14, 0x16, 0x39, 0x10, 0x09, + 0x32, 0x18, 0x23, 0x1F, 0x3B, 0x13, 0x38, 0x0F, 0x31, 0x1E, 0x12, 0x0E, 0x1D, 0x0D, 0x0C, 0x0B }; + + public static int NumberOfLeadingZeros(long i) + { + int x = (int)(i >> 32), n = 0; + if (x == 0) + { + n = 32; + x = (int)i; + } + return n + Integers.NumberOfLeadingZeros(x); + } + + public static int NumberOfTrailingZeros(long i) + { + int n = DeBruijnTZ[(uint)((ulong)((i & -i) * 0x045FBAC7992A70DAL) >> 58)]; + long m = (((i & 0xFFFFFFFFL) | (long)((ulong)i >> 32)) - 1L) >> 63; + return n - (int)m; + } + + public static long Reverse(long i) + { + return (long)Reverse((ulong)i); + } + + [CLSCompliantAttribute(false)] + public static ulong Reverse(ulong i) + { + i = Bits.BitPermuteStepSimple(i, 0x5555555555555555UL, 1); + i = Bits.BitPermuteStepSimple(i, 0x3333333333333333UL, 2); + i = Bits.BitPermuteStepSimple(i, 0x0F0F0F0F0F0F0F0FUL, 4); + return ReverseBytes(i); + } + + public static long ReverseBytes(long i) + { + return (long)ReverseBytes((ulong)i); + } + + [CLSCompliantAttribute(false)] + public static ulong ReverseBytes(ulong i) + { + return RotateLeft(i & 0xFF000000FF000000UL, 8) | + RotateLeft(i & 0x00FF000000FF0000UL, 24) | + RotateLeft(i & 0x0000FF000000FF00UL, 40) | + RotateLeft(i & 0x000000FF000000FFUL, 56); + } + + public static long RotateLeft(long i, int distance) + { + return (i << distance) ^ (long)((ulong)i >> -distance); + } + + [CLSCompliantAttribute(false)] + public static ulong RotateLeft(ulong i, int distance) + { + return (i << distance) ^ (i >> -distance); + } + + public static long RotateRight(long i, int distance) + { + return (long)((ulong)i >> distance) ^ (i << -distance); + } + + [CLSCompliantAttribute(false)] + public static ulong RotateRight(ulong i, int distance) + { + return (i >> distance) ^ (i << -distance); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/Longs.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/Longs.cs.meta new file mode 100644 index 0000000..4976c29 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/Longs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a4122f9185b1f4c46a7ecd3dd279925b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/MemoableResetException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/MemoableResetException.cs new file mode 100644 index 0000000..99554f6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/MemoableResetException.cs @@ -0,0 +1,27 @@ +using System; + +namespace Org.BouncyCastle.Utilities +{ + /** + * Exception to be thrown on a failure to reset an object implementing Memoable. + *

    + * The exception extends InvalidCastException to enable users to have a single handling case, + * only introducing specific handling of this one if required. + *

    + */ + public class MemoableResetException + : InvalidCastException + { + /** + * Basic Constructor. + * + * @param msg message to be associated with this exception. + */ + public MemoableResetException(string msg) + : base(msg) + { + } + } + +} + diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/MemoableResetException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/MemoableResetException.cs.meta new file mode 100644 index 0000000..b304f9b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/MemoableResetException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dd2a4f075e26fb44a902993658618e2f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/Platform.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/Platform.cs new file mode 100644 index 0000000..6f7a8b1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/Platform.cs @@ -0,0 +1,229 @@ +using System; +using System.Globalization; +using System.IO; +using System.Text; + +#if SILVERLIGHT || PORTABLE +using System.Collections.Generic; +#else +using System.Collections; +#endif + +namespace Org.BouncyCastle.Utilities +{ + internal abstract class Platform + { + private static readonly CompareInfo InvariantCompareInfo = CultureInfo.InvariantCulture.CompareInfo; + +#if NETCF_1_0 || NETCF_2_0 + private static string GetNewLine() + { + MemoryStream buf = new MemoryStream(); + StreamWriter w = new StreamWriter(buf, Encoding.UTF8); + w.WriteLine(); + Dispose(w); + byte[] bs = buf.ToArray(); + return Encoding.UTF8.GetString(bs, 0, bs.Length); + } +#else + private static string GetNewLine() + { + return Environment.NewLine; + } +#endif + + internal static bool EqualsIgnoreCase(string a, string b) + { +#if PORTABLE + return String.Equals(a, b, StringComparison.OrdinalIgnoreCase); +#else + return ToUpperInvariant(a) == ToUpperInvariant(b); +#endif + } + +#if NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || (PORTABLE && !DOTNET) + internal static string GetEnvironmentVariable( + string variable) + { + return null; + } +#else + internal static string GetEnvironmentVariable( + string variable) + { + try + { + return Environment.GetEnvironmentVariable(variable); + } + catch (System.Security.SecurityException) + { + // We don't have the required permission to read this environment variable, + // which is fine, just act as if it's not set + return null; + } + } +#endif + +#if NETCF_1_0 + internal static Exception CreateNotImplementedException( + string message) + { + return new Exception("Not implemented: " + message); + } + + internal static bool Equals( + object a, + object b) + { + return a == b || (a != null && b != null && a.Equals(b)); + } +#else + internal static Exception CreateNotImplementedException( + string message) + { + return new NotImplementedException(message); + } +#endif + +#if SILVERLIGHT || PORTABLE + internal static System.Collections.IList CreateArrayList() + { + return new List(); + } + internal static System.Collections.IList CreateArrayList(int capacity) + { + return new List(capacity); + } + internal static System.Collections.IList CreateArrayList(System.Collections.ICollection collection) + { + System.Collections.IList result = new List(collection.Count); + foreach (object o in collection) + { + result.Add(o); + } + return result; + } + internal static System.Collections.IList CreateArrayList(System.Collections.IEnumerable collection) + { + System.Collections.IList result = new List(); + foreach (object o in collection) + { + result.Add(o); + } + return result; + } + internal static System.Collections.IDictionary CreateHashtable() + { + return new Dictionary(); + } + internal static System.Collections.IDictionary CreateHashtable(int capacity) + { + return new Dictionary(capacity); + } + internal static System.Collections.IDictionary CreateHashtable(System.Collections.IDictionary dictionary) + { + System.Collections.IDictionary result = new Dictionary(dictionary.Count); + foreach (System.Collections.DictionaryEntry entry in dictionary) + { + result.Add(entry.Key, entry.Value); + } + return result; + } +#else + internal static System.Collections.IList CreateArrayList() + { + return new ArrayList(); + } + internal static System.Collections.IList CreateArrayList(int capacity) + { + return new ArrayList(capacity); + } + internal static System.Collections.IList CreateArrayList(System.Collections.ICollection collection) + { + return new ArrayList(collection); + } + internal static System.Collections.IList CreateArrayList(System.Collections.IEnumerable collection) + { + ArrayList result = new ArrayList(); + foreach (object o in collection) + { + result.Add(o); + } + return result; + } + internal static System.Collections.IDictionary CreateHashtable() + { + return new Hashtable(); + } + internal static System.Collections.IDictionary CreateHashtable(int capacity) + { + return new Hashtable(capacity); + } + internal static System.Collections.IDictionary CreateHashtable(System.Collections.IDictionary dictionary) + { + return new Hashtable(dictionary); + } +#endif + + internal static string ToLowerInvariant(string s) + { +#if PORTABLE + return s.ToLowerInvariant(); +#else + return s.ToLower(CultureInfo.InvariantCulture); +#endif + } + + internal static string ToUpperInvariant(string s) + { +#if PORTABLE + return s.ToUpperInvariant(); +#else + return s.ToUpper(CultureInfo.InvariantCulture); +#endif + } + + internal static readonly string NewLine = GetNewLine(); + +#if PORTABLE + internal static void Dispose(IDisposable d) + { + d.Dispose(); + } +#else + internal static void Dispose(Stream s) + { + s.Close(); + } + internal static void Dispose(TextWriter t) + { + t.Close(); + } +#endif + + internal static int IndexOf(string source, string value) + { + return InvariantCompareInfo.IndexOf(source, value, CompareOptions.Ordinal); + } + + internal static int LastIndexOf(string source, string value) + { + return InvariantCompareInfo.LastIndexOf(source, value, CompareOptions.Ordinal); + } + + internal static bool StartsWith(string source, string prefix) + { + return InvariantCompareInfo.IsPrefix(source, prefix, CompareOptions.Ordinal); + } + + internal static bool EndsWith(string source, string suffix) + { + return InvariantCompareInfo.IsSuffix(source, suffix, CompareOptions.Ordinal); + } + + internal static string GetTypeName(object obj) + { + return obj.GetType().FullName; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/Platform.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/Platform.cs.meta new file mode 100644 index 0000000..ed6426b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/Platform.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2ec660ed815704847be745b60364c4ef +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/Strings.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/Strings.cs new file mode 100644 index 0000000..73a15ea --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/Strings.cs @@ -0,0 +1,128 @@ +using System; +using System.Text; + +namespace Org.BouncyCastle.Utilities +{ + /// General string utilities. + public abstract class Strings + { + + public static string ToUpperCase(string original) + { + bool changed = false; + char[] chars = original.ToCharArray(); + + for (int i = 0; i != chars.Length; i++) + { + char ch = chars[i]; + if ('a' <= ch && 'z' >= ch) + { + changed = true; + chars[i] = (char)(ch - 'a' + 'A'); + } + } + + if (changed) + { + return new String(chars); + } + + return original; + } + + + internal static bool IsOneOf(string s, params string[] candidates) + { + foreach (string candidate in candidates) + { + if (s == candidate) + return true; + } + return false; + } + + public static string FromByteArray( + byte[] bs) + { + char[] cs = new char[bs.Length]; + for (int i = 0; i < cs.Length; ++i) + { + cs[i] = Convert.ToChar(bs[i]); + } + return new string(cs); + } + + public static byte[] ToByteArray( + char[] cs) + { + byte[] bs = new byte[cs.Length]; + for (int i = 0; i < bs.Length; ++i) + { + bs[i] = Convert.ToByte(cs[i]); + } + return bs; + } + + public static byte[] ToByteArray( + string s) + { + byte[] bs = new byte[s.Length]; + for (int i = 0; i < bs.Length; ++i) + { + bs[i] = Convert.ToByte(s[i]); + } + return bs; + } + + public static string FromAsciiByteArray( + byte[] bytes) + { +#if SILVERLIGHT || PORTABLE + // TODO Check for non-ASCII bytes in input? + return Encoding.UTF8.GetString(bytes, 0, bytes.Length); +#else + return Encoding.ASCII.GetString(bytes, 0, bytes.Length); +#endif + } + + public static byte[] ToAsciiByteArray( + char[] cs) + { +#if SILVERLIGHT || PORTABLE + // TODO Check for non-ASCII characters in input? + return Encoding.UTF8.GetBytes(cs); +#else + return Encoding.ASCII.GetBytes(cs); +#endif + } + + public static byte[] ToAsciiByteArray( + string s) + { +#if SILVERLIGHT || PORTABLE + // TODO Check for non-ASCII characters in input? + return Encoding.UTF8.GetBytes(s); +#else + return Encoding.ASCII.GetBytes(s); +#endif + } + + public static string FromUtf8ByteArray( + byte[] bytes) + { + return Encoding.UTF8.GetString(bytes, 0, bytes.Length); + } + + public static byte[] ToUtf8ByteArray( + char[] cs) + { + return Encoding.UTF8.GetBytes(cs); + } + + public static byte[] ToUtf8ByteArray( + string s) + { + return Encoding.UTF8.GetBytes(s); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/Strings.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/Strings.cs.meta new file mode 100644 index 0000000..992d34b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/Strings.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a6adc903344e8d342839286fa13d563e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/Times.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/Times.cs new file mode 100644 index 0000000..99a78d2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/Times.cs @@ -0,0 +1,14 @@ +using System; + +namespace Org.BouncyCastle.Utilities +{ + public sealed class Times + { + private static long NanosecondsPerTick = 100L; + + public static long NanoTime() + { + return DateTime.UtcNow.Ticks * NanosecondsPerTick; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/Times.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/Times.cs.meta new file mode 100644 index 0000000..5f7b6b7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/Times.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 59eef28370a346b40b4a6f86f58ec819 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/TypeExtensions.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/TypeExtensions.cs new file mode 100644 index 0000000..e2aeae4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/TypeExtensions.cs @@ -0,0 +1,17 @@ +#if NEW_REFLECTION + +using System; +using System.Reflection; + +namespace Org.BouncyCastle +{ + internal static class TypeExtensions + { + public static bool IsInstanceOfType(this Type type, object instance) + { + return instance != null && type.GetTypeInfo().IsAssignableFrom(instance.GetType().GetTypeInfo()); + } + } +} + +#endif diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/TypeExtensions.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/TypeExtensions.cs.meta new file mode 100644 index 0000000..0893eeb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/TypeExtensions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 58bab5fa23f783248a95e55f13da97b7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections.meta new file mode 100644 index 0000000..6d1fa1f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 47fe57f5975351e44868e6b7abc7358b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/CollectionUtilities.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/CollectionUtilities.cs new file mode 100644 index 0000000..e0c79bd --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/CollectionUtilities.cs @@ -0,0 +1,67 @@ +using System; +using System.Collections; +using System.Text; + +namespace Org.BouncyCastle.Utilities.Collections +{ + public abstract class CollectionUtilities + { + public static void AddRange(IList to, IEnumerable range) + { + foreach (object o in range) + { + to.Add(o); + } + } + + public static bool CheckElementsAreOfType(IEnumerable e, Type t) + { + foreach (object o in e) + { + if (!t.IsInstanceOfType(o)) + return false; + } + return true; + } + + public static IDictionary ReadOnly(IDictionary d) + { + return new UnmodifiableDictionaryProxy(d); + } + + public static IList ReadOnly(IList l) + { + return new UnmodifiableListProxy(l); + } + + public static ISet ReadOnly(ISet s) + { + return new UnmodifiableSetProxy(s); + } + + public static object RequireNext(IEnumerator e) + { + if (!e.MoveNext()) + throw new InvalidOperationException(); + + return e.Current; + } + + public static string ToString(IEnumerable c) + { + IEnumerator e = c.GetEnumerator(); + if (!e.MoveNext()) + return "[]"; + + StringBuilder sb = new StringBuilder("["); + sb.Append(e.Current.ToString()); + while (e.MoveNext()) + { + sb.Append(", "); + sb.Append(e.Current.ToString()); + } + sb.Append(']'); + return sb.ToString(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/CollectionUtilities.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/CollectionUtilities.cs.meta new file mode 100644 index 0000000..8aa7bf2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/CollectionUtilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1a9731ddaccd8ad4486c11207b25edc8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/EmptyEnumerable.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/EmptyEnumerable.cs new file mode 100644 index 0000000..a61a078 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/EmptyEnumerable.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections; + +namespace Org.BouncyCastle.Utilities.Collections +{ + public sealed class EmptyEnumerable + : IEnumerable + { + public static readonly IEnumerable Instance = new EmptyEnumerable(); + + private EmptyEnumerable() + { + } + + public IEnumerator GetEnumerator() + { + return EmptyEnumerator.Instance; + } + } + + public sealed class EmptyEnumerator + : IEnumerator + { + public static readonly IEnumerator Instance = new EmptyEnumerator(); + + private EmptyEnumerator() + { + } + + public bool MoveNext() + { + return false; + } + + public void Reset() + { + } + + public object Current + { + get { throw new InvalidOperationException("No elements"); } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/EmptyEnumerable.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/EmptyEnumerable.cs.meta new file mode 100644 index 0000000..50d442d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/EmptyEnumerable.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fa6dc4a47361ea2438349cce8701b527 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/EnumerableProxy.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/EnumerableProxy.cs new file mode 100644 index 0000000..9eec4af --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/EnumerableProxy.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections; + +namespace Org.BouncyCastle.Utilities.Collections +{ + public sealed class EnumerableProxy + : IEnumerable + { + private readonly IEnumerable inner; + + public EnumerableProxy( + IEnumerable inner) + { + if (inner == null) + throw new ArgumentNullException("inner"); + + this.inner = inner; + } + + public IEnumerator GetEnumerator() + { + return inner.GetEnumerator(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/EnumerableProxy.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/EnumerableProxy.cs.meta new file mode 100644 index 0000000..8f6b8cf --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/EnumerableProxy.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7aef054429df5dd40a81aa69d4ff8265 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/HashSet.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/HashSet.cs new file mode 100644 index 0000000..1facb58 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/HashSet.cs @@ -0,0 +1,99 @@ +using System; +using System.Collections; + +namespace Org.BouncyCastle.Utilities.Collections +{ + public class HashSet + : ISet + { + private readonly IDictionary impl = Platform.CreateHashtable(); + + public HashSet() + { + } + + public HashSet(IEnumerable s) + { + foreach (object o in s) + { + Add(o); + } + } + + public virtual void Add(object o) + { + impl[o] = null; + } + + public virtual void AddAll(IEnumerable e) + { + foreach (object o in e) + { + Add(o); + } + } + + public virtual void Clear() + { + impl.Clear(); + } + + public virtual bool Contains(object o) + { + return impl.Contains(o); + } + + public virtual void CopyTo(Array array, int index) + { + impl.Keys.CopyTo(array, index); + } + + public virtual int Count + { + get { return impl.Count; } + } + + public virtual IEnumerator GetEnumerator() + { + return impl.Keys.GetEnumerator(); + } + + public virtual bool IsEmpty + { + get { return impl.Count == 0; } + } + + public virtual bool IsFixedSize + { + get { return impl.IsFixedSize; } + } + + public virtual bool IsReadOnly + { + get { return impl.IsReadOnly; } + } + + public virtual bool IsSynchronized + { + get { return impl.IsSynchronized; } + } + + public virtual void Remove(object o) + { + impl.Remove(o); + } + + public virtual void RemoveAll(IEnumerable e) + { + foreach (object o in e) + { + Remove(o); + } + } + + public virtual object SyncRoot + { + get { return impl.SyncRoot; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/HashSet.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/HashSet.cs.meta new file mode 100644 index 0000000..ed2dc1a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/HashSet.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d16357b430defab489f729415decc890 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/ISet.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/ISet.cs new file mode 100644 index 0000000..1f8edba --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/ISet.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections; + +namespace Org.BouncyCastle.Utilities.Collections +{ + public interface ISet + : ICollection + { + void Add(object o); + void AddAll(IEnumerable e); + void Clear(); + bool Contains(object o); + bool IsEmpty { get; } + bool IsFixedSize { get; } + bool IsReadOnly { get; } + void Remove(object o); + void RemoveAll(IEnumerable e); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/ISet.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/ISet.cs.meta new file mode 100644 index 0000000..13a1917 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/ISet.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 722aaaf7d92a5314ab118ade420c3a96 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/LinkedDictionary.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/LinkedDictionary.cs new file mode 100644 index 0000000..933d38d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/LinkedDictionary.cs @@ -0,0 +1,178 @@ +using System; +using System.Collections; + +namespace Org.BouncyCastle.Utilities.Collections +{ + public class LinkedDictionary + : IDictionary + { + internal readonly IDictionary hash = Platform.CreateHashtable(); + internal readonly IList keys = Platform.CreateArrayList(); + + public LinkedDictionary() + { + } + + public virtual void Add(object k, object v) + { + hash.Add(k, v); + keys.Add(k); + } + + public virtual void Clear() + { + hash.Clear(); + keys.Clear(); + } + + public virtual bool Contains(object k) + { + return hash.Contains(k); + } + + public virtual void CopyTo(Array array, int index) + { + foreach (object k in keys) + { + array.SetValue(hash[k], index++); + } + } + + public virtual int Count + { + get { return hash.Count; } + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + public virtual IDictionaryEnumerator GetEnumerator() + { + return new LinkedDictionaryEnumerator(this); + } + + public virtual void Remove(object k) + { + hash.Remove(k); + keys.Remove(k); + } + + public virtual bool IsFixedSize + { + get { return false; } + } + + public virtual bool IsReadOnly + { + get { return false; } + } + + public virtual bool IsSynchronized + { + get { return false; } + } + + public virtual object SyncRoot + { + get { return false; } + } + + public virtual ICollection Keys + { + get { return Platform.CreateArrayList(keys); } + } + + public virtual ICollection Values + { + // NB: Order has to be the same as for Keys property + get + { + IList values = Platform.CreateArrayList(keys.Count); + foreach (object k in keys) + { + values.Add(hash[k]); + } + return values; + } + } + + public virtual object this[object k] + { + get + { + return hash[k]; + } + set + { + if (!hash.Contains(k)) + keys.Add(k); + hash[k] = value; + } + } + } + + internal class LinkedDictionaryEnumerator : IDictionaryEnumerator + { + private readonly LinkedDictionary parent; + private int pos = -1; + + internal LinkedDictionaryEnumerator(LinkedDictionary parent) + { + this.parent = parent; + } + + public virtual object Current + { + get { return Entry; } + } + + public virtual DictionaryEntry Entry + { + get + { + object k = CurrentKey; + return new DictionaryEntry(k, parent.hash[k]); + } + } + + public virtual object Key + { + get + { + return CurrentKey; + } + } + + public virtual bool MoveNext() + { + if (pos >= parent.keys.Count) + return false; + return ++pos < parent.keys.Count; + } + + public virtual void Reset() + { + this.pos = -1; + } + + public virtual object Value + { + get + { + return parent.hash[CurrentKey]; + } + } + + private object CurrentKey + { + get + { + if (pos < 0 || pos >= parent.keys.Count) + throw new InvalidOperationException(); + return parent.keys[pos]; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/LinkedDictionary.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/LinkedDictionary.cs.meta new file mode 100644 index 0000000..ae16ecb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/LinkedDictionary.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f7e1e62c5c9f62c46aefff71a88486c5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/UnmodifiableDictionary.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/UnmodifiableDictionary.cs new file mode 100644 index 0000000..0bdf70a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/UnmodifiableDictionary.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections; + +namespace Org.BouncyCastle.Utilities.Collections +{ + public abstract class UnmodifiableDictionary + : IDictionary + { + protected UnmodifiableDictionary() + { + } + + public virtual void Add(object k, object v) + { + throw new NotSupportedException(); + } + + public virtual void Clear() + { + throw new NotSupportedException(); + } + + public abstract bool Contains(object k); + + public abstract void CopyTo(Array array, int index); + + public abstract int Count { get; } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + public abstract IDictionaryEnumerator GetEnumerator(); + + public virtual void Remove(object k) + { + throw new NotSupportedException(); + } + + public abstract bool IsFixedSize { get; } + + public virtual bool IsReadOnly + { + get { return true; } + } + + public abstract bool IsSynchronized { get; } + + public abstract object SyncRoot { get; } + + public abstract ICollection Keys { get; } + + public abstract ICollection Values { get; } + + public virtual object this[object k] + { + get { return GetValue(k); } + set { throw new NotSupportedException(); } + } + + protected abstract object GetValue(object k); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/UnmodifiableDictionary.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/UnmodifiableDictionary.cs.meta new file mode 100644 index 0000000..94509e7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/UnmodifiableDictionary.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 382526675b25a3342ad3231b35b6eaa8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/UnmodifiableDictionaryProxy.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/UnmodifiableDictionaryProxy.cs new file mode 100644 index 0000000..0fca909 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/UnmodifiableDictionaryProxy.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections; + +namespace Org.BouncyCastle.Utilities.Collections +{ + public class UnmodifiableDictionaryProxy + : UnmodifiableDictionary + { + private readonly IDictionary d; + + public UnmodifiableDictionaryProxy(IDictionary d) + { + this.d = d; + } + + public override bool Contains(object k) + { + return d.Contains(k); + } + + public override void CopyTo(Array array, int index) + { + d.CopyTo(array, index); + } + + public override int Count + { + get { return d.Count; } + } + + public override IDictionaryEnumerator GetEnumerator() + { + return d.GetEnumerator(); + } + + public override bool IsFixedSize + { + get { return d.IsFixedSize; } + } + + public override bool IsSynchronized + { + get { return d.IsSynchronized; } + } + + public override object SyncRoot + { + get { return d.SyncRoot; } + } + + public override ICollection Keys + { + get { return d.Keys; } + } + + public override ICollection Values + { + get { return d.Values; } + } + + protected override object GetValue(object k) + { + return d[k]; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/UnmodifiableDictionaryProxy.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/UnmodifiableDictionaryProxy.cs.meta new file mode 100644 index 0000000..9e9f404 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/UnmodifiableDictionaryProxy.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 52bfe331cded1a845af3c4ce95ac0299 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/UnmodifiableList.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/UnmodifiableList.cs new file mode 100644 index 0000000..28e49ea --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/UnmodifiableList.cs @@ -0,0 +1,67 @@ +using System; +using System.Collections; + +namespace Org.BouncyCastle.Utilities.Collections +{ + public abstract class UnmodifiableList + : IList + { + protected UnmodifiableList() + { + } + + public virtual int Add(object o) + { + throw new NotSupportedException(); + } + + public virtual void Clear() + { + throw new NotSupportedException(); + } + + public abstract bool Contains(object o); + + public abstract void CopyTo(Array array, int index); + + public abstract int Count { get; } + + public abstract IEnumerator GetEnumerator(); + + public abstract int IndexOf(object o); + + public virtual void Insert(int i, object o) + { + throw new NotSupportedException(); + } + + public abstract bool IsFixedSize { get; } + + public virtual bool IsReadOnly + { + get { return true; } + } + + public abstract bool IsSynchronized { get; } + + public virtual void Remove(object o) + { + throw new NotSupportedException(); + } + + public virtual void RemoveAt(int i) + { + throw new NotSupportedException(); + } + + public abstract object SyncRoot { get; } + + public virtual object this[int i] + { + get { return GetValue(i); } + set { throw new NotSupportedException(); } + } + + protected abstract object GetValue(int i); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/UnmodifiableList.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/UnmodifiableList.cs.meta new file mode 100644 index 0000000..21f9a0a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/UnmodifiableList.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dea5ee11e34bfeb4194fc22180d80dad +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/UnmodifiableListProxy.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/UnmodifiableListProxy.cs new file mode 100644 index 0000000..9d00737 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/UnmodifiableListProxy.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections; + +namespace Org.BouncyCastle.Utilities.Collections +{ + public class UnmodifiableListProxy + : UnmodifiableList + { + private readonly IList l; + + public UnmodifiableListProxy(IList l) + { + this.l = l; + } + + public override bool Contains(object o) + { + return l.Contains(o); + } + + public override void CopyTo(Array array, int index) + { + l.CopyTo(array, index); + } + + public override int Count + { + get { return l.Count; } + } + + public override IEnumerator GetEnumerator() + { + return l.GetEnumerator(); + } + + public override int IndexOf(object o) + { + return l.IndexOf(o); + } + + public override bool IsFixedSize + { + get { return l.IsFixedSize; } + } + + public override bool IsSynchronized + { + get { return l.IsSynchronized; } + } + + public override object SyncRoot + { + get { return l.SyncRoot; } + } + + protected override object GetValue(int i) + { + return l[i]; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/UnmodifiableListProxy.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/UnmodifiableListProxy.cs.meta new file mode 100644 index 0000000..3f86ef0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/UnmodifiableListProxy.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 28353f79d2b81154abf7eca6efc6a631 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/UnmodifiableSet.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/UnmodifiableSet.cs new file mode 100644 index 0000000..8792815 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/UnmodifiableSet.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections; + +namespace Org.BouncyCastle.Utilities.Collections +{ + public abstract class UnmodifiableSet + : ISet + { + protected UnmodifiableSet() + { + } + + public virtual void Add(object o) + { + throw new NotSupportedException(); + } + + public virtual void AddAll(IEnumerable e) + { + throw new NotSupportedException(); + } + + public virtual void Clear() + { + throw new NotSupportedException(); + } + + public abstract bool Contains(object o); + + public abstract void CopyTo(Array array, int index); + + public abstract int Count { get; } + + public abstract IEnumerator GetEnumerator(); + + public abstract bool IsEmpty { get; } + + public abstract bool IsFixedSize { get; } + + public virtual bool IsReadOnly + { + get { return true; } + } + + public abstract bool IsSynchronized { get; } + + public abstract object SyncRoot { get; } + + public virtual void Remove(object o) + { + throw new NotSupportedException(); + } + + public virtual void RemoveAll(IEnumerable e) + { + throw new NotSupportedException(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/UnmodifiableSet.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/UnmodifiableSet.cs.meta new file mode 100644 index 0000000..4d9a8ed --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/UnmodifiableSet.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fa91f3405cc2cee43bfdcf62a5407959 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/UnmodifiableSetProxy.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/UnmodifiableSetProxy.cs new file mode 100644 index 0000000..e119e29 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/UnmodifiableSetProxy.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections; + +namespace Org.BouncyCastle.Utilities.Collections +{ + public class UnmodifiableSetProxy + : UnmodifiableSet + { + private readonly ISet s; + + public UnmodifiableSetProxy (ISet s) + { + this.s = s; + } + + public override bool Contains(object o) + { + return s.Contains(o); + } + + public override void CopyTo(Array array, int index) + { + s.CopyTo(array, index); + } + + public override int Count + { + get { return s.Count; } + } + + public override IEnumerator GetEnumerator() + { + return s.GetEnumerator(); + } + + public override bool IsEmpty + { + get { return s.IsEmpty; } + } + + public override bool IsFixedSize + { + get { return s.IsFixedSize; } + } + + public override bool IsSynchronized + { + get { return s.IsSynchronized; } + } + + public override object SyncRoot + { + get { return s.SyncRoot; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/UnmodifiableSetProxy.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/UnmodifiableSetProxy.cs.meta new file mode 100644 index 0000000..188e364 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/collections/UnmodifiableSetProxy.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3769213adc34e124f8a8cc55cd771b66 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/date.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/date.meta new file mode 100644 index 0000000..05e1f62 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/date.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ea8f006cb0b178f4198c76ef0a230a65 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/date/DateTimeObject.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/date/DateTimeObject.cs new file mode 100644 index 0000000..793376b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/date/DateTimeObject.cs @@ -0,0 +1,25 @@ +using System; + +namespace Org.BouncyCastle.Utilities.Date +{ + public sealed class DateTimeObject + { + private readonly DateTime dt; + + public DateTimeObject( + DateTime dt) + { + this.dt = dt; + } + + public DateTime Value + { + get { return dt; } + } + + public override string ToString() + { + return dt.ToString(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/date/DateTimeObject.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/date/DateTimeObject.cs.meta new file mode 100644 index 0000000..8235ba8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/date/DateTimeObject.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 34b89464b3361e246963deff8104781f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/date/DateTimeUtilities.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/date/DateTimeUtilities.cs new file mode 100644 index 0000000..311ad5d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/date/DateTimeUtilities.cs @@ -0,0 +1,47 @@ +using System; + +namespace Org.BouncyCastle.Utilities.Date +{ + public class DateTimeUtilities + { + public static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1); + + private DateTimeUtilities() + { + } + + /// + /// Return the number of milliseconds since the Unix epoch (1 Jan., 1970 UTC) for a given DateTime value. + /// + /// A UTC DateTime value not before epoch. + /// Number of whole milliseconds after epoch. + /// 'dateTime' is before epoch. + public static long DateTimeToUnixMs( + DateTime dateTime) + { + if (dateTime.CompareTo(UnixEpoch) < 0) + throw new ArgumentException("DateTime value may not be before the epoch", "dateTime"); + + return (dateTime.Ticks - UnixEpoch.Ticks) / TimeSpan.TicksPerMillisecond; + } + + /// + /// Create a DateTime value from the number of milliseconds since the Unix epoch (1 Jan., 1970 UTC). + /// + /// Number of milliseconds since the epoch. + /// A UTC DateTime value + public static DateTime UnixMsToDateTime( + long unixMs) + { + return new DateTime(unixMs * TimeSpan.TicksPerMillisecond + UnixEpoch.Ticks); + } + + /// + /// Return the current number of milliseconds since the Unix epoch (1 Jan., 1970 UTC). + /// + public static long CurrentUnixMs() + { + return DateTimeToUnixMs(DateTime.UtcNow); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/date/DateTimeUtilities.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/date/DateTimeUtilities.cs.meta new file mode 100644 index 0000000..33fa5bb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/date/DateTimeUtilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: de12cf62fe12ee84d85eec2091127384 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders.meta new file mode 100644 index 0000000..930a579 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 3aba4605e2658eb47bb847a3f675ffb5 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/Base64.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/Base64.cs new file mode 100644 index 0000000..ccecd8d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/Base64.cs @@ -0,0 +1,120 @@ +using System; +using System.IO; +using System.Text; + +namespace Org.BouncyCastle.Utilities.Encoders +{ + public sealed class Base64 + { + private Base64() + { + } + + public static string ToBase64String( + byte[] data) + { + return Convert.ToBase64String(data, 0, data.Length); + } + + public static string ToBase64String( + byte[] data, + int off, + int length) + { + return Convert.ToBase64String(data, off, length); + } + + /** + * encode the input data producing a base 64 encoded byte array. + * + * @return a byte array containing the base 64 encoded data. + */ + public static byte[] Encode( + byte[] data) + { + return Encode(data, 0, data.Length); + } + + /** + * encode the input data producing a base 64 encoded byte array. + * + * @return a byte array containing the base 64 encoded data. + */ + public static byte[] Encode( + byte[] data, + int off, + int length) + { + string s = Convert.ToBase64String(data, off, length); + return Strings.ToAsciiByteArray(s); + } + + /** + * Encode the byte data to base 64 writing it to the given output stream. + * + * @return the number of bytes produced. + */ + public static int Encode( + byte[] data, + Stream outStream) + { + byte[] encoded = Encode(data); + outStream.Write(encoded, 0, encoded.Length); + return encoded.Length; + } + + /** + * Encode the byte data to base 64 writing it to the given output stream. + * + * @return the number of bytes produced. + */ + public static int Encode( + byte[] data, + int off, + int length, + Stream outStream) + { + byte[] encoded = Encode(data, off, length); + outStream.Write(encoded, 0, encoded.Length); + return encoded.Length; + } + + /** + * decode the base 64 encoded input data. It is assumed the input data is valid. + * + * @return a byte array representing the decoded data. + */ + public static byte[] Decode( + byte[] data) + { + string s = Strings.FromAsciiByteArray(data); + return Convert.FromBase64String(s); + } + + /** + * decode the base 64 encoded string data - whitespace will be ignored. + * + * @return a byte array representing the decoded data. + */ + public static byte[] Decode( + string data) + { + return Convert.FromBase64String(data); + } + + /** + * decode the base 64 encoded string data writing it to the given output stream, + * whitespace characters will be ignored. + * + * @return the number of bytes produced. + */ + public static int Decode( + string data, + Stream outStream) + { + byte[] decoded = Decode(data); + outStream.Write(decoded, 0, decoded.Length); + return decoded.Length; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/Base64.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/Base64.cs.meta new file mode 100644 index 0000000..38d2a93 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/Base64.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 06e7104bf68cc504a9c2d1b587c49de5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/Base64Encoder.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/Base64Encoder.cs new file mode 100644 index 0000000..7ec79ea --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/Base64Encoder.cs @@ -0,0 +1,337 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Utilities.Encoders +{ + public class Base64Encoder + : IEncoder + { + protected readonly byte[] encodingTable = + { + (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G', + (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N', + (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U', + (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z', + (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g', + (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n', + (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u', + (byte)'v', + (byte)'w', (byte)'x', (byte)'y', (byte)'z', + (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', + (byte)'7', (byte)'8', (byte)'9', + (byte)'+', (byte)'/' + }; + + protected byte padding = (byte)'='; + + /* + * set up the decoding table. + */ + protected readonly byte[] decodingTable = new byte[128]; + + protected void InitialiseDecodingTable() + { + Arrays.Fill(decodingTable, (byte)0xff); + + for (int i = 0; i < encodingTable.Length; i++) + { + decodingTable[encodingTable[i]] = (byte)i; + } + } + + public Base64Encoder() + { + InitialiseDecodingTable(); + } + + public int Encode(byte[] inBuf, int inOff, int inLen, byte[] outBuf, int outOff) + { + int inPos = inOff; + int inEnd = inOff + inLen - 2; + int outPos = outOff; + + while (inPos < inEnd) + { + uint a1 = inBuf[inPos++]; + uint a2 = inBuf[inPos++]; + uint a3 = inBuf[inPos++]; + + outBuf[outPos++] = encodingTable[(a1 >> 2) & 0x3F]; + outBuf[outPos++] = encodingTable[((a1 << 4) | (a2 >> 4)) & 0x3F]; + outBuf[outPos++] = encodingTable[((a2 << 2) | (a3 >> 6)) & 0x3F]; + outBuf[outPos++] = encodingTable[a3 & 0x3F]; + } + + switch (inLen - (inPos - inOff)) + { + case 1: + { + uint a1 = inBuf[inPos++]; + + outBuf[outPos++] = encodingTable[(a1 >> 2) & 0x3F]; + outBuf[outPos++] = encodingTable[(a1 << 4) & 0x3F]; + outBuf[outPos++] = padding; + outBuf[outPos++] = padding; + break; + } + case 2: + { + uint a1 = inBuf[inPos++]; + uint a2 = inBuf[inPos++]; + + outBuf[outPos++] = encodingTable[(a1 >> 2) & 0x3F]; + outBuf[outPos++] = encodingTable[((a1 << 4) | (a2 >> 4)) & 0x3F]; + outBuf[outPos++] = encodingTable[(a2 << 2) & 0x3F]; + outBuf[outPos++] = padding; + break; + } + } + + return outPos - outOff; + } + + /** + * encode the input data producing a base 64 output stream. + * + * @return the number of bytes produced. + */ + public int Encode(byte[] buf, int off, int len, Stream outStream) + { + if (len < 0) + return 0; + + byte[] tmp = new byte[72]; + int remaining = len; + while (remaining > 0) + { + int inLen = System.Math.Min(54, remaining); + int outLen = Encode(buf, off, inLen, tmp, 0); + outStream.Write(tmp, 0, outLen); + off += inLen; + remaining -= inLen; + } + return (len + 2) / 3 * 4; + } + + private bool Ignore(char c) + { + return c == '\n' || c =='\r' || c == '\t' || c == ' '; + } + + /** + * decode the base 64 encoded byte data writing it to the given output stream, + * whitespace characters will be ignored. + * + * @return the number of bytes produced. + */ + public int Decode(byte[] data, int off, int length, Stream outStream) + { + byte b1, b2, b3, b4; + byte[] outBuffer = new byte[54]; // S/MIME standard + int bufOff = 0; + int outLen = 0; + int end = off + length; + + while (end > off) + { + if (!Ignore((char)data[end - 1])) + break; + + end--; + } + + int i = off; + int finish = end - 4; + + i = NextI(data, i, finish); + + while (i < finish) + { + b1 = decodingTable[data[i++]]; + + i = NextI(data, i, finish); + + b2 = decodingTable[data[i++]]; + + i = NextI(data, i, finish); + + b3 = decodingTable[data[i++]]; + + i = NextI(data, i, finish); + + b4 = decodingTable[data[i++]]; + + if ((b1 | b2 | b3 | b4) >= 0x80) + throw new IOException("invalid characters encountered in base64 data"); + + outBuffer[bufOff++] = (byte)((b1 << 2) | (b2 >> 4)); + outBuffer[bufOff++] = (byte)((b2 << 4) | (b3 >> 2)); + outBuffer[bufOff++] = (byte)((b3 << 6) | b4); + + if (bufOff == outBuffer.Length) + { + outStream.Write(outBuffer, 0, bufOff); + bufOff = 0; + } + + outLen += 3; + + i = NextI(data, i, finish); + } + + if (bufOff > 0) + { + outStream.Write(outBuffer, 0, bufOff); + } + + int e0 = NextI(data, i, end); + int e1 = NextI(data, e0 + 1, end); + int e2 = NextI(data, e1 + 1, end); + int e3 = NextI(data, e2 + 1, end); + + outLen += DecodeLastBlock(outStream, (char)data[e0], (char)data[e1], (char)data[e2], (char)data[e3]); + + return outLen; + } + + private int NextI( + byte[] data, + int i, + int finish) + { + while ((i < finish) && Ignore((char)data[i])) + { + i++; + } + return i; + } + + /** + * decode the base 64 encoded string data writing it to the given output stream, + * whitespace characters will be ignored. + * + * @return the number of bytes produced. + */ + public int DecodeString(string data, Stream outStream) + { + // Platform Implementation +// byte[] bytes = Convert.FromBase64String(data); +// outStream.Write(bytes, 0, bytes.Length); +// return bytes.Length; + + byte b1, b2, b3, b4; + int length = 0; + + int end = data.Length; + + while (end > 0) + { + if (!Ignore(data[end - 1])) + break; + + end--; + } + + int i = 0; + int finish = end - 4; + + i = NextI(data, i, finish); + + while (i < finish) + { + b1 = decodingTable[data[i++]]; + + i = NextI(data, i, finish); + + b2 = decodingTable[data[i++]]; + + i = NextI(data, i, finish); + + b3 = decodingTable[data[i++]]; + + i = NextI(data, i, finish); + + b4 = decodingTable[data[i++]]; + + if ((b1 | b2 | b3 | b4) >= 0x80) + throw new IOException("invalid characters encountered in base64 data"); + + outStream.WriteByte((byte)((b1 << 2) | (b2 >> 4))); + outStream.WriteByte((byte)((b2 << 4) | (b3 >> 2))); + outStream.WriteByte((byte)((b3 << 6) | b4)); + + length += 3; + + i = NextI(data, i, finish); + } + + length += DecodeLastBlock(outStream, data[end - 4], data[end - 3], data[end - 2], data[end - 1]); + + return length; + } + + private int DecodeLastBlock( + Stream outStream, + char c1, + char c2, + char c3, + char c4) + { + if (c3 == padding) + { + if (c4 != padding) + throw new IOException("invalid characters encountered at end of base64 data"); + + byte b1 = decodingTable[c1]; + byte b2 = decodingTable[c2]; + + if ((b1 | b2) >= 0x80) + throw new IOException("invalid characters encountered at end of base64 data"); + + outStream.WriteByte((byte)((b1 << 2) | (b2 >> 4))); + + return 1; + } + + if (c4 == padding) + { + byte b1 = decodingTable[c1]; + byte b2 = decodingTable[c2]; + byte b3 = decodingTable[c3]; + + if ((b1 | b2 | b3) >= 0x80) + throw new IOException("invalid characters encountered at end of base64 data"); + + outStream.WriteByte((byte)((b1 << 2) | (b2 >> 4))); + outStream.WriteByte((byte)((b2 << 4) | (b3 >> 2))); + + return 2; + } + + { + byte b1 = decodingTable[c1]; + byte b2 = decodingTable[c2]; + byte b3 = decodingTable[c3]; + byte b4 = decodingTable[c4]; + + if ((b1 | b2 | b3 | b4) >= 0x80) + throw new IOException("invalid characters encountered at end of base64 data"); + + outStream.WriteByte((byte)((b1 << 2) | (b2 >> 4))); + outStream.WriteByte((byte)((b2 << 4) | (b3 >> 2))); + outStream.WriteByte((byte)((b3 << 6) | b4)); + + return 3; + } + } + + private int NextI(string data, int i, int finish) + { + while ((i < finish) && Ignore(data[i])) + { + i++; + } + return i; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/Base64Encoder.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/Base64Encoder.cs.meta new file mode 100644 index 0000000..b43f4a5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/Base64Encoder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f702f20adec415348918e89d2bfc5db8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/BufferedDecoder.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/BufferedDecoder.cs new file mode 100644 index 0000000..633cf1e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/BufferedDecoder.cs @@ -0,0 +1,117 @@ +using System; + +namespace Org.BouncyCastle.Utilities.Encoders +{ + /// + /// A buffering class to allow translation from one format to another to + /// be done in discrete chunks. + /// + public class BufferedDecoder + { + internal byte[] buffer; + internal int bufOff; + + internal ITranslator translator; + + /// + /// Create a buffered Decoder. + /// + /// The translater to use. + /// The size of the buffer. + public BufferedDecoder( + ITranslator translator, + int bufferSize) + { + this.translator = translator; + + if ((bufferSize % translator.GetEncodedBlockSize()) != 0) + { + throw new ArgumentException("buffer size not multiple of input block size"); + } + + buffer = new byte[bufferSize]; +// bufOff = 0; + } + + /// + /// Process one byte of data. + /// + /// Data in. + /// Byte array for the output. + /// The offset in the output byte array to start writing from. + /// The amount of output bytes. + public int ProcessByte( + byte input, + byte[] output, + int outOff) + { + int resultLen = 0; + + buffer[bufOff++] = input; + + if (bufOff == buffer.Length) + { + resultLen = translator.Decode(buffer, 0, buffer.Length, output, outOff); + bufOff = 0; + } + + return resultLen; + } + + + /// + /// Process data from a byte array. + /// + /// The input data. + /// Start position within input data array. + /// Amount of data to process from input data array. + /// Array to store output. + /// Position in output array to start writing from. + /// The amount of output bytes. + public int ProcessBytes( + byte[] input, + int inOff, + int len, + byte[] outBytes, + int outOff) + { + if (len < 0) + { + throw new ArgumentException("Can't have a negative input length!"); + } + + int resultLen = 0; + int gapLen = buffer.Length - bufOff; + + if (len > gapLen) + { + Array.Copy(input, inOff, buffer, bufOff, gapLen); + + resultLen += translator.Decode(buffer, 0, buffer.Length, outBytes, outOff); + + bufOff = 0; + + len -= gapLen; + inOff += gapLen; + outOff += resultLen; + + int chunkSize = len - (len % buffer.Length); + + resultLen += translator.Decode(input, inOff, chunkSize, outBytes, outOff); + + len -= chunkSize; + inOff += chunkSize; + } + + if (len != 0) + { + Array.Copy(input, inOff, buffer, bufOff, len); + + bufOff += len; + } + + return resultLen; + } + } + +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/BufferedDecoder.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/BufferedDecoder.cs.meta new file mode 100644 index 0000000..397316f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/BufferedDecoder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7138b75009321e4409dd466a2fb2f325 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/BufferedEncoder.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/BufferedEncoder.cs new file mode 100644 index 0000000..5c3b1ab --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/BufferedEncoder.cs @@ -0,0 +1,117 @@ +using System; + +namespace Org.BouncyCastle.Utilities.Encoders +{ + /// + /// A class that allows encoding of data using a specific encoder to be processed in chunks. + /// + public class BufferedEncoder + { + internal byte[] Buffer; + internal int bufOff; + + internal ITranslator translator; + + + /// + /// Create. + /// + /// The translator to use. + /// Size of the chunks. + public BufferedEncoder( + ITranslator translator, + int bufferSize) + { + this.translator = translator; + + if ((bufferSize % translator.GetEncodedBlockSize()) != 0) + { + throw new ArgumentException("buffer size not multiple of input block size"); + } + + Buffer = new byte[bufferSize]; +// bufOff = 0; + } + + + /// + /// Process one byte of data. + /// + /// The byte. + /// An array to store output in. + /// Offset within output array to start writing from. + /// + public int ProcessByte( + byte input, + byte[] outBytes, + int outOff) + { + int resultLen = 0; + + Buffer[bufOff++] = input; + + if (bufOff == Buffer.Length) + { + resultLen = translator.Encode(Buffer, 0, Buffer.Length, outBytes, outOff); + bufOff = 0; + } + + return resultLen; + } + + /// + /// Process data from a byte array. + /// + /// Input data Byte array containing data to be processed. + /// Start position within input data array. + /// Amount of input data to be processed. + /// Output data array. + /// Offset within output data array to start writing to. + /// The amount of data written. + public int ProcessBytes( + byte[] input, + int inOff, + int len, + byte[] outBytes, + int outOff) + { + if (len < 0) + { + throw new ArgumentException("Can't have a negative input length!"); + } + + int resultLen = 0; + int gapLen = Buffer.Length - bufOff; + + if (len > gapLen) + { + Array.Copy(input, inOff, Buffer, bufOff, gapLen); + + resultLen += translator.Encode(Buffer, 0, Buffer.Length, outBytes, outOff); + + bufOff = 0; + + len -= gapLen; + inOff += gapLen; + outOff += resultLen; + + int chunkSize = len - (len % Buffer.Length); + + resultLen += translator.Encode(input, inOff, chunkSize, outBytes, outOff); + + len -= chunkSize; + inOff += chunkSize; + } + + if (len != 0) + { + Array.Copy(input, inOff, Buffer, bufOff, len); + + bufOff += len; + } + + return resultLen; + } + } + +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/BufferedEncoder.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/BufferedEncoder.cs.meta new file mode 100644 index 0000000..cf5c98e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/BufferedEncoder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 16c8084a81aa89546a4ac51d45aab8a7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/Hex.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/Hex.cs new file mode 100644 index 0000000..0b2a489 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/Hex.cs @@ -0,0 +1,151 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Utilities.Encoders +{ + /// + /// Class to decode and encode Hex. + /// + public sealed class Hex + { + private static readonly HexEncoder encoder = new HexEncoder(); + + private Hex() + { + } + + public static string ToHexString( + byte[] data) + { + return ToHexString(data, 0, data.Length); + } + + public static string ToHexString( + byte[] data, + int off, + int length) + { + byte[] hex = Encode(data, off, length); + return Strings.FromAsciiByteArray(hex); + } + + /** + * encode the input data producing a Hex encoded byte array. + * + * @return a byte array containing the Hex encoded data. + */ + public static byte[] Encode( + byte[] data) + { + return Encode(data, 0, data.Length); + } + + /** + * encode the input data producing a Hex encoded byte array. + * + * @return a byte array containing the Hex encoded data. + */ + public static byte[] Encode( + byte[] data, + int off, + int length) + { + MemoryStream bOut = new MemoryStream(length * 2); + + encoder.Encode(data, off, length, bOut); + + return bOut.ToArray(); + } + + /** + * Hex encode the byte data writing it to the given output stream. + * + * @return the number of bytes produced. + */ + public static int Encode( + byte[] data, + Stream outStream) + { + return encoder.Encode(data, 0, data.Length, outStream); + } + + /** + * Hex encode the byte data writing it to the given output stream. + * + * @return the number of bytes produced. + */ + public static int Encode( + byte[] data, + int off, + int length, + Stream outStream) + { + return encoder.Encode(data, off, length, outStream); + } + + /** + * decode the Hex encoded input data. It is assumed the input data is valid. + * + * @return a byte array representing the decoded data. + */ + public static byte[] Decode( + byte[] data) + { + MemoryStream bOut = new MemoryStream((data.Length + 1) / 2); + + encoder.Decode(data, 0, data.Length, bOut); + + return bOut.ToArray(); + } + + /** + * decode the Hex encoded string data - whitespace will be ignored. + * + * @return a byte array representing the decoded data. + */ + public static byte[] Decode( + string data) + { + MemoryStream bOut = new MemoryStream((data.Length + 1) / 2); + + encoder.DecodeString(data, bOut); + + return bOut.ToArray(); + } + + /** + * decode the Hex encoded string data writing it to the given output stream, + * whitespace characters will be ignored. + * + * @return the number of bytes produced. + */ + public static int Decode( + string data, + Stream outStream) + { + return encoder.DecodeString(data, outStream); + } + + /** + * Decode the hexadecimal-encoded string strictly i.e. any non-hexadecimal characters will be + * considered an error. + * + * @return a byte array representing the decoded data. + */ + public static byte[] DecodeStrict(string str) + { + return encoder.DecodeStrict(str, 0, str.Length); + } + + /** + * Decode the hexadecimal-encoded string strictly i.e. any non-hexadecimal characters will be + * considered an error. + * + * @return a byte array representing the decoded data. + */ + public static byte[] DecodeStrict(string str, int off, int len) + { + return encoder.DecodeStrict(str, off, len); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/Hex.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/Hex.cs.meta new file mode 100644 index 0000000..9ff992f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/Hex.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a73eb729e6deb2b4992b241753051580 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/HexEncoder.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/HexEncoder.cs new file mode 100644 index 0000000..bf68aff --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/HexEncoder.cs @@ -0,0 +1,241 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Utilities.Encoders +{ + public class HexEncoder + : IEncoder + { + protected readonly byte[] encodingTable = + { + (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', (byte)'7', + (byte)'8', (byte)'9', (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f' + }; + + /* + * set up the decoding table. + */ + protected readonly byte[] decodingTable = new byte[128]; + + protected void InitialiseDecodingTable() + { + Arrays.Fill(decodingTable, (byte)0xff); + + for (int i = 0; i < encodingTable.Length; i++) + { + decodingTable[encodingTable[i]] = (byte)i; + } + + decodingTable['A'] = decodingTable['a']; + decodingTable['B'] = decodingTable['b']; + decodingTable['C'] = decodingTable['c']; + decodingTable['D'] = decodingTable['d']; + decodingTable['E'] = decodingTable['e']; + decodingTable['F'] = decodingTable['f']; + } + + public HexEncoder() + { + InitialiseDecodingTable(); + } + + public int Encode(byte[] inBuf, int inOff, int inLen, byte[] outBuf, int outOff) + { + int inPos = inOff; + int inEnd = inOff + inLen; + int outPos = outOff; + + while (inPos < inEnd) + { + uint b = inBuf[inPos++]; + + outBuf[outPos++] = encodingTable[b >> 4]; + outBuf[outPos++] = encodingTable[b & 0xF]; + } + + return outPos - outOff; + } + + /** + * encode the input data producing a Hex output stream. + * + * @return the number of bytes produced. + */ + public int Encode(byte[] buf, int off, int len, Stream outStream) + { + if (len < 0) + return 0; + + byte[] tmp = new byte[72]; + int remaining = len; + while (remaining > 0) + { + int inLen = System.Math.Min(36, remaining); + int outLen = Encode(buf, off, inLen, tmp, 0); + outStream.Write(tmp, 0, outLen); + off += inLen; + remaining -= inLen; + } + return len * 2; + } + + private static bool Ignore(char c) + { + return c == '\n' || c =='\r' || c == '\t' || c == ' '; + } + + /** + * decode the Hex encoded byte data writing it to the given output stream, + * whitespace characters will be ignored. + * + * @return the number of bytes produced. + */ + public int Decode( + byte[] data, + int off, + int length, + Stream outStream) + { + byte b1, b2; + int outLen = 0; + byte[] buf = new byte[36]; + int bufOff = 0; + int end = off + length; + + while (end > off) + { + if (!Ignore((char)data[end - 1])) + break; + + end--; + } + + int i = off; + while (i < end) + { + while (i < end && Ignore((char)data[i])) + { + i++; + } + + b1 = decodingTable[data[i++]]; + + while (i < end && Ignore((char)data[i])) + { + i++; + } + + b2 = decodingTable[data[i++]]; + + if ((b1 | b2) >= 0x80) + throw new IOException("invalid characters encountered in Hex data"); + + buf[bufOff++] = (byte)((b1 << 4) | b2); + + if (bufOff == buf.Length) + { + outStream.Write(buf, 0, bufOff); + bufOff = 0; + } + + outLen++; + } + + if (bufOff > 0) + { + outStream.Write(buf, 0, bufOff); + } + + return outLen; + } + + /** + * decode the Hex encoded string data writing it to the given output stream, + * whitespace characters will be ignored. + * + * @return the number of bytes produced. + */ + public int DecodeString( + string data, + Stream outStream) + { + byte b1, b2; + int length = 0; + byte[] buf = new byte[36]; + int bufOff = 0; + int end = data.Length; + + while (end > 0) + { + if (!Ignore(data[end - 1])) + break; + + end--; + } + + int i = 0; + while (i < end) + { + while (i < end && Ignore(data[i])) + { + i++; + } + + b1 = decodingTable[data[i++]]; + + while (i < end && Ignore(data[i])) + { + i++; + } + + b2 = decodingTable[data[i++]]; + + if ((b1 | b2) >= 0x80) + throw new IOException("invalid characters encountered in Hex data"); + + buf[bufOff++] = (byte)((b1 << 4) | b2); + + if (bufOff == buf.Length) + { + outStream.Write(buf, 0, bufOff); + bufOff = 0; + } + + length++; + } + + if (bufOff > 0) + { + outStream.Write(buf, 0, bufOff); + } + + return length; + } + + internal byte[] DecodeStrict(string str, int off, int len) + { + if (null == str) + throw new ArgumentNullException("str"); + if (off < 0 || len < 0 || off > (str.Length - len)) + throw new IndexOutOfRangeException("invalid offset and/or length specified"); + if (0 != (len & 1)) + throw new ArgumentException("a hexadecimal encoding must have an even number of characters", "len"); + + int resultLen = len >> 1; + byte[] result = new byte[resultLen]; + + int strPos = off; + for (int i = 0; i < resultLen; ++i) + { + byte b1 = decodingTable[str[strPos++]]; + byte b2 = decodingTable[str[strPos++]]; + + if ((b1 | b2) >= 0x80) + throw new IOException("invalid characters encountered in Hex data"); + + result[i] = (byte)((b1 << 4) | b2); + } + return result; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/HexEncoder.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/HexEncoder.cs.meta new file mode 100644 index 0000000..539f9f8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/HexEncoder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 932d3cb7c6c2c4d4aabc68c0e5a0a15a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/HexTranslator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/HexTranslator.cs new file mode 100644 index 0000000..9775b69 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/HexTranslator.cs @@ -0,0 +1,108 @@ +using System; + +namespace Org.BouncyCastle.Utilities.Encoders +{ + /// + /// A hex translator. + /// + public class HexTranslator : ITranslator + { + private static readonly byte[] hexTable = + { + (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', (byte)'7', + (byte)'8', (byte)'9', (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f' + }; + + /// + /// Return encoded block size. + /// + /// 2 + public int GetEncodedBlockSize() + { + return 2; + } + + /// + /// Encode some data. + /// + /// Input data array. + /// Start position within input data array. + /// The amount of data to process. + /// The output data array. + /// The offset within the output data array to start writing from. + /// Amount of data encoded. + public int Encode( + byte[] input, + int inOff, + int length, + byte[] outBytes, + int outOff) + { + for (int i = 0, j = 0; i < length; i++, j += 2) + { + outBytes[outOff + j] = hexTable[(input[inOff] >> 4) & 0x0f]; + outBytes[outOff + j + 1] = hexTable[input[inOff] & 0x0f]; + + inOff++; + } + + return length * 2; + } + + /// + /// Returns the decoded block size. + /// + /// 1 + public int GetDecodedBlockSize() + { + return 1; + } + + /// + /// Decode data from a byte array. + /// + /// The input data array. + /// Start position within input data array. + /// The amounty of data to process. + /// The output data array. + /// The position within the output data array to start writing from. + /// The amount of data written. + public int Decode( + byte[] input, + int inOff, + int length, + byte[] outBytes, + int outOff) + { + int halfLength = length / 2; + byte left, right; + for (int i = 0; i < halfLength; i++) + { + left = input[inOff + i * 2]; + right = input[inOff + i * 2 + 1]; + + if (left < (byte)'a') + { + outBytes[outOff] = (byte)((left - '0') << 4); + } + else + { + outBytes[outOff] = (byte)((left - 'a' + 10) << 4); + } + if (right < (byte)'a') + { + outBytes[outOff] += (byte)(right - '0'); + } + else + { + outBytes[outOff] += (byte)(right - 'a' + 10); + } + + outOff++; + } + + return halfLength; + } + } + +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/HexTranslator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/HexTranslator.cs.meta new file mode 100644 index 0000000..dd54bed --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/HexTranslator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7f70fe76cee2b2e48b8c2474b14a139c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/IEncoder.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/IEncoder.cs new file mode 100644 index 0000000..5887d5d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/IEncoder.cs @@ -0,0 +1,18 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Utilities.Encoders +{ + /** + * Encode and decode byte arrays (typically from binary to 7-bit ASCII + * encodings). + */ + public interface IEncoder + { + int Encode(byte[] data, int off, int length, Stream outStream); + + int Decode(byte[] data, int off, int length, Stream outStream); + + int DecodeString(string data, Stream outStream); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/IEncoder.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/IEncoder.cs.meta new file mode 100644 index 0000000..c05a4ad --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/IEncoder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1c7aea86c1278a141bf15a3642a8e3ec +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/Translator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/Translator.cs new file mode 100644 index 0000000..10bd24b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/Translator.cs @@ -0,0 +1,19 @@ +using System; + +namespace Org.BouncyCastle.Utilities.Encoders +{ + /// + /// Translator interface. + /// + public interface ITranslator + { + int GetEncodedBlockSize(); + + int Encode(byte[] input, int inOff, int length, byte[] outBytes, int outOff); + + int GetDecodedBlockSize(); + + int Decode(byte[] input, int inOff, int length, byte[] outBytes, int outOff); + } + +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/Translator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/Translator.cs.meta new file mode 100644 index 0000000..4a8dc4d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/Translator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1c0eb8b9baf17b1448af048b90829267 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/UrlBase64.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/UrlBase64.cs new file mode 100644 index 0000000..94195ef --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/UrlBase64.cs @@ -0,0 +1,127 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Utilities.Encoders +{ + /** + * Convert binary data to and from UrlBase64 encoding. This is identical to + * Base64 encoding, except that the padding character is "." and the other + * non-alphanumeric characters are "-" and "_" instead of "+" and "/". + *

    + * The purpose of UrlBase64 encoding is to provide a compact encoding of binary + * data that is safe for use as an URL parameter. Base64 encoding does not + * produce encoded values that are safe for use in URLs, since "/" can be + * interpreted as a path delimiter; "+" is the encoded form of a space; and + * "=" is used to separate a name from the corresponding value in an URL + * parameter. + *

    + */ + public class UrlBase64 + { + private static readonly IEncoder encoder = new UrlBase64Encoder(); + + /** + * Encode the input data producing a URL safe base 64 encoded byte array. + * + * @return a byte array containing the URL safe base 64 encoded data. + */ + public static byte[] Encode( + byte[] data) + { + MemoryStream bOut = new MemoryStream(); + + try + { + encoder.Encode(data, 0, data.Length, bOut); + } + catch (IOException e) + { + throw new Exception("exception encoding URL safe base64 string: " + e.Message, e); + } + + return bOut.ToArray(); + } + + /** + * Encode the byte data writing it to the given output stream. + * + * @return the number of bytes produced. + */ + public static int Encode( + byte[] data, + Stream outStr) + { + return encoder.Encode(data, 0, data.Length, outStr); + } + + /** + * Decode the URL safe base 64 encoded input data - white space will be ignored. + * + * @return a byte array representing the decoded data. + */ + public static byte[] Decode( + byte[] data) + { + MemoryStream bOut = new MemoryStream(); + + try + { + encoder.Decode(data, 0, data.Length, bOut); + } + catch (IOException e) + { + throw new Exception("exception decoding URL safe base64 string: " + e.Message, e); + } + + return bOut.ToArray(); + } + + /** + * decode the URL safe base 64 encoded byte data writing it to the given output stream, + * whitespace characters will be ignored. + * + * @return the number of bytes produced. + */ + public static int Decode( + byte[] data, + Stream outStr) + { + return encoder.Decode(data, 0, data.Length, outStr); + } + + /** + * decode the URL safe base 64 encoded string data - whitespace will be ignored. + * + * @return a byte array representing the decoded data. + */ + public static byte[] Decode( + string data) + { + MemoryStream bOut = new MemoryStream(); + + try + { + encoder.DecodeString(data, bOut); + } + catch (IOException e) + { + throw new Exception("exception decoding URL safe base64 string: " + e.Message, e); + } + + return bOut.ToArray(); + } + + /** + * Decode the URL safe base 64 encoded string data writing it to the given output stream, + * whitespace characters will be ignored. + * + * @return the number of bytes produced. + */ + public static int Decode( + string data, + Stream outStr) + { + return encoder.DecodeString(data, outStr); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/UrlBase64.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/UrlBase64.cs.meta new file mode 100644 index 0000000..a213472 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/UrlBase64.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 18241bcb5e991d149b18cd701156b2b4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/UrlBase64Encoder.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/UrlBase64Encoder.cs new file mode 100644 index 0000000..5611a83 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/UrlBase64Encoder.cs @@ -0,0 +1,31 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Utilities.Encoders +{ + /** + * Convert binary data to and from UrlBase64 encoding. This is identical to + * Base64 encoding, except that the padding character is "." and the other + * non-alphanumeric characters are "-" and "_" instead of "+" and "/". + *

    + * The purpose of UrlBase64 encoding is to provide a compact encoding of binary + * data that is safe for use as an URL parameter. Base64 encoding does not + * produce encoded values that are safe for use in URLs, since "/" can be + * interpreted as a path delimiter; "+" is the encoded form of a space; and + * "=" is used to separate a name from the corresponding value in an URL + * parameter. + *

    + */ + public class UrlBase64Encoder + : Base64Encoder + { + public UrlBase64Encoder() + { + encodingTable[encodingTable.Length - 2] = (byte) '-'; + encodingTable[encodingTable.Length - 1] = (byte) '_'; + padding = (byte) '.'; + // we must re-create the decoding table with the new encoded values. + InitialiseDecodingTable(); + } + } +} \ No newline at end of file diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/UrlBase64Encoder.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/UrlBase64Encoder.cs.meta new file mode 100644 index 0000000..6823519 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/encoders/UrlBase64Encoder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ba248b6915d72234795801a78bab0d35 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io.meta new file mode 100644 index 0000000..02cabd5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0cb2e5f204d93fd4eb02d6ce6bc56b93 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/BaseInputStream.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/BaseInputStream.cs new file mode 100644 index 0000000..a5613d8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/BaseInputStream.cs @@ -0,0 +1,64 @@ +using System; +using System.Diagnostics; +using System.IO; + +namespace Org.BouncyCastle.Utilities.IO +{ + public abstract class BaseInputStream : Stream + { + private bool closed; + + public sealed override bool CanRead { get { return !closed; } } + public sealed override bool CanSeek { get { return false; } } + public sealed override bool CanWrite { get { return false; } } + +#if PORTABLE + protected override void Dispose(bool disposing) + { + if (disposing) + { + closed = true; + } + base.Dispose(disposing); + } +#else + public override void Close() + { + closed = true; + base.Close(); + } +#endif + + public sealed override void Flush() {} + public sealed override long Length { get { throw new NotSupportedException(); } } + public sealed override long Position + { + get { throw new NotSupportedException(); } + set { throw new NotSupportedException(); } + } + + public override int Read(byte[] buffer, int offset, int count) + { + int pos = offset; + try + { + int end = offset + count; + while (pos < end) + { + int b = ReadByte(); + if (b == -1) break; + buffer[pos++] = (byte) b; + } + } + catch (IOException) + { + if (pos == offset) throw; + } + return pos - offset; + } + + public sealed override long Seek(long offset, SeekOrigin origin) { throw new NotSupportedException(); } + public sealed override void SetLength(long value) { throw new NotSupportedException(); } + public sealed override void Write(byte[] buffer, int offset, int count) { throw new NotSupportedException(); } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/BaseInputStream.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/BaseInputStream.cs.meta new file mode 100644 index 0000000..5401a9b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/BaseInputStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 81fe0dc0a5e8035468d20240f6e3a96a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/BaseOutputStream.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/BaseOutputStream.cs new file mode 100644 index 0000000..0dbe821 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/BaseOutputStream.cs @@ -0,0 +1,69 @@ +using System; +using System.Diagnostics; +using System.IO; + +namespace Org.BouncyCastle.Utilities.IO +{ + public abstract class BaseOutputStream : Stream + { + private bool closed; + + public sealed override bool CanRead { get { return false; } } + public sealed override bool CanSeek { get { return false; } } + public sealed override bool CanWrite { get { return !closed; } } + +#if PORTABLE + protected override void Dispose(bool disposing) + { + if (disposing) + { + closed = true; + } + base.Dispose(disposing); + } +#else + public override void Close() + { + closed = true; + base.Close(); + } +#endif + + public override void Flush() { } + public sealed override long Length { get { throw new NotSupportedException(); } } + public sealed override long Position + { + get { throw new NotSupportedException(); } + set { throw new NotSupportedException(); } + } + public sealed override int Read(byte[] buffer, int offset, int count) { throw new NotSupportedException(); } + public sealed override long Seek(long offset, SeekOrigin origin) { throw new NotSupportedException(); } + public sealed override void SetLength(long value) { throw new NotSupportedException(); } + + public override void Write(byte[] buffer, int offset, int count) + { + Debug.Assert(buffer != null); + Debug.Assert(0 <= offset && offset <= buffer.Length); + Debug.Assert(count >= 0); + + int end = offset + count; + + Debug.Assert(0 <= end && end <= buffer.Length); + + for (int i = offset; i < end; ++i) + { + this.WriteByte(buffer[i]); + } + } + + public virtual void Write(params byte[] buffer) + { + Write(buffer, 0, buffer.Length); + } + + public override void WriteByte(byte b) + { + Write(new byte[]{ b }, 0, 1); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/BaseOutputStream.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/BaseOutputStream.cs.meta new file mode 100644 index 0000000..d6dcfda --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/BaseOutputStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 27df28ce3d2e2f741b9019cee45263c5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/FilterStream.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/FilterStream.cs new file mode 100644 index 0000000..a92dee3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/FilterStream.cs @@ -0,0 +1,78 @@ +using System.IO; + +namespace Org.BouncyCastle.Utilities.IO +{ + public class FilterStream : Stream + { + public FilterStream(Stream s) + { + this.s = s; + } + public override bool CanRead + { + get { return s.CanRead; } + } + public override bool CanSeek + { + get { return s.CanSeek; } + } + public override bool CanWrite + { + get { return s.CanWrite; } + } + public override long Length + { + get { return s.Length; } + } + public override long Position + { + get { return s.Position; } + set { s.Position = value; } + } +#if PORTABLE + protected override void Dispose(bool disposing) + { + if (disposing) + { + Platform.Dispose(s); + } + base.Dispose(disposing); + } +#else + public override void Close() + { + Platform.Dispose(s); + base.Close(); + } +#endif + public override void Flush() + { + s.Flush(); + } + public override long Seek(long offset, SeekOrigin origin) + { + return s.Seek(offset, origin); + } + public override void SetLength(long value) + { + s.SetLength(value); + } + public override int Read(byte[] buffer, int offset, int count) + { + return s.Read(buffer, offset, count); + } + public override int ReadByte() + { + return s.ReadByte(); + } + public override void Write(byte[] buffer, int offset, int count) + { + s.Write(buffer, offset, count); + } + public override void WriteByte(byte value) + { + s.WriteByte(value); + } + protected readonly Stream s; + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/FilterStream.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/FilterStream.cs.meta new file mode 100644 index 0000000..e28daf6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/FilterStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ba1620d212687a846acf8b89da45a0e0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/MemoryInputStream.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/MemoryInputStream.cs new file mode 100644 index 0000000..cdc5aaf --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/MemoryInputStream.cs @@ -0,0 +1,19 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Utilities.IO +{ + public class MemoryInputStream + : MemoryStream + { + public MemoryInputStream(byte[] buffer) + : base(buffer, false) + { + } + + public sealed override bool CanWrite + { + get { return false; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/MemoryInputStream.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/MemoryInputStream.cs.meta new file mode 100644 index 0000000..fc9b78a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/MemoryInputStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8e9d21d02e74ab243adb8790883955f4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/MemoryOutputStream.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/MemoryOutputStream.cs new file mode 100644 index 0000000..828f23b --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/MemoryOutputStream.cs @@ -0,0 +1,14 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Utilities.IO +{ + public class MemoryOutputStream + : MemoryStream + { + public sealed override bool CanRead + { + get { return false; } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/MemoryOutputStream.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/MemoryOutputStream.cs.meta new file mode 100644 index 0000000..967eb5c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/MemoryOutputStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 694fd447a65964344892e7a3ccac9e61 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/NullOutputStream.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/NullOutputStream.cs new file mode 100644 index 0000000..13877fa --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/NullOutputStream.cs @@ -0,0 +1,18 @@ +using System; + +namespace Org.BouncyCastle.Utilities.IO +{ + internal class NullOutputStream + : BaseOutputStream + { + public override void WriteByte(byte b) + { + // do nothing + } + + public override void Write(byte[] buffer, int offset, int count) + { + // do nothing + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/NullOutputStream.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/NullOutputStream.cs.meta new file mode 100644 index 0000000..3e1a294 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/NullOutputStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2b9ea36ea8009264ab5b05fb0e410ab4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/PushbackStream.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/PushbackStream.cs new file mode 100644 index 0000000..9546942 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/PushbackStream.cs @@ -0,0 +1,52 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Asn1.Utilities; + +namespace Org.BouncyCastle.Utilities.IO +{ + public class PushbackStream + : FilterStream + { + private int buf = -1; + + public PushbackStream( + Stream s) + : base(s) + { + } + + public override int ReadByte() + { + if (buf != -1) + { + int tmp = buf; + buf = -1; + return tmp; + } + + return base.ReadByte(); + } + + public override int Read(byte[] buffer, int offset, int count) + { + if (buf != -1 && count > 0) + { + // TODO Can this case be made more efficient? + buffer[offset] = (byte) buf; + buf = -1; + return 1; + } + + return base.Read(buffer, offset, count); + } + + public virtual void Unread(int b) + { + if (buf != -1) + throw new InvalidOperationException("Can only push back one byte"); + + buf = b & 0xFF; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/PushbackStream.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/PushbackStream.cs.meta new file mode 100644 index 0000000..10d548d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/PushbackStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 135e01f12f82be64ca5d4ff8f97ec17d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/StreamOverflowException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/StreamOverflowException.cs new file mode 100644 index 0000000..36d21e2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/StreamOverflowException.cs @@ -0,0 +1,30 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Utilities.IO +{ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE) + [Serializable] +#endif + public class StreamOverflowException + : IOException + { + public StreamOverflowException() + : base() + { + } + + public StreamOverflowException( + string message) + : base(message) + { + } + + public StreamOverflowException( + string message, + Exception exception) + : base(message, exception) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/StreamOverflowException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/StreamOverflowException.cs.meta new file mode 100644 index 0000000..291a098 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/StreamOverflowException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 23a2be4a3a0b42342b1611f9f530451c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/Streams.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/Streams.cs new file mode 100644 index 0000000..a86367e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/Streams.cs @@ -0,0 +1,133 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Utilities.IO +{ + public sealed class Streams + { + private const int BufferSize = 4096; + + private Streams() + { + } + + public static void Drain(Stream inStr) + { + byte[] bs = new byte[BufferSize]; + while (inStr.Read(bs, 0, bs.Length) > 0) + { + } + } + + public static byte[] ReadAll(Stream inStr) + { + MemoryStream buf = new MemoryStream(); + PipeAll(inStr, buf); + return buf.ToArray(); + } + + public static byte[] ReadAllLimited(Stream inStr, int limit) + { + MemoryStream buf = new MemoryStream(); + PipeAllLimited(inStr, limit, buf); + return buf.ToArray(); + } + + public static int ReadFully(Stream inStr, byte[] buf) + { + return ReadFully(inStr, buf, 0, buf.Length); + } + + public static int ReadFully(Stream inStr, byte[] buf, int off, int len) + { + int totalRead = 0; + while (totalRead < len) + { + int numRead = inStr.Read(buf, off + totalRead, len - totalRead); + if (numRead < 1) + break; + totalRead += numRead; + } + return totalRead; + } + + /// Write the full contents of inStr to the destination stream outStr. + /// Source stream. + /// Destination stream. + /// In case of IO failure. + public static void PipeAll(Stream inStr, Stream outStr) + { + PipeAll(inStr, outStr, BufferSize); + } + + /// Write the full contents of inStr to the destination stream outStr. + /// Source stream. + /// Destination stream. + /// The size of temporary buffer to use. + /// In case of IO failure. + public static void PipeAll(Stream inStr, Stream outStr, int bufferSize) + { + byte[] bs = new byte[bufferSize]; + int numRead; + while ((numRead = inStr.Read(bs, 0, bs.Length)) > 0) + { + outStr.Write(bs, 0, numRead); + } + } + + /// + /// Pipe all bytes from inStr to outStr, throwing StreamFlowException if greater + /// than limit bytes in inStr. + /// + /// + /// A + /// + /// + /// A + /// + /// + /// A + /// + /// The number of bytes actually transferred, if not greater than limit + /// + public static long PipeAllLimited(Stream inStr, long limit, Stream outStr) + { + byte[] bs = new byte[BufferSize]; + long total = 0; + int numRead; + while ((numRead = inStr.Read(bs, 0, bs.Length)) > 0) + { + if ((limit - total) < numRead) + throw new StreamOverflowException("Data Overflow"); + total += numRead; + outStr.Write(bs, 0, numRead); + } + return total; + } + + /// + public static void WriteBufTo(MemoryStream buf, Stream output) + { + buf.WriteTo(output); + } + + /// + public static int WriteBufTo(MemoryStream buf, byte[] output, int offset) + { + int size = (int)buf.Length; + WriteBufTo(buf, new MemoryStream(output, offset, size)); + return size; + } + + public static void WriteZeroes(Stream outStr, long count) + { + byte[] zeroes = new byte[BufferSize]; + while (count > BufferSize) + { + outStr.Write(zeroes, 0, BufferSize); + count -= BufferSize; + } + outStr.Write(zeroes, 0, (int)count); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/Streams.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/Streams.cs.meta new file mode 100644 index 0000000..f5aa44d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/Streams.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5b0fc5235088deb49bb1f80c4e5cdfe6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/TeeInputStream.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/TeeInputStream.cs new file mode 100644 index 0000000..6996f3f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/TeeInputStream.cs @@ -0,0 +1,64 @@ +using System; +using System.Diagnostics; +using System.IO; + +namespace Org.BouncyCastle.Utilities.IO +{ + public class TeeInputStream + : BaseInputStream + { + private readonly Stream input, tee; + + public TeeInputStream(Stream input, Stream tee) + { + Debug.Assert(input.CanRead); + Debug.Assert(tee.CanWrite); + + this.input = input; + this.tee = tee; + } + +#if PORTABLE + protected override void Dispose(bool disposing) + { + if (disposing) + { + Platform.Dispose(input); + Platform.Dispose(tee); + } + base.Dispose(disposing); + } +#else + public override void Close() + { + Platform.Dispose(input); + Platform.Dispose(tee); + base.Close(); + } +#endif + + public override int Read(byte[] buf, int off, int len) + { + int i = input.Read(buf, off, len); + + if (i > 0) + { + tee.Write(buf, off, i); + } + + return i; + } + + public override int ReadByte() + { + int i = input.ReadByte(); + + if (i >= 0) + { + tee.WriteByte((byte)i); + } + + return i; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/TeeInputStream.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/TeeInputStream.cs.meta new file mode 100644 index 0000000..1ad27ca --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/TeeInputStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 31bfbf2502ec522458809b4c90000388 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/TeeOutputStream.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/TeeOutputStream.cs new file mode 100644 index 0000000..a6c7fd5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/TeeOutputStream.cs @@ -0,0 +1,52 @@ +using System; +using System.Diagnostics; +using System.IO; + +namespace Org.BouncyCastle.Utilities.IO +{ + public class TeeOutputStream + : BaseOutputStream + { + private readonly Stream output, tee; + + public TeeOutputStream(Stream output, Stream tee) + { + Debug.Assert(output.CanWrite); + Debug.Assert(tee.CanWrite); + + this.output = output; + this.tee = tee; + } + +#if PORTABLE + protected override void Dispose(bool disposing) + { + if (disposing) + { + Platform.Dispose(output); + Platform.Dispose(tee); + } + base.Dispose(disposing); + } +#else + public override void Close() + { + Platform.Dispose(output); + Platform.Dispose(tee); + base.Close(); + } +#endif + + public override void Write(byte[] buffer, int offset, int count) + { + output.Write(buffer, offset, count); + tee.Write(buffer, offset, count); + } + + public override void WriteByte(byte b) + { + output.WriteByte(b); + tee.WriteByte(b); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/TeeOutputStream.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/TeeOutputStream.cs.meta new file mode 100644 index 0000000..83c8dde --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/TeeOutputStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 339bcb11697cdd647976ee26e6b79279 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/pem.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/pem.meta new file mode 100644 index 0000000..dbdb8f4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/pem.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 3340e3d895cd4dd499e536b28d0c78ab +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/pem/PemGenerationException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/pem/PemGenerationException.cs new file mode 100644 index 0000000..6b39585 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/pem/PemGenerationException.cs @@ -0,0 +1,29 @@ +using System; + +namespace Org.BouncyCastle.Utilities.IO.Pem +{ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE) + [Serializable] +#endif + public class PemGenerationException + : Exception + { + public PemGenerationException() + : base() + { + } + + public PemGenerationException( + string message) + : base(message) + { + } + + public PemGenerationException( + string message, + Exception exception) + : base(message, exception) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/pem/PemGenerationException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/pem/PemGenerationException.cs.meta new file mode 100644 index 0000000..c7bd3ca --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/pem/PemGenerationException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5cbd2baa9416ba7448d8e32ff2045816 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/pem/PemHeader.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/pem/PemHeader.cs new file mode 100644 index 0000000..c6236f5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/pem/PemHeader.cs @@ -0,0 +1,60 @@ +using System; + +namespace Org.BouncyCastle.Utilities.IO.Pem +{ + public class PemHeader + { + private string name; + private string val; + + public PemHeader(string name, string val) + { + this.name = name; + this.val = val; + } + + public virtual string Name + { + get { return name; } + } + + public virtual string Value + { + get { return val; } + } + + public override int GetHashCode() + { + return GetHashCode(this.name) + 31 * GetHashCode(this.val); + } + + public override bool Equals(object obj) + { + if (obj == this) + return true; + + if (!(obj is PemHeader)) + return false; + + PemHeader other = (PemHeader)obj; + + return Platform.Equals(this.name, other.name) + && Platform.Equals(this.val, other.val); + } + + private int GetHashCode(string s) + { + if (s == null) + { + return 1; + } + + return s.GetHashCode(); + } + + public override string ToString() + { + return name + ":" + val; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/pem/PemHeader.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/pem/PemHeader.cs.meta new file mode 100644 index 0000000..c20a4f8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/pem/PemHeader.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c5455dd1ca2528f4aadf3fa68b8dd62c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/pem/PemObject.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/pem/PemObject.cs new file mode 100644 index 0000000..41212f9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/pem/PemObject.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.Utilities.IO.Pem +{ + public class PemObject + : PemObjectGenerator + { + private string type; + private IList headers; + private byte[] content; + + public PemObject(string type, byte[] content) + : this(type, Platform.CreateArrayList(), content) + { + } + + public PemObject(String type, IList headers, byte[] content) + { + this.type = type; + this.headers = Platform.CreateArrayList(headers); + this.content = content; + } + + public string Type + { + get { return type; } + } + + public IList Headers + { + get { return headers; } + } + + public byte[] Content + { + get { return content; } + } + + public PemObject Generate() + { + return this; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/pem/PemObject.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/pem/PemObject.cs.meta new file mode 100644 index 0000000..813f614 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/pem/PemObject.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 19f14c0c44b0cab42ac034dc11c98233 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/pem/PemObjectGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/pem/PemObjectGenerator.cs new file mode 100644 index 0000000..6f9bfc1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/pem/PemObjectGenerator.cs @@ -0,0 +1,13 @@ +using System; + +namespace Org.BouncyCastle.Utilities.IO.Pem +{ + public interface PemObjectGenerator + { + /// + /// A + /// + /// + PemObject Generate(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/pem/PemObjectGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/pem/PemObjectGenerator.cs.meta new file mode 100644 index 0000000..e1ecc6c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/pem/PemObjectGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fd0586ebe4ceeca4cbd69a1053797d0a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/pem/PemObjectParser.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/pem/PemObjectParser.cs new file mode 100644 index 0000000..91d26dc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/pem/PemObjectParser.cs @@ -0,0 +1,17 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Utilities.IO.Pem +{ + public interface PemObjectParser + { + /// + /// A + /// + /// + /// A + /// + /// + object ParseObject(PemObject obj); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/pem/PemObjectParser.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/pem/PemObjectParser.cs.meta new file mode 100644 index 0000000..0a90359 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/pem/PemObjectParser.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 79d4531e1c4f98640bfbd4fc16d08cea +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/pem/PemReader.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/pem/PemReader.cs new file mode 100644 index 0000000..008a035 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/pem/PemReader.cs @@ -0,0 +1,371 @@ +using System; +using System.Collections; +using System.IO; + + +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Utilities.IO.Pem +{ + + public class PemReader + { + private readonly TextReader reader; + private readonly MemoryStream buffer; + private readonly StreamWriter textBuffer; + private readonly IList pushback = Platform.CreateArrayList(); + int c = 0; + + + + public PemReader(TextReader reader) + { + if (reader == null) + throw new ArgumentNullException("reader"); + + + buffer = new MemoryStream(); + textBuffer = new StreamWriter(buffer); + + this.reader = reader; + } + + public TextReader Reader + { + get { return reader; } + } + + + /// + /// A + /// + /// + public PemObject ReadPemObject() + { + + // + // Look for BEGIN + // + + for (; ; ) + { + + // Seek a leading dash, ignore anything up to that point. + if (!seekDash()) + { + // There are no pem objects here. + return null; + } + + + // consume dash [-----]BEGIN ... + if (!consumeDash()) + { + throw new IOException("no data after consuming leading dashes"); + } + + + skipWhiteSpace(); + + + if (!expect("BEGIN")) + { + continue; + } + + break; + + } + + + skipWhiteSpace(); + + // + // Consume type, accepting whitespace + // + + if (!bufferUntilStopChar('-',false) ) + { + throw new IOException("ran out of data before consuming type"); + } + + string type = bufferedString().Trim(); + + + // Consume dashes after type. + + if (!consumeDash()) + { + throw new IOException("ran out of data consuming header"); + } + + skipWhiteSpace(); + + + // + // Read ahead looking for headers. + // Look for a colon for up to 64 characters, as an indication there might be a header. + // + + IList headers = Platform.CreateArrayList(); + + while (seekColon(64)) + { + + if (!bufferUntilStopChar(':',false)) + { + throw new IOException("ran out of data reading header key value"); + } + + string key = bufferedString().Trim(); + + + c = Read(); + if (c != ':') + { + throw new IOException("expected colon"); + } + + + // + // We are going to look for well formed headers, if they do not end with a "LF" we cannot + // discern where they end. + // + + if (!bufferUntilStopChar('\n', false)) // Now read to the end of the line. + { + throw new IOException("ran out of data before consuming header value"); + } + + skipWhiteSpace(); + + string value = bufferedString().Trim(); + headers.Add(new PemHeader(key,value)); + } + + + // + // Consume payload, ignoring all white space until we encounter a '-' + // + + skipWhiteSpace(); + + if (!bufferUntilStopChar('-',true)) + { + throw new IOException("ran out of data before consuming payload"); + } + + string payload = bufferedString(); + + // Seek the start of the end. + if (!seekDash()) + { + throw new IOException("did not find leading '-'"); + } + + if (!consumeDash()) + { + throw new IOException("no data after consuming trailing dashes"); + } + + if (!expect("END "+type)) + { + throw new IOException("END "+type+" was not found."); + } + + + + if (!seekDash()) + { + throw new IOException("did not find ending '-'"); + } + + + // consume trailing dashes. + consumeDash(); + + + return new PemObject(type, headers, Base64.Decode(payload)); + + } + + + + private string bufferedString() + { + textBuffer.Flush(); + string value = Strings.FromUtf8ByteArray(buffer.ToArray()); + buffer.Position = 0; + buffer.SetLength(0); + return value; + } + + + private bool seekDash() + { + c = 0; + while((c = Read()) >=0) + { + if (c == '-') + { + break; + } + } + + PushBack(c); + + return c == '-'; + } + + + /// + /// Seek ':" up to the limit. + /// + /// + /// + private bool seekColon(int upTo) + { + c = 0; + bool colonFound = false; + IList read = Platform.CreateArrayList(); + + for (; upTo>=0 && c >=0; upTo--) + { + c = Read(); + read.Add(c); + if (c == ':') + { + colonFound = true; + break; + } + } + + while(read.Count>0) + { + PushBack((int)read[read.Count-1]); + read.RemoveAt(read.Count-1); + } + + return colonFound; + } + + + + /// + /// Consume the dashes + /// + /// + private bool consumeDash() + { + c = 0; + while ((c = Read()) >= 0) + { + if (c != '-') + { + break; + } + } + + PushBack(c); + + return c != -1; + } + + /// + /// Skip white space leave char in stream. + /// + private void skipWhiteSpace() + { + while ((c = Read()) >= 0) + { + if (c > ' ') + { + break; + } + } + PushBack(c); + } + + /// + /// Read forward consuming the expected string. + /// + /// expected string + /// false if not consumed + + private bool expect(String value) + { + for (int t=0; t + /// Consume until dash. + /// + /// true if stream end not met + private bool bufferUntilStopChar(char stopChar, bool skipWhiteSpace) + { + while ((c = Read()) >= 0) + { + if (skipWhiteSpace && c <=' ') + { + continue; + } + + if (c != stopChar) + { + textBuffer.Write((char)c); + textBuffer.Flush(); + + } else + { + PushBack(c); + break; + } + } + + return c > -1; + } + + + + private void PushBack(int value) + { + if (pushback.Count == 0) + { + pushback.Add(value); + } else + { + pushback.Insert(0, value); + } + } + + + private int Read() + { + if (pushback.Count>0) + { + int i = (int)pushback[0]; + pushback.RemoveAt(0); + return i; + } + + return reader.Read(); + } + + + + + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/pem/PemReader.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/pem/PemReader.cs.meta new file mode 100644 index 0000000..9ba65f0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/pem/PemReader.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bdf30b0907f420b4189f2ceb265d26e8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/pem/PemWriter.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/pem/PemWriter.cs new file mode 100644 index 0000000..e85b315 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/pem/PemWriter.cs @@ -0,0 +1,120 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Utilities.IO.Pem +{ + /** + * A generic PEM writer, based on RFC 1421 + */ + public class PemWriter + { + private const int LineLength = 64; + + private readonly TextWriter writer; + private readonly int nlLength; + private char[] buf = new char[LineLength]; + + /** + * Base constructor. + * + * @param out output stream to use. + */ + public PemWriter(TextWriter writer) + { + if (writer == null) + throw new ArgumentNullException("writer"); + + this.writer = writer; + this.nlLength = Platform.NewLine.Length; + } + + public TextWriter Writer + { + get { return writer; } + } + + /** + * Return the number of bytes or characters required to contain the + * passed in object if it is PEM encoded. + * + * @param obj pem object to be output + * @return an estimate of the number of bytes + */ + public int GetOutputSize(PemObject obj) + { + // BEGIN and END boundaries. + int size = (2 * (obj.Type.Length + 10 + nlLength)) + 6 + 4; + + if (obj.Headers.Count > 0) + { + foreach (PemHeader header in obj.Headers) + { + size += header.Name.Length + ": ".Length + header.Value.Length + nlLength; + } + + size += nlLength; + } + + // base64 encoding + int dataLen = ((obj.Content.Length + 2) / 3) * 4; + + size += dataLen + (((dataLen + LineLength - 1) / LineLength) * nlLength); + + return size; + } + + public void WriteObject(PemObjectGenerator objGen) + { + PemObject obj = objGen.Generate(); + + WritePreEncapsulationBoundary(obj.Type); + + if (obj.Headers.Count > 0) + { + foreach (PemHeader header in obj.Headers) + { + writer.Write(header.Name); + writer.Write(": "); + writer.WriteLine(header.Value); + } + + writer.WriteLine(); + } + + WriteEncoded(obj.Content); + WritePostEncapsulationBoundary(obj.Type); + } + + private void WriteEncoded(byte[] bytes) + { + bytes = Base64.Encode(bytes); + + for (int i = 0; i < bytes.Length; i += buf.Length) + { + int index = 0; + while (index != buf.Length) + { + if ((i + index) >= bytes.Length) + break; + + buf[index] = (char)bytes[i + index]; + index++; + } + writer.WriteLine(buf, 0, index); + } + } + + private void WritePreEncapsulationBoundary(string type) + { + writer.WriteLine("-----BEGIN " + type + "-----"); + } + + private void WritePostEncapsulationBoundary(string type) + { + writer.WriteLine("-----END " + type + "-----"); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/pem/PemWriter.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/pem/PemWriter.cs.meta new file mode 100644 index 0000000..42dc62c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/io/pem/PemWriter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 11d0998bb6d5fd5408cea1ffadac9fdc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/net.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/net.meta new file mode 100644 index 0000000..b46568e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/net.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e44ac9c066216bb4dab81f926aca3d16 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/net/IPAddress.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/net/IPAddress.cs new file mode 100644 index 0000000..38c1245 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/net/IPAddress.cs @@ -0,0 +1,197 @@ +using System; +using System.Globalization; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Utilities.Net +{ + public class IPAddress + { + /** + * Validate the given IPv4 or IPv6 address. + * + * @param address the IP address as a string. + * + * @return true if a valid address, false otherwise + */ + public static bool IsValid( + string address) + { + return IsValidIPv4(address) || IsValidIPv6(address); + } + + /** + * Validate the given IPv4 or IPv6 address and netmask. + * + * @param address the IP address as a string. + * + * @return true if a valid address with netmask, false otherwise + */ + public static bool IsValidWithNetMask( + string address) + { + return IsValidIPv4WithNetmask(address) || IsValidIPv6WithNetmask(address); + } + + /** + * Validate the given IPv4 address. + * + * @param address the IP address as a string. + * + * @return true if a valid IPv4 address, false otherwise + */ + public static bool IsValidIPv4( + string address) + { + try + { + return unsafeIsValidIPv4(address); + } + catch (FormatException) {} + catch (OverflowException) {} + return false; + } + + private static bool unsafeIsValidIPv4( + string address) + { + if (address.Length == 0) + return false; + + int octets = 0; + string temp = address + "."; + + int pos; + int start = 0; + while (start < temp.Length + && (pos = temp.IndexOf('.', start)) > start) + { + if (octets == 4) + return false; + + string octetStr = temp.Substring(start, pos - start); + int octet = Int32.Parse(octetStr); + + if (octet < 0 || octet > 255) + return false; + + start = pos + 1; + octets++; + } + + return octets == 4; + } + + public static bool IsValidIPv4WithNetmask( + string address) + { + int index = address.IndexOf('/'); + string mask = address.Substring(index + 1); + + return (index > 0) && IsValidIPv4(address.Substring(0, index)) + && (IsValidIPv4(mask) || IsMaskValue(mask, 32)); + } + + public static bool IsValidIPv6WithNetmask( + string address) + { + int index = address.IndexOf('/'); + string mask = address.Substring(index + 1); + + return (index > 0) && (IsValidIPv6(address.Substring(0, index)) + && (IsValidIPv6(mask) || IsMaskValue(mask, 128))); + } + + private static bool IsMaskValue( + string component, + int size) + { + int val = Int32.Parse(component); + try + { + return val >= 0 && val <= size; + } + catch (FormatException) {} + catch (OverflowException) {} + return false; + } + + /** + * Validate the given IPv6 address. + * + * @param address the IP address as a string. + * + * @return true if a valid IPv4 address, false otherwise + */ + public static bool IsValidIPv6( + string address) + { + try + { + return unsafeIsValidIPv6(address); + } + catch (FormatException) {} + catch (OverflowException) {} + return false; + } + + private static bool unsafeIsValidIPv6( + string address) + { + if (address.Length == 0) + { + return false; + } + + int octets = 0; + + string temp = address + ":"; + bool doubleColonFound = false; + int pos; + int start = 0; + while (start < temp.Length + && (pos = temp.IndexOf(':', start)) >= start) + { + if (octets == 8) + { + return false; + } + + if (start != pos) + { + string value = temp.Substring(start, pos - start); + + if (pos == (temp.Length - 1) && value.IndexOf('.') > 0) + { + if (!IsValidIPv4(value)) + { + return false; + } + + octets++; // add an extra one as address covers 2 words. + } + else + { + string octetStr = temp.Substring(start, pos - start); + int octet = Int32.Parse(octetStr, NumberStyles.AllowHexSpecifier); + + if (octet < 0 || octet > 0xffff) + return false; + } + } + else + { + if (pos != 1 && pos != temp.Length - 1 && doubleColonFound) + { + return false; + } + doubleColonFound = true; + } + start = pos + 1; + octets++; + } + + return octets == 8 || doubleColonFound; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/net/IPAddress.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/net/IPAddress.cs.meta new file mode 100644 index 0000000..9eee5d7 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/net/IPAddress.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 022adad7c819e1e4e964886981993f55 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib.meta new file mode 100644 index 0000000..4d1e0b1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a95a3fdcf2e539147ac1e6651b3096de +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib/Adler32.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib/Adler32.cs new file mode 100644 index 0000000..c38258f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib/Adler32.cs @@ -0,0 +1,88 @@ +using System; +/* + * $Id: Adler32.cs,v 1.1 2006-07-31 13:59:25 bouncy Exp $ + * +Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +namespace Org.BouncyCastle.Utilities.Zlib { + + internal sealed class Adler32{ + + // largest prime smaller than 65536 + private const int BASE=65521; + // NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 + private const int NMAX=5552; + + internal long adler32(long adler, byte[] buf, int index, int len){ + if(buf == null){ return 1L; } + + long s1=adler&0xffff; + long s2=(adler>>16)&0xffff; + int k; + + while(len > 0) { + k=len=16){ + s1+=buf[index++]&0xff; s2+=s1; + s1+=buf[index++]&0xff; s2+=s1; + s1+=buf[index++]&0xff; s2+=s1; + s1+=buf[index++]&0xff; s2+=s1; + s1+=buf[index++]&0xff; s2+=s1; + s1+=buf[index++]&0xff; s2+=s1; + s1+=buf[index++]&0xff; s2+=s1; + s1+=buf[index++]&0xff; s2+=s1; + s1+=buf[index++]&0xff; s2+=s1; + s1+=buf[index++]&0xff; s2+=s1; + s1+=buf[index++]&0xff; s2+=s1; + s1+=buf[index++]&0xff; s2+=s1; + s1+=buf[index++]&0xff; s2+=s1; + s1+=buf[index++]&0xff; s2+=s1; + s1+=buf[index++]&0xff; s2+=s1; + s1+=buf[index++]&0xff; s2+=s1; + k-=16; + } + if(k!=0){ + do{ + s1+=buf[index++]&0xff; s2+=s1; + } + while(--k!=0); + } + s1%=BASE; + s2%=BASE; + } + return (s2<<16)|s1; + } + + } +} \ No newline at end of file diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib/Adler32.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib/Adler32.cs.meta new file mode 100644 index 0000000..d13218d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib/Adler32.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: eac2a3a25caa1ef4197d1bd38e2d84e4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib/Deflate.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib/Deflate.cs new file mode 100644 index 0000000..90f8eb0 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib/Deflate.cs @@ -0,0 +1,1634 @@ +using System; +/* + * $Id: Deflate.cs,v 1.2 2008-05-10 09:35:40 bouncy Exp $ + * +Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +namespace Org.BouncyCastle.Utilities.Zlib { + + public sealed class Deflate{ + + private const int MAX_MEM_LEVEL=9; + + private const int Z_DEFAULT_COMPRESSION=-1; + + private const int MAX_WBITS=15; // 32K LZ77 window + private const int DEF_MEM_LEVEL=8; + + internal class Config{ + internal int good_length; // reduce lazy search above this match length + internal int max_lazy; // do not perform lazy search above this match length + internal int nice_length; // quit search above this match length + internal int max_chain; + internal int func; + internal Config(int good_length, int max_lazy, + int nice_length, int max_chain, int func){ + this.good_length=good_length; + this.max_lazy=max_lazy; + this.nice_length=nice_length; + this.max_chain=max_chain; + this.func=func; + } + } + + private const int STORED=0; + private const int FAST=1; + private const int SLOW=2; + private static readonly Config[] config_table; + + static Deflate(){ + config_table=new Config[10]; + // good lazy nice chain + config_table[0]=new Config(0, 0, 0, 0, STORED); + config_table[1]=new Config(4, 4, 8, 4, FAST); + config_table[2]=new Config(4, 5, 16, 8, FAST); + config_table[3]=new Config(4, 6, 32, 32, FAST); + + config_table[4]=new Config(4, 4, 16, 16, SLOW); + config_table[5]=new Config(8, 16, 32, 32, SLOW); + config_table[6]=new Config(8, 16, 128, 128, SLOW); + config_table[7]=new Config(8, 32, 128, 256, SLOW); + config_table[8]=new Config(32, 128, 258, 1024, SLOW); + config_table[9]=new Config(32, 258, 258, 4096, SLOW); + } + + private static readonly String[] z_errmsg = { + "need dictionary", // Z_NEED_DICT 2 + "stream end", // Z_STREAM_END 1 + "", // Z_OK 0 + "file error", // Z_ERRNO (-1) + "stream error", // Z_STREAM_ERROR (-2) + "data error", // Z_DATA_ERROR (-3) + "insufficient memory", // Z_MEM_ERROR (-4) + "buffer error", // Z_BUF_ERROR (-5) + "incompatible version",// Z_VERSION_ERROR (-6) + "" + }; + + // block not completed, need more input or more output + private const int NeedMore=0; + + // block flush performed + private const int BlockDone=1; + + // finish started, need only more output at next deflate + private const int FinishStarted=2; + + // finish done, accept no more input or output + private const int FinishDone=3; + + // preset dictionary flag in zlib header + private const int PRESET_DICT=0x20; + + private const int Z_FILTERED=1; + private const int Z_HUFFMAN_ONLY=2; + private const int Z_DEFAULT_STRATEGY=0; + + private const int Z_NO_FLUSH=0; + private const int Z_PARTIAL_FLUSH=1; + private const int Z_SYNC_FLUSH=2; + private const int Z_FULL_FLUSH=3; + private const int Z_FINISH=4; + + private const int Z_OK=0; + private const int Z_STREAM_END=1; + private const int Z_NEED_DICT=2; + private const int Z_ERRNO=-1; + private const int Z_STREAM_ERROR=-2; + private const int Z_DATA_ERROR=-3; + private const int Z_MEM_ERROR=-4; + private const int Z_BUF_ERROR=-5; + private const int Z_VERSION_ERROR=-6; + + private const int INIT_STATE=42; + private const int BUSY_STATE=113; + private const int FINISH_STATE=666; + + // The deflate compression method + private const int Z_DEFLATED=8; + + private const int STORED_BLOCK=0; + private const int STATIC_TREES=1; + private const int DYN_TREES=2; + + // The three kinds of block type + private const int Z_BINARY=0; + private const int Z_ASCII=1; + private const int Z_UNKNOWN=2; + + private const int Buf_size=8*2; + + // repeat previous bit length 3-6 times (2 bits of repeat count) + private const int REP_3_6=16; + + // repeat a zero length 3-10 times (3 bits of repeat count) + private const int REPZ_3_10=17; + + // repeat a zero length 11-138 times (7 bits of repeat count) + private const int REPZ_11_138=18; + + private const int MIN_MATCH=3; + private const int MAX_MATCH=258; + private const int MIN_LOOKAHEAD=(MAX_MATCH+MIN_MATCH+1); + + private const int MAX_BITS=15; + private const int D_CODES=30; + private const int BL_CODES=19; + private const int LENGTH_CODES=29; + private const int LITERALS=256; + private const int L_CODES=(LITERALS+1+LENGTH_CODES); + private const int HEAP_SIZE=(2*L_CODES+1); + + private const int END_BLOCK=256; + + internal ZStream strm; // pointer back to this zlib stream + internal int status; // as the name implies + internal byte[] pending_buf; // output still pending + internal int pending_out; // next pending byte to output to the stream + internal int pending; // nb of bytes in the pending buffer + internal int noheader; // suppress zlib header and adler32 + internal byte data_type; // UNKNOWN, BINARY or ASCII + internal byte method; // STORED (for zip only) or DEFLATED + internal int last_flush; // value of flush param for previous deflate call + + internal int w_size; // LZ77 window size (32K by default) + internal int w_bits; // log2(w_size) (8..16) + internal int w_mask; // w_size - 1 + + internal byte[] window; + // Sliding window. Input bytes are read into the second half of the window, + // and move to the first half later to keep a dictionary of at least wSize + // bytes. With this organization, matches are limited to a distance of + // wSize-MAX_MATCH bytes, but this ensures that IO is always + // performed with a length multiple of the block size. Also, it limits + // the window size to 64K, which is quite useful on MSDOS. + // To do: use the user input buffer as sliding window. + + internal int window_size; + // Actual size of window: 2*wSize, except when the user input buffer + // is directly used as sliding window. + + internal short[] prev; + // Link to older string with same hash index. To limit the size of this + // array to 64K, this link is maintained only for the last 32K strings. + // An index in this array is thus a window index modulo 32K. + + internal short[] head; // Heads of the hash chains or NIL. + + internal int ins_h; // hash index of string to be inserted + internal int hash_size; // number of elements in hash table + internal int hash_bits; // log2(hash_size) + internal int hash_mask; // hash_size-1 + + // Number of bits by which ins_h must be shifted at each input + // step. It must be such that after MIN_MATCH steps, the oldest + // byte no longer takes part in the hash key, that is: + // hash_shift * MIN_MATCH >= hash_bits + internal int hash_shift; + + // Window position at the beginning of the current output block. Gets + // negative when the window is moved backwards. + + internal int block_start; + + internal int match_length; // length of best match + internal int prev_match; // previous match + internal int match_available; // set if previous match exists + internal int strstart; // start of string to insert + internal int match_start; // start of matching string + internal int lookahead; // number of valid bytes ahead in window + + // Length of the best match at previous step. Matches not greater than this + // are discarded. This is used in the lazy match evaluation. + internal int prev_length; + + // To speed up deflation, hash chains are never searched beyond this + // length. A higher limit improves compression ratio but degrades the speed. + internal int max_chain_length; + + // Attempt to find a better match only when the current match is strictly + // smaller than this value. This mechanism is used only for compression + // levels >= 4. + internal int max_lazy_match; + + // Insert new strings in the hash table only if the match length is not + // greater than this length. This saves time but degrades compression. + // max_insert_length is used only for compression levels <= 3. + + internal int level; // compression level (1..9) + internal int strategy; // favor or force Huffman coding + + // Use a faster search when the previous match is longer than this + internal int good_match; + + // Stop searching when current match exceeds this + internal int nice_match; + + internal short[] dyn_ltree; // literal and length tree + internal short[] dyn_dtree; // distance tree + internal short[] bl_tree; // Huffman tree for bit lengths + + internal Tree l_desc=new Tree(); // desc for literal tree + internal Tree d_desc=new Tree(); // desc for distance tree + internal Tree bl_desc=new Tree(); // desc for bit length tree + + // number of codes at each bit length for an optimal tree + internal short[] bl_count=new short[MAX_BITS+1]; + + // heap used to build the Huffman trees + internal int[] heap=new int[2*L_CODES+1]; + + internal int heap_len; // number of elements in the heap + internal int heap_max; // element of largest frequency + // The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + // The same heap array is used to build all trees. + + // Depth of each subtree used as tie breaker for trees of equal frequency + internal byte[] depth=new byte[2*L_CODES+1]; + + internal int l_buf; // index for literals or lengths */ + + // Size of match buffer for literals/lengths. There are 4 reasons for + // limiting lit_bufsize to 64K: + // - frequencies can be kept in 16 bit counters + // - if compression is not successful for the first block, all input + // data is still in the window so we can still emit a stored block even + // when input comes from standard input. (This can also be done for + // all blocks if lit_bufsize is not greater than 32K.) + // - if compression is not successful for a file smaller than 64K, we can + // even emit a stored file instead of a stored block (saving 5 bytes). + // This is applicable only for zip (not gzip or zlib). + // - creating new Huffman trees less frequently may not provide fast + // adaptation to changes in the input data statistics. (Take for + // example a binary file with poorly compressible code followed by + // a highly compressible string table.) Smaller buffer sizes give + // fast adaptation but have of course the overhead of transmitting + // trees more frequently. + // - I can't count above 4 + internal int lit_bufsize; + + internal int last_lit; // running index in l_buf + + // Buffer for distances. To simplify the code, d_buf and l_buf have + // the same number of elements. To use different lengths, an extra flag + // array would be necessary. + + internal int d_buf; // index of pendig_buf + + internal int opt_len; // bit length of current block with optimal trees + internal int static_len; // bit length of current block with static trees + internal int matches; // number of string matches in current block + internal int last_eob_len; // bit length of EOB code for last block + + // Output buffer. bits are inserted starting at the bottom (least + // significant bits). + internal uint bi_buf; + + // Number of valid bits in bi_buf. All bits above the last valid bit + // are always zero. + internal int bi_valid; + + internal Deflate(){ + dyn_ltree=new short[HEAP_SIZE*2]; + dyn_dtree=new short[(2*D_CODES+1)*2]; // distance tree + bl_tree=new short[(2*BL_CODES+1)*2]; // Huffman tree for bit lengths + } + + internal void lm_init() { + window_size=2*w_size; + + head[hash_size-1]=0; + for(int i=0; i= 3; max_blindex--) { + if (bl_tree[Tree.bl_order[max_blindex]*2+1] != 0) break; + } + // Update opt_len to include the bit length tree and counts + opt_len += 3*(max_blindex+1) + 5+5+4; + + return max_blindex; + } + + + // Send the header for a block using dynamic Huffman trees: the counts, the + // lengths of the bit length codes, the literal tree and the distance tree. + // IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + internal void send_all_trees(int lcodes, int dcodes, int blcodes){ + int rank; // index in bl_order + + send_bits(lcodes-257, 5); // not +255 as stated in appnote.txt + send_bits(dcodes-1, 5); + send_bits(blcodes-4, 4); // not -3 as stated in appnote.txt + for (rank = 0; rank < blcodes; rank++) { + send_bits(bl_tree[Tree.bl_order[rank]*2+1], 3); + } + send_tree(dyn_ltree, lcodes-1); // literal tree + send_tree(dyn_dtree, dcodes-1); // distance tree + } + + // Send a literal or distance tree in compressed form, using the codes in + // bl_tree. + internal void send_tree (short[] tree,// the tree to be sent + int max_code // and its largest code of non zero frequency + ){ + int n; // iterates over all tree elements + int prevlen = -1; // last emitted length + int curlen; // length of current code + int nextlen = tree[0*2+1]; // length of next code + int count = 0; // repeat count of the current code + int max_count = 7; // max repeat count + int min_count = 4; // min repeat count + + if (nextlen == 0){ max_count = 138; min_count = 3; } + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[(n+1)*2+1]; + if(++count < max_count && curlen == nextlen) { + continue; + } + else if(count < min_count) { + do { send_code(curlen, bl_tree); } while (--count != 0); + } + else if(curlen != 0){ + if(curlen != prevlen){ + send_code(curlen, bl_tree); count--; + } + send_code(REP_3_6, bl_tree); + send_bits(count-3, 2); + } + else if(count <= 10){ + send_code(REPZ_3_10, bl_tree); + send_bits(count-3, 3); + } + else{ + send_code(REPZ_11_138, bl_tree); + send_bits(count-11, 7); + } + count = 0; prevlen = curlen; + if(nextlen == 0){ + max_count = 138; min_count = 3; + } + else if(curlen == nextlen){ + max_count = 6; min_count = 3; + } + else{ + max_count = 7; min_count = 4; + } + } + } + + // Output a byte on the stream. + // IN assertion: there is enough room in pending_buf. + internal void put_byte(byte[] p, int start, int len){ + System.Array.Copy(p, start, pending_buf, pending, len); + pending+=len; + } + + internal void put_byte(byte c){ + pending_buf[pending++]=c; + } + internal void put_short(int w) { + pending_buf[pending++]=(byte)(w/*&0xff*/); + pending_buf[pending++]=(byte)(w>>8); + } + internal void putShortMSB(int b){ + pending_buf[pending++]=(byte)(b>>8); + pending_buf[pending++]=(byte)(b/*&0xff*/); + } + + internal void send_code(int c, short[] tree){ + int c2=c*2; + send_bits((tree[c2]&0xffff), (tree[c2+1]&0xffff)); + } + + internal void send_bits(int val, int length){ + if (bi_valid > Buf_size - length) { + bi_buf |= (uint)(val << bi_valid); + pending_buf[pending++]=(byte)(bi_buf/*&0xff*/); + pending_buf[pending++]=(byte)(bi_buf>>8); + bi_buf = ((uint)val) >> (Buf_size - bi_valid); + bi_valid += length - Buf_size; + } else { + bi_buf |= (uint)(val << bi_valid); + bi_valid += length; + } +// int len = length; +// if (bi_valid > (int)Buf_size - len) { +// int val = value; +// // bi_buf |= (val << bi_valid); +// bi_buf = (short)((ushort)bi_buf | (ushort)((val << bi_valid)&0xffff)); +// put_short(bi_buf); +// bi_buf = (short)(((uint)val) >> (Buf_size - bi_valid)); +// bi_valid += len - Buf_size; +// } else { +// // bi_buf |= (value) << bi_valid; +// bi_buf = (short)((ushort)bi_buf | (ushort)(((value) << bi_valid)&0xffff)); +// bi_valid += len; +// } + } + + // Send one empty static block to give enough lookahead for inflate. + // This takes 10 bits, of which 7 may remain in the bit buffer. + // The current inflate code requires 9 bits of lookahead. If the + // last two codes for the previous block (real code plus EOB) were coded + // on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode + // the last real code. In this case we send two empty static blocks instead + // of one. (There are no problems if the previous block is stored or fixed.) + // To simplify the code, we assume the worst case of last real code encoded + // on one bit only. + internal void _tr_align(){ + send_bits(STATIC_TREES<<1, 3); + send_code(END_BLOCK, StaticTree.static_ltree); + + bi_flush(); + + // Of the 10 bits for the empty block, we have already sent + // (10 - bi_valid) bits. The lookahead for the last real code (before + // the EOB of the previous block) was thus at least one plus the length + // of the EOB plus what we have just sent of the empty static block. + if (1 + last_eob_len + 10 - bi_valid < 9) { + send_bits(STATIC_TREES<<1, 3); + send_code(END_BLOCK, StaticTree.static_ltree); + bi_flush(); + } + last_eob_len = 7; + } + + + // Save the match info and tally the frequency counts. Return true if + // the current block must be flushed. + internal bool _tr_tally (int dist, // distance of matched string + int lc // match length-MIN_MATCH or unmatched char (if dist==0) + ){ + + pending_buf[d_buf+last_lit*2] = (byte)(dist>>8); + pending_buf[d_buf+last_lit*2+1] = (byte)dist; + + pending_buf[l_buf+last_lit] = (byte)lc; last_lit++; + + if (dist == 0) { + // lc is the unmatched char + dyn_ltree[lc*2]++; + } + else { + matches++; + // Here, lc is the match length - MIN_MATCH + dist--; // dist = match distance - 1 + dyn_ltree[(Tree._length_code[lc]+LITERALS+1)*2]++; + dyn_dtree[Tree.d_code(dist)*2]++; + } + + if ((last_lit & 0x1fff) == 0 && level > 2) { + // Compute an upper bound for the compressed length + int out_length = last_lit*8; + int in_length = strstart - block_start; + int dcode; + for (dcode = 0; dcode < D_CODES; dcode++) { + out_length += (int)((int)dyn_dtree[dcode*2] * + (5L+Tree.extra_dbits[dcode])); + } + out_length >>= 3; + if ((matches < (last_lit/2)) && out_length < in_length/2) return true; + } + + return (last_lit == lit_bufsize-1); + // We avoid equality with lit_bufsize because of wraparound at 64K + // on 16 bit machines and because stored blocks are restricted to + // 64K-1 bytes. + } + + // Send the block data compressed using the given Huffman trees + internal void compress_block(short[] ltree, short[] dtree){ + int dist; // distance of matched string + int lc; // match length or unmatched char (if dist == 0) + int lx = 0; // running index in l_buf + int code; // the code to send + int extra; // number of extra bits to send + + if (last_lit != 0){ + do{ + dist=((pending_buf[d_buf+lx*2]<<8)&0xff00)| + (pending_buf[d_buf+lx*2+1]&0xff); + lc=(pending_buf[l_buf+lx])&0xff; lx++; + + if(dist == 0){ + send_code(lc, ltree); // send a literal byte + } + else{ + // Here, lc is the match length - MIN_MATCH + code = Tree._length_code[lc]; + + send_code(code+LITERALS+1, ltree); // send the length code + extra = Tree.extra_lbits[code]; + if(extra != 0){ + lc -= Tree.base_length[code]; + send_bits(lc, extra); // send the extra length bits + } + dist--; // dist is now the match distance - 1 + code = Tree.d_code(dist); + + send_code(code, dtree); // send the distance code + extra = Tree.extra_dbits[code]; + if (extra != 0) { + dist -= Tree.base_dist[code]; + send_bits(dist, extra); // send the extra distance bits + } + } // literal or match pair ? + + // Check that the overlay between pending_buf and d_buf+l_buf is ok: + } + while (lx < last_lit); + } + + send_code(END_BLOCK, ltree); + last_eob_len = ltree[END_BLOCK*2+1]; + } + + // Set the data type to ASCII or BINARY, using a crude approximation: + // binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise. + // IN assertion: the fields freq of dyn_ltree are set and the total of all + // frequencies does not exceed 64K (to fit in an int on 16 bit machines). + internal void set_data_type(){ + int n = 0; + int ascii_freq = 0; + int bin_freq = 0; + while(n<7){ bin_freq += dyn_ltree[n*2]; n++;} + while(n<128){ ascii_freq += dyn_ltree[n*2]; n++;} + while(n (ascii_freq >> 2) ? Z_BINARY : Z_ASCII); + } + + // Flush the bit buffer, keeping at most 7 bits in it. + internal void bi_flush(){ + if (bi_valid == 16) { + pending_buf[pending++]=(byte)(bi_buf/*&0xff*/); + pending_buf[pending++]=(byte)(bi_buf>>8); + bi_buf=0; + bi_valid=0; + } + else if (bi_valid >= 8) { + pending_buf[pending++]=(byte)(bi_buf); + bi_buf>>=8; + bi_buf &= 0x00ff; + bi_valid-=8; + } + } + + // Flush the bit buffer and align the output on a byte boundary + internal void bi_windup(){ + if (bi_valid > 8) { + pending_buf[pending++]=(byte)(bi_buf); + pending_buf[pending++]=(byte)(bi_buf>>8); + } else if (bi_valid > 0) { + pending_buf[pending++]=(byte)(bi_buf); + } + bi_buf = 0; + bi_valid = 0; + } + + // Copy a stored block, storing first the length and its + // one's complement if requested. + internal void copy_block(int buf, // the input data + int len, // its length + bool header // true if block header must be written + ){ + //int index=0; + bi_windup(); // align on byte boundary + last_eob_len = 8; // enough lookahead for inflate + + if (header) { + put_short((short)len); + put_short((short)~len); + } + + // while(len--!=0) { + // put_byte(window[buf+index]); + // index++; + // } + put_byte(window, buf, len); + } + + internal void flush_block_only(bool eof){ + _tr_flush_block(block_start>=0 ? block_start : -1, + strstart-block_start, + eof); + block_start=strstart; + strm.flush_pending(); + } + + // Copy without compression as much as possible from the input stream, return + // the current block state. + // This function does not insert new strings in the dictionary since + // uncompressible data is probably not useful. This function is used + // only for the level=0 compression option. + // NOTE: this function should be optimized to avoid extra copying from + // window to pending_buf. + internal int deflate_stored(int flush){ + // Stored blocks are limited to 0xffff bytes, pending_buf is limited + // to pending_buf_size, and each stored block has a 5 byte header: + + int max_block_size = System.Math.Min(0xffff, pending_buf.Length - 5); + int max_start; + + // Copy as much as possible from input to output: + while(true){ + // Fill the window as much as possible: + if(lookahead<=1){ + fill_window(); + if(lookahead==0 && flush==Z_NO_FLUSH) return NeedMore; + if(lookahead==0) break; // flush the current block + } + + strstart+=lookahead; + lookahead=0; + + // Emit a stored block if pending_buf will be full: + max_start=block_start+max_block_size; + if(strstart==0|| strstart>=max_start) { + // strstart == 0 is possible when wraparound on 16-bit machine + lookahead = (int)(strstart-max_start); + strstart = (int)max_start; + + flush_block_only(false); + if(strm.avail_out==0) return NeedMore; + + } + + // Flush if we may have to slide, otherwise block_start may become + // negative and the data will be gone: + if(strstart-block_start >= w_size-MIN_LOOKAHEAD) { + flush_block_only(false); + if(strm.avail_out==0) return NeedMore; + } + } + + flush_block_only(flush == Z_FINISH); + if(strm.avail_out==0) + return (flush == Z_FINISH) ? FinishStarted : NeedMore; + + return flush == Z_FINISH ? FinishDone : BlockDone; + } + + // Send a stored block + internal void _tr_stored_block(int buf, // input block + int stored_len, // length of input block + bool eof // true if this is the last block for a file + ){ + send_bits((STORED_BLOCK<<1)+(eof?1:0), 3); // send block type + copy_block(buf, stored_len, true); // with header + } + + // Determine the best encoding for the current block: dynamic trees, static + // trees or store, and output the encoded block to the zip file. + internal void _tr_flush_block(int buf, // input block, or NULL if too old + int stored_len, // length of input block + bool eof // true if this is the last block for a file + ) { + int opt_lenb, static_lenb;// opt_len and static_len in bytes + int max_blindex = 0; // index of last bit length code of non zero freq + + // Build the Huffman trees unless a stored block is forced + if(level > 0) { + // Check if the file is ascii or binary + if(data_type == Z_UNKNOWN) set_data_type(); + + // Construct the literal and distance trees + l_desc.build_tree(this); + + d_desc.build_tree(this); + + // At this point, opt_len and static_len are the total bit lengths of + // the compressed block data, excluding the tree representations. + + // Build the bit length tree for the above two trees, and get the index + // in bl_order of the last bit length code to send. + max_blindex=build_bl_tree(); + + // Determine the best encoding. Compute first the block length in bytes + opt_lenb=(opt_len+3+7)>>3; + static_lenb=(static_len+3+7)>>3; + + if(static_lenb<=opt_lenb) opt_lenb=static_lenb; + } + else { + opt_lenb=static_lenb=stored_len+5; // force a stored block + } + + if(stored_len+4<=opt_lenb && buf != -1){ + // 4: two words for the lengths + // The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + // Otherwise we can't have processed more than WSIZE input bytes since + // the last block flush, because compression would have been + // successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + // transform a block into a stored block. + _tr_stored_block(buf, stored_len, eof); + } + else if(static_lenb == opt_lenb){ + send_bits((STATIC_TREES<<1)+(eof?1:0), 3); + compress_block(StaticTree.static_ltree, StaticTree.static_dtree); + } + else{ + send_bits((DYN_TREES<<1)+(eof?1:0), 3); + send_all_trees(l_desc.max_code+1, d_desc.max_code+1, max_blindex+1); + compress_block(dyn_ltree, dyn_dtree); + } + + // The above check is made mod 2^32, for files larger than 512 MB + // and uLong implemented on 32 bits. + + init_block(); + + if(eof){ + bi_windup(); + } + } + + // Fill the window when the lookahead becomes insufficient. + // Updates strstart and lookahead. + // + // IN assertion: lookahead < MIN_LOOKAHEAD + // OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + // At least one byte has been read, or avail_in == 0; reads are + // performed for at least two bytes (required for the zip translate_eol + // option -- not supported here). + internal void fill_window(){ + int n, m; + int p; + int more; // Amount of free space at the end of the window. + + do{ + more = (window_size-lookahead-strstart); + + // Deal with !@#$% 64K limit: + if(more==0 && strstart==0 && lookahead==0){ + more = w_size; + } + else if(more==-1) { + // Very unlikely, but possible on 16 bit machine if strstart == 0 + // and lookahead == 1 (input done one byte at time) + more--; + + // If the window is almost full and there is insufficient lookahead, + // move the upper half to the lower one to make room in the upper half. + } + else if(strstart >= w_size+ w_size-MIN_LOOKAHEAD) { + System.Array.Copy(window, w_size, window, 0, w_size); + match_start-=w_size; + strstart-=w_size; // we now have strstart >= MAX_DIST + block_start-=w_size; + + // Slide the hash table (could be avoided with 32 bit values + // at the expense of memory usage). We slide even when level == 0 + // to keep the hash table consistent if we switch back to level > 0 + // later. (Using level 0 permanently is not an optimal usage of + // zlib, so we don't care about this pathological case.) + + n = hash_size; + p=n; + do { + m = (head[--p]&0xffff); + head[p]=(short)(m>=w_size ? (m-w_size) : 0); + } + while (--n != 0); + + n = w_size; + p = n; + do { + m = (prev[--p]&0xffff); + prev[p] = (short)(m >= w_size ? (m-w_size) : 0); + // If n is not on any hash chain, prev[n] is garbage but + // its value will never be used. + } + while (--n!=0); + more += w_size; + } + + if (strm.avail_in == 0) return; + + // If there was no sliding: + // strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + // more == window_size - lookahead - strstart + // => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + // => more >= window_size - 2*WSIZE + 2 + // In the BIG_MEM or MMAP case (not yet supported), + // window_size == input_size + MIN_LOOKAHEAD && + // strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + // Otherwise, window_size == 2*WSIZE so more >= 2. + // If there was sliding, more >= WSIZE. So in all cases, more >= 2. + + n = strm.read_buf(window, strstart + lookahead, more); + lookahead += n; + + // Initialize the hash value now that we have some input: + if(lookahead >= MIN_MATCH) { + ins_h = window[strstart]&0xff; + ins_h=(((ins_h)<= MIN_MATCH){ + ins_h=(((ins_h)<=MIN_MATCH){ + // check_match(strstart, match_start, match_length); + + bflush=_tr_tally(strstart-match_start, match_length-MIN_MATCH); + + lookahead -= match_length; + + // Insert new strings in the hash table only if the match length + // is not too large. This saves time but degrades compression. + if(match_length <= max_lazy_match && + lookahead >= MIN_MATCH) { + match_length--; // string at strstart already in hash table + do{ + strstart++; + + ins_h=((ins_h<= MIN_MATCH) { + ins_h=(((ins_h)< 4096))) { + + // If prev_match is also MIN_MATCH, match_start is garbage + // but we will ignore the current match anyway. + match_length = MIN_MATCH-1; + } + } + + // If there was a match at the previous step and the current + // match is not better, output the previous match: + if(prev_length >= MIN_MATCH && match_length <= prev_length) { + int max_insert = strstart + lookahead - MIN_MATCH; + // Do not insert strings in hash table beyond this. + + // check_match(strstart-1, prev_match, prev_length); + + bflush=_tr_tally(strstart-1-prev_match, prev_length - MIN_MATCH); + + // Insert in hash table all strings up to the end of the match. + // strstart-1 and strstart are already inserted. If there is not + // enough lookahead, the last two strings are not inserted in + // the hash table. + lookahead -= prev_length-1; + prev_length -= 2; + do{ + if(++strstart <= max_insert) { + ins_h=(((ins_h)<(w_size-MIN_LOOKAHEAD) ? + strstart-(w_size-MIN_LOOKAHEAD) : 0; + int nice_match=this.nice_match; + + // Stop when cur_match becomes <= limit. To simplify the code, + // we prevent matches with the string of window index 0. + + int wmask = w_mask; + + int strend = strstart + MAX_MATCH; + byte scan_end1 = window[scan+best_len-1]; + byte scan_end = window[scan+best_len]; + + // The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + // It is easy to get rid of this optimization if necessary. + + // Do not waste too much time if we already have a good match: + if (prev_length >= good_match) { + chain_length >>= 2; + } + + // Do not look for matches beyond the end of the input. This is necessary + // to make deflate deterministic. + if (nice_match > lookahead) nice_match = lookahead; + + do { + match = cur_match; + + // Skip to next match if the match length cannot increase + // or if the match length is less than 2: + if (window[match+best_len] != scan_end || + window[match+best_len-1] != scan_end1 || + window[match] != window[scan] || + window[++match] != window[scan+1]) continue; + + // The check at best_len-1 can be removed because it will be made + // again later. (This heuristic is not always a win.) + // It is not necessary to compare scan[2] and match[2] since they + // are always equal when the other bytes match, given that + // the hash keys are equal and that HASH_BITS >= 8. + scan += 2; match++; + + // We check for insufficient lookahead only every 8th comparison; + // the 256th check will be made at strstart+258. + do { + } while (window[++scan] == window[++match] && + window[++scan] == window[++match] && + window[++scan] == window[++match] && + window[++scan] == window[++match] && + window[++scan] == window[++match] && + window[++scan] == window[++match] && + window[++scan] == window[++match] && + window[++scan] == window[++match] && + scan < strend); + + len = MAX_MATCH - (int)(strend - scan); + scan = strend - MAX_MATCH; + + if(len>best_len) { + match_start = cur_match; + best_len = len; + if (len >= nice_match) break; + scan_end1 = window[scan+best_len-1]; + scan_end = window[scan+best_len]; + } + + } while ((cur_match = (prev[cur_match & wmask]&0xffff)) > limit + && --chain_length != 0); + + if (best_len <= lookahead) return best_len; + return lookahead; + } + + internal int deflateInit(ZStream strm, int level, int bits){ + return deflateInit2(strm, level, Z_DEFLATED, bits, DEF_MEM_LEVEL, + Z_DEFAULT_STRATEGY); + } + internal int deflateInit(ZStream strm, int level){ + return deflateInit(strm, level, MAX_WBITS); + } + internal int deflateInit2(ZStream strm, int level, int method, int windowBits, + int memLevel, int strategy){ + int noheader = 0; + // byte[] my_version=ZLIB_VERSION; + + // + // if (version == null || version[0] != my_version[0] + // || stream_size != sizeof(z_stream)) { + // return Z_VERSION_ERROR; + // } + + strm.msg = null; + + if (level == Z_DEFAULT_COMPRESSION) level = 6; + + if (windowBits < 0) { // undocumented feature: suppress zlib header + noheader = 1; + windowBits = -windowBits; + } + + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || + method != Z_DEFLATED || + windowBits < 9 || windowBits > 15 || level < 0 || level > 9 || + strategy < 0 || strategy > Z_HUFFMAN_ONLY) { + return Z_STREAM_ERROR; + } + + strm.dstate = (Deflate)this; + + this.noheader = noheader; + w_bits = windowBits; + w_size = 1 << w_bits; + w_mask = w_size - 1; + + hash_bits = memLevel + 7; + hash_size = 1 << hash_bits; + hash_mask = hash_size - 1; + hash_shift = ((hash_bits+MIN_MATCH-1)/MIN_MATCH); + + window = new byte[w_size*2]; + prev = new short[w_size]; + head = new short[hash_size]; + + lit_bufsize = 1 << (memLevel + 6); // 16K elements by default + + // We overlay pending_buf and d_buf+l_buf. This works since the average + // output size for (length,distance) codes is <= 24 bits. + pending_buf = new byte[lit_bufsize*4]; + + d_buf = lit_bufsize; + l_buf = (1+2)*lit_bufsize; + + this.level = level; + + //System.out.println("level="+level); + + this.strategy = strategy; + this.method = (byte)method; + + return deflateReset(strm); + } + + internal int deflateReset(ZStream strm){ + strm.total_in = strm.total_out = 0; + strm.msg = null; // + strm.data_type = Z_UNKNOWN; + + pending = 0; + pending_out = 0; + + if(noheader < 0) { + noheader = 0; // was set to -1 by deflate(..., Z_FINISH); + } + status = (noheader!=0) ? BUSY_STATE : INIT_STATE; + strm.adler=strm._adler.adler32(0, null, 0, 0); + + last_flush = Z_NO_FLUSH; + + tr_init(); + lm_init(); + return Z_OK; + } + + internal int deflateEnd(){ + if(status!=INIT_STATE && status!=BUSY_STATE && status!=FINISH_STATE){ + return Z_STREAM_ERROR; + } + // Deallocate in reverse order of allocations: + pending_buf=null; + head=null; + prev=null; + window=null; + // free + // dstate=null; + return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; + } + + internal int deflateParams(ZStream strm, int _level, int _strategy){ + int err=Z_OK; + + if(_level == Z_DEFAULT_COMPRESSION){ + _level = 6; + } + if(_level < 0 || _level > 9 || + _strategy < 0 || _strategy > Z_HUFFMAN_ONLY) { + return Z_STREAM_ERROR; + } + + if(config_table[level].func!=config_table[_level].func && + strm.total_in != 0) { + // Flush the last buffer: + err = strm.deflate(Z_PARTIAL_FLUSH); + } + + if(level != _level) { + level = _level; + max_lazy_match = config_table[level].max_lazy; + good_match = config_table[level].good_length; + nice_match = config_table[level].nice_length; + max_chain_length = config_table[level].max_chain; + } + strategy = _strategy; + return err; + } + + internal int deflateSetDictionary (ZStream strm, byte[] dictionary, int dictLength){ + int length = dictLength; + int index=0; + + if(dictionary == null || status != INIT_STATE) + return Z_STREAM_ERROR; + + strm.adler=strm._adler.adler32(strm.adler, dictionary, 0, dictLength); + + if(length < MIN_MATCH) return Z_OK; + if(length > w_size-MIN_LOOKAHEAD){ + length = w_size-MIN_LOOKAHEAD; + index=dictLength-length; // use the tail of the dictionary + } + System.Array.Copy(dictionary, index, window, 0, length); + strstart = length; + block_start = length; + + // Insert all strings in the hash table (except for the last two bytes). + // s->lookahead stays null, so s->ins_h will be recomputed at the next + // call of fill_window. + + ins_h = window[0]&0xff; + ins_h=(((ins_h)<Z_FINISH || flush<0){ + return Z_STREAM_ERROR; + } + + if(strm.next_out == null || + (strm.next_in == null && strm.avail_in != 0) || + (status == FINISH_STATE && flush != Z_FINISH)) { + strm.msg=z_errmsg[Z_NEED_DICT-(Z_STREAM_ERROR)]; + return Z_STREAM_ERROR; + } + if(strm.avail_out == 0){ + strm.msg=z_errmsg[Z_NEED_DICT-(Z_BUF_ERROR)]; + return Z_BUF_ERROR; + } + + this.strm = strm; // just in case + old_flush = last_flush; + last_flush = flush; + + // Write the zlib header + if(status == INIT_STATE) { + int header = (Z_DEFLATED+((w_bits-8)<<4))<<8; + int level_flags=((level-1)&0xff)>>1; + + if(level_flags>3) level_flags=3; + header |= (level_flags<<6); + if(strstart!=0) header |= PRESET_DICT; + header+=31-(header % 31); + + status=BUSY_STATE; + putShortMSB(header); + + + // Save the adler32 of the preset dictionary: + if(strstart!=0){ + putShortMSB((int)(strm.adler>>16)); + putShortMSB((int)(strm.adler&0xffff)); + } + strm.adler=strm._adler.adler32(0, null, 0, 0); + } + + // Flush as much pending output as possible + if(pending != 0) { + strm.flush_pending(); + if(strm.avail_out == 0) { + //System.out.println(" avail_out==0"); + // Since avail_out is 0, deflate will be called again with + // more output space, but possibly with both pending and + // avail_in equal to zero. There won't be anything to do, + // but this is not an error situation so make sure we + // return OK instead of BUF_ERROR at next call of deflate: + last_flush = -1; + return Z_OK; + } + + // Make sure there is something to do and avoid duplicate consecutive + // flushes. For repeated and useless calls with Z_FINISH, we keep + // returning Z_STREAM_END instead of Z_BUFF_ERROR. + } + else if(strm.avail_in==0 && flush <= old_flush && + flush != Z_FINISH) { + strm.msg=z_errmsg[Z_NEED_DICT-(Z_BUF_ERROR)]; + return Z_BUF_ERROR; + } + + // User must not provide more input after the first FINISH: + if(status == FINISH_STATE && strm.avail_in != 0) { + strm.msg=z_errmsg[Z_NEED_DICT-(Z_BUF_ERROR)]; + return Z_BUF_ERROR; + } + + // Start a new block or continue the current one. + if(strm.avail_in!=0 || lookahead!=0 || + (flush != Z_NO_FLUSH && status != FINISH_STATE)) { + int bstate=-1; + switch(config_table[level].func){ + case STORED: + bstate = deflate_stored(flush); + break; + case FAST: + bstate = deflate_fast(flush); + break; + case SLOW: + bstate = deflate_slow(flush); + break; + default: + break; + } + + if (bstate==FinishStarted || bstate==FinishDone) { + status = FINISH_STATE; + } + if (bstate==NeedMore || bstate==FinishStarted) { + if(strm.avail_out == 0) { + last_flush = -1; // avoid BUF_ERROR next call, see above + } + return Z_OK; + // If flush != Z_NO_FLUSH && avail_out == 0, the next call + // of deflate should use the same flush parameter to make sure + // that the flush is complete. So we don't have to output an + // empty block here, this will be done at next call. This also + // ensures that for a very small output buffer, we emit at most + // one empty block. + } + + if (bstate==BlockDone) { + if(flush == Z_PARTIAL_FLUSH) { + _tr_align(); + } + else { // FULL_FLUSH or SYNC_FLUSH + _tr_stored_block(0, 0, false); + // For a full flush, this empty block will be recognized + // as a special marker by inflate_sync(). + if(flush == Z_FULL_FLUSH) { + //state.head[s.hash_size-1]=0; + for(int i=0; i>16)); + putShortMSB((int)(strm.adler&0xffff)); + strm.flush_pending(); + + // If avail_out is zero, the application will call deflate again + // to flush the rest. + noheader = -1; // write the trailer only once! + return pending != 0 ? Z_OK : Z_STREAM_END; + } + } +} \ No newline at end of file diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib/Deflate.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib/Deflate.cs.meta new file mode 100644 index 0000000..1357b56 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib/Deflate.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: eca196d3673d79f468ff9909e664b2fe +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib/InfBlocks.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib/InfBlocks.cs new file mode 100644 index 0000000..479d9b5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib/InfBlocks.cs @@ -0,0 +1,618 @@ +using System; +/* + * $Id: InfBlocks.cs,v 1.2 2008-05-10 09:35:40 bouncy Exp $ + * +Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +namespace Org.BouncyCastle.Utilities.Zlib { + + internal sealed class InfBlocks{ + private const int MANY=1440; + + // And'ing with mask[n] masks the lower n bits + private static readonly int[] inflate_mask = { + 0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f, + 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff, + 0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff, + 0x00007fff, 0x0000ffff + }; + + // Table for deflate from PKZIP's appnote.txt. + static readonly int[] border = { // Order of the bit length code lengths + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 + }; + + private const int Z_OK=0; + private const int Z_STREAM_END=1; + private const int Z_NEED_DICT=2; + private const int Z_ERRNO=-1; + private const int Z_STREAM_ERROR=-2; + private const int Z_DATA_ERROR=-3; + private const int Z_MEM_ERROR=-4; + private const int Z_BUF_ERROR=-5; + private const int Z_VERSION_ERROR=-6; + + private const int TYPE=0; // get type bits (3, including end bit) + private const int LENS=1; // get lengths for stored + private const int STORED=2;// processing stored block + private const int TABLE=3; // get table lengths + private const int BTREE=4; // get bit lengths tree for a dynamic block + private const int DTREE=5; // get length, distance trees for a dynamic block + private const int CODES=6; // processing fixed or dynamic block + private const int DRY=7; // output remaining window bytes + private const int DONE=8; // finished last block, done + private const int BAD=9; // ot a data error--stuck here + + internal int mode; // current inflate_block mode + + internal int left; // if STORED, bytes left to copy + + internal int table; // table lengths (14 bits) + internal int index; // index into blens (or border) + internal int[] blens; // bit lengths of codes + internal int[] bb=new int[1]; // bit length tree depth + internal int[] tb=new int[1]; // bit length decoding tree + + internal InfCodes codes=new InfCodes(); // if CODES, current state + + int last; // true if this block is the last block + + // mode independent information + internal int bitk; // bits in bit buffer + internal int bitb; // bit buffer + internal int[] hufts; // single malloc for tree space + internal byte[] window; // sliding window + internal int end; // one byte after sliding window + internal int read; // window read pointer + internal int write; // window write pointer + internal Object checkfn; // check function + internal long check; // check on output + + internal InfTree inftree=new InfTree(); + + internal InfBlocks(ZStream z, Object checkfn, int w){ + hufts=new int[MANY*3]; + window=new byte[w]; + end=w; + this.checkfn = checkfn; + mode = TYPE; + reset(z, null); + } + + internal void reset(ZStream z, long[] c){ + if(c!=null) c[0]=check; + if(mode==BTREE || mode==DTREE){ + } + if(mode==CODES){ + codes.free(z); + } + mode=TYPE; + bitk=0; + bitb=0; + read=write=0; + + if(checkfn != null) + z.adler=check=z._adler.adler32(0L, null, 0, 0); + } + + internal int proc(ZStream z, int r){ + int t; // temporary storage + int b; // bit buffer + int k; // bits in bit buffer + int p; // input data pointer + int n; // bytes available there + int q; // output window write pointer + int m; { // bytes to end of window or read pointer + + // copy input/output information to locals (UPDATE macro restores) + p=z.next_in_index;n=z.avail_in;b=bitb;k=bitk;} { + q=write;m=(int)(q> 1){ + case 0: { // stored + b>>=(3);k-=(3);} + t = k & 7; { // go to byte boundary + + b>>=(t);k-=(t);} + mode = LENS; // get length of stored block + break; + case 1: { // fixed + int[] bl=new int[1]; + int[] bd=new int[1]; + int[][] tl=new int[1][]; + int[][] td=new int[1][]; + + InfTree.inflate_trees_fixed(bl, bd, tl, td, z); + codes.init(bl[0], bd[0], tl[0], 0, td[0], 0, z); + } { + + b>>=(3);k-=(3);} + + mode = CODES; + break; + case 2: { // dynamic + + b>>=(3);k-=(3);} + + mode = TABLE; + break; + case 3: { // illegal + + b>>=(3);k-=(3);} + mode = BAD; + z.msg = "invalid block type"; + r = Z_DATA_ERROR; + + bitb=b; bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(z,r); + } + break; + case LENS: + + while(k<(32)){ + if(n!=0){ + r=Z_OK; + } + else{ + bitb=b; bitk=k; + z.avail_in=n; + z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(z,r); + }; + n--; + b|=(z.next_in[p++]&0xff)<> 16) & 0xffff) != (b & 0xffff)){ + mode = BAD; + z.msg = "invalid stored block lengths"; + r = Z_DATA_ERROR; + + bitb=b; bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(z,r); + } + left = (b & 0xffff); + b = k = 0; // dump bits + mode = left!=0 ? STORED : (last!=0 ? DRY : TYPE); + break; + case STORED: + if (n == 0){ + bitb=b; bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(z,r); + } + + if(m==0){ + if(q==end&&read!=0){ + q=0; m=(int)(qn) t = n; + if(t>m) t = m; + System.Array.Copy(z.next_in, p, window, q, t); + p += t; n -= t; + q += t; m -= t; + if ((left -= t) != 0) + break; + mode = last!=0 ? DRY : TYPE; + break; + case TABLE: + + while(k<(14)){ + if(n!=0){ + r=Z_OK; + } + else{ + bitb=b; bitk=k; + z.avail_in=n; + z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(z,r); + }; + n--; + b|=(z.next_in[p++]&0xff)< 29 || ((t >> 5) & 0x1f) > 29) { + mode = BAD; + z.msg = "too many length or distance symbols"; + r = Z_DATA_ERROR; + + bitb=b; bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(z,r); + } + t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); + if(blens==null || blens.Length>=(14);k-=(14);} + + index = 0; + mode = BTREE; + goto case BTREE; + case BTREE: + while (index < 4 + (table >> 10)){ + while(k<(3)){ + if(n!=0){ + r=Z_OK; + } + else{ + bitb=b; bitk=k; + z.avail_in=n; + z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(z,r); + }; + n--; + b|=(z.next_in[p++]&0xff)<>=(3);k-=(3);} + } + + while(index < 19){ + blens[border[index++]] = 0; + } + + bb[0] = 7; + t = inftree.inflate_trees_bits(blens, bb, tb, hufts, z); + if (t != Z_OK){ + r = t; + if (r == Z_DATA_ERROR){ + blens=null; + mode = BAD; + } + + bitb=b; bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(z,r); + } + + index = 0; + mode = DTREE; + goto case DTREE; + case DTREE: + while (true){ + t = table; + if(!(index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))){ + break; + } + + int i, j, c; + + t = bb[0]; + + while(k<(t)){ + if(n!=0){ + r=Z_OK; + } + else{ + bitb=b; bitk=k; + z.avail_in=n; + z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(z,r); + }; + n--; + b|=(z.next_in[p++]&0xff)<>=(t);k-=(t); + blens[index++] = c; + } + else { // c == 16..18 + i = c == 18 ? 7 : c - 14; + j = c == 18 ? 11 : 3; + + while(k<(t+i)){ + if(n!=0){ + r=Z_OK; + } + else{ + bitb=b; bitk=k; + z.avail_in=n; + z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(z,r); + }; + n--; + b|=(z.next_in[p++]&0xff)<>=(t);k-=(t); + + j += (b & inflate_mask[i]); + + b>>=(i);k-=(i); + + i = index; + t = table; + if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || + (c == 16 && i < 1)){ + blens=null; + mode = BAD; + z.msg = "invalid bit length repeat"; + r = Z_DATA_ERROR; + + bitb=b; bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(z,r); + } + + c = c == 16 ? blens[i-1] : 0; + do{ + blens[i++] = c; + } + while (--j!=0); + index = i; + } + } + + tb[0]=-1; { + int[] bl=new int[1]; + int[] bd=new int[1]; + int[] tl=new int[1]; + int[] td=new int[1]; + bl[0] = 9; // must be <= 9 for lookahead assumptions + bd[0] = 6; // must be <= 9 for lookahead assumptions + + t = table; + t = inftree.inflate_trees_dynamic(257 + (t & 0x1f), + 1 + ((t >> 5) & 0x1f), + blens, bl, bd, tl, td, hufts, z); + + if (t != Z_OK){ + if (t == Z_DATA_ERROR){ + blens=null; + mode = BAD; + } + r = t; + + bitb=b; bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(z,r); + } + codes.init(bl[0], bd[0], hufts, tl[0], hufts, td[0], z); + } + mode = CODES; + goto case CODES; + case CODES: + bitb=b; bitk=k; + z.avail_in=n; z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + + if ((r = codes.proc(this, z, r)) != Z_STREAM_END){ + return inflate_flush(z, r); + } + r = Z_OK; + codes.free(z); + + p=z.next_in_index; n=z.avail_in;b=bitb;k=bitk; + q=write;m=(int)(q z.avail_out) n = z.avail_out; + if (n!=0 && r == Z_BUF_ERROR) r = Z_OK; + + // update counters + z.avail_out -= n; + z.total_out += n; + + // update check information + if(checkfn != null) + z.adler=check=z._adler.adler32(check, window, q, n); + + // copy as far as end of window + System.Array.Copy(window, q, z.next_out, p, n); + p += n; + q += n; + + // see if more to copy at beginning of window + if (q == end){ + // wrap pointers + q = 0; + if (write == end) + write = 0; + + // compute bytes to copy + n = write - q; + if (n > z.avail_out) n = z.avail_out; + if (n!=0 && r == Z_BUF_ERROR) r = Z_OK; + + // update counters + z.avail_out -= n; + z.total_out += n; + + // update check information + if(checkfn != null) + z.adler=check=z._adler.adler32(check, window, q, n); + + // copy + System.Array.Copy(window, q, z.next_out, p, n); + p += n; + q += n; + } + + // update pointers + z.next_out_index = p; + read = q; + + // done + return r; + } + } +} \ No newline at end of file diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib/InfBlocks.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib/InfBlocks.cs.meta new file mode 100644 index 0000000..118ce19 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib/InfBlocks.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3dea10ae60fc127458856b92e000bff0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib/InfCodes.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib/InfCodes.cs new file mode 100644 index 0000000..6fcafe4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib/InfCodes.cs @@ -0,0 +1,611 @@ +using System; +/* + * $Id: InfCodes.cs,v 1.2 2008-05-10 09:35:40 bouncy Exp $ + * +Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +namespace Org.BouncyCastle.Utilities.Zlib { + + internal sealed class InfCodes{ + + private static readonly int[] inflate_mask = { + 0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f, + 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff, + 0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff, + 0x00007fff, 0x0000ffff + }; + + private const int Z_OK=0; + private const int Z_STREAM_END=1; + private const int Z_NEED_DICT=2; + private const int Z_ERRNO=-1; + private const int Z_STREAM_ERROR=-2; + private const int Z_DATA_ERROR=-3; + private const int Z_MEM_ERROR=-4; + private const int Z_BUF_ERROR=-5; + private const int Z_VERSION_ERROR=-6; + + // waiting for "i:"=input, + // "o:"=output, + // "x:"=nothing + private const int START=0; // x: set up for LEN + private const int LEN=1; // i: get length/literal/eob next + private const int LENEXT=2; // i: getting length extra (have base) + private const int DIST=3; // i: get distance next + private const int DISTEXT=4;// i: getting distance extra + private const int COPY=5; // o: copying bytes in window, waiting for space + private const int LIT=6; // o: got literal, waiting for output space + private const int WASH=7; // o: got eob, possibly still output waiting + private const int END=8; // x: got eob and all data flushed + private const int BADCODE=9;// x: got error + + int mode; // current inflate_codes mode + + // mode dependent information + int len; + + int[] tree; // pointer into tree + int tree_index=0; + int need; // bits needed + + int lit; + + // if EXT or COPY, where and how much + int get; // bits to get for extra + int dist; // distance back to copy from + + byte lbits; // ltree bits decoded per branch + byte dbits; // dtree bits decoder per branch + int[] ltree; // literal/length/eob tree + int ltree_index; // literal/length/eob tree + int[] dtree; // distance tree + int dtree_index; // distance tree + + internal InfCodes(){ + } + internal void init(int bl, int bd, + int[] tl, int tl_index, + int[] td, int td_index, ZStream z){ + mode=START; + lbits=(byte)bl; + dbits=(byte)bd; + ltree=tl; + ltree_index=tl_index; + dtree = td; + dtree_index=td_index; + tree=null; + } + + internal int proc(InfBlocks s, ZStream z, int r){ + int j; // temporary storage + int tindex; // temporary pointer + int e; // extra bits or operation + int b=0; // bit buffer + int k=0; // bits in bit buffer + int p=0; // input data pointer + int n; // bytes available there + int q; // output window write pointer + int m; // bytes to end of window or read pointer + int f; // pointer to copy strings from + + // copy input/output information to locals (UPDATE macro restores) + p=z.next_in_index;n=z.avail_in;b=s.bitb;k=s.bitk; + q=s.write;m=q= 258 && n >= 10){ + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + r = inflate_fast(lbits, dbits, + ltree, ltree_index, + dtree, dtree_index, + s, z); + + p=z.next_in_index;n=z.avail_in;b=s.bitb;k=s.bitk; + q=s.write;m=q>=(tree[tindex+1]); + k-=(tree[tindex+1]); + + e=tree[tindex]; + + if(e == 0){ // literal + lit = tree[tindex+2]; + mode = LIT; + break; + } + if((e & 16)!=0 ){ // length + get = e & 15; + len = tree[tindex+2]; + mode = LENEXT; + break; + } + if ((e & 64) == 0){ // next table + need = e; + tree_index = tindex/3+tree[tindex+2]; + break; + } + if ((e & 32)!=0){ // end of block + mode = WASH; + break; + } + mode = BADCODE; // invalid code + z.msg = "invalid literal/length code"; + r = Z_DATA_ERROR; + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + return s.inflate_flush(z,r); + + case LENEXT: // i: getting length extra (have base) + j = get; + + while(k<(j)){ + if(n!=0)r=Z_OK; + else{ + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + return s.inflate_flush(z,r); + } + n--; b|=(z.next_in[p++]&0xff)<>=j; + k-=j; + + need = dbits; + tree = dtree; + tree_index=dtree_index; + mode = DIST; + goto case DIST; + case DIST: // i: get distance next + j = need; + + while(k<(j)){ + if(n!=0)r=Z_OK; + else{ + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + return s.inflate_flush(z,r); + } + n--; b|=(z.next_in[p++]&0xff)<>=tree[tindex+1]; + k-=tree[tindex+1]; + + e = (tree[tindex]); + if((e & 16)!=0){ // distance + get = e & 15; + dist = tree[tindex+2]; + mode = DISTEXT; + break; + } + if ((e & 64) == 0){ // next table + need = e; + tree_index = tindex/3 + tree[tindex+2]; + break; + } + mode = BADCODE; // invalid code + z.msg = "invalid distance code"; + r = Z_DATA_ERROR; + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + return s.inflate_flush(z,r); + + case DISTEXT: // i: getting distance extra + j = get; + + while(k<(j)){ + if(n!=0)r=Z_OK; + else{ + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + return s.inflate_flush(z,r); + } + n--; b|=(z.next_in[p++]&0xff)<>=j; + k-=j; + + mode = COPY; + goto case COPY; + case COPY: // o: copying bytes in window, waiting for space + f = q - dist; + while(f < 0){ // modulo window size-"while" instead + f += s.end; // of "if" handles invalid distances + } + while (len!=0){ + + if(m==0){ + if(q==s.end&&s.read!=0){q=0;m=q 7){ // return unused byte, if any + k -= 8; + n++; + p--; // can always return one + } + + s.write=q; r=s.inflate_flush(z,r); + q=s.write;m=q= 258 && n >= 10 + // get literal/length code + while(k<(20)){ // max bits for literal/length code + n--; + b|=(z.next_in[p++]&0xff)<>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); + + s.window[q++] = (byte)tp[tp_index_t_3+2]; + m--; + continue; + } + do { + + b>>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); + + if((e&16)!=0){ + e &= 15; + c = tp[tp_index_t_3+2] + ((int)b & inflate_mask[e]); + + b>>=e; k-=e; + + // decode distance base of block to copy + while(k<(15)){ // max bits for distance code + n--; + b|=(z.next_in[p++]&0xff)<>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); + + if((e&16)!=0){ + // get extra bits to add to distance base + e &= 15; + while(k<(e)){ // get extra bits (up to 13) + n--; + b|=(z.next_in[p++]&0xff)<>=(e); k-=(e); + + // do the copy + m -= c; + if (q >= d){ // offset before dest + // just copy + r=q-d; + if(q-r>0 && 2>(q-r)){ + s.window[q++]=s.window[r++]; // minimum count is three, + s.window[q++]=s.window[r++]; // so unroll loop a little + c-=2; + } + else{ + System.Array.Copy(s.window, r, s.window, q, 2); + q+=2; r+=2; c-=2; + } + } + else{ // else offset after destination + r=q-d; + do{ + r+=s.end; // force pointer in window + }while(r<0); // covers invalid distances + e=s.end-r; + if(c>e){ // if source crosses, + c-=e; // wrapped copy + if(q-r>0 && e>(q-r)){ + do{s.window[q++] = s.window[r++];} + while(--e!=0); + } + else{ + System.Array.Copy(s.window, r, s.window, q, e); + q+=e; r+=e; e=0; + } + r = 0; // copy rest from start of window + } + + } + + // copy all or what's left + if(q-r>0 && c>(q-r)){ + do{s.window[q++] = s.window[r++];} + while(--c!=0); + } + else{ + System.Array.Copy(s.window, r, s.window, q, c); + q+=c; r+=c; c=0; + } + break; + } + else if((e&64)==0){ + t+=tp[tp_index_t_3+2]; + t+=(b&inflate_mask[e]); + tp_index_t_3=(tp_index+t)*3; + e=tp[tp_index_t_3]; + } + else{ + z.msg = "invalid distance code"; + + c=z.avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3; + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + + return Z_DATA_ERROR; + } + } + while(true); + break; + } + + if((e&64)==0){ + t+=tp[tp_index_t_3+2]; + t+=(b&inflate_mask[e]); + tp_index_t_3=(tp_index+t)*3; + if((e=tp[tp_index_t_3])==0){ + + b>>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); + + s.window[q++]=(byte)tp[tp_index_t_3+2]; + m--; + break; + } + } + else if((e&32)!=0){ + + c=z.avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3; + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + + return Z_STREAM_END; + } + else{ + z.msg="invalid literal/length code"; + + c=z.avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3; + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + + return Z_DATA_ERROR; + } + } + while(true); + } + while(m>=258 && n>= 10); + + // not enough input or output--restore pointers and return + c=z.avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3; + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + + return Z_OK; + } + } +} \ No newline at end of file diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib/InfCodes.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib/InfCodes.cs.meta new file mode 100644 index 0000000..1ae3b39 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib/InfCodes.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 64ce354c0a70647418667b5ccabc611d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib/InfTree.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib/InfTree.cs new file mode 100644 index 0000000..6ed7d19 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib/InfTree.cs @@ -0,0 +1,523 @@ +using System; +/* + * $Id: InfTree.cs,v 1.2 2008-05-10 09:35:40 bouncy Exp $ + * +Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +namespace Org.BouncyCastle.Utilities.Zlib { + + internal sealed class InfTree{ + + private const int MANY=1440; + + private const int Z_OK=0; + private const int Z_STREAM_END=1; + private const int Z_NEED_DICT=2; + private const int Z_ERRNO=-1; + private const int Z_STREAM_ERROR=-2; + private const int Z_DATA_ERROR=-3; + private const int Z_MEM_ERROR=-4; + private const int Z_BUF_ERROR=-5; + private const int Z_VERSION_ERROR=-6; + + private const int fixed_bl = 9; + private const int fixed_bd = 5; + + static readonly int[] fixed_tl = { + 96,7,256, 0,8,80, 0,8,16, 84,8,115, + 82,7,31, 0,8,112, 0,8,48, 0,9,192, + 80,7,10, 0,8,96, 0,8,32, 0,9,160, + 0,8,0, 0,8,128, 0,8,64, 0,9,224, + 80,7,6, 0,8,88, 0,8,24, 0,9,144, + 83,7,59, 0,8,120, 0,8,56, 0,9,208, + 81,7,17, 0,8,104, 0,8,40, 0,9,176, + 0,8,8, 0,8,136, 0,8,72, 0,9,240, + 80,7,4, 0,8,84, 0,8,20, 85,8,227, + 83,7,43, 0,8,116, 0,8,52, 0,9,200, + 81,7,13, 0,8,100, 0,8,36, 0,9,168, + 0,8,4, 0,8,132, 0,8,68, 0,9,232, + 80,7,8, 0,8,92, 0,8,28, 0,9,152, + 84,7,83, 0,8,124, 0,8,60, 0,9,216, + 82,7,23, 0,8,108, 0,8,44, 0,9,184, + 0,8,12, 0,8,140, 0,8,76, 0,9,248, + 80,7,3, 0,8,82, 0,8,18, 85,8,163, + 83,7,35, 0,8,114, 0,8,50, 0,9,196, + 81,7,11, 0,8,98, 0,8,34, 0,9,164, + 0,8,2, 0,8,130, 0,8,66, 0,9,228, + 80,7,7, 0,8,90, 0,8,26, 0,9,148, + 84,7,67, 0,8,122, 0,8,58, 0,9,212, + 82,7,19, 0,8,106, 0,8,42, 0,9,180, + 0,8,10, 0,8,138, 0,8,74, 0,9,244, + 80,7,5, 0,8,86, 0,8,22, 192,8,0, + 83,7,51, 0,8,118, 0,8,54, 0,9,204, + 81,7,15, 0,8,102, 0,8,38, 0,9,172, + 0,8,6, 0,8,134, 0,8,70, 0,9,236, + 80,7,9, 0,8,94, 0,8,30, 0,9,156, + 84,7,99, 0,8,126, 0,8,62, 0,9,220, + 82,7,27, 0,8,110, 0,8,46, 0,9,188, + 0,8,14, 0,8,142, 0,8,78, 0,9,252, + 96,7,256, 0,8,81, 0,8,17, 85,8,131, + 82,7,31, 0,8,113, 0,8,49, 0,9,194, + 80,7,10, 0,8,97, 0,8,33, 0,9,162, + 0,8,1, 0,8,129, 0,8,65, 0,9,226, + 80,7,6, 0,8,89, 0,8,25, 0,9,146, + 83,7,59, 0,8,121, 0,8,57, 0,9,210, + 81,7,17, 0,8,105, 0,8,41, 0,9,178, + 0,8,9, 0,8,137, 0,8,73, 0,9,242, + 80,7,4, 0,8,85, 0,8,21, 80,8,258, + 83,7,43, 0,8,117, 0,8,53, 0,9,202, + 81,7,13, 0,8,101, 0,8,37, 0,9,170, + 0,8,5, 0,8,133, 0,8,69, 0,9,234, + 80,7,8, 0,8,93, 0,8,29, 0,9,154, + 84,7,83, 0,8,125, 0,8,61, 0,9,218, + 82,7,23, 0,8,109, 0,8,45, 0,9,186, + 0,8,13, 0,8,141, 0,8,77, 0,9,250, + 80,7,3, 0,8,83, 0,8,19, 85,8,195, + 83,7,35, 0,8,115, 0,8,51, 0,9,198, + 81,7,11, 0,8,99, 0,8,35, 0,9,166, + 0,8,3, 0,8,131, 0,8,67, 0,9,230, + 80,7,7, 0,8,91, 0,8,27, 0,9,150, + 84,7,67, 0,8,123, 0,8,59, 0,9,214, + 82,7,19, 0,8,107, 0,8,43, 0,9,182, + 0,8,11, 0,8,139, 0,8,75, 0,9,246, + 80,7,5, 0,8,87, 0,8,23, 192,8,0, + 83,7,51, 0,8,119, 0,8,55, 0,9,206, + 81,7,15, 0,8,103, 0,8,39, 0,9,174, + 0,8,7, 0,8,135, 0,8,71, 0,9,238, + 80,7,9, 0,8,95, 0,8,31, 0,9,158, + 84,7,99, 0,8,127, 0,8,63, 0,9,222, + 82,7,27, 0,8,111, 0,8,47, 0,9,190, + 0,8,15, 0,8,143, 0,8,79, 0,9,254, + 96,7,256, 0,8,80, 0,8,16, 84,8,115, + 82,7,31, 0,8,112, 0,8,48, 0,9,193, + + 80,7,10, 0,8,96, 0,8,32, 0,9,161, + 0,8,0, 0,8,128, 0,8,64, 0,9,225, + 80,7,6, 0,8,88, 0,8,24, 0,9,145, + 83,7,59, 0,8,120, 0,8,56, 0,9,209, + 81,7,17, 0,8,104, 0,8,40, 0,9,177, + 0,8,8, 0,8,136, 0,8,72, 0,9,241, + 80,7,4, 0,8,84, 0,8,20, 85,8,227, + 83,7,43, 0,8,116, 0,8,52, 0,9,201, + 81,7,13, 0,8,100, 0,8,36, 0,9,169, + 0,8,4, 0,8,132, 0,8,68, 0,9,233, + 80,7,8, 0,8,92, 0,8,28, 0,9,153, + 84,7,83, 0,8,124, 0,8,60, 0,9,217, + 82,7,23, 0,8,108, 0,8,44, 0,9,185, + 0,8,12, 0,8,140, 0,8,76, 0,9,249, + 80,7,3, 0,8,82, 0,8,18, 85,8,163, + 83,7,35, 0,8,114, 0,8,50, 0,9,197, + 81,7,11, 0,8,98, 0,8,34, 0,9,165, + 0,8,2, 0,8,130, 0,8,66, 0,9,229, + 80,7,7, 0,8,90, 0,8,26, 0,9,149, + 84,7,67, 0,8,122, 0,8,58, 0,9,213, + 82,7,19, 0,8,106, 0,8,42, 0,9,181, + 0,8,10, 0,8,138, 0,8,74, 0,9,245, + 80,7,5, 0,8,86, 0,8,22, 192,8,0, + 83,7,51, 0,8,118, 0,8,54, 0,9,205, + 81,7,15, 0,8,102, 0,8,38, 0,9,173, + 0,8,6, 0,8,134, 0,8,70, 0,9,237, + 80,7,9, 0,8,94, 0,8,30, 0,9,157, + 84,7,99, 0,8,126, 0,8,62, 0,9,221, + 82,7,27, 0,8,110, 0,8,46, 0,9,189, + 0,8,14, 0,8,142, 0,8,78, 0,9,253, + 96,7,256, 0,8,81, 0,8,17, 85,8,131, + 82,7,31, 0,8,113, 0,8,49, 0,9,195, + 80,7,10, 0,8,97, 0,8,33, 0,9,163, + 0,8,1, 0,8,129, 0,8,65, 0,9,227, + 80,7,6, 0,8,89, 0,8,25, 0,9,147, + 83,7,59, 0,8,121, 0,8,57, 0,9,211, + 81,7,17, 0,8,105, 0,8,41, 0,9,179, + 0,8,9, 0,8,137, 0,8,73, 0,9,243, + 80,7,4, 0,8,85, 0,8,21, 80,8,258, + 83,7,43, 0,8,117, 0,8,53, 0,9,203, + 81,7,13, 0,8,101, 0,8,37, 0,9,171, + 0,8,5, 0,8,133, 0,8,69, 0,9,235, + 80,7,8, 0,8,93, 0,8,29, 0,9,155, + 84,7,83, 0,8,125, 0,8,61, 0,9,219, + 82,7,23, 0,8,109, 0,8,45, 0,9,187, + 0,8,13, 0,8,141, 0,8,77, 0,9,251, + 80,7,3, 0,8,83, 0,8,19, 85,8,195, + 83,7,35, 0,8,115, 0,8,51, 0,9,199, + 81,7,11, 0,8,99, 0,8,35, 0,9,167, + 0,8,3, 0,8,131, 0,8,67, 0,9,231, + 80,7,7, 0,8,91, 0,8,27, 0,9,151, + 84,7,67, 0,8,123, 0,8,59, 0,9,215, + 82,7,19, 0,8,107, 0,8,43, 0,9,183, + 0,8,11, 0,8,139, 0,8,75, 0,9,247, + 80,7,5, 0,8,87, 0,8,23, 192,8,0, + 83,7,51, 0,8,119, 0,8,55, 0,9,207, + 81,7,15, 0,8,103, 0,8,39, 0,9,175, + 0,8,7, 0,8,135, 0,8,71, 0,9,239, + 80,7,9, 0,8,95, 0,8,31, 0,9,159, + 84,7,99, 0,8,127, 0,8,63, 0,9,223, + 82,7,27, 0,8,111, 0,8,47, 0,9,191, + 0,8,15, 0,8,143, 0,8,79, 0,9,255 + }; + static readonly int[] fixed_td = { + 80,5,1, 87,5,257, 83,5,17, 91,5,4097, + 81,5,5, 89,5,1025, 85,5,65, 93,5,16385, + 80,5,3, 88,5,513, 84,5,33, 92,5,8193, + 82,5,9, 90,5,2049, 86,5,129, 192,5,24577, + 80,5,2, 87,5,385, 83,5,25, 91,5,6145, + 81,5,7, 89,5,1537, 85,5,97, 93,5,24577, + 80,5,4, 88,5,769, 84,5,49, 92,5,12289, + 82,5,13, 90,5,3073, 86,5,193, 192,5,24577 + }; + + // Tables for deflate from PKZIP's appnote.txt. + static readonly int[] cplens = { // Copy lengths for literal codes 257..285 + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 + }; + + // see note #13 above about 258 + static readonly int[] cplext = { // Extra bits for literal codes 257..285 + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, + 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112 // 112==invalid + }; + + static readonly int[] cpdist = { // Copy offsets for distance codes 0..29 + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577 + }; + + static readonly int[] cpdext = { // Extra bits for distance codes + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, + 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, + 12, 12, 13, 13}; + + // If BMAX needs to be larger than 16, then h and x[] should be uLong. + const int BMAX=15; // maximum bit length of any code + + int[] hn = null; // hufts used in space + int[] v = null; // work area for huft_build + int[] c = null; // bit length count table + int[] r = null; // table entry for structure assignment + int[] u = null; // table stack + int[] x = null; // bit offsets, then code stack + + private int huft_build(int[] b, // code lengths in bits (all assumed <= BMAX) + int bindex, + int n, // number of codes (assumed <= 288) + int s, // number of simple-valued codes (0..s-1) + int[] d, // list of base values for non-simple codes + int[] e, // list of extra bits for non-simple codes + int[] t, // result: starting table + int[] m, // maximum lookup bits, returns actual + int[] hp,// space for trees + int[] hn,// hufts used in space + int[] v // working area: values in order of bit length + ){ + // Given a list of code lengths and a maximum table size, make a set of + // tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR + // if the given code set is incomplete (the tables are still built in this + // case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of + // lengths), or Z_MEM_ERROR if not enough memory. + + int a; // counter for codes of length k + int f; // i repeats in table every f entries + int g; // maximum code length + int h; // table level + int i; // counter, current code + int j; // counter + int k; // number of bits in current code + int l; // bits per table (returned in m) + int mask; // (1 << w) - 1, to avoid cc -O bug on HP + int p; // pointer into c[], b[], or v[] + int q; // points to current table + int w; // bits before this table == (l * h) + int xp; // pointer into x + int y; // number of dummy codes added + int z; // number of entries in current table + + // Generate counts for each bit length + + p = 0; i = n; + do { + c[b[bindex+p]]++; p++; i--; // assume all entries <= BMAX + }while(i!=0); + + if(c[0] == n){ // null input--all zero length codes + t[0] = -1; + m[0] = 0; + return Z_OK; + } + + // Find minimum and maximum length, bound *m by those + l = m[0]; + for (j = 1; j <= BMAX; j++) + if(c[j]!=0) break; + k = j; // minimum code length + if(l < j){ + l = j; + } + for (i = BMAX; i!=0; i--){ + if(c[i]!=0) break; + } + g = i; // maximum code length + if(l > i){ + l = i; + } + m[0] = l; + + // Adjust last length count to fill out codes, if needed + for (y = 1 << j; j < i; j++, y <<= 1){ + if ((y -= c[j]) < 0){ + return Z_DATA_ERROR; + } + } + if ((y -= c[i]) < 0){ + return Z_DATA_ERROR; + } + c[i] += y; + + // Generate starting offsets into the value table for each length + x[1] = j = 0; + p = 1; xp = 2; + while (--i!=0) { // note that i == g from above + x[xp] = (j += c[p]); + xp++; + p++; + } + + // Make a table of values in order of bit lengths + i = 0; p = 0; + do { + if ((j = b[bindex+p]) != 0){ + v[x[j]++] = i; + } + p++; + } + while (++i < n); + n = x[g]; // set n to length of v + + // Generate the Huffman codes and for each, make the table entries + x[0] = i = 0; // first Huffman code is zero + p = 0; // grab values in bit order + h = -1; // no tables yet--level -1 + w = -l; // bits decoded == (l * h) + u[0] = 0; // just to keep compilers happy + q = 0; // ditto + z = 0; // ditto + + // go through the bit lengths (k already is bits in shortest code) + for (; k <= g; k++){ + a = c[k]; + while (a--!=0){ + // here i is the Huffman code of length k bits for value *p + // make tables up to required level + while (k > w + l){ + h++; + w += l; // previous table always l bits + // compute minimum size table less than or equal to l bits + z = g - w; + z = (z > l) ? l : z; // table size upper limit + if((f=1<<(j=k-w))>a+1){ // try a k-w bit table + // too few codes for k-w bit table + f -= a + 1; // deduct codes from patterns left + xp = k; + if(j < z){ + while (++j < z){ // try smaller tables up to z bits + if((f <<= 1) <= c[++xp]) + break; // enough codes to use up j bits + f -= c[xp]; // else deduct codes from patterns + } + } + } + z = 1 << j; // table entries for j-bit table + + // allocate new table + if (hn[0] + z > MANY){ // (note: doesn't matter for fixed) + return Z_DATA_ERROR; // overflow of MANY + } + u[h] = q = /*hp+*/ hn[0]; // DEBUG + hn[0] += z; + + // connect to last table, if there is one + if(h!=0){ + x[h]=i; // save pattern for backing up + r[0]=(byte)j; // bits in this table + r[1]=(byte)l; // bits to dump before this table + j=i>>(w - l); + r[2] = (int)(q - u[h-1] - j); // offset to this table + System.Array.Copy(r, 0, hp, (u[h-1]+j)*3, 3); // connect to last table + } + else{ + t[0] = q; // first table is returned result + } + } + + // set up table entry in r + r[1] = (byte)(k - w); + if (p >= n){ + r[0] = 128 + 64; // out of values--invalid code + } + else if (v[p] < s){ + r[0] = (byte)(v[p] < 256 ? 0 : 32 + 64); // 256 is end-of-block + r[2] = v[p++]; // simple code is just the value + } + else{ + r[0]=(byte)(e[v[p]-s]+16+64); // non-simple--look up in lists + r[2]=d[v[p++] - s]; + } + + // fill code-like entries with r + f=1<<(k-w); + for (j=i>>w;j>= 1){ + i ^= j; + } + i ^= j; + + // backup over finished tables + mask = (1 << w) - 1; // needed on HP, cc -O bug + while ((i & mask) != x[h]){ + h--; // don't need to update q + w -= l; + mask = (1 << w) - 1; + } + } + } + // Return Z_BUF_ERROR if we were given an incomplete table + return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; + } + + internal int inflate_trees_bits(int[] c, // 19 code lengths + int[] bb, // bits tree desired/actual depth + int[] tb, // bits tree result + int[] hp, // space for trees + ZStream z // for messages + ){ + int result; + initWorkArea(19); + hn[0]=0; + result = huft_build(c, 0, 19, 19, null, null, tb, bb, hp, hn, v); + + if(result == Z_DATA_ERROR){ + z.msg = "oversubscribed dynamic bit lengths tree"; + } + else if(result == Z_BUF_ERROR || bb[0] == 0){ + z.msg = "incomplete dynamic bit lengths tree"; + result = Z_DATA_ERROR; + } + return result; + } + + internal int inflate_trees_dynamic(int nl, // number of literal/length codes + int nd, // number of distance codes + int[] c, // that many (total) code lengths + int[] bl, // literal desired/actual bit depth + int[] bd, // distance desired/actual bit depth + int[] tl, // literal/length tree result + int[] td, // distance tree result + int[] hp, // space for trees + ZStream z // for messages + ){ + int result; + + // build literal/length tree + initWorkArea(288); + hn[0]=0; + result = huft_build(c, 0, nl, 257, cplens, cplext, tl, bl, hp, hn, v); + if (result != Z_OK || bl[0] == 0){ + if(result == Z_DATA_ERROR){ + z.msg = "oversubscribed literal/length tree"; + } + else if (result != Z_MEM_ERROR){ + z.msg = "incomplete literal/length tree"; + result = Z_DATA_ERROR; + } + return result; + } + + // build distance tree + initWorkArea(288); + result = huft_build(c, nl, nd, 0, cpdist, cpdext, td, bd, hp, hn, v); + + if (result != Z_OK || (bd[0] == 0 && nl > 257)){ + if (result == Z_DATA_ERROR){ + z.msg = "oversubscribed distance tree"; + } + else if (result == Z_BUF_ERROR) { + z.msg = "incomplete distance tree"; + result = Z_DATA_ERROR; + } + else if (result != Z_MEM_ERROR){ + z.msg = "empty distance tree with lengths"; + result = Z_DATA_ERROR; + } + return result; + } + + return Z_OK; + } + + internal static int inflate_trees_fixed(int[] bl, //literal desired/actual bit depth + int[] bd, //distance desired/actual bit depth + int[][] tl,//literal/length tree result + int[][] td,//distance tree result + ZStream z //for memory allocation + ){ + bl[0]=fixed_bl; + bd[0]=fixed_bd; + tl[0]=fixed_tl; + td[0]=fixed_td; + return Z_OK; + } + + private void initWorkArea(int vsize){ + if(hn==null){ + hn=new int[1]; + v=new int[vsize]; + c=new int[BMAX+1]; + r=new int[3]; + u=new int[BMAX]; + x=new int[BMAX+1]; + } + if(v.Lengthstate); + return Z_OK; + } + + internal int inflateInit(ZStream z, int w){ + z.msg = null; + blocks = null; + + // handle undocumented nowrap option (no zlib header or check) + nowrap = 0; + if(w < 0){ + w = - w; + nowrap = 1; + } + + // set window size + if(w<8 ||w>15){ + inflateEnd(z); + return Z_STREAM_ERROR; + } + wbits=w; + + z.istate.blocks=new InfBlocks(z, + z.istate.nowrap!=0 ? null : this, + 1<>4)+8>z.istate.wbits){ + z.istate.mode = BAD; + z.msg="invalid window size"; + z.istate.marker = 5; // can't try inflateSync + break; + } + z.istate.mode=FLAG; + goto case FLAG; + case FLAG: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + b = (z.next_in[z.next_in_index++])&0xff; + + if((((z.istate.method << 8)+b) % 31)!=0){ + z.istate.mode = BAD; + z.msg = "incorrect header check"; + z.istate.marker = 5; // can't try inflateSync + break; + } + + if((b&PRESET_DICT)==0){ + z.istate.mode = BLOCKS; + break; + } + z.istate.mode = DICT4; + goto case DICT4; + case DICT4: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + z.istate.need=((z.next_in[z.next_in_index++]&0xff)<<24)&0xff000000L; + z.istate.mode=DICT3; + goto case DICT3; + case DICT3: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + z.istate.need+=((z.next_in[z.next_in_index++]&0xff)<<16)&0xff0000L; + z.istate.mode=DICT2; + goto case DICT2; + case DICT2: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + z.istate.need+=((z.next_in[z.next_in_index++]&0xff)<<8)&0xff00L; + z.istate.mode=DICT1; + goto case DICT1; + case DICT1: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + z.istate.need += (z.next_in[z.next_in_index++]&0xffL); + z.adler = z.istate.need; + z.istate.mode = DICT0; + return Z_NEED_DICT; + case DICT0: + z.istate.mode = BAD; + z.msg = "need dictionary"; + z.istate.marker = 0; // can try inflateSync + return Z_STREAM_ERROR; + case BLOCKS: + + r = z.istate.blocks.proc(z, r); + if(r == Z_DATA_ERROR){ + z.istate.mode = BAD; + z.istate.marker = 0; // can try inflateSync + break; + } + if(r == Z_OK){ + r = f; + } + if(r != Z_STREAM_END){ + return r; + } + r = f; + z.istate.blocks.reset(z, z.istate.was); + if(z.istate.nowrap!=0){ + z.istate.mode=DONE; + break; + } + z.istate.mode=CHECK4; + goto case CHECK4; + case CHECK4: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + z.istate.need=((z.next_in[z.next_in_index++]&0xff)<<24)&0xff000000L; + z.istate.mode=CHECK3; + goto case CHECK3; + case CHECK3: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + z.istate.need+=((z.next_in[z.next_in_index++]&0xff)<<16)&0xff0000L; + z.istate.mode = CHECK2; + goto case CHECK2; + case CHECK2: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + z.istate.need+=((z.next_in[z.next_in_index++]&0xff)<<8)&0xff00L; + z.istate.mode = CHECK1; + goto case CHECK1; + case CHECK1: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + z.istate.need+=(z.next_in[z.next_in_index++]&0xffL); + + if(((int)(z.istate.was[0])) != ((int)(z.istate.need))){ + z.istate.mode = BAD; + z.msg = "incorrect data check"; + z.istate.marker = 5; // can't try inflateSync + break; + } + + z.istate.mode = DONE; + goto case DONE; + case DONE: + return Z_STREAM_END; + case BAD: + return Z_DATA_ERROR; + default: + return Z_STREAM_ERROR; + } + } + } + + + internal int inflateSetDictionary(ZStream z, byte[] dictionary, int dictLength){ + int index=0; + int length = dictLength; + if(z==null || z.istate == null|| z.istate.mode != DICT0) + return Z_STREAM_ERROR; + + if(z._adler.adler32(1L, dictionary, 0, dictLength)!=z.adler){ + return Z_DATA_ERROR; + } + + z.adler = z._adler.adler32(0, null, 0, 0); + + if(length >= (1<>7)]); + } + + internal short[] dyn_tree; // the dynamic tree + internal int max_code; // largest code with non zero frequency + internal StaticTree stat_desc; // the corresponding static tree + + // Compute the optimal bit lengths for a tree and update the total bit length + // for the current block. + // IN assertion: the fields freq and dad are set, heap[heap_max] and + // above are the tree nodes sorted by increasing frequency. + // OUT assertions: the field len is set to the optimal bit length, the + // array bl_count contains the frequencies for each bit length. + // The length opt_len is updated; static_len is also updated if stree is + // not null. + internal void gen_bitlen(Deflate s){ + short[] tree = dyn_tree; + short[] stree = stat_desc.static_tree; + int[] extra = stat_desc.extra_bits; + int based = stat_desc.extra_base; + int max_length = stat_desc.max_length; + int h; // heap index + int n, m; // iterate over the tree elements + int bits; // bit length + int xbits; // extra bits + short f; // frequency + int overflow = 0; // number of elements with bit length too large + + for (bits = 0; bits <= MAX_BITS; bits++) s.bl_count[bits] = 0; + + // In a first pass, compute the optimal bit lengths (which may + // overflow in the case of the bit length tree). + tree[s.heap[s.heap_max]*2+1] = 0; // root of the heap + + for(h=s.heap_max+1; h max_length){ bits = max_length; overflow++; } + tree[n*2+1] = (short)bits; + // We overwrite tree[n*2+1] which is no longer needed + + if (n > max_code) continue; // not a leaf node + + s.bl_count[bits]++; + xbits = 0; + if (n >= based) xbits = extra[n-based]; + f = tree[n*2]; + s.opt_len += f * (bits + xbits); + if (stree!=null) s.static_len += f * (stree[n*2+1] + xbits); + } + if (overflow == 0) return; + + // This happens for example on obj2 and pic of the Calgary corpus + // Find the first bit length which could increase: + do { + bits = max_length-1; + while(s.bl_count[bits]==0) bits--; + s.bl_count[bits]--; // move one leaf down the tree + s.bl_count[bits+1]+=2; // move one overflow item as its brother + s.bl_count[max_length]--; + // The brother of the overflow item also moves one step up, + // but this does not affect bl_count[max_length] + overflow -= 2; + } + while (overflow > 0); + + for (bits = max_length; bits != 0; bits--) { + n = s.bl_count[bits]; + while (n != 0) { + m = s.heap[--h]; + if (m > max_code) continue; + if (tree[m*2+1] != bits) { + s.opt_len += (int)(((long)bits - (long)tree[m*2+1])*(long)tree[m*2]); + tree[m*2+1] = (short)bits; + } + n--; + } + } + } + + // Construct one Huffman tree and assigns the code bit strings and lengths. + // Update the total bit length for the current block. + // IN assertion: the field freq is set for all tree elements. + // OUT assertions: the fields len and code are set to the optimal bit length + // and corresponding code. The length opt_len is updated; static_len is + // also updated if stree is not null. The field max_code is set. + internal void build_tree(Deflate s){ + short[] tree=dyn_tree; + short[] stree=stat_desc.static_tree; + int elems=stat_desc.elems; + int n, m; // iterate over heap elements + int max_code=-1; // largest code with non zero frequency + int node; // new node being created + + // Construct the initial heap, with least frequent element in + // heap[1]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + // heap[0] is not used. + s.heap_len = 0; + s.heap_max = HEAP_SIZE; + + for(n=0; n=1; n--) + s.pqdownheap(tree, n); + + // Construct the Huffman tree by repeatedly combining the least two + // frequent nodes. + + node=elems; // next internal node of the tree + do{ + // n = node of least frequency + n=s.heap[1]; + s.heap[1]=s.heap[s.heap_len--]; + s.pqdownheap(tree, 1); + m=s.heap[1]; // m = node of next least frequency + + s.heap[--s.heap_max] = n; // keep the nodes sorted by frequency + s.heap[--s.heap_max] = m; + + // Create a new node father of n and m + tree[node*2] = (short)(tree[n*2] + tree[m*2]); + s.depth[node] = (byte)(System.Math.Max(s.depth[n],s.depth[m])+1); + tree[n*2+1] = tree[m*2+1] = (short)node; + + // and insert the new node in the heap + s.heap[1] = node++; + s.pqdownheap(tree, 1); + } + while(s.heap_len>=2); + + s.heap[--s.heap_max] = s.heap[1]; + + // At this point, the fields freq and dad are set. We can now + // generate the bit lengths. + + gen_bitlen(s); + + // The field len is now set, we can generate the bit codes + gen_codes(tree, max_code, s.bl_count); + } + + // Generate the codes for a given tree and bit counts (which need not be + // optimal). + // IN assertion: the array bl_count contains the bit length statistics for + // the given tree and the field len is set for all tree elements. + // OUT assertion: the field code is set for all tree elements of non + // zero code length. + internal static void gen_codes(short[] tree, // the tree to decorate + int max_code, // largest code with non zero frequency + short[] bl_count // number of codes at each bit length + ){ + short[] next_code=new short[MAX_BITS+1]; // next code value for each bit length + short code = 0; // running code value + int bits; // bit index + int n; // code index + + // The distribution counts are first used to generate the code values + // without bit reversal. + for (bits = 1; bits <= MAX_BITS; bits++) { + next_code[bits] = code = (short)((code + bl_count[bits-1]) << 1); + } + + // Check that the bit counts in bl_count are consistent. The last code + // must be all ones. + //Assert (code + bl_count[MAX_BITS]-1 == (1<>=1; + res<<=1; + } + while(--len>0); + return res>>1; + } + } +} \ No newline at end of file diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib/Tree.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib/Tree.cs.meta new file mode 100644 index 0000000..ac9cdde --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib/Tree.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f5b1cd5e0dfb9ec409f414537b4888b6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib/ZDeflaterOutputStream.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib/ZDeflaterOutputStream.cs new file mode 100644 index 0000000..d097894 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib/ZDeflaterOutputStream.cs @@ -0,0 +1,171 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Utilities.Zlib { + /// + /// Summary description for DeflaterOutputStream. + /// + [Obsolete("Use 'ZOutputStream' instead")] + public class ZDeflaterOutputStream : Stream { + protected ZStream z=new ZStream(); + protected int flushLevel=JZlib.Z_NO_FLUSH; + private const int BUFSIZE = 4192; + protected byte[] buf=new byte[BUFSIZE]; + private byte[] buf1=new byte[1]; + + protected Stream outp; + + public ZDeflaterOutputStream(Stream outp) : this(outp, 6, false) { + } + + public ZDeflaterOutputStream(Stream outp, int level) : this(outp, level, false) { + } + + public ZDeflaterOutputStream(Stream outp, int level, bool nowrap) { + this.outp=outp; + z.deflateInit(level, nowrap); + } + + + public override bool CanRead { + get { + // TODO: Add DeflaterOutputStream.CanRead getter implementation + return false; + } + } + + public override bool CanSeek { + get { + // TODO: Add DeflaterOutputStream.CanSeek getter implementation + return false; + } + } + + public override bool CanWrite { + get { + // TODO: Add DeflaterOutputStream.CanWrite getter implementation + return true; + } + } + + public override long Length { + get { + // TODO: Add DeflaterOutputStream.Length getter implementation + return 0; + } + } + + public override long Position { + get { + // TODO: Add DeflaterOutputStream.Position getter implementation + return 0; + } + set { + // TODO: Add DeflaterOutputStream.Position setter implementation + } + } + + public override void Write(byte[] b, int off, int len) { + if(len==0) + return; + int err; + z.next_in=b; + z.next_in_index=off; + z.avail_in=len; + do{ + z.next_out=buf; + z.next_out_index=0; + z.avail_out=BUFSIZE; + err=z.deflate(flushLevel); + if(err!=JZlib.Z_OK) + throw new IOException("deflating: "+z.msg); + if (z.avail_out < BUFSIZE) + { + outp.Write(buf, 0, BUFSIZE-z.avail_out); + } + } + while(z.avail_in>0 || z.avail_out==0); + } + + public override long Seek(long offset, SeekOrigin origin) { + // TODO: Add DeflaterOutputStream.Seek implementation + return 0; + } + + public override void SetLength(long value) { + // TODO: Add DeflaterOutputStream.SetLength implementation + + } + + public override int Read(byte[] buffer, int offset, int count) { + // TODO: Add DeflaterOutputStream.Read implementation + return 0; + } + + public override void Flush() { + outp.Flush(); + } + + public override void WriteByte(byte b) { + buf1[0]=(byte)b; + Write(buf1, 0, 1); + } + + public void Finish() { + int err; + do{ + z.next_out=buf; + z.next_out_index=0; + z.avail_out=BUFSIZE; + err=z.deflate(JZlib.Z_FINISH); + if(err!=JZlib.Z_STREAM_END && err != JZlib.Z_OK) + throw new IOException("deflating: "+z.msg); + if(BUFSIZE-z.avail_out>0){ + outp.Write(buf, 0, BUFSIZE-z.avail_out); + } + } + while(z.avail_in>0 || z.avail_out==0); + Flush(); + } + + public void End() { + if(z==null) + return; + z.deflateEnd(); + z.free(); + z=null; + } + +#if PORTABLE + protected override void Dispose(bool disposing) + { + if (disposing) + { + try{ + try{Finish();} + catch (IOException) {} + } + finally{ + End(); + Platform.Dispose(outp); + outp=null; + } + } + base.Dispose(disposing); + } +#else + public override void Close() { + try{ + try{Finish();} + catch (IOException) {} + } + finally{ + End(); + Platform.Dispose(outp); + outp=null; + } + base.Close(); + } +#endif + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib/ZDeflaterOutputStream.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib/ZDeflaterOutputStream.cs.meta new file mode 100644 index 0000000..5f7bbcc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib/ZDeflaterOutputStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0f7a0677d49471e409ef43b05a06b799 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib/ZInflaterInputStream.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib/ZInflaterInputStream.cs new file mode 100644 index 0000000..ef742bb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib/ZInflaterInputStream.cs @@ -0,0 +1,140 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Utilities.Zlib { + /// + /// Summary description for DeflaterOutputStream. + /// + [Obsolete("Use 'ZInputStream' instead")] + public class ZInflaterInputStream : Stream { + protected ZStream z=new ZStream(); + protected int flushLevel=JZlib.Z_NO_FLUSH; + private const int BUFSIZE = 4192; + protected byte[] buf=new byte[BUFSIZE]; + private byte[] buf1=new byte[1]; + + protected Stream inp=null; + private bool nomoreinput=false; + + public ZInflaterInputStream(Stream inp) : this(inp, false) { + } + + public ZInflaterInputStream(Stream inp, bool nowrap) { + this.inp=inp; + z.inflateInit(nowrap); + z.next_in=buf; + z.next_in_index=0; + z.avail_in=0; + } + + public override bool CanRead { + get { + // TODO: Add DeflaterOutputStream.CanRead getter implementation + return true; + } + } + + public override bool CanSeek { + get { + // TODO: Add DeflaterOutputStream.CanSeek getter implementation + return false; + } + } + + public override bool CanWrite { + get { + // TODO: Add DeflaterOutputStream.CanWrite getter implementation + return false; + } + } + + public override long Length { + get { + // TODO: Add DeflaterOutputStream.Length getter implementation + return 0; + } + } + + public override long Position { + get { + // TODO: Add DeflaterOutputStream.Position getter implementation + return 0; + } + set { + // TODO: Add DeflaterOutputStream.Position setter implementation + } + } + + public override void Write(byte[] b, int off, int len) { + } + + public override long Seek(long offset, SeekOrigin origin) { + // TODO: Add DeflaterOutputStream.Seek implementation + return 0; + } + + public override void SetLength(long value) { + // TODO: Add DeflaterOutputStream.SetLength implementation + + } + + public override int Read(byte[] b, int off, int len) { + if(len==0) + return(0); + int err; + z.next_out=b; + z.next_out_index=off; + z.avail_out=len; + do { + if((z.avail_in==0)&&(!nomoreinput)) { // if buffer is empty and more input is avaiable, refill it + z.next_in_index=0; + z.avail_in=inp.Read(buf, 0, BUFSIZE);//(BUFSIZE 0) + { + output.Write(buf, 0, count); + } + } + while (z.avail_in > 0 || z.avail_out == 0); + + Flush(); + } + + public override void Flush() + { + output.Flush(); + } + + public virtual int FlushMode + { + get { return flushLevel; } + set { this.flushLevel = value; } + } + + public sealed override long Length { get { throw new NotSupportedException(); } } + public sealed override long Position + { + get { throw new NotSupportedException(); } + set { throw new NotSupportedException(); } + } + public sealed override int Read(byte[] buffer, int offset, int count) { throw new NotSupportedException(); } + public sealed override long Seek(long offset, SeekOrigin origin) { throw new NotSupportedException(); } + public sealed override void SetLength(long value) { throw new NotSupportedException(); } + + public virtual long TotalIn + { + get { return z.total_in; } + } + + public virtual long TotalOut + { + get { return z.total_out; } + } + + public override void Write(byte[] b, int off, int len) + { + if (len == 0) + return; + + z.next_in = b; + z.next_in_index = off; + z.avail_in = len; + + do + { + z.next_out = buf; + z.next_out_index = 0; + z.avail_out = buf.Length; + + int err = compress + ? z.deflate(flushLevel) + : z.inflate(flushLevel); + + if (err != JZlib.Z_OK) + // TODO +// throw new ZStreamException((compress ? "de" : "in") + "flating: " + z.msg); + throw new IOException((compress ? "de" : "in") + "flating: " + z.msg); + + output.Write(buf, 0, buf.Length - z.avail_out); + } + while (z.avail_in > 0 || z.avail_out == 0); + } + + public override void WriteByte(byte b) + { + buf1[0] = b; + Write(buf1, 0, 1); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib/ZOutputStream.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib/ZOutputStream.cs.meta new file mode 100644 index 0000000..be8c7a8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib/ZOutputStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1b740e22153b6434baa7fd5262c6cc45 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib/ZStream.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib/ZStream.cs new file mode 100644 index 0000000..7ff9614 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib/ZStream.cs @@ -0,0 +1,214 @@ +using System; +/* + * $Id: ZStream.cs,v 1.1 2006-07-31 13:59:26 bouncy Exp $ + * +Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +namespace Org.BouncyCastle.Utilities.Zlib { + + public sealed class ZStream{ + + private const int MAX_WBITS=15; // 32K LZ77 window + private const int DEF_WBITS=MAX_WBITS; + + private const int Z_NO_FLUSH=0; + private const int Z_PARTIAL_FLUSH=1; + private const int Z_SYNC_FLUSH=2; + private const int Z_FULL_FLUSH=3; + private const int Z_FINISH=4; + + private const int MAX_MEM_LEVEL=9; + + private const int Z_OK=0; + private const int Z_STREAM_END=1; + private const int Z_NEED_DICT=2; + private const int Z_ERRNO=-1; + private const int Z_STREAM_ERROR=-2; + private const int Z_DATA_ERROR=-3; + private const int Z_MEM_ERROR=-4; + private const int Z_BUF_ERROR=-5; + private const int Z_VERSION_ERROR=-6; + + public byte[] next_in; // next input byte + public int next_in_index; + public int avail_in; // number of bytes available at next_in + public long total_in; // total nb of input bytes read so far + + public byte[] next_out; // next output byte should be put there + public int next_out_index; + public int avail_out; // remaining free space at next_out + public long total_out; // total nb of bytes output so far + + public String msg; + + internal Deflate dstate; + internal Inflate istate; + + internal int data_type; // best guess about the data type: ascii or binary + + public long adler; + internal Adler32 _adler=new Adler32(); + + public int inflateInit(){ + return inflateInit(DEF_WBITS); + } + public int inflateInit(bool nowrap){ + return inflateInit(DEF_WBITS, nowrap); + } + public int inflateInit(int w){ + return inflateInit(w, false); + } + + public int inflateInit(int w, bool nowrap){ + istate=new Inflate(); + return istate.inflateInit(this, nowrap?-w:w); + } + + public int inflate(int f){ + if(istate==null) return Z_STREAM_ERROR; + return istate.inflate(this, f); + } + public int inflateEnd(){ + if(istate==null) return Z_STREAM_ERROR; + int ret=istate.inflateEnd(this); + istate = null; + return ret; + } + public int inflateSync(){ + if(istate == null) + return Z_STREAM_ERROR; + return istate.inflateSync(this); + } + public int inflateSetDictionary(byte[] dictionary, int dictLength){ + if(istate == null) + return Z_STREAM_ERROR; + return istate.inflateSetDictionary(this, dictionary, dictLength); + } + + public int deflateInit(int level){ + return deflateInit(level, MAX_WBITS); + } + public int deflateInit(int level, bool nowrap){ + return deflateInit(level, MAX_WBITS, nowrap); + } + public int deflateInit(int level, int bits){ + return deflateInit(level, bits, false); + } + public int deflateInit(int level, int bits, bool nowrap){ + dstate=new Deflate(); + return dstate.deflateInit(this, level, nowrap?-bits:bits); + } + public int deflate(int flush){ + if(dstate==null){ + return Z_STREAM_ERROR; + } + return dstate.deflate(this, flush); + } + public int deflateEnd(){ + if(dstate==null) return Z_STREAM_ERROR; + int ret=dstate.deflateEnd(); + dstate=null; + return ret; + } + public int deflateParams(int level, int strategy){ + if(dstate==null) return Z_STREAM_ERROR; + return dstate.deflateParams(this, level, strategy); + } + public int deflateSetDictionary (byte[] dictionary, int dictLength){ + if(dstate == null) + return Z_STREAM_ERROR; + return dstate.deflateSetDictionary(this, dictionary, dictLength); + } + + // Flush as much pending output as possible. All deflate() output goes + // through this function so some applications may wish to modify it + // to avoid allocating a large strm->next_out buffer and copying into it. + // (See also read_buf()). + internal void flush_pending(){ + int len=dstate.pending; + + if(len>avail_out) len=avail_out; + if(len==0) return; + + if(dstate.pending_buf.Length<=dstate.pending_out || + next_out.Length<=next_out_index || + dstate.pending_buf.Length<(dstate.pending_out+len) || + next_out.Length<(next_out_index+len)){ + // System.out.println(dstate.pending_buf.length+", "+dstate.pending_out+ + // ", "+next_out.length+", "+next_out_index+", "+len); + // System.out.println("avail_out="+avail_out); + } + + System.Array.Copy(dstate.pending_buf, dstate.pending_out, + next_out, next_out_index, len); + + next_out_index+=len; + dstate.pending_out+=len; + total_out+=len; + avail_out-=len; + dstate.pending-=len; + if(dstate.pending==0){ + dstate.pending_out=0; + } + } + + // Read a new buffer from the current input stream, update the adler32 + // and total number of bytes read. All deflate() input goes through + // this function so some applications may wish to modify it to avoid + // allocating a large strm->next_in buffer and copying from it. + // (See also flush_pending()). + internal int read_buf(byte[] buf, int start, int size) { + int len=avail_in; + + if(len>size) len=size; + if(len==0) return 0; + + avail_in-=len; + + if(dstate.noheader==0) { + adler=_adler.adler32(adler, next_in, next_in_index, len); + } + System.Array.Copy(next_in, next_in_index, buf, start, len); + next_in_index += len; + total_in += len; + return len; + } + + public void free(){ + next_in=null; + next_out=null; + msg=null; + _adler=null; + } + } +} \ No newline at end of file diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib/ZStream.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib/ZStream.cs.meta new file mode 100644 index 0000000..71a59c5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/util/zlib/ZStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0c098cbea47e5f146a9af77a3609b159 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509.meta new file mode 100644 index 0000000..e4f4d13 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7f4c7cf88b988bf4aafda574acbf39b8 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/AttributeCertificateHolder.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/AttributeCertificateHolder.cs new file mode 100644 index 0000000..fdd4580 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/AttributeCertificateHolder.cs @@ -0,0 +1,434 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Security.Certificates; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.X509.Store; + +namespace Org.BouncyCastle.X509 +{ + /// + /// The Holder object. + ///
    + 	/// Holder ::= SEQUENCE {
    + 	///		baseCertificateID   [0] IssuerSerial OPTIONAL,
    + 	///			-- the issuer and serial number of
    + 	///			-- the holder's Public Key Certificate
    + 	///		entityName          [1] GeneralNames OPTIONAL,
    + 	///			-- the name of the claimant or role
    + 	///		objectDigestInfo    [2] ObjectDigestInfo OPTIONAL
    + 	///			-- used to directly authenticate the holder,
    + 	///			-- for example, an executable
    + 	/// }
    +	/// 
    + ///
    + public class AttributeCertificateHolder + //: CertSelector, Selector + : IX509Selector + { + internal readonly Holder holder; + + internal AttributeCertificateHolder( + Asn1Sequence seq) + { + holder = Holder.GetInstance(seq); + } + + public AttributeCertificateHolder( + X509Name issuerName, + BigInteger serialNumber) + { + holder = new Holder( + new IssuerSerial( + GenerateGeneralNames(issuerName), + new DerInteger(serialNumber))); + } + + public AttributeCertificateHolder( + X509Certificate cert) + { + X509Name name; + try + { + name = PrincipalUtilities.GetIssuerX509Principal(cert); + } + catch (Exception e) + { + throw new CertificateParsingException(e.Message); + } + + holder = new Holder(new IssuerSerial(GenerateGeneralNames(name), new DerInteger(cert.SerialNumber))); + } + + public AttributeCertificateHolder( + X509Name principal) + { + holder = new Holder(GenerateGeneralNames(principal)); + } + + /** + * Constructs a holder for v2 attribute certificates with a hash value for + * some type of object. + *

    + * digestedObjectType can be one of the following: + *

      + *
    • 0 - publicKey - A hash of the public key of the holder must be + * passed.
    • + *
    • 1 - publicKeyCert - A hash of the public key certificate of the + * holder must be passed.
    • + *
    • 2 - otherObjectDigest - A hash of some other object type must be + * passed. otherObjectTypeID must not be empty.
    • + *
    + *

    + *

    This cannot be used if a v1 attribute certificate is used.

    + * + * @param digestedObjectType The digest object type. + * @param digestAlgorithm The algorithm identifier for the hash. + * @param otherObjectTypeID The object type ID if + * digestedObjectType is + * otherObjectDigest. + * @param objectDigest The hash value. + */ + public AttributeCertificateHolder( + int digestedObjectType, + string digestAlgorithm, + string otherObjectTypeID, + byte[] objectDigest) + { + // TODO Allow 'objectDigest' to be null? + + holder = new Holder(new ObjectDigestInfo(digestedObjectType, otherObjectTypeID, + new AlgorithmIdentifier(new DerObjectIdentifier(digestAlgorithm)), Arrays.Clone(objectDigest))); + } + + /** + * Returns the digest object type if an object digest info is used. + *

    + *

      + *
    • 0 - publicKey - A hash of the public key of the holder must be + * passed.
    • + *
    • 1 - publicKeyCert - A hash of the public key certificate of the + * holder must be passed.
    • + *
    • 2 - otherObjectDigest - A hash of some other object type must be + * passed. otherObjectTypeID must not be empty.
    • + *
    + *

    + * + * @return The digest object type or -1 if no object digest info is set. + */ + public int DigestedObjectType + { + get + { + ObjectDigestInfo odi = holder.ObjectDigestInfo; + + return odi == null + ? -1 + : odi.DigestedObjectType.IntValueExact; + } + } + + /** + * Returns the other object type ID if an object digest info is used. + * + * @return The other object type ID or null if no object + * digest info is set. + */ + public string DigestAlgorithm + { + get + { + ObjectDigestInfo odi = holder.ObjectDigestInfo; + + return odi == null + ? null + : odi.DigestAlgorithm.Algorithm.Id; + } + } + + /** + * Returns the hash if an object digest info is used. + * + * @return The hash or null if no object digest info is set. + */ + public byte[] GetObjectDigest() + { + ObjectDigestInfo odi = holder.ObjectDigestInfo; + + return odi == null + ? null + : odi.ObjectDigest.GetBytes(); + } + + /** + * Returns the digest algorithm ID if an object digest info is used. + * + * @return The digest algorithm ID or null if no object + * digest info is set. + */ + public string OtherObjectTypeID + { + get + { + ObjectDigestInfo odi = holder.ObjectDigestInfo; + + return odi == null + ? null + : odi.OtherObjectTypeID.Id; + } + } + + private GeneralNames GenerateGeneralNames( + X509Name principal) + { +// return GeneralNames.GetInstance(new DerSequence(new GeneralName(principal))); + return new GeneralNames(new GeneralName(principal)); + } + + private bool MatchesDN( + X509Name subject, + GeneralNames targets) + { + GeneralName[] names = targets.GetNames(); + + for (int i = 0; i != names.Length; i++) + { + GeneralName gn = names[i]; + + if (gn.TagNo == GeneralName.DirectoryName) + { + try + { + if (X509Name.GetInstance(gn.Name).Equivalent(subject)) + { + return true; + } + } + catch (Exception) + { + } + } + } + + return false; + } + + private object[] GetNames( + GeneralName[] names) + { + int count = 0; + for (int i = 0; i != names.Length; i++) + { + if (names[i].TagNo == GeneralName.DirectoryName) + { + ++count; + } + } + + object[] result = new object[count]; + + int pos = 0; + for (int i = 0; i != names.Length; i++) + { + if (names[i].TagNo == GeneralName.DirectoryName) + { + result[pos++] = X509Name.GetInstance(names[i].Name); + } + } + + return result; + } + + private X509Name[] GetPrincipals( + GeneralNames names) + { + object[] p = this.GetNames(names.GetNames()); + + int count = 0; + + for (int i = 0; i != p.Length; i++) + { + if (p[i] is X509Name) + { + ++count; + } + } + + X509Name[] result = new X509Name[count]; + + int pos = 0; + for (int i = 0; i != p.Length; i++) + { + if (p[i] is X509Name) + { + result[pos++] = (X509Name)p[i]; + } + } + + return result; + } + + /** + * Return any principal objects inside the attribute certificate holder entity names field. + * + * @return an array of IPrincipal objects (usually X509Name), null if no entity names field is set. + */ + public X509Name[] GetEntityNames() + { + if (holder.EntityName != null) + { + return GetPrincipals(holder.EntityName); + } + + return null; + } + + /** + * Return the principals associated with the issuer attached to this holder + * + * @return an array of principals, null if no BaseCertificateID is set. + */ + public X509Name[] GetIssuer() + { + if (holder.BaseCertificateID != null) + { + return GetPrincipals(holder.BaseCertificateID.Issuer); + } + + return null; + } + + /** + * Return the serial number associated with the issuer attached to this holder. + * + * @return the certificate serial number, null if no BaseCertificateID is set. + */ + public BigInteger SerialNumber + { + get + { + if (holder.BaseCertificateID != null) + { + return holder.BaseCertificateID.Serial.Value; + } + + return null; + } + } + + public object Clone() + { + return new AttributeCertificateHolder((Asn1Sequence)holder.ToAsn1Object()); + } + + public bool Match( + X509Certificate x509Cert) + { + try + { + if (holder.BaseCertificateID != null) + { + return holder.BaseCertificateID.Serial.HasValue(x509Cert.SerialNumber) + && MatchesDN(PrincipalUtilities.GetIssuerX509Principal(x509Cert), holder.BaseCertificateID.Issuer); + } + + if (holder.EntityName != null) + { + if (MatchesDN(PrincipalUtilities.GetSubjectX509Principal(x509Cert), holder.EntityName)) + { + return true; + } + } + + if (holder.ObjectDigestInfo != null) + { + IDigest md = null; + try + { + md = DigestUtilities.GetDigest(DigestAlgorithm); + } + catch (Exception) + { + return false; + } + + switch (DigestedObjectType) + { + case ObjectDigestInfo.PublicKey: + { + // TODO: DSA Dss-parms + + //byte[] b = x509Cert.GetPublicKey().getEncoded(); + // TODO Is this the right way to encode? + byte[] b = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo( + x509Cert.GetPublicKey()).GetEncoded(); + md.BlockUpdate(b, 0, b.Length); + break; + } + + case ObjectDigestInfo.PublicKeyCert: + { + byte[] b = x509Cert.GetEncoded(); + md.BlockUpdate(b, 0, b.Length); + break; + } + + // TODO Default handler? + } + + // TODO Shouldn't this be the other way around? + if (!Arrays.AreEqual(DigestUtilities.DoFinal(md), GetObjectDigest())) + { + return false; + } + } + } + catch (CertificateEncodingException) + { + return false; + } + + return false; + } + + public override bool Equals( + object obj) + { + if (obj == this) + { + return true; + } + + if (!(obj is AttributeCertificateHolder)) + { + return false; + } + + AttributeCertificateHolder other = (AttributeCertificateHolder)obj; + + return this.holder.Equals(other.holder); + } + + public override int GetHashCode() + { + return this.holder.GetHashCode(); + } + + public bool Match( + object obj) + { + if (!(obj is X509Certificate)) + { + return false; + } + +// return Match((Certificate)obj); + return Match((X509Certificate)obj); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/AttributeCertificateHolder.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/AttributeCertificateHolder.cs.meta new file mode 100644 index 0000000..b54d6d5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/AttributeCertificateHolder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7c9da7c7587038d41a4a19101f12cd8a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/AttributeCertificateIssuer.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/AttributeCertificateIssuer.cs new file mode 100644 index 0000000..39fc04f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/AttributeCertificateIssuer.cs @@ -0,0 +1,191 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.X509.Store; + +namespace Org.BouncyCastle.X509 +{ + /** + * Carrying class for an attribute certificate issuer. + */ + public class AttributeCertificateIssuer + //: CertSelector, Selector + : IX509Selector + { + internal readonly Asn1Encodable form; + + /** + * Set the issuer directly with the ASN.1 structure. + * + * @param issuer The issuer + */ + public AttributeCertificateIssuer( + AttCertIssuer issuer) + { + form = issuer.Issuer; + } + + public AttributeCertificateIssuer( + X509Name principal) + { +// form = new V2Form(GeneralNames.GetInstance(new DerSequence(new GeneralName(principal)))); + form = new V2Form(new GeneralNames(new GeneralName(principal))); + } + + private object[] GetNames() + { + GeneralNames name; + if (form is V2Form) + { + name = ((V2Form)form).IssuerName; + } + else + { + name = (GeneralNames)form; + } + + GeneralName[] names = name.GetNames(); + + int count = 0; + for (int i = 0; i != names.Length; i++) + { + if (names[i].TagNo == GeneralName.DirectoryName) + { + ++count; + } + } + + object[] result = new object[count]; + + int pos = 0; + for (int i = 0; i != names.Length; i++) + { + if (names[i].TagNo == GeneralName.DirectoryName) + { + result[pos++] = X509Name.GetInstance(names[i].Name); + } + } + + return result; + } + + /// Return any principal objects inside the attribute certificate issuer object. + /// An array of IPrincipal objects (usually X509Principal). + public X509Name[] GetPrincipals() + { + object[] p = this.GetNames(); + + int count = 0; + for (int i = 0; i != p.Length; i++) + { + if (p[i] is X509Name) + { + ++count; + } + } + + X509Name[] result = new X509Name[count]; + + int pos = 0; + for (int i = 0; i != p.Length; i++) + { + if (p[i] is X509Name) + { + result[pos++] = (X509Name)p[i]; + } + } + + return result; + } + + private bool MatchesDN( + X509Name subject, + GeneralNames targets) + { + GeneralName[] names = targets.GetNames(); + + for (int i = 0; i != names.Length; i++) + { + GeneralName gn = names[i]; + + if (gn.TagNo == GeneralName.DirectoryName) + { + try + { + if (X509Name.GetInstance(gn.Name).Equivalent(subject)) + { + return true; + } + } + catch (Exception) + { + } + } + } + + return false; + } + + public object Clone() + { + return new AttributeCertificateIssuer(AttCertIssuer.GetInstance(form)); + } + + public bool Match( + X509Certificate x509Cert) + { + if (form is V2Form) + { + V2Form issuer = (V2Form) form; + if (issuer.BaseCertificateID != null) + { + return issuer.BaseCertificateID.Serial.HasValue(x509Cert.SerialNumber) + && MatchesDN(x509Cert.IssuerDN, issuer.BaseCertificateID.Issuer); + } + + return MatchesDN(x509Cert.SubjectDN, issuer.IssuerName); + } + + return MatchesDN(x509Cert.SubjectDN, (GeneralNames) form); + } + + public override bool Equals( + object obj) + { + if (obj == this) + { + return true; + } + + if (!(obj is AttributeCertificateIssuer)) + { + return false; + } + + AttributeCertificateIssuer other = (AttributeCertificateIssuer)obj; + + return this.form.Equals(other.form); + } + + public override int GetHashCode() + { + return this.form.GetHashCode(); + } + + public bool Match( + object obj) + { + if (!(obj is X509Certificate)) + { + return false; + } + + //return Match((Certificate)obj); + return Match((X509Certificate)obj); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/AttributeCertificateIssuer.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/AttributeCertificateIssuer.cs.meta new file mode 100644 index 0000000..06f98ad --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/AttributeCertificateIssuer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 26a5ea08e0b2921429d24f75523dd3d8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/IX509AttributeCertificate.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/IX509AttributeCertificate.cs new file mode 100644 index 0000000..9a3004e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/IX509AttributeCertificate.cs @@ -0,0 +1,57 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.X509 +{ + /// Interface for an X.509 Attribute Certificate. + public interface IX509AttributeCertificate + : IX509Extension + { + /// The version number for the certificate. + int Version { get; } + + /// The serial number for the certificate. + BigInteger SerialNumber { get; } + + /// The UTC DateTime before which the certificate is not valid. + DateTime NotBefore { get; } + + /// The UTC DateTime after which the certificate is not valid. + DateTime NotAfter { get; } + + /// The holder of the certificate. + AttributeCertificateHolder Holder { get; } + + /// The issuer details for the certificate. + AttributeCertificateIssuer Issuer { get; } + + /// Return the attributes contained in the attribute block in the certificate. + /// An array of attributes. + X509Attribute[] GetAttributes(); + + /// Return the attributes with the same type as the passed in oid. + /// The object identifier we wish to match. + /// An array of matched attributes, null if there is no match. + X509Attribute[] GetAttributes(string oid); + + bool[] GetIssuerUniqueID(); + + bool IsValidNow { get; } + bool IsValid(DateTime date); + + void CheckValidity(); + void CheckValidity(DateTime date); + + byte[] GetSignature(); + + void Verify(AsymmetricKeyParameter publicKey); + + /// Return an ASN.1 encoded byte array representing the attribute certificate. + /// An ASN.1 encoded byte array. + /// If the certificate cannot be encoded. + byte[] GetEncoded(); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/IX509AttributeCertificate.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/IX509AttributeCertificate.cs.meta new file mode 100644 index 0000000..a7077e8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/IX509AttributeCertificate.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 24d9bb8b91046c5469ba1b994c9a4894 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/IX509Extension.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/IX509Extension.cs new file mode 100644 index 0000000..e861e87 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/IX509Extension.cs @@ -0,0 +1,27 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.X509 +{ + public interface IX509Extension + { + /// + /// Get all critical extension values, by oid + /// + /// IDictionary with string (OID) keys and Asn1OctetString values + ISet GetCriticalExtensionOids(); + + /// + /// Get all non-critical extension values, by oid + /// + /// IDictionary with string (OID) keys and Asn1OctetString values + ISet GetNonCriticalExtensionOids(); + + [Obsolete("Use version taking a DerObjectIdentifier instead")] + Asn1OctetString GetExtensionValue(string oid); + + Asn1OctetString GetExtensionValue(DerObjectIdentifier oid); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/IX509Extension.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/IX509Extension.cs.meta new file mode 100644 index 0000000..a8946c8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/IX509Extension.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 49f6431abdee6a049aee256317325beb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/PEMParser.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/PEMParser.cs new file mode 100644 index 0000000..28f28ee --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/PEMParser.cs @@ -0,0 +1,95 @@ +using System; +using System.IO; +using System.Text; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.X509 +{ + class PemParser + { + private readonly string _header1; + private readonly string _header2; + private readonly string _footer1; + private readonly string _footer2; + + internal PemParser( + string type) + { + _header1 = "-----BEGIN " + type + "-----"; + _header2 = "-----BEGIN X509 " + type + "-----"; + _footer1 = "-----END " + type + "-----"; + _footer2 = "-----END X509 " + type + "-----"; + } + + private string ReadLine( + Stream inStream) + { + int c; + StringBuilder l = new StringBuilder(); + + do + { + while (((c = inStream.ReadByte()) != '\r') && c != '\n' && (c >= 0)) + { + if (c == '\r') + { + continue; + } + + l.Append((char)c); + } + } + while (c >= 0 && l.Length == 0); + + if (c < 0) + { + return null; + } + + return l.ToString(); + } + + internal Asn1Sequence ReadPemObject( + Stream inStream) + { + string line; + StringBuilder pemBuf = new StringBuilder(); + + while ((line = ReadLine(inStream)) != null) + { + if (Platform.StartsWith(line, _header1) || Platform.StartsWith(line, _header2)) + { + break; + } + } + + while ((line = ReadLine(inStream)) != null) + { + if (Platform.StartsWith(line, _footer1) || Platform.StartsWith(line, _footer2)) + { + break; + } + + pemBuf.Append(line); + } + + if (pemBuf.Length != 0) + { + Asn1Object o = Asn1Object.FromByteArray(Base64.Decode(pemBuf.ToString())); + + if (!(o is Asn1Sequence)) + { + throw new IOException("malformed PEM data encountered"); + } + + return (Asn1Sequence) o; + } + + return null; + } + } +} + diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/PEMParser.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/PEMParser.cs.meta new file mode 100644 index 0000000..cfd9877 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/PEMParser.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 52af9e2f205de3544b5a41346e48ac9a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/PrincipalUtil.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/PrincipalUtil.cs new file mode 100644 index 0000000..0edc4a3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/PrincipalUtil.cs @@ -0,0 +1,70 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Security.Certificates; + +namespace Org.BouncyCastle.X509 +{ + /// + /// A utility class that will extract X509Principal objects from X.509 certificates. + ///

    + /// Use this in preference to trying to recreate a principal from a string, not all + /// DNs are what they should be, so it's best to leave them encoded where they + /// can be.

    + ///
    + public class PrincipalUtilities + { + /// Return the issuer of the given cert as an X509Principal. + public static X509Name GetIssuerX509Principal( + X509Certificate cert) + { + try + { + TbsCertificateStructure tbsCert = TbsCertificateStructure.GetInstance( + Asn1Object.FromByteArray(cert.GetTbsCertificate())); + + return tbsCert.Issuer; + } + catch (Exception e) + { + throw new CertificateEncodingException("Could not extract issuer", e); + } + } + + /// Return the subject of the given cert as an X509Principal. + public static X509Name GetSubjectX509Principal( + X509Certificate cert) + { + try + { + TbsCertificateStructure tbsCert = TbsCertificateStructure.GetInstance( + Asn1Object.FromByteArray(cert.GetTbsCertificate())); + + return tbsCert.Subject; + } + catch (Exception e) + { + throw new CertificateEncodingException("Could not extract subject", e); + } + } + + /// Return the issuer of the given CRL as an X509Principal. + public static X509Name GetIssuerX509Principal( + X509Crl crl) + { + try + { + TbsCertificateList tbsCertList = TbsCertificateList.GetInstance( + Asn1Object.FromByteArray(crl.GetTbsCertList())); + + return tbsCertList.Issuer; + } + catch (Exception e) + { + throw new CrlException("Could not extract issuer", e); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/PrincipalUtil.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/PrincipalUtil.cs.meta new file mode 100644 index 0000000..1d3a72d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/PrincipalUtil.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6f9d735debca75a4e8dbb0045c6c282b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/SubjectPublicKeyInfoFactory.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/SubjectPublicKeyInfoFactory.cs new file mode 100644 index 0000000..395c312 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/SubjectPublicKeyInfoFactory.cs @@ -0,0 +1,277 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Asn1.EdEC; +using Org.BouncyCastle.Asn1.Oiw; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.Rosstandart; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.X509 +{ + /// + /// A factory to produce Public Key Info Objects. + /// + public sealed class SubjectPublicKeyInfoFactory + { + private SubjectPublicKeyInfoFactory() + { + } + + /// + /// Create a Subject Public Key Info object for a given public key. + /// + /// One of ElGammalPublicKeyParameters, DSAPublicKeyParameter, DHPublicKeyParameters, RsaKeyParameters or ECPublicKeyParameters + /// A subject public key info object. + /// Throw exception if object provided is not one of the above. + public static SubjectPublicKeyInfo CreateSubjectPublicKeyInfo( + AsymmetricKeyParameter publicKey) + { + if (publicKey == null) + throw new ArgumentNullException("publicKey"); + if (publicKey.IsPrivate) + throw new ArgumentException("Private key passed - public key expected.", "publicKey"); + + if (publicKey is ElGamalPublicKeyParameters) + { + ElGamalPublicKeyParameters _key = (ElGamalPublicKeyParameters)publicKey; + ElGamalParameters kp = _key.Parameters; + + SubjectPublicKeyInfo info = new SubjectPublicKeyInfo( + new AlgorithmIdentifier( + OiwObjectIdentifiers.ElGamalAlgorithm, + new ElGamalParameter(kp.P, kp.G).ToAsn1Object()), + new DerInteger(_key.Y)); + + return info; + } + + if (publicKey is DsaPublicKeyParameters) + { + DsaPublicKeyParameters _key = (DsaPublicKeyParameters) publicKey; + DsaParameters kp = _key.Parameters; + Asn1Encodable ae = kp == null + ? null + : new DsaParameter(kp.P, kp.Q, kp.G).ToAsn1Object(); + + return new SubjectPublicKeyInfo( + new AlgorithmIdentifier(X9ObjectIdentifiers.IdDsa, ae), + new DerInteger(_key.Y)); + } + + if (publicKey is DHPublicKeyParameters) + { + DHPublicKeyParameters _key = (DHPublicKeyParameters) publicKey; + DHParameters kp = _key.Parameters; + + SubjectPublicKeyInfo info = new SubjectPublicKeyInfo( + new AlgorithmIdentifier( + _key.AlgorithmOid, + new DHParameter(kp.P, kp.G, kp.L).ToAsn1Object()), + new DerInteger(_key.Y)); + + return info; + } // End of DH + + if (publicKey is RsaKeyParameters) + { + RsaKeyParameters _key = (RsaKeyParameters) publicKey; + + SubjectPublicKeyInfo info = new SubjectPublicKeyInfo( + new AlgorithmIdentifier(PkcsObjectIdentifiers.RsaEncryption, DerNull.Instance), + new RsaPublicKeyStructure(_key.Modulus, _key.Exponent).ToAsn1Object()); + + return info; + } // End of RSA. + + if (publicKey is ECPublicKeyParameters) + { + + ECPublicKeyParameters _key = (ECPublicKeyParameters) publicKey; + + + if (_key.Parameters is ECGost3410Parameters) + { + ECGost3410Parameters gostParams = (ECGost3410Parameters)_key.Parameters; + + BigInteger bX = _key.Q.AffineXCoord.ToBigInteger(); + BigInteger bY = _key.Q.AffineYCoord.ToBigInteger(); + bool is512 = (bX.BitLength > 256); + + Gost3410PublicKeyAlgParameters parameters = new Gost3410PublicKeyAlgParameters( + gostParams.PublicKeyParamSet, + gostParams.DigestParamSet, + gostParams.EncryptionParamSet); + + int encKeySize; + int offset; + DerObjectIdentifier algIdentifier; + if (is512) + { + encKeySize = 128; + offset = 64; + algIdentifier = RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512; + } + else + { + encKeySize = 64; + offset = 32; + algIdentifier = RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256; + } + + byte[] encKey = new byte[encKeySize]; + + ExtractBytes(encKey, encKeySize / 2, 0, bX); + ExtractBytes(encKey, encKeySize / 2, offset, bY); + + return new SubjectPublicKeyInfo(new AlgorithmIdentifier(algIdentifier, parameters), new DerOctetString(encKey)); + + + } // End of ECGOST3410_2012 + + + + + + if (_key.AlgorithmName == "ECGOST3410") + { + if (_key.PublicKeyParamSet == null) + throw Platform.CreateNotImplementedException("Not a CryptoPro parameter set"); + + ECPoint q = _key.Q.Normalize(); + BigInteger bX = q.AffineXCoord.ToBigInteger(); + BigInteger bY = q.AffineYCoord.ToBigInteger(); + + byte[] encKey = new byte[64]; + ExtractBytes(encKey, 0, bX); + ExtractBytes(encKey, 32, bY); + + Gost3410PublicKeyAlgParameters gostParams = new Gost3410PublicKeyAlgParameters( + _key.PublicKeyParamSet, CryptoProObjectIdentifiers.GostR3411x94CryptoProParamSet); + + AlgorithmIdentifier algID = new AlgorithmIdentifier( + CryptoProObjectIdentifiers.GostR3410x2001, + gostParams.ToAsn1Object()); + + return new SubjectPublicKeyInfo(algID, new DerOctetString(encKey)); + } + else + { + X962Parameters x962; + if (_key.PublicKeyParamSet == null) + { + ECDomainParameters kp = _key.Parameters; + X9ECParameters ecP = new X9ECParameters(kp.Curve, kp.G, kp.N, kp.H, kp.GetSeed()); + + x962 = new X962Parameters(ecP); + } + else + { + x962 = new X962Parameters(_key.PublicKeyParamSet); + } + + byte[] pubKey = _key.Q.GetEncoded(false); + + AlgorithmIdentifier algID = new AlgorithmIdentifier( + X9ObjectIdentifiers.IdECPublicKey, x962.ToAsn1Object()); + + return new SubjectPublicKeyInfo(algID, pubKey); + } + } // End of EC + + if (publicKey is Gost3410PublicKeyParameters) + { + Gost3410PublicKeyParameters _key = (Gost3410PublicKeyParameters) publicKey; + + if (_key.PublicKeyParamSet == null) + throw Platform.CreateNotImplementedException("Not a CryptoPro parameter set"); + + byte[] keyEnc = _key.Y.ToByteArrayUnsigned(); + byte[] keyBytes = new byte[keyEnc.Length]; + + for (int i = 0; i != keyBytes.Length; i++) + { + keyBytes[i] = keyEnc[keyEnc.Length - 1 - i]; // must be little endian + } + + Gost3410PublicKeyAlgParameters algParams = new Gost3410PublicKeyAlgParameters( + _key.PublicKeyParamSet, CryptoProObjectIdentifiers.GostR3411x94CryptoProParamSet); + + AlgorithmIdentifier algID = new AlgorithmIdentifier( + CryptoProObjectIdentifiers.GostR3410x94, + algParams.ToAsn1Object()); + + return new SubjectPublicKeyInfo(algID, new DerOctetString(keyBytes)); + } + + if (publicKey is X448PublicKeyParameters) + { + X448PublicKeyParameters key = (X448PublicKeyParameters)publicKey; + + return new SubjectPublicKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_X448), key.GetEncoded()); + } + + if (publicKey is X25519PublicKeyParameters) + { + X25519PublicKeyParameters key = (X25519PublicKeyParameters)publicKey; + + return new SubjectPublicKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_X25519), key.GetEncoded()); + } + + if (publicKey is Ed448PublicKeyParameters) + { + Ed448PublicKeyParameters key = (Ed448PublicKeyParameters)publicKey; + + return new SubjectPublicKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_Ed448), key.GetEncoded()); + } + + if (publicKey is Ed25519PublicKeyParameters) + { + Ed25519PublicKeyParameters key = (Ed25519PublicKeyParameters)publicKey; + + return new SubjectPublicKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_Ed25519), key.GetEncoded()); + } + + throw new ArgumentException("Class provided no convertible: " + Platform.GetTypeName(publicKey)); + } + + private static void ExtractBytes( + byte[] encKey, + int offset, + BigInteger bI) + { + byte[] val = bI.ToByteArray(); + int n = (bI.BitLength + 7) / 8; + + for (int i = 0; i < n; ++i) + { + encKey[offset + i] = val[val.Length - 1 - i]; + } + } + + + private static void ExtractBytes(byte[] encKey, int size, int offSet, BigInteger bI) + { + byte[] val = bI.ToByteArray(); + if (val.Length < size) + { + byte[] tmp = new byte[size]; + Array.Copy(val, 0, tmp, tmp.Length - val.Length, val.Length); + val = tmp; + } + + for (int i = 0; i != size; i++) + { + encKey[offSet + i] = val[val.Length - 1 - i]; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/SubjectPublicKeyInfoFactory.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/SubjectPublicKeyInfoFactory.cs.meta new file mode 100644 index 0000000..8d17d15 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/SubjectPublicKeyInfoFactory.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 06290f6f78e5db6479516918492223c5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509AttrCertParser.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509AttrCertParser.cs new file mode 100644 index 0000000..a5c0736 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509AttrCertParser.cs @@ -0,0 +1,173 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Security.Certificates; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.X509 +{ + public class X509AttrCertParser + { + private static readonly PemParser PemAttrCertParser = new PemParser("ATTRIBUTE CERTIFICATE"); + + private Asn1Set sData; + private int sDataObjectCount; + private Stream currentStream; + + private IX509AttributeCertificate ReadDerCertificate( + Asn1InputStream dIn) + { + Asn1Sequence seq = (Asn1Sequence)dIn.ReadObject(); + + if (seq.Count > 1 && seq[0] is DerObjectIdentifier) + { + if (seq[0].Equals(PkcsObjectIdentifiers.SignedData)) + { + sData = SignedData.GetInstance( + Asn1Sequence.GetInstance((Asn1TaggedObject) seq[1], true)).Certificates; + + return GetCertificate(); + } + } + +// return new X509V2AttributeCertificate(seq.getEncoded()); + return new X509V2AttributeCertificate(AttributeCertificate.GetInstance(seq)); + } + + private IX509AttributeCertificate GetCertificate() + { + if (sData != null) + { + while (sDataObjectCount < sData.Count) + { + object obj = sData[sDataObjectCount++]; + + if (obj is Asn1TaggedObject && ((Asn1TaggedObject)obj).TagNo == 2) + { + //return new X509V2AttributeCertificate( + // Asn1Sequence.GetInstance((Asn1TaggedObject)obj, false).GetEncoded()); + return new X509V2AttributeCertificate( + AttributeCertificate.GetInstance( + Asn1Sequence.GetInstance((Asn1TaggedObject)obj, false))); + } + } + } + + return null; + } + + private IX509AttributeCertificate ReadPemCertificate( + Stream inStream) + { + Asn1Sequence seq = PemAttrCertParser.ReadPemObject(inStream); + + return seq == null + ? null + //: new X509V2AttributeCertificate(seq.getEncoded()); + : new X509V2AttributeCertificate(AttributeCertificate.GetInstance(seq)); + } + + /// + /// Create loading data from byte array. + /// + /// + public IX509AttributeCertificate ReadAttrCert( + byte[] input) + { + return ReadAttrCert(new MemoryStream(input, false)); + } + + /// + /// Create loading data from byte array. + /// + /// + public ICollection ReadAttrCerts( + byte[] input) + { + return ReadAttrCerts(new MemoryStream(input, false)); + } + + /** + * Generates a certificate object and initializes it with the data + * read from the input stream inStream. + */ + public IX509AttributeCertificate ReadAttrCert( + Stream inStream) + { + if (inStream == null) + throw new ArgumentNullException("inStream"); + if (!inStream.CanRead) + throw new ArgumentException("inStream must be read-able", "inStream"); + + if (currentStream == null) + { + currentStream = inStream; + sData = null; + sDataObjectCount = 0; + } + else if (currentStream != inStream) // reset if input stream has changed + { + currentStream = inStream; + sData = null; + sDataObjectCount = 0; + } + + try + { + if (sData != null) + { + if (sDataObjectCount != sData.Count) + { + return GetCertificate(); + } + + sData = null; + sDataObjectCount = 0; + return null; + } + + PushbackStream pis = new PushbackStream(inStream); + int tag = pis.ReadByte(); + + if (tag < 0) + return null; + + pis.Unread(tag); + + if (tag != 0x30) // assume ascii PEM encoded. + { + return ReadPemCertificate(pis); + } + + return ReadDerCertificate(new Asn1InputStream(pis)); + } + catch (Exception e) + { + throw new CertificateException(e.ToString()); + } + } + + /** + * Returns a (possibly empty) collection view of the certificates + * read from the given input stream inStream. + */ + public ICollection ReadAttrCerts( + Stream inStream) + { + IX509AttributeCertificate attrCert; + IList attrCerts = Platform.CreateArrayList(); + + while ((attrCert = ReadAttrCert(inStream)) != null) + { + attrCerts.Add(attrCert); + } + + return attrCerts; + } + } +} \ No newline at end of file diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509AttrCertParser.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509AttrCertParser.cs.meta new file mode 100644 index 0000000..3efae23 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509AttrCertParser.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9be872de044321045a86a9ece96808dc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509Attribute.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509Attribute.cs new file mode 100644 index 0000000..248d66c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509Attribute.cs @@ -0,0 +1,76 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; + +namespace Org.BouncyCastle.X509 +{ + /** + * Class for carrying the values in an X.509 Attribute. + */ + public class X509Attribute + : Asn1Encodable + { + private readonly AttributeX509 attr; + + /** + * @param at an object representing an attribute. + */ + internal X509Attribute( + Asn1Encodable at) + { + this.attr = AttributeX509.GetInstance(at); + } + + /** + * Create an X.509 Attribute with the type given by the passed in oid and + * the value represented by an ASN.1 Set containing value. + * + * @param oid type of the attribute + * @param value value object to go into the atribute's value set. + */ + public X509Attribute( + string oid, + Asn1Encodable value) + { + this.attr = new AttributeX509(new DerObjectIdentifier(oid), new DerSet(value)); + } + + /** + * Create an X.59 Attribute with the type given by the passed in oid and the + * value represented by an ASN.1 Set containing the objects in value. + * + * @param oid type of the attribute + * @param value vector of values to go in the attribute's value set. + */ + public X509Attribute( + string oid, + Asn1EncodableVector value) + { + this.attr = new AttributeX509(new DerObjectIdentifier(oid), new DerSet(value)); + } + + public string Oid + { + get { return attr.AttrType.Id; } + } + + public Asn1Encodable[] GetValues() + { + Asn1Set s = attr.AttrValues; + Asn1Encodable[] values = new Asn1Encodable[s.Count]; + + for (int i = 0; i != s.Count; i++) + { + values[i] = (Asn1Encodable)s[i]; + } + + return values; + } + + public override Asn1Object ToAsn1Object() + { + return attr.ToAsn1Object(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509Attribute.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509Attribute.cs.meta new file mode 100644 index 0000000..0872b53 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509Attribute.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5c6350db8f7c0814591a493d9123c137 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509CertPairParser.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509CertPairParser.cs new file mode 100644 index 0000000..8261259 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509CertPairParser.cs @@ -0,0 +1,95 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Security.Certificates; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.X509 +{ + public class X509CertPairParser + { + private Stream currentStream; + + private X509CertificatePair ReadDerCrossCertificatePair( + Stream inStream) + { + Asn1InputStream dIn = new Asn1InputStream(inStream);//, ProviderUtil.getReadLimit(in)); + Asn1Sequence seq = (Asn1Sequence)dIn.ReadObject(); + CertificatePair pair = CertificatePair.GetInstance(seq); + return new X509CertificatePair(pair); + } + + /// + /// Create loading data from byte array. + /// + /// + public X509CertificatePair ReadCertPair( + byte[] input) + { + return ReadCertPair(new MemoryStream(input, false)); + } + + /// + /// Create loading data from byte array. + /// + /// + public ICollection ReadCertPairs( + byte[] input) + { + return ReadCertPairs(new MemoryStream(input, false)); + } + + public X509CertificatePair ReadCertPair( + Stream inStream) + { + if (inStream == null) + throw new ArgumentNullException("inStream"); + if (!inStream.CanRead) + throw new ArgumentException("inStream must be read-able", "inStream"); + + if (currentStream == null) + { + currentStream = inStream; + } + else if (currentStream != inStream) // reset if input stream has changed + { + currentStream = inStream; + } + + try + { + PushbackStream pis = new PushbackStream(inStream); + int tag = pis.ReadByte(); + + if (tag < 0) + return null; + + pis.Unread(tag); + + return ReadDerCrossCertificatePair(pis); + } + catch (Exception e) + { + throw new CertificateException(e.ToString()); + } + } + + public ICollection ReadCertPairs( + Stream inStream) + { + X509CertificatePair certPair; + IList certPairs = Platform.CreateArrayList(); + + while ((certPair = ReadCertPair(inStream)) != null) + { + certPairs.Add(certPair); + } + + return certPairs; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509CertPairParser.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509CertPairParser.cs.meta new file mode 100644 index 0000000..1291f5a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509CertPairParser.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8933b561d766d8d45a5d0fb1fe328053 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509Certificate.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509Certificate.cs new file mode 100644 index 0000000..985ec0a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509Certificate.cs @@ -0,0 +1,709 @@ +using System; +using System.Collections; +using System.IO; +using System.Text; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Misc; +using Org.BouncyCastle.Asn1.Utilities; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Operators; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Security.Certificates; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; +using Org.BouncyCastle.X509.Extension; + +namespace Org.BouncyCastle.X509 +{ + /// + /// An Object representing an X509 Certificate. + /// Has static methods for loading Certificates encoded in many forms that return X509Certificate Objects. + /// + public class X509Certificate + : X509ExtensionBase + // , PKCS12BagAttributeCarrier + { + private class CachedEncoding + { + private readonly byte[] encoding; + private readonly CertificateEncodingException exception; + + internal CachedEncoding(byte[] encoding, CertificateEncodingException exception) + { + this.encoding = encoding; + this.exception = exception; + } + + internal byte[] Encoding + { + get { return encoding; } + } + + internal byte[] GetEncoded() + { + if (null != exception) + throw exception; + + if (null == encoding) + throw new CertificateEncodingException(); + + return encoding; + } + } + + private readonly X509CertificateStructure c; + //private Hashtable pkcs12Attributes = Platform.CreateHashtable(); + //private ArrayList pkcs12Ordering = Platform.CreateArrayList(); + private readonly string sigAlgName; + private readonly byte[] sigAlgParams; + private readonly BasicConstraints basicConstraints; + private readonly bool[] keyUsage; + + private readonly object cacheLock = new object(); + private AsymmetricKeyParameter publicKeyValue; + private CachedEncoding cachedEncoding; + + private volatile bool hashValueSet; + private volatile int hashValue; + + protected X509Certificate() + { + } + + public X509Certificate(byte[] certData) + : this(X509CertificateStructure.GetInstance(certData)) + { + } + + public X509Certificate(X509CertificateStructure c) + { + this.c = c; + + try + { + this.sigAlgName = X509SignatureUtilities.GetSignatureName(c.SignatureAlgorithm); + + Asn1Encodable parameters = c.SignatureAlgorithm.Parameters; + this.sigAlgParams = (null == parameters) ? null : parameters.GetEncoded(Asn1Encodable.Der); + } + catch (Exception e) + { + throw new CertificateParsingException("Certificate contents invalid: " + e); + } + + try + { + Asn1OctetString str = this.GetExtensionValue(new DerObjectIdentifier("2.5.29.19")); + + if (str != null) + { + basicConstraints = BasicConstraints.GetInstance( + X509ExtensionUtilities.FromExtensionValue(str)); + } + } + catch (Exception e) + { + throw new CertificateParsingException("cannot construct BasicConstraints: " + e); + } + + try + { + Asn1OctetString str = this.GetExtensionValue(new DerObjectIdentifier("2.5.29.15")); + + if (str != null) + { + DerBitString bits = DerBitString.GetInstance( + X509ExtensionUtilities.FromExtensionValue(str)); + + byte[] bytes = bits.GetBytes(); + int length = (bytes.Length * 8) - bits.PadBits; + + keyUsage = new bool[(length < 9) ? 9 : length]; + + for (int i = 0; i != length; i++) + { + keyUsage[i] = (bytes[i / 8] & (0x80 >> (i % 8))) != 0; + } + } + else + { + keyUsage = null; + } + } + catch (Exception e) + { + throw new CertificateParsingException("cannot construct KeyUsage: " + e); + } + } + + // internal X509Certificate( + // Asn1Sequence seq) + // { + // this.c = X509CertificateStructure.GetInstance(seq); + // } + + // /// + // /// Load certificate from byte array. + // /// + // /// Byte array containing encoded X509Certificate. + // public X509Certificate( + // byte[] encoded) + // : this((Asn1Sequence) new Asn1InputStream(encoded).ReadObject()) + // { + // } + // + // /// + // /// Load certificate from Stream. + // /// Must be positioned at start of certificate. + // /// + // /// + // public X509Certificate( + // Stream input) + // : this((Asn1Sequence) new Asn1InputStream(input).ReadObject()) + // { + // } + + public virtual X509CertificateStructure CertificateStructure + { + get { return c; } + } + + /// + /// Return true if the current time is within the start and end times nominated on the certificate. + /// + /// true id certificate is valid for the current time. + public virtual bool IsValidNow + { + get { return IsValid(DateTime.UtcNow); } + } + + /// + /// Return true if the nominated time is within the start and end times nominated on the certificate. + /// + /// The time to test validity against. + /// True if certificate is valid for nominated time. + public virtual bool IsValid( + DateTime time) + { + return time.CompareTo(NotBefore) >= 0 && time.CompareTo(NotAfter) <= 0; + } + + /// + /// Checks if the current date is within certificate's validity period. + /// + public virtual void CheckValidity() + { + this.CheckValidity(DateTime.UtcNow); + } + + /// + /// Checks if the given date is within certificate's validity period. + /// + /// if the certificate is expired by given date + /// if the certificate is not yet valid on given date + public virtual void CheckValidity( + DateTime time) + { + if (time.CompareTo(NotAfter) > 0) + throw new CertificateExpiredException("certificate expired on " + c.EndDate.GetTime()); + if (time.CompareTo(NotBefore) < 0) + throw new CertificateNotYetValidException("certificate not valid until " + c.StartDate.GetTime()); + } + + /// + /// Return the certificate's version. + /// + /// An integer whose value Equals the version of the cerficate. + public virtual int Version + { + get { return c.Version; } + } + + /// + /// Return a BigInteger containing the serial number. + /// + /// The Serial number. + public virtual BigInteger SerialNumber + { + get { return c.SerialNumber.Value; } + } + + /// + /// Get the Issuer Distinguished Name. (Who signed the certificate.) + /// + /// And X509Object containing name and value pairs. + // public IPrincipal IssuerDN + public virtual X509Name IssuerDN + { + get { return c.Issuer; } + } + + /// + /// Get the subject of this certificate. + /// + /// An X509Name object containing name and value pairs. + // public IPrincipal SubjectDN + public virtual X509Name SubjectDN + { + get { return c.Subject; } + } + + /// + /// The time that this certificate is valid from. + /// + /// A DateTime object representing that time in the local time zone. + public virtual DateTime NotBefore + { + get { return c.StartDate.ToDateTime(); } + } + + /// + /// The time that this certificate is valid up to. + /// + /// A DateTime object representing that time in the local time zone. + public virtual DateTime NotAfter + { + get { return c.EndDate.ToDateTime(); } + } + + /// + /// Return the Der encoded TbsCertificate data. + /// This is the certificate component less the signature. + /// To Get the whole certificate call the GetEncoded() member. + /// + /// A byte array containing the Der encoded Certificate component. + public virtual byte[] GetTbsCertificate() + { + return c.TbsCertificate.GetDerEncoded(); + } + + /// + /// The signature. + /// + /// A byte array containg the signature of the certificate. + public virtual byte[] GetSignature() + { + return c.GetSignatureOctets(); + } + + /// + /// A meaningful version of the Signature Algorithm. (EG SHA1WITHRSA) + /// + /// A sting representing the signature algorithm. + public virtual string SigAlgName + { + get { return sigAlgName; } + } + + /// + /// Get the Signature Algorithms Object ID. + /// + /// A string containg a '.' separated object id. + public virtual string SigAlgOid + { + get { return c.SignatureAlgorithm.Algorithm.Id; } + } + + /// + /// Get the signature algorithms parameters. (EG DSA Parameters) + /// + /// A byte array containing the Der encoded version of the parameters or null if there are none. + public virtual byte[] GetSigAlgParams() + { + return Arrays.Clone(sigAlgParams); + } + + /// + /// Get the issuers UID. + /// + /// A DerBitString. + public virtual DerBitString IssuerUniqueID + { + get { return c.TbsCertificate.IssuerUniqueID; } + } + + /// + /// Get the subjects UID. + /// + /// A DerBitString. + public virtual DerBitString SubjectUniqueID + { + get { return c.TbsCertificate.SubjectUniqueID; } + } + + /// + /// Get a key usage guidlines. + /// + public virtual bool[] GetKeyUsage() + { + return Arrays.Clone(keyUsage); + } + + // TODO Replace with something that returns a list of DerObjectIdentifier + public virtual IList GetExtendedKeyUsage() + { + Asn1OctetString str = this.GetExtensionValue(new DerObjectIdentifier("2.5.29.37")); + + if (str == null) + return null; + + try + { + Asn1Sequence seq = Asn1Sequence.GetInstance( + X509ExtensionUtilities.FromExtensionValue(str)); + + IList list = Platform.CreateArrayList(); + + foreach (DerObjectIdentifier oid in seq) + { + list.Add(oid.Id); + } + + return list; + } + catch (Exception e) + { + throw new CertificateParsingException("error processing extended key usage extension", e); + } + } + + public virtual int GetBasicConstraints() + { + if (basicConstraints != null && basicConstraints.IsCA()) + { + if (basicConstraints.PathLenConstraint == null) + { + return int.MaxValue; + } + + return basicConstraints.PathLenConstraint.IntValue; + } + + return -1; + } + + public virtual ICollection GetSubjectAlternativeNames() + { + return GetAlternativeNames("2.5.29.17"); + } + + public virtual ICollection GetIssuerAlternativeNames() + { + return GetAlternativeNames("2.5.29.18"); + } + + protected virtual ICollection GetAlternativeNames( + string oid) + { + Asn1OctetString altNames = GetExtensionValue(new DerObjectIdentifier(oid)); + + if (altNames == null) + return null; + + Asn1Object asn1Object = X509ExtensionUtilities.FromExtensionValue(altNames); + + GeneralNames gns = GeneralNames.GetInstance(asn1Object); + + IList result = Platform.CreateArrayList(); + foreach (GeneralName gn in gns.GetNames()) + { + IList entry = Platform.CreateArrayList(); + entry.Add(gn.TagNo); + entry.Add(gn.Name.ToString()); + result.Add(entry); + } + return result; + } + + protected override X509Extensions GetX509Extensions() + { + return c.Version >= 3 + ? c.TbsCertificate.Extensions + : null; + } + + /// + /// Get the public key of the subject of the certificate. + /// + /// The public key parameters. + public virtual AsymmetricKeyParameter GetPublicKey() + { + // Cache the public key to support repeated-use optimizations + lock (cacheLock) + { + if (null != publicKeyValue) + return publicKeyValue; + } + + AsymmetricKeyParameter temp = PublicKeyFactory.CreateKey(c.SubjectPublicKeyInfo); + + lock (cacheLock) + { + if (null == publicKeyValue) + { + publicKeyValue = temp; + } + + return publicKeyValue; + } + } + + /// + /// Return the DER encoding of this certificate. + /// + /// A byte array containing the DER encoding of this certificate. + /// If there is an error encoding the certificate. + public virtual byte[] GetEncoded() + { + return Arrays.Clone(GetCachedEncoding().GetEncoded()); + } + + public override bool Equals(object other) + { + if (this == other) + return true; + + X509Certificate that = other as X509Certificate; + if (null == that) + return false; + + if (this.hashValueSet && that.hashValueSet) + { + if (this.hashValue != that.hashValue) + return false; + } + else if (null == this.cachedEncoding || null == that.cachedEncoding) + { + DerBitString signature = c.Signature; + if (null != signature && !signature.Equals(that.c.Signature)) + return false; + } + + byte[] thisEncoding = this.GetCachedEncoding().Encoding; + byte[] thatEncoding = that.GetCachedEncoding().Encoding; + + return null != thisEncoding + && null != thatEncoding + && Arrays.AreEqual(thisEncoding, thatEncoding); + } + + public override int GetHashCode() + { + if (!hashValueSet) + { + byte[] thisEncoding = this.GetCachedEncoding().Encoding; + + hashValue = Arrays.GetHashCode(thisEncoding); + hashValueSet = true; + } + + return hashValue; + } + + // public void setBagAttribute( + // DERObjectIdentifier oid, + // DEREncodable attribute) + // { + // pkcs12Attributes.put(oid, attribute); + // pkcs12Ordering.addElement(oid); + // } + // + // public DEREncodable getBagAttribute( + // DERObjectIdentifier oid) + // { + // return (DEREncodable)pkcs12Attributes.get(oid); + // } + // + // public Enumeration getBagAttributeKeys() + // { + // return pkcs12Ordering.elements(); + // } + + public override string ToString() + { + StringBuilder buf = new StringBuilder(); + string nl = Platform.NewLine; + + buf.Append(" [0] Version: ").Append(this.Version).Append(nl); + buf.Append(" SerialNumber: ").Append(this.SerialNumber).Append(nl); + buf.Append(" IssuerDN: ").Append(this.IssuerDN).Append(nl); + buf.Append(" Start Date: ").Append(this.NotBefore).Append(nl); + buf.Append(" Final Date: ").Append(this.NotAfter).Append(nl); + buf.Append(" SubjectDN: ").Append(this.SubjectDN).Append(nl); + buf.Append(" Public Key: ").Append(this.GetPublicKey()).Append(nl); + buf.Append(" Signature Algorithm: ").Append(this.SigAlgName).Append(nl); + + byte[] sig = this.GetSignature(); + buf.Append(" Signature: ").Append(Hex.ToHexString(sig, 0, 20)).Append(nl); + + for (int i = 20; i < sig.Length; i += 20) + { + int len = System.Math.Min(20, sig.Length - i); + buf.Append(" ").Append(Hex.ToHexString(sig, i, len)).Append(nl); + } + + X509Extensions extensions = c.TbsCertificate.Extensions; + + if (extensions != null) + { + IEnumerator e = extensions.ExtensionOids.GetEnumerator(); + + if (e.MoveNext()) + { + buf.Append(" Extensions: \n"); + } + + do + { + DerObjectIdentifier oid = (DerObjectIdentifier)e.Current; + X509Extension ext = extensions.GetExtension(oid); + + if (ext.Value != null) + { + Asn1Object obj = X509ExtensionUtilities.FromExtensionValue(ext.Value); + + buf.Append(" critical(").Append(ext.IsCritical).Append(") "); + try + { + if (oid.Equals(X509Extensions.BasicConstraints)) + { + buf.Append(BasicConstraints.GetInstance(obj)); + } + else if (oid.Equals(X509Extensions.KeyUsage)) + { + buf.Append(KeyUsage.GetInstance(obj)); + } + else if (oid.Equals(MiscObjectIdentifiers.NetscapeCertType)) + { + buf.Append(new NetscapeCertType((DerBitString)obj)); + } + else if (oid.Equals(MiscObjectIdentifiers.NetscapeRevocationUrl)) + { + buf.Append(new NetscapeRevocationUrl((DerIA5String)obj)); + } + else if (oid.Equals(MiscObjectIdentifiers.VerisignCzagExtension)) + { + buf.Append(new VerisignCzagExtension((DerIA5String)obj)); + } + else + { + buf.Append(oid.Id); + buf.Append(" value = ").Append(Asn1Dump.DumpAsString(obj)); + //buf.Append(" value = ").Append("*****").Append(nl); + } + } + catch (Exception) + { + buf.Append(oid.Id); + //buf.Append(" value = ").Append(new string(Hex.encode(ext.getValue().getOctets()))).Append(nl); + buf.Append(" value = ").Append("*****"); + } + } + + buf.Append(nl); + } + while (e.MoveNext()); + } + + return buf.ToString(); + } + + /// + /// Verify the certificate's signature using the nominated public key. + /// + /// An appropriate public key parameter object, RsaPublicKeyParameters, DsaPublicKeyParameters or ECDsaPublicKeyParameters + /// True if the signature is valid. + /// If key submitted is not of the above nominated types. + public virtual void Verify( + AsymmetricKeyParameter key) + { + CheckSignature(new Asn1VerifierFactory(c.SignatureAlgorithm, key)); + } + + /// + /// Verify the certificate's signature using a verifier created using the passed in verifier provider. + /// + /// An appropriate provider for verifying the certificate's signature. + /// True if the signature is valid. + /// If verifier provider is not appropriate or the certificate algorithm is invalid. + public virtual void Verify( + IVerifierFactoryProvider verifierProvider) + { + CheckSignature(verifierProvider.CreateVerifierFactory(c.SignatureAlgorithm)); + } + + protected virtual void CheckSignature( + IVerifierFactory verifier) + { + if (!IsAlgIDEqual(c.SignatureAlgorithm, c.TbsCertificate.Signature)) + throw new CertificateException("signature algorithm in TBS cert not same as outer cert"); + + Asn1Encodable parameters = c.SignatureAlgorithm.Parameters; + + IStreamCalculator streamCalculator = verifier.CreateCalculator(); + + byte[] b = this.GetTbsCertificate(); + + streamCalculator.Stream.Write(b, 0, b.Length); + + Platform.Dispose(streamCalculator.Stream); + + if (!((IVerifier)streamCalculator.GetResult()).IsVerified(this.GetSignature())) + { + throw new InvalidKeyException("Public key presented not for certificate signature"); + } + } + + private CachedEncoding GetCachedEncoding() + { + lock (cacheLock) + { + if (null != cachedEncoding) + return cachedEncoding; + } + + byte[] encoding = null; + CertificateEncodingException exception = null; + try + { + encoding = c.GetEncoded(Asn1Encodable.Der); + } + catch (IOException e) + { + exception = new CertificateEncodingException("Failed to DER-encode certificate", e); + } + + CachedEncoding temp = new CachedEncoding(encoding, exception); + + lock (cacheLock) + { + if (null == cachedEncoding) + { + cachedEncoding = temp; + } + + return cachedEncoding; + } + } + + private static bool IsAlgIDEqual(AlgorithmIdentifier id1, AlgorithmIdentifier id2) + { + if (!id1.Algorithm.Equals(id2.Algorithm)) + return false; + + Asn1Encodable p1 = id1.Parameters; + Asn1Encodable p2 = id2.Parameters; + + if ((p1 == null) == (p2 == null)) + return Platform.Equals(p1, p2); + + // Exactly one of p1, p2 is null at this point + return p1 == null + ? p2.ToAsn1Object() is Asn1Null + : p1.ToAsn1Object() is Asn1Null; + } + } +} \ No newline at end of file diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509Certificate.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509Certificate.cs.meta new file mode 100644 index 0000000..de6c6aa --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509Certificate.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fabb3f6a822e2c84db0843a12d0c204f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509CertificatePair.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509CertificatePair.cs new file mode 100644 index 0000000..fbeba4d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509CertificatePair.cs @@ -0,0 +1,123 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Security.Certificates; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.X509 +{ + /// + /// This class contains a cross certificate pair. Cross certificates pairs may + /// contain two cross signed certificates from two CAs. A certificate from the + /// other CA to this CA is contained in the forward certificate, the certificate + /// from this CA to the other CA is contained in the reverse certificate. + /// + public class X509CertificatePair + { + private readonly X509Certificate forward; + private readonly X509Certificate reverse; + + /// Constructor + /// Certificate from the other CA to this CA. + /// Certificate from this CA to the other CA. + public X509CertificatePair( + X509Certificate forward, + X509Certificate reverse) + { + this.forward = forward; + this.reverse = reverse; + } + + /// Constructor from a ASN.1 CertificatePair structure. + /// The CertificatePair ASN.1 object. + public X509CertificatePair( + CertificatePair pair) + { + if (pair.Forward != null) + { + this.forward = new X509Certificate(pair.Forward); + } + if (pair.Reverse != null) + { + this.reverse = new X509Certificate(pair.Reverse); + } + } + + public byte[] GetEncoded() + { + try + { + X509CertificateStructure f = null, r = null; + + if (forward != null) + { + f = X509CertificateStructure.GetInstance( + Asn1Object.FromByteArray(forward.GetEncoded())); + + if (f == null) + throw new CertificateEncodingException("unable to get encoding for forward"); + } + + if (reverse != null) + { + r = X509CertificateStructure.GetInstance( + Asn1Object.FromByteArray(reverse.GetEncoded())); + + if (r == null) + throw new CertificateEncodingException("unable to get encoding for reverse"); + } + + return new CertificatePair(f, r).GetDerEncoded(); + } + catch (Exception e) + { + // TODO +// throw new ExtCertificateEncodingException(e.toString(), e); + throw new CertificateEncodingException(e.Message, e); + } + } + + /// Returns the certificate from the other CA to this CA. + public X509Certificate Forward + { + get { return forward; } + } + + /// Returns the certificate from this CA to the other CA. + public X509Certificate Reverse + { + get { return reverse; } + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + X509CertificatePair other = obj as X509CertificatePair; + + if (other == null) + return false; + + return Platform.Equals(this.forward, other.forward) + && Platform.Equals(this.reverse, other.reverse); + } + + public override int GetHashCode() + { + int hash = -1; + if (forward != null) + { + hash ^= forward.GetHashCode(); + } + if (reverse != null) + { + hash *= 17; + hash ^= reverse.GetHashCode(); + } + return hash; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509CertificatePair.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509CertificatePair.cs.meta new file mode 100644 index 0000000..c62145c --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509CertificatePair.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: efc98efa34dc2c844ac88da0ed79201e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509CertificateParser.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509CertificateParser.cs new file mode 100644 index 0000000..8f0e740 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509CertificateParser.cs @@ -0,0 +1,183 @@ +using System; +using System.Collections; +using System.IO; +using System.Text; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Security.Certificates; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.X509 +{ + /** + * class for dealing with X509 certificates. + *

    + * At the moment this will deal with "-----BEGIN CERTIFICATE-----" to "-----END CERTIFICATE-----" + * base 64 encoded certs, as well as the BER binaries of certificates and some classes of PKCS#7 + * objects.

    + */ + public class X509CertificateParser + { + private static readonly PemParser PemCertParser = new PemParser("CERTIFICATE"); + + private Asn1Set sData; + private int sDataObjectCount; + private Stream currentStream; + + private X509Certificate ReadDerCertificate( + Asn1InputStream dIn) + { + Asn1Sequence seq = (Asn1Sequence)dIn.ReadObject(); + + if (seq.Count > 1 && seq[0] is DerObjectIdentifier) + { + if (seq[0].Equals(PkcsObjectIdentifiers.SignedData)) + { + sData = SignedData.GetInstance( + Asn1Sequence.GetInstance((Asn1TaggedObject) seq[1], true)).Certificates; + + return GetCertificate(); + } + } + + return CreateX509Certificate(X509CertificateStructure.GetInstance(seq)); + } + + private X509Certificate GetCertificate() + { + if (sData != null) + { + while (sDataObjectCount < sData.Count) + { + object obj = sData[sDataObjectCount++]; + + if (obj is Asn1Sequence) + { + return CreateX509Certificate( + X509CertificateStructure.GetInstance(obj)); + } + } + } + + return null; + } + + private X509Certificate ReadPemCertificate( + Stream inStream) + { + Asn1Sequence seq = PemCertParser.ReadPemObject(inStream); + + return seq == null + ? null + : CreateX509Certificate(X509CertificateStructure.GetInstance(seq)); + } + + protected virtual X509Certificate CreateX509Certificate( + X509CertificateStructure c) + { + return new X509Certificate(c); + } + + /// + /// Create loading data from byte array. + /// + /// + public X509Certificate ReadCertificate( + byte[] input) + { + return ReadCertificate(new MemoryStream(input, false)); + } + + /// + /// Create loading data from byte array. + /// + /// + public ICollection ReadCertificates( + byte[] input) + { + return ReadCertificates(new MemoryStream(input, false)); + } + + /** + * Generates a certificate object and initializes it with the data + * read from the input stream inStream. + */ + public X509Certificate ReadCertificate( + Stream inStream) + { + if (inStream == null) + throw new ArgumentNullException("inStream"); + if (!inStream.CanRead) + throw new ArgumentException("inStream must be read-able", "inStream"); + + if (currentStream == null) + { + currentStream = inStream; + sData = null; + sDataObjectCount = 0; + } + else if (currentStream != inStream) // reset if input stream has changed + { + currentStream = inStream; + sData = null; + sDataObjectCount = 0; + } + + try + { + if (sData != null) + { + if (sDataObjectCount != sData.Count) + { + return GetCertificate(); + } + + sData = null; + sDataObjectCount = 0; + return null; + } + + PushbackStream pis = new PushbackStream(inStream); + int tag = pis.ReadByte(); + + if (tag < 0) + return null; + + pis.Unread(tag); + + if (tag != 0x30) // assume ascii PEM encoded. + { + return ReadPemCertificate(pis); + } + + return ReadDerCertificate(new Asn1InputStream(pis)); + } + catch (Exception e) + { + throw new CertificateException("Failed to read certificate", e); + } + } + + /** + * Returns a (possibly empty) collection view of the certificates + * read from the given input stream inStream. + */ + public ICollection ReadCertificates( + Stream inStream) + { + X509Certificate cert; + IList certs = Platform.CreateArrayList(); + + while ((cert = ReadCertificate(inStream)) != null) + { + certs.Add(cert); + } + + return certs; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509CertificateParser.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509CertificateParser.cs.meta new file mode 100644 index 0000000..6cbca30 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509CertificateParser.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8e708c7f1992a184bb0078f708a3ae58 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509Crl.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509Crl.cs new file mode 100644 index 0000000..9acebf2 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509Crl.cs @@ -0,0 +1,511 @@ +using System; +using System.Collections; +using System.IO; +using System.Text; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Utilities; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Operators; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Security.Certificates; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; +using Org.BouncyCastle.Utilities.Date; +using Org.BouncyCastle.Utilities.Encoders; +using Org.BouncyCastle.X509.Extension; + +namespace Org.BouncyCastle.X509 +{ + /** + * The following extensions are listed in RFC 2459 as relevant to CRLs + * + * Authority Key Identifier + * Issuer Alternative Name + * CRL Number + * Delta CRL Indicator (critical) + * Issuing Distribution Point (critical) + */ + public class X509Crl + : X509ExtensionBase + // TODO Add interface Crl? + { + private class CachedEncoding + { + private readonly byte[] encoding; + private readonly CrlException exception; + + internal CachedEncoding(byte[] encoding, CrlException exception) + { + this.encoding = encoding; + this.exception = exception; + } + + internal byte[] Encoding + { + get { return encoding; } + } + + internal byte[] GetEncoded() + { + if (null != exception) + throw exception; + + if (null == encoding) + throw new CrlException(); + + return encoding; + } + } + + private readonly CertificateList c; + private readonly string sigAlgName; + private readonly byte[] sigAlgParams; + private readonly bool isIndirect; + + private readonly object cacheLock = new object(); + private CachedEncoding cachedEncoding; + + private volatile bool hashValueSet; + private volatile int hashValue; + + public X509Crl(byte[] encoding) + : this(CertificateList.GetInstance(encoding)) + { + } + + public X509Crl(CertificateList c) + { + this.c = c; + + try + { + this.sigAlgName = X509SignatureUtilities.GetSignatureName(c.SignatureAlgorithm); + + Asn1Encodable parameters = c.SignatureAlgorithm.Parameters; + this.sigAlgParams = (null == parameters) ? null : parameters.GetEncoded(Asn1Encodable.Der); + + this.isIndirect = IsIndirectCrl; + } + catch (Exception e) + { + throw new CrlException("CRL contents invalid: " + e); + } + } + + public virtual CertificateList CertificateList + { + get { return c; } + } + + protected override X509Extensions GetX509Extensions() + { + return c.Version >= 2 + ? c.TbsCertList.Extensions + : null; + } + + public virtual void Verify( + AsymmetricKeyParameter publicKey) + { + Verify(new Asn1VerifierFactoryProvider(publicKey)); + } + + /// + /// Verify the CRL's signature using a verifier created using the passed in verifier provider. + /// + /// An appropriate provider for verifying the CRL's signature. + /// True if the signature is valid. + /// If verifier provider is not appropriate or the CRL algorithm is invalid. + public virtual void Verify( + IVerifierFactoryProvider verifierProvider) + { + CheckSignature(verifierProvider.CreateVerifierFactory(c.SignatureAlgorithm)); + } + + protected virtual void CheckSignature( + IVerifierFactory verifier) + { + if (!c.SignatureAlgorithm.Equals(c.TbsCertList.Signature)) + { + throw new CrlException("Signature algorithm on CertificateList does not match TbsCertList."); + } + + Asn1Encodable parameters = c.SignatureAlgorithm.Parameters; + + IStreamCalculator streamCalculator = verifier.CreateCalculator(); + + byte[] b = this.GetTbsCertList(); + + streamCalculator.Stream.Write(b, 0, b.Length); + + Platform.Dispose(streamCalculator.Stream); + + if (!((IVerifier)streamCalculator.GetResult()).IsVerified(this.GetSignature())) + { + throw new InvalidKeyException("CRL does not verify with supplied public key."); + } + } + + public virtual int Version + { + get { return c.Version; } + } + + public virtual X509Name IssuerDN + { + get { return c.Issuer; } + } + + public virtual DateTime ThisUpdate + { + get { return c.ThisUpdate.ToDateTime(); } + } + + public virtual DateTimeObject NextUpdate + { + get + { + return c.NextUpdate == null + ? null + : new DateTimeObject(c.NextUpdate.ToDateTime()); + } + } + + private ISet LoadCrlEntries() + { + ISet entrySet = new HashSet(); + IEnumerable certs = c.GetRevokedCertificateEnumeration(); + + X509Name previousCertificateIssuer = IssuerDN; + foreach (CrlEntry entry in certs) + { + X509CrlEntry crlEntry = new X509CrlEntry(entry, isIndirect, previousCertificateIssuer); + entrySet.Add(crlEntry); + previousCertificateIssuer = crlEntry.GetCertificateIssuer(); + } + + return entrySet; + } + + public virtual X509CrlEntry GetRevokedCertificate( + BigInteger serialNumber) + { + IEnumerable certs = c.GetRevokedCertificateEnumeration(); + + X509Name previousCertificateIssuer = IssuerDN; + foreach (CrlEntry entry in certs) + { + X509CrlEntry crlEntry = new X509CrlEntry(entry, isIndirect, previousCertificateIssuer); + + if (serialNumber.Equals(entry.UserCertificate.Value)) + { + return crlEntry; + } + + previousCertificateIssuer = crlEntry.GetCertificateIssuer(); + } + + return null; + } + + public virtual ISet GetRevokedCertificates() + { + ISet entrySet = LoadCrlEntries(); + + if (entrySet.Count > 0) + { + return entrySet; // TODO? Collections.unmodifiableSet(entrySet); + } + + return null; + } + + public virtual byte[] GetTbsCertList() + { + try + { + return c.TbsCertList.GetDerEncoded(); + } + catch (Exception e) + { + throw new CrlException(e.ToString()); + } + } + + public virtual byte[] GetSignature() + { + return c.GetSignatureOctets(); + } + + public virtual string SigAlgName + { + get { return sigAlgName; } + } + + public virtual string SigAlgOid + { + get { return c.SignatureAlgorithm.Algorithm.Id; } + } + + public virtual byte[] GetSigAlgParams() + { + return Arrays.Clone(sigAlgParams); + } + + /// + /// Return the DER encoding of this CRL. + /// + /// A byte array containing the DER encoding of this CRL. + /// If there is an error encoding the CRL. + public virtual byte[] GetEncoded() + { + return Arrays.Clone(GetCachedEncoding().GetEncoded()); + } + + public override bool Equals(object other) + { + if (this == other) + return true; + + X509Crl that = other as X509Crl; + if (null == that) + return false; + + if (this.hashValueSet && that.hashValueSet) + { + if (this.hashValue != that.hashValue) + return false; + } + else if (null == this.cachedEncoding || null == that.cachedEncoding) + { + DerBitString signature = c.Signature; + if (null != signature && !signature.Equals(that.c.Signature)) + return false; + } + + byte[] thisEncoding = this.GetCachedEncoding().Encoding; + byte[] thatEncoding = that.GetCachedEncoding().Encoding; + + return null != thisEncoding + && null != thatEncoding + && Arrays.AreEqual(thisEncoding, thatEncoding); + } + + public override int GetHashCode() + { + if (!hashValueSet) + { + byte[] thisEncoding = this.GetCachedEncoding().Encoding; + + hashValue = Arrays.GetHashCode(thisEncoding); + hashValueSet = true; + } + + return hashValue; + } + + /** + * Returns a string representation of this CRL. + * + * @return a string representation of this CRL. + */ + public override string ToString() + { + StringBuilder buf = new StringBuilder(); + string nl = Platform.NewLine; + + buf.Append(" Version: ").Append(this.Version).Append(nl); + buf.Append(" IssuerDN: ").Append(this.IssuerDN).Append(nl); + buf.Append(" This update: ").Append(this.ThisUpdate).Append(nl); + buf.Append(" Next update: ").Append(this.NextUpdate).Append(nl); + buf.Append(" Signature Algorithm: ").Append(this.SigAlgName).Append(nl); + + byte[] sig = this.GetSignature(); + + buf.Append(" Signature: "); + buf.Append(Hex.ToHexString(sig, 0, 20)).Append(nl); + + for (int i = 20; i < sig.Length; i += 20) + { + int count = System.Math.Min(20, sig.Length - i); + buf.Append(" "); + buf.Append(Hex.ToHexString(sig, i, count)).Append(nl); + } + + X509Extensions extensions = c.TbsCertList.Extensions; + + if (extensions != null) + { + IEnumerator e = extensions.ExtensionOids.GetEnumerator(); + + if (e.MoveNext()) + { + buf.Append(" Extensions: ").Append(nl); + } + + do + { + DerObjectIdentifier oid = (DerObjectIdentifier) e.Current; + X509Extension ext = extensions.GetExtension(oid); + + if (ext.Value != null) + { + Asn1Object asn1Value = X509ExtensionUtilities.FromExtensionValue(ext.Value); + + buf.Append(" critical(").Append(ext.IsCritical).Append(") "); + try + { + if (oid.Equals(X509Extensions.CrlNumber)) + { + buf.Append(new CrlNumber(DerInteger.GetInstance(asn1Value).PositiveValue)).Append(nl); + } + else if (oid.Equals(X509Extensions.DeltaCrlIndicator)) + { + buf.Append( + "Base CRL: " + + new CrlNumber(DerInteger.GetInstance( + asn1Value).PositiveValue)) + .Append(nl); + } + else if (oid.Equals(X509Extensions.IssuingDistributionPoint)) + { + buf.Append(IssuingDistributionPoint.GetInstance((Asn1Sequence) asn1Value)).Append(nl); + } + else if (oid.Equals(X509Extensions.CrlDistributionPoints)) + { + buf.Append(CrlDistPoint.GetInstance((Asn1Sequence) asn1Value)).Append(nl); + } + else if (oid.Equals(X509Extensions.FreshestCrl)) + { + buf.Append(CrlDistPoint.GetInstance((Asn1Sequence) asn1Value)).Append(nl); + } + else + { + buf.Append(oid.Id); + buf.Append(" value = ").Append( + Asn1Dump.DumpAsString(asn1Value)) + .Append(nl); + } + } + catch (Exception) + { + buf.Append(oid.Id); + buf.Append(" value = ").Append("*****").Append(nl); + } + } + else + { + buf.Append(nl); + } + } + while (e.MoveNext()); + } + + ISet certSet = GetRevokedCertificates(); + if (certSet != null) + { + foreach (X509CrlEntry entry in certSet) + { + buf.Append(entry); + buf.Append(nl); + } + } + + return buf.ToString(); + } + + /** + * Checks whether the given certificate is on this CRL. + * + * @param cert the certificate to check for. + * @return true if the given certificate is on this CRL, + * false otherwise. + */ +// public bool IsRevoked( +// Certificate cert) +// { +// if (!cert.getType().Equals("X.509")) +// { +// throw new RuntimeException("X.509 CRL used with non X.509 Cert"); +// } + public virtual bool IsRevoked( + X509Certificate cert) + { + CrlEntry[] certs = c.GetRevokedCertificates(); + + if (certs != null) + { + BigInteger serial = cert.SerialNumber; + + for (int i = 0; i < certs.Length; i++) + { + if (certs[i].UserCertificate.HasValue(serial)) + return true; + } + } + + return false; + } + + protected virtual bool IsIndirectCrl + { + get + { + Asn1OctetString idp = GetExtensionValue(X509Extensions.IssuingDistributionPoint); + bool isIndirect = false; + + try + { + if (idp != null) + { + isIndirect = IssuingDistributionPoint.GetInstance( + X509ExtensionUtilities.FromExtensionValue(idp)).IsIndirectCrl; + } + } + catch (Exception e) + { + // TODO +// throw new ExtCrlException("Exception reading IssuingDistributionPoint", e); + throw new CrlException("Exception reading IssuingDistributionPoint" + e); + } + + return isIndirect; + } + } + + private CachedEncoding GetCachedEncoding() + { + lock (cacheLock) + { + if (null != cachedEncoding) + return cachedEncoding; + } + + byte[] encoding = null; + CrlException exception = null; + try + { + encoding = c.GetEncoded(Asn1Encodable.Der); + } + catch (IOException e) + { + exception = new CrlException("Failed to DER-encode CRL", e); + } + + CachedEncoding temp = new CachedEncoding(encoding, exception); + + lock (cacheLock) + { + if (null == cachedEncoding) + { + cachedEncoding = temp; + } + + return cachedEncoding; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509Crl.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509Crl.cs.meta new file mode 100644 index 0000000..e84b3d1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509Crl.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 41a3171977b4fdc489c9e452901c71af +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509CrlEntry.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509CrlEntry.cs new file mode 100644 index 0000000..9660a70 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509CrlEntry.cs @@ -0,0 +1,232 @@ +using System; +using System.Collections; +using System.Text; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Utilities; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security.Certificates; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.X509.Extension; + +namespace Org.BouncyCastle.X509 +{ + /** + * The following extensions are listed in RFC 2459 as relevant to CRL Entries + * + * ReasonCode Hode Instruction Code Invalidity Date Certificate Issuer + * (critical) + */ + public class X509CrlEntry + : X509ExtensionBase + { + private CrlEntry c; + private bool isIndirect; + private X509Name previousCertificateIssuer; + private X509Name certificateIssuer; + + private volatile bool hashValueSet; + private volatile int hashValue; + + public X509CrlEntry( + CrlEntry c) + { + this.c = c; + this.certificateIssuer = loadCertificateIssuer(); + } + + /** + * Constructor for CRLEntries of indirect CRLs. If isIndirect + * is false {@link #getCertificateIssuer()} will always + * return null, previousCertificateIssuer is + * ignored. If this isIndirect is specified and this CrlEntry + * has no certificate issuer CRL entry extension + * previousCertificateIssuer is returned by + * {@link #getCertificateIssuer()}. + * + * @param c + * TbsCertificateList.CrlEntry object. + * @param isIndirect + * true if the corresponding CRL is a indirect + * CRL. + * @param previousCertificateIssuer + * Certificate issuer of the previous CrlEntry. + */ + public X509CrlEntry( + CrlEntry c, + bool isIndirect, + X509Name previousCertificateIssuer) + { + this.c = c; + this.isIndirect = isIndirect; + this.previousCertificateIssuer = previousCertificateIssuer; + this.certificateIssuer = loadCertificateIssuer(); + } + + private X509Name loadCertificateIssuer() + { + if (!isIndirect) + { + return null; + } + + Asn1OctetString ext = GetExtensionValue(X509Extensions.CertificateIssuer); + if (ext == null) + { + return previousCertificateIssuer; + } + + try + { + GeneralName[] names = GeneralNames.GetInstance( + X509ExtensionUtilities.FromExtensionValue(ext)).GetNames(); + + for (int i = 0; i < names.Length; i++) + { + if (names[i].TagNo == GeneralName.DirectoryName) + { + return X509Name.GetInstance(names[i].Name); + } + } + } + catch (Exception) + { + } + + return null; + } + + public X509Name GetCertificateIssuer() + { + return certificateIssuer; + } + + protected override X509Extensions GetX509Extensions() + { + return c.Extensions; + } + + public byte[] GetEncoded() + { + try + { + return c.GetDerEncoded(); + } + catch (Exception e) + { + throw new CrlException(e.ToString()); + } + } + + public BigInteger SerialNumber + { + get { return c.UserCertificate.Value; } + } + + public DateTime RevocationDate + { + get { return c.RevocationDate.ToDateTime(); } + } + + public bool HasExtensions + { + get { return c.Extensions != null; } + } + + public override bool Equals(object other) + { + if (this == other) + return true; + + X509CrlEntry that = other as X509CrlEntry; + if (null == that) + return false; + + if (this.hashValueSet && that.hashValueSet) + { + if (this.hashValue != that.hashValue) + return false; + } + + return this.c.Equals(that.c); + } + + public override int GetHashCode() + { + if (!hashValueSet) + { + hashValue = this.c.GetHashCode(); + hashValueSet = true; + } + + return hashValue; + } + + public override string ToString() + { + StringBuilder buf = new StringBuilder(); + string nl = Platform.NewLine; + + buf.Append(" userCertificate: ").Append(this.SerialNumber).Append(nl); + buf.Append(" revocationDate: ").Append(this.RevocationDate).Append(nl); + buf.Append(" certificateIssuer: ").Append(this.GetCertificateIssuer()).Append(nl); + + X509Extensions extensions = c.Extensions; + + if (extensions != null) + { + IEnumerator e = extensions.ExtensionOids.GetEnumerator(); + if (e.MoveNext()) + { + buf.Append(" crlEntryExtensions:").Append(nl); + + do + { + DerObjectIdentifier oid = (DerObjectIdentifier)e.Current; + X509Extension ext = extensions.GetExtension(oid); + + if (ext.Value != null) + { + Asn1Object obj = X509ExtensionUtilities.FromExtensionValue(ext.Value); + + buf.Append(" critical(") + .Append(ext.IsCritical) + .Append(") "); + try + { + if (oid.Equals(X509Extensions.ReasonCode)) + { + buf.Append(new CrlReason(DerEnumerated.GetInstance(obj))); + } + else if (oid.Equals(X509Extensions.CertificateIssuer)) + { + buf.Append("Certificate issuer: ").Append( + GeneralNames.GetInstance((Asn1Sequence)obj)); + } + else + { + buf.Append(oid.Id); + buf.Append(" value = ").Append(Asn1Dump.DumpAsString(obj)); + } + buf.Append(nl); + } + catch (Exception) + { + buf.Append(oid.Id); + buf.Append(" value = ").Append("*****").Append(nl); + } + } + else + { + buf.Append(nl); + } + } + while (e.MoveNext()); + } + } + + return buf.ToString(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509CrlEntry.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509CrlEntry.cs.meta new file mode 100644 index 0000000..af767e4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509CrlEntry.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f46b3d402e2bc924a81fb4947aa3bd62 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509CrlParser.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509CrlParser.cs new file mode 100644 index 0000000..d830bb9 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509CrlParser.cs @@ -0,0 +1,195 @@ +using System; +using System.Collections; +using System.IO; +using System.Text; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Security.Certificates; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.X509 +{ + public class X509CrlParser + { + private static readonly PemParser PemCrlParser = new PemParser("CRL"); + + private readonly bool lazyAsn1; + + private Asn1Set sCrlData; + private int sCrlDataObjectCount; + private Stream currentCrlStream; + + public X509CrlParser() + : this(false) + { + } + + public X509CrlParser( + bool lazyAsn1) + { + this.lazyAsn1 = lazyAsn1; + } + + private X509Crl ReadPemCrl( + Stream inStream) + { + Asn1Sequence seq = PemCrlParser.ReadPemObject(inStream); + + return seq == null + ? null + : CreateX509Crl(CertificateList.GetInstance(seq)); + } + + private X509Crl ReadDerCrl( + Asn1InputStream dIn) + { + Asn1Sequence seq = (Asn1Sequence)dIn.ReadObject(); + + if (seq.Count > 1 && seq[0] is DerObjectIdentifier) + { + if (seq[0].Equals(PkcsObjectIdentifiers.SignedData)) + { + sCrlData = SignedData.GetInstance( + Asn1Sequence.GetInstance((Asn1TaggedObject) seq[1], true)).Crls; + + return GetCrl(); + } + } + + return CreateX509Crl(CertificateList.GetInstance(seq)); + } + + private X509Crl GetCrl() + { + if (sCrlData == null || sCrlDataObjectCount >= sCrlData.Count) + { + return null; + } + + return CreateX509Crl( + CertificateList.GetInstance( + sCrlData[sCrlDataObjectCount++])); + } + + protected virtual X509Crl CreateX509Crl( + CertificateList c) + { + return new X509Crl(c); + } + + /// + /// Create loading data from byte array. + /// + /// + public X509Crl ReadCrl( + byte[] input) + { + return ReadCrl(new MemoryStream(input, false)); + } + + /// + /// Create loading data from byte array. + /// + /// + public ICollection ReadCrls( + byte[] input) + { + return ReadCrls(new MemoryStream(input, false)); + } + + /** + * Generates a certificate revocation list (CRL) object and initializes + * it with the data read from the input stream inStream. + */ + public X509Crl ReadCrl( + Stream inStream) + { + if (inStream == null) + throw new ArgumentNullException("inStream"); + if (!inStream.CanRead) + throw new ArgumentException("inStream must be read-able", "inStream"); + + if (currentCrlStream == null) + { + currentCrlStream = inStream; + sCrlData = null; + sCrlDataObjectCount = 0; + } + else if (currentCrlStream != inStream) // reset if input stream has changed + { + currentCrlStream = inStream; + sCrlData = null; + sCrlDataObjectCount = 0; + } + + try + { + if (sCrlData != null) + { + if (sCrlDataObjectCount != sCrlData.Count) + { + return GetCrl(); + } + + sCrlData = null; + sCrlDataObjectCount = 0; + return null; + } + + PushbackStream pis = new PushbackStream(inStream); + int tag = pis.ReadByte(); + + if (tag < 0) + return null; + + pis.Unread(tag); + + if (tag != 0x30) // assume ascii PEM encoded. + { + return ReadPemCrl(pis); + } + + Asn1InputStream asn1 = lazyAsn1 + ? new LazyAsn1InputStream(pis) + : new Asn1InputStream(pis); + + return ReadDerCrl(asn1); + } + catch (CrlException e) + { + throw e; + } + catch (Exception e) + { + throw new CrlException(e.ToString()); + } + } + + /** + * Returns a (possibly empty) collection view of the CRLs read from + * the given input stream inStream. + * + * The inStream may contain a sequence of DER-encoded CRLs, or + * a PKCS#7 CRL set. This is a PKCS#7 SignedData object, with the + * only significant field being crls. In particular the signature + * and the contents are ignored. + */ + public ICollection ReadCrls( + Stream inStream) + { + X509Crl crl; + IList crls = Platform.CreateArrayList(); + + while ((crl = ReadCrl(inStream)) != null) + { + crls.Add(crl); + } + + return crls; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509CrlParser.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509CrlParser.cs.meta new file mode 100644 index 0000000..d7fca1d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509CrlParser.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1c16e86ee4047f843873f3029c7d81b7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509ExtensionBase.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509ExtensionBase.cs new file mode 100644 index 0000000..aaf6695 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509ExtensionBase.cs @@ -0,0 +1,82 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.X509 +{ + public abstract class X509ExtensionBase + : IX509Extension + { + protected abstract X509Extensions GetX509Extensions(); + + protected virtual ISet GetExtensionOids( + bool critical) + { + X509Extensions extensions = GetX509Extensions(); + if (extensions != null) + { + HashSet set = new HashSet(); + foreach (DerObjectIdentifier oid in extensions.ExtensionOids) + { + X509Extension ext = extensions.GetExtension(oid); + if (ext.IsCritical == critical) + { + set.Add(oid.Id); + } + } + + return set; + } + + return null; + } + + /// + /// Get non critical extensions. + /// + /// A set of non critical extension oids. + public virtual ISet GetNonCriticalExtensionOids() + { + return GetExtensionOids(false); + } + + /// + /// Get any critical extensions. + /// + /// A sorted list of critical entension. + public virtual ISet GetCriticalExtensionOids() + { + return GetExtensionOids(true); + } + + /// + /// Get the value of a given extension. + /// + /// The object ID of the extension. + /// An Asn1OctetString object if that extension is found or null if not. + [Obsolete("Use version taking a DerObjectIdentifier instead")] + public Asn1OctetString GetExtensionValue( + string oid) + { + return GetExtensionValue(new DerObjectIdentifier(oid)); + } + + public virtual Asn1OctetString GetExtensionValue( + DerObjectIdentifier oid) + { + X509Extensions exts = GetX509Extensions(); + if (exts != null) + { + X509Extension ext = exts.GetExtension(oid); + if (ext != null) + { + return ext.Value; + } + } + + return null; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509ExtensionBase.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509ExtensionBase.cs.meta new file mode 100644 index 0000000..f9b1e0a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509ExtensionBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8e3c160bea42d4d4ab1de9909bf50a32 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509KeyUsage.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509KeyUsage.cs new file mode 100644 index 0000000..e0a7b49 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509KeyUsage.cs @@ -0,0 +1,59 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; + +namespace Org.BouncyCastle.X509 +{ + /** + * A holding class for constructing an X509 Key Usage extension. + * + *
    +	 *    id-ce-keyUsage OBJECT IDENTIFIER ::=  { id-ce 15 }
    +	 *
    +	 *    KeyUsage ::= BIT STRING {
    +	 *         digitalSignature        (0),
    +	 *         nonRepudiation          (1),
    +	 *         keyEncipherment         (2),
    +	 *         dataEncipherment        (3),
    +	 *         keyAgreement            (4),
    +	 *         keyCertSign             (5),
    +	 *         cRLSign                 (6),
    +	 *         encipherOnly            (7),
    +	 *         decipherOnly            (8) }
    +	 * 
    + */ + public class X509KeyUsage + : Asn1Encodable + { + public const int DigitalSignature = 1 << 7; + public const int NonRepudiation = 1 << 6; + public const int KeyEncipherment = 1 << 5; + public const int DataEncipherment = 1 << 4; + public const int KeyAgreement = 1 << 3; + public const int KeyCertSign = 1 << 2; + public const int CrlSign = 1 << 1; + public const int EncipherOnly = 1 << 0; + public const int DecipherOnly = 1 << 15; + + private readonly int usage; + + /** + * Basic constructor. + * + * @param usage - the bitwise OR of the Key Usage flags giving the + * allowed uses for the key. + * e.g. (X509KeyUsage.keyEncipherment | X509KeyUsage.dataEncipherment) + */ + public X509KeyUsage( + int usage) + { + this.usage = usage; + } + + public override Asn1Object ToAsn1Object() + { + return new KeyUsage(usage); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509KeyUsage.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509KeyUsage.cs.meta new file mode 100644 index 0000000..3912e65 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509KeyUsage.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0ef87d3efb5204d46870d184e7fe181b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509SignatureUtil.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509SignatureUtil.cs new file mode 100644 index 0000000..6a6c0cf --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509SignatureUtil.cs @@ -0,0 +1,135 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Oiw; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.TeleTrust; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.X509 +{ + internal class X509SignatureUtilities + { + private static readonly Asn1Null derNull = DerNull.Instance; + + internal static void SetSignatureParameters( + ISigner signature, + Asn1Encodable parameters) + { + if (parameters != null && !derNull.Equals(parameters)) + { + // TODO Put back in +// AlgorithmParameters sigParams = AlgorithmParameters.GetInstance(signature.getAlgorithm()); +// +// try +// { +// sigParams.Init(parameters.ToAsn1Object().GetDerEncoded()); +// } +// catch (IOException e) +// { +// throw new SignatureException("IOException decoding parameters: " + e.Message); +// } +// +// if (Platform.EndsWith(signature.getAlgorithm(), "MGF1")) +// { +// try +// { +// signature.setParameter(sigParams.getParameterSpec(PSSParameterSpec.class)); +// } +// catch (GeneralSecurityException e) +// { +// throw new SignatureException("Exception extracting parameters: " + e.Message); +// } +// } + } + } + + internal static string GetSignatureName( + AlgorithmIdentifier sigAlgId) + { + Asn1Encodable parameters = sigAlgId.Parameters; + + if (parameters != null && !derNull.Equals(parameters)) + { + if (sigAlgId.Algorithm.Equals(PkcsObjectIdentifiers.IdRsassaPss)) + { + RsassaPssParameters rsaParams = RsassaPssParameters.GetInstance(parameters); + + return GetDigestAlgName(rsaParams.HashAlgorithm.Algorithm) + "withRSAandMGF1"; + } + if (sigAlgId.Algorithm.Equals(X9ObjectIdentifiers.ECDsaWithSha2)) + { + Asn1Sequence ecDsaParams = Asn1Sequence.GetInstance(parameters); + + return GetDigestAlgName((DerObjectIdentifier)ecDsaParams[0]) + "withECDSA"; + } + } + + string sigName = SignerUtilities.GetEncodingName(sigAlgId.Algorithm); + if (null != sigName) + { + return sigName; + } + + return sigAlgId.Algorithm.Id; + } + + /** + * Return the digest algorithm using one of the standard JCA string + * representations rather than the algorithm identifier (if possible). + */ + private static string GetDigestAlgName( + DerObjectIdentifier digestAlgOID) + { + if (PkcsObjectIdentifiers.MD5.Equals(digestAlgOID)) + { + return "MD5"; + } + else if (OiwObjectIdentifiers.IdSha1.Equals(digestAlgOID)) + { + return "SHA1"; + } + else if (NistObjectIdentifiers.IdSha224.Equals(digestAlgOID)) + { + return "SHA224"; + } + else if (NistObjectIdentifiers.IdSha256.Equals(digestAlgOID)) + { + return "SHA256"; + } + else if (NistObjectIdentifiers.IdSha384.Equals(digestAlgOID)) + { + return "SHA384"; + } + else if (NistObjectIdentifiers.IdSha512.Equals(digestAlgOID)) + { + return "SHA512"; + } + else if (TeleTrusTObjectIdentifiers.RipeMD128.Equals(digestAlgOID)) + { + return "RIPEMD128"; + } + else if (TeleTrusTObjectIdentifiers.RipeMD160.Equals(digestAlgOID)) + { + return "RIPEMD160"; + } + else if (TeleTrusTObjectIdentifiers.RipeMD256.Equals(digestAlgOID)) + { + return "RIPEMD256"; + } + else if (CryptoProObjectIdentifiers.GostR3411.Equals(digestAlgOID)) + { + return "GOST3411"; + } + else + { + return digestAlgOID.Id; + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509SignatureUtil.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509SignatureUtil.cs.meta new file mode 100644 index 0000000..e95907e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509SignatureUtil.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cdfa28e563f3c6148afb710e72b2f1d5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509Utilities.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509Utilities.cs new file mode 100644 index 0000000..ed4d345 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509Utilities.cs @@ -0,0 +1,206 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Oiw; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.TeleTrust; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Asn1.X9; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.X509 +{ + internal class X509Utilities + { + private static readonly IDictionary algorithms = Platform.CreateHashtable(); + private static readonly IDictionary exParams = Platform.CreateHashtable(); + private static readonly ISet noParams = new HashSet(); + + static X509Utilities() + { + algorithms.Add("MD2WITHRSAENCRYPTION", PkcsObjectIdentifiers.MD2WithRsaEncryption); + algorithms.Add("MD2WITHRSA", PkcsObjectIdentifiers.MD2WithRsaEncryption); + algorithms.Add("MD5WITHRSAENCRYPTION", PkcsObjectIdentifiers.MD5WithRsaEncryption); + algorithms.Add("MD5WITHRSA", PkcsObjectIdentifiers.MD5WithRsaEncryption); + algorithms.Add("SHA1WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha1WithRsaEncryption); + algorithms.Add("SHA-1WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha1WithRsaEncryption); + algorithms.Add("SHA1WITHRSA", PkcsObjectIdentifiers.Sha1WithRsaEncryption); + algorithms.Add("SHA-1WITHRSA", PkcsObjectIdentifiers.Sha1WithRsaEncryption); + algorithms.Add("SHA224WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha224WithRsaEncryption); + algorithms.Add("SHA-224WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha224WithRsaEncryption); + algorithms.Add("SHA224WITHRSA", PkcsObjectIdentifiers.Sha224WithRsaEncryption); + algorithms.Add("SHA-224WITHRSA", PkcsObjectIdentifiers.Sha224WithRsaEncryption); + algorithms.Add("SHA256WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha256WithRsaEncryption); + algorithms.Add("SHA-256WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha256WithRsaEncryption); + algorithms.Add("SHA256WITHRSA", PkcsObjectIdentifiers.Sha256WithRsaEncryption); + algorithms.Add("SHA-256WITHRSA", PkcsObjectIdentifiers.Sha256WithRsaEncryption); + algorithms.Add("SHA384WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha384WithRsaEncryption); + algorithms.Add("SHA-384WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha384WithRsaEncryption); + algorithms.Add("SHA384WITHRSA", PkcsObjectIdentifiers.Sha384WithRsaEncryption); + algorithms.Add("SHA-384WITHRSA", PkcsObjectIdentifiers.Sha384WithRsaEncryption); + algorithms.Add("SHA512WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha512WithRsaEncryption); + algorithms.Add("SHA-512WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha512WithRsaEncryption); + algorithms.Add("SHA512WITHRSA", PkcsObjectIdentifiers.Sha512WithRsaEncryption); + algorithms.Add("SHA-512WITHRSA", PkcsObjectIdentifiers.Sha512WithRsaEncryption); + algorithms.Add("SHA512(224)WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha512_224WithRSAEncryption); + algorithms.Add("SHA-512(224)WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha512_224WithRSAEncryption); + algorithms.Add("SHA512(224)WITHRSA", PkcsObjectIdentifiers.Sha512_224WithRSAEncryption); + algorithms.Add("SHA-512(224)WITHRSA", PkcsObjectIdentifiers.Sha512_224WithRSAEncryption); + algorithms.Add("SHA512(256)WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha512_256WithRSAEncryption); + algorithms.Add("SHA-512(256)WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha512_256WithRSAEncryption); + algorithms.Add("SHA512(256)WITHRSA", PkcsObjectIdentifiers.Sha512_256WithRSAEncryption); + algorithms.Add("SHA-512(256)WITHRSA", PkcsObjectIdentifiers.Sha512_256WithRSAEncryption); + algorithms.Add("SHA1WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss); + algorithms.Add("SHA224WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss); + algorithms.Add("SHA256WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss); + algorithms.Add("SHA384WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss); + algorithms.Add("SHA512WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss); + algorithms.Add("RIPEMD160WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160); + algorithms.Add("RIPEMD160WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160); + algorithms.Add("RIPEMD128WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128); + algorithms.Add("RIPEMD128WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128); + algorithms.Add("RIPEMD256WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256); + algorithms.Add("RIPEMD256WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256); + algorithms.Add("SHA1WITHDSA", X9ObjectIdentifiers.IdDsaWithSha1); + algorithms.Add("DSAWITHSHA1", X9ObjectIdentifiers.IdDsaWithSha1); + algorithms.Add("SHA224WITHDSA", NistObjectIdentifiers.DsaWithSha224); + algorithms.Add("SHA256WITHDSA", NistObjectIdentifiers.DsaWithSha256); + algorithms.Add("SHA384WITHDSA", NistObjectIdentifiers.DsaWithSha384); + algorithms.Add("SHA512WITHDSA", NistObjectIdentifiers.DsaWithSha512); + algorithms.Add("SHA1WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha1); + algorithms.Add("ECDSAWITHSHA1", X9ObjectIdentifiers.ECDsaWithSha1); + algorithms.Add("SHA224WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha224); + algorithms.Add("SHA256WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha256); + algorithms.Add("SHA384WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha384); + algorithms.Add("SHA512WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha512); + algorithms.Add("GOST3411WITHGOST3410", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94); + algorithms.Add("GOST3411WITHGOST3410-94", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94); + algorithms.Add("GOST3411WITHECGOST3410", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001); + algorithms.Add("GOST3411WITHECGOST3410-2001", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001); + algorithms.Add("GOST3411WITHGOST3410-2001", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001); + + // + // According to RFC 3279, the ASN.1 encoding SHALL (id-dsa-with-sha1) or MUST (ecdsa-with-SHA*) omit the parameters field. + // The parameters field SHALL be NULL for RSA based signature algorithms. + // + noParams.Add(X9ObjectIdentifiers.ECDsaWithSha1); + noParams.Add(X9ObjectIdentifiers.ECDsaWithSha224); + noParams.Add(X9ObjectIdentifiers.ECDsaWithSha256); + noParams.Add(X9ObjectIdentifiers.ECDsaWithSha384); + noParams.Add(X9ObjectIdentifiers.ECDsaWithSha512); + noParams.Add(X9ObjectIdentifiers.IdDsaWithSha1); + noParams.Add(OiwObjectIdentifiers.DsaWithSha1); + noParams.Add(NistObjectIdentifiers.DsaWithSha224); + noParams.Add(NistObjectIdentifiers.DsaWithSha256); + noParams.Add(NistObjectIdentifiers.DsaWithSha384); + noParams.Add(NistObjectIdentifiers.DsaWithSha512); + + // + // RFC 4491 + // + noParams.Add(CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94); + noParams.Add(CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001); + + // + // explicit params + // + AlgorithmIdentifier sha1AlgId = new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1, DerNull.Instance); + exParams.Add("SHA1WITHRSAANDMGF1", CreatePssParams(sha1AlgId, 20)); + + AlgorithmIdentifier sha224AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha224, DerNull.Instance); + exParams.Add("SHA224WITHRSAANDMGF1", CreatePssParams(sha224AlgId, 28)); + + AlgorithmIdentifier sha256AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha256, DerNull.Instance); + exParams.Add("SHA256WITHRSAANDMGF1", CreatePssParams(sha256AlgId, 32)); + + AlgorithmIdentifier sha384AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha384, DerNull.Instance); + exParams.Add("SHA384WITHRSAANDMGF1", CreatePssParams(sha384AlgId, 48)); + + AlgorithmIdentifier sha512AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha512, DerNull.Instance); + exParams.Add("SHA512WITHRSAANDMGF1", CreatePssParams(sha512AlgId, 64)); + } + + private static RsassaPssParameters CreatePssParams( + AlgorithmIdentifier hashAlgId, + int saltSize) + { + return new RsassaPssParameters( + hashAlgId, + new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, hashAlgId), + new DerInteger(saltSize), + new DerInteger(1)); + } + + internal static DerObjectIdentifier GetAlgorithmOid( + string algorithmName) + { + algorithmName = Platform.ToUpperInvariant(algorithmName); + + if (algorithms.Contains(algorithmName)) + { + return (DerObjectIdentifier) algorithms[algorithmName]; + } + + return new DerObjectIdentifier(algorithmName); + } + + internal static AlgorithmIdentifier GetSigAlgID( + DerObjectIdentifier sigOid, + string algorithmName) + { + if (noParams.Contains(sigOid)) + { + return new AlgorithmIdentifier(sigOid); + } + + algorithmName = Platform.ToUpperInvariant(algorithmName); + + if (exParams.Contains(algorithmName)) + { + return new AlgorithmIdentifier(sigOid, (Asn1Encodable) exParams[algorithmName]); + } + + return new AlgorithmIdentifier(sigOid, DerNull.Instance); + } + + internal static IEnumerable GetAlgNames() + { + return new EnumerableProxy(algorithms.Keys); + } + + internal static byte[] GetSignatureForObject( + DerObjectIdentifier sigOid, // TODO Redundant now? + string sigName, + AsymmetricKeyParameter privateKey, + SecureRandom random, + Asn1Encodable ae) + { + if (sigOid == null) + throw new ArgumentNullException("sigOid"); + + ISigner sig = SignerUtilities.GetSigner(sigName); + + if (random != null) + { + sig.Init(true, new ParametersWithRandom(privateKey, random)); + } + else + { + sig.Init(true, privateKey); + } + + byte[] encoded = ae.GetDerEncoded(); + sig.BlockUpdate(encoded, 0, encoded.Length); + + return sig.GenerateSignature(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509Utilities.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509Utilities.cs.meta new file mode 100644 index 0000000..b915056 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509Utilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4b125443c623a4d42853fade44937cf8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509V1CertificateGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509V1CertificateGenerator.cs new file mode 100644 index 0000000..9adebcb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509V1CertificateGenerator.cs @@ -0,0 +1,210 @@ +using System; +using System.IO; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Operators; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Security.Certificates; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.X509 +{ + /// + /// Class to Generate X509V1 Certificates. + /// + public class X509V1CertificateGenerator + { + private V1TbsCertificateGenerator tbsGen; + private DerObjectIdentifier sigOID; + private AlgorithmIdentifier sigAlgId; + private string signatureAlgorithm; + + /// + /// Default Constructor. + /// + public X509V1CertificateGenerator() + { + tbsGen = new V1TbsCertificateGenerator(); + } + + /// + /// Reset the generator. + /// + public void Reset() + { + tbsGen = new V1TbsCertificateGenerator(); + } + + /// + /// Set the certificate's serial number. + /// + /// Make serial numbers long, if you have no serial number policy make sure the number is at least 16 bytes of secure random data. + /// You will be surprised how ugly a serial number collision can get. + /// The serial number. + public void SetSerialNumber( + BigInteger serialNumber) + { + if (serialNumber.SignValue <= 0) + { + throw new ArgumentException("serial number must be a positive integer", "serialNumber"); + } + + tbsGen.SetSerialNumber(new DerInteger(serialNumber)); + } + + /// + /// Set the issuer distinguished name. + /// The issuer is the entity whose private key is used to sign the certificate. + /// + /// The issuers DN. + public void SetIssuerDN( + X509Name issuer) + { + tbsGen.SetIssuer(issuer); + } + + /// + /// Set the date that this certificate is to be valid from. + /// + /// + public void SetNotBefore( + DateTime date) + { + tbsGen.SetStartDate(new Time(date)); + } + + /// + /// Set the date after which this certificate will no longer be valid. + /// + /// + public void SetNotAfter( + DateTime date) + { + tbsGen.SetEndDate(new Time(date)); + } + + /// + /// Set the subject distinguished name. + /// The subject describes the entity associated with the public key. + /// + /// + public void SetSubjectDN( + X509Name subject) + { + tbsGen.SetSubject(subject); + } + + /// + /// Set the public key that this certificate identifies. + /// + /// + public void SetPublicKey( + AsymmetricKeyParameter publicKey) + { + try + { + tbsGen.SetSubjectPublicKeyInfo( + SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(publicKey)); + } + catch (Exception e) + { + throw new ArgumentException("unable to process key - " + e.ToString()); + } + } + + /// + /// Set the signature algorithm that will be used to sign this certificate. + /// This can be either a name or an OID, names are treated as case insensitive. + /// + /// string representation of the algorithm name + [Obsolete("Not needed if Generate used with an ISignatureFactory")] + public void SetSignatureAlgorithm( + string signatureAlgorithm) + { + this.signatureAlgorithm = signatureAlgorithm; + + try + { + sigOID = X509Utilities.GetAlgorithmOid(signatureAlgorithm); + } + catch (Exception) + { + throw new ArgumentException("Unknown signature type requested", "signatureAlgorithm"); + } + + sigAlgId = X509Utilities.GetSigAlgID(sigOID, signatureAlgorithm); + + tbsGen.SetSignature(sigAlgId); + } + + /// + /// Generate a new X509Certificate. + /// + /// The private key of the issuer used to sign this certificate. + /// An X509Certificate. + [Obsolete("Use Generate with an ISignatureFactory")] + public X509Certificate Generate( + AsymmetricKeyParameter privateKey) + { + return Generate(privateKey, null); + } + + /// + /// Generate a new X509Certificate specifying a SecureRandom instance that you would like to use. + /// + /// The private key of the issuer used to sign this certificate. + /// The Secure Random you want to use. + /// An X509Certificate. + [Obsolete("Use Generate with an ISignatureFactory")] + public X509Certificate Generate( + AsymmetricKeyParameter privateKey, + SecureRandom random) + { + return Generate(new Asn1SignatureFactory(signatureAlgorithm, privateKey, random)); + } + + /// + /// Generate a new X509Certificate using the passed in SignatureCalculator. + /// + /// A signature calculator factory with the necessary algorithm details. + /// An X509Certificate. + public X509Certificate Generate(ISignatureFactory signatureCalculatorFactory) + { + tbsGen.SetSignature ((AlgorithmIdentifier)signatureCalculatorFactory.AlgorithmDetails); + + TbsCertificateStructure tbsCert = tbsGen.GenerateTbsCertificate(); + + IStreamCalculator streamCalculator = signatureCalculatorFactory.CreateCalculator(); + + byte[] encoded = tbsCert.GetDerEncoded(); + + streamCalculator.Stream.Write(encoded, 0, encoded.Length); + + Platform.Dispose(streamCalculator.Stream); + + return GenerateJcaObject(tbsCert, (AlgorithmIdentifier)signatureCalculatorFactory.AlgorithmDetails, ((IBlockResult)streamCalculator.GetResult()).Collect()); + } + + private X509Certificate GenerateJcaObject( + TbsCertificateStructure tbsCert, + AlgorithmIdentifier sigAlg, + byte[] signature) + { + return new X509Certificate( + new X509CertificateStructure(tbsCert, sigAlg, new DerBitString(signature))); + } + + /// + /// Allows enumeration of the signature names supported by the generator. + /// + public IEnumerable SignatureAlgNames + { + get { return X509Utilities.GetAlgNames(); } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509V1CertificateGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509V1CertificateGenerator.cs.meta new file mode 100644 index 0000000..f1331a5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509V1CertificateGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 80e14b0a5f72b13428e8fa90ef72ffd7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509V2AttributeCertificate.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509V2AttributeCertificate.cs new file mode 100644 index 0000000..1ceba10 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509V2AttributeCertificate.cs @@ -0,0 +1,280 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Operators; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Security.Certificates; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.X509 +{ + /// An implementation of a version 2 X.509 Attribute Certificate. + public class X509V2AttributeCertificate + : X509ExtensionBase, IX509AttributeCertificate + { + private readonly AttributeCertificate cert; + private readonly DateTime notBefore; + private readonly DateTime notAfter; + + private static AttributeCertificate GetObject(Stream input) + { + try + { + return AttributeCertificate.GetInstance(Asn1Object.FromStream(input)); + } + catch (IOException e) + { + throw e; + } + catch (Exception e) + { + throw new IOException("exception decoding certificate structure", e); + } + } + + public X509V2AttributeCertificate( + Stream encIn) + : this(GetObject(encIn)) + { + } + + public X509V2AttributeCertificate( + byte[] encoded) + : this(new MemoryStream(encoded, false)) + { + } + + internal X509V2AttributeCertificate( + AttributeCertificate cert) + { + this.cert = cert; + + try + { + this.notAfter = cert.ACInfo.AttrCertValidityPeriod.NotAfterTime.ToDateTime(); + this.notBefore = cert.ACInfo.AttrCertValidityPeriod.NotBeforeTime.ToDateTime(); + } + catch (Exception e) + { + throw new IOException("invalid data structure in certificate!", e); + } + } + + public virtual int Version + { + get { return cert.ACInfo.Version.IntValueExact + 1; } + } + + public virtual BigInteger SerialNumber + { + get { return cert.ACInfo.SerialNumber.Value; } + } + + public virtual AttributeCertificateHolder Holder + { + get + { + return new AttributeCertificateHolder((Asn1Sequence)cert.ACInfo.Holder.ToAsn1Object()); + } + } + + public virtual AttributeCertificateIssuer Issuer + { + get + { + return new AttributeCertificateIssuer(cert.ACInfo.Issuer); + } + } + + public virtual DateTime NotBefore + { + get { return notBefore; } + } + + public virtual DateTime NotAfter + { + get { return notAfter; } + } + + public virtual bool[] GetIssuerUniqueID() + { + DerBitString id = cert.ACInfo.IssuerUniqueID; + + if (id != null) + { + byte[] bytes = id.GetBytes(); + bool[] boolId = new bool[bytes.Length * 8 - id.PadBits]; + + for (int i = 0; i != boolId.Length; i++) + { + //boolId[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0; + boolId[i] = (bytes[i / 8] & (0x80 >> (i % 8))) != 0; + } + + return boolId; + } + + return null; + } + + public virtual bool IsValidNow + { + get { return IsValid(DateTime.UtcNow); } + } + + public virtual bool IsValid( + DateTime date) + { + return date.CompareTo(NotBefore) >= 0 && date.CompareTo(NotAfter) <= 0; + } + + public virtual void CheckValidity() + { + this.CheckValidity(DateTime.UtcNow); + } + + public virtual void CheckValidity( + DateTime date) + { + if (date.CompareTo(NotAfter) > 0) + throw new CertificateExpiredException("certificate expired on " + NotAfter); + if (date.CompareTo(NotBefore) < 0) + throw new CertificateNotYetValidException("certificate not valid until " + NotBefore); + } + + public virtual AlgorithmIdentifier SignatureAlgorithm + { + get { return cert.SignatureAlgorithm; } + } + + public virtual byte[] GetSignature() + { + return cert.GetSignatureOctets(); + } + + public virtual void Verify( + AsymmetricKeyParameter key) + { + CheckSignature(new Asn1VerifierFactory(cert.SignatureAlgorithm, key)); + } + + /// + /// Verify the certificate's signature using a verifier created using the passed in verifier provider. + /// + /// An appropriate provider for verifying the certificate's signature. + /// True if the signature is valid. + /// If verifier provider is not appropriate or the certificate algorithm is invalid. + public virtual void Verify( + IVerifierFactoryProvider verifierProvider) + { + CheckSignature(verifierProvider.CreateVerifierFactory(cert.SignatureAlgorithm)); + } + + protected virtual void CheckSignature( + IVerifierFactory verifier) + { + if (!cert.SignatureAlgorithm.Equals(cert.ACInfo.Signature)) + { + throw new CertificateException("Signature algorithm in certificate info not same as outer certificate"); + } + + IStreamCalculator streamCalculator = verifier.CreateCalculator(); + + try + { + byte[] b = this.cert.ACInfo.GetEncoded(); + + streamCalculator.Stream.Write(b, 0, b.Length); + + Platform.Dispose(streamCalculator.Stream); + } + catch (IOException e) + { + throw new SignatureException("Exception encoding certificate info object", e); + } + + if (!((IVerifier)streamCalculator.GetResult()).IsVerified(this.GetSignature())) + { + throw new InvalidKeyException("Public key presented not for certificate signature"); + } + } + + public virtual byte[] GetEncoded() + { + return cert.GetEncoded(); + } + + protected override X509Extensions GetX509Extensions() + { + return cert.ACInfo.Extensions; + } + + public virtual X509Attribute[] GetAttributes() + { + Asn1Sequence seq = cert.ACInfo.Attributes; + X509Attribute[] attrs = new X509Attribute[seq.Count]; + + for (int i = 0; i != seq.Count; i++) + { + attrs[i] = new X509Attribute((Asn1Encodable)seq[i]); + } + + return attrs; + } + + public virtual X509Attribute[] GetAttributes( + string oid) + { + Asn1Sequence seq = cert.ACInfo.Attributes; + IList list = Platform.CreateArrayList(); + + for (int i = 0; i != seq.Count; i++) + { + X509Attribute attr = new X509Attribute((Asn1Encodable)seq[i]); + if (attr.Oid.Equals(oid)) + { + list.Add(attr); + } + } + + if (list.Count < 1) + { + return null; + } + + X509Attribute[] result = new X509Attribute[list.Count]; + for (int i = 0; i < list.Count; ++i) + { + result[i] = (X509Attribute)list[i]; + } + return result; + } + + public override bool Equals( + object obj) + { + if (obj == this) + return true; + + X509V2AttributeCertificate other = obj as X509V2AttributeCertificate; + + if (other == null) + return false; + + return cert.Equals(other.cert); + + // NB: May prefer this implementation of Equals if more than one certificate implementation in play + //return Arrays.AreEqual(this.GetEncoded(), other.GetEncoded()); + } + + public override int GetHashCode() + { + return cert.GetHashCode(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509V2AttributeCertificate.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509V2AttributeCertificate.cs.meta new file mode 100644 index 0000000..ed55a79 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509V2AttributeCertificate.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cb60a37d8c8f36e4690be68f587763da +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509V2AttributeCertificateGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509V2AttributeCertificateGenerator.cs new file mode 100644 index 0000000..18a4959 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509V2AttributeCertificateGenerator.cs @@ -0,0 +1,203 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Operators; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Security.Certificates; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.X509 +{ + /// Class to produce an X.509 Version 2 AttributeCertificate. + public class X509V2AttributeCertificateGenerator + { + private readonly X509ExtensionsGenerator extGenerator = new X509ExtensionsGenerator(); + + private V2AttributeCertificateInfoGenerator acInfoGen; + private DerObjectIdentifier sigOID; + private AlgorithmIdentifier sigAlgId; + private string signatureAlgorithm; + + public X509V2AttributeCertificateGenerator() + { + acInfoGen = new V2AttributeCertificateInfoGenerator(); + } + + /// Reset the generator + public void Reset() + { + acInfoGen = new V2AttributeCertificateInfoGenerator(); + extGenerator.Reset(); + } + + /// Set the Holder of this Attribute Certificate. + public void SetHolder( + AttributeCertificateHolder holder) + { + acInfoGen.SetHolder(holder.holder); + } + + /// Set the issuer. + public void SetIssuer( + AttributeCertificateIssuer issuer) + { + acInfoGen.SetIssuer(AttCertIssuer.GetInstance(issuer.form)); + } + + /// Set the serial number for the certificate. + public void SetSerialNumber( + BigInteger serialNumber) + { + acInfoGen.SetSerialNumber(new DerInteger(serialNumber)); + } + + public void SetNotBefore( + DateTime date) + { + acInfoGen.SetStartDate(new DerGeneralizedTime(date)); + } + + public void SetNotAfter( + DateTime date) + { + acInfoGen.SetEndDate(new DerGeneralizedTime(date)); + } + + /// + /// Set the signature algorithm. This can be either a name or an OID, names + /// are treated as case insensitive. + /// + /// The algorithm name. + [Obsolete("Not needed if Generate used with an ISignatureFactory")] + public void SetSignatureAlgorithm( + string signatureAlgorithm) + { + this.signatureAlgorithm = signatureAlgorithm; + + try + { + sigOID = X509Utilities.GetAlgorithmOid(signatureAlgorithm); + } + catch (Exception) + { + throw new ArgumentException("Unknown signature type requested"); + } + + sigAlgId = X509Utilities.GetSigAlgID(sigOID, signatureAlgorithm); + + acInfoGen.SetSignature(sigAlgId); + } + + /// Add an attribute. + public void AddAttribute( + X509Attribute attribute) + { + acInfoGen.AddAttribute(AttributeX509.GetInstance(attribute.ToAsn1Object())); + } + + public void SetIssuerUniqueId( + bool[] iui) + { + // TODO convert bool array to bit string + //acInfoGen.SetIssuerUniqueID(iui); + throw Platform.CreateNotImplementedException("SetIssuerUniqueId()"); + } + + /// Add a given extension field for the standard extensions tag. + public void AddExtension( + string oid, + bool critical, + Asn1Encodable extensionValue) + { + extGenerator.AddExtension(new DerObjectIdentifier(oid), critical, extensionValue); + } + + /// + /// Add a given extension field for the standard extensions tag. + /// The value parameter becomes the contents of the octet string associated + /// with the extension. + /// + public void AddExtension( + string oid, + bool critical, + byte[] extensionValue) + { + extGenerator.AddExtension(new DerObjectIdentifier(oid), critical, extensionValue); + } + + /// + /// Generate an X509 certificate, based on the current issuer and subject. + /// + [Obsolete("Use Generate with an ISignatureFactory")] + public IX509AttributeCertificate Generate( + AsymmetricKeyParameter privateKey) + { + return Generate(privateKey, null); + } + + /// + /// Generate an X509 certificate, based on the current issuer and subject, + /// using the supplied source of randomness, if required. + /// + [Obsolete("Use Generate with an ISignatureFactory")] + public IX509AttributeCertificate Generate( + AsymmetricKeyParameter privateKey, + SecureRandom random) + { + return Generate(new Asn1SignatureFactory(signatureAlgorithm, privateKey, random)); + } + + /// + /// Generate a new X.509 Attribute Certificate using the passed in SignatureCalculator. + /// + /// A signature calculator factory with the necessary algorithm details. + /// An IX509AttributeCertificate. + public IX509AttributeCertificate Generate(ISignatureFactory signatureCalculatorFactory) + { + if (!extGenerator.IsEmpty) + { + acInfoGen.SetExtensions(extGenerator.Generate()); + } + + AlgorithmIdentifier sigAlgID = (AlgorithmIdentifier)signatureCalculatorFactory.AlgorithmDetails; + + acInfoGen.SetSignature(sigAlgID); + + AttributeCertificateInfo acInfo = acInfoGen.GenerateAttributeCertificateInfo(); + + byte[] encoded = acInfo.GetDerEncoded(); + + IStreamCalculator streamCalculator = signatureCalculatorFactory.CreateCalculator(); + + streamCalculator.Stream.Write(encoded, 0, encoded.Length); + + Platform.Dispose(streamCalculator.Stream); + + try + { + DerBitString signatureValue = new DerBitString(((IBlockResult)streamCalculator.GetResult()).Collect()); + + return new X509V2AttributeCertificate(new AttributeCertificate(acInfo, sigAlgID, signatureValue)); + } + catch (Exception e) + { + // TODO +// throw new ExtCertificateEncodingException("constructed invalid certificate", e); + throw new CertificateEncodingException("constructed invalid certificate", e); + } + } + + /// + /// Allows enumeration of the signature names supported by the generator. + /// + public IEnumerable SignatureAlgNames + { + get { return X509Utilities.GetAlgNames(); } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509V2AttributeCertificateGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509V2AttributeCertificateGenerator.cs.meta new file mode 100644 index 0000000..0e647a4 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509V2AttributeCertificateGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 616479359b4cdf64e9e210d6288ecab5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509V2CRLGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509V2CRLGenerator.cs new file mode 100644 index 0000000..566d502 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509V2CRLGenerator.cs @@ -0,0 +1,278 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Operators; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Security.Certificates; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; + +namespace Org.BouncyCastle.X509 +{ + /** + * class to produce an X.509 Version 2 CRL. + */ + public class X509V2CrlGenerator + { + private readonly X509ExtensionsGenerator extGenerator = new X509ExtensionsGenerator(); + + private V2TbsCertListGenerator tbsGen; + private DerObjectIdentifier sigOID; + private AlgorithmIdentifier sigAlgId; + private string signatureAlgorithm; + + public X509V2CrlGenerator() + { + tbsGen = new V2TbsCertListGenerator(); + } + + /** + * reset the generator + */ + public void Reset() + { + tbsGen = new V2TbsCertListGenerator(); + extGenerator.Reset(); + } + + /** + * Set the issuer distinguished name - the issuer is the entity whose private key is used to sign the + * certificate. + */ + public void SetIssuerDN( + X509Name issuer) + { + tbsGen.SetIssuer(issuer); + } + + public void SetThisUpdate( + DateTime date) + { + tbsGen.SetThisUpdate(new Time(date)); + } + + public void SetNextUpdate( + DateTime date) + { + tbsGen.SetNextUpdate(new Time(date)); + } + + /** + * Reason being as indicated by CrlReason, i.e. CrlReason.KeyCompromise + * or 0 if CrlReason is not to be used + **/ + public void AddCrlEntry( + BigInteger userCertificate, + DateTime revocationDate, + int reason) + { + tbsGen.AddCrlEntry(new DerInteger(userCertificate), new Time(revocationDate), reason); + } + + /** + * Add a CRL entry with an Invalidity Date extension as well as a CrlReason extension. + * Reason being as indicated by CrlReason, i.e. CrlReason.KeyCompromise + * or 0 if CrlReason is not to be used + **/ + public void AddCrlEntry( + BigInteger userCertificate, + DateTime revocationDate, + int reason, + DateTime invalidityDate) + { + tbsGen.AddCrlEntry(new DerInteger(userCertificate), new Time(revocationDate), reason, new DerGeneralizedTime(invalidityDate)); + } + + /** + * Add a CRL entry with extensions. + **/ + public void AddCrlEntry( + BigInteger userCertificate, + DateTime revocationDate, + X509Extensions extensions) + { + tbsGen.AddCrlEntry(new DerInteger(userCertificate), new Time(revocationDate), extensions); + } + + /** + * Add the CRLEntry objects contained in a previous CRL. + * + * @param other the X509Crl to source the other entries from. + */ + public void AddCrl( + X509Crl other) + { + if (other == null) + throw new ArgumentNullException("other"); + + ISet revocations = other.GetRevokedCertificates(); + + if (revocations != null) + { + foreach (X509CrlEntry entry in revocations) + { + try + { + tbsGen.AddCrlEntry( + Asn1Sequence.GetInstance( + Asn1Object.FromByteArray(entry.GetEncoded()))); + } + catch (IOException e) + { + throw new CrlException("exception processing encoding of CRL", e); + } + } + } + } + + /// + /// Set the signature algorithm that will be used to sign this CRL. + /// + /// + [Obsolete("Not needed if Generate used with an ISignatureFactory")] + public void SetSignatureAlgorithm( + string signatureAlgorithm) + { + this.signatureAlgorithm = signatureAlgorithm; + + try + { + sigOID = X509Utilities.GetAlgorithmOid(signatureAlgorithm); + } + catch (Exception e) + { + throw new ArgumentException("Unknown signature type requested", e); + } + + sigAlgId = X509Utilities.GetSigAlgID(sigOID, signatureAlgorithm); + + tbsGen.SetSignature(sigAlgId); + } + + /** + * add a given extension field for the standard extensions tag (tag 0) + */ + public void AddExtension( + string oid, + bool critical, + Asn1Encodable extensionValue) + { + extGenerator.AddExtension(new DerObjectIdentifier(oid), critical, extensionValue); + } + + /** + * add a given extension field for the standard extensions tag (tag 0) + */ + public void AddExtension( + DerObjectIdentifier oid, + bool critical, + Asn1Encodable extensionValue) + { + extGenerator.AddExtension(oid, critical, extensionValue); + } + + /** + * add a given extension field for the standard extensions tag (tag 0) + */ + public void AddExtension( + string oid, + bool critical, + byte[] extensionValue) + { + extGenerator.AddExtension(new DerObjectIdentifier(oid), critical, new DerOctetString(extensionValue)); + } + + /** + * add a given extension field for the standard extensions tag (tag 0) + */ + public void AddExtension( + DerObjectIdentifier oid, + bool critical, + byte[] extensionValue) + { + extGenerator.AddExtension(oid, critical, new DerOctetString(extensionValue)); + } + + /// + /// Generate an X.509 CRL, based on the current issuer and subject. + /// + /// The private key of the issuer that is signing this certificate. + /// An X509Crl. + [Obsolete("Use Generate with an ISignatureFactory")] + public X509Crl Generate( + AsymmetricKeyParameter privateKey) + { + return Generate(privateKey, null); + } + + /// + /// Generate an X.509 CRL, based on the current issuer and subject using the specified secure random. + /// + /// The private key of the issuer that is signing this certificate. + /// Your Secure Random instance. + /// An X509Crl. + [Obsolete("Use Generate with an ISignatureFactory")] + public X509Crl Generate( + AsymmetricKeyParameter privateKey, + SecureRandom random) + { + return Generate(new Asn1SignatureFactory(signatureAlgorithm, privateKey, random)); + } + + /// + /// Generate a new X509Crl using the passed in SignatureCalculator. + /// + /// A signature calculator factory with the necessary algorithm details. + /// An X509Crl. + public X509Crl Generate(ISignatureFactory signatureCalculatorFactory) + { + tbsGen.SetSignature((AlgorithmIdentifier)signatureCalculatorFactory.AlgorithmDetails); + + TbsCertificateList tbsCertList = GenerateCertList(); + + IStreamCalculator streamCalculator = signatureCalculatorFactory.CreateCalculator(); + + byte[] encoded = tbsCertList.GetDerEncoded(); + + streamCalculator.Stream.Write(encoded, 0, encoded.Length); + + Platform.Dispose(streamCalculator.Stream); + + return GenerateJcaObject(tbsCertList, (AlgorithmIdentifier)signatureCalculatorFactory.AlgorithmDetails, ((IBlockResult)streamCalculator.GetResult()).Collect()); + } + + private TbsCertificateList GenerateCertList() + { + if (!extGenerator.IsEmpty) + { + tbsGen.SetExtensions(extGenerator.Generate()); + } + + return tbsGen.GenerateTbsCertList(); + } + + private X509Crl GenerateJcaObject( + TbsCertificateList tbsCrl, + AlgorithmIdentifier algId, + byte[] signature) + { + return new X509Crl( + CertificateList.GetInstance( + new DerSequence(tbsCrl, algId, new DerBitString(signature)))); + } + + /// + /// Allows enumeration of the signature names supported by the generator. + /// + public IEnumerable SignatureAlgNames + { + get { return X509Utilities.GetAlgNames(); } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509V2CRLGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509V2CRLGenerator.cs.meta new file mode 100644 index 0000000..039cb4d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509V2CRLGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f898b84a2b8f154428e620e0b14b629f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509V3CertificateGenerator.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509V3CertificateGenerator.cs new file mode 100644 index 0000000..bc619c3 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509V3CertificateGenerator.cs @@ -0,0 +1,344 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Operators; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Security.Certificates; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.X509.Extension; + +namespace Org.BouncyCastle.X509 +{ + /// + /// A class to Generate Version 3 X509Certificates. + /// + public class X509V3CertificateGenerator + { + private readonly X509ExtensionsGenerator extGenerator = new X509ExtensionsGenerator(); + + private V3TbsCertificateGenerator tbsGen; + private DerObjectIdentifier sigOid; + private AlgorithmIdentifier sigAlgId; + private string signatureAlgorithm; + + public X509V3CertificateGenerator() + { + tbsGen = new V3TbsCertificateGenerator(); + } + + /// + /// Reset the Generator. + /// + public void Reset() + { + tbsGen = new V3TbsCertificateGenerator(); + extGenerator.Reset(); + } + + /// + /// Set the certificate's serial number. + /// + /// Make serial numbers long, if you have no serial number policy make sure the number is at least 16 bytes of secure random data. + /// You will be surprised how ugly a serial number collision can Get. + /// The serial number. + public void SetSerialNumber( + BigInteger serialNumber) + { + if (serialNumber.SignValue <= 0) + { + throw new ArgumentException("serial number must be a positive integer", "serialNumber"); + } + + tbsGen.SetSerialNumber(new DerInteger(serialNumber)); + } + + /// + /// Set the distinguished name of the issuer. + /// The issuer is the entity which is signing the certificate. + /// + /// The issuer's DN. + public void SetIssuerDN( + X509Name issuer) + { + tbsGen.SetIssuer(issuer); + } + + /// + /// Set the date that this certificate is to be valid from. + /// + /// + public void SetNotBefore( + DateTime date) + { + tbsGen.SetStartDate(new Time(date)); + } + + /// + /// Set the date after which this certificate will no longer be valid. + /// + /// + public void SetNotAfter( + DateTime date) + { + tbsGen.SetEndDate(new Time(date)); + } + + /// + /// Set the DN of the entity that this certificate is about. + /// + /// + public void SetSubjectDN( + X509Name subject) + { + tbsGen.SetSubject(subject); + } + + /// + /// Set the public key that this certificate identifies. + /// + /// + public void SetPublicKey( + AsymmetricKeyParameter publicKey) + { + tbsGen.SetSubjectPublicKeyInfo(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(publicKey)); + } + + /// + /// Set the signature algorithm that will be used to sign this certificate. + /// + /// + [Obsolete("Not needed if Generate used with an ISignatureFactory")] + public void SetSignatureAlgorithm( + string signatureAlgorithm) + { + this.signatureAlgorithm = signatureAlgorithm; + + try + { + sigOid = X509Utilities.GetAlgorithmOid(signatureAlgorithm); + } + catch (Exception) + { + throw new ArgumentException("Unknown signature type requested: " + signatureAlgorithm); + } + + sigAlgId = X509Utilities.GetSigAlgID(sigOid, signatureAlgorithm); + + tbsGen.SetSignature(sigAlgId); + } + + /// + /// Set the subject unique ID - note: it is very rare that it is correct to do this. + /// + /// + public void SetSubjectUniqueID( + bool[] uniqueID) + { + tbsGen.SetSubjectUniqueID(booleanToBitString(uniqueID)); + } + + /// + /// Set the issuer unique ID - note: it is very rare that it is correct to do this. + /// + /// + public void SetIssuerUniqueID( + bool[] uniqueID) + { + tbsGen.SetIssuerUniqueID(booleanToBitString(uniqueID)); + } + + private DerBitString booleanToBitString( + bool[] id) + { + byte[] bytes = new byte[(id.Length + 7) / 8]; + + for (int i = 0; i != id.Length; i++) + { + if (id[i]) + { + bytes[i / 8] |= (byte)(1 << ((7 - (i % 8)))); + } + } + + int pad = id.Length % 8; + + if (pad == 0) + { + return new DerBitString(bytes); + } + + return new DerBitString(bytes, 8 - pad); + } + + /// + /// Add a given extension field for the standard extensions tag (tag 3). + /// + /// string containing a dotted decimal Object Identifier. + /// Is it critical. + /// The value. + public void AddExtension( + string oid, + bool critical, + Asn1Encodable extensionValue) + { + extGenerator.AddExtension(new DerObjectIdentifier(oid), critical, extensionValue); + } + + /// + /// Add an extension to this certificate. + /// + /// Its Object Identifier. + /// Is it critical. + /// The value. + public void AddExtension( + DerObjectIdentifier oid, + bool critical, + Asn1Encodable extensionValue) + { + extGenerator.AddExtension(oid, critical, extensionValue); + } + + /// + /// Add an extension using a string with a dotted decimal OID. + /// + /// string containing a dotted decimal Object Identifier. + /// Is it critical. + /// byte[] containing the value of this extension. + public void AddExtension( + string oid, + bool critical, + byte[] extensionValue) + { + extGenerator.AddExtension(new DerObjectIdentifier(oid), critical, new DerOctetString(extensionValue)); + } + + /// + /// Add an extension to this certificate. + /// + /// Its Object Identifier. + /// Is it critical. + /// byte[] containing the value of this extension. + public void AddExtension( + DerObjectIdentifier oid, + bool critical, + byte[] extensionValue) + { + extGenerator.AddExtension(oid, critical, new DerOctetString(extensionValue)); + } + + /// + /// Add a given extension field for the standard extensions tag (tag 3), + /// copying the extension value from another certificate. + /// + public void CopyAndAddExtension( + string oid, + bool critical, + X509Certificate cert) + { + CopyAndAddExtension(new DerObjectIdentifier(oid), critical, cert); + } + + /** + * add a given extension field for the standard extensions tag (tag 3) + * copying the extension value from another certificate. + * @throws CertificateParsingException if the extension cannot be extracted. + */ + public void CopyAndAddExtension( + DerObjectIdentifier oid, + bool critical, + X509Certificate cert) + { + Asn1OctetString extValue = cert.GetExtensionValue(oid); + + if (extValue == null) + { + throw new CertificateParsingException("extension " + oid + " not present"); + } + + try + { + Asn1Encodable value = X509ExtensionUtilities.FromExtensionValue(extValue); + + this.AddExtension(oid, critical, value); + } + catch (Exception e) + { + throw new CertificateParsingException(e.Message, e); + } + } + + /// + /// Generate an X509Certificate. + /// + /// The private key of the issuer that is signing this certificate. + /// An X509Certificate. + [Obsolete("Use Generate with an ISignatureFactory")] + public X509Certificate Generate( + AsymmetricKeyParameter privateKey) + { + return Generate(privateKey, null); + } + + /// + /// Generate an X509Certificate using your own SecureRandom. + /// + /// The private key of the issuer that is signing this certificate. + /// You Secure Random instance. + /// An X509Certificate. + [Obsolete("Use Generate with an ISignatureFactory")] + public X509Certificate Generate( + AsymmetricKeyParameter privateKey, + SecureRandom random) + { + return Generate(new Asn1SignatureFactory(signatureAlgorithm, privateKey, random)); + } + + /// + /// Generate a new X509Certificate using the passed in SignatureCalculator. + /// + /// A signature calculator factory with the necessary algorithm details. + /// An X509Certificate. + public X509Certificate Generate(ISignatureFactory signatureCalculatorFactory) + { + tbsGen.SetSignature ((AlgorithmIdentifier)signatureCalculatorFactory.AlgorithmDetails); + + if (!extGenerator.IsEmpty) + { + tbsGen.SetExtensions(extGenerator.Generate()); + } + + TbsCertificateStructure tbsCert = tbsGen.GenerateTbsCertificate(); + + IStreamCalculator streamCalculator = signatureCalculatorFactory.CreateCalculator(); + + byte[] encoded = tbsCert.GetDerEncoded(); + + streamCalculator.Stream.Write(encoded, 0, encoded.Length); + + Platform.Dispose(streamCalculator.Stream); + + return GenerateJcaObject(tbsCert, (AlgorithmIdentifier)signatureCalculatorFactory.AlgorithmDetails, ((IBlockResult)streamCalculator.GetResult()).Collect()); + } + + private X509Certificate GenerateJcaObject( + TbsCertificateStructure tbsCert, + AlgorithmIdentifier sigAlg, + byte[] signature) + { + return new X509Certificate( + new X509CertificateStructure(tbsCert, sigAlg, new DerBitString(signature))); + } + + /// + /// Allows enumeration of the signature names supported by the generator. + /// + public IEnumerable SignatureAlgNames + { + get { return X509Utilities.GetAlgNames(); } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509V3CertificateGenerator.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509V3CertificateGenerator.cs.meta new file mode 100644 index 0000000..a15d1a6 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/X509V3CertificateGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bd4743b1a95811a45a2f0363fdd61add +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/extension.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/extension.meta new file mode 100644 index 0000000..ed94a08 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/extension.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: cac78af00e1c1c446a515b0ef25ca0c9 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/extension/AuthorityKeyIdentifierStructure.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/extension/AuthorityKeyIdentifierStructure.cs new file mode 100644 index 0000000..006dc00 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/extension/AuthorityKeyIdentifierStructure.cs @@ -0,0 +1,102 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Security.Certificates; + +namespace Org.BouncyCastle.X509.Extension +{ + /// A high level authority key identifier. + public class AuthorityKeyIdentifierStructure + : AuthorityKeyIdentifier + { + /** + * Constructor which will take the byte[] returned from getExtensionValue() + * + * @param encodedValue a DER octet encoded string with the extension structure in it. + * @throws IOException on parsing errors. + */ + // TODO Add a functional constructor from byte[]? + public AuthorityKeyIdentifierStructure( + Asn1OctetString encodedValue) + : base((Asn1Sequence) X509ExtensionUtilities.FromExtensionValue(encodedValue)) + { + } + + private static Asn1Sequence FromCertificate( + X509Certificate certificate) + { + try + { + GeneralName genName = new GeneralName( + PrincipalUtilities.GetIssuerX509Principal(certificate)); + + if (certificate.Version == 3) + { + Asn1OctetString ext = certificate.GetExtensionValue(X509Extensions.SubjectKeyIdentifier); + + if (ext != null) + { + Asn1OctetString str = (Asn1OctetString) X509ExtensionUtilities.FromExtensionValue(ext); + + return (Asn1Sequence) new AuthorityKeyIdentifier( + str.GetOctets(), new GeneralNames(genName), certificate.SerialNumber).ToAsn1Object(); + } + } + + SubjectPublicKeyInfo info = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo( + certificate.GetPublicKey()); + + return (Asn1Sequence) new AuthorityKeyIdentifier( + info, new GeneralNames(genName), certificate.SerialNumber).ToAsn1Object(); + } + catch (Exception e) + { + throw new CertificateParsingException("Exception extracting certificate details", e); + } + } + + private static Asn1Sequence FromKey( + AsymmetricKeyParameter pubKey) + { + try + { + SubjectPublicKeyInfo info = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(pubKey); + + return (Asn1Sequence) new AuthorityKeyIdentifier(info).ToAsn1Object(); + } + catch (Exception e) + { + throw new InvalidKeyException("can't process key: " + e); + } + } + + /** + * Create an AuthorityKeyIdentifier using the passed in certificate's public + * key, issuer and serial number. + * + * @param certificate the certificate providing the information. + * @throws CertificateParsingException if there is a problem processing the certificate + */ + public AuthorityKeyIdentifierStructure( + X509Certificate certificate) + : base(FromCertificate(certificate)) + { + } + + /** + * Create an AuthorityKeyIdentifier using just the hash of the + * public key. + * + * @param pubKey the key to generate the hash from. + * @throws InvalidKeyException if there is a problem using the key. + */ + public AuthorityKeyIdentifierStructure( + AsymmetricKeyParameter pubKey) + : base(FromKey(pubKey)) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/extension/AuthorityKeyIdentifierStructure.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/extension/AuthorityKeyIdentifierStructure.cs.meta new file mode 100644 index 0000000..bfddaf5 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/extension/AuthorityKeyIdentifierStructure.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2e560974b580d0f42b73a1a209906405 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/extension/SubjectKeyIdentifierStructure.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/extension/SubjectKeyIdentifierStructure.cs new file mode 100644 index 0000000..4c7b79a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/extension/SubjectKeyIdentifierStructure.cs @@ -0,0 +1,49 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Security.Certificates; + +namespace Org.BouncyCastle.X509.Extension +{ + /** + * A high level subject key identifier. + */ + public class SubjectKeyIdentifierStructure + : SubjectKeyIdentifier + { + /** + * Constructor which will take the byte[] returned from getExtensionValue() + * + * @param encodedValue a DER octet encoded string with the extension structure in it. + * @throws IOException on parsing errors. + */ + public SubjectKeyIdentifierStructure( + Asn1OctetString encodedValue) + : base((Asn1OctetString) X509ExtensionUtilities.FromExtensionValue(encodedValue)) + { + } + + private static Asn1OctetString FromPublicKey( + AsymmetricKeyParameter pubKey) + { + try + { + SubjectPublicKeyInfo info = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(pubKey); + + return (Asn1OctetString) new SubjectKeyIdentifier(info).ToAsn1Object(); + } + catch (Exception e) + { + throw new CertificateParsingException("Exception extracting certificate details: " + e.ToString()); + } + } + + public SubjectKeyIdentifierStructure( + AsymmetricKeyParameter pubKey) + : base(FromPublicKey(pubKey)) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/extension/SubjectKeyIdentifierStructure.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/extension/SubjectKeyIdentifierStructure.cs.meta new file mode 100644 index 0000000..4e5821f --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/extension/SubjectKeyIdentifierStructure.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a657590ec6b791f4483288ab2b964bb6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/extension/X509ExtensionUtil.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/extension/X509ExtensionUtil.cs new file mode 100644 index 0000000..5f65ebf --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/extension/X509ExtensionUtil.cs @@ -0,0 +1,91 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Security.Certificates; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.X509.Extension +{ + public class X509ExtensionUtilities + { + public static Asn1Object FromExtensionValue( + Asn1OctetString extensionValue) + { + return Asn1Object.FromByteArray(extensionValue.GetOctets()); + } + + public static ICollection GetIssuerAlternativeNames( + X509Certificate cert) + { + Asn1OctetString extVal = cert.GetExtensionValue(X509Extensions.IssuerAlternativeName); + + return GetAlternativeName(extVal); + } + + public static ICollection GetSubjectAlternativeNames( + X509Certificate cert) + { + Asn1OctetString extVal = cert.GetExtensionValue(X509Extensions.SubjectAlternativeName); + + return GetAlternativeName(extVal); + } + + private static ICollection GetAlternativeName( + Asn1OctetString extVal) + { + IList temp = Platform.CreateArrayList(); + + if (extVal != null) + { + try + { + Asn1Sequence seq = DerSequence.GetInstance(FromExtensionValue(extVal)); + + foreach (Asn1Encodable primName in seq) + { + IList list = Platform.CreateArrayList(); + GeneralName genName = GeneralName.GetInstance(primName); + + list.Add(genName.TagNo); + + switch (genName.TagNo) + { + case GeneralName.EdiPartyName: + case GeneralName.X400Address: + case GeneralName.OtherName: + list.Add(genName.Name.ToAsn1Object()); + break; + case GeneralName.DirectoryName: + list.Add(X509Name.GetInstance(genName.Name).ToString()); + break; + case GeneralName.DnsName: + case GeneralName.Rfc822Name: + case GeneralName.UniformResourceIdentifier: + list.Add(((IAsn1String)genName.Name).GetString()); + break; + case GeneralName.RegisteredID: + list.Add(DerObjectIdentifier.GetInstance(genName.Name).Id); + break; + case GeneralName.IPAddress: + list.Add(DerOctetString.GetInstance(genName.Name).GetOctets()); + break; + default: + throw new IOException("Bad tag number: " + genName.TagNo); + } + + temp.Add(list); + } + } + catch (Exception e) + { + throw new CertificateParsingException(e.Message); + } + } + + return temp; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/extension/X509ExtensionUtil.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/extension/X509ExtensionUtil.cs.meta new file mode 100644 index 0000000..134dbad --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/extension/X509ExtensionUtil.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d2fe9e683cc6e124d976415fe10e1757 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store.meta new file mode 100644 index 0000000..2c76488 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9649a51fa31ab5441ab975e5cc6c64f4 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/IX509Selector.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/IX509Selector.cs new file mode 100644 index 0000000..75358cb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/IX509Selector.cs @@ -0,0 +1,15 @@ +using System; + +namespace Org.BouncyCastle.X509.Store +{ + public interface IX509Selector +#if !(SILVERLIGHT || PORTABLE) + : ICloneable +#endif + { +#if SILVERLIGHT || PORTABLE + object Clone(); +#endif + bool Match(object obj); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/IX509Selector.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/IX509Selector.cs.meta new file mode 100644 index 0000000..dc09a68 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/IX509Selector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 81a14eea68fb4a44ab7ec31e8f3b85fc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/IX509Store.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/IX509Store.cs new file mode 100644 index 0000000..e5c3a46 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/IX509Store.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections; + +namespace Org.BouncyCastle.X509.Store +{ + public interface IX509Store + { +// void Init(IX509StoreParameters parameters); + ICollection GetMatches(IX509Selector selector); + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/IX509Store.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/IX509Store.cs.meta new file mode 100644 index 0000000..95414cc --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/IX509Store.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c887cd71143d7544a89b9dd14ce3ad81 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/IX509StoreParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/IX509StoreParameters.cs new file mode 100644 index 0000000..aee3036 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/IX509StoreParameters.cs @@ -0,0 +1,8 @@ +using System; + +namespace Org.BouncyCastle.X509.Store +{ + public interface IX509StoreParameters + { + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/IX509StoreParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/IX509StoreParameters.cs.meta new file mode 100644 index 0000000..4c40a9d --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/IX509StoreParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 61d6dd2b24b06424c9c8ff0dde926934 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/NoSuchStoreException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/NoSuchStoreException.cs new file mode 100644 index 0000000..28b1889 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/NoSuchStoreException.cs @@ -0,0 +1,28 @@ +using System; + +namespace Org.BouncyCastle.X509.Store +{ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE) + [Serializable] +#endif + public class NoSuchStoreException + : X509StoreException + { + public NoSuchStoreException() + { + } + + public NoSuchStoreException( + string message) + : base(message) + { + } + + public NoSuchStoreException( + string message, + Exception e) + : base(message, e) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/NoSuchStoreException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/NoSuchStoreException.cs.meta new file mode 100644 index 0000000..99bdaf1 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/NoSuchStoreException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8c09481a9206e944a9026519a14f386e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/X509AttrCertStoreSelector.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/X509AttrCertStoreSelector.cs new file mode 100644 index 0000000..9f1dc20 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/X509AttrCertStoreSelector.cs @@ -0,0 +1,376 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities.Collections; +using Org.BouncyCastle.Utilities.Date; +using Org.BouncyCastle.X509.Extension; + +namespace Org.BouncyCastle.X509.Store +{ + /** + * This class is an Selector like implementation to select + * attribute certificates from a given set of criteria. + * + * @see org.bouncycastle.x509.X509AttributeCertificate + * @see org.bouncycastle.x509.X509Store + */ + public class X509AttrCertStoreSelector + : IX509Selector + { + // TODO: name constraints??? + + private IX509AttributeCertificate attributeCert; + private DateTimeObject attributeCertificateValid; + private AttributeCertificateHolder holder; + private AttributeCertificateIssuer issuer; + private BigInteger serialNumber; + private ISet targetNames = new HashSet(); + private ISet targetGroups = new HashSet(); + + public X509AttrCertStoreSelector() + { + } + + private X509AttrCertStoreSelector( + X509AttrCertStoreSelector o) + { + this.attributeCert = o.attributeCert; + this.attributeCertificateValid = o.attributeCertificateValid; + this.holder = o.holder; + this.issuer = o.issuer; + this.serialNumber = o.serialNumber; + this.targetGroups = new HashSet(o.targetGroups); + this.targetNames = new HashSet(o.targetNames); + } + + /// + /// Decides if the given attribute certificate should be selected. + /// + /// The attribute certificate to be checked. + /// true if the object matches this selector. + public bool Match( + object obj) + { + if (obj == null) + throw new ArgumentNullException("obj"); + + IX509AttributeCertificate attrCert = obj as IX509AttributeCertificate; + + if (attrCert == null) + return false; + + if (this.attributeCert != null && !this.attributeCert.Equals(attrCert)) + return false; + + if (serialNumber != null && !attrCert.SerialNumber.Equals(serialNumber)) + return false; + + if (holder != null && !attrCert.Holder.Equals(holder)) + return false; + + if (issuer != null && !attrCert.Issuer.Equals(issuer)) + return false; + + if (attributeCertificateValid != null && !attrCert.IsValid(attributeCertificateValid.Value)) + return false; + + if (targetNames.Count > 0 || targetGroups.Count > 0) + { + Asn1OctetString targetInfoExt = attrCert.GetExtensionValue( + X509Extensions.TargetInformation); + + if (targetInfoExt != null) + { + TargetInformation targetinfo; + try + { + targetinfo = TargetInformation.GetInstance( + X509ExtensionUtilities.FromExtensionValue(targetInfoExt)); + } + catch (Exception) + { + return false; + } + + Targets[] targetss = targetinfo.GetTargetsObjects(); + + if (targetNames.Count > 0) + { + bool found = false; + + for (int i = 0; i < targetss.Length && !found; i++) + { + Target[] targets = targetss[i].GetTargets(); + + for (int j = 0; j < targets.Length; j++) + { + GeneralName targetName = targets[j].TargetName; + + if (targetName != null && targetNames.Contains(targetName)) + { + found = true; + break; + } + } + } + if (!found) + { + return false; + } + } + + if (targetGroups.Count > 0) + { + bool found = false; + + for (int i = 0; i < targetss.Length && !found; i++) + { + Target[] targets = targetss[i].GetTargets(); + + for (int j = 0; j < targets.Length; j++) + { + GeneralName targetGroup = targets[j].TargetGroup; + + if (targetGroup != null && targetGroups.Contains(targetGroup)) + { + found = true; + break; + } + } + } + + if (!found) + { + return false; + } + } + } + } + + return true; + } + + public object Clone() + { + return new X509AttrCertStoreSelector(this); + } + + /// The attribute certificate which must be matched. + /// If null is given, any will do. + public IX509AttributeCertificate AttributeCert + { + get { return attributeCert; } + set { this.attributeCert = value; } + } + + [Obsolete("Use AttributeCertificateValid instead")] + public DateTimeObject AttribueCertificateValid + { + get { return attributeCertificateValid; } + set { this.attributeCertificateValid = value; } + } + + /// The criteria for validity + /// If null is given any will do. + public DateTimeObject AttributeCertificateValid + { + get { return attributeCertificateValid; } + set { this.attributeCertificateValid = value; } + } + + /// The holder. + /// If null is given any will do. + public AttributeCertificateHolder Holder + { + get { return holder; } + set { this.holder = value; } + } + + /// The issuer. + /// If null is given any will do. + public AttributeCertificateIssuer Issuer + { + get { return issuer; } + set { this.issuer = value; } + } + + /// The serial number. + /// If null is given any will do. + public BigInteger SerialNumber + { + get { return serialNumber; } + set { this.serialNumber = value; } + } + + /** + * Adds a target name criterion for the attribute certificate to the target + * information extension criteria. The X509AttributeCertificate + * must contain at least one of the specified target names. + *

    + * Each attribute certificate may contain a target information extension + * limiting the servers where this attribute certificate can be used. If + * this extension is not present, the attribute certificate is not targeted + * and may be accepted by any server. + *

    + * + * @param name The name as a GeneralName (not null) + */ + public void AddTargetName( + GeneralName name) + { + targetNames.Add(name); + } + + /** + * Adds a target name criterion for the attribute certificate to the target + * information extension criteria. The X509AttributeCertificate + * must contain at least one of the specified target names. + *

    + * Each attribute certificate may contain a target information extension + * limiting the servers where this attribute certificate can be used. If + * this extension is not present, the attribute certificate is not targeted + * and may be accepted by any server. + *

    + * + * @param name a byte array containing the name in ASN.1 DER encoded form of a GeneralName + * @throws IOException if a parsing error occurs. + */ + public void AddTargetName( + byte[] name) + { + AddTargetName(GeneralName.GetInstance(Asn1Object.FromByteArray(name))); + } + + /** + * Adds a collection with target names criteria. If null is + * given any will do. + *

    + * The collection consists of either GeneralName objects or byte[] arrays representing + * DER encoded GeneralName structures. + *

    + * + * @param names A collection of target names. + * @throws IOException if a parsing error occurs. + * @see #AddTargetName(byte[]) + * @see #AddTargetName(GeneralName) + */ + public void SetTargetNames( + IEnumerable names) + { + targetNames = ExtractGeneralNames(names); + } + + /** + * Gets the target names. The collection consists of Lists + * made up of an Integer in the first entry and a DER encoded + * byte array or a String in the second entry. + *

    The returned collection is immutable.

    + * + * @return The collection of target names + * @see #setTargetNames(Collection) + */ + public IEnumerable GetTargetNames() + { + return new EnumerableProxy(targetNames); + } + + /** + * Adds a target group criterion for the attribute certificate to the target + * information extension criteria. The X509AttributeCertificate + * must contain at least one of the specified target groups. + *

    + * Each attribute certificate may contain a target information extension + * limiting the servers where this attribute certificate can be used. If + * this extension is not present, the attribute certificate is not targeted + * and may be accepted by any server. + *

    + * + * @param group The group as GeneralName form (not null) + */ + public void AddTargetGroup( + GeneralName group) + { + targetGroups.Add(group); + } + + /** + * Adds a target group criterion for the attribute certificate to the target + * information extension criteria. The X509AttributeCertificate + * must contain at least one of the specified target groups. + *

    + * Each attribute certificate may contain a target information extension + * limiting the servers where this attribute certificate can be used. If + * this extension is not present, the attribute certificate is not targeted + * and may be accepted by any server. + *

    + * + * @param name a byte array containing the group in ASN.1 DER encoded form of a GeneralName + * @throws IOException if a parsing error occurs. + */ + public void AddTargetGroup( + byte[] name) + { + AddTargetGroup(GeneralName.GetInstance(Asn1Object.FromByteArray(name))); + } + + /** + * Adds a collection with target groups criteria. If null is + * given any will do. + *

    + * The collection consists of GeneralName objects or byte[] + * representing DER encoded GeneralNames. + *

    + * + * @param names A collection of target groups. + * @throws IOException if a parsing error occurs. + * @see #AddTargetGroup(byte[]) + * @see #AddTargetGroup(GeneralName) + */ + public void SetTargetGroups( + IEnumerable names) + { + targetGroups = ExtractGeneralNames(names); + } + + /** + * Gets the target groups. The collection consists of Lists + * made up of an Integer in the first entry and a DER encoded + * byte array or a String in the second entry. + *

    The returned collection is immutable.

    + * + * @return The collection of target groups. + * @see #setTargetGroups(Collection) + */ + public IEnumerable GetTargetGroups() + { + return new EnumerableProxy(targetGroups); + } + + private ISet ExtractGeneralNames( + IEnumerable names) + { + ISet result = new HashSet(); + + if (names != null) + { + foreach (object o in names) + { + if (o is GeneralName) + { + result.Add(o); + } + else + { + result.Add(GeneralName.GetInstance(Asn1Object.FromByteArray((byte[]) o))); + } + } + } + + return result; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/X509AttrCertStoreSelector.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/X509AttrCertStoreSelector.cs.meta new file mode 100644 index 0000000..40fdc5a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/X509AttrCertStoreSelector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ddfdc5cf01c6cd7409ac065553b022a3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/X509CertPairStoreSelector.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/X509CertPairStoreSelector.cs new file mode 100644 index 0000000..2796971 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/X509CertPairStoreSelector.cs @@ -0,0 +1,92 @@ +using System; + +namespace Org.BouncyCastle.X509.Store +{ + /// + /// This class is an IX509Selector implementation to select + /// certificate pairs, which are e.g. used for cross certificates. The set of + /// criteria is given from two X509CertStoreSelector objects, + /// each of which, if present, must match the respective component of a pair. + /// + public class X509CertPairStoreSelector + : IX509Selector + { + private static X509CertStoreSelector CloneSelector( + X509CertStoreSelector s) + { + return s == null ? null : (X509CertStoreSelector) s.Clone(); + } + + private X509CertificatePair certPair; + private X509CertStoreSelector forwardSelector; + private X509CertStoreSelector reverseSelector; + + public X509CertPairStoreSelector() + { + } + + private X509CertPairStoreSelector( + X509CertPairStoreSelector o) + { + this.certPair = o.CertPair; + this.forwardSelector = o.ForwardSelector; + this.reverseSelector = o.ReverseSelector; + } + + /// The certificate pair which is used for testing on equality. + public X509CertificatePair CertPair + { + get { return certPair; } + set { this.certPair = value; } + } + + /// The certificate selector for the forward part. + public X509CertStoreSelector ForwardSelector + { + get { return CloneSelector(forwardSelector); } + set { this.forwardSelector = CloneSelector(value); } + } + + /// The certificate selector for the reverse part. + public X509CertStoreSelector ReverseSelector + { + get { return CloneSelector(reverseSelector); } + set { this.reverseSelector = CloneSelector(value); } + } + + /// + /// Decides if the given certificate pair should be selected. If + /// obj is not a X509CertificatePair, this method + /// returns false. + /// + /// The X509CertificatePair to be tested. + /// true if the object matches this selector. + public bool Match( + object obj) + { + if (obj == null) + throw new ArgumentNullException("obj"); + + X509CertificatePair pair = obj as X509CertificatePair; + + if (pair == null) + return false; + + if (certPair != null && !certPair.Equals(pair)) + return false; + + if (forwardSelector != null && !forwardSelector.Match(pair.Forward)) + return false; + + if (reverseSelector != null && !reverseSelector.Match(pair.Reverse)) + return false; + + return true; + } + + public object Clone() + { + return new X509CertPairStoreSelector(this); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/X509CertPairStoreSelector.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/X509CertPairStoreSelector.cs.meta new file mode 100644 index 0000000..e16a353 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/X509CertPairStoreSelector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 908eb17fae46a7e46beb2190ac96ab78 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/X509CertStoreSelector.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/X509CertStoreSelector.cs new file mode 100644 index 0000000..f92a4ac --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/X509CertStoreSelector.cs @@ -0,0 +1,346 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Collections; +using Org.BouncyCastle.Utilities.Date; +using Org.BouncyCastle.X509.Extension; + +namespace Org.BouncyCastle.X509.Store +{ + public class X509CertStoreSelector + : IX509Selector + { + // TODO Missing criteria? + + private byte[] authorityKeyIdentifier; + private int basicConstraints = -1; + private X509Certificate certificate; + private DateTimeObject certificateValid; + private ISet extendedKeyUsage; + private bool ignoreX509NameOrdering; + private X509Name issuer; + private bool[] keyUsage; + private ISet policy; + private DateTimeObject privateKeyValid; + private BigInteger serialNumber; + private X509Name subject; + private byte[] subjectKeyIdentifier; + private SubjectPublicKeyInfo subjectPublicKey; + private DerObjectIdentifier subjectPublicKeyAlgID; + + public X509CertStoreSelector() + { + } + + public X509CertStoreSelector( + X509CertStoreSelector o) + { + this.authorityKeyIdentifier = o.AuthorityKeyIdentifier; + this.basicConstraints = o.BasicConstraints; + this.certificate = o.Certificate; + this.certificateValid = o.CertificateValid; + this.extendedKeyUsage = o.ExtendedKeyUsage; + this.ignoreX509NameOrdering = o.IgnoreX509NameOrdering; + this.issuer = o.Issuer; + this.keyUsage = o.KeyUsage; + this.policy = o.Policy; + this.privateKeyValid = o.PrivateKeyValid; + this.serialNumber = o.SerialNumber; + this.subject = o.Subject; + this.subjectKeyIdentifier = o.SubjectKeyIdentifier; + this.subjectPublicKey = o.SubjectPublicKey; + this.subjectPublicKeyAlgID = o.SubjectPublicKeyAlgID; + } + + public virtual object Clone() + { + return new X509CertStoreSelector(this); + } + + public byte[] AuthorityKeyIdentifier + { + get { return Arrays.Clone(authorityKeyIdentifier); } + set { authorityKeyIdentifier = Arrays.Clone(value); } + } + + public int BasicConstraints + { + get { return basicConstraints; } + set + { + if (value < -2) + throw new ArgumentException("value can't be less than -2", "value"); + + basicConstraints = value; + } + } + + public X509Certificate Certificate + { + get { return certificate; } + set { this.certificate = value; } + } + + public DateTimeObject CertificateValid + { + get { return certificateValid; } + set { certificateValid = value; } + } + + public ISet ExtendedKeyUsage + { + get { return CopySet(extendedKeyUsage); } + set { extendedKeyUsage = CopySet(value); } + } + + public bool IgnoreX509NameOrdering + { + get { return ignoreX509NameOrdering; } + set { this.ignoreX509NameOrdering = value; } + } + + public X509Name Issuer + { + get { return issuer; } + set { issuer = value; } + } + + [Obsolete("Avoid working with X509Name objects in string form")] + public string IssuerAsString + { + get { return issuer != null ? issuer.ToString() : null; } + } + + public bool[] KeyUsage + { + get { return CopyBoolArray(keyUsage); } + set { keyUsage = CopyBoolArray(value); } + } + + /// + /// An ISet of DerObjectIdentifier objects. + /// + public ISet Policy + { + get { return CopySet(policy); } + set { policy = CopySet(value); } + } + + public DateTimeObject PrivateKeyValid + { + get { return privateKeyValid; } + set { privateKeyValid = value; } + } + + public BigInteger SerialNumber + { + get { return serialNumber; } + set { serialNumber = value; } + } + + public X509Name Subject + { + get { return subject; } + set { subject = value; } + } + + [Obsolete("Avoid working with X509Name objects in string form")] + public string SubjectAsString + { + get { return subject != null ? subject.ToString() : null; } + } + + public byte[] SubjectKeyIdentifier + { + get { return Arrays.Clone(subjectKeyIdentifier); } + set { subjectKeyIdentifier = Arrays.Clone(value); } + } + + public SubjectPublicKeyInfo SubjectPublicKey + { + get { return subjectPublicKey; } + set { subjectPublicKey = value; } + } + + public DerObjectIdentifier SubjectPublicKeyAlgID + { + get { return subjectPublicKeyAlgID; } + set { subjectPublicKeyAlgID = value; } + } + + public virtual bool Match( + object obj) + { + X509Certificate c = obj as X509Certificate; + + if (c == null) + return false; + + if (!MatchExtension(authorityKeyIdentifier, c, X509Extensions.AuthorityKeyIdentifier)) + return false; + + if (basicConstraints != -1) + { + int bc = c.GetBasicConstraints(); + + if (basicConstraints == -2) + { + if (bc != -1) + return false; + } + else + { + if (bc < basicConstraints) + return false; + } + } + + if (certificate != null && !certificate.Equals(c)) + return false; + + if (certificateValid != null && !c.IsValid(certificateValid.Value)) + return false; + + if (extendedKeyUsage != null) + { + IList eku = c.GetExtendedKeyUsage(); + + // Note: if no extended key usage set, all key purposes are implicitly allowed + + if (eku != null) + { + foreach (DerObjectIdentifier oid in extendedKeyUsage) + { + if (!eku.Contains(oid.Id)) + return false; + } + } + } + + if (issuer != null && !issuer.Equivalent(c.IssuerDN, !ignoreX509NameOrdering)) + return false; + + if (keyUsage != null) + { + bool[] ku = c.GetKeyUsage(); + + // Note: if no key usage set, all key purposes are implicitly allowed + + if (ku != null) + { + for (int i = 0; i < 9; ++i) + { + if (keyUsage[i] && !ku[i]) + return false; + } + } + } + + if (policy != null) + { + Asn1OctetString extVal = c.GetExtensionValue(X509Extensions.CertificatePolicies); + if (extVal == null) + return false; + + Asn1Sequence certPolicies = Asn1Sequence.GetInstance( + X509ExtensionUtilities.FromExtensionValue(extVal)); + + if (policy.Count < 1 && certPolicies.Count < 1) + return false; + + bool found = false; + foreach (PolicyInformation pi in certPolicies) + { + if (policy.Contains(pi.PolicyIdentifier)) + { + found = true; + break; + } + } + + if (!found) + return false; + } + + if (privateKeyValid != null) + { + Asn1OctetString extVal = c.GetExtensionValue(X509Extensions.PrivateKeyUsagePeriod); + if (extVal == null) + return false; + + PrivateKeyUsagePeriod pkup = PrivateKeyUsagePeriod.GetInstance( + X509ExtensionUtilities.FromExtensionValue(extVal)); + + DateTime dt = privateKeyValid.Value; + DateTime notAfter = pkup.NotAfter.ToDateTime(); + DateTime notBefore = pkup.NotBefore.ToDateTime(); + + if (dt.CompareTo(notAfter) > 0 || dt.CompareTo(notBefore) < 0) + return false; + } + + if (serialNumber != null && !serialNumber.Equals(c.SerialNumber)) + return false; + + if (subject != null && !subject.Equivalent(c.SubjectDN, !ignoreX509NameOrdering)) + return false; + + if (!MatchExtension(subjectKeyIdentifier, c, X509Extensions.SubjectKeyIdentifier)) + return false; + + if (subjectPublicKey != null && !subjectPublicKey.Equals(GetSubjectPublicKey(c))) + return false; + + if (subjectPublicKeyAlgID != null + && !subjectPublicKeyAlgID.Equals(GetSubjectPublicKey(c).AlgorithmID)) + return false; + + return true; + } + + internal static bool IssuersMatch( + X509Name a, + X509Name b) + { + return a == null ? b == null : a.Equivalent(b, true); + } + + private static bool[] CopyBoolArray( + bool[] b) + { + return b == null ? null : (bool[]) b.Clone(); + } + + private static ISet CopySet( + ISet s) + { + return s == null ? null : new HashSet(s); + } + + private static SubjectPublicKeyInfo GetSubjectPublicKey( + X509Certificate c) + { + return SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(c.GetPublicKey()); + } + + private static bool MatchExtension( + byte[] b, + X509Certificate c, + DerObjectIdentifier oid) + { + if (b == null) + return true; + + Asn1OctetString extVal = c.GetExtensionValue(oid); + + if (extVal == null) + return false; + + return Arrays.AreEqual(b, extVal.GetOctets()); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/X509CertStoreSelector.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/X509CertStoreSelector.cs.meta new file mode 100644 index 0000000..f9f4b67 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/X509CertStoreSelector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 85e771ab142a38c49a1d3151d1bc5755 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/X509CollectionStore.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/X509CollectionStore.cs new file mode 100644 index 0000000..9217314 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/X509CollectionStore.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.X509.Store +{ + /** + * A simple collection backed store. + */ + internal class X509CollectionStore + : IX509Store + { + private ICollection _local; + + /** + * Basic constructor. + * + * @param collection - initial contents for the store, this is copied. + */ + internal X509CollectionStore( + ICollection collection) + { + _local = Platform.CreateArrayList(collection); + } + + /** + * Return the matches in the collection for the passed in selector. + * + * @param selector the selector to match against. + * @return a possibly empty collection of matching objects. + */ + public ICollection GetMatches( + IX509Selector selector) + { + if (selector == null) + { + return Platform.CreateArrayList(_local); + } + + IList result = Platform.CreateArrayList(); + foreach (object obj in _local) + { + if (selector.Match(obj)) + result.Add(obj); + } + + return result; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/X509CollectionStore.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/X509CollectionStore.cs.meta new file mode 100644 index 0000000..8c223cb --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/X509CollectionStore.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 803b791ee775d734ba55784bbd9e7015 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/X509CollectionStoreParameters.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/X509CollectionStoreParameters.cs new file mode 100644 index 0000000..7fd047a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/X509CollectionStoreParameters.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections; +using System.Text; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.X509.Store +{ + /// This class contains a collection for collection based X509Stores. + public class X509CollectionStoreParameters + : IX509StoreParameters + { + private readonly IList collection; + + /// + /// Constructor. + ///

    + /// The collection is copied. + ///

    + ///
    + /// The collection containing X.509 object types. + /// If collection is null. + public X509CollectionStoreParameters( + ICollection collection) + { + if (collection == null) + throw new ArgumentNullException("collection"); + + this.collection = Platform.CreateArrayList(collection); + } + + // TODO Do we need to be able to Clone() these, and should it really be shallow? +// /** +// * Returns a shallow clone. The returned contents are not copied, so adding +// * or removing objects will effect this. +// * +// * @return a shallow clone. +// */ +// public object Clone() +// { +// return new X509CollectionStoreParameters(collection); +// } + + /// Returns a copy of the ICollection. + public ICollection GetCollection() + { + return Platform.CreateArrayList(collection); + } + + /// Returns a formatted string describing the parameters. + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + sb.Append("X509CollectionStoreParameters: [\n"); + sb.Append(" collection: " + collection + "\n"); + sb.Append("]"); + return sb.ToString(); + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/X509CollectionStoreParameters.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/X509CollectionStoreParameters.cs.meta new file mode 100644 index 0000000..cc52b4a --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/X509CollectionStoreParameters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c4167d974d3e0584694c75cc677fefad +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/X509CrlStoreSelector.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/X509CrlStoreSelector.cs new file mode 100644 index 0000000..c4b0062 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/X509CrlStoreSelector.cs @@ -0,0 +1,283 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Date; +using Org.BouncyCastle.X509; +using Org.BouncyCastle.X509.Extension; + +namespace Org.BouncyCastle.X509.Store +{ + public class X509CrlStoreSelector + : IX509Selector + { + // TODO Missing criteria? + + private X509Certificate certificateChecking; + private DateTimeObject dateAndTime; + private ICollection issuers; + private BigInteger maxCrlNumber; + private BigInteger minCrlNumber; + + private IX509AttributeCertificate attrCertChecking; + private bool completeCrlEnabled; + private bool deltaCrlIndicatorEnabled; + private byte[] issuingDistributionPoint; + private bool issuingDistributionPointEnabled; + private BigInteger maxBaseCrlNumber; + + public X509CrlStoreSelector() + { + } + + public X509CrlStoreSelector( + X509CrlStoreSelector o) + { + this.certificateChecking = o.CertificateChecking; + this.dateAndTime = o.DateAndTime; + this.issuers = o.Issuers; + this.maxCrlNumber = o.MaxCrlNumber; + this.minCrlNumber = o.MinCrlNumber; + + this.deltaCrlIndicatorEnabled = o.DeltaCrlIndicatorEnabled; + this.completeCrlEnabled = o.CompleteCrlEnabled; + this.maxBaseCrlNumber = o.MaxBaseCrlNumber; + this.attrCertChecking = o.AttrCertChecking; + this.issuingDistributionPointEnabled = o.IssuingDistributionPointEnabled; + this.issuingDistributionPoint = o.IssuingDistributionPoint; + } + + public virtual object Clone() + { + return new X509CrlStoreSelector(this); + } + + public X509Certificate CertificateChecking + { + get { return certificateChecking; } + set { certificateChecking = value; } + } + + public DateTimeObject DateAndTime + { + get { return dateAndTime; } + set { dateAndTime = value; } + } + + /// + /// An ICollection of X509Name objects + /// + public ICollection Issuers + { + get { return Platform.CreateArrayList(issuers); } + set { issuers = Platform.CreateArrayList(value); } + } + + public BigInteger MaxCrlNumber + { + get { return maxCrlNumber; } + set { maxCrlNumber = value; } + } + + public BigInteger MinCrlNumber + { + get { return minCrlNumber; } + set { minCrlNumber = value; } + } + + /** + * The attribute certificate being checked. This is not a criterion. + * Rather, it is optional information that may help a {@link X509Store} find + * CRLs that would be relevant when checking revocation for the specified + * attribute certificate. If null is specified, then no such + * optional information is provided. + * + * @param attrCert the IX509AttributeCertificate being checked (or + * null) + * @see #getAttrCertificateChecking() + */ + public IX509AttributeCertificate AttrCertChecking + { + get { return attrCertChecking; } + set { this.attrCertChecking = value; } + } + + /** + * If true only complete CRLs are returned. Defaults to + * false. + * + * @return true if only complete CRLs are returned. + */ + public bool CompleteCrlEnabled + { + get { return completeCrlEnabled; } + set { this.completeCrlEnabled = value; } + } + + /** + * Returns if this selector must match CRLs with the delta CRL indicator + * extension set. Defaults to false. + * + * @return Returns true if only CRLs with the delta CRL + * indicator extension are selected. + */ + public bool DeltaCrlIndicatorEnabled + { + get { return deltaCrlIndicatorEnabled; } + set { this.deltaCrlIndicatorEnabled = value; } + } + + /** + * The issuing distribution point. + *

    + * The issuing distribution point extension is a CRL extension which + * identifies the scope and the distribution point of a CRL. The scope + * contains among others information about revocation reasons contained in + * the CRL. Delta CRLs and complete CRLs must have matching issuing + * distribution points.

    + *

    + * The byte array is cloned to protect against subsequent modifications.

    + *

    + * You must also enable or disable this criteria with + * {@link #setIssuingDistributionPointEnabled(bool)}.

    + * + * @param issuingDistributionPoint The issuing distribution point to set. + * This is the DER encoded OCTET STRING extension value. + * @see #getIssuingDistributionPoint() + */ + public byte[] IssuingDistributionPoint + { + get { return Arrays.Clone(issuingDistributionPoint); } + set { this.issuingDistributionPoint = Arrays.Clone(value); } + } + + /** + * Whether the issuing distribution point criteria should be applied. + * Defaults to false. + *

    + * You may also set the issuing distribution point criteria if not a missing + * issuing distribution point should be assumed.

    + * + * @return Returns if the issuing distribution point check is enabled. + */ + public bool IssuingDistributionPointEnabled + { + get { return issuingDistributionPointEnabled; } + set { this.issuingDistributionPointEnabled = value; } + } + + /** + * The maximum base CRL number. Defaults to null. + * + * @return Returns the maximum base CRL number. + * @see #setMaxBaseCRLNumber(BigInteger) + */ + public BigInteger MaxBaseCrlNumber + { + get { return maxBaseCrlNumber; } + set { this.maxBaseCrlNumber = value; } + } + + public virtual bool Match( + object obj) + { + X509Crl c = obj as X509Crl; + + if (c == null) + return false; + + if (dateAndTime != null) + { + DateTime dt = dateAndTime.Value; + DateTime tu = c.ThisUpdate; + DateTimeObject nu = c.NextUpdate; + + if (dt.CompareTo(tu) < 0 || nu == null || dt.CompareTo(nu.Value) >= 0) + return false; + } + + if (issuers != null) + { + X509Name i = c.IssuerDN; + + bool found = false; + + foreach (X509Name issuer in issuers) + { + if (issuer.Equivalent(i, true)) + { + found = true; + break; + } + } + + if (!found) + return false; + } + + if (maxCrlNumber != null || minCrlNumber != null) + { + Asn1OctetString extVal = c.GetExtensionValue(X509Extensions.CrlNumber); + if (extVal == null) + return false; + + BigInteger cn = CrlNumber.GetInstance( + X509ExtensionUtilities.FromExtensionValue(extVal)).PositiveValue; + + if (maxCrlNumber != null && cn.CompareTo(maxCrlNumber) > 0) + return false; + + if (minCrlNumber != null && cn.CompareTo(minCrlNumber) < 0) + return false; + } + + DerInteger dci = null; + try + { + Asn1OctetString bytes = c.GetExtensionValue(X509Extensions.DeltaCrlIndicator); + if (bytes != null) + { + dci = DerInteger.GetInstance(X509ExtensionUtilities.FromExtensionValue(bytes)); + } + } + catch (Exception) + { + return false; + } + + if (dci == null) + { + if (DeltaCrlIndicatorEnabled) + return false; + } + else + { + if (CompleteCrlEnabled) + return false; + + if (maxBaseCrlNumber != null && dci.PositiveValue.CompareTo(maxBaseCrlNumber) > 0) + return false; + } + + if (issuingDistributionPointEnabled) + { + Asn1OctetString idp = c.GetExtensionValue(X509Extensions.IssuingDistributionPoint); + if (issuingDistributionPoint == null) + { + if (idp != null) + return false; + } + else + { + if (!Arrays.AreEqual(idp.GetOctets(), issuingDistributionPoint)) + return false; + } + } + + return true; + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/X509CrlStoreSelector.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/X509CrlStoreSelector.cs.meta new file mode 100644 index 0000000..7d845e8 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/X509CrlStoreSelector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 942ff6fee429ef24eb3830bd80e5e84c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/X509StoreException.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/X509StoreException.cs new file mode 100644 index 0000000..ea7e51e --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/X509StoreException.cs @@ -0,0 +1,28 @@ +using System; + +namespace Org.BouncyCastle.X509.Store +{ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE) + [Serializable] +#endif + public class X509StoreException + : Exception + { + public X509StoreException() + { + } + + public X509StoreException( + string message) + : base(message) + { + } + + public X509StoreException( + string message, + Exception e) + : base(message, e) + { + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/X509StoreException.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/X509StoreException.cs.meta new file mode 100644 index 0000000..b15cb67 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/X509StoreException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 500480a462952224cb0c9a39ba705b07 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/X509StoreFactory.cs b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/X509StoreFactory.cs new file mode 100644 index 0000000..96f22be --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/X509StoreFactory.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.X509.Store +{ + public sealed class X509StoreFactory + { + private X509StoreFactory() + { + } + + public static IX509Store Create( + string type, + IX509StoreParameters parameters) + { + if (type == null) + throw new ArgumentNullException("type"); + + string[] parts = Platform.ToUpperInvariant(type).Split('/'); + + if (parts.Length < 2) + throw new ArgumentException("type"); + + if (parts[1] != "COLLECTION") + throw new NoSuchStoreException("X.509 store type '" + type + "' not available."); + + X509CollectionStoreParameters p = (X509CollectionStoreParameters) parameters; + ICollection coll = p.GetCollection(); + + switch (parts[0]) + { + case "ATTRIBUTECERTIFICATE": + checkCorrectType(coll, typeof(IX509AttributeCertificate)); + break; + case "CERTIFICATE": + checkCorrectType(coll, typeof(X509Certificate)); + break; + case "CERTIFICATEPAIR": + checkCorrectType(coll, typeof(X509CertificatePair)); + break; + case "CRL": + checkCorrectType(coll, typeof(X509Crl)); + break; + default: + throw new NoSuchStoreException("X.509 store type '" + type + "' not available."); + } + + return new X509CollectionStore(coll); + } + + private static void checkCorrectType(ICollection coll, Type t) + { + foreach (object o in coll) + { + if (!t.IsInstanceOfType(o)) + throw new InvalidCastException("Can't cast object to type: " + t.FullName); + } + } + } +} diff --git a/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/X509StoreFactory.cs.meta b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/X509StoreFactory.cs.meta new file mode 100644 index 0000000..389c108 --- /dev/null +++ b/Packages/bc-csharp-pcl-v1.9.0/bc-csharp-pcl-v1.9.0/src/x509/store/X509StoreFactory.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c79b3743f5f53b44fb7ec984ab84ba92 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/README.md b/README.md index 19cb093..1462b08 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,18 @@ +--- +Custom Fork which replaces RestSharp package with UnityWebRequests to make it Unity-oriented and compatible with all Unity platforms, specially WebGL. +RestSharp does not work in WebGL. +Also replaces Task with UniTask as Task/Threading also is not WebGL compatible + +``` +Requires - https://github.com/Cysharp/UniTask +Requires (custom fork of UnityWebRequests) - https://github.com/GamerzDan/unity-web-requests + +Need to add AsmDef references of both above packages to KineticSDK.asmdef +Tested in Unity 2021.3 with KinSDK rc12 in WebGL, PC, Editor +``` +--- + + --- title: Unity SDK layout: layout-index diff --git a/Runtime/1.0.0-rc.2.meta b/Runtime/1.0.0-rc.2.meta new file mode 100644 index 0000000..aa4cce8 --- /dev/null +++ b/Runtime/1.0.0-rc.2.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a075ee18980e0a7478c7102f891ef4f8 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Helpers.meta b/Runtime/Helpers.meta index 975dca2..b890f52 100644 --- a/Runtime/Helpers.meta +++ b/Runtime/Helpers.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 5df78d79a4e4b4b839927e2d70bdd44b +guid: 474db335df9702c49a2c825691123b8b folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Runtime/Kinetic.Sdk.asmdef b/Runtime/Kinetic.Sdk.asmdef index 7734470..e689dae 100644 --- a/Runtime/Kinetic.Sdk.asmdef +++ b/Runtime/Kinetic.Sdk.asmdef @@ -1,6 +1,13 @@ { "name": "Kinetic.Sdk", - "references": [], + "rootNamespace": "", + "references": [ + "GUID:f51ebe6a0ceec4240a699833d6309b23", + "GUID:ffcb8f9b55bf64a1183268740a6b8af2", + "GUID:3faeb4f0d920c5041a297aa38b21a5fe", + "GUID:b3e39678a8864ed408212bd7910fd844", + "GUID:e81c8beff9ece1e43848e56b1b271dea" + ], "includePlatforms": [], "excludePlatforms": [], "allowUnsafeCode": false, diff --git a/Runtime/Kinetic/Api/AccountApi.cs b/Runtime/Kinetic/Api/AccountApi.cs index 216b68f..4d78f80 100644 --- a/Runtime/Kinetic/Api/AccountApi.cs +++ b/Runtime/Kinetic/Api/AccountApi.cs @@ -1,12 +1,15 @@ using System; using System.Collections.Generic; -using RestSharp; +using JeffreyLanters.WebRequests; +using JeffreyLanters.WebRequests.Core; +using Cysharp.Threading.Tasks; using Client; using Model; #pragma warning disable 0472 // The result of the expression is always the same since a value of this type is never equal to 'null' using Commitment = System.String; +using System.Linq; namespace Api { @@ -20,13 +23,13 @@ public interface IAccountApi /// /// /// Transaction - Transaction CloseAccount (CloseAccountRequest closeAccountRequest); + UniTask CloseAccount (CloseAccountRequest closeAccountRequest); /// /// /// /// /// Transaction - Transaction CreateAccount (CreateAccountRequest createAccountRequest); + UniTask CreateAccount (CreateAccountRequest createAccountRequest); /// /// /// @@ -35,7 +38,7 @@ public interface IAccountApi /// /// /// AccountInfo - AccountInfo GetAccountInfo (string environment, int index, string accountId, Commitment commitment); + UniTask GetAccountInfo (string environment, int index, string accountId, Commitment commitment); /// /// /// @@ -44,7 +47,7 @@ public interface IAccountApi /// /// /// BalanceResponse - BalanceResponse GetBalance (string environment, int index, string accountId, Commitment commitment); + UniTask GetBalance (string environment, int index, string accountId, Commitment commitment); /// /// /// @@ -54,7 +57,7 @@ public interface IAccountApi /// /// /// List<HistoryResponse> - List GetHistory (string environment, int index, string accountId, string mint, Commitment commitment); + UniTask> GetHistory (string environment, int index, string accountId, string mint, Commitment commitment); /// /// /// @@ -64,7 +67,7 @@ public interface IAccountApi /// /// /// List<string> - List GetTokenAccounts (string environment, int index, string accountId, string mint, Commitment commitment); + UniTask> GetTokenAccounts (string environment, int index, string accountId, string mint, Commitment commitment); } /// @@ -125,7 +128,7 @@ public String GetBasePath(String basePath) /// /// /// Transaction - public Transaction CloseAccount (CloseAccountRequest closeAccountRequest) + public async UniTask CloseAccount (CloseAccountRequest closeAccountRequest) { // verify the required parameter 'closeAccountRequest' is set @@ -138,7 +141,7 @@ public Transaction CloseAccount (CloseAccountRequest closeAccountRequest) var queryParams = new Dictionary(); var headerParams = new Dictionary(); var formParams = new Dictionary(); - var fileParams = new Dictionary(); + var fileParams = new Dictionary(); String postBody = null; postBody = ApiClient.Serialize(closeAccountRequest); // http body (model) parameter @@ -147,14 +150,14 @@ public Transaction CloseAccount (CloseAccountRequest closeAccountRequest) String[] authSettings = new String[] { }; // make the HTTP request - IRestResponse response = (IRestResponse) ApiClient.CallApi(path, Method.POST, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + WebRequestResponse response = await ApiClient.CallApi(path, RequestMethod.Post, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) throw new ApiException ((int)response.StatusCode, "Error calling CloseAccount: " + response.Content, response.Content); else if (((int)response.StatusCode) == 0) throw new ApiException ((int)response.StatusCode, "Error calling CloseAccount: " + response.ErrorMessage, response.ErrorMessage); - return (Transaction) ApiClient.Deserialize(response.Content, typeof(Transaction), response.Headers); + return (Transaction) ApiClient.Deserialize(response.Content, typeof(Transaction), response.headers.Values.ToList()); } /// @@ -162,7 +165,7 @@ public Transaction CloseAccount (CloseAccountRequest closeAccountRequest) /// /// /// Transaction - public Transaction CreateAccount (CreateAccountRequest createAccountRequest) + public async UniTask CreateAccount (CreateAccountRequest createAccountRequest) { // verify the required parameter 'createAccountRequest' is set @@ -175,7 +178,7 @@ public Transaction CreateAccount (CreateAccountRequest createAccountRequest) var queryParams = new Dictionary(); var headerParams = new Dictionary(); var formParams = new Dictionary(); - var fileParams = new Dictionary(); + var fileParams = new Dictionary(); String postBody = null; postBody = ApiClient.Serialize(createAccountRequest); // http body (model) parameter @@ -184,14 +187,14 @@ public Transaction CreateAccount (CreateAccountRequest createAccountRequest) String[] authSettings = new String[] { }; // make the HTTP request - IRestResponse response = (IRestResponse) ApiClient.CallApi(path, Method.POST, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + WebRequestResponse response = await ApiClient.CallApi(path, RequestMethod.Post, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) throw new ApiException ((int)response.StatusCode, "Error calling CreateAccount: " + response.Content, response.Content); else if (((int)response.StatusCode) == 0) throw new ApiException ((int)response.StatusCode, "Error calling CreateAccount: " + response.ErrorMessage, response.ErrorMessage); - return (Transaction) ApiClient.Deserialize(response.Content, typeof(Transaction), response.Headers); + return (Transaction) ApiClient.Deserialize(response.Content, typeof(Transaction), response.headers.Values.ToList()); } /// @@ -202,7 +205,7 @@ public Transaction CreateAccount (CreateAccountRequest createAccountRequest) /// /// /// AccountInfo - public AccountInfo GetAccountInfo (string environment, int index, string accountId, Commitment commitment) + public async UniTask GetAccountInfo (string environment, int index, string accountId, Commitment commitment) { // verify the required parameter 'environment' is set @@ -227,7 +230,7 @@ public AccountInfo GetAccountInfo (string environment, int index, string account var queryParams = new Dictionary(); var headerParams = new Dictionary(); var formParams = new Dictionary(); - var fileParams = new Dictionary(); + var fileParams = new Dictionary(); String postBody = null; if (commitment != null) queryParams.Add("commitment", ApiClient.ParameterToString(commitment)); // query parameter @@ -236,14 +239,14 @@ public AccountInfo GetAccountInfo (string environment, int index, string account String[] authSettings = new String[] { }; // make the HTTP request - IRestResponse response = (IRestResponse) ApiClient.CallApi(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + WebRequestResponse response = await ApiClient.CallApi(path, RequestMethod.Get, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) throw new ApiException ((int)response.StatusCode, "Error calling GetAccountInfo: " + response.Content, response.Content); else if (((int)response.StatusCode) == 0) throw new ApiException ((int)response.StatusCode, "Error calling GetAccountInfo: " + response.ErrorMessage, response.ErrorMessage); - return (AccountInfo) ApiClient.Deserialize(response.Content, typeof(AccountInfo), response.Headers); + return (AccountInfo) ApiClient.Deserialize(response.Content, typeof(AccountInfo), response.headers.Values.ToList()); } /// @@ -254,7 +257,7 @@ public AccountInfo GetAccountInfo (string environment, int index, string account /// /// /// BalanceResponse - public BalanceResponse GetBalance (string environment, int index, string accountId, Commitment commitment) + public async UniTask GetBalance (string environment, int index, string accountId, Commitment commitment) { // verify the required parameter 'environment' is set @@ -279,7 +282,7 @@ public BalanceResponse GetBalance (string environment, int index, string account var queryParams = new Dictionary(); var headerParams = new Dictionary(); var formParams = new Dictionary(); - var fileParams = new Dictionary(); + var fileParams = new Dictionary(); String postBody = null; if (commitment != null) queryParams.Add("commitment", ApiClient.ParameterToString(commitment)); // query parameter @@ -288,14 +291,14 @@ public BalanceResponse GetBalance (string environment, int index, string account String[] authSettings = new String[] { }; // make the HTTP request - IRestResponse response = (IRestResponse) ApiClient.CallApi(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + WebRequestResponse response = await ApiClient.CallApi(path, RequestMethod.Get, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) throw new ApiException ((int)response.StatusCode, "Error calling GetBalance: " + response.Content, response.Content); else if (((int)response.StatusCode) == 0) throw new ApiException ((int)response.StatusCode, "Error calling GetBalance: " + response.ErrorMessage, response.ErrorMessage); - return (BalanceResponse) ApiClient.Deserialize(response.Content, typeof(BalanceResponse), response.Headers); + return (BalanceResponse) ApiClient.Deserialize(response.Content, typeof(BalanceResponse), response.headers.Values.ToList()); } /// @@ -307,7 +310,7 @@ public BalanceResponse GetBalance (string environment, int index, string account /// /// /// List<HistoryResponse> - public List GetHistory (string environment, int index, string accountId, string mint, Commitment commitment) + public async UniTask> GetHistory (string environment, int index, string accountId, string mint, Commitment commitment) { // verify the required parameter 'environment' is set @@ -336,7 +339,7 @@ public List GetHistory (string environment, int index, string a var queryParams = new Dictionary(); var headerParams = new Dictionary(); var formParams = new Dictionary(); - var fileParams = new Dictionary(); + var fileParams = new Dictionary(); String postBody = null; if (commitment != null) queryParams.Add("commitment", ApiClient.ParameterToString(commitment)); // query parameter @@ -345,14 +348,14 @@ public List GetHistory (string environment, int index, string a String[] authSettings = new String[] { }; // make the HTTP request - IRestResponse response = (IRestResponse) ApiClient.CallApi(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + WebRequestResponse response = await ApiClient.CallApi(path, RequestMethod.Get, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) throw new ApiException ((int)response.StatusCode, "Error calling GetHistory: " + response.Content, response.Content); else if (((int)response.StatusCode) == 0) throw new ApiException ((int)response.StatusCode, "Error calling GetHistory: " + response.ErrorMessage, response.ErrorMessage); - return (List) ApiClient.Deserialize(response.Content, typeof(List), response.Headers); + return (List) ApiClient.Deserialize(response.Content, typeof(List), response.headers.Values.ToList()); } /// @@ -364,7 +367,7 @@ public List GetHistory (string environment, int index, string a /// /// /// List<string> - public List GetTokenAccounts (string environment, int index, string accountId, string mint, Commitment commitment) + public async UniTask> GetTokenAccounts (string environment, int index, string accountId, string mint, Commitment commitment) { // verify the required parameter 'environment' is set @@ -393,7 +396,7 @@ public List GetTokenAccounts (string environment, int index, string acco var queryParams = new Dictionary(); var headerParams = new Dictionary(); var formParams = new Dictionary(); - var fileParams = new Dictionary(); + var fileParams = new Dictionary(); String postBody = null; if (commitment != null) queryParams.Add("commitment", ApiClient.ParameterToString(commitment)); // query parameter @@ -402,14 +405,14 @@ public List GetTokenAccounts (string environment, int index, string acco String[] authSettings = new String[] { }; // make the HTTP request - IRestResponse response = (IRestResponse) ApiClient.CallApi(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + WebRequestResponse response = await ApiClient.CallApi(path, RequestMethod.Get, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) throw new ApiException ((int)response.StatusCode, "Error calling GetTokenAccounts: " + response.Content, response.Content); else if (((int)response.StatusCode) == 0) throw new ApiException ((int)response.StatusCode, "Error calling GetTokenAccounts: " + response.ErrorMessage, response.ErrorMessage); - return (List) ApiClient.Deserialize(response.Content, typeof(List), response.Headers); + return (List) ApiClient.Deserialize(response.Content, typeof(List), response.headers.Values.ToList()); } } diff --git a/Runtime/Kinetic/Api/AirdropApi.cs b/Runtime/Kinetic/Api/AirdropApi.cs index 9474b60..ab0bf55 100644 --- a/Runtime/Kinetic/Api/AirdropApi.cs +++ b/Runtime/Kinetic/Api/AirdropApi.cs @@ -1,12 +1,15 @@ using System; using System.Collections.Generic; -using RestSharp; +using JeffreyLanters.WebRequests; +using JeffreyLanters.WebRequests.Core; +using Cysharp.Threading.Tasks; using Client; using Model; #pragma warning disable 0472 // The result of the expression is always the same since a value of this type is never equal to 'null' using Commitment = System.String; +using System.Linq; namespace Api { @@ -20,7 +23,7 @@ public interface IAirdropApi /// /// /// RequestAirdropResponse - RequestAirdropResponse RequestAirdrop (RequestAirdropRequest requestAirdropRequest); + UniTask RequestAirdrop (RequestAirdropRequest requestAirdropRequest); } /// @@ -81,7 +84,7 @@ public String GetBasePath(String basePath) /// /// /// RequestAirdropResponse - public RequestAirdropResponse RequestAirdrop (RequestAirdropRequest requestAirdropRequest) + public async UniTask RequestAirdrop (RequestAirdropRequest requestAirdropRequest) { // verify the required parameter 'requestAirdropRequest' is set @@ -94,7 +97,7 @@ public RequestAirdropResponse RequestAirdrop (RequestAirdropRequest requestAirdr var queryParams = new Dictionary(); var headerParams = new Dictionary(); var formParams = new Dictionary(); - var fileParams = new Dictionary(); + var fileParams = new Dictionary(); String postBody = null; postBody = ApiClient.Serialize(requestAirdropRequest); // http body (model) parameter @@ -103,14 +106,14 @@ public RequestAirdropResponse RequestAirdrop (RequestAirdropRequest requestAirdr String[] authSettings = new String[] { }; // make the HTTP request - IRestResponse response = (IRestResponse) ApiClient.CallApi(path, Method.POST, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + WebRequestResponse response = await ApiClient.CallApi(path, RequestMethod.Post, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) throw new ApiException ((int)response.StatusCode, "Error calling RequestAirdrop: " + response.Content, response.Content); else if (((int)response.StatusCode) == 0) throw new ApiException ((int)response.StatusCode, "Error calling RequestAirdrop: " + response.ErrorMessage, response.ErrorMessage); - return (RequestAirdropResponse) ApiClient.Deserialize(response.Content, typeof(RequestAirdropResponse), response.Headers); + return (RequestAirdropResponse) ApiClient.Deserialize(response.Content, typeof(RequestAirdropResponse), response.headers.Values.ToList()); } } diff --git a/Runtime/Kinetic/Api/AppApi.cs b/Runtime/Kinetic/Api/AppApi.cs index 3324e31..2dbe53c 100644 --- a/Runtime/Kinetic/Api/AppApi.cs +++ b/Runtime/Kinetic/Api/AppApi.cs @@ -1,12 +1,15 @@ using System; using System.Collections.Generic; -using RestSharp; +using JeffreyLanters.WebRequests; +using JeffreyLanters.WebRequests.Core; +using Cysharp.Threading.Tasks; using Client; using Model; #pragma warning disable 0472 // The result of the expression is always the same since a value of this type is never equal to 'null' using Commitment = System.String; +using System.Linq; namespace Api { @@ -21,14 +24,14 @@ public interface IAppApi /// /// /// AppConfig - AppConfig GetAppConfig (string environment, int index); + UniTask GetAppConfig (string environment, int index); /// /// /// /// /// /// AppHealth - AppHealth GetAppHealth (string environment, int index); + UniTask GetAppHealth (string environment, int index); } /// @@ -90,7 +93,7 @@ public String GetBasePath(String basePath) /// /// /// AppConfig - public AppConfig GetAppConfig (string environment, int index) + public async UniTask GetAppConfig (string environment, int index) { // verify the required parameter 'environment' is set @@ -108,22 +111,22 @@ public AppConfig GetAppConfig (string environment, int index) var queryParams = new Dictionary(); var headerParams = new Dictionary(); var formParams = new Dictionary(); - var fileParams = new Dictionary(); + var fileParams = new Dictionary(); String postBody = null; // authentication setting, if any String[] authSettings = new String[] { }; - + //UnityEngine.Debug.Log("Call GetAppConfig"); // make the HTTP request - IRestResponse response = (IRestResponse) ApiClient.CallApi(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings); - + WebRequestResponse response = await ApiClient.CallApi(path, RequestMethod.Get, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + //UnityEngine.Debug.Log("Finish GetAppConfig"); if (((int)response.StatusCode) >= 400) throw new ApiException ((int)response.StatusCode, "Error calling GetAppConfig: " + response.Content, response.Content); else if (((int)response.StatusCode) == 0) throw new ApiException ((int)response.StatusCode, "Error calling GetAppConfig: " + response.ErrorMessage, response.ErrorMessage); - return (AppConfig) ApiClient.Deserialize(response.Content, typeof(AppConfig), response.Headers); + return (AppConfig) ApiClient.Deserialize(response.Content, typeof(AppConfig), response.headers.Values.ToList()); } /// @@ -132,7 +135,7 @@ public AppConfig GetAppConfig (string environment, int index) /// /// /// AppHealth - public AppHealth GetAppHealth (string environment, int index) + public async UniTask GetAppHealth (string environment, int index) { // verify the required parameter 'environment' is set @@ -150,7 +153,7 @@ public AppHealth GetAppHealth (string environment, int index) var queryParams = new Dictionary(); var headerParams = new Dictionary(); var formParams = new Dictionary(); - var fileParams = new Dictionary(); + var fileParams = new Dictionary(); String postBody = null; @@ -158,14 +161,14 @@ public AppHealth GetAppHealth (string environment, int index) String[] authSettings = new String[] { }; // make the HTTP request - IRestResponse response = (IRestResponse) ApiClient.CallApi(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + WebRequestResponse response = await ApiClient.CallApi(path, RequestMethod.Get, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) throw new ApiException ((int)response.StatusCode, "Error calling GetAppHealth: " + response.Content, response.Content); else if (((int)response.StatusCode) == 0) throw new ApiException ((int)response.StatusCode, "Error calling GetAppHealth: " + response.ErrorMessage, response.ErrorMessage); - return (AppHealth) ApiClient.Deserialize(response.Content, typeof(AppHealth), response.Headers); + return (AppHealth) ApiClient.Deserialize(response.Content, typeof(AppHealth), response.headers.Values.ToList()); } } diff --git a/Runtime/Kinetic/Api/TransactionApi.cs b/Runtime/Kinetic/Api/TransactionApi.cs index 172b9c0..ebfac86 100644 --- a/Runtime/Kinetic/Api/TransactionApi.cs +++ b/Runtime/Kinetic/Api/TransactionApi.cs @@ -1,12 +1,15 @@ using System; using System.Collections.Generic; -using RestSharp; +using JeffreyLanters.WebRequests; +using JeffreyLanters.WebRequests.Core; +using Cysharp.Threading.Tasks; using Client; using Model; #pragma warning disable 0472 // The result of the expression is always the same since a value of this type is never equal to 'null' using Commitment = System.String; +using System.Linq; namespace Api { @@ -21,7 +24,7 @@ public interface ITransactionApi /// /// /// LatestBlockhashResponse - LatestBlockhashResponse GetLatestBlockhash (string environment, int index); + UniTask GetLatestBlockhash (string environment, int index); /// /// /// @@ -29,7 +32,7 @@ public interface ITransactionApi /// /// /// MinimumRentExemptionBalanceResponse - MinimumRentExemptionBalanceResponse GetMinimumRentExemptionBalance (string environment, int index, int dataLength); + UniTask GetMinimumRentExemptionBalance (string environment, int index, int dataLength); /// /// /// @@ -38,13 +41,13 @@ public interface ITransactionApi /// /// /// GetTransactionResponse - GetTransactionResponse GetTransaction (string environment, int index, string signature, Commitment commitment); + UniTask GetTransaction (string environment, int index, string signature, Commitment commitment); /// /// /// /// /// Transaction - Transaction MakeTransfer (MakeTransferRequest makeTransferRequest); + UniTask MakeTransfer (MakeTransferRequest makeTransferRequest); } /// @@ -106,7 +109,7 @@ public String GetBasePath(String basePath) /// /// /// LatestBlockhashResponse - public LatestBlockhashResponse GetLatestBlockhash (string environment, int index) + public async UniTask GetLatestBlockhash (string environment, int index) { // verify the required parameter 'environment' is set @@ -124,7 +127,7 @@ public LatestBlockhashResponse GetLatestBlockhash (string environment, int index var queryParams = new Dictionary(); var headerParams = new Dictionary(); var formParams = new Dictionary(); - var fileParams = new Dictionary(); + var fileParams = new Dictionary(); String postBody = null; @@ -132,14 +135,14 @@ public LatestBlockhashResponse GetLatestBlockhash (string environment, int index String[] authSettings = new String[] { }; // make the HTTP request - IRestResponse response = (IRestResponse) ApiClient.CallApi(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + WebRequestResponse response = await ApiClient.CallApi(path, RequestMethod.Get, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) throw new ApiException ((int)response.StatusCode, "Error calling GetLatestBlockhash: " + response.Content, response.Content); else if (((int)response.StatusCode) == 0) throw new ApiException ((int)response.StatusCode, "Error calling GetLatestBlockhash: " + response.ErrorMessage, response.ErrorMessage); - return (LatestBlockhashResponse) ApiClient.Deserialize(response.Content, typeof(LatestBlockhashResponse), response.Headers); + return (LatestBlockhashResponse) ApiClient.Deserialize(response.Content, typeof(LatestBlockhashResponse), response.headers.Values.ToList()); } /// @@ -149,7 +152,7 @@ public LatestBlockhashResponse GetLatestBlockhash (string environment, int index /// /// /// MinimumRentExemptionBalanceResponse - public MinimumRentExemptionBalanceResponse GetMinimumRentExemptionBalance (string environment, int index, int dataLength) + public async UniTask GetMinimumRentExemptionBalance (string environment, int index, int dataLength) { // verify the required parameter 'environment' is set @@ -170,7 +173,7 @@ public MinimumRentExemptionBalanceResponse GetMinimumRentExemptionBalance (strin var queryParams = new Dictionary(); var headerParams = new Dictionary(); var formParams = new Dictionary(); - var fileParams = new Dictionary(); + var fileParams = new Dictionary(); String postBody = null; if (dataLength != null) queryParams.Add("dataLength", ApiClient.ParameterToString(dataLength)); // query parameter @@ -179,14 +182,14 @@ public MinimumRentExemptionBalanceResponse GetMinimumRentExemptionBalance (strin String[] authSettings = new String[] { }; // make the HTTP request - IRestResponse response = (IRestResponse) ApiClient.CallApi(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + WebRequestResponse response = await ApiClient.CallApi(path, RequestMethod.Get, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) throw new ApiException ((int)response.StatusCode, "Error calling GetMinimumRentExemptionBalance: " + response.Content, response.Content); else if (((int)response.StatusCode) == 0) throw new ApiException ((int)response.StatusCode, "Error calling GetMinimumRentExemptionBalance: " + response.ErrorMessage, response.ErrorMessage); - return (MinimumRentExemptionBalanceResponse) ApiClient.Deserialize(response.Content, typeof(MinimumRentExemptionBalanceResponse), response.Headers); + return (MinimumRentExemptionBalanceResponse) ApiClient.Deserialize(response.Content, typeof(MinimumRentExemptionBalanceResponse), response.headers.Values.ToList()); } /// @@ -197,7 +200,7 @@ public MinimumRentExemptionBalanceResponse GetMinimumRentExemptionBalance (strin /// /// /// GetTransactionResponse - public GetTransactionResponse GetTransaction (string environment, int index, string signature, Commitment commitment) + public async UniTask GetTransaction (string environment, int index, string signature, Commitment commitment) { // verify the required parameter 'environment' is set @@ -222,7 +225,7 @@ public GetTransactionResponse GetTransaction (string environment, int index, str var queryParams = new Dictionary(); var headerParams = new Dictionary(); var formParams = new Dictionary(); - var fileParams = new Dictionary(); + var fileParams = new Dictionary(); String postBody = null; if (commitment != null) queryParams.Add("commitment", ApiClient.ParameterToString(commitment)); // query parameter @@ -231,14 +234,14 @@ public GetTransactionResponse GetTransaction (string environment, int index, str String[] authSettings = new String[] { }; // make the HTTP request - IRestResponse response = (IRestResponse) ApiClient.CallApi(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + WebRequestResponse response = await ApiClient.CallApi(path, RequestMethod.Get, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) throw new ApiException ((int)response.StatusCode, "Error calling GetTransaction: " + response.Content, response.Content); else if (((int)response.StatusCode) == 0) throw new ApiException ((int)response.StatusCode, "Error calling GetTransaction: " + response.ErrorMessage, response.ErrorMessage); - return (GetTransactionResponse) ApiClient.Deserialize(response.Content, typeof(GetTransactionResponse), response.Headers); + return (GetTransactionResponse) ApiClient.Deserialize(response.Content, typeof(GetTransactionResponse), response.headers.Values.ToList()); } /// @@ -246,7 +249,7 @@ public GetTransactionResponse GetTransaction (string environment, int index, str /// /// /// Transaction - public Transaction MakeTransfer (MakeTransferRequest makeTransferRequest) + public async UniTask MakeTransfer (MakeTransferRequest makeTransferRequest) { // verify the required parameter 'makeTransferRequest' is set @@ -259,7 +262,7 @@ public Transaction MakeTransfer (MakeTransferRequest makeTransferRequest) var queryParams = new Dictionary(); var headerParams = new Dictionary(); var formParams = new Dictionary(); - var fileParams = new Dictionary(); + var fileParams = new Dictionary(); String postBody = null; postBody = ApiClient.Serialize(makeTransferRequest); // http body (model) parameter @@ -268,14 +271,14 @@ public Transaction MakeTransfer (MakeTransferRequest makeTransferRequest) String[] authSettings = new String[] { }; // make the HTTP request - IRestResponse response = (IRestResponse) ApiClient.CallApi(path, Method.POST, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + WebRequestResponse response = await ApiClient.CallApi(path, RequestMethod.Post, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) throw new ApiException ((int)response.StatusCode, "Error calling MakeTransfer: " + response.Content, response.Content); else if (((int)response.StatusCode) == 0) throw new ApiException ((int)response.StatusCode, "Error calling MakeTransfer: " + response.ErrorMessage, response.ErrorMessage); - return (Transaction) ApiClient.Deserialize(response.Content, typeof(Transaction), response.Headers); + return (Transaction) ApiClient.Deserialize(response.Content, typeof(Transaction), response.headers.Values.ToList()); } } diff --git a/Runtime/Kinetic/Client/ApiClient.cs b/Runtime/Kinetic/Client/ApiClient.cs index 0903293..b068a1e 100644 --- a/Runtime/Kinetic/Client/ApiClient.cs +++ b/Runtime/Kinetic/Client/ApiClient.cs @@ -6,16 +6,17 @@ using System.IO; using System.Web; using System.Linq; -using System.Net; using System.Text; using Newtonsoft.Json; -using RestSharp; -using RestSharp.Extensions; +using JeffreyLanters.WebRequests; +using Cysharp.Threading.Tasks; +using JeffreyLanters.WebRequests.Core; #pragma warning disable 0618 // UNET transport deprecation namespace Client { + /// /// API client is mainly responsible for making the HTTP call to the API backend. /// @@ -30,7 +31,7 @@ public class ApiClient public ApiClient(String basePath="http://localhost:3000") { BasePath = basePath; - RestClient = new RestClient(BasePath); + RestClient = new WebRequest(basePath); } /// @@ -43,7 +44,7 @@ public ApiClient(String basePath="http://localhost:3000") /// Gets or sets the RestClient. /// /// An instance of the RestClient - public RestClient RestClient { get; set; } + public WebRequest RestClient { get; set; } /// /// Gets the default header. @@ -65,40 +66,68 @@ public Dictionary DefaultHeader /// File parameters. /// Authentication settings. /// Object - public Object CallApi(String path, RestSharp.Method method, Dictionary queryParams, String postBody, + public async UniTask CallApi(String path, RequestMethod method, Dictionary queryParams, String postBody, Dictionary headerParams, Dictionary formParams, - Dictionary fileParams, String[] authSettings) + Dictionary fileParams, String[] authSettings) { + //UnityEngine.Debug.Log("ApiClient CallApi"); + string url = this.BasePath + path; + string body = ""; + var _headers = _defaultHeaderMap.Concat(headerParams).ToDictionary(e => e.Key, e => e.Value); + //UnityEngine.Debug.Log("ApiClient CallApi 1"); + + var _queryParams = FormDataUtility.QueryString(queryParams); + //UnityEngine.Debug.Log("ApiClient CallApi 2"); + if (_queryParams != null && _queryParams != "") + { + url = url + "?" + UnityWebRequest.EscapeURL(_queryParams); + //UnityEngine.Debug.Log("ApiClient CallApi 2.5"); + } + //UnityEngine.Debug.Log("ApiClient CallApi 3"); - var request = new RestRequest(path, method); - - UpdateParamsForAuth(queryParams, headerParams, authSettings); - - // add default header, if any - foreach(var defaultHeader in _defaultHeaderMap) - request.AddHeader(defaultHeader.Key, defaultHeader.Value); - - // add header parameter, if any - foreach(var param in headerParams) - request.AddHeader(param.Key, param.Value); - - // add query parameter, if any - foreach(var param in queryParams) - request.AddParameter(param.Key, param.Value, ParameterType.GetOrPost); - - // add form parameter, if any - foreach(var param in formParams) - request.AddParameter(param.Key, param.Value, ParameterType.GetOrPost); - - // add file parameter, if any - foreach(var param in fileParams) - request.AddFile(param.Value.Name, param.Value.Writer, param.Value.FileName, param.Value.ContentLength, param.Value.ContentType); + var _formData = ""; + if (formParams.Count > 0) + { + _formData = FormDataUtility.ToFormData(formParams); + //UnityEngine.Debug.Log("ApiClient CallApi 4"); + } - if (postBody != null) // http body (model) parameter - request.AddParameter("application/json", postBody, ParameterType.RequestBody); + var headers = new List
    (); + foreach(KeyValuePair entry in _headers) + { + headers.Add(new Header(entry.Key, entry.Value)); + } + //UnityEngine.Debug.Log("ApiClient CallApi 5"); - return (Object)RestClient.Execute(request); + //Use postBody json string if not blank, else use the formData comprised of queryParams and formParams + if (postBody != null || postBody != "") + { + body = postBody; + } + else if (_formData != null || _formData != "") + { + body = _formData; + } + try + { + var request = new WebRequest(url) + { + method = method, + body = body, + contentType = ContentType.ApplicationJson, + headers = headers.ToArray() + }; + //UnityEngine.Debug.Log("ApiClient CallApi Send"); + return await request.Send(); + } + catch (WebRequestException exception) + { + UnityEngine.Debug.Log($"CallApiError {exception.httpStatusCode} while fetching {exception.url}"); + //UnityEngine.Debug.Log($"CallApiErrorBody {body}"); + UnityEngine.Debug.Log($"CallApiException {exception.rawResponseData}"); + return null; + } } /// @@ -122,20 +151,6 @@ public string EscapeString(string str) return UnityWebRequest.EscapeURL(str); } - /// - /// Create FileParameter based on Stream. - /// - /// Parameter name. - /// Input stream. - /// FileParameter. - public FileParameter ParameterToFile(string name, Stream stream) - { - if (stream is FileStream) - return FileParameter.Create(name, stream.ReadAsBytes(), Path.GetFileName(((FileStream)stream).Name)); - else - return FileParameter.Create(name, stream.ReadAsBytes(), "no_file_name_provided"); - } - /// /// If parameter is DateTime, output in a formatted string (default ISO 8601), customizable with Configuration.DateTime. /// If parameter is a list of string, join the list with ",". @@ -166,7 +181,7 @@ public string ParameterToString(object obj) /// Object type. /// HTTP headers. /// Object representation of the JSON string. - public object Deserialize(string content, Type type, IList headers=null) + public object Deserialize(string content, Type type, IList headers=null) { if (type == typeof(Object)) // return an object { diff --git a/Runtime/KineticSdk.cs b/Runtime/KineticSdk.cs index d00186d..a7f5b7c 100644 --- a/Runtime/KineticSdk.cs +++ b/Runtime/KineticSdk.cs @@ -1,11 +1,14 @@ using System; using System.Collections.Generic; +#if !UNITY_WEBGL using System.Threading.Tasks; +#endif using Kinetic.Sdk.Helpers; using Kinetic.Sdk.Interfaces; using Kinetic.Sdk.Transactions; using Model; using UnityEngine; +using Cysharp.Threading.Tasks; // ReSharper disable once CheckNamespace @@ -35,27 +38,27 @@ public AppConfig Config() return _sdkInternal.AppConfig; } - #region Utility +#region Utility - public AccountInfo GetAccountInfoSync(string account, Commitment? commitment = null) + public UniTask GetAccountInfoSync(string account, Commitment? commitment = null) { return _sdkInternal.GetAccountInfo(account, commitment); } - public async Task GetAccountInfo(string account, Commitment? commitment = null ) + public UniTask GetAccountInfo(string account, Commitment? commitment = null ) { - return await Task.Run(() => GetAccountInfoSync(account, commitment)); + return GetAccountInfoSync(account, commitment); } - public BalanceResponse GetBalanceSync(string account, Commitment? commitment = null) + public UniTask GetBalanceSync(string account, Commitment? commitment = null) { return _sdkInternal.GetBalance(account, commitment); } - public async Task GetBalance(string account, Commitment? commitment = null) + public UniTask GetBalance(string account, Commitment? commitment = null) { - return await Task.Run(() => GetBalanceSync(account, commitment)); + return GetBalanceSync(account, commitment); } public string GetExplorerUrl(string path) @@ -64,28 +67,29 @@ public string GetExplorerUrl(string path) } - public List GetHistorySync(string account, string mint = null, Commitment? commitment = null) + public UniTask> GetHistorySync(string account, string mint = null, Commitment? commitment = null) { return _sdkInternal.GetHistory(account, mint, commitment); } - public async Task> GetHistory(string account, string mint = null, Commitment? commitment = null) + public UniTask> GetHistory(string account, string mint = null, Commitment? commitment = null) { - return await Task.Run(() => GetHistorySync(account, mint, commitment)); + return GetHistorySync(account, mint, commitment); + } - public GetTransactionResponse GetTransactionSync(string signature, Commitment? commitment = null) + public UniTask GetTransactionSync(string signature, Commitment? commitment = null) { return _sdkInternal.GetTransaction(signature, commitment); } - public async Task GetTransaction(string signature, Commitment? commitment = null) + public UniTask GetTransaction(string signature, Commitment? commitment = null) { - return await Task.Run(() => GetTransactionSync(signature, commitment)); + return GetTransactionSync(signature, commitment); } - public List GetTokenAccountsSync( + public UniTask> GetTokenAccountsSync( string account, string mint = null, Commitment? commitment = null) @@ -93,15 +97,15 @@ public List GetTokenAccountsSync( return _sdkInternal.GetTokenAccounts(account, mint, commitment); } - public async Task> GetTokenAccounts( + public UniTask> GetTokenAccounts( string account, string mint = null, Commitment? commitment = null) { - return await Task.Run(() => GetTokenAccountsSync(account, mint, commitment)); + return GetTokenAccountsSync(account, mint, commitment); } - public RequestAirdropResponse RequestAirdropSync( + public UniTask RequestAirdropSync( string account, string amount, string mint = null, @@ -111,21 +115,22 @@ public RequestAirdropResponse RequestAirdropSync( return _sdkInternal.RequestAirdrop(account, amount, mint, commitment); } - public async Task RequestAirdrop( + public UniTask RequestAirdrop( string account, string amount, string mint = null, Commitment? commitment = null ) { - return await Task.Run(() => RequestAirdropSync(account, amount, mint, commitment)); + return RequestAirdropSync(account, amount, mint, commitment); + } #endregion #region Transactions - public Transaction CloseAccountSync( + public UniTask CloseAccountSync( string account, string mint = null, string referenceId = null, @@ -136,7 +141,7 @@ public Transaction CloseAccountSync( return _sdkInternal.CloseAccount(account, mint, referenceId, referenceType, commitment); } - public async Task CloseAccount( + public UniTask CloseAccount( string account, string mint = null, string referenceId = null, @@ -144,10 +149,10 @@ public async Task CloseAccount( Commitment? commitment = null ) { - return await Task.Run(() => CloseAccountSync(account, mint, referenceId, referenceType, commitment)); + return CloseAccountSync(account, mint, referenceId, referenceType, commitment); } - public Transaction CreateAccountSync( + public UniTask CreateAccountSync( Keypair owner, string mint = null, string referenceId = null, @@ -158,7 +163,7 @@ public Transaction CreateAccountSync( return _sdkInternal.CreateAccount(owner, mint, referenceId, referenceType, commitment); } - public async Task CreateAccount( + public UniTask CreateAccount( Keypair owner, string mint = null, string referenceId = null, @@ -166,10 +171,10 @@ public async Task CreateAccount( Commitment? commitment = null ) { - return await Task.Run(() => CreateAccountSync(owner, mint, referenceId, referenceType, commitment)); + return CreateAccountSync(owner, mint, referenceId, referenceType, commitment); } - public Transaction MakeTransferSync( + public UniTask MakeTransferSync( Keypair owner, string amount, string destination, @@ -185,7 +190,7 @@ public Transaction MakeTransferSync( senderCreate, type, commitment); } - public async Task MakeTransfer( + public UniTask MakeTransfer( Keypair owner, string amount, string destination, @@ -197,16 +202,16 @@ public async Task MakeTransfer( Commitment? commitment = null ) { - return await Task.Run(() => - MakeTransferSync(owner, amount, destination, mint, referenceId, referenceType, senderCreate, type, commitment)); + return MakeTransferSync(owner, amount, destination, mint, referenceId, referenceType, senderCreate, type, commitment); } #endregion #region Initialization - private AppConfig Init() + private async UniTask Init() { + //Debug.Log("AppConfigInit"); // Error if SdkConfig is not set if (SdkConfig == null) { @@ -215,7 +220,7 @@ private AppConfig Init() try { SdkConfig!.Logger?.Log("KineticSdk: initializing"); - var config = _sdkInternal.GetAppConfig(); + var config = await _sdkInternal.GetAppConfig(); SdkConfig!.SolanaRpcEndpoint = SdkConfig.SolanaRpcEndpoint != null ? SdkConfig.SolanaRpcEndpoint.GetSolanaRpcEndpoint() : config.Environment.Cluster.Endpoint.GetSolanaRpcEndpoint(); @@ -234,12 +239,13 @@ private AppConfig Init() } } - public static KineticSdk SetupSync(KineticSdkConfig config) + public static async UniTask SetupSync(KineticSdkConfig config) { + //Debug.Log("SetupSync"); var sdk = new KineticSdk(config: ValidateKineticSdkConfig.Validate(config)); try { - sdk.Init(); + await sdk.Init(); config.Logger?.Log("KineticSdk: Setup done."); return sdk; } @@ -250,11 +256,12 @@ public static KineticSdk SetupSync(KineticSdkConfig config) } } - public static async Task Setup(KineticSdkConfig config) + public static UniTask Setup(KineticSdkConfig config) { - return await Task.Run(() => SetupSync(config)); + //Debug.Log("Prepare Setup task"); + return SetupSync(config); } - #endregion +#endregion } } \ No newline at end of file diff --git a/Runtime/KineticSdkInternal.cs b/Runtime/KineticSdkInternal.cs index 1e05258..4655038 100644 --- a/Runtime/KineticSdkInternal.cs +++ b/Runtime/KineticSdkInternal.cs @@ -2,10 +2,12 @@ using System.Collections.Generic; using Api; using Client; +using Cysharp.Threading.Tasks; using Kinetic.Sdk.Helpers; using Kinetic.Sdk.Interfaces; using Kinetic.Sdk.Transactions; using Model; +using UnityEngine; // ReSharper disable once CheckNamespace @@ -48,7 +50,7 @@ internal KineticSdkInternal(KineticSdkConfig config) #region Core - public Transaction CloseAccount( + public UniTask CloseAccount( string account, string mint = null, string referenceId = null, @@ -74,7 +76,7 @@ public Transaction CloseAccount( return _accountApi.CloseAccount(request); } - public Transaction CreateAccount( + public async UniTask CreateAccount( Keypair owner, string mint = null, string referenceId = null, @@ -86,7 +88,7 @@ public Transaction CreateAccount( var appConfig = EnsureAppConfig(); var appMint = GetAppMint(appConfig, mint); - var blockhash = GetBlockhash(); + var blockhash = await GetBlockhash(); var tx = GenerateCreateAccountTransaction.Generate( appMint.AddMemo, @@ -109,10 +111,10 @@ public Transaction CreateAccount( Tx = Convert.ToBase64String(tx.Serialize()) }; - return _accountApi.CreateAccount(request); + return await _accountApi.CreateAccount(request); } - public AccountInfo GetAccountInfo(string account, Commitment? commitment = null) + public UniTask GetAccountInfo(string account, Commitment? commitment = null) { var appCommitment = GetCommitment(commitment); @@ -120,13 +122,14 @@ public AccountInfo GetAccountInfo(string account, Commitment? commitment = null) } - public AppConfig GetAppConfig() + public async UniTask GetAppConfig() { - AppConfig = _appApi.GetAppConfig(_sdkConfig.Environment, _sdkConfig.Index); + UnityEngine.Debug.Log("Try GetAppConfig"); + AppConfig = await _appApi.GetAppConfig(_sdkConfig.Environment, _sdkConfig.Index); return AppConfig; } - public BalanceResponse GetBalance(string account, Commitment? commitment = null) + public UniTask GetBalance(string account, Commitment? commitment = null) { var appCommitment = GetCommitment(commitment); @@ -138,7 +141,7 @@ public BalanceResponse GetBalance(string account, Commitment? commitment = null) ); } - public List GetHistory(string account, string mint = null, Commitment? commitment = null) + public UniTask> GetHistory(string account, string mint = null, Commitment? commitment = null) { var appCommitment = GetCommitment(commitment); var appConfig = EnsureAppConfig(); @@ -147,7 +150,7 @@ public List GetHistory(string account, string mint = null, Comm return _accountApi.GetHistory(_sdkConfig.Environment, _sdkConfig.Index, account, appMint.PublicKey, appCommitment.ToString()); } - public List GetTokenAccounts(string account, string mint = null, Commitment? commitment = null) + public UniTask> GetTokenAccounts(string account, string mint = null, Commitment? commitment = null) { var appCommitment = GetCommitment(commitment); var appConfig = EnsureAppConfig(); @@ -157,7 +160,7 @@ public List GetTokenAccounts(string account, string mint = null, Commitm .GetTokenAccounts(_sdkConfig.Environment, _sdkConfig.Index, account, appMint.PublicKey, appCommitment.ToString()); } - public GetTransactionResponse GetTransaction(string signature, Commitment? commitment = null) + public UniTask GetTransaction(string signature, Commitment? commitment = null) { var appCommitment = GetCommitment(commitment); @@ -165,7 +168,7 @@ public GetTransactionResponse GetTransaction(string signature, Commitment? commi .GetTransaction(_sdkConfig.Environment, _sdkConfig.Index, signature, appCommitment.ToString()); } - public Transaction MakeTransfer( + public async UniTask MakeTransfer( Keypair owner, string amount, string destination, @@ -186,9 +189,9 @@ public Transaction MakeTransfer( throw new Exception("Transfers to a mint are not allowed."); } - var blockhash = GetBlockhash(); + var blockhash = await GetBlockhash(); - var account = GetTokenAccounts(destination, appMint.PublicKey, appCommitment); + var account = await GetTokenAccounts(destination, appMint.PublicKey, appCommitment); if (account.Count == 0 && !senderCreate) throw new Exception("Destination account doesn't exist."); @@ -218,10 +221,10 @@ public Transaction MakeTransfer( Tx = Convert.ToBase64String(tx.Serialize()) }; - return _transactionApi.MakeTransfer(mkTransfer); + return await _transactionApi.MakeTransfer(mkTransfer); } - public RequestAirdropResponse RequestAirdrop( + public UniTask RequestAirdrop( string account, string amount, string mint = null, @@ -271,9 +274,9 @@ private AppConfigMint GetAppMint(AppConfig appConfig, string mint = null) return found; } - private PreTransaction GetBlockhash() + private async UniTask GetBlockhash() { - var latestBlockhashResponse = + var latestBlockhashResponse = await _transactionApi.GetLatestBlockhash(_sdkConfig.Environment, _sdkConfig.Index); return new PreTransaction diff --git a/Samples~/ExampleKinSDK/Images/Loading_2.gif b/Samples~/ExampleKinSDK/Images/Loading_2.gif index d3558d9..8df2c15 100644 Binary files a/Samples~/ExampleKinSDK/Images/Loading_2.gif and b/Samples~/ExampleKinSDK/Images/Loading_2.gif differ diff --git a/Samples~/ExampleKinSDK/Images/RoundedRectange.png b/Samples~/ExampleKinSDK/Images/RoundedRectange.png index 8c289a2..9118d54 100644 Binary files a/Samples~/ExampleKinSDK/Images/RoundedRectange.png and b/Samples~/ExampleKinSDK/Images/RoundedRectange.png differ diff --git a/Samples~/ExampleKinSDK/Images/bg.png b/Samples~/ExampleKinSDK/Images/bg.png index 4ea1728..f4f4db7 100644 Binary files a/Samples~/ExampleKinSDK/Images/bg.png and b/Samples~/ExampleKinSDK/Images/bg.png differ diff --git a/Tests/Runtime/Kinetic.Sdk.Tests.asmdef b/Tests/Runtime/Kinetic.Sdk.Tests.asmdef index e3391d7..91a8e97 100644 --- a/Tests/Runtime/Kinetic.Sdk.Tests.asmdef +++ b/Tests/Runtime/Kinetic.Sdk.Tests.asmdef @@ -1,9 +1,15 @@ { "name": "Kinetic.Sdk.Tests", + "rootNamespace": "", "references": [ "UnityEngine.TestRunner", "UnityEditor.TestRunner", - "Kinetic.Sdk" + "Kinetic.Sdk", + "UniTask", + "nl.jeffreylanters.web-requests", + "Solana.Unity", + "Chaos.Nacl", + "NewAssembly" ], "includePlatforms": [], "excludePlatforms": [], diff --git a/Tests/Runtime/KineticSdkTest.cs b/Tests/Runtime/KineticSdkTest.cs index dfcaef9..18f271f 100644 --- a/Tests/Runtime/KineticSdkTest.cs +++ b/Tests/Runtime/KineticSdkTest.cs @@ -12,9 +12,9 @@ namespace Kinetic.Sdk.Tests public class KineticSdkTest { [SetUp] - public void Init() + public async void Init() { - _sdk = KineticSdk.SetupSync( + _sdk = await KineticSdk.SetupSync( new KineticSdkConfig( Endpoint, Environment, @@ -64,18 +64,18 @@ public void PartialSignCreateAccountTransaction() } [Test] - public void GetBalance() + public async void GetBalance() { - var res = _sdk.GetBalanceSync(KineticSdkFixture.AliceKeypair.PublicKey); + var res = await _sdk.GetBalanceSync(KineticSdkFixture.AliceKeypair.PublicKey); var balance = double.Parse(res.Balance); Assert.IsTrue(!double.IsNaN(balance)); Assert.IsTrue(balance > 0); } [Test, Timeout(30000)] - public void TestGetAccountInfo() + public async void TestGetAccountInfo() { - var res = _sdk.GetAccountInfoSync(account: KineticSdkFixture.AliceKeypair.PublicKey); + var res = await _sdk.GetAccountInfoSync(account: KineticSdkFixture.AliceKeypair.PublicKey); Assert.IsFalse(res.IsMint); Assert.IsFalse(res.IsTokenAccount); @@ -89,11 +89,11 @@ public void TestGetAccountInfo() [Test, Timeout(30000)] - public void TestCloseAccount() + public async void TestCloseAccount() { var owner = Keypair.Random(); - var createdTx = _sdk.CreateAccountSync(owner, commitment: Commitment.Finalized, referenceType: "Unity: TestCloseAccount", referenceId: "Create"); + var createdTx = await _sdk.CreateAccountSync(owner, commitment: Commitment.Finalized, referenceType: "Unity: TestCloseAccount", referenceId: "Create"); Assert.NotNull(createdTx); Assert.NotNull(createdTx.Signature); @@ -101,7 +101,7 @@ public void TestCloseAccount() Assert.AreEqual(_sdk.Config().Mint.PublicKey, createdTx.Mint); Assert.AreEqual("Committed", createdTx.Status); - var closedTx = _sdk.CloseAccountSync(owner.PublicKey, commitment: Commitment.Finalized, referenceType: "Unity: TestCloseAccount", referenceId: "Close"); + var closedTx = await _sdk.CloseAccountSync(owner.PublicKey, commitment: Commitment.Finalized, referenceType: "Unity: TestCloseAccount", referenceId: "Close"); Assert.NotNull(closedTx); Assert.NotNull(closedTx.Signature); @@ -111,10 +111,10 @@ public void TestCloseAccount() } [Test] - public void TestCreateAccount() + public async void TestCreateAccount() { var owner = Keypair.Random(); - var tx = _sdk.CreateAccountSync(owner); + var tx = await _sdk.CreateAccountSync(owner); Assert.NotNull(tx); Assert.NotNull(tx.Signature); @@ -124,9 +124,9 @@ public void TestCreateAccount() } [Test] - public void TestCreateAccountAlreadyExists() + public async void TestCreateAccountAlreadyExists() { - var tx = _sdk.CreateAccountSync(KineticSdkFixture.DaveKeypair); + var tx = await _sdk.CreateAccountSync(KineticSdkFixture.DaveKeypair); Assert.IsNull(tx.Signature); Assert.IsNull(tx.Amount); Assert.IsTrue(tx.Errors.Count > 0); @@ -135,17 +135,17 @@ public void TestCreateAccountAlreadyExists() } [Test] - public void TestGetHistory() + public async void TestGetHistory() { - var history = _sdk.GetHistorySync(KineticSdkFixture.AliceKeypair.PublicKey); + var history = await _sdk.GetHistorySync(KineticSdkFixture.AliceKeypair.PublicKey); Assert.IsTrue(history.Count > 0); Assert.IsNotNull(history[0].Account); } [Test] - public void TestGetTokenAccounts() + public async void TestGetTokenAccounts() { - var tokenAccounts = _sdk.GetTokenAccountsSync(KineticSdkFixture.AliceKeypair.PublicKey); + var tokenAccounts = await _sdk.GetTokenAccountsSync(KineticSdkFixture.AliceKeypair.PublicKey); Assert.IsTrue(tokenAccounts.Count > 0); Assert.IsNotNull(tokenAccounts[0]); } @@ -159,9 +159,9 @@ public void TestGetExplorerUrl() } [Test] - public void TestTransaction() + public async void TestTransaction() { - var tx = _sdk.MakeTransferSync( + var tx = await _sdk.MakeTransferSync( amount: "43", destination: KineticSdkFixture.BobKeypair.PublicKey, owner: KineticSdkFixture.AliceKeypair); @@ -174,9 +174,9 @@ public void TestTransaction() } [Test] - public void TestTransactionWithInsufficientFunds() + public async void TestTransactionWithInsufficientFunds() { - var tx = _sdk.MakeTransferSync( + var tx = await _sdk.MakeTransferSync( amount: "99999999999999", destination: KineticSdkFixture.BobKeypair.PublicKey, owner: KineticSdkFixture.AliceKeypair); @@ -188,10 +188,10 @@ public void TestTransactionWithInsufficientFunds() } [Test] - public void TestTransactionWithSenderCreation() + public async void TestTransactionWithSenderCreation() { var destination = Keypair.Random(); - var tx = _sdk.MakeTransferSync( + var tx = await _sdk.MakeTransferSync( amount: "43", destination: destination.PublicKey, owner: KineticSdkFixture.AliceKeypair, @@ -242,9 +242,9 @@ public void TestTransactionToMint() } [Test] - public void TestRequestAirdrop() + public async void TestRequestAirdrop() { - var airdrop = _sdk.RequestAirdropSync(KineticSdkFixture.DaveKeypair.PublicKey, "1000"); + var airdrop = await _sdk.RequestAirdropSync(KineticSdkFixture.DaveKeypair.PublicKey, "1000"); Assert.IsNotNull(airdrop.Signature); }